44 * @author Michal Vasko <mvasko@cesnet.cz>
55 * @brief Schema compilation of augments, deviations, and refines.
66 *
7- * Copyright (c) 2015 - 2024 CESNET, z.s.p.o.
7+ * Copyright (c) 2015 - 2026 CESNET, z.s.p.o.
88 *
99 * This source code is licensed under BSD 3-Clause License (the "License").
1010 * You may not use this file except in compliance with the License.
@@ -1275,10 +1275,59 @@ lys_apply_deviate_add(struct lysc_ctx *ctx, struct lysp_deviate_add *d, struct l
12751275 * num = d -> max ;
12761276 }
12771277
1278+ /* *ext-inst */
1279+ DUP_EXTS (ctx -> ctx , ctx -> pmod , target , lyplg_ext_nodetype2stmt (target -> nodetype ), d -> exts , target -> exts , lysp_ext_dup );
1280+
12781281cleanup :
12791282 return ret ;
12801283}
12811284
1285+ /**
1286+ * @brief Find a matching parsed ext instance.
1287+ *
1288+ * @param[in] ctx Context to use.
1289+ * @param[in] pmod Current parsed module.
1290+ * @param[in] ext_def1 Ext inst definition to match.
1291+ * @param[in] ext_arg1 Ext inst argument to match.
1292+ * @param[in] exts2 Ext inst array to search in.
1293+ * @param[out] v Index of the matching ext inst in @p exts2.
1294+ * @return LY_ERR value.
1295+ */
1296+ static LY_ERR
1297+ lys_apply_deviate_ext_inst_find (const struct ly_ctx * ctx , const struct lysp_module * pmod ,
1298+ const struct lysp_ext * ext_def1 , const char * ext_arg1 , const struct lysp_ext_instance * exts2 , LY_ARRAY_COUNT_TYPE * v )
1299+ {
1300+ struct lysp_ext * ext_def2 ;
1301+
1302+ LY_ARRAY_FOR (exts2 , * v ) {
1303+ if (!(exts2 [* v ].parent_stmt & LY_STMT_NODE_MASK )) {
1304+ /* match only node ext instances */
1305+ continue ;
1306+ }
1307+
1308+ lysp_ext_find_definition (ctx , pmod , & exts2 [* v ], NULL , & ext_def2 );
1309+ assert (ext_def2 );
1310+ if (ext_def1 != ext_def2 ) {
1311+ /* definition mismatch */
1312+ continue ;
1313+ }
1314+
1315+ if ((ext_arg1 && !exts2 [* v ].argument ) || (!ext_arg1 && exts2 [* v ].argument ) ||
1316+ (ext_arg1 && exts2 [* v ].argument && strcmp (ext_arg1 , exts2 [* v ].argument ))) {
1317+ /* argument mismatch */
1318+ continue ;
1319+ }
1320+
1321+ /* match */
1322+ break ;
1323+ }
1324+
1325+ if (LY_ARRAY_COUNT (exts2 ) == * v ) {
1326+ return LY_ENOTFOUND ;
1327+ }
1328+ return LY_SUCCESS ;
1329+ }
1330+
12821331/**
12831332 * @brief Apply deviate delete.
12841333 *
@@ -1294,6 +1343,7 @@ lys_apply_deviate_delete(struct lysc_ctx *ctx, struct lysp_deviate_del *d, struc
12941343 struct lysp_restr * * musts ;
12951344 LY_ARRAY_COUNT_TYPE u , v ;
12961345 struct lysp_qname * * uniques , * * dflts ;
1346+ struct lysp_ext * ext_def ;
12971347
12981348#define DEV_DEL_ARRAY (DEV_ARRAY , ORIG_ARRAY , DEV_MEMBER , ORIG_MEMBER , FREE_FUNC , FREE_CTX , PROPERTY ) \
12991349 LY_ARRAY_FOR(d->DEV_ARRAY, u) { \
@@ -1396,6 +1446,30 @@ lys_apply_deviate_delete(struct lysc_ctx *ctx, struct lysp_deviate_del *d, struc
13961446 }
13971447 }
13981448
1449+ /* *ext-inst */
1450+ LY_ARRAY_FOR (d -> exts , u ) {
1451+ lysp_ext_find_definition (ctx -> ctx , ctx -> pmod , & d -> exts [u ], NULL , & ext_def );
1452+ assert (ext_def );
1453+
1454+ if (lys_apply_deviate_ext_inst_find (ctx -> ctx , ctx -> pmod , ext_def , d -> exts [u ].argument , target -> exts , & v )) {
1455+ LOGVAL (ctx -> ctx , NULL , LYVE_REFERENCE , "Invalid deviation deleting \"ext-inst\" property \"%s%s%s\" "
1456+ "which does not match any of the target's property values." , d -> exts [u ].name ,
1457+ d -> exts [u ].argument ? " " : "" , d -> exts [u ].argument ? d -> exts [u ].argument : "" );
1458+ ret = LY_EVALID ;
1459+ goto cleanup ;
1460+ }
1461+
1462+ LY_ARRAY_DECREMENT (target -> exts );
1463+ lysp_ext_instance_free (ctx -> ctx , & target -> exts [v ]);
1464+ if (v < LY_ARRAY_COUNT (target -> exts )) {
1465+ memmove (& target -> exts [v ], & target -> exts [v + 1 ], (LY_ARRAY_COUNT (target -> exts ) - v ) * sizeof * target -> exts );
1466+ }
1467+ }
1468+ if (!LY_ARRAY_COUNT (target -> exts )) {
1469+ LY_ARRAY_FREE (target -> exts );
1470+ target -> exts = NULL ;
1471+ }
1472+
13991473cleanup :
14001474 return ret ;
14011475}
@@ -1412,7 +1486,10 @@ static LY_ERR
14121486lys_apply_deviate_replace (struct lysc_ctx * ctx , struct lysp_deviate_rpl * d , struct lysp_node * target )
14131487{
14141488 LY_ERR ret = LY_SUCCESS ;
1489+ LY_ARRAY_COUNT_TYPE u , v ;
14151490 uint32_t * num ;
1491+ struct lysp_ext * ext_def ;
1492+ enum ly_stmt parent_stmt ;
14161493
14171494#define DEV_CHECK_PRESENCE (TYPE , MEMBER , DEVTYPE , PROPERTY , VALUE ) \
14181495 if (!((TYPE)target)->MEMBER) { \
@@ -1537,6 +1614,25 @@ lys_apply_deviate_replace(struct lysc_ctx *ctx, struct lysp_deviate_rpl *d, stru
15371614 * num = d -> max ;
15381615 }
15391616
1617+ /* *ext-inst */
1618+ LY_ARRAY_FOR (d -> exts , u ) {
1619+ lysp_ext_find_definition (ctx -> ctx , ctx -> pmod , & d -> exts [u ], NULL , & ext_def );
1620+ assert (ext_def );
1621+
1622+ if (lys_apply_deviate_ext_inst_find (ctx -> ctx , ctx -> pmod , ext_def , d -> exts [u ].argument , target -> exts , & v )) {
1623+ LOGVAL (ctx -> ctx , NULL , LYVE_REFERENCE , "Invalid deviation replacing \"ext-inst\" property \"%s%s%s\" "
1624+ "which is not present." , d -> exts [u ].name , d -> exts [u ].argument ? " " : "" ,
1625+ d -> exts [u ].argument ? d -> exts [u ].argument : "" );
1626+ ret = LY_EVALID ;
1627+ goto cleanup ;
1628+ }
1629+
1630+ parent_stmt = target -> exts [v ].parent_stmt ;
1631+ lysp_ext_instance_free (ctx -> ctx , & target -> exts [v ]);
1632+ memset (& target -> exts [v ], 0 , sizeof target -> exts [v ]);
1633+ LY_CHECK_GOTO (ret = lysp_ext_dup (ctx -> ctx , ctx -> pmod , target , parent_stmt , & d -> exts [u ], & target -> exts [v ]), cleanup );
1634+ }
1635+
15401636cleanup :
15411637 return ret ;
15421638}
@@ -1588,9 +1684,6 @@ lys_apply_deviation(struct lysc_ctx *ctx, struct lysp_deviation *dev, const stru
15881684 LY_CHECK_GOTO (ret , cleanup );
15891685 }
15901686
1591- /* deviation extension instances */
1592- DUP_EXTS (ctx -> ctx , dev_pmod , target , lyplg_ext_nodetype2stmt (target -> nodetype ), dev -> exts , target -> exts , lysp_ext_dup );
1593-
15941687cleanup :
15951688 ctx -> cur_mod = orig_mod ;
15961689 ctx -> pmod = orig_pmod ;
0 commit comments