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