2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
14 static int expr_eq(struct expr *e1, struct expr *e2);
15 static struct expr *expr_eliminate_yn(struct expr *e);
16 static struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
17 static struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
18 static void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
20 struct expr *expr_alloc_symbol(struct symbol *sym)
22 struct expr *e = xcalloc(1, sizeof(*e));
28 struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
30 struct expr *e = xcalloc(1, sizeof(*e));
36 struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
38 struct expr *e = xcalloc(1, sizeof(*e));
45 struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
47 struct expr *e = xcalloc(1, sizeof(*e));
54 struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
58 return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
61 struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
65 return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
68 struct expr *expr_copy(const struct expr *org)
75 e = xmalloc(sizeof(*org));
76 memcpy(e, org, sizeof(*org));
82 e->left.expr = expr_copy(org->left.expr);
86 e->left.sym = org->left.sym;
87 e->right.sym = org->right.sym;
92 e->left.expr = expr_copy(org->left.expr);
93 e->right.expr = expr_copy(org->right.expr);
96 printf("can't copy type %d\n", e->type);
105 void expr_free(struct expr *e)
114 expr_free(e->left.expr);
121 expr_free(e->left.expr);
122 expr_free(e->right.expr);
125 printf("how to free type %d?\n", e->type);
131 static int trans_count;
136 static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
138 if (e1->type == type) {
139 __expr_eliminate_eq(type, &e1->left.expr, &e2);
140 __expr_eliminate_eq(type, &e1->right.expr, &e2);
143 if (e2->type == type) {
144 __expr_eliminate_eq(type, &e1, &e2->left.expr);
145 __expr_eliminate_eq(type, &e1, &e2->right.expr);
148 if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
149 e1->left.sym == e2->left.sym &&
150 (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
152 if (!expr_eq(e1, e2))
155 expr_free(e1); expr_free(e2);
158 e1 = expr_alloc_symbol(&symbol_no);
159 e2 = expr_alloc_symbol(&symbol_no);
162 e1 = expr_alloc_symbol(&symbol_yes);
163 e2 = expr_alloc_symbol(&symbol_yes);
170 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
177 __expr_eliminate_eq(e1->type, ep1, ep2);
181 if (e1->type != e2->type) switch (e2->type) {
184 __expr_eliminate_eq(e2->type, ep1, ep2);
188 e1 = expr_eliminate_yn(e1);
189 e2 = expr_eliminate_yn(e2);
195 static int expr_eq(struct expr *e1, struct expr *e2)
199 if (e1->type != e2->type)
204 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
206 return e1->left.sym == e2->left.sym;
208 return expr_eq(e1->left.expr, e2->left.expr);
213 old_count = trans_count;
214 expr_eliminate_eq(&e1, &e2);
215 res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
216 e1->left.sym == e2->left.sym);
219 trans_count = old_count;
228 expr_fprint(e1, stdout);
230 expr_fprint(e2, stdout);
237 static struct expr *expr_eliminate_yn(struct expr *e)
241 if (e) switch (e->type) {
243 e->left.expr = expr_eliminate_yn(e->left.expr);
244 e->right.expr = expr_eliminate_yn(e->right.expr);
245 if (e->left.expr->type == E_SYMBOL) {
246 if (e->left.expr->left.sym == &symbol_no) {
247 expr_free(e->left.expr);
248 expr_free(e->right.expr);
250 e->left.sym = &symbol_no;
251 e->right.expr = NULL;
253 } else if (e->left.expr->left.sym == &symbol_yes) {
256 *e = *(e->right.expr);
261 if (e->right.expr->type == E_SYMBOL) {
262 if (e->right.expr->left.sym == &symbol_no) {
263 expr_free(e->left.expr);
264 expr_free(e->right.expr);
266 e->left.sym = &symbol_no;
267 e->right.expr = NULL;
269 } else if (e->right.expr->left.sym == &symbol_yes) {
272 *e = *(e->left.expr);
279 e->left.expr = expr_eliminate_yn(e->left.expr);
280 e->right.expr = expr_eliminate_yn(e->right.expr);
281 if (e->left.expr->type == E_SYMBOL) {
282 if (e->left.expr->left.sym == &symbol_no) {
285 *e = *(e->right.expr);
288 } else if (e->left.expr->left.sym == &symbol_yes) {
289 expr_free(e->left.expr);
290 expr_free(e->right.expr);
292 e->left.sym = &symbol_yes;
293 e->right.expr = NULL;
297 if (e->right.expr->type == E_SYMBOL) {
298 if (e->right.expr->left.sym == &symbol_no) {
301 *e = *(e->left.expr);
304 } else if (e->right.expr->left.sym == &symbol_yes) {
305 expr_free(e->left.expr);
306 expr_free(e->right.expr);
308 e->left.sym = &symbol_yes;
309 e->right.expr = NULL;
323 struct expr *expr_trans_bool(struct expr *e)
331 e->left.expr = expr_trans_bool(e->left.expr);
332 e->right.expr = expr_trans_bool(e->right.expr);
336 if (e->left.sym->type == S_TRISTATE) {
337 if (e->right.sym == &symbol_no) {
352 static struct expr *expr_join_or(struct expr *e1, struct expr *e2)
355 struct symbol *sym1, *sym2;
358 return expr_copy(e1);
359 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
361 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
363 if (e1->type == E_NOT) {
365 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
367 sym1 = tmp->left.sym;
370 if (e2->type == E_NOT) {
371 if (e2->left.expr->type != E_SYMBOL)
373 sym2 = e2->left.expr->left.sym;
378 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
380 if (sym1->type == S_TRISTATE) {
381 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
382 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
383 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) {
384 // (a='y') || (a='m') -> (a!='n')
385 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no);
387 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
388 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
389 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) {
390 // (a='y') || (a='n') -> (a!='m')
391 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod);
393 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
394 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
395 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) {
396 // (a='m') || (a='n') -> (a!='y')
397 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes);
400 if (sym1->type == S_BOOLEAN && sym1 == sym2) {
401 if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) ||
402 (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL))
403 return expr_alloc_symbol(&symbol_yes);
407 printf("optimize (");
408 expr_fprint(e1, stdout);
410 expr_fprint(e2, stdout);
416 static struct expr *expr_join_and(struct expr *e1, struct expr *e2)
419 struct symbol *sym1, *sym2;
422 return expr_copy(e1);
423 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
425 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
427 if (e1->type == E_NOT) {
429 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
431 sym1 = tmp->left.sym;
434 if (e2->type == E_NOT) {
435 if (e2->left.expr->type != E_SYMBOL)
437 sym2 = e2->left.expr->left.sym;
442 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
445 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
446 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
447 // (a) && (a='y') -> (a='y')
448 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
450 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
451 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
452 // (a) && (a!='n') -> (a)
453 return expr_alloc_symbol(sym1);
455 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) ||
456 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod))
457 // (a) && (a!='m') -> (a='y')
458 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
460 if (sym1->type == S_TRISTATE) {
461 if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
462 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
463 sym2 = e1->right.sym;
464 if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
465 return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
466 : expr_alloc_symbol(&symbol_no);
468 if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
469 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
470 sym2 = e2->right.sym;
471 if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
472 return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
473 : expr_alloc_symbol(&symbol_no);
475 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
476 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
477 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
478 // (a!='y') && (a!='n') -> (a='m')
479 return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
481 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
482 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
483 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
484 // (a!='y') && (a!='m') -> (a='n')
485 return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
487 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
488 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
489 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
490 // (a!='m') && (a!='n') -> (a='m')
491 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
493 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
494 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
495 (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
496 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
501 printf("optimize (");
502 expr_fprint(e1, stdout);
504 expr_fprint(e2, stdout);
510 static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
516 if (e1->type == type) {
517 expr_eliminate_dups1(type, &e1->left.expr, &e2);
518 expr_eliminate_dups1(type, &e1->right.expr, &e2);
521 if (e2->type == type) {
522 expr_eliminate_dups1(type, &e1, &e2->left.expr);
523 expr_eliminate_dups1(type, &e1, &e2->right.expr);
530 case E_OR: case E_AND:
531 expr_eliminate_dups1(e1->type, &e1, &e1);
538 tmp = expr_join_or(e1, e2);
540 expr_free(e1); expr_free(e2);
541 e1 = expr_alloc_symbol(&symbol_no);
547 tmp = expr_join_and(e1, e2);
549 expr_free(e1); expr_free(e2);
550 e1 = expr_alloc_symbol(&symbol_yes);
562 static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2)
566 struct expr *tmp, *tmp1, *tmp2;
568 if (e1->type == type) {
569 expr_eliminate_dups2(type, &e1->left.expr, &e2);
570 expr_eliminate_dups2(type, &e1->right.expr, &e2);
573 if (e2->type == type) {
574 expr_eliminate_dups2(type, &e1, &e2->left.expr);
575 expr_eliminate_dups2(type, &e1, &e2->right.expr);
582 expr_eliminate_dups2(e1->type, &e1, &e1);
583 // (FOO || BAR) && (!FOO && !BAR) -> n
584 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
585 tmp2 = expr_copy(e2);
586 tmp = expr_extract_eq_and(&tmp1, &tmp2);
587 if (expr_is_yes(tmp1)) {
589 e1 = expr_alloc_symbol(&symbol_no);
597 expr_eliminate_dups2(e1->type, &e1, &e1);
598 // (FOO && BAR) || (!FOO || !BAR) -> y
599 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
600 tmp2 = expr_copy(e2);
601 tmp = expr_extract_eq_or(&tmp1, &tmp2);
602 if (expr_is_no(tmp1)) {
604 e1 = expr_alloc_symbol(&symbol_yes);
618 struct expr *expr_eliminate_dups(struct expr *e)
624 oldcount = trans_count;
628 case E_OR: case E_AND:
629 expr_eliminate_dups1(e->type, &e, &e);
630 expr_eliminate_dups2(e->type, &e, &e);
636 e = expr_eliminate_yn(e);
638 trans_count = oldcount;
642 struct expr *expr_transform(struct expr *e)
655 e->left.expr = expr_transform(e->left.expr);
656 e->right.expr = expr_transform(e->right.expr);
661 if (e->left.sym->type != S_BOOLEAN)
663 if (e->right.sym == &symbol_no) {
665 e->left.expr = expr_alloc_symbol(e->left.sym);
669 if (e->right.sym == &symbol_mod) {
670 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
672 e->left.sym = &symbol_no;
676 if (e->right.sym == &symbol_yes) {
683 if (e->left.sym->type != S_BOOLEAN)
685 if (e->right.sym == &symbol_no) {
690 if (e->right.sym == &symbol_mod) {
691 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
693 e->left.sym = &symbol_yes;
697 if (e->right.sym == &symbol_yes) {
699 e->left.expr = expr_alloc_symbol(e->left.sym);
705 switch (e->left.expr->type) {
708 tmp = e->left.expr->left.expr;
712 e = expr_transform(e);
720 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
723 // !(a || b) -> !a && !b
726 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
728 tmp->right.expr = NULL;
729 e = expr_transform(e);
732 // !(a && b) -> !a || !b
735 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
737 tmp->right.expr = NULL;
738 e = expr_transform(e);
741 if (e->left.expr->left.sym == &symbol_yes) {
747 e->left.sym = &symbol_no;
750 if (e->left.expr->left.sym == &symbol_mod) {
756 e->left.sym = &symbol_mod;
759 if (e->left.expr->left.sym == &symbol_no) {
765 e->left.sym = &symbol_yes;
779 int expr_contains_symbol(struct expr *dep, struct symbol *sym)
787 return expr_contains_symbol(dep->left.expr, sym) ||
788 expr_contains_symbol(dep->right.expr, sym);
790 return dep->left.sym == sym;
793 return dep->left.sym == sym ||
794 dep->right.sym == sym;
796 return expr_contains_symbol(dep->left.expr, sym);
803 bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
810 return expr_depends_symbol(dep->left.expr, sym) ||
811 expr_depends_symbol(dep->right.expr, sym);
813 return dep->left.sym == sym;
815 if (dep->left.sym == sym) {
816 if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
821 if (dep->left.sym == sym) {
822 if (dep->right.sym == &symbol_no)
832 static struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
834 struct expr *tmp = NULL;
835 expr_extract_eq(E_AND, &tmp, ep1, ep2);
837 *ep1 = expr_eliminate_yn(*ep1);
838 *ep2 = expr_eliminate_yn(*ep2);
843 static struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
845 struct expr *tmp = NULL;
846 expr_extract_eq(E_OR, &tmp, ep1, ep2);
848 *ep1 = expr_eliminate_yn(*ep1);
849 *ep2 = expr_eliminate_yn(*ep2);
854 static void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
858 if (e1->type == type) {
859 expr_extract_eq(type, ep, &e1->left.expr, &e2);
860 expr_extract_eq(type, ep, &e1->right.expr, &e2);
863 if (e2->type == type) {
864 expr_extract_eq(type, ep, ep1, &e2->left.expr);
865 expr_extract_eq(type, ep, ep1, &e2->right.expr);
868 if (expr_eq(e1, e2)) {
869 *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
872 e1 = expr_alloc_symbol(&symbol_yes);
873 e2 = expr_alloc_symbol(&symbol_yes);
874 } else if (type == E_OR) {
875 e1 = expr_alloc_symbol(&symbol_no);
876 e2 = expr_alloc_symbol(&symbol_no);
883 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
885 struct expr *e1, *e2;
888 e = expr_alloc_symbol(sym);
889 if (type == E_UNEQUAL)
890 e = expr_alloc_one(E_NOT, e);
895 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
896 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
897 if (sym == &symbol_yes)
898 e = expr_alloc_two(E_AND, e1, e2);
899 if (sym == &symbol_no)
900 e = expr_alloc_two(E_OR, e1, e2);
901 if (type == E_UNEQUAL)
902 e = expr_alloc_one(E_NOT, e);
905 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
906 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
907 if (sym == &symbol_yes)
908 e = expr_alloc_two(E_OR, e1, e2);
909 if (sym == &symbol_no)
910 e = expr_alloc_two(E_AND, e1, e2);
911 if (type == E_UNEQUAL)
912 e = expr_alloc_one(E_NOT, e);
915 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
918 if (type == E_EQUAL) {
919 if (sym == &symbol_yes)
921 if (sym == &symbol_mod)
922 return expr_alloc_symbol(&symbol_no);
923 if (sym == &symbol_no)
924 return expr_alloc_one(E_NOT, expr_copy(e));
926 if (sym == &symbol_yes)
927 return expr_alloc_one(E_NOT, expr_copy(e));
928 if (sym == &symbol_mod)
929 return expr_alloc_symbol(&symbol_yes);
930 if (sym == &symbol_no)
935 return expr_alloc_comp(type, e->left.sym, sym);
944 tristate expr_calc_value(struct expr *e)
947 const char *str1, *str2;
954 sym_calc_value(e->left.sym);
955 return e->left.sym->curr.tri;
957 val1 = expr_calc_value(e->left.expr);
958 val2 = expr_calc_value(e->right.expr);
959 return EXPR_AND(val1, val2);
961 val1 = expr_calc_value(e->left.expr);
962 val2 = expr_calc_value(e->right.expr);
963 return EXPR_OR(val1, val2);
965 val1 = expr_calc_value(e->left.expr);
966 return EXPR_NOT(val1);
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) ? yes : no;
974 sym_calc_value(e->left.sym);
975 sym_calc_value(e->right.sym);
976 str1 = sym_get_string_value(e->left.sym);
977 str2 = sym_get_string_value(e->right.sym);
978 return !strcmp(str1, str2) ? no : yes;
980 printf("expr_calc_value: %d?\n", e->type);
985 static int expr_compare_type(enum expr_type t1, enum expr_type t2)
1009 printf("[%dgt%d?]", t1, t2);
1013 static inline struct expr *
1014 expr_get_leftmost_symbol(const struct expr *e)
1020 while (e->type != E_SYMBOL)
1023 return expr_copy(e);
1027 * Given expression `e1' and `e2', returns the leaf of the longest
1028 * sub-expression of `e1' not containing 'e2.
1030 struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
1036 return expr_alloc_and(
1037 expr_simplify_unmet_dep(e1->left.expr, e2),
1038 expr_simplify_unmet_dep(e1->right.expr, e2));
1041 e = expr_alloc_and(expr_copy(e1), expr_copy(e2));
1042 e = expr_eliminate_dups(e);
1043 ret = (!expr_eq(e, e1)) ? e1 : NULL;
1052 return expr_get_leftmost_symbol(ret);
1055 void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
1058 fn(data, NULL, "y");
1062 if (expr_compare_type(prevtoken, e->type) > 0)
1063 fn(data, NULL, "(");
1066 if (e->left.sym->name)
1067 fn(data, e->left.sym, e->left.sym->name);
1069 fn(data, NULL, "<choice>");
1072 fn(data, NULL, "!");
1073 expr_print(e->left.expr, fn, data, E_NOT);
1076 if (e->left.sym->name)
1077 fn(data, e->left.sym, e->left.sym->name);
1079 fn(data, NULL, "<choice>");
1080 fn(data, NULL, "=");
1081 fn(data, e->right.sym, e->right.sym->name);
1084 if (e->left.sym->name)
1085 fn(data, e->left.sym, e->left.sym->name);
1087 fn(data, NULL, "<choice>");
1088 fn(data, NULL, "!=");
1089 fn(data, e->right.sym, e->right.sym->name);
1092 expr_print(e->left.expr, fn, data, E_OR);
1093 fn(data, NULL, " || ");
1094 expr_print(e->right.expr, fn, data, E_OR);
1097 expr_print(e->left.expr, fn, data, E_AND);
1098 fn(data, NULL, " && ");
1099 expr_print(e->right.expr, fn, data, E_AND);
1102 fn(data, e->right.sym, e->right.sym->name);
1104 fn(data, NULL, " ^ ");
1105 expr_print(e->left.expr, fn, data, E_LIST);
1109 fn(data, NULL, "[");
1110 fn(data, e->left.sym, e->left.sym->name);
1111 fn(data, NULL, " ");
1112 fn(data, e->right.sym, e->right.sym->name);
1113 fn(data, NULL, "]");
1118 sprintf(buf, "<unknown type %d>", e->type);
1119 fn(data, NULL, buf);
1123 if (expr_compare_type(prevtoken, e->type) > 0)
1124 fn(data, NULL, ")");
1127 static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
1129 xfwrite(str, strlen(str), 1, data);
1132 void expr_fprint(struct expr *e, FILE *out)
1134 expr_print(e, expr_print_file_helper, out, E_NONE);
1137 static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
1139 struct gstr *gs = (struct gstr*)data;
1140 const char *sym_str = NULL;
1143 sym_str = sym_get_string_value(sym);
1145 if (gs->max_width) {
1146 unsigned extra_length = strlen(str);
1147 const char *last_cr = strrchr(gs->s, '\n');
1148 unsigned last_line_length;
1151 extra_length += 4 + strlen(sym_str);
1156 last_line_length = strlen(gs->s) - (last_cr - gs->s);
1158 if ((last_line_length + extra_length) > gs->max_width)
1159 str_append(gs, "\\\n");
1162 str_append(gs, str);
1163 if (sym && sym->type != S_UNKNOWN)
1164 str_printf(gs, " [=%s]", sym_str);
1167 void expr_gstr_print(struct expr *e, struct gstr *gs)
1169 expr_print(e, expr_print_gstr_helper, gs, E_NONE);