Fix left/right switch of truncation flag
[yaz-moved-to-github.git] / src / cqlutil.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2011 Index Data
3  * See the file LICENSE for details.
4  */
5 /**
6  * \file cqlutil.c
7  * \brief Implements CQL tree node utilities.
8  */
9 #if HAVE_CONFIG_H
10 #include <config.h>
11 #endif
12
13 #include <stdlib.h>
14 #include <string.h>
15
16 #include <yaz/cql.h>
17
18 void cql_fputs(const char *buf, void *client_data)
19 {
20     FILE *f = (FILE *) client_data;
21     fputs(buf, f);
22 }
23
24 struct cql_node *cql_node_dup (NMEM nmem, struct cql_node *cp)
25 {
26     struct cql_node *cn = 0;
27
28     if (!cp)
29         return 0;
30     switch (cp->which)
31     {
32     case CQL_NODE_ST:
33         cn = cql_node_mk_sc(nmem, cp->u.st.index,
34                             cp->u.st.relation,
35                             cp->u.st.term);
36         cn->u.st.modifiers = cql_node_dup(nmem, cp->u.st.modifiers);
37         cn->u.st.index_uri = cp->u.st.index_uri ? 
38             nmem_strdup(nmem, cp->u.st.index_uri) : 0;
39         cn->u.st.relation_uri = cp->u.st.relation_uri ?
40             nmem_strdup(nmem, cp->u.st.relation_uri) : 0;
41         break;
42     case CQL_NODE_BOOL:
43         cn = cql_node_mk_boolean(nmem, cp->u.boolean.value);
44         cn->u.boolean.left = cql_node_dup(nmem, cp->u.boolean.left);
45         cn->u.boolean.right = cql_node_dup(nmem, cp->u.boolean.right);
46     }
47     return cn;
48 }
49
50 struct cql_node *cql_node_mk_sc(NMEM nmem,
51                                 const char *index,
52                                 const char *relation,
53                                 const char *term)
54 {
55     struct cql_node *p = (struct cql_node *) nmem_malloc(nmem, sizeof(*p));
56     p->which = CQL_NODE_ST;
57     p->u.st.index = 0;
58     if (index)
59         p->u.st.index = nmem_strdup(nmem, index);
60     p->u.st.index_uri = 0;
61     p->u.st.term = 0;
62     if (term)
63         p->u.st.term = nmem_strdup(nmem, term);
64     p->u.st.relation = 0;
65     if (relation)
66         p->u.st.relation = nmem_strdup(nmem, relation);
67     p->u.st.relation_uri = 0;
68     p->u.st.modifiers = 0;
69     p->u.st.extra_terms = 0;
70     return p;
71 }
72
73 struct cql_node *cql_node_mk_boolean(NMEM nmem, const char *op)
74 {
75     struct cql_node *p = (struct cql_node *) nmem_malloc(nmem, sizeof(*p));
76     p->which = CQL_NODE_BOOL;
77     p->u.boolean.value = 0;
78     if (op)
79         p->u.boolean.value = nmem_strdup(nmem, op);
80     p->u.boolean.left = 0;
81     p->u.boolean.right = 0;
82     p->u.boolean.modifiers = 0;
83     return p;
84 }
85
86 const char *cql_uri(void)
87 {
88     return "info:srw/cql-context-set/1/cql-v1.2";
89 }
90
91 struct cql_node *cql_apply_prefix(NMEM nmem,
92                                   struct cql_node *n, const char *prefix,
93                                   const char *uri)
94 {
95     if (n->which == CQL_NODE_ST)
96     {
97         if (!n->u.st.index_uri && n->u.st.index)
98         {   /* not yet resolved.. */
99             const char *cp = strchr(n->u.st.index, '.');
100             if (prefix && cp && 
101                 strlen(prefix) == (size_t) (cp - n->u.st.index) &&
102                 !cql_strncmp(n->u.st.index, prefix, strlen(prefix)))
103             {
104                 char *nval = nmem_strdup(nmem, cp+1);
105                 n->u.st.index_uri = nmem_strdup(nmem, uri);
106                 n->u.st.index = nval;
107             }
108             else if (!prefix && !cp)
109             {
110                 n->u.st.index_uri = nmem_strdup(nmem, uri);
111             }
112         }
113         if (!n->u.st.relation_uri && n->u.st.relation)
114         {
115             const char *cp = strchr(n->u.st.relation, '.');
116             if (prefix && cp &&
117                 strlen(prefix) == (size_t)(cp - n->u.st.relation) &&
118                 !cql_strncmp(n->u.st.relation, prefix, strlen(prefix)))
119             {
120                 char *nval = nmem_strdup(nmem, cp+1);
121                 n->u.st.relation_uri = nmem_strdup(nmem, uri);
122                 n->u.st.relation = nval;
123             }
124         }
125     }
126     else if (n->which == CQL_NODE_BOOL)
127     {
128         cql_apply_prefix(nmem, n->u.boolean.left, prefix, uri);
129         cql_apply_prefix(nmem, n->u.boolean.right, prefix, uri);
130     }
131     return n;
132 }
133
134 void cql_node_destroy(struct cql_node *cn)
135 {
136     if (!cn)
137         return;
138     switch (cn->which)
139     {
140     case CQL_NODE_ST:
141         cql_node_destroy(cn->u.st.modifiers);
142         break;
143     case CQL_NODE_BOOL:
144         cql_node_destroy(cn->u.boolean.left);
145         cql_node_destroy(cn->u.boolean.right);
146         cql_node_destroy(cn->u.boolean.modifiers);
147     }
148 }
149
150 int cql_strcmp(const char *s1, const char *s2)
151 {
152     while (*s1 && *s2)
153     {
154         int c1 = *s1++;
155         int c2 = *s2++;
156         if (c1 >= 'A' && c1 <= 'Z')
157             c1 = c1 + ('a' - 'A');
158         if (c2 >= 'A' && c2 <= 'Z')
159             c2 = c2 + ('a' - 'A');
160         if (c1 != c2)
161             return c1 - c2;
162     }
163     return *s1 - *s2;
164 }
165
166 int cql_strncmp(const char *s1, const char *s2, size_t n)
167 {
168     while (*s1 && *s2 && n)
169     {
170         int c1 = *s1++;
171         int c2 = *s2++;
172         if (c1 >= 'A' && c1 <= 'Z')
173             c1 = c1 + ('a' - 'A');
174         if (c2 >= 'A' && c2 <= 'Z')
175             c2 = c2 + ('a' - 'A');
176         if (c1 != c2)
177             return c1 - c2;
178         --n;
179     }
180     if (!n)
181         return 0;
182     return *s1 - *s2;
183 }
184
185 /*
186  * Local variables:
187  * c-basic-offset: 4
188  * c-file-style: "Stroustrup"
189  * indent-tabs-mode: nil
190  * End:
191  * vim: shiftwidth=4 tabstop=8 expandtab
192  */
193