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);
17 struct expr *expr_alloc_symbol(struct symbol *sym)
19 struct expr *e = xcalloc(1, sizeof(*e));
25 struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
27 struct expr *e = xcalloc(1, sizeof(*e));
33 struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
35 struct expr *e = xcalloc(1, sizeof(*e));
42 struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
44 struct expr *e = xcalloc(1, sizeof(*e));
51 struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
55 return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
58 struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
62 return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
65 struct expr *expr_copy(const struct expr *org)
72 e = xmalloc(sizeof(*org));
73 memcpy(e, org, sizeof(*org));
79 e->left.expr = expr_copy(org->left.expr);
87 e->left.sym = org->left.sym;
88 e->right.sym = org->right.sym;
93 e->left.expr = expr_copy(org->left.expr);
94 e->right.expr = expr_copy(org->right.expr);
97 printf("can't copy type %d\n", e->type);
106 void expr_free(struct expr *e)
115 expr_free(e->left.expr);
126 expr_free(e->left.expr);
127 expr_free(e->right.expr);
130 printf("how to free type %d?\n", e->type);
136 static int trans_count;
141 static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
143 if (e1->type == type) {
144 __expr_eliminate_eq(type, &e1->left.expr, &e2);
145 __expr_eliminate_eq(type, &e1->right.expr, &e2);
148 if (e2->type == type) {
149 __expr_eliminate_eq(type, &e1, &e2->left.expr);
150 __expr_eliminate_eq(type, &e1, &e2->right.expr);
153 if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
154 e1->left.sym == e2->left.sym &&
155 (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
157 if (!expr_eq(e1, e2))
160 expr_free(e1); expr_free(e2);
163 e1 = expr_alloc_symbol(&symbol_no);
164 e2 = expr_alloc_symbol(&symbol_no);
167 e1 = expr_alloc_symbol(&symbol_yes);
168 e2 = expr_alloc_symbol(&symbol_yes);
175 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
182 __expr_eliminate_eq(e1->type, ep1, ep2);
186 if (e1->type != e2->type) switch (e2->type) {
189 __expr_eliminate_eq(e2->type, ep1, ep2);
193 e1 = expr_eliminate_yn(e1);
194 e2 = expr_eliminate_yn(e2);
200 static int expr_eq(struct expr *e1, struct expr *e2)
205 * A NULL expr is taken to be yes, but there's also a different way to
206 * represent yes. expr_is_yes() checks for either representation.
209 return expr_is_yes(e1) && expr_is_yes(e2);
211 if (e1->type != e2->type)
220 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
222 return e1->left.sym == e2->left.sym;
224 return expr_eq(e1->left.expr, e2->left.expr);
229 old_count = trans_count;
230 expr_eliminate_eq(&e1, &e2);
231 res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
232 e1->left.sym == e2->left.sym);
235 trans_count = old_count;
244 expr_fprint(e1, stdout);
246 expr_fprint(e2, stdout);
253 static struct expr *expr_eliminate_yn(struct expr *e)
257 if (e) switch (e->type) {
259 e->left.expr = expr_eliminate_yn(e->left.expr);
260 e->right.expr = expr_eliminate_yn(e->right.expr);
261 if (e->left.expr->type == E_SYMBOL) {
262 if (e->left.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->left.expr->left.sym == &symbol_yes) {
272 *e = *(e->right.expr);
277 if (e->right.expr->type == E_SYMBOL) {
278 if (e->right.expr->left.sym == &symbol_no) {
279 expr_free(e->left.expr);
280 expr_free(e->right.expr);
282 e->left.sym = &symbol_no;
283 e->right.expr = NULL;
285 } else if (e->right.expr->left.sym == &symbol_yes) {
288 *e = *(e->left.expr);
295 e->left.expr = expr_eliminate_yn(e->left.expr);
296 e->right.expr = expr_eliminate_yn(e->right.expr);
297 if (e->left.expr->type == E_SYMBOL) {
298 if (e->left.expr->left.sym == &symbol_no) {
301 *e = *(e->right.expr);
304 } else if (e->left.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;
313 if (e->right.expr->type == E_SYMBOL) {
314 if (e->right.expr->left.sym == &symbol_no) {
317 *e = *(e->left.expr);
320 } else if (e->right.expr->left.sym == &symbol_yes) {
321 expr_free(e->left.expr);
322 expr_free(e->right.expr);
324 e->left.sym = &symbol_yes;
325 e->right.expr = NULL;
339 struct expr *expr_trans_bool(struct expr *e)
347 e->left.expr = expr_trans_bool(e->left.expr);
348 e->right.expr = expr_trans_bool(e->right.expr);
352 if (e->left.sym->type == S_TRISTATE) {
353 if (e->right.sym == &symbol_no) {
368 static struct expr *expr_join_or(struct expr *e1, struct expr *e2)
371 struct symbol *sym1, *sym2;
374 return expr_copy(e1);
375 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
377 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
379 if (e1->type == E_NOT) {
381 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
383 sym1 = tmp->left.sym;
386 if (e2->type == E_NOT) {
387 if (e2->left.expr->type != E_SYMBOL)
389 sym2 = e2->left.expr->left.sym;
394 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
396 if (sym1->type == S_TRISTATE) {
397 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
398 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
399 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) {
400 // (a='y') || (a='m') -> (a!='n')
401 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no);
403 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
404 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
405 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) {
406 // (a='y') || (a='n') -> (a!='m')
407 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod);
409 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
410 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
411 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) {
412 // (a='m') || (a='n') -> (a!='y')
413 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes);
416 if (sym1->type == S_BOOLEAN && sym1 == sym2) {
417 if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) ||
418 (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL))
419 return expr_alloc_symbol(&symbol_yes);
423 printf("optimize (");
424 expr_fprint(e1, stdout);
426 expr_fprint(e2, stdout);
432 static struct expr *expr_join_and(struct expr *e1, struct expr *e2)
435 struct symbol *sym1, *sym2;
438 return expr_copy(e1);
439 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
441 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
443 if (e1->type == E_NOT) {
445 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
447 sym1 = tmp->left.sym;
450 if (e2->type == E_NOT) {
451 if (e2->left.expr->type != E_SYMBOL)
453 sym2 = e2->left.expr->left.sym;
458 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
461 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
462 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
463 // (a) && (a='y') -> (a='y')
464 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
466 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
467 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
468 // (a) && (a!='n') -> (a)
469 return expr_alloc_symbol(sym1);
471 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) ||
472 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod))
473 // (a) && (a!='m') -> (a='y')
474 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
476 if (sym1->type == S_TRISTATE) {
477 if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
478 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
479 sym2 = e1->right.sym;
480 if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
481 return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
482 : expr_alloc_symbol(&symbol_no);
484 if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
485 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
486 sym2 = e2->right.sym;
487 if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
488 return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
489 : expr_alloc_symbol(&symbol_no);
491 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
492 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
493 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
494 // (a!='y') && (a!='n') -> (a='m')
495 return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
497 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
498 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
499 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
500 // (a!='y') && (a!='m') -> (a='n')
501 return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
503 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
504 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
505 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
506 // (a!='m') && (a!='n') -> (a='m')
507 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
509 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
510 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
511 (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
512 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
517 printf("optimize (");
518 expr_fprint(e1, stdout);
520 expr_fprint(e2, stdout);
526 static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
532 if (e1->type == type) {
533 expr_eliminate_dups1(type, &e1->left.expr, &e2);
534 expr_eliminate_dups1(type, &e1->right.expr, &e2);
537 if (e2->type == type) {
538 expr_eliminate_dups1(type, &e1, &e2->left.expr);
539 expr_eliminate_dups1(type, &e1, &e2->right.expr);
546 case E_OR: case E_AND:
547 expr_eliminate_dups1(e1->type, &e1, &e1);
554 tmp = expr_join_or(e1, e2);
556 expr_free(e1); expr_free(e2);
557 e1 = expr_alloc_symbol(&symbol_no);
563 tmp = expr_join_and(e1, e2);
565 expr_free(e1); expr_free(e2);
566 e1 = expr_alloc_symbol(&symbol_yes);
578 struct expr *expr_eliminate_dups(struct expr *e)
584 oldcount = trans_count;
588 case E_OR: case E_AND:
589 expr_eliminate_dups1(e->type, &e, &e);
595 e = expr_eliminate_yn(e);
597 trans_count = oldcount;
601 struct expr *expr_transform(struct expr *e)
618 e->left.expr = expr_transform(e->left.expr);
619 e->right.expr = expr_transform(e->right.expr);
624 if (e->left.sym->type != S_BOOLEAN)
626 if (e->right.sym == &symbol_no) {
628 e->left.expr = expr_alloc_symbol(e->left.sym);
632 if (e->right.sym == &symbol_mod) {
633 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
635 e->left.sym = &symbol_no;
639 if (e->right.sym == &symbol_yes) {
646 if (e->left.sym->type != S_BOOLEAN)
648 if (e->right.sym == &symbol_no) {
653 if (e->right.sym == &symbol_mod) {
654 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
656 e->left.sym = &symbol_yes;
660 if (e->right.sym == &symbol_yes) {
662 e->left.expr = expr_alloc_symbol(e->left.sym);
668 switch (e->left.expr->type) {
671 tmp = e->left.expr->left.expr;
675 e = expr_transform(e);
683 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
691 e->type = e->type == E_LEQ ? E_GTH : E_LTH;
699 e->type = e->type == E_LTH ? E_GEQ : E_LEQ;
702 // !(a || b) -> !a && !b
705 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
707 tmp->right.expr = NULL;
708 e = expr_transform(e);
711 // !(a && b) -> !a || !b
714 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
716 tmp->right.expr = NULL;
717 e = expr_transform(e);
720 if (e->left.expr->left.sym == &symbol_yes) {
726 e->left.sym = &symbol_no;
729 if (e->left.expr->left.sym == &symbol_mod) {
735 e->left.sym = &symbol_mod;
738 if (e->left.expr->left.sym == &symbol_no) {
744 e->left.sym = &symbol_yes;
758 int expr_contains_symbol(struct expr *dep, struct symbol *sym)
766 return expr_contains_symbol(dep->left.expr, sym) ||
767 expr_contains_symbol(dep->right.expr, sym);
769 return dep->left.sym == sym;
776 return dep->left.sym == sym ||
777 dep->right.sym == sym;
779 return expr_contains_symbol(dep->left.expr, sym);
786 bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
793 return expr_depends_symbol(dep->left.expr, sym) ||
794 expr_depends_symbol(dep->right.expr, sym);
796 return dep->left.sym == sym;
798 if (dep->left.sym == sym) {
799 if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
804 if (dep->left.sym == sym) {
805 if (dep->right.sym == &symbol_no)
815 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
817 struct expr *e1, *e2;
820 e = expr_alloc_symbol(sym);
821 if (type == E_UNEQUAL)
822 e = expr_alloc_one(E_NOT, e);
827 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
828 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
829 if (sym == &symbol_yes)
830 e = expr_alloc_two(E_AND, e1, e2);
831 if (sym == &symbol_no)
832 e = expr_alloc_two(E_OR, e1, e2);
833 if (type == E_UNEQUAL)
834 e = expr_alloc_one(E_NOT, e);
837 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
838 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
839 if (sym == &symbol_yes)
840 e = expr_alloc_two(E_OR, e1, e2);
841 if (sym == &symbol_no)
842 e = expr_alloc_two(E_AND, e1, e2);
843 if (type == E_UNEQUAL)
844 e = expr_alloc_one(E_NOT, e);
847 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
854 if (type == E_EQUAL) {
855 if (sym == &symbol_yes)
857 if (sym == &symbol_mod)
858 return expr_alloc_symbol(&symbol_no);
859 if (sym == &symbol_no)
860 return expr_alloc_one(E_NOT, expr_copy(e));
862 if (sym == &symbol_yes)
863 return expr_alloc_one(E_NOT, expr_copy(e));
864 if (sym == &symbol_mod)
865 return expr_alloc_symbol(&symbol_yes);
866 if (sym == &symbol_no)
871 return expr_alloc_comp(type, e->left.sym, sym);
880 enum string_value_kind {
888 unsigned long long u;
892 static enum string_value_kind expr_parse_string(const char *str,
893 enum symbol_type type,
894 union string_value *val)
897 enum string_value_kind kind;
905 val->s = strtoll(str, &tail, 10);
909 val->u = strtoull(str, &tail, 16);
914 val->s = strtoll(str, &tail, 0);
920 return !errno && !*tail && tail > str && isxdigit(tail[-1])
924 tristate expr_calc_value(struct expr *e)
927 const char *str1, *str2;
928 enum string_value_kind k1 = k_string, k2 = k_string;
929 union string_value lval = {}, rval = {};
937 sym_calc_value(e->left.sym);
938 return e->left.sym->curr.tri;
940 val1 = expr_calc_value(e->left.expr);
941 val2 = expr_calc_value(e->right.expr);
942 return EXPR_AND(val1, val2);
944 val1 = expr_calc_value(e->left.expr);
945 val2 = expr_calc_value(e->right.expr);
946 return EXPR_OR(val1, val2);
948 val1 = expr_calc_value(e->left.expr);
949 return EXPR_NOT(val1);
958 printf("expr_calc_value: %d?\n", e->type);
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);
967 if (e->left.sym->type != S_STRING || e->right.sym->type != S_STRING) {
968 k1 = expr_parse_string(str1, e->left.sym->type, &lval);
969 k2 = expr_parse_string(str2, e->right.sym->type, &rval);
972 if (k1 == k_string || k2 == k_string)
973 res = strcmp(str1, str2);
974 else if (k1 == k_invalid || k2 == k_invalid) {
975 if (e->type != E_EQUAL && e->type != E_UNEQUAL) {
976 printf("Cannot compare \"%s\" and \"%s\"\n", str1, str2);
979 res = strcmp(str1, str2);
980 } else if (k1 == k_unsigned || k2 == k_unsigned)
981 res = (lval.u > rval.u) - (lval.u < rval.u);
982 else /* if (k1 == k_signed && k2 == k_signed) */
983 res = (lval.s > rval.s) - (lval.s < rval.s);
987 return res ? no : yes;
989 return res >= 0 ? yes : no;
991 return res > 0 ? yes : no;
993 return res <= 0 ? yes : no;
995 return res < 0 ? yes : no;
997 return res ? yes : no;
999 printf("expr_calc_value: relation %d?\n", e->type);
1004 static int expr_compare_type(enum expr_type t1, enum expr_type t2)
1013 if (t2 == E_EQUAL || t2 == E_UNEQUAL)
1034 printf("[%dgt%d?]", t1, t2);
1038 static inline struct expr *
1039 expr_get_leftmost_symbol(const struct expr *e)
1045 while (e->type != E_SYMBOL)
1048 return expr_copy(e);
1052 * Given expression `e1' and `e2', returns the leaf of the longest
1053 * sub-expression of `e1' not containing 'e2.
1055 struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
1061 return expr_alloc_and(
1062 expr_simplify_unmet_dep(e1->left.expr, e2),
1063 expr_simplify_unmet_dep(e1->right.expr, e2));
1066 e = expr_alloc_and(expr_copy(e1), expr_copy(e2));
1067 e = expr_eliminate_dups(e);
1068 ret = (!expr_eq(e, e1)) ? e1 : NULL;
1077 return expr_get_leftmost_symbol(ret);
1080 void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
1083 fn(data, NULL, "y");
1087 if (expr_compare_type(prevtoken, e->type) > 0)
1088 fn(data, NULL, "(");
1091 if (e->left.sym->name)
1092 fn(data, e->left.sym, e->left.sym->name);
1094 fn(data, NULL, "<choice>");
1097 fn(data, NULL, "!");
1098 expr_print(e->left.expr, fn, data, E_NOT);
1101 if (e->left.sym->name)
1102 fn(data, e->left.sym, e->left.sym->name);
1104 fn(data, NULL, "<choice>");
1105 fn(data, NULL, "=");
1106 fn(data, e->right.sym, e->right.sym->name);
1110 if (e->left.sym->name)
1111 fn(data, e->left.sym, e->left.sym->name);
1113 fn(data, NULL, "<choice>");
1114 fn(data, NULL, e->type == E_LEQ ? "<=" : "<");
1115 fn(data, e->right.sym, e->right.sym->name);
1119 if (e->left.sym->name)
1120 fn(data, e->left.sym, e->left.sym->name);
1122 fn(data, NULL, "<choice>");
1123 fn(data, NULL, e->type == E_GEQ ? ">=" : ">");
1124 fn(data, e->right.sym, e->right.sym->name);
1127 if (e->left.sym->name)
1128 fn(data, e->left.sym, e->left.sym->name);
1130 fn(data, NULL, "<choice>");
1131 fn(data, NULL, "!=");
1132 fn(data, e->right.sym, e->right.sym->name);
1135 expr_print(e->left.expr, fn, data, E_OR);
1136 fn(data, NULL, " || ");
1137 expr_print(e->right.expr, fn, data, E_OR);
1140 expr_print(e->left.expr, fn, data, E_AND);
1141 fn(data, NULL, " && ");
1142 expr_print(e->right.expr, fn, data, E_AND);
1145 fn(data, e->right.sym, e->right.sym->name);
1147 fn(data, NULL, " ^ ");
1148 expr_print(e->left.expr, fn, data, E_LIST);
1152 fn(data, NULL, "[");
1153 fn(data, e->left.sym, e->left.sym->name);
1154 fn(data, NULL, " ");
1155 fn(data, e->right.sym, e->right.sym->name);
1156 fn(data, NULL, "]");
1161 sprintf(buf, "<unknown type %d>", e->type);
1162 fn(data, NULL, buf);
1166 if (expr_compare_type(prevtoken, e->type) > 0)
1167 fn(data, NULL, ")");
1170 static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
1172 xfwrite(str, strlen(str), 1, data);
1175 void expr_fprint(struct expr *e, FILE *out)
1177 expr_print(e, expr_print_file_helper, out, E_NONE);
1180 static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
1182 struct gstr *gs = (struct gstr*)data;
1183 const char *sym_str = NULL;
1186 sym_str = sym_get_string_value(sym);
1188 if (gs->max_width) {
1189 unsigned extra_length = strlen(str);
1190 const char *last_cr = strrchr(gs->s, '\n');
1191 unsigned last_line_length;
1194 extra_length += 4 + strlen(sym_str);
1199 last_line_length = strlen(gs->s) - (last_cr - gs->s);
1201 if ((last_line_length + extra_length) > gs->max_width)
1202 str_append(gs, "\\\n");
1205 str_append(gs, str);
1206 if (sym && sym->type != S_UNKNOWN)
1207 str_printf(gs, " [=%s]", sym_str);
1210 void expr_gstr_print(struct expr *e, struct gstr *gs)
1212 expr_print(e, expr_print_gstr_helper, gs, E_NONE);