aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas G. Lockhart <lockhart@fourpalms.org>1998-03-02 00:13:36 +0000
committerThomas G. Lockhart <lockhart@fourpalms.org>1998-03-02 00:13:36 +0000
commit77ac40d73e7728bb2e2c5c108037d2573472ed3e (patch)
tree5fc1f8d674e3e53e7a0cb09afb5fede689e42b52 /src
parentbb63cb8f795975bd1d9c21ad17b84c6ca0bb017b (diff)
downloadpostgresql-77ac40d73e7728bb2e2c5c108037d2573472ed3e.tar.gz
postgresql-77ac40d73e7728bb2e2c5c108037d2573472ed3e.zip
Fix money type USE_LOCALE support at least for default "C" locale.
Still has questionable code for some locale-specific strings.
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/cash.c79
1 files changed, 53 insertions, 26 deletions
diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c
index e9e3a971b49..90f92bd24fa 100644
--- a/src/backend/utils/adt/cash.c
+++ b/src/backend/utils/adt/cash.c
@@ -9,7 +9,7 @@
* workings can be found in the book "Software Solutions in C" by
* Dale Schumacher, Academic Press, ISBN: 0-12-632360-7.
*
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/cash.c,v 1.22 1998/02/26 04:36:53 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/cash.c,v 1.23 1998/03/02 00:13:36 thomas Exp $
*/
#include <stdio.h>
@@ -34,7 +34,6 @@ static const char *num_word(Cash value);
#ifdef USE_LOCALE
static struct lconv *lconvert = NULL;
-
#endif
/* cash_in()
@@ -46,6 +45,8 @@ static struct lconv *lconvert = NULL;
* XXX HACK It looks as though some of the symbols for
* monetary values returned by localeconv() can be multiple
* bytes/characters. This code assumes one byte only. - tgl 97/04/14
+ * XXX UNHACK Allow the currency symbol to be multi-byte.
+ * - thomas 1998-03-01
*/
Cash *
cash_in(const char *str)
@@ -58,11 +59,11 @@ cash_in(const char *str)
int seen_dot = 0;
const char *s = str;
int fpoint;
+ char *csymbol;
char dsymbol,
ssymbol,
psymbol,
- nsymbol,
- csymbol;
+ *nsymbol;
#ifdef USE_LOCALE
#ifdef CASHDEBUG
@@ -76,33 +77,45 @@ cash_in(const char *str)
/* best guess is 2 in this case I think */
fpoint = ((lconvert->frac_digits != CHAR_MAX) ? lconvert->frac_digits : 2); /* int_frac_digits? */
- dsymbol = *lconvert->mon_decimal_point;
- ssymbol = *lconvert->mon_thousands_sep;
- csymbol = *lconvert->currency_symbol;
- psymbol = *lconvert->positive_sign;
- nsymbol = *lconvert->negative_sign;
+ dsymbol = ((*lconvert->mon_decimal_point != '\0')? *lconvert->mon_decimal_point: '.');
+ ssymbol = ((*lconvert->mon_thousands_sep != '\0')? *lconvert->mon_thousands_sep: ',');
+ csymbol = ((*lconvert->currency_symbol != '\0')? lconvert->currency_symbol: "$");
+ psymbol = ((*lconvert->positive_sign != '\0')? *lconvert->positive_sign: '+');
+ nsymbol = ((*lconvert->negative_sign != '\0')? lconvert->negative_sign: "-");
#else
fpoint = 2;
dsymbol = '.';
ssymbol = ',';
- csymbol = '$';
+ csymbol = "$";
psymbol = '+';
- nsymbol = '-';
+ nsymbol = "-";
#endif
#ifdef CASHDEBUG
- printf("cashin- precision %d; decimal %c; thousands %c; currency %c; positive %c; negative %c\n",
- fpoint, dsymbol, ssymbol, csymbol, psymbol, nsymbol);
+printf( "cashin- precision '%d'; decimal '%c'; thousands '%c'; currency '%s'; positive '%c'; negative '%s'\n",
+ fpoint, dsymbol, ssymbol, csymbol, psymbol, nsymbol);
#endif
/* we need to add all sorts of checking here. For now just */
- /* strip all leading whitespace and any leading dollar sign */
- while (isspace(*s) || *s == csymbol)
- s++;
+ /* strip all leading whitespace and any leading currency symbol */
+ while (isspace(*s)) s++;
+ if (strncmp(s,csymbol,strlen(csymbol)) == 0) s += strlen(csymbol);
+
+#ifdef CASHDEBUG
+printf( "cashin- string is '%s'\n", s);
+#endif
/* a leading minus or paren signifies a negative number */
/* again, better heuristics needed */
- if (*s == nsymbol || *s == '(')
+ if (strncmp(s,nsymbol,strlen(nsymbol)) == 0)
+ {
+ sgn = -1;
+ s += strlen(nsymbol);
+#ifdef CASHDEBUG
+printf( "cashin- negative symbol; string is '%s'\n", s);
+#endif
+ }
+ else if (*s == '(')
{
sgn = -1;
s++;
@@ -113,8 +126,16 @@ cash_in(const char *str)
s++;
}
- while (isspace(*s) || *s == csymbol)
- s++;
+#ifdef CASHDEBUG
+printf( "cashin- string is '%s'\n", s);
+#endif
+
+ while (isspace(*s)) s++;
+ if (strncmp(s,csymbol,strlen(csymbol)) == 0) s += strlen(csymbol);
+
+#ifdef CASHDEBUG
+printf( "cashin- string is '%s'\n", s);
+#endif
for (;; s++)
{
@@ -164,6 +185,10 @@ cash_in(const char *str)
*result = (value * sgn);
+#ifdef CASHDEBUG
+printf( "cashin- result is %d\n", *result);
+#endif
+
return (result);
} /* cash_in() */
@@ -186,7 +211,7 @@ cash_out(Cash *in_value)
char mon_group,
comma,
points;
- char csymbol,
+ char *csymbol,
dsymbol,
*nsymbol;
char convention;
@@ -196,18 +221,18 @@ cash_out(Cash *in_value)
lconvert = localeconv();
mon_group = *lconvert->mon_grouping;
- comma = *lconvert->mon_thousands_sep;
- csymbol = *lconvert->currency_symbol;
- dsymbol = *lconvert->mon_decimal_point;
- nsymbol = lconvert->negative_sign;
+ comma = ((*lconvert->mon_thousands_sep != '\0')? *lconvert->mon_thousands_sep: ',');
/* frac_digits in the C locale seems to return CHAR_MAX */
/* best guess is 2 in this case I think */
points = ((lconvert->frac_digits != CHAR_MAX) ? lconvert->frac_digits : 2); /* int_frac_digits? */
convention = lconvert->n_sign_posn;
+ dsymbol = ((*lconvert->mon_decimal_point != '\0')? *lconvert->mon_decimal_point: '.');
+ csymbol = ((*lconvert->currency_symbol != '\0')? lconvert->currency_symbol: "$");
+ nsymbol = ((*lconvert->negative_sign != '\0')? lconvert->negative_sign: "-");
#else
mon_group = 3;
comma = ',';
- csymbol = '$';
+ csymbol = "$";
dsymbol = '.';
nsymbol = "-";
points = 2;
@@ -217,6 +242,7 @@ cash_out(Cash *in_value)
point_pos = LAST_DIGIT - points;
/* We're playing a little fast and loose with this. Shoot me. */
+ /* Not me, that was the other guy. Haven't fixed it yet - thomas */
if (!mon_group || mon_group == CHAR_MAX)
mon_group = 3;
@@ -249,7 +275,8 @@ cash_out(Cash *in_value)
value /= 10;
}
- buf[count] = csymbol;
+ strncpy((buf+count-strlen(csymbol)+1),csymbol,strlen(csymbol));
+ count -= strlen(csymbol)-1;
if (buf[LAST_DIGIT] == ',')
buf[LAST_DIGIT] = buf[LAST_PAREN];