patch by Jeffrey Yasskin for porting to Ubuntu Hardy. Everything was accepted except there were some bug fixes needed in <locale> for the __nolocale_* series. For the apple branch I ended up using templates instead of the var_args solution because it seemed both safer and more efficient.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@104516 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/__config b/include/__config
index 7b66dfc..a3518d9 100644
--- a/include/__config
+++ b/include/__config
@@ -37,7 +37,16 @@
#endif
#if !defined(_LIBCPP_LITTLE_ENDIAN) || !defined(_LIBCPP_BIG_ENDIAN)
-#error unable to determine endian
+# include <endian.h>
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+# define _LIBCPP_LITTLE_ENDIAN 1
+# define _LIBCPP_BIG_ENDIAN 0
+# elif __BYTE_ORDER == __BIG_ENDIAN
+# define _LIBCPP_LITTLE_ENDIAN 0
+# define _LIBCPP_BIG_ENDIAN 1
+# else
+# error unable to determine endian
+# endif
#endif
#ifndef _LIBCPP_VISIBILITY_TAG
diff --git a/include/__locale b/include/__locale
index 249e5b8..395cb26 100644
--- a/include/__locale
+++ b/include/__locale
@@ -18,6 +18,7 @@
#include <mutex>
#include <cstdint>
#include <cctype>
+#include <locale.h>
#include <xlocale.h>
#pragma GCC system_header
@@ -294,6 +295,7 @@
public:
typedef __uint32_t mask;
+#if __APPLE__
static const mask space = _CTYPE_S;
static const mask print = _CTYPE_R;
static const mask cntrl = _CTYPE_C;
@@ -304,6 +306,18 @@
static const mask punct = _CTYPE_P;
static const mask xdigit = _CTYPE_X;
static const mask blank = _CTYPE_B;
+#else /* !__APPLE__ */
+ static const mask space = _ISspace;
+ static const mask print = _ISprint;
+ static const mask cntrl = _IScntrl;
+ static const mask upper = _ISupper;
+ static const mask lower = _ISlower;
+ static const mask alpha = _ISalpha;
+ static const mask digit = _ISdigit;
+ static const mask punct = _ISpunct;
+ static const mask xdigit = _ISxdigit;
+ static const mask blank = _ISblank;
+#endif /* __APPLE__ */
static const mask alnum = alpha | digit;
static const mask graph = alnum | punct;
@@ -507,7 +521,11 @@
static locale::id id;
+#ifdef _CACHED_RUNES
static const size_t table_size = _CACHED_RUNES;
+#else
+ static const size_t table_size = 256; // FIXME: Don't hardcode this.
+#endif
const mask* table() const throw() {return __tab_;}
static const mask* classic_table() throw();
diff --git a/include/algorithm b/include/algorithm
index f3412f7..c53bf37 100644
--- a/include/algorithm
+++ b/include/algorithm
@@ -552,16 +552,12 @@
#ifdef _LIBCPP_DEBUG
#include <cassert>
#endif
-//#include <cstdlib>
-#define RAND_MAX 0x7fffffff // #include <cstdlib>
-extern "C" int rand(void); // #include <cstdlib>
+#include <cstdlib>
#pragma GCC system_header
_LIBCPP_BEGIN_NAMESPACE_STD
-using ::rand; // #include <cstdlib>
-
template <class _T1, class _T2 = _T1>
struct __equal_to
{
diff --git a/include/cstddef b/include/cstddef
index 11d07a2..efe0f61 100644
--- a/include/cstddef
+++ b/include/cstddef
@@ -34,6 +34,8 @@
*/
#include <__config>
+#define __need_ptrdiff_t
+#define __need_size_t
#include <stddef.h>
#pragma GCC system_header
diff --git a/include/iosfwd b/include/iosfwd
index e9a6a0f..32f679e 100644
--- a/include/iosfwd
+++ b/include/iosfwd
@@ -86,7 +86,7 @@
*/
#include <__config>
-#include <_types.h> // for __darwin_mbstate_t
+#include <wchar.h> // for mbstate_t
#pragma GCC system_header
@@ -153,11 +153,11 @@
typedef basic_fstream<wchar_t> wfstream;
template <class _State> class fpos;
-typedef fpos<__darwin_mbstate_t> streampos;
-typedef fpos<__darwin_mbstate_t> wstreampos;
+typedef fpos<mbstate_t> streampos;
+typedef fpos<mbstate_t> wstreampos;
#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-typedef fpos<__darwin_mbstate_t> u16streampos;
-typedef fpos<__darwin_mbstate_t> u32streampos;
+typedef fpos<mbstate_t> u16streampos;
+typedef fpos<mbstate_t> u32streampos;
#endif
typedef long long streamoff; // for char_traits in <string>
diff --git a/include/locale b/include/locale
index 284184f..09faccd 100644
--- a/include/locale
+++ b/include/locale
@@ -137,6 +137,9 @@
#include <streambuf>
#include <iterator>
#include <limits>
+#if !__APPLE__
+#include <cstdarg>
+#endif
#include <cstdlib>
#include <ctime>
#include <nl_types.h>
@@ -145,6 +148,131 @@
_LIBCPP_BEGIN_NAMESPACE_STD
+// OSX has nice foo_l() functions that let you turn off use of the global
+// locale. Linux, not so much. The following functions avoid the locale when
+// that's possible and otherwise do the wrong thing. FIXME.
+#if __APPLE__
+
+template <class _Tp>
+inline
+int
+__nolocale_sprintf(char* __restrict __str,
+ const char* __restrict __format, _Tp __v)
+{
+ return sprintf_l(__str, 0, __format, __v);
+}
+
+template <class _Tp>
+inline
+int
+__nolocale_snprintf(char* __restrict __str, size_t __size,
+ const char* __restrict __format, _Tp __v)
+{
+ return snprintf_l(__str, __size, 0, __format, __v);
+}
+
+template <class _Tp>
+inline
+int
+__nolocale_snprintf(char* __restrict __str, size_t __size,
+ const char* __restrict __format, int __prec, _Tp __v)
+{
+ return snprintf_l(__str, __size, 0, __format, __prec, __v);
+}
+
+template <class _Tp>
+inline
+int
+__nolocale_asprintf(char** __ret, const char* __restrict __format, _Tp __v)
+{
+ return asprintf_l(__ret, 0, __format, __v);
+}
+
+template <class _Tp>
+inline
+int
+__nolocale_asprintf(char** __ret, const char* __restrict __format, int __prec,
+ _Tp __v)
+{
+ return asprintf_l(__ret, 0, __format, __prec, __v);
+}
+
+template <class _Tp>
+inline
+int
+__nolocale_sscanf(const char* __restrict __str,
+ const char* __restrict __format, _Tp* __v)
+{
+ return sscanf_l(__str, 0, __format, __v);
+}
+
+inline
+int
+__nolocale_isxdigit(int __c)
+{
+ return isxdigit_l(__c, 0);
+}
+
+inline
+int
+__nolocale_isdigit(int __c)
+{
+ return isdigit_l(__c, 0);
+}
+
+#else /* !__APPLE__ */
+inline int
+__nolocale_sprintf(char* __restrict __str,
+ const char* __restrict __format, ...)
+{
+ va_list __ap;
+ va_start(__ap, __format);
+ int __result = vsprintf(__str, __format, __ap);
+ va_end(__ap);
+ return __result;
+}
+inline int
+__nolocale_snprintf(char* __restrict __str, size_t __size,
+ const char* __restrict __format, ...)
+{
+ va_list __ap;
+ va_start(__ap, __format);
+ int __result = vsnprintf(__str, __size, __format, __ap);
+ va_end(__ap);
+ return __result;
+}
+inline int
+__nolocale_asprintf(char** __ret,
+ const char* __restrict __format, ...)
+{
+ va_list __ap;
+ va_start(__ap, __format);
+ int __result = vasprintf(__ret, __format, __ap);
+ va_end(__ap);
+ return __result;
+}
+inline int
+__nolocale_sscanf(const char* __restrict __str,
+ const char* __restrict __format, ...)
+{
+ va_list __ap;
+ va_start(__ap, __format);
+ int __result = vsscanf(__str, __format, __ap);
+ va_end(__ap);
+ return __result;
+}
+inline int
+__nolocale_isxdigit(int __c)
+{
+ return isxdigit(__c);
+}
+inline int
+__nolocale_isdigit(int __c)
+{
+ return isdigit(__c);
+}
+#endif /* __APPLE__ */
+
// __scan_keyword
// Scans [__b, __e) until a match is found in the basic_strings range
// [__kb, __ke) or until it can be shown that there is no match in [__kb, __ke).
@@ -1002,7 +1130,7 @@
break;
// Stage 3
__a[sizeof(__a)-1] = 0;
- if (sscanf_l(__a, 0, "%p", &__v) != 1)
+ if (__nolocale_sscanf(__a, "%p", &__v) != 1)
__err = ios_base::failbit;
// EOF checked
if (__b == __e)
@@ -1107,13 +1235,13 @@
*__oe++ = __ct.widen(*__nf++);
*__oe++ = __ct.widen(*__nf++);
for (__ns = __nf; __ns < __ne; ++__ns)
- if (!isxdigit_l(*__ns, 0))
+ if (!__nolocale_isxdigit(*__ns))
break;
}
else
{
for (__ns = __nf; __ns < __ne; ++__ns)
- if (!isdigit_l(*__ns, 0))
+ if (!__nolocale_isdigit(*__ns))
break;
}
if (__grouping.empty())
@@ -1310,7 +1438,7 @@
+ ((numeric_limits<long>::digits % 3) != 0)
+ 1;
char __nar[__nbuf];
- int __nc = sprintf_l(__nar, 0, __fmt, __v);
+ int __nc = __nolocale_sprintf(__nar, __fmt, __v);
char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob);
// Stage 2 - Widen __nar while adding thousands separators
@@ -1336,7 +1464,7 @@
+ ((numeric_limits<long long>::digits % 3) != 0)
+ 1;
char __nar[__nbuf];
- int __nc = sprintf_l(__nar, 0, __fmt, __v);
+ int __nc = __nolocale_sprintf(__nar, __fmt, __v);
char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob);
// Stage 2 - Widen __nar while adding thousands separators
@@ -1362,7 +1490,7 @@
+ ((numeric_limits<unsigned long>::digits % 3) != 0)
+ 1;
char __nar[__nbuf];
- int __nc = sprintf_l(__nar, 0, __fmt, __v);
+ int __nc = __nolocale_sprintf(__nar, __fmt, __v);
char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob);
// Stage 2 - Widen __nar while adding thousands separators
@@ -1388,7 +1516,7 @@
+ ((numeric_limits<unsigned long long>::digits % 3) != 0)
+ 1;
char __nar[__nbuf];
- int __nc = sprintf_l(__nar, 0, __fmt, __v);
+ int __nc = __nolocale_sprintf(__nar, __fmt, __v);
char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob);
// Stage 2 - Widen __nar while adding thousands separators
@@ -1415,16 +1543,18 @@
char* __nb = __nar;
int __nc;
if (__specify_precision)
- __nc = snprintf_l(__nb, __nbuf, 0, __fmt, (int)__iob.precision(), __v);
+ __nc = __nolocale_snprintf(__nb, __nbuf, __fmt,
+ (int)__iob.precision(), __v);
else
- __nc = snprintf_l(__nb, __nbuf, 0, __fmt, __v);
+ __nc = __nolocale_snprintf(__nb, __nbuf, __fmt, __v);
unique_ptr<char, void(*)(void*)> __nbh(0, free);
if (__nc > static_cast<int>(__nbuf-1))
{
if (__specify_precision)
- __nc = asprintf_l(&__nb, 0, __fmt, (int)__iob.precision(), __v);
+ __nc = __nolocale_asprintf(&__nb, __fmt, (int)__iob.precision(),
+ __v);
else
- __nc = asprintf_l(&__nb, 0, __fmt, __v);
+ __nc = __nolocale_asprintf(&__nb, __fmt, __v);
if (__nb == 0)
__throw_bad_alloc();
__nbh.reset(__nb);
@@ -1465,16 +1595,18 @@
char* __nb = __nar;
int __nc;
if (__specify_precision)
- __nc = snprintf_l(__nb, __nbuf, 0, __fmt, (int)__iob.precision(), __v);
+ __nc = __nolocale_snprintf(__nb, __nbuf, __fmt,
+ (int)__iob.precision(), __v);
else
- __nc = snprintf_l(__nb, __nbuf, 0, __fmt, __v);
+ __nc = __nolocale_snprintf(__nb, __nbuf, __fmt, __v);
unique_ptr<char, void(*)(void*)> __nbh(0, free);
if (__nc > static_cast<int>(__nbuf-1))
{
if (__specify_precision)
- __nc = asprintf_l(&__nb, 0, __fmt, (int)__iob.precision(), __v);
+ __nc = __nolocale_asprintf(&__nb, __fmt, (int)__iob.precision(),
+ __v);
else
- __nc = asprintf_l(&__nb, 0, __fmt, __v);
+ __nc = __nolocale_asprintf(&__nb, __fmt, __v);
if (__nb == 0)
__throw_bad_alloc();
__nbh.reset(__nb);
@@ -1510,7 +1642,7 @@
char __fmt[6] = "%p";
const unsigned __nbuf = 20;
char __nar[__nbuf];
- int __nc = sprintf_l(__nar, 0, __fmt, __v);
+ int __nc = __nolocale_sprintf(__nar, __fmt, __v);
char* __ne = __nar + __nc;
char* __np = this->__identify_padding(__nar, __ne, __iob);
// Stage 2 - Widen __nar
@@ -3162,7 +3294,7 @@
// secure memory for digit storage
if (__n > __bs-1)
{
- __n = asprintf_l(&__bb, 0, "%.0Lf", __units);
+ __n = __nolocale_asprintf(&__bb, "%.0Lf", __units);
if (__bb == 0)
__throw_bad_alloc();
__hn.reset(__bb);
diff --git a/include/string b/include/string
index 6b11e02..15713f0 100644
--- a/include/string
+++ b/include/string
@@ -358,6 +358,7 @@
#include <__config>
#include <iosfwd>
#include <cstring>
+#include <cstdio> // For EOF.
#include <cwchar>
#include <algorithm>
#include <iterator>
diff --git a/include/thread b/include/thread
index 3c1cf99..16faed9 100644
--- a/include/thread
+++ b/include/thread
@@ -115,6 +115,9 @@
class __thread_id
{
+ // FIXME: pthread_t is a pointer on Darwin but a long on Linux.
+ // NULL is the no-thread value on Darwin. Someone needs to check
+ // on other platforms. We assume 0 works everywhere for now.
pthread_t __id_;
public:
@@ -206,7 +209,7 @@
void swap(thread& __t) {_STD::swap(__t_, __t.__t_);}
- bool joinable() const {return __t_ != nullptr;}
+ bool joinable() const {return __t_ != 0;}
void join();
void detach();
id get_id() const {return __t_;}
diff --git a/include/vector b/include/vector
index a85d39a..e97e939 100644
--- a/include/vector
+++ b/include/vector
@@ -1118,7 +1118,7 @@
if (__n > __s)
__construct_at_end(__n - __s, __u);
else
- __destruct_at_end(this->__begin_ + __n);
+ this->__destruct_at_end(this->__begin_ + __n);
}
else
{