Tom Lane wrote:
> > The only question I have is whether those locale values are single-byte
> > strings in all locals, or could they be multi-byte or multi-character,
> > in which case I have to treat them as strings.
>
> I think you have to assume they could be strings.
OK, the following applied patch enables multi-byte locale strings for
numericsep. I also reorganized the code a little.
--
Bruce Momjian | http://candle.pha.pa.us
[email protected] | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
Index: src/bin/psql/print.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/print.c,v
retrieving revision 1.68
diff -c -c -r1.68 print.c
*** src/bin/psql/print.c 14 Jul 2005 15:54:21 -0000 1.68
--- src/bin/psql/print.c 14 Jul 2005 20:54:05 -0000
***************
*** 50,125 ****
}
static int
! num_numericseps(const char *my_str)
{
! int old_len, dec_len, int_len;
! int groupdigits = atoi(grouping);
if (my_str[0] == '-')
my_str++;
! old_len = strlen(my_str);
! dec_len = strchr(my_str, '.') ? strlen(strchr(my_str, '.')) : 0;
- int_len = old_len - dec_len;
if (int_len % groupdigits != 0)
! return int_len / groupdigits;
else
! return int_len / groupdigits - 1; /* no leading separator
*/
}
static int
len_with_numericsep(const char *my_str)
{
! return strlen(my_str) + num_numericseps(my_str);
}
static void
format_numericsep(char *my_str)
{
! int i, j, digits_before_sep, old_len, new_len, dec_len, int_len;
! char *new_str;
! char *dec_value;
int groupdigits = atoi(grouping);
if (my_str[0] == '-')
my_str++;
!
! old_len = strlen(my_str);
! dec_len = strchr(my_str, '.') ? strlen(strchr(my_str, '.')) : 0;
! int_len = old_len - dec_len;
! digits_before_sep = int_len % groupdigits;
!
! new_len = int_len + int_len / groupdigits + dec_len;
! if (digits_before_sep == 0)
! new_len--; /* no leading separator */
! new_str = pg_local_malloc(new_len + 1);
for (i=0, j=0; ; i++, j++)
{
! /* hit decimal point */
if (my_str[i] == '.')
{
! new_str[j] = *decimal_point;
! new_str[j+1] = '\0';
! dec_value = strchr(my_str, '.');
! strcat(new_str, ++dec_value);
break;
}
! /* end of string */
if (my_str[i] == '\0')
{
new_str[j] = '\0';
break;
}
! /* add separator? */
! if (i != 0 &&
! (i - (digits_before_sep ? digits_before_sep :
groupdigits))
! % groupdigits == 0)
! new_str[j++] = *thousands_sep;
new_str[j] = my_str[i];
}
--- 50,128 ----
}
static int
! integer_digits(const char *my_str)
{
! int frac_len;
if (my_str[0] == '-')
my_str++;
! frac_len = strchr(my_str, '.') ? strlen(strchr(my_str, '.')) : 0;
!
! return strlen(my_str) - frac_len;
! }
!
! static int
! len_numericseps(const char *my_str)
! {
! int int_len = integer_digits(my_str), sep_len;
! int groupdigits = atoi(grouping);
if (int_len % groupdigits != 0)
! sep_len = int_len / groupdigits;
else
! sep_len = int_len / groupdigits - 1; /* no leading separator
*/
!
! return sep_len * strlen(thousands_sep) -
! strlen(".") + strlen(decimal_point);
}
static int
len_with_numericsep(const char *my_str)
{
! return strlen(my_str) + len_numericseps(my_str);
}
static void
format_numericsep(char *my_str)
{
! int i, j, int_len = integer_digits(my_str), leading_digits;
int groupdigits = atoi(grouping);
+ char *new_str;
if (my_str[0] == '-')
my_str++;
!
! new_str = pg_local_malloc(len_numericseps(my_str) + 1);
! leading_digits = (int_len % groupdigits != 0) ?
! int_len % groupdigits : groupdigits;
for (i=0, j=0; ; i++, j++)
{
! /* Hit decimal point? */
if (my_str[i] == '.')
{
! strcpy(&new_str[j], decimal_point);
! j += strlen(decimal_point);
! /* add fractional part */
! strcpy(&new_str[j], &my_str[i] + 1);
break;
}
! /* End of string? */
if (my_str[i] == '\0')
{
new_str[j] = '\0';
break;
}
! /* Add separator? */
! if (i != 0 && (i - leading_digits) % groupdigits == 0)
! {
! strcpy(&new_str[j], thousands_sep);
! j += strlen(thousands_sep);
! }
new_str[j] = my_str[i];
}
***************
*** 396,402 ****
int numericseps;
if (opt_align[i % col_count] == 'r' && opt_numericsep)
! numericseps = num_numericseps(*ptr);
else
numericseps = 0;
--- 399,405 ----
int numericseps;
if (opt_align[i % col_count] == 'r' && opt_numericsep)
! numericseps = len_numericseps(*ptr);
else
numericseps = 0;
***************
*** 613,619 ****
int numericseps;
if (opt_align[i % col_count] == 'r' && opt_numericsep)
! numericseps = num_numericseps(*ptr);
else
numericseps = 0;
--- 616,622 ----
int numericseps;
if (opt_align[i % col_count] == 'r' && opt_numericsep)
! numericseps = len_numericseps(*ptr);
else
numericseps = 0;
***************
*** 1711,1717 ****
extlconv = localeconv();
- /* These are treated as single-byte strings in the code */
if (*extlconv->decimal_point)
decimal_point = strdup(extlconv->decimal_point);
else
--- 1714,1719 ----
---------------------------(end of broadcast)---------------------------
TIP 3: Have you checked our extensive FAQ?
http://www.postgresql.org/docs/faq