home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / lout2.lzh / LOUT2 / z38.c < prev    next >
Text File  |  1994-01-23  |  9KB  |  186 lines

  1. /*@z38.c:Encoding Vectors:Declarations@***************************************/
  2. /*                                                                           */
  3. /*  LOUT: A HIGH-LEVEL LANGUAGE FOR DOCUMENT FORMATTING (VERSION 2.05)       */
  4. /*  COPYRIGHT (C) 1993 Jeffrey H. Kingston                                   */
  5. /*                                                                           */
  6. /*  Jeffrey H. Kingston (jeff@cs.su.oz.au)                                   */
  7. /*  Basser Department of Computer Science                                    */
  8. /*  The University of Sydney 2006                                            */
  9. /*  AUSTRALIA                                                                */
  10. /*                                                                           */
  11. /*  This program is free software; you can redistribute it and/or modify     */
  12. /*  it under the terms of the GNU General Public License as published by     */
  13. /*  the Free Software Foundation; either version 1, or (at your option)      */
  14. /*  any later version.                                                       */
  15. /*                                                                           */
  16. /*  This program is distributed in the hope that it will be useful,          */
  17. /*  but WITHOUT ANY WARRANTY; without even the implied warranty of           */
  18. /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            */
  19. /*  GNU General Public License for more details.                             */
  20. /*                                                                           */
  21. /*  You should have received a copy of the GNU General Public License        */
  22. /*  along with this program; if not, write to the Free Software              */
  23. /*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
  24. /*                                                                           */
  25. /*  FILE:         z38.c                                                      */
  26. /*  MODULE:       Encoding Vectors                                           */
  27. /*  EXTERNS:      EvLoad(), EvRetrieve(), EvName(), EvPrintAll()             */
  28. /*                                                                           */
  29. /*****************************************************************************/
  30. #include "externs"
  31. #define MAX_EV         20        /* max number of encoding vectors    */
  32. #define MAX_CHAR    256        /* max chars represented in one char */
  33. #define    MAX_HASH    353        /* size of hash table                */
  34.  
  35. typedef struct evec {
  36.   OBJECT    file_name;        /* name of file containing the vec   */
  37.   FILE_NUM    fnum;            /* the file number of this file      */
  38.   BOOLEAN    must_print;        /* TRUE if this vec must be printed  */
  39.   OBJECT    name;            /* PostScript name of encoding vec   */
  40.   OBJECT    vector[MAX_CHAR];    /* character names                   */
  41.   FULL_CHAR    hash_table[MAX_HASH];    /* character hash table for inverse  */
  42. } *EVEC;
  43.  
  44. static    EVEC    ev_table[MAX_EV];    /* the encoding vectors              */
  45. static    int    evtop = 0;        /* first free slot in ev_table[]     */
  46.  
  47. #define hash(str, pos)                            \
  48. { FULL_CHAR *p = str;                            \
  49.   for( pos = 2 * *p++;  *p;  pos += *p++);                \
  50.   pos = pos % MAX_HASH;                            \
  51. }
  52.  
  53. /*@::EvLoad()@****************************************************************/
  54. /*                                                                           */
  55. /*  ENCODING EvLoad(file_name, must_print)                                   */
  56. /*                                                                           */
  57. /*  Declare file_name to be an encoding vector file.  A file may be so       */
  58. /*  declared more than once.  If must_print is true on any declaration,      */
  59. /*  the encoding vector must be down-loaded to the PostScript interpreter.   */
  60. /*                                                                           */
  61. /*****************************************************************************/
  62.  
  63. ENCODING EvLoad(file_name, must_print)
  64. OBJECT file_name;  BOOLEAN must_print;
  65. { int i;  FILE *fp;  EVEC ev;  char *malloc();
  66.   FULL_CHAR buff[30], enc; unsigned int code, pos;
  67.   debug2(DEV, D, "EvLoad(%s, %s)", EchoObject(file_name), bool(must_print));
  68.   enc = 0;
  69.   while( enc < evtop &&
  70.      !StringEqual(string(ev_table[enc]->file_name), string(file_name)) )
  71.     enc++;
  72.   if( enc < evtop )
  73.   {
  74.     /* encoding vector already loaded, so only need to record must_print */
  75.     ev_table[enc]->must_print = ev_table[enc]->must_print || must_print;
  76.     Dispose(file_name);
  77.   }
  78.   else
  79.   { 
  80.     /* initialize new slot in ev_table[] for a new encoding vector */
  81.     if( evtop++ == MAX_EV )
  82.       Error(FATAL, &fpos(file_name), "too many encoding vectors");
  83.     ev_table[enc] = ev = (EVEC) malloc( sizeof(struct evec) );
  84.     if( ev == (EVEC) NULL )  Error(FATAL, &fpos(file_name),
  85.       "run out of memory when loading encoding vector");
  86.     ev->must_print = must_print;
  87.     ev->file_name  = file_name;
  88.     for( i = 0;  i < MAX_CHAR; i++ )  ev->vector[i] = nil;
  89.     for( i = 0;  i < MAX_HASH; i++ )  ev->hash_table[i] = 0;
  90.  
  91.     /* define and open the file */
  92.     ev->fnum = DefineFile(string(file_name), STR_EMPTY, &fpos(file_name),
  93.       ENCODING_FILE, ENCODING_PATH);
  94.     fp = OpenFile(ev->fnum, FALSE, FALSE);
  95.     if( fp == NULL )  Error(FATAL, PosOfFile(ev->fnum),
  96.       "cannot open encoding vector file %s", FileName(ev->fnum));
  97.  
  98.     /* invent a PostScript name for the encoding vector */
  99.     StringCopy(buff, AsciiToFull("vec"));
  100.     StringCat(buff, StringInt(evtop));
  101.     ev->name = MakeWord(WORD, buff, no_fpos);
  102.  
  103.     /* read character names and insert (name, position) pairs into hash table */
  104.     for( code = 0;  fscanf(fp, "%s", buff) == 1;  code++ )
  105.     { if( code >= MAX_CHAR )  Error(FATAL, PosOfFile(ev->fnum),
  106.     "too many character names in encoding vector file %s",
  107.     FileName(ev->fnum));
  108.       hash(buff, pos);
  109.       while( (i = ev->hash_table[pos]) != 0 )
  110.       {    if( StringEqual(string(ev->vector[i]), buff) )
  111.     { ev->vector[code] = ev->vector[i];
  112.       break;
  113.     }
  114.     pos = (pos + 1) % MAX_HASH;
  115.       }
  116.       if( i == 0 )
  117.       {    ev->vector[code] = MakeWord(WORD, buff, no_fpos);
  118.     ev->hash_table[pos] = (FULL_CHAR) code;
  119.       }
  120.     }
  121.     if( code != MAX_CHAR )  Error(FATAL, PosOfFile(ev->fnum),
  122.     "too few character names in encoding vector file %s",
  123.     FileName(ev->fnum));
  124.   }
  125.   debug1(DEV, D, "EvLoad returning %d", enc);
  126.   return enc;
  127. } /* end EvLoad */
  128.  
  129.  
  130. /*@::EvRetrieve(), EvName(), EvPrintAll()@************************************/
  131. /*                                                                           */
  132. /*  FULL_CHAR EvRetrieve(str, enc)                                           */
  133. /*                                                                           */
  134. /*  Returns the character code corresponding to character name str in        */
  135. /*  ENCODING enc, or 0 if not found.                                         */
  136. /*                                                                           */
  137. /*****************************************************************************/
  138.  
  139. FULL_CHAR EvRetrieve(str, enc)
  140. FULL_CHAR *str;  ENCODING enc;
  141. { unsigned int pos;  FULL_CHAR code;  EVEC ev;
  142.   ev = ev_table[enc];
  143.   hash(str, pos);
  144.   while( (code = ev->hash_table[pos]) != 0 )
  145.   { if( StringEqual(string(ev->vector[code]), str) )  return code;
  146.     pos = (pos + 1) % MAX_HASH;
  147.   }
  148.   return '\0';
  149. } /* end EvRetrieve */
  150.  
  151.  
  152. /*****************************************************************************/
  153. /*                                                                           */
  154. /*  FULL_CHAR *EvName(enc)                                                   */
  155. /*                                                                           */
  156. /*  Returns the PostScript name of ENCODING enc                              */
  157. /*                                                                           */
  158. /*****************************************************************************/
  159.  
  160. FULL_CHAR *EvName(enc)
  161. ENCODING enc;
  162. { assert( enc < evtop, "EvName: enc out of range!" );
  163.   return string(ev_table[enc]->name);
  164. } /* end EvName */
  165.  
  166.  
  167. /*****************************************************************************/
  168. /*                                                                           */
  169. /*  EvPrintAll(fp)                                                           */
  170. /*                                                                           */
  171. /*  Print all encoding vectors in PostScript form on file fp.                */
  172. /*                                                                           */
  173. /*****************************************************************************/
  174.  
  175. EvPrintAll(fp)
  176. FILE *fp;
  177. { ENCODING enc;  EVEC ev;  int i;
  178.   for( enc = 0;  enc < evtop;  enc++ )  if( ev_table[enc]->must_print )
  179.   { ev = ev_table[enc];
  180.     fprintf(fp, "/%s [\n", string(ev->name));
  181.     for( i = 0;  i < MAX_CHAR;  i++ )
  182.       fprintf(fp, "/%s%c", string(ev->vector[i]), (i+1) % 8 != 0 ? ' ' : '\n');
  183.     fprintf(fp, "] def\n\n");
  184.   }
  185. } /* end EvPrintAll */
  186.