1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 1995-2013 Index Data
3 * See the file LICENSE for details.
7 \brief XML Include (not to be confused with W3C XInclude)
13 #include <sys/types.h>
18 #include <yaz/wrbuf.h>
19 #include <yaz/tpath.h>
21 #include <yaz/xml_include.h>
25 #include <libxml/parser.h>
26 #include <libxml/tree.h>
28 struct yaz_xml_include_s {
33 typedef struct yaz_xml_include_s *yaz_xml_include_t;
35 static int process_config_includes(yaz_xml_include_t config, xmlNode *n);
37 static void conf_dir_path(yaz_xml_include_t config, WRBUF w, const char *src)
39 if (config->confdir && *config->confdir > 0 &&
42 wrbuf_printf(w, "%s/%s", config->confdir, src);
48 static int config_include_one(yaz_xml_include_t config, xmlNode **sib,
52 if (stat(path, &st) < 0)
54 yaz_log(YLOG_FATAL|YLOG_ERRNO, "stat %s", path);
59 if ((st.st_mode & S_IFMT) == S_IFREG)
61 xmlDoc *doc = xmlParseFile(path);
64 xmlNodePtr t = xmlDocGetRootElement(doc);
65 int ret = process_config_includes(config, t);
66 *sib = xmlAddNextSibling(*sib, xmlCopyNode(t, 1));
73 yaz_log(YLOG_FATAL, "Could not parse %s", path);
81 static int config_include_src(yaz_xml_include_t config, xmlNode **np,
84 int ret = 0; /* return code. OK so far */
85 WRBUF w = wrbuf_alloc();
86 xmlNodePtr sib; /* our sibling that we append */
87 xmlNodePtr c; /* tmp node */
89 wrbuf_printf(w, " begin include src=\"%s\" ", src);
91 /* replace include element with a 'begin' comment */
92 sib = xmlNewComment((const xmlChar *) wrbuf_cstr(w));
93 xmlReplaceNode(*np, sib);
98 conf_dir_path(config, w, src);
101 yaz_glob_res_t glob_res;
103 glob_ret = yaz_file_glob2(wrbuf_cstr(w), &glob_res, config->glob_flags);
104 yaz_log(YLOG_LOG, "yaz_file_glob returned w=%s %d", wrbuf_cstr(w),
110 for (i = 0; (path = yaz_file_glob_get_file(glob_res, i)); i++)
111 ret = config_include_one(config, &sib, path);
112 yaz_file_globfree(&glob_res);
116 wrbuf_printf(w, " end include src=\"%s\" ", src);
117 c = xmlNewComment((const xmlChar *) wrbuf_cstr(w));
118 sib = xmlAddNextSibling(sib, c);
125 static int process_config_includes(yaz_xml_include_t config, xmlNode *n)
127 for (n = n->children; n; n = n->next)
129 if (n->type == XML_ELEMENT_NODE)
131 if (!strcmp((const char *) n->name, "include"))
133 xmlChar *src = xmlGetProp(n, (xmlChar *) "src");
136 int ret = config_include_src(config, &n,
146 if (process_config_includes(config, n))
154 int yaz_xml_include_glob(xmlNode *n, const char *base_path,
157 struct yaz_xml_include_s s;
159 s.confdir = base_path;
160 s.glob_flags = glob_flags;
161 return process_config_includes(&s, n);
164 int yaz_xml_include_simple(xmlNode *n, const char *base_path)
166 return yaz_xml_include_glob(n, base_path, 0);
176 * c-file-style: "Stroustrup"
177 * indent-tabs-mode: nil
179 * vim: shiftwidth=4 tabstop=8 expandtab