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