1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2011 Index Data
3 * See the file LICENSE for details.
7 * \brief Implements CQL to XCQL conversion.
19 static int cql_to_ccl_r(struct cql_node *cn,
20 void (*pr)(const char *buf, void *client_data),
23 static void pr_term(struct cql_node *cn,
24 void (*pr)(const char *buf, void *client_data),
29 if (! *cn->u.st.term) /* empty term special case */
30 pr("\"\"", client_data);
35 for (cp = cn->u.st.term; *cp; cp++)
39 if (*cp == '\\' && cp[1])
43 pr("\"", client_data);
47 if (*cp == '\"' || *cp == '\\')
48 pr("\\\"", client_data);
60 pr("\"", client_data);
69 pr("\"", client_data);
78 pr("\"", client_data);
87 pr("\"", client_data);
89 if (cn->u.st.extra_terms)
91 cn = cn->u.st.extra_terms;
95 static int node(struct cql_node *cn,
96 void (*pr)(const char *buf, void *client_data),
99 const char *ccl_field = 0;
100 const char *split_op = 0;
101 const char *ccl_rel = 0;
102 const char *rel = cn->u.st.relation;
104 if (cn->u.st.index && strcmp(cn->u.st.index,
106 ccl_field = cn->u.st.index;
110 else if (!strcmp(rel, "<") || !strcmp(rel, "<=")
111 || !strcmp(rel, ">") || !strcmp(rel, ">=")
112 || !strcmp(rel, "<>") || !strcmp(rel, "="))
114 else if (!strcmp(rel, "all"))
119 else if (!strcmp(rel, "any"))
124 else if (!strcmp(rel, "==") || !strcmp(rel, "adj"))
130 /* unsupported relation */
135 if (ccl_field && ccl_rel)
137 pr(ccl_field, client_data);
138 pr(ccl_rel, client_data);
140 pr_term(cn, pr, client_data);
144 const char *cp = cn->u.st.term;
150 if (ccl_field && ccl_rel)
152 pr(ccl_field, client_data);
153 pr(ccl_rel, client_data);
155 while (*cp && *cp != ' ')
170 pr(" ", client_data);
171 pr(split_op, client_data);
172 pr(" ", client_data);
179 static int bool(struct cql_node *cn,
180 void (*pr)(const char *buf, void *client_data),
183 char *value = cn->u.boolean.value;
186 pr("(", client_data);
187 r = cql_to_ccl_r(cn->u.boolean.left, pr, client_data);
191 pr(" ", client_data);
193 if (strcmp(value, "prox"))
194 { /* not proximity. assuming boolean */
195 pr(value, client_data);
199 struct cql_node *n = cn->u.boolean.modifiers;
202 for (; n ; n = n->u.st.modifiers)
203 if (n->which == CQL_NODE_ST)
205 if (!strcmp(n->u.st.index, "unit"))
207 if (!strcmp(n->u.st.term, "word"))
212 else if (!strcmp(n->u.st.index, "distance"))
214 if (!strcmp(n->u.st.relation, "<="))
215 distance = atoi(n->u.st.term);
216 else if (!strcmp(n->u.st.relation, "<"))
217 distance = atoi(n->u.st.term) - 1;
221 else if (!strcmp(n->u.st.index, "unordered"))
225 else if (!strcmp(n->u.st.index, "ordered"))
232 pr(ordered ? "!" : "%", client_data);
236 sprintf(x, "%d", distance);
240 pr(" ", client_data);
242 r = cql_to_ccl_r(cn->u.boolean.right, pr, client_data);
243 pr(")", client_data);
247 static int cql_to_ccl_r(struct cql_node *cn,
248 void (*pr)(const char *buf, void *client_data),
257 return node(cn, pr, client_data);
259 return bool(cn, pr, client_data);
261 return cql_to_ccl_r(cn->u.sort.search, pr, client_data);
266 int cql_to_ccl(struct cql_node *cn,
267 void (*pr)(const char *buf, void *client_data),
270 return cql_to_ccl_r(cn, pr, client_data);
273 void cql_to_ccl_stdio(struct cql_node *cn, FILE *f)
275 cql_to_ccl(cn, cql_fputs, f);
278 int cql_to_ccl_buf(struct cql_node *cn, char *out, int max)
280 struct cql_buf_write_info info;
285 r = cql_to_ccl(cn, cql_buf_write_handler, &info);
287 info.buf[info.off] = '\0';
289 return -2; /* buffer overflow */
296 * c-file-style: "Stroustrup"
297 * indent-tabs-mode: nil
299 * vim: shiftwidth=4 tabstop=8 expandtab