diff liboctave/util/kpse.cc @ 21873:40195d04b17c

still more simplification of pathsearch * kpse.cc (kpse_element_dir): Rename from kpse_element_dirs. Return string instead of list of strings. Don't check cache. (dir_search): Rename from dir_list_search. Search single directory instead of list. (match): Delete unused function. (dir_list_add, checked_dir_list_add): Delete. (cache_entry): Delete type. (the_cache, cache_length, dirname;): Delete static variables. (cache, cached): Delete. (path_search, path_find_first_of, kpse_path_expand): Update. * pathsearch.cc (directory_path::all_directories): Update.
author John W. Eaton <jwe@octave.org>
date Sat, 11 Jun 2016 20:07:46 -0400
parents adb0b3ac4b50
children 7508f3a8e234
line wrap: on
line diff
--- a/liboctave/util/kpse.cc	Sat Jun 11 19:06:54 2016 -0400
+++ b/liboctave/util/kpse.cc	Sat Jun 11 20:07:46 2016 -0400
@@ -232,7 +232,7 @@
 
 static std::string kpse_var_expand (const std::string& src);
 
-static std::list<std::string> kpse_element_dirs (const std::string& elt);
+static std::string kpse_element_dir (const std::string& elt);
 
 static std::string kpse_expand (const std::string& s);
 
@@ -467,24 +467,21 @@
    value, though, since we don't shrink it to the final size returned.)  */
 
 static std::list<std::string>
-dir_list_search (std::list<std::string>& dirs, const std::string& name,
-                 bool search_all)
+dir_search (const std::string& dir, const std::string& name,
+            bool search_all)
 {
   std::list<std::string> ret;
 
-  for (const auto &dir : dirs)
-    {
-      std::string potential = dir + name;
+  std::string potential = dir + name;
 
-      std::string tmp = kpse_readable_file (potential);
+  std::string tmp = kpse_readable_file (potential);
 
-      if (! tmp.empty ())
-        {
-          ret.push_back (potential);
+  if (! tmp.empty ())
+    {
+      ret.push_back (potential);
 
-          if (! search_all)
-            return ret;
-        }
+      if (! search_all)
+        return ret;
     }
 
   return ret;
@@ -550,10 +547,10 @@
 
       if (found.empty ())
         {
-          std::list<std::string> dirs = kpse_element_dirs (elt);
+          std::string dir = kpse_element_dir (elt);
 
-          if (! dirs.empty ())
-            found = dir_list_search (dirs, name, all);
+          if (! dir.empty ())
+            found = dir_search (dir, name, all);
         }
 
       /* Did we find anything anywhere?  */
@@ -678,7 +675,7 @@
     {
       std::string elt = *pi;
 
-      std::list<std::string> dirs;
+      std::string dir;
       std::list<std::string> found;
 
       /* Do not touch the device if present */
@@ -702,8 +699,9 @@
         }
 
       /* We have to search one directory at a time.  */
-      dirs = kpse_element_dirs (elt);
-      for (const auto &dir : dirs)
+      dir = kpse_element_dir (elt);
+
+      if (! dir.empty ())
         {
           for (auto it = names.cbegin (); it != names.cend () && ! done; it++)
             {
@@ -717,13 +715,7 @@
               /* Search the filesystem.  */
 
               if (found.empty ())
-                {
-                  std::list<std::string> tmp;
-
-                  tmp.push_back (dir);
-
-                  found = dir_list_search (tmp, name, all);
-                }
+                found = dir_search (dir, name, all);
 
               /* Did we find anything anywhere?  */
               if (! found.empty ())
@@ -1069,9 +1061,8 @@
    existing directories in the result. */
 
 /* Do brace expansion and call 'kpse_expand' on each argument of the
-   result, then expand any '//' constructs.  The final expansion (always
-   in fresh memory) is a path of all the existing directories that match
-   the pattern. */
+   result.  The final expansion (always in fresh memory) is a path of
+   all the existing directories that match the pattern. */
 
 static std::string
 kpse_path_expand (const std::string& path)
@@ -1089,7 +1080,7 @@
     {
       std::string elt = *pi;
 
-      std::list<std::string> dirs;
+      std::string dir;
 
       /* Do not touch the device if present */
       if (NAME_BEGINS_WITH_DEVICE (elt))
@@ -1112,28 +1103,25 @@
 
       /* Search the disk for all dirs in the component specified.
          Be faster to check the database, but this is more reliable.  */
-      dirs = kpse_element_dirs (elt);
+      dir = kpse_element_dir (elt);
 
-      if (! dirs.empty ())
+      size_t dirlen = dir.length ();
+
+      if (dirlen > 0)
         {
-          for (const auto &dir : dirs)
-            {
-              size_t dirlen = dir.length ();
-
-              ret += dir;
-              len += dirlen;
+          ret += dir;
+          len += dirlen;
 
-              /* Retain trailing slash if that's the root directory.  */
-              if (dirlen == 1
-                  || (dirlen == 3 && NAME_BEGINS_WITH_DEVICE (dir)
-                      && IS_DIR_SEP (dir[2])))
-                {
-                  ret += ENV_SEP_STRING;
-                  len++;
-                }
+          /* Retain trailing slash if that's the root directory.  */
+          if (dirlen == 1
+              || (dirlen == 3 && NAME_BEGINS_WITH_DEVICE (dir)
+                  && IS_DIR_SEP (dir[2])))
+            {
+              ret += ENV_SEP_STRING;
+              len++;
+            }
 
-              ret[len-1] = ENV_SEP;
-            }
+          ret[len-1] = ENV_SEP;
         }
     }
 
@@ -1338,81 +1326,6 @@
   return c;
 }
 
-/* Return true if FILENAME could be in PATH_ELT, i.e., if the directory
-   part of FILENAME matches PATH_ELT.  Have to consider // wildcards, but
-   $ and ~ expansion have already been done.  */
-
-static bool
-match (const std::string& filename_arg, const std::string& path_elt_arg)
-{
-  const char *filename = filename_arg.c_str ();
-  const char *path_elt = path_elt_arg.c_str ();
-
-  const char *original_filename = filename;
-  bool matched = false;
-
-  for (; *filename && *path_elt; filename++, path_elt++)
-    {
-      if (*filename == *path_elt) /* normal character match */
-        ;
-
-      else if (IS_DIR_SEP (*path_elt)  /* at // */
-               && original_filename < filename && IS_DIR_SEP (path_elt[-1]))
-        {
-          while (IS_DIR_SEP (*path_elt))
-            path_elt++; /* get past second and any subsequent /'s */
-
-          if (*path_elt == 0)
-            {
-              /* Trailing //, matches anything.  We could make this
-                 part of the other case, but it seems pointless to do
-                 the extra work.  */
-              matched = true;
-              break;
-            }
-          else
-            {
-              /* Intermediate //, have to match rest of PATH_ELT.  */
-              for (; ! matched && *filename; filename++)
-                {
-                  /* Try matching at each possible character.  */
-                  if (IS_DIR_SEP (filename[-1]) && *filename == *path_elt)
-                    matched = match (filename, path_elt);
-                }
-
-              /* Prevent filename++ when *filename='\0'. */
-              break;
-            }
-        }
-      else
-        /* normal character nonmatch, quit */
-        break;
-    }
-
-  /* If we've reached the end of PATH_ELT, check that we're at the last
-     component of FILENAME, we've matched.  */
-  if (! matched && *path_elt == 0)
-    {
-      /* Probably PATH_ELT ended with 'vf' or some such, and FILENAME
-         ends with 'vf/ptmr.vf'.  In that case, we'll be at a
-         directory separator.  On the other hand, if PATH_ELT ended
-         with a / (as in 'vf/'), FILENAME being the same 'vf/ptmr.vf',
-         we'll be at the 'p'.  Upshot: if we're at a dir separator in
-         FILENAME, skip it.  But if not, that's ok, as long as there
-         are no more dir separators.  */
-
-      if (IS_DIR_SEP (*filename))
-        filename++;
-
-      while (*filename && ! IS_DIR_SEP (*filename))
-        filename++;
-
-      matched = *filename == 0;
-    }
-
-  return matched;
-}
-
 /* Expand extra colons.  */
 
 /* Check for leading colon first, then trailing, then doubled, since
@@ -1477,22 +1390,6 @@
    definitions, we give all the subroutines first.  The entry point is
    the last routine in the file.  */
 
-/* Make a copy of DIR (unless it's null) and save it in L.  Ensure that
-   DIR ends with a DIR_SEP for the benefit of later searches.  */
-
-static void
-dir_list_add (std::list<std::string>& lst, const std::string& dir)
-{
-  char last_char = dir[dir.length () - 1];
-
-  std::string saved_dir = dir;
-
-  if (! (IS_DIR_SEP (last_char) || IS_DEVICE_SEP (last_char)))
-    saved_dir += DIR_SEP_STRING;
-
-  lst.push_back (saved_dir);
-}
-
 /* Return true if FN is a directory or a symlink to a directory,
    false if not. */
 
@@ -1504,131 +1401,34 @@
   return (fs && fs.is_dir ());
 }
 
-/* If DIR is a directory, add it to the list L.  */
-
-static void
-checked_dir_list_add (std::list<std::string>& lst, const std::string& dir)
-{
-  if (dir_p (dir))
-    dir_list_add (lst, dir);
-}
-
-/* The cache.  Typically, several paths have the same element; for
-   example, /usr/local/lib/texmf/fonts//.  We don't want to compute the
-   expansion of such a thing more than once.  */
-
-struct cache_entry
-{
-  cache_entry (void) : key (), value (0) { }
-
-  ~cache_entry (void) { }
-
-  std::string key;
-  std::list<std::string> value;
-};
-
-static cache_entry *the_cache = 0;
-static unsigned cache_length = 0;
-
-/* Associate KEY with VALUE.  We implement the cache as a simple linear
-   list, since it's unlikely to ever be more than a dozen or so elements
-   long.  We don't bother to check here if PATH has already been saved;
-   we always add it to our list.  We copy KEY but not VALUE; not sure
-   that's right, but it seems to be all that's needed.  */
-
-static void
-cache (const std::string key, std::list<std::string>& value)
-{
-  cache_entry *new_cache = new cache_entry [cache_length+1];
-
-  for (unsigned i = 0; i < cache_length; i++)
-    {
-      new_cache[i].key = the_cache[i].key;
-      new_cache[i].value = the_cache[i].value;
-    }
-
-  delete [] the_cache;
-
-  the_cache = new_cache;
-
-  the_cache[cache_length].key = key;
-  the_cache[cache_length].value = value;
-
-  cache_length++;
-}
-
-/* To retrieve, just check the list in order.  */
-
-static std::list<std::string>
-cached (const std::string& key)
-{
-  std::list<std::string> retval;
-
-  for (unsigned p = 0; p < cache_length; p++)
-    {
-      if (key == the_cache[p].key)
-        {
-          retval = the_cache[p].value;
-          break;
-        }
-    }
-
-  return retval;
-}
-
-#if defined (WIN32)
-
-/* Shared across recursive calls, it acts like a stack. */
-static std::string dirname;
-
-#else /* WIN32 */
-
-#endif /* WIN32 */
-
 /* Here is the entry point.  Returns directory list for ELT.  */
 
-/* Given a path element ELT, return a pointer to a NULL-terminated list
-   of the corresponding (existing) directory or directories, with
-   trailing slashes, or NULL.  If ELT is the empty string, check the
-   current working directory.
+/* Given a path element ELT, return a the element with a trailing slash
+   or an empty string if the element is not a directory.
 
    It's up to the caller to expand ELT.  This is because this routine is
    most likely only useful to be called from 'kpse_path_search', which
    has already assumed expansion has been done.  */
 
-static std::list<std::string>
-kpse_element_dirs (const std::string& elt)
+static std::string
+kpse_element_dir (const std::string& elt)
 {
-  std::list<std::string> ret;
+  std::string ret;
 
   /* If given nothing, return nothing.  */
   if (elt.empty ())
     return ret;
 
-  /* If we've already cached the answer for ELT, return it.  */
-  ret = cached (elt);
-  if (! ret.empty ())
-    return ret;
-
-  /* We handle the hard case in a subroutine.  */
-  checked_dir_list_add (ret, elt);
-
-  /* Remember the directory list we just found, in case future calls are
-     made with the same ELT.  */
-  cache (elt, ret);
+  if (dir_p (elt))
+    {
+      ret = elt;
 
-#if defined (KPSE_DEBUG)
-  if (KPSE_DEBUG_P (KPSE_DEBUG_EXPAND))
-    {
-      std::cerr << "kdebug: path element " << elt << " =>";
-      if (! ret.empty  ())
-        {
-          for (const auto &ret_elt : ret)
-            std::cerr << " " << ret_elt;
-        }
-      std::cerr << std::endl;
+      char last_char = ret[ret.length () - 1];
+
+      if (! (IS_DIR_SEP (last_char) || IS_DEVICE_SEP (last_char)))
+        ret += DIR_SEP_STRING;
+      
     }
-#endif /* KPSE_DEBUG */
 
   return ret;
 }