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;
}
Пример #2
0
static void
error_invalid_tag (ParserData *data,
		   const gchar *tag,
		   const gchar *expected,
		   GError **error)
{
  gint line_number, char_number;

  g_markup_parse_context_get_position (data->ctx,
                                       &line_number,
                                       &char_number);

  if (expected)
    g_set_error (error,
		 GTK_BUILDER_ERROR,
		 GTK_BUILDER_ERROR_INVALID_TAG,
		 "%s:%d:%d '%s' is not a valid tag here, expected a '%s' tag",
		 data->filename,
		 line_number, char_number, tag, expected);
  else
    g_set_error (error,
		 GTK_BUILDER_ERROR,
		 GTK_BUILDER_ERROR_INVALID_TAG,
		 "%s:%d:%d '%s' is not a valid tag here",
		 data->filename,
		 line_number, char_number, tag);
}
Пример #3
0
lfError lfDatabase::Load (const char *errcontext, const char *data, size_t data_size)
{
    static GMarkupParser gmp =
    {
        _xml_start_element,
        _xml_end_element,
        _xml_text,
        NULL,
        NULL
    };

    lfExtDatabase *This = static_cast<lfExtDatabase *> (this);

    /* Temporarily drop numeric format to "C" */
    char *old_numeric = setlocale (LC_NUMERIC, NULL);
    old_numeric = strdup(old_numeric);
    setlocale(LC_NUMERIC,"C");

    /* eek! GPtrArray does not have a method to insert a pointer
     into middle of the array... We have to remove the trailing
     NULL and re-append it after loading ... */
    g_ptr_array_remove_index_fast (This->Mounts, This->Mounts->len - 1);
    g_ptr_array_remove_index_fast (This->Cameras, This->Cameras->len - 1);
    g_ptr_array_remove_index_fast (This->Lenses, This->Lenses->len - 1);

    lfParserData pd;
    memset (&pd, 0, sizeof (pd));
    pd.db = This;

    GMarkupParseContext *mpc = g_markup_parse_context_new (
        &gmp, (GMarkupParseFlags)0, &pd, NULL);

    GError *err = NULL;
    lfError e = g_markup_parse_context_parse (mpc, data, data_size, &err) ?
        LF_NO_ERROR : LF_WRONG_FORMAT;

    /* Display the parsing error as a warning */
    if (e != LF_NO_ERROR)
    {
        gint line, col;
        g_markup_parse_context_get_position (mpc, &line, &col);
        g_warning ("%s:%d:%d: %s", errcontext, line, col, err->message);
    }

    g_markup_parse_context_free (mpc);

    /* Re-add the trailing NULL */
    g_ptr_array_add (This->Mounts, NULL);
    g_ptr_array_add (This->Cameras, NULL);
    g_ptr_array_add (This->Lenses, NULL);

    /* Restore numeric format */
    setlocale (LC_NUMERIC, old_numeric);
    free(old_numeric);

    return e;
}
Пример #4
0
static void
parse_requires (ParserData   *data,
		const gchar  *element_name,
		const gchar **names,
		const gchar **values,
		GError      **error)
{
  RequiresInfo *req_info;
  const gchar  *library = NULL;
  const gchar  *version = NULL;
  gchar       **split;
  gint          i, version_major = 0, version_minor = 0;
  gint          line_number, char_number;

  g_markup_parse_context_get_position (data->ctx,
                                       &line_number,
                                       &char_number);

  for (i = 0; names[i] != NULL; i++)
    {
      if (strcmp (names[i], "lib") == 0)
        library = values[i];
      else if (strcmp (names[i], "version") == 0)
	version = values[i];
      else
	error_invalid_attribute (data, element_name, names[i], error);
    }

  if (!library || !version)
    {
      error_missing_attribute (data, element_name, 
			       version ? "lib" : "version", error);
      return;
    }

  if (!(split = g_strsplit (version, ".", 2)) || !split[0] || !split[1])
    {
      g_set_error (error,
		   GTK_BUILDER_ERROR,
		   GTK_BUILDER_ERROR_INVALID_VALUE,
		   "%s:%d:%d <%s> attribute has malformed value \"%s\"",
		   data->filename,
		   line_number, char_number, "version", version);
      return;
    }
  version_major = g_ascii_strtoll (split[0], NULL, 10);
  version_minor = g_ascii_strtoll (split[1], NULL, 10);
  g_strfreev (split);

  req_info = g_slice_new0 (RequiresInfo);
  req_info->library = g_strdup (library);
  req_info->major   = version_major;
  req_info->minor   = version_minor;
  state_push (data, req_info);
  req_info->tag.name = element_name;
}
Пример #5
0
static void
error_unhandled_tag (ParserData   *data,
                     const gchar  *tag,
                     GError      **error)
{
  gint line, col;

  g_markup_parse_context_get_position (data->ctx, &line, &col);
  g_set_error (error,
               GTK_BUILDER_ERROR,
               GTK_BUILDER_ERROR_UNHANDLED_TAG,
               "%s:%d:%d Unhandled tag: <%s>",
               data->filename, line, col, tag);
}
Пример #6
0
static void mbpi_g_set_error(GMarkupParseContext *context, GError **error,
				GQuark domain, gint code, const gchar *fmt, ...)
{
	va_list ap;
	gint line_number, char_number;

	g_markup_parse_context_get_position(context, &line_number,
						&char_number);
	va_start(ap, fmt);

	*error = g_error_new_valist(domain, code, fmt, ap);

	va_end(ap);

	g_prefix_error(error, "%s:%d ", MBPI_DATABASE, line_number);
}
Пример #7
0
static void
error_missing_attribute (ParserData   *data,
                         const gchar  *tag,
                         const gchar  *attribute,
                         GError      **error)
{
  gint line, col;

  g_markup_parse_context_get_position (data->ctx, &line, &col);

  g_set_error (error,
               GTK_BUILDER_ERROR,
               GTK_BUILDER_ERROR_MISSING_ATTRIBUTE,
               "%s:%d:%d <%s> requires attribute '%s'",
               data->filename, line, col, tag, attribute);
}
Пример #8
0
static void
set_bad_attribute (GError             **error,
		   GMarkupParseContext *context,
		   const char          *element_name,
		   const char          *attribute_name)
{
  gint line_number, char_number;

  g_markup_parse_context_get_position (context,
				       &line_number, &char_number);

  g_set_error (error,
	       G_MARKUP_ERROR,
	       G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
	       _("Tag '%s' does not support attribute '%s' on line %d char %d"),
	       element_name,
	       attribute_name,
	       line_number, char_number);
}
Пример #9
0
static void
error_invalid_attribute (ParserData *data,
                         const gchar *tag,
                         const gchar *attribute,
                         GError **error)
{
  gint line_number, char_number;

  g_markup_parse_context_get_position (data->ctx,
                                       &line_number,
                                       &char_number);

  g_set_error (error,
               GTK_BUILDER_ERROR,
               GTK_BUILDER_ERROR_INVALID_ATTRIBUTE,
               "%s:%d:%d '%s' is not a valid attribute of <%s>",
               data->filename,
               line_number, char_number, attribute, tag);
}
Пример #10
0
static void
pdb_loader_set_error(PDBLoader *state, GError **error, const gchar *format, ...)
{
  gchar *error_text;
  gchar *error_location;
  gint line_number, col_number;
  va_list va;

  va_start(va, format);
  error_text = g_strdup_vprintf(format, va);
  va_end(va);

  g_markup_parse_context_get_position(state->context, &line_number, &col_number);
  error_location = g_strdup_printf("%s:%d:%d", state->filename, line_number, col_number);

  g_set_error(error, PDB_ERROR, PDB_ERROR_FAILED, "%s: %s", error_location, error_text);

  g_free(error_text);
  g_free(error_location);
}
Пример #11
0
/* report an error and propagate it */
static void
parse_error (XMPParseContext  *context,
             GError          **error,
             XMPParseError     code,
             const gchar      *format,
             ...)
{
  GError  *tmp_error;

  if (code == XMP_ERROR_NO_XPACKET)
    tmp_error = g_error_new (XMP_PARSE_ERROR, code,
                             _("Error: No XMP packet found"));
  else
    {
      gchar   *s;
      va_list  args;
      gint     line_number;
      gint     char_number;

      va_start (args, format);
      s = g_strdup_vprintf (format, args);
      va_end (args);

      g_markup_parse_context_get_position (context->markup_context,
                                           &line_number,
                                           &char_number);
      tmp_error = g_error_new (XMP_PARSE_ERROR, code,
                               _("Error on line %d char %d: %s"),
                               line_number, char_number, s);
      g_free (s);
    }

  context->state = STATE_ERROR;
  if (context->parser->error)
    (*context->parser->error) (context, tmp_error, context->user_data);

  g_propagate_error (error, tmp_error);
}
Пример #12
0
static void
set_error (GError              **err,
           GMarkupParseContext  *context,
           int                   error_domain,
           int                   error_code,
           const char           *format,
           ...)
{
  gint     line, ch;
  va_list  args;
  gchar   *str;

  g_markup_parse_context_get_position (context, &line, &ch);

  va_start (args, format);
  str = g_strdup_vprintf (format, args);
  va_end (args);

  g_set_error (err, error_domain, error_code,
               ("Line %d character %d: %s"),
               line, ch, str);

  g_free (str);
}
Пример #13
0
static void
parse_start_element_cb (GMarkupParseContext *context,
			const char *element_name,
			const char **attribute_names,
			const char **attribute_values,
			gpointer data,
			GError **error)
{
  struct parse_state *state;
  int line, col;

  state = data;
  g_markup_parse_context_get_position (context, &line, &col);

  switch (state->state)
    {
    case STATE_START:
      if (EQ (element_name, ELEMENT_TOPLEVEL))
	{
	  const char *version_str;

	  state->state = STATE_IN_TOPLEVEL;

	  version_str = get_attribute_value (attribute_names, attribute_values, ATTRIBUTE_VERSION);
	  if (!version_str)
	    state->version = -1;
	  else
	    if (sscanf (version_str, "%d", &state->version) != 1 || state->version < 0)
	      state->version = -1;
	}
      else
	{
	  state->state = STATE_ERROR;
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_UNKNOWN_ELEMENT,
		       _("Line %d, column %d: expected \"%s\" at the toplevel, but found \"%s\" instead"),
		       line,
		       col,
		       ELEMENT_TOPLEVEL,
		       element_name);
	}
      break;

    case STATE_END:
      g_assert_not_reached ();
      break;

    case STATE_ERROR:
      g_assert_not_reached ();
      break;

    case STATE_IN_TOPLEVEL:
      if (EQ (element_name, ELEMENT_LOCATION))
	{
	  const char *location_mode_str;

	  state->state = STATE_IN_LOCATION;

	  location_mode_str = get_attribute_value (attribute_names, attribute_values, ATTRIBUTE_MODE);
	  if (!location_mode_str)
	    set_missing_attribute_error (state, line, col, ATTRIBUTE_MODE, error);
	  else if (EQ (location_mode_str, MODE_PATH_BAR))
	    state->settings->location_mode = LOCATION_MODE_PATH_BAR;
	  else if (EQ (location_mode_str, MODE_FILENAME_ENTRY))
	    state->settings->location_mode = LOCATION_MODE_FILENAME_ENTRY;
	  else
	    {
	      state->state = STATE_ERROR;
	      g_set_error (error,
			   G_MARKUP_ERROR,
			   G_MARKUP_ERROR_INVALID_CONTENT,
			   _("Line %d, column %d: expected \"%s\" or \"%s\", but found \"%s\" instead"),
			   line,
			   col,
			   MODE_PATH_BAR,
			   MODE_FILENAME_ENTRY,
			   location_mode_str);
	    }
	}
      else if (EQ (element_name, ELEMENT_SHOW_HIDDEN))
	{
	  const char *value_str;

	  state->state = STATE_IN_SHOW_HIDDEN;

	  value_str = get_attribute_value (attribute_names, attribute_values, ATTRIBUTE_VALUE);

	  if (!value_str)
	    set_missing_attribute_error (state, line, col, ATTRIBUTE_VALUE, error);
	  else if (EQ (value_str, VALUE_TRUE))
	    state->settings->show_hidden = TRUE;
	  else if (EQ (value_str, VALUE_FALSE))
	    state->settings->show_hidden = FALSE;
	  else
	    {
	      state->state = STATE_ERROR;
	      g_set_error (error,
			   G_MARKUP_ERROR,
			   G_MARKUP_ERROR_INVALID_CONTENT,
			   _("Line %d, column %d: expected \"%s\" or \"%s\", but found \"%s\" instead"),
			   line,
			   col,
			   VALUE_FALSE,
			   VALUE_TRUE,
			   value_str);
	    }
	}
      else if (EQ (element_name, ELEMENT_EXPAND_FOLDERS))
	{
	  const char *value_str;

	  state->state = STATE_IN_EXPAND_FOLDERS;

	  value_str = get_attribute_value (attribute_names, attribute_values, ATTRIBUTE_VALUE);

	  if (!value_str)
	    set_missing_attribute_error (state, line, col, ATTRIBUTE_VALUE, error);
	  else if (EQ (value_str, VALUE_TRUE))
	    state->settings->expand_folders = TRUE;
	  else if (EQ (value_str, VALUE_FALSE))
	    state->settings->expand_folders = FALSE;
	  else
	    {
	      state->state = STATE_ERROR;
	      g_set_error (error,
			   G_MARKUP_ERROR,
			   G_MARKUP_ERROR_INVALID_CONTENT,
			   _("Line %d, column %d: expected \"%s\" or \"%s\", but found \"%s\" instead"),
			   line,
			   col,
			   VALUE_FALSE,
			   VALUE_TRUE,
			   value_str);
	    }
	}
      else
	set_unexpected_element_error (state, line, col, element_name, error);

      break;

    case STATE_IN_LOCATION:
    case STATE_IN_SHOW_HIDDEN:
      set_unexpected_element_error (state, line, col, element_name, error);
      break;

    default:
      g_assert_not_reached ();
    }
}
Пример #14
0
static void
parse_property (ParserData   *data,
                const gchar  *element_name,
                const gchar **names,
                const gchar **values,
                GError      **error)
{
  PropertyInfo *info;
  const gchar *name = NULL;
  const gchar *context = NULL;
  const gchar *bind_source = NULL;
  const gchar *bind_property = NULL;
  const gchar *bind_flags_str = NULL;
  GBindingFlags bind_flags = G_BINDING_DEFAULT;
  gboolean translatable = FALSE;
  ObjectInfo *object_info;
  GParamSpec *pspec = NULL;
  gint line, col;

  object_info = state_peek_info (data, ObjectInfo);
  if (!object_info ||
      !(strcmp (object_info->tag.name, "object") == 0 ||
        strcmp (object_info->tag.name, "template") == 0))
    {
      error_invalid_tag (data, element_name, NULL, error);
      return;
    }

  if (!g_markup_collect_attributes (element_name, names, values, error,
                                    G_MARKUP_COLLECT_STRING, "name", &name,
                                    G_MARKUP_COLLECT_BOOLEAN|G_MARKUP_COLLECT_OPTIONAL, "translatable", &translatable,
                                    G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "comments", NULL,
                                    G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "context", &context,
                                    G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "bind-source", &bind_source,
                                    G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "bind-property", &bind_property,
                                    G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "bind-flags", &bind_flags_str,
                                    G_MARKUP_COLLECT_INVALID))
    {
      _gtk_builder_prefix_error (data->builder, data->ctx, error);
      return;
    }

  pspec = g_object_class_find_property (object_info->oclass, name);

  if (!pspec)
    {
      g_set_error (error,
                   GTK_BUILDER_ERROR,
                   GTK_BUILDER_ERROR_INVALID_PROPERTY,
                   "Invalid property: %s.%s",
                   g_type_name (object_info->type), name);
      _gtk_builder_prefix_error (data->builder, data->ctx, error);
      return;
    }

  if (bind_flags_str)
    {
      if (!_gtk_builder_flags_from_string (G_TYPE_BINDING_FLAGS, NULL, bind_flags_str, &bind_flags, error))
        {
          _gtk_builder_prefix_error (data->builder, data->ctx, error);
          return;
        }
    }

  g_markup_parse_context_get_position (data->ctx, &line, &col);

  if (bind_source && bind_property)
    {
      BindingInfo *binfo;

      binfo = g_slice_new (BindingInfo);
      binfo->target = NULL;
      binfo->target_pspec = pspec;
      binfo->source = g_strdup (bind_source);
      binfo->source_property = g_strdup (bind_property);
      binfo->flags = bind_flags;
      binfo->line = line;
      binfo->col = col;

      object_info->bindings = g_slist_prepend (object_info->bindings, binfo);
    }
  else if (bind_source || bind_property)
    {
      error_missing_attribute (data, element_name,
                               (bind_source) ? "bind-property" : "bind-source",
                               error);
      return;
    }

  info = g_slice_new (PropertyInfo);
  info->tag.name = element_name;
  info->pspec = pspec;
  info->text = g_string_new ("");
  info->translatable = translatable;
  info->bound = (bind_source && bind_property);
  info->context = g_strdup (context);
  info->line = line;
  info->col = col;

  state_push (data, info);
}
Пример #15
0
static void
parse_template (GMarkupParseContext  *context,
                ParserData           *data,
                const gchar          *element_name,
                const gchar         **names,
                const gchar         **values,
                GError              **error)
{
  ObjectInfo *object_info;
  const gchar *object_class = NULL;
  const gchar *parent_class = NULL;
  gint line;
  GType template_type;
  GType parsed_type;

  template_type = _gtk_builder_get_template_type (data->builder);

  if (!g_markup_collect_attributes (element_name, names, values, error,
                                    G_MARKUP_COLLECT_STRING, "class", &object_class,
                                    G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "parent", &parent_class,
                                    G_MARKUP_COLLECT_INVALID))
    {
      _gtk_builder_prefix_error (data->builder, data->ctx, error);
      return;
    }

  if (template_type == 0)
    {
      g_set_error (error,
                   GTK_BUILDER_ERROR,
                   GTK_BUILDER_ERROR_UNHANDLED_TAG,
                   "Not expecting to handle a template (class '%s', parent '%s')",
                   object_class, parent_class ? parent_class : "GtkWidget");
      _gtk_builder_prefix_error (data->builder, context, error);
      return;
    }
  else if (state_peek (data) != NULL)
    {
      error_invalid_tag (data, "template", NULL, error);
      return;
    }

  parsed_type = g_type_from_name (object_class);
  if (template_type != parsed_type)
    {
      g_set_error (error,
                   GTK_BUILDER_ERROR,
                   GTK_BUILDER_ERROR_TEMPLATE_MISMATCH,
                   "Parsed template definition for type '%s', expected type '%s'",
                   object_class, g_type_name (template_type));
      _gtk_builder_prefix_error (data->builder, context, error);
      return;
    }

  if (parent_class)
    {
      GType parent_type = g_type_from_name (parent_class);
      GType expected_type = g_type_parent (parsed_type);

      if (parent_type == G_TYPE_INVALID)
        {
          g_set_error (error, GTK_BUILDER_ERROR,
                       GTK_BUILDER_ERROR_INVALID_VALUE,
                       "Invalid template parent type '%s'", parent_class);
          _gtk_builder_prefix_error (data->builder, context, error);
          return;
        }
      if (parent_type != expected_type)
        {
          g_set_error (error, GTK_BUILDER_ERROR,
                       GTK_BUILDER_ERROR_TEMPLATE_MISMATCH,
                       "Template parent type '%s' does not match instance parent type '%s'.",
                       parent_class, g_type_name (expected_type));
          _gtk_builder_prefix_error (data->builder, context, error);
          return;
        }
    }

  ++data->cur_object_level;

  object_info = g_slice_new0 (ObjectInfo);
  object_info->tag.name = element_name;
  object_info->type = parsed_type;
  object_info->oclass = g_type_class_ref (parsed_type);
  object_info->id = g_strdup (object_class);
  object_info->object = gtk_builder_get_object (data->builder, object_class);
  state_push (data, object_info);

  line = GPOINTER_TO_INT (g_hash_table_lookup (data->object_ids, object_class));
  if (line != 0)
    {
      g_set_error (error,
                   GTK_BUILDER_ERROR,
                   GTK_BUILDER_ERROR_DUPLICATE_ID,
                   "Duplicate object ID '%s' (previously on line %d)",
                   object_class, line);
      _gtk_builder_prefix_error (data->builder, context, error);
      return;
    }

  g_markup_parse_context_get_position (context, &line, NULL);
  g_hash_table_insert (data->object_ids, g_strdup (object_class), GINT_TO_POINTER (line));
}
Пример #16
0
static void
parse_object (GMarkupParseContext  *context,
              ParserData           *data,
              const gchar          *element_name,
              const gchar         **names,
              const gchar         **values,
              GError              **error)
{
  ObjectInfo *object_info;
  ChildInfo* child_info;
  GType object_type = G_TYPE_INVALID;
  const gchar *object_class = NULL;
  const gchar *constructor = NULL;
  const gchar *type_func = NULL;
  const gchar *object_id = NULL;
  gchar *internal_id = NULL;
  gint line;

  child_info = state_peek_info (data, ChildInfo);
  if (child_info && strcmp (child_info->tag.name, "object") == 0)
    {
      error_invalid_tag (data, element_name, NULL, error);
      return;
    }

  if (!g_markup_collect_attributes (element_name, names, values, error,
                                    G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "class", &object_class,
                                    G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "constructor", &constructor,
                                    G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "type-func", &type_func,
                                    G_MARKUP_COLLECT_STRING|G_MARKUP_COLLECT_OPTIONAL, "id", &object_id,
                                    G_MARKUP_COLLECT_INVALID))
    {
      _gtk_builder_prefix_error (data->builder, data->ctx, error);
      return;
    }

  if (type_func)
    {
      /* Call the GType function, and return the GType, it's guaranteed afterwards
       * that g_type_from_name on the name will return our GType
       */
      object_type = _get_type_by_symbol (type_func);
      if (object_type == G_TYPE_INVALID)
        {
          g_set_error (error,
                       GTK_BUILDER_ERROR,
                       GTK_BUILDER_ERROR_INVALID_TYPE_FUNCTION,
                       "Invalid type function '%s'", type_func);
          _gtk_builder_prefix_error (data->builder, context, error);
          return;
        }
    }
  else if (object_class)
    {
      object_type = gtk_builder_get_type_from_name (data->builder, object_class);
      if (object_type == G_TYPE_INVALID)
        {
          g_set_error (error,
                       GTK_BUILDER_ERROR,
                       GTK_BUILDER_ERROR_INVALID_VALUE,
                       "Invalid object type '%s'", object_class);
          _gtk_builder_prefix_error (data->builder, context, error);
          return;
       }
    }
  else
    {
      error_missing_attribute (data, element_name, "class", error);
      return;
    }

  if (!object_id)
    {
      internal_id = g_strdup_printf ("___object_%d___", ++data->object_counter);
      object_id = internal_id;
    }

  ++data->cur_object_level;

  /* check if we reached a requested object (if it is specified) */
  if (data->requested_objects && !data->inside_requested_object)
    {
      if (is_requested_object (object_id, data))
        {
          data->requested_object_level = data->cur_object_level;

          GTK_NOTE (BUILDER,
                    g_message ("requested object \"%s\" found at level %d",
                               object_id, data->requested_object_level));

          data->inside_requested_object = TRUE;
        }
      else
        {
          g_free (internal_id);
          return;
        }
    }

  object_info = g_slice_new0 (ObjectInfo);
  object_info->tag.name = element_name;
  object_info->type = object_type;
  object_info->oclass = g_type_class_ref (object_type);
  object_info->id = (internal_id) ? internal_id : g_strdup (object_id);
  object_info->constructor = g_strdup (constructor);
  object_info->parent = (CommonInfo*)child_info;
  state_push (data, object_info);

  line = GPOINTER_TO_INT (g_hash_table_lookup (data->object_ids, object_id));
  if (line != 0)
    {
      g_set_error (error,
                   GTK_BUILDER_ERROR,
                   GTK_BUILDER_ERROR_DUPLICATE_ID,
                   "Duplicate object ID '%s' (previously on line %d)",
                   object_id, line);
      _gtk_builder_prefix_error (data->builder, context, error);
      return;
    }

  g_markup_parse_context_get_position (context, &line, NULL);
  g_hash_table_insert (data->object_ids, g_strdup (object_id), GINT_TO_POINTER (line));
}
Пример #17
0
static void
parse_template (GMarkupParseContext  *context,
		ParserData           *data,
		const gchar          *element_name,
		const gchar         **names,
		const gchar         **values,
		GError              **error)
{
  ObjectInfo *object_info;
  int i;
  gchar *object_class = NULL;
  gint line, line2;
  GType template_type = _gtk_builder_get_template_type (data->builder);
  GType parsed_type;

  if (template_type == 0)
    {
      g_set_error (error,
		   GTK_BUILDER_ERROR,
		   GTK_BUILDER_ERROR_UNHANDLED_TAG,
		   "Encountered template definition but not parsing a template.");
      return;
    }
  else if (state_peek (data) != NULL)
    {
      g_set_error (error,
		   GTK_BUILDER_ERROR,
		   GTK_BUILDER_ERROR_UNHANDLED_TAG,
		   "Encountered template definition that is not at the top level.");
      return;
    }

  for (i = 0; names[i] != NULL; i++)
    {
      if (strcmp (names[i], "class") == 0)
        object_class = g_strdup (values[i]);
      else if (strcmp (names[i], "parent") == 0)
        /* Ignore 'parent' attribute, however it's needed by Glade */;
      else
	{
	  error_invalid_attribute (data, element_name, names[i], error);
	  return;
	}
    }

  if (!object_class)
    {
      error_missing_attribute (data, element_name, "class", error);
      return;
    }

  parsed_type = g_type_from_name (object_class);
  if (template_type != parsed_type)
    {
      g_set_error (error,
		   GTK_BUILDER_ERROR,
		   GTK_BUILDER_ERROR_TEMPLATE_MISMATCH,
		   "Parsed template definition for type `%s', expected type `%s'.",
		   object_class, g_type_name (template_type));
      return;
    }

  ++data->cur_object_level;

  object_info = g_slice_new0 (ObjectInfo);
  object_info->class_name = object_class;
  object_info->id = g_strdup (object_class);
  object_info->object = gtk_builder_get_object (data->builder, object_class);
  state_push (data, object_info);
  object_info->tag.name = element_name;

  g_markup_parse_context_get_position (context, &line, NULL);
  line2 = GPOINTER_TO_INT (g_hash_table_lookup (data->object_ids, object_class));
  if (line2 != 0)
    {
      g_set_error (error, GTK_BUILDER_ERROR,
                   GTK_BUILDER_ERROR_DUPLICATE_ID,
                   _("Duplicate object ID '%s' on line %d (previously on line %d)"),
                   object_class, line, line2);
      return;
    }

  g_hash_table_insert (data->object_ids, g_strdup (object_class), GINT_TO_POINTER (line));
}
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);
    }
}
Пример #19
0
static void
offset_start_element (GMarkupParseContext  *context,
                      const gchar          *element_name,
                      const gchar         **names,
                      const gchar         **values,
                      gpointer              user_data,
                      GError              **error)
{
  OffsetsParserData *parser_data = user_data;
  const gchar *name = NULL;
  const gchar *value_str = NULL;
  GtkLevelBarOffset *offset;
  gint line_number, char_number;
  gint idx;

  if (strcmp (element_name, "offsets") == 0)
    ;
  else if (strcmp (element_name, "offset") == 0)
    {
      for (idx = 0; names[idx] != NULL; idx++)
        {
          if (strcmp (names[idx], "name") == 0)
            {
              name = values[idx];
            }
          else if (strcmp (names[idx], "value") == 0)
            {
              value_str = values[idx];
            }
          else
            {
              g_markup_parse_context_get_position (context,
                                                   &line_number,
                                                   &char_number);
              g_set_error (error,
                           GTK_BUILDER_ERROR,
                           GTK_BUILDER_ERROR_INVALID_ATTRIBUTE,
                           "%s:%d:%d '%s' is not a valid attribute of <%s>",
                           "<input>",
                           line_number, char_number, names[idx], "offset");

              return;
            }
        }

      if (name && value_str)
        {
          offset = gtk_level_bar_offset_new (name, g_ascii_strtod (value_str, NULL));
          parser_data->offsets = g_list_prepend (parser_data->offsets, offset);
        }
    }
  else
    {
      g_markup_parse_context_get_position (context,
                                           &line_number,
                                           &char_number);
      g_set_error (error,
                   GTK_BUILDER_ERROR,
                   GTK_BUILDER_ERROR_UNHANDLED_TAG,
                   "%s:%d:%d unsupported tag for GtkLevelBar: \"%s\"",
                   "<input>",
                   line_number, char_number, element_name);
    }
}
Пример #20
0
static void
parse_end_element_cb (GMarkupParseContext *context,
		      const char *element_name,
		      gpointer data,
		      GError **error)
{
  struct parse_state *state;
  int line, col;

  state = data;
  g_markup_parse_context_get_position (context, &line, &col);

  switch (state->state)
    {
    case STATE_START:
      g_assert_not_reached ();
      break;

    case STATE_END:
      g_assert_not_reached ();
      break;

    case STATE_ERROR:
      g_assert_not_reached ();
      break;

    case STATE_IN_TOPLEVEL:
      if (EQ (element_name, ELEMENT_TOPLEVEL))
	state->state = STATE_END;
      else
	set_unexpected_element_end_error (state, line, col, ELEMENT_TOPLEVEL, element_name, error);

      break;

    case STATE_IN_LOCATION:
      if (EQ (element_name, ELEMENT_LOCATION))
	state->state = STATE_IN_TOPLEVEL;
      else
	set_unexpected_element_end_error (state, line, col, ELEMENT_LOCATION, element_name, error);

      break;

    case STATE_IN_SHOW_HIDDEN:
      if (EQ (element_name, ELEMENT_SHOW_HIDDEN))
	state->state = STATE_IN_TOPLEVEL;
      else
	set_unexpected_element_end_error (state, line, col, ELEMENT_SHOW_HIDDEN, element_name, error);

      break;

    case STATE_IN_EXPAND_FOLDERS:
      if (EQ (element_name, ELEMENT_EXPAND_FOLDERS))
	state->state = STATE_IN_TOPLEVEL;
      else
	set_unexpected_element_end_error (state, line, col, ELEMENT_EXPAND_FOLDERS, element_name, error);

      break;

    default:
      g_assert_not_reached ();
    }
}
Пример #21
0
static void
parse_object (GMarkupParseContext  *context,
              ParserData           *data,
              const gchar          *element_name,
              const gchar         **names,
              const gchar         **values,
              GError              **error)
{
  ObjectInfo *object_info;
  ChildInfo* child_info;
  int i;
  gchar *object_class = NULL;
  gchar *object_id = NULL;
  gchar *constructor = NULL;
  gint line, line2;

  child_info = state_peek_info (data, ChildInfo);
  if (child_info && strcmp (child_info->tag.name, "object") == 0)
    {
      error_invalid_tag (data, element_name, NULL, error);
      return;
    }

  for (i = 0; names[i] != NULL; i++)
    {
      if (strcmp (names[i], "class") == 0)
        object_class = g_strdup (values[i]);
      else if (strcmp (names[i], "id") == 0)
        object_id = g_strdup (values[i]);
      else if (strcmp (names[i], "constructor") == 0)
        constructor = g_strdup (values[i]);
      else if (strcmp (names[i], "type-func") == 0)
        {
	  /* Call the GType function, and return the name of the GType,
	   * it's guaranteed afterwards that g_type_from_name on the name
	   * will return our GType
	   */
          object_class = _get_type_by_symbol (values[i]);
          if (!object_class)
            {
              g_markup_parse_context_get_position (context, &line, NULL);
              g_set_error (error, GTK_BUILDER_ERROR,
                           GTK_BUILDER_ERROR_INVALID_TYPE_FUNCTION,
                           _("Invalid type function on line %d: '%s'"),
                           line, values[i]);
              return;
            }
        }
      else
	{
	  error_invalid_attribute (data, element_name, names[i], error);
	  return;
	}
    }

  if (!object_class)
    {
      error_missing_attribute (data, element_name, "class", error);
      return;
    }

  if (!object_id)
    {
      error_missing_attribute (data, element_name, "id", error);
      return;
    }

  ++data->cur_object_level;

  /* check if we reached a requested object (if it is specified) */
  if (data->requested_objects && !data->inside_requested_object)
    {
      if (is_requested_object (object_id, data))
        {
          data->requested_object_level = data->cur_object_level;

          GTK_NOTE (BUILDER, g_print ("requested object \"%s\" found at level %d\n",
                                      object_id,
                                      data->requested_object_level));

          data->inside_requested_object = TRUE;
        }
      else
        {
          g_free (object_class);
          g_free (object_id);
          g_free (constructor);
          return;
        }
    }

  object_info = g_slice_new0 (ObjectInfo);
  object_info->class_name = object_class;
  object_info->id = object_id;
  object_info->constructor = constructor;
  state_push (data, object_info);
  object_info->tag.name = element_name;

  if (child_info)
    object_info->parent = (CommonInfo*)child_info;

  g_markup_parse_context_get_position (context, &line, NULL);
  line2 = GPOINTER_TO_INT (g_hash_table_lookup (data->object_ids, object_id));
  if (line2 != 0)
    {
      g_set_error (error, GTK_BUILDER_ERROR,
                   GTK_BUILDER_ERROR_DUPLICATE_ID,
                   _("Duplicate object id '%s' on line %d (previously on line %d)"),
                   object_id, line, line2);
      return;
    }


  g_hash_table_insert (data->object_ids, g_strdup (object_id), GINT_TO_POINTER (line));
}
Пример #22
0
static gboolean
span_parse_func     (MarkupData            *md,
		     OpenTag               *tag,
		     const gchar          **names,
		     const gchar          **values,
		     GMarkupParseContext   *context,
		     GError               **error)
{
  int line_number, char_number;
  int i;

  const char *family = NULL;
  const char *size = NULL;
  const char *style = NULL;
  const char *weight = NULL;
  const char *variant = NULL;
  const char *stretch = NULL;
  const char *desc = NULL;
  const char *foreground = NULL;
  const char *background = NULL;
  const char *underline = NULL;
  const char *underline_color = NULL;
  const char *strikethrough = NULL;
  const char *strikethrough_color = NULL;
  const char *rise = NULL;
  const char *letter_spacing = NULL;
  const char *lang = NULL;
  const char *fallback = NULL;
  const char *gravity = NULL;
  const char *gravity_hint = NULL;

  g_markup_parse_context_get_position (context,
				       &line_number, &char_number);

#define CHECK_DUPLICATE(var) G_STMT_START{                              \
	  if ((var) != NULL) {                                          \
	    g_set_error (error, G_MARKUP_ERROR,                         \
			 G_MARKUP_ERROR_INVALID_CONTENT,                \
			 _("Attribute '%s' occurs twice on <span> tag " \
			   "on line %d char %d, may only occur once"),  \
			 names[i], line_number, char_number);           \
	    return FALSE;                                               \
	  }}G_STMT_END
#define CHECK_ATTRIBUTE2(var, name) \
	if (attr_strcmp (names[i], (name)) == 0) { \
	  CHECK_DUPLICATE (var); \
	  (var) = values[i]; \
	  found = TRUE; \
	  break; \
	}
#define CHECK_ATTRIBUTE(var) CHECK_ATTRIBUTE2 (var, G_STRINGIFY (var))

  i = 0;
  while (names[i])
    {
      gboolean found = FALSE;

      switch (names[i][0]) {
      case 'f':
	CHECK_ATTRIBUTE (fallback);
	CHECK_ATTRIBUTE2(desc, "font");
	CHECK_ATTRIBUTE2(desc, "font_desc");
	CHECK_ATTRIBUTE2(family, "face");

	CHECK_ATTRIBUTE2(family, "font_family");
	CHECK_ATTRIBUTE2(size, "font_size");
	CHECK_ATTRIBUTE2(stretch, "font_stretch");
	CHECK_ATTRIBUTE2(style, "font_style");
	CHECK_ATTRIBUTE2(variant, "font_variant");
	CHECK_ATTRIBUTE2(weight, "font_weight");

	CHECK_ATTRIBUTE (foreground);
	CHECK_ATTRIBUTE2 (foreground, "fgcolor");
	break;
      case 's':
	CHECK_ATTRIBUTE (size);
	CHECK_ATTRIBUTE (stretch);
	CHECK_ATTRIBUTE (strikethrough);
	CHECK_ATTRIBUTE (strikethrough_color);
	CHECK_ATTRIBUTE (style);
	break;
      case 'g':
	CHECK_ATTRIBUTE (gravity);
	CHECK_ATTRIBUTE (gravity_hint);
	break;
      case 'l':
	CHECK_ATTRIBUTE (lang);
	CHECK_ATTRIBUTE (letter_spacing);
	break;
      case 'u':
	CHECK_ATTRIBUTE (underline);
	CHECK_ATTRIBUTE (underline_color);
	break;
      default:
	CHECK_ATTRIBUTE (background);
	CHECK_ATTRIBUTE2 (background, "bgcolor");
	CHECK_ATTRIBUTE2(foreground, "color");
	CHECK_ATTRIBUTE (rise);
	CHECK_ATTRIBUTE (variant);
	CHECK_ATTRIBUTE (weight);
	break;
      }

      if (!found)
	{
	  g_set_error (error, G_MARKUP_ERROR,
		       G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
		       _("Attribute '%s' is not allowed on the <span> tag "
			 "on line %d char %d"),
		       names[i], line_number, char_number);
	  return FALSE;
	}

      ++i;
    }

  /* Parse desc first, then modify it with other font-related attributes. */
  if (G_UNLIKELY (desc))
    {
      PangoFontDescription *parsed;

      parsed = pango_font_description_from_string (desc);
      if (parsed)
	{
	  add_attribute (tag, pango_attr_font_desc_new (parsed));
	  if (tag)
	    open_tag_set_absolute_font_size (tag, pango_font_description_get_size (parsed));
	  pango_font_description_free (parsed);
	}
    }

  if (G_UNLIKELY (family))
    {
      add_attribute (tag, pango_attr_family_new (family));
    }

  if (G_UNLIKELY (size))
    {
      if (g_ascii_isdigit (*size))
	{
	  const char *end;
	  gint n;

/* cap size from the top at an arbitrary 2048 */
#define MAX_SIZE (2048 * PANGO_SCALE)

	  if ((end = size, !pango_scan_int (&end, &n)) || *end != '\0' || n < 0 || n > MAX_SIZE)
	    {
	      g_set_error (error,
			   G_MARKUP_ERROR,
			   G_MARKUP_ERROR_INVALID_CONTENT,
			   _("Value of 'size' attribute on <span> tag on line %d "
			     "could not be parsed; should be an integer less than %d, or a "
			     "string such as 'small', not '%s'"),
			   line_number, MAX_SIZE+1, size);
	      goto error;
	    }

	  add_attribute (tag, pango_attr_size_new (n));
	  if (tag)
	    open_tag_set_absolute_font_size (tag, n);
	}
      else if (strcmp (size, "smaller") == 0)
	{
	  if (tag)
	    {
	      tag->scale_level_delta -= 1;
	      tag->scale_level -= 1;
	    }
	}
      else if (strcmp (size, "larger") == 0)
	{
	  if (tag)
	    {
	      tag->scale_level_delta += 1;
	      tag->scale_level += 1;
	    }
	}
      else if (parse_absolute_size (tag, size))
	; /* nothing */
      else
	{
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_INVALID_CONTENT,
		       _("Value of 'size' attribute on <span> tag on line %d "
			 "could not be parsed; should be an integer, or a "
			 "string such as 'small', not '%s'"),
		       line_number, size);
	  goto error;
	}
    }

  if (G_UNLIKELY (style))
    {
      PangoStyle pango_style;

      if (pango_parse_style (style, &pango_style, FALSE))
	add_attribute (tag, pango_attr_style_new (pango_style));
      else
	{
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_INVALID_CONTENT,
		       _("'%s' is not a valid value for the 'style' attribute "
			 "on <span> tag, line %d; valid values are "
			 "'normal', 'oblique', 'italic'"),
		       style, line_number);
	  goto error;
	}
    }

  if (G_UNLIKELY (weight))
    {
      PangoWeight pango_weight;

      if (pango_parse_weight (weight, &pango_weight, FALSE))
	add_attribute (tag,
		       pango_attr_weight_new (pango_weight));
      else
	{
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_INVALID_CONTENT,
		       _("'%s' is not a valid value for the 'weight' "
			 "attribute on <span> tag, line %d; valid "
			 "values are for example 'light', 'ultrabold' or a number"),
		       weight, line_number);
	  goto error;
	}
    }

  if (G_UNLIKELY (variant))
    {
      PangoVariant pango_variant;

      if (pango_parse_variant (variant, &pango_variant, FALSE))
	add_attribute (tag, pango_attr_variant_new (pango_variant));
      else
	{
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_INVALID_CONTENT,
		       _("'%s' is not a valid value for the 'variant' "
			 "attribute on <span> tag, line %d; valid values are "
			 "'normal', 'smallcaps'"),
		       variant, line_number);
	  goto error;
	}
    }

  if (G_UNLIKELY (stretch))
    {
      PangoStretch pango_stretch;

      if (pango_parse_stretch (stretch, &pango_stretch, FALSE))
	add_attribute (tag, pango_attr_stretch_new (pango_stretch));
      else
	{
	  g_set_error (error,
		       G_MARKUP_ERROR,
		       G_MARKUP_ERROR_INVALID_CONTENT,
		       _("'%s' is not a valid value for the 'stretch' "
			 "attribute on <span> tag, line %d; valid "
			 "values are for example 'condensed', "
			 "'ultraexpanded', 'normal'"),
		       stretch, line_number);
	  goto error;
	}
    }

  if (G_UNLIKELY (foreground))
    {
      PangoColor color;

      if (!span_parse_color ("foreground", foreground, &color, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_foreground_new (color.red, color.green, color.blue));
    }

  if (G_UNLIKELY (background))
    {
      PangoColor color;

      if (!span_parse_color ("background", background, &color, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_background_new (color.red, color.green, color.blue));
    }

  if (G_UNLIKELY (underline))
    {
      PangoUnderline ul = PANGO_UNDERLINE_NONE;

      if (!span_parse_enum ("underline", underline, PANGO_TYPE_UNDERLINE, &ul, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_underline_new (ul));
    }

  if (G_UNLIKELY (underline_color))
    {
      PangoColor color;

      if (!span_parse_color ("underline_color", underline_color, &color, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_underline_color_new (color.red, color.green, color.blue));
    }

  if (G_UNLIKELY (gravity))
    {
      PangoGravity gr = PANGO_GRAVITY_SOUTH;

      if (!span_parse_enum ("gravity", gravity, PANGO_TYPE_GRAVITY, &gr, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_gravity_new (gr));
    }

  if (G_UNLIKELY (gravity_hint))
    {
      PangoGravityHint hint = PANGO_GRAVITY_HINT_NATURAL;

      if (!span_parse_enum ("gravity_hint", gravity_hint, PANGO_TYPE_GRAVITY_HINT, &hint, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_gravity_hint_new (hint));
    }

  if (G_UNLIKELY (strikethrough))
    {
      gboolean b = FALSE;

      if (!span_parse_boolean ("strikethrough", strikethrough, &b, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_strikethrough_new (b));
    }

  if (G_UNLIKELY (strikethrough_color))
    {
      PangoColor color;

      if (!span_parse_color ("strikethrough_color", strikethrough_color, &color, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_strikethrough_color_new (color.red, color.green, color.blue));
    }

  if (G_UNLIKELY (fallback))
    {
      gboolean b = FALSE;

      if (!span_parse_boolean ("fallback", fallback, &b, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_fallback_new (b));
    }

  if (G_UNLIKELY (rise))
    {
      gint n = 0;

      if (!span_parse_int ("rise", rise, &n, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_rise_new (n));
    }

  if (G_UNLIKELY (letter_spacing))
    {
      gint n = 0;

      if (!span_parse_int ("letter_spacing", letter_spacing, &n, line_number, error))
	goto error;

      add_attribute (tag, pango_attr_letter_spacing_new (n));
    }

  if (G_UNLIKELY (lang))
    {
      add_attribute (tag,
		     pango_attr_language_new (pango_language_from_string (lang)));
    }

  return TRUE;

 error:

  return FALSE;
}
Пример #23
0
/* Note: Error messages are passed back to the caller via the GError
 * mechanism. There is no need for dbg calls in this function. */
static void event_start_element(GMarkupParseContext *context,
                                const gchar         *element_name,
                                const gchar         **attribute_names,
                                const gchar         **attribute_values,
                                gpointer            user_data,
                                GError              **error)
{
        int i = 0;
	gchar *key = NULL;
        gint line, pos;
	ErrLog2EventInfoT *xmlinfo, working;
	struct errlog2event_hash_info *hash_info;

	memset(&working, 0, sizeof(ErrLog2EventInfoT));
	hash_info = (struct errlog2event_hash_info *)user_data;
 
        /* Ignore all XML elements except the event tag */
        if (g_ascii_strncasecmp(element_name, "event", sizeof("event")) != 0) {
                /* This is normal - not an error condition! */
                return;
        }

        /* Fetch XML element attributes and values. Build event info */
        while (attribute_names[i] != NULL) {
                if (g_ascii_strncasecmp(attribute_names[i], "name", sizeof("name")) == 0) {
                        /* Don't use this attribute so ignore it */
                }
                else if (g_ascii_strncasecmp(attribute_names[i], "msg", sizeof("msg")) == 0) {
                        key = g_strdup(attribute_values[i]);
                        if (key == NULL) {
                                g_set_error(error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
                                            "No memory for hash key=%s", attribute_values[i]);
                                return;
                        }
                }
                else if (g_ascii_strncasecmp(attribute_names[i], "hex", sizeof("hex")) == 0) {
                        working.event = g_strdup(attribute_values[i]);
                        if (working.event == NULL) {
                                g_set_error(error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
                                            "No memory for hash value=%s", attribute_values[i]);
                                return;
                        }
                }
                else if (g_ascii_strncasecmp(attribute_names[i], "severity", sizeof("severity")) == 0) {
                        if (g_ascii_strncasecmp(attribute_values[i], "SAHPI_CRITICAL", sizeof("SAHPI_CRITICAL")) == 0) {
                                working.event_sev = SAHPI_CRITICAL;
                        }
                        else if (g_ascii_strncasecmp(attribute_values[i], "SAHPI_MAJOR", sizeof("SAHPI_MAJOR")) == 0) {
                                working.event_sev = SAHPI_MAJOR;
                        }
                        else if (g_ascii_strncasecmp(attribute_values[i], "SAHPI_MINOR", sizeof("SAHPI_MINOR")) == 0) {
                                working.event_sev = SAHPI_MINOR;
                        }
                        else if (g_ascii_strncasecmp(attribute_values[i], "SAHPI_INFORMATIONAL", sizeof("SAHPI_INFORMATIONAL")) == 0) {
                                working.event_sev = SAHPI_INFORMATIONAL;
                        }
                        else {
                                g_markup_parse_context_get_position(context, &line, &pos);
                                g_set_error(error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                                            "Bad severity=%s for XML event element line %d", 
					    attribute_values[i], line);
                                return;
                        }
                }
                else if (g_ascii_strncasecmp(attribute_names[i], "override", sizeof("override")) == 0) {
                        working.event_ovr |= NO_OVR;
                        if (strstr(attribute_values[i], "OVR_SEV") != NULL) {
                                working.event_ovr |= OVR_SEV;
                        }
                        if (strstr(attribute_values[i], "OVR_RID") != NULL) {
                                working.event_ovr |= OVR_RID;
                        }
                        if (strstr(attribute_values[i], "OVR_EXP") != NULL) {
                                working.event_ovr |= OVR_EXP;
                        }
                        if (strstr(attribute_values[i], "OVR_VMM") != NULL) {
                                working.event_ovr |= OVR_VMM;
                        }
                        if (strstr(attribute_values[i], "OVR_MM1") != NULL) {
                                working.event_ovr |= OVR_MM1;
                        }
                        if (strstr(attribute_values[i], "OVR_MM2") != NULL) {
                                working.event_ovr |= OVR_MM2;
                        }
                        if (strstr(attribute_values[i], "OVR_MM_STBY") != NULL) {
                                working.event_ovr |= OVR_MM_STBY;
                        }
                        if (strstr(attribute_values[i], "OVR_MM_PRIME") != NULL) {
                                working.event_ovr |= OVR_MM_PRIME;
                        }
                        /* Ignore any other values */
                }
                else if (g_ascii_strncasecmp(attribute_names[i], "dup", sizeof("dup")) == 0) {
                        working.event_dup = (short)atoi(attribute_values[i]);
                }
                else {
                        g_markup_parse_context_get_position(context, &line, &pos);
                        g_set_error(error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
                                    "Bad name for XML event element line %d", line);
                        return;
                }
                i++;
        }

	/* Check for valid key */
        if (key == NULL) {
                g_set_error(error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                            "No key set from XML event element");
                return;
        }

        /* Malloc memory for hash value and set values */
        xmlinfo = g_malloc0(sizeof(ErrLog2EventInfoT));
        if (!xmlinfo) {
                g_set_error(error, G_MARKUP_ERROR,G_MARKUP_ERROR_PARSE,
                            "No memory for hash value");
                return;
        }
	*xmlinfo = working;

	/* Insert event into hash table */
        g_hash_table_insert(hash_info->hashtable, key, xmlinfo);
	trace("Inserted event=%s into hash table. Sev=%s, OVR=%lld, Dup=%d",
	      xmlinfo->event, oh_lookup_severity(xmlinfo->event_sev),
	      xmlinfo->event_ovr, xmlinfo->event_dup);
        return;
}
Пример #24
0
static void
start_element (GMarkupParseContext *context,
               const gchar         *element_name,
               const gchar        **attr_names,
               const gchar        **attr_values,
               gpointer             user_data,
               GError             **error)
{
	DeskmenuObject *dm_object = user_data;

	DeskmenuElementType element_type;
	const gchar **ncursor = attr_names, **vcursor = attr_values;
	GtkWidget *item, *menu;
	gint w, h;

	element_type = GPOINTER_TO_INT (g_hash_table_lookup
		(element_hash, element_name));

	if ((dm_object->menu && !dm_object->current_menu)
	   || (!dm_object->menu && element_type != DESKMENU_ELEMENT_MENU))
	{
		gint line_num, char_num;
		g_markup_parse_context_get_position (context, &line_num, &char_num);
		g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
			"Error on line %d char %d: Element '%s' declared outside of "
			"toplevel menu element", line_num, char_num, element_name);
		return;
	}

	switch (element_type)
	{
		case DESKMENU_ELEMENT_MENU:

			if (dm_object->current_item != NULL)
			{
				gint line_num, char_num;
				g_markup_parse_context_get_position (context, &line_num,
					&char_num);
				g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
					"Error on line %d char %d: Element 'menu' cannot be nested "
					"inside of an item element", line_num, char_num);
				return;
			}
			if (!dm_object->menu)
			{
				/*if (strcmp (*ncursor, "size") == 0) {
					deskmenu->w = g_strdup (*vcursor);
					deskmenu->h = g_strdup (*vcursor);
					}
				else {
					gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, deskmenu->w, deskmenu->h);
				}*/
				dm_object->menu = gtk_menu_new ();
				g_object_set_data (G_OBJECT (dm_object->menu), "parent menu",
					NULL);
				dm_object->current_menu = dm_object->menu;
			}
			else
			{
				gchar *name = NULL;
				gchar *icon = NULL;
				gboolean name_exec = FALSE;
				gboolean icon_file = FALSE;
				while (*ncursor)
				{
					if (strcmp (*ncursor, "name") == 0)
						name = g_strdup (*vcursor);
					else if (strcmp (*ncursor, "icon") == 0)
						icon = g_strdup (*vcursor);
					else if ((strcmp (*ncursor, "mode") == 0)
						&& (strcmp (*vcursor, "exec") == 0))
						name_exec = TRUE;
					else if ((strcmp (*ncursor, "mode1") == 0)
						&& (strcmp (*vcursor, "file") == 0))
						icon_file = TRUE;
					else
						g_set_error (error, G_MARKUP_ERROR,
							G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
							"Unknown attribute: %s", *ncursor);
					ncursor++;
					vcursor++;
				}
				if (name_exec)
				{
					GtkWidget *label;
					GHook *hook;

					item = gtk_image_menu_item_new ();
					label = gtk_label_new_with_mnemonic (NULL);
					gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);

					g_object_set_data (G_OBJECT (label), "exec", g_strdup (name));
					gtk_container_add (GTK_CONTAINER (item), label);
					hook = g_hook_alloc (dm_object->show_hooks);

					hook->data = (gpointer) label;
					hook->func = (GHookFunc *) launcher_name_exec_update;
					g_hook_append (dm_object->show_hooks, hook);
				}
				else
				{
					if (name)
						item = gtk_image_menu_item_new_with_mnemonic (name);
					else
						item = gtk_image_menu_item_new_with_mnemonic ("");
				}
				if (icon)
				{
					if (icon_file)
					{
						gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
						gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM(item), 
													   gtk_image_new_from_pixbuf (gdk_pixbuf_new_from_file_at_size (parse_expand_tilde(icon), w, h, NULL)));
					}
					else {
						gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item),
													   gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU));
					}
				}
				gtk_menu_shell_append (GTK_MENU_SHELL (dm_object->current_menu), item);
				menu = gtk_menu_new ();
				g_object_set_data (G_OBJECT (menu), "parent menu",
					dm_object->current_menu);
				dm_object->current_menu = menu;
				gtk_menu_item_set_submenu (GTK_MENU_ITEM (item),
					dm_object->current_menu);

				if (!dm_object->make_from_pipe)
				{
					GtkWidget *pin = gtk_tearoff_menu_item_new();
					gtk_menu_shell_append (GTK_MENU_SHELL (dm_object->current_menu),
						pin); //add a pin menu item
					dm_object->pin_items = g_slist_prepend (dm_object->pin_items, pin);
				}
				else
				{
					if (gtk_menu_get_tearoff_state (GTK_MENU(dm_object->menu)))
					{
						GtkWidget *pin = gtk_tearoff_menu_item_new();
						gtk_menu_shell_append (GTK_MENU_SHELL (dm_object->current_menu),
							pin); //add a pin menu item
					}
				}

				g_free (name);
				g_free (icon);
			}
			break;

		case DESKMENU_ELEMENT_SEPARATOR:
		if (dm_object->current_item != NULL)
		{
				gint line_num, char_num;
				g_markup_parse_context_get_position (context, &line_num,
					&char_num);
				g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
					"Error on line %d char %d: Element 'menu' cannot be nested "
					"inside of an item element", line_num, char_num);
				return;
		}
		else {
				gchar *name = NULL;
				gchar *icon = NULL;
				gboolean name_exec = FALSE;
				gboolean icon_file = FALSE;
				gboolean decorate = FALSE;
				gint w, h;
				item = gtk_separator_menu_item_new();
				while (*ncursor)
				{
					if (strcmp (*ncursor, "name") == 0)
					{
						name = g_strdup (*vcursor);
						if (!decorate)
						{
							decorate = TRUE;
						}
					}
					else if (strcmp (*ncursor, "icon") == 0)
					{
						icon = g_strdup (*vcursor);
						if (!decorate)
						{
							decorate = TRUE;
						}
					}
					else if ((strcmp (*ncursor, "mode") == 0)
					         && (strcmp (*vcursor, "exec") == 0))
						name_exec = TRUE;
					else if ((strcmp (*ncursor, "mode1") == 0)
					         && (strcmp (*vcursor, "file") == 0))
						icon_file = TRUE;
					else
						g_set_error (error, G_MARKUP_ERROR,
							G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
							"Unknown attribute: %s", *ncursor);
					ncursor++;
					vcursor++;
				}
				if (decorate)
				{
					GtkWidget *box = gtk_hbox_new (FALSE, 3);
					gtk_container_add (GTK_CONTAINER(item), GTK_WIDGET(box));
					if (name_exec)
					{
						GtkWidget *label;
						GHook *hook;

						label = gtk_label_new_with_mnemonic (NULL);

						g_object_set_data (G_OBJECT (label), "exec", g_strdup (name));
						gtk_box_pack_end (GTK_BOX(box), label, TRUE, FALSE, 0);
						hook = g_hook_alloc (dm_object->show_hooks);

						hook->data = (gpointer) label;
						hook->func = (GHookFunc *) launcher_name_exec_update;
						g_hook_append (dm_object->show_hooks, hook);
					}
					else
					{
						gtk_box_pack_end (GTK_BOX(box), gtk_label_new_with_mnemonic (name), TRUE, FALSE, 0);
					}
					if (icon)
					{
						GtkWidget *image;
						if (icon_file)
						{
							gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h);
							image = gtk_image_new_from_pixbuf (gdk_pixbuf_new_from_file_at_size (parse_expand_tilde(icon), w, h, NULL));
						}
						else {
							image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU);
						}
						gtk_box_pack_start (GTK_BOX(box), image, FALSE, FALSE, 0);
					}
					gtk_widget_set_state (item, GTK_STATE_PRELIGHT); /*derive colors from menu hover*/
					g_free (name);
					g_free (icon);
				}
				gtk_menu_shell_append (GTK_MENU_SHELL (dm_object->current_menu), item);
			}
			break;

		case DESKMENU_ELEMENT_ITEM:

			if (dm_object->current_item != NULL)
			{
				gint line_num, char_num;
				g_markup_parse_context_get_position (context, &line_num,
					&char_num);
				g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
					"Error on line %d char %d: Element 'item' cannot be nested "
					"inside of another item element", line_num, char_num);
				return;
			}

			dm_object->current_item = g_slice_new0 (DeskmenuItem);
				while (*ncursor)
				{
					if (strcmp (*ncursor, "type") == 0)
						dm_object->current_item->type = GPOINTER_TO_INT
						(g_hash_table_lookup (item_hash, *vcursor));
					else
						g_set_error (error, G_MARKUP_ERROR,
							G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
							"Unknown attribute: %s", *ncursor);
					ncursor++;
					vcursor++;
				}
			break;

		case DESKMENU_ELEMENT_NAME:
			 while (*ncursor)
				{
					if ((strcmp (*ncursor, "mode") == 0)
						&& (strcmp (*vcursor, "exec") == 0))
						dm_object->current_item->name_exec = TRUE;
					ncursor++;
					vcursor++;
				} /* no break here to let it fall through */
		case DESKMENU_ELEMENT_ICON:
				while (*ncursor)
				{
					if ((strcmp (*ncursor, "mode1") == 0)
						&& (strcmp (*vcursor, "file") == 0))
						dm_object->current_item->icon_file = TRUE;
					ncursor++;
					vcursor++;
				} /* no break here to let it fall through */
		case DESKMENU_ELEMENT_VPICON:
				while (*ncursor)
				{
					if ((strcmp (*ncursor, "mode1") == 0)
						&& (strcmp (*vcursor, "file") == 0))
						dm_object->current_item->vpicon_file = TRUE;
					ncursor++;
					vcursor++;
				} /* no break here to let it fall through */
		case DESKMENU_ELEMENT_COMMAND:
				while (*ncursor)
				{
					if ((strcmp (*ncursor, "mode2") == 0)
						&& (strcmp (*vcursor, "pipe") == 0))
						dm_object->current_item->command_pipe = TRUE;
					if (dm_object->current_item->command_pipe == TRUE
						&& (strcmp (*ncursor, "cache") == 0)
						&& (strcmp (*vcursor, "true") == 0))
						dm_object->current_item->cache_output = TRUE;
					ncursor++;
					vcursor++;
				} /* no break here to let it fall through */
		case DESKMENU_ELEMENT_WRAP:
			if (dm_object->current_item)
				dm_object->current_item->current_element = element_type;
			break;
		case DESKMENU_ELEMENT_THISVP:
			if (dm_object->current_item)
				dm_object->current_item->current_element = element_type;
			break;
		case DESKMENU_ELEMENT_MINIONLY:
			if (dm_object->current_item)
				dm_object->current_item->current_element = element_type;
			break;
		case DESKMENU_ELEMENT_QUANTITY:
			if (dm_object->current_item)
				dm_object->current_item->current_element = element_type;
			break;
		case DESKMENU_ELEMENT_SORT:
			if (dm_object->current_item)
				dm_object->current_item->current_element = element_type;
			break;
		case DESKMENU_ELEMENT_AGE:
			if (dm_object->current_item)
				dm_object->current_item->current_element = element_type;
			break;

		default:
			g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
				"Unknown element: %s", element_name);
			break;
	}
}
Пример #25
0
static void
start_element_handler  (GMarkupParseContext *context,
			const gchar         *element_name,
			const gchar        **attribute_names,
			const gchar        **attribute_values,
			gpointer             user_data,
			GError             **error)
{
  TagParseFunc parse_func = NULL;
  OpenTag *ot;

  switch (*element_name)
    {
    case 'b':
      if (strcmp ("b", element_name) == 0)
	parse_func = b_parse_func;
      else if (strcmp ("big", element_name) == 0)
	parse_func = big_parse_func;
      break;

    case 'i':
      if (strcmp ("i", element_name) == 0)
	parse_func = i_parse_func;
      break;

    case 'm':
      if (strcmp ("markup", element_name) == 0)
	parse_func = markup_parse_func;
      break;

    case 's':
      if (strcmp ("span", element_name) == 0)
	parse_func = span_parse_func;
      else if (strcmp ("s", element_name) == 0)
	parse_func = s_parse_func;
      else if (strcmp ("sub", element_name) == 0)
	parse_func = sub_parse_func;
      else if (strcmp ("sup", element_name) == 0)
	parse_func = sup_parse_func;
      else if (strcmp ("small", element_name) == 0)
	parse_func = small_parse_func;
      break;

    case 't':
      if (strcmp ("tt", element_name) == 0)
	parse_func = tt_parse_func;
      break;

    case 'u':
      if (strcmp ("u", element_name) == 0)
	parse_func = u_parse_func;
      break;
    }

  if (parse_func == NULL)
    {
      gint line_number, char_number;

      g_markup_parse_context_get_position (context,
					   &line_number, &char_number);

      g_set_error (error,
		   G_MARKUP_ERROR,
		   G_MARKUP_ERROR_UNKNOWN_ELEMENT,
		   _("Unknown tag '%s' on line %d char %d"),
		   element_name,
		   line_number, char_number);

      return;
    }

  ot = markup_data_open_tag (user_data);

  /* note ot may be NULL if the user didn't want the attribute list */

  if (!(*parse_func) (user_data, ot,
		      attribute_names, attribute_values,
		      context, error))
    {
      /* there's nothing to do; we return an error, and end up
       * freeing ot off the tag stack later.
       */
    }
}