aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Monnier2005-03-28 21:31:14 +0000
committerStefan Monnier2005-03-28 21:31:14 +0000
commitc70a4df6d2e683a591e7487c7940f7f18f5af65e (patch)
tree25a5032be73981721a11d5ee95e67cefeea3028b /src
parentf60a6f87ff45773b0d1737ef8d8d2b83269e34a6 (diff)
downloademacs-c70a4df6d2e683a591e7487c7940f7f18f5af65e.tar.gz
emacs-c70a4df6d2e683a591e7487c7940f7f18f5af65e.zip
(Fexpand_file_name): Use IS_DEVICE_SEP.
(file_name_absolute_p): New fun, extracted from Ffile_name_absolute_p. (Ffile_name_absolute_p): Use it. (search_embedded_absfilename): New fun, extracted from Fsubstitute_in_file_name. Use file_name_absolute_p. Free the pw data after use. (Fsubstitute_in_file_name): Use it. After cutting a prefix, re-check file-name-handler.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog11
-rw-r--r--src/fileio.c179
2 files changed, 99 insertions, 91 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 4ea174bdc60..1a5561160d0 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
12005-03-28 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * fileio.c (Fexpand_file_name): Use IS_DEVICE_SEP.
4 (file_name_absolute_p): New fun, extracted from Ffile_name_absolute_p.
5 (Ffile_name_absolute_p): Use it.
6 (search_embedded_absfilename): New fun, extracted from
7 Fsubstitute_in_file_name. Use file_name_absolute_p.
8 Free the pw data after use.
9 (Fsubstitute_in_file_name): Use it.
10 After cutting a prefix, re-check file-name-handler.
11
12005-03-26 Lennart Borgman <lennart.borgman.073@student.lu.se> 122005-03-26 Lennart Borgman <lennart.borgman.073@student.lu.se>
2 13
3 * w32term.h (x_output): add focus_state. 14 * w32term.h (x_output): add focus_state.
diff --git a/src/fileio.c b/src/fileio.c
index dbbcace1212..58efa38c254 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -1014,7 +1014,7 @@ probably use `make-temp-file' instead, except in three circumstances:
1014DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0, 1014DEFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
1015 doc: /* Convert filename NAME to absolute, and canonicalize it. 1015 doc: /* Convert filename NAME to absolute, and canonicalize it.
1016Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative 1016Second arg DEFAULT-DIRECTORY is directory to start with if NAME is relative
1017 (does not start with slash); if DEFAULT-DIRECTORY is nil or missing, 1017\(does not start with slash); if DEFAULT-DIRECTORY is nil or missing,
1018the current buffer's value of default-directory is used. 1018the current buffer's value of default-directory is used.
1019File name components that are `.' are removed, and 1019File name components that are `.' are removed, and
1020so are file name components followed by `..', along with the `..' itself; 1020so are file name components followed by `..', along with the `..' itself;
@@ -1464,7 +1464,7 @@ See also the function `substitute-in-file-name'. */)
1464 indirectly by prepending newdir to nm if necessary, and using 1464 indirectly by prepending newdir to nm if necessary, and using
1465 cwd (or the wd of newdir's drive) as the new newdir. */ 1465 cwd (or the wd of newdir's drive) as the new newdir. */
1466 1466
1467 if (IS_DRIVE (newdir[0]) && newdir[1] == ':') 1467 if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1]))
1468 { 1468 {
1469 drive = newdir[0]; 1469 drive = newdir[0];
1470 newdir += 2; 1470 newdir += 2;
@@ -1487,7 +1487,7 @@ See also the function `substitute-in-file-name'. */)
1487 } 1487 }
1488 1488
1489 /* Strip off drive name from prefix, if present. */ 1489 /* Strip off drive name from prefix, if present. */
1490 if (IS_DRIVE (newdir[0]) && newdir[1] == ':') 1490 if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1]))
1491 { 1491 {
1492 drive = newdir[0]; 1492 drive = newdir[0];
1493 newdir += 2; 1493 newdir += 2;
@@ -1721,7 +1721,7 @@ See also the function `substitute-in-file-name'. */)
1721DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0, 1721DEAFUN ("expand-file-name", Fexpand_file_name, Sexpand_file_name, 1, 2, 0,
1722 "Convert FILENAME to absolute, and canonicalize it.\n\ 1722 "Convert FILENAME to absolute, and canonicalize it.\n\
1723Second arg DEFAULT is directory to start with if FILENAME is relative\n\ 1723Second arg DEFAULT is directory to start with if FILENAME is relative\n\
1724 (does not start with slash); if DEFAULT is nil or missing,\n\ 1724\(does not start with slash); if DEFAULT is nil or missing,\n\
1725the current buffer's value of default-directory is used.\n\ 1725the current buffer's value of default-directory is used.\n\
1726Filenames containing `.' or `..' as components are simplified;\n\ 1726Filenames containing `.' or `..' as components are simplified;\n\
1727initial `~/' expands to your home directory.\n\ 1727initial `~/' expands to your home directory.\n\
@@ -2040,6 +2040,75 @@ See also the function `substitute-in-file-name'.")
2040} 2040}
2041#endif 2041#endif
2042 2042
2043/* If /~ or // appears, discard everything through first slash. */
2044static int
2045file_name_absolute_p (filename)
2046 const unsigned char *filename;
2047{
2048 return
2049 (IS_DIRECTORY_SEP (*filename) || *filename == '~'
2050#ifdef VMS
2051 /* ??? This criterion is probably wrong for '<'. */
2052 || index (filename, ':') || index (filename, '<')
2053 || (*filename == '[' && (filename[1] != '-'
2054 || (filename[2] != '.' && filename[2] != ']'))
2055 && filename[1] != '.')
2056#endif /* VMS */
2057#ifdef DOS_NT
2058 || (IS_DRIVE (*filename) && IS_DEVICE_SEP (filename[1])
2059 && IS_DIRECTORY_SEP (filename[2]))
2060#endif
2061 );
2062}
2063
2064static unsigned char *
2065search_embedded_absfilename (nm, endp)
2066 unsigned char *nm, *endp;
2067{
2068 unsigned char *p, *s;
2069
2070 for (p = nm + 1; p < endp; p++)
2071 {
2072 if ((0
2073#ifdef VMS
2074 || p[-1] == ':' || p[-1] == ']' || p[-1] == '>'
2075#endif /* VMS */
2076 || IS_DIRECTORY_SEP (p[-1]))
2077 && file_name_absolute_p (p)
2078#if defined (APOLLO) || defined (WINDOWSNT) || defined(CYGWIN)
2079 /* // at start of file name is meaningful in Apollo,
2080 WindowsNT and Cygwin systems. */
2081 && !(IS_DIRECTORY_SEP (p[0]) && p - 1 != nm)
2082#endif /* not (APOLLO || WINDOWSNT || CYGWIN) */
2083 )
2084 {
2085 for (s = p; *s && (!IS_DIRECTORY_SEP (*s)
2086#ifdef VMS
2087 && *s != ':'
2088#endif /* VMS */
2089 ); s++);
2090 if (p[0] == '~' && s > p + 1) /* we've got "/~something/" */
2091 {
2092 unsigned char *o = alloca (s - p + 1);
2093 struct passwd *pw;
2094 bcopy (p, o, s - p);
2095 o [s - p] = 0;
2096
2097 /* If we have ~user and `user' exists, discard
2098 everything up to ~. But if `user' does not exist, leave
2099 ~user alone, it might be a literal file name. */
2100 if ((pw = getpwnam (o + 1)))
2101 return p;
2102 else
2103 xfree (pw);
2104 }
2105 else
2106 return p;
2107 }
2108 }
2109 return NULL;
2110}
2111
2043DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name, 2112DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name,
2044 Ssubstitute_in_file_name, 1, 1, 0, 2113 Ssubstitute_in_file_name, 1, 1, 0,
2045 doc: /* Substitute environment variables referred to in FILENAME. 2114 doc: /* Substitute environment variables referred to in FILENAME.
@@ -2061,7 +2130,6 @@ duplicates what `expand-file-name' does. */)
2061 int total = 0; 2130 int total = 0;
2062 int substituted = 0; 2131 int substituted = 0;
2063 unsigned char *xnm; 2132 unsigned char *xnm;
2064 struct passwd *pw;
2065 Lisp_Object handler; 2133 Lisp_Object handler;
2066 2134
2067 CHECK_STRING (filename); 2135 CHECK_STRING (filename);
@@ -2081,61 +2149,17 @@ duplicates what `expand-file-name' does. */)
2081 endp = nm + SBYTES (filename); 2149 endp = nm + SBYTES (filename);
2082 2150
2083 /* If /~ or // appears, discard everything through first slash. */ 2151 /* If /~ or // appears, discard everything through first slash. */
2084 2152 p = search_embedded_absfilename (nm, endp);
2085 for (p = nm; p != endp; p++) 2153 if (p)
2086 { 2154 /* Start over with the new string, so we check the file-name-handler
2087 if ((p[0] == '~' 2155 again. Important with filenames like "/home/foo//:/hello///there"
2088#if defined (APOLLO) || defined (WINDOWSNT) || defined(CYGWIN) 2156 which whould substitute to "/:/hello///there" rather than "/there". */
2089 /* // at start of file name is meaningful in Apollo, 2157 return Fsubstitute_in_file_name
2090 WindowsNT and Cygwin systems. */ 2158 (make_specified_string (p, -1, endp - p,
2091 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != nm) 2159 STRING_MULTIBYTE (filename)));
2092#else /* not (APOLLO || WINDOWSNT || CYGWIN) */
2093 || IS_DIRECTORY_SEP (p[0])
2094#endif /* not (APOLLO || WINDOWSNT || CYGWIN) */
2095 )
2096 && p != nm
2097 && (0
2098#ifdef VMS
2099 || p[-1] == ':' || p[-1] == ']' || p[-1] == '>'
2100#endif /* VMS */
2101 || IS_DIRECTORY_SEP (p[-1])))
2102 {
2103 for (s = p; *s && (!IS_DIRECTORY_SEP (*s)
2104#ifdef VMS
2105 && *s != ':'
2106#endif /* VMS */
2107 ); s++);
2108 if (p[0] == '~' && s > p + 1) /* we've got "/~something/" */
2109 {
2110 o = (unsigned char *) alloca (s - p + 1);
2111 bcopy ((char *) p, o, s - p);
2112 o [s - p] = 0;
2113
2114 pw = (struct passwd *) getpwnam (o + 1);
2115 }
2116 /* If we have ~/ or ~user and `user' exists, discard
2117 everything up to ~. But if `user' does not exist, leave
2118 ~user alone, it might be a literal file name. */
2119 if (IS_DIRECTORY_SEP (p[0]) || s == p + 1 || pw)
2120 {
2121 nm = p;
2122 substituted = 1;
2123 }
2124 }
2125#ifdef DOS_NT
2126 /* see comment in expand-file-name about drive specifiers */
2127 else if (IS_DRIVE (p[0]) && p[1] == ':'
2128 && p > nm && IS_DIRECTORY_SEP (p[-1]))
2129 {
2130 nm = p;
2131 substituted = 1;
2132 }
2133#endif /* DOS_NT */
2134 }
2135 2160
2136#ifdef VMS 2161#ifdef VMS
2137 return make_specified_string (nm, -1, strlen (nm), 2162 return filename;
2138 STRING_MULTIBYTE (filename));
2139#else 2163#else
2140 2164
2141 /* See if any variables are substituted into the string 2165 /* See if any variables are substituted into the string
@@ -2261,22 +2285,11 @@ duplicates what `expand-file-name' does. */)
2261 *x = 0; 2285 *x = 0;
2262 2286
2263 /* If /~ or // appears, discard everything through first slash. */ 2287 /* If /~ or // appears, discard everything through first slash. */
2264 2288 while ((p = search_embedded_absfilename (xnm, x)))
2265 for (p = xnm; p != x; p++) 2289 /* This time we do not start over because we've already expanded envvars
2266 if ((p[0] == '~' 2290 and replaced $$ with $. Maybe we should start over as well, but we'd
2267#if defined (APOLLO) || defined (WINDOWSNT) || defined(CYGWIN) 2291 need to quote some $ to $$ first. */
2268 || (IS_DIRECTORY_SEP (p[0]) && p - 1 != xnm) 2292 xnm = p;
2269#else /* not (APOLLO || WINDOWSNT || CYGWIN) */
2270 || IS_DIRECTORY_SEP (p[0])
2271#endif /* not (APOLLO || WINDOWSNT || CYGWIN) */
2272 )
2273 && p != xnm && IS_DIRECTORY_SEP (p[-1]))
2274 xnm = p;
2275#ifdef DOS_NT
2276 else if (IS_DRIVE (p[0]) && p[1] == ':'
2277 && p > xnm && IS_DIRECTORY_SEP (p[-1]))
2278 xnm = p;
2279#endif
2280 2293
2281 return make_specified_string (xnm, -1, x - xnm, STRING_MULTIBYTE (filename)); 2294 return make_specified_string (xnm, -1, x - xnm, STRING_MULTIBYTE (filename));
2282 2295
@@ -2959,24 +2972,8 @@ On Unix, this is a name starting with a `/' or a `~'. */)
2959 (filename) 2972 (filename)
2960 Lisp_Object filename; 2973 Lisp_Object filename;
2961{ 2974{
2962 const unsigned char *ptr;
2963
2964 CHECK_STRING (filename); 2975 CHECK_STRING (filename);
2965 ptr = SDATA (filename); 2976 return file_name_absolute_p (SDATA (filename)) ? Qt : Qnil;
2966 if (IS_DIRECTORY_SEP (*ptr) || *ptr == '~'
2967#ifdef VMS
2968/* ??? This criterion is probably wrong for '<'. */
2969 || index (ptr, ':') || index (ptr, '<')
2970 || (*ptr == '[' && (ptr[1] != '-' || (ptr[2] != '.' && ptr[2] != ']'))
2971 && ptr[1] != '.')
2972#endif /* VMS */
2973#ifdef DOS_NT
2974 || (IS_DRIVE (*ptr) && ptr[1] == ':' && IS_DIRECTORY_SEP (ptr[2]))
2975#endif
2976 )
2977 return Qt;
2978 else
2979 return Qnil;
2980} 2977}
2981 2978
2982/* Return nonzero if file FILENAME exists and can be executed. */ 2979/* Return nonzero if file FILENAME exists and can be executed. */