Commit 199607e4 authored by Richard M. Stallman's avatar Richard M. Stallman

(Fexpand_file_name, Ffile_name_absolute_p): Doc fixes.

(Ffile_exists_p, Ffile_executable_p, Ffile_readable_p)
(Ffile_writable_p, Ffile_directory_p, Ffile_regular_p)
(Ffile_modes, Fset_file_modes, Ffile_newer_than_file_p)
(expand_and_dir_to_file): Rename abspath to absname.

(CORRECT_DIR_SEPS) [DOS_NT]: New macro.
(IS_DRIVE) [DOS_NT]: Added separate definitions for DOS and NT.
(Ffile_name_directory) [DOS_NT]: Simplify code to match change in
getdefdir in msdos.c.  Ignore embedded colons.  Correct dir seps.
(Ffile_name_nondirectory) [DOS_NT]: Ignore embedded colons.
Correct IS_ANY_SEP to IS_DIRECTORY_SEP.
(file_name_as_directory) [DOS_NT]: Correct dir seps.
Correct IS_ANY_SEP to IS_DIRECTORY_SEP.
(directory_file_name) [DOS_NT]: Correct dir seps.
(Fmake_temp_name) [DOS_NT: Correct dir seps.
(Fexpand_file_name) [mostly DOS_NT]: Remove relpath, tmp and
defdir variables; init drive to 0.
Correctly detect when default_directory is absolute.
Be strict when looking for MSDOS drive specifier; defer calling
getdefdir.  Ignore drive specifier if name now has UNC prefix.
Correctly recognise if name is not absolute when trying simple
method to expand; return original string if possible.
Skip dir sep after ~ or ~user.
Use getpwnam instead of HOME for ~user on NT.
Handle error return from getdefdir.
Correctly detect if newdir is absolute before using default_directory.
Handle case where newdir is not absolute - expand relative to
current working dir if necessary (instead of calling getdisk
later).  Only keep UNC prefix if nm starts with dir sep.
Replace kludgy handling of drive spec in newdir.  Correct dir seps.
(Fexpand_file_name) [!DOS_NT]: Fix incorrect expansion of
"/foo/../bar" -> "//bar".
(Fsubstitute_in_file_name) [DOS_NT]: Correct dir seps for NT as
well.  Merge equivalent #ifdef APOLLO and WINDOWSNT cases.  Ignore
embedded colons and be strict about drive specs.
(Fcopy_file) [DOS_NT]: Do dev/inode check on NT.
(Ffile_name_absolute_p) [DOS_NT]: Be strict about drive specs.
(check_executable) [DOS_NT]: Test st_mode on NT.
(Ffile_readable_p) [DOS_NT]: Use access instead of open on NT.
(Ffile_modes) [DOS_NT]: Don't embelish st_mode value on NT.
(Fread_file_name) [DOS_NT]: Correct dir seps in HOME.
(syms_of_fileio): Add Vdirectory_sep_char.
parent 37513bdf
/* File IO for GNU Emacs.
Copyright (C) 1985, 86, 87, 88, 93, 94, 95 Free Software Foundation, Inc.
Copyright (C) 1985,86,87,88,93,94,95,96 Free Software Foundation, Inc.
This file is part of GNU Emacs.
......@@ -93,6 +93,21 @@ extern char *strerror ();
#include <fcntl.h>
#endif /* not WINDOWSNT */
#ifdef DOS_NT
#define CORRECT_DIR_SEPS(s) \
do { if ('/' == DIRECTORY_SEP) dostounix_filename (s); \
else unixtodos_filename (s); \
} while (0)
/* On Windows, drive letters must be alphabetic - on DOS, the Netware
redirector allows the six letters between 'Z' and 'a' as well. */
#ifdef MSDOS
#define IS_DRIVE(x) ((x) >= 'A' && (x) <= 'z')
#endif
#ifdef WINDOWSNT
#define IS_DRIVE(x) isalpha (x)
#endif
#endif
#ifdef VMS
#include <file.h>
#include <rmsdef.h>
......@@ -129,7 +144,7 @@ int auto_saving;
a new file with the same mode as the original */
int auto_save_mode_bits;
/* Alist of elements (REGEXP . HANDLER) for file names
/* Alist of elements (REGEXP . HANDLER) for file names
whose I/O is done with a special handler. */
Lisp_Object Vfile_name_handler_alist;
......@@ -160,6 +175,10 @@ int insert_default_directory;
Zero means use var format. */
int vms_stmlf_recfm;
/* On NT, specifies the directory separator character, used (eg.) when
expanding file names. This can be bound to / or \. */
Lisp_Object Vdirectory_sep_char;
/* These variables describe handlers that have "already" had a chance
to handle the current operation.
......@@ -203,7 +222,7 @@ close_file_unwind (fd)
/* Restore point, having saved it as a marker. */
restore_point_unwind (location)
Lisp_Object location;
Lisp_Object location;
{
SET_PT (marker_position (location));
Fset_marker (location, Qnil, Qnil);
......@@ -312,44 +331,38 @@ on VMS, perhaps instead a string ending in `:', `]' or `>'.")
filename = FILE_SYSTEM_CASE (filename);
#endif
beg = XSTRING (filename)->data;
#ifdef DOS_NT
beg = strcpy (alloca (strlen (beg) + 1), beg);
#endif
p = beg + XSTRING (filename)->size;
while (p != beg && !IS_ANY_SEP (p[-1])
while (p != beg && !IS_DIRECTORY_SEP (p[-1])
#ifdef VMS
&& p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
#endif /* VMS */
#ifdef DOS_NT
/* only recognise drive specifier at beginning */
&& !(p[-1] == ':' && p == beg + 2)
#endif
) p--;
if (p == beg)
return Qnil;
#ifdef DOS_NT
/* Expansion of "c:" to drive and default directory. */
/* (NT does the right thing.) */
if (p == beg + 2 && beg[1] == ':')
{
int drive = (*beg) - 'a';
/* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */
unsigned char *res = alloca (MAXPATHLEN + 5);
unsigned char *res1;
#ifdef WINDOWSNT
res1 = res;
/* The NT version places the drive letter at the beginning already. */
#else /* not WINDOWSNT */
/* On MSDOG we must put the drive letter in by hand. */
res1 = res + 2;
#endif /* not WINDOWSNT */
if (getdefdir (drive + 1, res))
unsigned char *res = alloca (MAXPATHLEN + 1);
if (getdefdir (toupper (*beg) - 'A' + 1, res))
{
#ifdef MSDOS
res[0] = drive + 'a';
res[1] = ':';
#endif /* MSDOS */
if (IS_DIRECTORY_SEP (res[strlen (res) - 1]))
if (!IS_DIRECTORY_SEP (res[strlen (res) - 1]))
strcat (res, "/");
beg = res;
p = beg + strlen (beg);
}
}
CORRECT_DIR_SEPS (beg);
#endif /* DOS_NT */
return make_string (beg, p - beg);
}
......@@ -377,10 +390,14 @@ or the entire name if it contains no slash.")
beg = XSTRING (filename)->data;
end = p = beg + XSTRING (filename)->size;
while (p != beg && !IS_ANY_SEP (p[-1])
while (p != beg && !IS_DIRECTORY_SEP (p[-1])
#ifdef VMS
&& p[-1] != ':' && p[-1] != ']' && p[-1] != '>'
#endif /* VMS */
#ifdef DOS_NT
/* only recognise drive specifier at beginning */
&& !(p[-1] == ':' && p == beg + 2)
#endif
) p--;
return make_string (p, end - p);
......@@ -476,11 +493,14 @@ file_name_as_directory (out, in)
}
#else /* not VMS */
/* For Unix syntax, Append a slash if necessary */
if (!IS_ANY_SEP (out[size]))
if (!IS_DIRECTORY_SEP (out[size]))
{
out[size + 1] = DIRECTORY_SEP;
out[size + 2] = '\0';
}
#ifdef DOS_NT
CORRECT_DIR_SEPS (out);
#endif
#endif /* not VMS */
return out;
}
......@@ -519,7 +539,7 @@ On VMS, converts \"[X]FOO.DIR\" to \"[X.FOO]\", etc.")
* On VMS:
* xyzzy:[mukesh.emacs] => xyzzy:[mukesh]emacs.dir.1
* xyzzy:[mukesh] => xyzzy:[000000]mukesh.dir.1
* On UNIX, it's simple: just make sure there is a terminating /
* On UNIX, it's simple: just make sure there isn't a terminating /
* Value is nonzero if the string output is different from the input.
*/
......@@ -555,7 +575,7 @@ directory_file_name (src, dst)
nam.nam$b_nop |= NAM$M_SYNCHK;
/* We call SYS$PARSE to handle such things as [--] for us. */
if (SYS$PARSE(&fab, 0, 0) == RMS$_NORMAL)
if (SYS$PARSE (&fab, 0, 0) == RMS$_NORMAL)
{
slen = nam.nam$b_esl;
if (esa[slen - 1] == ';' && esa[slen - 2] == '.')
......@@ -624,7 +644,7 @@ directory_file_name (src, dst)
then translate the device and recurse. */
if (dst[slen - 1] == ':'
&& dst[slen - 2] != ':' /* skip decnet nodes */
&& strcmp(src + slen, "[000000]") == 0)
&& strcmp (src + slen, "[000000]") == 0)
{
dst[slen - 1] = '\0';
if ((ptr = egetenv (dst))
......@@ -661,13 +681,16 @@ directory_file_name (src, dst)
|| (slen > 1 && dst[0] != '/' && dst[slen - 1] == '/'))
dst[slen - 1] = 0;
#else
if (slen > 1
if (slen > 1
&& IS_DIRECTORY_SEP (dst[slen - 1])
#ifdef DOS_NT
&& !IS_ANY_SEP (dst[slen - 2])
#endif
)
dst[slen - 1] = 0;
#endif
#ifdef DOS_NT
CORRECT_DIR_SEPS (dst);
#endif
return 1;
}
......@@ -726,6 +749,9 @@ so there is no danger of generating a name being used by another process.")
val = concat2 (prefix, build_string ("XXXXXX"));
#endif
mktemp (XSTRING (val)->data);
#ifdef DOS_NT
CORRECT_DIR_SEPS (XSTRING (val)->data);
#endif
return val;
}
......@@ -734,10 +760,10 @@ DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative\n\
(does not start with slash); if DEFAULT-DIRECTORY is nil or missing,\n\
the current buffer's value of default-directory is used.\n\
Path components that are `.' are removed, and \n\
path components followed by `..' are removed, along with the `..' itself;\n\
File name components that are `.' are removed, and \n\
so are file name components followed by `..', along with the `..' itself;\n\
note that these simplifications are done without checking the resulting\n\
paths in the file system.\n\
file names in the file system.\n\
An initial `~/' expands to your home directory.\n\
An initial `~USER/' expands to USER's home directory.\n\
See also the function `substitute-in-file-name'.")
......@@ -745,7 +771,7 @@ See also the function `substitute-in-file-name'.")
Lisp_Object name, default_directory;
{
unsigned char *nm;
register unsigned char *newdir, *p, *o;
int tlen;
unsigned char *target;
......@@ -759,13 +785,11 @@ See also the function `substitute-in-file-name'.")
int dots = 0;
#endif /* VMS */
#ifdef DOS_NT
/* Demacs 1.1.2 91/10/20 Manabu Higashida */
int drive = -1;
int relpath = 0;
unsigned char *tmp, *defdir;
int drive = 0;
#endif /* DOS_NT */
int length;
Lisp_Object handler;
CHECK_STRING (name, 0);
/* If the file name has special constructs in it,
......@@ -799,15 +823,22 @@ See also the function `substitute-in-file-name'.")
The EQ test avoids infinite recursion. */
if (! NILP (default_directory) && !EQ (default_directory, name)
/* Save time in some common cases. */
/* 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 DOS_NT
/* Detect MSDOS file names with device names. */
&& ! (XSTRING (default_directory)->size >= 3
&& IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2]))
/* Detect MSDOS file names with drive specifiers. */
&& ! (IS_DRIVE (o[0]) && (IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2])))
#ifdef WINDOWSNT
/* Detect Windows file names in UNC format. */
&& ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1]))
#endif
/* Detect Unix absolute file names. */
&& ! (XSTRING (default_directory)->size >= 2
&& IS_DIRECTORY_SEP (o[0])))
#else /* not DOS_NT */
/* Detect Unix absolute file names (/... alone is not absolute on
DOS or Windows). */
&& ! (IS_DIRECTORY_SEP (o[0]))
#endif /* not DOS_NT */
)
{
struct gcpro gcpro1;
......@@ -825,29 +856,38 @@ See also the function `substitute-in-file-name'.")
#endif
nm = XSTRING (name)->data;
#ifdef MSDOS
/* First map all backslashes to slashes. */
dostounix_filename (nm = strcpy (alloca (strlen (nm) + 1), nm));
#endif
#ifdef DOS_NT
/* Now strip drive name. */
/* 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 (alloca (strlen (nm) + 1), nm);
/* Find and remove drive specifier if present; this makes nm absolute
even if the rest of the name appears to be relative. */
{
unsigned char *colon = rindex (nm, ':');
if (colon)
/* Only recognize colon as part of drive specifier if there is a
single alphabetic character preceeding the colon (and if the
character before the drive letter, if present, is a directory
separator); this is to support the remote system syntax used by
ange-ftp, and the "po:username" syntax for POP mailboxes. */
look_again:
if (nm == colon)
nm++;
else
else if (IS_DRIVE (colon[-1])
&& (colon == nm + 1 || IS_DIRECTORY_SEP (colon[-2])))
{
drive = colon[-1];
nm = colon + 1;
if (!IS_DIRECTORY_SEP (*nm))
{
defdir = alloca (MAXPATHLEN + 1);
relpath = getdefdir (tolower (drive) - 'a' + 1, defdir);
}
}
}
else
{
while (--colon >= nm)
if (colon[0] == ':')
goto look_again;
}
}
#endif /* DOS_NT */
......@@ -856,31 +896,43 @@ See also the function `substitute-in-file-name'.")
p = nm;
while (*p)
{
/* Since we know the path is absolute, we can assume that each
element starts with a "/". */
/* Since we are expecting the name to be absolute, we can assume
that each element starts with a "/". */
/* "//" anywhere isn't necessarily hairy; we just start afresh
with the second slash. */
if (IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1])
#if defined (APOLLO) || defined (WINDOWSNT)
/* // at start of filename is meaningful on Apollo
/* // at start of filename is meaningful on Apollo
and WindowsNT systems */
&& nm != p
#endif /* APOLLO || WINDOWSNT */
)
nm = p + 1;
/* "~" is hairy as the start of any path element. */
if (IS_DIRECTORY_SEP (p[0]) && p[1] == '~')
nm = p + 1;
p++;
}
/* If nm is absolute, flush ...// and detect /./ and /../.
If no /./ or /../ we can return right away. */
#ifdef WINDOWSNT
/* Discard any previous drive specifier if nm is now in UNC format. */
if (IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
{
drive = 0;
}
#endif
/* If nm is absolute, look for /./ or /../ sequences; if none are
found, we can probably return right away. We will avoid allocating
a new string if name is already fully expanded. */
if (
IS_DIRECTORY_SEP (nm[0])
#ifdef MSDOS
&& drive
#endif
#ifdef WINDOWSNT
&& (drive || IS_DIRECTORY_SEP (nm[1]))
#endif
#ifdef VMS
|| index (nm, ':')
#endif /* VMS */
......@@ -897,7 +949,7 @@ See also the function `substitute-in-file-name'.")
p = nm;
while (*p)
{
/* Since we know the path is absolute, we can assume that each
/* Since we know the name is absolute, we can assume that each
element starts with a "/". */
/* "." and ".." are hairy. */
......@@ -957,7 +1009,7 @@ See also the function `substitute-in-file-name'.")
nm = brack + 1;
brack = 0;
}
/* if /pathname/dev:, move nm to dev: */
/* if /name/dev:, move nm to dev: */
else if (slash)
nm = slash + 1;
/* if node::dev:, move colon following dev */
......@@ -989,7 +1041,28 @@ See also the function `substitute-in-file-name'.")
if (index (nm, '/'))
return build_string (sys_translate_unix (nm));
#endif /* VMS */
#ifndef DOS_NT
#ifdef DOS_NT
/* Make sure directories are all separated with / or \ as
desired, but avoid allocation of a new string when not
required. */
CORRECT_DIR_SEPS (nm);
#ifdef WINDOWSNT
if (IS_DIRECTORY_SEP (nm[1]))
{
if (strcmp (nm, XSTRING (name)->data) != 0)
name = build_string (nm);
}
else
#endif
/* drive must be set, so this is okay */
if (strcmp (nm - 2, XSTRING (name)->data) != 0)
{
name = make_string (nm - 2, p - nm + 2);
XSTRING (name)->data[0] = drive;
XSTRING (name)->data[1] = ':';
}
return name;
#else /* not DOS_NT */
if (nm == XSTRING (name)->data)
return name;
return build_string (nm);
......@@ -997,7 +1070,21 @@ See also the function `substitute-in-file-name'.")
}
}
/* Now determine directory to start with and put it in newdir */
/* At this point, nm might or might not be an absolute file name. We
need to expand ~ or ~user if present, otherwise prefix nm with
default_directory if nm is not absolute, and finally collapse /./
and /foo/../ sequences.
We set newdir to be the appropriate prefix if one is needed:
- the relevant user directory if nm starts with ~ or ~user
- the specified drive's working dir (DOS/NT only) if nm does not
start with /
- the value of default_directory.
Note that these prefixes are not guaranteed to be absolute (except
for the working dir of a drive). Therefore, to ensure we always
return an absolute name, if the final prefix is not absolute we
append it to the current working directory. */
newdir = 0;
......@@ -1011,14 +1098,12 @@ See also the function `substitute-in-file-name'.")
{
if (!(newdir = (unsigned char *) egetenv ("HOME")))
newdir = (unsigned char *) "";
nm++;
#ifdef DOS_NT
/* Problem when expanding "~\" if HOME is not on current drive.
Ulrich Leodolter, Wed Jan 11 10:20:35 1995 */
if (newdir[1] == ':')
drive = newdir[0];
dostounix_filename (newdir);
if (IS_DIRECTORY_SEP (nm[0]))
/* Make nm look like a relative file name. */
nm++;
#endif
nm++;
#ifdef VMS
nm++; /* Don't leave the slash in nm. */
#endif /* VMS */
......@@ -1034,10 +1119,6 @@ See also the function `substitute-in-file-name'.")
bcopy ((char *) nm, o, p - nm);
o [p - nm] = 0;
#ifdef WINDOWSNT
newdir = (unsigned char *) egetenv ("HOME");
dostounix_filename (newdir);
#else /* not WINDOWSNT */
pw = (struct passwd *) getpwnam (o + 1);
if (pw)
{
......@@ -1046,41 +1127,136 @@ See also the function `substitute-in-file-name'.")
nm = p + 1; /* skip the terminator */
#else
nm = p;
#ifdef DOS_NT
if (IS_DIRECTORY_SEP (nm[0]))
/* Make nm look like a relative name. */
nm++;
#endif
#endif /* VMS */
}
#endif /* not WINDOWSNT */
/* If we don't find a user of that name, leave the name
unchanged; don't move nm forward to p. */
}
}
if (!IS_ANY_SEP (nm[0])
#ifdef VMS
&& !index (nm, ':')
#endif /* not VMS */
#ifdef DOS_NT
&& drive == -1
/* 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)
{
/* Get default directory if needed to make nm absolute. */
if (!IS_DIRECTORY_SEP (nm[0]))
{
newdir = alloca (MAXPATHLEN + 1);
if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
newdir = NULL;
}
if (!newdir)
{
/* Either nm starts with /, or drive isn't mounted. */
newdir = alloca (4);
newdir[0] = drive;
newdir[1] = ':';
newdir[2] = '/';
newdir[3] = 0;
}
}
#endif /* DOS_NT */
/* Finally, if no prefix has been specified and nm is not absolute,
then it must be expanded relative to default_directory. */
if (
#ifndef DOS_NT
/* /... alone is not absolute on DOS and Windows. */
!IS_DIRECTORY_SEP (nm[0])
#endif
#ifdef WINDOWSNT
!(IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
#endif
#ifdef VMS
&& !index (nm, ':')
#endif
&& !newdir)
{
newdir = XSTRING (default_directory)->data;
}
#ifdef DOS_NT
if (newdir == 0 && relpath)
newdir = defdir;
if (newdir)
{
/* First ensure newdir is an absolute name. */
if (
/* Detect MSDOS file names with drive specifiers. */
! (IS_DRIVE (newdir[0])
&& IS_DEVICE_SEP (newdir[1]) && IS_DIRECTORY_SEP (newdir[2]))
#ifdef WINDOWSNT
/* Detect Windows file names in UNC format. */
&& ! (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
#endif
)
{
/* Effectively, let newdir be (expand-file-name newdir cwd).
Because of the admonition against calling expand-file-name
when we have pointers into lisp strings, we accomplish this
indirectly by prepending newdir to nm if necessary, and using
cwd (or the wd of newdir's drive) as the new newdir. */
if (IS_DRIVE (newdir[0]) && newdir[1] == ':')
{
drive = newdir[0];
newdir += 2;
}
if (!IS_DIRECTORY_SEP (nm[0]))
{
char * tmp = alloca (strlen (newdir) + strlen (nm) + 2);
file_name_as_directory (tmp, newdir);
strcat (tmp, nm);
nm = tmp;
}
newdir = alloca (MAXPATHLEN + 1);
if (drive)
{
if (!getdefdir (toupper (drive) - 'A' + 1, newdir))
newdir = "/";
}
else
getwd (newdir);
}
/* Strip off drive name from prefix, if present. */
if (IS_DRIVE (newdir[0]) && newdir[1] == ':')
{
drive = newdir[0];
newdir += 2;
}
/* Keep only a prefix from newdir if nm starts with slash
(//server/share for UNC, nothing otherwise). */
if (IS_DIRECTORY_SEP (nm[0]))
{
#ifdef WINDOWSNT
if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]))
{
newdir = strcpy (alloca (strlen (newdir) + 1), newdir);
p = newdir + 2;
while (*p && !IS_DIRECTORY_SEP (*p)) p++;
p++;
while (*p && !IS_DIRECTORY_SEP (*p)) p++;
*p = 0;
}
else
#endif
newdir = "";
}
}
#endif /* DOS_NT */
if (newdir != 0)
if (newdir)
{
/* Get rid of any slash at the end of newdir. */
int length = strlen (newdir);
/* Adding `length > 1 &&' makes ~ expand into / when homedir
is the root dir. People disagree about whether that is right.
Anyway, we can't take the risk of this change now. */
#ifdef DOS_NT
if (newdir[1] != ':' && length > 1)
#endif
length = strlen (newdir);
if (IS_DIRECTORY_SEP (newdir[length - 1]))
{
unsigned char *temp = (unsigned char *) alloca (length);
......@@ -1096,7 +1272,7 @@ See also the function `substitute-in-file-name'.")
/* Now concatenate the directory and name to new space in the stack frame */
tlen += strlen (nm) + 1;
#ifdef DOS_NT
/* Add reserved space for drive name. (The Microsoft x86 compiler
/* Add reserved space for drive name. (The Microsoft x86 compiler
produces incorrect code if the following two lines are combined.) */
target = (unsigned char *) alloca (tlen + 2);
target += 2;
......@@ -1121,6 +1297,8 @@ See also the function `substitute-in-file-name'.")
strcpy (target, sys_translate_unix (target));
#endif /* VMS */
/* ASSERT (IS_DIRECTORY_SEP (target[0])) if not VMS */
/* Now canonicalize by removing /. and /foo/.. if they appear. */
p = target;
......@@ -1176,10 +1354,10 @@ See also the function `substitute-in-file-name'.")
}
else if (IS_DIRECTORY_SEP (p[0]) && IS_DIRECTORY_SEP (p[1])
#if defined (APOLLO) || defined (WINDOWSNT)
/* // at start of filename is meaningful in Apollo
/* // at start of filename is meaningful in Apollo
and WindowsNT systems */
&& o != target
#endif /* APOLLO */
#endif /* APOLLO || WINDOWSNT */
)
{
o = target;
......@@ -1203,14 +1381,6 @@ See also the function `substitute-in-file-name'.")
{
while (o != target && (--o) && !IS_DIRECTORY_SEP (*o))
;
#if defined (APOLLO) || defined (WINDOWSNT)
if (o == target + 1
&& IS_DIRECTORY_SEP (o[-1]) && IS_DIRECTORY_SEP (o[0]))
++o;
else
#endif /* APOLLO || WINDOWSNT */
if (o == target && IS_ANY_SEP (*o))
++o;
p += 3;
}
else
......@@ -1221,18 +1391,18 @@ See also the function `substitute-in-file-name'.")
}
#ifdef DOS_NT
/* at last, set drive name. */
if (target[1] != ':'
/* At last, set drive name. */
#ifdef WINDOWSNT
/* Allow network paths that look like "\\foo" */
&& !(IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1]))
/* Except for network file name. */
if (!(IS_DIRECTORY_SEP (target[0]) && IS_DIRECTORY_SEP (target[1])))
#endif /* WINDOWSNT */
)
{
if (!drive) abort ();
target -= 2;
target[0] = (drive < 0 ? getdisk () + 'A' : drive);