#include #include #include #include #include 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[]) { if (argc < 2) { printf("Usage: %s \n", argv[0]); return 1; } 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(argv[1])); if (!value) { printf("Failed to parse DCFG file. Error: %s\n", dcfg_last_error(instance)); dcfg_destroy_instance(instance); return 1; } WALK(value, false, 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("", (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("\t"); walk_value(body, evaluate, indent + 1, false); } else { printf(""); } } break; case dcfg_ValueType_FunctionCall: if (evaluate) { dcfg_Value *res; if (dcfg_Value_evaluate(value, &res)) walk_value(res, evaluate, indent, first); else printf(""); } else { printf(""); } break; default: printf(""); break; } if (indent == 0) { putchar('\n'); } }