Author: vitek
Date: Mon Apr 14 10:15:49 2008
New Revision: 647908

URL: http://svn.apache.org/viewvc?rev=647908&view=rev
Log:
2008-04-14  Travis Vitek  <[EMAIL PROTECTED]>

        STDCXX-857
        * tests/src/fmt_defs.h: Add flag to struct Buffer to indicate
        who owns the allocated buffer.
        * tests/src/printf.cpp (_rw_bufcat): Simplify logic to get
        new buffer size. Avoid checking guard bytes and deallocating
        buffer that we do not own.
        (rw_vasnprintf): Set flag indicating that the caller owns the
        supplied buffer.
        (_rw_fmtarray): Ditto.
        (_rw_fmt_expr): Ditto.
        * tests/self/0.printf.cpp (test_reallocate): Add new test to
        verify buffer reallocation works as expected.

Modified:
    stdcxx/trunk/tests/self/0.printf.cpp
    stdcxx/trunk/tests/src/fmt_defs.h
    stdcxx/trunk/tests/src/printf.cpp

Modified: stdcxx/trunk/tests/self/0.printf.cpp
URL: 
http://svn.apache.org/viewvc/stdcxx/trunk/tests/self/0.printf.cpp?rev=647908&r1=647907&r2=647908&view=diff
==============================================================================
--- stdcxx/trunk/tests/self/0.printf.cpp (original)
+++ stdcxx/trunk/tests/self/0.printf.cpp Mon Apr 14 10:15:49 2008
@@ -3279,6 +3279,38 @@
 
 /***********************************************************************/
 
+static void
+test_reallocate ()
+{
+    static const char abc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+    char buffer [4] = { 0 };
+    char *buf = buffer;
+
+    size_t bufsize = sizeof buffer;
+
+    const int n = rw_asnprintf (&buf, &bufsize, "%s", abc);
+
+    if (n != 26 || strcmp (abc, buf)) {
+        ++nfailures;
+
+        fprintf (stderr, "# Assertion failed on line %d: "
+                         "rw_asnprintf(...) == \"%s\", got \"%s\"\n",
+                         __LINE__, abc, buf);
+    }
+
+    if (buf != buffer)
+        free (buf);
+    else {
+        ++nfailures;
+
+        fprintf (stderr, "# Assertion failed on line %d: "
+                         "rw_asnprintf(...) failed to reallocate buffer\n",
+                         __LINE__);
+    }
+}
+
+
 int main ()
 {
     test_percent ();
@@ -3326,6 +3358,8 @@
     test_nested_format ();
 
     test_malformed_directives ();
+
+    test_reallocate ();
 
     //////////////////////////////////////////////////////////////////
     if (nfailures) {

Modified: stdcxx/trunk/tests/src/fmt_defs.h
URL: 
http://svn.apache.org/viewvc/stdcxx/trunk/tests/src/fmt_defs.h?rev=647908&r1=647907&r2=647908&view=diff
==============================================================================
--- stdcxx/trunk/tests/src/fmt_defs.h (original)
+++ stdcxx/trunk/tests/src/fmt_defs.h Mon Apr 14 10:15:49 2008
@@ -59,6 +59,7 @@
     size_t  *pbufsize;   // pointer to the size of the buffer
     size_t   maxsize;    // maximum not-to-exceed size
     size_t   endoff;     // offset of the last character
+    size_t   owned;      // buffer is owned by caller, don't free it
 };
 
 /********************************************************************/

Modified: stdcxx/trunk/tests/src/printf.cpp
URL: 
http://svn.apache.org/viewvc/stdcxx/trunk/tests/src/printf.cpp?rev=647908&r1=647907&r2=647908&view=diff
==============================================================================
--- stdcxx/trunk/tests/src/printf.cpp (original)
+++ stdcxx/trunk/tests/src/printf.cpp Mon Apr 14 10:15:49 2008
@@ -450,26 +450,24 @@
 
         size_t guardsize = sizeof guard - 1;
 
-        size_t newbufsize = *buf.pbufsize * 2 + guardsize;
+        size_t newbufsize = *buf.pbufsize * 2;
 
-        if (newbufsize <= buflen + len + guardsize)
-            newbufsize = 2 * (buflen + len + 1) + guardsize;
+        const size_t required = buflen + len;
+        if (newbufsize < required)
+            newbufsize = required * 2;
 
         // prevent buffer size from exceeding the maximum
         if (buf.maxsize < newbufsize)
             newbufsize = buf.maxsize;
 
-        if (newbufsize < buflen + len + guardsize)
-            guardsize = 0;
-
-        if (newbufsize < buflen + len + guardsize) {
+        if (newbufsize < required) {
 #ifdef ENOMEM
             errno = ENOMEM;
 #endif   // ENOMEM
             return 0;
         }
 
-        char* const newbuf = (char*)malloc (newbufsize);
+        char* const newbuf = (char*)malloc (newbufsize + guardsize);
 
         // return 0 on failure to allocate, let caller deal with it
         if (0 == newbuf)
@@ -478,17 +476,21 @@
         memcpy (newbuf, *buf.pbuf, buflen);
 
         // append a guard block to the end of the buffer
-        memcpy (newbuf + newbufsize - guardsize, guard, guardsize);
+        memcpy (newbuf + newbufsize, guard, guardsize);
 
-        if (*buf.pbuf) {
+        if (*buf.pbuf && !buf.owned) {
             // verify that we didn't write past the end of the buffer
             RW_ASSERT (0 == memcmp (*buf.pbuf + *buf.pbufsize,
                                     guard, guardsize));
+
             free (*buf.pbuf);
         }
 
         *buf.pbuf     = newbuf;
-        *buf.pbufsize = newbufsize - guardsize;
+        *buf.pbufsize = newbufsize;
+
+        // we allocated the buffer, so we can free it
+        buf.owned = 0;
     }
 
     if (0 != str) {
@@ -958,7 +960,7 @@
     if (0 == pbufsize)
         pbufsize = &default_bufsize;
 
-    Buffer buf = { pbuf, pbufsize, _RWSTD_SIZE_MAX, 0 };
+    Buffer buf = { pbuf, pbufsize, _RWSTD_SIZE_MAX, 0, 1 };
 
     // save the initial value of `pbuf'
     char* const pbuf_save = *buf.pbuf;
@@ -1995,7 +1997,7 @@
                 size_t localbufsize = sizeof elemstr;
 
                 Buffer bufspec = {
-                    &localbuf, &localbufsize, sizeof elemstr, 0
+                    &localbuf, &localbufsize, sizeof elemstr, 0, 1
                 };
 
                 *localbuf = '\0';
@@ -2053,7 +2055,7 @@
                 size_t localbufsize = sizeof elemstr;
 
                 Buffer bufspec = {
-                    &localbuf, &localbufsize, sizeof elemstr, 0
+                    &localbuf, &localbufsize, sizeof elemstr, 0, 1
                 };
 
                 *localbuf = '\0';
@@ -2983,7 +2985,7 @@
         const char* const fmt = VA_ARG (*pva, char*);
 
         size_t dummy_size = 0;   // unused
-        Buffer tmpbuf = { &fmtword, &dummy_size, _RWSTD_SIZE_MAX, 0 };
+        Buffer tmpbuf = { &fmtword, &dummy_size, _RWSTD_SIZE_MAX, 0, 1 };
         const int len = _rw_pvasnprintf (tmpbuf, fmt, pva);
         if (len < 0)
             return -1;


Reply via email to