Fixed directory printing in case there was both a ~user and a ~user1.
[unix-history] / usr / src / bin / csh / lex.c
CommitLineData
ecc449eb
KB
1/*-
2 * Copyright (c) 1980, 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * %sccs.include.redist.c%
b79f4fa9
DF
6 */
7
5b182e7a 8#ifndef lint
abf583a4 9static char sccsid[] = "@(#)lex.c 5.26 (Berkeley) %G%";
b9c4f741 10#endif /* not lint */
3802e2ef 11
b9c4f741
KB
12#include <sys/types.h>
13#include <sys/ioctl.h>
14#include <termios.h>
15#include <errno.h>
16#include <stdlib.h>
17#include <string.h>
18#include <unistd.h>
4df6491c
CZ
19#if __STDC__
20# include <stdarg.h>
21#else
22# include <varargs.h>
23#endif
24
4d7b2685
KB
25#include "csh.h"
26#include "extern.h"
3802e2ef
BJ
27
28/*
29 * These lexical routines read input and form lists of words.
30 * There is some involved processing here, because of the complications
31 * of input buffering, and especially because of history substitution.
32 */
33
0aec749d
CZ
34static Char *word __P((void));
35static int getC1 __P((int));
36static void getdol __P((void));
37static void getexcl __P((int));
c28e64a2 38static struct Hist
0aec749d
CZ
39 *findev __P((Char *, bool));
40static void setexclp __P((Char *));
41static int bgetc __P((void));
42static void bfree __P((void));
c28e64a2 43static struct wordent
0aec749d
CZ
44 *gethent __P((int));
45static int matchs __P((Char *, Char *));
46static int getsel __P((int *, int *, int));
c28e64a2 47static struct wordent
0aec749d 48 *getsub __P((struct wordent *));
c28e64a2
CL
49static Char *subword __P((Char *, int, bool *));
50static struct wordent
0aec749d 51 *dosub __P((int, struct wordent *, bool));
3802e2ef
BJ
52
53/*
6e37afca 54 * Peekc is a peek character for getC, peekread for readc.
3802e2ef
BJ
55 * There is a subtlety here in many places... history routines
56 * will read ahead and then insert stuff into the input stream.
57 * If they push back a character then they must push it behind
58 * the text substituted by the history substitution. On the other
59 * hand in several places we need 2 peek characters. To make this
60 * all work, the history routines read with getC, and make use both
61 * of ungetC and unreadc. The key observation is that the state
62 * of getC at the call of a history reference is such that calls
63 * to getC from the history routines will always yield calls of
64 * readc, unless this peeking is involved. That is to say that during
65 * getexcl the variables lap, exclp, and exclnxt are all zero.
66 *
67 * Getdol invokes history substitution, hence the extra peek, peekd,
68 * which it can ungetD to be before history substitutions.
69 */
6e37afca
KB
70static Char peekc = 0, peekd = 0;
71static Char peekread = 0;
72
73/* (Tail of) current word from ! subst */
b9c4f741 74static Char *exclp = NULL;
6e37afca
KB
75
76/* The rest of the ! subst words */
b9c4f741 77static struct wordent *exclnxt = NULL;
3802e2ef 78
6e37afca
KB
79/* Count of remaining words in ! subst */
80static int exclc = 0;
81
82/* "Globp" for alias resubstitution */
b175c694 83Char *alvecp = NULL;
c4a58397 84int aret = F_SEEK;
6e37afca
KB
85
86/*
87 * Labuf implements a general buffer for lookahead during lexical operations.
88 * Text which is to be placed in the input stream can be stuck here.
89 * We stick parsed ahead $ constructs during initial input,
90 * process id's from `$$', and modified variable values (from qualifiers
91 * during expansion in sh.dol.c) here.
92 */
93static Char labuf[BUFSIZ];
3802e2ef
BJ
94
95/*
96 * Lex returns to its caller not only a wordlist (as a "var" parameter)
97 * but also whether a history substitution occurred. This is used in
98 * the main (process) routine to determine whether to echo, and also
99 * when called by the alias routine to determine whether to keep the
100 * argument list.
101 */
6e37afca
KB
102static bool hadhist = 0;
103
104/*
105 * Avoid alias expansion recursion via \!#
106 */
107int hleft;
108
109static Char getCtmp;
3802e2ef 110
35371dec 111#define getC(f) ((getCtmp = peekc) ? (peekc = 0, getCtmp) : getC1(f))
3802e2ef
BJ
112#define ungetC(c) peekc = c
113#define ungetD(c) peekd = c
114
6e37afca 115int
3802e2ef 116lex(hp)
6e37afca 117 register struct wordent *hp;
3802e2ef 118{
6e37afca
KB
119 register struct wordent *wdp;
120 int c;
121
c4a58397 122 btell(&lineloc);
6e37afca
KB
123 hp->next = hp->prev = hp;
124 hp->word = STRNULL;
c4a58397 125 hadhist = 0;
6e37afca
KB
126 do
127 c = readc(0);
128 while (c == ' ' || c == '\t');
129 if (c == HISTSUB && intty)
130 /* ^lef^rit from tty is short !:s^lef^rit */
131 getexcl(c);
132 else
133 unreadc(c);
134 wdp = hp;
135 /*
136 * The following loop is written so that the links needed by freelex will
137 * be ready and rarin to go even if it is interrupted.
138 */
139 do {
140 register struct wordent *new;
141
142 new = (struct wordent *) xmalloc((size_t) sizeof(*wdp));
143 new->word = 0;
144 new->prev = wdp;
145 new->next = hp;
146 wdp->next = new;
147 wdp = new;
148 wdp->word = word();
149 } while (wdp->word[0] != '\n');
150 hp->prev = wdp;
151 return (hadhist);
3802e2ef
BJ
152}
153
6e37afca 154void
454c2aa3
CZ
155prlex(fp, sp0)
156 FILE *fp;
6e37afca 157 struct wordent *sp0;
3802e2ef 158{
6e37afca
KB
159 register struct wordent *sp = sp0->next;
160
161 for (;;) {
abf583a4 162 (void) fprintf(fp, "%s", vis_str(sp->word));
6e37afca
KB
163 sp = sp->next;
164 if (sp == sp0)
165 break;
166 if (sp->word[0] != '\n')
454c2aa3 167 (void) fputc(' ', fp);
6e37afca 168 }
3802e2ef
BJ
169}
170
6e37afca 171void
3802e2ef 172copylex(hp, fp)
6e37afca
KB
173 register struct wordent *hp;
174 register struct wordent *fp;
3802e2ef 175{
6e37afca
KB
176 register struct wordent *wdp;
177
178 wdp = hp;
179 fp = fp->next;
180 do {
181 register struct wordent *new;
182
183 new = (struct wordent *) xmalloc((size_t) sizeof(*wdp));
184 new->prev = wdp;
185 new->next = hp;
186 wdp->next = new;
187 wdp = new;
188 wdp->word = Strsave(fp->word);
3802e2ef 189 fp = fp->next;
6e37afca
KB
190 } while (wdp->word[0] != '\n');
191 hp->prev = wdp;
3802e2ef
BJ
192}
193
6e37afca 194void
3802e2ef 195freelex(vp)
6e37afca 196 register struct wordent *vp;
3802e2ef 197{
6e37afca
KB
198 register struct wordent *fp;
199
200 while (vp->next != vp) {
201 fp = vp->next;
202 vp->next = fp->next;
203 xfree((ptr_t) fp->word);
204 xfree((ptr_t) fp);
205 }
206 vp->prev = vp;
3802e2ef
BJ
207}
208
6e37afca 209static Char *
3802e2ef
BJ
210word()
211{
6e37afca
KB
212 register Char c, c1;
213 register Char *wp;
214 Char wbuf[BUFSIZ];
215 register bool dolflg;
216 register int i;
217
218 wp = wbuf;
219 i = BUFSIZ - 4;
3802e2ef 220loop:
c28e64a2
CL
221 while ((c = getC(DOALL)) == ' ' || c == '\t')
222 continue;
6e37afca
KB
223 if (cmap(c, _META | _ESC))
224 switch (c) {
225 case '&':
226 case '|':
227 case '<':
228 case '>':
229 *wp++ = c;
230 c1 = getC(DOALL);
231 if (c1 == c)
232 *wp++ = c1;
233 else
234 ungetC(c1);
235 goto ret;
236
237 case '#':
238 if (intty)
239 break;
240 c = 0;
241 do {
242 c1 = c;
243 c = getC(0);
244 } while (c != '\n');
245 if (c1 == '\\')
246 goto loop;
247 /* fall into ... */
248
249 case ';':
250 case '(':
251 case ')':
252 case '\n':
253 *wp++ = c;
254 goto ret;
255
256 case '\\':
257 c = getC(0);
258 if (c == '\n') {
259 if (onelflg == 1)
260 onelflg = 2;
261 goto loop;
262 }
263 if (c != HIST)
264 *wp++ = '\\', --i;
265 c |= QUOTE;
266 }
267 c1 = 0;
268 dolflg = DOALL;
269 for (;;) {
270 if (c1) {
271 if (c == c1) {
272 c1 = 0;
273 dolflg = DOALL;
274 }
275 else if (c == '\\') {
276 c = getC(0);
277 if (c == HIST)
278 c |= QUOTE;
279 else {
280 if (c == '\n')
281 /*
282 * if (c1 == '`') c = ' '; else
283 */
3802e2ef 284 c |= QUOTE;
6e37afca
KB
285 ungetC(c);
286 c = '\\';
3802e2ef 287 }
6e37afca
KB
288 }
289 else if (c == '\n') {
290 seterror(ERR_UNMATCHED, c1);
291 ungetC(c);
292 break;
293 }
294 }
295 else if (cmap(c, _META | _Q | _Q1 | _ESC)) {
296 if (c == '\\') {
297 c = getC(0);
298 if (c == '\n') {
299 if (onelflg == 1)
300 onelflg = 2;
301 break;
3802e2ef 302 }
6e37afca
KB
303 if (c != HIST)
304 *wp++ = '\\', --i;
305 c |= QUOTE;
306 }
307 else if (cmap(c, _Q | _Q1)) { /* '"` */
308 c1 = c;
309 dolflg = c == '"' ? DOALL : DOEXCL;
310 }
311 else if (c != '#' || !intty) {
312 ungetC(c);
313 break;
314 }
315 }
316 if (--i > 0) {
317 *wp++ = c;
318 c = getC(dolflg);
319 }
320 else {
321 seterror(ERR_WTOOLONG);
322 wp = &wbuf[1];
323 break;
3802e2ef 324 }
6e37afca 325 }
3802e2ef 326ret:
6e37afca
KB
327 *wp = 0;
328 return (Strsave(wbuf));
3802e2ef
BJ
329}
330
6e37afca 331static int
35371dec 332getC1(flag)
6e37afca 333 register int flag;
3802e2ef 334{
6e37afca 335 register Char c;
3802e2ef 336
6e37afca 337 while (1) {
3802e2ef 338 if (c = peekc) {
6e37afca
KB
339 peekc = 0;
340 return (c);
3802e2ef
BJ
341 }
342 if (lap) {
6e37afca
KB
343 if ((c = *lap++) == 0)
344 lap = 0;
345 else {
346 if (cmap(c, _META | _Q | _Q1))
347 c |= QUOTE;
348 return (c);
349 }
3802e2ef
BJ
350 }
351 if (c = peekd) {
6e37afca
KB
352 peekd = 0;
353 return (c);
3802e2ef
BJ
354 }
355 if (exclp) {
6e37afca
KB
356 if (c = *exclp++)
357 return (c);
358 if (exclnxt && --exclc >= 0) {
359 exclnxt = exclnxt->next;
360 setexclp(exclnxt->word);
361 return (' ');
362 }
363 exclp = 0;
364 exclnxt = 0;
3802e2ef
BJ
365 }
366 if (exclnxt) {
6e37afca
KB
367 exclnxt = exclnxt->next;
368 if (--exclc < 0)
369 exclnxt = 0;
370 else
371 setexclp(exclnxt->word);
372 continue;
3802e2ef
BJ
373 }
374 c = readc(0);
375 if (c == '$' && (flag & DODOL)) {
6e37afca
KB
376 getdol();
377 continue;
3802e2ef
BJ
378 }
379 if (c == HIST && (flag & DOEXCL)) {
6e37afca
KB
380 getexcl(0);
381 continue;
3802e2ef 382 }
6e37afca
KB
383 break;
384 }
385 return (c);
3802e2ef
BJ
386}
387
6e37afca 388static void
3802e2ef
BJ
389getdol()
390{
6e37afca
KB
391 register Char *np, *ep;
392 Char name[4 * MAXVARLEN + 1];
393 register int c;
394 int sc;
395 bool special = 0, toolong;
396
397 np = name, *np++ = '$';
398 c = sc = getC(DOEXCL);
399 if (any("\t \n", c)) {
400 ungetD(c);
401 ungetC('$' | QUOTE);
402 return;
403 }
404 if (c == '{')
405 *np++ = c, c = getC(DOEXCL);
406 if (c == '#' || c == '?')
407 special++, *np++ = c, c = getC(DOEXCL);
408 *np++ = c;
409 switch (c) {
410
411 case '<':
412 case '$':
b175c694 413 case '!':
6e37afca
KB
414 if (special)
415 seterror(ERR_SPDOLLT);
416 *np = 0;
417 addla(name);
418 return;
3802e2ef 419
6e37afca
KB
420 case '\n':
421 ungetD(c);
422 np--;
423 seterror(ERR_NEWLINE);
424 *np = 0;
425 addla(name);
426 return;
3802e2ef 427
6e37afca
KB
428 case '*':
429 if (special)
430 seterror(ERR_SPSTAR);
431 *np = 0;
432 addla(name);
433 return;
3802e2ef 434
6e37afca
KB
435 default:
436 toolong = 0;
437 if (Isdigit(c)) {
438#ifdef notdef
439 /* let $?0 pass for now */
440 if (special) {
441 seterror(ERR_DIGIT);
442 *np = 0;
443 addla(name);
444 return;
445 }
446#endif
447 /* we know that np < &name[4] */
448 ep = &np[MAXVARLEN];
449 while (c = getC(DOEXCL)) {
450 if (!Isdigit(c))
451 break;
452 if (np < ep)
453 *np++ = c;
3802e2ef 454 else
6e37afca
KB
455 toolong = 1;
456 }
3802e2ef 457 }
6e37afca
KB
458 else if (letter(c)) {
459 /* we know that np < &name[4] */
460 ep = &np[MAXVARLEN];
461 toolong = 0;
462 while (c = getC(DOEXCL)) {
463 /* Bugfix for ${v123x} from Chris Torek, DAS DEC-90. */
464 if (!letter(c) && !Isdigit(c))
465 break;
466 if (np < ep)
467 *np++ = c;
468 else
469 toolong = 1;
470 }
3802e2ef 471 }
6e37afca
KB
472 else {
473 *np = 0;
474 seterror(ERR_VARILL);
475 addla(name);
476 return;
477 }
478 if (toolong) {
479 seterror(ERR_VARTOOLONG);
480 *np = 0;
481 addla(name);
482 return;
483 }
484 break;
485 }
486 if (c == '[') {
487 *np++ = c;
488 /*
489 * Name up to here is a max of MAXVARLEN + 8.
490 */
491 ep = &np[2 * MAXVARLEN + 8];
492 do {
493 /*
494 * Michael Greim: Allow $ expansion to take place in selector
495 * expressions. (limits the number of characters returned)
496 */
497 c = getC(DOEXCL | DODOL);
498 if (c == '\n') {
3802e2ef 499 ungetD(c);
6e37afca
KB
500 np--;
501 seterror(ERR_NLINDEX);
502 *np = 0;
503 addla(name);
504 return;
505 }
506 if (np < ep)
3802e2ef 507 *np++ = c;
6e37afca
KB
508 } while (c != ']');
509 *np = '\0';
510 if (np >= ep) {
511 seterror(ERR_SELOVFL);
512 addla(name);
513 return;
3802e2ef 514 }
6e37afca
KB
515 c = getC(DOEXCL);
516 }
517 /*
518 * Name up to here is a max of 2 * MAXVARLEN + 8.
519 */
520 if (c == ':') {
521 /*
522 * if the :g modifier is followed by a newline, then error right away!
523 * -strike
524 */
525
b175c694 526 int gmodflag = 0, amodflag = 0;
3802e2ef 527
df361440
CZ
528 do {
529 *np++ = c, c = getC(DOEXCL);
b175c694
CZ
530 if (c == 'g' || c == 'a') {
531 if (c == 'g')
532 gmodflag++;
533 else
534 amodflag++;
535 *np++ = c; c = getC(DOEXCL);
536 }
537 if ((c == 'g' && !gmodflag) || (c == 'a' && !amodflag)) {
538 if (c == 'g')
539 gmodflag++;
540 else
541 amodflag++;
542 *np++ = c; c = getC(DOEXCL);
543 }
df361440 544 *np++ = c;
b175c694
CZ
545 /* scan s// [eichin:19910926.0512EST] */
546 if (c == 's') {
547 int delimcnt = 2;
548 int delim = getC(0);
549 *np++ = delim;
550
551 if (!delim || letter(delim)
552 || Isdigit(delim) || any(" \t\n", delim)) {
553 seterror(ERR_BADSUBST);
554 break;
555 }
556 while ((c = getC(0)) != (-1)) {
557 *np++ = c;
558 if(c == delim) delimcnt--;
559 if(!delimcnt) break;
560 }
561 if(delimcnt) {
562 seterror(ERR_BADSUBST);
563 break;
564 }
565 c = 's';
566 }
567 if (!any("htrqxes", c)) {
568 if ((amodflag || gmodflag) && c == '\n')
df361440
CZ
569 stderror(ERR_VARSYN); /* strike */
570 seterror(ERR_VARMOD, c);
571 *np = 0;
572 addla(name);
573 return;
574 }
6e37afca 575 }
df361440
CZ
576 while ((c = getC(DOEXCL)) == ':');
577 ungetD(c);
6e37afca
KB
578 }
579 else
580 ungetD(c);
581 if (sc == '{') {
582 c = getC(DOEXCL);
583 if (c != '}') {
584 ungetD(c);
585 seterror(ERR_MISSING, '}');
586 *np = 0;
587 addla(name);
588 return;
589 }
590 *np++ = c;
591 }
592 *np = 0;
593 addla(name);
594 return;
3802e2ef
BJ
595}
596
6e37afca 597void
3802e2ef 598addla(cp)
6e37afca 599 Char *cp;
3802e2ef 600{
6e37afca 601 Char buf[BUFSIZ];
3802e2ef 602
6e37afca
KB
603 if (Strlen(cp) + (lap ? Strlen(lap) : 0) >=
604 (sizeof(labuf) - 4) / sizeof(Char)) {
605 seterror(ERR_EXPOVFL);
606 return;
607 }
608 if (lap)
609 (void) Strcpy(buf, lap);
610 (void) Strcpy(labuf, cp);
611 if (lap)
612 (void) Strcat(labuf, buf);
613 lap = labuf;
3802e2ef
BJ
614}
615
6e37afca
KB
616static Char lhsb[32];
617static Char slhs[32];
618static Char rhsb[64];
619static int quesarg;
3802e2ef 620
6e37afca 621static void
3802e2ef 622getexcl(sc)
0aec749d 623 int sc;
3802e2ef 624{
6e37afca
KB
625 register struct wordent *hp, *ip;
626 int left, right, dol;
627 register int c;
628
629 if (sc == 0) {
630 sc = getC(0);
631 if (sc != '{') {
632 ungetC(sc);
633 sc = 0;
3802e2ef 634 }
6e37afca
KB
635 }
636 quesarg = -1;
637 lastev = eventno;
638 hp = gethent(sc);
639 if (hp == 0)
640 return;
641 hadhist = 1;
642 dol = 0;
643 if (hp == alhistp)
644 for (ip = hp->next->next; ip != alhistt; ip = ip->next)
645 dol++;
646 else
647 for (ip = hp->next->next; ip != hp->prev; ip = ip->next)
648 dol++;
649 left = 0, right = dol;
650 if (sc == HISTSUB) {
651 ungetC('s'), unreadc(HISTSUB), c = ':';
652 goto subst;
653 }
654 c = getC(0);
655 if (!any(":^$*-%", c))
656 goto subst;
657 left = right = -1;
658 if (c == ':') {
3802e2ef 659 c = getC(0);
6e37afca
KB
660 unreadc(c);
661 if (letter(c) || c == '&') {
662 c = ':';
663 left = 0, right = dol;
664 goto subst;
665 }
666 }
667 else
668 ungetC(c);
669 if (!getsel(&left, &right, dol))
670 return;
671 c = getC(0);
672 if (c == '*')
673 ungetC(c), c = '-';
674 if (c == '-') {
3802e2ef 675 if (!getsel(&left, &right, dol))
6e37afca 676 return;
3802e2ef 677 c = getC(0);
6e37afca 678 }
3802e2ef 679subst:
6e37afca
KB
680 exclc = right - left + 1;
681 while (--left >= 0)
682 hp = hp->next;
683 if (sc == HISTSUB || c == ':') {
684 do {
685 hp = getsub(hp);
686 c = getC(0);
687 } while (c == ':');
688 }
689 unreadc(c);
690 if (sc == '{') {
691 c = getC(0);
692 if (c != '}')
693 seterror(ERR_BADBANG);
694 }
695 exclnxt = hp;
3802e2ef
BJ
696}
697
6e37afca 698static struct wordent *
3802e2ef 699getsub(en)
6e37afca 700 struct wordent *en;
3802e2ef 701{
6e37afca
KB
702 register Char *cp;
703 int delim;
704 register int c;
705 int sc;
b175c694 706 bool global;
6e37afca
KB
707 Char orhsb[sizeof(rhsb) / sizeof(Char)];
708
df361440
CZ
709 do {
710 exclnxt = 0;
b175c694 711 global = 0;
df361440 712 sc = c = getC(0);
b175c694
CZ
713 if (c == 'g' || c == 'a') {
714 global |= (c == 'g') ? 1 : 2;
715 sc = c = getC(0);
716 }
717 if (((c =='g') && !(global & 1)) || ((c == 'a') && !(global & 2))) {
718 global |= (c == 'g') ? 1 : 2;
719 sc = c = getC(0);
720 }
6e37afca 721
df361440
CZ
722 switch (c) {
723 case 'p':
724 justpr++;
725 return (en);
3802e2ef 726
df361440
CZ
727 case 'x':
728 case 'q':
b175c694 729 global |= 1;
3802e2ef 730
df361440 731 /* fall into ... */
3802e2ef 732
df361440
CZ
733 case 'h':
734 case 'r':
735 case 't':
736 case 'e':
737 break;
3802e2ef 738
df361440
CZ
739 case '&':
740 if (slhs[0] == 0) {
741 seterror(ERR_NOSUBST);
742 return (en);
743 }
744 (void) Strcpy(lhsb, slhs);
745 break;
6e37afca
KB
746
747#ifdef notdef
df361440
CZ
748 case '~':
749 if (lhsb[0] == 0)
750 goto badlhs;
751 break;
6e37afca 752#endif
3802e2ef 753
df361440
CZ
754 case 's':
755 delim = getC(0);
756 if (letter(delim) || Isdigit(delim) || any(" \t\n", delim)) {
757 unreadc(delim);
6e37afca
KB
758 lhsb[0] = 0;
759 seterror(ERR_BADSUBST);
760 return (en);
761 }
df361440
CZ
762 cp = lhsb;
763 for (;;) {
6e37afca 764 c = getC(0);
df361440
CZ
765 if (c == '\n') {
766 unreadc(c);
767 break;
768 }
769 if (c == delim)
770 break;
771 if (cp > &lhsb[sizeof(lhsb) / sizeof(Char) - 2]) {
772 lhsb[0] = 0;
773 seterror(ERR_BADSUBST);
774 return (en);
775 }
776 if (c == '\\') {
777 c = getC(0);
778 if (c != delim && c != '\\')
779 *cp++ = '\\';
780 }
781 *cp++ = c;
6e37afca 782 }
df361440
CZ
783 if (cp != lhsb)
784 *cp++ = 0;
785 else if (lhsb[0] == 0) {
786 seterror(ERR_LHS);
6e37afca
KB
787 return (en);
788 }
df361440
CZ
789 cp = rhsb;
790 (void) Strcpy(orhsb, cp);
791 for (;;) {
6e37afca 792 c = getC(0);
df361440
CZ
793 if (c == '\n') {
794 unreadc(c);
795 break;
796 }
797 if (c == delim)
798 break;
799#ifdef notdef
800 if (c == '~') {
c28e64a2 801 if (&cp[Strlen(orhsb)] > &rhsb[sizeof(rhsb) /
df361440
CZ
802 sizeof(Char) - 2])
803 goto toorhs;
804 (void) Strcpy(cp, orhsb);
805 cp = Strend(cp);
806 continue;
807 }
808#endif
809 if (cp > &rhsb[sizeof(rhsb) / sizeof(Char) - 2]) {
810 seterror(ERR_RHSLONG);
811 return (en);
812 }
813 if (c == '\\') {
814 c = getC(0);
815 if (c != delim /* && c != '~' */ )
816 *cp++ = '\\';
817 }
818 *cp++ = c;
6e37afca 819 }
df361440
CZ
820 *cp++ = 0;
821 break;
6e37afca 822
df361440
CZ
823 default:
824 if (c == '\n')
825 unreadc(c);
826 seterror(ERR_BADBANGMOD, c);
827 return (en);
828 }
829 (void) Strcpy(slhs, lhsb);
830 if (exclc)
831 en = dosub(sc, en, global);
6e37afca 832 }
df361440
CZ
833 while ((c = getC(0)) == ':');
834 unreadc(c);
6e37afca 835 return (en);
3802e2ef
BJ
836}
837
6e37afca 838static struct wordent *
3802e2ef 839dosub(sc, en, global)
6e37afca
KB
840 int sc;
841 struct wordent *en;
842 bool global;
3802e2ef 843{
6e37afca 844 struct wordent lexi;
b175c694 845 bool didsub = 0, didone = 0;
6e37afca
KB
846 struct wordent *hp = &lexi;
847 register struct wordent *wdp;
848 register int i = exclc;
849
850 wdp = hp;
851 while (--i >= 0) {
b175c694
CZ
852 register struct wordent *new =
853 (struct wordent *) xcalloc(1, sizeof *wdp);
6e37afca 854
6e37afca
KB
855 new->word = 0;
856 new->prev = wdp;
857 new->next = hp;
858 wdp->next = new;
859 wdp = new;
860 en = en->next;
b175c694
CZ
861 if (en->word) {
862 Char *tword, *otword;
863
864 if ((global & 1) || didsub == 0) {
865 tword = subword(en->word, sc, &didone);
866 if (didone)
867 didsub = 1;
868 if (global & 2) {
869 while (didone && tword != STRNULL) {
870 otword = tword;
871 tword = subword(otword, sc, &didone);
872 if (Strcmp(tword, otword) == 0) {
873 xfree((ptr_t) otword);
874 break;
875 }
876 else
877 xfree((ptr_t) otword);
878 }
879 }
880 }
881 else
882 tword = Strsave(en->word);
883 wdp->word = tword;
884 }
6e37afca
KB
885 }
886 if (didsub == 0)
887 seterror(ERR_MODFAIL);
888 hp->prev = wdp;
889 return (&enthist(-1000, &lexi, 0)->Hlex);
3802e2ef
BJ
890}
891
6e37afca 892static Char *
3802e2ef 893subword(cp, type, adid)
6e37afca
KB
894 Char *cp;
895 int type;
896 bool *adid;
3802e2ef 897{
6e37afca
KB
898 Char wbuf[BUFSIZ];
899 register Char *wp, *mp, *np;
900 register int i;
901
b175c694 902 *adid = 0;
6e37afca
KB
903 switch (type) {
904
905 case 'r':
906 case 'e':
907 case 'h':
908 case 't':
909 case 'q':
910 case 'x':
911 wp = domod(cp, type);
912 if (wp == 0)
913 return (Strsave(cp));
914 *adid = 1;
915 return (wp);
916
917 default:
918 wp = wbuf;
919 i = BUFSIZ - 4;
920 for (mp = cp; *mp; mp++)
921 if (matchs(mp, lhsb)) {
922 for (np = cp; np < mp;)
923 *wp++ = *np++, --i;
924 for (np = rhsb; *np; np++)
925 switch (*np) {
926
927 case '\\':
928 if (np[1] == '&')
929 np++;
930 /* fall into ... */
3802e2ef 931
6e37afca
KB
932 default:
933 if (--i < 0) {
934 seterror(ERR_SUBOVFL);
935 return (STRNULL);
3802e2ef 936 }
6e37afca
KB
937 *wp++ = *np;
938 continue;
939
940 case '&':
941 i -= Strlen(lhsb);
942 if (i < 0) {
943 seterror(ERR_SUBOVFL);
944 return (STRNULL);
945 }
946 *wp = 0;
947 (void) Strcat(wp, lhsb);
948 wp = Strend(wp);
949 continue;
950 }
951 mp += Strlen(lhsb);
952 i -= Strlen(mp);
953 if (i < 0) {
954 seterror(ERR_SUBOVFL);
955 return (STRNULL);
956 }
957 *wp = 0;
958 (void) Strcat(wp, mp);
959 *adid = 1;
960 return (Strsave(wbuf));
961 }
962 return (Strsave(cp));
963 }
3802e2ef
BJ
964}
965
6e37afca 966Char *
3802e2ef 967domod(cp, type)
6e37afca
KB
968 Char *cp;
969 int type;
3802e2ef 970{
6e37afca
KB
971 register Char *wp, *xp;
972 register int c;
973
974 switch (type) {
975
976 case 'x':
977 case 'q':
978 wp = Strsave(cp);
979 for (xp = wp; c = *xp; xp++)
980 if ((c != ' ' && c != '\t') || type == 'q')
981 *xp |= QUOTE;
982 return (wp);
983
984 case 'h':
985 case 't':
986 if (!any(short2str(cp), '/'))
987 return (type == 't' ? Strsave(cp) : 0);
988 wp = Strend(cp);
989 while (*--wp != '/')
990 continue;
991 if (type == 'h')
992 xp = Strsave(cp), xp[wp - cp] = 0;
993 else
994 xp = Strsave(wp + 1);
995 return (xp);
996
997 case 'e':
998 case 'r':
999 wp = Strend(cp);
1000 for (wp--; wp >= cp && *wp != '/'; wp--)
1001 if (*wp == '.') {
1002 if (type == 'e')
1003 xp = Strsave(wp + 1);
3802e2ef 1004 else
6e37afca 1005 xp = Strsave(cp), xp[wp - cp] = 0;
3802e2ef 1006 return (xp);
6e37afca
KB
1007 }
1008 return (Strsave(type == 'e' ? STRNULL : cp));
b175c694
CZ
1009 default:
1010 break;
6e37afca
KB
1011 }
1012 return (0);
3802e2ef
BJ
1013}
1014
6e37afca 1015static int
3802e2ef 1016matchs(str, pat)
6e37afca 1017 register Char *str, *pat;
3802e2ef 1018{
6e37afca
KB
1019 while (*str && *pat && *str == *pat)
1020 str++, pat++;
1021 return (*pat == 0);
3802e2ef
BJ
1022}
1023
6e37afca 1024static int
3802e2ef 1025getsel(al, ar, dol)
6e37afca
KB
1026 register int *al, *ar;
1027 int dol;
3802e2ef 1028{
6e37afca
KB
1029 register int c = getC(0);
1030 register int i;
1031 bool first = *al < 0;
3802e2ef 1032
6e37afca 1033 switch (c) {
3802e2ef 1034
6e37afca
KB
1035 case '%':
1036 if (quesarg == -1) {
1037 seterror(ERR_BADBANGARG);
1038 return (0);
1039 }
1040 if (*al < 0)
1041 *al = quesarg;
1042 *ar = quesarg;
1043 break;
1044
1045 case '-':
1046 if (*al < 0) {
1047 *al = 0;
1048 *ar = dol - 1;
1049 unreadc(c);
1050 }
1051 return (1);
3802e2ef 1052
6e37afca
KB
1053 case '^':
1054 if (*al < 0)
1055 *al = 1;
1056 *ar = 1;
1057 break;
1058
1059 case '$':
1060 if (*al < 0)
1061 *al = dol;
1062 *ar = dol;
1063 break;
1064
1065 case '*':
1066 if (*al < 0)
1067 *al = 1;
1068 *ar = dol;
1069 if (*ar < *al) {
1070 *ar = 0;
1071 *al = 1;
1072 return (1);
3802e2ef 1073 }
6e37afca
KB
1074 break;
1075
1076 default:
1077 if (Isdigit(c)) {
1078 i = 0;
1079 while (Isdigit(c)) {
1080 i = i * 10 + c - '0';
3802e2ef 1081 c = getC(0);
6e37afca
KB
1082 }
1083 if (i < 0)
1084 i = dol + 1;
1085 if (*al < 0)
1086 *al = i;
1087 *ar = i;
3802e2ef 1088 }
6e37afca
KB
1089 else if (*al < 0)
1090 *al = 0, *ar = dol;
1091 else
1092 *ar = dol - 1;
1093 unreadc(c);
1094 break;
1095 }
1096 if (first) {
1097 c = getC(0);
1098 unreadc(c);
1099 if (any("-$*", c))
1100 return (1);
1101 }
1102 if (*al > *ar || *ar > dol) {
1103 seterror(ERR_BADBANGARG);
1104 return (0);
1105 }
1106 return (1);
3802e2ef
BJ
1107
1108}
1109
6e37afca 1110static struct wordent *
3802e2ef 1111gethent(sc)
6e37afca 1112 int sc;
3802e2ef 1113{
6e37afca
KB
1114 register struct Hist *hp;
1115 register Char *np;
1116 register int c;
1117 int event;
1118 bool back = 0;
1119
1120 c = sc == HISTSUB ? HIST : getC(0);
1121 if (c == HIST) {
1122 if (alhistp)
1123 return (alhistp);
1124 event = eventno;
1125 }
1126 else
3802e2ef
BJ
1127 switch (c) {
1128
1129 case ':':
1130 case '^':
1131 case '$':
1132 case '*':
1133 case '%':
6e37afca
KB
1134 ungetC(c);
1135 if (lastev == eventno && alhistp)
1136 return (alhistp);
1137 event = lastev;
1138 break;
1139
1140 case '#': /* !# is command being typed in (mrh) */
1141 if (--hleft == 0) {
1142 seterror(ERR_HISTLOOP);
1143 return (0);
1144 }
1145 else
1146 return (&paraml);
1147 /* NOTREACHED */
3802e2ef
BJ
1148
1149 case '-':
6e37afca
KB
1150 back = 1;
1151 c = getC(0);
1152 /* FALLSTHROUGH */
3802e2ef
BJ
1153
1154 default:
6e37afca 1155 if (any("(=~", c)) {
3802e2ef 1156 unreadc(c);
6e37afca
KB
1157 ungetC(HIST);
1158 return (0);
1159 }
1160 np = lhsb;
1161 event = 0;
3a411568 1162 while (!cmap(c, _ESC | _META | _Q | _Q1) && !any("${}:", c)) {
6e37afca
KB
1163 if (event != -1 && Isdigit(c))
1164 event = event * 10 + c - '0';
1165 else
1166 event = -1;
1167 if (np < &lhsb[sizeof(lhsb) / sizeof(Char) - 2])
1168 *np++ = c;
1169 c = getC(0);
1170 }
1171 unreadc(c);
1172 if (np == lhsb) {
1173 ungetC(HIST);
1174 return (0);
1175 }
1176 *np++ = 0;
1177 if (event != -1) {
1178 /*
1179 * History had only digits
1180 */
1181 if (back)
1182 event = eventno + (alhistp == 0) - (event ? event : 0);
1183 break;
1184 }
1185 hp = findev(lhsb, 0);
1186 if (hp)
1187 lastev = hp->Hnum;
1188 return (&hp->Hlex);
3802e2ef
BJ
1189
1190 case '?':
6e37afca
KB
1191 np = lhsb;
1192 for (;;) {
1193 c = getC(0);
1194 if (c == '\n') {
1195 unreadc(c);
1196 break;
3802e2ef 1197 }
6e37afca
KB
1198 if (c == '?')
1199 break;
1200 if (np < &lhsb[sizeof(lhsb) / sizeof(Char) - 2])
1201 *np++ = c;
1202 }
1203 if (np == lhsb) {
1204 if (lhsb[0] == 0) {
1205 seterror(ERR_NOSEARCH);
1206 return (0);
3802e2ef 1207 }
6e37afca
KB
1208 }
1209 else
1210 *np++ = 0;
1211 hp = findev(lhsb, 1);
1212 if (hp)
1213 lastev = hp->Hnum;
1214 return (&hp->Hlex);
3802e2ef 1215 }
6e37afca
KB
1216
1217 for (hp = Histlist.Hnext; hp; hp = hp->Hnext)
1218 if (hp->Hnum == event) {
1219 hp->Href = eventno;
1220 lastev = hp->Hnum;
1221 return (&hp->Hlex);
1222 }
1223 np = putn(event);
abf583a4 1224 seterror(ERR_NOEVENT, vis_str(np));
6e37afca 1225 return (0);
3802e2ef
BJ
1226}
1227
6e37afca 1228static struct Hist *
3802e2ef 1229findev(cp, anyarg)
6e37afca
KB
1230 Char *cp;
1231 bool anyarg;
3802e2ef 1232{
6e37afca 1233 register struct Hist *hp;
3802e2ef 1234
6e37afca
KB
1235 for (hp = Histlist.Hnext; hp; hp = hp->Hnext) {
1236 Char *dp;
1237 register Char *p, *q;
1238 register struct wordent *lp = hp->Hlex.next;
1239 int argno = 0;
35371dec 1240
6e37afca
KB
1241 /*
1242 * The entries added by alias substitution don't have a newline but do
1243 * have a negative event number. Savehist() trims off these entries,
1244 * but it happens before alias expansion, too early to delete those
1245 * from the previous command.
1246 */
1247 if (hp->Hnum < 0)
1248 continue;
1249 if (lp->word[0] == '\n')
1250 continue;
1251 if (!anyarg) {
1252 p = cp;
1253 q = lp->word;
1254 do
1255 if (!*p)
1256 return (hp);
1257 while (*p++ == *q++);
1258 continue;
35371dec 1259 }
6e37afca
KB
1260 do {
1261 for (dp = lp->word; *dp; dp++) {
1262 p = cp;
1263 q = dp;
1264 do
1265 if (!*p) {
1266 quesarg = argno;
1267 return (hp);
1268 }
1269 while (*p++ == *q++);
1270 }
1271 lp = lp->next;
1272 argno++;
1273 } while (lp->word[0] != '\n');
1274 }
abf583a4 1275 seterror(ERR_NOEVENT, vis_str(cp));
6e37afca 1276 return (0);
3802e2ef
BJ
1277}
1278
3802e2ef 1279
6e37afca 1280static void
3802e2ef 1281setexclp(cp)
6e37afca 1282 register Char *cp;
3802e2ef 1283{
6e37afca
KB
1284 if (cp && cp[0] == '\n')
1285 return;
1286 exclp = cp;
3802e2ef
BJ
1287}
1288
6e37afca 1289void
3802e2ef 1290unreadc(c)
4d7b2685 1291 int c;
3802e2ef 1292{
6e37afca 1293 peekread = c;
3802e2ef
BJ
1294}
1295
6e37afca 1296int
3802e2ef 1297readc(wanteof)
6e37afca 1298 bool wanteof;
3802e2ef 1299{
6e37afca
KB
1300 register int c;
1301 static sincereal;
3802e2ef 1302
c4a58397 1303 aret = F_SEEK;
6e37afca
KB
1304 if (c = peekread) {
1305 peekread = 0;
1306 return (c);
1307 }
3802e2ef 1308top:
c4a58397 1309 aret = F_SEEK;
6e37afca 1310 if (alvecp) {
c4a58397 1311 aret = A_SEEK;
c28e64a2 1312 if (c = *alvecp++)
6e37afca 1313 return (c);
902c7425 1314 if (alvec && *alvec) {
c4a58397
CZ
1315 alvecp = *alvec++;
1316 return (' ');
1317 }
1318 else {
1319 aret = F_SEEK;
1320 alvecp = NULL;
1321 return('\n');
3802e2ef 1322 }
6e37afca
KB
1323 }
1324 if (alvec) {
1325 if (alvecp = *alvec) {
1326 alvec++;
1327 goto top;
3802e2ef 1328 }
6e37afca
KB
1329 /* Infinite source! */
1330 return ('\n');
1331 }
1332 if (evalp) {
c4a58397 1333 aret = E_SEEK;
6e37afca
KB
1334 if (c = *evalp++)
1335 return (c);
c4a58397 1336 if (evalvec && *evalvec) {
6e37afca
KB
1337 evalp = *evalvec++;
1338 return (' ');
3802e2ef 1339 }
c4a58397 1340 aret = F_SEEK;
6e37afca
KB
1341 evalp = 0;
1342 }
1343 if (evalvec) {
1344 if (evalvec == (Char **) 1) {
1345 doneinp = 1;
1346 reset();
1347 }
1348 if (evalp = *evalvec) {
1349 evalvec++;
1350 goto top;
1351 }
1352 evalvec = (Char **) 1;
1353 return ('\n');
1354 }
1355 do {
1356 if (arginp == (Char *) 1 || onelflg == 1) {
1357 if (wanteof)
1358 return (-1);
1359 exitstat();
1360 }
1361 if (arginp) {
1362 if ((c = *arginp++) == 0) {
1363 arginp = (Char *) 1;
3802e2ef 1364 return ('\n');
6e37afca
KB
1365 }
1366 return (c);
3802e2ef 1367 }
3802e2ef 1368reread:
6e37afca
KB
1369 c = bgetc();
1370 if (c < 0) {
6e37afca 1371 struct termios tty;
6e37afca
KB
1372 if (wanteof)
1373 return (-1);
1374 /* was isatty but raw with ignoreeof yields problems */
6e37afca 1375 if (tcgetattr(SHIN, &tty) == 0 && (tty.c_lflag & ICANON))
6e37afca
KB
1376 {
1377 /* was 'short' for FILEC */
1378 int ctpgrp;
1379
1380 if (++sincereal > 25)
1381 goto oops;
1382 if (tpgrp != -1 &&
1383 (ctpgrp = tcgetpgrp(FSHTTY)) != -1 &&
1384 tpgrp != ctpgrp) {
1385 (void) tcsetpgrp(FSHTTY, tpgrp);
1386 (void) killpg((pid_t) ctpgrp, SIGHUP);
c28e64a2 1387 (void) fprintf(csherr, "Reset tty pgrp from %d to %d\n",
454c2aa3 1388 ctpgrp, tpgrp);
6e37afca 1389 goto reread;
3802e2ef 1390 }
6e37afca
KB
1391 if (adrof(STRignoreeof)) {
1392 if (loginsh)
454c2aa3 1393 (void) fprintf(csherr,"\nUse \"logout\" to logout.\n");
6e37afca 1394 else
454c2aa3 1395 (void) fprintf(csherr,"\nUse \"exit\" to leave csh.\n");
6e37afca
KB
1396 reset();
1397 }
1398 if (chkstop == 0)
1399 panystop(1);
1400 }
1401 oops:
1402 doneinp = 1;
1403 reset();
1404 }
1405 sincereal = 0;
1406 if (c == '\n' && onelflg)
1407 onelflg--;
1408 } while (c == 0);
1409 return (c);
3802e2ef
BJ
1410}
1411
6e37afca 1412static int
3802e2ef
BJ
1413bgetc()
1414{
6e37afca
KB
1415 register int buf, off, c;
1416
fff1d7ed 1417#ifdef FILEC
6e37afca
KB
1418 register int numleft = 0, roomleft;
1419 Char ttyline[BUFSIZ];
5b182e7a 1420#endif
6e37afca 1421 char tbuf[BUFSIZ + 1];
3802e2ef 1422
6e37afca
KB
1423 if (cantell) {
1424 if (fseekp < fbobp || fseekp > feobp) {
1425 fbobp = feobp = fseekp;
1426 (void) lseek(SHIN, fseekp, L_SET);
1427 }
1428 if (fseekp == feobp) {
1429 int i;
1430
1431 fbobp = feobp;
1432 do
1433 c = read(SHIN, tbuf, BUFSIZ);
1434 while (c < 0 && errno == EINTR);
1435 if (c <= 0)
1436 return (-1);
1437 for (i = 0; i < c; i++)
1438 fbuf[0][i] = (unsigned char) tbuf[i];
1439 feobp += c;
3802e2ef 1440 }
6e37afca
KB
1441 c = fbuf[0][fseekp - fbobp];
1442 fseekp++;
1443 return (c);
1444 }
6e37afca 1445
3802e2ef 1446again:
6e37afca
KB
1447 buf = (int) fseekp / BUFSIZ;
1448 if (buf >= fblocks) {
1449 register Char **nfbuf =
1450 (Char **) xcalloc((size_t) (fblocks + 2),
1451 sizeof(Char **));
1452
1453 if (fbuf) {
1454 (void) blkcpy(nfbuf, fbuf);
1455 xfree((ptr_t) fbuf);
3802e2ef 1456 }
6e37afca
KB
1457 fbuf = nfbuf;
1458 fbuf[fblocks] = (Char *) xcalloc(BUFSIZ, sizeof(Char));
1459 fblocks++;
1460 if (!intty)
1461 goto again;
1462 }
1463 if (fseekp >= feobp) {
1464 buf = (int) feobp / BUFSIZ;
1465 off = (int) feobp % BUFSIZ;
1466 roomleft = BUFSIZ - off;
1467
1468#ifdef FILEC
1469 roomleft = BUFSIZ - off;
1470 for (;;) {
1471 if (filec && intty) {
1472 c = numleft ? numleft : tenex(ttyline, BUFSIZ);
1473 if (c > roomleft) {
1474 /* start with fresh buffer */
1475 feobp = fseekp = fblocks * BUFSIZ;
1476 numleft = c;
1477 goto again;
1478 }
1479 if (c > 0)
1480 bcopy(ttyline, fbuf[buf] + off, c * sizeof(Char));
1481 numleft = 0;
1482 }
1483 else {
5b182e7a 1484#endif
6e37afca
KB
1485 c = read(SHIN, tbuf, roomleft);
1486 if (c > 0) {
1487 int i;
1488 Char *ptr = fbuf[buf] + off;
1489
1490 for (i = 0; i < c; i++)
1491 ptr[i] = (unsigned char) tbuf[i];
0a2abf9e 1492 }
6e37afca
KB
1493#ifdef FILEC
1494 }
1495#endif
1496 if (c >= 0)
1497 break;
1498 if (errno == EWOULDBLOCK) {
1499 int off = 0;
1500
1501 (void) ioctl(SHIN, FIONBIO, (ioctl_t) & off);
1502 }
1503 else if (errno != EINTR)
1504 break;
1505 }
1506 if (c <= 0)
1507 return (-1);
1508 feobp += c;
fff1d7ed 1509#ifndef FILEC
6e37afca 1510 goto again;
5b182e7a 1511#else
6e37afca
KB
1512 if (filec && !intty)
1513 goto again;
5b182e7a 1514#endif
6e37afca
KB
1515 }
1516 c = fbuf[buf][(int) fseekp % BUFSIZ];
1517 fseekp++;
1518 return (c);
3802e2ef
BJ
1519}
1520
6e37afca 1521static void
3802e2ef
BJ
1522bfree()
1523{
6e37afca 1524 register int sb, i;
3802e2ef 1525
6e37afca
KB
1526 if (cantell)
1527 return;
6e37afca
KB
1528 if (whyles)
1529 return;
1530 sb = (int) (fseekp - 1) / BUFSIZ;
1531 if (sb > 0) {
1532 for (i = 0; i < sb; i++)
1533 xfree((ptr_t) fbuf[i]);
1534 (void) blkcpy(fbuf, &fbuf[sb]);
1535 fseekp -= BUFSIZ * sb;
1536 feobp -= BUFSIZ * sb;
1537 fblocks -= sb;
1538 }
3802e2ef
BJ
1539}
1540
6e37afca 1541void
3802e2ef 1542bseek(l)
c4a58397 1543 struct Ain *l;
3802e2ef 1544{
c4a58397
CZ
1545 switch (aret = l->type) {
1546 case E_SEEK:
1547 evalvec = l->a_seek;
1548 evalp = (Char *) l->f_seek;
1549 return;
1550 case A_SEEK:
1551 alvec = l->a_seek;
1552 alvecp = (Char *) l->f_seek;
1553 return;
c28e64a2 1554 case F_SEEK:
c4a58397
CZ
1555 fseekp = l->f_seek;
1556 return;
1557 default:
1558 (void) fprintf(csherr, "Bad seek type %d\n", aret);
1559 abort();
1560 }
1561}
3802e2ef 1562
c4a58397
CZ
1563void
1564btell(l)
1565 struct Ain *l;
1566{
1567 switch (l->type = aret) {
1568 case E_SEEK:
1569 l->a_seek = evalvec;
1570 l->f_seek = (off_t) evalp;
1571 return;
1572 case A_SEEK:
1573 l->a_seek = alvec;
1574 l->f_seek = (off_t) alvecp;
1575 return;
1576 case F_SEEK:
1577 l->f_seek = fseekp;
1578 l->a_seek = NULL;
1579 return;
1580 default:
1581 (void) fprintf(csherr, "Bad seek type %d\n", aret);
1582 abort();
6e37afca 1583 }
3802e2ef
BJ
1584}
1585
6e37afca 1586void
3802e2ef
BJ
1587btoeof()
1588{
6e37afca 1589 (void) lseek(SHIN, (off_t) 0, L_XTND);
40cf27d9 1590 aret = F_SEEK;
6e37afca 1591 fseekp = feobp;
40cf27d9
CZ
1592 alvec = NULL;
1593 alvecp = NULL;
1594 evalvec = NULL;
1595 evalp = NULL;
6e37afca
KB
1596 wfree();
1597 bfree();
3802e2ef
BJ
1598}
1599
6e37afca 1600void
3802e2ef
BJ
1601settell()
1602{
6e37afca
KB
1603 cantell = 0;
1604 if (arginp || onelflg || intty)
1605 return;
1606 if (lseek(SHIN, (off_t) 0, L_INCR) < 0 || errno == ESPIPE)
1607 return;
1608 fbuf = (Char **) xcalloc(2, sizeof(Char **));
1609 fblocks = 1;
1610 fbuf[0] = (Char *) xcalloc(BUFSIZ, sizeof(Char));
1611 fseekp = fbobp = feobp = lseek(SHIN, (off_t) 0, L_INCR);
1612 cantell = 1;
3802e2ef 1613}