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