Get something working
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>
This commit is contained in:
2025-08-01 07:38:13 +03:00
parent 80af330d1b
commit 1d40c785f8
5 changed files with 571 additions and 68 deletions

View File

@@ -1,9 +1,11 @@
#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)
@@ -16,11 +18,25 @@ static void print_indent(int indent)
int main(int argc, char *argv[])
{
if (argc < 2) {
printf("Usage: %s <dcfg file>\n", argv[0]);
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) {
@@ -29,7 +45,7 @@ int main(int argc, char *argv[])
return 1;
}
dcfg_Value *value = dcfg_parse(instance, dcfg_SV(argv[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));
@@ -37,7 +53,7 @@ int main(int argc, char *argv[])
return 1;
}
WALK(value, false, 0);
WALK(value, evaluate, 0);
dcfg_destroy(value);
dcfg_destroy_instance(instance);

143
programs/dcfgq.c Normal file
View File

@@ -0,0 +1,143 @@
#include <dcfg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum {
T_FIELD,
T_INDEX,
} TokenType;
typedef struct {
TokenType type;
union {
dcfg_StringView field;
size_t index;
} v;
} Token;
#define MAX_TOKENS 256
static size_t tokenize(char const *query, Token *out)
{
size_t count = 0;
size_t i = 0;
if (query[i] == '.')
i++;
while (query[i] && count < MAX_TOKENS) {
if (query[i] == '.') {
i++;
size_t start = i;
while (query[i] && query[i] != '.' && query[i] != '[')
i++;
out[count].type = T_FIELD;
out[count].v.field.data = query + start;
out[count].v.field.size = i - start;
count++;
} else if (query[i] == '[') {
i++;
char *end;
size_t idx = strtoul(query + i, &end, 10);
if (*end != ']') {
fprintf(stderr, "invalid index\n");
exit(1);
}
i = (size_t)(end - query) + 1;
out[count].type = T_INDEX;
out[count].v.index = idx;
count++;
} else {
size_t start = i;
while (query[i] && query[i] != '.' && query[i] != '[')
i++;
out[count].type = T_FIELD;
out[count].v.field.data = query + start;
out[count].v.field.size = i - start;
count++;
}
}
return count;
}
static void print_value(dcfg_Value *v)
{
dcfg_StringView sv;
if (dcfg_serialize_value(v, &sv)) {
fwrite(sv.data, 1, sv.size, stdout);
free((void *)sv.data);
putchar('\n');
} else {
puts("null");
}
}
int main(int argc, char **argv)
{
if (argc < 3) {
fprintf(stderr, "usage: %s <query> <file>\n", argv[0]);
return 1;
}
char const *query = argv[1];
char const *file = argv[2];
dcfg_Instance *inst = dcfg_make_instance(&(dcfg_InstanceCreateInfo) { 0 });
if (!inst) {
fprintf(stderr, "failed to create instance\n");
return 1;
}
dcfg_Value *root = dcfg_parse(inst, dcfg_SV(file));
if (!root) {
fprintf(stderr, "parse error: %s\n", dcfg_last_error(inst));
dcfg_destroy_instance(inst);
return 1;
}
Token toks[MAX_TOKENS];
size_t n = tokenize(query, toks);
dcfg_Value *evaled;
if (!dcfg_Value_evaluate_toplevel(root, &evaled, NULL, NULL, 0)) {
fprintf(stderr, "evaluation error: %s\n", dcfg_last_error(inst));
dcfg_destroy(root);
dcfg_destroy_instance(inst);
return 1;
}
dcfg_Value *cur = evaled;
for (size_t i = 0; i < n; i++) {
Token *t = &toks[i];
dcfg_Value *next = NULL;
if (t->type == T_FIELD) {
if (!dcfg_Value_get_object_field_ex(cur, t->v.field, &next, true)) {
fprintf(stderr, "no such field\n");
dcfg_destroy(evaled);
dcfg_destroy(root);
dcfg_destroy_instance(inst);
return 1;
}
} else {
if (!dcfg_Value_get_array_item_ex(cur, t->v.index, &next, true)) {
fprintf(stderr, "index out of bounds\n");
dcfg_destroy(evaled);
dcfg_destroy(root);
dcfg_destroy_instance(inst);
return 1;
}
}
if (cur != evaled)
dcfg_destroy(cur);
cur = next;
}
print_value(cur);
if (cur != evaled)
dcfg_destroy(cur);
dcfg_destroy(evaled);
dcfg_destroy(root);
dcfg_destroy_instance(inst);
return 0;
}