Annotation of 42BSD/ucb/xstr.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)xstr.c      4.3 (Berkeley) 6/27/82";
                      2: #include <stdio.h>
                      3: #include <ctype.h>
                      4: #include <sys/types.h>
                      5: #include <signal.h>
                      6: 
                      7: /*
                      8:  * xstr - extract and hash strings in a C program
                      9:  *
                     10:  * Bill Joy UCB
                     11:  * November, 1978
                     12:  */
                     13: 
                     14: #define        ignore(a)       Ignore((char *) a)
                     15: 
                     16: char   *calloc();
                     17: off_t  tellpt;
                     18: off_t  hashit();
                     19: char   *mktemp();
                     20: int    onintr();
                     21: char   *savestr();
                     22: char   *strcat();
                     23: char   *strcpy();
                     24: off_t  yankstr();
                     25: 
                     26: off_t  mesgpt;
                     27: char   *strings =      "strings";
                     28: 
                     29: int    cflg;
                     30: int    vflg;
                     31: int    readstd;
                     32: 
                     33: main(argc, argv)
                     34:        int argc;
                     35:        char *argv[];
                     36: {
                     37: 
                     38:        argc--, argv++;
                     39:        while (argc > 0 && argv[0][0] == '-') {
                     40:                register char *cp = &(*argv++)[1];
                     41: 
                     42:                argc--;
                     43:                if (*cp == 0) {
                     44:                        readstd++;
                     45:                        continue;
                     46:                }
                     47:                do switch (*cp++) {
                     48: 
                     49:                case 'c':
                     50:                        cflg++;
                     51:                        continue;
                     52: 
                     53:                case 'v':
                     54:                        vflg++;
                     55:                        continue;
                     56: 
                     57:                default:
                     58:                        fprintf(stderr, "usage: xstr [ -v ] [ -c ] [ - ] [ name ... ]\n");
                     59:                } while (*cp);
                     60:        }
                     61:        if (signal(SIGINT, SIG_IGN) == SIG_DFL)
                     62:                signal(SIGINT, onintr);
                     63:        if (cflg || argc == 0 && !readstd)
                     64:                inithash();
                     65:        else
                     66:                strings = mktemp(savestr("/tmp/xstrXXXXXX"));
                     67:        while (readstd || argc > 0) {
                     68:                if (freopen("x.c", "w", stdout) == NULL)
                     69:                        perror("x.c"), exit(1);
                     70:                if (!readstd && freopen(argv[0], "r", stdin) == NULL)
                     71:                        perror(argv[0]), exit(2);
                     72:                process("x.c");
                     73:                if (readstd == 0)
                     74:                        argc--, argv++;
                     75:                else
                     76:                        readstd = 0;
                     77:        };
                     78:        flushsh();
                     79:        if (cflg == 0)
                     80:                xsdotc();
                     81:        if (strings[0] == '/')
                     82:                ignore(unlink(strings));
                     83:        exit(0);
                     84: }
                     85: 
                     86: process(name)
                     87:        char *name;
                     88: {
                     89:        char *cp;
                     90:        char linebuf[BUFSIZ];
                     91:        register int c;
                     92:        register int incomm = 0;
                     93: 
                     94:        printf("char\txstr[];\n");
                     95:        for (;;) {
                     96:                if (fgets(linebuf, sizeof linebuf, stdin) == NULL) {
                     97:                        if (ferror(stdin)) {
                     98:                                perror(name);
                     99:                                exit(3);
                    100:                        }
                    101:                        break;
                    102:                }
                    103:                if (linebuf[0] == '#') {
                    104:                        if (linebuf[1] == ' ' && isdigit(linebuf[2]))
                    105:                                printf("#line%s", &linebuf[1]);
                    106:                        else
                    107:                                printf("%s", linebuf);
                    108:                        continue;
                    109:                }
                    110:                for (cp = linebuf; c = *cp++;) switch (c) {
                    111:                        
                    112:                case '"':
                    113:                        if (incomm)
                    114:                                goto def;
                    115:                        printf("(&xstr[%d])", (int) yankstr(&cp));
                    116:                        break;
                    117: 
                    118:                case '\'':
                    119:                        if (incomm)
                    120:                                goto def;
                    121:                        putchar(c);
                    122:                        if (*cp)
                    123:                                putchar(*cp++);
                    124:                        break;
                    125: 
                    126:                case '/':
                    127:                        if (incomm || *cp != '*')
                    128:                                goto def;
                    129:                        incomm = 1;
                    130:                        cp++;
                    131:                        printf("/*");
                    132:                        continue;
                    133: 
                    134:                case '*':
                    135:                        if (incomm && *cp == '/') {
                    136:                                incomm = 0;
                    137:                                cp++;
                    138:                                printf("*/");
                    139:                                continue;
                    140:                        }
                    141:                        goto def;
                    142:                
                    143: def:
                    144:                default:
                    145:                        putchar(c);
                    146:                        break;
                    147:                }
                    148:        }
                    149:        if (ferror(stdout))
                    150:                perror("x.c"), onintr();
                    151: }
                    152: 
                    153: off_t
                    154: yankstr(cpp)
                    155:        register char **cpp;
                    156: {
                    157:        register char *cp = *cpp;
                    158:        register int c, ch;
                    159:        char dbuf[BUFSIZ];
                    160:        register char *dp = dbuf;
                    161:        register char *tp;
                    162: 
                    163:        while (c = *cp++) {
                    164:                switch (c) {
                    165: 
                    166:                case '"':
                    167:                        cp++;
                    168:                        goto out;
                    169: 
                    170:                case '\\':
                    171:                        c = *cp++;
                    172:                        if (c == 0)
                    173:                                break;
                    174:                        if (c == '\n')
                    175:                                continue;
                    176:                        for (tp = "b\bt\tr\rn\nf\f\\\\\"\""; ch = *tp++; tp++)
                    177:                                if (c == ch) {
                    178:                                        c = *tp;
                    179:                                        goto gotc;
                    180:                                }
                    181:                        if (!octdigit(c)) {
                    182:                                *dp++ = '\\';
                    183:                                break;
                    184:                        }
                    185:                        c -= '0';
                    186:                        if (!octdigit(*cp))
                    187:                                break;
                    188:                        c <<= 3, c += *cp++ - '0';
                    189:                        if (!octdigit(*cp))
                    190:                                break;
                    191:                        c <<= 3, c += *cp++ - '0';
                    192:                        break;
                    193:                }
                    194: gotc:
                    195:                *dp++ = c;
                    196:        }
                    197: out:
                    198:        *cpp = --cp;
                    199:        *dp = 0;
                    200:        return (hashit(dbuf, 1));
                    201: }
                    202: 
                    203: octdigit(c)
                    204:        char c;
                    205: {
                    206: 
                    207:        return (isdigit(c) && c != '8' && c != '9');
                    208: }
                    209: 
                    210: inithash()
                    211: {
                    212:        char buf[BUFSIZ];
                    213:        register FILE *mesgread = fopen(strings, "r");
                    214: 
                    215:        if (mesgread == NULL)
                    216:                return;
                    217:        for (;;) {
                    218:                mesgpt = tellpt;
                    219:                if (fgetNUL(buf, sizeof buf, mesgread) == NULL)
                    220:                        break;
                    221:                ignore(hashit(buf, 0));
                    222:        }
                    223:        ignore(fclose(mesgread));
                    224: }
                    225: 
                    226: fgetNUL(obuf, rmdr, file)
                    227:        char *obuf;
                    228:        register int rmdr;
                    229:        FILE *file;
                    230: {
                    231:        register c;
                    232:        register char *buf = obuf;
                    233: 
                    234:        while (--rmdr > 0 && (c = xgetc(file)) != 0 && c != EOF)
                    235:                *buf++ = c;
                    236:        *buf++ = 0;
                    237:        return ((feof(file) || ferror(file)) ? NULL : 1);
                    238: }
                    239: 
                    240: xgetc(file)
                    241:        FILE *file;
                    242: {
                    243: 
                    244:        tellpt++;
                    245:        return (getc(file));
                    246: }
                    247: 
                    248: #define        BUCKETS 128
                    249: 
                    250: struct hash {
                    251:        off_t   hpt;
                    252:        char    *hstr;
                    253:        struct  hash *hnext;
                    254:        short   hnew;
                    255: } bucket[BUCKETS];
                    256: 
                    257: off_t
                    258: hashit(str, new)
                    259:        char *str;
                    260:        int new;
                    261: {
                    262:        int i;
                    263:        register struct hash *hp, *hp0;
                    264: 
                    265:        hp = hp0 = &bucket[lastchr(str) & 0177];
                    266:        while (hp->hnext) {
                    267:                hp = hp->hnext;
                    268:                i = istail(str, hp->hstr);
                    269:                if (i >= 0)
                    270:                        return (hp->hpt + i);
                    271:        }
                    272:        hp = (struct hash *) calloc(1, sizeof (*hp));
                    273:        hp->hpt = mesgpt;
                    274:        hp->hstr = savestr(str);
                    275:        mesgpt += strlen(hp->hstr) + 1;
                    276:        hp->hnext = hp0->hnext;
                    277:        hp->hnew = new;
                    278:        hp0->hnext = hp;
                    279:        return (hp->hpt);
                    280: }
                    281: 
                    282: flushsh()
                    283: {
                    284:        register int i;
                    285:        register struct hash *hp;
                    286:        register FILE *mesgwrit;
                    287:        register int old = 0, new = 0;
                    288: 
                    289:        for (i = 0; i < BUCKETS; i++)
                    290:                for (hp = bucket[i].hnext; hp != NULL; hp = hp->hnext)
                    291:                        if (hp->hnew)
                    292:                                new++;
                    293:                        else
                    294:                                old++;
                    295:        if (new == 0 && old != 0)
                    296:                return;
                    297:        mesgwrit = fopen(strings, old ? "r+" : "w");
                    298:        if (mesgwrit == NULL)
                    299:                perror(strings), exit(4);
                    300:        for (i = 0; i < BUCKETS; i++)
                    301:                for (hp = bucket[i].hnext; hp != NULL; hp = hp->hnext) {
                    302:                        found(hp->hnew, hp->hpt, hp->hstr);
                    303:                        if (hp->hnew) {
                    304:                                fseek(mesgwrit, hp->hpt, 0);
                    305:                                ignore(fwrite(hp->hstr, strlen(hp->hstr) + 1, 1, mesgwrit));
                    306:                                if (ferror(mesgwrit))
                    307:                                        perror(strings), exit(4);
                    308:                        }
                    309:                }
                    310:        ignore(fclose(mesgwrit));
                    311: }
                    312: 
                    313: found(new, off, str)
                    314:        int new;
                    315:        off_t off;
                    316:        char *str;
                    317: {
                    318:        register char *cp;
                    319: 
                    320:        if (vflg == 0)
                    321:                return;
                    322:        if (!new)
                    323:                fprintf(stderr, "found at %d:", (int) off);
                    324:        else
                    325:                fprintf(stderr, "new at %d:", (int) off);
                    326:        prstr(str);
                    327:        fprintf(stderr, "\n");
                    328: }
                    329: 
                    330: prstr(cp)
                    331:        register char *cp;
                    332: {
                    333:        register int c;
                    334: 
                    335:        while (c = (*cp++ & 0377))
                    336:                if (c < ' ')
                    337:                        fprintf(stderr, "^%c", c + '`');
                    338:                else if (c == 0177)
                    339:                        fprintf(stderr, "^?");
                    340:                else if (c > 0200)
                    341:                        fprintf(stderr, "\\%03o", c);
                    342:                else
                    343:                        fprintf(stderr, "%c", c);
                    344: }
                    345: 
                    346: xsdotc()
                    347: {
                    348:        register FILE *strf = fopen(strings, "r");
                    349:        register FILE *xdotcf;
                    350: 
                    351:        if (strf == NULL)
                    352:                perror(strings), exit(5);
                    353:        xdotcf = fopen("xs.c", "w");
                    354:        if (xdotcf == NULL)
                    355:                perror("xs.c"), exit(6);
                    356:        fprintf(xdotcf, "char\txstr[] = {\n");
                    357:        for (;;) {
                    358:                register int i, c;
                    359: 
                    360:                for (i = 0; i < 8; i++) {
                    361:                        c = getc(strf);
                    362:                        if (ferror(strf)) {
                    363:                                perror(strings);
                    364:                                onintr();
                    365:                        }
                    366:                        if (feof(strf)) {
                    367:                                fprintf(xdotcf, "\n");
                    368:                                goto out;
                    369:                        }
                    370:                        fprintf(xdotcf, "0x%02x,", c);
                    371:                }
                    372:                fprintf(xdotcf, "\n");
                    373:        }
                    374: out:
                    375:        fprintf(xdotcf, "};\n");
                    376:        ignore(fclose(xdotcf));
                    377:        ignore(fclose(strf));
                    378: }
                    379: 
                    380: char *
                    381: savestr(cp)
                    382:        register char *cp;
                    383: {
                    384:        register char *dp = (char *) calloc(1, strlen(cp) + 1);
                    385: 
                    386:        return (strcpy(dp, cp));
                    387: }
                    388: 
                    389: Ignore(a)
                    390:        char *a;
                    391: {
                    392: 
                    393:        a = a;
                    394: }
                    395: 
                    396: ignorf(a)
                    397:        int (*a)();
                    398: {
                    399: 
                    400:        a = a;
                    401: }
                    402: 
                    403: lastchr(cp)
                    404:        register char *cp;
                    405: {
                    406: 
                    407:        while (cp[0] && cp[1])
                    408:                cp++;
                    409:        return (*cp);
                    410: }
                    411: 
                    412: istail(str, of)
                    413:        register char *str, *of;
                    414: {
                    415:        register int d = strlen(of) - strlen(str);
                    416: 
                    417:        if (d < 0 || strcmp(&of[d], str) != 0)
                    418:                return (-1);
                    419:        return (d);
                    420: }
                    421: 
                    422: onintr()
                    423: {
                    424: 
                    425:        ignorf(signal(SIGINT, SIG_IGN));
                    426:        if (strings[0] == '/')
                    427:                ignore(unlink(strings));
                    428:        ignore(unlink("x.c"));
                    429:        ignore(unlink("xs.c"));
                    430:        exit(7);
                    431: }

unix.superglobalmegacorp.com

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