Return-Path: Delivered-To: apmail-incubator-stdcxx-dev-archive@www.apache.org Received: (qmail 7391 invoked from network); 27 Jun 2006 00:00:33 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 27 Jun 2006 00:00:33 -0000 Received: (qmail 25863 invoked by uid 500); 27 Jun 2006 00:00:33 -0000 Delivered-To: apmail-incubator-stdcxx-dev-archive@incubator.apache.org Received: (qmail 25844 invoked by uid 500); 27 Jun 2006 00:00:32 -0000 Mailing-List: contact stdcxx-dev-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: stdcxx-dev@incubator.apache.org Delivered-To: mailing list stdcxx-dev@incubator.apache.org Received: (qmail 25831 invoked by uid 99); 27 Jun 2006 00:00:32 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 26 Jun 2006 17:00:32 -0700 X-ASF-Spam-Status: No, hits=0.0 required=10.0 tests= X-Spam-Check-By: apache.org Received-SPF: neutral (asf.osuosl.org: local policy) Received: from [208.30.140.160] (HELO moroha.quovadx.com) (208.30.140.160) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 26 Jun 2006 17:00:31 -0700 Received: from qxvcexch01.ad.quovadx.com (qxvcexch01.ad.quovadx.com [192.168.170.59]) by moroha.quovadx.com (8.13.6/8.13.4) with ESMTP id k5QNxr7v018442 for ; Mon, 26 Jun 2006 23:59:53 GMT Received: from [10.70.3.113] ([10.70.3.113]) by qxvcexch01.ad.quovadx.com with Microsoft SMTPSVC(6.0.3790.1830); Mon, 26 Jun 2006 18:00:31 -0600 Message-ID: <44A07516.8090606@roguewave.com> Date: Mon, 26 Jun 2006 18:00:22 -0600 From: Martin Sebor Organization: Rogue Wave Software User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.12) Gecko/20050920 X-Accept-Language: en-us, en MIME-Version: 1.0 To: stdcxx-dev@incubator.apache.org Subject: rw_match() bus (was: Re: test for lib.string.io) References: <4D6A8407B7AC6F4D95B0E55C4E7C4C620470EA0B@exmsk.moscow.vdiweb.com> In-Reply-To: <4D6A8407B7AC6F4D95B0E55C4E7C4C620470EA0B@exmsk.moscow.vdiweb.com> Content-Type: multipart/mixed; boundary="------------080304090904020308040307" X-OriginalArrivalTime: 27 Jun 2006 00:00:31.0994 (UTC) FILETIME=[B518E5A0:01C6997C] X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N --------------080304090904020308040307 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Anton Pevtsov wrote: > Martin Sebor wrote: > >>But before committing the rest we need to first settle the issue of > > rw_expand(). > > Martin, in my previous mail I didn't mention that the problem occur when > rw_expand is called from the rw_match function. > Sorry about that. The test which illustrates the problem is here: > http://people.apache.org/~antonp/stdcxx06262006/rwmatch_rwexpand_test.cp > p Hmm. There are two possible interpretations of the third argument to rw_match(): 1. it gives the maximum number of characters to compare (i.e., after all directives have been expanded) 2. it denotes the number of characters in the first argument (i.e., before the expansion of any directives). It looks like currently we do (2). I missed this and made changes to implement (1). Needless to say, even though my changes are "good", they cause many failures in the test suite. I need to go back and implement (1). It shouldn't be too hard but it means that I won't be able to commit my changes tonight (what I have is attached so you can see where I am). Martin --------------080304090904020308040307 Content-Type: text/plain; name="char.cpp.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="char.cpp.diff" ==== //stdlib/dev/tests/stdlib/src/char.cpp#16 - /build/sebor/dev/stdlib/tests/src/char.cpp ==== @@ -678,59 +678,117 @@ size_t rw_match (const char *s1, const char *s2, size_t len /* = SIZE_MAX */) { + const char* p1 = s1; + const char* p2 = s2; + + // the length of the initial subsequence of s1 and s2 + // consisting solely of characters that compare equal + size_t count = 0; + if (0 == s1) { - // return the length of s2 if non-null - return s2 ? strlen (s2) : 0; + s1 = s2; + s2 = 0; } - if (0 == s2) - return strlen (s1); + if (0 == s2) { + // when one of the strings is null, compute the length + // of the other string when all directives are expanded + if (0 == s1 || 0 == *s1) + return 0; + + for (const char *pat = s1; ; ) { + + const char* const p = strchr (pat, '@'); - const char* const s1_save = s1; + if (p && 0 < p - pat) { + if (isdigit (p [1])) { + char* end; + const size_t n = strtoul (p + 1, &end, 10); + pat = end; + count += n; + } + else { + count += size_t (p - pat); + pat = p + 1; + } + } + else { + const size_t pat_len = strlen (pat); + count += pat_len; + pat += pat_len; + } - char s1_buf [256]; - size_t s1_len = sizeof s1_buf; + if ('\0' == *pat) { + if (_RWSTD_SIZE_MAX == len) + break; - // see if the first string contains '@' and might need - // to be expanded (see rw_expand() for details) - bool expand = false; + ++pat; + } + } - if (_RWSTD_SIZE_MAX == len) { - expand = 0 != strchr (s1, '@'); + return count; } - else { - for (const char *p = s1; *p; ++p) { - if (size_t (p - s1) == len) - break; - if ('@' == *p) { - expand = true; - break; + + + size_t n1 = 0; + size_t n2 = 0; + + for (char ch1, ch2; count < len; ) { + + while (0 == n1) { + ch1 = *p1++; + + if ('@' == p1 [0] && isdigit (p1 [1])) { + + char* end; + n1 = strtoul (p1 + 1, &end, 10); + p1 = end; } + else + n1 = 1; } - } + + while (0 == n2) { + ch2 = *p2++; - if (expand) { - s1 = rw_expand (s1_buf, s1, _RWSTD_SIZE_MAX, &s1_len); - len = s1_len; - } + if ('@' == p2 [0] && isdigit (p2 [1])) { - size_t n = 0; + char* end; + n2 = strtoul (p2 + 1, &end, 10); + p2 = end; + } + else + n2 = 1; + } - for ( ; n != len && s1 [n] == s2 [n]; ++n) { - if (_RWSTD_SIZE_MAX == len && '\0' == s1 [n]) + if (ch1 != ch2) break; - } + + if (n1 < n2) { + // the repeat count specified by the first directive + // is less than the repeat count given by the second + count += n1; + n2 -= n1; + n1 = 0; + + } + else if (n2 <= n1) { + // the repeat count specified by the second directive + // is less than or equal than that given by the first + count += n2; + n1 -= n2; + n2 = 0; + } - if (s1 && s1_save != s1 && s1_buf != s1) { - // deallocate memory if it was allocated by rw_expand() - delete[] s1; + if (_RWSTD_SIZE_MAX == len && '\0' == ch1) + break; } - return n; + return len < count ? len : count; } -#ifndef _RWSTD_WCHAR_T +#ifndef _RWSTD_NO_WCHAR_T _TEST_EXPORT wchar_t* @@ -829,35 +887,63 @@ } if (0 == s2) - return strlen (s1); + return rw_match (s1, (char*)0, len); + + const char* p1 = s1; + const wchar_t* p2 = s2; + + // the length of the initial subsequence of s1 and s2 + // consisting solely of characters that compare equal + size_t count = 0; + + size_t n1 = 0; + size_t n2 = 0; + + for (wchar_t ch1, ch2; count < len; ) { + + while (0 == n1) { + ch1 = wchar_t (UChar (*p1++)); + + if ('@' == p1 [0] && isdigit (p1 [1])) { + + char* end; + n1 = strtoul (p1 + 1, &end, 10); + p1 = end; + } + else + n1 = 1; + } + + ch2 = *p2++; + n2 = 1; - const char* const s1_save = s1; + if (ch1 != ch2) + break; - char s1_buf [256]; - size_t s1_len = sizeof s1_buf; - - // see if the first string contains '@' and might need - // to be expanded (see rw_expand() for details) - if ( _RWSTD_SIZE_MAX == len && strchr (s1, '@') - || _RWSTD_SIZE_MAX != len && memchr (s1, '@', len)) { - s1 = rw_expand (s1_buf, s1, len, &s1_len); - len = s1_len; - } + if (n1 < n2) { + // the repeat count specified by the first directive + // is less than the repeat count given by the second + count += n1; + n2 -= n1; + n1 = 0; - size_t n = 0; + } + else if (n2 <= n1) { + // the repeat count specified by the second directive + // is less than or equal than that given by the first + count += n2; + n1 -= n2; + n2 = 0; + } - for ( ; n != len && UChar (s1 [n]) == unsigned (s2 [n]); ++n) { - if (_RWSTD_SIZE_MAX == len && '\0' == s1 [n]) + if (_RWSTD_SIZE_MAX == len && L'\0' == ch1) break; } - if (s1 && s1_save != s1 && s1_buf != s1) - delete[] s1; - - return n; + return len < count ? len : count; } -#endif // _RWSTD_WCHAR_T +#endif // _RWSTD_NO_WCHAR_T _TEST_EXPORT @@ -958,32 +1044,62 @@ } if (0 == s2) - return strlen (s1); + return rw_match (s1, (char*)0, len); + + const char* p1 = s1; + const UserChar* p2 = s2; + + // the length of the initial subsequence of s1 and s2 + // consisting solely of characters that compare equal + size_t count = 0; + + size_t n1 = 0; + size_t n2 = 0; + + char ch1; + + for (UserChar ch2; count < len; ) { + + while (0 == n1) { + ch1 = wchar_t (UChar (*p1++)); + + if ('@' == p1 [0] && isdigit (p1 [1])) { + + char* end; + n1 = strtoul (p1 + 1, &end, 10); + p1 = end; + } + else + n1 = 1; + } + + ch2 = *p2++; + n2 = 1; - const char* const s1_save = s1; + if (ch1 != ch2.c) + break; - char s1_buf [256]; - size_t s1_len = sizeof s1_buf; - - // see if the first string contains '@' and might need - // to be expanded (see rw_expand() for details) - if ( _RWSTD_SIZE_MAX == len && strchr (s1, '@') - || _RWSTD_SIZE_MAX != len && memchr (s1, '@', len)) { - s1 = rw_expand (s1_buf, s1, len, &s1_len); - len = s1_len; - } + if (n1 < n2) { + // the repeat count specified by the first directive + // is less than the repeat count given by the second + count += n1; + n2 -= n1; + n1 = 0; - size_t n = 0; + } + else if (n2 <= n1) { + // the repeat count specified by the second directive + // is less than or equal than that given by the first + count += n2; + n1 -= n2; + n2 = 0; + } - for ( ; n != len && UChar (s1 [n]) == s2 [n].c; ++n) { - if (_RWSTD_SIZE_MAX == len && '\0' == s1 [n]) + if (_RWSTD_SIZE_MAX == len && L'\0' == ch1) break; } - if (s1 && s1_save != s1 && s1_buf != s1) - delete[] s1; - - return n; + return len < count ? len : count; } /**************************************************************************/ --------------080304090904020308040307 Content-Type: text/plain; name="00_char.cpp.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="00_char.cpp.diff" ==== //stdlib/dev/tests/stdlib/test/char.cpp#11 - /build/sebor/dev/stdlib/tests/test/00_char.cpp ==== @@ -732,33 +732,6 @@ /***********************************************************************/ -static size_t -length (const char *s) -{ - return s ? strlen (s) : 0; -} - - -static size_t -length (const wchar_t *ws) -{ - size_t len = 0; - if (ws) - for (len = 0; ws [len]; ++len); - return len; -} - - -static size_t -length (const UserChar *us) -{ - size_t len = 0; - if (us) - for (len = 0; us [len].f || us [len].c; ++len); - return len; -} - - static const UserChar* make_user_string (const char *s, size_t len) { @@ -786,48 +759,108 @@ ////////////////////////////////////////////////////////////////// rw_info (0, 0, 0, "rw_match(char*, const char*, size_t)"); - const size_t size_max = _RWSTD_SIZE_MAX; size_t result; -#define LEN(T, s, len) \ - int (size_max == size_t (len) ? length ((const T*)s) : size_t (len)) - #undef TEST #define TEST(s1, s2, len, expect) \ result = rw_match ((const char*)s1, (const char*)s2, size_t (len)); \ rw_assert (expect == result, \ 0, __LINE__, \ "rw_match(%{#*s}, %{#*s}, %zu) == %zu, got %zu", \ - LEN (char, s1, len), s1, LEN (char, s2, len), \ - s2, len, expect, result) + int (sizeof s1 - 1), s1, int (sizeof s2 - 1), s2, len, \ + expect, result) TEST (0, 0, -1, 0); TEST ("", 0, -1, 0); TEST (0, "", -1, 0); - TEST ("", "", -1, 0); + TEST ("", "", -1, 1); + + // same as above but using the @ directive + TEST ("a@0", "", -1, 1); + TEST ("", "b@0", -1, 1); + TEST ("a@0", "b@0", -1, 1); - // when invoked with NULL as the first string returns - // the length of the second string (if non-NULL) + // when invoked with NULL as the first argument returns + // the length of the second string with all directives + // expanded TEST (0, "a", -1, 1); TEST (0, "ab", -1, 2); TEST (0, "abc", -1, 3); + TEST (0, "a@0", -1, 0); + TEST (0, "a@1", -1, 1); + TEST (0, "a@2", -1, 2); + TEST (0, "a@2b@0", -1, 2); + TEST (0, "a@2b@1", -1, 3); + TEST (0, "a@2b@2", -1, 4); // same as above but with the arguments reversed - TEST ("a", 0, -1, 1); - TEST ("ab", 0, -1, 2); - TEST ("abc", 0, -1, 3); + TEST ("a", 0, -1, 1); + TEST ("ab", 0, -1, 2); + TEST ("abc", 0, -1, 3); + TEST ("a@0", 0, -1, 0); + TEST ("a@1", 0, -1, 1); + TEST ("a@2", 0, -1, 2); + TEST ("a@2b@0", 0, -1, 2); + TEST ("a@2b@1", 0, -1, 3); + TEST ("a@2b@2", 0, -1, 4); TEST ("", "a", -1, 0); TEST ("a", "", -1, 0); - TEST ("a", "a", -1, 1); + TEST ("a", "a", -1, 2); + + // same as above but using the @ directive + TEST ("", "a@1", -1, 0); + TEST ("a@1", "", -1, 0); + TEST ("a", "a@1", -1, 2); + TEST ("a@1", "a", -1, 2); + TEST ("a@1", "a@1", -1, 2); + + TEST ("\0ab", "\0ac", 2, 2); + TEST ("\0@0ab", "ab", 2, 2); + TEST ("\0@0a\0@0b", "ab", 2, 2); + TEST ("\0@1ab", "\0@1ac", 2, 2); + TEST ("\0@1ab", "\0@1ac", 2, 2); - TEST ("a\0bc", "a\0bd", -1, 1); + TEST ("a\0bc", "a\0bd", -1, 2); TEST ("a\0bc", "a\0bd", 0, 0); TEST ("a\0bc", "a\0bd", 1, 1); TEST ("a\0bc", "a\0bd", 2, 2); TEST ("a\0bc", "a\0bd", 3, 3); TEST ("a\0bc", "a\0bd", 4, 3); + TEST ("aaaaa", "a@5", -1, 6); + TEST ("aaaaaa@0", "a@5", -1, 6); + TEST ("aaaaa@1", "a@5", -1, 6); + TEST ("aaaa@2", "a@5", -1, 6); + TEST ("aaa@3", "a@5", -1, 6); + TEST ("aa@4", "a@5", -1, 6); + TEST ("a@5", "a@5", -1, 6); + TEST ("a@4a", "a@5", -1, 6); + TEST ("a@3aa", "a@5", -1, 6); + TEST ("a@2aaa", "a@5", -1, 6); + TEST ("a@1aaaa", "a@5", -1, 6); + TEST ("a@0aaaaa", "a@5", -1, 6); + + TEST ("a@0a@1a@2a@3", "a@3a@2a@1a@0", -1, 7); + TEST ("a@0a@1a@2a@3", "a@3a@2a@1a@0", 0, 0); + TEST ("a@0a@1a@2a@3", "a@3a@2a@1a@0", 1, 1); + TEST ("a@0a@1a@2a@3", "a@3a@2a@1a@0", 2, 2); + TEST ("a@0a@1a@2a@3", "a@3a@2a@1a@0", 3, 3); + TEST ("a@0a@1a@2a@3", "a@3a@2a@1a@0", 4, 4); + TEST ("a@0a@1a@2a@3", "a@3a@2a@1a@0", 5, 5); + TEST ("a@0a@1a@2a@3", "a@3a@2a@1a@0", 6, 6); + TEST ("a@0a@1a@2a@3", "a@3a@2a@1a@0", 7, 7); + + TEST ("a@0\0a@1a@2\0a@3\0", "\0a@3\0a@2a@1a@0\0", 10, 10); + TEST ("a@0*a@1a@2\0a@3\0", "\0a@3\0a@2a@1a@0\0", 10, 0); + TEST ("a@0\0a@1a@2*a@3\0", "\0a@3\0a@2a@1a@0\0", 10, 4); + TEST ("a@0\0a@1a@2\0a@3*", "\0a@3\0a@2a@1a@0\0", 10, 8); + TEST ("a@11aa@12aaa@13b", "a@13aa@12aaa@11c", -1, 39); + + // invalid directives + TEST ("a@b", "a@0a@b", -1, 4); + TEST ("a@b@c", "a@0a@b@c", -1, 6); + ////////////////////////////////////////////////////////////////// rw_info (0, 0, 0, "rw_match(char*, const wchar_t*, size_t)"); @@ -839,33 +872,92 @@ rw_assert (expect == result, \ 0, __LINE__, \ "rw_match(%{#*s}, L%{#*ls}, %zu) == %zu, got %zu", \ - LEN (char, s1, len), s1, LEN (wchar_t, s2, len), s2, \ - len, expect, result) + int (sizeof s1 - 1), s1, \ + int (sizeof (s2) / sizeof *(s2) - 1), s2, len, \ + expect, result) + + TEST (0, (wchar_t*)0, -1, 0); + TEST ("", (wchar_t*)0, -1, 0); + TEST (0, L"", -1, 0); + TEST ("", L"", -1, 1); + + // same as above but using the @ directive + TEST ("a@0", L"", -1, 1); + TEST ("", L"", -1, 1); + TEST ("a@0", L"", -1, 1); + + // when invoked with NULL as the first argument returns + // the length of the second string with all directives + // expanded + TEST (0, L"a", -1, 1); + TEST (0, L"ab", -1, 2); + TEST (0, L"abc", -1, 3); + TEST (0, L"abcd", -1, 4); + TEST (0, L"abcde", -1, 5); + TEST (0, L"abcdef", -1, 6); - TEST (0, 0, -1, 0); - TEST ("", 0, -1, 0); - TEST (0, L"", -1, 0); - TEST ("", L"", -1, 0); + // same as above but with the arguments reversed + TEST ("a", (wchar_t*)0, -1, 1); + TEST ("ab", (wchar_t*)0, -1, 2); + TEST ("abc", (wchar_t*)0, -1, 3); + TEST ("a@0", (wchar_t*)0, -1, 0); + TEST ("a@1", (wchar_t*)0, -1, 1); + TEST ("a@2", (wchar_t*)0, -1, 2); + TEST ("a@2b@0", (wchar_t*)0, -1, 2); + TEST ("a@2b@1", (wchar_t*)0, -1, 3); + TEST ("a@2b@2", (wchar_t*)0, -1, 4); - TEST (0, L"a", -1, 1); - TEST (0, L"ab", -1, 2); - TEST (0, L"abc", -1, 3); + TEST ("", L"a", -1, 0); + TEST ("a", L"", -1, 0); + TEST ("a", L"a", -1, 2); - TEST ("a", 0, -1, 1); - TEST ("ab", 0, -1, 2); - TEST ("abc", 0, -1, 3); + // same as above but using the @ directive + TEST ("a@1", L"", -1, 0); + TEST ("a@1", L"a", -1, 2); - TEST ("", L"a", -1, 0); - TEST ("a", L"", -1, 0); - TEST ("a", L"a", -1, 1); + TEST ("\0ab", L"\0ac", 2, 2); + TEST ("\0@0ab", L"ab", 2, 2); + TEST ("\0@0a\0@0b", L"ab", 2, 2); - TEST ("a\0bc", L"a\0bd", -1, 1); + TEST ("a\0bc", L"a\0bd", -1, 2); TEST ("a\0bc", L"a\0bd", 0, 0); TEST ("a\0bc", L"a\0bd", 1, 1); TEST ("a\0bc", L"a\0bd", 2, 2); TEST ("a\0bc", L"a\0bd", 3, 3); TEST ("a\0bc", L"a\0bd", 4, 3); + TEST ("aaaaa", L"aaaaa", -1, 6); + TEST ("aaaaaa@0", L"aaaaa", -1, 6); + TEST ("aaaaa@1", L"aaaaa", -1, 6); + TEST ("aaaa@2", L"aaaaa", -1, 6); + TEST ("aaa@3", L"aaaaa", -1, 6); + TEST ("aa@4", L"aaaaa", -1, 6); + TEST ("a@5", L"aaaaa", -1, 6); + TEST ("a@4a", L"aaaaa", -1, 6); + TEST ("a@3aa", L"aaaaa", -1, 6); + TEST ("a@2aaa", L"aaaaa", -1, 6); + TEST ("a@1aaaa", L"aaaaa", -1, 6); + TEST ("a@0aaaaa", L"aaaaa", -1, 6); + + TEST ("a@0a@1a@2a@3", L"aaaaaa", -1, 7); + TEST ("a@0a@1a@2a@3", L"aaaaaa", 0, 0); + TEST ("a@0a@1a@2a@3", L"aaaaaa", 1, 1); + TEST ("a@0a@1a@2a@3", L"aaaaaa", 2, 2); + TEST ("a@0a@1a@2a@3", L"aaaaaa", 3, 3); + TEST ("a@0a@1a@2a@3", L"aaaaaa", 4, 4); + TEST ("a@0a@1a@2a@3", L"aaaaaa", 5, 5); + TEST ("a@0a@1a@2a@3", L"aaaaaa", 6, 6); + TEST ("a@0a@1a@2a@3", L"aaaaaa", 7, 7); + + TEST ("a@0\0a@1a@2\0a@3\0", L"\0aaa\0aaa\0", 10, 10); + TEST ("a@0*a@1a@2\0a@3\0", L"\0aaa\0aaa\0", 10, 0); + TEST ("a@0\0a@1a@2*a@3\0", L"\0aaa\0aaa\0", 10, 4); + TEST ("a@0\0a@1a@2\0a@3*", L"\0aaa\0aaa\0", 10, 8); + + // invalid directives + TEST ("a@b", L"a@b", -1, 4); + TEST ("a@b@c", L"a@b@c", -1, 6); + #else // if defined (_RWSTD_NO_WCHAR_T) rw_note (0, 0, 0, "_RWSTD_NO_WCHAR_T #defined, wchar_t test disabled"); @@ -876,38 +968,86 @@ rw_info (0, 0, 0, "rw_match(char*, const UserChar*, size_t)"); #undef TEST -#define TEST(s1, s2, len, expect) \ - result = rw_match ((const char*)s1, \ - make_user_string (s2, sizeof (s2)), size_t (len)); \ - rw_assert (expect == result, \ - 0, __LINE__, \ - "rw_match(%{#*s}, %{#*s}, %zu) == %zu, got %zu", \ - LEN (char, s1, len), s1, LEN (char, s2, len), s2, \ +#define TEST(s1, s2, len, expect) \ + result = rw_match ((const char*)s1, \ + make_user_string (s2, sizeof (s2)), size_t (len)); \ + rw_assert (expect == result, \ + 0, __LINE__, \ + "rw_match(%{#*s}, %{#*s}, %zu) == %zu, got %zu", \ + int (sizeof s1 - 1), s1, int (sizeof s2 - 1), s2, len, \ expect, result) - TEST (0, 0, -1, 0); - TEST ("", 0, -1, 0); - TEST (0, "", -1, 0); - TEST ("", "", -1, 0); + TEST (0, 0, -1, 0); + TEST ("", 0, -1, 0); + TEST (0, "", -1, 0); + TEST ("", "", -1, 1); + + // same as above but using the @ directive + TEST ("a@0", "", -1, 1); + TEST ("", "", -1, 1); + TEST ("a@0", "", -1, 1); + + // when invoked with NULL as the first string returns + // the length of the second string (if non-NULL) + TEST (0, "a", -1, 1); + TEST (0, "ab", -1, 2); + TEST (0, "abc", -1, 3); + + // same as above but with the arguments reversed + TEST ("a", 0, -1, 1); + TEST ("ab", 0, -1, 2); + TEST ("abc", 0, -1, 3); - TEST (0, "a", -1, 1); - TEST (0, "ab", -1, 2); - TEST (0, "abc", -1, 3); + TEST ("", "a", -1, 0); + TEST ("a", "", -1, 0); + TEST ("a", "a", -1, 2); - TEST ("a", 0, -1, 1); - TEST ("ab", 0, -1, 2); - TEST ("abc", 0, -1, 3); + // same as above but using the @ directive + TEST ("a@1", "", -1, 0); + TEST ("a@1", "a", -1, 2); - TEST ("", "a", -1, 0); - TEST ("a", "", -1, 0); - TEST ("a", "a", -1, 1); + TEST ("\0ab", "\0ac", 2, 2); + TEST ("\0@0ab", "ab", 2, 2); + TEST ("\0@0a\0@0b", "ab", 2, 2); - TEST ("a\0bc", "a\0bd", -1, 1); + TEST ("a\0bc", "a\0bd", -1, 2); TEST ("a\0bc", "a\0bd", 0, 0); TEST ("a\0bc", "a\0bd", 1, 1); TEST ("a\0bc", "a\0bd", 2, 2); TEST ("a\0bc", "a\0bd", 3, 3); TEST ("a\0bc", "a\0bd", 4, 3); + + TEST ("aaaaa", "aaaaa", -1, 6); + TEST ("aaaaaa@0", "aaaaa", -1, 6); + TEST ("aaaaa@1", "aaaaa", -1, 6); + TEST ("aaaa@2", "aaaaa", -1, 6); + TEST ("aaa@3", "aaaaa", -1, 6); + TEST ("aa@4", "aaaaa", -1, 6); + TEST ("a@5", "aaaaa", -1, 6); + TEST ("a@4a", "aaaaa", -1, 6); + TEST ("a@3aa", "aaaaa", -1, 6); + TEST ("a@2aaa", "aaaaa", -1, 6); + TEST ("a@1aaaa", "aaaaa", -1, 6); + TEST ("a@0aaaaa", "aaaaa", -1, 6); + + TEST ("a@0a@1a@2a@3", "aaaaaa", -1, 7); + TEST ("a@0a@1a@2a@3", "aaaaaa", 0, 0); + TEST ("a@0a@1a@2a@3", "aaaaaa", 1, 1); + TEST ("a@0a@1a@2a@3", "aaaaaa", 2, 2); + TEST ("a@0a@1a@2a@3", "aaaaaa", 3, 3); + TEST ("a@0a@1a@2a@3", "aaaaaa", 4, 4); + TEST ("a@0a@1a@2a@3", "aaaaaa", 5, 5); + TEST ("a@0a@1a@2a@3", "aaaaaa", 6, 6); + TEST ("a@0a@1a@2a@3", "aaaaaa", 7, 7); + + TEST ("a@0\0a@1a@2\0a@3\0", "\0aaa\0aaa\0", 10, 10); + TEST ("a@0*a@1a@2\0a@3\0", "\0aaa\0aaa\0", 10, 0); + TEST ("a@0\0a@1a@2*a@3\0", "\0aaa\0aaa\0", 10, 4); + TEST ("a@0\0a@1a@2\0a@3*", "\0aaa\0aaa\0", 10, 8); + + // invalid directives + TEST ("a@b", "a@b", -1, 4); + TEST ("a@b@c", "a@b@c", -1, 6); } /***********************************************************************/ --------------080304090904020308040307--