diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/commands.c | 15 | ||||
-rw-r--r-- | src/commands.h | 3 | ||||
-rw-r--r-- | src/io.c | 72 |
3 files changed, 68 insertions, 22 deletions
diff --git a/src/commands.c b/src/commands.c index b89c5a4..40908b4 100644 --- a/src/commands.c +++ b/src/commands.c @@ -9,7 +9,8 @@ #include <readline/history.h> static void -list_users(struct cmumble_context *ctx) +list_users(struct cmumble_context *ctx, + int argc, char **argv) { struct cmumble_user *user = NULL; GList *l; @@ -22,7 +23,8 @@ list_users(struct cmumble_context *ctx) } static void -list_channels(struct cmumble_context *ctx) +list_channels(struct cmumble_context *ctx, + int argc, char **argv) { struct cmumble_channel *channel = NULL; GList *l; @@ -35,14 +37,16 @@ list_channels(struct cmumble_context *ctx) } static void -quit(struct cmumble_context *ctx) +quit(struct cmumble_context *ctx, + int argc, char **argv) { rl_already_prompted = 1; g_main_loop_quit(ctx->loop); } static void -clear(struct cmumble_context *ctx) +clear(struct cmumble_context *ctx, + int argc, char **argv) { rl_clear_screen(0,0); rl_reset_line_state(); @@ -50,7 +54,8 @@ clear(struct cmumble_context *ctx) } static void -help(struct cmumble_context *ctx) +help(struct cmumble_context *ctx, + int argc, char **argv) { int i; diff --git a/src/commands.h b/src/commands.h index 6ea8c67..a2cca59 100644 --- a/src/commands.h +++ b/src/commands.h @@ -5,7 +5,8 @@ struct cmumble_context; struct cmumble_command { const char *name; - void (*callback)(struct cmumble_context *); + void (*callback)(struct cmumble_context *, + int argc, char **argv); const char *description; }; @@ -62,8 +62,8 @@ print_preserve_prompt(const gchar *string) } } -static const char * -skip_whitespace(const char *text) +static char * +skip_whitespace(char *text) { int i; @@ -75,15 +75,55 @@ skip_whitespace(const char *text) return &text[i]; } +static char * +skip_non_whitespace(char *text) +{ + int i; + + for (i = 0; text[i] != '\0'; ++i) { + if (text[i] == ' ') + return &text[i]; + } + + return &text[i]; +} + +static int +command_split(char *cmd, char ***argv) +{ + static char *av[16]; + int i; + + for (i = 0; i < 15; ++i) { + cmd = skip_whitespace(cmd); + av[i] = cmd; + cmd = skip_non_whitespace(cmd); + if (cmd[0] == '\0') { + ++i; + break; + } else { + cmd[0] = '\0'; + cmd++; + } + } + av[i] = NULL; + *argv = av; + + return i; +} + static void process_line(char *line) { struct cmumble_context *ctx = global_rl_user_data; - const char *cmd; int i; + int argc; + char **argv; + const char *cmd; g_assert(global_rl_user_data); + rl_reset_line_state(); if (line == NULL) { @@ -93,28 +133,28 @@ process_line(char *line) g_main_loop_quit(ctx->loop); return; } + line = g_strdup(line); - cmd = skip_whitespace(line); - cmd = cmumble_command_expand_shortcut(cmd); - - for (i = 0; ctx->commands[i].name; ++i) { - if (strncmp(cmd, ctx->commands[i].name, - strlen(ctx->commands[i].name)) == 0) { + if (strlen(line)) + add_history(line); - if (strlen(cmd) > strlen(ctx->commands[i].name) && - cmd[strlen(ctx->commands[i].name)] != ' ') - continue; + argc = command_split(line, &argv); + if (argc == 0) + goto out; - ctx->commands[i].callback(ctx); + cmd = cmumble_command_expand_shortcut(argv[0]); + for (i = 0; ctx->commands[i].name; ++i) { + if (strlen(cmd) == strlen(ctx->commands[i].name) && + strcmp(cmd, ctx->commands[i].name) == 0) { + ctx->commands[i].callback(ctx, argc, argv); break; } } if (ctx->commands[i].name == NULL) g_print("Unknown command: %s\n", line); - - if (strlen(line)) - add_history(line); +out: + free(line); } int |