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;
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);
136 pr_term(&cp, split_op ? 1 : 0, pr, client_data);
141 pr(" ", client_data);
144 pr(split_op, client_data);
145 pr(" ", client_data);
148 if (cn->u.st.extra_terms)
150 pr(" ", client_data);
153 pr(split_op, client_data);
154 pr(" ", client_data);
162 static int bool(struct cql_node *cn,
163 void (*pr)(const char *buf, void *client_data),
166 char *value = cn->u.boolean.value;
169 pr("(", client_data);
170 r = cql_to_ccl_r(cn->u.boolean.left, pr, client_data);
174 pr(") ", client_data);
176 if (strcmp(value, "prox"))
177 { /* not proximity. assuming boolean */
178 pr(value, client_data);
182 struct cql_node *n = cn->u.boolean.modifiers;
185 for (; n ; n = n->u.st.modifiers)
186 if (n->which == CQL_NODE_ST)
188 if (!strcmp(n->u.st.index, "unit"))
190 if (!strcmp(n->u.st.term, "word"))
195 else if (!strcmp(n->u.st.index, "distance"))
197 if (!strcmp(n->u.st.relation, "<="))
198 distance = atoi(n->u.st.term);
199 else if (!strcmp(n->u.st.relation, "<"))
200 distance = atoi(n->u.st.term) - 1;
204 else if (!strcmp(n->u.st.index, "unordered"))
208 else if (!strcmp(n->u.st.index, "ordered"))
215 pr(ordered ? "!" : "%", client_data);
219 sprintf(x, "%d", distance);
223 pr(" (", client_data);
225 r = cql_to_ccl_r(cn->u.boolean.right, pr, client_data);
226 pr(")", client_data);
230 static int cql_to_ccl_r(struct cql_node *cn,
231 void (*pr)(const char *buf, void *client_data),
240 return node(cn, pr, client_data);
242 return bool(cn, pr, client_data);
244 return cql_to_ccl_r(cn->u.sort.search, pr, client_data);
249 int cql_to_ccl(struct cql_node *cn,
250 void (*pr)(const char *buf, void *client_data),
253 return cql_to_ccl_r(cn, pr, client_data);
256 void cql_to_ccl_stdio(struct cql_node *cn, FILE *f)
258 cql_to_ccl(cn, cql_fputs, f);
261 int cql_to_ccl_buf(struct cql_node *cn, char *out, int max)
263 struct cql_buf_write_info info;
268 r = cql_to_ccl(cn, cql_buf_write_handler, &info);
270 info.buf[info.off] = '\0';
272 return -2; /* buffer overflow */
279 * c-file-style: "Stroustrup"
280 * indent-tabs-mode: nil
282 * vim: shiftwidth=4 tabstop=8 expandtab