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