diff options
author | Thomas Jansen <mithi@mithi.net> | 2009-01-09 17:06:40 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2009-01-10 16:48:12 +0100 |
commit | 8ed3cf3e6b31e48369a2007da8c95d686c62d184 (patch) | |
tree | 6623b8352707949edba4a14ee84b6c784a1cf3df /src/command.c | |
parent | 5e93d3682faf450fb7dc34b1a5c458b87d8bf5d9 (diff) | |
download | mpd-8ed3cf3e6b31e48369a2007da8c95d686c62d184.tar.gz mpd-8ed3cf3e6b31e48369a2007da8c95d686c62d184.tar.xz mpd-8ed3cf3e6b31e48369a2007da8c95d686c62d184.zip |
command: add a parser for range arguments
A range argument looks like start[:end] and is used to specify the entries
of a list that should be returned (rather than the whole list).
Diffstat (limited to '')
-rw-r--r-- | src/command.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/command.c b/src/command.c index c9b3db1ca..652d3b3b0 100644 --- a/src/command.c +++ b/src/command.c @@ -160,6 +160,54 @@ check_int(struct client *client, int *value_r, return true; } +static bool G_GNUC_PRINTF(5, 6) +check_range(struct client *client, int *value_r1, int *value_r2, + const char *s, const char *fmt, ...) +{ + char *test, *test2; + long value; + + value = strtol(s, &test, 10); + if (*test != '\0' && *test != ':') { + va_list args; + va_start(args, fmt); + command_error_v(client, ACK_ERROR_ARG, fmt, args); + va_end(args); + return false; + } + +#if LONG_MAX > INT_MAX + if (value < INT_MIN || value > INT_MAX) { + command_error(client, ACK_ERROR_ARG, + "Number too large: %s", s); + return false; + } +#endif + + *value_r1 = (int)value; + + if (*test == ':') { + value = strtol(++test, &test2, 10); + if (*test2 != '\0' || test == test2) { + va_list args; + va_start(args, fmt); + command_error_v(client, ACK_ERROR_ARG, fmt, args); + va_end(args); + return false; + } +#if LONG_MAX > INT_MAX + if (value < INT_MIN || value > INT_MAX) { + command_error(client, ACK_ERROR_ARG, + "Number too large: %s", s); + return false; + } +#endif + *value_r2 = (int)value; + } + + return true; +} + static bool check_unsigned(struct client *client, unsigned *value_r, const char *s) { |