1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2013 Index Data
3 * See the file LICENSE for details.
7 * \brief Implements CQL to CCL 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(const char **cpp, int stop_at_space,
24 void (*pr)(const char *buf, void *client_data),
29 for (cp = *cpp; *cp; cp++)
33 if (*cp == '\\' && cp[1])
37 pr("\"", client_data);
41 if (*cp == '\"' || *cp == '\\')
42 pr("\\", client_data);
51 pr("\"", client_data);
60 pr("\"", client_data);
65 else if (*cp == ' ' && stop_at_space)
71 pr("\"", client_data);
80 pr("\"", client_data);
82 pr("\"\"", client_data);
86 static int node(struct cql_node *cn,
87 void (*pr)(const char *buf, void *client_data),
90 const char *ccl_field = 0;
91 const char *split_op = 0;
92 const char *ccl_rel = 0;
93 const char *rel = cn->u.st.relation;
96 if (cn->u.st.index && strcmp(cn->u.st.index,
98 ccl_field = cn->u.st.index;
102 else if (!strcmp(rel, "<") || !strcmp(rel, "<=")
103 || !strcmp(rel, ">") || !strcmp(rel, ">=")
104 || !strcmp(rel, "<>") || !strcmp(rel, "="))
106 else if (!strcmp(rel, "all"))
111 else if (!strcmp(rel, "any"))
116 else if (!strcmp(rel, "==") || !strcmp(rel, "adj"))
122 /* unsupported relation */
128 if (ccl_field && ccl_rel)
130 pr(ccl_field, client_data);
131 pr(ccl_rel, client_data);
135 pr_term(&cp, split_op ? 1 : 0, pr, client_data);
140 pr(" ", client_data);
143 pr(split_op, client_data);
144 pr(" ", client_data);
151 static int bool(struct cql_node *cn,
152 void (*pr)(const char *buf, void *client_data),
155 char *value = cn->u.boolean.value;
158 pr("(", client_data);
159 r = cql_to_ccl_r(cn->u.boolean.left, pr, client_data);
163 pr(") ", client_data);
165 if (strcmp(value, "prox"))
166 { /* not proximity. assuming boolean */
167 pr(value, client_data);
171 struct cql_node *n = cn->u.boolean.modifiers;
174 for (; n ; n = n->u.st.modifiers)
175 if (n->which == CQL_NODE_ST)
177 if (!strcmp(n->u.st.index, "unit"))
179 if (!strcmp(n->u.st.term, "word"))
184 else if (!strcmp(n->u.st.index, "distance"))
186 if (!strcmp(n->u.st.relation, "<="))
187 distance = atoi(n->u.st.term);
188 else if (!strcmp(n->u.st.relation, "<"))
189 distance = atoi(n->u.st.term) - 1;
193 else if (!strcmp(n->u.st.index, "unordered"))
197 else if (!strcmp(n->u.st.index, "ordered"))
204 pr(ordered ? "!" : "%", client_data);
208 sprintf(x, "%d", distance);
212 pr(" (", client_data);
214 r = cql_to_ccl_r(cn->u.boolean.right, pr, client_data);
215 pr(")", client_data);
219 static int cql_to_ccl_r(struct cql_node *cn,
220 void (*pr)(const char *buf, void *client_data),
229 return node(cn, pr, client_data);
231 return bool(cn, pr, client_data);
233 return cql_to_ccl_r(cn->u.sort.search, pr, client_data);
238 int cql_to_ccl(struct cql_node *cn,
239 void (*pr)(const char *buf, void *client_data),
242 return cql_to_ccl_r(cn, pr, client_data);
245 void cql_to_ccl_stdio(struct cql_node *cn, FILE *f)
247 cql_to_ccl(cn, cql_fputs, f);
250 int cql_to_ccl_buf(struct cql_node *cn, char *out, int max)
252 struct cql_buf_write_info info;
257 r = cql_to_ccl(cn, cql_buf_write_handler, &info);
259 info.buf[info.off] = '\0';
261 return -2; /* buffer overflow */
268 * c-file-style: "Stroustrup"
269 * indent-tabs-mode: nil
271 * vim: shiftwidth=4 tabstop=8 expandtab