DBG: implemented "Repeat Count" for watches

git-svn-id: trunk@37455 -
This commit is contained in:
martin 2012-05-29 20:46:36 +00:00
parent 6f93a15f00
commit bbf31875cd
4 changed files with 201 additions and 37 deletions

View File

@ -1069,6 +1069,7 @@ type
private private
FDisplayFormat: TWatchDisplayFormat; FDisplayFormat: TWatchDisplayFormat;
FEvaluateFlags: TDBGEvaluateFlags; FEvaluateFlags: TDBGEvaluateFlags;
FRepeatCount: Integer;
FStackFrame: Integer; FStackFrame: Integer;
FThreadId: Integer; FThreadId: Integer;
FValidity: TDebuggerDataState; FValidity: TDebuggerDataState;
@ -1096,6 +1097,7 @@ type
procedure Assign(AnOther: TWatchValue); procedure Assign(AnOther: TWatchValue);
property DisplayFormat: TWatchDisplayFormat read FDisplayFormat; property DisplayFormat: TWatchDisplayFormat read FDisplayFormat;
property EvaluateFlags: TDBGEvaluateFlags read FEvaluateFlags; property EvaluateFlags: TDBGEvaluateFlags read FEvaluateFlags;
property RepeatCount: Integer read FRepeatCount;
property ThreadId: Integer read FThreadId; property ThreadId: Integer read FThreadId;
property StackFrame: Integer read FStackFrame; property StackFrame: Integer read FStackFrame;
property Watch: TWatch read FWatch; property Watch: TWatch read FWatch;
@ -1140,10 +1142,12 @@ type
FEvaluateFlags: TDBGEvaluateFlags; FEvaluateFlags: TDBGEvaluateFlags;
FExpression: String; FExpression: String;
FDisplayFormat: TWatchDisplayFormat; FDisplayFormat: TWatchDisplayFormat;
FRepeatCount: Integer;
FValueList: TWatchValueList; FValueList: TWatchValueList;
function GetEnabled: Boolean; function GetEnabled: Boolean;
function GetValue(const AThreadId: Integer; const AStackFrame: Integer): TWatchValue; function GetValue(const AThreadId: Integer; const AStackFrame: Integer): TWatchValue;
procedure SetEvaluateFlags(AValue: TDBGEvaluateFlags); procedure SetEvaluateFlags(AValue: TDBGEvaluateFlags);
procedure SetRepeatCount(AValue: Integer);
protected protected
procedure AssignTo(Dest: TPersistent); override; procedure AssignTo(Dest: TPersistent); override;
function CreateValueList: TWatchValueList; virtual; function CreateValueList: TWatchValueList; virtual;
@ -1172,6 +1176,7 @@ type
property Expression: String read GetExpression write SetExpression; property Expression: String read GetExpression write SetExpression;
property DisplayFormat: TWatchDisplayFormat read GetDisplayFormat write SetDisplayFormat; property DisplayFormat: TWatchDisplayFormat read GetDisplayFormat write SetDisplayFormat;
property EvaluateFlags: TDBGEvaluateFlags read FEvaluateFlags write SetEvaluateFlags; property EvaluateFlags: TDBGEvaluateFlags read FEvaluateFlags write SetEvaluateFlags;
property RepeatCount: Integer read FRepeatCount write SetRepeatCount;
public public
property Values[const AThreadId: Integer; const AStackFrame: Integer]: TWatchValue property Values[const AThreadId: Integer; const AStackFrame: Integer]: TWatchValue
read GetValue; read GetValue;
@ -4598,6 +4603,7 @@ begin
Result := TWatchValue(FList[i]); Result := TWatchValue(FList[i]);
if (Result.ThreadId = AThreadId) and (Result.StackFrame = AStackFrame) and if (Result.ThreadId = AThreadId) and (Result.StackFrame = AStackFrame) and
(Result.DisplayFormat = FWatch.DisplayFormat) and (Result.DisplayFormat = FWatch.DisplayFormat) and
(Result.RepeatCount = FWatch.RepeatCount) and
(Result.EvaluateFlags = FWatch.EvaluateFlags) (Result.EvaluateFlags = FWatch.EvaluateFlags)
then then
exit; exit;
@ -4764,6 +4770,7 @@ begin
if AConfig.GetValue(APath + 'ClassAutoCast', False) if AConfig.GetValue(APath + 'ClassAutoCast', False)
then Include(FEvaluateFlags, defClassAutoCast) then Include(FEvaluateFlags, defClassAutoCast)
else Exclude(FEvaluateFlags, defClassAutoCast); else Exclude(FEvaluateFlags, defClassAutoCast);
FRepeatCount := AConfig.GetValue(APath + 'RepeatCount', 0);
try ReadStr(AConfig.GetValue(APath + 'DisplayFormat', 'wdfDefault'), FDisplayFormat); try ReadStr(AConfig.GetValue(APath + 'DisplayFormat', 'wdfDefault'), FDisplayFormat);
except FDisplayFormat := wdfDefault; end; except FDisplayFormat := wdfDefault; end;
try ReadStr(AConfig.GetValue(APath + 'Validity', 'ddsValid'), FValidity); try ReadStr(AConfig.GetValue(APath + 'Validity', 'ddsValid'), FValidity);
@ -4782,6 +4789,7 @@ begin
WriteStr(s, FValidity); WriteStr(s, FValidity);
AConfig.SetDeleteValue(APath + 'Validity', s, 'ddsValid'); AConfig.SetDeleteValue(APath + 'Validity', s, 'ddsValid');
AConfig.SetDeleteValue(APath + 'ClassAutoCast', defClassAutoCast in FEvaluateFlags, False); AConfig.SetDeleteValue(APath + 'ClassAutoCast', defClassAutoCast in FEvaluateFlags, False);
AConfig.SetDeleteValue(APath + 'RepeatCount', FRepeatCount, 0);
end; end;
constructor TWatchValue.Create; constructor TWatchValue.Create;
@ -4798,6 +4806,7 @@ begin
FWatch := AOwnerWatch; FWatch := AOwnerWatch;
FDisplayFormat := FWatch.DisplayFormat; FDisplayFormat := FWatch.DisplayFormat;
FEvaluateFlags := FWatch.EvaluateFlags; FEvaluateFlags := FWatch.EvaluateFlags;
FRepeatCount := FWatch.RepeatCount;
Create; Create;
end; end;
@ -8205,6 +8214,14 @@ begin
DoModified; DoModified;
end; end;
procedure TWatch.SetRepeatCount(AValue: Integer);
begin
if FRepeatCount = AValue then Exit;
FRepeatCount := AValue;
Changed;
DoModified;
end;
function TWatch.GetDisplayFormat: TWatchDisplayFormat; function TWatch.GetDisplayFormat: TWatchDisplayFormat;
begin begin
Result := FDisplayFormat; Result := FDisplayFormat;
@ -8226,6 +8243,7 @@ begin
else Exclude(FEvaluateFlags, defClassAutoCast); else Exclude(FEvaluateFlags, defClassAutoCast);
try ReadStr(AConfig.GetValue(APath + 'DisplayFormat', 'wdfDefault'), FDisplayFormat); try ReadStr(AConfig.GetValue(APath + 'DisplayFormat', 'wdfDefault'), FDisplayFormat);
except FDisplayFormat := wdfDefault; end; except FDisplayFormat := wdfDefault; end;
FRepeatCount := AConfig.GetValue(APath + 'RepeatCount', 0);
FValueList.LoadDataFromXMLConfig(AConfig, APath + 'ValueList/'); FValueList.LoadDataFromXMLConfig(AConfig, APath + 'ValueList/');
end; end;
@ -8239,6 +8257,7 @@ begin
WriteStr(s{%H-}, FDisplayFormat); WriteStr(s{%H-}, FDisplayFormat);
AConfig.SetDeleteValue(APath + 'DisplayFormat', s, 'wdfDefault'); AConfig.SetDeleteValue(APath + 'DisplayFormat', s, 'wdfDefault');
AConfig.SetDeleteValue(APath + 'ClassAutoCast', defClassAutoCast in FEvaluateFlags, False); AConfig.SetDeleteValue(APath + 'ClassAutoCast', defClassAutoCast in FEvaluateFlags, False);
AConfig.SetDeleteValue(APath + 'RepeatCount', FRepeatCount, 0);
FValueList.SaveDataToXMLConfig(AConfig, APath + 'ValueList/'); FValueList.SaveDataToXMLConfig(AConfig, APath + 'ValueList/');
end; end;
@ -8279,6 +8298,7 @@ begin
if FSnapShot = nil then begin if FSnapShot = nil then begin
TCurrentWatchValueList(FValueList).SnapShot := nil; TCurrentWatchValueList(FValueList).SnapShot := nil;
end else begin end else begin
// TODO: FValueList is copied twice ?
FSnapShot.Assign(self); FSnapShot.Assign(self);
FSnapShot.Enabled := True; // Snapshots are always enabled FSnapShot.Enabled := True; // Snapshots are always enabled
TCurrentWatchValueList(FValueList).SnapShot := FSnapShot.FValueList; TCurrentWatchValueList(FValueList).SnapShot := FSnapShot.FValueList;
@ -8340,6 +8360,7 @@ begin
if i >= 0 if i >= 0
then DisplayFormat := TWatchDisplayFormat(i) then DisplayFormat := TWatchDisplayFormat(i)
else DisplayFormat := wdfDefault; else DisplayFormat := wdfDefault;
FRepeatCount := AConfig.GetValue(APath + 'RepeatCount', 0);
end; end;
procedure TCurrentWatch.SaveToXMLConfig(const AConfig: TXMLConfig; const APath: string); procedure TCurrentWatch.SaveToXMLConfig(const AConfig: TXMLConfig; const APath: string);
@ -8349,6 +8370,7 @@ begin
AConfig.SetDeleteValue(APath + 'DisplayStyle/Value', AConfig.SetDeleteValue(APath + 'DisplayStyle/Value',
TWatchDisplayFormatNames[DisplayFormat], TWatchDisplayFormatNames[wdfDefault]); TWatchDisplayFormatNames[DisplayFormat], TWatchDisplayFormatNames[wdfDefault]);
AConfig.SetDeleteValue(APath + 'ClassAutoCast', defClassAutoCast in FEvaluateFlags, False); AConfig.SetDeleteValue(APath + 'ClassAutoCast', defClassAutoCast in FEvaluateFlags, False);
AConfig.SetDeleteValue(APath + 'RepeatCount', FRepeatCount, 0);
end; end;
{ =========================================================================== } { =========================================================================== }

View File

@ -259,7 +259,8 @@ type
function GetWideText(const ALocation: TDBGPtr): String; function GetWideText(const ALocation: TDBGPtr): String;
function GetGDBTypeInfo(const AExpression: String; FullTypeInfo: Boolean = False; function GetGDBTypeInfo(const AExpression: String; FullTypeInfo: Boolean = False;
AFlags: TGDBTypeCreationFlags = []; AFlags: TGDBTypeCreationFlags = [];
AFormat: TWatchDisplayFormat = wdfDefault): TGDBType; AFormat: TWatchDisplayFormat = wdfDefault;
ARepeatCount: Integer = 0): TGDBType;
function GetClassName(const AClass: TDBGPtr): String; overload; function GetClassName(const AClass: TDBGPtr): String; overload;
function GetClassName(const AExpression: String; const AValues: array of const): String; overload; function GetClassName(const AExpression: String; const AValues: array of const): String; overload;
function GetInstanceClassName(const AInstance: TDBGPtr): String; overload; function GetInstanceClassName(const AInstance: TDBGPtr): String; overload;
@ -10402,8 +10403,8 @@ begin
end; end;
function TGDBMIDebuggerCommand.GetGDBTypeInfo(const AExpression: String; function TGDBMIDebuggerCommand.GetGDBTypeInfo(const AExpression: String;
FullTypeInfo: Boolean = False; AFlags: TGDBTypeCreationFlags = []; FullTypeInfo: Boolean; AFlags: TGDBTypeCreationFlags; AFormat: TWatchDisplayFormat;
AFormat: TWatchDisplayFormat = wdfDefault): TGDBType; ARepeatCount: Integer): TGDBType;
var var
R: TGDBMIExecResult; R: TGDBMIExecResult;
f: Boolean; f: Boolean;
@ -10477,7 +10478,7 @@ begin
then AFlags := AFlags + [gtcfClassIsPointer]; then AFlags := AFlags + [gtcfClassIsPointer];
if FullTypeInfo if FullTypeInfo
then AFlags := AFlags + [gtcfFullTypeInfo]; then AFlags := AFlags + [gtcfFullTypeInfo];
Result := TGdbType.CreateForExpression(AExpression, AFlags); Result := TGdbType.CreateForExpression(AExpression, AFlags, wdfDefault, ARepeatCount);
while not Result.ProcessExpression do begin while not Result.ProcessExpression do begin
if Result.EvalError if Result.EvalError
then break; then break;
@ -12094,7 +12095,7 @@ var
ResultList: TGDBMINameValueList; ResultList: TGDBMINameValueList;
R: TGDBMIExecResult; R: TGDBMIExecResult;
MemDump: TGDBMIMemoryDumpResultList; MemDump: TGDBMIMemoryDumpResultList;
Size: integer; i, Size: integer;
s: String; s: String;
begin begin
Result := False; Result := False;
@ -12225,8 +12226,10 @@ var
begin begin
Result := False; Result := False;
Assert(FTypeInfo = nil, 'Type info must be nil'); Assert(FTypeInfo = nil, 'Type info must be nil');
i := 0;
if FWatchValue <> nil then i := FWatchValue.RepeatCount;
FTypeInfo := GetGDBTypeInfo(AnExpression, defFullTypeInfo in FEvalFlags, FTypeInfo := GetGDBTypeInfo(AnExpression, defFullTypeInfo in FEvalFlags,
TypeInfoFlags + [gtcfExprEvaluate, gtcfExprEvalStrFixed], FDisplayFormat); TypeInfoFlags + [gtcfExprEvaluate, gtcfExprEvalStrFixed], FDisplayFormat, i);
if (FTypeInfo = nil) or (dcsCanceled in SeenStates) if (FTypeInfo = nil) or (dcsCanceled in SeenStates)
then begin then begin

View File

@ -311,7 +311,8 @@ type
gtcfExprIsType, gtcfExprIsType,
gtcfExprEvaluate, gtcfExprEvaluate,
gtcfExprEvalStrFixed, // Evaluate with string fix, if needed; only if gtcfExprEvaluate is set gtcfExprEvalStrFixed, // Evaluate with string fix, if needed; only if gtcfExprEvaluate is set
gtcfAutoCastClass // Find real class of instance, and use, instead of declared class of variable gtcfAutoCastClass, // Find real class of instance, and use, instead of declared class of variable
gtcfForceArrayEval // Used by RepeatCount, in case of "SomePointer[i]"
); );
TGDBTypeCreationFlags = set of TGDBTypeCreationFlag; TGDBTypeCreationFlags = set of TGDBTypeCreationFlag;
@ -320,7 +321,8 @@ type
gtpsSimplePointer, gtpsSimplePointer,
gtpsClass, gtpsClassAutoCast, gtpsClassPointer, gtpsClassAncestor, gtpsClass, gtpsClassAutoCast, gtpsClassPointer, gtpsClassAncestor,
gtpsArray, gtpsArray,
gtpsEvalExpr, gtpsEvalExprArray, gtpsEvalExprDynArray, gtpsEvalExprDynArrayGetData, gtpsEvalExpr, gtpsEvalExprRepeated,
gtpsEvalExprArray, gtpsEvalExprDynArray, gtpsEvalExprDynArrayGetData,
gtpsFinished gtpsFinished
); );
@ -348,14 +350,17 @@ type
FExprEvaluatedAsText: String; FExprEvaluatedAsText: String;
FHasExprEvaluatedAsText: Boolean; FHasExprEvaluatedAsText: Boolean;
FExprEvaluateFormat: TWatchDisplayFormat; FExprEvaluateFormat: TWatchDisplayFormat;
FRepeatCount: Integer;
// Sub-Types (FNext is managed by creator / linked list) // Sub-Types (FNext is managed by creator / linked list)
FFirstProcessingSubType, FNextProcessingSubType: TGDBType; FFirstProcessingSubType, FNextProcessingSubType: TGDBType;
FRepeatFirstIndex: Integer;
FStringExprEvaluatedAsText: String; FStringExprEvaluatedAsText: String;
FTypeInfoAncestor: TGDBType; FTypeInfoAncestor: TGDBType;
FArrayIndexValues: Array of TGDBType; FArrayIndexValues: Array of TGDBType;
FArrayIndexValueLimit: Integer; FArrayIndexValueLimit: Integer;
FRepeatCountEval: TGDBType;
// Gdb-Requests // Gdb-Requests
FEvalError: boolean; FEvalError: boolean;
@ -377,10 +382,13 @@ type
function IsReqError(AReqType: TGDBTypeProcessRequest; CheckResKind: Boolean = True): Boolean; function IsReqError(AReqType: TGDBTypeProcessRequest; CheckResKind: Boolean = True): Boolean;
protected protected
procedure Init; override; procedure Init; override;
function DebugString: String;
property RepeatFirstIndex: Integer read FRepeatFirstIndex write FRepeatFirstIndex;
public public
constructor CreateForExpression(const AnExpression: string; constructor CreateForExpression(const AnExpression: string;
const AFlags: TGDBTypeCreationFlags; const AFlags: TGDBTypeCreationFlags;
AFormat: TWatchDisplayFormat = wdfDefault); AFormat: TWatchDisplayFormat = wdfDefault;
ARepeatCount: Integer = 0);
destructor Destroy; override; destructor Destroy; override;
function ProcessExpression: Boolean; function ProcessExpression: Boolean;
property EvalRequest: PGDBPTypeRequest read FEvalRequest; property EvalRequest: PGDBPTypeRequest read FEvalRequest;
@ -404,6 +412,9 @@ function ParseTypeFromGdb(const ATypeText: string): TGDBPTypeResult;
function dbgs(AFlag: TGDBPTypeResultFlag): string; overload; function dbgs(AFlag: TGDBPTypeResultFlag): string; overload;
function dbgs(AFlags: TGDBPTypeResultFlags): string; overload; function dbgs(AFlags: TGDBPTypeResultFlags): string; overload;
function dbgs(AFlag: TGDBTypeCreationFlag): string; overload;
function dbgs(AFlags: TGDBTypeCreationFlags): string; overload;
function dbgs(AState: TGDBTypeProcessState): string; overload;
function dbgs(AKind: TGDBPTypeResultKind): string; overload; function dbgs(AKind: TGDBPTypeResultKind): string; overload;
function dbgs(AReqType: TGDBCommandRequestType): string; overload; function dbgs(AReqType: TGDBCommandRequestType): string; overload;
function dbgs(AReq: TGDBPTypeRequest): string; overload; function dbgs(AReq: TGDBPTypeRequest): string; overload;
@ -917,6 +928,29 @@ begin
if Result <> '' then Result := '[' + Result + ']'; if Result <> '' then Result := '[' + Result + ']';
end; end;
function dbgs(AFlag: TGDBTypeCreationFlag): string;
begin
writestr(Result, AFlag);
end;
function dbgs(AFlags: TGDBTypeCreationFlags): string;
var
i: TGDBTypeCreationFlag;
begin
Result:='';
for i := low(TGDBTypeCreationFlags) to high(TGDBTypeCreationFlags) do
if i in AFlags then begin
if Result <> '' then Result := Result + ', ';
Result := Result + dbgs(i);
end;
if Result <> '' then Result := '[' + Result + ']';
end;
function dbgs(AState: TGDBTypeProcessState): string;
begin
writestr(Result, AState);
end;
function dbgs(AKind: TGDBPTypeResultKind): string; function dbgs(AKind: TGDBPTypeResultKind): string;
begin begin
writestr(Result, AKind); writestr(Result, AKind);
@ -2004,8 +2038,13 @@ begin
FParsedExpression := nil; FParsedExpression := nil;
end; end;
function TGDBType.DebugString: String;
begin
Result := Format('Expr="%s", Flags=%s, State=%s', [FExpression, dbgs(FCreationFlags), dbgs(FProcessState)]);
end;
constructor TGDBType.CreateForExpression(const AnExpression: string; constructor TGDBType.CreateForExpression(const AnExpression: string;
const AFlags: TGDBTypeCreationFlags; AFormat: TWatchDisplayFormat = wdfDefault); const AFlags: TGDBTypeCreationFlags; AFormat: TWatchDisplayFormat; ARepeatCount: Integer);
begin begin
Create(skSimple, ''); // initialize Create(skSimple, ''); // initialize
FInternalTypeName := ''; FInternalTypeName := '';
@ -2023,6 +2062,9 @@ begin
FHasAutoTypeCastFix := False; FHasAutoTypeCastFix := False;
FAutoTypeCastName := ''; FAutoTypeCastName := '';
FArrayIndexValueLimit := 5; FArrayIndexValueLimit := 5;
FRepeatCountEval := nil;
FRepeatCount := ARepeatCount;
FRepeatFirstIndex := 0;
end; end;
destructor TGDBType.Destroy; destructor TGDBType.Destroy;
@ -2035,6 +2077,7 @@ begin
FArrayIndexValues[i].Free; FArrayIndexValues[i].Free;
FArrayIndexValues := nil; FArrayIndexValues := nil;
FreeAndNil(FParsedExpression); FreeAndNil(FParsedExpression);
FreeAndNil(FRepeatCountEval);
end; end;
function TGDBType.ProcessExpression: Boolean; function TGDBType.ProcessExpression: Boolean;
@ -2043,6 +2086,7 @@ var
procedure ProcessInitial; forward; procedure ProcessInitial; forward;
procedure ProcessInitialSimple; forward; procedure ProcessInitialSimple; forward;
procedure ProcessSimplePointer; forward; procedure ProcessSimplePointer; forward;
procedure EvaluateExpression; forward;
function ClearAmpersand(s: string): string; function ClearAmpersand(s: string): string;
@ -2546,15 +2590,17 @@ var
FExprEvaluatedAsText := FExprEvaluatedAsText + ', '; FExprEvaluatedAsText := FExprEvaluatedAsText + ', ';
FExprEvaluatedAsText := FExprEvaluatedAsText + s; FExprEvaluatedAsText := FExprEvaluatedAsText + s;
end; end;
if FArrayIndexValueLimit < FLen then if Length(FArrayIndexValues) < FLen then
FExprEvaluatedAsText := FExprEvaluatedAsText + ', ...'; FExprEvaluatedAsText := FExprEvaluatedAsText + ', ...';
FHasExprEvaluatedAsText := True;
Result := True; Result := True;
exit; exit;
end; end;
if (FExprEvaluatedAsText <> '') and if (FExprEvaluatedAsText <> '') and
(FExprEvaluatedAsText[1] = '{') // gdb returned array data (FExprEvaluatedAsText[1] = '{') and // gdb returned array data
not(gtcfForceArrayEval in FCreationFlags)
then begin then begin
if (FLen = 0) or if (FLen = 0) or
((Length(FExprEvaluatedAsText) > 1) and (FExprEvaluatedAsText[2] <> '}') ) ((Length(FExprEvaluatedAsText) > 1) and (FExprEvaluatedAsText[2] <> '}') )
@ -2565,11 +2611,11 @@ var
end; end;
// Get Data // Get Data
m := Min(FArrayIndexValueLimit, FLen); m := Min(Max(FArrayIndexValueLimit, FRepeatCount), FLen);
SetLength(FArrayIndexValues, m); SetLength(FArrayIndexValues, m);
for i := 0 to m-1 do begin for i := 0 to m-1 do begin
FArrayIndexValues[i] := TGDBType.CreateForExpression(FExpression+'['+IntToStr(i)+']', FArrayIndexValues[i] := TGDBType.CreateForExpression(FExpression+'['+IntToStr(FRepeatFirstIndex + i)+']',
FCreationFlags + [gtcfExprEvaluate]); FCreationFlags + [gtcfExprEvaluate] - [gtcfForceArrayEval]);
if i = 0 if i = 0
then FArrayIndexValues[i].FArrayIndexValueLimit := FArrayIndexValueLimit - 2 then FArrayIndexValues[i].FArrayIndexValueLimit := FArrayIndexValueLimit - 2
else FArrayIndexValues[i].FArrayIndexValueLimit := FArrayIndexValueLimit - 3; else FArrayIndexValues[i].FArrayIndexValueLimit := FArrayIndexValueLimit - 3;
@ -2647,6 +2693,10 @@ var
FBoundHigh := PCLenToInt(PTypeResult.BoundHigh); FBoundHigh := PCLenToInt(PTypeResult.BoundHigh);
FLen := PCLenToInt(PTypeResult.BoundHigh) - PCLenToInt(PTypeResult.BoundLow) + 1; FLen := PCLenToInt(PTypeResult.BoundHigh) - PCLenToInt(PTypeResult.BoundLow) + 1;
if (gtcfForceArrayEval in FCreationFlags) then begin
EvaluateExpressionDynArrayGetData;
exit;
end;
if (saInternalPointer in FAttributes) then begin if (saInternalPointer in FAttributes) then begin
if not RequireRequests([gptrEvalExprDeRef]) then exit; if not RequireRequests([gptrEvalExprDeRef]) then exit;
@ -2678,6 +2728,77 @@ var
Result := True; Result := True;
end; end;
procedure EvaluateExpressionRepeated;
var
ExpArray: TGDBExpressionPartArray;
s: String;
Idx: Int64;
Error: word;
begin
FProcessState := gtpsEvalExprRepeated;
if (FRepeatCount < 1) then begin
Result := True;
exit;
end;
if (FRepeatCount < 1) or (FParsedExpression.PartCount <> 1) or
not (FParsedExpression.Parts[0] is TGDBExpressionPartArray)
then begin
FRepeatCount := 0;
EvaluateExpression;
exit;
end;
if FRepeatCountEval <> nil then begin
if not FRepeatCountEval.HasExprEvaluatedAsText then begin
FRepeatCount := 0;
EvaluateExpression;
exit;
end;
FExprEvaluatedAsText := FRepeatCountEval.ExprEvaluatedAsText;
FHasExprEvaluatedAsText := True;
FreeAndNil(FRepeatCountEval);
Result := True;
exit;
end;
ExpArray := TGDBExpressionPartArray(FParsedExpression.Parts[0]);
if ExpArray.IndexCount < 1 then begin
FRepeatCount := 0;
EvaluateExpression;
exit;
end;
s := ExpArray.IndexPart[ExpArray.IndexCount - 1].GetPlainText;
if not RequireRequests([gptrEvalExpr2], Quote('('+s+')+0')) then exit;
if IsReqError(gptrEvalExpr2, False) then begin
FRepeatCount := 0;
EvaluateExpression;
exit;
end;
s := GetParsedFromResult(FReqResults[gptrEvalExpr2].Result.GdbDescription, 'value');
Val(s, Idx, Error);
if Error <> 0 then begin
FRepeatCount := 0;
EvaluateExpression;
exit;
end;
FRepeatCountEval := TGDBType.CreateForExpression(
ExpArray.GetTextToIdx(ExpArray.IndexCount-2),
FCreationFlags + [gtcfExprEvaluate, gtcfForceArrayEval],
FExprEvaluateFormat,
FRepeatCount
);
FRepeatCountEval.RepeatFirstIndex := Idx;
AddSubType(FRepeatCountEval);
end;
procedure EvaluateExpression; procedure EvaluateExpression;
begin begin
FProcessState := gtpsEvalExpr; FProcessState := gtpsEvalExpr;
@ -2687,6 +2808,15 @@ var
exit; exit;
end; end;
if (FRepeatCount > 1) and (FParsedExpression.PartCount = 1) and
(FParsedExpression.Parts[0] is TGDBExpressionPartArray) and
not(gtcfForceArrayEval in FCreationFlags)
then begin
exclude(FProccesReuestsMade, gptrEvalExpr2);
EvaluateExpressionRepeated;
exit;
end;
if saDynArray in FAttributes then begin if saDynArray in FAttributes then begin
EvaluateExpressionDynArray; EvaluateExpressionDynArray;
exit; exit;
@ -2701,6 +2831,14 @@ var
exit; exit;
end; end;
if (gtcfForceArrayEval in FCreationFlags) then begin
FBoundLow := FRepeatFirstIndex;
FBoundHigh := FRepeatFirstIndex + FRepeatCount - 1;
FLen := FRepeatCount;
EvaluateExpressionDynArrayGetData;
exit;
end;
// TODO: stringFixed need to know about: // TODO: stringFixed need to know about:
// - AutoTypeCast // - AutoTypeCast
@ -2738,25 +2876,25 @@ var
end; end;
end; end;
if not RequireRequests([gptrEvalExpr]) then exit; if not RequireRequests([gptrEvalExpr]) then exit;
if not IsReqError(gptrEvalExpr, False) then begin if not IsReqError(gptrEvalExpr, False) then begin
ParseFromResult(FReqResults[gptrEvalExpr].Result.GdbDescription, 'value'); ParseFromResult(FReqResults[gptrEvalExpr].Result.GdbDescription, 'value');
if (gtcfExprEvalStrFixed in FCreationFlags) and if (gtcfExprEvalStrFixed in FCreationFlags) and
(FParsedExpression <> nil) and FParsedExpression.MayNeedStringFix (FParsedExpression <> nil) and FParsedExpression.MayNeedStringFix
then begin then begin
if not RequireRequests([gptrEvalExpr2], FParsedExpression.TextStrFixed) then exit; if not RequireRequests([gptrEvalExpr2], FParsedExpression.TextStrFixed) then exit;
ParseFromResultForStrFixed(FReqResults[gptrEvalExpr2].Result.GdbDescription, 'value'); ParseFromResultForStrFixed(FReqResults[gptrEvalExpr2].Result.GdbDescription, 'value');
end; end;
Result := True; Result := True;
exit; exit;
end; end;
// TODO: set Validity = error // TODO: set Validity = error
ParseFromResult(FReqResults[gptrEvalExpr].Result.GdbDescription, 'msg'); ParseFromResult(FReqResults[gptrEvalExpr].Result.GdbDescription, 'msg');
Result := True; Result := True;
end; end;
{%endregion * EvaluateExpression * } {%endregion * EvaluateExpression * }
procedure ProcessInitialSimple; procedure ProcessInitialSimple;
@ -2984,10 +3122,10 @@ var
var var
SubType, PrevSubType: TGDBType; SubType, PrevSubType: TGDBType;
begin begin
DebugLnEnter(DBGMI_TYPE_INFO, ['>>Enter Sub-Requests']);
PrevSubType := nil; PrevSubType := nil;
SubType := FFirstProcessingSubType; SubType := FFirstProcessingSubType;
while SubType <> nil do begin while SubType <> nil do begin
DebugLnEnter(DBGMI_TYPE_INFO, ['>>Enter Sub-Request']);
if SubType.ProcessExpression then begin if SubType.ProcessExpression then begin
if PrevSubType = nil if PrevSubType = nil
then FFirstProcessingSubType := SubType.FNextProcessingSubType then FFirstProcessingSubType := SubType.FNextProcessingSubType
@ -2996,10 +3134,10 @@ var
else else
PrevSubType := SubType; PrevSubType := SubType;
SubType := SubType.FNextProcessingSubType; SubType := SubType.FNextProcessingSubType;
DebugLnExit(DBGMI_TYPE_INFO, ['>>Leave Sub-Request']);
end; end;
Result := FFirstProcessingSubType = nil; Result := FFirstProcessingSubType = nil;
DebugLnExit(DBGMI_TYPE_INFO, ['>>Leave Sub-Request']);
end; end;
var var
@ -3011,8 +3149,7 @@ begin
FEvalRequest := nil; FEvalRequest := nil;
FLastEvalRequest := nil; FLastEvalRequest := nil;
Lines := nil; Lines := nil;
WriteStr(s, FProcessState); // TODO dbgs DebugLnEnter(DBGMI_TYPE_INFO, ['>>Enter: TGDBType.ProcessExpression: ', DebugString]);
DebugLnEnter(DBGMI_TYPE_INFO, ['>>Enter: TGDBType.ProcessExpression: state = ', s, ' Expression="', FExpression, '"']);
try try
@ -3036,6 +3173,7 @@ begin
gtpsClassAncestor: ProcessClassAncestor; gtpsClassAncestor: ProcessClassAncestor;
gtpsArray: ProcessArray; gtpsArray: ProcessArray;
gtpsEvalExpr: EvaluateExpression; gtpsEvalExpr: EvaluateExpression;
gtpsEvalExprRepeated: EvaluateExpressionRepeated;
gtpsEvalExprArray: EvaluateExpressionArray; gtpsEvalExprArray: EvaluateExpressionArray;
gtpsEvalExprDynArray: EvaluateExpressionDynArray; gtpsEvalExprDynArray: EvaluateExpressionDynArray;
gtpsEvalExprDynArrayGetData: EvaluateExpressionDynArrayGetData; gtpsEvalExprDynArrayGetData: EvaluateExpressionDynArrayGetData;

View File

@ -39,7 +39,7 @@ unit WatchPropertyDlg;
interface interface
uses uses
Classes, Forms, StdCtrls, Extctrls, ButtonPanel, LazarusIDEStrConsts, Classes, sysutils, Forms, StdCtrls, Extctrls, ButtonPanel, LazarusIDEStrConsts,
IDEHelpIntf, Debugger, BaseDebugManager, DebuggerStrConst; IDEHelpIntf, Debugger, BaseDebugManager, DebuggerStrConst;
type type
@ -97,6 +97,8 @@ begin
if chkUseInstanceClass.Checked if chkUseInstanceClass.Checked
then FWatch.EvaluateFlags := [defClassAutoCast] then FWatch.EvaluateFlags := [defClassAutoCast]
else FWatch.EvaluateFlags := []; else FWatch.EvaluateFlags := [];
FWatch.RepeatCount := StrToIntDef(txtRepCount.Text, 0);
FWatch.Enabled := chkEnabled.Checked; FWatch.Enabled := chkEnabled.Checked;
end; end;
@ -124,17 +126,16 @@ begin
txtExpression.Text := AWatchExpression; txtExpression.Text := AWatchExpression;
rgStyle.ItemIndex := 7; rgStyle.ItemIndex := 7;
chkUseInstanceClass.Checked := False; chkUseInstanceClass.Checked := False;
txtRepCount.Text := '0';
end end
else begin else begin
txtExpression.Text := FWatch.Expression; txtExpression.Text := FWatch.Expression;
chkEnabled.Checked := FWatch.Enabled; chkEnabled.Checked := FWatch.Enabled;
rgStyle.ItemIndex := DispFormatToStyle[FWatch.DisplayFormat]; rgStyle.ItemIndex := DispFormatToStyle[FWatch.DisplayFormat];
chkUseInstanceClass.Checked := defClassAutoCast in FWatch.EvaluateFlags; chkUseInstanceClass.Checked := defClassAutoCast in FWatch.EvaluateFlags;
txtRepCount.Text := IntToStr(FWatch.RepeatCount);
end; end;
lblRepCount.Enabled := False;
txtRepCount.Enabled := False;
lblDigits.Enabled := False; lblDigits.Enabled := False;
txtDigits.Enabled := False; txtDigits.Enabled := False;
chkAllowFunc.Enabled := False; chkAllowFunc.Enabled := False;