[tex-k] kpathsearch and Octave

John W. Eaton jwe@bevo.che.wisc.edu
Thu, 24 Oct 2002 22:30:20 -0500


Hi,

[I sent this message to the list several months back but never saw
any response so perhaps it was not posted.  --jwe]

I've been using the kpathsearch library to handle path expansion and
searching for Octave (www.octave.org) for a number of years now.  Even
though the library has many TeX-specific features, it has also been
quite useful to me as a general-purpose tool for searching for files
in large directory trees.

>From the time I started using kpathsearch with Octave, I've been
distributing the sources in the same tar file as the Octave sources.
Recently, people have started asking why this is so, since the library
is availble as a separate package on most Linux systems, and they
would like to avoid the duplication.  I agree, it would be nice to
avoid multiple copies of the same library, but there are several
reasons why Octave still uses its own version of the libarary.

First, Octave is interactive, and users may change the value of the
path used for searching for functions at any time, so I need to be
able to clear the directory cache and start fresh.  The patch below
adds a new function for this purpose.

Second, when a user changes the search path, Octave needs to expand it
again, prepending, appending, or inserting the default path, and this
needs to be done in a way that can avoid memory leaks.  The way
kpse_expand_default is currently written, it is impossible to know
whether it is safe to free the expansion that it returns.  The patch
below causes kpse_expand_default to always return newly allocated
storage, which the caller is then responsible for deleting.

Finally, there seems to be no independent distribution of the library
outside the teTeX sources (please correct me if I'm wrong about that).
If there is no separate distribution of just the path searching
library, why not?  It already seems self-contained -- after
downloading teTex, I'm able to run configure and make in just the
kpathsea directory without having to configure and build all of teTeX.
It would be very helpful for me to be able to tell people who are not
using Linux and/or who must build from source to go get the
kpathsearch library from some web or ftp site instead of telling them
to download all of teTeX.

Thanks,

jwe

-- 
www.octave.org        | Unfortunately we were hopelessly optimistic in 1954
www.che.wisc.edu/~jwe | about the problems of debugging FORTRAN programs.
                      |                                       -- J. Backus


2002-04-12  John W. Eaton  <jwe@bevo.che.wisc.edu>

	* kdefault.c (kpse_expand_default): Always return newly allocated
	storage.

	* elt-dirs.c (kpse_clear_dir_cache): New function.
	* pathsearch.h: Provide declaration.


--- kdefault.c.orig	Sat Nov 17 15:18:49 2001
+++ kdefault.c	Fri Apr 12 19:20:08 2002
@@ -32,18 +32,18 @@
 kpse_expand_default P2C(const_string, path,  const_string, fallback)
 {
   unsigned path_length;
-  string expansion;
+  string expansion = NULL;
   
   /* The default path better not be null.  */
   assert (fallback);
   
   if (path == NULL)
-    expansion = (string) fallback;
+    expansion = xstrdup (fallback);
 
   /* Solitary or leading :?  */
   else if (IS_ENV_SEP (*path))
     {
-      expansion = path[1] == 0 ? (string) fallback : concat (fallback, path);
+      expansion = path[1] == 0 ? xstrdup (fallback) : concat (fallback, path);
     }
 
   /* Sorry about the assignment in the middle of the expression, but
@@ -59,10 +59,7 @@
     {
       const_string loc;
 
-      /* What we'll return if we find none.  */
-      expansion = (string) path;
-
-      for (loc = path; *loc && expansion == path; loc++)
+      for (loc = path; *loc; loc++)
         {
           if (IS_ENV_SEP (loc[0]) && IS_ENV_SEP (loc[1]))
             { /* We have a doubled colon.  */
@@ -75,8 +72,16 @@
               /* Copy in FALLBACK, and then the rest of PATH.  */
               strcat (expansion, fallback);
               strcat (expansion, loc + 1);
+
+	      break;
             }
         }
+
+      if (! expansion)
+	{
+	  /* Doubled colon not found.  */
+	  expansion = xstrdup (path);
+	}
     }
   
   return expansion;
--- elt-dirs.c.orig	Mon Oct 22 16:31:30 2001
+++ elt-dirs.c	Fri Apr 12 18:59:03 2002
@@ -69,6 +69,35 @@
 static cache_entry *the_cache = NULL;
 static unsigned cache_length = 0;
 
+/* Clear the directory cache.  */
+void
+kpse_clear_dir_cache P1H(void)
+{
+  while (cache_length > 0)
+    {
+      str_llist_type elt = *the_cache[--cache_length].value;
+
+      while (elt)
+	{
+	  str_llist_type next = STR_LLIST_NEXT (*elt);
+
+	  string s = STR_LLIST (*elt);
+
+	  if (s)
+	    free (s);
+
+	  free (elt);
+
+	  elt = next;
+	}
+    }
+
+  if (the_cache)
+    free (the_cache);
+
+  the_cache = NULL;
+}
+
 
 /* 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
--- pathsearch.h.orig	Tue Oct 30 03:53:30 2001
+++ pathsearch.h	Fri Apr 12 18:57:22 2002
@@ -80,5 +80,8 @@
 extern KPSEDLL string *kpse_all_path_search P2H(const_string path,
                                                 const_string name);
 
+/* Clear the directory cache.  */
+extern void kpse_clear_dir_cache P1H(void);
+
 #endif /* not KPATHSEA_PATHSEARCH_H */