DisjConditions-t.pl 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. # Copyright (C) 2001-2017 Free Software Foundation, Inc.
  2. #
  3. # This program is free software; you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation; either version 2, or (at your option)
  6. # any later version.
  7. #
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. #
  13. # You should have received a copy of the GNU General Public License
  14. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. BEGIN {
  16. use Config;
  17. if (eval { require 5.007_002; } # for CLONE support
  18. && $Config{useithreads}
  19. && !$ENV{WANT_NO_THREADS})
  20. {
  21. require threads;
  22. import threads;
  23. }
  24. else
  25. {
  26. exit 77;
  27. }
  28. }
  29. use Automake::Condition qw/TRUE FALSE/;
  30. use Automake::DisjConditions;
  31. sub test_basics ()
  32. {
  33. my $true = new Automake::DisjConditions TRUE;
  34. my $false = new Automake::DisjConditions FALSE;
  35. my $cond = new Automake::Condition "COND1_TRUE", "COND2_FALSE";
  36. return threads->new (sub {
  37. my $other = new Automake::Condition "COND3_FALSE";
  38. my $another = new Automake::Condition "COND3_TRUE", "COND4_FALSE";
  39. return threads->new (sub {
  40. my $set1 = new Automake::DisjConditions $cond, $other;
  41. return threads->new (sub {
  42. my $set2 = new Automake::DisjConditions $other, $cond;
  43. my $set3 = new Automake::DisjConditions FALSE, $another;
  44. return 1 unless $set1 == $set2;
  45. return 1 if $set1->false;
  46. return 1 if $set1->true;
  47. return 1 unless (new Automake::DisjConditions)->false;
  48. return 1 if (new Automake::DisjConditions)->true;
  49. return 1 unless $true->human eq 'TRUE';
  50. return 1 unless $false->human eq 'FALSE';
  51. return 1 unless $set1->human eq "(COND1 and !COND2) or (!COND3)";
  52. return 1 unless $set2->human eq "(COND1 and !COND2) or (!COND3)";
  53. my $one_cond_human = $set1->one_cond->human;
  54. return 1 unless $one_cond_human eq "!COND3"
  55. || $one_cond_human eq "COND1 and !COND2";
  56. return 1 unless $set1->string eq "COND1_TRUE COND2_FALSE | COND3_FALSE";
  57. my $merged1 = $set1->merge ($set2);
  58. my $merged2 = $set1->merge ($cond);
  59. my $mult1 = $set1->multiply ($set3);
  60. return threads->new (sub {
  61. my $mult2 = $set1->multiply ($another);
  62. return threads->new (sub {
  63. return 1 unless $merged1->simplify->string eq "COND1_TRUE COND2_FALSE | COND3_FALSE";
  64. return 1 unless $merged2->simplify->string eq "COND1_TRUE COND2_FALSE | COND3_FALSE";
  65. return 1 unless $mult1->string eq "COND1_TRUE COND2_FALSE COND3_TRUE COND4_FALSE";
  66. return 1 unless $mult1 == $mult2;
  67. return 0;
  68. })->join;
  69. })->join;
  70. })->join;
  71. })->join;
  72. })->join;
  73. }
  74. sub build_set (@)
  75. {
  76. my @conds = @_;
  77. my @set = ();
  78. for my $cond (@conds)
  79. {
  80. push @set, new Automake::Condition @$cond;
  81. }
  82. return new Automake::DisjConditions @set;
  83. }
  84. sub test_invert ()
  85. {
  86. my @tests = ([[["FALSE"]],
  87. [["TRUE"]]],
  88. [[["TRUE"]],
  89. [["FALSE"]]],
  90. [[["COND1_TRUE", "COND2_TRUE"],
  91. ["COND3_FALSE", "COND2_TRUE"]],
  92. [["COND2_FALSE"],
  93. ["COND1_FALSE", "COND3_TRUE"]]],
  94. [[["COND1_TRUE", "COND2_TRUE"],
  95. ["TRUE"]],
  96. [["FALSE"]]],
  97. [[["COND1_TRUE", "COND2_TRUE"],
  98. ["FALSE"]],
  99. [["COND1_FALSE"],
  100. ["COND2_FALSE"]]],
  101. [[["COND1_TRUE"],
  102. ["COND2_FALSE"]],
  103. [["COND1_FALSE", "COND2_TRUE"]]]
  104. );
  105. for my $t (@tests)
  106. {
  107. my $set = build_set @{$t->[0]};
  108. return 1
  109. if threads->new(sub {
  110. my $res = build_set @{$t->[1]};
  111. my $inv = $set->invert;
  112. if ($inv != $res)
  113. {
  114. print " (I) " . $set->string . "\n\t"
  115. . $inv->string . ' != ' . $res->string . "\n";
  116. return 1;
  117. }
  118. return 0
  119. })-> join;
  120. }
  121. return 0;
  122. }
  123. sub test_simplify ()
  124. {
  125. my @tests = ([[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
  126. ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"]],
  127. [["FOO_TRUE", "BAR_FALSE"]]],
  128. [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
  129. ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
  130. ["FOO_TRUE", "BAR_TRUE"]],
  131. [["FOO_TRUE"]]],
  132. [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
  133. ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
  134. ["FOO_TRUE", "BAR_TRUE"],
  135. ["FOO_FALSE"]],
  136. [["TRUE"]]],
  137. [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
  138. ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
  139. ["BAR_TRUE", "BAZ_TRUE"],
  140. ["BAR_FALSE", "BAZ_TRUE"]],
  141. [["BAZ_TRUE"], ["FOO_TRUE", "BAR_FALSE"]]],
  142. [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
  143. ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
  144. ["BAR_TRUE", "BAZ_TRUE"],
  145. ["BAR_FALSE", "BAZ_TRUE"],
  146. ["FOO_FALSE"]],
  147. [["FOO_FALSE"], ["BAZ_TRUE"], ["BAR_FALSE"]]],
  148. [[["B_TRUE"],
  149. ["A_FALSE", "B_TRUE"]],
  150. [["B_TRUE"]]],
  151. [[["B_TRUE"],
  152. ["A_FALSE", "B_FALSE", "C_TRUE"],
  153. ["A_FALSE", "B_FALSE", "C_FALSE"]],
  154. [["A_FALSE"], ["B_TRUE"]]],
  155. [[["B_TRUE"],
  156. ["A_FALSE", "B_FALSE", "C_TRUE"],
  157. ["A_FALSE", "B_FALSE", "C_FALSE"],
  158. ["A_TRUE", "B_FALSE"]],
  159. [["TRUE"]]],
  160. [[["A_TRUE", "B_TRUE"],
  161. ["A_TRUE", "B_FALSE"],
  162. ["A_TRUE", "C_FALSE", "D_FALSE"]],
  163. [["A_TRUE"]]],
  164. [[["A_FALSE", "B_FALSE", "C_FALSE", "D_TRUE", "E_FALSE"],
  165. ["A_FALSE", "B_FALSE", "C_TRUE", "D_TRUE", "E_TRUE"],
  166. ["A_FALSE", "B_TRUE", "C_TRUE", "D_FALSE", "E_TRUE"],
  167. ["A_FALSE", "B_TRUE", "C_FALSE", "D_FALSE", "E_FALSE"],
  168. ["A_TRUE", "B_TRUE", "C_FALSE", "D_FALSE", "E_FALSE"],
  169. ["A_TRUE", "B_TRUE", "C_TRUE", "D_FALSE", "E_TRUE"],
  170. ["A_TRUE", "B_FALSE", "C_TRUE", "D_TRUE", "E_TRUE"],
  171. ["A_TRUE", "B_FALSE", "C_FALSE", "D_TRUE", "E_FALSE"]],
  172. [ ["B_FALSE", "C_FALSE", "D_TRUE", "E_FALSE"],
  173. ["B_FALSE", "C_TRUE", "D_TRUE", "E_TRUE"],
  174. ["B_TRUE", "C_TRUE", "D_FALSE", "E_TRUE"],
  175. ["B_TRUE", "C_FALSE", "D_FALSE", "E_FALSE"]]],
  176. [[["A_FALSE", "B_FALSE", "C_FALSE", "D_TRUE", "E_FALSE"],
  177. ["A_FALSE", "B_FALSE", "C_TRUE", "D_TRUE", "E_TRUE"],
  178. ["A_FALSE", "B_TRUE", "C_TRUE", "D_FALSE", "E_TRUE"],
  179. ["A_FALSE", "B_TRUE", "C_FALSE", "D_FALSE", "E_FALSE"],
  180. ["A_TRUE", "B_TRUE", "C_FALSE", "D_FALSE", "E_FALSE"],
  181. ["A_TRUE", "B_TRUE", "C_TRUE", "D_FALSE", "E_TRUE"],
  182. ["A_TRUE", "B_FALSE", "C_TRUE", "D_TRUE", "E_TRUE"],
  183. ["A_TRUE", "B_FALSE", "C_FALSE", "D_TRUE", "E_FALSE"],
  184. ["A_FALSE", "B_FALSE", "C_FALSE", "D_FALSE", "E_FALSE"],
  185. ["A_FALSE", "B_FALSE", "C_TRUE", "D_FALSE", "E_TRUE"],
  186. ["A_FALSE", "B_TRUE", "C_TRUE", "D_TRUE", "E_TRUE"],
  187. ["A_FALSE", "B_TRUE", "C_FALSE", "D_TRUE", "E_FALSE"],
  188. ["A_TRUE", "B_TRUE", "C_FALSE", "D_TRUE", "E_FALSE"],
  189. ["A_TRUE", "B_TRUE", "C_TRUE", "D_TRUE", "E_TRUE"],
  190. ["A_TRUE", "B_FALSE", "C_TRUE", "D_FALSE", "E_TRUE"],
  191. ["A_TRUE", "B_FALSE", "C_FALSE", "D_FALSE", "E_FALSE"]],
  192. [["C_FALSE", "E_FALSE"],
  193. ["C_TRUE", "E_TRUE"]]],
  194. [[["A_FALSE"],
  195. ["A_TRUE", "B_FALSE"],
  196. ["A_TRUE", "B_TRUE", "C_FALSE"],
  197. ["A_TRUE", "B_TRUE", "C_TRUE", "D_FALSE"],
  198. ["A_TRUE", "B_TRUE", "C_TRUE", "D_TRUE", "E_FALSE"],
  199. ["A_TRUE", "B_TRUE", "C_TRUE", "D_TRUE", "E_TRUE", "F_FALSE"],
  200. ["A_TRUE", "B_TRUE", "C_TRUE", "D_TRUE", "E_TRUE"]],
  201. [["TRUE"]]],
  202. # Simplify should work with up to 31 variables.
  203. [[["V01_TRUE", "V02_TRUE", "V03_TRUE", "V04_TRUE", "V05_TRUE",
  204. "V06_TRUE", "V07_TRUE", "V08_TRUE", "V09_TRUE", "V10_TRUE",
  205. "V11_TRUE", "V12_TRUE", "V13_TRUE", "V14_TRUE", "V15_TRUE",
  206. "V16_TRUE", "V17_TRUE", "V18_TRUE", "V19_TRUE", "V20_TRUE",
  207. "V21_TRUE", "V22_TRUE", "V23_TRUE", "V24_TRUE", "V25_TRUE",
  208. "V26_TRUE", "V27_TRUE", "V28_TRUE", "V29_TRUE", "V30_TRUE",
  209. "V31_TRUE"],
  210. ["V01_TRUE", "V02_TRUE", "V03_TRUE", "V04_TRUE", "V05_TRUE",
  211. "V06_TRUE", "V07_TRUE", "V08_TRUE", "V09_TRUE", "V10_TRUE",
  212. "V11_TRUE", "V12_TRUE", "V13_TRUE", "V14_TRUE", "V15_TRUE",
  213. "V16_TRUE", "V17_TRUE", "V18_TRUE", "V19_TRUE", "V20_TRUE",
  214. "V21_TRUE", "V22_TRUE", "V23_TRUE", "V24_TRUE", "V25_TRUE",
  215. "V26_TRUE", "V27_TRUE", "V28_TRUE", "V29_TRUE", "V30_TRUE",
  216. "V31_FALSE"],
  217. ["V01_FALSE","V02_TRUE", "V03_TRUE", "V04_TRUE", "V05_TRUE",
  218. "V06_TRUE", "V07_TRUE", "V08_TRUE", "V09_TRUE", "V10_TRUE",
  219. "V11_TRUE", "V12_TRUE", "V13_TRUE", "V14_TRUE", "V15_TRUE",
  220. "V16_TRUE", "V17_TRUE", "V18_TRUE", "V19_TRUE", "V20_TRUE",
  221. "V21_TRUE", "V22_TRUE", "V23_TRUE", "V24_TRUE", "V25_TRUE",
  222. "V26_TRUE", "V27_TRUE", "V28_TRUE", "V29_TRUE", "V30_TRUE",
  223. "V31_TRUE"],
  224. ["V01_FALSE","V02_TRUE", "V03_TRUE", "V04_TRUE", "V05_TRUE",
  225. "V06_TRUE", "V07_TRUE", "V08_TRUE", "V09_TRUE", "V10_TRUE",
  226. "V11_TRUE", "V12_TRUE", "V13_TRUE", "V14_TRUE", "V15_TRUE",
  227. "V16_TRUE", "V17_TRUE", "V18_TRUE", "V19_TRUE", "V20_TRUE",
  228. "V21_TRUE", "V22_TRUE", "V23_TRUE", "V24_TRUE", "V25_TRUE",
  229. "V26_TRUE", "V27_TRUE", "V28_TRUE", "V29_TRUE", "V30_TRUE",
  230. "V31_FALSE"]],
  231. [[ "V02_TRUE", "V03_TRUE", "V04_TRUE", "V05_TRUE",
  232. "V06_TRUE", "V07_TRUE", "V08_TRUE", "V09_TRUE", "V10_TRUE",
  233. "V11_TRUE", "V12_TRUE", "V13_TRUE", "V14_TRUE", "V15_TRUE",
  234. "V16_TRUE", "V17_TRUE", "V18_TRUE", "V19_TRUE", "V20_TRUE",
  235. "V21_TRUE", "V22_TRUE", "V23_TRUE", "V24_TRUE", "V25_TRUE",
  236. "V26_TRUE", "V27_TRUE", "V28_TRUE", "V29_TRUE", "V30_TRUE"
  237. ]]]);
  238. for my $t (@tests)
  239. {
  240. my $set = build_set @{$t->[0]};
  241. return 1
  242. if threads->new(sub {
  243. my $res = build_set @{$t->[1]};
  244. return threads->new(sub {
  245. # Make sure simplify() yields the expected result.
  246. my $sim = $set->simplify;
  247. return threads->new(sub {
  248. if ($sim != $res)
  249. {
  250. print " (S1) " . $set->string . "\n\t"
  251. . $sim->string . ' != ' . $res->string . "\n";
  252. return 1;
  253. }
  254. # Make sure simplify() is idempotent.
  255. my $sim2 = $sim->simplify;
  256. return threads->new(sub {
  257. if ($sim2 != $sim)
  258. {
  259. print " (S2) " . $sim->string . "\n\t"
  260. . $sim2->string . ' != ' . $sim->string . "\n";
  261. return 1;
  262. }
  263. # Also exercise invert() while we are at it.
  264. my $inv1 = $set->invert->simplify;
  265. return threads->new(sub {
  266. my $inv2 = $sim->invert->simplify;
  267. return threads->new(sub {
  268. if ($inv1 != $inv2)
  269. {
  270. print " (S3) " . $set->string . ", " . $sim->string . "\n\t"
  271. . $inv1->string . ' -= ' . $inv2->string . "\n";
  272. return 1;
  273. }
  274. })->join;
  275. })->join;
  276. })->join;
  277. })->join;
  278. })->join;
  279. })->join;
  280. }
  281. return 0;
  282. }
  283. sub test_sub_conditions ()
  284. {
  285. my @tests = ([[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
  286. ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
  287. ["FOO_FALSE"]],
  288. ["FOO_TRUE"],
  289. [["BAR_FALSE", "BAZ_FALSE"],
  290. ["BAR_FALSE", "BAZ_TRUE"]]],
  291. [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
  292. ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
  293. ["FOO_FALSE"]],
  294. ["FOO_TRUE", "BAR_FALSE"],
  295. [["BAZ_FALSE"],
  296. ["BAZ_TRUE"]]],
  297. [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
  298. ["FOO_TRUE", "BAR_FALSE", "BAZ_TRUE"],
  299. ["FOO_FALSE"]],
  300. ["FOO_TRUE", "BAR_TRUE"],
  301. [["FALSE"]]],
  302. [[["FOO_TRUE", "BAR_FALSE", "BAZ_FALSE"],
  303. ["FOO_TRUE", "BAZ_TRUE"],
  304. ["FOO_FALSE"]],
  305. ["FOO_TRUE", "BAR_TRUE"],
  306. [["BAZ_TRUE"]]],
  307. [[["FOO_TRUE", "BAR_FALSE"],
  308. ["FOO_TRUE", "BAR_TRUE"]],
  309. ["FOO_TRUE", "BAR_TRUE"],
  310. [["TRUE"]]],
  311. [[["TRUE"]],
  312. ["TRUE"],
  313. [["TRUE"]]],
  314. [[["FALSE"]],
  315. ["TRUE"],
  316. [["FALSE"]]],
  317. [[["FALSE"]],
  318. ["FALSE"],
  319. [["FALSE"]]]);
  320. for my $t (@tests)
  321. {
  322. my $t1 = build_set @{$t->[0]};
  323. return 1
  324. if threads->new(sub {
  325. my $t2 = new Automake::Condition @{$t->[1]};
  326. return threads->new(sub {
  327. my $t3 = build_set @{$t->[2]};
  328. return threads->new(sub {
  329. # Make sure sub_conditions() yields the expected result.
  330. my $s = $t1->sub_conditions ($t2);
  331. threads->new(sub {
  332. if ($s != $t3)
  333. {
  334. print " (SC) " . $t1->string . "\n\t"
  335. . $s->string . ' != ' . $t3->string . "\n";
  336. return 1;
  337. }
  338. })->join;
  339. })->join;
  340. })->join;
  341. })->join;
  342. }
  343. }
  344. sub test_ambig ()
  345. {
  346. my @tests = ([[["TRUE"]],
  347. ["TRUE"],
  348. "multiply defined"],
  349. [[["C1_TRUE"]],
  350. ["C1_TRUE"],
  351. "multiply defined"],
  352. [[["TRUE"]],
  353. ["C1_FALSE"],
  354. "which includes"],
  355. [[["C1_TRUE"]],
  356. ["C1_TRUE", "C2_TRUE"],
  357. "which includes"],
  358. [[["C1_TRUE", "C2_TRUE"]],
  359. ["C2_TRUE"],
  360. "which is included in"],
  361. [[["C1_TRUE"]],
  362. ["C2_TRUE"],
  363. ''],
  364. [[["C1_TRUE"],
  365. ["C2_FALSE"]],
  366. ["C1_FALSE", "C2_TRUE"],
  367. '']);
  368. my $failed = 0;
  369. for my $t (@tests)
  370. {
  371. my $t1 = build_set @{$t->[0]};
  372. $failed = 1
  373. if threads->new(sub {
  374. my $t2 = new Automake::Condition @{$t->[1]};
  375. my $t3 = $t->[2];
  376. return threads->new(sub {
  377. my ($ans, $cond) = $t1->ambiguous_p ("FOO", $t2);
  378. return threads->new(sub {
  379. if ($t3 && $ans !~ /FOO.*$t3/)
  380. {
  381. print " (A1) " . $t1->string . " vs. " . $t2->string . "\n\t"
  382. . "Error message '$ans' does not match '$t3'\n";
  383. return 1;
  384. }
  385. if (!$t3 && $ans ne '')
  386. {
  387. print " (A2) " . $t1->string . " vs. " . $t2->string . "\n\t"
  388. . "Unexpected error message: $ans\n";
  389. return 1;
  390. }
  391. })->join;
  392. })->join;
  393. })->join;
  394. }
  395. return $failed;
  396. }
  397. exit (test_basics
  398. || test_invert
  399. || test_simplify
  400. || test_sub_conditions
  401. || test_ambig);
  402. ### Setup "GNU" style for perl-mode and cperl-mode.
  403. ## Local Variables:
  404. ## perl-indent-level: 2
  405. ## perl-continued-statement-offset: 2
  406. ## perl-continued-brace-offset: 0
  407. ## perl-brace-offset: 0
  408. ## perl-brace-imaginary-offset: 0
  409. ## perl-label-offset: -2
  410. ## cperl-indent-level: 2
  411. ## cperl-brace-offset: 0
  412. ## cperl-continued-brace-offset: 0
  413. ## cperl-label-offset: -2
  414. ## cperl-extra-newline-before-brace: t
  415. ## cperl-merge-trailing-else: nil
  416. ## cperl-continued-statement-offset: 2
  417. ## End: