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