* Fix bug ID #0037189, backwards search

git-svn-id: trunk@45629 -
This commit is contained in:
michael 2020-06-09 14:19:47 +00:00
parent fcc4f587ff
commit 8a54e8a773

View File

@ -412,7 +412,7 @@ type
function MatchAtOnePos(APos: PRegExprChar): boolean; {$IFDEF InlineFuncs}inline;{$ENDIF} function MatchAtOnePos(APos: PRegExprChar): boolean; {$IFDEF InlineFuncs}inline;{$ENDIF}
// Exec for stored InputString // Exec for stored InputString
function ExecPrim(AOffset: integer; ATryOnce, ASlowChecks: boolean): boolean; function ExecPrim(AOffset: integer; ATryOnce, ASlowChecks, ABackward: boolean): boolean;
{$IFDEF RegExpPCodeDump} {$IFDEF RegExpPCodeDump}
function DumpOp(op: TREOp): RegExprString; function DumpOp(op: TREOp): RegExprString;
@ -454,12 +454,14 @@ type
// Raises exception if used without preceeding SUCCESSFUL call to // Raises exception if used without preceeding SUCCESSFUL call to
// Exec* (Exec, ExecPos, ExecNext). So You always must use something like // Exec* (Exec, ExecPos, ExecNext). So You always must use something like
// if Exec (InputString) then repeat { proceed results} until not ExecNext; // if Exec (InputString) then repeat { proceed results} until not ExecNext;
function ExecNext: boolean; function ExecNext: boolean; overload;
function ExecNext(ABackward: boolean): boolean; overload;
// find match for InputString starting from AOffset position // find match for InputString starting from AOffset position
// (AOffset=1 - first char of InputString) // (AOffset=1 - first char of InputString)
function ExecPos(AOffset: integer = 1): boolean; overload; function ExecPos(AOffset: integer = 1): boolean; overload;
function ExecPos(AOffset: integer; ATryOnce: boolean): boolean; overload; function ExecPos(AOffset: integer; ATryOnce: boolean): boolean; overload;
function ExecPos(AOffset: integer; ATryOnce, ABackward: boolean): boolean; overload;
// Returns ATemplate with '$&' or '$0' replaced by whole r.e. // Returns ATemplate with '$&' or '$0' replaced by whole r.e.
// occurence and '$1'...'$nn' replaced by subexpression with given index. // occurence and '$1'...'$nn' replaced by subexpression with given index.
@ -4124,7 +4126,7 @@ end; { of function TRegExpr.MatchPrim
function TRegExpr.Exec(const AInputString: RegExprString): boolean; function TRegExpr.Exec(const AInputString: RegExprString): boolean;
begin begin
InputString := AInputString; InputString := AInputString;
Result := ExecPrim(1, False, False); Result := ExecPrim(1, False, False, False);
end; { of function TRegExpr.Exec end; { of function TRegExpr.Exec
-------------------------------------------------------------- } -------------------------------------------------------------- }
@ -4134,27 +4136,33 @@ var
SlowChecks: boolean; SlowChecks: boolean;
begin begin
SlowChecks := Length(fInputString) < fSlowChecksSizeMax; SlowChecks := Length(fInputString) < fSlowChecksSizeMax;
Result := ExecPrim(1, False, SlowChecks); Result := ExecPrim(1, False, SlowChecks, False);
end; { of function TRegExpr.Exec end; { of function TRegExpr.Exec
-------------------------------------------------------------- } -------------------------------------------------------------- }
function TRegExpr.Exec(AOffset: integer): boolean; function TRegExpr.Exec(AOffset: integer): boolean;
begin begin
Result := ExecPrim(AOffset, False, False); Result := ExecPrim(AOffset, False, False, False);
end; { of function TRegExpr.Exec end; { of function TRegExpr.Exec
-------------------------------------------------------------- } -------------------------------------------------------------- }
function TRegExpr.ExecPos(AOffset: integer = 1): boolean; function TRegExpr.ExecPos(AOffset: integer = 1): boolean;
begin begin
Result := ExecPrim(AOffset, False, False); Result := ExecPrim(AOffset, False, False, False);
end; { of function TRegExpr.ExecPos end; { of function TRegExpr.ExecPos
-------------------------------------------------------------- } -------------------------------------------------------------- }
function TRegExpr.ExecPos(AOffset: integer; ATryOnce: boolean): boolean; function TRegExpr.ExecPos(AOffset: integer; ATryOnce: boolean): boolean;
begin begin
Result := ExecPrim(AOffset, ATryOnce, False); Result := ExecPrim(AOffset, ATryOnce, False, False);
end;
function TRegExpr.ExecPos(AOffset: integer; ATryOnce, aBackward: boolean): boolean;
begin
Result := ExecPrim(AOffset, ATryOnce, False, ABackward);
end; end;
@ -4187,7 +4195,8 @@ begin
GrpCount := 0; GrpCount := 0;
end; end;
function TRegExpr.ExecPrim(AOffset: integer; ATryOnce, ASlowChecks: boolean): boolean; function TRegExpr.ExecPrim(AOffset: integer;
ATryOnce, ASlowChecks, ABackward: boolean): boolean;
var var
Ptr: PRegExprChar; Ptr: PRegExprChar;
begin begin
@ -4255,11 +4264,23 @@ begin
end; end;
// Messy cases: unanchored match. // Messy cases: unanchored match.
Dec(Ptr); if ABackward then
Inc(Ptr, 2)
else
Dec(Ptr);
repeat repeat
Inc(Ptr); if ABackward then
if Ptr > fInputEnd then begin
Exit; Dec(Ptr);
if Ptr < fInputStart then
Exit;
end
else
begin
Inc(Ptr);
if Ptr > fInputEnd then
Exit;
end;
{$IFDEF UseFirstCharSet} {$IFDEF UseFirstCharSet}
{$IFDEF UniCode} {$IFDEF UniCode}
@ -4277,7 +4298,13 @@ begin
end; { of function TRegExpr.ExecPrim end; { of function TRegExpr.ExecPrim
-------------------------------------------------------------- } -------------------------------------------------------------- }
function TRegExpr.ExecNext: boolean; function TRegExpr.ExecNext: boolean;
begin
Result:=ExecNext(False);
end;
function TRegExpr.ExecNext(ABackward: boolean): boolean;
var var
PtrBegin, PtrEnd: PRegExprChar; PtrBegin, PtrEnd: PRegExprChar;
Offset: PtrInt; Offset: PtrInt;
@ -4296,8 +4323,9 @@ begin
if PtrBegin = PtrEnd then if PtrBegin = PtrEnd then
Inc(Offset); Inc(Offset);
Result := ExecPrim(Offset, False, False); Result := ExecPrim(Offset, False, False, ABackward);
end; { of function TRegExpr.ExecNext end; { of function TRegExpr.ExecNext
-------------------------------------------------------------- } -------------------------------------------------------------- }
procedure TRegExpr.SetInputString(const AInputString: RegExprString); procedure TRegExpr.SetInputString(const AInputString: RegExprString);