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