mirror of https://gerrit.osmocom.org/libosmocore
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
This commit is contained in:
parent
52a8375025
commit
2e717c968d
|
@ -49,6 +49,7 @@
|
||||||
#include <osmocom/core/linuxlist.h>
|
#include <osmocom/core/linuxlist.h>
|
||||||
#include <osmocom/core/talloc.h>
|
#include <osmocom/core/talloc.h>
|
||||||
#include <osmocom/core/utils.h>
|
#include <osmocom/core/utils.h>
|
||||||
|
#include <osmocom/core/msgfile.h>
|
||||||
|
|
||||||
struct node {
|
struct node {
|
||||||
struct node *parent; /* back-pointer */
|
struct node *parent; /* back-pointer */
|
||||||
|
@ -57,6 +58,11 @@ struct node {
|
||||||
char *line;
|
char *line;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct osmo_patch_entry {
|
||||||
|
struct llist_head list;
|
||||||
|
struct node *tree;
|
||||||
|
};
|
||||||
|
|
||||||
/* allocate a new node */
|
/* allocate a new node */
|
||||||
static struct node *node_alloc(void *ctx)
|
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)
|
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);
|
exit(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
const char *base_fname, *patch_fname;
|
struct node *base_tree;
|
||||||
struct node *base_tree, *patch_tree;
|
struct osmo_config_list *trees;
|
||||||
|
struct osmo_patch_entry *entry;
|
||||||
bool debug_enabled = false;
|
bool debug_enabled = false;
|
||||||
|
unsigned i;
|
||||||
void *ctx;
|
void *ctx;
|
||||||
|
|
||||||
if (argc < 3)
|
if (argc < 3)
|
||||||
exit_usage(1);
|
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");
|
ctx = talloc_named_const(NULL, 0, "root");
|
||||||
|
|
||||||
base_tree = file_read(ctx, base_fname);
|
base_tree = file_read(ctx, argv[1]);
|
||||||
patch_tree = file_read(ctx, patch_fname);
|
trees = talloc_zero(ctx, struct osmo_config_list);
|
||||||
|
if (!base_tree || !trees) {
|
||||||
if (!base_tree || ! patch_tree) {
|
|
||||||
talloc_free(ctx);
|
talloc_free(ctx);
|
||||||
return 2;
|
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) {
|
if (debug_enabled) {
|
||||||
fprintf(stderr, "====== dumping tree (base)\n");
|
fprintf(stderr, "====== dumping tree (base)\n");
|
||||||
dump_node(base_tree, stderr, true);
|
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)
|
if (debug_enabled)
|
||||||
fprintf(stderr, "====== dumping tree (patched)\n");
|
fprintf(stderr, "====== dumping tree (patched)\n");
|
||||||
|
@ -275,7 +299,7 @@ int main(int argc, char **argv)
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
/* make AddressSanitizer / LeakSanitizer happy by recursively freeing the trees */
|
/* make AddressSanitizer / LeakSanitizer happy by recursively freeing the trees */
|
||||||
talloc_free(patch_tree);
|
talloc_free(trees);
|
||||||
talloc_free(base_tree);
|
talloc_free(base_tree);
|
||||||
talloc_free(ctx);
|
talloc_free(ctx);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue