1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) 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);
108 for (i = 0; (path = yaz_file_glob_get_file(glob_res, i)); i++)
109 ret = config_include_one(config, &sib, path);
110 yaz_file_globfree(&glob_res);
114 wrbuf_printf(w, " end include src=\"%s\" ", src);
115 c = xmlNewComment((const xmlChar *) wrbuf_cstr(w));
116 sib = xmlAddNextSibling(sib, c);
123 static int process_config_includes(yaz_xml_include_t config, xmlNode *n)
125 for (n = n->children; n; n = n->next)
127 if (n->type == XML_ELEMENT_NODE)
129 if (!strcmp((const char *) n->name, "include"))
131 xmlChar *src = xmlGetProp(n, (xmlChar *) "src");
134 int ret = config_include_src(config, &n,
144 if (process_config_includes(config, n))
152 int yaz_xml_include_glob(xmlNode *n, const char *base_path,
155 struct yaz_xml_include_s s;
157 s.confdir = base_path;
158 s.glob_flags = glob_flags;
159 return process_config_includes(&s, n);
162 int yaz_xml_include_simple(xmlNode *n, const char *base_path)
164 return yaz_xml_include_glob(n, base_path, 0);
174 * c-file-style: "Stroustrup"
175 * indent-tabs-mode: nil
177 * vim: shiftwidth=4 tabstop=8 expandtab