Separate malloc debug library. Removal of ASN_COMPILED-#ifdefs.
[yaz-moved-to-github.git] / zutil / yaz-ccl.c
1 /*
2  * Copyright (c) 1996-2001, Index Data.
3  * See the file LICENSE for details.
4  *
5  * $Id: yaz-ccl.c,v 1.15 2001-11-13 23:00:43 adam Exp $
6  */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include <yaz/yaz-ccl.h>
13
14 static Z_RPNStructure *ccl_rpn_structure (ODR o, struct ccl_rpn_node *p);
15
16 static Z_AttributesPlusTerm *ccl_rpn_term (ODR o, struct ccl_rpn_node *p)
17 {
18     struct ccl_rpn_attr *attr;
19     int num = 0;
20     Z_AttributesPlusTerm *zapt;
21     Odr_oct *term_octet;
22     Z_Term *term;
23     Z_AttributeElement **elements;
24
25     zapt = (Z_AttributesPlusTerm *)odr_malloc (o, sizeof(*zapt));
26
27     term_octet = (Odr_oct *)odr_malloc (o, sizeof(*term_octet));
28
29     term = (Z_Term *)odr_malloc (o, sizeof(*term));
30
31     for (attr = p->u.t.attr_list; attr; attr = attr->next)
32         num++;
33     if (!num)
34         elements = (Z_AttributeElement**)odr_nullval();
35     else
36     {
37         int i = 0;
38         elements = (Z_AttributeElement **)
39             odr_malloc (o, num*sizeof(*elements));
40         for (attr = p->u.t.attr_list; attr; attr = attr->next, i++)
41         {
42             elements[i] = (Z_AttributeElement *)
43                 odr_malloc (o, sizeof(**elements));
44             elements[i]->attributeType =
45                 (int *)odr_malloc(o, sizeof(int));
46             *elements[i]->attributeType = attr->type;
47             elements[i]->attributeSet = 0;
48             if (attr->set && *attr->set)
49             {
50                 int value = oid_getvalbyname (attr->set);
51
52                 if (value != VAL_NONE)
53                 {
54                     elements[i]->attributeSet =
55                         yaz_oidval_to_z3950oid(o, CLASS_ATTSET, value);
56                 }
57             }
58             elements[i]->which = Z_AttributeValue_numeric;
59             elements[i]->value.numeric =
60                 (int *)odr_malloc (o, sizeof(int));
61             *elements[i]->value.numeric = attr->value;
62         }
63     }
64     zapt->attributes = (Z_AttributeList *)
65         odr_malloc (o, sizeof(*zapt->attributes));
66     zapt->attributes->num_attributes = num;
67     zapt->attributes->attributes = elements;
68     zapt->term = term;
69     term->which = Z_Term_general;
70     term->u.general = term_octet;
71     term_octet->len = term_octet->size = strlen (p->u.t.term);
72     term_octet->buf = (unsigned char *)odr_malloc (o, term_octet->len+1);
73     strcpy ((char*) term_octet->buf, p->u.t.term);
74     return zapt;
75 }
76
77 static Z_Operand *ccl_rpn_simple (ODR o, struct ccl_rpn_node *p)
78 {
79     Z_Operand *zo;
80
81     zo = (Z_Operand *)odr_malloc (o, sizeof(*zo));
82
83     switch (p->kind)
84     {
85     case CCL_RPN_TERM:
86         zo->which = Z_Operand_APT;
87         zo->u.attributesPlusTerm = ccl_rpn_term (o, p);
88         break;
89     case CCL_RPN_SET:
90         zo->which = Z_Operand_resultSetId;
91         zo->u.resultSetId = odr_strdup (o, p->u.setname);
92         break;
93     default:
94         return 0;
95     }
96     return zo;
97 }
98
99 static Z_Complex *ccl_rpn_complex (ODR o, struct ccl_rpn_node *p)
100 {
101     Z_Complex *zc;
102     Z_Operator *zo;
103
104     zc = (Z_Complex *)odr_malloc (o, sizeof(*zc));
105     zo = (Z_Operator *)odr_malloc (o, sizeof(*zo));
106
107     zc->roperator = zo;
108     switch (p->kind)
109     {
110     case CCL_RPN_AND:
111         zo->which = Z_Operator_and;
112         zo->u.and_not = odr_nullval();
113         break;
114     case CCL_RPN_OR:
115         zo->which = Z_Operator_or;
116         zo->u.and_not = odr_nullval();
117         break;
118     case CCL_RPN_NOT:
119         zo->which = Z_Operator_and_not;
120         zo->u.and_not = odr_nullval();
121         break;
122     case CCL_RPN_PROX:
123         zo->which = Z_Operator_prox;
124         zo->u.prox = (Z_ProximityOperator *)
125             odr_malloc (o, sizeof(*zo->u.prox));
126         zo->u.prox->exclusion = 0;
127
128         zo->u.prox->distance = (int *)
129             odr_malloc (o, sizeof(*zo->u.prox->distance));
130         *zo->u.prox->distance = 2;
131
132         zo->u.prox->ordered = (bool_t *)
133             odr_malloc (o, sizeof(*zo->u.prox->ordered));
134         *zo->u.prox->ordered = 0;
135
136         zo->u.prox->relationType = (int *)
137             odr_malloc (o, sizeof(*zo->u.prox->relationType));
138         *zo->u.prox->relationType = Z_ProximityOperator_Prox_lessThan;
139         zo->u.prox->which = Z_ProximityOperator_known;
140         zo->u.prox->u.known = 
141             (Z_ProxUnit *) odr_malloc (o, sizeof(*zo->u.prox->u.known));
142         *zo->u.prox->u.known = Z_ProxUnit_word;
143         break;
144     default:
145         return 0;
146     }
147     zc->s1 = ccl_rpn_structure (o, p->u.p[0]);
148     zc->s2 = ccl_rpn_structure (o, p->u.p[1]);
149     return zc;
150 }
151
152 static Z_RPNStructure *ccl_rpn_structure (ODR o, struct ccl_rpn_node *p)
153 {
154     Z_RPNStructure *zs;
155
156     zs = (Z_RPNStructure *)odr_malloc (o, sizeof(*zs));
157     switch (p->kind)
158     {
159     case CCL_RPN_AND:
160     case CCL_RPN_OR:
161     case CCL_RPN_NOT:
162     case CCL_RPN_PROX:
163         zs->which = Z_RPNStructure_complex;
164         zs->u.complex = ccl_rpn_complex (o, p);
165         break;
166     case CCL_RPN_TERM:
167     case CCL_RPN_SET:
168         zs->which = Z_RPNStructure_simple;
169         zs->u.simple = ccl_rpn_simple (o, p);
170         break;
171     default:
172         return 0;
173     }
174     return zs;
175 }
176
177 Z_RPNQuery *ccl_rpn_query (ODR o, struct ccl_rpn_node *p)
178 {
179     Z_RPNQuery *zq = (Z_RPNQuery *)odr_malloc (o, sizeof(*zq));
180     zq->attributeSetId = yaz_oidval_to_z3950oid (o, CLASS_ATTSET, VAL_BIB1);
181     zq->RPNStructure = ccl_rpn_structure (o, p);
182     return zq;
183 }
184
185 Z_AttributesPlusTerm *ccl_scan_query (ODR o, struct ccl_rpn_node *p)
186 {
187     if (p->kind != CCL_RPN_TERM)
188         return NULL;
189     return ccl_rpn_term (o, p);
190 }
191
192 static void ccl_pquery_complex (WRBUF w, struct ccl_rpn_node *p)
193 {
194     switch (p->kind)
195     {
196     case CCL_RPN_AND:
197         wrbuf_puts (w, "@and ");
198         break;
199     case CCL_RPN_OR:
200         wrbuf_puts(w, "@or ");
201         break;
202     case CCL_RPN_NOT:
203         wrbuf_puts(w, "@not ");
204         break;
205     case CCL_RPN_PROX:
206         wrbuf_puts(w, "@prox 0 2 0 1 known 2 ");
207         break;
208     default:
209         wrbuf_puts(w, "@ bad op (unknown) ");
210     };
211     ccl_pquery(w, p->u.p[0]);
212     ccl_pquery(w, p->u.p[1]);
213 }
214         
215 void ccl_pquery (WRBUF w, struct ccl_rpn_node *p)
216 {
217     struct ccl_rpn_attr *att;
218     const char *cp;
219
220     switch (p->kind)
221     {
222     case CCL_RPN_AND:
223     case CCL_RPN_OR:
224     case CCL_RPN_NOT:
225     case CCL_RPN_PROX:
226         ccl_pquery_complex (w, p);
227         break;
228     case CCL_RPN_SET:
229         wrbuf_puts (w, "@set ");
230         wrbuf_puts (w, p->u.setname);
231         wrbuf_puts (w, " ");
232         break;
233     case CCL_RPN_TERM:
234         for (att = p->u.t.attr_list; att; att = att->next)
235         {
236             char tmpattr[128];
237             wrbuf_puts (w, "@attr ");
238             if (att->set)
239             {
240                 wrbuf_puts (w, att->set);
241                 wrbuf_puts (w, " ");
242             }
243             sprintf(tmpattr, "%d=%d ", att->type, att->value);
244             wrbuf_puts (w, tmpattr);
245         }
246         for (cp = p->u.t.term; *cp; cp++)
247         {
248             if (*cp == ' ' || *cp == '\\')
249                 wrbuf_putc (w, '\\');
250             wrbuf_putc (w, *cp);
251         }
252         wrbuf_puts (w, " ");
253         break;
254     }
255 }