mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 17:19:19 +02:00
* Reduced stringmanipulation when parsing gdb mi result
git-svn-id: trunk@13810 -
This commit is contained in:
parent
e50a1ae171
commit
160f3905c4
@ -54,7 +54,7 @@ type
|
|||||||
|
|
||||||
function GetLine(var ABuffer: String): String;
|
function GetLine(var ABuffer: String): String;
|
||||||
function ConvertToCString(const AText: String): String;
|
function ConvertToCString(const AText: String): String;
|
||||||
function DeleteEscapeChars(const AValue: String; const ARemoveQuotes: Boolean = True; const AEscapeChar: Char = '\'): String;
|
function DeleteEscapeChars(const AValue: String; const AEscapeChar: Char = '\'): String;
|
||||||
function UnQuote(const AValue: String): String;
|
function UnQuote(const AValue: String): String;
|
||||||
|
|
||||||
|
|
||||||
@ -149,7 +149,7 @@ begin
|
|||||||
else Result := AValue;
|
else Result := AValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function DeleteEscapeChars(const AValue: String; const ARemoveQuotes: Boolean; const AEscapeChar: Char): String;
|
function DeleteEscapeChars(const AValue: String; const AEscapeChar: Char): String;
|
||||||
var
|
var
|
||||||
cnt, len: Integer;
|
cnt, len: Integer;
|
||||||
s: String;
|
s: String;
|
||||||
@ -158,15 +158,7 @@ begin
|
|||||||
len := Length(AValue);
|
len := Length(AValue);
|
||||||
if len = 0 then Exit('');
|
if len = 0 then Exit('');
|
||||||
|
|
||||||
if ARemoveQuotes and (len >= 2) and (AValue[1] = '"') and (AValue[len] = '"')
|
|
||||||
then begin
|
|
||||||
Dec(len, 2);
|
|
||||||
Src := @AValue[2];
|
|
||||||
if len = 0 then Exit('');
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
Src := @AValue[1];
|
Src := @AValue[1];
|
||||||
end;
|
|
||||||
cnt := len;
|
cnt := len;
|
||||||
SetLength(Result, len); // allocate initial space
|
SetLength(Result, len); // allocate initial space
|
||||||
|
|
||||||
|
@ -206,24 +206,37 @@ type
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
type
|
type
|
||||||
|
PGDBMINameValue = ^TGDBMINameValue;
|
||||||
|
TGDBMINameValue = record
|
||||||
|
NamePtr: PChar;
|
||||||
|
NameLen: Integer;
|
||||||
|
ValuePtr: PChar;
|
||||||
|
ValueLen: Integer;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TGDMIValueList }
|
{ TGDBMINameValueList }
|
||||||
TGDMIValueList = Class(TStringList)
|
TGDBMINameValueList = Class(TObject)
|
||||||
private
|
private
|
||||||
// function GetString(AIndex: Integer): string;
|
FText: String;
|
||||||
// function GetEscaped(AIndex: Integer): string;
|
FCount: Integer;
|
||||||
// function GetEscapedValues(const AName: string): string;
|
FIndex: array of TGDBMINameValue;
|
||||||
// function GetValue(const AName : string): string;
|
|
||||||
|
function Find(const AName : string): PGDBMINameValue;
|
||||||
|
function GetItem(const AIndex: Integer): PGDBMINameValue;
|
||||||
|
function GetValue(const AName : string): string;
|
||||||
public
|
public
|
||||||
constructor Create(const AResultValues: String);
|
constructor Create(const AResultValues: String);
|
||||||
constructor Create(AResult: TGDBMIExecResult);
|
constructor Create(AResult: TGDBMIExecResult);
|
||||||
constructor Create(const AResultValues: String; const APath: array of String);
|
constructor Create(const AResultValues: String; const APath: array of String);
|
||||||
constructor Create(AResult: TGDBMIExecResult; const APath: array of String);
|
constructor Create(AResult: TGDBMIExecResult; const APath: array of String);
|
||||||
procedure Init(AResultValues: String);
|
procedure Delete(AIndex: Integer);
|
||||||
|
procedure Init(const AResultValues: String);
|
||||||
|
procedure Init(AResultValues: PChar; ALength: Integer);
|
||||||
procedure SetPath(const APath: String); overload;
|
procedure SetPath(const APath: String); overload;
|
||||||
procedure SetPath(const APath: array of String); overload;
|
procedure SetPath(const APath: array of String); overload;
|
||||||
// property Strings[AIndex: Integer]: string read GetString; default;
|
property Count: Integer read FCount;
|
||||||
// property Values[const AName: string]: string read GetValue;
|
property Items[const AIndex: Integer]: PGDBMINameValue read GetItem;
|
||||||
|
property Values[const AName: string]: string read GetValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TGDBMIBreakPoint = class(TDBGBreakPoint)
|
TGDBMIBreakPoint = class(TDBGBreakPoint)
|
||||||
@ -340,151 +353,237 @@ type
|
|||||||
Tag: Integer;
|
Tag: Integer;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TGDMIValueList }
|
{ TGDBMINameValueList }
|
||||||
|
|
||||||
constructor TGDMIValueList.Create(const AResultValues: String);
|
constructor TGDBMINameValueList.Create(const AResultValues: String);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
Init(AResultValues);
|
Init(AResultValues);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TGDMIValueList.Create(const AResultValues: String; const APath: array of String);
|
constructor TGDBMINameValueList.Create(const AResultValues: String; const APath: array of String);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
Init(AResultValues);
|
Init(AResultValues);
|
||||||
SetPath(APath);
|
SetPath(APath);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TGDMIValueList.Create(AResult: TGDBMIExecResult);
|
constructor TGDBMINameValueList.Create(AResult: TGDBMIExecResult);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
Init(AResult.Values);
|
Init(AResult.Values);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TGDMIValueList.Create(AResult: TGDBMIExecResult; const APath: array of String);
|
constructor TGDBMINameValueList.Create(AResult: TGDBMIExecResult; const APath: array of String);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
Init(AResult.Values);
|
Init(AResult.Values);
|
||||||
SetPath(APath);
|
SetPath(APath);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TGDMIValueList.SetPath(const APath: String);
|
procedure TGDBMINameValueList.Delete(AIndex: Integer);
|
||||||
|
begin
|
||||||
|
if AIndex < 0 then Exit;
|
||||||
|
if AIndex >= FCount then Exit;
|
||||||
|
Dec(FCount);
|
||||||
|
Move(FIndex[AIndex + 1], FIndex[AIndex], SizeOf(FIndex[0]) * (FCount - AIndex));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGDBMINameValueList.Find(const AName: string): PGDBMINameValue;
|
||||||
|
var
|
||||||
|
n, len: Integer;
|
||||||
|
begin
|
||||||
|
if FCount = 0 then Exit(nil);
|
||||||
|
|
||||||
|
len := Length(AName);
|
||||||
|
Result := @FIndex[0];
|
||||||
|
for n := 0 to FCount - 1 do
|
||||||
|
begin
|
||||||
|
if (Result^.NameLen = len)
|
||||||
|
and (strlcomp(Result^.NamePtr, PChar(AName), len) = 0)
|
||||||
|
then Exit;
|
||||||
|
Inc(Result);
|
||||||
|
end;
|
||||||
|
Result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGDBMINameValueList.GetItem(const AIndex: Integer): PGDBMINameValue;
|
||||||
|
begin
|
||||||
|
if AIndex < 0 then Exit(nil);
|
||||||
|
if AIndex >= FCount then Exit(nil);
|
||||||
|
Result := @FIndex[AIndex];
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TGDBMINameValueList.GetValue(const AName: string): string;
|
||||||
|
var
|
||||||
|
item: PGDBMINameValue;
|
||||||
|
begin
|
||||||
|
Result := '';
|
||||||
|
if FCount = 0 then Exit;
|
||||||
|
item := Find(AName);
|
||||||
|
if item = nil then Exit;
|
||||||
|
|
||||||
|
SetLength(Result, Item^.ValueLen);
|
||||||
|
Move(Item^.ValuePtr^, Result[1], Item^.ValueLen);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMINameValueList.Init(AResultValues: PChar; ALength: Integer);
|
||||||
|
|
||||||
|
function FindNextQuote(ACurPtr, AEndPtr: PChar): PChar;
|
||||||
|
begin
|
||||||
|
Result := ACurPtr;
|
||||||
|
while Result <= AEndPtr do
|
||||||
|
begin
|
||||||
|
case Result^ of
|
||||||
|
'\': Inc(Result, 2);
|
||||||
|
'"': Break;
|
||||||
|
else
|
||||||
|
Inc(Result);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function FindClosingBracket(ACurPtr, AEndPtr: PChar): PChar;
|
||||||
|
var
|
||||||
|
deep: Integer;
|
||||||
|
begin
|
||||||
|
deep := 1;
|
||||||
|
Result := ACurPtr;
|
||||||
|
|
||||||
|
while Result <= AEndPtr do
|
||||||
|
begin
|
||||||
|
case Result^ of
|
||||||
|
'\': Inc(Result);
|
||||||
|
'"': Result := FindNextQuote(Result + 1, AEndPtr);
|
||||||
|
'[', '{': Inc(deep);
|
||||||
|
']', '}': begin
|
||||||
|
Dec(deep);
|
||||||
|
if deep = 0 then break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Inc(Result);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure Add(AStartPtr, AEquPtr, AEndPtr: PChar);
|
||||||
|
var
|
||||||
|
Item: PGDBMINameValue;
|
||||||
|
begin
|
||||||
|
if AEndPtr <= AStartPtr then Exit;
|
||||||
|
|
||||||
|
// check space
|
||||||
|
if Length(FIndex) <= FCount
|
||||||
|
then SetLength(FIndex, FCount + 16);
|
||||||
|
|
||||||
|
Item := @FIndex[FCount];
|
||||||
|
if AEquPtr < AStartPtr
|
||||||
|
then begin
|
||||||
|
// only name, no value
|
||||||
|
Item^.NamePtr := AStartPtr;
|
||||||
|
Item^.NameLen := PtrUInt(AEndPtr) - PtrUInt(AStartPtr) + 1;
|
||||||
|
Item^.ValuePtr := nil;
|
||||||
|
Item^.ValueLen := 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
Item^.NamePtr := AStartPtr;
|
||||||
|
Item^.NameLen := PtrUInt(AEquPtr) - PtrUInt(AStartPtr);
|
||||||
|
|
||||||
|
if (AEquPtr < AEndPtr - 1) and (AEquPtr[1] = '"') and (AEndPtr^ = '"')
|
||||||
|
then begin
|
||||||
|
// strip surrounding "
|
||||||
|
Item^.ValuePtr := AEquPtr + 2;
|
||||||
|
Item^.ValueLen := PtrUInt(AEndPtr) - PtrUInt(AEquPtr) - 2;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
Item^.ValuePtr := AEquPtr + 1;
|
||||||
|
Item^.ValueLen := PtrUInt(AEndPtr) - PtrUInt(AEquPtr)
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Inc(FCount);
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
CurPtr, StartPtr, EquPtr, EndPtr: PChar;
|
||||||
|
begin
|
||||||
|
// clear
|
||||||
|
FCount := 0;
|
||||||
|
|
||||||
|
if AResultValues = nil then Exit;
|
||||||
|
if ALength <= 0 then Exit;
|
||||||
|
EndPtr := AResultValues + ALength - 1;
|
||||||
|
|
||||||
|
// strip surrounding '[]' and '{}' first
|
||||||
|
case AResultValues^ of
|
||||||
|
'[': begin
|
||||||
|
if EndPtr^ = ']'
|
||||||
|
then begin
|
||||||
|
Inc(AResultValues);
|
||||||
|
Dec(EndPtr);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
'{': begin
|
||||||
|
if EndPtr^ = '}'
|
||||||
|
then begin
|
||||||
|
Inc(AResultValues);
|
||||||
|
Dec(EndPtr);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
StartPtr := AResultValues;
|
||||||
|
CurPtr := AResultValues;
|
||||||
|
EquPtr := nil;
|
||||||
|
while CurPtr <= EndPtr do
|
||||||
|
begin
|
||||||
|
case CurPtr^ of
|
||||||
|
'\': Inc(CurPtr); // skip escaped char
|
||||||
|
'"': CurPtr := FindNextQuote(CurPtr + 1, EndPtr);
|
||||||
|
'[',
|
||||||
|
'{': CurPtr := FindClosingBracket(CurPtr + 1, EndPtr);
|
||||||
|
'=': EquPtr := CurPtr;
|
||||||
|
',': begin
|
||||||
|
Add(StartPtr, EquPtr, CurPtr - 1);
|
||||||
|
Inc(CurPtr);
|
||||||
|
StartPtr := CurPtr;
|
||||||
|
Continue;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Inc(CurPtr);
|
||||||
|
end;
|
||||||
|
if StartPtr <= EndPtr
|
||||||
|
then Add(StartPtr, EquPtr, EndPtr);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMINameValueList.Init(const AResultValues: String);
|
||||||
|
begin
|
||||||
|
FText := AResultValues;
|
||||||
|
Init(PChar(FText), Length(FText));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TGDBMINameValueList.SetPath(const APath: String);
|
||||||
begin
|
begin
|
||||||
SetPath([APath]);
|
SetPath([APath]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TGDMIValueList.SetPath(const APath: array of String);
|
procedure TGDBMINameValueList.SetPath(const APath: array of String);
|
||||||
var
|
var
|
||||||
i: integer;
|
i: integer;
|
||||||
|
Item: PGDBMINameValue;
|
||||||
begin
|
begin
|
||||||
for i := low(APath) to High(APath) do
|
for i := low(APath) to High(APath) do
|
||||||
begin
|
begin
|
||||||
Init(Unquote(Values[APath[i]]));
|
item := Find(APath[i]);
|
||||||
end;
|
if item = nil
|
||||||
end;
|
|
||||||
|
|
||||||
(*
|
|
||||||
function TGDMIValueList.GetString(AIndex: Integer): string;
|
|
||||||
begin
|
|
||||||
Result := DeleteEscapeChars(inherited Strings[AIndex], '\', True);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGDMIValueList.GetEscaped(AIndex: Integer): string;
|
|
||||||
begin
|
|
||||||
Result := Unquote(inherited Strings[AIndex]);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGDMIValueList.GetEscapedValues(const AName: string): string;
|
|
||||||
begin
|
|
||||||
Result := Unquote(inherited Values[AName]);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGDMIValueList.GetValue(const AName: string): string;
|
|
||||||
begin
|
|
||||||
Result := DeleteEscapeChars(inherited Values[AName], '\', True);
|
|
||||||
end;
|
|
||||||
*)
|
|
||||||
|
|
||||||
procedure TGDMIValueList.Init(AResultValues: String);
|
|
||||||
function FindNextQuote(const S: String; idx: Integer) :Integer;
|
|
||||||
begin
|
|
||||||
while (idx <= Length(S)) do
|
|
||||||
begin
|
|
||||||
case S[idx] of
|
|
||||||
'\': Inc(idx, 2);
|
|
||||||
'"': Break;
|
|
||||||
else
|
|
||||||
inc(idx);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
result := idx;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function FindClosingBracket(const S: String; idx: Integer) :Integer;
|
|
||||||
var
|
|
||||||
deep, len: Integer;
|
|
||||||
c : Char;
|
|
||||||
begin
|
|
||||||
deep := 1;
|
|
||||||
len := Length(S);
|
|
||||||
while idx <= len do
|
|
||||||
begin
|
|
||||||
case S[idx] of
|
|
||||||
'\': Inc(idx);
|
|
||||||
'"': idx := FindNextQuote(S, idx + 1);
|
|
||||||
'[', '{': Inc(deep);
|
|
||||||
']', '}': Dec(deep);
|
|
||||||
end;
|
|
||||||
if deep = 0 then break;
|
|
||||||
Inc(idx);
|
|
||||||
end;
|
|
||||||
result := idx;
|
|
||||||
end;
|
|
||||||
|
|
||||||
var
|
|
||||||
n, len: Integer;
|
|
||||||
begin
|
|
||||||
Clear;
|
|
||||||
if AResultValues = '' then Exit;
|
|
||||||
// strip surrounding '[]' and '{}' first
|
|
||||||
case AResultValues[1] of
|
|
||||||
'[': begin
|
|
||||||
if AResultValues[Length(AResultValues)] = ']'
|
|
||||||
then begin
|
then begin
|
||||||
System.Delete(AResultValues, Length(AResultValues), 1);
|
FCount := 0;
|
||||||
System.Delete(AResultValues, 1, 1);
|
Exit;
|
||||||
end;
|
|
||||||
end;
|
|
||||||
'{': begin
|
|
||||||
if AResultValues[Length(AResultValues)] = '}'
|
|
||||||
then begin
|
|
||||||
System.Delete(AResultValues, Length(AResultValues), 1);
|
|
||||||
System.Delete(AResultValues, 1, 1);
|
|
||||||
end;
|
end;
|
||||||
|
Init(Item^.ValuePtr, Item^.ValueLen);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
n := 1;
|
|
||||||
len := Length(AResultValues);
|
|
||||||
while n <= len do
|
|
||||||
begin
|
|
||||||
case AResultValues[n] of
|
|
||||||
'\': Inc(n); // skip escaped char
|
|
||||||
'"': n := FindNextQuote(AResultValues, n + 1);
|
|
||||||
'[', '{': n := FindClosingBracket(AResultValues, n + 1);
|
|
||||||
',': begin
|
|
||||||
Add(Copy(AResultValues, 1, n - 1));
|
|
||||||
System.Delete(AResultValues, 1, n);
|
|
||||||
n := 1;
|
|
||||||
len := Length(AResultValues);
|
|
||||||
Continue;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
Inc(n);
|
|
||||||
end;
|
|
||||||
if AResultValues <> ''
|
|
||||||
then Add(AResultValues);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
{ Some win32 stuff }
|
{ Some win32 stuff }
|
||||||
@ -516,21 +615,6 @@ end;
|
|||||||
{ Helpers }
|
{ Helpers }
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
|
|
||||||
function CreateValueList(AResultValues: String): TStringList;
|
|
||||||
var
|
|
||||||
n: Integer;
|
|
||||||
begin
|
|
||||||
Result := TStringList.Create;
|
|
||||||
if AResultValues = '' then Exit;
|
|
||||||
n := Pos(' = ', AResultValues);
|
|
||||||
if n > 0
|
|
||||||
then begin
|
|
||||||
Delete(AResultValues, n, 1);
|
|
||||||
Delete(AResultValues, n + 1, 1);
|
|
||||||
end;
|
|
||||||
Result.Add(AResultValues);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function ConvertToGDBPath(APath: string): string;
|
function ConvertToGDBPath(APath: string): string;
|
||||||
// GDB wants forward slashes in its filenames, even on win32.
|
// GDB wants forward slashes in its filenames, even on win32.
|
||||||
begin
|
begin
|
||||||
@ -586,7 +670,7 @@ function TGDBMIDebugger.ChangeFileName: Boolean;
|
|||||||
var
|
var
|
||||||
S: String;
|
S: String;
|
||||||
R: TGDBMIExecResult;
|
R: TGDBMIExecResult;
|
||||||
List: TGDMIValueList;
|
List: TGDBMINameValueList;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
|
|
||||||
@ -601,7 +685,7 @@ begin
|
|||||||
if (R.State = dsError)
|
if (R.State = dsError)
|
||||||
and (FileName <> '')
|
and (FileName <> '')
|
||||||
then begin
|
then begin
|
||||||
List := TGDMIValueList.Create(R);
|
List := TGDBMINameValueList.Create(R);
|
||||||
MessageDlg('Debugger', Format('Failed to load file: %s', [DeleteEscapeChars((List.Values['msg']))]), mtError, [mbOK], 0);
|
MessageDlg('Debugger', Format('Failed to load file: %s', [DeleteEscapeChars((List.Values['msg']))]), mtError, [mbOK], 0);
|
||||||
List.Free;
|
List.Free;
|
||||||
SetState(dsStop);
|
SetState(dsStop);
|
||||||
@ -870,7 +954,7 @@ var
|
|||||||
OK: Boolean;
|
OK: Boolean;
|
||||||
S: String;
|
S: String;
|
||||||
R: TGDBMIExecResult;
|
R: TGDBMIExecResult;
|
||||||
ResultList: TGDMIValueList;
|
ResultList: TGDBMINameValueList;
|
||||||
begin
|
begin
|
||||||
Result := '';
|
Result := '';
|
||||||
|
|
||||||
@ -889,7 +973,7 @@ begin
|
|||||||
|
|
||||||
if OK
|
if OK
|
||||||
then begin
|
then begin
|
||||||
ResultList := TGDMIValueList.Create(R);
|
ResultList := TGDBMINameValueList.Create(R);
|
||||||
S := DeleteEscapeChars(ResultList.Values['value']);
|
S := DeleteEscapeChars(ResultList.Values['value']);
|
||||||
Result := GetPart('''', '''', S);
|
Result := GetPart('''', '''', S);
|
||||||
ResultList.Free;
|
ResultList.Free;
|
||||||
@ -1012,7 +1096,7 @@ function TGDBMIDebugger.GDBEvaluate(const AExpression: String;
|
|||||||
var
|
var
|
||||||
R: TGDBMIExecResult;
|
R: TGDBMIExecResult;
|
||||||
S: String;
|
S: String;
|
||||||
ResultList: TGDMIValueList;
|
ResultList: TGDBMINameValueList;
|
||||||
ResultInfo: TGDBType;
|
ResultInfo: TGDBType;
|
||||||
addr: TDbgPtr;
|
addr: TDbgPtr;
|
||||||
e: Integer;
|
e: Integer;
|
||||||
@ -1033,7 +1117,7 @@ begin
|
|||||||
|
|
||||||
Result := ExecuteCommand('-data-evaluate-expression %s', [S], [cfIgnoreError, cfExternal], R);
|
Result := ExecuteCommand('-data-evaluate-expression %s', [S], [cfIgnoreError, cfExternal], R);
|
||||||
|
|
||||||
ResultList := TGDMIValueList.Create(R);
|
ResultList := TGDBMINameValueList.Create(R);
|
||||||
if R.State = dsError
|
if R.State = dsError
|
||||||
then AResult := ResultList.Values['msg']
|
then AResult := ResultList.Values['msg']
|
||||||
else AResult := ResultList.Values['value'];
|
else AResult := ResultList.Values['value'];
|
||||||
@ -1254,12 +1338,12 @@ end;
|
|||||||
function TGDBMIDebugger.GetFrame(const AIndex: Integer): String;
|
function TGDBMIDebugger.GetFrame(const AIndex: Integer): String;
|
||||||
var
|
var
|
||||||
R: TGDBMIExecResult;
|
R: TGDBMIExecResult;
|
||||||
List: TGDMIValueList;
|
List: TGDBMINameValueList;
|
||||||
begin
|
begin
|
||||||
Result := '';
|
Result := '';
|
||||||
if ExecuteCommand('-stack-list-frames %d %d', [AIndex, AIndex], [cfIgnoreError], R)
|
if ExecuteCommand('-stack-list-frames %d %d', [AIndex, AIndex], [cfIgnoreError], R)
|
||||||
then begin
|
then begin
|
||||||
List := TGDMIValueList.Create(R, ['stack']);
|
List := TGDBMINameValueList.Create(R, ['stack']);
|
||||||
Result := List.Values['frame'];
|
Result := List.Values['frame'];
|
||||||
List.Free;
|
List.Free;
|
||||||
end;
|
end;
|
||||||
@ -1286,11 +1370,11 @@ end;
|
|||||||
function TGDBMIDebugger.GetStrValue(const AExpression: String; const AValues: array of const): String;
|
function TGDBMIDebugger.GetStrValue(const AExpression: String; const AValues: array of const): String;
|
||||||
var
|
var
|
||||||
R: TGDBMIExecResult;
|
R: TGDBMIExecResult;
|
||||||
ResultList: TGDMIValueList;
|
ResultList: TGDBMINameValueList;
|
||||||
begin
|
begin
|
||||||
if ExecuteCommand('-data-evaluate-expression %s', [Format(AExpression, AValues)], [cfIgnoreError], R)
|
if ExecuteCommand('-data-evaluate-expression %s', [Format(AExpression, AValues)], [cfIgnoreError], R)
|
||||||
then begin
|
then begin
|
||||||
ResultList := TGDMIValueList.Create(R);
|
ResultList := TGDBMINameValueList.Create(R);
|
||||||
Result := DeleteEscapeChars(ResultList.Values['value']);
|
Result := DeleteEscapeChars(ResultList.Values['value']);
|
||||||
ResultList.Free;
|
ResultList.Free;
|
||||||
end
|
end
|
||||||
@ -1558,7 +1642,7 @@ procedure TGDBMIDebugger.InterruptTargetCallback(const AResult: TGDBMIExecResult
|
|||||||
var
|
var
|
||||||
R: TGDBMIExecResult;
|
R: TGDBMIExecResult;
|
||||||
S: String;
|
S: String;
|
||||||
List: TGDMIValueList;
|
List: TGDBMINameValueList;
|
||||||
n: Integer;
|
n: Integer;
|
||||||
ID1, ID2: Integer;
|
ID1, ID2: Integer;
|
||||||
begin
|
begin
|
||||||
@ -1572,20 +1656,21 @@ begin
|
|||||||
|
|
||||||
S := '';
|
S := '';
|
||||||
if not ExecuteCommand('-thread-list-ids', [cfIgnoreError], R) then Exit;
|
if not ExecuteCommand('-thread-list-ids', [cfIgnoreError], R) then Exit;
|
||||||
List := TGDMIValueList.Create(R);
|
List := TGDBMINameValueList.Create(R);
|
||||||
try
|
try
|
||||||
n := StrToIntDef(Unquote(List.Values['number-of-threads']), 0);
|
n := StrToIntDef(List.Values['number-of-threads'], 0);
|
||||||
if n < 2 then Exit; //nothing to switch
|
if n < 2 then Exit; //nothing to switch
|
||||||
S := Unquote(List.Values['thread-ids']);
|
List.SetPath(['thread-ids']);
|
||||||
|
if List.Count < 2 then Exit; // ???
|
||||||
|
ID1 := StrToIntDef(List.Values['thread-id'], 0);
|
||||||
|
List.Delete(0);
|
||||||
|
ID2 := StrToIntDef(List.Values['thread-id'], 0);
|
||||||
|
|
||||||
|
if ID1 = ID2 then Exit;
|
||||||
finally
|
finally
|
||||||
List.Free;
|
List.Free;
|
||||||
end;
|
end;
|
||||||
List := TGDMIValueList.Create(S);
|
|
||||||
ID1 := StrToIntDef(Unquote(List.Values['thread-id']), 0);
|
|
||||||
List.Delete(0);
|
|
||||||
ID2 := StrToIntDef(Unquote(List.Values['thread-id']), 0);
|
|
||||||
List.Free;
|
|
||||||
if ID1 = ID2 then Exit;
|
|
||||||
|
|
||||||
if not ExecuteCommand('-thread-select %d', [ID2], [cfIgnoreError]) then Exit;
|
if not ExecuteCommand('-thread-select %d', [ID2], [cfIgnoreError]) then Exit;
|
||||||
end;
|
end;
|
||||||
@ -1614,7 +1699,7 @@ procedure TGDBMIDebugger.ProcessFrame(const AFrame: String);
|
|||||||
var
|
var
|
||||||
S: String;
|
S: String;
|
||||||
e: Integer;
|
e: Integer;
|
||||||
Frame: TGDMIValueList;
|
Frame: TGDBMINameValueList;
|
||||||
Location: TDBGLocationRec;
|
Location: TDBGLocationRec;
|
||||||
begin
|
begin
|
||||||
// Do we have a frame ?
|
// Do we have a frame ?
|
||||||
@ -1622,14 +1707,14 @@ begin
|
|||||||
then S := GetFrame(0)
|
then S := GetFrame(0)
|
||||||
else S := AFrame;
|
else S := AFrame;
|
||||||
|
|
||||||
Frame := TGDMIValueList.Create(S);
|
Frame := TGDBMINameValueList.Create(S);
|
||||||
|
|
||||||
Location.Address := 0;
|
Location.Address := 0;
|
||||||
Val(Unquote(Frame.Values['addr']), Location.Address, e);
|
Val(Frame.Values['addr'], Location.Address, e);
|
||||||
if e=0 then ;
|
if e=0 then ;
|
||||||
Location.FuncName := Unquote(Frame.Values['func']);
|
Location.FuncName := Frame.Values['func'];
|
||||||
Location.SrcFile := Unquote(Frame.Values['file']);
|
Location.SrcFile := Frame.Values['file'];
|
||||||
Location.SrcLine := StrToIntDef(Unquote(Frame.Values['line']), -1);
|
Location.SrcLine := StrToIntDef(Frame.Values['line'], -1);
|
||||||
|
|
||||||
Frame.Free;
|
Frame.Free;
|
||||||
|
|
||||||
@ -1898,7 +1983,7 @@ function TGDBMIDebugger.ProcessStopped(const AParams: String; const AIgnoreSigIn
|
|||||||
then begin
|
then begin
|
||||||
ExceptionMessage := GetText('^Exception(%s)^.FMessage', [ObjAddr]);
|
ExceptionMessage := GetText('^Exception(%s)^.FMessage', [ObjAddr]);
|
||||||
//ExceptionMessage := GetText('^^Exception($fp+8)^^.FMessage', []);
|
//ExceptionMessage := GetText('^^Exception($fp+8)^^.FMessage', []);
|
||||||
ExceptionMessage := DeleteEscapeChars(ExceptionMessage, False);
|
ExceptionMessage := DeleteEscapeChars(ExceptionMessage);
|
||||||
end
|
end
|
||||||
else ExceptionMessage := '### Not supported on GDB < 5.3 ###';
|
else ExceptionMessage := '### Not supported on GDB < 5.3 ###';
|
||||||
|
|
||||||
@ -1932,14 +2017,14 @@ function TGDBMIDebugger.ProcessStopped(const AParams: String; const AIgnoreSigIn
|
|||||||
ProcessFrame(GetFrame(1));
|
ProcessFrame(GetFrame(1));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure ProcessSignalReceived(const AList: TGDMIValueList);
|
procedure ProcessSignalReceived(const AList: TGDBMINameValueList);
|
||||||
var
|
var
|
||||||
SigInt: Boolean;
|
SigInt: Boolean;
|
||||||
S: String;
|
S: String;
|
||||||
begin
|
begin
|
||||||
// TODO: check to run (un)handled
|
// TODO: check to run (un)handled
|
||||||
|
|
||||||
S := Unquote(AList.Values['signal-name']);
|
S := AList.Values['signal-name'];
|
||||||
{$IFdef MSWindows}
|
{$IFdef MSWindows}
|
||||||
SigInt := S = 'SIGTRAP';
|
SigInt := S = 'SIGTRAP';
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
@ -1958,7 +2043,7 @@ function TGDBMIDebugger.ProcessStopped(const AParams: String; const AIgnoreSigIn
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
List: TGDMIValueList;
|
List: TGDBMINameValueList;
|
||||||
Reason: String;
|
Reason: String;
|
||||||
BreakID: Integer;
|
BreakID: Integer;
|
||||||
BreakPoint: TGDBMIBreakPoint;
|
BreakPoint: TGDBMIBreakPoint;
|
||||||
@ -1967,9 +2052,9 @@ begin
|
|||||||
Result := True;
|
Result := True;
|
||||||
FCurrentStackFrame := 0;
|
FCurrentStackFrame := 0;
|
||||||
|
|
||||||
List := TGDMIValueList.Create(AParams);
|
List := TGDBMINameValueList.Create(AParams);
|
||||||
try
|
try
|
||||||
Reason := Unquote(List.Values['reason']);
|
Reason := List.Values['reason'];
|
||||||
if (Reason = 'exited-normally')
|
if (Reason = 'exited-normally')
|
||||||
then begin
|
then begin
|
||||||
SetState(dsStop);
|
SetState(dsStop);
|
||||||
@ -1978,7 +2063,7 @@ begin
|
|||||||
|
|
||||||
if Reason = 'exited'
|
if Reason = 'exited'
|
||||||
then begin
|
then begin
|
||||||
SetExitCode(StrToIntDef(Unquote(List.Values['exit-code']), 0));
|
SetExitCode(StrToIntDef(List.Values['exit-code'], 0));
|
||||||
SetState(dsStop);
|
SetState(dsStop);
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
@ -1986,7 +2071,7 @@ begin
|
|||||||
if Reason = 'exited-signalled'
|
if Reason = 'exited-signalled'
|
||||||
then begin
|
then begin
|
||||||
SetState(dsStop);
|
SetState(dsStop);
|
||||||
DoException('External: ' + Unquote(List.Values['signal-name']), '');
|
DoException('External: ' + List.Values['signal-name'], '');
|
||||||
// ProcessFrame(List.Values['frame']);
|
// ProcessFrame(List.Values['frame']);
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
@ -1999,7 +2084,7 @@ begin
|
|||||||
|
|
||||||
if Reason = 'breakpoint-hit'
|
if Reason = 'breakpoint-hit'
|
||||||
then begin
|
then begin
|
||||||
BreakID := StrToIntDef(Unquote(List.Values['bkptno']), -1);
|
BreakID := StrToIntDef(List.Values['bkptno'], -1);
|
||||||
if BreakID = -1
|
if BreakID = -1
|
||||||
then begin
|
then begin
|
||||||
SetState(dsError);
|
SetState(dsError);
|
||||||
@ -2149,13 +2234,13 @@ function TGDBMIDebugger.StartDebugging(const AContinueCommand: String): Boolean;
|
|||||||
function InsertBreakPoint(const AName: String): Integer;
|
function InsertBreakPoint(const AName: String): Integer;
|
||||||
var
|
var
|
||||||
R: TGDBMIExecResult;
|
R: TGDBMIExecResult;
|
||||||
ResultList: TGDMIValueList;
|
ResultList: TGDBMINameValueList;
|
||||||
begin
|
begin
|
||||||
ExecuteCommand('-break-insert %s', [AName], [cfIgnoreError], R);
|
ExecuteCommand('-break-insert %s', [AName], [cfIgnoreError], R);
|
||||||
if R.State = dsError then Exit;
|
if R.State = dsError then Exit;
|
||||||
|
|
||||||
ResultList := TGDMIValueList.Create(R, ['bkpt']);
|
ResultList := TGDBMINameValueList.Create(R, ['bkpt']);
|
||||||
Result := StrToIntDef(Unquote(ResultList.Values['number']), -1);
|
Result := StrToIntDef(ResultList.Values['number'], -1);
|
||||||
ResultList.Free;
|
ResultList.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2257,7 +2342,7 @@ function TGDBMIDebugger.StartDebugging(const AContinueCommand: String): Boolean;
|
|||||||
var
|
var
|
||||||
R: TGDBMIExecResult;
|
R: TGDBMIExecResult;
|
||||||
S: String;
|
S: String;
|
||||||
ResultList: TGDMIValueList;
|
ResultList: TGDBMINameValueList;
|
||||||
begin
|
begin
|
||||||
// Try to retrieve the address of main. Setting a break on main is past initialization
|
// Try to retrieve the address of main. Setting a break on main is past initialization
|
||||||
if ExecuteCommand('info address main', [cfNoMICommand, cfIgnoreError], R)
|
if ExecuteCommand('info address main', [cfNoMICommand, cfIgnoreError], R)
|
||||||
@ -2277,15 +2362,15 @@ function TGDBMIDebugger.StartDebugging(const AContinueCommand: String): Boolean;
|
|||||||
Result := R.State <> dsError;
|
Result := R.State <> dsError;
|
||||||
if not Result then Exit;
|
if not Result then Exit;
|
||||||
|
|
||||||
ResultList := TGDMIValueList.Create(R, ['bkpt']);
|
ResultList := TGDBMINameValueList.Create(R, ['bkpt']);
|
||||||
FMainAddr := StrToIntDef(Unquote(ResultList.Values['addr']), 0);
|
FMainAddr := StrToIntDef(ResultList.Values['addr'], 0);
|
||||||
ResultList.Free;
|
ResultList.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
R: TGDBMIExecResult;
|
R: TGDBMIExecResult;
|
||||||
FileType, EntryPoint: String;
|
FileType, EntryPoint: String;
|
||||||
List: TGDMIValueList;
|
List: TGDBMINameValueList;
|
||||||
TargetPIDPart: String;
|
TargetPIDPart: String;
|
||||||
TempInstalled, CanContinue: Boolean;
|
TempInstalled, CanContinue: Boolean;
|
||||||
begin
|
begin
|
||||||
@ -2350,9 +2435,9 @@ begin
|
|||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
// OS X gdb has mi output here
|
// OS X gdb has mi output here
|
||||||
List := TGDMIValueList.Create(R, ['section-info']);
|
List := TGDBMINameValueList.Create(R, ['section-info']);
|
||||||
FileType := Unquote(List.Values['filetype']);
|
FileType := List.Values['filetype'];
|
||||||
EntryPoint := Unquote(List.Values['entry-point']);
|
EntryPoint := List.Values['entry-point'];
|
||||||
List.Free;
|
List.Free;
|
||||||
end;
|
end;
|
||||||
DebugLn('[Debugger] File type: ', FileType);
|
DebugLn('[Debugger] File type: ', FileType);
|
||||||
@ -2492,13 +2577,13 @@ end;
|
|||||||
|
|
||||||
procedure TGDBMIBreakPoint.SetBreakPointCallback(const AResult: TGDBMIExecResult; const ATag: Integer);
|
procedure TGDBMIBreakPoint.SetBreakPointCallback(const AResult: TGDBMIExecResult; const ATag: Integer);
|
||||||
var
|
var
|
||||||
ResultList: TGDMIValueList;
|
ResultList: TGDBMINameValueList;
|
||||||
begin
|
begin
|
||||||
BeginUpdate;
|
BeginUpdate;
|
||||||
try
|
try
|
||||||
ResultList := TGDMIValueList.Create(AResult, ['bkpt']);
|
ResultList := TGDBMINameValueList.Create(AResult, ['bkpt']);
|
||||||
FBreakID := StrToIntDef(Unquote(ResultList.Values['number']), 0);
|
FBreakID := StrToIntDef(ResultList.Values['number'], 0);
|
||||||
SetHitCount(StrToIntDef(Unquote(ResultList.Values['times']), 0));
|
SetHitCount(StrToIntDef(ResultList.Values['times'], 0));
|
||||||
if FBreakID <> 0
|
if FBreakID <> 0
|
||||||
then SetValid(vsValid)
|
then SetValid(vsValid)
|
||||||
else SetValid(vsInvalid);
|
else SetValid(vsInvalid);
|
||||||
@ -2510,7 +2595,7 @@ begin
|
|||||||
and (TGDBMIDebugger(Debugger).FBreakAtMain = nil)
|
and (TGDBMIDebugger(Debugger).FBreakAtMain = nil)
|
||||||
then begin
|
then begin
|
||||||
// Check if this BP is at the same location as the temp break
|
// Check if this BP is at the same location as the temp break
|
||||||
if StrToIntDef(Unquote(ResultList.Values['addr']), 0) = TGDBMIDebugger(Debugger).FMainAddr
|
if StrToIntDef(ResultList.Values['addr'], 0) = TGDBMIDebugger(Debugger).FMainAddr
|
||||||
then TGDBMIDebugger(Debugger).FBreakAtMain := Self;
|
then TGDBMIDebugger(Debugger).FBreakAtMain := Self;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2569,15 +2654,17 @@ procedure TGDBMILocals.AddLocals(const AParams: String);
|
|||||||
var
|
var
|
||||||
n, e: Integer;
|
n, e: Integer;
|
||||||
addr: TDbgPtr;
|
addr: TDbgPtr;
|
||||||
LocList, List: TGDMIValueList;
|
LocList, List: TGDBMINameValueList;
|
||||||
|
Item: PGDBMINameValue;
|
||||||
S, Name, Value: String;
|
S, Name, Value: String;
|
||||||
begin
|
begin
|
||||||
LocList := TGDMIValueList.Create(AParams);
|
LocList := TGDBMINameValueList.Create(AParams);
|
||||||
List := TGDMIValueList.Create('');
|
List := TGDBMINameValueList.Create('');
|
||||||
for n := 0 to LocList.Count - 1 do
|
for n := 0 to LocList.Count - 1 do
|
||||||
begin
|
begin
|
||||||
List.Init(LocList[n]);
|
Item := LocList.Items[n];
|
||||||
Name := Unquote(List.Values['name']);
|
List.Init(Item^.NamePtr, Item^.NameLen);
|
||||||
|
Name := List.Values['name'];
|
||||||
if Name = 'this'
|
if Name = 'this'
|
||||||
then Name := 'Self';
|
then Name := 'Self';
|
||||||
|
|
||||||
@ -2675,7 +2762,7 @@ end;
|
|||||||
procedure TGDBMILocals.LocalsNeeded;
|
procedure TGDBMILocals.LocalsNeeded;
|
||||||
var
|
var
|
||||||
R: TGDBMIExecResult;
|
R: TGDBMIExecResult;
|
||||||
List: TGDMIValueList;
|
List: TGDBMINameValueList;
|
||||||
begin
|
begin
|
||||||
if Debugger = nil then Exit;
|
if Debugger = nil then Exit;
|
||||||
if FLocalsValid then Exit;
|
if FLocalsValid then Exit;
|
||||||
@ -2685,7 +2772,7 @@ begin
|
|||||||
[TGDBMIDebugger(Debugger).FCurrentStackFrame], [cfIgnoreError], R);
|
[TGDBMIDebugger(Debugger).FCurrentStackFrame], [cfIgnoreError], R);
|
||||||
if R.State <> dsError
|
if R.State <> dsError
|
||||||
then begin
|
then begin
|
||||||
List := TGDMIValueList.Create(R, ['stack-args', 'frame']);
|
List := TGDBMINameValueList.Create(R, ['stack-args', 'frame']);
|
||||||
AddLocals(List.Values['args']);
|
AddLocals(List.Values['args']);
|
||||||
FreeAndNil(List);
|
FreeAndNil(List);
|
||||||
end;
|
end;
|
||||||
@ -2694,7 +2781,7 @@ begin
|
|||||||
TGDBMIDebugger(Debugger).ExecuteCommand('-stack-list-locals 1', [cfIgnoreError], R);
|
TGDBMIDebugger(Debugger).ExecuteCommand('-stack-list-locals 1', [cfIgnoreError], R);
|
||||||
if R.State <> dsError
|
if R.State <> dsError
|
||||||
then begin
|
then begin
|
||||||
List := TGDMIValueList.Create(R);
|
List := TGDBMINameValueList.Create(R);
|
||||||
AddLocals(List.Values['locals']);
|
AddLocals(List.Values['locals']);
|
||||||
FreeAndNil(List);
|
FreeAndNil(List);
|
||||||
end;
|
end;
|
||||||
@ -2803,15 +2890,15 @@ end;
|
|||||||
function TGDBMICallStack.CheckCount: Boolean;
|
function TGDBMICallStack.CheckCount: Boolean;
|
||||||
var
|
var
|
||||||
R: TGDBMIExecResult;
|
R: TGDBMIExecResult;
|
||||||
List: TGDMIValueList;
|
List: TGDBMINameValueList;
|
||||||
i, cnt: longint;
|
i, cnt: longint;
|
||||||
begin
|
begin
|
||||||
Result := inherited CheckCount;
|
Result := inherited CheckCount;
|
||||||
if not Result then Exit;
|
if not Result then Exit;
|
||||||
|
|
||||||
TGDBMIDebugger(Debugger).ExecuteCommand('-stack-info-depth', [cfIgnoreError], R);
|
TGDBMIDebugger(Debugger).ExecuteCommand('-stack-info-depth', [cfIgnoreError], R);
|
||||||
List := TGDMIValueList.Create(R);
|
List := TGDBMINameValueList.Create(R);
|
||||||
cnt := StrToIntDef(Unquote(List.Values['depth']), -1);
|
cnt := StrToIntDef(List.Values['depth'], -1);
|
||||||
FreeAndNil(List);
|
FreeAndNil(List);
|
||||||
if cnt = -1 then
|
if cnt = -1 then
|
||||||
begin
|
begin
|
||||||
@ -2823,8 +2910,8 @@ begin
|
|||||||
repeat
|
repeat
|
||||||
inc(i);
|
inc(i);
|
||||||
TGDBMIDebugger(Debugger).ExecuteCommand('-stack-info-depth %d', [i], [cfIgnoreError], R);
|
TGDBMIDebugger(Debugger).ExecuteCommand('-stack-info-depth %d', [i], [cfIgnoreError], R);
|
||||||
List := TGDMIValueList.Create(R);
|
List := TGDBMINameValueList.Create(R);
|
||||||
cnt := StrToIntDef(Unquote(List.Values['depth']), -1);
|
cnt := StrToIntDef(List.Values['depth'], -1);
|
||||||
FreeAndNil(List);
|
FreeAndNil(List);
|
||||||
if (cnt = -1) then begin
|
if (cnt = -1) then begin
|
||||||
// no valid stack-info-depth found, so the previous was the last valid one
|
// no valid stack-info-depth found, so the previous was the last valid one
|
||||||
@ -2841,7 +2928,8 @@ var
|
|||||||
R: TGDBMIExecResult;
|
R: TGDBMIExecResult;
|
||||||
addr: TDbgPtr;
|
addr: TDbgPtr;
|
||||||
Arguments: TStringList;
|
Arguments: TStringList;
|
||||||
ArgList, List: TGDMIValueList;
|
ArgList, List: TGDBMINameValueList;
|
||||||
|
Arg: PGDBMINameValue;
|
||||||
begin
|
begin
|
||||||
if Debugger = nil then Exit;
|
if Debugger = nil then Exit;
|
||||||
|
|
||||||
@ -2852,15 +2940,16 @@ begin
|
|||||||
|
|
||||||
if R.State <> dsError
|
if R.State <> dsError
|
||||||
then begin
|
then begin
|
||||||
ArgList := TGDMIValueList.Create(R, ['stack-args', 'frame', 'args']);
|
ArgList := TGDBMINameValueList.Create(R, ['stack-args', 'frame', 'args']);
|
||||||
|
|
||||||
if ArgList.Count > 0
|
if ArgList.Count > 0
|
||||||
then begin
|
then begin
|
||||||
List := TGDMIValueList.Create('');
|
List := TGDBMINameValueList.Create('');
|
||||||
for n := 0 to ArgList.Count - 1 do
|
for n := 0 to ArgList.Count - 1 do
|
||||||
begin
|
begin
|
||||||
List.Init(ArgList[n]);
|
Arg := ArgList.Items[n];
|
||||||
Arguments.Add(Unquote(List.Values['name']) + '=' + DeleteEscapeChars(List.Values['value']));
|
List.Init(Arg^.NamePtr, Arg^.NameLen);
|
||||||
|
Arguments.Add(List.Values['name'] + '=' + DeleteEscapeChars(List.Values['value']));
|
||||||
end;
|
end;
|
||||||
FreeAndNil(List);
|
FreeAndNil(List);
|
||||||
end;
|
end;
|
||||||
@ -2871,17 +2960,17 @@ begin
|
|||||||
[AIndex], [cfIgnoreError], R);
|
[AIndex], [cfIgnoreError], R);
|
||||||
if R.State <> dsError
|
if R.State <> dsError
|
||||||
then begin
|
then begin
|
||||||
List := TGDMIValueList.Create(R, ['stack', 'frame']);
|
List := TGDBMINameValueList.Create(R, ['stack', 'frame']);
|
||||||
addr := 0;
|
addr := 0;
|
||||||
Val(Unquote(List.Values['addr']), addr, e);
|
Val(List.Values['addr'], addr, e);
|
||||||
if e=0 then ;
|
if e=0 then ;
|
||||||
Result := TCallStackEntry.Create(
|
Result := TCallStackEntry.Create(
|
||||||
AIndex,
|
AIndex,
|
||||||
addr,
|
addr,
|
||||||
Arguments,
|
Arguments,
|
||||||
Unquote(List.Values['func']),
|
List.Values['func'],
|
||||||
Unquote(List.Values['file']),
|
List.Values['file'],
|
||||||
StrToIntDef(Unquote(List.Values['line']), 0)
|
StrToIntDef(List.Values['line'], 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
FreeAndNil(List);
|
FreeAndNil(List);
|
||||||
@ -3105,7 +3194,7 @@ function TGDBMIExpression.GetExpression(var AResult: String): Boolean;
|
|||||||
var
|
var
|
||||||
R: TGDBMIExecResult;
|
R: TGDBMIExecResult;
|
||||||
S: String;
|
S: String;
|
||||||
List: TStrings;
|
List: TGDBMINameValueList;
|
||||||
GDBType: TGDBType;
|
GDBType: TGDBType;
|
||||||
begin
|
begin
|
||||||
Result := False;
|
Result := False;
|
||||||
@ -3149,7 +3238,7 @@ begin
|
|||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
DebugLn('PType result: ', R.Values);
|
DebugLn('PType result: ', R.Values);
|
||||||
List := CreateValueList(R.Values);
|
List := TGDBMINameValueList.Create(R);
|
||||||
S := List.Values['type'];
|
S := List.Values['type'];
|
||||||
DebugLn('PType type: ', S);
|
DebugLn('PType type: ', S);
|
||||||
List.Free;
|
List.Free;
|
||||||
|
Loading…
Reference in New Issue
Block a user