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