1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2010 Index Data
3 * See the file LICENSE for details.
7 \brief XML Include (not to be confused with W3C XInclude)
14 #define USE_POSIX_GLOB 1
16 #define USE_POSIX_GLOB 0
23 #include <sys/types.h>
28 #include <yaz/wrbuf.h>
29 #include <yaz/tpath.h>
31 #include <yaz/xml_include.h>
35 #include <libxml/parser.h>
36 #include <libxml/tree.h>
38 struct yaz_xml_include_s {
42 typedef struct yaz_xml_include_s *yaz_xml_include_t;
44 static int process_config_includes(yaz_xml_include_t config, xmlNode *n);
46 static void conf_dir_path(yaz_xml_include_t config, WRBUF w, const char *src)
48 if (config->confdir && *config->confdir > 0 &&
51 wrbuf_printf(w, "%s/%s", config->confdir, src);
57 static int config_include_one(yaz_xml_include_t config, xmlNode **sib,
61 if (stat(path, &st) < 0)
63 yaz_log(YLOG_FATAL|YLOG_ERRNO, "stat %s", path);
68 if ((st.st_mode & S_IFMT) == S_IFREG)
70 xmlDoc *doc = xmlParseFile(path);
73 xmlNodePtr t = xmlDocGetRootElement(doc);
74 int ret = process_config_includes(config, t);
75 *sib = xmlAddNextSibling(*sib, xmlCopyNode(t, 1));
82 yaz_log(YLOG_FATAL, "Could not parse %s", path);
90 static int config_include_src(yaz_xml_include_t config, xmlNode **np,
93 int ret = 0; /* return code. OK so far */
94 WRBUF w = wrbuf_alloc();
95 xmlNodePtr sib; /* our sibling that we append */
96 xmlNodePtr c; /* tmp node */
98 wrbuf_printf(w, " begin include src=\"%s\" ", src);
100 /* replace include element with a 'begin' comment */
101 sib = xmlNewComment((const xmlChar *) wrbuf_cstr(w));
102 xmlReplaceNode(*np, sib);
107 conf_dir_path(config, w, src);
112 glob(wrbuf_cstr(w), 0 /* flags */, 0 /* errfunc */, &glob_res);
114 for (i = 0; ret == 0 && i < glob_res.gl_pathc; i++)
116 const char *path = glob_res.gl_pathv[i];
117 ret = config_include_one(config, &sib, path);
122 ret = config_include_one(config, &sib, wrbuf_cstr(w));
125 wrbuf_printf(w, " end include src=\"%s\" ", src);
126 c = xmlNewComment((const xmlChar *) wrbuf_cstr(w));
127 sib = xmlAddNextSibling(sib, c);
134 static int process_config_includes(yaz_xml_include_t config, xmlNode *n)
136 for (; n; n = n->next)
138 if (n->type == XML_ELEMENT_NODE)
140 if (!strcmp((const char *) n->name, "include"))
142 xmlChar *src = xmlGetProp(n, (xmlChar *) "src");
145 int ret = config_include_src(config, &n,
155 if (process_config_includes(config, n->children))
163 int yaz_xml_include_simple(xmlNode *n, const char *base_path)
165 struct yaz_xml_include_s s;
167 s.confdir = base_path;
168 process_config_includes(&s, n);
178 * c-file-style: "Stroustrup"
179 * indent-tabs-mode: nil
181 * vim: shiftwidth=4 tabstop=8 expandtab