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 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);
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;
95 if (cn->u.st.index && strcmp(cn->u.st.index,
97 ccl_field = cn->u.st.index;
101 else if (!strcmp(rel, "<") || !strcmp(rel, "<=")
102 || !strcmp(rel, ">") || !strcmp(rel, ">=")
103 || !strcmp(rel, "<>") || !strcmp(rel, "="))
105 else if (!strcmp(rel, "all"))
110 else if (!strcmp(rel, "any"))
115 else if (!strcmp(rel, "==") || !strcmp(rel, "adj"))
121 /* unsupported relation */
124 for (; cn; cn = cn->u.st.extra_terms)
126 const char *cp = cn->u.st.term;
129 if (ccl_field && ccl_rel)
131 pr(ccl_field, client_data);
132 pr(ccl_rel, client_data);
134 pr_term(&cp, split_op ? 1 : 0, pr, client_data);
141 pr(" ", client_data);
142 pr(split_op, client_data);
143 pr(" ", client_data);
145 if (cn->u.st.extra_terms)
147 pr(" ", client_data);
150 pr(split_op, client_data);
151 pr(" ", client_data);
159 static int bool(struct cql_node *cn,
160 void (*pr)(const char *buf, void *client_data),
163 char *value = cn->u.boolean.value;
166 pr("(", client_data);
167 r = cql_to_ccl_r(cn->u.boolean.left, pr, client_data);
171 pr(") ", client_data);
173 if (strcmp(value, "prox"))
174 { /* not proximity. assuming boolean */
175 pr(value, client_data);
179 struct cql_node *n = cn->u.boolean.modifiers;
182 for (; n ; n = n->u.st.modifiers)
183 if (n->which == CQL_NODE_ST)
185 if (!strcmp(n->u.st.index, "unit"))
187 if (!strcmp(n->u.st.term, "word"))
192 else if (!strcmp(n->u.st.index, "distance"))
194 if (!strcmp(n->u.st.relation, "<="))
195 distance = atoi(n->u.st.term);
196 else if (!strcmp(n->u.st.relation, "<"))
197 distance = atoi(n->u.st.term) - 1;
201 else if (!strcmp(n->u.st.index, "unordered"))
205 else if (!strcmp(n->u.st.index, "ordered"))
212 pr(ordered ? "!" : "%", client_data);
216 sprintf(x, "%d", distance);
220 pr(" (", client_data);
222 r = cql_to_ccl_r(cn->u.boolean.right, pr, client_data);
223 pr(")", client_data);
227 static int cql_to_ccl_r(struct cql_node *cn,
228 void (*pr)(const char *buf, void *client_data),
237 return node(cn, pr, client_data);
239 return bool(cn, pr, client_data);
241 return cql_to_ccl_r(cn->u.sort.search, pr, client_data);
246 int cql_to_ccl(struct cql_node *cn,
247 void (*pr)(const char *buf, void *client_data),
250 return cql_to_ccl_r(cn, pr, client_data);
253 void cql_to_ccl_stdio(struct cql_node *cn, FILE *f)
255 cql_to_ccl(cn, cql_fputs, f);
258 int cql_to_ccl_buf(struct cql_node *cn, char *out, int max)
260 struct cql_buf_write_info info;
265 r = cql_to_ccl(cn, cql_buf_write_handler, &info);
267 info.buf[info.off] = '\0';
269 return -2; /* buffer overflow */
276 * c-file-style: "Stroustrup"
277 * indent-tabs-mode: nil
279 * vim: shiftwidth=4 tabstop=8 expandtab