Remove the extensive logging
[yaz-moved-to-github.git] / src / logrpn.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2010 Index Data
3  * See the file LICENSE for details.
4  */
5
6 /**
7  * \file logrpn.c
8  * \brief Implements Z39.50 Query Printing
9  */
10
11 #include <stdio.h>
12 #include <assert.h>
13
14 #include <yaz/log.h>
15 #include <yaz/logrpn.h>
16 #include <yaz/oid_db.h>
17
18 static const char *relToStr(Odr_int v)
19 {
20     const char *str = 0;
21     switch (v)
22     {
23     case 1: str = "Less than"; break;
24     case 2: str = "Less than or equal"; break;
25     case 3: str = "Equal"; break;
26     case 4: str = "Greater or equal"; break;
27     case 5: str = "Greater than"; break;
28     case 6: str = "Not equal"; break;
29     case 100: str = "Phonetic"; break;
30     case 101: str = "Stem"; break;
31     case 102: str = "Relevance"; break;
32     case 103: str = "AlwaysMatches"; break;
33     }
34     return str;
35 }
36
37 static void attrStr(Odr_int type, Odr_int value, char *str)
38 {
39     const char *rstr;
40     *str = '\0';
41     switch (type)
42     {
43     case 1:
44         sprintf(str, "use");
45         break;
46     case 2:
47         rstr = relToStr(value);
48         if (rstr)
49             sprintf(str, "relation=%s", rstr);
50         else
51             sprintf(str, "relation=" ODR_INT_PRINTF, value);
52         break;
53     case 3:
54         switch (value)
55         {
56         case 1:
57             sprintf(str, "position=First in field");
58             break;
59         case 2:
60             sprintf(str, "position=First in any subfield");
61             break;
62         case 3:
63             sprintf(str, "position=Any position in field");
64             break;
65         default:
66             sprintf(str, "position");
67         }
68         break;
69     case 4:
70         switch (value)
71         {
72         case 1:
73             sprintf(str, "structure=Phrase");
74             break;
75         case 2:
76             sprintf(str, "structure=Word");
77             break;
78         case 3:
79             sprintf(str, "structure=Key");
80             break;
81         case 4:
82             sprintf(str, "structure=Year");
83             break;
84         case 5:
85             sprintf(str, "structure=Date");
86             break;
87         case 6:
88             sprintf(str, "structure=Word list");
89             break;
90         case 100:
91             sprintf(str, "structure=Date (un)");
92             break;
93         case 101:
94             sprintf(str, "structure=Name (norm)");
95             break;
96         case 102:
97             sprintf(str, "structure=Name (un)");
98             break;
99         case 103:
100             sprintf(str, "structure=Structure");
101             break;
102         case 104:
103             sprintf(str, "structure=urx");
104             break;
105         case 105:
106             sprintf(str, "structure=free-form-text");
107             break;
108         case 106:
109             sprintf(str, "structure=document-text");
110             break;
111         case 107:
112             sprintf(str, "structure=local-number");
113             break;
114         case 108:
115             sprintf(str, "structure=string");
116             break;
117         case 109:
118             sprintf(str, "structure=numeric string");
119             break;
120         default:
121             sprintf(str, "structure");
122         }
123         break;
124     case 5:
125         switch (value)
126         {
127         case 1:
128             sprintf(str, "truncation=Right");
129             break;
130         case 2:
131             sprintf(str, "truncation=Left");
132             break;
133         case 3:
134             sprintf(str, "truncation=Left&right");
135             break;
136         case 100:
137             sprintf(str, "truncation=Do not truncate");
138             break;
139         case 101:
140             sprintf(str, "truncation=Process #");
141             break;
142         case 102:
143             sprintf(str, "truncation=re-1");
144             break;
145         case 103:
146             sprintf(str, "truncation=re-2");
147             break;
148         case 104:
149             sprintf(str, "truncation=CCL");
150             break;
151         default:
152             sprintf(str, "truncation");
153         }
154         break;
155     case 6:
156         switch(value)
157         {
158         case 1:
159             sprintf(str, "completeness=Incomplete subfield");
160             break;
161         case 2:
162             sprintf(str, "completeness=Complete subfield");
163             break;
164         case 3:
165             sprintf(str, "completeness=Complete field");
166             break;
167         default:
168             sprintf(str, "completeness");
169         }
170         break;
171     }
172     if (*str)
173         sprintf(str + strlen(str), " (" ODR_INT_PRINTF "=" ODR_INT_PRINTF")",
174                 type, value);
175     else
176         sprintf(str, ODR_INT_PRINTF "=" ODR_INT_PRINTF, type, value);
177 }
178
179 /*
180  * zlog_attributes: print attributes of term
181  */
182 static void zlog_attributes(Z_AttributesPlusTerm *t, int depth,
183                             const Odr_oid *ast, int loglevel)
184 {
185     int of, i;
186     char str[80];
187     int num_attributes = t->attributes->num_attributes;
188     
189     for (of = 0; of < num_attributes; of++)
190     {
191         char attset_name_buf[OID_STR_MAX];
192         const char *attset_name = 0;
193         Z_AttributeElement *element;
194         element = t->attributes->attributes[of];
195         if (element->attributeSet)
196         {
197             attset_name = yaz_oid_to_string_buf(element->attributeSet,
198                                                 0, attset_name_buf);
199         }
200         if (!attset_name)
201             attset_name = "";
202         switch (element->which) 
203         {
204         case Z_AttributeValue_numeric:
205             attrStr(*element->attributeType,
206                      *element->value.numeric, str);
207             yaz_log(loglevel, "%*.0s%s %s", depth, "", attset_name, str);
208             break;
209         case Z_AttributeValue_complex:
210             yaz_log(loglevel, "%*.0s%s attributeType=" ODR_INT_PRINTF
211                      " complex",
212                   depth, "", attset_name, *element->attributeType);
213             for (i = 0; i<element->value.complex->num_list; i++)
214             {
215                 if (element->value.complex->list[i]->which ==
216                     Z_StringOrNumeric_string)
217                     yaz_log(loglevel, "%*.0s  string: '%s'", depth, "",
218                              element->value.complex->list[i]->u.string);
219                 else if (element->value.complex->list[i]->which ==
220                          Z_StringOrNumeric_numeric)
221                     yaz_log(loglevel, "%*.0s  numeric: '" ODR_INT_PRINTF
222                              " '", depth, "",
223                              *element->value.complex->list[i]->u.numeric);
224             }
225             break;
226         default:
227             yaz_log(loglevel, "%.*s%s attribute unknown",
228                      depth, "", attset_name);
229         }
230     }
231 }
232
233 static char *complex_op_name(Z_Operator *op)
234 {
235     switch (op->which)
236     {
237     case Z_Operator_and:
238         return "and";
239     case Z_Operator_or:
240         return "or";
241     case Z_Operator_and_not:
242         return "not";
243     case Z_Operator_prox:
244         return "prox";
245     default:
246         return "unknown complex operator";
247     }
248 }
249
250 static char *prox_unit_name(Z_ProximityOperator *op)
251 {
252     if (op->which!=Z_ProximityOperator_known)
253          return "private";
254     switch(*op->u.known)
255     {
256         case Z_ProxUnit_character: return "character";
257         case Z_ProxUnit_word: return "word";
258         case Z_ProxUnit_sentence: return "sentence";
259         case Z_ProxUnit_paragraph: return "paragraph";
260         case Z_ProxUnit_section: return "section";
261         case Z_ProxUnit_chapter: return "chapter";
262         case Z_ProxUnit_document: return "document";
263         case Z_ProxUnit_element: return "element";
264         case Z_ProxUnit_subelement: return "subelement";
265         case Z_ProxUnit_elementType: return "elementType";
266         case Z_ProxUnit_byte: return "byte";
267         default: return "unknown";
268     }
269 }
270
271 static void zlog_structure(Z_RPNStructure *zs, int depth, 
272                            const Odr_oid *ast, int loglevel)
273 {
274     if (zs->which == Z_RPNStructure_complex)
275     {
276         Z_Operator *op = zs->u.complex->roperator;
277         switch (op->which)
278         {
279         case Z_Operator_and:
280         case Z_Operator_or:
281         case Z_Operator_and_not:
282             yaz_log(loglevel, "%*.0s %s", depth, "", complex_op_name(op) );
283             break;
284         case Z_Operator_prox:
285             yaz_log(loglevel, "%*.0s prox excl=%s dist=" ODR_INT_PRINTF
286                      " order=%s "
287                      "rel=%s unit=%s",
288                      depth, "", op->u.prox->exclusion ?
289                      (*op->u.prox->exclusion ? "T" : "F") : "N", 
290                      *op->u.prox->distance,
291                      *op->u.prox->ordered ? "T" : "F",
292                      relToStr(*op->u.prox->relationType),
293                      prox_unit_name(op->u.prox) );
294             break;
295         default:
296             yaz_log(loglevel, "%*.0s unknown complex", depth, "");
297             return;
298         }
299         zlog_structure(zs->u.complex->s1, depth+2, ast, loglevel);
300         zlog_structure(zs->u.complex->s2, depth+2, ast, loglevel);
301     } 
302     else if (zs->which == Z_RPNStructure_simple)
303     {
304         if (zs->u.simple->which == Z_Operand_APT)
305         {
306             Z_AttributesPlusTerm *zapt = zs->u.simple->u.attributesPlusTerm;
307
308             switch (zapt->term->which)
309             {
310             case Z_Term_general:
311                 yaz_log(loglevel, "%*.0s term '%.*s' (general)", depth, "",
312                          zapt->term->u.general->len,
313                          zapt->term->u.general->buf);
314                 break;
315             case Z_Term_characterString:
316                 yaz_log(loglevel, "%*.0s term '%s' (string)", depth, "",
317                          zapt->term->u.characterString);
318                 break;
319             case Z_Term_numeric:
320                 yaz_log(loglevel, "%*.0s term '" ODR_INT_PRINTF
321                          "' (numeric)", depth, "",
322                          *zapt->term->u.numeric);
323                 break;
324             case Z_Term_null:
325                 yaz_log(loglevel, "%*.0s term (null)", depth, "");
326                 break;
327             default:
328                 yaz_log(loglevel, "%*.0s term (not general)", depth, "");
329             }
330             zlog_attributes(zapt, depth+2, ast, loglevel);
331         }
332         else if (zs->u.simple->which == Z_Operand_resultSetId)
333         {
334             yaz_log(loglevel, "%*.0s set '%s'", depth, "",
335                      zs->u.simple->u.resultSetId);
336         }
337         else
338             yaz_log(loglevel, "%*.0s unknown simple structure", depth, "");
339     }
340     else
341         yaz_log(loglevel, "%*.0s unknown structure", depth, "");
342 }
343
344 void log_rpn_query_level(int loglevel, Z_RPNQuery *rpn)
345 {
346     zlog_structure(rpn->RPNStructure, 0, rpn->attributeSetId, loglevel);
347 }
348
349 void log_rpn_query(Z_RPNQuery *rpn)
350 {
351     log_rpn_query_level(YLOG_LOG, rpn);
352 }
353
354 void log_scan_term_level(int loglevel, 
355                          Z_AttributesPlusTerm *zapt, const Odr_oid *ast)
356 {
357     int depth = 0;
358     if (!loglevel)
359         return;
360     if (zapt->term->which == Z_Term_general) 
361     {
362         yaz_log(loglevel, "%*.0s term '%.*s' (general)", depth, "",
363                  zapt->term->u.general->len, zapt->term->u.general->buf);
364     }
365     else
366         yaz_log(loglevel, "%*.0s term (not general)", depth, "");
367     zlog_attributes(zapt, depth+2, ast, loglevel);
368 }
369
370 void log_scan_term(Z_AttributesPlusTerm *zapt, const Odr_oid *ast)
371 {
372     log_scan_term_level(YLOG_LOG, zapt, ast);
373 }
374
375 void yaz_log_zquery_level(int loglevel, Z_Query *q)
376 {
377     if (!loglevel)
378         return; 
379     switch (q->which)
380     {
381     case Z_Query_type_1: case Z_Query_type_101:
382         log_rpn_query_level(loglevel, q->u.type_1);
383         break;
384     case Z_Query_type_2:
385         yaz_log(loglevel, "CCL: %.*s", q->u.type_2->len, q->u.type_2->buf);
386         break;
387     case Z_Query_type_100:
388         yaz_log(loglevel, "Z39.58: %.*s", q->u.type_100->len,
389                 q->u.type_100->buf);
390         break;
391     case Z_Query_type_104:
392         if (q->u.type_104->which == Z_External_CQL)
393             yaz_log(loglevel, "CQL: %s", q->u.type_104->u.cql);
394     }
395 }
396
397 void yaz_log_zquery(Z_Query *q)
398 {
399     yaz_log_zquery_level(YLOG_LOG, q);
400 }
401
402 /*
403  * Local variables:
404  * c-basic-offset: 4
405  * c-file-style: "Stroustrup"
406  * indent-tabs-mode: nil
407  * End:
408  * vim: shiftwidth=4 tabstop=8 expandtab
409  */
410