[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