/[emacs]/emacs/src/dired.c
ViewVC logotype

Diff of /emacs/src/dired.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.94 by eliz, Wed Dec 19 17:14:39 2001 UTC revision 1.94.4.1 by miles, Fri Apr 4 06:20:57 2003 UTC
# Line 130  directory_files_internal_unwind (dh) Line 130  directory_files_internal_unwind (dh)
130    return Qnil;    return Qnil;
131  }  }
132    
133  /* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.    /* Function shared by Fdirectory_files and Fdirectory_files_and_attributes.
134     When ATTRS is zero, return a list of directory filenames; when     When ATTRS is zero, return a list of directory filenames; when
135     non-zero, return a list of directory filenames and their attributes.  */     non-zero, return a list of directory filenames and their attributes.  */
136    
# Line 144  directory_files_internal (directory, ful Line 144  directory_files_internal (directory, ful
144    Lisp_Object list, dirfilename, encoded_directory;    Lisp_Object list, dirfilename, encoded_directory;
145    struct re_pattern_buffer *bufp = NULL;    struct re_pattern_buffer *bufp = NULL;
146    int needsep = 0;    int needsep = 0;
147    int count = specpdl_ptr - specpdl;    int count = SPECPDL_INDEX ();
148    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
149    DIRENTRY *dp;    DIRENTRY *dp;
150    int retry_p;    int retry_p;
# Line 153  directory_files_internal (directory, ful Line 153  directory_files_internal (directory, ful
153       Ffuncall, and cause a GC.  */       Ffuncall, and cause a GC.  */
154    list = encoded_directory = dirfilename = Qnil;    list = encoded_directory = dirfilename = Qnil;
155    GCPRO5 (match, directory, list, dirfilename, encoded_directory);    GCPRO5 (match, directory, list, dirfilename, encoded_directory);
   directory = Fexpand_file_name (directory, Qnil);  
156    dirfilename = Fdirectory_file_name (directory);    dirfilename = Fdirectory_file_name (directory);
157    
158    if (!NILP (match))    if (!NILP (match))
# Line 187  directory_files_internal (directory, ful Line 186  directory_files_internal (directory, ful
186       have to make sure it gets closed, and setting up an       have to make sure it gets closed, and setting up an
187       unwind_protect to do so would be a pain.  */       unwind_protect to do so would be a pain.  */
188   retry:   retry:
189      
190    d = opendir (XSTRING (dirfilename)->data);    d = opendir (SDATA (dirfilename));
191    if (d == NULL)    if (d == NULL)
192      report_file_error ("Opening directory", Fcons (directory, Qnil));      report_file_error ("Opening directory", Fcons (directory, Qnil));
193    
# Line 199  directory_files_internal (directory, ful Line 198  directory_files_internal (directory, ful
198                           Fcons (make_number (((unsigned long) d) >> 16),                           Fcons (make_number (((unsigned long) d) >> 16),
199                                  make_number (((unsigned long) d) & 0xffff)));                                  make_number (((unsigned long) d) & 0xffff)));
200    
201    directory_nbytes = STRING_BYTES (XSTRING (directory));    directory_nbytes = SBYTES (directory);
202    re_match_object = Qt;    re_match_object = Qt;
203    
204    /* Decide whether we need to add a directory separator.  */    /* Decide whether we need to add a directory separator.  */
205  #ifndef VMS  #ifndef VMS
206    if (directory_nbytes == 0    if (directory_nbytes == 0
207        || !IS_ANY_SEP (XSTRING (directory)->data[directory_nbytes - 1]))        || !IS_ANY_SEP (SREF (directory, directory_nbytes - 1)))
208      needsep = 1;      needsep = 1;
209  #endif /* not VMS */  #endif /* not VMS */
210    
# Line 219  directory_files_internal (directory, ful Line 218  directory_files_internal (directory, ful
218        if (dp == NULL && errno == EAGAIN)        if (dp == NULL && errno == EAGAIN)
219          continue;          continue;
220  #endif  #endif
221          
222        if (dp == NULL)        if (dp == NULL)
223          break;          break;
224    
# Line 233  directory_files_internal (directory, ful Line 232  directory_files_internal (directory, ful
232            len = NAMLEN (dp);            len = NAMLEN (dp);
233            name = finalname = make_unibyte_string (dp->d_name, len);            name = finalname = make_unibyte_string (dp->d_name, len);
234            GCPRO2 (finalname, name);            GCPRO2 (finalname, name);
235              
236            /* Note: ENCODE_FILE can GC; it should protect its argument,            /* Note: ENCODE_FILE can GC; it should protect its argument,
237               though.  */               though.  */
238            name = DECODE_FILE (name);            name = DECODE_FILE (name);
239            len = STRING_BYTES (XSTRING (name));            len = SBYTES (name);
240    
241            /* Now that we have unwind_protect in place, we might as well            /* Now that we have unwind_protect in place, we might as well
242               allow matching to be interrupted.  */               allow matching to be interrupted.  */
# Line 245  directory_files_internal (directory, ful Line 244  directory_files_internal (directory, ful
244            QUIT;            QUIT;
245    
246            if (NILP (match)            if (NILP (match)
247                || (0 <= re_search (bufp, XSTRING (name)->data, len, 0, len, 0)))                || (0 <= re_search (bufp, SDATA (name), len, 0, len, 0)))
248              wanted = 1;              wanted = 1;
249    
250            immediate_quit = 0;            immediate_quit = 0;
# Line 259  directory_files_internal (directory, ful Line 258  directory_files_internal (directory, ful
258                    int nchars;                    int nchars;
259    
260                    fullname = make_uninit_multibyte_string (nbytes, nbytes);                    fullname = make_uninit_multibyte_string (nbytes, nbytes);
261                    bcopy (XSTRING (directory)->data, XSTRING (fullname)->data,                    bcopy (SDATA (directory), SDATA (fullname),
262                           directory_nbytes);                           directory_nbytes);
263                      
264                    if (needsep)                    if (needsep)
265                      XSTRING (fullname)->data[directory_nbytes] = DIRECTORY_SEP;                      SSET (fullname, directory_nbytes, DIRECTORY_SEP);
266                      
267                    bcopy (XSTRING (name)->data,                    bcopy (SDATA (name),
268                           XSTRING (fullname)->data + directory_nbytes + needsep,                           SDATA (fullname) + directory_nbytes + needsep,
269                           len);                           len);
270                      
271                    nchars = chars_in_text (XSTRING (fullname)->data, nbytes);                    nchars = chars_in_text (SDATA (fullname), nbytes);
272    
273                    /* Some bug somewhere.  */                    /* Some bug somewhere.  */
274                    if (nchars > nbytes)                    if (nchars > nbytes)
275                      abort ();                      abort ();
276                          
277                    XSTRING (fullname)->size = nchars;                    STRING_SET_CHARS (fullname, nchars);
278                    if (nchars == nbytes)                    if (nchars == nbytes)
279                      SET_STRING_BYTES (XSTRING (fullname), -1);                      STRING_SET_UNIBYTE (fullname);
280                      
281                    finalname = fullname;                    finalname = fullname;
282                  }                  }
283                else                else
# Line 328  directory_files_internal (directory, ful Line 327  directory_files_internal (directory, ful
327    if (NILP (nosort))    if (NILP (nosort))
328      list = Fsort (Fnreverse (list),      list = Fsort (Fnreverse (list),
329                    attrs ? Qfile_attributes_lessp : Qstring_lessp);                    attrs ? Qfile_attributes_lessp : Qstring_lessp);
330      
331    RETURN_UNGCPRO (list);    RETURN_UNGCPRO (list);
332  }  }
333    
# Line 345  If NOSORT is non-nil, the list is not so Line 344  If NOSORT is non-nil, the list is not so
344       Lisp_Object directory, full, match, nosort;       Lisp_Object directory, full, match, nosort;
345  {  {
346    Lisp_Object handler;    Lisp_Object handler;
347      directory = Fexpand_file_name (directory, Qnil);
348    
349    /* If the file name has special constructs in it,    /* If the file name has special constructs in it,
350       call the corresponding file handler.  */       call the corresponding file handler.  */
# Line 378  If NOSORT is non-nil, the list is not so Line 378  If NOSORT is non-nil, the list is not so
378       Lisp_Object directory, full, match, nosort;       Lisp_Object directory, full, match, nosort;
379  {  {
380    Lisp_Object handler;    Lisp_Object handler;
381      directory = Fexpand_file_name (directory, Qnil);
382    
383    /* If the file name has special constructs in it,    /* If the file name has special constructs in it,
384       call the corresponding file handler.  */       call the corresponding file handler.  */
# Line 473  file_name_completion (file, dirname, all Line 474  file_name_completion (file, dirname, all
474    struct stat st;    struct stat st;
475    int directoryp;    int directoryp;
476    int passcount;    int passcount;
477    int count = specpdl_ptr - specpdl;    int count = SPECPDL_INDEX ();
478    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
479    
480    elt = Qnil;    elt = Qnil;
# Line 519  file_name_completion (file, dirname, all Line 520  file_name_completion (file, dirname, all
520    
521    for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++)    for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++)
522      {      {
523        d = opendir (XSTRING (Fdirectory_file_name (encoded_dir))->data);        int inner_count = SPECPDL_INDEX ();
524    
525          d = opendir (SDATA (Fdirectory_file_name (encoded_dir)));
526        if (!d)        if (!d)
527          report_file_error ("Opening directory", Fcons (dirname, Qnil));          report_file_error ("Opening directory", Fcons (dirname, Qnil));
528    
529          record_unwind_protect (directory_files_internal_unwind,
530                                 Fcons (make_number (((unsigned long) d) >> 16),
531                                        make_number (((unsigned long) d) & 0xffff)));
532    
533        /* Loop reading blocks */        /* Loop reading blocks */
534        /* (att3b compiler bug requires do a null comparison this way) */        /* (att3b compiler bug requires do a null comparison this way) */
535        while (1)        while (1)
# Line 539  file_name_completion (file, dirname, all Line 546  file_name_completion (file, dirname, all
546    
547            len = NAMLEN (dp);            len = NAMLEN (dp);
548    
549            if (!NILP (Vquit_flag) && NILP (Vinhibit_quit))            QUIT;
             goto quit;  
550            if (! DIRENTRY_NONEMPTY (dp)            if (! DIRENTRY_NONEMPTY (dp)
551                || len < XSTRING (encoded_file)->size                || len < SCHARS (encoded_file)
552                || 0 <= scmp (dp->d_name, XSTRING (encoded_file)->data,                || 0 <= scmp (dp->d_name, SDATA (encoded_file),
553                              XSTRING (encoded_file)->size))                              SCHARS (encoded_file)))
554              continue;              continue;
555    
556            if (file_name_completion_stat (encoded_dir, dp, &st) < 0)            if (file_name_completion_stat (encoded_dir, dp, &st) < 0)
# Line 561  file_name_completion (file, dirname, all Line 567  file_name_completion (file, dirname, all
567                   actually in the way in a directory contains only one file.  */                   actually in the way in a directory contains only one file.  */
568                if (!passcount && TRIVIAL_DIRECTORY_ENTRY (dp->d_name))                if (!passcount && TRIVIAL_DIRECTORY_ENTRY (dp->d_name))
569                  continue;                  continue;
570                if (!passcount && len > XSTRING (encoded_file)->size)                if (!passcount && len > SCHARS (encoded_file))
571                  /* Ignore directories if they match an element of                  /* Ignore directories if they match an element of
572                     completion-ignored-extensions which ends in a slash.  */                     completion-ignored-extensions which ends in a slash.  */
573                  for (tem = Vcompletion_ignored_extensions;                  for (tem = Vcompletion_ignored_extensions;
# Line 575  file_name_completion (file, dirname, all Line 581  file_name_completion (file, dirname, all
581                      /* Need to encode ELT, since scmp compares unibyte                      /* Need to encode ELT, since scmp compares unibyte
582                         strings only.  */                         strings only.  */
583                      elt = ENCODE_FILE (elt);                      elt = ENCODE_FILE (elt);
584                      elt_len = XSTRING (elt)->size - 1; /* -1 for trailing / */                      elt_len = SCHARS (elt) - 1; /* -1 for trailing / */
585                      if (elt_len <= 0)                      if (elt_len <= 0)
586                        continue;                        continue;
587                      p1 = XSTRING (elt)->data;                      p1 = SDATA (elt);
588                      if (p1[elt_len] != '/')                      if (p1[elt_len] != '/')
589                        continue;                        continue;
590                      skip = len - elt_len;                      skip = len - elt_len;
# Line 594  file_name_completion (file, dirname, all Line 600  file_name_completion (file, dirname, all
600              {              {
601                /* Compare extensions-to-be-ignored against end of this file name */                /* Compare extensions-to-be-ignored against end of this file name */
602                /* if name is not an exact match against specified string */                /* if name is not an exact match against specified string */
603                if (!passcount && len > XSTRING (encoded_file)->size)                if (!passcount && len > SCHARS (encoded_file))
604                  /* and exit this for loop if a match is found */                  /* and exit this for loop if a match is found */
605                  for (tem = Vcompletion_ignored_extensions;                  for (tem = Vcompletion_ignored_extensions;
606                       CONSP (tem); tem = XCDR (tem))                       CONSP (tem); tem = XCDR (tem))
# Line 604  file_name_completion (file, dirname, all Line 610  file_name_completion (file, dirname, all
610                      /* Need to encode ELT, since scmp compares unibyte                      /* Need to encode ELT, since scmp compares unibyte
611                         strings only.  */                         strings only.  */
612                      elt = ENCODE_FILE (elt);                      elt = ENCODE_FILE (elt);
613                      skip = len - XSTRING (elt)->size;                      skip = len - SCHARS (elt);
614                      if (skip < 0) continue;                      if (skip < 0) continue;
615    
616                      if (0 <= scmp (dp->d_name + skip,                      if (0 <= scmp (dp->d_name + skip,
617                                     XSTRING (elt)->data,                                     SDATA (elt),
618                                     XSTRING (elt)->size))                                     SCHARS (elt)))
619                        continue;                        continue;
620                      break;                      break;
621                    }                    }
# Line 661  file_name_completion (file, dirname, all Line 667  file_name_completion (file, dirname, all
667                else                else
668                  {                  {
669                    bestmatch = name;                    bestmatch = name;
670                    bestmatchsize = XSTRING (name)->size;                    bestmatchsize = SCHARS (name);
671                  }                  }
672              }              }
673            else            else
674              {              {
675                compare = min (bestmatchsize, len);                compare = min (bestmatchsize, len);
676                p1 = XSTRING (bestmatch)->data;                p1 = SDATA (bestmatch);
677                p2 = (unsigned char *) dp->d_name;                p2 = (unsigned char *) dp->d_name;
678                matchsize = scmp(p1, p2, compare);                matchsize = scmp(p1, p2, compare);
679                if (matchsize < 0)                if (matchsize < 0)
# Line 681  file_name_completion (file, dirname, all Line 687  file_name_completion (file, dirname, all
687                    /* This tests that the current file is an exact match                    /* This tests that the current file is an exact match
688                       but BESTMATCH is not (it is too long).  */                       but BESTMATCH is not (it is too long).  */
689                    if ((matchsize == len                    if ((matchsize == len
690                         && matchsize + !!directoryp                         && matchsize + !!directoryp
691                            < XSTRING (bestmatch)->size)                            < SCHARS (bestmatch))
692                        ||                        ||
693                        /* If there is no exact match ignoring case,                        /* If there is no exact match ignoring case,
694                           prefer a match that does not change the case                           prefer a match that does not change the case
# Line 694  file_name_completion (file, dirname, all Line 700  file_name_completion (file, dirname, all
700                           either both or neither are exact.  */                           either both or neither are exact.  */
701                        (((matchsize == len)                        (((matchsize == len)
702                          ==                          ==
703                          (matchsize + !!directoryp                          (matchsize + !!directoryp
704                           == XSTRING (bestmatch)->size))                           == SCHARS (bestmatch)))
705                         && !bcmp (p2, XSTRING (encoded_file)->data, XSTRING (encoded_file)->size)                         && !bcmp (p2, SDATA (encoded_file), SCHARS (encoded_file))
706                         && bcmp (p1, XSTRING (encoded_file)->data, XSTRING (encoded_file)->size)))                         && bcmp (p1, SDATA (encoded_file), SCHARS (encoded_file))))
707                      {                      {
708                        bestmatch = make_string (dp->d_name, len);                        bestmatch = make_string (dp->d_name, len);
709                        if (directoryp)                        if (directoryp)
# Line 715  file_name_completion (file, dirname, all Line 721  file_name_completion (file, dirname, all
721                bestmatchsize = matchsize;                bestmatchsize = matchsize;
722              }              }
723          }          }
724        closedir (d);        /* This closes the directory.  */
725          bestmatch = unbind_to (inner_count, bestmatch);
726      }      }
727    
728    UNGCPRO;    UNGCPRO;
# Line 727  file_name_completion (file, dirname, all Line 734  file_name_completion (file, dirname, all
734          bestmatch = DECODE_FILE (bestmatch);          bestmatch = DECODE_FILE (bestmatch);
735        return bestmatch;        return bestmatch;
736      }      }
737    if (matchcount == 1 && bestmatchsize == XSTRING (file)->size)    if (matchcount == 1 && bestmatchsize == SCHARS (file))
738      return Qt;      return Qt;
739    bestmatch = Fsubstring (bestmatch, make_number (0),    bestmatch = Fsubstring (bestmatch, make_number (0),
740                            make_number (bestmatchsize));                            make_number (bestmatchsize));
# Line 735  file_name_completion (file, dirname, all Line 742  file_name_completion (file, dirname, all
742       decode it from the coding system in use.  */       decode it from the coding system in use.  */
743    bestmatch = DECODE_FILE (bestmatch);    bestmatch = DECODE_FILE (bestmatch);
744    return bestmatch;    return bestmatch;
   
  quit:  
   if (d) closedir (d);  
   Vquit_flag = Qnil;  
   return Fsignal (Qquit, Qnil);  
745  }  }
746    
747  /* Compare exactly LEN chars of strings at S1 and S2,  /* Compare exactly LEN chars of strings at S1 and S2,
# Line 777  file_name_completion_stat (dirname, dp, Line 779  file_name_completion_stat (dirname, dp,
779       struct stat *st_addr;       struct stat *st_addr;
780  {  {
781    int len = NAMLEN (dp);    int len = NAMLEN (dp);
782    int pos = XSTRING (dirname)->size;    int pos = SCHARS (dirname);
783    int value;    int value;
784    char *fullname = (char *) alloca (len + pos + 2);    char *fullname = (char *) alloca (len + pos + 2);
785    
# Line 794  file_name_completion_stat (dirname, dp, Line 796  file_name_completion_stat (dirname, dp,
796  #endif /* __DJGPP__ > 1 */  #endif /* __DJGPP__ > 1 */
797  #endif /* MSDOS */  #endif /* MSDOS */
798    
799    bcopy (XSTRING (dirname)->data, fullname, pos);    bcopy (SDATA (dirname), fullname, pos);
800  #ifndef VMS  #ifndef VMS
801    if (!IS_DIRECTORY_SEP (fullname[pos - 1]))    if (!IS_DIRECTORY_SEP (fullname[pos - 1]))
802      fullname[pos++] = DIRECTORY_SEP;      fullname[pos++] = DIRECTORY_SEP;
# Line 847  Returns nil if the file cannot be opened Line 849  Returns nil if the file cannot be opened
849    filename = Fexpand_file_name (filename, Qnil);    filename = Fexpand_file_name (filename, Qnil);
850    fab      = cc$rms_fab;    fab      = cc$rms_fab;
851    xabfhc   = cc$rms_xabfhc;    xabfhc   = cc$rms_xabfhc;
852    fab.fab$l_fna = XSTRING (filename)->data;    fab.fab$l_fna = SDATA (filename);
853    fab.fab$b_fns = strlen (fab.fab$l_fna);    fab.fab$b_fns = strlen (fab.fab$l_fna);
854    fab.fab$l_xab = (char *) &xabfhc;    fab.fab$l_xab = (char *) &xabfhc;
855    status = sys$open (&fab, 0, 0);    status = sys$open (&fab, 0, 0);
# Line 916  If file does not exist, returns nil.  */ Line 918  If file does not exist, returns nil.  */
918    
919    encoded = ENCODE_FILE (filename);    encoded = ENCODE_FILE (filename);
920    
921    if (lstat (XSTRING (encoded)->data, &s) < 0)    if (lstat (SDATA (encoded), &s) < 0)
922      return Qnil;      return Qnil;
923    
924    switch (s.st_mode & S_IFMT)    switch (s.st_mode & S_IFMT)
# Line 940  If file does not exist, returns nil.  */ Line 942  If file does not exist, returns nil.  */
942    /* If the size is out of range for an integer, return a float.  */    /* If the size is out of range for an integer, return a float.  */
943    if (XINT (values[7]) != s.st_size)    if (XINT (values[7]) != s.st_size)
944      values[7] = make_float ((double)s.st_size);      values[7] = make_float ((double)s.st_size);
945      /* If the size is negative, and its type is long, convert it back to
946         positive.  */
947      if (s.st_size < 0 && sizeof (s.st_size) == sizeof (long))
948        values[7] = make_float ((double) ((unsigned long) s.st_size));
949    
950    filemodestring (&s, modes);    filemodestring (&s, modes);
951    values[8] = make_string (modes, 10);    values[8] = make_string (modes, 10);
952  #if defined (BSD4_2) || defined (BSD4_3) /* file gid will be dir gid */  #if defined (BSD4_2) || defined (BSD4_3) /* file gid will be dir gid */
953    dirname = Ffile_name_directory (filename);    dirname = Ffile_name_directory (filename);
954    if (! NILP (dirname))    if (! NILP (dirname))
955      encoded = ENCODE_FILE (dirname);      encoded = ENCODE_FILE (dirname);
956    if (! NILP (dirname) && stat (XSTRING (encoded)->data, &sdir) == 0)    if (! NILP (dirname) && stat (SDATA (encoded), &sdir) == 0)
957      values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;      values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;
958    else                                  /* if we can't tell, assume worst */    else                                  /* if we can't tell, assume worst */
959      values[9] = Qt;      values[9] = Qt;
960  #else                                   /* file gid will be egid */  #else                                   /* file gid will be egid */
961    values[9] = (s.st_gid != getegid ()) ? Qt : Qnil;    values[9] = (s.st_gid != getegid ()) ? Qt : Qnil;
962  #endif  /* BSD4_2 (or BSD4_3) */  #endif  /* BSD4_2 (or BSD4_3) */
   /* Cast -1 to avoid warning if int is not as wide as VALBITS.  */  
963    if (FIXNUM_OVERFLOW_P (s.st_ino))    if (FIXNUM_OVERFLOW_P (s.st_ino))
964      /* To allow inode numbers larger than VALBITS, separate the bottom      /* To allow inode numbers larger than VALBITS, separate the bottom
965         16 bits.  */         16 bits.  */

Legend:
Removed from v.1.94  
changed lines
  Added in v.1.94.4.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26