initdeck.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /* $NetBSD: initdeck.c,v 1.15 2003/08/07 09:37:28 agc Exp $ */
  2. /*
  3. * Copyright (c) 1980, 1993
  4. * The Regents of the University of California. All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the University nor the names of its contributors
  15. * may be used to endorse or promote products derived from this software
  16. * without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  22. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  24. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  25. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. */
  30. #ifdef __NetBSD__
  31. #include <sys/cdefs.h>
  32. #ifndef lint
  33. __COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\
  34. The Regents of the University of California. All rights reserved.\n");
  35. #endif /* not lint */
  36. #ifndef lint
  37. #if 0
  38. static char sccsid[] = "@(#)initdeck.c 8.1 (Berkeley) 5/31/93";
  39. #else
  40. __RCSID("$NetBSD: initdeck.c,v 1.15 2003/08/07 09:37:28 agc Exp $");
  41. #endif
  42. #endif /* not lint */
  43. #endif /* __NetBSD__ */
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47. #include <sys/types.h>
  48. #include "deck.h"
  49. #ifndef u_int32_t
  50. #define u_int32_t unsigned int
  51. #endif
  52. static u_int32_t
  53. h2nl(u_int32_t h)
  54. {
  55. unsigned char c[4];
  56. u_int32_t rv;
  57. c[0] = (h >> 24) & 0xff;
  58. c[1] = (h >> 16) & 0xff;
  59. c[2] = (h >> 8) & 0xff;
  60. c[3] = (h >> 0) & 0xff;
  61. memcpy(&rv, c, sizeof rv);
  62. return (rv);
  63. }
  64. /*
  65. * This program initializes the card files for monopoly.
  66. * It reads in a data file with Com. Chest cards, followed by
  67. * the Chance card. The two are separated by a line of "%-".
  68. * All other cards are separated by lines of "%%". In the front
  69. * of the file is the data for the decks in the same order.
  70. * This includes the seek pointer for the start of each card.
  71. * All cards start with their execution code, followed by the
  72. * string to print, terminated with a null byte.
  73. */
  74. #define TRUE 1
  75. #define FALSE 0
  76. #define bool char
  77. const char *infile = "cards.inp", /* input file */
  78. *outfile = "cards.pck"; /* "packed" file */
  79. DECK deck[2];
  80. FILE *inf, *outf;
  81. /* initdeck.c */
  82. int main(int, char *[]);
  83. static void getargs(int, char *[]);
  84. static void fwrite_be_offt(off_t, FILE *);
  85. static void count(void);
  86. static void putem(void);
  87. int
  88. main(ac, av)
  89. int ac;
  90. char *av[];
  91. {
  92. int i, nc;
  93. /* sanity test */
  94. if (sizeof(int) != 4) {
  95. fprintf(stderr, "sizeof(int) != 4\n");
  96. exit(1);
  97. }
  98. getargs(ac, av);
  99. if ((inf = fopen(infile, "r")) == NULL) {
  100. perror(infile);
  101. exit(1);
  102. }
  103. count();
  104. /*
  105. * allocate space for pointers.
  106. */
  107. CC_D.offsets = calloc(CC_D.num_cards + 1, /* sizeof (off_t) */ 8);
  108. CH_D.offsets = calloc(CH_D.num_cards + 1, /* sizeof (off_t) */ 8);
  109. if (CC_D.offsets == NULL || CH_D.offsets == NULL) {
  110. fprintf(stderr, "out of memory\n");
  111. exit(1);
  112. }
  113. fseek(inf, 0L, SEEK_SET);
  114. if ((outf = fopen(outfile, "w")) == NULL) {
  115. perror(outfile);
  116. exit(1);
  117. }
  118. /*
  119. * these fields will be overwritten after the offsets are calculated,
  120. * so byte-order doesn't matter yet.
  121. */
  122. fwrite(&nc, sizeof(nc), 1, outf);
  123. fwrite(&nc, sizeof(nc), 1, outf);
  124. fwrite(CC_D.offsets, /* sizeof (off_t) */ 8, CC_D.num_cards, outf);
  125. fwrite(CH_D.offsets, /* sizeof (off_t) */ 8, CH_D.num_cards, outf);
  126. /*
  127. * write out the cards themselves (calculating the offsets).
  128. */
  129. putem();
  130. fclose(inf);
  131. fseek(outf, 0, SEEK_SET);
  132. /* number of community chest cards first... */
  133. nc = h2nl(CC_D.num_cards);
  134. fwrite(&nc, sizeof(nc), 1, outf);
  135. /* ... then number of chance cards. */
  136. nc = h2nl(CH_D.num_cards);
  137. fwrite(&nc, sizeof(nc), 1, outf);
  138. /* dump offsets in big-endian byte order */
  139. for (i = 0; i < CC_D.num_cards; i++)
  140. fwrite_be_offt(CC_D.offsets[i], outf);
  141. for (i = 0; i < CH_D.num_cards; i++)
  142. fwrite_be_offt(CH_D.offsets[i], outf);
  143. fflush(outf);
  144. if (ferror(outf)) {
  145. perror(outfile);
  146. exit(1);
  147. }
  148. fclose(outf);
  149. printf("There were %d com. chest and %d chance cards\n",
  150. CC_D.num_cards, CH_D.num_cards);
  151. exit(0);
  152. }
  153. static void
  154. getargs(ac, av)
  155. int ac;
  156. char *av[];
  157. {
  158. if (ac > 1)
  159. infile = av[1];
  160. if (ac > 2)
  161. outfile = av[2];
  162. }
  163. /*
  164. * count the cards
  165. */
  166. static void
  167. count()
  168. {
  169. bool newline;
  170. DECK *in_deck;
  171. int c;
  172. newline = TRUE;
  173. in_deck = &CC_D;
  174. while ((c=getc(inf)) != EOF)
  175. if (newline && c == '%') {
  176. newline = FALSE;
  177. in_deck->num_cards++;
  178. if (getc(inf) == '-')
  179. in_deck = &CH_D;
  180. }
  181. else
  182. newline = (c == '\n');
  183. in_deck->num_cards++;
  184. }
  185. /*
  186. * put strings in the file
  187. */
  188. static void
  189. putem()
  190. {
  191. bool newline;
  192. DECK *in_deck;
  193. int c;
  194. int num;
  195. in_deck = &CC_D;
  196. CC_D.num_cards = 1;
  197. CH_D.num_cards = 0;
  198. CC_D.offsets[0] = ftell(outf);
  199. putc(getc(inf), outf);
  200. putc(getc(inf), outf);
  201. for (num = 0; (c=getc(inf)) != '\n'; )
  202. num = num * 10 + (c - '0');
  203. putw(h2nl(num), outf);
  204. newline = FALSE;
  205. while ((c=getc(inf)) != EOF)
  206. if (newline && c == '%') {
  207. putc('\0', outf);
  208. newline = FALSE;
  209. if (getc(inf) == '-')
  210. in_deck = &CH_D;
  211. while (getc(inf) != '\n')
  212. continue;
  213. in_deck->offsets[in_deck->num_cards++] = ftell(outf);
  214. if ((c=getc(inf)) == EOF)
  215. break;
  216. putc(c, outf);
  217. putc(c = getc(inf), outf);
  218. for (num = 0; (c=getc(inf)) != EOF && c != '\n'; )
  219. num = num * 10 + (c - '0');
  220. putw(h2nl(num), outf);
  221. }
  222. else {
  223. putc(c, outf);
  224. newline = (c == '\n');
  225. }
  226. putc('\0', outf);
  227. }
  228. /*
  229. * fwrite_be_offt:
  230. * Write out the off paramater as a 64 bit big endian number
  231. */
  232. static void
  233. fwrite_be_offt(off, f)
  234. off_t off;
  235. FILE *f;
  236. {
  237. int i;
  238. unsigned char c[8];
  239. for (i = 7; i >= 0; i--) {
  240. c[i] = off & 0xff;
  241. off >>= 8;
  242. }
  243. fwrite(c, sizeof(c), 1, f);
  244. }