Hi jfb, danalbert,

Give newlocale/freelocale/duplocale/uselocale something closer to how the real 
ones would behave, fixing failures like:

```
terminating with uncaught exception of type std::runtime_error: 
collate_byname<char>::collate_byname failed to construct for C
```
in tests like:

```
localization/locales/locale/locale.statics/classic.pass.cpp
```

http://reviews.llvm.org/D5418

Files:
  include/support/newlib/xlocale.h
  src/support/newlib/xlocale.cpp
Index: include/support/newlib/xlocale.h
===================================================================
--- include/support/newlib/xlocale.h
+++ include/support/newlib/xlocale.h
@@ -22,22 +22,12 @@
 #endif
 
 // Patch over newlib's lack of extended locale support
-typedef void *locale_t;
-static inline locale_t duplocale(locale_t) {
-  return NULL;
-}
+typedef const char *locale_t;
+locale_t duplocale(locale_t);
+void freelocale(locale_t);
+locale_t newlocale(int, const char *, locale_t);
+locale_t uselocale(locale_t);
 
-static inline void freelocale(locale_t) {
-}
-
-static inline locale_t newlocale(int, const char *, locale_t) {
-  return NULL;
-}
-
-static inline locale_t uselocale(locale_t) {
-  return NULL;
-}
-
 #define LC_COLLATE_MASK  (1 << LC_COLLATE)
 #define LC_CTYPE_MASK    (1 << LC_CTYPE)
 #define LC_MESSAGES_MASK (1 << LC_MESSAGES)
Index: src/support/newlib/xlocale.cpp
===================================================================
--- src/support/newlib/xlocale.cpp
+++ src/support/newlib/xlocale.cpp
@@ -0,0 +1,57 @@
+// -*- C++ -*-
+//===--------------------- support/newlib/xlocale.cpp ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <support/newlib/xlocale.h>
+#include <cstring>
+
+static locale_t CLocale;
+
+locale_t duplocale(locale_t old_locale) {
+  size_t len = strlen(old_locale);
+  locale_t new_locale = (locale_t) malloc(len);
+  if (!new_locale)
+  strncpy(const_cast<char *>(new_locale), old_locale, len);
+  return new_locale;
+}
+
+void freelocale(locale_t l) {
+  if (l != CLocale)
+    free(const_cast<char *>(l));
+}
+
+locale_t newlocale(int mask, const char *locale, locale_t base) {
+  // Since newlib only supports the 'C' / 'POSIX' locale...
+  (void)mask;
+  (void)base;
+
+  if ((locale == NULL) || (locale[0] == '\0') ||
+      ((locale[0] == 'C') && (locale[1] == '\0')) ||
+      ((locale[0] == 'P') && (locale[1] == 'O') && (locale[2] == 'S') &&
+       (locale[3] == 'I') && (locale[4] == 'X') && (locale[5] == '\0'))) {
+    return CLocale;
+  }
+
+  return 0;
+}
+
+locale_t uselocale(locale_t new_locale) {
+  locale_t old_locale = setlocale(LC_ALL, 0);
+  if ( new_locale == NULL )
+      return old_locale;
+  setlocale(LC_ALL, new_locale );
+  return old_locale;
+}
+
+// TODO(jroelofs): Is this multithread-safe? Do we care?
+__attribute__((constructor))
+static void initCLocale() {
+  CLocale = setlocale(LC_ALL, "C");
+}
+
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to