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