# 2.11BSD#431 - /usr/src/ucb/xstr.c

##### Functions

    fgetNUL           X
    flushsh           X
    found             X
    hashit            X
    inithash          X
    istail            X
    lastchr           X
    main              X
    octdigit          X
    onintr            X
    process           X
    prstr             X
    savestr           X
    xgetc             X
    xsdotc            X
    yankstr           X

##### Variables

    bucket            X
    cflg              X
    copyright         X
    linebuf           X
    mesgpt            X
    readstd           X
    strings           X
    tellpt            X
    vflg              X

##### Macros

    BUCKETS           X
    ignore            X

##### struct's

    hash              X

       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: }

#### Defined functions

fgetNUL defined in line 256; used 1 times

- in line 249

flushsh defined in line 315; used 1 times

- in line 93

found defined in line 347; used 1 times

- in line 335

hashit defined in line 287; used 3 times

- in line 33, 230, 251

inithash defined in line 240; used 1 times

- in line 79

istail defined in line 434; used 1 times

- in line 298

lastchr defined in line 425; used 1 times

- in line 295

main defined in line 48; never used
octdigit defined in line 233; used 3 times

- in line 211-219(3)

onintr defined in line 444; used 4 times

- in line 35, 77, 170, 396

process defined in line 103; used 1 times

- in line 87

prstr defined in line 362; used 1 times

- in line 358

savestr defined in line 412; used 3 times

- in line 36, 81, 307

xgetc defined in line 270; used 1 times

- in line 264

xsdotc defined in line 378; used 1 times

- in line 95

yankstr defined in line 173; used 2 times

- in line 39, 132

#### Defined variables

bucket defined in line 285; used 3 times

- in line 295, 323, 334

cflg defined in line 44; used 3 times

- in line 65, 78, 94

copyright defined in line 8; never used
linebuf defined in line 101; used 11 times

- in line 113(2), 120-127(6), 195(2), 203

mesgpt defined in line 41; used 3 times

- in line 248, 306-308(2)

readstd defined in line 46; used 6 times

- in line 59, 78-91(5)

sccsid defined in line 14; never used
strings defined in line 42; used 13 times

- in line 81, 96-97(2), 243, 330-332(2), 340-344(2), 380-384(2), 395, 448-449(2)

tellpt defined in line 32; used 2 times

- in line 248, 274

vflg defined in line 45; used 2 times

- in line 69, 352

#### Defined struct's

hash defined in line 280; used 8 times

- in line 283(2), 293(2), 302(2), 318(2)

#### Defined macros

BUCKETS defined in line 278; used 3 times

- in line 285, 322, 333

ignore defined in line 29; used 10 times

- in line 97, 251-253(2), 338, 408-409(2), 447-451(4)

Last modified: 1987-02-17 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1210 |