@@ -1824,58 +1824,112 @@ lys_compile(struct lys_module *mod, struct lys_depset_unres *unres)
18241824 return ret ;
18251825}
18261826
1827- LY_ERR
1828- lys_compile_extensions (struct lys_module * mod )
1827+ /**
1828+ * @brief Compile all extension definitions in a parsed module into the main module.
1829+ *
1830+ * @param[in] mod Module to use.
1831+ * @param[in] pmod Parsed (sub)module to use.
1832+ * @return LY_ERR value.
1833+ */
1834+ static LY_ERR
1835+ lys_compile_extensions_pmod (struct lys_module * mod , struct lysp_module * pmod )
18291836{
18301837 LY_ERR rc = LY_SUCCESS ;
18311838 struct lysc_ctx ctx = {0 };
18321839 LY_ARRAY_COUNT_TYPE u ;
18331840 struct lysp_ext * ep ;
18341841 struct lysc_ext * ec ;
18351842
1836- if (!mod -> parsed -> extensions ) {
1837- return LY_SUCCESS ;
1838- }
1839-
1840- LYSC_CTX_INIT_PMOD (ctx , mod -> parsed , NULL );
1843+ LYSC_CTX_INIT_PMOD (ctx , pmod , NULL );
18411844
1842- /* allocate the array */
1843- LY_ARRAY_CREATE_RET ( mod -> ctx , mod -> extensions , LY_ARRAY_COUNT ( mod -> parsed -> extensions ), LY_EMEM ) ;
1845+ LY_ARRAY_FOR ( pmod -> extensions , u ) {
1846+ ep = & pmod -> extensions [ u ] ;
18441847
1845- /* compile all extension definitions */
1846- LY_ARRAY_FOR (mod -> parsed -> extensions , u ) {
1847- ep = & mod -> parsed -> extensions [u ];
1848- ec = & mod -> extensions [u ];
1848+ /* allocate a new extension */
1849+ LY_ARRAY_NEW_GOTO (mod -> ctx , mod -> extensions , ec , rc , cleanup );
18491850
18501851 /* compile the extension definition */
18511852 DUP_STRING_GOTO (ctx .ctx , ep -> name , ec -> name , rc , cleanup );
18521853 DUP_STRING_GOTO (ctx .ctx , ep -> argname , ec -> argname , rc , cleanup );
18531854 ec -> module = mod ;
18541855 ec -> plugin_ref = ep -> plugin_ref ;
1855-
1856- LY_ARRAY_INCREMENT (mod -> extensions );
18571856 }
18581857
1859- /* compile all nested extension instances, which can reference the compiled definitions */
1860- LY_ARRAY_FOR (mod -> parsed -> extensions , u ) {
1861- ep = & mod -> parsed -> extensions [u ];
1862- ec = & mod -> extensions [u ];
1858+ cleanup :
1859+ return rc ;
1860+ }
1861+
1862+ /**
1863+ * @brief Compile all ext instances of extension definitions in a parsed module.
1864+ *
1865+ * @param[in] mod Module to use.
1866+ * @param[in] mod_ext_idx Index in ext of @p mod to start at.
1867+ * @param[in] pmod Parsed (sub)module to use.
1868+ * @return LY_ERR value.
1869+ */
1870+ static LY_ERR
1871+ lys_compile_extensions_ext_pmod (struct lys_module * mod , LY_ARRAY_COUNT_TYPE mod_ext_idx , struct lysp_module * pmod )
1872+ {
1873+ LY_ERR rc = LY_SUCCESS ;
1874+ struct lysc_ctx ctx = {0 };
1875+ LY_ARRAY_COUNT_TYPE u ;
1876+ struct lysp_ext * ep ;
1877+ struct lysc_ext * ec ;
1878+
1879+ LYSC_CTX_INIT_PMOD (ctx , pmod , NULL );
1880+
1881+ LY_ARRAY_FOR (pmod -> extensions , u ) {
1882+ ep = & pmod -> extensions [u ];
1883+ ec = & mod -> extensions [mod_ext_idx ];
18631884
18641885 lysc_update_path (& ctx , NULL , "{extension}" );
18651886 lysc_update_path (& ctx , NULL , ep -> name );
18661887
18671888 /* compile nested extensions */
1868- COMPILE_EXTS_GOTO (& ctx , ep -> exts , ec -> exts , ec , rc , cleanup );
1869-
1889+ COMPILE_EXTS_GOTO (& ctx , ep -> exts , ec -> exts , ec , rc , next_line );
1890+ next_line :
18701891 lysc_update_path (& ctx , NULL , NULL );
18711892 lysc_update_path (& ctx , NULL , NULL );
1893+
1894+ LY_CHECK_GOTO (rc , cleanup );
1895+
1896+ ++ mod_ext_idx ;
18721897 }
18731898
18741899cleanup :
1875- if (rc ) {
1876- lysc_update_path (& ctx , NULL , NULL );
1877- lysc_update_path (& ctx , NULL , NULL );
1900+ return rc ;
1901+ }
1902+
1903+ LY_ERR
1904+ lys_compile_extensions (struct lys_module * mod )
1905+ {
1906+ LY_ERR rc = LY_SUCCESS ;
1907+ LY_ARRAY_COUNT_TYPE u , v ;
1908+ struct lysp_include * inc ;
1909+
1910+ /* compile all module and submodule extension definitions */
1911+ LY_CHECK_GOTO (rc = lys_compile_extensions_pmod (mod , mod -> parsed ), cleanup );
1912+ LY_ARRAY_FOR (mod -> parsed -> includes , u ) {
1913+ LY_CHECK_GOTO (rc = lys_compile_extensions_pmod (mod , (struct lysp_module * )mod -> parsed -> includes [u ].submodule ),
1914+ cleanup );
18781915 }
1916+
1917+ /* compile all nested extension instances, which can reference the compiled definitions,
1918+ * there is one extensions array in main mod for the parsed module and all submodules so we need a special index */
1919+ v = 0 ;
1920+ LY_CHECK_GOTO (rc = lys_compile_extensions_ext_pmod (mod , v , mod -> parsed ), cleanup );
1921+
1922+ v += LY_ARRAY_COUNT (mod -> parsed -> extensions );
1923+ LY_ARRAY_FOR (mod -> parsed -> includes , u ) {
1924+ inc = & mod -> parsed -> includes [u ];
1925+ LY_CHECK_GOTO (rc = lys_compile_extensions_ext_pmod (mod , v , (struct lysp_module * )inc -> submodule ), cleanup );
1926+
1927+ v += LY_ARRAY_COUNT (inc -> submodule -> extensions );
1928+ }
1929+
1930+ assert (v == LY_ARRAY_COUNT (mod -> extensions ));
1931+
1932+ cleanup :
18791933 return rc ;
18801934}
18811935
0 commit comments