path OPTIMIZE manual path reparse
Refs #2007
diff --git a/src/path.c b/src/path.c
index 4ee9832..cfa934f 100644
--- a/src/path.c
+++ b/src/path.c
@@ -109,6 +109,11 @@
/* '=' */
LY_CHECK_GOTO(lyxp_next_token(ctx, exp, tok_idx, LYXP_TOKEN_OPER_EQUAL), token_error);
+ /* fill repeat */
+ exp->repeat[*tok_idx - 2] = calloc(2, sizeof *exp->repeat[*tok_idx]);
+ LY_CHECK_ERR_GOTO(!exp->repeat[*tok_idx - 2], LOGMEM(NULL); ret = LY_EMEM, cleanup);
+ exp->repeat[*tok_idx - 2][0] = LYXP_EXPR_EQUALITY;
+
/* Literal, Number, or VariableReference */
if (lyxp_next_token(NULL, exp, tok_idx, LYXP_TOKEN_LITERAL) &&
lyxp_next_token(NULL, exp, tok_idx, LYXP_TOKEN_NUMBER) &&
@@ -130,6 +135,11 @@
/* '=' */
LY_CHECK_GOTO(lyxp_next_token(ctx, exp, tok_idx, LYXP_TOKEN_OPER_EQUAL), token_error);
+ /* fill repeat */
+ exp->repeat[*tok_idx - 2] = calloc(2, sizeof *exp->repeat[*tok_idx]);
+ LY_CHECK_ERR_GOTO(!exp->repeat[*tok_idx - 2], LOGMEM(NULL); ret = LY_EMEM, cleanup);
+ exp->repeat[*tok_idx - 2][0] = LYXP_EXPR_EQUALITY;
+
/* Literal or Number */
LY_CHECK_GOTO(lyxp_next_token2(ctx, exp, tok_idx, LYXP_TOKEN_LITERAL, LYXP_TOKEN_NUMBER), token_error);
@@ -187,6 +197,11 @@
/* '=' */
LY_CHECK_GOTO(lyxp_next_token(ctx, exp, tok_idx, LYXP_TOKEN_OPER_EQUAL), token_error);
+ /* fill repeat */
+ exp->repeat[*tok_idx - 2] = calloc(2, sizeof *exp->repeat[*tok_idx]);
+ LY_CHECK_ERR_GOTO(!exp->repeat[*tok_idx - 2], LOGMEM(NULL); ret = LY_EMEM, cleanup);
+ exp->repeat[*tok_idx - 2][0] = LYXP_EXPR_EQUALITY;
+
/* FuncName */
LY_CHECK_GOTO(lyxp_check_token(ctx, exp, *tok_idx, LYXP_TOKEN_FUNCNAME), token_error);
if ((exp->tok_len[*tok_idx] != ly_strlen_const("current")) ||
@@ -266,10 +281,14 @@
LOG_LOCSET(ctx_node, NULL, NULL, NULL);
- /* parse as a generic XPath expression */
- LY_CHECK_GOTO(ret = lyxp_expr_parse(ctx, str_path, path_len, 1, &exp), error);
+ /* parse as a generic XPath expression, reparse is performed manually */
+ LY_CHECK_GOTO(ret = lyxp_expr_parse(ctx, str_path, path_len, 0, &exp), error);
tok_idx = 0;
+ /* alloc empty repeat (only '=', filled manually) */
+ exp->repeat = calloc(exp->size, sizeof *exp->repeat);
+ LY_CHECK_ERR_GOTO(!exp->repeat, LOGMEM(ctx); ret = LY_EMEM, error);
+
if (begin == LY_PATH_BEGIN_EITHER) {
/* is the path relative? */
if (lyxp_next_token(NULL, exp, &tok_idx, LYXP_TOKEN_OPER_PATH)) {
@@ -376,10 +395,14 @@
LOG_LOCSET(cur_node, NULL, NULL, NULL);
- /* parse as a generic XPath expression */
+ /* parse as a generic XPath expression, reparse is performed manually */
LY_CHECK_GOTO(ret = lyxp_expr_parse(ctx, str_path, path_len, 0, &exp), error);
tok_idx = 0;
+ /* alloc empty repeat (only '=', filled manually) */
+ exp->repeat = calloc(exp->size, sizeof *exp->repeat);
+ LY_CHECK_ERR_GOTO(!exp->repeat, LOGMEM(ctx); ret = LY_EMEM, error);
+
LY_CHECK_GOTO(ret = ly_path_check_predicate(ctx, cur_node, exp, &tok_idx, prefix, pred), error);
/* trailing token check */
diff --git a/tests/utests/schema/test_tree_schema_compile.c b/tests/utests/schema/test_tree_schema_compile.c
index e4ec983..09c63a3 100644
--- a/tests/utests/schema/test_tree_schema_compile.c
+++ b/tests/utests/schema/test_tree_schema_compile.c
@@ -1726,7 +1726,7 @@
path = "..[";
assert_int_equal(LY_EVALID, ly_path_parse(UTEST_LYCTX, NULL, path, strlen(path), 1, LY_PATH_BEGIN_EITHER,
LY_PATH_PREFIX_OPTIONAL, LY_PATH_PRED_LEAFREF, &expr));
- CHECK_LOG_CTX("Unparsed characters \"[\" left at the end of an XPath expression.", NULL);
+ CHECK_LOG_CTX("Unexpected XPath token \"[\" (\"[\"), expected \"Operator(Path)\".", NULL);
path = "../";
assert_int_equal(LY_EVALID, ly_path_parse(UTEST_LYCTX, NULL, path, strlen(path), 1, LY_PATH_BEGIN_EITHER,
@@ -2026,7 +2026,7 @@
"leaf address {type leafref{ path \"/interface[name = current()../ifname]/ip\";}}}",
LYS_IN_YANG, &mod));
CHECK_LOG_CTX("Parsing module \"tt\" failed.", NULL);
- CHECK_LOG_CTX("Unexpected XPath token \"..\" (\"../ifname]/ip\"), expected \"]\".", "Line number 4.");
+ CHECK_LOG_CTX("Unexpected XPath token \"..\" (\"../ifname]/ip\"), expected \"Operator(Path)\".", "Line number 4.");
assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module uu {namespace urn:uu;prefix uu;\n"
"list interface{key name;leaf name{type string;}leaf ip {type string;}}\n"
@@ -2050,7 +2050,7 @@
"leaf address {type leafref{ path \"/interface[name = current()/../]/ip\";}}}",
LYS_IN_YANG, &mod));
CHECK_LOG_CTX("Parsing module \"ww\" failed.", NULL);
- CHECK_LOG_CTX("Unexpected XPath token \"]\" (\"]/ip\").", "Line number 4.");
+ CHECK_LOG_CTX("Unexpected XPath token \"]\" (\"]/ip\"), expected \"NameTest\".", "Line number 4.");
assert_int_equal(LY_EVALID, lys_parse_mem(UTEST_LYCTX, "module xx {namespace urn:xx;prefix xx;\n"
"list interface{key name;leaf name{type string;}leaf ip {type string;}}\n"
diff --git a/tests/utests/types/instanceid.c b/tests/utests/types/instanceid.c
index b41e13e..4174e4d 100644
--- a/tests/utests/types/instanceid.c
+++ b/tests/utests/types/instanceid.c
@@ -214,7 +214,7 @@
"defs", "xmlns:m=\"urn:tests:mod\"", "l1", "[1]", LY_EVALID);
CHECK_LOG_CTX("Invalid instance-identifier \"[1]\" value - syntax error.",
"Schema location \"/defs:l1\", line number 1.");
- CHECK_LOG_CTX("Unexpected XPath token \"[\" (\"[1]\").",
+ CHECK_LOG_CTX("Unexpected XPath token \"[\" (\"[1]\"), expected \"Operator(Path)\".",
"Schema location \"/defs:l1\", line number 1.");
TEST_ERROR_XML2("<cont xmlns=\"urn:tests:mod\"><l2/></cont>",