1
0
Fork 0
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:
Steffen Vogel 2017-03-27 12:38:19 +02:00
parent 68aa917f78
commit f28dd96c30
5 changed files with 251 additions and 6 deletions

View file

@ -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)

View file

@ -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
View 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);
}

View file

@ -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
View 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;
}