diff options
author | Karl Berry <karl@freefriends.org> | 2007-12-23 00:21:33 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2007-12-23 00:21:33 +0000 |
commit | ff35e824456a6c889424b2a56ea65d769f1e5e19 (patch) | |
tree | ce06613e09682ec54cfe6e7f847b2f629843e790 | |
parent | bef64609b4b323e9ee4f3ac67b3769d0c192f8ec (diff) |
implement kpsewhich --all for normal searches
git-svn-id: svn://tug.org/texlive/trunk@5825 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r-- | Build/source/texk/kpathsea/.gdbinit | 13 | ||||
-rw-r--r-- | Build/source/texk/kpathsea/ChangeLog | 16 | ||||
-rw-r--r-- | Build/source/texk/kpathsea/kpsewhich.c | 24 | ||||
-rw-r--r-- | Build/source/texk/kpathsea/pathsearch.c | 52 | ||||
-rw-r--r-- | Build/source/texk/kpathsea/pathsearch.h | 59 | ||||
-rw-r--r-- | Build/source/texk/kpathsea/str-list.c | 35 | ||||
-rw-r--r-- | Build/source/texk/kpathsea/str-list.h | 17 | ||||
-rw-r--r-- | Build/source/texk/kpathsea/tex-file.c | 84 | ||||
-rw-r--r-- | Build/source/texk/kpathsea/tex-file.h | 9 |
9 files changed, 201 insertions, 108 deletions
diff --git a/Build/source/texk/kpathsea/.gdbinit b/Build/source/texk/kpathsea/.gdbinit new file mode 100644 index 00000000000..68e9a2a87a0 --- /dev/null +++ b/Build/source/texk/kpathsea/.gdbinit @@ -0,0 +1,13 @@ +define redo +file kpsewhich +end + +# afoot.sty +set env TEXMFCNF /home/texlive/karl/Master/texmf/web2c +set env TEXMFDBS /home/texlive/karl/Master/texmf-dist:/home/texlive/karl/Master/texmf +set env TEXINPUTS !!/home/texlive/karl/Master/texmf-dist/tex/latex//:!!/home/texlive/karl/Master/texmf/tex/generic//:!!/home/texlive/karl/Master/texmf/tex// +# +# preload.cfg +#set env TEXMFDBS /home/texlive/karl/Master/texmf +#set env TEXINPUTS !!/home/texlive/karl/Master/texmf/tex/generic//:!!/home/texlive/karl/Master/texmf/tex// +set args --all --debug=32 preload.cfg diff --git a/Build/source/texk/kpathsea/ChangeLog b/Build/source/texk/kpathsea/ChangeLog index fb501c37468..a83c47c0628 100644 --- a/Build/source/texk/kpathsea/ChangeLog +++ b/Build/source/texk/kpathsea/ChangeLog @@ -1,3 +1,19 @@ +2007-12-22 Karl Berry <karl@tug.org> + + * kpsewhich.c (lookup): handle --all for regular lookups as well + as user-specific paths. + * pathsearch.c (search_list): uniqify list before returning. + (kpse_path_search_list_generic): new fn. + (kpse_all_path_search_list, kpse_path_search_list): rewrite to + call ..._generic. + * pathsearch.h (kpse_path_search_list_generic): declare it. + * str-list.c (str_list_uniqify): new fn. + * str-list.h (str_list_uniqify): declare it. + * tex-file.c (kpse_find_file_generic): new name for kpse_find_file + code, with addition of argument to find all. + (kpse_find_file): rewrite to call ..._generic. + * tex-file.h (kpse_find_file_generic): declare it. + 2007-12-17 Karl Berry <karl@tug.org> * kpathsea.texi (Path searching options): clarify --expand-path doc. diff --git a/Build/source/texk/kpathsea/kpsewhich.c b/Build/source/texk/kpathsea/kpsewhich.c index 31c8e98bf40..3595fd6b255 100644 --- a/Build/source/texk/kpathsea/kpsewhich.c +++ b/Build/source/texk/kpathsea/kpsewhich.c @@ -165,11 +165,9 @@ find_format P2C(string, name, boolean, is_filename) static unsigned lookup P1C(string, name) { + int i; string ret = NULL; string *ret_list = NULL; - int i; - unsigned local_dpi; - kpse_glyph_file_type glyph_ret; if (user_path) { if (show_all) { @@ -186,11 +184,15 @@ lookup P1C(string, name) case kpse_pk_format: case kpse_gf_format: case kpse_any_glyph_format: - /* Try to extract the resolution from the name. */ - local_dpi = find_dpi (name); - if (!local_dpi) - local_dpi = dpi; - ret = kpse_find_glyph (remove_suffix (name), local_dpi, fmt, &glyph_ret); + { + kpse_glyph_file_type glyph_ret; + /* Try to extract the resolution from the name. */ + unsigned local_dpi = find_dpi (name); + if (!local_dpi) + local_dpi = dpi; + ret = kpse_find_glyph (remove_suffix (name), local_dpi, fmt, + &glyph_ret); + } break; case kpse_last_format: @@ -199,7 +201,11 @@ lookup P1C(string, name) /* fall through */ default: - ret = kpse_find_file (name, fmt, must_exist); + if (show_all) { + ret_list = kpse_find_file_generic (name, fmt, must_exist, true); + } else { + ret = kpse_find_file (name, fmt, must_exist); + } } } diff --git a/Build/source/texk/kpathsea/pathsearch.c b/Build/source/texk/kpathsea/pathsearch.c index e3b3fc14885..2234ed7cb29 100644 --- a/Build/source/texk/kpathsea/pathsearch.c +++ b/Build/source/texk/kpathsea/pathsearch.c @@ -1,7 +1,7 @@ /* pathsearch.c: look up a filename in a path. + Copyright 1993, 1994, 1995, 1997, 2007 Karl Berry. Copyright 1997-2005 Olaf Weber. - Copyright 1993, 94, 95, 97 Karl Berry. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -13,11 +13,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -*/ + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, see <http://www.gnu.org/licenses/>. */ #include <kpathsea/config.h> #include <kpathsea/c-pathch.h> @@ -402,7 +399,7 @@ static string * search_list P4C(const_string, path, const_string*, names, boolean, must_exist, boolean, all) { - str_list_type ret_list; + str_list_type ret_list, uniq_list; const_string* namep; string elt; boolean done = false; @@ -510,6 +507,11 @@ search_list P4C(const_string, path, const_string*, names, } out: + /* Uniqify, since our paths can often end up finding the same file + more than once. */ + str_list_uniqify (&ret_list); + + /* Add NULL if we will be returning multiple elements. */ if (STR_LIST_LENGTH (ret_list) == 0 || (all && STR_LIST_LAST_ELT (ret_list) != NULL)) str_list_add (&ret_list, NULL); @@ -522,8 +524,8 @@ search_list P4C(const_string, path, const_string*, names, if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) { DEBUGF1 ("search([%s", *names); for (namep = names+1; *namep != NULL; namep++) { - fputc(' ', stderr); - fputs(*namep, stderr); + fputc (' ', stderr); + fputs (*namep, stderr); } fputs ("]) =>", stderr); } @@ -540,7 +542,7 @@ search_list P4C(const_string, path, const_string*, names, return STR_LIST (ret_list); } -/* Search PATH for the first NAME. */ +/* Search PATH for the first NAME according to MUST_EXIST. */ string kpse_path_search P3C(const_string, path, const_string, name, @@ -552,20 +554,21 @@ kpse_path_search P3C(const_string, path, const_string, name, return ret; } -/* Search PATH for the first occurence of one of the NAMES. */ +/* Many inputs, return (more or less indeterminate) one matching string. */ string kpse_path_search_list P3C(const_string, path, const_string*, names, - boolean, must_exist) + boolean, must_exist) { - string *ret_list = search_list (path, names, must_exist, false); + string *ret_list + = kpse_path_search_list_generic (path, names, must_exist, false); string ret = *ret_list; free (ret_list); return ret; -} +} -/* Search all elements of PATH for files named NAME. Not sure if it's - right to assert `must_exist' here, but it suffices now. */ +/* Search PATH for all files named NAME. Might have been better not + to assert `must_exist' here, but it's too late to change. */ string * kpse_all_path_search P2C(const_string, path, const_string, name) @@ -574,11 +577,24 @@ kpse_all_path_search P2C(const_string, path, const_string, name) return ret; } + +/* Many inputs, return list, allow specifying MUST_EXIST and ALL. */ + +string * +kpse_path_search_list_generic P4C(const_string, path, const_string*, names, + boolean, must_exist, boolean, all) +{ + string *ret = search_list (path, names, must_exist, all); + return ret; +} + + +/* Many inputs, return list, MUST_EXIST and ALL always true. */ + string * kpse_all_path_search_list P2C(const_string, path, const_string*, names) { - string *ret = search_list (path, names, true, true); - return ret; + return kpse_path_search_list_generic (path, names, true, true); } #ifdef TEST diff --git a/Build/source/texk/kpathsea/pathsearch.h b/Build/source/texk/kpathsea/pathsearch.h index 927aa2dbd08..9478c2a53cc 100644 --- a/Build/source/texk/kpathsea/pathsearch.h +++ b/Build/source/texk/kpathsea/pathsearch.h @@ -1,7 +1,7 @@ /* pathsearch.h: mostly-generic path searching. + Copyright 1993, 1994, 1996, 1997, 2007 Karl Berry. Copyright 1999-2005 Olaf Weber. - Copyright 1993, 94, 96, 97 Karl Berry. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -13,11 +13,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -*/ + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef KPATHSEA_PATHSEARCH_H #define KPATHSEA_PATHSEARCH_H @@ -69,27 +66,33 @@ extern KPSEDLL str_llist_type *kpse_element_dirs P1H(string elt); the filesystem.) The caller must expand PATH. This is because it makes more sense to - do this once, in advance, instead of for every search using it. + do this once, in advance, instead of for every search. - In any case, return the complete filename if found, otherwise NULL. */ -extern KPSEDLL string kpse_path_search P3H(const_string path, - const_string name, - boolean must_exist); - -/* Like kpse_path_search, except we're given a list of names. */ -extern KPSEDLL string kpse_path_search_list P3H(const_string path, - const_string* names, - boolean must_exist); - -/* Like `kpse_path_search' with MUST_EXIST true, but return a list of - all the filenames (or NULL if none), instead of taking the first. */ -extern KPSEDLL string *kpse_all_path_search P2H(const_string path, - const_string name); - -/* Like `kpse_path_search_list' with MUST_EXIST true, but return a list of - all the filenames (or NULL if none), instead of taking the first. */ -extern KPSEDLL string *kpse_all_path_search_list P2H(const_string path, - const_string* names); - + In any case, return a matching filename if found, otherwise NULL. + If more than one file matches, which one gets returned is + unspecified. */ +extern KPSEDLL string kpse_path_search + P3H(const_string path, const_string name, boolean must_exist); + +/* Like `kpse_path_search', except look for a list of NAMES. */ +extern KPSEDLL string kpse_path_search_list + P3H(const_string path, const_string* names, boolean must_exist); + +/* Like `kpse_path_search' with MUST_EXIST true, but always return all + matches in a NULL-terminated list. */ +extern KPSEDLL string *kpse_all_path_search + P2H(const_string path, const_string name); + +/* Search for any of the NAMES in PATH, and allow specifying both + MUST_EXIST and ALL. */ +extern KPSEDLL string *kpse_path_search_list_generic + P4H(const_string path, const_string* names, boolean must_exist, boolean all); + +/* Search for any of NAMES, with MUST_EXIST and ALL true. */ +extern KPSEDLL string *kpse_all_path_search_list + P2H(const_string path, const_string* names); + +/* The naming of all these functions is rather scattered and + inconsistent, but they grew over time, and we don't want to change + the meaning of existing names. */ #endif /* not KPATHSEA_PATHSEARCH_H */ - diff --git a/Build/source/texk/kpathsea/str-list.c b/Build/source/texk/kpathsea/str-list.c index 66df7b791cc..8b4ab314dfe 100644 --- a/Build/source/texk/kpathsea/str-list.c +++ b/Build/source/texk/kpathsea/str-list.c @@ -118,3 +118,38 @@ str_list_free P1C(str_list_type *, l) STR_LIST (*l) = NULL; } } + + + +/* Remove duplicate elements from L, freeing their space. Since our + lists are so short, we do a maximally inefficient bubble search. */ + +void +str_list_uniqify P1C(str_list_type *, l) +{ + unsigned e; + str_list_type ret = str_list_init (); + + for (e = 0; e < STR_LIST_LENGTH (*l); e++) { + string elt1 = STR_LIST_ELT (*l, e); + unsigned f; + for (f = e + 1; f < STR_LIST_LENGTH (*l); f++) { + string elt2 = STR_LIST_ELT (*l, f); + /* I don't think our list should ever contain NULL's, but if + it does, let it stay and don't bother collapsing multiple + NULL's into one. */ + if (FILESTRCASEEQ (elt1, elt2)) { + break; + } + } + + if (f == STR_LIST_LENGTH (*l)) { + str_list_add (&ret, elt1); /* not found */ + } else { + free (elt1); /* duplicate, forget this one */ + } + } + + /* Replace the passed list with what we constructed. */ + *l = ret; +} diff --git a/Build/source/texk/kpathsea/str-list.h b/Build/source/texk/kpathsea/str-list.h index dcffd928424..1a80047a7bc 100644 --- a/Build/source/texk/kpathsea/str-list.h +++ b/Build/source/texk/kpathsea/str-list.h @@ -1,7 +1,7 @@ /* str-list.h: Declarations for string lists. + Copyright 1993, 1994, 2007 Karl Berry. Copyright 1999, 2005 Olaf Weber. - Copyright 1993, 94 Karl Berry. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -13,11 +13,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -*/ + You should have received a copy of the GNU Lesser General Public License + along with this library; if not, see <http://www.gnu.org/licenses/>. */ #ifndef KPATHSEA_STR_LIST_H #define KPATHSEA_STR_LIST_H @@ -54,7 +51,11 @@ extern void str_list_concat P2H(str_list_type * target, str_list_type more); themselves). */ extern void str_list_free P1H(str_list_type *l); -/* Append each element of more to each element of target. */ -extern void str_list_concat_elements P2H(str_list_type * target, str_list_type more); +/* Append each element of MORE to each element of TARGET. */ +extern void str_list_concat_elements + P2H(str_list_type *target, str_list_type more); + +/* Remove duplicate elements from L, freeing their space. */ +extern void str_list_uniqify P1H(str_list_type *l); #endif /* not KPATHSEA_STR_LIST_H */ diff --git a/Build/source/texk/kpathsea/tex-file.c b/Build/source/texk/kpathsea/tex-file.c index 6cec76df87a..e040e33eb74 100644 --- a/Build/source/texk/kpathsea/tex-file.c +++ b/Build/source/texk/kpathsea/tex-file.c @@ -295,10 +295,9 @@ init_path PVAR2C(kpse_format_info_type *, info, const_string, default_path, ap) }} -/* Some file types have more than one suffix. */ -/* Some times it is convenient to modify the list of searched suffixes. - *** Don't complain if this function goes away. *** - */ +/* Some file types have more than one suffix, and sometimes it is + convenient to modify the list of searched suffixes. */ + void kpse_set_suffixes PVAR2C(kpse_file_format_type, format, boolean, alternate, ap) @@ -309,8 +308,7 @@ kpse_set_suffixes PVAR2C(kpse_file_format_type, format, if (alternate) { list = &kpse_format_info[format].alt_suffix; - } - else { + } else { list = &kpse_format_info[format].suffix; } @@ -745,18 +743,31 @@ string kpse_find_file P3C(const_string, name, kpse_file_format_type, format, boolean, must_exist) { + string *ret_list = kpse_find_file_generic (name, format, must_exist, false); + string ret = *ret_list; + free (ret_list); + return ret; +} + +/* As with `kpse_find_file', but also allow passing ALL for the search, + hence we always return a NULL-terminated list. */ + +string * +kpse_find_file_generic P4C(const_string, name, kpse_file_format_type, format, + boolean, must_exist, boolean, all) +{ const_string *ext; - unsigned name_len = 0; - boolean name_has_suffix_already = false; string mapped_name; string *mapped_names; const_string *target; unsigned count; + unsigned name_len = 0; + boolean name_has_suffix_already = false; boolean use_fontmaps = (format == kpse_tfm_format || format == kpse_gf_format || format == kpse_pk_format || format == kpse_ofm_format); - string ret = NULL; + string *ret = NULL; /* NAME being NULL is a programming bug somewhere. NAME can be empty, though; this happens with constructs like `\input\relax'. */ @@ -765,12 +776,12 @@ kpse_find_file P3C(const_string, name, kpse_file_format_type, format, if (FMT_INFO.path == NULL) kpse_init_format (format); - if (KPSE_DEBUG_P(KPSE_DEBUG_SEARCH)) + if (KPSE_DEBUG_P (KPSE_DEBUG_SEARCH)) DEBUGF3 ("kpse_find_file: searching for %s of type %s (from %s)\n", name, FMT_INFO.type, FMT_INFO.path_source); /* Do variable and tilde expansion. */ - name = kpse_expand(name); + name = kpse_expand (name); /* Does NAME already end in a possible suffix? */ name_len = strlen (name); @@ -789,7 +800,7 @@ kpse_find_file P3C(const_string, name, kpse_file_format_type, format, } } - /* Set up target list. */ + /* Set up list of target names to search for. */ count = 0; target = XTALLOC1 (const_string); /* Case #1: NAME doesn't have a suffix which is equal to a "standard" @@ -827,31 +838,12 @@ kpse_find_file P3C(const_string, name, kpse_file_format_type, format, /* Terminate list. */ target[count] = NULL; - /* Search. */ -#if 0 - /* Simple version, just do the search for the list, and pound disk - * then and there if appropriate. - */ - ret = kpse_path_search_list (FMT_INFO.path, target, must_exist); -#elif 0 - /* Variant where we delay disk-pounding. */ - ret = kpse_path_search_list (FMT_INFO.path, target, false); - if (!ret && must_exist) - ret = kpse_path_search_list (FMT_INFO.path, target, true); -#else - /* Variant that tries the match the original behaviour more closely. - * The distinction is that we pound the disk for a far shorter list - * of names. - * - * This is the fastest variant, because it does fewer disk accesses - * than the two variants above -- for example some 750 calls of - * access(2) compared to 1500. - */ - ret = kpse_path_search_list (FMT_INFO.path, target, false); + /* Search, trying to minimize disk-pounding. */ + ret = kpse_path_search_list_generic (FMT_INFO.path, target, false, all); /* Do we need to pound the disk? */ - if (!ret && must_exist) { + if (! *ret && must_exist) { for (count = 0; target[count]; count++) - free((void*)target[count]); + free ((void *) target[count]); count = 0; /* We look for a subset of the previous set of names, so the * target array is large enough. In particular, we don't pound @@ -859,31 +851,37 @@ kpse_find_file P3C(const_string, name, kpse_file_format_type, format, * should? */ if (!name_has_suffix_already && FMT_INFO.suffix_search_only) { - for (ext = FMT_INFO.suffix; !ret && *ext; ext++) + for (ext = FMT_INFO.suffix; *ext; ext++) target[count++] = concat (name, *ext); } if (name_has_suffix_already || !FMT_INFO.suffix_search_only) { target[count++] = xstrdup (name); } target[count] = NULL; - ret = kpse_path_search_list (FMT_INFO.path, target, true); + ret = kpse_path_search_list_generic (FMT_INFO.path, target, true, all); } -#endif /* Free the list we created. */ for (count = 0; target[count]; count++) - free((void*)target[count]); - free(target); + free ((void *) target[count]); + free (target); - /* If nothing was found, call mktex* to create a missing file. */ + /* If nothing was found, call mktex* to create a missing file. Since + this returns a single string, morph it into a list. */ if (!ret && must_exist) { - ret = kpse_make_tex (format, name); + ret = XTALLOC (2, string); + ret[0] = kpse_make_tex (format, name); + if (ret[0]) { + ret[1] = NULL; + } } - free((void*)name); + free ((void *) name); return ret; } + + /* Open NAME along the search path for TYPE for reading and return the resulting file, or exit with an error message. */ diff --git a/Build/source/texk/kpathsea/tex-file.h b/Build/source/texk/kpathsea/tex-file.h index 72bb26eb2d0..d368fcc43fb 100644 --- a/Build/source/texk/kpathsea/tex-file.h +++ b/Build/source/texk/kpathsea/tex-file.h @@ -174,9 +174,15 @@ extern KPSEDLL const_string kpse_init_format P1H(kpse_file_format_type); /* If FORMAT has a non-null `suffix' member, append it to NAME "." and call `kpse_path_search' with the result and the other arguments. If that fails, try just NAME. */ -extern KPSEDLL string kpse_find_file P3H(const_string name, +extern KPSEDLL string kpse_find_file P3H(const_string name, kpse_file_format_type format, boolean must_exist); +/* Ditto, allowing ALL parameter and hence returning a NULL-terminated + list of results. */ +extern KPSEDLL string *kpse_find_file_generic + P4H(const_string name, kpse_file_format_type format, + boolean must_exist, boolean all); + /* 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) @@ -197,7 +203,6 @@ extern KPSEDLL FILE *kpse_open_file P2H(const_string, kpse_file_format_type); /* This function is used to set kpse_program_name (from progname.c) to a different value. It will clear the path searching information, to ensure that the search paths are appropriate to the new name. */ - extern KPSEDLL void kpse_reset_program_name P1H(const_string progname); #endif /* not KPATHSEA_TEX_FILE_H */ |