[gcalctool/gnome-2-32] Fix broken thousands separators code (Bug 628908)



commit d9c7ee8689bc27ac40d4de2ec61fa2e0ba69726c
Author: Robert Ancell <robert ancell canonical com>
Date:   Thu Oct 14 12:26:23 2010 +1100

    Fix broken thousands separators code (Bug 628908)

 NEWS                 |    4 +
 src/gcalccmd.c       |    2 +-
 src/gcalctool.c      |    2 +-
 src/math-buttons.c   |   30 +++++---
 src/math-equation.c  |  214 +++++++++++++++++++++++++++++++++++++++----------
 src/math-equation.h  |    6 +-
 src/math-variables.c |    2 +-
 src/mp-binary.c      |    6 +-
 src/mp-convert.c     |   14 ++--
 src/mp.h             |    5 +-
 src/unittest.c       |    2 +-
 11 files changed, 214 insertions(+), 73 deletions(-)
---
diff --git a/NEWS b/NEWS
index 9481a8b..f82d684 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,10 @@
 
 Overview of changes in gcalctool 5.32.0
 
+    * Fix broken thousands separators code (Bug 628908)
+
+Overview of changes in gcalctool 5.32.0
+
     * Updated translations
 
 Overview of changes in gcalctool 5.31.91
diff --git a/src/gcalccmd.c b/src/gcalccmd.c
index 9af9a58..a533c74 100644
--- a/src/gcalccmd.c
+++ b/src/gcalccmd.c
@@ -48,7 +48,7 @@ solve(const char *equation)
     else if (ret)        
         fprintf(stderr, "Error %d\n", ret);
     else {
-        mp_cast_to_string(&z, 10, 10, 9, 1, result_str, MAXLINE);
+        mp_cast_to_string(&z, 10, 10, 9, 1, '.', result_str, MAXLINE);
         printf("%s\n", result_str);
     }
 }
diff --git a/src/gcalctool.c b/src/gcalctool.c
index bc2f6ba..65d6a91 100644
--- a/src/gcalctool.c
+++ b/src/gcalctool.c
@@ -61,7 +61,7 @@ solve(const char *equation)
         exit(1);
     }
     else {
-        mp_cast_to_string(&result, 10, 10, 9, 1, result_str, 1024);
+        mp_cast_to_string(&result, 10, 10, 9, 1, '.', result_str, 1024);
         printf("%s\n", result_str);
         exit(0);
     }
diff --git a/src/math-buttons.c b/src/math-buttons.c
index 1978ca2..38009f3 100644
--- a/src/math-buttons.c
+++ b/src/math-buttons.c
@@ -422,10 +422,10 @@ update_angle_label (MathButtons *buttons)
             mp_set_from_mp(&x, &input);
             mp_set_from_integer(mp_is_negative(&input) ? -1 : 1, &fraction);
         }
-        mp_cast_to_string(&input, 10, 10, 2, false, input_text, 1024);
+        mp_cast_to_string(&input, 10, 10, 2, false, '.', input_text, 1024);
 
         mp_multiply_integer(&fraction, 360, &output);
-        mp_cast_to_string(&output, 10, 10, 2, false, output_text, 1024);
+        mp_cast_to_string(&output, 10, 10, 2, false, '.', output_text, 1024);
         label = g_strdup_printf(_("%s radians = %s degrees"), input_text, output_text);
         break;
     case MP_GRADIANS:
@@ -442,10 +442,10 @@ update_angle_label (MathButtons *buttons)
             mp_set_from_integer(mp_is_negative(&input) ? -1 : 1, &fraction);
         }
 
-        mp_cast_to_string(&input, 10, 10, 2, false, input_text, 1024);
+        mp_cast_to_string(&input, 10, 10, 2, false, '.', input_text, 1024);
 
         mp_multiply_integer(&fraction, 360, &output);
-        mp_cast_to_string(&output, 10, 10, 2, false, output_text, 1024);
+        mp_cast_to_string(&output, 10, 10, 2, false, '.', output_text, 1024);
         label = g_strdup_printf(_("%s gradians = %s degrees"), input_text, output_text);
         break;
     }
@@ -543,8 +543,8 @@ update_currency_label(MathButtons *buttons)
         const char *source_symbol, *target_symbol;
         int i;
 
-        mp_cast_to_string(&x, 10, 10, 2, false, input_text, 1024);
-        mp_cast_to_string(&value, 10, 10, 2, false, output_text, 1024);
+        mp_cast_to_string(&x, 10, 10, 2, false, '.', input_text, 1024);
+        mp_cast_to_string(&value, 10, 10, 2, false, '.', output_text, 1024);
 
         for (i = 0; strcmp(math_equation_get_source_currency(buttons->priv->equation), currency_names[i].short_name) != 0; i++);
         source_symbol = currency_names[i].symbol;
@@ -854,16 +854,26 @@ load_mode(MathButtons *buttons, ButtonMode mode)
         name = g_strdup_printf("calc_%d_button", i);
         button = GET_WIDGET(builder, name);
         if (button) {
+            gchar buffer[7];
+            gint len;
+
             g_object_set_data(G_OBJECT(button), "calc_digit", GINT_TO_POINTER(i));
             set_tint(button, &buttons->priv->color_numbers, 1);
-            gtk_button_set_label(GTK_BUTTON(button), math_equation_get_digit_text(buttons->priv->equation, i));
+            len = g_unichar_to_utf8(math_equation_get_digit_text(buttons->priv->equation, i), buffer);
+            buffer[len] = '\0';
+            gtk_button_set_label(GTK_BUTTON(button), buffer);
         }
         g_free(name);
     }
     widget = GET_WIDGET(builder, "calc_numeric_point_button");
-    if (widget)
-        gtk_button_set_label(GTK_BUTTON(widget), math_equation_get_numeric_point_text(buttons->priv->equation));
-  
+    if (widget) {
+        gchar buffer[7];
+        gint len;
+        len = g_unichar_to_utf8(math_equation_get_numeric_point_text(buttons->priv->equation), buffer);
+        buffer[len] = '\0';
+        gtk_button_set_label(GTK_BUTTON(widget), buffer);
+    }
+
     widget = GET_WIDGET(builder, "calc_superscript_button");
     if (widget) {
         buttons->priv->superscript_toggles = g_list_append(buttons->priv->superscript_toggles, widget);
diff --git a/src/math-equation.c b/src/math-equation.c
index 1cc033d..9e44e3b 100644
--- a/src/math-equation.c
+++ b/src/math-equation.c
@@ -83,15 +83,15 @@ struct MathEquationPrivate
     NumberMode number_mode;   /* ??? */
     gboolean can_super_minus; /* TRUE if entering minus can generate a superscript minus */
 
-    const char *digits[16];   /* Localized digit values */
-    const char *radix;        /* Locale specific radix string. */
-    const char *tsep;         /* Locale specific thousands separator. */
+    gunichar digits[16];      /* Localized digits */
+    gunichar radix;           /* Locale specific radix. */
+    gunichar tsep;            /* Locale specific thousands separator. */
     gint tsep_count;          /* Number of digits between separator. */
 
     GtkTextMark *ans_start, *ans_end;
 
     MathEquationState state;  /* Equation state */
-    GList *undo_stack;           /* History of expression mode states */
+    GList *undo_stack;        /* History of expression mode states */
     GList *redo_stack;
     gboolean in_undo_operation;
   
@@ -228,10 +228,10 @@ reformat_base(MathEquation *equation, gint old_base)
         }
         else if (in_number) {
             /* Allow one radix inside a number */
-            if (!have_radix && base < 0 && strncmp(read_iter, equation->priv->radix, strlen(equation->priv->radix)) == 0) {
+            if (!have_radix && base < 0 && c == equation->priv->radix) {
                 have_radix = TRUE;
-                read_iter += strlen(equation->priv->radix);
-                offset += g_utf8_strlen(equation->priv->radix, -1);
+                read_iter = g_utf8_next_char(read_iter);
+                offset++;
                 continue;
             }
 
@@ -296,29 +296,108 @@ reformat_base(MathEquation *equation, gint old_base)
 }
 
 
+static gint
+count_digits(MathEquation *equation, const gchar *text)
+{
+    const gchar *read_iter;
+    gint count = 0;
+
+    read_iter = text;
+    while (*read_iter != '\0') {
+        if (!g_unichar_isdigit(g_utf8_get_char(read_iter)))
+            return count;
+
+        read_iter = g_utf8_next_char(read_iter);
+
+        /* Allow a thousands separator between digits follow a digit */
+        if (g_utf8_get_char(read_iter) == equation->priv->tsep) {
+            read_iter = g_utf8_next_char(read_iter);
+            if (!g_unichar_isdigit(g_utf8_get_char(read_iter)))
+                return count;
+        }
+
+        count++;
+    }
+
+    return count;
+}
+
+
 static void
 reformat_separators(MathEquation *equation)
 {
-#if 0
     gchar *text, *read_iter;
-    gboolean in_number = FALSE, in_fraction = FALSE;
+    gint ans_start, ans_end;
+    gint offset, digit_offset = 0;
+    gboolean in_number = FALSE, in_radix = FALSE, last_is_tsep = FALSE;
 
-    text = math_equation_get_display(equation);
+    equation->priv->in_undo_operation = TRUE;
+    equation->priv->in_reformat = TRUE;
 
-    /* Find numbers in display, and modify if necessary */
-    read_iter = text;
-    while(*read_iter != '\0') {
+    text = math_equation_get_display(equation);
+    get_ans_offsets(equation, &ans_start, &ans_end);
+    for (read_iter = text, offset = 0; *read_iter != '\0'; read_iter = g_utf8_next_char(read_iter), offset++) {
         gunichar c;
-      
+        gboolean expect_tsep;
+
+        /* See what digit this character is */
         c = g_utf8_get_char(read_iter);
 
-        if (strncmp(read_iter, equation->priv->tsep, strlen(equation->priv->tsep)) == 0)
-            ;
-        read_iter = g_utf8_next_char(read_iter);
+        expect_tsep = equation->priv->show_tsep &&
+                      in_number && !in_radix && !last_is_tsep &&
+                      digit_offset > 0 && digit_offset % equation->priv->tsep_count == 0;
+        last_is_tsep = FALSE;
+
+        /* Don't mess with ans */
+        if (offset >= ans_start && offset <= ans_end) {
+            in_number = in_radix = FALSE;
+            continue;
+        }
+        if (g_unichar_isdigit(c)) {
+            if (!in_number)
+                digit_offset = count_digits(equation, read_iter);
+            in_number = TRUE;
+
+            /* Expected a thousands separator between these digits - insert it */
+            if (expect_tsep) {
+                GtkTextIter iter;
+                gchar buffer[7];
+                gint len;
+
+                gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(equation), &iter, offset);
+                len = g_unichar_to_utf8(equation->priv->tsep, buffer);
+                buffer[len] = '\0';
+                gtk_text_buffer_insert(GTK_TEXT_BUFFER(equation), &iter, buffer, -1);
+                offset++;
+                last_is_tsep = TRUE;
+            }
+
+            digit_offset--;
+        }
+        else if (c == equation->priv->radix) {
+            in_number = in_radix = TRUE;
+        }
+        else if (c == equation->priv->tsep) {
+            /* Didn't expect thousands separator - delete it */
+            if (!expect_tsep) {
+                GtkTextIter start, end;
+                gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(equation), &start, offset);
+                gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(equation), &end, offset + 1);
+                gtk_text_buffer_delete(GTK_TEXT_BUFFER(equation), &start, &end);
+                offset--;
+            }
+            else
+                last_is_tsep = TRUE;            
+        }
+        else {
+            in_number = in_radix = FALSE;
+        }
     }
 
     g_free(text);
-#endif
+
+    equation->priv->in_reformat = FALSE;
+    equation->priv->in_undo_operation = FALSE;
 }
 
 
@@ -535,21 +614,22 @@ math_equation_redo(MathEquation *equation)
 }
 
 
-const gchar *
+gunichar
 math_equation_get_digit_text(MathEquation *equation, guint digit)
 {
     return equation->priv->digits[digit];
 }
 
 
-const gchar *
+gunichar
 math_equation_get_numeric_point_text(MathEquation *equation)
 {
     return equation->priv->radix;
 }
 
 
-const gchar *math_equation_get_thousands_separator_text(MathEquation *equation)
+gunichar 
+math_equation_get_thousands_separator_text(MathEquation *equation)
 {
     return equation->priv->tsep;
 }
@@ -780,19 +860,52 @@ math_equation_get_display(MathEquation *equation)
 gchar *
 math_equation_get_equation(MathEquation *equation)
 {
-    char *text, *t;
-    gint ans_start, ans_end;
+    gchar *text;
+    GString *eq_text;
+    gint ans_start = -1, ans_end = -1, offset;
+    const gchar *read_iter;
+    gboolean last_is_digit = FALSE;
 
     text = math_equation_get_display(equation);
+    eq_text = g_string_sized_new(strlen(text));
+
+    if (equation->priv->ans_start)
+        get_ans_offsets(equation, &ans_start, &ans_end);
 
-    /* No ans to substitute */
-    if(!equation->priv->ans_start)
-        return text;
+    for (read_iter = text, offset = 0; *read_iter != '\0'; read_iter = g_utf8_next_char(read_iter), offset++) {
+        gunichar c;
+        gboolean is_digit, next_is_digit;
 
-    get_ans_offsets(equation, &ans_start, &ans_end);
-    t = g_strdup_printf("%.*sans%s", (int)(g_utf8_offset_to_pointer(text, ans_start) - text), text, g_utf8_offset_to_pointer(text, ans_end));
+        c = g_utf8_get_char(read_iter);
+        is_digit = g_unichar_isdigit(c);
+        next_is_digit = g_unichar_isdigit(g_utf8_get_char(g_utf8_next_char(read_iter)));
+
+        /* Replace ans text with variable */
+        if (offset == ans_start) { 
+             g_string_append(eq_text, "ans");
+             read_iter = g_utf8_offset_to_pointer(read_iter, ans_end - ans_start - 1);
+             offset += ans_end - ans_start - 1;
+             is_digit = FALSE;
+             continue;
+        }
+
+        /* Ignore thousands separators */
+        if (c == equation->priv->tsep && last_is_digit && next_is_digit)
+            ;
+        /* Substitute radix character */
+        else if (c == equation->priv->radix && (last_is_digit || next_is_digit))
+            g_string_append_unichar(eq_text, '.');
+        else
+            g_string_append_unichar(eq_text, c);
+
+        last_is_digit = is_digit;
+    }
     g_free(text);
-    return t;
+
+    text = eq_text->str;
+    g_string_free(eq_text, FALSE);
+
+    return text;
 }
 
 
@@ -911,8 +1024,6 @@ math_equation_insert(MathEquation *equation, const gchar *text)
     if (strstr("â?»â?°Â¹Â²Â³â?´â?µâ?¶â?·â?¸â?¹â??â??â??â??â??â??â??â??â??â??", text) == NULL)
         math_equation_set_number_mode(equation, NORMAL);
 
-    // FIXME: Add thousands separators
-
     gtk_text_buffer_delete_selection(GTK_TEXT_BUFFER(equation), FALSE, FALSE);
     gtk_text_buffer_insert_at_cursor(GTK_TEXT_BUFFER(equation), text, -1);
 }
@@ -924,8 +1035,13 @@ math_equation_insert_digit(MathEquation *equation, guint digit)
     static const char *subscript_digits[] = {"â??", "â??", "â??", "â??", "â??", "â??", "â??", "â??", "â??", "â??", NULL};
     static const char *superscript_digits[] = {"�", "¹", "²", "³", "�", "�", "�", "�", "�", "�", NULL};
 
-    if (equation->priv->number_mode == NORMAL || digit >= 10)
-        math_equation_insert(equation, math_equation_get_digit_text(equation, digit));
+    if (equation->priv->number_mode == NORMAL || digit >= 10) {
+        gchar buffer[7];
+        gint len;
+        len = g_unichar_to_utf8(math_equation_get_digit_text(equation, digit), buffer);
+        buffer[len] = '\0';
+        math_equation_insert(equation, buffer);
+    }
     else if (equation->priv->number_mode == SUPERSCRIPT)
         math_equation_insert(equation, superscript_digits[digit]);
     else if (equation->priv->number_mode == SUBSCRIPT)
@@ -936,7 +1052,11 @@ math_equation_insert_digit(MathEquation *equation, guint digit)
 void
 math_equation_insert_numeric_point(MathEquation *equation)
 {
-    math_equation_insert(equation, math_equation_get_numeric_point_text(equation));
+    gchar buffer[7];
+    gint len;
+    len = g_unichar_to_utf8(math_equation_get_numeric_point_text(equation), buffer);
+    buffer[len] = '\0';
+    math_equation_insert(equation, buffer);
 }
 
 
@@ -1276,13 +1396,13 @@ display_make_number(MathEquation *equation, char *target, int target_len, const
 {
     switch(equation->priv->format) {
     case FIX:
-        mp_cast_to_string(x, equation->priv->base, equation->priv->base, equation->priv->accuracy, !equation->priv->show_zeroes, target, target_len);
+        mp_cast_to_string(x, equation->priv->base, equation->priv->base, equation->priv->accuracy, !equation->priv->show_zeroes, equation->priv->radix, target, target_len);
         break;
     case SCI:
-        mp_cast_to_exponential_string(x, equation->priv->base, equation->priv->base, equation->priv->accuracy, !equation->priv->show_zeroes, false, target, target_len);
+        mp_cast_to_exponential_string(x, equation->priv->base, equation->priv->base, equation->priv->accuracy, !equation->priv->show_zeroes, equation->priv->radix, false, target, target_len);
         break;
     case ENG:
-        mp_cast_to_exponential_string(x, equation->priv->base, equation->priv->base, equation->priv->accuracy, !equation->priv->show_zeroes, true, target, target_len);
+        mp_cast_to_exponential_string(x, equation->priv->base, equation->priv->base, equation->priv->accuracy, !equation->priv->show_zeroes, equation->priv->radix, true, target, target_len);
         break;
     }
 }
@@ -1579,8 +1699,8 @@ pre_insert_text_cb (MathEquation  *equation,
 static gboolean
 on_delete(MathEquation *equation)
 {
-  equation->priv->in_delete = FALSE;  
-  return FALSE;
+    equation->priv->in_delete = FALSE;  
+    return FALSE;
 }
 
 
@@ -1624,6 +1744,10 @@ insert_text_cb (MathEquation  *equation,
         return;
 
     equation->priv->state.entered_multiply = strcmp(text, "Ã?") == 0;
+
+    /* Update thousands separators */
+    reformat_separators(equation);
+
     g_object_notify(G_OBJECT(equation), "display");
 }
 
@@ -1636,6 +1760,9 @@ delete_range_cb (MathEquation  *equation,
 {
     if (equation->priv->in_reformat)
         return;
+  
+    /* Update thousands separators */
+    reformat_separators(equation);  
 
     // FIXME: A replace will emit this both for delete-range and insert-text, can it be avoided?
     g_object_notify(G_OBJECT(equation), "display");
@@ -1668,20 +1795,19 @@ math_equation_init(MathEquation *equation)
     for (i = 0; i < 16; i++) {
         if (use_default_digits || digits[i] == NULL) {
             use_default_digits = TRUE;
-            equation->priv->digits[i] = strdup(default_digits[i]);
+            equation->priv->digits[i] = g_utf8_get_char(default_digits[i]);
         }
         else
-            equation->priv->digits[i] = strdup(digits[i]);
+            equation->priv->digits[i] = g_utf8_get_char(digits[i]);
     }
     g_strfreev(digits);
 
     setlocale(LC_NUMERIC, "");
 
     radix = nl_langinfo(RADIXCHAR);
-    equation->priv->radix = radix ? g_locale_to_utf8(radix, -1, NULL, NULL, NULL) : g_strdup(".");
+    equation->priv->radix = radix ? g_utf8_get_char(g_locale_to_utf8(radix, -1, NULL, NULL, NULL)) : '.';
     tsep = nl_langinfo(THOUSEP);
-    equation->priv->tsep = tsep ? g_locale_to_utf8(tsep, -1, NULL, NULL, NULL) : g_strdup(",");
-
+    equation->priv->tsep = tsep ? g_utf8_get_char(g_locale_to_utf8(tsep, -1, NULL, NULL, NULL)) : ',';
     equation->priv->tsep_count = 3;
   
     equation->priv->variables = math_variables_new();
diff --git a/src/math-equation.h b/src/math-equation.h
index e93137d..3a8c7b5 100644
--- a/src/math-equation.h
+++ b/src/math-equation.h
@@ -60,9 +60,9 @@ MathEquation *math_equation_new(void);
 
 MathVariables *math_equation_get_variables(MathEquation *equation);
 
-const gchar *math_equation_get_digit_text(MathEquation *equation, guint digit);
-const gchar *math_equation_get_numeric_point_text(MathEquation *equation);
-const gchar *math_equation_get_thousands_separator_text(MathEquation *equation);
+gunichar math_equation_get_digit_text(MathEquation *equation, guint digit);
+gunichar math_equation_get_numeric_point_text(MathEquation *equation);
+gunichar math_equation_get_thousands_separator_text(MathEquation *equation);
 
 void math_equation_set_status(MathEquation *equation, const gchar *status);
 const gchar *math_equation_get_status(MathEquation *equation);
diff --git a/src/math-variables.c b/src/math-variables.c
index b4f7720..7d5d4fd 100644
--- a/src/math-variables.c
+++ b/src/math-variables.c
@@ -97,7 +97,7 @@ registers_save(MathVariables *variables)
         MPNumber *value = val;
         char number[1024];
 
-        mp_cast_to_string(value, 10, 10, 50, TRUE, number, 1024);
+        mp_cast_to_string(value, 10, 10, 50, TRUE, '.', number, 1024);
         fprintf(f, "%s=%s\n", name, number);
     }
     fclose(f);
diff --git a/src/mp-binary.c b/src/mp-binary.c
index e4cedba..398d094 100644
--- a/src/mp-binary.c
+++ b/src/mp-binary.c
@@ -45,8 +45,8 @@ mp_bitwise(const MPNumber *x, const MPNumber *y, int (*bitwise_operator)(int, in
     char text1[MAX_DIGITS], text2[MAX_DIGITS], text_out[MAX_DIGITS], text_out2[MAX_DIGITS];
     int offset1, offset2, offset_out;
 
-    mp_cast_to_string(x, 16, 16, 0, 0, text1, MAX_DIGITS);
-    mp_cast_to_string(y, 16, 16, 0, 0, text2, MAX_DIGITS);
+    mp_cast_to_string(x, 16, 16, 0, 0, '.', text1, MAX_DIGITS);
+    mp_cast_to_string(y, 16, 16, 0, 0, '.', text2, MAX_DIGITS);
     offset1 = strlen(text1) - 1;
     offset2 = strlen(text2) - 1;
     offset_out = wordlen / 4 - 1;
@@ -156,7 +156,7 @@ mp_mask(const MPNumber *x, int wordlen, MPNumber *z)
     size_t len, offset;
 
     /* Convert to a hexadecimal string and use last characters */
-    mp_cast_to_string(x, 16, 16, 0, 0, text, MAX_DIGITS);
+    mp_cast_to_string(x, 16, 16, 0, 0, '.', text, MAX_DIGITS);
     len = strlen(text);
     offset = wordlen / 4;
     offset = len > offset ? len - offset: 0;
diff --git a/src/mp-convert.c b/src/mp-convert.c
index 68be574..7dbfa51 100644
--- a/src/mp-convert.c
+++ b/src/mp-convert.c
@@ -508,7 +508,7 @@ mp_cast_to_double(const MPNumber *x)
 
 
 static void
-mp_cast_to_string_real(const MPNumber *x, int default_base, int base, int accuracy, bool trim_zeroes, bool force_sign, GString *string)
+mp_cast_to_string_real(const MPNumber *x, int default_base, int base, int accuracy, bool trim_zeroes, gunichar radix, bool force_sign, GString *string)
 {
     static char digits[] = "0123456789ABCDEF";
     MPNumber number, integer_component, fractional_component, temp;
@@ -549,7 +549,7 @@ mp_cast_to_string_real(const MPNumber *x, int default_base, int base, int accura
     } while (!mp_is_zero(&temp));
 
     last_non_zero = string->len;
-    g_string_append_c(string, '.');
+    g_string_append_unichar(string, radix);
 
     /* Write out the fractional component */
     mp_set_from_mp(&fractional_component, &temp);
@@ -600,7 +600,7 @@ mp_cast_to_string_real(const MPNumber *x, int default_base, int base, int accura
 
 
 void
-mp_cast_to_string(const MPNumber *x, int default_base, int base, int accuracy, bool trim_zeroes, char *buffer, int buffer_length)
+mp_cast_to_string(const MPNumber *x, int default_base, int base, int accuracy, bool trim_zeroes, gunichar radix, char *buffer, int buffer_length)
 {
     GString *string;
     MPNumber x_real;
@@ -608,7 +608,7 @@ mp_cast_to_string(const MPNumber *x, int default_base, int base, int accuracy, b
     string = g_string_sized_new(buffer_length);
 
     mp_real_component(x, &x_real);
-    mp_cast_to_string_real(&x_real, default_base, base, accuracy, trim_zeroes, FALSE, string);
+    mp_cast_to_string_real(&x_real, default_base, base, accuracy, trim_zeroes, radix, FALSE, string);
     if (mp_is_complex(x)) {
         GString *s;
         gboolean force_sign = TRUE;
@@ -622,7 +622,7 @@ mp_cast_to_string(const MPNumber *x, int default_base, int base, int accuracy, b
         }
 
         s = g_string_sized_new(buffer_length);
-        mp_cast_to_string_real(&x_im, default_base, 10, accuracy, trim_zeroes, force_sign, s);
+        mp_cast_to_string_real(&x_im, default_base, 10, accuracy, trim_zeroes, radix, force_sign, s);
         if (strcmp(s->str, "0") == 0 || strcmp(s->str, "+0") == 0 || strcmp(s->str, "â??0") == 0) {
             /* Ignore */
         }
@@ -653,7 +653,7 @@ mp_cast_to_string(const MPNumber *x, int default_base, int base, int accuracy, b
 
 
 void
-mp_cast_to_exponential_string(const MPNumber *x, int default_base, int base_, int max_digits, bool trim_zeroes, bool eng_format, char *buffer, int buffer_length)
+mp_cast_to_exponential_string(const MPNumber *x, int default_base, int base_, int max_digits, bool trim_zeroes, gunichar radix, bool eng_format, char *buffer, int buffer_length)
 {
     char fixed[1024], *c;
     MPNumber t, z, base, base3, base10, base10inv, mantissa;
@@ -698,7 +698,7 @@ mp_cast_to_exponential_string(const MPNumber *x, int default_base, int base_, in
         }
     }
 
-    mp_cast_to_string(&mantissa, default_base, base_, max_digits, trim_zeroes, fixed, 1024);
+    mp_cast_to_string(&mantissa, default_base, base_, max_digits, trim_zeroes, radix, fixed, 1024);
     g_string_append(string, fixed);
     if (exponent != 0) {
         g_string_append_printf(string, "Ã?10"); // FIXME: Use the current base
diff --git a/src/mp.h b/src/mp.h
index d71111d..67ef8d5 100644
--- a/src/mp.h
+++ b/src/mp.h
@@ -276,8 +276,9 @@ uint64_t mp_cast_to_unsigned_int(const MPNumber *x);
  * The numbers are written in 'base' (e.g. 10).
  * If 'trim_zeroes' is non-zero then strip off trailing zeroes.
  * Fractional components are truncated at 'max_digits' digits.
+ * The radix character (e.g. '.' or ',') can be specified.
  */
-void   mp_cast_to_string(const MPNumber *x, int default_base, int base, int max_digits, bool trim_zeroes, char *buffer, int buffer_length);
+void   mp_cast_to_string(const MPNumber *x, int default_base, int base, int max_digits, bool trim_zeroes, gunichar radix, char *buffer, int buffer_length);
 
 /* Converts x to a string representation in exponential form.
  * The string is written into 'buffer' which is guaranteed to be at least 'buffer_length' octets in size.
@@ -286,7 +287,7 @@ void   mp_cast_to_string(const MPNumber *x, int default_base, int base, int max_
  * If 'trim_zeroes' is non-zero then strip off trailing zeroes.
  * Fractional components are truncated at 'max_digits' digits.
  */
-void   mp_cast_to_exponential_string(const MPNumber *x, int default_base, int base, int max_digits, bool trim_zeroes, bool eng_format, char *buffer, int buffer_length);
+void   mp_cast_to_exponential_string(const MPNumber *x, int default_base, int base, int max_digits, bool trim_zeroes, gunichar radix, bool eng_format, char *buffer, int buffer_length);
 
 /* Sets z = sin x */
 void   mp_sin(const MPNumber *x, MPAngleUnit unit, MPNumber *z);
diff --git a/src/unittest.c b/src/unittest.c
index 791391b..8cb5125 100644
--- a/src/unittest.c
+++ b/src/unittest.c
@@ -83,7 +83,7 @@ test(char *expression, char *expected, int expected_error)
     error = mp_equation_parse(expression, &options, &result, NULL);
 
     if(error == 0) {
-        mp_cast_to_string(&result, options.base, options.base, 9, 1, result_str, 1024);
+        mp_cast_to_string(&result, options.base, options.base, 9, 1, '.', result_str, 1024);
         if(expected_error != 0)
             fail("'%s' -> %s, expected error %s", expression, result_str, error_code_to_string(expected_error));
         else if(strcmp(result_str, expected) != 0)



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