wip xpointer
This commit is contained in:
parent
9ed0eea128
commit
8654e7ad07
6 changed files with 166 additions and 56 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
|
||||
OBJS = src/core.o src/file.o src/unicode.o src/util.o src/array.o src/xpointer.o
|
||||
|
||||
SO = .so
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <string.h>
|
||||
#include <setjmp.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
|
||||
#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
|
||||
|
|
|
|||
55
src/core.c
55
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
80
src/xpointer.c
Normal 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;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue