aboutsummaryrefslogtreecommitdiffstats
path: root/src/command.c
diff options
context:
space:
mode:
authorThomas Jansen <mithi@mithi.net>2009-01-09 17:06:40 +0100
committerMax Kellermann <max@duempel.org>2009-01-10 16:48:12 +0100
commit8ed3cf3e6b31e48369a2007da8c95d686c62d184 (patch)
tree6623b8352707949edba4a14ee84b6c784a1cf3df /src/command.c
parent5e93d3682faf450fb7dc34b1a5c458b87d8bf5d9 (diff)
downloadmpd-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 'src/command.c')
-rw-r--r--src/command.c48
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)
{