issue #82 add support for displaying varargs

pull/85/head
Dibyendu Majumdar 8 years ago
parent 3f98309264
commit 833a6dc2e5

@ -84,7 +84,7 @@ enum {
TEXT_LEN = 256,
MAX_BREAKPOINTS = 5,
MAX_STACK_FRAMES = 30,
MAX_SCOPES = 3,
MAX_SCOPES = 4,
MAX_VARIABLES = 120,
MAX_THREADS = 10,
SOURCE_LEN = 8196,

@ -11,9 +11,9 @@
#include <string.h>
#ifdef _WIN32
#include <direct.h>
#include <fcntl.h>
#include <io.h>
#include <direct.h>
#define chdir _chdir
#else
#include <unistd.h>
@ -39,7 +39,7 @@ enum {
enum { VAR_TYPE_LOCALS = 1, VAR_TYPE_UPVALUES = 2, VAR_TYPE_GLOBALS = 3 };
/* Some utilities to allow packing of 5 components into a 32-bit integer value
* This is used to encode the stack frame, variable reference
* This is used to encode the stack frame, variable reference
*/
#define MASK0 0x3F
#define MASK 0xFF
@ -69,6 +69,7 @@ static ProtocolMessage output_response;
static char LUA_PATH[1024];
static char LUA_CPATH[1024];
static char workingdir[1024];
static char source_references[MAX_STACK_FRAMES];
/*
* Generate response to InitializeRequest
@ -141,7 +142,7 @@ static void handle_stack_trace_request(ProtocolMessage *req,
size_t n = strlen(workingdir);
if (workingdir[n - 1] == '/')
snprintf(path, sizeof path, "%s%s", workingdir, src);
else
else
snprintf(path, sizeof path, "%s/%s", workingdir, src);
}
else {
@ -159,18 +160,24 @@ static void handle_stack_trace_request(ProtocolMessage *req,
}
else if (memcmp(src, "=[C]", 4) == 0) {
/* Source is a string - send a reference to the stack frame */
// res->u.Response.u.StackTraceResponse.stackFrames[depth]
// .source.sourceReference = ((depth + 1) & 0xFF) |
// ((int)(((intptr_t)src) << 8) & 0xFFFFFF00);
res->u.Response.u.StackTraceResponse.stackFrames[depth]
.source.sourceReference = ((depth + 1) & 0xFF) | ((int)(((intptr_t)src) << 8) & 0xFFFFFF00);
.source.sourceReference = depth + 1;
ravi_string_copy(
res->u.Response.u.StackTraceResponse.stackFrames[depth].source.name,
"<C function>",
sizeof res->u.Response.u.StackTraceResponse.stackFrames[depth]
.source.name);
res->u.Response.u.StackTraceResponse.stackFrames[depth].source.name,
"<C function>",
sizeof res->u.Response.u.StackTraceResponse.stackFrames[depth]
.source.name);
}
else {
/* Source is a string - send a reference to the stack frame */
// res->u.Response.u.StackTraceResponse.stackFrames[depth]
// .source.sourceReference = ((depth + 1) & 0xFF) |
// ((int)(((intptr_t)src) << 8) & 0xFFFFFF00) ;
res->u.Response.u.StackTraceResponse.stackFrames[depth]
.source.sourceReference = ((depth + 1) & 0xFF) | ((int)(((intptr_t)src) << 8) & 0xFFFFFF00) ;
.source.sourceReference = depth + 1;
ravi_string_copy(
res->u.Response.u.StackTraceResponse.stackFrames[depth].source.name,
"<dynamic function>",
@ -187,13 +194,29 @@ static void handle_stack_trace_request(ProtocolMessage *req,
depth++;
}
res->u.Response.u.StackTraceResponse.totalFrames = depth;
for (int i = depth - 1, j = 0; i >= 0; i--, j++) {
if (res->u.Response.u.StackTraceResponse.stackFrames[i]
.source.sourceReference != 0) {
/* swap depth */
source_references[j] = res->u.Response.u.StackTraceResponse.stackFrames[i]
.source.sourceReference -
1;
res->u.Response.u.StackTraceResponse.stackFrames[i]
.source.sourceReference = j;
}
else {
source_references[j] = 0;
}
}
vscode_send(res, out, my_logger);
}
static void handle_source_request(ProtocolMessage *req, ProtocolMessage *res,
lua_State *L, FILE *out) {
lua_Debug entry;
int depth = (req->u.Request.u.SourceRequest.sourceReference & 0xFF) - 1;
// int depth = (req->u.Request.u.SourceRequest.sourceReference & 0xFF) - 1;
int i = req->u.Request.u.SourceRequest.sourceReference;
int depth = i >= 0 && i < MAX_STACK_FRAMES ? source_references[i] : -1;
vscode_make_success_response(req, res, VSCODE_SOURCE_RESPONSE);
if (lua_getstack(L, depth, &entry)) {
int status = lua_getinfo(L, "Sln", &entry);
@ -205,18 +228,21 @@ static void handle_source_request(ProtocolMessage *req, ProtocolMessage *res,
sizeof res->u.Response.u.SourceResponse.content);
}
else {
ravi_string_copy(res->u.Response.u.SourceResponse.content, "Source not available",
sizeof res->u.Response.u.SourceResponse.content);
ravi_string_copy(res->u.Response.u.SourceResponse.content,
"Source not available",
sizeof res->u.Response.u.SourceResponse.content);
}
}
else {
ravi_string_copy(res->u.Response.u.SourceResponse.content, "Source not available",
sizeof res->u.Response.u.SourceResponse.content);
ravi_string_copy(res->u.Response.u.SourceResponse.content,
"Source not available",
sizeof res->u.Response.u.SourceResponse.content);
}
}
else {
ravi_string_copy(res->u.Response.u.SourceResponse.content, "Source not available",
sizeof res->u.Response.u.SourceResponse.content);
ravi_string_copy(res->u.Response.u.SourceResponse.content,
"Source not available",
sizeof res->u.Response.u.SourceResponse.content);
}
vscode_send(res, out, my_logger);
}
@ -293,6 +319,14 @@ static void handle_scopes_request(ProtocolMessage *req, ProtocolMessage *res,
res->u.Response.u.ScopesResponse.scopes[i].variablesReference =
MAKENUM(VAR_TYPE_LOCALS, depth, 0, 0, 0);
res->u.Response.u.ScopesResponse.scopes[i++].expensive = 0;
if (entry.isvararg) {
ravi_string_copy(res->u.Response.u.ScopesResponse.scopes[i].name,
"Var Args",
sizeof res->u.Response.u.ScopesResponse.scopes[0].name);
res->u.Response.u.ScopesResponse.scopes[i].variablesReference =
MAKENUM(VAR_TYPE_LOCALS, depth, 0, 0, 1);
res->u.Response.u.ScopesResponse.scopes[i++].expensive = 0;
}
if (entry.nups > 0) {
ravi_string_copy(res->u.Response.u.ScopesResponse.scopes[i].name,
"Up Values",
@ -396,7 +430,9 @@ static void handle_variables_request(ProtocolMessage *req, ProtocolMessage *res,
*/
int type = EXTRACT_T(varRef);
int depth = EXTRACT_A(varRef);
int var = EXTRACT_B(varRef);
int var = (char)(EXTRACT_B(varRef)); /* the cast is to get the signed value */
int isvararg = EXTRACT_D(varRef);
fprintf(my_logger, "Var Request --> %d isvararg=%d\n", type, isvararg);
if (lua_getstack(L, depth, &entry)) {
if (type == VAR_TYPE_LOCALS) { // locals
if (var == 0) {
@ -404,15 +440,26 @@ static void handle_variables_request(ProtocolMessage *req, ProtocolMessage *res,
* A top level request - i.e. from the scope
*/
for (int n = 1, v = 0; v < MAX_VARIABLES; n++) {
const char *name = lua_getlocal(L, &entry, n);
const char *name = lua_getlocal(L, &entry, isvararg ? -n : n);
if (name) {
/* Temporary variables have names that start with (.
/* Temporary variables have names that start with (*temporary).
* Skip such variables
*/
if (*name != '(') {
ravi_string_copy(
res->u.Response.u.VariablesResponse.variables[v].name, name,
sizeof res->u.Response.u.VariablesResponse.variables[0].name);
if (*name != '(' || strcmp(name, "(*vararg)") == 0) {
if (*name == '(') {
char temp[80];
snprintf(temp, sizeof temp, "vararg[%d]", n);
ravi_string_copy(
res->u.Response.u.VariablesResponse.variables[v].name, temp,
sizeof res->u.Response.u.VariablesResponse.variables[0]
.name);
}
else {
ravi_string_copy(
res->u.Response.u.VariablesResponse.variables[v].name, name,
sizeof res->u.Response.u.VariablesResponse.variables[0]
.name);
}
int is_table = get_value(
L, lua_gettop(L),
res->u.Response.u.VariablesResponse.variables[v].value,
@ -421,8 +468,12 @@ static void handle_variables_request(ProtocolMessage *req, ProtocolMessage *res,
/* If the variable is a table then we pass pack a reference
that is used by the front end to drill down */
res->u.Response.u.VariablesResponse.variables[v]
.variablesReference =
is_table ? MAKENUM(type, depth, n, 0, 0) : 0;
.variablesReference = is_table
? MAKENUM(type, depth,
isvararg ? ((char)-n) : n,
0, isvararg)
: 0; /* cast is to ensure that we
save a signed char value */
v++;
}
lua_pop(L, 1); /* pop the value */
@ -508,14 +559,15 @@ static void handle_launch_request(ProtocolMessage *req, ProtocolMessage *res,
if (chdir(req->u.Request.u.LaunchRequest.cwd) != 0) {
char temp[1024];
snprintf(temp, sizeof temp, "Unable to change directory to %s\n",
req->u.Request.u.LaunchRequest.cwd);
req->u.Request.u.LaunchRequest.cwd);
vscode_send_output_event(res, "console", temp, out, my_logger);
vscode_send_error_response(req, res, VSCODE_LAUNCH_RESPONSE,
"Launch failed", out, my_logger);
"Launch failed", out, my_logger);
return;
}
else {
ravi_string_copy(workingdir, req->u.Request.u.LaunchRequest.cwd, sizeof workingdir);
ravi_string_copy(workingdir, req->u.Request.u.LaunchRequest.cwd,
sizeof workingdir);
}
}
const char *progname = req->u.Request.u.LaunchRequest.program;
@ -702,9 +754,8 @@ void ravi_debughook(lua_State *L, lua_Debug *ar) {
void ravi_debug_writestring(const char *s, size_t l) {
char temp[256];
if (l >= sizeof temp)
l = sizeof temp - 1;
ravi_string_copy(temp, s, l+1);
if (l >= sizeof temp) l = sizeof temp - 1;
ravi_string_copy(temp, s, l + 1);
vscode_send_output_event(&output_response, "stdout", temp, stdout, my_logger);
}
@ -728,8 +779,8 @@ void ravi_debug_writestringerror(const char *fmt, const char *p) {
*/
static void createargtable(lua_State *L, char **argv, int argc, int script) {
int i, narg;
if (script == argc) script = 0; /* no script name? */
narg = argc - (script + 1); /* number of positive indices */
if (script == argc) script = 0; /* no script name? */
narg = argc - (script + 1); /* number of positive indices */
lua_createtable(L, narg, script + 1);
for (i = 0; i < argc; i++) {
lua_pushstring(L, argv[i]);
@ -768,9 +819,8 @@ int main(int argc, char **argv) {
lua_sethook(L, ravi_debughook, LUA_MASKCALL | LUA_MASKLINE | LUA_MASKRET, 0);
debugger_state = DEBUGGER_BIRTH;
ravi_set_debugger_data(
L,
&debugger_state); /* This is useless data right now but it ensures that
the hook cannot be removed */
L, &debugger_state); /* This is useless data right now but it ensures that
the hook cannot be removed */
debugger(L, NULL, stdin, stdout);
lua_close(L);
fclose(my_logger);

Loading…
Cancel
Save