elua lib: merge the 3 setup funcs into one
authorDaniel Kolesa <d.kolesa@osg.samsung.com>
Thu, 23 Apr 2015 15:02:58 +0000 (16:02 +0100)
committerDaniel Kolesa <d.kolesa@osg.samsung.com>
Wed, 6 May 2015 14:05:23 +0000 (15:05 +0100)
This allows simpler initialization and elua_util_require
can now queue up modules before full initialization is done.

src/bin/elua/main.c
src/lib/elua/Elua.h
src/lib/elua/cache.c
src/lib/elua/elua.c
src/lib/elua/elua_private.h

index c24951c64cff639dc1215506c0e01f18292f4114..6b55120067b1732771cd8fa46a3e5c3bb35679f4 100644 (file)
@@ -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;
 }
 
index 3a172515c5882dffa0e53a9bdd66aaf0f2e7cc9a..93814a359dac66fc66adc90732fffe058ed4fc14 100644 (file)
@@ -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.
index 43ef3d7d19bfb0adad33f35ff60c9ebca7a783be..b856b0bde9b7ce1b2617881d43d0a170e1e1c581 100644 (file)
@@ -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);
index 234674dfd97ec4efc36291187be7bf11fca97346..9ad15d17f0d8d872c8ee61bf48fad8b36ba05c5c 100644 (file)
@@ -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));
 }
index cf24e1e661ce37fe63e7593790a6c36077f04c5f..53b514e6276dcc9b0301913c827c05382fb30dbf 100644 (file)
@@ -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