Linux Audio

Check our new training course

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