Add wrbuf_sha1_puts
[yaz-moved-to-github.git] / src / cclxmlconfig.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
5 /** \file cclxmlconfig.c
6     \brief XML configuration for CCL
7 */
8 #if HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <assert.h>
15
16 #include <yaz/ccl_xml.h>
17
18 #if YAZ_HAVE_XML2
19
20 static int ccl_xml_config_combqual(WRBUF wrbuf,
21                                    const xmlNode *ptr,
22                                    const char **addinfo)
23 {
24     struct _xmlAttr *attr;
25     const char *name = 0;
26     for (attr = ptr->properties; attr; attr = attr->next)
27     {
28         if (!xmlStrcmp(attr->name, BAD_CAST "name") &&
29             attr->children && attr->children->type == XML_TEXT_NODE)
30             name = (const char *) attr->children->content;
31         else
32         {
33             *addinfo = "bad attribute for 'attr'. "
34                 "Expecting 'type', 'value', or 'attrset'";
35             return 1;
36         }
37     }
38     if (!name)
39     {
40         *addinfo = "missing attribute for 'name' for element 'qual'";
41         return 1;
42     }
43     wrbuf_printf(wrbuf, "%s", name);
44     return 0;
45
46
47 }
48
49 static int ccl_xml_config_attr(const char *default_set,
50                                WRBUF wrbuf,
51                                const xmlNode *ptr,
52                                const char **addinfo)
53 {
54     struct _xmlAttr *attr;
55     const char *type = 0;
56     const char *value = 0;
57     const char *attrset = default_set;
58     for (attr = ptr->properties; attr; attr = attr->next)
59     {
60         if (!xmlStrcmp(attr->name, BAD_CAST "type") &&
61             attr->children && attr->children->type == XML_TEXT_NODE)
62             type = (const char *) attr->children->content;
63         else if (!xmlStrcmp(attr->name, BAD_CAST "value") &&
64             attr->children && attr->children->type == XML_TEXT_NODE)
65             value = (const char *) attr->children->content;
66         else if (!xmlStrcmp(attr->name, BAD_CAST "attrset") &&
67             attr->children && attr->children->type == XML_TEXT_NODE)
68             attrset = (const char *) attr->children->content;
69         else
70         {
71             *addinfo = "bad attribute for 'attr'. "
72                 "Expecting 'type', 'value', or 'attrset'";
73             return 1;
74         }
75     }
76     if (!type)
77     {
78         *addinfo = "missing attribute for 'type' for element 'attr'";
79         return 1;
80     }
81     if (!value)
82     {
83         *addinfo = "missing attribute for 'value' for element 'attr'";
84         return 1;
85     }
86     if (attrset)
87         wrbuf_printf(wrbuf, "%s,%s=%s", attrset, type, value);
88     else
89         wrbuf_printf(wrbuf, "%s=%s", type, value);
90     return 0;
91 }
92
93 static int ccl_xml_config_qual(CCL_bibset bibset, const char *default_set,
94                                WRBUF wrbuf,
95                                const xmlNode *ptr,
96                                const char **addinfo)
97 {
98     struct _xmlAttr *attr;
99     const char *name = 0;
100     const xmlNode *a_ptr = ptr->children;
101     for (attr = ptr->properties; attr; attr = attr->next)
102     {
103         if (!xmlStrcmp(attr->name, BAD_CAST "name") &&
104             attr->children && attr->children->type == XML_TEXT_NODE)
105             name = (const char *) attr->children->content;
106         else
107         {
108             *addinfo = "bad attribute for 'qual'. Expecting 'name' only";
109             return 1;
110         }
111     }
112     if (!name)
113     {
114         *addinfo = "missing attribute 'name' for 'qual' element";
115         return 1;
116     }
117     for (; a_ptr; a_ptr = a_ptr->next)
118     {
119         if (a_ptr->type == XML_ELEMENT_NODE)
120         {
121             if (!xmlStrcmp(a_ptr->name, BAD_CAST "attr"))
122             {
123                 int r = ccl_xml_config_attr(default_set, wrbuf,
124                                             a_ptr, addinfo);
125                 if (r)
126                     return r;
127                 wrbuf_printf(wrbuf, " ");
128             }
129             else if (!xmlStrcmp(a_ptr->name, BAD_CAST "qual"))
130             {
131                 int r = ccl_xml_config_combqual(wrbuf, a_ptr, addinfo);
132                 if (r)
133                     return r;
134                 wrbuf_printf(wrbuf, " ");
135             }
136             else
137             {
138                 *addinfo = "bad element: expecting 'attr'";
139                 return 1;
140             }
141         }
142     }
143     ccl_qual_fitem(bibset, wrbuf_cstr(wrbuf), name);
144     return 0;
145 }
146
147 int ccl_xml_config_directive(CCL_bibset bibset, const xmlNode *ptr,
148                              const char **addinfo)
149 {
150     struct _xmlAttr *attr;
151     const char *name = 0;
152     const char *value = 0;
153     for (attr = ptr->properties; attr; attr = attr->next)
154     {
155         if (!xmlStrcmp(attr->name, BAD_CAST "name") &&
156             attr->children && attr->children->type == XML_TEXT_NODE)
157             name = (const char *) attr->children->content;
158         else if (!xmlStrcmp(attr->name, BAD_CAST "value") &&
159             attr->children && attr->children->type == XML_TEXT_NODE)
160             value = (const char *) attr->children->content;
161         else
162         {
163             *addinfo = "bad attribute for 'diretive'. "
164                 "Expecting 'name' or 'value'";
165             return 1;
166         }
167     }
168     if (!name)
169     {
170         *addinfo = "missing attribute 'name' for 'directive' element";
171         return 1;
172     }
173     if (!value)
174     {
175         *addinfo = "missing attribute 'name' for 'value' element";
176         return 1;
177     }
178     ccl_qual_add_special(bibset, name, value);
179     return 0;
180 }
181
182 int ccl_xml_config(CCL_bibset bibset, const xmlNode *ptr, const char **addinfo)
183 {
184     if (ptr && ptr->type == XML_ELEMENT_NODE &&
185         !xmlStrcmp(ptr->name, BAD_CAST "cclmap"))
186     {
187         const xmlNode *c_ptr;
188         const char *set = 0;
189         struct _xmlAttr *attr;
190         for (attr = ptr->properties; attr; attr = attr->next)
191         {
192             if (!xmlStrcmp(attr->name, BAD_CAST "defaultattrset") &&
193                 attr->children && attr->children->type == XML_TEXT_NODE)
194                 set = (const char *) attr->children->content;
195             else
196             {
197                 *addinfo = "bad attribute for 'cclmap'. "
198                     "expecting 'defaultattrset'";
199                 return 1;
200             }
201         }
202         for (c_ptr = ptr->children; c_ptr; c_ptr = c_ptr->next)
203         {
204             if (c_ptr->type == XML_ELEMENT_NODE)
205             {
206                 if (!xmlStrcmp(c_ptr->name, BAD_CAST "qual"))
207                 {
208                     WRBUF wrbuf = wrbuf_alloc();
209                     int r = ccl_xml_config_qual(bibset, set,
210                                                 wrbuf, c_ptr, addinfo);
211                     wrbuf_destroy(wrbuf);
212                     if (r)
213                         return r;
214                 }
215                 else if (!xmlStrcmp(c_ptr->name, BAD_CAST "directive"))
216                 {
217                     int r = ccl_xml_config_directive(bibset, c_ptr, addinfo);
218                     if (r)
219                         return r;
220                 }
221                 else
222                 {
223                     *addinfo = "bad element for 'cclmap'. "
224                         "expecting 'directive' or 'qual'";
225                     return 1;
226                 }
227             }
228         }
229     }
230     return 0;
231 }
232 #endif
233
234 /*
235  * Local variables:
236  * c-basic-offset: 4
237  * c-file-style: "Stroustrup"
238  * indent-tabs-mode: nil
239  * End:
240  * vim: shiftwidth=4 tabstop=8 expandtab
241  */
242