mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-21 14:55:57 -06:00
Ide/Debuggers/Gdb_MI2 : massive cleanup and some bugfixes
git-svn-id: svn://ultimatepp.org/upp/trunk@4875 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
3d4369aa3d
commit
408688d24a
3 changed files with 411 additions and 372 deletions
|
|
@ -10,7 +10,7 @@ void Gdb_MI2::DebugBar(Bar& bar)
|
|||
{
|
||||
bar.Add("Stop debugging", THISBACK(Stop)).Key(K_SHIFT_F5);
|
||||
bar.Separator();
|
||||
bar.Add("Asynchronous break", THISBACK(AsyncBrk));
|
||||
bar.Add(!stopped, "Asynchronous break", THISBACK(AsyncBrk));
|
||||
bool b = !IdeIsDebugLock();
|
||||
bar.Add(b, "Step into", DbgImg::StepInto(), THISBACK1(Step, disas.HasFocus() ? "exec-step-instruction" : "exec-step")).Key(K_F11);
|
||||
bar.Add(b, "Step over", DbgImg::StepOver(), THISBACK1(Step, disas.HasFocus() ? "exec-next-instruction" : "exec-next")).Key(K_F10);
|
||||
|
|
@ -515,7 +515,6 @@ MIValue Gdb_MI2::MICmd(const char *cmdLine)
|
|||
// is there and gives problems to MI interface. We shall maybe
|
||||
// parse and store it somewhere
|
||||
ReadGdb(false);
|
||||
|
||||
dbg->Write(String("-") + cmdLine + "\n");
|
||||
|
||||
return ReadGdb();
|
||||
|
|
@ -729,7 +728,12 @@ void Gdb_MI2::CheckStopReason(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
LogFrame(Format("Stopped, reason '%s'", reason), stopReason["frame"]);
|
||||
// weird stop reasons (i.e., signals, segfaults... may not have a frame
|
||||
// data inside
|
||||
if(stopReason.Find("frame") < 0)
|
||||
PutConsole(Format("Stopped, reason '%s'", reason));
|
||||
else
|
||||
LogFrame(Format("Stopped, reason '%s'", reason), stopReason["frame"]);
|
||||
SyncIde();
|
||||
}
|
||||
}
|
||||
|
|
@ -893,31 +897,23 @@ void Gdb_MI2::UpdateVars(void)
|
|||
MIValue &updated = iUpdated["changelist"];
|
||||
for(int iUpd = 0; iUpd < updated.GetCount(); iUpd++)
|
||||
{
|
||||
if(!updated[iUpd].IsTuple() || iUpdated.Find("name") < 0 || iUpdated.Find("value") < 0)
|
||||
if(!updated[iUpd].IsTuple() || updated[iUpd].Find("name") < 0 || updated[iUpd].Find("value") < 0)
|
||||
return;
|
||||
String varName = updated[iUpd]["name"];
|
||||
String value = updated[iUpd]["value"];
|
||||
int iVar;
|
||||
|
||||
// local variables
|
||||
if( (iVar = localVarNames.Find(varName)) >= 0)
|
||||
{
|
||||
if( updated[iUpd].Find("value") >= 0)
|
||||
localVarValues[iVar] = updated[iUpd]["value"];
|
||||
}
|
||||
localVarValues[iVar] = value;
|
||||
|
||||
// watches
|
||||
if( (iVar = watchesNames.Find(varName)) >= 0)
|
||||
{
|
||||
if( updated[iUpd].Find("value") >= 0)
|
||||
watchesValues[iVar] = updated[iUpd]["value"];
|
||||
}
|
||||
watchesValues[iVar] = value;
|
||||
|
||||
// autos
|
||||
if( (iVar = autosNames.Find(varName)) >= 0)
|
||||
{
|
||||
if( updated[iUpd].Find("value") >= 0)
|
||||
autosValues[iVar] = updated[iUpd]["value"];
|
||||
}
|
||||
autosValues[iVar] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -966,6 +962,7 @@ void Gdb_MI2::UpdateLocalVars(void)
|
|||
// still not active; we just skip them
|
||||
if(var.IsError() || var.IsEmpty())
|
||||
continue;
|
||||
|
||||
localVarNames.Add(var["name"]);
|
||||
localVarExpressions.Add(locIdx[iLoc]);
|
||||
localVarTypes.Add(var["type"]);
|
||||
|
|
|
|||
|
|
@ -1,355 +1,397 @@
|
|||
#include "MIValue.h"
|
||||
|
||||
MIValue NullMIValue;
|
||||
|
||||
int MIValue::ParsePair(String &name, MIValue &val, String const &s, int i)
|
||||
{
|
||||
name.Clear();
|
||||
val.Clear();
|
||||
while(s[i] && (s[i] != '=') && s[i] != ']' && s[i] != '}')
|
||||
name.Cat(s[i++]);
|
||||
if(s[i] != '=')
|
||||
return i;
|
||||
i++;
|
||||
switch(s[i])
|
||||
{
|
||||
case '"':
|
||||
{
|
||||
i = val.ParseString(s, i);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case '[':
|
||||
i = val.ParseArray(s, i);
|
||||
break;
|
||||
|
||||
case '{':
|
||||
i = val.ParseTuple(s, i);
|
||||
break;
|
||||
|
||||
default:
|
||||
NEVER();
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int MIValue::ParseTuple(String const &s, int i)
|
||||
{
|
||||
Clear();
|
||||
type = MITuple;
|
||||
|
||||
// drop opening delimiter
|
||||
ASSERT(s[i] == '{');
|
||||
i++;
|
||||
while(s[i] && s[i] != '}')
|
||||
{
|
||||
String name;
|
||||
MIValue val;
|
||||
i = ParsePair(name, val, s, i);
|
||||
tuple.Add(name, val);
|
||||
if(s[i] == '}')
|
||||
break;
|
||||
ASSERT(s[i] == ',');
|
||||
i++;
|
||||
}
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
int MIValue::ParseArray(String const &s, int i)
|
||||
{
|
||||
Clear();
|
||||
type = MIArray;
|
||||
|
||||
// drop opening delimiter
|
||||
ASSERT(s[i] == '[');
|
||||
i++;
|
||||
while(s[i] && s[i] != ']')
|
||||
{
|
||||
String name;
|
||||
MIValue val;
|
||||
if(s[i] == '[')
|
||||
i = val.ParseArray(s, i);
|
||||
else if(s[i] == '{')
|
||||
i = val.ParseTuple(s, i);
|
||||
else if(s[i] == '"')
|
||||
i = val.ParseString(s, i);
|
||||
else
|
||||
i = ParsePair(name, val, s, i);
|
||||
array.Add(val);
|
||||
if(s[i] == ']')
|
||||
break;
|
||||
ASSERT(s[i] == ',');
|
||||
i++;
|
||||
}
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
int MIValue::ParseString(String const &s, int i)
|
||||
{
|
||||
Clear();
|
||||
type = MIString;
|
||||
|
||||
char c;
|
||||
ASSERT(s[i] == '"');
|
||||
i++;
|
||||
while( (c = s[i++]) != 0)
|
||||
{
|
||||
// verbatim if escaped
|
||||
if(c == '\\')
|
||||
string.Cat(s[i++]);
|
||||
else if(c == '"')
|
||||
break;
|
||||
else
|
||||
string.Cat(c);
|
||||
}
|
||||
ASSERT(c == '"');
|
||||
return i;
|
||||
}
|
||||
|
||||
int MIValue::Parse(String const &s, int i)
|
||||
{
|
||||
// if starts with '"', it's a string
|
||||
// if starts with '[', it's an array
|
||||
// if starts with '{', it's a tuple
|
||||
// otherwise, it can be a sequence of pair name="value" which is stored like a tuple
|
||||
// latter case is an example o bad design of MI interface....
|
||||
Clear();
|
||||
if(s[i] == '"')
|
||||
return ParseString(s, i);
|
||||
else if(s[i] == '[')
|
||||
return ParseArray(s, i);
|
||||
else if(s[i] == '{')
|
||||
return ParseTuple(s, i);
|
||||
else
|
||||
{
|
||||
String name;
|
||||
MIValue val;
|
||||
type = MITuple;
|
||||
while(s[i])
|
||||
{
|
||||
i = ParsePair(name, val, s, i);
|
||||
tuple.Add(name, val);
|
||||
if(s[i] != ',')
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
MIValue &MIValue::operator=(pick_ MIValue &v)
|
||||
{
|
||||
Clear();
|
||||
type = v.type;
|
||||
switch(type)
|
||||
{
|
||||
case MIString:
|
||||
string = v.string;
|
||||
break;
|
||||
case MIArray:
|
||||
array = v.array;
|
||||
break;
|
||||
case MITuple:
|
||||
tuple = v.tuple;
|
||||
break;
|
||||
default:
|
||||
NEVER();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
MIValue::MIValue()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
MIValue::MIValue(MIValue pick_ &v)
|
||||
{
|
||||
Clear();
|
||||
type = v.type;
|
||||
switch(type)
|
||||
{
|
||||
case MIString:
|
||||
string = v.string;
|
||||
break;
|
||||
case MIArray:
|
||||
array = v.array;
|
||||
break;
|
||||
case MITuple:
|
||||
tuple = v.tuple;
|
||||
break;
|
||||
default:
|
||||
NEVER();
|
||||
}
|
||||
}
|
||||
|
||||
MIValue::MIValue(String const &s)
|
||||
{
|
||||
Parse(s);
|
||||
}
|
||||
|
||||
MIValue &MIValue::operator=(String const &s)
|
||||
{
|
||||
Parse(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void MIValue::Clear()
|
||||
{
|
||||
type = MIString;
|
||||
string = "";
|
||||
array.Clear();
|
||||
tuple.Clear();
|
||||
}
|
||||
|
||||
// sets value to an error condition
|
||||
MIValue &MIValue::SetError(String const &msg)
|
||||
{
|
||||
type = MIString;
|
||||
string = "error:" + msg;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// check if value contains an error
|
||||
bool MIValue::IsError(void)
|
||||
{
|
||||
return type == MIString && string.StartsWith("error:");
|
||||
}
|
||||
|
||||
// check for emptyness
|
||||
bool MIValue::IsEmpty(void)
|
||||
{
|
||||
return type == MIString && string == "";
|
||||
}
|
||||
|
||||
// simple accessors
|
||||
int MIValue::GetCount(void) const
|
||||
{
|
||||
if(type == MIArray)
|
||||
return array.GetCount();
|
||||
else if(type == MITuple)
|
||||
return tuple.GetCount();
|
||||
else
|
||||
NEVER();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int MIValue::Find(const char *key) const
|
||||
{
|
||||
ASSERT(type == MITuple);
|
||||
return tuple.Find(key);
|
||||
}
|
||||
|
||||
MIValue &MIValue::Get(int i)
|
||||
{
|
||||
ASSERT(type == MIArray);
|
||||
return array[i];
|
||||
}
|
||||
|
||||
MIValue &MIValue::Get(const char *key)
|
||||
{
|
||||
ASSERT(type == MITuple);
|
||||
return tuple.Get(key);
|
||||
}
|
||||
|
||||
String &MIValue::Get(void)
|
||||
{
|
||||
ASSERT(type == MIString);
|
||||
return string;
|
||||
}
|
||||
|
||||
String const &MIValue::Get(void) const
|
||||
{
|
||||
ASSERT(type == MIString);
|
||||
return string;
|
||||
}
|
||||
|
||||
// tuple string member accessor with default value if not found
|
||||
String MIValue::Get(const char *key, const char *def) const
|
||||
{
|
||||
ASSERT(type == MITuple);
|
||||
int i = tuple.Find(key);
|
||||
if(i >= 0)
|
||||
{
|
||||
ASSERT(tuple[i].type == MIString);
|
||||
return tuple[i].Get();
|
||||
}
|
||||
else
|
||||
return def;
|
||||
}
|
||||
|
||||
// data dump
|
||||
String MIValue::Dump(int level)
|
||||
{
|
||||
String spacer(' ', level);
|
||||
switch(type)
|
||||
{
|
||||
case MIString:
|
||||
return spacer + string;
|
||||
|
||||
case MITuple:
|
||||
{
|
||||
String s = spacer + "{\n";
|
||||
level += 4;
|
||||
spacer = String(' ', level);
|
||||
for(int i = 0; i < tuple.GetCount(); i++)
|
||||
{
|
||||
String s1 = spacer + tuple.GetKey(i) + "=";
|
||||
s += s1;
|
||||
MIValue &val = tuple[i];
|
||||
if(val.type == MIString)
|
||||
s += val.Dump();
|
||||
else
|
||||
{
|
||||
s += '\n' + val.Dump(level + 4);
|
||||
s = s.Left(s.GetCount()-1);
|
||||
}
|
||||
if(i < tuple.GetCount() - 1)
|
||||
s += ',';
|
||||
s += '\n';
|
||||
}
|
||||
level -= 4;
|
||||
spacer = String(' ', level);
|
||||
s += spacer + "}\n";
|
||||
return s;
|
||||
}
|
||||
|
||||
case MIArray:
|
||||
{
|
||||
String s = spacer + "[ \n";
|
||||
level += 4;
|
||||
for(int i = 0; i < array.GetCount(); i++)
|
||||
{
|
||||
MIValue &val = array[i];
|
||||
s += val.Dump(level);
|
||||
if(val.type != MIString)
|
||||
s = s.Left(s.GetCount()-1);
|
||||
if(i < array.GetCount() - 1)
|
||||
s += ',';
|
||||
s += '\n';
|
||||
}
|
||||
s += spacer + "]\n";
|
||||
return s;
|
||||
}
|
||||
|
||||
default:
|
||||
NEVER();
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
// finds breakpoint data given file and line
|
||||
MIValue &MIValue::FindBreakpoint(String const &file, int line)
|
||||
{
|
||||
MIValue &body = Get("body");
|
||||
body.AssertArray();
|
||||
for(int i = 0; i < body.GetCount(); i++)
|
||||
{
|
||||
MIValue &bp = body[i];
|
||||
bp.AssertTuple();
|
||||
if(bp["file"] == file && atoi(bp["line"].Get()) == line)
|
||||
return bp;
|
||||
}
|
||||
return NullMIValue;
|
||||
}
|
||||
#include "MIValue.h"
|
||||
|
||||
static MIValue &NullMIValue(void)
|
||||
{
|
||||
static MIValue v;
|
||||
return v;
|
||||
}
|
||||
|
||||
static MIValue &ErrorMIValue(String const &msg)
|
||||
{
|
||||
static MIValue v;
|
||||
v.SetError(msg);
|
||||
return v;
|
||||
}
|
||||
|
||||
int MIValue::ParsePair(String &name, MIValue &val, String const &s, int i)
|
||||
{
|
||||
name.Clear();
|
||||
val.Clear();
|
||||
while(s[i] && (s[i] != '=') && s[i] != ']' && s[i] != '}')
|
||||
name.Cat(s[i++]);
|
||||
if(s[i] != '=')
|
||||
return i;
|
||||
i++;
|
||||
switch(s[i])
|
||||
{
|
||||
case '"':
|
||||
{
|
||||
i = val.ParseString(s, i);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case '[':
|
||||
i = val.ParseArray(s, i);
|
||||
break;
|
||||
|
||||
case '{':
|
||||
i = val.ParseTuple(s, i);
|
||||
break;
|
||||
|
||||
default:
|
||||
NEVER();
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int MIValue::ParseTuple(String const &s, int i)
|
||||
{
|
||||
Clear();
|
||||
type = MITuple;
|
||||
|
||||
// drop opening delimiter
|
||||
if(s[i] != '{')
|
||||
{
|
||||
SetError(Format("Expected '{' at pos %d in '%s'", i, s));
|
||||
return s.GetCount();
|
||||
}
|
||||
i++;
|
||||
while(s[i] && s[i] != '}')
|
||||
{
|
||||
String name;
|
||||
MIValue val;
|
||||
i = ParsePair(name, val, s, i);
|
||||
tuple.Add(name, val);
|
||||
if(s[i] == '}')
|
||||
break;
|
||||
if(s[i] != ',')
|
||||
{
|
||||
SetError(Format("Expected ',' at pos %d in '%s'", i, s));
|
||||
return s.GetCount();
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
int MIValue::ParseArray(String const &s, int i)
|
||||
{
|
||||
Clear();
|
||||
type = MIArray;
|
||||
|
||||
// drop opening delimiter
|
||||
if(s[i] != '[')
|
||||
{
|
||||
SetError(Format("Expected '[' at pos %d in '%s'", i, s));
|
||||
return s.GetCount();
|
||||
}
|
||||
i++;
|
||||
while(s[i] && s[i] != ']')
|
||||
{
|
||||
String name;
|
||||
MIValue val;
|
||||
if(s[i] == '[')
|
||||
i = val.ParseArray(s, i);
|
||||
else if(s[i] == '{')
|
||||
i = val.ParseTuple(s, i);
|
||||
else if(s[i] == '"')
|
||||
i = val.ParseString(s, i);
|
||||
else
|
||||
i = ParsePair(name, val, s, i);
|
||||
array.Add(val);
|
||||
if(s[i] == ']')
|
||||
break;
|
||||
if(s[i] != ',')
|
||||
{
|
||||
SetError(Format("Expected ',' at pos %d in '%s'", i, s));
|
||||
return s.GetCount();
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
int MIValue::ParseString(String const &s, int i)
|
||||
{
|
||||
Clear();
|
||||
type = MIString;
|
||||
|
||||
char c;
|
||||
if(s[i] != '"')
|
||||
{
|
||||
SetError(Format("Expected '\"' at pos %d in '%s'", i, s));
|
||||
return s.GetCount();
|
||||
}
|
||||
i++;
|
||||
while( (c = s[i++]) != 0)
|
||||
{
|
||||
// verbatim if escaped
|
||||
if(c == '\\')
|
||||
string.Cat(s[i++]);
|
||||
else if(c == '"')
|
||||
break;
|
||||
else
|
||||
string.Cat(c);
|
||||
}
|
||||
if(c != '"')
|
||||
{
|
||||
SetError(Format("Expected '\"' at pos %d in '%s'", i, s));
|
||||
return s.GetCount();
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int MIValue::Parse(String const &s, int i)
|
||||
{
|
||||
// if starts with '"', it's a string
|
||||
// if starts with '[', it's an array
|
||||
// if starts with '{', it's a tuple
|
||||
// otherwise, it can be a sequence of pair name="value" which is stored like a tuple
|
||||
// latter case is an example o bad design of MI interface....
|
||||
Clear();
|
||||
if(s[i] == '"')
|
||||
return ParseString(s, i);
|
||||
else if(s[i] == '[')
|
||||
return ParseArray(s, i);
|
||||
else if(s[i] == '{')
|
||||
return ParseTuple(s, i);
|
||||
else
|
||||
{
|
||||
String name;
|
||||
MIValue val;
|
||||
type = MITuple;
|
||||
while(s[i])
|
||||
{
|
||||
i = ParsePair(name, val, s, i);
|
||||
tuple.Add(name, val);
|
||||
if(s[i] != ',')
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
MIValue &MIValue::operator=(pick_ MIValue &v)
|
||||
{
|
||||
Clear();
|
||||
type = v.type;
|
||||
switch(type)
|
||||
{
|
||||
case MIString:
|
||||
string = v.string;
|
||||
break;
|
||||
case MIArray:
|
||||
array = v.array;
|
||||
break;
|
||||
case MITuple:
|
||||
tuple = v.tuple;
|
||||
break;
|
||||
default:
|
||||
SetError("Unknown MIValue type");
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
MIValue::MIValue()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
MIValue::MIValue(MIValue pick_ &v)
|
||||
{
|
||||
Clear();
|
||||
type = v.type;
|
||||
switch(type)
|
||||
{
|
||||
case MIString:
|
||||
string = v.string;
|
||||
break;
|
||||
case MIArray:
|
||||
array = v.array;
|
||||
break;
|
||||
case MITuple:
|
||||
tuple = v.tuple;
|
||||
break;
|
||||
default:
|
||||
SetError("Unknown MIValue type");
|
||||
}
|
||||
}
|
||||
|
||||
MIValue::MIValue(String const &s)
|
||||
{
|
||||
Parse(s);
|
||||
}
|
||||
|
||||
MIValue &MIValue::operator=(String const &s)
|
||||
{
|
||||
Parse(s);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void MIValue::Clear()
|
||||
{
|
||||
type = MIString;
|
||||
string = "";
|
||||
array.Clear();
|
||||
tuple.Clear();
|
||||
}
|
||||
|
||||
// sets value to an error condition
|
||||
MIValue &MIValue::SetError(String const &msg)
|
||||
{
|
||||
type = MIString;
|
||||
string = "error:" + msg;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// check if value contains an error
|
||||
bool MIValue::IsError(void)
|
||||
{
|
||||
return type == MIString && string.StartsWith("error:");
|
||||
}
|
||||
|
||||
// check for emptyness
|
||||
bool MIValue::IsEmpty(void)
|
||||
{
|
||||
return type == MIString && string == "";
|
||||
}
|
||||
|
||||
// simple accessors
|
||||
int MIValue::GetCount(void) const
|
||||
{
|
||||
if(type == MIArray)
|
||||
return array.GetCount();
|
||||
else if(type == MITuple)
|
||||
return tuple.GetCount();
|
||||
else
|
||||
return string.GetCount();
|
||||
}
|
||||
|
||||
int MIValue::Find(const char *key) const
|
||||
{
|
||||
if(type != MITuple)
|
||||
return -1;
|
||||
return tuple.Find(key);
|
||||
}
|
||||
|
||||
MIValue &MIValue::Get(int i)
|
||||
{
|
||||
if(type != MIArray)
|
||||
return ErrorMIValue("Not an Array value type");
|
||||
return array[i];
|
||||
}
|
||||
|
||||
MIValue &MIValue::Get(const char *key)
|
||||
{
|
||||
if(type != MITuple)
|
||||
return ErrorMIValue("Not a Tuple value type");
|
||||
return tuple.Get(key);
|
||||
}
|
||||
|
||||
String &MIValue::Get(void)
|
||||
{
|
||||
if(type != MIString)
|
||||
return ErrorMIValue("Not a String value type");
|
||||
return string;
|
||||
}
|
||||
|
||||
String const &MIValue::Get(void) const
|
||||
{
|
||||
if(type != MIString)
|
||||
return ErrorMIValue("Not a String value type");
|
||||
return string;
|
||||
}
|
||||
|
||||
// tuple string member accessor with default value if not found
|
||||
String MIValue::Get(const char *key, const char *def) const
|
||||
{
|
||||
if(type != MITuple)
|
||||
return def;
|
||||
int i = tuple.Find(key);
|
||||
if(i >= 0)
|
||||
{
|
||||
if(tuple[i].type != MIString)
|
||||
return def;
|
||||
return tuple[i].Get();
|
||||
}
|
||||
else
|
||||
return def;
|
||||
}
|
||||
|
||||
// data dump
|
||||
String MIValue::Dump(int level)
|
||||
{
|
||||
String spacer(' ', level);
|
||||
switch(type)
|
||||
{
|
||||
case MIString:
|
||||
return spacer + string;
|
||||
|
||||
case MITuple:
|
||||
{
|
||||
String s = spacer + "{\n";
|
||||
level += 4;
|
||||
spacer = String(' ', level);
|
||||
for(int i = 0; i < tuple.GetCount(); i++)
|
||||
{
|
||||
String s1 = spacer + tuple.GetKey(i) + "=";
|
||||
s += s1;
|
||||
MIValue &val = tuple[i];
|
||||
if(val.type == MIString)
|
||||
s += val.Dump();
|
||||
else
|
||||
{
|
||||
s += '\n' + val.Dump(level + 4);
|
||||
s = s.Left(s.GetCount()-1);
|
||||
}
|
||||
if(i < tuple.GetCount() - 1)
|
||||
s += ',';
|
||||
s += '\n';
|
||||
}
|
||||
level -= 4;
|
||||
spacer = String(' ', level);
|
||||
s += spacer + "}\n";
|
||||
return s;
|
||||
}
|
||||
|
||||
case MIArray:
|
||||
{
|
||||
String s = spacer + "[ \n";
|
||||
level += 4;
|
||||
for(int i = 0; i < array.GetCount(); i++)
|
||||
{
|
||||
MIValue &val = array[i];
|
||||
s += val.Dump(level);
|
||||
if(val.type != MIString)
|
||||
s = s.Left(s.GetCount()-1);
|
||||
if(i < array.GetCount() - 1)
|
||||
s += ',';
|
||||
s += '\n';
|
||||
}
|
||||
s += spacer + "]\n";
|
||||
return s;
|
||||
}
|
||||
|
||||
default:
|
||||
return spacer + "*UNKNOWN MIVALUE TYPE*";
|
||||
}
|
||||
}
|
||||
|
||||
// finds breakpoint data given file and line
|
||||
MIValue &MIValue::FindBreakpoint(String const &file, int line)
|
||||
{
|
||||
MIValue &body = Get("body");
|
||||
if(body.IsError() || !body.IsArray())
|
||||
return NullMIValue();
|
||||
for(int i = 0; i < body.GetCount(); i++)
|
||||
{
|
||||
MIValue &bp = body[i];
|
||||
if(bp.IsError() || !bp.IsTuple())
|
||||
return NullMIValue();
|
||||
if(bp["file"] == file && atoi(bp["line"].Get()) == line)
|
||||
return bp;
|
||||
}
|
||||
return NullMIValue();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class UppStringPrinter(object):
|
|||
if(IsSmall):
|
||||
ptr = CHR
|
||||
else:
|
||||
ptr = self.val[ptr]
|
||||
ptr = self.val['ptr']
|
||||
return '"' + ptr.string() + '"'
|
||||
|
||||
def display_hint(self):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue