From 60ccf03a0b968be5fa0b1773072218aa6e1f7021 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Thu, 13 Dec 2007 20:41:31 +0000 Subject: [PATCH] * completed cwstring unit * optimized LowerWideString/UpperWideString not to call UniqueString for each string character * fixed LowerAnsiString/UpperAnsiString in case an ascii character has a lower/uppercase version with a different length than 1 + generic test for ansistring comparisons using on the widestring manager (based on glibc test) - removed ansi2ucs4-related stuff as it's not used/needed git-svn-id: trunk@9440 - --- .gitattributes | 1 + rtl/unix/cwstring.pp | 403 ++++++++++++++++---------- tests/test/units/sysutils/tastrcmp.pp | 167 +++++++++++ 3 files changed, 412 insertions(+), 159 deletions(-) create mode 100644 tests/test/units/sysutils/tastrcmp.pp diff --git a/.gitattributes b/.gitattributes index e5530ff89d..b335c4d43f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7407,6 +7407,7 @@ tests/test/units/system/tvalc.pp -text tests/test/units/sysutils/execansi.pp svneol=native#text/plain tests/test/units/sysutils/execedbya.pp svneol=native#text/plain tests/test/units/sysutils/extractquote.pp svneol=native#text/plain +tests/test/units/sysutils/tastrcmp.pp svneol=native#text/plain tests/test/units/sysutils/tfile1.pp svneol=native#text/plain tests/test/units/sysutils/tfloattostr.pp -text tests/test/units/sysutils/tsscanf.pp svneol=native#text/plain diff --git a/rtl/unix/cwstring.pp b/rtl/unix/cwstring.pp index 0ff901e9ca..985f99811a 100644 --- a/rtl/unix/cwstring.pp +++ b/rtl/unix/cwstring.pp @@ -46,20 +46,20 @@ Const {$endif} { helper functions from libc } -function tolower(__wc:cint):cint;cdecl;external libiconvname name 'tolower'; -function toupper(__wc:cint):cint;cdecl;external libiconvname name 'toupper'; -function towlower(__wc:wint_t):wint_t;cdecl;external libiconvname name 'towlower'; -function towupper(__wc:wint_t):wint_t;cdecl;external libiconvname name 'towupper'; +function towlower(__wc:wint_t):wint_t;cdecl;external clib name 'towlower'; +function towupper(__wc:wint_t):wint_t;cdecl;external clib name 'towupper'; -function wcscoll (__s1:pwchar_t; __s2:pwchar_t):cint;cdecl;external libiconvname name 'wcscoll'; -function strcoll (__s1:pchar; __s2:pchar):cint;cdecl;external libiconvname name 'strcoll'; +function wcscoll (__s1:pwchar_t; __s2:pwchar_t):cint;cdecl;external clib name 'wcscoll'; +function strcoll (__s1:pchar; __s2:pchar):cint;cdecl;external clib name 'strcoll'; function setlocale(category: cint; locale: pchar): pchar; cdecl; external clib name 'setlocale'; {$ifndef beos} function mbrtowc(pwc: pwchar_t; const s: pchar; n: size_t; ps: pmbstate_t): size_t; cdecl; external clib name 'mbrtowc'; function wcrtomb(s: pchar; wc: wchar_t; ps: pmbstate_t): size_t; cdecl; external clib name 'wcrtomb'; +function mbrlen(const s: pchar; n: size_t; ps: pmbstate_t): size_t; cdecl; external clib name 'mbrlen'; {$else beos} function mbtowc(pwc: pwchar_t; const s: pchar; n: size_t): size_t; cdecl; external clib name 'mbtowc'; function wctomb(s: pchar; wc: wchar_t): size_t; cdecl; external clib name 'wctomb'; +function mblen(const s: pchar; n: size_t): size_t; cdecl; external clib name 'mblen'; {$endif beos} @@ -109,6 +109,13 @@ const unicode_encoding4 = 'UCS-4BE'; {$endif FPC_LITTLE_ENDIAN} +{ en_US.UTF-8 needs maximally 6 chars, UCS-4/UTF-32 needs 4 } +{ -> 10 should be enough? Should actually use MB_CUR_MAX, but } +{ that's a libc macro mapped to internal functions/variables } +{ and thus not a stable external API on systems where libc } +{ breaks backwards compatibility every now and then } + MB_CUR_MAX = 10; + type piconv_t = ^iconv_t; iconv_t = pointer; @@ -127,9 +134,10 @@ function iconv(__cd:iconv_t; __inbuf:ppchar; __inbytesleft:psize_t; __outbuf:ppc function iconv_close(__cd:iconv_t):cint;cdecl;external libiconvname name 'libiconv_close'; {$endif} +procedure fpc_rangeerror; [external name 'FPC_RANGEERROR']; + + threadvar - iconv_ansi2ucs4, - iconv_ucs42ansi, iconv_ansi2wide, iconv_wide2ansi : iconv_t; @@ -270,8 +278,8 @@ function LowerWideString(const s : WideString) : WideString; i : SizeInt; begin SetLength(result,length(s)); - for i:=1 to length(s) do - result[i]:=WideChar(towlower(wint_t(s[i]))); + for i:=0 to length(s)-1 do + pwidechar(result)[i]:=WideChar(towlower(wint_t(s[i+1]))); end; @@ -280,8 +288,8 @@ function UpperWideString(const s : WideString) : WideString; i : SizeInt; begin SetLength(result,length(s)); - for i:=1 to length(s) do - result[i]:=WideChar(towupper(wint_t(s[i]))); + for i:=0 to length(s)-1 do + pwidechar(result)[i]:=WideChar(towupper(wint_t(s[i+1]))); end; @@ -319,12 +327,7 @@ begin ConcatCharToAnsiStr(char(nc),s,index) else begin - { en_US.UTF-8 needs maximally 6 chars, UCS-4/UTF-32 needs 4 } - { -> 10 should be enough? Should actually use MB_CUR_MAX, but } - { that's a libc macro mapped to internal functions/variables } - { and thus not a stable external API on systems where libc } - { breaks backwards compatibility every now and then } - EnsureAnsiLen(s,index+10); + EnsureAnsiLen(s,index+MB_CUR_MAX); {$ifndef beos} mblen:=wcrtomb(p,wchar_t(nc),@mbstate); {$else not beos} @@ -365,46 +368,44 @@ function LowerAnsiString(const s : AnsiString) : AnsiString; begin if (s[i]<=#127) then begin - ConcatCharToAnsiStr(char(tolower(cint(s[i]))),result,resindex); - inc(i) + wc:=wchar_t(s[i]); + mblen:= 1; end else - begin {$ifndef beos} - mblen:=mbrtowc(@wc, pchar(@s[i]), slen-i+1, @ombstate); + mblen:=mbrtowc(@wc, pchar(@s[i]), slen-i+1, @ombstate); {$else not beos} - mblen:=mbtowc(@wc, pchar(@s[i]), slen-i+1); + mblen:=mbtowc(@wc, pchar(@s[i]), slen-i+1); {$endif not beos} - case mblen of - size_t(-2): - begin - { partial invalid character, copy literally } - while (i<=slen) do - begin - ConcatCharToAnsiStr(s[i],result,resindex); - inc(i); - end; - end; - size_t(-1), 0: - begin - { invalid or null character } - ConcatCharToAnsiStr(s[i],result,resindex); - inc(i); - end; - else - begin - { a valid sequence } - { even if mblen = 1, the lowercase version may have a } - { different length } - { We can't do anything special if wchar_t is 16 bit... } + case mblen of + size_t(-2): + begin + { partial invalid character, copy literally } + while (i<=slen) do + begin + ConcatCharToAnsiStr(s[i],result,resindex); + inc(i); + end; + end; + size_t(-1), 0: + begin + { invalid or null character } + ConcatCharToAnsiStr(s[i],result,resindex); + inc(i); + end; + else + begin + { a valid sequence } + { even if mblen = 1, the lowercase version may have a } + { different length } + { We can't do anything special if wchar_t is 16 bit... } {$ifndef beos} - ConcatUTF32ToAnsiStr(towlower(wint_t(wc)),result,resindex,nmbstate); + ConcatUTF32ToAnsiStr(towlower(wint_t(wc)),result,resindex,nmbstate); {$else not beos} - ConcatUTF32ToAnsiStr(towlower(wint_t(wc)),result,resindex); + ConcatUTF32ToAnsiStr(towlower(wint_t(wc)),result,resindex); {$endif not beos} - inc(i,mblen); - end; - end; + inc(i,mblen); + end; end; end; SetLength(result,resindex-1); @@ -434,109 +435,50 @@ function UpperAnsiString(const s : AnsiString) : AnsiString; begin if (s[i]<=#127) then begin - ConcatCharToAnsiStr(char(toupper(cint(s[i]))),result,resindex); - inc(i) + wc:=wchar_t(s[i]); + mblen:= 1; end else - begin {$ifndef beos} - mblen:=mbrtowc(@wc, pchar(@s[i]), slen-i+1, @ombstate); + mblen:=mbrtowc(@wc, pchar(@s[i]), slen-i+1, @ombstate); {$else not beos} - mblen:=mbtowc(@wc, pchar(@s[i]), slen-i+1); + mblen:=mbtowc(@wc, pchar(@s[i]), slen-i+1); {$endif beos} - case mblen of - size_t(-2): - begin - { partial invalid character, copy literally } - while (i<=slen) do - begin - ConcatCharToAnsiStr(s[i],result,resindex); - inc(i); - end; - end; - size_t(-1), 0: - begin - { invalid or null character } - ConcatCharToAnsiStr(s[i],result,resindex); - inc(i); - end; - else - begin - { a valid sequence } - { even if mblen = 1, the uppercase version may have a } - { different length } - { We can't do anything special if wchar_t is 16 bit... } + case mblen of + size_t(-2): + begin + { partial invalid character, copy literally } + while (i<=slen) do + begin + ConcatCharToAnsiStr(s[i],result,resindex); + inc(i); + end; + end; + size_t(-1), 0: + begin + { invalid or null character } + ConcatCharToAnsiStr(s[i],result,resindex); + inc(i); + end; + else + begin + { a valid sequence } + { even if mblen = 1, the uppercase version may have a } + { different length } + { We can't do anything special if wchar_t is 16 bit... } {$ifndef beos} - ConcatUTF32ToAnsiStr(towupper(wint_t(wc)),result,resindex,nmbstate); + ConcatUTF32ToAnsiStr(towupper(wint_t(wc)),result,resindex,nmbstate); {$else not beos} - ConcatUTF32ToAnsiStr(towupper(wint_t(wc)),result,resindex); + ConcatUTF32ToAnsiStr(towupper(wint_t(wc)),result,resindex); {$endif not beos} - inc(i,mblen); - end; - end; + inc(i,mblen); + end; end; end; SetLength(result,resindex-1); end; -procedure Ansi2UCS4Move(source:pchar;var dest:UCS4String;len:SizeInt); - var - outlength, - outoffset, - outleft : size_t; - err: cint; - srcpos, - destpos: pchar; - mynil : pchar; - my0 : size_t; - begin - mynil:=nil; - my0:=0; - // extra space - outlength:=len+1; - setlength(dest,outlength); - outlength:=len+1; - srcpos:=source; - destpos:=pchar(dest); - outleft:=outlength*4; - while iconv(iconv_ansi2ucs4,@srcpos,psize(@len),@destpos,@outleft)=size_t(-1) do - begin - err:=fpgetCerrno; - case err of - ESysEINVAL, - ESysEILSEQ: - begin - { skip and set to '?' } - inc(srcpos); - dec(len); - plongint(destpos)^:=longint('?'); - inc(destpos,4); - dec(outleft,4); - { reset } - iconv(iconv_ansi2ucs4,@mynil,@my0,@mynil,@my0); - if err=ESysEINVAL then - break; - end; - ESysE2BIG: - begin - outoffset:=destpos-pchar(dest); - { extend } - setlength(dest,outlength+len); - inc(outleft,len*4); - inc(outlength,len); - { string could have been moved } - destpos:=pchar(dest)+outoffset; - end; - else - runerror(231); - end; - end; - // truncate string - setlength(dest,length(dest)-outleft div 4); - end; - - function utf16toutf32(const S: WideString; const index: SizeInt; out len: longint): UCS4Char; external name 'FPC_UTF16TOUTF32'; function WideStringToUCS4StringNoNulls(const s : WideString) : UCS4String; @@ -582,18 +524,169 @@ function CompareTextWideString(const s1, s2 : WideString): PtrInt; end; +function CharLengthPChar(const Str: PChar): PtrInt; + var + nextlen: ptrint; + s: pchar; +{$ifndef beos} + mbstate: mbstate_t; +{$endif not beos} + begin + result:=0; + s:=str; + repeat +{$ifdef beos} + nextlen:=ptrint(mblen(str,MB_CUR_MAX)); +{$else beos} + nextlen:=ptrint(mbrlen(str,MB_CUR_MAX,@mbstate)); +{$endif beos} + { skip invalid/incomplete sequences } + if (nextlen<0) then + nextlen:=1; + inc(result,nextlen); + inc(s,nextlen); + until (nextlen=0); + end; + + +function StrCompAnsiIntern(const s1,s2 : PChar; len1, len2: PtrInt): PtrInt; + var + a,b: pchar; + i: PtrInt; + begin + getmem(a,len1+1); + getmem(b,len2+1); + for i:=0 to len1-1 do + if s1[i]<>#0 then + a[i]:=s1[i] + else + a[i]:=#32; + a[len1]:=#0; + for i:=0 to len2-1 do + if s2[i]<>#0 then + b[i]:=s2[i] + else + b[i]:=#32; + b[len2]:=#0; + result:=strcoll(a,b); + freemem(a); + freemem(b); + end; + + +function CompareStrAnsiString(const s1, s2: ansistring): PtrInt; + begin + result:=StrCompAnsiIntern(pchar(s1),pchar(s2),length(s1),length(s2)); + end; + + function StrCompAnsi(s1,s2 : PChar): PtrInt; begin result:=strcoll(s1,s2); end; +function AnsiCompareText(const S1, S2: ansistring): PtrInt; + var + a, b: AnsiString; + begin + a:=UpperAnsistring(s1); + b:=UpperAnsistring(s2); + result:=StrCompAnsiIntern(pchar(a),pchar(b),length(a),length(b)); + end; + + +function AnsiStrIComp(S1, S2: PChar): PtrInt; + begin + result:=AnsiCompareText(ansistring(s1),ansistring(s2)); + end; + + +function AnsiStrLComp(S1, S2: PChar; MaxLen: PtrUInt): PtrInt; + var + a, b: pchar; +begin + if (IndexChar(s1^,maxlen,#0)<0) then + begin + getmem(a,maxlen+1); + move(s1^,a^,maxlen); + a[maxlen]:=#0; + end + else + a:=s1; + if (IndexChar(s2^,maxlen,#0)<0) then + begin + getmem(b,maxlen+1); + move(s2^,b^,maxlen); + b[maxlen]:=#0; + end + else + b:=s2; + result:=strcoll(a,b); + if (a<>s1) then + freemem(a); + if (b<>s2) then + freemem(b); +end; + + +function AnsiStrLIComp(S1, S2: PChar; MaxLen: PtrUInt): PtrInt; + var + a, b: ansistring; + len1,len2: SizeInt; +begin + len1:=IndexChar(s1^,maxlen,#0); + if (len1<0) then + len1:=maxlen; + setlength(a,len1); + if (len1<>0) then + move(s1^,a[1],len1); + len2:=IndexChar(s2^,maxlen,#0); + if (len2<0) then + len2:=maxlen; + setlength(b,len2); + if (len2<>0) then + move(s2^,b[1],len2); + result:=AnsiCompareText(a,b); +end; + + +procedure ansi2pchar(const s: ansistring; const orgp: pchar; out p: pchar); +var + newlen: sizeint; +begin + newlen:=length(s); + if newlen>strlen(orgp) then + fpc_rangeerror; + p:=orgp; + if (newlen>0) then + move(s[1],p[0],newlen); + p[newlen]:=#0; +end; + + +function AnsiStrLower(Str: PChar): PChar; +var + temp: ansistring; +begin + temp:=upperansistring(str); + ansi2pchar(temp,str,result); +end; + + +function AnsiStrUpper(Str: PChar): PChar; +var + temp: ansistring; +begin + temp:=loweransistring(str); + ansi2pchar(temp,str,result); +end; + + procedure InitThread; begin iconv_wide2ansi:=iconv_open(nl_langinfo(CODESET),unicode_encoding2); iconv_ansi2wide:=iconv_open(unicode_encoding2,nl_langinfo(CODESET)); - iconv_ucs42ansi:=iconv_open(nl_langinfo(CODESET),unicode_encoding4); - iconv_ansi2ucs4:=iconv_open(unicode_encoding4,nl_langinfo(CODESET)); end; @@ -603,10 +696,6 @@ begin iconv_close(iconv_wide2ansi); if (iconv_ansi2wide <> iconv_t(-1)) then iconv_close(iconv_ansi2wide); - if (iconv_ucs42ansi <> iconv_t(-1)) then - iconv_close(iconv_ucs42ansi); - if (iconv_ansi2ucs4 <> iconv_t(-1)) then - iconv_close(iconv_ansi2ucs4); end; @@ -625,23 +714,19 @@ begin CompareWideStringProc:=@CompareWideString; CompareTextWideStringProc:=@CompareTextWideString; - { - CharLengthPCharProc - } + + CharLengthPCharProc:=@CharLengthPChar; + UpperAnsiStringProc:=@UpperAnsiString; LowerAnsiStringProc:=@LowerAnsiString; - { - CompareStrAnsiStringProc - CompareTextAnsiStringProc - } + CompareStrAnsiStringProc:=@CompareStrAnsiString; + CompareTextAnsiStringProc:=@AnsiCompareText; StrCompAnsiStringProc:=@StrCompAnsi; - { - StrICompAnsiStringProc - StrLCompAnsiStringProc - StrLICompAnsiStringProc - StrLowerAnsiStringProc - StrUpperAnsiStringProc - } + StrICompAnsiStringProc:=@AnsiStrIComp; + StrLCompAnsiStringProc:=@AnsiStrLComp; + StrLICompAnsiStringProc:=@AnsiStrLIComp; + StrLowerAnsiStringProc:=@AnsiStrLower; + StrUpperAnsiStringProc:=@AnsiStrUpper; ThreadInitProc:=@InitThread; ThreadFiniProc:=@FiniThread; end; diff --git a/tests/test/units/sysutils/tastrcmp.pp b/tests/test/units/sysutils/tastrcmp.pp new file mode 100644 index 0000000000..fd35e04a02 --- /dev/null +++ b/tests/test/units/sysutils/tastrcmp.pp @@ -0,0 +1,167 @@ +{ based on string/tester.c of glibc 2.3.6 + +* Tester for string functions. + Copyright (C) 1995-2000, 2001, 2003 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ +} + +{$ifdef fpc} +{$mode delphi} +{$endif fpc} + +uses +{$ifdef unix} + cwstring, +{$endif unix} + SysUtils; + +var + teststr: string; + goterror: boolean; + +procedure check(b: boolean; testnr: longint); +begin + if not (b) then + begin + writeln(teststr,' error nr ',testnr); + goterror:=true; + end; +end; + +procedure testAnsiCompareText; +begin + teststr:='AnsiCompareText'; + check(ansicomparetext('a', 'a') = 0, 1); + check(ansicomparetext('a', 'A') = 0, 2); + check(ansicomparetext('A', 'a') = 0, 3); + check(ansicomparetext('a', 'b') < 0, 4); + check(ansicomparetext('c', 'b') > 0, 5); + check(ansicomparetext('abc', 'AbC') = 0, 6); + check(ansicomparetext('0123456789', '0123456789') = 0, 7); + check(ansicomparetext('', '0123456789') < 0, 8); + check(ansicomparetext('AbC', '') > 0, 9); + check(ansicomparetext('AbC', 'A') > 0, 10); + check(ansicomparetext('AbC', 'Ab') > 0, 11); + check(ansicomparetext('AbC', 'ab') > 0, 12); + check(ansicomparetext('Ab'#0'C', 'ab'#0) > 0, 13); +end; + + +procedure testAnsiStrIComp; +begin + teststr:='AnsiStrIComp'; + check(ansistricomp('a', 'a') = 0, 1); + check(ansistricomp('a', 'A') = 0, 2); + check(ansistricomp('A', 'a') = 0, 3); + check(ansistricomp('a', 'b') < 0, 4); + check(ansistricomp('c', 'b') > 0, 5); + check(ansistricomp('abc', 'AbC') = 0, 6); + check(ansistricomp('0123456789', '0123456789') = 0, 7); + check(ansistricomp('', '0123456789') < 0, 8); + check(ansistricomp('AbC', '') > 0, 9); + check(ansistricomp('AbC', 'A') > 0, 10); + check(ansistricomp('AbC', 'Ab') > 0, 11); + check(ansistricomp('AbC', 'ab') > 0, 12); + check(ansistricomp('Ab'#0'C', 'ab'#0) = 0, 13); +end; + + +procedure testAnsiStrLComp; +begin + teststr:='AnsiStrIComp'; + check (ansistrlcomp ('', '', 99) = 0, 1); { Trivial case. } + check (ansistrlcomp ('a', 'a', 99) = 0, 2); { Identity. } + check (ansistrlcomp ('abc', 'abc', 99) = 0, 3); { Multicharacter. } + check (ansistrlcomp ('abc', 'abcd', 99) < 0, 4); { Length unequal. } + check (ansistrlcomp ('abcd', 'abc', 99) > 0, 5); + check (ansistrlcomp ('abcd', 'abce', 99) < 0, 6); { Honestly unequal. } + check (ansistrlcomp ('abce', 'abcd', 99) > 0, 7); + check (ansistrlcomp ('abce', 'abcd', 3) = 0, 10); { Count limited. } + check (ansistrlcomp ('abce', 'abc', 3) = 0, 11); { Count = length. } + check (ansistrlcomp ('abcd', 'abce', 4) < 0, 12); { Nudging limit. } + check (ansistrlcomp ('abc', 'def', 0) = 0, 13); { Zero count. } + check (ansistrlcomp ('abc'#0'e', 'abc'#0'd', 99) = 0, 14); +end; + + +procedure testAnsiCompareStr; +begin + teststr:='AnsiCompareStr'; + check (ansicomparestr ('', '') = 0, 1); { Trivial case. } + check (ansicomparestr ('a', 'a') = 0, 2); { Identity. } + check (ansicomparestr ('abc', 'abc') = 0, 3); { Multicharacter. } + check (ansicomparestr ('abc', 'abcd') < 0, 4); { Length mismatches. } + check (ansicomparestr ('abcd', 'abc') > 0, 5); + check (ansicomparestr ('abcd', 'abce') < 0, 6); { Honest miscompares. } + check (ansicomparestr ('abce', 'abcd') > 0, 7); + check (ansicomparestr ('abc'#0'e', 'abc'#0'd') > 0, 8); +end; + + +procedure testAnsiStrComp; +begin + teststr:='AnsiStrComp'; + check (ansistrcomp ('', '') = 0, 1); { Trivial case. } + check (ansistrcomp ('a', 'a') = 0, 2); { Identity. } + check (ansistrcomp ('abc', 'abc') = 0, 3); { Multicharacter. } + check (ansistrcomp ('abc', 'abcd') < 0, 4); { Length mismatches. } + check (ansistrcomp ('abcd', 'abc') > 0, 5); + check (ansistrcomp ('abcd', 'abce') < 0, 6); { Honest miscompares. } + check (ansistrcomp ('abce', 'abcd') > 0, 7); + check (ansistrcomp ('abc'#0'e', 'abc'#0'd') = 0, 8); +end; + + +procedure testAnsiStrLIComp; +begin + teststr:='AnsiStrLIComp'; + check(ansistrlicomp('a', 'a', 5) = 0, 1); + check(ansistrlicomp('a', 'A', 5) = 0, 2); + check(ansistrlicomp('A', 'a', 5) = 0, 3); + check(ansistrlicomp('a', 'b', 5) < 0, 4); + check(ansistrlicomp('c', 'b', 5) > 0, 5); + check(ansistrlicomp('abc', 'AbC', 5) = 0, 6); + check(ansistrlicomp('0123456789', '0123456789', 10) = 0, 7); + check(ansistrlicomp('', '0123456789', 10) < 0, 8); + check(ansistrlicomp('AbC', '', 5) > 0, 9); + check(ansistrlicomp('AbC', 'A', 5) > 0, 10); + check(ansistrlicomp('AbC', 'Ab', 5) > 0, 11); + check(ansistrlicomp('AbC', 'ab', 5) > 0, 12); + check(ansistrlicomp('0123456789', 'AbC', 0) = 0, 13); + check(ansistrlicomp('AbC', 'abc', 1) = 0, 14); + check(ansistrlicomp('AbC', 'abc', 2) = 0, 15); + check(ansistrlicomp('AbC', 'abc', 3) = 0, 16); + check(ansistrlicomp('AbC', 'abcd', 3) = 0, 17); + check(ansistrlicomp('AbC', 'abcd', 4) < 0, 18); + check(ansistrlicomp('ADC', 'abcd', 1) = 0, 19); + check(ansistrlicomp('ADC', 'abcd', 2) > 0, 20); + check(ansistrlicomp('abc'#0'e', 'abc'#0'd', 99) = 0, 21); +end; + + +begin + goterror:=false; + testAnsiCompareText; + testAnsiStrIComp; + testAnsiStrLComp; + testAnsiCompareStr; + testAnsiStrComp; + testAnsiStrLIComp; + if goterror then + halt(1); +end. \ No newline at end of file