|
3 | 3 | * |
4 | 4 | * Copyright (c) 2000-2005, PostgreSQL Global Development Group |
5 | 5 | * |
6 | | - * $PostgreSQL: pgsql/src/bin/psql/print.c,v 1.68 2005/07/14 15:54:21 momjian Exp $ |
| 6 | + * $PostgreSQL: pgsql/src/bin/psql/print.c,v 1.69 2005/07/14 21:12:41 momjian Exp $ |
7 | 7 | */ |
8 | 8 | #include "postgres_fe.h" |
9 | 9 | #include "common.h" |
@@ -50,76 +50,79 @@ pg_local_malloc(size_t size) |
50 | 50 | } |
51 | 51 |
|
52 | 52 | static int |
53 | | -num_numericseps(const char *my_str) |
| 53 | +integer_digits(const char *my_str) |
54 | 54 | { |
55 | | - int old_len, dec_len, int_len; |
56 | | - int groupdigits = atoi(grouping); |
| 55 | + int frac_len; |
57 | 56 |
|
58 | 57 | if (my_str[0] == '-') |
59 | 58 | my_str++; |
60 | 59 |
|
61 | | - old_len = strlen(my_str); |
62 | | - dec_len = strchr(my_str, '.') ? strlen(strchr(my_str, '.')) : 0; |
| 60 | + frac_len = strchr(my_str, '.') ? strlen(strchr(my_str, '.')) : 0; |
| 61 | + |
| 62 | + return strlen(my_str) - frac_len; |
| 63 | +} |
| 64 | + |
| 65 | +static int |
| 66 | +len_numericseps(const char *my_str) |
| 67 | +{ |
| 68 | + int int_len = integer_digits(my_str), sep_len; |
| 69 | + int groupdigits = atoi(grouping); |
63 | 70 |
|
64 | | - int_len = old_len - dec_len; |
65 | 71 | if (int_len % groupdigits != 0) |
66 | | - return int_len / groupdigits; |
| 72 | + sep_len = int_len / groupdigits; |
67 | 73 | else |
68 | | - return int_len / groupdigits - 1; /* no leading separator */ |
| 74 | + sep_len = int_len / groupdigits - 1; /* no leading separator */ |
| 75 | + |
| 76 | + return sep_len * strlen(thousands_sep) - |
| 77 | + strlen(".") + strlen(decimal_point); |
69 | 78 | } |
70 | 79 |
|
71 | 80 | static int |
72 | 81 | len_with_numericsep(const char *my_str) |
73 | 82 | { |
74 | | - return strlen(my_str) + num_numericseps(my_str); |
| 83 | + return strlen(my_str) + len_numericseps(my_str); |
75 | 84 | } |
76 | 85 |
|
77 | 86 | static void |
78 | 87 | format_numericsep(char *my_str) |
79 | 88 | { |
80 | | - int i, j, digits_before_sep, old_len, new_len, dec_len, int_len; |
81 | | - char *new_str; |
82 | | - char *dec_value; |
| 89 | + int i, j, int_len = integer_digits(my_str), leading_digits; |
83 | 90 | int groupdigits = atoi(grouping); |
| 91 | + char *new_str; |
84 | 92 |
|
85 | 93 | if (my_str[0] == '-') |
86 | 94 | my_str++; |
87 | | - |
88 | | - old_len = strlen(my_str); |
89 | | - dec_len = strchr(my_str, '.') ? strlen(strchr(my_str, '.')) : 0; |
90 | | - int_len = old_len - dec_len; |
91 | | - digits_before_sep = int_len % groupdigits; |
92 | | - |
93 | | - new_len = int_len + int_len / groupdigits + dec_len; |
94 | | - if (digits_before_sep == 0) |
95 | | - new_len--; /* no leading separator */ |
| 95 | + |
| 96 | + new_str = pg_local_malloc(len_numericseps(my_str) + 1); |
96 | 97 |
|
97 | | - new_str = pg_local_malloc(new_len + 1); |
| 98 | + leading_digits = (int_len % groupdigits != 0) ? |
| 99 | + int_len % groupdigits : groupdigits; |
98 | 100 |
|
99 | 101 | for (i=0, j=0; ; i++, j++) |
100 | 102 | { |
101 | | - /* hit decimal point */ |
| 103 | + /* Hit decimal point? */ |
102 | 104 | if (my_str[i] == '.') |
103 | 105 | { |
104 | | - new_str[j] = *decimal_point; |
105 | | - new_str[j+1] = '\0'; |
106 | | - dec_value = strchr(my_str, '.'); |
107 | | - strcat(new_str, ++dec_value); |
| 106 | + strcpy(&new_str[j], decimal_point); |
| 107 | + j += strlen(decimal_point); |
| 108 | + /* add fractional part */ |
| 109 | + strcpy(&new_str[j], &my_str[i] + 1); |
108 | 110 | break; |
109 | 111 | } |
110 | 112 |
|
111 | | - /* end of string */ |
| 113 | + /* End of string? */ |
112 | 114 | if (my_str[i] == '\0') |
113 | 115 | { |
114 | 116 | new_str[j] = '\0'; |
115 | 117 | break; |
116 | 118 | } |
117 | 119 |
|
118 | | - /* add separator? */ |
119 | | - if (i != 0 && |
120 | | - (i - (digits_before_sep ? digits_before_sep : groupdigits)) |
121 | | - % groupdigits == 0) |
122 | | - new_str[j++] = *thousands_sep; |
| 120 | + /* Add separator? */ |
| 121 | + if (i != 0 && (i - leading_digits) % groupdigits == 0) |
| 122 | + { |
| 123 | + strcpy(&new_str[j], thousands_sep); |
| 124 | + j += strlen(thousands_sep); |
| 125 | + } |
123 | 126 |
|
124 | 127 | new_str[j] = my_str[i]; |
125 | 128 | } |
@@ -396,7 +399,7 @@ print_aligned_text(const char *title, const char *const *headers, |
396 | 399 | int numericseps; |
397 | 400 |
|
398 | 401 | if (opt_align[i % col_count] == 'r' && opt_numericsep) |
399 | | - numericseps = num_numericseps(*ptr); |
| 402 | + numericseps = len_numericseps(*ptr); |
400 | 403 | else |
401 | 404 | numericseps = 0; |
402 | 405 |
|
@@ -613,7 +616,7 @@ print_aligned_vertical(const char *title, const char *const *headers, |
613 | 616 | int numericseps; |
614 | 617 |
|
615 | 618 | if (opt_align[i % col_count] == 'r' && opt_numericsep) |
616 | | - numericseps = num_numericseps(*ptr); |
| 619 | + numericseps = len_numericseps(*ptr); |
617 | 620 | else |
618 | 621 | numericseps = 0; |
619 | 622 |
|
@@ -1711,7 +1714,6 @@ setDecimalLocale(void) |
1711 | 1714 |
|
1712 | 1715 | extlconv = localeconv(); |
1713 | 1716 |
|
1714 | | - /* These are treated as single-byte strings in the code */ |
1715 | 1717 | if (*extlconv->decimal_point) |
1716 | 1718 | decimal_point = strdup(extlconv->decimal_point); |
1717 | 1719 | else |
|
0 commit comments