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