diff --git a/src/bin/elua/main.c b/src/bin/elua/main.c index c24951c64c..6b55120067 100644 --- a/src/bin/elua/main.c +++ b/src/bin/elua/main.c @@ -54,9 +54,7 @@ static int elua_main(lua_State *L) { Eina_Bool noenv = EINA_FALSE; - Eina_List *largs = NULL; const char *coredir = NULL, *moddir = NULL, *appsdir = NULL; - char *data = NULL; struct Main_Data *m = (struct Main_Data*)lua_touserdata(L, 1); Elua_State *es = m->es; @@ -70,7 +68,7 @@ elua_main(lua_State *L) switch (ch) { case 'h': - elua_print_help(elua_state_prog_name_get(es), stdout); goto success; + elua_print_help(elua_state_prog_name_get(es), stdout); return 0; case 'C': coredir = optarg; break; case 'M': @@ -81,7 +79,7 @@ elua_main(lua_State *L) case 'I': if (!optarg[0]) continue; if (ch == 'l') - largs = eina_list_append(largs, optarg); + elua_util_require(es, optarg); else elua_state_include_path_add(es, optarg); break; @@ -96,39 +94,36 @@ elua_main(lua_State *L) elua_state_dirs_set(es, coredir, moddir, appsdir); elua_state_dirs_fill(es, noenv); - if (!elua_state_modules_setup(es) || !elua_state_i18n_setup(es) - || !elua_state_io_setup(es)) - goto error; + if (!elua_state_setup(es)) + { + m->status = 1; + return 0; + } lua_gc(L, LUA_GCRESTART, 0); INF("elua lua state initialized"); - EINA_LIST_FREE(largs, data) - if (elua_util_require(es, data)) goto error; - if (optind < argc) { int quit = 0; if (elua_util_script_run(es, argc, argv, optind, &quit)) - goto error; + { + m->status = 1; + return 0; + } if (quit) - goto success; + return 0; } else { ERR("nothing to run"); - goto error; + m->status = 1; + return 0; } ecore_main_loop_begin(); - goto success; - -error: - m->status = 1; -success: - if (largs) eina_list_free(largs); return 0; } diff --git a/src/lib/elua/Elua.h b/src/lib/elua/Elua.h index 3a172515c5..93814a359d 100644 --- a/src/lib/elua/Elua.h +++ b/src/lib/elua/Elua.h @@ -307,45 +307,29 @@ EAPI Eina_Bool elua_state_appload_ref_push(Elua_State *es); EAPI lua_State *elua_state_lua_state_get(const Elua_State *es); /** - * @brief Set up internationalization support for an Elua state. + * @brief Set up the Elua state. + * + * This API function sets up 3 things, module system, i18n and I/O. After that + * it requires all modules not yet required (i.e. those queued in before the + * state was fully initialized). * * This function sets up correct i18n for an Elua state. That means loading * the gettext bindings and making Lua aware of them. This also works when * i18n support is disabled at compilation time, so you can just call it * unconditionally. * - * @param[in] es The Elua state. - * @return EINA_TRUE on success, EINA_FALSE on failure. - * - * @ingroup Elua - */ -EAPI Eina_Bool elua_state_i18n_setup(const Elua_State *es); - -/** - * @brief Set up module support for an Elua state. - * - * This loads the Elua module system and makes Lua aware of it. It also + * This also loads the Elua module system and makes Lua aware of it. It also * registers the Elua C utility library module. * - * @param[in] es The Elua state. - * @return EINA_TRUE on success, EINA_FALSE on failure. - * - * @ingroup Elua - */ -EAPI Eina_Bool elua_state_modules_setup(const Elua_State *es); - -/** - * @brief Set up IO support for an Elua state. - * - * Elua provides its own loadfile based around mmap to replace the less - * efficient Lua version. This function takes care of the setup. + * Finally, Elua provides its own loadfile based around mmap to replace the + * less efficient Lua version. This function takes care of the setup. * * @param[in] es The Elua state. * @return EINA_TRUE on success, EINA_FALSE on failure. * * @ingroup Elua */ -EAPI Eina_Bool elua_state_io_setup(const Elua_State *es); +EAPI Eina_Bool elua_state_setup(Elua_State *es); /** * @brief Loads a file using Elua's own mmap-based IO. diff --git a/src/lib/elua/cache.c b/src/lib/elua/cache.c index 43ef3d7d19..b856b0bde9 100644 --- a/src/lib/elua/cache.c +++ b/src/lib/elua/cache.c @@ -208,8 +208,8 @@ loadfile(lua_State *L) return 2; } -EAPI Eina_Bool -elua_state_io_setup(const Elua_State *es) +Eina_Bool +_elua_state_io_setup(const Elua_State *es) { EINA_SAFETY_ON_FALSE_RETURN_VAL(es && es->luastate, EINA_FALSE); lua_pushcfunction(es->luastate, loadfile); diff --git a/src/lib/elua/elua.c b/src/lib/elua/elua.c index 234674dfd9..9ad15d17f0 100644 --- a/src/lib/elua/elua.c +++ b/src/lib/elua/elua.c @@ -94,6 +94,8 @@ elua_state_free(Elua_State *es) } else if (es->cmods) eina_list_free(es->cmods); + EINA_LIST_FREE(es->lmods, data) + eina_stringshare_del(data); EINA_LIST_FREE(es->lincs, data) eina_stringshare_del(data); eina_stringshare_del(es->progname); @@ -264,8 +266,8 @@ const luaL_reg gettextlib[] = { NULL, NULL } }; -EAPI Eina_Bool -elua_state_i18n_setup(const Elua_State *es) +static Eina_Bool +_elua_state_i18n_setup(const Elua_State *es) { #ifdef ENABLE_NLS char *(*dgettextp)(const char*, const char*) = dgettext; @@ -302,8 +304,8 @@ const luaL_reg _elua_cutillib[] = { NULL , NULL } }; -EAPI Eina_Bool -elua_state_modules_setup(const Elua_State *es) +static Eina_Bool +_elua_state_modules_setup(const Elua_State *es) { char buf[PATH_MAX]; EINA_SAFETY_ON_NULL_RETURN_VAL(es, EINA_FALSE); @@ -370,6 +372,42 @@ _elua_module_system_init(lua_State *L) return 2; } +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; +} + /* Utility functions - these could be written using the other APIs */ static int @@ -435,7 +473,12 @@ elua_util_require(Elua_State *es, const char *libname) { EINA_SAFETY_ON_NULL_RETURN_VAL(es, -1); EINA_SAFETY_ON_NULL_RETURN_VAL(es->luastate, -1); - EINA_SAFETY_ON_FALSE_RETURN_VAL(elua_state_require_ref_push(es), -1); + 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; + } lua_pushstring(es->luastate, libname); return elua_util_error_report(es, lua_pcall(es->luastate, 1, 0, 0)); } diff --git a/src/lib/elua/elua_private.h b/src/lib/elua/elua_private.h index cf24e1e661..53b514e627 100644 --- a/src/lib/elua/elua_private.h +++ b/src/lib/elua/elua_private.h @@ -34,6 +34,7 @@ struct _Elua_State Eina_Stringshare *coredir; Eina_Stringshare *moddir; Eina_Stringshare *appsdir; + Eina_List *lmods; Eina_List *cmods; Eina_List *lincs; int requireref, apploadref; @@ -48,5 +49,6 @@ extern int _elua_log_dom; #define CRT(...) EINA_LOG_DOM_CRITICAL(_elua_log_dom, __VA_ARGS__) int _elua_io_popen(lua_State *L); +Eina_Bool _elua_state_io_setup(const Elua_State *es); #endif