1 %{ 2 /* Written by Pace Willisson (pace@blitz.com) 3 * and placed in the public domain. 4 * 5 * Largely rewritten by J.T. Conklin (jtc@wimsey.com) 6 * 7 * $FreeBSD$ 8 */ 9 10 #include <sys/types.h> 11 12 #include <ctype.h> 13 #include <err.h> 14 #include <errno.h> 15 #include <inttypes.h> 16 #include <limits.h> 17 #include <locale.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include <regex.h> 22 #include <unistd.h> 23 24 /* 25 * POSIX specifies a specific error code for syntax errors. We exit 26 * with this code for all errors. 27 */ 28 #define ERR_EXIT 2 29 30 enum valtype { 31 integer, numeric_string, string 32 } ; 33 34 struct val { 35 enum valtype type; 36 union { 37 char *s; 38 intmax_t i; 39 } u; 40 } ; 41 42 struct val *result; 43 44 int chk_div(intmax_t, intmax_t); 45 int chk_minus(intmax_t, intmax_t, intmax_t); 46 int chk_plus(intmax_t, intmax_t, intmax_t); 47 int chk_times(intmax_t, intmax_t, intmax_t); 48 void free_value(struct val *); 49 int is_zero_or_null(struct val *); 50 int isstring(struct val *); 51 struct val *make_integer(intmax_t); 52 struct val *make_str(const char *); 53 struct val *op_and(struct val *, struct val *); 54 struct val *op_colon(struct val *, struct val *); 55 struct val *op_div(struct val *, struct val *); 56 struct val *op_eq(struct val *, struct val *); 57 struct val *op_ge(struct val *, struct val *); 58 struct val *op_gt(struct val *, struct val *); 59 struct val *op_le(struct val *, struct val *); 60 struct val *op_lt(struct val *, struct val *); 61 struct val *op_minus(struct val *, struct val *); 62 struct val *op_ne(struct val *, struct val *); 63 struct val *op_or(struct val *, struct val *); 64 struct val *op_plus(struct val *, struct val *); 65 struct val *op_rem(struct val *, struct val *); 66 struct val *op_times(struct val *, struct val *); 67 intmax_t to_integer(struct val *); 68 void to_string(struct val *); 69 int yyerror(const char *); 70 int yylex(void); 71 int yyparse(void); 72 73 static int eflag; 74 char **av; 75 %} 76 77 %union 78 { 79 struct val *val; 80 } 81 82 %left <val> '|' 83 %left <val> '&' 84 %left <val> '=' '>' '<' GE LE NE 85 %left <val> '+' '-' 86 %left <val> '*' '/' '%' 87 %left <val> ':' 88 89 %token <val> TOKEN 90 %type <val> start expr 91 92 %% 93 94 start: expr { result = $$; } 95 96 expr: TOKEN 97 | '(' expr ')' { $$ = $2; } 98 | expr '|' expr { $$ = op_or ($1, $3); } 99 | expr '&' expr { $$ = op_and ($1, $3); } 100 | expr '=' expr { $$ = op_eq ($1, $3); } 101 | expr '>' expr { $$ = op_gt ($1, $3); } 102 | expr '<' expr { $$ = op_lt ($1, $3); } 103 | expr GE expr { $$ = op_ge ($1, $3); } 104 | expr LE expr { $$ = op_le ($1, $3); } 105 | expr NE expr { $$ = op_ne ($1, $3); } 106 | expr '+' expr { $$ = op_plus ($1, $3); } 107 | expr '-' expr { $$ = op_minus ($1, $3); } 108 | expr '*' expr { $$ = op_times ($1, $3); } 109 | expr '/' expr { $$ = op_div ($1, $3); } 110 | expr '%' expr { $$ = op_rem ($1, $3); } 111 | expr ':' expr { $$ = op_colon ($1, $3); } 112 ; 113 114 115 %% 116 117 struct val * 118 make_integer(intmax_t i) 119 { 120 struct val *vp; 121 122 vp = (struct val *) malloc (sizeof (*vp)); 123 if (vp == NULL) { 124 errx(ERR_EXIT, "malloc() failed"); 125 } 126 127 vp->type = integer; 128 vp->u.i = i; 129 return vp; 130 } 131 132 struct val * 133 make_str(const char *s) 134 { 135 struct val *vp; 136 char *ep; 137 138 vp = (struct val *) malloc (sizeof (*vp)); 139 if (vp == NULL || ((vp->u.s = strdup (s)) == NULL)) { 140 errx(ERR_EXIT, "malloc() failed"); 141 } 142 143 /* 144 * Previously we tried to scan the string to see if it ``looked like'' 145 * an integer (erroneously, as it happened). Let strtoimax() do the 146 * dirty work. We could cache the value, except that we are using 147 * a union and need to preserve the original string form until we 148 * are certain that it is not needed. 149 * 150 * IEEE Std.1003.1-2001 says: 151 * /integer/ An argument consisting only of an (optional) unary minus 152 * followed by digits. 153 * 154 * This means that arguments which consist of digits followed by 155 * non-digits MUST NOT be considered integers. strtoimax() will 156 * figure this out for us. 157 */ 158 if (eflag) 159 (void)strtoimax(s, &ep, 10); 160 else 161 (void)strtol(s, &ep, 10); 162 163 if (*ep != '\0') 164 vp->type = string; 165 else 166 vp->type = numeric_string; 167 168 return vp; 169 } 170 171 172 void 173 free_value(struct val *vp) 174 { 175 if (vp->type == string || vp->type == numeric_string) 176 free (vp->u.s); 177 } 178 179 180 intmax_t 181 to_integer(struct val *vp) 182 { 183 intmax_t i; 184 185 if (vp->type == integer) 186 return 1; 187 188 if (vp->type == string) 189 return 0; 190 191 /* vp->type == numeric_string, make it numeric */ 192 errno = 0; 193 if (eflag) { 194 i = strtoimax(vp->u.s, (char **)NULL, 10); 195 if (errno == ERANGE) 196 err(ERR_EXIT, NULL); 197 } else { 198 i = strtol(vp->u.s, (char **)NULL, 10); 199 } 200 201 free (vp->u.s); 202 vp->u.i = i; 203 vp->type = integer; 204 return 1; 205 } 206 207 void 208 to_string(struct val *vp) 209 { 210 char *tmp; 211 212 if (vp->type == string || vp->type == numeric_string) 213 return; 214 215 /* 216 * log_10(x) ~= 0.3 * log_2(x). Rounding up gives the number 217 * of digits; add one each for the sign and terminating null 218 * character, respectively. 219 */ 220 #define NDIGITS(x) (3 * (sizeof(x) * CHAR_BIT) / 10 + 1 + 1 + 1) 221 tmp = malloc(NDIGITS(vp->u.i)); 222 if (tmp == NULL) 223 errx(ERR_EXIT, "malloc() failed"); 224 225 sprintf(tmp, "%jd", vp->u.i); 226 vp->type = string; 227 vp->u.s = tmp; 228 } 229 230 231 int 232 isstring(struct val *vp) 233 { 234 /* only TRUE if this string is not a valid integer */ 235 return (vp->type == string); 236 } 237 238 239 int 240 yylex(void) 241 { 242 char *p; 243 244 if (*av == NULL) 245 return (0); 246 247 p = *av++; 248 249 if (strlen (p) == 1) { 250 if (strchr ("|&=<>+-*/%:()", *p)) 251 return (*p); 252 } else if (strlen (p) == 2 && p[1] == '=') { 253 switch (*p) { 254 case '>': return (GE); 255 case '<': return (LE); 256 case '!': return (NE); 257 } 258 } 259 260 yylval.val = make_str (p); 261 return (TOKEN); 262 } 263 264 int 265 is_zero_or_null(struct val *vp) 266 { 267 if (vp->type == integer) { 268 return (vp->u.i == 0); 269 } else { 270 return (*vp->u.s == 0 || (to_integer (vp) && vp->u.i == 0)); 271 } 272 /* NOTREACHED */ 273 } 274 275 int 276 main(int argc, char *argv[]) 277 { 278 int c; 279 280 setlocale (LC_ALL, ""); 281 if (getenv("EXPR_COMPAT") != NULL 282 || check_utility_compat("expr")) { 283 av = argv + 1; 284 eflag = 1; 285 } else { 286 while ((c = getopt(argc, argv, "e")) != -1) 287 switch (c) { 288 case 'e': 289 eflag = 1; 290 break; 291 292 default: 293 fprintf(stderr, 294 "usage: expr [-e] expression\n"); 295 exit(ERR_EXIT); 296 } 297 av = argv + optind; 298 } 299 300 yyparse(); 301 302 if (result->type == integer) 303 printf("%jd\n", result->u.i); 304 else 305 printf("%s\n", result->u.s); 306 307 return (is_zero_or_null(result)); 308 } 309 310 int 311 yyerror(const char *s __unused) 312 { 313 errx(ERR_EXIT, "syntax error"); 314 } 315 316 317 struct val * 318 op_or(struct val *a, struct val *b) 319 { 320 if (is_zero_or_null (a)) { 321 free_value (a); 322 return (b); 323 } else { 324 free_value (b); 325 return (a); 326 } 327 } 328 329 struct val * 330 op_and(struct val *a, struct val *b) 331 { 332 if (is_zero_or_null (a) || is_zero_or_null (b)) { 333 free_value (a); 334 free_value (b); 335 return (make_integer ((intmax_t)0)); 336 } else { 337 free_value (b); 338 return (a); 339 } 340 } 341 342 struct val * 343 op_eq(struct val *a, struct val *b) 344 { 345 struct val *r; 346 347 if (isstring (a) || isstring (b)) { 348 to_string (a); 349 to_string (b); 350 r = make_integer ((intmax_t)(strcoll (a->u.s, b->u.s) == 0)); 351 } else { 352 (void)to_integer(a); 353 (void)to_integer(b); 354 r = make_integer ((intmax_t)(a->u.i == b->u.i)); 355 } 356 357 free_value (a); 358 free_value (b); 359 return r; 360 } 361 362 struct val * 363 op_gt(struct val *a, struct val *b) 364 { 365 struct val *r; 366 367 if (isstring (a) || isstring (b)) { 368 to_string (a); 369 to_string (b); 370 r = make_integer ((intmax_t)(strcoll (a->u.s, b->u.s) > 0)); 371 } else { 372 (void)to_integer(a); 373 (void)to_integer(b); 374 r = make_integer ((intmax_t)(a->u.i > b->u.i)); 375 } 376 377 free_value (a); 378 free_value (b); 379 return r; 380 } 381 382 struct val * 383 op_lt(struct val *a, struct val *b) 384 { 385 struct val *r; 386 387 if (isstring (a) || isstring (b)) { 388 to_string (a); 389 to_string (b); 390 r = make_integer ((intmax_t)(strcoll (a->u.s, b->u.s) < 0)); 391 } else { 392 (void)to_integer(a); 393 (void)to_integer(b); 394 r = make_integer ((intmax_t)(a->u.i < b->u.i)); 395 } 396 397 free_value (a); 398 free_value (b); 399 return r; 400 } 401 402 struct val * 403 op_ge(struct val *a, struct val *b) 404 { 405 struct val *r; 406 407 if (isstring (a) || isstring (b)) { 408 to_string (a); 409 to_string (b); 410 r = make_integer ((intmax_t)(strcoll (a->u.s, b->u.s) >= 0)); 411 } else { 412 (void)to_integer(a); 413 (void)to_integer(b); 414 r = make_integer ((intmax_t)(a->u.i >= b->u.i)); 415 } 416 417 free_value (a); 418 free_value (b); 419 return r; 420 } 421 422 struct val * 423 op_le(struct val *a, struct val *b) 424 { 425 struct val *r; 426 427 if (isstring (a) || isstring (b)) { 428 to_string (a); 429 to_string (b); 430 r = make_integer ((intmax_t)(strcoll (a->u.s, b->u.s) <= 0)); 431 } else { 432 (void)to_integer(a); 433 (void)to_integer(b); 434 r = make_integer ((intmax_t)(a->u.i <= b->u.i)); 435 } 436 437 free_value (a); 438 free_value (b); 439 return r; 440 } 441 442 struct val * 443 op_ne(struct val *a, struct val *b) 444 { 445 struct val *r; 446 447 if (isstring (a) || isstring (b)) { 448 to_string (a); 449 to_string (b); 450 r = make_integer ((intmax_t)(strcoll (a->u.s, b->u.s) != 0)); 451 } else { 452 (void)to_integer(a); 453 (void)to_integer(b); 454 r = make_integer ((intmax_t)(a->u.i != b->u.i)); 455 } 456 457 free_value (a); 458 free_value (b); 459 return r; 460 } 461 462 int 463 chk_plus(intmax_t a, intmax_t b, intmax_t r) 464 { 465 466 /* sum of two positive numbers must be positive */ 467 if (a > 0 && b > 0 && r <= 0) 468 return 1; 469 /* sum of two negative numbers must be negative */ 470 if (a < 0 && b < 0 && r >= 0) 471 return 1; 472 /* all other cases are OK */ 473 return 0; 474 } 475 476 struct val * 477 op_plus(struct val *a, struct val *b) 478 { 479 struct val *r; 480 481 if (!to_integer(a) || !to_integer(b)) { 482 errx(ERR_EXIT, "non-numeric argument"); 483 } 484 485 if (eflag) { 486 r = make_integer(a->u.i + b->u.i); 487 if (chk_plus(a->u.i, b->u.i, r->u.i)) { 488 errx(ERR_EXIT, "overflow"); 489 } 490 } else 491 r = make_integer((long)a->u.i + (long)b->u.i); 492 493 free_value (a); 494 free_value (b); 495 return r; 496 } 497 498 int 499 chk_minus(intmax_t a, intmax_t b, intmax_t r) 500 { 501 502 /* special case subtraction of INTMAX_MIN */ 503 if (b == INTMAX_MIN) { 504 if (a >= 0) 505 return 1; 506 else 507 return 0; 508 } 509 /* this is allowed for b != INTMAX_MIN */ 510 return chk_plus (a, -b, r); 511 } 512 513 struct val * 514 op_minus(struct val *a, struct val *b) 515 { 516 struct val *r; 517 518 if (!to_integer(a) || !to_integer(b)) { 519 errx(ERR_EXIT, "non-numeric argument"); 520 } 521 522 if (eflag) { 523 r = make_integer(a->u.i - b->u.i); 524 if (chk_minus(a->u.i, b->u.i, r->u.i)) { 525 errx(ERR_EXIT, "overflow"); 526 } 527 } else 528 r = make_integer((long)a->u.i - (long)b->u.i); 529 530 free_value (a); 531 free_value (b); 532 return r; 533 } 534 535 int 536 chk_times(intmax_t a, intmax_t b, intmax_t r) 537 { 538 /* special case: first operand is 0, no overflow possible */ 539 if (a == 0) 540 return 0; 541 /* cerify that result of division matches second operand */ 542 if (r / a != b) 543 return 1; 544 return 0; 545 } 546 547 struct val * 548 op_times(struct val *a, struct val *b) 549 { 550 struct val *r; 551 552 if (!to_integer(a) || !to_integer(b)) { 553 errx(ERR_EXIT, "non-numeric argument"); 554 } 555 556 if (eflag) { 557 r = make_integer(a->u.i * b->u.i); 558 if (chk_times(a->u.i, b->u.i, r->u.i)) { 559 errx(ERR_EXIT, "overflow"); 560 } 561 } else 562 r = make_integer((long)a->u.i * (long)b->u.i); 563 564 free_value (a); 565 free_value (b); 566 return (r); 567 } 568 569 int 570 chk_div(intmax_t a, intmax_t b) 571 { 572 /* div by zero has been taken care of before */ 573 /* only INTMAX_MIN / -1 causes overflow */ 574 if (a == INTMAX_MIN && b == -1) 575 return 1; 576 /* everything else is OK */ 577 return 0; 578 } 579 580 struct val * 581 op_div(struct val *a, struct val *b) 582 { 583 struct val *r; 584 585 if (!to_integer(a) || !to_integer(b)) { 586 errx(ERR_EXIT, "non-numeric argument"); 587 } 588 589 if (b->u.i == 0) { 590 errx(ERR_EXIT, "division by zero"); 591 } 592 593 if (eflag) { 594 r = make_integer(a->u.i / b->u.i); 595 if (chk_div(a->u.i, b->u.i)) { 596 errx(ERR_EXIT, "overflow"); 597 } 598 } else 599 r = make_integer((long)a->u.i / (long)b->u.i); 600 601 free_value (a); 602 free_value (b); 603 return r; 604 } 605 606 struct val * 607 op_rem(struct val *a, struct val *b) 608 { 609 struct val *r; 610 611 if (!to_integer(a) || !to_integer(b)) { 612 errx(ERR_EXIT, "non-numeric argument"); 613 } 614 615 if (b->u.i == 0) { 616 errx(ERR_EXIT, "division by zero"); 617 } 618 619 if (eflag) 620 r = make_integer(a->u.i % b->u.i); 621 /* chk_rem necessary ??? */ 622 else 623 r = make_integer((long)a->u.i % (long)b->u.i); 624 625 free_value (a); 626 free_value (b); 627 return r; 628 } 629 630 struct val * 631 op_colon(struct val *a, struct val *b) 632 { 633 regex_t rp; 634 regmatch_t rm[2]; 635 char errbuf[256]; 636 int eval; 637 struct val *v; 638 639 /* coerce to both arguments to strings */ 640 to_string(a); 641 to_string(b); 642 643 /* compile regular expression */ 644 if ((eval = regcomp (&rp, b->u.s, 0)) != 0) { 645 regerror (eval, &rp, errbuf, sizeof(errbuf)); 646 errx(ERR_EXIT, "%s", errbuf); 647 } 648 649 /* compare string against pattern */ 650 /* remember that patterns are anchored to the beginning of the line */ 651 if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 && rm[0].rm_so == 0) { 652 if (rm[1].rm_so >= 0) { 653 *(a->u.s + rm[1].rm_eo) = '\0'; 654 v = make_str (a->u.s + rm[1].rm_so); 655 656 } else { 657 v = make_integer ((intmax_t)(rm[0].rm_eo - rm[0].rm_so)); 658 } 659 } else { 660 if (rp.re_nsub == 0) { 661 v = make_integer ((intmax_t)0); 662 } else { 663 v = make_str (""); 664 } 665 } 666 667 /* free arguments and pattern buffer */ 668 free_value (a); 669 free_value (b); 670 regfree (&rp); 671 672 return v; 673 } 674