#endif /* HPUX_PRE_8_0 */
#endif /* HPUX */
+#if defined(WIN32_NATIVE) || defined(CYGWIN)
+#define WIN32_FILENAMES
#ifdef WIN32_NATIVE
+#include "nt.h"
+#endif /* WIN32_NATIVE */
#define IS_DRIVE(x) isalpha (x)
/* Need to lower-case the drive letter, or else expanded
filenames will sometimes compare inequal, because
`expand-file-name' doesn't always down-case the drive letter. */
#define DRIVE_LETTER(x) tolower (x)
-#endif /* WIN32_NATIVE */
+#ifndef CORRECT_DIR_SEPS
+#define CORRECT_DIR_SEPS(s) \
+ normalize_filename(s, DIRECTORY_SEP)
+/* Default implementation that coerces a file to use path_sep. */
+static void
+normalize_filename (Bufbyte *fp, Bufbyte path_sep)
+{
+ /* Always lower-case drive letters a-z, even if the filesystem
+ preserves case in filenames.
+ This is so filenames can be compared by string comparison
+ functions that are case-sensitive. Even case-preserving filesystems
+ do not distinguish case in drive letters. */
+ if (fp[1] == ':' && *fp >= 'A' && *fp <= 'Z')
+ {
+ *fp += 'a' - 'A';
+ fp += 2;
+ }
+
+ while (*fp)
+ {
+ if (*fp == '/' || *fp == '\\')
+ *fp = path_sep;
+ fp++;
+ }
+}
+#endif /* CORRECT_DIR_SEPS */
+#endif /* WIN32_NATIVE || CYGWIN */
int lisp_to_time (Lisp_Object, time_t *);
Lisp_Object time_to_lisp (time_t);
/* File name in which we write a list of all our auto save files. */
Lisp_Object Vauto_save_list_file_name;
+/* Prefix used to construct Vauto_save_list_file_name. */
+Lisp_Object Vauto_save_list_file_prefix;
+
+/* When non-nil, it prevents auto-save list file creation. */
+int inhibit_auto_save_session;
+
int disable_auto_save_when_buffer_shrinks;
Lisp_Object Vdirectory_sep_char;
any handlers that are members of `inhibit-file-name-handlers',
but we still do run any other handlers. This lets handlers
use the standard functions without calling themselves recursively.
+
+Otherwise, OPERATION is the name of a funcall'able function.
*/
(filename, operation))
{
\f
DEFUN ("file-name-directory", Ffile_name_directory, 1, 1, 0, /*
-Return the directory component in file name NAME.
-Return nil if NAME does not include a directory.
+Return the directory component in file name FILENAME.
+Return nil if FILENAME does not include a directory.
Otherwise return a directory spec.
Given a Unix syntax file name, returns a string ending in slash.
*/
- (file))
+ (filename))
{
/* This function can GC. GC checked 2000-07-28 ben */
Bufbyte *beg;
Bufbyte *p;
Lisp_Object handler;
- CHECK_STRING (file);
+ CHECK_STRING (filename);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (file, Qfile_name_directory);
+ handler = Ffind_file_name_handler (filename, Qfile_name_directory);
if (!NILP (handler))
- return call2_check_string_or_nil (handler, Qfile_name_directory, file);
+ return call2_check_string_or_nil (handler, Qfile_name_directory, filename);
#ifdef FILE_SYSTEM_CASE
- file = FILE_SYSTEM_CASE (file);
+ filename = FILE_SYSTEM_CASE (filename);
#endif
- beg = XSTRING_DATA (file);
- p = beg + XSTRING_LENGTH (file);
+ beg = XSTRING_DATA (filename);
+ p = beg + XSTRING_LENGTH (filename);
while (p != beg && !IS_ANY_SEP (p[-1])
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
/* only recognize drive specifier at beginning */
&& !(p[-1] == ':' && p == beg + 2)
#endif
}
DEFUN ("file-name-nondirectory", Ffile_name_nondirectory, 1, 1, 0, /*
-Return file name NAME sans its directory.
+Return file name FILENAME sans its directory.
For example, in a Unix-syntax file name,
this is everything after the last slash,
or the entire name if it contains no slash.
*/
- (file))
+ (filename))
{
/* This function can GC. GC checked 2000-07-28 ben */
Bufbyte *beg, *p, *end;
Lisp_Object handler;
- CHECK_STRING (file);
+ CHECK_STRING (filename);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (file, Qfile_name_nondirectory);
+ handler = Ffind_file_name_handler (filename, Qfile_name_nondirectory);
if (!NILP (handler))
- return call2_check_string (handler, Qfile_name_nondirectory, file);
+ return call2_check_string (handler, Qfile_name_nondirectory, filename);
- beg = XSTRING_DATA (file);
- end = p = beg + XSTRING_LENGTH (file);
+ beg = XSTRING_DATA (filename);
+ end = p = beg + XSTRING_LENGTH (filename);
while (p != beg && !IS_ANY_SEP (p[-1])
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
/* only recognize drive specifier at beginning */
&& !(p[-1] == ':' && p == beg + 2)
#endif
The `call-process' and `start-process' functions use this function to
get a current directory to run processes in.
*/
- (filename))
+ (filename))
{
/* This function can GC. GC checked 2000-07-28 ben */
Lisp_Object handler;
For a Unix-syntax file name, just appends a slash,
except for (file-name-as-directory \"\") => \"./\".
*/
- (file))
+ (filename))
{
/* This function can GC. GC checked 2000-07-28 ben */
char *buf;
Lisp_Object handler;
- CHECK_STRING (file);
+ CHECK_STRING (filename);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (file, Qfile_name_as_directory);
+ handler = Ffind_file_name_handler (filename, Qfile_name_as_directory);
if (!NILP (handler))
- return call2_check_string (handler, Qfile_name_as_directory, file);
+ return call2_check_string (handler, Qfile_name_as_directory, filename);
- buf = (char *) alloca (XSTRING_LENGTH (file) + 10);
+ buf = (char *) alloca (XSTRING_LENGTH (filename) + 10);
return build_string (file_name_as_directory
- (buf, (char *) XSTRING_DATA (file)));
+ (buf, (char *) XSTRING_DATA (filename)));
}
\f
/*
strcpy (dst, src);
if (slen > 1
&& IS_DIRECTORY_SEP (dst[slen - 1])
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
&& !IS_ANY_SEP (dst[slen - 2])
-#endif /* WIN32_NATIVE */
+#endif /* WIN32_FILENAMES */
)
dst[slen - 1] = 0;
return 1;
}
DEFUN ("directory-file-name", Fdirectory_file_name, 1, 1, 0, /*
-Return the file name of the directory named DIR.
-This is the name of the file that holds the data for the directory DIR.
+Return the file name of the directory named DIRECTORY.
+This is the name of the file that holds the data for the directory.
This operation exists because a directory is also a file, but its name as
a directory is different from its name as a file.
In Unix-syntax, this function just removes the final slash.
Convert filename NAME to absolute, and canonicalize it.
Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative
(does not start with slash); if DEFAULT-DIRECTORY is nil or missing,
-the current buffer's value of default-directory is used.
+the current buffer's value of `default-directory' is used.
File name components that are `.' are removed, and
so are file name components followed by `..', along with the `..' itself;
note that these simplifications are done without checking the resulting
*/
(name, default_directory))
{
- /* This function can GC. GC-checked 2000-07-11 ben */
+ /* This function can GC. GC-checked 2000-11-18 */
Bufbyte *nm;
Bufbyte *newdir, *p, *o;
int tlen;
Bufbyte *target;
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
int drive = 0;
int collapse_newdir = 1;
-#else
+#endif
+#ifndef WIN32_NATIVE
struct passwd *pw;
-#endif /* WIN32_NATIVE */
+#endif /* WIN32_FILENAMES */
int length;
- Lisp_Object handler;
+ Lisp_Object handler = Qnil;
#ifdef CYGWIN
char *user;
#endif
- struct gcpro gcpro1, gcpro2;
+ struct gcpro gcpro1, gcpro2, gcpro3;
/* both of these get set below */
- GCPRO2 (name, default_directory);
+ GCPRO3 (name, default_directory, handler);
CHECK_STRING (name);
call the corresponding file handler. */
handler = Ffind_file_name_handler (name, Qexpand_file_name);
if (!NILP (handler))
- {
- UNGCPRO;
- return call3_check_string (handler, Qexpand_file_name, name,
- default_directory);
- }
+ RETURN_UNGCPRO (call3_check_string (handler, Qexpand_file_name,
+ name, default_directory));
/* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */
if (NILP (default_directory))
{
handler = Ffind_file_name_handler (default_directory, Qexpand_file_name);
if (!NILP (handler))
- {
- UNGCPRO;
- return call3 (handler, Qexpand_file_name, name, default_directory);
- }
+ RETURN_UNGCPRO (call3 (handler, Qexpand_file_name,
+ name, default_directory));
}
o = XSTRING_DATA (default_directory);
/* Save time in some common cases - as long as default_directory
is not relative, it can be canonicalized with name below (if it
is needed at all) without requiring it to be expanded now. */
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
/* Detect Windows file names with drive specifiers. */
&& ! (IS_DRIVE (o[0]) && (IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2])))
/* Detect Windows file names in UNC format. */
&& ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1]))
-
-#else /* not WIN32_NATIVE */
-
+#endif /* not WIN32_FILENAMES */
+#ifndef WIN32_NATIVE
/* Detect Unix absolute file names (/... alone is not absolute on
Windows). */
&& ! (IS_DIRECTORY_SEP (o[0]))
into name should be safe during all of this, though. */
nm = XSTRING_DATA (name);
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
/* We will force directory separators to be either all \ or /, so make
a local copy to modify, even if there ends up being no change. */
- nm = strcpy ((char *)alloca (strlen ((char *)nm) + 1), (char *)nm);
+ nm = (Bufbyte *) strcpy ((char *) alloca (strlen ((char *) nm) + 1),
+ (char *) nm);
/* Find and remove drive specifier if present; this makes nm absolute
even if the rest of the name appears to be relative. */
Bufbyte *colon = (Bufbyte *) strrchr ((char *)nm, ':');
if (colon)
+ {
/* Only recognize colon as part of drive specifier if there is a
single alphabetic character preceding the colon (and if the
character before the drive letter, if present, is a directory
if (colon[0] == ':')
goto look_again;
}
+ }
}
/* If we see "c://somedir", we want to strip the first slash after the
"//somedir". */
if (drive && IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
nm++;
-#endif /* WIN32_NATIVE */
+#endif /* WIN32_FILENAMES */
/* If nm is absolute, look for /./ or /../ sequences; if none are
found, we can probably return right away. We will avoid allocating
}
if (!lose)
{
-#ifdef WIN32_NATIVE
- /* Make sure directories are all separated with / or \ as
- desired, but avoid allocation of a new string when not
- required. */
- CORRECT_DIR_SEPS (nm);
- if (IS_DIRECTORY_SEP (nm[1]))
+#ifdef WIN32_FILENAMES
+ if (drive || IS_DIRECTORY_SEP (nm[1]))
{
- if (strcmp (nm, XSTRING_DATA (name)) != 0)
- name = build_string (nm);
- }
- /* drive must be set, so this is okay */
- else if (strcmp (nm - 2, XSTRING_DATA (name)) != 0)
- {
- name = make_string (nm - 2, p - nm + 2);
- XSTRING_DATA (name)[0] = DRIVE_LETTER (drive);
- XSTRING_DATA (name)[1] = ':';
+ /* Make sure directories are all separated with / or \ as
+ desired, but avoid allocation of a new string when not
+ required. */
+ CORRECT_DIR_SEPS (nm);
+ if (IS_DIRECTORY_SEP (nm[1]))
+ {
+ if (strcmp ((char *) nm, (char *) XSTRING_DATA (name)) != 0)
+ name = build_string ((Bufbyte *) nm);
+ }
+ /* drive must be set, so this is okay */
+ else if (strcmp ((char *) nm - 2,
+ (char *) XSTRING_DATA (name)) != 0)
+ {
+ name = make_string (nm - 2, p - nm + 2);
+ XSTRING_DATA (name)[0] = DRIVE_LETTER (drive);
+ XSTRING_DATA (name)[1] = ':';
+ }
+ RETURN_UNGCPRO (name);
}
- RETURN_UNGCPRO (name);
-#else /* not WIN32_NATIVE */
+#endif /* not WIN32_FILENAMES */
+#ifndef WIN32_NATIVE
if (nm == XSTRING_DATA (name))
RETURN_UNGCPRO (name);
RETURN_UNGCPRO (build_string ((char *) nm));
Qfile_name);
nm++;
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
collapse_newdir = 0;
#endif
}
memcpy (o, (char *) nm, p - nm);
o [p - nm] = 0;
- /* #### marcpa's syncing note: FSF uses getpwnam even on NT,
- which does not work. The following works only if ~USER
- names the user who runs this instance of XEmacs. While
- NT is single-user (for the moment) you still can have
- multiple user profiles users defined, each with its HOME.
- Therefore, the following should be reworked to handle
- this case. */
-#ifdef WIN32_NATIVE
- /* Now if the file given is "~foo/file" and HOME="c:/", then
- we want the file to be named "c:/file" ("~foo" becomes
- "c:/"). The variable o has "~foo", so we can use the
- length of that string to offset nm. August Hill, 31 Aug
- 1998. */
- newdir = (Bufbyte *) get_home_directory();
- dostounix_filename (newdir);
- nm += strlen(o) + 1;
-#else /* not WIN32_NATIVE */
+ /* #### While NT is single-user (for the moment) you still
+ can have multiple user profiles users defined, each with
+ its HOME. So maybe possibly we should think about handling
+ ~user. --ben */
+#ifndef WIN32_NATIVE
#ifdef CYGWIN
if ((user = user_login_name (NULL)) != NULL)
{
}
}
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
/* On DOS and Windows, nm is absolute if a drive name was specified;
use the drive's current directory as the prefix if needed. */
if (!newdir && drive)
{
+#ifdef WIN32_NATIVE
/* Get default directory if needed to make nm absolute. */
if (!IS_DIRECTORY_SEP (nm[0]))
{
- newdir = alloca (MAXPATHLEN + 1);
+ newdir = (Bufbyte *) alloca (MAXPATHLEN + 1);
if (!_getdcwd (toupper (drive) - 'A' + 1, newdir, MAXPATHLEN))
newdir = NULL;
}
+#endif /* WIN32_NATIVE */
if (!newdir)
{
/* Either nm starts with /, or drive isn't mounted. */
- newdir = alloca (4);
+ newdir = (Bufbyte *) alloca (4);
newdir[0] = DRIVE_LETTER (drive);
newdir[1] = ':';
newdir[2] = '/';
newdir[3] = 0;
}
}
-#endif /* WIN32_NATIVE */
+#endif /* WIN32_FILENAMES */
/* Finally, if no prefix has been specified and nm is not absolute,
then it must be expanded relative to default_directory. */
#ifndef WIN32_NATIVE
/* /... alone is not absolute on DOS and Windows. */
&& !IS_DIRECTORY_SEP (nm[0])
-#else
+#endif
+#ifdef WIN32_FILENAMES
&& !(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
#endif
&& !newdir)
newdir = XSTRING_DATA (default_directory);
}
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
if (newdir)
{
/* First ensure newdir is an absolute name. */
&& ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
/* Detect drive spec by itself */
&& ! (IS_DEVICE_SEP (newdir[1]) && newdir[2] == 0)
+ /* Detect unix format. */
+#ifndef WIN32_NATIVE
+ && ! (IS_DIRECTORY_SEP (newdir[0]))
+#endif
)
{
/* Effectively, let newdir be (expand-file-name newdir cwd).
}
if (!IS_DIRECTORY_SEP (nm[0]))
{
- char * tmp = alloca (strlen (newdir) + strlen (nm) + 2);
- file_name_as_directory (tmp, newdir);
- strcat (tmp, nm);
+ Bufbyte *tmp = (Bufbyte *) alloca (strlen ((char *) newdir) +
+ strlen ((char *) nm) + 2);
+ file_name_as_directory ((char *) tmp, (char *) newdir);
+ strcat ((char *) tmp, (char *) nm);
nm = tmp;
}
- newdir = alloca (MAXPATHLEN + 1);
+ newdir = (Bufbyte *) alloca (MAXPATHLEN + 1);
if (drive)
{
+#ifdef WIN32_NATIVE
if (!_getdcwd (toupper (drive) - 'A' + 1, newdir, MAXPATHLEN))
- newdir = "/";
+#endif
+ newdir = (Bufbyte *) "/";
}
else
- getwd (newdir);
+ getcwd ((char *) newdir, MAXPATHLEN);
}
/* Strip off drive name from prefix, if present. */
/* Keep only a prefix from newdir if nm starts with slash
(/ /server/share for UNC, nothing otherwise). */
- if (IS_DIRECTORY_SEP (nm[0]) && collapse_newdir)
+ if (IS_DIRECTORY_SEP (nm[0])
+#ifndef WIN32_NATIVE
+ && IS_DIRECTORY_SEP (nm[1])
+#endif
+ && collapse_newdir)
{
if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
{
- newdir = strcpy (alloca (strlen (newdir) + 1), newdir);
+ newdir =
+ (Bufbyte *)
+ strcpy ((char *) alloca (strlen ((char *) newdir) + 1),
+ (char *) newdir);
p = newdir + 2;
while (*p && !IS_DIRECTORY_SEP (*p)) p++;
p++;
*p = 0;
}
else
- newdir = "";
+ newdir = (Bufbyte *) "";
}
}
-#endif /* WIN32_NATIVE */
+#endif /* WIN32_FILENAMES */
if (newdir)
{
just // (an incomplete UNC name). */
length = strlen ((char *) newdir);
if (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1])
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
&& !(length == 2 && IS_DIRECTORY_SEP (newdir[0]))
#endif
)
/* Now concatenate the directory and name to new space in the stack frame */
tlen += strlen ((char *) nm) + 1;
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
/* Add reserved space for drive name. (The Microsoft x86 compiler
produces incorrect code if the following two lines are combined.) */
target = (Bufbyte *) alloca (tlen + 2);
target += 2;
-#else /* not WIN32_NATIVE */
+#else /* not WIN32_FILENAMES */
target = (Bufbyte *) alloca (tlen);
-#endif /* not WIN32_NATIVE */
+#endif /* not WIN32_FILENAMES */
*target = 0;
if (newdir)
++o;
p += 3;
}
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
/* if drive is set, we're not dealing with an UNC, so
multiple dir-seps are redundant (and reportedly cause trouble
under win95) */
}
}
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
/* At last, set drive name, except for network file name. */
if (drive)
{
target[0] = DRIVE_LETTER (drive);
target[1] = ':';
}
+#ifdef WIN32_NATIVE
else
{
assert (IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1]));
}
+#endif
CORRECT_DIR_SEPS (target);
-#endif /* WIN32_NATIVE */
+#endif /* WIN32_FILENAMES */
RETURN_UNGCPRO (make_string (target, o - target));
}
DEFUN ("file-truename", Ffile_truename, 1, 2, 0, /*
-Return the canonical name of the given FILE.
-Second arg DEFAULT is directory to start with if FILE is relative
+Return the canonical name of FILENAME.
+Second arg DEFAULT is directory to start with if FILENAME is relative
(does not start with slash); if DEFAULT is nil or missing,
- the current buffer's value of default-directory is used.
+ the current buffer's value of `default-directory' is used.
No component of the resulting pathname will be a symbolic link, as
in the realpath() function.
*/
TO_EXTERNAL_FORMAT (LISP_STRING, expanded_name,
ALLOCA, (path, elen),
Qfile_name);
+
+#if defined(WIN32_FILENAMES) && defined(CYGWIN)
+ /* When using win32 filenames in cygwin we want file-truename to
+ detect that c:/windows == /windows for example. */
+ if ((IS_DIRECTORY_SEP (path[0])
+ && (elen == 1 || !IS_DIRECTORY_SEP (path[1])))
+ || (isalpha (path[0])
+ && (elen == 1 || !IS_DEVICE_SEP (path[1])))) {
+ int ltwff2 =
+ cygwin_posix_to_win32_path_list_buf_size (path);
+ p = (Bufbyte *) alloca (ltwff2);
+ cygwin_posix_to_win32_path_list (path, p);
+ path = p;
+ }
+#endif
p = path;
+
if (elen > MAXPATHLEN)
goto toolong;
we just use our own version in realpath.c. */
for (;;)
{
- p = (Extbyte *) memchr (p + 1, '/', elen - (p + 1 - path));
- if (p)
- *p = 0;
+ Extbyte *pos;
+
+#ifdef WIN32_FILENAMES
+ if (IS_DRIVE (p[0]) && IS_DEVICE_SEP (p[1])
+ && IS_DIRECTORY_SEP (p[2]))
+ /* don't test c: on windows */
+ p = p+2;
+ else if (IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1]))
+ /* start after // */
+ p = p+1;
+#endif
+ for (pos = p + 1; pos < path + elen; pos++)
+ if (IS_DIRECTORY_SEP (*pos))
+ {
+ *(p = pos) = 0;
+ break;
+ }
+ if (p != pos)
+ p = 0;
if (xrealpath ((char *) path, resolved_path))
{
if (p)
- *p = '/';
+ *p = DIRECTORY_SEP;
else
break;
{
int plen = elen - (p - path);
- if (rlen > 1 && resolved_path[rlen - 1] == '/')
+ if (rlen > 1 && IS_DIRECTORY_SEP (resolved_path[rlen - 1]))
rlen = rlen - 1;
if (plen + rlen + 1 > countof (resolved_path))
goto toolong;
- resolved_path[rlen] = '/';
+ resolved_path[rlen] = DIRECTORY_SEP;
memcpy (resolved_path + rlen + 1, p + 1, plen + 1 - 1);
}
break;
{
Lisp_Object resolved_name;
int rlen = strlen (resolved_path);
- if (elen > 0 && XSTRING_BYTE (expanded_name, elen - 1) == '/'
- && !(rlen > 0 && resolved_path[rlen - 1] == '/'))
+ if (elen > 0 && IS_DIRECTORY_SEP (XSTRING_BYTE (expanded_name, elen - 1))
+ && !(rlen > 0 && IS_DIRECTORY_SEP (resolved_path[rlen - 1])))
{
if (rlen + 1 > countof (resolved_path))
goto toolong;
- resolved_path[rlen++] = '/';
+ resolved_path[rlen++] = DIRECTORY_SEP;
resolved_path[rlen] = '\0';
}
TO_INTERNAL_FORMAT (DATA, (resolved_path, rlen),
Substitute environment variables referred to in FILENAME.
`$FOO' where FOO is an environment variable name means to substitute
the value of that variable. The variable name should be terminated
-with a character not a letter, digit or underscore; otherwise, enclose
+with a character, not a letter, digit or underscore; otherwise, enclose
the entire variable name in braces.
If `/~' appears, all of FILENAME through that `/' is discarded.
-
*/
- (string))
+ (filename))
{
/* This function can GC. GC checked 2000-07-28 ben. */
Bufbyte *nm;
Bufbyte *xnm;
Lisp_Object handler;
- CHECK_STRING (string);
+ CHECK_STRING (filename);
/* If the file name has special constructs in it,
call the corresponding file handler. */
- handler = Ffind_file_name_handler (string, Qsubstitute_in_file_name);
+ handler = Ffind_file_name_handler (filename, Qsubstitute_in_file_name);
if (!NILP (handler))
return call2_check_string_or_nil (handler, Qsubstitute_in_file_name,
- string);
+ filename);
- nm = XSTRING_DATA (string);
- endp = nm + XSTRING_LENGTH (string);
+ nm = XSTRING_DATA (filename);
+ endp = nm + XSTRING_LENGTH (filename);
/* If /~ or // appears, discard everything through first slash. */
for (p = nm; p != endp; p++)
{
if ((p[0] == '~'
-#if defined (WIN32_NATIVE) || defined (CYGWIN)
+#if defined (WIN32_FILENAMES)
/* // at start of file name is meaningful in WindowsNT systems */
|| (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm)
-#else /* not (WIN32_NATIVE || CYGWIN) */
+#else /* not (WIN32_FILENAMES) */
|| IS_DIRECTORY_SEP (p[0])
-#endif /* not (WIN32_NATIVE || CYGWIN) */
+#endif /* not (WIN32_FILENAMES) */
)
&& p != nm
&& (IS_DIRECTORY_SEP (p[-1])))
nm = p;
substituted = 1;
}
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
/* see comment in expand-file-name about drive specifiers */
else if (IS_DRIVE (p[0]) && p[1] == ':'
&& p > nm && IS_DIRECTORY_SEP (p[-1]))
nm = p;
substituted = 1;
}
-#endif /* WIN32_NATIVE */
+#endif /* WIN32_FILENAMES */
}
/* See if any variables are substituted into the string
}
if (!substituted)
- return string;
+ return filename;
- /* If substitution required, recopy the string and do it */
+ /* If substitution required, recopy the filename and do it */
/* Make space in stack frame for the new copy */
- xnm = (Bufbyte *) alloca (XSTRING_LENGTH (string) + total + 1);
+ xnm = (Bufbyte *) alloca (XSTRING_LENGTH (filename) + total + 1);
x = xnm;
/* Copy the rest of the name through, replacing $ constructs with values */
for (p = xnm; p != x; p++)
if ((p[0] == '~'
-#if defined (WIN32_NATIVE)
+#if defined (WIN32_FILENAMES)
|| (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm)
-#else /* not WIN32_NATIVE */
+#else /* not WIN32_FILENAMES */
|| IS_DIRECTORY_SEP (p[0])
-#endif /* not WIN32_NATIVE */
+#endif /* not WIN32_FILENAMES */
)
/* don't do p[-1] if that would go off the beginning --jwz */
&& p != nm && p > xnm && IS_DIRECTORY_SEP (p[-1]))
xnm = p;
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
else if (IS_DRIVE (p[0]) && p[1] == ':'
&& p > nm && IS_DIRECTORY_SEP (p[-1]))
xnm = p;
return make_string (xnm, x - xnm);
badsubst:
- syntax_error ("Bad format environment-variable substitution", string);
+ syntax_error ("Bad format environment-variable substitution", filename);
missingclose:
syntax_error ("Missing \"}\" in environment-variable substitution",
- string);
+ filename);
badvar:
syntax_error_2 ("Substituting nonexistent environment variable",
- string, build_string (target));
+ filename, build_string ((char *) target));
/* NOTREACHED */
return Qnil; /* suppress compiler warning */
DEFUN ("copy-file", Fcopy_file, 2, 4,
"fCopy file: \nFCopy %s to file: \np\nP", /*
-Copy FILE to NEWNAME. Both args must be strings.
+Copy FILENAME to NEWNAME. Both args must be strings.
Signals a `file-already-exists' error if file NEWNAME already exists,
unless a third argument OK-IF-ALREADY-EXISTS is supplied and non-nil.
A number as third arg means request confirmation if NEWNAME already exists.
EMACS_TIME atime, mtime;
EMACS_SET_SECS_USECS (atime, st.st_atime, 0);
EMACS_SET_SECS_USECS (mtime, st.st_mtime, 0);
- if (set_file_times ((char *) XSTRING_DATA (newname), atime,
- mtime))
+ if (set_file_times (newname, atime, mtime))
report_file_error ("I/O error", list1 (newname));
}
chmod ((const char *) XSTRING_DATA (newname),
\f
DEFUN ("rename-file", Frename_file, 2, 3,
"fRename file: \nFRename %s to file: \np", /*
-Rename FILE as NEWNAME. Both args strings.
-If file has names other than FILE, it continues to have those names.
+Rename FILENAME as NEWNAME. Both args must be strings.
+If file has names other than FILENAME, it continues to have those names.
Signals a `file-already-exists' error if a file NEWNAME already exists
unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
A number as third arg means request confirmation if NEWNAME already exists.
DEFUN ("add-name-to-file", Fadd_name_to_file, 2, 3,
"fAdd name to file: \nFName to add to %s: \np", /*
-Give FILE additional name NEWNAME. Both args strings.
+Give FILENAME additional name NEWNAME. Both args must be strings.
Signals a `file-already-exists' error if a file NEWNAME already exists
unless optional third argument OK-IF-ALREADY-EXISTS is non-nil.
A number as third arg means request confirmation if NEWNAME already exists.
CHECK_STRING (filename);
ptr = XSTRING_DATA (filename);
return (IS_DIRECTORY_SEP (*ptr) || *ptr == '~'
-#ifdef WIN32_NATIVE
+#ifdef WIN32_FILENAMES
|| (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2]))
#endif
) ? Qt : Qnil;
if (!NILP (handler))
RETURN_UNGCPRO (call2 (handler, Qfile_readable_p, abspath));
-#if defined(WIN32_NATIVE) || defined(CYGWIN)
+#if defined(WIN32_FILENAMES)
/* Under MS-DOS and Windows, open does not work for directories. */
UNGCPRO;
if (access (XSTRING_DATA (abspath), 0) == 0)
return Qt;
else
return Qnil;
-#else /* not WIN32_NATIVE */
+#else /* not WIN32_FILENAMES */
{
int desc = interruptible_open ((char *) XSTRING_DATA (abspath), O_RDONLY | OPEN_BINARY, 0);
UNGCPRO;
close (desc);
return Qt;
}
-#endif /* not WIN32_NATIVE */
+#endif /* not WIN32_FILENAMES */
}
/* Having this before file-symlink-p mysteriously caused it to be forgotten
}
\f
DEFUN ("file-modes", Ffile_modes, 1, 1, 0, /*
-Return mode bits of FILE, as an integer.
+Return mode bits of file named FILENAME, as an integer.
*/
(filename))
{
}
DEFUN ("set-file-modes", Fset_file_modes, 2, 2, 0, /*
-Set mode bits of FILE to MODE (an integer).
+Set mode bits of file named FILENAME to MODE (an integer).
Only the 12 low bits of MODE are used.
*/
(filename, mode))
DEFUN ("set-default-file-modes", Fset_default_file_modes, 1, 1, 0, /*
Set the file permission bits for newly created files.
-MASK should be an integer; if a permission's bit in MASK is 1,
-subsequently created files will not have that permission enabled.
-Only the low 9 bits are used.
+The argument MODE should be an integer; if a bit in MODE is 1,
+subsequently created files will not have the permission corresponding
+to that bit enabled. Only the low 9 bits are used.
This setting is inherited by subprocesses.
*/
(mode))
decoding is stored into it. It will in general be different from CODESYS
if CODESYS specifies automatic encoding detection or end-of-line detection.
-Currently BEG and END refer to byte positions (as opposed to character
+Currently START and END refer to byte positions (as opposed to character
positions), even in Mule. (Fixing this is very difficult.)
*/
- (filename, visit, beg, end, replace, codesys, used_codesys))
+ (filename, visit, start, end, replace, codesys, used_codesys))
{
/* This function can call lisp */
- /* #### dmoore - this function hasn't been checked for gc recently */
struct stat st;
int fd;
int saverrno = 0;
if (!NILP (handler))
{
val = call6 (handler, Qinsert_file_contents, filename,
- visit, beg, end, replace);
+ visit, start, end, replace);
goto handled;
}
CHECK_SYMBOL (used_codesys);
#endif
- if ( (!NILP (beg) || !NILP (end)) && !NILP (visit) )
+ if ( (!NILP (start) || !NILP (end)) && !NILP (visit) )
error ("Attempt to visit less than an entire file");
fd = -1;
#ifdef S_IFREG
/* Signal an error if we are accessing a non-regular file, with
- REPLACE, BEG or END being non-nil. */
+ REPLACE, START or END being non-nil. */
if (!S_ISREG (st.st_mode))
{
not_regular = 1;
if (!NILP (visit))
goto notfound;
- if (!NILP (replace) || !NILP (beg) || !NILP (end))
+ if (!NILP (replace) || !NILP (start) || !NILP (end))
{
end_multiple_change (buf, mc_count);
- return Fsignal (Qfile_error,
- list2 (build_translated_string("not a regular file"),
- filename));
+ RETURN_UNGCPRO
+ (Fsignal (Qfile_error,
+ list2 (build_translated_string("not a regular file"),
+ filename)));
}
}
#endif /* S_IFREG */
- if (!NILP (beg))
- CHECK_INT (beg);
+ if (!NILP (start))
+ CHECK_INT (start);
else
- beg = Qzero;
+ start = Qzero;
if (!NILP (end))
CHECK_INT (end);
same_at_end += overlap;
/* Arrange to read only the nonmatching middle part of the file. */
- beg = make_int (same_at_start - BUF_BEGV (buf));
+ start = make_int (same_at_start - BUF_BEGV (buf));
end = make_int (st.st_size - (BUF_ZV (buf) - same_at_end));
buffer_delete_range (buf, same_at_start, same_at_end,
if (!not_regular)
{
- total = XINT (end) - XINT (beg);
+ total = XINT (end) - XINT (start);
/* Make sure point-max won't overflow after this insertion. */
if (total != XINT (make_int (total)))
will make the stream functions read as much as possible. */
total = -1;
- if (XINT (beg) != 0
+ if (XINT (start) != 0
#ifdef FSFMACS_SPEEDY_INSERT
/* why was this here? asked jwz. The reason is that the replace-mode
connivings above will normally put the file pointer other than
#endif /* !FSFMACS_SPEEDY_INSERT */
)
{
- if (lseek (fd, XINT (beg), 0) < 0)
+ if (lseek (fd, XINT (start), 0) < 0)
report_file_error ("Setting file position", list1 (filename));
}
occurs inside of the filedesc stream. */
while (1)
{
- ssize_t this_len;
+ Lstream_data_count this_len;
Charcount cc_inserted;
QUIT;
it could be called here. But that's just silly.
There's no reason C code can't call out to Lisp
code, and it's a lot cleaner this way. */
+ /* Note: compute-buffer-file-truename is called for
+ side-effect! Its return value is intentionally
+ ignored. */
if (!NILP (Ffboundp (Qcompute_buffer_file_truename)))
call1 (Qcompute_buffer_file_truename, make_buffer (buf));
}
message ("Wrote %s", XSTRING_DATA (visit_file));
else
{
- Lisp_Object fsp;
+ Lisp_Object fsp = Qnil;
struct gcpro nngcpro1;
NNGCPRO1 (fsp);
\f
DEFUN ("verify-visited-file-modtime", Fverify_visited_file_modtime, 1, 1, 0, /*
-Return t if last mod time of BUF's visited file matches what BUF records.
+Return t if last mod time of BUFFER's visited file matches what BUFFER records.
This means that the file has not been changed since it was visited or saved.
*/
- (buf))
+ (buffer))
{
/* This function can call lisp; GC checked 2000-07-11 ben */
struct buffer *b;
struct stat st;
Lisp_Object handler;
- CHECK_BUFFER (buf);
- b = XBUFFER (buf);
+ CHECK_BUFFER (buffer);
+ b = XBUFFER (buffer);
if (!STRINGP (b->filename)) return Qt;
if (b->modtime == 0) return Qt;
handler = Ffind_file_name_handler (b->filename,
Qverify_visited_file_modtime);
if (!NILP (handler))
- return call2 (handler, Qverify_visited_file_modtime, buf);
+ return call2 (handler, Qverify_visited_file_modtime, buffer);
if (xemacs_stat ((char *) XSTRING_DATA (b->filename), &st) < 0)
{
}
else
{
- Lisp_Object filename;
+ Lisp_Object filename = Qnil;
struct stat st;
Lisp_Object handler;
struct gcpro gcpro1, gcpro2, gcpro3;
return
/* !!#### need to deal with this 'escape-quoted everywhere */
Fwrite_region_internal (Qnil, Qnil, a, Qnil, Qlambda, Qnil,
-#ifdef MULE
- Qescape_quoted
+#ifdef FILE_CODING
+ current_buffer->buffer_file_coding_system
#else
Qnil
#endif
/* Open the auto-save list file, if necessary.
We only do this now so that the file only exists
if we actually auto-saved any files. */
- if (!auto_saved && STRINGP (listfile) && listdesc < 0)
+ if (!auto_saved && !inhibit_auto_save_session
+ && !NILP (Vauto_save_list_file_prefix)
+ && STRINGP (listfile) && listdesc < 0)
{
listdesc = open ((char *) XSTRING_DATA (listfile),
O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY,
*/ );
Vauto_save_list_file_name = Qnil;
+ DEFVAR_LISP ("auto-save-list-file-prefix", &Vauto_save_list_file_prefix /*
+Prefix for generating auto-save-list-file-name.
+Emacs's pid and the system name will be appended to
+this prefix to create a unique file name.
+*/ );
+ Vauto_save_list_file_prefix = build_string ("~/.saves-");
+
+ DEFVAR_BOOL ("inhibit-auto-save-session", &inhibit_auto_save_session /*
+When non-nil, inhibit auto save list file creation.
+*/ );
+ inhibit_auto_save_session = 0;
+
DEFVAR_BOOL ("disable-auto-save-when-buffer-shrinks",
&disable_auto_save_when_buffer_shrinks /*
If non-nil, auto-saving is disabled when a buffer shrinks too much.