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