Annotation of researchv10no/cmd/troff/ancient.nroff/bldtab.c, revision 1.1.1.1

1.1       root        1: /*     bldtab - v 1.26 of 12/5/80
                      2:  *     
                      3:  *     This program translates an input stream of nroff/troff
                      4:  *     name table entries into a hashed table description.  The hash
                      5:  *     function used is defined by tdef.hd, the same definition used
                      6:  *     by the nroff/troff program.
                      7:  */
                      8: 
                      9: #include "tdef.hd"     /* get hashing table definitions */
                     10: #include "stdio.h"
                     11: 
                     12: #ifdef ebcdic
                     13: extern char etoa[], atoe[];
                     14: #endif
                     15: 
                     16: char version[] = "@(#)bldtab   1.26";
                     17: char ntversion[] = NTVER;      /* nroff/troff version */
                     18: 
                     19: 
                     20: 
                     21: #define vallen 15      /* length of value field */
                     22: #define llen 80                /* input line length */
                     23: #define bsize 512      /* buffer size */
                     24: #define CH 0177                /* character mask */
                     25: #define TRUE 1
                     26: #define FALSE 0
                     27: 
                     28: 
                     29: struct table   {
                     30:        int name;       /* name entry */
                     31:        int hval;       /* computed hash value */
                     32:        char val[vallen]; /* value text */
                     33:                } table[NN+NM];
                     34: 
                     35: int htable[NN+NM];     /* hashed table */
                     36: 
                     37: 
                     38: /*     global flags    */
                     39: 
                     40: FILE *filein;          /* input from file flag */
                     41: int stats;             /* output hashing statistics */
                     42: int eof;               /* end of input reached */
                     43: int valf = -1;         /* uninitialized (-1), name (FALSE), or name
                     44:                         *      and value format (TRUE) */
                     45: 
                     46: 
                     47: /*     global variables        */
                     48: 
                     49: char ibuf[bsize], obuf[bsize]; /* input and output buffers */
                     50: int ibp = 0, obp = 0;  /* input and output buffer pointers */
                     51: int ibpend = -1;       /* pointer to end of input buffer */
                     52: int rgc;               /* hold argc */
                     53: char **rgv;            /* hold argv */
                     54: int hits[10], dist[10];        /* statistics counters */
                     55: char lline[llen];      /* input line storage */
                     56: int lpos = 0, hlpos = 0;       /* line position pointers */
                     57: int elpos = -1;                /* pointer to end of line buffer */
                     58: int tsize;             /* size of target table */
                     59: main(argc, argv)
                     60: int argc;
                     61: char **argv;
                     62: {
                     63: 
                     64:        rgc = argc;  rgv = argv;        /* ptrs to command line args */
                     65: 
                     66:        readnames();    /* read all the names */
                     67:        btable();       /* build the hash table */
                     68:        outable();      /* output the table */
                     69:        exit(0);
                     70: 
                     71: }
                     72: 
                     73: 
                     74: btable()       /* build the hash table */
                     75: {      register int i, j, dst;
                     76: 
                     77:        for (i=0; table[i].name; i++)   {       /* compute hash values */
                     78:            if ((j = HASH(table[i].name,tsize)) < 0) j = -j;
                     79:            table[i].hval = j;  }
                     80: 
                     81:        if (stats) stat_pileup();       /* static statistics */
                     82: 
                     83:        for (i=0; table[i].name; i++)   {       /* put into hash table */
                     84:            dst = 0;            /* distance to insert name */
                     85:            for (j=table[i].hval; htable[j]; j=((j+1)%tsize))
                     86:                        dst++;  /* find where to insert */
                     87:            dist[(dst < 10) ? dst : 9]++;       /* mark how far */
                     88:            htable[j] = i + 1 /*bias*/; }
                     89: 
                     90:        if (stats) stat_dist(); /* search distance statistics */
                     91: 
                     92: }
                     93: readnames()
                     94: {      register int i, name;
                     95: 
                     96:        for (i=0; (!eof && i<(NN+NM-1)); i++)   {       /* read all names */
                     97: 
                     98:            if (!eat("PAIR(")) rdferr();
                     99:            name = gquotc();            /* get quoted character */
                    100: 
                    101:            if (!eat(", 0 )")) {        /* second character */
                    102:                if (!eat(",")) rdferr();
                    103:                name = PAIR(name, gquotc());    /* get it */
                    104:                if (!eat(")")) rdferr();        }
                    105: 
                    106:            table[i].name = name & NAMEMASK;    /* save name */
                    107: 
                    108:            if (valf < 0)
                    109:                if (eat(",")) { valf = TRUE;    /* name/value format */
                    110:                                gstr(table[i].val, vallen-1);   } /* first one */
                    111:                        else valf = FALSE;      /* name only format */
                    112:              else if (valf)    {
                    113:                        if (!eat(",")) rdferr();
                    114:                        gstr(table[i].val, vallen-1); } /* get val string */
                    115: 
                    116:            if (!eat("\n")) rdferr();
                    117: 
                    118:            getch();  lpos--;   }       /* force next line or eof */
                    119: }
                    120: eat(ptr)      /* eat input matching string pointed to by ptr */
                    121: char *ptr;
                    122: {
                    123:        skip();                 /* skip leading white space */
                    124:        hlpos = lpos;           /* save line position */
                    125:        while (*ptr)    {
                    126:            if (*ptr == ' ')            /* space in (ptr) -> skip white space */
                    127:                    { skip(); ptr++; }
                    128:                else if (*ptr++ != getch())     {
                    129:                        lpos = hlpos;   /* no match - restore line pointer */
                    130:                        return FALSE;   }}
                    131: 
                    132:        return TRUE;            /* matched */
                    133: }
                    134: 
                    135: 
                    136: skip()         /* skip white space in input */
                    137: {      register int c;
                    138: 
                    139:        do c = getch();
                    140:            while ((c == ' ') || (c == '\t'));
                    141:        lpos--;
                    142: }
                    143: 
                    144: 
                    145: gquotc()
                    146: {      register int c;
                    147: 
                    148:        if (!eat("'")) rdferr();
                    149:        c = getch();
                    150: #ifdef ebcdic
                    151:        c = etoa[c];
                    152: #endif
                    153:        if (!eat("'")) rdferr();
                    154:        return c;
                    155: }
                    156: 
                    157: 
                    158: /* store input until space or comma into (ptr) of length len */
                    159: 
                    160: gstr(ptr, len)
                    161: char *ptr;
                    162: int len;
                    163: {      register int i, ch;
                    164: 
                    165:        skip();         /* skip leading blanks */
                    166:        i = 0;
                    167:        while (((ch = getch()) != '\n') && (ch != ' ') && (i++ < len))
                    168:                        *ptr++ = ch;
                    169:        lpos--;
                    170:        if (i >= len) rdferr();
                    171:        *ptr = 0;
                    172: }
                    173: 
                    174: 
                    175: rdferr()
                    176: {      register int i;
                    177: 
                    178:        lline[elpos] = 0;
                    179:        wwrite(lline);          /* output line */
                    180:        for (i=0; i<lpos; i++)
                    181:            if (lline[i] == '\t') wwrite(2, "\t", 1);
                    182:                else wwrite(" ");
                    183:        wwrite("^ format error\n");
                    184:        exit(1);
                    185: }
                    186: getch()
                    187: {
                    188:        if (lpos > elpos)
                    189:            if (!newline())     {eof = 1; return 0;}
                    190:        return lline[lpos++];
                    191: }
                    192: 
                    193: 
                    194: newline()
                    195: {
                    196:        lpos = elpos = 0;
                    197:        do      {
                    198:                if (ibp > ibpend) getblk();     /* get a new block */
                    199:                if (ibpend < 0) return FALSE;   /* no more input */
                    200:                lline[elpos] = ibuf[ibp++];     }
                    201:            while ((lline[elpos] != '\n') && (++elpos < llen));
                    202:        return TRUE;
                    203: }
                    204: 
                    205: 
                    206: getblk()
                    207: {      int i;
                    208:        ibp = 0;
                    209:        if (!filein && (rgc > 1)) nextf();      /* process option or size */
                    210:        for (i=0; ((i<bsize)&&((ibuf[i]=getc(filein))!=EOF)); i++) ;
                    211:        if ((ibpend=i-1) == 0)
                    212:            if (rgc > 1)        {
                    213:                nextf();                        /* next file */
                    214:                getblk();       }               /* and get a block */
                    215: }
                    216: 
                    217: 
                    218: nextf()
                    219: {      register int i;
                    220: 
                    221:        if (--rgc <= 0) return FALSE;
                    222: 
                    223:        if ((**++rgv == '-') && (rgv[0][1] == 's') && (rgv[0][2] == 0)) {
                    224:                stats++;        /* turn on statistics */
                    225:                return nextf(); } 
                    226: 
                    227:        if (!filein)    {               /* first non-option argument */
                    228:            filein = (FILE *)(tsize = getnum());        /* is the table size */
                    229:            return nextf();     }
                    230: 
                    231:        if ((filein = fopen(*rgv,"r")) == NULL) {
                    232:                wwrite("Can't open ");
                    233:                wwrite(*rgv);
                    234:                wwrite("\n");
                    235:                exit(1);        }
                    236: 
                    237:        return TRUE;
                    238: }
                    239: getnum()
                    240: {      register int ac, i;
                    241: 
                    242:        ac = 0;
                    243:        for (i=0; rgv[0][i]; i++)       {
                    244:            if ((rgv[0][i] < '0') || (rgv[0][i] > '9')) {
                    245:                wwrite("Non-numeric size argument\n");
                    246:                exit(1);        }
                    247:            ac = (ac * 10) + (rgv[0][i] - '0'); }
                    248: 
                    249:        return ac;
                    250: }
                    251: outable()     /* output the hashed name table */
                    252: {      register int i, j, k;
                    253: 
                    254:        for (i=0; i<tsize; i++) {       /* output it */
                    255:            if (!(k = htable[i]))
                    256:                    if (valf) put("\t0,0,\n");
                    257:                        else put("\t0,\n");
                    258:                else    {
                    259:                    k--;
                    260:                    put("\tPAIR('");
                    261:                    putccode(table[k].name & CH);
                    262:                    put("',");
                    263:                    if (j = (table[k].name>>BYTE) & CH) {
                    264:                        putchar('\'');
                    265:                        putccode(j);
                    266:                        put("')");      }
                    267:                      else put("0)");
                    268:                    if (valf)   {
                    269:                        putchar(',');
                    270:                        for (j=0; table[k].val[j]!=0; j++)
                    271:                        putchar(table[k].val[j]);       }
                    272:                    put(", /*");
                    273: #ifndef ebcdic
                    274:                    putchar(table[k].name & CH);
                    275: #else
                    276:                    putchar(atoe[table[k].name & CH]);
                    277: #endif
                    278:                    if (j = (table[k].name>>BYTE) & CH)
                    279: #ifndef ebcdic
                    280:                        putchar(j);
                    281: #else
                    282:                        putchar(atoe[j]);
                    283: #endif
                    284:                    put("*/\n");        }}
                    285: }
                    286: 
                    287: 
                    288: put(ptr)
                    289: char *ptr;
                    290: {
                    291:        do putchar(*ptr++);
                    292:                while (*ptr);
                    293: }
                    294: 
                    295: 
                    296: putccode(ch)
                    297: char ch;
                    298: {
                    299:        putchar('\\');
                    300: #ifndef ebcdic
                    301:        putchar(((ch/0100)&07)+'\060');
                    302:        putchar(((ch/010)&07)+'\060');
                    303:        putchar(((ch)&07)+'\060');
                    304: #else
                    305:        putchar(atoe[((ch/0100)&07)+'\060']);
                    306:        putchar(atoe[((ch/010)&07)+'\060']);
                    307:        putchar(atoe[((ch)&07)+'\060']);
                    308: #endif
                    309: }
                    310: 
                    311: 
                    312: wwrite(str)
                    313: char *str;
                    314: {      char *p;
                    315: 
                    316:        for (p=str; *p; p++)
                    317:                putc(*p, stderr);
                    318: 
                    319: }
                    320: stat_pileup() /* give static statistics */
                    321: {      int i;
                    322:        register int j, cnt;
                    323: 
                    324:        for (i=0; i<tsize; i++) {
                    325:            cnt = 0;
                    326:            for (j=0; table[j].name; j++)
                    327:                if (table[j].hval == i) cnt++;
                    328:            hits[(cnt>9) ? 9 : cnt]++;  }
                    329: 
                    330:        for (i='0'; i<'9'; i++) {
                    331:            wwrite("count of ");
                    332:            putc((char)i, stderr);
                    333:            wwrite(" hits: ");
                    334:            wrnum(hits[i-'0']);
                    335:            wwrite("\n");       }
                    336: 
                    337:        wwrite("9 or more hits: ");
                    338:        wrnum(hits[9]);
                    339:        wwrite("\n");
                    340: }
                    341: 
                    342: 
                    343: stat_dist()    /* hash travel distance statistics */
                    344: {      char i;
                    345: 
                    346:        for (i='0'; i<'9'; i++) {
                    347:            wwrite("count of ");
                    348:            putc(i, stderr);
                    349:            wwrite(" hash travel distances: ");
                    350:            wrnum(dist[i-'0']);
                    351:            wwrite("\n");       }
                    352:        wwrite("search of 9 or more slots: ");
                    353:        wrnum(dist[9]);
                    354:        wwrite("\n");
                    355: }
                    356: wrnum(n)
                    357: int n;
                    358: {      int i;
                    359: 
                    360:        if (n < 0)      {
                    361:            wwrite("-");
                    362:            i = -n;     }
                    363:          else i = n;
                    364:        if (i / 10) wrnum(i / 10);
                    365:        *((char *)&i) = (i % 10) + '0';
                    366:        wwrite(&i);
                    367: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.