Bug Summary

File:src/dnf.c
Warning:line 194, column 2
Value stored to 'xxi' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name dnf.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/kfp/aldor/aldor/aldor/src -fcoverage-compilation-dir=/home/kfp/aldor/aldor/aldor/src -resource-dir /usr/local/lib/clang/18 -D PACKAGE_NAME="aldor" -D PACKAGE_TARNAME="aldor" -D PACKAGE_VERSION="1.4.0" -D PACKAGE_STRING="aldor 1.4.0" -D PACKAGE_BUGREPORT="aldor@xinutec.org" -D PACKAGE_URL="" -D PACKAGE="aldor" -D VERSION="1.4.0" -D YYTEXT_POINTER=1 -D HAVE_STDIO_H=1 -D HAVE_STDLIB_H=1 -D HAVE_STRING_H=1 -D HAVE_INTTYPES_H=1 -D HAVE_STDINT_H=1 -D HAVE_STRINGS_H=1 -D HAVE_SYS_STAT_H=1 -D HAVE_SYS_TYPES_H=1 -D HAVE_UNISTD_H=1 -D STDC_HEADERS=1 -D HAVE_LIBREADLINE=1 -D HAVE_READLINE_READLINE_H=1 -D HAVE_READLINE_HISTORY=1 -D HAVE_READLINE_HISTORY_H=1 -D USE_GLOOP_SHELL=1 -D GENERATOR_COROUTINES=0 -D HAVE_DLFCN_H=1 -D LT_OBJDIR=".libs/" -I . -D VCSVERSION="2c53e759f1e00e345f8b172e7139debda72fda13" -internal-isystem /usr/local/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-empty-body -Wno-enum-compare -Wno-missing-field-initializers -Wno-unused -Wno-unused-parameter -Wno-error=format -Wno-error=type-limits -Wno-error=strict-aliasing -Wno-sign-compare -Wno-error=shift-negative-value -Wno-error=clobbered -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2026-01-15-223856-845667-1 -x c dnf.c
1/*****************************************************************************
2 *
3 * dnf.c: Disjunctive normal form for boolean expressions.
4 *
5 * Copyright (c) 1990-2007 Aldor Software Organization Ltd (Aldor.org).
6 *
7 ****************************************************************************/
8
9#include "axlgen.h"
10#include "debug.h"
11#include "dnf.h"
12#include "store.h"
13
14Bool dnfDebug = false((int) 0);
15#define dnfDEBUGif (!dnfDebug) { } else afprintf DEBUG_IF(dnf)if (!dnfDebug) { } else afprintf
16
17/*****************************************************************************
18 *
19 * :: Forward declarations for local functions.
20 *
21 ****************************************************************************/
22
23localstatic Bool dnfAtomLT (DNF_Atom, DNF_Atom);
24
25localstatic DNF_And dnfAndNew (int argc);
26localstatic DNF_And dnfAndCopy (DNF_And);
27localstatic void dnfAndFree (DNF_And);
28localstatic Bool dnfAndIsTrue (DNF_And);
29localstatic DNF_And dnfAndMerge (DNF_And, DNF_And);
30localstatic Bool dnfAndImplies (DNF_And, DNF_And);
31localstatic Bool dnfAndImpliesNegation (DNF_And, DNF_And);
32localstatic DNF_And dnfAndCancelNegation (DNF_And, DNF_And);
33localstatic DNF dnfAndNot (DNF_And);
34
35localstatic DNF dnfOrNew (int argc);
36localstatic DNF dnfOrCopy (DNF);
37localstatic void dnfOrFree (DNF);
38localstatic Bool dnfOrIsFalse (DNF);
39localstatic void dnfOrMerge (DNF);
40
41
42/*****************************************************************************
43 *
44 * :: Atoms
45 *
46 ****************************************************************************/
47
48localstatic Bool
49dnfAtomLT(DNF_Atom l1, DNF_Atom l2)
50{
51 if (l1 < 0) l1 = -l1;
52 if (l2 < 0) l2 = -l2;
53 return l1 < l2;
54}
55
56
57/*****************************************************************************
58 *
59 * :: Conjunctions
60 *
61 ****************************************************************************/
62
63localstatic DNF_And
64dnfAndNew(int argc)
65{
66 int i;
67 DNF_And xx;
68
69 xx = (DNF_And) stoAlloc(OB_DNF10, fullsizeof(*xx, argc, DNF_Atom)(sizeof(*xx) + (argc) * sizeof(DNF_Atom) - 10 * sizeof(DNF_Atom
))
);
70
71 xx->argc = argc;
72 for (i = 0; i < argc; i += 1)
73 xx->argv[i] = 0;
74
75 dnfDEBUGif (!dnfDebug) { } else afprintf(dbOut, ">dnfAndNew: %pDNF\n", xx);
76
77 return xx;
78}
79
80localstatic DNF_And
81dnfAndCopy(DNF_And xx)
82{
83 int i;
84 DNF_And yy;
85
86 dnfDEBUGif (!dnfDebug) { } else afprintf(dbOut, ">dnfAndCopy: %pDNF\n", xx);
87
88 yy = dnfAndNew(xx->argc);
89 for (i = 0; i < xx->argc; i += 1)
90 yy->argv[i] = xx->argv[i];
91
92 return yy;
93}
94
95localstatic void
96dnfAndFree(DNF_And xx)
97{
98 dnfDEBUGif (!dnfDebug) { } else afprintf(dbOut, ">dnfAndFree: %pDNF\n", xx);
99 stoFree((Pointer) xx);
100}
101
102localstatic Bool
103dnfAndIsTrue(DNF_And xx)
104{
105 return xx->argc == 0;
106}
107
108/*
109 * Combine xx and yy into a new conjunction.
110 * Remove redundant literals along the way.
111 * Return NULL if a literal and its negation are found.
112 */
113localstatic DNF_And
114dnfAndMerge(DNF_And xx, DNF_And yy)
115{
116 DNF_And rr;
117 int xxi, yyi, rri;
118
119 if (dnfAndIsTrue(xx))
120 return dnfAndCopy(yy);
121 if (dnfAndIsTrue(yy))
122 return dnfAndCopy(xx);
123
124 rr = dnfAndNew(xx->argc + yy->argc);
125 rri = xxi = yyi = 0;
126
127 /* Merge, preserving order, removing redundant literals. */
128 while (xxi < xx->argc && yyi < yy->argc) {
129 if (dnfAtomLT(xx->argv[xxi], yy->argv[yyi]))
130 rr->argv[rri++] = xx->argv[xxi++];
131 else if (dnfAtomLT(yy->argv[yyi], xx->argv[xxi]))
132 rr->argv[rri++] = yy->argv[yyi++];
133 else if (xx->argv[xxi] == yy->argv[yyi]) {
134 xxi += 1;
135 }
136 else {
137 assert(xx->argv[xxi] == - yy->argv[yyi])do { if (!(xx->argv[xxi] == - yy->argv[yyi])) _do_assert
(("xx->argv[xxi] == - yy->argv[yyi]"),"dnf.c",137); } while
(0)
;
138 dnfAndFree(rr);
139 return NULL((void*)0);
140 }
141 }
142 while (xxi < xx->argc)
143 rr->argv[rri++] = xx->argv[xxi++];
144 while (yyi < yy->argc)
145 rr->argv[rri++] = yy->argv[yyi++];
146 rr->argc = rri;
147
148 return rr;
149}
150
151/*
152 * This tests to see if xx implies yy.
153 * If xx => yy then (xx or yy) == yy.
154 */
155
156localstatic Bool
157dnfAndImplies(DNF_And xx, DNF_And yy)
158{
159 int xxi, yyi;
160
161 /* xx implies yy if each atom in yy can be found in xx. */
162 if (xx->argc < yy->argc)
163 return false((int) 0);
164
165 xxi = yyi = 0;
166 for (xxi = yyi = 0; xxi < xx->argc && yyi < yy->argc; ) {
167 DNF_Atom xxa = xx->argv[xxi];
168 DNF_Atom yya = yy->argv[yyi];
169
170 if (dnfAtomLT(xxa, yya))
171 xxi += 1; /* Keep looking for yyi. */
172
173 else if (xxa == yya) {
174 xxi += 1; /* Found yyi. */
175 yyi += 1;
176 }
177 else
178 return false((int) 0); /* Failed to find yyi. */
179 }
180
181 /* Return true if we found each of the yyi. */
182 return yyi == yy->argc;
183}
184
185localstatic Bool
186dnfAndImpliesNegation(DNF_And xx, DNF_And yy)
187{
188 int xxi, yyi;
189
190 /* xx implies ~yy if each atom in ~yy can be found in xx. */
191 if (xx->argc < yy->argc)
192 return false((int) 0);
193
194 xxi = yyi = 0;
Value stored to 'xxi' is never read
195 for (xxi = yyi = 0; xxi < xx->argc && yyi < yy->argc; ) {
196 DNF_Atom xxa = xx->argv[xxi];
197 DNF_Atom yya = yy->argv[yyi];
198
199 if (dnfAtomLT(xxa, yya))
200 xxi += 1; /* Keep looking for yyi. */
201
202 else if (xxa == -yya) {
203 xxi += 1; /* Found yyi. */
204 yyi += 1;
205 }
206 else
207 return false((int) 0); /* Failed to find yyi. */
208 }
209
210 /* Return true if we found each of the yyi. */
211 return yyi == yy->argc;
212}
213
214localstatic DNF_And
215dnfAndCancelNegation(DNF_And xx, DNF_And yy)
216{
217 DNF_And result;
218 int xxi, yyi, rri;
219
220 /* xx implies ~yy if each atom in ~yy can be found in xx. */
221 assert (xx->argc >= yy->argc)do { if (!(xx->argc >= yy->argc)) _do_assert(("xx->argc >= yy->argc"
),"dnf.c",221); } while (0)
;
222
223 xxi = yyi = rri = 0;
224 result = dnfAndNew(xx->argc - yy->argc);
225 for (xxi = yyi = 0; xxi < xx->argc && yyi < yy->argc; ) {
226 DNF_Atom xxa = xx->argv[xxi];
227 DNF_Atom yya = yy->argv[yyi];
228
229 if (dnfAtomLT(xxa, yya)) {
230 result->argv[rri] = xx->argv[xxi];
231 rri += 1;
232 xxi += 1; /* Keep looking for yyi. */
233 yyi += 1;
234 }
235 else if (xxa == -yya) {
236 yyi += 1;
237 xxi += 1;
238 }
239 else {
240 assert(false)do { if (!(((int) 0))) _do_assert(("false"),"dnf.c",240); } while
(0)
;
241 }
242 }
243 while (xxi < xx->argc) {
244 result->argv[rri] = xx->argv[xxi];
245 xxi += 1;
246 rri += 1;
247 }
248
249 return result;
250}
251
252localstatic DNF
253dnfAndNot(DNF_And xx)
254{
255 DNF rr = dnfOrNew(xx->argc);
256 int i;
257
258 for (i = 0; i < xx->argc; i += 1) {
259 rr->argv[i] = dnfAndNew(1);
260 rr->argv[i]->argv[0] = - xx->argv[i];
261 }
262
263 return rr;
264}
265
266
267/*****************************************************************************
268 *
269 * :: Disjunctions
270 *
271 ****************************************************************************/
272
273localstatic DNF
274dnfOrNew(int argc)
275{
276 int i;
277 DNF xx;
278
279 xx = (DNF) stoAlloc(OB_DNF10, fullsizeof(*xx, argc, DNF_And)(sizeof(*xx) + (argc) * sizeof(DNF_And) - 10 * sizeof(DNF_And
))
);
280
281 xx->argc = argc;
282 for (i = 0; i < argc; i += 1)
283 xx->argv[i] = 0;
284
285 dnfDEBUGif (!dnfDebug) { } else afprintf(dbOut, ">dnfOrNew: %pDNF\n", xx);
286
287 return xx;
288}
289
290localstatic DNF
291dnfOrCopy(DNF xx)
292{
293 int i;
294 DNF yy;
295
296 dnfDEBUGif (!dnfDebug) { } else afprintf(dbOut, ">dnfOrCopy: %pDNF\n", xx);
297
298 yy = dnfOrNew(xx->argc);
299 for (i = 0; i < xx->argc; i += 1)
300 yy->argv[i] = dnfAndCopy(xx->argv[i]);
301
302 return yy;
303}
304
305localstatic void
306dnfOrFree(DNF xx)
307{
308 int i;
309
310 dnfDEBUGif (!dnfDebug) { } else afprintf(dbOut, ">dnfOrFree: %pDNF\n", xx);
311
312 for (i = 0; i < xx->argc; i += 1)
313 dnfAndFree(xx->argv[i]);
314
315 stoFree((Pointer) xx);
316}
317
318localstatic Bool
319dnfOrIsFalse(DNF xx)
320{
321 return xx->argc == 0;
322}
323
324/*
325 * Modify xx to merge redundant disjuncts.
326 */
327localstatic void
328dnfOrMerge(DNF xx)
329{
330 int i, j;
331
332 dnfDEBUGif (!dnfDebug) { } else afprintf(dbOut, ">dnfOrMerge: %pDNF\n", xx);
333
334 /* As we work, terms are merged by replacing them with NULL. */
335 for (i = 0; i < xx->argc; i += 1) {
336 for (j = 0; j < xx->argc; j += 1) {
337 /* If xxi => xxj then (xxi or xxj) == xxj. */
338 if (i != j && xx->argv[i] && xx->argv[j] &&
339 dnfAndImplies(xx->argv[i], xx->argv[j])) {
340 dnfAndFree(xx->argv[i]);
341 xx->argv[i] = NULL((void*)0);
342 }
343 if (i != j && xx->argv[i] && xx->argv[j] &&
344 dnfAndImpliesNegation(xx->argv[i], xx->argv[j])) {
345 DNF_And xxi = dnfAndCancelNegation(xx->argv[i], xx->argv[j]);
346 dnfAndFree(xx->argv[i]);
347 xx->argv[i] = xxi;
348 }
349 }
350 }
351
352 /* Now squeeze out NULLs. */
353 for (i = 0, j = 0; j < xx->argc; j += 1)
354 if (xx->argv[j])
355 xx->argv[i++] = xx->argv[j];
356 xx->argc = i;
357
358 dnfDEBUGif (!dnfDebug) { } else afprintf(dbOut, "<dnfOrMerge: %pDNF\n", xx);
359}
360
361
362/*****************************************************************************
363 *
364 * :: True and False.
365 *
366 ****************************************************************************/
367
368localstatic struct dnf_And dnfTrueProd = { 0 };
369localstatic struct dnf_Or dnfTrueStruct = { 1, { &dnfTrueProd }};
370localstatic DNF dnfTrueValue = &dnfTrueStruct;
371
372localstatic struct dnf_Or dnfFalseStruct = { 0 };
373localstatic DNF dnfFalseValue = &dnfFalseStruct;
374
375
376DNF
377dnfTrue(void)
378{
379 return dnfTrueValue;
380}
381
382DNF
383dnfFalse(void)
384{
385 return dnfFalseValue;
386}
387
388Bool
389dnfIsTrue(DNF xx)
390{
391 return xx->argc == 1 && dnfAndIsTrue(xx->argv[0]);
392}
393
394Bool
395dnfIsFalse(DNF xx)
396{
397 return dnfOrIsFalse(xx);
398}
399
400
401/*****************************************************************************
402 *
403 * :: Atoms
404 *
405 ****************************************************************************/
406
407DNF
408dnfAtom(DNF_Atom atom)
409{
410 DNF xx;
411
412 dnfDEBUGif (!dnfDebug) { } else afprintf(dbOut, ">dnfAtom: %d\n", atom);
413
414 xx = dnfOrNew(1);
415 xx->argv[0] = dnfAndNew(1);
416 xx->argv[0]->argv[0] = atom;
417
418 return xx;
419}
420
421DNF
422dnfNotAtom(DNF_Atom atom)
423{
424 return dnfAtom(-atom);
425}
426
427
428/*****************************************************************************
429 *
430 * :: Or
431 *
432 ****************************************************************************/
433
434DNF
435dnfOr(DNF xx, DNF yy)
436{
437 DNF rr;
438 int i, rri;
439
440 if (dnfIsTrue(xx) || dnfIsTrue(yy))
441 return dnfTrue();
442
443 if (dnfIsFalse(xx))
444 return dnfCopy(yy);
445 if (dnfIsFalse(yy))
446 return dnfCopy(xx);
447
448 dnfDEBUGif (!dnfDebug) { } else afprintf(dbOut, ">dnfOr: %pDNF %pDNF\n", xx, yy);
449
450 rr = dnfOrNew(xx->argc + yy->argc);
451 rri = 0;
452
453 for (i = 0; i < xx->argc; i += 1)
454 rr->argv[rri++] = dnfAndCopy(xx->argv[i]);
455 for (i = 0; i < yy->argc; i += 1)
456 rr->argv[rri++] = dnfAndCopy(yy->argv[i]);
457
458 dnfOrMerge(rr);
459
460 dnfDEBUGif (!dnfDebug) { } else afprintf(dbOut, "<dnfOr: %pDNF\n", rr);
461
462 return rr;
463}
464
465
466/*****************************************************************************
467 *
468 * :: And
469 *
470 ****************************************************************************/
471
472DNF
473dnfAnd(DNF xx, DNF yy)
474{
475 DNF rr;
476 int i, j, rri;
477
478 if (dnfIsFalse(xx) || dnfIsFalse(yy))
479 return dnfFalse();
480
481 if (dnfIsTrue(xx))
482 return dnfCopy(yy);
483 if (dnfIsTrue(yy))
484 return dnfCopy(xx);
485
486 dnfDEBUGif (!dnfDebug) { } else afprintf(dbOut, ">dnfAnd: %pDNF %pDNF\n",
487 xx, yy);
488
489 rr = dnfOrNew(xx->argc * yy->argc);
490 rri = 0;
491
492 for (i = 0; i < xx->argc; i += 1)
493 for (j = 0; j < yy->argc; j += 1, rri += 1)
494 rr->argv[rri] = dnfAndMerge(xx->argv[i], yy->argv[j]);
495
496 dnfOrMerge(rr);
497
498 dnfDEBUGif (!dnfDebug) { } else afprintf(dbOut, "<dnfAnd: %pDNF\n", rr);
499
500 return rr;
501}
502
503
504/*****************************************************************************
505 *
506 * :: Not
507 *
508 ****************************************************************************/
509
510DNF
511dnfNot(DNF xx)
512{
513 DNF aa, bb, rr;
514 int i;
515
516 if (dnfIsFalse(xx))
517 return dnfTrue();
518 if (dnfIsTrue(xx))
519 return dnfFalse();
520
521 dnfDEBUGif (!dnfDebug) { } else afprintf(dbOut, ">dnfNot: %pDNF\n", xx);
522
523 rr = dnfTrue();
524 for (i = 0; i < xx->argc; i += 1) {
525 aa = rr;
526 bb = dnfAndNot(xx->argv[i]);
527
528 rr = dnfAnd(aa, bb);
529 dnfFree(aa);
530 dnfFree(bb);
531 }
532
533 dnfDEBUGif (!dnfDebug) { } else afprintf(dbOut, "<dnfNot: %pDNF\n", rr);
534
535 return rr;
536}
537
538
539/*****************************************************************************
540 *
541 * :: General operations.
542 *
543 ****************************************************************************/
544
545DNF
546dnfCopy(DNF xx)
547{
548 return dnfOrCopy(xx);
549}
550
551void
552dnfFree(DNF xx)
553{
554 if (xx->argc == -1)
555 stoFree(xx);
556
557 if (ptrNE(xx, dnfTrueValue)(!((Pointer)((Pointer)(xx)) == (Pointer)((Pointer)(dnfTrueValue
))))
&& ptrNE(xx, dnfFalseValue)(!((Pointer)((Pointer)(xx)) == (Pointer)((Pointer)(dnfFalseValue
))))
)
558 dnfOrFree(xx);
559}
560
561int
562dnfPrint(FILE *fout, DNF xx)
563{
564 DNF_And xxi;
565 int i, j, cc = 0;
566
567 cc = fprintf(fout, "DNF{");
568 for (i = 0; i < xx->argc; i += 1) {
569 xxi = xx->argv[i];
570 if (i > 0) cc += fprintf(fout, " ");
571 cc += fprintf(fout, "[");
572 for (j = 0; j < xxi->argc; j += 1) {
573 if (j > 0) cc += fprintf(fout, " ");
574 cc += fprintf(fout, "%d", xxi->argv[j]);
575 }
576 cc += fprintf(fout, "]");
577 }
578 cc += fprintf(fout, "}");
579 return cc;
580}
581
582
583/******************************************************************************
584 *
585 * :: Equal
586 *
587 *****************************************************************************/
588
589Bool
590dnfEqual(DNF xx, DNF yy)
591{
592 if (xx == yy) return true1;
593 return dnfImplies(xx, yy) && dnfImplies(yy, xx);
594}
595
596/*
597 * xx => yy if each disjunct in xx implies a disjunct in yy.
598 */
599Bool
600dnfImplies(DNF xx, DNF yy)
601{
602 Bool result = true1;
603 int i, j;
604
605 for (i = 0; result && i < xx->argc; i += 1) {
606 result = false((int) 0);
607 for (j = 0; !result && j < yy->argc; j += 1)
608 result = dnfAndImplies(xx->argv[i], yy->argv[j]);
609 }
610
611 return result;
612}
613
614/******************************************************************************
615 *
616 * :: Mapping
617 *
618 *****************************************************************************/
619localstatic Bool
620dnfExpandAndImplies(Bool (*testFn)(void *, DNF_Atom, DNF_Atom),
621 void *clos, DNF_And xx, DNF_And yy);
622
623void
624dnfMap(Bool (*mapFn)(void*, DNF_Atom), void * clos, DNF xx)
625{
626 DNF_And xxi;
627 int i, j;
628
629 for (i=0; i<xx->argc; i++) {
630 xxi = xx->argv[i];
631 for (j=0; j < xxi->argc; j++)
632 if (mapFn(clos, xxi->argv[j]))
633 return;
634 }
635}
636
637Bool
638dnfExpandImplies(Bool (*testFn)(void *, DNF_Atom, DNF_Atom),
639 void *clos,
640 DNF xx, DNF yy)
641{
642 Bool result = true1;
643 int i, j;
644
645 for (i = 0; result && i < xx->argc; i += 1) {
646 result = false((int) 0);
647 for (j = 0; !result && j < yy->argc; j += 1)
648 result = dnfExpandAndImplies(testFn, clos,
649 xx->argv[i], yy->argv[j]);
650 }
651
652 return result;
653}
654
655localstatic Bool
656dnfExpandAndImplies(Bool (*testFn)(void *, DNF_Atom, DNF_Atom),
657 void *clos, DNF_And xx, DNF_And yy)
658{
659 int xxi, yyi;
660
661 /* xx implies yy if each atom in yy can be found in xx. */
662 if (xx->argc < yy->argc)
663 return false((int) 0);
664
665 xxi = yyi = 0;
666 for (xxi = yyi = 0; xxi < xx->argc && yyi < yy->argc; ) {
667 DNF_Atom xxa = xx->argv[xxi];
668 DNF_Atom yya = yy->argv[yyi];
669
670 if (xxa == yya) {
671 xxi += 1; /* Found yyi. */
672 yyi += 1;
673 }
674 else {
675 /* Be a bit more enthusiastic */
676 Bool res = false((int) 0);
677 int ti;
678 for (ti=0; (!res) && ti < xx->argc; ti++) {
679 xxa = xx->argv[ti];
680 res = (*testFn)(clos, xxa, yya);
681 }
682 if (!res)
683 return false((int) 0); /* Failed to find yyi. */
684 yyi++;
685 }
686 }
687
688 /* Return true if we found each of the yyi. */
689 return yyi == yy->argc;
690}
691
692
693/******************************************************************************
694 *
695 * :: Aliasing
696 * !!! This is currently broken, so don't try to use it.
697 *****************************************************************************/
698
699DNF
700dnfFollow(DNF dnf)
701{
702#if 0
703 if (dnf->argc != -1)
704 return dnf;
705 else {
706 dnf->argv[0] = dnfFollow( (DNF) dnf->argv[0]);
707 return (DNF) dnf->argv[0];
708 }
709#endif
710 return dnf;
711}
712
713void
714dnfAlias(DNF old, DNF new)
715{
716 int i;
717 /* If we start wanting to alias false (unlikely),
718 * then fix min. alloc to be 1 slot.
719 */
720 if (old->argc != -1) {
721 assert(old->argc != 0)do { if (!(old->argc != 0)) _do_assert(("old->argc != 0"
),"dnf.c",721); } while (0)
;
722 for (i=0; i < old->argc; i++)
723 dnfAndFree(old->argv[i]);
724 old->argc = -1;
725 }
726 old->argv[0] = (DNF_And) new;
727}
728
729int
730dnfFormatter(OStream ostream, Pointer p)
731{
732 DNF dnf = (DNF) p;
733 int c, i, j;
734
735 if (dnfIsTrue(dnf))
736 c = ostreamWrite(ostream, "[TRUE]", -1);
737 else if (dnfIsFalse(dnf))
738 c = ostreamWrite(ostream, "[FALSE]", -1);
739 else {
740 String sep = "";
741 c = ostreamWrite(ostream, "[", -1);
742 for (i = 0; i < dnf->argc; i++) {
743 DNF_And xx;
744 c += ostreamWrite(ostream, sep, -1);
745 sep = " ";
746 xx = dnf->argv[i];
747 c = ostreamWrite(ostream, "[", -1);
748 for (j = 0; j < xx->argc; j++) {
749 c += ostreamPrintf(ostream, "%s%d",
750 j > 0 ? " " : "",
751 xx->argv[j]);
752 }
753 c += ostreamWrite(ostream, "]", -1);
754 }
755 c += ostreamWrite(ostream, "]", -1);
756 }
757 return c;
758}