base/config/kconfig/expr.c

Go to the documentation of this file.
00001 /* 00002 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 00003 * Released under the terms of the GNU GPL v2.0. 00004 */ 00005 00006 #include <stdio.h> 00007 #include <stdlib.h> 00008 #include <string.h> 00009 00010 #define LKC_DIRECT_LINK 00011 #include "lkc.h" 00012 00013 struct expr *expr_alloc_symbol(struct symbol *sym) 00014 { 00015 struct expr *e = malloc(sizeof(*e)); 00016 memset(e, 0, sizeof(*e)); 00017 e->type = E_SYMBOL; 00018 e->left.sym = sym; 00019 return e; 00020 } 00021 00022 struct expr *expr_alloc_one(enum expr_type type, struct expr *ce) 00023 { 00024 struct expr *e = malloc(sizeof(*e)); 00025 memset(e, 0, sizeof(*e)); 00026 e->type = type; 00027 e->left.expr = ce; 00028 return e; 00029 } 00030 00031 struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e2) 00032 { 00033 struct expr *e = malloc(sizeof(*e)); 00034 memset(e, 0, sizeof(*e)); 00035 e->type = type; 00036 e->left.expr = e1; 00037 e->right.expr = e2; 00038 return e; 00039 } 00040 00041 struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2) 00042 { 00043 struct expr *e = malloc(sizeof(*e)); 00044 memset(e, 0, sizeof(*e)); 00045 e->type = type; 00046 e->left.sym = s1; 00047 e->right.sym = s2; 00048 return e; 00049 } 00050 00051 struct expr *expr_alloc_and(struct expr *e1, struct expr *e2) 00052 { 00053 if (!e1) 00054 return e2; 00055 return e2 ? expr_alloc_two(E_AND, e1, e2) : e1; 00056 } 00057 00058 struct expr *expr_alloc_or(struct expr *e1, struct expr *e2) 00059 { 00060 if (!e1) 00061 return e2; 00062 return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; 00063 } 00064 00065 struct expr *expr_copy(struct expr *org) 00066 { 00067 struct expr *e; 00068 00069 if (!org) 00070 return NULL; 00071 00072 e = malloc(sizeof(*org)); 00073 memcpy(e, org, sizeof(*org)); 00074 switch (org->type) { 00075 case E_SYMBOL: 00076 e->left = org->left; 00077 break; 00078 case E_NOT: 00079 e->left.expr = expr_copy(org->left.expr); 00080 break; 00081 case E_EQUAL: 00082 case E_UNEQUAL: 00083 e->left.sym = org->left.sym; 00084 e->right.sym = org->right.sym; 00085 break; 00086 case E_AND: 00087 case E_OR: 00088 case E_CHOICE: 00089 e->left.expr = expr_copy(org->left.expr); 00090 e->right.expr = expr_copy(org->right.expr); 00091 break; 00092 default: 00093 printf("can't copy type %d\n", e->type); 00094 free(e); 00095 e = NULL; 00096 break; 00097 } 00098 00099 return e; 00100 } 00101 00102 void expr_free(struct expr *e) 00103 { 00104 if (!e) 00105 return; 00106 00107 switch (e->type) { 00108 case E_SYMBOL: 00109 break; 00110 case E_NOT: 00111 expr_free(e->left.expr); 00112 return; 00113 case E_EQUAL: 00114 case E_UNEQUAL: 00115 break; 00116 case E_OR: 00117 case E_AND: 00118 expr_free(e->left.expr); 00119 expr_free(e->right.expr); 00120 break; 00121 default: 00122 printf("how to free type %d?\n", e->type); 00123 break; 00124 } 00125 free(e); 00126 } 00127 00128 static int trans_count; 00129 00130 #define e1 (*ep1) 00131 #define e2 (*ep2) 00132 00133 static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct expr **ep2) 00134 { 00135 if (e1->type == type) { 00136 __expr_eliminate_eq(type, &e1->left.expr, &e2); 00137 __expr_eliminate_eq(type, &e1->right.expr, &e2); 00138 return; 00139 } 00140 if (e2->type == type) { 00141 __expr_eliminate_eq(type, &e1, &e2->left.expr); 00142 __expr_eliminate_eq(type, &e1, &e2->right.expr); 00143 return; 00144 } 00145 if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && 00146 e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO))) 00147 return; 00148 if (!expr_eq(e1, e2)) 00149 return; 00150 trans_count++; 00151 expr_free(e1); expr_free(e2); 00152 switch (type) { 00153 case E_OR: 00154 e1 = expr_alloc_symbol(&symbol_no); 00155 e2 = expr_alloc_symbol(&symbol_no); 00156 break; 00157 case E_AND: 00158 e1 = expr_alloc_symbol(&symbol_yes); 00159 e2 = expr_alloc_symbol(&symbol_yes); 00160 break; 00161 default: 00162 ; 00163 } 00164 } 00165 00166 void expr_eliminate_eq(struct expr **ep1, struct expr **ep2) 00167 { 00168 if (!e1 || !e2) 00169 return; 00170 switch (e1->type) { 00171 case E_OR: 00172 case E_AND: 00173 __expr_eliminate_eq(e1->type, ep1, ep2); 00174 default: 00175 ; 00176 } 00177 if (e1->type != e2->type) switch (e2->type) { 00178 case E_OR: 00179 case E_AND: 00180 __expr_eliminate_eq(e2->type, ep1, ep2); 00181 default: 00182 ; 00183 } 00184 e1 = expr_eliminate_yn(e1); 00185 e2 = expr_eliminate_yn(e2); 00186 } 00187 00188 #undef e1 00189 #undef e2 00190 00191 int expr_eq(struct expr *e1, struct expr *e2) 00192 { 00193 int res, old_count; 00194 00195 if (e1->type != e2->type) 00196 return 0; 00197 switch (e1->type) { 00198 case E_EQUAL: 00199 case E_UNEQUAL: 00200 return e1->left.sym == e2->left.sym && e1->right.sym == e2->right.sym; 00201 case E_SYMBOL: 00202 return e1->left.sym == e2->left.sym; 00203 case E_NOT: 00204 return expr_eq(e1->left.expr, e2->left.expr); 00205 case E_AND: 00206 case E_OR: 00207 e1 = expr_copy(e1); 00208 e2 = expr_copy(e2); 00209 old_count = trans_count; 00210 expr_eliminate_eq(&e1, &e2); 00211 res = (e1->type == E_SYMBOL && e2->type == E_SYMBOL && 00212 e1->left.sym == e2->left.sym); 00213 expr_free(e1); 00214 expr_free(e2); 00215 trans_count = old_count; 00216 return res; 00217 case E_CHOICE: 00218 case E_RANGE: 00219 case E_NONE: 00220 /* panic */; 00221 } 00222 00223 print_expr(0, e1, 0); 00224 printf(" = "); 00225 print_expr(0, e2, 0); 00226 printf(" ?\n"); 00227 00228 return 0; 00229 } 00230 00231 struct expr *expr_eliminate_yn(struct expr *e) 00232 { 00233 struct expr *tmp; 00234 00235 if (e) switch (e->type) { 00236 case E_AND: 00237 e->left.expr = expr_eliminate_yn(e->left.expr); 00238 e->right.expr = expr_eliminate_yn(e->right.expr); 00239 if (e->left.expr->type == E_SYMBOL) { 00240 if (e->left.expr->left.sym == &symbol_no) { 00241 expr_free(e->left.expr); 00242 expr_free(e->right.expr); 00243 e->type = E_SYMBOL; 00244 e->left.sym = &symbol_no; 00245 e->right.expr = NULL; 00246 return e; 00247 } else if (e->left.expr->left.sym == &symbol_yes) { 00248 free(e->left.expr); 00249 tmp = e->right.expr; 00250 *e = *(e->right.expr); 00251 free(tmp); 00252 return e; 00253 } 00254 } 00255 if (e->right.expr->type == E_SYMBOL) { 00256 if (e->right.expr->left.sym == &symbol_no) { 00257 expr_free(e->left.expr); 00258 expr_free(e->right.expr); 00259 e->type = E_SYMBOL; 00260 e->left.sym = &symbol_no; 00261 e->right.expr = NULL; 00262 return e; 00263 } else if (e->right.expr->left.sym == &symbol_yes) { 00264 free(e->right.expr); 00265 tmp = e->left.expr; 00266 *e = *(e->left.expr); 00267 free(tmp); 00268 return e; 00269 } 00270 } 00271 break; 00272 case E_OR: 00273 e->left.expr = expr_eliminate_yn(e->left.expr); 00274 e->right.expr = expr_eliminate_yn(e->right.expr); 00275 if (e->left.expr->type == E_SYMBOL) { 00276 if (e->left.expr->left.sym == &symbol_no) { 00277 free(e->left.expr); 00278 tmp = e->right.expr; 00279 *e = *(e->right.expr); 00280 free(tmp); 00281 return e; 00282 } else if (e->left.expr->left.sym == &symbol_yes) { 00283 expr_free(e->left.expr); 00284 expr_free(e->right.expr); 00285 e->type = E_SYMBOL; 00286 e->left.sym = &symbol_yes; 00287 e->right.expr = NULL; 00288 return e; 00289 } 00290 } 00291 if (e->right.expr->type == E_SYMBOL) { 00292 if (e->right.expr->left.sym == &symbol_no) { 00293 free(e->right.expr); 00294 tmp = e->left.expr; 00295 *e = *(e->left.expr); 00296 free(tmp); 00297 return e; 00298 } else if (e->right.expr->left.sym == &symbol_yes) { 00299 expr_free(e->left.expr); 00300 expr_free(e->right.expr); 00301 e->type = E_SYMBOL; 00302 e->left.sym = &symbol_yes; 00303 e->right.expr = NULL; 00304 return e; 00305 } 00306 } 00307 break; 00308 default: 00309 ; 00310 } 00311 return e; 00312 } 00313 00314 /* 00315 * bool FOO!=n => FOO 00316 */ 00317 struct expr *expr_trans_bool(struct expr *e) 00318 { 00319 if (!e) 00320 return NULL; 00321 switch (e->type) { 00322 case E_AND: 00323 case E_OR: 00324 case E_NOT: 00325 e->left.expr = expr_trans_bool(e->left.expr); 00326 e->right.expr = expr_trans_bool(e->right.expr); 00327 break; 00328 case E_UNEQUAL: 00329 // FOO!=n -> FOO 00330 if (e->left.sym->type == S_TRISTATE) { 00331 if (e->right.sym == &symbol_no) { 00332 e->type = E_SYMBOL; 00333 e->right.sym = NULL; 00334 } 00335 } 00336 break; 00337 default: 00338 ; 00339 } 00340 return e; 00341 } 00342 00343 /* 00344 * e1 || e2 -> ? 00345 */ 00346 struct expr *expr_join_or(struct expr *e1, struct expr *e2) 00347 { 00348 struct expr *tmp; 00349 struct symbol *sym1, *sym2; 00350 00351 if (expr_eq(e1, e2)) 00352 return expr_copy(e1); 00353 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) 00354 return NULL; 00355 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) 00356 return NULL; 00357 if (e1->type == E_NOT) { 00358 tmp = e1->left.expr; 00359 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) 00360 return NULL; 00361 sym1 = tmp->left.sym; 00362 } else 00363 sym1 = e1->left.sym; 00364 if (e2->type == E_NOT) { 00365 if (e2->left.expr->type != E_SYMBOL) 00366 return NULL; 00367 sym2 = e2->left.expr->left.sym; 00368 } else 00369 sym2 = e2->left.sym; 00370 if (sym1 != sym2) 00371 return NULL; 00372 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) 00373 return NULL; 00374 if (sym1->type == S_TRISTATE) { 00375 if (e1->type == E_EQUAL && e2->type == E_EQUAL && 00376 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || 00377 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) { 00378 // (a='y') || (a='m') -> (a!='n') 00379 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_no); 00380 } 00381 if (e1->type == E_EQUAL && e2->type == E_EQUAL && 00382 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || 00383 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) { 00384 // (a='y') || (a='n') -> (a!='m') 00385 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_mod); 00386 } 00387 if (e1->type == E_EQUAL && e2->type == E_EQUAL && 00388 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || 00389 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) { 00390 // (a='m') || (a='n') -> (a!='y') 00391 return expr_alloc_comp(E_UNEQUAL, sym1, &symbol_yes); 00392 } 00393 } 00394 if (sym1->type == S_BOOLEAN && sym1 == sym2) { 00395 if ((e1->type == E_NOT && e1->left.expr->type == E_SYMBOL && e2->type == E_SYMBOL) || 00396 (e2->type == E_NOT && e2->left.expr->type == E_SYMBOL && e1->type == E_SYMBOL)) 00397 return expr_alloc_symbol(&symbol_yes); 00398 } 00399 00400 printf("optimize "); 00401 print_expr(0, e1, 0); 00402 printf(" || "); 00403 print_expr(0, e2, 0); 00404 printf(" ?\n"); 00405 return NULL; 00406 } 00407 00408 struct expr *expr_join_and(struct expr *e1, struct expr *e2) 00409 { 00410 struct expr *tmp; 00411 struct symbol *sym1, *sym2; 00412 00413 if (expr_eq(e1, e2)) 00414 return expr_copy(e1); 00415 if (e1->type != E_EQUAL && e1->type != E_UNEQUAL && e1->type != E_SYMBOL && e1->type != E_NOT) 00416 return NULL; 00417 if (e2->type != E_EQUAL && e2->type != E_UNEQUAL && e2->type != E_SYMBOL && e2->type != E_NOT) 00418 return NULL; 00419 if (e1->type == E_NOT) { 00420 tmp = e1->left.expr; 00421 if (tmp->type != E_EQUAL && tmp->type != E_UNEQUAL && tmp->type != E_SYMBOL) 00422 return NULL; 00423 sym1 = tmp->left.sym; 00424 } else 00425 sym1 = e1->left.sym; 00426 if (e2->type == E_NOT) { 00427 if (e2->left.expr->type != E_SYMBOL) 00428 return NULL; 00429 sym2 = e2->left.expr->left.sym; 00430 } else 00431 sym2 = e2->left.sym; 00432 if (sym1 != sym2) 00433 return NULL; 00434 if (sym1->type != S_BOOLEAN && sym1->type != S_TRISTATE) 00435 return NULL; 00436 00437 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_yes) || 00438 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_yes)) 00439 // (a) && (a='y') -> (a='y') 00440 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); 00441 00442 if ((e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_no) || 00443 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_no)) 00444 // (a) && (a!='n') -> (a) 00445 return expr_alloc_symbol(sym1); 00446 00447 if (sym1->type == S_TRISTATE) { 00448 if (e1->type == E_EQUAL && e2->type == E_UNEQUAL) { 00449 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' 00450 sym2 = e1->right.sym; 00451 if ((e2->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) 00452 return sym2 != e2->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) 00453 : expr_alloc_symbol(&symbol_no); 00454 } 00455 if (e1->type == E_UNEQUAL && e2->type == E_EQUAL) { 00456 // (a='b') && (a!='c') -> 'b'='c' ? 'n' : a='b' 00457 sym2 = e2->right.sym; 00458 if ((e1->right.sym->flags & SYMBOL_CONST) && (sym2->flags & SYMBOL_CONST)) 00459 return sym2 != e1->right.sym ? expr_alloc_comp(E_EQUAL, sym1, sym2) 00460 : expr_alloc_symbol(&symbol_no); 00461 } 00462 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && 00463 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_no) || 00464 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_yes))) 00465 // (a!='y') && (a!='n') -> (a='m') 00466 return expr_alloc_comp(E_EQUAL, sym1, &symbol_mod); 00467 00468 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && 00469 ((e1->right.sym == &symbol_yes && e2->right.sym == &symbol_mod) || 00470 (e1->right.sym == &symbol_mod && e2->right.sym == &symbol_yes))) 00471 // (a!='y') && (a!='m') -> (a='n') 00472 return expr_alloc_comp(E_EQUAL, sym1, &symbol_no); 00473 00474 if (e1->type == E_UNEQUAL && e2->type == E_UNEQUAL && 00475 ((e1->right.sym == &symbol_mod && e2->right.sym == &symbol_no) || 00476 (e1->right.sym == &symbol_no && e2->right.sym == &symbol_mod))) 00477 // (a!='m') && (a!='n') -> (a='m') 00478 return expr_alloc_comp(E_EQUAL, sym1, &symbol_yes); 00479 00480 if ((e1->type == E_SYMBOL && e2->type == E_EQUAL && e2->right.sym == &symbol_mod) || 00481 (e2->type == E_SYMBOL && e1->type == E_EQUAL && e1->right.sym == &symbol_mod) || 00482 (e1->type == E_SYMBOL && e2->type == E_UNEQUAL && e2->right.sym == &symbol_yes) || 00483 (e2->type == E_SYMBOL && e1->type == E_UNEQUAL && e1->right.sym == &symbol_yes)) 00484 return NULL; 00485 } 00486 printf("optimize "); 00487 print_expr(0, e1, 0); 00488 printf(" && "); 00489 print_expr(0, e2, 0); 00490 printf(" ?\n"); 00491 return NULL; 00492 } 00493 00494 static void expr_eliminate_dups1(enum expr_type type, struct expr **ep1, struct expr **ep2) 00495 { 00496 #define e1 (*ep1) 00497 #define e2 (*ep2) 00498 struct expr *tmp; 00499 00500 if (e1->type == type) { 00501 expr_eliminate_dups1(type, &e1->left.expr, &e2); 00502 expr_eliminate_dups1(type, &e1->right.expr, &e2); 00503 return; 00504 } 00505 if (e2->type == type) { 00506 expr_eliminate_dups1(type, &e1, &e2->left.expr); 00507 expr_eliminate_dups1(type, &e1, &e2->right.expr); 00508 return; 00509 } 00510 if (e1 == e2) 00511 return; 00512 00513 switch (e1->type) { 00514 case E_OR: case E_AND: 00515 expr_eliminate_dups1(e1->type, &e1, &e1); 00516 default: 00517 ; 00518 } 00519 00520 switch (type) { 00521 case E_OR: 00522 tmp = expr_join_or(e1, e2); 00523 if (tmp) { 00524 expr_free(e1); expr_free(e2); 00525 e1 = expr_alloc_symbol(&symbol_no); 00526 e2 = tmp; 00527 trans_count++; 00528 } 00529 break; 00530 case E_AND: 00531 tmp = expr_join_and(e1, e2); 00532 if (tmp) { 00533 expr_free(e1); expr_free(e2); 00534 e1 = expr_alloc_symbol(&symbol_yes); 00535 e2 = tmp; 00536 trans_count++; 00537 } 00538 break; 00539 default: 00540 ; 00541 } 00542 #undef e1 00543 #undef e2 00544 } 00545 00546 static void expr_eliminate_dups2(enum expr_type type, struct expr **ep1, struct expr **ep2) 00547 { 00548 #define e1 (*ep1) 00549 #define e2 (*ep2) 00550 struct expr *tmp, *tmp1, *tmp2; 00551 00552 if (e1->type == type) { 00553 expr_eliminate_dups2(type, &e1->left.expr, &e2); 00554 expr_eliminate_dups2(type, &e1->right.expr, &e2); 00555 return; 00556 } 00557 if (e2->type == type) { 00558 expr_eliminate_dups2(type, &e1, &e2->left.expr); 00559 expr_eliminate_dups2(type, &e1, &e2->right.expr); 00560 } 00561 if (e1 == e2) 00562 return; 00563 00564 switch (e1->type) { 00565 case E_OR: 00566 expr_eliminate_dups2(e1->type, &e1, &e1); 00567 // (FOO || BAR) && (!FOO && !BAR) -> n 00568 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); 00569 tmp2 = expr_copy(e2); 00570 tmp = expr_extract_eq_and(&tmp1, &tmp2); 00571 if (expr_is_yes(tmp1)) { 00572 expr_free(e1); 00573 e1 = expr_alloc_symbol(&symbol_no); 00574 trans_count++; 00575 } 00576 expr_free(tmp2); 00577 expr_free(tmp1); 00578 expr_free(tmp); 00579 break; 00580 case E_AND: 00581 expr_eliminate_dups2(e1->type, &e1, &e1); 00582 // (FOO && BAR) || (!FOO || !BAR) -> y 00583 tmp1 = expr_transform(expr_alloc_one(E_NOT, expr_copy(e1))); 00584 tmp2 = expr_copy(e2); 00585 tmp = expr_extract_eq_or(&tmp1, &tmp2); 00586 if (expr_is_no(tmp1)) { 00587 expr_free(e1); 00588 e1 = expr_alloc_symbol(&symbol_yes); 00589 trans_count++; 00590 } 00591 expr_free(tmp2); 00592 expr_free(tmp1); 00593 expr_free(tmp); 00594 break; 00595 default: 00596 ; 00597 } 00598 #undef e1 00599 #undef e2 00600 } 00601 00602 struct expr *expr_eliminate_dups(struct expr *e) 00603 { 00604 int oldcount; 00605 if (!e) 00606 return e; 00607 00608 oldcount = trans_count; 00609 while (1) { 00610 trans_count = 0; 00611 switch (e->type) { 00612 case E_OR: case E_AND: 00613 expr_eliminate_dups1(e->type, &e, &e); 00614 expr_eliminate_dups2(e->type, &e, &e); 00615 default: 00616 ; 00617 } 00618 if (!trans_count) 00619 break; 00620 e = expr_eliminate_yn(e); 00621 } 00622 trans_count = oldcount; 00623 return e; 00624 } 00625 00626 struct expr *expr_transform(struct expr *e) 00627 { 00628 struct expr *tmp; 00629 00630 if (!e) 00631 return NULL; 00632 switch (e->type) { 00633 case E_EQUAL: 00634 case E_UNEQUAL: 00635 case E_SYMBOL: 00636 case E_CHOICE: 00637 break; 00638 default: 00639 e->left.expr = expr_transform(e->left.expr); 00640 e->right.expr = expr_transform(e->right.expr); 00641 } 00642 00643 switch (e->type) { 00644 case E_EQUAL: 00645 if (e->left.sym->type != S_BOOLEAN) 00646 break; 00647 if (e->right.sym == &symbol_no) { 00648 e->type = E_NOT; 00649 e->left.expr = expr_alloc_symbol(e->left.sym); 00650 e->right.sym = NULL; 00651 break; 00652 } 00653 if (e->right.sym == &symbol_mod) { 00654 printf("boolean symbol %s tested for 'm'? test forced to 'n'\n", e->left.sym->name); 00655 e->type = E_SYMBOL; 00656 e->left.sym = &symbol_no; 00657 e->right.sym = NULL; 00658 break; 00659 } 00660 if (e->right.sym == &symbol_yes) { 00661 e->type = E_SYMBOL; 00662 e->right.sym = NULL; 00663 break; 00664 } 00665 break; 00666 case E_UNEQUAL: 00667 if (e->left.sym->type != S_BOOLEAN) 00668 break; 00669 if (e->right.sym == &symbol_no) { 00670 e->type = E_SYMBOL; 00671 e->right.sym = NULL; 00672 break; 00673 } 00674 if (e->right.sym == &symbol_mod) { 00675 printf("boolean symbol %s tested for 'm'? test forced to 'y'\n", e->left.sym->name); 00676 e->type = E_SYMBOL; 00677 e->left.sym = &symbol_yes; 00678 e->right.sym = NULL; 00679 break; 00680 } 00681 if (e->right.sym == &symbol_yes) { 00682 e->type = E_NOT; 00683 e->left.expr = expr_alloc_symbol(e->left.sym); 00684 e->right.sym = NULL; 00685 break; 00686 } 00687 break; 00688 case E_NOT: 00689 switch (e->left.expr->type) { 00690 case E_NOT: 00691 // !!a -> a 00692 tmp = e->left.expr->left.expr; 00693 free(e->left.expr); 00694 free(e); 00695 e = tmp; 00696 e = expr_transform(e); 00697 break; 00698 case E_EQUAL: 00699 case E_UNEQUAL: 00700 // !a='x' -> a!='x' 00701 tmp = e->left.expr; 00702 free(e); 00703 e = tmp; 00704 e->type = e->type == E_EQUAL ? E_UNEQUAL : E_EQUAL; 00705 break; 00706 case E_OR: 00707 // !(a || b) -> !a && !b 00708 tmp = e->left.expr; 00709 e->type = E_AND; 00710 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); 00711 tmp->type = E_NOT; 00712 tmp->right.expr = NULL; 00713 e = expr_transform(e); 00714 break; 00715 case E_AND: 00716 // !(a && b) -> !a || !b 00717 tmp = e->left.expr; 00718 e->type = E_OR; 00719 e->right.expr = expr_alloc_one(E_NOT, tmp->right.expr); 00720 tmp->type = E_NOT; 00721 tmp->right.expr = NULL; 00722 e = expr_transform(e); 00723 break; 00724 case E_SYMBOL: 00725 if (e->left.expr->left.sym == &symbol_yes) { 00726 // !'y' -> 'n' 00727 tmp = e->left.expr; 00728 free(e); 00729 e = tmp; 00730 e->type = E_SYMBOL; 00731 e->left.sym = &symbol_no; 00732 break; 00733 } 00734 if (e->left.expr->left.sym == &symbol_mod) { 00735 // !'m' -> 'm' 00736 tmp = e->left.expr; 00737 free(e); 00738 e = tmp; 00739 e->type = E_SYMBOL; 00740 e->left.sym = &symbol_mod; 00741 break; 00742 } 00743 if (e->left.expr->left.sym == &symbol_no) { 00744 // !'n' -> 'y' 00745 tmp = e->left.expr; 00746 free(e); 00747 e = tmp; 00748 e->type = E_SYMBOL; 00749 e->left.sym = &symbol_yes; 00750 break; 00751 } 00752 break; 00753 default: 00754 ; 00755 } 00756 break; 00757 default: 00758 ; 00759 } 00760 return e; 00761 } 00762 00763 int expr_contains_symbol(struct expr *dep, struct symbol *sym) 00764 { 00765 if (!dep) 00766 return 0; 00767 00768 switch (dep->type) { 00769 case E_AND: 00770 case E_OR: 00771 return expr_contains_symbol(dep->left.expr, sym) || 00772 expr_contains_symbol(dep->right.expr, sym); 00773 case E_SYMBOL: 00774 return dep->left.sym == sym; 00775 case E_EQUAL: 00776 case E_UNEQUAL: 00777 return dep->left.sym == sym || 00778 dep->right.sym == sym; 00779 case E_NOT: 00780 return expr_contains_symbol(dep->left.expr, sym); 00781 default: 00782 ; 00783 } 00784 return 0; 00785 } 00786 00787 bool expr_depends_symbol(struct expr *dep, struct symbol *sym) 00788 { 00789 if (!dep) 00790 return false; 00791 00792 switch (dep->type) { 00793 case E_AND: 00794 return expr_depends_symbol(dep->left.expr, sym) || 00795 expr_depends_symbol(dep->right.expr, sym); 00796 case E_SYMBOL: 00797 return dep->left.sym == sym; 00798 case E_EQUAL: 00799 if (dep->left.sym == sym) { 00800 if (dep->right.sym == &symbol_yes || dep->right.sym == &symbol_mod) 00801 return true; 00802 } 00803 break; 00804 case E_UNEQUAL: 00805 if (dep->left.sym == sym) { 00806 if (dep->right.sym == &symbol_no) 00807 return true; 00808 } 00809 break; 00810 default: 00811 ; 00812 } 00813 return false; 00814 } 00815 00816 struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2) 00817 { 00818 struct expr *tmp = NULL; 00819 expr_extract_eq(E_AND, &tmp, ep1, ep2); 00820 if (tmp) { 00821 *ep1 = expr_eliminate_yn(*ep1); 00822 *ep2 = expr_eliminate_yn(*ep2); 00823 } 00824 return tmp; 00825 } 00826 00827 struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2) 00828 { 00829 struct expr *tmp = NULL; 00830 expr_extract_eq(E_OR, &tmp, ep1, ep2); 00831 if (tmp) { 00832 *ep1 = expr_eliminate_yn(*ep1); 00833 *ep2 = expr_eliminate_yn(*ep2); 00834 } 00835 return tmp; 00836 } 00837 00838 void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2) 00839 { 00840 #define e1 (*ep1) 00841 #define e2 (*ep2) 00842 if (e1->type == type) { 00843 expr_extract_eq(type, ep, &e1->left.expr, &e2); 00844 expr_extract_eq(type, ep, &e1->right.expr, &e2); 00845 return; 00846 } 00847 if (e2->type == type) { 00848 expr_extract_eq(type, ep, ep1, &e2->left.expr); 00849 expr_extract_eq(type, ep, ep1, &e2->right.expr); 00850 return; 00851 } 00852 if (expr_eq(e1, e2)) { 00853 *ep = *ep ? expr_alloc_two(type, *ep, e1) : e1; 00854 expr_free(e2); 00855 if (type == E_AND) { 00856 e1 = expr_alloc_symbol(&symbol_yes); 00857 e2 = expr_alloc_symbol(&symbol_yes); 00858 } else if (type == E_OR) { 00859 e1 = expr_alloc_symbol(&symbol_no); 00860 e2 = expr_alloc_symbol(&symbol_no); 00861 } 00862 } 00863 #undef e1 00864 #undef e2 00865 } 00866 00867 struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym) 00868 { 00869 struct expr *e1, *e2; 00870 00871 if (!e) { 00872 e = expr_alloc_symbol(sym); 00873 if (type == E_UNEQUAL) 00874 e = expr_alloc_one(E_NOT, e); 00875 return e; 00876 } 00877 switch (e->type) { 00878 case E_AND: 00879 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); 00880 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); 00881 if (sym == &symbol_yes) 00882 e = expr_alloc_two(E_AND, e1, e2); 00883 if (sym == &symbol_no) 00884 e = expr_alloc_two(E_OR, e1, e2); 00885 if (type == E_UNEQUAL) 00886 e = expr_alloc_one(E_NOT, e); 00887 return e; 00888 case E_OR: 00889 e1 = expr_trans_compare(e->left.expr, E_EQUAL, sym); 00890 e2 = expr_trans_compare(e->right.expr, E_EQUAL, sym); 00891 if (sym == &symbol_yes) 00892 e = expr_alloc_two(E_OR, e1, e2); 00893 if (sym == &symbol_no) 00894 e = expr_alloc_two(E_AND, e1, e2); 00895 if (type == E_UNEQUAL) 00896 e = expr_alloc_one(E_NOT, e); 00897 return e; 00898 case E_NOT: 00899 return expr_trans_compare(e->left.expr, type == E_EQUAL ? E_UNEQUAL : E_EQUAL, sym); 00900 case E_UNEQUAL: 00901 case E_EQUAL: 00902 if (type == E_EQUAL) { 00903 if (sym == &symbol_yes) 00904 return expr_copy(e); 00905 if (sym == &symbol_mod) 00906 return expr_alloc_symbol(&symbol_no); 00907 if (sym == &symbol_no) 00908 return expr_alloc_one(E_NOT, expr_copy(e)); 00909 } else { 00910 if (sym == &symbol_yes) 00911 return expr_alloc_one(E_NOT, expr_copy(e)); 00912 if (sym == &symbol_mod) 00913 return expr_alloc_symbol(&symbol_yes); 00914 if (sym == &symbol_no) 00915 return expr_copy(e); 00916 } 00917 break; 00918 case E_SYMBOL: 00919 return expr_alloc_comp(type, e->left.sym, sym); 00920 case E_CHOICE: 00921 case E_RANGE: 00922 case E_NONE: 00923 /* panic */; 00924 } 00925 return NULL; 00926 } 00927 00928 tristate expr_calc_value(struct expr *e) 00929 { 00930 tristate val1, val2; 00931 const char *str1, *str2; 00932 00933 if (!e) 00934 return yes; 00935 00936 switch (e->type) { 00937 case E_SYMBOL: 00938 sym_calc_value(e->left.sym); 00939 return e->left.sym->curr.tri; 00940 case E_AND: 00941 val1 = expr_calc_value(e->left.expr); 00942 val2 = expr_calc_value(e->right.expr); 00943 return E_AND(val1, val2); 00944 case E_OR: 00945 val1 = expr_calc_value(e->left.expr); 00946 val2 = expr_calc_value(e->right.expr); 00947 return E_OR(val1, val2); 00948 case E_NOT: 00949 val1 = expr_calc_value(e->left.expr); 00950 return E_NOT(val1); 00951 case E_EQUAL: 00952 sym_calc_value(e->left.sym); 00953 sym_calc_value(e->right.sym); 00954 str1 = sym_get_string_value(e->left.sym); 00955 str2 = sym_get_string_value(e->right.sym); 00956 return !strcmp(str1, str2) ? yes : no; 00957 case E_UNEQUAL: 00958 sym_calc_value(e->left.sym); 00959 sym_calc_value(e->right.sym); 00960 str1 = sym_get_string_value(e->left.sym); 00961 str2 = sym_get_string_value(e->right.sym); 00962 return !strcmp(str1, str2) ? no : yes; 00963 default: 00964 printf("expr_calc_value: %d?\n", e->type); 00965 return no; 00966 } 00967 } 00968 00969 int expr_compare_type(enum expr_type t1, enum expr_type t2) 00970 { 00971 #if 0 00972 return 1; 00973 #else 00974 if (t1 == t2) 00975 return 0; 00976 switch (t1) { 00977 case E_EQUAL: 00978 case E_UNEQUAL: 00979 if (t2 == E_NOT) 00980 return 1; 00981 case E_NOT: 00982 if (t2 == E_AND) 00983 return 1; 00984 case E_AND: 00985 if (t2 == E_OR) 00986 return 1; 00987 case E_OR: 00988 if (t2 == E_CHOICE) 00989 return 1; 00990 case E_CHOICE: 00991 if (t2 == 0) 00992 return 1; 00993 default: 00994 return -1; 00995 } 00996 printf("[%dgt%d?]", t1, t2); 00997 return 0; 00998 #endif 00999 } 01000 01001 void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken) 01002 { 01003 if (!e) { 01004 fn(data, "y"); 01005 return; 01006 } 01007 01008 if (expr_compare_type(prevtoken, e->type) > 0) 01009 fn(data, "("); 01010 switch (e->type) { 01011 case E_SYMBOL: 01012 if (e->left.sym->name) 01013 fn(data, e->left.sym->name); 01014 else 01015 fn(data, "<choice>"); 01016 break; 01017 case E_NOT: 01018 fn(data, "!"); 01019 expr_print(e->left.expr, fn, data, E_NOT); 01020 break; 01021 case E_EQUAL: 01022 fn(data, e->left.sym->name); 01023 fn(data, "="); 01024 fn(data, e->right.sym->name); 01025 break; 01026 case E_UNEQUAL: 01027 fn(data, e->left.sym->name); 01028 fn(data, "!="); 01029 fn(data, e->right.sym->name); 01030 break; 01031 case E_OR: 01032 expr_print(e->left.expr, fn, data, E_OR); 01033 fn(data, " || "); 01034 expr_print(e->right.expr, fn, data, E_OR); 01035 break; 01036 case E_AND: 01037 expr_print(e->left.expr, fn, data, E_AND); 01038 fn(data, " && "); 01039 expr_print(e->right.expr, fn, data, E_AND); 01040 break; 01041 case E_CHOICE: 01042 fn(data, e->right.sym->name); 01043 if (e->left.expr) { 01044 fn(data, " ^ "); 01045 expr_print(e->left.expr, fn, data, E_CHOICE); 01046 } 01047 break; 01048 case E_RANGE: 01049 fn(data, "["); 01050 fn(data, e->left.sym->name); 01051 fn(data, " "); 01052 fn(data, e->right.sym->name); 01053 fn(data, "]"); 01054 break; 01055 default: 01056 { 01057 char buf[32]; 01058 sprintf(buf, "<unknown type %d>", e->type); 01059 fn(data, buf); 01060 break; 01061 } 01062 } 01063 if (expr_compare_type(prevtoken, e->type) > 0) 01064 fn(data, ")"); 01065 } 01066 01067 static void expr_print_file_helper(void *data, const char *str) 01068 { 01069 fwrite(str, strlen(str), 1, data); 01070 } 01071 01072 void expr_fprint(struct expr *e, FILE *out) 01073 { 01074 expr_print(e, expr_print_file_helper, out, E_NONE); 01075 } 01076 01077 void print_expr(int mask, struct expr *e, int prevtoken) 01078 { 01079 if (!(cdebug & mask)) 01080 return; 01081 expr_fprint(e, stdout); 01082 } 01083

Generated on Thu Nov 20 11:49:47 2008 for RTAI API by doxygen 1.3.8