mirror of
https://github.com/kichikuou/xsystem35-sdl2.git
synced 2026-10-04 04:38:03 +03:00
debugger_dap: Support variables and setVariable requests
This commit is contained in:
@@ -323,6 +323,18 @@ const char *dsym_source_line(struct debug_symbols *dsym, int page, int line) {
|
||||
return info->lines[line];
|
||||
}
|
||||
|
||||
int dsym_num_variables(struct debug_symbols *dsym) {
|
||||
if (!dsym)
|
||||
return 0;
|
||||
return dsym->nr_vars;
|
||||
}
|
||||
|
||||
const char *dsym_variable_name(struct debug_symbols *dsym, int i) {
|
||||
if (!dsym || (unsigned)i >= dsym->nr_vars)
|
||||
return NULL;
|
||||
return dsym->variables[i];
|
||||
}
|
||||
|
||||
int dsym_lookup_variable(struct debug_symbols *dsym, const char *name) {
|
||||
if (!dsym || !dsym->variables)
|
||||
return -1;
|
||||
|
||||
@@ -30,6 +30,8 @@ const char *dsym_page2src(struct debug_symbols *dsym, int page);
|
||||
int dsym_line2addr(struct debug_symbols *dsym, int page, int line);
|
||||
int dsym_addr2line(struct debug_symbols *dsym, int page, int addr);
|
||||
const char *dsym_source_line(struct debug_symbols *dsym, int page, int line);
|
||||
int dsym_num_variables(struct debug_symbols *dsym);
|
||||
const char *dsym_variable_name(struct debug_symbols *dsym, int i);
|
||||
int dsym_lookup_variable(struct debug_symbols *dsym, const char *name);
|
||||
const char *dsym_addr2func(struct debug_symbols *dsym, int page, int addr);
|
||||
boolean dsym_func2addr(struct debug_symbols *dsym, const char *name, int *inout_page, int *out_addr);
|
||||
|
||||
+145
-2
@@ -32,10 +32,16 @@
|
||||
#include "debugger_private.h"
|
||||
#include "debug_symbol.h"
|
||||
#include "system.h"
|
||||
#include "nact.h"
|
||||
#include "variable.h"
|
||||
|
||||
#define THREAD_ID 1
|
||||
|
||||
enum VariablesReference {
|
||||
VREF_GLOBALS = 1,
|
||||
VREF_STRINGS,
|
||||
};
|
||||
|
||||
static boolean initialized = false;
|
||||
static char *src_dir;
|
||||
|
||||
@@ -102,6 +108,7 @@ static void cmd_initialize(cJSON *args, cJSON *resp) {
|
||||
cJSON_AddItemToObjectCS(resp, "body", body = cJSON_CreateObject());
|
||||
cJSON_AddBoolToObject(body, "supportsConfigurationDoneRequest", true);
|
||||
cJSON_AddBoolToObject(body, "supportsEvaluateForHovers", true);
|
||||
cJSON_AddBoolToObject(body, "supportsSetVariable", true);
|
||||
}
|
||||
|
||||
static void cmd_launch(cJSON *args, cJSON *resp) {
|
||||
@@ -251,10 +258,142 @@ static void cmd_threads(cJSON *args, cJSON *resp) {
|
||||
}
|
||||
|
||||
static void cmd_scopes(cJSON *args, cJSON *resp) {
|
||||
cJSON *body;
|
||||
cJSON *body, *scopes, *globals, *strings;
|
||||
cJSON_AddBoolToObject(resp, "success", true);
|
||||
cJSON_AddItemToObjectCS(resp, "body", body = cJSON_CreateObject());
|
||||
cJSON_AddItemToObjectCS(body, "scopes", cJSON_CreateArray());
|
||||
cJSON_AddItemToObjectCS(body, "scopes", scopes = cJSON_CreateArray());
|
||||
cJSON_AddItemToArray(scopes, globals = cJSON_CreateObject());
|
||||
cJSON_AddStringToObject(globals, "name", "All Variables");
|
||||
cJSON_AddNumberToObject(globals, "variablesReference", VREF_GLOBALS);
|
||||
cJSON_AddNumberToObject(globals, "namedVariables", dsym_num_variables(symbols));
|
||||
cJSON_AddBoolToObject(globals, "expensive", false);
|
||||
cJSON_AddItemToArray(scopes, strings = cJSON_CreateObject());
|
||||
cJSON_AddStringToObject(strings, "name", "Strings");
|
||||
cJSON_AddNumberToObject(strings, "variablesReference", VREF_STRINGS);
|
||||
cJSON_AddNumberToObject(strings, "indexedVariables", svar_count() + 1);
|
||||
cJSON_AddBoolToObject(strings, "expensive", false);
|
||||
}
|
||||
|
||||
char *format_string_value(const char *str) {
|
||||
char *utf = toUTF8(str);
|
||||
char *new_value = malloc(strlen(utf) + 3);
|
||||
sprintf(new_value, "\"%s\"", utf);
|
||||
free(utf);
|
||||
return new_value;
|
||||
}
|
||||
|
||||
static void cmd_variables(cJSON *args, cJSON *resp) {
|
||||
cJSON *start_ = cJSON_GetObjectItemCaseSensitive(args, "start");
|
||||
cJSON *count_ = cJSON_GetObjectItemCaseSensitive(args, "count");
|
||||
int start = cJSON_IsNumber(start_) ? start_->valueint : 0;
|
||||
int count = cJSON_IsNumber(count_) ? count_->valueint : 65536;
|
||||
|
||||
cJSON *vref = cJSON_GetObjectItemCaseSensitive(args, "variablesReference");
|
||||
if (cJSON_IsNumber(vref) && vref->valueint == VREF_GLOBALS) {
|
||||
cJSON *body, *variables;
|
||||
cJSON_AddBoolToObject(resp, "success", true);
|
||||
cJSON_AddItemToObjectCS(resp, "body", body = cJSON_CreateObject());
|
||||
cJSON_AddItemToObjectCS(body, "variables", variables = cJSON_CreateArray());
|
||||
int end = dsym_num_variables(symbols);
|
||||
if (end > start + count)
|
||||
end = start + count;
|
||||
for (int i = start; i < end; i++) {
|
||||
cJSON *var = cJSON_CreateObject();
|
||||
cJSON_AddItemToArray(variables, var);
|
||||
cJSON_AddStringToObject(var, "name", dsym_variable_name(symbols, i));
|
||||
char value[20];
|
||||
sprintf(value, "%d", sysVar[i]);
|
||||
cJSON_AddStringToObject(var, "value", value);
|
||||
cJSON_AddNumberToObject(var, "variablesReference", 0);
|
||||
}
|
||||
} else if (cJSON_IsNumber(vref) && vref->valueint == VREF_STRINGS) {
|
||||
cJSON *body, *variables;
|
||||
cJSON_AddBoolToObject(resp, "success", true);
|
||||
cJSON_AddItemToObjectCS(resp, "body", body = cJSON_CreateObject());
|
||||
cJSON_AddItemToObjectCS(body, "variables", variables = cJSON_CreateArray());
|
||||
if (start == 0) {
|
||||
start++;
|
||||
count--;
|
||||
}
|
||||
int end = svar_count() + 1;
|
||||
if (end > start + count)
|
||||
end = start + count;
|
||||
for (int i = start; i < end; i++) {
|
||||
char name[20];
|
||||
cJSON *var = cJSON_CreateObject();
|
||||
cJSON_AddItemToArray(variables, var);
|
||||
sprintf(name, "[%d]", i);
|
||||
cJSON_AddStringToObject(var, "name", name);
|
||||
char *value = format_string_value(svar_get(i));
|
||||
cJSON_AddStringToObject(var, "value", value);
|
||||
free(value);
|
||||
cJSON_AddNumberToObject(var, "variablesReference", 0);
|
||||
}
|
||||
} else {
|
||||
cJSON_AddBoolToObject(resp, "success", false);
|
||||
cJSON_AddStringToObject(resp, "message", "invalid variablesReference");
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_setVariable(cJSON *args, cJSON *resp) {
|
||||
cJSON *name = cJSON_GetObjectItemCaseSensitive(args, "name");
|
||||
cJSON *value = cJSON_GetObjectItemCaseSensitive(args, "value");
|
||||
if (!cJSON_IsString(name) || !cJSON_IsString(value)) {
|
||||
cJSON_AddBoolToObject(resp, "success", false);
|
||||
cJSON_AddStringToObject(resp, "message", "invalid arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
cJSON *vref = cJSON_GetObjectItemCaseSensitive(args, "variablesReference");
|
||||
if (cJSON_IsNumber(vref) && vref->valueint == VREF_GLOBALS) {
|
||||
int var = dbg_lookup_var(name->valuestring);
|
||||
if (var < 0) {
|
||||
cJSON_AddBoolToObject(resp, "success", false);
|
||||
cJSON_AddStringToObject(resp, "message", "invalid variable name");
|
||||
return;
|
||||
}
|
||||
int parsed_value;
|
||||
if (sscanf(value->valuestring, "%i", &parsed_value) != 1) {
|
||||
cJSON_AddBoolToObject(resp, "success", false);
|
||||
cJSON_AddStringToObject(resp, "message", "syntax error");
|
||||
return;
|
||||
}
|
||||
sysVar[var] = parsed_value & 0xffff;
|
||||
|
||||
cJSON *body;
|
||||
cJSON_AddBoolToObject(resp, "success", true);
|
||||
cJSON_AddItemToObjectCS(resp, "body", body = cJSON_CreateObject());
|
||||
char new_value[20];
|
||||
sprintf(new_value, "%d", sysVar[var]);
|
||||
cJSON_AddStringToObject(body, "value", new_value);
|
||||
} else if (cJSON_IsNumber(vref) && vref->valueint == VREF_STRINGS) {
|
||||
int idx;
|
||||
if (sscanf(name->valuestring, "[%d]", &idx) != 1 || idx < 1 || idx > svar_count()) {
|
||||
cJSON_AddBoolToObject(resp, "success", false);
|
||||
cJSON_AddStringToObject(resp, "message", "invalid string index");
|
||||
return;
|
||||
}
|
||||
int len = strlen(value->valuestring);
|
||||
if (len < 2 || value->valuestring[0] != '"' || value->valuestring[len-1] != '"') {
|
||||
cJSON_AddBoolToObject(resp, "success", false);
|
||||
cJSON_AddStringToObject(resp, "message", "syntax error");
|
||||
return;
|
||||
}
|
||||
value->valuestring[len-1] = '\0';
|
||||
char *str = fromUTF8(value->valuestring + 1);
|
||||
svar_set(idx, str);
|
||||
free(str);
|
||||
|
||||
cJSON *body;
|
||||
cJSON_AddBoolToObject(resp, "success", true);
|
||||
cJSON_AddItemToObjectCS(resp, "body", body = cJSON_CreateObject());
|
||||
char *new_value = format_string_value(svar_get(idx));
|
||||
cJSON_AddStringToObject(body, "value", new_value);
|
||||
free(new_value);
|
||||
} else {
|
||||
cJSON_AddBoolToObject(resp, "success", false);
|
||||
cJSON_AddStringToObject(resp, "message", "invalid variablesReference");
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_disconnect(cJSON *args, cJSON *resp) {
|
||||
@@ -311,6 +450,10 @@ static boolean handle_request(cJSON *request) {
|
||||
cmd_threads(args, resp);
|
||||
} else if (!strcmp(command->valuestring, "scopes")) {
|
||||
cmd_scopes(args, resp);
|
||||
} else if (!strcmp(command->valuestring, "variables")) {
|
||||
cmd_variables(args, resp);
|
||||
} else if (!strcmp(command->valuestring, "setVariable")) {
|
||||
cmd_setVariable(args, resp);
|
||||
} else if (!strcmp(command->valuestring, "disconnect")) {
|
||||
cmd_disconnect(args, resp);
|
||||
} else {
|
||||
|
||||
@@ -111,6 +111,10 @@ extern void svar_init(int cnt, int len) {
|
||||
strvar_len = len;
|
||||
}
|
||||
|
||||
extern int svar_count(void) {
|
||||
return strvar_cnt;
|
||||
}
|
||||
|
||||
/* 変数の初期化 */
|
||||
extern boolean v_initVars() {
|
||||
strVar = calloc(STRVAR_MAX, sizeof(char *));
|
||||
|
||||
@@ -59,6 +59,7 @@ extern boolean v_getArrayBufferStatus(int page);
|
||||
extern boolean v_initVars();
|
||||
|
||||
extern void svar_init(int cnt, int len);
|
||||
extern int svar_count(void);
|
||||
extern const char *svar_get(int no);
|
||||
extern void svar_set(int no, const char *str);
|
||||
extern void svar_copy(int dstno, int dstpos, int srcno, int srcpos, int len);
|
||||
|
||||
Reference in New Issue
Block a user