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
This commit is contained in:
Dave Peticolas
2000-09-12 01:01:39 +00:00
parent 9d82f29a95
commit 58e0f71949
9 changed files with 2183 additions and 1898 deletions
+360 -195
View File
@@ -254,8 +254,7 @@
* Note: in the last five functions, in the function paramter (void
* *vp), "vp" is the pointer returned by the "init_parser" function.
*
* void *init_parser(
* var_store_ptr predefined_vars,
* void *init_parser(var_store_ptr predefined_vars,
* char radix_point,
* char group_char,
* void *trans_numeric(char *digit_str,
@@ -371,7 +370,8 @@
/* structure to hold parser environment - environment particular to
* each caller */
typedef struct parser_env {
typedef struct parser_env
{
unsigned stack_cnt;
unsigned stack_size;
var_store_ptr *stack;
@@ -393,16 +393,13 @@ typedef struct parser_env {
ParseError error_code;
void *numeric_value;
void *(*trans_numeric)(const char *digit_str,
char radix_point,
char group_char,
char **rstr);
void *(*numeric_ops)(char op_sym,
void *left_value,
void *right_value);
void *(*negate_numeric)(void *value);
void (*free_numeric)(void *numeric_value);
} parser_env;
void *(*trans_numeric) (const char *digit_str,
char radix_point, char group_char, char **rstr);
void *(*numeric_ops) (char op_sym, void *left_value, void *right_value);
void *(*negate_numeric) (void *value);
void (*free_numeric) (void *numeric_value);
}
parser_env;
#include "finproto.h"
#include "fin_static_proto.h"
@@ -420,24 +417,24 @@ typedef struct parser_env {
static char allowed_operators[] = "+-*/()=";
parser_env_ptr
init_parser(var_store_ptr predefined_vars,
init_parser (var_store_ptr predefined_vars,
char radix_point,
char group_char,
void *trans_numeric(const char *digit_str,
void *trans_numeric (const char *digit_str,
char radix_point,
char group_char,
char **rstr),
void *numeric_ops(char op_sym,
void *numeric_ops (char op_sym,
void *left_value,
void *right_value),
void *negate_numeric(void *value),
void free_numeric(void *numeric_value))
void *negate_numeric (void *value),
void free_numeric (void *numeric_value))
{
parser_env_ptr pe = g_new0(parser_env, 1);
parser_env_ptr pe = g_new0 (parser_env, 1);
pe->predefined_vars = predefined_vars;
pe->stack = g_new0(var_store_ptr, STACK_INIT);
pe->stack = g_new0 (var_store_ptr, STACK_INIT);
pe->stack_size = STACK_INIT;
pe->radix_point = radix_point;
@@ -451,34 +448,37 @@ init_parser(var_store_ptr predefined_vars,
return pe;
} /* init_parser */
void exit_parser(parser_env_ptr pe)
void
exit_parser (parser_env_ptr pe)
{
var_store_ptr vars, bv;
if (pe == NULL)
return;
for ( vars = pe->named_vars ; vars ; vars = bv ) {
g_free(vars->variable_name);
for (vars = pe->named_vars; vars; vars = bv)
{
g_free (vars->variable_name);
vars->variable_name = NULL;
if ( vars->value ) (pe->free_numeric)(vars->value);
if (vars->value)
(pe->free_numeric) (vars->value);
vars->value = NULL;
bv = vars->next_var;
g_free(vars);
g_free (vars);
} /* endfor */
pe->named_vars = NULL;
g_free(pe->stack);
g_free (pe->stack);
pe->stack = NULL;
g_free(pe);
g_free (pe);
} /* exit_parser */
/* return parser error code */
ParseError get_parse_error(parser_env_ptr pe)
ParseError get_parse_error (parser_env_ptr pe)
{
if (pe == NULL)
return PARSER_NO_ERROR;
@@ -487,7 +487,7 @@ ParseError get_parse_error(parser_env_ptr pe)
} /* get_parse_error */
/* return linked list of named variables which have been defined */
var_store_ptr parser_get_vars(parser_env_ptr pe)
var_store_ptr parser_get_vars (parser_env_ptr pe)
{
if (pe == NULL)
return NULL;
@@ -497,8 +497,8 @@ var_store_ptr parser_get_vars(parser_env_ptr pe)
/* function to delete variable with specified name from named variables
* if it exists. If it exists return TRUE, 1, else return FALSE, 0 */
unsigned delete_var(char *var_name,
parser_env_ptr pe)
unsigned
delete_var (char *var_name, parser_env_ptr pe)
{
unsigned ret = FALSE;
var_store_ptr nv, tv;
@@ -506,16 +506,23 @@ unsigned delete_var(char *var_name,
if (pe == NULL)
return FALSE;
for ( nv = pe->named_vars , tv = NULL ; nv ; tv = nv , nv = nv->next_var ) {
if ( strcmp(nv->variable_name,var_name) == 0 ) {
if ( tv ) {
for (nv = pe->named_vars, tv = NULL; nv; tv = nv, nv = nv->next_var)
{
if (strcmp (nv->variable_name, var_name) == 0)
{
if (tv)
tv->next_var = nv->next_var;
} else {
else
pe->named_vars = nv->next_var;
} /* endif */
g_free(nv->variable_name);
(pe->free_numeric)(nv->value);
g_free(nv);
g_free (nv->variable_name);
nv->variable_name = NULL;
(pe->free_numeric) (nv->value);
nv->value = NULL;
g_free (nv);
ret = TRUE;
break;
} /* endif */
@@ -529,9 +536,7 @@ unsigned delete_var(char *var_name,
* parse error if parse error, return pointer to character at which
* error occured. */
char *
parse_string(var_store_ptr value,
const char *string,
parser_env_ptr pe)
parse_string (var_store_ptr value, const char *string, parser_env_ptr pe)
{
var_store_ptr retv;
var_store unnamed_vars[UNNAMED_VARS];
@@ -540,175 +545,201 @@ parse_string(var_store_ptr value,
return NULL;
pe->unnamed_vars = unnamed_vars;
memset(unnamed_vars,0,UNNAMED_VARS * sizeof(var_store));
memset (unnamed_vars, 0, UNNAMED_VARS * sizeof (var_store));
pe->parse_str = string;
pe->error_code = PARSER_NO_ERROR;
next_token(pe);
assignment_op(pe);
next_token (pe);
if ( pe->Token == EOS ) {
if ( (pe->stack_cnt) && (retv = pop(pe)) ) {
if (!pe->error_code)
assignment_op (pe);
if (pe->Token == EOS)
{
if ((pe->stack_cnt) && (retv = pop (pe)))
{
if (value != NULL)
*value = *retv;
pe->parse_str = NULL;
} else {
}
else
pe->error_code = STACK_UNDERFLOW;
} /* endif */
} /* endif */
pe->stack_cnt = 0;
}
pe->stack_cnt = 0;
pe->unnamed_vars = NULL;
return (char *) pe->parse_str;
} /* expression */
/* pop value off value stack */
static var_store_ptr pop(parser_env_ptr pe)
static var_store_ptr
pop (parser_env_ptr pe)
{
var_store_ptr val;
if ( pe->stack_cnt ) val = pe->stack[--(pe->stack_cnt)];
else {
if (pe->stack_cnt)
val = pe->stack[--(pe->stack_cnt)];
else
{
val = NULL;
pe->error_code = STACK_OVERFLOW;
pe->error_code = STACK_UNDERFLOW;
} /* endif */
return val;
} /* pop */
/* push value onto value stack */
static var_store_ptr push(var_store_ptr push_value,
parser_env_ptr pe)
static var_store_ptr
push (var_store_ptr push_value, parser_env_ptr pe)
{
if ( pe->stack_cnt > pe->stack_size ) {
if (pe->stack_cnt > pe->stack_size)
{
pe->stack_size += STACK_INIT;
pe->stack = g_realloc(pe->stack,
pe->stack_size * sizeof(var_store_ptr));
pe->stack = g_realloc (pe->stack,
pe->stack_size * sizeof (var_store_ptr));
} /* endif */
pe->stack[(pe->stack_cnt)++] = push_value;
return push_value;
} /* push */
/* get/set variable with specified name - nothing fancy
* just scan each variable in linked list checking for a string match
* return variable found if match
* create new variable if none found
*/
static var_store_ptr get_named_var(parser_env_ptr pe)
/* get/set variable with specified name - nothing fancy just scan each
* variable in linked list checking for a string match return variable
* found if match create new variable if none found */
static var_store_ptr
get_named_var (parser_env_ptr pe)
{
var_store_ptr retp = NULL, bv;
for ( retp = pe->predefined_vars , bv = NULL ; retp ; retp = retp->next_var ) {
if ( strcmp(retp->variable_name,pe->name) == 0 ) {
for (retp = pe->predefined_vars, bv = NULL; retp; retp = retp->next_var)
if (strcmp (retp->variable_name, pe->name) == 0)
break;
} /* endif */
} /* endfor */
if ( !retp && pe->named_vars ) {
for ( retp = pe->named_vars ; retp ; bv = retp , retp = retp->next_var ) {
if ( strcmp(retp->variable_name,pe->name) == 0 ) {
if (!retp && pe->named_vars)
for (retp = pe->named_vars; retp; bv = retp, retp = retp->next_var)
if (strcmp (retp->variable_name, pe->name) == 0)
break;
} /* endif */
} /* endfor */
} /* endif */
if ( !retp ) {
retp = g_new0(var_store, 1);
if ( !pe->named_vars ) {
if (!retp)
{
retp = g_new0 (var_store, 1);
if (!pe->named_vars)
pe->named_vars = retp;
} else {
else
bv->next_var = retp;
} /* endif */
retp->variable_name = g_strdup(pe->name);
retp->value = (pe->trans_numeric)("0",pe->radix_point,pe->group_char,NULL);
} /* endif */
retp->variable_name = g_strdup (pe->name);
retp->value =
(pe->trans_numeric) ("0", pe->radix_point, pe->group_char, NULL);
}
return retp;
} /* get_var */
/* get un-named temporary variable
*/
static var_store_ptr get_unnamed_var(parser_env_ptr pe)
/* get un-named temporary variable */
static var_store_ptr
get_unnamed_var (parser_env_ptr pe)
{
var_store_ptr retp = NULL;
unsigned cntr;
for ( cntr = 0 ; cntr < UNNAMED_VARS ; cntr++ ) {
if ( pe->unnamed_vars[cntr].use_flag == UNUSED_VAR ) {
for (cntr = 0; cntr < UNNAMED_VARS; cntr++)
if (pe->unnamed_vars[cntr].use_flag == UNUSED_VAR)
{
retp = &(pe->unnamed_vars[cntr]);
retp->variable_name = NULL;
retp->use_flag = USED_VAR;
if ( retp->value ) {
(pe->free_numeric)(retp->value);
if (retp->value)
{
(pe->free_numeric) (retp->value);
retp->value = NULL;
} /* endif */
break;
} /* endif */
} /* endfor */
if (retp == NULL)
pe->error_code = PARSER_OUT_OF_MEMORY;
return retp;
} /* get_unnamed_var */
/* mark un-named temporary variable unused
*/
static void free_var(var_store_ptr value,
parser_env_ptr pe)
/* mark un-named temporary variable unused */
static void
free_var (var_store_ptr value, parser_env_ptr pe)
{
/* first check that not a named variable
*/
if ( !value->variable_name ) {
if (value == NULL)
return;
/* first check that not a named variable */
if (value->variable_name != NULL)
return;
value->use_flag = UNUSED_VAR;
if ( value->value ) {
(pe->free_numeric)(value->value);
if (value->value)
{
(pe->free_numeric) (value->value);
value->value = NULL;
} /* endif */
} /* endif */
}
} /* free_var */
/* parse next token from string
*/
static void next_token(parser_env_ptr pe)
/* parse next token from string */
static void
next_token (parser_env_ptr pe)
{
char *nstr;
const char *str_parse = pe->parse_str;
void *number;
while ( isspace(*str_parse) ) str_parse++;
while (isspace (*str_parse))
str_parse++;
pe->asn_op = EOS;
/* test for end of string
*/
if ( !*str_parse ) {
/* test for end of string */
if (!*str_parse)
{
pe->Token = EOS;
/* test for name
*/
} else if ( isalpha(*str_parse) || (*str_parse == '_') ) {
/* test for name */
}
else if (isalpha (*str_parse) || (*str_parse == '_'))
{
pe->Token = VAR_TOKEN;
nstr = pe->name;
do {
do
{
*nstr++ = *str_parse++;
} while ( (*str_parse == '_') || isalpha(*str_parse) || isdigit(*str_parse) ); /* enddo */
}
while ((*str_parse == '_') ||
isalpha (*str_parse) ||
isdigit (*str_parse));
*nstr = EOS;
/* test for possible operator
*/
} else if ( strchr(allowed_operators,*str_parse) ) {
/* test for possible operator */
}
else if (strchr (allowed_operators, *str_parse))
{
pe->Token = *str_parse++;
if ( *str_parse == '=' ) {
if (*str_parse == '=')
{
str_parse++;
pe->asn_op = pe->Token;
pe->Token = '=';
} /* endif */
/* test for numeric token
*/
} else if ( (number = (pe->trans_numeric)(str_parse,pe->radix_point,pe->group_char,&nstr)) ) {
/* test for numeric token */
}
else if ((number =
(pe->trans_numeric) (str_parse, pe->radix_point,
pe->group_char, &nstr)))
{
pe->Token = NUM_TOKEN;
pe->numeric_value = number;
str_parse = nstr;
/* unrecognized character - error
*/
} else {
/* unrecognized character - error */
}
else
{
pe->Token = *str_parse;
pe->error_code = UNDEFINED_CHARACTER;
} /* endif */
@@ -723,40 +754,75 @@ static void next_token(parser_env_ptr pe)
* \=
* *=
*/
static void assignment_op(parser_env_ptr pe)
static void
assignment_op (parser_env_ptr pe)
{
var_store_ptr vl, /* left value */
vr; /* right value */
var_store_ptr vl; /* left value */
var_store_ptr vr; /* right value */
void *sp; /* for swapping values */
char ao;
add_sub_op(pe);
while ( pe->Token == '=' ) {
vl = pop(pe);
add_sub_op (pe);
if (pe->error_code)
return;
while (pe->Token == '=')
{
vl = pop (pe);
if (pe->error_code)
return;
ao = pe->asn_op;
if ( vl->variable_name ) {
next_token(pe);
assignment_op(pe);
vr = pop(pe);
if (vl->variable_name)
{
next_token (pe);
if (pe->error_code)
{
free_var (vl, pe);
return;
}
assignment_op (pe);
if (pe->error_code)
{
free_var (vl, pe);
return;
}
vr = pop (pe);
if (pe->error_code)
{
free_var (vl, pe);
return;
}
vl->assign_flag = ASSIGNED_TO;
if ( ao ) {
if (ao)
{
sp = vl->value;
vl->value = (pe->numeric_ops)(ao,vl->value,vr->value);
(pe->free_numeric)(sp);
} else if ( vl != vr ) {
if ( !vr->variable_name ) {
(pe->free_numeric)(vl->value);
vl->value = (pe->numeric_ops) (ao, vl->value, vr->value);
(pe->free_numeric) (sp);
}
else if (vl != vr)
{
if (!vr->variable_name)
{
(pe->free_numeric) (vl->value);
vl->value = vr->value;
vr->value = NULL;
} else {
vl->value = (pe->numeric_ops)(ASN_OP,vl->value,vr->value);
}
else
vl->value = (pe->numeric_ops) (ASN_OP, vl->value, vr->value);
free_var (vr, pe);
} /* endif */
free_var(vr,pe);
} /* endif */
push(vl,pe);
} else {
push (vl, pe);
}
else
{
pe->Token = EOS; /* error !!!!!!!!!! */
pe->error_code = NOT_A_VARIABLE;
} /* endif */
@@ -764,50 +830,119 @@ static void assignment_op(parser_env_ptr pe)
} /* assignment_op */
/* evaluate addition, subtraction operators */
static void add_sub_op(parser_env_ptr pe)
static void
add_sub_op (parser_env_ptr pe)
{
var_store_ptr vl, /* left value */
vr, /* right value */
rslt;
var_store_ptr vl; /* left value */
var_store_ptr vr; /* right value */
var_store_ptr rslt; /* result */
char op;
multiply_divide_op(pe);
while ( (pe->Token == '+') || (pe->Token == '-') ) {
multiply_divide_op (pe);
if (pe->error_code)
return;
while ((pe->Token == '+') || (pe->Token == '-'))
{
op = pe->Token;
vl = pop(pe);
next_token(pe);
multiply_divide_op(pe);
vr = pop(pe);
rslt = get_unnamed_var(pe);
rslt->value = (pe->numeric_ops)(op,vl->value,vr->value);
free_var(vl,pe);
free_var(vr,pe);
push(rslt,pe);
vl = pop (pe);
if (pe->error_code)
return;
next_token (pe);
if (pe->error_code)
{
free_var (vl, pe);
return;
}
multiply_divide_op (pe);
if (pe->error_code)
{
free_var (vl, pe);
return;
}
vr = pop (pe);
if (pe->error_code)
{
free_var (vl, pe);
return;
}
rslt = get_unnamed_var (pe);
if (pe->error_code)
{
free_var (vl, pe);
return;
}
rslt->value = (pe->numeric_ops) (op, vl->value, vr->value);
free_var (vl, pe);
free_var (vr, pe);
push (rslt, pe);
} /* endwhile */
} /* add_sub_op */
/* evaluate multiplication, division operators
*/
static void multiply_divide_op(parser_env_ptr pe)
static void
multiply_divide_op (parser_env_ptr pe)
{
var_store_ptr vl, /* left value */
vr, /* right value */
rslt;
var_store_ptr vl; /* left value */
var_store_ptr vr; /* right value */
var_store_ptr rslt; /* result */
char op;
primary_exp(pe);
while ( (pe->Token == '*') || (pe->Token == '/') ) {
op = pe->Token;
vl = pop(pe);
next_token(pe);
primary_exp(pe);
vr = pop(pe);
rslt = get_unnamed_var(pe);
rslt->value = (pe->numeric_ops)(op,vl->value,vr->value);
primary_exp (pe);
if (pe->error_code)
return;
free_var(vl,pe);
free_var(vr,pe);
push(rslt,pe);
while ((pe->Token == '*') || (pe->Token == '/'))
{
op = pe->Token;
vl = pop (pe);
if (pe->error_code)
return;
next_token (pe);
if (pe->error_code)
{
free_var (vl, pe);
return;
}
primary_exp (pe);
if (pe->error_code)
{
free_var (vl, pe);
return;
}
vr = pop (pe);
if (pe->error_code)
{
free_var (vl, pe);
return;
}
rslt = get_unnamed_var (pe);
if (pe->error_code)
{
free_var (vl, pe);
return;
}
rslt->value = (pe->numeric_ops) (op, vl->value, vr->value);
free_var (vl, pe);
free_var (vr, pe);
push (rslt, pe);
} /* endwhile */
} /* multiply_divide_op */
@@ -817,41 +952,71 @@ static void multiply_divide_op(parser_env_ptr pe)
* numerics
* grouped expressions, "()"
*/
static void primary_exp(parser_env_ptr pe)
static void
primary_exp (parser_env_ptr pe)
{
var_store_ptr rslt = NULL;
char LToken = pe->Token;
next_token(pe);
switch ( LToken ) {
next_token (pe);
if (pe->error_code)
return;
switch (LToken)
{
case '(':
/*add_sub_op(pe); */
assignment_op(pe);
if ( pe->Token == ')' ) {
rslt = pop(pe);
next_token(pe);
} else {
assignment_op (pe);
if (pe->error_code)
return;
if (pe->Token == ')')
{
rslt = pop (pe);
if (pe->error_code)
return;
next_token (pe);
if (pe->error_code)
return;
}
else
{
pe->Token = EOS; /* error here */
pe->error_code = UNBALANCED_PARENS;
} /* endif */
break;
case '-':
case '+':
primary_exp(pe);
rslt = pop(pe);
if ( LToken == '-' ) {
(void)(pe->negate_numeric)(rslt->value);
} /* endif */
primary_exp (pe);
if (pe->error_code)
return;
rslt = pop (pe);
if (pe->error_code)
return;
if (LToken == '-')
(pe->negate_numeric) (rslt->value);
break;
case NUM_TOKEN:
rslt = get_unnamed_var(pe);
rslt = get_unnamed_var (pe);
if (pe->error_code)
return;
rslt->value = pe->numeric_value;
pe->numeric_value = NULL;
break;
case VAR_TOKEN:
rslt = get_named_var(pe);
rslt = get_named_var (pe);
break;
} /* endswitch */
push(rslt,pe);
if (rslt != NULL)
push (rslt, pe);
} /* primary_exp */
+1 -1
View File
@@ -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 ) {
+826 -707
View File
File diff suppressed because it is too large Load Diff
+61 -76
View File
@@ -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 */
/* 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 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 */
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 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 */
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 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 */
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 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 */
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 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);
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
+47 -28
View File
@@ -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 {
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 */
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 {
typedef struct numeric
{
char type; /* designates type of value */
union {
union
{
long int int_value; /* long integer value */
double dbl_value; /* double value */
} value;
} numeric;
}
value;
}
numeric;
/* The following structures are used by the amortization functions for
* storing amortization schedule information */
@@ -94,28 +102,33 @@ typedef struct numeric {
/* structure used by amortization routines for storing annual summary
information */
typedef struct yearly_summary *yearly_summary_ptr;
typedef struct yearly_summary {
typedef struct yearly_summary
{
unsigned year;
double interest;
double end_balance;
}yearly_summary;
}
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 {
typedef struct sched_pmt
{
unsigned period_num;
double interest;
double principal;
double advanced_pmt;
double total_pmt;
double balance;
} sched_pmt;
}
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 {
typedef struct amort_sched_yr
{
unsigned year;
unsigned num_periods;
sched_pmt_ptr payments;
@@ -125,14 +138,16 @@ typedef struct amort_sched_yr {
double total_interest_pd;
double final_pmt;
amort_sched_yr_ptr next_yr;
} amort_sched_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 */
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 */
@@ -150,14 +165,12 @@ functions */
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
*/
/* 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
*/
/* following information set by amortization functions */
double eint; /* effective interest rate */
double bp; /* float value of bep */
double total_interest; /* total interest paid */
@@ -177,17 +190,21 @@ functions */
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 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 {
union
{
amort_sched_yr_ptr first_yr;
yearly_summary_ptr summary;
} schedule;
} amort_sched;
}
schedule;
}
amort_sched;
/* The following structure is used to hold all of the financial
* variables used by the financial calculator */
@@ -195,7 +212,8 @@ functions */
/* structure used by financial computation routines to store financial
variables */
typedef struct financial_info *fi_ptr;
typedef struct financial_info {
typedef struct financial_info
{
double ir; /* interest rate */
double pv; /* present value */
double pmt; /* periodic payment */
@@ -218,7 +236,8 @@ typedef struct financial_info {
* 2 for US Dollars
*/
unsigned prec;
} financial_info;
}
financial_info;
typedef struct parser_env *parser_env_ptr;
+1 -1
View File
@@ -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
+3 -1
View File
@@ -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;
}
}
+24 -30
View File
@@ -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);
gnc_amount_edit_set_currency (GNC_AMOUNT_EDIT (xferData->amount_edit),
currency);
if (safe_strcmp(string, new_string) == 0)
return FALSE;
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));
+1
View File
@@ -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: ******************************/