mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-19 23:14:02 +02:00
* patch for regex. Fixes exception in rcclear, some casing issues and matching of \w. Also a fix for currentpos in the old version. Mantis 15466
git-svn-id: trunk@16506 -
This commit is contained in:
parent
af39178e06
commit
1c0e482d7d
@ -24,15 +24,49 @@ var
|
|||||||
begin
|
begin
|
||||||
writeln('*** Testing unit regexpr ***');
|
writeln('*** Testing unit regexpr ***');
|
||||||
|
|
||||||
|
{ runtime error test }
|
||||||
|
initok:=GenerateRegExprEngine('[o]{1,2}',[],r);
|
||||||
|
if not initok then
|
||||||
|
do_error(1);
|
||||||
|
if not(RegExprPos(r,'book',index,len)) or
|
||||||
|
(index<>1) or (len<>2) then
|
||||||
|
do_error(1);
|
||||||
|
// if it has bug, error An unhandled exception when r.Free
|
||||||
|
DestroyregExprEngine(r); // bug:Test for rcClear
|
||||||
|
|
||||||
writeln('*** Searching tests ***');
|
writeln('*** Searching tests ***');
|
||||||
{ basic tests }
|
{ basic tests }
|
||||||
|
|
||||||
initok:=GenerateRegExprEngine('.*',[],r);
|
initok:=GenerateRegExprEngine('.*',[],r);
|
||||||
if not initok then
|
if not initok then
|
||||||
do_error(90);
|
do_error(50);
|
||||||
if not(RegExprPos(r,'CXXXX',index,len)) or
|
if not(RegExprPos(r,'CXXXX',index,len)) or
|
||||||
(index<>0) or (len<>5) then
|
(index<>0) or (len<>5) then
|
||||||
do_error(91);
|
do_error(51);
|
||||||
|
DestroyregExprEngine(r);
|
||||||
|
|
||||||
|
initok:=GenerateRegExprEngine('\t\t',[],r);
|
||||||
|
if not initok then
|
||||||
|
do_error(52);
|
||||||
|
if not(RegExprPos(r,'a'+#9+#9+'b'+'\t\t',index,len)) or
|
||||||
|
(index<>1) or (len<>2) then
|
||||||
|
do_error(52);
|
||||||
|
DestroyregExprEngine(r);
|
||||||
|
|
||||||
|
initok:=GenerateRegExprEngine('\t',[],r);
|
||||||
|
if not initok then
|
||||||
|
do_error(53);
|
||||||
|
if not(RegExprPos(r,'a'+#9+#9+'b'+'\t\t',index,len)) or
|
||||||
|
(index<>1) or (len<>1) then
|
||||||
|
do_error(53);
|
||||||
|
DestroyregExprEngine(r);
|
||||||
|
|
||||||
|
initok:=GenerateRegExprEngine('\w',[],r);
|
||||||
|
if not initok then
|
||||||
|
do_error(54);
|
||||||
|
if not(RegExprPos(r,'- abc \w',index,len)) or
|
||||||
|
(index<>2) or (len<>1) then
|
||||||
|
do_error(54);
|
||||||
DestroyregExprEngine(r);
|
DestroyregExprEngine(r);
|
||||||
|
|
||||||
{ java package name }
|
{ java package name }
|
||||||
@ -364,6 +398,14 @@ begin
|
|||||||
do_error(718);
|
do_error(718);
|
||||||
DestroyregExprEngine(r);
|
DestroyregExprEngine(r);
|
||||||
|
|
||||||
|
initok:=GenerateRegExprEngine('o{2}',[],r);
|
||||||
|
if not initok then
|
||||||
|
do_error(719);
|
||||||
|
if not(RegExprPos(r,'book',index,len)) or
|
||||||
|
(index<>1) or (len<>2) then
|
||||||
|
do_error(719);
|
||||||
|
DestroyregExprEngine(r);
|
||||||
|
|
||||||
(* {n,m} tests *)
|
(* {n,m} tests *)
|
||||||
initok:=GenerateRegExprEngine('Cat(AZ){1,3}',[],r);
|
initok:=GenerateRegExprEngine('Cat(AZ){1,3}',[],r);
|
||||||
if not initok then
|
if not initok then
|
||||||
@ -412,6 +454,14 @@ begin
|
|||||||
do_error(729);
|
do_error(729);
|
||||||
DestroyregExprEngine(r);
|
DestroyregExprEngine(r);
|
||||||
|
|
||||||
|
initok:=GenerateRegExprEngine('o{2,2}',[],r);
|
||||||
|
if not initok then
|
||||||
|
do_error(730);
|
||||||
|
if not(RegExprPos(r,'book',index,len)) or
|
||||||
|
(index<>1) or (len<>2) then
|
||||||
|
do_error(730);
|
||||||
|
DestroyregExprEngine(r);
|
||||||
|
|
||||||
|
|
||||||
{ ()* tests }
|
{ ()* tests }
|
||||||
initok:=GenerateRegExprEngine('(AZ)*',[],r);
|
initok:=GenerateRegExprEngine('(AZ)*',[],r);
|
||||||
|
@ -564,7 +564,7 @@ unit regexpr;
|
|||||||
begin
|
begin
|
||||||
if not parseOccurences(currentPos,minOccurs,maxOccurs) then
|
if not parseOccurences(currentPos,minOccurs,maxOccurs) then
|
||||||
exit;
|
exit;
|
||||||
inc(currentpos);
|
// currentpos is increased by parseOccurences
|
||||||
new(hp3);
|
new(hp3);
|
||||||
doregister(hp3);
|
doregister(hp3);
|
||||||
hp3^.typ:=ret_pattern;
|
hp3^.typ:=ret_pattern;
|
||||||
|
@ -452,7 +452,7 @@ end;
|
|||||||
{--------}
|
{--------}
|
||||||
procedure TRegexEngine.rcClear;
|
procedure TRegexEngine.rcClear;
|
||||||
var
|
var
|
||||||
i : integer;
|
i, j : integer;
|
||||||
begin
|
begin
|
||||||
{free all items in the state transition table}
|
{free all items in the state transition table}
|
||||||
for i := 0 to FStateCount-1 do begin
|
for i := 0 to FStateCount-1 do begin
|
||||||
@ -460,8 +460,14 @@ begin
|
|||||||
if (sdMatchType = mtClass) or
|
if (sdMatchType = mtClass) or
|
||||||
(sdMatchType = mtNegClass) then
|
(sdMatchType = mtNegClass) then
|
||||||
if (sdClass <> nil) then
|
if (sdClass <> nil) then
|
||||||
|
begin
|
||||||
|
for j := i+1 to FStateCount-1 do
|
||||||
|
if (FStateTable[j].sdClass = sdClass) then
|
||||||
|
FStateTable[j].sdClass := nil;
|
||||||
FreeMem(sdClass, sizeof(TCharSet));
|
FreeMem(sdClass, sizeof(TCharSet));
|
||||||
end;
|
end;
|
||||||
|
FillChar(FStateTable[i],SizeOf(FStateTable[i]),#0);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
{clear the state transition table}
|
{clear the state transition table}
|
||||||
FStateCount:=0;
|
FStateCount:=0;
|
||||||
@ -734,6 +740,25 @@ begin
|
|||||||
Result := rcAddState(mtAnyChar, #0, nil,
|
Result := rcAddState(mtAnyChar, #0, nil,
|
||||||
NewFinalState, UnusedState);
|
NewFinalState, UnusedState);
|
||||||
end;
|
end;
|
||||||
|
'\' :
|
||||||
|
begin
|
||||||
|
case (FPosn+1)^ of
|
||||||
|
'd','D','s','S','w','W':
|
||||||
|
begin
|
||||||
|
New(CharClass);
|
||||||
|
CharClass^ := [];
|
||||||
|
if not rcParseCharRange(CharClass) then begin
|
||||||
|
Dispose(CharClass);
|
||||||
|
Result := ErrorState;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
Result := rcAddState(mtClass, #0, CharClass,
|
||||||
|
NewFinalState, UnusedState);
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
Result := rcParseChar;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
else
|
else
|
||||||
{otherwise parse a single character}
|
{otherwise parse a single character}
|
||||||
Result := rcParseChar;
|
Result := rcParseChar;
|
||||||
@ -791,6 +816,8 @@ begin
|
|||||||
begin
|
begin
|
||||||
inc(FPosn);
|
inc(FPosn);
|
||||||
ch := rcReturnEscapeChar;
|
ch := rcReturnEscapeChar;
|
||||||
|
if (FRegexType <> rtRegEx) then
|
||||||
|
FRegexType := rtRegEx;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
ch :=FPosn^;
|
ch :=FPosn^;
|
||||||
@ -1060,6 +1087,9 @@ begin
|
|||||||
if m = -1 then
|
if m = -1 then
|
||||||
rcAddState(mtNone, #0, nil, NewFinalState, TempEndStateAtom);
|
rcAddState(mtNone, #0, nil, NewFinalState, TempEndStateAtom);
|
||||||
|
|
||||||
|
if FRegexType <> rtRegEx then
|
||||||
|
FRegexType := rtRegEx;
|
||||||
|
|
||||||
Result := StartStateAtom;
|
Result := StartStateAtom;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -71,7 +71,9 @@ end;
|
|||||||
|
|
||||||
procedure DestroyRegExprEngine(var regexpr: TRegExprEngine);
|
procedure DestroyRegExprEngine(var regexpr: TRegExprEngine);
|
||||||
begin
|
begin
|
||||||
|
if regexpr <> nil then
|
||||||
regexpr.Free;
|
regexpr.Free;
|
||||||
|
regexpr := nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function RegExprPos(RegExprEngine: TRegExprEngine; p: pchar; var index,
|
function RegExprPos(RegExprEngine: TRegExprEngine; p: pchar; var index,
|
||||||
@ -81,6 +83,11 @@ begin
|
|||||||
Result := RegExprEngine.MatchString(p,index,len);
|
Result := RegExprEngine.MatchString(p,index,len);
|
||||||
Len := Len - index;
|
Len := Len - index;
|
||||||
Dec(Index);
|
Dec(Index);
|
||||||
|
if not Result then
|
||||||
|
begin
|
||||||
|
index := -1;
|
||||||
|
len := 0;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function RegExprReplaceAll(RegExprEngine: TRegExprEngine; const src,
|
function RegExprReplaceAll(RegExprEngine: TRegExprEngine; const src,
|
||||||
|
Loading…
Reference in New Issue
Block a user