diff options
author | Denis Bitouzé <dbitouze@wanadoo.fr> | 2021-02-25 18:23:07 +0000 |
---|---|---|
committer | Denis Bitouzé <dbitouze@wanadoo.fr> | 2021-02-25 18:23:07 +0000 |
commit | c6101f91d071883b48b1b4b51e5eba0f36d9a78d (patch) | |
tree | 1bf7f5a881d7a4f5c5bf59d0b2821943dd822372 /Build/source/texk/kpathsea/db.c | |
parent | 07ee7222e389b0777456b427a55c22d0e6ffd267 (diff) |
French translation for tlmgr updated
git-svn-id: svn://tug.org/texlive/trunk@57912 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/kpathsea/db.c')
-rw-r--r-- | Build/source/texk/kpathsea/db.c | 807 |
1 files changed, 0 insertions, 807 deletions
diff --git a/Build/source/texk/kpathsea/db.c b/Build/source/texk/kpathsea/db.c deleted file mode 100644 index fb4658c1968..00000000000 --- a/Build/source/texk/kpathsea/db.c +++ /dev/null @@ -1,807 +0,0 @@ -/* db.c: an external database to avoid filesystem lookups. - - Copyright 1994, 1995, 1996, 1997, 2008, 2009, 2011, 2012, 2014, 2016, - 2017 Karl Berry. - Copyright 1997-2005 Olaf Weber. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - 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, see <http://www.gnu.org/licenses/>. */ - -#include <kpathsea/config.h> -#include <kpathsea/absolute.h> -#include <kpathsea/c-stat.h> -#include <kpathsea/c-fopen.h> -#include <kpathsea/c-pathch.h> -#include <kpathsea/db.h> -#include <kpathsea/hash.h> -#include <kpathsea/line.h> -#include <kpathsea/pathsearch.h> -#include <kpathsea/readable.h> -#include <kpathsea/str-list.h> -#include <kpathsea/tex-file.h> -#include <kpathsea/variable.h> - -#ifndef DB_HASH_SIZE -/* Based on the size of 2014 texmf-dist/ls-R, about 130,000 entries. */ -#define DB_HASH_SIZE 64007 -#endif -#ifndef DB_NAME -#define DB_NAME "ls-R" -#endif -#ifndef DB_NAME_LC -#define DB_NAME_LC "ls-r" -#endif - -/* In the loop in init() below where we check for DB_NAME_LC and DB_NAME - being the same file, it's convenient to ignore the first of a pair. - So put the canonical name second. Sure wish I hadn't used a capital - letter in the name in the first place. */ -/* We use non-const strings initialized with string constants in order - to avoid some compiler warnings. */ -static char db_name_lc[] = DB_NAME_LC; -static char db_name[] = DB_NAME; -static string db_names[] = { - db_name_lc, - db_name, - NULL -}; - -#ifndef ALIAS_NAME -#define ALIAS_NAME "aliases" -#endif -#ifndef ALIAS_HASH_SIZE -#define ALIAS_HASH_SIZE 1009 -#endif - - -/* If DIRNAME contains any element beginning with a `.' (that is more - than just `./'), return true. This is to allow ``hidden'' - directories -- ones that don't get searched. */ - -static boolean -ignore_dir_p (const_string dirname) -{ - const_string dot_pos = dirname; - - while ((dot_pos = strchr (dot_pos + 1, '.'))) { - /* If / before and no / after, skip it. */ - if (IS_DIR_SEP_CH (dot_pos[-1]) && dot_pos[1] && !IS_DIR_SEP_CH (dot_pos[1])) - return true; - } - - return false; -} - -/* If no DB_FILENAME, return false (maybe they aren't using this feature). - Otherwise, add entries from DB_FILENAME to TABLE, and return true. */ - -static boolean -db_build (kpathsea kpse, hash_table_type *table, const_string db_filename) -{ - string line; - unsigned dir_count = 0, file_count = 0, ignore_dir_count = 0; - unsigned len = strlen (db_filename) - sizeof (DB_NAME) + 1; /* Keep the /. */ - string top_dir = (string)xmalloc (len + 1); - string cur_dir = NULL; /* First thing in ls-R might be a filename. */ - FILE *db_file = fopen (db_filename, FOPEN_R_MODE); -#if defined(MONOCASE_FILENAMES) - string pp; -#endif /* MONOCASE_FILENAMES */ - - strncpy (top_dir, db_filename, len); - top_dir[len] = 0; - - if (db_file) { - while ((line = read_line (db_file)) != NULL) { - len = strlen (line); - -#if defined(MONOCASE_FILENAMES) - for (pp = line; *pp; pp++) { -#if defined(_WIN32) - if (kpathsea_IS_KANJI(kpse, pp)) - pp++; - else -#endif /* _WIN32 */ - *pp = TRANSFORM(*pp); - } -#endif /* MONOCASE_FILENAMES */ - - /* A line like `/foo:' = new dir foo. Allow both absolute (/...) - and explicitly relative (./...) names here. It's a kludge to - pass in the directory name with the trailing : still attached, - but it doesn't actually hurt. */ - if (len > 0 && line[len - 1] == ':' - && kpathsea_absolute_p (kpse, line, true)) { - /* New directory line. */ - if (!ignore_dir_p (line)) { - /* If they gave a relative name, prepend full directory name now. */ - line[len - 1] = DIR_SEP; - /* Skip over leading `./', it confuses `match' and is just a - waste of space, anyway. This will lose on `../', but `match' - won't work there, either, so it doesn't matter. */ - cur_dir = *line == '.' ? concat (top_dir, line + 2) : xstrdup (line); - dir_count++; - } else { - cur_dir = NULL; - ignore_dir_count++; - } - - /* Ignore blank, `.' and `..' lines. */ - } else if (*line != 0 && cur_dir /* a file line? */ - && !(*line == '.' - && (line[1] == 0 || (line[1] == '.' && line[2] == 0)))) - { - /* Make a new hash table entry with a key of `line' and a data - of `cur_dir'. An already-existing identical key is ok, since - a file named `foo' can be in more than one directory. Share - `cur_dir' among all its files (and hence never free it). - - Note that we assume that all names in the ls-R file have already - been case-smashed to lowercase where appropriate. - */ - hash_insert_normalized (table, xstrdup (line), cur_dir); - file_count++; - - } /* else ignore blank lines or top-level files - or files in ignored directories*/ - - free (line); - } - - xfclose (db_file, db_filename); - - if (file_count == 0) { - WARNING1 ("kpathsea: %s: No usable entries in ls-R", db_filename); - WARNING ("kpathsea: See the manual for how to generate ls-R"); - db_file = NULL; - } else { - str_list_add (&(kpse->db_dir_list), xstrdup (top_dir)); - } - -#ifdef KPSE_DEBUG - if (KPATHSEA_DEBUG_P (KPSE_DEBUG_HASH)) { - /* Don't make this a debugging bit, since the output is so - voluminous, and being able to specify -1 is too useful. - Instead, let people who want it run the program under - a debugger and change the variable that way. */ - boolean hash_summary_only = true; - - DEBUGF4 ("%s: %u entries in %d directories (%d hidden).\n", - db_filename, file_count, dir_count, ignore_dir_count); - DEBUGF ("ls-R hash table:"); - hash_print (*table, hash_summary_only); - fflush (stderr); - } -#endif /* KPSE_DEBUG */ - } - - free (top_dir); - - return db_file != NULL; -} - - -/* Insert FNAME into the hash table. This is for files that get built - during a run. We wouldn't want to reread all of ls-R, even if it got - rebuilt. */ - -void -kpathsea_db_insert (kpathsea kpse, const_string passed_fname) -{ - /* We might not have found ls-R, or even had occasion to look for it - yet, so do nothing if we have no hash table. */ - if (kpse->db.buckets) { - const_string dir_part; - string fname = xstrdup (passed_fname); - string baseptr = fname + (xbasename (fname) - fname); - const_string file_part = xstrdup (baseptr); - - *baseptr = '\0'; /* Chop off the filename. */ - dir_part = fname; /* That leaves the dir, with the trailing /. */ - - /* Note that we do not assuse that these names have been normalized. */ - hash_insert (&(kpse->db), file_part, dir_part); - } -} - -/* 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 boolean -match (const_string filename, const_string path_elt) -{ - const_string original_filename = filename; - boolean matched = false; - - for (; *filename && *path_elt; filename++, path_elt++) { - if (FILECHARCASEEQ (*filename, *path_elt)) /* normal character match */ - ; - - else if (IS_DIR_SEP_CH (*path_elt) /* at // */ - && original_filename < filename && IS_DIR_SEP_CH (path_elt[-1])) { - while (IS_DIR_SEP_CH (*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_CH (filename[-1]) - && FILECHARCASEEQ (*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 (that is, no directory separators remaining); - only then have we matched. */ - if (!matched && *path_elt == 0) { - /* Typically PATH_ELT ends with, say, `vf', and FILENAME ends with - `vf/ptmr.vf'. In that case, we'll be at the /. 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 sep in FILENAME, skip it. */ - if (IS_DIR_SEP_CH (*filename)) - filename++; - - /* Here are the basic possibilities for the check on being at the - last component: - 1) PATH_ELT is empty and FILENAME is `ptmr.vf' => match. - (we now have original_filename == filename) - 2) PATH_ELT is empty and FILENAME is `foo/ptmr.vf' => no match. - (we now have original_filename == filename) - 3) PATH_ELT is `vf/' and FILENAME is `vf/ptmr.vf' - (we are now after the / in each) => match. - 4) PATH_ELT is `vf' and FILENAME is `vfoo.ext' - (we are now after the f in each) => no match. - - When (the original) PATH_ELT was the empty string, we want to match - a FILENAME without dir seps. (This could be argued, and may never - happen in practice, but is the historical behavior.) */ - /* if original_filename != filename then original_filename < filename */ - if (original_filename == filename || IS_DIR_SEP_CH (filename[-1])) { - while (*filename && !IS_DIR_SEP_CH (*filename)) - filename++; - matched = *filename == 0; - } - } - - return matched; -} - - -/* If DB_DIR is a prefix of PATH_ELT, return true; otherwise false. - That is, the question is whether to try the db for a file looked up - in PATH_ELT. If PATH_ELT == ".", for example, the answer is no. If - PATH_ELT == "/usr/local/lib/texmf/fonts//tfm", the answer is yes. - If either string is NULL or empty, return false. - - In practice, ls-R is only needed for lengthy subdirectory - comparisons, but there's no gain to checking PATH_ELT to see if it is - a subdir match, since the only way to do that is to do a string - search in it, which is all we do anyway. */ - -static boolean -elt_in_db (const_string db_dir, const_string path_elt) -{ - boolean found = false; - - /* If both strings are empty or null return false on the grounds that - it's useless to do anything further with such a strange case (which - likely never happens). In theory one could argue that the empty - string is a prefix of any other string, but let's just declare the - result otherwise. */ - if (db_dir == NULL || *db_dir == 0 - || path_elt == NULL || *path_elt == 0) - return false; - - while (!found && FILECHARCASEEQ (*db_dir++, *path_elt++)) { - /* If we've matched the entire db directory, it's good. */ - if (*db_dir == 0) - found = true; - - /* If we've reached the end of PATH_ELT, but not the end of the db - directory, it's no good. */ - else if (*path_elt == 0) - break; - } - - return found; -} - -/* If ALIAS_FILENAME exists, read it into TABLE. */ - -static boolean -alias_build (kpathsea kpse, hash_table_type *table, - const_string alias_filename) -{ - string line, real, alias; - unsigned count = 0; - FILE *alias_file = fopen (alias_filename, FOPEN_R_MODE); - - if (alias_file) { - while ((line = read_line (alias_file)) != NULL) { - /* comments or empty */ - if (*line == 0 || *line == '%' || *line == '#') { - ; - } else { - /* Each line should have two fields: realname aliasname. */ - real = line; - while (*real && ISSPACE (*real)) - real++; - alias = real; - while (*alias && !ISSPACE (*alias)) - alias++; - *alias++ = 0; - while (*alias && ISSPACE (*alias)) - alias++; - /* Is the check for errors strong enough? Should we warn the user - for potential errors? */ - if (strlen (real) != 0 && strlen (alias) != 0) { - /* Stuff in the alias file should be normalized. */ - hash_insert_normalized (table, xstrdup (alias), xstrdup (real)); - count++; - } - } - free (line); - } - -#ifdef KPSE_DEBUG - if (KPATHSEA_DEBUG_P (KPSE_DEBUG_HASH)) { - /* As with ls-R above ... */ - boolean hash_summary_only = true; - DEBUGF2 ("%s: %u aliases.\n", alias_filename, count); - DEBUGF ("alias hash table:"); - hash_print (*table, hash_summary_only); - fflush (stderr); - } -#endif /* KPSE_DEBUG */ - - xfclose (alias_file, alias_filename); - } - - return alias_file != NULL; -} - -/* Initialize the path for ls-R files, and read them all into the hash - table `db'. If no usable ls-R's found, set kpse->db.buckets to NULL. */ - -void -kpathsea_init_db (kpathsea kpse) -{ - const_string db_path; - string *db_files; - string *orig_db_files; - str_list_type unique_list; - int dbi; - boolean ok = false; - - assert (sizeof(DB_NAME) == sizeof(DB_NAME_LC)); - - db_path = kpathsea_init_format (kpse, kpse_db_format); - db_files = kpathsea_path_search_list_generic (kpse, db_path, db_names, - true, true); - orig_db_files = db_files; - - /* Mac OS X and others can use a case-insensitive, case-preserving - filesystem by default, in which case ls-R and ls-r point to the - same file. Also, Windows is case-insensitive. In these cases, - we want to avoid reading the same file multiple times. */ - dbi = 0; - unique_list = str_list_init (); - - while (db_files[dbi] != NULL) { - string path1 = db_files[dbi]; - string path2 = db_files[dbi + 1]; - - /* first-pass check in case path1/path2 aren't even - potentially equal; mainly in case the order from - kpathsea_path_search_list_generic changes. */ - if (path2 - && strcasecmp (path1, path2) == 0 - && same_file_p (path1, path2)) { - /* they are the same, skip over path1, we'll add path2 - on the next iteration (when it's path1). */ -#ifdef KPSE_DEBUG - if (KPATHSEA_DEBUG_P (KPSE_DEBUG_HASH)) { - DEBUGF2 ("db:init(): skipping db same_file_p %s, will add %s.\n", - path1, path2); - } -#endif - free (path1); - - } else { - /* they are not the same, add path1. */ -#ifdef KPSE_DEBUG - if (KPATHSEA_DEBUG_P (KPSE_DEBUG_HASH)) { - DEBUGF1 ("db:init(): using db file %s.\n", path1); - } -#endif - str_list_add (&unique_list, path1); - } - - /* could be more clever and increment by two, but then would - have to avoid jumping off the end of db_files */ - dbi++; - } - - /* always add a NULL terminator. */ - str_list_add (&unique_list, NULL); - - free (orig_db_files); - db_files = STR_LIST (unique_list); - orig_db_files = db_files; - - /* Must do this after the path searching (which ends up calling - kpse_db_search recursively), so kpse->db.buckets stays NULL. */ - kpse->db = hash_create (DB_HASH_SIZE); - - while (db_files && *db_files) { - if (db_build (kpse, &(kpse->db), *db_files)) - ok = true; - free (*db_files); - db_files++; - } - - if (!ok) { - /* If db can't be built, leave `size' nonzero (so we don't - rebuild it), but clear `buckets' (so we don't look in it). */ - free (kpse->db.buckets); - kpse->db.buckets = NULL; - } - - free (orig_db_files); - - /* Add the content of any alias databases. There may exist more than - one alias file along DB_NAME files. This duplicates the above code - -- should be a function. */ - ok = false; - db_files = kpathsea_all_path_search (kpse, db_path, ALIAS_NAME); - orig_db_files = db_files; - - kpse->alias_db = hash_create (ALIAS_HASH_SIZE); - - while (db_files && *db_files) { - if (alias_build (kpse, &(kpse->alias_db), *db_files)) - ok = true; - free (*db_files); - db_files++; - } - - if (!ok) { - free (kpse->alias_db.buckets); - kpse->alias_db.buckets = NULL; - } - - free (orig_db_files); -} - -/* Avoid doing anything if this PATH_ELT is irrelevant to the databases. */ -str_list_type * -kpathsea_db_search (kpathsea kpse, const_string name, - const_string orig_path_elt, boolean all) -{ - const_string *db_dirs, *orig_dirs; - const_string last_slash, path_elt; - string temp_str = NULL; - boolean done; - unsigned e; - str_list_type *ret = NULL; - const_string *aliases, *r; - boolean relevant = false; - - /* If we failed to build the database (or if this is the recursive - call to build the db path), quit. */ - if (kpse->db.buckets == NULL) - return NULL; - - /* When tex-glyph.c calls us looking for, e.g., dpi600/cmr10.pk, we - won't find it unless we change NAME to just `cmr10.pk' and append - `/dpi600' to PATH_ELT. We are justified in using a literal `/' - here, since that's what tex-glyph.c unconditionally uses in - DPI_BITMAP_SPEC. But don't do anything if the / begins NAME; that - should never happen. */ - last_slash = strrchr (name, '/'); - if (last_slash && last_slash != name) { - unsigned len = last_slash - name + 1; - string dir_part = (string)xmalloc (len); - strncpy (dir_part, name, len - 1); - dir_part[len - 1] = 0; - path_elt = temp_str = concat3 (orig_path_elt, "/", dir_part); - name = last_slash + 1; - free (dir_part); - } else - path_elt = orig_path_elt; - - /* Don't bother doing any lookups if this `path_elt' isn't covered by - any of database directories. We do this not so much because the - extra couple of hash lookups matter -- they don't -- but rather - because we want to return NULL in this case, so path_search can - know to do a disk search. */ - for (e = 0; !relevant && e < STR_LIST_LENGTH (kpse->db_dir_list); e++) { - relevant = elt_in_db (STR_LIST_ELT (kpse->db_dir_list, e), path_elt); - } - if (!relevant) - return NULL; - - /* If we have aliases for this name, use them. */ - if (kpse->alias_db.buckets) - aliases = hash_lookup (kpse->alias_db, name); - else - aliases = NULL; - - if (!aliases) { - aliases = XTALLOC1 (const_string); - aliases[0] = NULL; - } - { /* Push aliases up by one and insert the original name at the front. */ - unsigned i; - unsigned len = 1; /* Have NULL element already allocated. */ - for (r = aliases; *r; r++) - len++; - /* This is essentially - XRETALLOC (aliases, len + 1, const_string); - except that MSVC warns without the cast to `void *'. */ - aliases = (const_string *) xrealloc ((void *) aliases, - (len + 1) * sizeof(const_string)); - for (i = len; i > 0; i--) { - aliases[i] = aliases[i - 1]; - } - aliases[0] = name; - } - - done = false; - for (r = aliases; !done && *r; r++) { - const_string ctry = *r; - - /* We have an ls-R db. Look up `try'. */ - orig_dirs = db_dirs = hash_lookup (kpse->db, ctry); - - ret = XTALLOC1 (str_list_type); - *ret = str_list_init (); - - /* For each filename found, see if it matches the path element. For - example, if we have .../cx/cmr10.300pk and .../ricoh/cmr10.300pk, - and the path looks like .../cx, we don't want the ricoh file. */ - while (!done && db_dirs && *db_dirs) { - string db_file = concat (*db_dirs, ctry); - boolean matched = match (db_file, path_elt); - -#ifdef KPSE_DEBUG - if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) - DEBUGF3 ("db:match(%s,%s) = %d\n", db_file, path_elt, matched); -#endif - - /* We got a hit in the database. Now see if the file actually - exists, possibly under an alias. */ - if (matched) { - string found = NULL; - if (kpathsea_readable_file (kpse, db_file)) { - found = db_file; - - } else { - const_string *a; - - free (db_file); /* `db_file' wasn't on disk. */ - - /* The hit in the DB doesn't exist in disk. Now try all its - aliases. For example, suppose we have a hierarchy on CD, - thus `mf.bas', but ls-R contains `mf.base'. Find it anyway. - Could probably work around this with aliases, but - this is pretty easy and shouldn't hurt. The upshot is that - if one of the aliases actually exists, we use that. */ - for (a = aliases + 1; *a && !found; a++) { - string atry = concat (*db_dirs, *a); - if (kpathsea_readable_file (kpse, atry)) - found = atry; - else - free (atry); - } - } - - /* If we have a real file, add it to the list, maybe done. */ - if (found) { - str_list_add (ret, found); - if (!all && found) - done = true; - } - } else { /* no match in the db */ - free (db_file); - } - - - /* On to the next directory, if any. */ - db_dirs++; - } - - /* This is just the space for the pointers, not the strings. */ - if (orig_dirs && *orig_dirs) - free (orig_dirs); - } - - free ((void *) aliases); - - /* If we had to break up NAME, free the TEMP_STR. */ - if (temp_str) - free (temp_str); - - return ret; -} - -str_list_type * -kpathsea_db_search_list (kpathsea kpse, string* names, - const_string path_elt, boolean all) -{ - const_string *db_dirs, *orig_dirs; - const_string last_slash, name, path; - string temp_str = NULL; - boolean done; - unsigned e; - const_string *aliases, *r; - int n; - str_list_type *ret = NULL; - boolean relevant = false; - - /* If we failed to build the database (or if this is the recursive - call to build the db path), quit. */ - if (kpse->db.buckets == NULL) - return NULL; - - /* Don't bother doing any lookups if this `path_elt' isn't covered by - any of database directories. We do this not so much because the - extra couple of hash lookups matter -- they don't -- but rather - because we want to return NULL in this case, so path_search can - know to do a disk search. */ - for (e = 0; !relevant && e < STR_LIST_LENGTH (kpse->db_dir_list); e++) { - relevant = elt_in_db (STR_LIST_ELT (kpse->db_dir_list, e), path_elt); - } - if (!relevant) - return NULL; - - done = false; - ret = XTALLOC1 (str_list_type); - *ret = str_list_init (); - - /* Handle each name. */ - for (n = 0; !done && names[n]; n++) { - name = names[n]; - - /* Absolute names should have been caught in our caller. */ - if (kpathsea_absolute_p(kpse, name, true)) - continue; - - /* When tex-glyph.c calls us looking for, e.g., dpi600/cmr10.pk, we - won't find it unless we change NAME to just `cmr10.pk' and append - `/dpi600' to PATH_ELT. We are justified in using a literal `/' - here, since that's what tex-glyph.c unconditionally uses in - DPI_BITMAP_SPEC. But don't do anything if the / begins NAME; that - should never happen. */ - last_slash = strrchr (name, '/'); - if (last_slash && last_slash != name) { - unsigned len = last_slash - name + 1; - string dir_part = (string)xmalloc (len); - strncpy (dir_part, name, len - 1); - dir_part[len - 1] = 0; - path = temp_str = concat3 (path_elt, "/", dir_part); - name = last_slash + 1; - free (dir_part); - } else { - path = path_elt; - } - - /* If we have aliases for this name, use them. */ - if (kpse->alias_db.buckets) - aliases = hash_lookup (kpse->alias_db, name); - else - aliases = NULL; - - if (!aliases) { - aliases = XTALLOC1 (const_string); - aliases[0] = NULL; - } - { /* Push aliases up by one and insert the original name at front. */ - unsigned i; - unsigned len = 1; /* Have NULL element already allocated. */ - for (r = aliases; *r; r++) - len++; - aliases = (const_string *) xrealloc ((void *) aliases, - (len + 1) * sizeof(const_string)); - for (i = len; i > 0; i--) { - aliases[i] = aliases[i - 1]; - } - aliases[0] = name; - } - - for (r = aliases; !done && *r; r++) { - const_string ctry = *r; - - /* We have an ls-R db. Look up `try'. */ - orig_dirs = db_dirs = hash_lookup (kpse->db, ctry); - - /* For each filename found, see if it matches the path element. For - example, if we have .../cx/cmr10.300pk and .../ricoh/cmr10.300pk, - and the path looks like .../cx, we don't want the ricoh file. */ - while (!done && db_dirs && *db_dirs) { - string db_file = concat (*db_dirs, ctry); - boolean matched = match (db_file, path); - -#ifdef KPSE_DEBUG - if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) - DEBUGF3 ("db:match(%s,%s) = %d\n", db_file, path, matched); -#endif - - /* We got a hit in the database. Now see if the file actually - exists, possibly under an alias. */ - if (matched) { - string found = NULL; - if (kpathsea_readable_file (kpse, db_file)) { - found = db_file; - - } else { - const_string *a; - - free (db_file); /* `db_file' wasn't on disk. */ - - /* The hit in the DB doesn't exist in disk. Now try all its - aliases. For example, suppose we have a hierarchy on CD, - thus `mf.bas', but ls-R contains `mf.base'. Find it anyway. - Could probably work around this with aliases, but - this is pretty easy and shouldn't hurt. The upshot is that - if one of the aliases actually exists, we use that. */ - for (a = aliases + 1; *a && !found; a++) { - string atry = concat (*db_dirs, *a); - if (kpathsea_readable_file (kpse, atry)) - found = atry; - else - free (atry); - } - } - - /* If we have a real file, add it to the list, maybe done. */ - if (found) { - str_list_add (ret, found); - if (!all) - done = true; - } - } else { /* no match in the db */ - free (db_file); - } - - /* On to the next directory, if any. */ - db_dirs++; - } - - /* This is just the space for the pointers, not the strings. */ - if (orig_dirs && *orig_dirs) - free (orig_dirs); - } - - free ((void *) aliases); - if (temp_str) - free (temp_str); - } - - return ret; -} |