|
|
1.1 ! root 1: static char *sccsid = "@(#)xstr.c 4.1 (Berkeley) 10/1/80"; ! 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 ? "a" : "w"); ! 298: for (i = 0; i < BUCKETS; i++) ! 299: for (hp = bucket[i].hnext; hp != NULL; hp = hp->hnext) { ! 300: found(hp->hnew, hp->hpt, hp->hstr); ! 301: if (hp->hnew) { ! 302: fseek(mesgwrit, hp->hpt, 0); ! 303: ignore(fwrite(hp->hstr, strlen(hp->hstr) + 1, 1, mesgwrit)); ! 304: if (ferror(mesgwrit)) ! 305: perror(strings), exit(4); ! 306: } ! 307: } ! 308: ignore(fclose(mesgwrit)); ! 309: } ! 310: ! 311: found(new, off, str) ! 312: int new; ! 313: off_t off; ! 314: char *str; ! 315: { ! 316: register char *cp; ! 317: ! 318: if (vflg == 0) ! 319: return; ! 320: if (!new) ! 321: fprintf(stderr, "found at %d:", (int) off); ! 322: else ! 323: fprintf(stderr, "new at %d:", (int) off); ! 324: prstr(str); ! 325: fprintf(stderr, "\n"); ! 326: } ! 327: ! 328: prstr(cp) ! 329: register char *cp; ! 330: { ! 331: register int c; ! 332: ! 333: while (c = (*cp++ & 0377)) ! 334: if (c < ' ') ! 335: fprintf(stderr, "^%c", c + '`'); ! 336: else if (c == 0177) ! 337: fprintf(stderr, "^?"); ! 338: else if (c > 0200) ! 339: fprintf(stderr, "\\%03o", c); ! 340: else ! 341: fprintf(stderr, "%c", c); ! 342: } ! 343: ! 344: xsdotc() ! 345: { ! 346: register FILE *strf = fopen(strings, "r"); ! 347: register FILE *xdotcf; ! 348: ! 349: if (strf == NULL) ! 350: perror(strings), exit(5); ! 351: xdotcf = fopen("xs.c", "w"); ! 352: if (xdotcf == NULL) ! 353: perror("xs.c"), exit(6); ! 354: fprintf(xdotcf, "char\txstr[] = {\n"); ! 355: for (;;) { ! 356: register int i, c; ! 357: ! 358: for (i = 0; i < 8; i++) { ! 359: c = getc(strf); ! 360: if (ferror(strf)) { ! 361: perror(strings); ! 362: onintr(); ! 363: } ! 364: if (feof(strf)) { ! 365: fprintf(xdotcf, "\n"); ! 366: goto out; ! 367: } ! 368: fprintf(xdotcf, "0x%02x,", c); ! 369: } ! 370: fprintf(xdotcf, "\n"); ! 371: } ! 372: out: ! 373: fprintf(xdotcf, "};\n"); ! 374: ignore(fclose(xdotcf)); ! 375: ignore(fclose(strf)); ! 376: } ! 377: ! 378: char * ! 379: savestr(cp) ! 380: register char *cp; ! 381: { ! 382: register char *dp = (char *) calloc(1, strlen(cp) + 1); ! 383: ! 384: return (strcpy(dp, cp)); ! 385: } ! 386: ! 387: Ignore(a) ! 388: char *a; ! 389: { ! 390: ! 391: a = a; ! 392: } ! 393: ! 394: ignorf(a) ! 395: int (*a)(); ! 396: { ! 397: ! 398: a = a; ! 399: } ! 400: ! 401: lastchr(cp) ! 402: register char *cp; ! 403: { ! 404: ! 405: while (cp[0] && cp[1]) ! 406: cp++; ! 407: return (*cp); ! 408: } ! 409: ! 410: istail(str, of) ! 411: register char *str, *of; ! 412: { ! 413: register int d = strlen(of) - strlen(str); ! 414: ! 415: if (d < 0 || strcmp(&of[d], str) != 0) ! 416: return (-1); ! 417: return (d); ! 418: } ! 419: ! 420: onintr() ! 421: { ! 422: ! 423: ignorf(signal(SIGINT, SIG_IGN)); ! 424: if (strings[0] == '/') ! 425: ignore(unlink(strings)); ! 426: ignore(unlink("x.c")); ! 427: ignore(unlink("xs.c")); ! 428: exit(7); ! 429: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.