path FEATURE support number key values in predicates
In addition to the more common literal.
diff --git a/src/path.c b/src/path.c
index baa3da8..0e787c4 100644
--- a/src/path.c
+++ b/src/path.c
@@ -108,8 +108,8 @@
/* '=' */
LY_CHECK_GOTO(lyxp_next_token(ctx, exp, tok_idx, LYXP_TOKEN_OPER_EQUAL), token_error);
- /* Literal */
- LY_CHECK_GOTO(lyxp_next_token(ctx, exp, tok_idx, LYXP_TOKEN_LITERAL), token_error);
+ /* Literal or Number */
+ LY_CHECK_GOTO(lyxp_next_token2(ctx, exp, tok_idx, LYXP_TOKEN_LITERAL, LYXP_TOKEN_NUMBER), token_error);
/* ']' */
LY_CHECK_GOTO(lyxp_next_token(ctx, exp, tok_idx, LYXP_TOKEN_BRACK2), token_error);
@@ -123,8 +123,8 @@
/* '=' */
LY_CHECK_GOTO(lyxp_next_token(ctx, exp, tok_idx, LYXP_TOKEN_OPER_EQUAL), token_error);
- /* Literal */
- LY_CHECK_GOTO(lyxp_next_token(ctx, exp, tok_idx, LYXP_TOKEN_LITERAL), token_error);
+ /* Literal or Number */
+ LY_CHECK_GOTO(lyxp_next_token2(ctx, exp, tok_idx, LYXP_TOKEN_LITERAL, LYXP_TOKEN_NUMBER), token_error);
/* ']' */
LY_CHECK_GOTO(lyxp_next_token(ctx, exp, tok_idx, LYXP_TOKEN_BRACK2), token_error);
@@ -568,8 +568,8 @@
struct ly_path_predicate *p;
const struct lysc_node *key;
const struct lys_module *mod = NULL;
- const char *name;
- size_t name_len, key_count;
+ const char *name, *val;
+ size_t name_len, val_len, key_count;
assert(ctx && ctx_node);
@@ -624,12 +624,21 @@
assert(expr->tokens[*tok_idx] == LYXP_TOKEN_OPER_EQUAL);
++(*tok_idx);
- /* Literal */
- assert(expr->tokens[*tok_idx] == LYXP_TOKEN_LITERAL);
+ /* Literal or Number */
+ assert((expr->tokens[*tok_idx] == LYXP_TOKEN_LITERAL) || (expr->tokens[*tok_idx] == LYXP_TOKEN_NUMBER));
+ if (expr->tokens[*tok_idx] == LYXP_TOKEN_LITERAL) {
+ /* skip quotes */
+ val = expr->expr + expr->tok_pos[*tok_idx] + 1;
+ val_len = expr->tok_len[*tok_idx] - 2;
+ } else {
+ val = expr->expr + expr->tok_pos[*tok_idx];
+ val_len = expr->tok_len[*tok_idx];
+ }
+
+ /* store the value */
LOG_LOCSET(key, NULL, NULL, NULL);
- ret = lyd_value_store(ctx, &p->value, ((struct lysc_node_leaf *)key)->type,
- expr->expr + expr->tok_pos[*tok_idx] + 1, expr->tok_len[*tok_idx] - 2, NULL, format, prefix_data,
- LYD_HINT_DATA, key, NULL);
+ ret = lyd_value_store(ctx, &p->value, ((struct lysc_node_leaf *)key)->type, val, val_len, NULL, format,
+ prefix_data, LYD_HINT_DATA, key, NULL);
LOG_LOCBACK(key ? 1 : 0, 0, 0, 0);
LY_CHECK_ERR_GOTO(ret, p->value.realtype = NULL, cleanup);
++(*tok_idx);
@@ -676,12 +685,21 @@
assert(expr->tokens[*tok_idx] == LYXP_TOKEN_OPER_EQUAL);
++(*tok_idx);
- assert(expr->tokens[*tok_idx] == LYXP_TOKEN_LITERAL);
+ /* Literal or Number */
+ assert((expr->tokens[*tok_idx] == LYXP_TOKEN_LITERAL) || (expr->tokens[*tok_idx] == LYXP_TOKEN_NUMBER));
+ if (expr->tokens[*tok_idx] == LYXP_TOKEN_LITERAL) {
+ /* skip quotes */
+ val = expr->expr + expr->tok_pos[*tok_idx] + 1;
+ val_len = expr->tok_len[*tok_idx] - 2;
+ } else {
+ val = expr->expr + expr->tok_pos[*tok_idx];
+ val_len = expr->tok_len[*tok_idx];
+ }
+
/* store the value */
LOG_LOCSET(ctx_node, NULL, NULL, NULL);
- ret = lyd_value_store(ctx, &p->value, ((struct lysc_node_leaflist *)ctx_node)->type,
- expr->expr + expr->tok_pos[*tok_idx] + 1, expr->tok_len[*tok_idx] - 2, NULL, format, prefix_data,
- LYD_HINT_DATA, ctx_node, NULL);
+ ret = lyd_value_store(ctx, &p->value, ((struct lysc_node_leaflist *)ctx_node)->type, val, val_len, NULL, format,
+ prefix_data, LYD_HINT_DATA, ctx_node, NULL);
LOG_LOCBACK(ctx_node ? 1 : 0, 0, 0, 0);
LY_CHECK_ERR_GOTO(ret, p->value.realtype = NULL, cleanup);
++(*tok_idx);
diff --git a/src/xpath.c b/src/xpath.c
index 5375431..7df3987 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -1920,6 +1920,18 @@
return LY_SUCCESS;
}
+LY_ERR
+lyxp_next_token2(const struct ly_ctx *ctx, const struct lyxp_expr *exp, uint16_t *tok_idx, enum lyxp_token want_tok1,
+ enum lyxp_token want_tok2)
+{
+ LY_CHECK_RET(exp_check_token2(ctx, exp, *tok_idx, want_tok1, want_tok2));
+
+ /* skip the token */
+ ++(*tok_idx);
+
+ return LY_SUCCESS;
+}
+
/**
* @brief Stack operation push on the repeat array.
*
diff --git a/src/xpath.h b/src/xpath.h
index dcb8fcc..5835a06 100644
--- a/src/xpath.h
+++ b/src/xpath.h
@@ -435,6 +435,21 @@
LY_ERR lyxp_next_token(const struct ly_ctx *ctx, const struct lyxp_expr *exp, uint16_t *tok_idx, enum lyxp_token want_tok);
/**
+ * @brief Look at the next token and skip it if it matches either of the 2 expected ones.
+ *
+ * @param[in] ctx Context for logging, not logged if NULL.
+ * @param[in] exp Expression to use.
+ * @param[in,out] tok_idx Token index in the expression \p exp, is updated.
+ * @param[in] want_tok1 Expected token 1.
+ * @param[in] want_tok2 Expected token 2.
+ * @return LY_EINCOMPLETE on EOF,
+ * @return LY_ENOT on non-matching token,
+ * @return LY_SUCCESS on success.
+ */
+LY_ERR lyxp_next_token2(const struct ly_ctx *ctx, const struct lyxp_expr *exp, uint16_t *tok_idx,
+ enum lyxp_token want_tok1, enum lyxp_token want_tok2);
+
+/**
* @brief Frees a parsed XPath expression. @p expr should not be used afterwards.
*
* @param[in] ctx libyang context of the expression.