home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume15 / nroffgraphics / part01 / ditread.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-06-06  |  6.2 KB  |  215 lines

  1. /*
  2.  * ditread.c -- read ditroff-format tables into internal form
  3.  *
  4.  * Use this function to read a ditroff-style all-ASCII driver table into the
  5.  * internal form given in the term.h header file.
  6.  *
  7.  * Standard C-style octal, hex and character escapes are accepted in string
  8.  * and character fields. Due to lack of documentation, I don't know whether
  9.  * {n,t}roff accepts hex escapes or character escape other than \[bnrt].
  10.  *
  11.  * The global ignorebad may be set to any nonzero value to cause this function
  12.  * to simply skip invalid ditroff characters (such as \(bx) rather than
  13.  * aborting when they are encountered. Otherwise, all errors emit a diagnostic
  14.  * to stderr and call exit(1).
  15.  *
  16.  * This code expects to be able to call an escape processor escape() to do
  17.  * its input character processing.
  18.  *
  19.  * This code brought to you as a public service by Eric S. Raymond, Feb 1988
  20.  * and is copyrighted (c)1988 by the author. Use, distribute, and mangle
  21.  * freely, but don't try to make money selling it unless you're going to send
  22.  * me a cut. Send bug reports, love letters and death threats to eric@snark
  23.  * aka ...!rutgers!vu-vlsi!snark!eric.
  24.  */
  25. /*LINTLIBRARY*/
  26. #include <stdio.h>
  27. #include <ctype.h>
  28. #include "termtab.h"
  29.  
  30. extern char *strcpy(), *strchr(), *calloc();
  31. extern void exit();
  32.  
  33. #define CTRL(c)    ((c) & 0x1F)
  34. #define META    0x80
  35.  
  36. int ignorebad;    /* if nz, skip invalid character names instead of bombing */
  37.  
  38. static char buf[BUFSIZ];    /* common input buffer */
  39.  
  40. static char *digetstr(key, fp)
  41. /* fill in the next string slot in the fixed-format part of the table */
  42. char    *key;
  43. FILE    *fp;
  44. {
  45.     char *lq, *rq;
  46.  
  47.     (void) fgets(buf, BUFSIZ, fp);
  48.     if (strncmp(buf, key, strlen(key)))
  49.     {
  50.     (void) fprintf(stderr, "tabconv: expected %s, saw %s", key, buf);
  51.     exit(1);
  52.     }
  53.  
  54.     /* delimit the value string part */
  55.     if ((lq = strchr(buf + strlen(key), '"')) == (char *)NULL)
  56.     {
  57.     (void) fprintf(stderr, "tabconv: missing leading quote at %s", buf);
  58.     exit(1);
  59.     }
  60.     if ((rq = strchr(++lq, '"')) == (char *)NULL)
  61.     {
  62.     (void) fprintf(stderr, "tabconv: missing trailing quote at %s", buf);
  63.     exit(1);
  64.     }
  65.     *rq = '\0';
  66.     
  67.     (void) escape(lq, lq);
  68.     return(lq);
  69. }
  70.  
  71. static void digetint(key, loc, fp)
  72. char    *key;
  73. int    *loc;
  74. FILE    *fp;
  75. {
  76.     (void) fgets(buf, BUFSIZ, fp);
  77.     if (strncmp(buf, key, strlen(key)))
  78.     {
  79.     (void) fprintf(stderr, "tabconv: expected %s, saw %s", key, buf);
  80.     exit(1);
  81.     }
  82.  
  83.     if (sscanf(buf + strlen(key), " %d", loc) != 1)
  84.     {
  85.     (void) fprintf(stderr, "tabconv: bad integer format at %s", buf);
  86.     exit(1);
  87.     }
  88. }
  89.  
  90. static int digetchr(tp, fp)
  91. nrtab_t    *tp;
  92. FILE    *fp;
  93. {
  94.     char charname[BUFSIZ], charval[BUFSIZ];
  95.     register char **sp;
  96.     int fc, width;
  97.  
  98.     if (fgets(buf, BUFSIZ, fp) == (char *)NULL)
  99.     return(EOF);
  100.  
  101.     /* we must discard the width info, the old format doesn't support it */
  102.     if ((fc = sscanf(buf, "%s %d %s", charname, &width, charval + 1)) != 3)
  103.     {
  104.     (void) fprintf(stderr,
  105.         "tabconv: only %d fields found, bad char definition at %s",fc,buf);
  106.     exit(1);
  107.     }
  108.  
  109.     /* find the referenced character name in the {n,t}roff name table */
  110.     for (sp = ntnames; *sp != (char *)NULL; sp++)
  111.     if (strcmp(*sp, charname) == 0)
  112.         break;
  113.     if (*sp == (char *)NULL)
  114.     {
  115.     (void) fprintf(stderr, "tabconv: bad character name at %s", buf);
  116.     if (!ignorebad)
  117.         exit(1);
  118.     }
  119.     else    /* character name found OK */
  120.     {
  121.     /* the hackery below is so we don't botch zero-width characters */
  122.     if ((charval[0] = width) == 0)
  123.         charval[0] |= META;
  124.  
  125.     (void) escape(charval + 1, charval + 1);
  126.     tp->codetab[sp - ntnames] = addstring(charval, &tp->pool);
  127.  
  128.     if (width == 0)
  129.         tp->codetab[sp - ntnames][0] &=~ META;
  130.     }
  131.     return(0);
  132. }
  133.  
  134. nrtab_t *ditread(fp)
  135. /* fill in a terminal table structure from a ditroff-format description */
  136. FILE *fp;
  137. {
  138.     register char ch;
  139.  
  140. #ifndef lint
  141.     nrtab_t    *tp = (nrtab_t *) calloc(sizeof(nrtab_t), 1);
  142. #else
  143.     nrtab_t    *tp = (nrtab_t *)NULL;
  144. #endif /* lint */
  145.  
  146.     /* initialize the string table part of the malloc'd structure */
  147.     (void) newstrings(&tp->pool);
  148.  
  149.     /* read in the fixed-format part of the table first */
  150.  
  151.     /* read name line */
  152.     (void) fgets(buf, BUFSIZ, fp);
  153.     buf[strlen(buf) - 1] = '\0';
  154.     tp->name = addstring(buf, &tp->pool);
  155.  
  156.     /* read integer printer parameters */
  157.     digetint("bset", &tp->bset, fp);
  158.     digetint("breset", &tp->breset, fp);
  159.     digetint("Hor", &tp->Hor, fp);
  160.     digetint("Vert", &tp->Vert, fp);
  161.     digetint("Newline", &tp->Newline, fp);
  162.     digetint("Char", &tp->Char, fp);
  163. #ifdef KANJI
  164.     digetint("Kchar", &tp->Kchar, fp);
  165. #endif KANJI
  166.     digetint("Em", &tp->Em, fp);
  167.     digetint("Halfline", &tp->Halfline, fp);
  168.     digetint("Adj", &tp->Adj, fp);
  169.  
  170.     /* read string-valued parameters */
  171.     tp->twinit    = addstring(digetstr("twinit", fp), &tp->pool);
  172.     tp->twrest    = addstring(digetstr("twrest", fp), &tp->pool);
  173.     tp->twnl    = addstring(digetstr("twnl", fp), &tp->pool);
  174.     tp->hlr    = addstring(digetstr("hlr", fp), &tp->pool);
  175.     tp->hlf    = addstring(digetstr("hlf", fp), &tp->pool);
  176.     tp->flr    = addstring(digetstr("flr", fp), &tp->pool);
  177.     tp->bdon    = addstring(digetstr("bdon", fp), &tp->pool);
  178.     tp->bdoff    = addstring(digetstr("bdoff", fp), &tp->pool);
  179.     tp->iton    = addstring(digetstr("iton", fp), &tp->pool);
  180.     tp->itoff    = addstring(digetstr("itoff", fp), &tp->pool);
  181.     tp->ploton    = addstring(digetstr("ploton", fp), &tp->pool);
  182.     tp->plotoff = addstring(digetstr("plotoff", fp), &tp->pool);
  183.     tp->up    = addstring(digetstr("up", fp), &tp->pool);
  184.     tp->down    = addstring(digetstr("down", fp), &tp->pool);
  185.     tp->right    = addstring(digetstr("right", fp), &tp->pool);
  186.     tp->left    = addstring(digetstr("left", fp), &tp->pool);
  187.  
  188.     /* skip blank line(s), then expect character set keyword */
  189.     do {
  190.         (void) fgets(buf, BUFSIZ, fp);
  191.     } while
  192.     (buf[0] == '\n');
  193.     if (strcmp(buf, "charset\n"))
  194.     {
  195.     (void) fprintf(stderr, "tabconv: charset keyword missing\n");
  196.     exit(1);
  197.     }
  198.  
  199.     /* insert defaults for printable characters */
  200.     for (ch = CHARMIN; ch < CHARMAX && isprint(ch); ch++)
  201.     {
  202.     buf[0] = 1;                /* set default width */
  203.     (void) strcpy(buf + 1, ntnames[ch - CHARMIN]);
  204.     tp->codetab[ch-CHARMIN] = addstring(buf, &tp->pool);
  205.     }
  206.  
  207.     /* now read the character definitions */
  208.     while (digetchr(tp, fp) != EOF)
  209.     continue;
  210.  
  211.     return(tp);
  212. }
  213.  
  214. /* ditread.c ends here */
  215.