Clean up expression parser and calculation code.

Add in extra error handling for expression parser.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@2829 57a11ea4-9604-0410-9ed3-97b8803252fd
zzzoldreleases/1.6
Dave Peticolas 26 years ago
parent 9d82f29a95
commit 58e0f71949

File diff suppressed because it is too large Load Diff

@ -475,7 +475,7 @@ int main(int argc, char **argv, char **env)
stdout);
break;
case 'v':
for ( value_list = get_vars(parse_env) ; value_list ; value_list = value_list->next_var ) {
for ( value_list = parser_get_vars(parse_env) ; value_list ; value_list = value_list->next_var ) {
printf("%s: ",value_list->variable_name);
nval = (numeric_ptr)(value_list->value);
switch ( nval->type ) {

File diff suppressed because it is too large Load Diff

@ -27,116 +27,101 @@
#include "finvar.h"
/*==================================================*/
/* fin.c
*/
/* Line Number: 1209 */
unsigned fi_calc_num_payments(
fi_ptr fi);
/* Line Number: 1221 */
double _fi_calc_num_payments(
double nint, /* nominal interest rate */
double pv, /* present value */
double pmt, /* periodic payment */
double fv, /* future value */
unsigned CF, /* compounding frequency */
unsigned PF, /* payment frequency */
unsigned disc, /* discrete/continuous compounding flag */
unsigned bep); /* beginning/end of period payment flag */
/* Line Number: 1240 */
double fi_calc_interest(
fi_ptr fi);
/* Line Number: 1257 */
double _fi_calc_interest(
unsigned per, /* number of periods */
double pv, /* present value */
double pmt, /* periodic payment */
double fv, /* future value */
unsigned CF, /* compounding frequency */
unsigned PF, /* payment frequency */
unsigned disc, /* discrete/continuous compounding flag */
unsigned bep); /* beginning/end of period payment flag */
/* Line Number: 1300 */
double fi_calc_present_value(
fi_ptr fi);
/* Line Number: 1312 */
double _fi_calc_present_value(
unsigned per, /* number of periods */
double nint, /* nominal interest rate */
double pmt, /* periodic payment */
double fv, /* future value */
unsigned CF, /* compounding frequency */
unsigned PF, /* payment frequency */
unsigned disc, /* discrete/continuous compounding flag */
unsigned bep); /* beginning/end of period payment flag */
/* Line Number: 1332 */
double fi_calc_payment(
fi_ptr fi);
/* Line Number: 1344 */
double _fi_calc_payment(
unsigned per, /* number of periods */
double nint, /* nominal interest rate */
double pv, /* present value */
double fv, /* future value */
unsigned CF, /* compounding frequency */
unsigned PF, /* payment frequency */
unsigned disc, /* discrete/continuous compounding flag */
unsigned bep); /* beginning/end of period payment flag */
/* Line Number: 1363 */
double fi_calc_future_value(
fi_ptr fi);
/* Line Number: 1375 */
double _fi_calc_future_value(
unsigned per, /* number of periods */
double nint, /* nominal interest rate */
double pv, /* present value */
double pmt, /* periodic payment */
unsigned CF, /* compounding frequency */
unsigned PF, /* payment frequency */
unsigned disc, /* discrete/continuous compounding flag */
unsigned bep); /* beginning/end of period payment flag */
/* Line Number: 1464 */
void set_default(
fi_ptr fi);
/* Line Number: 1511 */
unsigned long julian_day_number(
unsigned year,
unsigned month,
unsigned day);
/* Line Number: 1533 */
amort_sched_ptr Amortization_init(
amort_sched_ptr amortsched);
/* Line Number: 1664 */
amort_sched_ptr Amortization_Schedule(
amort_sched_ptr amortsched);
/* Line Number: 2336 */
void Amortization_free(
amort_sched_ptr amortsched);
/* fin.c */
unsigned fi_calc_num_payments (fi_ptr fi);
double
_fi_calc_num_payments (double nint, /* nominal interest rate */
double pv, /* present value */
double pmt, /* periodic payment */
double fv, /* future value */
unsigned CF, /* compounding frequency */
unsigned PF, /* payment frequency */
unsigned disc, /* discrete/continuous compounding */
unsigned bep); /* beginning/end of period payment */
double fi_calc_interest (fi_ptr fi);
double
_fi_calc_interest (unsigned per, /* number of periods */
double pv, /* present value */
double pmt, /* periodic payment */
double fv, /* future value */
unsigned CF, /* compounding frequency */
unsigned PF, /* payment frequency */
unsigned disc, /* discrete/continuous compounding */
unsigned bep); /* beginning/end of period payment */
double fi_calc_present_value (fi_ptr fi);
double
_fi_calc_present_value (unsigned per, /* number of periods */
double nint, /* nominal interest rate */
double pmt, /* periodic payment */
double fv, /* future value */
unsigned CF, /* compounding frequency */
unsigned PF, /* payment frequency */
unsigned disc, /* discrete/continuous compounding */
unsigned bep); /* beginning/end of period payment */
double fi_calc_payment (fi_ptr fi);
double
_fi_calc_payment (unsigned per, /* number of periods */
double nint, /* nominal interest rate */
double pv, /* present value */
double fv, /* future value */
unsigned CF, /* compounding frequency */
unsigned PF, /* payment frequency */
unsigned disc, /* discrete/continuous compounding */
unsigned bep); /* beginning/end of period payment */
double fi_calc_future_value (fi_ptr fi);
double
_fi_calc_future_value (unsigned per, /* number of periods */
double nint, /* nominal interest rate */
double pv, /* present value */
double pmt, /* periodic payment */
unsigned CF, /* compounding frequency */
unsigned PF, /* payment frequency */
unsigned disc, /* discrete/continuous compounding */
unsigned bep); /* beginning/end of period payment */
void set_default (fi_ptr fi);
unsigned long julian_day_number (unsigned year, unsigned month, unsigned day);
amort_sched_ptr Amortization_init (amort_sched_ptr amortsched);
amort_sched_ptr Amortization_Schedule (amort_sched_ptr amortsched);
void Amortization_free (amort_sched_ptr amortsched);
/*==================================================*/
/* expression_parser.c */
/* Line Number: 377 */
void exit_parser(parser_env_ptr pe);
/* Line Number: 400 */
ParseError get_parse_error(parser_env_ptr pe);
/* Line Number: 408 */
var_store_ptr parser_get_vars(parser_env_ptr pe);
/* Line Number: 417 */
unsigned delete_var(char *var_name,
parser_env_ptr pe);
/* Line Number: 451 */
char *parse_string(var_store_ptr value,
const char *string,
parser_env_ptr pe);
void exit_parser (parser_env_ptr pe);
ParseError get_parse_error (parser_env_ptr pe);
var_store_ptr parser_get_vars (parser_env_ptr pe);
unsigned delete_var (char *var_name, parser_env_ptr pe);
char *parse_string (var_store_ptr value,
const char *string, parser_env_ptr pe);
/*==================================================*/
/* amort_opt.c */
amort_sched_ptr amort_opt(amort_sched_ptr amortsched,
void *parse_env);
amort_sched_ptr amort_opt (amort_sched_ptr amortsched, void *parse_env);
/*==================================================*/
/* amort_prt.c */
void prt_amortization_schedule (amort_sched_ptr amortsched, /* amortization schedule to print */
FILE *ofile); /* output file */
void prt_amortization_schedule (amort_sched_ptr amortsched, FILE * ofile);
#endif

@ -45,8 +45,10 @@ typedef enum
STACK_UNDERFLOW,
UNDEFINED_CHARACTER,
NOT_A_VARIABLE,
PARSER_OUT_OF_MEMORY,
PARSER_NUM_ERRORS
} ParseError;
}
ParseError;
#define UNUSED_VAR '\x000'
#define USED_VAR '\x001'
@ -65,13 +67,15 @@ typedef enum
*/
typedef struct var_store *var_store_ptr;
typedef struct var_store {
char *variable_name; /* variable name if variable, NULL otherwise */
char use_flag; /* flag if variable has been assigned to */
char assign_flag; /* flag if variable is used */
void *value; /* pointer to imp[lementation defined numeric value */
typedef struct var_store
{
char *variable_name; /* variable name if variable, NULL otherwise */
char use_flag; /* flag if variable has been assigned to */
char assign_flag; /* flag if variable is used */
void *value; /* pointer to implementation defined numeric value */
var_store_ptr next_var; /* pointer to next variable in linked list */
} var_store;
}
var_store;
/* The following structure is used for the numeric operations
@ -80,13 +84,17 @@ typedef struct var_store {
/* structure used for storing numeric values - used by routines which
* evaluate arithmetic operators '+', '-', '/', '*' */
typedef struct numeric *numeric_ptr;
typedef struct numeric {
char type; /* designates type of value */
union {
long int int_value; /* long integer value */
double dbl_value; /* double value */
} value;
} numeric;
typedef struct numeric
{
char type; /* designates type of value */
union
{
long int int_value; /* long integer value */
double dbl_value; /* double value */
}
value;
}
numeric;
/* The following structures are used by the amortization functions for
* storing amortization schedule information */
@ -94,131 +102,142 @@ typedef struct numeric {
/* structure used by amortization routines for storing annual summary
information */
typedef struct yearly_summary *yearly_summary_ptr;
typedef struct yearly_summary {
unsigned year;
double interest;
double end_balance;
}yearly_summary;
typedef struct yearly_summary
{
unsigned year;
double interest;
double end_balance;
}
yearly_summary;
/* structure used by amortization routines for storing information on
a single payment */
typedef struct sched_pmt *sched_pmt_ptr;
typedef struct sched_pmt {
unsigned period_num;
double interest;
double principal;
double advanced_pmt;
double total_pmt;
double balance;
} sched_pmt;
typedef struct sched_pmt
{
unsigned period_num;
double interest;
double principal;
double advanced_pmt;
double total_pmt;
double balance;
}
sched_pmt;
/* structure used by amortization routines for storing information on
* payments for a single year */
typedef struct amort_sched_yr *amort_sched_yr_ptr;
typedef struct amort_sched_yr {
unsigned year;
unsigned num_periods;
sched_pmt_ptr payments;
double interest_pd;
double principal_pd;
double yr_end_balance;
double total_interest_pd;
double final_pmt;
amort_sched_yr_ptr next_yr;
} amort_sched_yr;
typedef struct amort_sched_yr
{
unsigned year;
unsigned num_periods;
sched_pmt_ptr payments;
double interest_pd;
double principal_pd;
double yr_end_balance;
double total_interest_pd;
double final_pmt;
amort_sched_yr_ptr next_yr;
}
amort_sched_yr;
/* structure used by amortization routines for passing and storing
* infomation on a particular amortization transaction */
typedef struct amort_sched *amort_sched_ptr;
typedef struct amort_sched {
/* following information set by function calling amortization
functions */
unsigned n; /* number of periods */
double nint; /* nominal interest rate */
double pv; /* present value */
double pmt; /* periodic payment */
double fv; /* future value */
unsigned CF; /* compounding frequency */
unsigned PF; /* payment frequency */
unsigned disc; /* discrete/continuous compounding flag */
unsigned bep; /* beginning/end of period payment flag */
unsigned prec; /* roundoff precision */
unsigned year_E; /* Effective date - year */
unsigned month_E; /* Effective date - month */
unsigned day_E; /* Effective date - day of month */
unsigned year_I; /* Initial payment date - year */
unsigned month_I; /* Initial payment date - month */
unsigned day_I; /* Initial payment date - day of month */
/* following information set by calling function to indicate which schedule
* to compute and which type of schedule
*/
unsigned option; /* option flag from 1 to 6 inclusive */
char summary; /* summary flag == 'y', 'p', 'a' or 'f' */
/* following information set by amortization functions
*/
double eint; /* effective interest rate */
double bp; /* float value of bep */
double total_interest; /* total interest paid */
unsigned total_periods; /* total numer of periods in schedule */
unsigned long yr_pmt; /* number of payments in first year */
double final_pmt_opt_1; /* final payment option 1 */
double final_pmt_opt_2; /* final payment option 2 */
double final_pmt_opt_3; /* final payment option 3 */
double final_pmt_opt_4; /* final payment option 4 */
double final_pmt_opt_5; /* final payment option 5 */
double final_pmt_opt_6; /* final payment option 6 */
double final_pmt; /* final payment */
double pve; /* pv adjusted for delayed initial payment */
double new_pmt; /* pmt adjusted for delayed initial payment */
double cpmt; /* constant payment to principal */
double cpmt1; /* constant payment to principal, 1st case */
double cpmt2; /* constant payment to principal, 2cd case */
double delayed_int; /* interest due to delayed initial payment */
double fixed_pmt; /* fixed prepayment amount for amortization */
unsigned new_n; /* new number of periods to amortize due to delayed intial payment */
unsigned fv_case; /* fv case flag */
unsigned long Eff_Date_jdn;
unsigned yday_E;
unsigned long Init_Date_jdn;
unsigned yday_I;
union {
amort_sched_yr_ptr first_yr;
yearly_summary_ptr summary;
} schedule;
} amort_sched;
typedef struct amort_sched
{
/* following information set by function calling amortization
functions */
unsigned n; /* number of periods */
double nint; /* nominal interest rate */
double pv; /* present value */
double pmt; /* periodic payment */
double fv; /* future value */
unsigned CF; /* compounding frequency */
unsigned PF; /* payment frequency */
unsigned disc; /* discrete/continuous compounding flag */
unsigned bep; /* beginning/end of period payment flag */
unsigned prec; /* roundoff precision */
unsigned year_E; /* Effective date - year */
unsigned month_E; /* Effective date - month */
unsigned day_E; /* Effective date - day of month */
unsigned year_I; /* Initial payment date - year */
unsigned month_I; /* Initial payment date - month */
unsigned day_I; /* Initial payment date - day of month */
/* following information set by calling function to indicate which
* schedule to compute and which type of schedule */
unsigned option; /* option flag from 1 to 6 inclusive */
char summary; /* summary flag == 'y', 'p', 'a' or 'f' */
/* following information set by amortization functions */
double eint; /* effective interest rate */
double bp; /* float value of bep */
double total_interest; /* total interest paid */
unsigned total_periods; /* total numer of periods in schedule */
unsigned long yr_pmt; /* number of payments in first year */
double final_pmt_opt_1; /* final payment option 1 */
double final_pmt_opt_2; /* final payment option 2 */
double final_pmt_opt_3; /* final payment option 3 */
double final_pmt_opt_4; /* final payment option 4 */
double final_pmt_opt_5; /* final payment option 5 */
double final_pmt_opt_6; /* final payment option 6 */
double final_pmt; /* final payment */
double pve; /* pv adjusted for delayed initial payment */
double new_pmt; /* pmt adjusted for delayed initial payment */
double cpmt; /* constant payment to principal */
double cpmt1; /* constant payment to principal, 1st case */
double cpmt2; /* constant payment to principal, 2cd case */
double delayed_int; /* interest due to delayed initial payment */
double fixed_pmt; /* fixed prepayment amount for amortization */
unsigned new_n; /* new number of periods to amortize due to
delayed intial payment */
unsigned fv_case; /* fv case flag */
unsigned long Eff_Date_jdn;
unsigned yday_E;
unsigned long Init_Date_jdn;
unsigned yday_I;
union
{
amort_sched_yr_ptr first_yr;
yearly_summary_ptr summary;
}
schedule;
}
amort_sched;
/* The following structure is used to hold all of the financial
* variables used by the financial calculator */
/* structure used by financial computation routines to store financial
variables */
variables */
typedef struct financial_info *fi_ptr;
typedef struct financial_info {
double ir; /* interest rate */
double pv; /* present value */
double pmt; /* periodic payment */
double fv; /* future value */
unsigned npp; /* number of payment periods */
unsigned CF; /* Compounding frequency */
unsigned PF; /* payment frequency */
unsigned bep; /* beginning/end of period payment flag */
/* TRUE == beginning of period */
/* FALSE == end of period */
unsigned disc; /* discrete/continuous compounding flag */
/* TRUE == discrete compounding */
/* FALSE == continuous compounding */
/* precision of roundoff for pv, pmt and fv.
* i, Interest not rounded
* n, number of periods rounded to integer value, implicit value of zero, 0
*
* 2 for US Dollars
*/
unsigned prec;
} financial_info;
typedef struct financial_info
{
double ir; /* interest rate */
double pv; /* present value */
double pmt; /* periodic payment */
double fv; /* future value */
unsigned npp; /* number of payment periods */
unsigned CF; /* Compounding frequency */
unsigned PF; /* payment frequency */
unsigned bep; /* beginning/end of period payment flag */
/* TRUE == beginning of period */
/* FALSE == end of period */
unsigned disc; /* discrete/continuous compounding flag */
/* TRUE == discrete compounding */
/* FALSE == continuous compounding */
/* precision of roundoff for pv, pmt and fv.
* i, Interest not rounded
* n, number of periods rounded to integer value, implicit value of zero, 0
*
* 2 for US Dollars
*/
unsigned prec;
}
financial_info;
typedef struct parser_env *parser_env_ptr;

@ -22,7 +22,7 @@
#ifndef __NUMERIC_OPS_H__
#define __NUMERIC_OPS_H__
void *trans_numeric(char *str, /* pointer to string to translate */
void *trans_numeric(const char *str, /* pointer to string to translate */
char radix_point, /* radix character */
char group_char, /* grouping character to left of radix */
char **endstr); /* where to return pointer to first

@ -366,7 +366,7 @@ gnc_exp_parser_parse (const char * expression, double *value_p,
exit_parser (pe);
return (error_loc == NULL);
return last_error == PARSER_NO_ERROR;
}
const char *
@ -387,5 +387,7 @@ gnc_exp_parser_error_string (void)
return PARSER_UNDEFINED_CHARACTER;
case NOT_A_VARIABLE:
return PARSER_NOT_A_VARIABLE;
case PARSER_OUT_OF_MEMORY:
return PARSER_OUT_OF_MEMORY_STR;
}
}

@ -140,37 +140,41 @@ gnc_xfer_dialog_create_tree_frame(gchar *title,
}
static void
gnc_parse_error_dialog (XferDialog *xferData)
{
const char *error_string;
char * error_phrase;
error_string = gnc_exp_parser_error_string ();
if (error_string == NULL)
error_string = "";
error_phrase = g_strdup_printf(ERROR_IN_AMOUNT, error_string);
gnc_error_dialog_parented(GTK_WINDOW(xferData->dialog), error_phrase);
g_free(error_phrase);
}
static gboolean
gnc_xfer_update_cb(GtkWidget *widget, GdkEventFocus *event, gpointer data)
{
GtkEntry *entry = GTK_ENTRY(widget);
XferDialog *xferData = data;
Account *account;
const char *new_string;
const char *currency;
const char *string;
double value;
Account *account;
account = gnc_account_tree_get_current_account(xferData->from);
if (account == NULL)
account = gnc_account_tree_get_current_account(xferData->to);
string = gtk_entry_get_text(entry);
if ((string == NULL) || (*string == 0))
return FALSE;
value = 0.0;
xaccParseAmount(string, TRUE, &value, NULL);
currency = xaccAccountGetCurrency(account);
new_string = xaccPrintAmount(value, PRTSEP, currency);
if (safe_strcmp(string, new_string) == 0)
return FALSE;
gnc_amount_edit_set_currency (GNC_AMOUNT_EDIT (xferData->amount_edit),
currency);
gtk_entry_set_text(entry, new_string);
gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->amount_edit));
return FALSE;
}
@ -329,18 +333,8 @@ gnc_xfer_dialog_ok_cb(GtkWidget * widget, gpointer data)
if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->amount_edit)))
{
const char *error_string;
char * error_phrase;
error_string = gnc_exp_parser_error_string ();
if (error_string == NULL)
error_string = "";
error_phrase = g_strdup_printf(ERROR_IN_AMOUNT, error_string);
gnc_error_dialog_parented(GTK_WINDOW(xferData->dialog), error_phrase);
g_free(error_phrase);
gnc_parse_error_dialog (xferData);
return;
}
amount = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->amount_edit));

@ -444,6 +444,7 @@
#define PARSER_STACK_UNDERFLOW _("Stack underflow")
#define PARSER_UNDEFINED_CHARACTER _("Undefined character")
#define PARSER_NOT_A_VARIABLE _("Not a variable")
#define PARSER_OUT_OF_MEMORY_STR _("Out of memory")
/** MISC INTERNATIONALIZATION STRINGS: ******************************/

Loading…
Cancel
Save