[vlc-commits] Lua: load extensions in .vle files (Zip archives)

Jean-Philippe André git at videolan.org
Sat Jan 22 00:56:48 CET 2011


vlc | branch: master | Jean-Philippe André <jpeg at videolan.org> | Wed Jan 19 18:08:48 2011 +0100| [3aa82557e68f1c8f1a18357ca3ca5649ef39cb94] | committer: Jean-Philippe André

Lua: load extensions in .vle files (Zip archives)

Main script's name must be "script.lua"
Modules are not supported yet

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=3aa82557e68f1c8f1a18357ca3ca5649ef39cb94
---

 modules/misc/lua/extension.c |   33 +++++++++++++++++++++++++++------
 modules/misc/lua/vlc.c       |   32 +++++++++++++++++++++++++++++++-
 modules/misc/lua/vlc.h       |    5 +++++
 3 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/modules/misc/lua/extension.c b/modules/misc/lua/extension.c
index c50a76d..951eedb 100644
--- a/modules/misc/lua/extension.c
+++ b/modules/misc/lua/extension.c
@@ -217,31 +217,52 @@ static int ScanExtensions( extensions_manager_t *p_mgr )
 static int vlclua_dummy_require( lua_State *L )
 {
     (void) L;
+    // const char *psz_module = luaL_checkstring( L, 1 );
     return 0;
 }
 
 /**
  * Batch scan all Lua files in folder "extensions": callback
  * @param p_this This extensions_manager_t object
- * @param psz_script Name of the script to run
+ * @param psz_filename Name of the script to run
  * @param L Lua State, common to all scripts here
  * @param dummy: unused
  **/
-int ScanLuaCallback( vlc_object_t *p_this, const char *psz_script,
+int ScanLuaCallback( vlc_object_t *p_this, const char *psz_filename,
                      void *dummy )
 {
     VLC_UNUSED(dummy);
     extensions_manager_t *p_mgr = ( extensions_manager_t* ) p_this;
     bool b_ok = false;
 
-    msg_Dbg( p_mgr, "Scanning Lua script %s", psz_script );
+    msg_Dbg( p_mgr, "Scanning Lua script %s", psz_filename );
+
+    /* Experimental: read .vle packages (Zip archives) */
+    char *psz_script = NULL;
+    int i_flen = strlen( psz_filename );
+    if( !strncasecmp( psz_filename + i_flen - 4, ".vle", 4 ) )
+    {
+        msg_Dbg( p_this, "reading Lua script in a zip archive" );
+        psz_script = calloc( 1, i_flen + 6 + 2 + 10 + 1 );
+        if( !psz_script )
+            return 0;
+        strcpy( psz_script, "zip://" );
+        strncat( psz_script, psz_filename, i_flen + 19 );
+        strncat( psz_script, "!/script.lua", i_flen + 19 );
+    }
+    else
+    {
+        psz_script = strdup( psz_filename );
+        if( !psz_script )
+            return 0;
+    }
 
     /* Create new script descriptor */
     extension_t *p_ext = ( extension_t* ) calloc( 1, sizeof( extension_t ) );
     if( !p_ext )
         return 0;
 
-    p_ext->psz_name = strdup( psz_script );
+    p_ext->psz_name = psz_script;
     p_ext->p_sys = (extension_sys_t*) calloc( 1, sizeof( extension_sys_t ) );
     if( !p_ext->p_sys || !p_ext->psz_name )
     {
@@ -271,7 +292,7 @@ int ScanLuaCallback( vlc_object_t *p_this, const char *psz_script,
     lua_register( L, "require", &vlclua_dummy_require );
 
     /* Let's run it */
-    if( luaL_dofile( L, psz_script ) )
+    if( vlclua_dofile( p_this, L, psz_script ) ) // luaL_dofile
     {
         msg_Warn( p_mgr, "Error loading script %s: %s", psz_script,
                   lua_tostring( L, lua_gettop( L ) ) );
@@ -778,7 +799,7 @@ static lua_State* GetLuaState( extensions_manager_t *p_mgr,
             }
 
             /* Load and run the script(s) */
-            if( luaL_dofile( L, p_ext->psz_name ) != 0 )
+            if( vlclua_dofile( p_mgr, L, p_ext->psz_name ) ) // luaL_dofile
             {
                 msg_Warn( p_mgr, "Error loading script %s: %s", p_ext->psz_name,
                           lua_tostring( L, lua_gettop( L ) ) );
diff --git a/modules/misc/lua/vlc.c b/modules/misc/lua/vlc.c
index 43f19d4..871dcb8 100644
--- a/modules/misc/lua/vlc.c
+++ b/modules/misc/lua/vlc.c
@@ -42,6 +42,7 @@
 #include <vlc_fs.h>
 #include <vlc_aout.h>
 #include <vlc_services_discovery.h>
+#include <vlc_stream.h>
 #include <sys/stat.h>
 
 #include <lua.h>        /* Low level lua C API */
@@ -188,7 +189,7 @@ vlc_module_end ()
 /*****************************************************************************
  *
  *****************************************************************************/
-static const char *ppsz_lua_exts[] = { ".luac", ".lua", NULL };
+static const char *ppsz_lua_exts[] = { ".luac", ".lua", ".vle", NULL };
 static int file_select( const char *file )
 {
     int i = strlen( file );
@@ -839,3 +840,32 @@ int __vlclua_add_modules_path( vlc_object_t *obj, lua_State *L, const char *psz_
     return 0;
 }
 
+/** Replacement for luaL_dofile, using VLC's input capabilities */
+int vlclua_dofile( vlc_object_t *p_this, lua_State *L, const char *uri )
+{
+    if( !strstr( uri, "://" ) )
+        return luaL_dofile( L, uri );
+    if( !strncasecmp( uri, "file://", 7 ) )
+        return luaL_dofile( L, uri + 7 );
+    stream_t *s = stream_UrlNew( p_this, uri );
+    if( !s )
+        return 1;
+    int64_t i_size = stream_Size( s );
+    char *p_buffer = ( i_size > 0 ) ? malloc( i_size ) : NULL;
+    if( !p_buffer )
+    {
+        // FIXME: read the whole stream until we reach the end (if no size)
+        stream_Delete( s );
+        return 1;
+    }
+    int64_t i_read = stream_Read( s, p_buffer, (int) i_size );
+    int i_ret = ( i_read == i_size ) ? 0 : 1;
+    if( !i_ret )
+        i_ret = luaL_loadbuffer( L, p_buffer, (size_t) i_size, uri );
+    if( !i_ret )
+        i_ret = lua_pcall( L, 0, LUA_MULTRET, 0 );
+    stream_Delete( s );
+    free( p_buffer );
+    return i_ret;
+}
+
diff --git a/modules/misc/lua/vlc.h b/modules/misc/lua/vlc.h
index d3187e7..4e1ee04 100644
--- a/modules/misc/lua/vlc.h
+++ b/modules/misc/lua/vlc.h
@@ -123,6 +123,11 @@ void vlclua_dir_list_free( char **ppsz_dir_list );
 char *vlclua_find_file( vlc_object_t *p_this, const char *psz_luadirname, const char *psz_name );
 
 /*****************************************************************************
+ * Replace Lua file reader by VLC input. Allows loadings scripts in Zip pkg.
+ *****************************************************************************/
+int vlclua_dofile( vlc_object_t *p_this, lua_State *L, const char *url );
+
+/*****************************************************************************
  * Playlist and meta data internal utilities.
  *****************************************************************************/
 void __vlclua_read_options( vlc_object_t *, lua_State *, int *, char *** );



More information about the vlc-commits mailing list