From fb9441d785d32e6332caece4cb59e0f730fa9be1 Mon Sep 17 00:00:00 2001 From: Mark Nunberg Date: Sun, 9 Jul 2017 16:42:34 +0300 Subject: [PATCH] Add ParseVarArgs This allows a parsing of generic keyword arg0..argN format for arguments. --- rmutil/util.c | 33 ++++++++++++++++++++++++++++++++- rmutil/util.h | 11 +++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/rmutil/util.c b/rmutil/util.c index ea6fb7b..8307e59 100644 --- a/rmutil/util.c +++ b/rmutil/util.c @@ -243,4 +243,35 @@ int RedisModule_TryGetValue(RedisModuleKey *key, const RedisModuleType *type, vo } else { return RMUTIL_VALUE_MISMATCH; } -} \ No newline at end of file +} + +RedisModuleString **RMUtil_ParseVarArgs(RedisModuleString **argv, int argc, int offset, + const char *keyword, size_t *nargs) { + if (offset > argc) { + return NULL; + } + + argv += offset; + argc -= offset; + + int ix = RMUtil_ArgIndex(keyword, argv, argc); + if (ix < 0) { + return NULL; + } else if (ix >= argc - 1) { + *nargs = RMUTIL_VARARGS_BADARG; + return argv; + } + + argv += (ix + 1); + argc -= (ix + 1); + + long long n = 0; + RMUtil_ParseArgs(argv, argc, 0, "l", &n); + if (n > argc - 1 || n < 0) { + *nargs = RMUTIL_VARARGS_BADARG; + return argv; + } + + *nargs = n; + return argv + 1; +} diff --git a/rmutil/util.h b/rmutil/util.h index 3b3be76..a51c8ca 100644 --- a/rmutil/util.h +++ b/rmutil/util.h @@ -61,6 +61,17 @@ int RMUtil_ParseArgsAfter(const char *token, RedisModuleString **argv, int argc, int rmutil_vparseArgs(RedisModuleString **argv, int argc, int offset, const char *fmt, va_list ap); +#define RMUTIL_VARARGS_BADARG ((size_t)-1) +/** + * Parse arguments in the form of KEYWORD {len} {arg} .. {arg}_len. + * If keyword is present, returns the position within `argv` containing the arguments. + * Returns NULL if the keyword is not found. + * If a parse error has occurred, `nargs` is set to RMUTIL_VARARGS_BADARG, but + * the return value is not NULL. + */ +RedisModuleString **RMUtil_ParseVarArgs(RedisModuleString **argv, int argc, int offset, + const char *keyword, size_t *nargs); + // A single key/value entry in a redis info map typedef struct { const char *key;