aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDmitry Antipov2014-09-01 20:05:43 +0400
committerDmitry Antipov2014-09-01 20:05:43 +0400
commit50e9e580077869b2f2ced5916299bade6b4f4efd (patch)
tree911756b76f580c119c080770ff895e6955f0be95 /src
parent203fb3639ace0e05284d9be5aa5c3d63701f33a4 (diff)
downloademacs-50e9e580077869b2f2ced5916299bade6b4f4efd.tar.gz
emacs-50e9e580077869b2f2ced5916299bade6b4f4efd.zip
Avoid extra calls to strlen in filesystem I/O routines.
* fileio.c (Fexpand_file_name): Avoid calls to strlen if the length of 'newdir' is known or may be precalculated. (file_accessible_directory_p): Prefer to pass Lisp_Object, not 'char *', and so use precalculated length. (Ffile_accessible_directory_p): * callproc.c (encode_current_directory, init_callproc): * charset.c (init_charset): * lread.c (load_path_check, load_path_default): Adjust users. * lisp.h (file_accessible_directory_p): Tweak prototype.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog13
-rw-r--r--src/callproc.c6
-rw-r--r--src/charset.c2
-rw-r--r--src/fileio.c48
-rw-r--r--src/lisp.h2
-rw-r--r--src/lread.c2
6 files changed, 51 insertions, 22 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 02435801d69..a5ec9c35efa 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,16 @@
12014-09-01 Dmitry Antipov <dmantipov@yandex.ru>
2
3 Avoid extra calls to strlen in filesystem I/O routines.
4 * fileio.c (Fexpand_file_name): Avoid calls to strlen if
5 the length of 'newdir' is known or may be precalculated.
6 (file_accessible_directory_p): Prefer to pass Lisp_Object,
7 not 'char *', and so use precalculated length.
8 (Ffile_accessible_directory_p):
9 * callproc.c (encode_current_directory, init_callproc):
10 * charset.c (init_charset):
11 * lread.c (load_path_check, load_path_default): Adjust users.
12 * lisp.h (file_accessible_directory_p): Tweak prototype.
13
12014-09-01 Eli Zaretskii <eliz@gnu.org> 142014-09-01 Eli Zaretskii <eliz@gnu.org>
2 15
3 * w32proc.c (w32_compare_strings): Support "C" and "POSIX" 16 * w32proc.c (w32_compare_strings): Support "C" and "POSIX"
diff --git a/src/callproc.c b/src/callproc.c
index 2f68ea6f328..01008312155 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -129,7 +129,7 @@ encode_current_directory (void)
129 129
130 if (STRING_MULTIBYTE (dir)) 130 if (STRING_MULTIBYTE (dir))
131 dir = ENCODE_FILE (dir); 131 dir = ENCODE_FILE (dir);
132 if (! file_accessible_directory_p (SSDATA (dir))) 132 if (! file_accessible_directory_p (dir))
133 report_file_error ("Setting current directory", 133 report_file_error ("Setting current directory",
134 BVAR (current_buffer, directory)); 134 BVAR (current_buffer, directory));
135 135
@@ -1625,12 +1625,12 @@ init_callproc (void)
1625#endif 1625#endif
1626 { 1626 {
1627 tempdir = Fdirectory_file_name (Vexec_directory); 1627 tempdir = Fdirectory_file_name (Vexec_directory);
1628 if (! file_accessible_directory_p (SSDATA (tempdir))) 1628 if (! file_accessible_directory_p (tempdir))
1629 dir_warning ("arch-dependent data dir", Vexec_directory); 1629 dir_warning ("arch-dependent data dir", Vexec_directory);
1630 } 1630 }
1631 1631
1632 tempdir = Fdirectory_file_name (Vdata_directory); 1632 tempdir = Fdirectory_file_name (Vdata_directory);
1633 if (! file_accessible_directory_p (SSDATA (tempdir))) 1633 if (! file_accessible_directory_p (tempdir))
1634 dir_warning ("arch-independent data dir", Vdata_directory); 1634 dir_warning ("arch-independent data dir", Vdata_directory);
1635 1635
1636 sh = getenv ("SHELL"); 1636 sh = getenv ("SHELL");
diff --git a/src/charset.c b/src/charset.c
index 341ac356aff..6964208137b 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -2298,7 +2298,7 @@ init_charset (void)
2298{ 2298{
2299 Lisp_Object tempdir; 2299 Lisp_Object tempdir;
2300 tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory); 2300 tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory);
2301 if (! file_accessible_directory_p (SSDATA (tempdir))) 2301 if (! file_accessible_directory_p (tempdir))
2302 { 2302 {
2303 /* This used to be non-fatal (dir_warning), but it should not 2303 /* This used to be non-fatal (dir_warning), but it should not
2304 happen, and if it does sooner or later it will cause some 2304 happen, and if it does sooner or later it will cause some
diff --git a/src/fileio.c b/src/fileio.c
index d9c7397c2de..d4929184cee 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -889,7 +889,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
889 bool collapse_newdir = 1; 889 bool collapse_newdir = 1;
890 bool is_escaped = 0; 890 bool is_escaped = 0;
891#endif /* DOS_NT */ 891#endif /* DOS_NT */
892 ptrdiff_t length; 892 ptrdiff_t length, newdirlen;
893 Lisp_Object handler, result, handled_name; 893 Lisp_Object handler, result, handled_name;
894 bool multibyte; 894 bool multibyte;
895 Lisp_Object hdir; 895 Lisp_Object hdir;
@@ -1147,6 +1147,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1147 append it to the current working directory. */ 1147 append it to the current working directory. */
1148 1148
1149 newdir = 0; 1149 newdir = 0;
1150 newdirlen = -1;
1150 1151
1151 if (nm[0] == '~') /* prefix ~ */ 1152 if (nm[0] == '~') /* prefix ~ */
1152 { 1153 {
@@ -1171,10 +1172,12 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1171 else 1172 else
1172#endif 1173#endif
1173 tem = build_string (newdir); 1174 tem = build_string (newdir);
1175 newdirlen = SBYTES (tem);
1174 if (multibyte && !STRING_MULTIBYTE (tem)) 1176 if (multibyte && !STRING_MULTIBYTE (tem))
1175 { 1177 {
1176 hdir = DECODE_FILE (tem); 1178 hdir = DECODE_FILE (tem);
1177 newdir = SSDATA (hdir); 1179 newdir = SSDATA (hdir);
1180 newdirlen = SBYTES (hdir);
1178 } 1181 }
1179#ifdef DOS_NT 1182#ifdef DOS_NT
1180 collapse_newdir = 0; 1183 collapse_newdir = 0;
@@ -1201,10 +1204,12 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1201 bite us since we expect the directory to be 1204 bite us since we expect the directory to be
1202 multibyte. */ 1205 multibyte. */
1203 tem = build_string (newdir); 1206 tem = build_string (newdir);
1207 newdirlen = SBYTES (tem);
1204 if (multibyte && !STRING_MULTIBYTE (tem)) 1208 if (multibyte && !STRING_MULTIBYTE (tem))
1205 { 1209 {
1206 hdir = DECODE_FILE (tem); 1210 hdir = DECODE_FILE (tem);
1207 newdir = SSDATA (hdir); 1211 newdir = SSDATA (hdir);
1212 newdirlen = SBYTES (hdir);
1208 } 1213 }
1209 nm = p; 1214 nm = p;
1210#ifdef DOS_NT 1215#ifdef DOS_NT
@@ -1234,7 +1239,8 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1234 Lisp_Object tem = build_string (adir); 1239 Lisp_Object tem = build_string (adir);
1235 1240
1236 tem = DECODE_FILE (tem); 1241 tem = DECODE_FILE (tem);
1237 memcpy (adir, SSDATA (tem), SBYTES (tem) + 1); 1242 newdirlen = SBYTES (tem);
1243 memcpy (adir, SSDATA (tem), newdirlen + 1);
1238 } 1244 }
1239 } 1245 }
1240 if (!adir) 1246 if (!adir)
@@ -1245,6 +1251,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1245 adir[1] = ':'; 1251 adir[1] = ':';
1246 adir[2] = '/'; 1252 adir[2] = '/';
1247 adir[3] = 0; 1253 adir[3] = 0;
1254 newdirlen = 3;
1248 } 1255 }
1249 newdir = adir; 1256 newdir = adir;
1250 } 1257 }
@@ -1265,11 +1272,13 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1265 && !newdir) 1272 && !newdir)
1266 { 1273 {
1267 newdir = SSDATA (default_directory); 1274 newdir = SSDATA (default_directory);
1275 newdirlen = SBYTES (default_directory);
1268#ifdef DOS_NT 1276#ifdef DOS_NT
1269 /* Note if special escape prefix is present, but remove for now. */ 1277 /* Note if special escape prefix is present, but remove for now. */
1270 if (newdir[0] == '/' && newdir[1] == ':') 1278 if (newdir[0] == '/' && newdir[1] == ':')
1271 { 1279 {
1272 is_escaped = 1; 1280 is_escaped = 1;
1281 newdirlen -= 2;
1273 newdir += 2; 1282 newdir += 2;
1274 } 1283 }
1275#endif 1284#endif
@@ -1305,14 +1314,14 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1305 if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1])) 1314 if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1]))
1306 { 1315 {
1307 drive = (unsigned char) newdir[0]; 1316 drive = (unsigned char) newdir[0];
1317 newdirlen -= 2;
1308 newdir += 2; 1318 newdir += 2;
1309 } 1319 }
1310 if (!IS_DIRECTORY_SEP (nm[0])) 1320 if (!IS_DIRECTORY_SEP (nm[0]))
1311 { 1321 {
1312 ptrdiff_t newlen = strlen (newdir); 1322 char *tmp = alloca (newdirlen + file_name_as_directory_slop
1313 char *tmp = alloca (newlen + file_name_as_directory_slop
1314 + strlen (nm) + 1); 1323 + strlen (nm) + 1);
1315 file_name_as_directory (tmp, newdir, newlen, multibyte); 1324 file_name_as_directory (tmp, newdir, newdirlen, multibyte);
1316 strcat (tmp, nm); 1325 strcat (tmp, nm);
1317 nm = tmp; 1326 nm = tmp;
1318 } 1327 }
@@ -1329,8 +1338,11 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1329 Lisp_Object tem = build_string (adir); 1338 Lisp_Object tem = build_string (adir);
1330 1339
1331 tem = DECODE_FILE (tem); 1340 tem = DECODE_FILE (tem);
1332 memcpy (adir, SSDATA (tem), SBYTES (tem) + 1); 1341 newdirlen = SBYTES (tem);
1342 memcpy (adir, SSDATA (tem), newdirlen + 1);
1333 } 1343 }
1344 else
1345 newdirlen = strlen (aidr);
1334 newdir = adir; 1346 newdir = adir;
1335 } 1347 }
1336 1348
@@ -1338,6 +1350,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1338 if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1])) 1350 if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1]))
1339 { 1351 {
1340 drive = newdir[0]; 1352 drive = newdir[0];
1353 newdirlen -= 2;
1341 newdir += 2; 1354 newdir += 2;
1342 } 1355 }
1343 1356
@@ -1349,17 +1362,18 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1349 if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1]) 1362 if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1])
1350 && !IS_DIRECTORY_SEP (newdir[2])) 1363 && !IS_DIRECTORY_SEP (newdir[2]))
1351 { 1364 {
1352 char *adir = strcpy (alloca (strlen (newdir) + 1), newdir); 1365 char *adir = strcpy (alloca (newdirlen + 1), newdir);
1353 char *p = adir + 2; 1366 char *p = adir + 2;
1354 while (*p && !IS_DIRECTORY_SEP (*p)) p++; 1367 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1355 p++; 1368 p++;
1356 while (*p && !IS_DIRECTORY_SEP (*p)) p++; 1369 while (*p && !IS_DIRECTORY_SEP (*p)) p++;
1357 *p = 0; 1370 *p = 0;
1358 newdir = adir; 1371 newdir = adir;
1372 newdirlen = strlen (adir);
1359 } 1373 }
1360 else 1374 else
1361#endif 1375#endif
1362 newdir = ""; 1376 newdirlen = 0, newdir = "";
1363 } 1377 }
1364 } 1378 }
1365#endif /* DOS_NT */ 1379#endif /* DOS_NT */
@@ -1368,7 +1382,8 @@ filesystem tree, not (expand-file-name ".." dirname). */)
1368 { 1382 {
1369 /* Ignore any slash at the end of newdir, unless newdir is 1383 /* Ignore any slash at the end of newdir, unless newdir is
1370 just "/" or "//". */ 1384 just "/" or "//". */
1371 length = strlen (newdir); 1385 length = newdirlen;
1386 eassert (length == strlen (newdir));
1372 while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1]) 1387 while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1])
1373 && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0]))) 1388 && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0])))
1374 length--; 1389 length--;
@@ -2765,23 +2780,24 @@ searchable directory. */)
2765 } 2780 }
2766 2781
2767 absname = ENCODE_FILE (absname); 2782 absname = ENCODE_FILE (absname);
2768 return file_accessible_directory_p (SSDATA (absname)) ? Qt : Qnil; 2783 return file_accessible_directory_p (absname) ? Qt : Qnil;
2769} 2784}
2770 2785
2771/* If FILE is a searchable directory or a symlink to a 2786/* If FILE is a searchable directory or a symlink to a
2772 searchable directory, return true. Otherwise return 2787 searchable directory, return true. Otherwise return
2773 false and set errno to an error number. */ 2788 false and set errno to an error number. */
2774bool 2789bool
2775file_accessible_directory_p (char const *file) 2790file_accessible_directory_p (Lisp_Object file)
2776{ 2791{
2777#ifdef DOS_NT 2792#ifdef DOS_NT
2778 /* There's no need to test whether FILE is searchable, as the 2793 /* There's no need to test whether FILE is searchable, as the
2779 searchable/executable bit is invented on DOS_NT platforms. */ 2794 searchable/executable bit is invented on DOS_NT platforms. */
2780 return file_directory_p (file); 2795 return file_directory_p (SSDATA (file));
2781#else 2796#else
2782 /* On POSIXish platforms, use just one system call; this avoids a 2797 /* On POSIXish platforms, use just one system call; this avoids a
2783 race and is typically faster. */ 2798 race and is typically faster. */
2784 ptrdiff_t len = strlen (file); 2799 const char *data = SSDATA (file);
2800 ptrdiff_t len = SBYTES (file);
2785 char const *dir; 2801 char const *dir;
2786 bool ok; 2802 bool ok;
2787 int saved_errno; 2803 int saved_errno;
@@ -2793,15 +2809,15 @@ file_accessible_directory_p (char const *file)
2793 "/" and "//" are distinct on some platforms, whereas "/", "///", 2809 "/" and "//" are distinct on some platforms, whereas "/", "///",
2794 "////", etc. are all equivalent. */ 2810 "////", etc. are all equivalent. */
2795 if (! len) 2811 if (! len)
2796 dir = file; 2812 dir = data;
2797 else 2813 else
2798 { 2814 {
2799 /* Just check for trailing '/' when deciding whether to append '/'. 2815 /* Just check for trailing '/' when deciding whether to append '/'.
2800 That's simpler than testing the two special cases "/" and "//", 2816 That's simpler than testing the two special cases "/" and "//",
2801 and it's a safe optimization here. */ 2817 and it's a safe optimization here. */
2802 char *buf = SAFE_ALLOCA (len + 3); 2818 char *buf = SAFE_ALLOCA (len + 3);
2803 memcpy (buf, file, len); 2819 memcpy (buf, data, len);
2804 strcpy (buf + len, &"/."[file[len - 1] == '/']); 2820 strcpy (buf + len, &"/."[data[len - 1] == '/']);
2805 dir = buf; 2821 dir = buf;
2806 } 2822 }
2807 2823
diff --git a/src/lisp.h b/src/lisp.h
index 53d6cf8009e..05b27ab9f00 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4029,7 +4029,7 @@ extern _Noreturn void report_file_error (const char *, Lisp_Object);
4029extern bool internal_delete_file (Lisp_Object); 4029extern bool internal_delete_file (Lisp_Object);
4030extern Lisp_Object emacs_readlinkat (int, const char *); 4030extern Lisp_Object emacs_readlinkat (int, const char *);
4031extern bool file_directory_p (const char *); 4031extern bool file_directory_p (const char *);
4032extern bool file_accessible_directory_p (const char *); 4032extern bool file_accessible_directory_p (Lisp_Object);
4033extern void init_fileio (void); 4033extern void init_fileio (void);
4034extern void syms_of_fileio (void); 4034extern void syms_of_fileio (void);
4035extern Lisp_Object make_temp_name (Lisp_Object, bool); 4035extern Lisp_Object make_temp_name (Lisp_Object, bool);
diff --git a/src/lread.c b/src/lread.c
index 639d574ac6b..7626e16e818 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -4213,7 +4213,7 @@ load_path_check (Lisp_Object lpath)
4213 if (STRINGP (dirfile)) 4213 if (STRINGP (dirfile))
4214 { 4214 {
4215 dirfile = Fdirectory_file_name (dirfile); 4215 dirfile = Fdirectory_file_name (dirfile);
4216 if (! file_accessible_directory_p (SSDATA (dirfile))) 4216 if (! file_accessible_directory_p (dirfile))
4217 dir_warning ("Lisp directory", XCAR (path_tail)); 4217 dir_warning ("Lisp directory", XCAR (path_tail));
4218 } 4218 }
4219 } 4219 }