expr.c revision d6ee35764f270c699e165b15dc59f4e55546bfda
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Released under the terms of the GNU GPL v2.0. 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <stdio.h> 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <stdlib.h> 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <string.h> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define LKC_DIRECT_LINK 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "lkc.h" 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEBUG_EXPR 0 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_alloc_symbol(struct symbol *sym) 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct expr *e = malloc(sizeof(*e)); 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(e, 0, sizeof(*e)); 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_SYMBOL; 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.sym = sym; 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_alloc_one(enum expr_type type, struct expr *ce) 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct expr *e = malloc(sizeof(*e)); 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(e, 0, sizeof(*e)); 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = type; 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.expr = ce; 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2) 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct expr *e = malloc(sizeof(*e)); 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(e, 0, sizeof(*e)); 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = type; 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.expr = e1; 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.expr = e2; 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2) 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct expr *e = malloc(sizeof(*e)); 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memset(e, 0, sizeof(*e)); 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = type; 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.sym = s1; 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.sym = s2; 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_alloc_and(struct expr *e1, struct expr *e2) 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!e1) 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e2; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e2 ? expr_alloc_two(E_AND, e1, e2) : e1; 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_alloc_or(struct expr *e1, struct expr *e2) 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!e1) 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e2; 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_copy(struct expr *org) 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct expr *e; 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!org) 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = malloc(sizeof(*org)); 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(e, org, sizeof(*org)); 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (org->type) { 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_SYMBOL: 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left = org->left; 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_NOT: 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.expr = expr_copy(org->left.expr); 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_EQUAL: 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_UNEQUAL: 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.sym = org->left.sym; 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.sym = org->right.sym; 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_CHOICE: 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.expr = expr_copy(org->left.expr); 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.expr = expr_copy(org->right.expr); 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("can't copy type %d\n", e->type); 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(e); 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = NULL; 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid expr_free(struct expr *e) 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!e) 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (e->type) { 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_SYMBOL: 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_NOT: 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e->left.expr); 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_EQUAL: 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_UNEQUAL: 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e->left.expr); 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e->right.expr); 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("how to free type %d?\n", e->type); 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(e); 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int trans_count; 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define e1 (*ep1) 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define e2 (*ep2) 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2) 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type == type) { 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __expr_eliminate_eq(type, &e1->left.expr, &e2); 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __expr_eliminate_eq(type, &e1->right.expr, &e2); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e2->type == type) { 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __expr_eliminate_eq(type, &e1, &e2->left.expr); 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __expr_eliminate_eq(type, &e1, &e2->right.expr); 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && 148c0e150acde52e4661675539bf5323309270f2e83Roman Zippel e1->left.sym == e2->left.sym && 149c0e150acde52e4661675539bf5323309270f2e83Roman Zippel (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no)) 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!expr_eq(e1, e2)) 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds trans_count++; 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e1); expr_free(e2); 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (type) { 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e1 = expr_alloc_symbol(&symbol_no); 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e2 = expr_alloc_symbol(&symbol_no); 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e1 = expr_alloc_symbol(&symbol_yes); 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e2 = expr_alloc_symbol(&symbol_yes); 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ; 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid expr_eliminate_eq(struct expr **ep1, struct expr **ep2) 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!e1 || !e2) 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (e1->type) { 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __expr_eliminate_eq(e1->type, ep1, ep2); 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ; 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type != e2->type) switch (e2->type) { 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __expr_eliminate_eq(e2->type, ep1, ep2); 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ; 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e1 = expr_eliminate_yn(e1); 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e2 = expr_eliminate_yn(e2); 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef e1 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef e2 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint expr_eq(struct expr *e1, struct expr *e2) 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int res, old_count; 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type != e2->type) 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (e1->type) { 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_EQUAL: 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_UNEQUAL: 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym; 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_SYMBOL: 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e1->left.sym == e2->left.sym; 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_NOT: 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_eq(e1->left.expr, e2->left.expr); 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e1 = expr_copy(e1); 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e2 = expr_copy(e2); 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds old_count = trans_count; 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_eliminate_eq(&e1, &e2); 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL && 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e1->left.sym == e2->left.sym); 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e1); 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e2); 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds trans_count = old_count; 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return res; 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_CHOICE: 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_RANGE: 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_NONE: 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* panic */; 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (DEBUG_EXPR) { 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_fprint(e1, stdout); 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" = "); 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_fprint(e2, stdout); 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(" ?\n"); 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_eliminate_yn(struct expr *e) 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct expr *tmp; 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e) switch (e->type) { 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.expr = expr_eliminate_yn(e->left.expr); 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.expr = expr_eliminate_yn(e->right.expr); 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->left.expr->type == E_SYMBOL) { 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->left.expr->left.sym == &symbol_no) { 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e->left.expr); 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e->right.expr); 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_SYMBOL; 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.sym = &symbol_no; 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.expr = NULL; 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (e->left.expr->left.sym == &symbol_yes) { 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(e->left.expr); 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = e->right.expr; 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *e = *(e->right.expr); 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(tmp); 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->right.expr->type == E_SYMBOL) { 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->right.expr->left.sym == &symbol_no) { 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e->left.expr); 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e->right.expr); 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_SYMBOL; 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.sym = &symbol_no; 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.expr = NULL; 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (e->right.expr->left.sym == &symbol_yes) { 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(e->right.expr); 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = e->left.expr; 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *e = *(e->left.expr); 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(tmp); 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.expr = expr_eliminate_yn(e->left.expr); 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.expr = expr_eliminate_yn(e->right.expr); 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->left.expr->type == E_SYMBOL) { 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->left.expr->left.sym == &symbol_no) { 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(e->left.expr); 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = e->right.expr; 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *e = *(e->right.expr); 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(tmp); 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (e->left.expr->left.sym == &symbol_yes) { 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e->left.expr); 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e->right.expr); 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_SYMBOL; 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.sym = &symbol_yes; 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.expr = NULL; 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->right.expr->type == E_SYMBOL) { 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->right.expr->left.sym == &symbol_no) { 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(e->right.expr); 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = e->left.expr; 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *e = *(e->left.expr); 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(tmp); 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (e->right.expr->left.sym == &symbol_yes) { 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e->left.expr); 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e->right.expr); 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_SYMBOL; 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.sym = &symbol_yes; 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.expr = NULL; 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ; 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bool FOO!=n => FOO 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_trans_bool(struct expr *e) 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!e) 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (e->type) { 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_NOT: 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.expr = expr_trans_bool(e->left.expr); 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.expr = expr_trans_bool(e->right.expr); 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_UNEQUAL: 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // FOO!=n -> FOO 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->left.sym->type == S_TRISTATE) { 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->right.sym == &symbol_no) { 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_SYMBOL; 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.sym = NULL; 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ; 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * e1 || e2 -> ? 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_join_or(struct expr *e1, struct expr *e2) 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct expr *tmp; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct symbol *sym1, *sym2; 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (expr_eq(e1, e2)) 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_copy(e1); 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type == E_NOT) { 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = e1->left.expr; 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym1 = tmp->left.sym; 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym1 = e1->left.sym; 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e2->type == E_NOT) { 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e2->left.expr->type != E_SYMBOL) 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym2 = e2->left.expr->left.sym; 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym2 = e2->left.sym; 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym1 != sym2) 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym1->type == S_TRISTATE) { 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type == E_EQUAL && e2->type == E_EQUAL && 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) { 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // (a='y') || (a='m') -> (a!='n') 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no); 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type == E_EQUAL && e2->type == E_EQUAL && 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) { 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // (a='y') || (a='n') -> (a!='m') 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod); 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type == E_EQUAL && e2->type == E_EQUAL && 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) { 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // (a='m') || (a='n') -> (a!='y') 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes); 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym1->type == S_BOOLEAN && sym1 == sym2) { 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) || 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL)) 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_alloc_symbol(&symbol_yes); 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (DEBUG_EXPR) { 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("optimize ("); 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_fprint(e1, stdout); 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(") || ("); 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_fprint(e2, stdout); 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(")?\n"); 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_join_and(struct expr *e1, struct expr *e2) 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct expr *tmp; 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct symbol *sym1, *sym2; 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (expr_eq(e1, e2)) 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_copy(e1); 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type == E_NOT) { 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = e1->left.expr; 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym1 = tmp->left.sym; 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym1 = e1->left.sym; 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e2->type == E_NOT) { 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e2->left.expr->type != E_SYMBOL) 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym2 = e2->left.expr->left.sym; 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym2 = e2->left.sym; 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym1 != sym2) 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) || 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes)) 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // (a) && (a='y') -> (a='y') 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) || 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no)) 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // (a) && (a!='n') -> (a) 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_alloc_symbol(sym1); 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) || 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod)) 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // (a) && (a!='m') -> (a='y') 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym1->type == S_TRISTATE) { 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) { 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym2 = e1->right.sym; 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds : expr_alloc_symbol(&symbol_no); 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) { 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym2 = e2->right.sym; 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds : expr_alloc_symbol(&symbol_no); 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // (a!='y') && (a!='n') -> (a='m') 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod); 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // (a!='y') && (a!='m') -> (a='n') 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_alloc_comp(E_EQUAL, sym1, &symbol_no); 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // (a!='m') && (a!='n') -> (a='m') 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) || 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) || 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) || 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes)) 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (DEBUG_EXPR) { 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("optimize ("); 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_fprint(e1, stdout); 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(") && ("); 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_fprint(e2, stdout); 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf(")?\n"); 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2) 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define e1 (*ep1) 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define e2 (*ep2) 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct expr *tmp; 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type == type) { 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_eliminate_dups1(type, &e1->left.expr, &e2); 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_eliminate_dups1(type, &e1->right.expr, &e2); 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e2->type == type) { 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_eliminate_dups1(type, &e1, &e2->left.expr); 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_eliminate_dups1(type, &e1, &e2->right.expr); 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1 == e2) 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (e1->type) { 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: case E_AND: 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_eliminate_dups1(e1->type, &e1, &e1); 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ; 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (type) { 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = expr_join_or(e1, e2); 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tmp) { 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e1); expr_free(e2); 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e1 = expr_alloc_symbol(&symbol_no); 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e2 = tmp; 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds trans_count++; 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = expr_join_and(e1, e2); 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tmp) { 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e1); expr_free(e2); 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e1 = expr_alloc_symbol(&symbol_yes); 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e2 = tmp; 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds trans_count++; 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ; 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef e1 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef e2 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2) 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define e1 (*ep1) 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define e2 (*ep2) 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct expr *tmp, *tmp1, *tmp2; 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type == type) { 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_eliminate_dups2(type, &e1->left.expr, &e2); 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_eliminate_dups2(type, &e1->right.expr, &e2); 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e2->type == type) { 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_eliminate_dups2(type, &e1, &e2->left.expr); 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_eliminate_dups2(type, &e1, &e2->right.expr); 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1 == e2) 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (e1->type) { 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_eliminate_dups2(e1->type, &e1, &e1); 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // (FOO || BAR) && (!FOO && !BAR) -> n 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp2 = expr_copy(e2); 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = expr_extract_eq_and(&tmp1, &tmp2); 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (expr_is_yes(tmp1)) { 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e1); 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e1 = expr_alloc_symbol(&symbol_no); 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds trans_count++; 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(tmp2); 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(tmp1); 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(tmp); 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_eliminate_dups2(e1->type, &e1, &e1); 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // (FOO && BAR) || (!FOO || !BAR) -> y 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp2 = expr_copy(e2); 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = expr_extract_eq_or(&tmp1, &tmp2); 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (expr_is_no(tmp1)) { 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e1); 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e1 = expr_alloc_symbol(&symbol_yes); 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds trans_count++; 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(tmp2); 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(tmp1); 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(tmp); 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ; 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef e1 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef e2 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_eliminate_dups(struct expr *e) 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int oldcount; 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!e) 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds oldcount = trans_count; 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (1) { 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds trans_count = 0; 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (e->type) { 6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: case E_AND: 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_eliminate_dups1(e->type, &e, &e); 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_eliminate_dups2(e->type, &e, &e); 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ; 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!trans_count) 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = expr_eliminate_yn(e); 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds trans_count = oldcount; 6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_transform(struct expr *e) 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct expr *tmp; 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!e) 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (e->type) { 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_EQUAL: 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_UNEQUAL: 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_SYMBOL: 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_CHOICE: 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.expr = expr_transform(e->left.expr); 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.expr = expr_transform(e->right.expr); 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (e->type) { 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_EQUAL: 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->left.sym->type != S_BOOLEAN) 6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->right.sym == &symbol_no) { 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_NOT; 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.expr = expr_alloc_symbol(e->left.sym); 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.sym = NULL; 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->right.sym == &symbol_mod) { 6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name); 6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_SYMBOL; 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.sym = &symbol_no; 6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.sym = NULL; 6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->right.sym == &symbol_yes) { 6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_SYMBOL; 6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.sym = NULL; 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_UNEQUAL: 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->left.sym->type != S_BOOLEAN) 6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->right.sym == &symbol_no) { 6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_SYMBOL; 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.sym = NULL; 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->right.sym == &symbol_mod) { 6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name); 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_SYMBOL; 6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.sym = &symbol_yes; 6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.sym = NULL; 6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->right.sym == &symbol_yes) { 6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_NOT; 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.expr = expr_alloc_symbol(e->left.sym); 6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.sym = NULL; 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_NOT: 7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (e->left.expr->type) { 7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_NOT: 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // !!a -> a 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = e->left.expr->left.expr; 7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(e->left.expr); 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(e); 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = tmp; 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = expr_transform(e); 7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_EQUAL: 7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_UNEQUAL: 7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // !a='x' -> a!='x' 7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = e->left.expr; 7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(e); 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = tmp; 7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // !(a || b) -> !a && !b 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = e->left.expr; 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_AND; 7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); 7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp->type = E_NOT; 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp->right.expr = NULL; 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = expr_transform(e); 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // !(a && b) -> !a || !b 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = e->left.expr; 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_OR; 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp->type = E_NOT; 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp->right.expr = NULL; 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = expr_transform(e); 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_SYMBOL: 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->left.expr->left.sym == &symbol_yes) { 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // !'y' -> 'n' 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = e->left.expr; 7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(e); 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = tmp; 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_SYMBOL; 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.sym = &symbol_no; 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->left.expr->left.sym == &symbol_mod) { 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // !'m' -> 'm' 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = e->left.expr; 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(e); 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = tmp; 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_SYMBOL; 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.sym = &symbol_mod; 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->left.expr->left.sym == &symbol_no) { 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds // !'n' -> 'y' 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = e->left.expr; 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free(e); 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = tmp; 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->type = E_SYMBOL; 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e->left.sym = &symbol_yes; 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ; 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ; 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint expr_contains_symbol(struct expr *dep, struct symbol *sym) 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dep) 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (dep->type) { 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_contains_symbol(dep->left.expr, sym) || 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_contains_symbol(dep->right.expr, sym); 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_SYMBOL: 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dep->left.sym == sym; 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_EQUAL: 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_UNEQUAL: 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dep->left.sym == sym || 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dep->right.sym == sym; 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_NOT: 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_contains_symbol(dep->left.expr, sym); 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ; 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsbool expr_depends_symbol(struct expr *dep, struct symbol *sym) 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dep) 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return false; 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (dep->type) { 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_depends_symbol(dep->left.expr, sym) || 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_depends_symbol(dep->right.expr, sym); 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_SYMBOL: 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dep->left.sym == sym; 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_EQUAL: 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dep->left.sym == sym) { 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod) 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return true; 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_UNEQUAL: 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dep->left.sym == sym) { 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dep->right.sym == &symbol_no) 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return true; 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ; 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return false; 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2) 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct expr *tmp = NULL; 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_extract_eq(E_AND, &tmp, ep1, ep2); 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tmp) { 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ep1 = expr_eliminate_yn(*ep1); 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ep2 = expr_eliminate_yn(*ep2); 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return tmp; 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2) 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct expr *tmp = NULL; 8451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_extract_eq(E_OR, &tmp, ep1, ep2); 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (tmp) { 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ep1 = expr_eliminate_yn(*ep1); 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ep2 = expr_eliminate_yn(*ep2); 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return tmp; 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2) 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define e1 (*ep1) 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define e2 (*ep2) 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e1->type == type) { 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_extract_eq(type, ep, &e1->left.expr, &e2); 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_extract_eq(type, ep, &e1->right.expr, &e2); 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e2->type == type) { 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_extract_eq(type, ep, ep1, &e2->left.expr); 8641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_extract_eq(type, ep, ep1, &e2->right.expr); 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (expr_eq(e1, e2)) { 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1; 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_free(e2); 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (type == E_AND) { 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e1 = expr_alloc_symbol(&symbol_yes); 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e2 = expr_alloc_symbol(&symbol_yes); 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else if (type == E_OR) { 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e1 = expr_alloc_symbol(&symbol_no); 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e2 = expr_alloc_symbol(&symbol_no); 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef e1 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef e2 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym) 8831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct expr *e1, *e2; 8851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!e) { 8871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = expr_alloc_symbol(sym); 8881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (type == E_UNEQUAL) 8891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = expr_alloc_one(E_NOT, e); 8901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 8911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (e->type) { 8931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 8941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); 8951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); 8961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym == &symbol_yes) 8971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = expr_alloc_two(E_AND, e1, e2); 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym == &symbol_no) 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = expr_alloc_two(E_OR, e1, e2); 9001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (type == E_UNEQUAL) 9011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = expr_alloc_one(E_NOT, e); 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 9031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); 9061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym == &symbol_yes) 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = expr_alloc_two(E_OR, e1, e2); 9081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym == &symbol_no) 9091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = expr_alloc_two(E_AND, e1, e2); 9101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (type == E_UNEQUAL) 9111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds e = expr_alloc_one(E_NOT, e); 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e; 9131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_NOT: 9141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym); 9151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_UNEQUAL: 9161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_EQUAL: 9171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (type == E_EQUAL) { 9181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym == &symbol_yes) 9191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_copy(e); 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym == &symbol_mod) 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_alloc_symbol(&symbol_no); 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym == &symbol_no) 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_alloc_one(E_NOT, expr_copy(e)); 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 9251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym == &symbol_yes) 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_alloc_one(E_NOT, expr_copy(e)); 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym == &symbol_mod) 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_alloc_symbol(&symbol_yes); 9291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sym == &symbol_no) 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_copy(e); 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_SYMBOL: 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return expr_alloc_comp(type, e->left.sym, sym); 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_CHOICE: 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_RANGE: 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_NONE: 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* panic */; 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldstristate expr_calc_value(struct expr *e) 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tristate val1, val2; 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const char *str1, *str2; 9471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!e) 9491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return yes; 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (e->type) { 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_SYMBOL: 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym_calc_value(e->left.sym); 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return e->left.sym->curr.tri; 9551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 9561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val1 = expr_calc_value(e->left.expr); 9571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val2 = expr_calc_value(e->right.expr); 958d6ee35764f270c699e165b15dc59f4e55546bfdaSam Ravnborg return EXPR_AND(val1, val2); 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val1 = expr_calc_value(e->left.expr); 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val2 = expr_calc_value(e->right.expr); 962d6ee35764f270c699e165b15dc59f4e55546bfdaSam Ravnborg return EXPR_OR(val1, val2); 9631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_NOT: 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds val1 = expr_calc_value(e->left.expr); 965d6ee35764f270c699e165b15dc59f4e55546bfdaSam Ravnborg return EXPR_NOT(val1); 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_EQUAL: 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym_calc_value(e->left.sym); 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym_calc_value(e->right.sym); 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds str1 = sym_get_string_value(e->left.sym); 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds str2 = sym_get_string_value(e->right.sym); 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return !strcmp(str1, str2) ? yes : no; 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_UNEQUAL: 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym_calc_value(e->left.sym); 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym_calc_value(e->right.sym); 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds str1 = sym_get_string_value(e->left.sym); 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds str2 = sym_get_string_value(e->right.sym); 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return !strcmp(str1, str2) ? no : yes; 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 9791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("expr_calc_value: %d?\n", e->type); 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return no; 9811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 9831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint expr_compare_type(enum expr_type t1, enum expr_type t2) 9851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if 0 9871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 9881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 9891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (t1 == t2) 9901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 9911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (t1) { 9921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_EQUAL: 9931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_UNEQUAL: 9941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (t2 == E_NOT) 9951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 9961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_NOT: 9971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (t2 == E_AND) 9981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 9991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 10001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (t2 == E_OR) 10011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 10021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 10031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (t2 == E_CHOICE) 10041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 10051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_CHOICE: 10061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (t2 == 0) 10071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 10081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 10091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 10101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printf("[%dgt%d?]", t1, t2); 10121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 10131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 10141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1016ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippelvoid expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken) 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!e) { 1019ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, NULL, "y"); 10201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 10211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (expr_compare_type(prevtoken, e->type) > 0) 1024ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, NULL, "("); 10251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (e->type) { 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_SYMBOL: 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->left.sym->name) 1028ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, e->left.sym, e->left.sym->name); 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds else 1030ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, NULL, "<choice>"); 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_NOT: 1033ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, NULL, "!"); 10341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_print(e->left.expr, fn, data, E_NOT); 10351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_EQUAL: 1037ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, e->left.sym, e->left.sym->name); 1038ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, NULL, "="); 1039ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, e->right.sym, e->right.sym->name); 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_UNEQUAL: 1042ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, e->left.sym, e->left.sym->name); 1043ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, NULL, "!="); 1044ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, e->right.sym, e->right.sym->name); 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_OR: 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_print(e->left.expr, fn, data, E_OR); 1048ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, NULL, " || "); 10491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_print(e->right.expr, fn, data, E_OR); 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_AND: 10521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_print(e->left.expr, fn, data, E_AND); 1053ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, NULL, " && "); 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_print(e->right.expr, fn, data, E_AND); 10551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_CHOICE: 1057ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, e->right.sym, e->right.sym->name); 10581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (e->left.expr) { 1059ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, NULL, " ^ "); 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_print(e->left.expr, fn, data, E_CHOICE); 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case E_RANGE: 1064ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, NULL, "["); 1065ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, e->left.sym, e->left.sym->name); 1066ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, NULL, " "); 1067ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, e->right.sym, e->right.sym->name); 1068ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, NULL, "]"); 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char buf[32]; 10731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sprintf(buf, "<unknown type %d>", e->type); 1074ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, NULL, buf); 10751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 10761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (expr_compare_type(prevtoken, e->type) > 0) 1079ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippel fn(data, NULL, ")"); 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1082ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippelstatic void expr_print_file_helper(void *data, struct symbol *sym, const char *str) 10831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fwrite(str, strlen(str), 1, data); 10851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid expr_fprint(struct expr *e, FILE *out) 10881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_print(e, expr_print_file_helper, out, E_NONE); 10901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1092ab45d190fd4acf0b0e5d307294ce24a90a69cc23Roman Zippelstatic void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str) 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds str_append((struct gstr*)data, str); 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid expr_gstr_print(struct expr *e, struct gstr *gs) 10981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expr_print(e, expr_print_gstr_helper, gs, E_NONE); 11001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1101