After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 327198 - Add g_key_file_[gs]et_enum
Add g_key_file_[gs]et_enum
Status: RESOLVED WONTFIX
Product: glib
Classification: Platform
Component: general
2.8.x
Other Linux
: Normal enhancement
: ---
Assigned To: gtkdev
gtkdev
Depends on: 447907
Blocks:
 
 
Reported: 2006-01-16 12:25 UTC by Mathias Hasselmann (IRC: tbf)
Modified: 2013-02-03 02:13 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Mathias Hasselmann (IRC: tbf) 2006-01-16 12:25:16 UTC
Glib has this nice enumeration types. Therefore I'd like to see the following two functions for storing and retreiving enum values beeing added to glib:

void g_key_file_set_enum(
        GKeyFile *key_file, const gchar *group_name,
        const gchar *key, GType enum_type, gint value)
{
    g_return_if_fail(NULL != key_file);
    g_return_if_fail(NULL != key);
    
    GEnumClass *enum_class = G_ENUM_CLASS(g_type_class_peek(enum_type));
    g_return_if_fail(NULL != enum_class);
    
    GEnumValue *enum_value = g_enum_get_value(enum_class, value);
    g_return_if_fail(NULL != enum_value);

    g_key_file_set_string(key_file, group_name, key, enum_value->value_nick);
}

gint g_key_file_get_enum(
        GKeyFile *key_file, const gchar *group_name,
        const gchar *key, GType enum_type, GError **error)
{
    g_return_val_if_fail(NULL != key_file, -1);
    g_return_val_if_fail(NULL != key, -1);
    
    GEnumClass *enum_class = G_ENUM_CLASS(g_type_class_peek(enum_type));
    g_return_val_if_fail(NULL != enum_class, -1);
    
    gchar *nick = g_key_file_get_string(key_file, group_name, key, error);
    gint result = -1;

    if (NULL != nick) {
        GEnumValue *enum_value = g_enum_get_value_by_nick(enum_class, nick);

        if (NULL == enum_value) {
            g_propagate_error(error, g_error_new(
                    G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE,
                    _("Invalid value for %s enumeration: '%s'"),
                    g_type_name(enum_type), nick));
        } else {
            result = enum_value->value;
        }
    }

    return result;
}
Comment 1 Mathias Hasselmann (IRC: tbf) 2006-01-16 12:28:17 UTC
Duh: Error message in g_key_file_get_enum should be:


_("Key file contains key '%s' in group '%s' which has value that cannot be "
  "interpreted."), key, group_name

instead of:

_("Invalid value for %s enumeration: '%s'"), g_type_name(enum_type), nick)
Comment 2 Samuel Cormier-Iijima 2006-11-04 22:37:22 UTC
This would be very useful - +1. This way users could have preferences that have the name of the enum, instead of e.g. an integer that maps to the enum values. Could this be included soon?
Comment 3 Samuel Cormier-Iijima 2006-11-04 22:51:43 UTC
I tried adding this, but unfortunately this means we'd have to pull all of GObject into GLib... and I unless this is possible we'd have to hand-write all the enum checking code.... :-(
Comment 4 Havoc Pennington 2006-11-04 23:03:08 UTC
If you do this, it's always good to allow the value to be a list where the first understood enum value is used; then it's possible to write a config file that works with both old and new versions of the app when the enum is extended. (by having "NEWER_ENUM_VALUE,OLDER_ENUM_VALUE" as the setting)
Comment 5 Behdad Esfahbod 2007-01-16 06:20:11 UTC
I need similar functionality in GOption.  I went on and implemented one in pango.

The problem is that GOption and GKeyFile are in glib, while enums/flags are in gobject.

I added this function to pango, which may be of greater interest:

/**
 * pango_parse_enum:
 * @type: enum type to parse, eg. %PANGO_TYPE_ELLIPSIZE_MODE.
 * @str: string to parse.  May be %NULL.
 * @value: integer to store the result in, or %NULL.
 * @warn: if %TRUE, issue a g_warning() on bad input.
 * @possible_values: place to store list of possible values on failure, or %NULL.
 * 
 * Parses an enum type and stored the result in @value.
 *
 * If @str does not match the nick name of any of the possible values for the
 * enum, %FALSE is returned, a warning is issued if @warn is %TRUE, and a
 * string representing the list of possible values is stored in
 * @possible_values.  The list is slash-separated, eg.
 * "none/start/middle/end".  If failed and @possible_values is not %NULL,
 * returned string should be freed using g_free().
 * 
 * Return value: %TRUE if @str was successfully parsed.
 *
 * Since: 1.16
 **/
gboolean
pango_parse_enum (GType       type,
                  const char *str,
                  int        *value,
                  gboolean    warn,
                  char      **possible_values)
{
  GEnumClass *class = NULL;
  gboolean ret = TRUE;
  GEnumValue *v = NULL;

  class = g_type_class_ref (type);

  if (G_LIKELY (str))
    v = g_enum_get_value_by_nick (class, str);

  if (v)
    {
      if (G_LIKELY (value))
        *value = v->value;
    }
  else
    {
      ret = FALSE;
      if (warn || possible_values)
        {
          int i;
          GString *s = g_string_new (NULL);

          for (i = 0, v = g_enum_get_value (class, i); v;
               i++  , v = g_enum_get_value (class, i))
            {
              if (i)
                g_string_append_c (s, '/');
              g_string_append (s, v->value_nick);
            }

          if (warn)
            g_warning ("%s must be one of %s",
                       G_ENUM_CLASS_TYPE_NAME(class),
                       s->str);

          if (possible_values)
            *possible_values = s->str;

          g_string_free (s, possible_values ? FALSE : TRUE);
        }
    }

  g_type_class_unref (class);

  return ret;
}
Comment 6 Mathias Hasselmann (IRC: tbf) 2007-09-05 10:26:24 UTC
(In reply to comment #5)
Didn't understand the purpose of your post initially, but you are right: As neither GKeyFile nor GOptions can support enums directly we should have at least this convenience API in the gobject library. Just wondering if that function shouldn't be split into two pieces: g_parse_enum and g_enum_describe_values, as I didn't understand the purpose of possible_values initially.
Comment 7 Christian Dywan 2010-03-16 16:16:22 UTC
It's unfortunate that enums cannot be supported by GKeyFile. I don't exactly see the use of the enum parsing in the context of the feature request. There is no need to enumerate and save all values just for config file handling.
Comment 8 Behdad Esfahbod 2010-03-31 20:13:56 UTC
Perhaps the relevant functions can be put in libgobject?
Comment 9 Matthias Clasen 2013-02-03 02:13:26 UTC
closing some old bugs