void kpathsea_init_db (kpathsea kpse) { boolean ok = false; const_string db_path; string *db_files; string *orig_db_files; 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; /* 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); }
static void read_all_cnf (kpathsea kpse) { string *cnf_files; string *cnf; const_string cnf_path = kpathsea_init_format (kpse, kpse_cnf_format); kpse->cnf_hash = hash_create (CNF_HASH_SIZE); cnf_files = kpathsea_all_path_search (kpse, cnf_path, CNF_NAME); if (cnf_files && *cnf_files) { for (cnf = cnf_files; *cnf; cnf++) { string line; FILE *cnf_file = xfopen (*cnf, FOPEN_R_MODE); if (kpse->record_input) kpse->record_input (*cnf); while ((line = read_line (cnf_file)) != NULL) { unsigned len = strlen (line); /* Strip trailing spaces. */ while (len > 0 && ISSPACE(line[len-1])) { line[len - 1] = 0; --len; } /* Concatenate consecutive lines that end with \. */ while (len > 0 && line[len - 1] == '\\') { string next_line = read_line (cnf_file); line[len - 1] = 0; if (!next_line) { WARNING1 ("%s: Last line ends with \\", *cnf); } else { string new_line; new_line = concat (line, next_line); free (line); line = new_line; len = strlen (line); } } do_line (kpse, line); free (line); } xfclose (cnf_file, *cnf); free (*cnf); } free (cnf_files); } else { string warn = getenv ("KPATHSEA_WARNING"); if (!(warn && STREQ (warn, "0"))) { WARNING1 ("kpathsea: configuration file texmf.cnf not found in these directories: %s", cnf_path); } } }
static int lua_kpathsea_show_path(lua_State * L) { kpathsea *kp = (kpathsea *) luaL_checkudata(L, 1, KPATHSEA_METATABLE); int op = luaL_checkoption(L, -1, "tex", filetypenames); unsigned user_format = filetypes[op]; if (!(*kp)->format_info[user_format].type) /* needed if arg was numeric */ kpathsea_init_format(*kp, user_format); lua_pushstring(L, (*kp)->format_info[user_format].path); return 1; }
static void read_all_maps (kpathsea kpse) { string *filenames; kpse->map_path = kpathsea_init_format (kpse, kpse_fontmap_format); filenames = kpathsea_all_path_search (kpse, kpse->map_path, MAP_NAME); kpse->map = hash_create (MAP_HASH_SIZE); while (*filenames) { map_file_parse (kpse, *filenames); filenames++; } }
static kpse_file_format_type find_format(kpathsea kpse, const_string name, boolean is_filename) { kpse_file_format_type ret; if (FILESTRCASEEQ(name, "config.ps")) { ret = kpse_dvips_config_format; } else if (FILESTRCASEEQ(name, "dvipdfmx.cfg")) { ret = kpse_program_text_format; } else if (FILESTRCASEEQ(name, "fmtutil.cnf")) { ret = kpse_web2c_format; } else if (FILESTRCASEEQ(name, "glyphlist.txt")) { ret = kpse_fontmap_format; } else if (FILESTRCASEEQ(name, "mktex.cnf")) { ret = kpse_web2c_format; } else if (FILESTRCASEEQ(name, "pdfglyphlist.txt")) { ret = kpse_fontmap_format; } else if (FILESTRCASEEQ(name, "pdftex.cfg")) { ret = kpse_pdftex_config_format; } else if (FILESTRCASEEQ(name, "texmf.cnf")) { ret = kpse_cnf_format; } else if (FILESTRCASEEQ(name, "updmap.cfg")) { ret = kpse_web2c_format; } else if (FILESTRCASEEQ(name, "XDvi")) { ret = kpse_program_text_format; } else { int f = 0; /* kpse_file_format_type */ size_t name_len = strlen(name); /* Have to rely on `try_len' being declared here, since we can't assume GNU C and statement expressions. */ #define TRY_SUFFIX(ftry) (\ try_len = (ftry) ? strlen (ftry) : 0, \ (ftry) && try_len <= name_len \ && FILESTRCASEEQ (ftry, name + name_len - try_len)) while (f != kpse_last_format) { size_t try_len; const_string *ext; const_string ftry; boolean found = false; if (!kpse->format_info[f].type) kpathsea_init_format(kpse, (kpse_file_format_type) f); if (!is_filename) { /* Allow the long name, but only in the -format option. We don't want a filename confused with a format name. */ ftry = kpse->format_info[f].type; found = TRY_SUFFIX(ftry); } for (ext = kpse->format_info[f].suffix; !found && ext && *ext; ext++) { found = TRY_SUFFIX(*ext); } for (ext = kpse->format_info[f].alt_suffix; !found && ext && *ext; ext++) { found = TRY_SUFFIX(*ext); } if (found) break; /* Some trickery here: the extensions for kpse_fmt_format can * clash with other extensions in use, and we prefer for those * others to be preferred. And we don't want to change the * integer value of kpse_fmt_format. So skip it when first * enountered, then use it when we've done everything else, * and use it as the end-guard. */ if (f == kpse_fmt_format) { f = kpse_last_format; } else if (++f == kpse_fmt_format) { f++; } else if (f == kpse_last_format) { f = kpse_fmt_format; } } /* If there was a match, f will be one past the correct value. */ ret = f; } return ret; }
string kpathsea_make_tex (kpathsea kpse, kpse_file_format_type format, const_string base) { kpse_format_info_type spec; /* some compilers lack struct initialization */ string ret = NULL; spec = kpse->format_info[format]; if (!spec.type) { /* Not initialized yet? */ kpathsea_init_format (kpse, format); spec = kpse->format_info[format]; } if (spec.program && spec.program_enabled_p) { /* See the documentation for the envvars we're dealing with here. */ /* Number of arguments is spec.argc + 1, plus the trailing NULL. */ string *args = XTALLOC (spec.argc + 2, string); /* Helpers */ int argnum; int i; /* FIXME * Check whether the name we were given is likely to be a problem. * Right now we err on the side of strictness: * - may not start with a hyphen (fixable in the scripts). * - allowed are: alphanumeric, underscore, hyphen, period, plus * ? also allowed DIRSEP, as we can be fed that when creating pk fonts * No doubt some possibilities were overlooked. */ if (base[0] == '-' /* || IS_DIR_SEP(base[0]) */) { fprintf(stderr, "kpathsea:make_tex: Invalid filename `%s', starts with '%c'\n", base, base[0]); return NULL; } for (i = 0; base[i]; i++) { if (!ISALNUM(base[i]) && base[i] != '-' && base[i] != '+' && base[i] != '_' && base[i] != '.' && !IS_DIR_SEP(base[i])) { fprintf(stderr, "kpathsea:make_tex: Invalid filename `%s', contains '%c'\n", base, base[i]); return NULL; } } if (format == kpse_gf_format || format == kpse_pk_format || format == kpse_any_glyph_format) set_maketex_mag (kpse); /* Here's an awful kludge: if the mode is `/', mktexpk recognizes it as a special case. `kpse_prog_init' sets it to this in the first place when no mode is otherwise specified; this is so when the user defines a resolution, they don't also have to specify a mode; instead, mktexpk's guesses will take over. They use / for the value because then when it is expanded as part of the PKFONTS et al. path values, we'll wind up searching all the pk directories. We put $MAKETEX_MODE in the path values in the first place so that sites with two different devices with the same resolution can find the right fonts; but such sites are uncommon, so they shouldn't make things harder for everyone else. */ for (argnum = 0; argnum < spec.argc; argnum++) { args[argnum] = kpathsea_var_expand (kpse, spec.argv[argnum]); } args[argnum++] = xstrdup(base); args[argnum] = NULL; ret = maketex (kpse, format, args); for (argnum = 0; args[argnum] != NULL; argnum++) free (args[argnum]); free (args); } return ret; }
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); }