xref: /netbsd-src/games/hack/makedefs.c (revision 1c7f94e505e668f20d7b855ceac877d04bd31eb3)
1*1c7f94e5Sjsm /* $NetBSD: makedefs.c,v 1.8 2003/04/02 18:36:42 jsm Exp $ */
23ea4a95cSchristos 
3210cab45Smycroft /*
4*1c7f94e5Sjsm  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5*1c7f94e5Sjsm  * Amsterdam
6*1c7f94e5Sjsm  * All rights reserved.
7*1c7f94e5Sjsm  *
8*1c7f94e5Sjsm  * Redistribution and use in source and binary forms, with or without
9*1c7f94e5Sjsm  * modification, are permitted provided that the following conditions are
10*1c7f94e5Sjsm  * met:
11*1c7f94e5Sjsm  *
12*1c7f94e5Sjsm  * - Redistributions of source code must retain the above copyright notice,
13*1c7f94e5Sjsm  * this list of conditions and the following disclaimer.
14*1c7f94e5Sjsm  *
15*1c7f94e5Sjsm  * - Redistributions in binary form must reproduce the above copyright
16*1c7f94e5Sjsm  * notice, this list of conditions and the following disclaimer in the
17*1c7f94e5Sjsm  * documentation and/or other materials provided with the distribution.
18*1c7f94e5Sjsm  *
19*1c7f94e5Sjsm  * - Neither the name of the Stichting Centrum voor Wiskunde en
20*1c7f94e5Sjsm  * Informatica, nor the names of its contributors may be used to endorse or
21*1c7f94e5Sjsm  * promote products derived from this software without specific prior
22*1c7f94e5Sjsm  * written permission.
23*1c7f94e5Sjsm  *
24*1c7f94e5Sjsm  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25*1c7f94e5Sjsm  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26*1c7f94e5Sjsm  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27*1c7f94e5Sjsm  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28*1c7f94e5Sjsm  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29*1c7f94e5Sjsm  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30*1c7f94e5Sjsm  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31*1c7f94e5Sjsm  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32*1c7f94e5Sjsm  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33*1c7f94e5Sjsm  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34*1c7f94e5Sjsm  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35*1c7f94e5Sjsm  */
36*1c7f94e5Sjsm 
37*1c7f94e5Sjsm /*
38*1c7f94e5Sjsm  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39*1c7f94e5Sjsm  * All rights reserved.
40*1c7f94e5Sjsm  *
41*1c7f94e5Sjsm  * Redistribution and use in source and binary forms, with or without
42*1c7f94e5Sjsm  * modification, are permitted provided that the following conditions
43*1c7f94e5Sjsm  * are met:
44*1c7f94e5Sjsm  * 1. Redistributions of source code must retain the above copyright
45*1c7f94e5Sjsm  *    notice, this list of conditions and the following disclaimer.
46*1c7f94e5Sjsm  * 2. Redistributions in binary form must reproduce the above copyright
47*1c7f94e5Sjsm  *    notice, this list of conditions and the following disclaimer in the
48*1c7f94e5Sjsm  *    documentation and/or other materials provided with the distribution.
49*1c7f94e5Sjsm  * 3. The name of the author may not be used to endorse or promote products
50*1c7f94e5Sjsm  *    derived from this software without specific prior written permission.
51*1c7f94e5Sjsm  *
52*1c7f94e5Sjsm  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53*1c7f94e5Sjsm  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54*1c7f94e5Sjsm  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
55*1c7f94e5Sjsm  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56*1c7f94e5Sjsm  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57*1c7f94e5Sjsm  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58*1c7f94e5Sjsm  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59*1c7f94e5Sjsm  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60*1c7f94e5Sjsm  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61*1c7f94e5Sjsm  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62210cab45Smycroft  */
63210cab45Smycroft 
64210cab45Smycroft #ifndef lint
65ab8b6343Sjsm static const char rcsid[] =
66*1c7f94e5Sjsm     "$NetBSD: makedefs.c,v 1.8 2003/04/02 18:36:42 jsm Exp $";
67210cab45Smycroft #endif				/* not lint */
6861f28255Scgd 
6961f28255Scgd #include <stdio.h>
70ab8b6343Sjsm #include <stdlib.h>
71c4816c32Scgd #include <string.h>
723ea4a95cSchristos #include <fcntl.h>
733ea4a95cSchristos #include <unistd.h>
7461f28255Scgd 
7561f28255Scgd /* construct definitions of object constants */
7661f28255Scgd #define	LINSZ	1000
7761f28255Scgd #define	STRSZ	40
7861f28255Scgd 
7961f28255Scgd int             fd;
8061f28255Scgd char            string[STRSZ];
8161f28255Scgd 
82959e90b8Ssimonb static void readline(void);
83959e90b8Ssimonb static char nextchar(void);
84ab8b6343Sjsm static int skipuntil(const char *);
85959e90b8Ssimonb static int getentry(void);
86959e90b8Ssimonb static void capitalize(char *);
87959e90b8Ssimonb static int letter(int);
88959e90b8Ssimonb static int digit(int);
893ea4a95cSchristos 
90959e90b8Ssimonb int main(int, char **);
913ea4a95cSchristos 
923ea4a95cSchristos int
main(argc,argv)9361f28255Scgd main(argc, argv)
9461f28255Scgd 	int             argc;
9561f28255Scgd 	char          **argv;
9661f28255Scgd {
973ea4a95cSchristos 	int             i = 0;
983ea4a95cSchristos 	int             propct = 0;
993ea4a95cSchristos 	char           *sp;
10061f28255Scgd 	if (argc != 2) {
10161f28255Scgd 		(void) fprintf(stderr, "usage: makedefs file\n");
10261f28255Scgd 		exit(1);
10361f28255Scgd 	}
104ab8b6343Sjsm 	if ((fd = open(argv[1], O_RDONLY)) < 0) {
10561f28255Scgd 		perror(argv[1]);
10661f28255Scgd 		exit(1);
10761f28255Scgd 	}
10861f28255Scgd 	skipuntil("objects[] = {");
10961f28255Scgd 	while (getentry()) {
11061f28255Scgd 		if (!*string) {
1113ea4a95cSchristos 			i++;
11261f28255Scgd 			continue;
11361f28255Scgd 		}
11461f28255Scgd 		for (sp = string; *sp; sp++)
11561f28255Scgd 			if (*sp == ' ' || *sp == '\t' || *sp == '-')
11661f28255Scgd 				*sp = '_';
11761f28255Scgd 		if (!strncmp(string, "RIN_", 4)) {
11861f28255Scgd 			capitalize(string + 4);
11961f28255Scgd 			printf("#define	%s	u.uprops[%d].p_flgs\n",
12061f28255Scgd 			       string + 4, propct++);
12161f28255Scgd 		}
1223ea4a95cSchristos 		for (sp = string; *sp; sp++)
1233ea4a95cSchristos 			capitalize(sp);
12461f28255Scgd 		/* avoid trouble with stupid C preprocessors */
12561f28255Scgd 		if (!strncmp(string, "WORTHLESS_PIECE_OF_", 19))
1263ea4a95cSchristos 			printf("/* #define %s	%d */\n", string, i);
12761f28255Scgd 		else
1283ea4a95cSchristos 			printf("#define	%s	%d\n", string, i);
1293ea4a95cSchristos 		i++;
13061f28255Scgd 	}
13161f28255Scgd 	printf("\n#define	CORPSE	DEAD_HUMAN\n");
13261f28255Scgd 	printf("#define	LAST_GEM	(JADE+1)\n");
13361f28255Scgd 	printf("#define	LAST_RING	%d\n", propct);
1343ea4a95cSchristos 	printf("#define	NROFOBJECTS	%d\n", i - 1);
135ab8b6343Sjsm 	fflush(stdout);
136ab8b6343Sjsm 	if (ferror(stdout)) {
137ab8b6343Sjsm 		perror("standard output");
138ab8b6343Sjsm 		exit(1);
139ab8b6343Sjsm 	}
14061f28255Scgd 	exit(0);
14161f28255Scgd }
14261f28255Scgd 
14361f28255Scgd char            line[LINSZ], *lp = line, *lp0 = line, *lpe = line;
14461f28255Scgd int             eof;
14561f28255Scgd 
1463ea4a95cSchristos static void
readline()1473ea4a95cSchristos readline()
1483ea4a95cSchristos {
1493ea4a95cSchristos 	int             n = read(fd, lp0, (line + LINSZ) - lp0);
15061f28255Scgd 	if (n < 0) {
15161f28255Scgd 		printf("Input error.\n");
15261f28255Scgd 		exit(1);
15361f28255Scgd 	}
1543ea4a95cSchristos 	if (n == 0)
1553ea4a95cSchristos 		eof++;
15661f28255Scgd 	lpe = lp0 + n;
15761f28255Scgd }
15861f28255Scgd 
1593ea4a95cSchristos static char
nextchar()1603ea4a95cSchristos nextchar()
1613ea4a95cSchristos {
16261f28255Scgd 	if (lp == lpe) {
16361f28255Scgd 		readline();
16461f28255Scgd 		lp = lp0;
16561f28255Scgd 	}
16661f28255Scgd 	return ((lp == lpe) ? 0 : *lp++);
16761f28255Scgd }
16861f28255Scgd 
1693ea4a95cSchristos static int
skipuntil(s)1703ea4a95cSchristos skipuntil(s)
171ab8b6343Sjsm 	const char           *s;
1723ea4a95cSchristos {
173ab8b6343Sjsm 	const char *sp0;
174ab8b6343Sjsm 	char *sp1;
17561f28255Scgd loop:
17661f28255Scgd 	while (*s != nextchar())
17761f28255Scgd 		if (eof) {
17861f28255Scgd 			printf("Cannot skipuntil %s\n", s);
17961f28255Scgd 			exit(1);
18061f28255Scgd 		}
18161f28255Scgd 	if (strlen(s) > lpe - lp + 1) {
1823ea4a95cSchristos 		char           *lp1, *lp2;
18361f28255Scgd 		lp2 = lp;
18461f28255Scgd 		lp1 = lp = lp0;
1853ea4a95cSchristos 		while (lp2 != lpe)
1863ea4a95cSchristos 			*lp1++ = *lp2++;
18761f28255Scgd 		lp2 = lp0;	/* save value */
18861f28255Scgd 		lp0 = lp1;
18961f28255Scgd 		readline();
19061f28255Scgd 		lp0 = lp2;
19161f28255Scgd 		if (strlen(s) > lpe - lp + 1) {
19261f28255Scgd 			printf("error in skipuntil");
19361f28255Scgd 			exit(1);
19461f28255Scgd 		}
19561f28255Scgd 	}
19661f28255Scgd 	sp0 = s + 1;
19761f28255Scgd 	sp1 = lp;
1983ea4a95cSchristos 	while (*sp0 && *sp0 == *sp1)
1993ea4a95cSchristos 		sp0++, sp1++;
20061f28255Scgd 	if (!*sp0) {
20161f28255Scgd 		lp = sp1;
20261f28255Scgd 		return (1);
20361f28255Scgd 	}
20461f28255Scgd 	goto loop;
20561f28255Scgd }
20661f28255Scgd 
2073ea4a95cSchristos static int
getentry()2083ea4a95cSchristos getentry()
2093ea4a95cSchristos {
21061f28255Scgd 	int             inbraces = 0, inparens = 0, stringseen = 0, commaseen = 0;
21161f28255Scgd 	int             prefix = 0;
21261f28255Scgd 	char            ch;
21361f28255Scgd #define	NSZ	10
21461f28255Scgd 	char            identif[NSZ], *ip;
21561f28255Scgd 	string[0] = string[4] = 0;
2163ea4a95cSchristos 	/*
2173ea4a95cSchristos 	 * read until {...} or XXX(...) followed by , skip comment and
2183ea4a95cSchristos 	 * #define lines deliver 0 on failure
21961f28255Scgd 	 */
22061f28255Scgd 	while (1) {
22161f28255Scgd 		ch = nextchar();
22261f28255Scgd swi:
22361f28255Scgd 		if (letter(ch)) {
22461f28255Scgd 			ip = identif;
22561f28255Scgd 			do {
2263ea4a95cSchristos 				if (ip < identif + NSZ - 1)
2273ea4a95cSchristos 					*ip++ = ch;
22861f28255Scgd 				ch = nextchar();
22961f28255Scgd 			} while (letter(ch) || digit(ch));
23061f28255Scgd 			*ip = 0;
2313ea4a95cSchristos 			while (ch == ' ' || ch == '\t')
2323ea4a95cSchristos 				ch = nextchar();
23361f28255Scgd 			if (ch == '(' && !inparens && !stringseen)
23461f28255Scgd 				if (!strcmp(identif, "WAND") ||
23561f28255Scgd 				    !strcmp(identif, "RING") ||
23661f28255Scgd 				    !strcmp(identif, "POTION") ||
23761f28255Scgd 				    !strcmp(identif, "SCROLL"))
23861f28255Scgd 					(void) strncpy(string, identif, 3),
23961f28255Scgd 						string[3] = '_',
24061f28255Scgd 						prefix = 4;
24161f28255Scgd 		}
24261f28255Scgd 		switch (ch) {
24361f28255Scgd 		case '/':
24461f28255Scgd 			/* watch for comment */
24561f28255Scgd 			if ((ch = nextchar()) == '*')
24661f28255Scgd 				skipuntil("*/");
24761f28255Scgd 			goto swi;
24861f28255Scgd 		case '{':
24961f28255Scgd 			inbraces++;
25061f28255Scgd 			continue;
25161f28255Scgd 		case '(':
25261f28255Scgd 			inparens++;
25361f28255Scgd 			continue;
25461f28255Scgd 		case '}':
25561f28255Scgd 			inbraces--;
2563ea4a95cSchristos 			if (inbraces < 0)
2573ea4a95cSchristos 				return (0);
25861f28255Scgd 			continue;
25961f28255Scgd 		case ')':
26061f28255Scgd 			inparens--;
26161f28255Scgd 			if (inparens < 0) {
26261f28255Scgd 				printf("too many ) ?");
26361f28255Scgd 				exit(1);
26461f28255Scgd 			}
26561f28255Scgd 			continue;
26661f28255Scgd 		case '\n':
26761f28255Scgd 			/* watch for #define at begin of line */
26861f28255Scgd 			if ((ch = nextchar()) == '#') {
2693ea4a95cSchristos 				char            pch;
27061f28255Scgd 				/* skip until '\n' not preceded by '\\' */
27161f28255Scgd 				do {
27261f28255Scgd 					pch = ch;
27361f28255Scgd 					ch = nextchar();
27461f28255Scgd 				} while (ch != '\n' || pch == '\\');
27561f28255Scgd 				continue;
27661f28255Scgd 			}
27761f28255Scgd 			goto swi;
27861f28255Scgd 		case ',':
27961f28255Scgd 			if (!inparens && !inbraces) {
28061f28255Scgd 				if (prefix && !string[prefix])
28161f28255Scgd 					string[0] = 0;
2823ea4a95cSchristos 				if (stringseen)
2833ea4a95cSchristos 					return (1);
28461f28255Scgd 				printf("unexpected ,\n");
28561f28255Scgd 				exit(1);
28661f28255Scgd 			}
28761f28255Scgd 			commaseen++;
28861f28255Scgd 			continue;
28961f28255Scgd 		case '\'':
2903ea4a95cSchristos 			if ((ch = nextchar()) == '\\')
2913ea4a95cSchristos 				ch = nextchar();
29261f28255Scgd 			if (nextchar() != '\'') {
29361f28255Scgd 				printf("strange character denotation?\n");
29461f28255Scgd 				exit(1);
29561f28255Scgd 			}
29661f28255Scgd 			continue;
29761f28255Scgd 		case '"':
29861f28255Scgd 			{
2993ea4a95cSchristos 				char           *sp = string + prefix;
3003ea4a95cSchristos 				char            pch;
3013ea4a95cSchristos 				int             store = (inbraces || inparens)
30261f28255Scgd 				&& !stringseen++ && !commaseen;
30361f28255Scgd 				do {
30461f28255Scgd 					pch = ch;
30561f28255Scgd 					ch = nextchar();
30661f28255Scgd 					if (store && sp < string + STRSZ)
30761f28255Scgd 						*sp++ = ch;
30861f28255Scgd 				} while (ch != '"' || pch == '\\');
3093ea4a95cSchristos 				if (store)
3103ea4a95cSchristos 					*--sp = 0;
31161f28255Scgd 				continue;
31261f28255Scgd 			}
31361f28255Scgd 		}
31461f28255Scgd 	}
31561f28255Scgd }
31661f28255Scgd 
3173ea4a95cSchristos static void
capitalize(sp)3183ea4a95cSchristos capitalize(sp)
3193ea4a95cSchristos 	char           *sp;
3203ea4a95cSchristos {
3213ea4a95cSchristos 	if ('a' <= *sp && *sp <= 'z')
3223ea4a95cSchristos 		*sp += 'A' - 'a';
32361f28255Scgd }
32461f28255Scgd 
3253ea4a95cSchristos static int
letter(ch)3263ea4a95cSchristos letter(ch)
3273ea4a95cSchristos 	char            ch;
3283ea4a95cSchristos {
32961f28255Scgd 	return (('a' <= ch && ch <= 'z') ||
33061f28255Scgd 		('A' <= ch && ch <= 'Z'));
33161f28255Scgd }
33261f28255Scgd 
3333ea4a95cSchristos static int
digit(ch)3343ea4a95cSchristos digit(ch)
3353ea4a95cSchristos 	char            ch;
3363ea4a95cSchristos {
33761f28255Scgd 	return ('0' <= ch && ch <= '9');
33861f28255Scgd }
339