Linux Audio

Check our new training course

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