mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-18 05:59:19 +02:00
debugger, gdb: improve break conditions for charvalue='a'
git-svn-id: trunk@48151 -
This commit is contained in:
parent
f44411bd31
commit
c4f6dcb1fa
@ -58,6 +58,7 @@ function ConvertGdbPathAndFile(const AValue: String): String; // fix path, delim
|
|||||||
function ParseGDBString(const AValue: String): String; // remove quotes(') and convert #dd chars: #9'ab'#9'x'
|
function ParseGDBString(const AValue: String): String; // remove quotes(') and convert #dd chars: #9'ab'#9'x'
|
||||||
function GetLeadingAddr(var AValue: String; out AnAddr: TDBGPtr; ARemoveFromValue: Boolean = False): Boolean;
|
function GetLeadingAddr(var AValue: String; out AnAddr: TDBGPtr; ARemoveFromValue: Boolean = False): Boolean;
|
||||||
function UpperCaseSymbols(s: string): string;
|
function UpperCaseSymbols(s: string): string;
|
||||||
|
function ConvertPascalExpression(var AExpression: String): Boolean;
|
||||||
|
|
||||||
procedure SmartWriteln(const s: string);
|
procedure SmartWriteln(const s: string);
|
||||||
|
|
||||||
@ -460,6 +461,170 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function ConvertPascalExpression(var AExpression: String): Boolean;
|
||||||
|
var
|
||||||
|
QuoteChar, R: String;
|
||||||
|
P: PChar;
|
||||||
|
InString, WasString, IsText, ValIsChar: Boolean;
|
||||||
|
n: Integer;
|
||||||
|
ValMode: Char;
|
||||||
|
Value: QWord;
|
||||||
|
|
||||||
|
function AppendValue: Boolean;
|
||||||
|
var
|
||||||
|
S: String;
|
||||||
|
begin
|
||||||
|
if ValMode = #0 then Exit(True);
|
||||||
|
if not (ValMode in ['h', 'd', 'o', 'b']) then Exit(False);
|
||||||
|
|
||||||
|
if ValIsChar
|
||||||
|
then begin
|
||||||
|
if not IsText
|
||||||
|
then begin
|
||||||
|
R := R + '"';
|
||||||
|
IsText := True;
|
||||||
|
end;
|
||||||
|
R := R + '\' + OctStr(Value, 3);
|
||||||
|
ValIsChar := False;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if IsText
|
||||||
|
then begin
|
||||||
|
R := R + '"';
|
||||||
|
IsText := False;
|
||||||
|
end;
|
||||||
|
Str(Value, S);
|
||||||
|
R := R + S;
|
||||||
|
end;
|
||||||
|
Result := True;
|
||||||
|
ValMode := #0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
R := '';
|
||||||
|
Instring := False;
|
||||||
|
WasString := False;
|
||||||
|
IsText := False;
|
||||||
|
QuoteChar := '"';
|
||||||
|
ValIsChar := False;
|
||||||
|
ValMode := #0;
|
||||||
|
Value := 0;
|
||||||
|
|
||||||
|
P := PChar(AExpression);
|
||||||
|
for n := 1 to Length(AExpression) do
|
||||||
|
begin
|
||||||
|
if InString
|
||||||
|
then begin
|
||||||
|
case P^ of
|
||||||
|
'''': begin
|
||||||
|
InString := False;
|
||||||
|
// delay setting terminating ", more characters defined through # may follow
|
||||||
|
WasString := True;
|
||||||
|
end;
|
||||||
|
#0..#31,
|
||||||
|
'\',
|
||||||
|
#128..#255: begin
|
||||||
|
R := R + '\' + OctStr(Ord(P^), 3);
|
||||||
|
end;
|
||||||
|
else begin
|
||||||
|
if p^ = QuoteChar then
|
||||||
|
R := R + '\' + OctStr(Ord(P^), 3)
|
||||||
|
else
|
||||||
|
R := R + P^;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Inc(P);
|
||||||
|
Continue;
|
||||||
|
end;
|
||||||
|
|
||||||
|
case P^ of
|
||||||
|
'''': begin
|
||||||
|
if WasString
|
||||||
|
then begin
|
||||||
|
R := R + '\' + OctStr(Ord(''''), 3)
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if not AppendValue then Exit(False);
|
||||||
|
if not IsText
|
||||||
|
then begin
|
||||||
|
QuoteChar := '"';
|
||||||
|
// single CHAR ?
|
||||||
|
if ( ((p+1)^ <> '''') and ((p+2)^ = '''') and not((p+3)^ in ['#', '''']) ) or
|
||||||
|
( ((p+1)^ = '''') and ((p+2)^ = '''') and ((p+3)^ = '''') and not((p+4)^ in ['#', '''']) )
|
||||||
|
then
|
||||||
|
QuoteChar := '''';
|
||||||
|
R := R + QuoteChar;
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
IsText := True;
|
||||||
|
InString := True;
|
||||||
|
end;
|
||||||
|
'#': begin
|
||||||
|
if not AppendValue then Exit(False);
|
||||||
|
Value := 0;
|
||||||
|
ValMode := 'D';
|
||||||
|
ValIsChar := True;
|
||||||
|
end;
|
||||||
|
'$', '&', '%': begin
|
||||||
|
if not (ValMode in [#0, 'D']) then Exit(False);
|
||||||
|
ValMode := P^;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
case ValMode of
|
||||||
|
'D', 'd': begin
|
||||||
|
case P^ of
|
||||||
|
'0'..'9': Value := Value * 10 + Ord(P^) - Ord('0');
|
||||||
|
else
|
||||||
|
Exit(False);
|
||||||
|
end;
|
||||||
|
ValMode := 'd';
|
||||||
|
end;
|
||||||
|
'$', 'h': begin
|
||||||
|
case P^ of
|
||||||
|
'0'..'9': Value := Value * 16 + Ord(P^) - Ord('0');
|
||||||
|
'a'..'f': Value := Value * 16 + Ord(P^) - Ord('a');
|
||||||
|
'A'..'F': Value := Value * 16 + Ord(P^) - Ord('A');
|
||||||
|
else
|
||||||
|
Exit(False);
|
||||||
|
end;
|
||||||
|
ValMode := 'h';
|
||||||
|
end;
|
||||||
|
'&', 'o': begin
|
||||||
|
case P^ of
|
||||||
|
'0'..'7': Value := Value * 8 + Ord(P^) - Ord('0');
|
||||||
|
else
|
||||||
|
Exit(False);
|
||||||
|
end;
|
||||||
|
ValMode := 'o';
|
||||||
|
end;
|
||||||
|
'%', 'b': begin
|
||||||
|
case P^ of
|
||||||
|
'0': Value := Value shl 1;
|
||||||
|
'1': Value := Value shl 1 or 1;
|
||||||
|
else
|
||||||
|
Exit(False);
|
||||||
|
end;
|
||||||
|
ValMode := 'b';
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
if IsText
|
||||||
|
then begin
|
||||||
|
R := R + QuoteChar;
|
||||||
|
IsText := False;
|
||||||
|
end;
|
||||||
|
R := R + P^;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
WasString := False;
|
||||||
|
Inc(p);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if not AppendValue then Exit(False);
|
||||||
|
if IsText then R := R + QuoteChar;
|
||||||
|
AExpression := R;
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
function DeleteEscapeChars(const AValue: String; const AEscapeChar: Char): String;
|
function DeleteEscapeChars(const AValue: String; const AEscapeChar: Char): String;
|
||||||
var
|
var
|
||||||
cnt, len: Integer;
|
cnt, len: Integer;
|
||||||
|
@ -770,7 +770,6 @@ type
|
|||||||
procedure LockRelease;
|
procedure LockRelease;
|
||||||
procedure UnlockRelease;
|
procedure UnlockRelease;
|
||||||
|
|
||||||
function ConvertPascalExpression(var AExpression: String): Boolean;
|
|
||||||
// ---
|
// ---
|
||||||
procedure ClearSourceInfo;
|
procedure ClearSourceInfo;
|
||||||
function FindBreakpoint(const ABreakpoint: Integer): TDBGBreakPoint;
|
function FindBreakpoint(const ABreakpoint: Integer): TDBGBreakPoint;
|
||||||
@ -8968,157 +8967,6 @@ begin
|
|||||||
FSourceNames.Clear;
|
FSourceNames.Clear;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TGDBMIDebugger.ConvertPascalExpression(var AExpression: String): Boolean;
|
|
||||||
var
|
|
||||||
R: String;
|
|
||||||
P: PChar;
|
|
||||||
InString, WasString, IsText, ValIsChar: Boolean;
|
|
||||||
n: Integer;
|
|
||||||
ValMode: Char;
|
|
||||||
Value: QWord;
|
|
||||||
|
|
||||||
function AppendValue: Boolean;
|
|
||||||
var
|
|
||||||
S: String;
|
|
||||||
begin
|
|
||||||
if ValMode = #0 then Exit(True);
|
|
||||||
if not (ValMode in ['h', 'd', 'o', 'b']) then Exit(False);
|
|
||||||
|
|
||||||
if ValIsChar
|
|
||||||
then begin
|
|
||||||
if not IsText
|
|
||||||
then begin
|
|
||||||
R := R + '"';
|
|
||||||
IsText := True;
|
|
||||||
end;
|
|
||||||
R := R + '\' + OctStr(Value, 3);
|
|
||||||
ValIsChar := False;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
if IsText
|
|
||||||
then begin
|
|
||||||
R := R + '"';
|
|
||||||
IsText := False;
|
|
||||||
end;
|
|
||||||
Str(Value, S);
|
|
||||||
R := R + S;
|
|
||||||
end;
|
|
||||||
Result := True;
|
|
||||||
ValMode := #0;
|
|
||||||
end;
|
|
||||||
|
|
||||||
begin
|
|
||||||
R := '';
|
|
||||||
Instring := False;
|
|
||||||
WasString := False;
|
|
||||||
IsText := False;
|
|
||||||
ValIsChar := False;
|
|
||||||
ValMode := #0;
|
|
||||||
Value := 0;
|
|
||||||
|
|
||||||
P := PChar(AExpression);
|
|
||||||
for n := 1 to Length(AExpression) do
|
|
||||||
begin
|
|
||||||
if InString
|
|
||||||
then begin
|
|
||||||
case P^ of
|
|
||||||
'''': begin
|
|
||||||
InString := False;
|
|
||||||
// delay setting terminating ", more characters defined through # may follow
|
|
||||||
WasString := True;
|
|
||||||
end;
|
|
||||||
#0..#31,
|
|
||||||
'"', '\',
|
|
||||||
#128..#255: begin
|
|
||||||
R := R + '\' + OctStr(Ord(P^), 3);
|
|
||||||
end;
|
|
||||||
else
|
|
||||||
R := R + P^;
|
|
||||||
end;
|
|
||||||
Inc(P);
|
|
||||||
Continue;
|
|
||||||
end;
|
|
||||||
|
|
||||||
case P^ of
|
|
||||||
'''': begin
|
|
||||||
if WasString
|
|
||||||
then begin
|
|
||||||
R := R + '\' + OctStr(Ord(''''), 3)
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
if not AppendValue then Exit(False);
|
|
||||||
if not IsText
|
|
||||||
then R := R + '"';
|
|
||||||
end;
|
|
||||||
IsText := True;
|
|
||||||
InString := True;
|
|
||||||
end;
|
|
||||||
'#': begin
|
|
||||||
if not AppendValue then Exit(False);
|
|
||||||
Value := 0;
|
|
||||||
ValMode := 'D';
|
|
||||||
ValIsChar := True;
|
|
||||||
end;
|
|
||||||
'$', '&', '%': begin
|
|
||||||
if not (ValMode in [#0, 'D']) then Exit(False);
|
|
||||||
ValMode := P^;
|
|
||||||
end;
|
|
||||||
else
|
|
||||||
case ValMode of
|
|
||||||
'D', 'd': begin
|
|
||||||
case P^ of
|
|
||||||
'0'..'9': Value := Value * 10 + Ord(P^) - Ord('0');
|
|
||||||
else
|
|
||||||
Exit(False);
|
|
||||||
end;
|
|
||||||
ValMode := 'd';
|
|
||||||
end;
|
|
||||||
'$', 'h': begin
|
|
||||||
case P^ of
|
|
||||||
'0'..'9': Value := Value * 16 + Ord(P^) - Ord('0');
|
|
||||||
'a'..'f': Value := Value * 16 + Ord(P^) - Ord('a');
|
|
||||||
'A'..'F': Value := Value * 16 + Ord(P^) - Ord('A');
|
|
||||||
else
|
|
||||||
Exit(False);
|
|
||||||
end;
|
|
||||||
ValMode := 'h';
|
|
||||||
end;
|
|
||||||
'&', 'o': begin
|
|
||||||
case P^ of
|
|
||||||
'0'..'7': Value := Value * 8 + Ord(P^) - Ord('0');
|
|
||||||
else
|
|
||||||
Exit(False);
|
|
||||||
end;
|
|
||||||
ValMode := 'o';
|
|
||||||
end;
|
|
||||||
'%', 'b': begin
|
|
||||||
case P^ of
|
|
||||||
'0': Value := Value shl 1;
|
|
||||||
'1': Value := Value shl 1 or 1;
|
|
||||||
else
|
|
||||||
Exit(False);
|
|
||||||
end;
|
|
||||||
ValMode := 'b';
|
|
||||||
end;
|
|
||||||
else
|
|
||||||
if IsText
|
|
||||||
then begin
|
|
||||||
R := R + '"';
|
|
||||||
IsText := False;
|
|
||||||
end;
|
|
||||||
R := R + P^;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
WasString := False;
|
|
||||||
Inc(p);
|
|
||||||
end;
|
|
||||||
|
|
||||||
if not AppendValue then Exit(False);
|
|
||||||
if IsText then R := R + '"';
|
|
||||||
AExpression := R;
|
|
||||||
Result := True;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TGDBMIDebugger.StartDebugging(AContinueCommand: TGDBMIExecCommandType): Boolean;
|
function TGDBMIDebugger.StartDebugging(AContinueCommand: TGDBMIExecCommandType): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := StartDebugging(TGDBMIDebuggerCommandExecute.Create(Self, AContinueCommand));
|
Result := StartDebugging(TGDBMIDebuggerCommandExecute.Create(Self, AContinueCommand));
|
||||||
@ -9587,7 +9435,7 @@ var
|
|||||||
S: String;
|
S: String;
|
||||||
begin
|
begin
|
||||||
S := Expression;
|
S := Expression;
|
||||||
if TGDBMIDebugger(Debugger).ConvertPascalExpression(S)
|
if ConvertPascalExpression(S)
|
||||||
then FParsedExpression := S
|
then FParsedExpression := S
|
||||||
else FParsedExpression := Expression;
|
else FParsedExpression := Expression;
|
||||||
if (FBreakID = 0) and Enabled and
|
if (FBreakID = 0) and Enabled and
|
||||||
|
@ -18,6 +18,7 @@ type
|
|||||||
procedure TestPTypeParser;
|
procedure TestPTypeParser;
|
||||||
procedure TestExpressionBreaker;
|
procedure TestExpressionBreaker;
|
||||||
procedure TestUnEscape;
|
procedure TestUnEscape;
|
||||||
|
procedure TestConvertPascalExpression;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -829,6 +830,23 @@ begin
|
|||||||
AssertEquals('4:a\102\tc\\d (no oct)', 'a\102 c\d', UnEscapeBackslashed('a\102\tc\\d', [uefTab],4));
|
AssertEquals('4:a\102\tc\\d (no oct)', 'a\102 c\d', UnEscapeBackslashed('a\102\tc\\d', [uefTab],4));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TTestGdbType.TestConvertPascalExpression;
|
||||||
|
procedure AssertEqualsConv(n, s1, s2: string);
|
||||||
|
begin
|
||||||
|
AssertTrue(n, ConvertPascalExpression(s2));
|
||||||
|
AssertEquals(n, s1, s2);
|
||||||
|
end;
|
||||||
|
begin
|
||||||
|
AssertEqualsConv('', 'a=1', 'a=1');
|
||||||
|
AssertEqualsConv('', 'a="11"', 'a=''11''');
|
||||||
|
AssertEqualsConv('', 'a="1\0471"', 'a=''1''''1''');
|
||||||
|
AssertEqualsConv('', 'a="11"', 'a="11"');
|
||||||
|
AssertEqualsConv('', 'a="11\061"', 'a=''11''#49');
|
||||||
|
AssertEqualsConv('', 'a="1\061"', 'a=''1''#49');
|
||||||
|
|
||||||
|
AssertEqualsConv('', 'a=''1''', 'a=''1''');
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
|
Loading…
Reference in New Issue
Block a user