[gcalctool] Handle powers in convesion units, (e.g. 1m² in mm²)



commit aae08f9fbce94fb1bbb7c46830524f9ca1bcc2c2
Author: Robert Ancell <robert ancell gmail com>
Date:   Thu Mar 18 22:45:37 2010 +1100

    Handle powers in convesion units, (e.g. 1m² in mm²)

 NEWS                     |    6 ++++++
 src/mp-equation-parser.y |   30 ++++++++++++++++++++++++++++--
 src/mp-equation.c        |    6 ++++--
 3 files changed, 38 insertions(+), 4 deletions(-)
---
diff --git a/NEWS b/NEWS
index aaf2252..8c0e455 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,12 @@
  
 Overview of changes in gcalctool 5.29.92
 
+    * Fix errors in variable exponents (e.g. xy²)
+
+    * Handle powers in convesion units, (e.g. 1m² in mm²)
+ 
+Overview of changes in gcalctool 5.29.92
+
     * Add shortcuts to base buttons (Ctrl+B, Ctrl+O, Ctrl+D, Ctrl+H)
 
     * Convert number in display if it has a base and a base button is pressed
diff --git a/src/mp-equation-parser.y b/src/mp-equation-parser.y
index 440741c..0f019de 100644
--- a/src/mp-equation-parser.y
+++ b/src/mp-equation-parser.y
@@ -122,6 +122,27 @@ static void do_not(yyscan_t yyscanner, const MPNumber *x, MPNumber *z)
     mp_not(x, _mp_equation_get_extra(yyscanner)->options->wordlen, z);
 }
 
+static char *make_unit(const char *name, int power)
+{
+    char *name2;
+
+    // FIXME: Hacky
+    if (power == 2) {
+        name2 = malloc(sizeof(char) * (strlen(name) + strlen("²") + 1));
+        sprintf(name2, "%s²", name);
+    }
+    else if (power == 3) {
+        name2 = malloc(sizeof(char) * (strlen(name) + strlen("³") + 1));
+        sprintf(name2, "%s³", name);
+    }
+    else {
+        name2 = malloc(sizeof(char) * (strlen(name) + strlen("?") + 1));
+        sprintf(name2, "%s?", name);
+    }
+    
+    return name2;
+}
+
 static void do_conversion(yyscan_t yyscanner, const MPNumber *x, const char *x_units, const char *z_units, MPNumber *z)
 {
     if (!_mp_equation_get_extra(yyscanner)->convert(_mp_equation_get_extra(yyscanner), x, x_units, z_units, z))
@@ -158,6 +179,7 @@ static void do_conversion(yyscan_t yyscanner, const MPNumber *x, const char *x_u
 %left tIN
 
 %type <int_t> exp variable term
+%type <name> unit
 %start statement
 
 %%
@@ -166,10 +188,14 @@ statement:
   exp { set_result(yyscanner, &$1); }
 | exp '=' { set_result(yyscanner, &$1); }
 | tVARIABLE '=' exp {set_variable(yyscanner, $1, &$3); set_result(yyscanner, &$3); }
-| tNUMBER tVARIABLE tIN tVARIABLE { MPNumber t; do_conversion(yyscanner, &$1, $2, $4, &t); set_result(yyscanner, &t); free($2); free($4); }
-| tVARIABLE tIN tVARIABLE { MPNumber x, t; mp_set_from_integer(1, &x); do_conversion(yyscanner, &x, $1, $3, &t); set_result(yyscanner, &t); free($1); free($3); }
+| tNUMBER unit tIN unit { MPNumber t; do_conversion(yyscanner, &$1, $2, $4, &t); set_result(yyscanner, &t); free($2); free($4); }
+| unit tIN unit { MPNumber x, t; mp_set_from_integer(1, &x); do_conversion(yyscanner, &x, $1, $3, &t); set_result(yyscanner, &t); free($1); free($3); }
 ;
 
+unit:
+  tVARIABLE {$$ = $1;}
+| tVARIABLE tSUPNUM {$$ = make_unit($1, $2); free($1);}
+
 /* |x| gets confused and thinks = |x|(...||) */
 
 exp:
diff --git a/src/mp-equation.c b/src/mp-equation.c
index e13f20b..0399484 100644
--- a/src/mp-equation.c
+++ b/src/mp-equation.c
@@ -301,11 +301,12 @@ convert(MPEquationParserState *state, const MPNumber *x, const char *x_units, co
         {"acres",            "4046.8564224"},
         {"m²",                  "1"},
         {"cm²",                 "0.001"},
+        {"mm²",                 "0.000001"},
         {NULL, NULL}
     };
 
     const char *volume_units[][2] = {
-        {"cm³",              "1000"},
+        {"m³",               "1000"},
         {"gallon",              "3.785412"},
         {"gallons",             "3.785412"},
         {"gal",                 "3.785412"},
@@ -325,7 +326,8 @@ convert(MPEquationParserState *state, const MPNumber *x, const char *x_units, co
         {"milliliter",          "0.001"},
         {"milliliters",         "0.001"},
         {"mL",                  "0.001"},
-        {"m³",                  "0.001"},
+        {"cm³",                 "0.001"},
+        {"mm³",                 "0.000001"},
         {NULL, NULL}
     };
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]