2 * Copyright (c) 1995-1996, Index Data.
3 * See the file LICENSE for details.
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.10 1996-08-12 14:10:35 adam
8 * New function p_query_attset to define default attribute set.
10 * Revision 1.9 1996/03/15 11:03:46 adam
11 * Attribute set can be set globally for a query with the @attrset
12 * operator. The @attr operator has an optional attribute-set specifier
13 * that sets the attribute set locally.
15 * Revision 1.8 1996/01/02 11:46:56 quinn
16 * Changed 'operator' to 'roperator' to avoid C++ conflict.
18 * Revision 1.7 1995/09/29 17:12:36 quinn
21 * Revision 1.6 1995/09/27 15:03:03 quinn
22 * Modified function heads & prototypes.
24 * Revision 1.5 1995/06/15 12:31:02 quinn
25 * *** empty log message ***
27 * Revision 1.4 1995/06/15 07:45:19 quinn
30 * Revision 1.3 1995/06/14 11:06:35 adam
31 * Bug fix: Attributes wasn't interpreted correctly!
33 * Revision 1.2 1995/05/26 08:56:11 adam
34 * New function: p_query_scan.
36 * Revision 1.1 1995/05/22 15:31:49 adam
37 * New function, p_query_rpn, to convert from prefix (ascii) to rpn (asn).
50 static oid_value p_query_dfset = VAL_NONE;
52 static const char *query_buf;
53 static const char *query_lex_buf;
54 static int query_lex_len;
55 static int query_look = 0;
56 static char *left_sep = "{\"";
57 static char *right_sep = "}\"";
58 static int escape_char = '@';
60 static Z_RPNStructure *rpn_structure (ODR o, oid_proto,
61 int num_attr, int max_attr,
62 int *attr_list, oid_value *attr_set);
64 static int query_oid_getvalbyname (void)
68 if (query_lex_len > 31)
70 memcpy (buf, query_lex_buf, query_lex_len);
71 buf[query_lex_len] = '\0';
72 return oid_getvalbyname (buf);
75 static int query_token (const char **qptr, const char **lex_buf, int *lex_len)
77 const char *sep_match;
84 if ((sep_match = strchr (left_sep, **qptr)))
86 int sep_index = sep_match - left_sep;
90 while (**qptr && **qptr != right_sep[sep_index])
101 while (**qptr && **qptr != ' ')
107 if (*lex_len >= 1 && (*lex_buf)[0] == escape_char)
109 if (*lex_len == 4 && !memcmp (*lex_buf+1, "and", 3))
111 if (*lex_len == 3 && !memcmp (*lex_buf+1, "or", 2))
113 if (*lex_len == 4 && !memcmp (*lex_buf+1, "not", 3))
115 if (*lex_len == 5 && !memcmp (*lex_buf+1, "attr", 4))
117 if (*lex_len == 4 && !memcmp (*lex_buf+1, "set", 3))
119 if (*lex_len == 8 && !memcmp (*lex_buf+1, "attrset", 7))
125 static int lex (void)
128 query_token (&query_buf, &query_lex_buf, &query_lex_len);
131 static Z_AttributesPlusTerm *rpn_term (ODR o, oid_proto proto,
132 int num_attr, int *attr_list,
135 Z_AttributesPlusTerm *zapt;
139 zapt = odr_malloc (o, sizeof(*zapt));
140 term_octet = odr_malloc (o, sizeof(*term_octet));
141 term = odr_malloc (o, sizeof(*term));
143 zapt->num_attributes = num_attr;
149 zapt->attributeList = odr_malloc (o, num_attr *
150 sizeof(*zapt->attributeList));
152 attr_tmp = odr_malloc (o, num_attr * 2 * sizeof(int));
153 memcpy (attr_tmp, attr_list, num_attr * 2 * sizeof(int));
154 for (i = 0; i < num_attr; i++)
156 zapt->attributeList[i] =
157 odr_malloc (o,sizeof(**zapt->attributeList));
158 zapt->attributeList[i]->attributeType = &attr_tmp[2*i];
160 if (attr_set[i] == VAL_NONE)
161 zapt->attributeList[i]->attributeSet = 0;
166 attrid.proto = PROTO_Z3950;
167 attrid.oclass = CLASS_ATTSET;
168 attrid.value = attr_set[i];
170 zapt->attributeList[i]->attributeSet =
171 odr_oiddup (o, oid_getoidbyent (&attrid));
173 zapt->attributeList[i]->which = Z_AttributeValue_numeric;
174 zapt->attributeList[i]->value.numeric = &attr_tmp[2*i+1];
176 zapt->attributeList[i]->attributeValue = &attr_tmp[2*i+1];
181 zapt->attributeList = ODR_NULLVAL;
183 term->which = Z_Term_general;
184 term->u.general = term_octet;
185 term_octet->buf = odr_malloc (o, query_lex_len);
186 term_octet->size = term_octet->len = query_lex_len;
187 memcpy (term_octet->buf, query_lex_buf, query_lex_len);
191 static Z_Operand *rpn_simple (ODR o, oid_proto proto,
192 int num_attr, int *attr_list,
197 zo = odr_malloc (o, sizeof(*zo));
201 zo->which = Z_Operand_APT;
202 if (!(zo->u.attributesPlusTerm =
203 rpn_term (o, proto, num_attr, attr_list, attr_set)))
211 zo->which = Z_Operand_resultSetId;
212 zo->u.resultSetId = odr_malloc (o, query_lex_len+1);
213 memcpy (zo->u.resultSetId, query_lex_buf, query_lex_len);
214 zo->u.resultSetId[query_lex_len] = '\0';
223 static Z_Complex *rpn_complex (ODR o, oid_proto proto,
224 int num_attr, int max_attr,
225 int *attr_list, oid_value *attr_set)
230 zc = odr_malloc (o, sizeof(*zc));
231 zo = odr_malloc (o, sizeof(*zo));
236 zo->which = Z_Operator_and;
237 zo->u.and = ODR_NULLVAL;
240 zo->which = Z_Operator_or;
241 zo->u.and = ODR_NULLVAL;
244 zo->which = Z_Operator_and_not;
245 zo->u.and = ODR_NULLVAL;
252 rpn_structure (o, proto, num_attr, max_attr, attr_list, attr_set)))
255 rpn_structure (o, proto, num_attr, max_attr, attr_list, attr_set)))
260 static Z_RPNStructure *rpn_structure (ODR o, oid_proto proto,
261 int num_attr, int max_attr,
262 int *attr_list, oid_value *attr_set)
267 sz = odr_malloc (o, sizeof(*sz));
273 sz->which = Z_RPNStructure_complex;
274 if (!(sz->u.complex =
275 rpn_complex (o, proto, num_attr, max_attr, attr_list, attr_set)))
280 sz->which = Z_RPNStructure_simple;
282 rpn_simple (o, proto, num_attr, attr_list, attr_set)))
289 if (num_attr >= max_attr)
291 if (!(cp = strchr (query_lex_buf, '=')) ||
292 (cp-query_lex_buf) > query_lex_len)
294 attr_set[num_attr] = query_oid_getvalbyname ();
297 if (!(cp = strchr (query_lex_buf, '=')))
303 attr_set[num_attr] = attr_set[num_attr-1];
305 attr_set[num_attr] = VAL_NONE;
307 attr_list[2*num_attr] = atoi (query_lex_buf);
308 attr_list[2*num_attr+1] = atoi (cp+1);
312 rpn_structure (o, proto, num_attr, max_attr, attr_list, attr_set);
313 case 0: /* operator/operand expected! */
319 Z_RPNQuery *p_query_rpn (ODR o, oid_proto proto, const char *qbuf)
322 int attr_array[1024];
323 oid_value attr_set[512];
324 oid_value topSet = VAL_NONE;
328 zq = odr_malloc (o, sizeof(*zq));
330 if (query_look == 'r')
333 topSet = query_oid_getvalbyname ();
334 if (topSet == VAL_NONE)
339 if (topSet == VAL_NONE)
340 topSet = p_query_dfset;
341 if (topSet == VAL_NONE)
344 oset.oclass = CLASS_ATTSET;
347 zq->attributeSetId = odr_oiddup (o, oid_getoidbyent (&oset));
349 if (!(zq->RPNStructure = rpn_structure (o, proto, 0, 512,
350 attr_array, attr_set)))
355 Z_AttributesPlusTerm *p_query_scan (ODR o, oid_proto proto,
356 Odr_oid **attributeSetP,
360 oid_value attr_set[512];
364 oid_value topSet = VAL_NONE;
370 if (query_look == 'r')
373 topSet = query_oid_getvalbyname ();
377 if (topSet == VAL_NONE)
378 topSet = p_query_dfset;
379 if (topSet == VAL_NONE)
382 oset.oclass = CLASS_ATTSET;
385 *attributeSetP = odr_oiddup (o, oid_getoidbyent (&oset));
387 while (query_look == 'l')
392 if (num_attr >= max_attr)
395 if (!(cp = strchr (query_lex_buf, '=')) ||
396 (cp-query_lex_buf) > query_lex_len)
398 attr_set[num_attr] = query_oid_getvalbyname ();
401 if (!(cp = strchr (query_lex_buf, '=')))
407 attr_set[num_attr] = attr_set[num_attr-1];
409 attr_set[num_attr] = VAL_NONE;
411 attr_list[2*num_attr] = atoi (query_lex_buf);
412 attr_list[2*num_attr+1] = atoi (cp+1);
418 return rpn_term (o, proto, num_attr, attr_list, attr_set);
421 int p_query_attset (const char *arg)
423 p_query_dfset = oid_getvalbyname (arg);
424 return (p_query_dfset == VAL_NONE) ? -1 : 0;