Request YANG schemas via sysrepo

The std::function that is fed into YangSchema::registerModuleCallback
does not have the same signature that libyang requires, because we would
have to include libyang in the sysrepo_access header file. We don't want this
class to know about libyang, so instead, we use an intermediate function,
that has string arguments and a string return type. In YangSchema, this
function is wrapped with another function, that has the required signature.

Change-Id: Ibd2dcb89344cf1454ba0b3970cac0c8e88ffa20d
diff --git a/src/yang_schema.cpp b/src/yang_schema.cpp
index 68a4cf2..946162b 100644
--- a/src/yang_schema.cpp
+++ b/src/yang_schema.cpp
@@ -51,7 +51,7 @@
 }
 
 YangSchema::YangSchema()
-    : m_context(std::make_shared<libyang::Context>())
+    : m_context(std::make_shared<libyang::Context>(nullptr, LY_CTX_DISABLE_SEARCHDIRS | LY_CTX_DISABLE_SEARCHDIR_CWD))
 {
 }
 
@@ -223,3 +223,25 @@
     }
     return res;
 }
+
+void YangSchema::loadModule(const std::string& moduleName)
+{
+    m_context->load_module(moduleName.c_str());
+}
+
+void YangSchema::registerModuleCallback(const std::function<std::string(const char*, const char*, const char*)>& clb)
+{
+    auto lambda = [clb](const char* mod_name, const char* mod_revision, const char* submod_name, const char* submod_revision) {
+        (void)submod_revision;
+        auto moduleSource = clb(mod_name, mod_revision, submod_name);
+        if (moduleSource.empty()) {
+            return libyang::Context::mod_missing_cb_return{LYS_IN_YANG, nullptr};
+        }
+        return libyang::Context::mod_missing_cb_return{LYS_IN_YANG, strdup(moduleSource.c_str())};
+    };
+
+    auto deleter = [](void* data) {
+        free(data);
+    };
+    m_context->add_missing_module_callback(lambda, deleter);
+}