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