Search Postgresql Archives

Re: trouble with to_char('L')

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Bruce Momjian wrote:
Hiroshi Inoue wrote:
Bruce Momjian wrote:
Where are we on this issue?
Oops I forgot it completely.
I have a little improved version and would post it tonight.

Ah, very good.  Thanks.

Attached is an improved version.

regards,
Hiroshi Inoue
? formatting.patch
? pg_locale.patch
? pg_locale_20081221.patch
? pg_locale_20090120.patch
? pg_locale_20090422.patch
? pg_locale_20090423.patch
? pg_locale_20090427.patch
? pg_locale_20090608.patch
? pg_locale_20090901.patch
? pg_locale_with_debug.c
Index: pg_locale.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v
retrieving revision 1.51
diff -c -c -r1.51 pg_locale.c
*** pg_locale.c	2 Jan 2010 16:57:54 -0000	1.51
--- pg_locale.c	26 Feb 2010 22:43:52 -0000
***************
*** 386,391 ****
--- 386,449 ----
  		free(s->positive_sign);
  }
  
+ #ifdef	WIN32
+ static char *db_strdup(const char *item, const char *str)
+ {
+ 	int	encoding = GetDatabaseEncoding();
+ 	size_t	wchars, ilen, wclen, dstlen;
+ 	int	utflen, bytes_per_char;
+ 	wchar_t	*wbuf;
+ 	char	*dst;
+ 
+ 	if (!str[0])
+ 		return strdup(str);
+ 	ilen = strlen(str) + 1;
+ 	wclen = ilen * sizeof(wchar_t);
+ 	wbuf = (wchar_t *) palloc(wclen);
+ 	wchars = mbstowcs(wbuf, str, ilen);
+ 	if (wchars == (size_t) -1)
+ 		elog(ERROR,
+ 			"could not convert string to Wide characters:error %lu", GetLastError());
+ 
+ 	bytes_per_char = pg_encoding_max_length(PG_UTF8);
+ 	if (pg_encoding_max_length(encoding) > bytes_per_char)
+ 		bytes_per_char = pg_encoding_max_length(encoding);
+ 	dstlen = wchars * bytes_per_char + 1;
+ 	dst = malloc(dstlen);
+ 	if (dst == NULL)
+ 		elog(ERROR, "could not allocate a destination buffer");
+   
+ 	utflen = WideCharToMultiByte(CP_UTF8, 0, wbuf, wchars, dst, dstlen, NULL, NULL);
+ 	if (utflen == 0)
+ 		elog(ERROR,
+ 			"could not convert string %04x to UTF-8:error %lu", wbuf[0], GetLastError());
+ 	pfree(wbuf);
+ 
+ 	dst[utflen] = '\0';
+ 	if (encoding != PG_UTF8)
+ 	{
+ 		PG_TRY();
+ 		{
+ 			char *convstr = pg_do_encoding_conversion(dst, utflen, PG_UTF8, encoding);
+ 			if (dst != convstr)
+ 			{
+ 				strlcpy(dst, convstr, dstlen);
+ 				pfree(convstr);
+ 			}
+ 		}
+ 		PG_CATCH();
+ 		{
+ 			FlushErrorState();
+ 			dst[0] = '\0';
+ 		}
+ 		PG_END_TRY();
+ 	}
+ 
+ 	return dst;
+ }
+ #else
+ static char *db_strdup(const char *item, const char *str)	{return strdup(str);}
+ #endif /* WIN32 */
  
  /*
   * Return the POSIX lconv struct (contains number/money formatting
***************
*** 398,403 ****
--- 456,463 ----
  	struct lconv *extlconv;
  	char	   *save_lc_monetary;
  	char	   *save_lc_numeric;
+ 	bool	change_lc_ctype = false, is_same_locale = true;
+ 	char	*save_lc_ctype = NULL;
  
  	/* Did we do it already? */
  	if (CurrentLocaleConvValid)
***************
*** 413,422 ****
  	if (save_lc_numeric)
  		save_lc_numeric = pstrdup(save_lc_numeric);
  
  	setlocale(LC_MONETARY, locale_monetary);
! 	setlocale(LC_NUMERIC, locale_numeric);
  
! 	/* Get formatting information */
  	extlconv = localeconv();
  
  	/*
--- 473,496 ----
  	if (save_lc_numeric)
  		save_lc_numeric = pstrdup(save_lc_numeric);
  
+ #ifdef	WIN32
+ 	is_same_locale = (stricmp(locale_monetary, locale_numeric) == 0);
+ 	save_lc_ctype = setlocale(LC_CTYPE, NULL);
+ 	if (!is_same_locale || save_lc_ctype == NULL || stricmp(locale_monetary, save_lc_ctype) != 0)
+ 		change_lc_ctype = true;
+ 	if (change_lc_ctype && save_lc_ctype)
+ 		save_lc_ctype = pstrdup(save_lc_ctype);
+ 	else
+ 		save_lc_ctype = NULL;
+ #endif
+ 
+ 	if (change_lc_ctype)
+ 		setlocale(LC_CTYPE, locale_monetary);
  	setlocale(LC_MONETARY, locale_monetary);
! 	if (is_same_locale)
! 		setlocale(LC_NUMERIC, locale_numeric);
  
! 	/* Get formatting information for LC_MONETARY( and LC_NUMERIC when they are the same) */
  	extlconv = localeconv();
  
  	/*
***************
*** 424,442 ****
  	 * localeconv()'s results.
  	 */
  	CurrentLocaleConv = *extlconv;
! 	CurrentLocaleConv.currency_symbol = strdup(extlconv->currency_symbol);
! 	CurrentLocaleConv.decimal_point = strdup(extlconv->decimal_point);
! 	CurrentLocaleConv.grouping = strdup(extlconv->grouping);
! 	CurrentLocaleConv.thousands_sep = strdup(extlconv->thousands_sep);
! 	CurrentLocaleConv.int_curr_symbol = strdup(extlconv->int_curr_symbol);
! 	CurrentLocaleConv.mon_decimal_point = strdup(extlconv->mon_decimal_point);
  	CurrentLocaleConv.mon_grouping = strdup(extlconv->mon_grouping);
! 	CurrentLocaleConv.mon_thousands_sep = strdup(extlconv->mon_thousands_sep);
! 	CurrentLocaleConv.negative_sign = strdup(extlconv->negative_sign);
! 	CurrentLocaleConv.positive_sign = strdup(extlconv->positive_sign);
  	CurrentLocaleConv.n_sign_posn = extlconv->n_sign_posn;
  
  	/* Try to restore internal settings */
  	if (save_lc_monetary)
  	{
  		setlocale(LC_MONETARY, save_lc_monetary);
--- 498,528 ----
  	 * localeconv()'s results.
  	 */
  	CurrentLocaleConv = *extlconv;
! 	CurrentLocaleConv.currency_symbol = db_strdup("currency_symbol", extlconv->currency_symbol);
! 	CurrentLocaleConv.int_curr_symbol = db_strdup("int_curr_symbol", extlconv->int_curr_symbol);
! 	CurrentLocaleConv.mon_decimal_point = db_strdup("mon_decimal_point", extlconv->mon_decimal_point);
  	CurrentLocaleConv.mon_grouping = strdup(extlconv->mon_grouping);
! 	CurrentLocaleConv.mon_thousands_sep = db_strdup("mon_thousands_sep", extlconv->mon_thousands_sep);
! 	CurrentLocaleConv.negative_sign = db_strdup("nagative_sign", extlconv->negative_sign);
! 	CurrentLocaleConv.positive_sign = db_strdup("positive_sign", extlconv->positive_sign);
  	CurrentLocaleConv.n_sign_posn = extlconv->n_sign_posn;
  
+ 	if (!is_same_locale)
+ 	{
+ 		setlocale(LC_CTYPE, locale_numeric);
+ 		setlocale(LC_NUMERIC, locale_numeric);
+ 		/* Get formatting information for LC_NUMERIC */
+ 		extlconv = localeconv();
+ 	}
+ 	CurrentLocaleConv.decimal_point = db_strdup("decimal_point", extlconv->decimal_point);
+ 	CurrentLocaleConv.grouping = strdup(extlconv->grouping);
+ 	CurrentLocaleConv.thousands_sep = db_strdup("thousands_sep", extlconv->thousands_sep);
  	/* Try to restore internal settings */
+ 	if (save_lc_ctype)
+ 	{
+ 		setlocale(LC_CTYPE, save_lc_ctype);
+ 		pfree(save_lc_ctype);
+ 	}
  	if (save_lc_monetary)
  	{
  		setlocale(LC_MONETARY, save_lc_monetary);
-- 
Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux