wip xpointer

This commit is contained in:
Nishi 2026-03-09 22:09:30 +09:00
commit 8654e7ad07
Signed by: nishi
GPG key ID: 27EF69B208EB9343
6 changed files with 166 additions and 56 deletions

View file

@ -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;
}

View file

@ -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;
}

80
src/xpointer.c Normal file
View file

@ -0,0 +1,80 @@
#include <xemil.h>
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;
}