Fixed description
[yaz-moved-to-github.git] / src / rpn2cql.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2008 Index Data
3  * See the file LICENSE for details.
4  */
5
6 /**
7  * \file
8  * \brief Implements RPN to CQL conversion
9  *
10  * Evaluation order of rules:
11  *
12  * always
13  * relation
14  * structure
15  * position
16  * truncation
17  * index
18  * relationModifier
19  */
20
21 #include <assert.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <yaz/rpn2cql.h>
25 #include <yaz/xmalloc.h>
26 #include <yaz/diagbib1.h>
27 #include <yaz/z-core.h>
28 #include <yaz/wrbuf.h>
29
30 static int rpn2cql_attr(cql_transform_t ct,
31                         void (*pr)(const char *buf, void *client_data),
32                         void *client_data,
33                         Z_AttributeList *attributes, WRBUF w)
34 {
35     int i;
36     for (i = 0; i < attributes->num_attributes; i++)
37     {
38         Z_AttributeElement *elem = attributes->attributes[i];
39     }
40     return 0;
41 }
42
43 static int rpn2cql_simple(cql_transform_t ct,
44                           void (*pr)(const char *buf, void *client_data),
45                           void *client_data,
46                           Z_Operand *q, WRBUF w)
47 {
48     int ret = 0;
49     if (q->which != Z_Operand_APT)
50     {
51         ret = -1;
52         cql_transform_set_error(ct, YAZ_BIB1_RESULT_SET_UNSUPP_AS_A_SEARCH_TERM, 0);
53     }
54     else
55     {
56         Z_AttributesPlusTerm *apt = q->u.attributesPlusTerm;
57         Z_Term *term = apt->term;
58
59         wrbuf_rewind(w);
60         ret = rpn2cql_attr(ct, pr, client_data, apt->attributes, w);
61
62         switch(term->which)
63         {
64         case Z_Term_general:
65             wrbuf_write(w, (const char *) term->u.general->buf, term->u.general->len);
66             break;
67         case Z_Term_numeric:
68             wrbuf_printf(w, "%d", *term->u.numeric);
69             break;
70         case Z_Term_characterString:
71             wrbuf_puts(w, term->u.characterString);
72             break;
73         default:
74             ret = -1;
75             cql_transform_set_error(ct, YAZ_BIB1_TERM_TYPE_UNSUPP, 0);
76         }
77         if (ret == 0)
78             pr(wrbuf_cstr(w), client_data);
79     }
80     return ret;
81 }
82
83 static int rpn2cql_structure(cql_transform_t ct,
84                              void (*pr)(const char *buf, void *client_data),
85                              void *client_data,
86                              Z_RPNStructure *q, int nested,
87                              WRBUF w)
88 {
89     if (q->which == Z_RPNStructure_simple)
90         return rpn2cql_simple(ct, pr, client_data, q->u.simple, w);
91     else
92     {
93         Z_Operator *op = q->u.complex->roperator;
94         int r;
95
96         if (nested)
97             pr("(", client_data);
98
99         r = rpn2cql_structure(ct, pr, client_data, q->u.complex->s1, 1, w);
100         if (r)
101             return r;
102         switch(op->which)
103         {
104         case  Z_Operator_and:
105             pr(" and ", client_data);
106             break;
107         case  Z_Operator_or:
108             pr(" or ", client_data);
109             break;
110         case  Z_Operator_and_not:
111             pr(" not ", client_data);
112             break;
113         case  Z_Operator_prox:
114             cql_transform_set_error(ct, YAZ_BIB1_UNSUPP_SEARCH, 0);
115             return -1;
116         }
117         r = rpn2cql_structure(ct, pr, client_data, q->u.complex->s2, 1, w);
118         if (nested)
119             pr(")", client_data);
120         return r;
121     }
122 }
123
124 int cql_transform_rpn2cql_stream(cql_transform_t ct,
125                                  void (*pr)(const char *buf, void *client_data),
126                                  void *client_data,
127                                  Z_RPNQuery *q)
128 {
129     int r;
130     WRBUF w = wrbuf_alloc();
131     cql_transform_set_error(ct, 0, 0);
132     r = rpn2cql_structure(ct, pr, client_data, q->RPNStructure, 0, w);
133     wrbuf_destroy(w);
134     return r;
135 }
136
137
138 int cql_transform_rpn2cql_wrbuf(cql_transform_t ct,
139                                 WRBUF w,
140                                 Z_RPNQuery *q)
141 {
142     return cql_transform_rpn2cql_stream(ct, wrbuf_vputs, w, q);
143 }
144
145 /*
146  * Local variables:
147  * c-basic-offset: 4
148  * indent-tabs-mode: nil
149  * End:
150  * vim: shiftwidth=4 tabstop=8 expandtab
151  */
152