[qwaq] Move local defs viewer to its own class

While trying to build a view without deriving from it was a neat idea,
it doesn't work so well because a view really needs to know how to draw
itself. This even fixes the segfault when stepping past the end of the
program.
This commit is contained in:
Bill Currie 2020-03-30 13:42:31 +09:00
parent 1c13339bbe
commit 6d3fadfe6e
5 changed files with 171 additions and 125 deletions

View file

@ -29,6 +29,7 @@ qwaq_app_dat_src= \
qwaq-app.r \
debugger/debug.r \
debugger/debugger.r \
debugger/localsview.r \
debugger/typeencodings.r \
editor/editbuffer.r \
editor/editor.r \

View file

@ -5,6 +5,7 @@
#include <Object.h>
#include "debugger/debug.h"
#include "debugger/localsview.h"
@class ProxyView;
@class Editor;
@ -14,7 +15,6 @@
@interface Debugger : Object
{
qdb_target_t target;
qfot_type_encodings_t target_encodings;
Window *source_window;
ProxyView *file_proxy;
@ -22,13 +22,7 @@
Editor *current_file;
Window *locals_window;
View *locals_view;
unsigned current_fnum;
qdb_function_t *func;
qdb_auxfunction_t *aux_func;
qdb_def_t *local_defs;
void *local_data;
LocalsView *locals_view;
}
-(qdb_target_t)target;
-initWithTarget:(qdb_target_t) target;

View file

@ -29,9 +29,6 @@
source_window = [[Window alloc] initWithRect: {nil, [application size]}];
[application addView:source_window];
qdb_def_t encodings_def = qdb_find_global (target, ".type_encodings");
qdb_get_data (target, encodings_def.offset, sizeof(target_encodings),
&target_encodings);
return self;
}
@ -68,9 +65,8 @@
locals_window = [[Window alloc] initWithRect: {{0, 0}, {40, 10}}];
[locals_window setBackground: color_palette[064]];
[locals_window setTitle: "Locals"];
locals_view = [[View alloc] initWithRect: {{1, 1}, {38, 8}}
options: ofCanFocus];
[locals_view setGrowMode:gfGrowHi];
locals_view = [[LocalsView alloc] initWithRect: {{1, 1}, {38, 8}}
target: target];
[locals_window insertSelected: locals_view];
[application addView: locals_window];
@ -94,120 +90,11 @@
[source_window redraw];
}
static void
update_current_func (Debugger *self, unsigned fnum)
{
self.current_fnum = fnum;
if (self.aux_func) {
obj_free (self.aux_func);
self.aux_func = nil;
}
if (self.local_defs) {
obj_free (self.local_defs);
}
if (self.local_data) {
obj_free (self.local_data);
}
self.func = qdb_get_function (self.target, fnum);
self.aux_func = qdb_get_auxfunction (self.target, fnum);
if (self.aux_func) {
self.local_defs = qdb_get_local_defs (self.target, fnum);
}
if (self.func) {
self.local_data = obj_malloc (self.func.local_size);
}
}
-(void)update_watchvars
{
qdb_state_t state = qdb_get_state (target);
if (state.func != current_fnum) {
update_current_func (self, state.func);
}
if (!local_data) {
return;
}
qdb_get_data (target, func.local_data, func.local_size, local_data);
[locals_view clear];
if (!local_defs) {
[locals_view mvprintf:{0,0}, "%d", func.local_size];
for (int y = 1; y < [locals_view size].height; y++) {
unsigned ind = (y - 1) * 4;
if (ind < func.local_size) {
[locals_view mvprintf:{0, y}, "%02x", ind];
for (int x = 0; x < 4 && ind < func.local_size; x++, ind++) {
[locals_view mvprintf:{x * 9 + 3, y}, "%08x",
local_data[ind]];
}
} else {
break;
}
}
} else {
for (int y = 0; y < [locals_view size].height; y++) {
if (y >= aux_func.num_locals) {
break;
}
qdb_def_t *def = local_defs + y;
unsigned te = def.type_encoding + (int) target_encodings.types;
qfot_type_t *type;
type = [TypeEncodings getType:te fromTarget:target];
[locals_view mvprintf:{0, y}, "%s",
qdb_get_string (target, def.name)];
@param value = nil;
string valstr = "--";
unsigned offset = func.local_data + def.offset;
printf ("%d %d %s %d\n", def.type_size, offset,
qdb_get_string (target, def.name),
def.type_encoding);
qdb_get_data (target, offset, def.type_size >> 16, &value);
switch (def.type_size & 0xffff) {
case ev_void:
case ev_invalid:
case ev_type_count:
break;
case ev_string:
valstr = qdb_get_string (target, value.integer_val);
break;
case ev_float:
valstr = sprintf ("%.9g", value.float_val);
break;
case ev_vector:
valstr = sprintf ("%.9v", value.vector_val);
break;
case ev_entity:
valstr = sprintf ("%e", value.entity_val);
break;
case ev_field:
valstr = sprintf ("[%x]", value.field_val);
break;
case ev_func:
valstr = sprintf ("[%x]", value.func_val);
break;
case ev_pointer:
valstr = sprintf ("[%x]", value.pointer_val);
break;
case ev_quat:
valstr = sprintf ("[%q]", value.quaternion_val);
break;
case ev_integer:
valstr = sprintf ("%d", value.integer_val);
break;
case ev_uinteger:
valstr = sprintf ("%d", value.integer_val);
break;
case ev_short:
valstr = sprintf ("%d", value.integer_val);
break;
case ev_double:
valstr = sprintf ("%.17g", value.double_val);
break;
}
int x = [locals_view size].width - strlen (valstr);
[locals_view mvaddstr:{x, y}, valstr];
}
}
[TextContext refresh];
[locals_view setFunction:state.func];
[locals_view redraw];
}
static int

View file

@ -0,0 +1,22 @@
#ifndef __qwaq_debugger_localsview_h
#define __qwaq_debugger_localsview_h
#include <types.h>
#include "ui/view.h"
#include "debugger/debug.h"
@interface LocalsView : View
{
qdb_target_t target;
qfot_type_encodings_t target_encodings;
unsigned current_fnum;
qdb_function_t *func;
qdb_auxfunction_t *aux_func;
qdb_def_t *defs;
void *data;
}
-initWithRect:(Rect)rect target:(qdb_target_t) target;
-setFunction:(unsigned) fnum;
@end
#endif

View file

@ -0,0 +1,142 @@
#include <string.h>
#include <types.h>
#include "debugger/localsview.h"
#include "debugger/typeencodings.h"
@implementation LocalsView
-initWithRect:(Rect)rect target:(qdb_target_t) target
{
if (!(self = [super initWithRect:rect])) {
return nil;
}
options = ofCanFocus;
growMode = gfGrowHi;
self.target = target;
qdb_def_t encodings_def = qdb_find_global (target, ".type_encodings");
qdb_get_data (target, encodings_def.offset, sizeof(target_encodings),
&target_encodings);
return self;
}
-setFunction:(unsigned) fnum
{
if (current_fnum == fnum) {
return self;
}
current_fnum =fnum;
if (defs) {
obj_free (defs);
defs = nil;
}
if (data) {
obj_free (data);
data = nil;
}
func = qdb_get_function (target, fnum);
aux_func = qdb_get_auxfunction (target, fnum);
if (aux_func) {
defs = qdb_get_local_defs (target, fnum);
}
if (func) {
data = obj_malloc (func.local_size);
}
return self;
}
-draw
{
[super draw];
if (!data) {
return self;
}
qdb_get_data (target, func.local_data, func.local_size, data);
[self clear];
if (!defs) {
[self mvprintf:{0,0}, "%d", func.local_size];
for (int y = 1; y < ylen; y++) {
unsigned ind = (y - 1) * 4;
if (ind < func.local_size) {
[self mvprintf:{0, y}, "%02x", ind];
for (int x = 0; x < 4 && ind < func.local_size; x++, ind++) {
[self mvprintf:{x * 9 + 3, y}, "%08x",
data[ind]];
}
} else {
break;
}
}
} else {
for (int y = 0; y < ylen; y++) {
if (y >= aux_func.num_locals) {
break;
}
qdb_def_t *def = defs + y;
unsigned te = def.type_encoding + (int) target_encodings.types;
qfot_type_t *type;
type = [TypeEncodings getType:te fromTarget:target];
[self mvprintf:{0, y}, "%s",
qdb_get_string (target, def.name)];
@param value = nil;
string valstr = "--";
unsigned offset = func.local_data + def.offset;
printf ("%d %d %s %d\n", def.type_size, offset,
qdb_get_string (target, def.name),
def.type_encoding);
qdb_get_data (target, offset, def.type_size >> 16, &value);
switch (def.type_size & 0xffff) {
case ev_void:
case ev_invalid:
case ev_type_count:
break;
case ev_string:
valstr = qdb_get_string (target, value.integer_val);
break;
case ev_float:
valstr = sprintf ("%.9g", value.float_val);
break;
case ev_vector:
valstr = sprintf ("%.9v", value.vector_val);
break;
case ev_entity:
valstr = sprintf ("%e", value.entity_val);
break;
case ev_field:
valstr = sprintf ("[%x]", value.field_val);
break;
case ev_func:
valstr = sprintf ("[%x]", value.func_val);
break;
case ev_pointer:
valstr = sprintf ("[%x]", value.pointer_val);
break;
case ev_quat:
valstr = sprintf ("[%q]", value.quaternion_val);
break;
case ev_integer:
valstr = sprintf ("%d", value.integer_val);
break;
case ev_uinteger:
valstr = sprintf ("%d", value.integer_val);
break;
case ev_short:
valstr = sprintf ("%d", value.integer_val);
break;
case ev_double:
valstr = sprintf ("%.17g", value.double_val);
break;
}
int x = xlen - strlen (valstr);
[self mvaddstr:{x, y}, valstr];
}
}
return self;
}
@end