expr.c 30 KB

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