* 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:
marco 2010-12-05 11:10:06 +00:00
parent af39178e06
commit 1c0e482d7d
4 changed files with 92 additions and 5 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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,