X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=glib%2Fgbookmarkfile.c;h=3123669cb7dca00c026868a13a7c1954aaa80f18;hb=14f2376c8a06f0936d734ec6a7e0e836072acf65;hp=cf052faeb4431f9af342aeb40935b3ad042ee6af;hpb=d4ac791e02528a3fc285276586ba154c1c04c27b;p=platform%2Fupstream%2Fglib.git diff --git a/glib/gbookmarkfile.c b/glib/gbookmarkfile.c index cf052fa..3123669 100644 --- a/glib/gbookmarkfile.c +++ b/glib/gbookmarkfile.c @@ -29,11 +29,6 @@ #include #include #include -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif #include "gconvert.h" #include "gdataset.h" @@ -42,11 +37,11 @@ #include "ghash.h" #include "glibintl.h" #include "glist.h" -#include "gslist.h" #include "gmain.h" #include "gmarkup.h" #include "gmem.h" #include "gmessages.h" +#include "gshell.h" #include "gslice.h" #include "gstdio.h" #include "gstring.h" @@ -54,7 +49,51 @@ #include "gtimer.h" #include "gutils.h" -#include "galias.h" + +/** + * SECTION:bookmarkfile + * @title: Bookmark file parser + * @short_description: parses files containing bookmarks + * + * GBookmarkFile lets you parse, edit or create files containing bookmarks + * to URI, along with some meta-data about the resource pointed by the URI + * like its MIME type, the application that is registering the bookmark and + * the icon that should be used to represent the bookmark. The data is stored + * using the + * [Desktop Bookmark Specification](http://www.gnome.org/~ebassi/bookmark-spec). + * + * The syntax of the bookmark files is described in detail inside the + * Desktop Bookmark Specification, here is a quick summary: bookmark + * files use a sub-class of the XML Bookmark Exchange Language + * specification, consisting of valid UTF-8 encoded XML, under the + * root element; each bookmark is stored inside a + * element, using its URI: no relative paths can + * be used inside a bookmark file. The bookmark may have a user defined + * title and description, to be used instead of the URI. Under the + * element, with its owner attribute set to + * `http://freedesktop.org`, is stored the meta-data about a resource + * pointed by its URI. The meta-data consists of the resource's MIME + * type; the applications that have registered a bookmark; the groups + * to which a bookmark belongs to; a visibility flag, used to set the + * bookmark as "private" to the applications and groups that has it + * registered; the URI and MIME type of an icon, to be used when + * displaying the bookmark inside a GUI. + * + * Here is an example of a bookmark file: + * [bookmarks.xbel](https://git.gnome.org/browse/glib/tree/glib/tests/bookmarks.xbel) + * + * A bookmark file might contain more than one bookmark; each bookmark + * is accessed through its URI. + * + * The important caveat of bookmark files is that when you add a new + * bookmark you must also add the application that is registering it, using + * g_bookmark_file_add_application() or g_bookmark_file_set_app_info(). + * If a bookmark has no applications then it won't be dumped when creating + * the on disk representation, using g_bookmark_file_to_data() or + * g_bookmark_file_to_file(). + * + * The #GBookmarkFile parser was added in GLib 2.12. + */ /* XBEL 1.0 standard entities */ #define XBEL_VERSION "1.0" @@ -103,7 +142,8 @@ #define BOOKMARK_NAME_ATTRIBUTE "name" #define BOOKMARK_EXEC_ATTRIBUTE "exec" #define BOOKMARK_COUNT_ATTRIBUTE "count" -#define BOOKMARK_TIMESTAMP_ATTRIBUTE "timestamp" +#define BOOKMARK_TIMESTAMP_ATTRIBUTE "timestamp" /* deprecated by "modified" */ +#define BOOKMARK_MODIFIED_ATTRIBUTE "modified" #define BOOKMARK_HREF_ATTRIBUTE "href" #define BOOKMARK_TYPE_ATTRIBUTE "type" @@ -219,14 +259,14 @@ bookmark_app_info_new (const gchar *name) { BookmarkAppInfo *retval; - g_assert (name != NULL); + g_warn_if_fail (name != NULL); retval = g_slice_new (BookmarkAppInfo); retval->name = g_strdup (name); retval->exec = NULL; retval->count = 0; - retval->stamp = time (NULL); + retval->stamp = 0; return retval; } @@ -237,11 +277,8 @@ bookmark_app_info_free (BookmarkAppInfo *app_info) if (!app_info) return; - if (app_info->name) - g_free (app_info->name); - - if (app_info->exec) - g_free (app_info->exec); + g_free (app_info->name); + g_free (app_info->exec); g_slice_free (BookmarkAppInfo, app_info); } @@ -250,19 +287,30 @@ static gchar * bookmark_app_info_dump (BookmarkAppInfo *app_info) { gchar *retval; + gchar *name, *exec, *modified, *count; - g_assert (app_info != NULL); + g_warn_if_fail (app_info != NULL); if (app_info->count == 0) return NULL; - - retval = g_strdup_printf (" <%s:%s %s=\"%s\" %s=\"%s\" %s=\"%ld\" %s=\"%u\"/>\n", - BOOKMARK_NAMESPACE_NAME, - BOOKMARK_APPLICATION_ELEMENT, - BOOKMARK_NAME_ATTRIBUTE, app_info->name, - BOOKMARK_EXEC_ATTRIBUTE, app_info->exec, - BOOKMARK_TIMESTAMP_ATTRIBUTE, (time_t) app_info->stamp, - BOOKMARK_COUNT_ATTRIBUTE, app_info->count); + + name = g_markup_escape_text (app_info->name, -1); + exec = g_markup_escape_text (app_info->exec, -1); + modified = timestamp_to_iso8601 (app_info->stamp); + count = g_strdup_printf ("%u", app_info->count); + + retval = g_strconcat (" " + "<" BOOKMARK_NAMESPACE_NAME ":" BOOKMARK_APPLICATION_ELEMENT + " " BOOKMARK_NAME_ATTRIBUTE "=\"", name, "\"" + " " BOOKMARK_EXEC_ATTRIBUTE "=\"", exec, "\"" + " " BOOKMARK_MODIFIED_ATTRIBUTE "=\"", modified, "\"" + " " BOOKMARK_COUNT_ATTRIBUTE "=\"", count, "\"/>\n", + NULL); + + g_free (name); + g_free (exec); + g_free (modified); + g_free (count); return retval; } @@ -304,32 +352,15 @@ bookmark_metadata_free (BookmarkMetadata *metadata) if (!metadata) return; - if (metadata->mime_type) - g_free (metadata->mime_type); + g_free (metadata->mime_type); - if (metadata->groups) - { - g_list_foreach (metadata->groups, - (GFunc) g_free, - NULL); - g_list_free (metadata->groups); - } - - if (metadata->applications) - { - g_list_foreach (metadata->applications, - (GFunc) bookmark_app_info_free, - NULL); - g_list_free (metadata->applications); - - g_hash_table_destroy (metadata->apps_by_name); - } - - if (metadata->icon_href) - g_free (metadata->icon_href); - - if (metadata->icon_mime) - g_free (metadata->icon_mime); + g_list_free_full (metadata->groups, g_free); + g_list_free_full (metadata->applications, (GDestroyNotify) bookmark_app_info_free); + + g_hash_table_destroy (metadata->apps_by_name); + + g_free (metadata->icon_href); + g_free (metadata->icon_mime); g_slice_free (BookmarkMetadata, metadata); } @@ -338,54 +369,62 @@ static gchar * bookmark_metadata_dump (BookmarkMetadata *metadata) { GString *retval; + gchar *buffer; if (!metadata->applications) return NULL; - retval = g_string_new (NULL); + retval = g_string_sized_new (1024); /* metadata container */ - g_string_append_printf (retval, - " <%s %s=\"%s\">\n", - XBEL_METADATA_ELEMENT, - XBEL_OWNER_ATTRIBUTE, BOOKMARK_METADATA_OWNER); - + g_string_append (retval, + " " + "<" XBEL_METADATA_ELEMENT + " " XBEL_OWNER_ATTRIBUTE "=\"" BOOKMARK_METADATA_OWNER + "\">\n"); + /* mime type */ - if (metadata->mime_type) - g_string_append_printf (retval, - " <%s:%s %s=\"%s\"/>\n", - MIME_NAMESPACE_NAME, - MIME_TYPE_ELEMENT, - MIME_TYPE_ATTRIBUTE, metadata->mime_type); - + if (metadata->mime_type) { + buffer = g_strconcat (" " + "<" MIME_NAMESPACE_NAME ":" MIME_TYPE_ELEMENT " " + MIME_TYPE_ATTRIBUTE "=\"", metadata->mime_type, "\"/>\n", + NULL); + g_string_append (retval, buffer); + g_free (buffer); + } + if (metadata->groups) { GList *l; /* open groups container */ - g_string_append_printf (retval, - " <%s:%s>\n", - BOOKMARK_NAMESPACE_NAME, - BOOKMARK_GROUPS_ELEMENT); + g_string_append (retval, + " " + "<" BOOKMARK_NAMESPACE_NAME + ":" BOOKMARK_GROUPS_ELEMENT ">\n"); for (l = g_list_last (metadata->groups); l != NULL; l = l->prev) { - gchar *group_name = (gchar *) l->data; - - g_string_append_printf (retval, - " <%s:%s>%s\n", - BOOKMARK_NAMESPACE_NAME, - BOOKMARK_GROUP_ELEMENT, - group_name, - BOOKMARK_NAMESPACE_NAME, - BOOKMARK_GROUP_ELEMENT); + gchar *group_name; + + group_name = g_markup_escape_text ((gchar *) l->data, -1); + buffer = g_strconcat (" " + "<" BOOKMARK_NAMESPACE_NAME + ":" BOOKMARK_GROUP_ELEMENT ">", + group_name, + "\n", NULL); + g_string_append (retval, buffer); + + g_free (buffer); + g_free (group_name); } /* close groups container */ - g_string_append_printf (retval, - " \n", - BOOKMARK_NAMESPACE_NAME, - BOOKMARK_GROUPS_ELEMENT); + g_string_append (retval, + " " + "\n"); } if (metadata->applications) @@ -393,17 +432,17 @@ bookmark_metadata_dump (BookmarkMetadata *metadata) GList *l; /* open applications container */ - g_string_append_printf (retval, - " <%s:%s>\n", - BOOKMARK_NAMESPACE_NAME, - BOOKMARK_APPLICATIONS_ELEMENT); + g_string_append (retval, + " " + "<" BOOKMARK_NAMESPACE_NAME + ":" BOOKMARK_APPLICATIONS_ELEMENT ">\n"); for (l = g_list_last (metadata->applications); l != NULL; l = l->prev) { BookmarkAppInfo *app_info = (BookmarkAppInfo *) l->data; gchar *app_data; - g_assert (app_info != NULL); + g_warn_if_fail (app_info != NULL); app_data = bookmark_app_info_dump (app_info); @@ -416,10 +455,10 @@ bookmark_metadata_dump (BookmarkMetadata *metadata) } /* close applications container */ - g_string_append_printf (retval, - " \n", - BOOKMARK_NAMESPACE_NAME, - BOOKMARK_APPLICATIONS_ELEMENT); + g_string_append (retval, + " " + "\n"); } /* icon */ @@ -427,24 +466,28 @@ bookmark_metadata_dump (BookmarkMetadata *metadata) { if (!metadata->icon_mime) metadata->icon_mime = g_strdup ("application/octet-stream"); - - g_string_append_printf (retval, - " <%s:%s %s=\"%s\" %s=\"%s\"/>\n", - BOOKMARK_NAMESPACE_NAME, - BOOKMARK_ICON_ELEMENT, - BOOKMARK_HREF_ATTRIBUTE, metadata->icon_href, - BOOKMARK_TYPE_ATTRIBUTE, metadata->icon_mime); + + buffer = g_strconcat (" " + "<" BOOKMARK_NAMESPACE_NAME + ":" BOOKMARK_ICON_ELEMENT + " " BOOKMARK_HREF_ATTRIBUTE "=\"", metadata->icon_href, + "\" " BOOKMARK_TYPE_ATTRIBUTE "=\"", metadata->icon_mime, "\"/>\n", NULL); + g_string_append (retval, buffer); + + g_free (buffer); } /* private hint */ if (metadata->is_private) - g_string_append_printf (retval, - " <%s:%s/>\n", - BOOKMARK_NAMESPACE_NAME, - BOOKMARK_PRIVATE_ELEMENT); + g_string_append (retval, + " " + "<" BOOKMARK_NAMESPACE_NAME + ":" BOOKMARK_PRIVATE_ELEMENT "/>\n"); /* close metadata container */ - g_string_append_printf (retval, " \n", XBEL_METADATA_ELEMENT); + g_string_append (retval, + " " + "\n"); return g_string_free (retval, FALSE); } @@ -459,7 +502,7 @@ bookmark_item_new (const gchar *uri) { BookmarkItem *item; - g_assert (uri != NULL); + g_warn_if_fail (uri != NULL); item = g_slice_new (BookmarkItem); item->uri = g_strdup (uri); @@ -482,14 +525,9 @@ bookmark_item_free (BookmarkItem *item) if (!item) return; - if (item->uri) - g_free (item->uri); - - if (item->title) - g_free (item->title); - - if (item->description) - g_free (item->description); + g_free (item->uri); + g_free (item->title); + g_free (item->description); if (item->metadata) bookmark_metadata_free (item->metadata); @@ -503,6 +541,7 @@ bookmark_item_dump (BookmarkItem *item) GString *retval; gchar *added, *visited, *modified; gchar *escaped_uri; + gchar *buffer; /* at this point, we must have at least a registered application; if we don't * we don't screw up the bookmark file, and just skip this item @@ -513,72 +552,84 @@ bookmark_item_dump (BookmarkItem *item) return NULL; } - retval = g_string_new (NULL); + retval = g_string_sized_new (4096); added = timestamp_to_iso8601 (item->added); modified = timestamp_to_iso8601 (item->modified); visited = timestamp_to_iso8601 (item->visited); - escaped_uri = g_markup_escape_text (item->uri, strlen (item->uri)); - - g_string_append_printf (retval, - " <%s %s=\"%s\" %s=\"%s\" %s=\"%s\" %s=\"%s\">\n", - XBEL_BOOKMARK_ELEMENT, - XBEL_HREF_ATTRIBUTE, escaped_uri, - XBEL_ADDED_ATTRIBUTE, added, - XBEL_MODIFIED_ATTRIBUTE, modified, - XBEL_VISITED_ATTRIBUTE, visited); + escaped_uri = g_markup_escape_text (item->uri, -1); + + buffer = g_strconcat (" <" + XBEL_BOOKMARK_ELEMENT + " " + XBEL_HREF_ATTRIBUTE "=\"", escaped_uri, "\" " + XBEL_ADDED_ATTRIBUTE "=\"", added, "\" " + XBEL_MODIFIED_ATTRIBUTE "=\"", modified, "\" " + XBEL_VISITED_ATTRIBUTE "=\"", visited, "\">\n", + NULL); + + g_string_append (retval, buffer); + g_free (escaped_uri); g_free (visited); g_free (modified); g_free (added); + g_free (buffer); if (item->title) { gchar *escaped_title; - escaped_title = g_markup_escape_text (item->title, strlen (item->title)); - g_string_append_printf (retval, - " <%s>%s\n", - XBEL_TITLE_ELEMENT, - escaped_title, - XBEL_TITLE_ELEMENT); + escaped_title = g_markup_escape_text (item->title, -1); + buffer = g_strconcat (" " + "<" XBEL_TITLE_ELEMENT ">", + escaped_title, + "\n", + NULL); + g_string_append (retval, buffer); + g_free (escaped_title); + g_free (buffer); } if (item->description) { gchar *escaped_desc; - escaped_desc = g_markup_escape_text (item->description, strlen (item->description)); - g_string_append_printf (retval, - " <%s>%s\n", - XBEL_DESC_ELEMENT, - item->description, - XBEL_DESC_ELEMENT); + escaped_desc = g_markup_escape_text (item->description, -1); + buffer = g_strconcat (" " + "<" XBEL_DESC_ELEMENT ">", + escaped_desc, + "\n", + NULL); + g_string_append (retval, buffer); + g_free (escaped_desc); + g_free (buffer); } if (item->metadata) { gchar *metadata; - /* open info container */ - g_string_append_printf (retval, " <%s>\n", XBEL_INFO_ELEMENT); - metadata = bookmark_metadata_dump (item->metadata); if (metadata) { - retval = g_string_append (retval, metadata); + buffer = g_strconcat (" " + "<" XBEL_INFO_ELEMENT ">\n", + metadata, + " " + "\n", + NULL); + retval = g_string_append (retval, buffer); + g_free (buffer); g_free (metadata); } - - /* close info container */ - g_string_append_printf (retval, " \n", XBEL_INFO_ELEMENT); } - - g_string_append_printf (retval, " \n", XBEL_BOOKMARK_ELEMENT); + + g_string_append (retval, " \n"); return g_string_free (retval, FALSE); } @@ -587,7 +638,7 @@ static BookmarkAppInfo * bookmark_item_lookup_app_info (BookmarkItem *item, const gchar *app_name) { - g_assert (item != NULL && app_name != NULL); + g_warn_if_fail (item != NULL && app_name != NULL); if (!item->metadata) return NULL; @@ -618,15 +669,8 @@ g_bookmark_file_clear (GBookmarkFile *bookmark) g_free (bookmark->title); g_free (bookmark->description); - if (bookmark->items) - { - g_list_foreach (bookmark->items, - (GFunc) bookmark_item_free, - NULL); - g_list_free (bookmark->items); - - bookmark->items = NULL; - } + g_list_free_full (bookmark->items, (GDestroyNotify) bookmark_item_free); + bookmark->items = NULL; if (bookmark->items_by_uri) { @@ -686,7 +730,7 @@ parse_bookmark_element (GMarkupParseContext *context, BookmarkItem *item; GError *add_error; - g_assert ((parse_data != NULL) && (parse_data->state == STATE_BOOKMARK)); + g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_BOOKMARK)); i = 0; uri = added = modified = visited = NULL; @@ -702,6 +746,10 @@ parse_bookmark_element (GMarkupParseContext *context, visited = attribute_values[i]; else { + /* bookmark is defined by the XBEL spec, so we need + * to error out if the element has different or + * missing attributes + */ g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, _("Unexpected attribute '%s' for element '%s'"), @@ -721,7 +769,7 @@ parse_bookmark_element (GMarkupParseContext *context, return; } - g_assert (parse_data->current_item == NULL); + g_warn_if_fail (parse_data->current_item == NULL); item = bookmark_item_new (uri); @@ -736,8 +784,8 @@ parse_bookmark_element (GMarkupParseContext *context, add_error = NULL; g_bookmark_file_add_item (parse_data->bookmark_file, - item, - &add_error); + item, + &add_error); if (add_error) { bookmark_item_free (item); @@ -757,16 +805,16 @@ parse_application_element (GMarkupParseContext *context, const gchar **attribute_values, GError **error) { - const gchar *name, *exec, *count, *stamp; + const gchar *name, *exec, *count, *stamp, *modified; const gchar *attr; gint i; BookmarkItem *item; BookmarkAppInfo *ai; - g_assert ((parse_data != NULL) && (parse_data->state == STATE_APPLICATION)); + g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_APPLICATION)); i = 0; - name = exec = count = stamp = NULL; + name = exec = count = stamp = modified = NULL; for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i]) { if (IS_ATTRIBUTE (attr, BOOKMARK_NAME_ATTRIBUTE)) @@ -777,17 +825,11 @@ parse_application_element (GMarkupParseContext *context, count = attribute_values[i]; else if (IS_ATTRIBUTE (attr, BOOKMARK_TIMESTAMP_ATTRIBUTE)) stamp = attribute_values[i]; - else - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, - _("Unexpected attribute '%s' for element '%s'"), - attr, - BOOKMARK_APPLICATION_ELEMENT); - return; - } + else if (IS_ATTRIBUTE (attr, BOOKMARK_MODIFIED_ATTRIBUTE)) + modified = attribute_values[i]; } + /* the "name" and "exec" attributes are mandatory */ if (!name) { g_set_error (error, G_MARKUP_ERROR, @@ -808,7 +850,7 @@ parse_application_element (GMarkupParseContext *context, return; } - g_assert (parse_data->current_item != NULL); + g_warn_if_fail (parse_data->current_item != NULL); item = parse_data->current_item; ai = bookmark_item_lookup_app_info (item, name); @@ -829,11 +871,19 @@ parse_application_element (GMarkupParseContext *context, ai->count = atoi (count); else ai->count = 1; - - if (stamp) - ai->stamp = (time_t) atol (stamp); + + if (modified) + ai->stamp = timestamp_from_iso8601 (modified); else - ai->stamp = time (NULL); + { + /* the timestamp attribute has been deprecated but we still parse + * it for backward compatibility + */ + if (stamp) + ai->stamp = (time_t) atol (stamp); + else + ai->stamp = time (NULL); + } } static void @@ -848,7 +898,7 @@ parse_mime_type_element (GMarkupParseContext *context, gint i; BookmarkItem *item; - g_assert ((parse_data != NULL) && (parse_data->state == STATE_MIME)); + g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_MIME)); i = 0; type = NULL; @@ -856,21 +906,12 @@ parse_mime_type_element (GMarkupParseContext *context, { if (IS_ATTRIBUTE (attr, MIME_TYPE_ATTRIBUTE)) type = attribute_values[i]; - else - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, - _("Unexpected attribute '%s' for element '%s'"), - attr, - MIME_TYPE_ELEMENT); - return; - } } if (!type) type = "application/octet-stream"; - g_assert (parse_data->current_item != NULL); + g_warn_if_fail (parse_data->current_item != NULL); item = parse_data->current_item; if (!item->metadata) @@ -892,7 +933,7 @@ parse_icon_element (GMarkupParseContext *context, gint i; BookmarkItem *item; - g_assert ((parse_data != NULL) && (parse_data->state == STATE_ICON)); + g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_ICON)); i = 0; href = NULL; @@ -903,17 +944,9 @@ parse_icon_element (GMarkupParseContext *context, href = attribute_values[i]; else if (IS_ATTRIBUTE (attr, BOOKMARK_TYPE_ATTRIBUTE)) type = attribute_values[i]; - else - { - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, - _("Unexpected attribute '%s' for element '%s'"), - attr, - BOOKMARK_ICON_ELEMENT); - return; - } } + /* the "href" attribute is mandatory */ if (!href) { g_set_error (error, G_MARKUP_ERROR, @@ -927,7 +960,7 @@ parse_icon_element (GMarkupParseContext *context, if (!type) type = "application/octet-stream"; - g_assert (parse_data->current_item != NULL); + g_warn_if_fail (parse_data->current_item != NULL); item = parse_data->current_item; if (!item->metadata) @@ -958,7 +991,7 @@ map_namespace_to_name (ParseData *parse_data, const gchar *attr; gint i; - g_assert (parse_data != NULL); + g_warn_if_fail (parse_data != NULL); if (!attribute_names || !attribute_names[0]) return; @@ -1001,12 +1034,11 @@ is_element_full (ParseData *parse_data, const gchar sep) { gchar *ns_uri, *ns_name; - gchar *element_name, *resolved; - gchar *p, *s; + const gchar *p, *element_name; gboolean retval; - g_assert (parse_data != NULL); - g_assert (element_full != NULL); + g_warn_if_fail (parse_data != NULL); + g_warn_if_fail (element_full != NULL); if (!element) return FALSE; @@ -1020,7 +1052,7 @@ is_element_full (ParseData *parse_data, * namespace has been set, just do a plain comparison between @full_element * and @element. */ - p = strchr (element_full, ':'); + p = g_utf8_strchr (element_full, -1, ':'); if (p) { ns_name = g_strndup (element_full, p - element_full); @@ -1040,14 +1072,11 @@ is_element_full (ParseData *parse_data, return (0 == strcmp (element_full, element)); } - - resolved = g_strdup_printf ("%s%c%s", ns_uri, sep, element_name); - s = g_strdup_printf ("%s%c%s", namespace, sep, element); - retval = (0 == strcmp (resolved, s)); + + retval = (0 == strcmp (ns_uri, namespace) && + 0 == strcmp (element_name, element)); g_free (ns_name); - g_free (resolved); - g_free (s); return retval; } @@ -1235,28 +1264,8 @@ start_element_raw_cb (GMarkupParseContext *context, element_name, BOOKMARK_GROUP_ELEMENT); break; - case STATE_ICON: - if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_ICON_ELEMENT)) - { - GError *inner_error = NULL; - - parse_icon_element (context, - parse_data, - attribute_names, - attribute_values, - &inner_error); - if (inner_error) - g_propagate_error (error, inner_error); - } - else - g_set_error (error, G_MARKUP_ERROR, - G_MARKUP_ERROR_UNKNOWN_ELEMENT, - _("Unexpected tag '%s' inside '%s'"), - element_name, - XBEL_METADATA_ELEMENT); - break; default: - g_assert_not_reached (); + g_warn_if_reached (); break; } } @@ -1346,7 +1355,7 @@ text_raw_cb (GMarkupParseContext *context, { GList *groups; - g_assert (parse_data->current_item != NULL); + g_warn_if_fail (parse_data->current_item != NULL); if (!parse_data->current_item->metadata) parse_data->current_item->metadata = bookmark_metadata_new (); @@ -1366,7 +1375,7 @@ text_raw_cb (GMarkupParseContext *context, case STATE_ICON: break; default: - g_assert_not_reached (); + g_warn_if_reached (); break; } @@ -1384,21 +1393,24 @@ static const GMarkupParser markup_parser = static gboolean g_bookmark_file_parse (GBookmarkFile *bookmark, - const gchar *buffer, - gsize length, - GError **error) + const gchar *buffer, + gsize length, + GError **error) { GMarkupParseContext *context; ParseData *parse_data; GError *parse_error, *end_error; gboolean retval; - g_assert (bookmark != NULL); + g_warn_if_fail (bookmark != NULL); if (!buffer) return FALSE; + + parse_error = NULL; + end_error = NULL; - if (length == -1) + if (length == (gsize) -1) length = strlen (buffer); parse_data = parse_data_new (); @@ -1409,88 +1421,77 @@ g_bookmark_file_parse (GBookmarkFile *bookmark, parse_data, (GDestroyNotify) parse_data_free); - parse_error = NULL; retval = g_markup_parse_context_parse (context, buffer, length, &parse_error); if (!retval) - { - g_propagate_error (error, parse_error); - - return FALSE; - } - - end_error = NULL; - retval = g_markup_parse_context_end_parse (context, &end_error); - if (!retval) - { - g_propagate_error (error, end_error); - - return FALSE; - } - + g_propagate_error (error, parse_error); + else + { + retval = g_markup_parse_context_end_parse (context, &end_error); + if (!retval) + g_propagate_error (error, end_error); + } + g_markup_parse_context_free (context); - - return TRUE; + + return retval; } static gchar * g_bookmark_file_dump (GBookmarkFile *bookmark, - gsize *length, - GError **error) + gsize *length, + GError **error) { GString *retval; + gchar *buffer; GList *l; - retval = g_string_new (NULL); - - g_string_append_printf (retval, - "\n" -#if 0 - /* XXX - do we really need the doctype? */ - "\n" -#endif - "<%s %s=\"%s\"\n" - " xmlns:%s=\"%s\"\n" - " xmlns:%s=\"%s\"\n>", + retval = g_string_sized_new (4096); + + g_string_append (retval, + "\n" #if 0 - /* XXX - do we really need the doctype? */ - XBEL_DTD_NICK, - XBEL_DTD_SYSTEM, XBEL_DTD_URI, + /* XXX - do we really need the doctype? */ + "\n" #endif - XBEL_ROOT_ELEMENT, - XBEL_VERSION_ATTRIBUTE, XBEL_VERSION, - BOOKMARK_NAMESPACE_NAME, BOOKMARK_NAMESPACE_URI, - MIME_NAMESPACE_NAME, MIME_NAMESPACE_URI); + "<" XBEL_ROOT_ELEMENT " " XBEL_VERSION_ATTRIBUTE "=\"" XBEL_VERSION "\"\n" + " xmlns:" BOOKMARK_NAMESPACE_NAME "=\"" BOOKMARK_NAMESPACE_URI "\"\n" + " xmlns:" MIME_NAMESPACE_NAME "=\"" MIME_NAMESPACE_URI "\"\n>"); if (bookmark->title) { gchar *escaped_title; - + escaped_title = g_markup_escape_text (bookmark->title, -1); + + buffer = g_strconcat (" " + "<" XBEL_TITLE_ELEMENT ">", + escaped_title, + "\n", NULL); - g_string_append_printf (retval, " <%s>%s\n", - XBEL_TITLE_ELEMENT, - escaped_title, - XBEL_TITLE_ELEMENT); - + g_string_append (retval, buffer); + + g_free (buffer); g_free (escaped_title); } if (bookmark->description) { gchar *escaped_desc; - + escaped_desc = g_markup_escape_text (bookmark->description, -1); - - g_string_append_printf (retval, " <%s>%s\n", - XBEL_DESC_ELEMENT, - escaped_desc, - XBEL_DESC_ELEMENT); - + + buffer = g_strconcat (" " + "<" XBEL_DESC_ELEMENT ">", + escaped_desc, + "\n", NULL); + g_string_append (retval, buffer); + + g_free (buffer); g_free (escaped_desc); } @@ -1498,7 +1499,8 @@ g_bookmark_file_dump (GBookmarkFile *bookmark, goto out; else retval = g_string_append (retval, "\n"); - + + /* the items are stored in reverse order */ for (l = g_list_last (bookmark->items); l != NULL; l = l->prev) @@ -1512,11 +1514,11 @@ g_bookmark_file_dump (GBookmarkFile *bookmark, retval = g_string_append (retval, item_dump); - g_free (item_dump); + g_free (item_dump); } out: - g_string_append_printf (retval, "", XBEL_ROOT_ELEMENT); + g_string_append (retval, ""); if (length) *length = retval->len; @@ -1558,15 +1560,7 @@ timestamp_from_iso8601 (const gchar *iso_date) return (time_t) stamp.tv_sec; } - - -GQuark -g_bookmark_file_error_quark (void) -{ - return g_quark_from_static_string ("egg-bookmark-file-error-quark"); -} - - +G_DEFINE_QUARK (g-bookmark-file-error-quark, g_bookmark_file_error) /******************** * Public API * @@ -1581,7 +1575,7 @@ g_bookmark_file_error_quark (void) * or g_bookmark_file_load_from_data_dirs() to read an existing bookmark * file. * - * Return value: an empty #GBookmarkFile + * Returns: an empty #GBookmarkFile * * Since: 2.12 */ @@ -1627,7 +1621,7 @@ g_bookmark_file_free (GBookmarkFile *bookmark) * structure. If the object cannot be created then @error is set to a * #GBookmarkFileError. * - * Return value: %TRUE if a desktop bookmark could be loaded. + * Returns: %TRUE if a desktop bookmark could be loaded. * * Since: 2.12 */ @@ -1641,9 +1635,7 @@ g_bookmark_file_load_from_data (GBookmarkFile *bookmark, gboolean retval; g_return_val_if_fail (bookmark != NULL, FALSE); - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (length != 0, FALSE); - + if (length == (gsize) -1) length = strlen (data); @@ -1652,17 +1644,14 @@ g_bookmark_file_load_from_data (GBookmarkFile *bookmark, g_bookmark_file_clear (bookmark); g_bookmark_file_init (bookmark); } - + parse_error = NULL; retval = g_bookmark_file_parse (bookmark, data, length, &parse_error); + if (!retval) - { - g_propagate_error (error, parse_error); - - return FALSE; - } - - return TRUE; + g_propagate_error (error, parse_error); + + return retval; } /** @@ -1675,7 +1664,7 @@ g_bookmark_file_load_from_data (GBookmarkFile *bookmark, * If the file could not be loaded then @error is set to either a #GFileError * or #GBookmarkFileError. * - * Return value: %TRUE if a desktop bookmark file could be loaded + * Returns: %TRUE if a desktop bookmark file could be loaded * * Since: 2.12 */ @@ -1684,40 +1673,23 @@ g_bookmark_file_load_from_file (GBookmarkFile *bookmark, const gchar *filename, GError **error) { - gchar *buffer; + gboolean ret = FALSE; + gchar *buffer = NULL; gsize len; - GError *read_error; - gboolean retval; g_return_val_if_fail (bookmark != NULL, FALSE); g_return_val_if_fail (filename != NULL, FALSE); - read_error = NULL; - g_file_get_contents (filename, &buffer, &len, &read_error); - if (read_error) - { - g_propagate_error (error, read_error); - - return FALSE; - } + if (!g_file_get_contents (filename, &buffer, &len, error)) + goto out; - read_error = NULL; - retval = g_bookmark_file_load_from_data (bookmark, - buffer, - len, - &read_error); - if (read_error) - { - g_propagate_error (error, read_error); - - g_free (buffer); - - return FALSE; - } + if (!g_bookmark_file_load_from_data (bookmark, buffer, len, error)) + goto out; + ret = TRUE; + out: g_free (buffer); - - return retval; + return ret; } @@ -1779,9 +1751,9 @@ find_file_in_data_dirs (const gchar *file, if (!path) { - g_set_error (error, G_BOOKMARK_FILE_ERROR, - G_BOOKMARK_FILE_ERROR_FILE_NOT_FOUND, - _("No valid bookmark file was be found in data dirs")); + g_set_error_literal (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_FILE_NOT_FOUND, + _("No valid bookmark file found in data dirs")); return NULL; } @@ -1794,7 +1766,7 @@ find_file_in_data_dirs (const gchar *file, * g_bookmark_file_load_from_data_dirs: * @bookmark: a #GBookmarkFile * @file: a relative path to a filename to open and parse - * @full_path: return location for a string containing the full path + * @full_path: (allow-none): return location for a string containing the full path * of the file, or %NULL * @error: return location for a #GError, or %NULL * @@ -1804,7 +1776,7 @@ find_file_in_data_dirs (const gchar *file, * @full_path. If the file could not be loaded then an %error is * set to either a #GFileError or #GBookmarkFileError. * - * Return value: %TRUE if a key file could be loaded, %FALSE othewise + * Returns: %TRUE if a key file could be loaded, %FALSE otherwise * * Since: 2.12 */ @@ -1875,12 +1847,12 @@ g_bookmark_file_load_from_data_dirs (GBookmarkFile *bookmark, /** * g_bookmark_file_to_data: * @bookmark: a #GBookmarkFile - * @length: return location for the length of the returned string, or %NULL + * @length: (allow-none) (out): return location for the length of the returned string, or %NULL * @error: return location for a #GError, or %NULL * * This function outputs @bookmark as a string. * - * Return value: a newly allocated string holding + * Returns: a newly allocated string holding * the contents of the #GBookmarkFile * * Since: 2.12 @@ -1915,7 +1887,7 @@ g_bookmark_file_to_data (GBookmarkFile *bookmark, * This function outputs @bookmark into a file. The write process is * guaranteed to be atomic by using g_file_set_contents() internally. * - * Return value: %TRUE if the file was successfully written. + * Returns: %TRUE if the file was successfully written. * * Since: 2.12 */ @@ -1961,7 +1933,7 @@ static BookmarkItem * g_bookmark_file_lookup_item (GBookmarkFile *bookmark, const gchar *uri) { - g_assert (bookmark != NULL && uri != NULL); + g_warn_if_fail (bookmark != NULL && uri != NULL); return g_hash_table_lookup (bookmark->items_by_uri, uri); } @@ -1972,8 +1944,8 @@ g_bookmark_file_add_item (GBookmarkFile *bookmark, BookmarkItem *item, GError **error) { - g_assert (bookmark != NULL); - g_assert (item != NULL); + g_warn_if_fail (bookmark != NULL); + g_warn_if_fail (item != NULL); /* this should never happen; and if it does, then we are * screwing up something big time. @@ -2008,17 +1980,19 @@ g_bookmark_file_add_item (GBookmarkFile *bookmark, * * Removes the bookmark for @uri from the bookmark file @bookmark. * + * Returns: %TRUE if the bookmark was removed successfully. + * * Since: 2.12 */ -void +gboolean g_bookmark_file_remove_item (GBookmarkFile *bookmark, const gchar *uri, GError **error) { BookmarkItem *item; - g_return_if_fail (bookmark != NULL); - g_return_if_fail (uri != NULL); + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); item = g_bookmark_file_lookup_item (bookmark, uri); @@ -2028,13 +2002,15 @@ g_bookmark_file_remove_item (GBookmarkFile *bookmark, G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, _("No bookmark found for URI '%s'"), uri); - return; + return FALSE; } bookmark->items = g_list_remove (bookmark->items, item); g_hash_table_remove (bookmark->items_by_uri, item->uri); bookmark_item_free (item); + + return TRUE; } /** @@ -2044,7 +2020,7 @@ g_bookmark_file_remove_item (GBookmarkFile *bookmark, * * Looks whether the desktop bookmark has an item with its URI set to @uri. * - * Return value: %TRUE if @uri is inside @bookmark, %FALSE otherwise + * Returns: %TRUE if @uri is inside @bookmark, %FALSE otherwise * * Since: 2.12 */ @@ -2061,13 +2037,13 @@ g_bookmark_file_has_item (GBookmarkFile *bookmark, /** * g_bookmark_file_get_uris: * @bookmark: a #GBookmarkFile - * @length: return location for the number of returned URIs, or %NULL + * @length: (allow-none) (out): return location for the number of returned URIs, or %NULL * * Returns all URIs of the bookmarks in the bookmark file @bookmark. * The array of returned URIs will be %NULL-terminated, so @length may * optionally be %NULL. * - * Return value: a newly allocated %NULL-terminated array of strings. + * Returns: (array length=length) (transfer full): a newly allocated %NULL-terminated array of strings. * Use g_strfreev() to free it. * * Since: 2.12 @@ -2084,12 +2060,13 @@ g_bookmark_file_get_uris (GBookmarkFile *bookmark, n_items = g_list_length (bookmark->items); uris = g_new0 (gchar *, n_items + 1); - + + /* the items are stored in reverse order, so we walk the list backward */ for (l = g_list_last (bookmark->items), i = 0; l != NULL; l = l->prev) { BookmarkItem *item = (BookmarkItem *) l->data; - g_assert (item != NULL); + g_warn_if_fail (item != NULL); uris[i++] = g_strdup (item->uri); } @@ -2104,7 +2081,7 @@ g_bookmark_file_get_uris (GBookmarkFile *bookmark, /** * g_bookmark_file_set_title: * @bookmark: a #GBookmarkFile - * @uri: a valid URI or %NULL + * @uri: (allow-none): a valid URI or %NULL * @title: a UTF-8 encoded string * * Sets @title as the title of the bookmark for @uri inside the @@ -2126,9 +2103,7 @@ g_bookmark_file_set_title (GBookmarkFile *bookmark, if (!uri) { g_free (bookmark->title); - - if (title && title[0] != '\0') - bookmark->title = g_strdup (title); + bookmark->title = g_strdup (title); } else { @@ -2142,9 +2117,7 @@ g_bookmark_file_set_title (GBookmarkFile *bookmark, } g_free (item->title); - - if (title && title[0] != '\0') - item->title = g_strdup (title); + item->title = g_strdup (title); item->modified = time (NULL); } @@ -2153,7 +2126,7 @@ g_bookmark_file_set_title (GBookmarkFile *bookmark, /** * g_bookmark_file_get_title: * @bookmark: a #GBookmarkFile - * @uri: a valid URI or %NULL + * @uri: (allow-none): a valid URI or %NULL * @error: return location for a #GError, or %NULL * * Returns the title of the bookmark for @uri. @@ -2163,7 +2136,7 @@ g_bookmark_file_set_title (GBookmarkFile *bookmark, * In the event the URI cannot be found, %NULL is returned and * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. * - * Return value: a newly allocated string or %NULL if the specified + * Returns: a newly allocated string or %NULL if the specified * URI cannot be found. * * Since: 2.12 @@ -2196,7 +2169,7 @@ g_bookmark_file_get_title (GBookmarkFile *bookmark, /** * g_bookmark_file_set_description: * @bookmark: a #GBookmarkFile - * @uri: a valid URI or %NULL + * @uri: (allow-none): a valid URI or %NULL * @description: a string * * Sets @description as the description of the bookmark for @uri. @@ -2216,10 +2189,8 @@ g_bookmark_file_set_description (GBookmarkFile *bookmark, if (!uri) { - g_free (bookmark->description); - - if (description && description[0] != '\0') - bookmark->description = g_strdup (description); + g_free (bookmark->description); + bookmark->description = g_strdup (description); } else { @@ -2233,9 +2204,7 @@ g_bookmark_file_set_description (GBookmarkFile *bookmark, } g_free (item->description); - - if (description && description[0] != '\0') - item->description = g_strdup (description); + item->description = g_strdup (description); item->modified = time (NULL); } @@ -2252,7 +2221,7 @@ g_bookmark_file_set_description (GBookmarkFile *bookmark, * In the event the URI cannot be found, %NULL is returned and * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. * - * Return value: a newly allocated string or %NULL if the specified + * Returns: a newly allocated string or %NULL if the specified * URI cannot be found. * * Since: 2.12 @@ -2315,8 +2284,7 @@ g_bookmark_file_set_mime_type (GBookmarkFile *bookmark, if (!item->metadata) item->metadata = bookmark_metadata_new (); - if (item->metadata->mime_type != NULL) - g_free (item->metadata->mime_type); + g_free (item->metadata->mime_type); item->metadata->mime_type = g_strdup (mime_type); item->modified = time (NULL); @@ -2335,7 +2303,7 @@ g_bookmark_file_set_mime_type (GBookmarkFile *bookmark, * event that the MIME type cannot be found, %NULL is returned and * @error is set to #G_BOOKMARK_FILE_ERROR_INVALID_VALUE. * - * Return value: a newly allocated string or %NULL if the specified + * Returns: a newly allocated string or %NULL if the specified * URI cannot be found. * * Since: 2.12 @@ -2421,7 +2389,7 @@ g_bookmark_file_set_is_private (GBookmarkFile *bookmark, * event that the private flag cannot be found, %FALSE is returned and * @error is set to #G_BOOKMARK_FILE_ERROR_INVALID_VALUE. * - * Return value: %TRUE if the private flag is set, %FALSE otherwise. + * Returns: %TRUE if the private flag is set, %FALSE otherwise. * * Since: 2.12 */ @@ -2504,7 +2472,7 @@ g_bookmark_file_set_added (GBookmarkFile *bookmark, * In the event the URI cannot be found, -1 is returned and * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. * - * Return value: a timestamp + * Returns: a timestamp * * Since: 2.12 */ @@ -2582,7 +2550,7 @@ g_bookmark_file_set_modified (GBookmarkFile *bookmark, * In the event the URI cannot be found, -1 is returned and * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. * - * Return value: a timestamp + * Returns: a timestamp * * Since: 2.12 */ @@ -2661,7 +2629,7 @@ g_bookmark_file_set_visited (GBookmarkFile *bookmark, * In the event the URI cannot be found, -1 is returned and * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. * - * Return value: a timestamp. + * Returns: a timestamp. * * Since: 2.12 */ @@ -2701,7 +2669,7 @@ g_bookmark_file_get_visited (GBookmarkFile *bookmark, * In the event the URI cannot be found, %FALSE is returned and * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. * - * Return value: %TRUE if @group was found. + * Returns: %TRUE if @group was found. * * Since: 2.12 */ @@ -2798,7 +2766,7 @@ g_bookmark_file_add_group (GBookmarkFile *bookmark, * In the event no group was defined, %FALSE is returned and * @error is set to #G_BOOKMARK_FILE_ERROR_INVALID_VALUE. * - * Return value: %TRUE if @group was successfully removed. + * Returns: %TRUE if @group was successfully removed. * * Since: 2.12 */ @@ -2838,7 +2806,8 @@ g_bookmark_file_remove_group (GBookmarkFile *bookmark, if (strcmp (l->data, group) == 0) { item->metadata->groups = g_list_remove_link (item->metadata->groups, l); - g_list_free_1 (l); + g_free (l->data); + g_list_free_1 (l); item->modified = time (NULL); @@ -2853,7 +2822,7 @@ g_bookmark_file_remove_group (GBookmarkFile *bookmark, * g_bookmark_file_set_groups: * @bookmark: a #GBookmarkFile * @uri: an item's URI - * @groups: an array of group names, or %NULL to remove all groups + * @groups: (allow-none): an array of group names, or %NULL to remove all groups * @length: number of group name values in @groups * * Sets a list of group names for the item with URI @uri. Each previously @@ -2886,14 +2855,8 @@ g_bookmark_file_set_groups (GBookmarkFile *bookmark, if (!item->metadata) item->metadata = bookmark_metadata_new (); - if (item->metadata->groups != NULL) - { - g_list_foreach (item->metadata->groups, - (GFunc) g_free, - NULL); - g_list_free (item->metadata->groups); - item->metadata->groups = NULL; - } + g_list_free_full (item->metadata->groups, g_free); + item->metadata->groups = NULL; if (groups) { @@ -2909,7 +2872,7 @@ g_bookmark_file_set_groups (GBookmarkFile *bookmark, * g_bookmark_file_get_groups: * @bookmark: a #GBookmarkFile * @uri: a valid URI - * @length: return location for the length of the returned string, or %NULL + * @length: (allow-none) (out): return location for the length of the returned string, or %NULL * @error: return location for a #GError, or %NULL * * Retrieves the list of group names of the bookmark for @uri. @@ -2920,8 +2883,10 @@ g_bookmark_file_set_groups (GBookmarkFile *bookmark, * The returned array is %NULL terminated, so @length may optionally * be %NULL. * - * Return value: a newly allocated %NULL-terminated array of group names. + * Returns: (array length=length) (transfer full): a newly allocated %NULL-terminated array of group names. * Use g_strfreev() to free it. + * + * Since: 2.12 */ gchar ** g_bookmark_file_get_groups (GBookmarkFile *bookmark, @@ -2963,7 +2928,7 @@ g_bookmark_file_get_groups (GBookmarkFile *bookmark, { gchar *group_name = (gchar *) l->data; - g_assert (group_name != NULL); + g_warn_if_fail (group_name != NULL); retval[i++] = g_strdup (group_name); } @@ -2979,9 +2944,9 @@ g_bookmark_file_get_groups (GBookmarkFile *bookmark, * g_bookmark_file_add_application: * @bookmark: a #GBookmarkFile * @uri: a valid URI - * @name: the name of the application registering the bookmark + * @name: (allow-none): the name of the application registering the bookmark * or %NULL - * @exec: command line to be used to launch the bookmark or %NULL + * @exec: (allow-none): command line to be used to launch the bookmark or %NULL * * Adds the application with @name and @exec to the list of * applications that have registered a bookmark for @uri into @@ -2994,9 +2959,9 @@ g_bookmark_file_get_groups (GBookmarkFile *bookmark, * time the application registered this bookmark. * * If @name is %NULL, the name of the application will be the - * same returned by g_get_application(); if @exec is %NULL, the + * same returned by g_get_application_name(); if @exec is %NULL, the * command line will be a composition of the program name as - * returned by g_get_prgname() and the "%u" modifier, which will be + * returned by g_get_prgname() and the "\%u" modifier, which will be * expanded to the bookmark's URI. * * This function will automatically take care of updating the @@ -3064,7 +3029,7 @@ g_bookmark_file_add_application (GBookmarkFile *bookmark, * a bookmark for @uri, %FALSE is returned and error is set to * #G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED. * - * Return value: %TRUE if the application was successfully removed. + * Returns: %TRUE if the application was successfully removed. * * Since: 2.12 */ @@ -3084,7 +3049,7 @@ g_bookmark_file_remove_application (GBookmarkFile *bookmark, set_error = NULL; retval = g_bookmark_file_set_app_info (bookmark, uri, name, - NULL, + "", 0, (time_t) -1, &set_error); @@ -3111,7 +3076,7 @@ g_bookmark_file_remove_application (GBookmarkFile *bookmark, * In the event the URI cannot be found, %FALSE is returned and * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. * - * Return value: %TRUE if the application @name was found + * Returns: %TRUE if the application @name was found * * Since: 2.12 */ @@ -3159,9 +3124,9 @@ g_bookmark_file_has_application (GBookmarkFile *bookmark, * * @name can be any UTF-8 encoded string used to identify an * application. - * @exec can have one of these two modifiers: "%f", which will + * @exec can have one of these two modifiers: "\%f", which will * be expanded as the local file name retrieved from the bookmark's - * URI; "%u", which will be expanded as the bookmark's URI. + * URI; "\%u", which will be expanded as the bookmark's URI. * The expansion is done automatically when retrieving the stored * command line using the g_bookmark_file_get_app_info() function. * @count is the number of times the application has registered the @@ -3179,7 +3144,7 @@ g_bookmark_file_has_application (GBookmarkFile *bookmark, * #G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED. Otherwise, if no bookmark * for @uri is found, one is created. * - * Return value: %TRUE if the application's meta-data was successfully + * Returns: %TRUE if the application's meta-data was successfully * changed. * * Since: 2.12 @@ -3219,6 +3184,9 @@ g_bookmark_file_set_app_info (GBookmarkFile *bookmark, } } + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + ai = bookmark_item_lookup_app_info (item, name); if (!ai) { @@ -3244,7 +3212,8 @@ g_bookmark_file_set_app_info (GBookmarkFile *bookmark, { item->metadata->applications = g_list_remove (item->metadata->applications, ai); g_hash_table_remove (item->metadata->apps_by_name, ai->name); - + bookmark_app_info_free (ai); + item->modified = time (NULL); return TRUE; @@ -3262,7 +3231,7 @@ g_bookmark_file_set_app_info (GBookmarkFile *bookmark, if (exec && exec[0] != '\0') { g_free (ai->exec); - ai->exec = g_strdup (exec); + ai->exec = g_shell_quote (exec); } item->modified = time (NULL); @@ -3278,7 +3247,7 @@ expand_exec_line (const gchar *exec_fmt, GString *exec; gchar ch; - exec = g_string_new (NULL); + exec = g_string_sized_new (512); while ((ch = *exec_fmt++) != '\0') { if (ch != '%') @@ -3290,14 +3259,26 @@ expand_exec_line (const gchar *exec_fmt, ch = *exec_fmt++; switch (ch) { + case '\0': + goto out; + case 'U': case 'u': - g_string_append_printf (exec, "%s", uri); + g_string_append (exec, uri); break; + case 'F': case 'f': { - gchar *file = g_filename_from_uri (uri, NULL, NULL); - g_string_append_printf (exec, "%s", file); - g_free (file); + gchar *file = g_filename_from_uri (uri, NULL, NULL); + if (file) + { + g_string_append (exec, file); + g_free (file); + } + else + { + g_string_free (exec, TRUE); + return NULL; + } } break; case '%': @@ -3307,6 +3288,7 @@ expand_exec_line (const gchar *exec_fmt, } } + out: return g_string_free (exec, FALSE); } @@ -3315,9 +3297,9 @@ expand_exec_line (const gchar *exec_fmt, * @bookmark: a #GBookmarkFile * @uri: a valid URI * @name: an application's name - * @exec: location for the command line of the application, or %NULL - * @count: return location for the registration count, or %NULL - * @stamp: return location for the last registration time, or %NULL + * @exec: (allow-none) (out): return location for the command line of the application, or %NULL + * @count: (allow-none) (out): return location for the registration count, or %NULL + * @stamp: (allow-none) (out): return location for the last registration time, or %NULL * @error: return location for a #GError, or %NULL * * Gets the registration informations of @app_name for the bookmark for @@ -3330,9 +3312,11 @@ expand_exec_line (const gchar *exec_fmt, * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. In the * event that no application with name @app_name has registered a bookmark * for @uri, %FALSE is returned and error is set to - * #G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED. + * #G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED. In the event that unquoting + * the command line fails, an error of the #G_SHELL_ERROR domain is + * set and %FALSE is returned. * - * Return value: %TRUE on success. + * Returns: %TRUE on success. * * Since: 2.12 */ @@ -3374,8 +3358,32 @@ g_bookmark_file_get_app_info (GBookmarkFile *bookmark, } if (exec) - *exec = expand_exec_line (ai->exec, uri); - + { + GError *unquote_error = NULL; + gchar *command_line; + + command_line = g_shell_unquote (ai->exec, &unquote_error); + if (unquote_error) + { + g_propagate_error (error, unquote_error); + return FALSE; + } + + *exec = expand_exec_line (command_line, uri); + if (!*exec) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_INVALID_URI, + _("Failed to expand exec line '%s' with URI '%s'"), + ai->exec, uri); + g_free (command_line); + + return FALSE; + } + else + g_free (command_line); + } + if (count) *count = ai->count; @@ -3389,7 +3397,7 @@ g_bookmark_file_get_app_info (GBookmarkFile *bookmark, * g_bookmark_file_get_applications: * @bookmark: a #GBookmarkFile * @uri: a valid URI - * @length: return location of the length of the returned list, or %NULL + * @length: (allow-none) (out): return location of the length of the returned list, or %NULL * @error: return location for a #GError, or %NULL * * Retrieves the names of the applications that have registered the @@ -3398,7 +3406,7 @@ g_bookmark_file_get_app_info (GBookmarkFile *bookmark, * In the event the URI cannot be found, %NULL is returned and * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. * - * Return value: a newly allocated %NULL-terminated array of strings. + * Returns: (array length=length) (transfer full): a newly allocated %NULL-terminated array of strings. * Use g_strfreev() to free it. * * Since: 2.12 @@ -3446,8 +3454,8 @@ g_bookmark_file_get_applications (GBookmarkFile *bookmark, ai = (BookmarkAppInfo *) l->data; - g_assert (ai != NULL); - g_assert (ai->name != NULL); + g_warn_if_fail (ai != NULL); + g_warn_if_fail (ai->name != NULL); apps[i++] = g_strdup (ai->name); } @@ -3465,7 +3473,7 @@ g_bookmark_file_get_applications (GBookmarkFile *bookmark, * * Gets the number of bookmarks inside @bookmark. * - * Return value: the number of bookmarks + * Returns: the number of bookmarks * * Since: 2.12 */ @@ -3481,7 +3489,7 @@ g_bookmark_file_get_size (GBookmarkFile *bookmark) * g_bookmark_file_move_item: * @bookmark: a #GBookmarkFile * @old_uri: a valid URI - * @new_uri: a valid URI, or %NULL + * @new_uri: (allow-none): a valid URI, or %NULL * @error: return location for a #GError or %NULL * * Changes the URI of a bookmark item from @old_uri to @new_uri. Any @@ -3491,7 +3499,7 @@ g_bookmark_file_get_size (GBookmarkFile *bookmark) * In the event the URI cannot be found, %FALSE is returned and * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. * - * Return value: %TRUE if the URI was successfully changed + * Returns: %TRUE if the URI was successfully changed * * Since: 2.12 */ @@ -3502,11 +3510,10 @@ g_bookmark_file_move_item (GBookmarkFile *bookmark, GError **error) { BookmarkItem *item; - GError *remove_error; g_return_val_if_fail (bookmark != NULL, FALSE); g_return_val_if_fail (old_uri != NULL, FALSE); - + item = g_bookmark_file_lookup_item (bookmark, old_uri); if (!item) { @@ -3521,48 +3528,41 @@ g_bookmark_file_move_item (GBookmarkFile *bookmark, { if (g_bookmark_file_has_item (bookmark, new_uri)) { - remove_error = NULL; - g_bookmark_file_remove_item (bookmark, new_uri, &remove_error); - if (remove_error) - { - g_propagate_error (error, remove_error); - - return FALSE; - } + if (!g_bookmark_file_remove_item (bookmark, new_uri, error)) + return FALSE; } + + g_hash_table_steal (bookmark->items_by_uri, item->uri); g_free (item->uri); item->uri = g_strdup (new_uri); item->modified = time (NULL); - + + g_hash_table_replace (bookmark->items_by_uri, item->uri, item); + return TRUE; } else { - remove_error = NULL; - g_bookmark_file_remove_item (bookmark, old_uri, &remove_error); - if (remove_error) - { - g_propagate_error (error, remove_error); - - return FALSE; - } + if (!g_bookmark_file_remove_item (bookmark, old_uri, error)) + return FALSE; + + return TRUE; } - - return FALSE; } /** * g_bookmark_file_set_icon: * @bookmark: a #GBookmarkFile * @uri: a valid URI - * @href: the URI of the icon for the bookmark, or %NULL + * @href: (allow-none): the URI of the icon for the bookmark, or %NULL * @mime_type: the MIME type of the icon for the bookmark * - * Sets the icon for the bookmark for @uri. If @href is %NULL, unsets - * the currently set icon. + * Sets the icon for the bookmark for @uri. If @href is %NULL, unsets + * the currently set icon. @href can either be a full URL for the icon + * file or the icon name following the Icon Naming specification. * - * If no bookmark for @uri is found it is created. + * If no bookmark for @uri is found one is created. * * Since: 2.12 */ @@ -3590,8 +3590,7 @@ g_bookmark_file_set_icon (GBookmarkFile *bookmark, g_free (item->metadata->icon_href); g_free (item->metadata->icon_mime); - if (href && href[0] != '\0') - item->metadata->icon_href = g_strdup (href); + item->metadata->icon_href = g_strdup (href); if (mime_type && mime_type[0] != '\0') item->metadata->icon_mime = g_strdup (mime_type); @@ -3605,8 +3604,8 @@ g_bookmark_file_set_icon (GBookmarkFile *bookmark, * g_bookmark_file_get_icon: * @bookmark: a #GBookmarkFile * @uri: a valid URI - * @href: return location for the icon's location or %NULL - * @mime_type: return location for the icon's MIME type or %NULL + * @href: (allow-none) (out): return location for the icon's location or %NULL + * @mime_type: (allow-none) (out): return location for the icon's MIME type or %NULL * @error: return location for a #GError or %NULL * * Gets the icon of the bookmark for @uri. @@ -3614,7 +3613,7 @@ g_bookmark_file_set_icon (GBookmarkFile *bookmark, * In the event the URI cannot be found, %FALSE is returned and * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. * - * Return value: %TRUE if the icon for the bookmark for the URI was found. + * Returns: %TRUE if the icon for the bookmark for the URI was found. * You should free the returned strings. * * Since: 2.12 @@ -3652,6 +3651,3 @@ g_bookmark_file_get_icon (GBookmarkFile *bookmark, return TRUE; } - -#define __G_BOOKMARK_FILE_C__ -#include "galiasdef.c"