]> git.eshelyaron.com Git - emacs.git/commitdiff
Avoid extra calls to strlen in filesystem I/O routines.
authorDmitry Antipov <dmantipov@yandex.ru>
Mon, 1 Sep 2014 16:05:43 +0000 (20:05 +0400)
committerDmitry Antipov <dmantipov@yandex.ru>
Mon, 1 Sep 2014 16:05:43 +0000 (20:05 +0400)
* 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.

src/ChangeLog
src/callproc.c
src/charset.c
src/fileio.c
src/lisp.h
src/lread.c

index 02435801d69c94690f5d6b4a9cff0087734822f4..a5ec9c35efa159a83e0897bcea2f7738fc127378 100644 (file)
@@ -1,3 +1,16 @@
+2014-09-01  Dmitry Antipov  <dmantipov@yandex.ru>
+
+       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.
+
 2014-09-01  Eli Zaretskii  <eliz@gnu.org>
 
        * w32proc.c (w32_compare_strings): Support "C" and "POSIX"
index 2f68ea6f32802e361b7507611206f6aada9fc502..0100831215528f26def45d25b07111545252539d 100644 (file)
@@ -129,7 +129,7 @@ encode_current_directory (void)
 
   if (STRING_MULTIBYTE (dir))
     dir = ENCODE_FILE (dir);
-  if (! file_accessible_directory_p (SSDATA (dir)))
+  if (! file_accessible_directory_p (dir))
     report_file_error ("Setting current directory",
                       BVAR (current_buffer, directory));
 
@@ -1625,12 +1625,12 @@ init_callproc (void)
 #endif
     {
       tempdir = Fdirectory_file_name (Vexec_directory);
-      if (! file_accessible_directory_p (SSDATA (tempdir)))
+      if (! file_accessible_directory_p (tempdir))
        dir_warning ("arch-dependent data dir", Vexec_directory);
     }
 
   tempdir = Fdirectory_file_name (Vdata_directory);
-  if (! file_accessible_directory_p (SSDATA (tempdir)))
+  if (! file_accessible_directory_p (tempdir))
     dir_warning ("arch-independent data dir", Vdata_directory);
 
   sh = getenv ("SHELL");
index 341ac356aff2674c71dbd3ab87c6d6d91869f455..6964208137bd2c62c78d48e1c5216f0ee4254f58 100644 (file)
@@ -2298,7 +2298,7 @@ init_charset (void)
 {
   Lisp_Object tempdir;
   tempdir = Fexpand_file_name (build_string ("charsets"), Vdata_directory);
-  if (! file_accessible_directory_p (SSDATA (tempdir)))
+  if (! file_accessible_directory_p (tempdir))
     {
       /* This used to be non-fatal (dir_warning), but it should not
          happen, and if it does sooner or later it will cause some
index d9c7397c2de0cdfa513d79c08f4f075cc4035774..d4929184ceec06dc5176d865d3e8795aa9775825 100644 (file)
@@ -889,7 +889,7 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
   bool collapse_newdir = 1;
   bool is_escaped = 0;
 #endif /* DOS_NT */
-  ptrdiff_t length;
+  ptrdiff_t length, newdirlen;
   Lisp_Object handler, result, handled_name;
   bool multibyte;
   Lisp_Object hdir;
@@ -1147,6 +1147,7 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
      append it to the current working directory.  */
 
   newdir = 0;
+  newdirlen = -1;
 
   if (nm[0] == '~')            /* prefix ~ */
     {
@@ -1171,10 +1172,12 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
          else
 #endif
            tem = build_string (newdir);
+         newdirlen = SBYTES (tem);
          if (multibyte && !STRING_MULTIBYTE (tem))
            {
              hdir = DECODE_FILE (tem);
              newdir = SSDATA (hdir);
+             newdirlen = SBYTES (hdir);
            }
 #ifdef DOS_NT
          collapse_newdir = 0;
@@ -1201,10 +1204,12 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
                 bite us since we expect the directory to be
                 multibyte.  */
              tem = build_string (newdir);
+             newdirlen = SBYTES (tem);
              if (multibyte && !STRING_MULTIBYTE (tem))
                {
                  hdir = DECODE_FILE (tem);
                  newdir = SSDATA (hdir);
+                 newdirlen = SBYTES (hdir);
                }
              nm = p;
 #ifdef DOS_NT
@@ -1234,7 +1239,8 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
              Lisp_Object tem = build_string (adir);
 
              tem = DECODE_FILE (tem);
-             memcpy (adir, SSDATA (tem), SBYTES (tem) + 1);
+             newdirlen = SBYTES (tem);
+             memcpy (adir, SSDATA (tem), newdirlen + 1);
            }
        }
       if (!adir)
@@ -1245,6 +1251,7 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
          adir[1] = ':';
          adir[2] = '/';
          adir[3] = 0;
+         newdirlen = 3;
        }
       newdir = adir;
     }
@@ -1265,11 +1272,13 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
       && !newdir)
     {
       newdir = SSDATA (default_directory);
+      newdirlen = SBYTES (default_directory);
 #ifdef DOS_NT
       /* Note if special escape prefix is present, but remove for now.  */
       if (newdir[0] == '/' && newdir[1] == ':')
        {
          is_escaped = 1;
+         newdirlen -= 2;
          newdir += 2;
        }
 #endif
@@ -1305,14 +1314,14 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
          if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1]))
            {
              drive = (unsigned char) newdir[0];
+             newdirlen -= 2;
              newdir += 2;
            }
          if (!IS_DIRECTORY_SEP (nm[0]))
            {
-             ptrdiff_t newlen = strlen (newdir);
-             char *tmp = alloca (newlen + file_name_as_directory_slop
+             char *tmp = alloca (newdirlen + file_name_as_directory_slop
                                  + strlen (nm) + 1);
-             file_name_as_directory (tmp, newdir, newlen, multibyte);
+             file_name_as_directory (tmp, newdir, newdirlen, multibyte);
              strcat (tmp, nm);
              nm = tmp;
            }
@@ -1329,8 +1338,11 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
              Lisp_Object tem = build_string (adir);
 
              tem = DECODE_FILE (tem);
-             memcpy (adir, SSDATA (tem), SBYTES (tem) + 1);
+             newdirlen = SBYTES (tem);
+             memcpy (adir, SSDATA (tem), newdirlen + 1);
            }
+         else
+           newdirlen = strlen (aidr);
          newdir = adir;
        }
 
@@ -1338,6 +1350,7 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
       if (IS_DRIVE (newdir[0]) && IS_DEVICE_SEP (newdir[1]))
        {
          drive = newdir[0];
+         newdirlen -= 2;
          newdir += 2;
        }
 
@@ -1349,17 +1362,18 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
          if (IS_DIRECTORY_SEP (newdir[0]) && IS_DIRECTORY_SEP (newdir[1])
              && !IS_DIRECTORY_SEP (newdir[2]))
            {
-             char *adir = strcpy (alloca (strlen (newdir) + 1), newdir);
+             char *adir = strcpy (alloca (newdirlen + 1), newdir);
              char *p = adir + 2;
              while (*p && !IS_DIRECTORY_SEP (*p)) p++;
              p++;
              while (*p && !IS_DIRECTORY_SEP (*p)) p++;
              *p = 0;
              newdir = adir;
+             newdirlen = strlen (adir);
            }
          else
 #endif
-           newdir = "";
+           newdirlen = 0, newdir = "";
        }
     }
 #endif /* DOS_NT */
@@ -1368,7 +1382,8 @@ filesystem tree, not (expand-file-name ".."  dirname).  */)
     {
       /* Ignore any slash at the end of newdir, unless newdir is
         just "/" or "//".  */
-      length = strlen (newdir);
+      length = newdirlen;
+      eassert (length == strlen (newdir));
       while (length > 1 && IS_DIRECTORY_SEP (newdir[length - 1])
             && ! (length == 2 && IS_DIRECTORY_SEP (newdir[0])))
        length--;
@@ -2765,23 +2780,24 @@ searchable directory.  */)
     }
 
   absname = ENCODE_FILE (absname);
-  return file_accessible_directory_p (SSDATA (absname)) ? Qt : Qnil;
+  return file_accessible_directory_p (absname) ? Qt : Qnil;
 }
 
 /* If FILE is a searchable directory or a symlink to a
    searchable directory, return true.  Otherwise return
    false and set errno to an error number.  */
 bool
-file_accessible_directory_p (char const *file)
+file_accessible_directory_p (Lisp_Object file)
 {
 #ifdef DOS_NT
   /* There's no need to test whether FILE is searchable, as the
      searchable/executable bit is invented on DOS_NT platforms.  */
-  return file_directory_p (file);
+  return file_directory_p (SSDATA (file));
 #else
   /* On POSIXish platforms, use just one system call; this avoids a
      race and is typically faster.  */
-  ptrdiff_t len = strlen (file);
+  const char *data = SSDATA (file);
+  ptrdiff_t len = SBYTES (file);
   char const *dir;
   bool ok;
   int saved_errno;
@@ -2793,15 +2809,15 @@ file_accessible_directory_p (char const *file)
      "/" and "//" are distinct on some platforms, whereas "/", "///",
      "////", etc. are all equivalent.  */
   if (! len)
-    dir = file;
+    dir = data;
   else
     {
       /* Just check for trailing '/' when deciding whether to append '/'.
         That's simpler than testing the two special cases "/" and "//",
         and it's a safe optimization here.  */
       char *buf = SAFE_ALLOCA (len + 3);
-      memcpy (buf, file, len);
-      strcpy (buf + len, &"/."[file[len - 1] == '/']);
+      memcpy (buf, data, len);
+      strcpy (buf + len, &"/."[data[len - 1] == '/']);
       dir = buf;
     }
 
index 53d6cf8009e580e565cd6a9d2659e774e29484f4..05b27ab9f00379632a45def37dabde3cf10a7c27 100644 (file)
@@ -4029,7 +4029,7 @@ extern _Noreturn void report_file_error (const char *, Lisp_Object);
 extern bool internal_delete_file (Lisp_Object);
 extern Lisp_Object emacs_readlinkat (int, const char *);
 extern bool file_directory_p (const char *);
-extern bool file_accessible_directory_p (const char *);
+extern bool file_accessible_directory_p (Lisp_Object);
 extern void init_fileio (void);
 extern void syms_of_fileio (void);
 extern Lisp_Object make_temp_name (Lisp_Object, bool);
index 639d574ac6b757992ea0da86289e60f2258cfa51..7626e16e818697df16a524a1e08027576d7adc24 100644 (file)
@@ -4213,7 +4213,7 @@ load_path_check (Lisp_Object lpath)
       if (STRINGP (dirfile))
         {
           dirfile = Fdirectory_file_name (dirfile);
-          if (! file_accessible_directory_p (SSDATA (dirfile)))
+          if (! file_accessible_directory_p (dirfile))
             dir_warning ("Lisp directory", XCAR (path_tail));
         }
     }