Переглянути джерело

* ansi(start/ends)(str/text) MBCS compatible (via widestringmgr), mantis #16153 + tests
Patch by Flavio Etrusco.

git-svn-id: trunk@19043 -

marco 14 роки тому
батько
коміт
91b017a985
4 змінених файлів з 155 додано та 14 видалено
  1. 2 0
      .gitattributes
  2. 28 14
      rtl/objpas/strutils.pp
  3. 62 0
      tests/test/tstrutils1.pp
  4. 63 0
      tests/test/tstrutils2.pp

+ 2 - 0
.gitattributes

@@ -10486,6 +10486,8 @@ tests/test/tstrreal2.pp svneol=native#text/plain
 tests/test/tstrreal3.pp svneol=native#text/plain
 tests/test/tstrreal4.pp svneol=native#text/plain
 tests/test/tstrreal5.pp svneol=native#text/plain
+tests/test/tstrutils1.pp svneol=native#text/plain
+tests/test/tstrutils2.pp svneol=native#text/plain
 tests/test/tsubdecl.pp svneol=native#text/plain
 tests/test/tsymlibrary1.pp svneol=native#text/pascal
 tests/test/ttpara1.pp svneol=native#text/plain

+ 28 - 14
rtl/objpas/strutils.pp

@@ -28,10 +28,10 @@ uses
 
 Function AnsiResemblesText(const AText, AOther: string): Boolean;
 Function AnsiContainsText(const AText, ASubText: string): Boolean;
-Function AnsiStartsText(const ASubText, AText: string): Boolean;inline;
-Function AnsiEndsText(const ASubText, AText: string): Boolean;inline;
+Function AnsiStartsText(const ASubText, AText: string): Boolean;
+Function AnsiEndsText(const ASubText, AText: string): Boolean;
 Function AnsiReplaceText(const AText, AFromText, AToText: string): string;inline;
-Function AnsiMatchText(const AText: string; const AValues: array of string): Boolean;
+Function AnsiMatchText(const AText: string; const AValues: array of string): Boolean;inline;
 Function AnsiIndexText(const AText: string; const AValues: array of string): Integer;
 
 { ---------------------------------------------------------------------
@@ -39,10 +39,10 @@ Function AnsiIndexText(const AText: string; const AValues: array of string): Int
   ---------------------------------------------------------------------}
 
 Function AnsiContainsStr(const AText, ASubText: string): Boolean;inline;
-Function AnsiStartsStr(const ASubText, AText: string): Boolean;inline;
-Function AnsiEndsStr(const ASubText, AText: string): Boolean;inline;
+Function AnsiStartsStr(const ASubText, AText: string): Boolean;
+Function AnsiEndsStr(const ASubText, AText: string): Boolean;
 Function AnsiReplaceStr(const AText, AFromText, AToText: string): string;inline;
-Function AnsiMatchStr(const AText: string; const AValues: array of string): Boolean;
+Function AnsiMatchStr(const AText: string; const AValues: array of string): Boolean;inline;
 Function AnsiIndexStr(const AText: string; const AValues: array of string): Integer;
 
 { ---------------------------------------------------------------------
@@ -241,15 +241,22 @@ begin
 end;
 
 
-Function AnsiStartsText(const ASubText, AText: string): Boolean;inline;
+Function AnsiStartsText(const ASubText, AText: string): Boolean;
 begin
-  Result:=AnsiCompareText(Copy(AText,1,Length(AsubText)),ASubText)=0;
+  if (Length(AText) >= Length(ASubText)) and (ASubText <> '') then
+    Result := AnsiStrLIComp(PChar(ASubText), PChar(AText), Length(ASubText)) = 0
+  else
+    Result := False;
 end;
 
 
-Function AnsiEndsText(const ASubText, AText: string): Boolean;inline;
+Function AnsiEndsText(const ASubText, AText: string): Boolean;
 begin
- result:=AnsiCompareText(Copy(AText,Length(AText)-Length(ASubText)+1,Length(ASubText)),asubtext)=0;
+  if Length(AText) >= Length(ASubText) then
+    Result := AnsiStrLIComp(PChar(ASubText),
+      PChar(AText) + Length(AText) - Length(ASubText), Length(ASubText)) = 0
+  else
+    Result := False;
 end;
 
 
@@ -289,15 +296,22 @@ begin
 end;
 
 
-Function AnsiStartsStr(const ASubText, AText: string): Boolean;inline;
+Function AnsiStartsStr(const ASubText, AText: string): Boolean;
 begin
-  Result := AnsiPos(ASubText,AText)=1;
+  if (Length(AText) >= Length(ASubText)) and (ASubText <> '') then
+    Result := AnsiStrLComp(PChar(ASubText), PChar(AText), Length(ASubText)) = 0
+  else
+    Result := False;
 end;
 
 
-Function AnsiEndsStr(const ASubText, AText: string): Boolean;inline;
+Function AnsiEndsStr(const ASubText, AText: string): Boolean;
 begin
- Result := AnsiCompareStr(Copy(AText,length(AText)-length(ASubText)+1,length(ASubText)),ASubText)=0;
+  if Length(AText) >= Length(ASubText) then
+    Result := AnsiStrLComp(PChar(ASubText),
+      PChar(AText) + Length(AText) - Length(ASubText), Length(ASubText)) = 0
+  else
+    Result := False;
 end;
 
 

+ 62 - 0
tests/test/tstrutils1.pp

@@ -0,0 +1,62 @@
+program tstrutils1;
+
+// tests MBCS compatibility of strutils ansistartsstr and -endsstr.
+
+{$mode objfpc}
+{$h+}
+
+uses
+  {SysUtils, }cwstring,StrUtils;
+
+var
+  ResultCounter: Integer = 0;
+
+function TestValue(const Value: Boolean): Boolean;
+begin
+  Result := Value;
+  if not Value then
+    WriteLn('Failed: ', ResultCounter);
+  Inc(ResultCounter);
+end;
+
+function TestOK: Boolean;
+begin
+  TestOK :=
+    // AnsiStartsStr
+    not AnsiStartsStr('', '')
+    and not AnsiStartsStr('', 'ab')
+    and not AnsiStartsStr('ab', '')
+    and AnsiStartsStr('abc', 'abc')
+    and not AnsiStartsStr('abc', 'def')
+    and AnsiStartsStr('abc', 'abcedfg')
+    and not AnsiStartsStr('abc', 'ab')
+    and AnsiStartsStr('áéíç', 'áéíç')
+    and AnsiStartsStr('áé', 'áéíç')
+    and not AnsiStartsStr('áéíç', 'áé')
+    and not AnsiStartsStr('áéíç', 'áéio')
+    // AnsiEndsStr
+    and AnsiEndsStr('', '')
+    and AnsiEndsStr('', 'ab')
+    and not AnsiEndsStr('ab', '')
+    and AnsiEndsStr('abc', 'abc')
+    and not AnsiEndsStr('abc', 'def')
+    and AnsiEndsStr('dfg', 'abcedfg')
+    and not AnsiEndsStr('dfg', 'df')
+    and AnsiEndsStr('áéíç', 'áéíç')
+    and AnsiEndsStr('áé', 'íçáé')
+    and not AnsiEndsStr('áéíç', 'áé')
+    and not AnsiEndsStr('íçáé', 'ioáé');
+end;
+
+begin
+  if TestOK() then
+  begin
+    WriteLn('Test OK');
+    halt(0);
+  end
+  else
+    begin
+      WriteLn('Test Failure!');
+      halt(1);
+    end;
+end.

+ 63 - 0
tests/test/tstrutils2.pp

@@ -0,0 +1,63 @@
+program tstrutils2;
+
+// tests MBCS compatibility of strutils ansistartstext and -endstext. 
+// (case-insensitive)
+
+{$mode objfpc}
+{$h+}
+
+uses
+  StrUtils,cwstring;
+
+var
+  ResultCounter: Integer = 0;
+
+function TestValue(const Value: Boolean): Boolean;
+begin
+  Result := Value;
+  if not Value then
+    WriteLn('Failed: ', ResultCounter);
+  Inc(ResultCounter);
+end;
+
+function TestOK: Boolean;
+begin
+  TestOK :=
+    // AnsiStartsText
+    not AnsiStartsText('', '')
+    and not AnsiStartsText('', 'ab')
+    and not AnsiStartsText('ab', '')
+    and AnsiStartsText('abc', 'abc')
+    and not AnsiStartsText('abc', 'def')
+    and AnsiStartsText('abc', 'abcedfg')
+    and not AnsiStartsText('abc', 'ab')
+    and AnsiStartsText('áÉíç', 'áéíÇ')
+    and AnsiStartsText('áé', 'áÉíç')
+    and not AnsiStartsText('áÉíç', 'Áé')
+    and not AnsiStartsText('ÁÉíç', 'áéio')
+    // AnsiEndsText
+    and AnsiEndsText('', '')
+    and AnsiEndsText('', 'ab')
+    and not AnsiEndsText('ab', '')
+    and AnsiEndsText('abc', 'abc')
+    and not AnsiEndsText('abc', 'def')
+    and AnsiEndsText('dfg', 'abcedfg')
+    and not AnsiEndsText('dfg', 'df')
+    and AnsiEndsText('áÉíç', 'Áéíç')
+    and AnsiEndsText('áé', 'íçáÉ')
+    and not AnsiEndsText('áÉíç', 'áé')
+    and not AnsiEndsText('íçÁÉ', 'ioÁé');
+end;
+
+begin
+  if TestOK() then
+  begin
+    WriteLn('Test OK');
+    halt(0);
+  end
+  else
+    begin
+      WriteLn('Test Failure!');
+      halt(1);
+    end;
+end.