2 * Copyright (C) 1995-2004, Index Data
5 * $Id: logrpn.c,v 1.4 2004-11-16 17:08:11 heikki Exp $
10 * \brief Implements Z39.50 Query Printing
17 #include <yaz/logrpn.h>
19 static const char *relToStr(int v)
24 case 1: str = "Less than"; break;
25 case 2: str = "Less than or equal"; break;
26 case 3: str = "Equal"; break;
27 case 4: str = "Greater or equal"; break;
28 case 5: str = "Greater than"; break;
29 case 6: str = "Not equal"; break;
30 case 100: str = "Phonetic"; break;
31 case 101: str = "Stem"; break;
32 case 102: str = "Relevance"; break;
33 case 103: str = "AlwaysMatches"; break;
37 static void attrStr (int type, int value, enum oid_value ast, char *str)
52 rstr = relToStr(value);
54 sprintf (str, "relation=%s", rstr);
56 sprintf (str, "relation=%d", value);
62 sprintf (str, "position=First in field");
65 sprintf (str, "position=First in any subfield");
68 sprintf (str, "position=Any position in field");
71 sprintf (str, "position");
78 sprintf (str, "structure=Phrase");
81 sprintf (str, "structure=Word");
84 sprintf (str, "structure=Key");
87 sprintf (str, "structure=Year");
90 sprintf (str, "structure=Date");
93 sprintf (str, "structure=Word list");
96 sprintf (str, "structure=Date (un)");
99 sprintf (str, "structure=Name (norm)");
102 sprintf (str, "structure=Name (un)");
105 sprintf (str, "structure=Structure");
108 sprintf (str, "structure=urx");
111 sprintf (str, "structure=free-form-text");
114 sprintf (str, "structure=document-text");
117 sprintf (str, "structure=local-number");
120 sprintf (str, "structure=string");
123 sprintf (str, "structure=numeric string");
126 sprintf (str, "structure");
133 sprintf (str, "truncation=Right");
136 sprintf (str, "truncation=Left");
139 sprintf (str, "truncation=Left&right");
142 sprintf (str, "truncation=Do not truncate");
145 sprintf (str, "truncation=Process #");
148 sprintf (str, "truncation=re-1");
151 sprintf (str, "truncation=re-2");
154 sprintf (str, "truncation=CCL");
157 sprintf (str, "truncation");
164 sprintf (str, "completeness=Incomplete subfield");
167 sprintf (str, "completeness=Complete subfield");
170 sprintf (str, "completeness=Complete field");
173 sprintf (str, "completeness");
182 sprintf (str + strlen(str), " (%d=%d)", type, value);
184 sprintf (str, "%d=%d", type, value);
187 static void wrbuf_attr(WRBUF b, Z_AttributeElement *element)
191 char *sep=""; /* optional space after attrset name */
192 if (element->attributeSet)
195 attrset = oid_getentbyoid (element->attributeSet);
196 setname=attrset->desc;
199 switch (element->which)
201 case Z_AttributeValue_numeric:
202 wrbuf_printf(b,"@attr %s%s%d=%d ", setname,sep,
203 *element->attributeType, *element->value.numeric);
205 case Z_AttributeValue_complex:
206 wrbuf_printf(b,"@attr %s%s%d=", setname,sep,*element->attributeType);
207 for (i = 0; i<element->value.complex->num_list; i++)
211 if (element->value.complex->list[i]->which ==
212 Z_StringOrNumeric_string)
213 wrbuf_printf (b, "'%s'",
214 element->value.complex->list[i]->u.string);
215 else if (element->value.complex->list[i]->which ==
216 Z_StringOrNumeric_numeric)
217 wrbuf_printf (b, "%d",
218 *element->value.complex->list[i]->u.numeric);
223 wrbuf_printf (b, "(unknown attr type) ");
229 * zlog_attributes: print attributes of term
231 static void zlog_attributes (Z_AttributesPlusTerm *t, int depth,
232 enum oid_value ast, int loglevel)
236 int num_attributes = t->attributes->num_attributes;
238 for (of = 0; of < num_attributes; of++)
240 const char *attset_name = "";
241 Z_AttributeElement *element;
242 element = t->attributes->attributes[of];
243 if (element->attributeSet)
246 attrset = oid_getentbyoid (element->attributeSet);
247 attset_name = attrset->desc;
249 switch (element->which)
251 case Z_AttributeValue_numeric:
252 attrStr (*element->attributeType,
253 *element->value.numeric, ast, str);
254 yaz_log (loglevel, "%*.0s%s %s", depth, "", attset_name, str);
256 case Z_AttributeValue_complex:
257 yaz_log (loglevel, "%*.0s%s attributeType=%d complex",
258 depth, "", attset_name, *element->attributeType);
259 for (i = 0; i<element->value.complex->num_list; i++)
261 if (element->value.complex->list[i]->which ==
262 Z_StringOrNumeric_string)
263 yaz_log (loglevel, "%*.0s string: '%s'", depth, "",
264 element->value.complex->list[i]->u.string);
265 else if (element->value.complex->list[i]->which ==
266 Z_StringOrNumeric_numeric)
267 yaz_log (loglevel, "%*.0s numeric: '%d'", depth, "",
268 *element->value.complex->list[i]->u.numeric);
272 yaz_log (loglevel, "%.*s%s attribute unknown",
273 depth, "", attset_name);
278 static char *complex_op_name(Z_Operator *op)
286 case Z_Operator_and_not:
288 case Z_Operator_prox:
291 return "unknown complex operator";
295 static char *prox_unit_name(Z_ProximityOperator *op)
297 if (op->which!=Z_ProximityOperator_known)
301 case Z_ProxUnit_character: return "character";
302 case Z_ProxUnit_word: return "word";
303 case Z_ProxUnit_sentence: return "sentence";
304 case Z_ProxUnit_paragraph: return "paragraph";
305 case Z_ProxUnit_section: return "section";
306 case Z_ProxUnit_chapter: return "chapter";
307 case Z_ProxUnit_document: return "document";
308 case Z_ProxUnit_element: return "element";
309 case Z_ProxUnit_subelement: return "subelement";
310 case Z_ProxUnit_elementType: return "elementType";
311 case Z_ProxUnit_byte: return "byte";
312 default: return "unknown";
316 static void zlog_structure (Z_RPNStructure *zs, int depth,
317 enum oid_value ast, int loglevel)
319 if (zs->which == Z_RPNStructure_complex)
321 Z_Operator *op = zs->u.complex->roperator;
326 case Z_Operator_and_not:
327 yaz_log (loglevel, "%*.0s %s", depth, "", complex_op_name(op) );
329 case Z_Operator_prox:
330 yaz_log (loglevel, "%*.0s prox excl=%s dist=%d order=%s "
332 depth, "", op->u.prox->exclusion ?
333 (*op->u.prox->exclusion ? "T" : "F") : "N",
334 *op->u.prox->distance,
335 *op->u.prox->ordered ? "T" : "F",
336 relToStr(*op->u.prox->relationType),
337 prox_unit_name(op->u.prox) );
340 yaz_log (loglevel, "%*.0s unknown complex", depth, "");
343 zlog_structure (zs->u.complex->s1, depth+2, ast, loglevel);
344 zlog_structure (zs->u.complex->s2, depth+2, ast, loglevel);
346 else if (zs->which == Z_RPNStructure_simple)
348 if (zs->u.simple->which == Z_Operand_APT)
350 Z_AttributesPlusTerm *zapt = zs->u.simple->u.attributesPlusTerm;
352 switch (zapt->term->which)
355 yaz_log (loglevel, "%*.0s term '%.*s' (general)", depth, "",
356 zapt->term->u.general->len,
357 zapt->term->u.general->buf);
359 case Z_Term_characterString:
360 yaz_log (loglevel, "%*.0s term '%s' (string)", depth, "",
361 zapt->term->u.characterString);
364 yaz_log (loglevel, "%*.0s term '%d' (numeric)", depth, "",
365 *zapt->term->u.numeric);
368 yaz_log (loglevel, "%*.0s term (null)", depth, "");
371 yaz_log (loglevel, "%*.0s term (not general)", depth, "");
373 zlog_attributes (zapt, depth+2, ast, loglevel);
375 else if (zs->u.simple->which == Z_Operand_resultSetId)
377 yaz_log (loglevel, "%*.0s set '%s'", depth, "",
378 zs->u.simple->u.resultSetId);
381 yaz_log (loglevel, "%*.0s unknown simple structure", depth, "");
384 yaz_log (loglevel, "%*.0s unknown structure", depth, "");
387 static void wrbuf_structure (WRBUF b, Z_RPNStructure *zs, enum oid_value ast)
390 if (zs->which == Z_RPNStructure_complex)
392 Z_Operator *op = zs->u.complex->roperator;
393 wrbuf_printf(b, "@%s ", complex_op_name(op) );
394 if (op->which== Z_Operator_prox)
396 wrbuf_printf(b, "(excl=%s dist=%d order=%s "
398 op->u.prox->exclusion ?
399 (*op->u.prox->exclusion ? "T" : "F") : "N",
400 *op->u.prox->distance,
401 *op->u.prox->ordered ? "T" : "F",
402 relToStr(*op->u.prox->relationType),
403 prox_unit_name(op->u.prox) );
405 wrbuf_structure (b,zs->u.complex->s1, ast);
406 wrbuf_structure (b,zs->u.complex->s2, ast);
408 else if (zs->which == Z_RPNStructure_simple)
410 if (zs->u.simple->which == Z_Operand_APT)
412 Z_AttributesPlusTerm *zapt = zs->u.simple->u.attributesPlusTerm;
413 int num_attributes = zapt->attributes->num_attributes;
414 for (i=0;i<num_attributes;i++)
415 wrbuf_attr(b,zapt->attributes->attributes[i]);
417 switch (zapt->term->which)
420 wrbuf_printf(b, "'%.*s' ",
421 zapt->term->u.general->len,
422 zapt->term->u.general->buf);
424 case Z_Term_characterString:
425 wrbuf_printf(b, "\"%s\" ", zapt->term->u.characterString);
428 wrbuf_printf(b, "%d ", *zapt->term->u.numeric);
431 wrbuf_printf(b, "(null) ");
434 wrbuf_printf(b, "(unknown term type %d) ", zapt->term->which);
437 else if (zs->u.simple->which == Z_Operand_resultSetId)
439 wrbuf_printf(b, "@set '%s' ", zs->u.simple->u.resultSetId);
442 wrbuf_printf (b, "(unknown simple structure)");
445 wrbuf_puts(b, "(unknown structure)");
448 void log_rpn_query_level (int loglevel, Z_RPNQuery *rpn)
453 attrset = oid_getentbyoid (rpn->attributeSetId);
456 ast = attrset->value;
457 yaz_log (loglevel, "RPN query. Type: %s", attrset->desc);
462 yaz_log (loglevel, "RPN query. Unknown type");
464 zlog_structure (rpn->RPNStructure, 0, ast, loglevel);
467 static void wrbuf_rpn_query(WRBUF b, Z_RPNQuery *rpn)
472 attrset = oid_getentbyoid (rpn->attributeSetId);
475 ast = attrset->value;
476 wrbuf_printf(b, " @attrset %s ", attrset->desc);
481 wrbuf_printf (b, "Unknown:");
483 wrbuf_structure (b,rpn->RPNStructure, ast);
487 void log_rpn_query (Z_RPNQuery *rpn)
489 log_rpn_query_level(LOG_LOG, rpn);
492 void log_scan_term_level (int loglevel,
493 Z_AttributesPlusTerm *zapt, oid_value ast)
498 if (zapt->term->which == Z_Term_general)
500 yaz_log (loglevel, "%*.0s term '%.*s' (general)", depth, "",
501 zapt->term->u.general->len, zapt->term->u.general->buf);
504 yaz_log (loglevel, "%*.0s term (not general)", depth, "");
505 zlog_attributes (zapt, depth+2, ast, loglevel);
508 void log_scan_term (Z_AttributesPlusTerm *zapt, oid_value ast)
510 log_scan_term_level (LOG_LOG, zapt, ast);
513 void wrbuf_scan_term(WRBUF b, Z_AttributesPlusTerm *zapt, oid_value ast)
515 int num_attributes = zapt->attributes->num_attributes;
517 for (i=0;i<num_attributes;i++)
518 wrbuf_attr(b,zapt->attributes->attributes[i]);
519 if (zapt->term->which == Z_Term_general)
521 wrbuf_printf (b, "'%.*s' ",
522 zapt->term->u.general->len,
523 zapt->term->u.general->buf);
526 wrbuf_printf (b, "(not a general term)");
529 void yaz_log_zquery_level (int loglevel, Z_Query *q)
535 case Z_Query_type_1: case Z_Query_type_101:
536 log_rpn_query_level (loglevel, q->u.type_1);
539 yaz_log(loglevel, "CCL: %.*s", q->u.type_2->len, q->u.type_2->buf);
541 case Z_Query_type_100:
542 yaz_log(loglevel, "Z39.58: %.*s", q->u.type_100->len,
545 case Z_Query_type_104:
546 if (q->u.type_104->which == Z_External_CQL)
547 yaz_log (loglevel, "CQL: %s", q->u.type_104->u.cql);
551 void yaz_log_zquery (Z_Query *q)
553 yaz_log_zquery_level(LOG_LOG,q);
556 void wrbuf_put_zquery(WRBUF b, Z_Query *q)
563 case Z_Query_type_101:
564 wrbuf_printf(b,"Z:");
565 wrbuf_rpn_query(b,q->u.type_1);
568 wrbuf_printf(b, "CCL: %.*s", q->u.type_2->len, q->u.type_2->buf);
570 case Z_Query_type_100:
571 wrbuf_printf(b, "Z39.58: %.*s", q->u.type_100->len,
574 case Z_Query_type_104:
575 if (q->u.type_104->which == Z_External_CQL)
576 wrbuf_printf(b, "CQL: %s", q->u.type_104->u.cql);
578 wrbuf_printf(b,"Unknown type 104 query %d", q->u.type_104->which);
582 void wrbuf_diags(WRBUF b, int num_diagnostics,Z_DiagRec **diags)
584 /* we only dump the first diag - that keeps the log cleaner. */
585 wrbuf_printf(b," ERROR ");
586 if (diags[0]->which != Z_DiagRec_defaultFormat)
587 wrbuf_printf(b,"(diag not in default format?)");
590 Z_DefaultDiagFormat *e=diags[0]->u.defaultFormat;
592 wrbuf_printf(b, "%d ",*e->condition);
594 wrbuf_printf(b, "?? ");
595 if ((e->which==Z_DefaultDiagFormat_v2Addinfo) && (e->u.v2Addinfo))
596 wrbuf_printf(b,"%s ",e->u.v2Addinfo);
597 else if ((e->which==Z_DefaultDiagFormat_v3Addinfo) && (e->u.v3Addinfo))
598 wrbuf_printf(b,"%s ",e->u.v3Addinfo);