debugger: clean up, removed TGDBMIExpression (an never finished attempt to support pre gdb 5.2)

git-svn-id: trunk@42424 -
This commit is contained in:
martin 2013-08-18 19:38:53 +00:00
parent 16c296ef1d
commit 8ad2de8e3a

View File

@ -1509,130 +1509,6 @@ type
{%endregion ^^^^^ Threads ^^^^^ }
{%region ***** TGDBMIExpression ***** }
{ TGDBMIExpression }
// TGDBMIExpression was an attempt to make expression evaluation on Objects possible for GDB <= 5.2
// It is not completed and buggy. Since 5.3 expression evaluation is OK, so maybe in future the
// TGDBMIExpression will be completed to support older gdb versions
TDBGExpressionOperator = (
eoNone,
eoNegate,
eoPlus,
eoSubstract,
eoAdd,
eoMultiply,
eoPower,
eoDivide,
eoDereference,
eoAddress,
eoEqual,
eoLess,
eoLessOrEqual,
eoGreater,
eoGreaterOrEqual,
eoNotEqual,
eoIn,
eoIs,
eoAs,
eoDot,
eoComma,
eoBracket,
eoIndex,
eoClose,
eoAnd,
eoOr,
eoMod,
eoNot,
eoDiv,
eoXor,
eoShl,
eoShr
);
const
OPER_LEVEL: array[TDBGExpressionOperator] of Byte = (
{eoNone } 0,
{eoNegate } 5,
{eoPlus } 5,
{eoSubstract } 7,
{eoAdd } 7,
{eoMultiply } 6,
{eoPower } 4,
{eoDivide } 6,
{eoDereference } 2,
{eoAddress } 4,
{eoEqual } 8,
{eoLess } 8,
{eoLessOrEqual } 8,
{eoGreater } 8,
{eoGreaterOrEqual } 8,
{eoNotEqual } 8,
{eoIn } 8,
{eoIs } 8,
{eoAs } 6,
{eoDot } 2,
{eoComma } 9,
{eoBracket } 1,
{eoIndex } 3,
{eoClose } 9,
{eoAnd } 6,
{eoOr } 7,
{eoMod } 6,
{eoNot } 5,
{eoDiv } 6,
{eoXor } 7,
{eoShl } 6,
{eoShr } 6
);
type
PGDBMISubExpression = ^TGDBMISubExpression;
TGDBMISubExpression = record
Opertor: TDBGExpressionOperator;
Operand: String;
Next, Prev: PGDBMISubExpression;
end;
PGDBMIExpressionResult = ^TGDBMIExpressionResult;
TGDBMIExpressionResult = record
Opertor: TDBGExpressionOperator;
// Operand: String;
Value: String;
Info: TGDBType;
Next, Prev: PGDBMIExpressionResult;
end;
TGDBMIExpression = class(TObject)
private
FList: PGDBMISubExpression;
FStack: PGDBMIExpressionResult;
FStackPtr: PGDBMIExpressionResult;
procedure Push(var AResult: PGDBMIExpressionResult);
procedure Pop(var AResult: PGDBMIExpressionResult);
procedure DisposeList(AList: PGDBMIExpressionResult);
function Solve(const ADebuggerCommand: TGDBMIDebuggerCommand; ALimit: Byte; const ARight: String; out AValue: String; out AInfo: TGDBType): Boolean;
function SolveAddress(const ADebuggerCommand: TGDBMIDebuggerCommand; ARight: PGDBMIExpressionResult; out AValue: String; out AInfo: TGDBType): Boolean;
function SolveMath(const ADebuggerCommand: TGDBMIDebuggerCommand; ALeft, ARight: PGDBMIExpressionResult; out AValue: String; out AInfo: TGDBType): Boolean;
function SolveIn(const ADebuggerCommand: TGDBMIDebuggerCommand; ALeft, ARight: PGDBMIExpressionResult; out AValue: String; out AInfo: TGDBType): Boolean;
function SolveIs(const ADebuggerCommand: TGDBMIDebuggerCommand; ALeft, ARight: PGDBMIExpressionResult; out AValue: String; out AInfo: TGDBType): Boolean;
function SolveAs(const ADebuggerCommand: TGDBMIDebuggerCommand; ALeft, ARight: PGDBMIExpressionResult; out AValue: String; out AInfo: TGDBType): Boolean;
function SolveDeref(const ADebuggerCommand: TGDBMIDebuggerCommand; ALeft: PGDBMIExpressionResult; out AValue: String; out AInfo: TGDBType): Boolean;
function SolveDot(const ADebuggerCommand: TGDBMIDebuggerCommand; ALeft: PGDBMIExpressionResult; const ARight: String; out AVAlue: String; out AInfo: TGDBType): Boolean;
protected
function Evaluate(const ADebuggerCommand: TGDBMIDebuggerCommand; const AText: String; out AResult: String; out AResultInfo: TGDBType): Boolean;
public
constructor Create(const AExpression: String);
destructor Destroy; override;
function DumpExpression: String;
function Evaluate(const ADebuggerCommand: TGDBMIDebuggerCommand; out AResult: String; out AResultInfo: TGDBType): Boolean;
end;
{%endregion *^^^* TGDBMIExpression *^^^* }
{ TGDBStringIterator }
TGDBStringIterator=class
@ -9672,730 +9548,6 @@ begin
FreeAndNil(FCommandList);
end;
{ =========================================================================== }
{ TGDBMIExpression }
{ =========================================================================== }
function GetSubExpression(var AExpression: PChar; var ALength: Integer; out AOperator: TDBGExpressionOperator; out AOperand: String): Boolean;
type
TScanState = (
ssNone, // start scanning
ssString, // inside string
ssEndString, // just left a string, we may reenter if another ' is present
ssOperand, // reading operand
ssOperator // delimeter found, next must be operator
);
var
State: TScanState;
function GetOperand(const AOperand: String): String;
begin
if (AOperand = '')
or (AOperand[1] <> '''')
then Result := AOperand
else Result := ConvertToCString(AOperand);
end;
function GetOperator(AOperator: PChar; ALen: Integer): TDBGExpressionOperator;
begin
case AOperator[0] of
'-': Result := eoSubstract;
'+': Result := eoAdd;
'*': begin
if ALen = 1
then Result := eoMultiply
else Result := eoPower;
end;
'/': Result := eoDivide;
'^': Result := eoDereference;
'@': Result := eoAddress;
'=': Result := eoEqual;
'<': begin
if ALen = 1
then Result := eoLess
else if AOperator[1] = '='
then Result := eoLessOrEqual
else Result := eoNotEqual;
end;
'>': begin
if ALen = 1
then Result := eoGreater
else Result := eoGreaterOrEqual;
end;
'.': Result := eoDot;
',': Result := eoComma;
'(': Result := eoBracket;
'[': Result := eoIndex;
')': Result := eoClose;
']': Result := eoClose;
'a', 'A': begin
if AOperator[1] in ['s', 'S']
then Result := eoAs
else Result := eoAnd;
end;
'o', 'O': Result := eoOr;
'i', 'I': begin
if AOperator[1] in ['s', 'S']
then Result := eoIs
else Result := eoIn;
end;
'm', 'M': Result := eoMod;
'n', 'N': Result := eoNot;
'd', 'D': Result := eoDiv;
'x', 'X': Result := eoXor;
's', 'S': begin
if AOperator[2] in ['l', 'L']
then Result := eoShl
else Result := eoShr;
end;
end;
Inc(AExpression, ALen);
Dec(ALength, ALen);
end;
function CheckOperator(const AOperator: String): Boolean;
var
len: Integer;
begin
len := Length(AOperator);
if ALength <= len then Exit(False); // net char after operator too
if not (AExpression[len] in [' ', #9, '(']) then Exit(False);
if StrLIComp(AExpression, @AOperator[1], len) <> 0 then Exit(False);
Result := True;
end;
var
Sub: String;
len: Integer;
begin
while (ALength > 0) and (AExpression^ in [#9, ' ']) do
begin
Dec(ALength);
Inc(AExpression);
end;
if ALength = 0 then Exit;
State := ssNone;
Sub:='';
while ALength > 0 do
begin
if AExpression^ = ''''
then begin
case State of
ssOperand,
ssOperator: Exit(False); //illegal
ssNone: State := ssString;
ssString:State := ssEndString;
ssEndString: State := ssString;
end;
Sub := Sub + AExpression^;
Inc(AExpression);
Dec(ALength);
Continue;
end;
case State of
ssString: begin
Sub := Sub + AExpression^;
Inc(AExpression);
Dec(ALength);
Continue;
end;
ssEndString: State := ssOperator;
ssNone: State := ssOperand;
end;
case AExpression^ of
' ', #9: begin
State := ssOperator;
Inc(AExpression);
Dec(ALength);
Continue;
end;
'(', '[': begin
AOperand := GetOperand(Sub);
AOperator := GetOperator(AExpression, 1);
Exit(True);
end;
')', ']': begin
AOperand := GetOperand(Sub);
AOperator := GetOperator(AExpression, 1);
Exit(True);
end;
'-', '+': begin
if Sub = ''
then begin
//unary
AOperand := '';
if AExpression^ = '-'
then AOperator := eoNegate
else AOperator := eoPlus;
Inc(AExpression);
Dec(ALength);
end
else begin
AOperand := GetOperand(Sub);
end;
Exit(True);
end;
'/', '^', '@', '=', ',': begin
AOperand := GetOperand(Sub);
AOperator := GetOperator(AExpression, 1);
Exit(True);
end;
'*', '<', '>': begin
AOperand := GetOperand(Sub);
if ALength > 1
then begin
if AExpression[0] = '*'
then begin
if AExpression[1] = '*'
then AOperator := GetOperator(AExpression, 2)
else AOperator := GetOperator(AExpression, 1);
end
else begin
if AExpression[1] = '='
then AOperator := GetOperator(AExpression, 2)
else AOperator := GetOperator(AExpression, 1);
end;
end
else AOperator := GetOperator(AExpression, 1);
Exit(True);
end;
'.': begin
if (State <> ssOperand) or (Length(Sub) = 0) or not (Sub[1] in ['0'..'9'])
then begin
AOperand := GetOperand(Sub);
AOperator := GetOperator(AExpression, 1);
Exit(True);
end;
end;
end;
if (State = ssOperator)
then begin
len := 3;
case AExpression^ of
'a', 'A': begin
if not CheckOperator('and') then Exit(False);
if not CheckOperator('as') then Exit(False);
end;
'o', 'O': begin
if not CheckOperator('or') then Exit(False);
len := 2;
end;
'i', 'I': begin
if not CheckOperator('in') then Exit(False);
if not CheckOperator('is') then Exit(False);
end;
'm', 'M': begin
if not CheckOperator('mod') then Exit(False);
end;
'd', 'D': begin
if not CheckOperator('div') then Exit(False);
end;
'x', 'X': begin
if not CheckOperator('xor') then Exit(False);
end;
's', 'S': begin
if not (CheckOperator('shl') or CheckOperator('shr')) then Exit(False);
end;
else
Exit(False);
end;
AOperand := GetOperand(Sub);
AOperator := GetOperator(AExpression, len);
Exit(True);
end;
if (State = ssOperand)
and (Sub = '')
and CheckOperator('not')
then begin
AOperand := '';
AOperator := GetOperator(AExpression, 3);
Exit(True);
end;
Sub := Sub + AExpression^;
Inc(AExpression);
Dec(ALength);
end;
if not (State in [ssOperator, ssOperand, ssEndString]) then Exit(False);
AOperand := GetOperand(Sub);
AOperator := eoNone;
Result := True;
end;
constructor TGDBMIExpression.Create(const AExpression: String);
var
len: Integer;
P: PChar;
Run, Work: PGDBMISubExpression;
Opertor: TDBGExpressionOperator;
Operand: String;
begin
inherited Create;
len := Length(AExpression);
p := PChar(AExpression);
Run := nil;
while (len > 0) and GetSubExpression(p, len, Opertor, Operand) do
begin
New(Work);
Work^.Opertor := Opertor;
Work^.Operand := Operand;
Work^.Prev := Run;
Work^.Next := nil;
if FList = nil
then FList := Work
else Run^.Next := Work;
Run := Work;
end;
end;
destructor TGDBMIExpression.Destroy;
var
Run, Work: PGDBMISubExpression;
begin
Run := FList;
while Run <> nil do
begin
Work := Run;
Run := Work^.Next;
Dispose(Work);
end;
inherited;
end;
procedure TGDBMIExpression.DisposeList(AList: PGDBMIExpressionResult);
var
Temp: PGDBMIExpressionResult;
begin
while AList <> nil do
begin
AList^.Info.Free;
Temp := AList;
AList := Alist^.Next;
Dispose(Temp);
end;
end;
function TGDBMIExpression.DumpExpression: String;
// Mainly used for debugging purposes
var
Sub: PGDBMISubExpression;
s: string;
begin
Result := '';
Sub := FList;
while Sub <> nil do
begin
WriteStr(s, Sub^.Opertor);
Result := Result + Sub^.Operand + ' ' + s + ' ';
Sub := Sub^.Next;
end;
end;
function TGDBMIExpression.Evaluate(const ADebuggerCommand: TGDBMIDebuggerCommand; out AResult: String; out AResultInfo: TGDBType): Boolean;
const
OPER_UNARY = [eoNot, eoNegate, eoPlus, eoAddress, eoBracket];
var
Sub: PGDBMISubExpression;
R: PGDBMIExpressionResult;
begin
Result := True;
Sub := FList;
FStack := nil;
FStackPtr := nil;
New(R);
FillByte(R^, SizeOf(R^), 0);
while Sub <> nil do
begin
R^.Opertor := Sub^.Opertor;
if Sub^.Operand = ''
then begin
if not (Sub^.OperTor in OPER_UNARY)
then begin
// check if we have a 2nd operator
Result := False;
if FStackPtr = nil then Break;
case FStackPtr^.OperTor of
eoClose, eoDereference: begin
if not (Sub^.OperTor in [eoDot, eoDereference, eoIndex]) then Break;
end;
eoBracket: begin
if Sub^.OperTor <> eoBracket then Break;
end;
end;
Result := True;
end;
Push(R);
Sub := Sub^.Next;
Continue;
end;
if Sub^.OperTor in OPER_UNARY then Break;
if (FStackPtr = nil)
or (OPER_LEVEL[Sub^.OperTor] < OPER_LEVEL[FStackPtr^.OperTor])
then begin
if not Evaluate(ADebuggerCommand, Sub^.Operand, R^.Value, R^.Info)
then begin
Result := False;
Break;
end;
end
else begin
if not Solve(ADebuggerCommand, OPER_LEVEL[Sub^.OperTor], Sub^.Operand, R^.Value, R^.Info)
then begin
Result := False;
Break;
end;
end;
Push(R);
Sub := Sub^.Next;
end;
if Result and (FStackPtr <> nil)
then begin
New(R);
FillByte(R^, SizeOf(R^), 0);
Result := Solve(ADebuggerCommand, 255, '', R^.Value, R^.Info);
Push(R); // make sure it gets cleaned later
end;
if Result
then begin
AResult := R^.Value;
AResultInfo := R^.Info;
R^.Info := nil;
end;
while FStackPtr <> nil do
begin
Pop(R);
R^.Info.Free;
Dispose(R);
end;
end;
function TGDBMIExpression.Evaluate(const ADebuggerCommand: TGDBMIDebuggerCommand; const AText: String; out AResult: String; out AResultInfo: TGDBType): Boolean;
var
R: TGDBMIExecResult;
ResultList: TGDBMINameValueList;
begin
// special cases
if ATExt = ''
then begin
AResult := '';
AResultInfo := nil;
Exit(True);
end;
if AText = '""'
then begin
AResult := '0x0';
AResultInfo := TGDBType.Create(skPointer, '^character');
Exit(True);
end;
Result := ADebuggerCommand.ExecuteCommand('-data-evaluate-expression %s', [Quote(AText)], R)
and (R.State <> dsError);
ResultList := TGDBMINameValueList.Create(R);
if R.State = dsError
then AResult := ResultList.Values['msg']
else AResult := ResultList.Values['value'];
// AResult := DeleteEscapeChars(AResult);
ResultList.Free;
if Result
then AResultInfo := ADebuggerCommand.GetGDBTypeInfo(AText)
else AResultInfo := nil;
if AResultInfo = nil then Exit;
//post format some results (for inscance a char is returned as "ord 'Value'"
if AResultInfo.Kind <> skSimple then Exit;
case StringCase(AResultInfo.TypeName, ['character'], true, false) of
0: AResult := GetPart([' '], [], AResult);
end;
end;
procedure TGDBMIExpression.Pop(var AResult: PGDBMIExpressionResult);
begin
AResult := FStackPtr;
if AResult = nil then Exit;
FStackPtr := AResult^.Prev;
if FStackPtr = nil
then FStack := nil;
AResult^.Next := nil;
AResult^.Prev := nil;
end;
procedure TGDBMIExpression.Push(var AResult: PGDBMIExpressionResult);
begin
if FStack = nil
then begin
FStack := AResult;
FStackPtr := AResult;
end
else begin
FStackPtr^.Next := AResult;
AResult^.Prev := FStackPtr;
FStackPtr := AResult;
end;
New(AResult);
FillByte(AResult^, SizeOf(AResult^), 0);
end;
function TGDBMIExpression.Solve(const ADebuggerCommand: TGDBMIDebuggerCommand; ALimit: Byte; const ARight: String; out AValue: String; out AInfo: TGDBType): Boolean;
var
StartPtr, Left: PGDBMIExpressionResult;
Right: TGDBMIExpressionResult;
Value: String;
Info: TGDBType;
begin
StartPtr := FStackPtr;
while (ALimit >= OPER_LEVEL[StartPtr^.OperTor]) and (StartPtr^.Prev <> nil) do
StartPtr := StartPtr^.Prev;
// we will solve this till end of stack
FStackPtr := StartPtr^.Prev;
if FStackPtr = nil
then FStack := nil
else FStackPtr^.Next := nil;
StartPtr^.Prev := nil;
Left := StartPtr;
FillChar(Right, SizeOf(Right), 0);
repeat
Info := nil;
Value := '';
case Left^.Opertor of
eoNone: begin
// only posible as first and only item on stack
Result := (FStackPtr = nil) and (Left = StartPtr) and (ARight = '');
if Result
then begin
Value := Left^.Value;
Info := Left^.Info;
Left^.Info := nil;
end;
end;
eoNegate, eoPlus, eoSubstract, eoAdd,
eoMultiply, eoPower, eoDivide, eoEqual,
eoLess, eoLessOrEqual, eoGreater, eoGreaterOrEqual,
eoNotEqual, eoAnd, eoOr, eoMod,
eoNot, eoDiv, eoXor, eoShl,
eoShr: begin
if Left^.Next = nil
then begin
Result := Evaluate(ADebuggerCommand, ARight, Right.Value, Right.Info)
and SolveMath(ADebuggerCommand, Left, @Right, Value, Info);
FreeAndNil(Right.Info);
end
else Result := SolveMath(ADebuggerCommand, Left, Left^.Next, Value, Info);
end;
eoDereference: begin
Result := (ARight = '') // right part can not have value
and SolveDeref(ADebuggerCommand, Left, Value, Info);
end;
eoAddress: begin
Result := (Left^.Info = nil);
if not Result then Break;
if Left^.Next = nil
then begin
Result := Evaluate(ADebuggerCommand, ARight, Right.Value, Right.Info)
and SolveAddress(ADebuggerCommand, @Right, Value, Info);
FreeAndNil(Right.Info);
end
else Result := SolveIn(ADebuggerCommand, Left, Left^.Next, Value, Info);
end;
eoDot: begin
// its impossible to have next already resolved. Its a member of left
Result := (Left^.Next = nil) and SolveDot(ADebuggerCommand, Left, ARight, Value, Info);
end;
// eoComma: begin
// end;
eoBracket: begin
Result := Evaluate(ADebuggerCommand, ARight, Value, Info);
// we can finish when closed
end;
eoIndex: begin
if Left^.Info = nil
then begin
// only possible when part of "in"
Result := (Left^.Prev <> nil)
and (Left^.Prev^.OperTor = eoIn)
and Evaluate(ADebuggerCommand, ARight, Value, Info);
end
else begin
Result := Evaluate(ADebuggerCommand, ARight, Value, Info);
// we can finish when closed
end;
end;
eoIn: begin
if Left^.Next = nil
then begin
Result := Evaluate(ADebuggerCommand, ARight, Right.Value, Right.Info)
and SolveIn(ADebuggerCommand, Left, @Right, Value, Info);
FreeAndNil(Right.Info);
end
else Result := SolveIn(ADebuggerCommand, Left, Left^.Next, Value, Info);
end;
eoIs: begin
if Left^.Next = nil
then begin
Result := Evaluate(ADebuggerCommand, ARight, Right.Value, Right.Info)
and SolveIs(ADebuggerCommand, Left, @Right, Value, Info);
FreeAndNil(Right.Info);
end
else Result := SolveIs(ADebuggerCommand, Left, Left^.Next, Value, Info);
end;
eoAs: begin
if Left^.Next = nil
then begin
Result := Evaluate(ADebuggerCommand, ARight, Right.Value, Right.Info)
and SolveAs(ADebuggerCommand, Left, @Right, Value, Info);
FreeAndNil(Right.Info);
end
else Result := SolveAs(ADebuggerCommand, Left, Left^.Next, Value, Info);
end;
else
Result := False;
end;
if not Result then Break;
if Left^.Next = nil then Break;
Left := Left^.Next;
Left^.Info.Free;
Left^.Info := Info;
Left^.Value := Value;
until False;
DisposeList(StartPtr);
if Result
then begin
AValue := Value;
AInfo := Info;
end
else begin
AValue := '';
AInfo := nil;
end;
end;
function TGDBMIExpression.SolveAddress(const ADebuggerCommand: TGDBMIDebuggerCommand; ARight: PGDBMIExpressionResult; out AValue: String; out AInfo: TGDBType): Boolean;
begin
Result := False;
end;
function TGDBMIExpression.SolveAs(const ADebuggerCommand: TGDBMIDebuggerCommand; ALeft, ARight: PGDBMIExpressionResult; out AValue: String; out AInfo: TGDBType): Boolean;
begin
Result := False;
end;
function TGDBMIExpression.SolveDeref(const ADebuggerCommand: TGDBMIDebuggerCommand; ALeft: PGDBMIExpressionResult; out AValue: String; out AInfo: TGDBType): Boolean;
var
Eval: String;
begin
Result := ALeft^.Info.Kind = skPointer;
if not Result then Exit;
Eval := '^' + ALeft^.Info.TypeName + '(' + ALeft^.Value + ')^';
Result := Evaluate(ADebuggerCommand, Eval, AValue, AInfo);
end;
function TGDBMIExpression.SolveDot(const ADebuggerCommand: TGDBMIDebuggerCommand; ALeft: PGDBMIExpressionResult; const ARight: String; out AValue: String; out AInfo: TGDBType): Boolean;
var
Prefix: String;
begin
if not (ALeft^.Info.Kind in [skClass, skRecord]) then Exit(False);
Prefix := '^' + ALeft^.Info.TypeName + '(' + ALeft^.Value + ')^.';
Result := Evaluate(ADebuggerCommand, Prefix + ARight, AValue, AInfo);
if Result then Exit;
// maybe property
Result := Evaluate(ADebuggerCommand, Prefix + 'F' + ARight, AValue, AInfo);
//todo: method call
end;
function TGDBMIExpression.SolveIn(const ADebuggerCommand: TGDBMIDebuggerCommand; ALeft, ARight: PGDBMIExpressionResult; out AValue: String; out AInfo: TGDBType): Boolean;
begin
Result := False;
end;
function TGDBMIExpression.SolveIs(const ADebuggerCommand: TGDBMIDebuggerCommand; ALeft, ARight: PGDBMIExpressionResult; out AValue: String; out AInfo: TGDBType): Boolean;
begin
Result := False;
end;
function TGDBMIExpression.SolveMath(const ADebuggerCommand: TGDBMIDebuggerCommand; ALeft, ARight: PGDBMIExpressionResult; out AValue: String; out AInfo: TGDBType): Boolean;
const
OPERATOR_TEXT: array[TDBGExpressionOperator] of string = (
{eoNone } '',
{eoNegate } '-',
{eoPlus } '',
{eoSubstact } '-',
{eoAdd } '+',
{eoMultiply } '*',
{eoPower } '',
{eoDivide } '/',
{eoDereference } '',
{eoAddress } '',
{eoEqual } '=',
{eoLess } '<',
{eoLessOrEqual } '<=',
{eoGreater } '>',
{eoGreaterOrEqual } '>=',
{eoNotEqual } '<>',
{eoIn } '',
{eoIs } '',
{eoAs } '',
{eoDot } '',
{eoComma } '',
{eoBracket } '',
{eoIndex } '',
{eoClose } '',
{eoAnd } 'and',
{eoOr } 'or',
{eoMod } 'mod',
{eoNot } 'not',
{eoDiv } 'div',
{eoXor } 'xor',
{eoShl } 'shl',
{eoShr } 'shr'
);
var
Eval: String;
begin
case ALeft^.Opertor of
eoAnd, eoOr, eoMod, eoNot,
eoDiv, eoXor, eoShl, eoShr: begin
Eval := '(' + ALeft^.Value + ')' + OPERATOR_TEXT[ALeft^.Opertor] + '(' + ARight^.Value + ')';
end
else
Eval := ALeft^.Value + OPERATOR_TEXT[ALeft^.Opertor] + ARight^.Value;
end;
Result := Evaluate(ADebuggerCommand, Eval, AValue, AInfo);
end;
{ TGDBStringIterator }
constructor TGDBStringIterator.Create(const AParsableData: String);
@ -13264,7 +12416,6 @@ var
var
S: String;
ResultList: TGDBMINameValueList;
Expr: TGDBMIExpression;
frameidx: Integer;
{$IFDEF DBG_WITH_GDB_WATCHES} R: TGDBMIExecResult; {$ENDIF}
begin
@ -13284,19 +12435,6 @@ begin
S := StripExprNewlines(FExpression);
if S = '' then Exit(false);
if S[1] = '!'
then begin
//TESTING...
Delete(S, 1, 1);
Expr := TGDBMIExpression.Create(S);
FTextValue := Expr.DumpExpression;
FTextValue := FTextValue + LineEnding;
Expr.Evaluate(Self, S, FTypeInfo);
FreeAndNil(FTypeInfo);
FTextValue := FTextValue + S;
Expr.Free;
Exit(True);
end;
{$IFDEF DBG_WITH_GDB_WATCHES}
(* This code is experimental. No support will be provided.