Skip to content

Commit a878a89

Browse files
committed
parser UPDATE guess opaque node schema nodes
... for their descendant parsing purposes. Refs #2086
1 parent 47da70b commit a878a89

File tree

11 files changed

+226
-72
lines changed

11 files changed

+226
-72
lines changed

src/common.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,21 @@ void ly_log_location(const struct lysc_node *scnode, const struct lyd_node *dnod
129129
*/
130130
void ly_log_location_revert(uint32_t scnode_steps, uint32_t dnode_steps, uint32_t path_steps, uint32_t in_steps);
131131

132+
/**
133+
* @brief Get the stored data node for logging at the index.
134+
*
135+
* @param[in] idx Index of the data node.
136+
* @return Logged data node, NULL if out of range.
137+
*/
138+
const struct lyd_node *ly_log_location_dnode(uint32_t idx);
139+
140+
/**
141+
* @brief Get the count of stored data nodes for logging.
142+
*
143+
* @return Count of the data nodes.
144+
*/
145+
uint32_t ly_log_location_dnode_count(void);
146+
132147
/**
133148
* @brief Update location data for logger, not provided arguments (NULLs) are kept (does not override).
134149
*

src/log.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,22 @@ ly_log_location_revert(uint32_t scnode_steps, uint32_t dnode_steps, uint32_t pat
500500
}
501501
}
502502

503+
const struct lyd_node *
504+
ly_log_location_dnode(uint32_t idx)
505+
{
506+
if (idx < log_location.dnodes.count) {
507+
return log_location.dnodes.dnodes[idx];
508+
}
509+
510+
return NULL;
511+
}
512+
513+
uint32_t
514+
ly_log_location_dnode_count(void)
515+
{
516+
return log_location.dnodes.count;
517+
}
518+
503519
/**
504520
* @brief Store generated error in a context.
505521
*

src/parser_common.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,63 @@ lyd_parser_find_operation(const struct lyd_node *parent, uint32_t int_opts, stru
157157
return LY_SUCCESS;
158158
}
159159

160+
const struct lysc_node *
161+
lyd_parser_node_schema(const struct lyd_node *node)
162+
{
163+
uint32_t i;
164+
const struct lyd_node *iter;
165+
const struct lysc_node *schema = NULL;
166+
const struct lys_module *mod;
167+
168+
if (!node) {
169+
return NULL;
170+
} else if (node->schema) {
171+
/* simplest case */
172+
return node->schema;
173+
}
174+
175+
/* find the first schema node in the parsed nodes */
176+
i = ly_log_location_dnode_count();
177+
if (i) {
178+
do {
179+
--i;
180+
if (ly_log_location_dnode(i)->schema) {
181+
/* this node is processed */
182+
schema = ly_log_location_dnode(i)->schema;
183+
++i;
184+
break;
185+
}
186+
} while (i);
187+
}
188+
189+
/* get schema node of an opaque node */
190+
do {
191+
/* get next data node */
192+
if (i == ly_log_location_dnode_count()) {
193+
iter = node;
194+
} else {
195+
iter = ly_log_location_dnode(i);
196+
}
197+
assert(!iter->schema);
198+
199+
/* get module */
200+
mod = lyd_owner_module(iter);
201+
if (!mod) {
202+
/* unknown module, no schema node */
203+
schema = NULL;
204+
break;
205+
}
206+
207+
/* get schema node */
208+
schema = lys_find_child(schema, mod, LYD_NAME(iter), 0, 0, 0);
209+
210+
/* move to the descendant */
211+
++i;
212+
} while (schema && (iter != node));
213+
214+
return schema;
215+
}
216+
160217
LY_ERR
161218
lyd_parser_check_schema(struct lyd_ctx *lydctx, const struct lysc_node *snode)
162219
{

src/parser_internal.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,14 @@ LY_ERR lyd_parser_notif_eventtime_validate(const struct lyd_node *node);
357357
*/
358358
LY_ERR lyd_parser_find_operation(const struct lyd_node *parent, uint32_t int_opts, struct lyd_node **op);
359359

360+
/**
361+
* @brief Get schema node of a node being parsed, use nodes stored for logging.
362+
*
363+
* @param[in] node Node whose schema node to get.
364+
* @return Schema node even for an opaque node, NULL if none found.
365+
*/
366+
const struct lysc_node *lyd_parser_node_schema(const struct lyd_node *node);
367+
360368
/**
361369
* @brief Check that a data node representing the @p snode is suitable based on options.
362370
*

src/parser_json.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ lydjson_get_snode(struct lyd_json_ctx *lydctx, ly_bool is_attr, const char *pref
295295
if (!parent && lydctx->ext) {
296296
*snode = lysc_ext_find_node(lydctx->ext, mod, name, name_len, 0, getnext_opts);
297297
} else {
298-
*snode = lys_find_child(parent ? parent->schema : NULL, mod, name, name_len, 0, getnext_opts);
298+
*snode = lys_find_child(lyd_parser_node_schema(parent), mod, name, name_len, 0, getnext_opts);
299299
}
300300
if (!*snode) {
301301
/* check for extension data */
@@ -1018,17 +1018,23 @@ lydjson_parse_opaq(struct lyd_json_ctx *lydctx, const char *name, size_t name_le
10181018
struct lyd_node *parent, enum LYJSON_PARSER_STATUS *status_p, enum LYJSON_PARSER_STATUS *status_inner_p,
10191019
struct lyd_node **first_p, struct lyd_node **node_p)
10201020
{
1021-
LY_CHECK_RET(lydjson_create_opaq(lydctx, name, name_len, prefix, prefix_len, parent, status_inner_p, node_p));
1021+
LY_ERR ret = LY_SUCCESS;
1022+
1023+
LY_CHECK_GOTO(ret = lydjson_create_opaq(lydctx, name, name_len, prefix, prefix_len, parent, status_inner_p, node_p), cleanup);
1024+
1025+
assert(*node_p);
1026+
LOG_LOCSET(NULL, *node_p, NULL, NULL);
10221027

10231028
if ((*status_p == LYJSON_ARRAY) && (*status_inner_p == LYJSON_NULL)) {
10241029
/* special array null value */
10251030
((struct lyd_node_opaq *)*node_p)->hints |= LYD_VALHINT_EMPTY;
10261031

10271032
/* must be the only item */
1028-
LY_CHECK_RET(lyjson_ctx_next(lydctx->jsonctx, status_inner_p));
1033+
LY_CHECK_GOTO(ret = lyjson_ctx_next(lydctx->jsonctx, status_inner_p), cleanup);
10291034
if (*status_inner_p != LYJSON_ARRAY_CLOSED) {
10301035
LOGVAL(lydctx->jsonctx->ctx, LYVE_SYNTAX, "Array \"null\" member with another member.");
1031-
return LY_EVALID;
1036+
ret = LY_EVALID;
1037+
goto cleanup;
10321038
}
10331039

10341040
goto finish;
@@ -1042,38 +1048,50 @@ lydjson_parse_opaq(struct lyd_json_ctx *lydctx, const char *name, size_t name_le
10421048

10431049
/* but first process children of the object in the array */
10441050
do {
1045-
LY_CHECK_RET(lydjson_subtree_r(lydctx, *node_p, lyd_node_child_p(*node_p), NULL));
1051+
LY_CHECK_GOTO(ret = lydjson_subtree_r(lydctx, *node_p, lyd_node_child_p(*node_p), NULL), cleanup);
10461052
*status_inner_p = lyjson_ctx_status(lydctx->jsonctx);
10471053
} while (*status_inner_p == LYJSON_OBJECT_NEXT);
10481054
} else {
10491055
/* array with values, leaf-list */
10501056
((struct lyd_node_opaq *)*node_p)->hints |= LYD_NODEHINT_LEAFLIST;
10511057
}
10521058

1053-
LY_CHECK_RET(lyjson_ctx_next(lydctx->jsonctx, status_inner_p));
1059+
LY_CHECK_GOTO(ret = lyjson_ctx_next(lydctx->jsonctx, status_inner_p), cleanup);
10541060
if (*status_inner_p == LYJSON_ARRAY_CLOSED) {
10551061
goto finish;
10561062
}
10571063
assert(*status_inner_p == LYJSON_ARRAY_NEXT);
10581064

10591065
/* continue with the next instance */
1060-
LY_CHECK_RET(lyjson_ctx_next(lydctx->jsonctx, status_inner_p));
1061-
assert(node_p);
1066+
LY_CHECK_GOTO(ret = lyjson_ctx_next(lydctx->jsonctx, status_inner_p), cleanup);
1067+
assert(*node_p);
10621068
lydjson_maintain_children(parent, first_p, node_p, lydctx->parse_opts & LYD_PARSE_ORDERED ? 1 : 0, NULL);
1063-
LY_CHECK_RET(lydjson_create_opaq(lydctx, name, name_len, prefix, prefix_len, parent, status_inner_p, node_p));
1069+
1070+
LOG_LOCBACK(0, 1, 0, 0);
1071+
1072+
LY_CHECK_GOTO(ret = lydjson_create_opaq(lydctx, name, name_len, prefix, prefix_len, parent, status_inner_p, node_p), cleanup);
1073+
1074+
assert(*node_p);
1075+
LOG_LOCSET(NULL, *node_p, NULL, NULL);
10641076
}
10651077

10661078
if (*status_p == LYJSON_OBJECT) {
10671079
/* process children */
10681080
do {
1069-
LY_CHECK_RET(lydjson_subtree_r(lydctx, *node_p, lyd_node_child_p(*node_p), NULL));
1081+
LY_CHECK_GOTO(ret = lydjson_subtree_r(lydctx, *node_p, lyd_node_child_p(*node_p), NULL), cleanup);
10701082
*status_p = lyjson_ctx_status(lydctx->jsonctx);
10711083
} while (*status_p == LYJSON_OBJECT_NEXT);
10721084
}
10731085

10741086
finish:
10751087
/* finish linking metadata */
1076-
return lydjson_metadata_finish(lydctx, lyd_node_child_p(*node_p));
1088+
ret = lydjson_metadata_finish(lydctx, lyd_node_child_p(*node_p));
1089+
1090+
cleanup:
1091+
if (*node_p) {
1092+
LOG_LOCBACK(0, 1, 0, 0);
1093+
}
1094+
return ret;
10771095
}
10781096

10791097
/**

src/parser_lyb.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1171,15 +1171,22 @@ lyb_parse_node_opaq(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, struct
11711171
value, strlen(value), &dynamic, format, val_prefix_data, LYD_HINT_DATA, &node);
11721172
LY_CHECK_GOTO(ret, cleanup);
11731173

1174+
assert(node);
1175+
LOG_LOCSET(NULL, node, NULL, NULL);
1176+
11741177
/* process children */
11751178
ret = lyb_parse_siblings(lybctx, node, NULL, NULL);
11761179
LY_CHECK_GOTO(ret, cleanup);
11771180

11781181
/* register parsed opaq node */
11791182
lyb_finish_opaq(lybctx, parent, flags, &attr, &node, first_p, parsed);
11801183
assert(!attr && !node);
1184+
LOG_LOCBACK(0, 1, 0, 0);
11811185

11821186
cleanup:
1187+
if (node) {
1188+
LOG_LOCBACK(0, 1, 0, 0);
1189+
}
11831190
free(prefix);
11841191
free(module_key);
11851192
free(name);
@@ -1265,9 +1272,13 @@ lyb_parse_node_any(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, const st
12651272
goto error;
12661273
}
12671274

1275+
assert(node);
1276+
LOG_LOCSET(NULL, node, NULL, NULL);
1277+
12681278
/* register parsed anydata node */
12691279
lyb_finish_node(lybctx, parent, flags, &meta, &node, first_p, parsed);
12701280

1281+
LOG_LOCBACK(0, 1, 0, 0);
12711282
return LY_SUCCESS;
12721283

12731284
error:
@@ -1304,6 +1315,9 @@ lyb_parse_node_inner(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, const
13041315
ret = lyd_create_inner(snode, &node);
13051316
LY_CHECK_GOTO(ret, error);
13061317

1318+
assert(node);
1319+
LOG_LOCSET(NULL, node, NULL, NULL);
1320+
13071321
/* process children */
13081322
ret = lyb_parse_siblings(lybctx, node, NULL, NULL);
13091323
LY_CHECK_GOTO(ret, error);
@@ -1320,9 +1334,13 @@ lyb_parse_node_inner(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, const
13201334
/* register parsed node */
13211335
lyb_finish_node(lybctx, parent, flags, &meta, &node, first_p, parsed);
13221336

1337+
LOG_LOCBACK(0, 1, 0, 0);
13231338
return LY_SUCCESS;
13241339

13251340
error:
1341+
if (node) {
1342+
LOG_LOCBACK(0, 1, 0, 0);
1343+
}
13261344
lyd_free_meta_siblings(meta);
13271345
lyd_free_tree(node);
13281346
return ret;
@@ -1355,8 +1373,12 @@ lyb_parse_node_leaf(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, const s
13551373
ret = lyb_create_term(lybctx, snode, &node);
13561374
LY_CHECK_GOTO(ret, error);
13571375

1376+
assert(node);
1377+
LOG_LOCSET(NULL, node, NULL, NULL);
1378+
13581379
lyb_finish_node(lybctx, parent, flags, &meta, &node, first_p, parsed);
13591380

1381+
LOG_LOCBACK(0, 1, 0, 0);
13601382
return LY_SUCCESS;
13611383

13621384
error:
@@ -1416,6 +1438,7 @@ lyb_parse_node_list(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, const s
14161438
struct lyd_node *node = NULL;
14171439
struct lyd_meta *meta = NULL;
14181440
uint32_t flags;
1441+
ly_bool log_node = 0;
14191442

14201443
/* register a new sibling */
14211444
ret = lyb_read_start_siblings(lybctx->lybctx);
@@ -1430,6 +1453,10 @@ lyb_parse_node_list(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, const s
14301453
ret = lyd_create_inner(snode, &node);
14311454
LY_CHECK_GOTO(ret, error);
14321455

1456+
assert(node);
1457+
LOG_LOCSET(NULL, node, NULL, NULL);
1458+
log_node = 1;
1459+
14331460
/* process children */
14341461
ret = lyb_parse_siblings(lybctx, node, NULL, NULL);
14351462
LY_CHECK_GOTO(ret, error);
@@ -1445,6 +1472,9 @@ lyb_parse_node_list(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, const s
14451472

14461473
/* register parsed list node */
14471474
lyb_finish_node(lybctx, parent, flags, &meta, &node, first_p, parsed);
1475+
1476+
LOG_LOCBACK(0, 1, 0, 0);
1477+
log_node = 0;
14481478
}
14491479

14501480
/* end the sibling */
@@ -1454,6 +1484,9 @@ lyb_parse_node_list(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, const s
14541484
return LY_SUCCESS;
14551485

14561486
error:
1487+
if (log_node) {
1488+
LOG_LOCBACK(0, 1, 0, 0);
1489+
}
14571490
lyd_free_meta_siblings(meta);
14581491
lyd_free_tree(node);
14591492
return ret;
@@ -1492,7 +1525,7 @@ lyb_parse_node(struct lyd_lyb_ctx *lybctx, struct lyd_node *parent, struct lyd_n
14921525
case LYB_NODE_CHILD:
14931526
case LYB_NODE_OPAQ:
14941527
/* read hash, find the schema node starting from parent schema, if any */
1495-
LY_CHECK_GOTO(ret = lyb_parse_schema_hash(lybctx, parent ? parent->schema : NULL, NULL, &snode), cleanup);
1528+
LY_CHECK_GOTO(ret = lyb_parse_schema_hash(lybctx, lyd_parser_node_schema(parent), NULL, &snode), cleanup);
14961529
break;
14971530
case LYB_NODE_EXT:
14981531
/* ext, read module name */

0 commit comments

Comments
 (0)