[vlc-commits] lua: revector input item generation

Rémi Denis-Courmont git at videolan.org
Tue Apr 18 22:43:18 CEST 2017


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Apr 18 23:13:33 2017 +0300| [6030a44d47e2a4d9daed4ac85d8852c594e9b026] | committer: Rémi Denis-Courmont

lua: revector input item generation

This splits vlclua_playlist_add_internal() in two functions. The new
function parses a single input item from a Lua script.

This also adds handling for a few error cases.

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

 modules/lua/vlc.c | 268 +++++++++++++++++++++++++++---------------------------
 modules/lua/vlc.h |   2 +
 2 files changed, 136 insertions(+), 134 deletions(-)

diff --git a/modules/lua/vlc.c b/modules/lua/vlc.c
index 0270a4bd73..db3bb4afa6 100644
--- a/modules/lua/vlc.c
+++ b/modules/lua/vlc.c
@@ -463,158 +463,158 @@ void vlclua_read_options( vlc_object_t *p_this, lua_State *L,
     lua_pop( L, 1 ); /* pop "options" */
 }
 
+input_item_t *vlclua_read_input_item(vlc_object_t *obj, lua_State *L)
+{
+    if (!lua_istable(L, -1))
+    {
+        msg_Warn(obj, "Playlist item should be a table" );
+        return NULL;
+    }
+
+    lua_getfield(L, -1, "path");
+
+    /* playlist key item path */
+    if (!lua_isstring(L, -1))
+    {
+        lua_pop(L, 1); /* pop "path" */
+        msg_Warn(obj, "Playlist item's path should be a string");
+        return NULL;
+    }
+
+    /* Read path and name */
+    const char *path = lua_tostring(L, -1);
+    msg_Dbg(obj, "Path: %s", path);
+
+    const char *name = NULL;
+    lua_getfield(L, -2, "name");
+    if (lua_isstring(L, -1))
+    {
+        name = lua_tostring(L, -1);
+        msg_Dbg(obj, "Name: %s", name);
+    }
+    else if (!lua_isnil(L, -1))
+        msg_Warn(obj, "Playlist item name should be a string" );
+
+    /* Read duration */
+    mtime_t duration = -1;
+
+    lua_getfield( L, -3, "duration" );
+    if (lua_isnumber(L, -1))
+        duration = (mtime_t)(lua_tonumber(L, -1) * (CLOCK_FREQ * 1.));
+    else if (!lua_isnil(L, -1))
+        msg_Warn(obj, "Playlist item duration should be a number (seconds)");
+    lua_pop( L, 1 ); /* pop "duration" */
+
+    /* Read options: item must be on top of stack */
+    char **optv = NULL;
+    int optc = 0;
+
+    lua_pushvalue(L, -3);
+    vlclua_read_options(obj, L, &optc, &optv);
+
+    /* Create input item */
+    input_item_t *item = input_item_NewExt(path, name, duration,
+                                           ITEM_TYPE_UNKNOWN,
+                                           ITEM_NET_UNKNOWN);
+    if (unlikely(item == NULL))
+        goto out;
+
+    input_item_AddOptions(item, optc, (const char **)optv,
+                          VLC_INPUT_OPTION_TRUSTED);
+    lua_pop(L, 3); /* pop "path name item" */
+    /* playlist key item */
+
+    /* Read meta data: item must be on top of stack */
+    vlclua_read_meta_data(obj, L, item);
+
+    /* copy the psz_name to the meta data, if "Title" is still empty */
+    char* title = input_item_GetTitle(item);
+    if (title == NULL)
+        input_item_SetTitle(item, name);
+    free(title);
+
+    /* Read custom meta data: item must be on top of stack*/
+    vlclua_read_custom_meta_data(obj, L, item);
+
+out:
+    while (optc > 0)
+           free(optv[--optc]);
+    free(optv);
+    return item;
+}
+
 #undef vlclua_playlist_add_internal
-int vlclua_playlist_add_internal( vlc_object_t *p_this, lua_State *L,
-                                    playlist_t *p_playlist,
-                                    input_item_t *p_parent, bool b_play )
+int vlclua_playlist_add_internal(vlc_object_t *obj, lua_State *L,
+                                 playlist_t *playlist, input_item_t *parent,
+                                 bool play)
 {
-    int i_count = 0;
-    input_item_node_t *p_parent_node = NULL;
+    int count = 0;
 
-    assert( p_parent || p_playlist );
+    assert(parent != NULL || playlist != NULL);
 
     /* playlist */
-    if( lua_istable( L, -1 ) )
+    if (!lua_istable(L, -1))
     {
-        if( p_parent ) p_parent_node = input_item_node_Create( p_parent );
-        lua_pushnil( L );
-        /* playlist nil */
-        while( lua_next( L, -2 ) )
-        {
-            /* playlist key item */
-            /* <Parse playlist item> */
-            if( lua_istable( L, -1 ) )
-            {
-                lua_getfield( L, -1, "path" );
-                /* playlist key item path */
-                if( lua_isstring( L, -1 ) )
-                {
-                    char         *psz_oldurl   = NULL;
-                    const char   *psz_path     = NULL;
-                    const char   *psz_name     = NULL;
-                    char        **ppsz_options = NULL;
-                    int           i_options    = 0;
-                    mtime_t       i_duration   = -1;
-                    input_item_t *p_input;
-
-                    /* Read path and name */
-                    if (p_parent) {
-                        psz_oldurl = input_item_GetURI( p_parent );
-                        msg_Dbg( p_this, "old path: %s", psz_oldurl );
-                    }
-                    psz_path = lua_tostring( L, -1 );
-                    msg_Dbg( p_this, "Path: %s", psz_path );
-                    lua_getfield( L, -2, "name" );
-                    /* playlist key item path name */
-                    if( lua_isstring( L, -1 ) )
-                    {
-                        psz_name = lua_tostring( L, -1 );
-                        msg_Dbg( p_this, "Name: %s", psz_name );
-                    }
-                    else
-                    {
-                        if( !lua_isnil( L, -1 ) )
-                            msg_Warn( p_this, "Playlist item name should be a string." );
-                    }
+        msg_Warn(obj, "Playlist should be a table.");
+        return 0;
+    }
 
-                    /* Read duration */
-                    lua_getfield( L, -3, "duration" );
-                    /* playlist key item path name duration */
-                    if( lua_isnumber( L, -1 ) )
-                    {
-                        i_duration = (mtime_t)(lua_tonumber( L, -1 )*1e6);
-                    }
-                    else if( !lua_isnil( L, -1 ) )
-                    {
-                        msg_Warn( p_this, "Playlist item duration should be a number (in seconds)." );
-                    }
-                    lua_pop( L, 1 ); /* pop "duration" */
-
-                    /* playlist key item path name */
-
-                    /* Read options: item must be on top of stack */
-                    lua_pushvalue( L, -3 );
-                    /* playlist key item path name item */
-                    vlclua_read_options( p_this, L, &i_options, &ppsz_options );
-
-                    /* Create input item */
-                    p_input = input_item_NewExt( psz_path, psz_name, i_duration,
-                                                 ITEM_TYPE_UNKNOWN, ITEM_NET_UNKNOWN );
-                    input_item_AddOptions( p_input, i_options,
-                                           (const char **)ppsz_options,
-                                           VLC_INPUT_OPTION_TRUSTED );
-                    lua_pop( L, 3 ); /* pop "path name item" */
-                    /* playlist key item */
-
-                    /* Read meta data: item must be on top of stack */
-                    vlclua_read_meta_data( p_this, L, p_input );
-
-                    /* copy the original URL to the meta data, if "URL" is still empty */
-                    char* url = input_item_GetURL( p_input );
-                    if( url == NULL && p_parent)
-                    {
-                        EnsureUTF8( psz_oldurl );
-                        msg_Dbg( p_this, "meta-URL: %s", psz_oldurl );
-                        input_item_SetURL ( p_input, psz_oldurl );
-                    }
-                    free( psz_oldurl );
-                    free( url );
+    input_item_node_t *node = NULL;
 
-                    /* copy the psz_name to the meta data, if "Title" is still empty */
-                    char* title = input_item_GetTitle( p_input );
-                    if( title == NULL )
-                        input_item_SetTitle ( p_input, psz_name );
-                    free( title );
+    if (parent != NULL)
+        node = input_item_node_Create(parent);
 
-                    /* Read custom meta data: item must be on top of stack*/
-                    vlclua_read_custom_meta_data( p_this, L, p_input );
+    lua_pushnil(L);
 
-                    /* Append item to playlist */
-                    if( p_parent ) /* Add to node */
+    /* playlist nil */
+    while (lua_next(L, -2))
+    {
+        input_item_t *item = vlclua_read_input_item(obj, L);
+        if (item != NULL)
+        {
+            /* Append item to playlist */
+            if (node != NULL) /* Add to node */
+            {
+                /* copy the original URL to the meta data,
+                 * if "URL" is still empty */
+                char *url = input_item_GetURL(item);
+                if (url == NULL)
+                {
+                    url = input_item_GetURI(parent);
+                    if (likely(url != NULL))
                     {
-                        input_item_CopyOptions( p_input, p_parent );
-                        input_item_node_AppendItem( p_parent_node, p_input );
+                        EnsureUTF8(url);
+                        msg_Dbg(obj, "meta-URL: %s", url);
+                        input_item_SetURL(item, url);
                     }
-                    else /* Play or Enqueue (preparse) */
-                        /* FIXME: playlist_AddInput() can fail */
-                        playlist_AddInput( p_playlist, p_input,
-                                           ( b_play ? PLAYLIST_GO : 0 ),
-                                           true );
-                    i_count ++; /* increment counter */
-                    input_item_Release( p_input );
-                    while( i_options > 0 )
-                        free( ppsz_options[--i_options] );
-                    free( ppsz_options );
                 }
-                else
-                {
-                    lua_pop( L, 1 ); /* pop "path" */
-                    msg_Warn( p_this,
-                             "Playlist item's path should be a string" );
-                }
-                /* playlist key item */
-            }
-            else
-            {
-                msg_Warn( p_this, "Playlist item should be a table" );
+                free(url);
+
+                input_item_CopyOptions(item, parent);
+                input_item_node_AppendItem(node, item);
             }
-            /* <Parse playlist item> */
-            lua_pop( L, 1 ); /* pop the value, keep the key for
-                              * the next lua_next() call */
-            /* playlist key */
-        }
-        /* playlist */
-        if( p_parent )
-        {
-            if( i_count ) input_item_node_PostAndDelete( p_parent_node );
-            else input_item_node_Delete( p_parent_node );
+            else if (likely(parent == NULL))
+            /* Play or Enqueue (preparse) */
+                /* FIXME: playlist_AddInput() can fail */
+                playlist_AddInput(playlist, item, play ? PLAYLIST_GO : 0,
+                                  true);
+
+            input_item_Release(item);
+            count++;
         }
+        /* pop the value, keep the key for the next lua_next() call */
+        lua_pop(L, 1);
     }
-    else
+    /* playlist */
+
+    if (node != NULL)
     {
-        msg_Warn( p_this, "Playlist should be a table." );
+        if (count > 0)
+            input_item_node_PostAndDelete(node);
+        else
+            input_item_node_Delete(node);
     }
-    return i_count;
+    return count;
 }
 
 static int vlc_sd_probe_Open( vlc_object_t *obj )
diff --git a/modules/lua/vlc.h b/modules/lua/vlc.h
index f79d9c6c1d..972b35f1da 100644
--- a/modules/lua/vlc.h
+++ b/modules/lua/vlc.h
@@ -180,6 +180,8 @@ void vlclua_read_meta_data( vlc_object_t *, lua_State *, input_item_t * );
 void vlclua_read_custom_meta_data( vlc_object_t *, lua_State *,
                                    input_item_t *);
 #define vlclua_read_custom_meta_data( a, b, c ) vlclua_read_custom_meta_data( VLC_OBJECT( a ), b, c )
+
+input_item_t *vlclua_read_input_item(vlc_object_t *, lua_State *);
 int vlclua_playlist_add_internal( vlc_object_t *, lua_State *, playlist_t *,
                                   input_item_t *, bool );
 #define vlclua_playlist_add_internal( a, b, c, d, e ) vlclua_playlist_add_internal( VLC_OBJECT( a ), b, c, d, e )



More information about the vlc-commits mailing list