mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-11-19 17:08:22 +01:00
gobject: Make enum/flags value lookups case-insensitive
Make g_enum_get_value_by_name(), g_flags_get_value_by_name(), g_enum_get_value_by_nick() and g_flags_get_value_by_nick() perform ASCII case-insensitive comparisons when matching names and nicks. This aligns behavior with common expectations for user-visible nicks and reduces rejections of mixed-case inputs. Implementation switches from strcmp() to strcmp_ignore_case() when comparing the provided name/nick to registered values. This is a minor behavior change that only broadens accepted input. Types with values that differ only by case are now allowed. Tests: Extend gobject/tests/enums.c to cover mixed-case lookups for both enums and flags (names and nicks). Fixes: #74
This commit is contained in:
@@ -351,6 +351,33 @@ g_flags_class_init (GFlagsClass *class,
|
||||
}
|
||||
}
|
||||
|
||||
/* Internal function to compare strings without taking into account
|
||||
* character case and more... in order to ease the look ups. */
|
||||
static int
|
||||
strcmp_ignore_case (const char *str1, const char *str2)
|
||||
{
|
||||
const char *ptr1 = str1, *ptr2 = str2;
|
||||
char c1, c2;
|
||||
|
||||
do
|
||||
{
|
||||
/* Normalize to lower case */
|
||||
c1 = g_ascii_tolower (*ptr1++);
|
||||
c2 = g_ascii_tolower (*ptr2++);
|
||||
|
||||
/* End of either string */
|
||||
if (c1 == '\0' || c2 == '\0')
|
||||
return c1 - c2;
|
||||
|
||||
/* Normalize '-' to '_' */
|
||||
c1 = (c1 == '-') ? '_' : c1;
|
||||
c2 = (c2 == '-') ? '_' : c2;
|
||||
}
|
||||
while (c1 == c2);
|
||||
|
||||
return c1 - c2;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_enum_get_value_by_name:
|
||||
* @enum_class: a #GEnumClass
|
||||
@@ -374,8 +401,8 @@ g_enum_get_value_by_name (GEnumClass *enum_class,
|
||||
GEnumValue *enum_value;
|
||||
|
||||
for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
|
||||
if (strcmp (name, enum_value->value_name) == 0)
|
||||
return enum_value;
|
||||
if (strcmp_ignore_case (name, enum_value->value_name) == 0)
|
||||
return enum_value;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -403,8 +430,8 @@ g_flags_get_value_by_name (GFlagsClass *flags_class,
|
||||
GFlagsValue *flags_value;
|
||||
|
||||
for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
|
||||
if (strcmp (name, flags_value->value_name) == 0)
|
||||
return flags_value;
|
||||
if (strcmp_ignore_case (name, flags_value->value_name) == 0)
|
||||
return flags_value;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -433,8 +460,8 @@ g_enum_get_value_by_nick (GEnumClass *enum_class,
|
||||
GEnumValue *enum_value;
|
||||
|
||||
for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
|
||||
if (enum_value->value_nick && strcmp (nick, enum_value->value_nick) == 0)
|
||||
return enum_value;
|
||||
if (enum_value->value_nick && strcmp_ignore_case (nick, enum_value->value_nick) == 0)
|
||||
return enum_value;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@@ -462,8 +489,8 @@ g_flags_get_value_by_nick (GFlagsClass *flags_class,
|
||||
GFlagsValue *flags_value;
|
||||
|
||||
for (flags_value = flags_class->values; flags_value->value_nick; flags_value++)
|
||||
if (flags_value->value_nick && strcmp (nick, flags_value->value_nick) == 0)
|
||||
return flags_value;
|
||||
if (flags_value->value_nick && strcmp_ignore_case (nick, flags_value->value_nick) == 0)
|
||||
return flags_value;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -41,12 +41,14 @@ test_enum_basic (void)
|
||||
val = g_enum_get_value_by_name (class, "the third value");
|
||||
g_assert_nonnull (val);
|
||||
g_assert_cmpint (val->value, ==, 3);
|
||||
g_assert_true (g_enum_get_value_by_name (class, "The Third Value") == val);
|
||||
val = g_enum_get_value_by_name (class, "the color purple");
|
||||
g_assert_null (val);
|
||||
|
||||
val = g_enum_get_value_by_nick (class, "one");
|
||||
g_assert_nonnull (val);
|
||||
g_assert_cmpint (val->value, ==, 1);
|
||||
g_assert_true (g_enum_get_value_by_nick (class, "One") == val);
|
||||
val = g_enum_get_value_by_nick (class, "purple");
|
||||
g_assert_null (val);
|
||||
|
||||
@@ -118,6 +120,7 @@ test_flags_basic (void)
|
||||
|
||||
val = g_flags_get_value_by_name (class, "the third flag");
|
||||
g_assert_nonnull (val);
|
||||
g_assert_true (g_flags_get_value_by_name (class, "The Third Flag") == val);
|
||||
g_assert_cmpint (val->value, ==, 8);
|
||||
val = g_flags_get_value_by_name (class, "the color purple");
|
||||
g_assert_null (val);
|
||||
@@ -125,6 +128,7 @@ test_flags_basic (void)
|
||||
val = g_flags_get_value_by_nick (class, "one");
|
||||
g_assert_nonnull (val);
|
||||
g_assert_cmpint (val->value, ==, 1);
|
||||
g_assert_true (g_flags_get_value_by_nick (class, "One") == val);
|
||||
val = g_flags_get_value_by_nick (class, "purple");
|
||||
g_assert_null (val);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user