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