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; }
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); }
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; }
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; }
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); }
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); }
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); }
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); }
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); }
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); }
/* 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); }
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); }
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 (); } }
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); }
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)); }
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)); }
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); } }
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); } }
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 (); } }
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)); }
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; }
/* 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; }
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; } }
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. */ } }