[gcalctool] Fix crash in scientific mode Add new automatic display mode that switches from fixed to scientific w
- From: Robert Ancell <rancell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gcalctool] Fix crash in scientific mode Add new automatic display mode that switches from fixed to scientific w
- Date: Mon, 29 Nov 2010 07:24:07 +0000 (UTC)
commit 8f864023cf7fcee2f415928b60883bd80b2ffa7d
Author: Robert Ancell <robert ancell canonical com>
Date: Mon Nov 29 18:23:31 2010 +1100
Fix crash in scientific mode
Add new automatic display mode that switches from fixed to scientific when numbers are too large
NEWS | 3 ++
data/org.gnome.gcalctool.gschema.xml.in | 9 +++--
src/Makefile.am | 4 +-
src/gcalccmd.c | 2 +-
src/gcalctool.c | 2 +-
src/math-buttons.c | 4 +-
src/math-equation.c | 4 +-
src/math-preferences.c | 4 ++
src/math-variables.c | 2 +-
src/mp-binary.c | 2 +-
src/mp-serializer.c | 48 ++++++++++++++++++++++---------
src/mp-serializer.h | 9 +++--
src/unittest.c | 2 +-
13 files changed, 62 insertions(+), 33 deletions(-)
---
diff --git a/NEWS b/NEWS
index 6bda71d..a4d4e9a 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,9 @@ Overview of changes in gcalctool 5.91.3
* Fix incorrect calculation of tanh
* Fix dropping of decimal points when thousand separator is '.' (Bug #635517)
* Improve conversion bar
+ * Fix crash in scientific mode
+ * Add new automatic display mode that switches from fixed to scientific when
+ numbers are too large
Overview of changes in gcalctool 5.91.2
diff --git a/data/org.gnome.gcalctool.gschema.xml.in b/data/org.gnome.gcalctool.gschema.xml.in
index 909e4a1..51dfaa0 100644
--- a/data/org.gnome.gcalctool.gschema.xml.in
+++ b/data/org.gnome.gcalctool.gschema.xml.in
@@ -1,9 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<schemalist>
<enum id="org.gnome.gcalctool.NumberFormat">
- <value value="0" nick="fixed"/>
- <value value="1" nick="scientific"/>
- <value value="2" nick="engineering"/>
+ <value value="0" nick="automatic"/>
+ <value value="1" nick="fixed"/>
+ <value value="2" nick="scientific"/>
+ <value value="3" nick="engineering"/>
</enum>
<enum id="org.gnome.gcalctool.ButtonMode">
<value value="0" nick="basic"/>
@@ -47,7 +48,7 @@
<_description>Indicates whether any trailing zeroes after the numeric point should be shown in the display value.</_description>
</key>
<key name="number-format" enum="org.gnome.gcalctool.NumberFormat">
- <default>'fixed'</default>
+ <default>'automatic'</default>
<_summary>Number format</_summary>
<_description>The format to display numbers in</_description>
</key>
diff --git a/src/Makefile.am b/src/Makefile.am
index 0404e3f..070f235 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -93,10 +93,10 @@ mp-equation-lexer.o: mp-equation-parser.h
mp-equation.c: mp-equation-lexer.h mp-equation-parser.h
# Generate enum types
-math-enums.h: math-enums.h.template
+math-enums.h: math-enums.h.template mp-serializer.h
$(AM_V_GEN)$(GLIB_MKENUMS) --template $(srcdir)/math-enums.h.template $(srcdir)/mp-serializer.h > math-enums.h
-math-enums.c: math-enums.c.template math-enums.h
+math-enums.c: math-enums.c.template math-enums.h mp-serializer.h
$(AM_V_GEN)$(GLIB_MKENUMS) --template $(srcdir)/math-enums.c.template $(srcdir)/mp-serializer.h > math-enums.c
# Fix dependencies
diff --git a/src/gcalccmd.c b/src/gcalccmd.c
index 190df8f..5fb2d45 100644
--- a/src/gcalccmd.c
+++ b/src/gcalccmd.c
@@ -87,7 +87,7 @@ main(int argc, char **argv)
g_type_init ();
setlocale(LC_ALL, "");
- result_serializer = mp_serializer_new(10, 9);
+ result_serializer = mp_serializer_new(MP_DISPLAY_FORMAT_AUTOMATIC, 10, 9);
equation = (char *) malloc(MAXLINE * sizeof(char));
while (1) {
diff --git a/src/gcalctool.c b/src/gcalctool.c
index f0f3467..b2bb23b 100644
--- a/src/gcalctool.c
+++ b/src/gcalctool.c
@@ -62,7 +62,7 @@ solve(const char *equation)
exit(1);
}
else {
- result_str = mp_serializer_to_string(mp_serializer_new(10, 9), &result);
+ result_str = mp_serializer_to_string(mp_serializer_new(MP_DISPLAY_FORMAT_AUTOMATIC, 10, 9), &result);
printf("%s\n", result_str);
exit(0);
}
diff --git a/src/math-buttons.c b/src/math-buttons.c
index 697606a..de3b213 100644
--- a/src/math-buttons.c
+++ b/src/math-buttons.c
@@ -1055,7 +1055,7 @@ load_mode(MathButtons *buttons, ButtonMode mode)
int i, j;
buttons->priv->convert_result_label = GET_WIDGET(builder, "convert_result_label");
- buttons->priv->units_serializer = mp_serializer_new(10, 2);
+ buttons->priv->units_serializer = mp_serializer_new(MP_DISPLAY_FORMAT_AUTOMATIC, 10, 2);
buttons->priv->convert_from_combo = GET_WIDGET(builder, "convert_from_combo");
from_model = gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT);
@@ -1147,7 +1147,7 @@ load_mode(MathButtons *buttons, ButtonMode mode)
buttons->priv->target_currency_combo = GET_WIDGET(builder, "target_currency_combo");
buttons->priv->currency_label = GET_WIDGET(builder, "currency_label");
- buttons->priv->currency_serializer = mp_serializer_new(10, 2);
+ buttons->priv->currency_serializer = mp_serializer_new(MP_DISPLAY_FORMAT_AUTOMATIC, 10, 2);
model = gtk_list_store_new(1, G_TYPE_STRING);
diff --git a/src/math-equation.c b/src/math-equation.c
index 0a431ce..3dbab8d 100644
--- a/src/math-equation.c
+++ b/src/math-equation.c
@@ -1578,7 +1578,7 @@ math_equation_class_init(MathEquationClass *klass)
g_type_class_add_private(klass, sizeof(MathEquationPrivate));
number_mode_type = g_enum_register_static("NumberMode", number_mode_values);
- number_format_type = math_display_format_get_type();
+ number_format_type = math_mp_display_format_get_type();
angle_unit_type = g_enum_register_static("AngleUnit", angle_unit_values);
g_object_class_install_property(object_class,
@@ -1853,7 +1853,7 @@ math_equation_init(MathEquation *equation)
equation->priv->target_currency = g_strdup(currency_names[0].short_name);
equation->priv->source_units = g_strdup("");
equation->priv->target_units = g_strdup("");
- equation->priv->serializer = mp_serializer_new(10, 9);
+ equation->priv->serializer = mp_serializer_new(MP_DISPLAY_FORMAT_AUTOMATIC, 10, 9);
equation->priv->queue = g_async_queue_new();
mp_set_from_integer(0, &equation->priv->state.ans);
diff --git a/src/math-preferences.c b/src/math-preferences.c
index 74b2316..9bc59df 100644
--- a/src/math-preferences.c
+++ b/src/math-preferences.c
@@ -268,6 +268,10 @@ create_gui(MathPreferencesDialog *dialog)
model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
gtk_list_store_append(GTK_LIST_STORE(model), &iter);
gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0,
+ /* Number display mode combo: Automatic, e.g. 1234 (or scientific for large number 1.234Ã?10^99) */
+ _("Automatic"), 1, MP_DISPLAY_FORMAT_AUTOMATIC, -1);
+ gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, 0,
/* Number display mode combo: Fixed, e.g. 1234 */
_("Fixed"), 1, MP_DISPLAY_FORMAT_FIXED, -1);
gtk_list_store_append(GTK_LIST_STORE(model), &iter);
diff --git a/src/math-variables.c b/src/math-variables.c
index a57a509..1d9becc 100644
--- a/src/math-variables.c
+++ b/src/math-variables.c
@@ -162,7 +162,7 @@ math_variables_init(MathVariables *variables)
variables->priv = G_TYPE_INSTANCE_GET_PRIVATE (variables, math_variables_get_type(), MathVariablesPrivate);
variables->priv->registers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
variables->priv->file_name = g_build_filename(g_get_user_data_dir(), "gcalctool", "registers", NULL);
- variables->priv->serializer = mp_serializer_new(10, 50);
+ variables->priv->serializer = mp_serializer_new(MP_DISPLAY_FORMAT_SCIENTIFIC, 10, 50);
mp_serializer_set_radix(variables->priv->serializer, '.');
registers_load(variables);
}
diff --git a/src/mp-binary.c b/src/mp-binary.c
index 7f033db..968a210 100644
--- a/src/mp-binary.c
+++ b/src/mp-binary.c
@@ -46,7 +46,7 @@ to_hex_string(const MPNumber *x)
MpSerializer *serializer;
gchar *result;
- serializer = mp_serializer_new(16, 0);
+ serializer = mp_serializer_new(MP_DISPLAY_FORMAT_FIXED, 16, 0);
result = mp_serializer_to_string(serializer, x);
g_object_unref(serializer);
diff --git a/src/mp-serializer.c b/src/mp-serializer.c
index 79eb942..9d2b052 100644
--- a/src/mp-serializer.c
+++ b/src/mp-serializer.c
@@ -54,9 +54,10 @@ struct MpSerializerPrivate
G_DEFINE_TYPE(MpSerializer, mp_serializer, G_TYPE_OBJECT);
MpSerializer *
-mp_serializer_new(int base, int accuracy)
+mp_serializer_new(MpDisplayFormat format, int base, int accuracy)
{
- MpSerializer *serializer = g_object_new(mp_serializer_get_type(), NULL);
+ MpSerializer *serializer = g_object_new(mp_serializer_get_type(), /*"number-format", format,*/ NULL);
+ mp_serializer_set_number_format(serializer, format);
mp_serializer_set_base(serializer, base);
mp_serializer_set_accuracy(serializer, accuracy);
return serializer;
@@ -273,14 +274,18 @@ mp_cast_to_exponential_string(MpSerializer *serializer, const MPNumber *x, gbool
g_string_append(string, fixed);
g_free(fixed);
if (exponent != 0) {
+ gchar *super_value;
+
g_string_append_printf(string, "Ã?10"); // FIXME: Use the current base
if (exponent < 0) {
exponent = -exponent;
g_string_append(string, "â?»");
}
- snprintf(fixed, 1024, "%d", exponent);
- for (c = fixed; *c; c++)
+
+ super_value = g_strdup_printf("%d", exponent);
+ for (c = super_value; *c; c++)
g_string_append(string, super_digits[*c - '0']);
+ g_free (super_value);
}
result = g_strndup(string->str, string->len + 1);
@@ -293,8 +298,23 @@ mp_cast_to_exponential_string(MpSerializer *serializer, const MPNumber *x, gbool
gchar *
mp_serializer_to_string(MpSerializer *serializer, const MPNumber *x)
{
+ gchar *s0, *s1;
switch(serializer->priv->format) {
default:
+ case MP_DISPLAY_FORMAT_AUTOMATIC:
+ s0 = mp_cast_to_string(serializer, x);
+ s1 = mp_cast_to_exponential_string(serializer, x, FALSE);
+ if (g_utf8_strlen(s0, -1) < g_utf8_strlen(s1, -1))
+ {
+ g_free(s1);
+ return s0;
+ }
+ else
+ {
+ g_free(s0);
+ return s1;
+ }
+ break;
case MP_DISPLAY_FORMAT_FIXED:
return mp_cast_to_string(serializer, x);
case MP_DISPLAY_FORMAT_SCIENTIFIC:
@@ -476,7 +496,7 @@ mp_serializer_class_init(MpSerializerClass *klass)
g_type_class_add_private(klass, sizeof(MpSerializerPrivate));
- number_format_type = math_display_format_get_type();
+ number_format_type = math_mp_display_format_get_type();
g_object_class_install_property(object_class,
PROP_SHOW_THOUSANDS_SEPARATORS,
@@ -493,20 +513,20 @@ mp_serializer_class_init(MpSerializerClass *klass)
FALSE,
G_PARAM_READWRITE));
g_object_class_install_property(object_class,
- PROP_BASE,
- g_param_spec_int("base",
- "base",
- "Default number base (derived from number-format)",
- 2, 16, 10,
- G_PARAM_READWRITE));
- g_object_class_install_property(object_class,
PROP_NUMBER_FORMAT,
g_param_spec_enum("number-format",
"number-format",
"Display format",
number_format_type,
- MP_DISPLAY_FORMAT_FIXED,
+ MP_DISPLAY_FORMAT_AUTOMATIC,
G_PARAM_READWRITE));
+ g_object_class_install_property(object_class,
+ PROP_BASE,
+ g_param_spec_int("base",
+ "base",
+ "Default number base",
+ 2, 16, 10,
+ G_PARAM_READWRITE));
}
@@ -529,5 +549,5 @@ mp_serializer_init(MpSerializer *serializer)
serializer->priv->accuracy = 9;
serializer->priv->show_zeroes = FALSE;
serializer->priv->show_tsep = FALSE;
- serializer->priv->format = MP_DISPLAY_FORMAT_FIXED;
+ serializer->priv->format = MP_DISPLAY_FORMAT_AUTOMATIC;
}
diff --git a/src/mp-serializer.h b/src/mp-serializer.h
index 5e2fd28..f4e0a9b 100644
--- a/src/mp-serializer.h
+++ b/src/mp-serializer.h
@@ -42,6 +42,7 @@ typedef struct {
/* Number display mode. */
typedef enum {
+ MP_DISPLAY_FORMAT_AUTOMATIC,
MP_DISPLAY_FORMAT_FIXED,
MP_DISPLAY_FORMAT_SCIENTIFIC,
MP_DISPLAY_FORMAT_ENGINEERING
@@ -49,20 +50,20 @@ typedef enum {
GType mp_serializer_get_type(void);
-MpSerializer *mp_serializer_new(int base, int accuracy);
+MpSerializer *mp_serializer_new(MpDisplayFormat format, int base, int accuracy);
gchar *mp_serializer_to_string(MpSerializer *serializer, const MPNumber *z);
gboolean mp_serializer_from_string(MpSerializer *serializer, const gchar *str, MPNumber *z);
+void mp_serializer_set_number_format(MpSerializer *serializer, MpDisplayFormat format);
+MpDisplayFormat mp_serializer_get_number_format(MpSerializer *serializer);
+
void mp_serializer_set_base(MpSerializer *serializer, int base);
int mp_serializer_get_base(MpSerializer *serializer);
void mp_serializer_set_accuracy(MpSerializer *serializer, int accuracy);
int mp_serializer_get_accuracy(MpSerializer *serializer);
-void mp_serializer_set_number_format(MpSerializer *serializer, MpDisplayFormat format);
-MpDisplayFormat mp_serializer_get_number_format(MpSerializer *serializer);
-
void mp_serializer_set_radix(MpSerializer *serializer, gunichar radix);
gunichar mp_serializer_get_radix(MpSerializer *serializer);
diff --git a/src/unittest.c b/src/unittest.c
index 6652080..40704dc 100644
--- a/src/unittest.c
+++ b/src/unittest.c
@@ -86,7 +86,7 @@ test(char *expression, char *expected, int expected_error)
char *result_str;
MpSerializer *serializer;
- serializer = mp_serializer_new(options.base, 9);
+ serializer = mp_serializer_new(MP_DISPLAY_FORMAT_FIXED, options.base, 9);
result_str = mp_serializer_to_string(serializer, &result);
g_object_unref(serializer);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]