Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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;
    }
}
Ejemplo n.º 3
0
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);
}
Ejemplo n.º 4
0
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;
    }
}
Ejemplo n.º 5
0
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);
    }
}
Ejemplo n.º 6
0
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;
    }
}