X-Git-Url: http://git.chise.org/gitweb/?p=chise%2Fxemacs-chise.git.1;a=blobdiff_plain;f=src%2Fdired.c;h=e0639f9f656bf08cf5c4d7f034a1fc6f61068853;hp=472133ed857872020dfe918ab544528e19a3d5b6;hb=1a5e625ffcc6b2e9a9828a89763c062a0b09b361;hpb=976b002b16336930724ae22476014583ad022e7d diff --git a/src/dired.c b/src/dired.c index 472133e..e0639f9 100644 --- a/src/dired.c +++ b/src/dired.c @@ -23,16 +23,17 @@ Boston, MA 02111-1307, USA. */ #include #include "lisp.h" -#include "buffer.h" -#include "commands.h" -#include "elhash.h" -#include "regex.h" -#include "opaque.h" #include "sysfile.h" #include "sysdir.h" #include "systime.h" #include "sysdep.h" #include "syspwd.h" +#include "buffer.h" +#include "commands.h" +#include "elhash.h" +#include "regex.h" +#include "opaque.h" +#include "syntax.h" Lisp_Object Vcompletion_ignored_extensions; Lisp_Object Qdirectory_files; @@ -110,7 +111,7 @@ If FILES-ONLY is the symbol t, then only the "files" in the directory /* MATCH might be a flawed regular expression. Rather than catching and signalling our own errors, we just call compile_pattern to do the work for us. */ - bufp = compile_pattern (match, 0, 0, 0, ERROR_ME); + bufp = compile_pattern (match, 0, Qnil, 0, ERROR_ME); } /* Now *bufp is the compiled form of MATCH; don't call anything @@ -123,6 +124,10 @@ If FILES-ONLY is the symbol t, then only the "files" in the directory if (!d) report_file_error ("Opening directory", list1 (directory)); + /* #### In Matt's code, this was Qt. Why? */ + regex_match_object = Qnil; + regex_emacs_buffer = current_buffer; + record_unwind_protect (close_directory_unwind, make_opaque_ptr ((void *)d)); /* Loop reading blocks */ @@ -146,7 +151,7 @@ If FILES-ONLY is the symbol t, then only the "files" in the directory memcpy (statbuf_tail, dp->d_name, len); statbuf_tail[len] = 0; - if (stat (statbuf, &st) == 0 + if (xemacs_stat (statbuf, &st) == 0 && (st.st_mode & S_IFMT) == S_IFDIR) dir_p = 1; @@ -179,18 +184,18 @@ static Lisp_Object file_name_completion (Lisp_Object file, int all_flag, int ver_flag); DEFUN ("file-name-completion", Ffile_name_completion, 2, 2, 0, /* -Complete file name FILE in directory DIRECTORY. -Returns the longest string common to all filenames in DIRECTORY -that start with FILE. -If there is only one and FILE matches it exactly, returns t. -Returns nil if DIRECTORY contains no name starting with FILE. - -Filenames which end with any member of `completion-ignored-extensions' -are not considered as possible completions for FILE unless there is no -other possible completion. `completion-ignored-extensions' is not applied -to the names of directories. +Complete file name PARTIAL-FILENAME in directory DIRECTORY. +Return the longest prefix common to all file names in DIRECTORY +that start with PARTIAL-FILENAME. +If there is only one and PARTIAL-FILENAME matches it exactly, return t. +Return nil if DIRECTORY contains no name starting with PARTIAL-FILENAME. + +File names which end with any member of `completion-ignored-extensions' +are not considered as possible completions for PARTIAL-FILENAME unless +there is no other possible completion. `completion-ignored-extensions' +is not applied to the names of directories. */ - (file, directory)) + (partial_filename, directory)) { /* This function can GC. GC checked 1996.04.06. */ Lisp_Object handler; @@ -199,27 +204,22 @@ to the names of directories. call the corresponding file handler. */ handler = Ffind_file_name_handler (directory, Qfile_name_completion); if (!NILP (handler)) - return call3 (handler, Qfile_name_completion, file, directory); + return call3 (handler, Qfile_name_completion, partial_filename, directory); /* If the file name has special constructs in it, call the corresponding file handler. */ - handler = Ffind_file_name_handler (file, Qfile_name_completion); + handler = Ffind_file_name_handler (partial_filename, Qfile_name_completion); if (!NILP (handler)) - return call3 (handler, Qfile_name_completion, file, directory); + return call3 (handler, Qfile_name_completion, partial_filename, directory); - return file_name_completion (file, directory, 0, 0); + return file_name_completion (partial_filename, directory, 0, 0); } DEFUN ("file-name-all-completions", Ffile_name_all_completions, 2, 2, 0, /* -Return a list of all completions of file name FILE in directory DIRECTORY. -These are all file names in directory DIRECTORY which begin with FILE. - -File names which end with any member of `completion-ignored-extensions' -are not considered as possible completions for FILE unless there is no -other possible completion. `completion-ignored-extensions' is not applied -to the names of directories. +Return a list of all completions of PARTIAL-FILENAME in DIRECTORY. +These are all file names in DIRECTORY which begin with PARTIAL-FILENAME. */ - (file, directory)) + (partial_filename, directory)) { /* This function can GC. GC checked 1997.06.04. */ Lisp_Object handler; @@ -232,10 +232,10 @@ to the names of directories. handler = Ffind_file_name_handler (directory, Qfile_name_all_completions); UNGCPRO; if (!NILP (handler)) - return call3 (handler, Qfile_name_all_completions, file, + return call3 (handler, Qfile_name_all_completions, partial_filename, directory); - return file_name_completion (file, directory, 1, 0); + return file_name_completion (partial_filename, directory, 1, 0); } static int @@ -260,9 +260,9 @@ file_name_completion_stat (Lisp_Object directory, DIRENTRY *dp, in case it is a directory. */ value = lstat (fullname, st_addr); if (S_ISLNK (st_addr->st_mode)) - stat (fullname, st_addr); + xemacs_stat (fullname, st_addr); #else - value = stat (fullname, st_addr); + value = xemacs_stat (fullname, st_addr); #endif return value; } @@ -303,11 +303,11 @@ file_name_completion (Lisp_Object file, Lisp_Object directory, int all_flag, CHECK_STRING (file); -#ifdef WINDOWSNT +#ifdef WIN32_NATIVE /* Filename completion on Windows ignores case, since Windows filesystems do. */ specbind (Qcompletion_ignore_case, Qt); -#endif /* WINDOWSNT */ +#endif /* WIN32_NATIVE */ #ifdef FILE_SYSTEM_CASE file = FILE_SYSTEM_CASE (file); @@ -507,58 +507,65 @@ file_name_completion (Lisp_Object file, Lisp_Object directory, int all_flag, -/* The *pwent() functions do not exist on NT */ -#ifndef WINDOWSNT +/* The *pwent() functions do not exist on NT. #### The NT equivalent + is NetUserEnum(), and rewriting to use it is not hard.*/ +#ifndef WIN32_NATIVE static Lisp_Object user_name_completion (Lisp_Object user, int all_flag, int *uniq); DEFUN ("user-name-completion", Fuser_name_completion, 1, 1, 0, /* -Complete user name USER. - -Returns the longest string common to all user names that start -with USER. If there is only one and USER matches it exactly, -returns t. Returns nil if there is no user name starting with USER. +Complete user name from PARTIAL-USERNAME. +Return the longest prefix common to all user names starting with +PARTIAL-USERNAME. If there is only one and PARTIAL-USERNAME matches +it exactly, returns t. Return nil if there is no user name starting +with PARTIAL-USERNAME. */ - (user)) + (partial_username)) { - return user_name_completion (user, 0, NULL); + return user_name_completion (partial_username, 0, NULL); } DEFUN ("user-name-completion-1", Fuser_name_completion_1, 1, 1, 0, /* -Complete user name USER. +Complete user name from PARTIAL-USERNAME. This function is identical to `user-name-completion', except that the cons of the completion and an indication of whether the completion was unique is returned. -The car of the returned value is the longest string common to all -user names that start with USER. If there is only one and USER -matches it exactly, the car is t. The car is nil if there is no -user name starting with USER. The cdr of the result is non-nil -if and only if the completion returned in the car was unique. +The car of the returned value is the longest prefix common to all user +names that start with PARTIAL-USERNAME. If there is only one and +PARTIAL-USERNAME matches it exactly, the car is t. The car is nil if +there is no user name starting with PARTIAL-USERNAME. The cdr of the +result is non-nil if and only if the completion returned in the car +was unique. */ - (user)) + (partial_username)) { int uniq; - Lisp_Object completed; - - completed = user_name_completion (user, 0, &uniq); + Lisp_Object completed = user_name_completion (partial_username, 0, &uniq); return Fcons (completed, uniq ? Qt : Qnil); } DEFUN ("user-name-all-completions", Fuser_name_all_completions, 1, 1, 0, /* -Return a list of all completions of user name USER. -These are all user names which begin with USER. +Return a list of all user name completions from PARTIAL-USERNAME. +These are all the user names which begin with PARTIAL-USERNAME. */ - (user)) + (partial_username)) { - return user_name_completion (user, 1, NULL); + return user_name_completion (partial_username, 1, NULL); } -struct user_cache { - char **data; +struct user_name +{ + Bufbyte *ptr; + size_t len; +}; + +struct user_cache +{ + struct user_name *user_names; int length; int size; EMACS_TIME last_rebuild_time; @@ -570,27 +577,26 @@ free_user_cache (struct user_cache *cache) { int i; for (i = 0; i < cache->length; i++) - xfree (cache->data[i]); - xfree (cache->data); + xfree (cache->user_names[i].ptr); + xfree (cache->user_names); + xzero (*cache); } static Lisp_Object -user_name_completion_unwind (Lisp_Object locative) +user_name_completion_unwind (Lisp_Object cache_incomplete_p) { - int interrupted = !NILP (XCAR (locative)); + endpwent (); + speed_up_interrupts (); - if (interrupted) - { - endpwent (); - speed_up_interrupts (); - free_user_cache (&user_cache); - } - free_cons (XCONS (locative)); + if (! NILP (XCAR (cache_incomplete_p))) + free_user_cache (&user_cache); + + free_cons (XCONS (cache_incomplete_p)); return Qnil; } -#define USER_CACHE_REBUILD (24*60*60) /* 1 day, in seconds */ +#define USER_CACHE_TTL (24*60*60) /* Time to live: 1 day, in seconds */ static Lisp_Object user_name_completion (Lisp_Object user, int all_flag, int *uniq) @@ -599,7 +605,6 @@ user_name_completion (Lisp_Object user, int all_flag, int *uniq) int matchcount = 0; Lisp_Object bestmatch = Qnil; Charcount bestmatchsize = 0; - int speccount = specpdl_depth (); Charcount user_name_length; EMACS_TIME t; int i; @@ -614,41 +619,42 @@ user_name_completion (Lisp_Object user, int all_flag, int *uniq) /* Cache user name lookups because it tends to be quite slow. * Rebuild the cache occasionally to catch changes */ EMACS_GET_TIME (t); - if (user_cache.data && + if (user_cache.user_names && (EMACS_SECS (t) - EMACS_SECS (user_cache.last_rebuild_time) - > USER_CACHE_REBUILD)) - { - free_user_cache (&user_cache); - xzero (user_cache); - } + > USER_CACHE_TTL)) + free_user_cache (&user_cache); - if (!user_cache.data) + if (!user_cache.user_names) { struct passwd *pwd; - Lisp_Object locative = noseeum_cons (Qt, Qnil); + Lisp_Object cache_incomplete_p = noseeum_cons (Qt, Qnil); + int speccount = specpdl_depth (); + slow_down_interrupts (); setpwent (); - record_unwind_protect (user_name_completion_unwind, locative); + record_unwind_protect (user_name_completion_unwind, cache_incomplete_p); while ((pwd = getpwent ())) { - Bufbyte *pwuser; QUIT; - DO_REALLOC (user_cache.data, user_cache.size, - user_cache.length + 1, char *); - GET_C_CHARPTR_INT_DATA_ALLOCA (pwd->pw_name, FORMAT_OS, pwuser); - user_cache.data[user_cache.length++] = xstrdup (pwuser); + DO_REALLOC (user_cache.user_names, user_cache.size, + user_cache.length + 1, struct user_name); + TO_INTERNAL_FORMAT (C_STRING, pwd->pw_name, + MALLOC, + (user_cache.user_names[user_cache.length].ptr, + user_cache.user_names[user_cache.length].len), + Qnative); + user_cache.length++; } - endpwent (); - speed_up_interrupts (); - XCAR (locative) = Qnil; - unbind_to (speccount, Qnil); /* free locative cons */ + XCAR (cache_incomplete_p) = Qnil; + unbind_to (speccount, Qnil); + EMACS_GET_TIME (user_cache.last_rebuild_time); } for (i = 0; i < user_cache.length; i++) { - Bufbyte *u_name = user_cache.data[i]; - Bytecount len = strlen ((char *) u_name); + Bufbyte *u_name = user_cache.user_names[i].ptr; + Bytecount len = user_cache.user_names[i].len; /* scmp() works in chars, not bytes, so we have to compute this: */ Charcount cclen = bytecount_to_charcount (u_name, len); @@ -703,11 +709,11 @@ user_name_completion (Lisp_Object user, int all_flag, int *uniq) return Qt; return Fsubstring (bestmatch, Qzero, make_int (bestmatchsize)); } -#endif /* ! defined WINDOWSNT */ +#endif /* ! defined WIN32_NATIVE */ Lisp_Object -make_directory_hash_table (CONST char *path) +make_directory_hash_table (const char *path) { DIR *d; if ((d = opendir (path))) @@ -730,6 +736,9 @@ make_directory_hash_table (CONST char *path) return Qnil; } +#if 0 +/* ... never used ... should use list2 directly anyway ... */ +/* NOTE: This function can never return a negative value. */ Lisp_Object wasteful_word_to_lisp (unsigned int item) { @@ -739,6 +748,7 @@ wasteful_word_to_lisp (unsigned int item) XCDR (cons) = Fcons (XCDR (cons), Qnil); return cons; } +#endif DEFUN ("file-attributes", Ffile_attributes, 1, 1, 0, /* Return a list of attributes of file FILENAME. @@ -792,7 +802,7 @@ If file does not exist, returns nil. directory = Ffile_name_directory (filename); #endif -#ifdef MSDOS +#if 0 /* #### shouldn't this apply to WIN32_NATIVE and maybe CYGWIN? */ { char *tmpnam = (char *) XSTRING_DATA (Ffile_name_nondirectory (filename)); int l = strlen (tmpnam); @@ -806,7 +816,7 @@ If file does not exist, returns nil. s.st_mode |= S_IEXEC; } } -#endif /* MSDOS */ +#endif switch (s.st_mode & S_IFMT) { @@ -825,9 +835,9 @@ If file does not exist, returns nil. values[1] = make_int (s.st_nlink); values[2] = make_int (s.st_uid); values[3] = make_int (s.st_gid); - values[4] = wasteful_word_to_lisp (s.st_atime); - values[5] = wasteful_word_to_lisp (s.st_mtime); - values[6] = wasteful_word_to_lisp (s.st_ctime); + values[4] = make_time (s.st_atime); + values[5] = make_time (s.st_mtime); + values[6] = make_time (s.st_ctime); values[7] = make_int ((EMACS_INT) s.st_size); /* If the size is out of range, give back -1. */ /* #### Fix when Emacs gets bignums! */ @@ -839,7 +849,7 @@ If file does not exist, returns nil. { struct stat sdir; - if (!NILP (directory) && stat ((char *) XSTRING_DATA (directory), &sdir) == 0) + if (!NILP (directory) && xemacs_stat ((char *) XSTRING_DATA (directory), &sdir) == 0) values[9] = (sdir.st_gid != s.st_gid) ? Qt : Qnil; else /* if we can't tell, assume worst */ values[9] = Qt; @@ -869,7 +879,7 @@ syms_of_dired (void) DEFSUBR (Fdirectory_files); DEFSUBR (Ffile_name_completion); DEFSUBR (Ffile_name_all_completions); -#ifndef WINDOWSNT +#ifndef WIN32_NATIVE DEFSUBR (Fuser_name_completion); DEFSUBR (Fuser_name_completion_1); DEFSUBR (Fuser_name_all_completions); @@ -884,8 +894,7 @@ vars_of_dired (void) *Completion ignores filenames ending in any string in this list. This variable does not affect lists of possible completions, but does affect the commands that actually do completions. -It is used by the functions `file-name-completion' and -`file-name-all-completions'. +It is used by the function `file-name-completion'. */ ); Vcompletion_ignored_extensions = Qnil; }