diff options
author | Timo Sirainen <cras@irssi.org> | 2000-06-01 16:46:50 +0000 |
---|---|---|
committer | cras <cras@dbcabf3a-b0e7-0310-adc4-f8d773084564> | 2000-06-01 16:46:50 +0000 |
commit | e5385ceb35c22b2cca00d03241596dcd96582e91 (patch) | |
tree | de94948ad735e4de1a78fe234f8d209829b7481c /src | |
parent | bf8616ee26b7dd9f4b93b61a8ab8216351b12fa8 (diff) | |
download | irssi-e5385ceb35c22b2cca00d03241596dcd96582e91.zip |
cmd_get_params() fixes:
- arguments and optional channel flags couldn't be used together
- -- argument treats the rest of the text as non-arguments, like
/topic -- -hello- sets the topic to -hello-.
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@256 dbcabf3a-b0e7-0310-adc4-f8d773084564
Diffstat (limited to 'src')
-rw-r--r-- | src/core/commands.c | 98 |
1 files changed, 71 insertions, 27 deletions
diff --git a/src/core/commands.c b/src/core/commands.c index a2c92ef1..10cf9123 100644 --- a/src/core/commands.c +++ b/src/core/commands.c @@ -160,22 +160,31 @@ static char *get_opt_args(char **data) { /* -cmd1 -cmd2 -cmd3 ... */ char *p, *ret; + int stopnext; g_return_val_if_fail(data != NULL, NULL); g_return_val_if_fail(*data != NULL, NULL); + stopnext = FALSE; ret = NULL; for (p = *data;;) { - if (*p != '-') { + if (*p != '-' || stopnext) { if (p == *data) return ""; - while (isspace(p[-1]) && p > *data) p--; - if (*p != '\0') *p++ = '\0'; ret = *data; *data = p; + + while (isspace(p[-1]) && p > ret) p--; + if (*p != '\0') *p = '\0'; return ret; } + if (p[1] == '-') { + /* -- argument means end of arguments even if + next word starts with - */ + stopnext = TRUE; + } + while (!isspace(*p) && *p != '\0') p++; while (isspace(*p)) p++; } @@ -224,7 +233,7 @@ int arg_find(char **array, const char *item) return -1; } -static int get_multi_args(char **data, va_list va) +static int get_multi_args(char **data, int checkonly, va_list va) { /* -cmd1 arg1 -cmd2 "argument two" -cmd3 */ GString *returnargs; @@ -256,7 +265,16 @@ static int get_multi_args(char **data, va_list va) nextarg = NULL; for (;;) { if (**data == '-') { - (*data)++; arg = cmd_get_param(data); + (*data)++; + if (**data == '-') { + /* -- argument means end of arguments even + if next word starts with - */ + (*data)++; + while (isspace(**data)) (*data)++; + break; + } + + arg = cmd_get_param(data); g_string_sprintfa(returnargs, "-%s ", arg); /* check if this argument can have parameter */ @@ -280,19 +298,22 @@ static int get_multi_args(char **data, va_list va) while (isspace(**data)) (*data)++; } - /* ok, this is a bit stupid. this will pack the arguments in `data' - like "-arg1 subarg -arg2 sub2\0" -> "-arg1 -arg2\0subarg\0sub2\0" - this is because it's easier to free only _one_ string instead of - two (`args') when using PARAM_FLAG_MULTIARGS. */ - if (origdata == *data) - *args = ""; - else { - cmd_params_pack(subargs, **data == '\0' ? *data : (*data)-1, - origdata, origdata+returnargs->len); - - g_string_truncate(returnargs, returnargs->len-1); - strcpy(origdata, returnargs->str); - *args = origdata; + if (!checkonly) { + /* ok, this is a bit stupid. this will pack the arguments in + `data' like "-arg1 subarg -arg2 sub2\0" -> + "-arg1 -arg2\0subarg\0sub2\0" this is because it's easier + to free only _one_ string instead of two (`args') when + using PARAM_FLAG_MULTIARGS. */ + if (returnargs->len == 0) + *args = ""; + else { + cmd_params_pack(subargs, **data == '\0' ? *data : (*data)-1, + origdata, origdata+returnargs->len); + + g_string_truncate(returnargs, returnargs->len-1); + strcpy(origdata, returnargs->str); + *args = origdata; + } } g_string_free(returnargs, TRUE); @@ -322,28 +343,51 @@ char *cmd_get_callfuncs(const char *data, int *count, va_list *args) char *cmd_get_params(const char *data, int count, ...) { - char **str, *arg, *ret, *datad; + char **str, *arg, *datad, *old; va_list args; - int cnt, eat; + int cnt, eat, len; g_return_val_if_fail(data != NULL, NULL); va_start(args, count); - ret = datad = cmd_get_callfuncs(data, &count, &args); + /* get the length of the arguments in string */ + old = datad = g_strdup(data); + if (count & PARAM_FLAG_MULTIARGS) + get_multi_args(&datad, TRUE, args); + else if (count & PARAM_FLAG_OPTARGS) + get_opt_args(&datad); + len = (int) (datad-old); + g_free(old); + + /* send the text to custom functions to handle - skip arguments */ + old = datad = cmd_get_callfuncs(data+len, &count, &args); + + if (len > 0) { + /* put the arguments + the new data to one string */ + datad = g_malloc(len+1 + strlen(old)+1); + memcpy(datad, data, len); + datad[len] = ' '; + memcpy(datad+len+1, old, strlen(old)+1); + g_free(old); + + old = datad; + } + + /* and now handle the string */ cnt = PARAM_WITHOUT_FLAGS(count); while (cnt-- > 0) { - if (count & PARAM_FLAG_OPTARGS) { - arg = get_opt_args(&datad); - count &= ~PARAM_FLAG_OPTARGS; - } else if (count & PARAM_FLAG_MULTIARGS) { - eat = get_multi_args(&datad, args)+1; + if (count & PARAM_FLAG_MULTIARGS) { + eat = get_multi_args(&datad, FALSE, args)+1; count &= ~PARAM_FLAG_MULTIARGS; cnt -= eat-1; while (eat-- > 0) str = (char **) va_arg(args, char **); continue; + } else if (count & PARAM_FLAG_OPTARGS) { + arg = get_opt_args(&datad); + count &= ~PARAM_FLAG_OPTARGS; } else if (cnt == 0 && count & PARAM_FLAG_GETREST) { /* get rest */ arg = datad; @@ -356,7 +400,7 @@ char *cmd_get_params(const char *data, int count, ...) } va_end(args); - return ret; + return old; } void cmd_get_add_func(CMD_GET_FUNC func) |