|
|
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: (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 Regents of the University of California.\n\
23: All rights reserved.\n";
24: #endif /* not lint */
25:
26: #ifndef lint
27: static char sccsid[] = "@(#)mkstr.c 5.4 (Berkeley) 6/1/90";
28: #endif /* not lint */
29:
30: #include <stdio.h>
31:
32: #define ungetchar(c) ungetc(c, stdin)
33:
34: long ftell();
35: char *calloc();
36: /*
37: * mkstr - create a string error message file by massaging C source
38: *
39: * Bill Joy UCB August 1977
40: *
41: * Modified March 1978 to hash old messages to be able to recompile
42: * without addding messages to the message file (usually)
43: *
44: * Based on an earlier program conceived by Bill Joy and Chuck Haley
45: *
46: * Program to create a string error message file
47: * from a group of C programs. Arguments are the name
48: * of the file where the strings are to be placed, the
49: * prefix of the new files where the processed source text
50: * is to be placed, and the files to be processed.
51: *
52: * The program looks for 'error("' in the source stream.
53: * Whenever it finds this, the following characters from the '"'
54: * to a '"' are replaced by 'seekpt' where seekpt is a
55: * pointer into the error message file.
56: * If the '(' is not immediately followed by a '"' no change occurs.
57: *
58: * The optional '-' causes strings to be added at the end of the
59: * existing error message file for recompilation of single routines.
60: */
61:
62:
63: FILE *mesgread, *mesgwrite;
64: char *progname;
65: char usagestr[] = "usage: %s [ - ] mesgfile prefix file ...\n";
66: char name[100], *np;
67:
68: main(argc, argv)
69: int argc;
70: char *argv[];
71: {
72: char addon = 0;
73:
74: argc--, progname = *argv++;
75: if (argc > 1 && argv[0][0] == '-')
76: addon++, argc--, argv++;
77: if (argc < 3)
78: fprintf(stderr, usagestr, progname), exit(1);
79: mesgwrite = fopen(argv[0], addon ? "a" : "w");
80: if (mesgwrite == NULL)
81: perror(argv[0]), exit(1);
82: mesgread = fopen(argv[0], "r");
83: if (mesgread == NULL)
84: perror(argv[0]), exit(1);
85: inithash();
86: argc--, argv++;
87: strcpy(name, argv[0]);
88: np = name + strlen(name);
89: argc--, argv++;
90: do {
91: strcpy(np, argv[0]);
92: if (freopen(name, "w", stdout) == NULL)
93: perror(name), exit(1);
94: if (freopen(argv[0], "r", stdin) == NULL)
95: perror(argv[0]), exit(1);
96: process();
97: argc--, argv++;
98: } while (argc > 0);
99: exit(0);
100: }
101:
102: process()
103: {
104: register char *cp;
105: register c;
106:
107: for (;;) {
108: c = getchar();
109: if (c == EOF)
110: return;
111: if (c != 'e') {
112: putchar(c);
113: continue;
114: }
115: if (match("error(")) {
116: printf("error(");
117: c = getchar();
118: if (c != '"')
119: putchar(c);
120: else
121: copystr();
122: }
123: }
124: }
125:
126: match(ocp)
127: char *ocp;
128: {
129: register char *cp;
130: register c;
131:
132: for (cp = ocp + 1; *cp; cp++) {
133: c = getchar();
134: if (c != *cp) {
135: while (ocp < cp)
136: putchar(*ocp++);
137: ungetchar(c);
138: return (0);
139: }
140: }
141: return (1);
142: }
143:
144: copystr()
145: {
146: register c, ch;
147: char buf[512];
148: register char *cp = buf;
149:
150: for (;;) {
151: c = getchar();
152: if (c == EOF)
153: break;
154: switch (c) {
155:
156: case '"':
157: *cp++ = 0;
158: goto out;
159: case '\\':
160: c = getchar();
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 '0':
181: c = 0;
182: break;
183: case '\\':
184: break;
185: default:
186: if (!octdigit(c))
187: break;
188: c -= '0';
189: ch = getchar();
190: if (!octdigit(ch))
191: break;
192: c <<= 7, c += ch - '0';
193: ch = getchar();
194: if (!octdigit(ch))
195: break;
196: c <<= 3, c+= ch - '0', ch = -1;
197: break;
198: }
199: }
200: *cp++ = c;
201: }
202: out:
203: *cp = 0;
204: printf("%d", hashit(buf, 1, NULL));
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 hashval = 0;
243: register char *cp;
244:
245: if (really)
246: fflush(mesgwrite);
247: for (cp = str; *cp;)
248: hashval = (hashval << 1) + *cp++;
249: i = hashval % 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 == hashval) {
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 = hashval;
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.