home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / tex / texsrc1 / Src / lib / old-c / fontmap < prev    next >
Encoding:
Text File  |  1993-05-01  |  5.4 KB  |  211 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.  
  25.  
  26. /* Fontname mapping.  We use a straightforward hash table.  */
  27.  
  28. #define MAP_SIZE 199
  29.  
  30.  
  31. /* The hash function.  We go for simplicity here.  */
  32.  
  33. static unsigned
  34. map_hash (key)
  35.     char *key;
  36. {
  37.   unsigned n = 0;
  38.   
  39.   /* There are very few font names which are anagrams of each other (I
  40.      think), so no point in weighting the characters.  */
  41.   while (*key != 0)
  42.     n += *key++;
  43.   
  44.   n %= MAP_SIZE;
  45.   
  46.   return n;
  47. }
  48.  
  49. /* Look up STR in MAP.  Return the corresponding `value' or NULL.  */
  50.  
  51. static char *
  52. map_lookup_str (map, key)
  53.     map_type map;
  54.     char *key;
  55. {
  56.   map_element_type *p;
  57.   unsigned n = map_hash (key);
  58.   
  59.   for (p = map[n]; p != NULL; p = p->next)
  60.     if (STREQ (key, p->key))
  61.       return p->value;
  62.   
  63.   return NULL;
  64. }
  65.  
  66.  
  67. /* Look up KEY in MAP; if it's not found, remove any suffix from KEY and
  68.    try again.  */
  69.  
  70. char *
  71. map_lookup (map, key)
  72.     map_type map;
  73.     char *key;
  74. {
  75.   extern string extend_filename ();
  76.   string suffix = find_suffix (key);
  77.   string ret = map_lookup_str (map, key);
  78.   
  79.   if (!ret)
  80.     {
  81.       /* OK, the original KEY didn't work.  Let's check for the KEY without
  82.          an extension -- perhaps they gave foobar.tfm, but the mapping only
  83.          defines `foobar'.  */
  84.       if (suffix)
  85.         {
  86.           string base_key = remove_suffix (key);
  87.           
  88.           ret = map_lookup_str (map, base_key);
  89.  
  90.           free (base_key);
  91.         }
  92.     }
  93.  
  94.   /* Append the same suffix we took off, if necessary.  */
  95.   if (ret)
  96.     ret = extend_filename (ret, suffix);
  97.  
  98.   return ret;
  99. }
  100.  
  101. /* If KEY is not already in MAP, insert it and VALUE.  */
  102.  
  103. static void
  104. map_insert (map, key, value)
  105.     map_type map;
  106.     char *key;
  107.     char *value;
  108. {
  109.   unsigned n = map_hash (key);
  110.   map_element_type **p = &map[n];
  111.   map_element_type ***trailer = &p;
  112.  
  113.   while (*p != NULL && !STREQ (key, (*p)->key))
  114.     {
  115.        *p = (*p)->next;
  116.        trailer = &p;
  117.     }
  118.  
  119.   if (*p == NULL)
  120.     {
  121.       **trailer = XTALLOC (MAP_SIZE, map_element_type);
  122.       (**trailer)->key = xstrdup (key);
  123.       (**trailer)->value = xstrdup (value);
  124.       (**trailer)->next = NULL;
  125.     }
  126. }
  127.  
  128. /* Open and read the mapping file FILENAME, putting its entries into
  129.    MAP. Comments begin with % and continue to the end of the line.  Each
  130.    line of the file defines an entry: the first word is the real
  131.    filename (e.g., `ptmr'), the second word is the alias (e.g.,
  132.    `Times-Roman'), and any subsequent words are ignored.  .tfm is added
  133.    if either the filename or the alias have no extension.  This is the
  134.    same order as in Dvips' psfonts.map; unfortunately, we can't have TeX
  135.    read that same file, since most of the real filenames start with an
  136.    `r', because of the virtual fonts Dvips uses.  */
  137.  
  138. static void
  139. map_file_parse (map, map_filename)
  140.     map_type map;
  141.     char *map_filename;
  142. {
  143.   extern FILE *xfopen ();    /* In xfopen.c.  */
  144.   extern char *read_line ();    /* In line.c.  */
  145.   char *l;
  146.   unsigned map_lineno = 0;
  147.   FILE *f = xfopen (map_filename, FOPEN_R_MODE);
  148.   
  149.   while ((l = read_line (f)) != NULL)
  150.     {
  151.       string filename;
  152.       string comment_loc = strrchr (l, '%');
  153.       
  154.       map_lineno++;
  155.       
  156.       /* Ignore anything after a %.  */
  157.       if (comment_loc)
  158.         *comment_loc = 0;
  159.       
  160.       /* If we don't have any filename, that's ok, the line is blank.  */
  161.       filename = strtok (l, " \t");
  162.       if (filename)
  163.         {
  164.           string alias = strtok (NULL, " \t");
  165.           
  166.           /* But if we have a filename and no alias, something's wrong.  */
  167.           if (alias == NULL || *alias == 0)
  168.             fprintf (stderr, "%s:%u: Alias missing for filename `%s'.\n",
  169.                      map_filename, map_lineno, filename);
  170.           else
  171.             {
  172.               /* We've got everything.  Insert the new entry.  */
  173.               map_insert (map, alias, filename);
  174.             }
  175.         }
  176.       
  177.       free (l);
  178.     }
  179.   
  180.   xfclose (f, map_filename);
  181. }
  182.  
  183.  
  184. /* Look for the file `texfonts.map' in each of the directories in
  185.    DIR_LIST.  Entries in earlier files override later files.  */
  186.  
  187. map_type
  188. map_create (dir_list)
  189.     string *dir_list;
  190. {
  191.   map_type map = (map_type) xcalloc (MAP_SIZE, sizeof (map_element_type *));
  192.   
  193.   while (*dir_list)
  194.     {
  195.       char filename[PATH_MAX];
  196.       
  197.       /* We don't bother with the filename truncation that `readable' in
  198.          `pathsrch.c' does, since we ourselves are giving the filename,
  199.          and I don't think it's worth worrying about too-long
  200.          intermediate directory names in the path.  */
  201.       strcpy (filename, *dir_list);
  202.       strcat (filename, "texfonts.map");
  203.       
  204.       if (riscos_readable (filename) == 0)
  205.         map_file_parse (map, filename);
  206.       
  207.       dir_list++;
  208.     }
  209.   return map;
  210. }
  211.