beta-0.89.2
[luatex.git] / source / texk / kpathsea / kpsewhich.c
blob83fa3541a8d9ce6d7f556d2e5acc4c692e84635a
1 /* kpsewhich -- standalone path lookup and variable expansion for Kpathsea.
2 Ideas from Thomas Esser, Pierre MacKay, and many others.
4 Copyright 1995-2015 Karl Berry & 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-ctype.h>
21 #include <kpathsea/c-pathch.h>
22 #include <kpathsea/expand.h>
23 #include <kpathsea/getopt.h>
24 #include <kpathsea/line.h>
25 #include <kpathsea/pathsearch.h>
26 #include <kpathsea/proginit.h>
27 #include <kpathsea/str-list.h>
28 #include <kpathsea/tex-file.h>
29 #include <kpathsea/tex-glyph.h>
30 #include <kpathsea/variable.h>
31 #include <kpathsea/version.h>
33 #ifdef WIN32
34 #undef fputs
35 #undef puts
36 #define fputs win32_fputs
37 #define puts win32_puts
38 #endif
40 /* For variable and path expansion. (-expand-var, -expand-path,
41 -show-path) */
42 string var_to_expand = NULL;
43 string braces_to_expand = NULL;
44 string path_to_expand = NULL;
45 string path_to_show = NULL;
46 string var_to_value = NULL;
48 /* Base resolution. (-D, -dpi) */
49 unsigned dpi = 600;
51 /* The engine name, for '$engine' construct in texmf.cnf. (-engine) */
52 string engine = NULL;
54 /* Interactively ask for names to look up? (-interactive) */
55 boolean interactive = false;
57 /* The device name, for $MAKETEX_MODE. (-mode) */
58 string mode = NULL;
60 /* Search the disk as well as ls-R? (-must-exist, -mktex) */
61 boolean must_exist = false;
63 /* The program name, for `.PROG' construct in texmf.cnf. (-program) */
64 string progname = NULL;
66 /* Safe input and output names to check. (-safe-in-name and -safe-out-name) */
67 string safe_in_name = NULL;
68 string safe_out_name = NULL;
70 /* Return all matches, not just the first one? (-all) */
71 boolean show_all = false;
73 /* Only match files in given subdirs. (-subdir) */
74 str_list_type subdir_paths;
76 /* The file type and path for lookups. (-format, -path) */
77 kpse_file_format_type user_format = kpse_last_format;
78 string user_format_string;
79 string user_path;
83 /* Define one-word abbreviations for those format types which
84 can otherwise only be specified by strings containing spaces. */
86 typedef struct
88 const_string abbr;
89 kpse_file_format_type format;
90 } format_abbr_type;
92 static format_abbr_type format_abbrs[]
93 = { { "bitmapfont", kpse_any_glyph_format },
94 { "mpsupport", kpse_mpsupport_format },
95 { "doc", kpse_texdoc_format },
96 { "source", kpse_texsource_format },
97 { "trofffont", kpse_troff_font_format },
98 { "dvipsconfig", kpse_dvips_config_format },
99 { "web2c", kpse_web2c_format },
100 { "othertext", kpse_program_text_format },
101 { "otherbin", kpse_program_binary_format },
102 { "miscfont", kpse_miscfonts_format },
103 { "cmap", kpse_cmap_format },
104 { "pdftexconfig", kpse_pdftex_config_format },
105 { NULL, kpse_last_format } };
107 /* The function to look up STR in the abbr table above.
108 This is called only on a user-specified format string.
109 Return `kpse_last_format' if no match. */
111 static kpse_file_format_type
112 format_abbr (const_string str)
114 kpse_file_format_type ret = kpse_last_format;
115 unsigned a = 0;
117 while (format_abbrs[a].abbr != NULL) {
118 if (STREQ (str, format_abbrs[a].abbr)) {
119 ret = format_abbrs[a].format;
120 break;
122 a++;
125 return ret;
130 /* Return the <number> substring in `<name>.<number><stuff>', if S has
131 that form. If it doesn't, return 0. */
133 static unsigned
134 find_dpi (string s)
136 unsigned dpi_number = 0;
137 const_string extension = find_suffix (s);
139 if (extension != NULL)
140 sscanf (extension, "%u", &dpi_number);
142 return dpi_number;
147 /* Return true if FTRY (the candidate suffix) matches NAME. If
148 IS_FILENAME is true, the check is simply that FTRY is a suffix of
149 NAME. If false (that is, NAME is a format), then FTRY and NAME must
150 be entirely equal. */
152 static boolean
153 try_suffix (boolean is_filename, string name, unsigned name_len,
154 const_string ftry)
156 unsigned try_len;
158 if (!ftry || ! *ftry) {
159 return false;
162 try_len = strlen (ftry);
163 if (try_len > name_len) {
164 /* Candidate is longer than what we're looking for. */
165 return false;
167 if (!is_filename && try_len < name_len) {
168 /* We're doing format names, not file names, and candidate is
169 shorter than what we're looking for. E.g., do not find `lua'
170 when looking for `clua'. */
171 return false;
174 if (FILESTRCASEEQ (name + name_len - try_len, ftry)) {
175 return true;
178 return false;
183 /* Use the file type from -format if that was previously determined
184 (i.e., the user_format global variable), else guess dynamically from
185 NAME. Return kpse_last_format if undeterminable. This function is
186 also used to parse the -format string, a case we distinguish via
187 is_filename being false.
189 A few filenames have been hard-coded for format types that
190 differ from what would be inferred from their extensions. */
192 static kpse_file_format_type
193 find_format (kpathsea kpse, string name, boolean is_filename)
195 kpse_file_format_type ret = kpse_last_format;
197 if (is_filename && user_format != kpse_last_format) {
198 ret = user_format; /* just return what we already computed */
200 } else if (FILESTRCASEEQ (name, "config.ps")) {
201 ret = kpse_dvips_config_format;
202 } else if (FILESTRCASEEQ (name, "fmtutil.cnf")) {
203 ret = kpse_web2c_format;
204 } else if (FILESTRCASEEQ (name, "glyphlist.txt")) {
205 ret = kpse_fontmap_format;
206 } else if (FILESTRCASEEQ (name, "mktex.cnf")) {
207 ret = kpse_web2c_format;
208 } else if (FILESTRCASEEQ (name, "pdfglyphlist.txt")) {
209 ret = kpse_fontmap_format;
210 } else if (FILESTRCASEEQ (name, "pdftex.cfg")) {
211 ret = kpse_pdftex_config_format;
212 } else if (FILESTRCASEEQ (name, "texglyphlist.txt")) {
213 ret = kpse_fontmap_format;
214 } else if (FILESTRCASEEQ (name, "texmf.cnf")) {
215 ret = kpse_cnf_format;
216 } else if (FILESTRCASEEQ (name, "updmap.cfg")) {
217 ret = kpse_web2c_format;
218 } else if (FILESTRCASEEQ (name, "XDvi")) {
219 ret = kpse_program_text_format;
220 } else {
221 if (!is_filename) {
222 /* Look for kpsewhich-specific format abbreviations. */
223 ret = format_abbr (name);
226 if (ret == kpse_last_format) {
227 int f = 0; /* kpse_file_format_type */
228 unsigned name_len = strlen (name);
230 while (f != kpse_last_format) {
231 const_string *ext;
232 const_string ftry;
233 boolean found = false;
235 if (!kpse->format_info[f].type)
236 kpathsea_init_format (kpse, (kpse_file_format_type) f);
238 /* Just to abbreviate this lengthy call. */
239 #define TRY_SUFFIX(ftry) try_suffix (is_filename, name, name_len, (ftry))
241 if (!is_filename) {
242 /* Allow the long name, but only in the format options. We don't
243 want a filename confused with a format name. */
244 ftry = kpse->format_info[f].type;
245 found = TRY_SUFFIX (ftry);
247 for (ext = kpse->format_info[f].suffix; !found && ext && *ext; ext++) {
248 found = TRY_SUFFIX (*ext);
250 for (ext=kpse->format_info[f].alt_suffix; !found && ext && *ext;ext++){
251 found = TRY_SUFFIX (*ext);
254 if (found)
255 break;
256 f++;
258 ret = f;
261 return ret;
266 /* Return newly-allocated NULL-terminated list of strings from MATCHES
267 that are prefixed with any of the subdirectories in SUBDIRS. That
268 is, for a string S in MATCHES, its dirname must end with one of the
269 elements in SUBDIRS. For instance, if subdir=foo/bar, that will
270 match a string foo/bar/baz or /some/texmf/foo/bar/baz.
272 We don't reallocate the actual strings, just the list elements.
273 Perhaps later we will implement wildcards or // or something. */
275 static string *
276 subdir_match (str_list_type subdirs, string *matches)
278 string *ret = XTALLOC1 (string);
279 unsigned len = 1;
280 unsigned e;
281 unsigned m;
282 #if defined(WIN32)
283 string p;
285 for (e = 0; e < STR_LIST_LENGTH (subdirs); e++) {
286 for (p = STR_LIST_ELT (subdirs, e); *p; p++) {
287 if (*p == '\\')
288 *p = '/';
289 else if (IS_KANJI(p))
290 p++;
293 #endif
295 for (m = 0; matches[m]; m++) {
296 unsigned loc;
297 string s = xstrdup (matches[m]);
298 for (loc = strlen (s); loc > 0 && !IS_DIR_SEP_CH (s[loc-1]); loc--)
300 while (loc > 0 && IS_DIR_SEP_CH (s[loc-1])) {
301 loc--;
303 s[loc] = 0; /* wipe out basename */
305 for (e = 0; e < STR_LIST_LENGTH (subdirs); e++) {
306 string subdir = STR_LIST_ELT (subdirs, e);
307 unsigned subdir_len = strlen (subdir);
308 while (subdir_len > 0 && IS_DIR_SEP_CH (subdir[subdir_len-1])) {
309 subdir_len--;
310 subdir[subdir_len] = 0; /* remove trailing slashes from subdir spec */
312 if (FILESTRCASEEQ (subdir, s + loc - subdir_len)) {
313 /* matched, save this one. */
314 XRETALLOC (ret, len + 1, string);
315 ret[len-1] = matches[m];
316 len++;
319 free (s);
321 ret[len-1] = NULL;
322 return ret;
327 /* Look up a single filename NAME. Return 0 if success, 1 if failure. */
329 static unsigned
330 lookup (kpathsea kpse, string name)
332 int i;
333 string ret = NULL;
334 string *ret_list = NULL;
336 if (user_path) {
337 /* Translate ; to : if that's our ENV_SEP. See cnf.c. */
338 if (IS_ENV_SEP (':')) {
339 string loc;
340 for (loc = user_path; *loc; loc++) {
341 if (*loc == ';')
342 *loc = ':';
345 user_path = kpathsea_path_expand (kpse, user_path);
346 if (show_all) {
347 ret_list = kpathsea_all_path_search (kpse, user_path, name);
348 } else {
349 ret = kpathsea_path_search (kpse, user_path, name, must_exist);
352 } else {
353 /* No user-specified search path, check user format or guess from NAME. */
354 kpse_file_format_type fmt = find_format (kpse, name, true);
356 switch (fmt) {
357 case kpse_pk_format:
358 case kpse_gf_format:
359 case kpse_any_glyph_format:
361 kpse_glyph_file_type glyph_ret;
362 string temp = remove_suffix (name);
363 /* Try to extract the resolution from the name. */
364 unsigned local_dpi = find_dpi (name);
365 if (!local_dpi)
366 local_dpi = dpi;
367 ret = kpathsea_find_glyph (kpse, temp,
368 local_dpi, fmt, &glyph_ret);
369 if (temp != name)
370 free (temp);
372 break;
374 case kpse_last_format:
375 /* If the suffix isn't recognized, assume it's a tex file. */
376 fmt = kpse_tex_format;
377 /* fall through */
379 default:
380 if (show_all) {
381 ret_list = kpathsea_find_file_generic (kpse, name, fmt,
382 must_exist, true);
383 } else {
384 ret = kpathsea_find_file (kpse, name, fmt, must_exist);
389 /* Turn single return into a null-terminated list for uniform treatment. */
390 if (ret) {
391 ret_list = XTALLOC (2, string);
392 ret_list[0] = ret;
393 ret_list[1] = NULL;
396 /* Filter by subdirectories, if specified. */
397 if (STR_LIST_LENGTH (subdir_paths) > 0) {
398 string *new_list = subdir_match (subdir_paths, ret_list);
399 free (ret_list);
400 ret_list = new_list;
403 /* Print output. */
404 if (ret_list) {
405 for (i = 0; ret_list[i]; i++)
406 puts (ret_list[i]);
407 /* Save whether we found anything */
408 ret = ret_list[0];
409 free (ret_list);
412 return ret == NULL;
415 /* Help message. */
417 #define USAGE "\n\
418 Standalone path lookup and expansion for the Kpathsea library.\n\
419 The default is to look up each FILENAME in turn and report its\n\
420 first match (if any) to standard output.\n\
422 When looking up format (.fmt/.base/.mem) files, it is usually necessary\n\
423 to also use -engine, or nothing will be returned; in particular,\n\
424 -engine=/ will return matching format files for any engine.\n\
426 -all output all matches, one per line.\n\
427 -debug=NUM set debugging flags.\n\
428 -D, -dpi=NUM use a base resolution of NUM; default 600.\n\
429 -engine=STRING set engine name to STRING.\n\
430 -expand-braces=STRING output variable and brace expansion of STRING.\n\
431 -expand-path=STRING output complete path expansion of STRING.\n\
432 -expand-var=STRING output variable expansion of STRING.\n\
433 -format=NAME use file type NAME (list shown by -help-formats).\n\
434 -help display this message and exit.\n\
435 -help-formats display information about all supported file formats.\n\
436 -interactive ask for additional filenames to look up.\n\
437 [-no]-mktex=FMT disable/enable mktexFMT generation (FMT=pk/mf/tex/tfm).\n\
438 -mode=STRING set device name for $MAKETEX_MODE to STRING; no default.\n\
439 -must-exist search the disk as well as ls-R if necessary.\n\
440 -path=STRING search in the path STRING.\n\
441 -progname=STRING set program name to STRING.\n\
442 -safe-in-name=STRING check if STRING is ok to open for input.\n\
443 -safe-out-name=STRING check if STRING is ok to open for output.\n\
444 -show-path=NAME output search path for file type NAME\n\
445 (list shown by -help-formats).\n\
446 -subdir=STRING only output matches whose directory ends with STRING.\n\
447 -var-value=STRING output the value of variable $STRING.\n\
448 -version display version information number and exit.\n \
451 static void
452 help_message (kpathsea kpse, string *argv)
454 printf ("Usage: %s [OPTION]... [FILENAME]...\n", argv[0]);
455 fputs (USAGE, stdout);
456 putchar ('\n');
457 fputs (kpathsea_bug_address, stdout);
458 fputs ("Kpathsea home page: http://tug.org/kpathsea/\n", stdout);
459 exit (0);
462 static void
463 help_formats (kpathsea kpse, string *argv)
465 int f; /* kpse_file_format_type */
467 /* Have to set this for init_format to work. */
468 kpathsea_set_program_name (kpse, argv[0], progname);
470 puts (kpathsea_version_string);
471 puts ("\nRecognized Kpathsea format names and their (abbreviations) and suffixes:");
472 for (f = 0; f < kpse_last_format; f++) {
473 const_string *ext;
475 const_string envvar_list =
476 kpathsea_init_format_return_varlist (kpse, (kpse_file_format_type) f);
477 printf ("%s", kpse->format_info[f].type);
479 /* Show abbreviation if we accept one. We repeatedly go through the
480 abbr list here, but it's so short, it doesn't matter. */
482 unsigned a = 0;
483 while (format_abbrs[a].abbr != NULL) {
484 if (f == format_abbrs[a].format) {
485 printf (" (%s)", format_abbrs[a].abbr);
486 break;
488 a++;
492 /* Regular suffixes. */
493 putchar (':');
494 for (ext = kpse->format_info[f].suffix; ext && *ext; ext++) {
495 putchar (' ');
496 fputs (*ext, stdout);
499 if (kpse->format_info[f].alt_suffix) {
500 /* leave extra space between default and alt suffixes */
501 putchar (' ');
503 for (ext = kpse->format_info[f].alt_suffix; ext && *ext; ext++) {
504 putchar (' ');
505 fputs (*ext, stdout);
508 printf (" [variables: %s]\n", envvar_list);
510 printf (" [original path (from %s) = %s]\n",
511 kpse->format_info[f].path_source, kpse->format_info[f].raw_path);
514 fputs ("\nTo see paths after expansion, use --show-path=FMT.\n\n", stdout);
515 fputs (kpathsea_bug_address, stdout);
516 exit (0);
520 /* Reading the options. */
522 /* This macro tests whether getopt found an option ``A''.
523 Assumes the option index is in the variable `option_index', and the
524 option table in a variable `long_options'. */
525 #define ARGUMENT_IS(a) STREQ (long_options[option_index].name, a)
527 /* SunOS cc can't initialize automatic structs. */
528 static struct option long_options[]
529 = { { "D", 1, 0, 0 },
530 { "all", 0, (int *) &show_all, 1 },
531 { "debug", 1, 0, 0 },
532 { "dpi", 1, 0, 0 },
533 { "engine", 1, 0, 0 },
534 { "expand-braces", 1, 0, 0 },
535 { "expand-path", 1, 0, 0 },
536 { "expand-var", 1, 0, 0 },
537 { "format", 1, 0, 0 },
538 { "help", 0, 0, 0 },
539 { "help-formats", 0, 0, 0 },
540 { "interactive", 0, (int *) &interactive, 1 },
541 { "mktex", 1, 0, 0 },
542 { "mode", 1, 0, 0 },
543 { "must-exist", 0, (int *) &must_exist, 1 },
544 { "path", 1, 0, 0 },
545 { "no-mktex", 1, 0, 0 },
546 { "progname", 1, 0, 0 },
547 { "safe-in-name", 1, 0, 0 },
548 { "safe-out-name", 1, 0, 0 },
549 { "subdir", 1, 0, 0 },
550 { "show-path", 1, 0, 0 },
551 { "var-value", 1, 0, 0 },
552 { "version", 0, 0, 0 },
553 { 0, 0, 0, 0 } };
555 static void
556 read_command_line (kpathsea kpse, int argc, string *argv)
558 int g; /* `getopt' return code. */
559 int option_index;
561 for (;;) {
562 g = getopt_long_only (argc, argv, "", long_options, &option_index);
564 if (g == -1)
565 break;
567 if (g == '?')
568 exit (1); /* Unknown option. */
570 assert (g == 0); /* We have no short option names. */
572 if (ARGUMENT_IS ("debug")) {
573 kpse->debug |= atoi (optarg);
575 } else if (ARGUMENT_IS ("dpi") || ARGUMENT_IS ("D")) {
576 dpi = atoi (optarg);
578 } else if (ARGUMENT_IS ("engine")) {
579 engine = optarg;
581 } else if (ARGUMENT_IS ("expand-braces")) {
582 braces_to_expand = optarg;
584 } else if (ARGUMENT_IS ("expand-path")) {
585 path_to_expand = optarg;
587 } else if (ARGUMENT_IS ("expand-var")) {
588 var_to_expand = optarg;
590 } else if (ARGUMENT_IS ("format")) {
591 user_format_string = optarg;
593 } else if (ARGUMENT_IS ("help")) {
594 help_message (kpse, argv);
596 } else if (ARGUMENT_IS ("help-formats")) {
597 help_formats (kpse, argv);
599 } else if (ARGUMENT_IS ("mktex")) {
600 kpathsea_maketex_option (kpse, optarg, true);
601 must_exist = 1; /* otherwise it never gets called */
603 } else if (ARGUMENT_IS ("mode")) {
604 mode = optarg;
606 } else if (ARGUMENT_IS ("no-mktex")) {
607 kpathsea_maketex_option (kpse, optarg, false);
608 must_exist = 0;
610 } else if (ARGUMENT_IS ("path")) {
611 user_path = optarg;
613 } else if (ARGUMENT_IS ("progname")) {
614 progname = optarg;
616 } else if (ARGUMENT_IS ("safe-in-name")) {
617 safe_in_name = optarg;
619 } else if (ARGUMENT_IS ("safe-out-name")) {
620 safe_out_name = optarg;
622 } else if (ARGUMENT_IS ("show-path")) {
623 path_to_show = optarg;
624 user_format_string = optarg;
626 } else if (ARGUMENT_IS ("subdir")) {
627 str_list_add (&subdir_paths, optarg);
629 } else if (ARGUMENT_IS ("var-value")) {
630 var_to_value = optarg;
632 } else if (ARGUMENT_IS ("version")) {
633 puts (kpathsea_version_string);
634 puts ("Copyright 2015 Karl Berry & Olaf Weber.\n\
635 License LGPLv2.1+: GNU Lesser GPL version 2.1 or later <http://gnu.org/licenses/lgpl.html>\n\
636 This is free software: you are free to change and redistribute it.\n\
637 There is NO WARRANTY, to the extent permitted by law.\n");
638 exit (0);
641 /* Else it was just a flag; getopt has already done the assignment. */
644 if (user_path && user_format_string) {
645 fprintf (stderr, "-path (%s) and -format (%s) are mutually exclusive.\n",
646 user_path, user_format_string);
647 fputs ("Try `kpsewhich --help' for more information.\n", stderr);
648 exit (1);
651 if (optind == argc
652 && !var_to_expand && !braces_to_expand && !path_to_expand
653 && !path_to_show && !var_to_value
654 && !safe_in_name && !safe_out_name) {
655 fputs ("Missing argument. Try `kpsewhich --help' for more information.\n",
656 stderr);
657 exit (1);
663 /* Initializations that may depend on the options. */
665 static void
666 init_more (kpathsea kpse)
668 if (engine)
669 kpathsea_xputenv (kpse, "engine", engine);
671 /* Disable all mktex programs unless they were explicitly enabled on our
672 command line. */
673 #define DISABLE_MKTEX(fmt) \
674 kpathsea_set_program_enabled (kpse, fmt, false, kpse_src_cmdline - 1)
675 DISABLE_MKTEX (kpse_pk_format);
676 DISABLE_MKTEX (kpse_mf_format);
677 DISABLE_MKTEX (kpse_tex_format);
678 DISABLE_MKTEX (kpse_tfm_format);
679 DISABLE_MKTEX (kpse_fmt_format);
680 DISABLE_MKTEX (kpse_ofm_format);
681 DISABLE_MKTEX (kpse_ocp_format);
683 /* NULL for no fallback font. */
684 kpathsea_init_prog (kpse, uppercasify (kpse->program_name), dpi, mode, NULL);
686 /* Have to do this after setting the program name. */
687 if (user_format_string) {
688 user_format = find_format (kpse, user_format_string, false);
689 if (user_format == kpse_last_format) {
690 WARNING1 ("kpsewhich: Ignoring unknown file type `%s'",
691 user_format_string);
699 main (int argc, string *argv)
701 #ifdef WIN32
702 string *av, enc;
703 int ac;
704 #endif
705 unsigned unfound = 0;
706 kpathsea kpse = kpathsea_new();
708 /* Read options, then dependent initializations. */
709 read_command_line (kpse, argc, argv);
711 kpathsea_set_program_name (kpse, argv[0], progname);
712 #ifdef WIN32
713 if(strstr(kpse->program_name,"xetex") || strstr(kpse->program_name,"xelatex")
714 || strstr(kpse->program_name,"uptex") || strstr(kpse->program_name,"uplatex")
715 || strstr(kpse->program_name,"dvipdfm") || strstr(kpse->program_name,"extractbb")
716 || strstr(kpse->program_name,"xbb") || strstr(kpse->program_name,"ebb")
717 || strstr(kpse->program_name,"dvips"))
719 enc = kpathsea_var_value (kpse, "command_line_encoding");
720 if (get_command_line_args_utf8(enc, &ac, &av)) {
721 optind = 0;
722 read_command_line (kpse, ac, av);
723 argv = av;
724 argc = ac;
727 #endif
728 init_more (kpse);
731 /* Perform actions. */
733 /* Variable expansion. */
734 if (var_to_expand)
735 puts (kpathsea_var_expand (kpse, var_to_expand));
737 /* Brace expansion. */
738 if (braces_to_expand)
739 puts (kpathsea_brace_expand (kpse, braces_to_expand));
741 /* Path expansion. */
742 if (path_to_expand)
743 puts (kpathsea_path_expand (kpse, path_to_expand));
745 /* Show a search path. */
746 if (path_to_show) {
747 if (user_format != kpse_last_format) {
748 if (!kpse->format_info[user_format].type) /* needed if arg was numeric */
749 kpathsea_init_format (kpse, user_format);
750 puts (kpse->format_info[user_format].path);
751 } else {
752 WARNING ("kpsewhich: Cannot show path for unknown file type");
756 /* Var to value. */
757 if (var_to_value) {
758 const_string value = kpathsea_var_value (kpse, var_to_value);
759 if (!value) {
760 unfound++;
761 value = "";
763 puts (value);
766 if (safe_in_name) {
767 if (!kpathsea_in_name_ok_silent (kpse, safe_in_name))
768 unfound++;
771 if (safe_out_name) {
772 if (!kpathsea_out_name_ok_silent (kpse, safe_out_name))
773 unfound++;
776 /* --subdir must imply --all, since we filter here after doing the
777 search, rather than inside the search itself. */
778 if (STR_LIST_LENGTH (subdir_paths) > 0) {
779 show_all = 1;
782 /* Usual case: look up each given filename. */
783 for (; optind < argc; optind++) {
784 unfound += lookup (kpse, argv[optind]);
787 if (interactive) {
788 for (;;) {
789 string name = read_line (stdin);
790 if (!name || STREQ (name, "q") || STREQ (name, "quit"))
791 break;
792 unfound += lookup (kpse, name);
793 free (name);
797 kpathsea_finish (kpse);
798 return unfound > 255 ? 1 : unfound;