add part of xinclude/xpointer
This commit is contained in:
parent
8654e7ad07
commit
d0379fc869
6 changed files with 167 additions and 14 deletions
2
Makefile
2
Makefile
|
|
@ -3,7 +3,7 @@ CFLAGS = -I include -fPIC -g
|
|||
LDFLAGS = -shared
|
||||
LIBS =
|
||||
|
||||
OBJS = src/core.o src/file.o src/unicode.o src/util.o src/array.o src/xpointer.o
|
||||
OBJS = src/core.o src/file.o src/unicode.o src/util.o src/array.o src/xpointer.o src/xinclude.o
|
||||
|
||||
SO = .so
|
||||
|
||||
|
|
|
|||
|
|
@ -49,8 +49,9 @@ int main(int argc, char** argv) {
|
|||
xl_node_t* n;
|
||||
|
||||
for(i = 1; i < argc; i++) {
|
||||
xemil_t* h = xl_open_file(argv[i]);
|
||||
h->new_text = 1;
|
||||
xemil_t* h = xl_open_file(argv[i]);
|
||||
h->new_text = 1;
|
||||
h->do_xinclude = 1;
|
||||
if(h != NULL) {
|
||||
printf("%s:\n", argv[i]);
|
||||
if(xl_parse(h)) {
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ struct xemil {
|
|||
void* drv_opaque;
|
||||
void* drv_arg;
|
||||
int new_text;
|
||||
int do_xinclude;
|
||||
char* path;
|
||||
xl_node_t* pre;
|
||||
xl_node_t* root;
|
||||
};
|
||||
|
|
@ -66,6 +68,7 @@ struct xemil {
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* clang-format off */
|
||||
#define XL_MERGE(target, source) \
|
||||
{ \
|
||||
xl_node_t** target##_old = target; \
|
||||
|
|
@ -109,19 +112,19 @@ extern "C" {
|
|||
xl_node_t* scanned_node = r[j];
|
||||
|
||||
#define XL_LIST_END \
|
||||
if(nodes != NULL) { \
|
||||
XL_MERGE(new, nodes); \
|
||||
if(nodes != NULL) { \
|
||||
XL_MERGE(new, nodes); \
|
||||
\
|
||||
free(nodes); \
|
||||
} \
|
||||
} \
|
||||
free(r); \
|
||||
r = new; \
|
||||
free(nodes); \
|
||||
} \
|
||||
} \
|
||||
free(r); \
|
||||
r = new; \
|
||||
\
|
||||
s = i + 1; \
|
||||
s = i + 1; \
|
||||
\
|
||||
if(old == 0) break; \
|
||||
} \
|
||||
if(old == 0) break; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
if(r[0] == NULL) { \
|
||||
|
|
@ -130,12 +133,15 @@ extern "C" {
|
|||
} \
|
||||
\
|
||||
return r;
|
||||
/* clang-format on */
|
||||
|
||||
/* core.c */
|
||||
XLDECL xemil_t* xl_open(xl_driver_t* driver, void* arg);
|
||||
XLDECL int xl_parse(xemil_t* handle);
|
||||
XLDECL void xl_close(xemil_t* handle);
|
||||
XLDECL char* xl_get_attribute(xl_node_t* node, const char* key);
|
||||
XLDECL void xl_free(xl_node_t* node);
|
||||
XLDECL void xl_replace(xl_node_t* node, xl_node_t* new);
|
||||
|
||||
XLDECL xl_node_t** xl_get_nodes(xl_node_t* node, const char* name); /* NULL-terminated */
|
||||
XLDECL xl_node_t** xl_get_path(xl_node_t* node, const char* path); /* NULL-terminated */
|
||||
|
|
@ -165,6 +171,9 @@ XLDECL void xl_array_free(int** array);
|
|||
/* xpointer.c */
|
||||
xl_node_t** xl_xpointer(xl_node_t* node, const char* path);
|
||||
|
||||
/* xinclude.c */
|
||||
void xl_xinclude_scan(xemil_t* handle, xl_node_t* node);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
83
src/core.c
83
src/core.c
|
|
@ -10,7 +10,10 @@ xemil_t* xl_open(xl_driver_t* driver, void* arg) {
|
|||
handle->pre = NULL;
|
||||
handle->root = NULL;
|
||||
|
||||
handle->new_text = 0;
|
||||
handle->path = NULL;
|
||||
|
||||
handle->new_text = 0;
|
||||
handle->do_xinclude = 0;
|
||||
|
||||
if(!handle->driver->open(handle)) {
|
||||
free(handle);
|
||||
|
|
@ -560,6 +563,10 @@ int xl_parse(xemil_t* handle) {
|
|||
|
||||
CLEANUP;
|
||||
|
||||
if(handle->do_xinclude) {
|
||||
xl_xinclude_scan(handle, handle->root);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -589,8 +596,82 @@ static void recursive_free(xl_node_t* node) {
|
|||
free(node);
|
||||
}
|
||||
|
||||
void xl_free(xl_node_t* node) {
|
||||
xl_node_t* parent = node->parent;
|
||||
xl_node_t* child;
|
||||
|
||||
child = parent->first_child;
|
||||
if(child != NULL && child == node) {
|
||||
parent->first_child = child->next;
|
||||
if(child->next != NULL) child->next->prev = NULL;
|
||||
child = child->next;
|
||||
}
|
||||
|
||||
while(child != NULL) {
|
||||
xl_node_t* next = child->next;
|
||||
|
||||
if(child == node) {
|
||||
if(child->prev != NULL) child->prev->next = child->next;
|
||||
if(child->next != NULL) child->next->prev = child->prev;
|
||||
}
|
||||
|
||||
child = next;
|
||||
}
|
||||
|
||||
recursive_free(node);
|
||||
}
|
||||
|
||||
void xl_replace(xl_node_t* node, xl_node_t* new) {
|
||||
xl_node_t* parent = node->parent;
|
||||
xl_node_t* child;
|
||||
|
||||
if(new->parent != NULL&& new->parent->first_child == new) {
|
||||
new->parent->first_child = new->next;
|
||||
if(new->next->prev != NULL) new->next->prev = NULL;
|
||||
}
|
||||
if(new->parent != NULL) {
|
||||
child = new->parent->first_child;
|
||||
|
||||
while(child != NULL) {
|
||||
if(child == new) {
|
||||
if(child->prev != NULL) child->prev->next = child->next;
|
||||
if(child->next != NULL) child->next->prev = child->prev;
|
||||
}
|
||||
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
|
||||
child = parent->first_child;
|
||||
if(child != NULL && child == node) {
|
||||
parent->first_child = new;
|
||||
|
||||
new->parent = parent;
|
||||
new->prev = NULL;
|
||||
new->next = child->next;
|
||||
|
||||
child = child->next;
|
||||
}
|
||||
|
||||
while(child != NULL) {
|
||||
if(child == node) {
|
||||
new->parent = parent;
|
||||
new->next = child->next;
|
||||
new->prev = child->prev;
|
||||
|
||||
if(child->prev != NULL) child->prev->next = new;
|
||||
if(child->next != NULL) child->next->prev = new;
|
||||
}
|
||||
|
||||
child = child->next;
|
||||
}
|
||||
|
||||
recursive_free(node);
|
||||
}
|
||||
|
||||
void xl_close(xemil_t* handle) {
|
||||
if(handle->root != NULL) recursive_free(handle->root);
|
||||
if(handle->path != NULL) free(handle->path);
|
||||
|
||||
handle->driver->close(handle);
|
||||
free(handle);
|
||||
|
|
|
|||
11
src/file.c
11
src/file.c
|
|
@ -1,8 +1,19 @@
|
|||
#include <xemil.h>
|
||||
|
||||
static int xl_driver_file_open(xemil_t* handle) {
|
||||
char* s;
|
||||
|
||||
if((handle->drv_opaque = fopen(handle->drv_arg, "rb")) == NULL) return 0;
|
||||
|
||||
handle->path = xl_util_strdup(handle->drv_arg);
|
||||
|
||||
if((s = strrchr(handle->path, '/')) == NULL) {
|
||||
free(handle->path);
|
||||
handle->path = xl_util_strdup("./");
|
||||
} else {
|
||||
s[1] = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
51
src/xinclude.c
Normal file
51
src/xinclude.c
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include <xemil.h>
|
||||
|
||||
void xl_xinclude_scan(xemil_t* handle, xl_node_t* node) {
|
||||
xl_node_t* child;
|
||||
|
||||
if(node->type == XL_NODE_NODE && node->name != NULL && strcmp(node->name, "xi:include") == 0) {
|
||||
char* href = xl_get_attribute(node, "href");
|
||||
char* parse = xl_get_attribute(node, "parse");
|
||||
char* xpointer = xl_get_attribute(node, "xpointer");
|
||||
|
||||
if(href != NULL) {
|
||||
xemil_t* new;
|
||||
|
||||
if(handle->path == NULL) {
|
||||
href = xl_util_strdup(href);
|
||||
} else {
|
||||
href = xl_util_strvacat(handle->path, href, NULL);
|
||||
}
|
||||
|
||||
if(parse == NULL) parse = "xml";
|
||||
if(xpointer == NULL) xpointer = "element(/)";
|
||||
|
||||
if((new = xl_open_file(href)) != NULL) {
|
||||
new->do_xinclude = 1;
|
||||
new->new_text = handle->new_text;
|
||||
if(xl_parse(new) && new->root != NULL) {
|
||||
xl_node_t** nodes;
|
||||
if((nodes = xl_xpointer(new->root, xpointer)) != NULL) {
|
||||
xl_replace(node, nodes[0]);
|
||||
|
||||
if(nodes[0] == new->root) new->root = NULL;
|
||||
|
||||
free(nodes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(new != NULL) xl_close(new);
|
||||
|
||||
free(href);
|
||||
}
|
||||
}
|
||||
|
||||
child = node->first_child;
|
||||
|
||||
while(child != NULL) {
|
||||
xl_xinclude_scan(handle, child);
|
||||
|
||||
child = child->next;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue