static char * generate_repr(GType gtype, int value) { GFlagsClass *flags_class; char *retval = NULL, *tmp; int i; flags_class = g_type_class_ref(gtype); g_assert(G_IS_FLAGS_CLASS(flags_class)); for (i = 0; i < flags_class->n_values; i++) { /* Some types (eg GstElementState in GStreamer 0.8) has flags with 0 values, * we're just ignore them for now otherwise they'll always show up */ if (flags_class->values[i].value == 0) continue; if ((value & flags_class->values[i].value) == flags_class->values[i].value) { if (retval) { tmp = g_strdup_printf("%s | %s", retval, flags_class->values[i].value_name); g_free(retval); retval = tmp; } else { retval = g_strdup_printf("%s", flags_class->values[i].value_name); } } } g_type_class_unref(flags_class); return retval; }
/* Flags can contain multiple values. We assume here that values are like * C identifiers (that is, they match /[A-Za-z_][A-Za-z0-9_]+/), although * that doesn't seem to be a requirement of GLib. With that assumption in * mind, we look for the format "FLAG_1 | FLAG_2 | ... | FLAG_N". */ static gboolean g_value_set_flags_from_string(GValue * val, char * string) { guint value = 0; char * strtok_saveptr; char * string_copy; char * strtok_first_arg; const char delim[] = " \t,|"; GFlagsClass * flags_class; flags_class = (GFlagsClass*) g_type_class_ref(G_VALUE_TYPE(val)); g_return_val_if_fail(flags_class != NULL, FALSE); g_return_val_if_fail(G_IS_FLAGS_CLASS(flags_class), FALSE); /* Don't let strtok stop on original. */ strtok_first_arg = string_copy = strdup(string); for (;;) { GFlagsValue * flag_value; char * token = strtok_r(strtok_first_arg, delim, &strtok_saveptr); strtok_first_arg = NULL; if (token == NULL) { break; } flag_value = g_flags_get_value_by_name(flags_class, token); if (flag_value == NULL) { flag_value = g_flags_get_value_by_nick(flags_class, token); } if (flag_value == NULL) { g_fprintf(stderr, _("Invalid flag %s for type %s\n"), token, g_type_name(G_VALUE_TYPE(val))); continue; } value |= flag_value->value; } amfree(string_copy); if (value == 0) { g_fprintf(stderr, _("No valid flags for type %s in string %s\n"), g_type_name(G_VALUE_TYPE(val)), string); return FALSE; } g_value_set_flags(val, value); return TRUE; }
/** * gimp_flags_get_first_desc: * @flags_class: a #GFlagsClass * @value: a value from @flags_class * * Retrieves the first #GimpFlagsDesc that matches the given value, or %NULL. * * Return value: the value's #GimpFlagsDesc. * * Since: GIMP 2.2 **/ GimpFlagsDesc * gimp_flags_get_first_desc (GFlagsClass *flags_class, guint value) { const GimpFlagsDesc *value_desc; g_return_val_if_fail (G_IS_FLAGS_CLASS (flags_class), NULL); value_desc = gimp_flags_get_value_descriptions (G_TYPE_FROM_CLASS (flags_class)); if (value_desc) { while (value_desc->value_desc) { if ((value_desc->value & value) == value_desc->value) return (GimpFlagsDesc *) value_desc; value_desc++; } } return NULL; }