YAZ 5.35.1
xcqlutil.c
Go to the documentation of this file.
1/* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
4 */
9#if HAVE_CONFIG_H
10#include <config.h>
11#endif
12
13#include <stdlib.h>
14#include <string.h>
15#include <stdio.h>
16
17#include <yaz/cql.h>
18
19static void pr_n(const char *buf,
20 void (*pr)(const char *buf, void *client_data),
21 void *client_data, int n)
22{
23 int i;
24 for (i = 0; i<n; i++)
25 (*pr)(" ", client_data);
26 (*pr)(buf, client_data);
27}
28
29static void pr_cdata(const char *buf,
30 void (*pr)(const char *buf, void *client_data),
31 void *client_data)
32{
33 const char *src = buf;
34 char bf[2];
35 while (*src)
36 {
37 switch(*src)
38 {
39 case '&':
40 (*pr)("&amp;", client_data);
41 break;
42 case '<':
43 (*pr)("&lt;", client_data);
44 break;
45 case '>':
46 (*pr)("&gt;", client_data);
47 break;
48 default:
49 bf[0] = *src;
50 bf[1] = 0;
51 (*pr)(bf, client_data);
52 }
53 src++;
54 }
55}
56
57static void prefixes(struct cql_node *cn,
58 void (*pr)(const char *buf, void *client_data),
59 void *client_data, int level)
60{
61 int head = 0;
62 if (cn->u.st.index_uri)
63 {
64 pr_n("<prefixes>\n", pr, client_data, level);
65 head = 1;
66
67 pr_n("<prefix>\n", pr, client_data, level+2);
68 pr_n("<identifier>", pr, client_data, level+4);
69 pr_cdata(cn->u.st.index_uri, pr, client_data);
70 pr_n("</identifier>\n", pr, client_data, 0);
71 pr_n("</prefix>\n", pr, client_data, level+2);
72 }
73 if (cn->u.st.relation_uri && cn->u.st.relation)
74 {
75 if (!head)
76 pr_n("<prefixes>\n", pr, client_data, level);
77 pr_n("<prefix>\n", pr, client_data, level+2);
78 pr_n("<name>", pr, client_data, level+4);
79 pr_cdata("rel", pr, client_data);
80 pr_n("</name>\n", pr, client_data, 0);
81 pr_n("<identifier>", pr, client_data, level+4);
82 pr_cdata(cn->u.st.relation_uri, pr, client_data);
83 pr_n("</identifier>\n", pr, client_data, 0);
84 pr_n("</prefix>\n", pr, client_data, level+2);
85 }
86 if (head)
87 pr_n("</prefixes>\n", pr, client_data, level);
88}
89
90static void cql_to_xml_mod(struct cql_node *m,
91 void (*pr)(const char *buf, void *client_data),
92 void *client_data, int level)
93{
94 if (m)
95 {
96 pr_n("<modifiers>\n", pr, client_data, level);
97 for (; m; m = m->u.st.modifiers)
98 {
99 pr_n("<modifier>\n", pr, client_data, level+2);
100 pr_n("<type>", pr, client_data, level+4);
101 pr_cdata(m->u.st.index, pr, client_data);
102 pr_n("</type>\n", pr, client_data, 0);
103 if (m->u.st.relation)
104 {
105 pr_n("<comparison>", pr, client_data, level+4);
106 pr_cdata(m->u.st.relation, pr, client_data);
107 pr_n("</comparison>\n", pr, client_data, 0);
108 }
109 if (m->u.st.term)
110 {
111 pr_n("<value>", pr, client_data, level+4);
112 pr_cdata(m->u.st.term, pr, client_data);
113 pr_n("</value>\n", pr, client_data, 0);
114 }
115 pr_n("</modifier>\n", pr, client_data, level+2);
116 }
117 pr_n("</modifiers>\n", pr, client_data, level);
118 }
119}
120
121static void cql_sort_to_xml(struct cql_node *cn,
122 void (*pr)(const char *buf, void *client_data),
123 void *client_data, int level)
124{
125 if (cn)
126 {
127 pr_n("<sortKeys>\n", pr, client_data, level);
128 for (; cn; cn = cn->u.sort.next)
129 {
130 pr_n("<key>\n", pr, client_data, level+2);
131
132 if (cn->u.sort.index)
133 {
134 pr_n("<index>", pr, client_data, level+4);
135 pr_cdata(cn->u.sort.index, pr, client_data);
136 pr_n("</index>\n", pr, client_data, 0);
137
139 pr, client_data, level+6);
140 }
141 pr_n("</key>\n", pr, client_data, level+2);
142 }
143 pr_n("</sortKeys>\n", pr, client_data, level);
144 }
145}
146
147static void cql_to_xml_r(struct cql_node *cn,
148 void (*pr)(const char *buf, void *client_data),
149 void *client_data, int level,
150 struct cql_node *sort_node)
151{
152 if (!cn)
153 return;
154 switch (cn->which)
155 {
156 case CQL_NODE_ST:
157 pr_n("<searchClause>\n", pr, client_data, level);
158 prefixes(cn, pr, client_data, level+2);
159 if (cn->u.st.index)
160 {
161 pr_n("<index>", pr, client_data, level+2);
162 pr_cdata(cn->u.st.index, pr, client_data);
163 pr_n("</index>\n", pr, client_data, 0);
164 }
165 if (cn->u.st.relation)
166 {
167 pr_n("<relation>\n", pr, client_data, level+2);
168 pr_n("<value>", pr, client_data, level+4);
169 if (cn->u.st.relation_uri)
170 pr_cdata("rel.", pr, client_data);
171 pr_cdata(cn->u.st.relation, pr, client_data);
172 pr_n("</value>\n", pr, client_data, 0);
173
174 if (cn->u.st.relation_uri)
175 {
176 pr_n("<identifier>", pr, client_data, level+4);
177 pr_cdata(cn->u.st.relation_uri, pr, client_data);
178 pr_n("</identifier>\n", pr, client_data, 0);
179 }
181 pr, client_data, level+4);
182
183 pr_n("</relation>\n", pr, client_data, level+2);
184 }
185 if (cn->u.st.term)
186 {
187 pr_n("<term>", pr, client_data, level+2);
188 pr_cdata(cn->u.st.term, pr, client_data);
189 pr_n("</term>\n", pr, client_data, 0);
190 }
191 if (cn->u.st.extra_terms)
192 {
193 struct cql_node *n = cn->u.st.extra_terms;
194 for (; n; n = n->u.st.extra_terms)
195 {
196 pr_n("<term>", pr, client_data, level+2);
197 pr_cdata(n->u.st.term, pr, client_data);
198 pr_n("</term>\n", pr, client_data, 0);
199 }
200 }
201 cql_sort_to_xml(sort_node, pr, client_data, level+2);
202 pr_n("</searchClause>\n", pr, client_data, level);
203 break;
204 case CQL_NODE_BOOL:
205 pr_n("<triple>\n", pr, client_data, level);
206 if (cn->u.boolean.value)
207 {
208 pr_n("<boolean>\n", pr, client_data, level+2);
209
210 pr_n("<value>", pr, client_data, level+4);
211 pr_cdata(cn->u.boolean.value, pr, client_data);
212 pr_n("</value>\n", pr, client_data, 0);
213
215 pr, client_data, level+4);
216
217 pr_n("</boolean>\n", pr, client_data, level+2);
218 }
219 if (cn->u.boolean.left)
220 {
221 printf ("%*s<leftOperand>\n", level+2, "");
222 cql_to_xml_r(cn->u.boolean.left, pr, client_data, level+4, 0);
223 printf ("%*s</leftOperand>\n", level+2, "");
224 }
225 if (cn->u.boolean.right)
226 {
227 printf ("%*s<rightOperand>\n", level+2, "");
228 cql_to_xml_r(cn->u.boolean.right, pr, client_data, level+4, 0);
229 printf ("%*s</rightOperand>\n", level+2, "");
230 }
231 cql_sort_to_xml(sort_node, pr, client_data, level+2);
232 pr_n("</triple>\n", pr, client_data, level);
233 break;
234 case CQL_NODE_SORT:
235 cql_to_xml_r(cn->u.sort.search, pr, client_data, level, cn);
236 }
237}
238
239void cql_to_xml(struct cql_node *cn,
240 void (*pr)(const char *buf, void *client_data),
241 void *client_data)
242{
243 cql_to_xml_r(cn, pr, client_data, 0, 0);
244}
245
246void cql_to_xml_stdio(struct cql_node *cn, FILE *f)
247{
248 cql_to_xml(cn, cql_fputs, f);
249}
250
251void cql_buf_write_handler (const char *b, void *client_data)
252{
253 struct cql_buf_write_info *info = (struct cql_buf_write_info *)client_data;
254 int l = strlen(b);
255 if (info->off < 0 || (info->off + l >= info->max))
256 {
257 info->off = -1;
258 return;
259 }
260 memcpy (info->buf + info->off, b, l);
261 info->off += l;
262}
263
264int cql_to_xml_buf(struct cql_node *cn, char *out, int max)
265{
266 struct cql_buf_write_info info;
267 info.off = 0;
268 info.max = max;
269 info.buf = out;
271 if (info.off >= 0)
272 info.buf[info.off] = '\0';
273 return info.off;
274}
275
276/*
277 * Local variables:
278 * c-basic-offset: 4
279 * c-file-style: "Stroustrup"
280 * indent-tabs-mode: nil
281 * End:
282 * vim: shiftwidth=4 tabstop=8 expandtab
283 */
284
Header with public definitions about CQL.
#define CQL_NODE_SORT
Node type: sortby single spec.
Definition cql.h:115
#define CQL_NODE_ST
Node type: search term.
Definition cql.h:111
#define CQL_NODE_BOOL
Node type: boolean.
Definition cql.h:113
void cql_fputs(const char *buf, void *client_data)
stream handle for file (used by cql_to_xml_stdio)
Definition cqlutil.c:18
Structure used by cql_buf_write_handler.
Definition cql.h:170
CQL parse tree (node)
Definition cql.h:119
struct cql_node::@10::@12 boolean
struct cql_node * right
Definition cql.h:147
char * value
Definition cql.h:143
char * relation_uri
Definition cql.h:134
struct cql_node::@10::@13 sort
struct cql_node * search
Definition cql.h:159
struct cql_node * next
Definition cql.h:155
struct cql_node::@10::@11 st
struct cql_node * extra_terms
Definition cql.h:138
union cql_node::@10 u
struct cql_node * modifiers
Definition cql.h:136
int which
Definition cql.h:121
char * relation
Definition cql.h:132
char * index
Definition cql.h:126
char * index_uri
Definition cql.h:128
struct cql_node * left
Definition cql.h:145
char * term
Definition cql.h:130
static void cql_sort_to_xml(struct cql_node *cn, void(*pr)(const char *buf, void *client_data), void *client_data, int level)
Definition xcqlutil.c:121
void cql_to_xml(struct cql_node *cn, void(*pr)(const char *buf, void *client_data), void *client_data)
converts CQL tree to XCQL and writes to user-defined stream
Definition xcqlutil.c:239
static void cql_to_xml_r(struct cql_node *cn, void(*pr)(const char *buf, void *client_data), void *client_data, int level, struct cql_node *sort_node)
Definition xcqlutil.c:147
static void pr_n(const char *buf, void(*pr)(const char *buf, void *client_data), void *client_data, int n)
Definition xcqlutil.c:19
static void cql_to_xml_mod(struct cql_node *m, void(*pr)(const char *buf, void *client_data), void *client_data, int level)
Definition xcqlutil.c:90
static void pr_cdata(const char *buf, void(*pr)(const char *buf, void *client_data), void *client_data)
Definition xcqlutil.c:29
void cql_to_xml_stdio(struct cql_node *cn, FILE *f)
converts CQL tree to XCQL and writes to file
Definition xcqlutil.c:246
int cql_to_xml_buf(struct cql_node *cn, char *out, int max)
converts CQL tree to XCQL and writes result to buffer
Definition xcqlutil.c:264
static void prefixes(struct cql_node *cn, void(*pr)(const char *buf, void *client_data), void *client_data, int level)
Definition xcqlutil.c:57
void cql_buf_write_handler(const char *b, void *client_data)
Handler for cql_buf_write_info.
Definition xcqlutil.c:251