0001
0002
0003
0004
0005
0006 #include <ctype.h>
0007 #include <errno.h>
0008 #include <stdio.h>
0009 #include <stdlib.h>
0010 #include <string.h>
0011
0012 #include "lkc.h"
0013
0014 #define DEBUG_EXPR 0
0015
0016 static struct expr *expr_eliminate_yn(struct expr *e);
0017
0018 struct expr *expr_alloc_symbol(struct symbol *sym)
0019 {
0020 struct expr *e = xcalloc(1, sizeof(*e));
0021 e->type = E_SYMBOL;
0022 e->left.sym = sym;
0023 return e;
0024 }
0025
0026 struct expr *expr_alloc_one(enum expr_type type, struct expr *ce)
0027 {
0028 struct expr *e = xcalloc(1, sizeof(*e));
0029 e->type = type;
0030 e->left.expr = ce;
0031 return e;
0032 }
0033
0034 struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2)
0035 {
0036 struct expr *e = xcalloc(1, sizeof(*e));
0037 e->type = type;
0038 e->left.expr = e1;
0039 e->right.expr = e2;
0040 return e;
0041 }
0042
0043 struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2)
0044 {
0045 struct expr *e = xcalloc(1, sizeof(*e));
0046 e->type = type;
0047 e->left.sym = s1;
0048 e->right.sym = s2;
0049 return e;
0050 }
0051
0052 struct expr *expr_alloc_and(struct expr *e1, struct expr *e2)
0053 {
0054 if (!e1)
0055 return e2;
0056 return e2 ? expr_alloc_two(E_AND, e1, e2) : e1;
0057 }
0058
0059 struct expr *expr_alloc_or(struct expr *e1, struct expr *e2)
0060 {
0061 if (!e1)
0062 return e2;
0063 return e2 ? expr_alloc_two(E_OR, e1, e2) : e1;
0064 }
0065
0066 struct expr *expr_copy(const struct expr *org)
0067 {
0068 struct expr *e;
0069
0070 if (!org)
0071 return NULL;
0072
0073 e = xmalloc(sizeof(*org));
0074 memcpy(e, org, sizeof(*org));
0075 switch (org->type) {
0076 case E_SYMBOL:
0077 e->left = org->left;
0078 break;
0079 case E_NOT:
0080 e->left.expr = expr_copy(org->left.expr);
0081 break;
0082 case E_EQUAL:
0083 case E_GEQ:
0084 case E_GTH:
0085 case E_LEQ:
0086 case E_LTH:
0087 case E_UNEQUAL:
0088 e->left.sym = org->left.sym;
0089 e->right.sym = org->right.sym;
0090 break;
0091 case E_AND:
0092 case E_OR:
0093 case E_LIST:
0094 e->left.expr = expr_copy(org->left.expr);
0095 e->right.expr = expr_copy(org->right.expr);
0096 break;
0097 default:
0098 fprintf(stderr, "can't copy type %d\n", e->type);
0099 free(e);
0100 e = NULL;
0101 break;
0102 }
0103
0104 return e;
0105 }
0106
0107 void expr_free(struct expr *e)
0108 {
0109 if (!e)
0110 return;
0111
0112 switch (e->type) {
0113 case E_SYMBOL:
0114 break;
0115 case E_NOT:
0116 expr_free(e->left.expr);
0117 break;
0118 case E_EQUAL:
0119 case E_GEQ:
0120 case E_GTH:
0121 case E_LEQ:
0122 case E_LTH:
0123 case E_UNEQUAL:
0124 break;
0125 case E_OR:
0126 case E_AND:
0127 expr_free(e->left.expr);
0128 expr_free(e->right.expr);
0129 break;
0130 default:
0131 fprintf(stderr, "how to free type %d?\n", e->type);
0132 break;
0133 }
0134 free(e);
0135 }
0136
0137 static int trans_count;
0138
0139 #define e1 (*ep1)
0140 #define e2 (*ep2)
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2)
0151 {
0152
0153
0154 if (e1->type == type) {
0155 __expr_eliminate_eq(type, &e1->left.expr, &e2);
0156 __expr_eliminate_eq(type, &e1->right.expr, &e2);
0157 return;
0158 }
0159 if (e2->type == type) {
0160 __expr_eliminate_eq(type, &e1, &e2->left.expr);
0161 __expr_eliminate_eq(type, &e1, &e2->right.expr);
0162 return;
0163 }
0164
0165
0166
0167 if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
0168 e1->left.sym == e2->left.sym &&
0169 (e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
0170 return;
0171 if (!expr_eq(e1, e2))
0172 return;
0173
0174
0175
0176 trans_count++;
0177 expr_free(e1); expr_free(e2);
0178 switch (type) {
0179 case E_OR:
0180 e1 = expr_alloc_symbol(&symbol_no);
0181 e2 = expr_alloc_symbol(&symbol_no);
0182 break;
0183 case E_AND:
0184 e1 = expr_alloc_symbol(&symbol_yes);
0185 e2 = expr_alloc_symbol(&symbol_yes);
0186 break;
0187 default:
0188 ;
0189 }
0190 }
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217
0218
0219
0220
0221 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2)
0222 {
0223 if (!e1 || !e2)
0224 return;
0225 switch (e1->type) {
0226 case E_OR:
0227 case E_AND:
0228 __expr_eliminate_eq(e1->type, ep1, ep2);
0229 default:
0230 ;
0231 }
0232 if (e1->type != e2->type) switch (e2->type) {
0233 case E_OR:
0234 case E_AND:
0235 __expr_eliminate_eq(e2->type, ep1, ep2);
0236 default:
0237 ;
0238 }
0239 e1 = expr_eliminate_yn(e1);
0240 e2 = expr_eliminate_yn(e2);
0241 }
0242
0243 #undef e1
0244 #undef e2
0245
0246
0247
0248
0249
0250
0251
0252 int expr_eq(struct expr *e1, struct expr *e2)
0253 {
0254 int res, old_count;
0255
0256
0257
0258
0259
0260 if (!e1 || !e2)
0261 return expr_is_yes(e1) && expr_is_yes(e2);
0262
0263 if (e1->type != e2->type)
0264 return 0;
0265 switch (e1->type) {
0266 case E_EQUAL:
0267 case E_GEQ:
0268 case E_GTH:
0269 case E_LEQ:
0270 case E_LTH:
0271 case E_UNEQUAL:
0272 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym;
0273 case E_SYMBOL:
0274 return e1->left.sym == e2->left.sym;
0275 case E_NOT:
0276 return expr_eq(e1->left.expr, e2->left.expr);
0277 case E_AND:
0278 case E_OR:
0279 e1 = expr_copy(e1);
0280 e2 = expr_copy(e2);
0281 old_count = trans_count;
0282 expr_eliminate_eq(&e1, &e2);
0283 res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
0284 e1->left.sym == e2->left.sym);
0285 expr_free(e1);
0286 expr_free(e2);
0287 trans_count = old_count;
0288 return res;
0289 case E_LIST:
0290 case E_RANGE:
0291 case E_NONE:
0292 ;
0293 }
0294
0295 if (DEBUG_EXPR) {
0296 expr_fprint(e1, stdout);
0297 printf(" = ");
0298 expr_fprint(e2, stdout);
0299 printf(" ?\n");
0300 }
0301
0302 return 0;
0303 }
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316 static struct expr *expr_eliminate_yn(struct expr *e)
0317 {
0318 struct expr *tmp;
0319
0320 if (e) switch (e->type) {
0321 case E_AND:
0322 e->left.expr = expr_eliminate_yn(e->left.expr);
0323 e->right.expr = expr_eliminate_yn(e->right.expr);
0324 if (e->left.expr->type == E_SYMBOL) {
0325 if (e->left.expr->left.sym == &symbol_no) {
0326 expr_free(e->left.expr);
0327 expr_free(e->right.expr);
0328 e->type = E_SYMBOL;
0329 e->left.sym = &symbol_no;
0330 e->right.expr = NULL;
0331 return e;
0332 } else if (e->left.expr->left.sym == &symbol_yes) {
0333 free(e->left.expr);
0334 tmp = e->right.expr;
0335 *e = *(e->right.expr);
0336 free(tmp);
0337 return e;
0338 }
0339 }
0340 if (e->right.expr->type == E_SYMBOL) {
0341 if (e->right.expr->left.sym == &symbol_no) {
0342 expr_free(e->left.expr);
0343 expr_free(e->right.expr);
0344 e->type = E_SYMBOL;
0345 e->left.sym = &symbol_no;
0346 e->right.expr = NULL;
0347 return e;
0348 } else if (e->right.expr->left.sym == &symbol_yes) {
0349 free(e->right.expr);
0350 tmp = e->left.expr;
0351 *e = *(e->left.expr);
0352 free(tmp);
0353 return e;
0354 }
0355 }
0356 break;
0357 case E_OR:
0358 e->left.expr = expr_eliminate_yn(e->left.expr);
0359 e->right.expr = expr_eliminate_yn(e->right.expr);
0360 if (e->left.expr->type == E_SYMBOL) {
0361 if (e->left.expr->left.sym == &symbol_no) {
0362 free(e->left.expr);
0363 tmp = e->right.expr;
0364 *e = *(e->right.expr);
0365 free(tmp);
0366 return e;
0367 } else if (e->left.expr->left.sym == &symbol_yes) {
0368 expr_free(e->left.expr);
0369 expr_free(e->right.expr);
0370 e->type = E_SYMBOL;
0371 e->left.sym = &symbol_yes;
0372 e->right.expr = NULL;
0373 return e;
0374 }
0375 }
0376 if (e->right.expr->type == E_SYMBOL) {
0377 if (e->right.expr->left.sym == &symbol_no) {
0378 free(e->right.expr);
0379 tmp = e->left.expr;
0380 *e = *(e->left.expr);
0381 free(tmp);
0382 return e;
0383 } else if (e->right.expr->left.sym == &symbol_yes) {
0384 expr_free(e->left.expr);
0385 expr_free(e->right.expr);
0386 e->type = E_SYMBOL;
0387 e->left.sym = &symbol_yes;
0388 e->right.expr = NULL;
0389 return e;
0390 }
0391 }
0392 break;
0393 default:
0394 ;
0395 }
0396 return e;
0397 }
0398
0399
0400
0401
0402 struct expr *expr_trans_bool(struct expr *e)
0403 {
0404 if (!e)
0405 return NULL;
0406 switch (e->type) {
0407 case E_AND:
0408 case E_OR:
0409 case E_NOT:
0410 e->left.expr = expr_trans_bool(e->left.expr);
0411 e->right.expr = expr_trans_bool(e->right.expr);
0412 break;
0413 case E_UNEQUAL:
0414
0415 if (e->left.sym->type == S_TRISTATE) {
0416 if (e->right.sym == &symbol_no) {
0417 e->type = E_SYMBOL;
0418 e->right.sym = NULL;
0419 }
0420 }
0421 break;
0422 default:
0423 ;
0424 }
0425 return e;
0426 }
0427
0428
0429
0430
0431 static struct expr *expr_join_or(struct expr *e1, struct expr *e2)
0432 {
0433 struct expr *tmp;
0434 struct symbol *sym1, *sym2;
0435
0436 if (expr_eq(e1, e2))
0437 return expr_copy(e1);
0438 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
0439 return NULL;
0440 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
0441 return NULL;
0442 if (e1->type == E_NOT) {
0443 tmp = e1->left.expr;
0444 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
0445 return NULL;
0446 sym1 = tmp->left.sym;
0447 } else
0448 sym1 = e1->left.sym;
0449 if (e2->type == E_NOT) {
0450 if (e2->left.expr->type != E_SYMBOL)
0451 return NULL;
0452 sym2 = e2->left.expr->left.sym;
0453 } else
0454 sym2 = e2->left.sym;
0455 if (sym1 != sym2)
0456 return NULL;
0457 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
0458 return NULL;
0459 if (sym1->type == S_TRISTATE) {
0460 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
0461 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
0462 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) {
0463
0464 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no);
0465 }
0466 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
0467 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
0468 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) {
0469
0470 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod);
0471 }
0472 if (e1->type == E_EQUAL && e2->type == E_EQUAL &&
0473 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
0474 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) {
0475
0476 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes);
0477 }
0478 }
0479 if (sym1->type == S_BOOLEAN && sym1 == sym2) {
0480 if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) ||
0481 (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL))
0482 return expr_alloc_symbol(&symbol_yes);
0483 }
0484
0485 if (DEBUG_EXPR) {
0486 printf("optimize (");
0487 expr_fprint(e1, stdout);
0488 printf(") || (");
0489 expr_fprint(e2, stdout);
0490 printf(")?\n");
0491 }
0492 return NULL;
0493 }
0494
0495 static struct expr *expr_join_and(struct expr *e1, struct expr *e2)
0496 {
0497 struct expr *tmp;
0498 struct symbol *sym1, *sym2;
0499
0500 if (expr_eq(e1, e2))
0501 return expr_copy(e1);
0502 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT)
0503 return NULL;
0504 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT)
0505 return NULL;
0506 if (e1->type == E_NOT) {
0507 tmp = e1->left.expr;
0508 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL)
0509 return NULL;
0510 sym1 = tmp->left.sym;
0511 } else
0512 sym1 = e1->left.sym;
0513 if (e2->type == E_NOT) {
0514 if (e2->left.expr->type != E_SYMBOL)
0515 return NULL;
0516 sym2 = e2->left.expr->left.sym;
0517 } else
0518 sym2 = e2->left.sym;
0519 if (sym1 != sym2)
0520 return NULL;
0521 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE)
0522 return NULL;
0523
0524 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) ||
0525 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes))
0526
0527 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
0528
0529 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) ||
0530 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no))
0531
0532 return expr_alloc_symbol(sym1);
0533
0534 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_mod) ||
0535 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_mod))
0536
0537 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
0538
0539 if (sym1->type == S_TRISTATE) {
0540 if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) {
0541
0542 sym2 = e1->right.sym;
0543 if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
0544 return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
0545 : expr_alloc_symbol(&symbol_no);
0546 }
0547 if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) {
0548
0549 sym2 = e2->right.sym;
0550 if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST))
0551 return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2)
0552 : expr_alloc_symbol(&symbol_no);
0553 }
0554 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
0555 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) ||
0556 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes)))
0557
0558 return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod);
0559
0560 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
0561 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) ||
0562 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes)))
0563
0564 return expr_alloc_comp(E_EQUAL, sym1, &symbol_no);
0565
0566 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL &&
0567 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) ||
0568 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod)))
0569
0570 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes);
0571
0572 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) ||
0573 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) ||
0574 (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) ||
0575 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes))
0576 return NULL;
0577 }
0578
0579 if (DEBUG_EXPR) {
0580 printf("optimize (");
0581 expr_fprint(e1, stdout);
0582 printf(") && (");
0583 expr_fprint(e2, stdout);
0584 printf(")?\n");
0585 }
0586 return NULL;
0587 }
0588
0589
0590
0591
0592
0593
0594
0595
0596 static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2)
0597 {
0598 #define e1 (*ep1)
0599 #define e2 (*ep2)
0600 struct expr *tmp;
0601
0602
0603
0604 if (e1->type == type) {
0605 expr_eliminate_dups1(type, &e1->left.expr, &e2);
0606 expr_eliminate_dups1(type, &e1->right.expr, &e2);
0607 return;
0608 }
0609 if (e2->type == type) {
0610 expr_eliminate_dups1(type, &e1, &e2->left.expr);
0611 expr_eliminate_dups1(type, &e1, &e2->right.expr);
0612 return;
0613 }
0614
0615
0616
0617 if (e1 == e2)
0618 return;
0619
0620 switch (e1->type) {
0621 case E_OR: case E_AND:
0622 expr_eliminate_dups1(e1->type, &e1, &e1);
0623 default:
0624 ;
0625 }
0626
0627 switch (type) {
0628 case E_OR:
0629 tmp = expr_join_or(e1, e2);
0630 if (tmp) {
0631 expr_free(e1); expr_free(e2);
0632 e1 = expr_alloc_symbol(&symbol_no);
0633 e2 = tmp;
0634 trans_count++;
0635 }
0636 break;
0637 case E_AND:
0638 tmp = expr_join_and(e1, e2);
0639 if (tmp) {
0640 expr_free(e1); expr_free(e2);
0641 e1 = expr_alloc_symbol(&symbol_yes);
0642 e2 = tmp;
0643 trans_count++;
0644 }
0645 break;
0646 default:
0647 ;
0648 }
0649 #undef e1
0650 #undef e2
0651 }
0652
0653
0654
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664 struct expr *expr_eliminate_dups(struct expr *e)
0665 {
0666 int oldcount;
0667 if (!e)
0668 return e;
0669
0670 oldcount = trans_count;
0671 while (1) {
0672 trans_count = 0;
0673 switch (e->type) {
0674 case E_OR: case E_AND:
0675 expr_eliminate_dups1(e->type, &e, &e);
0676 default:
0677 ;
0678 }
0679 if (!trans_count)
0680
0681 break;
0682 e = expr_eliminate_yn(e);
0683 }
0684 trans_count = oldcount;
0685 return e;
0686 }
0687
0688
0689
0690
0691
0692
0693
0694 struct expr *expr_transform(struct expr *e)
0695 {
0696 struct expr *tmp;
0697
0698 if (!e)
0699 return NULL;
0700 switch (e->type) {
0701 case E_EQUAL:
0702 case E_GEQ:
0703 case E_GTH:
0704 case E_LEQ:
0705 case E_LTH:
0706 case E_UNEQUAL:
0707 case E_SYMBOL:
0708 case E_LIST:
0709 break;
0710 default:
0711 e->left.expr = expr_transform(e->left.expr);
0712 e->right.expr = expr_transform(e->right.expr);
0713 }
0714
0715 switch (e->type) {
0716 case E_EQUAL:
0717 if (e->left.sym->type != S_BOOLEAN)
0718 break;
0719 if (e->right.sym == &symbol_no) {
0720 e->type = E_NOT;
0721 e->left.expr = expr_alloc_symbol(e->left.sym);
0722 e->right.sym = NULL;
0723 break;
0724 }
0725 if (e->right.sym == &symbol_mod) {
0726 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name);
0727 e->type = E_SYMBOL;
0728 e->left.sym = &symbol_no;
0729 e->right.sym = NULL;
0730 break;
0731 }
0732 if (e->right.sym == &symbol_yes) {
0733 e->type = E_SYMBOL;
0734 e->right.sym = NULL;
0735 break;
0736 }
0737 break;
0738 case E_UNEQUAL:
0739 if (e->left.sym->type != S_BOOLEAN)
0740 break;
0741 if (e->right.sym == &symbol_no) {
0742 e->type = E_SYMBOL;
0743 e->right.sym = NULL;
0744 break;
0745 }
0746 if (e->right.sym == &symbol_mod) {
0747 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name);
0748 e->type = E_SYMBOL;
0749 e->left.sym = &symbol_yes;
0750 e->right.sym = NULL;
0751 break;
0752 }
0753 if (e->right.sym == &symbol_yes) {
0754 e->type = E_NOT;
0755 e->left.expr = expr_alloc_symbol(e->left.sym);
0756 e->right.sym = NULL;
0757 break;
0758 }
0759 break;
0760 case E_NOT:
0761 switch (e->left.expr->type) {
0762 case E_NOT:
0763
0764 tmp = e->left.expr->left.expr;
0765 free(e->left.expr);
0766 free(e);
0767 e = tmp;
0768 e = expr_transform(e);
0769 break;
0770 case E_EQUAL:
0771 case E_UNEQUAL:
0772
0773 tmp = e->left.expr;
0774 free(e);
0775 e = tmp;
0776 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL;
0777 break;
0778 case E_LEQ:
0779 case E_GEQ:
0780
0781 tmp = e->left.expr;
0782 free(e);
0783 e = tmp;
0784 e->type = e->type == E_LEQ ? E_GTH : E_LTH;
0785 break;
0786 case E_LTH:
0787 case E_GTH:
0788
0789 tmp = e->left.expr;
0790 free(e);
0791 e = tmp;
0792 e->type = e->type == E_LTH ? E_GEQ : E_LEQ;
0793 break;
0794 case E_OR:
0795
0796 tmp = e->left.expr;
0797 e->type = E_AND;
0798 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
0799 tmp->type = E_NOT;
0800 tmp->right.expr = NULL;
0801 e = expr_transform(e);
0802 break;
0803 case E_AND:
0804
0805 tmp = e->left.expr;
0806 e->type = E_OR;
0807 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr);
0808 tmp->type = E_NOT;
0809 tmp->right.expr = NULL;
0810 e = expr_transform(e);
0811 break;
0812 case E_SYMBOL:
0813 if (e->left.expr->left.sym == &symbol_yes) {
0814
0815 tmp = e->left.expr;
0816 free(e);
0817 e = tmp;
0818 e->type = E_SYMBOL;
0819 e->left.sym = &symbol_no;
0820 break;
0821 }
0822 if (e->left.expr->left.sym == &symbol_mod) {
0823
0824 tmp = e->left.expr;
0825 free(e);
0826 e = tmp;
0827 e->type = E_SYMBOL;
0828 e->left.sym = &symbol_mod;
0829 break;
0830 }
0831 if (e->left.expr->left.sym == &symbol_no) {
0832
0833 tmp = e->left.expr;
0834 free(e);
0835 e = tmp;
0836 e->type = E_SYMBOL;
0837 e->left.sym = &symbol_yes;
0838 break;
0839 }
0840 break;
0841 default:
0842 ;
0843 }
0844 break;
0845 default:
0846 ;
0847 }
0848 return e;
0849 }
0850
0851 int expr_contains_symbol(struct expr *dep, struct symbol *sym)
0852 {
0853 if (!dep)
0854 return 0;
0855
0856 switch (dep->type) {
0857 case E_AND:
0858 case E_OR:
0859 return expr_contains_symbol(dep->left.expr, sym) ||
0860 expr_contains_symbol(dep->right.expr, sym);
0861 case E_SYMBOL:
0862 return dep->left.sym == sym;
0863 case E_EQUAL:
0864 case E_GEQ:
0865 case E_GTH:
0866 case E_LEQ:
0867 case E_LTH:
0868 case E_UNEQUAL:
0869 return dep->left.sym == sym ||
0870 dep->right.sym == sym;
0871 case E_NOT:
0872 return expr_contains_symbol(dep->left.expr, sym);
0873 default:
0874 ;
0875 }
0876 return 0;
0877 }
0878
0879 bool expr_depends_symbol(struct expr *dep, struct symbol *sym)
0880 {
0881 if (!dep)
0882 return false;
0883
0884 switch (dep->type) {
0885 case E_AND:
0886 return expr_depends_symbol(dep->left.expr, sym) ||
0887 expr_depends_symbol(dep->right.expr, sym);
0888 case E_SYMBOL:
0889 return dep->left.sym == sym;
0890 case E_EQUAL:
0891 if (dep->left.sym == sym) {
0892 if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod)
0893 return true;
0894 }
0895 break;
0896 case E_UNEQUAL:
0897 if (dep->left.sym == sym) {
0898 if (dep->right.sym == &symbol_no)
0899 return true;
0900 }
0901 break;
0902 default:
0903 ;
0904 }
0905 return false;
0906 }
0907
0908
0909
0910
0911
0912
0913
0914
0915
0916
0917
0918
0919
0920
0921
0922 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym)
0923 {
0924 struct expr *e1, *e2;
0925
0926 if (!e) {
0927 e = expr_alloc_symbol(sym);
0928 if (type == E_UNEQUAL)
0929 e = expr_alloc_one(E_NOT, e);
0930 return e;
0931 }
0932 switch (e->type) {
0933 case E_AND:
0934 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
0935 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
0936 if (sym == &symbol_yes)
0937 e = expr_alloc_two(E_AND, e1, e2);
0938 if (sym == &symbol_no)
0939 e = expr_alloc_two(E_OR, e1, e2);
0940 if (type == E_UNEQUAL)
0941 e = expr_alloc_one(E_NOT, e);
0942 return e;
0943 case E_OR:
0944 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym);
0945 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym);
0946 if (sym == &symbol_yes)
0947 e = expr_alloc_two(E_OR, e1, e2);
0948 if (sym == &symbol_no)
0949 e = expr_alloc_two(E_AND, e1, e2);
0950 if (type == E_UNEQUAL)
0951 e = expr_alloc_one(E_NOT, e);
0952 return e;
0953 case E_NOT:
0954 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym);
0955 case E_UNEQUAL:
0956 case E_LTH:
0957 case E_LEQ:
0958 case E_GTH:
0959 case E_GEQ:
0960 case E_EQUAL:
0961 if (type == E_EQUAL) {
0962 if (sym == &symbol_yes)
0963 return expr_copy(e);
0964 if (sym == &symbol_mod)
0965 return expr_alloc_symbol(&symbol_no);
0966 if (sym == &symbol_no)
0967 return expr_alloc_one(E_NOT, expr_copy(e));
0968 } else {
0969 if (sym == &symbol_yes)
0970 return expr_alloc_one(E_NOT, expr_copy(e));
0971 if (sym == &symbol_mod)
0972 return expr_alloc_symbol(&symbol_yes);
0973 if (sym == &symbol_no)
0974 return expr_copy(e);
0975 }
0976 break;
0977 case E_SYMBOL:
0978 return expr_alloc_comp(type, e->left.sym, sym);
0979 case E_LIST:
0980 case E_RANGE:
0981 case E_NONE:
0982 ;
0983 }
0984 return NULL;
0985 }
0986
0987 enum string_value_kind {
0988 k_string,
0989 k_signed,
0990 k_unsigned,
0991 };
0992
0993 union string_value {
0994 unsigned long long u;
0995 signed long long s;
0996 };
0997
0998 static enum string_value_kind expr_parse_string(const char *str,
0999 enum symbol_type type,
1000 union string_value *val)
1001 {
1002 char *tail;
1003 enum string_value_kind kind;
1004
1005 errno = 0;
1006 switch (type) {
1007 case S_BOOLEAN:
1008 case S_TRISTATE:
1009 val->s = !strcmp(str, "n") ? 0 :
1010 !strcmp(str, "m") ? 1 :
1011 !strcmp(str, "y") ? 2 : -1;
1012 return k_signed;
1013 case S_INT:
1014 val->s = strtoll(str, &tail, 10);
1015 kind = k_signed;
1016 break;
1017 case S_HEX:
1018 val->u = strtoull(str, &tail, 16);
1019 kind = k_unsigned;
1020 break;
1021 default:
1022 val->s = strtoll(str, &tail, 0);
1023 kind = k_signed;
1024 break;
1025 }
1026 return !errno && !*tail && tail > str && isxdigit(tail[-1])
1027 ? kind : k_string;
1028 }
1029
1030 tristate expr_calc_value(struct expr *e)
1031 {
1032 tristate val1, val2;
1033 const char *str1, *str2;
1034 enum string_value_kind k1 = k_string, k2 = k_string;
1035 union string_value lval = {}, rval = {};
1036 int res;
1037
1038 if (!e)
1039 return yes;
1040
1041 switch (e->type) {
1042 case E_SYMBOL:
1043 sym_calc_value(e->left.sym);
1044 return e->left.sym->curr.tri;
1045 case E_AND:
1046 val1 = expr_calc_value(e->left.expr);
1047 val2 = expr_calc_value(e->right.expr);
1048 return EXPR_AND(val1, val2);
1049 case E_OR:
1050 val1 = expr_calc_value(e->left.expr);
1051 val2 = expr_calc_value(e->right.expr);
1052 return EXPR_OR(val1, val2);
1053 case E_NOT:
1054 val1 = expr_calc_value(e->left.expr);
1055 return EXPR_NOT(val1);
1056 case E_EQUAL:
1057 case E_GEQ:
1058 case E_GTH:
1059 case E_LEQ:
1060 case E_LTH:
1061 case E_UNEQUAL:
1062 break;
1063 default:
1064 printf("expr_calc_value: %d?\n", e->type);
1065 return no;
1066 }
1067
1068 sym_calc_value(e->left.sym);
1069 sym_calc_value(e->right.sym);
1070 str1 = sym_get_string_value(e->left.sym);
1071 str2 = sym_get_string_value(e->right.sym);
1072
1073 if (e->left.sym->type != S_STRING || e->right.sym->type != S_STRING) {
1074 k1 = expr_parse_string(str1, e->left.sym->type, &lval);
1075 k2 = expr_parse_string(str2, e->right.sym->type, &rval);
1076 }
1077
1078 if (k1 == k_string || k2 == k_string)
1079 res = strcmp(str1, str2);
1080 else if (k1 == k_unsigned || k2 == k_unsigned)
1081 res = (lval.u > rval.u) - (lval.u < rval.u);
1082 else
1083 res = (lval.s > rval.s) - (lval.s < rval.s);
1084
1085 switch(e->type) {
1086 case E_EQUAL:
1087 return res ? no : yes;
1088 case E_GEQ:
1089 return res >= 0 ? yes : no;
1090 case E_GTH:
1091 return res > 0 ? yes : no;
1092 case E_LEQ:
1093 return res <= 0 ? yes : no;
1094 case E_LTH:
1095 return res < 0 ? yes : no;
1096 case E_UNEQUAL:
1097 return res ? yes : no;
1098 default:
1099 printf("expr_calc_value: relation %d?\n", e->type);
1100 return no;
1101 }
1102 }
1103
1104 static int expr_compare_type(enum expr_type t1, enum expr_type t2)
1105 {
1106 if (t1 == t2)
1107 return 0;
1108 switch (t1) {
1109 case E_LEQ:
1110 case E_LTH:
1111 case E_GEQ:
1112 case E_GTH:
1113 if (t2 == E_EQUAL || t2 == E_UNEQUAL)
1114 return 1;
1115 case E_EQUAL:
1116 case E_UNEQUAL:
1117 if (t2 == E_NOT)
1118 return 1;
1119 case E_NOT:
1120 if (t2 == E_AND)
1121 return 1;
1122 case E_AND:
1123 if (t2 == E_OR)
1124 return 1;
1125 case E_OR:
1126 if (t2 == E_LIST)
1127 return 1;
1128 case E_LIST:
1129 if (t2 == 0)
1130 return 1;
1131 default:
1132 return -1;
1133 }
1134 printf("[%dgt%d?]", t1, t2);
1135 return 0;
1136 }
1137
1138 void expr_print(struct expr *e,
1139 void (*fn)(void *, struct symbol *, const char *),
1140 void *data, int prevtoken)
1141 {
1142 if (!e) {
1143 fn(data, NULL, "y");
1144 return;
1145 }
1146
1147 if (expr_compare_type(prevtoken, e->type) > 0)
1148 fn(data, NULL, "(");
1149 switch (e->type) {
1150 case E_SYMBOL:
1151 if (e->left.sym->name)
1152 fn(data, e->left.sym, e->left.sym->name);
1153 else
1154 fn(data, NULL, "<choice>");
1155 break;
1156 case E_NOT:
1157 fn(data, NULL, "!");
1158 expr_print(e->left.expr, fn, data, E_NOT);
1159 break;
1160 case E_EQUAL:
1161 if (e->left.sym->name)
1162 fn(data, e->left.sym, e->left.sym->name);
1163 else
1164 fn(data, NULL, "<choice>");
1165 fn(data, NULL, "=");
1166 fn(data, e->right.sym, e->right.sym->name);
1167 break;
1168 case E_LEQ:
1169 case E_LTH:
1170 if (e->left.sym->name)
1171 fn(data, e->left.sym, e->left.sym->name);
1172 else
1173 fn(data, NULL, "<choice>");
1174 fn(data, NULL, e->type == E_LEQ ? "<=" : "<");
1175 fn(data, e->right.sym, e->right.sym->name);
1176 break;
1177 case E_GEQ:
1178 case E_GTH:
1179 if (e->left.sym->name)
1180 fn(data, e->left.sym, e->left.sym->name);
1181 else
1182 fn(data, NULL, "<choice>");
1183 fn(data, NULL, e->type == E_GEQ ? ">=" : ">");
1184 fn(data, e->right.sym, e->right.sym->name);
1185 break;
1186 case E_UNEQUAL:
1187 if (e->left.sym->name)
1188 fn(data, e->left.sym, e->left.sym->name);
1189 else
1190 fn(data, NULL, "<choice>");
1191 fn(data, NULL, "!=");
1192 fn(data, e->right.sym, e->right.sym->name);
1193 break;
1194 case E_OR:
1195 expr_print(e->left.expr, fn, data, E_OR);
1196 fn(data, NULL, " || ");
1197 expr_print(e->right.expr, fn, data, E_OR);
1198 break;
1199 case E_AND:
1200 expr_print(e->left.expr, fn, data, E_AND);
1201 fn(data, NULL, " && ");
1202 expr_print(e->right.expr, fn, data, E_AND);
1203 break;
1204 case E_LIST:
1205 fn(data, e->right.sym, e->right.sym->name);
1206 if (e->left.expr) {
1207 fn(data, NULL, " ^ ");
1208 expr_print(e->left.expr, fn, data, E_LIST);
1209 }
1210 break;
1211 case E_RANGE:
1212 fn(data, NULL, "[");
1213 fn(data, e->left.sym, e->left.sym->name);
1214 fn(data, NULL, " ");
1215 fn(data, e->right.sym, e->right.sym->name);
1216 fn(data, NULL, "]");
1217 break;
1218 default:
1219 {
1220 char buf[32];
1221 sprintf(buf, "<unknown type %d>", e->type);
1222 fn(data, NULL, buf);
1223 break;
1224 }
1225 }
1226 if (expr_compare_type(prevtoken, e->type) > 0)
1227 fn(data, NULL, ")");
1228 }
1229
1230 static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
1231 {
1232 xfwrite(str, strlen(str), 1, data);
1233 }
1234
1235 void expr_fprint(struct expr *e, FILE *out)
1236 {
1237 expr_print(e, expr_print_file_helper, out, E_NONE);
1238 }
1239
1240 static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
1241 {
1242 struct gstr *gs = (struct gstr*)data;
1243 const char *sym_str = NULL;
1244
1245 if (sym)
1246 sym_str = sym_get_string_value(sym);
1247
1248 if (gs->max_width) {
1249 unsigned extra_length = strlen(str);
1250 const char *last_cr = strrchr(gs->s, '\n');
1251 unsigned last_line_length;
1252
1253 if (sym_str)
1254 extra_length += 4 + strlen(sym_str);
1255
1256 if (!last_cr)
1257 last_cr = gs->s;
1258
1259 last_line_length = strlen(gs->s) - (last_cr - gs->s);
1260
1261 if ((last_line_length + extra_length) > gs->max_width)
1262 str_append(gs, "\\\n");
1263 }
1264
1265 str_append(gs, str);
1266 if (sym && sym->type != S_UNKNOWN)
1267 str_printf(gs, " [=%s]", sym_str);
1268 }
1269
1270 void expr_gstr_print(struct expr *e, struct gstr *gs)
1271 {
1272 expr_print(e, expr_print_gstr_helper, gs, E_NONE);
1273 }
1274
1275
1276
1277
1278
1279
1280 static void expr_print_revdep(struct expr *e,
1281 void (*fn)(void *, struct symbol *, const char *),
1282 void *data, tristate pr_type, const char **title)
1283 {
1284 if (e->type == E_OR) {
1285 expr_print_revdep(e->left.expr, fn, data, pr_type, title);
1286 expr_print_revdep(e->right.expr, fn, data, pr_type, title);
1287 } else if (expr_calc_value(e) == pr_type) {
1288 if (*title) {
1289 fn(data, NULL, *title);
1290 *title = NULL;
1291 }
1292
1293 fn(data, NULL, " - ");
1294 expr_print(e, fn, data, E_NONE);
1295 fn(data, NULL, "\n");
1296 }
1297 }
1298
1299 void expr_gstr_print_revdep(struct expr *e, struct gstr *gs,
1300 tristate pr_type, const char *title)
1301 {
1302 expr_print_revdep(e, expr_print_gstr_helper, gs, pr_type, &title);
1303 }