[gcalctool] Improve MP equation interface



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, &registers[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]