xref: /original-bsd/old/sh/word.c (revision 18f6d767)
1 #ifndef lint
2 static char sccsid[] = "@(#)word.c	4.4 02/13/85";
3 #endif
4 
5 #
6 /*
7  * UNIX shell
8  *
9  * S. R. Bourne
10  * Bell Telephone Laboratories
11  *
12  */
13 
14 #include	"defs.h"
15 #include	"sym.h"
16 
17 
18 /* ========	character handling for command lines	========*/
19 
20 
21 word()
22 {
23 	REG CHAR	c, d;
24 	REG CHAR	*argp=locstak()+BYTESPERWORD;
25 	INT		alpha=1;
26 
27 	wdnum=0; wdset=0;
28 
29 	WHILE (c=nextc(0), space(c)) DONE
30 
31 	IF c=='#' ANDF (flags&ttyflg)==0
32 	THEN	WHILE (c=readc()) ANDF c!=NL DONE
33 	FI
34 
35 	IF !eofmeta(c)
36 	THEN	REP	IF c==LITERAL
37 			THEN	*argp++=(DQUOTE);
38 				WHILE (c=readc()) ANDF c!=LITERAL
39 				DO *argp++=(c|QUOTE); chkpr(c) OD
40 				*argp++=(DQUOTE);
41 
42 			ELSE	*argp++=(c);
43 				IF c=='=' THEN wdset |= alpha FI
44 				IF !alphanum(c) THEN alpha=0 FI
45 				IF qotchar(c)
46 				THEN	d=c;
47 					WHILE (*argp++=(c=nextc(d))) ANDF c!=d
48 					DO chkpr(c) OD
49 				FI
50 			FI
51 		PER (c=nextc(0), !eofmeta(c)) DONE
52 		argp=endstak(argp);
53 		IF !letter(argp->argval[0]) THEN wdset=0 FI
54 
55 		peekc=c|MARK;
56 		IF argp->argval[1]==0 ANDF (d=argp->argval[0], digit(d)) ANDF (c=='>' ORF c=='<')
57 		THEN	word(); wdnum=d-'0';
58 		ELSE	/*check for reserved words*/
59 			IF reserv==FALSE ORF (wdval=syslook(argp->argval,reserved))==0
60 			THEN	wdarg=argp; wdval=0;
61 			FI
62 		FI
63 
64 	ELIF dipchar(c)
65 	THEN	IF (d=nextc(0))==c
66 		THEN	wdval = c|SYMREP;
67 		ELSE	peekc = d|MARK; wdval = c;
68 		FI
69 	ELSE	IF (wdval=c)==EOF
70 		THEN	wdval=EOFSYM;
71 		FI
72 		IF iopend ANDF eolchar(c)
73 		THEN	copy(iopend); iopend=0;
74 		FI
75 	FI
76 	reserv=FALSE;
77 	return(wdval);
78 }
79 
80 nextc(quote)
81 	CHAR		quote;
82 {
83 	REG CHAR	c, d;
84 	IF (d=readc())==ESCAPE
85 	THEN	IF (c=readc())==NL
86 		THEN	chkpr(NL); d=nextc(quote);
87 		ELIF quote ANDF c!=quote ANDF !escchar(c)
88 		THEN	peekc=c|MARK;
89 		ELSE	d = c|QUOTE;
90 		FI
91 	FI
92 	return(d);
93 }
94 
95 readc()
96 {
97 	REG CHAR	c;
98 	REG INT		len;
99 	REG FILE	f;
100 
101 retry:
102 	IF peekc
103 	THEN	c=peekc; peekc=0;
104 	ELIF (f=standin, f->fnxt!=f->fend)
105 	THEN	IF (c = *f->fnxt++)==0
106 		THEN	IF f->feval
107 			THEN	IF estabf(*f->feval++)
108 				THEN	c=EOF;
109 				ELSE	c=SP;
110 				FI
111 			ELSE	goto retry; /* = c=readc(); */
112 			FI
113 		FI
114 		IF flags&readpr ANDF standin->fstak==0 THEN prc(c) FI
115 		IF c==NL THEN f->flin++ FI
116 	ELIF f->feof ORF f->fdes<0
117 	THEN	c=EOF; f->feof++;
118 	ELIF (len=readb())<=0
119 	THEN	close(f->fdes); f->fdes = -1; c=EOF; f->feof++;
120 	ELSE	f->fend = (f->fnxt = f->fbuf)+len;
121 		goto retry;
122 	FI
123 	return(c);
124 }
125 
126 LOCAL	readb()
127 {
128 	REG FILE	f=standin;
129 	REG INT		len;
130 
131 	IF setjmp(INTbuf) == 0 THEN trapjmp[INTR] = 1; FI
132 	REP	IF trapnote&SIGSET THEN newline(); sigchk() FI
133 	PER (len=read(f->fdes,f->fbuf,f->fsiz))<0 ANDF trapnote DONE
134 	trapjmp[INTR] = 0;
135 	return(len);
136 }
137