mirror of
https://github.com/fluencelabs/redis
synced 2025-03-23 19:10:51 +00:00
Lua debugger: much better Lua values pretty printer.
This commit is contained in:
parent
f4805800dc
commit
1f8fdafe65
@ -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. */
|
||||
|
@ -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 = sdscatlen(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. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user