00001
00002
00003
00004
00005
00011 #include <stdio.h>
00012 #include <assert.h>
00013
00014 #include <yaz/log.h>
00015 #include <yaz/logrpn.h>
00016 #include <yaz/oid_db.h>
00017
00018 static const char *relToStr(int v)
00019 {
00020 const char *str = 0;
00021 switch (v)
00022 {
00023 case 1: str = "Less than"; break;
00024 case 2: str = "Less than or equal"; break;
00025 case 3: str = "Equal"; break;
00026 case 4: str = "Greater or equal"; break;
00027 case 5: str = "Greater than"; break;
00028 case 6: str = "Not equal"; break;
00029 case 100: str = "Phonetic"; break;
00030 case 101: str = "Stem"; break;
00031 case 102: str = "Relevance"; break;
00032 case 103: str = "AlwaysMatches"; break;
00033 }
00034 return str;
00035 }
00036
00037 static void attrStr (int type, int value, char *str)
00038 {
00039 const char *rstr;
00040 *str = '\0';
00041 switch (type)
00042 {
00043 case 1:
00044 sprintf (str, "use");
00045 break;
00046 case 2:
00047 rstr = relToStr(value);
00048 if (rstr)
00049 sprintf(str, "relation=%s", rstr);
00050 else
00051 sprintf(str, "relation=%d", value);
00052 break;
00053 case 3:
00054 switch (value)
00055 {
00056 case 1:
00057 sprintf(str, "position=First in field");
00058 break;
00059 case 2:
00060 sprintf(str, "position=First in any subfield");
00061 break;
00062 case 3:
00063 sprintf(str, "position=Any position in field");
00064 break;
00065 default:
00066 sprintf(str, "position");
00067 }
00068 break;
00069 case 4:
00070 switch (value)
00071 {
00072 case 1:
00073 sprintf(str, "structure=Phrase");
00074 break;
00075 case 2:
00076 sprintf(str, "structure=Word");
00077 break;
00078 case 3:
00079 sprintf(str, "structure=Key");
00080 break;
00081 case 4:
00082 sprintf(str, "structure=Year");
00083 break;
00084 case 5:
00085 sprintf(str, "structure=Date");
00086 break;
00087 case 6:
00088 sprintf(str, "structure=Word list");
00089 break;
00090 case 100:
00091 sprintf(str, "structure=Date (un)");
00092 break;
00093 case 101:
00094 sprintf(str, "structure=Name (norm)");
00095 break;
00096 case 102:
00097 sprintf(str, "structure=Name (un)");
00098 break;
00099 case 103:
00100 sprintf(str, "structure=Structure");
00101 break;
00102 case 104:
00103 sprintf(str, "structure=urx");
00104 break;
00105 case 105:
00106 sprintf(str, "structure=free-form-text");
00107 break;
00108 case 106:
00109 sprintf(str, "structure=document-text");
00110 break;
00111 case 107:
00112 sprintf(str, "structure=local-number");
00113 break;
00114 case 108:
00115 sprintf(str, "structure=string");
00116 break;
00117 case 109:
00118 sprintf(str, "structure=numeric string");
00119 break;
00120 default:
00121 sprintf(str, "structure");
00122 }
00123 break;
00124 case 5:
00125 switch (value)
00126 {
00127 case 1:
00128 sprintf(str, "truncation=Right");
00129 break;
00130 case 2:
00131 sprintf(str, "truncation=Left");
00132 break;
00133 case 3:
00134 sprintf(str, "truncation=Left&right");
00135 break;
00136 case 100:
00137 sprintf(str, "truncation=Do not truncate");
00138 break;
00139 case 101:
00140 sprintf(str, "truncation=Process #");
00141 break;
00142 case 102:
00143 sprintf(str, "truncation=re-1");
00144 break;
00145 case 103:
00146 sprintf(str, "truncation=re-2");
00147 break;
00148 case 104:
00149 sprintf(str, "truncation=CCL");
00150 break;
00151 default:
00152 sprintf(str, "truncation");
00153 }
00154 break;
00155 case 6:
00156 switch(value)
00157 {
00158 case 1:
00159 sprintf(str, "completeness=Incomplete subfield");
00160 break;
00161 case 2:
00162 sprintf(str, "completeness=Complete subfield");
00163 break;
00164 case 3:
00165 sprintf(str, "completeness=Complete field");
00166 break;
00167 default:
00168 sprintf(str, "completeness");
00169 }
00170 break;
00171 }
00172 if (*str)
00173 sprintf(str + strlen(str), " (%d=%d)", type, value);
00174 else
00175 sprintf(str, "%d=%d", type, value);
00176 }
00177
00178
00179
00180
00181 static void zlog_attributes(Z_AttributesPlusTerm *t, int depth,
00182 const Odr_oid *ast, int loglevel)
00183 {
00184 int of, i;
00185 char str[80];
00186 int num_attributes = t->attributes->num_attributes;
00187
00188 for (of = 0; of < num_attributes; of++)
00189 {
00190 char attset_name_buf[OID_STR_MAX];
00191 const char *attset_name = 0;
00192 Z_AttributeElement *element;
00193 element = t->attributes->attributes[of];
00194 if (element->attributeSet)
00195 {
00196 attset_name = yaz_oid_to_string_buf(element->attributeSet,
00197 0, attset_name_buf);
00198 }
00199 if (!attset_name)
00200 attset_name = "";
00201 switch (element->which)
00202 {
00203 case Z_AttributeValue_numeric:
00204 attrStr (*element->attributeType,
00205 *element->value.numeric, str);
00206 yaz_log (loglevel, "%*.0s%s %s", depth, "", attset_name, str);
00207 break;
00208 case Z_AttributeValue_complex:
00209 yaz_log (loglevel, "%*.0s%s attributeType=%d complex",
00210 depth, "", attset_name, *element->attributeType);
00211 for (i = 0; i<element->value.complex->num_list; i++)
00212 {
00213 if (element->value.complex->list[i]->which ==
00214 Z_StringOrNumeric_string)
00215 yaz_log (loglevel, "%*.0s string: '%s'", depth, "",
00216 element->value.complex->list[i]->u.string);
00217 else if (element->value.complex->list[i]->which ==
00218 Z_StringOrNumeric_numeric)
00219 yaz_log (loglevel, "%*.0s numeric: '%d'", depth, "",
00220 *element->value.complex->list[i]->u.numeric);
00221 }
00222 break;
00223 default:
00224 yaz_log (loglevel, "%.*s%s attribute unknown",
00225 depth, "", attset_name);
00226 }
00227 }
00228 }
00229
00230 static char *complex_op_name(Z_Operator *op)
00231 {
00232 switch (op->which)
00233 {
00234 case Z_Operator_and:
00235 return "and";
00236 case Z_Operator_or:
00237 return "or";
00238 case Z_Operator_and_not:
00239 return "not";
00240 case Z_Operator_prox:
00241 return "prox";
00242 default:
00243 return "unknown complex operator";
00244 }
00245 }
00246
00247 static char *prox_unit_name(Z_ProximityOperator *op)
00248 {
00249 if (op->which!=Z_ProximityOperator_known)
00250 return "private";
00251 switch(*op->u.known)
00252 {
00253 case Z_ProxUnit_character: return "character";
00254 case Z_ProxUnit_word: return "word";
00255 case Z_ProxUnit_sentence: return "sentence";
00256 case Z_ProxUnit_paragraph: return "paragraph";
00257 case Z_ProxUnit_section: return "section";
00258 case Z_ProxUnit_chapter: return "chapter";
00259 case Z_ProxUnit_document: return "document";
00260 case Z_ProxUnit_element: return "element";
00261 case Z_ProxUnit_subelement: return "subelement";
00262 case Z_ProxUnit_elementType: return "elementType";
00263 case Z_ProxUnit_byte: return "byte";
00264 default: return "unknown";
00265 }
00266 }
00267
00268 static void zlog_structure(Z_RPNStructure *zs, int depth,
00269 const Odr_oid *ast, int loglevel)
00270 {
00271 if (zs->which == Z_RPNStructure_complex)
00272 {
00273 Z_Operator *op = zs->u.complex->roperator;
00274 switch (op->which)
00275 {
00276 case Z_Operator_and:
00277 case Z_Operator_or:
00278 case Z_Operator_and_not:
00279 yaz_log (loglevel, "%*.0s %s", depth, "", complex_op_name(op) );
00280 break;
00281 case Z_Operator_prox:
00282 yaz_log (loglevel, "%*.0s prox excl=%s dist=%d order=%s "
00283 "rel=%s unit=%s",
00284 depth, "", op->u.prox->exclusion ?
00285 (*op->u.prox->exclusion ? "T" : "F") : "N",
00286 *op->u.prox->distance,
00287 *op->u.prox->ordered ? "T" : "F",
00288 relToStr(*op->u.prox->relationType),
00289 prox_unit_name(op->u.prox) );
00290 break;
00291 default:
00292 yaz_log (loglevel, "%*.0s unknown complex", depth, "");
00293 return;
00294 }
00295 zlog_structure (zs->u.complex->s1, depth+2, ast, loglevel);
00296 zlog_structure (zs->u.complex->s2, depth+2, ast, loglevel);
00297 }
00298 else if (zs->which == Z_RPNStructure_simple)
00299 {
00300 if (zs->u.simple->which == Z_Operand_APT)
00301 {
00302 Z_AttributesPlusTerm *zapt = zs->u.simple->u.attributesPlusTerm;
00303
00304 switch (zapt->term->which)
00305 {
00306 case Z_Term_general:
00307 yaz_log (loglevel, "%*.0s term '%.*s' (general)", depth, "",
00308 zapt->term->u.general->len,
00309 zapt->term->u.general->buf);
00310 break;
00311 case Z_Term_characterString:
00312 yaz_log (loglevel, "%*.0s term '%s' (string)", depth, "",
00313 zapt->term->u.characterString);
00314 break;
00315 case Z_Term_numeric:
00316 yaz_log (loglevel, "%*.0s term '%d' (numeric)", depth, "",
00317 *zapt->term->u.numeric);
00318 break;
00319 case Z_Term_null:
00320 yaz_log (loglevel, "%*.0s term (null)", depth, "");
00321 break;
00322 default:
00323 yaz_log (loglevel, "%*.0s term (not general)", depth, "");
00324 }
00325 zlog_attributes(zapt, depth+2, ast, loglevel);
00326 }
00327 else if (zs->u.simple->which == Z_Operand_resultSetId)
00328 {
00329 yaz_log (loglevel, "%*.0s set '%s'", depth, "",
00330 zs->u.simple->u.resultSetId);
00331 }
00332 else
00333 yaz_log (loglevel, "%*.0s unknown simple structure", depth, "");
00334 }
00335 else
00336 yaz_log (loglevel, "%*.0s unknown structure", depth, "");
00337 }
00338
00339 void log_rpn_query_level (int loglevel, Z_RPNQuery *rpn)
00340 {
00341 zlog_structure(rpn->RPNStructure, 0, rpn->attributeSetId, loglevel);
00342 }
00343
00344 void log_rpn_query(Z_RPNQuery *rpn)
00345 {
00346 log_rpn_query_level(YLOG_LOG, rpn);
00347 }
00348
00349 void log_scan_term_level(int loglevel,
00350 Z_AttributesPlusTerm *zapt, const Odr_oid *ast)
00351 {
00352 int depth = 0;
00353 if (!loglevel)
00354 return;
00355 if (zapt->term->which == Z_Term_general)
00356 {
00357 yaz_log (loglevel, "%*.0s term '%.*s' (general)", depth, "",
00358 zapt->term->u.general->len, zapt->term->u.general->buf);
00359 }
00360 else
00361 yaz_log (loglevel, "%*.0s term (not general)", depth, "");
00362 zlog_attributes(zapt, depth+2, ast, loglevel);
00363 }
00364
00365 void log_scan_term(Z_AttributesPlusTerm *zapt, const Odr_oid *ast)
00366 {
00367 log_scan_term_level (YLOG_LOG, zapt, ast);
00368 }
00369
00370 void yaz_log_zquery_level (int loglevel, Z_Query *q)
00371 {
00372 if (!loglevel)
00373 return;
00374 switch (q->which)
00375 {
00376 case Z_Query_type_1: case Z_Query_type_101:
00377 log_rpn_query_level (loglevel, q->u.type_1);
00378 break;
00379 case Z_Query_type_2:
00380 yaz_log(loglevel, "CCL: %.*s", q->u.type_2->len, q->u.type_2->buf);
00381 break;
00382 case Z_Query_type_100:
00383 yaz_log(loglevel, "Z39.58: %.*s", q->u.type_100->len,
00384 q->u.type_100->buf);
00385 break;
00386 case Z_Query_type_104:
00387 if (q->u.type_104->which == Z_External_CQL)
00388 yaz_log (loglevel, "CQL: %s", q->u.type_104->u.cql);
00389 }
00390 }
00391
00392 void yaz_log_zquery (Z_Query *q)
00393 {
00394 yaz_log_zquery_level(YLOG_LOG, q);
00395 }
00396
00397
00398
00399
00400
00401
00402
00403
00404