1/* $NetBSD: makedefs.c,v 1.7 2001/03/25 20:44:04 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#ifndef lint 65static const char rcsid[] = 66 "$NetBSD: makedefs.c,v 1.7 2001/03/25 20:44:04 jsm Exp $"; 67#endif /* not lint */ 68 69#include <stdio.h> 70#include <stdlib.h> 71#include <string.h> 72#include <fcntl.h> 73#include <unistd.h> 74 75/* construct definitions of object constants */ 76#define LINSZ 1000 77#define STRSZ 40 78 79int fd; 80char string[STRSZ]; 81 82static void readline(void); 83static char nextchar(void); 84static int skipuntil(const char *); 85static int getentry(void); 86static void capitalize(char *); 87static int letter(int); 88static int digit(int); 89 90int main(int, char **); 91 92int 93main(argc, argv) 94 int argc; 95 char **argv; 96{ 97 int i = 0; 98 int propct = 0; 99 char *sp; 100 if (argc != 2) { 101 (void) fprintf(stderr, "usage: makedefs file\n"); 102 exit(1); 103 } 104 if ((fd = open(argv[1], O_RDONLY)) < 0) { 105 perror(argv[1]); 106 exit(1); 107 } 108 skipuntil("objects[] = {"); 109 while (getentry()) { 110 if (!*string) { 111 i++; 112 continue; 113 } 114 for (sp = string; *sp; sp++) 115 if (*sp == ' ' || *sp == '\t' || *sp == '-') 116 *sp = '_'; 117 if (!strncmp(string, "RIN_", 4)) { 118 capitalize(string + 4); 119 printf("#define %s u.uprops[%d].p_flgs\n", 120 string + 4, propct++); 121 } 122 for (sp = string; *sp; sp++) 123 capitalize(sp); 124 /* avoid trouble with stupid C preprocessors */ 125 if (!strncmp(string, "WORTHLESS_PIECE_OF_", 19)) 126 printf("/* #define %s %d */\n", string, i); 127 else 128 printf("#define %s %d\n", string, i); 129 i++; 130 } 131 printf("\n#define CORPSE DEAD_HUMAN\n"); 132 printf("#define LAST_GEM (JADE+1)\n"); 133 printf("#define LAST_RING %d\n", propct); 134 printf("#define NROFOBJECTS %d\n", i - 1); 135 fflush(stdout); 136 if (ferror(stdout)) { 137 perror("standard output"); 138 exit(1); 139 } 140 exit(0); 141} 142 143char line[LINSZ], *lp = line, *lp0 = line, *lpe = line; 144int eof; 145 146static void 147readline() 148{ 149 int n = read(fd, lp0, (line + LINSZ) - lp0); 150 if (n < 0) { 151 printf("Input error.\n"); 152 exit(1); 153 } 154 if (n == 0) 155 eof++; 156 lpe = lp0 + n; 157} 158 159static char 160nextchar() 161{ 162 if (lp == lpe) { 163 readline(); 164 lp = lp0; 165 } 166 return ((lp == lpe) ? 0 : *lp++); 167} 168 169static int 170skipuntil(s) 171 const char *s; 172{ 173 const char *sp0; 174 char *sp1; 175loop: 176 while (*s != nextchar()) 177 if (eof) { 178 printf("Cannot skipuntil %s\n", s); 179 exit(1); 180 } 181 if (strlen(s) > lpe - lp + 1) { 182 char *lp1, *lp2; 183 lp2 = lp; 184 lp1 = lp = lp0; 185 while (lp2 != lpe) 186 *lp1++ = *lp2++; 187 lp2 = lp0; /* save value */ 188 lp0 = lp1; 189 readline(); 190 lp0 = lp2; 191 if (strlen(s) > lpe - lp + 1) { 192 printf("error in skipuntil"); 193 exit(1); 194 } 195 } 196 sp0 = s + 1; 197 sp1 = lp; 198 while (*sp0 && *sp0 == *sp1) 199 sp0++, sp1++; 200 if (!*sp0) { 201 lp = sp1; 202 return (1); 203 } 204 goto loop; 205} 206 207static int 208getentry() 209{ 210 int inbraces = 0, inparens = 0, stringseen = 0, commaseen = 0; 211 int prefix = 0; 212 char ch; 213#define NSZ 10 214 char identif[NSZ], *ip; 215 string[0] = string[4] = 0; 216 /* 217 * read until {...} or XXX(...) followed by , skip comment and 218 * #define lines deliver 0 on failure 219 */ 220 while (1) { 221 ch = nextchar(); 222swi: 223 if (letter(ch)) { 224 ip = identif; 225 do { 226 if (ip < identif + NSZ - 1) 227 *ip++ = ch; 228 ch = nextchar(); 229 } while (letter(ch) || digit(ch)); 230 *ip = 0; 231 while (ch == ' ' || ch == '\t') 232 ch = nextchar(); 233 if (ch == '(' && !inparens && !stringseen) 234 if (!strcmp(identif, "WAND") || 235 !strcmp(identif, "RING") || 236 !strcmp(identif, "POTION") || 237 !strcmp(identif, "SCROLL")) 238 (void) strncpy(string, identif, 3), 239 string[3] = '_', 240 prefix = 4; 241 } 242 switch (ch) { 243 case '/': 244 /* watch for comment */ 245 if ((ch = nextchar()) == '*') 246 skipuntil("*/"); 247 goto swi; 248 case '{': 249 inbraces++; 250 continue; 251 case '(': 252 inparens++; 253 continue; 254 case '}': 255 inbraces--; 256 if (inbraces < 0) 257 return (0); 258 continue; 259 case ')': 260 inparens--; 261 if (inparens < 0) { 262 printf("too many ) ?"); 263 exit(1); 264 } 265 continue; 266 case '\n': 267 /* watch for #define at begin of line */ 268 if ((ch = nextchar()) == '#') { 269 char pch; 270 /* skip until '\n' not preceded by '\\' */ 271 do { 272 pch = ch; 273 ch = nextchar(); 274 } while (ch != '\n' || pch == '\\'); 275 continue; 276 } 277 goto swi; 278 case ',': 279 if (!inparens && !inbraces) { 280 if (prefix && !string[prefix]) 281 string[0] = 0; 282 if (stringseen) 283 return (1); 284 printf("unexpected ,\n"); 285 exit(1); 286 } 287 commaseen++; 288 continue; 289 case '\'': 290 if ((ch = nextchar()) == '\\') 291 ch = nextchar(); 292 if (nextchar() != '\'') { 293 printf("strange character denotation?\n"); 294 exit(1); 295 } 296 continue; 297 case '"': 298 { 299 char *sp = string + prefix; 300 char pch; 301 int store = (inbraces || inparens) 302 && !stringseen++ && !commaseen; 303 do { 304 pch = ch; 305 ch = nextchar(); 306 if (store && sp < string + STRSZ) 307 *sp++ = ch; 308 } while (ch != '"' || pch == '\\'); 309 if (store) 310 *--sp = 0; 311 continue; 312 } 313 } 314 } 315} 316 317static void 318capitalize(sp) 319 char *sp; 320{ 321 if ('a' <= *sp && *sp <= 'z') 322 *sp += 'A' - 'a'; 323} 324 325static int 326letter(ch) 327 char ch; 328{ 329 return (('a' <= ch && ch <= 'z') || 330 ('A' <= ch && ch <= 'Z')); 331} 332 333static int 334digit(ch) 335 char ch; 336{ 337 return ('0' <= ch && ch <= '9'); 338} 339