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