home *** CD-ROM | disk | FTP | other *** search
- /*
- * ditread.c -- read ditroff-format tables into internal form
- *
- * Use this function to read a ditroff-style all-ASCII driver table into the
- * internal form given in the term.h header file.
- *
- * Standard C-style octal, hex and character escapes are accepted in string
- * and character fields. Due to lack of documentation, I don't know whether
- * {n,t}roff accepts hex escapes or character escape other than \[bnrt].
- *
- * The global ignorebad may be set to any nonzero value to cause this function
- * to simply skip invalid ditroff characters (such as \(bx) rather than
- * aborting when they are encountered. Otherwise, all errors emit a diagnostic
- * to stderr and call exit(1).
- *
- * This code expects to be able to call an escape processor escape() to do
- * its input character processing.
- *
- * This code brought to you as a public service by Eric S. Raymond, Feb 1988
- * and is copyrighted (c)1988 by the author. Use, distribute, and mangle
- * freely, but don't try to make money selling it unless you're going to send
- * me a cut. Send bug reports, love letters and death threats to eric@snark
- * aka ...!rutgers!vu-vlsi!snark!eric.
- */
- /*LINTLIBRARY*/
- #include <stdio.h>
- #include <ctype.h>
- #include "termtab.h"
-
- extern char *strcpy(), *strchr(), *calloc();
- extern void exit();
-
- #define CTRL(c) ((c) & 0x1F)
- #define META 0x80
-
- int ignorebad; /* if nz, skip invalid character names instead of bombing */
-
- static char buf[BUFSIZ]; /* common input buffer */
-
- static char *digetstr(key, fp)
- /* fill in the next string slot in the fixed-format part of the table */
- char *key;
- FILE *fp;
- {
- char *lq, *rq;
-
- (void) fgets(buf, BUFSIZ, fp);
- if (strncmp(buf, key, strlen(key)))
- {
- (void) fprintf(stderr, "tabconv: expected %s, saw %s", key, buf);
- exit(1);
- }
-
- /* delimit the value string part */
- if ((lq = strchr(buf + strlen(key), '"')) == (char *)NULL)
- {
- (void) fprintf(stderr, "tabconv: missing leading quote at %s", buf);
- exit(1);
- }
- if ((rq = strchr(++lq, '"')) == (char *)NULL)
- {
- (void) fprintf(stderr, "tabconv: missing trailing quote at %s", buf);
- exit(1);
- }
- *rq = '\0';
-
- (void) escape(lq, lq);
- return(lq);
- }
-
- static void digetint(key, loc, fp)
- char *key;
- int *loc;
- FILE *fp;
- {
- (void) fgets(buf, BUFSIZ, fp);
- if (strncmp(buf, key, strlen(key)))
- {
- (void) fprintf(stderr, "tabconv: expected %s, saw %s", key, buf);
- exit(1);
- }
-
- if (sscanf(buf + strlen(key), " %d", loc) != 1)
- {
- (void) fprintf(stderr, "tabconv: bad integer format at %s", buf);
- exit(1);
- }
- }
-
- static int digetchr(tp, fp)
- nrtab_t *tp;
- FILE *fp;
- {
- char charname[BUFSIZ], charval[BUFSIZ];
- register char **sp;
- int fc, width;
-
- if (fgets(buf, BUFSIZ, fp) == (char *)NULL)
- return(EOF);
-
- /* we must discard the width info, the old format doesn't support it */
- if ((fc = sscanf(buf, "%s %d %s", charname, &width, charval + 1)) != 3)
- {
- (void) fprintf(stderr,
- "tabconv: only %d fields found, bad char definition at %s",fc,buf);
- exit(1);
- }
-
- /* find the referenced character name in the {n,t}roff name table */
- for (sp = ntnames; *sp != (char *)NULL; sp++)
- if (strcmp(*sp, charname) == 0)
- break;
- if (*sp == (char *)NULL)
- {
- (void) fprintf(stderr, "tabconv: bad character name at %s", buf);
- if (!ignorebad)
- exit(1);
- }
- else /* character name found OK */
- {
- /* the hackery below is so we don't botch zero-width characters */
- if ((charval[0] = width) == 0)
- charval[0] |= META;
-
- (void) escape(charval + 1, charval + 1);
- tp->codetab[sp - ntnames] = addstring(charval, &tp->pool);
-
- if (width == 0)
- tp->codetab[sp - ntnames][0] &=~ META;
- }
- return(0);
- }
-
- nrtab_t *ditread(fp)
- /* fill in a terminal table structure from a ditroff-format description */
- FILE *fp;
- {
- register char ch;
-
- #ifndef lint
- nrtab_t *tp = (nrtab_t *) calloc(sizeof(nrtab_t), 1);
- #else
- nrtab_t *tp = (nrtab_t *)NULL;
- #endif /* lint */
-
- /* initialize the string table part of the malloc'd structure */
- (void) newstrings(&tp->pool);
-
- /* read in the fixed-format part of the table first */
-
- /* read name line */
- (void) fgets(buf, BUFSIZ, fp);
- buf[strlen(buf) - 1] = '\0';
- tp->name = addstring(buf, &tp->pool);
-
- /* read integer printer parameters */
- digetint("bset", &tp->bset, fp);
- digetint("breset", &tp->breset, fp);
- digetint("Hor", &tp->Hor, fp);
- digetint("Vert", &tp->Vert, fp);
- digetint("Newline", &tp->Newline, fp);
- digetint("Char", &tp->Char, fp);
- #ifdef KANJI
- digetint("Kchar", &tp->Kchar, fp);
- #endif KANJI
- digetint("Em", &tp->Em, fp);
- digetint("Halfline", &tp->Halfline, fp);
- digetint("Adj", &tp->Adj, fp);
-
- /* read string-valued parameters */
- tp->twinit = addstring(digetstr("twinit", fp), &tp->pool);
- tp->twrest = addstring(digetstr("twrest", fp), &tp->pool);
- tp->twnl = addstring(digetstr("twnl", fp), &tp->pool);
- tp->hlr = addstring(digetstr("hlr", fp), &tp->pool);
- tp->hlf = addstring(digetstr("hlf", fp), &tp->pool);
- tp->flr = addstring(digetstr("flr", fp), &tp->pool);
- tp->bdon = addstring(digetstr("bdon", fp), &tp->pool);
- tp->bdoff = addstring(digetstr("bdoff", fp), &tp->pool);
- tp->iton = addstring(digetstr("iton", fp), &tp->pool);
- tp->itoff = addstring(digetstr("itoff", fp), &tp->pool);
- tp->ploton = addstring(digetstr("ploton", fp), &tp->pool);
- tp->plotoff = addstring(digetstr("plotoff", fp), &tp->pool);
- tp->up = addstring(digetstr("up", fp), &tp->pool);
- tp->down = addstring(digetstr("down", fp), &tp->pool);
- tp->right = addstring(digetstr("right", fp), &tp->pool);
- tp->left = addstring(digetstr("left", fp), &tp->pool);
-
- /* skip blank line(s), then expect character set keyword */
- do {
- (void) fgets(buf, BUFSIZ, fp);
- } while
- (buf[0] == '\n');
- if (strcmp(buf, "charset\n"))
- {
- (void) fprintf(stderr, "tabconv: charset keyword missing\n");
- exit(1);
- }
-
- /* insert defaults for printable characters */
- for (ch = CHARMIN; ch < CHARMAX && isprint(ch); ch++)
- {
- buf[0] = 1; /* set default width */
- (void) strcpy(buf + 1, ntnames[ch - CHARMIN]);
- tp->codetab[ch-CHARMIN] = addstring(buf, &tp->pool);
- }
-
- /* now read the character definitions */
- while (digetchr(tp, fp) != EOF)
- continue;
-
- return(tp);
- }
-
- /* ditread.c ends here */
-