From 8654e7ad07f23c8cf4aeb6ba52997b55da96d513 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Mon, 9 Mar 2026 22:09:30 +0900 Subject: [PATCH] wip xpointer --- Makefile | 2 +- example.c | 6 ++-- include/xemil.h | 70 +++++++++++++++++++++++++++++++++++++++++++ src/core.c | 55 ++-------------------------------- src/util.c | 9 ++++++ src/xpointer.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 166 insertions(+), 56 deletions(-) create mode 100644 src/xpointer.c diff --git a/Makefile b/Makefile index d004580..5e01160 100644 --- a/Makefile +++ b/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 +OBJS = src/core.o src/file.o src/unicode.o src/util.o src/array.o src/xpointer.o SO = .so diff --git a/example.c b/example.c index 41aaa1d..c182f00 100644 --- a/example.c +++ b/example.c @@ -59,14 +59,14 @@ int main(int argc, char** argv) { n = h->pre; if(n != NULL) { while(n != NULL) { - // recursive(h, n, INDENT); + /* recursive(h, n, INDENT); */ n = n->next; } } - /* f(h->root != NULL) recursive(h, h->root, INDENT); */ + /* if(h->root != NULL) recursive(h, h->root, INDENT); */ - r = xl_get_path(h->root, "book.title"); + r = xl_xpointer(h->root, "element(/book/title)"); /* check if book.title dosent exist to prevent SEGFAULT */ if(r != NULL) { diff --git a/include/xemil.h b/include/xemil.h index 78bed76..36f4b90 100644 --- a/include/xemil.h +++ b/include/xemil.h @@ -6,6 +6,7 @@ #include #include #include +#include #define XLDECL extern @@ -65,6 +66,71 @@ struct xemil { extern "C" { #endif +#define XL_MERGE(target, source) \ + { \ + xl_node_t** target##_old = target; \ + int target##_k, target##_l; \ + int target##_len = 0; \ +\ + for(target##_k = 0; target##_old[target##_k] != NULL; target##_k++) target##_len++; \ + for(target##_k = 0; source[target##_k] != NULL; target##_k++) target##_len++; \ +\ + target = malloc(sizeof(*target) * (target##_len + 1)); \ + target[target##_len] = NULL; \ +\ + for(target##_k = 0; target##_old[target##_k] != NULL; target##_k++) target[target##_k] = target##_old[target##_k]; \ + for(target##_l = 0; source[target##_l] != NULL; target##_l++) target[target##_k + target##_l] = source[target##_l]; \ +\ + free(target##_old); \ + } + +#define XL_LIST_BEGIN(x) \ + xl_node_t** r = malloc(sizeof(*r) * 2); \ + char* p = xl_util_strdup(path); \ + int i; \ + int s = 0; \ +\ + r[0] = node; \ + r[1] = NULL; \ +\ + for(i = 0;; i++) { \ + if(p[i] == x || p[i] == 0) { \ + char old = p[i]; \ + int j; \ + xl_node_t** new = malloc(sizeof(*new)); \ + char* token = p + s; \ +\ + new[0] = NULL; \ +\ + p[i] = 0; \ +\ + for(j = 0; r[j] != NULL; j++) { \ + xl_node_t** nodes = NULL; \ + xl_node_t* scanned_node = r[j]; + +#define XL_LIST_END \ + if(nodes != NULL) { \ + XL_MERGE(new, nodes); \ +\ + free(nodes); \ + } \ + } \ + free(r); \ + r = new; \ +\ + s = i + 1; \ +\ + if(old == 0) break; \ + } \ + } \ +\ + if(r[0] == NULL) { \ + free(r); \ + r = NULL; \ + } \ +\ + return r; + /* core.c */ XLDECL xemil_t* xl_open(xl_driver_t* driver, void* arg); XLDECL int xl_parse(xemil_t* handle); @@ -83,6 +149,7 @@ XLDECL xemil_t* xl_open_file(const char* filename); XLDECL char* xl_util_trim(const char* str); XLDECL char* xl_util_strdup(const char* str); XLDECL char* xl_util_strvacat(const char* str, ...); +XLDECL int xl_util_is_integer(const char* str); /* unicode.c */ XLDECL int xl_unicode_count(unsigned char c); @@ -95,6 +162,9 @@ XLDECL int xl_array_length(int** array); XLDECL void xl_array_pop(int** array); XLDECL void xl_array_free(int** array); +/* xpointer.c */ +xl_node_t** xl_xpointer(xl_node_t* node, const char* path); + #ifdef __cplusplus } #endif diff --git a/src/core.c b/src/core.c index b14e1b7..e0f2afc 100644 --- a/src/core.c +++ b/src/core.c @@ -641,58 +641,9 @@ xl_node_t** xl_get_nodes(xl_node_t* node, const char* name) { } xl_node_t** xl_get_path(xl_node_t* node, const char* path) { - xl_node_t** r = malloc(sizeof(*r) * 2); - char* p = xl_util_strdup(path); - int i; - int s = 0; + XL_LIST_BEGIN('.'); - r[0] = node; - r[1] = NULL; + nodes = xl_get_nodes(scanned_node, token); - for(i = 0;; i++) { - if(p[i] == '.' || p[i] == 0) { - char old = p[i]; - int j; - xl_node_t** new = malloc(sizeof(*new)); - - new[0] = NULL; - - p[i] = 0; - - for(j = 0; r[j] != NULL; j++) { - xl_node_t** nodes = xl_get_nodes(r[j], p + s); - if(nodes != NULL) { - xl_node_t** old = new; - int k, l; - int len = 0; - - for(k = 0; old[k] != NULL; k++) len++; - for(k = 0; nodes[k] != NULL; k++) len++; - - new = malloc(sizeof(*new) * (len + 1)); - new[len] = NULL; - - for(k = 0; old[k] != NULL; k++) new[k] = old[k]; - for(l = 0; nodes[l] != NULL; l++) new[k + l] = nodes[l]; - - free(old); - - free(nodes); - } - } - free(r); - r = new; - - s = i + 1; - - if(old == 0) break; - } - } - - if(r[0] == NULL) { - free(r); - r = NULL; - } - - return r; + XL_LIST_END; } diff --git a/src/util.c b/src/util.c index fa55c08..194f820 100644 --- a/src/util.c +++ b/src/util.c @@ -103,3 +103,12 @@ char* xl_util_strvacat(const char* str, ...) { return r; } + +int xl_util_is_integer(const char* str) { + char* ep; + + strtol(str, &ep, 10); + if(ep == str || *ep != 0 || errno) return 0; + + return 1; +} diff --git a/src/xpointer.c b/src/xpointer.c new file mode 100644 index 0000000..2813d1b --- /dev/null +++ b/src/xpointer.c @@ -0,0 +1,80 @@ +#include + +static xl_node_t** xl_xpointer_element(xl_node_t* node, const char* path) { + XL_LIST_BEGIN('/'); + + if(strlen(token) == 0) { + nodes = malloc(sizeof(*nodes) * 2); + nodes[0] = scanned_node; + nodes[1] = NULL; + + while(nodes[0]->parent != NULL) nodes[0] = nodes[0]->parent; + } else { + nodes = xl_get_nodes(scanned_node, token); + } + + XL_LIST_END; +} + +xl_node_t** xl_xpointer(xl_node_t* node, const char* path) { + xl_node_t** r = malloc(sizeof(*r) * 2); + char* p = xl_util_strdup(path); + int i; + int s = 0; + int br = 0; + + r[0] = node; + r[1] = NULL; + + for(i = 0;; i++) { + int trig = 0; + + if(p[i] == '(') { + br++; + } else if(p[i] == ')') { + br--; + if(br == 0) trig = 1; + } + if(p[i] == 0) break; + if(trig) { + int j; + xl_node_t** new = malloc(sizeof(*new)); + char* m = malloc(i - s + 2); + + m[i - s + 1] = 0; + memcpy(m, p + s, i - s + 1); + + new[0] = NULL; + + for(j = 0; r[j] != NULL; j++) { + xl_node_t** nodes = NULL; + char* name = strchr(m, '('); + + if(name != NULL) { + char* n = strrchr(name, ')'); + if(n != NULL) n[0] = 0; + + nodes = xl_xpointer_element(r[j], name + 1); + } + + if(nodes != NULL) { + XL_MERGE(new, nodes); + + free(nodes); + } + } + free(m); + free(r); + r = new; + + s = i + 1; + } + } + + if(r[0] == NULL) { + free(r); + r = NULL; + } + + return r; +}