4
4
*
5
5
* Portions Copyright (c) 2002-2009, PostgreSQL Global Development Group
6
6
*
7
- * $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.43 2009/01/01 17:23:49 momjian Exp $
7
+ * $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.44 2009/01/09 13:03:55 mha Exp $
8
8
*
9
9
*-----------------------------------------------------------------------
10
10
*/
51
51
#include <time.h>
52
52
53
53
#include "catalog/pg_control.h"
54
+ #include "mb/pg_wchar.h"
54
55
#include "utils/memutils.h"
55
56
#include "utils/pg_locale.h"
56
57
@@ -452,6 +453,57 @@ PGLC_localeconv(void)
452
453
return & CurrentLocaleConv ;
453
454
}
454
455
456
+ #ifdef WIN32
457
+ /*
458
+ * On win32, strftime() returns the encoding in CP_ACP, which is likely
459
+ * different from SERVER_ENCODING. This is especially important in Japanese
460
+ * versions of Windows which will use SJIS encoding, which we don't support
461
+ * as a server encoding.
462
+ *
463
+ * Replace strftime() with a version that gets the string in UTF16 and then
464
+ * converts it to the appropriate encoding as necessary.
465
+ *
466
+ * Note that this only affects the calls to strftime() in this file, which are
467
+ * used to get the locale-aware strings. Other parts of the backend use
468
+ * pg_strftime(), which isn't locale-aware and does not need to be replaced.
469
+ */
470
+ static size_t
471
+ strftime_win32 (char * dst , size_t dstlen , const wchar_t * format , const struct tm * tm )
472
+ {
473
+ size_t len ;
474
+ wchar_t wbuf [MAX_L10N_DATA ];
475
+ int encoding ;
476
+
477
+ encoding = GetDatabaseEncoding ();
478
+
479
+ len = wcsftime (wbuf , sizeof (wbuf ), format , tm );
480
+ if (len == 0 )
481
+ /* strftime call failed - return 0 with the contents of dst unspecified */
482
+ return 0 ;
483
+
484
+ len = WideCharToMultiByte (CP_UTF8 , 0 , wbuf , len , dst , dstlen , NULL , NULL );
485
+ if (len == 0 )
486
+ elog (ERROR ,
487
+ "could not convert string to UTF-8:error %lu" , GetLastError ());
488
+
489
+ dst [len ] = '\0' ;
490
+ if (encoding != PG_UTF8 )
491
+ {
492
+ char * convstr = pg_do_encoding_conversion (dst , len , PG_UTF8 , encoding );
493
+ if (dst != convstr )
494
+ {
495
+ StrNCpy (dst , convstr , dstlen );
496
+ len = strlen (dst );
497
+ }
498
+ }
499
+
500
+ return len ;
501
+ }
502
+
503
+ #define strftime (a ,b ,c ,d ) strftime_win32(a,b,L##c,d)
504
+
505
+ #endif /* WIN32 */
506
+
455
507
456
508
/*
457
509
* Update the lc_time localization cache variables if needed.
@@ -465,13 +517,25 @@ cache_locale_time(void)
465
517
char buf [MAX_L10N_DATA ];
466
518
char * ptr ;
467
519
int i ;
520
+ #ifdef WIN32
521
+ char * save_lc_ctype ;
522
+ #endif
468
523
469
524
/* did we do this already? */
470
525
if (CurrentLCTimeValid )
471
526
return ;
472
527
473
528
elog (DEBUG3 , "cache_locale_time() executed; locale: \"%s\"" , locale_time );
474
529
530
+ #ifdef WIN32
531
+ /* set user's value of ctype locale */
532
+ save_lc_ctype = setlocale (LC_CTYPE , NULL );
533
+ if (save_lc_ctype )
534
+ save_lc_ctype = pstrdup (save_lc_ctype );
535
+
536
+ setlocale (LC_CTYPE , locale_time );
537
+ #endif
538
+
475
539
/* set user's value of time locale */
476
540
save_lc_time = setlocale (LC_TIME , NULL );
477
541
if (save_lc_time )
@@ -524,5 +588,14 @@ cache_locale_time(void)
524
588
pfree (save_lc_time );
525
589
}
526
590
591
+ #ifdef WIN32
592
+ /* try to restore internal ctype settings */
593
+ if (save_lc_ctype )
594
+ {
595
+ setlocale (LC_CTYPE , save_lc_ctype );
596
+ pfree (save_lc_ctype );
597
+ }
598
+ #endif
599
+
527
600
CurrentLCTimeValid = true;
528
601
}
0 commit comments