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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}