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)
204 if (e1->type != e2->type)
213 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
215 return e1->left.sym == e2->left.sym;
217 return expr_eq(e1->left.expr, e2->left.expr);
222 old_count = trans_count;
223 expr_eliminate_eq(&e1, &e2);
224 res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
225 e1->left.sym == e2->left.sym);
228 trans_count = old_count;
237 expr_fprint(e1, stdout);
239 expr_fprint(e2, stdout);
246 static struct expr *expr_eliminate_yn(struct expr *e)
250 if (e) switch (e->type) {
252 e->left.expr = expr_eliminate_yn(e->left.expr);
253 e->right.expr = expr_eliminate_yn(e->right.expr);
254 if (e->left.expr->type == E_SYMBOL) {
255 if (e->left.expr->left.sym == &symbol_no) {
256 expr_free(e->left.expr);
257 expr_free(e->right.expr);
259 e->left.sym = &symbol_no;
260 e->right.expr = NULL;
262 } else if (e->left.expr->left.sym == &symbol_yes) {
265 *e = *(e->right.expr);
270 if (e->right.expr->type == E_SYMBOL) {
271 if (e->right.expr->left.sym == &symbol_no) {
272 expr_free(e->left.expr);
273 expr_free(e->right.expr);
275 e->left.sym = &symbol_no;
276 e->right.expr = NULL;
278 } else if (e->right.expr->left.sym == &symbol_yes) {
281 *e = *(e->left.expr);
288 e->left.expr = expr_eliminate_yn(e->left.expr);
289 e->right.expr = expr_eliminate_yn(e->right.expr);
290 if (e->left.expr->type == E_SYMBOL) {
291 if (e->left.expr->left.sym == &symbol_no) {
294 *e = *(e->right.expr);
297 } else if (e->left.expr->left.sym == &symbol_yes) {
298 expr_free(e->left.expr);
299 expr_free(e->right.expr);
301 e->left.sym = &symbol_yes;
302 e->right.expr = NULL;
306 if (e->right.expr->type == E_SYMBOL) {
307 if (e->right.expr->left.sym == &symbol_no) {
310 *e = *(e->left.expr);
313 } else if (e->right.expr->left.sym == &symbol_yes) {
314 expr_free(e->left.expr);
315 expr_free(e->right.expr);
317 e->left.sym = &symbol_yes;
318 e->right.expr = NULL;
332 struct expr *expr_trans_bool(struct expr *e)
340 e->left.expr = expr_trans_bool(e->left.expr);
341 e->right.expr = expr_trans_bool(e->right.expr);
345 if (e->left.sym->type == S_TRISTATE) {
346 if (e->right.sym == &symbol_no) {
361 static struct expr *expr_join_or(struct expr *e1, struct expr *e2)
364 struct symbol *sym1, *sym2;
367 return expr_copy(e1);
368 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
370 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
372 if (e1->type == E_NOT) {
374 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
376 sym1 = tmp->left.sym;
379 if (e2->type == E_NOT) {
380 if (e2->left.expr->type != E_SYMBOL)
382 sym2 = e2->left.expr->left.sym;
387 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
389 if (sym1->type == S_TRISTATE) {
390 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
391 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
392 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) {
393 // (a='y') || (a='m') -> (a!='n')
394 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no);
396 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
397 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
398 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) {
399 // (a='y') || (a='n') -> (a!='m')
400 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod);
402 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
403 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
404 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) {
405 // (a='m') || (a='n') -> (a!='y')
406 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes);
409 if (sym1->type == S_BOOLEAN && sym1 == sym2) {
410 if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) ||
411 (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL))
412 return expr_alloc_symbol(&symbol_yes);
416 printf("optimize (");
417 expr_fprint(e1, stdout);
419 expr_fprint(e2, stdout);
425 static struct expr *expr_join_and(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)
454 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
455 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
456 // (a) && (a='y') -> (a='y')
457 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
459 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
460 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
461 // (a) && (a!='n') -> (a)
462 return expr_alloc_symbol(sym1);
464 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) ||
465 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod))
466 // (a) && (a!='m') -> (a='y')
467 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
469 if (sym1->type == S_TRISTATE) {
470 if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
471 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
472 sym2 = e1->right.sym;
473 if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
474 return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
475 : expr_alloc_symbol(&symbol_no);
477 if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
478 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
479 sym2 = e2->right.sym;
480 if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
481 return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
482 : expr_alloc_symbol(&symbol_no);
484 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
485 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
486 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
487 // (a!='y') && (a!='n') -> (a='m')
488 return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
490 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
491 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
492 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
493 // (a!='y') && (a!='m') -> (a='n')
494 return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
496 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
497 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
498 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
499 // (a!='m') && (a!='n') -> (a='m')
500 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
502 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
503 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
504 (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
505 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
510 printf("optimize (");
511 expr_fprint(e1, stdout);
513 expr_fprint(e2, stdout);
519 static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
525 if (e1->type == type) {
526 expr_eliminate_dups1(type, &e1->left.expr, &e2);
527 expr_eliminate_dups1(type, &e1->right.expr, &e2);
530 if (e2->type == type) {
531 expr_eliminate_dups1(type, &e1, &e2->left.expr);
532 expr_eliminate_dups1(type, &e1, &e2->right.expr);
539 case E_OR: case E_AND:
540 expr_eliminate_dups1(e1->type, &e1, &e1);
547 tmp = expr_join_or(e1, e2);
549 expr_free(e1); expr_free(e2);
550 e1 = expr_alloc_symbol(&symbol_no);
556 tmp = expr_join_and(e1, e2);
558 expr_free(e1); expr_free(e2);
559 e1 = expr_alloc_symbol(&symbol_yes);
571 struct expr *expr_eliminate_dups(struct expr *e)
577 oldcount = trans_count;
581 case E_OR: case E_AND:
582 expr_eliminate_dups1(e->type, &e, &e);
588 e = expr_eliminate_yn(e);
590 trans_count = oldcount;
594 struct expr *expr_transform(struct expr *e)
611 e->left.expr = expr_transform(e->left.expr);
612 e->right.expr = expr_transform(e->right.expr);
617 if (e->left.sym->type != S_BOOLEAN)
619 if (e->right.sym == &symbol_no) {
621 e->left.expr = expr_alloc_symbol(e->left.sym);
625 if (e->right.sym == &symbol_mod) {
626 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
628 e->left.sym = &symbol_no;
632 if (e->right.sym == &symbol_yes) {
639 if (e->left.sym->type != S_BOOLEAN)
641 if (e->right.sym == &symbol_no) {
646 if (e->right.sym == &symbol_mod) {
647 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
649 e->left.sym = &symbol_yes;
653 if (e->right.sym == &symbol_yes) {
655 e->left.expr = expr_alloc_symbol(e->left.sym);
661 switch (e->left.expr->type) {
664 tmp = e->left.expr->left.expr;
668 e = expr_transform(e);
676 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
684 e->type = e->type == E_LEQ ? E_GTH : E_LTH;
692 e->type = e->type == E_LTH ? E_GEQ : E_LEQ;
695 // !(a || b) -> !a && !b
698 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
700 tmp->right.expr = NULL;
701 e = expr_transform(e);
704 // !(a && b) -> !a || !b
707 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
709 tmp->right.expr = NULL;
710 e = expr_transform(e);
713 if (e->left.expr->left.sym == &symbol_yes) {
719 e->left.sym = &symbol_no;
722 if (e->left.expr->left.sym == &symbol_mod) {
728 e->left.sym = &symbol_mod;
731 if (e->left.expr->left.sym == &symbol_no) {
737 e->left.sym = &symbol_yes;
751 int expr_contains_symbol(struct expr *dep, struct symbol *sym)
759 return expr_contains_symbol(dep->left.expr, sym) ||
760 expr_contains_symbol(dep->right.expr, sym);
762 return dep->left.sym == sym;
769 return dep->left.sym == sym ||
770 dep->right.sym == sym;
772 return expr_contains_symbol(dep->left.expr, sym);
779 bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
786 return expr_depends_symbol(dep->left.expr, sym) ||
787 expr_depends_symbol(dep->right.expr, sym);
789 return dep->left.sym == sym;
791 if (dep->left.sym == sym) {
792 if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
797 if (dep->left.sym == sym) {
798 if (dep->right.sym == &symbol_no)
808 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
810 struct expr *e1, *e2;
813 e = expr_alloc_symbol(sym);
814 if (type == E_UNEQUAL)
815 e = expr_alloc_one(E_NOT, e);
820 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
821 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
822 if (sym == &symbol_yes)
823 e = expr_alloc_two(E_AND, e1, e2);
824 if (sym == &symbol_no)
825 e = expr_alloc_two(E_OR, e1, e2);
826 if (type == E_UNEQUAL)
827 e = expr_alloc_one(E_NOT, e);
830 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
831 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
832 if (sym == &symbol_yes)
833 e = expr_alloc_two(E_OR, e1, e2);
834 if (sym == &symbol_no)
835 e = expr_alloc_two(E_AND, e1, e2);
836 if (type == E_UNEQUAL)
837 e = expr_alloc_one(E_NOT, e);
840 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
847 if (type == E_EQUAL) {
848 if (sym == &symbol_yes)
850 if (sym == &symbol_mod)
851 return expr_alloc_symbol(&symbol_no);
852 if (sym == &symbol_no)
853 return expr_alloc_one(E_NOT, expr_copy(e));
855 if (sym == &symbol_yes)
856 return expr_alloc_one(E_NOT, expr_copy(e));
857 if (sym == &symbol_mod)
858 return expr_alloc_symbol(&symbol_yes);
859 if (sym == &symbol_no)
864 return expr_alloc_comp(type, e->left.sym, sym);
873 enum string_value_kind {
881 unsigned long long u;
885 static enum string_value_kind expr_parse_string(const char *str,
886 enum symbol_type type,
887 union string_value *val)
890 enum string_value_kind kind;
896 val->s = !strcmp(str, "n") ? 0 :
897 !strcmp(str, "m") ? 1 :
898 !strcmp(str, "y") ? 2 : -1;
901 val->s = strtoll(str, &tail, 10);
905 val->u = strtoull(str, &tail, 16);
910 val->s = strtoll(str, &tail, 0);
916 return !errno && !*tail && tail > str && isxdigit(tail[-1])
920 tristate expr_calc_value(struct expr *e)
923 const char *str1, *str2;
924 enum string_value_kind k1 = k_string, k2 = k_string;
925 union string_value lval = {}, rval = {};
933 sym_calc_value(e->left.sym);
934 return e->left.sym->curr.tri;
936 val1 = expr_calc_value(e->left.expr);
937 val2 = expr_calc_value(e->right.expr);
938 return EXPR_AND(val1, val2);
940 val1 = expr_calc_value(e->left.expr);
941 val2 = expr_calc_value(e->right.expr);
942 return EXPR_OR(val1, val2);
944 val1 = expr_calc_value(e->left.expr);
945 return EXPR_NOT(val1);
954 printf("expr_calc_value: %d?\n", e->type);
958 sym_calc_value(e->left.sym);
959 sym_calc_value(e->right.sym);
960 str1 = sym_get_string_value(e->left.sym);
961 str2 = sym_get_string_value(e->right.sym);
963 if (e->left.sym->type != S_STRING || e->right.sym->type != S_STRING) {
964 k1 = expr_parse_string(str1, e->left.sym->type, &lval);
965 k2 = expr_parse_string(str2, e->right.sym->type, &rval);
968 if (k1 == k_string || k2 == k_string)
969 res = strcmp(str1, str2);
970 else if (k1 == k_invalid || k2 == k_invalid) {
971 if (e->type != E_EQUAL && e->type != E_UNEQUAL) {
972 printf("Cannot compare \"%s\" and \"%s\"\n", str1, str2);
975 res = strcmp(str1, str2);
976 } else if (k1 == k_unsigned || k2 == k_unsigned)
977 res = (lval.u > rval.u) - (lval.u < rval.u);
978 else /* if (k1 == k_signed && k2 == k_signed) */
979 res = (lval.s > rval.s) - (lval.s < rval.s);
983 return res ? no : yes;
985 return res >= 0 ? yes : no;
987 return res > 0 ? yes : no;
989 return res <= 0 ? yes : no;
991 return res < 0 ? yes : no;
993 return res ? yes : no;
995 printf("expr_calc_value: relation %d?\n", e->type);
1000 static int expr_compare_type(enum expr_type t1, enum expr_type t2)
1009 if (t2 == E_EQUAL || t2 == E_UNEQUAL)
1030 printf("[%dgt%d?]", t1, t2);
1034 static inline struct expr *
1035 expr_get_leftmost_symbol(const struct expr *e)
1041 while (e->type != E_SYMBOL)
1044 return expr_copy(e);
1048 * Given expression `e1' and `e2', returns the leaf of the longest
1049 * sub-expression of `e1' not containing 'e2.
1051 struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2)
1057 return expr_alloc_and(
1058 expr_simplify_unmet_dep(e1->left.expr, e2),
1059 expr_simplify_unmet_dep(e1->right.expr, e2));
1062 e = expr_alloc_and(expr_copy(e1), expr_copy(e2));
1063 e = expr_eliminate_dups(e);
1064 ret = (!expr_eq(e, e1)) ? e1 : NULL;
1073 return expr_get_leftmost_symbol(ret);
1076 void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
1079 fn(data, NULL, "y");
1083 if (expr_compare_type(prevtoken, e->type) > 0)
1084 fn(data, NULL, "(");
1087 if (e->left.sym->name)
1088 fn(data, e->left.sym, e->left.sym->name);
1090 fn(data, NULL, "<choice>");
1093 fn(data, NULL, "!");
1094 expr_print(e->left.expr, fn, data, E_NOT);
1097 if (e->left.sym->name)
1098 fn(data, e->left.sym, e->left.sym->name);
1100 fn(data, NULL, "<choice>");
1101 fn(data, NULL, "=");
1102 fn(data, e->right.sym, e->right.sym->name);
1106 if (e->left.sym->name)
1107 fn(data, e->left.sym, e->left.sym->name);
1109 fn(data, NULL, "<choice>");
1110 fn(data, NULL, e->type == E_LEQ ? "<=" : "<");
1111 fn(data, e->right.sym, e->right.sym->name);
1115 if (e->left.sym->name)
1116 fn(data, e->left.sym, e->left.sym->name);
1118 fn(data, NULL, "<choice>");
1119 fn(data, NULL, e->type == E_GEQ ? ">=" : ">");
1120 fn(data, e->right.sym, e->right.sym->name);
1123 if (e->left.sym->name)
1124 fn(data, e->left.sym, e->left.sym->name);
1126 fn(data, NULL, "<choice>");
1127 fn(data, NULL, "!=");
1128 fn(data, e->right.sym, e->right.sym->name);
1131 expr_print(e->left.expr, fn, data, E_OR);
1132 fn(data, NULL, " || ");
1133 expr_print(e->right.expr, fn, data, E_OR);
1136 expr_print(e->left.expr, fn, data, E_AND);
1137 fn(data, NULL, " && ");
1138 expr_print(e->right.expr, fn, data, E_AND);
1141 fn(data, e->right.sym, e->right.sym->name);
1143 fn(data, NULL, " ^ ");
1144 expr_print(e->left.expr, fn, data, E_LIST);
1148 fn(data, NULL, "[");
1149 fn(data, e->left.sym, e->left.sym->name);
1150 fn(data, NULL, " ");
1151 fn(data, e->right.sym, e->right.sym->name);
1152 fn(data, NULL, "]");
1157 sprintf(buf, "<unknown type %d>", e->type);
1158 fn(data, NULL, buf);
1162 if (expr_compare_type(prevtoken, e->type) > 0)
1163 fn(data, NULL, ")");
1166 static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
1168 xfwrite(str, strlen(str), 1, data);
1171 void expr_fprint(struct expr *e, FILE *out)
1173 expr_print(e, expr_print_file_helper, out, E_NONE);
1176 static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
1178 struct gstr *gs = (struct gstr*)data;
1179 const char *sym_str = NULL;
1182 sym_str = sym_get_string_value(sym);
1184 if (gs->max_width) {
1185 unsigned extra_length = strlen(str);
1186 const char *last_cr = strrchr(gs->s, '\n');
1187 unsigned last_line_length;
1190 extra_length += 4 + strlen(sym_str);
1195 last_line_length = strlen(gs->s) - (last_cr - gs->s);
1197 if ((last_line_length + extra_length) > gs->max_width)
1198 str_append(gs, "\\\n");
1201 str_append(gs, str);
1202 if (sym && sym->type != S_UNKNOWN)
1203 str_printf(gs, " [=%s]", sym_str);
1206 void expr_gstr_print(struct expr *e, struct gstr *gs)
1208 expr_print(e, expr_print_gstr_helper, gs, E_NONE);