|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.