[recipes] ingredients list: Use the new number parser
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [recipes] ingredients list: Use the new number parser
- Date: Fri, 23 Dec 2016 23:59:55 +0000 (UTC)
commit c0ef56b744352d401d54bc245e09403004faf24b
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Dec 23 18:58:55 2016 -0500
ingredients list: Use the new number parser
All the number-related code has been moved over now.
src/gr-ingredients-list.c | 240 ++-------------------------------------------
1 files changed, 9 insertions(+), 231 deletions(-)
---
diff --git a/src/gr-ingredients-list.c b/src/gr-ingredients-list.c
index b937b5d..abba793 100644
--- a/src/gr-ingredients-list.c
+++ b/src/gr-ingredients-list.c
@@ -25,6 +25,7 @@
#include "gr-ingredients-list.h"
#include "gr-ingredient.h"
+#include "gr-number.h"
/* Parsing ingredients is tricky business. We operate under the following
@@ -38,9 +39,7 @@
typedef struct
{
- gboolean fraction;
- int num, denom;
- gdouble value;
+ GrNumber amount;
gchar *unit;
gchar *name;
gchar *segment;
@@ -72,168 +71,6 @@ skip_whitespace (char **line)
}
typedef struct {
- int num;
- int denom;
- const char *ch;
-} VulgarFraction;
-
-static VulgarFraction fractions[] = {
- { 1, 4, "¼" },
- { 1, 2, "½" },
- { 3, 4, "¾" },
- { 1, 7, "⅐" },
- { 1, 9, "⅑" },
- { 1, 10, "⅒" },
- { 1, 3, "⅓" },
- { 2, 3, "⅔" },
- { 1, 5, "⅕" },
- { 2, 5, "⅖" },
- { 3, 5, "⅗" },
- { 4, 5, "⅘" },
- { 1, 6, "⅙" },
- { 5, 6, "⅚" },
- { 1, 8, "⅛" },
- { 3, 8, "⅜" },
- { 5, 8, "⅝" },
- { 7, 8, "⅞" }
-};
-
-static gboolean
-parse_as_vulgar_fraction (Ingredient *ing,
- char **string,
- GError **error)
-{
- int i;
-
- for (i = 0; i < G_N_ELEMENTS (fractions); i++) {
- const char *vf = fractions[i].ch;
- if (g_str_has_prefix (*string, vf) &&
- g_ascii_isspace ((*string)[strlen (vf)])) {
-
- ing->fraction = TRUE;
- ing->num = fractions[i].num;
- ing->denom = fractions[i].denom;
-
- *string += strlen (vf);
-
- return TRUE;
- }
- }
-
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Could not parse %s as a fraction"), *string);
- return FALSE;
-}
-
-static gboolean
-parse_as_fraction (Ingredient *ing,
- char **string,
- GError **error)
-{
- guint64 num, denom;
- char *end = NULL;
-
- num = g_ascii_strtoull (*string, &end, 10);
- if (end[0] != '/') {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Could not parse %s as a fraction"), *string);
- return FALSE;
- }
- *string = end + 1;
-
- denom = g_ascii_strtoull (*string, &end, 10);
- if (end != NULL && end[0] != '\0' && !g_ascii_isspace (end[0])) {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Could not parse %s as a fraction"), *string);
- return FALSE;
- }
- *string = end;
-
- ing->fraction = TRUE;
- ing->num = num;
- ing->denom = denom;
-
- return TRUE;
-}
-
-typedef struct {
- const char *string;
- int value;
-} NumberForm;
-
-static NumberForm numberforms[] = {
- { NC_("number", "a dozen"), 12 },
- { NC_("number", "a"), 1 },
- { NC_("number", "an"), 1 },
- { NC_("number", "one"), 1 },
- { NC_("number", "two"), 2 },
- { NC_("number", "three"), 3 },
- { NC_("number", "four"), 4 },
- { NC_("number", "five"), 5 },
- { NC_("number", "six"), 6 },
- { NC_("number", "seven"), 7 },
- { NC_("number", "eight"), 8 },
- { NC_("number", "nine"), 9 },
- { NC_("number", "ten"), 10 },
- { NC_("number", "eleven"), 11 },
- { NC_("number", "twelve"), 12 }
-};
-
-static gboolean
-parse_as_number (Ingredient *ing,
- char **string,
- GError **error)
-{
- double value;
- gint64 ival;
- char *end = NULL;
- int i;
-
- for (i = 0; i < G_N_ELEMENTS (numberforms); i++) {
- const char *nf;
-
- nf = g_dpgettext2 (NULL, "number", numberforms[i].string);
- if (g_str_has_prefix (*string, nf) &&
- g_ascii_isspace ((*string)[strlen (nf)])) {
- ing->fraction = TRUE;
- ing->num = numberforms[i].value;
- ing->denom = 1;
- *string += strlen (nf);
- return TRUE;
- }
- }
-
- if (parse_as_vulgar_fraction (ing, string, error))
- return TRUE;
-
- ival = g_ascii_strtoll (*string, &end, 10);
- if (end == NULL || end[0] == '\0' || g_ascii_isspace (end[0])) {
- ing->fraction = TRUE;
- ing->num = ival;
- ing->denom = 1;
- *string = end;
- return TRUE;
- }
-
- if (strchr (*string, '/'))
- return parse_as_fraction (ing, string, error);
-
- value = g_strtod (*string, &end);
-
- if (end != NULL && end[0] != '\0' && !g_ascii_isspace (end[0])) {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- _("Could not parse %s as a number"), *string);
- return FALSE;
- }
-
- *string = end;
- ing->fraction = FALSE;
- ing->value = value;
-
- return TRUE;
-}
-
-typedef struct {
const char *unit;
const char *names[4];
} Unit;
@@ -294,7 +131,7 @@ gr_ingredients_list_add_one (GrIngredientsList *ingredients,
line = g_strstrip (line);
- if (!parse_as_number (ing, &line, error)) {
+ if (!gr_number_parse (&ing->amount, &line, error)) {
ingredient_free (ing);
return FALSE;
}
@@ -399,76 +236,17 @@ gr_ingredients_list_validate (const char *text,
return gr_ingredients_list_populate (ingredients, text, error);
}
-static int
-gcd (int m, int n)
-{
- int r;
-
- if (m == 0 && n == 0)
- return -1;
-
- if (m < 0) m = -m;
- if (n < 0) n = -n;
-
- while (n) {
- r = m % n;
- m = n;
- n = r;
- }
-
- return m;
-}
-
-static char *
-format_fraction (int num, int denom)
-{
- int i;
-
- for (i = 0; i < G_N_ELEMENTS (fractions); i++) {
- if (fractions[i].num == num && fractions[i].denom == denom)
- return g_strdup (fractions[i].ch);
- }
-
- return g_strdup_printf ("%d/%d", num, denom);
-}
-
-static char *
-format_scaled_number (Ingredient *ing, int num, int denom)
-{
- if (ing->fraction) {
- int n = ing->num * num;
- int d = ing->denom * denom;
- int g = gcd (n, d);
- int integral;
- g_autofree char *fraction = NULL;
-
- n = n / g;
- d = d / g;
-
- if (d == 1)
- return g_strdup_printf ("%d", n);
- else {
- integral = n / d;
- fraction = format_fraction (n % d, d);
- if (integral == 0)
- return g_strdup_printf ("%s", fraction);
- else
- return g_strdup_printf ("%d %s", integral, fraction);
- }
- }
- else {
- double value = ing->value * num / denom;
-
- return g_strdup_printf ("%g", value);
- }
-}
-
static void
ingredient_scale_unit (Ingredient *ing, int num, int denom, GString *s)
{
g_autofree char *scaled = NULL;
+ GrNumber *snum;
+
+ snum = gr_number_new_fraction (num, denom);
+ gr_number_multiply (&ing->amount, snum, snum);
+ scaled = gr_number_format (snum);
+ g_free (snum);
- scaled = format_scaled_number (ing, num, denom);
g_string_append (s, scaled);
if (ing->unit) {
g_string_append (s, " ");
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]