issue #82 support for VSCode IDE

pull/93/merge
Dibyendu Majumdar 8 years ago
parent 52d89447e5
commit 0b1f051971

@ -224,7 +224,7 @@ static int vscode_parse_initialize_request(json_value *js, ProtocolMessage *msg,
adapterID != NULL ? adapterID : "null");
return VSCODE_UNKNOWN_REQUEST;
}
ravi_string_copy(msg->u.Request.u.InitializeRequest.adapterID, adapterID,
vscode_string_copy(msg->u.Request.u.InitializeRequest.adapterID, adapterID,
sizeof msg->u.Request.u.InitializeRequest.adapterID);
const char *pathFormat = get_string_value(args, "pathFormat", log);
if (pathFormat != NULL && strcmp(pathFormat, "path") != 0) {
@ -233,7 +233,7 @@ static int vscode_parse_initialize_request(json_value *js, ProtocolMessage *msg,
return VSCODE_UNKNOWN_REQUEST;
}
if (pathFormat)
ravi_string_copy(msg->u.Request.u.InitializeRequest.pathFormat, pathFormat,
vscode_string_copy(msg->u.Request.u.InitializeRequest.pathFormat, pathFormat,
sizeof msg->u.Request.u.InitializeRequest.pathFormat);
int found = 0;
msg->u.Request.u.InitializeRequest.columnsStartAt1 =
@ -292,23 +292,23 @@ static int vscode_parse_launch_request(json_value *js, ProtocolMessage *msg,
get_boolean_value(args, "stopOnEntry", log, &found);
const char *prog = get_string_value(args, "program", log);
if (prog == NULL) return VSCODE_UNKNOWN_REQUEST;
ravi_string_copy(msg->u.Request.u.LaunchRequest.program, prog,
vscode_string_copy(msg->u.Request.u.LaunchRequest.program, prog,
sizeof msg->u.Request.u.LaunchRequest.program);
fix_path(msg->u.Request.u.LaunchRequest.program);
fprintf(log, "LAUNCH %s\n", prog);
const char *lua_path = get_string_value(args, "LUA_PATH", log);
if (lua_path != NULL)
ravi_string_copy(msg->u.Request.u.LaunchRequest.lua_path, lua_path,
vscode_string_copy(msg->u.Request.u.LaunchRequest.lua_path, lua_path,
sizeof msg->u.Request.u.LaunchRequest.lua_path);
fix_path(msg->u.Request.u.LaunchRequest.lua_path);
const char *lua_cpath = get_string_value(args, "LUA_CPATH", log);
if (lua_cpath != NULL)
ravi_string_copy(msg->u.Request.u.LaunchRequest.lua_cpath, lua_cpath,
vscode_string_copy(msg->u.Request.u.LaunchRequest.lua_cpath, lua_cpath,
sizeof msg->u.Request.u.LaunchRequest.lua_cpath);
fix_path(msg->u.Request.u.LaunchRequest.lua_cpath);
const char *cwd = get_string_value(args, "cwd", log);
if (cwd != NULL)
ravi_string_copy(msg->u.Request.u.LaunchRequest.cwd, cwd,
vscode_string_copy(msg->u.Request.u.LaunchRequest.cwd, cwd,
sizeof msg->u.Request.u.LaunchRequest.cwd);
fix_path(msg->u.Request.u.LaunchRequest.cwd);
msg->u.Request.request_type = msgtype;
@ -325,7 +325,7 @@ static int vscode_parse_set_breakpoints_request(json_value *js,
if (source == NULL) return VSCODE_UNKNOWN_REQUEST;
const char *prog = get_string_value(source, "path", log);
if (prog == NULL) return VSCODE_UNKNOWN_REQUEST;
ravi_string_copy(msg->u.Request.u.SetBreakpointsRequest.source.path, prog,
vscode_string_copy(msg->u.Request.u.SetBreakpointsRequest.source.path, prog,
sizeof msg->u.Request.u.SetBreakpointsRequest.source.path);
fix_path(msg->u.Request.u.SetBreakpointsRequest.source.path);
json_value *breakpoints = get_array_value(args, "breakpoints", log);
@ -367,7 +367,7 @@ static int vscode_parse_request(json_value *js, ProtocolMessage *msg,
if (cmd == NULL) return VSCODE_UNKNOWN_REQUEST;
msg->type = VSCODE_REQUEST;
msg->seq = get_int_value(js, "seq", log, &found);
ravi_string_copy(msg->u.Request.command, cmd, sizeof msg->u.Request.command);
vscode_string_copy(msg->u.Request.command, cmd, sizeof msg->u.Request.command);
fprintf(log, "\nRequest --> '%s'\n", cmd);
int cmdtype = get_cmdtype(msg->u.Request.command);
switch (cmdtype) {
@ -425,11 +425,11 @@ void vscode_make_error_response(ProtocolMessage *req, ProtocolMessage *res,
memset(res, 0, sizeof(ProtocolMessage));
res->seq = seq++;
res->type = VSCODE_RESPONSE;
ravi_string_copy(res->u.Response.command, req->u.Request.command,
vscode_string_copy(res->u.Response.command, req->u.Request.command,
sizeof res->u.Response.command);
res->u.Response.request_seq = req->seq;
res->u.Response.response_type = restype;
ravi_string_copy(res->u.Response.message, errormsg,
vscode_string_copy(res->u.Response.message, errormsg,
sizeof res->u.Response.message);
res->u.Response.success = 0;
}
@ -439,7 +439,7 @@ void vscode_make_success_response(ProtocolMessage *req, ProtocolMessage *res,
memset(res, 0, sizeof(ProtocolMessage));
res->seq = seq++;
res->type = VSCODE_RESPONSE;
ravi_string_copy(res->u.Response.command, req->u.Request.command,
vscode_string_copy(res->u.Response.command, req->u.Request.command,
sizeof res->u.Response.command);
res->u.Response.request_seq = req->seq;
res->u.Response.response_type = restype;
@ -450,7 +450,7 @@ void vscode_make_initialized_event(ProtocolMessage *res) {
memset(res, 0, sizeof(ProtocolMessage));
res->seq = seq++;
res->type = VSCODE_EVENT;
ravi_string_copy(res->u.Event.event, "initialized",
vscode_string_copy(res->u.Event.event, "initialized",
sizeof res->u.Event.event);
res->u.Event.event_type = VSCODE_INITIALIZED_EVENT;
}
@ -460,8 +460,8 @@ static void vscode_make_output_event(ProtocolMessage *res, const char *category,
memset(res, 0, sizeof(ProtocolMessage));
res->seq = seq++;
res->type = VSCODE_EVENT;
ravi_string_copy(res->u.Event.event, "output", sizeof res->u.Event.event);
ravi_string_copy(res->u.Event.u.OutputEvent.category, category,
vscode_string_copy(res->u.Event.event, "output", sizeof res->u.Event.event);
vscode_string_copy(res->u.Event.u.OutputEvent.category, category,
sizeof res->u.Event.u.OutputEvent.category);
vscode_json_stringify(msg, res->u.Event.u.OutputEvent.output,
sizeof res->u.Event.u.OutputEvent.output);
@ -476,9 +476,9 @@ void vscode_make_stopped_event(ProtocolMessage *res, const char *reason) {
res->seq = seq++;
res->type = VSCODE_EVENT;
res->u.Event.event_type = VSCODE_STOPPED_EVENT;
ravi_string_copy(res->u.Event.event, "stopped", sizeof res->u.Event.event);
vscode_string_copy(res->u.Event.event, "stopped", sizeof res->u.Event.event);
res->u.Event.u.StoppedEvent.threadId = 1; /* dummy thread id - always 1 */
ravi_string_copy(res->u.Event.u.StoppedEvent.reason, reason,
vscode_string_copy(res->u.Event.u.StoppedEvent.reason, reason,
sizeof res->u.Event.u.StoppedEvent.reason);
}
@ -490,7 +490,7 @@ void vscode_make_terminated_event(ProtocolMessage *res) {
res->seq = seq++;
res->type = VSCODE_EVENT;
res->u.Event.event_type = VSCODE_TERMINATED_EVENT;
ravi_string_copy(res->u.Event.event, "terminated", sizeof res->u.Event.event);
vscode_string_copy(res->u.Event.event, "terminated", sizeof res->u.Event.event);
res->u.Event.u.TerminatedEvent.restart = 0;
}
@ -502,9 +502,9 @@ void vscode_make_thread_event(ProtocolMessage *res, bool started) {
res->seq = seq++;
res->type = VSCODE_EVENT;
res->u.Event.event_type = VSCODE_THREAD_EVENT;
ravi_string_copy(res->u.Event.event, "thread", sizeof res->u.Event.event);
vscode_string_copy(res->u.Event.event, "thread", sizeof res->u.Event.event);
res->u.Event.u.ThreadEvent.threadId = 1; /* dummy thread id - always 1 */
ravi_string_copy(res->u.Event.u.ThreadEvent.reason,
vscode_string_copy(res->u.Event.u.ThreadEvent.reason,
started ? "started" : "exited",
sizeof res->u.Event.u.ThreadEvent.reason);
}
@ -672,7 +672,7 @@ void vscode_serialize_response(char *buf, size_t buflen, ProtocolMessage *res) {
cp = temp + strlen(temp);
}
snprintf(cp, sizeof temp - strlen(temp), "}");
ravi_string_copy(buf, temp, buflen);
vscode_string_copy(buf, temp, buflen);
}
/*
@ -715,7 +715,7 @@ void vscode_serialize_event(char *buf, size_t buflen, ProtocolMessage *res) {
cp = temp + strlen(temp);
}
snprintf(cp, sizeof temp - strlen(temp), "}");
ravi_string_copy(buf, temp, buflen);
vscode_string_copy(buf, temp, buflen);
}
void vscode_send(ProtocolMessage *msg, FILE *out, FILE *log) {
@ -833,7 +833,7 @@ int vscode_get_request(FILE *in, ProtocolMessage *req, FILE *log) {
}
}
void ravi_string_copy(char *buf, const char *src, size_t buflen) {
void vscode_string_copy(char *buf, const char *src, size_t buflen) {
strncpy(buf, src, buflen);
buf[buflen - 1] = 0;
}

@ -378,6 +378,6 @@ extern int vscode_get_request(FILE *in, ProtocolMessage *req, FILE *log);
extern void vscode_json_stringify(const char *src, char *dest, size_t len);
/* guaranteed null termination */
extern void ravi_string_copy(char *buf, const char *src, size_t buflen);
extern void vscode_string_copy(char *buf, const char *src, size_t buflen);
#endif

@ -27,23 +27,23 @@
/* debugger state */
enum {
DEBUGGER_BIRTH = 1,
DEBUGGER_INITIALIZED = 2,
DEBUGGER_PROGRAM_LAUNCHED = 3,
DEBUGGER_PROGRAM_STEPPING = 4,
DEBUGGER_PROGRAM_RUNNING = 5,
DEBUGGER_PROGRAM_STOPPED = 6,
DEBUGGER_PROGRAM_TERMINATED = 7
DEBUGGER_BIRTH = 1, /* Initial state */
DEBUGGER_INITIALIZED = 2, /* Have processed VSCode initialize request */
DEBUGGER_PROGRAM_LAUNCHED = 3, /* Have processed VSCode launch request - Lua program running */
DEBUGGER_PROGRAM_STEPPING = 4, /* In stepping mode */
DEBUGGER_PROGRAM_RUNNING = 5, /* In continue mode - will stop at breakpoint */
DEBUGGER_PROGRAM_STOPPED = 6, /* Have hit a break point */
DEBUGGER_PROGRAM_TERMINATED = 7 /* Program completed */
};
/* sub states of DEBUGGER_PROGRAM_STEPPING */
enum {
DEBUGGER_STEPPING_IN = 1,
DEBUGGER_STEPPING_OVER = 2, /* next */
DEBUGGER_STEPPING_OUT = 3
DEBUGGER_STEPPING_IN = 1, /* Step into */
DEBUGGER_STEPPING_OVER = 2, /* Step over */
DEBUGGER_STEPPING_OUT = 3 /* Step out of the current function */
};
/* Following must fir into 2 bits and 0 is not a valid value */
/* Following values must fit into 2 bits and 0 is not a valid value */
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
@ -75,8 +75,8 @@ typedef struct {
* evolving this is easier to work with.
*/
static FILE *my_logger = NULL;
static int thread_event_sent = 0;
static int debugger_state = DEBUGGER_BIRTH;
static int thread_event_sent = 0; /* Set to 1 once we have sent a thread event to VSCode */
static int debugger_state = DEBUGGER_BIRTH; /* Debugger's state is tracked in this variable */
static Breakpoint breakpoints[MAX_TOTAL_BREAKPOINTS];
static ProtocolMessage req, res;
static ProtocolMessage output_response;
@ -86,8 +86,8 @@ static SourceOnStack sourceOnStack[MAX_STACK_FRAMES];
static int sourceOnStackCount = 0;
/* Following three are for the three differet stepping modes */
static int stepping_mode = DEBUGGER_STEPPING_IN; /* default */
static int stepping_stacklevel = -1;
static lua_State *stepping_lua_State = NULL;
static int stepping_stacklevel = -1; /* This tracks the stack level from where a step over or step out was requested */
static lua_State *stepping_lua_State = NULL; /* Tracks the Lua State that requested a step over or step out */
/*
* Generate response to InitializeRequest
@ -154,14 +154,15 @@ typedef union {
* 52 bits in size.
*/
static intptr_t ensure_value_fits_in_mantissa(intptr_t sourceReference) {
/* FIXME - big endian support */
int64_t orig = sourceReference;
doublebits bits;
bits.mant = sourceReference;
bits.expo = 0; /* cleanup */
bits.sign = 0; /* cleanup */
sourceReference = bits.i; /* extract mantissa */
fprintf(my_logger, "Source Reference WAS %lld NOW %lld\n", orig,
sourceReference);
fprintf(my_logger, "Source Reference WAS %lld NOW %lld\n", (int64_t)orig,
(int64_t)sourceReference);
return sourceReference;
}
@ -198,12 +199,12 @@ static void handle_stack_trace_request(ProtocolMessage *req,
char name[256];
if (last_path_delim) {
/* source includes a path */
ravi_string_copy(name, last_path_delim + 1, sizeof name);
ravi_string_copy(path, src, sizeof path);
vscode_string_copy(name, last_path_delim + 1, sizeof name);
vscode_string_copy(path, src, sizeof path);
}
else {
/* prepend the working directory to the name */
ravi_string_copy(name, src, sizeof name);
vscode_string_copy(name, src, sizeof name);
if (workingdir[0]) {
size_t n = strlen(workingdir);
if (workingdir[n - 1] == '/')
@ -212,14 +213,14 @@ static void handle_stack_trace_request(ProtocolMessage *req,
snprintf(path, sizeof path, "%s/%s", workingdir, src);
}
else {
ravi_string_copy(path, src, sizeof path);
vscode_string_copy(path, src, sizeof path);
}
}
ravi_string_copy(
vscode_string_copy(
res->u.Response.u.StackTraceResponse.stackFrames[depth].source.path,
path, sizeof res->u.Response.u.StackTraceResponse.stackFrames[depth]
.source.path);
ravi_string_copy(
vscode_string_copy(
res->u.Response.u.StackTraceResponse.stackFrames[depth].source.name,
name, sizeof res->u.Response.u.StackTraceResponse.stackFrames[depth]
.source.name);
@ -228,7 +229,7 @@ static void handle_stack_trace_request(ProtocolMessage *req,
/* C Function so source is not available */
res->u.Response.u.StackTraceResponse.stackFrames[depth]
.source.sourceReference = -1;
ravi_string_copy(
vscode_string_copy(
res->u.Response.u.StackTraceResponse.stackFrames[depth].source.name,
"<C function>",
sizeof res->u.Response.u.StackTraceResponse.stackFrames[depth]
@ -265,7 +266,7 @@ static void handle_stack_trace_request(ProtocolMessage *req,
res->u.Response.u.StackTraceResponse.stackFrames[depth].line =
entry.currentline;
const char *funcname = entry.name ? entry.name : "?";
ravi_string_copy(
vscode_string_copy(
res->u.Response.u.StackTraceResponse.stackFrames[depth].name, funcname,
sizeof res->u.Response.u.StackTraceResponse.stackFrames[depth].name);
depth++;
@ -302,7 +303,7 @@ static void handle_source_request(ProtocolMessage *req, ProtocolMessage *res,
const char *src = entry.source;
if (*src != '@' && *src != '=') {
/* Source is a string */
ravi_string_copy(res->u.Response.u.SourceResponse.content, src,
vscode_string_copy(res->u.Response.u.SourceResponse.content, src,
sizeof res->u.Response.u.SourceResponse.content);
}
else
@ -313,7 +314,7 @@ static void handle_source_request(ProtocolMessage *req, ProtocolMessage *res,
}
else {
l_nosource:
ravi_string_copy(res->u.Response.u.SourceResponse.content,
vscode_string_copy(res->u.Response.u.SourceResponse.content,
"Source not available",
sizeof res->u.Response.u.SourceResponse.content);
}
@ -346,7 +347,7 @@ static void handle_set_breakpoints_request(ProtocolMessage *req,
if (breakpoints[y].source.path[0] == 0 ||
strcmp(breakpoints[y].source.path,
req->u.Request.u.SetBreakpointsRequest.source.path) == 0) {
ravi_string_copy(breakpoints[y].source.path,
vscode_string_copy(breakpoints[y].source.path,
req->u.Request.u.SetBreakpointsRequest.source.path,
sizeof breakpoints[0].source.path);
breakpoints[y].line =
@ -357,7 +358,7 @@ static void handle_set_breakpoints_request(ProtocolMessage *req,
req->u.Request.u.SetBreakpointsRequest.breakpoints[i].line;
res->u.Response.u.SetBreakpointsResponse.breakpoints[k].verified =
false;
ravi_string_copy(
vscode_string_copy(
res->u.Response.u.SetBreakpointsResponse.breakpoints[k]
.source.path,
breakpoints[y].source.path,
@ -398,29 +399,20 @@ static void handle_scopes_request(ProtocolMessage *req, ProtocolMessage *res,
int status = lua_getinfo(L, "u", &entry);
assert(status);
int i = 0;
ravi_string_copy(res->u.Response.u.ScopesResponse.scopes[i].name, "Locals",
vscode_string_copy(res->u.Response.u.ScopesResponse.scopes[i].name, "Locals",
sizeof res->u.Response.u.ScopesResponse.scopes[0].name);
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,
vscode_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",
// sizeof
// res->u.Response.u.ScopesResponse.scopes[0].name);
// res->u.Response.u.ScopesResponse.scopes[i].variablesReference =
// MAKENUM(VAR_TYPE_UPVALUES, depth, 0, 0, 0);
// res->u.Response.u.ScopesResponse.scopes[i++].expensive = 0;
// }
ravi_string_copy(res->u.Response.u.ScopesResponse.scopes[i].name, "Globals",
vscode_string_copy(res->u.Response.u.ScopesResponse.scopes[i].name, "Globals",
sizeof res->u.Response.u.ScopesResponse.scopes[0].name);
res->u.Response.u.ScopesResponse.scopes[i].variablesReference =
MAKENUM(VAR_TYPE_GLOBALS, depth, 0, 0, 0);
@ -541,10 +533,10 @@ static void get_table_values(ProtocolMessage *res, lua_State *L, int stack_idx,
while (lua_next(L, -2) && v < MAX_VARIABLES) {
// stack now contains: -1 => value; -2 => key; -3 => table
if (v+1 == MAX_VARIABLES) {
ravi_string_copy(
vscode_string_copy(
res->u.Response.u.VariablesResponse.variables[v].name, "...",
sizeof res->u.Response.u.VariablesResponse.variables[0].name);
ravi_string_copy(
vscode_string_copy(
res->u.Response.u.VariablesResponse.variables[v].value, "truncated",
sizeof res->u.Response.u.VariablesResponse.variables[0].value);
lua_pop(L, 1); /* pop value */
@ -627,13 +619,13 @@ static void handle_variables_request(ProtocolMessage *req, ProtocolMessage *res,
if (*name == '(') {
char temp[80];
snprintf(temp, sizeof temp, "vararg[%d]", n);
ravi_string_copy(
vscode_string_copy(
res->u.Response.u.VariablesResponse.variables[v].name, temp,
sizeof res->u.Response.u.VariablesResponse.variables[0]
.name);
}
else {
ravi_string_copy(
vscode_string_copy(
res->u.Response.u.VariablesResponse.variables[v].name, name,
sizeof res->u.Response.u.VariablesResponse.variables[0]
.name);
@ -689,6 +681,7 @@ static void handle_variables_request(ProtocolMessage *req, ProtocolMessage *res,
vscode_send(res, out, my_logger);
}
/* Sets values in the Lua global package table such as 'path' and 'cpath' */
static void set_package_var(lua_State *L, const char *key, const char *value) {
lua_getglobal(L, "package");
lua_pushstring(L, value);
@ -726,7 +719,7 @@ static void handle_launch_request(ProtocolMessage *req, ProtocolMessage *res,
return;
}
else {
ravi_string_copy(workingdir, req->u.Request.u.LaunchRequest.cwd,
vscode_string_copy(workingdir, req->u.Request.u.LaunchRequest.cwd,
sizeof workingdir);
}
}
@ -752,6 +745,9 @@ static void handle_launch_request(ProtocolMessage *req, ProtocolMessage *res,
else
debugger_state = DEBUGGER_PROGRAM_RUNNING;
/* Start the Lua code! */
/* From here on the debugger will get control inside the debugger function
which is setup as a Lua hook whenever Lua steps across a new line of
code */
if (lua_pcall(L, 0, 0, 0)) {
char temp[1024];
snprintf(temp, sizeof temp, "Program terminated with error: %s\n",
@ -775,15 +771,15 @@ static void debugger(lua_State *L, lua_Debug *ar, FILE *in, FILE *out) {
stepping_mode == DEBUGGER_STEPPING_OVER))) {
int initialized = 0;
for (int j = 0; j < MAX_BREAKPOINTS; j++) {
/* fast check */
/* fast check - are we on a brekpoint line number */
if (!breakpoints[j].source.path[0] ||
ar->currentline != breakpoints[j].line)
continue;
/* potential match */
/* potential match of breakpoint line - we need to check the source name */
if (!initialized) initialized = lua_getinfo(L, "S", ar);
if (!initialized) break;
if (ar->source[0] == '@') {
/* Only support breakpoints on disk based code */
/* Only support breakpoints on source files */
if (strcmp(breakpoints[j].source.path, ar->source + 1) == 0) {
debugger_state = DEBUGGER_PROGRAM_STEPPING;
stepping_mode = DEBUGGER_STEPPING_IN;
@ -934,7 +930,7 @@ 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);
vscode_string_copy(temp, s, l + 1);
vscode_send_output_event(&output_response, "stdout", temp, stdout, my_logger);
}

Loading…
Cancel
Save