summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSalvatore Sanfilippo <antirez@gmail.com>2016-09-21 11:46:53 +0200
committerGitHub <noreply@github.com>2016-09-21 11:46:53 +0200
commit6e866ee05e49ab93e626b5a576e4c0f28cca71f0 (patch)
tree7615cb255f4e5baba3de35ff3737f679b5e8bba5
parent670586715a19e7aff9b3af793a7a9b334b418752 (diff)
parenta91650fc57077f53eac658d2da452bcf10d14ee6 (diff)
downloadredis-6e866ee05e49ab93e626b5a576e4c0f28cca71f0.tar.gz
Merge pull request #3511 from dvirsky/create_string_printf
added RM_CreateStringPrintf
-rw-r--r--src/module.c25
-rw-r--r--src/modules/testmodule.c26
-rw-r--r--src/object.c2
-rw-r--r--src/redismodule.h2
4 files changed, 52 insertions, 3 deletions
diff --git a/src/module.c b/src/module.c
index 3c757a5cb..b94c98acf 100644
--- a/src/module.c
+++ b/src/module.c
@@ -681,13 +681,33 @@ void autoMemoryCollect(RedisModuleCtx *ctx) {
*
* The string is created by copying the `len` bytes starting
* at `ptr`. No reference is retained to the passed buffer. */
-RedisModuleString *RM_CreateString(RedisModuleCtx *ctx, const char *ptr, size_t len)
-{
+RedisModuleString *RM_CreateString(RedisModuleCtx *ctx, const char *ptr, size_t len) {
RedisModuleString *o = createStringObject(ptr,len);
autoMemoryAdd(ctx,REDISMODULE_AM_STRING,o);
return o;
}
+
+/* Create a new module string object from a printf format and arguments.
+ * The returned string must be freed with RedisModule_FreeString(), unless automatic
+ * memory is enabled.
+ *
+ * The string is created using the sds formatter function sdscatvprintf() */
+RedisModuleString *RM_CreateStringPrintf(RedisModuleCtx *ctx, const char *fmt, ...) {
+ sds s = sdsempty();
+
+ va_list ap;
+ va_start(ap, fmt);
+ s = sdscatvprintf(s, fmt, ap);
+ va_end(ap);
+
+ RedisModuleString *o = createObject(OBJ_STRING, s);
+ autoMemoryAdd(ctx,REDISMODULE_AM_STRING,o);
+
+ return o;
+}
+
+
/* Like RedisModule_CreatString(), but creates a string starting from a long long
* integer instead of taking a buffer and its length.
*
@@ -3194,6 +3214,7 @@ void moduleRegisterCoreAPI(void) {
REGISTER_API(CreateString);
REGISTER_API(CreateStringFromLongLong);
REGISTER_API(CreateStringFromString);
+ REGISTER_API(CreateStringPrintf);
REGISTER_API(FreeString);
REGISTER_API(StringPtrLen);
REGISTER_API(AutoMemory);
diff --git a/src/modules/testmodule.c b/src/modules/testmodule.c
index a1a42f43b..db809a8e6 100644
--- a/src/modules/testmodule.c
+++ b/src/modules/testmodule.c
@@ -93,6 +93,25 @@ int TestStringAppendAM(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
return REDISMODULE_OK;
}
+/* TEST.STRING.PRINTF -- Test string formatting. */
+int TestStringPrintf(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
+ RedisModule_AutoMemory(ctx);
+ if (argc < 3) {
+ return RedisModule_WrongArity(ctx);
+ }
+ RedisModuleString *s = RedisModule_CreateStringPrintf(ctx,
+ "Got %d args. argv[1]: %s, argv[2]: %s",
+ argc,
+ RedisModule_StringPtrLen(argv[1], NULL),
+ RedisModule_StringPtrLen(argv[2], NULL)
+ );
+
+ RedisModule_ReplyWithString(ctx,s);
+
+ return REDISMODULE_OK;
+}
+
+
/* ----------------------------- Test framework ----------------------------- */
/* Return 1 if the reply matches the specified string, otherwise log errors
@@ -163,6 +182,9 @@ int TestIt(RedisModuleCtx *ctx, RedisModuleString **argv, int argc) {
T("test.string.append.am","");
if (!TestAssertStringReply(ctx,reply,"foobar",6)) goto fail;
+ T("test.string.printf", "cc", "foo", "bar");
+ if (!TestAssertStringReply(ctx,reply,"Got 3 args. argv[1]: foo, argv[2]: bar",38)) goto fail;
+
RedisModule_ReplyWithSimpleString(ctx,"ALL TESTS PASSED");
return REDISMODULE_OK;
@@ -188,6 +210,10 @@ int RedisModule_OnLoad(RedisModuleCtx *ctx, RedisModuleString **argv, int argc)
TestStringAppendAM,"write deny-oom",1,1,1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
+ if (RedisModule_CreateCommand(ctx,"test.string.printf",
+ TestStringPrintf,"write deny-oom",1,1,1) == REDISMODULE_ERR)
+ return REDISMODULE_ERR;
+
if (RedisModule_CreateCommand(ctx,"test.it",
TestIt,"readonly",1,1,1) == REDISMODULE_ERR)
return REDISMODULE_ERR;
diff --git a/src/object.c b/src/object.c
index 75839926e..210e980e7 100644
--- a/src/object.c
+++ b/src/object.c
@@ -75,7 +75,7 @@ robj *makeObjectShared(robj *o) {
/* Create a string object with encoding OBJ_ENCODING_RAW, that is a plain
* string object where o->ptr points to a proper sds string. */
robj *createRawStringObject(const char *ptr, size_t len) {
- return createObject(OBJ_STRING,sdsnewlen(ptr,len));
+ return createObject(OBJ_STRING, sdsnewlen(ptr,len));
}
/* Create a string object with encoding OBJ_ENCODING_EMBSTR, that is
diff --git a/src/redismodule.h b/src/redismodule.h
index 0a35cf047..75b13ad52 100644
--- a/src/redismodule.h
+++ b/src/redismodule.h
@@ -125,6 +125,7 @@ RedisModuleCallReply *REDISMODULE_API_FUNC(RedisModule_CallReplyArrayElement)(Re
RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateString)(RedisModuleCtx *ctx, const char *ptr, size_t len);
RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringFromLongLong)(RedisModuleCtx *ctx, long long ll);
RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringFromString)(RedisModuleCtx *ctx, const RedisModuleString *str);
+RedisModuleString *REDISMODULE_API_FUNC(RedisModule_CreateStringPrintf)(RedisModuleCtx *ctx, const char *fmt, ...);
void REDISMODULE_API_FUNC(RedisModule_FreeString)(RedisModuleCtx *ctx, RedisModuleString *str);
const char *REDISMODULE_API_FUNC(RedisModule_StringPtrLen)(const RedisModuleString *str, size_t *len);
int REDISMODULE_API_FUNC(RedisModule_ReplyWithError)(RedisModuleCtx *ctx, const char *err);
@@ -234,6 +235,7 @@ static int RedisModule_Init(RedisModuleCtx *ctx, const char *name, int ver, int
REDISMODULE_GET_API(CreateString);
REDISMODULE_GET_API(CreateStringFromLongLong);
REDISMODULE_GET_API(CreateStringFromString);
+ REDISMODULE_GET_API(CreateStringPrintf);
REDISMODULE_GET_API(FreeString);
REDISMODULE_GET_API(StringPtrLen);
REDISMODULE_GET_API(AutoMemory);