home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / fontutils-0.6-base.tgz / fontutils-0.6-base.tar / fsf / fontutils / lib / encoding.c < prev    next >
C/C++ Source or Header  |  1992-08-17  |  5KB  |  192 lines

  1. /* encoding.c: read a font encoding (.enc) file.
  2.  
  3. Copyright (C) 1992 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 "encoding.h"
  22. #include "libfile.h"
  23. #include "str-lcase.h"
  24. #include "tfm.h"
  25.  
  26.  
  27. static encoding_char_type parse_encoding_line (string);
  28. static tfm_ligature_type parse_ligature (void);
  29.  
  30. /* Look through INFO for NAME.  */
  31.  
  32. int 
  33. encoding_number (encoding_info_type info, string name)
  34. {
  35.   unsigned code;
  36.  
  37.   if (name == NULL)
  38.     return -1;
  39.  
  40.   for (code = 0; code <= MAX_CHARCODE; code++)
  41.     if (ENCODING_CHAR_NAME (info, code) != NULL
  42.         && STREQ (ENCODING_CHAR_NAME (info, code), name))   
  43.       return code;
  44.  
  45.   return -1;  
  46. }
  47.  
  48. /* Return the basename for the encoding file in which the encoding 
  49.    CODING_SCHEME can be found.  If we can't find CODING_SCHEME, return
  50.    DEFAULT_ENCODING.  */
  51.  
  52. string
  53. coding_scheme_to_filename (string coding_scheme)
  54. {
  55.   string mapping_line, enc_name;
  56.   string lc_coding_scheme = str_to_lower (coding_scheme);
  57.   
  58.   libfile_start ("encoding", "map");
  59.  
  60.   while ((mapping_line = libfile_line ()) != NULL)
  61.     {
  62.       string test_coding_scheme, lc_test_coding_scheme;
  63.  
  64.       enc_name = strtok (mapping_line, " \t");
  65.       test_coding_scheme = strtok (NULL, "\t");
  66.       lc_test_coding_scheme = str_to_lower (test_coding_scheme);
  67.  
  68.       if (STREQ (lc_coding_scheme, lc_test_coding_scheme))
  69.         break;
  70.  
  71.       free (lc_test_coding_scheme);
  72.       free (mapping_line);
  73.     }
  74.  
  75.   libfile_close ();
  76.  
  77.   if (mapping_line == NULL)
  78.     {
  79.       WARNING3 ("%s: unknown encoding `%s'; using default `%s'",
  80.                 "encoding.map", coding_scheme, DEFAULT_ENCODING);
  81.       enc_name = DEFAULT_ENCODING;
  82.     }
  83.  
  84.   free (lc_coding_scheme);
  85.   
  86.   return enc_name;
  87. }
  88.  
  89. /* Parse the encoding file `FILENAME.enc' and return a structure
  90.    describing what we read.  If the file doesn't exist, give a fatal
  91.    error.  */
  92.  
  93. encoding_info_type
  94. read_encoding_file (string filename)
  95. {
  96.   encoding_info_type info;
  97.   string line;
  98.   unsigned code;
  99.   
  100.   /* Prepare to read from FILENAME.  */
  101.   libfile_start (filename, "enc");
  102.   
  103.   /* Start with an empty encoding.  */
  104.   for (code = 0; code <= MAX_CHARCODE; code++)
  105.     ENCODING_CHAR_NAME (info, code) = NULL;
  106.  
  107.   /* The entire first line is the TFM `CODINGSCHEME'.  */
  108.   ENCODING_SCHEME_NAME (info) = libfile_line ();
  109.   
  110.   /* Each remaining line defines one character.  */
  111.   code = 0;
  112.   while ((line = libfile_line ()) != NULL)
  113.     {
  114.       ENCODING_CHAR_ELT (info, code) = parse_encoding_line (line);
  115.       code++;
  116.       free (line);
  117.     }
  118.   
  119.   return info;
  120. }
  121.  
  122. /* Parse one line of the encoding file; this specifies one character.
  123.    The BNF is:
  124.    
  125.    <line>      ::= <word>  <ligatures>
  126.  
  127.    <ligatures> ::= <ligature> [<ligature>]?
  128.                  | <empty>
  129.  
  130.    <ligature>  ::= lig <charcode> =: <charcode>
  131.    
  132.    Whitespace must be between all elements.
  133.    
  134.    If the line is malformed, we give a fatal error.  */
  135.  
  136. #define WORD_SEPARATOR " \t"
  137. #define GET_WORD() strtok (NULL, WORD_SEPARATOR)
  138.  
  139. static encoding_char_type
  140. parse_encoding_line (string line)
  141. {
  142.   encoding_char_type c;
  143.   
  144.   c.name = xstrdup (strtok (line, WORD_SEPARATOR));
  145.   c.ligature = list_init ();
  146.   
  147.   do
  148.     {
  149.       tfm_ligature_type *lig;
  150.       string t = GET_WORD ();
  151.       
  152.       if (t == NULL) /* Do we have more ligature specs?  */
  153.         break;
  154.         
  155.       if (!STREQ (t, "lig"))
  156.         LIBFILE_ERROR1 ("Expected `lig', found `%s'", t);
  157.  
  158.       lig = LIST_TAPPEND (&c.ligature, tfm_ligature_type);
  159.       *lig = parse_ligature ();
  160.     }
  161.   while (true);
  162.  
  163.   return c;
  164. }
  165.  
  166.  
  167. /* Parse a single ligature: <charcode> =: <charcode>.  */
  168.  
  169. static tfm_ligature_type
  170. parse_ligature ()
  171. {
  172.   tfm_ligature_type lig;
  173.   boolean valid;
  174.   string t = GET_WORD ();
  175.   
  176.   lig.character = parse_charcode (t, &valid);
  177.   
  178.   if (!valid)
  179.     LIBFILE_ERROR1 ("Invalid right character code `%s'", t);
  180.  
  181.   t = GET_WORD ();
  182.   if (!STREQ (t, "=:"))
  183.     LIBFILE_ERROR1 ("Expected `=:', found `%s'", t);
  184.   
  185.   t = GET_WORD ();
  186.   lig.ligature = parse_charcode (t, &valid);
  187.   if (!valid)
  188.     LIBFILE_ERROR1 ("Invalid ligature character code `%s'", t);
  189.   
  190.   return lig;
  191. }
  192.