static boolean alias_build (kpathsea kpse, hash_table_type *table, const_string alias_filename) { string line, real, alias; unsigned count = 0; FILE *alias_file = fopen (alias_filename, FOPEN_R_MODE); if (alias_file) { while ((line = read_line (alias_file)) != NULL) { /* comments or empty */ if (*line == 0 || *line == '%' || *line == '#') { ; } else { /* Each line should have two fields: realname aliasname. */ real = line; while (*real && ISSPACE (*real)) real++; alias = real; while (*alias && !ISSPACE (*alias)) alias++; *alias++ = 0; while (*alias && ISSPACE (*alias)) alias++; /* Is the check for errors strong enough? Should we warn the user for potential errors? */ if (strlen (real) != 0 && strlen (alias) != 0) { /* Stuff in the alias file should be normalized. */ hash_insert_normalized (table, xstrdup (alias), xstrdup (real)); count++; } } free (line); } #ifdef KPSE_DEBUG if (KPATHSEA_DEBUG_P (KPSE_DEBUG_HASH)) { /* As with ls-R above ... */ boolean hash_summary_only = true; DEBUGF2 ("%s: %u aliases.\n", alias_filename, count); DEBUGF ("alias hash table:"); hash_print (*table, hash_summary_only); fflush (stderr); } #endif /* KPSE_DEBUG */ xfclose (alias_file, alias_filename); } return alias_file != NULL; }
static void map_file_parse (kpathsea kpse, const_string map_filename) { char *orig_l; unsigned map_lineno = 0; FILE *f = xfopen (map_filename, FOPEN_R_MODE); if (kpse->record_input) kpse->record_input (map_filename); while ((orig_l = read_line (f)) != NULL) { string filename; string l = orig_l; /* save for free() */ string comment_loc = strrchr (l, '%'); if (!comment_loc) { comment_loc = strstr (l, "@c"); } /* Ignore anything after a % or @c. */ if (comment_loc) *comment_loc = 0; map_lineno++; /* Skip leading whitespace so we can use strlen below. Can't use strtok since this routine is recursive. */ while (*l && ISSPACE (*l)) l++; /* If we don't have any filename, that's ok, the line is blank. */ filename = token (l); if (filename) { string alias = token (l + strlen (filename)); if (STREQ (filename, "include")) { if (alias == NULL) { WARNING2 ("%s:%u: Filename argument for include directive missing", map_filename, map_lineno); } else { string include_fname = kpathsea_path_search (kpse, kpse->map_path, alias, false); if (include_fname) { map_file_parse (kpse, include_fname); if (include_fname != alias) free (include_fname); } else { WARNING3 ("%s:%u: Can't find fontname include file `%s'", map_filename, map_lineno, alias); } free (alias); free (filename); } /* But if we have a filename and no alias, something's wrong. */ } else if (alias == NULL) { WARNING3 ("%s:%u: Fontname alias missing for filename `%s'", map_filename, map_lineno, filename); free (filename); } else { /* We've got everything. Insert the new entry. They were already dynamically allocated by token(), so don't bother with xstrdup. */ hash_insert_normalized (&(kpse->map), alias, filename); } } free (orig_l); } xfclose (f, map_filename); }
static boolean db_build (kpathsea kpse, hash_table_type *table, const_string db_filename) { string line; unsigned dir_count = 0, file_count = 0, ignore_dir_count = 0; unsigned len = strlen (db_filename) - sizeof (DB_NAME) + 1; /* Keep the /. */ string top_dir = (string)xmalloc (len + 1); string cur_dir = NULL; /* First thing in ls-R might be a filename. */ FILE *db_file = fopen (db_filename, FOPEN_R_MODE); #if defined(WIN32) string pp; #endif strncpy (top_dir, db_filename, len); top_dir[len] = 0; if (db_file) { while ((line = read_line (db_file)) != NULL) { len = strlen (line); #if defined(WIN32) for (pp = line; *pp; pp++) { if (IS_KANJI(pp)) pp++; else *pp = TRANSFORM(*pp); } #endif /* A line like `/foo:' = new dir foo. Allow both absolute (/...) and explicitly relative (./...) names here. It's a kludge to pass in the directory name with the trailing : still attached, but it doesn't actually hurt. */ if (len > 0 && line[len - 1] == ':' && kpathsea_absolute_p (kpse, line, true)) { /* New directory line. */ if (!ignore_dir_p (line)) { /* If they gave a relative name, prepend full directory name now. */ line[len - 1] = DIR_SEP; /* Skip over leading `./', it confuses `match' and is just a waste of space, anyway. This will lose on `../', but `match' won't work there, either, so it doesn't matter. */ cur_dir = *line == '.' ? concat (top_dir, line + 2) : xstrdup (line); dir_count++; } else { cur_dir = NULL; ignore_dir_count++; } /* Ignore blank, `.' and `..' lines. */ } else if (*line != 0 && cur_dir /* a file line? */ && !(*line == '.' && (line[1] == 0 || (line[1] == '.' && line[2] == 0)))) { /* Make a new hash table entry with a key of `line' and a data of `cur_dir'. An already-existing identical key is ok, since a file named `foo' can be in more than one directory. Share `cur_dir' among all its files (and hence never free it). Note that we assume that all names in the ls-R file have already been case-smashed to lowercase where appropriate. */ hash_insert_normalized (table, xstrdup (line), cur_dir); file_count++; } /* else ignore blank lines or top-level files or files in ignored directories*/ free (line); } xfclose (db_file, db_filename); if (file_count == 0) { WARNING1 ("kpathsea: %s: No usable entries in ls-R", db_filename); WARNING ("kpathsea: See the manual for how to generate ls-R"); db_file = NULL; } else { str_list_add (&(kpse->db_dir_list), xstrdup (top_dir)); } #ifdef KPSE_DEBUG if (KPATHSEA_DEBUG_P (KPSE_DEBUG_HASH)) { /* Don't make this a debugging bit, since the output is so voluminous, and being able to specify -1 is too useful. Instead, let people who want it run the program under a debugger and change the variable that way. */ boolean hash_summary_only = true; DEBUGF4 ("%s: %u entries in %d directories (%d hidden).\n", db_filename, file_count, dir_count, ignore_dir_count); DEBUGF ("ls-R hash table:"); hash_print (*table, hash_summary_only); fflush (stderr); } #endif /* KPSE_DEBUG */ } free (top_dir); return db_file != NULL; }