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: /* 8: * Somewhat modified to key on strstr(" instead of error(", for use 9: * as a general purpose string stripper. Also replaces pointer with 10: * a (long) pointer. 11: */ 12: 13: #ifndef lint 14: char copyright[] = 15: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 16: All rights reserved.\n"; 17: #endif not lint 18: 19: #ifndef lint 20: static char sccsid[] = "@(#)mkstr.c 5.1 (Berkeley) 5/31/85"; 21: #endif not lint 22: 23: #include <stdio.h> 24: 25: #define ungetchar(c) ungetc(c, stdin) 26: 27: long ftell(); 28: char *calloc(); 29: /* 30: * mkstr - create a string error message file by massaging C source 31: * 32: * Bill Joy UCB August 1977 33: * 34: * Modified March 1978 to hash old messages to be able to recompile 35: * without addding messages to the message file (usually) 36: * 37: * Based on an earlier program conceived by Bill Joy and Chuck Haley 38: * 39: * Program to create a string error message file 40: * from a group of C programs. Arguments are the name 41: * of the file where the strings are to be placed, the 42: * prefix of the new files where the processed source text 43: * is to be placed, and the files to be processed. 44: * 45: * The program looks for 'strstr("' in the source stream. 46: * Whenever it finds this, the following characters from the '"' 47: * to a '"' are replaced by 'seekpt' where seekpt is a 48: * pointer into the error message file. 49: * If the '(' is not immediately followed by a '"' no change occurs. 50: * 51: * The optional '-' causes strings to be added at the end of the 52: * existing error message file for recompilation of single routines. 53: */ 54: 55: 56: FILE *mesgread, *mesgwrite; 57: char *progname; 58: char usagestr[] = "usage: %s [ - ] mesgfile prefix file ...\n"; 59: char name[100], *np; 60: 61: main(argc, argv) 62: int argc; 63: char *argv[]; 64: { 65: char addon = 0; 66: 67: argc--, progname = *argv++; 68: if (argc > 1 && argv[0][0] == '-') 69: addon++, argc--, argv++; 70: if (argc < 3) 71: fprintf(stderr, usagestr, progname), exit(1); 72: mesgwrite = fopen(argv[0], addon ? "a" : "w"); 73: if (mesgwrite == NULL) 74: perror(argv[0]), exit(1); 75: mesgread = fopen(argv[0], "r"); 76: if (mesgread == NULL) 77: perror(argv[0]), exit(1); 78: inithash(); 79: argc--, argv++; 80: strcpy(name, argv[0]); 81: np = name + strlen(name); 82: argc--, argv++; 83: do { 84: strcpy(np, argv[0]); 85: if (freopen(name, "w", stdout) == NULL) 86: perror(name), exit(1); 87: if (freopen(argv[0], "r", stdin) == NULL) 88: perror(argv[0]), exit(1); 89: process(); 90: argc--, argv++; 91: } while (argc > 0); 92: exit(0); 93: } 94: 95: process() 96: { 97: register char *cp; 98: register c; 99: 100: for (;;) { 101: c = getchar(); 102: if (c == EOF) 103: return; 104: if (c != 's') { 105: putchar(c); 106: continue; 107: } 108: if (match("strstr(")) { 109: printf("strstr("); 110: c = getchar(); 111: if (c != '"') 112: putchar(c); 113: else 114: copystr(); 115: } 116: } 117: } 118: 119: match(ocp) 120: char *ocp; 121: { 122: register char *cp; 123: register c; 124: 125: for (cp = ocp + 1; *cp; cp++) { 126: c = getchar(); 127: if (c != *cp) { 128: while (ocp < cp) 129: putchar(*ocp++); 130: ungetchar(c); 131: return (0); 132: } 133: } 134: return (1); 135: } 136: 137: copystr() 138: { 139: register c, ch; 140: char buf[512]; 141: register char *cp = buf; 142: long hashit(); 143: 144: for (;;) { 145: c = getchar(); 146: if (c == EOF) 147: break; 148: switch (c) { 149: 150: case '"': 151: *cp++ = 0; 152: goto out; 153: case '\\': 154: c = getchar(); 155: switch (c) { 156: 157: case 'b': 158: c = '\b'; 159: break; 160: case 't': 161: c = '\t'; 162: break; 163: case 'r': 164: c = '\r'; 165: break; 166: case 'n': 167: c = '\n'; 168: break; 169: case '\n': 170: continue; 171: case 'f': 172: c = '\f'; 173: break; 174: case '0': 175: c = 0; 176: break; 177: case '\\': 178: break; 179: default: 180: if (!octdigit(c)) 181: break; 182: c -= '0'; 183: ch = getchar(); 184: if (!octdigit(ch)) 185: break; 186: c <<= 7, c += ch - '0'; 187: ch = getchar(); 188: if (!octdigit(ch)) 189: break; 190: c <<= 3, c+= ch - '0', ch = -1; 191: break; 192: } 193: } 194: *cp++ = c; 195: } 196: out: 197: *cp = 0; 198: printf("%ld", hashit(buf, 1, NULL)); 199: } 200: 201: octdigit(c) 202: char c; 203: { 204: 205: return (c >= '0' && c <= '7'); 206: } 207: 208: inithash() 209: { 210: char buf[512]; 211: int mesgpt = 0; 212: 213: rewind(mesgread); 214: while (fgetNUL(buf, sizeof buf, mesgread) != NULL) { 215: hashit(buf, 0, mesgpt); 216: mesgpt += strlen(buf) + 2; 217: } 218: } 219: 220: #define NBUCKETS 511 221: 222: struct hash { 223: long hval; 224: long hpt; 225: struct hash *hnext; 226: } *bucket[NBUCKETS]; 227: 228: long 229: hashit(str, really, fakept) 230: char *str; 231: char really; 232: unsigned fakept; 233: { 234: int i; 235: register struct hash *hp; 236: char buf[512]; 237: long hashval = 0; 238: register char *cp; 239: 240: if (really) 241: fflush(mesgwrite); 242: for (cp = str; *cp;) 243: hashval = (hashval << 1) + *cp++; 244: i = hashval % NBUCKETS; 245: if (i < 0) 246: i += NBUCKETS; 247: if (really != 0) 248: for (hp = bucket[i]; hp != 0; hp = hp->hnext) 249: if (hp->hval == hashval) { 250: fseek(mesgread, (long) hp->hpt, 0); 251: fgetNUL(buf, sizeof buf, mesgread); 252: #ifdef DEBUG 253: fprintf(stderr, "Got (from %ld) %s\n", hp->hpt, buf); 254: #endif 255: if (strcmp(buf, str) == 0) 256: break; 257: } 258: if (!really || hp == 0) { 259: hp = (struct hash *) calloc(1, sizeof *hp); 260: hp->hnext = bucket[i]; 261: hp->hval = hashval; 262: hp->hpt = really ? ftell(mesgwrite) : fakept; 263: if (really) { 264: fwrite(str, sizeof (char), strlen(str) + 1, mesgwrite); 265: fwrite("\n", sizeof (char), 1, mesgwrite); 266: } 267: bucket[i] = hp; 268: } 269: #ifdef DEBUG 270: fprintf(stderr, "%s hashed to %ld at %ld\n", str, hp->hval, hp->hpt); 271: #endif 272: return (hp->hpt); 273: } 274: 275: #include <sys/types.h> 276: #include <sys/stat.h> 277: 278: fgetNUL(obuf, rmdr, file) 279: char *obuf; 280: register int rmdr; 281: FILE *file; 282: { 283: register c; 284: register char *buf = obuf; 285: 286: while (--rmdr > 0 && (c = getc(file)) != 0 && c != EOF) 287: *buf++ = c; 288: *buf++ = 0; 289: getc(file); 290: return ((feof(file) || ferror(file)) ? NULL : 1); 291: }