Bug 796919 - Leading '+' character not accepted in amount when value surrounded by quotes

Use a variant of xaccParseAmount that allows to ignore the locale's positive_sign character
or the + sign if locale doesn't define a positive_sign character.

In a future redesign it would probably be better to replace use
of xaccParseAmount with some variant of the gnc-expression-parser
but that would require more that a few tweaks to get right.
This commit is contained in:
Geert Janssens 2018-11-18 17:23:14 +01:00
parent f13d21b973
commit cd04e805e3
4 changed files with 35 additions and 3 deletions

View File

@ -72,7 +72,7 @@ GncNumeric parse_amount_price (const std::string &str, int currency_format)
{
case 0:
/* Currency locale */
if (!(xaccParseAmount (str_no_symbols.c_str(), TRUE, &val, &endptr)))
if (!(xaccParseAmountPosSign (str_no_symbols.c_str(), TRUE, &val, &endptr, TRUE)))
throw std::invalid_argument (_("Value can't be parsed into a number using the selected currency format."));
break;
case 1:

View File

@ -120,7 +120,7 @@ GncNumeric parse_amount (const std::string &str, int currency_format)
{
case 0:
/* Currency locale */
if (!(xaccParseAmount (str_no_symbols.c_str(), TRUE, &val, &endptr)))
if (!(xaccParseAmountPosSign (str_no_symbols.c_str(), TRUE, &val, &endptr, TRUE)))
throw std::invalid_argument (_("Value can't be parsed into a number using the selected currency format."));
break;
case 1:

View File

@ -1985,12 +1985,21 @@ multiplier (int num_decimals)
gboolean
xaccParseAmount (const char * in_str, gboolean monetary, gnc_numeric *result,
char **endstr)
{
return xaccParseAmountPosSign (in_str, monetary, result, endstr, FALSE);
}
gboolean
xaccParseAmountPosSign (const char * in_str, gboolean monetary, gnc_numeric *result,
char **endstr, gboolean skip)
{
struct lconv *lc = gnc_localeconv();
gunichar negative_sign;
gunichar decimal_point;
gunichar group_separator;
gchar *ignore = NULL;
char *plus_sign = "+";
char *group;
negative_sign = g_utf8_get_char(lc->negative_sign);
@ -2007,8 +2016,18 @@ xaccParseAmount (const char * in_str, gboolean monetary, gnc_numeric *result,
group = lc->grouping;
}
if (skip)
{
/* We want the locale's positive sign to be ignored.
* If the locale doesn't specify one, we assume "+" as
* an optional positive sign and ignore that */
ignore = lc->positive_sign;
if (!ignore || !*ignore)
ignore = plus_sign;
}
return xaccParseAmountExtended(in_str, monetary, negative_sign, decimal_point,
group_separator, group, NULL, result, endstr);
group_separator, group, ignore, result, endstr);
}
/* Note: xaccParseAmountExtended causes test-print-parse-amount

View File

@ -321,6 +321,19 @@ gchar *numeric_to_words(gnc_numeric val);
gboolean xaccParseAmount (const char * in_str, gboolean monetary,
gnc_numeric *result, char **endstr);
/*
* xaccParseAmountPosSign is just like xaccParseAmount except the
* caller can choose whether the locale's postive sign (or in absense
* the '+') character is ignored. Setting skip to TRUE will cause
* the function to ignore any positive sign. Setting it to FALSE,
* and positive signs will be treated as unrecognized characters.
* xaccParseAmount will run as if skip is FALSE for compatibility
* reasons (gnc-expression-parser depends on this behaviour).
*/
gboolean
xaccParseAmountPosSign (const char * in_str, gboolean monetary, gnc_numeric *result,
char **endstr, gboolean skip);
/*
* xaccParseAmountExtended is just like xaccParseAmount except the
* caller must provide all the locale-specific information.