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