1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
24
25
26 /*
27 * University Copyright- Copyright (c) 1982, 1986, 1988
28 * The Regents of the University of California
29 * All Rights Reserved
30 *
31 * University Acknowledgment- Portions of this document are derived from
32 * software developed by the University of California, Berkeley, and its
33 * contributors.
34 */
35
36 #pragma ident "%Z%%M% %I% %E% SMI"
37 #include <stdio.h>
38
39 #define ungetchar(c) ungetc(c, stdin)
40
41 long ftell();
42 char *calloc();
43 /*
44 * mkstr - create a string error message file by massaging C source
45 *
46 * Modified March 1978 to hash old messages to be able to recompile
47 * without adding messages to the message file (usually)
48 *
49 * Program to create a string error message file
50 * from a group of C programs. Arguments are the name
51 * of the file where the strings are to be placed, the
52 * prefix of the new files where the processed source text
53 * is to be placed, and the files to be processed.
54 *
55 * The program looks for 'error("' in the source stream.
56 * Whenever it finds this, the following characters from the '"'
57 * to a '"' are replaced by 'seekpt' where seekpt is a
58 * pointer into the error message file.
59 * If the '(' is not immediately followed by a '"' no change occurs.
60 *
61 * The optional '-' causes strings to be added at the end of the
62 * existing error message file for recompilation of single routines.
63 */
64
65
66 FILE *mesgread, *mesgwrite;
67 char *progname;
68 char usagestr[] = "usage: %s [ - ] mesgfile prefix file ...\n";
69 char name[100], *np;
70
main(argc,argv)71 main(argc, argv)
72 int argc;
73 char *argv[];
74 {
75 char addon = 0;
76
77 argc--, progname = *argv++;
78 if (argc > 1 && argv[0][0] == '-')
79 addon++, argc--, argv++;
80 if (argc < 3)
81 fprintf(stderr, usagestr, progname), exit(1);
82 mesgwrite = fopen(argv[0], addon ? "a" : "w");
83 if (mesgwrite == NULL)
84 perror(argv[0]), exit(1);
85 mesgread = fopen(argv[0], "r");
86 if (mesgread == NULL)
87 perror(argv[0]), exit(1);
88 inithash();
89 argc--, argv++;
90 strcpy(name, argv[0]);
91 np = name + strlen(name);
92 argc--, argv++;
93 do {
94 strcpy(np, argv[0]);
95 if (freopen(name, "w", stdout) == NULL)
96 perror(name), exit(1);
97 if (freopen(argv[0], "r", stdin) == NULL)
98 perror(argv[0]), exit(1);
99 process();
100 argc--, argv++;
101 } while (argc > 0);
102 exit(0);
103 }
104
process()105 process()
106 {
107 register c;
108
109 for (;;) {
110 c = getchar();
111 if (c == EOF)
112 return;
113 if (c != 'e') {
114 putchar(c);
115 continue;
116 }
117 if (match("error(")) {
118 printf("error(");
119 c = getchar();
120 if (c != '"')
121 putchar(c);
122 else
123 copystr();
124 }
125 }
126 }
127
match(ocp)128 match(ocp)
129 char *ocp;
130 {
131 register char *cp;
132 register c;
133
134 for (cp = ocp + 1; *cp; cp++) {
135 c = getchar();
136 if (c != *cp) {
137 while (ocp < cp)
138 putchar(*ocp++);
139 ungetchar(c);
140 return (0);
141 }
142 }
143 return (1);
144 }
145
copystr()146 copystr()
147 {
148 register c, ch;
149 char buf[512];
150 register char *cp = buf;
151
152 for (;;) {
153 c = getchar();
154 if (c == EOF)
155 break;
156 switch (c) {
157
158 case '"':
159 *cp++ = 0;
160 goto out;
161 case '\\':
162 c = getchar();
163 switch (c) {
164
165 case 'b':
166 c = '\b';
167 break;
168 case 't':
169 c = '\t';
170 break;
171 case 'r':
172 c = '\r';
173 break;
174 case 'n':
175 c = '\n';
176 break;
177 case '\n':
178 continue;
179 case 'f':
180 c = '\f';
181 break;
182 case '0':
183 c = 0;
184 break;
185 case '\\':
186 break;
187 default:
188 if (!octdigit(c))
189 break;
190 c -= '0';
191 ch = getchar();
192 if (!octdigit(ch))
193 break;
194 c <<= 7, c += ch - '0';
195 ch = getchar();
196 if (!octdigit(ch))
197 break;
198 c <<= 3, c+= ch - '0', ch = -1;
199 break;
200 }
201 }
202 *cp++ = c;
203 }
204 out:
205 *cp = 0;
206 printf("%d", hashit(buf, 1, NULL));
207 }
208
octdigit(c)209 octdigit(c)
210 char c;
211 {
212
213 return (c >= '0' && c <= '7');
214 }
215
inithash()216 inithash()
217 {
218 char buf[512];
219 int mesgpt = 0;
220
221 rewind(mesgread);
222 while (fgetNUL(buf, sizeof buf, mesgread) != NULL) {
223 hashit(buf, 0, mesgpt);
224 mesgpt += strlen(buf) + 2;
225 }
226 }
227
228 #define NBUCKETS 511
229
230 struct hash {
231 long hval;
232 unsigned hpt;
233 struct hash *hnext;
234 } *bucket[NBUCKETS];
235
hashit(str,really,fakept)236 hashit(str, really, fakept)
237 char *str;
238 char really;
239 unsigned fakept;
240 {
241 int i;
242 register struct hash *hp;
243 char buf[512];
244 long hashval = 0;
245 register char *cp;
246
247 if (really)
248 fflush(mesgwrite);
249 for (cp = str; *cp;)
250 hashval = (hashval << 1) + *cp++;
251 i = hashval % NBUCKETS;
252 if (i < 0)
253 i += NBUCKETS;
254 if (really != 0)
255 for (hp = bucket[i]; hp != 0; hp = hp->hnext)
256 if (hp->hval == hashval) {
257 fseek(mesgread, (long) hp->hpt, 0);
258 fgetNUL(buf, sizeof buf, mesgread);
259 /*
260 fprintf(stderr, "Got (from %d) %s\n", hp->hpt, buf);
261 */
262 if (strcmp(buf, str) == 0)
263 break;
264 }
265 if (!really || hp == 0) {
266 hp = (struct hash *) calloc(1, sizeof *hp);
267 hp->hnext = bucket[i];
268 hp->hval = hashval;
269 hp->hpt = really ? ftell(mesgwrite) : fakept;
270 if (really) {
271 fwrite(str, sizeof (char), strlen(str) + 1, mesgwrite);
272 fwrite("\n", sizeof (char), 1, mesgwrite);
273 }
274 bucket[i] = hp;
275 }
276 /*
277 fprintf(stderr, "%s hashed to %ld at %d\n", str, hp->hval, hp->hpt);
278 */
279 return (hp->hpt);
280 }
281
282 #include <sys/types.h>
283 #include <sys/stat.h>
284
fgetNUL(obuf,rmdr,file)285 fgetNUL(obuf, rmdr, file)
286 char *obuf;
287 register int rmdr;
288 FILE *file;
289 {
290 register c;
291 register char *buf = obuf;
292
293 while (--rmdr > 0 && (c = getc(file)) != 0 && c != EOF)
294 *buf++ = c;
295 *buf++ = 0;
296 getc(file);
297 return ((feof(file) || ferror(file)) ? NULL : 1);
298 }
299