diff --git a/uppsrc/CodeEditor/CInit.cpp b/uppsrc/CodeEditor/CInit.cpp index f486d0672..ef249fdb5 100644 --- a/uppsrc/CodeEditor/CInit.cpp +++ b/uppsrc/CodeEditor/CInit.cpp @@ -110,7 +110,7 @@ void CSyntax::InitKeywords() "default", "break", "return", "switch", "operator", "for", "fn", "typename", "value", "from", "items", "template_param", - "TEXT", "HAS_DATA", "ITEM_COUNT", "ITEM_TYPE", "STRING", + "TEXT", "ITEM_COUNT", "ITEM_TYPE", "STRING", "ITEM_PTR", "ITEM_PTRS", "ITEM_DEREF_PTRS", "CHUNK", NULL }; @@ -119,9 +119,9 @@ void CSyntax::InitKeywords() "count", "keys", "values", "rand", "reverse", "sort", "order", "replace", "ToUpper", "ToLower", "len", "mid", "exists", - "SizeOf", "TypeName", "DeRef", "Field", + "SizeOf", "TypeName", "TypeNo", "DeRef", "Field", "NestedType", "PeekPtr", "Peek8", "Peek16", "Peek32", "Peek64", "Peek32f", "Peek64f", - "SizeOfPtr", + "SizeOfPtr", "Offset", "LOG", diff --git a/uppsrc/ide/Debuggers/Pdb.h b/uppsrc/ide/Debuggers/Pdb.h index b481a35fa..19ef2d876 100644 --- a/uppsrc/ide/Debuggers/Pdb.h +++ b/uppsrc/ide/Debuggers/Pdb.h @@ -134,6 +134,7 @@ struct Pdb : Debugger, ParentCtrl { Vector base; VectorMap member; VectorMap static_member; + Vector member_type; }; struct Frame : Moveable { @@ -276,13 +277,12 @@ struct Pdb : Debugger, ParentCtrl { Vector data_type; // type of data items (usually type_param), >1 - display as tuples, usually key : value Vector data_ptr; // pointer to items (data_count.GetCount() * data_type.GetCount() items) Visual text; - bool has_data = true; // do display the data for SINGLE_VALUE (false for e.g. void Value) bool separated_types = false; // item tuples are in consequent arrays int chunk = 10000; // maximum number of items to be displayed in treeview in single node - void Text(const char *s, Color color = SRed) { text.Cat(s, color); has_data = false; } - void Text(const String& s, Color color = SRed) { text.Cat(s, color); has_data = false; } - void SetNull() { Text("Null", SCyan); has_data = false; } + void Text(const char *s, Color color = SRed) { text.Cat(s, color); } + void Text(const String& s, Color color = SRed) { text.Cat(s, color); } + void SetNull() { Text("Null", SCyan); } }; VectorMap&, int64, int, Pdb::Pretty&>>> pretty; diff --git a/uppsrc/ide/Debuggers/Pretty.cpp b/uppsrc/ide/Debuggers/Pretty.cpp index 5e1387ea7..427cc8f37 100644 --- a/uppsrc/ide/Debuggers/Pretty.cpp +++ b/uppsrc/ide/Debuggers/Pretty.cpp @@ -18,8 +18,7 @@ bool Pdb::PrettyVal(Pdb::Val val, int64 from, int count, Pretty& p) return false; const Type& t = GetType(val.type); - - + current_modbase = t.modbase; // so that we do not need to pass it as parameter in Pretty routines String type = t.name; @@ -120,14 +119,12 @@ bool Pdb::VisualisePretty(Visual& result, Pdb::Val val, dword flags) Pretty p; if(PrettyVal(val, 0, 0, p)) { + for(const VisualPart& vp : p.text.part) + result.Cat(vp.text, vp.ink); if(p.kind == TEXT) { int count = (int)min(p.data_count, (int64)200); Pretty p; PrettyVal(val, 0, count, p); - if(p.kind == SINGLE_VALUE) // support script errors - for(const VisualPart& vp : p.text.part) - result.Cat(vp.text, vp.ink); - else if(p.data_type.GetCount()) { String s; WString ws; @@ -150,51 +147,38 @@ bool Pdb::VisualisePretty(Visual& result, Pdb::Val val, dword flags) } else if(p.kind == SINGLE_VALUE) { - Pretty p; - PrettyVal(val, 0, 1, p); - for(const VisualPart& vp : p.text.part) - result.Cat(vp.text, vp.ink); - if(p.has_data) { - if(p.data_type.GetCount() && p.data_ptr.GetCount()) - Visualise(result, MakeVal(p.data_type[0], p.data_ptr[0]), flags); - else - Visualise(result, val, flags | RAW); - } + if(p.data_type.GetCount() && p.data_ptr.GetCount()) + Visualise(result, MakeVal(p.data_type[0], p.data_ptr[0]), flags); } else { // CONTAINER int count = (int)min(p.data_count, (int64)40); Pretty p; PrettyVal(val, 0, count, p); - if(p.kind == SINGLE_VALUE) // support script errors - for(const VisualPart& vp : p.text.part) - result.Cat(vp.text, vp.ink); - else { - ResultCount(p.data_count); - if(p.data_type.GetCount()) { - Buffer item(p.data_type.GetCount()); - for(int i = 0; i < p.data_type.GetCount(); i++) { - (TypeInfo &)item[i] = GetTypeInfo(p.data_type[i]); - item[i].context = val.context; - } - int ii = 0; - int n = p.data_ptr.GetCount() / p.data_type.GetCount(); - Color bc = decode(bc_lvl++ & 3, 0, SGray(), 1, SCyan(), 2, SBrown(), SGreen()); - result.Cat("{", bc); - for(int i = 0; i < n; i++) { - if(i) - result.Cat(", ", SGray); - for(int j = 0; j < p.data_type.GetCount(); j++) { - if(j) - result.Cat(": ", SBlue); - item[j].address = p.data_ptr[p.separated_types ? n * j + i : ii++]; - if(item[j].type != UNKNOWN) - Visualise(result, item[j], flags | MEMBER); - } - } - result.Cat("}", bc); - bc_lvl--; + ResultCount(p.data_count); + if(p.data_type.GetCount()) { + Buffer item(p.data_type.GetCount()); + for(int i = 0; i < p.data_type.GetCount(); i++) { + (TypeInfo &)item[i] = GetTypeInfo(p.data_type[i]); + item[i].context = val.context; } + int ii = 0; + int n = p.data_ptr.GetCount() / p.data_type.GetCount(); + Color bc = decode(bc_lvl++ & 3, 0, SGray(), 1, SCyan(), 2, SBrown(), SGreen()); + result.Cat("{", bc); + for(int i = 0; i < n; i++) { + if(i) + result.Cat(", ", SGray); + for(int j = 0; j < p.data_type.GetCount(); j++) { + if(j) + result.Cat(": ", SBlue); + item[j].address = p.data_ptr[p.separated_types ? n * j + i : ii++]; + if(item[j].type != UNKNOWN) + Visualise(result, item[j], flags | MEMBER); + } + } + result.Cat("}", bc); + bc_lvl--; } if(p.data_count > count) diff --git a/uppsrc/ide/Debuggers/PrettyUpp.cpp b/uppsrc/ide/Debuggers/PrettyUpp.cpp index 5018db715..0d0985566 100644 --- a/uppsrc/ide/Debuggers/PrettyUpp.cpp +++ b/uppsrc/ide/Debuggers/PrettyUpp.cpp @@ -176,7 +176,6 @@ void Pdb::PrettyValue(Pdb::Val val, const Vector&, int64 from, int count } if(st == 6) { // ERROR_V p.Text("ErrorValue ", SLtRed()); - p.has_data = true; a = PeekPtr(a); Val v = GetAttr(MakeVal("Upp::RawValueRep", a), "v"); p.data_type << "Upp::String"; diff --git a/uppsrc/ide/Debuggers/Scripts.cpp b/uppsrc/ide/Debuggers/Scripts.cpp index 801bfde32..31eb32259 100644 --- a/uppsrc/ide/Debuggers/Scripts.cpp +++ b/uppsrc/ide/Debuggers/Scripts.cpp @@ -71,7 +71,9 @@ void Pdb::LoadPrettyScripts() Escape(pretty_globals, "TypeName(x)", [=](EscEscape& e) { e = GetType(Type(e)).name; }); - + Escape(pretty_globals, "TypeNo(s)", [=](EscEscape& e) { + e = GetTypeInfo((String)e[0]).type; + }); Escape(pretty_globals, "PeekPtr(x)", [=](EscEscape& e) { e = (int64)PeekPtr(Adr(e)); }); @@ -104,7 +106,6 @@ void Pdb::LoadPrettyScripts() txt = e[0].ToString(); PutConsole("dbg! " + txt); }); - Escape(pretty_globals, "DeRef(x)", [=](EscEscape& e) { EscValue v = e[0]; if(!v.IsMap()) @@ -112,6 +113,16 @@ void Pdb::LoadPrettyScripts() v.MapSet("address", (int64)PeekPtr(v.MapGet("address").GetInt64())); e = v; }); + Escape(pretty_globals, "NestedType(x, id)", [=](EscEscape& e) { + const auto& t = GetType(Type(e)); + String id = (String)e[1]; + for(int st : t.member_type) + if(GetType(st).name == id) { + e = st; + return; + } + e = 0; + }); Escape(pretty_globals, "Field(x, id)", [=](EscEscape& e) { EscValue v = e[0]; if(!v.IsMap()) @@ -150,14 +161,19 @@ bool Pdb::PrettyScript(const String& type, Pdb::Val val, const Vector& t bool ret = false; p.kind = CONTAINER; p.separated_types = true; - Escape(g, "TEXT(x)", [&](EscEscape& e) { + Escape(g, "TEXT(x, color = 0)", [&](EscEscape& e) { ret = true; - p.kind = SINGLE_VALUE; + static Color col[] = { + SBlack(), SRed(), SGreen(), SBrown(), SBlue(), SMagenta(), SCyan(), SGray(), + SLtGray(), SLtRed(), SLtGreen(), SLtYellow(), SLtBlue(), SLtMagenta(), + SLtCyan(), SYellow(), SWhiteGray(), SWhite() + }; + Color c = col[clamp((int)e[1].GetInt(), 0, __countof(col))]; if(e[0].IsArray()) - p.Text((String) e[0]); + p.Text((String) e[0], c); else if(e[0].IsNumber()) - p.Text(AsString(e[0].GetNumber())); + p.Text(AsString(e[0].GetNumber()), c); else e.ThrowError("invalid argument to 'Text'"); }); @@ -197,10 +213,6 @@ bool Pdb::PrettyScript(const String& type, Pdb::Val val, const Vector& t p.kind = TEXT; ret = true; }); - Escape(g, "HAS_DATA()", [&](EscEscape& e) { - p.has_data = true; - ret = true; - }); Escape(g, "CHUNK(x)", [&](EscEscape& e) { p.chunk = clamp(e[0].GetInt(), 1, 10000); ret = true; @@ -208,6 +220,10 @@ bool Pdb::PrettyScript(const String& type, Pdb::Val val, const Vector& t try { Execute(g, NULL, pretty_scripts[ii], args, 2000); + DDUMP(type); + DDUMP(p.data_count); + if(p.data_count == 0 && p.kind == CONTAINER) + p.kind = SINGLE_VALUE; } catch(CParser::Error e) { p.kind = SINGLE_VALUE; diff --git a/uppsrc/ide/Debuggers/Sym.cpp b/uppsrc/ide/Debuggers/Sym.cpp index 36d0c41df..316178f83 100644 --- a/uppsrc/ide/Debuggers/Sym.cpp +++ b/uppsrc/ide/Debuggers/Sym.cpp @@ -353,6 +353,7 @@ const Pdb::Type& Pdb::GetType(int ti) int typeindex = type.GetKey(ti); if(t.size < 0) { t.name = GetSymName(t.modbase, typeindex); + DDUMP(t.name); type_name.GetAdd(t.name) = ti; ULONG64 sz = 0; SymGetTypeInfo(hProcess, t.modbase, typeindex, TI_GET_LENGTH, &sz); @@ -368,6 +369,10 @@ const Pdb::Type& Pdb::GetType(int ti) dword ch = children->ChildId[i]; dword tag = GetSymInfo(t.modbase, ch, TI_GET_SYMTAG); dword kind = GetSymInfo(t.modbase, ch, TI_GET_DATAKIND); + DDUMP(SymTagAsString(tag)); + if(tag == SymTagUDT) + t.member_type << GetTypeIndex(t.modbase, ch); + else if(tag == SymTagData) { String name = GetSymName(t.modbase, ch); if(kind == DataIsMember) { diff --git a/upptst/PdbAll/PdbAll.cpp b/upptst/PdbAll/PdbAll.cpp index 8ad87ea67..a7e496965 100644 --- a/upptst/PdbAll/PdbAll.cpp +++ b/upptst/PdbAll/PdbAll.cpp @@ -34,6 +34,9 @@ GUI_APP_MAIN ValueArray valuearray { "I", "II", "III", "IV", "V" }; ValueMap valuemap { { 1 , "I"}, { 2, "II" }, { 3, "III"}, { 4, "IV"}, { 5, "V" } }; Value value = valuemap; + Value text_value = "Test"; + Value error_value = ErrorValue("Test"); + Value void_value; std::string std_string = "Hello world!"; std::wstring std_wstring = wstring.ToStd(); diff --git a/upptst/ScriptDbgPretty/pretty.dbg b/upptst/ScriptDbgPretty/pretty.dbg index b3b5f3109..b325b35b0 100644 --- a/upptst/ScriptDbgPretty/pretty.dbg +++ b/upptst/ScriptDbgPretty/pretty.dbg @@ -1,5 +1,5 @@ typename MyStruct { - TEXT("My struct: "); + TEXT("My struct: ", 7); TEXT(Peek32(Field(value, "second").address)); }