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