static void gnc_template_register_save_debcred_cell (BasicCell * cell, gpointer save_data, gpointer user_data) { SRSaveData *sd = save_data; SplitRegister *reg = user_data; const char *credit_formula, *debit_formula; char *error_loc; gnc_numeric credit_amount, debit_amount; gboolean parse_result; g_return_if_fail (gnc_basic_cell_has_name (cell, FDEBT_CELL) || gnc_basic_cell_has_name (cell, FCRED_CELL)); if (sd->handled_dc) return; /* amountStr = gnc_numeric_to_string (new_amount); */ credit_formula = gnc_table_layout_get_cell_value (reg->table->layout, FCRED_CELL); /* If the value can be parsed into a numeric result (without any * further variable definitions), store that numeric value * additionally in the kvp. Otherwise store a zero numeric * there.*/ parse_result = gnc_exp_parser_parse_separate_vars(credit_formula, &credit_amount, &error_loc, NULL); if (!parse_result) credit_amount = gnc_numeric_zero(); debit_formula = gnc_table_layout_get_cell_value (reg->table->layout, FDEBT_CELL); /* If the value can be parsed into a numeric result, store that * numeric value additionally. See above comment.*/ parse_result = gnc_exp_parser_parse_separate_vars(debit_formula, &debit_amount, &error_loc, NULL); if (!parse_result) debit_amount = gnc_numeric_zero(); qof_instance_set (QOF_INSTANCE (sd->split), "sx-credit-formula", credit_formula, "sx-credit-numeric", &credit_amount, "sx-debit-formula", debit_formula, "sx-debit-numeric", &debit_amount, NULL); /* set the amount to an innocuous value */ /* Note that this marks the split dirty */ xaccSplitSetValue (sd->split, gnc_numeric_create (0, 1)); sd->handled_dc = TRUE; }
int gnc_sx_parse_vars_from_formula(const char *formula, GHashTable *var_hash, gnc_numeric *result) { gnc_numeric num; char *errLoc = NULL; int toRet = 0; GHashTable *parser_vars; // convert var_hash -> variables for the parser. parser_vars = gnc_sx_instance_get_variables_for_parser(var_hash); num = gnc_numeric_zero(); if (!gnc_exp_parser_parse_separate_vars(formula, &num, &errLoc, parser_vars)) { toRet = -1; } // convert back. g_hash_table_foreach(parser_vars, (GHFunc)_var_numeric_to_sx_var, var_hash); g_hash_table_destroy(parser_vars); if (result != NULL) { *result = num; } return toRet; }
gboolean gnc_exp_parser_parse( const char * expression, gnc_numeric *value_p, char **error_loc_p ) { 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; }
static void _get_sx_formula_value(GncSxInstance *instance, Split *template_split, gnc_numeric *numeric, GList **creation_errors, const char *formula_key) { kvp_frame *split_kvpf; kvp_value *kvp_val; char *formula_str, *parseErrorLoc; split_kvpf = xaccSplitGetSlots(template_split); kvp_val = kvp_frame_get_slot_path(split_kvpf, GNC_SX_ID, formula_key, NULL); formula_str = kvp_value_get_string(kvp_val); if (formula_str != NULL && strlen(formula_str) != 0) { GHashTable *parser_vars = gnc_sx_instance_get_variables_for_parser(instance->variable_bindings); if (!gnc_exp_parser_parse_separate_vars(formula_str, numeric, &parseErrorLoc, parser_vars)) { GString *err = g_string_new(""); g_string_printf(err, "Error parsing SX [%s] key [%s]=formula [%s] at [%s]: %s", xaccSchedXactionGetName(instance->parent->sx), formula_key, formula_str, parseErrorLoc, gnc_exp_parser_error_string()); g_critical("%s", err->str); if (creation_errors != NULL) *creation_errors = g_list_append(*creation_errors, err); else g_string_free(err, TRUE); } if (parser_vars != NULL) { g_hash_table_destroy(parser_vars); } } }
static void gnc_template_register_save_debcred_cell (BasicCell * cell, gpointer save_data, gpointer user_data) { SRSaveData *sd = save_data; SplitRegister *reg = user_data; kvp_frame *kvpf; const char *value; char *error_loc; gnc_numeric new_amount; gboolean parse_result; g_return_if_fail (gnc_basic_cell_has_name (cell, FDEBT_CELL) || gnc_basic_cell_has_name (cell, FCRED_CELL)); if (sd->handled_dc) return; kvpf = xaccSplitGetSlots (sd->split); DEBUG ("kvp_frame before: %s\n", kvp_frame_to_string (kvpf)); /* amountStr = gnc_numeric_to_string (new_amount); */ value = gnc_table_layout_get_cell_value (reg->table->layout, FCRED_CELL); kvp_frame_set_slot_path (kvpf, kvp_value_new_string (value), GNC_SX_ID, GNC_SX_CREDIT_FORMULA, NULL); /* If the value can be parsed into a numeric result (without any * further variable definitions), store that numeric value * additionally in the kvp. Otherwise store a zero numeric * there.*/ parse_result = gnc_exp_parser_parse_separate_vars(value, &new_amount, &error_loc, NULL); if (!parse_result) { new_amount = gnc_numeric_zero(); } kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_amount), GNC_SX_ID, GNC_SX_CREDIT_NUMERIC, NULL); value = gnc_table_layout_get_cell_value (reg->table->layout, FDEBT_CELL); kvp_frame_set_slot_path (kvpf, kvp_value_new_string (value), GNC_SX_ID, GNC_SX_DEBIT_FORMULA, NULL); /* If the value can be parsed into a numeric result, store that * numeric value additionally. See above comment.*/ parse_result = gnc_exp_parser_parse_separate_vars(value, &new_amount, &error_loc, NULL); if (!parse_result) { new_amount = gnc_numeric_zero(); } kvp_frame_set_slot_path (kvpf, kvp_value_new_numeric (new_amount), GNC_SX_ID, GNC_SX_DEBIT_NUMERIC, NULL); DEBUG ("kvp_frame after: %s\n", kvp_frame_to_string (kvpf)); /* set the amount to an innocuous value */ /* Note that this marks the split dirty */ xaccSplitSetValue (sd->split, gnc_numeric_create (0, 1)); sd->handled_dc = TRUE; }