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