[recipes] Add a parsing function



commit 6590707772dc8a208cddd5fb86eb2e3b90eb6788
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Nov 11 16:51:46 2017 -0500

    Add a parsing function
    
    This function can parse units in the form produced
    by gr_convert_format, which is important to ensure
    that we don't loose data when editing existing
    recipes.

 src/gr-convert-units.c |   88 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/gr-convert-units.h |    1 +
 2 files changed, 89 insertions(+), 0 deletions(-)
---
diff --git a/src/gr-convert-units.c b/src/gr-convert-units.c
index 5b10eb6..b2388f9 100644
--- a/src/gr-convert-units.c
+++ b/src/gr-convert-units.c
@@ -524,3 +524,91 @@ gr_convert_format (GString *s, double amount, GrUnit unit)
 
         gr_convert_format_for_display (s, amount, unit, amount2, unit2);
 }
+
+static gboolean
+parse_unit (const char  *text,
+            double      *number,
+            GrUnit      *unit)
+{
+        char *tmp;
+        g_autofree char *num = NULL;
+
+        tmp = (char *)text;
+        skip_whitespace (&tmp);
+        if (!gr_number_parse (number, &tmp, NULL)) {
+                *unit = GR_UNIT_UNKNOWN;
+        }
+        else {
+                skip_whitespace (&tmp);
+                *unit = gr_unit_parse (&tmp, NULL);
+        }
+
+        return *unit != GR_UNIT_UNKNOWN;
+}
+
+gboolean
+gr_parse_units (const char  *text,
+                double      *amount,
+                GrUnit      *unit)
+{
+        char *p;
+        GSettings *settings = gr_settings_get ();
+
+        if ((p = strchr (text, ',')) != NULL) {
+                g_autofree char *text1 = NULL;
+                g_autofree char *text2 = NULL;
+                double a1, a2;
+                GrUnit u1, u2;
+                GrDimension dim1, dim2;
+
+                text1 = g_strndup (text, p - text);
+                text2 = g_strdup (p + 1);
+
+                if (!parse_unit (text1, &a1, &u1) ||
+                    !parse_unit (text2, &a2, &u2)) {
+                        *amount = 0.0;
+                        *unit = GR_UNIT_UNKNOWN;
+
+                        return FALSE;
+                }
+
+                dim1 = gr_unit_get_dimension (u1);
+                dim2 = gr_unit_get_dimension (u2);
+
+                if (dim1 == GR_DIMENSION_VOLUME &&
+                    dim2 == GR_DIMENSION_VOLUME) {
+                        int preferred;
+
+                        preferred = g_settings_get_enum (settings, "volume-unit");
+                        gr_convert_volume (&a1, &u1, preferred);
+                        gr_convert_volume (&a2, &u2, preferred);
+
+                        *amount = a1 + a2;
+                        *unit = u1;
+
+                        return TRUE;
+                }
+                else if (dim1 == GR_DIMENSION_MASS &&
+                         dim2 == GR_DIMENSION_MASS) {
+                        int preferred;
+
+                        preferred = g_settings_get_enum (settings, "weight-unit");
+                        gr_convert_weight (&a1, &u1, preferred);
+                        gr_convert_weight (&a2, &u2, preferred);
+
+                        *amount = a1 + a2;
+                        *unit = u1;
+
+                        return TRUE;
+                }
+                else {
+                        *amount = 0.0;
+                        *unit = GR_UNIT_UNKNOWN;
+
+                        return FALSE;
+                }
+        }
+        else {
+                return parse_unit (text, amount, unit);
+        }
+}
diff --git a/src/gr-convert-units.h b/src/gr-convert-units.h
index 88f4913..66be903 100644
--- a/src/gr-convert-units.h
+++ b/src/gr-convert-units.h
@@ -50,5 +50,6 @@ void                gr_convert_human_readable           (double *amount, GrUnit
 void                gr_convert_multiple_units           (double *amount1, GrUnit *unit1, double *amount2, 
GrUnit *unit2);
 void                gr_convert_format_for_display       (GString *s, double a1, GrUnit u1, double a2, GrUnit 
u2);
 void                gr_convert_format                   (GString *s, double amount, GrUnit unit);
+gboolean            gr_parse_units                      (const char *text, double *amount, GrUnit *unit);
 
 G_END_DECLS


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