From 56f8c953dd609bc5c94011fe4acdd9ef6b875747 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 19 Jun 2004 01:01:09 +0000 Subject: some more work on the cli git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@24 fefdeb5f-60dc-0310-8127-8f9354f1896f --- src/cli.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 204 insertions(+), 38 deletions(-) (limited to 'src/cli.c') diff --git a/src/cli.c b/src/cli.c index 4a198141..4f67f8b7 100644 --- a/src/cli.c +++ b/src/cli.c @@ -11,6 +11,8 @@ #include "client.h" #include "sinkinput.h" #include "sourceoutput.h" +#include "tokenizer.h" +#include "strbuf.h" struct cli { struct core *core; @@ -20,8 +22,46 @@ struct cli { void *userdata; }; +struct command { + const char *name; + void (*proc) (struct cli *cli, struct tokenizer*t); + const char *help; + unsigned args; +}; + static void line_callback(struct ioline *line, const char *s, void *userdata); +static void cli_command_exit(struct cli *c, struct tokenizer *t); +static void cli_command_help(struct cli *c, struct tokenizer *t); +static void cli_command_modules(struct cli *c, struct tokenizer *t); +static void cli_command_clients(struct cli *c, struct tokenizer *t); +static void cli_command_sinks(struct cli *c, struct tokenizer *t); +static void cli_command_sources(struct cli *c, struct tokenizer *t); +static void cli_command_sink_inputs(struct cli *c, struct tokenizer *t); +static void cli_command_source_outputs(struct cli *c, struct tokenizer *t); +static void cli_command_stat(struct cli *c, struct tokenizer *t); +static void cli_command_info(struct cli *c, struct tokenizer *t); +static void cli_command_load(struct cli *c, struct tokenizer *t); +static void cli_command_unload(struct cli *c, struct tokenizer *t); + +static const struct command commands[] = { + { "exit", cli_command_exit, "Terminate the daemon", 1 }, + { "help", cli_command_help, "Show this help", 1 }, + { "modules", cli_command_modules, "List loaded modules", 1 }, + { "sinks", cli_command_sinks, "List loaded sinks", 1 }, + { "sources", cli_command_sources, "List loaded sources", 1 }, + { "clients", cli_command_clients, "List loaded clients", 1 }, + { "sink_inputs", cli_command_sink_inputs, "List sink inputs", 1 }, + { "source_outputs", cli_command_source_outputs, "List source outputs", 1 }, + { "stat", cli_command_stat, "Show memory block statistics", 1 }, + { "info", cli_command_info, "Show comprehensive status", 1 }, + { "load", cli_command_load, "Load a module (given by name and arguments)", 3 }, + { "unload", cli_command_unload, "Unload a module (specified by index)", 2 }, + { NULL, NULL, NULL, 0 } +}; + +static const char prompt[] = ">>> "; + struct cli* cli_new(struct core *core, struct iochannel *io) { struct cli *c; assert(io); @@ -36,7 +76,8 @@ struct cli* cli_new(struct core *core, struct iochannel *io) { c->eof_callback = NULL; ioline_set_callback(c->line, line_callback, c); - ioline_puts(c->line, "Welcome to polypaudio! Use \"help\" for usage information.\n> "); + ioline_puts(c->line, "Welcome to polypaudio! Use \"help\" for usage information.\n"); + ioline_puts(c->line, prompt); return c; } @@ -49,7 +90,8 @@ void cli_free(struct cli *c) { static void line_callback(struct ioline *line, const char *s, void *userdata) { struct cli *c = userdata; - char *t = NULL; + const char *cs; + const char delimiter[] = " \t\n\r"; assert(line && c); if (!s) { @@ -60,42 +102,29 @@ static void line_callback(struct ioline *line, const char *s, void *userdata) { return; } - if (!strcmp(s, "modules")) - ioline_puts(line, (t = module_list_to_string(c->core))); - else if (!strcmp(s, "sources")) - ioline_puts(line, (t = source_list_to_string(c->core))); - else if (!strcmp(s, "sinks")) - ioline_puts(line, (t = sink_list_to_string(c->core))); - else if (!strcmp(s, "clients")) - ioline_puts(line, (t = client_list_to_string(c->core))); - else if (!strcmp(s, "source_outputs")) - ioline_puts(line, (t = source_output_list_to_string(c->core))); - else if (!strcmp(s, "sink_inputs")) - ioline_puts(line, (t = sink_input_list_to_string(c->core))); - else if (!strcmp(s, "stat")) { - char txt[256]; - snprintf(txt, sizeof(txt), "Memory blocks allocated: %u, total size: %u bytes.\n", memblock_count, memblock_total); - ioline_puts(line, txt); - } else if (!strcmp(s, "exit")) { - assert(c->core && c->core->mainloop); - mainloop_quit(c->core->mainloop, -1); - } else if (!strcmp(s, "help")) - ioline_puts(line, - "Available commands:\n" - " modules\t\tlist modules\n" - " sinks\t\tlist sinks\n" - " sources\t\tlist sources\n" - " clients\t\tlist clients\n" - " source_outputs\tlist source outputs\n" - " sink_inputs\t\tlist sink inputs\n" - " stat\t\tshow memblock statistics\n" - " exit\t\tterminate the daemon\n" - " help\t\tshow this help\n"); - else if (*s) - ioline_puts(line, "Unknown command\n"); - - free(t); - ioline_puts(line, "> "); + cs = s+strspn(s, delimiter); + if (*cs && *cs != '#') { + const struct command*command; + int unknown = 1; + size_t l; + + l = strcspn(s, delimiter); + + for (command = commands; command->name; command++) + if (!strncmp(s, command->name, l)) { + struct tokenizer *t = tokenizer_new(s, command->args); + assert(t); + command->proc(c, t); + tokenizer_free(t); + unknown = 0; + break; + } + + if (unknown) + ioline_puts(line, "Unknown command\n"); + } + + ioline_puts(c->line, prompt); } void cli_set_eof_callback(struct cli *c, void (*cb)(struct cli*c, void *userdata), void *userdata) { @@ -103,3 +132,140 @@ void cli_set_eof_callback(struct cli *c, void (*cb)(struct cli*c, void *userdata c->eof_callback = cb; c->userdata = userdata; } + +static void cli_command_exit(struct cli *c, struct tokenizer *t) { + assert(c && c->core && c->core->mainloop && t); + mainloop_quit(c->core->mainloop, -1); +} + +static void cli_command_help(struct cli *c, struct tokenizer *t) { + const struct command*command; + struct strbuf *strbuf; + char *p; + assert(c && t); + + strbuf = strbuf_new(); + assert(strbuf); + + strbuf_puts(strbuf, "Available commands:\n"); + + for (command = commands; command->name; command++) + strbuf_printf(strbuf, " %-20s %s\n", command->name, command->help); + + ioline_puts(c->line, p = strbuf_tostring_free(strbuf)); + free(p); +} + +static void cli_command_modules(struct cli *c, struct tokenizer *t) { + char *s; + assert(c && t); + s = module_list_to_string(c->core); + assert(s); + ioline_puts(c->line, s); + free(s); +} + +static void cli_command_clients(struct cli *c, struct tokenizer *t) { + char *s; + assert(c && t); + s = client_list_to_string(c->core); + assert(s); + ioline_puts(c->line, s); + free(s); +} + +static void cli_command_sinks(struct cli *c, struct tokenizer *t) { + char *s; + assert(c && t); + s = sink_list_to_string(c->core); + assert(s); + ioline_puts(c->line, s); + free(s); +} + +static void cli_command_sources(struct cli *c, struct tokenizer *t) { + char *s; + assert(c && t); + s = source_list_to_string(c->core); + assert(s); + ioline_puts(c->line, s); + free(s); +} + +static void cli_command_sink_inputs(struct cli *c, struct tokenizer *t) { + char *s; + assert(c && t); + s = sink_input_list_to_string(c->core); + assert(s); + ioline_puts(c->line, s); + free(s); +} + +static void cli_command_source_outputs(struct cli *c, struct tokenizer *t) { + char *s; + assert(c && t); + s = source_output_list_to_string(c->core); + assert(s); + ioline_puts(c->line, s); + free(s); +} + +static void cli_command_stat(struct cli *c, struct tokenizer *t) { + char txt[256]; + assert(c && t); + snprintf(txt, sizeof(txt), "Memory blocks allocated: %u, total size: %u bytes.\n", memblock_count, memblock_total); + ioline_puts(c->line, txt); +} + +static void cli_command_info(struct cli *c, struct tokenizer *t) { + assert(c && t); + cli_command_stat(c, t); + cli_command_modules(c, t); + cli_command_sources(c, t); + cli_command_sinks(c, t); + cli_command_clients(c, t); + cli_command_sink_inputs(c, t); + cli_command_source_outputs(c, t); +} + +static void cli_command_load(struct cli *c, struct tokenizer *t) { + struct module *m; + const char *name; + char txt[256]; + assert(c && t); + + if (!(name = tokenizer_get(t, 1))) { + ioline_puts(c->line, "You need to specfiy the module name and optionally arguments.\n"); + return; + } + + if (!(m = module_load(c->core, name, tokenizer_get(t, 2)))) { + ioline_puts(c->line, "Module load failed.\n"); + return; + } + + snprintf(txt, sizeof(txt), "Module successfully loaded, index: %u.\n", m->index); + ioline_puts(c->line, txt); +} + +static void cli_command_unload(struct cli *c, struct tokenizer *t) { + struct module *m; + uint32_t index; + const char *i; + char *e; + assert(c && t); + + if (!(i = tokenizer_get(t, 1))) { + ioline_puts(c->line, "You need to specfiy the module index.\n"); + return; + } + + index = (uint32_t) strtoul(i, &e, 10); + if (*e || !(m = idxset_get_by_index(c->core->modules, index))) { + ioline_puts(c->line, "Invalid module index.\n"); + return; + } + + module_unload_request(c->core, m); +} + -- cgit