Linux Audio

Check our new training course

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