#include "debugtree.hpp" #include "prefs.hpp" #include "stdafx.hpp" //#include "basic.hpp" IMPLEMENT_DYNAMIC(DebugTree, CTreeCtrl) BEGIN_MESSAGE_MAP(DebugTree, CTreeCtrl) ON_WM_CREATE() END_MESSAGE_MAP() DebugTree::DebugTree() : st_nest(0) {} DebugTree::~DebugTree() {} int DebugTree::OnCreate(LPCREATESTRUCT lpCreateStruct) { CTreeCtrl::OnCreate(lpCreateStruct); SetBkColor(prefs.rgb_bkgrnd); SetTextColor(prefs.rgb_default); SetFont(&prefs.debugFont); return 0; } static string typeTag(Type* t) { if (t->intType()) return ""; if (t->floatType()) return "#"; if (t->stringType()) return "$"; if (StructType* s = t->structType()) return "." + s->ident; if (VectorType* v = t->vectorType()) { string s = typeTag(v->elementType) + "["; for (int k = 0; k < v->sizes.size(); ++k) { if (k) s += ","; s += itoa(v->sizes[k] - 1); } return s + "]"; } return ""; } HTREEITEM DebugTree::insertVar(void* var, Decl* d, const string& name, HTREEITEM it, HTREEITEM parent) { string s = name; ConstType* ct = d->type->constType(); StructType* st = d->type->structType(); VectorType* vt = d->type->vectorType(); if (ct) { Type* t = ct->valueType; s += typeTag(t); if (t->intType()) { s += "=" + itoa(ct->intValue); } else if (t->floatType()) { s += "=" + ftoa(ct->floatValue); } else if (t->stringType()) { s += "=\"" + ct->stringValue + '\"'; } } else if (var) { Type* t = d->type; s += typeTag(t); if (t->intType()) { s += "=" + itoa(*(int*)var); } else if (t->floatType()) { s += "=" + ftoa(*(float*)var); } else if (t->stringType()) { BBStr* str = *(BBStr**)var; if (str) s += "=\"" + *str + '\"'; else s += "=\"\""; } else if (st) { var = *(void**)var; if (var) var = *(void**)var; if (!var) s += " (Null)"; } } if (it) { if (GetItemText(it) != s.c_str()) { SetItemText(it, s.c_str()); } } else { it = InsertItem(s.c_str(), parent); } ++st_nest; if (st) { if (var) { if (st_nest < 4) { HTREEITEM st_it = GetChildItem(it); for (int k = 0; k < st->fields->size(); ++k) { Decl* st_d = st->fields->decls[k]; void* st_var = (char*)var + st_d->offset; char name[256]; st_d->getName(name); st_it = insertVar(st_var, st_d, name, st_it, it); } } } else { while (HTREEITEM t = GetChildItem(it)) { DeleteItem(t); } } } --st_nest; return it ? GetNextSiblingItem(it) : 0; } /******************************* CONSTS ***********************************/ ConstsTree::ConstsTree() {} void ConstsTree::reset(Environ* env) { HTREEITEM it = GetChildItem(TVI_ROOT); for (int k = 0; k < env->decls->size(); ++k) { Decl* d = env->decls->decls[k]; if (!(d->kind & (DECL_GLOBAL))) continue; if (d->type->constType()) { char name[256]; d->getName(name); it = insertVar(0, d, name, it, TVI_ROOT); } } } /******************************* GLOBALS **********************************/ GlobalsTree::GlobalsTree() : module(0), envron(0) {} void GlobalsTree::reset(Module* mod, Environ* env) { module = mod; envron = env; } void GlobalsTree::refresh() { if (!module || !envron) return; HTREEITEM it = GetChildItem(TVI_ROOT); for (int k = 0; k < envron->decls->size(); ++k) { Decl* d = envron->decls->decls[k]; if (!(d->kind & (DECL_GLOBAL))) continue; if (!d->type->constType()) { char name[256]; d->getName(name); void* var = 0; module->findSymbol(("_v" + string(name)).c_str(), (int*)&var); it = insertVar(var, d, name, it, TVI_ROOT); } } } /******************************** LOCALS **********************************/ LocalsTree::LocalsTree() : envron(0) {} void LocalsTree::reset(Environ* env) { envron = env; } void LocalsTree::refresh() { if (!envron || !frames.size()) return; HTREEITEM item = GetChildItem(TVI_ROOT); int n = 0; for (n = 0; n < frames.size(); ++n) { if (!item || item != frames[n].item) break; item = GetNextSiblingItem(item); } while (item) { HTREEITEM next = GetNextSiblingItem(item); DeleteItem(item); item = next; } for (; n < frames.size(); ++n) { item = frames[n].item = InsertItem(frames[n].func, TVI_ROOT, TVI_LAST); if (n < frames.size() - 1) refreshFrame(frames[n]); } refreshFrame(frames.back()); } void LocalsTree::refreshFrame(const Frame& f) { HTREEITEM it = GetChildItem(f.item); for (int n = 0; n < f.env->decls->size(); ++n) { Decl* d = f.env->decls->decls[n]; if (!(d->kind & (DECL_LOCAL | DECL_PARAM))) continue; char name[256]; d->getName(name); if (!isalpha(name[0])) continue; it = insertVar((char*)f.frame + d->offset, d, name, it, f.item); } } void LocalsTree::pushFrame(void* f, void* e, const char* func) { frames.push_back(Frame(f, (Environ*)e, func)); } void LocalsTree::popFrame() { frames.pop_back(); }