context CHANGE support multiple search paths
allow to set multiple directories to a context to be searched when
resolving imports and includes
diff --git a/src/context.c b/src/context.c
index e52e8a4..b68988a 100644
--- a/src/context.c
+++ b/src/context.c
@@ -102,7 +102,9 @@
ly_ctx_destroy(ctx, NULL);
return NULL;
}
- ctx->models.search_path = get_current_dir_name();
+ ctx->models.search_paths = malloc(2 * sizeof *ctx->models.search_paths);
+ ctx->models.search_paths[0] = get_current_dir_name();
+ ctx->models.search_paths[1] = NULL;
if (chdir(cwd)) {
LOGWRN("Unable to return back to working directory \"%s\" (%s)",
cwd, strerror(errno));
@@ -242,6 +244,8 @@
ly_ctx_set_searchdir(struct ly_ctx *ctx, const char *search_dir)
{
char *cwd;
+ int index = 0;
+ void *r;
if (!ctx) {
return;
@@ -255,17 +259,27 @@
free(cwd);
return;
}
- free(ctx->models.search_path);
- ctx->models.search_path = get_current_dir_name();
+
+ if (!ctx->models.search_paths) {
+ ctx->models.search_paths = malloc(2 * sizeof *ctx->models.search_paths);
+ index = 0;
+ } else {
+ for (index = 0; ctx->models.search_paths[index]; index++);
+ r = realloc(ctx->models.search_paths, (index + 2) * sizeof *ctx->models.search_paths);
+ if (!r) {
+ LOGMEM;
+ return;
+ }
+ ctx->models.search_paths = r;
+ }
+ ctx->models.search_paths[index] = get_current_dir_name();
+ ctx->models.search_paths[index + 1] = NULL;
if (chdir(cwd)) {
LOGWRN("Unable to return back to working directory \"%s\" (%s)",
cwd, strerror(errno));
}
free(cwd);
- } else {
- free(ctx->models.search_path);
- ctx->models.search_path = NULL;
}
}
@@ -276,12 +290,30 @@
ly_errno = LY_EINVAL;
return NULL;
}
- return ctx->models.search_path;
+ return ctx->models.search_paths ? ctx->models.search_paths[0] : NULL;
+}
+
+API void
+ly_ctx_unset_searchdirs(struct ly_ctx *ctx)
+{
+ int i;
+
+ if (!ctx->models.search_paths) {
+ return;
+ }
+
+ for (i = 0; ctx->models.search_paths[i]; i++) {
+ free(ctx->models.search_paths[i]);
+ }
+ free(ctx->models.search_paths);
+ ctx->models.search_paths = NULL;
}
API void
ly_ctx_destroy(struct ly_ctx *ctx, void (*private_destructor)(const struct lys_node *node, void *priv))
{
+ int i;
+
if (!ctx) {
return;
}
@@ -293,7 +325,12 @@
/* remove the module */
lys_free(ctx->models.list[ctx->models.used - 1], private_destructor, 0);
}
- free(ctx->models.search_path);
+ if (ctx->models.search_paths) {
+ for(i = 0; ctx->models.search_paths[i]; i++) {
+ free(ctx->models.search_paths[i]);
+ }
+ free(ctx->models.search_paths);
+ }
free(ctx->models.list);
/* dictionary */