#include "package.h" #include "lauxlib.h" #include "lualib.h" #include "malloc.h" #include "pow_lua.h" #include "stdio.h" #include "string.h" #include int extract_package_info(lua_State *L, pow_package *pkg) { lua_getfield(L, -1, "name"); if (!lua_isstring(L, -1)) { printf("invalid package, name is not string (or doesn't exist)\n"); return 1; } pkg->name = strdup(lua_tostring(L, -1)); if (!pkg->name) { printf("strdup failed trying to get package name\n"); return 1; } lua_pop(L, 1); lua_getfield(L, -1, "version"); if (!lua_isstring(L, -1)) { free(pkg->name); printf("invalid package, version is not string (or doesn't exist)\n"); return 1; } pkg->version = strdup(lua_tostring(L, -1)); lua_pop(L, 1); if (!pkg->version) { free(pkg->name); printf("strdup failed trying to get package name\n"); return 1; } lua_getfield(L, -1, "sources"); if (!lua_istable(L, -1)) { free(pkg->name); free(pkg->version); printf("sources is not table or doesn't exist\n"); return 1; } size_t sources_len = lua_rawlen(L, -1); for (size_t i = 0; i < sources_len; i++) { lua_pushinteger(L, i + 1); lua_gettable(L, -2); if (lua_type(L, -1) == LUA_TNIL) break; lua_getfield(L, -1, "path"); pow_package_source *src = malloc(sizeof(pow_package_source)); if (!src) { printf("failed to malloc pow_package_source\n"); return 1; } if (!lua_isstring(L, -1)) { lua_pop(L, 1); printf("path is not string\n"); return 1; } const char *in = strdup(lua_tostring(L, -1)); if (!in) { printf("failed to strdup path?"); return 1; } src->in = in; lua_pop(L, 1); lua_getfield(L, -1, "out"); if (!lua_isstring(L, -1)) { lua_pop(L, 1); printf("out is not string\n"); return 1; } const char *out = strdup(lua_tostring(L, -1)); if (!out) { free(in); lua_pop(L, 1); printf("out strdup failed?\n"); return 1; } src->out = out; lua_pop(L, 1); lua_getfield(L, -1, "hash"); if (!lua_isstring(L, -1)) { free(in); free(out); printf("hash is not string?\n"); return 1; } const char *hash = strdup(lua_tostring(L, -1)); src->hash = hash; pkg->source_count++; printf("attempting to malloc\n"); pkg->sources = realloc(pkg->sources, pkg->source_count * sizeof(pow_package_source *)); pkg->sources[pkg->source_count - 1] = src; lua_pop(L, 1); lua_pop(L, 1); } lua_pop(L, 1); return 0; } int pow_package_open(pow_package *pkg, const char *path) { FILE *fp; int c; int err; fp = fopen(path, "r"); if (!fp) { printf("error opening package definition, doesn't exist?\n"); return 1; } char *package_buffer = malloc(4096); size_t total = 0; size_t capacity = 4096; while ((c = fgetc(fp)) != EOF) { if (total + 1 >= capacity) { capacity *= 2; char *tmp = realloc(package_buffer, capacity); if (!tmp) { fclose(fp); free(package_buffer); printf("failed to realloc package buffer\n"); return 1; } printf("reallocated package buffer due to size constraints\n"); package_buffer = tmp; } package_buffer[total++] = c; } fclose(fp); package_buffer[total] = '\0'; lua_State *L = luaL_newstate(); pkg->L = L; luaL_openlibs(L); pow_lua_load(L); luaL_loadstring(L, package_buffer); err = lua_pcall(L, 0, 1, 0); free(package_buffer); if (err) { printf("%s\n", lua_tostring(L, -1)); return 1; } if (!lua_istable(L, -1)) { printf("invalid package, scripts must return table\n"); return 1; } pkg->source_count = 0; pkg->sources = NULL; extract_package_info(L, pkg); pkg->path = path; pkg->pkg_ref = luaL_ref(L, LUA_REGISTRYINDEX); return 0; } int pow_package_close(pow_package *pkg) { free(pkg->name); free(pkg->version); lua_close(pkg->L); return 0; }