xref: /titanic_54/usr/src/cmd/csh/sh.exp.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright 1995 Sun Microsystems, Inc.  All rights reserved.
3*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
4*7c478bd9Sstevel@tonic-gate  */
5*7c478bd9Sstevel@tonic-gate 
6*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
7*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
8*7c478bd9Sstevel@tonic-gate 
9*7c478bd9Sstevel@tonic-gate /*
10*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
11*7c478bd9Sstevel@tonic-gate  * All rights reserved.  The Berkeley Software License Agreement
12*7c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
13*7c478bd9Sstevel@tonic-gate  */
14*7c478bd9Sstevel@tonic-gate 
15*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
16*7c478bd9Sstevel@tonic-gate 
17*7c478bd9Sstevel@tonic-gate #include "sh.h"
18*7c478bd9Sstevel@tonic-gate #include "sh.tconst.h"
19*7c478bd9Sstevel@tonic-gate 
20*7c478bd9Sstevel@tonic-gate /*
21*7c478bd9Sstevel@tonic-gate  * C shell
22*7c478bd9Sstevel@tonic-gate  */
23*7c478bd9Sstevel@tonic-gate 
24*7c478bd9Sstevel@tonic-gate #define IGNORE	1	/* in ignore, it means to ignore value, just parse */
25*7c478bd9Sstevel@tonic-gate #define NOGLOB	2	/* in ignore, it means not to globone */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #define	ADDOP	1
28*7c478bd9Sstevel@tonic-gate #define	MULOP	2
29*7c478bd9Sstevel@tonic-gate #define	EQOP	4
30*7c478bd9Sstevel@tonic-gate #define	RELOP	8
31*7c478bd9Sstevel@tonic-gate #define	RESTOP	16
32*7c478bd9Sstevel@tonic-gate #define	ANYOP	31
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate #define	EQEQ	1
35*7c478bd9Sstevel@tonic-gate #define	GTR	2
36*7c478bd9Sstevel@tonic-gate #define	LSS	4
37*7c478bd9Sstevel@tonic-gate #define	NOTEQ	6
38*7c478bd9Sstevel@tonic-gate #define EQMATCH 7
39*7c478bd9Sstevel@tonic-gate #define NOTEQMATCH 8
40*7c478bd9Sstevel@tonic-gate 
41*7c478bd9Sstevel@tonic-gate /*
42*7c478bd9Sstevel@tonic-gate  * Determine if file given by name is accessible with permissions
43*7c478bd9Sstevel@tonic-gate  * given by mode.
44*7c478bd9Sstevel@tonic-gate  *
45*7c478bd9Sstevel@tonic-gate  * Borrowed from the Bourne sh, and modified a bit
46*7c478bd9Sstevel@tonic-gate  *
47*7c478bd9Sstevel@tonic-gate  * If the requested access  is  permitted,  a  value  of  0  is
48*7c478bd9Sstevel@tonic-gate  * returned.  Otherwise, a value of -1 is returned and errno is
49*7c478bd9Sstevel@tonic-gate  * set to indicate the error
50*7c478bd9Sstevel@tonic-gate  */
51*7c478bd9Sstevel@tonic-gate 
52*7c478bd9Sstevel@tonic-gate chk_access(path, mode)
53*7c478bd9Sstevel@tonic-gate register tchar *path;
54*7c478bd9Sstevel@tonic-gate mode_t mode;
55*7c478bd9Sstevel@tonic-gate {
56*7c478bd9Sstevel@tonic-gate 	static int flag;
57*7c478bd9Sstevel@tonic-gate 	static uid_t euid;
58*7c478bd9Sstevel@tonic-gate 	struct stat statb;
59*7c478bd9Sstevel@tonic-gate 	mode_t ftype;
60*7c478bd9Sstevel@tonic-gate 	unsigned char name[MAXPATHLEN*MB_LEN_MAX]; /* General use buffer. */
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate 	/* convert tchar * to char * */
63*7c478bd9Sstevel@tonic-gate 	tstostr(name, path);
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate 	if(flag == 0) {
66*7c478bd9Sstevel@tonic-gate 		euid = geteuid();
67*7c478bd9Sstevel@tonic-gate 		flag = 1;
68*7c478bd9Sstevel@tonic-gate 	}
69*7c478bd9Sstevel@tonic-gate 	if (stat((char *)name, &statb) == 0) {
70*7c478bd9Sstevel@tonic-gate 		ftype = statb.st_mode & S_IFMT;
71*7c478bd9Sstevel@tonic-gate 		if(access((char *)name, 010|(mode>>6)) == 0) {
72*7c478bd9Sstevel@tonic-gate 			if(euid == 0) {
73*7c478bd9Sstevel@tonic-gate 				if (ftype != S_IFREG || mode != S_IEXEC)
74*7c478bd9Sstevel@tonic-gate 					return(0);
75*7c478bd9Sstevel@tonic-gate 		    		/* root can execute file as long as it has execute
76*7c478bd9Sstevel@tonic-gate 			   	permission for someone */
77*7c478bd9Sstevel@tonic-gate 				if (statb.st_mode & (S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6)))
78*7c478bd9Sstevel@tonic-gate 					return(0);
79*7c478bd9Sstevel@tonic-gate 				return(-1);
80*7c478bd9Sstevel@tonic-gate 			}
81*7c478bd9Sstevel@tonic-gate 			return(0);
82*7c478bd9Sstevel@tonic-gate 		}
83*7c478bd9Sstevel@tonic-gate 	}
84*7c478bd9Sstevel@tonic-gate 	return(-1);
85*7c478bd9Sstevel@tonic-gate }
86*7c478bd9Sstevel@tonic-gate 
87*7c478bd9Sstevel@tonic-gate exp(vp)
88*7c478bd9Sstevel@tonic-gate 	register tchar ***vp;
89*7c478bd9Sstevel@tonic-gate {
90*7c478bd9Sstevel@tonic-gate #ifdef TRACE
91*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- exp()\n");
92*7c478bd9Sstevel@tonic-gate #endif
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate 	return (exp0(vp, 0));
95*7c478bd9Sstevel@tonic-gate }
96*7c478bd9Sstevel@tonic-gate 
97*7c478bd9Sstevel@tonic-gate exp0(vp, ignore)
98*7c478bd9Sstevel@tonic-gate 	register tchar ***vp;
99*7c478bd9Sstevel@tonic-gate 	bool ignore;
100*7c478bd9Sstevel@tonic-gate {
101*7c478bd9Sstevel@tonic-gate 	register int p1 = exp1(vp, ignore);
102*7c478bd9Sstevel@tonic-gate #ifdef TRACE
103*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- exp0()\n");
104*7c478bd9Sstevel@tonic-gate #endif
105*7c478bd9Sstevel@tonic-gate 
106*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
107*7c478bd9Sstevel@tonic-gate 	etraci("exp0 p1", p1, vp);
108*7c478bd9Sstevel@tonic-gate #endif
109*7c478bd9Sstevel@tonic-gate 	if (**vp && eq(**vp, S_BARBAR /*"||"*/)) {
110*7c478bd9Sstevel@tonic-gate 		register int p2;
111*7c478bd9Sstevel@tonic-gate 
112*7c478bd9Sstevel@tonic-gate 		(*vp)++;
113*7c478bd9Sstevel@tonic-gate 		p2 = exp0(vp, (ignore&IGNORE) || p1);
114*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
115*7c478bd9Sstevel@tonic-gate 		etraci("exp0 p2", p2, vp);
116*7c478bd9Sstevel@tonic-gate #endif
117*7c478bd9Sstevel@tonic-gate 		return (p1 || p2);
118*7c478bd9Sstevel@tonic-gate 	}
119*7c478bd9Sstevel@tonic-gate 	return (p1);
120*7c478bd9Sstevel@tonic-gate }
121*7c478bd9Sstevel@tonic-gate 
122*7c478bd9Sstevel@tonic-gate exp1(vp, ignore)
123*7c478bd9Sstevel@tonic-gate 	register tchar ***vp;
124*7c478bd9Sstevel@tonic-gate {
125*7c478bd9Sstevel@tonic-gate 	register int p1 = exp2(vp, ignore);
126*7c478bd9Sstevel@tonic-gate 
127*7c478bd9Sstevel@tonic-gate #ifdef TRACE
128*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- exp1()\n");
129*7c478bd9Sstevel@tonic-gate #endif
130*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
131*7c478bd9Sstevel@tonic-gate 	etraci("exp1 p1", p1, vp);
132*7c478bd9Sstevel@tonic-gate #endif
133*7c478bd9Sstevel@tonic-gate 	if (**vp && eq(**vp, S_ANDAND /*"&&" */)) {
134*7c478bd9Sstevel@tonic-gate 		register int p2;
135*7c478bd9Sstevel@tonic-gate 
136*7c478bd9Sstevel@tonic-gate 		(*vp)++;
137*7c478bd9Sstevel@tonic-gate 		p2 = exp1(vp, (ignore&IGNORE) || !p1);
138*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
139*7c478bd9Sstevel@tonic-gate 		etraci("exp1 p2", p2, vp);
140*7c478bd9Sstevel@tonic-gate #endif
141*7c478bd9Sstevel@tonic-gate 		return (p1 && p2);
142*7c478bd9Sstevel@tonic-gate 	}
143*7c478bd9Sstevel@tonic-gate 	return (p1);
144*7c478bd9Sstevel@tonic-gate }
145*7c478bd9Sstevel@tonic-gate 
146*7c478bd9Sstevel@tonic-gate exp2(vp, ignore)
147*7c478bd9Sstevel@tonic-gate 	register tchar ***vp;
148*7c478bd9Sstevel@tonic-gate 	bool ignore;
149*7c478bd9Sstevel@tonic-gate {
150*7c478bd9Sstevel@tonic-gate 	register int p1 = exp2a(vp, ignore);
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate #ifdef TRACE
153*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- exp2()\n");
154*7c478bd9Sstevel@tonic-gate #endif
155*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
156*7c478bd9Sstevel@tonic-gate 	etraci("exp3 p1", p1, vp);
157*7c478bd9Sstevel@tonic-gate #endif
158*7c478bd9Sstevel@tonic-gate 	if (**vp && eq(**vp, S_BAR /*"|" */)) {
159*7c478bd9Sstevel@tonic-gate 		register int p2;
160*7c478bd9Sstevel@tonic-gate 
161*7c478bd9Sstevel@tonic-gate 		(*vp)++;
162*7c478bd9Sstevel@tonic-gate 		p2 = exp2(vp, ignore);
163*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
164*7c478bd9Sstevel@tonic-gate 		etraci("exp3 p2", p2, vp);
165*7c478bd9Sstevel@tonic-gate #endif
166*7c478bd9Sstevel@tonic-gate 		return (p1 | p2);
167*7c478bd9Sstevel@tonic-gate 	}
168*7c478bd9Sstevel@tonic-gate 	return (p1);
169*7c478bd9Sstevel@tonic-gate }
170*7c478bd9Sstevel@tonic-gate 
171*7c478bd9Sstevel@tonic-gate exp2a(vp, ignore)
172*7c478bd9Sstevel@tonic-gate 	register tchar ***vp;
173*7c478bd9Sstevel@tonic-gate 	bool ignore;
174*7c478bd9Sstevel@tonic-gate {
175*7c478bd9Sstevel@tonic-gate 	register int p1 = exp2b(vp, ignore);
176*7c478bd9Sstevel@tonic-gate 
177*7c478bd9Sstevel@tonic-gate #ifdef TRACE
178*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- exp2a()\n");
179*7c478bd9Sstevel@tonic-gate #endif
180*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
181*7c478bd9Sstevel@tonic-gate 	etraci("exp2a p1", p1, vp);
182*7c478bd9Sstevel@tonic-gate #endif
183*7c478bd9Sstevel@tonic-gate 	if (**vp && eq(**vp, S_HAT /*"^" */)) {
184*7c478bd9Sstevel@tonic-gate 		register int p2;
185*7c478bd9Sstevel@tonic-gate 
186*7c478bd9Sstevel@tonic-gate 		(*vp)++;
187*7c478bd9Sstevel@tonic-gate 		p2 = exp2a(vp, ignore);
188*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
189*7c478bd9Sstevel@tonic-gate 		etraci("exp2a p2", p2, vp);
190*7c478bd9Sstevel@tonic-gate #endif
191*7c478bd9Sstevel@tonic-gate 		return (p1 ^ p2);
192*7c478bd9Sstevel@tonic-gate 	}
193*7c478bd9Sstevel@tonic-gate 	return (p1);
194*7c478bd9Sstevel@tonic-gate }
195*7c478bd9Sstevel@tonic-gate 
196*7c478bd9Sstevel@tonic-gate exp2b(vp, ignore)
197*7c478bd9Sstevel@tonic-gate 	register tchar ***vp;
198*7c478bd9Sstevel@tonic-gate 	bool ignore;
199*7c478bd9Sstevel@tonic-gate {
200*7c478bd9Sstevel@tonic-gate 	register int p1 = exp2c(vp, ignore);
201*7c478bd9Sstevel@tonic-gate 
202*7c478bd9Sstevel@tonic-gate #ifdef TRACE
203*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- exp2b()\n");
204*7c478bd9Sstevel@tonic-gate #endif
205*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
206*7c478bd9Sstevel@tonic-gate 	etraci("exp2b p1", p1, vp);
207*7c478bd9Sstevel@tonic-gate #endif
208*7c478bd9Sstevel@tonic-gate 	if (**vp && eq(**vp, S_AND /*"&"*/)) {
209*7c478bd9Sstevel@tonic-gate 		register int p2;
210*7c478bd9Sstevel@tonic-gate 
211*7c478bd9Sstevel@tonic-gate 		(*vp)++;
212*7c478bd9Sstevel@tonic-gate 		p2 = exp2b(vp, ignore);
213*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
214*7c478bd9Sstevel@tonic-gate 		etraci("exp2b p2", p2, vp);
215*7c478bd9Sstevel@tonic-gate #endif
216*7c478bd9Sstevel@tonic-gate 		return (p1 & p2);
217*7c478bd9Sstevel@tonic-gate 	}
218*7c478bd9Sstevel@tonic-gate 	return (p1);
219*7c478bd9Sstevel@tonic-gate }
220*7c478bd9Sstevel@tonic-gate 
221*7c478bd9Sstevel@tonic-gate exp2c(vp, ignore)
222*7c478bd9Sstevel@tonic-gate 	register tchar ***vp;
223*7c478bd9Sstevel@tonic-gate 	bool ignore;
224*7c478bd9Sstevel@tonic-gate {
225*7c478bd9Sstevel@tonic-gate 	register tchar *p1 = exp3(vp, ignore);
226*7c478bd9Sstevel@tonic-gate 	register tchar *p2;
227*7c478bd9Sstevel@tonic-gate 	register int i;
228*7c478bd9Sstevel@tonic-gate 
229*7c478bd9Sstevel@tonic-gate #ifdef TRACE
230*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- exp2c()\n");
231*7c478bd9Sstevel@tonic-gate #endif
232*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
233*7c478bd9Sstevel@tonic-gate 	etracc("exp2c p1", p1, vp);
234*7c478bd9Sstevel@tonic-gate #endif
235*7c478bd9Sstevel@tonic-gate 	if (i = isa(**vp, EQOP)) {
236*7c478bd9Sstevel@tonic-gate 		(*vp)++;
237*7c478bd9Sstevel@tonic-gate 		if (i == EQMATCH || i == NOTEQMATCH)
238*7c478bd9Sstevel@tonic-gate 			ignore |= NOGLOB;
239*7c478bd9Sstevel@tonic-gate 		p2 = exp3(vp, ignore);
240*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
241*7c478bd9Sstevel@tonic-gate 		etracc("exp2c p2", p2, vp);
242*7c478bd9Sstevel@tonic-gate #endif
243*7c478bd9Sstevel@tonic-gate 		if (!(ignore&IGNORE)) switch (i) {
244*7c478bd9Sstevel@tonic-gate 
245*7c478bd9Sstevel@tonic-gate 		case EQEQ:
246*7c478bd9Sstevel@tonic-gate 			i = eq(p1, p2);
247*7c478bd9Sstevel@tonic-gate 			break;
248*7c478bd9Sstevel@tonic-gate 
249*7c478bd9Sstevel@tonic-gate 		case NOTEQ:
250*7c478bd9Sstevel@tonic-gate 			i = !eq(p1, p2);
251*7c478bd9Sstevel@tonic-gate 			break;
252*7c478bd9Sstevel@tonic-gate 
253*7c478bd9Sstevel@tonic-gate 		case EQMATCH:
254*7c478bd9Sstevel@tonic-gate 			i = Gmatch(p1, p2);
255*7c478bd9Sstevel@tonic-gate 			break;
256*7c478bd9Sstevel@tonic-gate 
257*7c478bd9Sstevel@tonic-gate 		case NOTEQMATCH:
258*7c478bd9Sstevel@tonic-gate 			i = !Gmatch(p1, p2);
259*7c478bd9Sstevel@tonic-gate 			break;
260*7c478bd9Sstevel@tonic-gate 		}
261*7c478bd9Sstevel@tonic-gate 		xfree(p1), xfree(p2);
262*7c478bd9Sstevel@tonic-gate 		return (i);
263*7c478bd9Sstevel@tonic-gate 	}
264*7c478bd9Sstevel@tonic-gate 	i = egetn(p1);
265*7c478bd9Sstevel@tonic-gate 	xfree(p1);
266*7c478bd9Sstevel@tonic-gate 	return (i);
267*7c478bd9Sstevel@tonic-gate }
268*7c478bd9Sstevel@tonic-gate 
269*7c478bd9Sstevel@tonic-gate tchar *
270*7c478bd9Sstevel@tonic-gate exp3(vp, ignore)
271*7c478bd9Sstevel@tonic-gate 	register tchar ***vp;
272*7c478bd9Sstevel@tonic-gate 	bool ignore;
273*7c478bd9Sstevel@tonic-gate {
274*7c478bd9Sstevel@tonic-gate 	register tchar *p1, *p2;
275*7c478bd9Sstevel@tonic-gate 	register int i;
276*7c478bd9Sstevel@tonic-gate 
277*7c478bd9Sstevel@tonic-gate #ifdef TRACE
278*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- exp3()\n");
279*7c478bd9Sstevel@tonic-gate #endif
280*7c478bd9Sstevel@tonic-gate 	p1 = exp3a(vp, ignore);
281*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
282*7c478bd9Sstevel@tonic-gate 	etracc("exp3 p1", p1, vp);
283*7c478bd9Sstevel@tonic-gate #endif
284*7c478bd9Sstevel@tonic-gate 	if (i = isa(**vp, RELOP)) {
285*7c478bd9Sstevel@tonic-gate 		(*vp)++;
286*7c478bd9Sstevel@tonic-gate 		if (**vp && eq(**vp, S_EQ /*"=" */))
287*7c478bd9Sstevel@tonic-gate 			i |= 1, (*vp)++;
288*7c478bd9Sstevel@tonic-gate 		p2 = exp3(vp, ignore);
289*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
290*7c478bd9Sstevel@tonic-gate 		etracc("exp3 p2", p2, vp);
291*7c478bd9Sstevel@tonic-gate #endif
292*7c478bd9Sstevel@tonic-gate 		if (!(ignore&IGNORE)) switch (i) {
293*7c478bd9Sstevel@tonic-gate 
294*7c478bd9Sstevel@tonic-gate 		case GTR:
295*7c478bd9Sstevel@tonic-gate 			i = egetn(p1) > egetn(p2);
296*7c478bd9Sstevel@tonic-gate 			break;
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate 		case GTR|1:
299*7c478bd9Sstevel@tonic-gate 			i = egetn(p1) >= egetn(p2);
300*7c478bd9Sstevel@tonic-gate 			break;
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate 		case LSS:
303*7c478bd9Sstevel@tonic-gate 			i = egetn(p1) < egetn(p2);
304*7c478bd9Sstevel@tonic-gate 			break;
305*7c478bd9Sstevel@tonic-gate 
306*7c478bd9Sstevel@tonic-gate 		case LSS|1:
307*7c478bd9Sstevel@tonic-gate 			i = egetn(p1) <= egetn(p2);
308*7c478bd9Sstevel@tonic-gate 			break;
309*7c478bd9Sstevel@tonic-gate 		}
310*7c478bd9Sstevel@tonic-gate 		xfree(p1), xfree(p2);
311*7c478bd9Sstevel@tonic-gate 		return (putn(i));
312*7c478bd9Sstevel@tonic-gate 	}
313*7c478bd9Sstevel@tonic-gate 	return (p1);
314*7c478bd9Sstevel@tonic-gate }
315*7c478bd9Sstevel@tonic-gate 
316*7c478bd9Sstevel@tonic-gate tchar *
317*7c478bd9Sstevel@tonic-gate exp3a(vp, ignore)
318*7c478bd9Sstevel@tonic-gate 	register tchar ***vp;
319*7c478bd9Sstevel@tonic-gate 	bool ignore;
320*7c478bd9Sstevel@tonic-gate {
321*7c478bd9Sstevel@tonic-gate 	register tchar *p1, *p2, *op;
322*7c478bd9Sstevel@tonic-gate 	register int i;
323*7c478bd9Sstevel@tonic-gate 
324*7c478bd9Sstevel@tonic-gate #ifdef TRACE
325*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- exp3a()\n");
326*7c478bd9Sstevel@tonic-gate #endif
327*7c478bd9Sstevel@tonic-gate 	p1 = exp4(vp, ignore);
328*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
329*7c478bd9Sstevel@tonic-gate 	etracc("exp3a p1", p1, vp);
330*7c478bd9Sstevel@tonic-gate #endif
331*7c478bd9Sstevel@tonic-gate 	op = **vp;
332*7c478bd9Sstevel@tonic-gate 	/* if (op && any(op[0], "<>") && op[0] == op[1]) { */
333*7c478bd9Sstevel@tonic-gate 	if (op && (op[0] == '<' || op[0] == '>') && op[0] == op[1]) {
334*7c478bd9Sstevel@tonic-gate 		(*vp)++;
335*7c478bd9Sstevel@tonic-gate 		p2 = exp3a(vp, ignore);
336*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
337*7c478bd9Sstevel@tonic-gate 		etracc("exp3a p2", p2, vp);
338*7c478bd9Sstevel@tonic-gate #endif
339*7c478bd9Sstevel@tonic-gate 		if (op[0] == '<')
340*7c478bd9Sstevel@tonic-gate 			i = egetn(p1) << egetn(p2);
341*7c478bd9Sstevel@tonic-gate 		else
342*7c478bd9Sstevel@tonic-gate 			i = egetn(p1) >> egetn(p2);
343*7c478bd9Sstevel@tonic-gate 		xfree(p1), xfree(p2);
344*7c478bd9Sstevel@tonic-gate 		return (putn(i));
345*7c478bd9Sstevel@tonic-gate 	}
346*7c478bd9Sstevel@tonic-gate 	return (p1);
347*7c478bd9Sstevel@tonic-gate }
348*7c478bd9Sstevel@tonic-gate 
349*7c478bd9Sstevel@tonic-gate tchar *
350*7c478bd9Sstevel@tonic-gate exp4(vp, ignore)
351*7c478bd9Sstevel@tonic-gate 	register tchar ***vp;
352*7c478bd9Sstevel@tonic-gate 	bool ignore;
353*7c478bd9Sstevel@tonic-gate {
354*7c478bd9Sstevel@tonic-gate 	register tchar *p1, *p2;
355*7c478bd9Sstevel@tonic-gate 	register int i = 0;
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate #ifdef TRACE
358*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- exp4()\n");
359*7c478bd9Sstevel@tonic-gate #endif
360*7c478bd9Sstevel@tonic-gate 	p1 = exp5(vp, ignore);
361*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
362*7c478bd9Sstevel@tonic-gate 	etracc("exp4 p1", p1, vp);
363*7c478bd9Sstevel@tonic-gate #endif
364*7c478bd9Sstevel@tonic-gate 	if (isa(**vp, ADDOP)) {
365*7c478bd9Sstevel@tonic-gate 		register tchar *op = *(*vp)++;
366*7c478bd9Sstevel@tonic-gate 
367*7c478bd9Sstevel@tonic-gate 		p2 = exp4(vp, ignore);
368*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
369*7c478bd9Sstevel@tonic-gate 		etracc("exp4 p2", p2, vp);
370*7c478bd9Sstevel@tonic-gate #endif
371*7c478bd9Sstevel@tonic-gate 		if (!(ignore&IGNORE)) switch (op[0]) {
372*7c478bd9Sstevel@tonic-gate 
373*7c478bd9Sstevel@tonic-gate 		case '+':
374*7c478bd9Sstevel@tonic-gate 			i = egetn(p1) + egetn(p2);
375*7c478bd9Sstevel@tonic-gate 			break;
376*7c478bd9Sstevel@tonic-gate 
377*7c478bd9Sstevel@tonic-gate 		case '-':
378*7c478bd9Sstevel@tonic-gate 			i = egetn(p1) - egetn(p2);
379*7c478bd9Sstevel@tonic-gate 			break;
380*7c478bd9Sstevel@tonic-gate 		}
381*7c478bd9Sstevel@tonic-gate 		xfree(p1), xfree(p2);
382*7c478bd9Sstevel@tonic-gate 		return (putn(i));
383*7c478bd9Sstevel@tonic-gate 	}
384*7c478bd9Sstevel@tonic-gate 	return (p1);
385*7c478bd9Sstevel@tonic-gate }
386*7c478bd9Sstevel@tonic-gate 
387*7c478bd9Sstevel@tonic-gate tchar *
388*7c478bd9Sstevel@tonic-gate exp5(vp, ignore)
389*7c478bd9Sstevel@tonic-gate 	register tchar ***vp;
390*7c478bd9Sstevel@tonic-gate 	bool ignore;
391*7c478bd9Sstevel@tonic-gate {
392*7c478bd9Sstevel@tonic-gate 	register tchar *p1, *p2;
393*7c478bd9Sstevel@tonic-gate 	register int i = 0;
394*7c478bd9Sstevel@tonic-gate 
395*7c478bd9Sstevel@tonic-gate #ifdef TRACE
396*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- exp5()\n");
397*7c478bd9Sstevel@tonic-gate #endif
398*7c478bd9Sstevel@tonic-gate 	p1 = exp6(vp, ignore);
399*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
400*7c478bd9Sstevel@tonic-gate 	etracc("exp5 p1", p1, vp);
401*7c478bd9Sstevel@tonic-gate #endif
402*7c478bd9Sstevel@tonic-gate 	if (isa(**vp, MULOP)) {
403*7c478bd9Sstevel@tonic-gate 		register tchar *op = *(*vp)++;
404*7c478bd9Sstevel@tonic-gate 
405*7c478bd9Sstevel@tonic-gate 		p2 = exp5(vp, ignore);
406*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
407*7c478bd9Sstevel@tonic-gate 		etracc("exp5 p2", p2, vp);
408*7c478bd9Sstevel@tonic-gate #endif
409*7c478bd9Sstevel@tonic-gate 		if (!(ignore&IGNORE)) switch (op[0]) {
410*7c478bd9Sstevel@tonic-gate 
411*7c478bd9Sstevel@tonic-gate 		case '*':
412*7c478bd9Sstevel@tonic-gate 			i = egetn(p1) * egetn(p2);
413*7c478bd9Sstevel@tonic-gate 			break;
414*7c478bd9Sstevel@tonic-gate 
415*7c478bd9Sstevel@tonic-gate 		case '/':
416*7c478bd9Sstevel@tonic-gate 			i = egetn(p2);
417*7c478bd9Sstevel@tonic-gate 			if (i == 0)
418*7c478bd9Sstevel@tonic-gate 				error("Divide by 0");
419*7c478bd9Sstevel@tonic-gate 			i = egetn(p1) / i;
420*7c478bd9Sstevel@tonic-gate 			break;
421*7c478bd9Sstevel@tonic-gate 
422*7c478bd9Sstevel@tonic-gate 		case '%':
423*7c478bd9Sstevel@tonic-gate 			i = egetn(p2);
424*7c478bd9Sstevel@tonic-gate 			if (i == 0)
425*7c478bd9Sstevel@tonic-gate 				error("Mod by 0");
426*7c478bd9Sstevel@tonic-gate 			i = egetn(p1) % i;
427*7c478bd9Sstevel@tonic-gate 			break;
428*7c478bd9Sstevel@tonic-gate 		}
429*7c478bd9Sstevel@tonic-gate 		xfree(p1), xfree(p2);
430*7c478bd9Sstevel@tonic-gate 		return (putn(i));
431*7c478bd9Sstevel@tonic-gate 	}
432*7c478bd9Sstevel@tonic-gate 	return (p1);
433*7c478bd9Sstevel@tonic-gate }
434*7c478bd9Sstevel@tonic-gate 
435*7c478bd9Sstevel@tonic-gate tchar *
436*7c478bd9Sstevel@tonic-gate exp6(vp, ignore)
437*7c478bd9Sstevel@tonic-gate 	register tchar ***vp;
438*7c478bd9Sstevel@tonic-gate {
439*7c478bd9Sstevel@tonic-gate 	int ccode, i;
440*7c478bd9Sstevel@tonic-gate 	register tchar *cp, *dp, *ep;
441*7c478bd9Sstevel@tonic-gate 
442*7c478bd9Sstevel@tonic-gate #ifdef TRACE
443*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- exp6()\n");
444*7c478bd9Sstevel@tonic-gate #endif
445*7c478bd9Sstevel@tonic-gate 	if (**vp == 0)
446*7c478bd9Sstevel@tonic-gate 		bferr("Expression syntax");
447*7c478bd9Sstevel@tonic-gate 	if (eq(**vp, S_EXAS /* "!" */)) {
448*7c478bd9Sstevel@tonic-gate 		(*vp)++;
449*7c478bd9Sstevel@tonic-gate 		cp = exp6(vp, ignore);
450*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
451*7c478bd9Sstevel@tonic-gate 		etracc("exp6 ! cp", cp, vp);
452*7c478bd9Sstevel@tonic-gate #endif
453*7c478bd9Sstevel@tonic-gate 		i = egetn(cp);
454*7c478bd9Sstevel@tonic-gate 		xfree(cp);
455*7c478bd9Sstevel@tonic-gate 		return (putn(!i));
456*7c478bd9Sstevel@tonic-gate 	}
457*7c478bd9Sstevel@tonic-gate 	if (eq(**vp, S_TIL /*"~" */)) {
458*7c478bd9Sstevel@tonic-gate 		(*vp)++;
459*7c478bd9Sstevel@tonic-gate 		cp = exp6(vp, ignore);
460*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
461*7c478bd9Sstevel@tonic-gate 		etracc("exp6 ~ cp", cp, vp);
462*7c478bd9Sstevel@tonic-gate #endif
463*7c478bd9Sstevel@tonic-gate 		i = egetn(cp);
464*7c478bd9Sstevel@tonic-gate 		xfree(cp);
465*7c478bd9Sstevel@tonic-gate 		return (putn(~i));
466*7c478bd9Sstevel@tonic-gate 	}
467*7c478bd9Sstevel@tonic-gate 	if (eq(**vp, S_LPAR /*"(" */)) {
468*7c478bd9Sstevel@tonic-gate 		(*vp)++;
469*7c478bd9Sstevel@tonic-gate 		ccode = exp0(vp, ignore);
470*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
471*7c478bd9Sstevel@tonic-gate 		etraci("exp6 () ccode", ccode, vp);
472*7c478bd9Sstevel@tonic-gate #endif
473*7c478bd9Sstevel@tonic-gate 		if (*vp == 0 || **vp == 0 || ***vp != ')')
474*7c478bd9Sstevel@tonic-gate 			bferr("Expression syntax");
475*7c478bd9Sstevel@tonic-gate 		(*vp)++;
476*7c478bd9Sstevel@tonic-gate 		return (putn(ccode));
477*7c478bd9Sstevel@tonic-gate 	}
478*7c478bd9Sstevel@tonic-gate 	if (eq(**vp, S_LBRA /* "{" */)) {
479*7c478bd9Sstevel@tonic-gate 		register tchar **v;
480*7c478bd9Sstevel@tonic-gate 		struct command faket;
481*7c478bd9Sstevel@tonic-gate 		tchar *fakecom[2];
482*7c478bd9Sstevel@tonic-gate 
483*7c478bd9Sstevel@tonic-gate 		faket.t_dtyp = TCOM;
484*7c478bd9Sstevel@tonic-gate 		faket.t_dflg = 0;
485*7c478bd9Sstevel@tonic-gate 		faket.t_dcar = faket.t_dcdr = faket.t_dspr = (struct command *)0;
486*7c478bd9Sstevel@tonic-gate 		faket.t_dcom = fakecom;
487*7c478bd9Sstevel@tonic-gate 		fakecom[0] = S_BRAPPPBRA /*"{ ... }" */;
488*7c478bd9Sstevel@tonic-gate 		fakecom[1] = NOSTR;
489*7c478bd9Sstevel@tonic-gate 		(*vp)++;
490*7c478bd9Sstevel@tonic-gate 		v = *vp;
491*7c478bd9Sstevel@tonic-gate 		for (;;) {
492*7c478bd9Sstevel@tonic-gate 			if (!**vp)
493*7c478bd9Sstevel@tonic-gate 				bferr("Missing }");
494*7c478bd9Sstevel@tonic-gate 			if (eq(*(*vp)++, S_RBRA /*"}" */))
495*7c478bd9Sstevel@tonic-gate 				break;
496*7c478bd9Sstevel@tonic-gate 		}
497*7c478bd9Sstevel@tonic-gate 		if (ignore&IGNORE)
498*7c478bd9Sstevel@tonic-gate 			return (S_ /*""*/);
499*7c478bd9Sstevel@tonic-gate 		psavejob();
500*7c478bd9Sstevel@tonic-gate 		if (pfork(&faket, -1) == 0) {
501*7c478bd9Sstevel@tonic-gate 			*--(*vp) = 0;
502*7c478bd9Sstevel@tonic-gate 			evalav(v);
503*7c478bd9Sstevel@tonic-gate 			exitstat();
504*7c478bd9Sstevel@tonic-gate 		}
505*7c478bd9Sstevel@tonic-gate 		pwait();
506*7c478bd9Sstevel@tonic-gate 		prestjob();
507*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
508*7c478bd9Sstevel@tonic-gate 		etraci("exp6 {} status", egetn(value("status")), vp);
509*7c478bd9Sstevel@tonic-gate #endif
510*7c478bd9Sstevel@tonic-gate 		return (putn(egetn(value(S_status /*"status" */)) == 0));
511*7c478bd9Sstevel@tonic-gate 	}
512*7c478bd9Sstevel@tonic-gate 	if (isa(**vp, ANYOP))
513*7c478bd9Sstevel@tonic-gate 		return (S_ /*""*/);
514*7c478bd9Sstevel@tonic-gate 	cp = *(*vp)++;
515*7c478bd9Sstevel@tonic-gate 	if (*cp == '-' && any(cp[1], S_erwxfdzo /*"erwxfdzo" */)) {
516*7c478bd9Sstevel@tonic-gate 		struct stat stb;
517*7c478bd9Sstevel@tonic-gate 
518*7c478bd9Sstevel@tonic-gate 		if (cp[2] != '\0')
519*7c478bd9Sstevel@tonic-gate 			bferr("Malformed file inquiry");
520*7c478bd9Sstevel@tonic-gate 
521*7c478bd9Sstevel@tonic-gate 		/*
522*7c478bd9Sstevel@tonic-gate 		 * Detect missing file names by checking for operator
523*7c478bd9Sstevel@tonic-gate 		 * in the file name position.  However, if an operator
524*7c478bd9Sstevel@tonic-gate 		 * name appears there, we must make sure that there's
525*7c478bd9Sstevel@tonic-gate 		 * no file by that name (e.g., "/") before announcing
526*7c478bd9Sstevel@tonic-gate 		 * an error.  Even this check isn't quite right, since
527*7c478bd9Sstevel@tonic-gate 		 * it doesn't take globbing into account.
528*7c478bd9Sstevel@tonic-gate 		 */
529*7c478bd9Sstevel@tonic-gate 		if (isa(**vp, ANYOP) && stat_(**vp, &stb))
530*7c478bd9Sstevel@tonic-gate 			bferr("Missing file name");
531*7c478bd9Sstevel@tonic-gate 		dp = *(*vp)++;
532*7c478bd9Sstevel@tonic-gate 
533*7c478bd9Sstevel@tonic-gate 		if (ignore&IGNORE)
534*7c478bd9Sstevel@tonic-gate 			return (S_ /*""*/);
535*7c478bd9Sstevel@tonic-gate 		ep = globone(dp);
536*7c478bd9Sstevel@tonic-gate 		switch (cp[1]) {
537*7c478bd9Sstevel@tonic-gate 
538*7c478bd9Sstevel@tonic-gate 		case 'r':
539*7c478bd9Sstevel@tonic-gate 			i = !chk_access(ep, S_IREAD);
540*7c478bd9Sstevel@tonic-gate 			break;
541*7c478bd9Sstevel@tonic-gate 
542*7c478bd9Sstevel@tonic-gate 		case 'w':
543*7c478bd9Sstevel@tonic-gate 			i = !chk_access(ep, S_IWRITE);
544*7c478bd9Sstevel@tonic-gate 			break;
545*7c478bd9Sstevel@tonic-gate 
546*7c478bd9Sstevel@tonic-gate 		case 'x':
547*7c478bd9Sstevel@tonic-gate 			i = !chk_access(ep, S_IEXEC);
548*7c478bd9Sstevel@tonic-gate 			break;
549*7c478bd9Sstevel@tonic-gate 
550*7c478bd9Sstevel@tonic-gate 		default:
551*7c478bd9Sstevel@tonic-gate 			if (stat_(ep, &stb)) {
552*7c478bd9Sstevel@tonic-gate 				xfree(ep);
553*7c478bd9Sstevel@tonic-gate 				return (S_0 /*"0"*/);
554*7c478bd9Sstevel@tonic-gate 			}
555*7c478bd9Sstevel@tonic-gate 			switch (cp[1]) {
556*7c478bd9Sstevel@tonic-gate 
557*7c478bd9Sstevel@tonic-gate 			case 'f':
558*7c478bd9Sstevel@tonic-gate 				i = (stb.st_mode & S_IFMT) == S_IFREG;
559*7c478bd9Sstevel@tonic-gate 				break;
560*7c478bd9Sstevel@tonic-gate 
561*7c478bd9Sstevel@tonic-gate 			case 'd':
562*7c478bd9Sstevel@tonic-gate 				i = (stb.st_mode & S_IFMT) == S_IFDIR;
563*7c478bd9Sstevel@tonic-gate 				break;
564*7c478bd9Sstevel@tonic-gate 
565*7c478bd9Sstevel@tonic-gate 			case 'z':
566*7c478bd9Sstevel@tonic-gate 				i = stb.st_size == 0;
567*7c478bd9Sstevel@tonic-gate 				break;
568*7c478bd9Sstevel@tonic-gate 
569*7c478bd9Sstevel@tonic-gate 			case 'e':
570*7c478bd9Sstevel@tonic-gate 				i = 1;
571*7c478bd9Sstevel@tonic-gate 				break;
572*7c478bd9Sstevel@tonic-gate 
573*7c478bd9Sstevel@tonic-gate 			case 'o':
574*7c478bd9Sstevel@tonic-gate 				i = stb.st_uid == uid;
575*7c478bd9Sstevel@tonic-gate 				break;
576*7c478bd9Sstevel@tonic-gate 			}
577*7c478bd9Sstevel@tonic-gate 		}
578*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
579*7c478bd9Sstevel@tonic-gate 		etraci("exp6 -? i", i, vp);
580*7c478bd9Sstevel@tonic-gate #endif
581*7c478bd9Sstevel@tonic-gate 		xfree(ep);
582*7c478bd9Sstevel@tonic-gate 		return (putn(i));
583*7c478bd9Sstevel@tonic-gate 	}
584*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
585*7c478bd9Sstevel@tonic-gate 	etracc("exp6 default", cp, vp);
586*7c478bd9Sstevel@tonic-gate #endif
587*7c478bd9Sstevel@tonic-gate 	return (ignore&NOGLOB ? savestr(cp) : globone(cp));
588*7c478bd9Sstevel@tonic-gate }
589*7c478bd9Sstevel@tonic-gate 
590*7c478bd9Sstevel@tonic-gate evalav(v)
591*7c478bd9Sstevel@tonic-gate 	register tchar **v;
592*7c478bd9Sstevel@tonic-gate {
593*7c478bd9Sstevel@tonic-gate 	struct wordent paraml;
594*7c478bd9Sstevel@tonic-gate 	register struct wordent *hp = &paraml;
595*7c478bd9Sstevel@tonic-gate 	struct command *t;
596*7c478bd9Sstevel@tonic-gate 	register struct wordent *wdp = hp;
597*7c478bd9Sstevel@tonic-gate 
598*7c478bd9Sstevel@tonic-gate #ifdef TRACE
599*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- evalav()\n");
600*7c478bd9Sstevel@tonic-gate #endif
601*7c478bd9Sstevel@tonic-gate 	set(S_status /*"status" */, S_0 /*"0"*/);
602*7c478bd9Sstevel@tonic-gate 	hp->prev = hp->next = hp;
603*7c478bd9Sstevel@tonic-gate 	hp->word = S_ /*""*/;
604*7c478bd9Sstevel@tonic-gate 	while (*v) {
605*7c478bd9Sstevel@tonic-gate 		register struct wordent *new = (struct wordent *) calloc(1, sizeof *wdp);
606*7c478bd9Sstevel@tonic-gate 
607*7c478bd9Sstevel@tonic-gate 		new->prev = wdp;
608*7c478bd9Sstevel@tonic-gate 		new->next = hp;
609*7c478bd9Sstevel@tonic-gate 		wdp->next = new;
610*7c478bd9Sstevel@tonic-gate 		wdp = new;
611*7c478bd9Sstevel@tonic-gate 		wdp->word = savestr(*v++);
612*7c478bd9Sstevel@tonic-gate 	}
613*7c478bd9Sstevel@tonic-gate 	hp->prev = wdp;
614*7c478bd9Sstevel@tonic-gate 	alias(&paraml);
615*7c478bd9Sstevel@tonic-gate 	t = syntax(paraml.next, &paraml, 0);
616*7c478bd9Sstevel@tonic-gate 	if (err)
617*7c478bd9Sstevel@tonic-gate 		error("%s", gettext(err));
618*7c478bd9Sstevel@tonic-gate 	execute(t, -1);
619*7c478bd9Sstevel@tonic-gate 	freelex(&paraml), freesyn(t);
620*7c478bd9Sstevel@tonic-gate }
621*7c478bd9Sstevel@tonic-gate 
622*7c478bd9Sstevel@tonic-gate isa(cp, what)
623*7c478bd9Sstevel@tonic-gate 	register tchar *cp;
624*7c478bd9Sstevel@tonic-gate 	register int what;
625*7c478bd9Sstevel@tonic-gate {
626*7c478bd9Sstevel@tonic-gate 
627*7c478bd9Sstevel@tonic-gate #ifdef TRACE
628*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- isa()\n");
629*7c478bd9Sstevel@tonic-gate #endif
630*7c478bd9Sstevel@tonic-gate 	if (cp == 0)
631*7c478bd9Sstevel@tonic-gate 		return ((what & RESTOP) != 0);
632*7c478bd9Sstevel@tonic-gate 	if (cp[1] == 0) {
633*7c478bd9Sstevel@tonic-gate 		if (what & ADDOP && (*cp == '+' || *cp == '-'))
634*7c478bd9Sstevel@tonic-gate 			return (1);
635*7c478bd9Sstevel@tonic-gate 		if (what & MULOP && (*cp == '*' || *cp == '/' || *cp == '%'))
636*7c478bd9Sstevel@tonic-gate 			return (1);
637*7c478bd9Sstevel@tonic-gate 		if (what & RESTOP && (*cp == '(' || *cp == ')' || *cp == '!' ||
638*7c478bd9Sstevel@tonic-gate 				      *cp == '~' || *cp == '^' || *cp == '"'))
639*7c478bd9Sstevel@tonic-gate 			return (1);
640*7c478bd9Sstevel@tonic-gate 	} else if (cp[2] == 0) {
641*7c478bd9Sstevel@tonic-gate 		if (what & RESTOP) {
642*7c478bd9Sstevel@tonic-gate 			if (cp[0] == '|' && cp[1] == '&')
643*7c478bd9Sstevel@tonic-gate 				return (1);
644*7c478bd9Sstevel@tonic-gate 			if (cp[0] == '<' && cp[1] == '<')
645*7c478bd9Sstevel@tonic-gate 				return (1);
646*7c478bd9Sstevel@tonic-gate 			if (cp[0] == '>' && cp[1] == '>')
647*7c478bd9Sstevel@tonic-gate 				return (1);
648*7c478bd9Sstevel@tonic-gate 		}
649*7c478bd9Sstevel@tonic-gate 		if (what & EQOP) {
650*7c478bd9Sstevel@tonic-gate 			if (cp[0] == '=') {
651*7c478bd9Sstevel@tonic-gate 				if (cp[1] == '=')
652*7c478bd9Sstevel@tonic-gate 					return (EQEQ);
653*7c478bd9Sstevel@tonic-gate 				if (cp[1] == '~')
654*7c478bd9Sstevel@tonic-gate 					return (EQMATCH);
655*7c478bd9Sstevel@tonic-gate 			} else if (cp[0] == '!') {
656*7c478bd9Sstevel@tonic-gate 				if (cp[1] == '=')
657*7c478bd9Sstevel@tonic-gate 					return (NOTEQ);
658*7c478bd9Sstevel@tonic-gate 				if (cp[1] == '~')
659*7c478bd9Sstevel@tonic-gate 					return (NOTEQMATCH);
660*7c478bd9Sstevel@tonic-gate 			}
661*7c478bd9Sstevel@tonic-gate 		}
662*7c478bd9Sstevel@tonic-gate 	}
663*7c478bd9Sstevel@tonic-gate 	if (what & RELOP) {
664*7c478bd9Sstevel@tonic-gate 		if (*cp == '<')
665*7c478bd9Sstevel@tonic-gate 			return (LSS);
666*7c478bd9Sstevel@tonic-gate 		if (*cp == '>')
667*7c478bd9Sstevel@tonic-gate 			return (GTR);
668*7c478bd9Sstevel@tonic-gate 	}
669*7c478bd9Sstevel@tonic-gate 	return (0);
670*7c478bd9Sstevel@tonic-gate }
671*7c478bd9Sstevel@tonic-gate 
672*7c478bd9Sstevel@tonic-gate egetn(cp)
673*7c478bd9Sstevel@tonic-gate 	register tchar *cp;
674*7c478bd9Sstevel@tonic-gate {
675*7c478bd9Sstevel@tonic-gate 
676*7c478bd9Sstevel@tonic-gate #ifdef TRACE
677*7c478bd9Sstevel@tonic-gate 	tprintf("TRACE- egetn()\n");
678*7c478bd9Sstevel@tonic-gate #endif
679*7c478bd9Sstevel@tonic-gate 	if (*cp && *cp != '-' && !digit(*cp))
680*7c478bd9Sstevel@tonic-gate 		bferr("Expression syntax");
681*7c478bd9Sstevel@tonic-gate 	return (getn(cp));
682*7c478bd9Sstevel@tonic-gate }
683*7c478bd9Sstevel@tonic-gate 
684*7c478bd9Sstevel@tonic-gate /* Phew! */
685*7c478bd9Sstevel@tonic-gate 
686*7c478bd9Sstevel@tonic-gate #ifdef EDEBUG
687*7c478bd9Sstevel@tonic-gate etraci(str, i, vp)
688*7c478bd9Sstevel@tonic-gate 	tchar *str;
689*7c478bd9Sstevel@tonic-gate 	int i;
690*7c478bd9Sstevel@tonic-gate 	tchar ***vp;
691*7c478bd9Sstevel@tonic-gate {
692*7c478bd9Sstevel@tonic-gate 
693*7c478bd9Sstevel@tonic-gate 	printf("%s=%d\t", str, i);
694*7c478bd9Sstevel@tonic-gate 	blkpr(*vp);
695*7c478bd9Sstevel@tonic-gate 	printf("\n");
696*7c478bd9Sstevel@tonic-gate }
697*7c478bd9Sstevel@tonic-gate 
698*7c478bd9Sstevel@tonic-gate etracc(str, cp, vp)
699*7c478bd9Sstevel@tonic-gate 	tchar *str, *cp;
700*7c478bd9Sstevel@tonic-gate 	tchar ***vp;
701*7c478bd9Sstevel@tonic-gate {
702*7c478bd9Sstevel@tonic-gate 
703*7c478bd9Sstevel@tonic-gate 	printf("%s=%s\t", str, cp);
704*7c478bd9Sstevel@tonic-gate 	blkpr(*vp);
705*7c478bd9Sstevel@tonic-gate 	printf("\n");
706*7c478bd9Sstevel@tonic-gate }
707*7c478bd9Sstevel@tonic-gate #endif
708