00001
00002
00003
00004
00005
00011 #include <stdlib.h>
00012 #include <string.h>
00013 #include <stdio.h>
00014
00015 #include <yaz/cql.h>
00016
00017 static void pr_n(const char *buf,
00018 void (*pr)(const char *buf, void *client_data),
00019 void *client_data, int n)
00020 {
00021 int i;
00022 for (i = 0; i<n; i++)
00023 (*pr)(" ", client_data);
00024 (*pr)(buf, client_data);
00025 }
00026
00027 static void pr_cdata(const char *buf,
00028 void (*pr)(const char *buf, void *client_data),
00029 void *client_data)
00030 {
00031 const char *src = buf;
00032 char bf[2];
00033 while (*src)
00034 {
00035 switch(*src)
00036 {
00037 case '&':
00038 (*pr)("&", client_data);
00039 break;
00040 case '<':
00041 (*pr)("<", client_data);
00042 break;
00043 case '>':
00044 (*pr)(">", client_data);
00045 break;
00046 default:
00047 bf[0] = *src;
00048 bf[1] = 0;
00049 (*pr)(bf, client_data);
00050 }
00051 src++;
00052 }
00053 }
00054
00055 static void prefixes(struct cql_node *cn,
00056 void (*pr)(const char *buf, void *client_data),
00057 void *client_data, int level)
00058 {
00059 int head = 0;
00060 if (cn->u.st.index_uri)
00061 {
00062 pr_n("<prefixes>\n", pr, client_data, level);
00063 head = 1;
00064
00065 pr_n("<prefix>\n", pr, client_data, level+2);
00066 pr_n("<identifier>", pr, client_data, level+4);
00067 pr_cdata(cn->u.st.index_uri, pr, client_data);
00068 pr_n("</identifier>\n", pr, client_data, 0);
00069 pr_n("</prefix>\n", pr, client_data, level+2);
00070 }
00071 if (cn->u.st.relation_uri && cn->u.st.relation)
00072 {
00073 if (!head)
00074 pr_n("<prefixes>\n", pr, client_data, level);
00075 pr_n("<prefix>\n", pr, client_data, level+2);
00076 pr_n("<name>", pr, client_data, level+4);
00077 pr_cdata("rel", pr, client_data);
00078 pr_n("</name>\n", pr, client_data, 0);
00079 pr_n("<identifier>", pr, client_data, level+4);
00080 pr_cdata(cn->u.st.relation_uri, pr, client_data);
00081 pr_n("</identifier>\n", pr, client_data, 0);
00082 pr_n("</prefix>\n", pr, client_data, level+2);
00083 }
00084 if (head)
00085 pr_n("</prefixes>\n", pr, client_data, level);
00086 }
00087
00088 static void cql_to_xml_mod(struct cql_node *m,
00089 void (*pr)(const char *buf, void *client_data),
00090 void *client_data, int level)
00091 {
00092 if (m)
00093 {
00094 pr_n("<modifiers>\n", pr, client_data, level);
00095 for (; m; m = m->u.st.modifiers)
00096 {
00097 pr_n("<modifier>\n", pr, client_data, level+2);
00098 pr_n("<type>", pr, client_data, level+4);
00099 pr_cdata(m->u.st.index, pr, client_data);
00100 pr_n("</type>\n", pr, client_data, 0);
00101 if (m->u.st.relation)
00102 {
00103 pr_n("<comparison>", pr, client_data, level+4);
00104 pr_cdata(m->u.st.relation, pr, client_data);
00105 pr_n("</comparison>\n", pr, client_data, 0);
00106 }
00107 if (m->u.st.term)
00108 {
00109 pr_n("<value>", pr, client_data, level+4);
00110 pr_cdata(m->u.st.term, pr, client_data);
00111 pr_n("</value>\n", pr, client_data, 0);
00112 }
00113 pr_n("</modifier>\n", pr, client_data, level+2);
00114 }
00115 pr_n("</modifiers>\n", pr, client_data, level);
00116 }
00117 }
00118
00119 static void cql_to_xml_r(struct cql_node *cn,
00120 void (*pr)(const char *buf, void *client_data),
00121 void *client_data, int level)
00122 {
00123 if (!cn)
00124 return;
00125 switch (cn->which)
00126 {
00127 case CQL_NODE_ST:
00128 pr_n("<searchClause>\n", pr, client_data, level);
00129 prefixes(cn, pr, client_data, level+2);
00130 if (cn->u.st.index)
00131 {
00132 pr_n("<index>", pr, client_data, level+2);
00133 pr_cdata(cn->u.st.index, pr, client_data);
00134 pr_n("</index>\n", pr, client_data, 0);
00135 }
00136 if (cn->u.st.relation)
00137 {
00138 pr_n("<relation>\n", pr, client_data, level+2);
00139 pr_n("<value>", pr, client_data, level+4);
00140 if (cn->u.st.relation_uri)
00141 pr_cdata("rel.", pr, client_data);
00142 pr_cdata(cn->u.st.relation, pr, client_data);
00143 pr_n("</value>\n", pr, client_data, 0);
00144
00145 if (cn->u.st.relation_uri)
00146 {
00147 pr_n("<identifier>", pr, client_data, level+4);
00148 pr_cdata(cn->u.st.relation_uri, pr, client_data);
00149 pr_n("</identifier>\n", pr, client_data, 0);
00150 }
00151 cql_to_xml_mod(cn->u.st.modifiers,
00152 pr, client_data, level+4);
00153
00154 pr_n("</relation>\n", pr, client_data, level+2);
00155 }
00156 if (cn->u.st.term)
00157 {
00158 pr_n("<term>", pr, client_data, level+2);
00159 pr_cdata(cn->u.st.term, pr, client_data);
00160 pr_n("</term>\n", pr, client_data, 0);
00161 }
00162 if (cn->u.st.extra_terms)
00163 {
00164 struct cql_node *n = cn->u.st.extra_terms;
00165 for (; n; n = n->u.st.extra_terms)
00166 {
00167 pr_n("<term>", pr, client_data, level+2);
00168 pr_cdata(n->u.st.term, pr, client_data);
00169 pr_n("</term>\n", pr, client_data, 0);
00170 }
00171 }
00172 pr_n("</searchClause>\n", pr, client_data, level);
00173 break;
00174 case CQL_NODE_BOOL:
00175 pr_n("<triple>\n", pr, client_data, level);
00176 if (cn->u.boolean.value)
00177 {
00178 pr_n("<boolean>\n", pr, client_data, level+2);
00179
00180 pr_n("<value>", pr, client_data, level+4);
00181 pr_cdata(cn->u.boolean.value, pr, client_data);
00182 pr_n("</value>\n", pr, client_data, 0);
00183
00184 cql_to_xml_mod(cn->u.boolean.modifiers,
00185 pr, client_data, level+4);
00186
00187 pr_n("</boolean>\n", pr, client_data, level+2);
00188 }
00189 if (cn->u.boolean.left)
00190 {
00191 printf ("%*s<leftOperand>\n", level+2, "");
00192 cql_to_xml_r(cn->u.boolean.left, pr, client_data, level+4);
00193 printf ("%*s</leftOperand>\n", level+2, "");
00194 }
00195 if (cn->u.boolean.right)
00196 {
00197 printf ("%*s<rightOperand>\n", level+2, "");
00198 cql_to_xml_r(cn->u.boolean.right, pr, client_data, level+4);
00199 printf ("%*s</rightOperand>\n", level+2, "");
00200 }
00201 pr_n("</triple>\n", pr, client_data, level);
00202 }
00203 }
00204
00205 void cql_to_xml(struct cql_node *cn,
00206 void (*pr)(const char *buf, void *client_data),
00207 void *client_data)
00208 {
00209 cql_to_xml_r(cn, pr, client_data, 0);
00210 }
00211
00212 void cql_to_xml_stdio(struct cql_node *cn, FILE *f)
00213 {
00214 cql_to_xml(cn, cql_fputs, f);
00215 }
00216
00217 void cql_buf_write_handler (const char *b, void *client_data)
00218 {
00219 struct cql_buf_write_info *info = (struct cql_buf_write_info *)client_data;
00220 int l = strlen(b);
00221 if (info->off < 0 || (info->off + l >= info->max))
00222 {
00223 info->off = -1;
00224 return;
00225 }
00226 memcpy (info->buf + info->off, b, l);
00227 info->off += l;
00228 }
00229
00230 int cql_to_xml_buf(struct cql_node *cn, char *out, int max)
00231 {
00232 struct cql_buf_write_info info;
00233 info.off = 0;
00234 info.max = max;
00235 info.buf = out;
00236 cql_to_xml(cn, cql_buf_write_handler, &info);
00237 if (info.off >= 0)
00238 info.buf[info.off] = '\0';
00239 return info.off;
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250