# HG changeset patch # User Gerd Moellmann # Date 973781299 0 # Node ID 8ee80e8c9093126d7c6201456588636a88f9f3b1 # Parent ae432b5b679d764c27db4c2b677a92ec28995546 (directory_files_internal): Add missing GCPRO's. Some cleanup. diff -r ae432b5b679d -r 8ee80e8c9093 src/dired.c --- 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); }