home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / unixtex-6.1b-src.tgz / tar.out / contrib / unixtex / kpathsea / kpsewhich.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-28  |  6.9 KB  |  259 lines

  1. /* kpsewhich -- standalone path lookup and variable expansion for Kpathsea.
  2.    Ideas from Tom Esser and Pierre MacKay.
  3.  
  4. Copyright (C) 1995 Karl Berry.
  5.  
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. This program 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
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include <kpathsea/config.h>
  21. #include <kpathsea/getopt.h>
  22. #include <kpathsea/line.h>
  23. #include <kpathsea/proginit.h>
  24. #include <kpathsea/progname.h>
  25. #include <kpathsea/tex-file.h>
  26. #include <kpathsea/tex-glyph.h>
  27. #include <kpathsea/variable.h>
  28.  
  29.  
  30. /* Base resolution. (-D, -dpi) */
  31. unsigned dpi = 300;
  32.  
  33. /* A construct to do variable expansion on.  (-expand) */
  34. string expand = NULL;
  35.  
  36. /* The file type for lookups.  (-format) */
  37. kpse_file_format_type format = kpse_last_format;
  38.  
  39. /* Ask interactively?  (-interactive) */
  40. boolean interactive = false;
  41.  
  42. /* The device name, for $MAKETEX_MODE.  (-mode) */
  43. string mode = NULL;
  44.  
  45. /* The program name, for `.program' in texmf.cnf.  (-program) */
  46. string progname = NULL;
  47.  
  48. /* Return the <number> substring in `<name>.<number><stuff>', if S has
  49.    that form.  If it doesn't, return 0.  */
  50.  
  51. static unsigned
  52. find_dpi P1C(string, s)
  53. {
  54.   unsigned dpi_number = 0;
  55.   string extension = find_suffix (s);
  56.   
  57.   if (extension != NULL)
  58.     sscanf (extension, "%u", &dpi_number);
  59.  
  60.   return dpi_number;
  61. }
  62.  
  63. /* Use the -format if specified, else guess dynamically from NAME.  */
  64.  
  65. /* We could partially initialize this array from `kpse_format_info',
  66.    but it doesn't seem worth the trouble.  */
  67. static const_string suffix[]
  68.   = { "gf", "pk", "", ".base", ".bib", ".bst", ".cnf", ".fmt", ".mf",
  69.       ".pool", ".eps", ".tex", ".pool", ".tfm", ".vf", ".ps", ".pfa" };
  70.  
  71. static kpse_file_format_type
  72. find_format P1C(string, name)
  73. {
  74.   kpse_file_format_type ret;
  75.   
  76.   if (format != kpse_last_format)
  77.     ret = format;
  78.   else
  79.     {
  80.       unsigned name_len = strlen (name);
  81.       for (ret = 0; ret < kpse_last_format; ret++)
  82.         {
  83.           const_string suffix_try = suffix[ret];
  84.           unsigned try_len = strlen (suffix_try);
  85.           if (try_len && try_len < name_len
  86.               && STREQ (suffix_try, name + name_len - try_len))
  87.             break;
  88.         }
  89.       if (ret == kpse_last_format)
  90.         {
  91.           fprintf (stderr,
  92.                    "kpsewhich: Can't guess format for %s, using tex.\n", name);
  93.           ret = kpse_tex_format;
  94.         }
  95.     }
  96.   
  97.   return ret;
  98. }
  99.  
  100. /* Look up a single filename NAME.  Return 0 if success, 1 if failure.  */
  101.  
  102. static unsigned
  103. lookup P1C(string, name)
  104. {
  105.   string ret;
  106.   unsigned local_dpi;
  107.   kpse_glyph_file_type glyph_ret;
  108.   kpse_file_format_type fmt = find_format (name);
  109.   
  110.   switch (fmt)
  111.     {
  112.     case kpse_pk_format:
  113.     case kpse_gf_format:
  114.     case kpse_any_glyph_format:
  115.       /* Try to extract the resolution from the name.  */
  116.       local_dpi = find_dpi (name);
  117.       if (!local_dpi)
  118.         local_dpi = dpi;
  119.       ret = kpse_find_glyph (remove_suffix (name), local_dpi, fmt, &glyph_ret);
  120.       break;
  121.     default:
  122.       ret = kpse_find_file (name, fmt, false);
  123.     }
  124.   
  125.   if (ret)
  126.     puts (ret);
  127.   
  128.   return ret == NULL;
  129. }
  130.  
  131. /* Reading the options.  */
  132.  
  133. #define USAGE "Options:\n\
  134.   You can use `--' or `-' to start an option.\n\
  135.   You can use any unambiguous abbreviation for an option name.\n\
  136.   You can separate option names and values with `=' or ` '.\n\
  137. debug <integer>: set debugging flags.\n\
  138. D, dpi <unsigned>: use a base resolution of <unsigned>; default 300.\n\
  139. expand <string>: do variable expansion on <string>.\n\
  140. help: print this message and exit.\n\
  141. interactive: ask for additional filenames to look up.\n\
  142. mode <string>: set device name for $MAKETEX_MODE to <string>; no default.\n\
  143. version: print version number and exit.\n\
  144. "
  145.  
  146. /* Test whether getopt found an option ``A''.
  147.    Assumes the option index is in the variable `option_index', and the
  148.    option table in a variable `long_options'.  */
  149. #define ARGUMENT_IS(a) STREQ (long_options[option_index].name, a)
  150.  
  151. /* SunOS cc can't initialize automatic structs.  */
  152. static struct option long_options[]
  153.   = { { "debug",        1, 0, 0 },
  154.       { "dpi",            1, 0, 0 },
  155.       { "D",            1, 0, 0 },
  156.       { "expand",        1, 0, 0 },
  157.       { "format",        1, 0, 0 },
  158.       { "help",                 0, 0, 0 },
  159.       { "interactive",        0, (int *) &interactive, 1 },
  160.       { "mode",            1, 0, 0 },
  161.       { "program",        1, 0, 0 },
  162.       { "version",              0, 0, 0 },
  163.       { 0, 0, 0, 0 } };
  164.  
  165.  
  166. /* We return the name of the font to process.  */
  167.  
  168. static void
  169. read_command_line P2C(int, argc,  string *, argv)
  170. {
  171.   int g;   /* `getopt' return code.  */
  172.   int option_index;
  173.  
  174.   while (true)
  175.     {
  176.       g = getopt_long_only (argc, argv, "", long_options, &option_index);
  177.       
  178.       if (g == EOF)
  179.         break;
  180.  
  181.       if (g == '?')
  182.         exit (1);  /* Unknown option.  */
  183.   
  184.       assert (g == 0); /* We have no short option names.  */
  185.       
  186.       if (ARGUMENT_IS ("debug"))
  187.         kpathsea_debug |= atoi (optarg);
  188.  
  189.       else if (ARGUMENT_IS ("dpi") || ARGUMENT_IS ("D"))
  190.         dpi = atoi (optarg);
  191.  
  192.       else if (ARGUMENT_IS ("expand"))
  193.         expand = optarg;
  194.  
  195.       else if (ARGUMENT_IS ("format"))
  196.         format = atoi (optarg);
  197.  
  198.       else if (ARGUMENT_IS ("help"))
  199.         {
  200.           printf ("Usage: %s [options] [filenames].\n", argv[0]);
  201.           fputs (USAGE, stdout);
  202.           exit (0);
  203.         }
  204.  
  205.       else if (ARGUMENT_IS ("mode"))
  206.         mode = optarg;
  207.  
  208.       else if (ARGUMENT_IS ("program"))
  209.         progname = optarg;
  210.  
  211.       else if (ARGUMENT_IS ("version"))
  212.         {
  213.           extern char *kpathsea_version_string; /* from version.c */
  214.           printf ("%s.\n", kpathsea_version_string);
  215.           exit (0);
  216.         }
  217.       
  218.       /* Else it was just a flag; getopt has already done the assignment.  */
  219.     }
  220. }
  221.  
  222. int
  223. main P2C(int, argc,  string *, argv)
  224. {
  225.   unsigned unfound = 0;
  226.   
  227.   read_command_line (argc, argv);
  228.   
  229.   if (!progname)
  230.     progname = (string) "";
  231.  
  232.   kpse_set_progname (progname);
  233.   
  234.   /* false for no MakeTeXPK, NULL for no fallback font.  */
  235.   kpse_init_prog (uppercasify (progname), dpi, mode, false, NULL);
  236.   
  237.   /* No extra frills on expansion output, to make it easy to use.  */
  238.   if (expand)
  239.     puts (kpse_var_expand (expand));
  240.  
  241.   for (; optind < argc; optind++)
  242.     {
  243.       unfound += lookup (argv[optind]);
  244.     }
  245.  
  246.   if (interactive)
  247.     {
  248.       for (;;)
  249.         {
  250.           string name = read_line (stdin);
  251.           if (!name || STREQ (name, "q") || STREQ (name, "quit")) break;
  252.           unfound += lookup (name);
  253.           free (name);
  254.         }
  255.     }
  256.   
  257.   exit (unfound);
  258. }
  259.