mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
added json_to_config in order to support JSON as new config file format
This commit is contained in:
parent
68aa917f78
commit
f28dd96c30
5 changed files with 251 additions and 6 deletions
86
lib/utils.c
86
lib/utils.c
|
@ -241,6 +241,22 @@ char *cpulist_create(char *str, size_t len, cpu_set_t *set)
|
|||
}
|
||||
|
||||
#ifdef WITH_JANSSON
|
||||
static int json_to_config_type(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case JSON_OBJECT: return CONFIG_TYPE_GROUP;
|
||||
case JSON_ARRAY: return CONFIG_TYPE_LIST;
|
||||
case JSON_STRING: return CONFIG_TYPE_STRING;
|
||||
case JSON_INTEGER: return CONFIG_TYPE_INT64;
|
||||
case JSON_REAL: return CONFIG_TYPE_FLOAT;
|
||||
case JSON_TRUE:
|
||||
case JSON_FALSE:
|
||||
case JSON_NULL: return CONFIG_TYPE_BOOL;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
json_t * config_to_json(config_setting_t *cfg)
|
||||
{
|
||||
switch (config_setting_type(cfg)) {
|
||||
|
@ -263,19 +279,83 @@ json_t * config_to_json(config_setting_t *cfg)
|
|||
case CONFIG_TYPE_GROUP: {
|
||||
json_t *json = json_object();
|
||||
|
||||
for (int i = 0; i < config_setting_length(cfg); i++)
|
||||
for (int i = 0; i < config_setting_length(cfg); i++) {
|
||||
json_object_set_new(json,
|
||||
config_setting_name(config_setting_get_elem(cfg, i)),
|
||||
config_to_json(config_setting_get_elem(cfg, i))
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
return json_object();
|
||||
}
|
||||
}
|
||||
|
||||
int json_to_config(json_t *json, config_setting_t *parent)
|
||||
{
|
||||
config_setting_t *cfg;
|
||||
int ret, type;
|
||||
|
||||
if (config_setting_is_root(parent)) {
|
||||
if (!json_is_object(json))
|
||||
return -1; /* The root must be an object! */
|
||||
}
|
||||
|
||||
switch (json_typeof(json)) {
|
||||
case JSON_OBJECT: {
|
||||
const char *key;
|
||||
json_t *json_value;
|
||||
|
||||
json_object_foreach(json, key, json_value) {
|
||||
type = json_to_config_type(json_typeof(json_value));
|
||||
|
||||
cfg = config_setting_add(parent, key, type);
|
||||
ret = json_to_config(json_value, cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case JSON_ARRAY: {
|
||||
size_t i;
|
||||
json_t *json_value;
|
||||
|
||||
json_array_foreach(json, i, json_value) {
|
||||
type = json_to_config_type(json_typeof(json_value));
|
||||
|
||||
cfg = config_setting_add(parent, NULL, type);
|
||||
ret = json_to_config(json_value, cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case JSON_STRING:
|
||||
config_setting_set_string(parent, json_string_value(json));
|
||||
break;
|
||||
|
||||
case JSON_INTEGER:
|
||||
config_setting_set_int64(parent, json_integer_value(json));
|
||||
break;
|
||||
|
||||
case JSON_REAL:
|
||||
config_setting_set_float(parent, json_real_value(json));
|
||||
break;
|
||||
|
||||
case JSON_TRUE:
|
||||
case JSON_FALSE:
|
||||
case JSON_NULL:
|
||||
config_setting_set_bool(parent, json_is_true(json));
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void * alloc(size_t bytes)
|
||||
|
|
|
@ -3,7 +3,7 @@ TEST_OBJS = $(patsubst %.c,$(BUILDDIR)/%.o,$(TEST_SRCS))
|
|||
|
||||
TEST_CFLAGS = $(CFLAGS)
|
||||
TEST_LDFLAGS = $(LDFLAGS) -Wl,-rpath,'$$ORIGIN'
|
||||
TEST_LDLIBS = $(LDLIBS) -lcriterion -lvillas -pthread
|
||||
TEST_LDLIBS = $(LDLIBS) -lcriterion -lvillas -pthread -ljansson
|
||||
|
||||
unit-tests: $(BUILDDIR)/unit-tests
|
||||
|
||||
|
|
99
tests/unit/config_json.c
Normal file
99
tests/unit/config_json.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/** Unit tests libconfig to jansson converters.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
||||
#include <criterion/criterion.h>
|
||||
|
||||
#include <jansson.h>
|
||||
#include <libconfig.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
const char *cfg_example = "test : \n"
|
||||
"{\n"
|
||||
" hallo = 1L;\n"
|
||||
"};\n"
|
||||
"liste = ( 1.1, 2L, 3L, 4L, \n"
|
||||
" {\n"
|
||||
" objekt : \n"
|
||||
" {\n"
|
||||
" key = \"value\";\n"
|
||||
" };\n"
|
||||
" } );\n";
|
||||
|
||||
const char *json_example = "{\n"
|
||||
" \"test\": {\n"
|
||||
" \"hallo\": 1\n"
|
||||
" },\n"
|
||||
" \"liste\": [\n"
|
||||
" 1.1000000000000001,\n"
|
||||
" 2,\n"
|
||||
" 3,\n"
|
||||
" 4,\n"
|
||||
" {\n"
|
||||
" \"objekt\": {\n"
|
||||
" \"key\": \"value\"\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" ]\n"
|
||||
"}";
|
||||
|
||||
Test(utils, config_to_json)
|
||||
{
|
||||
int ret;
|
||||
config_t cfg;
|
||||
config_setting_t *cfg_root;
|
||||
json_t *json;
|
||||
|
||||
config_init(&cfg);
|
||||
|
||||
ret = config_read_string(&cfg, cfg_example);
|
||||
cr_assert_eq(ret, CONFIG_TRUE);
|
||||
|
||||
cfg_root = config_root_setting(&cfg);
|
||||
|
||||
json = config_to_json(cfg_root);
|
||||
cr_assert_not_null(json);
|
||||
|
||||
char *str = json_dumps(json, JSON_INDENT(2));
|
||||
|
||||
//printf("%s\n", str);
|
||||
|
||||
json_decref(json);
|
||||
|
||||
cr_assert_str_eq(str, json_example);
|
||||
|
||||
config_destroy(&cfg);
|
||||
}
|
||||
|
||||
Test(utils, json_to_config)
|
||||
{
|
||||
config_t cfg;
|
||||
config_setting_t *cfg_root;
|
||||
json_t *json;
|
||||
|
||||
/* For config_write() */
|
||||
FILE *f;
|
||||
char str[1024];
|
||||
|
||||
config_init(&cfg);
|
||||
|
||||
cfg_root = config_root_setting(&cfg);
|
||||
|
||||
json = json_loads(json_example, 0, NULL);
|
||||
cr_assert_not_null(json);
|
||||
|
||||
json_to_config(json, cfg_root);
|
||||
|
||||
//config_write(&cfg, stdout);
|
||||
|
||||
f = fmemopen(str, sizeof(str), "w+");
|
||||
config_write(&cfg, f);
|
||||
fclose(f);
|
||||
|
||||
cr_assert_str_eq(str, cfg_example);
|
||||
|
||||
json_decref(json);
|
||||
}
|
|
@ -1,8 +1,23 @@
|
|||
tools:
|
||||
TOOLS = $(BUILDDIR)/conf2json
|
||||
|
||||
TOOLS_CFLAGS = $(CFLAGS)
|
||||
TOOLS_LDLIBS = -lconfig -ljansson -lvillas
|
||||
|
||||
# Compile executable objects
|
||||
$(BUILDDIR)/tools/%.o: tools/%.c | $$(dir $$@)
|
||||
$(CC) $(TOOLS_CFLAGS) -c $< -o $@
|
||||
|
||||
# Link target executables
|
||||
$(TOOLS): $(BUILDDIR)/%: $(BUILDDIR)/tools/%.o | $(LIBS)
|
||||
$(CC) $(TOOLS_LDFLAGS) $^ $(TOOLS_LDLIBS) -o $@
|
||||
|
||||
tools: $(TOOLS)
|
||||
|
||||
clean-tools:
|
||||
rm -rf $(BUILDDIR)/tools $(TOOLS)
|
||||
|
||||
install-tools:
|
||||
install-tools: $(TOOLS)
|
||||
install -m 0755 tools/villas.sh $(PREFIX)/bin/villas
|
||||
install -m 0755 -D -t $(DESTDIR)$(PREFIX)/bin $(TOOLS)
|
||||
|
||||
.PHONY: tools clean-tools install-tools
|
51
tools/conf2json.c
Normal file
51
tools/conf2json.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/** Convert old style config to new JSON format.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
||||
#include <jansson.h>
|
||||
#include <libconfig.h>
|
||||
|
||||
#include <villas/utils.h>
|
||||
|
||||
void usage()
|
||||
{
|
||||
printf("Usage: conf2json < input.conf > output.json\n\n");
|
||||
|
||||
print_copyright();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
config_t cfg;
|
||||
config_setting_t *cfg_root;
|
||||
json_t *json;
|
||||
|
||||
if (argc != 1) {
|
||||
usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
config_init(&cfg);
|
||||
|
||||
ret = config_read(&cfg, stdin);
|
||||
if (ret != CONFIG_TRUE)
|
||||
return ret;
|
||||
|
||||
cfg_root = config_root_setting(&cfg);
|
||||
|
||||
json = config_to_json(cfg_root);
|
||||
if (!json)
|
||||
return -1;
|
||||
|
||||
ret = json_dumpf(json, stdout, JSON_INDENT(2)); fflush(stdout);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
json_decref(json);
|
||||
config_destroy(&cfg);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Reference in a new issue