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"; +}