beta-0.89.2
[luatex.git] / source / texk / kpathsea / pathsearch.c
blob0f59ac5ed95c20507fa8e37e40d594e0b4f966ef
1 /* pathsearch.c: look up a filename in a path.
3 Copyright 1993, 1994, 1995, 1997, 2007, 2009-2012 Karl Berry.
4 Copyright 1997-2005 Olaf Weber.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with this library; if not, see <http://www.gnu.org/licenses/>. */
19 #include <kpathsea/config.h>
20 #include <kpathsea/c-pathch.h>
21 #include <kpathsea/c-fopen.h>
22 #include <kpathsea/absolute.h>
23 #include <kpathsea/expand.h>
24 #include <kpathsea/db.h>
25 #include <kpathsea/pathsearch.h>
26 #include <kpathsea/readable.h>
27 #include <kpathsea/str-list.h>
28 #include <kpathsea/str-llist.h>
29 #include <kpathsea/variable.h>
31 #include <time.h> /* for `time' */
33 #ifdef __DJGPP__
34 #include <sys/stat.h> /* for stat bits */
35 #endif
37 #ifdef WIN32
38 #undef fputs
39 #undef puts
40 #define fputs win32_fputs
41 #define puts win32_puts
42 #endif
44 /* The very first search is for texmf.cnf, called when someone tries to
45 initialize the TFM path or whatever. init_path calls kpse_cnf_get
46 which calls kpse_all_path_search to find all the texmf.cnf's. We
47 need to do various special things in this case, since we obviously
48 don't yet have the configuration files when we're searching for the
49 configuration files. */
53 /* This function is called after every search (except the first, since
54 we definitely want to allow enabling the logging in texmf.cnf) to
55 record the filename(s) found in $TEXMFLOG. */
57 static void
58 log_search (kpathsea kpse, str_list_type filenames)
61 if (kpse->log_opened == false) {
62 /* Get name from either envvar or config file. */
63 string log_name = kpathsea_var_value (kpse, "TEXMFLOG");
64 kpse->log_opened = true;
65 if (log_name) {
66 kpse->log_file = fopen (log_name, FOPEN_A_MODE);
67 if (!kpse->log_file)
68 perror (log_name);
69 free (log_name);
73 if (
74 #ifdef KPSE_DEBUG
75 KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH) ||
76 #endif /* KPSE_DEBUG */
77 kpse->log_file) {
78 unsigned e;
80 /* FILENAMES should never be null, but safety doesn't hurt. */
81 for (e = 0; e < STR_LIST_LENGTH (filenames) && STR_LIST_ELT (filenames, e);
82 e++) {
83 string filename = STR_LIST_ELT (filenames, e);
85 /* Only record absolute filenames, for privacy. */
86 if (kpse->log_file && kpathsea_absolute_p (kpse, filename, false))
87 fprintf (kpse->log_file, "%lu %s\n", (long unsigned) time (NULL),
88 filename);
90 #ifdef KPSE_DEBUG
91 /* And show them online, if debugging. We've already started
92 the debugging line in `search', where this is called, so
93 just print the filename here, don't use DEBUGF. */
94 if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) {
95 putc (' ', stderr);
96 fputs (filename, stderr);
98 #endif /* KPSE_DEBUG */
103 /* Concatenate each element in DIRS with NAME (assume each ends with a
104 /, to save time). If SEARCH_ALL is false, return the first readable
105 regular file. Else continue to search for more. In any case, if
106 none, return a list containing just NULL.
108 We keep a single buffer for the potential filenames and reallocate
109 only when necessary. I'm not sure it's noticeably faster, but it
110 does seem cleaner. (We do waste a bit of space in the return
111 value, though, since we don't shrink it to the final size returned.) */
113 #define INIT_ALLOC 75 /* Doesn't much matter what this number is. */
115 static str_list_type
116 dir_list_search (kpathsea kpse, str_llist_type *dirs, const_string name,
117 boolean search_all)
119 str_llist_elt_type *elt;
120 str_list_type ret;
121 unsigned name_len = strlen (name);
122 unsigned allocated = INIT_ALLOC;
123 string potential = (string)xmalloc (allocated);
125 ret = str_list_init ();
127 for (elt = *dirs; elt; elt = STR_LLIST_NEXT (*elt))
129 const_string dir = STR_LLIST (*elt);
130 unsigned dir_len = strlen (dir);
132 while (dir_len + name_len + 1 > allocated)
134 allocated += allocated;
135 XRETALLOC (potential, allocated, char);
138 strcpy (potential, dir);
139 strcat (potential, name);
141 if (kpathsea_readable_file (kpse, potential))
143 str_list_add (&ret, potential);
145 /* Move this element towards the top of the list. */
146 str_llist_float (dirs, elt);
148 /* If caller only wanted one file returned, no need to
149 terminate the list with NULL; the caller knows to only look
150 at the first element. */
151 if (!search_all)
152 return ret;
154 /* Start new filename. */
155 allocated = INIT_ALLOC;
156 potential = (string)xmalloc (allocated);
160 /* If we get here, either we didn't find any files, or we were finding
161 all the files. But we're done with the last filename, anyway. */
162 free (potential);
164 return ret;
167 /* Note: NAMES[i] is not modified. */
168 static str_list_type
169 dir_list_search_list (kpathsea kpse, str_llist_type *dirs, string* names,
170 boolean search_all)
172 str_llist_elt_type *elt;
173 str_list_type ret;
174 unsigned allocated = INIT_ALLOC;
175 string potential = XTALLOC(allocated, char);
177 ret = str_list_init ();
179 for (elt = *dirs; elt; elt = STR_LLIST_NEXT(*elt)) {
180 const_string dir = STR_LLIST (*elt);
181 unsigned dir_len = strlen (dir);
182 int i;
184 for (i = 0; names[i]; i++) {
185 const_string name = names[i];
186 unsigned name_len;
188 /* Don't bother with absolute & explicit relative. */
189 if (kpathsea_absolute_p(kpse, name, true))
190 continue;
192 name_len = strlen(name);
194 while (dir_len + name_len + 1 > allocated) {
195 allocated += allocated;
196 XRETALLOC (potential, allocated, char);
199 strcpy (potential, dir);
200 strcat (potential+dir_len, name);
202 if (kpathsea_readable_file (kpse, potential)) {
203 str_list_add (&ret, potential);
205 /* Move this element towards the top of the list. */
206 str_llist_float (dirs, elt);
208 /* If caller only wanted one file returned, no need to
209 terminate the list with NULL; the caller knows to only look
210 at the first element. */
211 if (!search_all)
212 return ret;
214 /* Start new filename. */
215 allocated = INIT_ALLOC;
216 potential = XTALLOC(allocated, char);
221 /* If we get here, either we didn't find any files, or we were finding
222 all the files. But we're done with the last filename, anyway. */
223 free (potential);
225 return ret;
228 /* This is called when NAME is absolute or explicitly relative; if it's
229 readable, return (a list containing) it; otherwise, return NULL. */
231 static str_list_type
232 absolute_search (kpathsea kpse, string name)
234 str_list_type ret_list;
235 string found = kpathsea_readable_file (kpse, name);
237 /* Some old compilers can't initialize structs. */
238 ret_list = str_list_init ();
240 /* If NAME wasn't found, free the expansion. */
241 if (name != found)
242 free (name);
244 /* Add `found' to the return list even if it's null; that tells
245 the caller we didn't find anything. */
246 str_list_add (&ret_list, found);
248 return ret_list;
251 /* This is the hard case -- look for NAME in PATH. If ALL is false,
252 return the first file found. Otherwise, search all elements of PATH. */
254 static str_list_type
255 path_search (kpathsea kpse, const_string path, string name,
256 boolean must_exist, boolean all)
258 string elt;
259 str_list_type ret_list;
260 boolean done = false;
261 ret_list = str_list_init (); /* some compilers lack struct initialization */
263 for (elt = kpathsea_path_element (kpse, path); !done && elt;
264 elt = kpathsea_path_element (kpse, NULL)) {
265 str_list_type *found;
266 boolean allow_disk_search = true;
268 if (*elt == '!' && *(elt + 1) == '!') {
269 /* Those magic leading chars in a path element means don't search the
270 disk for this elt. And move past the magic to get to the name. */
271 allow_disk_search = false;
272 elt += 2;
275 /* See elt-dirs.c for side effects of this function */
276 kpathsea_normalize_path(kpse, elt);
278 /* Try ls-R, unless we're searching for texmf.cnf. Our caller
279 (search), also tests first_search, and does the resetting. */
280 found = kpse->followup_search ? kpathsea_db_search (kpse, name, elt, all)
281 : NULL;
283 /* Search the filesystem if (1) the path spec allows it, and either
284 (2a) we are searching for texmf.cnf ; or
285 (2b) no db exists; or
286 (2c) no db's are relevant to this elt; or
287 (3) MUST_EXIST && NAME was not in the db.
288 In (2*), `found' will be NULL.
289 In (3), `found' will be an empty list. */
290 if (allow_disk_search && (!found || (must_exist && !STR_LIST (*found)))) {
291 str_llist_type *dirs = kpathsea_element_dirs (kpse, elt);
292 if (dirs && *dirs) {
293 if (!found)
294 found = XTALLOC1 (str_list_type);
295 *found = dir_list_search (kpse, dirs, name, all);
299 /* Did we find anything anywhere? */
300 if (found && STR_LIST (*found)) {
301 if (all)
302 str_list_concat (&ret_list, *found);
303 else {
304 str_list_add (&ret_list, STR_LIST_ELT (*found, 0));
305 done = true;
309 /* Free the list space, if any (but not the elements). */
310 if (found) {
311 str_list_free (found);
312 free (found);
316 /* Free the expanded name we were passed. It can't be in the return
317 list, since the path directories got unconditionally prepended. */
318 free (name);
320 return ret_list;
323 /* Search PATH for ORIGINAL_NAME. If ALL is false, or ORIGINAL_NAME is
324 absolute_p, check ORIGINAL_NAME itself. Otherwise, look at each
325 element of PATH for the first readable ORIGINAL_NAME.
327 Always return a list; if no files are found, the list will
328 contain just NULL. If ALL is true, the list will be
329 terminated with NULL. */
331 static string *
332 search (kpathsea kpse, const_string path, const_string original_name,
333 boolean must_exist, boolean all)
335 str_list_type ret_list;
336 string name;
337 boolean absolute_p;
339 #ifdef __DJGPP__
340 /* We will use `stat' heavily, so let's request for
341 the fastest possible version of `stat', by telling
342 it what members of struct stat do we really need.
344 We need to set this on each call because this is a
345 library function; the caller might need other options
346 from `stat'. Thus save the flags and restore them
347 before exit.
349 This call tells `stat' that we do NOT need to recognize
350 executable files (neither by an extension nor by a magic
351 signature); that we do NOT need time stamp of root directories;
352 and that we do NOT need the write access bit in st_mode.
354 Note that `kpse_set_program_name' needs the EXEC bits,
355 but it was already called by the time we get here. */
356 unsigned short save_djgpp_flags = _djstat_flags;
358 _djstat_flags = _STAT_EXEC_MAGIC | _STAT_EXEC_EXT
359 | _STAT_ROOT_TIME | _STAT_WRITEBIT;
360 #endif
362 /* Make a leading ~ count as an absolute filename, and expand $FOO's. */
363 name = kpathsea_expand (kpse, original_name);
365 /* If the first name is absolute or explicitly relative, no need to
366 consider PATH at all. */
367 absolute_p = kpathsea_absolute_p (kpse, name, true);
369 #ifdef KPSE_DEBUG
370 if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH))
371 DEBUGF4 ("start search(file=%s, must_exist=%d, find_all=%d, path=%s).\n",
372 name, must_exist, all, path);
373 #endif /* KPSE_DEBUG */
375 /* Find the file(s). */
376 ret_list = absolute_p ? absolute_search (kpse, name)
377 : path_search (kpse, path, name, must_exist, all);
379 /* Append NULL terminator if we didn't find anything at all, or we're
380 supposed to find ALL and the list doesn't end in NULL now. */
381 if (STR_LIST_LENGTH (ret_list) == 0
382 || (all && STR_LIST_LAST_ELT (ret_list) != NULL))
383 str_list_add (&ret_list, NULL);
385 /* The very first search is for texmf.cnf. We can't log that, since
386 we want to allow setting TEXMFLOG in texmf.cnf. */
387 if (kpse->followup_search == false) {
388 kpse->followup_search = true;
389 } else {
390 /* Record the filenames we found, if desired. And wrap them in a
391 debugging line if we're doing that. */
392 #ifdef KPSE_DEBUG
393 if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH))
394 DEBUGF1 ("search(%s) =>", original_name);
395 #endif /* KPSE_DEBUG */
396 log_search (kpse, ret_list);
397 #ifdef KPSE_DEBUG
398 if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH))
399 putc ('\n', stderr);
400 #endif /* KPSE_DEBUG */
403 #ifdef __DJGPP__
404 /* Undo any side effects. */
405 _djstat_flags = save_djgpp_flags;
406 #endif
408 return STR_LIST (ret_list);
411 /* Search PATH for NAMES.
413 Always return a list; if no files are found, the list will
414 contain just NULL. If ALL is true, the list will be
415 terminated with NULL. */
417 string *
418 kpathsea_path_search_list_generic (kpathsea kpse,
419 const_string path, string* names,
420 boolean must_exist, boolean all)
422 str_list_type ret_list;
423 string* namep;
424 string elt;
425 boolean done = false;
426 boolean all_absolute = true;
428 #ifdef __DJGPP__
429 /* We will use `stat' heavily, so let's request for
430 the fastest possible version of `stat', by telling
431 it what members of struct stat do we really need.
433 We need to set this on each call because this is a
434 library function; the caller might need other options
435 from `stat'. Thus save the flags and restore them
436 before exit.
438 This call tells `stat' that we do NOT need to recognize
439 executable files (neither by an extension nor by a magic
440 signature); that we do NOT need time stamp of root directories;
441 and that we do NOT need the write access bit in st_mode.
443 Note that `kpse_set_program_name' needs the EXEC bits,
444 but it was already called by the time we get here. */
445 unsigned short save_djgpp_flags = _djstat_flags;
447 _djstat_flags = _STAT_EXEC_MAGIC | _STAT_EXEC_EXT
448 | _STAT_ROOT_TIME | _STAT_WRITEBIT;
449 #endif
451 ret_list = str_list_init();
453 #ifdef KPSE_DEBUG
454 if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) {
455 DEBUGF1 ("start search(files=[%s", *names);
456 for (namep = names+1; *namep != NULL; namep++) {
457 fputc(' ', stderr);
458 fputs(*namep, stderr);
460 fprintf (stderr, "], must_exist=%d, find_all=%d, path=%s).\n",
461 must_exist, all, path);
463 #endif /* KPSE_DEBUG */
465 /* FIXME: is this really true? No need to do any expansion on names. */
467 /* First catch any absolute or explicit relative names. */
468 for (namep = names; *namep; namep++) {
469 if (kpathsea_absolute_p (kpse, *namep, true)) {
470 if (kpathsea_readable_file (kpse, *namep)) {
471 str_list_add (&ret_list, xstrdup(*namep));
472 if (!all)
473 goto out;
475 } else {
476 all_absolute = false;
479 /* Shortcut: if we were only given absolute/explicit relative names,
480 we can skip the rest. Typically, if one name is absolute, they
481 all are, because our caller derived them from each other. */
482 if (all_absolute)
483 goto out;
485 /* Look at each path element in turn. */
486 for (elt = kpathsea_path_element (kpse, path); !done && elt;
487 elt = kpathsea_path_element (kpse, NULL))
489 str_list_type *found;
490 boolean allow_disk_search = true;
491 if (elt[0] == '!' && elt[1] == '!') {
492 /* !! magic -> disallow disk searches. */
493 allow_disk_search = false;
494 elt += 2;
497 /* See elt-dirs.c for side effects of this function. */
498 kpathsea_normalize_path (kpse, elt);
500 /* Try ls-R, unless we're searching for texmf.cnf. */
501 found = kpse->followup_search
502 ? kpathsea_db_search_list (kpse, names, elt, all) : NULL;
504 /* Search the filesystem if (1) the path spec allows it, and either
505 (2a) we are searching for texmf.cnf ; or
506 (2b) no db exists; or
507 (2c) no db's are relevant to this elt; or
508 (3) MUST_EXIST && NAME was not in the db.
509 In (2*), `found' will be NULL.
510 In (3), `found' will be an empty list. */
511 if (allow_disk_search && (!found || (must_exist && !STR_LIST(*found)))) {
512 str_llist_type *dirs = kpathsea_element_dirs (kpse, elt);
513 if (dirs && *dirs) {
514 if (!found)
515 found = XTALLOC1 (str_list_type);
516 *found = dir_list_search_list (kpse, dirs, names, all);
520 /* Did we find anything? */
521 if (found && STR_LIST (*found)) {
522 if (all) {
523 str_list_concat (&ret_list, *found);
524 } else {
525 str_list_add (&ret_list, STR_LIST_ELT (*found, 0));
526 done = true;
531 out:
532 /* Uniqify, since our paths can often end up finding the same file
533 more than once. */
534 str_list_uniqify (&ret_list);
536 /* Add NULL if we will be returning multiple elements. */
537 if (STR_LIST_LENGTH (ret_list) == 0
538 || (all && STR_LIST_LAST_ELT (ret_list) != NULL))
539 str_list_add (&ret_list, NULL);
541 if (kpse->followup_search == false) {
542 kpse->followup_search = true;
543 } else {
544 /* Record the filenames we found, if desired. And wrap them in a
545 debugging line if we're doing that. */
546 #ifdef KPSE_DEBUG
547 if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH)) {
548 DEBUGF1 ("search([%s", *names);
549 for (namep = names+1; *namep != NULL; namep++) {
550 fputc (' ', stderr);
551 fputs (*namep, stderr);
553 fputs ("]) =>", stderr);
555 #endif /* KPSE_DEBUG */
556 log_search (kpse, ret_list);
557 #ifdef KPSE_DEBUG
558 if (KPATHSEA_DEBUG_P (KPSE_DEBUG_SEARCH))
559 putc ('\n', stderr);
560 #endif /* KPSE_DEBUG */
563 #ifdef __DJGPP__
564 /* Undo any side effects. */
565 _djstat_flags = save_djgpp_flags;
566 #endif
568 return STR_LIST (ret_list);
571 /* Search PATH for the first NAME according to MUST_EXIST. */
573 string
574 kpathsea_path_search (kpathsea kpse, const_string path, const_string name,
575 boolean must_exist)
577 string *ret_list = search (kpse, path, name, must_exist, false);
578 string ret = *ret_list;
579 free (ret_list);
580 return ret;
583 /* Search PATH for all files named NAME. Might have been better not
584 to assert `must_exist' here, but it's too late to change. */
586 string *
587 kpathsea_all_path_search (kpathsea kpse, const_string path, const_string name)
589 string *ret = search (kpse, path, name, true, true);
590 return ret;
593 #if defined (KPSE_COMPAT_API)
595 string
596 kpse_path_search (const_string path, const_string name, boolean must_exist)
598 return kpathsea_path_search (kpse_def, path, name, must_exist);
601 string *
602 kpse_all_path_search (const_string path, const_string name)
604 return kpathsea_all_path_search (kpse_def, path, name);
606 #endif
609 #ifdef TEST
611 void
612 test_path_search (const_string path, const_string file)
614 string answer;
615 string *answer_list;
617 printf ("\nSearch %s for %s:\t", path, file);
618 answer = kpse_path_search (path, file, 0);
619 puts (answer ? answer : "(nil)");
621 printf ("Search %s for all %s:\t", path, file);
622 answer_list = kpse_all_path_search (path, file);
623 putchar ('\n');
624 while (*answer_list)
626 putchar ('\t');
627 puts (*answer_list);
628 answer_list++;
632 #define TEXFONTS "/usr/local/lib/tex/fonts"
635 main (int argc, char **argv)
637 kpse_set_program_name(argv[0], NULL);
638 /* All lists end with NULL. */
639 test_path_search (".", "nonexistent");
640 test_path_search (".", "/nonexistent");
641 test_path_search ("/k" ENV_SEP_STRING ".", "kpathsea.texi");
642 test_path_search ("/k" ENV_SEP_STRING ".", "/etc/fstab");
643 test_path_search ("." ENV_SEP_STRING TEXFONTS "//", "cmr10.tfm");
644 test_path_search ("." ENV_SEP_STRING TEXFONTS "//", "logo10.tfm");
645 test_path_search (TEXFONTS "//times" ENV_SEP_STRING "."
646 ENV_SEP_STRING ENV_SEP_STRING, "ptmr.vf");
647 test_path_search (TEXFONTS "/adobe//" ENV_SEP_STRING
648 "/usr/local/src/TeX+MF/typefaces//", "plcr.pfa");
650 test_path_search ("~karl", ".bashrc");
651 test_path_search ("/k", "~karl/.bashrc");
653 xputenv ("NONEXIST", "nonexistent");
654 test_path_search (".", "$NONEXISTENT");
655 xputenv ("KPATHSEA", "kpathsea");
656 test_path_search ("/k" ENV_SEP_STRING ".", "$KPATHSEA.texi");
657 test_path_search ("/k" ENV_SEP_STRING ".", "${KPATHSEA}.texi");
658 test_path_search ("$KPATHSEA" ENV_SEP_STRING ".", "README");
659 test_path_search ("." ENV_SEP_STRING "$KPATHSEA", "README");
661 return 0;
664 #endif /* TEST */
668 Local variables:
669 standalone-compile-command: "gcc -posix -g -I. -I.. -DTEST pathsearch.c kpathsea.a"
670 End: