aboutsummaryrefslogtreecommitdiffstats
path: root/src/fileio.c
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/fileio.c
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/fileio.c')
-rw-r--r--src/fileio.c48
1 files changed, 32 insertions, 16 deletions
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