Implemented ccl_pquery to convert from CCL tree to prefix query.
[yaz-moved-to-github.git] / zutil / yaz-ccl.c
1 /*
2  * Copyright (c) 1996-1999, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: yaz-ccl.c,v $
7  * Revision 1.4  1999-12-20 15:20:13  adam
8  * Implemented ccl_pquery to convert from CCL tree to prefix query.
9  *
10  * Revision 1.3  1999/11/30 13:47:12  adam
11  * Improved installation. Moved header files to include/yaz.
12  *
13  * Revision 1.2  1999/06/16 12:00:08  adam
14  * Added proximity.
15  *
16  * Revision 1.1  1999/06/08 10:12:43  adam
17  * Moved file to be part of zutil (instead of util).
18  *
19  * Revision 1.13  1998/03/31 15:13:20  adam
20  * Development towards compiled ASN.1.
21  *
22  * Revision 1.12  1998/02/11 11:53:36  adam
23  * Changed code so that it compiles as C++.
24  *
25  * Revision 1.11  1997/11/24 11:33:57  adam
26  * Using function odr_nullval() instead of global ODR_NULLVAL when
27  * appropriate.
28  *
29  * Revision 1.10  1997/09/29 08:58:25  adam
30  * Fixed conversion of trees so that true copy is made.
31  *
32  * Revision 1.9  1997/06/23 10:31:25  adam
33  * Added ODR argument to ccl_rpn_query and ccl_scan_query.
34  *
35  * Revision 1.8  1996/10/29 13:36:27  adam
36  * Added header.
37  *
38  */
39
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <assert.h>
44
45 #include <yaz/yaz-ccl.h>
46
47 static Z_RPNStructure *ccl_rpn_structure (ODR o, struct ccl_rpn_node *p);
48
49 static Z_AttributesPlusTerm *ccl_rpn_term (ODR o, struct ccl_rpn_node *p)
50 {
51     struct ccl_rpn_attr *attr;
52     int num = 0;
53     Z_AttributesPlusTerm *zapt;
54     Odr_oct *term_octet;
55     Z_Term *term;
56     Z_AttributeElement **elements;
57
58     zapt = (Z_AttributesPlusTerm *)odr_malloc (o, sizeof(*zapt));
59     assert (zapt);
60
61     term_octet = (Odr_oct *)odr_malloc (o, sizeof(*term_octet));
62     assert (term_octet);
63
64     term = (Z_Term *)odr_malloc (o, sizeof(*term));
65     assert(term);
66
67     for (attr = p->u.t.attr_list; attr; attr = attr->next)
68         num++;
69     if (!num)
70         elements = (Z_AttributeElement**)odr_nullval();
71     else
72     {
73         int i = 0;
74         elements = (Z_AttributeElement **)
75             odr_malloc (o, num*sizeof(*elements));
76         for (attr = p->u.t.attr_list; attr; attr = attr->next, i++)
77         {
78             elements[i] = (Z_AttributeElement *)
79                 odr_malloc (o, sizeof(**elements));
80             assert (elements[i]);
81             elements[i]->attributeType =
82                 (int *)odr_malloc(o, sizeof(int));
83             *elements[i]->attributeType = attr->type;
84             elements[i]->attributeSet = 0;
85             elements[i]->which = Z_AttributeValue_numeric;
86             elements[i]->value.numeric =
87                 (int *)odr_malloc (o, sizeof(int));
88             *elements[i]->value.numeric = attr->value;
89         }
90     }
91 #ifdef ASN_COMPILED
92     zapt->attributes = (Z_AttributeList *)
93         odr_malloc (o, sizeof(*zapt->attributes));
94     zapt->attributes->num_attributes = num;
95     zapt->attributes->attributes = elements;
96 #else
97     zapt->num_attributes = num;
98     zapt->attributeList = elements;
99 #endif    
100     zapt->term = term;
101     term->which = Z_Term_general;
102     term->u.general = term_octet;
103     term_octet->len = term_octet->size = strlen (p->u.t.term);
104     term_octet->buf = (unsigned char *)odr_malloc (o, term_octet->len+1);
105     strcpy ((char*) term_octet->buf, p->u.t.term);
106     return zapt;
107 }
108
109 static Z_Operand *ccl_rpn_simple (ODR o, struct ccl_rpn_node *p)
110 {
111     Z_Operand *zo;
112
113     zo = (Z_Operand *)odr_malloc (o, sizeof(*zo));
114     assert (zo);
115
116     switch (p->kind)
117     {
118     case CCL_RPN_TERM:
119         zo->which = Z_Operand_APT;
120         zo->u.attributesPlusTerm = ccl_rpn_term (o, p);
121         break;
122     case CCL_RPN_SET:
123         zo->which = Z_Operand_resultSetId;
124         zo->u.resultSetId = p->u.setname;
125         break;
126     default:
127         assert (0);
128     }
129     return zo;
130 }
131
132 static Z_Complex *ccl_rpn_complex (ODR o, struct ccl_rpn_node *p)
133 {
134     Z_Complex *zc;
135     Z_Operator *zo;
136
137     zc = (Z_Complex *)odr_malloc (o, sizeof(*zc));
138     assert (zc);
139     zo = (Z_Operator *)odr_malloc (o, sizeof(*zo));
140     assert (zo);
141
142     zc->roperator = zo;
143     switch (p->kind)
144     {
145     case CCL_RPN_AND:
146         zo->which = Z_Operator_and;
147         zo->u.and = odr_nullval();
148         break;
149     case CCL_RPN_OR:
150         zo->which = Z_Operator_or;
151         zo->u.and = odr_nullval();
152         break;
153     case CCL_RPN_NOT:
154         zo->which = Z_Operator_and_not;
155         zo->u.and = odr_nullval();
156         break;
157     case CCL_RPN_PROX:
158         zo->which = Z_Operator_prox;
159         zo->u.prox = (Z_ProximityOperator *)
160             odr_malloc (o, sizeof(*zo->u.prox));
161         zo->u.prox->exclusion = 0;
162
163         zo->u.prox->distance = (int *)
164             odr_malloc (o, sizeof(*zo->u.prox->distance));
165         *zo->u.prox->distance = 2;
166
167         zo->u.prox->ordered = (bool_t *)
168             odr_malloc (o, sizeof(*zo->u.prox->ordered));
169         *zo->u.prox->ordered = 0;
170
171         zo->u.prox->relationType = (int *)
172             odr_malloc (o, sizeof(*zo->u.prox->relationType));
173 #ifdef ASN_COMPILED
174         *zo->u.prox->relationType = Z_ProximityOperator_Prox_lessThan;
175         zo->u.prox->which = Z_ProximityOperator_known;
176         zo->u.prox->u.known = 
177             odr_malloc (o, sizeof(*zo->u.prox->u.known));
178         *zo->u.prox->u.known = Z_ProxUnit_word;
179 #else
180         *zo->u.prox->relationType = Z_Prox_lessThan;
181         zo->u.prox->which = Z_ProxCode_known;
182         zo->u.prox->proximityUnitCode = (int*)
183             odr_malloc (o, sizeof(*zo->u.prox->proximityUnitCode));
184         *zo->u.prox->proximityUnitCode = Z_ProxUnit_word;
185 #endif
186         break;
187     default:
188         assert (0);
189     }
190     zc->s1 = ccl_rpn_structure (o, p->u.p[0]);
191     zc->s2 = ccl_rpn_structure (o, p->u.p[1]);
192     return zc;
193 }
194
195 static Z_RPNStructure *ccl_rpn_structure (ODR o, struct ccl_rpn_node *p)
196 {
197     Z_RPNStructure *zs;
198
199     zs = (Z_RPNStructure *)odr_malloc (o, sizeof(*zs));
200     assert (zs);
201     switch (p->kind)
202     {
203     case CCL_RPN_AND:
204     case CCL_RPN_OR:
205     case CCL_RPN_NOT:
206     case CCL_RPN_PROX:
207         zs->which = Z_RPNStructure_complex;
208         zs->u.complex = ccl_rpn_complex (o, p);
209         break;
210     case CCL_RPN_TERM:
211     case CCL_RPN_SET:
212         zs->which = Z_RPNStructure_simple;
213         zs->u.simple = ccl_rpn_simple (o, p);
214         break;
215     default:
216         assert (0);
217     }
218     return zs;
219 }
220
221 Z_RPNQuery *ccl_rpn_query (ODR o, struct ccl_rpn_node *p)
222 {
223     Z_RPNQuery *zq;
224
225     zq = (Z_RPNQuery *)odr_malloc (o, sizeof(*zq));
226     assert (zq);
227     zq->attributeSetId = NULL;
228     zq->RPNStructure = ccl_rpn_structure (o, p);
229     return zq;
230 }
231
232 Z_AttributesPlusTerm *ccl_scan_query (ODR o, struct ccl_rpn_node *p)
233 {
234     if (p->kind != CCL_RPN_TERM)
235         return NULL;
236     return ccl_rpn_term (o, p);
237 }
238
239 static void ccl_pquery_complex (WRBUF w, struct ccl_rpn_node *p)
240 {
241     switch (p->kind)
242     {
243     case CCL_RPN_AND:
244         wrbuf_puts (w, "@and ");
245         break;
246     case CCL_RPN_OR:
247         wrbuf_puts(w, "@or ");
248         break;
249     case CCL_RPN_NOT:
250         wrbuf_puts(w, "@not ");
251         break;
252     case CCL_RPN_PROX:
253         wrbuf_puts(w, "@prox 0 2 0 1 known 2 ");
254         break;
255     default:
256         assert(0);
257     };
258     ccl_pquery(w, p->u.p[0]);
259     ccl_pquery(w, p->u.p[1]);
260 }
261         
262 void ccl_pquery (WRBUF w, struct ccl_rpn_node *p)
263 {
264     struct ccl_rpn_attr *att;
265
266     switch (p->kind)
267     {
268     case CCL_RPN_AND:
269     case CCL_RPN_OR:
270     case CCL_RPN_NOT:
271     case CCL_RPN_PROX:
272         ccl_pquery_complex (w, p);
273         break;
274     case CCL_RPN_SET:
275         wrbuf_puts (w, "@set ");
276         wrbuf_puts (w, p->u.setname);
277         wrbuf_puts (w, " ");
278         break;
279     case CCL_RPN_TERM:
280         for (att = p->u.t.attr_list; att; att = att->next)
281         {
282             char tmpattr[128];
283             sprintf(tmpattr, "@attr %d=%d ", att->type, att->value);
284             wrbuf_puts (w, tmpattr);
285         }
286         wrbuf_puts (w, "{");
287         wrbuf_puts (w, p->u.t.term);
288         wrbuf_puts (w, "} ");
289         break;
290     default:
291         assert (0);
292     };
293 }