libyang REFACTOR major logging updates

Structured error information instead of a
single error message.
diff --git a/tests/utests/data/test_diff.c b/tests/utests/data/test_diff.c
index 4400b5d..0edd6bd 100644
--- a/tests/utests/data/test_diff.c
+++ b/tests/utests/data/test_diff.c
@@ -318,7 +318,7 @@
     struct lyd_node *diff = NULL;
 
     assert_int_equal(lyd_diff_siblings(model_1, lyd_child(model_1), 0, &diff), LY_EINVAL);
-    CHECK_LOG_CTX("Invalid arguments - cannot create diff for unrelated data (lyd_diff()).", NULL);
+    CHECK_LOG_CTX("Invalid arguments - cannot create diff for unrelated data (lyd_diff()).", NULL, 0);
 
     assert_int_equal(lyd_diff_siblings(NULL, NULL, 0, NULL), LY_EINVAL);
 
diff --git a/tests/utests/data/test_new.c b/tests/utests/data/test_new.c
index 5cee903..d75f667 100644
--- a/tests/utests/data/test_new.c
+++ b/tests/utests/data/test_new.c
@@ -106,16 +106,16 @@
     lyd_free_tree(node);
 
     assert_int_equal(lyd_new_list2(NULL, mod, "l1", "[]", 0, &node), LY_EVALID);
-    CHECK_LOG_CTX("Unexpected XPath token \"]\" (\"]\").", "Schema location \"/a:l1\".");
+    CHECK_LOG_CTX("Unexpected XPath token \"]\" (\"]\").", "/a:l1", 0);
 
     assert_int_equal(lyd_new_list2(NULL, mod, "l1", "[key1='a'][key2='b']", 0, &node), LY_ENOTFOUND);
-    CHECK_LOG_CTX("Not found node \"key1\" in path.", "Schema location \"/a:l1\".");
+    CHECK_LOG_CTX("Not found node \"key1\" in path.", "/a:l1", 0);
 
     assert_int_equal(lyd_new_list2(NULL, mod, "l1", "[a='a'][b='b'][c='c']", 0, &node), LY_EVALID);
-    CHECK_LOG_CTX("Key expected instead of leaf \"c\" in path.", "Schema location \"/a:l1\".");
+    CHECK_LOG_CTX("Key expected instead of leaf \"c\" in path.", "/a:l1", 0);
 
     assert_int_equal(lyd_new_list2(NULL, mod, "c", "[a='a'][b='b']", 0, &node), LY_ENOTFOUND);
-    CHECK_LOG_CTX("List node \"c\" not found.", NULL);
+    CHECK_LOG_CTX("List node \"c\" not found.", NULL, 0);
 
     assert_int_equal(lyd_new_list2(NULL, mod, "l1", "[a='a'][b='b']", 0, &node), LY_SUCCESS);
     lyd_free_tree(node);
@@ -141,10 +141,10 @@
 
     /* leaf */
     assert_int_equal(lyd_new_term(NULL, mod, "foo", "[a='a'][b='b'][c='c']", 0, &node), LY_EVALID);
-    CHECK_LOG_CTX("Invalid type uint16 value \"[a='a'][b='b'][c='c']\".", "Schema location \"/a:foo\".");
+    CHECK_LOG_CTX("Invalid type uint16 value \"[a='a'][b='b'][c='c']\".", "/a:foo", 0);
 
     assert_int_equal(lyd_new_term(NULL, mod, "c", "value", 0, &node), LY_ENOTFOUND);
-    CHECK_LOG_CTX("Term node \"c\" not found.", NULL);
+    CHECK_LOG_CTX("Term node \"c\" not found.", NULL, 0);
 
     assert_int_equal(lyd_new_term(NULL, mod, "foo", "256", 0, &node), LY_SUCCESS);
     lyd_free_tree(node);
@@ -158,10 +158,10 @@
     lyd_free_tree(node);
 
     assert_int_equal(lyd_new_inner(NULL, mod, "l1", 0, &node), LY_ENOTFOUND);
-    CHECK_LOG_CTX("Inner node (container, notif, RPC, or action) \"l1\" not found.", NULL);
+    CHECK_LOG_CTX("Inner node (container, notif, RPC, or action) \"l1\" not found.", NULL, 0);
 
     assert_int_equal(lyd_new_inner(NULL, mod, "l2", 0, &node), LY_ENOTFOUND);
-    CHECK_LOG_CTX("Inner node (container, notif, RPC, or action) \"l2\" not found.", NULL);
+    CHECK_LOG_CTX("Inner node (container, notif, RPC, or action) \"l2\" not found.", NULL, 0);
 
     /* anydata */
     assert_int_equal(lyd_new_any(NULL, mod, "any", "{\"node\":\"val\"}", 0, LYD_ANYDATA_STRING, 0, &node), LY_SUCCESS);
@@ -171,7 +171,7 @@
 
     /* key-less list */
     assert_int_equal(lyd_new_list2(NULL, mod, "l2", "[a='a'][b='b']", 0, &node), LY_EVALID);
-    CHECK_LOG_CTX("List predicate defined for keyless list \"l2\" in path.", "Schema location \"/a:l2\".");
+    CHECK_LOG_CTX("List predicate defined for keyless list \"l2\" in path.", "/a:l2", 0);
 
     assert_int_equal(lyd_new_list2(NULL, mod, "l2", "", 0, &node), LY_SUCCESS);
     lyd_free_tree(node);
@@ -255,7 +255,7 @@
     /* try LYD_NEWOPT_OPAQ */
     ret = lyd_new_path2(NULL, UTEST_LYCTX, "/a:l1", NULL, 0, 0, 0, NULL, NULL);
     assert_int_equal(ret, LY_EINVAL);
-    CHECK_LOG_CTX("Predicate missing for list \"l1\" in path \"/a:l1\".", "Schema location \"/a:l1\".");
+    CHECK_LOG_CTX("Predicate missing for list \"l1\" in path \"/a:l1\".", "/a:l1", 0);
 
     ret = lyd_new_path2(NULL, UTEST_LYCTX, "/a:l1", NULL, 0, 0, LYD_NEW_PATH_OPAQ, NULL, &root);
     assert_int_equal(ret, LY_SUCCESS);
@@ -266,7 +266,7 @@
 
     ret = lyd_new_path2(NULL, UTEST_LYCTX, "/a:foo", NULL, 0, 0, 0, NULL, NULL);
     assert_int_equal(ret, LY_EVALID);
-    CHECK_LOG_CTX("Invalid type uint16 empty value.", "Schema location \"/a:foo\".");
+    CHECK_LOG_CTX("Invalid type uint16 empty value.", "/a:foo", 0);
 
     ret = lyd_new_path2(NULL, UTEST_LYCTX, "/a:foo", NULL, 0, 0, LYD_NEW_PATH_OPAQ, NULL, &root);
     assert_int_equal(ret, LY_SUCCESS);
@@ -301,7 +301,7 @@
 
     ret = lyd_new_path2(root, NULL, "/a:c2/l3[1]", NULL, 0, 0, 0, NULL, &node);
     assert_int_equal(ret, LY_EEXIST);
-    CHECK_LOG_CTX("Path \"/a:c2/l3[1]\" already exists.", "Data location \"/a:c2/l3[1]\".");
+    CHECK_LOG_CTX("Path \"/a:c2/l3[1]\" already exists.", "/a:c2/l3[1]", 0);
 
     ret = lyd_new_path2(root, NULL, "/a:c2/l3[2]/x", "val2", 0, 0, 0, NULL, &node);
     assert_int_equal(ret, LY_SUCCESS);
@@ -360,7 +360,7 @@
 
     ret = lyd_new_path2(root, NULL, "/a:ll2[1]", "", 0, 0, 0, NULL, &node);
     assert_int_equal(ret, LY_EEXIST);
-    CHECK_LOG_CTX("Path \"/a:ll2[1]\" already exists.", "Data location \"/a:ll2[1]\".");
+    CHECK_LOG_CTX("Path \"/a:ll2[1]\" already exists.", "/a:ll2[1]", 0);
 
     ret = lyd_new_path2(root, NULL, "/a:ll2[2]", "val2", 0, 0, 0, NULL, &node);
     assert_int_equal(ret, LY_SUCCESS);
@@ -375,7 +375,7 @@
 
     ret = lyd_new_path2(root, NULL, "/a:ll2[3][.='val3']", NULL, 0, 0, 0, NULL, &node);
     assert_int_equal(ret, LY_EVALID);
-    CHECK_LOG_CTX("Unparsed characters \"[.='val3']\" left at the end of path.", NULL);
+    CHECK_LOG_CTX("Unparsed characters \"[.='val3']\" left at the end of path.", NULL, 0);
 
     lyd_print_mem(&str, root, LYD_XML, LYD_PRINT_WITHSIBLINGS);
     assert_string_equal(str,
diff --git a/tests/utests/data/test_parser_json.c b/tests/utests/data/test_parser_json.c
index 8feed9c..0361b6a 100644
--- a/tests/utests/data/test_parser_json.c
+++ b/tests/utests/data/test_parser_json.c
@@ -61,9 +61,9 @@
 #define CHECK_PARSE_LYD(INPUT, PARSE_OPTION, VALIDATE_OPTION, TREE) \
     CHECK_PARSE_LYD_PARAM(INPUT, LYD_JSON, PARSE_OPTION, VALIDATE_OPTION, LY_SUCCESS, TREE)
 
-#define PARSER_CHECK_ERROR(INPUT, PARSE_OPTION, VALIDATE_OPTION, MODEL, RET_VAL, ERR_MESSAGE, ERR_PATH) \
+#define PARSER_CHECK_ERROR(INPUT, PARSE_OPTION, VALIDATE_OPTION, MODEL, RET_VAL, ERR_MESSAGE, ERR_PATH, ERR_LINE) \
     assert_int_equal(RET_VAL, lyd_parse_data_mem(UTEST_LYCTX, INPUT, LYD_JSON, PARSE_OPTION, VALIDATE_OPTION, &MODEL));\
-    CHECK_LOG_CTX(ERR_MESSAGE, ERR_PATH);\
+    CHECK_LOG_CTX(ERR_MESSAGE, ERR_PATH, ERR_LINE);\
     assert_null(MODEL)
 
 #define CHECK_LYD_STRING(IN_MODEL, PRINT_OPTION, TEXT) \
@@ -144,27 +144,25 @@
     lyd_free_all(tree);
 
     PARSER_CHECK_ERROR(data, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "Unknown (or not implemented) YANG module \"x\" of metadata \"x:xxx\".", "Data location \"/@a:foo\", line number 1.");
+            "Unknown (or not implemented) YANG module \"x\" of metadata \"x:xxx\".", "/@a:foo", 1);
 
     /* missing referenced metadata node */
     PARSER_CHECK_ERROR("{\"@a:foo\" : { \"a:hint\" : 1 }}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "Missing JSON data instance to be coupled with @a:foo metadata.", "Data location \"/@a:foo\", line number 1.");
+            "Missing JSON data instance to be coupled with @a:foo metadata.", "/@a:foo", 1);
 
     /* missing namespace for meatadata*/
     PARSER_CHECK_ERROR("{\"a:foo\" : \"value\", \"@a:foo\" : { \"hint\" : 1 }}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "Metadata in JSON must be namespace-qualified, missing prefix for \"hint\".",
-            "Schema location \"/a:foo\", line number 1.");
+            "Metadata in JSON must be namespace-qualified, missing prefix for \"hint\".", "/a:foo", 1);
 
     /* invalid JSON type */
     data = "{\"a:l1\" : [{ \"a\" : \"val-a\", \"b\" : \"val-b\", \"c\" : 1, \"cont\" : { \"e\" : \"0\" } }]}";
     PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "Invalid non-boolean-encoded boolean value \"0\".",
-            "Data location \"/a:l1[a='val-a'][b='val-b'][c='1']/cont/e\", line number 1.");
+            "Invalid non-boolean-encoded boolean value \"0\".", "/a:l1[a='val-a'][b='val-b'][c='1']/cont/e", 1);
 
     /* reverse solidus in JSON object member name */
     data = "{\"@a:foo\":{\"a:hi\\nt\":1},\"a:foo\":\"xxx\"}";
     assert_int_equal(LY_EINVAL, lyd_parse_data_mem(UTEST_LYCTX, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
-    CHECK_LOG_CTX("Annotation definition for attribute \"a:hi\nt\" not found.", "Path \"/@a:foo/@a:hi\nt\", line number 1.");
+    CHECK_LOG_CTX("Annotation definition for attribute \"a:hi\nt\" not found.", "/@a:foo/@a:hi\nt", 1);
 }
 
 static void
@@ -253,14 +251,13 @@
 
     /* missing referenced metadata node */
     PARSER_CHECK_ERROR("{\"@a:ll1\":[{\"a:hint\":1}]}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "Missing JSON data instance to be coupled with @a:ll1 metadata.", "Data location \"/@a:ll1\", line number 1.");
+            "Missing JSON data instance to be coupled with @a:ll1 metadata.", "/@a:ll1", 1);
 
     PARSER_CHECK_ERROR("{\"a:ll1\":[1],\"@a:ll1\":[{\"a:hint\":1},{\"a:hint\":2}]}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "Missing JSON data instance #2 of a:ll1 to be coupled with metadata.", "Schema location \"/a:ll1\", line number 1.");
+            "Missing JSON data instance #2 of a:ll1 to be coupled with metadata.", "/a:ll1", 1);
 
     PARSER_CHECK_ERROR("{\"@a:ll1\":[{\"a:hint\":1},{\"a:hint\":2},{\"a:hint\":3}],\"a:ll1\" : [1, 2]}", 0, LYD_VALIDATE_PRESENT,
-            tree, LY_EVALID, "Missing JSON data instance #3 to be coupled with @a:ll1 metadata.",
-            "Data location \"/@a:ll1\", line number 1.");
+            tree, LY_EVALID, "Missing JSON data instance #3 to be coupled with @a:ll1 metadata.", "/@a:ll1", 1);
 }
 
 static void
@@ -404,19 +401,17 @@
 
     /* missing keys */
     PARSER_CHECK_ERROR("{ \"a:l1\": [ {\"c\" : 1, \"b\" : \"b\"}]}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "List instance is missing its key \"a\".",
-            "Data location \"/a:l1[b='b'][c='1']\", line number 1.");
+            "List instance is missing its key \"a\".", "/a:l1[b='b'][c='1']", 1);
 
     PARSER_CHECK_ERROR("{ \"a:l1\": [ {\"a\" : \"a\"}]}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "List instance is missing its key \"b\".", "Data location \"/a:l1[a='a']\", line number 1.");
+            "List instance is missing its key \"b\".", "/a:l1[a='a']", 1);
 
     PARSER_CHECK_ERROR("{ \"a:l1\": [ {\"b\" : \"b\", \"a\" : \"a\"}]}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "List instance is missing its key \"c\".", "Data location \"/a:l1[a='a'][b='b']\", line number 1.");
+            "List instance is missing its key \"c\".", "/a:l1[a='a'][b='b']", 1);
 
     /* key duplicate */
     PARSER_CHECK_ERROR("{ \"a:l1\": [ {\"c\" : 1, \"b\" : \"b\", \"a\" : \"a\", \"c\" : 1}]}", 0, LYD_VALIDATE_PRESENT,
-            tree, LY_EVALID, "Duplicate instance of \"c\".",
-            "Data location \"/a:l1[a='a'][b='b'][c='1'][c='1']/c\", line number 1.");
+            tree, LY_EVALID, "Duplicate instance of \"c\".", "/a:l1[a='a'][b='b'][c='1'][c='1']/c", 1);
 
     /* keys order, in contrast to XML, JSON accepts keys in any order even in strict mode */
     CHECK_PARSE_LYD("{ \"a:l1\": [ {\"d\" : \"d\", \"a\" : \"a\", \"c\" : 1, \"b\" : \"b\"}]}", 0, LYD_VALIDATE_PRESENT, tree);
@@ -431,7 +426,7 @@
     CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c", 1, LYS_LEAF, 1, 0, NULL, 0);
     assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
     CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "d", 1, LYS_LEAF, 1, 0, NULL, 0);
-    CHECK_LOG_CTX(NULL, NULL);
+    CHECK_LOG_CTX(NULL, NULL, 0);
     CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS,
             "{\"a:l1\":[{\"a\":\"a\",\"b\":\"b\",\"c\":1,\"d\":\"d\"}]}");
     lyd_free_all(tree);
@@ -449,7 +444,7 @@
     assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
     CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c",
             1, LYS_LEAF, 1, 0, NULL, 0);
-    CHECK_LOG_CTX(NULL, NULL);
+    CHECK_LOG_CTX(NULL, NULL, 0);
     CHECK_LYD_STRING(tree, LYD_PRINT_SHRINK | LYD_PRINT_WITHSIBLINGS,
             "{\"a:l1\":[{\"a\":\"a\",\"b\":\"b\",\"c\":1}]}");
     lyd_free_all(tree);
@@ -515,7 +510,7 @@
     /* invalid value, no flags */
     data = "{\"a:foo3\":[null]}";
     PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "Invalid non-number-encoded uint32 value \"\".", "Schema location \"/a:foo3\", line number 1.");
+            "Invalid non-number-encoded uint32 value \"\".", "/a:foo3", 1);
 
     /* opaq flag */
     CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
@@ -545,8 +540,7 @@
     /* missing key, no flags */
     data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\",\"d\":\"val_d\"}]}";
     PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "List instance is missing its key \"c\".",
-            "Data location \"/a:l1[a='val_a'][b='val_b']\", line number 1.");
+            "List instance is missing its key \"c\".", "/a:l1[a='val_a'][b='val_b']", 1);
 
     /* opaq flag */
     CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
@@ -557,8 +551,7 @@
     /* invalid key, no flags */
     data = "{\"a:l1\":[{\"a\":\"val_a\",\"b\":\"val_b\",\"c\":\"val_c\"}]}";
     PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "Invalid non-number-encoded int16 value \"val_c\".",
-            "Data location \"/a:l1[a='val_a'][b='val_b']/c\", line number 1.");
+            "Invalid non-number-encoded int16 value \"val_c\".", "/a:l1[a='val_a'][b='val_b']/c", 1);
 
     /* opaq flag */
     CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
@@ -580,13 +573,12 @@
 
     /* invalid metadata */
     data = "{\"@a:foo\":\"str\",\"@a:foo3\":1,\"a:foo3\":2}";
-    PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "Unknown module of node \"@a:foo\".", "Path \"/\".");
-    CHECK_LOG_CTX("Missing JSON data instance to be coupled with @a:foo metadata.", "Data location \"/@a:foo\", line number 1.");
+    PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID, "Unknown module of node \"@a:foo\".", "/", 0);
+    CHECK_LOG_CTX("Missing JSON data instance to be coupled with @a:foo metadata.", "/@a:foo", 1);
 
     /* empty name */
     PARSER_CHECK_ERROR("{\"@a:foo\":{\"\":0}}", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "JSON object member name cannot be a zero-length string.", "Data location \"/@a:foo\", line number 1.");
+            "JSON object member name cannot be a zero-length string.", "/@a:foo", 1);
 
     /* opaque data tree format print */
     data =
@@ -911,7 +903,7 @@
     data = "{\"a:c\":{\"x\":\"xval\",\"@x\":{\"a:hint\":\"value\"}}}";
     assert_int_equal(LY_EVALID, lyd_parse_data_mem(_UC->ctx, data, LYD_JSON, 0, LYD_VALIDATE_PRESENT, &tree));
     assert_null(tree);
-    CHECK_LOG_CTX("Invalid non-number-encoded int8 value \"value\".", "Path \"/a:c/x/@a:hint\", line number 1.");
+    CHECK_LOG_CTX("Invalid non-number-encoded int8 value \"value\".", "/a:c/x/@a:hint", 1);
 }
 
 int
diff --git a/tests/utests/data/test_parser_xml.c b/tests/utests/data/test_parser_xml.c
index 4f33f00..d5336c0 100644
--- a/tests/utests/data/test_parser_xml.c
+++ b/tests/utests/data/test_parser_xml.c
@@ -61,9 +61,9 @@
 #define CHECK_PARSE_LYD(INPUT, PARSE_OPTION, VALIDATE_OPTION, TREE) \
     CHECK_PARSE_LYD_PARAM(INPUT, LYD_XML, PARSE_OPTION, VALIDATE_OPTION, LY_SUCCESS, TREE)
 
-#define PARSER_CHECK_ERROR(INPUT, PARSE_OPTION, VALIDATE_OPTION, MODEL, RET_VAL, ERR_MESSAGE, ERR_PATH) \
+#define PARSER_CHECK_ERROR(INPUT, PARSE_OPTION, VALIDATE_OPTION, MODEL, RET_VAL, ERR_MESSAGE, ERR_PATH, ERR_LINE) \
     assert_int_equal(RET_VAL, lyd_parse_data_mem(UTEST_LYCTX, INPUT, LYD_XML, PARSE_OPTION, VALIDATE_OPTION, &MODEL));\
-    CHECK_LOG_CTX(ERR_MESSAGE, ERR_PATH);\
+    CHECK_LOG_CTX(ERR_MESSAGE, ERR_PATH, ERR_LINE);\
     assert_null(MODEL)
 
 #define CHECK_LYD_STRING(IN_MODEL, PRINT_OPTION, TEXT) \
@@ -118,8 +118,7 @@
     /* invalid value */
     data = "<l1 xmlns=\"urn:tests:a\"><a>val-a</a><b>val-b</b><c>1</c><cont><e>0</e></cont></l1>";
     PARSER_CHECK_ERROR(data, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "Invalid boolean value \"0\".",
-            "Data location \"/a:l1[a='val-a'][b='val-b'][c='1']/cont/e\", line number 1.");
+            "Invalid boolean value \"0\".", "/a:l1[a='val-a'][b='val-b'][c='1']/cont/e", 1);
 }
 
 static void
@@ -217,22 +216,21 @@
 
     /* missing keys */
     PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "List instance is missing its key \"a\".", "Data location \"/a:l1[b='b'][c='1']\", line number 1.");
-    CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL);
+            "List instance is missing its key \"a\".", "/a:l1[b='b'][c='1']", 1);
+    CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL, 0);
 
     PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><a>a</a></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "List instance is missing its key \"b\".", "Data location \"/a:l1[a='a']\", line number 1.");
+            "List instance is missing its key \"b\".", "/a:l1[a='a']", 1);
 
     PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><b>b</b><a>a</a></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "List instance is missing its key \"c\".", "Data location \"/a:l1[a='a'][b='b']\", line number 1.");
-    CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL);
+            "List instance is missing its key \"c\".", "/a:l1[a='a'][b='b']", 1);
+    CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL, 0);
 
     /* key duplicate */
     PARSER_CHECK_ERROR("<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a><c>1</c></l1>", 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "Duplicate instance of \"c\".",
-            "Data location \"/a:l1[a='a'][b='b'][c='1'][c='1']/c\", line number 1.");
-    CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL);
-    CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL);
+            "Duplicate instance of \"c\".", "/a:l1[a='a'][b='b'][c='1'][c='1']/c", 1);
+    CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL, 0);
+    CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL, 0);
 
     /* keys order */
     CHECK_PARSE_LYD("<l1 xmlns=\"urn:tests:a\"><d>d</d><a>a</a><c>1</c><b>b</b></l1>", 0, LYD_VALIDATE_PRESENT, tree);
@@ -247,7 +245,7 @@
     CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c", 1, LYS_LEAF, 1, 0, NULL, 0);
     assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
     CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "d", 1, LYS_LEAF, 1, 0, NULL, 0);
-    CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL);
+    CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL, 0);
     lyd_free_all(tree);
 
     data = "<l1 xmlns=\"urn:tests:a\"><c>1</c><b>b</b><a>a</a></l1>";
@@ -260,12 +258,12 @@
     CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "b", 1, LYS_LEAF, 1, 0, NULL, 0);
     assert_non_null(leaf = (struct lyd_node_term *)leaf->next);
     CHECK_LYSC_NODE(leaf->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_KEY, 1, "c", 1, LYS_LEAF, 1, 0, NULL, 0);
-    CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL);
-    CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL);
+    CHECK_LOG_CTX("Invalid position of the key \"a\" in a list.", NULL, 0);
+    CHECK_LOG_CTX("Invalid position of the key \"b\" in a list.", NULL, 0);
     lyd_free_all(tree);
 
     PARSER_CHECK_ERROR(data, LYD_PARSE_STRICT, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "Invalid position of the key \"b\" in a list.", "Data location \"/a:l1[c='1']/b\", line number 1.");
+            "Invalid position of the key \"b\" in a list.", "/a:l1[c='1']/b", 1);
 }
 
 static void
@@ -299,7 +297,7 @@
     /* invalid value, no flags */
     data = "<foo3 xmlns=\"urn:tests:a\"/>";
     PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "Invalid type uint32 empty value.", "Schema location \"/a:foo3\", line number 1.");
+            "Invalid type uint32 empty value.", "/a:foo3", 1);
 
     /* opaq flag */
     CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
@@ -321,8 +319,7 @@
             "  <d>val_d</d>\n"
             "</l1>\n";
     PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "List instance is missing its key \"c\".",
-            "Data location \"/a:l1[a='val_a'][b='val_b']\", line number 5.");
+            "List instance is missing its key \"c\".", "/a:l1[a='val_a'][b='val_b']", 5);
 
     /* opaq flag */
     CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
@@ -337,8 +334,7 @@
             "  <c>val_c</c>\n"
             "</l1>\n";
     PARSER_CHECK_ERROR(data, 0, LYD_VALIDATE_PRESENT, tree, LY_EVALID,
-            "Invalid type int16 value \"val_c\".",
-            "Data location \"/a:l1[a='val_a'][b='val_b']/c\", line number 4.");
+            "Invalid type int16 value \"val_c\".", "/a:l1[a='val_a'][b='val_b']/c", 4);
 
     /* opaq flag */
     CHECK_PARSE_LYD(data, LYD_PARSE_OPAQ | LYD_PARSE_ONLY, 0, tree);
@@ -353,7 +349,7 @@
             "  <c xmld:id=\"D\">1</c>\n"
             "</a>\n",
             LYD_XML, LYD_PARSE_OPAQ, LYD_VALIDATE_PRESENT, &tree));
-    CHECK_LOG_CTX("Unknown XML prefix \"xmld\".", "Data location \"/a\", line number 3.");
+    CHECK_LOG_CTX("Unknown XML prefix \"xmld\".", "/a", 3);
 }
 
 static void
@@ -658,7 +654,7 @@
     assert_int_equal(LY_EVALID, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_NETCONF, &tree, &op));
     ly_in_free(in, 0);
     CHECK_LOG_CTX("Invalid enumeration value \"merge2\".",
-            "Path \"/ietf-netconf:copy-config/source/config/a:l1[a='val_a'][b='val_b'][c='5']/cont/e/@ietf-netconf:operation\", line number 13.");
+            "/ietf-netconf:copy-config/source/config/a:l1[a='val_a'][b='val_b'][c='5']/cont/e/@ietf-netconf:operation", 13);
     lyd_free_all(tree);
     assert_null(op);
 }
@@ -974,7 +970,7 @@
     data = "<c xmlns=\"urn:tests:a\" xmlns:a=\"urn:tests:a\"><x a:attr=\"value\">xval</x></c>";
     assert_int_equal(LY_EVALID, lyd_parse_data_mem(_UC->ctx, data, LYD_XML, 0, LYD_VALIDATE_PRESENT, &tree));
     assert_null(tree);
-    CHECK_LOG_CTX("Invalid enumeration value \"value\".", "Path \"/a:c/x/@a:attr\", line number 1.");
+    CHECK_LOG_CTX("Invalid enumeration value \"value\".", "/a:c/x/@a:attr", 1);
 }
 
 static void
@@ -1004,7 +1000,7 @@
     assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
     assert_int_equal(LY_EVALID, lyd_parse_data(UTEST_LYCTX, tree, in, LYD_XML, 0, LYD_VALIDATE_PRESENT, NULL));
     ly_in_free(in, 0);
-    CHECK_LOG_CTX("Duplicate instance of \"cont\".", "Data location \"/a:l1[a='val_a'][b='val_b'][c='1']/cont\".");
+    CHECK_LOG_CTX("Duplicate instance of \"cont\".", "/a:l1[a='val_a'][b='val_b'][c='1']/cont", 0);
 
     lyd_free_all(tree);
 }
diff --git a/tests/utests/data/test_tree_data.c b/tests/utests/data/test_tree_data.c
index 5dd3473..fabd170 100644
--- a/tests/utests/data/test_tree_data.c
+++ b/tests/utests/data/test_tree_data.c
@@ -370,8 +370,7 @@
     CHECK_PARSE_LYD(data, 0, LYD_VALIDATE_PRESENT, tree1);
     assert_int_equal(LY_EINVAL, lyd_dup_single(((struct lyd_node_inner *)tree1)->child->prev,
             (struct lyd_node_inner *)tree1->next, LYD_DUP_WITH_PARENTS, NULL));
-    CHECK_LOG_CTX("None of the duplicated node \"c\" schema parents match the provided parent \"c\".",
-            NULL);
+    CHECK_LOG_CTX("None of the duplicated node \"c\" schema parents match the provided parent \"c\".", NULL, 0);
     lyd_free_all(tree1);
 }
 
@@ -499,7 +498,7 @@
     assert_int_equal(LY_SUCCESS, lyd_find_path(root, "/c:cont/pref[.='fc00::/64']", 0, NULL));
 
     assert_int_equal(LY_EVALID, lyd_find_path(root, "/cont", 0, NULL));
-    CHECK_LOG_CTX("Prefix missing for \"cont\" in path.", "Schema location \"/c:cont\".");
+    CHECK_LOG_CTX("Prefix missing for \"cont\" in path.", "/c:cont", 0);
     assert_int_equal(LY_SUCCESS, lyd_find_path(root, "nexthop[gateway='2100::1']", 0, NULL));
 
     lyd_free_all(root);
@@ -539,7 +538,7 @@
 
     /* The run must not crash due to the assert that checks the hash. */
     CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("Duplicate instance of \"ll\".", "Data location \"/test-data-hash:c/ll[.='']\", line number 1.");
+    CHECK_LOG_CTX("Duplicate instance of \"ll\".", "/test-data-hash:c/ll[.='']", 1);
     lyd_free_all(tree);
 }
 
diff --git a/tests/utests/data/test_validation.c b/tests/utests/data/test_validation.c
index d0dcae5..17fd078 100644
--- a/tests/utests/data/test_validation.c
+++ b/tests/utests/data/test_validation.c
@@ -57,7 +57,7 @@
     UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
 
     CHECK_PARSE_LYD_PARAM("<c xmlns=\"urn:tests:a\">hey</c>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("When condition \"/cont/b = 'val_b'\" not satisfied.", "Data location \"/a:c\".");
+    CHECK_LOG_CTX("When condition \"/cont/b = 'val_b'\" not satisfied.", "/a:c", 0);
 
     LYD_TREE_CREATE("<cont xmlns=\"urn:tests:a\"><b>val_b</b></cont><c xmlns=\"urn:tests:a\">hey</c>", tree);
     CHECK_LYSC_NODE(tree->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR, 1, "c", 0, LYS_LEAF, 0, 0, NULL, 1);
@@ -105,10 +105,10 @@
     UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
 
     CHECK_PARSE_LYD_PARAM("<d xmlns=\"urn:tests:a\">hey</d>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("When condition \"../c = 'val_c'\" not satisfied.", "Data location \"/a:d\".");
+    CHECK_LOG_CTX("When condition \"../c = 'val_c'\" not satisfied.", "/a:d", 0);
 
     CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:a\"><b>hey</b></cont>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("When condition \"../a = 'val_a'\" not satisfied.", "Data location \"/a:cont/b\".");
+    CHECK_LOG_CTX("When condition \"../a = 'val_a'\" not satisfied.", "/a:cont/b", 0);
 
     LYD_TREE_CREATE("<c xmlns=\"urn:tests:a\">val_c</c><d xmlns=\"urn:tests:a\">hey</d>", tree);
     CHECK_LYSC_NODE(tree->next->next->schema, NULL, 0, LYS_CONFIG_W | LYS_STATUS_CURR | LYS_MAND_TRUE, 1, "d", 0, LYS_LEAF, 0, 0, NULL, 1);
@@ -196,13 +196,13 @@
     UTEST_ADD_MODULE(schema, LYS_IN_YANG, NULL, NULL);
 
     CHECK_PARSE_LYD_PARAM("<d xmlns=\"urn:tests:b\"/>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX_APPTAG("Mandatory choice \"choic\" data do not exist.", "Schema location \"/b:choic\".", "missing-choice");
+    CHECK_LOG_CTX_APPTAG("Mandatory choice \"choic\" data do not exist.", "/b:choic", 0, "missing-choice");
 
     CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:b\">string</l><d xmlns=\"urn:tests:b\"/>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("Mandatory node \"c\" instance does not exist.", "Schema location \"/b:c\".");
+    CHECK_LOG_CTX("Mandatory node \"c\" instance does not exist.", "/b:c", 0);
 
     CHECK_PARSE_LYD_PARAM("<a xmlns=\"urn:tests:b\">string</a>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("Mandatory node \"c\" instance does not exist.", "Schema location \"/b:c\".");
+    CHECK_LOG_CTX("Mandatory node \"c\" instance does not exist.", "/b:c", 0);
 
     LYD_TREE_CREATE("<a xmlns=\"urn:tests:b\">string</a><c xmlns=\"urn:tests:b\">string2</c>", tree);
     lyd_free_siblings(tree);
@@ -246,12 +246,12 @@
     CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:c\">mate</l>"
             "<d xmlns=\"urn:tests:c\"/>",
             LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX_APPTAG("Too few \"l\" instances.", "Schema location \"/c:choic/b/l\".", "too-few-elements");
+    CHECK_LOG_CTX_APPTAG("Too few \"l\" instances.", "/c:choic/b/l", 0, "too-few-elements");
 
     CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:c\">val1</l>"
             "<l xmlns=\"urn:tests:c\">val2</l>",
             LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX_APPTAG("Too few \"l\" instances.", "Schema location \"/c:choic/b/l\".", "too-few-elements");
+    CHECK_LOG_CTX_APPTAG("Too few \"l\" instances.", "/c:choic/b/l", 0, "too-few-elements");
 
     LYD_TREE_CREATE("<l xmlns=\"urn:tests:c\">val1</l>"
             "<l xmlns=\"urn:tests:c\">val2</l>"
@@ -267,8 +267,7 @@
             "<lt xmlns=\"urn:tests:c\"><k>val4</k></lt>"
             "<lt xmlns=\"urn:tests:c\"><k>val5</k></lt>"
             "<lt xmlns=\"urn:tests:c\"><k>val6</k></lt>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX_APPTAG("Too many \"lt\" instances.", "Data location \"/c:lt[k='val5']\".",
-            "too-many-elements");
+    CHECK_LOG_CTX_APPTAG("Too many \"lt\" instances.", "/c:lt[k='val5']", 0, "too-many-elements");
 }
 
 const char *schema_d =
@@ -356,7 +355,7 @@
             "    <l1>same</l1>\n"
             "</lt>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
     CHECK_LOG_CTX_APPTAG("Unique data leaf(s) \"l1\" not satisfied in \"/d:lt[k='val1']\" and \"/d:lt[k='val2']\".",
-            "Data location \"/d:lt[k='val2']\".", "data-not-unique");
+            "/d:lt[k='val2']", 0, "data-not-unique");
 
     /* now try with more instances */
     LYD_TREE_CREATE("<lt xmlns=\"urn:tests:d\">\n"
@@ -454,7 +453,7 @@
             "    <l1>8</l1>\n"
             "</lt>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
     CHECK_LOG_CTX_APPTAG("Unique data leaf(s) \"l1\" not satisfied in \"/d:lt[k='val7']\" and \"/d:lt[k='val2']\".",
-            "Data location \"/d:lt[k='val2']\".", "data-not-unique");
+            "/d:lt[k='val2']", 0, "data-not-unique");
 }
 
 static void
@@ -579,8 +578,7 @@
             "    </lt3>\n"
             "</lt2>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
     CHECK_LOG_CTX_APPTAG("Unique data leaf(s) \"l3\" not satisfied in \"/d:lt2[k='val2']/lt3[kk='val3']\" and "
-            "\"/d:lt2[k='val2']/lt3[kk='val1']\".",
-            "Data location \"/d:lt2[k='val2']/lt3[kk='val1']\".", "data-not-unique");
+            "\"/d:lt2[k='val2']/lt3[kk='val1']\".", "/d:lt2[k='val2']/lt3[kk='val1']", 0, "data-not-unique");
 
     CHECK_PARSE_LYD_PARAM("<lt2 xmlns=\"urn:tests:d\">\n"
             "    <k>val1</k>\n"
@@ -618,7 +616,7 @@
             "    <l4>5</l4>\n"
             "</lt2>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
     CHECK_LOG_CTX_APPTAG("Unique data leaf(s) \"cont/l2 l4\" not satisfied in \"/d:lt2[k='val4']\" and \"/d:lt2[k='val2']\".",
-            "Data location \"/d:lt2[k='val2']\".", "data-not-unique");
+            "/d:lt2[k='val2']", 0, "data-not-unique");
 
     CHECK_PARSE_LYD_PARAM("<lt2 xmlns=\"urn:tests:d\">\n"
             "    <k>val1</k>\n"
@@ -664,7 +662,7 @@
             "    <l6>3</l6>\n"
             "</lt2>", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
     CHECK_LOG_CTX_APPTAG("Unique data leaf(s) \"l5 l6\" not satisfied in \"/d:lt2[k='val5']\" and \"/d:lt2[k='val3']\".",
-            "Data location \"/d:lt2[k='val3']\".", "data-not-unique");
+            "/d:lt2[k='val3']", 0, "data-not-unique");
 }
 
 static void
@@ -725,28 +723,28 @@
 
     CHECK_PARSE_LYD_PARAM("<d xmlns=\"urn:tests:e\">25</d><d xmlns=\"urn:tests:e\">50</d>",
             LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("Duplicate instance of \"d\".", "Data location \"/e:d\".");
+    CHECK_LOG_CTX("Duplicate instance of \"d\".", "/e:d", 0);
 
     CHECK_PARSE_LYD_PARAM("<lt xmlns=\"urn:tests:e\"><k>A</k></lt>"
             "<lt xmlns=\"urn:tests:e\"><k>B</k></lt>"
             "<lt xmlns=\"urn:tests:e\"><k>A</k></lt>",
             LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("Duplicate instance of \"lt\".", "Data location \"/e:lt[k='A']\".");
+    CHECK_LOG_CTX("Duplicate instance of \"lt\".", "/e:lt[k='A']", 0);
 
     CHECK_PARSE_LYD_PARAM("<ll xmlns=\"urn:tests:e\">A</ll>"
             "<ll xmlns=\"urn:tests:e\">B</ll>"
             "<ll xmlns=\"urn:tests:e\">B</ll>",
             LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("Duplicate instance of \"ll\".", "Data location \"/e:ll[.='B']\".");
+    CHECK_LOG_CTX("Duplicate instance of \"ll\".", "/e:ll[.='B']", 0);
 
     CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:e\"></cont><cont xmlns=\"urn:tests:e\"/>",
             LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("Duplicate instance of \"cont\".", "Data location \"/e:cont\".");
+    CHECK_LOG_CTX("Duplicate instance of \"cont\".", "/e:cont", 0);
 
     /* same tests again but using hashes */
     CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:e\"><d>25</d><d>50</d><ll>1</ll><ll>2</ll><ll>3</ll><ll>4</ll></cont>",
             LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("Duplicate instance of \"d\".", "Data location \"/e:cont/d\", line number 1.");
+    CHECK_LOG_CTX("Duplicate instance of \"d\".", "/e:cont/d", 1);
 
     CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:e\"><ll>1</ll><ll>2</ll><ll>3</ll><ll>4</ll>"
             "<lt><k>a</k></lt>"
@@ -755,12 +753,12 @@
             "<lt><k>d</k></lt>"
             "<lt><k>c</k></lt></cont>",
             LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("Duplicate instance of \"lt\".", "Data location \"/e:cont/lt[k='c']\", line number 1.");
+    CHECK_LOG_CTX("Duplicate instance of \"lt\".", "/e:cont/lt[k='c']", 1);
 
     CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:e\"><ll>1</ll><ll>2</ll><ll>3</ll><ll>4</ll>"
             "<ll>a</ll><ll>b</ll><ll>c</ll><ll>d</ll><ll>d</ll></cont>",
             LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("Duplicate instance of \"ll\".", "Data location \"/e:cont/ll[.='d']\", line number 1.");
+    CHECK_LOG_CTX("Duplicate instance of \"ll\".", "/e:cont/ll[.='d']", 1);
 
     /* cases */
     CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:e\">a</l>"
@@ -768,13 +766,13 @@
             "<l xmlns=\"urn:tests:e\">c</l>"
             "<l xmlns=\"urn:tests:e\">b</l>",
             LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("Duplicate instance of \"l\".", "Data location \"/e:l[.='b']\".");
+    CHECK_LOG_CTX("Duplicate instance of \"l\".", "/e:l[.='b']", 0);
 
     CHECK_PARSE_LYD_PARAM("<l xmlns=\"urn:tests:e\">a</l><l xmlns=\"urn:tests:e\">b</l>"
             "<l xmlns=\"urn:tests:e\">c</l>"
             "<a xmlns=\"urn:tests:e\">aa</a>",
             LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("Data for both cases \"a\" and \"b\" exist.", "Schema location \"/e:choic\".");
+    CHECK_LOG_CTX("Data for both cases \"a\" and \"b\" exist.", "/e:choic", 0);
 }
 
 static void
@@ -1094,13 +1092,11 @@
             "  </cont2>\n"
             "</cont>\n";
     CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY | LYD_PARSE_NO_STATE, 0, LY_EVALID, tree);
-    CHECK_LOG_CTX("Unexpected data state node \"cont2\" found.",
-            "Data location \"/h:cont/cont2\", line number 3.");
+    CHECK_LOG_CTX("Unexpected data state node \"cont2\" found.", "/h:cont/cont2", 3);
 
     CHECK_PARSE_LYD_PARAM(data, LYD_XML, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
     assert_int_equal(LY_EVALID, lyd_validate_all(&tree, NULL, LYD_VALIDATE_PRESENT | LYD_VALIDATE_NO_STATE, NULL));
-    CHECK_LOG_CTX("Unexpected data state node \"cont2\" found.",
-            "Data location \"/h:cont/cont2\".");
+    CHECK_LOG_CTX("Unexpected data state node \"cont2\" found.", "/h:cont/cont2", 0);
     lyd_free_all(tree);
 }
 
@@ -1138,8 +1134,7 @@
             "  <l>wrong</l>\n"
             "  <l2>val</l2>\n"
             "</cont>\n", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX_APPTAG("Must condition \"../l = 'right'\" not satisfied.",
-            "Data location \"/i:cont/l2\".", "must-violation");
+    CHECK_LOG_CTX_APPTAG("Must condition \"../l = 'right'\" not satisfied.", "/i:cont/l2", 0, "must-violation");
 
     LYD_TREE_CREATE("<cont xmlns=\"urn:tests:i\">\n"
             "  <l>right</l>\n"
@@ -1151,7 +1146,7 @@
             "  <l>wrong</l>\n"
             "  <l3>val</l3>\n"
             "</cont>\n", LYD_XML, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX_APPTAG("l leaf is not left", "Data location \"/i:cont/l3\".", "not-left");
+    CHECK_LOG_CTX_APPTAG("l leaf is not left", "/i:cont/l3", 0, "not-left");
 }
 
 static void
@@ -1199,10 +1194,10 @@
             "  <ll>ahoy</ll>\n"
             "</cont>\n";
     CHECK_PARSE_LYD_PARAM(data, LYD_XML, 0, LYD_VALIDATE_PRESENT | LYD_VALIDATE_MULTI_ERROR, LY_EVALID, tree);
-    CHECK_LOG_CTX_APPTAG("Too few \"ll\" instances.", "Schema location \"/ii:cont/ll\".", "too-few-elements");
-    CHECK_LOG_CTX_APPTAG("l leaf is not left", "Data location \"/ii:cont/l3\".", "not-left");
-    CHECK_LOG_CTX_APPTAG("Must condition \"../l = 'right'\" not satisfied.", "Data location \"/ii:cont/l2\".", "must-violation");
-    CHECK_LOG_CTX_APPTAG("Invalid type uint32 value \"ahoy\".", "Data location \"/ii:cont/ll\", line number 6.", NULL);
+    CHECK_LOG_CTX_APPTAG("Too few \"ll\" instances.", "/ii:cont/ll", 0, "too-few-elements");
+    CHECK_LOG_CTX_APPTAG("l leaf is not left", "/ii:cont/l3", 0, "not-left");
+    CHECK_LOG_CTX_APPTAG("Must condition \"../l = 'right'\" not satisfied.", "/ii:cont/l2", 0, "must-violation");
+    CHECK_LOG_CTX_APPTAG("Invalid type uint32 value \"ahoy\".", "/ii:cont/ll", 6, NULL);
 
     /* json */
     data = "{\n"
@@ -1215,10 +1210,10 @@
             "  }\n"
             "}\n";
     CHECK_PARSE_LYD_PARAM(data, LYD_JSON, 0, LYD_VALIDATE_PRESENT | LYD_VALIDATE_MULTI_ERROR, LY_EVALID, tree);
-    CHECK_LOG_CTX_APPTAG("Too few \"ll\" instances.", "Schema location \"/ii:cont/ll\".", "too-few-elements");
-    CHECK_LOG_CTX_APPTAG("l leaf is not left", "Data location \"/ii:cont/l3\".", "not-left");
-    CHECK_LOG_CTX_APPTAG("Must condition \"../l = 'right'\" not satisfied.", "Data location \"/ii:cont/l2\".", "must-violation");
-    CHECK_LOG_CTX_APPTAG("Invalid non-number-encoded uint32 value \"ahoy\".", "Data location \"/ii:cont/ll\", line number 7.", NULL);
+    CHECK_LOG_CTX_APPTAG("Too few \"ll\" instances.", "/ii:cont/ll", 0, "too-few-elements");
+    CHECK_LOG_CTX_APPTAG("l leaf is not left", "/ii:cont/l3", 0, "not-left");
+    CHECK_LOG_CTX_APPTAG("Must condition \"../l = 'right'\" not satisfied.", "/ii:cont/l2", 0, "must-violation");
+    CHECK_LOG_CTX_APPTAG("Invalid non-number-encoded uint32 value \"ahoy\".", "/ii:cont/ll", 7, NULL);
 
     /* validation */
     data = "{\n"
@@ -1233,11 +1228,11 @@
     CHECK_PARSE_LYD_PARAM(data, LYD_JSON, LYD_PARSE_ONLY, 0, LY_SUCCESS, tree);
     assert_int_equal(LY_EVALID, lyd_validate_all(&tree, NULL, LYD_VALIDATE_PRESENT | LYD_VALIDATE_MULTI_ERROR, NULL));
     lyd_free_tree(tree);
-    CHECK_LOG_CTX_APPTAG("Too few \"ll\" instances.", "Schema location \"/ii:cont/ll\".", "too-few-elements");
-    CHECK_LOG_CTX_APPTAG("l leaf is not left", "Data location \"/ii:cont/l3\".", "not-left");
-    CHECK_LOG_CTX_APPTAG("Must condition \"../l = 'right'\" not satisfied.", "Data location \"/ii:cont/l2\".", "must-violation");
-    CHECK_LOG_CTX_APPTAG("Duplicate instance of \"l\".", "Data location \"/ii:cont/l\".", NULL);
-    CHECK_LOG_CTX_APPTAG("Duplicate instance of \"l\".", "Data location \"/ii:cont/l\".", NULL);
+    CHECK_LOG_CTX_APPTAG("Too few \"ll\" instances.", "/ii:cont/ll", 0, "too-few-elements");
+    CHECK_LOG_CTX_APPTAG("l leaf is not left", "/ii:cont/l3", 0, "not-left");
+    CHECK_LOG_CTX_APPTAG("Must condition \"../l = 'right'\" not satisfied.", "/ii:cont/l2", 0, "must-violation");
+    CHECK_LOG_CTX_APPTAG("Duplicate instance of \"l\".", "/ii:cont/l", 0, NULL);
+    CHECK_LOG_CTX_APPTAG("Duplicate instance of \"l\".", "/ii:cont/l", 0, NULL);
 }
 
 const char *schema_j =
@@ -1315,7 +1310,7 @@
     /* missing leafref */
     assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, NULL, LYD_TYPE_RPC_YANG, NULL));
     CHECK_LOG_CTX("Invalid leafref value \"target\" - no target instance \"/lf3\" with the same value.",
-            "Data location \"/j:cont/l1[k='val1']/act/lf2\".");
+            "/j:cont/l1[k='val1']/act/lf2", 0);
     ly_in_free(in, 0);
 
     CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
@@ -1326,8 +1321,7 @@
 
     /* input must false */
     assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, tree, LYD_TYPE_RPC_YANG, NULL));
-    CHECK_LOG_CTX("Must condition \"../../lf1 = 'true'\" not satisfied.",
-            "Data location \"/j:cont/l1[k='val1']/act\".");
+    CHECK_LOG_CTX("Must condition \"../../lf1 = 'true'\" not satisfied.", "/j:cont/l1[k='val1']/act", 0);
 
     lyd_free_all(tree);
     CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
@@ -1380,7 +1374,7 @@
     assert_int_equal(LY_SUCCESS, ly_in_new_memory(data, &in));
     assert_int_equal(LY_EVALID, lyd_parse_op(UTEST_LYCTX, NULL, in, LYD_XML, LYD_TYPE_RPC_YANG, &tree, NULL));
     CHECK_LOG_CTX("Unsatisfied length - string \"123\" length is not allowed.",
-            "Data location \"/val-str:modify-user-password/new-password\", line number 3.");
+            "/val-str:modify-user-password/new-password", 3);
     ly_in_free(in, 0);
 }
 
@@ -1409,7 +1403,7 @@
     /* missing leafref */
     assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, NULL, LYD_TYPE_REPLY_YANG, NULL));
     CHECK_LOG_CTX("Invalid leafref value \"target\" - no target instance \"/lf4\" with the same value.",
-            "Data location \"/j:cont/l1[k='val1']/act/lf2\".");
+            "/j:cont/l1[k='val1']/act/lf2", 0);
 
     CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
             "  <lf1>not true</lf1>\n"
@@ -1419,7 +1413,7 @@
 
     /* input must false */
     assert_int_equal(LY_EVALID, lyd_validate_op(op_tree, tree, LYD_TYPE_REPLY_YANG, NULL));
-    CHECK_LOG_CTX("Must condition \"../../lf1 = 'true2'\" not satisfied.", "Data location \"/j:cont/l1[k='val1']/act\".");
+    CHECK_LOG_CTX("Must condition \"../../lf1 = 'true2'\" not satisfied.", "/j:cont/l1[k='val1']/act", 0);
 
     lyd_free_all(tree);
     CHECK_PARSE_LYD_PARAM("<cont xmlns=\"urn:tests:j\">\n"
@@ -1509,8 +1503,7 @@
             "    \"g7\": \"value_g7\"\n"
             "  }\n"
             "}\n", LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("Data for both cases \"v0\" and \"v2\" exist.",
-            "Data location \"/k:ch\", line number 6.");
+    CHECK_LOG_CTX("Data for both cases \"v0\" and \"v2\" exist.", "/k:ch", 6);
 
     CHECK_PARSE_LYD_PARAM(
             "{\n"
@@ -1519,8 +1512,7 @@
             "    \"g0\": \"value_g0\"\n"
             "  }\n"
             "}\n", LYD_JSON, 0, LYD_VALIDATE_PRESENT, LY_EVALID, tree);
-    CHECK_LOG_CTX("Data for both cases \"v0\" and \"v2\" exist.",
-            "Data location \"/k:ch\", line number 6.");
+    CHECK_LOG_CTX("Data for both cases \"v0\" and \"v2\" exist.", "/k:ch", 6);
 }
 
 int