mirror of
https://github.com/Gnucash/gnucash.git
synced 2024-12-01 04:59:29 -06:00
2002-10-16 Joshua Sled <jsled@asynchronous.org>
* src/app-utils/gnc-exp-parser.c (gnc_exp_parser_parse): This function now fails correctly if there are un-bound variables in the expression. This causes expressions like 'AUD 1.23' to fail. This is related to, but not a fix for, Bug#95474. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7328 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
8fe4bf789c
commit
b4986ed2de
@ -1,3 +1,10 @@
|
||||
2002-10-16 Joshua Sled <jsled@asynchronous.org>
|
||||
|
||||
* src/app-utils/gnc-exp-parser.c (gnc_exp_parser_parse): This
|
||||
function now fails correctly if there are un-bound variables in
|
||||
the expression. This causes expressions like 'AUD 1.23' to fail.
|
||||
This is related to, but not a fix for, Bug#95474.
|
||||
|
||||
2002-10-16 Christian Stimming <stimming@tuhh.de>
|
||||
|
||||
* src/import-export/hbci/hbci-account-picker.c,
|
||||
|
@ -44,9 +44,10 @@ typedef struct ParserNum
|
||||
|
||||
|
||||
/** Static Globals *************************************************/
|
||||
static GHashTable *variable_bindings = NULL;
|
||||
static ParseError last_error = PARSER_NO_ERROR;
|
||||
static gboolean parser_inited = FALSE;
|
||||
static GHashTable *variable_bindings = NULL;
|
||||
static ParseError last_error = PARSER_NO_ERROR;
|
||||
static GNCParseError last_gncp_error = NO_ERR;
|
||||
static gboolean parser_inited = FALSE;
|
||||
|
||||
|
||||
/** Implementations ************************************************/
|
||||
@ -169,6 +170,7 @@ gnc_exp_parser_shutdown (void)
|
||||
variable_bindings = NULL;
|
||||
|
||||
last_error = PARSER_NO_ERROR;
|
||||
last_gncp_error = NO_ERR;
|
||||
|
||||
parser_inited = FALSE;
|
||||
}
|
||||
@ -470,12 +472,58 @@ negate_numeric(void *value)
|
||||
return result;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gnc_ep_tmpvarhash_check_vals( gpointer key, gpointer value, gpointer user_data )
|
||||
{
|
||||
gboolean *allVarsHaveValues = (gboolean*)user_data;
|
||||
gnc_numeric *num = (gnc_numeric*)value;
|
||||
printf( "var %s with value %s\n",
|
||||
(char*)key, num ? gnc_numeric_to_string( *num ) : "(null)" );
|
||||
*allVarsHaveValues &= ( num && gnc_numeric_check( *num ) != GNC_ERROR_ARG );
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gnc_ep_tmpvarhash_clean( gpointer key, gpointer value, gpointer user_data )
|
||||
{
|
||||
if ( key ) {
|
||||
g_free( (gchar*)key );
|
||||
}
|
||||
if ( value ) {
|
||||
g_free( (gnc_numeric*)value );
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
gnc_exp_parser_parse( const char * expression, gnc_numeric *value_p,
|
||||
char **error_loc_p )
|
||||
{
|
||||
return gnc_exp_parser_parse_separate_vars( expression, value_p,
|
||||
error_loc_p, NULL );
|
||||
GHashTable *tmpVarHash;
|
||||
gboolean ret, toRet = TRUE;
|
||||
gboolean allVarsHaveValues = TRUE;
|
||||
|
||||
tmpVarHash = g_hash_table_new( g_str_hash, g_str_equal );
|
||||
ret = gnc_exp_parser_parse_separate_vars( expression, value_p,
|
||||
error_loc_p, tmpVarHash );
|
||||
if ( !ret ) {
|
||||
toRet = ret;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
g_hash_table_foreach( tmpVarHash,
|
||||
gnc_ep_tmpvarhash_check_vals,
|
||||
&allVarsHaveValues );
|
||||
if ( !allVarsHaveValues ) {
|
||||
toRet = FALSE;
|
||||
last_gncp_error = VARIABLE_IN_EXP;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
g_hash_table_foreach( tmpVarHash, gnc_ep_tmpvarhash_clean, NULL );
|
||||
g_hash_table_destroy( tmpVarHash );
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -567,7 +615,8 @@ gnc_exp_parser_parse_separate_vars (const char * expression,
|
||||
}
|
||||
numericValue = g_new0( gnc_numeric, 1 );
|
||||
*numericValue = ((ParserNum*)newVars->value)->value;
|
||||
numericValue = NULL;
|
||||
// WTF?
|
||||
// numericValue = NULL;
|
||||
g_hash_table_insert( varHash,
|
||||
g_strdup(newVars->variable_name),
|
||||
numericValue );
|
||||
@ -586,6 +635,16 @@ gnc_exp_parser_parse_separate_vars (const char * expression,
|
||||
const char *
|
||||
gnc_exp_parser_error_string (void)
|
||||
{
|
||||
if ( last_error == PARSER_NO_ERROR ) {
|
||||
switch ( last_gncp_error ) {
|
||||
default:
|
||||
case NO_ERR:
|
||||
return NULL; break;
|
||||
case VARIABLE_IN_EXP:
|
||||
return _("Illegal variable in expression." ); break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (last_error)
|
||||
{
|
||||
default:
|
||||
|
@ -26,6 +26,15 @@
|
||||
|
||||
#include "gnc-numeric.h"
|
||||
|
||||
/**
|
||||
* The errors which can be determined at the gnc-exp-parser level.
|
||||
**/
|
||||
typedef enum {
|
||||
NO_ERR,
|
||||
VARIABLE_IN_EXP,
|
||||
NUM_ERRORS
|
||||
} GNCParseError;
|
||||
|
||||
/* Initialize the expression parser. If this function is not
|
||||
* called before one of the other parsing routines (other than
|
||||
* gnc_exp_parser_shutdown), it will be called if needed.
|
||||
@ -82,6 +91,7 @@ gboolean gnc_exp_parser_parse (const char * expression,
|
||||
* dealing with a non-shared variable list and state, local to the expression
|
||||
* being parsed. This is a hashTable of variable names mapping to
|
||||
* gnc_numeric pointers.
|
||||
*
|
||||
* @note It is the CALLER'S RESPONSIBILITY to g_free() both the keys and
|
||||
* values of varHash when done.
|
||||
**/
|
||||
|
@ -122,6 +122,8 @@ test_parser (void)
|
||||
add_fail_test ("whitespace", " \t\n", 4);
|
||||
add_fail_test ("bad expression", "\\", 0);
|
||||
add_fail_test ("bad expression", "1 +", 3);
|
||||
/* FIXME: This should be a failure test... */
|
||||
//add_fail_test ("bad expression", "1 2", 2);
|
||||
add_fail_test ("bad expression", " (5 + 23)/ ", 14);
|
||||
add_fail_test ("bad expression", " ((((5 + 23)/ ", 17);
|
||||
add_fail_test ("divide by zero", " 4 / (1 - 1)", -1);
|
||||
@ -133,7 +135,15 @@ test_parser (void)
|
||||
add_pass_test ("5 * 6", NULL, gnc_numeric_create (30, 1));
|
||||
add_pass_test (" 34 / (22) ", NULL, gnc_numeric_create (34, 22));
|
||||
add_pass_test (" (4 + 5 * 2) - 7 / 3", NULL, gnc_numeric_create (35, 3));
|
||||
add_pass_test ("1 + 2 * 3 + 4 + 5 * 6 * 7", NULL, gnc_numeric_create(221, 1) );
|
||||
add_pass_test( "(a = 42) + (b = 12) - a", NULL, gnc_numeric_create( 12, 1 ) );
|
||||
add_fail_test( "AUD $1.23", NULL, 0 );
|
||||
add_fail_test( "AUD $0.0", NULL, 0 );
|
||||
add_fail_test( "AUD 1.23", NULL, 0 );
|
||||
add_fail_test( "AUD 0.0", NULL, 0 );
|
||||
add_fail_test( "AUD 1.2 + CAN 2.3", NULL, 0 );
|
||||
add_fail_test( "AUD $1.2 + CAN $2.3", NULL, 0 );
|
||||
|
||||
add_pass_test( "1 + 2 * 3 + 4 + 5 * 6 * 7", NULL, gnc_numeric_create(221, 1) );
|
||||
add_pass_test( "1 - 2 * 3 + 4 - 5 * 6 * 7", NULL,
|
||||
gnc_numeric_create(-211, 1) );
|
||||
add_pass_test( "Conrad's bug",
|
||||
|
Loading…
Reference in New Issue
Block a user