This source file includes following definitions.
- expr_alloc_symbol
- expr_alloc_one
- expr_alloc_two
- expr_alloc_comp
- expr_alloc_and
- expr_alloc_or
- expr_copy
- expr_free
- __expr_eliminate_eq
- expr_eliminate_eq
- expr_eq
- expr_eliminate_yn
- expr_trans_bool
- expr_join_or
- expr_join_and
- expr_eliminate_dups1
- expr_eliminate_dups
- expr_transform
- expr_contains_symbol
- expr_depends_symbol
- expr_trans_compare
- expr_parse_string
- expr_calc_value
- expr_compare_type
- expr_print
- expr_print_file_helper
- expr_fprint
- expr_print_gstr_helper
- expr_gstr_print
- expr_print_revdep
- expr_gstr_print_revdep
1
2
3
4
5
6 #include <ctype.h>
7 #include <errno.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include "lkc.h"
13
14 #define DEBUG_EXPR 0
15
16 static int expr_eq(struct expr *e1, struct expr *e2);
17 static struct expr *expr_eliminate_yn(struct expr *e);
18
19 struct expr *expr_alloc_symbol(struct symbol *sym)
20 {
21 struct expr *e = xcalloc(1, sizeof(*e));
22 e->type = E_SYMBOL;
23 e->left.sym = sym;
24 return e;
25 }
26
27 struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
28 {
29 struct expr *e = xcalloc(1, sizeof(*e));
30 e->type = type;
31 e->left.expr = ce;
32 return e;
33 }
34
35 struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
36 {
37 struct expr *e = xcalloc(1, sizeof(*e));
38 e->type = type;
39 e->left.expr = e1;
40 e->right.expr = e2;
41 return e;
42 }
43
44 struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
45 {
46 struct expr *e = xcalloc(1, sizeof(*e));
47 e->type = type;
48 e->left.sym = s1;
49 e->right.sym = s2;
50 return e;
51 }
52
53 struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
54 {
55 if (!e1)
56 return e2;
57 return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
58 }
59
60 struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
61 {
62 if (!e1)
63 return e2;
64 return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
65 }
66
67 struct expr *expr_copy(const struct expr *org)
68 {
69 struct expr *e;
70
71 if (!org)
72 return NULL;
73
74 e = xmalloc(sizeof(*org));
75 memcpy(e, org, sizeof(*org));
76 switch (org->type) {
77 case E_SYMBOL:
78 e->left = org->left;
79 break;
80 case E_NOT:
81 e->left.expr = expr_copy(org->left.expr);
82 break;
83 case E_EQUAL:
84 case E_GEQ:
85 case E_GTH:
86 case E_LEQ:
87 case E_LTH:
88 case E_UNEQUAL:
89 e->left.sym = org->left.sym;
90 e->right.sym = org->right.sym;
91 break;
92 case E_AND:
93 case E_OR:
94 case E_LIST:
95 e->left.expr = expr_copy(org->left.expr);
96 e->right.expr = expr_copy(org->right.expr);
97 break;
98 default:
99 fprintf(stderr, "can't copy type %d\n", e->type);
100 free(e);
101 e = NULL;
102 break;
103 }
104
105 return e;
106 }
107
108 void expr_free(struct expr *e)
109 {
110 if (!e)
111 return;
112
113 switch (e->type) {
114 case E_SYMBOL:
115 break;
116 case E_NOT:
117 expr_free(e->left.expr);
118 break;
119 case E_EQUAL:
120 case E_GEQ:
121 case E_GTH:
122 case E_LEQ:
123 case E_LTH:
124 case E_UNEQUAL:
125 break;
126 case E_OR:
127 case E_AND:
128 expr_free(e->left.expr);
129 expr_free(e->right.expr);
130 break;
131 default:
132 fprintf(stderr, "how to free type %d?\n", e->type);
133 break;
134 }
135 free(e);
136 }
137
138 static int trans_count;
139
140 #define e1 (*ep1)
141 #define e2 (*ep2)
142
143
144
145
146
147
148
149
150
151 static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
152 {
153
154
155 if (e1->type == type) {
156 __expr_eliminate_eq(type, &e1->left.expr, &e2);
157 __expr_eliminate_eq(type, &e1->right.expr, &e2);
158 return;
159 }
160 if (e2->type == type) {
161 __expr_eliminate_eq(type, &e1, &e2->left.expr);
162 __expr_eliminate_eq(type, &e1, &e2->right.expr);
163 return;
164 }
165
166
167
168 if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
169 e1->left.sym == e2->left.sym &&
170 (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
171 return;
172 if (!expr_eq(e1, e2))
173 return;
174
175
176
177 trans_count++;
178 expr_free(e1); expr_free(e2);
179 switch (type) {
180 case E_OR:
181 e1 = expr_alloc_symbol(&symbol_no);
182 e2 = expr_alloc_symbol(&symbol_no);
183 break;
184 case E_AND:
185 e1 = expr_alloc_symbol(&symbol_yes);
186 e2 = expr_alloc_symbol(&symbol_yes);
187 break;
188 default:
189 ;
190 }
191 }
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
223 {
224 if (!e1 || !e2)
225 return;
226 switch (e1->type) {
227 case E_OR:
228 case E_AND:
229 __expr_eliminate_eq(e1->type, ep1, ep2);
230 default:
231 ;
232 }
233 if (e1->type != e2->type) switch (e2->type) {
234 case E_OR:
235 case E_AND:
236 __expr_eliminate_eq(e2->type, ep1, ep2);
237 default:
238 ;
239 }
240 e1 = expr_eliminate_yn(e1);
241 e2 = expr_eliminate_yn(e2);
242 }
243
244 #undef e1
245 #undef e2
246
247
248
249
250
251
252
253 static int expr_eq(struct expr *e1, struct expr *e2)
254 {
255 int res, old_count;
256
257
258
259
260
261 if (!e1 || !e2)
262 return expr_is_yes(e1) && expr_is_yes(e2);
263
264 if (e1->type != e2->type)
265 return 0;
266 switch (e1->type) {
267 case E_EQUAL:
268 case E_GEQ:
269 case E_GTH:
270 case E_LEQ:
271 case E_LTH:
272 case E_UNEQUAL:
273 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
274 case E_SYMBOL:
275 return e1->left.sym == e2->left.sym;
276 case E_NOT:
277 return expr_eq(e1->left.expr, e2->left.expr);
278 case E_AND:
279 case E_OR:
280 e1 = expr_copy(e1);
281 e2 = expr_copy(e2);
282 old_count = trans_count;
283 expr_eliminate_eq(&e1, &e2);
284 res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
285 e1->left.sym == e2->left.sym);
286 expr_free(e1);
287 expr_free(e2);
288 trans_count = old_count;
289 return res;
290 case E_LIST:
291 case E_RANGE:
292 case E_NONE:
293 ;
294 }
295
296 if (DEBUG_EXPR) {
297 expr_fprint(e1, stdout);
298 printf(" = ");
299 expr_fprint(e2, stdout);
300 printf(" ?\n");
301 }
302
303 return 0;
304 }
305
306
307
308
309
310
311
312
313
314
315
316
317 static struct expr *expr_eliminate_yn(struct expr *e)
318 {
319 struct expr *tmp;
320
321 if (e) switch (e->type) {
322 case E_AND:
323 e->left.expr = expr_eliminate_yn(e->left.expr);
324 e->right.expr = expr_eliminate_yn(e->right.expr);
325 if (e->left.expr->type == E_SYMBOL) {
326 if (e->left.expr->left.sym == &symbol_no) {
327 expr_free(e->left.expr);
328 expr_free(e->right.expr);
329 e->type = E_SYMBOL;
330 e->left.sym = &symbol_no;
331 e->right.expr = NULL;
332 return e;
333 } else if (e->left.expr->left.sym == &symbol_yes) {
334 free(e->left.expr);
335 tmp = e->right.expr;
336 *e = *(e->right.expr);
337 free(tmp);
338 return e;
339 }
340 }
341 if (e->right.expr->type == E_SYMBOL) {
342 if (e->right.expr->left.sym == &symbol_no) {
343 expr_free(e->left.expr);
344 expr_free(e->right.expr);
345 e->type = E_SYMBOL;
346 e->left.sym = &symbol_no;
347 e->right.expr = NULL;
348 return e;
349 } else if (e->right.expr->left.sym == &symbol_yes) {
350 free(e->right.expr);
351 tmp = e->left.expr;
352 *e = *(e->left.expr);
353 free(tmp);
354 return e;
355 }
356 }
357 break;
358 case E_OR:
359 e->left.expr = expr_eliminate_yn(e->left.expr);
360 e->right.expr = expr_eliminate_yn(e->right.expr);
361 if (e->left.expr->type == E_SYMBOL) {
362 if (e->left.expr->left.sym == &symbol_no) {
363 free(e->left.expr);
364 tmp = e->right.expr;
365 *e = *(e->right.expr);
366 free(tmp);
367 return e;
368 } else if (e->left.expr->left.sym == &symbol_yes) {
369 expr_free(e->left.expr);
370 expr_free(e->right.expr);
371 e->type = E_SYMBOL;
372 e->left.sym = &symbol_yes;
373 e->right.expr = NULL;
374 return e;
375 }
376 }
377 if (e->right.expr->type == E_SYMBOL) {
378 if (e->right.expr->left.sym == &symbol_no) {
379 free(e->right.expr);
380 tmp = e->left.expr;
381 *e = *(e->left.expr);
382 free(tmp);
383 return e;
384 } else if (e->right.expr->left.sym == &symbol_yes) {
385 expr_free(e->left.expr);
386 expr_free(e->right.expr);
387 e->type = E_SYMBOL;
388 e->left.sym = &symbol_yes;
389 e->right.expr = NULL;
390 return e;
391 }
392 }
393 break;
394 default:
395 ;
396 }
397 return e;
398 }
399
400
401
402
403 struct expr *expr_trans_bool(struct expr *e)
404 {
405 if (!e)
406 return NULL;
407 switch (e->type) {
408 case E_AND:
409 case E_OR:
410 case E_NOT:
411 e->left.expr = expr_trans_bool(e->left.expr);
412 e->right.expr = expr_trans_bool(e->right.expr);
413 break;
414 case E_UNEQUAL:
415
416 if (e->left.sym->type == S_TRISTATE) {
417 if (e->right.sym == &symbol_no) {
418 e->type = E_SYMBOL;
419 e->right.sym = NULL;
420 }
421 }
422 break;
423 default:
424 ;
425 }
426 return e;
427 }
428
429
430
431
432 static struct expr *expr_join_or(struct expr *e1, struct expr *e2)
433 {
434 struct expr *tmp;
435 struct symbol *sym1, *sym2;
436
437 if (expr_eq(e1, e2))
438 return expr_copy(e1);
439 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
440 return NULL;
441 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
442 return NULL;
443 if (e1->type == E_NOT) {
444 tmp = e1->left.expr;
445 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
446 return NULL;
447 sym1 = tmp->left.sym;
448 } else
449 sym1 = e1->left.sym;
450 if (e2->type == E_NOT) {
451 if (e2->left.expr->type != E_SYMBOL)
452 return NULL;
453 sym2 = e2->left.expr->left.sym;
454 } else
455 sym2 = e2->left.sym;
456 if (sym1 != sym2)
457 return NULL;
458 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
459 return NULL;
460 if (sym1->type == S_TRISTATE) {
461 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
462 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
463 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) {
464
465 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no);
466 }
467 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
468 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
469 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) {
470
471 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod);
472 }
473 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
474 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
475 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) {
476
477 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes);
478 }
479 }
480 if (sym1->type == S_BOOLEAN && sym1 == sym2) {
481 if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) ||
482 (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL))
483 return expr_alloc_symbol(&symbol_yes);
484 }
485
486 if (DEBUG_EXPR) {
487 printf("optimize (");
488 expr_fprint(e1, stdout);
489 printf(") || (");
490 expr_fprint(e2, stdout);
491 printf(")?\n");
492 }
493 return NULL;
494 }
495
496 static struct expr *expr_join_and(struct expr *e1, struct expr *e2)
497 {
498 struct expr *tmp;
499 struct symbol *sym1, *sym2;
500
501 if (expr_eq(e1, e2))
502 return expr_copy(e1);
503 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
504 return NULL;
505 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
506 return NULL;
507 if (e1->type == E_NOT) {
508 tmp = e1->left.expr;
509 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
510 return NULL;
511 sym1 = tmp->left.sym;
512 } else
513 sym1 = e1->left.sym;
514 if (e2->type == E_NOT) {
515 if (e2->left.expr->type != E_SYMBOL)
516 return NULL;
517 sym2 = e2->left.expr->left.sym;
518 } else
519 sym2 = e2->left.sym;
520 if (sym1 != sym2)
521 return NULL;
522 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
523 return NULL;
524
525 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
526 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
527
528 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
529
530 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
531 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
532
533 return expr_alloc_symbol(sym1);
534
535 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) ||
536 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod))
537
538 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
539
540 if (sym1->type == S_TRISTATE) {
541 if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
542
543 sym2 = e1->right.sym;
544 if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
545 return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
546 : expr_alloc_symbol(&symbol_no);
547 }
548 if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
549
550 sym2 = e2->right.sym;
551 if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
552 return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
553 : expr_alloc_symbol(&symbol_no);
554 }
555 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
556 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
557 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
558
559 return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
560
561 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
562 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
563 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
564
565 return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
566
567 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
568 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
569 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
570
571 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
572
573 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
574 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
575 (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
576 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
577 return NULL;
578 }
579
580 if (DEBUG_EXPR) {
581 printf("optimize (");
582 expr_fprint(e1, stdout);
583 printf(") && (");
584 expr_fprint(e2, stdout);
585 printf(")?\n");
586 }
587 return NULL;
588 }
589
590
591
592
593
594
595
596
597 static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
598 {
599 #define e1 (*ep1)
600 #define e2 (*ep2)
601 struct expr *tmp;
602
603
604
605 if (e1->type == type) {
606 expr_eliminate_dups1(type, &e1->left.expr, &e2);
607 expr_eliminate_dups1(type, &e1->right.expr, &e2);
608 return;
609 }
610 if (e2->type == type) {
611 expr_eliminate_dups1(type, &e1, &e2->left.expr);
612 expr_eliminate_dups1(type, &e1, &e2->right.expr);
613 return;
614 }
615
616
617
618 if (e1 == e2)
619 return;
620
621 switch (e1->type) {
622 case E_OR: case E_AND:
623 expr_eliminate_dups1(e1->type, &e1, &e1);
624 default:
625 ;
626 }
627
628 switch (type) {
629 case E_OR:
630 tmp = expr_join_or(e1, e2);
631 if (tmp) {
632 expr_free(e1); expr_free(e2);
633 e1 = expr_alloc_symbol(&symbol_no);
634 e2 = tmp;
635 trans_count++;
636 }
637 break;
638 case E_AND:
639 tmp = expr_join_and(e1, e2);
640 if (tmp) {
641 expr_free(e1); expr_free(e2);
642 e1 = expr_alloc_symbol(&symbol_yes);
643 e2 = tmp;
644 trans_count++;
645 }
646 break;
647 default:
648 ;
649 }
650 #undef e1
651 #undef e2
652 }
653
654
655
656
657
658
659
660
661
662
663
664
665 struct expr *expr_eliminate_dups(struct expr *e)
666 {
667 int oldcount;
668 if (!e)
669 return e;
670
671 oldcount = trans_count;
672 while (1) {
673 trans_count = 0;
674 switch (e->type) {
675 case E_OR: case E_AND:
676 expr_eliminate_dups1(e->type, &e, &e);
677 default:
678 ;
679 }
680 if (!trans_count)
681
682 break;
683 e = expr_eliminate_yn(e);
684 }
685 trans_count = oldcount;
686 return e;
687 }
688
689
690
691
692
693
694
695 struct expr *expr_transform(struct expr *e)
696 {
697 struct expr *tmp;
698
699 if (!e)
700 return NULL;
701 switch (e->type) {
702 case E_EQUAL:
703 case E_GEQ:
704 case E_GTH:
705 case E_LEQ:
706 case E_LTH:
707 case E_UNEQUAL:
708 case E_SYMBOL:
709 case E_LIST:
710 break;
711 default:
712 e->left.expr = expr_transform(e->left.expr);
713 e->right.expr = expr_transform(e->right.expr);
714 }
715
716 switch (e->type) {
717 case E_EQUAL:
718 if (e->left.sym->type != S_BOOLEAN)
719 break;
720 if (e->right.sym == &symbol_no) {
721 e->type = E_NOT;
722 e->left.expr = expr_alloc_symbol(e->left.sym);
723 e->right.sym = NULL;
724 break;
725 }
726 if (e->right.sym == &symbol_mod) {
727 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
728 e->type = E_SYMBOL;
729 e->left.sym = &symbol_no;
730 e->right.sym = NULL;
731 break;
732 }
733 if (e->right.sym == &symbol_yes) {
734 e->type = E_SYMBOL;
735 e->right.sym = NULL;
736 break;
737 }
738 break;
739 case E_UNEQUAL:
740 if (e->left.sym->type != S_BOOLEAN)
741 break;
742 if (e->right.sym == &symbol_no) {
743 e->type = E_SYMBOL;
744 e->right.sym = NULL;
745 break;
746 }
747 if (e->right.sym == &symbol_mod) {
748 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
749 e->type = E_SYMBOL;
750 e->left.sym = &symbol_yes;
751 e->right.sym = NULL;
752 break;
753 }
754 if (e->right.sym == &symbol_yes) {
755 e->type = E_NOT;
756 e->left.expr = expr_alloc_symbol(e->left.sym);
757 e->right.sym = NULL;
758 break;
759 }
760 break;
761 case E_NOT:
762 switch (e->left.expr->type) {
763 case E_NOT:
764
765 tmp = e->left.expr->left.expr;
766 free(e->left.expr);
767 free(e);
768 e = tmp;
769 e = expr_transform(e);
770 break;
771 case E_EQUAL:
772 case E_UNEQUAL:
773
774 tmp = e->left.expr;
775 free(e);
776 e = tmp;
777 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
778 break;
779 case E_LEQ:
780 case E_GEQ:
781
782 tmp = e->left.expr;
783 free(e);
784 e = tmp;
785 e->type = e->type == E_LEQ ? E_GTH : E_LTH;
786 break;
787 case E_LTH:
788 case E_GTH:
789
790 tmp = e->left.expr;
791 free(e);
792 e = tmp;
793 e->type = e->type == E_LTH ? E_GEQ : E_LEQ;
794 break;
795 case E_OR:
796
797 tmp = e->left.expr;
798 e->type = E_AND;
799 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
800 tmp->type = E_NOT;
801 tmp->right.expr = NULL;
802 e = expr_transform(e);
803 break;
804 case E_AND:
805
806 tmp = e->left.expr;
807 e->type = E_OR;
808 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
809 tmp->type = E_NOT;
810 tmp->right.expr = NULL;
811 e = expr_transform(e);
812 break;
813 case E_SYMBOL:
814 if (e->left.expr->left.sym == &symbol_yes) {
815
816 tmp = e->left.expr;
817 free(e);
818 e = tmp;
819 e->type = E_SYMBOL;
820 e->left.sym = &symbol_no;
821 break;
822 }
823 if (e->left.expr->left.sym == &symbol_mod) {
824
825 tmp = e->left.expr;
826 free(e);
827 e = tmp;
828 e->type = E_SYMBOL;
829 e->left.sym = &symbol_mod;
830 break;
831 }
832 if (e->left.expr->left.sym == &symbol_no) {
833
834 tmp = e->left.expr;
835 free(e);
836 e = tmp;
837 e->type = E_SYMBOL;
838 e->left.sym = &symbol_yes;
839 break;
840 }
841 break;
842 default:
843 ;
844 }
845 break;
846 default:
847 ;
848 }
849 return e;
850 }
851
852 int expr_contains_symbol(struct expr *dep, struct symbol *sym)
853 {
854 if (!dep)
855 return 0;
856
857 switch (dep->type) {
858 case E_AND:
859 case E_OR:
860 return expr_contains_symbol(dep->left.expr, sym) ||
861 expr_contains_symbol(dep->right.expr, sym);
862 case E_SYMBOL:
863 return dep->left.sym == sym;
864 case E_EQUAL:
865 case E_GEQ:
866 case E_GTH:
867 case E_LEQ:
868 case E_LTH:
869 case E_UNEQUAL:
870 return dep->left.sym == sym ||
871 dep->right.sym == sym;
872 case E_NOT:
873 return expr_contains_symbol(dep->left.expr, sym);
874 default:
875 ;
876 }
877 return 0;
878 }
879
880 bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
881 {
882 if (!dep)
883 return false;
884
885 switch (dep->type) {
886 case E_AND:
887 return expr_depends_symbol(dep->left.expr, sym) ||
888 expr_depends_symbol(dep->right.expr, sym);
889 case E_SYMBOL:
890 return dep->left.sym == sym;
891 case E_EQUAL:
892 if (dep->left.sym == sym) {
893 if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
894 return true;
895 }
896 break;
897 case E_UNEQUAL:
898 if (dep->left.sym == sym) {
899 if (dep->right.sym == &symbol_no)
900 return true;
901 }
902 break;
903 default:
904 ;
905 }
906 return false;
907 }
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
924 {
925 struct expr *e1, *e2;
926
927 if (!e) {
928 e = expr_alloc_symbol(sym);
929 if (type == E_UNEQUAL)
930 e = expr_alloc_one(E_NOT, e);
931 return e;
932 }
933 switch (e->type) {
934 case E_AND:
935 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
936 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
937 if (sym == &symbol_yes)
938 e = expr_alloc_two(E_AND, e1, e2);
939 if (sym == &symbol_no)
940 e = expr_alloc_two(E_OR, e1, e2);
941 if (type == E_UNEQUAL)
942 e = expr_alloc_one(E_NOT, e);
943 return e;
944 case E_OR:
945 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
946 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
947 if (sym == &symbol_yes)
948 e = expr_alloc_two(E_OR, e1, e2);
949 if (sym == &symbol_no)
950 e = expr_alloc_two(E_AND, e1, e2);
951 if (type == E_UNEQUAL)
952 e = expr_alloc_one(E_NOT, e);
953 return e;
954 case E_NOT:
955 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
956 case E_UNEQUAL:
957 case E_LTH:
958 case E_LEQ:
959 case E_GTH:
960 case E_GEQ:
961 case E_EQUAL:
962 if (type == E_EQUAL) {
963 if (sym == &symbol_yes)
964 return expr_copy(e);
965 if (sym == &symbol_mod)
966 return expr_alloc_symbol(&symbol_no);
967 if (sym == &symbol_no)
968 return expr_alloc_one(E_NOT, expr_copy(e));
969 } else {
970 if (sym == &symbol_yes)
971 return expr_alloc_one(E_NOT, expr_copy(e));
972 if (sym == &symbol_mod)
973 return expr_alloc_symbol(&symbol_yes);
974 if (sym == &symbol_no)
975 return expr_copy(e);
976 }
977 break;
978 case E_SYMBOL:
979 return expr_alloc_comp(type, e->left.sym, sym);
980 case E_LIST:
981 case E_RANGE:
982 case E_NONE:
983 ;
984 }
985 return NULL;
986 }
987
988 enum string_value_kind {
989 k_string,
990 k_signed,
991 k_unsigned,
992 };
993
994 union string_value {
995 unsigned long long u;
996 signed long long s;
997 };
998
999 static enum string_value_kind expr_parse_string(const char *str,
1000 enum symbol_type type,
1001 union string_value *val)
1002 {
1003 char *tail;
1004 enum string_value_kind kind;
1005
1006 errno = 0;
1007 switch (type) {
1008 case S_BOOLEAN:
1009 case S_TRISTATE:
1010 val->s = !strcmp(str, "n") ? 0 :
1011 !strcmp(str, "m") ? 1 :
1012 !strcmp(str, "y") ? 2 : -1;
1013 return k_signed;
1014 case S_INT:
1015 val->s = strtoll(str, &tail, 10);
1016 kind = k_signed;
1017 break;
1018 case S_HEX:
1019 val->u = strtoull(str, &tail, 16);
1020 kind = k_unsigned;
1021 break;
1022 default:
1023 val->s = strtoll(str, &tail, 0);
1024 kind = k_signed;
1025 break;
1026 }
1027 return !errno && !*tail && tail > str && isxdigit(tail[-1])
1028 ? kind : k_string;
1029 }
1030
1031 tristate expr_calc_value(struct expr *e)
1032 {
1033 tristate val1, val2;
1034 const char *str1, *str2;
1035 enum string_value_kind k1 = k_string, k2 = k_string;
1036 union string_value lval = {}, rval = {};
1037 int res;
1038
1039 if (!e)
1040 return yes;
1041
1042 switch (e->type) {
1043 case E_SYMBOL:
1044 sym_calc_value(e->left.sym);
1045 return e->left.sym->curr.tri;
1046 case E_AND:
1047 val1 = expr_calc_value(e->left.expr);
1048 val2 = expr_calc_value(e->right.expr);
1049 return EXPR_AND(val1, val2);
1050 case E_OR:
1051 val1 = expr_calc_value(e->left.expr);
1052 val2 = expr_calc_value(e->right.expr);
1053 return EXPR_OR(val1, val2);
1054 case E_NOT:
1055 val1 = expr_calc_value(e->left.expr);
1056 return EXPR_NOT(val1);
1057 case E_EQUAL:
1058 case E_GEQ:
1059 case E_GTH:
1060 case E_LEQ:
1061 case E_LTH:
1062 case E_UNEQUAL:
1063 break;
1064 default:
1065 printf("expr_calc_value: %d?\n", e->type);
1066 return no;
1067 }
1068
1069 sym_calc_value(e->left.sym);
1070 sym_calc_value(e->right.sym);
1071 str1 = sym_get_string_value(e->left.sym);
1072 str2 = sym_get_string_value(e->right.sym);
1073
1074 if (e->left.sym->type != S_STRING || e->right.sym->type != S_STRING) {
1075 k1 = expr_parse_string(str1, e->left.sym->type, &lval);
1076 k2 = expr_parse_string(str2, e->right.sym->type, &rval);
1077 }
1078
1079 if (k1 == k_string || k2 == k_string)
1080 res = strcmp(str1, str2);
1081 else if (k1 == k_unsigned || k2 == k_unsigned)
1082 res = (lval.u > rval.u) - (lval.u < rval.u);
1083 else
1084 res = (lval.s > rval.s) - (lval.s < rval.s);
1085
1086 switch(e->type) {
1087 case E_EQUAL:
1088 return res ? no : yes;
1089 case E_GEQ:
1090 return res >= 0 ? yes : no;
1091 case E_GTH:
1092 return res > 0 ? yes : no;
1093 case E_LEQ:
1094 return res <= 0 ? yes : no;
1095 case E_LTH:
1096 return res < 0 ? yes : no;
1097 case E_UNEQUAL:
1098 return res ? yes : no;
1099 default:
1100 printf("expr_calc_value: relation %d?\n", e->type);
1101 return no;
1102 }
1103 }
1104
1105 static int expr_compare_type(enum expr_type t1, enum expr_type t2)
1106 {
1107 if (t1 == t2)
1108 return 0;
1109 switch (t1) {
1110 case E_LEQ:
1111 case E_LTH:
1112 case E_GEQ:
1113 case E_GTH:
1114 if (t2 == E_EQUAL || t2 == E_UNEQUAL)
1115 return 1;
1116 case E_EQUAL:
1117 case E_UNEQUAL:
1118 if (t2 == E_NOT)
1119 return 1;
1120 case E_NOT:
1121 if (t2 == E_AND)
1122 return 1;
1123 case E_AND:
1124 if (t2 == E_OR)
1125 return 1;
1126 case E_OR:
1127 if (t2 == E_LIST)
1128 return 1;
1129 case E_LIST:
1130 if (t2 == 0)
1131 return 1;
1132 default:
1133 return -1;
1134 }
1135 printf("[%dgt%d?]", t1, t2);
1136 return 0;
1137 }
1138
1139 void expr_print(struct expr *e,
1140 void (*fn)(void *, struct symbol *, const char *),
1141 void *data, int prevtoken)
1142 {
1143 if (!e) {
1144 fn(data, NULL, "y");
1145 return;
1146 }
1147
1148 if (expr_compare_type(prevtoken, e->type) > 0)
1149 fn(data, NULL, "(");
1150 switch (e->type) {
1151 case E_SYMBOL:
1152 if (e->left.sym->name)
1153 fn(data, e->left.sym, e->left.sym->name);
1154 else
1155 fn(data, NULL, "<choice>");
1156 break;
1157 case E_NOT:
1158 fn(data, NULL, "!");
1159 expr_print(e->left.expr, fn, data, E_NOT);
1160 break;
1161 case E_EQUAL:
1162 if (e->left.sym->name)
1163 fn(data, e->left.sym, e->left.sym->name);
1164 else
1165 fn(data, NULL, "<choice>");
1166 fn(data, NULL, "=");
1167 fn(data, e->right.sym, e->right.sym->name);
1168 break;
1169 case E_LEQ:
1170 case E_LTH:
1171 if (e->left.sym->name)
1172 fn(data, e->left.sym, e->left.sym->name);
1173 else
1174 fn(data, NULL, "<choice>");
1175 fn(data, NULL, e->type == E_LEQ ? "<=" : "<");
1176 fn(data, e->right.sym, e->right.sym->name);
1177 break;
1178 case E_GEQ:
1179 case E_GTH:
1180 if (e->left.sym->name)
1181 fn(data, e->left.sym, e->left.sym->name);
1182 else
1183 fn(data, NULL, "<choice>");
1184 fn(data, NULL, e->type == E_GEQ ? ">=" : ">");
1185 fn(data, e->right.sym, e->right.sym->name);
1186 break;
1187 case E_UNEQUAL:
1188 if (e->left.sym->name)
1189 fn(data, e->left.sym, e->left.sym->name);
1190 else
1191 fn(data, NULL, "<choice>");
1192 fn(data, NULL, "!=");
1193 fn(data, e->right.sym, e->right.sym->name);
1194 break;
1195 case E_OR:
1196 expr_print(e->left.expr, fn, data, E_OR);
1197 fn(data, NULL, " || ");
1198 expr_print(e->right.expr, fn, data, E_OR);
1199 break;
1200 case E_AND:
1201 expr_print(e->left.expr, fn, data, E_AND);
1202 fn(data, NULL, " && ");
1203 expr_print(e->right.expr, fn, data, E_AND);
1204 break;
1205 case E_LIST:
1206 fn(data, e->right.sym, e->right.sym->name);
1207 if (e->left.expr) {
1208 fn(data, NULL, " ^ ");
1209 expr_print(e->left.expr, fn, data, E_LIST);
1210 }
1211 break;
1212 case E_RANGE:
1213 fn(data, NULL, "[");
1214 fn(data, e->left.sym, e->left.sym->name);
1215 fn(data, NULL, " ");
1216 fn(data, e->right.sym, e->right.sym->name);
1217 fn(data, NULL, "]");
1218 break;
1219 default:
1220 {
1221 char buf[32];
1222 sprintf(buf, "<unknown type %d>", e->type);
1223 fn(data, NULL, buf);
1224 break;
1225 }
1226 }
1227 if (expr_compare_type(prevtoken, e->type) > 0)
1228 fn(data, NULL, ")");
1229 }
1230
1231 static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
1232 {
1233 xfwrite(str, strlen(str), 1, data);
1234 }
1235
1236 void expr_fprint(struct expr *e, FILE *out)
1237 {
1238 expr_print(e, expr_print_file_helper, out, E_NONE);
1239 }
1240
1241 static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
1242 {
1243 struct gstr *gs = (struct gstr*)data;
1244 const char *sym_str = NULL;
1245
1246 if (sym)
1247 sym_str = sym_get_string_value(sym);
1248
1249 if (gs->max_width) {
1250 unsigned extra_length = strlen(str);
1251 const char *last_cr = strrchr(gs->s, '\n');
1252 unsigned last_line_length;
1253
1254 if (sym_str)
1255 extra_length += 4 + strlen(sym_str);
1256
1257 if (!last_cr)
1258 last_cr = gs->s;
1259
1260 last_line_length = strlen(gs->s) - (last_cr - gs->s);
1261
1262 if ((last_line_length + extra_length) > gs->max_width)
1263 str_append(gs, "\\\n");
1264 }
1265
1266 str_append(gs, str);
1267 if (sym && sym->type != S_UNKNOWN)
1268 str_printf(gs, " [=%s]", sym_str);
1269 }
1270
1271 void expr_gstr_print(struct expr *e, struct gstr *gs)
1272 {
1273 expr_print(e, expr_print_gstr_helper, gs, E_NONE);
1274 }
1275
1276
1277
1278
1279
1280
1281 static void expr_print_revdep(struct expr *e,
1282 void (*fn)(void *, struct symbol *, const char *),
1283 void *data, tristate pr_type, const char **title)
1284 {
1285 if (e->type == E_OR) {
1286 expr_print_revdep(e->left.expr, fn, data, pr_type, title);
1287 expr_print_revdep(e->right.expr, fn, data, pr_type, title);
1288 } else if (expr_calc_value(e) == pr_type) {
1289 if (*title) {
1290 fn(data, NULL, *title);
1291 *title = NULL;
1292 }
1293
1294 fn(data, NULL, " - ");
1295 expr_print(e, fn, data, E_NONE);
1296 fn(data, NULL, "\n");
1297 }
1298 }
1299
1300 void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
1301 tristate pr_type, const char *title)
1302 {
1303 expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title);
1304 }