diff options
author | gmcdonald | 2010-02-13 01:32:03 +0000 |
---|---|---|
committer | gmcdonald | 2010-02-13 01:32:03 +0000 |
commit | 0425aadc78680e53000fd0108b540d6eca048516 (patch) | |
tree | 8ec7ab8e015d454c5ec586dfc91e05a2dce1cfc0 /axiom/src/xpath/xpath_internals_parser.c | |
download | axis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.gz axis2c-0425aadc78680e53000fd0108b540d6eca048516.tar.bz2 |
Moving axis svn, part of TLP move INFRA-2441
git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@909681 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'axiom/src/xpath/xpath_internals_parser.c')
-rwxr-xr-x | axiom/src/xpath/xpath_internals_parser.c | 1245 |
1 files changed, 1245 insertions, 0 deletions
diff --git a/axiom/src/xpath/xpath_internals_parser.c b/axiom/src/xpath/xpath_internals_parser.c new file mode 100755 index 0000000..a1ce79a --- /dev/null +++ b/axiom/src/xpath/xpath_internals_parser.c @@ -0,0 +1,1245 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <axiom_xpath.h> +#include "xpath_internals.h" +#include "xpath_internals_parser.h" +#include <ctype.h> + +/* Compile an XPath expression */ +int +axiom_xpath_compile( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + if(!expr || !expr->expr_str) + { +#ifdef AXIOM_XPATH_DEBUG + printf("Expression in NULL.\n"); +#endif + + return AXIS2_FAILURE; + } + + expr->expr_len = (int)axutil_strlen(expr->expr_str); + + expr->operations = axutil_array_list_create(env, 0); + + expr->expr_ptr = 0; + + expr->start = axiom_xpath_compile_orexpr(env, expr); + + if(expr->start == AXIOM_XPATH_PARSE_ERROR) + { + axutil_array_list_free(expr->operations, env); + + return AXIOM_XPATH_PARSE_ERROR; + } + else + { +#ifdef AXIOM_XPATH_DEBUG + printf("Expression successfully parsed\n"); +#endif + + return AXIOM_XPATH_PARSE_SUCCESS; + } +} + +/* Parse Or Expression */ +int +axiom_xpath_compile_orexpr( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op1, op2; + + if(!AXIOM_XPATH_HAS_MORE) + { + return AXIOM_XPATH_PARSE_END; + } + + op1 = axiom_xpath_compile_andexpr(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: AndEpxr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_SKIP_WHITESPACES; + + while(AXIOM_XPATH_CURRENT == 'o' && AXIOM_XPATH_NEXT(1) == 'r') + { + AXIOM_XPATH_READ(2); + AXIOM_XPATH_SKIP_WHITESPACES; + + op2 = axiom_xpath_compile_andexpr(env, expr); + + if(op2 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: AndEpxr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + op1 = AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_OR_EXPR, op1, op2); + + AXIOM_XPATH_SKIP_WHITESPACES; + } + + return op1; +} + +/* Parse And Expression */ +int +axiom_xpath_compile_andexpr( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op1, op2; + + if(!AXIOM_XPATH_HAS_MORE) + { + return AXIOM_XPATH_PARSE_END; + } + + op1 = axiom_xpath_compile_equalexpr(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: EqualityExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_SKIP_WHITESPACES; + + while(AXIOM_XPATH_CURRENT == 'a' && AXIOM_XPATH_NEXT(1) == 'n' && AXIOM_XPATH_NEXT(1) == 'd') + { + AXIOM_XPATH_READ(2); + AXIOM_XPATH_SKIP_WHITESPACES; + + op2 = axiom_xpath_compile_equalexpr(env, expr); + + if(op2 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: EqualityExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + op1 = AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_AND_EXPR, op1, op2); + + AXIOM_XPATH_SKIP_WHITESPACES; + } + + return op1; +} + +/* Parse Equality Expression */ +int +axiom_xpath_compile_equalexpr( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op1, op2; + + if(!AXIOM_XPATH_HAS_MORE) + { + return AXIOM_XPATH_PARSE_END; + } + + op1 = axiom_xpath_compile_union(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: UnionExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + while(AXIOM_XPATH_CURRENT == '=') + { + AXIOM_XPATH_SKIP_WHITESPACES; + AXIOM_XPATH_READ(1); + AXIOM_XPATH_SKIP_WHITESPACES; + + op2 = axiom_xpath_compile_union(env, expr); + + if(op2 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: UnionExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + op1 = AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_EQUAL_EXPR, op1, op2); + + AXIOM_XPATH_SKIP_WHITESPACES; + } + + return op1; +} + +/* Parse Union */ +int +axiom_xpath_compile_union( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op1, op2; + + if(!AXIOM_XPATH_HAS_MORE) + { + return AXIOM_XPATH_PARSE_END; + } + + op1 = axiom_xpath_compile_path_expression(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: PathExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(AXIOM_XPATH_CURRENT == '|') + { + AXIOM_XPATH_READ(1); + AXIOM_XPATH_SKIP_WHITESPACES; + op2 = axiom_xpath_compile_union(env, expr); + + if(op2 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: UnionExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + return AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_UNION, op1, op2); + } + + /* Just a location path */ + return op1; +} + +/* Compile Filter expression */ +int +axiom_xpath_compile_filter( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op = AXIOM_XPATH_PARSE_END; + + if(AXIOM_XPATH_CURRENT == '(') + { + AXIOM_XPATH_READ(1); + op = axiom_xpath_compile_orexpr(env, expr); + AXIOM_XPATH_SKIP_WHITESPACES; + if(AXIOM_XPATH_CURRENT == ')') + { + AXIOM_XPATH_READ(1); + return op; + } + else + { + return AXIOM_XPATH_PARSE_ERROR; + } + } + else if(AXIOM_XPATH_CURRENT == '\'' || AXIOM_XPATH_CURRENT == '\"') + { + return AXIOM_XPATH_PUSH_PAR(AXIOM_XPATH_OPERATION_LITERAL, axiom_xpath_compile_literal(env, + expr), NULL, AXIOM_XPATH_PARSE_END); + } + else if(isdigit(AXIOM_XPATH_CURRENT) || (AXIOM_XPATH_CURRENT == '.' && isdigit( + AXIOM_XPATH_NEXT(1)))) + { + return AXIOM_XPATH_PUSH_PAR(AXIOM_XPATH_OPERATION_NUMBER, axiom_xpath_compile_number(env, + expr), NULL, AXIOM_XPATH_PARSE_END); + } + else if(AXIOM_XPATH_CURRENT == '$') + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: Variables are not supported, yet - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + } + else + { + return axiom_xpath_compile_function_call(env, expr); + } + +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: Invalid Filter expression - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + /* TODO: functions and variables */ +} + +/* Parse Path expression (not a location path) */ +int +axiom_xpath_path_compile_path_expression_filter( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op_filter, op_next; + + op_filter = axiom_xpath_compile_filter(env, expr); + + if(op_filter == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: FilterExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(AXIOM_XPATH_NEXT(0) == '/' && AXIOM_XPATH_NEXT(1) == '/') + { + AXIOM_XPATH_READ(2); + + op_next = axiom_xpath_compile_relative_location(env, expr); + + if(op_next == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + op_next = AXIOM_XPATH_WRAP_SELF_DESCENDANT(op_next); + } + else if(AXIOM_XPATH_NEXT(0) == '/') + { + AXIOM_XPATH_READ(1); + + op_next = axiom_xpath_compile_relative_location(env, expr); + + if(op_next == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + } + else + { + op_next = AXIOM_XPATH_PARSE_END; + } + + return AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_PATH_EXPRESSION, op_filter, op_next); +} + +/* Parse Path expression */ +int +axiom_xpath_compile_path_expression( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int temp_ptr = expr->expr_ptr; + axis2_char_t *name; + axis2_char_t *node_types[] = { "comment", "node", "processing-instruction", "text" }; + axis2_char_t filter_start[] = { '$', '\'', '\"', '(' }; + int i; + + /* if | FilterExpr + | FilterExpr '/' RelativeLocationPath + | FilterExpr '//' RelativeLocationPath */ + for(i = 0; i < 4; i++) + { + if(AXIOM_XPATH_CURRENT == filter_start[i]) + { + return axiom_xpath_path_compile_path_expression_filter(env, expr); + } + } + + if(isdigit(AXIOM_XPATH_CURRENT) || (AXIOM_XPATH_CURRENT == '.' && isdigit(AXIOM_XPATH_NEXT(1)))) + { + return axiom_xpath_path_compile_path_expression_filter(env, expr); + } + + /* Funciton calls */ + name = axiom_xpath_compile_ncname(env, expr); + AXIOM_XPATH_SKIP_WHITESPACES; + + if(name != NULL && AXIOM_XPATH_CURRENT == '(') + { + expr->expr_ptr = temp_ptr; + for(i = 0; i < 4; i++) + { + /* If node type */ + if(axutil_strcmp(name, node_types[i]) == 0) + { + return axiom_xpath_compile_location_path(env, expr); + } + } + + return axiom_xpath_path_compile_path_expression_filter(env, expr); + } + + expr->expr_ptr = temp_ptr; + + return axiom_xpath_compile_location_path(env, expr); +} + +/* Parses Location Path */ +int +axiom_xpath_compile_location_path( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op1; + axiom_xpath_operation_type_t opr; + + if(!AXIOM_XPATH_HAS_MORE) + { + return AXIOM_XPATH_PARSE_END; + } + + if(AXIOM_XPATH_CURRENT == '/') + { + /* Descendent */ + if(AXIOM_XPATH_NEXT(1) == '/') + { + opr = AXIOM_XPATH_OPERATION_CONTEXT_NODE; + AXIOM_XPATH_READ(2); + AXIOM_XPATH_SKIP_WHITESPACES; + + op1 = axiom_xpath_compile_relative_location(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + op1 = AXIOM_XPATH_WRAP_SELF_DESCENDANT(op1); + } + else + { + opr = AXIOM_XPATH_OPERATION_ROOT_NODE; + AXIOM_XPATH_READ(1); + + op1 = axiom_xpath_compile_relative_location(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + } + } + else + { + opr = AXIOM_XPATH_OPERATION_CONTEXT_NODE; + + op1 = axiom_xpath_compile_relative_location(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + } + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + return AXIOM_XPATH_PUSH(opr, op1, AXIOM_XPATH_PARSE_END); +} + +/* Parses Relative Location Path */ +int +axiom_xpath_compile_relative_location( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op_step, op_next; + + if(!AXIOM_XPATH_HAS_MORE) + { + return AXIOM_XPATH_PARSE_END; + } + + op_step = axiom_xpath_compile_step(env, expr); + op_next = AXIOM_XPATH_PARSE_END; /* Will change if there are more steps */ + + if(op_step == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: Step expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(AXIOM_XPATH_NEXT(0) == '/' && AXIOM_XPATH_NEXT(1) == '/') + { + AXIOM_XPATH_READ(2); + + op_next = axiom_xpath_compile_relative_location(env, expr); + + if(op_next == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + op_next = AXIOM_XPATH_WRAP_SELF_DESCENDANT(op_next); + } + else if(AXIOM_XPATH_NEXT(0) == '/') + { + AXIOM_XPATH_READ(1); + + op_next = axiom_xpath_compile_relative_location(env, expr); + + if(op_next == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: RelativeLocation expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + } + + /* End of the location path */ + if(op_next == AXIOM_XPATH_PARSE_END) + { + op_next = AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_RESULT, AXIOM_XPATH_PARSE_END, + AXIOM_XPATH_PARSE_END); + } + + return AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_STEP, op_step, op_next); +} + +/* Parses Step */ +int +axiom_xpath_compile_step( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op_predicate = AXIOM_XPATH_PARSE_END; + axiom_xpath_node_test_t *node_test; + int temp_ptr; + axis2_char_t *name = NULL; + axiom_xpath_axis_t axis = AXIOM_XPATH_AXIS_NONE; + + AXIOM_XPATH_SKIP_WHITESPACES; + + /* . and .. */ + if(AXIOM_XPATH_CURRENT == '.') + { + if(AXIOM_XPATH_NEXT(1) == '.') + { + AXIOM_XPATH_READ(2); + axis = AXIOM_XPATH_AXIS_PARENT; + } + else + { + AXIOM_XPATH_READ(1); + axis = AXIOM_XPATH_AXIS_SELF; + } + + return AXIOM_XPATH_PUSH_PAR(AXIOM_XPATH_OPERATION_NODE_TEST, + axiom_xpath_create_node_test_node(env), axiom_xpath_create_axis(env, axis), + op_predicate); + } + else if(AXIOM_XPATH_CURRENT == '@') + { + axis = AXIOM_XPATH_AXIS_ATTRIBUTE; + + AXIOM_XPATH_READ(1); + AXIOM_XPATH_SKIP_WHITESPACES; + } + else + { + temp_ptr = expr->expr_ptr; + + name = axiom_xpath_compile_ncname(env, expr); + + if(name) + { + AXIOM_XPATH_SKIP_WHITESPACES; + + /* An axis */ + if(AXIOM_XPATH_CURRENT == ':' && AXIOM_XPATH_NEXT(1) == ':') + { + axis = axiom_xpath_get_axis(env, name); + + if(axis == AXIOM_XPATH_AXIS_NONE) + { +#ifdef AXIOM_XPATH_DEBUG + printf("Parse error: Invalid axis - %s\n", name); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_READ(2); + AXIOM_XPATH_SKIP_WHITESPACES; + } + else + { + axis = AXIOM_XPATH_AXIS_CHILD; + + expr->expr_ptr = temp_ptr; + } + } + else + { + axis = AXIOM_XPATH_AXIS_CHILD; + + expr->expr_ptr = temp_ptr; + } + } + + node_test = axiom_xpath_compile_node_test(env, expr); + + if(!node_test) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: NodeTest expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + op_predicate = axiom_xpath_compile_predicate(env, expr); + + if(op_predicate == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: Predicate expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + return AXIOM_XPATH_PUSH_PAR(AXIOM_XPATH_OPERATION_NODE_TEST, node_test, + axiom_xpath_create_axis(env, axis), op_predicate); +} + +axiom_xpath_node_test_t* +axiom_xpath_compile_node_test( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + axis2_char_t* name; + axiom_xpath_node_test_t *node_test; + + node_test = AXIS2_MALLOC(env->allocator, sizeof(axiom_xpath_node_test_t)); + node_test->type = AXIOM_XPATH_NODE_TEST_NONE; + node_test->prefix = NULL; + node_test->name = NULL; + node_test->lit = NULL; + + if(AXIOM_XPATH_CURRENT == '*') + { + AXIOM_XPATH_READ(1); + + node_test->type = AXIOM_XPATH_NODE_TEST_ALL; + + return node_test; + } + + name = axiom_xpath_compile_ncname(env, expr); + + if(!name) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: NCName expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + AXIS2_FREE(env->allocator, node_test); + + return NULL; + } + + /* Node type */ + + if(AXIOM_XPATH_CURRENT == '(') + { + AXIOM_XPATH_READ(1); + + if(axutil_strcmp(name, "comment") == 0) + { + node_test->type = AXIOM_XPATH_NODE_TYPE_COMMENT; + } + if(axutil_strcmp(name, "node") == 0) + { + node_test->type = AXIOM_XPATH_NODE_TYPE_NODE; + } + if(axutil_strcmp(name, "processing-instruction") == 0) + { + node_test->type = AXIOM_XPATH_NODE_TYPE_PI; + + node_test->lit = axiom_xpath_compile_literal(env, expr); + } + if(axutil_strcmp(name, "text") == 0) + { + node_test->type = AXIOM_XPATH_NODE_TYPE_TEXT; + } + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(node_test->type == AXIOM_XPATH_NODE_TEST_NONE || AXIOM_XPATH_CURRENT != ')') + { +#ifdef AXIOM_XPATH_DEBUG + printf("Parse error: Invalid node type - %s\n", name); +#endif + + AXIS2_FREE(env->allocator, node_test); + + return NULL; + } + + AXIOM_XPATH_READ(1); + } + else + { + node_test->type = AXIOM_XPATH_NODE_TEST_STANDARD; + + if(AXIOM_XPATH_CURRENT == ':') + { + AXIOM_XPATH_READ(1); + + node_test->prefix = name; + + if(AXIOM_XPATH_CURRENT == '*') + { + AXIOM_XPATH_READ(1); + + node_test->type = AXIOM_XPATH_NODE_TEST_ALL; + + return node_test; + } + + node_test->name = axiom_xpath_compile_ncname(env, expr); + + if(!node_test->name) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: NCName expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + AXIS2_FREE(env->allocator, node_test); + + return NULL; + } + } + else + { + node_test->name = name; + } + } + + return node_test; +} + +int +axiom_xpath_compile_function_call( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + axis2_char_t *name; + int op1 = AXIOM_XPATH_PARSE_END; + + name = axiom_xpath_compile_ncname(env, expr); + + if(!name) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: NCName expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + if(AXIOM_XPATH_CURRENT != '(') + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: '(' expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_READ(1); + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(AXIOM_XPATH_CURRENT != ')') + { + op1 = axiom_xpath_compile_argument(env, expr); + } + + if(AXIOM_XPATH_CURRENT != ')') + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: ')' expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_READ(1); + + return AXIOM_XPATH_PUSH_PAR(AXIOM_XPATH_OPERATION_FUNCTION_CALL, name, NULL, op1); +} + +int +axiom_xpath_compile_argument( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op1 = AXIOM_XPATH_PARSE_END; + int op2 = AXIOM_XPATH_PARSE_END; + + op1 = axiom_xpath_compile_orexpr(env, expr); + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(AXIOM_XPATH_CURRENT == ',') + { + op2 = axiom_xpath_compile_argument(env, expr); + } + + return AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_ARGUMENT, op1, op2); +} + +axiom_xpath_node_test_t* +axiom_xpath_create_node_test_all( + const axutil_env_t *env) +{ + axiom_xpath_node_test_t *node_test; + + node_test = AXIS2_MALLOC(env->allocator, sizeof(axiom_xpath_node_test_t)); + node_test->type = AXIOM_XPATH_NODE_TEST_ALL; + node_test->prefix = NULL; + node_test->name = NULL; + node_test->lit = NULL; + + return node_test; +} + +axiom_xpath_node_test_t* +axiom_xpath_create_node_test_node( + const axutil_env_t *env) +{ + axiom_xpath_node_test_t *node_test; + + node_test = AXIS2_MALLOC(env->allocator, sizeof(axiom_xpath_node_test_t)); + node_test->type = AXIOM_XPATH_NODE_TYPE_NODE; + node_test->prefix = NULL; + node_test->name = NULL; + node_test->lit = NULL; + + return node_test; +} + +double* +axiom_xpath_compile_number( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + double *ret = AXIS2_MALLOC(env->allocator, sizeof(double)); + double res = 0, dec = 0.1; + axis2_bool_t dot = AXIS2_FALSE; + + *ret = 0; + + while(1) + { + if(isdigit(AXIOM_XPATH_CURRENT)) + { + if(!dot) + { + res = res * 10 + (AXIOM_XPATH_CURRENT - '0'); + } + else + { + res += dec * (AXIOM_XPATH_CURRENT - '0'); + dec /= 10; + } + } + else if(AXIOM_XPATH_CURRENT == '.') + { + if(dot) + { + return ret; + } + else + { + dot = AXIS2_TRUE; + dec = 0.1; + } + } + else + { + break; + } + + AXIOM_XPATH_READ(1); + } + + *ret = res; + return ret; +} + +axis2_char_t* +axiom_xpath_compile_literal( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + axis2_char_t lit[255]; + int i = 0; + axis2_char_t del; + + if(AXIOM_XPATH_CURRENT == '\"') + { + del = '\"'; + } + else if(AXIOM_XPATH_CURRENT == '\'') + { + del = '\''; + } + else + return NULL; + + AXIOM_XPATH_READ(1); + + while(AXIOM_XPATH_HAS_MORE && AXIOM_XPATH_CURRENT != del) + { + lit[i] = AXIOM_XPATH_CURRENT; + AXIOM_XPATH_READ(1); + ++i; + } + + if(AXIOM_XPATH_HAS_MORE) + { + AXIOM_XPATH_READ(1); + } + + lit[i] = '\0'; + + return axutil_strdup(env, lit); + +} + +/* Get axis for name */ +axiom_xpath_axis_t +axiom_xpath_get_axis( + const axutil_env_t *env, + axis2_char_t* name) +{ + if(axutil_strcmp(name, "child") == 0) + { + return AXIOM_XPATH_AXIS_CHILD; + } + else if(axutil_strcmp(name, "descendant") == 0) + { + return AXIOM_XPATH_AXIS_DESCENDANT; + } + else if(axutil_strcmp(name, "parent") == 0) + { + return AXIOM_XPATH_AXIS_PARENT; + } + else if(axutil_strcmp(name, "ancestor") == 0) + { + return AXIOM_XPATH_AXIS_ANCESTOR; + } + else if(axutil_strcmp(name, "following-sibling") == 0) + { + return AXIOM_XPATH_AXIS_FOLLOWING_SIBLING; + } + else if(axutil_strcmp(name, "preceding-sibling") == 0) + { + return AXIOM_XPATH_AXIS_PRECEDING_SIBLING; + } + else if(axutil_strcmp(name, "following") == 0) + { + return AXIOM_XPATH_AXIS_FOLLOWING; + } + else if(axutil_strcmp(name, "preceding") == 0) + { + return AXIOM_XPATH_AXIS_PRECEDING; + } + else if(axutil_strcmp(name, "attribute") == 0) + { + return AXIOM_XPATH_AXIS_ATTRIBUTE; + } + else if(axutil_strcmp(name, "namespace") == 0) + { + return AXIOM_XPATH_AXIS_NAMESPACE; + } + else if(axutil_strcmp(name, "self") == 0) + { + return AXIOM_XPATH_AXIS_SELF; + } + else if(axutil_strcmp(name, "descendant-or-self") == 0) + { + return AXIOM_XPATH_AXIS_DESCENDANT_OR_SELF; + } + else if(axutil_strcmp(name, "ancestor-or-self") == 0) + { + return AXIOM_XPATH_AXIS_ANCESTOR_OR_SELF; + } + else + { +#ifdef AXIOM_XPATH_DEBUG + printf("Unidentified axis name.\n"); +#endif + + return AXIOM_XPATH_AXIS_NONE; + } +} + +/* Parse Predicate */ +int +axiom_xpath_compile_predicate( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + int op1, op_next_predicate; + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(!AXIOM_XPATH_HAS_MORE || AXIOM_XPATH_CURRENT != '[') + { + return AXIOM_XPATH_PARSE_END; + } + + AXIOM_XPATH_READ(1); + AXIOM_XPATH_SKIP_WHITESPACES; + + /* A PredicateExpr is evaluated by evaluating the Expr and converting the result to a boolean. + If the result is a number, the result will be converted to true if the number is equal to the + context position and will be converted to false otherwise; if the result is not a number, + then the result will be converted as if by a call to the boolean function. */ + + op1 = axiom_xpath_compile_orexpr(env, expr); + + if(op1 == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: EqualExpr expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_SKIP_WHITESPACES; + + if(AXIOM_XPATH_CURRENT != ']') + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: ] expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + AXIOM_XPATH_READ(1); + + op_next_predicate = axiom_xpath_compile_predicate(env, expr); + + if(op_next_predicate == AXIOM_XPATH_PARSE_ERROR) + { +#ifdef AXIOM_XPATH_DEBUG + printf( + "Parse error: Predicate expected - %s\n", + expr->expr_str + expr->expr_ptr); +#endif + + return AXIOM_XPATH_PARSE_ERROR; + } + + return AXIOM_XPATH_PUSH(AXIOM_XPATH_OPERATION_PREDICATE, op1, op_next_predicate); +} + +/* Parse Node Test */ +axis2_char_t * +axiom_xpath_compile_ncname( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + axis2_char_t name[255]; + int i = 0; + + if(!isalpha(AXIOM_XPATH_CURRENT) && AXIOM_XPATH_CURRENT != '_') + { + return NULL; + } + + /* TODO: Add CombiningChar and Extender + * Link http://www.w3.org/TR/REC-xml/#NT-NameChar */ + while(AXIOM_XPATH_HAS_MORE && (isalnum(AXIOM_XPATH_CURRENT) || AXIOM_XPATH_CURRENT == '_' + || AXIOM_XPATH_CURRENT == '.' || AXIOM_XPATH_CURRENT == '-')) + { + name[i] = AXIOM_XPATH_CURRENT; + AXIOM_XPATH_READ(1); + ++i; + } + + name[i] = '\0'; + + return axutil_strdup(env, name); +} + +/* Supporting functions */ +int +axiom_xpath_add_operation( + const axutil_env_t *env, + axiom_xpath_expression_t* expr, + axiom_xpath_operation_type_t op_type, + int op1, + int op2, + void *par1, + void *par2) +{ + axiom_xpath_operation_t *op; + + op = AXIS2_MALLOC(env->allocator, sizeof(axiom_xpath_operation_t)); + op->opr = op_type; + op->op1 = op1; + op->op2 = op2; + + op->pos = 0; + + op->par1 = par1; + op->par2 = par2; + + axutil_array_list_add(expr->operations, env, op); + + return axutil_array_list_size(expr->operations, env) - 1; +} + +axiom_xpath_axis_t * +axiom_xpath_create_axis( + const axutil_env_t *env, + axiom_xpath_axis_t axis) +{ + axiom_xpath_axis_t *axis_p = AXIS2_MALLOC(env->allocator, sizeof(axiom_xpath_axis_t)); + + *axis_p = axis; + return axis_p; +} |