#! /bin/sh
-# From configure.in Id: configure.in 59561 2009-03-15 16:07:56Z KO .
+# From configure.in Id: configure.in 59905 2009-03-28 19:10:05Z VZ .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.61 for wxWidgets 2.9.0.
#
fi
if test "$wxUSE_DATETIME" = "yes"; then
- { echo "$as_me:$LINENO: checking for strptime" >&5
-echo $ECHO_N "checking for strptime... $ECHO_C" >&6; }
-if test "${ac_cv_func_strptime+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define strptime to an innocuous variant, in case <limits.h> declares strptime.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define strptime innocuous_strptime
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char strptime (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef strptime
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char strptime ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined __stub_strptime || defined __stub___strptime
-choke me
-#endif
-
-int
-main ()
-{
-return strptime ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_c_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- ac_cv_func_strptime=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_cv_func_strptime=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_strptime" >&5
-echo "${ECHO_T}$ac_cv_func_strptime" >&6; }
-
- if test "$ac_cv_func_strptime" = "yes"; then
- { echo "$as_me:$LINENO: checking for strptime declaration" >&5
-echo $ECHO_N "checking for strptime declaration... $ECHO_C" >&6; }
-if test "${wx_cv_func_strptime_decl+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
- #include <time.h>
-
-int
-main ()
-{
-
- struct tm t;
- strptime("foo", "bar", &t);
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_compile") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest.$ac_objext; then
- wx_cv_func_strptime_decl=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- wx_cv_func_strptime_decl=no
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-fi
-{ echo "$as_me:$LINENO: result: $wx_cv_func_strptime_decl" >&5
-echo "${ECHO_T}$wx_cv_func_strptime_decl" >&6; }
- fi
- if test "$wx_cv_func_strptime_decl" = "yes"; then
- cat >>confdefs.h <<\_ACEOF
-#define HAVE_STRPTIME_DECL 1
-_ACEOF
-
- else
- wx_strptime_decl="extern char *strptime(const char *, const char *, struct tm *);"
- fi
- if test "$ac_cv_func_strptime" = "yes"; then
- { echo "$as_me:$LINENO: checking whether strptime() fails on invalid strings" >&5
-echo $ECHO_N "checking whether strptime() fails on invalid strings... $ECHO_C" >&6; }
-if test "${wx_cv_func_strptime_ok+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test "$cross_compiling" = yes; then
- wx_cv_func_strptime_ok=no
-
-else
- cat >conftest.$ac_ext <<_ACEOF
-
- #include <stdlib.h>
- #include <time.h>
- #include "confdefs.h"
-
- $wx_strptime_decl
-
- int main()
- {
- struct tm t;
- return !!strptime("", "%x", &t);
- }
-
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- wx_cv_func_strptime_ok=yes
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-wx_cv_func_strptime_ok=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-
-fi
-{ echo "$as_me:$LINENO: result: $wx_cv_func_strptime_ok" >&5
-echo "${ECHO_T}$wx_cv_func_strptime_ok" >&6; }
-
- if test "$wx_cv_func_strptime_ok" = "yes"; then
- cat >>confdefs.h <<\_ACEOF
-#define HAVE_STRPTIME 1
-_ACEOF
-
- fi
- fi
-
{ echo "$as_me:$LINENO: checking for timezone variable in <time.h>" >&5
echo $ECHO_N "checking for timezone variable in <time.h>... $ECHO_C" >&6; }
if test "${wx_cv_var_timezone+set}" = set; then
fi
if test "$wxUSE_DATETIME" = "yes"; then
- dnl check for strptime and for its declaration as some systems lack it
- AC_CHECK_FUNC(strptime)
- if test "$ac_cv_func_strptime" = "yes"; then
- AC_CACHE_CHECK([for strptime declaration], wx_cv_func_strptime_decl,
- [
- AC_LANG_PUSH(C++)
- AC_TRY_COMPILE(
- [
- #include <time.h>
- ],
- [
- struct tm t;
- strptime("foo", "bar", &t);
- ],
- wx_cv_func_strptime_decl=yes,
- wx_cv_func_strptime_decl=no
- )
- AC_LANG_POP()
- ]
- )
- fi
- if test "$wx_cv_func_strptime_decl" = "yes"; then
- AC_DEFINE(HAVE_STRPTIME_DECL)
- else
- wx_strptime_decl="extern char *strptime(const char *, const char *, struct tm *);"
- fi
- if test "$ac_cv_func_strptime" = "yes"; then
- dnl strptime() behaviour doesn't conform to POSIX under Mac OS X <
- dnl 10.5 and possibly other BSD variants, check that strptime() we
- dnl have fails to parse format when the string doesn't match it instea
- dnl of just stopping immediately and returning non-NULL
- AC_CACHE_CHECK([whether strptime() fails on invalid strings],
- wx_cv_func_strptime_ok,
- [AC_RUN_IFELSE(
- [
- #include <stdlib.h>
- #include <time.h>
- #include "confdefs.h"
-
- $wx_strptime_decl
-
- int main()
- {
- struct tm t;
- return !!strptime("", "%x", &t);
- }
- ],
- wx_cv_func_strptime_ok=yes,
- wx_cv_func_strptime_ok=no,
- dnl be pessimistic when cross-compiling
- wx_cv_func_strptime_ok=no
- )]
- )
-
- if test "$wx_cv_func_strptime_ok" = "yes"; then
- AC_DEFINE(HAVE_STRPTIME)
- fi
- fi
-
dnl check for timezone variable
dnl doesn't exist under Darwin / Mac OS X which uses tm_gmtoff instead
AC_CACHE_CHECK(for timezone variable in <time.h>,
- Added support of %l format specifier to wxDateTime::ParseFormat().
- wxImage handlers can now support multiple extensions (Ivan Krestinin).
- Added wxFileName::StripExtension() (troelsk).
+- Added wxLOCALE_DATE/TIME_FMT support to wxLocale::GetInfo().
All (Unix):
// conditional compilation
// ----------------------------------------------------------------------------
-#if defined(HAVE_STRPTIME) && defined(__GLIBC__) && \
- ((__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0))
- // glibc 2.0.7 strptime() is broken - the following snippet causes it to
- // crash (instead of just failing):
- //
- // strncpy(buf, "Tue Dec 21 20:25:40 1999", 128);
- // strptime(buf, "%x", &tm);
- //
- // so don't use it
- #undef HAVE_STRPTIME
-#endif // broken strptime()
-
-#if defined(HAVE_STRPTIME) && defined(__DARWIN__) && defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS
- // configure detects strptime as linkable because it's in the OS X
- // System library but MSL headers don't declare it.
-
-// char *strptime(const char *, const char *, struct tm *);
- // However, we DON'T want to just provide it here because we would
- // crash and/or overwrite data when strptime from OS X tries
- // to fill in MW's struct tm which is two fields shorter (no TZ stuff)
- // So for now let's just say we don't have strptime
- #undef HAVE_STRPTIME
-#endif
-
// everyone has strftime except Win CE unless VC8 is used
#if !defined(__WXWINCE__) || defined(__VISUALC8__)
#define HAVE_STRFTIME
// monetary value
wxLOCALE_CAT_MONEY,
+ // default category for wxLocaleInfo values which only apply to a single
+ // category (e.g. wxLOCALE_SHORT_DATE_FMT)
+ wxLOCALE_CAT_DEFAULT,
+
wxLOCALE_CAT_MAX
};
enum wxLocaleInfo
{
- // the thounsands separator
+ // the thousands separator (for wxLOCALE_CAT_NUMBER or MONEY)
wxLOCALE_THOUSANDS_SEP,
- // the character used as decimal point
- wxLOCALE_DECIMAL_POINT
+ // the character used as decimal point (for wxLOCALE_CAT_NUMBER or MONEY)
+ wxLOCALE_DECIMAL_POINT,
+
+ // the stftime()-formats used for short/long date and time representations
+ // (under some platforms short and long date formats are the same)
+ //
+ // NB: these elements should appear in this order, code in GetInfo() relies
+ // on it
+ wxLOCALE_SHORT_DATE_FMT,
+ wxLOCALE_LONG_DATE_FMT,
+ wxLOCALE_DATE_TIME_FMT,
+ wxLOCALE_TIME_FMT
};
// get the values of the given locale-dependent datum: the current locale
// is used, the US default value is returned if everything else fails
- static wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat);
+ static wxString GetInfo(wxLocaleInfo index,
+ wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT);
// return true if the locale was set successfully
bool IsOk() const { return m_pszOldLocale != NULL; }
*/
struct WXDLLIMPEXP_BASE wxLanguageInfo
{
- /// ::wxLanguage id.
+ /// ::wxLanguage id.
/// It should be greater than @c wxLANGUAGE_USER_DEFINED when defining your own
/// language info structure.
int Language;
/**
- The category of locale settings. See wxLocale::GetInfo().
+ The category of locale settings.
+
+ @see wxLocale::GetInfo()
*/
enum wxLocaleCategory
{
- /// (any) numbers
+ /// Number formatting.
wxLOCALE_CAT_NUMBER,
- /// date/time
+ /// Date/time formatting.
wxLOCALE_CAT_DATE,
- /// monetary value
+ /// Monetary values formatting.
wxLOCALE_CAT_MONEY,
- wxLOCALE_CAT_MAX
+ /**
+ Default category for the wxLocaleInfo value.
+
+ This category can be used for values which only make sense for a single
+ category, e.g. wxLOCALE_SHORT_DATE_FMT which can only be used with
+ wxLOCALE_CAT_DATE. As this is the default value of the second parameter
+ of wxLocale::GetInfo(), wxLOCALE_CAT_DATE can be omitted when asking
+ for wxLOCALE_SHORT_DATE_FMT value.
+
+ @since 2.9.0
+ */
+ wxLOCALE_CAT_DEFAULT
};
/**
*/
enum wxLocaleInfo
{
- /// The thounsands separator
+ /**
+ The thousands separator.
+
+ This value can be used with either wxLOCALE_CAT_NUMBER or
+ wxLOCALE_CAT_MONEY categories.
+ */
wxLOCALE_THOUSANDS_SEP,
- /// The character used as decimal point
- wxLOCALE_DECIMAL_POINT
+ /**
+ The character used as decimal point.
+
+ This value can be used with either wxLOCALE_CAT_NUMBER or
+ wxLOCALE_CAT_MONEY categories.
+ */
+ wxLOCALE_DECIMAL_POINT,
+
+ /**
+ The date and time formats.
+
+ The strings returned by wxLocale::GetInfo() use strftime() or,
+ equivalently, wxDateTime::Format() format. If the relevant format
+ couldn't be determined, an empty string is returned -- there is no
+ fallback value so that the application could determine the best course
+ of actions itself in such case.
+
+ All of these values are used with wxLOCALE_CAT_DATE in
+ wxLocale::GetInfo() or, more typically, with wxLOCALE_CAT_DEFAULT as
+ they only apply to a single category.
+ */
+ //@{
+
+ /**
+ Short date format.
+
+ Notice that short and long date formats may be the same under POSIX
+ systems currently but may, and typically are, different under MSW or OS
+ X.
+
+ @since 2.9.0
+ */
+ wxLOCALE_SHORT_DATE_FMT,
+
+ /**
+ Long date format.
+
+ @since 2.9.0
+ */
+ wxLOCALE_LONG_DATE_FMT,
+
+ /**
+ Date and time format.
+
+ @since 2.9.0
+ */
+ wxLOCALE_DATE_TIME_FMT,
+
+ /**
+ Time format.
+
+ @since 2.9.0
+ */
+ wxLOCALE_TIME_FMT
+
+ //@}
};
/**
Tries to detect the user's default language setting.
-
+
Returns the ::wxLanguage value or @c wxLANGUAGE_UNKNOWN if the language-guessing
algorithm failed.
*/
/**
Get the values of the given locale-dependent datum.
- The current locale is used, the US default value is returned if everything
- else fails.
+ This function returns the value of the locale-specific option specified
+ by the given @a index.
+
+ @param index
+ One of the elements of wxLocaleInfo enum.
+ @param cat
+ The category to use with the given index or wxLOCALE_CAT_DEFAULT if
+ the index can only apply to a single category.
+ @return
+ The option value or empty string if the function failed.
*/
- static wxString GetInfo(wxLocaleInfo index, wxLocaleCategory cat);
+ static wxString GetInfo(wxLocaleInfo index,
+ wxLocaleCategory cat = wxLOCALE_CAT_DEFAULT);
/**
Initializes the wxLocale instance.
/* define if you have statvfs function */
#undef HAVE_STATVFS
-/* Define if you have strptime() */
-#undef HAVE_STRPTIME
-
-/* Define if strptime() is declared in headers */
-#undef HAVE_STRPTIME_DECL
-
/* Define if you have strtoull() and strtoll() */
#undef HAVE_STRTOULL
/* define if you have statvfs function */
#undef HAVE_STATVFS
-/* Define if you have strptime() */
-#define HAVE_STRPTIME 1
-
-/* Define if you have strptime() declaration */
-#define HAVE_STRPTIME_DECL 1
-
/* Define if you have strtoull() and strtoll() */
#define HAVE_STRTOULL 1
namespace
{
-#ifdef HAVE_STRPTIME
-
-#if wxUSE_UNIX && !defined(HAVE_STRPTIME_DECL)
- // configure detected that we had strptime() but not its declaration,
- // provide it ourselves
- extern "C" char *strptime(const char *, const char *, struct tm *);
-#endif
-
-// strptime() wrapper: call strptime() for the string starting at the given
-// iterator and fill output tm struct with the results and modify input to
-// point to the end of the string consumed by strptime() if successful,
-// otherwise return false and don't modify anything
-bool
-CallStrptime(const wxString& str,
- wxString::const_iterator& p,
- const char *fmt,
- tm *tm)
-{
- // convert from iterator to char pointer: this is simple as wxCStrData
- // already supports this
- const char * const start = str.c_str() + (p - str.begin());
-
- const char * const end = strptime(start, fmt, tm);
- if ( !end )
- return false;
-
- // convert back from char pointer to iterator: unfortunately we have no way
- // to do it efficiently currently so create a temporary string just to
- // compute the number of characters between start and end
- p += wxString(start, end - start).length();
-
- return true;
-}
-
-#endif // HAVE_STRPTIME
-
enum
{
DateLang_English = 1,
// FIXME-VC6: using wxString() instead of wxEmptyString in the
// line below results in error C2062: type 'class
// wxString (__cdecl *)(void)' unexpected
- const wxString& fmtAlt = wxEmptyString,
- const wxString& fmtAlt2 = wxString())
+ const wxString& fmtAlt = wxEmptyString)
{
const wxString str(p, end);
wxString::const_iterator endParse;
wxDateTime dt;
if ( dt.ParseFormat(str, fmt, &endParse) ||
- (!fmtAlt.empty() && dt.ParseFormat(str, fmtAlt, &endParse)) ||
- (!fmtAlt2.empty() && dt.ParseFormat(str, fmtAlt2, &endParse)) )
+ (!fmtAlt.empty() && dt.ParseFormat(str, fmtAlt, &endParse)) )
{
p += endParse - str.begin();
}
return true;
}
-#ifdef __WINDOWS__
-
-// returns the string containing strftime() format used for short dates in the
-// current locale or an empty string
-static wxString GetLocaleDateFormat()
-{
- wxString fmtWX;
-
- // there is no setlocale() under Windows CE, so just always query the
- // system there
-#ifndef __WXWINCE__
- if ( strcmp(setlocale(LC_ALL, NULL), "C") != 0 )
-#endif
- {
- // The locale was programatically set to non-C. We assume that this was
- // done using wxLocale, in which case thread's current locale is also
- // set to correct LCID value and we can use GetLocaleInfo to determine
- // the correct formatting string:
-#ifdef __WXWINCE__
- LCID lcid = LOCALE_USER_DEFAULT;
-#else
- LCID lcid = GetThreadLocale();
-#endif
- // according to MSDN 80 chars is max allowed for short date format
- wxChar fmt[81];
- if ( ::GetLocaleInfo(lcid, LOCALE_SSHORTDATE, fmt, WXSIZEOF(fmt)) )
- {
- wxChar chLast = _T('\0');
- size_t lastCount = 0;
- for ( const wxChar *p = fmt; /* NUL handled inside */; p++ )
- {
- if ( *p == chLast )
- {
- lastCount++;
- continue;
- }
-
- switch ( *p )
- {
- // these characters come in groups, start counting them
- case _T('d'):
- case _T('M'):
- case _T('y'):
- case _T('g'):
- chLast = *p;
- lastCount = 1;
- break;
-
- default:
- // first deal with any special characters we have had
- if ( lastCount )
- {
- switch ( chLast )
- {
- case _T('d'):
- switch ( lastCount )
- {
- case 1: // d
- case 2: // dd
- // these two are the same as we
- // don't distinguish between 1 and
- // 2 digits for days
- fmtWX += _T("%d");
- break;
-
- case 3: // ddd
- fmtWX += _T("%a");
- break;
-
- case 4: // dddd
- fmtWX += _T("%A");
- break;
-
- default:
- wxFAIL_MSG( _T("too many 'd's") );
- }
- break;
-
- case _T('M'):
- switch ( lastCount )
- {
- case 1: // M
- case 2: // MM
- // as for 'd' and 'dd' above
- fmtWX += _T("%m");
- break;
-
- case 3:
- fmtWX += _T("%b");
- break;
-
- case 4:
- fmtWX += _T("%B");
- break;
-
- default:
- wxFAIL_MSG( _T("too many 'M's") );
- }
- break;
-
- case _T('y'):
- switch ( lastCount )
- {
- case 1: // y
- case 2: // yy
- fmtWX += _T("%y");
- break;
-
- case 4: // yyyy
- fmtWX += _T("%Y");
- break;
-
- default:
- wxFAIL_MSG( _T("wrong number of 'y's") );
- }
- break;
-
- case _T('g'):
- // strftime() doesn't have era string,
- // ignore this format
- wxASSERT_MSG( lastCount <= 2,
- _T("too many 'g's") );
- break;
-
- default:
- wxFAIL_MSG( _T("unreachable") );
- }
-
- chLast = _T('\0');
- lastCount = 0;
- }
-
- // not a special character so must be just a separator,
- // treat as is
- if ( *p != _T('\0') )
- {
- if ( *p == _T('%') )
- {
- // this one needs to be escaped
- fmtWX += _T('%');
- }
-
- fmtWX += *p;
- }
- }
-
- if ( *p == _T('\0') )
- break;
- }
- }
- //else: GetLocaleInfo() failed, leave fmtDate value unchanged and
- // try our luck with the default formats
- }
- //else: default C locale, default formats should work
-
- return fmtWX;
-}
-
-#endif // __WINDOWS__
-
-#ifdef __WXOSX__
-
-#include "wx/osx/private.h"
-
-// under OSX locale formats are defined using
-// http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns
-//
-// so we need a translation function, bluntly copied from the windows
-// version above and enhanced with the additional elements needed
-
-static wxString TranslateFromUnicodeFormat(const wxString& fmt)
-{
- wxString fmtWX;
-
- wxChar chLast = _T('\0');
- size_t lastCount = 0;
- for ( wxString::const_iterator p = fmt.begin(); /* end handled inside */; ++p )
- {
- if ( p == fmt.end() || *p == chLast )
- {
- lastCount++;
- if ( p == fmt.end() )
- break;
-
- continue;
- }
-
- switch ( (*p).GetValue() )
- {
- // these characters come in groups, start counting them
- case _T('d'):
- case _T('M'):
- case _T('y'):
- case _T('g'):
- case _T('h'):
- case _T('H'):
- case _T('m'):
- case _T('s'):
- chLast = *p;
- lastCount = 1;
- break;
-
- default:
- // first deal with any special characters we have had
- if ( lastCount )
- {
- switch ( chLast )
- {
- case _T('d'):
- switch ( lastCount )
- {
- case 1: // d
- case 2: // dd
- // these two are the same as we
- // don't distinguish between 1 and
- // 2 digits for days
- fmtWX += _T("%d");
- break;
-
- case 3: // ddd
- fmtWX += _T("%a");
- break;
-
- case 4: // dddd
- fmtWX += _T("%A");
- break;
-
- default:
- wxFAIL_MSG( _T("too many 'd's") );
- }
- break;
-
- case _T('M'):
- switch ( lastCount )
- {
- case 1: // M
- case 2: // MM
- // as for 'd' and 'dd' above
- fmtWX += _T("%m");
- break;
-
- case 3:
- fmtWX += _T("%b");
- break;
-
- case 4:
- fmtWX += _T("%B");
- break;
-
- default:
- wxFAIL_MSG( _T("too many 'M's") );
- }
- break;
-
- case _T('y'):
- switch ( lastCount )
- {
- case 1: // y
- case 2: // yy
- fmtWX += _T("%y");
- break;
-
- case 4: // yyyy
- fmtWX += _T("%Y");
- break;
-
- default:
- wxFAIL_MSG( _T("wrong number of 'y's") );
- }
- break;
-
- case _T('H'):
- switch ( lastCount )
- {
- case 1: // H
- case 2: // HH
- fmtWX += _T("%H");
- break;
-
- default:
- wxFAIL_MSG( _T("wrong number of 'H's") );
- }
- break;
-
- case _T('h'):
- switch ( lastCount )
- {
- case 1: // h
- case 2: // hh
- fmtWX += _T("%h");
- break;
-
- default:
- wxFAIL_MSG( _T("wrong number of 'h's") );
- }
- break;
-
- case _T('m'):
- switch ( lastCount )
- {
- case 1: // m
- case 2: // mm
- fmtWX += _T("%M");
- break;
-
- default:
- wxFAIL_MSG( _T("wrong number of 'm's") );
- }
- break;
-
- case _T('s'):
- switch ( lastCount )
- {
- case 1: // s
- case 2: // ss
- fmtWX += _T("%S");
- break;
-
- default:
- wxFAIL_MSG( _T("wrong number of 's's") );
- }
- break;
-
- case _T('g'):
- // strftime() doesn't have era string,
- // ignore this format
- wxASSERT_MSG( lastCount <= 2,
- _T("too many 'g's") );
- break;
-
- default:
- wxFAIL_MSG( _T("unreachable") );
- }
-
- chLast = _T('\0');
- lastCount = 0;
- }
-
- // not a special character so must be just a separator,
- // treat as is
- if ( *p == _T('%') )
- {
- // this one needs to be escaped
- fmtWX += _T('%');
- }
-
- fmtWX += *p;
- }
- }
-
- return fmtWX;
-}
-
-static wxString GetLocaleDateFormat()
-{
- wxCFRef<CFLocaleRef> currentLocale( CFLocaleCopyCurrent() );
-
- wxCFRef<CFDateFormatterRef> dateFormatter( CFDateFormatterCreate
- (NULL, currentLocale, kCFDateFormatterShortStyle, kCFDateFormatterNoStyle));
- wxCFStringRef cfs = wxCFRetain( CFDateFormatterGetFormat(dateFormatter ));
- return TranslateFromUnicodeFormat(cfs.AsString());
-}
-
-static wxString GetLocaleFullDateFormat()
-{
- wxCFRef<CFLocaleRef> currentLocale( CFLocaleCopyCurrent() );
-
- wxCFRef<CFDateFormatterRef> dateFormatter( CFDateFormatterCreate
- (NULL, currentLocale, kCFDateFormatterLongStyle, kCFDateFormatterMediumStyle));
- wxCFStringRef cfs = wxCFRetain( CFDateFormatterGetFormat(dateFormatter ));
- return TranslateFromUnicodeFormat(cfs.AsString());
-}
-
-
-
-#endif // __WXOSX__
-
bool
wxDateTime::ParseFormat(const wxString& date,
const wxString& format,
case _T('c'): // locale default date and time representation
{
-#ifdef HAVE_STRPTIME
- struct tm tm;
+ wxDateTime dt;
- // try using strptime() -- it may fail even if the input is
- // correct but the date is out of range, so we will fall back
- // to our generic code anyhow
- if ( CallStrptime(date, input, "%c", &tm) )
- {
- hour = tm.tm_hour;
- min = tm.tm_min;
- sec = tm.tm_sec;
+ const wxString
+ fmtDateTime = wxLocale::GetInfo(wxLOCALE_DATE_TIME_FMT);
+ if ( !fmtDateTime.empty() )
+ dt = ParseFormatAt(input, end, fmtDateTime);
- year = 1900 + tm.tm_year;
- mon = (Month)tm.tm_mon;
- mday = tm.tm_mday;
+ if ( !dt.IsValid() )
+ {
+ // also try the format which corresponds to ctime()
+ // output (i.e. the "C" locale default)
+ dt = ParseFormatAt(input, end, wxS("%a %b %d %H:%M:%S %Y"));
}
- else // strptime() failed; try generic heuristic code
-#endif // HAVE_STRPTIME
+
+ if ( !dt.IsValid() )
{
- Tm tm;
-#ifdef __WXOSX__
- bool hasValidDate = false;
- wxString fmtDate = GetLocaleFullDateFormat();
- if ( !fmtDate.empty() )
- {
- const wxDateTime dt = ParseFormatAt
- (
- input,
- end,
- fmtDate
- );
- if ( dt.IsValid() )
- {
- tm = dt.GetTm();
- hasValidDate = true;
- }
- }
+ // and finally also the two generic date/time formats
+ dt = ParseFormatAt(input, end, wxS("%x %X"), wxS("%X %x"));
+ }
- if ( !hasValidDate )
-#endif // __WXOSX__
- {
- // try the format which corresponds to ctime() output
- // first, then the generic date/time formats
- const wxDateTime dt = ParseFormatAt
- (
- input,
- end,
- wxS("%a %b %d %H:%M:%S %Y"),
- wxS("%x %X"),
- wxS("%X %x")
- );
- if ( !dt.IsValid() )
- return false;
- tm = dt.GetTm();
- }
+ if ( !dt.IsValid() )
+ return false;
+ const Tm tm = dt.GetTm();
- hour = tm.hour;
- min = tm.min;
- sec = tm.sec;
+ hour = tm.hour;
+ min = tm.min;
+ sec = tm.sec;
- year = tm.year;
- mon = tm.mon;
- mday = tm.mday;
- }
+ year = tm.year;
+ mon = tm.mon;
+ mday = tm.mday;
haveDay = haveMon = haveYear =
haveHour = haveMin = haveSec = true;
haveHour = haveMin = haveSec = true;
- Tm tm = dt.GetTm();
+ const Tm tm = dt.GetTm();
hour = tm.hour;
min = tm.min;
sec = tm.sec;
haveHour =
haveMin = true;
- Tm tm = dt.GetTm();
+ const Tm tm = dt.GetTm();
hour = tm.hour;
min = tm.min;
}
haveMin =
haveSec = true;
- Tm tm = dt.GetTm();
+ const Tm tm = dt.GetTm();
hour = tm.hour;
min = tm.min;
sec = tm.sec;
break;
case _T('x'): // locale default date representation
-#ifdef HAVE_STRPTIME
- // try using strptime() -- it may fail even if the input is
- // correct but the date is out of range, so we will fall back
- // to our generic code anyhow
- {
- struct tm tm;
-
- if ( CallStrptime(date, input, "%x", &tm) )
- {
- haveDay = haveMon = haveYear = true;
-
- year = 1900 + tm.tm_year;
- mon = (Month)tm.tm_mon;
- mday = tm.tm_mday;
-
- break;
- }
- }
-#endif // HAVE_STRPTIME
-
{
- wxString fmtDate,
- fmtDateAlt;
+ wxString
+ fmtDate = wxLocale::GetInfo(wxLOCALE_SHORT_DATE_FMT),
+ fmtDateAlt = wxLocale::GetInfo(wxLOCALE_LONG_DATE_FMT);
-#if defined( __WINDOWS__ ) || defined( __WXOSX__ )
- // The above doesn't work for all locales, try to query
- // the OS for the right way of formatting the date:
- fmtDate = GetLocaleDateFormat();
if ( fmtDate.empty() )
-#endif // __WINDOWS__
{
if ( IsWestEuropeanCountry(GetCountry()) ||
GetCountry() == Russia )
{
- fmtDate = _T("%d/%m/%y");
- fmtDateAlt = _T("%m/%d/%y");
+ fmtDate = wxS("%d/%m/%Y");
+ fmtDateAlt = wxS("%m/%d/%Y");
}
else // assume USA
{
- fmtDate = _T("%m/%d/%y");
- fmtDateAlt = _T("%d/%m/%y");
+ fmtDate = wxS("%m/%d/%Y");
+ fmtDateAlt = wxS("%d/%m/%Y");
}
}
- const wxDateTime
- dt = ParseFormatAt(input, end,
- fmtDate, fmtDateAlt);
- Tm tm;
+ wxDateTime
+ dt = ParseFormatAt(input, end, fmtDate, fmtDateAlt);
if ( !dt.IsValid() )
{
- wxString fmtDateLong = fmtDate;
- wxString fmtDateLongAlt = fmtDateAlt;
-
+ // try with short years too
+ fmtDate.Replace("%Y","%y");
+ fmtDateAlt.Replace("%Y","%y");
+ dt = ParseFormatAt(input, end, fmtDate, fmtDateAlt);
- if ( !fmtDateLong.empty() )
- {
- fmtDateLong.Replace("%y","%Y");
- fmtDateLongAlt.Replace("%y","%Y");
- const wxDateTime dtLong = ParseFormatAt(input, end,
- fmtDateLong, fmtDateLongAlt);
- if ( !dtLong.IsValid() )
- return false;
-
- tm = dtLong.GetTm();
- }
- else
+ if ( !dt.IsValid() )
return false;
}
- else
- tm = dt.GetTm();
+
+ const Tm tm = dt.GetTm();
haveDay =
haveMon =
break;
case _T('X'): // locale default time representation
-#ifdef HAVE_STRPTIME
{
- // use strptime() to do it for us (FIXME !Unicode friendly)
- struct tm tm;
- if ( !CallStrptime(date, input, "%X", &tm) )
- return false;
+ wxString fmtTime = wxLocale::GetInfo(wxLOCALE_TIME_FMT),
+ fmtTimeAlt;
- haveHour = haveMin = haveSec = true;
+ if ( fmtTime.empty() )
+ {
+ // try to parse what follows as "%H:%M:%S" and, if this
+ // fails, as "%I:%M:%S %p" - this should catch the most
+ // common cases
+ fmtTime = "%T";
+ fmtTimeAlt = "%r";
+ }
- hour = tm.tm_hour;
- min = tm.tm_min;
- sec = tm.tm_sec;
- }
-#else // !HAVE_STRPTIME
- // TODO under Win32 we can query the LOCALE_ITIME system
- // setting which says whether the default time format is
- // 24 or 12 hour
- {
- // try to parse what follows as "%H:%M:%S" and, if this
- // fails, as "%I:%M:%S %p" - this should catch the most
- // common cases
const wxDateTime
- dt = ParseFormatAt(input, end, "%T", "%r");
+ dt = ParseFormatAt(input, end, fmtTime, fmtTimeAlt);
if ( !dt.IsValid() )
return false;
haveMin =
haveSec = true;
- Tm tm = dt.GetTm();
+ const Tm tm = dt.GetTm();
hour = tm.hour;
min = tm.min;
sec = tm.sec;
}
-#endif // HAVE_STRPTIME/!HAVE_STRPTIME
break;
case _T('y'): // year without century (00-99)
break;
case _T('Z'): // timezone name
- wxFAIL_MSG(_T("TODO"));
+ // FIXME: currently we just ignore everything that looks like a
+ // time zone here
+ GetAlphaToken(input, end);
break;
case _T('%'): // a percent sign
#include "wx/hashset.h"
#include "wx/filesys.h"
-#if defined(__DARWIN__)
+#if defined(__WXOSX__)
#include "wx/osx/core/cfref.h"
#include <CoreFoundation/CFLocale.h>
#include "wx/osx/core/cfstring.h"
//
// This is a "low-level" class and is used only by wxMsgCatalog
// NOTE: for the documentation of the binary catalog (.MO) files refer to
-// the GNU gettext manual:
+// the GNU gettext manual:
// http://www.gnu.org/software/autoconf/manual/gettext/MO-Files.html
// ----------------------------------------------------------------------------
}
// skip this string
- // IMPORTANT: accesses to the 'data' pointer are valid only for
+ // IMPORTANT: accesses to the 'data' pointer are valid only for
// the first 'length+1' bytes (GNU specs says that the
- // final NUL is not counted in length); using wxStrnlen()
+ // final NUL is not counted in length); using wxStrnlen()
// we make sure we don't access memory beyond the valid range
// (which otherwise may happen for invalid MO files):
offset += wxStrnlen(str, length - offset) + 1;
// accessors for locale-dependent data
// ----------------------------------------------------------------------------
+#if defined(__WXMSW__) || defined(__WXOSX__)
+
+namespace
+{
+
+// This function translates from Unicode date formats described at
+//
+// http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns
+//
+// to strftime()-like syntax. This translation is not lossless but we try to do
+// our best.
+
+static wxString TranslateFromUnicodeFormat(const wxString& fmt)
+{
+ wxString fmtWX;
+ fmtWX.reserve(fmt.length());
+
+ char chLast = '\0';
+ size_t lastCount = 0;
+ for ( wxString::const_iterator p = fmt.begin(); /* end handled inside */; ++p )
+ {
+ if ( p != fmt.end() )
+ {
+ if ( *p == chLast )
+ {
+ lastCount++;
+ continue;
+ }
+
+ const wxUniChar ch = (*p).GetValue();
+ if ( ch.IsAscii() && strchr("dghHmMsSy", ch) )
+ {
+ // these characters come in groups, start counting them
+ chLast = ch;
+ lastCount = 1;
+ continue;
+ }
+ }
+
+ // interpret any special characters we collected so far
+ if ( lastCount )
+ {
+ switch ( chLast )
+ {
+ case 'd':
+ switch ( lastCount )
+ {
+ case 1: // d
+ case 2: // dd
+ // these two are the same as we don't distinguish
+ // between 1 and 2 digits for days
+ fmtWX += "%d";
+ break;
+
+ case 3: // ddd
+ fmtWX += "%a";
+ break;
+
+ case 4: // dddd
+ fmtWX += "%A";
+ break;
+
+ default:
+ wxFAIL_MSG( "too many 'd's" );
+ }
+ break;
+
+ case 'M':
+ switch ( lastCount )
+ {
+ case 1: // M
+ case 2: // MM
+ // as for 'd' and 'dd' above
+ fmtWX += "%m";
+ break;
+
+ case 3:
+ fmtWX += "%b";
+ break;
+
+ case 4:
+ fmtWX += "%B";
+ break;
+
+ default:
+ wxFAIL_MSG( "too many 'M's" );
+ }
+ break;
+
+ case 'y':
+ switch ( lastCount )
+ {
+ case 1: // y
+ case 2: // yy
+ fmtWX += "%y";
+ break;
+
+ case 4: // yyyy
+ fmtWX += "%Y";
+ break;
+
+ default:
+ wxFAIL_MSG( "wrong number of 'y's" );
+ }
+ break;
+
+ case 'H':
+ switch ( lastCount )
+ {
+ case 1: // H
+ case 2: // HH
+ fmtWX += "%H";
+ break;
+
+ default:
+ wxFAIL_MSG( "wrong number of 'H's" );
+ }
+ break;
+
+ case 'h':
+ switch ( lastCount )
+ {
+ case 1: // h
+ case 2: // hh
+ fmtWX += "%h";
+ break;
+
+ default:
+ wxFAIL_MSG( "wrong number of 'h's" );
+ }
+ break;
+
+ case 'm':
+ switch ( lastCount )
+ {
+ case 1: // m
+ case 2: // mm
+ fmtWX += "%M";
+ break;
+
+ default:
+ wxFAIL_MSG( "wrong number of 'm's" );
+ }
+ break;
+
+ case 's':
+ switch ( lastCount )
+ {
+ case 1: // s
+ case 2: // ss
+ fmtWX += "%S";
+ break;
+
+ default:
+ wxFAIL_MSG( "wrong number of 's's" );
+ }
+ break;
+
+ case 'g':
+ // strftime() doesn't have era string,
+ // ignore this format
+ wxASSERT_MSG( lastCount <= 2, "too many 'g's" );
+ break;
+
+ default:
+ wxFAIL_MSG( "unreachable" );
+ }
+
+ chLast = '\0';
+ lastCount = 0;
+ }
+
+ if ( p == fmt.end() )
+ break;
+
+ // not a special character so must be just a separator, treat as is
+ if ( *p == _T('%') )
+ {
+ // this one needs to be escaped
+ fmtWX += _T('%');
+ }
+
+ fmtWX += *p;
+ }
+
+ return fmtWX;
+}
+
+} // anonymous namespace
+
+#endif // __WXMSW__ || __WXOSX__
+
#if defined(__WXMSW__)
+namespace
+{
+
+LCTYPE GetLCTYPEFormatFromLocalInfo(wxLocaleInfo index)
+{
+ switch ( index )
+ {
+ case wxLOCALE_SHORT_DATE_FMT:
+ return LOCALE_SSHORTDATE;
+
+ case wxLOCALE_LONG_DATE_FMT:
+ return LOCALE_SLONGDATE;
+
+ case wxLOCALE_TIME_FMT:
+ return LOCALE_STIMEFORMAT;
+
+ default:
+ wxFAIL_MSG( "no matching LCTYPE" );
+ }
+
+ return 0;
+}
+
+} // anonymous namespace
+
/* static */
wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat))
{
wxUint32 lcid = LOCALE_USER_DEFAULT;
-
- if (wxGetLocale())
+ if ( wxGetLocale() )
{
- const wxLanguageInfo *info = GetLanguageInfo(wxGetLocale()->GetLanguage());
+ const wxLanguageInfo * const
+ info = GetLanguageInfo(wxGetLocale()->GetLanguage());
if ( info )
lcid = info->GetLCID();
}
wxString str;
- wxChar buffer[256];
- size_t count;
- buffer[0] = wxS('\0');
- switch (index)
+
+ wxChar buf[256];
+ buf[0] = wxT('\0');
+
+ switch ( index )
{
case wxLOCALE_DECIMAL_POINT:
- count = ::GetLocaleInfo(lcid, LOCALE_SDECIMAL, buffer, 256);
- if (!count)
- str << wxS(".");
- else
- str << buffer;
+ if ( ::GetLocaleInfo(lcid, LOCALE_SDECIMAL, buf, WXSIZEOF(buf)) )
+ str = buf;
break;
-#if 0
- case wxSYS_LIST_SEPARATOR:
- count = ::GetLocaleInfo(lcid, LOCALE_SLIST, buffer, 256);
- if (!count)
- str << wxS(",");
- else
- str << buffer;
+
+ case wxLOCALE_SHORT_DATE_FMT:
+ case wxLOCALE_LONG_DATE_FMT:
+ case wxLOCALE_TIME_FMT:
+ if ( ::GetLocaleInfo(lcid, GetLCTYPEFormatFromLocalInfo(index),
+ buf, WXSIZEOF(buf)) )
+ {
+ return TranslateFromUnicodeFormat(buf);
+ }
break;
- case wxSYS_LEADING_ZERO: // 0 means no leading zero, 1 means leading zero
- count = ::GetLocaleInfo(lcid, LOCALE_ILZERO, buffer, 256);
- if (!count)
- str << wxS("0");
- else
- str << buffer;
+
+ case wxLOCALE_DATE_TIME_FMT:
+ // there doesn't seem to be any specific setting for this, so just
+ // combine date and time ones
+ {
+ const wxString datefmt = GetInfo(wxLOCALE_LONG_DATE_FMT);
+ if ( datefmt.empty() )
+ break;
+
+ const wxString timefmt = GetInfo(wxLOCALE_TIME_FMT);
+ if ( timefmt.empty() )
+ break;
+
+ str << datefmt << ' ' << timefmt;
+ }
break;
-#endif
+
default:
- wxFAIL_MSG(wxS("Unknown System String !"));
+ wxFAIL_MSG( "unknown wxLocaleInfo" );
}
+
return str;
}
-#elif defined(__DARWIN__)
+#elif defined(__WXOSX__)
/* static */
wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat))
cfstr = (CFStringRef) CFLocaleGetValue(userLocaleRef, kCFLocaleDecimalSeparator);
break;
+ case wxLOCALE_SHORT_DATE_FMT:
+ case wxLOCALE_LONG_DATE_FMT:
+ case wxLOCALE_DATE_TIME_FMT:
+ case wxLOCALE_TIME_FMT:
+ // TODO
+ return wxString();
+
default:
wxFAIL_MSG( "Unknown locale info" );
- cfstr = CFSTR("");
- break;
+ return wxString();
}
wxCFStringRef str(wxCFRetain(cfstr));
return str.AsString();
}
-#else // !__WXMSW__ && !__DARWIN__
+#else // !__WXMSW__ && !__WXOSX__, assume generic POSIX
+
+namespace
+{
+
+wxString GetDateFormatFromLangInfo(wxLocaleInfo index)
+{
+#ifdef HAVE_LANGINFO_H
+ // array containing parameters for nl_langinfo() indexes by offset of index
+ // from wxLOCALE_SHORT_DATE_FMT
+ static const nl_item items[] =
+ {
+ D_FMT, D_T_FMT, D_T_FMT, T_FMT,
+ };
+
+ const int nlidx = index - wxLOCALE_SHORT_DATE_FMT;
+ if ( nlidx < 0 || nlidx >= (int)WXSIZEOF(items) )
+ {
+ wxFAIL_MSG( "logic error in GetInfo() code" );
+ return wxString();
+ }
+
+ const wxString fmt(nl_langinfo(items[nlidx]));
+
+ // just return the format returned by nl_langinfo() except for long date
+ // format which we need to recover from date/time format ourselves (but not
+ // if we failed completely)
+ if ( fmt.empty() || index != wxLOCALE_LONG_DATE_FMT )
+ return fmt;
+
+ // this is not 100% precise but the idea is that a typical date/time format
+ // under POSIX systems is a combination of a long date format with time one
+ // so we should be able to get just the long date format by removing all
+ // time-specific format specifiers
+ static const char *timeFmtSpecs = "HIklMpPrRsSTXzZ";
+ static const char *timeSep = " :./-";
+
+ wxString fmtDateOnly;
+ const wxString::const_iterator end = fmt.end();
+ wxString::const_iterator lastSep = end;
+ for ( wxString::const_iterator p = fmt.begin(); p != end; ++p )
+ {
+ if ( strchr(timeSep, *p) )
+ {
+ if ( lastSep == end )
+ lastSep = p;
+
+ // skip it for now, we'll discard it if it's followed by a time
+ // specifier later or add it to fmtDateOnly if it is not
+ continue;
+ }
+
+ if ( *p == '%' &&
+ (p + 1 != end) && strchr(timeFmtSpecs, p[1]) )
+ {
+ // time specified found: skip it and any preceding separators
+ ++p;
+ lastSep = end;
+ continue;
+ }
+
+ if ( lastSep != end )
+ {
+ fmtDateOnly += wxString(lastSep, p);
+ lastSep = end;
+ }
+
+ fmtDateOnly += *p;
+ }
+
+ return fmtDateOnly;
+#else // !HAVE_LANGINFO_H
+ // no fallback, let the application deal with unavailability of
+ // nl_langinfo() itself as there is no good way for us to do it (well, we
+ // could try to reverse engineer the format from strftime() output but this
+ // looks like too much trouble considering the relatively small number of
+ // systems without nl_langinfo() still in use)
+ return wxString();
+#endif // HAVE_LANGINFO_H/!HAVE_LANGINFO_H
+}
+
+} // anonymous namespace
/* static */
wxString wxLocale::GetInfo(wxLocaleInfo index, wxLocaleCategory cat)
if ( !lc )
return wxString();
- switch ( cat )
+ switch ( index )
{
- case wxLOCALE_CAT_NUMBER:
- switch ( index )
- {
- case wxLOCALE_THOUSANDS_SEP:
- return lc->thousands_sep;
+ case wxLOCALE_THOUSANDS_SEP:
+ if ( cat == wxLOCALE_CAT_NUMBER )
+ return lc->thousands_sep;
+ else if ( cat == wxLOCALE_CAT_MONEY )
+ return lc->mon_thousands_sep;
- case wxLOCALE_DECIMAL_POINT:
- return lc->decimal_point;
- }
+ wxFAIL_MSG( "invalid wxLocaleCategory" );
break;
- case wxLOCALE_CAT_MONEY:
- switch ( index )
- {
- case wxLOCALE_THOUSANDS_SEP:
- return lc->mon_thousands_sep;
- case wxLOCALE_DECIMAL_POINT:
- return lc->mon_decimal_point;
- }
+ case wxLOCALE_DECIMAL_POINT:
+ if ( cat == wxLOCALE_CAT_NUMBER )
+ return lc->decimal_point;
+ else if ( cat == wxLOCALE_CAT_MONEY )
+ return lc->mon_decimal_point;
+
+ wxFAIL_MSG( "invalid wxLocaleCategory" );
break;
+ case wxLOCALE_SHORT_DATE_FMT:
+ case wxLOCALE_LONG_DATE_FMT:
+ case wxLOCALE_DATE_TIME_FMT:
+ case wxLOCALE_TIME_FMT:
+ if ( cat != wxLOCALE_CAT_DATE && cat != wxLOCALE_CAT_DEFAULT )
+ {
+ wxFAIL_MSG( "invalid wxLocaleCategory" );
+ break;
+ }
+
+ return GetDateFormatFromLangInfo(index);
+
+
default:
- wxFAIL_MSG( "unknown wxLocaleCategory" );
- return wxString(); // skip second assert below
+ wxFAIL_MSG( "unknown wxLocaleInfo value" );
}
- wxFAIL_MSG( "unknown wxLocaleInfo value for this category" );
-
return wxString();
}
{ 6, wxDateTime::Feb, 1856, 23, 30, 00, 0.0, wxDateTime::Inv_WeekDay },
{ 6, wxDateTime::Feb, 1857, 23, 30, 00, 0.0, wxDateTime::Inv_WeekDay },
{ 29, wxDateTime::May, 2076, 18, 30, 00, 0.0, wxDateTime::Inv_WeekDay },
- { 29, wxDateTime::Feb, 2400, 02, 15, 25, 0.0, wxDateTime::Inv_WeekDay },
+
+ // FIXME: the test with 02:15:25 time doesn't pass because of DST
+ // computation problems, we get back 03:15:25
+ { 29, wxDateTime::Feb, 2400, 04, 15, 25, 0.0, wxDateTime::Inv_WeekDay },
#if 0
// Need to add support for BCE dates.
{ 01, wxDateTime::Jan, -52, 03, 16, 47, 0.0, wxDateTime::Inv_WeekDay },
wxDateTime dt;
+#if 0
+ // special case which was known to fail
+ CPPUNIT_ASSERT( dt.ParseFormat("02/06/1856", "%x") );
+ CPPUNIT_ASSERT_EQUAL( 1856, dt.GetYear() );
+#endif
+
// test partially specified dates too
wxDateTime dtDef(26, wxDateTime::Sep, 2008);
CPPUNIT_ASSERT( dt.ParseFormat("17", "%d") );
CPPUNIT_TEST_SUITE( IntlTestCase );
CPPUNIT_TEST( Domain );
CPPUNIT_TEST( Headers );
+ CPPUNIT_TEST( DateTimeFmt );
CPPUNIT_TEST_SUITE_END();
void Domain();
void Headers();
+ void DateTimeFmt();
wxLocale *m_locale;
void IntlTestCase::setUp()
{
- if (!wxLocale::IsAvailable(wxLANGUAGE_FRENCH))
- return; // you should have french support installed to run this test!
+ // Check that French locale is supported, this test doesn't work without it
+ // and all the other function need to check whether m_locale is non-NULL
+ // before continuing
+ if ( !wxLocale::IsAvailable(wxLANGUAGE_FRENCH) )
+ return;
wxLocale::AddCatalogLookupPathPrefix("./intl");
m_locale = new wxLocale;
- CPPUNIT_ASSERT( m_locale);
-
+ CPPUNIT_ASSERT( m_locale );
+
// don't load default catalog, it may be unavailable:
bool loaded = m_locale->Init(wxLANGUAGE_FRENCH, wxLOCALE_CONV_ENCODING);
CPPUNIT_ASSERT( loaded );
void IntlTestCase::Domain()
{
if (!m_locale)
- return; // no french support installed on this system!
+ return;
// _() searches all domains by default:
CPPUNIT_ASSERT_EQUAL( "&Ouvrir un fichier", _("&Open bogus file") );
void IntlTestCase::Headers()
{
- if (!m_locale)
- return; // no french support installed on this system!
+ if ( !m_locale )
+ return;
CPPUNIT_ASSERT_EQUAL( "wxWindows 2.0 i18n sample", m_locale->GetHeaderValue("Project-Id-Version") );
CPPUNIT_ASSERT_EQUAL( "1999-01-13 18:19+0100", m_locale->GetHeaderValue("POT-Creation-Date") );
CPPUNIT_ASSERT_EQUAL( "", m_locale->GetHeaderValue("X-Not-Here") );
}
+static void CompareFormats(const wxString& expected, wxString actual)
+{
+ if ( actual.empty() )
+ {
+ // this means that GetInfo() failed which can happen, just ignore
+ return;
+ }
+
+#ifdef __GLIBC__
+ // glibc uses some extensions in its formats which we need to convert to
+ // standard form
+ actual.Replace("%T", "%H:%M:%S");
+ actual.Replace("%e", "%d");
+#endif // __GLIBC__
+
+ CPPUNIT_ASSERT_EQUAL( expected, actual );
+}
+
+void IntlTestCase::DateTimeFmt()
+{
+ if ( !m_locale )
+ return;
+
+ CompareFormats( "%d.%m.%Y", m_locale->GetInfo(wxLOCALE_SHORT_DATE_FMT) );
+ CompareFormats( "%a %d %b %Y", m_locale->GetInfo(wxLOCALE_LONG_DATE_FMT) );
+ CompareFormats( "%a %d %b %Y %H:%M:%S %Z",
+ m_locale->GetInfo(wxLOCALE_DATE_TIME_FMT) );
+ CompareFormats( "%H:%M:%S", m_locale->GetInfo(wxLOCALE_TIME_FMT) );
+
+ // also test for "C" locale
+ setlocale(LC_ALL, "C");
+
+ CompareFormats( "%m/%d/%y", m_locale->GetInfo(wxLOCALE_SHORT_DATE_FMT) );
+ CompareFormats( "%a %b %d %Y", m_locale->GetInfo(wxLOCALE_LONG_DATE_FMT) );
+ CompareFormats( "%a %b %d %H:%M:%S %Y",
+ m_locale->GetInfo(wxLOCALE_DATE_TIME_FMT) );
+ CompareFormats( "%H:%M:%S", m_locale->GetInfo(wxLOCALE_TIME_FMT) );
+}
+
#endif // wxUSE_INTL