apk-tools/src/lua-apk.c

231 lines
5.6 KiB
C
Raw Normal View History

2010-12-15 10:09:35 +00:00
#include <features.h>
2010-03-06 19:07:38 +00:00
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include "apk_blob.h"
#include "apk_database.h"
2010-03-06 19:07:38 +00:00
#include "apk_defines.h"
#include "apk_version.h"
#define LIBNAME "apk"
2010-10-15 22:16:22 +00:00
#define APKDB_META "apk_database"
2010-03-06 19:07:38 +00:00
struct flagmap {
const char *name;
int flag;
};
struct flagmap opendb_flagmap[] = {
{"read", APK_OPENF_READ},
{"write", APK_OPENF_WRITE},
{"create", APK_OPENF_CREATE},
{"no_installed", APK_OPENF_NO_INSTALLED},
{"no_scripts", APK_OPENF_NO_SCRIPTS},
{"no_world", APK_OPENF_NO_WORLD},
{"no_sys_repos", APK_OPENF_NO_SYS_REPOS},
{"no_installed_repo", APK_OPENF_NO_INSTALLED_REPO},
{"no_repos", APK_OPENF_NO_REPOS},
{"no_state", APK_OPENF_NO_STATE},
{"no_scripts", APK_OPENF_NO_SCRIPTS},
{"no_world", APK_OPENF_NO_WORLD},
{NULL, 0}
};
static apk_blob_t check_blob(lua_State *L, int index)
{
apk_blob_t blob;
blob.ptr = (char *)luaL_checklstring(L, index, (size_t *)&blob.len);
return blob;
}
2010-03-06 19:07:38 +00:00
/* version_validate(verstr) */
/* returns boolean */
static int Pversion_validate(lua_State *L)
{
apk_blob_t ver = check_blob(L, 1);
2010-03-06 19:07:38 +00:00
lua_pushboolean(L, apk_version_validate(ver));
return 1;
}
/* version_compare(verstr1, verstr2)
returns either '<', '=' or '>'
*/
static int Pversion_compare(lua_State *L)
{
apk_blob_t a, b;
a = check_blob(L, 1);
b = check_blob(L, 2);
2010-03-06 19:07:38 +00:00
lua_pushstring(L, apk_version_op_string(apk_version_compare_blob(a, b)));
return 1;
}
/* version_is_less(verstr1, verstr2)
returns either '<', '=' or '>'
*/
static int Pversion_is_less(lua_State *L)
{
apk_blob_t a, b;
a = check_blob(L, 1);
b = check_blob(L, 2);
2010-03-06 19:07:38 +00:00
lua_pushboolean(L, apk_version_compare_blob(a, b) == APK_VERSION_LESS);
return 1;
}
//static getfield(lua_State *L, const char *key)
//{
static const char *get_opt_string_field(lua_State *L, int index,
const char *key, const char *def)
{
const char *value;
lua_getfield(L, index, key);
value = luaL_optstring(L, -1, def);
lua_pop(L, 1);
return value;
}
2010-12-15 10:09:35 +00:00
static void set_string_field(lua_State *L, int index, const char *key,
const char *value)
{
lua_pushstring(L, key);
lua_pushstring(L, value);
lua_settable(L, index);
}
static int get_opt_int_field(lua_State *L, int index, const char *key, int def)
{
int value;
lua_getfield(L, index, key);
value = luaL_optinteger(L, -1, def);
lua_pop(L, 1);
return value;
}
2010-12-15 10:09:35 +00:00
static void set_int_field(lua_State *L, int index, const char *key, int value)
{
lua_pushstring(L, key);
lua_pushinteger(L, value);
lua_settable(L, index);
}
static int get_boolean_field(lua_State *L, int index, const char *key)
{
int value;
lua_getfield(L, index, key);
value = lua_toboolean(L, -1);
lua_pop(L, 1);
return value;
}
static int get_dbopts(lua_State *L, int i, struct apk_db_options *o)
{
struct flagmap *f;
o->root = (char *)get_opt_string_field(L, i, "root", NULL);
o->repositories_file = (char *)get_opt_string_field(L, i, "repositories_file", NULL);
o->keys_dir = (char *)get_opt_string_field(L, i, "keys_dir", NULL);
o->lock_wait = get_opt_int_field(L, i, "lock_wait", 0);
for (f = opendb_flagmap; f->name != NULL; f++)
if (get_boolean_field(L, i, f->name))
o->open_flags |= f->flag;
return 0;
}
2010-10-15 22:16:22 +00:00
static struct apk_database *checkdb(lua_State *L, int index)
{
struct apk_database *db;
luaL_checktype(L, index, LUA_TUSERDATA);
db = (struct apk_database *) luaL_checkudata(L, index, APKDB_META);
if (db == NULL)
luaL_typerror(L, index, APKDB_META);
return db;
}
static int Papk_db_open(lua_State *L)
{
struct apk_db_options opts;
2010-10-15 22:16:22 +00:00
struct apk_database *db;
int r;
memset(&opts, 0, sizeof(opts));
2010-10-15 22:16:22 +00:00
list_init(&opts.repository_list);
if (lua_istable(L, 1))
get_dbopts(L, 1, &opts);
2010-10-15 22:16:22 +00:00
db = lua_newuserdata(L, sizeof(struct apk_database));
luaL_getmetatable(L, APKDB_META);
lua_setmetatable(L, -2);
r = apk_db_open(db, &opts);
if (r != 0)
luaL_error(L, "apk_db_open() failed");
return 1;
}
static int Papk_db_close(lua_State *L)
{
struct apk_database *db = checkdb(L, 1);
apk_db_close(db);
return 0;
}
2010-03-06 19:07:38 +00:00
2010-10-15 22:16:22 +00:00
2010-12-15 10:09:35 +00:00
static int push_package(lua_State *L, struct apk_package *pkg)
{
if (pkg == NULL) {
lua_pushnil(L);
return 1;
}
lua_newtable(L);
set_string_field(L, -3, "name", pkg->name->name);
set_string_field(L, -3, "version", apk_blob_cstr(*pkg->version));
set_string_field(L, -3, "url", pkg->url);
set_string_field(L, -3, "license", apk_blob_cstr(*pkg->license));
set_string_field(L, -3, "description", pkg->description);
set_string_field(L, -3, "filename", pkg->filename);
set_int_field(L, -3, "size", pkg->size);
return 1;
}
static int Papk_who_owns(lua_State *L)
{
struct apk_database *db = checkdb(L, 1);
const char *path = luaL_checkstring(L, 2);
struct apk_package *pkg = apk_db_get_file_owner(db, APK_BLOB_STR(path));
return push_package(L, pkg);
}
2010-10-15 22:16:22 +00:00
static const luaL_reg reg_apk_methods[] = {
2010-03-06 19:07:38 +00:00
{"version_validate", Pversion_validate},
{"version_compare", Pversion_compare},
{"version_is_less", Pversion_is_less},
{"db_open", Papk_db_open},
2010-12-15 10:09:35 +00:00
{"who_owns", Papk_who_owns},
2010-03-06 19:07:38 +00:00
{NULL, NULL}
};
2010-10-15 22:16:22 +00:00
static const luaL_reg reg_apk_db_meta_methods[] = {
{"__gc", Papk_db_close},
{NULL, NULL}
};
2010-03-06 19:07:38 +00:00
LUALIB_API int luaopen_apk(lua_State *L)
{
2010-10-15 22:16:22 +00:00
luaL_register(L, LIBNAME, reg_apk_methods);
2010-03-06 19:07:38 +00:00
lua_pushliteral(L, "version");
lua_pushliteral(L, APK_VERSION);
lua_settable(L, -3);
2010-10-15 22:16:22 +00:00
luaL_newmetatable(L, APKDB_META);
luaL_register(L, NULL, reg_apk_db_meta_methods);
lua_pushliteral(L, "__index");
lua_pushvalue(L, -3);
lua_rawset(L, -3);
lua_pushliteral(L, "__metatable");
lua_pushvalue(L, -3);
lua_rawset(L, -3);
lua_pop(L, 1);
2010-03-06 19:07:38 +00:00
return 1;
}