mirror of
https://github.com/fluencelabs/redis
synced 2025-03-26 04:11:04 +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,"<redis>")) color = "green";
|
||||||
if (strstr(s,"<reply>")) color = "cyan";
|
if (strstr(s,"<reply>")) color = "cyan";
|
||||||
if (strstr(s,"<error>")) color = "red";
|
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 (len > 4 && isdigit(s[3])) {
|
||||||
if (s[1] == '>') color = "yellow"; /* Current line. */
|
if (s[1] == '>') color = "yellow"; /* Current line. */
|
||||||
else if (s[2] == '#') color = "bold"; /* Break point. */
|
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
|
/* Append an human readable representation of the Lua value at position 'idx'
|
||||||
* currently on the top of the stack. As a side effect the element is
|
* on the stack of the 'lua' state, to the SDS string passed as argument.
|
||||||
* popped. */
|
* The new SDS string with the represented value attached is returned.
|
||||||
void ldbLogStackValue(lua_State *lua, char *prefix) {
|
* Used in order to implement ldbLogStackValue().
|
||||||
int t = lua_type(lua,-1);
|
*
|
||||||
sds s = sdsnew(prefix);
|
* 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) {
|
switch(t) {
|
||||||
case LUA_TSTRING:
|
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;
|
break;
|
||||||
case LUA_TBOOLEAN:
|
case LUA_TBOOLEAN:
|
||||||
s = sdscat(s,lua_toboolean(lua,-1) ? "true" : "false");
|
s = sdscat(s,lua_toboolean(lua,idx) ? "true" : "false");
|
||||||
break;
|
break;
|
||||||
case LUA_TNUMBER:
|
case LUA_TNUMBER:
|
||||||
s = sdscatprintf(s,"%g",(double)lua_tonumber(lua,-1));
|
s = sdscatprintf(s,"%g",(double)lua_tonumber(lua,idx));
|
||||||
break;
|
break;
|
||||||
case LUA_TNIL:
|
case LUA_TNIL:
|
||||||
s = sdscat(s,"nil");
|
s = sdscatlen(s,"nil",3);
|
||||||
break;
|
break;
|
||||||
case LUA_TTABLE:
|
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_TFUNCTION:
|
||||||
case LUA_TUSERDATA:
|
case LUA_TUSERDATA:
|
||||||
case LUA_TTHREAD:
|
case LUA_TTHREAD:
|
||||||
case LUA_TLIGHTUSERDATA:
|
case LUA_TLIGHTUSERDATA:
|
||||||
{
|
{
|
||||||
const void *p = lua_topointer(lua,-1);
|
const void *p = lua_topointer(lua,idx);
|
||||||
char *typename = "unknown";
|
char *typename = "unknown";
|
||||||
if (t == LUA_TTABLE) typename = "table";
|
if (t == LUA_TFUNCTION) typename = "function";
|
||||||
else if (t == LUA_TFUNCTION) typename = "function";
|
|
||||||
else if (t == LUA_TUSERDATA) typename = "userdata";
|
else if (t == LUA_TUSERDATA) typename = "userdata";
|
||||||
else if (t == LUA_TTHREAD) typename = "thread";
|
else if (t == LUA_TTHREAD) typename = "thread";
|
||||||
else if (t == LUA_TLIGHTUSERDATA) typename = "light-userdata";
|
else if (t == LUA_TLIGHTUSERDATA) typename = "light-userdata";
|
||||||
s = sdscatprintf(s,"%s at %p",typename,p);
|
s = sdscatprintf(s,"%s@%p",typename,p);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
s = sdscat(s,"?");
|
s = sdscat(s,"<unknown-lua-type>");
|
||||||
break;
|
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);
|
ldbLog(s);
|
||||||
lua_pop(lua,1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *ldbRedisProtocolToHuman_Int(sds *o, char *reply);
|
char *ldbRedisProtocolToHuman_Int(sds *o, char *reply);
|
||||||
@ -1875,6 +1926,7 @@ void ldbPrint(lua_State *lua, char *varname) {
|
|||||||
i++;
|
i++;
|
||||||
if (strcmp(varname,name) == 0) {
|
if (strcmp(varname,name) == 0) {
|
||||||
ldbLogStackValue(lua,"<value> ");
|
ldbLogStackValue(lua,"<value> ");
|
||||||
|
lua_pop(lua,1);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
lua_pop(lua,1); /* Discard the var name on the stack. */
|
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;
|
return;
|
||||||
}
|
}
|
||||||
ldbLogStackValue(lua,"<retval> ");
|
ldbLogStackValue(lua,"<retval> ");
|
||||||
|
lua_pop(lua,1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read debugging commands from client. */
|
/* Read debugging commands from client. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user