[cfe-commits] [libcxx] r151721 - in /libcxx/trunk: include/support/solaris/ include/support/solaris/floatingpoint.h include/support/solaris/wchar.h include/support/solaris/xlocale.h src/support/solaris/ src/support/solaris/README src/support/solaris/mbsnrtowcs.inc src/support/solaris/wcsnrtombs.inc src/support/solaris/xlocale.c

David Chisnall csdavec at swan.ac.uk
Wed Feb 29 05:17:29 PST 2012


Author: theraven
Date: Wed Feb 29 07:17:28 2012
New Revision: 151721

URL: http://llvm.org/viewvc/llvm-project?rev=151721&view=rev
Log:
Add support files required for building on Solaris.


Added:
    libcxx/trunk/include/support/solaris/
    libcxx/trunk/include/support/solaris/floatingpoint.h
    libcxx/trunk/include/support/solaris/wchar.h
    libcxx/trunk/include/support/solaris/xlocale.h
    libcxx/trunk/src/support/solaris/
    libcxx/trunk/src/support/solaris/README
    libcxx/trunk/src/support/solaris/mbsnrtowcs.inc
    libcxx/trunk/src/support/solaris/wcsnrtombs.inc
    libcxx/trunk/src/support/solaris/xlocale.c

Added: libcxx/trunk/include/support/solaris/floatingpoint.h
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/support/solaris/floatingpoint.h?rev=151721&view=auto
==============================================================================
--- libcxx/trunk/include/support/solaris/floatingpoint.h (added)
+++ libcxx/trunk/include/support/solaris/floatingpoint.h Wed Feb 29 07:17:28 2012
@@ -0,0 +1,5 @@
+#define atof sun_atof
+#define strtod sun_strtod
+#include_next "floatingpoint.h"
+#undef atof
+#undef strtod

Added: libcxx/trunk/include/support/solaris/wchar.h
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/support/solaris/wchar.h?rev=151721&view=auto
==============================================================================
--- libcxx/trunk/include/support/solaris/wchar.h (added)
+++ libcxx/trunk/include/support/solaris/wchar.h Wed Feb 29 07:17:28 2012
@@ -0,0 +1,37 @@
+#define iswalpha sun_iswalpha
+#define iswupper sun_iswupper
+#define iswlower sun_iswlower
+#define iswdigit sun_iswdigit
+#define iswxdigit sun_iswxdigit
+#define iswalnum sun_iswalnum
+#define iswspace sun_iswspace
+#define iswpunct sun_iswpunct
+#define iswprint sun_iswprint
+#define iswgraph sun_iswgraph
+#define iswcntrl sun_iswcntrl
+#define iswctype sun_iswctype
+#define towlower sun_towlower
+#define towupper sun_towupper
+#define wcswcs sun_wcswcs
+#define wcswidth sun_wcswidth
+#define wcwidth sun_wcwidth
+#define wctype sun_wctype
+#include_next "wchar.h"
+#undef iswalpha 
+#undef iswupper
+#undef iswlower
+#undef iswdigit
+#undef iswxdigit
+#undef iswalnum
+#undef iswspace
+#undef iswpunct
+#undef iswprint
+#undef iswgraph
+#undef iswcntrl
+#undef iswctype
+#undef towlower
+#undef towupper
+#undef wcswcs
+#undef wcswidth
+#undef wcwidth
+#undef wctype

Added: libcxx/trunk/include/support/solaris/xlocale.h
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/support/solaris/xlocale.h?rev=151721&view=auto
==============================================================================
--- libcxx/trunk/include/support/solaris/xlocale.h (added)
+++ libcxx/trunk/include/support/solaris/xlocale.h Wed Feb 29 07:17:28 2012
@@ -0,0 +1,146 @@
+////////////////////////////////////////////////////////////////////////////////
+// Minimal xlocale implementation for Solaris.  This implements the subset of
+// the xlocale APIs that libc++ depends on.
+////////////////////////////////////////////////////////////////////////////////
+#ifndef __XLOCALE_H_INCLUDED
+#define __XLOCALE_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct _LC_locale_t* locale_t;
+
+#define LC_COLLATE_MASK  (1<<0)
+#define LC_CTYPE_MASK    (1<<1)
+#define LC_MESSAGES_MASK (1<<2)
+#define LC_MONETARY_MASK (1<<3)
+#define LC_NUMERIC_MASK  (1<<4)
+#define LC_TIME_MASK     (1<<5)
+#define LC_ALL_MASK      (LC_COLLATE_MASK | LC_CTYPE_MASK | LC_MESSAGES_MASK | \
+                LC_MONETARY_MASK | LC_NUMERIC_MASK | LC_TIME_MASK)
+
+#define LC_GLOBAL_LOCALE ((locale_t)-1)
+
+size_t __mb_cur_max(locale_t l);
+#define MB_CUR_MAX_L(l) __mb_cur_max(l) 
+
+locale_t newlocale(int mask, const char * locale, locale_t base);
+void freelocale(locale_t loc);
+
+wint_t btowc_l(int __c, locale_t __l);
+
+int wctob_l(wint_t __c, locale_t __l);
+
+size_t wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l);
+
+size_t mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
+                 mbstate_t *__ps, locale_t __l);
+
+int mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l);
+
+size_t mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l);
+
+struct lconv *localeconv_l(locale_t __l);
+
+size_t mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
+                   mbstate_t *__ps, locale_t __l);
+
+int sprintf_l(char *__s, locale_t __l, const char *__format, ...);
+
+int snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...);
+
+int asprintf_l(char **__s, locale_t __l, const char *__format, ...);
+
+int sscanf_l(const char *__s, locale_t __l, const char *__format, ...);
+
+int isalnum_l(int,locale_t);
+int isalpha_l(int,locale_t);
+int isblank_l(int,locale_t);
+int iscntrl_l(int,locale_t);
+int isdigit_l(int,locale_t);
+int isgraph_l(int,locale_t);
+int islower_l(int,locale_t);
+int isprint_l(int,locale_t);
+int ispunct_l(int,locale_t);
+int isspace_l(int,locale_t);
+int isupper_l(int,locale_t);
+int isxdigit_l(int,locale_t);
+
+int iswalnum_l(wchar_t,locale_t);
+int iswalpha_l(wchar_t,locale_t);
+int iswblank_l(wchar_t,locale_t);
+int iswcntrl_l(wchar_t,locale_t);
+int iswdigit_l(wchar_t,locale_t);
+int iswgraph_l(wchar_t,locale_t);
+int iswlower_l(wchar_t,locale_t);
+int iswprint_l(wchar_t,locale_t);
+int iswpunct_l(wchar_t,locale_t);
+int iswspace_l(wchar_t,locale_t);
+int iswupper_l(wchar_t,locale_t);
+int iswxdigit_l(wchar_t,locale_t);
+
+int iswctype_l(wint_t, wctype_t, locale_t);
+
+int toupper_l(int __c, locale_t __l);
+int tolower_l(int __c, locale_t __l);
+wint_t towupper_l(wint_t __c, locale_t __l);
+wint_t towlower_l(wint_t __c, locale_t __l);
+
+
+int strcoll_l(const char *__s1, const char *__s2, locale_t __l);
+int wcscoll_l(const wchar_t *__s1, const wchar_t *__s2, locale_t __l);
+size_t strftime_l(char *__s, size_t __size, const char *__fmt, const struct tm
+    *__tm, locale_t __l);
+
+size_t strxfrm_l(char *__s1, const char *__s2, size_t __n, locale_t __l);
+
+size_t wcsxfrm_l(wchar_t *__ws1, const wchar_t *__ws2, size_t __n,
+    locale_t __l);
+
+
+
+size_t
+mbsnrtowcs_l(wchar_t * __restrict dst, const char ** __restrict src,
+    size_t nms, size_t len, mbstate_t * __restrict ps, locale_t loc);
+
+
+size_t
+wcsnrtombs_l(char * __restrict dst, const wchar_t ** __restrict src,
+    size_t nwc, size_t len, mbstate_t * __restrict ps, locale_t loc);
+
+locale_t __cloc(void);
+
+// FIXME: These are quick-and-dirty hacks to make things pretend to work
+static inline
+long long strtoll_l(const char *__nptr, char **__endptr,
+    int __base, locale_t __loc) {
+  return strtoll(__nptr, __endptr, __base);
+}
+static inline
+long strtol_l(const char *__nptr, char **__endptr,
+    int __base, locale_t __loc) {
+  return strtol(__nptr, __endptr, __base);
+}
+static inline
+long double strtold_l(const char *__nptr, char **__endptr,
+    locale_t __loc) {
+  return strtold(__nptr, __endptr);
+}
+static inline
+unsigned long long strtoull_l(const char *__nptr, char **__endptr,
+    int __base, locale_t __loc) {
+  return strtoull(__nptr, __endptr, __base);
+}
+static inline
+unsigned long strtoul_l(const char *__nptr, char **__endptr,
+    int __base, locale_t __loc) {
+  return strtoul(__nptr, __endptr, __base);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

Added: libcxx/trunk/src/support/solaris/README
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/support/solaris/README?rev=151721&view=auto
==============================================================================
--- libcxx/trunk/src/support/solaris/README (added)
+++ libcxx/trunk/src/support/solaris/README Wed Feb 29 07:17:28 2012
@@ -0,0 +1,4 @@
+This directory contains a partial implementation of the xlocale APIs for
+Solaris.  Some portions are lifted from FreeBSD libc, and so are covered by a
+2-clause BSD license instead of the MIT/UUIC license that the rest of libc++ is
+distributed under.

Added: libcxx/trunk/src/support/solaris/mbsnrtowcs.inc
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/support/solaris/mbsnrtowcs.inc?rev=151721&view=auto
==============================================================================
--- libcxx/trunk/src/support/solaris/mbsnrtowcs.inc (added)
+++ libcxx/trunk/src/support/solaris/mbsnrtowcs.inc Wed Feb 29 07:17:28 2012
@@ -0,0 +1,76 @@
+
+
+/*-
+ * As noted in the source, some portions of this implementation are copied from
+ * FreeBSD libc.  These are covered by the following copyright:
+ *
+ * Copyright (c) 2002-2004 Tim J. Robbins.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+size_t
+mbsnrtowcs_l(wchar_t * __restrict dst, const char ** __restrict src,
+    size_t nms, size_t len, mbstate_t * __restrict ps, locale_t loc)
+{
+  const char *s;
+  size_t nchr;
+  wchar_t wc;
+  size_t nb;
+  FIX_LOCALE(loc);
+
+  s = *src;
+  nchr = 0;
+
+  if (dst == NULL) {
+    for (;;) {
+      if ((nb = mbrtowc_l(&wc, s, nms, ps, loc)) == (size_t)-1)
+        /* Invalid sequence - mbrtowc() sets errno. */
+        return ((size_t)-1);
+      else if (nb == 0 || nb == (size_t)-2)
+        return (nchr);
+      s += nb;
+      nms -= nb;
+      nchr++;
+    }
+    /*NOTREACHED*/
+  }
+
+  while (len-- > 0) {
+    if ((nb = mbrtowc_l(dst, s, nms, ps, loc)) == (size_t)-1) {
+      *src = s;
+      return ((size_t)-1);
+    } else if (nb == (size_t)-2) {
+      *src = s + nms;
+      return (nchr);
+    } else if (nb == 0) {
+      *src = NULL;
+      return (nchr);
+    }
+    s += nb;
+    nms -= nb;
+    nchr++;
+    dst++;
+  }
+  *src = s;
+  return (nchr);
+}

Added: libcxx/trunk/src/support/solaris/wcsnrtombs.inc
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/support/solaris/wcsnrtombs.inc?rev=151721&view=auto
==============================================================================
--- libcxx/trunk/src/support/solaris/wcsnrtombs.inc (added)
+++ libcxx/trunk/src/support/solaris/wcsnrtombs.inc Wed Feb 29 07:17:28 2012
@@ -0,0 +1,93 @@
+/*-
+ * Copyright (c) 2002-2004 Tim J. Robbins.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+size_t
+wcsnrtombs_l(char * __restrict dst, const wchar_t ** __restrict src,
+    size_t nwc, size_t len, mbstate_t * __restrict ps, locale_t loc)
+{
+  FIX_LOCALE(loc);
+  mbstate_t mbsbak;
+  char buf[MB_CUR_MAX_L(loc)];
+  const wchar_t *s;
+  size_t nbytes;
+  size_t nb;
+
+  s = *src;
+  nbytes = 0;
+
+  if (dst == NULL) {
+    while (nwc-- > 0) {
+      if ((nb = wcrtomb_l(buf, *s, ps, loc)) == (size_t)-1)
+        /* Invalid character - wcrtomb() sets errno. */
+        return ((size_t)-1);
+      else if (*s == L'\0')
+        return (nbytes + nb - 1);
+      s++;
+      nbytes += nb;
+    }
+    return (nbytes);
+  }
+
+  while (len > 0 && nwc-- > 0) {
+    if (len > (size_t)MB_CUR_MAX_L(loc)) {
+      /* Enough space to translate in-place. */
+      if ((nb = wcrtomb_l(dst, *s, ps, loc)) == (size_t)-1) {
+        *src = s;
+        return ((size_t)-1);
+      }
+    } else {
+      /*
+       * May not be enough space; use temp. buffer.
+       *
+       * We need to save a copy of the conversion state
+       * here so we can restore it if the multibyte
+       * character is too long for the buffer.
+       */
+      mbsbak = *ps;
+      if ((nb = wcrtomb_l(buf, *s, ps, loc)) == (size_t)-1) {
+        *src = s;
+        return ((size_t)-1);
+      }
+      if (nb > (int)len) {
+        /* MB sequence for character won't fit. */
+        *ps = mbsbak;
+        break;
+      }
+      memcpy(dst, buf, nb);
+    }
+    if (*s == L'\0') {
+      *src = NULL;
+      return (nbytes + nb - 1);
+    }
+    s++;
+    dst += nb;
+    len -= nb;
+    nbytes += nb;
+  }
+  *src = s;
+  return (nbytes);
+}
+

Added: libcxx/trunk/src/support/solaris/xlocale.c
URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/src/support/solaris/xlocale.c?rev=151721&view=auto
==============================================================================
--- libcxx/trunk/src/support/solaris/xlocale.c (added)
+++ libcxx/trunk/src/support/solaris/xlocale.c Wed Feb 29 07:17:28 2012
@@ -0,0 +1,245 @@
+
+#ifdef __sun__
+      
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h> 
+#include <dlfcn.h>
+#include <locale.h>
+#include <limits.h>
+#include <assert.h>
+#include <sys/localedef.h>
+#include "xlocale.h"
+
+static _LC_locale_t *__C_locale;
+
+#define FIX_LOCALE(l) l = (l == 0) ? __C_locale : l
+
+#include "mbsnrtowcs.inc"
+#include "wcsnrtombs.inc"
+      
+size_t __mb_cur_max(locale_t __l) {
+  FIX_LOCALE(__l);
+  return (__l->lc_ctype->cmapp->cm_mb_cur_max);
+}
+
+wint_t btowc_l(int __c, locale_t __l) {
+  FIX_LOCALE(__l);
+  return __l->lc_ctype->cmapp->core.user_api->btowc(__l->lc_ctype->cmapp, __c);
+}
+
+int wctob_l(wint_t __c, locale_t __l) {
+  FIX_LOCALE(__l);
+  return __l->lc_ctype->cmapp->core.user_api->wctob(__l->lc_ctype->cmapp, __c);
+}
+
+size_t wcrtomb_l(char *__s, wchar_t __wc, mbstate_t *__ps, locale_t __l) {
+  FIX_LOCALE(__l);
+  return __l->lc_ctype->cmapp->core.user_api->wcrtomb(__l->lc_ctype->cmapp,
+      __s, __wc, __ps);
+}
+
+size_t mbrtowc_l(wchar_t *__pwc, const char *__s, size_t __n,
+                 mbstate_t *__ps, locale_t __l) {
+  FIX_LOCALE(__l);
+  return __l->lc_ctype->cmapp->core.user_api->mbrtowc(__l->lc_ctype->cmapp,
+      __pwc, __s, __n, __ps);
+}
+
+int mbtowc_l(wchar_t *__pwc, const char *__pmb, size_t __max, locale_t __l) {
+  FIX_LOCALE(__l);
+  return __l->lc_ctype->cmapp->core.user_api->mbtowc(__l->lc_ctype->cmapp,
+      __pwc, __pmb, __max);
+} 
+  
+size_t mbrlen_l(const char *__s, size_t __n, mbstate_t *__ps, locale_t __l) {
+  FIX_LOCALE(__l);
+  return __l->lc_ctype->cmapp->core.user_api->mbrlen(__l->lc_ctype->cmapp, __s,
+    __n, __ps);
+}
+
+struct lconv *localeconv_l(locale_t __l) {
+  FIX_LOCALE(__l);
+  return __l->core.user_api->localeconv(__l);
+} 
+  
+size_t mbsrtowcs_l(wchar_t *__dest, const char **__src, size_t __len,
+                   mbstate_t *__ps, locale_t __l) {
+  FIX_LOCALE(__l);
+  return __l->lc_ctype->cmapp->core.user_api->mbsrtowcs(__l->lc_ctype->cmapp,
+      __dest, __src, __len, __ps);
+}
+
+int wcscoll_l(const wchar_t *__s1, const wchar_t *__s2, locale_t __l) {
+  FIX_LOCALE(__l);
+  return __l->lc_collate->core.user_api->wcscoll(__l->lc_collate,
+      __s1, __s2);
+}
+
+int strcoll_l(const char *__s1, const char *__s2, locale_t __l) {
+  FIX_LOCALE(__l);
+  return __l->lc_collate->core.user_api->strcoll(__l->lc_collate,
+      __s1, __s2);
+}
+
+size_t strxfrm_l(char *__s1, const char *__s2, size_t __n, locale_t __l) {
+  FIX_LOCALE(__l);
+  return __l->lc_collate->core.user_api->strxfrm(__l->lc_collate,
+      __s1, __s2, __n);
+}
+size_t strftime_l(char *__s, size_t __size, const char *__fmt, const struct tm
+    *__tm, locale_t __l) {
+  FIX_LOCALE(__l);
+  return __l->lc_time->core.user_api->strftime(__l->lc_time,
+      __s, __size, __fmt, __tm);
+}
+
+size_t wcsxfrm_l(wchar_t *__ws1, const wchar_t *__ws2, size_t __n,
+    locale_t __l) {
+  FIX_LOCALE(__l);
+  return __l->lc_collate->core.user_api->wcsxfrm(__l->lc_collate,
+      __ws1, __ws2, __n);
+}
+
+#define LOCALE_ISCTYPE(ctype, m) \
+  int is##ctype##_l(int __c, locale_t __l) { \
+    if ((__c < 0) || (__c > 255)) return 0;\
+    FIX_LOCALE(__l);\
+    return __l->lc_ctype->mask[__c] & m;\
+  }\
+  int isw##ctype##_l(wchar_t __c, locale_t __l) { \
+    FIX_LOCALE(__l);\
+    return __l->lc_ctype->core.user_api->iswctype(__l->lc_ctype, __c, m);\
+  }
+
+LOCALE_ISCTYPE(alnum, _ISALNUM)
+LOCALE_ISCTYPE(alpha, _ISALPHA)
+LOCALE_ISCTYPE(blank, _ISALPHA)
+LOCALE_ISCTYPE(cntrl, _ISCNTRL)
+LOCALE_ISCTYPE(digit, _ISDIGIT)
+LOCALE_ISCTYPE(graph, _ISGRAPH)
+LOCALE_ISCTYPE(lower, _ISLOWER)
+LOCALE_ISCTYPE(print, _ISPRINT)
+LOCALE_ISCTYPE(punct, _ISPUNCT)
+LOCALE_ISCTYPE(space, _ISSPACE)
+LOCALE_ISCTYPE(upper, _ISUPPER)
+LOCALE_ISCTYPE(xdigit, _ISXDIGIT)
+
+int iswctype_l(wint_t __c, wctype_t __m, locale_t __l) {
+    FIX_LOCALE(__l);\
+    return __l->lc_ctype->core.user_api->iswctype(__l->lc_ctype, __c, __m);\
+}
+
+int toupper_l(int __c, locale_t __l) {
+  FIX_LOCALE(__l);
+    if ((__c < 0) || (__c > __l->lc_ctype->max_upper)) return __c;
+  return __l->lc_ctype->upper[__c];
+}
+int tolower_l(int __c, locale_t __l) {
+  FIX_LOCALE(__l);
+  if ((__c < 0) || (__c > __l->lc_ctype->max_lower)) return __c;
+  return __l->lc_ctype->lower[__c];
+}
+wint_t towupper_l(wint_t __c, locale_t __l) {
+  FIX_LOCALE(__l);
+  return __l->lc_ctype->core.user_api->towupper(__l->lc_ctype, __c);
+}
+wint_t towlower_l(wint_t __c, locale_t __l) {
+  FIX_LOCALE(__l);
+  return __l->lc_ctype->core.user_api->towlower(__l->lc_ctype, __c);
+}
+
+// FIXME: This disregards the locale, which is Very Wrong
+#define vsnprintf_l(__s, __n, __l, __format, __va)  \
+    vsnprintf(__s, __n, __format, __va) 
+
+int sprintf_l(char *__s, locale_t __l, const char *__format, ...) {
+  va_list __va;
+  va_start(__va, __format);
+  int __res = vsnprintf_l(__s, SIZE_MAX, __l, __format, __va);
+  va_end(__va);
+  return __res;
+}
+
+int snprintf_l(char *__s, size_t __n, locale_t __l, const char *__format, ...)
+{
+  va_list __va;
+  va_start(__va, __format);
+  int __res = vsnprintf_l(__s, __n , __l, __format, __va);
+  va_end(__va);
+  return __res;
+}
+
+int asprintf_l(char **__s, locale_t __l, const char *__format, ...) {
+  va_list __va;
+  va_start(__va, __format);
+  // FIXME:
+  int __res = vasprintf(__s, __format, __va);
+  va_end(__va);
+  return __res;
+}
+
+int sscanf_l(const char *__s, locale_t __l, const char *__format, ...) {
+  va_list __va;
+  va_start(__va, __format);
+  // FIXME:
+  int __res = vsscanf(__s, __format, __va);
+  va_end(__va);
+  return __res;
+}
+
+locale_t newlocale(int mask, const char *locale, locale_t base) {
+
+  if ((locale == NULL) || (locale[0] == '\0') ||
+      ((locale[0] == 'C') && (locale[1] == '\0')))
+  {
+    return __C_locale;
+  }
+
+  // Solaris locales are shared libraries that contain 
+  char *path;
+#ifdef __LP64
+  asprintf(&path, "/usr/lib/locale/%1$s/amd64/%1$s.so.3", locale);
+#else
+  asprintf(&path, "/usr/lib/locale/%1$s/%1$s.so.3", locale);
+#endif
+  void *handle = dlopen(path, RTLD_LOCAL | RTLD_NOW);
+  free(path);
+  if (!handle) 
+    return 0;
+  _LC_locale_t *(*init)() = dlsym(handle, "instantiate");
+  if (!init)
+    return 0;
+  _LC_locale_t  *p = init();
+  if (!p)
+    return 0;
+
+  if (!base)
+    base = __C_locale;
+
+  locale_t ret = calloc(1, sizeof(struct _LC_locale_t));
+  memcpy(ret, p, sizeof (_LC_locale_t));
+  ret->lc_collate = (mask & LC_COLLATE_MASK) ? p->lc_collate : base->lc_collate;
+  ret->lc_ctype = (mask & LC_CTYPE_MASK) ? p->lc_ctype : base->lc_ctype;
+  ret->lc_messages = (mask & LC_MESSAGES_MASK) ? p->lc_messages : base->lc_messages;
+  ret->lc_monetary = (mask & LC_MONETARY_MASK) ? p->lc_monetary : base->lc_monetary;
+  ret->lc_time = (mask & LC_TIME_MASK) ? p->lc_time : base->lc_time;
+  return ret;
+}
+
+void freelocale(locale_t loc)
+{
+  if (loc != __C_locale)
+    free(loc);
+}
+
+__attribute__((constructor))
+static void setupCLocale(void) {
+  // The default initial locale is the C locale.  This is a statically
+  // allocated locale inside libc.  At program start, __lc_locale will point to
+  // this.  We need to grab a copy because it's not a public symbol.  If we had
+  // access to the source code for libc, then we'd just use it directly...
+  assert('C' == setlocale(LC_ALL, 0)[0]);
+  __C_locale = __lc_locale;
+}
+#endif





More information about the cfe-commits mailing list