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