#include "posix.h"
#include <assert.h>
#include <string.h>
#include "error.h"
#include "formats/ini.h"
#include "machine_file.h"
#include "platform/filesystem.h"
#include "platform/mem.h"
struct machine_info {
uint32_t system, cpu_family, cpu, endian;
struct {
uint32_t c, ld, ar;
} binaries;
};
enum machine_file_section {
mfile_section_constants,
mfile_section_binaries,
mfile_section_properties,
mfile_section_host_machine,
machine_file_section_count,
};
static const char *machine_file_section_names[machine_file_section_count] = {
[mfile_section_constants] = "constants",
[mfile_section_binaries] = "binaries",
[mfile_section_properties] = "properties",
[mfile_section_host_machine] = "host_machine",
};
static bool
mfile_lookup(const char *val, const char *table[], uint32_t len, uint32_t *ret)
{
uint32_t i;
for (i = 0; i < len; ++i) {
if (strcmp(val, table[i]) == 0) {
*ret = i;
return true;
}
}
return false;
}
struct machine_file_parse_ctx {
struct workspace *wk, *dest_wk;
};
static bool
machine_file_parse_cb(void *_ctx, struct source *src, const char *_sect,
const char *k, const char *v, uint32_t line)
{
struct machine_file_parse_ctx *ctx = _ctx;
enum machine_file_section sect;
if (!mfile_lookup(_sect, machine_file_section_names,
machine_file_section_count, §)) {
if (!k) {
error_messagef(src, line, 1, "invalid section '%s'", _sect);
}
return false;
} else if (!k) {
hash_clear(¤t_project(ctx->wk)->scope);
return true;
}
if (!_sect) {
error_messagef(src, line, 1, "key not under any section");
return false;
}
struct source val_src = { .label = k, .src = v, .len = strlen(v), };
uint32_t res;
if (!eval(ctx->wk, &val_src, &res)) {
error_messagef(src, line, 1, "failed to parse value");
return false;
}
char buf[2048];
obj_to_s(ctx->wk, res, buf, 2048);
if (sect == mfile_section_constants) {
hash_set(&ctx->wk->scope, k, res);
} else {
hash_set(¤t_project(ctx->wk)->scope, k, res);
uint32_t cloned, objkey, dest_dict;
if (!obj_clone(ctx->wk, ctx->dest_wk, res, &cloned)) {
return false;
}
make_obj(ctx->dest_wk, &objkey, obj_string)->dat.str =
wk_str_push(ctx->dest_wk, k);
switch (sect) {
case mfile_section_binaries:
printf("setting binaries.%s=%s\n", k, buf);
dest_dict = ctx->dest_wk->binaries;
break;
case mfile_section_host_machine:
dest_dict = ctx->dest_wk->host_machine;
break;
default:
assert(false && "todo");
return false;
}
obj_dict_set(ctx->dest_wk, dest_dict, objkey, cloned);
}
return true;
}
bool
machine_file_parse(struct workspace *dest_wk, const char *path)
{
bool ret = false;
char *ini_buf;
struct workspace wk;
workspace_init(&wk);
wk.lang_mode = language_internal;
uint32_t id;
make_project(&wk, &id, "dummy", wk.source_root, wk.build_root);
struct machine_file_parse_ctx ctx = { .wk = &wk, .dest_wk = dest_wk, };
if (!ini_parse(path, &ini_buf, machine_file_parse_cb, &ctx)) {
goto ret;
}
ret = true;
ret:
if (ini_buf) {
z_free(ini_buf);
}
workspace_destroy(&wk);
return ret;
}