Merge branch 'ignore_case_in_genums' into 'main'

gobject: Make enum/flags value lookups case-insensitive

Closes #74

See merge request GNOME/glib!4906
This commit is contained in:
Philip Withnall
2025-11-17 23:23:28 +00:00
2 changed files with 39 additions and 8 deletions

View File

@@ -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: * g_enum_get_value_by_name:
* @enum_class: a #GEnumClass * @enum_class: a #GEnumClass
@@ -374,7 +401,7 @@ g_enum_get_value_by_name (GEnumClass *enum_class,
GEnumValue *enum_value; GEnumValue *enum_value;
for (enum_value = enum_class->values; enum_value->value_name; enum_value++) for (enum_value = enum_class->values; enum_value->value_name; enum_value++)
if (strcmp (name, enum_value->value_name) == 0) if (strcmp_ignore_case (name, enum_value->value_name) == 0)
return enum_value; return enum_value;
} }
@@ -403,7 +430,7 @@ g_flags_get_value_by_name (GFlagsClass *flags_class,
GFlagsValue *flags_value; GFlagsValue *flags_value;
for (flags_value = flags_class->values; flags_value->value_name; flags_value++) for (flags_value = flags_class->values; flags_value->value_name; flags_value++)
if (strcmp (name, flags_value->value_name) == 0) if (strcmp_ignore_case (name, flags_value->value_name) == 0)
return flags_value; return flags_value;
} }
@@ -433,7 +460,7 @@ g_enum_get_value_by_nick (GEnumClass *enum_class,
GEnumValue *enum_value; GEnumValue *enum_value;
for (enum_value = enum_class->values; enum_value->value_name; 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) if (enum_value->value_nick && strcmp_ignore_case (nick, enum_value->value_nick) == 0)
return enum_value; return enum_value;
} }
@@ -462,7 +489,7 @@ g_flags_get_value_by_nick (GFlagsClass *flags_class,
GFlagsValue *flags_value; GFlagsValue *flags_value;
for (flags_value = flags_class->values; flags_value->value_nick; 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) if (flags_value->value_nick && strcmp_ignore_case (nick, flags_value->value_nick) == 0)
return flags_value; return flags_value;
} }

View File

@@ -41,12 +41,14 @@ test_enum_basic (void)
val = g_enum_get_value_by_name (class, "the third value"); val = g_enum_get_value_by_name (class, "the third value");
g_assert_nonnull (val); g_assert_nonnull (val);
g_assert_cmpint (val->value, ==, 3); 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"); val = g_enum_get_value_by_name (class, "the color purple");
g_assert_null (val); g_assert_null (val);
val = g_enum_get_value_by_nick (class, "one"); val = g_enum_get_value_by_nick (class, "one");
g_assert_nonnull (val); g_assert_nonnull (val);
g_assert_cmpint (val->value, ==, 1); 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"); val = g_enum_get_value_by_nick (class, "purple");
g_assert_null (val); g_assert_null (val);
@@ -118,6 +120,7 @@ test_flags_basic (void)
val = g_flags_get_value_by_name (class, "the third flag"); val = g_flags_get_value_by_name (class, "the third flag");
g_assert_nonnull (val); g_assert_nonnull (val);
g_assert_true (g_flags_get_value_by_name (class, "The Third Flag") == val);
g_assert_cmpint (val->value, ==, 8); g_assert_cmpint (val->value, ==, 8);
val = g_flags_get_value_by_name (class, "the color purple"); val = g_flags_get_value_by_name (class, "the color purple");
g_assert_null (val); g_assert_null (val);
@@ -125,6 +128,7 @@ test_flags_basic (void)
val = g_flags_get_value_by_nick (class, "one"); val = g_flags_get_value_by_nick (class, "one");
g_assert_nonnull (val); g_assert_nonnull (val);
g_assert_cmpint (val->value, ==, 1); 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"); val = g_flags_get_value_by_nick (class, "purple");
g_assert_null (val); g_assert_null (val);