[vlc-commits] cli: store commands in a search tree

Rémi Denis-Courmont git at videolan.org
Sat Oct 17 20:36:07 CEST 2020


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Oct 17 19:11:03 2020 +0300| [bfbe4b68bb16b3b4df4bfafd0b75740b430499a4] | committer: Rémi Denis-Courmont

cli: store commands in a search tree

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

 modules/control/cli/cli.c | 55 +++++++++++++++++++++++++++++++++++++----------
 modules/control/cli/cli.h | 10 +++++++++
 2 files changed, 54 insertions(+), 11 deletions(-)

diff --git a/modules/control/cli/cli.c b/modules/control/cli/cli.c
index 8086db514c..0538b9a410 100644
--- a/modules/control/cli/cli.c
+++ b/modules/control/cli/cli.c
@@ -37,6 +37,9 @@
 #ifdef HAVE_WORDEXP_H
 #include <wordexp.h>
 #endif
+#ifdef HAVE_SEARCH_H
+#include <search.h>
+#endif
 
 #define VLC_MODULE_LICENSE VLC_LICENSE_GPL_2_PLUS
 #include <vlc_common.h>
@@ -87,6 +90,33 @@ void msg_print(intf_thread_t *p_intf, const char *psz_fmt, ...)
     free( msg );
 }
 
+static int cmdcmp(const void *a, const void *b)
+{
+    const char *const *na = a;
+    const char *const *nb = b;
+
+    return strcmp(*na, *nb);
+}
+
+void RegisterHandlers(intf_thread_t *intf, const struct cli_handler *handlers,
+                      size_t count)
+{
+    intf_sys_t *sys = intf->p_sys;
+
+    for (size_t i = 0; i < count; i++)
+    {
+        const char *const *name = &handlers[i].name;
+        const char *const **pp;
+
+        pp = tsearch(name, &sys->commands, cmdcmp);
+
+        if (unlikely(pp == NULL))
+            continue;
+
+        assert(*pp == name); /* Fails if duplicate command */
+    }
+}
+
 #if defined (_WIN32) && !VLC_WINSTORE_APP
 # include "../intromsg.h"
 #endif
@@ -186,11 +216,7 @@ static void KeyAction(intf_thread_t *intf, const char *const *args, size_t n)
         var_SetInteger(vlc, "key-action", vlc_actions_get_id(args[1]));
 }
 
-static const struct
-{
-    const char *name;
-    void (*handler)(intf_thread_t *, const char *const *, size_t);
-} cmds[] =
+static const struct cli_handler cmds[] =
 {
     { "playlist", PlaylistList },
     { "sort", PlaylistSort },
@@ -273,6 +299,7 @@ static void UnknownCmd(intf_thread_t *intf, const char *const *args,
 
 static void Process(intf_thread_t *intf, const char *line)
 {
+    intf_sys_t *sys = intf->p_sys;
     /* Skip heading spaces */
     const char *cmd = line + strspn(line, " ");
 
@@ -318,13 +345,10 @@ error:      wordfree(&we);
     if (count > 0)
     {
         void (*cb)(intf_thread_t *, const char *const *, size_t) = UnknownCmd;
+        const struct cli_handler **h = tfind(&args[0], &sys->commands, cmdcmp);
 
-        for (size_t i = 0; i < ARRAY_SIZE(cmds); i++)
-            if (strcmp(args[0], cmds[i].name) == 0)
-            {
-                cb = cmds[i].handler;
-                break;
-            }
+        if (h != NULL)
+            cb = (*h)->callback;
 
         cb(intf, args, count);
     }
@@ -703,6 +727,7 @@ static int Activate( vlc_object_t *p_this )
     }
 
     p_intf->p_sys = p_sys;
+    p_sys->commands = NULL;
     p_sys->pi_socket_listen = pi_socket;
     p_sys->i_socket = -1;
 #ifdef AF_LOCAL
@@ -710,6 +735,8 @@ static int Activate( vlc_object_t *p_this )
 #endif
     p_sys->playlist = vlc_intf_GetMainPlaylist(p_intf);;
 
+    RegisterHandlers(p_intf, cmds, ARRAY_SIZE(cmds));
+
     /* Non-buffered stdout */
     setvbuf( stdout, (char *)NULL, _IOLBF, 0 );
 
@@ -739,6 +766,11 @@ error:
     return VLC_EGENERIC;
 }
 
+static void dummy_free(void *p)
+{
+    (void) p;
+}
+
 /*****************************************************************************
  * Deactivate: uninitialize and cleanup
  *****************************************************************************/
@@ -751,6 +783,7 @@ static void Deactivate( vlc_object_t *p_this )
     vlc_join( p_sys->thread, NULL );
 
     DeregisterPlayer(p_intf, p_sys->player_cli);
+    tdestroy(p_sys->commands, dummy_free);
 
     net_ListenClose( p_sys->pi_socket_listen );
     if( p_sys->i_socket != -1 )
diff --git a/modules/control/cli/cli.h b/modules/control/cli/cli.h
index 8891a9e57c..972f6efa96 100644
--- a/modules/control/cli/cli.h
+++ b/modules/control/cli/cli.h
@@ -27,6 +27,7 @@
 struct intf_sys_t
 {
     vlc_thread_t thread;
+    void *commands;
     void *player_cli;
 
     /* playlist */
@@ -48,6 +49,15 @@ void msg_print(intf_thread_t *p_intf, const char *psz_fmt, ...);
 #define msg_rc(...) msg_print(p_intf, __VA_ARGS__)
 #define STATUS_CHANGE "status change: "
 
+struct cli_handler
+{
+    const char *name;
+    void (*callback)(intf_thread_t *intf, const char *const *, size_t);
+};
+
+void RegisterHandlers(intf_thread_t *intf, const struct cli_handler *handlers,
+                      size_t count);
+
 void PlayerPause(intf_thread_t *intf, const char *const *, size_t);
 void PlayerFastForward(intf_thread_t *intf, const char *const *, size_t);
 void PlayerRewind(intf_thread_t *intf, const char *const *, size_t);



More information about the vlc-commits mailing list