diff --git a/example.c b/example.c index a009555..4a47c93 100644 --- a/example.c +++ b/example.c @@ -2,7 +2,7 @@ #define INDENT 2 -void recursive(xl_node_t* node, int indent) { +void recursive(xemil_t* handle, xl_node_t* node, int indent) { int i; xl_node_t* n; for(i = 0; i < indent; i++) printf(" "); @@ -22,21 +22,23 @@ void recursive(xl_node_t* node, int indent) { } printf("%s%s>\n", node->type == XL_NODE_PROCESS ? "?" : "", (node->first_child == NULL && node->text == NULL) ? " /" : ""); - if(node->text != NULL) { + if(node->text != NULL && !handle->new_text) { for(i = 0; i < indent + INDENT; i++) printf(" "); printf("%s\n", node->text); } } else if(node->text != NULL && node->type == XL_NODE_COMMENT) { printf("\n", node->text); + } else if(node->text != NULL && node->type == XL_NODE_TEXT) { + printf("%s\n", node->text); } n = node->first_child; while(n != NULL) { - recursive(n, indent + INDENT); + recursive(handle, n, indent + INDENT); n = n->next; } - if(node->name != NULL && node->type == XL_NODE_NODE && !(node->first_child == NULL && node->text == NULL)) { + if(node->name != NULL && node->type == XL_NODE_NODE && !(node->first_child == NULL && node->text == NULL && !handle->new_text)) { for(i = 0; i < indent; i++) printf(" "); printf("\n", node->name); } @@ -48,18 +50,19 @@ int main(int argc, char** argv) { for(i = 1; i < argc; i++) { xemil_t* h = xl_open_file(argv[i]); + h->new_text = 1; if(h != NULL) { printf("%s:\n", argv[i]); if(xl_parse(h)) { n = h->pre; if(n != NULL) { while(n != NULL) { - recursive(n, INDENT); + recursive(h, n, INDENT); n = n->next; } } - if(h->root != NULL) recursive(h->root, INDENT); + if(h->root != NULL) recursive(h, h->root, INDENT); } else { int j; for(j = 0; j < INDENT; j++) printf(" "); diff --git a/include/xemil.h b/include/xemil.h index e577da2..f3d409d 100644 --- a/include/xemil.h +++ b/include/xemil.h @@ -24,7 +24,8 @@ struct xl_driver { enum XL_NODE_TYPE { XL_NODE_COMMENT = 0, XL_NODE_NODE, - XL_NODE_PROCESS + XL_NODE_PROCESS, + XL_NODE_TEXT }; struct xl_attribute { @@ -54,6 +55,7 @@ struct xemil { xl_driver_t* driver; void* drv_opaque; void* drv_arg; + int new_text; xl_node_t* pre; xl_node_t* root; }; diff --git a/src/core.c b/src/core.c index 2f31676..e9d43e1 100644 --- a/src/core.c +++ b/src/core.c @@ -204,19 +204,63 @@ int xl_parse(xemil_t* handle) { n->text[strlen(n->text) - 2] = 0; } } else if(strlen(node) > 8 && memcmp(&node[1], "[CDATA[", 7) == 0 && node[strlen(node) - 1] == ']' && node[strlen(node) - 2] == ']') { - char* old = current->text; + char* old; + char* text; + xl_node_t* last; + + if(handle->new_text){ + old = NULL; + + last = current->first_child; + if(last != NULL){ + while(last->next != NULL) last = last->next; + + if(last->type == XL_NODE_TEXT){ + old = last->text; + } + } + }else{ + old = current->text; + } if(old == NULL) { - current->text = malloc(strlen(node)); - strcpy(current->text, node + 8); + text = malloc(strlen(node)); + strcpy(text, node + 8); } else { - current->text = malloc(strlen(old) + strlen(node)); - strcpy(current->text, old); - strcpy(current->text + strlen(old), node + 8); + text = malloc(strlen(old) + strlen(node)); + strcpy(text, old); + strcpy(text + strlen(old), node + 8); free(old); } - if(strlen(current->text) > 2) { - current->text[strlen(current->text) - 2] = 0; + if(strlen(text) > 2) { + text[strlen(text) - 2] = 0; + } + + if(handle->new_text){ + if(last == NULL){ + xl_node_t* n; + + last = malloc(sizeof(*last)); + + memset(last, 0, sizeof(*last)); + + last->type = XL_NODE_TEXT; + last->parent = current; + + n = current->first_child; + if(n == NULL){ + current->first_child = last; + }else{ + while(n->next != NULL) n = n->next; + + n->next = last; + last->prev = n; + } + } + + last->text = text; + }else{ + current->text = text; } } else { /* DOCTYPE or something - ignored for now */ @@ -237,14 +281,44 @@ int xl_parse(xemil_t* handle) { nest_level--; - if(current->text != NULL) { - str = xl_util_trim(current->text); - free(current->text); - current->text = str; + if(handle->new_text){ + xl_node_t* n = current->first_child; + while(n != NULL){ + if(n->type == XL_NODE_TEXT){ + if(n->text != NULL){ + str = xl_util_trim(n->text); + free(n->text); + n->text = str; - if(strlen(current->text) == 0) { + if(strlen(n->text) == 0) { + free(n->text); + n->text = NULL; + + if(n->prev != NULL) n->prev->next = n->next; + if(n->next != NULL) n->next->prev = n->prev; + + n = n->next; + if(n != NULL) free(n->prev); + + if(n->prev == NULL) n->parent->first_child = n; + + continue; + } + } + } + + n = n->next; + } + }else{ + if(current->text != NULL) { + str = xl_util_trim(current->text); free(current->text); - current->text = NULL; + current->text = str; + + if(strlen(current->text) == 0) { + free(current->text); + current->text = NULL; + } } } @@ -391,24 +465,69 @@ int xl_parse(xemil_t* handle) { TAKE_AS_NODE(cp); } else if(STATE == STATE_INITIAL) { if(current != NULL) { - char* old = current->text; + char* text; + char* old; + xl_node_t* last; + + if(handle->new_text){ + old = NULL; + + last = current->first_child; + if(last != NULL){ + while(last->next != NULL) last = last->next; + + if(last->type == XL_NODE_TEXT){ + old = last->text; + } + } + }else{ + old = current->text; + } + if(old != NULL) { char buf[4]; int new = xl_unicode_32_to_8(cp, &buf[0]); - current->text = malloc(strlen(old) + new + 1); - strcpy(current->text, old); - memcpy(current->text + strlen(old), &buf[0], new); - current->text[strlen(old) + new] = 0; + text = malloc(strlen(old) + new + 1); + strcpy(text, old); + memcpy(text + strlen(old), &buf[0], new); + text[strlen(old) + new] = 0; free(old); } else { char buf[4]; int new = xl_unicode_32_to_8(cp, &buf[0]); - current->text = malloc(new + 1); - memcpy(current->text, &buf[0], new); - current->text[new] = 0; + text = malloc(new + 1); + memcpy(text, &buf[0], new); + text[new] = 0; + } + + if(handle->new_text){ + if(last == NULL){ + xl_node_t* n; + + last = malloc(sizeof(*last)); + + memset(last, 0, sizeof(*last)); + + last->type = XL_NODE_TEXT; + last->parent = current; + + n = current->first_child; + if(n == NULL){ + current->first_child = last; + }else{ + while(n->next != NULL) n = n->next; + + n->next = last; + last->prev = n; + } + } + + last->text = text; + }else{ + current->text = text; } } } else {