You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by se...@apache.org on 2006/05/08 18:22:45 UTC

svn commit: r405086 - in /incubator/stdcxx/trunk/tests: include/rw_char.h self/0.char.cpp src/char.cpp

Author: sebor
Date: Mon May  8 09:22:42 2006
New Revision: 405086

URL: http://svn.apache.org/viewcvs?rev=405086&view=rev
Log:
2006-05-08  Martin Sebor  <se...@roguewave.com>

	* rw_char.h (rw_expand): Declared a set of new utility overloads.
	* src/char.cpp (rw_expand): Defined the above.
	* test/char.cpp (test_rw_expand): (Partially) exercised the above.

Modified:
    incubator/stdcxx/trunk/tests/include/rw_char.h
    incubator/stdcxx/trunk/tests/self/0.char.cpp
    incubator/stdcxx/trunk/tests/src/char.cpp

Modified: incubator/stdcxx/trunk/tests/include/rw_char.h
URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/include/rw_char.h?rev=405086&r1=405085&r2=405086&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/include/rw_char.h (original)
+++ incubator/stdcxx/trunk/tests/include/rw_char.h Mon May  8 09:22:42 2006
@@ -385,6 +385,25 @@
                 const char*   /* src */,
                 _RWSTD_SIZE_T /* len */ = _RWSTD_SIZE_MAX);
 
+// rw_expand() interprets string src as a sequence of directives and
+// widens the result of their processing into the provided buffer dst
+// when (dst != 0), otherwise into a dynamically allocated buffer of
+// sufficient size
+// each directive consists of a character C, optionally followed by
+// the '@' sign followed by a non-negative decimal number N; the result
+// of the processing of a directive is N consecutive copies of the
+// character C where (N = 1) when the '@' is absent
+// when (dst_len != 0) the function sets *dst_len to the number of
+// produced characters not counting the terminating NUL
+// the function returns the dynamically allocated buffer; the caller
+// must deallocate the buffer using the delete expression
+_TEST_EXPORT
+char* rw_expand (char*          /* dst     */,
+                 const char*    /* src     */,
+                 _RWSTD_SIZE_T  /* src_len */ = _RWSTD_SIZE_MAX,
+                 _RWSTD_SIZE_T* /* dst_len */ = 0);
+
+
 // rw_narrow() narrows successive elements of src into the buffer dst
 // (see rw_widen() for details)
 _TEST_EXPORT
@@ -409,6 +428,12 @@
 wchar_t* rw_widen (wchar_t*, const char*, _RWSTD_SIZE_T = _RWSTD_SIZE_MAX);
 
 _TEST_EXPORT
+wchar_t* rw_expand (wchar_t*       /* dst     */,
+                    const char*    /* src     */,
+                    _RWSTD_SIZE_T  /* src_len */ = _RWSTD_SIZE_MAX,
+                    _RWSTD_SIZE_T* /* dst_len */ = 0);
+
+_TEST_EXPORT
 char* rw_narrow (char*, const wchar_t*, _RWSTD_SIZE_T = _RWSTD_SIZE_MAX);
 
 _TEST_EXPORT
@@ -419,6 +444,12 @@
 
 _TEST_EXPORT
 UserChar* rw_widen (UserChar*, const char*, _RWSTD_SIZE_T = _RWSTD_SIZE_MAX);
+
+_TEST_EXPORT
+UserChar* rw_expand (UserChar*      /* dst     */,
+                     const char*    /* src     */,
+                     _RWSTD_SIZE_T  /* src_len */ = _RWSTD_SIZE_MAX,
+                     _RWSTD_SIZE_T* /* dst_len */ = 0);
 
 _TEST_EXPORT
 char* rw_narrow (char*, const UserChar*, _RWSTD_SIZE_T = _RWSTD_SIZE_MAX);

Modified: incubator/stdcxx/trunk/tests/self/0.char.cpp
URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/self/0.char.cpp?rev=405086&r1=405085&r2=405086&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/self/0.char.cpp (original)
+++ incubator/stdcxx/trunk/tests/self/0.char.cpp Mon May  8 09:22:42 2006
@@ -499,6 +499,92 @@
 /***********************************************************************/
 
 static void
+test_rw_expand ()
+{
+    //////////////////////////////////////////////////////////////////
+    rw_info (0, 0, 0, "rw_expand(char*, const char*, size_t, size_t*)");
+
+    char *result;
+    size_t len;
+
+#undef TEST
+#define TEST(str, expstr, size)                                         \
+    result = rw_expand ((char*)0, str, sizeof str - 1, &len);           \
+    rw_assert (0 == memcmp (result, expstr, size + 1), 0, __LINE__,     \
+               "rw_expand(0, %#s, %zu, ...) == %#s, got %#s",           \
+               str, sizeof str -1, expstr, result);
+
+    TEST ("",          "",          0);
+    TEST ("a",         "a",         1);
+    TEST ("ab",        "ab",        2);
+    TEST ("abc",       "abc",       3);
+    TEST ("a\0b",      "a\0b",      3);
+    TEST ("a\0b\0c\0", "a\0b\0c\0", 6);
+
+    TEST ("a@0",       "",          0);
+    TEST ("a@1",       "a",         1);
+    TEST ("a@2",       "aa",        2);
+    TEST ("a@3",       "aaa",       3);
+    TEST ("a@1b",      "ab",        2);
+    TEST ("a@2b",      "aab",       3);
+    TEST ("a@3b",      "aaab",      4);
+    TEST ("a@3bc",     "aaabc",     5);
+    TEST ("a@3b@1c",   "aaabc",     5);
+    TEST ("a@3b@2c",   "aaabbc",    6);
+    TEST ("a@3b@2c@1", "aaabbc",    6);
+    TEST ("a@3b@3c@2", "aaabbbcc",  8);
+
+    //////////////////////////////////////////////////////////////////
+    rw_info (0, 0, 0, "rw_expand(wchar_t*, const char*, size_t, size_t*)");
+
+#ifndef _RWSTD_NO_WCHAR_T
+
+    wchar_t *wresult;
+
+#  undef TEST
+#  define TEST(str, expstr, size)                                       \
+      wresult = rw_expand ((wchar_t*)0, str, sizeof str - 1, &len);     \
+      rw_assert (0 == memcmp (wresult, expstr, size + 1), 0, __LINE__,  \
+                 "rw_expand(0, %#s, %zu, ...) == %#ls, got %#ls",       \
+                 str, sizeof str -1, expstr, wresult);
+
+    TEST ("",          L"",          0);
+    TEST ("a",         L"a",         1);
+    TEST ("ab",        L"ab",        2);
+    TEST ("abc",       L"abc",       3);
+    TEST ("a\0b",      L"a\0b",      3);
+    TEST ("a\0b\0c\0", L"a\0b\0c\0", 6);
+
+    TEST ("a@0",       L"",          0);
+    TEST ("a@1",       L"a",         1);
+    TEST ("a@2",       L"aa",        2);
+    TEST ("a@3",       L"aaa",       3);
+    TEST ("a@1b",      L"ab",        2);
+    TEST ("a@2b",      L"aab",       3);
+    TEST ("a@3b",      L"aaab",      4);
+    TEST ("a@3bc",     L"aaabc",     5);
+    TEST ("a@3b@1c",   L"aaabc",     5);
+    TEST ("a@3b@2c",   L"aaabbc",    6);
+    TEST ("a@3b@2c@1", L"aaabbc",    6);
+    TEST ("a@3b@3c@2", L"aaabbbcc",  8);
+
+#else   // if defined (_RWSTD_NO_WCHAR_T)
+
+    rw_note (0, 0, 0, "_RWSTD_NO_WCHAR_T #defined, wchar_t test disabled");
+
+#endif   // _RWSTD_NO_WCHAR_T
+
+    //////////////////////////////////////////////////////////////////
+    rw_info (0, 0, 0, "rw_expand(UserChar*, const char*, size_t, size_t*)");
+
+    rw_warn (0, 0, 0, "rw_expand(UserChar*, const char*, size_t, size_t*) "
+             "not exercised");
+}
+
+
+/***********************************************************************/
+
+static void
 test_rw_narrow ()
 {
     //////////////////////////////////////////////////////////////////
@@ -849,6 +935,7 @@
 static int no_user_traits_wchar_t;
 static int no_user_traits_user_char;
 static int no_rw_widen;
+static int no_rw_expand;
 static int no_rw_narrow;
 static int no_rw_match;
 static int no_formatting;
@@ -891,6 +978,7 @@
             test_ ## fun ()
 
     TEST (rw_widen);
+    TEST (rw_expand);
     TEST (rw_narrow);
     TEST (rw_match);
     TEST (formatting);
@@ -911,6 +999,7 @@
                     "|-no-UserTraits<wchar_t># "
                     "|-no-UserTraits<UserChar># "
                     "|-no-rw_widen# "
+                    "|-no-expand# "
                     "|-no-rw_narrow# "
                     "|-no-rw_macth# "
                     "|-no-formatting#",
@@ -919,6 +1008,7 @@
                     &no_user_traits_wchar_t,
                     &no_user_traits_user_char,
                     &no_rw_widen,
+                    &no_rw_expand, 
                     &no_rw_narrow,
                     &no_rw_match,
                     &no_formatting,

Modified: incubator/stdcxx/trunk/tests/src/char.cpp
URL: http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/tests/src/char.cpp?rev=405086&r1=405085&r2=405086&view=diff
==============================================================================
--- incubator/stdcxx/trunk/tests/src/char.cpp (original)
+++ incubator/stdcxx/trunk/tests/src/char.cpp Mon May  8 09:22:42 2006
@@ -263,6 +263,85 @@
 
 _TEST_EXPORT
 char*
+rw_expand (char *dst, const char *src, size_t src_len /* = SIZE_MAX */,
+           size_t *dst_len /* = 0 */)
+{
+    size_t bufsize = dst ? _RWSTD_SIZE_MAX : 0;
+    size_t buflen  = 0;
+
+    if (_RWSTD_SIZE_MAX == src_len)
+        src_len = strlen (src);
+
+    char *pnext = dst;
+
+    for (const char *psrc = src; ; ) {
+
+        const char c = *psrc;
+
+        unsigned long count;
+
+        if ('@' == psrc [1] && isdigit (psrc [2])) {
+            // process directive
+            psrc += 2;
+
+            char *end = 0;
+            count = strtoul (psrc, &end, 10);
+
+            src_len -= (end - psrc) + 2;
+
+            psrc = end;
+
+        }
+        else {
+            count = 1;
+
+            // decrement length unless it's already 0
+            if (src_len)
+                --src_len;
+
+            ++psrc;
+        }
+
+        if (bufsize - buflen <= count) {
+            // increase the size of the buffer
+            bufsize = (bufsize + count) * 2;
+            if (bufsize < 128)
+                bufsize = 128;
+
+            // allocate larger buffer
+            char* const tmp = new char [bufsize];
+
+            // copy old buffer into new one
+            memcpy (tmp, dst, buflen);
+
+            // dispose of old buffer
+            delete[] dst;
+
+            dst   = tmp;
+            pnext = dst + buflen;
+        }
+
+        typedef unsigned char UChar;
+        memset (pnext, UChar (c), count);
+
+        pnext += count;
+        buflen += count;
+
+        if (0 == src_len)
+            break;
+    }
+
+    *pnext = '\0';
+
+    if (dst_len)
+        *dst_len = buflen;
+
+    return dst;
+}
+
+
+_TEST_EXPORT
+char*
 rw_narrow (char *dst, const char *src, size_t len /* = SIZE_MAX */)
 {
     return rw_widen (dst, src, len);
@@ -330,6 +409,85 @@
 
 
 _TEST_EXPORT
+wchar_t*
+rw_expand (wchar_t *dst, const char *src, size_t src_len /* = SIZE_MAX */,
+           size_t *dst_len /* = 0 */)
+{
+    size_t bufsize = dst ? _RWSTD_SIZE_MAX : 0;
+    size_t buflen  = 0;
+
+    if (_RWSTD_SIZE_MAX == src_len)
+        src_len = strlen (src);
+
+    wchar_t *pnext = dst;
+
+    for (const char *psrc = src; ; ) {
+
+        const char c = *psrc;
+
+        unsigned long count;
+
+        if ('@' == psrc [1] && isdigit (psrc [2])) {
+            // process directive 
+           psrc += 2;
+
+            char *end = 0;
+            count = strtoul (psrc, &end, 10);
+
+            src_len -= (end - psrc) + 2;
+
+            psrc = end;
+
+        }
+        else {
+            count = 1;
+
+            // decrement length unless it's already 0
+            if (src_len)
+                --src_len;
+
+            ++psrc;
+        }
+
+        if (bufsize - buflen <= count) {
+            // increase the size of the buffer
+            bufsize = (bufsize + count) * 2;
+            if (bufsize < 128)
+                bufsize = 128;
+
+            // allocate larger buffer
+            wchar_t* const tmp = new wchar_t [bufsize];
+
+            // copy old buffer into new one
+            memcpy (tmp, dst, buflen * sizeof *tmp);
+
+            // dispose of old buffer
+            delete[] dst;
+
+            dst   = tmp;
+            pnext = dst + buflen;
+        }
+
+        typedef unsigned char UChar;
+        for (size_t i = 0; i != count; ++i)
+            *pnext++ = wchar_t (UChar (c));
+
+        buflen += count;
+
+        if (0 == src_len)
+            break;
+    }
+
+    *pnext = L'\0';
+
+    if (dst_len)
+        *dst_len = buflen;
+
+    return dst;
+}
+
+
+_TEST_EXPORT
 char*
 rw_narrow (char *dst, const wchar_t *src, size_t len /* = SIZE_MAX */)
 {
@@ -432,6 +590,88 @@
             memset (dst, 0, len * sizeof *dst);
         }
     }
+
+    return dst;
+}
+
+
+_TEST_EXPORT
+UserChar*
+rw_expand (UserChar *dst, const char *src, size_t src_len /* = SIZE_MAX */,
+           size_t *dst_len /* = 0 */)
+{
+    size_t bufsize = dst ? _RWSTD_SIZE_MAX : 0;
+    size_t buflen  = 0;
+
+    if (_RWSTD_SIZE_MAX == src_len)
+        src_len = strlen (src);
+
+    UserChar *pnext = dst;
+
+    for (const char *psrc = src; ; ) {
+
+        const char c = *psrc;
+
+        unsigned long count;
+
+        if ('@' == psrc [1] && isdigit (psrc [2])) {
+            // process directive 
+            psrc += 2;
+
+            char *end = 0;
+            count = strtoul (psrc, &end, 10);
+
+            src_len -= (end - psrc) + 2;
+
+            psrc = end;
+
+        }
+        else {
+            count = 1;
+
+            // decrement length unless it's already 0
+            if (src_len)
+                --src_len;
+
+            ++psrc;
+        }
+
+        if (bufsize - buflen <= count) {
+            // increase the size of the buffer
+            bufsize = (bufsize + count) * 2;
+            if (bufsize < 128)
+                bufsize = 128;
+
+            // allocate larger buffer
+            UserChar* const tmp = new UserChar [bufsize];
+
+            // copy old buffer into new one
+            memcpy (tmp, dst, buflen * sizeof *tmp);
+
+            // dispose of old buffer
+            delete[] dst;
+
+            dst   = tmp;
+            pnext = dst + buflen;
+        }
+
+        typedef unsigned char UChar;
+        for (size_t i = 0; i != count; ++i) {
+            pnext->f = 0;
+            pnext->c = UChar (c);
+            ++pnext;
+        }
+
+        buflen += count;
+
+        if (0 == src_len)
+            break;
+    }
+
+    *pnext = UserChar::eos ();
+
+    if (dst_len)
+        *dst_len = buflen;
 
     return dst;
 }