mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-07 18:58:04 +02:00
IdeDebugger: Value-formatters, match expression/name
This commit is contained in:
parent
066b6f09a2
commit
ee125ebe32
@ -35,7 +35,9 @@ type
|
||||
|
||||
TDbgTypePatternList = class(TStringList)
|
||||
private
|
||||
FMatchesExpression: boolean;
|
||||
FMatchesInheritedTypes: boolean;
|
||||
FMatchesName: boolean;
|
||||
protected
|
||||
procedure Put(Index: Integer; const S: string); override;
|
||||
procedure InsertItem(Index: Integer; const S: string); override;
|
||||
@ -44,8 +46,14 @@ type
|
||||
constructor Create;
|
||||
function AddObject(const S: string; AObject: TObject): Integer; override;
|
||||
function CheckTypeName(ATypeName: String): boolean;
|
||||
function CheckUpperCaseTypeName(const AnUpperTypeName: String): boolean; // already upper case
|
||||
function CheckInheritedTypeName(ATypeName: String): boolean;
|
||||
function CheckUpperCaseName(const AnUpperName: String): boolean;
|
||||
function CheckUpperCaseExpression(const AnUpperExpression: String): boolean;
|
||||
|
||||
property MatchesInheritedTypes: boolean read FMatchesInheritedTypes; // perform "is TFooClass"
|
||||
property MatchesExpression: boolean read FMatchesExpression; // expr: pattern
|
||||
property MatchesName: boolean read FMatchesName; // var: pattern
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -57,13 +65,17 @@ type
|
||||
TDbgTypePattern = class
|
||||
private
|
||||
FMatchesInheritedTypes: boolean;
|
||||
FMatchesExpression: boolean;
|
||||
FMatchesName: boolean;
|
||||
FPatterType: (ptNever, ptAny, ptExact, ptExactAtStart, ptExactAtEnd, ptSubString, ptMatch);
|
||||
FStartsWithMatch, FEndsWithMatch: Boolean;
|
||||
FPatternParts: array of string;
|
||||
public
|
||||
procedure SetPattern(APattern: String);
|
||||
function CheckTypeName(const ATypeName: String): boolean;
|
||||
property MatchesInheritedTypes: boolean read FMatchesInheritedTypes; // perform "is TFooClass"
|
||||
property MatchesInheritedTypes: boolean read FMatchesInheritedTypes; // is: pattern // perform "is TFooClass"
|
||||
property MatchesExpression: boolean read FMatchesExpression; // expr: pattern
|
||||
property MatchesName: boolean read FMatchesName; // var: pattern
|
||||
end;
|
||||
|
||||
{ TDbgTypePattern }
|
||||
@ -80,6 +92,21 @@ begin
|
||||
APattern := TrimLeft(APattern);
|
||||
end;
|
||||
|
||||
FMatchesExpression := (Length(APattern) >= 5) and
|
||||
(APattern[1] = 'E') and (APattern[2] = 'X') and
|
||||
(APattern[3] = 'P') and (APattern[4] = 'R') and (APattern[5] = ':');
|
||||
if FMatchesExpression then begin
|
||||
Delete(APattern, 1, 5);
|
||||
APattern := TrimLeft(APattern);
|
||||
end;
|
||||
|
||||
FMatchesName := (Length(APattern) >= 4) and
|
||||
(APattern[1] = 'V') and (APattern[2] = 'A') and (APattern[3] = 'R') and (APattern[4] = ':');
|
||||
if FMatchesName then begin
|
||||
Delete(APattern, 1, 4);
|
||||
APattern := TrimLeft(APattern);
|
||||
end;
|
||||
|
||||
if APattern = '' then begin
|
||||
FPatterType := ptNever;
|
||||
SetLength(FPatternParts, 0);
|
||||
@ -213,7 +240,7 @@ end;
|
||||
procedure TDbgTypePatternList.Put(Index: Integer; const S: string);
|
||||
var
|
||||
p: TDbgTypePattern;
|
||||
wasInheritMatch: Boolean;
|
||||
wasInheritMatch, wasNameMatch, wasExpressionMatch: Boolean;
|
||||
i: Integer;
|
||||
begin
|
||||
inherited Put(Index, S);
|
||||
@ -223,7 +250,10 @@ begin
|
||||
Objects[Index] := p;
|
||||
end;
|
||||
wasInheritMatch := p.MatchesInheritedTypes;
|
||||
wasNameMatch := p.MatchesName;
|
||||
wasExpressionMatch := p.MatchesExpression;
|
||||
p.SetPattern(S);
|
||||
|
||||
if p.MatchesInheritedTypes then begin
|
||||
FMatchesInheritedTypes := True;
|
||||
end
|
||||
@ -234,6 +264,28 @@ begin
|
||||
dec(i);
|
||||
FMatchesInheritedTypes := i >= 0;
|
||||
end;
|
||||
|
||||
if p.MatchesName then begin
|
||||
FMatchesName := True;
|
||||
end
|
||||
else
|
||||
if wasInheritMatch then begin
|
||||
i := Count - 1;
|
||||
while (i >= 0) and not TDbgTypePattern(Objects[Index]).MatchesName do
|
||||
dec(i);
|
||||
FMatchesName := i >= 0;
|
||||
end;
|
||||
|
||||
if p.MatchesExpression then begin
|
||||
FMatchesExpression := True;
|
||||
end
|
||||
else
|
||||
if wasInheritMatch then begin
|
||||
i := Count - 1;
|
||||
while (i >= 0) and not TDbgTypePattern(Objects[Index]).MatchesExpression do
|
||||
dec(i);
|
||||
FMatchesExpression := i >= 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDbgTypePatternList.InsertItem(Index: Integer; const S: string);
|
||||
@ -245,6 +297,10 @@ begin
|
||||
p.SetPattern(S);
|
||||
if p.MatchesInheritedTypes then
|
||||
FMatchesInheritedTypes := True;
|
||||
if p.MatchesName then
|
||||
FMatchesName := True;
|
||||
if p.MatchesExpression then
|
||||
FMatchesExpression := True;
|
||||
end;
|
||||
|
||||
procedure TDbgTypePatternList.InsertItem(Index: Integer; const S: string;
|
||||
@ -280,10 +336,23 @@ begin
|
||||
Result := i >= 0;
|
||||
end;
|
||||
|
||||
function TDbgTypePatternList.CheckUpperCaseTypeName(const AnUpperTypeName: String): boolean;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
i := Count - 1;
|
||||
while (i >= 0) and not TDbgTypePattern(Objects[i]).CheckTypeName(AnUpperTypeName) do
|
||||
dec(i);
|
||||
Result := i >= 0;
|
||||
end;
|
||||
|
||||
function TDbgTypePatternList.CheckInheritedTypeName(ATypeName: String): boolean;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := FMatchesInheritedTypes;
|
||||
if not Result then
|
||||
exit;
|
||||
ATypeName := AnsiUpperCase(ATypeName);
|
||||
i := Count - 1;
|
||||
while (i >= 0) and
|
||||
@ -295,5 +364,39 @@ begin
|
||||
Result := i >= 0;
|
||||
end;
|
||||
|
||||
function TDbgTypePatternList.CheckUpperCasename(const AnUpperName: String): boolean;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := FMatchesName;
|
||||
if not Result then
|
||||
exit;
|
||||
i := Count - 1;
|
||||
while (i >= 0) and not
|
||||
( TDbgTypePattern(Objects[i]).MatchesName and
|
||||
TDbgTypePattern(Objects[i]).CheckTypeName(AnUpperName)
|
||||
)
|
||||
do
|
||||
dec(i);
|
||||
Result := i >= 0;
|
||||
end;
|
||||
|
||||
function TDbgTypePatternList.CheckUpperCaseExpression(const AnUpperExpression: String): boolean;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := FMatchesExpression;
|
||||
if not Result then
|
||||
exit;
|
||||
i := Count - 1;
|
||||
while (i >= 0) and not
|
||||
( TDbgTypePattern(Objects[i]).MatchesExpression and
|
||||
TDbgTypePattern(Objects[i]).CheckTypeName(AnUpperExpression)
|
||||
)
|
||||
do
|
||||
dec(i);
|
||||
Result := i >= 0;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
@ -11485,7 +11485,7 @@ procedure TMainIDE.HintWatchValidityChanged(Sender: TObject);
|
||||
var
|
||||
p: SizeInt;
|
||||
WatchPrinter: TWatchResultPrinter;
|
||||
ResultText: String;
|
||||
ResultText, s: String;
|
||||
ResData: TWatchResultData;
|
||||
DispFormat: TWatchDisplayFormat;
|
||||
begin
|
||||
@ -11511,12 +11511,13 @@ begin
|
||||
if (ResData <> nil) and
|
||||
not( (ResData.ValueKind = rdkPrePrinted) and (FHintWatchData.WatchValue.TypeInfo <> nil) )
|
||||
then begin
|
||||
ResultText := WatchPrinter.PrintWatchValue(ResData, DispFormat);
|
||||
ResultText := WatchPrinter.PrintWatchValue(ResData, DispFormat, FHintWatchData.WatchValue.Expression);
|
||||
end
|
||||
else begin
|
||||
s := AnsiUpperCase(FHintWatchData.WatchValue.Expression);
|
||||
if (FHintWatchData.WatchValue.TypeInfo = nil) or
|
||||
not GlobalValueFormatterSelectorList.FormatValue(FHintWatchData.WatchValue.TypeInfo,
|
||||
FHintWatchData.WatchValue.Value, DispFormat, ResultText)
|
||||
FHintWatchData.WatchValue.Value, DispFormat, ResultText, s, s)
|
||||
then begin
|
||||
ResultText := FHintWatchData.WatchValue.Value;
|
||||
if (FHintWatchData.WatchValue.TypeInfo <> nil) and
|
||||
|
@ -280,7 +280,7 @@ begin
|
||||
else
|
||||
FWatchPrinter.FormatFlags := FWatchPrinter.FormatFlags - [rpfSkipValueFormatter];
|
||||
FWatchPrinter.OnlyValueFormatter := WatchInspectNav1.DbgValueFormatter;
|
||||
ResultText := FWatchPrinter.PrintWatchValue(WatchInspectNav1.CurrentWatchValue.ResultData, WatchInspectNav1.DisplayFormat);
|
||||
ResultText := FWatchPrinter.PrintWatchValue(WatchInspectNav1.CurrentWatchValue.ResultData, WatchInspectNav1.DisplayFormat, AWatch.Expression);
|
||||
if (WatchInspectNav1.CurrentWatchValue.ResultData <> nil) and
|
||||
(WatchInspectNav1.CurrentWatchValue.ResultData.ValueKind = rdkArray) and (WatchInspectNav1.CurrentWatchValue.ResultData.ArrayLength > 0)
|
||||
then
|
||||
|
@ -23,12 +23,14 @@ type
|
||||
IIdeDbgValueFormatterIntf = interface ['{2BEC59F6-7CD8-4CFE-B399-C25AFCADB700}']
|
||||
function FormatValue(AWatchValue: IWatchResultDataIntf;
|
||||
ADisplayFormat: TWatchDisplayFormat; ANestLevel: integer;
|
||||
AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String
|
||||
AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String;
|
||||
const AWatchedVarUpper, AWatchedExprUpper: String // must be already uppercase
|
||||
): Boolean;
|
||||
function FormatValue(aDBGType: TDBGType;
|
||||
aValue: string;
|
||||
ADisplayFormat: TWatchDisplayFormat;
|
||||
out APrintedValue: String
|
||||
out APrintedValue: String;
|
||||
const AWatchedVarUpper, AWatchedExprUpper: String // must be already uppercase
|
||||
): boolean; deprecated 'For values from older backends only - to be removed as backends are upgraded';
|
||||
end;
|
||||
|
||||
@ -63,19 +65,23 @@ type
|
||||
procedure LoadDataFromXMLConfig(const AConfig: TRttiXMLConfig; const APath: string);
|
||||
procedure SaveDataToXMLConfig(const AConfig: TRttiXMLConfig; const APath: string);
|
||||
|
||||
function MatchesAll(AWatchValue: IWatchResultDataIntf; ADisplayFormat: TWatchDisplayFormat; ANestLevel: integer): Boolean;
|
||||
function MatchesAll(AWatchValue: IWatchResultDataIntf; ADisplayFormat: TWatchDisplayFormat; ANestLevel: integer;
|
||||
const AWatchedVarUpper, AWatchedExprUpper: String): Boolean;
|
||||
function FormatValue(AWatchValue: IWatchResultDataIntf;
|
||||
ADisplayFormat: TWatchDisplayFormat; ANestLevel: integer;
|
||||
AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String
|
||||
AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String;
|
||||
const AWatchedVarUpper, AWatchedExprUpper: String // must be already uppercase
|
||||
): Boolean; experimental;
|
||||
function FormatValue(aDBGType: TDBGType;
|
||||
aValue: string;
|
||||
ADisplayFormat: TWatchDisplayFormat;
|
||||
out APrintedValue: String
|
||||
out APrintedValue: String;
|
||||
const AWatchedVarUpper, AWatchedExprUpper: String // must be already uppercase
|
||||
): boolean; deprecated 'For values from older backends only - to be removed as backends are upgraded';
|
||||
|
||||
function IsMatchingTypeName(ATypeName: String): boolean;
|
||||
function IsMatchingInheritedTypeName(ATypeName: String): boolean;
|
||||
function IsMatchingTypeName(const ATypeNameUpper: String): boolean; inline;
|
||||
function IsMatchingInheritedTypeName(ATypeName: String): boolean; inline;
|
||||
function IsMatchingName(const AWatchedVarUpper, AWatchedExprUpper: String): boolean; inline;
|
||||
published
|
||||
property ValFormatter: ILazDbgIdeValueFormatterIntf read FValFormatter;
|
||||
property ValFormatterRegEntry: TLazDbgIdeValueFormatterRegistryEntryClass read FValFormatterRegEntry;
|
||||
@ -118,12 +124,14 @@ type
|
||||
destructor Destroy; override;
|
||||
function FormatValue(AWatchValue: IWatchResultDataIntf;
|
||||
ADisplayFormat: TWatchDisplayFormat; ANestLevel: integer;
|
||||
AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String
|
||||
AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String;
|
||||
const AWatchedVarUpper, AWatchedExprUpper: String
|
||||
): Boolean;
|
||||
function FormatValue(aDBGType: TDBGType;
|
||||
aValue: string;
|
||||
ADisplayFormat: TWatchDisplayFormat;
|
||||
out APrintedValue: String
|
||||
out APrintedValue: String;
|
||||
const AWatchedVarUpper, AWatchedExprUpper: String
|
||||
): boolean; deprecated 'For values from older backends only - to be removed as backends are upgraded';
|
||||
published
|
||||
// This will only be saved to disk, if "Changed = True", i.e. if the list itself changed
|
||||
@ -262,7 +270,8 @@ begin
|
||||
end;
|
||||
|
||||
function TIdeDbgValueFormatterSelector.MatchesAll(AWatchValue: IWatchResultDataIntf;
|
||||
ADisplayFormat: TWatchDisplayFormat; ANestLevel: integer): Boolean;
|
||||
ADisplayFormat: TWatchDisplayFormat; ANestLevel: integer; const AWatchedVarUpper,
|
||||
AWatchedExprUpper: String): Boolean;
|
||||
var
|
||||
j: Integer;
|
||||
a: IWatchResultDataIntf;
|
||||
@ -278,7 +287,7 @@ begin
|
||||
then
|
||||
exit;
|
||||
|
||||
if not IsMatchingTypeName(AWatchValue.TypeName) then begin
|
||||
if not IsMatchingTypeName(AnsiUpperCase(AWatchValue.TypeName)) then begin
|
||||
if not MatchInherited then
|
||||
exit;
|
||||
j := AWatchValue.AnchestorCount - 1;
|
||||
@ -292,20 +301,25 @@ begin
|
||||
exit;
|
||||
end;
|
||||
|
||||
if not IsMatchingName(AWatchedVarUpper, AWatchedExprUpper) then
|
||||
exit;
|
||||
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
function TIdeDbgValueFormatterSelector.FormatValue(AWatchValue: IWatchResultDataIntf;
|
||||
ADisplayFormat: TWatchDisplayFormat; ANestLevel: integer;
|
||||
AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String): Boolean;
|
||||
AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String;
|
||||
const AWatchedVarUpper, AWatchedExprUpper: String): Boolean;
|
||||
begin
|
||||
Result := MatchesAll(AWatchValue, ADisplayFormat, ANestLevel);
|
||||
Result := MatchesAll(AWatchValue, ADisplayFormat, ANestLevel, AWatchedVarUpper, AWatchedExprUpper);
|
||||
if Result then
|
||||
Result := DoFormatValue(AWatchValue, ADisplayFormat, AWatchResultPrinter, APrintedValue);
|
||||
end;
|
||||
|
||||
function TIdeDbgValueFormatterSelector.FormatValue(aDBGType: TDBGType; aValue: string;
|
||||
ADisplayFormat: TWatchDisplayFormat; out APrintedValue: String): boolean;
|
||||
ADisplayFormat: TWatchDisplayFormat; out APrintedValue: String;
|
||||
const AWatchedVarUpper, AWatchedExprUpper: String): boolean;
|
||||
begin
|
||||
Result := False;
|
||||
if (ValFormatter = nil) or
|
||||
@ -317,7 +331,9 @@ begin
|
||||
then
|
||||
exit;
|
||||
|
||||
if not IsMatchingTypeName(aDBGType.TypeName) then
|
||||
if not IsMatchingTypeName(AnsiUpperCase(aDBGType.TypeName)) then
|
||||
exit;
|
||||
if not IsMatchingName(AWatchedVarUpper, AWatchedExprUpper) then
|
||||
exit;
|
||||
|
||||
FInFormatValue := True;
|
||||
@ -331,9 +347,9 @@ begin
|
||||
FInFormatValue := False;
|
||||
end;
|
||||
|
||||
function TIdeDbgValueFormatterSelector.IsMatchingTypeName(ATypeName: String): boolean;
|
||||
function TIdeDbgValueFormatterSelector.IsMatchingTypeName(const ATypeNameUpper: String): boolean;
|
||||
begin
|
||||
Result := FMatchTypeNames.CheckTypeName(ATypeName);
|
||||
Result := FMatchTypeNames.CheckUpperCaseTypeName(ATypeNameUpper);
|
||||
end;
|
||||
|
||||
function TIdeDbgValueFormatterSelector.IsMatchingInheritedTypeName(
|
||||
@ -342,6 +358,17 @@ begin
|
||||
Result := FMatchTypeNames.CheckInheritedTypeName(ATypeName);
|
||||
end;
|
||||
|
||||
function TIdeDbgValueFormatterSelector.IsMatchingName(const AWatchedVarUpper,
|
||||
AWatchedExprUpper: String): boolean;
|
||||
begin
|
||||
Result := not (FMatchTypeNames.MatchesName or FMatchTypeNames.MatchesExpression);
|
||||
if Result then
|
||||
exit;
|
||||
Result := (AWatchedVarUpper = '') or FMatchTypeNames.CheckUpperCaseName(AWatchedVarUpper);
|
||||
if not Result then
|
||||
Result := (AWatchedExprUpper = '') or FMatchTypeNames.CheckUpperCaseExpression(AWatchedExprUpper);
|
||||
end;
|
||||
|
||||
{ TIdeDbgValueFormatterSelectorList }
|
||||
|
||||
procedure TIdeDbgValueFormatterSelectorList.SetChanged(AValue: Boolean);
|
||||
@ -445,14 +472,15 @@ end;
|
||||
|
||||
function TIdeDbgValueFormatterSelectorList.FormatValue(AWatchValue: IWatchResultDataIntf;
|
||||
ADisplayFormat: TWatchDisplayFormat; ANestLevel: integer;
|
||||
AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String): Boolean;
|
||||
AWatchResultPrinter: IWatchResultPrinter; out APrintedValue: String; const AWatchedVarUpper,
|
||||
AWatchedExprUpper: String): Boolean;
|
||||
var
|
||||
i: Integer;
|
||||
f: TIdeDbgValueFormatterSelector;
|
||||
begin
|
||||
for i := 0 to Count - 1 do begin
|
||||
f := Items[i];
|
||||
if not f.MatchesAll(AWatchValue, ADisplayFormat, ANestLevel) then
|
||||
if not f.MatchesAll(AWatchValue, ADisplayFormat, ANestLevel, AWatchedVarUpper, AWatchedExprUpper) then
|
||||
continue;
|
||||
|
||||
Result := f.DoFormatValue(AWatchValue, ADisplayFormat, AWatchResultPrinter, APrintedValue);
|
||||
@ -462,9 +490,9 @@ begin
|
||||
Result := False;
|
||||
end;
|
||||
|
||||
function TIdeDbgValueFormatterSelectorList.FormatValue(aDBGType: TDBGType;
|
||||
aValue: string; ADisplayFormat: TWatchDisplayFormat; out APrintedValue: String
|
||||
): boolean;
|
||||
function TIdeDbgValueFormatterSelectorList.FormatValue(aDBGType: TDBGType; aValue: string;
|
||||
ADisplayFormat: TWatchDisplayFormat; out APrintedValue: String; const AWatchedVarUpper,
|
||||
AWatchedExprUpper: String): boolean;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
@ -472,7 +500,7 @@ begin
|
||||
if not Result then
|
||||
exit;
|
||||
for i := 0 to Count - 1 do begin
|
||||
Result := Items[i].FormatValue(aDBGType, aValue, ADisplayFormat, APrintedValue);
|
||||
Result := Items[i].FormatValue(aDBGType, aValue, ADisplayFormat, APrintedValue, AWatchedVarUpper, AWatchedExprUpper);
|
||||
if Result then
|
||||
exit;
|
||||
end;
|
||||
|
@ -72,11 +72,13 @@ type
|
||||
FLineSeparator: String;
|
||||
FOnlyValueFormatter: IIdeDbgValueFormatterIntf;
|
||||
FDefaultValueFormatter, FCurrentValueFormatter, FNextValueFormatter: IIdeDbgValueFormatterIntf;
|
||||
FWatchedVarName: String;
|
||||
FTargetAddressSize: integer;
|
||||
FDisplayFormatResolver: TDisplayFormatResolver;
|
||||
FNextCallIsValueFormatter: Boolean;
|
||||
FInValFormNestLevel: integer;
|
||||
FResValueInFormatter: TWatchResultData;
|
||||
FWatchedExprInFormatter: String;
|
||||
protected const
|
||||
MAX_ALLOWED_NEST_LVL = 100;
|
||||
protected type
|
||||
@ -93,16 +95,16 @@ type
|
||||
const ANumFormat: TResolvedDisplayFormatNum;
|
||||
PrintNil: Boolean = False
|
||||
): String;
|
||||
function PrintArray(AResValue: TWatchResultData; const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer): String;
|
||||
function PrintStruct(AResValue: TWatchResultData; const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer): String;
|
||||
function PrintConverted(AResValue: TWatchResultData; const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer): String;
|
||||
function PrintArray(AResValue: TWatchResultData; const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer; const AWatchedExpr: String): String;
|
||||
function PrintStruct(AResValue: TWatchResultData; const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer; const AWatchedExpr: String): String;
|
||||
function PrintConverted(AResValue: TWatchResultData; const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer; const AWatchedExpr: String): String;
|
||||
function PrintProc(AResValue: TWatchResultData; const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer): String;
|
||||
|
||||
function PrintWatchValueEx(AResValue: TWatchResultData; const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer): String;
|
||||
function PrintWatchValueEx(AResValue: TWatchResultData; const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer; const AWatchedExpr: String): String;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
function PrintWatchValue(AResValue: TWatchResultData; const ADispFormat: TWatchDisplayFormat): String;
|
||||
function PrintWatchValue(AResValue: TWatchResultData; const ADispFormat: TWatchDisplayFormat; const AWatchedExpr: String): String;
|
||||
function PrintWatchValueIntf(AResValue: IWatchResultDataIntf; const ADispFormat: TWatchDisplayFormat; AFlags: TWatchResultPrinterFlags = []): String;
|
||||
function IWatchResultPrinter.PrintWatchValue = PrintWatchValueIntf;
|
||||
|
||||
@ -574,7 +576,7 @@ begin
|
||||
end;
|
||||
|
||||
function TWatchResultPrinter.PrintArray(AResValue: TWatchResultData;
|
||||
const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer): String;
|
||||
const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer; const AWatchedExpr: String): String;
|
||||
var
|
||||
i: Integer;
|
||||
sep, tn: String;
|
||||
@ -608,7 +610,7 @@ begin
|
||||
if Result <> '' then
|
||||
Result := Result + sep;
|
||||
AResValue.SetSelectedIndex(i);
|
||||
Result := Result + PrintWatchValueEx(AResValue.SelectedEntry, ADispFormat, ANestLvl);
|
||||
Result := Result + PrintWatchValueEx(AResValue.SelectedEntry, ADispFormat, ANestLvl, AWatchedExpr);
|
||||
if Length(Result) > 1000*1000 div Max(1, ANestLvl*4) then begin
|
||||
Result := Result + sep +'...';
|
||||
break;
|
||||
@ -623,7 +625,7 @@ begin
|
||||
end;
|
||||
|
||||
function TWatchResultPrinter.PrintStruct(AResValue: TWatchResultData;
|
||||
const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer): String;
|
||||
const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer; const AWatchedExpr: String): String;
|
||||
const
|
||||
VisibilityNames: array [TLzDbgFieldVisibility] of string = (
|
||||
'', 'private', 'protected', 'public', 'published'
|
||||
@ -632,7 +634,7 @@ var
|
||||
Resolved: TResolvedDisplayFormat;
|
||||
FldInfo: TWatchResultDataFieldInfo;
|
||||
FldOwner: TWatchResultData;
|
||||
vis, indent, sep, tn, Header: String;
|
||||
vis, indent, sep, tn, Header, we: String;
|
||||
InclVisSect: Boolean;
|
||||
begin
|
||||
Resolved := DisplayFormatResolver.ResolveDispFormat(ADispFormat, AResValue);
|
||||
@ -672,6 +674,7 @@ begin
|
||||
else
|
||||
sep := ' ';
|
||||
|
||||
we := AWatchedExpr + '.';
|
||||
InclVisSect := (Resolved.Struct.DataFormat = vdfStructFull) and (AResValue.StructType in [dstClass, dstObject]);
|
||||
FldOwner := nil;
|
||||
vis := '';
|
||||
@ -703,7 +706,7 @@ begin
|
||||
Result := Result + indent + FldInfo.FieldName + ': '
|
||||
else
|
||||
Result := Result + indent;
|
||||
Result := Result + PrintWatchValueEx(FldInfo.Field, ADispFormat, ANestLvl) + ';';
|
||||
Result := Result + PrintWatchValueEx(FldInfo.Field, ADispFormat, ANestLvl, we + UpperCase(FldInfo.FieldName)) + ';';
|
||||
|
||||
if Length(Result) > 1000*1000 div Max(1, ANestLvl*4) then begin
|
||||
Result := Result + sep +'...';
|
||||
@ -739,7 +742,7 @@ begin
|
||||
end;
|
||||
|
||||
function TWatchResultPrinter.PrintConverted(AResValue: TWatchResultData;
|
||||
const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer): String;
|
||||
const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer; const AWatchedExpr: String): String;
|
||||
begin
|
||||
if AResValue.FieldCount = 0 then
|
||||
exit('Error: No result');
|
||||
@ -749,18 +752,18 @@ begin
|
||||
((AResValue.Fields[0].Field.ValueKind <> rdkError))
|
||||
)
|
||||
then begin
|
||||
Result := PrintWatchValueEx(AResValue.Fields[0].Field, ADispFormat, ANestLvl);
|
||||
Result := PrintWatchValueEx(AResValue.Fields[0].Field, ADispFormat, ANestLvl, AWatchedExpr);
|
||||
exit;
|
||||
end;
|
||||
|
||||
if (AResValue.FieldCount > 1) then begin
|
||||
Result := PrintWatchValueEx(AResValue.Fields[1].Field, ADispFormat, ANestLvl);
|
||||
Result := PrintWatchValueEx(AResValue.Fields[1].Field, ADispFormat, ANestLvl, AWatchedExpr);
|
||||
if (AResValue.Fields[0].Field = nil) or
|
||||
(AResValue.Fields[0].Field.ValueKind <> rdkError) or
|
||||
(AResValue.Fields[0].Field.AsString <> '')
|
||||
then
|
||||
Result := Result + ' { '
|
||||
+ PrintWatchValueEx(AResValue.Fields[0].Field, ADispFormat, ANestLvl)
|
||||
+ PrintWatchValueEx(AResValue.Fields[0].Field, ADispFormat, ANestLvl, AWatchedExpr)
|
||||
+ ' }';
|
||||
exit;
|
||||
end;
|
||||
@ -797,7 +800,7 @@ begin
|
||||
end;
|
||||
|
||||
function TWatchResultPrinter.PrintWatchValueEx(AResValue: TWatchResultData;
|
||||
const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer): String;
|
||||
const ADispFormat: TWatchDisplayFormat; ANestLvl: Integer; const AWatchedExpr: String): String;
|
||||
|
||||
function PrintChar: String;
|
||||
var
|
||||
@ -913,9 +916,10 @@ begin
|
||||
FNextCallIsValueFormatter := True;
|
||||
FInValFormNestLevel := ANestLvl;
|
||||
FResValueInFormatter := AResValue;
|
||||
FWatchedExprInFormatter := AWatchedExpr;
|
||||
//
|
||||
try
|
||||
if FCurrentValueFormatter.FormatValue(AResValue, ADispFormat, ANestLvl, Self, Result) then
|
||||
if FCurrentValueFormatter.FormatValue(AResValue, ADispFormat, ANestLvl, Self, Result, FWatchedVarName, AWatchedExpr) then
|
||||
exit;
|
||||
finally
|
||||
FNextCallIsValueFormatter := False;
|
||||
@ -977,9 +981,9 @@ begin
|
||||
PtrDeref := PtrDeref.DerefData;
|
||||
end;
|
||||
if PtrDeref <> nil then
|
||||
Result := Result + '^: ' + PrintWatchValueEx(PtrDeref, ADispFormat, ANestLvl)
|
||||
Result := Result + '^: ' + PrintWatchValueEx(PtrDeref, ADispFormat, ANestLvl, AWatchedExpr+'^')
|
||||
else
|
||||
Result := Result + ': ' + PrintWatchValueEx(PtrDeref2, ADispFormat, ANestLvl);
|
||||
Result := Result + ': ' + PrintWatchValueEx(PtrDeref2, ADispFormat, ANestLvl, AWatchedExpr+'^');
|
||||
end;
|
||||
end;
|
||||
rdkFloatVal: begin
|
||||
@ -1006,19 +1010,19 @@ begin
|
||||
rdkSet: Result := PrintSet;
|
||||
rdkPCharOrString: begin
|
||||
AResValue.SetSelectedIndex(0); // pchar res
|
||||
Result := 'PChar: ' + PrintWatchValueEx(AResValue.SelectedEntry, ADispFormat, ANestLvl);
|
||||
Result := 'PChar: ' + PrintWatchValueEx(AResValue.SelectedEntry, ADispFormat, ANestLvl, AWatchedExpr);
|
||||
AResValue.SetSelectedIndex(1); // string res
|
||||
Result := Result + FLineSeparator
|
||||
+ 'String: ' + PrintWatchValueEx(AResValue.SelectedEntry, ADispFormat, ANestLvl);
|
||||
+ 'String: ' + PrintWatchValueEx(AResValue.SelectedEntry, ADispFormat, ANestLvl, AWatchedExpr);
|
||||
end;
|
||||
rdkArray: Result := PrintArray(AResValue, ADispFormat, ANestLvl);
|
||||
rdkStruct: Result := PrintStruct(AResValue, ADispFormat, ANestLvl);
|
||||
rdkConvertRes: Result := PrintConverted(AResValue, ADispFormat, ANestLvl);
|
||||
rdkArray: Result := PrintArray(AResValue, ADispFormat, ANestLvl, AWatchedExpr);
|
||||
rdkStruct: Result := PrintStruct(AResValue, ADispFormat, ANestLvl, AWatchedExpr);
|
||||
rdkConvertRes: Result := PrintConverted(AResValue, ADispFormat, ANestLvl, AWatchedExpr);
|
||||
rdkFunction,
|
||||
rdkProcedure,
|
||||
rdkFunctionRef,
|
||||
rdkProcedureRef: Result := PrintProc(AResValue, ADispFormat, ANestLvl);
|
||||
rdkVariant: Result := PrintWatchValueEx(AResValue.DerefData, ADispFormat, ANestLvl);
|
||||
rdkVariant: Result := PrintWatchValueEx(AResValue.DerefData, ADispFormat, ANestLvl, AWatchedExpr);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1036,7 +1040,7 @@ begin
|
||||
end;
|
||||
|
||||
function TWatchResultPrinter.PrintWatchValue(AResValue: TWatchResultData;
|
||||
const ADispFormat: TWatchDisplayFormat): String;
|
||||
const ADispFormat: TWatchDisplayFormat; const AWatchedExpr: String): String;
|
||||
begin
|
||||
FNextValueFormatter := nil;
|
||||
if FOnlyValueFormatter <> nil then
|
||||
@ -1054,7 +1058,8 @@ begin
|
||||
else
|
||||
FLineSeparator := ' ';
|
||||
|
||||
Result := PrintWatchValueEx(AResValue, ADispFormat, -1);
|
||||
FWatchedVarName := UpperCase(AWatchedExpr);
|
||||
Result := PrintWatchValueEx(AResValue, ADispFormat, -1, FWatchedVarName);
|
||||
end;
|
||||
|
||||
function TWatchResultPrinter.PrintWatchValueIntf(AResValue: IWatchResultDataIntf;
|
||||
@ -1081,12 +1086,12 @@ begin
|
||||
|
||||
if FNextCallIsValueFormatter then begin
|
||||
FNextCallIsValueFormatter := False;
|
||||
Result := PrintWatchValueEx(AResValObj, ADispFormat, FInValFormNestLevel - 1 + IncLvl); // This will increase it by one, compared to the value given to the formatter
|
||||
Result := PrintWatchValueEx(AResValObj, ADispFormat, FInValFormNestLevel - 1 + IncLvl, FWatchedExprInFormatter); // This will increase it by one, compared to the value given to the formatter
|
||||
end
|
||||
else begin
|
||||
// TOOD: full init? Or Call PrintWatchValueEx ?
|
||||
// TODO: inc level/count of iterations
|
||||
Result := PrintWatchValueEx(AResValObj, ADispFormat, -1);
|
||||
Result := PrintWatchValueEx(AResValObj, ADispFormat, -1, FWatchedExprInFormatter);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -212,7 +212,7 @@ begin
|
||||
WatchInspectNav1.ColTypeEnabled := True;
|
||||
WatchInspectNav1.ColVisibilityEnabled := False;
|
||||
|
||||
v := ClearMultiline(FWatchPrinter.PrintWatchValue(Res, WatchInspectNav1.DisplayFormat));
|
||||
v := ClearMultiline(FWatchPrinter.PrintWatchValue(Res, WatchInspectNav1.DisplayFormat, WatchInspectNav1.CurrentWatchValue.Expression));
|
||||
StatusBar1.SimpleText:=ShortenedExpression+' : '+FCurrentTypePrefix+Res.TypeName + ' = ' + v;
|
||||
|
||||
GridDataSetup;
|
||||
@ -239,13 +239,13 @@ begin
|
||||
WatchInspectNav1.ColTypeEnabled := True;
|
||||
WatchInspectNav1.ColVisibilityEnabled := False;
|
||||
|
||||
v := ClearMultiline(FWatchPrinter.PrintWatchValue(Res, WatchInspectNav1.DisplayFormat));
|
||||
v := ClearMultiline(FWatchPrinter.PrintWatchValue(Res, WatchInspectNav1.DisplayFormat, WatchInspectNav1.CurrentWatchValue.Expression));
|
||||
StatusBar1.SimpleText:=ShortenedExpression+' : '+FCurrentTypePrefix+Res.TypeName + ' = ' + v;
|
||||
|
||||
GridDataSetup;
|
||||
df := WatchInspectNav1.DisplayFormat;
|
||||
df.Num.BaseFormat := vdfBaseHex; //xxxxxxxxxxxxxxxxxxxxxx
|
||||
v := ClearMultiline(FWatchPrinter.PrintWatchValue(Res, df));
|
||||
v := ClearMultiline(FWatchPrinter.PrintWatchValue(Res, df, WatchInspectNav1.CurrentWatchValue.Expression));
|
||||
FGridData.Cells[1,1]:=WatchInspectNav1.Expression;
|
||||
FGridData.Cells[2,1]:=FCurrentTypePrefix+Res.TypeName;
|
||||
FGridData.Cells[3,1]:=v;
|
||||
@ -255,7 +255,7 @@ begin
|
||||
FGridData.RowCount := 3;
|
||||
FGridData.Cells[1,2]:=Format(lisInspectPointerTo, ['']);
|
||||
FGridData.Cells[2,2]:=Res.TypeName;
|
||||
FGridData.Cells[3,2]:=ClearMultiline(FWatchPrinter.PrintWatchValue(Res, WatchInspectNav1.DisplayFormat));
|
||||
FGridData.Cells[3,2]:=ClearMultiline(FWatchPrinter.PrintWatchValue(Res, WatchInspectNav1.DisplayFormat, WatchInspectNav1.CurrentWatchValue.Expression));
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -277,7 +277,7 @@ begin
|
||||
WatchInspectNav1.ColTypeEnabled := True;
|
||||
WatchInspectNav1.ColVisibilityEnabled := False;
|
||||
|
||||
v := ClearMultiline(FWatchPrinter.PrintWatchValue(Res, WatchInspectNav1.DisplayFormat));
|
||||
v := ClearMultiline(FWatchPrinter.PrintWatchValue(Res, WatchInspectNav1.DisplayFormat, WatchInspectNav1.CurrentWatchValue.Expression));
|
||||
StatusBar1.SimpleText:=ShortenedExpression+' : '+FCurrentTypePrefix+Res.TypeName + ' = ' + v;
|
||||
|
||||
GridDataSetup;
|
||||
@ -367,7 +367,7 @@ begin
|
||||
Res.SetSelectedIndex(i);
|
||||
Entry := Res.SelectedEntry;
|
||||
Entry := Entry.ConvertedRes;
|
||||
s := ClearMultiline(FWatchPrinter.PrintWatchValue(Entry, WatchInspectNav1.DisplayFormat));
|
||||
s := ClearMultiline(FWatchPrinter.PrintWatchValue(Entry, WatchInspectNav1.DisplayFormat, WatchInspectNav1.CurrentWatchValue.Expression));
|
||||
|
||||
if (filter <> '') and
|
||||
// index
|
||||
@ -512,7 +512,7 @@ begin
|
||||
else begin
|
||||
s := '';
|
||||
if Fld <> nil then
|
||||
s := ClearMultiline(FWatchPrinter.PrintWatchValue(Fld, WatchInspectNav1.DisplayFormat));
|
||||
s := ClearMultiline(FWatchPrinter.PrintWatchValue(Fld, WatchInspectNav1.DisplayFormat, WatchInspectNav1.CurrentWatchValue.Expression));
|
||||
if (filter <> '') and
|
||||
// name
|
||||
(pos(filter, LowerCase(FldInfo.FieldName)) < 1) and
|
||||
@ -1373,7 +1373,7 @@ begin
|
||||
FExpressionWasEvaluated := True;
|
||||
FCurrentResData := WatchInspectNav1.CurrentWatchValue.ResultData;
|
||||
FCurrentTypePrefix := '';
|
||||
FHumanReadable := FWatchPrinter.PrintWatchValue(FCurrentResData, DefaultWatchDisplayFormat);
|
||||
FHumanReadable := FWatchPrinter.PrintWatchValue(FCurrentResData, DefaultWatchDisplayFormat, WatchInspectNav1.CurrentWatchValue.Expression);
|
||||
|
||||
if WatchInspectNav1.CurrentWatchValue.Validity = ddsValid then begin
|
||||
if WatchInspectNav1.CurrentWatchValue.TypeInfo <> nil then begin
|
||||
|
@ -787,7 +787,7 @@ begin
|
||||
LVal := GetSelected;
|
||||
if (LVal <> nil) and (LVal.ResultData <> nil) then begin
|
||||
Clipboard.Open;
|
||||
Clipboard.AsText := ValueToRAW(FWatchPrinter.PrintWatchValue(LVal.ResultData, DefaultWatchDisplayFormat));
|
||||
Clipboard.AsText := ValueToRAW(FWatchPrinter.PrintWatchValue(LVal.ResultData, DefaultWatchDisplayFormat, LVal.Name));
|
||||
Clipboard.Close;
|
||||
end;
|
||||
end;
|
||||
@ -807,7 +807,7 @@ begin
|
||||
LVal := GetSelected;
|
||||
if (LVal <> nil) and (LVal.ResultData <> nil) then begin
|
||||
Clipboard.Open;
|
||||
Clipboard.AsText := FWatchPrinter.PrintWatchValue(LVal.ResultData, DefaultWatchDisplayFormat);
|
||||
Clipboard.AsText := FWatchPrinter.PrintWatchValue(LVal.ResultData, DefaultWatchDisplayFormat, LVal.Name);
|
||||
Clipboard.Close;
|
||||
end;
|
||||
end;
|
||||
@ -850,6 +850,7 @@ var
|
||||
ResData: TWatchResultData;
|
||||
da: TDBGPtr;
|
||||
DispFormat: TWatchDisplayFormat;
|
||||
s: String;
|
||||
begin
|
||||
if AWatchAbleResult = nil then
|
||||
exit(inherited);
|
||||
@ -892,12 +893,13 @@ begin
|
||||
if (ResData <> nil) and
|
||||
not( (ResData.ValueKind = rdkPrePrinted) and (AWatchAbleResult.TypeInfo <> nil) )
|
||||
then begin
|
||||
Result := FLocalsDlg.FWatchPrinter.PrintWatchValue(ResData, DispFormat);
|
||||
Result := FLocalsDlg.FWatchPrinter.PrintWatchValue(ResData, DispFormat, TIdeLocalsValue(AWatchAble).Name);
|
||||
end
|
||||
else begin
|
||||
s := AnsiUpperCase(TIdeLocalsValue(AWatchAble).Name);
|
||||
if (AWatchAbleResult.TypeInfo = nil) or
|
||||
not GlobalValueFormatterSelectorList.FormatValue(AWatchAbleResult.TypeInfo,
|
||||
AWatchAbleResult.Value, DispFormat, Result)
|
||||
AWatchAbleResult.Value, DispFormat, Result, s, s)
|
||||
then begin
|
||||
Result := AWatchAbleResult.Value;
|
||||
end;
|
||||
@ -920,7 +922,7 @@ end;
|
||||
procedure TDbgTreeViewLocalsValueMgr.UpdateColumnsText(AWatchAble: TObject;
|
||||
AWatchAbleResult: IWatchAbleResultIntf; AVNode: PVirtualNode);
|
||||
var
|
||||
WatchValueStr: String;
|
||||
WatchValueStr, s: String;
|
||||
ResData: TWatchResultData;
|
||||
da: TDBGPtr;
|
||||
DispFormat: TWatchDisplayFormat;
|
||||
@ -930,12 +932,13 @@ begin
|
||||
if (ResData <> nil) and
|
||||
not( (ResData.ValueKind = rdkPrePrinted) and (AWatchAbleResult.TypeInfo <> nil) )
|
||||
then begin
|
||||
WatchValueStr := FLocalsDlg.FWatchPrinter.PrintWatchValue(ResData, DispFormat);
|
||||
WatchValueStr := FLocalsDlg.FWatchPrinter.PrintWatchValue(ResData, DispFormat, TIdeLocalsValue(AWatchAble).Name);
|
||||
end
|
||||
else begin
|
||||
s := AnsiUpperCase(TIdeLocalsValue(AWatchAble).Name);
|
||||
if (AWatchAbleResult.TypeInfo = nil) or
|
||||
not GlobalValueFormatterSelectorList.FormatValue(AWatchAbleResult.TypeInfo,
|
||||
AWatchAbleResult.Value, DispFormat, WatchValueStr)
|
||||
AWatchAbleResult.Value, DispFormat, WatchValueStr, s, s)
|
||||
then begin
|
||||
WatchValueStr := AWatchAbleResult.Value;
|
||||
end;
|
||||
|
@ -42,7 +42,7 @@ end;
|
||||
function TTestWatchResPrinter.TestPrint(AResValue: TWatchResultData;
|
||||
const ADispFormat: TWatchDisplayFormat): String;
|
||||
begin
|
||||
Result := FWatchResPrinter.PrintWatchValue(AResValue, ADispFormat);
|
||||
Result := FWatchResPrinter.PrintWatchValue(AResValue, ADispFormat, '');
|
||||
end;
|
||||
|
||||
procedure TTestWatchResPrinter.AssertPrint(AExp: String; AResValue: TWatchResultData;
|
||||
@ -91,103 +91,103 @@ begin
|
||||
|
||||
// Pad with lead 0
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 0;
|
||||
AssertEquals('Pad 201', '201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad 201', '201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 1;
|
||||
AssertEquals('Pad 201', '201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad 201', '201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 2;
|
||||
AssertEquals('Pad 201', '201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad 201', '201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 4;
|
||||
AssertEquals('Pad 0201', '0201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad 0201', '0201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 7;
|
||||
AssertEquals('Pad 0201', '0000201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad 0201', '0000201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.MinDigits[vdfBaseDecimal] := -1;
|
||||
AssertEquals('Pad 201', '00201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad 201', '00201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
|
||||
// Pad with lead 0 and thousand-dot
|
||||
d.Num.SeparatorDec := True;
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 0;
|
||||
AssertEquals('Pad/Sep 201', '201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad/Sep 201', '201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 1;
|
||||
AssertEquals('Pad/Sep 201', '201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad/Sep 201', '201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 2;
|
||||
AssertEquals('Pad/Sep 201', '201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad/Sep 201', '201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 4;
|
||||
AssertEquals('Pad/Sep 0201', '0.201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad/Sep 0201', '0.201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 5;
|
||||
AssertEquals('Pad 0201', '00.201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad 0201', '00.201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 6;
|
||||
AssertEquals('Pad 0201', '000.201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad 0201', '000.201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 7;
|
||||
AssertEquals('Pad 0201', '0.000.201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad 0201', '0.000.201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 8;
|
||||
AssertEquals('Pad 0201', '00.000.201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad 0201', '00.000.201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 9;
|
||||
AssertEquals('Pad 0201', '000.000.201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad 0201', '000.000.201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.MinDigits[vdfBaseDecimal] := -1;
|
||||
AssertEquals('Pad/Sep 201', '00.201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Pad/Sep 201', '00.201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
|
||||
// thousand-dot
|
||||
Res := GetNumRes(QWord(1234567), True, 4);
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 0;
|
||||
d.Num.SeparatorDec := False;
|
||||
AssertEquals('Sep 1234567', '1234567', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Sep 1234567', '1234567', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.SeparatorDec := True;
|
||||
AssertEquals('Sep 1234567', '1.234.567', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Sep 1234567', '1.234.567', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
|
||||
d.Num.SeparatorDec := True;
|
||||
Res := GetNumRes(QWord(123456), True, 4);
|
||||
AssertEquals('Sep 123456', '123.456', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Sep 123456', '123.456', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
Res := GetNumRes(QWord(23456), True, 4);
|
||||
AssertEquals('Sep 23456', '23.456', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Sep 23456', '23.456', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
|
||||
|
||||
Res := GetNumRes(QWord(-1201), True, 2);
|
||||
d.Num.SeparatorDec := False;
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 0;
|
||||
AssertEquals('', '-1201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('', '-1201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 7;
|
||||
AssertEquals('', '-0001201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('', '-0001201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
|
||||
d.Num.MinDigits[vdfBaseDecimal] := -1;
|
||||
AssertEquals('', '-01201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('', '-01201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 0;
|
||||
d.Num.SeparatorDec := True;
|
||||
AssertEquals('', '-1.201', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('', '-1.201', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
|
||||
// hex full digit
|
||||
Res := GetNumRes(QWord($123456789A), False, 8);
|
||||
d.Num.BaseFormat := vdfBaseHex;
|
||||
d.Num.MinDigits[vdfBaseDecimal] := 0;
|
||||
AssertEquals('Hex grp', '$000000123456789A', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Hex grp', '$000000123456789A', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.MinDigits[vdfBaseDecimal] := -1;
|
||||
AssertEquals('Hex grp', '$000000123456789A', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Hex grp', '$000000123456789A', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
|
||||
// hex spacing
|
||||
d.Num.MinDigits[vdfBaseHex] := 1;
|
||||
AssertEquals('Hex grp', '$123456789A', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Hex grp', '$123456789A', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.SeparatorHexBin := vdfhsByte;
|
||||
AssertEquals('Hex grp', '$12 34 56 78 9A', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Hex grp', '$12 34 56 78 9A', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.SeparatorHexBin := vdfhsWord;
|
||||
AssertEquals('Hex grp', '$12 3456 789A', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Hex grp', '$12 3456 789A', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
d.Num.SeparatorHexBin := vdfhsLong;
|
||||
AssertEquals('Hex grp', '$12 3456789A', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Hex grp', '$12 3456789A', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
|
||||
|
||||
// digit count oct/bin
|
||||
Res := GetNumRes(QWord(201), True, 2);
|
||||
d.Num.BaseFormat := vdfBaseOct;
|
||||
AssertEquals('Hex grp', '&311', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Hex grp', '&311', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
|
||||
d.Num.MinDigits[vdfBaseOct] := -1;
|
||||
AssertEquals('Hex grp', '&000311', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Hex grp', '&000311', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
|
||||
d.Num.BaseFormat := vdfBaseBin;
|
||||
AssertEquals('Hex grp', '%11001001', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Hex grp', '%11001001', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
|
||||
d.Num.MinDigits[vdfBaseBin] := 12;
|
||||
AssertEquals('Hex grp', '%000011001001', FWatchResPrinter.PrintWatchValue(Res, d));
|
||||
AssertEquals('Hex grp', '%000011001001', FWatchResPrinter.PrintWatchValue(Res, d, ''));
|
||||
end;
|
||||
|
||||
procedure TTestWatchResPrinter.TestPrintNumberSignFormat;
|
||||
|
@ -1208,7 +1208,7 @@ begin
|
||||
if defSkipValueFormatter in Watch.EvaluateFlags then
|
||||
FWatchPrinter.FormatFlags := [rpfIndent, rpfMultiLine, rpfSkipValueFormatter];
|
||||
FWatchPrinter.OnlyValueFormatter := Watch.DbgValueFormatter;
|
||||
s := FWatchPrinter.PrintWatchValue(d.ResultData, Watch.DisplayFormat);
|
||||
s := FWatchPrinter.PrintWatchValue(d.ResultData, Watch.DisplayFormat, Watch.Expression);
|
||||
InspectMemo.WordWrap := True;
|
||||
InspectMemo.Text := s;
|
||||
exit;
|
||||
@ -1216,7 +1216,7 @@ begin
|
||||
|
||||
// Old style value
|
||||
if (t <> nil) and
|
||||
GlobalValueFormatterSelectorList.FormatValue(t, d.Value, Watch.DisplayFormat, s)
|
||||
GlobalValueFormatterSelectorList.FormatValue(t, d.Value, Watch.DisplayFormat, s, AnsiUpperCase(Watch.Expression), AnsiUpperCase(Watch.Expression))
|
||||
then begin
|
||||
InspectMemo.WordWrap := True;
|
||||
InspectMemo.Text := s;
|
||||
@ -1461,6 +1461,7 @@ var
|
||||
ResData: TWatchResultData;
|
||||
da: TDBGPtr;
|
||||
DispFormat: TWatchDisplayFormat;
|
||||
s: String;
|
||||
begin
|
||||
if AWatchAbleResult = nil then
|
||||
exit(inherited);
|
||||
@ -1509,12 +1510,13 @@ begin
|
||||
FWatchDlg.FWatchPrinter.FormatFlags := [rpfIndent, rpfMultiLine, rpfSkipValueFormatter];
|
||||
FWatchDlg.FWatchPrinter.OnlyValueFormatter := TheWatch.DbgValueFormatter;
|
||||
|
||||
Result := FWatchDlg.FWatchPrinter.PrintWatchValue(ResData, DispFormat);
|
||||
Result := FWatchDlg.FWatchPrinter.PrintWatchValue(ResData, DispFormat, TheWatch.Expression);
|
||||
end
|
||||
else begin
|
||||
s := AnsiUpperCase(TheWatch.Expression);
|
||||
if (AWatchAbleResult.TypeInfo = nil) or
|
||||
not GlobalValueFormatterSelectorList.FormatValue(AWatchAbleResult.TypeInfo,
|
||||
AWatchAbleResult.Value, DispFormat, Result)
|
||||
AWatchAbleResult.Value, DispFormat, Result, s, s)
|
||||
then begin
|
||||
Result := AWatchAbleResult.Value;
|
||||
end;
|
||||
@ -1539,7 +1541,7 @@ procedure TDbgTreeViewWatchValueMgr.UpdateColumnsText(AWatchAble: TObject;
|
||||
var
|
||||
TheWatch: TIdeWatch absolute AWatchAble;
|
||||
ResData: TWatchResultData;
|
||||
WatchValueStr: String;
|
||||
WatchValueStr, s: String;
|
||||
da: TDBGPtr;
|
||||
DispFormat: TWatchDisplayFormat;
|
||||
begin
|
||||
@ -1570,7 +1572,7 @@ begin
|
||||
else
|
||||
FWatchDlg.FWatchPrinter.FormatFlags := [rpfClearMultiLine, rpfPrefixOuterArrayLen];
|
||||
FWatchDlg.FWatchPrinter.OnlyValueFormatter := TheWatch.DbgValueFormatter;
|
||||
WatchValueStr := FWatchDlg.FWatchPrinter.PrintWatchValue(ResData, DispFormat);
|
||||
WatchValueStr := FWatchDlg.FWatchPrinter.PrintWatchValue(ResData, DispFormat, TheWatch.Expression);
|
||||
TreeView.NodeText[AVNode, COL_WATCH_VALUE-1] := WatchValueStr;
|
||||
|
||||
if ResData.HasDataAddress then begin
|
||||
@ -1581,9 +1583,10 @@ begin
|
||||
end
|
||||
end
|
||||
else begin
|
||||
s := AnsiUpperCase(TheWatch.Expression);
|
||||
if (AWatchAbleResult.TypeInfo = nil) or
|
||||
not GlobalValueFormatterSelectorList.FormatValue(AWatchAbleResult.TypeInfo,
|
||||
AWatchAbleResult.Value, DispFormat, WatchValueStr)
|
||||
AWatchAbleResult.Value, DispFormat, WatchValueStr, s, s)
|
||||
then begin
|
||||
WatchValueStr := AWatchAbleResult.Value;
|
||||
if (AWatchAbleResult.TypeInfo <> nil) and
|
||||
|
Loading…
Reference in New Issue
Block a user