#include <config.h>
#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;
/* 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
if (!d)
report_file_error ("Opening directory", list1 (directory));
+ regex_match_object = Qt;
+ regex_emacs_buffer = current_buffer;
+
record_unwind_protect (close_directory_unwind, make_opaque_ptr ((void *)d));
/* Loop reading blocks */
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;
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;
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.
+Return a list of all completions of PARTIAL-FILENAME in DIRECTORY.
+These are all file names in DIRECTORY which begin with PARTIAL-FILENAME.
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.
+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 1997.06.04. */
Lisp_Object handler;
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
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;
}
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);
\f
-/* 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;
{
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)
int matchcount = 0;
Lisp_Object bestmatch = Qnil;
Charcount bestmatchsize = 0;
- int speccount = specpdl_depth ();
Charcount user_name_length;
EMACS_TIME t;
int i;
/* 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);
return Qt;
return Fsubstring (bestmatch, Qzero, make_int (bestmatchsize));
}
-#endif /* ! defined WINDOWSNT */
+#endif /* ! defined WIN32_NATIVE */
\f
Lisp_Object
-make_directory_hash_table (CONST char *path)
+make_directory_hash_table (const char *path)
{
DIR *d;
if ((d = opendir (path)))
return Qnil;
}
\f
+#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)
{
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.
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);
s.st_mode |= S_IEXEC;
}
}
-#endif /* MSDOS */
+#endif
switch (s.st_mode & S_IFMT)
{
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! */
{
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;
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);