26 #include "roxml-parse-engine.h"
29 unsigned int _nb_node = 0;
30 unsigned int _nb_attr = 0;
31 unsigned int _nb_text = 0;
40 while(cell->
next != NULL) { cell = cell->
next; }
42 if(!cell->
next) {
return NULL; }
43 cell->
next->next = NULL;
44 cell->
next->prev = cell;
47 cell->
id = pthread_self();
49 cell->
ptr = calloc(num, size);
50 head_cell.
prev = cell;
58 if(size > 0 && buffer) {
60 fseek(node->
src.fil, pos, SEEK_SET);
61 ret_len = fread(buffer, 1, size, node->
src.fil);
64 char const *r2 = node->
src.buf+pos;
66 while (size-- && (*r1++ = *r2++));
67 ret_len = r1 - buffer;
111 unsigned char id = *(
unsigned char*)n->
priv;
113 if(
id == ROXML_REQTABLE_ID) {
117 pthread_mutex_destroy(&table->mut);
124 }
else if(
id == ROXML_NS_ID) {
134 if(n == NULL) {
return; }
145 double r = strtod(input, &end);
163 char separators[32] =
"\t\n ";
164 while(separators[i] != 0) {
165 if(sep == separators[i]) {
184 ns->
id = ROXML_NS_ID;
200 #ifdef IGNORE_EMPTY_TEXT_NODES
207 #ifdef IGNORE_EMPTY_TEXT_NODES
220 char int_buffer[ROXML_BULK_READ+1];
229 parser = roxml_append_parser_item(parser,
" ", _func_load_white);
230 parser = roxml_append_parser_item(parser,
"<", _func_load_open_node);
231 parser = roxml_append_parser_item(parser,
">", _func_load_close_node);
232 parser = roxml_append_parser_item(parser,
"/", _func_load_end_node);
233 parser = roxml_append_parser_item(parser,
"'", _func_load_quoted);
234 parser = roxml_append_parser_item(parser,
"\"", _func_load_dquoted);
235 parser = roxml_append_parser_item(parser,
"\t", _func_load_white);
236 parser = roxml_append_parser_item(parser,
"\n", _func_load_white);
237 parser = roxml_append_parser_item(parser,
"\r", _func_load_white);
238 parser = roxml_append_parser_item(parser,
"!", _func_load_open_spec_node);
239 parser = roxml_append_parser_item(parser,
"]", _func_load_close_cdata);
240 parser = roxml_append_parser_item(parser,
"-", _func_load_close_comment);
241 parser = roxml_append_parser_item(parser,
"?", _func_load_close_pi);
242 parser = roxml_append_parser_item(parser,
":", _func_load_colon);
243 parser = roxml_append_parser_item(parser, NULL, _func_load_default);
245 parser = roxml_parser_prepare(parser);
251 context.
src = (
void*)file;
256 int_len = fread(int_buffer+circle, 1, ROXML_BULK_READ-circle, file) + circle;
257 int_buffer[int_len] =
'\0';
259 if(int_len == ROXML_BULK_READ) {
260 chunk_len = int_len - ROXML_LONG_LEN;
265 ret = roxml_parse_line(parser, int_buffer, chunk_len, &context);
266 circle = int_len-ret;
267 if((ret < 0)||(circle < 0)) {
271 memmove(int_buffer, int_buffer+ret, circle);
272 }
while(int_len == ROXML_BULK_READ);
276 context.
src = (
void*)buffer;
277 ret = roxml_parse_line(parser, buffer, 0, &context);
283 roxml_parser_free(parser);
285 #ifdef IGNORE_EMPTY_TEXT_NODES
294 virtroot = current_node;
295 while(virtroot->
prnt) {
296 virtroot = virtroot->
prnt;
299 table->
id = ROXML_REQTABLE_ID;
300 table->
ids[ROXML_REQTABLE_ID] = 1;
301 pthread_mutex_init(&table->
mut, NULL);
302 virtroot->
priv = (
void*)table;
316 for(len = 0; ns[len] !=
'\0' && ns[len] !=
':'; len++) {
317 namespace[len] = ns[len];
319 namespace[len] =
'\0';
343 struct _xpath_axes xpath_axes[14] = {
344 {ROXML_ID_PARENT, ROXML_L_PARENT},
345 {ROXML_ID_PARENT, ROXML_S_PARENT},
346 {ROXML_ID_SELF, ROXML_L_SELF},
347 {ROXML_ID_SELF, ROXML_S_SELF},
348 {ROXML_ID_ATTR, ROXML_L_ATTR},
349 {ROXML_ID_ATTR, ROXML_S_ATTR},
350 {ROXML_ID_ANC, ROXML_L_ANC},
351 {ROXML_ID_ANC_O_SELF, ROXML_L_ANC_O_SELF},
352 {ROXML_ID_NEXT_SIBL, ROXML_L_NEXT_SIBL},
353 {ROXML_ID_PREV_SIBL, ROXML_L_PREV_SIBL},
354 {ROXML_ID_NEXT, ROXML_L_NEXT},
355 {ROXML_ID_PREV, ROXML_L_PREV},
356 {ROXML_ID_NS, ROXML_L_NS},
357 {ROXML_ID_CHILD, ROXML_L_CHILD},
368 node->
axes = ROXML_ID_DESC_O_SELF;
371 tmp_node->
axes = ROXML_ID_CHILD;
372 node->
next = tmp_node;
373 if(strlen(node->
name) > 0) {
375 node->
next->next = tmp_node;
378 }
else if(strncmp(ROXML_L_DESC_O_SELF, axes, strlen(ROXML_L_DESC_O_SELF))==0) {
380 node->
axes = ROXML_ID_DESC_O_SELF;
381 node->
name = axes+strlen(ROXML_L_DESC_O_SELF);
382 *offset += strlen(ROXML_L_DESC_O_SELF);
384 tmp_node->
axes = ROXML_ID_CHILD;
385 node->
next = tmp_node;
386 node =
roxml_set_axes(tmp_node, axes+strlen(ROXML_L_DESC_O_SELF), offset);
387 }
else if(strncmp(ROXML_L_DESC, axes, strlen(ROXML_L_DESC))==0) {
389 node->
axes = ROXML_ID_DESC;
390 node->
name = axes+strlen(ROXML_L_DESC);
391 *offset += strlen(ROXML_L_DESC);
393 tmp_node->
axes = ROXML_ID_CHILD;
394 node->
next = tmp_node;
395 node =
roxml_set_axes(tmp_node, axes+strlen(ROXML_L_DESC), offset);
400 node->
axes = ROXML_ID_CHILD;
403 for(i = 0; i < 14; i++) {
404 int len = strlen(xpath_axes[i].name);
405 if(strncmp(xpath_axes[i].name, axes, len)==0) {
406 node->
axes = xpath_axes[i].id;
407 node->
name = axes+len;
420 if(n == NULL) {
return 0; }
428 while((first)&&(first != n)) {
457 parser = roxml_append_parser_item(parser,
" ", _func_xpath_ignore);
458 parser = roxml_append_parser_item(parser,
"\t", _func_xpath_ignore);
459 parser = roxml_append_parser_item(parser,
"\n", _func_xpath_ignore);
460 parser = roxml_append_parser_item(parser,
"\r", _func_xpath_ignore);
461 parser = roxml_append_parser_item(parser,
"\"", _func_xpath_dquote);
462 parser = roxml_append_parser_item(parser,
"\'", _func_xpath_quote);
463 parser = roxml_append_parser_item(parser,
"/", _func_xpath_new_node);
464 parser = roxml_append_parser_item(parser,
"(", _func_xpath_open_parenthesys);
465 parser = roxml_append_parser_item(parser,
")", _func_xpath_close_parenthesys);
466 parser = roxml_append_parser_item(parser,
"[", _func_xpath_open_brackets);
467 parser = roxml_append_parser_item(parser,
"]", _func_xpath_close_brackets);
468 parser = roxml_append_parser_item(parser,
"=", _func_xpath_operator_equal);
469 parser = roxml_append_parser_item(parser,
">", _func_xpath_operator_sup);
470 parser = roxml_append_parser_item(parser,
"<", _func_xpath_operator_inf);
471 parser = roxml_append_parser_item(parser,
"!", _func_xpath_operator_diff);
472 parser = roxml_append_parser_item(parser,
"0", _func_xpath_number);
473 parser = roxml_append_parser_item(parser,
"1", _func_xpath_number);
474 parser = roxml_append_parser_item(parser,
"2", _func_xpath_number);
475 parser = roxml_append_parser_item(parser,
"3", _func_xpath_number);
476 parser = roxml_append_parser_item(parser,
"4", _func_xpath_number);
477 parser = roxml_append_parser_item(parser,
"5", _func_xpath_number);
478 parser = roxml_append_parser_item(parser,
"6", _func_xpath_number);
479 parser = roxml_append_parser_item(parser,
"7", _func_xpath_number);
480 parser = roxml_append_parser_item(parser,
"8", _func_xpath_number);
481 parser = roxml_append_parser_item(parser,
"9", _func_xpath_number);
482 parser = roxml_append_parser_item(parser,
"+", _func_xpath_operator_add);
483 parser = roxml_append_parser_item(parser,
"-", _func_xpath_operator_subs);
484 parser = roxml_append_parser_item(parser, ROXML_PATH_OR, _func_xpath_path_or);
485 parser = roxml_append_parser_item(parser, ROXML_COND_OR, _func_xpath_condition_or);
486 parser = roxml_append_parser_item(parser, ROXML_COND_AND, _func_xpath_condition_and);
487 parser = roxml_append_parser_item(parser, ROXML_FUNC_POS_STR, _func_xpath_position);
488 parser = roxml_append_parser_item(parser, ROXML_FUNC_FIRST_STR, _func_xpath_first);
489 parser = roxml_append_parser_item(parser, ROXML_FUNC_LAST_STR, _func_xpath_last);
490 parser = roxml_append_parser_item(parser, ROXML_FUNC_NSURI_STR, _func_xpath_nsuri);
491 parser = roxml_append_parser_item(parser, NULL, _func_xpath_default);
493 parser = roxml_parser_prepare(parser);
494 ret = roxml_parse_line(parser, path, 0, &ctx);
495 roxml_parser_free(parser);
522 for(i = 0; i < nb; i++) {
529 free(xpath[i].xp_cond);
536 if(op == ROXML_OPERATOR_ADD) {
538 }
else if(op == ROXML_OPERATOR_SUB) {
540 }
else if(op == ROXML_OPERATOR_MUL) {
542 }
else if(op == ROXML_OPERATOR_DIV) {
550 if(op == ROXML_OPERATOR_DIFF) {
552 }
else if(op == ROXML_OPERATOR_EINF) {
554 }
else if(op == ROXML_OPERATOR_INF) {
556 }
else if(op == ROXML_OPERATOR_ESUP) {
558 }
else if(op == ROXML_OPERATOR_SUP) {
560 }
else if(op == ROXML_OPERATOR_EQU) {
570 result = strcmp(sa, sb);
572 if(op == ROXML_OPERATOR_DIFF) {
573 return (result != 0);
574 }
else if(op == ROXML_OPERATOR_EINF) {
575 return (result <= 0);
576 }
else if(op == ROXML_OPERATOR_INF) {
578 }
else if(op == ROXML_OPERATOR_ESUP) {
579 return (result >= 0);
580 }
else if(op == ROXML_OPERATOR_SUP) {
582 }
else if(op == ROXML_OPERATOR_EQU) {
583 return (result == 0);
594 if(xn == NULL) {
return 1; }
596 condition = xn->
cond;
609 if(condition->
func == ROXML_FUNC_POS) {
611 iarg2 = atof(condition->
arg2);
612 if(xn->
name[0] ==
'*') {
618 }
else if(condition->
func == ROXML_FUNC_LAST) {
621 if(xn->
name[0] ==
'*') {
626 if(condition->
op > 0) {
628 operand = atof(condition->
arg2);
632 }
else if(condition->
func == ROXML_FUNC_FIRST) {
635 if(xn->
name[0] ==
'*') {
640 if(condition->
op > 0) {
642 operand = atof(condition->
arg2);
646 }
else if(condition->
func == ROXML_FUNC_INTCOMP) {
647 char strval[ROXML_BASE_LEN];
652 if(status >= ROXML_BASE_LEN) {
656 iarg2 = atof(condition->
arg2);
659 }
else if(condition->
func == ROXML_FUNC_NSURI) {
660 char strval[ROXML_BASE_LEN];
665 if(status >= ROXML_BASE_LEN) {
668 sarg2 = condition->
arg2;
672 sarg2 = condition->
arg2;
675 }
else if(condition->
func == ROXML_FUNC_STRCOMP) {
676 char strval[ROXML_BASE_LEN];
681 if(status >= ROXML_BASE_LEN) {
684 sarg2 = condition->
arg2;
688 }
else if(condition->
func == ROXML_FUNC_XPATH) {
689 int index = condition->
func2;
699 if(count > 0) { status = 1; }
707 if(condition->
rel == ROXML_OPERATOR_OR) {
708 valid = valid || status;
709 }
else if(condition->
rel == ROXML_OPERATOR_AND) {
710 valid = valid && status;
713 condition = condition->
next;
730 pthread_mutex_lock(&table->
mut);
731 for(i = ROXML_XPATH_FIRST_ID; i < 255; i++) {
732 if(table->
ids[i] == 0) {
734 pthread_mutex_unlock(&table->
mut);
738 pthread_mutex_unlock(&table->
mut);
752 pthread_mutex_lock(&table->
mut);
755 if(tok->
id == req_id) {
756 pthread_mutex_unlock(&table->
mut);
760 if(tok->
id == req_id) {
761 pthread_mutex_unlock(&table->
mut);
768 pthread_mutex_unlock(&table->
mut);
783 for(i = 0; i < pool_len; i++) {
786 pthread_mutex_lock(&table->
mut);
787 table->
ids[req_id] = 0;
788 pthread_mutex_unlock(&table->
mut);
801 pthread_mutex_lock(&table->
mut);
805 if(tok->id == req_id) {
806 n->
priv = (
void*)tok->next;
810 if(tok->id == req_id) {
811 prev->
next = tok->next;
820 pthread_mutex_unlock(&table->
mut);
833 if(req_id == 0) {
return 1; }
837 pthread_mutex_lock(&table->
mut);
841 if(tok->
id == req_id) {
842 pthread_mutex_unlock(&table->
mut);
848 if(last_tok == NULL) {
853 last_tok = last_tok->
next;
855 last_tok->
id = req_id;
856 pthread_mutex_unlock(&table->
mut);
876 if((axes == NULL) || (strcmp(
"node()", axes) == 0)) {
878 }
else if(strcmp(
"*", axes) == 0) {
881 }
else if(strcmp(
"comment()", axes) == 0) {
883 }
else if(strcmp(
"processing-instruction()", axes) == 0) {
885 }
else if(strcmp(
"text()", axes) == 0) {
887 }
else if(strcmp(
"", axes) == 0) {
897 if(xn->
next == NULL) { path_end = 1; }
898 if((xn->
axes == ROXML_ID_SELF)||(xn->
axes == ROXML_ID_PARENT)) { valid = 1; }
903 char * name = intern_buff;
906 ns_len = strlen(name);
913 if(name && strcmp(name, axes) == 0) {
928 if(condition->
func == ROXML_FUNC_STRCOMP) {
929 char strval[ROXML_BASE_LEN];
931 if(status >= ROXML_BASE_LEN) {
934 sarg2 = condition->
arg2;
937 }
else if(condition->
func == ROXML_FUNC_INTCOMP) {
940 char strval[ROXML_BASE_LEN];
942 if(status >= ROXML_BASE_LEN) {
946 iarg2 = atof(condition->
arg2);
951 if((valid)&&(path_end)) {
954 if((*nb) >= (*max)) {
955 int new_max = (*max)*2;
957 memcpy(new_ans, (*ans), *(max)*
sizeof(
node_t*));
962 (*ans)[*nb] = candidat;
973 int validate_node = 0;
975 if((req_id == 0) && (*nb > 0)) {
982 if(ignore == ROXML_DESC_ONLY) {
986 current = current->
sibl;
991 case ROXML_ID_CHILD: {
998 current = current->
sibl;
1000 if((xp->
name == NULL)||(strcmp(xp->
name,
"text()") == 0)||(strcmp(xp->
name,
"node()") == 0)) {
1004 current = current->
sibl;
1007 if((xp->
name == NULL)||(strcmp(xp->
name,
"node()") == 0)) {
1011 current = current->
sibl;
1015 case ROXML_ID_DESC: {
1017 roxml_check_node(xp, root, context, ans, nb, max, ROXML_DESC_ONLY, req_id);
1019 case ROXML_ID_DESC_O_SELF: {
1025 roxml_check_node(xp, root, context, ans, nb, max, ROXML_DESC_ONLY, req_id);
1027 case ROXML_ID_SELF: {
1031 case ROXML_ID_PARENT: {
1032 if (context->
prnt) {
1039 case ROXML_ID_ATTR: {
1046 attribute = attribute->
sibl;
1049 case ROXML_ID_ANC: {
1056 current = current->
prnt;
1059 case ROXML_ID_NEXT_SIBL: {
1066 current = current->
sibl;
1069 case ROXML_ID_PREV_SIBL: {
1071 while(current != context) {
1076 current = current->
sibl;
1079 case ROXML_ID_NEXT: {
1080 node_t *current = context;
1088 xp->
axes = ROXML_ID_CHILD;
1089 roxml_check_node(xp, root, following, ans, nb, max, ROXML_DESC_ONLY, req_id);
1090 xp->
axes = ROXML_ID_NEXT;
1092 following = following->
sibl;
1094 following = current->
prnt->chld;
1095 while(following != current) { following = following->
sibl; }
1096 current = following->
sibl;
1099 case ROXML_ID_PREV: {
1100 node_t *current = context;
1101 while(current && current->
prnt) {
1103 while(preceding != current) {
1108 xp->
axes = ROXML_ID_CHILD;
1109 roxml_check_node(xp, root, preceding, ans, nb, max, ROXML_DESC_ONLY, req_id);
1110 xp->
axes = ROXML_ID_PREV;
1112 preceding = preceding->
sibl;
1114 current = current->
prnt;
1123 case ROXML_ID_ANC_O_SELF: {
1124 node_t *current = context;
1130 current = current->
prnt;
1141 if(parent == NULL) {
1165 parent->
next->sibl = n;
1179 if(n == NULL) {
return NULL; }
1180 if(parent == NULL) {
return n; }
1218 next = parent->
attr;
1220 for(i = 1; i < position; i++) {
1236 int pos = *offset + lvl;
1238 *buf = realloc(*buf, *len+ROXML_LONG_LEN);
1239 memset(*buf+*len, 0, ROXML_LONG_LEN);
1240 *len += ROXML_LONG_LEN;
1242 for(; i < lvl; i++) {
1248 for(; i < lvl; i++) {
1249 fwrite(
" ", 1, 1, f);
1257 int min_len = strlen(str);
1258 int pos = *offset + min_len;
1259 int appended_space = ROXML_LONG_LEN*((int)(min_len/ROXML_LONG_LEN)+1);
1261 if((pos >= *len) && (buf) && (*buf)) {
1262 *buf = realloc(*buf, *len+appended_space);
1263 memset(*buf+*len, 0, appended_space);
1264 *len += appended_space;
1266 if(f) { fprintf(f,
"%s", str); }
1267 if(buf && *buf) { strcat(*buf+(*offset), str); }
1273 char name[ROXML_BASE_LEN];
1274 char ns[ROXML_BASE_LEN];
1295 char arg[ROXML_BASE_LEN];
1296 char val[ROXML_BASE_LEN];
1297 char arg_ns[ROXML_BASE_LEN];
1300 if(status >= ROXML_BASE_LEN) {
1306 if(arg[0] !=
'\0') {
1312 if(arg_ns[0] !=
'\0') {
1333 char val[ROXML_LONG_LEN];
1341 if(status >= ROXML_LONG_LEN) {
1349 char * end = value + status - 2;
1350 char * strip = value;
1398 char val[ROXML_LONG_LEN];
1403 strcpy(head,
"<!--");
1404 strcpy(tail,
"-->");
1423 if(status >= ROXML_LONG_LEN) {
1426 if(name && value && value[0]) {
1466 if(attr->
ns == ns) {
1467 attr->
ns = attr->
prnt->ns;
1484 }
else if(current) {
1485 while(current->
sibl && current->
sibl != n) {
1486 current = current->
sibl;
1498 current = current->
sibl;
1500 if(n->
prnt && n->
prnt->next == n) {
1505 }
else if(current) {
1506 while(current->
sibl && current->
sibl != n) {
1507 current = current->
sibl;
1517 if(n->
prnt && n->
prnt->next == n) {
1522 }
else if(current) {
1523 while(current->
sibl && current->
sibl != n) {
1524 current = current->
sibl;
1535 for(i = 0; i < *count; i++) {
1541 node_set[i] = node_set[(*count)-1];
1550 for(i = 0; i < *count; i++) {
1562 int max_answers = 1;
1564 int * req_ids = NULL;
1569 req_ids = calloc(index,
sizeof(
int));
1573 for(path_id = 0; path_id < index; path_id++) {
1576 cur_xpath = &xpath[path_id];
1577 if(path_id < index-1) { next_xpath = &xpath[path_id+1]; }
1579 if((cur_xpath->
rel == ROXML_OPERATOR_AND)||((next_xpath) && (next_xpath->
rel == ROXML_OPERATOR_AND))) {
1583 if(cur_xpath->
abs) {
1588 roxml_check_node(cur_xpath, root, orig, &node_set, count, &max_answers, ROXML_DIRECT, req_id);
1590 if(cur_xpath->
rel == ROXML_OPERATOR_AND) {
1593 req_ids[path_id] = req_id;
1598 for(path_id = 0; path_id < index; path_id++) {
1602 if(cur_xpath->
rel == ROXML_OPERATOR_OR) {
1603 if(req_ids[path_id] == 0) {
1604 if(cur_xpath->
abs) {
1609 roxml_check_node(cur_xpath, root, orig, &node_set, count, &max_answers, ROXML_DIRECT, glob_id);
1618 for(path_id = 0; path_id < index; path_id++) {
1619 if(req_ids[path_id] != 0) {