summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/commands.c15
-rw-r--r--src/commands.h3
-rw-r--r--src/io.c72
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;
};
diff --git a/src/io.c b/src/io.c
index e3b9bcb..2a981b1 100644
--- a/src/io.c
+++ b/src/io.c
@@ -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