@ -575,22 +575,32 @@ PGLC_localeconv(void)
* pg_strftime ( ) , which isn ' t locale - aware and does not need to be replaced .
* pg_strftime ( ) , which isn ' t locale - aware and does not need to be replaced .
*/
*/
static size_t
static size_t
strftime_win32 ( char * dst , size_t dstlen , const wchar_t * format , const struct tm * tm )
strftime_win32 ( char * dst , size_t dstlen ,
const char * format , const struct tm * tm )
{
{
size_t len ;
size_t len ;
wchar_t wformat [ 8 ] ; /* formats used below need 3 bytes */
wchar_t wbuf [ MAX_L10N_DATA ] ;
wchar_t wbuf [ MAX_L10N_DATA ] ;
len = wcsftime ( wbuf , MAX_L10N_DATA , format , tm ) ;
/* get a wchar_t version of the format string */
len = MultiByteToWideChar ( CP_UTF8 , 0 , format , - 1 ,
wformat , lengthof ( wformat ) ) ;
if ( len = = 0 )
elog ( ERROR , " could not convert format string from UTF-8: error code %lu " ,
GetLastError ( ) ) ;
len = wcsftime ( wbuf , MAX_L10N_DATA , wformat , tm ) ;
if ( len = = 0 )
if ( len = = 0 )
{
{
/*
/*
* strftime call failed - return 0 with the contents of dst
* strftime failed , possibly because the result would not fit in
* unspecified
* MAX_L10N_DATA . Return 0 with the contents of dst unspecified .
*/
*/
return 0 ;
return 0 ;
}
}
len = WideCharToMultiByte ( CP_UTF8 , 0 , wbuf , len , dst , dstlen , NULL , NULL ) ;
len = WideCharToMultiByte ( CP_UTF8 , 0 , wbuf , len , dst , dstlen - 1 ,
NULL , NULL ) ;
if ( len = = 0 )
if ( len = = 0 )
elog ( ERROR , " could not convert string to UTF-8: error code %lu " ,
elog ( ERROR , " could not convert string to UTF-8: error code %lu " ,
GetLastError ( ) ) ;
GetLastError ( ) ) ;
@ -612,9 +622,33 @@ strftime_win32(char *dst, size_t dstlen, const wchar_t *format, const struct tm
}
}
/* redefine strftime() */
/* redefine strftime() */
# define strftime(a,b,c,d) strftime_win32(a,b,L## c,d)
# define strftime(a,b,c,d) strftime_win32(a,b,c,d)
# endif /* WIN32 */
# endif /* WIN32 */
/* Subroutine for cache_locale_time(). */
static void
cache_single_time ( char * * dst , const char * format , const struct tm * tm )
{
char buf [ MAX_L10N_DATA ] ;
char * ptr ;
/*
* MAX_L10N_DATA is sufficient buffer space for every known locale , and
* POSIX defines no strftime ( ) errors . ( Buffer space exhaustion is not an
* error . ) An implementation might report errors ( e . g . ENOMEM ) by
* returning 0 ( or , less plausibly , a negative value ) and setting errno .
* Report errno just in case the implementation did that , but clear it in
* advance of the call so we don ' t emit a stale , unrelated errno .
*/
errno = 0 ;
if ( strftime ( buf , MAX_L10N_DATA , format , tm ) < = 0 )
elog ( ERROR , " strftime(%s) failed: %m " , format ) ;
ptr = MemoryContextStrdup ( TopMemoryContext , buf ) ;
if ( * dst )
pfree ( * dst ) ;
* dst = ptr ;
}
/*
/*
* Update the lc_time localization cache variables if needed .
* Update the lc_time localization cache variables if needed .
@ -625,8 +659,6 @@ cache_locale_time(void)
char * save_lc_time ;
char * save_lc_time ;
time_t timenow ;
time_t timenow ;
struct tm * timeinfo ;
struct tm * timeinfo ;
char buf [ MAX_L10N_DATA ] ;
char * ptr ;
int i ;
int i ;
# ifdef WIN32
# ifdef WIN32
@ -673,17 +705,8 @@ cache_locale_time(void)
for ( i = 0 ; i < 7 ; i + + )
for ( i = 0 ; i < 7 ; i + + )
{
{
timeinfo - > tm_wday = i ;
timeinfo - > tm_wday = i ;
strftime ( buf , MAX_L10N_DATA , " %a " , timeinfo ) ;
cache_single_time ( & localized_abbrev_days [ i ] , " %a " , timeinfo ) ;
ptr = MemoryContextStrdup ( TopMemoryContext , buf ) ;
cache_single_time ( & localized_full_days [ i ] , " %A " , timeinfo ) ;
if ( localized_abbrev_days [ i ] )
pfree ( localized_abbrev_days [ i ] ) ;
localized_abbrev_days [ i ] = ptr ;
strftime ( buf , MAX_L10N_DATA , " %A " , timeinfo ) ;
ptr = MemoryContextStrdup ( TopMemoryContext , buf ) ;
if ( localized_full_days [ i ] )
pfree ( localized_full_days [ i ] ) ;
localized_full_days [ i ] = ptr ;
}
}
/* localized months */
/* localized months */
@ -691,17 +714,8 @@ cache_locale_time(void)
{
{
timeinfo - > tm_mon = i ;
timeinfo - > tm_mon = i ;
timeinfo - > tm_mday = 1 ; /* make sure we don't have invalid date */
timeinfo - > tm_mday = 1 ; /* make sure we don't have invalid date */
strftime ( buf , MAX_L10N_DATA , " %b " , timeinfo ) ;
cache_single_time ( & localized_abbrev_months [ i ] , " %b " , timeinfo ) ;
ptr = MemoryContextStrdup ( TopMemoryContext , buf ) ;
cache_single_time ( & localized_full_months [ i ] , " %B " , timeinfo ) ;
if ( localized_abbrev_months [ i ] )
pfree ( localized_abbrev_months [ i ] ) ;
localized_abbrev_months [ i ] = ptr ;
strftime ( buf , MAX_L10N_DATA , " %B " , timeinfo ) ;
ptr = MemoryContextStrdup ( TopMemoryContext , buf ) ;
if ( localized_full_months [ i ] )
pfree ( localized_full_months [ i ] ) ;
localized_full_months [ i ] = ptr ;
}
}
/* try to restore internal settings */
/* try to restore internal settings */