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