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