diff options
author | Max <msuraev@sysmocom.de> | 2019-02-13 18:00:06 +0100 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2019-02-22 21:28:45 +0000 |
commit | 2e717c968d86b3b4d4671aea0019ba47e59bcc2c (patch) | |
tree | 37c9eb37f7964d804e33ff5b80c975bd7477e853 | |
parent | 52a8375025cb266a43f937198569e8947a930ead (diff) |
Add multipatch capability to osmo-config-merge
That's pretty straightforward and convenient extention: handle all
extra positional arguments as patch file names. This makes it similar to
'cp' and other coreutils basic tools. For example:
osmo-config-merge base.cfg patch1.cfg patch2.cfg patch3.cfg
will apply 3 patches to the base config file.
Change-Id: I212cbdc3bf6f251c1a3175737ac74242fb004c6d
-rw-r--r-- | utils/osmo-config-merge.c | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/utils/osmo-config-merge.c b/utils/osmo-config-merge.c index afaf86b5..477bb028 100644 --- a/utils/osmo-config-merge.c +++ b/utils/osmo-config-merge.c @@ -49,6 +49,7 @@ #include <osmocom/core/linuxlist.h> #include <osmocom/core/talloc.h> #include <osmocom/core/utils.h> +#include <osmocom/core/msgfile.h> struct node { struct node *parent; /* back-pointer */ @@ -57,6 +58,11 @@ struct node { char *line; }; +struct osmo_patch_entry { + struct llist_head list; + struct node *tree; +}; + /* allocate a new node */ static struct node *node_alloc(void *ctx) { @@ -225,49 +231,67 @@ static void dump_node(struct node *root, FILE *out, bool print_node_depth) static void exit_usage(int rc) { - fprintf(stderr, "Usage: osmo-config-merge <config-file> <config-patch> [--debug]\n"); + fprintf(stderr, "Usage: osmo-config-merge <config-file> <config-patch>...<config-patch> [--debug]\n"); exit(rc); } int main(int argc, char **argv) { - const char *base_fname, *patch_fname; - struct node *base_tree, *patch_tree; + struct node *base_tree; + struct osmo_config_list *trees; + struct osmo_patch_entry *entry; bool debug_enabled = false; + unsigned i; void *ctx; if (argc < 3) exit_usage(1); - base_fname = argv[1]; - patch_fname = argv[2]; - - if (argc > 3) { - if (!strcmp(argv[3], "--debug")) - debug_enabled = true; - else - exit_usage(1); - } - ctx = talloc_named_const(NULL, 0, "root"); - base_tree = file_read(ctx, base_fname); - patch_tree = file_read(ctx, patch_fname); - - if (!base_tree || ! patch_tree) { + base_tree = file_read(ctx, argv[1]); + trees = talloc_zero(ctx, struct osmo_config_list); + if (!base_tree || !trees) { talloc_free(ctx); return 2; } + INIT_LLIST_HEAD(&trees->entry); + for (i = 2; i < argc; i++) { + if (!strcmp(argv[i], "--debug")) + debug_enabled = true; + else { + entry = talloc_zero(trees, struct osmo_patch_entry); + if (!entry) { + talloc_free(ctx); + return 3; + } + + entry->tree = file_read(ctx, argv[i]); + if (!entry->tree) { + talloc_free(ctx); + return 4; + } + llist_add_tail(&entry->list, &trees->entry); + } + } + + if (llist_empty(&trees->entry)) + exit_usage(1); + if (debug_enabled) { fprintf(stderr, "====== dumping tree (base)\n"); dump_node(base_tree, stderr, true); - fprintf(stderr, "====== dumping tree (patch)\n"); - dump_node(patch_tree, stderr, true); } - append_patch(base_tree, patch_tree); + llist_for_each_entry(entry, &trees->entry, list) { + append_patch(base_tree, entry->tree); + if (debug_enabled) { + fprintf(stderr, "====== dumping tree (patch)\n"); + dump_node(entry->tree, stderr, true); + } + } if (debug_enabled) fprintf(stderr, "====== dumping tree (patched)\n"); @@ -275,7 +299,7 @@ int main(int argc, char **argv) fflush(stdout); /* make AddressSanitizer / LeakSanitizer happy by recursively freeing the trees */ - talloc_free(patch_tree); + talloc_free(trees); talloc_free(base_tree); talloc_free(ctx); |