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