|
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