Home | History | Annotate | Line # | Download | only in hack
makedefs.c revision 1.1
      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 
     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 
     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
     71 nextchar(){
     72 	if(lp == lpe){
     73 		readline();
     74 		lp = lp0;
     75 	}
     76 	return((lp == lpe) ? 0 : *lp++);
     77 }
     78 
     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 
    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 
    213 capitalize(sp) register char *sp; {
    214 	if('a' <= *sp && *sp <= 'z') *sp += 'A'-'a';
    215 }
    216 
    217 letter(ch) register char ch; {
    218 	return( ('a' <= ch && ch <= 'z') ||
    219 		('A' <= ch && ch <= 'Z') );
    220 }
    221 
    222 digit(ch) register char ch; {
    223 	return( '0' <= ch && ch <= '9' );
    224 }
    225