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