#include "config.h" #include "lauxlib.h" #include "lualib.h" #include "stdlib.h" #include "string.h" int pow_open_config(pow_config *cfg, char *path) { int err; cfg->L = luaL_newstate(); if (!cfg->L) { return 1; } lua_State *L = cfg->L; // just easier to access luaL_openlibs(L); err = luaL_loadfile(L, path); if (err) { return 1; } err = lua_pcall(L, 0, 1, 0); if (err) { printf("%s\n", lua_tostring(L, -1)); return 1; } if (!lua_istable(L, -1)) { printf("bad config. you must return a table.\n"); return 1; } lua_getfield(L, -1, "repos"); // this will push the entire config table to -2 // and push repos to -1 if (lua_istable(L, -1)) { size_t repo_count = lua_rawlen(L, -1); for (size_t i = 1; i <= repo_count; i++) { lua_rawgeti(L, -1, i); if (lua_istable(L, -1)) { pow_repo *repo = malloc(sizeof(pow_repo)); if (!repo) { lua_pop(L, 1); printf("malloc for repo failed, what the fuck? something really bad " "happened i guess\n"); return 1; } lua_getfield(L, -1, "path"); if (lua_isstring(L, -1)) { const char *path = lua_tostring(L, -1); const char *path_dup = strdup(path); if (!path_dup) { lua_pop(L, 1); lua_pop(L, 1); free(repo); printf( "malloc for path failed, what the fuck? something really bad " "happened i guess\n"); return 1; } repo->path = path_dup; } else { printf("invalid (or non existent) path for repo\n"); lua_pop(L, 1); lua_pop(L, 1); free(repo); continue; } pow_repo **repos = realloc(cfg->repos, (cfg->repos_count + 1) * sizeof(*repos)); if (!repos) { printf("failed realloc! bad things coming\n"); lua_pop(L, 1); lua_pop(L, 1); free(repo->path); free(repo); return 1; } repos[cfg->repos_count++] = repo; cfg->repos = repos; lua_pop(L, 1); } lua_pop(L, 1); } } return 0; } int pow_close_config(pow_config *cfg) { for (size_t i = 0; i < cfg->repos_count; i++) { free(cfg->repos[i]->path); free(cfg->repos[i]); } free(cfg->repos); lua_close(cfg->L); return 0; }