mirror of
https://github.com/postgres/postgres.git
synced 2025-06-25 01:02:05 +03:00
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:
@ -9,7 +9,7 @@
|
|||||||
* workings can be found in the book "Software Solutions in C" by
|
* workings can be found in the book "Software Solutions in C" by
|
||||||
* Dale Schumacher, Academic Press, ISBN: 0-12-632360-7.
|
* 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>
|
#include <stdio.h>
|
||||||
@ -34,7 +34,6 @@ static const char *num_word(Cash value);
|
|||||||
|
|
||||||
#ifdef USE_LOCALE
|
#ifdef USE_LOCALE
|
||||||
static struct lconv *lconvert = NULL;
|
static struct lconv *lconvert = NULL;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* cash_in()
|
/* cash_in()
|
||||||
@ -46,6 +45,8 @@ static struct lconv *lconvert = NULL;
|
|||||||
* XXX HACK It looks as though some of the symbols for
|
* XXX HACK It looks as though some of the symbols for
|
||||||
* monetary values returned by localeconv() can be multiple
|
* monetary values returned by localeconv() can be multiple
|
||||||
* bytes/characters. This code assumes one byte only. - tgl 97/04/14
|
* 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 *
|
||||||
cash_in(const char *str)
|
cash_in(const char *str)
|
||||||
@ -58,11 +59,11 @@ cash_in(const char *str)
|
|||||||
int seen_dot = 0;
|
int seen_dot = 0;
|
||||||
const char *s = str;
|
const char *s = str;
|
||||||
int fpoint;
|
int fpoint;
|
||||||
|
char *csymbol;
|
||||||
char dsymbol,
|
char dsymbol,
|
||||||
ssymbol,
|
ssymbol,
|
||||||
psymbol,
|
psymbol,
|
||||||
nsymbol,
|
*nsymbol;
|
||||||
csymbol;
|
|
||||||
|
|
||||||
#ifdef USE_LOCALE
|
#ifdef USE_LOCALE
|
||||||
#ifdef CASHDEBUG
|
#ifdef CASHDEBUG
|
||||||
@ -76,33 +77,45 @@ cash_in(const char *str)
|
|||||||
/* best guess is 2 in this case I think */
|
/* best guess is 2 in this case I think */
|
||||||
fpoint = ((lconvert->frac_digits != CHAR_MAX) ? lconvert->frac_digits : 2); /* int_frac_digits? */
|
fpoint = ((lconvert->frac_digits != CHAR_MAX) ? lconvert->frac_digits : 2); /* int_frac_digits? */
|
||||||
|
|
||||||
dsymbol = *lconvert->mon_decimal_point;
|
dsymbol = ((*lconvert->mon_decimal_point != '\0')? *lconvert->mon_decimal_point: '.');
|
||||||
ssymbol = *lconvert->mon_thousands_sep;
|
ssymbol = ((*lconvert->mon_thousands_sep != '\0')? *lconvert->mon_thousands_sep: ',');
|
||||||
csymbol = *lconvert->currency_symbol;
|
csymbol = ((*lconvert->currency_symbol != '\0')? lconvert->currency_symbol: "$");
|
||||||
psymbol = *lconvert->positive_sign;
|
psymbol = ((*lconvert->positive_sign != '\0')? *lconvert->positive_sign: '+');
|
||||||
nsymbol = *lconvert->negative_sign;
|
nsymbol = ((*lconvert->negative_sign != '\0')? lconvert->negative_sign: "-");
|
||||||
#else
|
#else
|
||||||
fpoint = 2;
|
fpoint = 2;
|
||||||
dsymbol = '.';
|
dsymbol = '.';
|
||||||
ssymbol = ',';
|
ssymbol = ',';
|
||||||
csymbol = '$';
|
csymbol = "$";
|
||||||
psymbol = '+';
|
psymbol = '+';
|
||||||
nsymbol = '-';
|
nsymbol = "-";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CASHDEBUG
|
#ifdef CASHDEBUG
|
||||||
printf("cashin- precision %d; decimal %c; thousands %c; currency %c; positive %c; negative %c\n",
|
printf( "cashin- precision '%d'; decimal '%c'; thousands '%c'; currency '%s'; positive '%c'; negative '%s'\n",
|
||||||
fpoint, dsymbol, ssymbol, csymbol, psymbol, nsymbol);
|
fpoint, dsymbol, ssymbol, csymbol, psymbol, nsymbol);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* we need to add all sorts of checking here. For now just */
|
/* we need to add all sorts of checking here. For now just */
|
||||||
/* strip all leading whitespace and any leading dollar sign */
|
/* strip all leading whitespace and any leading currency symbol */
|
||||||
while (isspace(*s) || *s == csymbol)
|
while (isspace(*s)) 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 */
|
/* a leading minus or paren signifies a negative number */
|
||||||
/* again, better heuristics needed */
|
/* 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;
|
sgn = -1;
|
||||||
s++;
|
s++;
|
||||||
@ -113,8 +126,16 @@ cash_in(const char *str)
|
|||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (isspace(*s) || *s == csymbol)
|
#ifdef CASHDEBUG
|
||||||
s++;
|
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++)
|
for (;; s++)
|
||||||
{
|
{
|
||||||
@ -164,6 +185,10 @@ cash_in(const char *str)
|
|||||||
|
|
||||||
*result = (value * sgn);
|
*result = (value * sgn);
|
||||||
|
|
||||||
|
#ifdef CASHDEBUG
|
||||||
|
printf( "cashin- result is %d\n", *result);
|
||||||
|
#endif
|
||||||
|
|
||||||
return (result);
|
return (result);
|
||||||
} /* cash_in() */
|
} /* cash_in() */
|
||||||
|
|
||||||
@ -186,7 +211,7 @@ cash_out(Cash *in_value)
|
|||||||
char mon_group,
|
char mon_group,
|
||||||
comma,
|
comma,
|
||||||
points;
|
points;
|
||||||
char csymbol,
|
char *csymbol,
|
||||||
dsymbol,
|
dsymbol,
|
||||||
*nsymbol;
|
*nsymbol;
|
||||||
char convention;
|
char convention;
|
||||||
@ -196,18 +221,18 @@ cash_out(Cash *in_value)
|
|||||||
lconvert = localeconv();
|
lconvert = localeconv();
|
||||||
|
|
||||||
mon_group = *lconvert->mon_grouping;
|
mon_group = *lconvert->mon_grouping;
|
||||||
comma = *lconvert->mon_thousands_sep;
|
comma = ((*lconvert->mon_thousands_sep != '\0')? *lconvert->mon_thousands_sep: ',');
|
||||||
csymbol = *lconvert->currency_symbol;
|
|
||||||
dsymbol = *lconvert->mon_decimal_point;
|
|
||||||
nsymbol = lconvert->negative_sign;
|
|
||||||
/* frac_digits in the C locale seems to return CHAR_MAX */
|
/* frac_digits in the C locale seems to return CHAR_MAX */
|
||||||
/* best guess is 2 in this case I think */
|
/* best guess is 2 in this case I think */
|
||||||
points = ((lconvert->frac_digits != CHAR_MAX) ? lconvert->frac_digits : 2); /* int_frac_digits? */
|
points = ((lconvert->frac_digits != CHAR_MAX) ? lconvert->frac_digits : 2); /* int_frac_digits? */
|
||||||
convention = lconvert->n_sign_posn;
|
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
|
#else
|
||||||
mon_group = 3;
|
mon_group = 3;
|
||||||
comma = ',';
|
comma = ',';
|
||||||
csymbol = '$';
|
csymbol = "$";
|
||||||
dsymbol = '.';
|
dsymbol = '.';
|
||||||
nsymbol = "-";
|
nsymbol = "-";
|
||||||
points = 2;
|
points = 2;
|
||||||
@ -217,6 +242,7 @@ cash_out(Cash *in_value)
|
|||||||
point_pos = LAST_DIGIT - points;
|
point_pos = LAST_DIGIT - points;
|
||||||
|
|
||||||
/* We're playing a little fast and loose with this. Shoot me. */
|
/* 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)
|
if (!mon_group || mon_group == CHAR_MAX)
|
||||||
mon_group = 3;
|
mon_group = 3;
|
||||||
|
|
||||||
@ -249,7 +275,8 @@ cash_out(Cash *in_value)
|
|||||||
value /= 10;
|
value /= 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[count] = csymbol;
|
strncpy((buf+count-strlen(csymbol)+1),csymbol,strlen(csymbol));
|
||||||
|
count -= strlen(csymbol)-1;
|
||||||
|
|
||||||
if (buf[LAST_DIGIT] == ',')
|
if (buf[LAST_DIGIT] == ',')
|
||||||
buf[LAST_DIGIT] = buf[LAST_PAREN];
|
buf[LAST_DIGIT] = buf[LAST_PAREN];
|
||||||
|
Reference in New Issue
Block a user