[gcalctool/gcalctool-newui2] merge head changes



commit eddf03a0748aeea60e3ef569284e4d57e5e861bd
Author: Robert Ancell <robert ancell gmail com>
Date:   Mon Aug 17 14:59:13 2009 -0700

    merge head changes

 src/Makefile.am          |    3 +-
 src/calctool.c           |   39 ++++----------------------
 src/calctool.h           |    4 --
 src/display.c            |   18 ++++++++---
 src/display.h            |    1 +
 src/functions.c          |   69 +++++++++++++++++++++++++++++++++++++--------
 src/mp-binary.c          |    4 ++-
 src/mp-equation-lexer.l  |    2 +-
 src/mp-equation-parser.y |    6 ++--
 src/mp-equation.c        |   67 ++++++++++++++++++++------------------------
 src/mp-equation.h        |   33 +++++++++------------
 src/mp.c                 |   40 ++++++++++++++++++--------
 src/mp.h                 |    7 ++++
 src/register.c           |    2 +-
 src/register.h           |    2 +-
 src/unittest.c           |   62 ++++++++++++++++++++--------------------
 16 files changed, 197 insertions(+), 162 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 688b37a..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 \
@@ -64,7 +65,7 @@ libparser.a: \
 	$(RANLIB) libparser.a
 
 mp-equation-parser.c mp-equation-parser.h: mp-equation-parser.y
-	bison -d -o mp-equation-parser.c $(srcdir)/mp-equation-parser.y
+	$(YACC) -d -o mp-equation-parser.c $(srcdir)/mp-equation-parser.y
 
 mp-equation-lexer.c mp-equation-lexer.h: mp-equation-lexer.l
 	$(LEX) $(srcdir)/mp-equation-lexer.l
diff --git a/src/calctool.c b/src/calctool.c
index 230b7d0..5e6388e 100644
--- a/src/calctool.c
+++ b/src/calctool.c
@@ -44,31 +44,6 @@ time_t time();
 static CalculatorVariables calc_state;
 CalculatorVariables *v;
 
-/* Calctools' customised math library error-handling routine. */
-void
-doerr(char *errmes)
-{
-    v->math_error = -MPMATH_ERR;
-    free(v->math_error_text);
-    v->math_error_text = strdup(errmes);
-}
-
-/* Default math library exception handling routine. */
-
-/*ARGSUSED*/
-int
-matherr(struct exception *exc)
-{
-    char text[MAXLINE];
-    
-    /* Translators: Error displayed to user when the math library reports an
-     * error */
-    snprintf(text, MAXLINE, _("Error in math library function %s"), exc->name);
-    doerr(text);
-
-    return 1;
-}
-
 static void
 version()
 {
@@ -79,16 +54,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);
@@ -223,9 +199,6 @@ init_state(void)
     v->tsep          = get_tsep();     /* Locale specific thousands separator. */
     v->tsep_count    = get_tsep_count();
     
-    v->math_error = 0;
-    v->math_error_text = strdup("");
-   
     if (get_int_resource(R_ACCURACY, &i))
         v->accuracy = i;
     else
diff --git a/src/calctool.h b/src/calctool.h
index db6954a..b2cfbc5 100644
--- a/src/calctool.h
+++ b/src/calctool.h
@@ -74,12 +74,8 @@ typedef struct {
     int accuracy;             /* Number of digits precision. */
 
     int error;                /* true if there is a display error */
-    int math_error;           /* Math error */
-    char *math_error_text;    /* Text for math error */
 } CalculatorVariables;
 
 extern CalculatorVariables *v; /* Calctool variables and options. */
 
-void doerr(char *);
-
 #endif /*CALCTOOL_H*/
diff --git a/src/display.c b/src/display.c
index 6dc83db..8eab055 100644
--- a/src/display.c
+++ b/src/display.c
@@ -151,7 +151,7 @@ display_clear(GCDisplay *display)
 }
 
 
-static const char *
+const char *
 display_get_text(GCDisplay *display)
 {
     return get_state(display)->expression;
@@ -540,12 +540,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 FALSE;
+        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
     }
 }
 
@@ -622,14 +623,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 d434a2e..8ed93b6 100644
--- a/src/functions.c
+++ b/src/functions.c
@@ -67,6 +67,53 @@ static Function functions[NFUNCTIONS] = {
 };
 
 
+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')
+        mp_set_from_mp(register_get_value(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_value(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);
+}
+
+
 static void
 do_paste(int cursor_start, int cursor_end, const char *text)
 {
@@ -144,16 +191,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);
     }
 }
@@ -274,21 +321,17 @@ 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;
 
-                    case -PARSER_ERR_TOO_LONG_NUMBER:
-                        message = _("Too long number");
-                        break;
-
                     case -PARSER_ERR_BITWISEOP:
                         /* Translators: Error displayed to user when they
                          * perform an invalid bitwise operation, e.g.
@@ -322,8 +365,8 @@ do_expression(int function, int arg, int cursor_start, int cursor_end)
                        message = _("Unknown function");
                        break;
 
-                    case -MPMATH_ERR:
-                        message = v->math_error_text;
+                    case -PARSER_ERR_MP:
+                        message = mp_get_error();
                         break;
 
                     default:
diff --git a/src/mp-binary.c b/src/mp-binary.c
index 5b6914f..bf5cbc4 100644
--- a/src/mp-binary.c
+++ b/src/mp-binary.c
@@ -2,7 +2,9 @@
 
 #include "mp.h"
 #include "mp-internal.h"
-#include "calctool.h" // FIXME: Used for MAX_DIGITS
+
+// FIXME: Make dynamic
+#define MAX_DIGITS 1000
 
 static char digits[] = "0123456789ABCDEF";
 
diff --git a/src/mp-equation-lexer.l b/src/mp-equation-lexer.l
index 2f99417..a717bba 100644
--- a/src/mp-equation-lexer.l
+++ b/src/mp-equation-lexer.l
@@ -31,7 +31,7 @@
 #include <string.h>
 #include <sys/types.h>
 
-#include "mp-equation.h"
+#include "mp-equation-private.h"
 #include "mp-equation-parser.h"
 
 static int super_atoi(const char *data)
diff --git a/src/mp-equation-parser.y b/src/mp-equation-parser.y
index 4316b2e..42429da 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,10 +66,10 @@ 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.c b/src/mp-equation.c
index 0890ce2..9cffbbd 100644
--- a/src/mp-equation.c
+++ b/src/mp-equation.c
@@ -22,9 +22,7 @@
 
 #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"
 
@@ -33,34 +31,28 @@ 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')
-        mp_set_from_mp(register_get_value(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_value(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 +112,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 +136,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 +150,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;
@@ -165,17 +159,16 @@ mp_equation_parse(const char *expression, MPNumber *result)
     YY_BUFFER_STATE buffer;
 
     if (!(expression && result) || strlen(expression) == 0)
-        return(-EINVAL);
+        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;
+
+    mp_clear_error();
 
     _mp_equation_lex_init_extra(&state, &yyscanner);
     buffer = _mp_equation__scan_string(expression, yyscanner);
@@ -193,8 +186,8 @@ mp_equation_parse(const char *expression, MPNumber *result)
     if (state.error)
         return state.error;
 
-    if (v->math_error)
-        return v->math_error;
+    if (mp_get_error())
+        return -PARSER_ERR_MP;
 
     mp_set_from_mp(&state.ret, result);
 
diff --git a/src/mp-equation.h b/src/mp-equation.h
index e43d768..969f489 100644
--- a/src/mp-equation.h
+++ b/src/mp-equation.h
@@ -26,17 +26,15 @@
 #include "mp.h"
 
 #define PARSER_ERR_INVALID          1
-#define PARSER_ERR_TOO_LONG_NUMBER  2
 #define PARSER_ERR_BITWISEOP        3
 #define PARSER_ERR_MODULUSOP        4
 #define PARSER_ERR_OVERFLOW         5
 #define PARSER_ERR_UNKNOWN_VARIABLE 6
 #define PARSER_ERR_UNKNOWN_FUNCTION 7
+#define PARSER_ERR_MP               9
 
-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;
 
@@ -46,25 +44,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/mp.c b/src/mp.c
index d87a6b0..ba02eb0 100644
--- a/src/mp.c
+++ b/src/mp.c
@@ -27,11 +27,10 @@
 
 #include "mp.h"
 #include "mp-internal.h"
-#include "calctool.h" // FIXME: Required for doerr() and MAXLINE
-
 
 // FIXME: Re-add overflow and underflow detection
 
+char *mp_error = NULL;
 
 /*  THIS ROUTINE IS CALLED WHEN AN ERROR CONDITION IS ENCOUNTERED, AND
  *  AFTER A MESSAGE HAS BEEN WRITTEN TO STDERR.
@@ -39,13 +38,30 @@
 void
 mperr(const char *format, ...)
 {
-    char text[MAXLINE];
+    char text[1024];
     va_list args;
     
     va_start(args, format);
-    vsnprintf(text, MAXLINE, format, args);
+    vsnprintf(text, 1024, format, args);
     va_end(args);
-    doerr(text);
+
+    if (mp_error)
+        free(mp_error);
+    mp_error = strdup(text);
+}
+
+
+const char *mp_get_error()
+{
+    return mp_error;
+}
+
+
+void mp_clear_error()
+{
+    if (mp_error)
+        free(mp_error);
+    mp_error = NULL;
 }
 
 
@@ -631,18 +647,18 @@ L210:
 int
 mp_is_integer(const MPNumber *x)
 {
-    MPNumber MPtt, MP0, MP1;
+    MPNumber t1, t2, t3;
 
     /* This fix is required for 1/3 repiprocal not being detected as an integer */
     /* Multiplication and division by 10000 is used to get around a 
      * limitation to the "fix" for Sun bugtraq bug #4006391 in the 
      * mp_integer_component() routine in mp.c, when the exponent is less than 1.
      */
-    mp_set_from_integer(10000, &MPtt);
-    mp_multiply(x, &MPtt, &MP0);
-    mp_divide(&MP0, &MPtt, &MP0);
-    mp_integer_component(&MP0, &MP1);
-    return mp_is_equal(&MP0, &MP1);
+    mp_set_from_integer(10000, &t3);
+    mp_multiply(x, &t3, &t1);
+    mp_divide(&t1, &t3, &t1);
+    mp_integer_component(&t1, &t2);
+    return mp_is_equal(&t1, &t2);
 
     /* Correct way to check for integer */
     /*int i;
@@ -715,7 +731,7 @@ mpexp(const MPNumber *x, MPNumber *z)
     /* HALVE Q TIMES */
     if (q > 0) {
         int ib, ic;
-        
+
         ib = MP_BASE << 2;
         ic = 1;
         for (i = 1; i <= q; ++i) {
diff --git a/src/mp.h b/src/mp.h
index 377cc57..4cef038 100644
--- a/src/mp.h
+++ b/src/mp.h
@@ -70,6 +70,13 @@ typedef enum
     MP_GRADIANS
 } MPAngleUnit;
 
+/* Returns error string or NULL if no error */
+// FIXME: Global variable
+const char *mp_get_error();
+
+/* Clear any current error */
+void mp_clear_error();
+
 /* Returns:
  *  0 if x == y
  * <0 if x < y
diff --git a/src/register.c b/src/register.c
index 5ea69a6..3c7c346 100644
--- a/src/register.c
+++ b/src/register.c
@@ -115,7 +115,7 @@ void register_init()
 
 
 void
-register_set_value(int index, MPNumber *value)
+register_set_value(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 14aae63..5b2dff3 100644
--- a/src/register.h
+++ b/src/register.h
@@ -25,7 +25,7 @@
 #include "mp.h"
 
 void register_init();
-void register_set_value(int index, MPNumber *value);
+void register_set_value(int index, const MPNumber *value);
 void register_set_name(int index, const char *name);
 const MPNumber *register_get_value(int index);
 const char *register_get_name(int index);
diff --git a/src/unittest.c b/src/unittest.c
index b93b376..bcfd9a7 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,20 +92,21 @@ 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("2", "10â??", 0);
 
-    v->base = 8;
+    options.base = 8;
     test("16434824", "76543210â??", 0);
     
-    v->base = 16;
+    options.base = 16;
     test("18364758544493064720", "FEDCBA9876543210â??â??", 0);
 
-    v->base = 10;
+    options.base = 10;
     test("0â??", "0", 0); test("0â??", "0", 0); test("0", "0", 0); test("0â??â??", "0", 0);
     test("1â??", "1", 0); test("1â??", "1", 0); test("1", "1", 0); test("1â??â??", "1", 0);
     test("2â??", "", -1); test("2â??", "2", 0); test("2", "2", 0); test("2â??â??", "2", 0);
@@ -213,8 +213,8 @@ test_parser()
     test("1÷4", "0.25", 0);
     test("1÷3", "0.333333333", 0);
     test("2÷3", "0.666666667", 0);
-    test("1÷0", "", -20001);
-    test("0÷0", "", -20001);
+    test("1÷0", "", -9);
+    test("0÷0", "", -9);
     
     /* Precision */
     test("1000000000000000â??1000000000000000", "0", 0);
@@ -241,9 +241,9 @@ test_parser()
     test("1!", "1", 0);
     test("5!", "120", 0);
     test("69!", "171122452428141311372468338881272839092270544893520369393648040923257279754140647424000000000000000", 0);
-    test("0.1!", "", -20001);
+    test("0.1!", "", -9);
     test("â??1!", "â??1", 0);
-    test("(â??1)!", "", -20001);
+    test("(â??1)!", "", -9);
     test("â??(1!)", "â??1", 0);
 
     /* Powers */
@@ -254,7 +254,7 @@ test_parser()
     test("2^1", "2", 0);
     test("2^2", "4", 0);
     test("2�¹", "0.5", 0);
-    //test("2â?»", "", -20001); // FIXME: Maybe an error in bison?
+    //test("2â?»", "", -9); // FIXME: Maybe an error in bison?
     test("2^â??1", "0.5", 0);
     test("2^(â??1)", "0.5", 0);
     test("â??10^2", "â??100", 0);
@@ -278,7 +278,7 @@ test_parser()
     test("Sqrt(2)", "1.414213562", 0);
     test("4^0.5", "2", 0);
     test("2^0.5", "1.414213562", 0);
-    test("(â??4)^0.5", "", -20001);
+    test("(â??4)^0.5", "", -9);
     test("(â??8)^(1÷3)", "â??2", 0);
     
     test("0 mod 7", "0", 0);
@@ -300,8 +300,8 @@ test_parser()
     test("abs 1", "1", 0);
     test("abs â??1", "1", 0);
 
-    test("log â??1", "", -20001);
-    test("log 0", "", -20001);
+    test("log â??1", "", -9);
+    test("log 0", "", -9);
     test("log 1", "0", 0);
     test("log 2", "0.301029996", 0);
     test("log 10", "1", 0);
@@ -309,14 +309,14 @@ test_parser()
     test("logâ?? 2", "1", 0);
     test("2 log 2", "0.602059991", 0);
 
-    test("ln â??1", "", -20001);
-    test("ln 0", "", -20001);
+    test("ln â??1", "", -9);
+    test("ln 0", "", -9);
     test("ln 1", "0", 0);
     test("ln 2", "0.693147181", 0);
     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);
@@ -335,7 +335,7 @@ test_parser()
 
     test("tan 0", "0", 0);
     test("tan 10 â?? sin 10÷cos 10", "0", 0);
-    test("tan 90", "", -20001);
+    test("tan 90", "", -9);
     test("tan 10", "0.176326981", 0);    
     test("tan²10", "0.031091204", 0);
 
@@ -363,20 +363,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]