[qwaq] Implement more debugger def views

Structs and arrays now work (though could be better, eg collapsible).
This commit is contained in:
Bill Currie 2021-09-25 01:42:36 +09:00
parent 7ed12e2f37
commit 0a60f46a64
20 changed files with 448 additions and 6 deletions

View file

@ -16,6 +16,7 @@ ruamoko_qwaq_libui_a_SOURCES= \
ruamoko/qwaq/ui/proxyview.r \
ruamoko/qwaq/ui/rect.r \
ruamoko/qwaq/ui/scrollbar.r \
ruamoko/qwaq/ui/stringview.r \
ruamoko/qwaq/ui/tableview.r \
ruamoko/qwaq/ui/textcontext.r \
ruamoko/qwaq/ui/titlebar.r \
@ -29,6 +30,7 @@ r_depfiles_remade += $(ruamoko_qwaq_libui_a_dep)
qwaq_app_dat_src= \
ruamoko/qwaq/qwaq-app.r \
ruamoko/qwaq/debugger/views/arrayview.r \
ruamoko/qwaq/debugger/views/basicview.r \
ruamoko/qwaq/debugger/views/defview.r \
ruamoko/qwaq/debugger/views/doubleview.r \
@ -36,11 +38,13 @@ qwaq_app_dat_src= \
ruamoko/qwaq/debugger/views/fieldview.r \
ruamoko/qwaq/debugger/views/floatview.r \
ruamoko/qwaq/debugger/views/funcview.r \
ruamoko/qwaq/debugger/views/indexview.r \
ruamoko/qwaq/debugger/views/intview.r \
ruamoko/qwaq/debugger/views/nameview.r \
ruamoko/qwaq/debugger/views/pointerview.r\
ruamoko/qwaq/debugger/views/quatview.r \
ruamoko/qwaq/debugger/views/stringview.r \
ruamoko/qwaq/debugger/views/structview.r \
ruamoko/qwaq/debugger/views/uintview.r \
ruamoko/qwaq/debugger/views/vectorview.r \
ruamoko/qwaq/debugger/views/voidview.r \

View file

@ -601,7 +601,7 @@ cmd_mvwvline (qwaq_resources_t *res)
static void
dump_command (qwaq_resources_t *res, int len)
{
if (1) {
if (0) {
qwaq_commands cmd = qwaq_cmd_peek (res, 0);
Sys_Printf ("%s[%d]", qwaq_command_names[cmd], len);
if (cmd == qwaq_cmd_syncprint) {

View file

@ -301,7 +301,11 @@ qdb_get_state (progs_t *pr)
string_t file = 0;
unsigned line = 0;
unsigned staddr = tpr->pr_xstatement;
func_t func = tpr->pr_xfunction - tpr->function_table;
func_t func = 0;
if (tpr->pr_xfunction) {
func = tpr->pr_xfunction - tpr->function_table;
}
lineno = PR_Find_Lineno (tpr, staddr);
if (lineno) {
@ -458,6 +462,18 @@ qdb_get_file_path (progs_t *pr)
}
}
static void
qdb_find_string (progs_t *pr)
{
__auto_type debug = PR_Resources_Find (pr, "qwaq-debug");
pointer_t handle = P_INT (pr, 0);
qwaq_target_t *target = get_target (debug, __FUNCTION__, handle);
progs_t *tpr = target->pr;
const char *str = P_GSTRING (pr, 1);
R_INT (pr) = PR_FindString (tpr, str);
}
static void
qdb_find_global (progs_t *pr)
{
@ -648,6 +664,7 @@ static builtin_t builtins[] = {
{"qdb_get_string|{tag qdb_target_s=}i", qdb_get_string, -1},
{"qdb_get_string|{tag qdb_target_s=}*", qdb_get_string, -1},
{"qdb_get_file_path", qdb_get_file_path, -1},
{"qdb_find_string", qdb_find_string, -1},
{"qdb_find_global", qdb_find_global, -1},
{"qdb_find_field", qdb_find_field, -1},
{"qdb_find_function", qdb_find_function, -1},

View file

@ -754,7 +754,7 @@ cmd_get_device_info (qwaq_input_resources_t *res)
static void
dump_command (qwaq_input_resources_t *res, int len)
{
if (1) {
if (0) {
qwaq_input_commands cmd = qwaq_cmd_peek (res, 0);
Sys_Printf ("%s[%d]", qwaq_input_command_names[cmd], len);
for (int i = 2; i < len; i++) {

View file

@ -92,7 +92,7 @@ qwaq_pipe_submit (qwaq_pipe_t *pipe, const int *cmd, unsigned len)
void
qwaq_pipe_receive (qwaq_pipe_t *pipe, int *result, int cmd, unsigned len)
{
Sys_Printf ("qwaq_wait_result: %d %d\n", cmd, len);
//Sys_Printf ("qwaq_wait_result: %d %d\n", cmd, len);
pthread_mutex_lock (&pipe->pipe_cond.mut);
while (RB_DATA_AVAILABLE (pipe->pipe) < len
|| *RB_PEEK_DATA (pipe->pipe, 0) != cmd) {
@ -102,7 +102,7 @@ qwaq_pipe_receive (qwaq_pipe_t *pipe, int *result, int cmd, unsigned len)
RB_READ_DATA (pipe->pipe, result, len);
pthread_cond_broadcast (&pipe->pipe_cond.wcond);
pthread_mutex_unlock (&pipe->pipe_cond.mut);
Sys_Printf ("qwaq_wait_result exit: %d %d\n", cmd, len);
//Sys_Printf ("qwaq_wait_result exit: %d %d\n", cmd, len);
}
void

View file

@ -88,6 +88,7 @@ int qdb_get_data (qdb_target_t target, unsigned src, unsigned len, void *dst);
// avoid cast shenanigans when getting type encoding strings
@overload string qdb_get_string (qdb_target_t target, string str);
string qdb_get_file_path (qdb_target_t target, string file);
int qdb_find_string (qdb_target_t target, string str);
qdb_def_t qdb_find_global (qdb_target_t target, string name);
qdb_def_t qdb_find_field (qdb_target_t target, string name);
qdb_function_t *qdb_find_function (qdb_target_t target, string name);

View file

@ -18,6 +18,7 @@ int qdb_get_data (qdb_target_t target, unsigned src, unsigned len,
string qdb_get_string (qdb_target_t target, unsigned str) = #0;
string qdb_get_string (qdb_target_t target, string str) = #0;
string qdb_get_file_path (qdb_target_t target, string file) = #0;
int qdb_find_string (qdb_target_t target, string str) = #0;
qdb_def_t qdb_find_global (qdb_target_t target, string name) = #0;
qdb_def_t qdb_find_field (qdb_target_t target, string name) = #0;
qdb_function_t *qdb_find_function (qdb_target_t target, string name) = #0;

View file

@ -0,0 +1,15 @@
#ifndef __qwaq_debugger_arrayructview_h
#define __qwaq_debugger_arrayructview_h
#include "ruamoko/qwaq/debugger/views/defview.h"
@interface ArrayView : DefView
{
unsigned *data;
DefView **element_views;
int *element_rows;
}
+(ArrayView *)withDef:(qdb_def_t)def in:(void *)data type:(qfot_type_t *)type;
@end
#endif//__qwaq_debugger_arrayructview_h

View file

@ -0,0 +1,115 @@
#include <string.h>
#include <stdlib.h>
#include "ruamoko/qwaq/debugger/typeencodings.h"
#include "ruamoko/qwaq/debugger/views/indexview.h"
#include "ruamoko/qwaq/debugger/views/nameview.h"
#include "ruamoko/qwaq/debugger/views/arrayview.h"
#include "ruamoko/qwaq/ui/tableview.h"
@implementation ArrayView
-initWithDef:(qdb_def_t)def in:(void *)data type:(qfot_type_t *)type
{
if (!(self = [super initWithDef:def type:type])) {
return nil;
}
self.data = (unsigned *)(data + def.offset);
element_views = obj_malloc (type.array.size);
element_rows = obj_malloc (type.array.size);
element_rows[0] = 0;
qfot_type_t *element_type = type.array.type;
int element_size = [TypeEncodings typeSize:element_type];
for (int i = 0; i < type.array.size; i++) {
qdb_def_t def = {
0, // XXX type/size not needed at this stage
i * element_size,
0, // filled in by setTarget
(unsigned)type.fldptr.aux_type
};
element_views[i] = [[DefView withDef:def
type:element_type
in:data
target:target] retain];
element_rows[i + 1] = [element_views[i] rows];
}
prefixsum (element_rows, type.array.size + 1);
return self;
}
+(ArrayView *)withDef:(qdb_def_t)def in:(void *)data type:(qfot_type_t *)type
{
return [[[self alloc] initWithDef:def in:data type:type] autorelease];
}
-setTarget:(qdb_target_t)target
{
[super setTarget:target];
for (int i = 0; i < type.array.size; i++) {
[element_views[i] setTarget:target];
}
return self;
}
-(void)dealloc
{
for (int i = 0; i < type.array.size; i++) {
[element_views[i] release];
}
obj_free (element_views);
obj_free (element_rows);
}
-draw
{
[super draw];
string val = sprintf ("%s[%d..%d]", type.array.type.encoding,
type.array.base,
type.array.base + type.array.size - 1);
[self mvprintf:{0, 0}, "%*.*s", xlen, xlen, val];
return self;
}
-fetchData
{
[super fetchData];
element_rows[0] = 0;
for (int i = 0; i < type.array.size; i++) {
[element_views[i] fetchData];
element_rows[i + 1] = [element_views[i] rows];
}
prefixsum (element_rows, type.array.size + 1);
return self;
}
-(int) rows
{
return 1 + element_rows[type.array.size];
}
-(View *) viewAtRow:(int)row forColumn:(TableViewColumn *)column
{
if (row == 0) {
if ([column name] == "name") {
return [NameView withName:qdb_get_string (target, def.name)];
}
return self;
}
row -= 1;
View *view = nil;
int *index = fbsearch (&row, element_rows, type.array.size, 1, nil);
if ([column name] == "name") {
return [IndexView withIndex:index - element_rows + type.array.base];
}
if (index) {
DefView *dv = element_views[index - element_rows];
int r = row - *index;
view = [dv viewAtRow: r forColumn:column];
}
return view;
}
@end

View file

@ -17,6 +17,7 @@
+(DefView *)withDef:(qdb_def_t)def in:(void *)data target:(qdb_target_t)target;
+(DefView *)withDef:(qdb_def_t)def type:(qfot_type_t *)type in:(void *)data target:(qdb_target_t)target;
-initWithDef:(qdb_def_t)def type:(qfot_type_t *)type;
-setTarget:(qdb_target_t)target;
-fetchData;
-(int) rows;
-(View *) viewAtRow:(int) row forColumn:(TableViewColumn *)column;

View file

@ -7,7 +7,7 @@
static string meta_views[] = {
"BasicView",
"StructView",
"UnionView",
"StructView",
"EnumView",
"ArrayView",
"ClassView",

View file

@ -0,0 +1,13 @@
#ifndef __qwaq_debugger_indexview_h
#define __qwaq_debugger_indexview_h
#include "ruamoko/qwaq/debugger/views/defview.h"
@interface IndexView : DefView
{
int index;
}
+(IndexView *)withIndex:(int)index;
@end
#endif//__qwaq_debugger_indexview_h

View file

@ -0,0 +1,33 @@
#include <string.h>
#include "ruamoko/qwaq/debugger/views/indexview.h"
@implementation IndexView
-initWithIndex:(int)index
{
if (!(self = [super initWithDef:def type:nil])) {
return nil;
}
self.index = index;
return self;
}
+(IndexView *)withIndex:(int)index
{
return [[[self alloc] initWithIndex:index] autorelease];
}
-draw
{
[super draw];
string val = sprintf ("[%d]", index);
[self mvprintf:{0, 0}, "%*.*s", xlen, xlen, val];
return self;
}
-(View *) viewAtRow:(int) row forColumn:(TableViewColumn *)column
{
return self;
}
@end

View file

@ -30,4 +30,9 @@
return self;
}
-(View *) viewAtRow:(int) row forColumn:(TableViewColumn *)column
{
return self;
}
@end

View file

@ -0,0 +1,15 @@
#ifndef __qwaq_debugger_structview_h
#define __qwaq_debugger_structview_h
#include "ruamoko/qwaq/debugger/views/defview.h"
@interface StructView : DefView
{
unsigned *data;
DefView **field_views;
int *field_rows;
}
+(StructView *)withDef:(qdb_def_t)def in:(void *)data type:(qfot_type_t *)type;
@end
#endif//__qwaq_debugger_structview_h

View file

@ -0,0 +1,119 @@
#include <string.h>
#include <stdlib.h>
#include "ruamoko/qwaq/debugger/typeencodings.h"
#include "ruamoko/qwaq/debugger/views/nameview.h"
#include "ruamoko/qwaq/debugger/views/structview.h"
#include "ruamoko/qwaq/ui/tableview.h"
@implementation StructView
-initWithDef:(qdb_def_t)def in:(void *)data type:(qfot_type_t *)type
{
if (!(self = [super initWithDef:def type:type])) {
return nil;
}
self.data = (unsigned *)(data + def.offset);
field_views = obj_malloc (type.strct.num_fields);
field_rows = obj_malloc (type.strct.num_fields);
field_rows[0] = 0;
for (int i = 0; i < type.strct.num_fields; i++) {
qfot_type_t *field_type = type.strct.fields[i].type;
qdb_def_t def = {
0, // XXX type/size not needed at this stage
type.strct.fields[i].offset,
0, // filled in by setTarget
(unsigned)type.fldptr.aux_type
};
field_views[i] = [[DefView withDef:def
type:field_type
in:data
target:target] retain];
field_rows[i + 1] = 0;
if (str_mid (type.strct.fields[i].name, 0, 11) != ".anonymous.") {
field_rows[i + 1] = [field_views[i] rows];
}
}
prefixsum (field_rows, type.strct.num_fields + 1);
return self;
}
+(StructView *)withDef:(qdb_def_t)def in:(void *)data type:(qfot_type_t *)type
{
return [[[self alloc] initWithDef:def in:data type:type] autorelease];
}
-setTarget:(qdb_target_t)target
{
[super setTarget:target];
for (int i = 0; i < type.strct.num_fields; i++) {
if (target.handle) {
// the field name is already in local space because the same type
// may be defined in both progs
string name = type.strct.fields[i].name;
field_views[i].def.name = qdb_find_string (target, name);
}
[field_views[i] setTarget:target];
}
return self;
}
-(void)dealloc
{
for (int i = 0; i < type.strct.num_fields; i++) {
[field_views[i] release];
}
obj_free (field_views);
obj_free (field_rows);
}
-draw
{
[super draw];
string val = sprintf ("%s", type.strct.tag);
[self mvprintf:{0, 0}, "%*.*s", xlen, xlen, val];
return self;
}
-fetchData
{
[super fetchData];
field_rows[0] = 0;
for (int i = 0; i < type.strct.num_fields; i++) {
[field_views[i] fetchData];
field_rows[i + 1] = 0;
if (str_mid (type.strct.fields[i].name, 0, 11) != ".anonymous.") {
field_rows[i + 1] = [field_views[i] rows];
}
}
prefixsum (field_rows, type.strct.num_fields + 1);
return self;
}
-(int) rows
{
return 1 + field_rows[type.strct.num_fields];
}
-(View *) viewAtRow:(int) row forColumn:(TableViewColumn *)column
{
if (row == 0) {
if ([column name] == "name") {
return [NameView withName:qdb_get_string (target, def.name)];
}
return self;
}
row -= 1;
View *view = nil;
int *index = fbsearch (&row, field_rows, type.strct.num_fields, 1, nil);
if (index) {
DefView *dv = field_views[index - field_rows];
int r = row - *index;
view = [dv viewAtRow: r forColumn:column];
}
return view;
}
@end

View file

@ -0,0 +1,13 @@
#ifndef __qwaq_debugger_nameview_h
#define __qwaq_debugger_nameview_h
#include "ruamoko/qwaq/debugger/views/defview.h"
@interface NameView : DefView
{
string name;
}
+(NameView *)withName:(string)name;
@end
#endif//__qwaq_debugger_nameview_h

View file

@ -0,0 +1,33 @@
#include <string.h>
#include "ruamoko/qwaq/debugger/views/nameview.h"
@implementation NameView
-initWithName:(string)name
{
if (!(self = [super initWithDef:def type:nil])) {
return nil;
}
self.name = name;
return self;
}
-(void)dealloc
{
str_free (name);
[super dealloc];
}
+(NameView *)withName:(string)name
{
return [[[self alloc] initWithName:name] autorelease];
}
-draw
{
[super draw];
[self mvaddstr:{0, 0}, str_mid (name, 0, xlen)];
return self;
}
@end

View file

@ -0,0 +1,15 @@
#ifndef __qwaq_ui_stringview_h
#define __qwaq_ui_stringview_h
#include "ruamoko/qwaq/ui/view.h"
@interface StringView : View
{
string str;
}
+(StringView *)withRect:(Rect)rect;
+(StringView *)withRect:(Rect)rect string:(string)str;
-setString:(string)newString;
@end
#endif//__qwaq_ui_stringview_h

View file

@ -0,0 +1,42 @@
#include <string.h>
#include "ruamoko/qwaq/ui/group.h"
#include "ruamoko/qwaq/ui/stringview.h"
@implementation StringView
-initWithRect:(Rect)rect string:(string)str
{
if (!(self = [super initWithRect:rect])) {
return nil;
}
self.str = str;
growMode = gfGrowHiX;
return self;
}
+(StringView *)withRect:(Rect)rect
{
return [[[self alloc] initWithRect:rect string:nil] autorelease];
}
+(StringView *)withRect:(Rect)rect string:(string)str
{
return [[[self alloc] initWithRect:rect string:str] autorelease];
}
-setString:(string) newTitle
{
str = newTitle;
[self redraw];
return self;
}
-draw
{
[super draw];
[self mvaddstr: { 0, 0}, str];
return self;
}
@end