xref: /netbsd/games/hack/makedefs.c (revision bf9ec67e)
1 /* $NetBSD: makedefs.c,v 1.7 2001/03/25 20:44:04 jsm Exp $ */
2 
3 /*
4  * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
5  */
6 
7 #ifndef lint
8 static const char rcsid[] =
9     "$NetBSD: makedefs.c,v 1.7 2001/03/25 20:44:04 jsm Exp $";
10 #endif				/* not lint */
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <fcntl.h>
16 #include <unistd.h>
17 
18 /* construct definitions of object constants */
19 #define	LINSZ	1000
20 #define	STRSZ	40
21 
22 int             fd;
23 char            string[STRSZ];
24 
25 static void readline(void);
26 static char nextchar(void);
27 static int skipuntil(const char *);
28 static int getentry(void);
29 static void capitalize(char *);
30 static int letter(int);
31 static int digit(int);
32 
33 int main(int, char **);
34 
35 int
36 main(argc, argv)
37 	int             argc;
38 	char          **argv;
39 {
40 	int             i = 0;
41 	int             propct = 0;
42 	char           *sp;
43 	if (argc != 2) {
44 		(void) fprintf(stderr, "usage: makedefs file\n");
45 		exit(1);
46 	}
47 	if ((fd = open(argv[1], O_RDONLY)) < 0) {
48 		perror(argv[1]);
49 		exit(1);
50 	}
51 	skipuntil("objects[] = {");
52 	while (getentry()) {
53 		if (!*string) {
54 			i++;
55 			continue;
56 		}
57 		for (sp = string; *sp; sp++)
58 			if (*sp == ' ' || *sp == '\t' || *sp == '-')
59 				*sp = '_';
60 		if (!strncmp(string, "RIN_", 4)) {
61 			capitalize(string + 4);
62 			printf("#define	%s	u.uprops[%d].p_flgs\n",
63 			       string + 4, propct++);
64 		}
65 		for (sp = string; *sp; sp++)
66 			capitalize(sp);
67 		/* avoid trouble with stupid C preprocessors */
68 		if (!strncmp(string, "WORTHLESS_PIECE_OF_", 19))
69 			printf("/* #define %s	%d */\n", string, i);
70 		else
71 			printf("#define	%s	%d\n", string, i);
72 		i++;
73 	}
74 	printf("\n#define	CORPSE	DEAD_HUMAN\n");
75 	printf("#define	LAST_GEM	(JADE+1)\n");
76 	printf("#define	LAST_RING	%d\n", propct);
77 	printf("#define	NROFOBJECTS	%d\n", i - 1);
78 	fflush(stdout);
79 	if (ferror(stdout)) {
80 		perror("standard output");
81 		exit(1);
82 	}
83 	exit(0);
84 }
85 
86 char            line[LINSZ], *lp = line, *lp0 = line, *lpe = line;
87 int             eof;
88 
89 static void
90 readline()
91 {
92 	int             n = read(fd, lp0, (line + LINSZ) - lp0);
93 	if (n < 0) {
94 		printf("Input error.\n");
95 		exit(1);
96 	}
97 	if (n == 0)
98 		eof++;
99 	lpe = lp0 + n;
100 }
101 
102 static char
103 nextchar()
104 {
105 	if (lp == lpe) {
106 		readline();
107 		lp = lp0;
108 	}
109 	return ((lp == lpe) ? 0 : *lp++);
110 }
111 
112 static int
113 skipuntil(s)
114 	const char           *s;
115 {
116 	const char *sp0;
117 	char *sp1;
118 loop:
119 	while (*s != nextchar())
120 		if (eof) {
121 			printf("Cannot skipuntil %s\n", s);
122 			exit(1);
123 		}
124 	if (strlen(s) > lpe - lp + 1) {
125 		char           *lp1, *lp2;
126 		lp2 = lp;
127 		lp1 = lp = lp0;
128 		while (lp2 != lpe)
129 			*lp1++ = *lp2++;
130 		lp2 = lp0;	/* save value */
131 		lp0 = lp1;
132 		readline();
133 		lp0 = lp2;
134 		if (strlen(s) > lpe - lp + 1) {
135 			printf("error in skipuntil");
136 			exit(1);
137 		}
138 	}
139 	sp0 = s + 1;
140 	sp1 = lp;
141 	while (*sp0 && *sp0 == *sp1)
142 		sp0++, sp1++;
143 	if (!*sp0) {
144 		lp = sp1;
145 		return (1);
146 	}
147 	goto loop;
148 }
149 
150 static int
151 getentry()
152 {
153 	int             inbraces = 0, inparens = 0, stringseen = 0, commaseen = 0;
154 	int             prefix = 0;
155 	char            ch;
156 #define	NSZ	10
157 	char            identif[NSZ], *ip;
158 	string[0] = string[4] = 0;
159 	/*
160 	 * read until {...} or XXX(...) followed by , skip comment and
161 	 * #define lines deliver 0 on failure
162 	 */
163 	while (1) {
164 		ch = nextchar();
165 swi:
166 		if (letter(ch)) {
167 			ip = identif;
168 			do {
169 				if (ip < identif + NSZ - 1)
170 					*ip++ = ch;
171 				ch = nextchar();
172 			} while (letter(ch) || digit(ch));
173 			*ip = 0;
174 			while (ch == ' ' || ch == '\t')
175 				ch = nextchar();
176 			if (ch == '(' && !inparens && !stringseen)
177 				if (!strcmp(identif, "WAND") ||
178 				    !strcmp(identif, "RING") ||
179 				    !strcmp(identif, "POTION") ||
180 				    !strcmp(identif, "SCROLL"))
181 					(void) strncpy(string, identif, 3),
182 						string[3] = '_',
183 						prefix = 4;
184 		}
185 		switch (ch) {
186 		case '/':
187 			/* watch for comment */
188 			if ((ch = nextchar()) == '*')
189 				skipuntil("*/");
190 			goto swi;
191 		case '{':
192 			inbraces++;
193 			continue;
194 		case '(':
195 			inparens++;
196 			continue;
197 		case '}':
198 			inbraces--;
199 			if (inbraces < 0)
200 				return (0);
201 			continue;
202 		case ')':
203 			inparens--;
204 			if (inparens < 0) {
205 				printf("too many ) ?");
206 				exit(1);
207 			}
208 			continue;
209 		case '\n':
210 			/* watch for #define at begin of line */
211 			if ((ch = nextchar()) == '#') {
212 				char            pch;
213 				/* skip until '\n' not preceded by '\\' */
214 				do {
215 					pch = ch;
216 					ch = nextchar();
217 				} while (ch != '\n' || pch == '\\');
218 				continue;
219 			}
220 			goto swi;
221 		case ',':
222 			if (!inparens && !inbraces) {
223 				if (prefix && !string[prefix])
224 					string[0] = 0;
225 				if (stringseen)
226 					return (1);
227 				printf("unexpected ,\n");
228 				exit(1);
229 			}
230 			commaseen++;
231 			continue;
232 		case '\'':
233 			if ((ch = nextchar()) == '\\')
234 				ch = nextchar();
235 			if (nextchar() != '\'') {
236 				printf("strange character denotation?\n");
237 				exit(1);
238 			}
239 			continue;
240 		case '"':
241 			{
242 				char           *sp = string + prefix;
243 				char            pch;
244 				int             store = (inbraces || inparens)
245 				&& !stringseen++ && !commaseen;
246 				do {
247 					pch = ch;
248 					ch = nextchar();
249 					if (store && sp < string + STRSZ)
250 						*sp++ = ch;
251 				} while (ch != '"' || pch == '\\');
252 				if (store)
253 					*--sp = 0;
254 				continue;
255 			}
256 		}
257 	}
258 }
259 
260 static void
261 capitalize(sp)
262 	char           *sp;
263 {
264 	if ('a' <= *sp && *sp <= 'z')
265 		*sp += 'A' - 'a';
266 }
267 
268 static int
269 letter(ch)
270 	char            ch;
271 {
272 	return (('a' <= ch && ch <= 'z') ||
273 		('A' <= ch && ch <= 'Z'));
274 }
275 
276 static int
277 digit(ch)
278 	char            ch;
279 {
280 	return ('0' <= ch && ch <= '9');
281 }
282