ultimatepp/uppsrc/ide/Debuggers/UppSimplifiers.icpp
micio 1acd5b1585 Ide/Debuggers/Gdb_MI2 : updated explorer pane
git-svn-id: svn://ultimatepp.org/upp/trunk@6933 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2014-02-19 13:49:19 +00:00

422 lines
11 KiB
Text

#include "TypeSimplify.h"
#define EVALDEEP
#define EVALDEEP_VECTOR 5
#define EVALDEEP_ARRAY 5
#define EVALDEEP_VECTORMAP 5
#define EVALDEEP_ARRAYMAP 5
#define EVALDEEP_INDEX 5
#define SLEN 15
#define LLEN 2
static bool UppStringSimplify(Gdb_MI2 &gdb, MIValue &val, bool deep)
{
union
{
char chr[16];
char *ptr;
dword *wptr;
qword *qptr;
word v[8];
dword w[4];
qword q[2];
} u;
// 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 chrs = unn["chr"][SIMPLIFY_VALUE];
memcpy(u.chr, ~chrs, 16);
bool isSmall = (u.chr[14] == 0);
String s;
if(isSmall)
{
byte len = u.chr[SLEN];
s = chrs.Left(len);
}
else
{
if(unn.Find("ptr") < 0)
return false;
dword len = u.w[LLEN];
s = unn["ptr"][SIMPLIFY_VALUE].ToString();
// strip address...
int i = s.Find('"');
if(i >= 0)
{
s = s.Mid(i+1);
s = s.Left(s.GetCount()-1);
}
s = s.Left(len);
}
val[SIMPLIFY_VALUE].Set("\"" + s + "\"");
val.FindAdd(SIMPLIFY_HINT, SIMPLIFY_SIMPLE);
// no need for further evaluation on this object
return false;
}
catch(...)
{
return false;
}
}
static bool UppVectorSimplify(Gdb_MI2 &gdb, MIValue &val, bool deep)
{
// if we're just doing first scan phase, signal that we need further evaluation later
#ifdef EVALDEEP
if(!deep)
return true;
#endif
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
String vals;
int count = min(EVALDEEP_VECTOR, items);
//RLOG("COUNT : " << count);
#ifdef EVALDEEP
if(count)
{
vals = ": [ ... ]";
String expr = vectorExpr + Format("[0]@%d", count);
MIValue vi = gdb.Evaluate(expr);
//RLOG(vi.Dump());
if(vi.IsArray() && vi.GetCount() && vi[0][SIMPLIFY_VALUE].IsString())
{
vals = ": [ ";
for(int i = 0; i < vi.GetCount(); i++)
vals = vals + vi[i][SIMPLIFY_VALUE].ToString() + " , ";
if(count < items)
vals << "... ]";
else
vals = vals.Left(vals.GetCount() - 2) + "]";
}
}
#else
if(count)
vals = ": [ ... ]";
#endif
vals = Format("Upp::Vector with %d elements %s", items, vals);
val[SIMPLIFY_VALUE].Set(vals);
// signal we've done a deep evaluation
#ifdef EVALDEEP
return true;
#else
return false;
#endif
}
catch(...)
{
return false;
}
}
static bool UppVectorMapSimplify(Gdb_MI2 &gdb, MIValue &val, bool deep)
{
//RLOG(val.Dump());
// if we're just doing first scan phase, signal that we need further evaluation later
#ifdef EVALDEEP
if(!deep)
return true;
#endif
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 5 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
String vals;
int count = min(EVALDEEP_VECTORMAP, items);
#ifdef EVALDEEP
if(count)
{
vals = ": { ... }";
String kExpr = keyExpr + Format("[0]@%d", count);
MIValue viKey = gdb.Evaluate(kExpr);
if(viKey.IsArray() && viKey[0][SIMPLIFY_VALUE].IsString())
{
String vExpr = valExpr + Format("[0]@%d", count);
MIValue viVal = gdb.Evaluate(vExpr);
if(viVal.IsArray() && viVal[0][SIMPLIFY_VALUE].IsString())
{
vals = ": { ";
for(int i = 0; i < viKey.GetCount(); i++)
vals << "( " << viKey[i][SIMPLIFY_VALUE].ToString() << " , " << viVal[i][SIMPLIFY_VALUE].ToString() << " ) , ";
if(count < items)
vals << "... }";
else
vals = vals.Left(vals.GetCount() - 2) + "}";
}
//RLOG(vals);
}
}
#else
if(count)
vals = ": { ... }";
#endif
vals = Format("Upp::VectorMap with %d elements %s", items, vals);
val[SIMPLIFY_VALUE].Set(vals);
// signal we've done a deep evaluation
#ifdef EVALDEEP
return true;
#else
return false;
#endif
}
catch(...)
{
return false;
}
}
static bool UppArraySimplify(Gdb_MI2 &gdb, MIValue &val, bool deep)
{
//RLOG(val.Dump());
// if we're just doing first scan phase, signal that we need further evaluation later
#ifdef EVALDEEP
if(!deep)
return true;
#endif
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
String vals;
int count = min(EVALDEEP_ARRAY, items);
#ifdef EVALDEEP
if(count)
{
// pre-fetch main array variable to speedup element request
gdb.MICmd("gdb-set variable $thearray=" + vectorExpr);
// get array elements
vals = ": [ ... ]";
String expr = "{";
for(int i = 0; i < count; i++)
expr << Format("$thearray[%d][0]", i) << ",";
expr = expr.Left(expr.GetCount()-1) + "}";
MIValue vi = gdb.Evaluate(expr);
if(vi.IsArray() && vi.GetCount() && vi[0][SIMPLIFY_VALUE].IsString())
{
vals = ": [ ";
for(int i = 0; i < vi.GetCount(); i++)
vals = vals + vi[i][SIMPLIFY_VALUE].ToString() + " , ";
if(count < items)
vals << "... ]";
else
vals = vals.Left(vals.GetCount() - 2) + "]";
}
}
#else
if(count)
vals = ": [ ... ]";
#endif
vals = Format("Upp::Array with %d elements %s", items, vals);
val[SIMPLIFY_VALUE].Set(vals);
// signal we've done a deep evaluation
#ifdef EVALDEEP
return true;
#else
return false;
#endif
}
catch(...)
{
return false;
}
}
static bool UppArrayMapSimplify(Gdb_MI2 &gdb, MIValue &val, bool deep)
{
//RLOG(val.Dump());
// if we're just doing first scan phase, signal that we need further evaluation later
#ifdef EVALDEEP
if(!deep)
return true;
#endif
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
String vals;
int count = min(EVALDEEP_ARRAYMAP, items);
#ifdef EVALDEEP
if(count)
{
// pre-fetch main array variable to speedup element request
gdb.MICmd("gdb-set variable $thearray=" + valExpr);
vals = ": { ... }";
String kExpr = keyExpr + Format("[0]@%d", count);
MIValue viKey = gdb.Evaluate(kExpr);
if(viKey.IsArray() && viKey[0][SIMPLIFY_VALUE].IsString())
{
String vExpr = "{";
for(int i = 0; i < count; i++)
vExpr << Format("$thearray[%d][0]", i) << ",";
vExpr = vExpr.Left(vExpr.GetCount()-1) + "}";
MIValue viVal = gdb.Evaluate(vExpr);
if(viVal.IsArray() && viVal[0][SIMPLIFY_VALUE].IsString())
{
vals = ": { ";
for(int i = 0; i < viKey.GetCount(); i++)
vals << "( " << viKey[i][SIMPLIFY_VALUE].ToString() << " , " << viVal[i][SIMPLIFY_VALUE].ToString() << " ) , ";
if(count < items)
vals << "... }";
else
vals = vals.Left(vals.GetCount() - 2) + "}";
}
//RLOG(vals);
}
}
#else
if(count)
vals = ": { ... }";
#endif
vals = Format("Upp::ArrayMap with %d elements %s", items, vals);
val[SIMPLIFY_VALUE].Set(vals);
// signal we've done a deep evaluation
#ifdef EVALDEEP
return true;
#else
return false;
#endif
}
catch(...)
{
return false;
}
}
static bool UppIndexSimplify(Gdb_MI2 &gdb, MIValue &val, bool deep)
{
//RLOG(val.Dump());
// if we're just doing first scan phase, signal that we need further evaluation later
#ifdef EVALDEEP
if(!deep)
return true;
#endif
try
{
MIValue &keyExpr = val[SIMPLIFY_VALUE][1][SIMPLIFY_VALUE]["key"][SIMPLIFY_VALUE];
String vectorExpr = keyExpr["vector"][SIMPLIFY_EXPR];
int items = atoi(keyExpr["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
String vals;
int count = min(EVALDEEP_INDEX, items);
#ifdef EVALDEEP
if(count)
{
vals = ": [ ... ]";
String expr = vectorExpr << Format("[0]@%d", count);
MIValue vi = gdb.Evaluate(expr);
if(vi.IsArray() && vi.GetCount() && vi[0][SIMPLIFY_VALUE].IsString())
{
vals = ": [ ";
for(int i = 0; i < vi.GetCount(); i++)
vals = vals + vi[i][SIMPLIFY_VALUE].ToString() + " , ";
if(count < items)
vals << "... ]";
else
vals = vals.Left(vals.GetCount() - 2) + "]";
}
}
#else
if(count)
vals = ": [ ... ]";
#endif
vals = Format("Upp::Index with %d elements %s", items, vals);
val[SIMPLIFY_VALUE].Set(vals);
// signal we've done a deep evaluation
#ifdef EVALDEEP
return true;
#else
return false;
#endif
}
catch(...)
{
return false;
}
}
// Register the simplifiers
REGISTERSIMPLIFIER("<Upp::Moveable<Upp::String,Upp::AString<Upp::String0>>>" , UppStringSimplify);
REGISTERSIMPLIFIER("<Upp::MoveableAndDeepCopyOption<Upp::Vector<" , UppVectorSimplify);
REGISTERSIMPLIFIER("<Upp::MoveableAndDeepCopyOption<Upp::VectorMap<" , UppVectorMapSimplify);
REGISTERSIMPLIFIER("<Upp::MoveableAndDeepCopyOption<Upp::Array<" , UppArraySimplify);
REGISTERSIMPLIFIER("<Upp::MoveableAndDeepCopyOption<Upp::ArrayMap<" , UppArrayMapSimplify);
REGISTERSIMPLIFIER("<Upp::MoveableAndDeepCopyOption<Upp::Index<" , UppIndexSimplify);