Fix money type USE_LOCALE support at least for default "C" locale.
Still has questionable code for some locale-specific strings.
This commit is contained in:
parent
bb63cb8f79
commit
77ac40d73e
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue