include fixes
[unix-history] / usr / src / bin / csh / exp.c
CommitLineData
843d5d49
BJ
1static char *sccsid = "@(#)exp.c 4.1 %G%";
2
3#include "sh.h"
4
5/*
6 * C shell
7 */
8
9#define IGNORE 1 /* in ignore, it means to ignore value, just parse */
10#define NOGLOB 2 /* in ignore, it means not to globone */
11
12#define ADDOP 1
13#define MULOP 2
14#define EQOP 4
15#define RELOP 8
16#define RESTOP 16
17#define ANYOP 31
18
19#define EQEQ 1
20#define GTR 2
21#define LSS 4
22#define NOTEQ 6
23#define EQMATCH 7
24#define NOTEQMATCH 8
25
26exp(vp)
27 register char ***vp;
28{
29
30 return (exp0(vp, 0));
31}
32
33exp0(vp, ignore)
34 register char ***vp;
35 bool ignore;
36{
37 register int p1 = exp1(vp, ignore);
38
39#ifdef EDEBUG
40 etraci("exp0 p1", p1, vp);
41#endif
42 if (**vp && eq(**vp, "||")) {
43 register int p2;
44
45 (*vp)++;
46 p2 = exp0(vp, (ignore&IGNORE) || p1);
47#ifdef EDEBUG
48 etraci("exp0 p2", p2, vp);
49#endif
50 return (p1 || p2);
51 }
52 return (p1);
53}
54
55exp1(vp, ignore)
56 register char ***vp;
57{
58 register int p1 = exp2(vp, ignore);
59
60#ifdef EDEBUG
61 etraci("exp1 p1", p1, vp);
62#endif
63 if (**vp && eq(**vp, "&&")) {
64 register int p2;
65
66 (*vp)++;
67 p2 = exp1(vp, (ignore&IGNORE) || !p1);
68#ifdef EDEBUG
69 etraci("exp1 p2", p2, vp);
70#endif
71 return (p1 && p2);
72 }
73 return (p1);
74}
75
76exp2(vp, ignore)
77 register char ***vp;
78 bool ignore;
79{
80 register int p1 = exp2a(vp, ignore);
81
82#ifdef EDEBUG
83 etraci("exp3 p1", p1, vp);
84#endif
85 if (**vp && eq(**vp, "|")) {
86 register int p2;
87
88 (*vp)++;
89 p2 = exp2(vp, ignore);
90#ifdef EDEBUG
91 etraci("exp3 p2", p2, vp);
92#endif
93 return (p1 | p2);
94 }
95 return (p1);
96}
97
98exp2a(vp, ignore)
99 register char ***vp;
100 bool ignore;
101{
102 register int p1 = exp2b(vp, ignore);
103
104#ifdef EDEBUG
105 etraci("exp2a p1", p1, vp);
106#endif
107 if (**vp && eq(**vp, "^")) {
108 register int p2;
109
110 (*vp)++;
111 p2 = exp2a(vp, ignore);
112#ifdef EDEBUG
113 etraci("exp2a p2", p2, vp);
114#endif
115 return (p1 ^ p2);
116 }
117 return (p1);
118}
119
120exp2b(vp, ignore)
121 register char ***vp;
122 bool ignore;
123{
124 register int p1 = exp2c(vp, ignore);
125
126#ifdef EDEBUG
127 etraci("exp2b p1", p1, vp);
128#endif
129 if (**vp && eq(**vp, "&")) {
130 register int p2;
131
132 (*vp)++;
133 p2 = exp2b(vp, ignore);
134#ifdef EDEBUG
135 etraci("exp2b p2", p2, vp);
136#endif
137 return (p1 & p2);
138 }
139 return (p1);
140}
141
142exp2c(vp, ignore)
143 register char ***vp;
144 bool ignore;
145{
146 register char *p1 = exp3(vp, ignore);
147 register char *p2;
148 register int i;
149
150#ifdef EDEBUG
151 etracc("exp2c p1", p1, vp);
152#endif
153 if (i = isa(**vp, EQOP)) {
154 (*vp)++;
155 if (i == EQMATCH || i == NOTEQMATCH)
156 ignore |= NOGLOB;
157 p2 = exp3(vp, ignore);
158#ifdef EDEBUG
159 etracc("exp2c p2", p2, vp);
160#endif
161 if (!(ignore&IGNORE)) switch (i) {
162
163 case EQEQ:
164 i = eq(p1, p2);
165 break;
166
167 case NOTEQ:
168 i = !eq(p1, p2);
169 break;
170
171 case EQMATCH:
172 i = Gmatch(p1, p2);
173 break;
174
175 case NOTEQMATCH:
176 i = !Gmatch(p1, p2);
177 break;
178 }
179 xfree(p1), xfree(p2);
180 return (i);
181 }
182 i = egetn(p1);
183 xfree(p1);
184 return (i);
185}
186
187char *
188exp3(vp, ignore)
189 register char ***vp;
190 bool ignore;
191{
192 register char *p1, *p2;
193 register int i;
194
195 p1 = exp3a(vp, ignore);
196#ifdef EDEBUG
197 etracc("exp3 p1", p1, vp);
198#endif
199 if (i = isa(**vp, RELOP)) {
200 (*vp)++;
201 if (**vp && eq(**vp, "="))
202 i |= 1, (*vp)++;
203 p2 = exp3(vp, ignore);
204#ifdef EDEBUG
205 etracc("exp3 p2", p2, vp);
206#endif
207 if (!(ignore&IGNORE)) switch (i) {
208
209 case GTR:
210 i = egetn(p1) > egetn(p2);
211 break;
212
213 case GTR|1:
214 i = egetn(p1) >= egetn(p2);
215 break;
216
217 case LSS:
218 i = egetn(p1) < egetn(p2);
219 break;
220
221 case LSS|1:
222 i = egetn(p1) <= egetn(p2);
223 break;
224 }
225 xfree(p1), xfree(p2);
226 return (putn(i));
227 }
228 return (p1);
229}
230
231char *
232exp3a(vp, ignore)
233 register char ***vp;
234 bool ignore;
235{
236 register char *p1, *p2, *op;
237 register int i;
238
239 p1 = exp4(vp, ignore);
240#ifdef EDEBUG
241 etracc("exp3a p1", p1, vp);
242#endif
243 op = **vp;
244 if (op && any(op[0], "<>") && op[0] == op[1]) {
245 (*vp)++;
246 p2 = exp3a(vp, ignore);
247#ifdef EDEBUG
248 etracc("exp3a p2", p2, vp);
249#endif
250 if (op[0] == '<')
251 i = egetn(p1) << egetn(p2);
252 else
253 i = egetn(p1) >> egetn(p2);
254 xfree(p1), xfree(p2);
255 return (putn(i));
256 }
257 return (p1);
258}
259
260char *
261exp4(vp, ignore)
262 register char ***vp;
263 bool ignore;
264{
265 register char *p1, *p2;
266 register int i = 0;
267
268 p1 = exp5(vp, ignore);
269#ifdef EDEBUG
270 etracc("exp4 p1", p1, vp);
271#endif
272 if (isa(**vp, ADDOP)) {
273 register char *op = *(*vp)++;
274
275 p2 = exp4(vp, ignore);
276#ifdef EDEBUG
277 etracc("exp4 p2", p2, vp);
278#endif
279 if (!(ignore&IGNORE)) switch (op[0]) {
280
281 case '+':
282 i = egetn(p1) + egetn(p2);
283 break;
284
285 case '-':
286 i = egetn(p1) - egetn(p2);
287 break;
288 }
289 xfree(p1), xfree(p2);
290 return (putn(i));
291 }
292 return (p1);
293}
294
295char *
296exp5(vp, ignore)
297 register char ***vp;
298 bool ignore;
299{
300 register char *p1, *p2;
301 register int i = 0;
302
303 p1 = exp6(vp, ignore);
304#ifdef EDEBUG
305 etracc("exp5 p1", p1, vp);
306#endif
307 if (isa(**vp, MULOP)) {
308 register char *op = *(*vp)++;
309
310 p2 = exp5(vp, ignore);
311#ifdef EDEBUG
312 etracc("exp5 p2", p2, vp);
313#endif
314 if (!(ignore&IGNORE)) switch (op[0]) {
315
316 case '*':
317 i = egetn(p1) * egetn(p2);
318 break;
319
320 case '/':
321 i = egetn(p2);
322 if (i == 0)
323 error("Divide by 0");
324 i = egetn(p1) / i;
325 break;
326
327 case '%':
328 i = egetn(p2);
329 if (i == 0)
330 error("Mod by 0");
331 i = egetn(p1) % i;
332 break;
333 }
334 xfree(p1), xfree(p2);
335 return (putn(i));
336 }
337 return (p1);
338}
339
340char *
341exp6(vp, ignore)
342 register char ***vp;
343{
344 int ccode, i;
345 register char *cp, *dp, *ep;
346
347 if (eq(**vp, "!")) {
348 (*vp)++;
349 cp = exp6(vp, ignore);
350#ifdef EDEBUG
351 etracc("exp6 ! cp", cp, vp);
352#endif
353 i = egetn(cp);
354 xfree(cp);
355 return (putn(!i));
356 }
357 if (eq(**vp, "~")) {
358 (*vp)++;
359 cp = exp6(vp, ignore);
360#ifdef EDEBUG
361 etracc("exp6 ~ cp", cp, vp);
362#endif
363 i = egetn(cp);
364 xfree(cp);
365 return (putn(~i));
366 }
367 if (eq(**vp, "(")) {
368 (*vp)++;
369 ccode = exp0(vp, ignore);
370#ifdef EDEBUG
371 etraci("exp6 () ccode", ccode, vp);
372#endif
373 if (*vp == 0 || **vp == 0 || ***vp != ')')
374 bferr("Expression syntax");
375 (*vp)++;
376 return (putn(ccode));
377 }
378 if (eq(**vp, "{")) {
379 register char **v;
380 struct command faket;
381 char *fakecom[2];
382
383 faket.t_dtyp = TCOM;
384 faket.t_dflg = 0;
385 faket.t_dcar = faket.t_dcdr = faket.t_dspr = (struct command *)0;
386 faket.t_dcom = fakecom;
387 fakecom[0] = "{ ... }";
388 fakecom[1] = NOSTR;
389 (*vp)++;
390 v = *vp;
391 for (;;) {
392 if (!**vp)
393 bferr("Missing }");
394 if (eq(*(*vp)++, "}"))
395 break;
396 }
397 if (ignore&IGNORE)
398 return ("");
399 psavejob();
400 if (pfork(&faket, -1) == 0) {
401 *--(*vp) = 0;
402 evalav(v);
403 exitstat();
404 }
405 pwait();
406 prestjob();
407#ifdef EDEBUG
408 etraci("exp6 {} status", egetn(value("status")), vp);
409#endif
410 return (putn(egetn(value("status")) == 0));
411 }
412 if (isa(**vp, ANYOP))
413 return ("");
414 cp = *(*vp)++;
415 if (*cp == '-' && any(cp[1], "erwxfdzo")) {
416 struct stat stb;
417
418 if (isa(**vp, ANYOP))
419 bferr("Missing file name");
420 dp = *(*vp)++;
421 if (ignore&IGNORE)
422 return ("");
423 ep = globone(dp);
424 switch (cp[1]) {
425
426 case 'r':
427 i = !access(ep, 4);
428 break;
429
430 case 'w':
431 i = !access(ep, 2);
432 break;
433
434 case 'x':
435 i = !access(ep, 1);
436 break;
437
438 default:
439 if (stat(ep, &stb)) {
440 xfree(ep);
441 return ("0");
442 }
443 switch (cp[1]) {
444
445 case 'f':
446 i = (stb.st_mode & S_IFMT) == S_IFREG;
447 break;
448
449 case 'd':
450 i = (stb.st_mode & S_IFMT) == S_IFDIR;
451 break;
452
453 case 'z':
454 i = stb.st_size == 0;
455 break;
456
457 case 'e':
458 i = 1;
459 break;
460
461 case 'o':
462 i = stb.st_uid == uid;
463 break;
464 }
465 }
466#ifdef EDEBUG
467 etraci("exp6 -? i", i, vp);
468#endif
469 xfree(ep);
470 return (putn(i));
471 }
472#ifdef EDEBUG
473 etracc("exp6 default", cp, vp);
474#endif
475 return (ignore&NOGLOB ? cp : globone(cp));
476}
477
478evalav(v)
479 register char **v;
480{
481 struct wordent paraml;
482 register struct wordent *hp = &paraml;
483 struct command *t;
484 register struct wordent *wdp = hp;
485
486 set("status", "0");
487 hp->prev = hp->next = hp;
488 hp->word = "";
489 while (*v) {
490 register struct wordent *new = (struct wordent *) calloc(1, sizeof *wdp);
491
492 new->prev = wdp;
493 new->next = hp;
494 wdp->next = new;
495 wdp = new;
496 wdp->word = savestr(*v++);
497 }
498 hp->prev = wdp;
499 alias(&paraml);
500 t = syntax(paraml.next, &paraml, 0);
501 if (err)
502 error(err);
503 execute(t, -1);
504 freelex(&paraml), freesyn(t);
505}
506
507isa(cp, what)
508 register char *cp;
509 register int what;
510{
511
512 if (cp == 0)
513 return ((what & RESTOP) != 0);
514 if (cp[1] == 0) {
515 if ((what & ADDOP) && any(cp[0], "+-"))
516 return (1);
517 if ((what & MULOP) && any(cp[0], "*/%"))
518 return (1);
519 if ((what & RESTOP) && any(cp[0], "()!~^"))
520 return (1);
521 }
522 if ((what & RESTOP) && (any(cp[0], "|&") || eq(cp, "<<") || eq(cp, ">>")))
523 return (1);
524 if (what & EQOP) {
525 if (eq(cp, "=="))
526 return (EQEQ);
527 if (eq(cp, "!="))
528 return (NOTEQ);
529 if (eq(cp, "=~"))
530 return (EQMATCH);
531 if (eq(cp, "!~"))
532 return (NOTEQMATCH);
533 }
534 if (!(what & RELOP))
535 return (0);
536 if (*cp == '<')
537 return (LSS);
538 if (*cp == '>')
539 return (GTR);
540 return (0);
541}
542
543egetn(cp)
544 register char *cp;
545{
546
547 if (*cp && *cp != '-' && !digit(*cp))
548 bferr("Expression syntax");
549 return (getn(cp));
550}
551
552/* Phew! */
553
554#ifdef EDEBUG
555etraci(str, i, vp)
556 char *str;
557 int i;
558 char ***vp;
559{
560
561 printf("%s=%d\t", str, i);
562 blkpr(*vp);
563 printf("\n");
564}
565
566etracc(str, cp, vp)
567 char *str, *cp;
568 char ***vp;
569{
570
571 printf("%s=%s\t", str, cp);
572 blkpr(*vp);
573 printf("\n");
574}
575#endif