1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37: #include <sys/cdefs.h>
38: #ifndef lint
39: #if 0
40: static char sccsid[] = "@(#)io.c 8.1 (Berkeley) 5/31/93";
41: #else
42: __RCSID("$NetBSD: io.c,v 1.15 2003/09/19 10:01:53 itojun Exp $");
43: #endif
44: #endif
45:
46:
47:
48: #include <err.h>
49: #include <stdio.h>
50: #include <string.h>
51: #include <stdlib.h>
52: #include "hdr.h"
53: #include "extern.h"
54:
55:
56: void
57: getin(wrd1, wrd2)
58: char **wrd1, **wrd2;
59: {
60: char *s;
61: static char wd1buf[MAXSTR], wd2buf[MAXSTR];
62: int first, numch;
63:
64: *wrd1 = wd1buf;
65: *wrd2 = wd2buf;
66: wd2buf[0] = 0;
67: for (s = wd1buf, first = 1, numch = 0;;) {
68: if ((*s = getchar()) >= 'A' && *s <= 'Z')
69: *s = *s - ('A' - 'a');
70:
71: switch (*s) {
72: case '\n':
73: *s = 0;
74: return;
75: case ' ':
76: if (s == wd1buf || s == wd2buf)
77: continue;
78: *s = 0;
79: if (first) {
80: first = numch = 0;
81: s = wd2buf;
82: break;
83: } else {
84: FLUSHLINE;
85: *s = 0;
86: return;
87: }
88: case EOF:
89: printf("user closed input stream, quitting...\n");
90: exit(0);
91: default:
92: if (++numch >= MAXSTR) {
93: printf("Give me a break!!\n");
94: wd1buf[0] = wd2buf[0] = 0;
95: FLUSHLINE;
96: return;
97: }
98: s++;
99: }
100: }
101: }
102:
103: int
104: yes(x, y, z)
105: int x, y, z;
106: {
107: int result = TRUE;
108: int ch;
109: for (;;) {
110: rspeak(x);
111: if ((ch = getchar()) == 'y')
112: result = TRUE;
113: else if (ch == 'n')
114: result = FALSE;
115: else if (ch == EOF) {
116: printf("user closed input stream, quitting...\n");
117: exit(0);
118: }
119: FLUSHLINE;
120: if (ch == 'y' || ch == 'n')
121: break;
122: printf("Please answer the question.\n");
123: }
124: if (result == TRUE)
125: rspeak(y);
126: if (result == FALSE)
127: rspeak(z);
128: return (result);
129: }
130:
131: int
132: yesm(x, y, z)
133: int x, y, z;
134: {
135: int result = TRUE;
136: int ch;
137: for (;;) {
138: mspeak(x);
139: if ((ch = getchar()) == 'y')
140: result = TRUE;
141: else if (ch == 'n')
142: result = FALSE;
143: else if (ch == EOF) {
144: printf("user closed input stream, quitting...\n");
145: exit(0);
146: }
147: FLUSHLINE;
148: if (ch == 'y' || ch == 'n')
149: break;
150: printf("Please answer the question.\n");
151: }
152: if (result == TRUE)
153: mspeak(y);
154: if (result == FALSE)
155: mspeak(z);
156: return (result);
157: }
158:
159:
160: char *inptr;
161:
162: int outsw = 0;
163:
164: const char iotape[] = "Ax3F'\003tt$8h\315qer*h\017nGKrX\207:!l";
165: const char *tape = iotape;
166:
167: int
168: next()
169: {
170: int ch;
171:
172: ch = (*inptr ^ random()) & 0xFF;
173: if (outsw) {
174: if (*tape == 0)
175: tape = iotape;
176: *inptr = ch ^ *tape++;
177: }
178: inptr++;
179: return (ch);
180: }
181:
182: char breakch;
183:
184: void
185: rdata()
186: {
187: int sect;
188: char ch;
189:
190: inptr = data_file;
191: srandom(SEED);
192:
193: clsses = 1;
194: for (;;) {
195: sect = next() - '0';
196: #ifdef VERBOSE
197: printf("Section %c", sect + '0');
198: #endif
199: if ((ch = next()) != LF) {
200: FLUSHLF;
201: #ifdef VERBOSE
202: putchar(ch);
203: #endif
204: sect = 10 * sect + ch - '0';
205: }
206: #ifdef VERBOSE
207: putchar('\n');
208: #endif
209: switch (sect) {
210: case 0:
211: return;
212: case 1:
213: rdesc(1);
214: break;
215: case 2:
216: rdesc(2);
217: break;
218: case 3:
219: rtrav();
220: break;
221: case 4:
222: rvoc();
223: break;
224: case 5:
225: rdesc(5);
226: break;
227: case 6:
228: rdesc(6);
229: break;
230: case 7:
231: rlocs();
232: break;
233: case 8:
234: rdflt();
235: break;
236: case 9:
237: rliq();
238: break;
239: case 10:
240: rdesc(10);
241: break;
242: case 11:
243: rhints();
244: break;
245: case 12:
246: rdesc(12);
247: break;
248: default:
249: printf("Invalid data section number: %d\n", sect);
250: for (;;)
251: putchar(next());
252: }
253: if (breakch != LF)
254: FLUSHLF;
255: }
256: }
257:
258: char nbf[12];
259:
260:
261: int
262: rnum()
263: {
264: char *s;
265: tape = iotape;
266: for (s = nbf, *s = 0;; s++)
267: if ((*s = next()) == TAB || *s == '\n' || *s == LF)
268: break;
269: breakch = *s;
270: *s = 0;
271: if (nbf[0] == '-')
272: return (-1);
273: return (atoi(nbf));
274: }
275:
276: char *seekhere;
277:
278: void
279: rdesc(sect)
280: int sect;
281: {
282: int locc;
283: char *seekstart, *maystart;
284:
285: seekhere = inptr;
286: outsw = 1;
287: for (oldloc = -1, seekstart = seekhere;;) {
288: maystart = inptr;
289: if ((locc = rnum()) != oldloc && oldloc >= 0
290: && !(sect == 5 && (locc == 0 || locc >= 100))) {
291: switch (sect) {
292: case 1:
293: ltext[oldloc].seekadr = seekhere;
294: ltext[oldloc].txtlen = maystart - seekstart;
295: break;
296: case 2:
297: stext[oldloc].seekadr = seekhere;
298: stext[oldloc].txtlen = maystart - seekstart;
299: break;
300: case 5:
301: ptext[oldloc].seekadr = seekhere;
302: ptext[oldloc].txtlen = maystart - seekstart;
303: break;
304: case 6:
305: if (oldloc >= RTXSIZ)
306: errx(1,"Too many random msgs");
307: rtext[oldloc].seekadr = seekhere;
308: rtext[oldloc].txtlen = maystart - seekstart;
309: break;
310: case 10:
311: ctext[clsses].seekadr = seekhere;
312: ctext[clsses].txtlen = maystart - seekstart;
313: cval[clsses++] = oldloc;
314: break;
315: case 12:
316: if (oldloc >= MAGSIZ)
317: errx(1,"Too many magic msgs");
318: mtext[oldloc].seekadr = seekhere;
319: mtext[oldloc].txtlen = maystart - seekstart;
320: break;
321: default:
322: errx(1,"rdesc called with bad section");
323: }
324: seekhere += maystart - seekstart;
325: }
326: if (locc < 0) {
327: outsw = 0;
328: seekhere += 3;
329: return;
330: }
331: if (sect != 5 || (locc > 0 && locc < 100)) {
332: if (oldloc != locc)
333: seekstart = maystart;
334: oldloc = locc;
335: }
336: FLUSHLF;
337: }
338: }
339:
340: void
341: rtrav()
342: {
343: int locc;
344: struct travlist *t = NULL;
345: char *s;
346: char buf[12];
347: int len, m, n, entries = 0;
348:
349: for (oldloc = -1;;) {
350: if ((locc = rnum()) != oldloc && oldloc >= 0) {
351: t->next = 0;
352:
353:
354: }
355: if (locc == -1)
356: return;
357: if (locc != oldloc) {
358: t = travel[locc] = (struct travlist *) malloc(sizeof(struct travlist));
359: if ( t == NULL)
360: err(1, NULL);
361:
362: entries = 0;
363: oldloc = locc;
364: }
365: for (s = buf;; s++)
366: if ((*s = next()) == TAB || *s == LF)
367: break;
368: *s = 0;
369: len = length(buf) - 1;
370:
371: if (len < 4) {
372: m = 0;
373: n = atoi(buf);
374: } else {
375: n = atoi(buf + len - 3);
376: buf[len - 3] = 0;
377: m = atoi(buf);
378: }
379: while (breakch != LF) {
380: if (entries++) {
381: t = t->next = (struct travlist *) malloc(sizeof(struct travlist));
382: if (t == NULL)
383: err(1, NULL);
384: }
385: t->tverb = rnum();
386: t->tloc = n;
387: t->conditions = m;
388:
389: }
390: }
391: }
392: #ifdef DEBUG
393:
394: void
395: twrite(loq)
396: int loq;
397: {
398: struct travlist *t;
399: printf("If");
400: speak(<ext[loq]);
401: printf("then\n");
402: for (t = travel[loq]; t != 0; t = t->next) {
403: printf("verb %d takes you to ", t->tverb);
404: if (t->tloc <= 300)
405: speak(<ext[t->tloc]);
406: else
407: if (t->tloc <= 500)
408: printf("special code %d\n", t->tloc - 300);
409: else
410: rspeak(t->tloc - 500);
411: printf("under conditions %d\n", t->conditions);
412: }
413: }
414: #endif
415:
416: void
417: rvoc()
418: {
419: char *s;
420: int index;
421: char buf[6];
422: for (;;) {
423: index = rnum();
424: if (index < 0)
425: break;
426: for (s = buf, *s = 0;; s++)
427: if ((*s = next()) == TAB || *s == '\n' || *s == LF
428: || *s == ' ')
429: break;
430:
431: if (*s != '\n' && *s != LF)
432: FLUSHLF;
433: *s = 0;
434:
435: vocab(buf, -2, index);
436: }
437:
438: }
439:
440:
441: void
442: rlocs()
443: {
444: for (;;) {
445: if ((obj = rnum()) < 0)
446: break;
447: plac[obj] = rnum();
448: if (breakch == TAB)
449: fixd[obj] = rnum();
450: else
451: fixd[obj] = 0;
452: }
453: }
454:
455: void
456: rdflt()
457: {
458: for (;;) {
459: if ((verb = rnum()) < 0)
460: break;
461: actspk[verb] = rnum();
462: }
463: }
464:
465: void
466: rliq()
467: {
468: int bitnum;
469: for (;;) {
470: if ((bitnum = rnum()) < 0)
471: break;
472: for (;;) {
473: cond[rnum()] |= setbit[bitnum];
474: if (breakch == LF)
475: break;
476: }
477: }
478: }
479:
480: void
481: rhints()
482: {
483: int hintnum, i;
484: hntmax = 0;
485: for (;;) {
486: if ((hintnum = rnum()) < 0)
487: break;
488: for (i = 1; i < 5; i++)
489: hints[hintnum][i] = rnum();
490: if (hintnum > hntmax)
491: hntmax = hintnum;
492: }
493: }
494:
495:
496: void
497: rspeak(msg)
498: int msg;
499: {
500: if (msg != 0)
501: speak(&rtext[msg]);
502: }
503:
504:
505: void
506: mspeak(msg)
507: int msg;
508: {
509: if (msg != 0)
510: speak(&mtext[msg]);
511: }
512:
513:
514: void
515: speak(msg)
516:
517: const struct text *msg;
518:
519: {
520: char *s, nonfirst;
521:
522: s = msg->seekadr;
523: nonfirst = 0;
524: while (s - msg->seekadr < msg->txtlen) {
525: tape = iotape;
526: while ((*s++ ^ *tape++) != TAB);
527:
528:
529: if ((*s ^ *tape) == '>' &&
530: (*(s + 1) ^ *(tape + 1)) == '$' &&
531: (*(s + 2) ^ *(tape + 2)) == '<')
532: break;
533: if (blklin && !nonfirst++)
534: putchar('\n');
535: do {
536: if (*tape == 0)
537: tape = iotape;
538: putchar(*s ^ *tape);
539: } while ((*s++ ^ *tape++) != LF);
540: }
541: }
542:
543:
544: void
545: pspeak(m, skip)
546: int m;
547:
548: int skip;
549:
550: {
551: char *s, nonfirst;
552: char *numst, save;
553: struct text *msg;
554: char *tbuf;
555:
556: