andgineer / TRegExpr

Regular expressions (regex), pascal.
https://regex.sorokin.engineer/en/latest/
MIT License
174 stars 63 forks source link

Issues when compiling user4martin branch on Delphi 7 #314

Closed Alexey-T closed 1 year ago

Alexey-T commented 1 year ago

@user4martin

I wait for these fixes in your branch look-around-new

Alexey-T commented 1 year ago

More

Alexey-T commented 1 year ago

Operator is not applicable to operand type for:

scan := AlignToPtr(scan + 1) + SizeOf(TRENextOff);

can we change it to:

scan := AlignToPtr(scan + 1 + SizeOf(TRENextOff));

User4martin commented 1 year ago

PtrInt fix comming.

I can't find the PChar ?

function StrLPos(str1,str2 : PRegExprChar; len1, len2: PtrInt) : PRegExprChar;

It will be the same kind of char, than the rest of the regex.

And the call is also ensuring all params are the correct type (regMustString: RegExprString;)

      if StrLPos(fInputStart, PRegExprChar(regMustString), fInputEnd - fInputStart, length(regMustString)) = nil then
Alexey-T commented 1 year ago

PChar/PWideChar. to fix it, copy StrLComp from FPC to regexpr.pas. adjust types to RegExpr types.

function strlcomp(str1,str2 : pwidechar;l : SizeInt) : SizeInt;
  var
    counter: sizeint;
    c1, c2: widechar;
  begin
    if l = 0 then
      begin
        strlcomp := 0;
        exit;
      end;
    counter:=0;
    repeat
      c1:=str1[counter];
      c2:=str2[counter];
      inc(counter);
   until (c1<>c2) or (counter>=l) or
         (c1=#0) or (c2=#0);
    strlcomp:=ord(c1)-ord(c2);
  end; 
Alexey-T commented 1 year ago

Bug

User4martin commented 1 year ago

Operator is not applicable to operand type for:

It will be RENextOffSz since then it's pointer math. Anyway that part is ok.

However it isn't the same. => It only currently would be the same (by accident)


Currently TRENextOff = PtrInt;

So aligning to pointer firs or last, will lead to the same end result.

But if ever the above changes to TRENextOff = LongInt; (on a platform with 8 byte ptr, and 4 byte longint) then it will break.

Say scan is at 0x...1

But when adding first

Since the align is part of EmitNode, and the data of size(TRENextOff) was therefore added after the AlignToPtr, the first calculation is correct.


I don't know all the Delphi details, but it should have directives on what you can do with pointers.

If not

Alexey-T commented 1 year ago

https://www.freepascal.org/docs-html/prog/progsu112.html

By default, pointer arithmetic is enabled in FPC/OBJFPC modes and disabled in DELPHI mode. The directive $POINTERMATH ON/OFF can be used to toggle pointer arithmetic support

so I cannot solve it - $POINTERMATH is not supported in D7. what to do?

Alexey-T commented 1 year ago

Martin, here are my changes, buggy of course because of Align-changes. please see which lines I must change regarding AlignToPtr. can you change these Aligns on ur side?

and StrLComp types are not adjusted...

diff --git a/src/regexpr.pas b/src/regexpr.pas
index fef6cb5..d04f187 100644
--- a/src/regexpr.pas
+++ b/src/regexpr.pas
@@ -136,6 +136,7 @@ type
     PtrInt = Int64;
     PtrUInt = UInt64;
     {$IFEND}
+    SizeInt = PtrInt;
   {$ENDIF}

   {$IFDEF UnicodeRE}
@@ -1044,6 +1045,26 @@ Begin
 end;

+function strlcomp(str1,str2 : pwidechar;l : SizeInt) : SizeInt;
+  var
+    counter: sizeint;
+    c1, c2: widechar;
+  begin
+    if l = 0 then
+      begin
+        strlcomp := 0;
+        exit;
+      end;
+    counter:=0;
+    repeat
+      c1:=str1[counter];
+      c2:=str2[counter];
+      inc(counter);
+   until (c1<>c2) or (counter>=l) or
+         (c1=#0) or (c2=#0);
+    strlcomp:=ord(c1)-ord(c2);
+  end;
+        
 function StrLPos(str1,str2 : PRegExprChar; len1, len2: SizeInt) : PRegExprChar;
 var
   p : PRegExprChar;
@@ -1235,7 +1256,10 @@ begin
     case APtr[i] of
       '-':
         if not IsOn then
-          Exit(False)
+        begin
+          result:= False;
+          Exit;
+        end
         else
           IsOn := False;
       'I', 'i':
@@ -5413,7 +5437,7 @@ begin
           LookAroundInfoList := @Local.LookAroundInfo;
           fInputCurrentEnd := fInputEnd;

-          scan := AlignToPtr(scan + 1) + SizeOf(TRENextOff);
+          scan := AlignToPtr(scan + 1 + SizeOf(TRENextOff));
           Result := MatchPrim(scan);

           if Local.LookAroundInfo.IsBackTracking then
@@ -5421,11 +5445,11 @@ begin
           LookAroundInfoList := Local.LookAroundInfo.OuterInfo;
           fInputCurrentEnd := Local.LookAroundInfo.savedInputCurrentEnd;

-          next := AlignToPtr(next + 1) + SizeOf(TRENextOff);
+          next := AlignToPtr(next + 1 + SizeOf(TRENextOff));
           if Local.IsNegativeLook then begin
             Result := (next^ = OP_LOOKAROUND_OPTIONAL);
             if Result then
-              next := AlignToPtr(next + 1) + SizeOf(TRENextOff)
+              next := AlignToPtr(next + 1 + SizeOf(TRENextOff))
             else
               Result := (not Local.LookAroundInfo.HasMatchedToEnd);
             if Result then begin
@@ -5436,7 +5460,7 @@ begin
           end
           else
           if (next^ = OP_LOOKAROUND_OPTIONAL) then begin
-            next := AlignToPtr(next + 1) + SizeOf(TRENextOff);
+            next := AlignToPtr(next + 1 + SizeOf(TRENextOff));
             if not Local.LookAroundInfo.HasMatchedToEnd then begin
               regInput := Local.LookAroundInfo.InputPos;
               Result := MatchPrim(next);
@@ -5453,7 +5477,7 @@ begin
       OP_LOOKBEHIND, OP_LOOKBEHIND_NEG:
         begin
           Local.IsNegativeLook := (scan^ = OP_LOOKBEHIND_NEG);
-          scan := AlignToPtr(scan + 1) + SizeOf(TRENextOff);
+          scan := AlignToPtr(scan + 1 + SizeOf(TRENextOff));
           Local.IsGreedy := PReOpLookBehindOptions(scan)^.IsGreedy;

           Local.LookAroundInfo.InputPos := regInput;
@@ -5497,11 +5521,11 @@ begin
           LookAroundInfoList := Local.LookAroundInfo.OuterInfo;
           fInputCurrentEnd := Local.LookAroundInfo.savedInputCurrentEnd;

-          next := AlignToPtr(next + 1) + SizeOf(TRENextOff);
+          next := AlignToPtr(next + 1 + SizeOf(TRENextOff));
           if Local.IsNegativeLook then begin
             Result := (next^ = OP_LOOKAROUND_OPTIONAL);
             if Result then
-              next := AlignToPtr(next + 1) + SizeOf(TRENextOff)
+              next := AlignToPtr(next + 1 + SizeOf(TRENextOff))
             else
               Result := not Local.LookAroundInfo.HasMatchedToEnd;
             if Result then begin
@@ -5512,7 +5536,7 @@ begin
           end
           else
           if (next^ = OP_LOOKAROUND_OPTIONAL) then begin
-            next := AlignToPtr(next + 1) + SizeOf(TRENextOff);
+            next := AlignToPtr(next + 1 + SizeOf(TRENextOff));
             if not Local.LookAroundInfo.HasMatchedToEnd then begin
               regInput := Local.LookAroundInfo.InputPos;
               Result := MatchPrim(next);
@@ -5538,7 +5562,7 @@ begin
             LookAroundInfoList := Local.LookAroundInfoPtr^.OuterInfo;

             if (next^ = OP_LOOKAROUND_OPTIONAL) then
-              next := AlignToPtr(next + 1) + SizeOf(TRENextOff);
+              next := AlignToPtr(next + 1 + SizeOf(TRENextOff));
             Result := MatchPrim(next);
             LookAroundInfoList := Local.LookAroundInfoPtr;
           end;
@@ -5567,7 +5591,7 @@ begin
             LookAroundInfoList := Local.LookAroundInfoPtr^.OuterInfo;

             if (next^ = OP_LOOKAROUND_OPTIONAL) then
-              next := AlignToPtr(next + 1) + SizeOf(TRENextOff);
+              next := AlignToPtr(next + 1 + SizeOf(TRENextOff));
             Result := MatchPrim(next);
             LookAroundInfoList := Local.LookAroundInfoPtr;
           end;
@@ -6625,7 +6649,7 @@ begin
       OP_BACK:
         begin
           // No point to rescan the code again
-          Next := AlignToPtr(scan + 1) + SizeOf(TRENextOff);
+          Next := AlignToPtr(scan + 1 + SizeOf(TRENextOff));
         end;

       OP_OPEN_FIRST .. OP_OPEN_LAST:
User4martin commented 1 year ago

Afaik it isn't PointerMath => PointerMath is the one that is working

SomePWideChar := SomePWideChar + 1 adds 2 to the address, because a WideChar has 2 bytes.

Without PointerMath, you need to add 2, to advance to the next char.

AlignToPtr return Pointer => which does not have a type. Adding to a pointer is the most basic thing... I wonder if Delphi really has an issue, or if it is something else that causes this.

But anyway, I can't test it, I don't have Delphi.


I will change the AlignToPtr Of course the SizeOf(TRENextOff) must be replaced by TRENextOffSz otherwise it adds twice the value.

Or well before, could you test:

 Next := PRegExprChar(AlignToPtr(scan + 1) + SizeOf(TRENextOff));

It probably isn't the add, but the assign.

User4martin commented 1 year ago

Ok I added a PR for the stuff that relates to already merged changes

StrInt / StrLComp

And the rename of TRegEx[pr]Anchor.


I'll go through the rest, but I believe they are all for the upcoming PR.

Alexey-T commented 1 year ago

Please update ur branch 'look-around-new' with last fixes. i will pull it and test on D7.

User4martin commented 1 year ago

Please update ur branch 'look-around-new' with last fixes. i will pull it and test on D7.

on the way.

Did you check if the Next := PRegExprChar(AlignToPtr(scan + 1) + SizeOf(TRENextOff)); works? Or do you rather not have the pointer?

Because Next := AlignToPtr(scan + 1 + SizeOf(TRENextOff)); or actually Next := AlignToPtr(scan + 1 + TRENextOffSz);

Is using AlignToPtr wrong => in that case, do what half of the other code does, and remove it? Next := scan + 1 + TRENextOffSz; ?

User4martin commented 1 year ago

AlignToPtr is still pending. The rest should be updated.

AlignToPtr => I go with whatever option you like. Just wanted the different options on the table/considered, before making the change. (see my last comment please.)

User4martin commented 1 year ago

SHould probably be scan := PRegExprChar(AlignToPtr(scan + 1)) + RENextOffSz;

That way the cast happens before the addition, the addition uses the adjusted value

Alexey-T commented 1 year ago

Yes! I also just found it! this works: temp := PRegExprChar(AlignToPtr(scan + 1)) + SizeOf(TRENextOff);

User4martin commented 1 year ago

good, give me 5 minutes

User4martin commented 1 year ago

OK, pushed

Alexey-T commented 1 year ago

It compiles. Tks.