Minor change.
[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.6  2000-02-02 15:13:23  adam
8  * Minor change.
9  *
10  * Revision 1.5  2000/01/31 13:15:22  adam
11  * Removed uses of assert(3). Cleanup of ODR. CCL parser update so
12  * that some characters are not surrounded by spaces in resulting term.
13  * ILL-code updates.
14  *
15  * Revision 1.4  1999/12/20 15:20:13  adam
16  * Implemented ccl_pquery to convert from CCL tree to prefix query.
17  *
18  * Revision 1.3  1999/11/30 13:47:12  adam
19  * Improved installation. Moved header files to include/yaz.
20  *
21  * Revision 1.2  1999/06/16 12:00:08  adam
22  * Added proximity.
23  *
24  * Revision 1.1  1999/06/08 10:12:43  adam
25  * Moved file to be part of zutil (instead of util).
26  *
27  * Revision 1.13  1998/03/31 15:13:20  adam
28  * Development towards compiled ASN.1.
29  *
30  * Revision 1.12  1998/02/11 11:53:36  adam
31  * Changed code so that it compiles as C++.
32  *
33  * Revision 1.11  1997/11/24 11:33:57  adam
34  * Using function odr_nullval() instead of global ODR_NULLVAL when
35  * appropriate.
36  *
37  * Revision 1.10  1997/09/29 08:58:25  adam
38  * Fixed conversion of trees so that true copy is made.
39  *
40  * Revision 1.9  1997/06/23 10:31:25  adam
41  * Added ODR argument to ccl_rpn_query and ccl_scan_query.
42  *
43  * Revision 1.8  1996/10/29 13:36:27  adam
44  * Added header.
45  *
46  */
47
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51
52 #include <yaz/yaz-ccl.h>
53
54 static Z_RPNStructure *ccl_rpn_structure (ODR o, struct ccl_rpn_node *p);
55
56 static Z_AttributesPlusTerm *ccl_rpn_term (ODR o, struct ccl_rpn_node *p)
57 {
58     struct ccl_rpn_attr *attr;
59     int num = 0;
60     Z_AttributesPlusTerm *zapt;
61     Odr_oct *term_octet;
62     Z_Term *term;
63     Z_AttributeElement **elements;
64
65     zapt = (Z_AttributesPlusTerm *)odr_malloc (o, sizeof(*zapt));
66
67     term_octet = (Odr_oct *)odr_malloc (o, sizeof(*term_octet));
68
69     term = (Z_Term *)odr_malloc (o, sizeof(*term));
70
71     for (attr = p->u.t.attr_list; attr; attr = attr->next)
72         num++;
73     if (!num)
74         elements = (Z_AttributeElement**)odr_nullval();
75     else
76     {
77         int i = 0;
78         elements = (Z_AttributeElement **)
79             odr_malloc (o, num*sizeof(*elements));
80         for (attr = p->u.t.attr_list; attr; attr = attr->next, i++)
81         {
82             elements[i] = (Z_AttributeElement *)
83                 odr_malloc (o, sizeof(**elements));
84             elements[i]->attributeType =
85                 (int *)odr_malloc(o, sizeof(int));
86             *elements[i]->attributeType = attr->type;
87             elements[i]->attributeSet = 0;
88             elements[i]->which = Z_AttributeValue_numeric;
89             elements[i]->value.numeric =
90                 (int *)odr_malloc (o, sizeof(int));
91             *elements[i]->value.numeric = attr->value;
92         }
93     }
94 #ifdef ASN_COMPILED
95     zapt->attributes = (Z_AttributeList *)
96         odr_malloc (o, sizeof(*zapt->attributes));
97     zapt->attributes->num_attributes = num;
98     zapt->attributes->attributes = elements;
99 #else
100     zapt->num_attributes = num;
101     zapt->attributeList = elements;
102 #endif    
103     zapt->term = term;
104     term->which = Z_Term_general;
105     term->u.general = term_octet;
106     term_octet->len = term_octet->size = strlen (p->u.t.term);
107     term_octet->buf = (unsigned char *)odr_malloc (o, term_octet->len+1);
108     strcpy ((char*) term_octet->buf, p->u.t.term);
109     return zapt;
110 }
111
112 static Z_Operand *ccl_rpn_simple (ODR o, struct ccl_rpn_node *p)
113 {
114     Z_Operand *zo;
115
116     zo = (Z_Operand *)odr_malloc (o, sizeof(*zo));
117
118     switch (p->kind)
119     {
120     case CCL_RPN_TERM:
121         zo->which = Z_Operand_APT;
122         zo->u.attributesPlusTerm = ccl_rpn_term (o, p);
123         break;
124     case CCL_RPN_SET:
125         zo->which = Z_Operand_resultSetId;
126         zo->u.resultSetId = p->u.setname;
127         break;
128     default:
129         return 0;
130     }
131     return zo;
132 }
133
134 static Z_Complex *ccl_rpn_complex (ODR o, struct ccl_rpn_node *p)
135 {
136     Z_Complex *zc;
137     Z_Operator *zo;
138
139     zc = (Z_Complex *)odr_malloc (o, sizeof(*zc));
140     zo = (Z_Operator *)odr_malloc (o, sizeof(*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         return 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     switch (p->kind)
201     {
202     case CCL_RPN_AND:
203     case CCL_RPN_OR:
204     case CCL_RPN_NOT:
205     case CCL_RPN_PROX:
206         zs->which = Z_RPNStructure_complex;
207         zs->u.complex = ccl_rpn_complex (o, p);
208         break;
209     case CCL_RPN_TERM:
210     case CCL_RPN_SET:
211         zs->which = Z_RPNStructure_simple;
212         zs->u.simple = ccl_rpn_simple (o, p);
213         break;
214     default:
215         return 0;
216     }
217     return zs;
218 }
219
220 Z_RPNQuery *ccl_rpn_query (ODR o, struct ccl_rpn_node *p)
221 {
222     Z_RPNQuery *zq;
223
224     zq = (Z_RPNQuery *)odr_malloc (o, sizeof(*zq));
225     zq->attributeSetId = NULL;
226     zq->RPNStructure = ccl_rpn_structure (o, p);
227     return zq;
228 }
229
230 Z_AttributesPlusTerm *ccl_scan_query (ODR o, struct ccl_rpn_node *p)
231 {
232     if (p->kind != CCL_RPN_TERM)
233         return NULL;
234     return ccl_rpn_term (o, p);
235 }
236
237 static void ccl_pquery_complex (WRBUF w, struct ccl_rpn_node *p)
238 {
239     switch (p->kind)
240     {
241     case CCL_RPN_AND:
242         wrbuf_puts (w, "@and ");
243         break;
244     case CCL_RPN_OR:
245         wrbuf_puts(w, "@or ");
246         break;
247     case CCL_RPN_NOT:
248         wrbuf_puts(w, "@not ");
249         break;
250     case CCL_RPN_PROX:
251         wrbuf_puts(w, "@prox 0 2 0 1 known 2 ");
252         break;
253     default:
254         wrbuf_puts(w, "@ bad op (unknown) ");
255     };
256     ccl_pquery(w, p->u.p[0]);
257     ccl_pquery(w, p->u.p[1]);
258 }
259         
260 void ccl_pquery (WRBUF w, struct ccl_rpn_node *p)
261 {
262     struct ccl_rpn_attr *att;
263
264     switch (p->kind)
265     {
266     case CCL_RPN_AND:
267     case CCL_RPN_OR:
268     case CCL_RPN_NOT:
269     case CCL_RPN_PROX:
270         ccl_pquery_complex (w, p);
271         break;
272     case CCL_RPN_SET:
273         wrbuf_puts (w, "@set ");
274         wrbuf_puts (w, p->u.setname);
275         wrbuf_puts (w, " ");
276         break;
277     case CCL_RPN_TERM:
278         for (att = p->u.t.attr_list; att; att = att->next)
279         {
280             char tmpattr[128];
281             sprintf(tmpattr, "@attr %d=%d ", att->type, att->value);
282             wrbuf_puts (w, tmpattr);
283         }
284         wrbuf_puts (w, "{");
285         wrbuf_puts (w, p->u.t.term);
286         wrbuf_puts (w, "} ");
287         break;
288     }
289 }