1 static char *sccsid = "@(#)exp.c 4.1 10/09/80"; 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 26 exp(vp) 27 register char ***vp; 28 { 29 30 return (exp0(vp, 0)); 31 } 32 33 exp0(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 55 exp1(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 76 exp2(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 98 exp2a(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 120 exp2b(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 142 exp2c(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 187 char * 188 exp3(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 231 char * 232 exp3a(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 260 char * 261 exp4(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 295 char * 296 exp5(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 340 char * 341 exp6(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 478 evalav(v) 479 register char **v; 480 { 481 struct wordent paraml; 482 register struct wordent *hp = ¶ml; 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(¶ml); 500 t = syntax(paraml.next, ¶ml, 0); 501 if (err) 502 error(err); 503 execute(t, -1); 504 freelex(¶ml), freesyn(t); 505 } 506 507 isa(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 543 egetn(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 555 etraci(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 566 etracc(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 576