[tex-k] Patch to kpsewhich: switch --all to show all matching files

Harald Harders h.harders at tu-bs.de
Sun Mar 2 21:34:07 CET 2003


I have written a patch for kpsewhich which implements the command line
switch --all. It enables the output of all matching files. It seems to me
that this switch was already planned (since the unpatched version handled
the switch, but it did not do anything with it).
For my few tests, the patch worked.
I am sure that this patch is far from perfect. I would like you to test it
and discuss what can be improved.

Yours
Harald

-- 
Harald Harders                              Langer Kamp 8
Institut für Werkstoffe                     D-38106 Braunschweig
Technische Universität Braunschweig         Germany
E-Mail: h.harders at tu-bs.de                  Tel: +49 (5 31) 3 91-3062
WWW   : http://www.tu-bs.de/institute/ifw/  Fax: +49 (5 31) 3 91-3058
-------------- next part --------------
Only in neu/: c-auto.h
diff -ur orig/kpsewhich.c neu/kpsewhich.c
--- orig/kpsewhich.c	Sun Mar  2 18:19:35 2003
+++ neu/kpsewhich.c	Sun Mar  2 18:24:17 2003
@@ -139,13 +139,33 @@
 static unsigned
 lookup P1C(string, name)
 {
-  string ret;
+  string ret=NULL;
   unsigned local_dpi;
   kpse_glyph_file_type glyph_ret;
   
   if (user_path) {
-    ret = kpse_path_search (user_path, name, must_exist);
-    
+    if (show_all) {
+      unsigned int totallength=0;
+      string *tmpret, *runret;
+      tmpret = kpse_all_path_search (user_path, name);
+      runret = tmpret;
+      while (runret && *runret) {
+	totallength+=strlen(*runret)+1;
+	++runret;
+      }
+      if (runret && (totallength>0)) {
+        ret = calloc(sizeof(char)*totallength,'\0');
+	runret = tmpret;
+	while (*runret) {
+	  strcat(ret,*runret);
+	  strcat(ret,"\n");
+	  ++runret;
+	}
+	ret[strlen(ret)-1]='\0';
+      }
+    }
+    else
+      ret = kpse_path_search (user_path, name, must_exist);
   } else {
     /* No user-specified search path, check user format or guess from NAME.  */
     kpse_file_format_type fmt = find_format (name, true);
@@ -167,10 +187,31 @@
         /* fall through */
 
       default:
-        ret = kpse_find_file (name, fmt, must_exist);
+	  if (show_all) {
+	    unsigned int totallength=0;
+	    string *tmpret, *runret;
+	    tmpret = kpse_find_all_files (name, fmt, must_exist);
+	    runret = tmpret;
+	    while (runret && *runret) {
+	      totallength+=strlen(*runret)+1;
+	      ++runret;
+	    }
+	    if (runret && (totallength>0)) {
+	      ret = calloc(sizeof(char)*totallength,'\0');
+	      runret = tmpret;
+	      while (*runret) {
+		strcat(ret,*runret);
+		strcat(ret,"\n");
+		++runret;
+	      }
+	      ret[strlen(ret)-1]='\0';
+	    }
+	  }
+	  else
+	    ret = kpse_find_file (name, fmt, must_exist);
     }
   }
-  
+
   if (ret)
     puts (ret);
   
@@ -182,6 +223,7 @@
 #define USAGE "\
   Standalone path lookup and expansion for Kpathsea.\n\
 \n\
+-all                   print all matching files.\n\
 -debug=NUM             set debugging flags.\n\
 -D, -dpi=NUM           use a base resolution of NUM; default 600.\n\
 -expand-braces=STRING  output variable and brace expansion of STRING.\n\
Only in neu/: paths.h
diff -ur orig/tex-file.c neu/tex-file.c
--- orig/tex-file.c	Sun Mar  2 18:19:35 2003
+++ neu/tex-file.c	Sun Mar  2 18:18:52 2003
@@ -773,6 +773,141 @@
   return ret;
 }
 
+/* Look up a file NAME of type FORMAT, and the given MUST_EXIST.  This
+   initializes the path spec for FORMAT if it's the first lookup of that
+   type.  Return the filename found, or NULL.  This is the most likely
+   thing for clients to call.  */
+   
+string *
+kpse_find_all_files P3C(const_string, name,  kpse_file_format_type, format,
+                        boolean, must_exist)
+{
+  const_string *ext;
+  unsigned name_len = 0;
+  boolean name_has_suffix_already = false;
+  string mapped_name;
+  string *mapped_names;
+  boolean use_fontmaps = (format == kpse_tfm_format
+                          || format == kpse_gf_format
+                          || format == kpse_pk_format
+                          || format == kpse_ofm_format);
+  string *ret = NULL;
+
+  /* NAME being NULL is a programming bug somewhere.  NAME can be empty,
+     though; this happens with constructs like `\input\relax'.  */
+  assert (name);
+  
+  if (FMT_INFO.path == NULL)
+    kpse_init_format (format);
+
+  /* Does NAME already end in a possible suffix?  */
+  name_len = strlen (name);
+  if (FMT_INFO.suffix) {
+    for (ext = FMT_INFO.suffix; !name_has_suffix_already && *ext; ext++) {
+      unsigned suffix_len = strlen (*ext);
+      name_has_suffix_already = (name_len >= suffix_len
+          && FILESTRCASEEQ (*ext, name + name_len - suffix_len));
+    }
+  }
+  if (!name_has_suffix_already && FMT_INFO.alt_suffix) {
+    for (ext = FMT_INFO.alt_suffix; !name_has_suffix_already && *ext; ext++) {
+      unsigned suffix_len = strlen (*ext);
+      name_has_suffix_already = (name_len >= suffix_len
+          && FILESTRCASEEQ (*ext, name + name_len - suffix_len));
+    }
+  }
+
+  /* Search #1: NAME doesn't have a suffix which is equal to a "standard"
+     suffix.  For example, foo.bar, but not foo.tex.  We look for the
+     name with the standard suffixes appended. */
+  if (!name_has_suffix_already && FMT_INFO.suffix) {
+    /* Append a suffix and search for it.   Don't pound the disk yet.  */
+    for (ext = FMT_INFO.suffix; !ret && *ext; ext++) {
+      string name_with_suffix = concat (name, *ext);
+      ret = kpse_all_path_search (FMT_INFO.path, name_with_suffix);
+      if (! *ret)
+      {
+	  free(ret);
+	  ret=NULL;
+      }/* if */
+      if (!ret && use_fontmaps) {
+        mapped_names = kpse_fontmap_lookup (name_with_suffix);
+        while (mapped_names && (mapped_name = *mapped_names++) && !ret)
+	{
+          ret = kpse_all_path_search (FMT_INFO.path, mapped_name);
+	  if (! *ret)
+	  {
+	      free(ret);
+	      ret=NULL;
+	  }/* if */
+	}
+      }
+      free (name_with_suffix);
+    }
+    /* If we only do suffix searches, and are instructed to pound the disk,
+       do so now.  We don't pound the disk for aliases...perhaps we should? */
+    if (!ret && FMT_INFO.suffix_search_only && must_exist) {
+      for (ext = FMT_INFO.suffix; !ret && *ext; ext++) {
+        string name_with_suffix = concat (name, *ext);
+        ret = kpse_all_path_search (FMT_INFO.path, name_with_suffix);
+	if (! *ret)
+	{
+	    free(ret);
+	    ret=NULL;
+	}/* if */
+        free (name_with_suffix);
+      }
+    }
+  }
+
+  /* Search #2: Just look for the name we've been given, provided non-suffix
+     searches are allowed or the name already includes a suffix. */
+  if (!ret && (name_has_suffix_already || !FMT_INFO.suffix_search_only)) {
+    ret = kpse_all_path_search (FMT_INFO.path, name);
+    if (! *ret)
+    {
+	free(ret);
+	ret=NULL;
+    }/* if */
+    if (!ret && use_fontmaps) {
+      mapped_names = kpse_fontmap_lookup (name);
+      while (mapped_names && (mapped_name = *mapped_names++) && !ret)
+      {
+        ret = kpse_all_path_search (FMT_INFO.path, mapped_name);
+	if (! *ret)
+	{
+	    free(ret);
+	    ret=NULL;
+	}/* if */
+      }
+    }
+    /* We don't pound the disk for aliases...perhaps we should? */
+    if (!ret && must_exist) {
+      ret = kpse_all_path_search (FMT_INFO.path, name);
+      if (! *ret)
+      {
+	  free(ret);
+	  ret=NULL;
+      }/* if */
+    }
+  }
+
+  /* Search #3 (sort of): Call mktextfm or whatever to create a
+     missing file.  */
+  /*
+  if (!ret && must_exist) {
+    ret = kpse_make_tex (format, name);
+    if (! *ret)
+    {
+        free(ret);
+	ret=NULL;
+    }
+  }
+  */
+
+  return ret;
+}
+
 /* Open NAME along the search path for TYPE for reading and return the
    resulting file, or exit with an error message.  */
 
diff -ur orig/tex-file.h neu/tex-file.h
--- orig/tex-file.h	Sun Mar  2 18:19:35 2003
+++ neu/tex-file.h	Sun Mar  2 18:19:18 2003
@@ -167,6 +167,9 @@
 extern KPSEDLL string kpse_find_file P3H(const_string name,  
                             kpse_file_format_type format,  boolean must_exist);
 
+extern KPSEDLL string *kpse_find_all_files P3H(const_string name,  
+                            kpse_file_format_type format,  boolean must_exist);
+
 /* Here are some abbreviations.  */
 #define kpse_find_mf(name)   kpse_find_file (name, kpse_mf_format, true)
 #define kpse_find_mft(name)  kpse_find_file (name, kpse_mft_format, true)


More information about the tex-k mailing list