home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / tex / texsrc1 / Src / lib / c / fontmap < prev    next >
Encoding:
Text File  |  1993-05-02  |  5.5 KB  |  217 lines

  1. /* fontmap.c: read a file for additional font names.
  2.  
  3. Copyright (C) 1993 Free Software Foundation, Inc.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include "config.h"
  20.  
  21. #include "c-pathmx.h"
  22. #include "fontmap.h"
  23.  
  24. #ifdef RISCOS
  25. extern boolean riscos_readable(string name);
  26. #endif
  27.  
  28. /* Fontname mapping.  We use a straightforward hash table.  */
  29.  
  30. #define MAP_SIZE 199
  31.  
  32.  
  33. /* The hash function.  We go for simplicity here.  */
  34.  
  35. static unsigned
  36. map_hash (key)
  37.     char *key;
  38. {
  39.   unsigned n = 0;
  40.   
  41.   /* There are very few font names which are anagrams of each other (I
  42.      think), so no point in weighting the characters.  */
  43.   while (*key != 0)
  44.     n += *key++;
  45.   
  46.   n %= MAP_SIZE;
  47.   
  48.   return n;
  49. }
  50.  
  51. /* Look up STR in MAP.  Return the corresponding `value' or NULL.  */
  52.  
  53. static char *
  54. map_lookup_str (map, key)
  55.     map_type map;
  56.     char *key;
  57. {
  58.   map_element_type *p;
  59.   unsigned n = map_hash (key);
  60.   
  61.   for (p = map[n]; p != NULL; p = p->next)
  62.     if (STREQ (key, p->key))
  63.       return p->value;
  64.   
  65.   return NULL;
  66. }
  67.  
  68.  
  69. /* Look up KEY in MAP; if it's not found, remove any suffix from KEY and
  70.    try again.  */
  71.  
  72. char *
  73. map_lookup (map, key)
  74.     map_type map;
  75.     char *key;
  76. {
  77.   extern string extend_filename ();
  78.   string suffix = find_suffix (key);
  79.   string ret = map_lookup_str (map, key);
  80.   
  81.   if (!ret)
  82.     {
  83.       /* OK, the original KEY didn't work.  Let's check for the KEY without
  84.          an extension -- perhaps they gave foobar.tfm, but the mapping only
  85.          defines `foobar'.  */
  86.       if (suffix)
  87.         {
  88.           string base_key = remove_suffix (key);
  89.           
  90.           ret = map_lookup_str (map, base_key);
  91.  
  92.           free (base_key);
  93.         }
  94.     }
  95.  
  96.   /* Append the same suffix we took off, if necessary.  */
  97.   if (ret)
  98.     ret = extend_filename (ret, suffix);
  99.  
  100.   return ret;
  101. }
  102.  
  103. /* If KEY is not already in MAP, insert it and VALUE.  */
  104.  
  105. static void
  106. map_insert (map, key, value)
  107.     map_type map;
  108.     char *key;
  109.     char *value;
  110. {
  111.   unsigned n = map_hash (key);
  112.   map_element_type **p = &map[n];
  113.   map_element_type ***trailer = &p;
  114.  
  115.   while (*p != NULL && !STREQ (key, (*p)->key))
  116.     {
  117.        *p = (*p)->next;
  118.        trailer = &p;
  119.     }
  120.  
  121.   if (*p == NULL)
  122.     {
  123.       **trailer = XTALLOC (MAP_SIZE, map_element_type);
  124.       (**trailer)->key = xstrdup (key);
  125.       (**trailer)->value = xstrdup (value);
  126.       (**trailer)->next = NULL;
  127.     }
  128. }
  129.  
  130. /* Open and read the mapping file FILENAME, putting its entries into
  131.    MAP. Comments begin with % and continue to the end of the line.  Each
  132.    line of the file defines an entry: the first word is the real
  133.    filename (e.g., `ptmr'), the second word is the alias (e.g.,
  134.    `Times-Roman'), and any subsequent words are ignored.  .tfm is added
  135.    if either the filename or the alias have no extension.  This is the
  136.    same order as in Dvips' psfonts.map; unfortunately, we can't have TeX
  137.    read that same file, since most of the real filenames start with an
  138.    `r', because of the virtual fonts Dvips uses.  */
  139.  
  140. static void
  141. map_file_parse (map, map_filename)
  142.     map_type map;
  143.     char *map_filename;
  144. {
  145.   extern FILE *xfopen ();    /* In xfopen.c.  */
  146.   extern char *read_line ();    /* In line.c.  */
  147.   char *l;
  148.   unsigned map_lineno = 0;
  149.   FILE *f = xfopen (map_filename, FOPEN_R_MODE);
  150.   
  151.   while ((l = read_line (f)) != NULL)
  152.     {
  153.       string filename;
  154.       string comment_loc = strrchr (l, '%');
  155.       
  156.       map_lineno++;
  157.       
  158.       /* Ignore anything after a %.  */
  159.       if (comment_loc)
  160.         *comment_loc = 0;
  161.       
  162.       /* If we don't have any filename, that's ok, the line is blank.  */
  163.       filename = strtok (l, " \t");
  164.       if (filename)
  165.         {
  166.           string alias = strtok (NULL, " \t");
  167.           
  168.           /* But if we have a filename and no alias, something's wrong.  */
  169.           if (alias == NULL || *alias == 0)
  170.             fprintf (stderr, "%s:%u: Alias missing for filename `%s'.\n",
  171.                      map_filename, map_lineno, filename);
  172.           else
  173.             {
  174.               /* We've got everything.  Insert the new entry.  */
  175.               map_insert (map, alias, filename);
  176.             }
  177.         }
  178.       
  179.       free (l);
  180.     }
  181.   
  182.   xfclose (f, map_filename);
  183. }
  184.  
  185.  
  186. /* Look for the file `texfonts.map' in each of the directories in
  187.    DIR_LIST.  Entries in earlier files override later files.  */
  188.  
  189. map_type
  190. map_create (dir_list)
  191.     string *dir_list;
  192. {
  193.   map_type map = (map_type) xcalloc (MAP_SIZE, sizeof (map_element_type *));
  194.   
  195.   while (*dir_list)
  196.     {
  197.       char filename[PATH_MAX];
  198.       
  199.       /* We don't bother with the filename truncation that `readable' in
  200.          `pathsrch.c' does, since we ourselves are giving the filename,
  201.          and I don't think it's worth worrying about too-long
  202.          intermediate directory names in the path.  */
  203.       strcpy (filename, *dir_list);
  204.       strcat (filename, "texfonts.map");
  205.       
  206. #ifdef RISCOS
  207.       if (riscos_readaccess(filename))
  208. #else
  209.       if (access (filename, R_OK) == 0)
  210. #endif
  211.         map_file_parse (map, filename);
  212.       
  213.       dir_list++;
  214.     }
  215.   return map;
  216. }
  217.