[gcalctool] Test for conversions
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gcalctool] Test for conversions
- Date: Thu, 18 Mar 2010 11:45:49 +0000 (UTC)
commit 1c0413fd1275609a2bdfc3cc4ace940e8bf68726
Author: Robert Ancell <robert ancell gmail com>
Date: Thu Mar 18 22:19:48 2010 +1100
Test for conversions
src/display.c | 158 +------------------------------------------
src/mp-equation-parser.y | 6 +--
src/mp-equation-private.h | 3 +
src/mp-equation.c | 165 +++++++++++++++++++++++++++++++++++++++++++++
src/unittest.c | 33 ++++++++-
5 files changed, 201 insertions(+), 164 deletions(-)
---
diff --git a/src/display.c b/src/display.c
index 07565fd..6f5054f 100644
--- a/src/display.c
+++ b/src/display.c
@@ -807,156 +807,9 @@ set_variable(const char *name, const MPNumber *x, void *data)
static int
-do_convert(const char *units[][2], const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z)
-{
- int x_index, z_index;
- MPNumber x_factor, z_factor;
-
- for (x_index = 0; units[x_index][0] != NULL && strcmp(units[x_index][0], x_units) != 0; x_index++);
- if (units[x_index][0] == NULL)
- return 0;
- for (z_index = 0; units[z_index][0] != NULL && strcmp(units[z_index][0], z_units) != 0; z_index++);
- if (units[z_index][0] == NULL)
- return 0;
-
- mp_set_from_string(units[x_index][1], &x_factor);
- mp_set_from_string(units[z_index][1], &z_factor);
- mp_multiply(x, &x_factor, z);
- mp_divide(z, &z_factor, z);
-
- return 1;
-}
-
-
-static int
convert(const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z, void *data)
-{
- const char *length_units[][2] = {
- {"parsec", "30857000000000000"},
- {"parsecs", "30857000000000000"},
- {"pc", "30857000000000000"},
- {"lightyear", "9460730472580800"},
- {"lightyears", "9460730472580800"},
- {"ly", "9460730472580800"},
- {"au", "149597870691"},
- {"nm", "1852000"},
- {"mile", "1609.344"},
- {"miles", "1609.344"},
- {"mi", "1609.344"},
- {"kilometer", "1000"},
- {"kilometers", "1000"},
- {"km", "1000"},
- {"kms", "1000"},
- {"cable", "219.456"},
- {"cables", "219.456"},
- {"cb", "219.456"},
- {"fathom", "1.8288"},
- {"fathoms", "1.8288"},
- {"ftm", "1.8288"},
- {"meter", "1"},
- {"meters", "1"},
- {"m", "1"},
- {"yard", "0.9144"},
- {"yd", "0.9144"},
- {"foot", "0.3048"},
- {"feet", "0.3048"},
- {"ft", "0.3048"},
- {"inch", "0.0254"},
- {"inches", "0.0254"},
- {"centimeter", "0.01"},
- {"centimeters", "0.01"},
- {"cm", "0.01"},
- {"cms", "0.01"},
- {"millimeter", "0.001"},
- {"millimeters", "0.001"},
- {"mm", "0.001"},
- {"micrometer", "0.000001"},
- {"micrometers", "0.000001"},
- {"um", "0.000001"},
- {"nanometer", "0.000000001"},
- {"nanometers", "0.000000001"},
- {NULL, NULL}
- };
-
- const char *area_units[][2] = {
- {"hectare", "10000"},
- {"hectares", "10000"},
- {"acre", "4046.8564224"},
- {"acres", "4046.8564224"},
- {"m²", "1"},
- {"cm²", "0.001"},
- {NULL, NULL}
- };
-
- const char *volume_units[][2] = {
- {"cm³", "1000"},
- {"gallon", "3.785412"},
- {"gallons", "3.785412"},
- {"gal", "3.785412"},
- {"litre", "1"},
- {"litres", "1"},
- {"liter", "1"},
- {"liters", "1"},
- {"L", "1"},
- {"quart", "0.9463529"},
- {"quarts", "0.9463529"},
- {"qt", "0.9463529"},
- {"pint", "0.4731765"},
- {"pints", "0.4731765"},
- {"pt", "0.4731765"},
- {"millilitre", "0.001"},
- {"millilitres", "0.001"},
- {"milliliter", "0.001"},
- {"milliliters", "0.001"},
- {"mL", "0.001"},
- {"m³", "0.001"},
- {NULL, NULL}
- };
-
- const char *weight_units[][2] = {
- {"tonne", "1000"},
- {"tonnes", "1000"},
- {"kilograms", "1"},
- {"kilogramme", "1"},
- {"kilogrammes", "1"},
- {"kg", "1"},
- {"kgs", "1"},
- {"pound", "0.45359237"},
- {"pounds", "0.45359237"},
- {"lb", "0.45359237"},
- {"ounce", "0.002834952"},
- {"ounces", "0.002834952"},
- {"oz", "0.002834952"},
- {"gram", "0.001"},
- {"grams", "0.001"},
- {"gramme", "0.001"},
- {"grammes", "0.001"},
- {"g", "0.001"},
- {NULL, NULL}
- };
-
- const char *time_units[][2] = {
- {"year", "31557600"},
- {"years", "31557600"},
- {"day", "86400"},
- {"days", "86400"},
- {"hour", "3600"},
- {"hours", "3600"},
- {"minute", "60"},
- {"minutes", "60"},
- {"second", "1"},
- {"seconds", "1"},
- {"s", "1"},
- {"millisecond", "0.001"},
- {"milliseconds", "0.001"},
- {"ms", "0.001"},
- {"microsecond", "0.000001"},
- {"microseconds", "0.000001"},
- {"us", "0.000001"},
- {NULL, NULL}
- };
-
- /* See if currency */
+{
+ /* Update currency if necessary */
if (currency_rates_needs_update())
currency_download_rates();
currency_load_rates();
@@ -965,13 +818,6 @@ convert(const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z
currency_convert(x, currency_get_index(x_units), currency_get_index(z_units), z);
return 1;
}
-
- if (do_convert(length_units, x, x_units, z_units, z) ||
- do_convert(area_units, x, x_units, z_units, z) ||
- do_convert(volume_units, x, x_units, z_units, z) ||
- do_convert(weight_units, x, x_units, z_units, z) ||
- do_convert(time_units, x, x_units, z_units, z))
- return 1;
return 0;
}
diff --git a/src/mp-equation-parser.y b/src/mp-equation-parser.y
index a882695..440741c 100644
--- a/src/mp-equation-parser.y
+++ b/src/mp-equation-parser.y
@@ -124,12 +124,8 @@ static void do_not(yyscan_t yyscanner, const MPNumber *x, MPNumber *z)
static void do_conversion(yyscan_t yyscanner, const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z)
{
- void *data = _mp_equation_get_extra(yyscanner)->options->callback_data;
-
- if (_mp_equation_get_extra(yyscanner)->options->convert == NULL
- || !_mp_equation_get_extra(yyscanner)->options->convert(x, x_units, z_units, z, data)) {
+ if (!_mp_equation_get_extra(yyscanner)->convert(_mp_equation_get_extra(yyscanner), x, x_units, z_units, z))
set_error(yyscanner, PARSER_ERR_UNKNOWN_CONVERSION, NULL);
- }
}
%}
diff --git a/src/mp-equation-private.h b/src/mp-equation-private.h
index 190c71a..7ef96c2 100644
--- a/src/mp-equation-private.h
+++ b/src/mp-equation-private.h
@@ -44,6 +44,9 @@ struct MPEquationParserState {
/* Function to solve functions */
int (*get_function)(MPEquationParserState *state, const char *name, const MPNumber *x, MPNumber *z);
+ /* Function to convert units */
+ int (*convert)(MPEquationParserState *state, const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z);
+
// FIXME: get_operator??
/* Error returned from parser */
diff --git a/src/mp-equation.c b/src/mp-equation.c
index 180fff1..e13f20b 100644
--- a/src/mp-equation.c
+++ b/src/mp-equation.c
@@ -222,6 +222,170 @@ get_function(MPEquationParserState *state, const char *name, const MPNumber *x,
}
+static int
+do_convert(const char *units[][2], const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z)
+{
+ int x_index, z_index;
+ MPNumber x_factor, z_factor;
+
+ for (x_index = 0; units[x_index][0] != NULL && strcmp(units[x_index][0], x_units) != 0; x_index++);
+ if (units[x_index][0] == NULL)
+ return 0;
+ for (z_index = 0; units[z_index][0] != NULL && strcmp(units[z_index][0], z_units) != 0; z_index++);
+ if (units[z_index][0] == NULL)
+ return 0;
+
+ mp_set_from_string(units[x_index][1], &x_factor);
+ mp_set_from_string(units[z_index][1], &z_factor);
+ mp_multiply(x, &x_factor, z);
+ mp_divide(z, &z_factor, z);
+
+ return 1;
+}
+
+
+static int
+convert(MPEquationParserState *state, const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z)
+{
+ const char *length_units[][2] = {
+ {"parsec", "30857000000000000"},
+ {"parsecs", "30857000000000000"},
+ {"pc", "30857000000000000"},
+ {"lightyear", "9460730472580800"},
+ {"lightyears", "9460730472580800"},
+ {"ly", "9460730472580800"},
+ {"au", "149597870691"},
+ {"nm", "1852000"},
+ {"mile", "1609.344"},
+ {"miles", "1609.344"},
+ {"mi", "1609.344"},
+ {"kilometer", "1000"},
+ {"kilometers", "1000"},
+ {"km", "1000"},
+ {"kms", "1000"},
+ {"cable", "219.456"},
+ {"cables", "219.456"},
+ {"cb", "219.456"},
+ {"fathom", "1.8288"},
+ {"fathoms", "1.8288"},
+ {"ftm", "1.8288"},
+ {"meter", "1"},
+ {"meters", "1"},
+ {"m", "1"},
+ {"yard", "0.9144"},
+ {"yd", "0.9144"},
+ {"foot", "0.3048"},
+ {"feet", "0.3048"},
+ {"ft", "0.3048"},
+ {"inch", "0.0254"},
+ {"inches", "0.0254"},
+ {"centimeter", "0.01"},
+ {"centimeters", "0.01"},
+ {"cm", "0.01"},
+ {"cms", "0.01"},
+ {"millimeter", "0.001"},
+ {"millimeters", "0.001"},
+ {"mm", "0.001"},
+ {"micrometer", "0.000001"},
+ {"micrometers", "0.000001"},
+ {"um", "0.000001"},
+ {"nanometer", "0.000000001"},
+ {"nanometers", "0.000000001"},
+ {NULL, NULL}
+ };
+
+ const char *area_units[][2] = {
+ {"hectare", "10000"},
+ {"hectares", "10000"},
+ {"acre", "4046.8564224"},
+ {"acres", "4046.8564224"},
+ {"m²", "1"},
+ {"cm²", "0.001"},
+ {NULL, NULL}
+ };
+
+ const char *volume_units[][2] = {
+ {"cm³", "1000"},
+ {"gallon", "3.785412"},
+ {"gallons", "3.785412"},
+ {"gal", "3.785412"},
+ {"litre", "1"},
+ {"litres", "1"},
+ {"liter", "1"},
+ {"liters", "1"},
+ {"L", "1"},
+ {"quart", "0.9463529"},
+ {"quarts", "0.9463529"},
+ {"qt", "0.9463529"},
+ {"pint", "0.4731765"},
+ {"pints", "0.4731765"},
+ {"pt", "0.4731765"},
+ {"millilitre", "0.001"},
+ {"millilitres", "0.001"},
+ {"milliliter", "0.001"},
+ {"milliliters", "0.001"},
+ {"mL", "0.001"},
+ {"m³", "0.001"},
+ {NULL, NULL}
+ };
+
+ const char *weight_units[][2] = {
+ {"tonne", "1000"},
+ {"tonnes", "1000"},
+ {"kilograms", "1"},
+ {"kilogramme", "1"},
+ {"kilogrammes", "1"},
+ {"kg", "1"},
+ {"kgs", "1"},
+ {"pound", "0.45359237"},
+ {"pounds", "0.45359237"},
+ {"lb", "0.45359237"},
+ {"ounce", "0.002834952"},
+ {"ounces", "0.002834952"},
+ {"oz", "0.002834952"},
+ {"gram", "0.001"},
+ {"grams", "0.001"},
+ {"gramme", "0.001"},
+ {"grammes", "0.001"},
+ {"g", "0.001"},
+ {NULL, NULL}
+ };
+
+ const char *time_units[][2] = {
+ {"year", "31557600"},
+ {"years", "31557600"},
+ {"day", "86400"},
+ {"days", "86400"},
+ {"hour", "3600"},
+ {"hours", "3600"},
+ {"minute", "60"},
+ {"minutes", "60"},
+ {"second", "1"},
+ {"seconds", "1"},
+ {"s", "1"},
+ {"millisecond", "0.001"},
+ {"milliseconds", "0.001"},
+ {"ms", "0.001"},
+ {"microsecond", "0.000001"},
+ {"microseconds", "0.000001"},
+ {"us", "0.000001"},
+ {NULL, NULL}
+ };
+
+ if (do_convert(length_units, x, x_units, z_units, z) ||
+ do_convert(area_units, x, x_units, z_units, z) ||
+ do_convert(volume_units, x, x_units, z_units, z) ||
+ do_convert(weight_units, x, x_units, z_units, z) ||
+ do_convert(time_units, x, x_units, z_units, z))
+ return 1;
+
+ if (state->options->convert)
+ return state->options->convert(x, x_units, z_units, z, state->options->callback_data);
+
+ return 0;
+}
+
+
MPErrorCode
mp_equation_parse(const char *expression, MPEquationOptions *options, MPNumber *result, char **error_token)
{
@@ -240,6 +404,7 @@ mp_equation_parse(const char *expression, MPEquationOptions *options, MPNumber *
state.set_variable = set_variable;
state.function_is_defined = function_is_defined;
state.get_function = get_function;
+ state.convert = convert;
state.error = 0;
mp_clear_error();
diff --git a/src/unittest.c b/src/unittest.c
index e3eb2a6..defb1ab 100644
--- a/src/unittest.c
+++ b/src/unittest.c
@@ -102,6 +102,33 @@ test(char *expression, char *expected, int expected_error)
}
+static void
+test_conversions()
+{
+ memset(&options, 0, sizeof(options));
+ base = 10;
+ options.wordlen = 32;
+ options.angle_units = MP_DEGREES;
+
+ /* Length */
+ test("1 meter in mm", "1000", 0);
+ test("1m in mm", "1000", 0);
+ test("1 inch in cm", "2.54", 0);
+
+ /* Area */
+ test("1m² in mm²", "1000000", 0);
+
+ /* Volume */
+ test("1m³ in mm³", "1000000000", 0);
+
+ /* Weight */
+ test("1 kg in pounds", "2.204622622", 0);
+
+ /* Time */
+ test("1 minute in seconds", "60", 0);
+}
+
+
int
variable_is_defined(const char *name)
{
@@ -129,9 +156,8 @@ set_variable(const char *name, const MPNumber *x, void *data)
{
}
-
void
-test_parser()
+test_equations()
{
memset(&options, 0, sizeof(options));
base = 10;
@@ -645,6 +671,7 @@ unittest()
{
test_mp();
test_numbers();
- test_parser();
+ test_conversions();
+ test_equations();
exit(fails > 0 ? 1 : 0);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]