xref: /dragonfly/games/hack/makedefs.c (revision 333227be)
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 }
228