comparison src/dired.c @ 771:943eaba38521

[xemacs-hg @ 2002-03-13 08:51:24 by ben] The big ben-mule-21-5 check-in! Various files were added and deleted. See CHANGES-ben-mule. There are still some test suite failures. No crashes, though. Many of the failures have to do with problems in the test suite itself rather than in the actual code. I'll be addressing these in the next day or so -- none of the test suite failures are at all critical. Meanwhile I'll be trying to address the biggest issues -- i.e. build or run failures, which will almost certainly happen on various platforms. All comments should be sent to ben@xemacs.org -- use a Cc: if necessary when sending to mailing lists. There will be pre- and post- tags, something like pre-ben-mule-21-5-merge-in, and post-ben-mule-21-5-merge-in.
author ben
date Wed, 13 Mar 2002 08:54:06 +0000
parents 336a418893b5
children a5954632b187
comparison
equal deleted inserted replaced
770:336a418893b5 771:943eaba38521
1 /* Lisp functions for making directory listings. 1 /* Lisp functions for making directory listings.
2 Copyright (C) 1985, 1986, 1992, 1993, 1994 Free Software Foundation, Inc. 2 Copyright (C) 1985, 1986, 1992, 1993, 1994 Free Software Foundation, Inc.
3 Copyright (C) 2001 Ben Wing.
3 4
4 This file is part of XEmacs. 5 This file is part of XEmacs.
5 6
6 XEmacs is free software; you can redistribute it and/or modify it 7 XEmacs is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the 8 under the terms of the GNU General Public License as published by the
47 48
48 static Lisp_Object 49 static Lisp_Object
49 close_directory_unwind (Lisp_Object unwind_obj) 50 close_directory_unwind (Lisp_Object unwind_obj)
50 { 51 {
51 DIR *d = (DIR *)get_opaque_ptr (unwind_obj); 52 DIR *d = (DIR *)get_opaque_ptr (unwind_obj);
52 closedir (d); 53 qxe_closedir (d);
53 free_opaque_ptr (unwind_obj); 54 free_opaque_ptr (unwind_obj);
54 return Qnil; 55 return Qnil;
55 } 56 }
56 57
57 DEFUN ("directory-files", Fdirectory_files, 1, 5, 0, /* 58 DEFUN ("directory-files", Fdirectory_files, 1, 5, 0, /*
74 Lisp_Object list = Qnil; 75 Lisp_Object list = Qnil;
75 Bytecount directorylen; 76 Bytecount directorylen;
76 Lisp_Object handler; 77 Lisp_Object handler;
77 struct re_pattern_buffer *bufp = NULL; 78 struct re_pattern_buffer *bufp = NULL;
78 int speccount = specpdl_depth (); 79 int speccount = specpdl_depth ();
79 char *statbuf, *statbuf_tail; 80 Intbyte *statbuf, *statbuf_tail;
80 81
81 struct gcpro gcpro1, gcpro2; 82 struct gcpro gcpro1, gcpro2;
82 GCPRO2 (directory, list); 83 GCPRO2 (directory, list);
83 84
84 /* If the file name has special constructs in it, 85 /* If the file name has special constructs in it,
99 but earlier everywhere else? */ 100 but earlier everywhere else? */
100 directory = Fexpand_file_name (directory, Qnil); 101 directory = Fexpand_file_name (directory, Qnil);
101 directory = Ffile_name_as_directory (directory); 102 directory = Ffile_name_as_directory (directory);
102 directorylen = XSTRING_LENGTH (directory); 103 directorylen = XSTRING_LENGTH (directory);
103 104
104 statbuf = (char *)alloca (directorylen + MAXNAMLEN + 1); 105 statbuf = (Intbyte *) alloca (directorylen + MAXNAMLEN + 1);
105 memcpy (statbuf, XSTRING_DATA (directory), directorylen); 106 memcpy (statbuf, XSTRING_DATA (directory), directorylen);
106 statbuf_tail = statbuf + directorylen; 107 statbuf_tail = statbuf + directorylen;
107 108
108 /* XEmacs: this should come after Ffile_name_as_directory() to avoid 109 /* XEmacs: this should come after Ffile_name_as_directory() to avoid
109 potential regexp cache smashage. It comes before the opendir() 110 potential regexp cache smashage. It comes before the opendir()
122 which might compile a new regexp until we're done with the loop! */ 123 which might compile a new regexp until we're done with the loop! */
123 124
124 /* Do this opendir after anything which might signal an error. 125 /* Do this opendir after anything which might signal an error.
125 NOTE: the above comment is old; previously, there was no 126 NOTE: the above comment is old; previously, there was no
126 unwind-protection in case of error, but now there is. */ 127 unwind-protection in case of error, but now there is. */
127 d = opendir ((char *) XSTRING_DATA (directory)); 128 d = qxe_opendir (XSTRING_DATA (directory));
128 if (!d) 129 if (!d)
129 report_file_error ("Opening directory", directory); 130 report_file_error ("Opening directory", directory);
130 131
131 regex_match_object = Qt; 132 regex_match_object = Qt;
132 regex_emacs_buffer = current_buffer; 133 regex_emacs_buffer = current_buffer;
134 record_unwind_protect (close_directory_unwind, make_opaque_ptr ((void *)d)); 135 record_unwind_protect (close_directory_unwind, make_opaque_ptr ((void *)d));
135 136
136 /* Loop reading blocks */ 137 /* Loop reading blocks */
137 while (1) 138 while (1)
138 { 139 {
139 DIRENTRY *dp = readdir (d); 140 DIRENTRY *dp = qxe_readdir (d);
140 int len; 141 int len;
141 142
142 if (!dp) 143 if (!dp)
143 break; 144 break;
144 len = NAMLEN (dp); 145 len = NAMLEN (dp);
152 int dir_p = 0; 153 int dir_p = 0;
153 154
154 memcpy (statbuf_tail, dp->d_name, len); 155 memcpy (statbuf_tail, dp->d_name, len);
155 statbuf_tail[len] = 0; 156 statbuf_tail[len] = 0;
156 157
157 if (xemacs_stat (statbuf, &st) == 0 158 if (qxe_stat (statbuf, &st) == 0
158 && (st.st_mode & S_IFMT) == S_IFDIR) 159 && (st.st_mode & S_IFMT) == S_IFDIR)
159 dir_p = 1; 160 dir_p = 1;
160 161
161 if (EQ (files_only, Qt) && dir_p) 162 if (EQ (files_only, Qt) && dir_p)
162 continue; 163 continue;
172 173
173 list = Fcons (name, list); 174 list = Fcons (name, list);
174 } 175 }
175 } 176 }
176 } 177 }
177 unbind_to (speccount, Qnil); /* This will close the dir */ 178 unbind_to (speccount); /* This will close the dir */
178 179
179 if (NILP (nosort)) 180 if (NILP (nosort))
180 list = Fsort (Fnreverse (list), Qstring_lessp); 181 list = Fsort (Fnreverse (list), Qstring_lessp);
181 182
182 RETURN_UNGCPRO (list); 183 RETURN_UNGCPRO (list);
246 struct stat *st_addr) 247 struct stat *st_addr)
247 { 248 {
248 Bytecount len = NAMLEN (dp); 249 Bytecount len = NAMLEN (dp);
249 Bytecount pos = XSTRING_LENGTH (directory); 250 Bytecount pos = XSTRING_LENGTH (directory);
250 int value; 251 int value;
251 char *fullname = (char *) alloca (len + pos + 2); 252 Intbyte *fullname = (Intbyte *) alloca (len + pos + 2);
252 253
253 memcpy (fullname, XSTRING_DATA (directory), pos); 254 memcpy (fullname, XSTRING_DATA (directory), pos);
254 if (!IS_DIRECTORY_SEP (fullname[pos - 1])) 255 if (!IS_DIRECTORY_SEP (fullname[pos - 1]))
255 fullname[pos++] = DIRECTORY_SEP; 256 fullname[pos++] = DIRECTORY_SEP;
256 257
259 260
260 #ifdef S_IFLNK 261 #ifdef S_IFLNK
261 /* We want to return success if a link points to a nonexistent file, 262 /* We want to return success if a link points to a nonexistent file,
262 but we want to return the status for what the link points to, 263 but we want to return the status for what the link points to,
263 in case it is a directory. */ 264 in case it is a directory. */
264 value = lstat (fullname, st_addr); 265 value = qxe_lstat (fullname, st_addr);
265 if (S_ISLNK (st_addr->st_mode)) 266 if (S_ISLNK (st_addr->st_mode))
266 xemacs_stat (fullname, st_addr); 267 qxe_stat (fullname, st_addr);
267 #else 268 #else
268 value = xemacs_stat (fullname, st_addr); 269 value = qxe_stat (fullname, st_addr);
269 #endif 270 #endif
270 return value; 271 return value;
271 } 272 }
272 273
273 static Lisp_Object 274 static Lisp_Object
277 Lisp_Object obj = XCAR (locative); 278 Lisp_Object obj = XCAR (locative);
278 279
279 if (!NILP (obj)) 280 if (!NILP (obj))
280 { 281 {
281 d = (DIR *)get_opaque_ptr (obj); 282 d = (DIR *)get_opaque_ptr (obj);
282 closedir (d); 283 qxe_closedir (d);
283 free_opaque_ptr (obj); 284 free_opaque_ptr (obj);
284 } 285 }
285 free_cons (XCONS (locative)); 286 free_cons (XCONS (locative));
286 return Qnil; 287 return Qnil;
287 } 288 }
334 locative = noseeum_cons (Qnil, Qnil); 335 locative = noseeum_cons (Qnil, Qnil);
335 record_unwind_protect (file_name_completion_unwind, locative); 336 record_unwind_protect (file_name_completion_unwind, locative);
336 337
337 for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++) 338 for (passcount = !!all_flag; NILP (bestmatch) && passcount < 2; passcount++)
338 { 339 {
339 d = opendir ((char *) XSTRING_DATA (Fdirectory_file_name (directory))); 340 d = qxe_opendir (XSTRING_DATA (Fdirectory_file_name (directory)));
340 if (!d) 341 if (!d)
341 report_file_error ("Opening directory", directory); 342 report_file_error ("Opening directory", directory);
342 XCAR (locative) = make_opaque_ptr ((void *)d); 343 XCAR (locative) = make_opaque_ptr ((void *)d);
343 344
344 /* Loop reading blocks */ 345 /* Loop reading blocks */
351 Charcount cclen; 352 Charcount cclen;
352 int directoryp; 353 int directoryp;
353 int ignored_extension_p = 0; 354 int ignored_extension_p = 0;
354 Intbyte *d_name; 355 Intbyte *d_name;
355 356
356 dp = readdir (d); 357 dp = qxe_readdir (d);
357 if (!dp) break; 358 if (!dp) break;
358 359
359 /* Cast to Intbyte* is OK, as readdir() Mule-encapsulates. */ 360 /* Cast to Intbyte* is OK, as qxe_readdir() Mule-encapsulates. */
360 d_name = (Intbyte *) dp->d_name; 361 d_name = (Intbyte *) dp->d_name;
361 len = NAMLEN (dp); 362 len = NAMLEN (dp);
362 cclen = bytecount_to_charcount (d_name, len); 363 cclen = bytecount_to_charcount (d_name, len);
363 364
364 QUIT; 365 QUIT;
490 && IS_ANY_SEP (charptr_emchar_n (p1, matchsize))) 491 && IS_ANY_SEP (charptr_emchar_n (p1, matchsize)))
491 matchsize++; 492 matchsize++;
492 bestmatchsize = matchsize; 493 bestmatchsize = matchsize;
493 } 494 }
494 } 495 }
495 closedir (d); 496 qxe_closedir (d);
496 free_opaque_ptr (XCAR (locative)); 497 free_opaque_ptr (XCAR (locative));
497 XCAR (locative) = Qnil; 498 XCAR (locative) = Qnil;
498 } 499 }
499 500
500 unbind_to (speccount, Qnil); 501 unbind_to (speccount);
501 502
502 UNGCPRO; 503 UNGCPRO;
503 504
504 if (all_flag || NILP (bestmatch)) 505 if (all_flag || NILP (bestmatch))
505 return bestmatch; 506 return bestmatch;
639 640
640 record_unwind_protect (user_name_completion_unwind, cache_incomplete_p); 641 record_unwind_protect (user_name_completion_unwind, cache_incomplete_p);
641 #ifndef WIN32_NATIVE 642 #ifndef WIN32_NATIVE
642 slow_down_interrupts (); 643 slow_down_interrupts ();
643 setpwent (); 644 setpwent ();
644 while ((pwd = getpwent ())) 645 while ((pwd = qxe_getpwent ()))
645 { 646 {
646 QUIT; 647 QUIT;
647 DO_REALLOC (user_cache.user_names, user_cache.size, 648 DO_REALLOC (user_cache.user_names, user_cache.size,
648 user_cache.length + 1, struct user_name); 649 user_cache.length + 1, struct user_name);
649 TO_INTERNAL_FORMAT (C_STRING, pwd->pw_name, 650 user_cache.user_names[user_cache.length].ptr =
650 MALLOC, 651 (Intbyte *) xstrdup (pwd->pw_name);
651 (user_cache.user_names[user_cache.length].ptr, 652 user_cache.user_names[user_cache.length].len = strlen (pwd->pw_name);
652 user_cache.user_names[user_cache.length].len),
653 Qnative);
654 user_cache.length++; 653 user_cache.length++;
655 } 654 }
656 #else 655 #else
657 if (xNetUserEnum) 656 if (xNetUserEnum)
658 { 657 {
670 status_status_statui_statum_statu != ERROR_MORE_DATA) 669 status_status_statui_statum_statu != ERROR_MORE_DATA)
671 invalid_operation ("Error enumerating users", 670 invalid_operation ("Error enumerating users",
672 make_int (GetLastError ())); 671 make_int (GetLastError ()));
673 for (i = 0; i < (int) entriesread; i++) 672 for (i = 0; i < (int) entriesread; i++)
674 { 673 {
675 int nout =
676 WideCharToMultiByte (CP_ACP, WC_COMPOSITECHECK,
677 bufptr[i].usri0_name,
678 -1, 0, 0, "~", 0);
679 void *outp = alloca (nout);
680 WideCharToMultiByte (CP_ACP, WC_COMPOSITECHECK,
681 bufptr[i].usri0_name, -1,
682 (LPSTR) outp, nout, "~", 0);
683 DO_REALLOC (user_cache.user_names, user_cache.size, 674 DO_REALLOC (user_cache.user_names, user_cache.size,
684 user_cache.length + 1, struct user_name); 675 user_cache.length + 1, struct user_name);
685 TO_INTERNAL_FORMAT (C_STRING, outp, 676 TO_INTERNAL_FORMAT (C_STRING,
677 bufptr[i].usri0_name,
686 MALLOC, 678 MALLOC,
687 (user_cache. 679 (user_cache.
688 user_names[user_cache.length].ptr, 680 user_names[user_cache.length].ptr,
689 user_cache. 681 user_cache.
690 user_names[user_cache.length].len), 682 user_names[user_cache.length].len),
691 Qmswindows_tstr); 683 Qmswindows_unicode);
692 user_cache.length++; 684 user_cache.length++;
693 } 685 }
694 xNetApiBufferFree (bufptr); 686 xNetApiBufferFree (bufptr);
695 } 687 }
696 while (entriesread != totalentries); 688 while (entriesread != totalentries);
698 else /* Win 9x */ 690 else /* Win 9x */
699 { 691 {
700 Extbyte name[2 * (UNLEN + 1)]; 692 Extbyte name[2 * (UNLEN + 1)];
701 DWORD length = sizeof (name); 693 DWORD length = sizeof (name);
702 694
703 if (GetUserName (name, &length)) 695 if (qxeGetUserName (name, &length))
704 { 696 {
705 DO_REALLOC (user_cache.user_names, user_cache.size, 697 DO_REALLOC (user_cache.user_names, user_cache.size,
706 user_cache.length + 1, struct user_name); 698 user_cache.length + 1, struct user_name);
707 TO_INTERNAL_FORMAT (C_STRING, name, 699 TO_INTERNAL_FORMAT (C_STRING, name,
708 MALLOC, 700 MALLOC,
715 } 707 }
716 } 708 }
717 #endif 709 #endif
718 710
719 XCAR (cache_incomplete_p) = Qnil; 711 XCAR (cache_incomplete_p) = Qnil;
720 unbind_to (speccount, Qnil); 712 unbind_to (speccount);
721 713
722 EMACS_GET_TIME (user_cache.last_rebuild_time); 714 EMACS_GET_TIME (user_cache.last_rebuild_time);
723 } 715 }
724 716
725 for (i = 0; i < user_cache.length; i++) 717 for (i = 0; i < user_cache.length; i++)
781 return Fsubstring (bestmatch, Qzero, make_int (bestmatchsize)); 773 return Fsubstring (bestmatch, Qzero, make_int (bestmatchsize));
782 } 774 }
783 775
784 776
785 Lisp_Object 777 Lisp_Object
786 make_directory_hash_table (const char *path) 778 make_directory_hash_table (const Intbyte *path)
787 { 779 {
788 DIR *d; 780 DIR *d;
789 if ((d = opendir (path))) 781 if ((d = qxe_opendir (path)))
790 { 782 {
791 DIRENTRY *dp; 783 DIRENTRY *dp;
792 Lisp_Object hash = 784 Lisp_Object hash =
793 make_lisp_hash_table (20, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL); 785 make_lisp_hash_table (20, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
794 786
795 while ((dp = readdir (d))) 787 while ((dp = qxe_readdir (d)))
796 { 788 {
797 Bytecount len = NAMLEN (dp); 789 Bytecount len = NAMLEN (dp);
798 if (DIRENTRY_NONEMPTY (dp)) 790 if (DIRENTRY_NONEMPTY (dp))
799 /* Cast to Intbyte* is OK, as readdir() Mule-encapsulates. */ 791 /* Cast to Intbyte* is OK, as qxe_readdir() Mule-encapsulates. */
800 Fputhash (make_string ((Intbyte *) dp->d_name, len), Qt, hash); 792 Fputhash (make_string ((Intbyte *) dp->d_name, len), Qt, hash);
801 } 793 }
802 closedir (d); 794 qxe_closedir (d);
803 return hash; 795 return hash;
804 } 796 }
805 else 797 else
806 return Qnil; 798 return Qnil;
807 } 799 }
860 { 852 {
861 UNGCPRO; 853 UNGCPRO;
862 return call2 (handler, Qfile_attributes, filename); 854 return call2 (handler, Qfile_attributes, filename);
863 } 855 }
864 856
865 if (lstat ((char *) XSTRING_DATA (filename), &s) < 0) 857 if (qxe_lstat (XSTRING_DATA (filename), &s) < 0)
866 { 858 {
867 UNGCPRO; 859 UNGCPRO;
868 return Qnil; 860 return Qnil;
869 } 861 }
870 862
872 directory = Ffile_name_directory (filename); 864 directory = Ffile_name_directory (filename);
873 #endif 865 #endif
874 866
875 #if 0 /* #### shouldn't this apply to WIN32_NATIVE and maybe CYGWIN? */ 867 #if 0 /* #### shouldn't this apply to WIN32_NATIVE and maybe CYGWIN? */
876 { 868 {
877 char *tmpnam = (char *) XSTRING_DATA (Ffile_name_nondirectory (filename)); 869 Intbyte *tmpnam = XSTRING_DATA (Ffile_name_nondirectory (filename));
878 int l = strlen (tmpnam); 870 Bytecount l = qxestrlen (tmpnam);
879 871
880 if (l >= 5 872 if (l >= 5
881 && S_ISREG (s.st_mode) 873 && S_ISREG (s.st_mode)
882 && (stricmp (&tmpnam[l - 4], ".com") == 0 || 874 && (qxestrcasecmp (&tmpnam[l - 4], ".com") == 0 ||
883 stricmp (&tmpnam[l - 4], ".exe") == 0 || 875 qxestrcasecmp (&tmpnam[l - 4], ".exe") == 0 ||
884 stricmp (&tmpnam[l - 4], ".bat") == 0)) 876 qxestrcasecmp (&tmpnam[l - 4], ".bat") == 0))
885 { 877 {
886 s.st_mode |= S_IEXEC; 878 s.st_mode |= S_IEXEC;
887 } 879 }
888 } 880 }
889 #endif 881 #endif
917 values[8] = make_string ((Intbyte *) modes, 10); 909 values[8] = make_string ((Intbyte *) modes, 10);
918 #if defined (BSD4_2) || defined (BSD4_3) /* file gid will be dir gid */ 910 #if defined (BSD4_2) || defined (BSD4_3) /* file gid will be dir gid */
919 { 911 {
920 struct stat sdir; 912 struct stat sdir;
921 913
922 if (!NILP (directory) && xemacs_stat ((char *) XSTRING_DATA (directory), &sdir) == 0) 914 if (!NILP (directory) && qxe_stat (XSTRING_DATA (directory), &sdir) == 0)
923 values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil; 915 values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil;
924 else /* if we can't tell, assume worst */ 916 else /* if we can't tell, assume worst */
925 values[9] = Qt; 917 values[9] = Qt;
926 } 918 }
927 #else /* file gid will be egid */ 919 #else /* file gid will be egid */