1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
16 static int expr_eq(struct expr
*e1
, struct expr
*e2
);
17 static struct expr
*expr_eliminate_yn(struct expr
*e
);
19 struct expr
*expr_alloc_symbol(struct symbol
*sym
)
21 struct expr
*e
= xcalloc(1, sizeof(*e
));
27 struct expr
*expr_alloc_one(enum expr_type type
, struct expr
*ce
)
29 struct expr
*e
= xcalloc(1, sizeof(*e
));
35 struct expr
*expr_alloc_two(enum expr_type type
, struct expr
*e1
, struct expr
*e2
)
37 struct expr
*e
= xcalloc(1, sizeof(*e
));
44 struct expr
*expr_alloc_comp(enum expr_type type
, struct symbol
*s1
, struct symbol
*s2
)
46 struct expr
*e
= xcalloc(1, sizeof(*e
));
53 struct expr
*expr_alloc_and(struct expr
*e1
, struct expr
*e2
)
57 return e2
? expr_alloc_two(E_AND
, e1
, e2
) : e1
;
60 struct expr
*expr_alloc_or(struct expr
*e1
, struct expr
*e2
)
64 return e2
? expr_alloc_two(E_OR
, e1
, e2
) : e1
;
67 struct expr
*expr_copy(const struct expr
*org
)
74 e
= xmalloc(sizeof(*org
));
75 memcpy(e
, org
, sizeof(*org
));
81 e
->left
.expr
= expr_copy(org
->left
.expr
);
89 e
->left
.sym
= org
->left
.sym
;
90 e
->right
.sym
= org
->right
.sym
;
95 e
->left
.expr
= expr_copy(org
->left
.expr
);
96 e
->right
.expr
= expr_copy(org
->right
.expr
);
99 fprintf(stderr
, "can't copy type %d\n", e
->type
);
108 void expr_free(struct expr
*e
)
117 expr_free(e
->left
.expr
);
128 expr_free(e
->left
.expr
);
129 expr_free(e
->right
.expr
);
132 fprintf(stderr
, "how to free type %d?\n", e
->type
);
138 static int trans_count
;
144 * expr_eliminate_eq() helper.
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.
151 static void __expr_eliminate_eq(enum expr_type type
, struct expr
**ep1
, struct expr
**ep2
)
153 /* Recurse down to leaves */
155 if (e1
->type
== type
) {
156 __expr_eliminate_eq(type
, &e1
->left
.expr
, &e2
);
157 __expr_eliminate_eq(type
, &e1
->right
.expr
, &e2
);
160 if (e2
->type
== type
) {
161 __expr_eliminate_eq(type
, &e1
, &e2
->left
.expr
);
162 __expr_eliminate_eq(type
, &e1
, &e2
->right
.expr
);
166 /* e1 and e2 are leaves. Compare them. */
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
))
172 if (!expr_eq(e1
, e2
))
175 /* e1 and e2 are equal leaves. Prepare them for elimination. */
178 expr_free(e1
); expr_free(e2
);
181 e1
= expr_alloc_symbol(&symbol_no
);
182 e2
= expr_alloc_symbol(&symbol_no
);
185 e1
= expr_alloc_symbol(&symbol_yes
);
186 e2
= expr_alloc_symbol(&symbol_yes
);
194 * Rewrites the expressions 'ep1' and 'ep2' to remove operands common to both.
195 * Example reductions:
197 * ep1: A && B -> ep1: y
198 * ep2: A && B && C -> ep2: C
200 * ep1: A || B -> ep1: n
201 * ep2: A || B || C -> ep2: C
203 * ep1: A && (B && FOO) -> ep1: FOO
204 * ep2: (BAR && B) && A -> ep2: BAR
206 * ep1: A && (B || C) -> ep1: y
207 * ep2: (C || B) && A -> ep2: y
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:
213 * - 'e1', 'e2 || e3', and 'e4 || e5', against each other
217 * Parentheses are irrelevant within a single level. 'e1 && (e2 && e3)' and
218 * '(e1 && e2) && e3' are both a single level.
220 * See __expr_eliminate_eq() as well.
222 void expr_eliminate_eq(struct expr
**ep1
, struct expr
**ep2
)
229 __expr_eliminate_eq(e1
->type
, ep1
, ep2
);
233 if (e1
->type
!= e2
->type
) switch (e2
->type
) {
236 __expr_eliminate_eq(e2
->type
, ep1
, ep2
);
240 e1
= expr_eliminate_yn(e1
);
241 e2
= expr_eliminate_yn(e2
);
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.
253 static int expr_eq(struct expr
*e1
, struct expr
*e2
)
257 if (e1
->type
!= e2
->type
)
266 return e1
->left
.sym
== e2
->left
.sym
&& e1
->right
.sym
== e2
->right
.sym
;
268 return e1
->left
.sym
== e2
->left
.sym
;
270 return expr_eq(e1
->left
.expr
, e2
->left
.expr
);
275 old_count
= trans_count
;
276 expr_eliminate_eq(&e1
, &e2
);
277 res
= (e1
->type
== E_SYMBOL
&& e2
->type
== E_SYMBOL
&&
278 e1
->left
.sym
== e2
->left
.sym
);
281 trans_count
= old_count
;
290 expr_fprint(e1
, stdout
);
292 expr_fprint(e2
, stdout
);
300 * Recursively performs the following simplifications in-place (as well as the
301 * corresponding simplifications with swapped operands):
308 * Returns the optimized expression.
310 static struct expr
*expr_eliminate_yn(struct expr
*e
)
314 if (e
) switch (e
->type
) {
316 e
->left
.expr
= expr_eliminate_yn(e
->left
.expr
);
317 e
->right
.expr
= expr_eliminate_yn(e
->right
.expr
);
318 if (e
->left
.expr
->type
== E_SYMBOL
) {
319 if (e
->left
.expr
->left
.sym
== &symbol_no
) {
320 expr_free(e
->left
.expr
);
321 expr_free(e
->right
.expr
);
323 e
->left
.sym
= &symbol_no
;
324 e
->right
.expr
= NULL
;
326 } else if (e
->left
.expr
->left
.sym
== &symbol_yes
) {
329 *e
= *(e
->right
.expr
);
334 if (e
->right
.expr
->type
== E_SYMBOL
) {
335 if (e
->right
.expr
->left
.sym
== &symbol_no
) {
336 expr_free(e
->left
.expr
);
337 expr_free(e
->right
.expr
);
339 e
->left
.sym
= &symbol_no
;
340 e
->right
.expr
= NULL
;
342 } else if (e
->right
.expr
->left
.sym
== &symbol_yes
) {
345 *e
= *(e
->left
.expr
);
352 e
->left
.expr
= expr_eliminate_yn(e
->left
.expr
);
353 e
->right
.expr
= expr_eliminate_yn(e
->right
.expr
);
354 if (e
->left
.expr
->type
== E_SYMBOL
) {
355 if (e
->left
.expr
->left
.sym
== &symbol_no
) {
358 *e
= *(e
->right
.expr
);
361 } else if (e
->left
.expr
->left
.sym
== &symbol_yes
) {
362 expr_free(e
->left
.expr
);
363 expr_free(e
->right
.expr
);
365 e
->left
.sym
= &symbol_yes
;
366 e
->right
.expr
= NULL
;
370 if (e
->right
.expr
->type
== E_SYMBOL
) {
371 if (e
->right
.expr
->left
.sym
== &symbol_no
) {
374 *e
= *(e
->left
.expr
);
377 } else if (e
->right
.expr
->left
.sym
== &symbol_yes
) {
378 expr_free(e
->left
.expr
);
379 expr_free(e
->right
.expr
);
381 e
->left
.sym
= &symbol_yes
;
382 e
->right
.expr
= NULL
;
396 struct expr
*expr_trans_bool(struct expr
*e
)
404 e
->left
.expr
= expr_trans_bool(e
->left
.expr
);
405 e
->right
.expr
= expr_trans_bool(e
->right
.expr
);
409 if (e
->left
.sym
->type
== S_TRISTATE
) {
410 if (e
->right
.sym
== &symbol_no
) {
425 static struct expr
*expr_join_or(struct expr
*e1
, struct expr
*e2
)
428 struct symbol
*sym1
, *sym2
;
431 return expr_copy(e1
);
432 if (e1
->type
!= E_EQUAL
&& e1
->type
!= E_UNEQUAL
&& e1
->type
!= E_SYMBOL
&& e1
->type
!= E_NOT
)
434 if (e2
->type
!= E_EQUAL
&& e2
->type
!= E_UNEQUAL
&& e2
->type
!= E_SYMBOL
&& e2
->type
!= E_NOT
)
436 if (e1
->type
== E_NOT
) {
438 if (tmp
->type
!= E_EQUAL
&& tmp
->type
!= E_UNEQUAL
&& tmp
->type
!= E_SYMBOL
)
440 sym1
= tmp
->left
.sym
;
443 if (e2
->type
== E_NOT
) {
444 if (e2
->left
.expr
->type
!= E_SYMBOL
)
446 sym2
= e2
->left
.expr
->left
.sym
;
451 if (sym1
->type
!= S_BOOLEAN
&& sym1
->type
!= S_TRISTATE
)
453 if (sym1
->type
== S_TRISTATE
) {
454 if (e1
->type
== E_EQUAL
&& e2
->type
== E_EQUAL
&&
455 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_mod
) ||
456 (e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_yes
))) {
457 // (a='y') || (a='m') -> (a!='n')
458 return expr_alloc_comp(E_UNEQUAL
, sym1
, &symbol_no
);
460 if (e1
->type
== E_EQUAL
&& e2
->type
== E_EQUAL
&&
461 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_no
) ||
462 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_yes
))) {
463 // (a='y') || (a='n') -> (a!='m')
464 return expr_alloc_comp(E_UNEQUAL
, sym1
, &symbol_mod
);
466 if (e1
->type
== E_EQUAL
&& e2
->type
== E_EQUAL
&&
467 ((e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_no
) ||
468 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_mod
))) {
469 // (a='m') || (a='n') -> (a!='y')
470 return expr_alloc_comp(E_UNEQUAL
, sym1
, &symbol_yes
);
473 if (sym1
->type
== S_BOOLEAN
&& sym1
== sym2
) {
474 if ((e1
->type
== E_NOT
&& e1
->left
.expr
->type
== E_SYMBOL
&& e2
->type
== E_SYMBOL
) ||
475 (e2
->type
== E_NOT
&& e2
->left
.expr
->type
== E_SYMBOL
&& e1
->type
== E_SYMBOL
))
476 return expr_alloc_symbol(&symbol_yes
);
480 printf("optimize (");
481 expr_fprint(e1
, stdout
);
483 expr_fprint(e2
, stdout
);
489 static struct expr
*expr_join_and(struct expr
*e1
, struct expr
*e2
)
492 struct symbol
*sym1
, *sym2
;
495 return expr_copy(e1
);
496 if (e1
->type
!= E_EQUAL
&& e1
->type
!= E_UNEQUAL
&& e1
->type
!= E_SYMBOL
&& e1
->type
!= E_NOT
)
498 if (e2
->type
!= E_EQUAL
&& e2
->type
!= E_UNEQUAL
&& e2
->type
!= E_SYMBOL
&& e2
->type
!= E_NOT
)
500 if (e1
->type
== E_NOT
) {
502 if (tmp
->type
!= E_EQUAL
&& tmp
->type
!= E_UNEQUAL
&& tmp
->type
!= E_SYMBOL
)
504 sym1
= tmp
->left
.sym
;
507 if (e2
->type
== E_NOT
) {
508 if (e2
->left
.expr
->type
!= E_SYMBOL
)
510 sym2
= e2
->left
.expr
->left
.sym
;
515 if (sym1
->type
!= S_BOOLEAN
&& sym1
->type
!= S_TRISTATE
)
518 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_EQUAL
&& e2
->right
.sym
== &symbol_yes
) ||
519 (e2
->type
== E_SYMBOL
&& e1
->type
== E_EQUAL
&& e1
->right
.sym
== &symbol_yes
))
520 // (a) && (a='y') -> (a='y')
521 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_yes
);
523 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_UNEQUAL
&& e2
->right
.sym
== &symbol_no
) ||
524 (e2
->type
== E_SYMBOL
&& e1
->type
== E_UNEQUAL
&& e1
->right
.sym
== &symbol_no
))
525 // (a) && (a!='n') -> (a)
526 return expr_alloc_symbol(sym1
);
528 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_UNEQUAL
&& e2
->right
.sym
== &symbol_mod
) ||
529 (e2
->type
== E_SYMBOL
&& e1
->type
== E_UNEQUAL
&& e1
->right
.sym
== &symbol_mod
))
530 // (a) && (a!='m') -> (a='y')
531 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_yes
);
533 if (sym1
->type
== S_TRISTATE
) {
534 if (e1
->type
== E_EQUAL
&& e2
->type
== E_UNEQUAL
) {
535 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
536 sym2
= e1
->right
.sym
;
537 if ((e2
->right
.sym
->flags
& SYMBOL_CONST
) && (sym2
->flags
& SYMBOL_CONST
))
538 return sym2
!= e2
->right
.sym
? expr_alloc_comp(E_EQUAL
, sym1
, sym2
)
539 : expr_alloc_symbol(&symbol_no
);
541 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_EQUAL
) {
542 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
543 sym2
= e2
->right
.sym
;
544 if ((e1
->right
.sym
->flags
& SYMBOL_CONST
) && (sym2
->flags
& SYMBOL_CONST
))
545 return sym2
!= e1
->right
.sym
? expr_alloc_comp(E_EQUAL
, sym1
, sym2
)
546 : expr_alloc_symbol(&symbol_no
);
548 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_UNEQUAL
&&
549 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_no
) ||
550 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_yes
)))
551 // (a!='y') && (a!='n') -> (a='m')
552 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_mod
);
554 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_UNEQUAL
&&
555 ((e1
->right
.sym
== &symbol_yes
&& e2
->right
.sym
== &symbol_mod
) ||
556 (e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_yes
)))
557 // (a!='y') && (a!='m') -> (a='n')
558 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_no
);
560 if (e1
->type
== E_UNEQUAL
&& e2
->type
== E_UNEQUAL
&&
561 ((e1
->right
.sym
== &symbol_mod
&& e2
->right
.sym
== &symbol_no
) ||
562 (e1
->right
.sym
== &symbol_no
&& e2
->right
.sym
== &symbol_mod
)))
563 // (a!='m') && (a!='n') -> (a='m')
564 return expr_alloc_comp(E_EQUAL
, sym1
, &symbol_yes
);
566 if ((e1
->type
== E_SYMBOL
&& e2
->type
== E_EQUAL
&& e2
->right
.sym
== &symbol_mod
) ||
567 (e2
->type
== E_SYMBOL
&& e1
->type
== E_EQUAL
&& e1
->right
.sym
== &symbol_mod
) ||
568 (e1
->type
== E_SYMBOL
&& e2
->type
== E_UNEQUAL
&& e2
->right
.sym
== &symbol_yes
) ||
569 (e2
->type
== E_SYMBOL
&& e1
->type
== E_UNEQUAL
&& e1
->right
.sym
== &symbol_yes
))
574 printf("optimize (");
575 expr_fprint(e1
, stdout
);
577 expr_fprint(e2
, stdout
);
584 * expr_eliminate_dups() helper.
586 * Walks the two expression trees given in 'ep1' and 'ep2'. Any node that does
587 * not have type 'type' (E_OR/E_AND) is considered a leaf, and is compared
588 * against all other leaves to look for simplifications.
590 static void expr_eliminate_dups1(enum expr_type type
, struct expr
**ep1
, struct expr
**ep2
)
596 /* Recurse down to leaves */
598 if (e1
->type
== type
) {
599 expr_eliminate_dups1(type
, &e1
->left
.expr
, &e2
);
600 expr_eliminate_dups1(type
, &e1
->right
.expr
, &e2
);
603 if (e2
->type
== type
) {
604 expr_eliminate_dups1(type
, &e1
, &e2
->left
.expr
);
605 expr_eliminate_dups1(type
, &e1
, &e2
->right
.expr
);
609 /* e1 and e2 are leaves. Compare and process them. */
615 case E_OR
: case E_AND
:
616 expr_eliminate_dups1(e1
->type
, &e1
, &e1
);
623 tmp
= expr_join_or(e1
, e2
);
625 expr_free(e1
); expr_free(e2
);
626 e1
= expr_alloc_symbol(&symbol_no
);
632 tmp
= expr_join_and(e1
, e2
);
634 expr_free(e1
); expr_free(e2
);
635 e1
= expr_alloc_symbol(&symbol_yes
);
648 * Rewrites 'e' in-place to remove ("join") duplicate and other redundant
651 * Example simplifications:
653 * A || B || A -> A || B
654 * A && B && A=y -> A=y && B
656 * Returns the deduplicated expression.
658 struct expr
*expr_eliminate_dups(struct expr
*e
)
664 oldcount
= trans_count
;
668 case E_OR
: case E_AND
:
669 expr_eliminate_dups1(e
->type
, &e
, &e
);
674 /* No simplifications done in this pass. We're done */
676 e
= expr_eliminate_yn(e
);
678 trans_count
= oldcount
;
683 * Performs various simplifications involving logical operators and
686 * Allocates and returns a new expression.
688 struct expr
*expr_transform(struct expr
*e
)
705 e
->left
.expr
= expr_transform(e
->left
.expr
);
706 e
->right
.expr
= expr_transform(e
->right
.expr
);
711 if (e
->left
.sym
->type
!= S_BOOLEAN
)
713 if (e
->right
.sym
== &symbol_no
) {
715 e
->left
.expr
= expr_alloc_symbol(e
->left
.sym
);
719 if (e
->right
.sym
== &symbol_mod
) {
720 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e
->left
.sym
->name
);
722 e
->left
.sym
= &symbol_no
;
726 if (e
->right
.sym
== &symbol_yes
) {
733 if (e
->left
.sym
->type
!= S_BOOLEAN
)
735 if (e
->right
.sym
== &symbol_no
) {
740 if (e
->right
.sym
== &symbol_mod
) {
741 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e
->left
.sym
->name
);
743 e
->left
.sym
= &symbol_yes
;
747 if (e
->right
.sym
== &symbol_yes
) {
749 e
->left
.expr
= expr_alloc_symbol(e
->left
.sym
);
755 switch (e
->left
.expr
->type
) {
758 tmp
= e
->left
.expr
->left
.expr
;
762 e
= expr_transform(e
);
770 e
->type
= e
->type
== E_EQUAL
? E_UNEQUAL
: E_EQUAL
;
778 e
->type
= e
->type
== E_LEQ
? E_GTH
: E_LTH
;
786 e
->type
= e
->type
== E_LTH
? E_GEQ
: E_LEQ
;
789 // !(a || b) -> !a && !b
792 e
->right
.expr
= expr_alloc_one(E_NOT
, tmp
->right
.expr
);
794 tmp
->right
.expr
= NULL
;
795 e
= expr_transform(e
);
798 // !(a && b) -> !a || !b
801 e
->right
.expr
= expr_alloc_one(E_NOT
, tmp
->right
.expr
);
803 tmp
->right
.expr
= NULL
;
804 e
= expr_transform(e
);
807 if (e
->left
.expr
->left
.sym
== &symbol_yes
) {
813 e
->left
.sym
= &symbol_no
;
816 if (e
->left
.expr
->left
.sym
== &symbol_mod
) {
822 e
->left
.sym
= &symbol_mod
;
825 if (e
->left
.expr
->left
.sym
== &symbol_no
) {
831 e
->left
.sym
= &symbol_yes
;
845 int expr_contains_symbol(struct expr
*dep
, struct symbol
*sym
)
853 return expr_contains_symbol(dep
->left
.expr
, sym
) ||
854 expr_contains_symbol(dep
->right
.expr
, sym
);
856 return dep
->left
.sym
== sym
;
863 return dep
->left
.sym
== sym
||
864 dep
->right
.sym
== sym
;
866 return expr_contains_symbol(dep
->left
.expr
, sym
);
873 bool expr_depends_symbol(struct expr
*dep
, struct symbol
*sym
)
880 return expr_depends_symbol(dep
->left
.expr
, sym
) ||
881 expr_depends_symbol(dep
->right
.expr
, sym
);
883 return dep
->left
.sym
== sym
;
885 if (dep
->left
.sym
== sym
) {
886 if (dep
->right
.sym
== &symbol_yes
|| dep
->right
.sym
== &symbol_mod
)
891 if (dep
->left
.sym
== sym
) {
892 if (dep
->right
.sym
== &symbol_no
)
903 * Inserts explicit comparisons of type 'type' to symbol 'sym' into the
906 * Examples transformations for type == E_UNEQUAL, sym == &symbol_no:
910 * A && B -> !(A=n || B=n)
911 * A || B -> !(A=n && B=n)
912 * A && (B || C) -> !(A=n || (B=n && C=n))
914 * Allocates and returns a new expression.
916 struct expr
*expr_trans_compare(struct expr
*e
, enum expr_type type
, struct symbol
*sym
)
918 struct expr
*e1
, *e2
;
921 e
= expr_alloc_symbol(sym
);
922 if (type
== E_UNEQUAL
)
923 e
= expr_alloc_one(E_NOT
, e
);
928 e1
= expr_trans_compare(e
->left
.expr
, E_EQUAL
, sym
);
929 e2
= expr_trans_compare(e
->right
.expr
, E_EQUAL
, sym
);
930 if (sym
== &symbol_yes
)
931 e
= expr_alloc_two(E_AND
, e1
, e2
);
932 if (sym
== &symbol_no
)
933 e
= expr_alloc_two(E_OR
, e1
, e2
);
934 if (type
== E_UNEQUAL
)
935 e
= expr_alloc_one(E_NOT
, e
);
938 e1
= expr_trans_compare(e
->left
.expr
, E_EQUAL
, sym
);
939 e2
= expr_trans_compare(e
->right
.expr
, E_EQUAL
, sym
);
940 if (sym
== &symbol_yes
)
941 e
= expr_alloc_two(E_OR
, e1
, e2
);
942 if (sym
== &symbol_no
)
943 e
= expr_alloc_two(E_AND
, e1
, e2
);
944 if (type
== E_UNEQUAL
)
945 e
= expr_alloc_one(E_NOT
, e
);
948 return expr_trans_compare(e
->left
.expr
, type
== E_EQUAL
? E_UNEQUAL
: E_EQUAL
, sym
);
955 if (type
== E_EQUAL
) {
956 if (sym
== &symbol_yes
)
958 if (sym
== &symbol_mod
)
959 return expr_alloc_symbol(&symbol_no
);
960 if (sym
== &symbol_no
)
961 return expr_alloc_one(E_NOT
, expr_copy(e
));
963 if (sym
== &symbol_yes
)
964 return expr_alloc_one(E_NOT
, expr_copy(e
));
965 if (sym
== &symbol_mod
)
966 return expr_alloc_symbol(&symbol_yes
);
967 if (sym
== &symbol_no
)
972 return expr_alloc_comp(type
, e
->left
.sym
, sym
);
981 enum string_value_kind
{
988 unsigned long long u
;
992 static enum string_value_kind
expr_parse_string(const char *str
,
993 enum symbol_type type
,
994 union string_value
*val
)
997 enum string_value_kind kind
;
1003 val
->s
= !strcmp(str
, "n") ? 0 :
1004 !strcmp(str
, "m") ? 1 :
1005 !strcmp(str
, "y") ? 2 : -1;
1008 val
->s
= strtoll(str
, &tail
, 10);
1012 val
->u
= strtoull(str
, &tail
, 16);
1016 val
->s
= strtoll(str
, &tail
, 0);
1020 return !errno
&& !*tail
&& tail
> str
&& isxdigit(tail
[-1])
1024 tristate
expr_calc_value(struct expr
*e
)
1026 tristate val1
, val2
;
1027 const char *str1
, *str2
;
1028 enum string_value_kind k1
= k_string
, k2
= k_string
;
1029 union string_value lval
= {}, rval
= {};
1037 sym_calc_value(e
->left
.sym
);
1038 return e
->left
.sym
->curr
.tri
;
1040 val1
= expr_calc_value(e
->left
.expr
);
1041 val2
= expr_calc_value(e
->right
.expr
);
1042 return EXPR_AND(val1
, val2
);
1044 val1
= expr_calc_value(e
->left
.expr
);
1045 val2
= expr_calc_value(e
->right
.expr
);
1046 return EXPR_OR(val1
, val2
);
1048 val1
= expr_calc_value(e
->left
.expr
);
1049 return EXPR_NOT(val1
);
1058 printf("expr_calc_value: %d?\n", e
->type
);
1062 sym_calc_value(e
->left
.sym
);
1063 sym_calc_value(e
->right
.sym
);
1064 str1
= sym_get_string_value(e
->left
.sym
);
1065 str2
= sym_get_string_value(e
->right
.sym
);
1067 if (e
->left
.sym
->type
!= S_STRING
|| e
->right
.sym
->type
!= S_STRING
) {
1068 k1
= expr_parse_string(str1
, e
->left
.sym
->type
, &lval
);
1069 k2
= expr_parse_string(str2
, e
->right
.sym
->type
, &rval
);
1072 if (k1
== k_string
|| k2
== k_string
)
1073 res
= strcmp(str1
, str2
);
1074 else if (k1
== k_unsigned
|| k2
== k_unsigned
)
1075 res
= (lval
.u
> rval
.u
) - (lval
.u
< rval
.u
);
1076 else /* if (k1 == k_signed && k2 == k_signed) */
1077 res
= (lval
.s
> rval
.s
) - (lval
.s
< rval
.s
);
1081 return res
? no
: yes
;
1083 return res
>= 0 ? yes
: no
;
1085 return res
> 0 ? yes
: no
;
1087 return res
<= 0 ? yes
: no
;
1089 return res
< 0 ? yes
: no
;
1091 return res
? yes
: no
;
1093 printf("expr_calc_value: relation %d?\n", e
->type
);
1098 static int expr_compare_type(enum expr_type t1
, enum expr_type t2
)
1107 if (t2
== E_EQUAL
|| t2
== E_UNEQUAL
)
1128 printf("[%dgt%d?]", t1
, t2
);
1132 void expr_print(struct expr
*e
,
1133 void (*fn
)(void *, struct symbol
*, const char *),
1134 void *data
, int prevtoken
)
1137 fn(data
, NULL
, "y");
1141 if (expr_compare_type(prevtoken
, e
->type
) > 0)
1142 fn(data
, NULL
, "(");
1145 if (e
->left
.sym
->name
)
1146 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1148 fn(data
, NULL
, "<choice>");
1151 fn(data
, NULL
, "!");
1152 expr_print(e
->left
.expr
, fn
, data
, E_NOT
);
1155 if (e
->left
.sym
->name
)
1156 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1158 fn(data
, NULL
, "<choice>");
1159 fn(data
, NULL
, "=");
1160 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1164 if (e
->left
.sym
->name
)
1165 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1167 fn(data
, NULL
, "<choice>");
1168 fn(data
, NULL
, e
->type
== E_LEQ
? "<=" : "<");
1169 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1173 if (e
->left
.sym
->name
)
1174 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1176 fn(data
, NULL
, "<choice>");
1177 fn(data
, NULL
, e
->type
== E_GEQ
? ">=" : ">");
1178 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1181 if (e
->left
.sym
->name
)
1182 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1184 fn(data
, NULL
, "<choice>");
1185 fn(data
, NULL
, "!=");
1186 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1189 expr_print(e
->left
.expr
, fn
, data
, E_OR
);
1190 fn(data
, NULL
, " || ");
1191 expr_print(e
->right
.expr
, fn
, data
, E_OR
);
1194 expr_print(e
->left
.expr
, fn
, data
, E_AND
);
1195 fn(data
, NULL
, " && ");
1196 expr_print(e
->right
.expr
, fn
, data
, E_AND
);
1199 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1201 fn(data
, NULL
, " ^ ");
1202 expr_print(e
->left
.expr
, fn
, data
, E_LIST
);
1206 fn(data
, NULL
, "[");
1207 fn(data
, e
->left
.sym
, e
->left
.sym
->name
);
1208 fn(data
, NULL
, " ");
1209 fn(data
, e
->right
.sym
, e
->right
.sym
->name
);
1210 fn(data
, NULL
, "]");
1215 sprintf(buf
, "<unknown type %d>", e
->type
);
1216 fn(data
, NULL
, buf
);
1220 if (expr_compare_type(prevtoken
, e
->type
) > 0)
1221 fn(data
, NULL
, ")");
1224 static void expr_print_file_helper(void *data
, struct symbol
*sym
, const char *str
)
1226 xfwrite(str
, strlen(str
), 1, data
);
1229 void expr_fprint(struct expr
*e
, FILE *out
)
1231 expr_print(e
, expr_print_file_helper
, out
, E_NONE
);
1234 static void expr_print_gstr_helper(void *data
, struct symbol
*sym
, const char *str
)
1236 struct gstr
*gs
= (struct gstr
*)data
;
1237 const char *sym_str
= NULL
;
1240 sym_str
= sym_get_string_value(sym
);
1242 if (gs
->max_width
) {
1243 unsigned extra_length
= strlen(str
);
1244 const char *last_cr
= strrchr(gs
->s
, '\n');
1245 unsigned last_line_length
;
1248 extra_length
+= 4 + strlen(sym_str
);
1253 last_line_length
= strlen(gs
->s
) - (last_cr
- gs
->s
);
1255 if ((last_line_length
+ extra_length
) > gs
->max_width
)
1256 str_append(gs
, "\\\n");
1259 str_append(gs
, str
);
1260 if (sym
&& sym
->type
!= S_UNKNOWN
)
1261 str_printf(gs
, " [=%s]", sym_str
);
1264 void expr_gstr_print(struct expr
*e
, struct gstr
*gs
)
1266 expr_print(e
, expr_print_gstr_helper
, gs
, E_NONE
);
1270 * Transform the top level "||" tokens into newlines and prepend each
1271 * line with a minus. This makes expressions much easier to read.
1272 * Suitable for reverse dependency expressions.
1274 static void expr_print_revdep(struct expr
*e
,
1275 void (*fn
)(void *, struct symbol
*, const char *),
1276 void *data
, tristate pr_type
, const char **title
)
1278 if (e
->type
== E_OR
) {
1279 expr_print_revdep(e
->left
.expr
, fn
, data
, pr_type
, title
);
1280 expr_print_revdep(e
->right
.expr
, fn
, data
, pr_type
, title
);
1281 } else if (expr_calc_value(e
) == pr_type
) {
1283 fn(data
, NULL
, *title
);
1287 fn(data
, NULL
, " - ");
1288 expr_print(e
, fn
, data
, E_NONE
);
1289 fn(data
, NULL
, "\n");
1293 void expr_gstr_print_revdep(struct expr
*e
, struct gstr
*gs
,
1294 tristate pr_type
, const char *title
)
1296 expr_print_revdep(e
, expr_print_gstr_helper
, gs
, pr_type
, &title
);