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