summaryrefslogtreecommitdiffstats
path: root/libcxx/src/support/win32/support.cpp
diff options
context:
space:
mode:
authorHoward Hinnant <hhinnant@apple.com>2013-05-16 17:13:40 +0000
committerHoward Hinnant <hhinnant@apple.com>2013-05-16 17:13:40 +0000
commit9daaf5775cf3157bc1942a391d366fc6ab9277ff (patch)
treec04579d3e7dde8eb4092891ad38e3e2ab10fcef2 /libcxx/src/support/win32/support.cpp
parent8b2a1d69cb2e1d86920a2a7774a7c4307a8d4655 (diff)
downloadbcm5719-llvm-9daaf5775cf3157bc1942a391d366fc6ab9277ff.tar.gz
bcm5719-llvm-9daaf5775cf3157bc1942a391d366fc6ab9277ff.zip
Glen: This patch gets the string conversion functions working on Windows. It also refactors repetitive code in string.cpp do greatly reduce the repetitiveness, increasing maintainability.
llvm-svn: 182026
Diffstat (limited to 'libcxx/src/support/win32/support.cpp')
-rw-r--r--libcxx/src/support/win32/support.cpp57
1 files changed, 37 insertions, 20 deletions
diff --git a/libcxx/src/support/win32/support.cpp b/libcxx/src/support/win32/support.cpp
index 75f63919122..1a8bcf62892 100644
--- a/libcxx/src/support/win32/support.cpp
+++ b/libcxx/src/support/win32/support.cpp
@@ -8,38 +8,55 @@
//
//===----------------------------------------------------------------------===//
-#include <support/win32/support.h>
-#include <stdarg.h> // va_start, va_end
-#include <stddef.h> // size_t
-#include <stdlib.h> // malloc
-#include <stdio.h> // vsprintf, vsnprintf
-#include <string.h> // strcpy, wcsncpy
+#include <cstdarg> // va_start, va_end
+#include <cstddef> // size_t
+#include <cstdlib> // malloc
+#include <cstdio> // vsprintf, vsnprintf
+#include <cstring> // strcpy, wcsncpy
+#include <cwchar> // mbstate_t
+#include <memory> // unique_ptr
-int asprintf(char **sptr, const char *__restrict fmt, ...)
+namespace { // Private
+
+ struct free_deleter {
+ inline void operator()(char* p) { free(p); }
+ };
+}
+// Some of these functions aren't standard or if they conform, the name does not.
+
+int asprintf(char **sptr, const char *__restrict format, ...)
{
va_list ap;
- va_start(ap, fmt);
- int result = vasprintf(sptr, fmt, ap);
+ va_start(ap, format);
+ int result;
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ try {
+#endif
+ result = vasprintf(sptr, format, ap);
+#ifndef _LIBCPP_NO_EXCEPTIONS
+ } catch( ... ) {
+ va_end(ap);
+ throw;
+ }
+#endif
va_end(ap);
return result;
}
// Like sprintf, but when return value >= 0 it returns a pointer to a malloc'd string in *sptr.
// If return >= 0, use free to delete *sptr.
-int vasprintf( char **sptr, const char *__restrict fmt, va_list ap )
+int vasprintf( char **sptr, const char *__restrict format, va_list ap )
{
*sptr = NULL;
- int count = vsnprintf( NULL, 0, fmt, ap ); // Query the buffer size required.
+ int count = _vsnprintf( NULL, 0, format, ap ); // Query the buffer size required.
if( count >= 0 ) {
- char* p = static_cast<char*>(malloc(count+1)); // Allocate memory for it and the terminator.
- if ( p == NULL )
- return -1;
- if ( vsnprintf( p, count+1, fmt, ap ) == count ) // We should have used exactly what was required.
- *sptr = p;
- else { // Otherwise something is wrong, likely a bug in vsnprintf. If so free the memory and report the error.
- free(p);
+ std::unique_ptr<char, free_deleter> p( static_cast<char*>(malloc(count+1)) );
+ if ( ! p )
return -1;
- }
+ if ( vsnprintf( p.get(), count+1, format, ap ) == count ) // We should have used exactly what was required.
+ *sptr = p.release();
+ else // Otherwise something is wrong, likely a bug in vsnprintf. If so free the memory and report the error.
+ return -1; // Pointer will get automaticlaly deleted.
}
return count;
@@ -120,7 +137,7 @@ size_t wcsnrtombs( char *__restrict dst, const wchar_t **__restrict src,
if ( dst )
result = wcrtomb_s( &char_size, dst + dest_converted, dest_remaining, c, ps);
else
- result = wcrtomb_s( &char_size, NULL, 0, c, ps);
+ result = wcrtomb_s( &char_size, NULL, 0, c, ps);
// If result is zero there is no error and char_size contains the size of the multi-byte-sequence converted.
// Otherwise result indicates an errno type error.
if ( result == no_error ) {
OpenPOWER on IntegriCloud