Make the loop support stuff be much less evil, and make it cope
[oweals/busybox.git] / scripts / config / expr.c
1 /*
2  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3  * Released under the terms of the GNU GPL v2.0.
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9
10 #define LKC_DIRECT_LINK
11 #include "lkc.h"
12
13 struct expr *expr_alloc_symbol(struct symbol *sym)
14 {
15         struct expr *e = malloc(sizeof(*e));
16         memset(e, 0, sizeof(*e));
17         e->type = E_SYMBOL;
18         e->left.sym = sym;
19         return e;
20 }
21
22 struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
23 {
24         struct expr *e = malloc(sizeof(*e));
25         memset(e, 0, sizeof(*e));
26         e->type = type;
27         e->left.expr = ce;
28         return e;
29 }
30
31 struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
32 {
33         struct expr *e = malloc(sizeof(*e));
34         memset(e, 0, sizeof(*e));
35         e->type = type;
36         e->left.expr = e1;
37         e->right.expr = e2;
38         return e;
39 }
40
41 struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
42 {
43         struct expr *e = malloc(sizeof(*e));
44         memset(e, 0, sizeof(*e));
45         e->type = type;
46         e->left.sym = s1;
47         e->right.sym = s2;
48         return e;
49 }
50
51 struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
52 {
53         if (!e1)
54                 return e2;
55         return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
56 }
57
58 struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
59 {
60         if (!e1)
61                 return e2;
62         return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
63 }
64
65 struct expr *expr_copy(struct expr *org)
66 {
67         struct expr *e;
68
69         if (!org)
70                 return NULL;
71
72         e = malloc(sizeof(*org));
73         memcpy(e, org, sizeof(*org));
74         switch (org->type) {
75         case E_SYMBOL:
76                 e->left = org->left;
77                 break;
78         case E_NOT:
79                 e->left.expr = expr_copy(org->left.expr);
80                 break;
81         case E_EQUAL:
82         case E_UNEQUAL:
83                 e->left.sym = org->left.sym;
84                 e->right.sym = org->right.sym;
85                 break;
86         case E_AND:
87         case E_OR:
88         case E_CHOICE:
89                 e->left.expr = expr_copy(org->left.expr);
90                 e->right.expr = expr_copy(org->right.expr);
91                 break;
92         default:
93                 printf("can't copy type %d\n", e->type);
94                 free(e);
95                 e = NULL;
96                 break;
97         }
98
99         return e;
100 }
101
102 void expr_free(struct expr *e)
103 {
104         if (!e)
105                 return;
106
107         switch (e->type) {
108         case E_SYMBOL:
109                 break;
110         case E_NOT:
111                 expr_free(e->left.expr);
112                 return;
113         case E_EQUAL:
114         case E_UNEQUAL:
115                 break;
116         case E_OR:
117         case E_AND:
118                 expr_free(e->left.expr);
119                 expr_free(e->right.expr);
120                 break;
121         default:
122                 printf("how to free type %d?\n", e->type);
123                 break;
124         }
125         free(e);
126 }
127
128 static int trans_count;
129
130 #define e1 (*ep1)
131 #define e2 (*ep2)
132
133 static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
134 {
135         if (e1->type == type) {
136                 __expr_eliminate_eq(type, &e1->left.expr, &e2);
137                 __expr_eliminate_eq(type, &e1->right.expr, &e2);
138                 return;
139         }
140         if (e2->type == type) {
141                 __expr_eliminate_eq(type, &e1, &e2->left.expr);
142                 __expr_eliminate_eq(type, &e1, &e2->right.expr);
143                 return;
144         }
145         if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
146             e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO)))
147                 return;
148         if (!expr_eq(e1, e2))
149                 return;
150         trans_count++;
151         expr_free(e1); expr_free(e2);
152         switch (type) {
153         case E_OR:
154                 e1 = expr_alloc_symbol(&symbol_no);
155                 e2 = expr_alloc_symbol(&symbol_no);
156                 break;
157         case E_AND:
158                 e1 = expr_alloc_symbol(&symbol_yes);
159                 e2 = expr_alloc_symbol(&symbol_yes);
160                 break;
161         default:
162                 ;
163         }
164 }
165
166 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
167 {
168         if (!e1 || !e2)
169                 return;
170         switch (e1->type) {
171         case E_OR:
172         case E_AND:
173                 __expr_eliminate_eq(e1->type, ep1, ep2);
174         default:
175                 ;
176         }
177         if (e1->type != e2->type) switch (e2->type) {
178         case E_OR:
179         case E_AND:
180                 __expr_eliminate_eq(e2->type, ep1, ep2);
181         default:
182                 ;
183         }
184         e1 = expr_eliminate_yn(e1);
185         e2 = expr_eliminate_yn(e2);
186 }
187
188 #undef e1
189 #undef e2
190
191 int expr_eq(struct expr *e1, struct expr *e2)
192 {
193         int res, old_count;
194
195         if (e1->type != e2->type)
196                 return 0;
197         switch (e1->type) {
198         case E_EQUAL:
199         case E_UNEQUAL:
200                 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
201         case E_SYMBOL:
202                 return e1->left.sym == e2->left.sym;
203         case E_NOT:
204                 return expr_eq(e1->left.expr, e2->left.expr);
205         case E_AND:
206         case E_OR:
207                 e1 = expr_copy(e1);
208                 e2 = expr_copy(e2);
209                 old_count = trans_count;
210                 expr_eliminate_eq(&e1, &e2);
211                 res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
212                        e1->left.sym == e2->left.sym);
213                 expr_free(e1);
214                 expr_free(e2);
215                 trans_count = old_count;
216                 return res;
217         case E_CHOICE:
218         case E_RANGE:
219         case E_NONE:
220                 /* panic */;
221         }
222
223         print_expr(0, e1, 0);
224         printf(" = ");
225         print_expr(0, e2, 0);
226         printf(" ?\n");
227
228         return 0;
229 }
230
231 struct expr *expr_eliminate_yn(struct expr *e)
232 {
233         struct expr *tmp;
234
235         if (e) switch (e->type) {
236         case E_AND:
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);
243                                 e->type = E_SYMBOL;
244                                 e->left.sym = &symbol_no;
245                                 e->right.expr = NULL;
246                                 return e;
247                         } else if (e->left.expr->left.sym == &symbol_yes) {
248                                 free(e->left.expr);
249                                 tmp = e->right.expr;
250                                 *e = *(e->right.expr);
251                                 free(tmp);
252                                 return e;
253                         }
254                 }
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);
259                                 e->type = E_SYMBOL;
260                                 e->left.sym = &symbol_no;
261                                 e->right.expr = NULL;
262                                 return e;
263                         } else if (e->right.expr->left.sym == &symbol_yes) {
264                                 free(e->right.expr);
265                                 tmp = e->left.expr;
266                                 *e = *(e->left.expr);
267                                 free(tmp);
268                                 return e;
269                         }
270                 }
271                 break;
272         case E_OR:
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) {
277                                 free(e->left.expr);
278                                 tmp = e->right.expr;
279                                 *e = *(e->right.expr);
280                                 free(tmp);
281                                 return e;
282                         } else if (e->left.expr->left.sym == &symbol_yes) {
283                                 expr_free(e->left.expr);
284                                 expr_free(e->right.expr);
285                                 e->type = E_SYMBOL;
286                                 e->left.sym = &symbol_yes;
287                                 e->right.expr = NULL;
288                                 return e;
289                         }
290                 }
291                 if (e->right.expr->type == E_SYMBOL) {
292                         if (e->right.expr->left.sym == &symbol_no) {
293                                 free(e->right.expr);
294                                 tmp = e->left.expr;
295                                 *e = *(e->left.expr);
296                                 free(tmp);
297                                 return e;
298                         } else if (e->right.expr->left.sym == &symbol_yes) {
299                                 expr_free(e->left.expr);
300                                 expr_free(e->right.expr);
301                                 e->type = E_SYMBOL;
302                                 e->left.sym = &symbol_yes;
303                                 e->right.expr = NULL;
304                                 return e;
305                         }
306                 }
307                 break;
308         default:
309                 ;
310         }
311         return e;
312 }
313
314 /*
315  * bool FOO!=n => FOO
316  */
317 struct expr *expr_trans_bool(struct expr *e)
318 {
319         if (!e)
320                 return NULL;
321         switch (e->type) {
322         case E_AND:
323         case E_OR:
324         case E_NOT:
325                 e->left.expr = expr_trans_bool(e->left.expr);
326                 e->right.expr = expr_trans_bool(e->right.expr);
327                 break;
328         case E_UNEQUAL:
329                 // FOO!=n -> FOO
330                 if (e->left.sym->type == S_TRISTATE) {
331                         if (e->right.sym == &symbol_no) {
332                                 e->type = E_SYMBOL;
333                                 e->right.sym = NULL;
334                         }
335                 }
336                 break;
337         default:
338                 ;
339         }
340         return e;
341 }
342
343 /*
344  * e1 || e2 -> ?
345  */
346 struct expr *expr_join_or(struct expr *e1, struct expr *e2)
347 {
348         struct expr *tmp;
349         struct symbol *sym1, *sym2;
350
351         if (expr_eq(e1, e2))
352                 return expr_copy(e1);
353         if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
354                 return NULL;
355         if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
356                 return NULL;
357         if (e1->type == E_NOT) {
358                 tmp = e1->left.expr;
359                 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
360                         return NULL;
361                 sym1 = tmp->left.sym;
362         } else
363                 sym1 = e1->left.sym;
364         if (e2->type == E_NOT) {
365                 if (e2->left.expr->type != E_SYMBOL)
366                         return NULL;
367                 sym2 = e2->left.expr->left.sym;
368         } else
369                 sym2 = e2->left.sym;
370         if (sym1 != sym2)
371                 return NULL;
372         if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
373                 return NULL;
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);
380                 }
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);
386                 }
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);
392                 }
393         }
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);
398         }
399
400         printf("optimize ");
401         print_expr(0, e1, 0);
402         printf(" || ");
403         print_expr(0, e2, 0);
404         printf(" ?\n");
405         return NULL;
406 }
407
408 struct expr *expr_join_and(struct expr *e1, struct expr *e2)
409 {
410         struct expr *tmp;
411         struct symbol *sym1, *sym2;
412
413         if (expr_eq(e1, e2))
414                 return expr_copy(e1);
415         if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
416                 return NULL;
417         if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
418                 return NULL;
419         if (e1->type == E_NOT) {
420                 tmp = e1->left.expr;
421                 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
422                         return NULL;
423                 sym1 = tmp->left.sym;
424         } else
425                 sym1 = e1->left.sym;
426         if (e2->type == E_NOT) {
427                 if (e2->left.expr->type != E_SYMBOL)
428                         return NULL;
429                 sym2 = e2->left.expr->left.sym;
430         } else
431                 sym2 = e2->left.sym;
432         if (sym1 != sym2)
433                 return NULL;
434         if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
435                 return NULL;
436
437         if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
438             (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
439                 // (a) && (a='y') -> (a='y')
440                 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
441
442         if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
443             (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
444                 // (a) && (a!='n') -> (a)
445                 return expr_alloc_symbol(sym1);
446
447         if (sym1->type == S_TRISTATE) {
448                 if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
449                         // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
450                         sym2 = e1->right.sym;
451                         if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
452                                 return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
453                                                              : expr_alloc_symbol(&symbol_no);
454                 }
455                 if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
456                         // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b'
457                         sym2 = e2->right.sym;
458                         if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
459                                 return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
460                                                              : expr_alloc_symbol(&symbol_no);
461                 }
462                 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
463                            ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
464                             (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
465                         // (a!='y') && (a!='n') -> (a='m')
466                         return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
467
468                 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
469                            ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
470                             (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
471                         // (a!='y') && (a!='m') -> (a='n')
472                         return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
473
474                 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
475                            ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
476                             (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
477                         // (a!='m') && (a!='n') -> (a='m')
478                         return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
479
480                 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
481                     (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
482                     (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
483                     (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
484                         return NULL;
485         }
486         printf("optimize ");
487         print_expr(0, e1, 0);
488         printf(" && ");
489         print_expr(0, e2, 0);
490         printf(" ?\n");
491         return NULL;
492 }
493
494 static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
495 {
496 #define e1 (*ep1)
497 #define e2 (*ep2)
498         struct expr *tmp;
499
500         if (e1->type == type) {
501                 expr_eliminate_dups1(type, &e1->left.expr, &e2);
502                 expr_eliminate_dups1(type, &e1->right.expr, &e2);
503                 return;
504         }
505         if (e2->type == type) {
506                 expr_eliminate_dups1(type, &e1, &e2->left.expr);
507                 expr_eliminate_dups1(type, &e1, &e2->right.expr);
508                 return;
509         }
510         if (e1 == e2)
511                 return;
512
513         switch (e1->type) {
514         case E_OR: case E_AND:
515                 expr_eliminate_dups1(e1->type, &e1, &e1);
516         default:
517                 ;
518         }
519
520         switch (type) {
521         case E_OR:
522                 tmp = expr_join_or(e1, e2);
523                 if (tmp) {
524                         expr_free(e1); expr_free(e2);
525                         e1 = expr_alloc_symbol(&symbol_no);
526                         e2 = tmp;
527                         trans_count++;
528                 }
529                 break;
530         case E_AND:
531                 tmp = expr_join_and(e1, e2);
532                 if (tmp) {
533                         expr_free(e1); expr_free(e2);
534                         e1 = expr_alloc_symbol(&symbol_yes);
535                         e2 = tmp;
536                         trans_count++;
537                 }
538                 break;
539         default:
540                 ;
541         }
542 #undef e1
543 #undef e2
544 }
545
546 static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2)
547 {
548 #define e1 (*ep1)
549 #define e2 (*ep2)
550         struct expr *tmp, *tmp1, *tmp2;
551
552         if (e1->type == type) {
553                 expr_eliminate_dups2(type, &e1->left.expr, &e2);
554                 expr_eliminate_dups2(type, &e1->right.expr, &e2);
555                 return;
556         }
557         if (e2->type == type) {
558                 expr_eliminate_dups2(type, &e1, &e2->left.expr);
559                 expr_eliminate_dups2(type, &e1, &e2->right.expr);
560         }
561         if (e1 == e2)
562                 return;
563
564         switch (e1->type) {
565         case E_OR:
566                 expr_eliminate_dups2(e1->type, &e1, &e1);
567                 // (FOO || BAR) && (!FOO && !BAR) -> n
568                 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
569                 tmp2 = expr_copy(e2);
570                 tmp = expr_extract_eq_and(&tmp1, &tmp2);
571                 if (expr_is_yes(tmp1)) {
572                         expr_free(e1);
573                         e1 = expr_alloc_symbol(&symbol_no);
574                         trans_count++;
575                 }
576                 expr_free(tmp2);
577                 expr_free(tmp1);
578                 expr_free(tmp);
579                 break;
580         case E_AND:
581                 expr_eliminate_dups2(e1->type, &e1, &e1);
582                 // (FOO && BAR) || (!FOO || !BAR) -> y
583                 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1)));
584                 tmp2 = expr_copy(e2);
585                 tmp = expr_extract_eq_or(&tmp1, &tmp2);
586                 if (expr_is_no(tmp1)) {
587                         expr_free(e1);
588                         e1 = expr_alloc_symbol(&symbol_yes);
589                         trans_count++;
590                 }
591                 expr_free(tmp2);
592                 expr_free(tmp1);
593                 expr_free(tmp);
594                 break;
595         default:
596                 ;
597         }
598 #undef e1
599 #undef e2
600 }
601
602 struct expr *expr_eliminate_dups(struct expr *e)
603 {
604         int oldcount;
605         if (!e)
606                 return e;
607
608         oldcount = trans_count;
609         while (1) {
610                 trans_count = 0;
611                 switch (e->type) {
612                 case E_OR: case E_AND:
613                         expr_eliminate_dups1(e->type, &e, &e);
614                         expr_eliminate_dups2(e->type, &e, &e);
615                 default:
616                         ;
617                 }
618                 if (!trans_count)
619                         break;
620                 e = expr_eliminate_yn(e);
621         }
622         trans_count = oldcount;
623         return e;
624 }
625
626 struct expr *expr_transform(struct expr *e)
627 {
628         struct expr *tmp;
629
630         if (!e)
631                 return NULL;
632         switch (e->type) {
633         case E_EQUAL:
634         case E_UNEQUAL:
635         case E_SYMBOL:
636         case E_CHOICE:
637                 break;
638         default:
639                 e->left.expr = expr_transform(e->left.expr);
640                 e->right.expr = expr_transform(e->right.expr);
641         }
642
643         switch (e->type) {
644         case E_EQUAL:
645                 if (e->left.sym->type != S_BOOLEAN)
646                         break;
647                 if (e->right.sym == &symbol_no) {
648                         e->type = E_NOT;
649                         e->left.expr = expr_alloc_symbol(e->left.sym);
650                         e->right.sym = NULL;
651                         break;
652                 }
653                 if (e->right.sym == &symbol_mod) {
654                         printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
655                         e->type = E_SYMBOL;
656                         e->left.sym = &symbol_no;
657                         e->right.sym = NULL;
658                         break;
659                 }
660                 if (e->right.sym == &symbol_yes) {
661                         e->type = E_SYMBOL;
662                         e->right.sym = NULL;
663                         break;
664                 }
665                 break;
666         case E_UNEQUAL:
667                 if (e->left.sym->type != S_BOOLEAN)
668                         break;
669                 if (e->right.sym == &symbol_no) {
670                         e->type = E_SYMBOL;
671                         e->right.sym = NULL;
672                         break;
673                 }
674                 if (e->right.sym == &symbol_mod) {
675                         printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
676                         e->type = E_SYMBOL;
677                         e->left.sym = &symbol_yes;
678                         e->right.sym = NULL;
679                         break;
680                 }
681                 if (e->right.sym == &symbol_yes) {
682                         e->type = E_NOT;
683                         e->left.expr = expr_alloc_symbol(e->left.sym);
684                         e->right.sym = NULL;
685                         break;
686                 }
687                 break;
688         case E_NOT:
689                 switch (e->left.expr->type) {
690                 case E_NOT:
691                         // !!a -> a
692                         tmp = e->left.expr->left.expr;
693                         free(e->left.expr);
694                         free(e);
695                         e = tmp;
696                         e = expr_transform(e);
697                         break;
698                 case E_EQUAL:
699                 case E_UNEQUAL:
700                         // !a='x' -> a!='x'
701                         tmp = e->left.expr;
702                         free(e);
703                         e = tmp;
704                         e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
705                         break;
706                 case E_OR:
707                         // !(a || b) -> !a && !b
708                         tmp = e->left.expr;
709                         e->type = E_AND;
710                         e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
711                         tmp->type = E_NOT;
712                         tmp->right.expr = NULL;
713                         e = expr_transform(e);
714                         break;
715                 case E_AND:
716                         // !(a && b) -> !a || !b
717                         tmp = e->left.expr;
718                         e->type = E_OR;
719                         e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
720                         tmp->type = E_NOT;
721                         tmp->right.expr = NULL;
722                         e = expr_transform(e);
723                         break;
724                 case E_SYMBOL:
725                         if (e->left.expr->left.sym == &symbol_yes) {
726                                 // !'y' -> 'n'
727                                 tmp = e->left.expr;
728                                 free(e);
729                                 e = tmp;
730                                 e->type = E_SYMBOL;
731                                 e->left.sym = &symbol_no;
732                                 break;
733                         }
734                         if (e->left.expr->left.sym == &symbol_mod) {
735                                 // !'m' -> 'm'
736                                 tmp = e->left.expr;
737                                 free(e);
738                                 e = tmp;
739                                 e->type = E_SYMBOL;
740                                 e->left.sym = &symbol_mod;
741                                 break;
742                         }
743                         if (e->left.expr->left.sym == &symbol_no) {
744                                 // !'n' -> 'y'
745                                 tmp = e->left.expr;
746                                 free(e);
747                                 e = tmp;
748                                 e->type = E_SYMBOL;
749                                 e->left.sym = &symbol_yes;
750                                 break;
751                         }
752                         break;
753                 default:
754                         ;
755                 }
756                 break;
757         default:
758                 ;
759         }
760         return e;
761 }
762
763 int expr_contains_symbol(struct expr *dep, struct symbol *sym)
764 {
765         if (!dep)
766                 return 0;
767
768         switch (dep->type) {
769         case E_AND:
770         case E_OR:
771                 return expr_contains_symbol(dep->left.expr, sym) ||
772                        expr_contains_symbol(dep->right.expr, sym);
773         case E_SYMBOL:
774                 return dep->left.sym == sym;
775         case E_EQUAL:
776         case E_UNEQUAL:
777                 return dep->left.sym == sym ||
778                        dep->right.sym == sym;
779         case E_NOT:
780                 return expr_contains_symbol(dep->left.expr, sym);
781         default:
782                 ;
783         }
784         return 0;
785 }
786
787 bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
788 {
789         if (!dep)
790                 return false;
791
792         switch (dep->type) {
793         case E_AND:
794                 return expr_depends_symbol(dep->left.expr, sym) ||
795                        expr_depends_symbol(dep->right.expr, sym);
796         case E_SYMBOL:
797                 return dep->left.sym == sym;
798         case E_EQUAL:
799                 if (dep->left.sym == sym) {
800                         if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
801                                 return true;
802                 }
803                 break;
804         case E_UNEQUAL:
805                 if (dep->left.sym == sym) {
806                         if (dep->right.sym == &symbol_no)
807                                 return true;
808                 }
809                 break;
810         default:
811                 ;
812         }
813         return false;
814 }
815
816 struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
817 {
818         struct expr *tmp = NULL;
819         expr_extract_eq(E_AND, &tmp, ep1, ep2);
820         if (tmp) {
821                 *ep1 = expr_eliminate_yn(*ep1);
822                 *ep2 = expr_eliminate_yn(*ep2);
823         }
824         return tmp;
825 }
826
827 struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
828 {
829         struct expr *tmp = NULL;
830         expr_extract_eq(E_OR, &tmp, ep1, ep2);
831         if (tmp) {
832                 *ep1 = expr_eliminate_yn(*ep1);
833                 *ep2 = expr_eliminate_yn(*ep2);
834         }
835         return tmp;
836 }
837
838 void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
839 {
840 #define e1 (*ep1)
841 #define e2 (*ep2)
842         if (e1->type == type) {
843                 expr_extract_eq(type, ep, &e1->left.expr, &e2);
844                 expr_extract_eq(type, ep, &e1->right.expr, &e2);
845                 return;
846         }
847         if (e2->type == type) {
848                 expr_extract_eq(type, ep, ep1, &e2->left.expr);
849                 expr_extract_eq(type, ep, ep1, &e2->right.expr);
850                 return;
851         }
852         if (expr_eq(e1, e2)) {
853                 *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1;
854                 expr_free(e2);
855                 if (type == E_AND) {
856                         e1 = expr_alloc_symbol(&symbol_yes);
857                         e2 = expr_alloc_symbol(&symbol_yes);
858                 } else if (type == E_OR) {
859                         e1 = expr_alloc_symbol(&symbol_no);
860                         e2 = expr_alloc_symbol(&symbol_no);
861                 }
862         }
863 #undef e1
864 #undef e2
865 }
866
867 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
868 {
869         struct expr *e1, *e2;
870
871         if (!e) {
872                 e = expr_alloc_symbol(sym);
873                 if (type == E_UNEQUAL)
874                         e = expr_alloc_one(E_NOT, e);
875                 return e;
876         }
877         switch (e->type) {
878         case E_AND:
879                 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
880                 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
881                 if (sym == &symbol_yes)
882                         e = expr_alloc_two(E_AND, e1, e2);
883                 if (sym == &symbol_no)
884                         e = expr_alloc_two(E_OR, e1, e2);
885                 if (type == E_UNEQUAL)
886                         e = expr_alloc_one(E_NOT, e);
887                 return e;
888         case E_OR:
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_OR, e1, e2);
893                 if (sym == &symbol_no)
894                         e = expr_alloc_two(E_AND, e1, e2);
895                 if (type == E_UNEQUAL)
896                         e = expr_alloc_one(E_NOT, e);
897                 return e;
898         case E_NOT:
899                 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
900         case E_UNEQUAL:
901         case E_EQUAL:
902                 if (type == E_EQUAL) {
903                         if (sym == &symbol_yes)
904                                 return expr_copy(e);
905                         if (sym == &symbol_mod)
906                                 return expr_alloc_symbol(&symbol_no);
907                         if (sym == &symbol_no)
908                                 return expr_alloc_one(E_NOT, expr_copy(e));
909                 } else {
910                         if (sym == &symbol_yes)
911                                 return expr_alloc_one(E_NOT, expr_copy(e));
912                         if (sym == &symbol_mod)
913                                 return expr_alloc_symbol(&symbol_yes);
914                         if (sym == &symbol_no)
915                                 return expr_copy(e);
916                 }
917                 break;
918         case E_SYMBOL:
919                 return expr_alloc_comp(type, e->left.sym, sym);
920         case E_CHOICE:
921         case E_RANGE:
922         case E_NONE:
923                 /* panic */;
924         }
925         return NULL;
926 }
927
928 tristate expr_calc_value(struct expr *e)
929 {
930         tristate val1, val2;
931         const char *str1, *str2;
932
933         if (!e)
934                 return yes;
935
936         switch (e->type) {
937         case E_SYMBOL:
938                 sym_calc_value(e->left.sym);
939                 return e->left.sym->curr.tri;
940         case E_AND:
941                 val1 = expr_calc_value(e->left.expr);
942                 val2 = expr_calc_value(e->right.expr);
943                 return E_AND(val1, val2);
944         case E_OR:
945                 val1 = expr_calc_value(e->left.expr);
946                 val2 = expr_calc_value(e->right.expr);
947                 return E_OR(val1, val2);
948         case E_NOT:
949                 val1 = expr_calc_value(e->left.expr);
950                 return E_NOT(val1);
951         case E_EQUAL:
952                 sym_calc_value(e->left.sym);
953                 sym_calc_value(e->right.sym);
954                 str1 = sym_get_string_value(e->left.sym);
955                 str2 = sym_get_string_value(e->right.sym);
956                 return !strcmp(str1, str2) ? yes : no;
957         case E_UNEQUAL:
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);
962                 return !strcmp(str1, str2) ? no : yes;
963         default:
964                 printf("expr_calc_value: %d?\n", e->type);
965                 return no;
966         }
967 }
968
969 int expr_compare_type(enum expr_type t1, enum expr_type t2)
970 {
971 #if 0
972         return 1;
973 #else
974         if (t1 == t2)
975                 return 0;
976         switch (t1) {
977         case E_EQUAL:
978         case E_UNEQUAL:
979                 if (t2 == E_NOT)
980                         return 1;
981         case E_NOT:
982                 if (t2 == E_AND)
983                         return 1;
984         case E_AND:
985                 if (t2 == E_OR)
986                         return 1;
987         case E_OR:
988                 if (t2 == E_CHOICE)
989                         return 1;
990         case E_CHOICE:
991                 if (t2 == 0)
992                         return 1;
993         default:
994                 return -1;
995         }
996         printf("[%dgt%d?]", t1, t2);
997         return 0;
998 #endif
999 }
1000
1001 void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken)
1002 {
1003         if (!e) {
1004                 fn(data, "y");
1005                 return;
1006         }
1007
1008         if (expr_compare_type(prevtoken, e->type) > 0)
1009                 fn(data, "(");
1010         switch (e->type) {
1011         case E_SYMBOL:
1012                 if (e->left.sym->name)
1013                         fn(data, e->left.sym->name);
1014                 else
1015                         fn(data, "<choice>");
1016                 break;
1017         case E_NOT:
1018                 fn(data, "!");
1019                 expr_print(e->left.expr, fn, data, E_NOT);
1020                 break;
1021         case E_EQUAL:
1022                 fn(data, e->left.sym->name);
1023                 fn(data, "=");
1024                 fn(data, e->right.sym->name);
1025                 break;
1026         case E_UNEQUAL:
1027                 fn(data, e->left.sym->name);
1028                 fn(data, "!=");
1029                 fn(data, e->right.sym->name);
1030                 break;
1031         case E_OR:
1032                 expr_print(e->left.expr, fn, data, E_OR);
1033                 fn(data, " || ");
1034                 expr_print(e->right.expr, fn, data, E_OR);
1035                 break;
1036         case E_AND:
1037                 expr_print(e->left.expr, fn, data, E_AND);
1038                 fn(data, " && ");
1039                 expr_print(e->right.expr, fn, data, E_AND);
1040                 break;
1041         case E_CHOICE:
1042                 fn(data, e->right.sym->name);
1043                 if (e->left.expr) {
1044                         fn(data, " ^ ");
1045                         expr_print(e->left.expr, fn, data, E_CHOICE);
1046                 }
1047                 break;
1048         case E_RANGE:
1049                 fn(data, "[");
1050                 fn(data, e->left.sym->name);
1051                 fn(data, " ");
1052                 fn(data, e->right.sym->name);
1053                 fn(data, "]");
1054                 break;
1055         default:
1056           {
1057                 char buf[32];
1058                 sprintf(buf, "<unknown type %d>", e->type);
1059                 fn(data, buf);
1060                 break;
1061           }
1062         }
1063         if (expr_compare_type(prevtoken, e->type) > 0)
1064                 fn(data, ")");
1065 }
1066
1067 static void expr_print_file_helper(void *data, const char *str)
1068 {
1069         fwrite(str, strlen(str), 1, data);
1070 }
1071
1072 void expr_fprint(struct expr *e, FILE *out)
1073 {
1074         expr_print(e, expr_print_file_helper, out, E_NONE);
1075 }
1076
1077 void print_expr(int mask, struct expr *e, int prevtoken)
1078 {
1079         if (!(cdebug & mask))
1080                 return;
1081         expr_fprint(e, stdout);
1082 }
1083