static void parse_error (GMarkupParseContext *context, GError *error, gpointer data) { GnomeXkbInfoPrivate *priv = GNOME_XKB_INFO (data)->priv; free_option_group (priv->current_parser_group); free_option (priv->current_parser_option); free_layout (priv->current_parser_layout); free_layout (priv->current_parser_variant); g_free (priv->current_parser_iso639Id); }
static void parse_text (GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer data, GError **error) { GnomeXkbInfoPrivate *priv = GNOME_XKB_INFO (data)->priv; if (priv->current_parser_text) { *priv->current_parser_text = g_strndup (text, text_len); priv->current_parser_text = NULL; } }
static void gnome_xkb_info_finalize (GObject *self) { GnomeXkbInfoPrivate *priv = GNOME_XKB_INFO (self)->priv; if (priv->option_groups_table) g_hash_table_destroy (priv->option_groups_table); if (priv->layouts_by_short_desc) g_hash_table_destroy (priv->layouts_by_short_desc); if (priv->layouts_by_iso639) g_hash_table_destroy (priv->layouts_by_iso639); if (priv->layouts_table) g_hash_table_destroy (priv->layouts_table); G_OBJECT_CLASS (gnome_xkb_info_parent_class)->finalize (self); }
static void parse_end_element (GMarkupParseContext *context, const gchar *element_name, gpointer data, GError **error) { GnomeXkbInfoPrivate *priv = GNOME_XKB_INFO (data)->priv; if (strcmp (element_name, "layout") == 0) { if (!priv->current_parser_layout->description || !priv->current_parser_layout->xkb_name) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'layout' elements must enclose 'description' and 'name' elements"); return; } priv->current_parser_layout->id = g_strdup (priv->current_parser_layout->xkb_name); if (g_hash_table_contains (priv->layouts_table, priv->current_parser_layout->id)) { if (priv->current_parser_layout != NULL) { free_layout (priv->current_parser_layout); priv->current_parser_layout = NULL; } return; } if (priv->current_parser_layout->short_desc) maybe_replace (priv->layouts_by_short_desc, priv->current_parser_layout->short_desc, priv->current_parser_layout); g_hash_table_replace (priv->layouts_table, priv->current_parser_layout->id, priv->current_parser_layout); priv->current_parser_layout = NULL; } else if (strcmp (element_name, "variant") == 0) { if (!priv->current_parser_variant->description || !priv->current_parser_variant->xkb_name) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'variant' elements must enclose 'description' and 'name' elements"); return; } priv->current_parser_variant->id = g_strjoin ("+", priv->current_parser_layout->xkb_name, priv->current_parser_variant->xkb_name, NULL); if (priv->current_parser_variant->short_desc) maybe_replace (priv->layouts_by_short_desc, priv->current_parser_variant->short_desc, priv->current_parser_variant); g_hash_table_replace (priv->layouts_table, priv->current_parser_variant->id, priv->current_parser_variant); priv->current_parser_variant = NULL; } else if (strcmp (element_name, "iso639Id") == 0) { gboolean replaced = FALSE; if (!priv->current_parser_iso639Id) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'iso639Id' elements must enclose text"); return; } if (priv->current_parser_layout) replaced = maybe_replace (priv->layouts_by_iso639, priv->current_parser_iso639Id, priv->current_parser_layout); else if (priv->current_parser_variant) replaced = maybe_replace (priv->layouts_by_iso639, priv->current_parser_iso639Id, priv->current_parser_variant); if (!replaced) g_free (priv->current_parser_iso639Id); priv->current_parser_iso639Id = NULL; } else if (strcmp (element_name, "group") == 0) { if (!priv->current_parser_group->description || !priv->current_parser_group->id) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'group' elements must enclose 'description' and 'name' elements"); return; } g_hash_table_replace (priv->option_groups_table, priv->current_parser_group->id, priv->current_parser_group); priv->current_parser_group = NULL; } else if (strcmp (element_name, "option") == 0) { if (!priv->current_parser_option->description || !priv->current_parser_option->id) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'option' elements must enclose 'description' and 'name' elements"); return; } g_hash_table_replace (priv->current_parser_group->options_table, priv->current_parser_option->id, priv->current_parser_option); priv->current_parser_option = NULL; } }
static void parse_start_element (GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer data, GError **error) { GnomeXkbInfoPrivate *priv = GNOME_XKB_INFO (data)->priv; if (priv->current_parser_text) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "Expected character data but got element '%s'", element_name); return; } if (strcmp (element_name, "name") == 0) { if (priv->current_parser_variant) priv->current_parser_text = &priv->current_parser_variant->xkb_name; else if (priv->current_parser_layout) priv->current_parser_text = &priv->current_parser_layout->xkb_name; else if (priv->current_parser_option) priv->current_parser_text = &priv->current_parser_option->id; else if (priv->current_parser_group) priv->current_parser_text = &priv->current_parser_group->id; } else if (strcmp (element_name, "description") == 0) { if (priv->current_parser_variant) priv->current_parser_text = &priv->current_parser_variant->description; else if (priv->current_parser_layout) priv->current_parser_text = &priv->current_parser_layout->description; else if (priv->current_parser_option) priv->current_parser_text = &priv->current_parser_option->description; else if (priv->current_parser_group) priv->current_parser_text = &priv->current_parser_group->description; } else if (strcmp (element_name, "shortDescription") == 0) { if (priv->current_parser_variant) priv->current_parser_text = &priv->current_parser_variant->short_desc; else if (priv->current_parser_layout) priv->current_parser_text = &priv->current_parser_layout->short_desc; } else if (strcmp (element_name, "iso639Id") == 0) { priv->current_parser_text = &priv->current_parser_iso639Id; } else if (strcmp (element_name, "layout") == 0) { if (priv->current_parser_layout) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'layout' elements can't be nested"); return; } priv->current_parser_layout = g_slice_new0 (Layout); } else if (strcmp (element_name, "variant") == 0) { Layout *layout; if (priv->current_parser_variant) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'variant' elements can't be nested"); return; } if (!priv->current_parser_layout) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'variant' elements must be inside 'layout' elements"); return; } if (!priv->current_parser_layout->xkb_name) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'variant' elements must be inside named 'layout' elements"); return; } layout = g_hash_table_lookup (priv->layouts_table, priv->current_parser_layout->xkb_name); if (!layout) layout = priv->current_parser_layout; priv->current_parser_variant = g_slice_new0 (Layout); priv->current_parser_variant->is_variant = TRUE; priv->current_parser_variant->main_layout = layout; } else if (strcmp (element_name, "group") == 0) { if (priv->current_parser_group) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'group' elements can't be nested"); return; } priv->current_parser_group = g_slice_new0 (XkbOptionGroup); /* Maps option ids to XkbOption structs. Owns the XkbOption structs. */ priv->current_parser_group->options_table = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, free_option); g_markup_collect_attributes (element_name, attribute_names, attribute_values, error, G_MARKUP_COLLECT_BOOLEAN | G_MARKUP_COLLECT_OPTIONAL, "allowMultipleSelection", &priv->current_parser_group->allow_multiple_selection, G_MARKUP_COLLECT_INVALID); } else if (strcmp (element_name, "option") == 0) { if (priv->current_parser_option) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'option' elements can't be nested"); return; } if (!priv->current_parser_group) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'option' elements must be inside 'group' elements"); return; } priv->current_parser_option = g_slice_new0 (XkbOption); } }
static void parse_end_element (GMarkupParseContext *context, const gchar *element_name, gpointer data, GError **error) { GnomeXkbInfoPrivate *priv = GNOME_XKB_INFO (data)->priv; if (strcmp (element_name, "layout") == 0) { if (!priv->current_parser_layout->description || !priv->current_parser_layout->xkb_name) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'layout' elements must enclose 'description' and 'name' elements"); return; } priv->current_parser_layout->id = g_strdup (priv->current_parser_layout->xkb_name); if (g_hash_table_contains (priv->layouts_table, priv->current_parser_layout->id)) { g_clear_pointer (&priv->current_parser_layout, free_layout); return; } g_hash_table_replace (priv->layouts_table, priv->current_parser_layout->id, priv->current_parser_layout); add_layout_to_locale_tables (priv->current_parser_layout, priv->layouts_by_language, priv->layouts_by_country); priv->current_parser_layout = NULL; } else if (strcmp (element_name, "variant") == 0) { if (!priv->current_parser_variant->description || !priv->current_parser_variant->xkb_name) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'variant' elements must enclose 'description' and 'name' elements"); return; } priv->current_parser_variant->id = g_strjoin ("+", priv->current_parser_layout->xkb_name, priv->current_parser_variant->xkb_name, NULL); g_hash_table_replace (priv->layouts_table, priv->current_parser_variant->id, priv->current_parser_variant); add_layout_to_locale_tables (priv->current_parser_variant, priv->layouts_by_language, priv->layouts_by_country); priv->current_parser_variant = NULL; } else if (strcmp (element_name, "iso639Id") == 0) { if (!priv->current_parser_iso639Id) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'iso639Id' elements must enclose text"); return; } if (priv->current_parser_variant) add_iso639 (priv->current_parser_variant, priv->current_parser_iso639Id); else if (priv->current_parser_layout) add_iso639 (priv->current_parser_layout, priv->current_parser_iso639Id); priv->current_parser_iso639Id = NULL; } else if (strcmp (element_name, "iso3166Id") == 0) { if (!priv->current_parser_iso3166Id) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'iso3166Id' elements must enclose text"); return; } if (priv->current_parser_variant) add_iso3166 (priv->current_parser_variant, priv->current_parser_iso3166Id); else if (priv->current_parser_layout) add_iso3166 (priv->current_parser_layout, priv->current_parser_iso3166Id); priv->current_parser_iso3166Id = NULL; } else if (strcmp (element_name, "group") == 0) { if (!priv->current_parser_group->description || !priv->current_parser_group->id) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'group' elements must enclose 'description' and 'name' elements"); return; } g_hash_table_replace (priv->option_groups_table, priv->current_parser_group->id, priv->current_parser_group); priv->current_parser_group = NULL; } else if (strcmp (element_name, "option") == 0) { if (!priv->current_parser_option->description || !priv->current_parser_option->id) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "'option' elements must enclose 'description' and 'name' elements"); return; } g_hash_table_replace (priv->current_parser_group->options_table, priv->current_parser_option->id, priv->current_parser_option); priv->current_parser_option = NULL; } }