From 2b09abdfa7185209f2c0851a519c51df0fc2e20a Mon Sep 17 00:00:00 2001 From: micio Date: Thu, 13 Feb 2014 00:27:14 +0000 Subject: [PATCH] Ide/Debuggers/Gdb_MI2 : completed type evaluators for string, vector and corresponding maps git-svn-id: svn://ultimatepp.org/upp/trunk@6913 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/ide/Debuggers/Debuggers.upp | 3 + uppsrc/ide/Debuggers/Gdb_MI2.cpp | 156 ++---------- uppsrc/ide/Debuggers/Gdb_MI2.h | 30 ++- uppsrc/ide/Debuggers/Gdb_MI2Eval.cpp | 182 ++++++++++++++ uppsrc/ide/Debuggers/MIValue.cpp | 63 ++++- uppsrc/ide/Debuggers/MIValue.h | 11 + uppsrc/ide/Debuggers/TypeSimplify.cpp | 91 ++----- uppsrc/ide/Debuggers/TypeSimplify.h | 32 +++ uppsrc/ide/Debuggers/UppSimplifiers.icpp | 297 +++++++++++++++++++++++ uppsrc/ide/Debuggers/init | 3 + 10 files changed, 636 insertions(+), 232 deletions(-) create mode 100644 uppsrc/ide/Debuggers/Gdb_MI2Eval.cpp create mode 100644 uppsrc/ide/Debuggers/TypeSimplify.h create mode 100644 uppsrc/ide/Debuggers/UppSimplifiers.icpp diff --git a/uppsrc/ide/Debuggers/Debuggers.upp b/uppsrc/ide/Debuggers/Debuggers.upp index e6ce5fdaa..7731e0e3e 100644 --- a/uppsrc/ide/Debuggers/Debuggers.upp +++ b/uppsrc/ide/Debuggers/Debuggers.upp @@ -11,7 +11,9 @@ file Gdb.lay, MIValue.h, MIValue.cpp, + TypeSimplify.h, TypeSimplify.cpp, + UppSimplifiers.icpp, VarItem.cpp, Terminal.cpp, Disas.cpp, @@ -19,6 +21,7 @@ file Gdb.cpp, Gdb_MI2.lay, Gdb_MI2.h, + Gdb_MI2Eval.cpp, Gdb_MI2.cpp, PrettyPrinters.brc, PrettyPrinters.py, diff --git a/uppsrc/ide/Debuggers/Gdb_MI2.cpp b/uppsrc/ide/Debuggers/Gdb_MI2.cpp index 6a20a0d0c..ccbb92cd1 100644 --- a/uppsrc/ide/Debuggers/Gdb_MI2.cpp +++ b/uppsrc/ide/Debuggers/Gdb_MI2.cpp @@ -11,7 +11,7 @@ static VectorMap DataMap2(const ArrayCtrl& data) { VectorMap m; for(int i = 0; i < data.GetCount(); i++) - m.Add(data.Get(i, 0), data.Get(i, 2)); + m.Add(data.Get(i, 0), data.Get(i, 1)); return m; } @@ -20,10 +20,10 @@ static void MarkChanged2(const VectorMap& m, ArrayCtrl& data) for(int i = 0; i < data.GetCount(); i++) { int q = m.Find(data.Get(i, 0)); - if(q >= 0 && m[q] != data.Get(i, 2)) - data.SetDisplay(i, 2, Single()); + if(q >= 0 && m[q] != data.Get(i, 1)) + data.SetDisplay(i, 1, Single()); else - data.SetDisplay(i, 2, StdDisplay()); + data.SetDisplay(i, 1, StdDisplay()); } } @@ -1108,145 +1108,11 @@ void Gdb_MI2::UpdateLocalVars(void) } } -// deeply explore a value -// taking its members and skipping types -// WARNING, it APPENDS results to given arrays -void Gdb_MI2::ExploreValueDeep(String baseName, MIValue const &val, Vector &fullNames, Vector &values) const -{ - // if value is a string, just append baseName and value to result - if(val.IsString()) - { - fullNames.Add(baseName); - values.Add(val.ToString()); - } - // otherwise, if value is a tuple, recursively add all subvalues - else if(val.IsTuple()) - { - for(int iVal = 0; iVal < val.GetCount(); iVal++) - { - String name = val.GetKey(iVal); - if(!name.StartsWith("<")) - name = baseName + '.' + name; - else - name = baseName; - ExploreValueDeep(name, val.Get(iVal), fullNames, values); - } - } -} - // update 'this' inspector data void Gdb_MI2::UpdateThis(void) { -/* - thisNames.Clear(); - thisExpressions.Clear(); - thisValues.Clear(); - - VarItem v = EvalGdb("*this"); - v.shortExpression = "."; - - thisNames.Add(v.shortExpression); - thisExpressions.Add(v.evaluableExpression); - thisValues.Add(v.value); - - Vector vv; - if(v.kind == VarItem::SIMPLE) - vv = GetChildren(v); - else - vv = GetChildren(v, 0, 10); - - for(int iChild = 0; iChild < vv.GetCount(); iChild++) - { - VarItem &v = vv[iChild]; - thisNames.Add(v.shortExpression); - thisExpressions.Add(v.evaluableExpression); - thisValues.Add(v.value); - } -*/ - - thisNames.Clear(); - thisExpressions.Clear(); - thisValues.Clear(); - - Vectornames, values; - - MIValue thisVal = MICmd("data-evaluate-expression *this"); - - if(!thisVal.IsTuple()) - return; - if(thisVal.Find("value") >= 0) - { - // weird but the value is quoted, so must be parsed again... - MIValue const &tup = thisVal.Get("value"); - if(!tup.IsString()) - return; - MIValue s(tup.ToString()); - s.PackNames(); -//RLOG(s.Dump()); - TypeSimplify(s); - ExploreValueDeep("", s, names, values); - } - else if(thisVal.Find("variables") >= 0) - { - MIValue &arr = thisVal.Get("variables"); - - if(!arr.IsArray()) - return; - for(int iVal = 0; iVal < arr.GetCount(); iVal++) - { - MIValue &val = arr[iVal]; - if(!val.IsTuple() || val.Find("name") < 0 || val.Find("value") < 0) - continue; - MIValue &s = val.Get("value"); - s.PackNames(); - TypeSimplify(s); - val.PackNames(); - ExploreValueDeep("." + val.Get("name").ToString(), s, thisExpressions, thisValues); - } - } - - // build short names from full names - for(int iName = 0; iName < thisExpressions.GetCount(); iName++) - { - String const &nam = thisExpressions[iName]; - String shortName; - int pos = nam.ReverseFind('.'); - if(pos < 0) - shortName = nam; - else - shortName = nam.Mid(pos + 1); - thisNames.Add(shortName); - } - - // here the 'this' object is dumped inside the 2 vectors 'names' and 'values' - // we need to do some cleanup, removing empty values, class names and so on - // we shall also construct the 'thisNames' vector containing just the last name path - // used for tooltip - for(int iName = 0; iName < names.GetCount(); iName++) - { - String const &name = names[iName]; - if(name.IsEmpty()) - continue; - if(name == "") - continue; - if(name.StartsWith("_vptr.")) - continue; - - String const &val = values[iName]; - if(val.IsEmpty()) - continue; - - String shortName; - int dotPos = name.ReverseFind('.'); - if(dotPos < 0) - shortName = name; - else - shortName = name.Mid(dotPos + 1); - - thisNames.Add(shortName); - thisExpressions.Add(name); - thisValues.Add(val); - } + MIValue val = Evaluate("*this"); + CollectVariables(val, thisExpressions, thisValues, thisHints); } // sync auto vars treectrl @@ -1299,8 +1165,8 @@ void Gdb_MI2::SyncMembers(void) VectorMap prev = DataMap2(members); members.Clear(); - for(int iMem = 0; iMem < thisNames.GetCount(); iMem++) - members.Add(thisExpressions[iMem], thisValues[iMem]); + for(int iMem = 0; iMem < thisExpressions.GetCount(); iMem++) + members.Add(thisExpressions[iMem].Mid(7), thisValues[iMem]); MarkChanged2(prev, members); } @@ -1639,6 +1505,12 @@ void Gdb_MI2::onExploreExpr(ArrayCtrl *what) // we use the expression editbox expr = ~explorerExprEdit; } + else if(what == &members) + { + int line = what->GetCursor(); + if(line >= 0) + expr = thisExpressions[line]; + } else { // otherwise, we use the expression from sending ArrayCtrl diff --git a/uppsrc/ide/Debuggers/Gdb_MI2.h b/uppsrc/ide/Debuggers/Gdb_MI2.h index 581429bec..e019fb31a 100644 --- a/uppsrc/ide/Debuggers/Gdb_MI2.h +++ b/uppsrc/ide/Debuggers/Gdb_MI2.h @@ -170,9 +170,9 @@ class Gdb_MI2 : public Debugger, public ParentCtrl VectorwatchesValues; // 'this' variable inspection data - IndexthisNames; VectorthisExpressions; VectorthisValues; + VectorthisHints; // stored autos expressions, values and types String autoLine; @@ -180,18 +180,7 @@ class Gdb_MI2 : public Debugger, public ParentCtrl // update local variables on demand void UpdateLocalVars(void); - // deeply explore a value - // taking its members and skipping types - // WARNING, it APPENDS results to given arrays - void ExploreValueDeep(String baseName, MIValue const &val, Vector &fullNames, Vector &values) const; - - // known types simplifier - // takes a MIValue from '-data-evaluate-expression' command and try - // do simplify diplay of known types - void TypeSimplify(MIValue &val); - // update 'this' inspector data - void UpdateThisDeep(VarItem &v); void UpdateThis(void); // logs frame data on console @@ -285,6 +274,16 @@ class Gdb_MI2 : public Debugger, public ParentCtrl String GetHostPath(const String& path) { return host->GetHostPath(path); } String GetLocalPath(const String& path) { return host->GetLocalPath(path); } + // known types simplifier + // takes a MIValue from '-data-evaluate-expression' command and try + // do simplify diplay of known types + void TypeSimplify(MIValue &val); + + // collects evaluated variables got with Evaluate + // hints are used to choose the visualizer when deep-inspecting members + // 0 for simple values, 1 for arrays, 2 for map + void CollectVariables(MIValue &val, Vector &exprs, Vector &vals, Vector &hints); + protected: public : @@ -306,6 +305,13 @@ class Gdb_MI2 : public Debugger, public ParentCtrl Gdb_MI2(); virtual ~Gdb_MI2(); + + + // variable inspection support + // returns a MIValue with inspected data and some info fields added + // and known types simplified and cathegorized + // unknown and simple types are left as they are + MIValue Evaluate(String expr); }; #endif diff --git a/uppsrc/ide/Debuggers/Gdb_MI2Eval.cpp b/uppsrc/ide/Debuggers/Gdb_MI2Eval.cpp new file mode 100644 index 000000000..d83281447 --- /dev/null +++ b/uppsrc/ide/Debuggers/Gdb_MI2Eval.cpp @@ -0,0 +1,182 @@ +#include "Debuggers.h" +#include + +#include "TypeSimplify.h" + +// now we scan the result and add some info +// so, for example, if we find tuple like this one: +// data = simplevalue +// this will be modified as +// data = { value = simplevalue, expr = evaluable_expression } +// and for a complex value +// data = { some=complex, not_simple=val } +// woll be modified as +// data = { = { some=complex, not_simple=val }, = evaluable_expression } +// More attributes will be added by type simplifier phase +static void AddAttribs(String const &expr, MIValue &valExpr) +{ + if(valExpr.IsTuple()) + { + for(int i = 0; i < valExpr.GetCount(); i++) + { + String nam = valExpr.GetKey(i); + String nExpr; + if(!nam.StartsWith("<")) + nExpr = expr + "." + nam; + else + nExpr = expr; + MIValue v = valExpr[i]; + valExpr[i].Clear(); + valExpr[i].Add(SIMPLIFY_VALUE, v); + valExpr[i].Add(SIMPLIFY_EXPR, nExpr); + AddAttribs(nExpr, valExpr[i][SIMPLIFY_VALUE]); + } + } + else if(valExpr.IsArray()) + { + } +} + +void Gdb_MI2::TypeSimplify(MIValue &val) +{ + if(val.IsTuple()) + { + for(int i = 0; i < val.GetCount(); i++) + { + // root of variable -- contains VALUE, EXPRESSION and will add HINTS + MIValue &vRoot = val[i]; + + // value part of variable + MIValue &v = vRoot[SIMPLIFY_VALUE]; + + if(v.IsTuple() && v.GetCount()) + { + String key = v.GetKey(0); + if(key.StartsWith("= 0) + { + // weird but the value is quoted, so must be parsed again... + MIValue const &tup = valExpr.Get("value"); + if(!tup.IsString()) + return MIValue(); + String s = tup.ToString(); + MIValue parsed(s); + + // enclose it in a dummy container + MIValue enclosed; + enclosed.Add("", parsed); + + // remove spaces from names + enclosed.PackNames(); + + // Add attributes to expression data + AddAttribs(expr, enclosed); + + // now we go through the type simplifier, which try to give simple representation + // for known types + TypeSimplify(enclosed); + +//RLOG(enclosed.Dump()); + + // now we can de-enclose it... + parsed = enclosed[""][SIMPLIFY_VALUE]; + +//RLOG(parsed.Dump()); + + // and finally return the cleaned evaluated data + return parsed; + } + + else if(valExpr.Find("variables") >= 0) + { +RLOG("ARRAY SIDE UNHANDLED...."); + return MIValue(); + } + else + { +RLOG("WEIRD STUFF HERE...."); + return MIValue(); + } +} + +// collects evaluated variables got with Evaluate +// hints are used to choose the visualizer when deep-inspecting members +// 0 for simple values, 1 for arrays, 2 for map +static void Collect0(MIValue &val, Vector &exprs, Vector &vals, Vector &hints) +{ + if(!val.IsTuple()) + return; + + for(int i = 0; i < val.GetCount(); i++) + { + MIValue &v = val[i]; + MIValue &data = v[SIMPLIFY_VALUE]; + if(data.IsError()) + continue; + if(data.IsString()) + { + String d = data.ToString(); + if(!d.StartsWith("<")) + { + vals.Add(data.ToString()), + exprs.Add(v[SIMPLIFY_EXPR]); + String hint = v.Get(SIMPLIFY_HINT, SIMPLIFY_SIMPLE); + if(hint == SIMPLIFY_SIMPLE) + hints << 0; + else if(hint == SIMPLIFY_ARRAY) + hints << 1; + else if(hint == SIMPLIFY_MAP) + hints << 2; + else + hints << 0; + } + } + else if(data.IsTuple()) + Collect0(data, exprs, vals, hints); + } +} + +void Gdb_MI2::CollectVariables(MIValue &val, Vector &exprs, Vector &vals, Vector &hints) +{ + exprs.Clear(); + vals.Clear(); + hints.Clear(); + + Collect0(val, exprs, vals, hints); +} + diff --git a/uppsrc/ide/Debuggers/MIValue.cpp b/uppsrc/ide/Debuggers/MIValue.cpp index c43422298..57763ac6e 100644 --- a/uppsrc/ide/Debuggers/MIValue.cpp +++ b/uppsrc/ide/Debuggers/MIValue.cpp @@ -245,7 +245,7 @@ int MIValue::ParseAngle(String const &s, int i) } i++; } - if(!expect("ParseAngle", '"', i-1, s)) + if(!expect("ParseAngle", '>', i-1, s)) return s.GetCount(); string.Cat('>'); @@ -638,3 +638,64 @@ void MIValue::PackNames(void) array[i].PackNames(); } } + +// add an item to a tuple +MIValue &MIValue::Add(String const &key, MIValue pick_ &v) +{ + if(IsEmpty()) + { + Clear(); + type = MITuple; + } + if(type != MITuple) + return ErrorMIValue("Not a Tuple value type"); + tuple.AddPick(key, v); + return *this; +} + +MIValue &MIValue::Add(String const &key, String const &data) +{ + MIValue v; + v.Set(data); + return Add(key, v); +} + +MIValue &MIValue::FindAdd(String const &key, String const &data) +{ + if(IsEmpty()) + { + Clear(); + type = MITuple; + } + if(type != MITuple) + return ErrorMIValue("Not a Tuple value type"); + int idx = tuple.Find(key); + MIValue v; + v.Set(data); + if(idx >= 0) + tuple[idx] = v; + else + tuple.AddPick(key, v); + return *this; +} + +// add an item to an array +MIValue &MIValue::Add(MIValue pick_ &v) +{ + if(IsEmpty()) + { + Clear(); + type = MIArray; + } + if(type != MIArray) + return ErrorMIValue("Not a Array value type"); + array.AddPick(v); + return *this; +} + +MIValue &MIValue::Add(String const &data) +{ + MIValue v; + v.Set(data); + return Add(v); +} diff --git a/uppsrc/ide/Debuggers/MIValue.h b/uppsrc/ide/Debuggers/MIValue.h index 0bd40968c..e84f39ae0 100644 --- a/uppsrc/ide/Debuggers/MIValue.h +++ b/uppsrc/ide/Debuggers/MIValue.h @@ -96,6 +96,17 @@ class MIValue : public Moveable // packs names inside tuples -- to make type recognition easy void PackNames(void); + + // add some data to a value + + // add an item to a tuple + MIValue &Add(String const &key, MIValue pick_ &v); + MIValue &Add(String const &key, String const &data); + MIValue &FindAdd(String const &key, String const &data); + + // add an item to an array + MIValue &Add(MIValue pick_ &v); + MIValue &Add(String const &data); }; #endif diff --git a/uppsrc/ide/Debuggers/TypeSimplify.cpp b/uppsrc/ide/Debuggers/TypeSimplify.cpp index 81f91ea90..6f45214fe 100644 --- a/uppsrc/ide/Debuggers/TypeSimplify.cpp +++ b/uppsrc/ide/Debuggers/TypeSimplify.cpp @@ -1,86 +1,23 @@ -#include "Debuggers.h" -#include +#include "TypeSimplify.h" -typedef bool (*TYPE_SIMPLIFIER_HANDLER)(MIValue &val); - -static bool UppStringSimplify(MIValue &val) +static VectorMap &GetSimplifierMap(void) { - // strings are "easy", in debug mode 's' and 'len' members are provided - // so we shall just look at them in tuple - // see Upp::String code for how it works.... - try - { - MIValue &v = val[0][0][0]; - MIValue &unn = v[1]; - if(!v.IsTuple() || !unn.IsTuple()) - return false; - - if(unn.Find("chr") < 0) - return false; - String chr = unn["chr"]; - bool isSmall = (chr[14] == 0); - String s; - if(isSmall) - s = chr; - else - { - if(unn.Find("ptr") < 0) - return false; - s = unn["ptr"]; - - // strip address... - int i = s.Find('"'); - if(i >= 0) - { - s = s.Mid(i+1); - s = s.Left(s.GetCount()-1); - } - } - val.Set(s); - return true; - } - catch(...) - { - return false; - } + static VectorMap map; + return map; } -struct TYPE_SIMPLIFIER +void RegisterSimplifier(const char *pattern, TYPE_SIMPLIFIER_HANDLER handler) { - const char *type; - TYPE_SIMPLIFIER_HANDLER handler; + GetSimplifierMap().Add(pattern, handler); +} -}; - -TYPE_SIMPLIFIER TYPE_SIMPLIFIERS[] = +TYPE_SIMPLIFIER_HANDLER GetSimplifier(String const &pattern) { - { ">>", UppStringSimplify } -}; - -#define SIMPLIFIERS_COUNT ((int)(sizeof(TYPE_SIMPLIFIERS) / sizeof(TYPE_SIMPLIFIER))) - -void Gdb_MI2::TypeSimplify(MIValue &val) -{ - static VectorMap handlers; - if(!handlers.GetCount()) - for(int i = 0; i < SIMPLIFIERS_COUNT; i++) - handlers.Add(TYPE_SIMPLIFIERS[i].type, TYPE_SIMPLIFIERS[i].handler); - - if(val.IsTuple()) + VectorMap &map = GetSimplifierMap(); + for(int i = 0; i < map.GetCount(); i++) { - for(int i = 0; i < val.GetCount(); i++) - { - MIValue &v = val[i]; - if(v.IsTuple() && v.GetCount()) - { - int idx = handlers.Find(v.GetKey(0)); - if(idx >= 0) - handlers[idx](v); - else - TypeSimplify(v); - } - else - TypeSimplify(v); - } + if(pattern.StartsWith(map.GetKey(i))) + return map[i]; } -} \ No newline at end of file + return NULL; +} diff --git a/uppsrc/ide/Debuggers/TypeSimplify.h b/uppsrc/ide/Debuggers/TypeSimplify.h new file mode 100644 index 000000000..6a58bb9cb --- /dev/null +++ b/uppsrc/ide/Debuggers/TypeSimplify.h @@ -0,0 +1,32 @@ +#ifndef _ide_Debuggers_TypeSimplify_h_ +#define _ide_Debuggers_TypeSimplify_h_ + +#include "Debuggers.h" +#include + +#define SIMPLIFY_EXPR "" +#define SIMPLIFY_VALUE "" +#define SIMPLIFY_HINT "" +#define SIMPLIFY_START "" +#define SIMPLIFY_COUNT "" + +#define SIMPLIFY_SIMPLE "" +#define SIMPLIFY_ARRAY "" +#define SIMPLIFY_MAP "" + +// Simplifier handler +// parameters: +// gdb handler to debugger object -- used mostly to inspect deeper +// expRoot gdb evaluable expression of 'val' expression root. The one used to get the 'val'. +typedef bool (*TYPE_SIMPLIFIER_HANDLER)(Gdb_MI2 &gdb, MIValue &val); + +void RegisterSimplifier(const char *pattern, TYPE_SIMPLIFIER_HANDLER handler); + +TYPE_SIMPLIFIER_HANDLER GetSimplifier(String const &pattern); + +#define REGISTERSIMPLIFIER(pattern, handler) \ + INITBLOCK { \ + RegisterSimplifier(pattern, handler); \ +} + +#endif diff --git a/uppsrc/ide/Debuggers/UppSimplifiers.icpp b/uppsrc/ide/Debuggers/UppSimplifiers.icpp new file mode 100644 index 000000000..b8af40a76 --- /dev/null +++ b/uppsrc/ide/Debuggers/UppSimplifiers.icpp @@ -0,0 +1,297 @@ +#include "TypeSimplify.h" + +static bool UppStringSimplify(Gdb_MI2 &gdb, MIValue &val) +{ + + // strings are "easy", in debug mode 's' and 'len' members are provided + // so we shall just look at them in tuple + // see Upp::String code for how it works.... + try + { + MIValue &v = val[SIMPLIFY_VALUE][0][0][0][0][0][SIMPLIFY_VALUE]; + MIValue &unn = v[1][SIMPLIFY_VALUE]; + + if(!v.IsTuple() || !unn.IsTuple()) + return false; + + if(unn.Find("chr") < 0) + return false; + String chr = unn["chr"][SIMPLIFY_VALUE]; + bool isSmall = (chr[14] == 0); + String s; + if(isSmall) + s = chr; + else + { + if(unn.Find("ptr") < 0) + return false; + s = unn["ptr"][SIMPLIFY_VALUE]; + + // strip address... + int i = s.Find('"'); + if(i >= 0) + { + s = s.Mid(i+1); + s = s.Left(s.GetCount()-1); + } + } + val[SIMPLIFY_VALUE].Set("\"" + s + "\""); + val.FindAdd(SIMPLIFY_HINT, SIMPLIFY_SIMPLE); + return true; + } + catch(...) + { + return false; + } +} + +static bool UppVectorSimplify(Gdb_MI2 &gdb, MIValue &val) +{ +//RLOG(val.Dump()); + try + { + MIValue &v = val[SIMPLIFY_VALUE]; + String vectorExpr = v["vector"][SIMPLIFY_EXPR]; + int items = atoi(v["items"][SIMPLIFY_VALUE].ToString()); + + val.FindAdd(SIMPLIFY_HINT, SIMPLIFY_ARRAY); + val.FindAdd(SIMPLIFY_START, "0"); + val.FindAdd(SIMPLIFY_COUNT, FormatInt(items)); + + // display max 5 elements of array, starting from 0 and ONLY if elements evaluate to a simple type + // otherwise display {...} string + // to do this, we shall ask gdb to evaluate the undelying vector + int count = min(5, items); + String vals = ""; + for(int i = 0; i < count; i++) + { + MIValue vi = gdb.Evaluate(vectorExpr + Format("[%d]", i)); + if(vi.IsError()) + { + vals = "can't evaluate"; + break; + } + if(!vi.IsString()) + { + vals = "{...}"; + break; + } + vals = vals + ", " + vi.ToString(); + } + if(vals.StartsWith(", ")) + vals = vals.Mid(2); + vals = Format("Upp::Vector with %d elements : %s", items, vals); +//RLOG("VALS = " << vals); + val[SIMPLIFY_VALUE].Set(vals); + +//RLOG(v.Dump()); + return true; + } + catch(...) + { + return false; + } +} + +static bool UppVectorMapSimplify(Gdb_MI2 &gdb, MIValue &val) +{ +//RLOG(val.Dump()); + try + { + MIValue &v = val[SIMPLIFY_VALUE]; + + MIValue &keyPtr = v[1][0]["key"][0][1][0][0][0]; + String keyExpr = keyPtr["vector"][SIMPLIFY_EXPR].ToString(); + int items = atoi(keyPtr["items"][SIMPLIFY_VALUE].ToString()); + + MIValue &valPtr = v[1][0]["value"][SIMPLIFY_VALUE];; + String valExpr = valPtr["vector"][SIMPLIFY_EXPR].ToString(); + + val.FindAdd(SIMPLIFY_HINT, SIMPLIFY_MAP); + val.FindAdd(SIMPLIFY_START, "0"); + val.FindAdd(SIMPLIFY_COUNT, FormatInt(items)); + + + // display max 3 elements of map, starting from 0 and ONLY if elements evaluate to a simple type + // otherwise display {...} string + // to do this, we shall ask gdb to evaluate the undelying vector + int count = min(3, items); + String vals = ""; + bool err = false; + bool complex = false; + for(int i = 0; i < count; i++) + { + MIValue vk = gdb.Evaluate(keyExpr + Format("[%d]", i)); + if(vk.IsError()) + { + err = true; + break; + } + if(!vk.IsString()) + { + complex = true; + break; + } + MIValue vv = gdb.Evaluate(valExpr + Format("[%d]", i)); + if(vv.IsError()) + { + err = true; + break; + } + if(!vv.IsString()) + { + complex = true; + break; + } + vals = vals + ", (" + vk.ToString() + "," + vv.ToString() + ")"; + } + + if(complex) + vals = "{...}"; + else if(err) + vals = "can't evaluate"; + if(vals.StartsWith(", ")) + vals = vals.Mid(2); + vals = Format("Upp::VectorMap with %d elements : %s", items, vals); +//RLOG("VALS = " << vals); + val[SIMPLIFY_VALUE].Set(vals); + return true; + + } + catch(...) + { + return false; + } +} + + +static bool UppArraySimplify(Gdb_MI2 &gdb, MIValue &val) +{ +//RLOG(val.Dump()); + try + { + MIValue &v = val[SIMPLIFY_VALUE]["vector"][SIMPLIFY_VALUE]; + + String vectorExpr = v["vector"][SIMPLIFY_EXPR]; + int items = atoi(v["items"][SIMPLIFY_VALUE].ToString()); + + val.FindAdd(SIMPLIFY_HINT, SIMPLIFY_ARRAY); + val.FindAdd(SIMPLIFY_START, "0"); + val.FindAdd(SIMPLIFY_COUNT, FormatInt(items)); + + // display max 5 elements of array, starting from 0 and ONLY if elements evaluate to a simple type + // otherwise display {...} string + // to do this, we shall ask gdb to evaluate the undelying vector + int count = min(5, items); + String vals = ""; + for(int i = 0; i < count; i++) + { + MIValue vi = gdb.Evaluate(vectorExpr + Format("[%d][0]", i)); + if(vi.IsError()) + { + vals = "can't evaluate"; + break; + } + if(!vi.IsString()) + { + vals = "{...}"; + break; + } + vals = vals + ", " + vi.ToString(); + } + if(vals.StartsWith(", ")) + vals = vals.Mid(2); + vals = Format("Upp::Array with %d elements : %s", items, vals); +//RLOG("VALS = " << vals); + val[SIMPLIFY_VALUE].Set(vals); + +//RLOG(v.Dump()); + return true; + } + catch(...) + { + return false; + } +} + +static bool UppArrayMapSimplify(Gdb_MI2 &gdb, MIValue &val) +{ +//RLOG(val.Dump()); + try + { + MIValue &v = val[SIMPLIFY_VALUE]; + + MIValue &keyPtr = v[1][0]["key"][0][1][0][0][0]; + String keyExpr = keyPtr["vector"][SIMPLIFY_EXPR].ToString(); + int items = atoi(keyPtr["items"][SIMPLIFY_VALUE].ToString()); + + MIValue &valPtr = v[1][0]["value"][SIMPLIFY_VALUE];; + String valExpr = valPtr["vector"][SIMPLIFY_VALUE]["vector"][SIMPLIFY_EXPR].ToString(); + + val.FindAdd(SIMPLIFY_HINT, SIMPLIFY_MAP); + val.FindAdd(SIMPLIFY_START, "0"); + val.FindAdd(SIMPLIFY_COUNT, FormatInt(items)); + + + // display max 3 elements of map, starting from 0 and ONLY if elements evaluate to a simple type + // otherwise display {...} string + // to do this, we shall ask gdb to evaluate the undelying vector + int count = min(3, items); + String vals = ""; + bool err = false; + bool complex = false; + for(int i = 0; i < count; i++) + { + MIValue vk = gdb.Evaluate(keyExpr + Format("[%d]", i)); + if(vk.IsError()) + { + err = true; + break; + } + if(!vk.IsString()) + { + complex = true; + break; + } + MIValue vv = gdb.Evaluate(valExpr + Format("[%d][0]", i)); + if(vv.IsError()) + { + err = true; + break; + } + if(!vv.IsString()) + { + complex = true; + break; + } + vals = vals + ", (" + vk.ToString() + "," + vv.ToString() + ")"; + } + + if(complex) + vals = "{...}"; + else if(err) + vals = "can't evaluate"; + if(vals.StartsWith(", ")) + vals = vals.Mid(2); + vals = Format("Upp::ArrayMap with %d elements : %s", items, vals); +//RLOG("VALS = " << vals); + val[SIMPLIFY_VALUE].Set(vals); + + return true; + + } + catch(...) + { + return false; + } +} + + +// Register the simplifiers +REGISTERSIMPLIFIER(">>" , UppStringSimplify); +REGISTERSIMPLIFIER("