Browse Source

Improve shortstring Pos() and generic fpc_shortstr_compare().

Rika Ichinose 2 years ago
parent
commit
fca0ace070
2 changed files with 18 additions and 42 deletions
  1. 5 16
      rtl/inc/generic.inc
  2. 13 26
      rtl/inc/sstrings.inc

+ 5 - 16
rtl/inc/generic.inc

@@ -951,8 +951,7 @@ end;
 {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
 function fpc_shortstr_compare(const left,right:shortstring) : longint;[public,alias:'FPC_SHORTSTR_COMPARE']; compilerproc;
 var
-   s1,s2,max,i : byte;
-   d : ObjpasInt;
+   s1,s2,max : byte;
 begin
   s1:=length(left);
   s2:=length(right);
@@ -960,20 +959,10 @@ begin
     max:=s1
   else
     max:=s2;
-  for i:=1 to max do
-    begin
-     d:=byte(left[i])-byte(right[i]);
-     if d>0 then
-       exit(1)
-     else if d<0 then
-       exit(-1);
-    end;
-  if s1>s2 then
-    exit(1)
-  else if s1<s2 then
-    exit(-1)
-  else
-    exit(0);
+  result:=CompareByte(left[1],right[1],max);
+  if result=0 then
+    result:=s1-s2;
+  result:=ord(result>0)-ord(result<0);
 end;
 {$endif ndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
 

+ 13 - 26
rtl/inc/sstrings.inc

@@ -127,25 +127,21 @@ end;
 {$define FPC_HAS_SHORTSTR_POS_SHORTSTR}
 function pos(const substr : shortstring;const s : shortstring; Offset : Sizeint = 1):SizeInt;
 var
-  i,MaxLen : SizeInt;
-  pc : PAnsiChar;
+  i,MaxLen,d : SizeInt;
 begin
   Pos:=0;
   if (Length(SubStr)>0) and (Offset>0) and (Offset<=Length(S)) then
    begin
-     MaxLen:=sizeint(Length(s))-Length(SubStr);
-     i:=Offset-1;
-     pc:=@s[Offset];
+     MaxLen:=sizeint(Length(s))-Length(SubStr)+1;
+     i:=Offset;
      while (i<=MaxLen) do
       begin
-        inc(i);
-        if (SubStr[1]=pc^) and
-           (CompareChar(Substr[1],pc^,Length(SubStr))=0) then
-         begin
-           Pos:=i;
-           exit;
-         end;
-        inc(pc);
+        d:=IndexByte(s[i],MaxLen-i+1,byte(substr[1]));
+        if d<0 then
+          exit;
+        if (CompareByte(Substr[1],s[i+d],Length(SubStr))=0) then
+          exit(i+d);
+        i:=i+d+1;
       end;
    end;
 end;
@@ -157,23 +153,14 @@ end;
 {Faster when looking for a single AnsiChar...}
 function pos(c:ansichar;const s:shortstring; Offset : Sizeint = 1 ):SizeInt;
 var
-  i : SizeInt;
-  pc : PAnsiChar;
+  idx : SizeInt;
 begin
   Pos:=0;
   if (Offset<1) or (Offset>Length(S)) then
     exit;
-  pc:=@s[Offset];
-  for i:=Offset to length(s) do
-   begin
-     if pc^=c then
-      begin
-        pos:=i;
-        exit;
-      end;
-     inc(pc);
-   end;
-  pos:=0;
+  idx:=IndexByte(s[Offset],length(s)-Offset+1,byte(c));
+  if idx>=0 then
+    Pos:=Offset+idx;
 end;
 {$endif FPC_HAS_SHORTSTR_POS_CHAR}