makedefs.c 8.4 KB

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