[haiku-commits] r36341 - in haiku/branches/developer/zooey/posix-locale: headers/private/libroot headers/private/libroot/locale headers/private/libroot/time src/system/libroot/posix/locale src/system/libroot/posix/time ...
- From: zooey@xxxxxxxxxxxxxxx
- To: haiku-commits@xxxxxxxxxxxxx
- Date: Sun, 18 Apr 2010 22:18:40 +0200 (CEST)
Author: zooey
Date: 2010-04-18 22:18:40 +0200 (Sun, 18 Apr 2010)
New Revision: 36341
Changeset: http://dev.haiku-os.org/changeset/36341/haiku
Added:
haiku/branches/developer/zooey/posix-locale/headers/private/libroot/locale/
haiku/branches/developer/zooey/posix-locale/headers/private/libroot/locale/ICULocaleBackend.h
haiku/branches/developer/zooey/posix-locale/headers/private/libroot/locale/LocaleBackend.h
haiku/branches/developer/zooey/posix-locale/headers/private/libroot/time/timelocal.h
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/time/timelocal.cpp
Removed:
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.h
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/LocaleBackend.h
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/time/timelocal.c
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/time/timelocal.h
Modified:
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.cpp
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/Jamfile
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/time/Jamfile
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/time/strftime.c
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/time/strptime.c
haiku/branches/developer/zooey/posix-locale/src/tests/system/libroot/posix/locale_test.cpp
Log:
implemented support for LC-time information, as used in strftime() and
strptime():
* fleshed out TimeData in ICULocaleBackend, which is now fetching all the
information required to fill lc_time_t from ICU
* moved timelocal.h to headers/private/time
* moved locale-private headers to headers/private/locale
* adjusted strftime() and strptime() to make use of LocaleBackend
* added tests for LC-time info to locale_test
* adjusted codings style of class declarations to use one indent before
the "virtual"/"static" keyword
Copied:
haiku/branches/developer/zooey/posix-locale/headers/private/libroot/locale/ICULocaleBackend.h
(from rev 36176,
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.h)
===================================================================
---
haiku/branches/developer/zooey/posix-locale/headers/private/libroot/locale/ICULocaleBackend.h
(rev 0)
+++
haiku/branches/developer/zooey/posix-locale/headers/private/libroot/locale/ICULocaleBackend.h
2010-04-18 20:18:40 UTC (rev 36341)
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2010, Oliver Tappe, zooey@xxxxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _ICU_LOCALE_BACKEND_H
+#define _ICU_LOCALE_BACKEND_H
+
+
+#include <unicode/dcfmtsym.h>
+#include <unicode/datefmt.h>
+#include <unicode/locid.h>
+#include <unicode/ucnv.h>
+#include <unicode/unistr.h>
+
+#include "LocaleBackend.h"
+
+
+namespace BPrivate {
+
+
+typedef DecimalFormatSymbols::ENumberFormatSymbol FormatSymbol;
+
+class CategoryData {
+public:
+ CategoryData();
+ virtual ~CategoryData();
+
+ virtual status_t SetTo(const Locale& locale,
+ const
char* posixLocaleName);
+
+ const char * PosixLocaleName()
+ {
return fPosixLocaleName; }
+
+protected:
+ status_t
_ConvertUnicodeStringToLocaleconvEntry(
+ const
UnicodeString& string,
+ char*
destination, int destinationSize,
+ char*
defaultValue = "");
+
+ static const uint16 skMaxPosixLocaleNameLen = 128;
+
+ Locale fLocale;
+ UConverter* fConverter;
+ char
fPosixLocaleName[skMaxPosixLocaleNameLen];
+ char
fGivenCharset[UCNV_MAX_CONVERTER_NAME_LENGTH];
+};
+
+
+class CollateData : public CategoryData {
+public:
+ virtual status_t SetTo(const Locale& locale,
+
const char* posixLocaleName);
+};
+
+
+class CtypeData : public CategoryData {
+public:
+ CtypeData();
+ virtual ~CtypeData();
+
+ virtual status_t SetTo(const Locale& locale,
+ const
char* posixLocaleName);
+
+private:
+};
+
+
+class MessagesData : public CategoryData {
+public:
+ virtual status_t SetTo(const Locale& locale,
+ const
char* posixLocaleName);
+};
+
+
+class LocaleconvData : public CategoryData {
+protected:
+ status_t _SetLocaleconvEntry(
+ const
DecimalFormatSymbols* formatSymbols,
+ char*
destination, FormatSymbol symbol,
+ char*
defaultValue = "");
+};
+
+
+class MonetaryData : public LocaleconvData {
+public:
+ static const int32
kParenthesesAroundCurrencyAndValue = 0;
+ static const int32 kSignPrecedesCurrencyAndValue
= 1;
+ static const int32 kSignSucceedsCurrencyAndValue
= 2;
+ static const int32
kSignImmediatelyPrecedesCurrency = 3;
+ static const int32
kSignImmediatelySucceedsCurrency = 4;
+
+ virtual status_t SetTo(const Locale& locale,
+ const
char* posixLocaleName);
+
+private:
+ static const int32 kCsPrecedesFlag = 1 << 0;
+ static const int32 kSepBySpaceFlag = 1 << 1;
+
+ int32
_DetermineCurrencyPosAndSeparator(
+ const
UnicodeString& prefix,
+ const
UnicodeString& suffix,
+ const
UnicodeString& signSymbol,
+ const
UnicodeString& currencySymbol,
+ UChar&
currencySeparatorChar);
+ int32 _DetermineSignPos(const
UnicodeString& prefix,
+ const
UnicodeString& suffix,
+ const
UnicodeString& signSymbol,
+ const
UnicodeString& currencySymbol);
+};
+
+
+class NumericData : public LocaleconvData {
+public:
+ virtual status_t SetTo(const Locale& locale,
+ const
char* posixLocaleName);
+};
+
+
+class TimeData : public CategoryData {
+public:
+ virtual status_t SetTo(const Locale& locale,
+ const
char* posixLocaleName);
+
+private:
+ status_t _SetLCTimeEntries(const
UnicodeString* strings,
+ char*
destination, int entrySize,
+ int
count, int maxCount);
+ status_t
_SetLCTimePattern(DateFormat* format,
+ char*
destination, int destinationSize);
+};
+
+
+class ICULocaleBackend : public LocaleBackend {
+public:
+
ICULocaleBackend();
+ virtual ~ICULocaleBackend();
+
+ virtual const char* SetLocale(int category,
+ const
char* posixLocaleName);
+ virtual const struct lconv* LocaleConv();
+ virtual const struct lc_time_t* LCTimeInfo();
+
+private:
+ const char* _QueryLocale(int
category);
+
+ CollateData fCollateData;
+ CtypeData fCtypeData;
+ MessagesData fMessagesData;
+ MonetaryData fMonetaryData;
+ NumericData fNumericData;
+ TimeData fTimeData;
+};
+
+
+} // namespace BPrivate
+
+
+#endif // _ICU_LOCALE_BACKEND_H
Copied:
haiku/branches/developer/zooey/posix-locale/headers/private/libroot/locale/LocaleBackend.h
(from rev 36014,
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/LocaleBackend.h)
===================================================================
---
haiku/branches/developer/zooey/posix-locale/headers/private/libroot/locale/LocaleBackend.h
(rev 0)
+++
haiku/branches/developer/zooey/posix-locale/headers/private/libroot/locale/LocaleBackend.h
2010-04-18 20:18:40 UTC (rev 36341)
@@ -0,0 +1,38 @@
+/*
+ * 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;
+struct lc_time_t;
+
+
+namespace BPrivate {
+
+
+class LocaleBackend {
+public:
+ LocaleBackend();
+ virtual ~LocaleBackend();
+
+ virtual const char* SetLocale(int category, const
char* locale) = 0;
+ virtual const struct lconv* LocaleConv() = 0;
+ virtual const struct lc_time_t* LCTimeInfo() = 0;
+
+ static status_t LoadBackend();
+};
+
+
+extern LocaleBackend* gLocaleBackend;
+
+
+} // namespace BPrivate
+
+
+#endif // _LOCALE_BACKEND_H
Copied:
haiku/branches/developer/zooey/posix-locale/headers/private/libroot/time/timelocal.h
(from rev 35983,
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/time/timelocal.h)
===================================================================
---
haiku/branches/developer/zooey/posix-locale/headers/private/libroot/time/timelocal.h
(rev 0)
+++
haiku/branches/developer/zooey/posix-locale/headers/private/libroot/time/timelocal.h
2010-04-18 20:18:40 UTC (rev 36341)
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 1997-2002 FreeBSD Project.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * $FreeBSD: /repoman/r/ncvs/src/lib/libc/stdtime/timelocal.h,v 1.11
2002/01/24 15:07:44 phantom Exp $
+ */
+#ifndef _TIMELOCAL_H_
+#define _TIMELOCAL_H_
+
+
+#include <sys/cdefs.h>
+
+
+/*
+ * Private header file for the strftime and strptime localization
+ * stuff.
+ */
+struct lc_time_t {
+ const char* mon[12];
+ const char* month[12];
+ const char* wday[7];
+ const char* weekday[7];
+ const char* X_fmt;
+ const char* x_fmt;
+ const char* c_fmt;
+ const char* am;
+ const char* pm;
+ const char* date_fmt;
+ const char* alt_month[12];
+ const char* md_order;
+ const char* ampm_fmt;
+};
+
+__BEGIN_DECLS
+const struct lc_time_t* __get_current_time_locale(void);
+__END_DECLS
+
+
+#endif /* !_TIMELOCAL_H_ */
Modified:
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.cpp
===================================================================
---
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.cpp
2010-04-18 17:06:02 UTC (rev 36340)
+++
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/ICULocaleBackend.cpp
2010-04-18 20:18:40 UTC (rev 36341)
@@ -12,7 +12,11 @@
#include <locale.h>
#include <string.h>
+#include <timelocal.h>
+
#include <unicode/decimfmt.h>
+#include <unicode/dtfmtsym.h>
+#include <unicode/smpdtfmt.h>
namespace BPrivate {
@@ -23,17 +27,17 @@
* buffer, which will be initialized to match the "C"/"POSIX" locale, but it
* will be changed according to any locale requested via SetLocale()
*/
-static const uint16 skLCBufSize = 10;
-static char sDecimalPoint[skLCBufSize] = ".";
-static char sThousandsSep[skLCBufSize] = "";
-static char sGrouping[skLCBufSize] = "";
-static char sIntCurrSymbol[skLCBufSize] = "";
-static char sCurrencySymbol[skLCBufSize] = "";
-static char sMonDecimalPoint[skLCBufSize] = "";
-static char sMonThousandsSep[skLCBufSize] = "";
-static char sMonGrouping[skLCBufSize] = "";
-static char sPositiveSign[skLCBufSize] = "";
-static char sNegativeSign[skLCBufSize] = "";
+static const uint16 kLCBufSize = 10;
+static char sDecimalPoint[kLCBufSize] = ".";
+static char sThousandsSep[kLCBufSize] = "";
+static char sGrouping[kLCBufSize] = "";
+static char sIntCurrSymbol[kLCBufSize] = "";
+static char sCurrencySymbol[kLCBufSize] = "";
+static char sMonDecimalPoint[kLCBufSize] = "";
+static char sMonThousandsSep[kLCBufSize] = "";
+static char sMonGrouping[kLCBufSize] = "";
+static char sPositiveSign[kLCBufSize] = "";
+static char sNegativeSign[kLCBufSize] = "";
static struct lconv sLocaleConv = {
sDecimalPoint,
sThousandsSep,
@@ -62,6 +66,69 @@
};
+/*
+ * the values below initialize the struct to let each member point to a static
+ * buffer, which will be initialized to match the "C"/"POSIX" locale, but it
+ * will be changed according to any locale requested via SetLocale()
+ */
+static char sMon[12][24] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+static char sMonth[12][64] = {
+ "January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"
+};
+static char sWday[7][24] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+};
+static char sWeekday[7][64] = {
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
"Saturday"
+};
+static char sTimeFmt[24] = "%H:%M:%S";
+static char sDateFmt[24] = "%m/%d/%y";
+static char sDateTimeFmt[32] = "%a %b %e %H:%M:%S %Y";
+static char sAM[24] = "AM";
+static char sPM[24] = "PM";
+static char sDateTimeZoneFmt[32] = "%a %b %e %H:%M:%S %Z %Y";
+static char sAltMonth[12][64] = {
+ "January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"
+};
+static char sMdOrder[4] = "md";
+static char sAmPmFmt[32] = "%I:%M:%S %p";
+static const struct lc_time_t sLCTimeInfo = {
+ {
+ sMon[0], sMon[1], sMon[2], sMon[3], sMon[4], sMon[5],
+ sMon[6], sMon[7], sMon[8], sMon[9], sMon[10], sMon[11]
+ },
+ {
+ sMonth[0], sMonth[1], sMonth[2], sMonth[3], sMonth[4],
sMonth[5],
+ sMonth[6], sMonth[7], sMonth[8], sMonth[9], sMonth[10],
sMonth[11]
+ },
+ {
+ sWday[0], sWday[1], sWday[2], sWday[3], sWday[4], sWday[5],
sWday[6]
+ },
+ {
+ sWeekday[0], sWeekday[1], sWeekday[2], sWeekday[3],
+ sWeekday[4], sWeekday[5], sWeekday[6]
+ },
+ sTimeFmt,
+ sDateFmt,
+ sDateTimeFmt,
+ sAM,
+ sPM,
+ sDateTimeZoneFmt,
+ {
+ sAltMonth[0], sAltMonth[1], sAltMonth[2], sAltMonth[3],
+ sAltMonth[4], sAltMonth[5], sAltMonth[6], sAltMonth[7],
+ sAltMonth[8], sAltMonth[9], sAltMonth[10], sAltMonth[11]
+ },
+ sMdOrder,
+ sAmPmFmt
+};
+
+
CategoryData::CategoryData()
:
fConverter(NULL)
@@ -121,14 +188,15 @@
status_t
-CategoryData::_ConvertUnicodeStringToLocaleconvEntry(UnicodeString& string,
- char* destination, char* defaultValue)
+CategoryData::_ConvertUnicodeStringToLocaleconvEntry(
+ const UnicodeString& string, char* destination, int destinationSize,
+ char* defaultValue)
{
status_t result = B_OK;
UErrorCode icuStatus = U_ZERO_ERROR;
- ucnv_fromUChars(fConverter, destination, skLCBufSize,
string.getBuffer(),
- string.length(), &icuStatus);
+ ucnv_fromUChars(fConverter, destination, destinationSize,
+ string.getBuffer(), string.length(), &icuStatus);
if (!U_SUCCESS(icuStatus)) {
switch (icuStatus) {
case U_BUFFER_OVERFLOW_ERROR:
@@ -196,7 +264,7 @@
UnicodeString symbolString = formatSymbols->getSymbol(symbol);
if (!symbolString.isEmpty()) {
result = _ConvertUnicodeStringToLocaleconvEntry(symbolString,
- destination, defaultValue);
+ destination, kLCBufSize, defaultValue);
} else
destination[0] = '\0';
@@ -317,7 +385,7 @@
if (intlCurrencySeparatorChar != CHAR_MAX)
intlCurrencySymbol += intlCurrencySeparatorChar;
result =
_ConvertUnicodeStringToLocaleconvEntry(intlCurrencySymbol,
- sIntCurrSymbol);
+ sIntCurrSymbol, kLCBufSize);
}
if (result == B_OK) {
result = _SetLocaleconvEntry(formatSymbols,
sCurrencySymbol,
@@ -382,7 +450,7 @@
/*
* This method determines the <>_sign_posn value according to the following
* map (where '$' indicated the currency symbol, '#' the number value, and
- * '-' the sign symbol [or alternatively the paranthesis]):
+ * '-' or parantheses the sign symbol):
* ($#) -> 0
* (#$) -> 0
* -$# -> 1
@@ -399,7 +467,7 @@
{
if (prefix.indexOf(UnicodeString("(", "")) >= 0
&& suffix.indexOf(UnicodeString(")", "")) >= 0)
- return 0; // parentheses around currency and value
+ return kParenthesesAroundCurrencyAndValue;
UnicodeString value("#", "");
UnicodeString prefixNumberSuffixString = prefix + value + suffix;
@@ -410,13 +478,13 @@
= prefixNumberSuffixString.indexOf(currencySymbol);
if (signSymbolPos < valuePos && signSymbolPos <
currencySymbolPos)
- return 1; // sign precedes currency and value
+ return kSignPrecedesCurrencyAndValue;
if (signSymbolPos > valuePos && signSymbolPos >
currencySymbolPos)
- return 2; // sign succeeds currency and value
+ return kSignSucceedsCurrencyAndValue;
if (signSymbolPos == currencySymbolPos - 1)
- return 3; // sign immediately precedes currency
+ return kSignImmediatelyPrecedesCurrency;
if (signSymbolPos == currencySymbolPos +
currencySymbol.length())
- return 4; // sign immediately succeeds currency
+ return kSignImmediatelySucceedsCurrency;
}
return CHAR_MAX;
@@ -478,11 +546,250 @@
TimeData::SetTo(const Locale& locale, const char* posixLocaleName)
{
status_t result = CategoryData::SetTo(locale, posixLocaleName);
+ if (result != B_OK)
+ return result;
+ UErrorCode icuStatus = U_ZERO_ERROR;
+ DateFormatSymbols formatSymbols(fLocale, icuStatus);
+ if (!U_SUCCESS(icuStatus))
+ return B_UNSUPPORTED;
+
+ int count = 0;
+ const UnicodeString* strings = formatSymbols.getShortMonths(count);
+ result = _SetLCTimeEntries(strings, sMon[0], sizeof(sMon[0]), count,
12);
+
+ if (result == B_OK) {
+ strings = formatSymbols.getMonths(count);
+ result = _SetLCTimeEntries(strings, sMonth[0],
sizeof(sMonth[0]), count,
+ 12);
+ }
+
+ if (result == B_OK) {
+ strings = formatSymbols.getShortWeekdays(count);
+ if (count == 8 && strings[0].length() == 0) {
+ // ICUs weekday arrays are 1-based
+ strings++;
+ count = 7;
+ }
+ result = _SetLCTimeEntries(strings, sWday[0], sizeof(sWday[0]),
count,
+ 7);
+ }
+
+ if (result == B_OK) {
+ strings = formatSymbols.getWeekdays(count);
+ if (count == 8 && strings[0].length() == 0) {
+ // ICUs weekday arrays are 1-based
+ strings++;
+ count = 7;
+ }
+ result = _SetLCTimeEntries(strings, sWeekday[0],
sizeof(sWeekday[0]),
+ count, 7);
+ }
+
+ if (result == B_OK) {
+ try {
+ DateFormat* format = DateFormat::createTimeInstance(
+ DateFormat::kDefault, fLocale);
+ result = _SetLCTimePattern(format, sTimeFmt,
sizeof(sTimeFmt));
+ delete format;
+ } catch(...) {
+ result = B_NO_MEMORY;
+ }
+ }
+
+ if (result == B_OK) {
+ try {
+ DateFormat* format = DateFormat::createDateInstance(
+ DateFormat::kDefault, fLocale);
+ result = _SetLCTimePattern(format, sDateFmt,
sizeof(sDateFmt));
+ delete format;
+ } catch(...) {
+ result = B_NO_MEMORY;
+ }
+ }
+
+ if (result == B_OK) {
+ try {
+ DateFormat* format = DateFormat::createDateTimeInstance(
+ DateFormat::kFull, DateFormat::kFull, fLocale);
+ result = _SetLCTimePattern(format, sDateTimeFmt,
+ sizeof(sDateTimeFmt));
+ delete format;
+ } catch(...) {
+ result = B_NO_MEMORY;
+ }
+ }
+
+ if (result == B_OK) {
+ strings = formatSymbols.getAmPmStrings(count);
+ result = _SetLCTimeEntries(strings, sAM, sizeof(sAM), 1, 1);
+ if (result == B_OK)
+ result = _SetLCTimeEntries(&strings[1], sPM,
sizeof(sPM), 1, 1);
+ }
+
+ if (result == B_OK) {
+ strings = formatSymbols.getMonths(count,
DateFormatSymbols::STANDALONE,
+ DateFormatSymbols::WIDE);
+ result = _SetLCTimeEntries(strings, sAltMonth[0],
sizeof(sAltMonth[0]),
+ count, 12);
+ }
+
return result;
}
+status_t
+TimeData::_SetLCTimeEntries(const UnicodeString* strings, char* destination,
+ int entrySize, int count, int maxCount)
+{
+ if (strings == NULL)
+ return B_ERROR;
+
+ status_t result = B_OK;
+ if (count > maxCount)
+ count = maxCount;
+ for (int32 i = 0; result == B_OK && i < count; ++i) {
+ result = _ConvertUnicodeStringToLocaleconvEntry(strings[i],
destination,
+ entrySize);
+ destination += entrySize;
+ }
+
+ return result;
+}
+
+
+status_t
+TimeData::_SetLCTimePattern(DateFormat* format, char* destination,
+ int destinationSize)
+{
+ SimpleDateFormat* simpleFormat =
dynamic_cast<SimpleDateFormat*>(format);
+ if (!simpleFormat)
+ return B_BAD_TYPE;
+
+ // convert ICU-type pattern to posix (i.e. strftime()) format string
+ UnicodeString icuPattern;
+ simpleFormat->toPattern(icuPattern);
+ UnicodeString posixPattern;
+ if (icuPattern.length() > 0) {
+ UChar lastCharSeen = 0;
+ int lastCharCount = 1;
+ bool inSingleQuotes = false;
+ bool inDoubleQuotes = false;
+ // we loop one character past the end on purpose, which will
result in a
+ // final -1 char to be processed, which in turn will let us
handle the
+ // last character (via lastCharSeen)
+ for (int i = 0; i <= icuPattern.length(); ++i) {
+ UChar currChar = icuPattern.charAt(i);
+ if (lastCharSeen != 0 && currChar == lastCharSeen) {
+ lastCharCount++;
+ continue;
+ }
+
+ if (!inSingleQuotes && !inDoubleQuotes) {
+ switch (lastCharSeen) {
+ case L'a':
+
posixPattern.append(UnicodeString("%p", ""));
+ break;
+ case L'd':
+ if (lastCharCount == 2)
+
posixPattern.append(UnicodeString("%d", ""));
+ else
+
posixPattern.append(UnicodeString("%e", ""));
+ break;
+ case L'D':
+
posixPattern.append(UnicodeString("%j", ""));
+ break;
+ case L'c':
+ // fall through, to handle 'c'
the same as 'e'
+ case L'e':
+ if (lastCharCount == 4)
+
posixPattern.append(UnicodeString("%A", ""));
+ else if (lastCharCount <= 2)
+
posixPattern.append(UnicodeString("%u", ""));
+ else
+
posixPattern.append(UnicodeString("%a", ""));
+ break;
+ case L'E':
+ if (lastCharCount == 4)
+
posixPattern.append(UnicodeString("%A", ""));
+ else
+
posixPattern.append(UnicodeString("%a", ""));
+ break;
+ case L'k':
+ // fall through, to handle 'k'
the same as 'h'
+ case L'h':
+ if (lastCharCount == 2)
+
posixPattern.append(UnicodeString("%I", ""));
+ else
+
posixPattern.append(UnicodeString("%l", ""));
+ break;
+ case L'H':
+ if (lastCharCount == 2)
+
posixPattern.append(UnicodeString("%H", ""));
+ else
+
posixPattern.append(UnicodeString("%k", ""));
+ break;
+ case L'm':
+
posixPattern.append(UnicodeString("%M", ""));
+ break;
+ case L'L':
+ // fall through, to handle 'L'
the same as 'M'
+ case L'M':
+ if (lastCharCount == 4)
+
posixPattern.append(UnicodeString("%B", ""));
+ else if (lastCharCount == 3)
+
posixPattern.append(UnicodeString("%b", ""));
+ else
+
posixPattern.append(UnicodeString("%m", ""));
+ break;
+ case L's':
+
posixPattern.append(UnicodeString("%S", ""));
+ break;
+ case L'w':
+
posixPattern.append(UnicodeString("%V", ""));
+ break;
+ case L'y':
+ if (lastCharCount == 2)
+
posixPattern.append(UnicodeString("%y", ""));
+ else
+
posixPattern.append(UnicodeString("%Y", ""));
+ break;
+ case L'Y':
+
posixPattern.append(UnicodeString("%G", ""));
+ break;
+ case L'z':
+
posixPattern.append(UnicodeString("%Z", ""));
+ break;
+ case L'Z':
+
posixPattern.append(UnicodeString("%z", ""));
+ break;
+ default:
+ if (lastCharSeen != 0)
+
posixPattern.append(lastCharSeen);
+ }
+ } else {
+ if (lastCharSeen != 0)
+ posixPattern.append(lastCharSeen);
+ }
+
+ if (currChar == L'"') {
+ inDoubleQuotes = !inDoubleQuotes;
+ lastCharSeen = 0;
+ } else if (currChar == L'\'') {
+ inSingleQuotes = !inSingleQuotes;
+ lastCharSeen = 0;
+ } else
+ lastCharSeen = currChar;
+
+ lastCharCount = 1;
+ }
+ }
+
+ return _ConvertUnicodeStringToLocaleconvEntry(posixPattern, destination,
+ destinationSize);
+}
+
+
extern "C" LocaleBackend*
CreateInstance()
{
@@ -550,13 +857,20 @@
}
-struct lconv*
+const struct lconv*
ICULocaleBackend::LocaleConv()
{
return &sLocaleConv;
}
+const struct lc_time_t*
+ICULocaleBackend::LCTimeInfo()
+{
+ return &sLCTimeInfo;
+}
+
+
const char*
ICULocaleBackend::_QueryLocale(int category)
{
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-04-18 17:06:02 UTC (rev 36340)
+++
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/locale/Jamfile
2010-04-18 20:18:40 UTC (rev 36341)
@@ -13,6 +13,8 @@
;
UseLibraryHeaders icu ;
+UsePrivateHeaders [ FDirName libroot locale ] ;
+UsePrivateHeaders [ FDirName libroot time ] ;
SharedLibrary libroot-addon-locale.so
:
Modified:
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/time/Jamfile
===================================================================
---
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/time/Jamfile
2010-04-18 17:06:02 UTC (rev 36340)
+++
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/time/Jamfile
2010-04-18 20:18:40 UTC (rev 36341)
@@ -4,6 +4,7 @@
SubDirCcFlags -DNOID -DTZDIR='get_timezones_directory()' -DUSG_COMPAT
-DTM_GMTOFF=tm_gmtoff -DTM_ZONE=tm_zone -DPCTS=1 -DSTD_INSPIRED ;
+UsePrivateHeaders [ FDirName libroot locale ] ;
UsePrivateHeaders [ FDirName libroot time ] ;
UsePrivateSystemHeaders ;
@@ -17,7 +18,7 @@
stime.c
strftime.c
strptime.c
- timelocal.c
+ timelocal.cpp
time.c
;
Modified:
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/time/strftime.c
===================================================================
---
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/time/strftime.c
2010-04-18 17:06:02 UTC (rev 36340)
+++
haiku/branches/developer/zooey/posix-locale/src/system/libroot/posix/time/strftime.c
2010-04-18 20:18:40 UTC (rev 36341)
@@ -36,76 +36,10 @@
#include "tzfile.h"
#include "fcntl.h"
#include "locale.h"
+#include "timelocal.h"
-struct lc_time_T {
- const char * mon[MONSPERYEAR];
- const char * month[MONSPERYEAR];
- const char * wday[DAYSPERWEEK];
- const char * weekday[DAYSPERWEEK];
- const char * X_fmt;
- const char * x_fmt;
- const char * c_fmt;
- const char * am;
- const char * pm;
- const char * date_fmt;
-};
+#define Locale __get_current_time_locale()
-#ifdef LOCALE_HOME
-#include "sys/stat.h"
-static struct lc_time_T localebuf;
-static struct lc_time_T * _loc P((void));
-#define Locale _loc()
-#endif /* defined LOCALE_HOME */
-#ifndef LOCALE_HOME
-#define Locale (&C_time_locale)
-#endif /* !defined LOCALE_HOME */
-
-static const struct lc_time_T C_time_locale = {
- {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
- }, {
- "January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December"
- }, {
- "Sun", "Mon", "Tue", "Wed",
- "Thu", "Fri", "Sat"
- }, {
- "Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday"
- },
-
- /* X_fmt */
- "%H:%M:%S",
-
- /*
- ** x_fmt
- ** C99 requires this format.
- ** Using just numbers (as here) makes Quakers happier;
- ** it's also compatible with SVR4.
- */
- "%m/%d/%y",
-
- /*
- ** c_fmt
- ** C99 requires this format.
- ** Previously this code used "%D %X", but we now conform to C99.
- ** Note that
- ** "%a %b %d %H:%M:%S %Y"
- ** is used by Solaris 2.3.
- */
- "%a %b %e %T %Y",
-
- /* am */
- "AM",
-
- /* pm */
- "PM",
-
- /* date_fmt */
- "%a %b %e %H:%M:%S %Z %Y"
-};
-
static char * _add P((const char *, char *, const char *));
static char * _conv P((int, const char *, char *, const char *));
static char * _fmt P((const char *, const struct tm *, char *, const char *,
@@ -123,6 +57,8 @@
#define IN_THIS 2
#define IN_ALL 3
+#define NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
+
size_t
strftime(s, maxsize, format, t)
char * const s;
@@ -134,9 +70,6 @@
int warn;
tzset();
-#ifdef LOCALE_HOME
- localebuf.mon[0] = 0;
-#endif /* defined LOCALE_HOME */
warn = IN_NONE;
p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn);
#ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
@@ -641,124 +574,3 @@
pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim);
return pt;
}
-
-#ifdef LOCALE_HOME
-static struct lc_time_T *
-_loc P((void))
-{
- static const char locale_home[] = LOCALE_HOME;
- static const char lc_time[] = "LC_TIME";
- static char * locale_buf;
-
- int fd;
- int oldsun; /* "...ain't got nothin' to do..." */
- char * lbuf;
- char * name;
- char * p;
- const char ** ap;
- const char * plim;
- char filename[FILENAME_MAX];
- struct stat st;
- size_t namesize;
- size_t bufsize;
-
- /*
- ** Use localebuf.mon[0] to signal whether locale is already set up.
- */
- if (localebuf.mon[0])
- return &localebuf;
- name = setlocale(LC_TIME, (char *) NULL);
- if (name == NULL || *name == '\0')
- goto no_locale;
- /*
- ** If the locale name is the same as our cache, use the cache.
- */
- lbuf = locale_buf;
- if (lbuf != NULL && strcmp(name, lbuf) == 0) {
- p = lbuf;
- for (ap = (const char **) &localebuf;
- ap < (const char **) (&localebuf + 1);
- ++ap)
- *ap = p += strlen(p) + 1;
- return &localebuf;
- }
- /*
- ** Slurp the locale file into the cache.
- */
- namesize = strlen(name) + 1;
- if (sizeof filename <
- ((sizeof locale_home) + namesize + (sizeof lc_time)))
- goto no_locale;
- oldsun = 0;
- (void) sprintf(filename, "%s/%s/%s", locale_home, name, lc_time);
- fd = open(filename, O_RDONLY);
- if (fd < 0) {
- /*
- ** Old Sun systems have a different naming and data convention.
- */
- oldsun = 1;
- (void) sprintf(filename, "%s/%s/%s", locale_home,
- lc_time, name);
- fd = open(filename, O_RDONLY);
- if (fd < 0)
- goto no_locale;
- }
- if (fstat(fd, &st) != 0)
- goto bad_locale;
- if (st.st_size <= 0)
- goto bad_locale;
- bufsize = namesize + st.st_size;
- locale_buf = NULL;
- lbuf = (lbuf == NULL) ? malloc(bufsize) : realloc(lbuf, bufsize);
- if (lbuf == NULL)
- goto bad_locale;
- (void) strcpy(lbuf, name);
- p = lbuf + namesize;
- plim = p + st.st_size;
- if (read(fd, p, (size_t) st.st_size) != st.st_size)
- goto bad_lbuf;
- if (close(fd) != 0)
- goto bad_lbuf;
- /*
- ** Parse the locale file into localebuf.
- */
- if (plim[-1] != '\n')
- goto bad_lbuf;
- for (ap = (const char **) &localebuf;
- ap < (const char **) (&localebuf + 1);
- ++ap) {
- if (p == plim)
- goto bad_lbuf;
- *ap = p;
- while (*p != '\n')
- ++p;
- *p++ = '\0';
- }
- if (oldsun) {
- /*
- ** SunOS 4 used an obsolescent format; see localdtconv(3).
- ** c_fmt had the ``short format for dates and times together''
- ** (SunOS 4 date, "%a %b %e %T %Z %Y" in the C locale);
- ** date_fmt had the ``long format for dates''
- ** (SunOS 4 strftime %C, "%A, %B %e, %Y" in the C locale).
- ** Discard the latter in favor of the former.
- */
- localebuf.date_fmt = localebuf.c_fmt;
- }
- /*
- ** Record the successful parse in the cache.
- */
- locale_buf = lbuf;
-
- return &localebuf;
-
-bad_lbuf:
- free(lbuf);
-bad_locale:
- (void) close(fd);
-no_locale:
- localebuf = C_time_locale;
- locale_buf = NULL;
- return &localebuf;
-}
-#endif /* defined LOCALE_HOME */
[... truncated: 194 lines follow ...]
Other related posts:
- » [haiku-commits] r36341 - in haiku/branches/developer/zooey/posix-locale: headers/private/libroot headers/private/libroot/locale headers/private/libroot/time src/system/libroot/posix/locale src/system/libroot/posix/time ... - zooey