libyang CHANGE extend input handler by line counter
So far, all the parsers were counting lines on their own, in the
parsers' specific variables. The patch unifies the place where the
line is counted and store it in the input handler.
diff --git a/src/in.c b/src/in.c
index 26f4226..8e8cf07 100644
--- a/src/in.c
+++ b/src/in.c
@@ -70,6 +70,7 @@
(*in)->type = LY_IN_FD;
(*in)->method.fd = fd;
(*in)->current = (*in)->start = (*in)->func_start = addr;
+ (*in)->line = 1;
(*in)->length = length;
return LY_SUCCESS;
@@ -97,6 +98,7 @@
in->method.fd = fd;
in->current = in->start = addr;
+ in->line = 1;
in->length = length;
}
@@ -154,6 +156,7 @@
(*in)->type = LY_IN_MEMORY;
(*in)->start = (*in)->current = (*in)->func_start = str;
+ (*in)->line = 1;
return LY_SUCCESS;
}
@@ -169,6 +172,7 @@
if (str) {
in->start = in->current = str;
+ in->line = 1;
}
return data;
@@ -180,6 +184,7 @@
LY_CHECK_ARG_RET(NULL, in, LY_EINVAL);
in->current = in->func_start = in->start;
+ in->line = 1;
return LY_SUCCESS;
}
@@ -344,6 +349,12 @@
return LY_EDENIED;
}
+ for (size_t i = 0; i < count; i++) {
+ if (in->current[i] == '\n') {
+ LY_IN_NEW_LINE(in);
+ }
+ }
+
memcpy(buf, in->current, count);
in->current += count;
return LY_SUCCESS;
@@ -363,6 +374,12 @@
return LY_EDENIED;
}
+ for (size_t i = 0; i < count; i++) {
+ if (in->current[i] == '\n') {
+ LY_IN_NEW_LINE(in);
+ }
+ }
+
in->current += count;
return LY_SUCCESS;
}
diff --git a/src/in_internal.h b/src/in_internal.h
index 684487f..11f33c3 100644
--- a/src/in_internal.h
+++ b/src/in_internal.h
@@ -35,9 +35,17 @@
char *filepath; /**< stored original filepath */
} fpath; /**< filepath structure for LY_IN_FILEPATH */
} method; /**< type-specific information about the output */
+ uint64_t line; /**< current line of the input */
};
/**
+ * @brief Increment line counter.
+ * @param[in] IN The input handler.
+ */
+#define LY_IN_NEW_LINE(IN) \
+ (IN)->line++
+
+/**
* @brief Read bytes from an input.
*
* @param[in] in Input structure.
diff --git a/src/json.c b/src/json.c
index f24b349..059cf88 100644
--- a/src/json.c
+++ b/src/json.c
@@ -71,10 +71,6 @@
{
/* skip leading whitespaces */
while (*jsonctx->in->current != '\0' && is_jsonws(*jsonctx->in->current)) {
- if (*jsonctx->in->current == '\n') {
- /* new line */
- jsonctx->line++;
- }
ly_in_skip(jsonctx->in, 1);
}
if (*jsonctx->in->current == '\0') {
@@ -119,7 +115,7 @@
return LY_SUCCESS;
}
} else {
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SYNTAX,
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SYNTAX,
"Unexpected character \"%c\" after JSON %s.", *jsonctx->in->current, lyjson_token2str(lyjson_ctx_status(jsonctx, 0)));
}
@@ -148,7 +144,7 @@
/* init */
start = in;
- start_line = jsonctx->line;
+ start_line = jsonctx->in->line;
offset = len = 0;
/* parse */
@@ -221,7 +217,7 @@
offset++;
for (value = i = 0; i < 4; i++) {
if (!in[offset + i]) {
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SYNTAX,
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SYNTAX,
"Invalid basic multilingual plane character \"%s\".", &in[slash]);
goto error;
} else if (isdigit(in[offset + i])) {
@@ -236,7 +232,7 @@
break;
default:
/* invalid escape sequence */
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SYNTAX,
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SYNTAX,
"Invalid character escape sequence \\%c.", in[offset]);
goto error;
@@ -244,7 +240,7 @@
offset += i; /* add read escaped characters */
LY_CHECK_ERR_GOTO(ly_pututf8(&buf[len], value, &u),
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SYNTAX,
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SYNTAX,
"Invalid character reference \"%.*s\" (0x%08x).", offset - slash, &in[slash], value),
error);
len += u; /* update number of bytes in buffer */
@@ -274,10 +270,10 @@
size_t code_len = 0;
LY_CHECK_ERR_GOTO(ly_getutf8(&c, &code, &code_len),
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_INCHAR, in[offset]), error);
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_INCHAR, in[offset]), error);
LY_CHECK_ERR_GOTO(!is_jsonstrchar(code),
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SYNTAX,
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SYNTAX,
"Invalid character in JSON string \"%.*s\" (0x%08x).", &in[offset] - start + code_len, start, code),
error);
@@ -287,7 +283,7 @@
}
/* EOF reached before endchar */
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_EOF);
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_EOF);
LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &start_line, LYVE_SYNTAX, "Missing quotation-mark at the end of a JSON string.");
error:
@@ -295,7 +291,7 @@
return LY_EVALID;
success:
- ly_in_skip(jsonctx->in, in - jsonctx->in->current);
+ jsonctx->in->current = in;
if (buf) {
lyjson_ctx_set_value(jsonctx, buf, len, 1);
} else {
@@ -345,9 +341,9 @@
} else {
invalid_character:
if (in[offset]) {
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SYNTAX, "Invalid character in JSON Number value (\"%c\").", in[offset]);
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SYNTAX, "Invalid character in JSON Number value (\"%c\").", in[offset]);
} else {
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_EOF);
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_EOF);
}
return LY_EVALID;
}
@@ -386,7 +382,7 @@
errno = 0;
e_val = strtol(e_ptr, &ptr, LY_BASE_DEC);
if (errno) {
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SEMANTICS,
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SEMANTICS,
"Exponent out-of-bounds in a JSON Number value (%.*s).", offset - minus - (e_ptr - in), e_ptr);
return LY_EVALID;
}
@@ -488,7 +484,7 @@
lyjson_object_name(struct lyjson_ctx *jsonctx)
{
if (*jsonctx->in->current != '"') {
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
jsonctx->in->current, "a JSON object's member");
return LY_EVALID;
}
@@ -497,7 +493,7 @@
LY_CHECK_RET(lyjson_string_(jsonctx));
LY_CHECK_RET(skip_ws(jsonctx));
if (*jsonctx->in->current != ':') {
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_INSTREXP,
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_INSTREXP,
LY_VCODE_INSTREXP_len(jsonctx->in->current), jsonctx->in->current, "a JSON object's name-separator ':'");
return LY_EVALID;
}
@@ -604,7 +600,7 @@
} else {
/* unexpected value */
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
jsonctx->in->current, "a JSON value");
return LY_EVALID;
}
@@ -626,7 +622,6 @@
jsonctx = calloc(1, sizeof *jsonctx);
LY_CHECK_ERR_RET(!jsonctx, LOGMEM(ctx), LY_EMEM);
jsonctx->ctx = ctx;
- jsonctx->line = 1;
jsonctx->in = in;
/* parse JSON value, if any */
@@ -639,7 +634,7 @@
ret = lyjson_value(jsonctx);
if ((jsonctx->status.count > 1) && (lyjson_ctx_status(jsonctx, 0) == LYJSON_END)) {
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_EOF);
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_EOF);
ret = LY_EVALID;
}
@@ -710,7 +705,7 @@
LY_CHECK_RET(skip_ws(jsonctx));
if (toplevel && !jsonctx->status.count) {
/* EOF expected, but there are some data after the top level token */
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LYVE_SYNTAX,
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LYVE_SYNTAX,
"Expecting end-of-input, but some data follows the top level JSON value.");
return LY_EVALID;
}
@@ -741,14 +736,14 @@
JSON_PUSH_STATUS_RET(jsonctx, prev + 1);
} else {
/* unexpected value */
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(jsonctx->in->current),
jsonctx->in->current, prev == LYJSON_ARRAY ? "another JSON value in array" : "another JSON object's member");
return LY_EVALID;
}
result:
if ((ret == LY_SUCCESS) && (jsonctx->status.count > 1) && (lyjson_ctx_status(jsonctx, 0) == LYJSON_END)) {
- LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->line, LY_VCODE_EOF);
+ LOGVAL(jsonctx->ctx, LY_VLOG_LINE, &jsonctx->in->line, LY_VCODE_EOF);
ret = LY_EVALID;
}
diff --git a/src/json.h b/src/json.h
index 5adac03..ba22884 100644
--- a/src/json.h
+++ b/src/json.h
@@ -52,7 +52,6 @@
struct lyjson_ctx {
const struct ly_ctx *ctx;
- uint64_t line; /* current line */
struct ly_in *in; /* input structure */
struct ly_set status; /* stack of LYJSON_PARSER_STATUS values corresponding to the JSON items being processed */
diff --git a/src/parser_json.c b/src/parser_json.c
index 241ce99..da65f2f 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -25,7 +25,6 @@
#include "in_internal.h"
#include "json.h"
#include "log.h"
-#include "parser_data.h"
#include "parser_internal.h"
#include "set.h"
#include "tree.h"
@@ -1300,7 +1299,7 @@
{
LY_ERR ret = LY_SUCCESS;
struct lyd_json_ctx *lydctx;
- size_t i, line = 1;
+ size_t i;
assert(lydctx_p);
assert(status);
@@ -1316,7 +1315,7 @@
for (i = 0; in->current[i] != '\0' && is_jsonws(in->current[i]); i++) {
if (in->current[i] == '\n') {
/* new line */
- line++;
+ LY_IN_NEW_LINE(in);
}
}
@@ -1327,7 +1326,7 @@
return LY_SUCCESS;
} else {
/* expecting top-level object */
- LOGVAL(ctx, LY_VLOG_LINE, &line, LYVE_SYNTAX_JSON, "Expected top-level JSON object, but %s found.",
+ LOGVAL(ctx, LY_VLOG_LINE, &in->line, LYVE_SYNTAX_JSON, "Expected top-level JSON object, but %s found.",
lyjson_token2str(*status));
*lydctx_p = NULL;
lyd_json_ctx_free((struct lyd_ctx *)lydctx);
@@ -1503,7 +1502,7 @@
ret = LY_EVALID;
goto cleanup;
} else if (lydctx->jsonctx->in->current[0] && (lyjson_ctx_status(lydctx->jsonctx, 0) != LYJSON_OBJECT_CLOSED)) {
- LOGVAL(ctx, LY_VLOG_LINE, &lydctx->jsonctx->line, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
+ LOGVAL(ctx, LY_VLOG_LINE, &lydctx->jsonctx->in->line, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
tree->schema->name);
ret = LY_EVALID;
goto cleanup;
@@ -1647,7 +1646,7 @@
ret = LY_EVALID;
goto cleanup;
} else if (lydctx->jsonctx->in->current[0] && (lyjson_ctx_status(lydctx->jsonctx, 0) != LYJSON_OBJECT_CLOSED)) {
- LOGVAL(ctx, LY_VLOG_LINE, &lydctx->jsonctx->line, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
+ LOGVAL(ctx, LY_VLOG_LINE, &lydctx->jsonctx->in->line, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
tree->schema->name);
ret = LY_EVALID;
goto cleanup;
diff --git a/src/parser_stmt.c b/src/parser_stmt.c
index 5cca207..1ba3cdf 100644
--- a/src/parser_stmt.c
+++ b/src/parser_stmt.c
@@ -22,6 +22,7 @@
#include "common.h"
#include "dict.h"
#include "in.h"
+#include "in_internal.h"
#include "log.h"
#include "parser_schema.h"
#include "path.h"
@@ -126,7 +127,7 @@
for (child = stmt->child; child; child = child->next) {
struct ly_in *in;
LY_CHECK_RET(ly_in_new_memory(child->stmt, &in));
- enum ly_stmt kw = lysp_match_kw(NULL, in);
+ enum ly_stmt kw = lysp_match_kw(in, NULL);
ly_in_free(in, 0);
switch (kw) {
@@ -170,7 +171,7 @@
for (child = stmt->child; child; child = child->next) {
struct ly_in *in;
LY_CHECK_RET(ly_in_new_memory(child->stmt, &in));
- enum ly_stmt kw = lysp_match_kw(NULL, in);
+ enum ly_stmt kw = lysp_match_kw(in, NULL);
ly_in_free(in, 0);
switch (kw) {
@@ -213,7 +214,7 @@
for (child = stmt->child; child; child = child->next) {
struct ly_in *in;
LY_CHECK_RET(ly_in_new_memory(child->stmt, &in));
- enum ly_stmt kw = lysp_match_kw(NULL, in);
+ enum ly_stmt kw = lysp_match_kw(in, NULL);
ly_in_free(in, 0);
switch (kw) {
@@ -265,7 +266,7 @@
for (child = stmt->child; child; child = child->next) {
struct ly_in *in;
LY_CHECK_RET(ly_in_new_memory(child->stmt, &in));
- enum ly_stmt kw = lysp_match_kw(NULL, in);
+ enum ly_stmt kw = lysp_match_kw(in, NULL);
ly_in_free(in, 0);
switch (kw) {
@@ -302,7 +303,7 @@
for (child = stmt->child; child; child = child->next) {
struct ly_in *in;
LY_CHECK_RET(ly_in_new_memory(child->stmt, &in));
- enum ly_stmt kw = lysp_match_kw(NULL, in);
+ enum ly_stmt kw = lysp_match_kw(in, NULL);
ly_in_free(in, 0);
switch (kw) {
@@ -416,7 +417,7 @@
for (child = stmt->child; child; child = child->next) {
struct ly_in *in;
LY_CHECK_RET(ly_in_new_memory(child->stmt, &in));
- enum ly_stmt kw = lysp_match_kw(NULL, in);
+ enum ly_stmt kw = lysp_match_kw(in, NULL);
ly_in_free(in, 0);
switch (kw) {
@@ -464,7 +465,7 @@
for (child = stmt->child; child; child = child->next) {
struct ly_in *in;
LY_CHECK_RET(ly_in_new_memory(child->stmt, &in));
- enum ly_stmt kw = lysp_match_kw(NULL, in);
+ enum ly_stmt kw = lysp_match_kw(in, NULL);
ly_in_free(in, 0);
switch (kw) {
@@ -548,7 +549,7 @@
for (child = stmt->child; child; child = child->next) {
struct ly_in *in;
LY_CHECK_RET(ly_in_new_memory(child->stmt, &in));
- enum ly_stmt kw = lysp_match_kw(NULL, in);
+ enum ly_stmt kw = lysp_match_kw(in, NULL);
ly_in_free(in, 0);
switch (kw) {
@@ -599,7 +600,7 @@
for (child = stmt->child; child; child = child->next) {
struct ly_in *in;
LY_CHECK_RET(ly_in_new_memory(child->stmt, &in));
- enum ly_stmt kw = lysp_match_kw(NULL, in);
+ enum ly_stmt kw = lysp_match_kw(in, NULL);
ly_in_free(in, 0);
switch (kw) {
@@ -656,7 +657,7 @@
for (child = stmt->child; child; child = child->next) {
struct ly_in *in;
LY_CHECK_RET(ly_in_new_memory(child->stmt, &in));
- enum ly_stmt kw = lysp_match_kw(NULL, in);
+ enum ly_stmt kw = lysp_match_kw(in, NULL);
ly_in_free(in, 0);
switch (kw) {
@@ -704,7 +705,7 @@
for (child = stmt->child; child; child = child->next) {
struct ly_in *in;
LY_CHECK_RET(ly_in_new_memory(child->stmt, &in));
- enum ly_stmt kw = lysp_match_kw(NULL, in);
+ enum ly_stmt kw = lysp_match_kw(in, NULL);
ly_in_free(in, 0);
switch (kw) {
@@ -762,7 +763,7 @@
for (child = stmt->child; child; child = child->next) {
struct ly_in *in;
LY_CHECK_RET(ly_in_new_memory(child->stmt, &in));
- enum ly_stmt kw = lysp_match_kw(NULL, in);
+ enum ly_stmt kw = lysp_match_kw(in, NULL);
ly_in_free(in, 0);
switch (kw) {
diff --git a/src/parser_xml.c b/src/parser_xml.c
index c350395..15577c2 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -79,7 +79,7 @@
/* in XML, all attributes must be prefixed
* TODO exception for NETCONF filters which are supposed to map to the ietf-netconf without prefix */
if (lydctx->parse_options & LYD_PARSE_STRICT) {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Missing mandatory prefix for XML metadata \"%.*s\".",
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Missing mandatory prefix for XML metadata \"%.*s\".",
xmlctx->name_len, xmlctx->name);
goto cleanup;
}
@@ -95,7 +95,7 @@
ns = lyxml_ns_get(&xmlctx->ns, xmlctx->prefix, xmlctx->prefix_len);
if (!ns) {
/* unknown namespace, XML error */
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
xmlctx->prefix_len, xmlctx->prefix);
goto cleanup;
}
@@ -103,7 +103,7 @@
if (!mod) {
/* module is not implemented or not present in the schema */
if (lydctx->parse_options & LYD_PARSE_STRICT) {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE,
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE,
"Unknown (or not implemented) YANG module with namespace \"%s\" for metadata \"%.*s%s%.*s\".",
ns->uri, xmlctx->prefix_len, xmlctx->prefix, xmlctx->prefix_len ? ":" : "", xmlctx->name_len,
xmlctx->name);
@@ -157,7 +157,7 @@
/* get namespace of the attribute */
ns = lyxml_ns_get(&xmlctx->ns, xmlctx->prefix, xmlctx->prefix_len);
if (!ns) {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
xmlctx->prefix_len, xmlctx->prefix);
ret = LY_EVALID;
goto cleanup;
@@ -402,7 +402,7 @@
/* get the element module */
ns = lyxml_ns_get(&xmlctx->ns, prefix, prefix_len);
if (!ns) {
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
prefix_len, prefix);
ret = LY_EVALID;
goto error;
@@ -410,7 +410,7 @@
mod = ly_ctx_get_module_implemented_ns(ctx, ns->uri);
if (!mod) {
if (lydctx->parse_options & LYD_PARSE_STRICT) {
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "No module with namespace \"%s\" in the context.",
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "No module with namespace \"%s\" in the context.",
ns->uri);
ret = LY_EVALID;
goto error;
@@ -431,7 +431,7 @@
snode = lys_find_child(parent ? parent->schema : NULL, mod, name, name_len, 0, getnext_opts);
if (!snode) {
if (lydctx->parse_options & LYD_PARSE_STRICT) {
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Element \"%.*s\" not found in the \"%s\" module.",
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Element \"%.*s\" not found in the \"%s\" module.",
name_len, name, mod->name);
ret = LY_EVALID;
goto error;
@@ -498,7 +498,7 @@
anchor = lyd_insert_get_next_anchor(parent->child, node);
if (anchor && (anchor->schema->flags & LYS_KEY)) {
if (lydctx->parse_options & LYD_PARSE_STRICT) {
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_DATA, "Invalid position of the key \"%s\" in a list.",
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_DATA, "Invalid position of the key \"%s\" in a list.",
node->schema->name);
ret = LY_EVALID;
goto error;
@@ -513,7 +513,7 @@
/* no children expected */
if (xmlctx->status == LYXML_ELEMENT) {
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Child element \"%.*s\" inside a terminal node \"%s\" found.",
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Child element \"%.*s\" inside a terminal node \"%s\" found.",
xmlctx->name_len, xmlctx->name, snode->name);
ret = LY_EVALID;
goto error;
@@ -521,7 +521,7 @@
} else if (snode->nodetype & LYD_NODE_INNER) {
if (!xmlctx->ws_only) {
/* value in inner node */
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Text value \"%.*s\" inside an inner node \"%s\" found.",
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Text value \"%.*s\" inside an inner node \"%s\" found.",
xmlctx->value_len, xmlctx->value, snode->name);
ret = LY_EVALID;
goto error;
@@ -563,7 +563,7 @@
} else if (snode->nodetype & LYD_NODE_ANY) {
if (!xmlctx->ws_only) {
/* value in inner node */
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Text value \"%.*s\" inside an any node \"%s\" found.",
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Text value \"%.*s\" inside an any node \"%s\" found.",
xmlctx->value_len, xmlctx->value, snode->name);
ret = LY_EVALID;
goto error;
@@ -752,7 +752,7 @@
ret = LY_EVALID;
goto cleanup;
} else if (lydctx.xmlctx->status == LYXML_ELEMENT) {
- LOGVAL(ctx, LY_VLOG_LINE, &lydctx.xmlctx->line, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
+ LOGVAL(ctx, LY_VLOG_LINE, &lydctx.xmlctx->in->line, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
tree->schema->name);
ret = LY_EVALID;
goto cleanup;
@@ -800,7 +800,7 @@
/* child "eventTime" */
if ((xmlctx->status != LYXML_ELEMENT) || ly_strncmp("eventTime", xmlctx->name, xmlctx->name_len)) {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Missing the \"eventTime\" element.");
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Missing the \"eventTime\" element.");
ret = LY_EVALID;
goto cleanup;
}
@@ -809,12 +809,12 @@
prefix_len = xmlctx->prefix_len;
ns = lyxml_ns_get(&xmlctx->ns, prefix, prefix_len);
if (!ns) {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Unknown XML prefix \"%.*s\".",
prefix_len, prefix);
ret = LY_EVALID;
goto cleanup;
} else if (strcmp(ns->uri, "urn:ietf:params:xml:ns:netconf:notification:1.0")) {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_REFERENCE, "Invalid namespace \"%s\" of \"eventTime\".",
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_REFERENCE, "Invalid namespace \"%s\" of \"eventTime\".",
ns->uri);
ret = LY_EVALID;
goto cleanup;
@@ -852,7 +852,7 @@
LY_CHECK_GOTO(ret = lyxml_ctx_next(xmlctx), cleanup);
if (xmlctx->status != LYXML_ELEM_CLOSE) {
assert(xmlctx->status == LYXML_ELEMENT);
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Unexpected sibling element \"%.*s\" of \"eventTime\".",
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Unexpected sibling element \"%.*s\" of \"eventTime\".",
xmlctx->name_len, xmlctx->name);
ret = LY_EVALID;
goto cleanup;
@@ -895,7 +895,7 @@
ret = LY_EVALID;
goto cleanup;
} else if (lydctx.xmlctx->status == LYXML_ELEMENT) {
- LOGVAL(ctx, LY_VLOG_LINE, &lydctx.xmlctx->line, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
+ LOGVAL(ctx, LY_VLOG_LINE, &lydctx.xmlctx->in->line, LYVE_SYNTAX, "Unexpected sibling element of \"%s\".",
tree->schema->name);
ret = LY_EVALID;
goto cleanup;
diff --git a/src/parser_yang.c b/src/parser_yang.c
index da537a0..0019403 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -50,7 +50,7 @@
* @param[in] CTX yang parser context to update its indent value.
* @param[in] COUNT number of items for which the DATA pointer is supposed to move on.
*/
-#define MOVE_INPUT(CTX, COUNT) ly_in_skip(CTX->in, COUNT);(CTX)->indent+=COUNT
+#define MOVE_INPUT(CTX, COUNT) ly_in_skip((CTX)->in, COUNT);(CTX)->indent+=COUNT
/**
* @brief Loop through all substatements providing, return if there are none.
@@ -232,14 +232,14 @@
case COMMENT_LINE:
if (ctx->in->current[0] == '\n') {
comment = COMMENT_NO;
- ++ctx->line;
+ LY_IN_NEW_LINE(ctx->in);
}
break;
case COMMENT_BLOCK:
if (ctx->in->current[0] == '*') {
comment = COMMENT_BLOCK_END;
} else if (ctx->in->current[0] == '\n') {
- ++ctx->line;
+ LY_IN_NEW_LINE(ctx->in);
}
break;
case COMMENT_BLOCK_END:
@@ -247,7 +247,7 @@
comment = COMMENT_NO;
} else if (ctx->in->current[0] != '*') {
if (ctx->in->current[0] == '\n') {
- ++ctx->line;
+ LY_IN_NEW_LINE(ctx->in);
}
comment = COMMENT_BLOCK;
}
@@ -407,9 +407,6 @@
/* check and store character */
LY_CHECK_RET(buf_store_char(ctx, arg, word_p, word_len, word_b, buf_len, need_buf, &prefix));
- /* maintain line number */
- ++ctx->line;
-
/* reset context indentation counter for possible string after this one */
ctx->indent = 0;
trailing_ws = 0;
@@ -458,8 +455,6 @@
need_buf = 1;
break;
case '\n':
- ++ctx->line;
- /* fall through */
case ' ':
case '\t':
/* just skip */
@@ -473,8 +468,6 @@
case STRING_PAUSED_CONTINUE:
switch (ctx->in->current[0]) {
case '\n':
- ++ctx->line;
- /* fall through */
case ' ':
case '\t':
/* skip */
@@ -591,13 +584,10 @@
/* word is finished */
goto str_end;
}
+ MOVE_INPUT(ctx, 1);
+
/* reset indent */
ctx->indent = 0;
-
- /* track line numbers */
- ++ctx->line;
-
- ++ctx->in->current;
break;
case ';':
case '{':
@@ -677,7 +667,6 @@
continue;
case '\n':
/* skip whitespaces (optsep) */
- ++ctx->line;
ctx->indent = 0;
break;
case ' ':
@@ -698,7 +687,7 @@
keyword_start:
word_start = ctx->in->current;
- *kw = lysp_match_kw(ctx, ctx->in);
+ *kw = lysp_match_kw(ctx->in, &ctx->indent);
if ((*kw == LY_STMT_SYNTAX_SEMICOLON) || (*kw == LY_STMT_SYNTAX_LEFT_BRACE) || (*kw == LY_STMT_SYNTAX_RIGHT_BRACE)) {
goto success;
@@ -735,8 +724,8 @@
/* still can be an extension */
prefix = 0;
extension:
- while (ctx->in->current[0] && (ctx->in->current[0] != ' ') && (ctx->in->current[0] != '\t') && (ctx->in->current[0] != '\n') &&
- (ctx->in->current[0] != '{') && (ctx->in->current[0] != ';')) {
+ while (ctx->in->current[0] && (ctx->in->current[0] != ' ') && (ctx->in->current[0] != '\t') &&
+ (ctx->in->current[0] != '\n') && (ctx->in->current[0] != '{') && (ctx->in->current[0] != ';')) {
uint32_t c = 0;
LY_CHECK_ERR_RET(ly_getutf8(&ctx->in->current, &c, &len),
@@ -4490,7 +4479,6 @@
(*context)->unres = main_ctx->unres;
(*context)->pos_type = LY_VLOG_LINE;
(*context)->in = in;
- (*context)->line = 1;
mod_p = calloc(1, sizeof *mod_p);
LY_CHECK_ERR_GOTO(!mod_p, LOGMEM(ly_ctx); ret = LY_EMEM, cleanup);
@@ -4562,7 +4550,6 @@
(*context)->unres = unres;
(*context)->pos_type = LY_VLOG_LINE;
(*context)->in = in;
- (*context)->line = 1;
mod_p = calloc(1, sizeof *mod_p);
LY_CHECK_ERR_GOTO(!mod_p, LOGMEM(mod->ctx), cleanup);
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 5012b2e..f117f43 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -189,7 +189,7 @@
LY_CHECK_RET(ly_in_new_memory(name, &in), LY_STMT_NONE);
start = in->current;
- kw = lysp_match_kw(NULL, in);
+ kw = lysp_match_kw(in, NULL);
name = in->current;
ly_in_free(in, 0);
@@ -3818,9 +3818,6 @@
/* skip possible trailing whitespaces at end of the input */
while (isspace(in->current[0])) {
- if (in->current[0] == '\n') {
- (*yin_ctx)->xmlctx->line++;
- }
ly_in_skip(in, 1);
}
if (in->current[0]) {
@@ -3881,9 +3878,6 @@
/* skip possible trailing whitespaces at end of the input */
while (isspace(in->current[0])) {
- if (in->current[0] == '\n') {
- (*yin_ctx)->xmlctx->line++;
- }
ly_in_skip(in, 1);
}
if (in->current[0]) {
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index 9d8d5ee..61cbd1f 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -1426,20 +1426,29 @@
}
enum ly_stmt
-lysp_match_kw(struct lys_yang_parser_ctx *ctx, struct ly_in *in)
+lysp_match_kw(struct ly_in *in, uint64_t *indent)
{
/**
- * @brief Move the INPUT by COUNT items. Also updates the indent value in yang parser context
- * @param[in] CTX yang parser context to update its indent value.
- * @param[in,out] IN input to move
+ * @brief Move the input by COUNT items. Also updates the indent value in yang parser context
* @param[in] COUNT number of items for which the DATA pointer is supposed to move on.
*
* *INDENT-OFF*
*/
-#define MOVE_IN(CTX, IN, COUNT) ly_in_skip(IN, COUNT);if(CTX){(CTX)->indent+=COUNT;}
-#define IF_KW(STR, LEN, STMT) if (!strncmp(in->current, STR, LEN)) {MOVE_IN(ctx, in, LEN);*kw=STMT;}
-#define IF_KW_PREFIX(STR, LEN) if (!strncmp(in->current, STR, LEN)) {MOVE_IN(ctx, in, LEN);
-#define IF_KW_PREFIX_END }
+#define MOVE_IN(COUNT) \
+ ly_in_skip(in, COUNT); \
+ if (indent) { \
+ (*indent)+=COUNT; \
+ }
+#define IF_KW(STR, LEN, STMT) \
+ if (!strncmp(in->current, STR, LEN)) { \
+ MOVE_IN(LEN); \
+ (*kw)=STMT; \
+ }
+#define IF_KW_PREFIX(STR, LEN) \
+ if (!strncmp(in->current, STR, LEN)) { \
+ MOVE_IN(LEN);
+#define IF_KW_PREFIX_END \
+ }
const char *start = in->current;
enum ly_stmt result = LY_STMT_NONE;
@@ -1447,7 +1456,7 @@
/* read the keyword itself */
switch (in->current[0]) {
case 'a':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("rgument", 7, LY_STMT_ARGUMENT)
else IF_KW("ugment", 6, LY_STMT_AUGMENT)
else IF_KW("ction", 5, LY_STMT_ACTION)
@@ -1457,13 +1466,13 @@
IF_KW_PREFIX_END
break;
case 'b':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("ase", 3, LY_STMT_BASE)
else IF_KW("elongs-to", 9, LY_STMT_BELONGS_TO)
else IF_KW("it", 2, LY_STMT_BIT)
break;
case 'c':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("ase", 3, LY_STMT_CASE)
else IF_KW("hoice", 5, LY_STMT_CHOICE)
else IF_KW_PREFIX("on", 2)
@@ -1475,7 +1484,7 @@
IF_KW_PREFIX_END
break;
case 'd':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW_PREFIX("e", 1)
IF_KW("fault", 5, LY_STMT_DEFAULT)
else IF_KW("scription", 9, LY_STMT_DESCRIPTION)
@@ -1486,7 +1495,7 @@
IF_KW_PREFIX_END
break;
case 'e':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("num", 3, LY_STMT_ENUM)
else IF_KW_PREFIX("rror-", 5)
IF_KW("app-tag", 7, LY_STMT_ERROR_APP_TAG)
@@ -1495,16 +1504,16 @@
else IF_KW("xtension", 8, LY_STMT_EXTENSION)
break;
case 'f':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("eature", 6, LY_STMT_FEATURE)
else IF_KW("raction-digits", 14, LY_STMT_FRACTION_DIGITS)
break;
case 'g':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("rouping", 7, LY_STMT_GROUPING)
break;
case 'i':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("dentity", 7, LY_STMT_IDENTITY)
else IF_KW("f-feature", 9, LY_STMT_IF_FEATURE)
else IF_KW("mport", 5, LY_STMT_IMPORT)
@@ -1514,11 +1523,11 @@
IF_KW_PREFIX_END
break;
case 'k':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("ey", 2, LY_STMT_KEY)
break;
case 'l':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW_PREFIX("e", 1)
IF_KW("af-list", 7, LY_STMT_LEAF_LIST)
else IF_KW("af", 2, LY_STMT_LEAF)
@@ -1527,7 +1536,7 @@
else IF_KW("ist", 3, LY_STMT_LIST)
break;
case 'm':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW_PREFIX("a", 1)
IF_KW("ndatory", 7, LY_STMT_MANDATORY)
else IF_KW("x-elements", 10, LY_STMT_MAX_ELEMENTS)
@@ -1540,12 +1549,12 @@
IF_KW_PREFIX_END
break;
case 'n':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("amespace", 8, LY_STMT_NAMESPACE)
else IF_KW("otification", 11, LY_STMT_NOTIFICATION)
break;
case 'o':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW_PREFIX("r", 1)
IF_KW("dered-by", 8, LY_STMT_ORDERED_BY)
else IF_KW("ganization", 10, LY_STMT_ORGANIZATION)
@@ -1553,7 +1562,7 @@
else IF_KW("utput", 5, LY_STMT_OUTPUT)
break;
case 'p':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("ath", 3, LY_STMT_PATH)
else IF_KW("attern", 6, LY_STMT_PATTERN)
else IF_KW("osition", 7, LY_STMT_POSITION)
@@ -1563,7 +1572,7 @@
IF_KW_PREFIX_END
break;
case 'r':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("ange", 4, LY_STMT_RANGE)
else IF_KW_PREFIX("e", 1)
IF_KW_PREFIX("f", 1)
@@ -1577,17 +1586,17 @@
else IF_KW("pc", 2, LY_STMT_RPC)
break;
case 's':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("tatus", 5, LY_STMT_STATUS)
else IF_KW("ubmodule", 8, LY_STMT_SUBMODULE)
break;
case 't':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("ypedef", 6, LY_STMT_TYPEDEF)
else IF_KW("ype", 3, LY_STMT_TYPE)
break;
case 'u':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW_PREFIX("ni", 2)
IF_KW("que", 3, LY_STMT_UNIQUE)
else IF_KW("ts", 2, LY_STMT_UNITS)
@@ -1595,29 +1604,29 @@
else IF_KW("ses", 3, LY_STMT_USES)
break;
case 'v':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("alue", 4, LY_STMT_VALUE)
break;
case 'w':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("hen", 3, LY_STMT_WHEN)
break;
case 'y':
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
IF_KW("ang-version", 11, LY_STMT_YANG_VERSION)
else IF_KW("in-element", 10, LY_STMT_YIN_ELEMENT)
break;
default:
- /* if context is not NULL we are matching keyword from YANG data*/
- if (ctx) {
+ /* if indent is not NULL we are matching keyword from YANG data */
+ if (indent) {
if (in->current[0] == ';') {
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
*kw = LY_STMT_SYNTAX_SEMICOLON;
} else if (in->current[0] == '{') {
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
*kw = LY_STMT_SYNTAX_LEFT_BRACE;
} else if (in->current[0] == '}') {
- MOVE_IN(ctx, in, 1);
+ MOVE_IN(1);
*kw = LY_STMT_SYNTAX_RIGHT_BRACE;
}
}
diff --git a/src/tree_schema_internal.h b/src/tree_schema_internal.h
index 268413f..0848a31 100644
--- a/src/tree_schema_internal.h
+++ b/src/tree_schema_internal.h
@@ -119,11 +119,11 @@
#define LOGVAL_YANG(CTX, ...) LOGVAL(PARSER_CTX(CTX), ((struct lys_yang_parser_ctx *)CTX)->pos_type, \
((struct lys_yang_parser_ctx *)CTX)->pos_type == LY_VLOG_LINE ? \
- (void *)&((struct lys_yang_parser_ctx *)CTX)->line : \
+ (void *)&((struct lys_yang_parser_ctx *)CTX)->in->line : \
(void *)((struct lys_yang_parser_ctx *)CTX)->path, __VA_ARGS__)
#define LOGVAL_YIN(CTX, ...) LOGVAL(PARSER_CTX(CTX), LY_VLOG_LINE, \
- &((struct lys_yin_parser_ctx *)CTX)->xmlctx->line, __VA_ARGS__)
+ &((struct lys_yin_parser_ctx *)CTX)->xmlctx->in->line, __VA_ARGS__)
struct lys_parser_ctx {
LYS_INFORMAT format; /**< parser format */
@@ -144,10 +144,9 @@
struct lys_glob_unres *unres; /**< global unres structure */
enum LY_VLOG_ELEM pos_type; /**< */
struct ly_in *in; /**< input handler for the parser */
- union {
- uint64_t line; /**< line number */
- const char *path; /**< path */
- };
+
+ const char *path; /**< path */
+
uint64_t indent; /**< current position on the line for YANG indentation */
};
@@ -692,11 +691,11 @@
/**
* @brief match yang keyword
*
- * @param[in] ctx yang parser context for logging, can be NULL if keyword is from YIN data.
* @param[in,out] in Input structure, is updated.
+ * @param[in,out] indent Pointer to the counter of current position on the line for YANG indentation (optional).
* @return yang_keyword values.
*/
-enum ly_stmt lysp_match_kw(struct lys_yang_parser_ctx *ctx, struct ly_in *in);
+enum ly_stmt lysp_match_kw(struct ly_in *in, uint64_t *indent);
/**
* @brief Generate path of the given node in the requested format.
diff --git a/src/xml.c b/src/xml.c
index 8a1a7a2..6f87b81 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -32,10 +32,10 @@
#include "tree_data.h"
/* Move input p by s characters, if EOF log with lyxml_ctx c */
-#define move_input(c, s) ly_in_skip(c->in, s); LY_CHECK_ERR_RET(!c->in->current[0], LOGVAL(c->ctx, LY_VLOG_LINE, &c->line, LY_VCODE_EOF), LY_EVALID)
+#define move_input(c, s) ly_in_skip(c->in, s); LY_CHECK_ERR_RET(!c->in->current[0], LOGVAL(c->ctx, LY_VLOG_LINE, &c->in->line, LY_VCODE_EOF), LY_EVALID)
/* Ignore whitespaces in the input string p */
-#define ign_xmlws(c) while (is_xmlws(*(c)->in->current)) {if (*(c)->in->current == '\n') {++c->line;} ly_in_skip(c->in, 1);}
+#define ign_xmlws(c) while (is_xmlws(*(c)->in->current)) {ly_in_skip(c->in, 1);}
static LY_ERR lyxml_next_attr_content(struct lyxml_ctx *xmlctx, const char **value, size_t *value_len, ly_bool *ws_only,
ly_bool *dynamic);
@@ -47,18 +47,14 @@
* Returns Boolean value whether delim was found or not.
*/
static ly_bool
-ign_todelim(register const char *input, const char *delim, size_t delim_len, size_t *newlines, size_t *parsed)
+ign_todelim(register const char *input, const char *delim, size_t delim_len, size_t *parsed)
{
size_t i;
register const char *a, *b;
- (*newlines) = 0;
(*parsed) = 0;
for ( ; *input; ++input, ++(*parsed)) {
if (*input != *delim) {
- if (*input == '\n') {
- ++(*newlines);
- }
continue;
}
a = input;
@@ -103,10 +99,10 @@
/* check NameStartChar (minus colon) */
LY_CHECK_ERR_RET(ly_getutf8(&in, &c, &parsed),
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INCHAR, in[0]),
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INCHAR, in[0]),
LY_EVALID);
LY_CHECK_ERR_RET(!is_xmlqnamestartchar(c),
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX,
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX,
"Identifier \"%s\" starts with an invalid character.", in - parsed),
LY_EVALID);
@@ -116,7 +112,7 @@
ly_in_skip(xmlctx->in, parsed);
rc = ly_getutf8(&in, &c, &parsed);
- LY_CHECK_ERR_RET(rc, LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INCHAR, in[0]), LY_EVALID);
+ LY_CHECK_ERR_RET(rc, LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INCHAR, in[0]), LY_EVALID);
} while (is_xmlqnamechar(c));
*start = s;
@@ -227,7 +223,7 @@
{
const struct ly_ctx *ctx = xmlctx->ctx; /* shortcut */
const char *endtag, *sectname;
- size_t endtag_len, newlines, parsed;
+ size_t endtag_len, parsed;
ly_bool rc;
while (1) {
@@ -236,12 +232,12 @@
if (xmlctx->in->current[0] == '\0') {
/* EOF */
if (xmlctx->elements.count) {
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_EOF);
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_EOF);
return LY_EVALID;
}
return LY_SUCCESS;
} else if (xmlctx->in->current[0] != '<') {
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
xmlctx->in->current, "element tag start ('<')");
return LY_EVALID;
}
@@ -264,21 +260,19 @@
endtag_len = ly_strlen_const("]]>");
} else if (!strncmp(xmlctx->in->current, "DOCTYPE", ly_strlen_const("DOCTYPE"))) {
/* Document type declaration - not supported */
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_NSUPP, "Document Type Declaration");
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_NSUPP, "Document Type Declaration");
return LY_EVALID;
} else {
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Unknown XML section \"%.20s\".",
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Unknown XML section \"%.20s\".",
&xmlctx->in->current[-2]);
return LY_EVALID;
}
- rc = ign_todelim(xmlctx->in->current, endtag, endtag_len, &newlines, &parsed);
- LY_CHECK_ERR_RET(rc, LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_NTERM, sectname), LY_EVALID);
- xmlctx->line += newlines;
+ rc = ign_todelim(xmlctx->in->current, endtag, endtag_len, &parsed);
+ LY_CHECK_ERR_RET(rc, LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_NTERM, sectname), LY_EVALID);
ly_in_skip(xmlctx->in, parsed + endtag_len);
} else if (xmlctx->in->current[0] == '?') {
- rc = ign_todelim(xmlctx->in->current, "?>", 2, &newlines, &parsed);
- LY_CHECK_ERR_RET(rc, LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_NTERM, "Declaration"), LY_EVALID);
- xmlctx->line += newlines;
+ rc = ign_todelim(xmlctx->in->current, "?>", 2, &parsed);
+ LY_CHECK_ERR_RET(rc, LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_NTERM, "Declaration"), LY_EVALID);
ly_in_skip(xmlctx->in, parsed + 2);
} else {
/* other non-WS character */
@@ -405,7 +399,7 @@
buf[len++] = '\"';
in += ly_strlen_const(""");
} else {
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX,
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX,
"Entity reference \"%.*s\" not supported, only predefined references allowed.", 10, &in[offset - 1]);
goto error;
}
@@ -430,18 +424,18 @@
n = (LY_BASE_HEX * n) + u;
}
} else {
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Invalid character reference \"%.*s\".", 12, p);
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Invalid character reference \"%.*s\".", 12, p);
goto error;
}
LY_CHECK_ERR_GOTO(in[offset] != ';',
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INSTREXP,
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INSTREXP,
LY_VCODE_INSTREXP_len(&in[offset]), &in[offset], ";"),
error);
++offset;
LY_CHECK_ERR_GOTO(ly_pututf8(&buf[len], n, &u),
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX,
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX,
"Invalid character reference \"%.*s\" (0x%08x).", 12, p, n),
error);
len += u;
@@ -471,7 +465,7 @@
/* log lines */
if (in[offset] == '\n') {
- ++xmlctx->line;
+ LY_IN_NEW_LINE(xmlctx->in);
}
/* continue */
@@ -480,7 +474,7 @@
}
/* EOF reached before endchar */
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_EOF);
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_EOF);
error:
free(buf);
@@ -497,7 +491,7 @@
*length = len;
*ws_only = ws;
- ly_in_skip(xmlctx->in, in - xmlctx->in->current);
+ xmlctx->in->current = in;
return LY_SUCCESS;
#undef BUFSIZE
@@ -523,7 +517,7 @@
/* match opening and closing element tags */
if (!xmlctx->elements.count) {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Stray closing element tag (\"%.*s\").",
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Stray closing element tag (\"%.*s\").",
name_len, name);
return LY_EVALID;
}
@@ -531,7 +525,7 @@
e = (struct lyxml_elem *)xmlctx->elements.objs[xmlctx->elements.count - 1];
if ((e->prefix_len != prefix_len) || (e->name_len != name_len) ||
(prefix_len && strncmp(prefix, e->prefix, e->prefix_len)) || strncmp(name, e->name, e->name_len)) {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX,
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX,
"Opening (\"%.*s%s%.*s\") and closing (\"%.*s%s%.*s\") elements tag mismatch.",
e->prefix_len, e->prefix ? e->prefix : "", e->prefix ? ":" : "", e->name_len, e->name,
prefix_len, prefix ? prefix : "", prefix ? ":" : "", name_len, name);
@@ -554,7 +548,7 @@
/* parse closing tag */
if (xmlctx->in->current[0] != '>') {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
xmlctx->in->current, "element tag termination ('>')");
return LY_EVALID;
}
@@ -659,10 +653,10 @@
/* skip '=' */
if (xmlctx->in->current[0] == '\0') {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_EOF);
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_EOF);
return LY_EVALID;
} else if (xmlctx->in->current[0] != '=') {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
xmlctx->in->current, "'='");
return LY_EVALID;
}
@@ -673,10 +667,10 @@
/* find quotes */
if (xmlctx->in->current[0] == '\0') {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_EOF);
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_EOF);
return LY_EVALID;
} else if ((xmlctx->in->current[0] != '\'') && (xmlctx->in->current[0] != '\"')) {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(xmlctx->in->current),
xmlctx->in->current, "either single or double quotation mark");
return LY_EVALID;
}
@@ -720,10 +714,10 @@
while ((xmlctx->in->current[0] != '>') && (xmlctx->in->current[0] != '/')) {
in = xmlctx->in->current;
if (in[0] == '\0') {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_EOF);
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_EOF);
return LY_EVALID;
} else if ((ly_getutf8(&in, &c, &parsed) || !is_xmlqnamestartchar(c))) {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(in - parsed), in - parsed,
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_INSTREXP, LY_VCODE_INSTREXP_len(in - parsed), in - parsed,
"element tag end ('>' or '/>') or an attribute");
return LY_EVALID;
}
@@ -800,7 +794,6 @@
xmlctx = calloc(1, sizeof *xmlctx);
LY_CHECK_ERR_RET(!xmlctx, LOGMEM(ctx), LY_EMEM);
xmlctx->ctx = ctx;
- xmlctx->line = 1;
xmlctx->in = in;
/* parse next element, if any */
@@ -811,7 +804,7 @@
/* update status */
xmlctx->status = LYXML_END;
} else if (closing) {
- LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->line, LYVE_SYNTAX, "Stray closing element tag (\"%.*s\").",
+ LOGVAL(ctx, LY_VLOG_LINE, &xmlctx->in->line, LYVE_SYNTAX, "Stray closing element tag (\"%.*s\").",
xmlctx->name_len, xmlctx->name);
ret = LY_EVALID;
goto cleanup;
@@ -904,7 +897,7 @@
/* no attributes but a closing tag */
ly_in_skip(xmlctx->in, 1);
if (!xmlctx->in->current[0]) {
- LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->line, LY_VCODE_EOF);
+ LOGVAL(xmlctx->ctx, LY_VLOG_LINE, &xmlctx->in->line, LY_VCODE_EOF);
ret = LY_EVALID;
goto cleanup;
}
diff --git a/src/xml.h b/src/xml.h
index 629ad04..34bbde5 100644
--- a/src/xml.h
+++ b/src/xml.h
@@ -78,7 +78,6 @@
struct lyxml_ctx {
const struct ly_ctx *ctx;
- uint64_t line; /* current line */
struct ly_in *in; /* input structure */
enum LYXML_PARSER_STATUS status; /* status providing information about the last parsed object, following attributes
diff --git a/tests/utests/basic/test_xml.c b/tests/utests/basic/test_xml.c
index abf0bf1..b6935e2 100644
--- a/tests/utests/basic/test_xml.c
+++ b/tests/utests/basic/test_xml.c
@@ -401,14 +401,14 @@
xmlctx->in = in;
xmlctx->status = LYXML_ELEM_CONTENT;
assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
- CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 2.");
+ CHECK_LOG_CTX("Unexpected end-of-input.", "Line number 1.");
ly_in_free(in, 0);
assert_int_equal(LY_SUCCESS, ly_in_new_memory("xxx", &in));
xmlctx->in = in;
xmlctx->status = LYXML_ELEM_CONTENT;
assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
- CHECK_LOG_CTX("Invalid character sequence \"xxx\", expected element tag start ('<').", "Line number 2.");
+ CHECK_LOG_CTX("Invalid character sequence \"xxx\", expected element tag start ('<').", "Line number 1.");
ly_in_free(in, 0);
lyxml_ctx_free(xmlctx);
@@ -444,49 +444,49 @@
xmlctx->in = in;
xmlctx->status = LYXML_ATTRIBUTE;
assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
- CHECK_LOG_CTX("Invalid character sequence \"'\", expected ;.", "Line number 2.");
+ CHECK_LOG_CTX("Invalid character sequence \"'\", expected ;.", "Line number 1.");
ly_in_free(in, 0);
assert_int_equal(LY_SUCCESS, ly_in_new_memory("=\"R\"", &in));
xmlctx->in = in;
xmlctx->status = LYXML_ATTRIBUTE;
assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
- CHECK_LOG_CTX("Invalid character sequence \"\"\", expected ;.", "Line number 2.");
+ CHECK_LOG_CTX("Invalid character sequence \"\"\", expected ;.", "Line number 1.");
ly_in_free(in, 0);
assert_int_equal(LY_SUCCESS, ly_in_new_memory("=\"&nonsense;\"", &in));
xmlctx->in = in;
xmlctx->status = LYXML_ATTRIBUTE;
assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
- CHECK_LOG_CTX("Entity reference \"&nonsense;\" not supported, only predefined references allowed.", "Line number 2.");
+ CHECK_LOG_CTX("Entity reference \"&nonsense;\" not supported, only predefined references allowed.", "Line number 1.");
ly_in_free(in, 0);
assert_int_equal(LY_SUCCESS, ly_in_new_memory(">&#o122;", &in));
xmlctx->in = in;
xmlctx->status = LYXML_ELEMENT;
assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
- CHECK_LOG_CTX("Invalid character reference \"&#o122;\".", "Line number 2.");
+ CHECK_LOG_CTX("Invalid character reference \"&#o122;\".", "Line number 1.");
ly_in_free(in, 0);
assert_int_equal(LY_SUCCESS, ly_in_new_memory("=\'\'", &in));
xmlctx->in = in;
xmlctx->status = LYXML_ATTRIBUTE;
assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
- CHECK_LOG_CTX("Invalid character reference \"\'\" (0x00000006).", "Line number 2.");
+ CHECK_LOG_CTX("Invalid character reference \"\'\" (0x00000006).", "Line number 1.");
ly_in_free(in, 0);
assert_int_equal(LY_SUCCESS, ly_in_new_memory("=\'\'", &in));
xmlctx->in = in;
xmlctx->status = LYXML_ATTRIBUTE;
assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
- CHECK_LOG_CTX("Invalid character reference \"\'\" (0x0000fdd0).", "Line number 2.");
+ CHECK_LOG_CTX("Invalid character reference \"\'\" (0x0000fdd0).", "Line number 1.");
ly_in_free(in, 0);
assert_int_equal(LY_SUCCESS, ly_in_new_memory("=\'\'", &in));
xmlctx->in = in;
xmlctx->status = LYXML_ATTRIBUTE;
assert_int_equal(LY_EVALID, lyxml_ctx_next(xmlctx));
- CHECK_LOG_CTX("Invalid character reference \"\'\" (0x0000ffff).", "Line number 2.");
+ CHECK_LOG_CTX("Invalid character reference \"\'\" (0x0000ffff).", "Line number 1.");
ly_in_free(in, 0);
lyxml_ctx_free(xmlctx);
diff --git a/tests/utests/schema/test_parser_yang.c b/tests/utests/schema/test_parser_yang.c
index 6f09084..f0193fb 100644
--- a/tests/utests/schema/test_parser_yang.c
+++ b/tests/utests/schema/test_parser_yang.c
@@ -68,6 +68,7 @@
#define YCTX_INIT \
struct ly_in in = {0}; \
+ in.line = 1; \
YCTX->in = &in
static int
@@ -79,7 +80,6 @@
YCTX = calloc(1, sizeof(*YCTX));
YCTX->format = LYS_IN_YANG;
YCTX->pos_type = LY_VLOG_LINE;
- YCTX->line = 1;
/* allocate new parsed module */
YCTX->parsed_mod = calloc(1, sizeof *YCTX->parsed_mod);
@@ -310,7 +310,7 @@
in.current = "\"hel\" +\t\nlo"; /* unquoted the second part */
assert_int_equal(LY_EVALID, get_argument(YCTX, Y_STR_ARG, NULL, &word, &buf, &len));
- CHECK_LOG_CTX("Both string parts divided by '+' must be quoted.", "Line number 6.");
+ CHECK_LOG_CTX("Both string parts divided by '+' must be quoted.", "Line number 8.");
TEST_GET_ARGUMENT_SUCCESS("\'he\'\t\n+ \"llo\"", YCTX, Y_STR_ARG, "hello", 5, "");
free(buf);
@@ -321,7 +321,7 @@
/* missing argument */
in.current = ";";
assert_int_equal(LY_EVALID, get_argument(YCTX, Y_STR_ARG, NULL, &word, &buf, &len));
- CHECK_LOG_CTX("Invalid character sequence \";\", expected an argument.", "Line number 8.");
+ CHECK_LOG_CTX("Invalid character sequence \";\", expected an argument.", "Line number 10.");
}
#define TEST_STMS_SUCCESS(INPUT_TEXT, CTX, ACTION, EXPECT_WORD)\
@@ -754,6 +754,9 @@
assert_int_equal(2, mod->version);
mod = mod_renew(YCTX);
+ /* reset line */
+ in.line = 1;
+
in.current = "module " SCHEMA_BEGINNING "} module q {namespace urn:q;prefixq;}";
m = calloc(1, sizeof *m);
m->ctx = YCTX->parsed_mod->mod->ctx;
@@ -787,7 +790,7 @@
/* invalid substatement */
in.current = SCHEMA_BEGINNING "must false;}";
assert_int_equal(LY_EVALID, parse_module(YCTX, mod));
- CHECK_LOG_CTX("Invalid keyword \"must\" as a child of \"module\".", "Line number 3.");
+ CHECK_LOG_CTX("Invalid keyword \"must\" as a child of \"module\".", "Line number 1.");
/* submodule */
submod = submod_renew(YCTX);
@@ -795,7 +798,7 @@
/* missing mandatory substatements */
in.current = " subname {}";
assert_int_equal(LY_EVALID, parse_submodule(YCTX, submod));
- CHECK_LOG_CTX("Missing mandatory keyword \"belongs-to\" as a child of \"submodule\".", "Line number 3.");
+ CHECK_LOG_CTX("Missing mandatory keyword \"belongs-to\" as a child of \"submodule\".", "Line number 1.");
assert_string_equal("subname", submod->name);
submod = submod_renew(YCTX);
@@ -811,17 +814,17 @@
/* duplicated namespace, prefix */
in.current = " subname {belongs-to name {prefix x;}belongs-to module1;belongs-to module2;} ...";
assert_int_equal(LY_EVALID, parse_submodule(YCTX, submod));
- CHECK_LOG_CTX("Duplicate keyword \"belongs-to\".", "Line number 3.");
+ CHECK_LOG_CTX("Duplicate keyword \"belongs-to\".", "Line number 1.");
submod = submod_renew(YCTX);
/* not allowed in submodule (module-specific) */
in.current = SCHEMA_BEGINNING "namespace \"urn:z\";}";
assert_int_equal(LY_EVALID, parse_submodule(YCTX, submod));
- CHECK_LOG_CTX("Invalid keyword \"namespace\" as a child of \"submodule\".", "Line number 3.");
+ CHECK_LOG_CTX("Invalid keyword \"namespace\" as a child of \"submodule\".", "Line number 1.");
submod = submod_renew(YCTX);
in.current = SCHEMA_BEGINNING "prefix m;}}";
assert_int_equal(LY_EVALID, parse_submodule(YCTX, submod));
- CHECK_LOG_CTX("Invalid keyword \"prefix\" as a child of \"submodule\".", "Line number 3.");
+ CHECK_LOG_CTX("Invalid keyword \"prefix\" as a child of \"submodule\".", "Line number 1.");
submod = submod_renew(YCTX);
in.current = "submodule " SCHEMA_BEGINNING "} module q {namespace urn:q;prefixq;}";