5a48e5e8bfbf6413f673ccaec69d669c67c4051f
[rrq/rrqmisc.git] / vector / OrQuery.c
1 #include <stdarg.h>
2 #include <stdlib.h>
3 #include <OrQuery.h>
4
5 static void OrQuery_reclaim(Query *this) {
6     OrQuery *q = (OrQuery*) this;
7     int i;
8     for ( i = 0; i < q->size; i++ ) {
9         Query_reclaim( q->disjuncts[i] );
10     }
11     free( q->disjuncts );
12     free( this );
13 }
14
15 static int OrQuery_next( Query *this,BindingTable *bt,enum NextState state) {
16     OrQuery *q = (OrQuery*) this;
17     int i = q->index;
18     enum NextState s = subsequent;
19     switch ( state ) {
20     case initial:
21         i = 0;
22         s = initial;
23     case subsequent:
24         for ( ; i < q->size; i++ ) {
25             if ( Query_next( q->disjuncts[i], bt, s ) ) {
26                 q->index = i;
27                 return 1;
28             }
29             Query_next( q->disjuncts[i], bt, restore );
30             s = initial;
31         }
32         q->index = -1;
33         return 0;
34     case restore:
35         if ( i >= 0 ) {
36             Query_next( q->disjuncts[i], bt, restore );
37             q->index = -1;
38         }
39         return 0;
40     }
41     return 0;
42 }
43
44 static void OrQuery_variables(Query *this,HashVector *hv) {
45     OrQuery *q = (OrQuery*) this;
46     int i; 
47     for ( i = 0; i < q->size; i++ ) {
48         Query_variables( q->disjuncts[i], hv );
49     }
50 }
51
52 static struct QueryCallbacks OrQuery_def = {
53     .reclaim = OrQuery_reclaim,
54     .next = OrQuery_next,
55     .variables = OrQuery_variables
56 };
57
58 Query *Query_or(int n,...) {
59     va_list args;
60     OrQuery *q = (OrQuery *)
61         malloc( sizeof( OrQuery ) );
62     (*q) = (OrQuery) {
63         .def = &OrQuery_def,
64         .index = -1,
65         .size = n,
66         .disjuncts = (Query**) malloc( n * sizeof( Query* ) ),
67     };
68     int i;
69     va_start( args, n );
70     for ( i = 0; i < n; i++ ) {
71         q->disjuncts[i] = va_arg( args, Query* );
72     }
73     va_end( args );
74     return (Query*) q;
75 }
76