void ROXML_API roxml_del_node(node_t * n) { if(n == NULL) return; if(n->type & ROXML_ELM_NODE) { roxml_del_std_node(n); } else if(n->type & ROXML_ATTR_NODE) { roxml_del_arg_node(n); } else if(n->type & ROXML_PI_NODE) { roxml_del_std_node(n); } else if(n->type & ROXML_CMT_NODE) { roxml_del_std_node(n); } else if(n->type & ROXML_TXT_NODE) { roxml_del_txt_node(n); } roxml_free_node(n); }
void ROXML_API roxml_close(node_t *n) { node_t *root = n; if(root == NULL) { return; } while(root->prnt != NULL) { root = root->prnt; } roxml_del_tree(root->chld); roxml_del_tree(root->sibl); if((root->type & ROXML_FILE) == ROXML_FILE) { fclose(root->src.fil); } roxml_free_node(root); }
int _func_load_close_node(char * chunk, void * data) { #ifdef DEBUG_PARSING fprintf(stderr, "calling func %s chunk %c\n",__func__,chunk[0]); #endif /* DEBUG_PARSING */ int cur = 1; roxml_load_ctx_t *context = (roxml_load_ctx_t*)data; switch(context->state) { case STATE_NODE_NAME: context->empty_text_node = 1; context->current_node = roxml_parent_node(context->current_node, context->candidat_node, 0); break; case STATE_NODE_ATTR: if((context->mode != MODE_COMMENT_DQUOTE)||(context->mode != MODE_COMMENT_QUOTE)) { if(context->inside_node_state == STATE_INSIDE_VAL) { node_t * to_be_closed = NULL; if(context->content_quoted) { context->content_quoted = 0; to_be_closed = roxml_create_node(context->pos-1, context->src, ROXML_ATTR_NODE | context->type); } else { to_be_closed = roxml_create_node(context->pos, context->src, ROXML_ATTR_NODE | context->type); } roxml_close_node(context->candidat_val, to_be_closed); } context->current_node = roxml_parent_node(context->current_node, context->candidat_node, 0); context->inside_node_state = STATE_INSIDE_ARG_BEG; roxml_process_unaliased_ns(context); } else { context->pos++; return 1; } break; case STATE_NODE_SINGLE: if(context->doctype) { context->doctype--; if(context->doctype > 0) { context->pos++; return 1; } context->candidat_node->end = context->pos; } context->empty_text_node = 1; context->current_node = roxml_parent_node(context->current_node, context->candidat_node, 0); if(context->current_node->prnt != NULL) { context->current_node = context->current_node->prnt; } roxml_process_unaliased_ns(context); break; case STATE_NODE_END: context->empty_text_node = 1; roxml_close_node(context->current_node, context->candidat_node); context->candidat_node = NULL; if(context->current_node->prnt != NULL) { context->current_node = context->current_node->prnt; } break; case STATE_NODE_CDATA: case STATE_NODE_CONTENT: default: context->pos++; return 1; break; } if(context->candidat_node && context->candidat_node->ns && ((context->candidat_node->ns->type & ROXML_INVALID) == ROXML_INVALID)) { roxml_free_node(context->candidat_node->ns); } context->state = STATE_NODE_CONTENT; context->previous_state = STATE_NODE_CONTENT; context->candidat_txt = roxml_create_node(context->pos+1, context->src, ROXML_TXT_NODE | context->type); #ifdef IGNORE_EMPTY_TEXT_NODES while(chunk[cur] != '\0') { if(chunk[cur] == '<') { break; } else if(!ROXML_WHITE(chunk[cur])) { context->empty_text_node = 0; break; } cur++; } #endif /* IGNORE_EMPTY_TEXT_NODES */ while((chunk[cur] != '<')&&(chunk[cur] != '\0')) { cur++; } context->pos += cur; return cur; }
int _func_load_default(char * chunk, void * data) { node_t * to_be_closed; int cur = 1; roxml_load_ctx_t *context = (roxml_load_ctx_t*)data; #ifdef DEBUG_PARSING fprintf(stderr, "calling func %s chunk %c\n",__func__,chunk[0]); #endif /* DEBUG_PARSING */ switch(context->state) { case STATE_NODE_SINGLE: context->state = context->previous_state; break; case STATE_NODE_BEG: if(context->ns == 0) { roxml_process_begin_node(context, context->pos-1); } context->ns = 0; context->state = STATE_NODE_NAME; context->curr_name = chunk; while(!ROXML_WHITE(chunk[cur])&&(chunk[cur] != '>')&&(chunk[cur] != '/')&&(chunk[cur] != ':')&&(chunk[cur] != '\0')) { cur++; } context->curr_name_len = cur; break; case STATE_NODE_ATTR: if(context->inside_node_state == STATE_INSIDE_ARG_BEG) { if(context->nsdef) { if(context->namespaces == NULL) { context->namespaces = context->candidat_arg; context->last_ns = context->candidat_arg; } else { context->last_ns->next = context->candidat_arg; context->last_ns = context->candidat_arg; } } else if(context->ns == 0) { context->candidat_arg = roxml_create_node(context->pos-1, context->src, ROXML_ATTR_NODE | context->type); context->candidat_arg = roxml_parent_node(context->candidat_node, context->candidat_arg, 0); } context->ns = 0; context->inside_node_state = STATE_INSIDE_ARG; context->curr_name = chunk; while((chunk[cur] != '=')&&(chunk[cur] != '>')&&(chunk[cur] != ':')&&(chunk[cur] != '\0')) { cur++; } context->curr_name_len = cur; if(context->nsdef) { roxml_ns_t * ns = calloc(1, sizeof(roxml_ns_t)+(1+context->curr_name_len)); ns->id = ROXML_NS_ID; ns->alias = (char*)ns + sizeof(roxml_ns_t); memcpy(ns->alias, context->curr_name, context->curr_name_len); context->candidat_arg->priv = ns; context->nsdef = 0; if(context->candidat_node->ns) { if((context->candidat_node->ns->type & ROXML_INVALID) == ROXML_INVALID) { if(strcmp(context->candidat_arg->prnt->ns->src.buf, ns->alias) == 0) { roxml_free_node(context->candidat_node->ns); context->candidat_node->ns = context->candidat_arg; } } } } } else if(context->inside_node_state == STATE_INSIDE_VAL_BEG) { if(context->mode != MODE_COMMENT_NONE) { context->content_quoted = 1; context->candidat_val = roxml_create_node(context->pos+1, context->src, ROXML_TXT_NODE | context->type); } else { context->candidat_val = roxml_create_node(context->pos, context->src, ROXML_TXT_NODE | context->type); } context->candidat_val = roxml_parent_node(context->candidat_arg, context->candidat_val, 0); context->inside_node_state = STATE_INSIDE_VAL; } else if((context->inside_node_state == STATE_INSIDE_ARG)&&(chunk[0] == '=')) { context->inside_node_state = STATE_INSIDE_VAL_BEG; to_be_closed = roxml_create_node(context->pos, context->src, ROXML_ATTR_NODE | context->type); roxml_close_node(context->candidat_arg, to_be_closed); if((context->curr_name_len==5)&&(strncmp(context->curr_name, "xmlns", 5) == 0)) { context->nsdef = 1; } } break; } context->pos += cur; return cur; }