int _func_xpath_operator_subs(char * chunk, void * data) { #ifdef DEBUG_PARSING fprintf(stderr, "calling func %s chunk %c\n",__func__,chunk[0]); #endif /* DEBUG_PARSING */ roxml_xpath_ctx_t *ctx = (roxml_xpath_ctx_t*)data; int cur = 0; if(ctx->bracket && !ctx->quoted && !ctx->dquoted) { if(ctx->new_cond->func != ROXML_FUNC_XPATH) { if((ctx->new_cond->func == ROXML_FUNC_LAST)||(ctx->new_cond->func == ROXML_FUNC_FIRST)) { ctx->new_cond->op = ROXML_OPERATOR_SUB; } chunk[cur] = '\0'; if(ROXML_WHITE(chunk[cur+1])) { cur++; chunk[cur] = '\0'; } ctx->new_cond->arg2 = chunk+cur+1; } } ctx->shorten_cond = 0; return cur; }
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; }
static int _func_xpath_operators(char * chunk, void * data, int operator, int operator_bis) { roxml_xpath_ctx_t *ctx = (roxml_xpath_ctx_t*)data; int cur = 0; if(!ctx->bracket && !ctx->quoted && !ctx->dquoted) { xpath_node_t *xp_root = ctx->new_node; xpath_cond_t * xp_cond = (xpath_cond_t*)calloc(1, sizeof(xpath_cond_t)); xp_root->xp_cond = xp_cond; chunk[cur] = '\0'; xp_cond->op = operator; if(ROXML_WHITE(chunk[cur-1])) { chunk[cur-1] = '\0'; } if(chunk[cur+1] == '=') { cur++; chunk[cur] = '\0'; xp_cond->op = operator_bis; } if(ROXML_WHITE(chunk[cur+1])) { cur++; chunk[cur] = '\0'; } xp_cond->arg2 = chunk+cur+1; if(xp_cond->arg2[0] == '"') { ctx->content_quoted = MODE_COMMENT_DQUOTE; xp_cond->arg2++; } else if(xp_cond->arg2[0] == '\'') { ctx->content_quoted = MODE_COMMENT_QUOTE; xp_cond->arg2++; } if(!xp_cond->func) { xp_cond->func = ROXML_FUNC_INTCOMP; if(!roxml_is_number(xp_cond->arg2)) { xp_cond->func = ROXML_FUNC_STRCOMP; } } cur++; } else if(ctx->bracket && !ctx->quoted && !ctx->dquoted) { if(ctx->new_cond->func != ROXML_FUNC_XPATH) { chunk[cur] = '\0'; ctx->new_cond->op = operator; if(ROXML_WHITE(chunk[cur-1])) { chunk[cur-1] = '\0'; } if(chunk[cur+1] == '=') { cur++; chunk[cur] = '\0'; ctx->new_cond->op = operator_bis; } if(ROXML_WHITE(chunk[cur+1])) { cur++; chunk[cur] = '\0'; } ctx->new_cond->arg2 = chunk+cur+1; if(ctx->new_cond->arg2[0] == '"') { ctx->content_quoted = MODE_COMMENT_DQUOTE; ctx->new_cond->arg2++; } else if(ctx->new_cond->arg2[0] == '\'') { ctx->content_quoted = MODE_COMMENT_QUOTE; ctx->new_cond->arg2++; } if(ctx->new_cond->func == 0) { ctx->new_cond->func = ROXML_FUNC_INTCOMP; if(!roxml_is_number(ctx->new_cond->arg2)) { ctx->new_cond->func = ROXML_FUNC_STRCOMP; } } cur++; } } return cur; ctx->shorten_cond = 0; }
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; }
char * ROXML_API roxml_get_name(node_t *n, char * buffer, int size) { int offset = 0; int count = 0; char tmp_name[INTERNAL_BUF_SIZE]; memset(tmp_name, 0, INTERNAL_BUF_SIZE*sizeof(char)); if(buffer) { memset(buffer, 0, size*sizeof(char)); } if(n == NULL) { if(buffer) { strcpy(buffer, ""); } return buffer; } if(n->prnt == NULL) { strcpy(tmp_name, "documentRoot"); } else if(n->type & ROXML_NS_NODE) { roxml_ns_t * ns = (roxml_ns_t*)n->priv; if(ns) { strcpy(tmp_name, ns->alias); } else { tmp_name[0] ='\0'; } } else if((n->type & ROXML_TXT_NODE) || (n->type & ROXML_CMT_NODE)) { if(buffer) { strcpy(buffer, ""); return buffer; } return NULL; } else { int spec_offset = 0; if(n->type & ROXML_PI_NODE) { spec_offset = 2; } else if(n->type & ROXML_DOCTYPE_NODE) { spec_offset = 1; } roxml_read(n->pos+spec_offset, INTERNAL_BUF_SIZE, tmp_name, n); while(ROXML_WHITE(tmp_name[offset]) || tmp_name[offset] == '<') { offset++; } count = offset; if(n->type & ROXML_PI_NODE) { for(;count < INTERNAL_BUF_SIZE; count++) { if(ROXML_WHITE(tmp_name[count])) { break; } else if((tmp_name[count] == '?')&&(tmp_name[count+1] == '>')) { break; } } } else if(n->type & ROXML_ELM_NODE) { for(;count < INTERNAL_BUF_SIZE; count++) { if(ROXML_WHITE(tmp_name[count])) { break; } else if((tmp_name[count] == '/')&&(tmp_name[count+1] == '>')) { break; } else if(tmp_name[count] == '>') { break; } } } else if(n->type & ROXML_ATTR_NODE) { for(;count < INTERNAL_BUF_SIZE; count++) { if(ROXML_WHITE(tmp_name[count])) { break; } else if(tmp_name[count] == '=') { break; } else if(tmp_name[count] == '>') { break; } else if((tmp_name[count] == '/')&&(tmp_name[count+1] == '>')) { break; } } } else if(n->type & ROXML_DOCTYPE_NODE) { for(;count < INTERNAL_BUF_SIZE; count++) { if(ROXML_WHITE(tmp_name[count])) { break; } else if(tmp_name[count] == '>') { break; } } } tmp_name[count] = '\0'; } if(buffer == NULL) { buffer = (char*)roxml_malloc(sizeof(char), strlen(tmp_name)-offset+1, PTR_CHAR); strcpy(buffer, tmp_name+offset); } else { if(strlen(tmp_name)-offset < (unsigned int)size) { size = strlen(tmp_name)-offset; } strncpy(buffer, tmp_name+offset, size); } return buffer; }
char * ROXML_API roxml_get_name(node_t *n, char * buffer, int size) { int count = 0; char tmp_name[INTERNAL_BUF_SIZE]; memset(tmp_name, 0, INTERNAL_BUF_SIZE*sizeof(char)); if(buffer) { memset(buffer, 0, size*sizeof(char)); } if(n == NULL) { if(buffer) { strcpy(buffer, ""); } return buffer; } if(n->prnt == NULL) { strcpy(tmp_name, "documentRoot"); } else if(n->type & ROXML_ATTR_NODE) { int offset = 0; char *internal_ptr; char internal_buf[INTERNAL_BUF_SIZE]; roxml_read(n->pos, INTERNAL_BUF_SIZE, internal_buf, n); internal_ptr = internal_buf; while(ROXML_WHITE(internal_ptr[offset])) { offset++; } while(count<INTERNAL_BUF_SIZE) { if(internal_ptr[offset] == '=') { break; } if(internal_ptr[offset] == '/') { break; } if(internal_ptr[offset] == '>') { break; } tmp_name[count] = internal_ptr[offset]; offset++; count++; } } else if(n->type & ROXML_ELM_NODE) { int offset = 0; char *internal_ptr; char internal_buf[INTERNAL_BUF_SIZE]; roxml_read(n->pos, INTERNAL_BUF_SIZE, internal_buf, n); internal_ptr = internal_buf; while((internal_ptr[offset] == '<')||(ROXML_WHITE(internal_ptr[offset]))) { offset++; } while(count<INTERNAL_BUF_SIZE) { if(internal_ptr[offset] == '/') { break; } if(internal_ptr[offset] == '>') { break; } if(ROXML_WHITE(internal_ptr[offset])) { break; } tmp_name[count] = internal_ptr[offset]; offset++; count++; } } else if(n->type & ROXML_TXT_NODE) { if(buffer) { strcpy(buffer, ""); return buffer; } return NULL; } else if(n->type & ROXML_CMT_NODE) { if(buffer) { strcpy(buffer, ""); return buffer; } return NULL; } else if(n->type & ROXML_PI_NODE) { if(buffer) { strcpy(buffer, ""); return buffer; } return NULL; } if(buffer == NULL) { buffer = (char*)roxml_malloc(sizeof(char), strlen(tmp_name)+1, PTR_CHAR); strcpy(buffer, tmp_name); } else { if(strlen(tmp_name) < (unsigned int)size) { size = strlen(tmp_name); } strncpy(buffer, tmp_name, size); } return buffer; }