View Issue Details

IDProjectCategoryView StatusLast Update
0028725FPCRTLpublic2015-11-26 23:10
ReporterAlexey Tor.Assigned ToMichael Van Canneyt 
PrioritynormalSeverityminorReproducibilityN/A
Status resolvedResolutionfixed 
Product Version3.0.0Product Build 
Target Version4.0.0Fixed in Version3.1.1 
Summary0028725: Req: add PosEx() for UnicodeString
DescriptionI make proj with Unicodestring usage. Now i need to do

  //PosEx don't supp Unicodestring, Pos does
  N:= Pos(ch, Copy(SText, N+1, MaxInt));

to find what PosEx finds. It's no good, please, add posEx for Unicodestring?
Tagspatch
Fixed in Revision
FPCOldBugId
FPCTarget
Attached Files
  • strutils.diff (2,558 bytes)
    Index: packages/rtl-objpas/src/inc/strutils.pp
    ===================================================================
    --- packages/rtl-objpas/src/inc/strutils.pp	(revision 31843)
    +++ packages/rtl-objpas/src/inc/strutils.pp	(working copy)
    @@ -94,6 +94,9 @@
     Function PosEx(const SubStr, S: string; Offset: Cardinal): Integer;
     Function PosEx(const SubStr, S: string): Integer;inline; // Offset: Cardinal = 1
     Function PosEx(c:char; const S: string; Offset: Cardinal): Integer;
    +Function PosEx(const SubStr, S: UnicodeString; Offset: Cardinal): Integer;
    +Function PosEx(c: WideChar; const S: UnicodeString; Offset: Cardinal): Integer;
    +Function PosEx(const SubStr, S: UnicodeString): Integer;inline; // Offset: Cardinal = 1
     function StringsReplace(const S: string; OldPattern, NewPattern: array of string;  Flags: TReplaceFlags): string;
     
     { ---------------------------------------------------------------------
    @@ -697,6 +700,56 @@
       posex:=posex(substr,s,1);
     end;
     
    +Function PosEx(const SubStr, S: UnicodeString; Offset: Cardinal): Integer;
    +var
    +  i,MaxLen, SubLen : SizeInt;
    +  SubFirst: WideChar;
    +  pc : pwidechar;
    +begin
    +  PosEx:=0;
    +  SubLen := Length(SubStr);
    +  if (SubLen > 0) and (Offset > 0) and (Offset <= Cardinal(Length(S))) then
    +   begin
    +    MaxLen := Length(S)- SubLen;
    +    SubFirst := SubStr[1];
    +    i := indexword(S[Offset],Length(S) - Offset + 1, Word(SubFirst));
    +    while (i >= 0) and ((i + sizeint(Offset) - 1) <= MaxLen) do
    +    begin
    +      pc := @S[i+SizeInt(Offset)];
    +      //we know now that pc^ = SubFirst, because indexbyte returned a value > -1
    +      if (CompareWord(Substr[1],pc^,SubLen) = 0) then
    +      begin
    +        PosEx := i + SizeInt(Offset);
    +        Exit;
    +      end;
    +      //point Offset to next char in S
    +      Offset := sizeuint(i) + Offset + 1;
    +      i := indexword(S[Offset],Length(S) - Offset + 1, Word(SubFirst));
    +    end;
    +  end;
    +end;
    +
    +Function PosEx(c: WideChar; const S: UnicodeString; Offset: Cardinal): Integer;
    +var
    +  Len : longint;
    +  p: SizeInt;
    +begin
    +  Len := length(S);
    +  if (Offset < 1) or (Offset > SizeUInt(Length(S))) then exit(0);
    +  Len := length(S);
    +  p := indexword(S[Offset],Len-offset+1,Word(c));
    +  if (p < 0) then
    +    PosEx := 0
    +  else
    +    PosEx := p + sizeint(Offset);
    +end;
    +
    +Function PosEx(const SubStr, S: UnicodeString): Integer;inline; // Offset: Cardinal = 1
    +begin
    +  PosEx:=PosEx(SubStr,S,1);
    +end;
    +
    +
     function StringsReplace(const S: string; OldPattern, NewPattern: array of string;  Flags: TReplaceFlags): string;
     
     var pc,pcc,lastpc : pchar;
    
    strutils.diff (2,558 bytes)

Activities

Bart Broersma

2015-09-25 17:41

reporter   ~0086074

Is this OK?

Function PosEx(const SubStr, S: UnicodeString; Offset: Cardinal): Integer;
var
  i,MaxLen, SubLen : SizeInt;
  SubFirst: WideChar;
  pc : pwidechar;
begin
  PosEx:=0;
  SubLen := Length(SubStr);
  if (SubLen > 0) and (Offset > 0) and (Offset <= Cardinal(Length(S))) then
   begin
    MaxLen := Length(S)- SubLen;
    SubFirst := SubStr[1];
    i := indexword(S[Offset],Length(S) - Offset + 1, Word(SubFirst));
    while (i >= 0) and ((i + sizeint(Offset) - 1) <= MaxLen) do
    begin
      pc := @S[i+SizeInt(Offset)];
      //we know now that pc^ = SubFirst, because indexbyte returned a value > -1
      if (CompareWord(Substr[1],pc^,SubLen) = 0) then
      begin
        PosEx := i + SizeInt(Offset);
        Exit;
      end;
      //point Offset to next char in S
      Offset := sizeuint(i) + Offset + 1;
      i := indexword(S[Offset],Length(S) - Offset + 1, Word(SubFirst));
    end;
  end;
end;

Function PosEx(c: WideChar; const S: UnicodeString; Offset: Cardinal): Integer;
var
  Len : longint;
  p: SizeInt;
begin
  Len := length(S);
  if (Offset < 1) or (Offset > SizeUInt(Length(S))) then exit(0);
  Len := length(S);
  p := indexword(S[Offset],Len-offset+1,Word(c));
  if (p < 0) then
    PosEx := 0
  else
    PosEx := p + sizeint(Offset);
end;

Function PosEx(const SubStr, S: UnicodeString): Integer;inline; // Offset: Cardinal = 1
begin
  PosEx:=PosEx(SubStr,S,1);
end;

Alexey Tor.

2015-09-25 19:37

reporter   ~0086079

Bart:I don't see why u have 1) for unicodestring 2)for widechar-- 2 is case of 1

Alexey Tor.

2015-09-25 20:30

reporter   ~0086081

No, not ok. Ok is first find Pos in cutted part, then if found, add to it FromPos

Bart Broersma

2015-09-25 22:22

reporter   ~0086083

Last edited: 2015-09-25 22:24

View 2 revisions

Basically these are overloaded versions of the PosEx() functions in StrUtils unit, just using UnicodeString and WideChar instead of AnsiString and AnsiChar.

It would make no sense to NOT also have the third PosEx() (the one without Offset), because that ne is defined for ansistring as well.

Tested with following code:

procedure TestPosEx;
var
  US, Sub: UnicodeString;
  WC: WideChar;
  P: Integer;
begin
  US := '1234567äëïäëïabcabc';
  Sub := 'äëï';
  WC := 'ä';
  P := PosEx(Sub, US, 7);
  writeln('P = ',P,' Expected: 8');
  P := PosEx(Sub, US, 9);
  writeln('P = ',P,' Expected: 11');

  P := PosEx(WC, US, 7);
  writeln('P = ',P,' Expected: 8');
  P := PosEx(WC, US, 9);
  writeln('P = ',P,' Expected: 11');
end;

If I understand you correctly you want a PosEx with a totally different signature?

Alexey Tor.

2015-09-25 23:52

reporter   ~0086087

I wanted posex for Unicodestring instead of string.So it exists.Solved

Bart Broersma

2015-09-27 00:09

reporter   ~0086098

> So it exists.
Where?

Alexey Tor.

2015-09-27 02:54

reporter   ~0086099

You tell that StrUtils has posex for Unicodestring. it is what I wanted. so solved

Bart Broersma

2015-09-27 11:24

reporter   ~0086101

No I did not. I just wrote overloaded functions that could be added to StrUtils unit.
Mind you I was too lazy to check if trunk didn't already have them. 3.0.0rc does not.

Alexey Tor.

2015-09-27 11:43

reporter   ~0086104

Last edited: 2015-09-27 11:43

View 2 revisions

Then StrUtils needs these funcs, if not yet

Bart Broersma

2015-09-27 13:53

reporter  

strutils.diff (2,558 bytes)
Index: packages/rtl-objpas/src/inc/strutils.pp
===================================================================
--- packages/rtl-objpas/src/inc/strutils.pp	(revision 31843)
+++ packages/rtl-objpas/src/inc/strutils.pp	(working copy)
@@ -94,6 +94,9 @@
 Function PosEx(const SubStr, S: string; Offset: Cardinal): Integer;
 Function PosEx(const SubStr, S: string): Integer;inline; // Offset: Cardinal = 1
 Function PosEx(c:char; const S: string; Offset: Cardinal): Integer;
+Function PosEx(const SubStr, S: UnicodeString; Offset: Cardinal): Integer;
+Function PosEx(c: WideChar; const S: UnicodeString; Offset: Cardinal): Integer;
+Function PosEx(const SubStr, S: UnicodeString): Integer;inline; // Offset: Cardinal = 1
 function StringsReplace(const S: string; OldPattern, NewPattern: array of string;  Flags: TReplaceFlags): string;
 
 { ---------------------------------------------------------------------
@@ -697,6 +700,56 @@
   posex:=posex(substr,s,1);
 end;
 
+Function PosEx(const SubStr, S: UnicodeString; Offset: Cardinal): Integer;
+var
+  i,MaxLen, SubLen : SizeInt;
+  SubFirst: WideChar;
+  pc : pwidechar;
+begin
+  PosEx:=0;
+  SubLen := Length(SubStr);
+  if (SubLen > 0) and (Offset > 0) and (Offset <= Cardinal(Length(S))) then
+   begin
+    MaxLen := Length(S)- SubLen;
+    SubFirst := SubStr[1];
+    i := indexword(S[Offset],Length(S) - Offset + 1, Word(SubFirst));
+    while (i >= 0) and ((i + sizeint(Offset) - 1) <= MaxLen) do
+    begin
+      pc := @S[i+SizeInt(Offset)];
+      //we know now that pc^ = SubFirst, because indexbyte returned a value > -1
+      if (CompareWord(Substr[1],pc^,SubLen) = 0) then
+      begin
+        PosEx := i + SizeInt(Offset);
+        Exit;
+      end;
+      //point Offset to next char in S
+      Offset := sizeuint(i) + Offset + 1;
+      i := indexword(S[Offset],Length(S) - Offset + 1, Word(SubFirst));
+    end;
+  end;
+end;
+
+Function PosEx(c: WideChar; const S: UnicodeString; Offset: Cardinal): Integer;
+var
+  Len : longint;
+  p: SizeInt;
+begin
+  Len := length(S);
+  if (Offset < 1) or (Offset > SizeUInt(Length(S))) then exit(0);
+  Len := length(S);
+  p := indexword(S[Offset],Len-offset+1,Word(c));
+  if (p < 0) then
+    PosEx := 0
+  else
+    PosEx := p + sizeint(Offset);
+end;
+
+Function PosEx(const SubStr, S: UnicodeString): Integer;inline; // Offset: Cardinal = 1
+begin
+  PosEx:=PosEx(SubStr,S,1);
+end;
+
+
 function StringsReplace(const S: string; OldPattern, NewPattern: array of string;  Flags: TReplaceFlags): string;
 
 var pc,pcc,lastpc : pchar;
strutils.diff (2,558 bytes)

Bart Broersma

2015-09-27 13:53

reporter   ~0086105

Attached patch.

Bart Broersma

2015-10-28 13:34

reporter   ~0086938

Can some fpc-devel at least indicate wether this proposal/patch is acceptable at all?

Michael Van Canneyt

2015-11-26 21:56

administrator   ~0087627

Applied the patch.

if we don't respond: it is possible we didn't see the bug and/or patch.

I personally was not aware of either.

Feel free to mail personally or on the lists.

Issue History

Date Modified Username Field Change
2015-09-25 16:11 Alexey Tor. New Issue
2015-09-25 17:41 Bart Broersma Note Added: 0086074
2015-09-25 19:37 Alexey Tor. Note Added: 0086079
2015-09-25 20:30 Alexey Tor. Note Added: 0086081
2015-09-25 22:22 Bart Broersma Note Added: 0086083
2015-09-25 22:24 Bart Broersma Note Edited: 0086083 View Revisions
2015-09-25 23:52 Alexey Tor. Note Added: 0086087
2015-09-27 00:09 Bart Broersma Note Added: 0086098
2015-09-27 02:54 Alexey Tor. Note Added: 0086099
2015-09-27 11:24 Bart Broersma Note Added: 0086101
2015-09-27 11:43 Alexey Tor. Note Added: 0086104
2015-09-27 11:43 Alexey Tor. Note Edited: 0086104 View Revisions
2015-09-27 13:53 Bart Broersma File Added: strutils.diff
2015-09-27 13:53 Bart Broersma Note Added: 0086105
2015-09-27 13:54 Bart Broersma Tag Attached: patch
2015-10-28 13:34 Bart Broersma Note Added: 0086938
2015-11-26 21:56 Michael Van Canneyt Note Added: 0087627
2015-11-26 21:56 Michael Van Canneyt Status new => resolved
2015-11-26 21:56 Michael Van Canneyt Fixed in Version => 3.1.1
2015-11-26 21:56 Michael Van Canneyt Resolution open => fixed
2015-11-26 21:56 Michael Van Canneyt Assigned To => Michael Van Canneyt
2015-11-26 21:56 Michael Van Canneyt Target Version => 4.0.0