From: Felix Fietkau Date: Sat, 2 Feb 2008 21:47:00 +0000 (+0100) Subject: add import merging functionality, fix error handling in uci_import X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fuci.git;a=commitdiff_plain;h=9387bced4effec755ccd2a5cdb52c00d0c45990b add import merging functionality, fix error handling in uci_import --- diff --git a/file.c b/file.c index fe52876..afa57bf 100644 --- a/file.c +++ b/file.c @@ -372,6 +372,7 @@ static void uci_fixup_section(struct uci_context *ctx, struct uci_section *s) */ static void uci_parse_config(struct uci_context *ctx, char **str) { + struct uci_parse_context *pctx = ctx->pctx; struct uci_section *s; char *name = NULL; char *type = NULL; @@ -390,7 +391,11 @@ static void uci_parse_config(struct uci_context *ctx, char **str) type = next_arg(ctx, str, true, true); name = next_arg(ctx, str, false, true); assert_eol(ctx, str); - ctx->pctx->section = uci_alloc_section(ctx->pctx->package, type, name); + + if (pctx->merge) + UCI_INTERNAL(uci_set, ctx, pctx->package, name, NULL, type); + else + pctx->section = uci_alloc_section(pctx->package, type, name); } /* @@ -398,10 +403,11 @@ static void uci_parse_config(struct uci_context *ctx, char **str) */ static void uci_parse_option(struct uci_context *ctx, char **str) { + struct uci_parse_context *pctx = ctx->pctx; char *name = NULL; char *value = NULL; - if (!ctx->pctx->section) + if (!pctx->section) uci_parse_error(ctx, *str, "option command found before the first section"); /* command string null-terminated by strtok */ @@ -410,7 +416,11 @@ static void uci_parse_option(struct uci_context *ctx, char **str) name = next_arg(ctx, str, true, true); value = next_arg(ctx, str, true, false); assert_eol(ctx, str); - uci_alloc_option(ctx->pctx->section, name, value); + + if (pctx->merge) + UCI_INTERNAL(uci_set, ctx, pctx->package, pctx->section->e.name, name, value); + else + uci_alloc_option(pctx->section, name, value); } @@ -537,6 +547,7 @@ int uci_export(struct uci_context *ctx, FILE *stream, struct uci_package *packag int uci_import(struct uci_context *ctx, FILE *stream, const char *name, struct uci_package **package, bool single) { struct uci_parse_context *pctx; + UCI_HANDLE_ERR(ctx); /* make sure no memory from previous parse attempts is leaked */ uci_file_cleanup(ctx); @@ -544,6 +555,10 @@ int uci_import(struct uci_context *ctx, FILE *stream, const char *name, struct u pctx = (struct uci_parse_context *) uci_malloc(ctx, sizeof(struct uci_parse_context)); ctx->pctx = pctx; pctx->file = stream; + if (*package && single) { + pctx->package = *package; + pctx->merge = true; + } /* * If 'name' was supplied, assume that the supplied stream does not contain diff --git a/list.c b/list.c index ae7fce8..4ff4f7b 100644 --- a/list.c +++ b/list.c @@ -455,6 +455,8 @@ int uci_set(struct uci_context *ctx, struct uci_package *p, char *section, char if (!e) goto notfound; o = uci_to_option(e); + } else if (internal && ctx->pctx) { + ctx->pctx->section = s; } /* diff --git a/uci.h b/uci.h index 93f8bce..6b5de9a 100644 --- a/uci.h +++ b/uci.h @@ -105,6 +105,7 @@ extern void uci_perror(struct uci_context *ctx, const char *str); * @single: ignore the 'package' keyword and parse everything into a single package * * the name parameter is for config files that don't explicitly use the 'package <...>' keyword + * if 'package' points to a non-null struct pointer, enable history tracking and merge */ extern int uci_import(struct uci_context *ctx, FILE *stream, const char *name, struct uci_package **package, bool single); @@ -276,6 +277,7 @@ struct uci_parse_context /* private: */ struct uci_package *package; struct uci_section *section; + bool merge; FILE *file; const char *name; char *buf;