[haiku-commits] r36010 - in haiku/branches/developer/zooey/posix-locale/src/system: kernel/lib libroot/posix/locale

Author: zooey
Date: 2010-03-30 21:55:24 +0200 (Tue, 30 Mar 2010)
New Revision: 36010
Changeset: http://dev.haiku-os.org/changeset/36010/haiku

Added:
   
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/LocaleBackend.cpp
   
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/LocaleBackend.h
   
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/localeconv.cpp
   
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/setlocale.cpp
Removed:
   
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/localeconv.c
   
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/setlocale.c
Modified:
   haiku/branches/developer/zooey/posix-locale/src/system/kernel/lib/Jamfile
   
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/Jamfile
Log:
first steps towards posix locale support:
* basic implementation for on-demand loading of a locale backend, whenever
  a locale different from POSIX/C is requested
* c++-ified localeconv.c and setlocale.c and added delegation to locale 
  backend
* adjusted kernel_lib_posix to stay limited to the POSIX locale


Modified: 
haiku/branches/developer/zooey/posix-locale/src/system/kernel/lib/Jamfile
===================================================================
--- haiku/branches/developer/zooey/posix-locale/src/system/kernel/lib/Jamfile   
2010-03-30 18:21:26 UTC (rev 36009)
+++ haiku/branches/developer/zooey/posix-locale/src/system/kernel/lib/Jamfile   
2010-03-30 19:55:24 UTC (rev 36010)
@@ -42,7 +42,7 @@
        utime.c
        # locale
        ctype.c
-       localeconv.c
+       localeconv.cpp
        # stdio (this subdir)
        kernel_vsprintf.cpp
        # stdlib

Modified: 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/Jamfile
===================================================================
--- 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/Jamfile
 2010-03-30 18:21:26 UTC (rev 36009)
+++ 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/Jamfile
 2010-03-30 19:55:24 UTC (rev 36010)
@@ -2,8 +2,9 @@
 
 MergeObject posix_locale.o :
        #ctype.c
-       localeconv.c
-       setlocale.c
+       LocaleBackend.cpp
+       localeconv.cpp
+       setlocale.cpp
        #mb_none.c
        #mblen.c
        #mbrtowc.c

Added: 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/LocaleBackend.cpp
===================================================================
--- 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/LocaleBackend.cpp
                               (rev 0)
+++ 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/LocaleBackend.cpp
       2010-03-30 19:55:24 UTC (rev 36010)
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2010, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "LocaleBackend.h"
+
+#include <locale.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+namespace BPrivate {
+
+
+LocaleBackend* gLocaleBackend = NULL;
+
+
+static pthread_once_t sBackendInitOnce = PTHREAD_ONCE_INIT;
+
+
+static void
+LoadBackend()
+{
+//     gLocaleBackend = ...
+}
+
+
+LocaleBackend::LocaleBackend()
+{
+}
+
+
+LocaleBackend::~LocaleBackend()
+{
+}
+
+
+const char*
+LocaleBackend::LocaleAccordingToEnvironment(int category)
+{
+       const char* locale = getenv("LC_ALL");
+       if (!locale || !*locale) {
+               switch(category) {
+                       case LC_COLLATE:
+                               locale = getenv("LC_COLLATE");
+                               break;
+                       case LC_CTYPE:
+                               locale = getenv("LC_CTYPE");
+                               break;
+                       case LC_MESSAGES:
+                               locale = getenv("LC_MESSAGES");
+                               break;
+                       case LC_MONETARY:
+                               locale = getenv("LC_MONETARY");
+                               break;
+                       case LC_NUMERIC:
+                               locale = getenv("LC_NUMERIC");
+                               break;
+                       case LC_TIME:
+                               locale = getenv("LC_TIME");
+                               break;
+               }
+               if (!locale || !*locale)
+                       locale = getenv("LANG");
+               if (!locale || !*locale)
+                       locale = "POSIX";
+       }
+       return locale;
+}
+
+
+status_t
+LocaleBackend::LoadBackendIfNeededFor(int category, const char* locale)
+{
+       // nothing to do if the backend is already loaded, or if it's a query
+       if (gLocaleBackend || locale == NULL)
+               return B_OK;
+
+       // update locale according to environment vars, if requested
+       if (*locale == '\0')
+               locale = LocaleAccordingToEnvironment(category);
+
+       // for any locale other than POSIX/C, we try to activate the ICU backend
+       if (strcmp(locale, "POSIX") != 0 && strcmp(locale, "C") != 0) {
+               pthread_once(&sBackendInitOnce, &LoadBackend);
+               return gLocaleBackend != NULL ? B_OK : B_ERROR;
+       }
+
+       return B_OK;
+}
+
+
+}      // namespace BPrivate

Added: 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/LocaleBackend.h
===================================================================
--- 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/LocaleBackend.h
                         (rev 0)
+++ 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/LocaleBackend.h
 2010-03-30 19:55:24 UTC (rev 36010)
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _LOCALE_BACKEND_H
+#define _LOCALE_BACKEND_H
+
+
+#include <SupportDefs.h>
+
+
+struct lconv;
+
+
+namespace BPrivate {
+
+
+class LocaleBackend {
+public:
+                                                               LocaleBackend();
+virtual                                                        
~LocaleBackend();
+
+virtual                const char*                     SetLocale(int category, 
const char *locale) = 0;
+virtual                struct lconv*           LocaleConv() = 0;
+
+static         status_t                        LoadBackendIfNeededFor(int 
category,
+                                                                       const 
char* locale);
+
+static         const char*                     
LocaleAccordingToEnvironment(int category);
+};
+
+
+extern LocaleBackend* gLocaleBackend;
+
+
+}      // namespace BPrivate
+
+
+#endif // _LOCALE_BACKEND_H

Copied: 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/localeconv.cpp
 (from rev 35983, 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/localeconv.c)
===================================================================
--- 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/localeconv.cpp
                          (rev 0)
+++ 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/localeconv.cpp
  2010-03-30 19:55:24 UTC (rev 36010)
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2002-2010 Haiku Inc. All rights reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Author:
+ *             Daniel Reinhold, danielre@xxxxxxxxxxxx
+ *             Oliver Tappe, zooey@xxxxxxxxxxxxxxx
+ */
+
+
+#include <limits.h>
+#include <locale.h>
+
+#ifndef _KERNEL_MODE
+#include "LocaleBackend.h"
+using BPrivate::gLocaleBackend;
+#endif
+
+
+/*
+ * the values below initialize the struct to the "C"/"POSIX" locale
+ * which is the only locale supported by this backend
+ */
+static struct lconv sLocale = {
+       ".",            // decimal point
+
+       "",                     // thousands separator
+       "",                     // grouping
+       "",                     // international currency symbol
+       "",                     // local currency symbol
+       "",                     // monetary decimal point
+       "",                     // monetary thousands separator
+       "",                     // monetary grouping
+       "",                     // positive sign
+       "",                     // negative sign
+
+       CHAR_MAX,       // int_frac_digits
+       CHAR_MAX,       // frac_digits
+       CHAR_MAX,       // p_cs_precedes
+       CHAR_MAX,       // p_sep_by_space
+       CHAR_MAX,       // n_cs_precedes
+       CHAR_MAX,       // n_sep_by_space
+       CHAR_MAX,       // p_sign_posn
+       CHAR_MAX        // n_sign_posn
+};
+
+
+extern "C" struct lconv*
+localeconv(void)
+{
+#ifndef _KERNEL_MODE
+       if (gLocaleBackend)
+               return gLocaleBackend->LocaleConv();
+#endif
+
+       return &sLocale;
+}

Copied: 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/setlocale.cpp
 (from rev 35983, 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/setlocale.c)
===================================================================
--- 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/setlocale.cpp
                           (rev 0)
+++ 
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/setlocale.cpp
   2010-03-30 19:55:24 UTC (rev 36010)
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2004-2007, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx
+ * Copyright 2010, Oliver Tappe, zooey@xxxxxxxxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+
+
+#include "LocaleBackend.h"
+
+
+using BPrivate::gLocaleBackend;
+using BPrivate::LocaleBackend;
+
+
+extern "C" char *
+setlocale(int category, const char *locale)
+{
+       if (!gLocaleBackend) {
+               if (LocaleBackend::LoadBackendIfNeededFor(category, locale) != 
B_OK)
+                       return NULL;
+       }
+
+       if (gLocaleBackend)
+               return const_cast<char*>(gLocaleBackend->SetLocale(category, 
locale));
+
+       return "POSIX";
+}


Other related posts: