/* This file is part of the YAZ toolkit. * Copyright (C) Index Data * See the file LICENSE for details. */ /** * \file xcqlutil.c * \brief Implements CQL to XCQL conversion. */ #if HAVE_CONFIG_H #include #endif #include #include #include #include static void pr_n(const char *buf, void (*pr)(const char *buf, void *client_data), void *client_data, int n) { int i; for (i = 0; i': (*pr)(">", client_data); break; default: bf[0] = *src; bf[1] = 0; (*pr)(bf, client_data); } src++; } } static void prefixes(struct cql_node *cn, void (*pr)(const char *buf, void *client_data), void *client_data, int level) { int head = 0; if (cn->u.st.index_uri) { pr_n("\n", pr, client_data, level); head = 1; pr_n("\n", pr, client_data, level+2); pr_n("", pr, client_data, level+4); pr_cdata(cn->u.st.index_uri, pr, client_data); pr_n("\n", pr, client_data, 0); pr_n("\n", pr, client_data, level+2); } if (cn->u.st.relation_uri && cn->u.st.relation) { if (!head) pr_n("\n", pr, client_data, level); pr_n("\n", pr, client_data, level+2); pr_n("", pr, client_data, level+4); pr_cdata("rel", pr, client_data); pr_n("\n", pr, client_data, 0); pr_n("", pr, client_data, level+4); pr_cdata(cn->u.st.relation_uri, pr, client_data); pr_n("\n", pr, client_data, 0); pr_n("\n", pr, client_data, level+2); } if (head) pr_n("\n", pr, client_data, level); } static void cql_to_xml_mod(struct cql_node *m, void (*pr)(const char *buf, void *client_data), void *client_data, int level) { if (m) { pr_n("\n", pr, client_data, level); for (; m; m = m->u.st.modifiers) { pr_n("\n", pr, client_data, level+2); pr_n("", pr, client_data, level+4); pr_cdata(m->u.st.index, pr, client_data); pr_n("\n", pr, client_data, 0); if (m->u.st.relation) { pr_n("", pr, client_data, level+4); pr_cdata(m->u.st.relation, pr, client_data); pr_n("\n", pr, client_data, 0); } if (m->u.st.term) { pr_n("", pr, client_data, level+4); pr_cdata(m->u.st.term, pr, client_data); pr_n("\n", pr, client_data, 0); } pr_n("\n", pr, client_data, level+2); } pr_n("\n", pr, client_data, level); } } static void cql_sort_to_xml(struct cql_node *cn, void (*pr)(const char *buf, void *client_data), void *client_data, int level) { if (cn) { pr_n("\n", pr, client_data, level); for (; cn; cn = cn->u.sort.next) { pr_n("\n", pr, client_data, level+2); if (cn->u.sort.index) { pr_n("", pr, client_data, level+4); pr_cdata(cn->u.sort.index, pr, client_data); pr_n("\n", pr, client_data, 0); cql_to_xml_mod(cn->u.sort.modifiers, pr, client_data, level+6); } pr_n("\n", pr, client_data, level+2); } pr_n("\n", pr, client_data, level); } } 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) { if (!cn) return; switch (cn->which) { case CQL_NODE_ST: pr_n("\n", pr, client_data, level); prefixes(cn, pr, client_data, level+2); if (cn->u.st.index) { pr_n("", pr, client_data, level+2); pr_cdata(cn->u.st.index, pr, client_data); pr_n("\n", pr, client_data, 0); } if (cn->u.st.relation) { pr_n("\n", pr, client_data, level+2); pr_n("", pr, client_data, level+4); if (cn->u.st.relation_uri) pr_cdata("rel.", pr, client_data); pr_cdata(cn->u.st.relation, pr, client_data); pr_n("\n", pr, client_data, 0); if (cn->u.st.relation_uri) { pr_n("", pr, client_data, level+4); pr_cdata(cn->u.st.relation_uri, pr, client_data); pr_n("\n", pr, client_data, 0); } cql_to_xml_mod(cn->u.st.modifiers, pr, client_data, level+4); pr_n("\n", pr, client_data, level+2); } if (cn->u.st.term) { pr_n("", pr, client_data, level+2); pr_cdata(cn->u.st.term, pr, client_data); pr_n("\n", pr, client_data, 0); } if (cn->u.st.extra_terms) { struct cql_node *n = cn->u.st.extra_terms; for (; n; n = n->u.st.extra_terms) { pr_n("", pr, client_data, level+2); pr_cdata(n->u.st.term, pr, client_data); pr_n("\n", pr, client_data, 0); } } cql_sort_to_xml(sort_node, pr, client_data, level+2); pr_n("\n", pr, client_data, level); break; case CQL_NODE_BOOL: pr_n("\n", pr, client_data, level); if (cn->u.boolean.value) { pr_n("\n", pr, client_data, level+2); pr_n("", pr, client_data, level+4); pr_cdata(cn->u.boolean.value, pr, client_data); pr_n("\n", pr, client_data, 0); cql_to_xml_mod(cn->u.boolean.modifiers, pr, client_data, level+4); pr_n("\n", pr, client_data, level+2); } if (cn->u.boolean.left) { printf ("%*s\n", level+2, ""); cql_to_xml_r(cn->u.boolean.left, pr, client_data, level+4, 0); printf ("%*s\n", level+2, ""); } if (cn->u.boolean.right) { printf ("%*s\n", level+2, ""); cql_to_xml_r(cn->u.boolean.right, pr, client_data, level+4, 0); printf ("%*s\n", level+2, ""); } cql_sort_to_xml(sort_node, pr, client_data, level+2); pr_n("\n", pr, client_data, level); break; case CQL_NODE_SORT: cql_to_xml_r(cn->u.sort.search, pr, client_data, level, cn); } } void cql_to_xml(struct cql_node *cn, void (*pr)(const char *buf, void *client_data), void *client_data) { cql_to_xml_r(cn, pr, client_data, 0, 0); } void cql_to_xml_stdio(struct cql_node *cn, FILE *f) { cql_to_xml(cn, cql_fputs, f); } void cql_buf_write_handler (const char *b, void *client_data) { struct cql_buf_write_info *info = (struct cql_buf_write_info *)client_data; int l = strlen(b); if (info->off < 0 || (info->off + l >= info->max)) { info->off = -1; return; } memcpy (info->buf + info->off, b, l); info->off += l; } int cql_to_xml_buf(struct cql_node *cn, char *out, int max) { struct cql_buf_write_info info; info.off = 0; info.max = max; info.buf = out; cql_to_xml(cn, cql_buf_write_handler, &info); if (info.off >= 0) info.buf[info.off] = '\0'; return info.off; } /* * Local variables: * c-basic-offset: 4 * c-file-style: "Stroustrup" * indent-tabs-mode: nil * End: * vim: shiftwidth=4 tabstop=8 expandtab */