mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 17:19:19 +02:00
DBG: implemented "Repeat Count" for watches
git-svn-id: trunk@37455 -
This commit is contained in:
parent
6f93a15f00
commit
bbf31875cd
@ -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;
|
||||||
|
|
||||||
{ =========================================================================== }
|
{ =========================================================================== }
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user