diff --git a/ChangeLog b/ChangeLog index 440968f34c..504334ed8f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2007-06-30 Johan Dahlin + + * gtk/gtkbuilder.c: (gtk_builder_value_from_string_type): + * gtk/gtkbuilderparser.c: (_gtk_builder_parse_boolean), + (parse_property), (parse_signal): + * gtk/gtkbuilderprivate.h: + * tests/buildertest.c: (test_value_from_string): + Make boolean string parsing consistent, #452464 + 2007-06-30 Matthias Clasen * gtk/gtkbuilder.c: diff --git a/gtk/gtkbuilder.c b/gtk/gtkbuilder.c index 03f28817ea..22228acdc1 100644 --- a/gtk/gtkbuilder.c +++ b/gtk/gtkbuilder.c @@ -1038,33 +1038,10 @@ gtk_builder_value_from_string_type (GtkBuilder *builder, { gboolean b; - switch (g_ascii_tolower (string[0])) - { - case 't': - case 'y': - b = TRUE; - break; - case 'f': - case 'n': - b = FALSE; - break; - default: - { - gchar *endptr; - errno = 0; - b = strtol (string, &endptr, 0); - if (errno || endptr == string) - { - g_set_error (error, - GTK_BUILDER_ERROR, - GTK_BUILDER_ERROR_INVALID_VALUE, - "Could not parse boolean `%s'", - string); - ret = FALSE; - break; - } - } - break; + if (!_gtk_builder_parse_boolean (string, &b, error)) + { + ret = FALSE; + break; } g_value_set_boolean (value, b); break; diff --git a/gtk/gtkbuilderparser.c b/gtk/gtkbuilderparser.c index a619a1f507..a18d5ec7c4 100644 --- a/gtk/gtkbuilderparser.c +++ b/gtk/gtkbuilderparser.c @@ -157,6 +157,55 @@ error_missing_property_value (ParserData *data, line_number, char_number); } +gboolean +_gtk_builder_parse_boolean (const gchar *string, + gboolean *value, + GError **error) +{ + gboolean retval = TRUE; + int i; + int length; + + g_assert (string != NULL); + length = strlen (string); + + if (length == 0) + retval = FALSE; + else if (length == 1) + { + gchar c = g_ascii_tolower (string[0]); + if (c == 'y' || c == 't' || c == '1') + *value = TRUE; + else if (c == 'n' || c == 'f' || c == '0') + *value = FALSE; + else + retval = FALSE; + } + else + { + gchar *lower = g_strdup (string); + for (i = 0; i < strlen (string); i++) + lower[i] = g_ascii_tolower (string[i]); + + if (strcmp (lower, "yes") == 0 || strcmp (lower, "true") == 0) + *value = TRUE; + else if (strcmp (lower, "no") == 0 || strcmp (lower, "false") == 0) + *value = FALSE; + else + retval = FALSE; + g_free (lower); + } + + if (!retval) + g_set_error (error, + GTK_BUILDER_ERROR, + GTK_BUILDER_ERROR_INVALID_VALUE, + "could not parse boolean `%s'", + string); + + return retval; +} + static GObject * builder_construct (ParserData *data, ObjectInfo *object_info) @@ -353,7 +402,10 @@ parse_property (ParserData *data, if (strcmp (names[i], "name") == 0) name = g_strdelimit (g_strdup (values[i]), "_", '-'); else if (strcmp (names[i], "translatable") == 0) - translatable = strcmp (values[i], "yes") == 0; + { + if (!_gtk_builder_parse_boolean (values[i], &translatable, error)) + return; + } else { error_invalid_attribute (data, element_name, names[i], error); @@ -408,10 +460,14 @@ parse_signal (ParserData *data, else if (strcmp (names[i], "handler") == 0) handler = g_strdup (values[i]); else if (strcmp (names[i], "after") == 0) - after = strcmp (values[i], "yes") == 0; + { + if (!_gtk_builder_parse_boolean (values[i], &after, error)) + return; + } else if (strcmp (names[i], "swapped") == 0) { - swapped = strcmp (values[i], "yes") == 0; + if (!_gtk_builder_parse_boolean (values[i], &swapped, error)) + return; swapped_set = TRUE; } else if (strcmp (names[i], "object") == 0) diff --git a/gtk/gtkbuilderprivate.h b/gtk/gtkbuilderprivate.h index 1a65d48cc4..11d8974a77 100644 --- a/gtk/gtkbuilderprivate.h +++ b/gtk/gtkbuilderprivate.h @@ -107,5 +107,8 @@ void _gtk_builder_add (GtkBuilder *builder, void _gtk_builder_finish (GtkBuilder *builder); void _free_signal_info (SignalInfo *info, gpointer user_data); +gboolean _gtk_builder_parse_boolean (const gchar *string, + gboolean *value, + GError **error); #endif /* __GTK_BUILDER_PRIVATE_H__ */ diff --git a/tests/buildertest.c b/tests/buildertest.c index ce46928968..48fbd88cee 100644 --- a/tests/buildertest.c +++ b/tests/buildertest.c @@ -1508,6 +1508,11 @@ test_value_from_string (void) g_return_val_if_fail (g_value_get_boolean (&value) == TRUE, FALSE); g_value_unset (&value); + g_return_val_if_fail (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "tRuE", &value, &error), FALSE); + g_return_val_if_fail (G_VALUE_HOLDS_BOOLEAN (&value), FALSE); + g_return_val_if_fail (g_value_get_boolean (&value) == TRUE, FALSE); + g_value_unset (&value); + g_return_val_if_fail (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "blaurgh", &value, &error) == FALSE, FALSE); g_return_val_if_fail (error != NULL, FALSE); g_value_unset (&value); @@ -1516,6 +1521,27 @@ test_value_from_string (void) g_error_free (error); error = NULL; + g_return_val_if_fail (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "yess", &value, &error) == FALSE, FALSE); + g_value_unset (&value); + g_return_val_if_fail (error->domain == GTK_BUILDER_ERROR, FALSE); + g_return_val_if_fail (error->code == GTK_BUILDER_ERROR_INVALID_VALUE, FALSE); + g_error_free (error); + error = NULL; + + g_return_val_if_fail (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "trueee", &value, &error) == FALSE, FALSE); + g_value_unset (&value); + g_return_val_if_fail (error->domain == GTK_BUILDER_ERROR, FALSE); + g_return_val_if_fail (error->code == GTK_BUILDER_ERROR_INVALID_VALUE, FALSE); + g_error_free (error); + error = NULL; + + g_return_val_if_fail (gtk_builder_value_from_string_type (builder, G_TYPE_BOOLEAN, "", &value, &error) == FALSE, FALSE); + g_value_unset (&value); + g_return_val_if_fail (error->domain == GTK_BUILDER_ERROR, FALSE); + g_return_val_if_fail (error->code == GTK_BUILDER_ERROR_INVALID_VALUE, FALSE); + g_error_free (error); + error = NULL; + g_return_val_if_fail (gtk_builder_value_from_string_type (builder, G_TYPE_INT, "12345", &value, &error), FALSE); g_return_val_if_fail (G_VALUE_HOLDS_INT (&value), FALSE); g_return_val_if_fail (g_value_get_int (&value) == 12345, FALSE);