diff --git a/vscode-debugger/src/protocol.c b/vscode-debugger/src/protocol.c index 3902a85..3334bfe 100644 --- a/vscode-debugger/src/protocol.c +++ b/vscode-debugger/src/protocol.c @@ -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; } \ No newline at end of file diff --git a/vscode-debugger/src/protocol.h b/vscode-debugger/src/protocol.h index 20dc27f..b5fb9cb 100644 --- a/vscode-debugger/src/protocol.h +++ b/vscode-debugger/src/protocol.h @@ -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 \ No newline at end of file diff --git a/vscode-debugger/src/ravidebug.c b/vscode-debugger/src/ravidebug.c index a2e6d7c..31f6eb6 100644 --- a/vscode-debugger/src/ravidebug.c +++ b/vscode-debugger/src/ravidebug.c @@ -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, "", 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); }