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