[gcalctool] Improve MP equation interface
- From: Robert Ancell <rancell src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gcalctool] Improve MP equation interface
- Date: Tue, 11 Aug 2009 00:18:02 +0000 (UTC)
commit c4316ad6fc9157321a5633bd64b31c578a820779
Author: Robert Ancell <robert ancell gmail com>
Date: Mon Aug 10 13:48:56 2009 +0100
Improve MP equation interface
src/Makefile.am | 1 +
src/calctool.c | 11 +++---
src/display.c | 20 +++++++---
src/display.h | 1 +
src/functions.c | 85 +++++++++++++++++++++++++++++++++++----------
src/mp-equation-lexer.l | 22 ++++++------
src/mp-equation-parser.y | 10 +++---
src/mp-equation-private.h | 55 +++++++++++++++++++++++++++++
src/mp-equation.c | 61 ++++++++++++++------------------
src/mp-equation.h | 31 +++++++---------
src/register.c | 2 +-
src/register.h | 2 +-
src/unittest.c | 40 ++++++++++----------
13 files changed, 221 insertions(+), 120 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index bae900e..23d9efc 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -30,6 +30,7 @@ gcalctool_SOURCES = \
mp-trigonometric.c \
mp-equation.c \
mp-equation.h \
+ mp-equation-private.h \
mp-equation-lexer.c \
mp-equation-lexer.h \
mp-equation-parser.c \
diff --git a/src/calctool.c b/src/calctool.c
index dcdfe86..4a64995 100644
--- a/src/calctool.c
+++ b/src/calctool.c
@@ -78,16 +78,17 @@ version()
static void
solve(const char *equation)
{
+ MPEquationOptions options;
int error;
MPNumber result;
char result_str[MAXLINE];
- v->base = 10;
- v->ttype = MP_DEGREES;
- v->wordlen = 32;
- v->accuracy = 9;
+ memset(&options, 0, sizeof(options));
+ options.base = 10;
+ options.wordlen = 32;
+ options.angle_units = MP_DEGREES;
- error = mp_equation_parse(equation, &result);
+ error = mp_equation_parse(equation, &options, &result);
if(error != 0) {
fprintf(stderr, "Error %d\n", error);
exit(1);
diff --git a/src/display.c b/src/display.c
index 1f82085..6d2280a 100644
--- a/src/display.c
+++ b/src/display.c
@@ -32,9 +32,9 @@
#include "get.h"
#include "mp.h"
+#include "mp-equation.h"
#include "functions.h"
#include "ui.h"
-#include "mp-equation.h" // For mp_equation_parse()
#include "register.h"
static const char *display_types[] = { "ENG", "FIX", "SCI", NULL };
@@ -171,7 +171,7 @@ display_clear(GCDisplay *display)
}
-static const char *
+const char *
display_get_text(GCDisplay *display)
{
return get_state(display)->expression;
@@ -589,12 +589,13 @@ display_is_result(GCDisplay *display)
gboolean
-display_is_usable_number(GCDisplay *display, MPNumber *MPnum)
+display_is_usable_number(GCDisplay *display, MPNumber *z)
{
if (display_is_empty(display)) {
- return mp_equation_parse("0", MPnum);
+ mp_set_from_integer(0, z);
+ return TRUE;
} else {
- return mp_equation_parse(display_get_text(display), MPnum);
+ return display_solve(display, z) == 0; // FIXME: Change to MP
}
}
@@ -671,14 +672,21 @@ void display_set_format(GCDisplay *display, DisplayFormat type)
}
+// FIXME: Obsolete
int
display_solve(GCDisplay *display, MPNumber *result)
{
+ MPEquationOptions options;
const char *text;
int errorCode;
+
+ memset(&options, 0, sizeof(options));
+ options.base = v->base;
+ options.wordlen = v->wordlen;
+ options.angle_units = v->ttype;
text = display_get_text(display);
- errorCode = mp_equation_parse(text, result);
+ errorCode = mp_equation_parse(text, &options, result);
return errorCode;
}
diff --git a/src/display.h b/src/display.h
index 1d1dfca..deb6328 100644
--- a/src/display.h
+++ b/src/display.h
@@ -91,6 +91,7 @@ gboolean display_is_empty(GCDisplay *);
gboolean display_is_result(GCDisplay *);
gboolean display_is_usable_number(GCDisplay *display, MPNumber *);
+const char *display_get_text(GCDisplay *display);
int display_solve(GCDisplay *display, MPNumber *);
void display_make_number(GCDisplay *display, char *target, int target_len, const MPNumber *MPnumber, int base, int ignoreError);
diff --git a/src/functions.c b/src/functions.c
index b9189d4..8912254 100644
--- a/src/functions.c
+++ b/src/functions.c
@@ -169,6 +169,53 @@ do_accuracy(int value)
}
+static int
+get_variable(const char *name, MPNumber *z, void *data)
+{
+ char *c, *lower_name;
+ int result = 1;
+
+ lower_name = strdup(name);
+ for (c = lower_name; *c; c++)
+ *c = tolower(*c);
+
+ if (lower_name[0] == 'r')
+ register_get(atoi(name+1), z);
+ else if (strcmp(lower_name, "ans") == 0)
+ mp_set_from_mp(display_get_answer(&v->display), z);
+ else
+ result = 0;
+
+ free(lower_name);
+
+ return result;
+}
+
+
+static void
+set_variable(const char *name, const MPNumber *x, void *data)
+{
+ if (name[0] == 'R' || name[0] == 'r')
+ register_set(atoi(name+1), x);
+}
+
+
+static int
+parse(const char *text, MPNumber *z)
+{
+ MPEquationOptions options;
+
+ memset(&options, 0, sizeof(options));
+ options.base = v->base;
+ options.wordlen = v->wordlen;
+ options.angle_units = v->ttype;
+ options.get_variable = get_variable;
+ options.set_variable = set_variable;
+
+ return mp_equation_parse(text, &options, z);
+}
+
+
/* Perform a user defined function. */
static void
do_function(int index)
@@ -178,7 +225,7 @@ do_function(int index)
assert(index >= 0);
assert(index <= 9);
- ret = mp_equation_parse(function_get_value(index), display_get_answer(&v->display));
+ ret = parse(function_get_value(index), display_get_answer(&v->display));
if (ret == 0) {
display_set_answer(&v->display);
ui_set_statusbar("", "");
@@ -267,16 +314,16 @@ do_insert_character(const char *text)
static void
do_shift(int count)
{
- MPNumber MPval;
+ MPNumber z;
- if (display_is_usable_number(&v->display, &MPval) || !mp_is_integer(&MPval)) {
+ if (display_is_usable_number(&v->display, &z) || !mp_is_integer(&z)) {
/* Translators: This message is displayed in the status bar when a bit
shift operation is performed and the display does not contain a number */
ui_set_statusbar(_("No sane value to do bitwise shift"),
"gtk-dialog-error");
}
else {
- mp_shift(&MPval, count, display_get_answer(&v->display));
+ mp_shift(&z, count, display_get_answer(&v->display));
display_set_answer(&v->display);
}
}
@@ -287,16 +334,16 @@ static void
do_base(int b)
{
int ret;
- MPNumber MP;
+ MPNumber z;
if (!display_is_empty(&v->display))
{
- ret = display_is_usable_number(&v->display, &MP);
+ ret = display_is_usable_number(&v->display, &z);
if (ret) {
ui_set_statusbar(_("No sane value to convert"),
"gtk-dialog-error");
} else {
- mp_set_from_mp(&MP, display_get_answer(&v->display));
+ mp_set_from_mp(&z, display_get_answer(&v->display));
display_set_answer(&v->display);
clear_undo_history();
}
@@ -313,15 +360,15 @@ do_base(int b)
static void
do_exchange(int index)
{
- MPNumber MPtemp, MPexpr;
+ MPNumber r, z;
- if (display_is_usable_number(&v->display, &MPexpr)) {
+ if (display_is_usable_number(&v->display, &z)) {
ui_set_statusbar(_("No sane value to store"),
"gtk-dialog-error");
} else {
- register_get(index, &MPtemp);
- register_set(index, &MPexpr);
- mp_set_from_mp(&MPtemp, display_get_answer(&v->display));
+ register_get(index, &r);
+ register_set(index, &z);
+ mp_set_from_mp(&r, display_get_answer(&v->display));
display_set_answer(&v->display);
ui_make_registers();
}
@@ -341,17 +388,17 @@ static void
do_numtype(DisplayFormat n) /* Set number display type. */
{
int ret;
- MPNumber MP;
+ MPNumber z;
/* Convert display if it contains a number */
if (!display_is_empty(&v->display))
{
- ret = display_is_usable_number(&v->display, &MP);
+ ret = display_is_usable_number(&v->display, &z);
if (ret) {
ui_set_statusbar(_("No sane value to convert"),
"gtk-dialog-error");
} else {
- mp_set_from_mp(&MP, display_get_answer(&v->display));
+ mp_set_from_mp(&z, display_get_answer(&v->display));
display_set_answer(&v->display);
clear_undo_history();
}
@@ -521,14 +568,14 @@ do_expression(int function, int arg, int cursor_start, int cursor_end)
/* Solve the equation */
} else {
- MPNumber MPval;
+ MPNumber z;
int result;
const char *message = NULL;
-
- result = display_solve(&v->display, &MPval);
+
+ result = parse(display_get_text(&v->display), &z);
switch (result) {
case 0:
- mp_set_from_mp(&MPval, ans);
+ mp_set_from_mp(&z, ans);
display_set_answer(&v->display);
break;
diff --git a/src/mp-equation-lexer.l b/src/mp-equation-lexer.l
index b8a4c89..94c14d6 100644
--- a/src/mp-equation-lexer.l
+++ b/src/mp-equation-lexer.l
@@ -32,7 +32,7 @@
#include <sys/types.h>
#include "calctool.h"
-#include "mp-equation.h"
+#include "mp-equation-private.h"
#include "mp-equation-parser.h"
static int super_atoi(const char *data)
@@ -132,37 +132,37 @@ NOT "¬"|"~"|[nN][oO][tT]
{INVERSE} {return tINVERSE;}
{DEC_NUM}{EXP}{DEC_NUM} {
-if (_mp_equation_get_extra(yyscanner)->base == 16) REJECT;
+if (_mp_equation_get_extra(yyscanner)->options->base == 16) REJECT;
if (strlen(yytext) > MAX_DIGITS) yyextra->error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, _mp_equation_get_extra(yyscanner)->base, &yylval->int_t);
+mp_set_from_string(yytext, _mp_equation_get_extra(yyscanner)->options->base, &yylval->int_t);
return tNUMBER;
}
{BIN_NUM} {
-if (_mp_equation_get_extra(yyscanner)->base != 2) REJECT;
+if (_mp_equation_get_extra(yyscanner)->options->base != 2) REJECT;
if (strlen(yytext) > MAX_DIGITS) yyextra->error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, _mp_equation_get_extra(yyscanner)->base, &yylval->int_t);
+mp_set_from_string(yytext, _mp_equation_get_extra(yyscanner)->options->base, &yylval->int_t);
return tNUMBER;
}
{OCT_NUM} {
-if (_mp_equation_get_extra(yyscanner)->base != 8) REJECT;
+if (_mp_equation_get_extra(yyscanner)->options->base != 8) REJECT;
if (strlen(yytext) > MAX_DIGITS) yyextra->error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, _mp_equation_get_extra(yyscanner)->base, &yylval->int_t);
+mp_set_from_string(yytext, _mp_equation_get_extra(yyscanner)->options->base, &yylval->int_t);
return tNUMBER;
}
{DEC_NUM} {
-if (_mp_equation_get_extra(yyscanner)->base != 10) REJECT;
+if (_mp_equation_get_extra(yyscanner)->options->base != 10) REJECT;
if (strlen(yytext) > MAX_DIGITS) yyextra->error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, _mp_equation_get_extra(yyscanner)->base, &yylval->int_t);
+mp_set_from_string(yytext, _mp_equation_get_extra(yyscanner)->options->base, &yylval->int_t);
return tNUMBER;
}
{HEX_NUM} {
-if (_mp_equation_get_extra(yyscanner)->base != 16) REJECT;
+if (_mp_equation_get_extra(yyscanner)->options->base != 16) REJECT;
if (strlen(yytext) > MAX_DIGITS) yyextra->error = -PARSER_ERR_TOO_LONG_NUMBER;
-mp_set_from_string(yytext, _mp_equation_get_extra(yyscanner)->base, &yylval->int_t);
+mp_set_from_string(yytext, _mp_equation_get_extra(yyscanner)->options->base, &yylval->int_t);
return tNUMBER;
}
diff --git a/src/mp-equation-parser.y b/src/mp-equation-parser.y
index e8e5e35..a2f7897 100644
--- a/src/mp-equation-parser.y
+++ b/src/mp-equation-parser.y
@@ -24,7 +24,7 @@
#include <math.h>
#include <errno.h>
-#include "mp-equation.h"
+#include "mp-equation-private.h"
#include "mp-equation-parser.h"
#include "mp-equation-lexer.h"
@@ -66,20 +66,20 @@ static void do_xnor(yyscan_t yyscanner, const MPNumber *x, const MPNumber *y, MP
{
if (!mp_is_natural(x)) {
set_error(yyscanner, -PARSER_ERR_BITWISEOP);
- } else if (!mp_is_overflow(x, _mp_equation_get_extra(yyscanner)->wordlen)) {
+ } else if (!mp_is_overflow(x, _mp_equation_get_extra(yyscanner)->options->wordlen)) {
set_error(yyscanner, -PARSER_ERR_OVERFLOW);
}
- mp_xnor(x, y, _mp_equation_get_extra(yyscanner)->wordlen, z);
+ mp_xnor(x, y, _mp_equation_get_extra(yyscanner)->options->wordlen, z);
}
static void do_not(yyscan_t yyscanner, const MPNumber *x, MPNumber *z)
{
if (!mp_is_natural(x)) {
set_error(yyscanner, -PARSER_ERR_BITWISEOP);
- } else if (!mp_is_overflow(x, _mp_equation_get_extra(yyscanner)->wordlen)) {
+ } else if (!mp_is_overflow(x, _mp_equation_get_extra(yyscanner)->options->wordlen)) {
set_error(yyscanner, -PARSER_ERR_OVERFLOW);
}
- mp_not(x, _mp_equation_get_extra(yyscanner)->wordlen, z);
+ mp_not(x, _mp_equation_get_extra(yyscanner)->options->wordlen, z);
}
static void do_mod(yyscan_t yyscanner, const MPNumber *x, const MPNumber *y, MPNumber *z)
diff --git a/src/mp-equation-private.h b/src/mp-equation-private.h
new file mode 100644
index 0000000..16bf6ec
--- /dev/null
+++ b/src/mp-equation-private.h
@@ -0,0 +1,55 @@
+
+/* $Header$
+ *
+ * Copyright (C) 2004-2008 Sami Pietila
+ * Copyright (c) 2008-2009 Robert Ancell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#ifndef MP_EQUATION_PRIVATE_H
+#define MP_EQUATION_PRIVATE_H
+
+#include "mp-equation.h"
+
+typedef struct MPEquationParserState MPEquationParserState;
+
+/* State for parser */
+struct MPEquationParserState {
+ /* User provided options */
+ MPEquationOptions *options;
+
+ /* Function to get variable values */
+ int (*get_variable)(MPEquationParserState *state, const char *name, MPNumber *z);
+
+ /* Function to set variable values */
+ void (*set_variable)(MPEquationParserState *state, const char *name, const MPNumber *x);
+
+ /* Function to solve functions */
+ int (*get_function)(MPEquationParserState *state, const char *name, const MPNumber *x, MPNumber *z);
+
+ // FIXME: get_operator??
+
+ /* Error returned from parser */
+ int error;
+
+ /* Value returned from parser */
+ MPNumber ret;
+};
+
+int _mp_equation_error(void *yylloc, MPEquationParserState *state, char *text);
+
+#endif
diff --git a/src/mp-equation.c b/src/mp-equation.c
index 72b275f..022a520 100644
--- a/src/mp-equation.c
+++ b/src/mp-equation.c
@@ -22,45 +22,38 @@
#include <ctype.h>
-#include "mp-equation.h"
-#include "calctool.h"
-#include "register.h"
+#include "mp-equation-private.h"
#include "mp-equation-parser.h"
#include "mp-equation-lexer.h"
+#include "calctool.h" // FIXME v->math_error
extern int _mp_equation_parse(yyscan_t yyscanner);
static int
get_variable(MPEquationParserState *state, const char *name, MPNumber *z)
{
- char *c, *lower_name;
int result = 1;
- lower_name = strdup(name);
- for (c = lower_name; *c; c++)
- *c = tolower(*c);
-
- if (lower_name[0] == 'r')
- register_get(atoi(name+1), z);
- else if (strcmp(lower_name, "ans") == 0)
- mp_set_from_mp(display_get_answer(&v->display), z);
- else if (strcmp(name, "e") == 0)
+ if (strcmp(name, "e") == 0)
mp_get_eulers(z);
else if (strcmp(name, "Ï?") == 0)
mp_get_pi(z);
+ else if (state->options->get_variable)
+ result = state->options->get_variable(name, z, state->options->callback_data);
else
result = 0;
-
- free(lower_name);
-
+
return result;
}
static void
-set_variable(MPEquationParserState *state, const char *name, MPNumber *x)
+set_variable(MPEquationParserState *state, const char *name, const MPNumber *x)
{
- if (name[0] == 'R' || name[0] == 'r')
- register_set(atoi(name+1), x);
+ if (strcmp(name, "e") == 0 || strcmp(name, "Ï?") == 0)
+ return; // FALSE
+
+ if (state->options->set_variable)
+ state->options->set_variable(name, x, state->options->callback_data);
}
// FIXME: Accept "2sin" not "2 sin", i.e. let the tokenizer collect the multiple
@@ -120,17 +113,17 @@ get_function(MPEquationParserState *state, const char *name, const MPNumber *x,
else if (strcmp(lower_name, "frac") == 0)
mp_fractional_component(x, z);
else if (strcmp(lower_name, "sin") == 0)
- mp_sin(x, state->angle_units, z);
+ mp_sin(x, state->options->angle_units, z);
else if (strcmp(lower_name, "cos") == 0)
- mp_cos(x, state->angle_units, z);
+ mp_cos(x, state->options->angle_units, z);
else if (strcmp(lower_name, "tan") == 0)
- mp_tan(x, state->angle_units, z);
+ mp_tan(x, state->options->angle_units, z);
else if (strcmp(lower_name, "sin�¹") == 0 || strcmp(lower_name, "asin") == 0)
- mp_asin(x, state->angle_units, z);
+ mp_asin(x, state->options->angle_units, z);
else if (strcmp(lower_name, "cos�¹") == 0 || strcmp(lower_name, "acos") == 0)
- mp_acos(x, state->angle_units, z);
+ mp_acos(x, state->options->angle_units, z);
else if (strcmp(lower_name, "tan�¹") == 0 || strcmp(lower_name, "atan") == 0)
- mp_atan(x, state->angle_units, z);
+ mp_atan(x, state->options->angle_units, z);
else if (strcmp(lower_name, "sinh") == 0)
mp_sinh(x, z);
else if (strcmp(lower_name, "cosh") == 0)
@@ -144,9 +137,11 @@ get_function(MPEquationParserState *state, const char *name, const MPNumber *x,
else if (strcmp(lower_name, "tanh�¹") == 0 || strcmp(lower_name, "atanh") == 0)
mp_atanh(x, z);
else if (strcmp(lower_name, "ones") == 0)
- mp_ones_complement(x, state->wordlen, z);
+ mp_ones_complement(x, state->options->wordlen, z);
else if (strcmp(lower_name, "twos") == 0)
- mp_twos_complement(x, state->wordlen, z);
+ mp_twos_complement(x, state->options->wordlen, z);
+ else if (state->options->get_function)
+ result = state->options->get_function(name, x, z, state->options->callback_data);
else
result = 0;
@@ -156,8 +151,8 @@ get_function(MPEquationParserState *state, const char *name, const MPNumber *x,
}
-int
-mp_equation_parse(const char *expression, MPNumber *result)
+int
+mp_equation_parse(const char *expression, MPEquationOptions *options, MPNumber *result)
{
int ret;
MPEquationParserState state;
@@ -168,14 +163,12 @@ mp_equation_parse(const char *expression, MPNumber *result)
return(-EINVAL);
memset(&state, 0, sizeof(MPEquationParserState));
- state.base = v->base;
- state.wordlen = v->wordlen;
- state.angle_units = v->ttype;
+ state.options = options;
state.get_variable = get_variable;
state.set_variable = set_variable;
- state.get_function = get_function;
+ state.get_function = get_function;
state.error = 0;
- v->math_error = 0;
+ v->math_error = 0; // FIXME: Move up one level
_mp_equation_lex_init_extra(&state, &yyscanner);
buffer = _mp_equation__scan_string(expression, yyscanner);
diff --git a/src/mp-equation.h b/src/mp-equation.h
index 70d8400..80a0be3 100644
--- a/src/mp-equation.h
+++ b/src/mp-equation.h
@@ -34,10 +34,8 @@
#define PARSER_ERR_UNKNOWN_FUNCTION 7
#define PARSER_ERR_INVALID_BASE 8
-typedef struct MPEquationParserState MPEquationParserState;
-
-/* State for parser */
-struct MPEquationParserState {
+/* Options for parser */
+typedef struct {
/* The numeric base (e.g 2, 8, 10, 16) */
int base;
@@ -47,25 +45,22 @@ struct MPEquationParserState {
/* Units for angles (e.g. radians, degrees) */
MPAngleUnit angle_units;
+ // FIXME:
+ // int enable_builtins;
+
+ /* Data to pass to callbacks */
+ void *callback_data;
+
/* Function to get variable values */
- int (*get_variable)(MPEquationParserState *state, const char *name, MPNumber *z);
+ int (*get_variable)(const char *name, MPNumber *z, void *data);
/* Function to set variable values */
- void (*set_variable)(MPEquationParserState *state, const char *name, MPNumber *x);
+ void (*set_variable)(const char *name, const MPNumber *x, void *data);
/* Function to solve functions */
- int (*get_function)(MPEquationParserState *state, const char *name, const MPNumber *x, MPNumber *z);
-
- // FIXME: get_operator??
-
- /* Error returned from parser */
- int error;
-
- /* Value returned from parser */
- MPNumber ret;
-};
+ int (*get_function)(const char *name, const MPNumber *x, MPNumber *z, void *data);
+} MPEquationOptions;
-int mp_equation_parse(const char *expression, MPNumber *result);
-int _mp_equation_error(void *yylloc, MPEquationParserState *state, char *text);
+int mp_equation_parse(const char *expression, MPEquationOptions *options, MPNumber *result);
#endif
diff --git a/src/register.c b/src/register.c
index 8a8ff8c..40567af 100644
--- a/src/register.c
+++ b/src/register.c
@@ -126,7 +126,7 @@ void register_init()
void
-register_set(int index, MPNumber *value)
+register_set(int index, const MPNumber *value)
{
if ((index >= 0) && (index <= 10))
mp_set_from_mp(value, ®isters[index]);
diff --git a/src/register.h b/src/register.h
index f157599..c0593d9 100644
--- a/src/register.h
+++ b/src/register.h
@@ -25,7 +25,7 @@
#include "mp.h"
void register_init();
-void register_set(int index, MPNumber *value);
+void register_set(int index, const MPNumber *value);
void register_get(int index, MPNumber *value);
void constant_set(int index, const char *name, MPNumber *value);
diff --git a/src/unittest.c b/src/unittest.c
index 9716ec5..85bb38b 100644
--- a/src/unittest.c
+++ b/src/unittest.c
@@ -21,15 +21,14 @@
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include <stdarg.h>
#include "unittest.h"
-
-#include "display.h"
-#include "functions.h"
-#include "calctool.h"
#include "mp-equation.h"
+static MPEquationOptions options;
+
static int fails = 0;
/* If we're not using GNU C, elide __attribute__ */
@@ -68,12 +67,12 @@ test(char *expression, char *expected, int expected_error)
{
int error;
MPNumber result;
- char result_str[MAXLINE] = "";
+ char result_str[1024] = "";
- error = mp_equation_parse(expression, &result);
+ error = mp_equation_parse(expression, &options, &result);
if(error == 0) {
- mp_cast_to_string(&result, v->base, 9, 1, result_str, MAXLINE);
+ mp_cast_to_string(&result, options.base, 9, 1, result_str, 1024);
if(expected_error != 0)
fail("'%s' -> %s, expected error %d", expression, result_str, expected_error);
else if(strcmp(result_str, expected) != 0)
@@ -93,17 +92,18 @@ test(char *expression, char *expected, int expected_error)
void
test_parser()
{
- v->ttype = MP_DEGREES;
- v->wordlen = 32;
- v->accuracy = 9;
+ memset(&options, 0, sizeof(options));
+ options.base = 10;
+ options.wordlen = 32;
+ options.angle_units = MP_DEGREES;
- v->base = 2;
+ options.base = 2;
test("0", "0", 0);
test("1", "1", 0);
test("10", "10", 0);
test("210", "", -1);
- v->base = 8;
+ options.base = 8;
test("0", "0", 0);
test("1", "1", 0);
test("2", "2", 0);
@@ -115,7 +115,7 @@ test_parser()
test("76543210", "76543210", 0);
test("876543210", "", -1);
- v->base = 10;
+ options.base = 10;
test("0", "0", 0);
test("1", "1", 0);
test("2", "2", 0);
@@ -129,7 +129,7 @@ test_parser()
test("9876543210", "9876543210", 0);
test("A9876543210", "", -7);
- v->base = 16;
+ options.base = 16;
test("0", "0", 0);
test("1", "1", 0);
test("2", "2", 0);
@@ -149,7 +149,7 @@ test_parser()
test("FEDBCA9876543210", "FEDBCA9876543210", 0);
test("GFEDBCA9876543210", "", -7);
- v->base = 10;
+ options.base = 10;
test("+1", "1", 0);
test("â??1", "â??1", 0);
test("+ 1", "1", 0); // FIXME: Should this be allowed?
@@ -345,7 +345,7 @@ test_parser()
test("ln e", "1", 0);
test("2 ln 2", "1.386294361", 0);
- v->ttype = MP_DEGREES;
+ options.angle_units = MP_DEGREES;
test("sin 0", "0", 0);
test("sin 45 â?? 1÷â??2", "0", 0);
test("sin 20 + sin(â??20)", "0", 0);
@@ -392,20 +392,20 @@ test_parser()
test("atanh 0", "0", 0);
test("atanh (1÷10) â?? 0.5 ln(11÷9)", "0", 0);
- v->ttype = MP_DEGREES;
+ options.angle_units = MP_DEGREES;
test("sin 90", "1", 0);
- v->ttype = MP_RADIANS;
+ options.angle_units = MP_RADIANS;
test("sin (Ï?÷2)", "1", 0); // FIXME: Shouldn't need brackets
- v->ttype = MP_GRADIANS;
+ options.angle_units = MP_GRADIANS;
test("sin 100", "1", 0);
test("3 and 5", "1", 0);
test("3 or 5", "7", 0);
test("3 xor 5", "6", 0);
- v->base = 16;
+ options.base = 16;
test("ones 1", "FFFFFFFE", 0);
test("ones 7FFFFFFF", "80000000", 0);
test("twos 1", "FFFFFFFF", 0);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]