2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
14 struct expr *expr_alloc_symbol(struct symbol *sym)
16 struct expr *e = calloc(1, sizeof(*e));
22 struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
24 struct expr *e = calloc(1, sizeof(*e));
30 struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
32 struct expr *e = calloc(1, sizeof(*e));
39 struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
41 struct expr *e = calloc(1, sizeof(*e));
48 struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
52 return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
55 struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
59 return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
62 struct expr *expr_copy(const struct expr *org)
69 e = malloc(sizeof(*org));
70 memcpy(e, org, sizeof(*org));
76 e->left.expr = expr_copy(org->left.expr);
80 e->left.sym = org->left.sym;
81 e->right.sym = org->right.sym;
86 e->left.expr = expr_copy(org->left.expr);
87 e->right.expr = expr_copy(org->right.expr);
90 printf("can't copy type %d\n", e->type);
99 void expr_free(struct expr *e)
108 expr_free(e->left.expr);
115 expr_free(e->left.expr);
116 expr_free(e->right.expr);
119 printf("how to free type %d?\n", e->type);
125 static int trans_count;
130 static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
132 if (e1->type == type) {
133 __expr_eliminate_eq(type, &e1->left.expr, &e2);
134 __expr_eliminate_eq(type, &e1->right.expr, &e2);
137 if (e2->type == type) {
138 __expr_eliminate_eq(type, &e1, &e2->left.expr);
139 __expr_eliminate_eq(type, &e1, &e2->right.expr);
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))
146 if (!expr_eq(e1, e2))
149 expr_free(e1); expr_free(e2);
152 e1 = expr_alloc_symbol(&symbol_no);
153 e2 = expr_alloc_symbol(&symbol_no);
156 e1 = expr_alloc_symbol(&symbol_yes);
157 e2 = expr_alloc_symbol(&symbol_yes);
164 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
171 __expr_eliminate_eq(e1->type, ep1, ep2);
175 if (e1->type != e2->type) switch (e2->type) {
178 __expr_eliminate_eq(e2->type, ep1, ep2);
182 e1 = expr_eliminate_yn(e1);
183 e2 = expr_eliminate_yn(e2);
189 int expr_eq(struct expr *e1, struct expr *e2)
193 if (e1->type != e2->type)
198 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
200 return e1->left.sym == e2->left.sym;
202 return expr_eq(e1->left.expr, e2->left.expr);
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);
213 trans_count = old_count;
222 expr_fprint(e1, stdout);
224 expr_fprint(e2, stdout);
231 struct expr *expr_eliminate_yn(struct expr *e)
235 if (e) switch (e->type) {
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);
244 e->left.sym = &symbol_no;
245 e->right.expr = NULL;
247 } else if (e->left.expr->left.sym == &symbol_yes) {
250 *e = *(e->right.expr);
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);
260 e->left.sym = &symbol_no;
261 e->right.expr = NULL;
263 } else if (e->right.expr->left.sym == &symbol_yes) {
266 *e = *(e->left.expr);
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) {
279 *e = *(e->right.expr);
282 } else if (e->left.expr->left.sym == &symbol_yes) {
283 expr_free(e->left.expr);
284 expr_free(e->right.expr);
286 e->left.sym = &symbol_yes;
287 e->right.expr = NULL;
291 if (e->right.expr->type == E_SYMBOL) {
292 if (e->right.expr->left.sym == &symbol_no) {
295 *e = *(e->left.expr);
298 } else if (e->right.expr->left.sym == &symbol_yes) {
299 expr_free(e->left.expr);
300 expr_free(e->right.expr);
302 e->left.sym = &symbol_yes;
303 e->right.expr = NULL;
317 struct expr *expr_trans_bool(struct expr *e)
325 e->left.expr = expr_trans_bool(e->left.expr);
326 e->right.expr = expr_trans_bool(e->right.expr);
330 if (e->left.sym->type == S_TRISTATE) {
331 if (e->right.sym == &symbol_no) {
346 static struct expr *expr_join_or(struct expr *e1, struct expr *e2)
349 struct symbol *sym1, *sym2;
352 return expr_copy(e1);
353 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
355 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
357 if (e1->type == E_NOT) {
359 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
361 sym1 = tmp->left.sym;
364 if (e2->type == E_NOT) {
365 if (e2->left.expr->type != E_SYMBOL)
367 sym2 = e2->left.expr->left.sym;
372 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
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);
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);
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);
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);
401 printf("optimize (");
402 expr_fprint(e1, stdout);
404 expr_fprint(e2, stdout);
410 static struct expr *expr_join_and(struct expr *e1, struct expr *e2)
413 struct symbol *sym1, *sym2;
416 return expr_copy(e1);
417 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
419 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
421 if (e1->type == E_NOT) {
423 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
425 sym1 = tmp->left.sym;
428 if (e2->type == E_NOT) {
429 if (e2->left.expr->type != E_SYMBOL)
431 sym2 = e2->left.expr->left.sym;
436 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
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);
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);
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);
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);
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);
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);
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);
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);
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))
495 printf("optimize (");
496 expr_fprint(e1, stdout);
498 expr_fprint(e2, stdout);
504 static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
510 if (e1->type == type) {
511 expr_eliminate_dups1(type, &e1->left.expr, &e2);
512 expr_eliminate_dups1(type, &e1->right.expr, &e2);
515 if (e2->type == type) {
516 expr_eliminate_dups1(type, &e1, &e2->left.expr);
517 expr_eliminate_dups1(type, &e1, &e2->right.expr);
524 case E_OR: case E_AND:
525 expr_eliminate_dups1(e1->type, &e1, &e1);
532 tmp = expr_join_or(e1, e2);
534 expr_free(e1); expr_free(e2);
535 e1 = expr_alloc_symbol(&symbol_no);
541 tmp = expr_join_and(e1, e2);
543 expr_free(e1); expr_free(e2);
544 e1 = expr_alloc_symbol(&symbol_yes);
556 static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2)
560 struct expr *tmp, *tmp1, *tmp2;
562 if (e1->type == type) {
563 expr_eliminate_dups2(type, &e1->left.expr, &e2);
564 expr_eliminate_dups2(type, &e1->right.expr, &e2);
567 if (e2->type == type) {
568 expr_eliminate_dups2(type, &e1, &e2->left.expr);
569 expr_eliminate_dups2(type, &e1, &e2->right.expr);
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)) {
583 e1 = expr_alloc_symbol(&symbol_no);
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)) {
598 e1 = expr_alloc_symbol(&symbol_yes);
612 struct expr *expr_eliminate_dups(struct expr *e)
618 oldcount = trans_count;
622 case E_OR: case E_AND:
623 expr_eliminate_dups1(e->type, &e, &e);
624 expr_eliminate_dups2(e->type, &e, &e);
630 e = expr_eliminate_yn(e);
632 trans_count = oldcount;
636 struct expr *expr_transform(struct expr *e)
649 e->left.expr = expr_transform(e->left.expr);
650 e->right.expr = expr_transform(e->right.expr);
655 if (e->left.sym->type != S_BOOLEAN)
657 if (e->right.sym == &symbol_no) {
659 e->left.expr = expr_alloc_symbol(e->left.sym);
663 if (e->right.sym == &symbol_mod) {
664 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
666 e->left.sym = &symbol_no;
670 if (e->right.sym == &symbol_yes) {
677 if (e->left.sym->type != S_BOOLEAN)
679 if (e->right.sym == &symbol_no) {
684 if (e->right.sym == &symbol_mod) {
685 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
687 e->left.sym = &symbol_yes;
691 if (e->right.sym == &symbol_yes) {
693 e->left.expr = expr_alloc_symbol(e->left.sym);
699 switch (e->left.expr->type) {
702 tmp = e->left.expr->left.expr;
706 e = expr_transform(e);
714 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
717 // !(a || b) -> !a && !b
720 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
722 tmp->right.expr = NULL;
723 e = expr_transform(e);
726 // !(a && b) -> !a || !b
729 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
731 tmp->right.expr = NULL;
732 e = expr_transform(e);
735 if (e->left.expr->left.sym == &symbol_yes) {
741 e->left.sym = &symbol_no;
744 if (e->left.expr->left.sym == &symbol_mod) {
750 e->left.sym = &symbol_mod;
753 if (e->left.expr->left.sym == &symbol_no) {
759 e->left.sym = &symbol_yes;
773 int expr_contains_symbol(struct expr *dep, struct symbol *sym)
781 return expr_contains_symbol(dep->left.expr, sym) ||
782 expr_contains_symbol(dep->right.expr, sym);
784 return dep->left.sym == sym;
787 return dep->left.sym == sym ||
788 dep->right.sym == sym;
790 return expr_contains_symbol(dep->left.expr, sym);
797 bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
804 return expr_depends_symbol(dep->left.expr, sym) ||
805 expr_depends_symbol(dep->right.expr, sym);
807 return dep->left.sym == sym;
809 if (dep->left.sym == sym) {
810 if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
815 if (dep->left.sym == sym) {
816 if (dep->right.sym == &symbol_no)
826 struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
828 struct expr *tmp = NULL;
829 expr_extract_eq(E_AND, &tmp, ep1, ep2);
831 *ep1 = expr_eliminate_yn(*ep1);
832 *ep2 = expr_eliminate_yn(*ep2);
837 struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
839 struct expr *tmp = NULL;
840 expr_extract_eq(E_OR, &tmp, ep1, ep2);
842 *ep1 = expr_eliminate_yn(*ep1);
843 *ep2 = expr_eliminate_yn(*ep2);
848 void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **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);
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);
862 if (expr_eq(e1, e2)) {
863 *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
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);
877 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
879 struct expr *e1, *e2;
882 e = expr_alloc_symbol(sym);
883 if (type == E_UNEQUAL)
884 e = expr_alloc_one(E_NOT, e);
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);
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);
909 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
912 if (type == E_EQUAL) {
913 if (sym == &symbol_yes)
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));
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)
929 return expr_alloc_comp(type, e->left.sym, sym);
938 tristate expr_calc_value(struct expr *e)
941 const char *str1, *str2;
948 sym_calc_value(e->left.sym);
949 return e->left.sym->curr.tri;
951 val1 = expr_calc_value(e->left.expr);
952 val2 = expr_calc_value(e->right.expr);
953 return EXPR_AND(val1, val2);
955 val1 = expr_calc_value(e->left.expr);
956 val2 = expr_calc_value(e->right.expr);
957 return EXPR_OR(val1, val2);
959 val1 = expr_calc_value(e->left.expr);
960 return EXPR_NOT(val1);
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;
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;
974 printf("expr_calc_value: %d?\n", e->type);
979 int expr_compare_type(enum expr_type t1, enum expr_type t2)
1006 printf("[%dgt%d?]", t1, t2);
1011 static inline struct expr *
1012 expr_get_leftmost_symbol(const struct expr *e)
1018 while (e->type != E_SYMBOL)
1021 return expr_copy(e);
1025 * Given expression `e1' and `e2', returns the leaf of the longest
1026 * sub-expression of `e1' not containing 'e2.
1028 struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
1034 return expr_alloc_and(
1035 expr_simplify_unmet_dep(e1->left.expr, e2),
1036 expr_simplify_unmet_dep(e1->right.expr, e2));
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;
1050 return expr_get_leftmost_symbol(ret);
1053 void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
1056 fn(data, NULL, "y");
1060 if (expr_compare_type(prevtoken, e->type) > 0)
1061 fn(data, NULL, "(");
1064 if (e->left.sym->name)
1065 fn(data, e->left.sym, e->left.sym->name);
1067 fn(data, NULL, "<choice>");
1070 fn(data, NULL, "!");
1071 expr_print(e->left.expr, fn, data, E_NOT);
1074 if (e->left.sym->name)
1075 fn(data, e->left.sym, e->left.sym->name);
1077 fn(data, NULL, "<choice>");
1078 fn(data, NULL, "=");
1079 fn(data, e->right.sym, e->right.sym->name);
1082 if (e->left.sym->name)
1083 fn(data, e->left.sym, e->left.sym->name);
1085 fn(data, NULL, "<choice>");
1086 fn(data, NULL, "!=");
1087 fn(data, e->right.sym, e->right.sym->name);
1090 expr_print(e->left.expr, fn, data, E_OR);
1091 fn(data, NULL, " || ");
1092 expr_print(e->right.expr, fn, data, E_OR);
1095 expr_print(e->left.expr, fn, data, E_AND);
1096 fn(data, NULL, " && ");
1097 expr_print(e->right.expr, fn, data, E_AND);
1100 fn(data, e->right.sym, e->right.sym->name);
1102 fn(data, NULL, " ^ ");
1103 expr_print(e->left.expr, fn, data, E_LIST);
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, "]");
1116 sprintf(buf, "<unknown type %d>", e->type);
1117 fn(data, NULL, buf);
1121 if (expr_compare_type(prevtoken, e->type) > 0)
1122 fn(data, NULL, ")");
1125 static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
1127 xfwrite(str, strlen(str), 1, data);
1130 void expr_fprint(struct expr *e, FILE *out)
1132 expr_print(e, expr_print_file_helper, out, E_NONE);
1135 static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
1137 struct gstr *gs = (struct gstr*)data;
1138 const char *sym_str = NULL;
1141 sym_str = sym_get_string_value(sym);
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;
1149 extra_length += 4 + strlen(sym_str);
1154 last_line_length = strlen(gs->s) - (last_cr - gs->s);
1156 if ((last_line_length + extra_length) > gs->max_width)
1157 str_append(gs, "\\\n");
1160 str_append(gs, str);
1161 if (sym && sym->type != S_UNKNOWN)
1162 str_printf(gs, " [=%s]", sym_str);
1165 void expr_gstr_print(struct expr *e, struct gstr *gs)
1167 expr_print(e, expr_print_gstr_helper, gs, E_NONE);