From d9c7ee8689bc27ac40d4de2ec61fa2e0ba69726c Mon Sep 17 00:00:00 2001 From: Robert Ancell Date: Thu, 14 Oct 2010 12:26:23 +1100 Subject: [PATCH 24/25] Fix broken thousands separators code (Bug 628908) Bug: https://bugzilla.gnome.org/show_bug.cgi?id=628908 Bug-Ubuntu: http://launchpad.net/bugs/631665 --- 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(-) Index: gcalctool-5.32.0/NEWS =================================================================== --- gcalctool-5.32.0.orig/NEWS 2010-10-14 16:28:45.389934001 +1100 +++ gcalctool-5.32.0/NEWS 2010-10-14 16:28:52.359934000 +1100 @@ -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 Index: gcalctool-5.32.0/src/gcalccmd.c =================================================================== --- gcalctool-5.32.0.orig/src/gcalccmd.c 2010-10-14 16:28:45.429934001 +1100 +++ gcalctool-5.32.0/src/gcalccmd.c 2010-10-14 16:28:52.359934000 +1100 @@ -48,7 +48,7 @@ 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); } } Index: gcalctool-5.32.0/src/gcalctool.c =================================================================== --- gcalctool-5.32.0.orig/src/gcalctool.c 2010-10-14 16:28:45.409934001 +1100 +++ gcalctool-5.32.0/src/gcalctool.c 2010-10-14 16:28:52.359934000 +1100 @@ -61,7 +61,7 @@ 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); } Index: gcalctool-5.32.0/src/math-buttons.c =================================================================== --- gcalctool-5.32.0.orig/src/math-buttons.c 2010-10-14 16:28:45.419934001 +1100 +++ gcalctool-5.32.0/src/math-buttons.c 2010-10-14 16:28:52.359934000 +1100 @@ -422,10 +422,10 @@ 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 @@ 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 @@ 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; @@ -853,16 +853,26 @@ 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); Index: gcalctool-5.32.0/src/math-equation.c =================================================================== --- gcalctool-5.32.0.orig/src/math-equation.c 2010-10-14 16:28:51.199934000 +1100 +++ gcalctool-5.32.0/src/math-equation.c 2010-10-14 16:28:52.359934000 +1100 @@ -83,15 +83,15 @@ 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 @@ } 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 @@ } +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 @@ } -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 @@ 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 @@ 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 @@ 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 @@ 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 @@ { 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 @@ static gboolean on_delete(MathEquation *equation) { - equation->priv->in_delete = FALSE; - return FALSE; + equation->priv->in_delete = FALSE; + return FALSE; } @@ -1624,6 +1744,10 @@ 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 @@ { 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 @@ 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(); Index: gcalctool-5.32.0/src/math-equation.h =================================================================== --- gcalctool-5.32.0.orig/src/math-equation.h 2010-10-14 16:28:45.439934001 +1100 +++ gcalctool-5.32.0/src/math-equation.h 2010-10-14 16:28:52.359934000 +1100 @@ -60,9 +60,9 @@ 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); Index: gcalctool-5.32.0/src/math-variables.c =================================================================== --- gcalctool-5.32.0.orig/src/math-variables.c 2010-10-14 16:28:45.399934001 +1100 +++ gcalctool-5.32.0/src/math-variables.c 2010-10-14 16:28:52.359934000 +1100 @@ -97,7 +97,7 @@ 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); Index: gcalctool-5.32.0/src/mp-binary.c =================================================================== --- gcalctool-5.32.0.orig/src/mp-binary.c 2010-10-14 16:28:45.479934001 +1100 +++ gcalctool-5.32.0/src/mp-binary.c 2010-10-14 16:28:52.359934000 +1100 @@ -45,8 +45,8 @@ 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 @@ 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; Index: gcalctool-5.32.0/src/mp-convert.c =================================================================== --- gcalctool-5.32.0.orig/src/mp-convert.c 2010-10-14 16:28:45.449934001 +1100 +++ gcalctool-5.32.0/src/mp-convert.c 2010-10-14 16:28:52.359934000 +1100 @@ -508,7 +508,7 @@ 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 @@ } 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 @@ 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 @@ 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 @@ } 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 @@ 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_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 Index: gcalctool-5.32.0/src/mp.h =================================================================== --- gcalctool-5.32.0.orig/src/mp.h 2010-10-14 16:28:45.469934001 +1100 +++ gcalctool-5.32.0/src/mp.h 2010-10-14 16:28:52.359934000 +1100 @@ -276,8 +276,9 @@ * 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 @@ * 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); Index: gcalctool-5.32.0/src/unittest.c =================================================================== --- gcalctool-5.32.0.orig/src/unittest.c 2010-10-14 16:28:45.459934001 +1100 +++ gcalctool-5.32.0/src/unittest.c 2010-10-14 16:28:52.359934000 +1100 @@ -83,7 +83,7 @@ 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)