changeset 33345:8ee80e8c9093

(directory_files_internal): Add missing GCPRO's. Some cleanup.
author Gerd Moellmann <gerd@gnu.org>
date Thu, 09 Nov 2000 14:48:19 +0000
parents ae432b5b679d
children 8b937b4669a8
files src/dired.c
diffstat 1 files changed, 58 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/src/dired.c	Thu Nov 09 14:32:25 2000 +0000
+++ b/src/dired.c	Thu Nov 09 14:48:19 2000 +0000
@@ -137,23 +137,20 @@
      int attrs;
 {
   DIR *d;
-  int dirnamelen;
-  Lisp_Object list, name, dirfilename;
-  Lisp_Object encoded_directory;
+  int directory_nbytes;
+  Lisp_Object list, dirfilename, encoded_directory;
   Lisp_Object handler;
   struct re_pattern_buffer *bufp = NULL;
   int needsep = 0;
   int count = specpdl_ptr - specpdl;
-  struct gcpro gcpro1, gcpro2;
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
 
   /* Because of file name handlers, these functions might call
      Ffuncall, and cause a GC.  */
-  GCPRO1 (match);
+  list = encoded_directory = dirfilename = Qnil;
+  GCPRO5 (match, directory, list, dirfilename, encoded_directory);
   directory = Fexpand_file_name (directory, Qnil);
-  UNGCPRO;
-  GCPRO2 (match, directory);
   dirfilename = Fdirectory_file_name (directory);
-  UNGCPRO;
 
   if (!NILP (match))
     {
@@ -172,8 +169,10 @@
 #endif
     }
 
+  /* Note: ENOCDE_FILE and DECODE_FILE can GC because they can run
+     run_pre_post_conversion_on_str which calls Lisp directly and
+     indirectly.  */
   dirfilename = ENCODE_FILE (dirfilename);
-
   encoded_directory = ENCODE_FILE (directory);
 
   /* Now *bufp is the compiled form of MATCH; don't call anything
@@ -184,7 +183,7 @@
      have to make sure it gets closed, and setting up an
      unwind_protect to do so would be a pain.  */
   d = opendir (XSTRING (dirfilename)->data);
-  if (! d)
+  if (d == NULL)
     report_file_error ("Opening directory", Fcons (directory, Qnil));
 
   /* Unfortunately, we can now invoke expand-file-name and
@@ -194,32 +193,38 @@
 			 Fcons (make_number (((unsigned long) d) >> 16),
 				make_number (((unsigned long) d) & 0xffff)));
 
-  list = Qnil;
-  dirnamelen = STRING_BYTES (XSTRING (directory));
+  directory_nbytes = STRING_BYTES (XSTRING (directory));
   re_match_object = Qt;
 
   /* Decide whether we need to add a directory separator.  */
 #ifndef VMS
-  if (dirnamelen == 0
-      || !IS_ANY_SEP (XSTRING (directory)->data[dirnamelen - 1]))
+  if (directory_nbytes == 0
+      || !IS_ANY_SEP (XSTRING (directory)->data[directory_nbytes - 1]))
     needsep = 1;
 #endif /* not VMS */
 
-  GCPRO2 (encoded_directory, list);
-
   /* Loop reading blocks */
   while (1)
     {
       DIRENTRY *dp = readdir (d);
 
-      if (!dp) break;
+      if (dp == NULL)
+	break;
+      
       if (DIRENTRY_NONEMPTY (dp))
 	{
 	  int len;
 	  int wanted = 0;
+	  Lisp_Object name, finalname;
+	  struct gcpro gcpro1, gcpro2;
 
 	  len = NAMLEN (dp);
-	  name = DECODE_FILE (make_string (dp->d_name, len));
+	  name = finalname = make_string (dp->d_name, len);
+	  GCPRO2 (finalname, name);
+	  
+	  /* Note: ENCODE_FILE can GC; it should protect its argument,
+	     though.  */
+	  name = DECODE_FILE (name);
 	  len = STRING_BYTES (XSTRING (name));
 
 	  /* Now that we have unwind_protect in place, we might as well
@@ -229,37 +234,40 @@
 
 	  if (NILP (match)
 	      || (0 <= re_search (bufp, XSTRING (name)->data, len, 0, len, 0)))
-	    {
-	      wanted = 1;
-	    }
+	    wanted = 1;
 
 	  immediate_quit = 0;
 
 	  if (wanted)
 	    {
-	      Lisp_Object finalname;
-
-	      finalname = name;
 	      if (!NILP (full))
 		{
-		  int afterdirindex = dirnamelen;
-		  int total = len + dirnamelen;
+		  Lisp_Object fullname;
+		  int nbytes = len + directory_nbytes + needsep;
 		  int nchars;
-		  Lisp_Object fullname;
 
-		  fullname = make_uninit_multibyte_string (total + needsep,
-							   total + needsep);
+		  fullname = make_uninit_multibyte_string (nbytes, nbytes);
 		  bcopy (XSTRING (directory)->data, XSTRING (fullname)->data,
-			 dirnamelen);
+			 directory_nbytes);
+		  
 		  if (needsep)
-		    XSTRING (fullname)->data[afterdirindex++] = DIRECTORY_SEP;
+		    XSTRING (fullname)->data[directory_nbytes + 1]
+		      = DIRECTORY_SEP;
+		  
 		  bcopy (XSTRING (name)->data,
-			 XSTRING (fullname)->data + afterdirindex, len);
-		  nchars = chars_in_text (XSTRING (fullname)->data,
-					  afterdirindex + len);
+			 XSTRING (fullname)->data + directory_nbytes + needsep,
+			 len);
+		  
+		  nchars = chars_in_text (XSTRING (fullname)->data, nbytes);
+
+		  /* Some bug somewhere.  */
+		  if (nchars > nbytes)
+		    abort ();
+		      
 		  XSTRING (fullname)->size = nchars;
-		  if (nchars == STRING_BYTES (XSTRING (fullname)))
+		  if (nchars == nbytes)
 		    SET_STRING_BYTES (XSTRING (fullname), -1);
+		  
 		  finalname = fullname;
 		}
 
@@ -267,19 +275,24 @@
 		{
 		  /* Construct an expanded filename for the directory entry.
 		     Use the decoded names for input to Ffile_attributes.  */
-		  Lisp_Object decoded_fullname;
-		  Lisp_Object fileattrs;
+		  Lisp_Object decoded_fullname, fileattrs;
+		  struct gcpro gcpro1, gcpro2;
 
+		  decoded_fullname = fileattrs = Qnil;
+		  GCPRO2 (decoded_fullname, fileattrs);
+
+		  /* Both Fexpand_file_name and Ffile_attributes can GC.  */
 		  decoded_fullname = Fexpand_file_name (name, directory);
 		  fileattrs = Ffile_attributes (decoded_fullname);
 
 		  list = Fcons (Fcons (finalname, fileattrs), list);
+		  UNGCPRO;
 		}
 	      else
-		{
-		  list = Fcons (finalname, list);
-		}
+		list = Fcons (finalname, list);
 	    }
+
+	  UNGCPRO;
 	}
     }
 
@@ -288,13 +301,11 @@
   /* Discard the unwind protect.  */
   specpdl_ptr = specpdl + count;
 
-  UNGCPRO;
-  if (!NILP (nosort))
-    return list;
-  if (attrs)
-    return Fsort (Fnreverse (list), Qfile_attributes_lessp);
-  else
-    return Fsort (Fnreverse (list), Qstring_lessp);
+  if (NILP (nosort))
+    list = Fsort (Fnreverse (list),
+		  attrs ? Qfile_attributes_lessp : Qstring_lessp);
+  
+  RETURN_UNGCPRO (list);
 }