1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 4 */ 5 6 #include <ctype.h> 7 #include <errno.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 12 #include "lkc.h" 13 14 #define DEBUG_EXPR 0 15 16 static int expr_eq(struct expr *e1, struct expr *e2); 17 static struct expr *expr_eliminate_yn(struct expr *e); 18 19 struct expr *expr_alloc_symbol(struct symbol *sym) 20 { 21 struct expr *e = xcalloc(1, sizeof(*e)); 22 e->type = E_SYMBOL; 23 e->left.sym = sym; 24 return e; 25 } 26 27 struct expr *expr_alloc_one(enum expr_type type, struct expr *ce) 28 { 29 struct expr *e = xcalloc(1, sizeof(*e)); 30 e->type = type; 31 e->left.expr = ce; 32 return e; 33 } 34 35 struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2) 36 { 37 struct expr *e = xcalloc(1, sizeof(*e)); 38 e->type = type; 39 e->left.expr = e1; 40 e->right.expr = e2; 41 return e; 42 } 43 44 struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2) 45 { 46 struct expr *e = xcalloc(1, sizeof(*e)); 47 e->type = type; 48 e->left.sym = s1; 49 e->right.sym = s2; 50 return e; 51 } 52 53 struct expr *expr_alloc_and(struct expr *e1, struct expr *e2) 54 { 55 if (!e1) 56 return e2; 57 return e2 ? expr_alloc_two(E_AND, e1, e2) : e1; 58 } 59 60 struct expr *expr_alloc_or(struct expr *e1, struct expr *e2) 61 { 62 if (!e1) 63 return e2; 64 return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; 65 } 66 67 struct expr *expr_copy(const struct expr *org) 68 { 69 struct expr *e; 70 71 if (!org) 72 return NULL; 73 74 e = xmalloc(sizeof(*org)); 75 memcpy(e, org, sizeof(*org)); 76 switch (org->type) { 77 case E_SYMBOL: 78 e->left = org->left; 79 break; 80 case E_NOT: 81 e->left.expr = expr_copy(org->left.expr); 82 break; 83 case E_EQUAL: 84 case E_GEQ: 85 case E_GTH: 86 case E_LEQ: 87 case E_LTH: 88 case E_UNEQUAL: 89 e->left.sym = org->left.sym; 90 e->right.sym = org->right.sym; 91 break; 92 case E_AND: 93 case E_OR: 94 case E_LIST: 95 e->left.expr = expr_copy(org->left.expr); 96 e->right.expr = expr_copy(org->right.expr); 97 break; 98 default: 99 fprintf(stderr, "can't copy type %d\n", e->type); 100 free(e); 101 e = NULL; 102 break; 103 } 104 105 return e; 106 } 107 108 void expr_free(struct expr *e) 109 { 110 if (!e) 111 return; 112 113 switch (e->type) { 114 case E_SYMBOL: 115 break; 116 case E_NOT: 117 expr_free(e->left.expr); 118 break; 119 case E_EQUAL: 120 case E_GEQ: 121 case E_GTH: 122 case E_LEQ: 123 case E_LTH: 124 case E_UNEQUAL: 125 break; 126 case E_OR: 127 case E_AND: 128 expr_free(e->left.expr); 129 expr_free(e->right.expr); 130 break; 131 default: 132 fprintf(stderr, "how to free type %d?\n", e->type); 133 break; 134 } 135 free(e); 136 } 137 138 static int trans_count; 139 140 #define e1 (*ep1) 141 #define e2 (*ep2) 142 143 /* 144 * expr_eliminate_eq() helper. 145 * 146 * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does 147 * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared 148 * against all other leaves. Two equal leaves are both replaced with either 'y' 149 * or 'n' as appropriate for 'type', to be eliminated later. 150 */ 151 static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2) 152 { 153 /* Recurse down to leaves */ 154 155 if (e1->type == type) { 156 __expr_eliminate_eq(type, &e1->left.expr, &e2); 157 __expr_eliminate_eq(type, &e1->right.expr, &e2); 158 return; 159 } 160 if (e2->type == type) { 161 __expr_eliminate_eq(type, &e1, &e2->left.expr); 162 __expr_eliminate_eq(type, &e1, &e2->right.expr); 163 return; 164 } 165 166 /* e1 and e2 are leaves. Compare them. */ 167 168 if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && 169 e1->left.sym == e2->left.sym && 170 (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no)) 171 return; 172 if (!expr_eq(e1, e2)) 173 return; 174 175 /* e1 and e2 are equal leaves. Prepare them for elimination. */ 176 177 trans_count++; 178 expr_free(e1); expr_free(e2); 179 switch (type) { 180 case E_OR: 181 e1 = expr_alloc_symbol(&symbol_no); 182 e2 = expr_alloc_symbol(&symbol_no); 183 break; 184 case E_AND: 185 e1 = expr_alloc_symbol(&symbol_yes); 186 e2 = expr_alloc_symbol(&symbol_yes); 187 break; 188 default: 189 ; 190 } 191 } 192 193 /* 194 * Rewrites the expressions 'ep1' and 'ep2' to remove operands common to both. 195 * Example reductions: 196 * 197 * ep1: A && B -> ep1: y 198 * ep2: A && B && C -> ep2: C 199 * 200 * ep1: A || B -> ep1: n 201 * ep2: A || B || C -> ep2: C 202 * 203 * ep1: A && (B && FOO) -> ep1: FOO 204 * ep2: (BAR && B) && A -> ep2: BAR 205 * 206 * ep1: A && (B || C) -> ep1: y 207 * ep2: (C || B) && A -> ep2: y 208 * 209 * Comparisons are done between all operands at the same "level" of && or ||. 210 * For example, in the expression 'e1 && (e2 || e3) && (e4 || e5)', the 211 * following operands will be compared: 212 * 213 * - 'e1', 'e2 || e3', and 'e4 || e5', against each other 214 * - e2 against e3 215 * - e4 against e5 216 * 217 * Parentheses are irrelevant within a single level. 'e1 && (e2 && e3)' and 218 * '(e1 && e2) && e3' are both a single level. 219 * 220 * See __expr_eliminate_eq() as well. 221 */ 222 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) 223 { 224 if (!e1 || !e2) 225 return; 226 switch (e1->type) { 227 case E_OR: 228 case E_AND: 229 __expr_eliminate_eq(e1->type, ep1, ep2); 230 default: 231 ; 232 } 233 if (e1->type != e2->type) switch (e2->type) { 234 case E_OR: 235 case E_AND: 236 __expr_eliminate_eq(e2->type, ep1, ep2); 237 default: 238 ; 239 } 240 e1 = expr_eliminate_yn(e1); 241 e2 = expr_eliminate_yn(e2); 242 } 243 244 #undef e1 245 #undef e2 246 247 /* 248 * Returns true if 'e1' and 'e2' are equal, after minor simplification. Two 249 * &&/|| expressions are considered equal if every operand in one expression 250 * equals some operand in the other (operands do not need to appear in the same 251 * order), recursively. 252 */ 253 static int expr_eq(struct expr *e1, struct expr *e2) 254 { 255 int res, old_count; 256 257 /* 258 * A NULL expr is taken to be yes, but there's also a different way to 259 * represent yes. expr_is_yes() checks for either representation. 260 */ 261 if (!e1 || !e2) 262 return expr_is_yes(e1) && expr_is_yes(e2); 263 264 if (e1->type != e2->type) 265 return 0; 266 switch (e1->type) { 267 case E_EQUAL: 268 case E_GEQ: 269 case E_GTH: 270 case E_LEQ: 271 case E_LTH: 272 case E_UNEQUAL: 273 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym; 274 case E_SYMBOL: 275 return e1->left.sym == e2->left.sym; 276 case E_NOT: 277 return expr_eq(e1->left.expr, e2->left.expr); 278 case E_AND: 279 case E_OR: 280 e1 = expr_copy(e1); 281 e2 = expr_copy(e2); 282 old_count = trans_count; 283 expr_eliminate_eq(&e1, &e2); 284 res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL && 285 e1->left.sym == e2->left.sym); 286 expr_free(e1); 287 expr_free(e2); 288 trans_count = old_count; 289 return res; 290 case E_LIST: 291 case E_RANGE: 292 case E_NONE: 293 /* panic */; 294 } 295 296 if (DEBUG_EXPR) { 297 expr_fprint(e1, stdout); 298 printf(" = "); 299 expr_fprint(e2, stdout); 300 printf(" ?\n"); 301 } 302 303 return 0; 304 } 305 306 /* 307 * Recursively performs the following simplifications in-place (as well as the 308 * corresponding simplifications with swapped operands): 309 * 310 * expr && n -> n 311 * expr && y -> expr 312 * expr || n -> expr 313 * expr || y -> y 314 * 315 * Returns the optimized expression. 316 */ 317 static struct expr *expr_eliminate_yn(struct expr *e) 318 { 319 struct expr *tmp; 320 321 if (e) switch (e->type) { 322 case E_AND: 323 e->left.expr = expr_eliminate_yn(e->left.expr); 324 e->right.expr = expr_eliminate_yn(e->right.expr); 325 if (e->left.expr->type == E_SYMBOL) { 326 if (e->left.expr->left.sym == &symbol_no) { 327 expr_free(e->left.expr); 328 expr_free(e->right.expr); 329 e->type = E_SYMBOL; 330 e->left.sym = &symbol_no; 331 e->right.expr = NULL; 332 return e; 333 } else if (e->left.expr->left.sym == &symbol_yes) { 334 free(e->left.expr); 335 tmp = e->right.expr; 336 *e = *(e->right.expr); 337 free(tmp); 338 return e; 339 } 340 } 341 if (e->right.expr->type == E_SYMBOL) { 342 if (e->right.expr->left.sym == &symbol_no) { 343 expr_free(e->left.expr); 344 expr_free(e->right.expr); 345 e->type = E_SYMBOL; 346 e->left.sym = &symbol_no; 347 e->right.expr = NULL; 348 return e; 349 } else if (e->right.expr->left.sym == &symbol_yes) { 350 free(e->right.expr); 351 tmp = e->left.expr; 352 *e = *(e->left.expr); 353 free(tmp); 354 return e; 355 } 356 } 357 break; 358 case E_OR: 359 e->left.expr = expr_eliminate_yn(e->left.expr); 360 e->right.expr = expr_eliminate_yn(e->right.expr); 361 if (e->left.expr->type == E_SYMBOL) { 362 if (e->left.expr->left.sym == &symbol_no) { 363 free(e->left.expr); 364 tmp = e->right.expr; 365 *e = *(e->right.expr); 366 free(tmp); 367 return e; 368 } else if (e->left.expr->left.sym == &symbol_yes) { 369 expr_free(e->left.expr); 370 expr_free(e->right.expr); 371 e->type = E_SYMBOL; 372 e->left.sym = &symbol_yes; 373 e->right.expr = NULL; 374 return e; 375 } 376 } 377 if (e->right.expr->type == E_SYMBOL) { 378 if (e->right.expr->left.sym == &symbol_no) { 379 free(e->right.expr); 380 tmp = e->left.expr; 381 *e = *(e->left.expr); 382 free(tmp); 383 return e; 384 } else if (e->right.expr->left.sym == &symbol_yes) { 385 expr_free(e->left.expr); 386 expr_free(e->right.expr); 387 e->type = E_SYMBOL; 388 e->left.sym = &symbol_yes; 389 e->right.expr = NULL; 390 return e; 391 } 392 } 393 break; 394 default: 395 ; 396 } 397 return e; 398 } 399 400 /* 401 * bool FOO!=n => FOO 402 */ 403 struct expr *expr_trans_bool(struct expr *e) 404 { 405 if (!e) 406 return NULL; 407 switch (e->type) { 408 case E_AND: 409 case E_OR: 410 case E_NOT: 411 e->left.expr = expr_trans_bool(e->left.expr); 412 e->right.expr = expr_trans_bool(e->right.expr); 413 break; 414 case E_UNEQUAL: 415 // FOO!=n -> FOO 416 if (e->left.sym->type == S_TRISTATE) { 417 if (e->right.sym == &symbol_no) { 418 e->type = E_SYMBOL; 419 e->right.sym = NULL; 420 } 421 } 422 break; 423 default: 424 ; 425 } 426 return e; 427 } 428 429 /* 430 * e1 || e2 -> ? 431 */ 432 static struct expr *expr_join_or(struct expr *e1, struct expr *e2) 433 { 434 struct expr *tmp; 435 struct symbol *sym1, *sym2; 436 437 if (expr_eq(e1, e2)) 438 return expr_copy(e1); 439 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) 440 return NULL; 441 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) 442 return NULL; 443 if (e1->type == E_NOT) { 444 tmp = e1->left.expr; 445 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) 446 return NULL; 447 sym1 = tmp->left.sym; 448 } else 449 sym1 = e1->left.sym; 450 if (e2->type == E_NOT) { 451 if (e2->left.expr->type != E_SYMBOL) 452 return NULL; 453 sym2 = e2->left.expr->left.sym; 454 } else 455 sym2 = e2->left.sym; 456 if (sym1 != sym2) 457 return NULL; 458 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) 459 return NULL; 460 if (sym1->type == S_TRISTATE) { 461 if (e1->type == E_EQUAL && e2->type == E_EQUAL && 462 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || 463 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) { 464 // (a='y') || (a='m') -> (a!='n') 465 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no); 466 } 467 if (e1->type == E_EQUAL && e2->type == E_EQUAL && 468 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || 469 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) { 470 // (a='y') || (a='n') -> (a!='m') 471 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod); 472 } 473 if (e1->type == E_EQUAL && e2->type == E_EQUAL && 474 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || 475 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) { 476 // (a='m') || (a='n') -> (a!='y') 477 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes); 478 } 479 } 480 if (sym1->type == S_BOOLEAN && sym1 == sym2) { 481 if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) || 482 (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL)) 483 return expr_alloc_symbol(&symbol_yes); 484 } 485 486 if (DEBUG_EXPR) { 487 printf("optimize ("); 488 expr_fprint(e1, stdout); 489 printf(") || ("); 490 expr_fprint(e2, stdout); 491 printf(")?\n"); 492 } 493 return NULL; 494 } 495 496 static struct expr *expr_join_and(struct expr *e1, struct expr *e2) 497 { 498 struct expr *tmp; 499 struct symbol *sym1, *sym2; 500 501 if (expr_eq(e1, e2)) 502 return expr_copy(e1); 503 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) 504 return NULL; 505 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) 506 return NULL; 507 if (e1->type == E_NOT) { 508 tmp = e1->left.expr; 509 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) 510 return NULL; 511 sym1 = tmp->left.sym; 512 } else 513 sym1 = e1->left.sym; 514 if (e2->type == E_NOT) { 515 if (e2->left.expr->type != E_SYMBOL) 516 return NULL; 517 sym2 = e2->left.expr->left.sym; 518 } else 519 sym2 = e2->left.sym; 520 if (sym1 != sym2) 521 return NULL; 522 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) 523 return NULL; 524 525 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) || 526 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes)) 527 // (a) && (a='y') -> (a='y') 528 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); 529 530 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) || 531 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no)) 532 // (a) && (a!='n') -> (a) 533 return expr_alloc_symbol(sym1); 534 535 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) || 536 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod)) 537 // (a) && (a!='m') -> (a='y') 538 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); 539 540 if (sym1->type == S_TRISTATE) { 541 if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) { 542 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' 543 sym2 = e1->right.sym; 544 if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) 545 return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) 546 : expr_alloc_symbol(&symbol_no); 547 } 548 if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) { 549 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' 550 sym2 = e2->right.sym; 551 if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) 552 return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) 553 : expr_alloc_symbol(&symbol_no); 554 } 555 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && 556 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || 557 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) 558 // (a!='y') && (a!='n') -> (a='m') 559 return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod); 560 561 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && 562 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || 563 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) 564 // (a!='y') && (a!='m') -> (a='n') 565 return expr_alloc_comp(E_EQUAL, sym1, &symbol_no); 566 567 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && 568 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || 569 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) 570 // (a!='m') && (a!='n') -> (a='m') 571 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); 572 573 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) || 574 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) || 575 (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) || 576 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes)) 577 return NULL; 578 } 579 580 if (DEBUG_EXPR) { 581 printf("optimize ("); 582 expr_fprint(e1, stdout); 583 printf(") && ("); 584 expr_fprint(e2, stdout); 585 printf(")?\n"); 586 } 587 return NULL; 588 } 589 590 /* 591 * expr_eliminate_dups() helper. 592 * 593 * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does 594 * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared 595 * against all other leaves to look for simplifications. 596 */ 597 static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2) 598 { 599 #define e1 (*ep1) 600 #define e2 (*ep2) 601 struct expr *tmp; 602 603 /* Recurse down to leaves */ 604 605 if (e1->type == type) { 606 expr_eliminate_dups1(type, &e1->left.expr, &e2); 607 expr_eliminate_dups1(type, &e1->right.expr, &e2); 608 return; 609 } 610 if (e2->type == type) { 611 expr_eliminate_dups1(type, &e1, &e2->left.expr); 612 expr_eliminate_dups1(type, &e1, &e2->right.expr); 613 return; 614 } 615 616 /* e1 and e2 are leaves. Compare and process them. */ 617 618 if (e1 == e2) 619 return; 620 621 switch (e1->type) { 622 case E_OR: case E_AND: 623 expr_eliminate_dups1(e1->type, &e1, &e1); 624 default: 625 ; 626 } 627 628 switch (type) { 629 case E_OR: 630 tmp = expr_join_or(e1, e2); 631 if (tmp) { 632 expr_free(e1); expr_free(e2); 633 e1 = expr_alloc_symbol(&symbol_no); 634 e2 = tmp; 635 trans_count++; 636 } 637 break; 638 case E_AND: 639 tmp = expr_join_and(e1, e2); 640 if (tmp) { 641 expr_free(e1); expr_free(e2); 642 e1 = expr_alloc_symbol(&symbol_yes); 643 e2 = tmp; 644 trans_count++; 645 } 646 break; 647 default: 648 ; 649 } 650 #undef e1 651 #undef e2 652 } 653 654 /* 655 * Rewrites 'e' in-place to remove ("join") duplicate and other redundant 656 * operands. 657 * 658 * Example simplifications: 659 * 660 * A || B || A -> A || B 661 * A && B && A=y -> A=y && B 662 * 663 * Returns the deduplicated expression. 664 */ 665 struct expr *expr_eliminate_dups(struct expr *e) 666 { 667 int oldcount; 668 if (!e) 669 return e; 670 671 oldcount = trans_count; 672 while (1) { 673 trans_count = 0; 674 switch (e->type) { 675 case E_OR: case E_AND: 676 expr_eliminate_dups1(e->type, &e, &e); 677 default: 678 ; 679 } 680 if (!trans_count) 681 /* No simplifications done in this pass. We're done */ 682 break; 683 e = expr_eliminate_yn(e); 684 } 685 trans_count = oldcount; 686 return e; 687 } 688 689 /* 690 * Performs various simplifications involving logical operators and 691 * comparisons. 692 * 693 * Allocates and returns a new expression. 694 */ 695 struct expr *expr_transform(struct expr *e) 696 { 697 struct expr *tmp; 698 699 if (!e) 700 return NULL; 701 switch (e->type) { 702 case E_EQUAL: 703 case E_GEQ: 704 case E_GTH: 705 case E_LEQ: 706 case E_LTH: 707 case E_UNEQUAL: 708 case E_SYMBOL: 709 case E_LIST: 710 break; 711 default: 712 e->left.expr = expr_transform(e->left.expr); 713 e->right.expr = expr_transform(e->right.expr); 714 } 715 716 switch (e->type) { 717 case E_EQUAL: 718 if (e->left.sym->type != S_BOOLEAN) 719 break; 720 if (e->right.sym == &symbol_no) { 721 e->type = E_NOT; 722 e->left.expr = expr_alloc_symbol(e->left.sym); 723 e->right.sym = NULL; 724 break; 725 } 726 if (e->right.sym == &symbol_mod) { 727 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name); 728 e->type = E_SYMBOL; 729 e->left.sym = &symbol_no; 730 e->right.sym = NULL; 731 break; 732 } 733 if (e->right.sym == &symbol_yes) { 734 e->type = E_SYMBOL; 735 e->right.sym = NULL; 736 break; 737 } 738 break; 739 case E_UNEQUAL: 740 if (e->left.sym->type != S_BOOLEAN) 741 break; 742 if (e->right.sym == &symbol_no) { 743 e->type = E_SYMBOL; 744 e->right.sym = NULL; 745 break; 746 } 747 if (e->right.sym == &symbol_mod) { 748 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name); 749 e->type = E_SYMBOL; 750 e->left.sym = &symbol_yes; 751 e->right.sym = NULL; 752 break; 753 } 754 if (e->right.sym == &symbol_yes) { 755 e->type = E_NOT; 756 e->left.expr = expr_alloc_symbol(e->left.sym); 757 e->right.sym = NULL; 758 break; 759 } 760 break; 761 case E_NOT: 762 switch (e->left.expr->type) { 763 case E_NOT: 764 // !!a -> a 765 tmp = e->left.expr->left.expr; 766 free(e->left.expr); 767 free(e); 768 e = tmp; 769 e = expr_transform(e); 770 break; 771 case E_EQUAL: 772 case E_UNEQUAL: 773 // !a='x' -> a!='x' 774 tmp = e->left.expr; 775 free(e); 776 e = tmp; 777 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; 778 break; 779 case E_LEQ: 780 case E_GEQ: 781 // !a<='x' -> a>'x' 782 tmp = e->left.expr; 783 free(e); 784 e = tmp; 785 e->type = e->type == E_LEQ ? E_GTH : E_LTH; 786 break; 787 case E_LTH: 788 case E_GTH: 789 // !a<'x' -> a>='x' 790 tmp = e->left.expr; 791 free(e); 792 e = tmp; 793 e->type = e->type == E_LTH ? E_GEQ : E_LEQ; 794 break; 795 case E_OR: 796 // !(a || b) -> !a && !b 797 tmp = e->left.expr; 798 e->type = E_AND; 799 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); 800 tmp->type = E_NOT; 801 tmp->right.expr = NULL; 802 e = expr_transform(e); 803 break; 804 case E_AND: 805 // !(a && b) -> !a || !b 806 tmp = e->left.expr; 807 e->type = E_OR; 808 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); 809 tmp->type = E_NOT; 810 tmp->right.expr = NULL; 811 e = expr_transform(e); 812 break; 813 case E_SYMBOL: 814 if (e->left.expr->left.sym == &symbol_yes) { 815 // !'y' -> 'n' 816 tmp = e->left.expr; 817 free(e); 818 e = tmp; 819 e->type = E_SYMBOL; 820 e->left.sym = &symbol_no; 821 break; 822 } 823 if (e->left.expr->left.sym == &symbol_mod) { 824 // !'m' -> 'm' 825 tmp = e->left.expr; 826 free(e); 827 e = tmp; 828 e->type = E_SYMBOL; 829 e->left.sym = &symbol_mod; 830 break; 831 } 832 if (e->left.expr->left.sym == &symbol_no) { 833 // !'n' -> 'y' 834 tmp = e->left.expr; 835 free(e); 836 e = tmp; 837 e->type = E_SYMBOL; 838 e->left.sym = &symbol_yes; 839 break; 840 } 841 break; 842 default: 843 ; 844 } 845 break; 846 default: 847 ; 848 } 849 return e; 850 } 851 852 int expr_contains_symbol(struct expr *dep, struct symbol *sym) 853 { 854 if (!dep) 855 return 0; 856 857 switch (dep->type) { 858 case E_AND: 859 case E_OR: 860 return expr_contains_symbol(dep->left.expr, sym) || 861 expr_contains_symbol(dep->right.expr, sym); 862 case E_SYMBOL: 863 return dep->left.sym == sym; 864 case E_EQUAL: 865 case E_GEQ: 866 case E_GTH: 867 case E_LEQ: 868 case E_LTH: 869 case E_UNEQUAL: 870 return dep->left.sym == sym || 871 dep->right.sym == sym; 872 case E_NOT: 873 return expr_contains_symbol(dep->left.expr, sym); 874 default: 875 ; 876 } 877 return 0; 878 } 879 880 bool expr_depends_symbol(struct expr *dep, struct symbol *sym) 881 { 882 if (!dep) 883 return false; 884 885 switch (dep->type) { 886 case E_AND: 887 return expr_depends_symbol(dep->left.expr, sym) || 888 expr_depends_symbol(dep->right.expr, sym); 889 case E_SYMBOL: 890 return dep->left.sym == sym; 891 case E_EQUAL: 892 if (dep->left.sym == sym) { 893 if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod) 894 return true; 895 } 896 break; 897 case E_UNEQUAL: 898 if (dep->left.sym == sym) { 899 if (dep->right.sym == &symbol_no) 900 return true; 901 } 902 break; 903 default: 904 ; 905 } 906 return false; 907 } 908 909 /* 910 * Inserts explicit comparisons of type 'type' to symbol 'sym' into the 911 * expression 'e'. 912 * 913 * Examples transformations for type == E_UNEQUAL, sym == &symbol_no: 914 * 915 * A -> A!=n 916 * !A -> A=n 917 * A && B -> !(A=n || B=n) 918 * A || B -> !(A=n && B=n) 919 * A && (B || C) -> !(A=n || (B=n && C=n)) 920 * 921 * Allocates and returns a new expression. 922 */ 923 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym) 924 { 925 struct expr *e1, *e2; 926 927 if (!e) { 928 e = expr_alloc_symbol(sym); 929 if (type == E_UNEQUAL) 930 e = expr_alloc_one(E_NOT, e); 931 return e; 932 } 933 switch (e->type) { 934 case E_AND: 935 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); 936 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); 937 if (sym == &symbol_yes) 938 e = expr_alloc_two(E_AND, e1, e2); 939 if (sym == &symbol_no) 940 e = expr_alloc_two(E_OR, e1, e2); 941 if (type == E_UNEQUAL) 942 e = expr_alloc_one(E_NOT, e); 943 return e; 944 case E_OR: 945 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); 946 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); 947 if (sym == &symbol_yes) 948 e = expr_alloc_two(E_OR, e1, e2); 949 if (sym == &symbol_no) 950 e = expr_alloc_two(E_AND, e1, e2); 951 if (type == E_UNEQUAL) 952 e = expr_alloc_one(E_NOT, e); 953 return e; 954 case E_NOT: 955 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym); 956 case E_UNEQUAL: 957 case E_LTH: 958 case E_LEQ: 959 case E_GTH: 960 case E_GEQ: 961 case E_EQUAL: 962 if (type == E_EQUAL) { 963 if (sym == &symbol_yes) 964 return expr_copy(e); 965 if (sym == &symbol_mod) 966 return expr_alloc_symbol(&symbol_no); 967 if (sym == &symbol_no) 968 return expr_alloc_one(E_NOT, expr_copy(e)); 969 } else { 970 if (sym == &symbol_yes) 971 return expr_alloc_one(E_NOT, expr_copy(e)); 972 if (sym == &symbol_mod) 973 return expr_alloc_symbol(&symbol_yes); 974 if (sym == &symbol_no) 975 return expr_copy(e); 976 } 977 break; 978 case E_SYMBOL: 979 return expr_alloc_comp(type, e->left.sym, sym); 980 case E_LIST: 981 case E_RANGE: 982 case E_NONE: 983 /* panic */; 984 } 985 return NULL; 986 } 987 988 enum string_value_kind { 989 k_string, 990 k_signed, 991 k_unsigned, 992 }; 993 994 union string_value { 995 unsigned long long u; 996 signed long long s; 997 }; 998 999 static enum string_value_kind expr_parse_string(const char *str, 1000 enum symbol_type type, 1001 union string_value *val) 1002 { 1003 char *tail; 1004 enum string_value_kind kind; 1005 1006 errno = 0; 1007 switch (type) { 1008 case S_BOOLEAN: 1009 case S_TRISTATE: 1010 val->s = !strcmp(str, "n") ? 0 : 1011 !strcmp(str, "m") ? 1 : 1012 !strcmp(str, "y") ? 2 : -1; 1013 return k_signed; 1014 case S_INT: 1015 val->s = strtoll(str, &tail, 10); 1016 kind = k_signed; 1017 break; 1018 case S_HEX: 1019 val->u = strtoull(str, &tail, 16); 1020 kind = k_unsigned; 1021 break; 1022 default: 1023 val->s = strtoll(str, &tail, 0); 1024 kind = k_signed; 1025 break; 1026 } 1027 return !errno && !*tail && tail > str && isxdigit(tail[-1]) 1028 ? kind : k_string; 1029 } 1030 1031 tristate expr_calc_value(struct expr *e) 1032 { 1033 tristate val1, val2; 1034 const char *str1, *str2; 1035 enum string_value_kind k1 = k_string, k2 = k_string; 1036 union string_value lval = {}, rval = {}; 1037 int res; 1038 1039 if (!e) 1040 return yes; 1041 1042 switch (e->type) { 1043 case E_SYMBOL: 1044 sym_calc_value(e->left.sym); 1045 return e->left.sym->curr.tri; 1046 case E_AND: 1047 val1 = expr_calc_value(e->left.expr); 1048 val2 = expr_calc_value(e->right.expr); 1049 return EXPR_AND(val1, val2); 1050 case E_OR: 1051 val1 = expr_calc_value(e->left.expr); 1052 val2 = expr_calc_value(e->right.expr); 1053 return EXPR_OR(val1, val2); 1054 case E_NOT: 1055 val1 = expr_calc_value(e->left.expr); 1056 return EXPR_NOT(val1); 1057 case E_EQUAL: 1058 case E_GEQ: 1059 case E_GTH: 1060 case E_LEQ: 1061 case E_LTH: 1062 case E_UNEQUAL: 1063 break; 1064 default: 1065 printf("expr_calc_value: %d?\n", e->type); 1066 return no; 1067 } 1068 1069 sym_calc_value(e->left.sym); 1070 sym_calc_value(e->right.sym); 1071 str1 = sym_get_string_value(e->left.sym); 1072 str2 = sym_get_string_value(e->right.sym); 1073 1074 if (e->left.sym->type != S_STRING || e->right.sym->type != S_STRING) { 1075 k1 = expr_parse_string(str1, e->left.sym->type, &lval); 1076 k2 = expr_parse_string(str2, e->right.sym->type, &rval); 1077 } 1078 1079 if (k1 == k_string || k2 == k_string) 1080 res = strcmp(str1, str2); 1081 else if (k1 == k_unsigned || k2 == k_unsigned) 1082 res = (lval.u > rval.u) - (lval.u < rval.u); 1083 else /* if (k1 == k_signed && k2 == k_signed) */ 1084 res = (lval.s > rval.s) - (lval.s < rval.s); 1085 1086 switch(e->type) { 1087 case E_EQUAL: 1088 return res ? no : yes; 1089 case E_GEQ: 1090 return res >= 0 ? yes : no; 1091 case E_GTH: 1092 return res > 0 ? yes : no; 1093 case E_LEQ: 1094 return res <= 0 ? yes : no; 1095 case E_LTH: 1096 return res < 0 ? yes : no; 1097 case E_UNEQUAL: 1098 return res ? yes : no; 1099 default: 1100 printf("expr_calc_value: relation %d?\n", e->type); 1101 return no; 1102 } 1103 } 1104 1105 static int expr_compare_type(enum expr_type t1, enum expr_type t2) 1106 { 1107 if (t1 == t2) 1108 return 0; 1109 switch (t1) { 1110 case E_LEQ: 1111 case E_LTH: 1112 case E_GEQ: 1113 case E_GTH: 1114 if (t2 == E_EQUAL || t2 == E_UNEQUAL) 1115 return 1; 1116 case E_EQUAL: 1117 case E_UNEQUAL: 1118 if (t2 == E_NOT) 1119 return 1; 1120 case E_NOT: 1121 if (t2 == E_AND) 1122 return 1; 1123 case E_AND: 1124 if (t2 == E_OR) 1125 return 1; 1126 case E_OR: 1127 if (t2 == E_LIST) 1128 return 1; 1129 case E_LIST: 1130 if (t2 == 0) 1131 return 1; 1132 default: 1133 return -1; 1134 } 1135 printf("[%dgt%d?]", t1, t2); 1136 return 0; 1137 } 1138 1139 void expr_print(struct expr *e, 1140 void (*fn)(void *, struct symbol *, const char *), 1141 void *data, int prevtoken) 1142 { 1143 if (!e) { 1144 fn(data, NULL, "y"); 1145 return; 1146 } 1147 1148 if (expr_compare_type(prevtoken, e->type) > 0) 1149 fn(data, NULL, "("); 1150 switch (e->type) { 1151 case E_SYMBOL: 1152 if (e->left.sym->name) 1153 fn(data, e->left.sym, e->left.sym->name); 1154 else 1155 fn(data, NULL, "<choice>"); 1156 break; 1157 case E_NOT: 1158 fn(data, NULL, "!"); 1159 expr_print(e->left.expr, fn, data, E_NOT); 1160 break; 1161 case E_EQUAL: 1162 if (e->left.sym->name) 1163 fn(data, e->left.sym, e->left.sym->name); 1164 else 1165 fn(data, NULL, "<choice>"); 1166 fn(data, NULL, "="); 1167 fn(data, e->right.sym, e->right.sym->name); 1168 break; 1169 case E_LEQ: 1170 case E_LTH: 1171 if (e->left.sym->name) 1172 fn(data, e->left.sym, e->left.sym->name); 1173 else 1174 fn(data, NULL, "<choice>"); 1175 fn(data, NULL, e->type == E_LEQ ? "<=" : "<"); 1176 fn(data, e->right.sym, e->right.sym->name); 1177 break; 1178 case E_GEQ: 1179 case E_GTH: 1180 if (e->left.sym->name) 1181 fn(data, e->left.sym, e->left.sym->name); 1182 else 1183 fn(data, NULL, "<choice>"); 1184 fn(data, NULL, e->type == E_GEQ ? ">=" : ">"); 1185 fn(data, e->right.sym, e->right.sym->name); 1186 break; 1187 case E_UNEQUAL: 1188 if (e->left.sym->name) 1189 fn(data, e->left.sym, e->left.sym->name); 1190 else 1191 fn(data, NULL, "<choice>"); 1192 fn(data, NULL, "!="); 1193 fn(data, e->right.sym, e->right.sym->name); 1194 break; 1195 case E_OR: 1196 expr_print(e->left.expr, fn, data, E_OR); 1197 fn(data, NULL, " || "); 1198 expr_print(e->right.expr, fn, data, E_OR); 1199 break; 1200 case E_AND: 1201 expr_print(e->left.expr, fn, data, E_AND); 1202 fn(data, NULL, " && "); 1203 expr_print(e->right.expr, fn, data, E_AND); 1204 break; 1205 case E_LIST: 1206 fn(data, e->right.sym, e->right.sym->name); 1207 if (e->left.expr) { 1208 fn(data, NULL, " ^ "); 1209 expr_print(e->left.expr, fn, data, E_LIST); 1210 } 1211 break; 1212 case E_RANGE: 1213 fn(data, NULL, "["); 1214 fn(data, e->left.sym, e->left.sym->name); 1215 fn(data, NULL, " "); 1216 fn(data, e->right.sym, e->right.sym->name); 1217 fn(data, NULL, "]"); 1218 break; 1219 default: 1220 { 1221 char buf[32]; 1222 sprintf(buf, "<unknown type %d>", e->type); 1223 fn(data, NULL, buf); 1224 break; 1225 } 1226 } 1227 if (expr_compare_type(prevtoken, e->type) > 0) 1228 fn(data, NULL, ")"); 1229 } 1230 1231 static void expr_print_file_helper(void *data, struct symbol *sym, const char *str) 1232 { 1233 xfwrite(str, strlen(str), 1, data); 1234 } 1235 1236 void expr_fprint(struct expr *e, FILE *out) 1237 { 1238 expr_print(e, expr_print_file_helper, out, E_NONE); 1239 } 1240 1241 static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str) 1242 { 1243 struct gstr *gs = (struct gstr*)data; 1244 const char *sym_str = NULL; 1245 1246 if (sym) 1247 sym_str = sym_get_string_value(sym); 1248 1249 if (gs->max_width) { 1250 unsigned extra_length = strlen(str); 1251 const char *last_cr = strrchr(gs->s, '\n'); 1252 unsigned last_line_length; 1253 1254 if (sym_str) 1255 extra_length += 4 + strlen(sym_str); 1256 1257 if (!last_cr) 1258 last_cr = gs->s; 1259 1260 last_line_length = strlen(gs->s) - (last_cr - gs->s); 1261 1262 if ((last_line_length + extra_length) > gs->max_width) 1263 str_append(gs, "\\\n"); 1264 } 1265 1266 str_append(gs, str); 1267 if (sym && sym->type != S_UNKNOWN) 1268 str_printf(gs, " [=%s]", sym_str); 1269 } 1270 1271 void expr_gstr_print(struct expr *e, struct gstr *gs) 1272 { 1273 expr_print(e, expr_print_gstr_helper, gs, E_NONE); 1274 } 1275 1276 /* 1277 * Transform the top level "||" tokens into newlines and prepend each 1278 * line with a minus. This makes expressions much easier to read. 1279 * Suitable for reverse dependency expressions. 1280 */ 1281 static void expr_print_revdep(struct expr *e, 1282 void (*fn)(void *, struct symbol *, const char *), 1283 void *data, tristate pr_type, const char **title) 1284 { 1285 if (e->type == E_OR) { 1286 expr_print_revdep(e->left.expr, fn, data, pr_type, title); 1287 expr_print_revdep(e->right.expr, fn, data, pr_type, title); 1288 } else if (expr_calc_value(e) == pr_type) { 1289 if (*title) { 1290 fn(data, NULL, *title); 1291 *title = NULL; 1292 } 1293 1294 fn(data, NULL, " - "); 1295 expr_print(e, fn, data, E_NONE); 1296 fn(data, NULL, "\n"); 1297 } 1298 } 1299 1300 void expr_gstr_print_revdep(struct expr *e, struct gstr *gs, 1301 tristate pr_type, const char *title) 1302 { 1303 expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title); 1304 } 1305