Merge commit '81241a944099014cc56929a99355cede91ada83c' into HEAD
Conflicts:
CMakeLists.txt
cmake/config-ix.cmake
include/locale
src/locale.cpp
src/thread.cpp
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2f0da84
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,25 @@
+#==============================================================================#
+# This file specifies intentionally untracked files that git should ignore.
+# See: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html
+#
+# This file is intentionally different from the output of `git svn show-ignore`,
+# as most of those are useless.
+#==============================================================================#
+
+#==============================================================================#
+# File extensions to be ignored anywhere in the tree.
+#==============================================================================#
+# Temp files created by most text editors.
+*~
+# Merge files created by git.
+*.orig
+# Byte compiled python modules.
+*.pyc
+# vim swap files
+.*.swp
+.sw?
+
+#==============================================================================#
+# Explicit files to ignore (only matches one).
+#==============================================================================#
+.gitusers
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..ac015a5
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,8 @@
+dschuff@chromium.org
+eliben@chromium.org
+jfb@chromium.org
+jvoung@chromium.org
+kschimpf@chromium.org
+mseaborn@chromium.org
+sehr@chromium.org
+stichnot@chromium.org
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
new file mode 100644
index 0000000..4d9f899
--- /dev/null
+++ b/PRESUBMIT.py
@@ -0,0 +1,66 @@
+# Copyright (c) 2013 The Native Client Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Documentation on PRESUBMIT.py can be found at:
+# http://www.chromium.org/developers/how-tos/depottools/presubmit-scripts
+
+EXCLUDE_PROJECT_CHECKS_DIRS = [ '.' ]
+
+import subprocess
+def CheckGitBranch():
+ p = subprocess.Popen("git branch -vv", shell=True,
+ stdout=subprocess.PIPE)
+ output, _ = p.communicate()
+
+ lines = output.split('\n')
+ for line in lines:
+ # output format for checked-out branch should be
+ # * branchname hash [TrackedBranchName ...
+ toks = line.split()
+ if '*' not in toks[0]:
+ continue
+ if not 'origin/master' in toks[3]:
+ warning = 'Warning: your current branch:\n' + line
+ warning += '\nis not tracking origin/master. git cl push may silently '
+ warning += 'fail to push your change. To fix this, do\n'
+ warning += 'git branch -u origin/master'
+ return warning
+ return None
+ print 'Warning: presubmit check could not determine local git branch'
+ return None
+
+def _CommonChecks(input_api, output_api):
+ """Checks for both upload and commit."""
+ results = []
+ results.extend(input_api.canned_checks.PanProjectChecks(
+ input_api, output_api, project_name='Native Client',
+ excluded_paths=tuple(EXCLUDE_PROJECT_CHECKS_DIRS)))
+ branch_warning = CheckGitBranch()
+ if branch_warning:
+ results.append(output_api.PresubmitPromptWarning(branch_warning))
+ return results
+
+def CheckChangeOnUpload(input_api, output_api):
+ """Verifies all changes in all files.
+ Args:
+ input_api: the limited set of input modules allowed in presubmit.
+ output_api: the limited set of output modules allowed in presubmit.
+ """
+ report = []
+ report.extend(_CommonChecks(input_api, output_api))
+ return report
+
+def CheckChangeOnCommit(input_api, output_api):
+ """Verifies all changes in all files and verifies that the
+ tree is open and can accept a commit.
+ Args:
+ input_api: the limited set of input modules allowed in presubmit.
+ output_api: the limited set of output modules allowed in presubmit.
+ """
+ report = []
+ report.extend(CheckChangeOnUpload(input_api, output_api))
+ return report
+
+def GetPreferredTrySlaves(project, change):
+ return []
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake
index f0219c0..e8d6025 100644
--- a/cmake/config-ix.cmake
+++ b/cmake/config-ix.cmake
@@ -1,34 +1,39 @@
-include(CheckLibraryExists)
-include(CheckCXXCompilerFlag)
+# @LOCALMOD-START The PNaCl driver automatically adds dependencies to
+# libc++ which hasn't been built yet. The tests for
+# flags therefore fail because the library can't be
+# found. We should fix this in a different CL, and add
+# proper detection for newlib's lack of locale_t
+# support. See:
+# https://code.google.com/p/nativeclient/issues/detail?id=3661
-# Check compiler flags
-check_cxx_compiler_flag(-std=c++0x LIBCXX_HAS_STDCXX0X_FLAG)
-check_cxx_compiler_flag(-fPIC LIBCXX_HAS_FPIC_FLAG)
-check_cxx_compiler_flag(-nodefaultlibs LIBCXX_HAS_NODEFAULTLIBS_FLAG)
-check_cxx_compiler_flag(-nostdinc++ LIBCXX_HAS_NOSTDINCXX_FLAG)
-check_cxx_compiler_flag(-Wall LIBCXX_HAS_WALL_FLAG)
-check_cxx_compiler_flag(-W LIBCXX_HAS_W_FLAG)
-check_cxx_compiler_flag(-Wno-unused-parameter LIBCXX_HAS_WNO_UNUSED_PARAMETER_FLAG)
-check_cxx_compiler_flag(-Wwrite-strings LIBCXX_HAS_WWRITE_STRINGS_FLAG)
-check_cxx_compiler_flag(-Wno-long-long LIBCXX_HAS_WNO_LONG_LONG_FLAG)
-check_cxx_compiler_flag(-pedantic LIBCXX_HAS_PEDANTIC_FLAG)
-check_cxx_compiler_flag(-Werror LIBCXX_HAS_WERROR_FLAG)
-check_cxx_compiler_flag(-Wno-error LIBCXX_HAS_WNO_ERROR_FLAG)
-check_cxx_compiler_flag(-fno-exceptions LIBCXX_HAS_FNO_EXCEPTIONS_FLAG)
-check_cxx_compiler_flag(-fno-rtti LIBCXX_HAS_FNO_RTTI_FLAG)
-check_cxx_compiler_flag(/WX LIBCXX_HAS_WX_FLAG)
-check_cxx_compiler_flag(/WX- LIBCXX_HAS_NO_WX_FLAG)
-check_cxx_compiler_flag(/EHsc LIBCXX_HAS_EHSC_FLAG)
-check_cxx_compiler_flag(/EHs- LIBCXX_HAS_NO_EHS_FLAG)
-check_cxx_compiler_flag(/EHa- LIBCXX_HAS_NO_EHA_FLAG)
-check_cxx_compiler_flag(/GR- LIBCXX_HAS_NO_GR_FLAG)
+set(LIBCXX_HAS_STDCXX0X_FLAG 1)
+set(LIBCXX_HAS_FPIC_FLAG 0) # Not quite true, but untested in PNaCl.
+set(LIBCXX_HAS_NODEFAULTLIBS_FLAG 1)
+set(LIBCXX_HAS_NOSTDINCXX_FLAG 1)
+set(LIBCXX_HAS_WALL_FLAG 1)
+set(LIBCXX_HAS_W_FLAG 1)
+set(LIBCXX_HAS_WNO_UNUSED_PARAMETER_FLAG 1)
+set(LIBCXX_HAS_WWRITE_STRINGS_FLAG 1)
+set(LIBCXX_HAS_WNO_LONG_LONG_FLAG 1)
+set(LIBCXX_HAS_PEDANTIC_FLAG 1)
+set(LIBCXX_HAS_WERROR_FLAG 1)
+set(LIBCXX_HAS_WNO_ERROR_FLAG 1)
+set(LIBCXX_HAS_FNO_EXCEPTIONS_FLAG 1)
+set(LIBCXX_HAS_FNO_RTTI_FLAG 1)
+# MSVC flags:
+set(LIBCXX_HAS_WX_FLAG 0)
+set(LIBCXX_HAS_NO_WX_FLAG 0)
+set(LIBCXX_HAS_EHSC_FLAG 0)
+set(LIBCXX_HAS_NO_EHS_FLAG 0)
+set(LIBCXX_HAS_NO_EHA_FLAG 0)
+set(LIBCXX_HAS_NO_GR_FLAG 0)
-# Check libraries
-check_library_exists(pthread pthread_create "" LIBCXX_HAS_PTHREAD_LIB)
-check_library_exists(c printf "" LIBCXX_HAS_C_LIB)
-check_library_exists(m ccos "" LIBCXX_HAS_M_LIB)
-check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB)
-check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXX_HAS_GCC_S_LIB)
+set(LIBCXX_HAS_PTHREAD_LIB 1)
+set(LIBCXX_HAS_C_LIB 1)
+set(LIBCXX_HAS_M_LIB 1)
+set(LIBCXX_HAS_RT_LIB 0)
+set(LIBCXX_HAS_GCC_S_LIB 0)
+# @LOCALMOD-END
# Check C++0x features
if (LIBCXX_ENABLE_CXX0X)
diff --git a/codereview.settings b/codereview.settings
new file mode 100644
index 0000000..21c6452
--- /dev/null
+++ b/codereview.settings
@@ -0,0 +1,10 @@
+# This file is used by gcl to get repository specific information.
+CODE_REVIEW_SERVER: codereview.chromium.org
+CC_LIST: native-client-reviews@googlegroups.com
+VIEW_VC: https://gerrit.chromium.org/gerrit/gitweb?p=native_client/pnacl-libcxx.git;a=commit;h=
+STATUS: http://nativeclient-status.appspot.com/status
+TRY_ON_UPLOAD: False
+TRYSERVER_PROJECT: nacl
+TRYSERVER_SVN_URL: svn://svn.chromium.org/chrome-try/try-nacl
+PUSH_URL_CONFIG: url.ssh://gerrit.chromium.org.pushinsteadof
+ORIGIN_URL_CONFIG: http://chromium.googlesource.com
diff --git a/include/__locale b/include/__locale
index 2073e1b..e78c8ee 100644
--- a/include/__locale
+++ b/include/__locale
@@ -31,6 +31,66 @@
#pragma GCC system_header
#endif
+// @LOCALMOD-START Newlib doesn't have the following C extensions for
+// locales. This probably shouldn't rely on
+// _NEWLIB_VERSION: lack of locale_t support could
+// instead be detected at configuration time.
+#if defined(_NEWLIB_VERSION)
+typedef void *locale_t;
+extern "C" locale_t duplocale(locale_t);
+extern "C" void freelocale(locale_t);
+extern "C" locale_t newlocale(int, const char *, locale_t);
+extern "C" locale_t uselocale(locale_t);
+#define LC_COLLATE_MASK (1 << LC_COLLATE)
+#define LC_CTYPE_MASK (1 << LC_CTYPE)
+#define LC_MESSAGES_MASK (1 << LC_MESSAGES)
+#define LC_MONETARY_MASK (1 << LC_MONETARY)
+#define LC_NUMERIC_MASK (1 << LC_NUMERIC)
+#define LC_TIME_MASK (1 << LC_TIME)
+#define LC_ALL_MASK (LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MESSAGES_MASK | \
+ LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK)
+#define isxdigit_l(a, L) (((void) L), isxdigit(a))
+#define iswxdigit_l(a, L) (((void) L), iswxdigit(a))
+#define isdigit_l(a, L) (((void) L), isdigit(a))
+#define iswdigit_l(a, L) (((void) L), iswdigit(a))
+#define iswcntrl_l(a, L) (((void) L), iswcntrl(a))
+#define iswcntrl_l(a, L) (((void) L), iswcntrl(a))
+#define isalpha_l(a, L) (((void) L), isalpha(a))
+#define iswalpha_l(a, L) (((void) L), iswalpha(a))
+#define ispunct_l(a, L) (((void) L), ispunct(a))
+#define iswpunct_l(a, L) (((void) L), iswpunct(a))
+#define isblank_l(a, L) (((void) L), isblank(a))
+#define iswblank_l(a, L) (((void) L), iswblank(a))
+#define isspace_l(a, L) (((void) L), isspace(a))
+#define iswspace_l(a, L) (((void) L), iswspace(a))
+#define isprint_l(a, L) (((void) L), isprint(a))
+#define iswprint_l(a, L) (((void) L), iswprint(a))
+#define islower_l(a, L) (((void) L), islower(a))
+#define iswlower_l(a, L) (((void) L), iswlower(a))
+#define isupper_l(a, L) (((void) L), isupper(a))
+#define iswupper_l(a, L) (((void) L), iswupper(a))
+#define tolower_l(a, L) (((void) L), tolower(a))
+#define towlower_l(a, L) (((void) L), towlower(a))
+#define toupper_l(a, L) (((void) L), toupper(a))
+#define towupper_l(a, L) (((void) L), towupper(a))
+#define strftime_l(a, b, c, d, L) (((void) L), strftime(a, b, c, d))
+#define strtoll_l(a, b, c, L) (((void) L), strtoll(a, b, c))
+#define strtoull_l(a, b, c, L) (((void) L), strtoull(a, b, c))
+#define strtold_l(a, b, L) (((void) L), strtold(a, b))
+#define strcoll_l(a, b, L) (((void) L), strcoll(a, b))
+#define wstrcoll_l(a, b, L) (((void) L), wstrcoll(a, b))
+#define cscoll_l(a, b, L) (((void) L), cscoll(a, b))
+#define wcscoll_l(a, b, L) (((void) L), wcscoll(a, b))
+#define strxfrm_l(a, b, c, L) (((void) L), strxfrm(a, b, c))
+#define wstrxfrm_l(a, b, c, L) (((void) L), wstrxfrm(a, b, c))
+#define csxfrm_l(a, b, c, L) (((void) L), csxfrm(a, b, c))
+#define wcsxfrm_l(a, b, c, L) (((void) L), wcsxfrm(a, b, c))
+#define sscanf_l(a, b, L, ...) (((void) L), sscanf(a, b, ##__VA_ARGS__))
+#define snprintf_l(a, b, L, c, ...) (((void) L), snprintf(a, b, c, ##__VA_ARGS__))
+#define asprintf_l(a, L, b, ...) (((void) L), asprintf(a, b, ##__VA_ARGS__))
+#endif
+ // @LOCALMOD-END
+
_LIBCPP_BEGIN_NAMESPACE_STD
class _LIBCPP_TYPE_VIS locale;
@@ -375,6 +435,21 @@
static const mask punct = _ISPUNCT;
static const mask xdigit = _ISXDIGIT;
static const mask blank = _ISBLANK;
+// @LOCALMOD-START
+#elif defined(_NEWLIB_VERSION)
+ typedef char mask; // Same type as Newlib's _ctype_ array in ctype.h.
+ // Defined in Newlib's ctype.h.
+ static const mask space = _S;
+ static const mask print = _P | _U | _L | _N | _B;
+ static const mask cntrl = _C;
+ static const mask upper = _U;
+ static const mask lower = _L;
+ static const mask alpha = _U | _L;
+ static const mask digit = _N;
+ static const mask punct = _P;
+ static const mask xdigit = _X | _N;
+ static const mask blank = _B;
+// @LOCALMOD-END
#else // __GLIBC__ || _WIN32 || __APPLE__ || __FreeBSD__ || EMSCRIPTEN || __sun__
typedef unsigned long mask;
static const mask space = 1<<0;
diff --git a/include/atomic b/include/atomic
index f6ab1cb..98f52a0 100644
--- a/include/atomic
+++ b/include/atomic
@@ -560,12 +560,24 @@
{
mutable _Atomic(_Tp) __a_;
+ // @LOCALMOD-BEGIN The NaCl builtin delays resolution of the lock-free
+ // property until translation time (time at which the
+ // actual target is known).
+#if defined (__pnacl__)
+ _LIBCPP_INLINE_VISIBILITY
+ bool is_lock_free() const volatile _NOEXCEPT
+ {return __nacl_atomic_is_lock_free(sizeof(_Tp), &__a_);}
+ _LIBCPP_INLINE_VISIBILITY
+ bool is_lock_free() const _NOEXCEPT
+ {return __nacl_atomic_is_lock_free(sizeof(_Tp), &__a_);}
+#else
_LIBCPP_INLINE_VISIBILITY
bool is_lock_free() const volatile _NOEXCEPT
{return __c11_atomic_is_lock_free(sizeof(_Tp));}
_LIBCPP_INLINE_VISIBILITY
bool is_lock_free() const _NOEXCEPT
{return __c11_atomic_is_lock_free(sizeof(_Tp));}
+#endif // @LOCALMOD-END
_LIBCPP_INLINE_VISIBILITY
void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
{__c11_atomic_store(&__a_, __d, __m);}
diff --git a/include/cmath b/include/cmath
index 75087ae..25a9b6b 100644
--- a/include/cmath
+++ b/include/cmath
@@ -1382,7 +1382,11 @@
using ::log2f;
inline _LIBCPP_INLINE_VISIBILITY float log2(float __x) _NOEXCEPT {return log2f(__x);}
+#if defined(_NEWLIB_VERSION) // @LOCALMOD-START Missing from newlib. Note that PNaCl represents ``long double`` as ``double``, hence the intrinsic's type.
+inline _LIBCPP_INLINE_VISIBILITY long double log2(long double __x) _NOEXCEPT {return __builtin_log2(__x);}
+#else
inline _LIBCPP_INLINE_VISIBILITY long double log2(long double __x) _NOEXCEPT {return log2l(__x);}
+#endif // @LOCALMOD-END
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -1395,7 +1399,11 @@
using ::logbf;
inline _LIBCPP_INLINE_VISIBILITY float logb(float __x) _NOEXCEPT {return logbf(__x);}
+#if defined(_NEWLIB_VERSION) // @LOCALMOD-START Missing from newlib. Note that PNaCl represents ``long double`` as ``double``, hence the intrinsic's type.
+inline _LIBCPP_INLINE_VISIBILITY long double logb(long double __x) _NOEXCEPT {return __builtin_logb(__x);}
+#else
inline _LIBCPP_INLINE_VISIBILITY long double logb(long double __x) _NOEXCEPT {return logbl(__x);}
+#endif // @LOCALMOD-END
template <class _A1>
inline _LIBCPP_INLINE_VISIBILITY
@@ -1480,6 +1488,15 @@
// nexttoward
+#if defined(_NEWLIB_VERSION) // @LOCALMOD-START Missing from newlib. Note that PNaCl represents ``long double`` as ``double``, hence the intrinsic's type.
+inline _LIBCPP_INLINE_VISIBILITY float nexttoward(float __x, long double __y) _NOEXCEPT {return __builtin_nexttoward(__x, __y);}
+inline _LIBCPP_INLINE_VISIBILITY long double nexttoward(long double __x, long double __y) _NOEXCEPT {return __builtin_nexttoward(__x, __y);}
+
+template <class _A1>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_integral<_A1>::value, double>::type
+nexttoward(_A1 __x, long double __y) _NOEXCEPT {return __builtin_nexttoward((double)__x, __y);}
+#else
using ::nexttoward;
using ::nexttowardf;
@@ -1490,7 +1507,7 @@
inline _LIBCPP_INLINE_VISIBILITY
typename enable_if<is_integral<_A1>::value, double>::type
nexttoward(_A1 __x, long double __y) _NOEXCEPT {return nexttoward((double)__x, __y);}
-
+#endif // @LOCALMOD-END
// remainder
using ::remainder;
@@ -1663,14 +1680,18 @@
using ::llrintl;
using ::llroundl;
using ::log1pl;
+#if !defined(_NEWLIB_VERSION) // @LOCALMOD-START Missing from newlib.
using ::log2l;
using ::logbl;
+#endif // @LOCALMOD-END
using ::lrintl;
using ::lroundl;
using ::nanl;
using ::nearbyintl;
using ::nextafterl;
+#if !defined(_NEWLIB_VERSION) // @LOCALMOD-START Missing from newlib.
using ::nexttowardl;
+#endif // @LOCALMOD-END
using ::remainderl;
using ::remquol;
using ::rintl;
diff --git a/include/cstdio b/include/cstdio
index ce3af4d..e7d8fab 100644
--- a/include/cstdio
+++ b/include/cstdio
@@ -172,8 +172,11 @@
using ::fsetpos;
using ::ftell;
using ::rewind;
+#undef clearerr // @LOCALMOD
using ::clearerr;
+#undef feof // @LOCALMOD
using ::feof;
+#undef ferror // @LOCALMOD
using ::ferror;
using ::perror;
diff --git a/include/limits b/include/limits
index d917c57..1b8a87d 100644
--- a/include/limits
+++ b/include/limits
@@ -237,7 +237,7 @@
static _LIBCPP_CONSTEXPR const bool is_bounded = true;
static _LIBCPP_CONSTEXPR const bool is_modulo = true;
-#if __i386__ || __x86_64__
+#if __i386__ || __x86_64__ || defined(__pnacl__) // @LOCALMOD
static _LIBCPP_CONSTEXPR const bool traps = true;
#else
static _LIBCPP_CONSTEXPR const bool traps = false;
diff --git a/include/locale b/include/locale
index d13d49e..cc0fcf6 100644
--- a/include/locale
+++ b/include/locale
@@ -193,6 +193,8 @@
#include <ctime>
#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
#include <support/win32/locale_win32.h>
+#elif defined(_NEWLIB_VERSION) // @LOCALMOD Not supported by newlib.
+// Nothing.
#else // _LIBCPP_MSVCRT
#include <nl_types.h>
#endif // !_LIBCPP_MSVCRT
@@ -229,7 +231,7 @@
// 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 defined(__linux__) || defined(EMSCRIPTEN) || defined(_AIX)
+#if defined(__linux__) || defined(EMSCRIPTEN) || defined(_AIX) || defined(_NEWLIB_VERSION) // @LOCALMOD
#ifdef _LIBCPP_LOCALE__L_EXTENSIONS
decltype(MB_CUR_MAX_L(_VSTD::declval<locale_t>()))
@@ -3673,7 +3675,7 @@
typename messages<_CharT>::catalog
messages<_CharT>::do_open(const basic_string<char>& __nm, const locale&) const
{
-#ifdef _WIN32
+#if defined(_WIN32) || defined(_NEWLIB_VERSION) // @LOCALMOD Not supported by newlib.
return -1;
#else // _WIN32
catalog __cat = (catalog)catopen(__nm.c_str(), NL_CAT_LOCALE);
@@ -3688,7 +3690,7 @@
messages<_CharT>::do_get(catalog __c, int __set, int __msgid,
const string_type& __dflt) const
{
-#ifdef _WIN32
+#if defined(_WIN32) || defined(_NEWLIB_VERSION) // @LOCALMOD Not supported by newlib.
return __dflt;
#else // _WIN32
string __ndflt;
@@ -3710,7 +3712,7 @@
void
messages<_CharT>::do_close(catalog __c) const
{
-#if !defined(_WIN32)
+#if !defined(_WIN32) && !defined(_NEWLIB_VERSION) // @LOCALMOD Not supported by newlib.
if (__c != -1)
__c <<= 1;
nl_catd __cat = (nl_catd)__c;
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index cec0bee..35076a1 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -1,5 +1,11 @@
# Get sources
file(GLOB LIBCXX_SOURCES ../src/*.cpp)
+
+# @LOCALMOD-START Bake libcxxabi into the libcxx build.
+file(GLOB LIBCXXABI_SOURCES ../../libcxxabi/src/*.cpp)
+list(APPEND LIBCXX_SOURCES ${LIBCXXABI_SOURCES})
+# @LOCALMOD-END
+
if(WIN32)
file(GLOB LIBCXX_WIN32_SOURCES ../src/support/win32/*.cpp)
list(APPEND LIBCXX_SOURCES ${LIBCXX_WIN32_SOURCES})
diff --git a/src/locale.cpp b/src/locale.cpp
index 8fadbb6..79195a4 100644
--- a/src/locale.cpp
+++ b/src/locale.cpp
@@ -42,6 +42,17 @@
#pragma clang diagnostic ignored "-Wsign-conversion"
#endif
+// @LOCALMOD-START Newlib doesn't have the following C extensions for locales.
+#if defined(_NEWLIB_VERSION)
+extern "C" {
+ locale_t duplocale(locale_t) { return NULL; }
+ void freelocale(locale_t) { }
+ locale_t newlocale(int, const char *, locale_t) { return NULL; }
+ locale_t uselocale(locale_t) { return NULL; }
+}
+#endif
+ // @LOCALMOD-END
+
_LIBCPP_BEGIN_NAMESPACE_STD
#ifdef __cloc_defined
@@ -1035,6 +1046,10 @@
// going to end up dereferencing it later...
#elif defined(EMSCRIPTEN)
return *__ctype_b_loc();
+#elif defined(_NEWLIB_VERSION) // @LOCALMOD-START
+ // Newlib has a 257-entry table in ctype_.c, where (char)0 starts at [1].
+ return _ctype_ + 1;
+ // @LOCALMOD-END
#elif defined(_AIX)
return (const unsigned long *)__lc_ctype_ptr->obj->mask;
#else
diff --git a/src/random.cpp b/src/random.cpp
index bd24f2e..f7f83c9 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -24,6 +24,11 @@
#include <unistd.h>
#endif // defined(_WIN32)
#include <errno.h>
+// @LOCALMOD-START
+#if defined(__native_client__)
+#include <nacl/nacl_random.h>
+#endif
+// @LOCALMOD-END
_LIBCPP_BEGIN_NAMESPACE_STD
@@ -47,22 +52,49 @@
}
#else
random_device::random_device(const string& __token)
+// @LOCALMOD-START
+#if defined(__native_client__)
+{
+ if (__token != "/dev/urandom")
+ __throw_system_error(ENODEV, ("random device not supported " + __token).c_str());
+ int error = nacl_secure_random_init();
+ if (error)
+ __throw_system_error(error, ("random device failed to open " + __token).c_str());
+}
+#else
: __f_(open(__token.c_str(), O_RDONLY))
{
if (__f_ <= 0)
__throw_system_error(errno, ("random_device failed to open " + __token).c_str());
}
+#endif
+// @LOCALMOD-END
random_device::~random_device()
{
+// @LOCALMOD-START
+#if !defined(__native_client__)
close(__f_);
+#endif
+// @LOCALMOD-END
}
unsigned
random_device::operator()()
{
unsigned r;
+// @LOCALMOD-START
+#if defined(__native_client__)
+ size_t bytes_written;
+ int error = nacl_secure_random(&r, sizeof(r), &bytes_written);
+ if (error != 0)
+ __throw_system_error(error, "random_device failed getting bytes");
+ else if (bytes_written != sizeof(r))
+ __throw_runtime_error("random_device failed obtaining enough bytes");
+#else
read(__f_, &r, sizeof(r));
+#endif
+// @LOCALMOD-END
return r;
}
#endif // defined(_WIN32)
diff --git a/src/thread.cpp b/src/thread.cpp
index 338a8a2..a7351cf 100644
--- a/src/thread.cpp
+++ b/src/thread.cpp
@@ -14,7 +14,7 @@
#include "limits"
#include <sys/types.h>
#if !defined(_WIN32)
-#if !defined(__sun__) && !defined(__linux__) && !defined(_AIX)
+#if !defined(__sun__) && !defined(__linux__) && !defined(_AIX) && !defined(__native_client__) // @LOCALMOD
#include <sys/sysctl.h>
#endif // !__sun__ && !__linux__ && !_AIX
#include <unistd.h>
diff --git a/test/lit.cfg b/test/lit.cfg
index aa45439..a49baae 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -118,7 +118,10 @@
report += "\n\nExpected compilation to fail!"
return lit.Test.FAIL, report
else:
- exec_file = tempfile.NamedTemporaryFile(suffix="exe", delete=False)
+ # @LOCALMOD-START
+ exec_file = tempfile.NamedTemporaryFile(
+ suffix=exe_suffix, delete=False)
+ # @LOCALMOD-END
exec_path = exec_file.name
exec_file.close()
@@ -144,6 +147,10 @@
cmd.extend('%s=%s' % (name, value)
for name,value in self.exec_env.items())
cmd.append(exec_path)
+ # @LOCALMOD-START
+ if shell_prefix:
+ cmd = shell_prefix + cmd
+ # @LOCALMOD-END
if lit_config.useValgrind:
cmd = lit_config.valgrindArgs + cmd
out, err, exitCode = self.execute_command(cmd, source_dir)
@@ -281,8 +288,12 @@
config.test_format = LibcxxTestFormat(
cxx_under_test,
- cpp_flags = ['-nostdinc++'] + compile_flags + include_paths,
- ld_flags = ['-nodefaultlibs'] + library_paths + ['-lc++'] + link_flags,
+ # @LOCALMOD-START
+ cpp_flags = (([] if use_system_lib else ['-nostdinc++']) +
+ compile_flags + include_paths),
+ ld_flags = (([] if use_system_lib else ['-nodefaultlibs', '-lc++']) +
+ library_paths + link_flags),
+ # @LOCALMOD-END
exec_env = exec_env)
# Get or infer the target triple.
@@ -293,6 +304,16 @@
[cxx_under_test, '-dumpmachine']).strip()
lit_config.note("inferred target_triple as: %r" % (config.target_triple,))
+# @LOCALMOD-START
+# Executable suffix.
+exe_suffix = lit.params.get('exe_suffix', "exe")
+
+# Prefix the executable command with a shell.
+shell_prefix = lit.params.get('shell_prefix', None)
+if shell_prefix:
+ shell_prefix = shlex.split(shell_prefix)
+# @LOCALMOD-END
+
# Write an "available feature" that combines the triple when use_system_lib is
# enabled. This is so that we can easily write XFAIL markers for tests that are
# known to fail with versions of libc++ as were shipped with a particular