1 /* $NetBSD: makedefs.c,v 1.8 2003/04/02 18:36:42 jsm Exp $ */ 2 3 /* 4 * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica, 5 * Amsterdam 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are 10 * met: 11 * 12 * - Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * - Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * - Neither the name of the Stichting Centrum voor Wiskunde en 20 * Informatica, nor the names of its contributors may be used to endorse or 21 * promote products derived from this software without specific prior 22 * written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 25 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 26 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 27 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 28 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 29 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 30 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 */ 36 37 /* 38 * Copyright (c) 1982 Jay Fenlason <hack@gnu.org> 39 * All rights reserved. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 3. The name of the author may not be used to endorse or promote products 50 * derived from this software without specific prior written permission. 51 * 52 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 53 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 54 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 55 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 56 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 57 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 58 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 59 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 60 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 61 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 */ 63 64 #include <stdio.h> 65 #include <stdlib.h> 66 #include <string.h> 67 #include <fcntl.h> 68 #include <unistd.h> 69 70 /* construct definitions of object constants */ 71 #define LINSZ 1000 72 #define STRSZ 40 73 74 int fd; 75 char string[STRSZ]; 76 77 static void readline(void); 78 static char nextchar(void); 79 static int skipuntil(const char *); 80 static int getentry(void); 81 static void capitalize(char *); 82 static int letter(char); 83 static int digit(char); 84 85 int 86 main(int argc, char **argv) 87 { 88 int i = 0; 89 int propct = 0; 90 char *sp; 91 if (argc != 2) { 92 (void) fprintf(stderr, "usage: makedefs file\n"); 93 exit(1); 94 } 95 if ((fd = open(argv[1], O_RDONLY)) < 0) { 96 perror(argv[1]); 97 exit(1); 98 } 99 skipuntil("objects[] = {"); 100 while (getentry()) { 101 if (!*string) { 102 i++; 103 continue; 104 } 105 for (sp = string; *sp; sp++) 106 if (*sp == ' ' || *sp == '\t' || *sp == '-') 107 *sp = '_'; 108 if (!strncmp(string, "RIN_", 4)) { 109 capitalize(string + 4); 110 printf("#define %s u.uprops[%d].p_flgs\n", 111 string + 4, propct++); 112 } 113 for (sp = string; *sp; sp++) 114 capitalize(sp); 115 /* avoid trouble with stupid C preprocessors */ 116 if (!strncmp(string, "WORTHLESS_PIECE_OF_", 19)) 117 printf("/* #define %s %d */\n", string, i); 118 else 119 printf("#define %s %d\n", string, i); 120 i++; 121 } 122 printf("\n#define CORPSE DEAD_HUMAN\n"); 123 printf("#define LAST_GEM (JADE+1)\n"); 124 printf("#define LAST_RING %d\n", propct); 125 printf("#define NROFOBJECTS %d\n", i - 1); 126 fflush(stdout); 127 if (ferror(stdout)) { 128 perror("standard output"); 129 exit(1); 130 } 131 exit(0); 132 } 133 134 char line[LINSZ], *lp = line, *lp0 = line, *lpe = line; 135 int eof; 136 137 static void 138 readline(void) 139 { 140 int n = read(fd, lp0, (line + LINSZ) - lp0); 141 if (n < 0) { 142 printf("Input error.\n"); 143 exit(1); 144 } 145 if (n == 0) 146 eof++; 147 lpe = lp0 + n; 148 } 149 150 static char 151 nextchar(void) 152 { 153 if (lp == lpe) { 154 readline(); 155 lp = lp0; 156 } 157 return ((lp == lpe) ? 0 : *lp++); 158 } 159 160 static int 161 skipuntil(const char *s) 162 { 163 const char *sp0; 164 char *sp1; 165 loop: 166 while (*s != nextchar()) 167 if (eof) { 168 printf("Cannot skipuntil %s\n", s); 169 exit(1); 170 } 171 if (strlen(s) > (size_t)(lpe - lp + 1)) { 172 char *lp1, *lp2; 173 lp2 = lp; 174 lp1 = lp = lp0; 175 while (lp2 != lpe) 176 *lp1++ = *lp2++; 177 lp2 = lp0; /* save value */ 178 lp0 = lp1; 179 readline(); 180 lp0 = lp2; 181 if (strlen(s) > (size_t)(lpe - lp + 1)) { 182 printf("error in skipuntil"); 183 exit(1); 184 } 185 } 186 sp0 = s + 1; 187 sp1 = lp; 188 while (*sp0 && *sp0 == *sp1) 189 sp0++, sp1++; 190 if (!*sp0) { 191 lp = sp1; 192 return (1); 193 } 194 goto loop; 195 } 196 197 static int 198 getentry(void) 199 { 200 int inbraces = 0, inparens = 0, stringseen = 0, commaseen = 0; 201 int prefix = 0; 202 char ch; 203 #define NSZ 10 204 char identif[NSZ], *ip; 205 string[0] = string[4] = 0; 206 /* 207 * read until {...} or XXX(...) followed by , skip comment and 208 * #define lines deliver 0 on failure 209 */ 210 while (1) { 211 ch = nextchar(); 212 swi: 213 if (letter(ch)) { 214 ip = identif; 215 do { 216 if (ip < identif + NSZ - 1) 217 *ip++ = ch; 218 ch = nextchar(); 219 } while (letter(ch) || digit(ch)); 220 *ip = 0; 221 while (ch == ' ' || ch == '\t') 222 ch = nextchar(); 223 if (ch == '(' && !inparens && !stringseen) 224 if (!strcmp(identif, "WAND") || 225 !strcmp(identif, "RING") || 226 !strcmp(identif, "POTION") || 227 !strcmp(identif, "SCROLL")) 228 (void) strncpy(string, identif, 3), 229 string[3] = '_', 230 prefix = 4; 231 } 232 switch (ch) { 233 case '/': 234 /* watch for comment */ 235 if ((ch = nextchar()) == '*') 236 skipuntil("*/"); 237 goto swi; 238 case '{': 239 inbraces++; 240 continue; 241 case '(': 242 inparens++; 243 continue; 244 case '}': 245 inbraces--; 246 if (inbraces < 0) 247 return (0); 248 continue; 249 case ')': 250 inparens--; 251 if (inparens < 0) { 252 printf("too many ) ?"); 253 exit(1); 254 } 255 continue; 256 case '\n': 257 /* watch for #define at begin of line */ 258 if ((ch = nextchar()) == '#') { 259 char pch; 260 /* skip until '\n' not preceded by '\\' */ 261 do { 262 pch = ch; 263 ch = nextchar(); 264 } while (ch != '\n' || pch == '\\'); 265 continue; 266 } 267 goto swi; 268 case ',': 269 if (!inparens && !inbraces) { 270 if (prefix && !string[prefix]) 271 string[0] = 0; 272 if (stringseen) 273 return (1); 274 printf("unexpected ,\n"); 275 exit(1); 276 } 277 commaseen++; 278 continue; 279 case '\'': 280 if ((ch = nextchar()) == '\\') 281 ch = nextchar(); 282 if (nextchar() != '\'') { 283 printf("strange character denotation?\n"); 284 exit(1); 285 } 286 continue; 287 case '"': 288 { 289 char *sp = string + prefix; 290 char pch; 291 int store = (inbraces || inparens) 292 && !stringseen++ && !commaseen; 293 do { 294 pch = ch; 295 ch = nextchar(); 296 if (store && sp < string + STRSZ) 297 *sp++ = ch; 298 } while (ch != '"' || pch == '\\'); 299 if (store) 300 *--sp = 0; 301 continue; 302 } 303 } 304 } 305 } 306 307 static void 308 capitalize(char *sp) 309 { 310 if ('a' <= *sp && *sp <= 'z') 311 *sp += 'A' - 'a'; 312 } 313 314 static int 315 letter(char ch) 316 { 317 return (('a' <= ch && ch <= 'z') || 318 ('A' <= ch && ch <= 'Z')); 319 } 320 321 static int 322 digit(char ch) 323 { 324 return ('0' <= ch && ch <= '9'); 325 } 326