Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
hiredis
Commits
7684d556
Commit
7684d556
authored
Dec 02, 2010
by
Pieter Noordhuis
Browse files
Add (nearly) full printf support by delegating to vsprintf
parent
ff50dff7
Changes
2
Hide whitespace changes
Inline
Side-by-side
hiredis.c
View file @
7684d556
...
@@ -32,6 +32,7 @@
...
@@ -32,6 +32,7 @@
#include <unistd.h>
#include <unistd.h>
#include <assert.h>
#include <assert.h>
#include <errno.h>
#include <errno.h>
#include <ctype.h>
#include "hiredis.h"
#include "hiredis.h"
#include "net.h"
#include "net.h"
...
@@ -639,6 +640,59 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
...
@@ -639,6 +640,59 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
case
'%'
:
case
'%'
:
current
=
sdscat
(
current
,
"%"
);
current
=
sdscat
(
current
,
"%"
);
break
;
break
;
default:
/* Try to detect printf format */
{
char
_format
[
16
];
const
char
*
_p
=
c
+
1
;
size_t
_l
=
0
;
va_list
_cpy
;
/* Flags */
if
(
*
_p
!=
'\0'
&&
*
_p
==
'#'
)
_p
++
;
if
(
*
_p
!=
'\0'
&&
*
_p
==
'0'
)
_p
++
;
if
(
*
_p
!=
'\0'
&&
*
_p
==
'-'
)
_p
++
;
if
(
*
_p
!=
'\0'
&&
*
_p
==
' '
)
_p
++
;
if
(
*
_p
!=
'\0'
&&
*
_p
==
'+'
)
_p
++
;
/* Field width */
while
(
*
_p
!=
'\0'
&&
isdigit
(
*
_p
))
_p
++
;
/* Precision */
if
(
*
_p
==
'.'
)
{
_p
++
;
while
(
*
_p
!=
'\0'
&&
isdigit
(
*
_p
))
_p
++
;
}
/* Modifiers */
if
(
*
_p
!=
'\0'
)
{
if
(
*
_p
==
'h'
||
*
_p
==
'l'
)
{
/* Allow a single repetition for these modifiers */
if
(
_p
[
0
]
==
_p
[
1
])
_p
++
;
_p
++
;
}
}
/* Conversion specifier */
if
(
*
_p
!=
'\0'
&&
strchr
(
"diouxXeEfFgGaA"
,
*
_p
)
!=
NULL
)
{
_l
=
(
_p
+
1
)
-
c
;
if
(
_l
<
sizeof
(
_format
)
-
2
)
{
memcpy
(
_format
,
c
,
_l
);
_format
[
_l
]
=
'\0'
;
va_copy
(
_cpy
,
ap
);
current
=
sdscatvprintf
(
current
,
_format
,
_cpy
);
interpolated
=
1
;
va_end
(
_cpy
);
/* Update current position (note: outer blocks
* increment c twice so compensate here) */
c
=
_p
-
1
;
}
}
/* Consume and discard vararg */
va_arg
(
ap
,
void
);
}
}
}
c
++
;
c
++
;
}
}
...
...
test.c
View file @
7684d556
...
@@ -71,6 +71,30 @@ static void test_format_commands() {
...
@@ -71,6 +71,30 @@ static void test_format_commands() {
len
==
4
+
4
+
(
3
+
2
)
+
4
+
(
1
+
2
)
+
4
+
(
1
+
2
));
len
==
4
+
4
+
(
3
+
2
)
+
4
+
(
1
+
2
)
+
4
+
(
1
+
2
));
free
(
cmd
);
free
(
cmd
);
test
(
"Format command with printf-delegation (long long): "
);
len
=
redisFormatCommand
(
&
cmd
,
"key:%08lld"
,
1234ll
);
test_cond
(
strncmp
(
cmd
,
"*1
\r\n
$12
\r\n
key:00001234
\r\n
"
,
len
)
==
0
&&
len
==
4
+
5
+
(
12
+
2
));
free
(
cmd
);
test
(
"Format command with printf-delegation (float): "
);
len
=
redisFormatCommand
(
&
cmd
,
"v:%06.1f"
,
12
.
34
f
);
test_cond
(
strncmp
(
cmd
,
"*1
\r\n
$8
\r\n
v:0012.3
\r\n
"
,
len
)
==
0
&&
len
==
4
+
4
+
(
8
+
2
));
free
(
cmd
);
test
(
"Format command with printf-delegation and extra interpolation: "
);
len
=
redisFormatCommand
(
&
cmd
,
"key:%d %b"
,
1234
,
"foo"
,
3
);
test_cond
(
strncmp
(
cmd
,
"*2
\r\n
$8
\r\n
key:1234
\r\n
$3
\r\n
foo
\r\n
"
,
len
)
==
0
&&
len
==
4
+
4
+
(
8
+
2
)
+
4
+
(
3
+
2
));
free
(
cmd
);
test
(
"Format command with wrong printf format and extra interpolation: "
);
len
=
redisFormatCommand
(
&
cmd
,
"key:%08p %b"
,
1234
,
"foo"
,
3
);
test_cond
(
strncmp
(
cmd
,
"*2
\r\n
$6
\r\n
key:8p
\r\n
$3
\r\n
foo
\r\n
"
,
len
)
==
0
&&
len
==
4
+
4
+
(
6
+
2
)
+
4
+
(
3
+
2
));
free
(
cmd
);
const
char
*
argv
[
3
];
const
char
*
argv
[
3
];
argv
[
0
]
=
"SET"
;
argv
[
0
]
=
"SET"
;
argv
[
1
]
=
"foo
\0
xxx"
;
argv
[
1
]
=
"foo
\0
xxx"
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment