File: | src/games/adventure/io.c |
Warning: | line 565, column 3 Value stored to 'save' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* $OpenBSD: io.c,v 1.23 2017/06/23 12:56:25 fcambus Exp $ */ |
2 | /* $NetBSD: io.c,v 1.3 1995/04/24 12:21:37 cgd Exp $ */ |
3 | |
4 | /*- |
5 | * Copyright (c) 1991, 1993 |
6 | * The Regents of the University of California. All rights reserved. |
7 | * |
8 | * The game adventure was originally written in Fortran by Will Crowther |
9 | * and Don Woods. It was later translated to C and enhanced by Jim |
10 | * Gillogly. This code is derived from software contributed to Berkeley |
11 | * by Jim Gillogly at The Rand Corporation. |
12 | * |
13 | * Redistribution and use in source and binary forms, with or without |
14 | * modification, are permitted provided that the following conditions |
15 | * are met: |
16 | * 1. Redistributions of source code must retain the above copyright |
17 | * notice, this list of conditions and the following disclaimer. |
18 | * 2. Redistributions in binary form must reproduce the above copyright |
19 | * notice, this list of conditions and the following disclaimer in the |
20 | * documentation and/or other materials provided with the distribution. |
21 | * 3. Neither the name of the University nor the names of its contributors |
22 | * may be used to endorse or promote products derived from this software |
23 | * without specific prior written permission. |
24 | * |
25 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
26 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
28 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
33 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
34 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
35 | * SUCH DAMAGE. |
36 | */ |
37 | |
38 | /* Re-coding of advent in C: file i/o and user i/o */ |
39 | |
40 | #include <err.h> |
41 | #include <stdio.h> |
42 | #include <stdlib.h> |
43 | |
44 | #include "extern.h" |
45 | #include "hdr.h" |
46 | |
47 | /* Get command from user. No prompt, usually. */ |
48 | void |
49 | getin(char *wrd1, size_t siz1, char *wrd2, size_t siz2) |
50 | { |
51 | char *s, *slast; |
52 | int ch, first; |
53 | |
54 | *wrd2 = 0; /* in case it isn't set here */ |
55 | for (s = wrd1, first = 1, slast = wrd1 + siz1 - 1;;) { |
56 | if ((ch = getchar()(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget( (&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc) ((&__sF[0])))) >= 'A' && ch <= 'Z') |
57 | ch = ch - ('A' - 'a'); |
58 | /* convert to upper case */ |
59 | switch (ch) { /* start reading from user */ |
60 | case '\n': |
61 | *s = 0; |
62 | return; |
63 | case ' ': |
64 | if (s == wrd1 || s == wrd2) /* initial blank */ |
65 | continue; |
66 | *s = 0; |
67 | if (first) { /* finished 1st wd; start 2nd */ |
68 | first = 0; |
69 | s = wrd2; |
70 | slast = wrd2 + siz2 - 1; |
71 | break; |
72 | } else { /* finished 2nd word */ |
73 | FLUSHLINEdo { int c; while ((c = (!__isthreaded ? (--((&__sF[0]))-> _r < 0 ? __srget((&__sF[0])) : (int)(*((&__sF[0])) ->_p++)) : (getc)((&__sF[0])))) != (-1) && c != '\n'); } while (0); |
74 | *s = 0; |
75 | return; |
76 | } |
77 | case EOF(-1): |
78 | printf("user closed input stream, quitting...\n"); |
79 | exit(0); |
80 | default: |
81 | if (s == slast) { /* string too long */ |
82 | printf("Give me a break!!\n"); |
83 | *wrd1 = *wrd2 = 0; |
84 | FLUSHLINEdo { int c; while ((c = (!__isthreaded ? (--((&__sF[0]))-> _r < 0 ? __srget((&__sF[0])) : (int)(*((&__sF[0])) ->_p++)) : (getc)((&__sF[0])))) != (-1) && c != '\n'); } while (0); |
85 | return; |
86 | } |
87 | *s++ = ch; |
88 | } |
89 | } |
90 | } |
91 | |
92 | int |
93 | yes(int x, int y, int z) /* confirm with rspeak */ |
94 | { |
95 | int result; |
96 | int ch; |
97 | |
98 | for (;;) { |
99 | rspeak(x); /* tell him what we want*/ |
100 | if ((ch = getchar()(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget( (&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc) ((&__sF[0]))))=='y') |
101 | result = TRUE1; |
102 | else if (ch=='n') |
103 | result = FALSE0; |
104 | else if (ch == EOF(-1)) { |
105 | printf("user closed input stream, quitting...\n"); |
106 | exit(0); |
107 | } |
108 | if (ch != '\n') |
109 | FLUSHLINEdo { int c; while ((c = (!__isthreaded ? (--((&__sF[0]))-> _r < 0 ? __srget((&__sF[0])) : (int)(*((&__sF[0])) ->_p++)) : (getc)((&__sF[0])))) != (-1) && c != '\n'); } while (0); |
110 | if (ch == 'y' || ch == 'n') |
111 | break; |
112 | printf("Please answer the question.\n"); |
113 | } |
114 | if (result == TRUE1) |
115 | rspeak(y); |
116 | if (result == FALSE0) |
117 | rspeak(z); |
118 | return (result); |
119 | } |
120 | |
121 | int |
122 | yesm(int x, int y, int z) /* confirm with mspeak */ |
123 | { |
124 | int result; |
125 | int ch; |
126 | |
127 | for (;;) { |
128 | mspeak(x); /* tell him what we want */ |
129 | if ((ch = getchar()(!__isthreaded ? (--((&__sF[0]))->_r < 0 ? __srget( (&__sF[0])) : (int)(*((&__sF[0]))->_p++)) : (getc) ((&__sF[0])))) == 'y') |
130 | result = TRUE1; |
131 | else if (ch == 'n') |
132 | result = FALSE0; |
133 | else if (ch == EOF(-1)) { |
134 | printf("user closed input stream, quitting...\n"); |
135 | exit(0); |
136 | } |
137 | if (ch != '\n') |
138 | FLUSHLINEdo { int c; while ((c = (!__isthreaded ? (--((&__sF[0]))-> _r < 0 ? __srget((&__sF[0])) : (int)(*((&__sF[0])) ->_p++)) : (getc)((&__sF[0])))) != (-1) && c != '\n'); } while (0); |
139 | if (ch == 'y' || ch == 'n') |
140 | break; |
141 | printf("Please answer the question.\n"); |
142 | } |
143 | if (result == TRUE1) |
144 | mspeak(y); |
145 | if (result == FALSE0) |
146 | mspeak(z); |
147 | return (result); |
148 | } |
149 | |
150 | /* FILE *inbuf,*outbuf; */ |
151 | |
152 | char *inptr; /* Pointer into virtual disk */ |
153 | |
154 | int outsw = 0; /* putting stuff to data file? */ |
155 | |
156 | const char iotape[] = "Ax3F'\003tt$8h\315qer*h\017nGKrX\207:!l"; |
157 | const char *tape = iotape; /* pointer to obfuscation tape */ |
158 | |
159 | int |
160 | next(void) /* next virtual char, bump adr */ |
161 | { |
162 | int ch; |
163 | |
164 | ch=(*inptr ^ random()) & 0xFF; /* Deobfuscate input data */ |
165 | if (outsw) { /* putting data in tmp file */ |
166 | if (*tape == 0) |
167 | tape = iotape; /* rewind obfuscation tape */ |
168 | *inptr = ch ^ *tape++; /* re-obfuscate and replace value */ |
169 | } |
170 | inptr++; |
171 | return (ch); |
172 | } |
173 | |
174 | char breakch; /* tell which char ended rnum */ |
175 | |
176 | void |
177 | rdata(void) /* "read" data from virtual file */ |
178 | { |
179 | int sect; |
180 | char ch; |
181 | |
182 | inptr = data_file; /* Pointer to virtual data file */ |
183 | |
184 | clsses = 1; |
185 | for (;;) { /* read data sections */ |
186 | sect = next() - '0'; /* 1st digit of section number */ |
187 | #ifdef VERBOSE |
188 | printf("Section %c", sect + '0'); |
189 | #endif |
190 | if ((ch = next()) != LF012) { /* is there a second digit? */ |
191 | FLUSHLFwhile (next()!=012); |
192 | #ifdef VERBOSE |
193 | putchar(ch)(!__isthreaded ? __sputc(ch, (&__sF[1])) : (putc)(ch, (& __sF[1]))); |
194 | #endif |
195 | sect = 10 * sect + ch - '0'; |
196 | } |
197 | #ifdef VERBOSE |
198 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); |
199 | #endif |
200 | switch (sect) { |
201 | case 0: /* finished reading database */ |
202 | return; |
203 | case 1: /* long form descriptions */ |
204 | rdesc(1); |
205 | break; |
206 | case 2: /* short form descriptions */ |
207 | rdesc(2); |
208 | break; |
209 | case 3: /* travel table */ |
210 | rtrav(); |
211 | break; |
212 | case 4: /* vocabulary */ |
213 | rvoc(); |
214 | break; |
215 | case 5: /* object descriptions */ |
216 | rdesc(5); |
217 | break; |
218 | case 6: /* arbitrary messages */ |
219 | rdesc(6); |
220 | break; |
221 | case 7: /* object locations */ |
222 | rlocs(); |
223 | break; |
224 | case 8: /* action defaults */ |
225 | rdflt(); |
226 | break; |
227 | case 9: /* liquid assets */ |
228 | rliq(); |
229 | break; |
230 | case 10: /* class messages */ |
231 | rdesc(10); |
232 | break; |
233 | case 11: /* hints */ |
234 | rhints(); |
235 | break; |
236 | case 12: /* magic messages */ |
237 | rdesc(12); |
238 | break; |
239 | default: |
240 | printf("Invalid data section number: %d\n", sect); |
241 | for (;;) |
242 | putchar(next())(!__isthreaded ? __sputc(next(), (&__sF[1])) : (putc)(next (), (&__sF[1]))); |
243 | } |
244 | if (breakch != LF012) /* routines return after "-1" */ |
245 | FLUSHLFwhile (next()!=012); |
246 | } |
247 | } |
248 | |
249 | char nbf[12]; |
250 | |
251 | |
252 | int |
253 | rnum(void) /* read initial location num */ |
254 | { |
255 | char *s; |
256 | |
257 | tape = iotape; /* restart obfuscation tape */ |
258 | for (s = nbf, *s = 0;; s++) |
259 | if ((*s = next()) == TAB011 || *s == '\n' || *s == LF012) |
260 | break; |
261 | breakch = *s; /* save char for rtrav() */ |
262 | *s = 0; /* got the number as ascii */ |
263 | if (nbf[0] == '-') |
264 | return (-1); /* end of data */ |
265 | return (atoi(nbf)); /* convert it to integer */ |
266 | } |
267 | |
268 | char *seekhere; |
269 | |
270 | void |
271 | rdesc(int sect) /* read description-format msgs */ |
272 | { |
273 | int locc; |
274 | char *seekstart, *maystart; |
275 | |
276 | seekhere = inptr; /* Where are we in virtual file?*/ |
277 | outsw = 1; /* these msgs go into tmp file */ |
278 | for (oldloc = -1, seekstart = seekhere;;) { |
279 | maystart = inptr; /* maybe starting new entry */ |
280 | if ((locc = rnum()) != oldloc && oldloc >= 0 /* finished msg */ |
281 | && !(sect == 5 && (locc == 0 || locc >= 100)))/* unless sect 5*/ |
282 | { |
283 | switch (sect) { /* now put it into right table */ |
284 | case 1: /* long descriptions */ |
285 | ltext[oldloc].seekadr = seekhere; |
286 | ltext[oldloc].txtlen = maystart - seekstart; |
287 | break; |
288 | case 2: /* short descriptions */ |
289 | stext[oldloc].seekadr = seekhere; |
290 | stext[oldloc].txtlen = maystart - seekstart; |
291 | break; |
292 | case 5: /* object descriptions */ |
293 | ptext[oldloc].seekadr = seekhere; |
294 | ptext[oldloc].txtlen = maystart - seekstart; |
295 | break; |
296 | case 6: /* random messages */ |
297 | if (oldloc >= RTXSIZ205) |
298 | errx(1, "Too many random msgs"); |
299 | rtext[oldloc].seekadr = seekhere; |
300 | rtext[oldloc].txtlen = maystart - seekstart; |
301 | break; |
302 | case 10:/* class messages */ |
303 | ctext[clsses].seekadr = seekhere; |
304 | ctext[clsses].txtlen = maystart - seekstart; |
305 | cval[clsses++] = oldloc; |
306 | break; |
307 | case 12:/* magic messages */ |
308 | if (oldloc >= MAGSIZ35) |
309 | errx(1, "Too many magic msgs"); |
310 | mtext[oldloc].seekadr = seekhere; |
311 | mtext[oldloc].txtlen = maystart - seekstart; |
312 | break; |
313 | default: |
314 | errx(1, "rdesc called with bad section"); |
315 | } |
316 | seekhere += maystart - seekstart; |
317 | } |
318 | if (locc < 0) { |
319 | outsw = 0; /* turn off output */ |
320 | seekhere += 3; /* -1<delimiter> */ |
321 | return; |
322 | } |
323 | if (sect != 5 || (locc > 0 && locc < 100)) { |
324 | if (oldloc != locc)/* starting a new message */ |
325 | seekstart = maystart; |
326 | oldloc = locc; |
327 | } |
328 | FLUSHLFwhile (next()!=012); /* scan the line */ |
329 | } |
330 | } |
331 | |
332 | |
333 | void |
334 | rtrav(void) /* read travel table */ |
335 | { |
336 | int locc; |
337 | struct travlist *t; |
338 | char *s; |
339 | char buf[12]; |
340 | int len, m, n, entries; |
341 | |
342 | for (oldloc = -1;;) { /* get another line */ |
343 | if ((locc = rnum()) != oldloc && oldloc >= 0) { /* end of entry */ |
344 | t->next = NULL((void *)0); /* terminate the old entry */ |
345 | /* printf("%d:%d entries\n", oldloc, entries); */ |
346 | /* twrite(oldloc); */ |
347 | } |
348 | if (locc == -1) |
349 | return; |
350 | if (locc != oldloc) { /* getting a new entry */ |
351 | t = travel[locc] = calloc(1, sizeof(*t)); |
352 | if (t == NULL((void *)0)) |
353 | err(1, NULL((void *)0)); |
354 | /* printf("New travel list for %d\n", locc); */ |
355 | entries = 0; |
356 | oldloc = locc; |
357 | } |
358 | for (s = buf; ; s++) /* get the newloc number /ASCII */ |
359 | if ((*s = next()) == TAB011 || *s == LF012) |
360 | break; |
361 | *s = 0; |
362 | len = length(buf)(strlen((buf)) + 1) - 1; /* quad long number handling */ |
363 | /* printf("Newloc: %s (%d chars)\n", buf, len); */ |
364 | if (len < 4) { /* no "m" conditions */ |
365 | m = 0; |
366 | n = atoi(buf); /* newloc mod 1000 = newloc */ |
367 | } else { /* a long integer */ |
368 | n = atoi(buf + len - 3); |
369 | buf[len - 3] = 0; /* terminate newloc/1000*/ |
370 | m = atoi(buf); |
371 | } |
372 | while (breakch != LF012) { /* only do one line at a time */ |
373 | if (t == NULL((void *)0)) |
374 | errx(1, "corrupt file"); |
375 | if (entries++) { |
376 | t->next = calloc(1, sizeof (*t->next)); |
377 | if (t->next == NULL((void *)0)) |
378 | err(1, NULL((void *)0)); |
379 | t = t->next; |
380 | } |
381 | t->tverb = rnum();/* get verb from the file */ |
382 | t->tloc = n; /* table entry mod 1000 */ |
383 | t->conditions = m;/* table entry / 1000 */ |
384 | /* printf("entry %d for %d\n", entries, locc); */ |
385 | } |
386 | } |
387 | } |
388 | |
389 | #ifdef DEBUG |
390 | |
391 | void |
392 | twrite(int loq) /* travel options from this loc */ |
393 | { |
394 | struct travlist *t; |
395 | |
396 | printf("If"); |
397 | speak(<ext[loq]); |
398 | printf("then\n"); |
399 | for (t = travel[loq]; t != 0; t = t->next) { |
400 | printf("verb %d takes you to ", t->tverb); |
401 | if (t->tloc <= 300) |
402 | speak(<ext[t->tloc]); |
403 | else if (t->tloc <= 500) |
404 | printf("special code %d\n", t->tloc - 300); |
405 | else |
406 | rspeak(t->tloc - 500); |
407 | printf("under conditions %d\n", t->conditions); |
408 | } |
409 | } |
410 | #endif /* DEBUG */ |
411 | |
412 | void |
413 | rvoc(void) |
414 | { |
415 | char *s; /* read the vocabulary */ |
416 | int index; |
417 | char buf[6]; |
418 | |
419 | for (;;) { |
420 | index = rnum(); |
421 | if (index < 0) |
422 | break; |
423 | for (s = buf, *s = 0;; s++) /* get the word */ |
424 | if ((*s = next()) == TAB011 || *s == '\n' || *s == LF012 |
425 | || *s == ' ') |
426 | break; |
427 | /* terminate word with newline, LF, tab, blank */ |
428 | if (*s != '\n' && *s != LF012) |
429 | FLUSHLFwhile (next()!=012); /* can be comments */ |
430 | *s = 0; |
431 | /* printf("\"%s\"=%d\n", buf, index);*/ |
432 | vocab(buf, -2, index); |
433 | } |
434 | /* prht(); */ |
435 | } |
436 | |
437 | |
438 | void |
439 | rlocs(void) /* initial object locations */ |
440 | { |
441 | for (;;) { |
442 | if ((obj = rnum()) < 0) |
443 | break; |
444 | plac[obj] = rnum(); /* initial loc for this obj */ |
445 | if (breakch == TAB011) /* there's another entry */ |
446 | fixd[obj] = rnum(); |
447 | else |
448 | fixd[obj] = 0; |
449 | } |
450 | } |
451 | |
452 | void |
453 | rdflt(void) /* default verb messages */ |
454 | { |
455 | for (;;) { |
456 | if ((verb = rnum()) < 0) |
457 | break; |
458 | actspk[verb] = rnum(); |
459 | } |
460 | } |
461 | |
462 | void |
463 | rliq(void) /* liquid assets &c: cond bits */ |
464 | { |
465 | int bitnum; |
466 | |
467 | for (;;) { /* read new bit list */ |
468 | if ((bitnum = rnum()) < 0) |
469 | break; |
470 | for (;;) { /* read locs for bits */ |
471 | cond[rnum()] |= setbit[bitnum]; |
472 | if (breakch == LF012) |
473 | break; |
474 | } |
475 | } |
476 | } |
477 | |
478 | void |
479 | rhints(void) |
480 | { |
481 | int hintnum, i; |
482 | |
483 | hntmax = 0; |
484 | for (;;) { |
485 | if ((hintnum = rnum()) < 0) |
486 | break; |
487 | for (i = 1; i < 5; i++) |
488 | hints[hintnum][i] = rnum(); |
489 | if (hintnum > hntmax) |
490 | hntmax = hintnum; |
491 | } |
492 | } |
493 | |
494 | |
495 | void |
496 | rspeak(int msg) |
497 | { |
498 | if (msg != 0) |
499 | speak(&rtext[msg]); |
500 | } |
501 | |
502 | |
503 | void |
504 | mspeak(int msg) |
505 | { |
506 | if (msg != 0) |
507 | speak(&mtext[msg]); |
508 | } |
509 | |
510 | /* |
511 | * Read, deobfuscate, and print a message (not ptext) |
512 | * msg is a pointer to seek address and length of mess |
513 | */ |
514 | void |
515 | speak(const struct text *msg) |
516 | { |
517 | char *s, nonfirst; |
518 | |
519 | s = msg->seekadr; |
520 | nonfirst = 0; |
521 | while (s - msg->seekadr < msg->txtlen) { /* read a line at a time */ |
522 | tape = iotape; /* restart deobfuscation tape */ |
523 | while ((*s++ ^ *tape++) != TAB011); /* read past loc num */ |
524 | /* assume tape is longer than location number */ |
525 | /* plus the lookahead put together */ |
526 | if ((*s ^ *tape) == '>' && |
527 | (*(s + 1) ^ *(tape + 1)) == '$' && |
528 | (*(s + 2) ^ *(tape + 2)) == '<') |
529 | break; |
530 | if (blklin && !nonfirst++) |
531 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); |
532 | do { |
533 | if (*tape == 0) |
534 | tape = iotape;/* rewind decryp tape */ |
535 | putchar(*s ^ *tape)(!__isthreaded ? __sputc(*s ^ *tape, (&__sF[1])) : (putc) (*s ^ *tape, (&__sF[1]))); |
536 | } while ((*s++ ^ *tape++) != LF012); /* better end with LF */ |
537 | } |
538 | } |
539 | |
540 | /* |
541 | * Read, deobfuscate, and print a ptext message |
542 | * msg is the number of all the p msgs for this place |
543 | * assumes object 1 doesn't have prop 1, obj 2 no prop 2 &c |
544 | */ |
545 | void |
546 | pspeak(int m, int skip) |
547 | { |
548 | char *s, nonfirst; |
549 | char *numst, save; |
550 | struct text *msg; |
551 | char *tbuf; |
552 | |
553 | msg = &ptext[m]; |
554 | if ((tbuf = malloc(msg->txtlen + 1)) == 0) |
555 | err(1, NULL((void *)0)); |
556 | memcpy(tbuf, msg->seekadr, msg->txtlen + 1); /* Room to null */ |
557 | s = tbuf; |
558 | |
559 | nonfirst = 0; |
560 | while (s - tbuf < msg->txtlen) { /* read line at a time */ |
561 | tape = iotape; /* restart dobfuscation tape */ |
562 | for (numst = s; (*s ^= *tape++) != TAB011; s++) |
563 | ; /* get number */ |
564 | |
565 | save = *s; /* Temporarily trash the string (cringe) */ |
Value stored to 'save' is never read | |
566 | *s++ = 0; /* deobfuscation number within the string */ |
567 | |
568 | if (atoi(numst) != 100 * skip && skip >= 0) { |
569 | while ((*s++ ^ * tape++) != LF012) /* flush the line */ |
570 | if (*tape == 0) |
571 | tape = iotape; |
572 | continue; |
573 | } |
574 | if ((*s^ * tape) == '>' && (*(s + 1) ^ * (tape + 1)) == '$' && |
575 | (*(s + 2) ^ * (tape + 2)) == '<') |
576 | break; |
577 | if (blklin && !nonfirst++) |
578 | putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n', (&__sF[1]))); |
579 | do { |
580 | if (*tape == 0) |
581 | tape = iotape; |
582 | putchar(*s^ * tape)(!__isthreaded ? __sputc(*s^ * tape, (&__sF[1])) : (putc) (*s^ * tape, (&__sF[1]))); |
583 | } while ((*s++ ^ * tape++) != LF012); /* better end with LF */ |
584 | if (skip < 0) |
585 | break; |
586 | } |
587 | free(tbuf); |
588 | } |