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