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
redis
Commits
1f8fdafe
Commit
1f8fdafe
authored
Nov 11, 2015
by
antirez
Browse files
Lua debugger: much better Lua values pretty printer.
parent
f4805800
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/redis-cli.c
View file @
1f8fdafe
...
...
@@ -525,7 +525,7 @@ sds sdsCatColorizedLdbReply(sds o, char *s, size_t len) {
if
(
strstr
(
s
,
"<redis>"
))
color
=
"green"
;
if
(
strstr
(
s
,
"<reply>"
))
color
=
"cyan"
;
if
(
strstr
(
s
,
"<error>"
))
color
=
"red"
;
if
(
strstr
(
s
,
"<value>"
))
color
=
"magenta"
;
if
(
strstr
(
s
,
"<value>"
)
||
strstr
(
s
,
"<retval>"
)
)
color
=
"magenta"
;
if
(
len
>
4
&&
isdigit
(
s
[
3
]))
{
if
(
s
[
1
]
==
'>'
)
color
=
"yellow"
;
/* Current line. */
else
if
(
s
[
2
]
==
'#'
)
color
=
"bold"
;
/* Break point. */
...
...
src/scripting.c
View file @
1f8fdafe
...
...
@@ -1728,48 +1728,99 @@ void ldbList(int around, int context) {
}
}
/* Produce a debugger log entry representing the value of the Lua object
* currently on the top of the stack. As a side effect the element is
* popped. */
void
ldbLogStackValue
(
lua_State
*
lua
,
char
*
prefix
)
{
int
t
=
lua_type
(
lua
,
-
1
);
sds
s
=
sdsnew
(
prefix
);
/* Append an human readable representation of the Lua value at position 'idx'
* on the stack of the 'lua' state, to the SDS string passed as argument.
* The new SDS string with the represented value attached is returned.
* Used in order to implement ldbLogStackValue().
*
* The element is not automatically removed from the stack, nor it is
* converted to a different type. */
sds ldbCatStackValue(sds s, lua_State *lua, int idx) {
int t = lua_type(lua,idx);
switch(t) {
case LUA_TSTRING:
s
=
sdscat
(
s
,
lua_tostring
(
lua
,
-
1
));
{
size_t strl;
char *strp = (char*)lua_tolstring(lua,idx,&strl);
s = sdscatrepr(s,strp,strl);
}
break;
case LUA_TBOOLEAN:
s
=
sdscat
(
s
,
lua_toboolean
(
lua
,
-
1
)
?
"true"
:
"false"
);
s = sdscat(s,lua_toboolean(lua,
idx
) ? "true" : "false");
break;
case LUA_TNUMBER:
s
=
sdscatprintf
(
s
,
"%g"
,(
double
)
lua_tonumber
(
lua
,
-
1
));
s = sdscatprintf(s,"%g",(double)lua_tonumber(lua,
idx
));
break;
case LUA_TNIL:
s
=
sdscat
(
s
,
"nil"
);
s = sdscat
len
(s,"nil"
,3
);
break;
case LUA_TTABLE:
{
int expected_index = 1; /* First index we expect in an array. */
int is_array = 1; /* Will be set to null if check fails. */
/* Note: we create two representations at the same time, one
* assuming the table is an array, one assuming it is not. At the
* end we know what is true and select the right one. */
sds repr1 = sdsempty();
sds repr2 = sdsempty();
lua_pushnil(lua); /* The first key to start the iteration is nil. */
while (lua_next(lua,idx-1)) {
/* Test if so far the table looks like an array. */
if (is_array &&
(lua_type(lua,-2) != LUA_TNUMBER ||
lua_tonumber(lua,-2) != expected_index)) is_array = 0;
/* Stack now: table, key, value */
/* Array repr. */
repr1 = ldbCatStackValue(repr1,lua,-1);
repr1 = sdscatlen(repr1,"; ",2);
/* Full repr. */
repr2 = ldbCatStackValue(repr2,lua,-2);
repr2 = sdscatlen(repr2,"=",1);
repr2 = ldbCatStackValue(repr2,lua,-1);
repr2 = sdscatlen(repr2,"; ",2);
lua_pop(lua,1); /* Stack: table, key. Ready for next iteration. */
expected_index++;
}
/* Strip the last " ;" from both the representations. */
if (sdslen(repr1)) sdsrange(repr1,0,-3);
if (sdslen(repr2)) sdsrange(repr2,0,-3);
/* Select the right one and discard the other. */
s = sdscatlen(s,"{",1);
s = sdscatsds(s,is_array ? repr1 : repr2);
s = sdscatlen(s,"}",1);
sdsfree(repr1);
sdsfree(repr2);
}
break;
case LUA_TFUNCTION:
case LUA_TUSERDATA:
case LUA_TTHREAD:
case LUA_TLIGHTUSERDATA:
{
const
void
*
p
=
lua_topointer
(
lua
,
-
1
);
const void *p = lua_topointer(lua,
idx
);
char *typename = "unknown";
if
(
t
==
LUA_TTABLE
)
typename
=
"table"
;
else
if
(
t
==
LUA_TFUNCTION
)
typename
=
"function"
;
if (t == LUA_TFUNCTION) typename = "function";
else if (t == LUA_TUSERDATA) typename = "userdata";
else if (t == LUA_TTHREAD) typename = "thread";
else if (t == LUA_TLIGHTUSERDATA) typename = "light-userdata";
s
=
sdscatprintf
(
s
,
"%s
at
%p"
,
typename
,
p
);
s = sdscatprintf(s,"%s
@
%p",typename,p);
}
break;
default:
s
=
sdscat
(
s
,
"
?
"
);
s = sdscat(s,"
<unknown-lua-type>
");
break;
}
return s;
}
/* Produce a debugger log entry representing the value of the Lua object
* currently on the top of the stack. The element is ot popped nor modified.
* Check ldbCatStackValue() for the actual implementation. */
void ldbLogStackValue(lua_State *lua, char *prefix) {
sds s = sdsnew(prefix);
s = ldbCatStackValue(s,lua,-1);
ldbLog(s);
lua_pop
(
lua
,
1
);
}
char *ldbRedisProtocolToHuman_Int(sds *o, char *reply);
...
...
@@ -1875,6 +1926,7 @@ void ldbPrint(lua_State *lua, char *varname) {
i++;
if (strcmp(varname,name) == 0) {
ldbLogStackValue(lua,"<value> ");
lua_pop(lua,1);
return;
} else {
lua_pop(lua,1); /* Discard the var name on the stack. */
...
...
@@ -1954,6 +2006,7 @@ void ldbEval(lua_State *lua, sds *argv, int argc) {
return;
}
ldbLogStackValue(lua,"<retval> ");
lua_pop(lua,1);
}
/* Read debugging commands from client. */
...
...
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