Back to index

tetex-bin  3.0
tex-file.c
Go to the documentation of this file.
00001 /* tex-file.c: high-level file searching by format.
00002 
00003 Copyright (C) 1993, 94, 95, 96, 97 Karl Berry.
00004 Copyright 1998-2004 Olaf Weber.
00005 
00006 This library is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU Library General Public
00008 License as published by the Free Software Foundation; either
00009 version 2 of the License, or (at your option) any later version.
00010 
00011 This library is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 Library General Public License for more details.
00015 
00016 You should have received a copy of the GNU Library General Public
00017 License along with this library; if not, write to the Free Software
00018 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
00019 
00020 #include <kpathsea/config.h>
00021 
00022 #include <kpathsea/c-fopen.h>
00023 #include <kpathsea/c-pathch.h>
00024 #include <kpathsea/c-vararg.h>
00025 #include <kpathsea/cnf.h>
00026 #include <kpathsea/concatn.h>
00027 #include <kpathsea/default.h>
00028 #include <kpathsea/expand.h>
00029 #include <kpathsea/fontmap.h>
00030 #include <kpathsea/paths.h>
00031 #include <kpathsea/pathsearch.h>
00032 #include <kpathsea/tex-file.h>
00033 #include <kpathsea/tex-make.h>
00034 #include <kpathsea/variable.h>
00035 
00036 
00037 /* See tex-file.h.  */
00038 const_string kpse_fallback_font = NULL;
00039 const_string kpse_fallback_resolutions_string = NULL;
00040 unsigned *kpse_fallback_resolutions = NULL;
00041 kpse_format_info_type kpse_format_info[kpse_last_format];
00042 
00043 /* These are not in the structure
00044    because it's annoying to initialize lists in C.  */
00045 #define GF_ENVS "GFFONTS", GLYPH_ENVS
00046 #define PK_ENVS "PKFONTS", "TEXPKS", GLYPH_ENVS
00047 #define GLYPH_ENVS "GLYPHFONTS", "TEXFONTS"
00048 #define TFM_ENVS "TFMFONTS", "TEXFONTS"
00049 #define AFM_ENVS "AFMFONTS", "TEXFONTS"
00050 #define BASE_ENVS "MFBASES", "TEXMFINI"
00051 #define BIB_ENVS "BIBINPUTS", "TEXBIB"
00052 #define BST_ENVS "BSTINPUTS"
00053 #define CNF_ENVS "TEXMFCNF"
00054 #define DB_ENVS "TEXMFDBS"
00055 #define FMT_ENVS "TEXFORMATS", "TEXMFINI"
00056 #define FONTMAP_ENVS "TEXFONTMAPS", "TEXFONTS"
00057 #define MEM_ENVS "MPMEMS", "TEXMFINI"
00058 #define MF_ENVS "MFINPUTS"
00059 #define MFPOOL_ENVS "MFPOOL", "TEXMFINI"
00060 #define MFT_ENVS "MFTINPUTS"
00061 #define MP_ENVS "MPINPUTS"
00062 #define MPPOOL_ENVS "MPPOOL", "TEXMFINI" 
00063 #define MPSUPPORT_ENVS "MPSUPPORT"
00064 #define OCP_ENVS "OCPINPUTS"
00065 #define OFM_ENVS "OFMFONTS", "TEXFONTS"
00066 #define OPL_ENVS "OPLFONTS", "TEXFONTS"
00067 #define OTP_ENVS "OTPINPUTS"
00068 #define OVF_ENVS "OVFFONTS", "TEXFONTS"
00069 #define OVP_ENVS "OVPFONTS", "TEXFONTS"
00070 #define PICT_ENVS "TEXPICTS", TEX_ENVS
00071 #define TEX_ENVS "TEXINPUTS"
00072 #define TEXDOC_ENVS "TEXDOCS"
00073 #define TEXPOOL_ENVS "TEXPOOL", "TEXMFINI"
00074 #define TEXSOURCE_ENVS "TEXSOURCES"
00075 #define TEX_PS_HEADER_ENVS "TEXPSHEADERS", "PSHEADERS"
00076 #define TROFF_FONT_ENVS "TRFONTS"
00077 #define TYPE1_ENVS "T1FONTS", "T1INPUTS", "TEXFONTS", TEX_PS_HEADER_ENVS
00078 #define VF_ENVS "VFFONTS", "TEXFONTS"
00079 #define DVIPS_CONFIG_ENVS "TEXCONFIG"
00080 #define IST_ENVS "TEXINDEXSTYLE", "INDEXSTYLE"
00081 #define TRUETYPE_ENVS "TTFONTS", "TEXFONTS"
00082 #define TYPE42_ENVS "T42FONTS", "TEXFONTS"
00083 #define WEB2C_ENVS "WEB2C"
00084 #define MISCFONTS_ENVS "MISCFONTS", "TEXFONTS"
00085 #define WEB_ENVS "WEBINPUTS"
00086 #define CWEB_ENVS "CWEBINPUTS"
00087 #define ENC_ENVS "ENCFONTS", "TEXFONTS"
00088 #define CMAP_ENVS "CMAPFONTS", "TEXFONTS"
00089 #define SFD_ENVS "SFDFONTS", "TEXFONTS"
00090 #define OPENTYPE_ENVS "OPENTYPEFONTS", "TEXFONTS"
00091 #define PDFTEXCONFIG_ENVS "PDFTEXCONFIG"
00092 #define LIG_ENVS "LIGFONTS", "TEXFONTS"
00093 #define TEXMFSCRIPTS_ENVS "TEXMFSCRIPTS"
00094 
00095 /* The compiled-in default list, DEFAULT_FONT_SIZES, is intended to be
00096    set from the command line (presumably via the Makefile).  */
00097 
00098 #ifndef DEFAULT_FONT_SIZES
00099 #define DEFAULT_FONT_SIZES ""
00100 #endif
00101 
00102 void
00103 kpse_init_fallback_resolutions P1C(string, envvar)
00104 {
00105   string size;
00106   const_string size_var = ENVVAR (envvar, "TEXSIZES");
00107   string size_str = getenv (size_var);
00108   unsigned *last_resort_sizes = NULL;
00109   unsigned size_count = 0;
00110   const_string default_sizes = kpse_fallback_resolutions_string
00111                          ? kpse_fallback_resolutions_string
00112                          : DEFAULT_FONT_SIZES; 
00113   string size_list = kpse_expand_default (size_str, default_sizes);
00114   
00115   /* Initialize the list of last-resort sizes.  */
00116   for (size = kpse_path_element (size_list); size != NULL;
00117        size = kpse_path_element (NULL))
00118     {
00119       unsigned s;
00120       if (! *size) /* Skip empty elements.  */
00121         continue;
00122       
00123       s = atoi (size);
00124       if (size_count && s < last_resort_sizes[size_count - 1]) {
00125     WARNING1 ("kpathsea: last resort size %s not in ascending order, ignored",
00126           size);
00127       } else {
00128         size_count++;
00129         XRETALLOC (last_resort_sizes, size_count, unsigned);
00130         last_resort_sizes[size_count - 1] = atoi (size);
00131       }
00132     }
00133 
00134   /* Add a zero to mark the end of the list.  */
00135   size_count++;
00136   XRETALLOC (last_resort_sizes, size_count, unsigned);
00137   last_resort_sizes[size_count - 1] = 0;
00138 
00139   free (size_list);
00140     
00141   kpse_fallback_resolutions = last_resort_sizes;
00142 }
00143 
00144 /* We should be able to set the program arguments in the same way.  Not
00145    to mention the path values themselves.  */
00146 
00147 void
00148 kpse_set_program_enabled P3C(kpse_file_format_type, fmt,  boolean, value,
00149                              kpse_src_type, level)
00150 {
00151   kpse_format_info_type *f = &kpse_format_info[fmt];
00152   if (level >= f->program_enable_level) {
00153     f->program_enabled_p = value;
00154     f->program_enable_level = level;
00155   }
00156 }
00157 
00158 
00159 /* Web2c and kpsewhich have command-line options to set this stuff.  May
00160    as well have a common place.  */
00161 
00162 void
00163 kpse_maketex_option P2C(const_string, fmtname,  boolean, value)
00164 {
00165   kpse_file_format_type fmt = kpse_last_format;
00166   
00167   /* Trying to match up with the suffix lists unfortunately doesn't work
00168      well, since that would require initializing the formats.  */
00169   /* FIXME: Currently the function silently ignores unrecognized arguments.*/
00170   if (FILESTRCASEEQ (fmtname, "pk")) {
00171     fmt = kpse_pk_format;
00172   } else if (FILESTRCASEEQ (fmtname, "mf")) {
00173     fmt = kpse_mf_format;
00174   } else if (FILESTRCASEEQ (fmtname, "tex")) {
00175     fmt = kpse_tex_format;
00176   } else if (FILESTRCASEEQ (fmtname, "tfm")) {
00177     fmt = kpse_tfm_format;
00178   } else if (FILESTRCASEEQ (fmtname, "ofm")) {
00179     fmt = kpse_ofm_format;
00180   } else if (FILESTRCASEEQ (fmtname, "ocp")) {
00181     fmt = kpse_ocp_format;
00182   }
00183   if (fmt != kpse_last_format) {
00184     kpse_set_program_enabled (fmt, value, kpse_src_cmdline);
00185   }
00186 }
00187 
00188 /* Macro subroutines for `init_path'.  TRY_ENV checks if an envvar ENAME
00189    is set and non-null, and sets var to ENAME if so.  */
00190 #define TRY_ENV(ename) do { \
00191   string evar = ename; \
00192 } while (0)
00193 
00194 /* And EXPAND_DEFAULT calls kpse_expand_default on try_path and the
00195    present info->path.  */
00196 #define EXPAND_DEFAULT(try_path, source_string)                \
00197   if (try_path) {                                       \
00198       info->raw_path = try_path;                        \
00199       info->path = kpse_expand_default (try_path, info->path); \
00200       info->path_source = source_string;                \
00201   }
00202 
00203 /* Find the final search path to use for the format entry INFO, given
00204    the compile-time default (DEFAULT_PATH), and the environment
00205    variables to check (the remaining arguments, terminated with NULL).
00206    We set the `path' and `path_source' members of INFO.  The
00207    `client_path' member must already be set upon entry.  */
00208 
00209 static void
00210 init_path PVAR2C(kpse_format_info_type *, info, const_string, default_path, ap)
00211 {
00212   string env_name;
00213   string var = NULL;
00214   
00215   info->default_path = default_path;
00216 
00217   /* First envvar that's set to a nonempty value will exit the loop.  If
00218      none are set, we want the first cnf entry that matches.  Find the
00219      cnf entries simultaneously, to avoid having to go through envvar
00220      list twice -- because of the PVAR?C macro, that would mean having
00221      to create a str_list and then use it twice.  Yuck.  */
00222   while ((env_name = va_arg (ap, string)) != NULL) {
00223     /* Since sh doesn't like envvar names with `.', check PATH_prog
00224        as well as PATH.prog.  */
00225     if (!var) {
00226       /* Try PATH.prog. */
00227       string evar = concat3 (env_name, ".", kpse_program_name);
00228       string env_value = getenv (evar);
00229       if (env_value && *env_value) {
00230         var = evar;
00231       } else {
00232         free (evar);
00233         /* Try PATH_prog. */
00234         evar = concat3 (env_name, "_", kpse_program_name);
00235         env_value = getenv (evar);
00236         if (env_value && *env_value) {
00237           var = evar;
00238         } else {
00239           free (evar);
00240           /* Try simply PATH.  */
00241           env_value = getenv (env_name);
00242           if (env_value && *env_value) {
00243             var = env_name;        
00244           }
00245         }
00246       }
00247     }
00248     
00249     /* If we are initializing the cnf path, don't try to get any
00250        values from the cnf files; that's infinite loop time.  */
00251     if (!info->cnf_path && info != &kpse_format_info[kpse_cnf_format])
00252       info->cnf_path = kpse_cnf_get (env_name);
00253       
00254     if (var && info->cnf_path)
00255       break;
00256   }
00257   va_end (ap);
00258   
00259   /* Expand any extra :'s.  For each level, we replace an extra : with
00260      the path at the next lower level.  For example, an extra : in a
00261      user-set envvar should be replaced with the path from the cnf file.
00262      things are complicated because none of the levels above the very
00263      bottom are guaranteed to exist.  */
00264 
00265   /* Assume we can reliably start with the compile-time default.  */
00266   info->path = info->raw_path = info->default_path;
00267   info->path_source = "compile-time paths.h";
00268 
00269   EXPAND_DEFAULT (info->cnf_path, "texmf.cnf");
00270   EXPAND_DEFAULT (info->client_path, "program config file");
00271   if (var)
00272     EXPAND_DEFAULT (getenv (var), concat (var, " environment variable"));
00273   EXPAND_DEFAULT (info->override_path, "application override variable");
00274   info->path = kpse_brace_expand (info->path);
00275 }}
00276 
00277 
00278 /* Some file types have more than one suffix.  */
00279 /* Some times it is convenient to modify the list of searched suffixes.
00280    *** Don't complain if this function goes away. ***
00281  */
00282 void
00283 kpse_set_suffixes PVAR2C(kpse_file_format_type, format,
00284   boolean, alternate,  ap)
00285 {
00286   const_string **list;
00287   const_string s;
00288   int count = 0;
00289 
00290   if (alternate) {
00291     list = &kpse_format_info[format].alt_suffix;
00292   } 
00293   else {
00294     list = &kpse_format_info[format].suffix;
00295   }
00296 
00297   while ((s = va_arg (ap, string)) != NULL) {
00298     count++;
00299     XRETALLOC (*list, count + 1, const_string);
00300     (*list)[count - 1] = s;
00301   }
00302   va_end (ap);
00303   (*list)[count] = NULL;
00304 
00305 }}
00306 
00307 /* The path spec we are defining, one element of the global array.  */
00308 #define FMT_INFO kpse_format_info[format]
00309 /* Call kpse_set_add_suffixes.  */
00310 #define SUFFIXES(args) kpse_set_suffixes(format, false, args, NULL)
00311 #define ALT_SUFFIXES(args) kpse_set_suffixes(format, true, args, NULL)
00312 
00313 /* Call `init_path', including appending the trailing NULL to the envvar
00314    list. Also initialize the fields not needed in setting the path.  */
00315 #define INIT_FORMAT(text, default_path, envs) \
00316   FMT_INFO.type = text; \
00317   init_path (&FMT_INFO, default_path, envs, NULL)
00318 
00319 
00320 /* A few file types allow for runtime generation by an external program.
00321    kpse_init_prog may have already initialized it (the `program'
00322    member).  Here we allow people to turn it off or on in the config
00323    file, by setting the variable whose name is the uppercasified program
00324    name to 0 or 1.  */
00325 
00326 static void
00327 init_maketex PVAR2C(kpse_file_format_type, fmt,  const_string, dflt_prog, ap)
00328 {
00329   kpse_format_info_type *f = &kpse_format_info[fmt];
00330   const_string prog = f->program ? f->program : dflt_prog; /* mktexpk */
00331   string PROG = uppercasify (prog);             /* MKTEXPK */
00332   string progval = kpse_var_value (PROG);       /* ENV/cnf{"MKTEXPK"} */
00333   const_string arg;
00334 
00335   /* Doesn't hurt to always set this info.  */
00336   f->program = prog;
00337 
00338   /* Set up the argument vector. */
00339   f->argc = 0;
00340   f->argv = XTALLOC(2, const_string);
00341   f->argv[f->argc++] = dflt_prog;
00342   while ((arg = va_arg (ap, string)) != NULL) {
00343     f->argc++;
00344     XRETALLOC (f->argv, f->argc + 1, const_string);
00345     f->argv[f->argc - 1] = arg;
00346   }
00347   f->argv[f->argc] = NULL;
00348 
00349   if (progval && *progval) {
00350     /* This might actually be from an environment variable value, but in
00351        that case, we'll have previously set it from kpse_init_prog.  */
00352     kpse_set_program_enabled (fmt, *progval == '1', kpse_src_client_cnf);
00353   }
00354   
00355   free (PROG);
00356 }}
00357 
00358 /* We need this twice, so ... */
00359 #define MKTEXPK_ARGS \
00360   "--mfmode","$MAKETEX_MODE",\
00361   "--bdpi","$MAKETEX_BASE_DPI",\
00362   "--mag","$MAKETEX_MAG",\
00363   "--dpi","$KPATHSEA_DPI",\
00364   NULL
00365 
00366 static string
00367 remove_dbonly P1C(const_string, path)
00368 {
00369   string ret = XTALLOC(strlen (path) + 1, char), q=ret;
00370   const_string p=path;
00371   boolean new_elt=true;
00372 
00373   while (*p) {
00374     if (new_elt && *p && *p == '!' && *(p+1) == '!')
00375       p += 2;
00376     else {
00377       new_elt = (*p == ENV_SEP);
00378       *q++ = *p++;
00379     }
00380   }
00381   *q = '\0';
00382   return(ret);
00383 }
00384 
00385 /* Initialize everything for FORMAT.  */
00386 
00387 const_string
00388 kpse_init_format P1C(kpse_file_format_type, format)
00389 {
00390   /* If we get called twice, don't redo all the work.  */
00391   if (FMT_INFO.path)
00392     return FMT_INFO.path;
00393     
00394   switch (format)
00395     { /* We might be able to avoid repeating `gf' or whatever so many
00396          times with token pasting, but it doesn't seem worth it.  */
00397     case kpse_gf_format:
00398       INIT_FORMAT ("gf", DEFAULT_GFFONTS, GF_ENVS);
00399       SUFFIXES ("gf");
00400       FMT_INFO.suffix_search_only = true;
00401       FMT_INFO.binmode = true;
00402       break;
00403     case kpse_pk_format:
00404       init_maketex (format, "mktexpk", MKTEXPK_ARGS);
00405       INIT_FORMAT ("pk", DEFAULT_PKFONTS, PK_ENVS);
00406       SUFFIXES ("pk");
00407       FMT_INFO.suffix_search_only = true;
00408       FMT_INFO.binmode = true;
00409       break;
00410     case kpse_any_glyph_format:
00411       init_maketex (format, "mktexpk", MKTEXPK_ARGS);
00412       INIT_FORMAT ("bitmap font", DEFAULT_GLYPHFONTS, GLYPH_ENVS);
00413       FMT_INFO.suffix_search_only = true;
00414       FMT_INFO.binmode = true;
00415       break;
00416     case kpse_tfm_format:
00417       /* Must come before kpse_ofm_format. */
00418       init_maketex (format, "mktextfm", NULL);
00419       INIT_FORMAT ("tfm", DEFAULT_TFMFONTS, TFM_ENVS);
00420       SUFFIXES (".tfm");
00421       FMT_INFO.suffix_search_only = true;
00422       FMT_INFO.binmode = true;
00423       break;
00424     case kpse_afm_format:
00425       INIT_FORMAT ("afm", DEFAULT_AFMFONTS, AFM_ENVS);
00426       SUFFIXES (".afm");
00427       break;
00428     case kpse_base_format:
00429       init_maketex (format, "mktexfmt", NULL);
00430       INIT_FORMAT ("base", DEFAULT_MFBASES, BASE_ENVS);
00431       SUFFIXES (".base");
00432       FMT_INFO.binmode = true;
00433       break;
00434     case kpse_bib_format:
00435       INIT_FORMAT ("bib", DEFAULT_BIBINPUTS, BIB_ENVS);
00436       SUFFIXES (".bib");
00437       FMT_INFO.suffix_search_only = true;
00438       break;
00439     case kpse_bst_format:
00440       INIT_FORMAT ("bst", DEFAULT_BSTINPUTS, BST_ENVS);
00441       SUFFIXES (".bst");
00442       break;
00443     case kpse_cnf_format:
00444       INIT_FORMAT ("cnf", DEFAULT_TEXMFCNF, CNF_ENVS);
00445       SUFFIXES (".cnf");
00446       break;
00447     case kpse_db_format:
00448       INIT_FORMAT ("ls-R", DEFAULT_TEXMFDBS, DB_ENVS);
00449 #define LSR_SUFFIXES "ls-R", "ls-r"
00450       SUFFIXES (LSR_SUFFIXES);
00451       FMT_INFO.path = remove_dbonly (FMT_INFO.path);
00452       break;
00453     case kpse_fmt_format:
00454       init_maketex (format, "mktexfmt", NULL);
00455       INIT_FORMAT ("fmt", DEFAULT_TEXFORMATS, FMT_ENVS);
00456       SUFFIXES (".fmt");
00457 #define FMT_SUFFIXES ".efmt",".efm",".ofmt",".ofm",".oft",".eofmt",".eoft",".eof",".pfmt",".pfm",".epfmt",".epf",".xpfmt",".xpf",".afmt",".afm"
00458       ALT_SUFFIXES (FMT_SUFFIXES);
00459       FMT_INFO.binmode = true;
00460       break;
00461     case kpse_fontmap_format:
00462       INIT_FORMAT ("map", DEFAULT_TEXFONTMAPS, FONTMAP_ENVS);
00463       SUFFIXES (".map");
00464       break;
00465     case kpse_mem_format:
00466       init_maketex (format, "mktexfmt", NULL);
00467       INIT_FORMAT ("mem", DEFAULT_MPMEMS, MEM_ENVS);
00468       SUFFIXES (".mem");
00469       FMT_INFO.binmode = true;
00470       break;
00471     case kpse_mf_format:
00472       init_maketex (format, "mktexmf", NULL);
00473       INIT_FORMAT ("mf", DEFAULT_MFINPUTS, MF_ENVS);
00474       SUFFIXES (".mf");
00475       break;
00476     case kpse_mft_format:
00477       INIT_FORMAT ("mft", DEFAULT_MFTINPUTS, MFT_ENVS);
00478       SUFFIXES (".mft");
00479       break;
00480     case kpse_mfpool_format:
00481       INIT_FORMAT ("mfpool", DEFAULT_MFPOOL, MFPOOL_ENVS);
00482       SUFFIXES (".pool");
00483       break;
00484     case kpse_mp_format:
00485       INIT_FORMAT ("mp", DEFAULT_MPINPUTS, MP_ENVS);
00486       SUFFIXES (".mp");
00487       break;
00488     case kpse_mppool_format:
00489       INIT_FORMAT ("mppool", DEFAULT_MPPOOL, MPPOOL_ENVS);
00490       SUFFIXES (".pool");
00491       break;
00492     case kpse_mpsupport_format:
00493       INIT_FORMAT ("MetaPost support", DEFAULT_MPSUPPORT, MPSUPPORT_ENVS);
00494       break;
00495     case kpse_ocp_format:
00496       init_maketex (format, "mkocp", NULL);
00497       INIT_FORMAT ("ocp", DEFAULT_OCPINPUTS, OCP_ENVS);
00498       SUFFIXES (".ocp");
00499       FMT_INFO.suffix_search_only = true;
00500       FMT_INFO.binmode = true;
00501       break;
00502     case kpse_ofm_format:
00503       init_maketex (format, "mkofm", NULL);
00504       INIT_FORMAT ("ofm", DEFAULT_OFMFONTS, OFM_ENVS);
00505 #define OFM_SUFFIXES ".ofm", ".tfm"
00506       SUFFIXES (OFM_SUFFIXES);
00507       FMT_INFO.suffix_search_only = true;
00508       FMT_INFO.binmode = true;
00509       break;
00510     case kpse_opl_format:
00511       INIT_FORMAT ("opl", DEFAULT_OPLFONTS, OPL_ENVS);
00512       SUFFIXES (".opl");
00513       FMT_INFO.suffix_search_only = true;
00514       break;
00515     case kpse_otp_format:
00516       INIT_FORMAT ("otp", DEFAULT_OTPINPUTS, OTP_ENVS);
00517       SUFFIXES (".otp");
00518       FMT_INFO.suffix_search_only = true;
00519       break;
00520     case kpse_ovf_format:
00521       INIT_FORMAT ("ovf", DEFAULT_OVFFONTS, OVF_ENVS);
00522       SUFFIXES (".ovf");
00523       FMT_INFO.suffix_search_only = true;
00524       FMT_INFO.binmode = true;
00525       break;
00526     case kpse_ovp_format:
00527       INIT_FORMAT ("ovp", DEFAULT_OVPFONTS, OVP_ENVS);
00528       SUFFIXES (".ovp");
00529       FMT_INFO.suffix_search_only = true;
00530       break;
00531     case kpse_pict_format:
00532       INIT_FORMAT ("graphic/figure", DEFAULT_TEXINPUTS, PICT_ENVS);
00533 #define PICT_SUFFIXES ".eps", ".epsi"
00534       ALT_SUFFIXES (PICT_SUFFIXES);
00535       FMT_INFO.binmode = true;
00536       break;
00537     case kpse_tex_format:
00538       init_maketex (format, "mktextex", NULL);
00539       INIT_FORMAT ("tex", DEFAULT_TEXINPUTS, TEX_ENVS);
00540       SUFFIXES (".tex");
00541       /* We don't maintain a list of alternate TeX suffixes.  Such a list
00542          could never be complete.  */
00543       break;
00544     case kpse_tex_ps_header_format:
00545       INIT_FORMAT ("PostScript header", DEFAULT_TEXPSHEADERS,
00546                    TEX_PS_HEADER_ENVS);
00547 /* Unfortunately, dvipsk uses this format for type1 fonts.  */
00548 #define TEXPSHEADER_SUFFIXES ".pro"
00549       ALT_SUFFIXES (TEXPSHEADER_SUFFIXES);
00550       FMT_INFO.binmode = true;
00551       break;
00552     case kpse_texdoc_format:
00553       INIT_FORMAT ("TeX system documentation", DEFAULT_TEXDOCS, TEXDOC_ENVS);
00554       break;
00555     case kpse_texpool_format:
00556       INIT_FORMAT ("texpool", DEFAULT_TEXPOOL, TEXPOOL_ENVS);
00557       SUFFIXES (".pool");
00558       break;
00559     case kpse_texsource_format:
00560       INIT_FORMAT ("TeX system sources", DEFAULT_TEXSOURCES, TEXSOURCE_ENVS);
00561       break;
00562     case kpse_troff_font_format:
00563       INIT_FORMAT ("Troff fonts", DEFAULT_TRFONTS, TROFF_FONT_ENVS);
00564       FMT_INFO.binmode = true;
00565       break;
00566     case kpse_type1_format:
00567       INIT_FORMAT ("type1 fonts", DEFAULT_T1FONTS, TYPE1_ENVS);
00568 #define TYPE1_SUFFIXES ".pfa", ".pfb"
00569       SUFFIXES (TYPE1_SUFFIXES);
00570       FMT_INFO.binmode = true;
00571       break;
00572     case kpse_vf_format:
00573       INIT_FORMAT ("vf", DEFAULT_VFFONTS, VF_ENVS);
00574       SUFFIXES (".vf");
00575       FMT_INFO.suffix_search_only = true;
00576       FMT_INFO.binmode = true;
00577       break;
00578     case kpse_dvips_config_format:
00579       INIT_FORMAT ("dvips config", DEFAULT_TEXCONFIG, DVIPS_CONFIG_ENVS);
00580       break;
00581     case kpse_ist_format:
00582       INIT_FORMAT ("ist", DEFAULT_INDEXSTYLE, IST_ENVS);
00583       SUFFIXES (".ist");
00584       break;
00585     case kpse_truetype_format:
00586       INIT_FORMAT ("truetype fonts", DEFAULT_TTFONTS, TRUETYPE_ENVS);
00587 #define TRUETYPE_SUFFIXES ".ttf", ".ttc"
00588       SUFFIXES (TRUETYPE_SUFFIXES);
00589       FMT_INFO.suffix_search_only = true;
00590       FMT_INFO.binmode = true;
00591       break;
00592     case kpse_type42_format:
00593       INIT_FORMAT ("type42 fonts", DEFAULT_T42FONTS, TYPE42_ENVS);
00594       FMT_INFO.binmode = true;
00595       break;
00596     case kpse_web2c_format:
00597       INIT_FORMAT ("web2c files", DEFAULT_WEB2C, WEB2C_ENVS);
00598       break;
00599     case kpse_program_text_format:
00600       INIT_FORMAT ("other text files",
00601                    concatn (".", ENV_SEP_STRING, "$TEXMF/",
00602                             kpse_program_name, "//", NULL),
00603                    concat (uppercasify (kpse_program_name), "INPUTS"));
00604       break;
00605     case kpse_program_binary_format:
00606       INIT_FORMAT ("other binary files",
00607                    concatn (".", ENV_SEP_STRING, "$TEXMF/",
00608                             kpse_program_name, "//", NULL),
00609                    concat (uppercasify (kpse_program_name), "INPUTS"));
00610       FMT_INFO.binmode = true;
00611       break;
00612     case kpse_miscfonts_format:
00613       INIT_FORMAT ("misc fonts", DEFAULT_MISCFONTS, MISCFONTS_ENVS);
00614       FMT_INFO.binmode = true;
00615       break;
00616     case kpse_web_format:
00617       INIT_FORMAT ("web", DEFAULT_WEBINPUTS, WEB_ENVS);
00618       SUFFIXES (".web");
00619       ALT_SUFFIXES (".ch");
00620       break;
00621     case kpse_cweb_format:
00622       INIT_FORMAT ("cweb", DEFAULT_CWEBINPUTS, CWEB_ENVS);
00623 #define CWEB_SUFFIXES ".w", ".web"
00624       SUFFIXES (CWEB_SUFFIXES);
00625       ALT_SUFFIXES (".ch");
00626       break;
00627     case kpse_enc_format:
00628       INIT_FORMAT ("enc files", DEFAULT_ENCFONTS, ENC_ENVS);
00629       SUFFIXES (".enc");
00630       break;
00631     case kpse_cmap_format:
00632       INIT_FORMAT ("cmap files", DEFAULT_CMAPFONTS, CMAP_ENVS);
00633       SUFFIXES (".cmap");      
00634       break;
00635     case kpse_sfd_format:
00636       INIT_FORMAT ("subfont definition files", DEFAULT_SFDFONTS, SFD_ENVS);
00637       SUFFIXES (".sfd");
00638       break;
00639     case kpse_opentype_format:
00640       INIT_FORMAT ("opentype fonts", DEFAULT_OPENTYPEFONTS, OPENTYPE_ENVS);
00641       FMT_INFO.binmode = true;
00642       break;
00643     case kpse_pdftex_config_format:
00644       INIT_FORMAT ("pdftex config", DEFAULT_PDFTEXCONFIG, PDFTEXCONFIG_ENVS);
00645       break;
00646     case kpse_lig_format:
00647       INIT_FORMAT ("lig files", DEFAULT_LIGFONTS, LIG_ENVS);
00648       SUFFIXES (".lig");
00649       break;
00650     case kpse_texmfscripts_format:
00651       INIT_FORMAT ("texmfscripts", DEFAULT_TEXMFSCRIPTS, TEXMFSCRIPTS_ENVS);
00652       break;
00653     default:
00654       FATAL1 ("kpse_init_format: Unknown format %d", format);
00655     }
00656 
00657 #ifdef KPSE_DEBUG
00658 #define MAYBE(member) (FMT_INFO.member ? FMT_INFO.member : "(none)")
00659 
00660   /* Describe the monster we've created.  */
00661   if (KPSE_DEBUG_P (KPSE_DEBUG_PATHS))
00662     {
00663       DEBUGF2 ("Search path for %s files (from %s)\n",
00664               FMT_INFO.type, FMT_INFO.path_source);
00665       DEBUGF1 ("  = %s\n", FMT_INFO.path);
00666       DEBUGF1 ("  before expansion = %s\n", FMT_INFO.raw_path);
00667       DEBUGF1 ("  application override path = %s\n", MAYBE (override_path));
00668       DEBUGF1 ("  application config file path = %s\n", MAYBE (client_path));
00669       DEBUGF1 ("  texmf.cnf path = %s\n", MAYBE (cnf_path));
00670       DEBUGF1 ("  compile-time path = %s\n", MAYBE (default_path));
00671       DEBUGF  ("  default suffixes =");
00672       if (FMT_INFO.suffix) {
00673         const_string *ext;
00674         for (ext = FMT_INFO.suffix; ext && *ext; ext++) {
00675           fprintf (stderr, " %s", *ext);
00676         }
00677         putc ('\n', stderr);
00678       } else {
00679         fputs (" (none)\n", stderr);
00680       }
00681       DEBUGF  ("  other suffixes =");
00682       if (FMT_INFO.alt_suffix) {
00683         const_string *alt;
00684         for (alt = FMT_INFO.alt_suffix; alt && *alt; alt++) {
00685           fprintf (stderr, " %s", *alt);
00686         }
00687         putc ('\n', stderr);
00688       } else {
00689         fputs (" (none)\n", stderr);
00690       }
00691       DEBUGF1 ("  search only with suffix = %d\n",FMT_INFO.suffix_search_only);
00692       DEBUGF1 ("  numeric format value = %d\n", format);
00693       DEBUGF1 ("  runtime generation program = %s\n", MAYBE (program));
00694       DEBUGF  ("  runtime generation command =");
00695       if (FMT_INFO.argv) {
00696         const_string *arg;
00697         for (arg = FMT_INFO.argv; *arg; arg++) {
00698           fprintf (stderr, " %s", *arg);
00699         }
00700         putc ('\n', stderr);
00701       } else {
00702           fputs(" (none)\n", stderr);
00703       }
00704       DEBUGF1 ("  program enabled = %d\n", FMT_INFO.program_enabled_p);
00705       DEBUGF1 ("  program enable level = %d\n", FMT_INFO.program_enable_level);
00706     }
00707 #endif /* KPSE_DEBUG */
00708 
00709   return FMT_INFO.path;
00710 }
00711 
00712 /* Look up a file NAME of type FORMAT, and the given MUST_EXIST.  This
00713    initializes the path spec for FORMAT if it's the first lookup of that
00714    type.  Return the filename found, or NULL.  This is the most likely
00715    thing for clients to call.  */
00716    
00717 string
00718 kpse_find_file P3C(const_string, name,  kpse_file_format_type, format,
00719                    boolean, must_exist)
00720 {
00721   const_string *ext;
00722   unsigned name_len = 0;
00723   boolean name_has_suffix_already = false;
00724   string mapped_name;
00725   string *mapped_names;
00726   const_string *target;
00727   unsigned count;
00728   boolean use_fontmaps = (format == kpse_tfm_format
00729                           || format == kpse_gf_format
00730                           || format == kpse_pk_format
00731                           || format == kpse_ofm_format);
00732   string ret = NULL;
00733 
00734   /* NAME being NULL is a programming bug somewhere.  NAME can be empty,
00735      though; this happens with constructs like `\input\relax'.  */
00736   assert (name);
00737   
00738   if (FMT_INFO.path == NULL)
00739     kpse_init_format (format);
00740 
00741   if (KPSE_DEBUG_P(KPSE_DEBUG_SEARCH))
00742     DEBUGF3 ("kpse_find_file: searching for %s of type %s (from %s)\n",
00743              name, FMT_INFO.type, FMT_INFO.path_source);
00744 
00745   /* Does NAME already end in a possible suffix?  */
00746   name_len = strlen (name);
00747   if (FMT_INFO.suffix) {
00748     for (ext = FMT_INFO.suffix; !name_has_suffix_already && *ext; ext++) {
00749       unsigned suffix_len = strlen (*ext);
00750       name_has_suffix_already = (name_len >= suffix_len
00751           && FILESTRCASEEQ (*ext, name + name_len - suffix_len));
00752     }
00753   }
00754   if (!name_has_suffix_already && FMT_INFO.alt_suffix) {
00755     for (ext = FMT_INFO.alt_suffix; !name_has_suffix_already && *ext; ext++) {
00756       unsigned suffix_len = strlen (*ext);
00757       name_has_suffix_already = (name_len >= suffix_len
00758           && FILESTRCASEEQ (*ext, name + name_len - suffix_len));
00759     }
00760   }
00761 
00762   /* Set up target list. */
00763   count = 0;
00764   target = XTALLOC1 (const_string);
00765   /* Case #1: NAME doesn't have a suffix which is equal to a "standard"
00766      suffix.  For example, foo.bar, but not foo.tex.  We look for the
00767      name with the standard suffixes appended. */
00768   if (!name_has_suffix_already && FMT_INFO.suffix) {
00769     for (ext = FMT_INFO.suffix; *ext; ext++) {
00770       string name_with_suffix = concat (name, *ext);
00771       target[count++] = name_with_suffix;
00772       XRETALLOC(target, count+1, const_string);
00773       if (use_fontmaps
00774           && (mapped_names = kpse_fontmap_lookup (name_with_suffix)) != NULL)
00775       {
00776         /* FIXME: we leak mapped_names and its elements, some of the time */
00777         while ((mapped_name = *mapped_names++) != NULL) {
00778           target[count++] = xstrdup (mapped_name);
00779           XRETALLOC(target, count+1, const_string);
00780         }
00781       }
00782     }
00783   }
00784   /* Case #2: Just look for the name we've been given, provided non-suffix
00785      searches are allowed or the name already includes a suffix. */
00786   if (name_has_suffix_already || !FMT_INFO.suffix_search_only) {
00787     target[count++] = xstrdup (name);
00788     XRETALLOC(target, count+1, const_string);
00789     if (use_fontmaps && (mapped_names = kpse_fontmap_lookup (name)) != NULL) {
00790       /* FIXME: we leak mapped_names and its elements, some of the time */
00791       while ((mapped_name = *mapped_names++) != NULL) {
00792         target[count++] = xstrdup (mapped_name);
00793         XRETALLOC(target, count+1, const_string);
00794       }
00795     }
00796   }
00797   /* Terminate list. */
00798   target[count] = NULL;
00799 
00800   /* Search. */
00801 #if 0
00802   /* Simple version, just do the search for the list, and pound disk
00803    * then and there if appropriate.
00804    */
00805   ret = kpse_path_search_list (FMT_INFO.path, target, must_exist);
00806 #elif 0
00807   /* Variant where we delay disk-pounding. */
00808   ret = kpse_path_search_list (FMT_INFO.path, target, false);
00809   if (!ret && must_exist)
00810       ret = kpse_path_search_list (FMT_INFO.path, target, true);
00811 #else
00812   /* Variant that tries the match the original behaviour more closely.
00813    * The distinction is that we pound the disk for a far shorter list
00814    * of names.
00815    *
00816    * This is the fastest variant, because it does fewer disk accesses
00817    * than the two variants above -- for example some 750 calls of
00818    * access(2) compared to 1500.
00819    */
00820   ret = kpse_path_search_list (FMT_INFO.path, target, false);
00821   /* Do we need to pound the disk? */
00822   if (!ret && must_exist) {
00823     for (count = 0; target[count]; count++)
00824       free((void*)target[count]);
00825     count = 0;
00826     /* We look for a subset of the previous set of names, so the
00827      * target array is large enough.  In particular, we don't pound
00828      * the disk for alternate names from the fontmaps.  Perhaps we
00829      * should?
00830      */
00831     if (!name_has_suffix_already && FMT_INFO.suffix_search_only) {
00832       for (ext = FMT_INFO.suffix; !ret && *ext; ext++)
00833         target[count++] = concat (name, *ext);
00834     }
00835     if (name_has_suffix_already || !FMT_INFO.suffix_search_only) {
00836       target[count++] = xstrdup (name);
00837     }
00838     target[count] = NULL;
00839     ret = kpse_path_search_list (FMT_INFO.path, target, true);
00840   }
00841 #endif  
00842   
00843   /* Free the list we created. */
00844   for (count = 0; target[count]; count++)
00845     free((void*)target[count]);
00846   free(target);
00847   
00848   /* If nothing was found, call mktex* to create a missing file.  */
00849   if (!ret && must_exist) {
00850     ret = kpse_make_tex (format, name);
00851   }
00852 
00853   return ret;
00854 }
00855 
00856 /* Open NAME along the search path for TYPE for reading and return the
00857    resulting file, or exit with an error message.  */
00858 
00859 FILE *
00860 kpse_open_file P2C(const_string, name,  kpse_file_format_type, type)
00861 {
00862   string fullname = kpse_find_file (name, type, true);
00863   const_string mode = kpse_format_info[type].binmode
00864                       ? FOPEN_RBIN_MODE
00865                       : FOPEN_R_MODE;
00866   FILE *f = fullname ? fopen (fullname, mode) : NULL;
00867   if (!f) {
00868     if (fullname) {
00869       perror (fullname);
00870       exit (1);
00871     } else {
00872       FATAL2 ("%s file `%s' not found", kpse_format_info[type].type, name);
00873     }
00874   }
00875   
00876   return f;
00877 }
00878 
00879 /* When using the %&<format> construct, we'd like to use the paths for
00880    that format, rather than those for the name we were called with.
00881    Of course this happens after various initializations have been
00882    performed, so we have this function to force the issue.  Note that
00883    the paths for kpse_cnf_format and kpse_db_format are not cleared.
00884 
00885    This function is defined here, and not in progname.c, because it
00886    need kpse_format_info, and would cause all of tex-file to be pulled
00887    in by programs that do not need it. */
00888 void
00889 kpse_reset_program_name P1C(const_string, progname)
00890 {
00891   int i;
00892 
00893   /* It is a fatal error for either of these to be NULL. */
00894   assert (progname && kpse_program_name);
00895   /* Do nothing if the name is unchanged. */
00896   if (STREQ(kpse_program_name, progname))
00897     return;
00898 
00899   free (kpse_program_name);
00900   kpse_program_name = xstrdup (progname);
00901   xputenv("progname", kpse_program_name);
00902   
00903   /* Clear paths -- do we want the db path to be cleared? */
00904   for (i = 0; i != kpse_last_format; ++i) {
00905     /* Do not erase the cnf of db paths.  This means that the filename
00906        database is not rebuilt, nor are different configuration files
00907        searched.  The alternative is to tolerate a memory leak of up
00908        to 100k if this function is called. */
00909     if (i == kpse_cnf_format || i == kpse_db_format)
00910       continue;
00911     /* Wipe the path (it is tested) and the cnf_path and because their
00912        values may differ with the new program name.  */
00913     if (kpse_format_info[i].path != NULL) {
00914       free ((string)kpse_format_info[i].path);
00915       kpse_format_info[i].path = NULL;
00916     }
00917     /* We cannot free the cnf_path: it points into the cnf hash, which
00918        means all hell will break loose if we did. */
00919     if (kpse_format_info[i].cnf_path != NULL) {
00920       kpse_format_info[i].cnf_path = NULL;
00921     }
00922     /* We do not wipe the override_path at this point, though arguably
00923        we should provide new values.  It is not likely to matter for
00924        the programs that call this function. */
00925   }
00926 }