Extend MARC-8 to handle ESC-G0 EACC. Fix conversion order for MARCXML
[yaz-moved-to-github.git] / src / cqlutil.c
1 /* $Id: cqlutil.c,v 1.3 2004-03-15 21:39:06 adam Exp $
2    Copyright (C) 2002-2004
3    Index Data Aps
4
5 This file is part of the YAZ toolkit.
6
7 See the file LICENSE.
8 */
9
10 #include <stdlib.h>
11 #include <string.h>
12
13 #include <yaz/xmalloc.h>
14 #include <yaz/cql.h>
15
16 void cql_fputs(const char *buf, void *client_data)
17 {
18     FILE *f = (FILE *) client_data;
19     fputs(buf, f);
20 }
21
22 struct cql_node *cql_node_dup (struct cql_node *cp)
23 {
24     struct cql_node *cn = 0;
25
26     if (!cp)
27         return 0;
28     switch (cp->which)
29     {
30     case CQL_NODE_ST:
31         cn = cql_node_mk_sc(cp->u.st.index,
32                             cp->u.st.relation,
33                             cp->u.st.term);
34         cn->u.st.modifiers = cql_node_dup(cp->u.st.modifiers);
35         cn->u.st.index_uri = cp->u.st.index_uri ? 
36             xstrdup(cp->u.st.index_uri) : 0;
37         cn->u.st.relation_uri = cp->u.st.relation_uri ?
38             xstrdup(cp->u.st.relation_uri) : 0;
39         break;
40     case CQL_NODE_BOOL:
41         cn = cql_node_mk_boolean(cp->u.boolean.value);
42         cn->u.boolean.left = cql_node_dup(cp->u.boolean.left);
43         cn->u.boolean.right = cql_node_dup(cp->u.boolean.right);
44     }
45     return cn;
46 }
47
48 struct cql_node *cql_node_mk_sc(const char *index,
49                                 const char *relation,
50                                 const char *term)
51 {
52     struct cql_node *p = (struct cql_node *) xmalloc(sizeof(*p));
53     p->which = CQL_NODE_ST;
54     p->u.st.index = 0;
55     if (index)
56         p->u.st.index = xstrdup(index);
57     p->u.st.index_uri = 0;
58     p->u.st.term = 0;
59     if (term)
60         p->u.st.term = xstrdup(term);
61     p->u.st.relation = 0;
62     if (relation)
63         p->u.st.relation = xstrdup(relation);
64     p->u.st.relation_uri = 0;
65     p->u.st.modifiers = 0;
66     return p;
67 }
68
69 struct cql_node *cql_node_mk_boolean(const char *op)
70 {
71     struct cql_node *p = (struct cql_node *) xmalloc(sizeof(*p));
72     p->which = CQL_NODE_BOOL;
73     p->u.boolean.value = 0;
74     if (op)
75         p->u.boolean.value = xstrdup(op);
76     p->u.boolean.left = 0;
77     p->u.boolean.right = 0;
78     p->u.boolean.modifiers = 0;
79     return p;
80 }
81
82 const char *cql_uri()
83 {
84     return "info:srw/cql-context-set/1/cql-v1.1";
85 }
86
87 struct cql_node *cql_apply_prefix(struct cql_node *n, const char *prefix,
88                                   const char *uri)
89 {
90     if (n->which == CQL_NODE_ST)
91     {
92         if (!n->u.st.index_uri && n->u.st.index)
93         {   /* not yet resolved.. */
94             const char *cp = strchr(n->u.st.index, '.');
95             if (prefix && cp && strlen(prefix) == cp - n->u.st.index &&
96                 !memcmp(n->u.st.index, prefix, strlen(prefix)))
97             {
98                 char *nval = xstrdup(cp+1);
99                 n->u.st.index_uri = xstrdup(uri);
100                 xfree (n->u.st.index);
101                 n->u.st.index = nval;
102             }
103             else if (!prefix && !cp)
104             {
105                 n->u.st.index_uri = xstrdup(uri);
106             }
107         }
108         if (!n->u.st.relation_uri && n->u.st.relation)
109         {
110             const char *cp = strchr(n->u.st.relation, '.');
111             if (prefix && cp && strlen(prefix) == cp - n->u.st.relation &&
112                 !memcmp(n->u.st.relation, prefix, strlen(prefix)))
113             {
114                 char *nval = xstrdup(cp+1);
115                 n->u.st.relation_uri = xstrdup(uri);
116                 xfree (n->u.st.relation);
117                 n->u.st.relation = nval;
118             }
119         }
120     }
121     else if (n->which == CQL_NODE_BOOL)
122     {
123         cql_apply_prefix(n->u.boolean.left, prefix, uri);
124         cql_apply_prefix(n->u.boolean.right, prefix, uri);
125     }
126     return n;
127 }
128
129 void cql_node_destroy(struct cql_node *cn)
130 {
131     if (!cn)
132         return;
133     switch (cn->which)
134     {
135     case CQL_NODE_ST:
136         xfree (cn->u.st.index);
137         xfree (cn->u.st.relation);
138         xfree (cn->u.st.term);
139         xfree (cn->u.st.index_uri);
140         xfree (cn->u.st.relation_uri);
141         cql_node_destroy(cn->u.st.modifiers);
142         break;
143     case CQL_NODE_BOOL:
144         xfree (cn->u.boolean.value);
145         cql_node_destroy(cn->u.boolean.left);
146         cql_node_destroy(cn->u.boolean.right);
147         cql_node_destroy(cn->u.boolean.modifiers);
148     }
149     xfree (cn);
150 }