mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-29 14:22:49 -06:00
422 lines
11 KiB
Text
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);
|
|
|