static gboolean
check_parent (GMarkupParseContext  *context,
              const gchar          *element_name,
              GError              **error)
{
  const GSList *stack;
  const gchar *parent_name;
  const gchar *our_name;

  stack = g_markup_parse_context_get_element_stack (context);
  our_name = stack->data;
  parent_name = stack->next ? stack->next->data : "";

  if (g_strcmp0 (parent_name, element_name) != 0)
    {
      gint line;
      gint col;

      g_markup_parse_context_get_position (context, &line, &col);
      g_set_error (error,
                   GTK_BUILDER_ERROR,
                   GTK_BUILDER_ERROR_INVALID_TAG,
                   "%d:%d: Element <%s> found in <%s>, expected <%s>.",
                   line, col, our_name, parent_name, element_name);
      return FALSE;
    }

  return TRUE;
}
Example #2
0
static void
start_element (GMarkupParseContext  *context,
	       const gchar          *element_name,
	       const gchar         **attribute_names,
	       const gchar         **attribute_values,
	       gpointer              user_data,
	       GError              **error)
{
  ParseState *state = user_data;
  const GSList *element_stack;
  const gchar *container;

  element_stack = g_markup_parse_context_get_element_stack (context);
  container = element_stack->next ? element_stack->next->data : NULL;

#define COLLECT(first, ...) \
  g_markup_collect_attributes (element_name,                                 \
			       attribute_names, attribute_values, error,     \
			       first, __VA_ARGS__, G_MARKUP_COLLECT_INVALID)
#define OPTIONAL   G_MARKUP_COLLECT_OPTIONAL
#define STRDUP     G_MARKUP_COLLECT_STRDUP
#define STRING     G_MARKUP_COLLECT_STRING
#define BOOL       G_MARKUP_COLLECT_BOOLEAN
#define NO_ATTRS()  COLLECT (G_MARKUP_COLLECT_INVALID, NULL)

  if (container == NULL)
    {
      if (strcmp (element_name, "gresources") == 0)
	return;
    }
  else if (strcmp (container, "gresources") == 0)
    {
      if (strcmp (element_name, "gresource") == 0)
	{
	  COLLECT (OPTIONAL | STRDUP,
		   "prefix", &state->prefix);
	  return;
	}
    }
  else if (strcmp (container, "gresource") == 0)
    {
      if (strcmp (element_name, "file") == 0)
	{
	  COLLECT (OPTIONAL | STRDUP, "alias", &state->alias,
		   OPTIONAL | BOOL, "compressed", &state->compressed,
                   OPTIONAL | STRDUP, "preprocess", &state->preproc_options);
	  state->string = g_string_new ("");
	  return;
	}
    }

  if (container)
    g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
		 _("Element <%s> not allowed inside <%s>"),
		 element_name, container);
  else
    g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
		 _("Element <%s> not allowed at toplevel"), element_name);

}
Example #3
0
void KeyConfig::start_element(GMarkupParseContext *context,
    const char *element_name, const char **attribute_names,
    const char **attribute_values, GError **error)
{
  const GSList *stack = g_markup_parse_context_get_element_stack(context);
  guint size = g_slist_length(const_cast<GSList*>(stack));
  if (size == 1) {
    if (strcmp(element_name, "keyconfig")) {
      *error = g_error_new(g_markup_error_quark(), G_MARKUP_ERROR_PARSE,
          _("Expected 'keyconfig' element, found '%s'"), element_name);
    }
  }
  else if (size == 2) {
    if (strcmp(element_name, "bind")) {
      *error = g_error_new(g_markup_error_quark(), G_MARKUP_ERROR_PARSE,
          _("Expected 'bind' element, found '%s'"), element_name);
      return;
    }

    const char *context;
    const char *action;
    const char *key;
    if (!g_markup_collect_attributes (element_name, attribute_names,
          attribute_values, error,
          G_MARKUP_COLLECT_STRING, "context", &context,
          G_MARKUP_COLLECT_STRING, "action", &action,
          G_MARKUP_COLLECT_STRING, "key", &key,
          G_MARKUP_COLLECT_INVALID))
      return;

    if (!BindKey(context, action, key)) {
      *error = g_error_new(g_markup_error_quark(), G_MARKUP_ERROR_INVALID_CONTENT,
          _("Unrecognized key '%s'"), key);
      return;
    }
  }
  else
    *error = g_error_new(g_markup_error_quark(), G_MARKUP_ERROR_PARSE,
        _("Unexpected element '%s'"), element_name);
}
static void
views_parser_start_element (GMarkupParseContext  *context,
                            const gchar          *element_name,
                            const gchar         **attribute_names,
                            const gchar         **attribute_values,
                            gpointer              user_data,
                            GError              **error)
{
  ViewsParserData *parser_data = user_data;
  GtkWidget *item;

  g_assert (context != NULL);
  g_assert (element_name != NULL);
  g_assert (parser_data != NULL);

  if (g_strcmp0 (element_name, "views") == 0)
    {
    }
  else if (g_strcmp0 (element_name, "view") == 0)
    {
      const gchar *name = NULL;

      if (!check_parent (context, "views", error))
        return;

      if (!g_markup_collect_attributes (element_name, attribute_names, attribute_values, error,
                                        G_MARKUP_COLLECT_STRING, "name", &name,
                                        G_MARKUP_COLLECT_INVALID))
        return;

      item = g_object_new (GB_TYPE_SHORTCUTS_VIEW,
                           "view-name", name,
                           "visible", TRUE,
                           NULL);

      g_queue_push_head (parser_data->stack, g_object_ref_sink (item));
    }
  else if (g_strcmp0 (element_name, "page") == 0)
    {
      if (!check_parent (context, "view", error))
        return;

      item = g_object_new (GB_TYPE_SHORTCUTS_PAGE,
                           "visible", TRUE,
                           NULL);
      g_queue_push_head (parser_data->stack, g_object_ref_sink (item));
    }
  else if (g_strcmp0 (element_name, "column") == 0)
    {
      GtkSizeGroup *size_group;

      if (!check_parent (context, "page", error))
        return;

      size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
      g_queue_push_head (parser_data->column_image_size_groups, size_group);

      size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
      g_queue_push_head (parser_data->column_desc_size_groups, size_group);

      item = g_object_new (GB_TYPE_SHORTCUTS_COLUMN,
                           "visible", TRUE,
                           NULL);
      g_queue_push_head (parser_data->stack, g_object_ref_sink (item));
    }
  else if (g_strcmp0 (element_name, "group") == 0)
    {
      if (!check_parent (context, "column", error))
        return;

      item = g_object_new (GB_TYPE_SHORTCUTS_GROUP,
                           "visible", TRUE,
                           NULL);
      g_queue_push_head (parser_data->stack, g_object_ref_sink (item));
    }
  else if (g_strcmp0 (element_name, "shortcut") == 0)
    {
      GtkSizeGroup *accel_size_group;
      GtkSizeGroup *desc_size_group;

      if (!check_parent (context, "group", error))
        return;

      accel_size_group = g_queue_peek_head (parser_data->column_image_size_groups);
      desc_size_group = g_queue_peek_head (parser_data->column_desc_size_groups);

      parser_data->search_item = g_object_new (GB_TYPE_SHORTCUTS_SHORTCUT,
                                               "visible", TRUE,
                                               NULL);

      item = g_object_new (GB_TYPE_SHORTCUTS_SHORTCUT,
                           "accelerator-size-group", accel_size_group,
                           "title-size-group", desc_size_group,
                           "visible", TRUE,
                           NULL);
      g_queue_push_head (parser_data->stack, g_object_ref_sink (item));
    }
  else if (g_strcmp0 (element_name, "gesture") == 0)
    {
      GtkSizeGroup *accel_size_group;
      GtkSizeGroup *desc_size_group;

      if (!check_parent (context, "group", error))
        return;

      accel_size_group = g_queue_peek_head (parser_data->column_image_size_groups);
      desc_size_group = g_queue_peek_head (parser_data->column_desc_size_groups);

      parser_data->search_item = g_object_new (GB_TYPE_SHORTCUTS_GESTURE,
                                               "visible", TRUE,
                                               NULL);

      item = g_object_new (GB_TYPE_SHORTCUTS_GESTURE,
                           "desc-size-group", desc_size_group,
                           "icon-size-group", accel_size_group,
                           "visible", TRUE,
                           NULL);
      g_queue_push_head (parser_data->stack, g_object_ref_sink (item));
    }
  else if (g_strcmp0 (element_name, "property") == 0)
    {
      const gchar *name = NULL;
      const gchar *translatable = NULL;

      item = g_queue_peek_head (parser_data->stack);

      if (item == NULL)
        {
          g_set_error (error,
                       GTK_BUILDER_ERROR,
                       GTK_BUILDER_ERROR_INVALID_TAG,
                       "Property called without a parent object");
          return;
        }

      if (!g_markup_collect_attributes (element_name, attribute_names, attribute_values, error,
                                        G_MARKUP_COLLECT_STRING, "name", &name,
                                        G_MARKUP_COLLECT_OPTIONAL | G_MARKUP_COLLECT_STRING, "translatable", &translatable,
                                        G_MARKUP_COLLECT_INVALID))
        return;

      g_free (parser_data->property_name);
      parser_data->property_name = g_strdup (name);
      parser_data->translatable = (g_strcmp0 (translatable, "yes") == 0);
    }
  else
    {
      const GSList *stack;
      const gchar *parent_name;
      const gchar *our_name;
      gint line;
      gint col;

      stack = g_markup_parse_context_get_element_stack (context);
      our_name = stack->data;
      parent_name = stack->next ? stack->next->data : "";

      g_markup_parse_context_get_position (context, &line, &col);
      g_set_error (error,
                   GTK_BUILDER_ERROR,
                   GTK_BUILDER_ERROR_INVALID_TAG,
                   "%d:%d: Unknown element <%s> found in <%s>.",
                   line, col, our_name, parent_name);
    }
}
Example #5
0
static void
start_element (GMarkupParseContext  *context,
               const gchar          *element_name,
               const gchar         **attribute_names,
               const gchar         **attribute_values,
               gpointer              user_data,
               GError              **error)
{
  ParseState *state = user_data;
  const GSList *element_stack;
  const gchar *container;

  element_stack = g_markup_parse_context_get_element_stack (context);
  container = element_stack->next ? element_stack->next->data : NULL;

#define COLLECT(first, ...) \
  g_markup_collect_attributes (element_name,                                 \
                               attribute_names, attribute_values, error,     \
                               first, __VA_ARGS__, G_MARKUP_COLLECT_INVALID)
#define OPTIONAL   G_MARKUP_COLLECT_OPTIONAL
#define STRDUP     G_MARKUP_COLLECT_STRDUP
#define STRING     G_MARKUP_COLLECT_STRING
#define NO_ATTRS()  COLLECT (G_MARKUP_COLLECT_INVALID, NULL)

  if (container == NULL)
    {
      if (strcmp (element_name, "schemalist") == 0)
        {
          COLLECT (OPTIONAL | STRDUP,
                   "gettext-domain",
                   &state->schemalist_domain);
          return;
        }
    }
  else if (strcmp (container, "schemalist") == 0)
    {
      if (strcmp (element_name, "schema") == 0)
        {
          const gchar *id, *path;

          if (COLLECT (STRING, "id", &id,
                       OPTIONAL | STRING, "path", &path,
                       OPTIONAL | STRDUP, "gettext-domain",
                                          &state->schema_domain))
            {
              if (!g_hash_table_lookup (state->schemas, id))
                {
                  state->schema = gvdb_hash_table_new (state->schemas, id);
                  state->schema_root = gvdb_hash_table_insert (state->schema, "");

                  if (path != NULL)
                    gvdb_hash_table_insert_string (state->schema,
                                                   ".path", path);
                }
              else
                g_set_error (error, G_MARKUP_ERROR,
                             G_MARKUP_ERROR_INVALID_CONTENT,
                             "<schema id='%s'> already specified", id);
            }
          return;
        }
    }
  else if (strcmp (container, "schema") == 0)
    {
      if (strcmp (element_name, "key") == 0)
        {
          const gchar *name, *type;

          if (COLLECT (STRING, "name", &name, STRING, "type", &type))
            {
              if (!is_valid_keyname (name, error))
                return;

              if (!g_hash_table_lookup (state->schema, name))
                {
                  state->key = gvdb_hash_table_insert (state->schema, name);
                  gvdb_item_set_parent (state->key, state->schema_root);
                }
              else
                {
                  g_set_error (error, G_MARKUP_ERROR,
                               G_MARKUP_ERROR_INVALID_CONTENT,
                               "<key name='%s'> already specified", name);
                  return;
                }

              if (g_variant_type_string_is_valid (type))
                state->type = g_variant_type_new (type);
              else
                {
                  g_set_error (error, G_MARKUP_ERROR,
                               G_MARKUP_ERROR_INVALID_CONTENT,
                               "invalid GVariant type string '%s'", type);
                  return;
                }

              g_variant_builder_init (&state->key_options,
                                      G_VARIANT_TYPE ("a{sv}"));
            }

          return;
        }
      else if (strcmp (element_name, "child") == 0)
        {
          const gchar *name, *schema;

          if (COLLECT (STRING, "name", &name, STRING, "schema", &schema))
            {
              gchar *childname;

              if (!is_valid_keyname (name, error))
                return;

              childname = g_strconcat (name, "/", NULL);

              if (!g_hash_table_lookup (state->schema, childname))
                gvdb_hash_table_insert_string (state->schema, childname, schema);
              else
                g_set_error (error, G_MARKUP_ERROR,
                             G_MARKUP_ERROR_INVALID_CONTENT,
                             "<child name='%s'> already specified", name);

              g_free (childname);
              return;
            }
        }
    }
  else if (strcmp (container, "key") == 0)
    {
      if (strcmp (element_name, "default") == 0)
        {
          const gchar *l10n;

          if (COLLECT (STRING | OPTIONAL, "l10n", &l10n,
                       STRDUP | OPTIONAL, "context", &state->context))
            {
              if (l10n != NULL)
                {
                  if (!g_hash_table_lookup (state->schema, ".gettext-domain"))
                    {
                      const gchar *domain = state->schema_domain ?
                                            state->schema_domain :
                                            state->schemalist_domain;

                      if (domain == NULL)
                        {
                          g_set_error_literal (error, G_MARKUP_ERROR,
                                               G_MARKUP_ERROR_INVALID_CONTENT,
                                               "l10n requested, but no "
                                               "gettext domain given");
                          return;
                        }

                      gvdb_hash_table_insert_string (state->schema,
                                                     ".gettext-domain",
                                                     domain);

                      if (strcmp (l10n, "messages") == 0)
                        state->l10n = 'm';
                      else if (strcmp (l10n, "time") == 0)
                        state->l10n = 't';
                      else
                        {
                          g_set_error (error, G_MARKUP_ERROR,
                                       G_MARKUP_ERROR_INVALID_CONTENT,
                                       "unsupported l10n category: %s", l10n);
                          return;
                        }
                    }
                }
              else
                {
                  state->l10n = '\0';

                  if (state->context != NULL)
                    {
                      g_set_error_literal (error, G_MARKUP_ERROR,
                                           G_MARKUP_ERROR_INVALID_CONTENT,
                                           "translation context given for "
                                           " value without l10n enabled");
                      return;
                    }
                }

              state->string = g_string_new (NULL);
            }

          return;
        }
      else if (strcmp (element_name, "summary") == 0 ||
               strcmp (element_name, "description") == 0)
        {
          state->string = g_string_new (NULL);
          NO_ATTRS ();
          return;
        }
      else if (strcmp (element_name, "range") == 0)
        {
          const gchar *min_str, *max_str;

          if (!type_allows_range (state->type))
            {
              gchar *type = g_variant_type_dup_string (state->type);
              g_set_error (error, G_MARKUP_ERROR,
                          G_MARKUP_ERROR_INVALID_CONTENT,
                          "Element <%s> not allowed for keys of type \"%s\"\n",
                          element_name, type);
              g_free (type);
              return;
            }

          if (!COLLECT (STRING, "min", &min_str,
                        STRING, "max", &max_str))
            return;

          state->min = g_variant_parse (state->type, min_str, NULL, NULL, error);
          if (state->min == NULL)
            return;

          state->max = g_variant_parse (state->type, max_str, NULL, NULL, error);
          if (state->max == NULL)
            return;

          if (g_variant_compare (state->min, state->max) > 0)
            {
              g_set_error (error, G_MARKUP_ERROR,
                           G_MARKUP_ERROR_INVALID_CONTENT,
                           "Element <%s> specified minimum is greater than maxmimum",
                           element_name);
              return;
            }

          g_variant_builder_add (&state->key_options, "{sv}", "range",
                                 g_variant_new ("(@?@?)", state->min, state->max));
          return;
        }
      else if (strcmp (element_name, "choices") == 0)
        {
          if (!type_allows_choices (state->type))
            {
              gchar *type = g_variant_type_dup_string (state->type);
              g_set_error (error, G_MARKUP_ERROR,
                           G_MARKUP_ERROR_INVALID_CONTENT,
                           "Element <%s> not allowed for keys of type \"%s\"\n",
                           element_name, type);
              g_free (type);
              return;
            }

          state->choices = g_string_new ("\xff");

          NO_ATTRS ();
          return;
        }
    }
  else if (strcmp (container, "choices") == 0)
    {
      if (strcmp (element_name, "choice") == 0)
        {
          const gchar *value;

          if (COLLECT (STRING, "value", &value))
            g_string_append_printf (state->choices, "%s\xff", value);

          return;
        }
    }

  if (container)
    g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
                 "Element <%s> not allowed inside <%s>\n",
                 element_name, container);
  else
    g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
                 "Element <%s> not allowed at toplevel\n", element_name);
}