2014-12-11 07:48:18 -08:00
|
|
|
#include "elua_private.h"
|
|
|
|
|
2016-03-29 05:22:39 -07:00
|
|
|
#include <Ecore_File.h>
|
|
|
|
|
2014-12-11 07:48:18 -08:00
|
|
|
static Eina_Prefix *_elua_pfx = NULL;
|
|
|
|
|
|
|
|
static int _elua_init_counter = 0;
|
|
|
|
int _elua_log_dom = -1;
|
|
|
|
|
|
|
|
EAPI int
|
|
|
|
elua_init(void)
|
|
|
|
{
|
|
|
|
const char *dom = "elua";
|
|
|
|
if (_elua_init_counter > 0) return ++_elua_init_counter;
|
|
|
|
|
|
|
|
eina_init();
|
2016-03-29 05:22:39 -07:00
|
|
|
ecore_file_init();
|
|
|
|
|
2014-12-11 07:48:18 -08:00
|
|
|
_elua_log_dom = eina_log_domain_register(dom, EINA_COLOR_LIGHTBLUE);
|
|
|
|
if (_elua_log_dom < 0)
|
|
|
|
{
|
|
|
|
EINA_LOG_ERR("Could not register log domain: %s", dom);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
eina_log_timing(_elua_log_dom, EINA_LOG_STATE_STOP, EINA_LOG_STATE_INIT);
|
|
|
|
INF("elua init");
|
|
|
|
|
2014-12-11 08:41:24 -08:00
|
|
|
_elua_pfx = eina_prefix_new(NULL, elua_init, "ELUA", "elua", "checkme",
|
2014-12-11 07:48:18 -08:00
|
|
|
PACKAGE_BIN_DIR, "", PACKAGE_DATA_DIR,
|
|
|
|
LOCALE_DIR);
|
|
|
|
|
|
|
|
if (!_elua_pfx)
|
|
|
|
{
|
|
|
|
ERR("coul not find elua prefix");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ++_elua_init_counter;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
|
|
|
elua_shutdown(void)
|
|
|
|
{
|
|
|
|
if (_elua_init_counter <= 0)
|
|
|
|
{
|
|
|
|
EINA_LOG_ERR("Init count not greater than 0 in shutdown.");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
--_elua_init_counter;
|
|
|
|
|
|
|
|
if (_elua_init_counter > 0)
|
|
|
|
return _elua_init_counter;
|
|
|
|
|
|
|
|
INF("shutdown");
|
|
|
|
eina_log_timing(_elua_log_dom, EINA_LOG_STATE_START, EINA_LOG_STATE_SHUTDOWN);
|
|
|
|
|
|
|
|
eina_prefix_free(_elua_pfx);
|
|
|
|
_elua_pfx = NULL;
|
|
|
|
|
|
|
|
eina_log_domain_unregister(_elua_log_dom);
|
|
|
|
_elua_log_dom = -1;
|
|
|
|
|
2016-03-29 05:22:39 -07:00
|
|
|
ecore_file_shutdown();
|
2014-12-11 07:48:18 -08:00
|
|
|
eina_shutdown();
|
|
|
|
return _elua_init_counter;
|
|
|
|
}
|
2014-12-12 02:44:58 -08:00
|
|
|
|
2015-04-08 06:00:57 -07:00
|
|
|
EAPI Elua_State *
|
2015-04-10 06:36:26 -07:00
|
|
|
elua_state_new(const char *progname)
|
2015-04-08 06:00:57 -07:00
|
|
|
{
|
|
|
|
Elua_State *ret = NULL;
|
2017-11-23 01:07:01 -08:00
|
|
|
Eina_Safepointer *sp;
|
2015-04-08 06:00:57 -07:00
|
|
|
lua_State *L = luaL_newstate();
|
|
|
|
if (!L)
|
|
|
|
return NULL;
|
2015-04-08 08:43:14 -07:00
|
|
|
ret = calloc(1, sizeof(Elua_State));
|
2015-04-08 06:00:57 -07:00
|
|
|
ret->luastate = L;
|
2015-04-10 06:36:26 -07:00
|
|
|
if (progname) ret->progname = eina_stringshare_add(progname);
|
2015-04-08 06:00:57 -07:00
|
|
|
luaL_openlibs(L);
|
2017-11-23 01:07:01 -08:00
|
|
|
sp = (Eina_Safepointer *)eina_safepointer_register(ret);
|
|
|
|
ret->sp = sp;
|
|
|
|
lua_pushlightuserdata(L, sp);
|
2015-04-08 06:29:58 -07:00
|
|
|
lua_setfield(L, LUA_REGISTRYINDEX, "elua_ptr");
|
2015-04-08 06:00:57 -07:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI void
|
2015-04-08 06:52:06 -07:00
|
|
|
elua_state_free(Elua_State *es)
|
2015-04-08 06:00:57 -07:00
|
|
|
{
|
2015-04-10 04:02:08 -07:00
|
|
|
void *data;
|
2015-04-08 06:52:06 -07:00
|
|
|
if (!es) return;
|
2015-04-09 08:12:15 -07:00
|
|
|
if (es->luastate)
|
|
|
|
{
|
|
|
|
EINA_LIST_FREE(es->cmods, data)
|
|
|
|
{
|
|
|
|
lua_rawgeti(es->luastate, LUA_REGISTRYINDEX, (size_t)data);
|
|
|
|
lua_call(es->luastate, 0, 0);
|
|
|
|
}
|
|
|
|
lua_close(es->luastate);
|
|
|
|
}
|
|
|
|
else if (es->cmods)
|
|
|
|
eina_list_free(es->cmods);
|
2015-04-23 08:02:58 -07:00
|
|
|
EINA_LIST_FREE(es->lmods, data)
|
|
|
|
eina_stringshare_del(data);
|
2015-04-10 04:02:08 -07:00
|
|
|
EINA_LIST_FREE(es->lincs, data)
|
|
|
|
eina_stringshare_del(data);
|
2015-04-10 06:36:26 -07:00
|
|
|
eina_stringshare_del(es->progname);
|
2015-04-08 08:43:14 -07:00
|
|
|
eina_stringshare_del(es->coredir);
|
|
|
|
eina_stringshare_del(es->moddir);
|
|
|
|
eina_stringshare_del(es->appsdir);
|
2017-11-23 01:07:01 -08:00
|
|
|
eina_safepointer_unregister(es->sp);
|
2015-04-08 06:52:06 -07:00
|
|
|
free(es);
|
2015-04-08 06:00:57 -07:00
|
|
|
}
|
|
|
|
|
2015-04-08 08:43:14 -07:00
|
|
|
EAPI void
|
|
|
|
elua_state_dirs_set(Elua_State *es, const char *core, const char *mods,
|
|
|
|
const char *apps)
|
|
|
|
{
|
2015-06-09 06:01:25 -07:00
|
|
|
char *spath = NULL;
|
2015-04-09 03:06:48 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(es);
|
2015-06-09 06:01:25 -07:00
|
|
|
if (core)
|
|
|
|
{
|
|
|
|
eina_stringshare_del(es->coredir);
|
|
|
|
spath = eina_file_path_sanitize(core);
|
|
|
|
es->coredir = eina_stringshare_add(spath);
|
|
|
|
free(spath);
|
|
|
|
}
|
|
|
|
if (mods)
|
|
|
|
{
|
|
|
|
eina_stringshare_del(es->moddir);
|
|
|
|
spath = eina_file_path_sanitize(mods);
|
|
|
|
es->moddir = eina_stringshare_add(spath);
|
|
|
|
free(spath);
|
|
|
|
}
|
|
|
|
if (apps)
|
|
|
|
{
|
|
|
|
eina_stringshare_del(es->appsdir);
|
|
|
|
spath = eina_file_path_sanitize(apps);
|
|
|
|
es->appsdir = eina_stringshare_add(spath);
|
|
|
|
free(spath);
|
|
|
|
}
|
2015-04-08 08:43:14 -07:00
|
|
|
}
|
|
|
|
|
2015-04-10 03:42:09 -07:00
|
|
|
EAPI void
|
|
|
|
elua_state_dirs_fill(Elua_State *es, Eina_Bool ignore_env)
|
|
|
|
{
|
|
|
|
const char *coredir = NULL, *moddir = NULL, *appsdir = NULL;
|
|
|
|
char coredirbuf[PATH_MAX], moddirbuf[PATH_MAX], appsdirbuf[PATH_MAX];
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(es);
|
|
|
|
if (!(coredir = es->coredir))
|
|
|
|
{
|
|
|
|
if (ignore_env || !(coredir = getenv("ELUA_CORE_DIR")) || !coredir[0])
|
|
|
|
{
|
|
|
|
coredir = coredirbuf;
|
|
|
|
snprintf(coredirbuf, sizeof(coredirbuf), "%s/core",
|
|
|
|
eina_prefix_data_get(_elua_pfx));
|
|
|
|
}
|
2015-06-09 06:01:25 -07:00
|
|
|
if (coredir) {
|
|
|
|
char *sdir = eina_file_path_sanitize(coredir);
|
|
|
|
es->coredir = eina_stringshare_add(sdir);
|
|
|
|
free(sdir);
|
|
|
|
}
|
2015-04-10 03:42:09 -07:00
|
|
|
}
|
|
|
|
if (!(moddir = es->moddir))
|
|
|
|
{
|
|
|
|
if (ignore_env || !(moddir = getenv("ELUA_MODULES_DIR")) || !moddir[0])
|
|
|
|
{
|
|
|
|
moddir = moddirbuf;
|
|
|
|
snprintf(moddirbuf, sizeof(moddirbuf), "%s/modules",
|
|
|
|
eina_prefix_data_get(_elua_pfx));
|
|
|
|
}
|
2015-06-09 06:01:25 -07:00
|
|
|
if (moddir) {
|
|
|
|
char *sdir = eina_file_path_sanitize(moddir);
|
|
|
|
es->moddir = eina_stringshare_add(sdir);
|
|
|
|
free(sdir);
|
|
|
|
}
|
2015-04-10 03:42:09 -07:00
|
|
|
}
|
|
|
|
if (!(appsdir = es->appsdir))
|
|
|
|
{
|
|
|
|
if (ignore_env || !(appsdir = getenv("ELUA_APPS_DIR")) || !appsdir[0])
|
|
|
|
{
|
|
|
|
appsdir = appsdirbuf;
|
|
|
|
snprintf(appsdirbuf, sizeof(appsdirbuf), "%s/apps",
|
|
|
|
eina_prefix_data_get(_elua_pfx));
|
|
|
|
}
|
2015-06-09 06:01:25 -07:00
|
|
|
if (appsdir) {
|
|
|
|
char *sdir = eina_file_path_sanitize(appsdir);
|
|
|
|
es->appsdir = eina_stringshare_add(sdir);
|
|
|
|
free(sdir);
|
|
|
|
}
|
2015-04-10 03:42:09 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-09 06:17:38 -07:00
|
|
|
EAPI Eina_Stringshare *
|
2015-04-09 06:21:18 -07:00
|
|
|
elua_state_core_dir_get(const Elua_State *es)
|
2015-04-09 06:17:38 -07:00
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, NULL);
|
|
|
|
return es->coredir;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Stringshare *
|
2015-04-09 06:21:18 -07:00
|
|
|
elua_state_mod_dir_get(const Elua_State *es)
|
2015-04-09 06:17:38 -07:00
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, NULL);
|
|
|
|
return es->moddir;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Stringshare *
|
2015-04-09 06:21:18 -07:00
|
|
|
elua_state_apps_dir_get(const Elua_State *es)
|
2015-04-09 06:17:38 -07:00
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, NULL);
|
2015-04-16 06:58:42 -07:00
|
|
|
return es->appsdir;
|
2015-04-09 06:17:38 -07:00
|
|
|
}
|
|
|
|
|
2015-04-10 06:39:20 -07:00
|
|
|
EAPI Eina_Stringshare *
|
|
|
|
elua_state_prog_name_get(const Elua_State *es)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, NULL);
|
|
|
|
return es->progname;
|
|
|
|
}
|
|
|
|
|
2015-04-10 04:02:08 -07:00
|
|
|
EAPI void
|
|
|
|
elua_state_include_path_add(Elua_State *es, const char *path)
|
|
|
|
{
|
2015-06-09 06:01:25 -07:00
|
|
|
char *spath = NULL;
|
2015-04-10 04:02:08 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN(es);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN(path);
|
|
|
|
EINA_SAFETY_ON_FALSE_RETURN(path[0]);
|
2015-06-09 06:01:25 -07:00
|
|
|
spath = eina_file_path_sanitize(path);
|
|
|
|
es->lincs = eina_list_append(es->lincs, eina_stringshare_add(spath));
|
|
|
|
free(spath);
|
2015-04-10 04:02:08 -07:00
|
|
|
}
|
|
|
|
|
2015-04-10 04:05:54 -07:00
|
|
|
EAPI Eina_Bool
|
|
|
|
elua_state_require_ref_push(Elua_State *es)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE);
|
|
|
|
EINA_SAFETY_ON_FALSE_RETURN_VAL(es->requireref != LUA_REFNIL, EINA_FALSE);
|
|
|
|
lua_rawgeti(es->luastate, LUA_REGISTRYINDEX, es->requireref);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI Eina_Bool
|
|
|
|
elua_state_appload_ref_push(Elua_State *es)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE);
|
|
|
|
EINA_SAFETY_ON_FALSE_RETURN_VAL(es->apploadref != LUA_REFNIL, EINA_FALSE);
|
|
|
|
lua_rawgeti(es->luastate, LUA_REGISTRYINDEX, es->apploadref);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2015-04-09 06:34:21 -07:00
|
|
|
EAPI lua_State *
|
|
|
|
elua_state_lua_state_get(const Elua_State *es)
|
|
|
|
{
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, NULL);
|
|
|
|
return es->luastate;
|
|
|
|
}
|
|
|
|
|
2015-04-08 06:29:58 -07:00
|
|
|
EAPI Elua_State *
|
2015-04-14 06:14:50 -07:00
|
|
|
elua_state_from_lua_state_get(lua_State *L)
|
2015-04-08 06:29:58 -07:00
|
|
|
{
|
2015-04-09 03:06:48 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(L, NULL);
|
2015-04-08 06:29:58 -07:00
|
|
|
lua_getfield(L, LUA_REGISTRYINDEX, "elua_ptr");
|
|
|
|
if (!lua_isnil(L, -1))
|
|
|
|
{
|
2017-11-23 01:07:01 -08:00
|
|
|
Eina_Safepointer *sp = lua_touserdata(L, -1);
|
|
|
|
void *st = eina_safepointer_get(sp);
|
2015-04-08 06:29:58 -07:00
|
|
|
lua_pop(L, 1);
|
|
|
|
return (Elua_State *)st;
|
|
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-12-12 02:44:58 -08:00
|
|
|
static int
|
|
|
|
_elua_gettext_bind_textdomain(lua_State *L)
|
|
|
|
{
|
|
|
|
#ifdef ENABLE_NLS
|
|
|
|
const char *textdomain = luaL_checkstring(L, 1);
|
|
|
|
const char *dirname = luaL_checkstring(L, 2);
|
|
|
|
const char *ret;
|
|
|
|
if (!textdomain[0] || !strcmp(textdomain, PACKAGE))
|
|
|
|
{
|
|
|
|
lua_pushnil(L);
|
|
|
|
lua_pushliteral(L, "invalid textdomain");
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
if (!(ret = bindtextdomain(textdomain, dirname)))
|
|
|
|
{
|
|
|
|
lua_pushnil(L);
|
|
|
|
lua_pushstring(L, strerror(errno));
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
bind_textdomain_codeset(textdomain, "UTF-8");
|
|
|
|
lua_pushstring(L, ret);
|
|
|
|
return 1;
|
|
|
|
#else
|
|
|
|
lua_pushliteral(L, "");
|
|
|
|
return 1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-04-30 03:15:48 -07:00
|
|
|
static int
|
|
|
|
_elua_get_message_language(lua_State *L)
|
|
|
|
{
|
|
|
|
const char *e;
|
|
|
|
e = getenv("LANGUAGE");
|
|
|
|
if (e && e[0]) goto success;
|
|
|
|
e = getenv("LC_ALL");
|
|
|
|
if (e && e[0]) goto success;
|
|
|
|
e = getenv("LC_MESSAGES");
|
|
|
|
if (e && e[0]) goto success;
|
|
|
|
e = getenv("LANG");
|
|
|
|
if (e && e[0]) goto success;
|
|
|
|
lua_pushnil(L);
|
|
|
|
return 1;
|
|
|
|
success:
|
|
|
|
lua_pushstring(L, e);
|
|
|
|
return 1;
|
|
|
|
};
|
|
|
|
|
2015-04-30 03:50:09 -07:00
|
|
|
static int
|
|
|
|
_elua_get_localeconv(lua_State *L)
|
|
|
|
{
|
|
|
|
struct lconv *lc = localeconv();
|
|
|
|
lua_createtable(L, 0, 24);
|
|
|
|
|
|
|
|
#define ELUA_LCF_S(name) \
|
|
|
|
lua_pushstring(L, lc->name); \
|
|
|
|
lua_setfield(L, -2, #name);
|
|
|
|
|
|
|
|
#define ELUA_LCF_C(name) \
|
2015-04-30 05:35:11 -07:00
|
|
|
lua_pushinteger(L, (lc->name == CHAR_MAX) ? -1 : (int)lc->name); \
|
2015-04-30 03:50:09 -07:00
|
|
|
lua_setfield(L, -2, #name);
|
|
|
|
|
|
|
|
ELUA_LCF_S(decimal_point);
|
|
|
|
ELUA_LCF_S(thousands_sep);
|
|
|
|
ELUA_LCF_S(grouping);
|
|
|
|
ELUA_LCF_S(int_curr_symbol);
|
|
|
|
ELUA_LCF_S(currency_symbol);
|
|
|
|
ELUA_LCF_S(mon_decimal_point);
|
|
|
|
ELUA_LCF_S(mon_thousands_sep);
|
|
|
|
ELUA_LCF_S(mon_grouping);
|
|
|
|
ELUA_LCF_S(positive_sign);
|
|
|
|
ELUA_LCF_S(negative_sign);
|
|
|
|
|
|
|
|
ELUA_LCF_C(frac_digits);
|
|
|
|
ELUA_LCF_C(p_cs_precedes);
|
|
|
|
ELUA_LCF_C(n_cs_precedes);
|
|
|
|
ELUA_LCF_C(p_sep_by_space);
|
|
|
|
ELUA_LCF_C(n_sep_by_space);
|
|
|
|
ELUA_LCF_C(p_sign_posn);
|
|
|
|
ELUA_LCF_C(n_sign_posn);
|
|
|
|
ELUA_LCF_C(int_frac_digits);
|
|
|
|
|
|
|
|
#undef ELUA_LCF_S
|
|
|
|
#undef ELUA_LCF_C
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
};
|
|
|
|
|
2017-11-24 01:53:27 -08:00
|
|
|
#ifdef ENABLE_NLS
|
|
|
|
static int
|
|
|
|
_elua_dgettext(lua_State *L)
|
|
|
|
{
|
|
|
|
const char *domain = luaL_checkstring(L, 1);
|
|
|
|
const char *msgid = luaL_checkstring(L, 2);
|
|
|
|
char *ret = dgettext(domain, msgid);
|
|
|
|
if (!ret)
|
|
|
|
lua_pushnil(L);
|
|
|
|
else
|
|
|
|
lua_pushstring(L, ret);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_elua_dngettext(lua_State *L)
|
|
|
|
{
|
|
|
|
const char *domain = luaL_checkstring(L, 1);
|
|
|
|
const char *msgid = luaL_checkstring(L, 2);
|
|
|
|
const char *plmsgid = luaL_checkstring(L, 3);
|
|
|
|
char *ret = dngettext(domain, msgid, plmsgid, luaL_checklong(L, 4));
|
|
|
|
if (!ret)
|
|
|
|
lua_pushnil(L);
|
|
|
|
else
|
|
|
|
lua_pushstring(L, ret);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-06-28 02:51:29 -07:00
|
|
|
const luaL_Reg gettextlib[] =
|
2014-12-12 02:44:58 -08:00
|
|
|
{
|
|
|
|
{ "bind_textdomain", _elua_gettext_bind_textdomain },
|
2015-04-30 03:15:48 -07:00
|
|
|
{ "get_message_language", _elua_get_message_language },
|
2015-04-30 03:50:09 -07:00
|
|
|
{ "get_localeconv", _elua_get_localeconv },
|
2017-11-23 01:07:01 -08:00
|
|
|
#ifdef ENABLE_NLS
|
2017-11-24 01:53:27 -08:00
|
|
|
{ "dgettext", _elua_dgettext },
|
|
|
|
{ "dngettext", _elua_dngettext },
|
2017-11-23 01:07:01 -08:00
|
|
|
#endif
|
2014-12-12 02:44:58 -08:00
|
|
|
{ NULL, NULL }
|
|
|
|
};
|
|
|
|
|
2015-04-23 08:02:58 -07:00
|
|
|
static Eina_Bool
|
2017-11-23 01:07:01 -08:00
|
|
|
_elua_state_i18n_setup(Elua_State *es)
|
2014-12-12 02:44:58 -08:00
|
|
|
{
|
2015-04-10 08:58:27 -07:00
|
|
|
char buf[PATH_MAX];
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es->coredir, EINA_FALSE);
|
2015-04-10 09:04:07 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es->progname, EINA_FALSE);
|
2015-04-10 08:58:27 -07:00
|
|
|
snprintf(buf, sizeof(buf), "%s/gettext.lua", es->coredir);
|
2015-04-20 09:04:33 -07:00
|
|
|
if (elua_util_error_report(es, elua_io_loadfile(es, buf)))
|
2015-04-10 08:58:27 -07:00
|
|
|
return EINA_FALSE;
|
2015-04-08 06:52:06 -07:00
|
|
|
lua_createtable(es->luastate, 0, 0);
|
|
|
|
luaL_register(es->luastate, NULL, gettextlib);
|
2015-04-10 08:58:27 -07:00
|
|
|
lua_call(es->luastate, 1, 0);
|
|
|
|
return EINA_TRUE;
|
2014-12-12 02:44:58 -08:00
|
|
|
}
|
2015-04-09 08:12:15 -07:00
|
|
|
|
2015-04-16 08:30:05 -07:00
|
|
|
int _elua_module_init(lua_State *L);
|
|
|
|
int _elua_module_system_init(lua_State *L);
|
|
|
|
|
2016-03-29 05:22:39 -07:00
|
|
|
static int
|
|
|
|
_elua_file_is_dir(lua_State *L)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L, ecore_file_is_dir(luaL_checkstring(L, 1)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_elua_file_exists(lua_State *L)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L, ecore_file_exists(luaL_checkstring(L, 1)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_elua_file_mkdir(lua_State *L)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L, ecore_file_mkdir(luaL_checkstring(L, 1)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-04-16 10:15:35 -07:00
|
|
|
static int
|
|
|
|
_elua_file_mkpath(lua_State *L)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L, ecore_file_mkpath(luaL_checkstring(L, 1)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_elua_file_rmdir(lua_State *L)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L, ecore_file_rmdir(luaL_checkstring(L, 1)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_elua_file_unlink(lua_State *L)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L, ecore_file_unlink(luaL_checkstring(L, 1)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_elua_file_rmrf(lua_State *L)
|
|
|
|
{
|
|
|
|
lua_pushboolean(L, ecore_file_recursive_rm(luaL_checkstring(L, 1)));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-06-28 02:51:29 -07:00
|
|
|
const luaL_Reg _elua_cutillib[] =
|
2015-04-10 09:04:07 -07:00
|
|
|
{
|
2015-04-16 08:30:05 -07:00
|
|
|
{ "init_module", _elua_module_init },
|
|
|
|
{ "popenv" , _elua_io_popen },
|
2016-03-29 05:22:39 -07:00
|
|
|
{ "file_is_dir", _elua_file_is_dir },
|
|
|
|
{ "file_exists", _elua_file_exists },
|
|
|
|
{ "file_mkdir" , _elua_file_mkdir },
|
2016-04-16 10:15:35 -07:00
|
|
|
{ "file_mkpath", _elua_file_mkpath },
|
|
|
|
{ "file_rmdir" , _elua_file_rmdir },
|
|
|
|
{ "file_unlink", _elua_file_unlink },
|
|
|
|
{ "file_rmrf" , _elua_file_rmrf },
|
2015-04-16 08:30:05 -07:00
|
|
|
{ NULL , NULL }
|
2015-04-10 09:04:07 -07:00
|
|
|
};
|
|
|
|
|
2015-04-23 08:02:58 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_elua_state_modules_setup(const Elua_State *es)
|
2015-04-10 09:04:07 -07:00
|
|
|
{
|
|
|
|
char buf[PATH_MAX];
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es->coredir, EINA_FALSE);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es->progname, EINA_FALSE);
|
|
|
|
snprintf(buf, sizeof(buf), "%s/module.lua", es->coredir);
|
2015-04-20 09:04:33 -07:00
|
|
|
if (elua_util_error_report(es, elua_io_loadfile(es, buf)))
|
2015-04-10 09:04:07 -07:00
|
|
|
return EINA_FALSE;
|
2015-04-16 08:30:05 -07:00
|
|
|
lua_pushcfunction(es->luastate, _elua_module_system_init);
|
2015-04-10 09:04:07 -07:00
|
|
|
lua_createtable(es->luastate, 0, 0);
|
|
|
|
luaL_register(es->luastate, NULL, _elua_cutillib);
|
|
|
|
lua_call(es->luastate, 2, 0);
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2015-04-16 08:30:05 -07:00
|
|
|
int
|
|
|
|
_elua_module_init(lua_State *L)
|
2015-04-09 08:12:15 -07:00
|
|
|
{
|
2015-04-14 06:14:50 -07:00
|
|
|
Elua_State *es = elua_state_from_lua_state_get(L);
|
2015-04-09 08:12:15 -07:00
|
|
|
if (!lua_isnoneornil(L, 1))
|
|
|
|
{
|
|
|
|
lua_pushvalue(L, 1);
|
|
|
|
lua_call(L, 0, 0);
|
|
|
|
}
|
|
|
|
if (!lua_isnoneornil(L, 2))
|
|
|
|
{
|
|
|
|
lua_pushvalue(L, 2);
|
|
|
|
es->cmods = eina_list_append(es->cmods,
|
|
|
|
(void*)(size_t)luaL_ref(L, LUA_REGISTRYINDEX));
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2015-04-10 04:02:08 -07:00
|
|
|
|
2015-04-16 08:30:05 -07:00
|
|
|
int
|
|
|
|
_elua_module_system_init(lua_State *L)
|
2015-04-10 04:02:08 -07:00
|
|
|
{
|
2015-04-14 06:14:50 -07:00
|
|
|
Elua_State *es = elua_state_from_lua_state_get(L);
|
2015-04-10 04:02:08 -07:00
|
|
|
const char *corepath = es->coredir;
|
|
|
|
const char *modpath = es->moddir;
|
|
|
|
const char *appspath = es->appsdir;
|
|
|
|
Eina_Stringshare *data = NULL;
|
|
|
|
if (!corepath || !modpath || !appspath)
|
|
|
|
return 0;
|
|
|
|
lua_pushvalue(L, 1);
|
|
|
|
es->requireref = luaL_ref(L, LUA_REGISTRYINDEX);
|
|
|
|
lua_pushvalue(L, 2);
|
|
|
|
es->apploadref = luaL_ref(L, LUA_REGISTRYINDEX);
|
2016-08-08 06:38:08 -07:00
|
|
|
|
|
|
|
/* module path, local directories take priority */
|
|
|
|
int n = 0;
|
|
|
|
lua_pushvalue(L, 3); ++n;
|
|
|
|
lua_pushfstring(L, ";%s/?.lua", corepath); ++n;
|
2015-04-10 04:02:08 -07:00
|
|
|
EINA_LIST_FREE(es->lincs, data)
|
|
|
|
{
|
2016-08-08 06:38:08 -07:00
|
|
|
lua_pushfstring(L, ";%s/?.lua", data);
|
2015-04-10 04:02:08 -07:00
|
|
|
eina_stringshare_del(data);
|
|
|
|
++n;
|
|
|
|
}
|
2016-08-08 06:38:08 -07:00
|
|
|
lua_pushfstring(L, ";%s/?.eo.lua", modpath); ++n;
|
|
|
|
lua_pushfstring(L, ";%s/?.lua", modpath); ++n;
|
|
|
|
lua_pushfstring(L, ";%s/?.lua", appspath); ++n;
|
|
|
|
lua_concat(L, n);
|
|
|
|
|
|
|
|
/* apps path, local directory takes priority as well */
|
2015-04-10 04:02:08 -07:00
|
|
|
lua_pushvalue(L, 4);
|
2016-08-08 06:38:08 -07:00
|
|
|
lua_pushfstring(L, ";%s/?.lua", appspath);
|
2015-04-10 04:02:08 -07:00
|
|
|
lua_concat(L, 2);
|
2016-08-08 06:38:08 -07:00
|
|
|
|
2015-04-10 04:02:08 -07:00
|
|
|
return 2;
|
|
|
|
}
|
2015-04-10 08:36:26 -07:00
|
|
|
|
2015-04-23 08:02:58 -07:00
|
|
|
EAPI Eina_Bool
|
|
|
|
elua_state_setup(Elua_State *es)
|
|
|
|
{
|
|
|
|
Eina_Stringshare *data;
|
|
|
|
Eina_Bool failed = EINA_FALSE;
|
|
|
|
|
|
|
|
if (!_elua_state_modules_setup(es))
|
|
|
|
return EINA_FALSE;
|
|
|
|
if (!_elua_state_i18n_setup(es))
|
|
|
|
return EINA_FALSE;
|
|
|
|
if (!_elua_state_io_setup(es))
|
|
|
|
return EINA_FALSE;
|
|
|
|
|
|
|
|
/* finally require the necessary modules */
|
|
|
|
EINA_LIST_FREE(es->lmods, data)
|
|
|
|
{
|
|
|
|
if (!failed)
|
|
|
|
{
|
|
|
|
if (!elua_state_require_ref_push(es))
|
|
|
|
{
|
|
|
|
failed = EINA_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
lua_pushstring(es->luastate, data);
|
|
|
|
if (elua_util_error_report(es, lua_pcall(es->luastate, 1, 0, 0)))
|
|
|
|
{
|
|
|
|
failed = EINA_TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
eina_stringshare_del(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2015-04-10 08:36:26 -07:00
|
|
|
/* Utility functions - these could be written using the other APIs */
|
|
|
|
|
|
|
|
static int
|
|
|
|
_elua_traceback(lua_State *L)
|
|
|
|
{
|
|
|
|
lua_getglobal(L, "debug");
|
|
|
|
if (!lua_istable(L, -1))
|
|
|
|
{
|
|
|
|
lua_pop(L, 1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
lua_getfield(L, -1, "traceback");
|
|
|
|
if (!lua_isfunction(L, -1))
|
|
|
|
{
|
|
|
|
lua_pop(L, 2);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
lua_pushvalue(L, 1);
|
|
|
|
lua_pushinteger(L, 2);
|
|
|
|
lua_call(L, 2, 1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_elua_docall(Elua_State *es, int narg, int nret)
|
|
|
|
{
|
|
|
|
int status;
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, -1);
|
|
|
|
int bs = lua_gettop(es->luastate) - narg;
|
|
|
|
lua_pushcfunction(es->luastate, _elua_traceback);
|
|
|
|
lua_insert(es->luastate, bs);
|
|
|
|
status = lua_pcall(es->luastate, narg, nret, bs);
|
|
|
|
lua_remove(es->luastate, bs);
|
|
|
|
if (status)
|
|
|
|
lua_gc(es->luastate, LUA_GCCOLLECT, 0);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
_elua_getargs(Elua_State *es, int argc, char **argv, int n)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int narg = argc - (n + 1);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, -1);
|
|
|
|
luaL_checkstack(es->luastate, narg + 3, "too many arguments to script");
|
|
|
|
for (i = n + 1; i < argc; ++i)
|
|
|
|
{
|
|
|
|
lua_pushstring(es->luastate, argv[i]);
|
|
|
|
}
|
|
|
|
lua_createtable(es->luastate, narg, n + 1);
|
|
|
|
for (i = 0; i < argc; ++i)
|
|
|
|
{
|
|
|
|
lua_pushstring(es->luastate, argv[i]);
|
|
|
|
lua_rawseti(es->luastate, -2, i - n);
|
|
|
|
}
|
|
|
|
return narg;
|
|
|
|
}
|
|
|
|
|
2015-04-24 08:01:24 -07:00
|
|
|
EAPI Eina_Bool
|
2015-04-10 08:36:26 -07:00
|
|
|
elua_util_require(Elua_State *es, const char *libname)
|
|
|
|
{
|
2015-04-24 08:01:24 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE);
|
2015-04-23 08:02:58 -07:00
|
|
|
if (!elua_state_require_ref_push(es))
|
|
|
|
{
|
|
|
|
/* store stuff until things are correctly set up */
|
|
|
|
es->lmods = eina_list_append(es->lmods, eina_stringshare_add(libname));
|
|
|
|
return 0;
|
|
|
|
}
|
2015-04-10 08:36:26 -07:00
|
|
|
lua_pushstring(es->luastate, libname);
|
2015-04-24 08:01:24 -07:00
|
|
|
return !elua_util_error_report(es, lua_pcall(es->luastate, 1, 0, 0));
|
2015-04-10 08:36:26 -07:00
|
|
|
}
|
|
|
|
|
2015-04-24 08:01:24 -07:00
|
|
|
EAPI Eina_Bool
|
2015-04-10 08:36:26 -07:00
|
|
|
elua_util_file_run(Elua_State *es, const char *fname)
|
|
|
|
{
|
2015-04-24 08:01:24 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE);
|
|
|
|
return !elua_util_error_report(es, elua_io_loadfile(es, fname)
|
|
|
|
|| _elua_docall(es, 0, 1));
|
2015-04-10 08:36:26 -07:00
|
|
|
}
|
|
|
|
|
2015-04-24 08:01:24 -07:00
|
|
|
EAPI Eina_Bool
|
2015-04-10 08:36:26 -07:00
|
|
|
elua_util_string_run(Elua_State *es, const char *chunk, const char *chname)
|
|
|
|
{
|
2015-04-24 08:01:24 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE);
|
|
|
|
return !elua_util_error_report(es, luaL_loadbuffer(es->luastate, chunk,
|
|
|
|
strlen(chunk), chname)
|
|
|
|
|| _elua_docall(es, 0, 0));
|
2015-04-10 08:36:26 -07:00
|
|
|
}
|
|
|
|
|
2015-04-27 03:30:33 -07:00
|
|
|
EAPI int
|
2015-04-10 08:36:26 -07:00
|
|
|
elua_util_app_load(Elua_State *es, const char *appname)
|
|
|
|
{
|
2015-04-27 03:30:33 -07:00
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, -1);
|
|
|
|
EINA_SAFETY_ON_FALSE_RETURN_VAL(elua_state_appload_ref_push(es), -1);
|
2015-04-10 08:36:26 -07:00
|
|
|
lua_pushstring(es->luastate, appname);
|
|
|
|
lua_call(es->luastate, 1, 2);
|
|
|
|
if (lua_isnil(es->luastate, -2))
|
|
|
|
{
|
|
|
|
lua_remove(es->luastate, -2);
|
2015-04-27 03:30:33 -07:00
|
|
|
return 1;
|
2015-04-10 08:36:26 -07:00
|
|
|
}
|
|
|
|
lua_pop(es->luastate, 1);
|
2015-04-27 03:30:33 -07:00
|
|
|
return 0;
|
2015-04-10 08:36:26 -07:00
|
|
|
}
|
|
|
|
|
2015-04-24 08:01:24 -07:00
|
|
|
EAPI Eina_Bool
|
2015-04-10 08:36:26 -07:00
|
|
|
elua_util_script_run(Elua_State *es, int argc, char **argv, int n, int *quit)
|
|
|
|
{
|
|
|
|
int status, narg;
|
|
|
|
const char *fname;
|
|
|
|
EINA_SAFETY_ON_FALSE_RETURN_VAL(n < argc, -1);
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(es, -1);
|
|
|
|
fname = argv[n];
|
|
|
|
narg = _elua_getargs(es, argc, argv, n);
|
|
|
|
lua_setglobal(es->luastate, "arg");
|
|
|
|
if (fname[0] == '-' && !fname[1]) fname = NULL;
|
|
|
|
if (fname)
|
|
|
|
{
|
|
|
|
/* check if there is a file of that name */
|
2015-12-03 00:32:39 -08:00
|
|
|
FILE *f = fopen(fname, "rb");
|
2015-04-10 08:36:26 -07:00
|
|
|
if (f)
|
|
|
|
{
|
|
|
|
fclose(f);
|
|
|
|
status = elua_io_loadfile(es, fname);
|
|
|
|
}
|
|
|
|
else
|
2015-04-27 03:30:33 -07:00
|
|
|
status = elua_util_app_load(es, fname);
|
2015-04-10 08:36:26 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
status = elua_io_loadfile(es, fname);
|
|
|
|
lua_insert(es->luastate, -(narg + 1));
|
|
|
|
if (!status)
|
|
|
|
status = _elua_docall(es, narg, 1);
|
|
|
|
else
|
|
|
|
lua_pop(es->luastate, narg);
|
|
|
|
if (!status)
|
|
|
|
{
|
|
|
|
*quit = lua_toboolean(es->luastate, -1);
|
|
|
|
lua_pop(es->luastate, 1);
|
|
|
|
}
|
2015-04-24 08:01:24 -07:00
|
|
|
return !elua_util_error_report(es, status);
|
2015-04-14 08:14:51 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_elua_errmsg(const char *pname, const char *msg)
|
|
|
|
{
|
|
|
|
ERR("%s%s%s", pname ? pname : "", pname ? ": " : "", msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
EAPI int
|
2015-04-20 09:04:33 -07:00
|
|
|
elua_util_error_report(const Elua_State *es, int status)
|
2015-04-14 08:14:51 -07:00
|
|
|
{
|
2015-04-27 03:34:29 -07:00
|
|
|
EINA_SAFETY_ON_FALSE_RETURN_VAL(es, status);
|
2015-04-14 08:14:51 -07:00
|
|
|
if (status && !lua_isnil(es->luastate, -1))
|
|
|
|
{
|
|
|
|
const char *msg = lua_tostring(es->luastate, -1);
|
2015-04-20 09:04:33 -07:00
|
|
|
_elua_errmsg(es->progname, msg ? msg : "(non-string error)");
|
2015-04-14 08:14:51 -07:00
|
|
|
lua_pop(es->luastate, 1);
|
|
|
|
}
|
|
|
|
return status;
|
2015-04-10 08:36:26 -07:00
|
|
|
}
|