makedefs.c revision 1.8 1 1.8 jsm /* $NetBSD: makedefs.c,v 1.8 2003/04/02 18:36:42 jsm Exp $ */
2 1.5 christos
3 1.2 mycroft /*
4 1.8 jsm * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5 1.8 jsm * Amsterdam
6 1.8 jsm * All rights reserved.
7 1.8 jsm *
8 1.8 jsm * Redistribution and use in source and binary forms, with or without
9 1.8 jsm * modification, are permitted provided that the following conditions are
10 1.8 jsm * met:
11 1.8 jsm *
12 1.8 jsm * - Redistributions of source code must retain the above copyright notice,
13 1.8 jsm * this list of conditions and the following disclaimer.
14 1.8 jsm *
15 1.8 jsm * - Redistributions in binary form must reproduce the above copyright
16 1.8 jsm * notice, this list of conditions and the following disclaimer in the
17 1.8 jsm * documentation and/or other materials provided with the distribution.
18 1.8 jsm *
19 1.8 jsm * - Neither the name of the Stichting Centrum voor Wiskunde en
20 1.8 jsm * Informatica, nor the names of its contributors may be used to endorse or
21 1.8 jsm * promote products derived from this software without specific prior
22 1.8 jsm * written permission.
23 1.8 jsm *
24 1.8 jsm * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25 1.8 jsm * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26 1.8 jsm * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27 1.8 jsm * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28 1.8 jsm * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 1.8 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 1.8 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 1.8 jsm * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 1.8 jsm * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 1.8 jsm * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 1.8 jsm * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 1.8 jsm */
36 1.8 jsm
37 1.8 jsm /*
38 1.8 jsm * Copyright (c) 1982 Jay Fenlason <hack (at) gnu.org>
39 1.8 jsm * All rights reserved.
40 1.8 jsm *
41 1.8 jsm * Redistribution and use in source and binary forms, with or without
42 1.8 jsm * modification, are permitted provided that the following conditions
43 1.8 jsm * are met:
44 1.8 jsm * 1. Redistributions of source code must retain the above copyright
45 1.8 jsm * notice, this list of conditions and the following disclaimer.
46 1.8 jsm * 2. Redistributions in binary form must reproduce the above copyright
47 1.8 jsm * notice, this list of conditions and the following disclaimer in the
48 1.8 jsm * documentation and/or other materials provided with the distribution.
49 1.8 jsm * 3. The name of the author may not be used to endorse or promote products
50 1.8 jsm * derived from this software without specific prior written permission.
51 1.8 jsm *
52 1.8 jsm * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53 1.8 jsm * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54 1.8 jsm * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
55 1.8 jsm * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56 1.8 jsm * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57 1.8 jsm * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58 1.8 jsm * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59 1.8 jsm * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60 1.8 jsm * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61 1.8 jsm * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 1.2 mycroft */
63 1.2 mycroft
64 1.2 mycroft #ifndef lint
65 1.7 jsm static const char rcsid[] =
66 1.8 jsm "$NetBSD: makedefs.c,v 1.8 2003/04/02 18:36:42 jsm Exp $";
67 1.5 christos #endif /* not lint */
68 1.1 cgd
69 1.1 cgd #include <stdio.h>
70 1.7 jsm #include <stdlib.h>
71 1.4 cgd #include <string.h>
72 1.5 christos #include <fcntl.h>
73 1.5 christos #include <unistd.h>
74 1.1 cgd
75 1.1 cgd /* construct definitions of object constants */
76 1.1 cgd #define LINSZ 1000
77 1.1 cgd #define STRSZ 40
78 1.1 cgd
79 1.5 christos int fd;
80 1.5 christos char string[STRSZ];
81 1.5 christos
82 1.6 simonb static void readline(void);
83 1.6 simonb static char nextchar(void);
84 1.7 jsm static int skipuntil(const char *);
85 1.6 simonb static int getentry(void);
86 1.6 simonb static void capitalize(char *);
87 1.6 simonb static int letter(int);
88 1.6 simonb static int digit(int);
89 1.5 christos
90 1.6 simonb int main(int, char **);
91 1.1 cgd
92 1.5 christos int
93 1.1 cgd main(argc, argv)
94 1.5 christos int argc;
95 1.5 christos char **argv;
96 1.1 cgd {
97 1.5 christos int i = 0;
98 1.5 christos int propct = 0;
99 1.5 christos char *sp;
100 1.1 cgd if (argc != 2) {
101 1.5 christos (void) fprintf(stderr, "usage: makedefs file\n");
102 1.1 cgd exit(1);
103 1.1 cgd }
104 1.7 jsm if ((fd = open(argv[1], O_RDONLY)) < 0) {
105 1.1 cgd perror(argv[1]);
106 1.1 cgd exit(1);
107 1.1 cgd }
108 1.1 cgd skipuntil("objects[] = {");
109 1.5 christos while (getentry()) {
110 1.5 christos if (!*string) {
111 1.5 christos i++;
112 1.1 cgd continue;
113 1.1 cgd }
114 1.5 christos for (sp = string; *sp; sp++)
115 1.5 christos if (*sp == ' ' || *sp == '\t' || *sp == '-')
116 1.1 cgd *sp = '_';
117 1.5 christos if (!strncmp(string, "RIN_", 4)) {
118 1.5 christos capitalize(string + 4);
119 1.1 cgd printf("#define %s u.uprops[%d].p_flgs\n",
120 1.5 christos string + 4, propct++);
121 1.1 cgd }
122 1.5 christos for (sp = string; *sp; sp++)
123 1.5 christos capitalize(sp);
124 1.1 cgd /* avoid trouble with stupid C preprocessors */
125 1.5 christos if (!strncmp(string, "WORTHLESS_PIECE_OF_", 19))
126 1.5 christos printf("/* #define %s %d */\n", string, i);
127 1.1 cgd else
128 1.5 christos printf("#define %s %d\n", string, i);
129 1.5 christos i++;
130 1.1 cgd }
131 1.1 cgd printf("\n#define CORPSE DEAD_HUMAN\n");
132 1.1 cgd printf("#define LAST_GEM (JADE+1)\n");
133 1.1 cgd printf("#define LAST_RING %d\n", propct);
134 1.5 christos printf("#define NROFOBJECTS %d\n", i - 1);
135 1.7 jsm fflush(stdout);
136 1.7 jsm if (ferror(stdout)) {
137 1.7 jsm perror("standard output");
138 1.7 jsm exit(1);
139 1.7 jsm }
140 1.1 cgd exit(0);
141 1.1 cgd }
142 1.1 cgd
143 1.5 christos char line[LINSZ], *lp = line, *lp0 = line, *lpe = line;
144 1.5 christos int eof;
145 1.1 cgd
146 1.5 christos static void
147 1.5 christos readline()
148 1.5 christos {
149 1.5 christos int n = read(fd, lp0, (line + LINSZ) - lp0);
150 1.5 christos if (n < 0) {
151 1.1 cgd printf("Input error.\n");
152 1.1 cgd exit(1);
153 1.1 cgd }
154 1.5 christos if (n == 0)
155 1.5 christos eof++;
156 1.5 christos lpe = lp0 + n;
157 1.1 cgd }
158 1.1 cgd
159 1.5 christos static char
160 1.5 christos nextchar()
161 1.5 christos {
162 1.5 christos if (lp == lpe) {
163 1.1 cgd readline();
164 1.1 cgd lp = lp0;
165 1.1 cgd }
166 1.5 christos return ((lp == lpe) ? 0 : *lp++);
167 1.1 cgd }
168 1.1 cgd
169 1.5 christos static int
170 1.5 christos skipuntil(s)
171 1.7 jsm const char *s;
172 1.5 christos {
173 1.7 jsm const char *sp0;
174 1.7 jsm char *sp1;
175 1.1 cgd loop:
176 1.5 christos while (*s != nextchar())
177 1.5 christos if (eof) {
178 1.1 cgd printf("Cannot skipuntil %s\n", s);
179 1.1 cgd exit(1);
180 1.1 cgd }
181 1.5 christos if (strlen(s) > lpe - lp + 1) {
182 1.5 christos char *lp1, *lp2;
183 1.1 cgd lp2 = lp;
184 1.1 cgd lp1 = lp = lp0;
185 1.5 christos while (lp2 != lpe)
186 1.5 christos *lp1++ = *lp2++;
187 1.1 cgd lp2 = lp0; /* save value */
188 1.1 cgd lp0 = lp1;
189 1.1 cgd readline();
190 1.1 cgd lp0 = lp2;
191 1.5 christos if (strlen(s) > lpe - lp + 1) {
192 1.1 cgd printf("error in skipuntil");
193 1.1 cgd exit(1);
194 1.1 cgd }
195 1.1 cgd }
196 1.5 christos sp0 = s + 1;
197 1.1 cgd sp1 = lp;
198 1.5 christos while (*sp0 && *sp0 == *sp1)
199 1.5 christos sp0++, sp1++;
200 1.5 christos if (!*sp0) {
201 1.1 cgd lp = sp1;
202 1.5 christos return (1);
203 1.1 cgd }
204 1.1 cgd goto loop;
205 1.1 cgd }
206 1.1 cgd
207 1.5 christos static int
208 1.5 christos getentry()
209 1.5 christos {
210 1.5 christos int inbraces = 0, inparens = 0, stringseen = 0, commaseen = 0;
211 1.5 christos int prefix = 0;
212 1.5 christos char ch;
213 1.1 cgd #define NSZ 10
214 1.5 christos char identif[NSZ], *ip;
215 1.1 cgd string[0] = string[4] = 0;
216 1.5 christos /*
217 1.5 christos * read until {...} or XXX(...) followed by , skip comment and
218 1.5 christos * #define lines deliver 0 on failure
219 1.1 cgd */
220 1.5 christos while (1) {
221 1.1 cgd ch = nextchar();
222 1.5 christos swi:
223 1.5 christos if (letter(ch)) {
224 1.1 cgd ip = identif;
225 1.1 cgd do {
226 1.5 christos if (ip < identif + NSZ - 1)
227 1.5 christos *ip++ = ch;
228 1.1 cgd ch = nextchar();
229 1.5 christos } while (letter(ch) || digit(ch));
230 1.1 cgd *ip = 0;
231 1.5 christos while (ch == ' ' || ch == '\t')
232 1.5 christos ch = nextchar();
233 1.5 christos if (ch == '(' && !inparens && !stringseen)
234 1.5 christos if (!strcmp(identif, "WAND") ||
235 1.5 christos !strcmp(identif, "RING") ||
236 1.5 christos !strcmp(identif, "POTION") ||
237 1.5 christos !strcmp(identif, "SCROLL"))
238 1.5 christos (void) strncpy(string, identif, 3),
239 1.5 christos string[3] = '_',
240 1.5 christos prefix = 4;
241 1.1 cgd }
242 1.5 christos switch (ch) {
243 1.1 cgd case '/':
244 1.1 cgd /* watch for comment */
245 1.5 christos if ((ch = nextchar()) == '*')
246 1.1 cgd skipuntil("*/");
247 1.1 cgd goto swi;
248 1.1 cgd case '{':
249 1.1 cgd inbraces++;
250 1.1 cgd continue;
251 1.1 cgd case '(':
252 1.1 cgd inparens++;
253 1.1 cgd continue;
254 1.1 cgd case '}':
255 1.1 cgd inbraces--;
256 1.5 christos if (inbraces < 0)
257 1.5 christos return (0);
258 1.1 cgd continue;
259 1.1 cgd case ')':
260 1.1 cgd inparens--;
261 1.5 christos if (inparens < 0) {
262 1.1 cgd printf("too many ) ?");
263 1.1 cgd exit(1);
264 1.1 cgd }
265 1.1 cgd continue;
266 1.1 cgd case '\n':
267 1.1 cgd /* watch for #define at begin of line */
268 1.5 christos if ((ch = nextchar()) == '#') {
269 1.5 christos char pch;
270 1.1 cgd /* skip until '\n' not preceded by '\\' */
271 1.1 cgd do {
272 1.1 cgd pch = ch;
273 1.1 cgd ch = nextchar();
274 1.5 christos } while (ch != '\n' || pch == '\\');
275 1.1 cgd continue;
276 1.1 cgd }
277 1.1 cgd goto swi;
278 1.1 cgd case ',':
279 1.5 christos if (!inparens && !inbraces) {
280 1.5 christos if (prefix && !string[prefix])
281 1.1 cgd string[0] = 0;
282 1.5 christos if (stringseen)
283 1.5 christos return (1);
284 1.1 cgd printf("unexpected ,\n");
285 1.1 cgd exit(1);
286 1.1 cgd }
287 1.1 cgd commaseen++;
288 1.1 cgd continue;
289 1.1 cgd case '\'':
290 1.5 christos if ((ch = nextchar()) == '\\')
291 1.5 christos ch = nextchar();
292 1.5 christos if (nextchar() != '\'') {
293 1.1 cgd printf("strange character denotation?\n");
294 1.1 cgd exit(1);
295 1.1 cgd }
296 1.1 cgd continue;
297 1.1 cgd case '"':
298 1.1 cgd {
299 1.5 christos char *sp = string + prefix;
300 1.5 christos char pch;
301 1.5 christos int store = (inbraces || inparens)
302 1.5 christos && !stringseen++ && !commaseen;
303 1.1 cgd do {
304 1.1 cgd pch = ch;
305 1.1 cgd ch = nextchar();
306 1.5 christos if (store && sp < string + STRSZ)
307 1.1 cgd *sp++ = ch;
308 1.5 christos } while (ch != '"' || pch == '\\');
309 1.5 christos if (store)
310 1.5 christos *--sp = 0;
311 1.1 cgd continue;
312 1.1 cgd }
313 1.1 cgd }
314 1.1 cgd }
315 1.1 cgd }
316 1.1 cgd
317 1.5 christos static void
318 1.5 christos capitalize(sp)
319 1.5 christos char *sp;
320 1.5 christos {
321 1.5 christos if ('a' <= *sp && *sp <= 'z')
322 1.5 christos *sp += 'A' - 'a';
323 1.1 cgd }
324 1.1 cgd
325 1.5 christos static int
326 1.5 christos letter(ch)
327 1.5 christos char ch;
328 1.5 christos {
329 1.5 christos return (('a' <= ch && ch <= 'z') ||
330 1.5 christos ('A' <= ch && ch <= 'Z'));
331 1.1 cgd }
332 1.1 cgd
333 1.5 christos static int
334 1.5 christos digit(ch)
335 1.5 christos char ch;
336 1.5 christos {
337 1.5 christos return ('0' <= ch && ch <= '9');
338 1.1 cgd }
339