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

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

unix.superglobalmegacorp.com

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