Some checks failed
CMake / ubuntu-latest - shared=OFF, pthread=OFF, posix=OFF (push) Failing after 13s
CMake / ubuntu-latest - shared=ON, pthread=OFF, posix=OFF (push) Failing after 16s
CMake / ubuntu-latest - shared=OFF, pthread=OFF, posix=ON (push) Failing after 12s
CMake / ubuntu-latest - shared=ON, pthread=OFF, posix=ON (push) Failing after 14s
CMake / ubuntu-latest - shared=OFF, pthread=ON, posix=ON (push) Failing after 16s
CMake / ubuntu-latest - shared=ON, pthread=ON, posix=ON (push) Failing after 13s
Signed-off-by: Slendi <slendi@socopon.com>
181 lines
3.8 KiB
C
181 lines
3.8 KiB
C
#include <dcfg.h>
|
|
|
|
#include <alloca.h>
|
|
#include <getopt.h>
|
|
#include <inttypes.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
|
|
void walk_value(dcfg_Value *value, bool evaluate, int indent, bool first);
|
|
#define WALK(v, e, i) walk_value((v), (e), (i), true)
|
|
|
|
static void print_indent(int indent)
|
|
{
|
|
for (int i = 0; i < indent; ++i)
|
|
putchar('\t');
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
bool evaluate = false;
|
|
int opt;
|
|
while ((opt = getopt(argc, argv, "e")) != -1) {
|
|
switch (opt) {
|
|
case 'e':
|
|
evaluate = true;
|
|
break;
|
|
default:
|
|
fprintf(stderr, "Usage: %s [-e] <dcfg file>\n", argv[0]);
|
|
return 1;
|
|
}
|
|
}
|
|
if (optind >= argc) {
|
|
fprintf(stderr, "Usage: %s [-e] <dcfg file>\n", argv[0]);
|
|
return 1;
|
|
}
|
|
|
|
char const *path = argv[optind];
|
|
|
|
dcfg_InstanceCreateInfo ci = { 0 };
|
|
dcfg_Instance *instance = dcfg_make_instance(&ci);
|
|
if (!instance) {
|
|
printf("Failed to create DCFG instance. Error: %s\n",
|
|
dcfg_last_error(instance));
|
|
return 1;
|
|
}
|
|
|
|
dcfg_Value *value = dcfg_parse(instance, dcfg_SV(path));
|
|
if (!value) {
|
|
printf("Failed to parse DCFG file. Error: %s\n",
|
|
dcfg_last_error(instance));
|
|
dcfg_destroy_instance(instance);
|
|
return 1;
|
|
}
|
|
|
|
WALK(value, evaluate, 0);
|
|
|
|
dcfg_destroy(value);
|
|
dcfg_destroy_instance(instance);
|
|
}
|
|
|
|
void walk_value(dcfg_Value *value, bool evaluate, int indent, bool first)
|
|
{
|
|
if (first)
|
|
print_indent(indent);
|
|
|
|
dcfg_ValueType type = dcfg_Value_type_ex(value, evaluate);
|
|
|
|
switch (type) {
|
|
case dcfg_ValueType_Nil:
|
|
printf("null");
|
|
break;
|
|
|
|
case dcfg_ValueType_Boolean: {
|
|
bool b;
|
|
dcfg_Value_get_boolean(value, &b);
|
|
printf("%s", b ? "true" : "false");
|
|
} break;
|
|
|
|
case dcfg_ValueType_Integer: {
|
|
int64_t v;
|
|
dcfg_Value_get_integer(value, &v);
|
|
printf("%" PRId64, v);
|
|
} break;
|
|
|
|
case dcfg_ValueType_Real: {
|
|
double v;
|
|
dcfg_Value_get_real(value, &v);
|
|
printf("%g", v);
|
|
} break;
|
|
|
|
case dcfg_ValueType_String: {
|
|
dcfg_StringView sv;
|
|
dcfg_Value_get_string(value, &sv);
|
|
printf("\"%.*s\"", (int)sv.size, sv.data);
|
|
} break;
|
|
|
|
case dcfg_ValueType_Path: {
|
|
dcfg_StringView sv;
|
|
dcfg_Value_get_path(value, &sv);
|
|
printf("<path \"%.*s\">", (int)sv.size, sv.data);
|
|
} break;
|
|
|
|
case dcfg_ValueType_Object: {
|
|
size_t n = 0;
|
|
dcfg_Value_get_object_keys(value, 0, &n, NULL);
|
|
dcfg_StringView *keys
|
|
= n ? (dcfg_StringView *)alloca(n * sizeof(*keys)) : NULL;
|
|
dcfg_Value_get_object_keys(value, n, &n, keys);
|
|
|
|
printf("{\n");
|
|
for (size_t i = 0; i < n; ++i) {
|
|
dcfg_Value *child;
|
|
if (!dcfg_Value_get_object_field_ex(
|
|
value, keys[i], &child, evaluate))
|
|
continue;
|
|
|
|
print_indent(indent + 1);
|
|
printf("\"%.*s\": ", (int)keys[i].size, keys[i].data);
|
|
walk_value(child, evaluate, indent + 1, false);
|
|
if (i + 1 < n)
|
|
printf(",");
|
|
printf("\n");
|
|
}
|
|
print_indent(indent);
|
|
printf("}");
|
|
} break;
|
|
|
|
case dcfg_ValueType_Array: {
|
|
size_t sz = 0;
|
|
dcfg_Value_get_array_size(value, &sz);
|
|
|
|
printf("[\n");
|
|
for (size_t i = 0; i < sz; ++i) {
|
|
dcfg_Value *item;
|
|
if (!dcfg_Value_get_array_item_ex(value, i, &item, evaluate))
|
|
continue;
|
|
|
|
print_indent(indent + 1);
|
|
walk_value(item, evaluate, indent + 1, false);
|
|
if (i + 1 < sz)
|
|
printf(",");
|
|
printf("\n");
|
|
}
|
|
print_indent(indent);
|
|
printf("]");
|
|
} break;
|
|
|
|
case dcfg_ValueType_Function: {
|
|
dcfg_Value *body = NULL;
|
|
|
|
if (dcfg_Value_get_function_body_ex(value, &body, evaluate) && body) {
|
|
printf("<fn>\t");
|
|
walk_value(body, evaluate, indent + 1, false);
|
|
} else {
|
|
printf("<builtin-fn>");
|
|
}
|
|
} break;
|
|
|
|
case dcfg_ValueType_FunctionCall:
|
|
if (evaluate) {
|
|
dcfg_Value *res;
|
|
if (dcfg_Value_evaluate(value, &res))
|
|
walk_value(res, evaluate, indent, first);
|
|
else
|
|
printf("<error-evaluating-call>");
|
|
} else {
|
|
printf("<function-call>");
|
|
}
|
|
break;
|
|
|
|
default:
|
|
printf("<unknown>");
|
|
break;
|
|
}
|
|
|
|
if (indent == 0) {
|
|
putchar('\n');
|
|
}
|
|
}
|