[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] Changes to emacs/src/fileio.c
From: |
Stefan Monnier |
Subject: |
[Emacs-diffs] Changes to emacs/src/fileio.c |
Date: |
Mon, 28 Mar 2005 16:31:16 -0500 |
Index: emacs/src/fileio.c
diff -c emacs/src/fileio.c:1.533 emacs/src/fileio.c:1.534
*** emacs/src/fileio.c:1.533 Thu Mar 17 23:36:03 2005
--- emacs/src/fileio.c Mon Mar 28 21:31:14 2005
***************
*** 1014,1020 ****
DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
doc: /* 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.
File name components that are `.' are removed, and
so are file name components followed by `..', along with the `..' itself;
--- 1014,1020 ----
DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
doc: /* 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.
File name components that are `.' are removed, and
so are file name components followed by `..', along with the `..' itself;
***************
*** 1464,1470 ****
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;
--- 1464,1470 ----
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]) && IS_DEVICE_SEP (newdir[1]))
{
drive = newdir[0];
newdir += 2;
***************
*** 1487,1493 ****
}
/* Strip off drive name from prefix, if present. */
! if (IS_DRIVE (newdir[0]) && newdir[1] == ':')
{
drive = newdir[0];
newdir += 2;
--- 1487,1493 ----
}
/* Strip off drive name from prefix, if present. */
! if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1]))
{
drive = newdir[0];
newdir += 2;
***************
*** 1721,1727 ****
DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
"Convert FILENAME to absolute, and canonicalize it.\n\
Second arg DEFAULT is directory to start with if FILENAME is relative\n\
! (does not start with slash); if DEFAULT is nil or missing,\n\
the current buffer's value of default-directory is used.\n\
Filenames containing `.' or `..' as components are simplified;\n\
initial `~/' expands to your home directory.\n\
--- 1721,1727 ----
DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
"Convert FILENAME to absolute, and canonicalize it.\n\
Second arg DEFAULT is directory to start with if FILENAME is relative\n\
! \(does not start with slash); if DEFAULT is nil or missing,\n\
the current buffer's value of default-directory is used.\n\
Filenames containing `.' or `..' as components are simplified;\n\
initial `~/' expands to your home directory.\n\
***************
*** 2040,2045 ****
--- 2040,2114 ----
}
#endif
+ /* If /~ or // appears, discard everything through first slash. */
+ static int
+ file_name_absolute_p (filename)
+ const unsigned char *filename;
+ {
+ return
+ (IS_DIRECTORY_SEP (*filename) || *filename == '~'
+ #ifdef VMS
+ /* ??? This criterion is probably wrong for '<'. */
+ || index (filename, ':') || index (filename, '<')
+ || (*filename == '[' && (filename[1] != '-'
+ || (filename[2] != '.' && filename[2] != ']'))
+ && filename[1] != '.')
+ #endif /* VMS */
+ #ifdef DOS_NT
+ || (IS_DRIVE (*filename) && IS_DEVICE_SEP (filename[1])
+ && IS_DIRECTORY_SEP (filename[2]))
+ #endif
+ );
+ }
+
+ static unsigned char *
+ search_embedded_absfilename (nm, endp)
+ unsigned char *nm, *endp;
+ {
+ unsigned char *p, *s;
+
+ for (p = nm + 1; p < endp; p++)
+ {
+ if ((0
+ #ifdef VMS
+ || p[-1] == ':' || p[-1] == ']' || p[-1] == '>'
+ #endif /* VMS */
+ || IS_DIRECTORY_SEP (p[-1]))
+ && file_name_absolute_p (p)
+ #if defined (APOLLO) || defined (WINDOWSNT) || defined(CYGWIN)
+ /* // at start of file name is meaningful in Apollo,
+ WindowsNT and Cygwin systems. */
+ && !(IS_DIRECTORY_SEP (p[0]) && p - 1 != nm)
+ #endif /* not (APOLLO || WINDOWSNT || CYGWIN) */
+ )
+ {
+ for (s = p; *s && (!IS_DIRECTORY_SEP (*s)
+ #ifdef VMS
+ && *s != ':'
+ #endif /* VMS */
+ ); s++);
+ if (p[0] == '~' && s > p + 1) /* we've got "/~something/" */
+ {
+ unsigned char *o = alloca (s - p + 1);
+ struct passwd *pw;
+ bcopy (p, o, s - p);
+ o [s - p] = 0;
+
+ /* If we have ~user and `user' exists, discard
+ everything up to ~. But if `user' does not exist, leave
+ ~user alone, it might be a literal file name. */
+ if ((pw = getpwnam (o + 1)))
+ return p;
+ else
+ xfree (pw);
+ }
+ else
+ return p;
+ }
+ }
+ return NULL;
+ }
+
DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name,
Ssubstitute_in_file_name, 1, 1, 0,
doc: /* Substitute environment variables referred to in FILENAME.
***************
*** 2061,2067 ****
int total = 0;
int substituted = 0;
unsigned char *xnm;
- struct passwd *pw;
Lisp_Object handler;
CHECK_STRING (filename);
--- 2130,2135 ----
***************
*** 2081,2141 ****
endp = nm + SBYTES (filename);
/* If /~ or // appears, discard everything through first slash. */
- for (p = nm; p != endp; p++)
- {
- if ((p[0] == '~'
- #if defined (APOLLO) || defined (WINDOWSNT) || defined(CYGWIN)
- /* // at start of file name is meaningful in Apollo,
- WindowsNT and Cygwin systems. */
- || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm)
- #else /* not (APOLLO || WINDOWSNT || CYGWIN) */
- || IS_DIRECTORY_SEP (p[0])
- #endif /* not (APOLLO || WINDOWSNT || CYGWIN) */
- )
- && p != nm
- && (0
#ifdef VMS
! || p[-1] == ':' || p[-1] == ']' || p[-1] == '>'
! #endif /* VMS */
! || IS_DIRECTORY_SEP (p[-1])))
! {
! for (s = p; *s && (!IS_DIRECTORY_SEP (*s)
! #ifdef VMS
! && *s != ':'
! #endif /* VMS */
! ); s++);
! if (p[0] == '~' && s > p + 1) /* we've got "/~something/" */
! {
! o = (unsigned char *) alloca (s - p + 1);
! bcopy ((char *) p, o, s - p);
! o [s - p] = 0;
!
! pw = (struct passwd *) getpwnam (o + 1);
! }
! /* If we have ~/ or ~user and `user' exists, discard
! everything up to ~. But if `user' does not exist, leave
! ~user alone, it might be a literal file name. */
! if (IS_DIRECTORY_SEP (p[0]) || s == p + 1 || pw)
! {
! nm = p;
! substituted = 1;
! }
! }
! #ifdef DOS_NT
! /* 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 /* DOS_NT */
! }
!
! #ifdef VMS
! return make_specified_string (nm, -1, strlen (nm),
! STRING_MULTIBYTE (filename));
#else
/* See if any variables are substituted into the string
--- 2149,2165 ----
endp = nm + SBYTES (filename);
/* If /~ or // appears, discard everything through first slash. */
+ p = search_embedded_absfilename (nm, endp);
+ if (p)
+ /* Start over with the new string, so we check the file-name-handler
+ again. Important with filenames like "/home/foo//:/hello///there"
+ which whould substitute to "/:/hello///there" rather than "/there". */
+ return Fsubstitute_in_file_name
+ (make_specified_string (p, -1, endp - p,
+ STRING_MULTIBYTE (filename)));
#ifdef VMS
! return filename;
#else
/* See if any variables are substituted into the string
***************
*** 2261,2282 ****
*x = 0;
/* If /~ or // appears, discard everything through first slash. */
!
! for (p = xnm; p != x; p++)
! if ((p[0] == '~'
! #if defined (APOLLO) || defined (WINDOWSNT) || defined(CYGWIN)
! || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm)
! #else /* not (APOLLO || WINDOWSNT || CYGWIN) */
! || IS_DIRECTORY_SEP (p[0])
! #endif /* not (APOLLO || WINDOWSNT || CYGWIN) */
! )
! && p != xnm && IS_DIRECTORY_SEP (p[-1]))
! xnm = p;
! #ifdef DOS_NT
! else if (IS_DRIVE (p[0]) && p[1] == ':'
! && p > xnm && IS_DIRECTORY_SEP (p[-1]))
! xnm = p;
! #endif
return make_specified_string (xnm, -1, x - xnm, STRING_MULTIBYTE
(filename));
--- 2285,2295 ----
*x = 0;
/* If /~ or // appears, discard everything through first slash. */
! while ((p = search_embedded_absfilename (xnm, x)))
! /* This time we do not start over because we've already expanded envvars
! and replaced $$ with $. Maybe we should start over as well, but we'd
! need to quote some $ to $$ first. */
! xnm = p;
return make_specified_string (xnm, -1, x - xnm, STRING_MULTIBYTE
(filename));
***************
*** 2959,2982 ****
(filename)
Lisp_Object filename;
{
- const unsigned char *ptr;
-
CHECK_STRING (filename);
! ptr = SDATA (filename);
! if (IS_DIRECTORY_SEP (*ptr) || *ptr == '~'
! #ifdef VMS
! /* ??? This criterion is probably wrong for '<'. */
! || index (ptr, ':') || index (ptr, '<')
! || (*ptr == '[' && (ptr[1] != '-' || (ptr[2] != '.' && ptr[2] != ']'))
! && ptr[1] != '.')
! #endif /* VMS */
! #ifdef DOS_NT
! || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2]))
! #endif
! )
! return Qt;
! else
! return Qnil;
}
/* Return nonzero if file FILENAME exists and can be executed. */
--- 2972,2979 ----
(filename)
Lisp_Object filename;
{
CHECK_STRING (filename);
! return file_name_absolute_p (SDATA (filename)) ? Qt : Qnil;
}
/* Return nonzero if file FILENAME exists and can be executed. */
- [Emacs-diffs] Changes to emacs/src/fileio.c, Thien-Thi Nguyen, 2005/03/03
- [Emacs-diffs] Changes to emacs/src/fileio.c, Thien-Thi Nguyen, 2005/03/04
- [Emacs-diffs] Changes to emacs/src/fileio.c, Thien-Thi Nguyen, 2005/03/04
- [Emacs-diffs] Changes to emacs/src/fileio.c, Kenichi Handa, 2005/03/11
- [Emacs-diffs] Changes to emacs/src/fileio.c, Richard M . Stallman, 2005/03/11
- [Emacs-diffs] Changes to emacs/src/fileio.c, Stefan Monnier, 2005/03/11
- [Emacs-diffs] Changes to emacs/src/fileio.c, Richard M . Stallman, 2005/03/17
- [Emacs-diffs] Changes to emacs/src/fileio.c,
Stefan Monnier <=
- [Emacs-diffs] Changes to emacs/src/fileio.c, Stefan Monnier, 2005/03/30