1: #
   2: /*      Re-coding of advent in C: file i/o and user i/o                 */
   3: 
   4: static char sccsid[] = "	io.c	4.1	82/05/11	";
   5: 
   6: #include "hdr.h"
   7: #include <stdio.h>
   8: 
   9: 
  10: getin(wrd1,wrd2)                        /* get command from user        */
  11: char **wrd1,**wrd2;                     /* no prompt, usually           */
  12: {       register char *s;
  13:     static char wd1buf[MAXSTR],wd2buf[MAXSTR];
  14:     int first, numch;
  15: 
  16:     *wrd1=wd1buf;                   /* return ptr to internal string*/
  17:     *wrd2=wd2buf;
  18:     wd2buf[0]=0;                    /* in case it isn't set here    */
  19:     for (s=wd1buf, first=1, numch=0;;)
  20:     {       if ((*s=getchar())>='A' && *s <='Z') *s = *s - ('A' -'a');
  21:                     /* convert to upper case        */
  22:         if (feof(stdin)) {
  23:             clearerr(stdin);
  24:             continue;
  25:         }
  26:         switch(*s)              /* start reading from user      */
  27:         {   case '\n':
  28:             *s=0;
  29:             return;
  30:             case ' ':
  31:             if (s==wd1buf||s==wd2buf)  /* initial blank   */
  32:                 continue;
  33:             *s=0;
  34:             if (first)      /* finished 1st wd; start 2nd   */
  35:             {       first=numch=0;
  36:                 s=wd2buf;
  37:                 break;
  38:             }
  39:             else            /* finished 2nd word            */
  40:             {       FLUSHLINE;
  41:                 *s=0;
  42:                 return;
  43:             }
  44:             default:
  45:             if (++numch>=MAXSTR)    /* string too long      */
  46:             {       printf("Give me a break!!\n");
  47:                 wd1buf[0]=wd2buf[0]=0;
  48:                 FLUSHLINE;
  49:                 return;
  50:             }
  51:             s++;
  52:         }
  53:     }
  54: }
  55: 
  56: 
  57: confirm(mesg)                           /* confirm irreversible action  */
  58: char *mesg;
  59: {       register int result;
  60:     printf("%s",mesg);              /* tell him what he did         */
  61:     if (getchar()=='y')             /* was his first letter a 'y'?  */
  62:         result=1;
  63:     else    result=0;
  64:     FLUSHLINE;
  65:     return(result);
  66: }
  67: 
  68: yes(x,y,z)                              /* confirm with rspeak          */
  69: int x,y,z;
  70: {       register int result;
  71:     register char ch;
  72:     for (;;)
  73:     {       rspeak(x);                     /* tell him what we want*/
  74:         if ((ch=getchar())=='y')
  75:             result=TRUE;
  76:         else if (ch=='n') result=FALSE;
  77:         FLUSHLINE;
  78:         if (ch=='y'|| ch=='n') break;
  79:         printf("Please answer the question.\n");
  80:     }
  81:     if (result==TRUE) rspeak(y);
  82:     if (result==FALSE) rspeak(z);
  83:     return(result);
  84: }
  85: 
  86: yesm(x,y,z)                             /* confirm with mspeak          */
  87: int x,y,z;
  88: {       register int result;
  89:     register char ch;
  90:     for (;;)
  91:     {       mspeak(x);                     /* tell him what we want*/
  92:         if ((ch=getchar())=='y')
  93:             result=TRUE;
  94:         else if (ch=='n') result=FALSE;
  95:         FLUSHLINE;
  96:         if (ch=='y'|| ch=='n') break;
  97:         printf("Please answer the question.\n");
  98:     }
  99:     if (result==TRUE) mspeak(y);
 100:     if (result==FALSE) mspeak(z);
 101:     return(result);
 102: }
 103: 
 104: FILE *inbuf,*outbuf;
 105: 
 106: int adrptr;                             /* current seek adr ptr         */
 107: int outsw = 0;              /* putting stuff to data file?  */
 108: 
 109: char iotape[] = "Ax3F'tt$8hqer*hnGKrX:!l";
 110: char *tape = iotape;            /* pointer to encryption tape   */
 111: 
 112: next()                                  /* next char frm file, bump adr */
 113: {       register char ch,t;
 114:     adrptr++;                       /* seek address in file         */
 115:     ch=getc(inbuf);
 116:     if (outsw)                      /* putting data in tmp file     */
 117:     {       if (*tape==0) tape=iotape; /* rewind encryption tape    */
 118:         putc(ch ^ *tape++,outbuf); /* encrypt & output char     */
 119:     }
 120:     return(ch);
 121: }
 122: 
 123: 
 124: char breakch;                           /* tell which char ended rnum   */
 125: 
 126: 
 127: rdata()                                 /* read all data from orig file */
 128: {       register int sect;
 129:     register char ch;
 130:     if ((inbuf=fopen(DATFILE,"r"))==NULL)     /* all the data lives in here   */
 131:     {       printf("Cannot open data file %s\n",DATFILE);
 132:         exit(0);
 133:     }
 134:     if ((outbuf=fopen(TMPFILE,"w"))==NULL)   /* the text lines will go here  */
 135:     {       printf("Cannot create output file %s\n",TMPFILE);
 136:         exit(0);
 137:     }
 138:     setup=clsses=1;
 139:     for (;;)                        /* read data sections           */
 140:     {       sect=next()-'0';        /* 1st digit of section number  */
 141:         printf("Section %c",sect+'0');
 142:         if ((ch=next())!=LF)    /* is there a second digit?     */
 143:         {       FLUSHLF;
 144:             putchar(ch);
 145:             sect=10*sect+ch-'0';
 146:         }
 147:         putchar('\n');
 148:         switch(sect)
 149:         {   case 0:             /* finished reading database    */
 150:             fclose(inbuf);
 151:             fclose(outbuf);
 152:             return;
 153:             case 1:             /* long form descriptions       */
 154:             rdesc(1);
 155:             break;
 156:             case 2:             /* short form descriptions      */
 157:             rdesc(2);
 158:             break;
 159:             case 3:             /* travel table                 */
 160:             rtrav();   break;
 161:             case 4:             /* vocabulary                   */
 162:             rvoc();
 163:             break;
 164:             case 5:             /* object descriptions          */
 165:             rdesc(5);
 166:             break;
 167:             case 6:             /* arbitrary messages           */
 168:             rdesc(6);
 169:             break;
 170:             case 7:             /* object locations             */
 171:             rlocs();   break;
 172:             case 8:             /* action defaults              */
 173:             rdflt();   break;
 174:             case 9:             /* liquid assets                */
 175:             rliq();    break;
 176:             case 10:            /* class messages               */
 177:             rdesc(10);
 178:             break;
 179:             case 11:            /* hints                        */
 180:             rhints();  break;
 181:             case 12:            /* magic messages               */
 182:             rdesc(12);
 183:             break;
 184:             default:
 185:             printf("Invalid data section number: %d\n",sect);
 186:             for (;;) putchar(next());
 187:         }
 188:         if (breakch!=LF)        /* routines return after "-1"   */
 189:             FLUSHLF;
 190:     }
 191: }
 192: 
 193: char nbf[12];
 194: 
 195: 
 196: rnum()                                  /* read initial location num    */
 197: {       register char *s;
 198:     tape = iotape;                  /* restart encryption tape      */
 199:     for (s=nbf,*s=0;; s++)
 200:         if ((*s=next())==TAB || *s=='\n' || *s==LF)
 201:             break;
 202:     breakch= *s;                    /* save char for rtrav()        */
 203:     *s=0;                           /* got the number as ascii      */
 204:     if (nbf[0]=='-') return(-1);    /* end of data                  */
 205:     return(atoi(nbf));              /* convert it to integer        */
 206: }
 207: 
 208: int seekhere = 1;           /* initial seek for output file */
 209: 
 210: rdesc(sect)                             /* read description-format msgs */
 211: int sect;
 212: {       register char *s,*t;
 213:     register int locc;
 214:     int  seekstart, maystart, adrstart;
 215:     char *entry;
 216:     outsw=1;                        /* these msgs go into tmp file  */
 217:     if (sect==1) putc('X',outbuf);  /* so seekadr > 0               */
 218:     adrptr=0;
 219:     for (oldloc= -1, seekstart=seekhere;;)
 220:     {       maystart=adrptr;        /* maybe starting new entry     */
 221:         if ((locc=rnum())!=oldloc && oldloc>=0  /* finished msg */
 222:             && ! (sect==5 && (locc==0 || locc>=100)))/* unless sect 5*/
 223:         {       switch(sect)    /* now put it into right table  */
 224:             {   case 1:     /* long descriptions            */
 225:                 ltext[oldloc].seekadr=seekhere;
 226:                 ltext[oldloc].txtlen=maystart-seekstart;
 227:                 break;
 228:                 case 2:     /* short descriptions           */
 229:                 stext[oldloc].seekadr=seekhere;
 230:                 stext[oldloc].txtlen=maystart-seekstart;
 231:                 break;
 232:                 case 5:     /* object descriptions          */
 233:                 ptext[oldloc].seekadr=seekhere;
 234:                 ptext[oldloc].txtlen=maystart-seekstart;
 235:                 break;
 236:                 case 6:     /* random messages              */
 237:                 if (oldloc>RTXSIZ)
 238:                 {       printf("Too many random msgs\n");
 239:                     exit(0);
 240:                 }
 241:                 rtext[oldloc].seekadr=seekhere;
 242:                 rtext[oldloc].txtlen=maystart-seekstart;
 243:                 break;
 244:                 case 10:    /* class messages               */
 245:                 ctext[clsses].seekadr=seekhere;
 246:                 ctext[clsses].txtlen=maystart-seekstart;
 247:                 cval[clsses++]=oldloc;
 248:                 break;
 249:                 case 12:    /* magic messages               */
 250:                 if (oldloc>MAGSIZ)
 251:                 {       printf("Too many magic msgs\n");
 252:                     exit(0);
 253:                 }
 254:                 mtext[oldloc].seekadr=seekhere;
 255:                 mtext[oldloc].txtlen=maystart-seekstart;
 256:                 break;
 257:                 default:
 258:                 printf("rdesc called with bad section\n");
 259:                 exit(0);
 260:             }
 261:             seekhere += maystart-seekstart;
 262:         }
 263:         if (locc<0)
 264:         {       outsw=0;        /* turn off output              */
 265:             seekhere += 3;  /* -1<delimiter>                */
 266:             return;
 267:         }
 268:         if (sect!=5 || (locc>0 && locc<100))
 269:         {       if (oldloc!=locc)/* starting a new message       */
 270:                 seekstart=maystart;
 271:             oldloc=locc;
 272:         }
 273:         FLUSHLF;                /* scan the line                */
 274:     }
 275: }
 276: 
 277: 
 278: rtrav()                                 /* read travel table            */
 279: {       register int locc;
 280:     register struct travlist *t;
 281:     register char *s;
 282:     char buf[12];
 283:     int len,m,n,entries;
 284:     for (oldloc= -1;;)              /* get another line             */
 285:     {       if ((locc=rnum())!=oldloc && oldloc>=0) /* end of entry */
 286:         {
 287:             t->next = 0;    /* terminate the old entry      */
 288:         /*      printf("%d:%d entries\n",oldloc,entries);       */
 289:         /*      twrite(oldloc);                                 */
 290:         }
 291:         if (locc== -1) return;
 292:         if (locc!=oldloc)        /* getting a new entry         */
 293:         {       t=travel[locc]=(struct travlist *) malloc(sizeof (struct travlist));
 294:         /*      printf("New travel list for %d\n",locc);        */
 295:             entries=0;
 296:             oldloc=locc;
 297:         }
 298:         for (s=buf;; *s++)      /* get the newloc number /ASCII */
 299:             if ((*s=next())==TAB || *s==LF) break;
 300:         *s=0;
 301:         len=length(buf)-1;      /* quad long number handling    */
 302:     /*      printf("Newloc: %s (%d chars)\n",buf,len);              */
 303:         if (len<4)              /* no "m" conditions            */
 304:         {       m=0;
 305:             n=atoi(buf);    /* newloc mod 1000 = newloc     */
 306:         }
 307:         else                    /* a long integer               */
 308:         {       n=atoi(buf+len-3);
 309:             buf[len-3]=0;   /* terminate newloc/1000        */
 310:             m=atoi(buf);
 311:         }
 312:         while (breakch!=LF)     /* only do one line at a time   */
 313:         {       if (entries++) t=t->next=(struct travlist *) malloc(sizeof (struct travlist));
 314:             t->tverb=rnum();/* get verb from the file       */
 315:             t->tloc=n;      /* table entry mod 1000         */
 316:             t->conditions=m;/* table entry / 1000           */
 317:         /*      printf("entry %d for %d\n",entries,locc);       */
 318:         }
 319:     }
 320: }
 321: 
 322: 
 323: twrite(loq)                             /* travel options from this loc */
 324: int loq;
 325: {       register struct travlist *t;
 326:     printf("If");
 327:     speak(&ltext[loq]);
 328:     printf("then\n");
 329:     for (t=travel[loq]; t!=0; t=t->next)
 330:     {       printf("verb %d takes you to ",t->tverb);
 331:         if (t->tloc<=300)
 332:             speak(&ltext[t->tloc]);
 333:         else if (t->tloc<=500)
 334:             printf("special code %d\n",t->tloc-300);
 335:         else
 336:             rspeak(t->tloc-500);
 337:         printf("under conditions %d\n",t->conditions);
 338:     }
 339: }
 340: 
 341: 
 342: 
 343: rvoc()
 344: {       register char *s;               /* read the vocabulary          */
 345:     register int index;
 346:     char buf[6];
 347:     for (;;)
 348:     {       index=rnum();
 349:         if (index<0) break;
 350:         for (s=buf,*s=0;; s++)  /* get the word                 */
 351:             if ((*s=next())==TAB || *s=='\n' || *s==LF
 352:                 || *s==' ') break;
 353:             /* terminate word with newline, LF, tab, blank  */
 354:         if (*s!='\n' && *s!=LF) FLUSHLF;  /* can be comments    */
 355:         *s=0;
 356:     /*      printf("\"%s\"=%d\n",buf,index);*/
 357:         vocab(buf,-2,index);
 358:     }
 359: /*	prht();	*/
 360: }
 361: 
 362: 
 363: rlocs()                                 /* initial object locations     */
 364: {   for (;;)
 365:     {       if ((obj=rnum())<0) break;
 366:         plac[obj]=rnum();       /* initial loc for this obj     */
 367:         if (breakch==TAB)       /* there's another entry        */
 368:             fixd[obj]=rnum();
 369:         else    fixd[obj]=0;
 370:     }
 371: }
 372: 
 373: rdflt()                                 /* default verb messages        */
 374: {   for (;;)
 375:     {       if ((verb=rnum())<0) break;
 376:         actspk[verb]=rnum();
 377:     }
 378: }
 379: 
 380: rliq()                                  /* liquid assets &c: cond bits  */
 381: {       register int bitnum;
 382:     for (;;)                        /* read new bit list            */
 383:     {       if ((bitnum=rnum())<0) break;
 384:         for (;;)                /* read locs for bits           */
 385:         {       cond[rnum()] |= setbit[bitnum];
 386:             if (breakch==LF) break;
 387:         }
 388:     }
 389: }
 390: 
 391: rhints()
 392: {       register int hintnum,i;
 393:     hntmax=0;
 394:     for (;;)
 395:     {       if ((hintnum=rnum())<0) break;
 396:         for (i=1; i<5; i++)
 397:             hints[hintnum][i]=rnum();
 398:         if (hintnum>hntmax) hntmax=hintnum;
 399:     }
 400: }
 401: 
 402: 
 403: rspeak(msg)
 404: int msg;
 405: {       if (msg!=0) speak(&rtext[msg]);
 406: }
 407: 
 408: 
 409: mspeak(msg)
 410: int msg;
 411: {       if (msg!=0) speak(&mtext[msg]);
 412: }
 413: 
 414: 
 415: doseek(offset)  /* do 2 seeks to get to right place in the file         */
 416: unsigned offset;
 417: {
 418:     extern unsigned filesize;
 419:     lseek(datfd,(long)offset+(long)filesize, 0);
 420: #ifdef notdef
 421:     blockadr=chadr=0;
 422:     if (offset<0)                   /* right place is offset+filesize*/
 423:     {       blockadr += 64;         /* take off 32768 bytes         */
 424:         chadr += offset+32768;  /* & make them into 64 blocks   */
 425:     }
 426:     else chadr += offset;
 427:     if (filesize<0)                 /* data starts after file       */
 428:     {       blockadr += 64;         /* which may also be large      */
 429:         chadr += filesize+32768;
 430:     }
 431:     else chadr += filesize;
 432:     if (chadr<0)                    /* and the leftovers may be lge */
 433:     {       blockadr += 64;
 434:         chadr += 32768;
 435:     }
 436:     seek(datfd,blockadr,3);         /* get within 32767             */
 437:     seek(datfd,chadr,1);            /* then the rest of the way     */
 438: #endif
 439: }
 440: 
 441: 
 442: speak(msg)       /* read, decrypt, and print a message (not ptext)      */
 443: struct text *msg;/* msg is a pointer to seek address and length of mess */
 444: {       register char *s,nonfirst;
 445:     register char *tbuf;
 446:     doseek(msg->seekadr);
 447:     if ((tbuf=(char *) malloc(msg->txtlen+1))<0) bug(109);
 448:     read(datfd,tbuf,msg->txtlen);
 449:     s=tbuf;
 450:     nonfirst=0;
 451:     while (s-tbuf<msg->txtlen)      /* read a line at a time        */
 452:     {       tape=iotape;            /* restart decryption tape      */
 453:         while ((*s++^*tape++)!=TAB); /* read past loc num       */
 454:         /* assume tape is longer than location number           */
 455:         /*   plus the lookahead put together                    */
 456:         if ((*s^*tape)=='>' &&
 457:             (*(s+1)^*(tape+1))=='$' &&
 458:             (*(s+2)^*(tape+2))=='<') break;
 459:         if (blklin&&!nonfirst++) putchar('\n');
 460:         do
 461:         {       if (*tape==0) tape=iotape;/* rewind decryp tape */
 462:             putchar(*s^*tape);
 463:         } while ((*s++^*tape++)!=LF);   /* better end with LF   */
 464:     }
 465:     free(tbuf);
 466: }
 467: 
 468: 
 469: pspeak(msg,skip) /* read, decrypt an print a ptext message              */
 470: int msg;         /* msg is the number of all the p msgs for this place  */
 471: int skip;       /* assumes object 1 doesn't have prop 1, obj 2 no prop 2 &c*/
 472: {       register char *s,nonfirst;
 473:     register char *tbuf;
 474:     char *numst;
 475:     int lstr;
 476:     doseek(ptext[msg].seekadr);
 477:     if ((tbuf=(char *) malloc((lstr=ptext[msg].txtlen)+1))<0) bug(108);
 478:     read(datfd,tbuf,lstr);
 479:     s=tbuf;
 480:     nonfirst=0;
 481:     while (s-tbuf<lstr)             /* read a line at a time        */
 482:     {       tape=iotape;            /* restart decryption tape      */
 483:         for (numst=s; (*s^= *tape++)!=TAB; s++); /* get number  */
 484:         *s++=0; /* decrypting number within the string          */
 485:         if (atoi(numst)!=100*skip && skip>=0)
 486:         {       while ((*s++^*tape++)!=LF) /* flush the line    */
 487:                 if (*tape==0) tape=iotape;
 488:             continue;
 489:         }
 490:         if ((*s^*tape)=='>' && (*(s+1)^*(tape+1))=='$' &&
 491:             (*(s+2)^*(tape+2))=='<') break;
 492:         if (blklin && ! nonfirst++) putchar('\n');
 493:         do
 494:         {       if (*tape==0) tape=iotape;
 495:             putchar(*s^*tape);
 496:         } while ((*s++^*tape++)!=LF);   /* better end with LF   */
 497:         if (skip<0) break;
 498:     }
 499:     free(tbuf);
 500: }

Defined functions

confirm defined in line 57; used 1 times
doseek defined in line 415; used 2 times
mspeak defined in line 409; used 10 times
next defined in line 112; used 11 times
pspeak defined in line 469; used 10 times
rdata defined in line 127; used 1 times
rdesc defined in line 210; used 6 times
rdflt defined in line 373; used 1 times
rhints defined in line 391; used 1 times
rliq defined in line 380; used 1 times
rlocs defined in line 363; used 1 times
rnum defined in line 196; used 13 times
rspeak defined in line 403; used 53 times
rtrav defined in line 278; used 1 times
rvoc defined in line 343; used 1 times
speak defined in line 442; used 6 times
twrite defined in line 323; never used
yesm defined in line 86; used 1 times

Defined variables

adrptr defined in line 106; used 3 times
breakch defined in line 124; used 5 times
iotape defined in line 109; used 8 times
nbf defined in line 193; used 3 times
outsw defined in line 107; used 3 times
sccsid defined in line 4; never used
seekhere defined in line 208; used 9 times
tape defined in line 110; used 25 times
Last modified: 1987-08-26
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3908
Valid CSS Valid XHTML 1.0 Strict