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