diff options
-rw-r--r-- | client/Makefile.am | 2 | ||||
-rw-r--r-- | client/as-util.c | 321 | ||||
-rw-r--r-- | libappstream-glib/Makefile.am | 1 | ||||
-rw-r--r-- | libappstream-glib/as-app-validate.c | 117 | ||||
-rw-r--r-- | libappstream-glib/as-app.c | 269 | ||||
-rw-r--r-- | libappstream-glib/as-cleanup.h | 97 | ||||
-rw-r--r-- | libappstream-glib/as-image.c | 48 | ||||
-rw-r--r-- | libappstream-glib/as-node.c | 166 | ||||
-rw-r--r-- | libappstream-glib/as-release.c | 7 | ||||
-rw-r--r-- | libappstream-glib/as-screenshot.c | 24 | ||||
-rw-r--r-- | libappstream-glib/as-self-test.c | 160 | ||||
-rw-r--r-- | libappstream-glib/as-store.c | 319 | ||||
-rw-r--r-- | libappstream-glib/as-utils.c | 112 |
13 files changed, 605 insertions, 1038 deletions
diff --git a/client/Makefile.am b/client/Makefile.am index 73e0592..d490f98 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -3,6 +3,7 @@ AM_CPPFLAGS = \ $(GLIB_CFLAGS) \ $(GDKPIXBUF_CFLAGS) \ $(LIBARCHIVE_CFLAGS) \ + $(SOUP_CFLAGS) \ -I$(top_srcdir) \ -I$(top_builddir) \ -I$(top_srcdir)/libappstream-glib \ @@ -22,6 +23,7 @@ appstream_util_SOURCES = \ appstream_util_LDADD = \ $(AS_GLIB_LIBS) \ $(GLIB_LIBS) \ + $(SOUP_LIBS) \ $(LIBARCHIVE_LIBS) appstream_util_LDFLAGS = \ $(PIE_LDFLAGS) diff --git a/client/as-util.c b/client/as-util.c index 754cace..535918a 100644 --- a/client/as-util.c +++ b/client/as-util.c @@ -30,6 +30,8 @@ #include <archive.h> #include <locale.h> +#include "as-cleanup.h" + #define AS_ERROR 1 #define AS_ERROR_INVALID_ARGUMENTS 0 #define AS_ERROR_NO_SUCH_CMD 1 @@ -82,7 +84,7 @@ as_util_add (GPtrArray *array, const gchar *description, AsUtilPrivateCb callback) { - gchar **names; + _cleanup_free_strv gchar **names = NULL; guint i; AsUtilItem *item; @@ -106,7 +108,6 @@ as_util_add (GPtrArray *array, item->callback = callback; g_ptr_array_add (array, item); } - g_strfreev (names); } /** @@ -161,18 +162,15 @@ as_util_get_descriptions (GPtrArray *array) static gboolean as_util_run (AsUtilPrivate *priv, const gchar *command, gchar **values, GError **error) { - gboolean ret = FALSE; - guint i; AsUtilItem *item; - GString *string; + _cleanup_free_string GString *string = NULL; + guint i; /* find command */ for (i = 0; i < priv->cmd_array->len; i++) { item = g_ptr_array_index (priv->cmd_array, i); - if (g_strcmp0 (item->name, command) == 0) { - ret = item->callback (priv, values, error); - goto out; - } + if (g_strcmp0 (item->name, command) == 0) + return item->callback (priv, values, error); } /* not found */ @@ -187,9 +185,7 @@ as_util_run (AsUtilPrivate *priv, const gchar *command, gchar **values, GError * item->arguments ? item->arguments : ""); } g_set_error_literal (error, AS_ERROR, AS_ERROR_NO_SUCH_CMD, string->str); - g_string_free (string, TRUE); -out: - return ret; + return FALSE; } /** @@ -198,48 +194,37 @@ out: static gboolean as_util_convert (AsUtilPrivate *priv, gchar **values, GError **error) { - AsStore *store = NULL; - GFile *file_input = NULL; - GFile *file_output = NULL; - gboolean ret = TRUE; + _cleanup_unref_object AsStore *store = NULL; + _cleanup_unref_object GFile *file_input = NULL; + _cleanup_unref_object GFile *file_output = NULL; /* check args */ if (g_strv_length (values) != 3) { - ret = FALSE; g_set_error_literal (error, AS_ERROR, AS_ERROR_INVALID_ARGUMENTS, "Not enough arguments, " "expected old.xml new.xml version"); - goto out; + return FALSE; } /* load file */ store = as_store_new (); file_input = g_file_new_for_path (values[0]); - ret = as_store_from_file (store, file_input, NULL, NULL, error); - if (!ret) - goto out; + if (!as_store_from_file (store, file_input, NULL, NULL, error)) + return FALSE; g_print ("Old API version: %.2f\n", as_store_get_api_version (store)); /* save file */ as_store_set_api_version (store, g_ascii_strtod (values[2], NULL)); file_output = g_file_new_for_path (values[1]); - ret = as_store_to_file (store, file_output, + if (!as_store_to_file (store, file_output, AS_NODE_TO_XML_FLAG_FORMAT_MULTILINE | AS_NODE_TO_XML_FLAG_ADD_HEADER, - NULL, error); - if (!ret) - goto out; + NULL, error)) + return FALSE; g_print ("New API version: %.2f\n", as_store_get_api_version (store)); -out: - if (store != NULL) - g_object_unref (store); - if (file_input != NULL) - g_object_unref (file_input); - if (file_output != NULL) - g_object_unref (file_output); - return ret; + return TRUE; } /** @@ -248,28 +233,25 @@ out: static gboolean as_util_dump (AsUtilPrivate *priv, gchar **values, GError **error) { - AsStore *store = NULL; - GFile *file_input = NULL; - GString *xml = NULL; - gboolean ret = TRUE; + _cleanup_free_string GString *xml = NULL; + _cleanup_unref_object AsStore *store = NULL; + _cleanup_unref_object GFile *file_input = NULL; /* check args */ if (g_strv_length (values) != 1) { - ret = FALSE; g_set_error_literal (error, AS_ERROR, AS_ERROR_INVALID_ARGUMENTS, "Not enough arguments, " "expected data.xml"); - goto out; + return FALSE; } /* load file */ store = as_store_new (); file_input = g_file_new_for_path (values[0]); - ret = as_store_from_file (store, file_input, NULL, NULL, error); - if (!ret) - goto out; + if (!as_store_from_file (store, file_input, NULL, NULL, error)) + return FALSE; /* dump to screen */ as_store_set_api_version (store, 1.0); @@ -278,14 +260,7 @@ as_util_dump (AsUtilPrivate *priv, gchar **values, GError **error) AS_NODE_TO_XML_FLAG_FORMAT_INDENT | AS_NODE_TO_XML_FLAG_ADD_HEADER); g_print ("%s\n", xml->str); -out: - if (store != NULL) - g_object_unref (store); - if (xml != NULL) - g_string_free (xml, TRUE); - if (file_input != NULL) - g_object_unref (file_input); - return ret; + return TRUE; } /** @@ -294,12 +269,12 @@ out: static gboolean as_util_install_icons (const gchar *filename, const gchar *origin, GError **error) { + _cleanup_free gchar *data = NULL; + _cleanup_free gchar *dir = NULL; const gchar *destdir; const gchar *tmp; gboolean ret = TRUE; gchar buf[PATH_MAX]; - gchar *data = NULL; - gchar *dir; gsize len; int r; struct archive *arch = NULL; @@ -379,8 +354,6 @@ as_util_install_icons (const gchar *filename, const gchar *origin, GError **erro } } out: - g_free (data); - g_free (dir); if (arch != NULL) { archive_read_close (arch); archive_read_free (arch); @@ -394,27 +367,23 @@ out: static gboolean as_util_install_xml (const gchar *filename, GError **error) { - GFile *file_dest = NULL; - GFile *file_src = NULL; + _cleanup_free gchar *basename = NULL; + _cleanup_free gchar *path_dest = NULL; + _cleanup_free gchar *path_parent = NULL; + _cleanup_unref_object GFile *file_dest = NULL; + _cleanup_unref_object GFile *file_src = NULL; const gchar *destdir; - gboolean ret; - gchar *basename = NULL; - gchar *path_dest = NULL; - gchar *path_parent = NULL; - gint rc; /* create directory structure */ destdir = g_getenv ("DESTDIR"); path_parent = g_strdup_printf ("%s/usr/share/app-info/xmls", destdir != NULL ? destdir : ""); - rc = g_mkdir_with_parents (path_parent, 0777); - if (rc != 0) { - ret = FALSE; + if (g_mkdir_with_parents (path_parent, 0777) != 0) { g_set_error (error, AS_ERROR, AS_ERROR_FAILED, "Failed to create %s", path_parent); - goto out; + return FALSE; } /* copy XML file */ @@ -422,17 +391,8 @@ as_util_install_xml (const gchar *filename, GError **error) basename = g_path_get_basename (filename); path_dest = g_build_filename (path_parent, basename, NULL); file_dest = g_file_new_for_path (path_dest); - ret = g_file_copy (file_src, file_dest, G_FILE_COPY_OVERWRITE, - NULL, NULL, NULL, error); -out: - if (file_dest != NULL) - g_object_unref (file_dest); - if (file_src != NULL) - g_object_unref (file_src); - g_free (basename); - g_free (path_parent); - g_free (path_dest); - return ret; + return g_file_copy (file_src, file_dest, G_FILE_COPY_OVERWRITE, + NULL, NULL, NULL, error); } /** @@ -441,24 +401,20 @@ out: static gboolean as_util_install_filename (const gchar *filename, GError **error) { - gchar *basename = NULL; + _cleanup_free gchar *basename = NULL; gchar *tmp; - gboolean ret = FALSE; /* xml */ tmp = g_strstr_len (filename, -1, ".xml.gz"); - if (tmp != NULL) { - ret = as_util_install_xml (filename, error); - goto out; - } + if (tmp != NULL) + return as_util_install_xml (filename, error); /* icons */ basename = g_path_get_basename (filename); tmp = g_strstr_len (basename, -1, "-icons.tar.gz"); if (tmp != NULL) { *tmp = '\0'; - ret = as_util_install_icons (filename, basename, error); - goto out; + return as_util_install_icons (filename, basename, error); } /* unrecognised */ @@ -466,9 +422,7 @@ as_util_install_filename (const gchar *filename, GError **error) AS_ERROR, AS_ERROR_FAILED, "No idea how to process files of this type"); -out: - g_free (basename); - return ret; + return FALSE; } /** @@ -477,29 +431,25 @@ out: static gboolean as_util_install (AsUtilPrivate *priv, gchar **values, GError **error) { - gboolean ret = TRUE; guint i; /* check args */ if (g_strv_length (values) < 1) { - ret = FALSE; g_set_error_literal (error, AS_ERROR, AS_ERROR_INVALID_ARGUMENTS, "Not enough arguments, " "expected filename(s)"); - goto out; + return FALSE; } /* for each item on the command line, install the xml files and * explode the icon files */ for (i = 0; values[i] != NULL; i++) { - ret = as_util_install_filename (values[i], error); - if (!ret) - goto out; + if (!as_util_install_filename (values[i], error)) + return FALSE; } -out: - return ret; + return TRUE; } @@ -509,55 +459,41 @@ out: static gboolean as_util_rmtree (const gchar *directory, GError **error) { + _cleanup_close_dir GDir *dir = NULL; const gchar *filename; - gboolean ret = TRUE; - gchar *src; - GDir *dir = NULL; - gint rc; /* try to open */ dir = g_dir_open (directory, 0, error); - if (dir == NULL) { - ret = FALSE; - goto out; - } + if (dir == NULL) + return FALSE; /* find each */ while ((filename = g_dir_read_name (dir))) { + _cleanup_free gchar *src = NULL; src = g_build_filename (directory, filename, NULL); - ret = g_file_test (src, G_FILE_TEST_IS_DIR); - if (ret) { - ret = as_util_rmtree (src, error); - if (!ret) - goto out; + if (g_file_test (src, G_FILE_TEST_IS_DIR)) { + if (!as_util_rmtree (src, error)) + return FALSE; } else { - rc = g_unlink (src); - if (rc != 0) { - ret = FALSE; + if (g_unlink (src) != 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to delete %s", src); - goto out; + return FALSE; } } - g_free (src); } /* remove directory */ - rc = g_remove (directory); - if (rc != 0) { - ret = FALSE; + if (g_remove (directory) != 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to delete %s", directory); - goto out; + return FALSE; } -out: - if (dir != NULL) - g_dir_close (dir); - return ret; + return TRUE; } /** @@ -566,21 +502,19 @@ out: static gboolean as_util_uninstall (AsUtilPrivate *priv, gchar **values, GError **error) { - GFile *file_xml = NULL; + _cleanup_free gchar *path_icons = NULL; + _cleanup_free gchar *path_xml = NULL; + _cleanup_unref_object GFile *file_xml = NULL; const gchar *destdir; - gboolean ret = TRUE; - gchar *path_icons = NULL; - gchar *path_xml = NULL; /* check args */ if (g_strv_length (values) != 1) { - ret = FALSE; g_set_error_literal (error, AS_ERROR, AS_ERROR_INVALID_ARGUMENTS, "Not enough arguments, " "expected appstream-id"); - goto out; + return FALSE; } /* remove XML file */ @@ -588,35 +522,27 @@ as_util_uninstall (AsUtilPrivate *priv, gchar **values, GError **error) path_xml = g_strdup_printf ("%s/usr/share/app-info/xmls/%s.xml.gz", destdir != NULL ? destdir : "", values[0]); if (!g_file_test (path_xml, G_FILE_TEST_EXISTS)) { - ret = FALSE; g_set_error (error, AS_ERROR, AS_ERROR_INVALID_ARGUMENTS, "AppStream file with that ID not found: %s", path_xml); - goto out; + return FALSE; } file_xml = g_file_new_for_path (path_xml); - ret = g_file_delete (file_xml, NULL, error); - if (!ret) { + if (!g_file_delete (file_xml, NULL, error)) { g_prefix_error (error, "Failed to remove %s: ", path_xml); - goto out; + return FALSE; } /* remove icons */ path_icons = g_strdup_printf ("%s/usr/share/app-info/icons/%s", destdir != NULL ? destdir : "", values[0]); if (g_file_test (path_icons, G_FILE_TEST_EXISTS)) { - ret = as_util_rmtree (path_icons, error); - if (!ret) - goto out; + if (!as_util_rmtree (path_icons, error)) + return FALSE; } -out: - g_free (path_icons); - g_free (path_xml); - if (file_xml != NULL) - g_object_unref (file_xml); - return ret; + return TRUE; } /** @@ -783,7 +709,6 @@ as_util_status_html_write_exec_summary (GPtrArray *apps, { AsApp *app; const gchar *project_groups[] = { "GNOME", "KDE", "XFCE", NULL }; - gboolean ret = TRUE; gdouble perc; guint cnt; guint i; @@ -800,12 +725,11 @@ as_util_status_html_write_exec_summary (GPtrArray *apps, total++; } if (total == 0) { - ret = FALSE; g_set_error_literal (error, AS_ERROR, AS_ERROR_INVALID_ARGUMENTS, "No desktop applications found"); - goto out; + return FALSE; } /* long descriptions */ @@ -873,8 +797,7 @@ as_util_status_html_write_exec_summary (GPtrArray *apps, total, perc); } g_string_append (html, "</ul>\n"); -out: - return ret; + return TRUE; } /** @@ -884,30 +807,27 @@ static gboolean as_util_status_html (AsUtilPrivate *priv, gchar **values, GError **error) { AsApp *app; - AsStore *store = NULL; - GFile *file = NULL; GPtrArray *apps = NULL; - GString *html = NULL; - gboolean ret = TRUE; + _cleanup_free_string GString *html = NULL; + _cleanup_unref_object AsStore *store = NULL; + _cleanup_unref_object GFile *file = NULL; guint i; /* check args */ if (g_strv_length (values) != 1) { - ret = FALSE; g_set_error_literal (error, AS_ERROR, AS_ERROR_INVALID_ARGUMENTS, "Not enough arguments, " "expected filename.xml.gz"); - goto out; + return FALSE; } /* load file */ store = as_store_new (); file = g_file_new_for_path (values[0]); - ret = as_store_from_file (store, file, NULL, NULL, error); - if (!ret) - goto out; + if (!as_store_from_file (store, file, NULL, NULL, error)) + return FALSE; apps = as_store_get_apps (store); /* create header */ @@ -925,9 +845,8 @@ as_util_status_html (AsUtilPrivate *priv, gchar **values, GError **error) /* summary section */ if (apps->len > 0) { - ret = as_util_status_html_write_exec_summary (apps, html, error); - if (!ret) - goto out; + if (!as_util_status_html_write_exec_summary (apps, html, error)) + return FALSE; } /* write applications */ @@ -949,17 +868,9 @@ as_util_status_html (AsUtilPrivate *priv, gchar **values, GError **error) g_string_append (html, "</html>\n"); /* save file */ - ret = g_file_set_contents ("./status.html", html->str, -1, error); - if (!ret) - goto out; -out: - if (html != NULL) - g_string_free (html, TRUE); - if (store != NULL) - g_object_unref (store); - if (file != NULL) - g_object_unref (file); - return ret; + if (!g_file_set_contents ("./status.html", html->str, -1, error)) + return FALSE; + return TRUE; } /** @@ -969,30 +880,27 @@ static gboolean as_util_non_package_yaml (AsUtilPrivate *priv, gchar **values, GError **error) { AsApp *app; - AsStore *store = NULL; - GFile *file = NULL; GPtrArray *apps = NULL; - GString *yaml = NULL; - gboolean ret = TRUE; + _cleanup_free_string GString *yaml = NULL; + _cleanup_unref_object AsStore *store = NULL; + _cleanup_unref_object GFile *file = NULL; guint i; /* check args */ if (g_strv_length (values) != 1) { - ret = FALSE; g_set_error_literal (error, AS_ERROR, AS_ERROR_INVALID_ARGUMENTS, "Not enough arguments, " "expected filename.xml.gz"); - goto out; + return FALSE; } /* load file */ store = as_store_new (); file = g_file_new_for_path (values[0]); - ret = as_store_from_file (store, file, NULL, NULL, error); - if (!ret) - goto out; + if (!as_store_from_file (store, file, NULL, NULL, error)) + return FALSE; apps = as_store_get_apps (store); /* write applications */ @@ -1010,17 +918,9 @@ as_util_non_package_yaml (AsUtilPrivate *priv, gchar **values, GError **error) } /* save file */ - ret = g_file_set_contents ("./applications-to-import.yaml", yaml->str, -1, error); - if (!ret) - goto out; -out: - if (yaml != NULL) - g_string_free (yaml, TRUE); - if (store != NULL) - g_object_unref (store); - if (file != NULL) - g_object_unref (file); - return ret; + if (!g_file_set_contents ("./applications-to-import.yaml", yaml->str, -1, error)) + return FALSE; + return TRUE; } /** @@ -1029,56 +929,46 @@ out: static gboolean as_util_validate (AsUtilPrivate *priv, gchar **values, GError **error) { - AsApp *app = NULL; AsProblemKind kind; AsProblem *problem; - GPtrArray *probs = NULL; - gboolean ret = TRUE; + _cleanup_unref_object AsApp *app = NULL; + _cleanup_unref_ptrarray GPtrArray *probs = NULL; guint i; /* check args */ if (g_strv_length (values) != 1) { - ret = FALSE; g_set_error_literal (error, AS_ERROR, AS_ERROR_INVALID_ARGUMENTS, "Not enough arguments, " "expected example.appdata.xml"); - goto out; + return FALSE; } /* load file */ app = as_app_new (); - ret = as_app_parse_file (app, values[0], AS_APP_PARSE_FLAG_NONE, error); - if (!ret) - goto out; + if (!as_app_parse_file (app, values[0], AS_APP_PARSE_FLAG_NONE, error)) + return FALSE; probs = as_app_validate (app, AS_APP_VALIDATE_FLAG_NONE, error); - if (probs == NULL) { - ret = FALSE; - goto out; + if (probs == NULL) + return FALSE; + for (i = 0; i < probs->len; i++) { + problem = g_ptr_array_index (probs, i); + kind = as_problem_get_kind (problem); + g_print ("%s\t%s\n", + as_problem_kind_to_string (kind), + as_problem_get_message (problem)); } if (probs->len == 0) { g_print ("%s\n", _("File validated successfully!")); } else { - ret = FALSE; g_set_error_literal (error, AS_ERROR, AS_ERROR_INVALID_ARGUMENTS, _("Validation failed")); + return FALSE; } - for (i = 0; i < probs->len; i++) { - problem = g_ptr_array_index (probs, i); - kind = as_problem_get_kind (problem); - g_print ("%s\t%s\n", - as_problem_kind_to_string (kind), - as_problem_get_message (problem)); - } -out: - if (probs != NULL) - g_ptr_array_unref (probs); - if (app != NULL) - g_object_unref (app); - return ret; + return TRUE; } /** @@ -1097,10 +987,10 @@ int main (int argc, char *argv[]) { AsUtilPrivate *priv; + _cleanup_free gchar *cmd_descriptions = NULL; gboolean ret; gboolean verbose = FALSE; gboolean version = FALSE; - gchar *cmd_descriptions = NULL; GError *error = NULL; guint retval = 1; const GOptionEntry options[] = { @@ -1223,6 +1113,5 @@ out: g_option_context_free (priv->context); g_free (priv); } - g_free (cmd_descriptions); return retval; } diff --git a/libappstream-glib/Makefile.am b/libappstream-glib/Makefile.am index e73d1a1..09d3bc1 100644 --- a/libappstream-glib/Makefile.am +++ b/libappstream-glib/Makefile.am @@ -72,6 +72,7 @@ libappstream_glib_la_SOURCES = \ as-app.c \ as-app-private.h \ as-app-validate.c \ + as-cleanup.h \ as-enums.c \ as-image.c \ as-image-private.h \ diff --git a/libappstream-glib/as-app-validate.c b/libappstream-glib/as-app-validate.c index 67e2516..53a94e5 100644 --- a/libappstream-glib/as-app-validate.c +++ b/libappstream-glib/as-app-validate.c @@ -27,6 +27,7 @@ #include <string.h> #include "as-app-private.h" +#include "as-cleanup.h" #include "as-node-private.h" #include "as-problem.h" #include "as-utils.h" @@ -229,17 +230,14 @@ as_app_validate_description (const gchar *xml, { GNode *l; GNode *l2; - GNode *node; - gboolean ret = TRUE; + _cleanup_unref_node GNode *node; /* parse xml */ node = as_node_from_xml (xml, -1, AS_NODE_FROM_XML_FLAG_NONE, error); - if (node == NULL) { - ret = FALSE; - goto out; - } + if (node == NULL) + return FALSE; helper->number_paragraphs = 0; helper->previous_para_was_short = FALSE; for (l = node->children; l != NULL; l = l->next) { @@ -260,25 +258,23 @@ as_app_validate_description (const gchar *xml, helper); } else { /* only <li> supported */ - ret = FALSE; g_set_error (error, AS_APP_ERROR, AS_APP_ERROR_FAILED, "invalid markup: <%s> follows <%s>", as_node_get_name (l2), as_node_get_name (l)); - goto out; + return FALSE; } } } else { /* only <p>, <ol> and <ul> supported */ - ret = FALSE; g_set_error (error, AS_APP_ERROR, AS_APP_ERROR_FAILED, "invalid markup: tag <%s> invalid here", as_node_get_name (l)); - goto out; + return FALSE; } } @@ -298,10 +294,7 @@ as_app_validate_description (const gchar *xml, AS_PROBLEM_KIND_STYLE_INCORRECT, "Too many <p> tags for a good description"); } -out: - if (node != NULL) - as_node_unref (node); - return ret; + return TRUE; } /** @@ -328,14 +321,12 @@ as_app_validate_image_url_already_exists (AsAppValidateHelper *helper, static gboolean ai_app_validate_image_check (AsImage *im, AsAppValidateHelper *helper) { - GdkPixbuf *pixbuf = NULL; - GError *error = NULL; - GInputStream *stream = NULL; - SoupMessage *msg = NULL; - SoupURI *base_uri = NULL; + _cleanup_unref_object GdkPixbuf *pixbuf = NULL; + _cleanup_unref_object GInputStream *stream = NULL; + _cleanup_unref_object SoupMessage *msg = NULL; + _cleanup_unref_uri SoupURI *base_uri = NULL; const gchar *url; gboolean require_correct_aspect_ratio = FALSE; - gboolean ret = TRUE; gdouble desired_aspect = 1.777777778; gdouble screenshot_aspect; gint status_code; @@ -361,42 +352,39 @@ ai_app_validate_image_check (AsImage *im, AsAppValidateHelper *helper) /* have we got network access */ if ((helper->flags & AS_APP_VALIDATE_FLAG_NO_NETWORK) > 0) - goto out; + return TRUE; /* GET file */ url = as_image_get_url (im); g_debug ("checking %s", url); base_uri = soup_uri_new (url); if (base_uri == NULL) { - ret = FALSE; ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_URL_NOT_FOUND, "<screenshot> url not valid"); - goto out; + return FALSE; } msg = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri); if (msg == NULL) { g_warning ("Failed to setup message"); - goto out; + return FALSE; } /* send sync */ status_code = soup_session_send_message (helper->session, msg); if (status_code != SOUP_STATUS_OK) { - ret = FALSE; ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_URL_NOT_FOUND, "<screenshot> url not found"); - goto out; + return FALSE; } /* check if it's a zero sized file */ if (msg->response_body->length == 0) { - ret = FALSE; ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_FILE_INVALID, "<screenshot> url is a zero length file"); - goto out; + return FALSE; } /* create a buffer with the data */ @@ -404,21 +392,19 @@ ai_app_validate_image_check (AsImage *im, AsAppValidateHelper *helper) msg->response_body->length, NULL); if (stream == NULL) { - ret = FALSE; ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_URL_NOT_FOUND, "<screenshot> failed to load data"); - goto out; + return FALSE; } /* load the image */ - pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &error); + pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, NULL); if (pixbuf == NULL) { - ret = FALSE; ai_app_validate_add (helper->probs, AS_PROBLEM_KIND_FILE_INVALID, "<screenshot> failed to load image"); - goto out; + return FALSE; } /* check width matches */ @@ -472,16 +458,7 @@ ai_app_validate_image_check (AsImage *im, AsAppValidateHelper *helper) "<screenshot> aspect ratio was not 16:9"); } } -out: - if (base_uri != NULL) - soup_uri_free (base_uri); - if (msg != NULL) - g_object_unref (msg); - if (stream != NULL) - g_object_unref (stream); - if (pixbuf != NULL) - g_object_unref (pixbuf); - return ret; + return TRUE; } /** @@ -513,9 +490,8 @@ as_app_validate_image (AsImage *im, AsAppValidateHelper *helper) /* validate the URL */ ret = ai_app_validate_image_check (im, helper); - if (ret) { + if (ret) g_ptr_array_add (helper->screenshot_urls, g_strdup (url)); - } } /** @@ -601,7 +577,6 @@ static gboolean as_app_validate_release (AsRelease *release, AsAppValidateHelper *helper, GError **error) { const gchar *tmp; - gboolean ret = TRUE; guint64 timestamp; guint number_para_max = 2; guint number_para_min = 1; @@ -647,16 +622,14 @@ as_app_validate_release (AsRelease *release, AsAppValidateHelper *helper, GError "<release> description should be " "prose and not contain hyperlinks"); } - ret = as_app_validate_description (tmp, - helper, - number_para_min, - number_para_max, - error); - if (!ret) - goto out; - } -out: - return ret; + if (!as_app_validate_description (tmp, + helper, + number_para_min, + number_para_max, + error)) + return FALSE; + } + return TRUE; } /** @@ -667,12 +640,11 @@ as_app_validate_releases (AsApp *app, AsAppValidateHelper *helper, GError **erro { AsRelease *release; GPtrArray *releases; - gboolean ret = TRUE; guint i; /* only for AppData */ if (as_app_get_source_kind (app) != AS_APP_SOURCE_KIND_APPDATA) - goto out; + return TRUE; releases = as_app_get_releases (app); if (releases->len > 10) { @@ -682,12 +654,10 @@ as_app_validate_releases (AsApp *app, AsAppValidateHelper *helper, GError **erro } for (i = 0; i < releases->len; i++) { release = g_ptr_array_index (releases, i); - ret = as_app_validate_release (release, helper, error); - if (!ret) - goto out; + if (!as_app_validate_release (release, helper, error)) + return FALSE; } -out: - return ret; + return TRUE; } /** @@ -696,25 +666,21 @@ out: static gboolean as_app_validate_setup_networking (AsAppValidateHelper *helper, GError **error) { - gboolean ret = TRUE; - helper->session = soup_session_sync_new_with_options (SOUP_SESSION_USER_AGENT, "libappstream-glib", SOUP_SESSION_TIMEOUT, 5000, NULL); if (helper->session == NULL) { - ret = FALSE; g_set_error_literal (error, AS_APP_ERROR, AS_APP_ERROR_FAILED, "Failed to set up networking"); - goto out; + return FALSE; } soup_session_add_feature_by_type (helper->session, SOUP_TYPE_PROXY_RESOLVER_DEFAULT); -out: - return ret; + return TRUE; } /** @@ -723,8 +689,7 @@ out: static gboolean as_app_validate_license (const gchar *license_text, GError **error) { - gboolean ret = TRUE; - gchar **licenses; + _cleanup_free_strv gchar **licenses = NULL; guint i; licenses = as_utils_spdx_license_tokenize (license_text); @@ -732,18 +697,15 @@ as_app_validate_license (const gchar *license_text, GError **error) if (g_str_has_prefix (licenses[i], "#")) continue; if (!as_utils_is_spdx_license_id (licenses[i])) { - ret = FALSE; g_set_error (error, AS_APP_ERROR, AS_APP_ERROR_FAILED, "SPDX ID '%s' unknown", licenses[i]); - goto out; + return FALSE; } } -out: - g_strfreev (licenses); - return ret; + return TRUE; } /** @@ -765,9 +727,9 @@ as_app_validate (AsApp *app, AsAppValidateFlags flags, GError **error) AsAppValidateHelper helper; GError *error_local = NULL; GHashTable *urls; - GList *keys; GList *l; GPtrArray *probs = NULL; + _cleanup_free_list GList *keys = NULL; const gchar *description; const gchar *id_full; const gchar *key; @@ -963,7 +925,6 @@ as_app_validate (AsApp *app, AsAppValidateFlags flags, GError **error) "<url> does not start with 'http://'"); } } - g_list_free (keys); /* screenshots */ as_app_validate_screenshots (app, &helper); diff --git a/libappstream-glib/as-app.c b/libappstream-glib/as-app.c index a7f9df7..21cbf08 100644 --- a/libappstream-glib/as-app.c +++ b/libappstream-glib/as-app.c @@ -38,6 +38,7 @@ #include <string.h> #include "as-app-private.h" +#include "as-cleanup.h" #include "as-enums.h" #include "as-node-private.h" #include "as-provide-private.h" @@ -1502,7 +1503,7 @@ static void as_app_subsume_dict (GHashTable *dest, GHashTable *src, gboolean overwrite) { GList *l; - GList *keys; + _cleanup_free_list GList *keys; const gchar *tmp; const gchar *key; const gchar *value; @@ -1518,7 +1519,6 @@ as_app_subsume_dict (GHashTable *dest, GHashTable *src, gboolean overwrite) value = g_hash_table_lookup (src, key); g_hash_table_insert (dest, g_strdup (key), g_strdup (value)); } - g_list_free (keys); } /** @@ -1536,7 +1536,7 @@ as_app_subsume_private (AsApp *app, AsApp *donor, AsAppSubsumeFlags flags) guint i; gint percentage; GList *l; - GList *keys; + _cleanup_free_list GList *keys; overwrite = (flags & AS_APP_SUBSUME_FLAG_NO_OVERWRITE) == 0; @@ -1570,7 +1570,6 @@ as_app_subsume_private (AsApp *app, AsApp *donor, AsAppSubsumeFlags flags) percentage = GPOINTER_TO_INT (g_hash_table_lookup (priv->languages, key)); as_app_add_language (app, percentage, key, -1); } - g_list_free (keys); /* dictionaries */ as_app_subsume_dict (papp->names, priv->names, overwrite); @@ -1646,8 +1645,8 @@ static void as_app_node_insert_languages (AsApp *app, GNode *parent) { GNode *node_tmp; - GList *langs; GList *l; + _cleanup_free_list GList *langs; const gchar *locale; gchar tmp[4]; gint percentage; @@ -1667,7 +1666,6 @@ as_app_node_insert_languages (AsApp *app, GNode *parent) NULL); } } - g_list_free (langs); } /** @@ -1885,15 +1883,9 @@ static gboolean as_app_node_parse_child (AsApp *app, GNode *n, GError **error) { AsAppPrivate *priv = GET_PRIVATE (app); - AsRelease *r; - AsScreenshot *ss; - GHashTable *unwrapped; GNode *c; - GString *xml; const gchar *tmp; - gboolean ret = TRUE; gchar *taken; - guint percent; switch (as_node_get_tag (n)) { @@ -1941,13 +1933,11 @@ as_app_node_parse_child (AsApp *app, GNode *n, GError **error) /* unwrap appdata inline */ if (priv->source_kind == AS_APP_SOURCE_KIND_APPDATA) { + _cleanup_unref_hashtable GHashTable *unwrapped; unwrapped = as_node_get_localized_unwrap (n, error); - if (unwrapped == NULL) { - ret = FALSE; - goto out; - } + if (unwrapped == NULL) + return FALSE; as_app_subsume_dict (priv->descriptions, unwrapped, FALSE); - g_hash_table_unref (unwrapped); break; } @@ -1958,12 +1948,12 @@ as_app_node_parse_child (AsApp *app, GNode *n, GError **error) as_node_get_data (n), -1); } else { + _cleanup_free_string GString *xml; xml = as_node_to_xml (n->children, AS_NODE_TO_XML_FLAG_INCLUDE_SIBLINGS); as_app_set_description (app, as_node_get_attribute (n, "xml:lang"), xml->str, xml->len); - g_string_free (xml, TRUE); } break; @@ -2055,16 +2045,13 @@ as_app_node_parse_child (AsApp *app, GNode *n, GError **error) case AS_TAG_SCREENSHOTS: g_ptr_array_set_size (priv->screenshots, 0); for (c = n->children; c != NULL; c = c->next) { + _cleanup_unref_object AsScreenshot *ss = NULL; if (as_node_get_tag (c) != AS_TAG_SCREENSHOT) continue; ss = as_screenshot_new (); - ret = as_screenshot_node_parse (ss, c, error); - if (!ret) { - g_object_unref (ss); - goto out; - } + if (!as_screenshot_node_parse (ss, c, error)) + return FALSE; as_app_add_screenshot (app, ss); - g_object_unref (ss); } break; @@ -2072,16 +2059,13 @@ as_app_node_parse_child (AsApp *app, GNode *n, GError **error) case AS_TAG_RELEASES: g_ptr_array_set_size (priv->releases, 0); for (c = n->children; c != NULL; c = c->next) { + _cleanup_unref_object AsRelease *r = NULL; if (as_node_get_tag (c) != AS_TAG_RELEASE) continue; r = as_release_new (); - ret = as_release_node_parse (r, c, error); - if (!ret) { - g_object_unref (r); - goto out; - } + if (!as_release_node_parse (r, c, error)) + return FALSE; as_app_add_release (app, r); - g_object_unref (r); } break; @@ -2089,15 +2073,11 @@ as_app_node_parse_child (AsApp *app, GNode *n, GError **error) case AS_TAG_PROVIDES: g_ptr_array_set_size (priv->provides, 0); for (c = n->children; c != NULL; c = c->next) { - AsProvide *p; + _cleanup_unref_object AsProvide *p; p = as_provide_new (); - ret = as_provide_node_parse (p, c, error); - if (!ret) { - g_object_unref (p); - goto out; - } + if (!as_provide_node_parse (p, c, error)) + return FALSE; as_app_add_provide (app, p); - g_object_unref (p); } break; @@ -2105,6 +2085,7 @@ as_app_node_parse_child (AsApp *app, GNode *n, GError **error) case AS_TAG_LANGUAGES: g_hash_table_remove_all (priv->languages); for (c = n->children; c != NULL; c = c->next) { + guint percent; if (as_node_get_tag (c) != AS_TAG_LANG) continue; percent = as_node_get_attribute_as_int (c, "percentage"); @@ -2134,8 +2115,7 @@ as_app_node_parse_child (AsApp *app, GNode *n, GError **error) default: break; } -out: - return ret; + return TRUE; } /** @@ -2156,7 +2136,6 @@ as_app_node_parse (AsApp *app, GNode *node, GError **error) AsAppPrivate *priv = GET_PRIVATE (app); GNode *n; const gchar *tmp; - gboolean ret = TRUE; guint prio; /* new style */ @@ -2174,12 +2153,10 @@ as_app_node_parse (AsApp *app, GNode *node, GError **error) g_ptr_array_set_size (priv->pkgnames, 0); g_ptr_array_set_size (priv->architectures, 0); for (n = node->children; n != NULL; n = n->next) { - ret = as_app_node_parse_child (app, n, error); - if (!ret) - goto out; + if (!as_app_node_parse_child (app, n, error)) + return FALSE; } -out: - return ret; + return TRUE; } #if !GLIB_CHECK_VERSION(2,39,1) @@ -2365,13 +2342,12 @@ as_app_desktop_key_get_locale (const gchar *key) tmp1 = g_strstr_len (key, -1, "["); if (tmp1 == NULL) - goto out; + return NULL; tmp2 = g_strstr_len (tmp1, -1, "]"); if (tmp1 == NULL) - goto out; + return NULL; locale = g_strdup (tmp1 + 1); locale[tmp2 - tmp1 - 1] = '\0'; -out: return locale; } @@ -2384,52 +2360,39 @@ as_app_infer_file_key (AsApp *app, const gchar *key, GError **error) { - gboolean ret = TRUE; - gchar *tmp = NULL; + _cleanup_free gchar *tmp = NULL; if (g_strcmp0 (key, "X-GNOME-UsesNotifications") == 0) { as_app_add_metadata (app, "X-Kudo-UsesNotifications", "", -1); - goto out; - } - if (g_strcmp0 (key, "X-GNOME-Bugzilla-Product") == 0) { + } else if (g_strcmp0 (key, "X-GNOME-Bugzilla-Product") == 0) { as_app_set_project_group (app, "GNOME", -1); - goto out; - } - if (g_strcmp0 (key, "X-MATE-Bugzilla-Product") == 0) { + } else if (g_strcmp0 (key, "X-MATE-Bugzilla-Product") == 0) { as_app_set_project_group (app, "MATE", -1); - goto out; - } - if (g_strcmp0 (key, "X-KDE-StartupNotify") == 0) { + } else if (g_strcmp0 (key, "X-KDE-StartupNotify") == 0) { as_app_set_project_group (app, "KDE", -1); - goto out; - } - if (g_strcmp0 (key, "X-DocPath") == 0) { + } else if (g_strcmp0 (key, "X-DocPath") == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (g_str_has_prefix (tmp, "http://userbase.kde.org/")) as_app_set_project_group (app, "KDE", -1); - goto out; - } /* Exec */ - if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_EXEC) == 0) { + } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_EXEC) == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (g_str_has_prefix (tmp, "xfce4-")) as_app_set_project_group (app, "XFCE", -1); - goto out; } -out: - g_free (tmp); - return ret; + + return TRUE; } /** @@ -2441,22 +2404,18 @@ as_app_parse_file_key (AsApp *app, const gchar *key, GError **error) { - - gboolean ret = TRUE; - gchar **list = NULL; + _cleanup_free gchar *locale = NULL; + _cleanup_free gchar *tmp = NULL; + _cleanup_free_strv gchar **list = NULL; gchar *dot = NULL; - gchar *locale = NULL; - gchar *tmp = NULL; guint i; /* NoDisplay */ if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY) == 0) { as_app_add_metadata (app, "NoDisplay", "", -1); - goto out; - } /* Type */ - if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_TYPE) == 0) { + } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_TYPE) == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, @@ -2466,14 +2425,11 @@ as_app_parse_file_key (AsApp *app, AS_APP_ERROR, AS_APP_ERROR_INVALID_TYPE, "not an application"); - ret = FALSE; - goto out; + return FALSE; } - goto out; - } /* Icon */ - if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_ICON) == 0) { + } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_ICON) == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, @@ -2488,11 +2444,9 @@ as_app_parse_file_key (AsApp *app, as_app_set_icon_kind (app, AS_ICON_KIND_STOCK); } } - goto out; - } /* Categories */ - if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_CATEGORIES) == 0) { + } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_CATEGORIES) == 0) { list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, @@ -2504,13 +2458,12 @@ as_app_parse_file_key (AsApp *app, if (fnmatch ("X-*-Settings-Panel", list[i], 0) == 0 || fnmatch ("X-*-Settings", list[i], 0) == 0 || fnmatch ("X-*-SettingsDialog", list[i], 0) == 0) { - ret = FALSE; g_set_error (error, AS_APP_ERROR, AS_APP_ERROR_INVALID_TYPE, "category %s is blacklisted", list[i]); - goto out; + return FALSE; } /* ignore some useless keys */ @@ -2526,41 +2479,33 @@ as_app_parse_file_key (AsApp *app, continue; as_app_add_category (app, list[i], -1); } - goto out; - } - if (g_strcmp0 (key, "Keywords") == 0) { + } else if (g_strcmp0 (key, "Keywords") == 0) { list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL, NULL); for (i = 0; list[i] != NULL; i++) as_app_add_keyword (app, list[i], -1); - goto out; - } - if (g_strcmp0 (key, "MimeType") == 0) { + } else if (g_strcmp0 (key, "MimeType") == 0) { list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL, NULL); for (i = 0; list[i] != NULL; i++) as_app_add_mimetype (app, list[i], -1); - goto out; - } - if (g_strcmp0 (key, "X-AppInstall-Package") == 0) { + } else if (g_strcmp0 (key, "X-AppInstall-Package") == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_add_pkgname (app, tmp, -1); - goto out; - } /* OnlyShowIn */ - if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN) == 0) { + } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN) == 0) { /* if an app has only one entry, it's that desktop */ list = g_key_file_get_string_list (kf, G_KEY_FILE_DESKTOP_GROUP, @@ -2568,22 +2513,18 @@ as_app_parse_file_key (AsApp *app, NULL, NULL); if (g_strv_length (list) == 1) as_app_set_project_group (app, list[0], -1); - goto out; - } /* Name */ - if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_NAME) == 0) { + } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_NAME) == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_name (app, "C", tmp, -1); - goto out; - } /* Name[] */ - if (g_str_has_prefix (key, G_KEY_FILE_DESKTOP_KEY_NAME)) { + } else if (g_str_has_prefix (key, G_KEY_FILE_DESKTOP_KEY_NAME)) { locale = as_app_desktop_key_get_locale (key); tmp = g_key_file_get_locale_string (kf, G_KEY_FILE_DESKTOP_GROUP, @@ -2592,22 +2533,18 @@ as_app_parse_file_key (AsApp *app, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_name (app, locale, tmp, -1); - goto out; - } /* Comment */ - if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_COMMENT) == 0) { + } else if (g_strcmp0 (key, G_KEY_FILE_DESKTOP_KEY_COMMENT) == 0) { tmp = g_key_file_get_string (kf, G_KEY_FILE_DESKTOP_GROUP, key, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_comment (app, "C", tmp, -1); - goto out; - } /* Comment[] */ - if (g_str_has_prefix (key, G_KEY_FILE_DESKTOP_KEY_COMMENT)) { + } else if (g_str_has_prefix (key, G_KEY_FILE_DESKTOP_KEY_COMMENT)) { locale = as_app_desktop_key_get_locale (key); tmp = g_key_file_get_locale_string (kf, G_KEY_FILE_DESKTOP_GROUP, @@ -2616,13 +2553,8 @@ as_app_parse_file_key (AsApp *app, NULL); if (tmp != NULL && tmp[0] != '\0') as_app_set_comment (app, locale, tmp, -1); - goto out; } -out: - g_free (locale); - g_free (tmp); - g_strfreev (list); - return ret; + return TRUE; } /** @@ -2635,10 +2567,9 @@ as_app_parse_desktop_file (AsApp *app, GError **error) { GKeyFileFlags kf_flags = G_KEY_FILE_KEEP_TRANSLATIONS; - GKeyFile *kf; - gboolean ret; - gchar *app_id = NULL; - gchar **keys = NULL; + _cleanup_free gchar *app_id = NULL; + _cleanup_unref_keyfile GKeyFile *kf = NULL; + _cleanup_free_strv gchar **keys = NULL; gchar *tmp; guint i; @@ -2646,9 +2577,8 @@ as_app_parse_desktop_file (AsApp *app, kf = g_key_file_new (); if (flags & AS_APP_PARSE_FLAG_KEEP_COMMENTS) kf_flags |= G_KEY_FILE_KEEP_COMMENTS; - ret = g_key_file_load_from_file (kf, desktop_file, kf_flags, error); - if (!ret) - goto out; + if (!g_key_file_load_from_file (kf, desktop_file, kf_flags, error)) + return FALSE; /* create app */ app_id = g_path_get_basename (desktop_file); @@ -2663,36 +2593,28 @@ as_app_parse_desktop_file (AsApp *app, /* look at all the keys */ keys = g_key_file_get_keys (kf, G_KEY_FILE_DESKTOP_GROUP, NULL, error); - if (keys == NULL) { - ret = FALSE; - goto out; - } + if (keys == NULL) + return FALSE; for (i = 0; keys[i] != NULL; i++) { - ret = as_app_parse_file_key (app, kf, keys[i], error); - if (!ret) - goto out; + if (!as_app_parse_file_key (app, kf, keys[i], error)) + return FALSE; if ((flags & AS_APP_PARSE_FLAG_USE_HEURISTICS) > 0) { - ret = as_app_infer_file_key (app, kf, keys[i], error); - if (!ret) - goto out; + if (!as_app_infer_file_key (app, kf, keys[i], error)) + return FALSE; } } /* all applications require icons */ if (as_app_get_icon (app) == NULL) { - ret = FALSE; g_set_error (error, AS_APP_ERROR, AS_APP_ERROR_INVALID_TYPE, "Application %s has no icon", app_id); - goto out; + return FALSE; } -out: - g_free (app_id); - g_key_file_unref (kf); - g_strfreev (keys); - return ret; + + return TRUE; } /** @@ -2702,29 +2624,17 @@ static gboolean as_app_parse_appdata_unintltoolize_cb (GNode *node, gpointer data) { const gchar *name; - name = as_node_get_name (node); - if (g_strcmp0 (name, "_name") == 0) { + if (g_strcmp0 (name, "_name") == 0) as_node_set_name (node, "name"); - goto out; - } - if (g_strcmp0 (name, "_summary") == 0) { + else if (g_strcmp0 (name, "_summary") == 0) as_node_set_name (node, "summary"); - goto out; - } - if (g_strcmp0 (name, "_caption") == 0) { + else if (g_strcmp0 (name, "_caption") == 0) as_node_set_name (node, "caption"); - goto out; - } - if (g_strcmp0 (name, "_p") == 0) { + else if (g_strcmp0 (name, "_p") == 0) as_node_set_name (node, "p"); - goto out; - } - if (g_strcmp0 (name, "_li") == 0) { + else if (g_strcmp0 (name, "_li") == 0) as_node_set_name (node, "li"); - goto out; - } -out: return FALSE; } @@ -2741,17 +2651,15 @@ as_app_parse_appdata_file (AsApp *app, AsNodeFromXmlFlags from_xml_flags = AS_NODE_FROM_XML_FLAG_NONE; GNode *l; GNode *node; - GNode *root = NULL; - gboolean ret = TRUE; gboolean seen_application = FALSE; - gchar *data = NULL; + _cleanup_free gchar *data = NULL; + _cleanup_unref_node GNode *root = NULL; gchar *tmp; gsize len; /* open file */ - ret = g_file_get_contents (filename, &data, &len, error); - if (!ret) - goto out; + if (!g_file_get_contents (filename, &data, &len, error)) + return FALSE; /* validate */ tmp = g_strstr_len (data, len, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); @@ -2771,10 +2679,8 @@ as_app_parse_appdata_file (AsApp *app, root = as_node_from_xml (data, len, from_xml_flags, error); - if (root == NULL) { - ret = FALSE; - goto out; - } + if (root == NULL) + return FALSE; /* make the <_summary> tags into <summary> */ if (flags & AS_APP_PARSE_FLAG_CONVERT_TRANSLATABLE) { @@ -2790,13 +2696,12 @@ as_app_parse_appdata_file (AsApp *app, if (node == NULL) node = as_node_find (root, "component"); if (node == NULL) { - ret = FALSE; g_set_error (error, AS_APP_ERROR, AS_APP_ERROR_INVALID_TYPE, "%s has an unrecognised contents", filename); - goto out; + return FALSE; } for (l = node->children; l != NULL; l = l->next) { if (g_strcmp0 (as_node_get_name (l), "licence") == 0) { @@ -2810,14 +2715,9 @@ as_app_parse_appdata_file (AsApp *app, seen_application = TRUE; } } - ret = as_app_node_parse (app, node, error); - if (!ret) - goto out; -out: - if (root != NULL) - as_node_unref (root); - g_free (data); - return ret; + if (!as_app_node_parse (app, node, error)) + return FALSE; + return TRUE; } /** @@ -2840,7 +2740,6 @@ as_app_parse_file (AsApp *app, GError **error) { AsAppPrivate *priv = GET_PRIVATE (app); - gboolean ret = FALSE; /* autodetect */ if (priv->source_kind == AS_APP_SOURCE_KIND_UNKNOWN) { @@ -2857,17 +2756,19 @@ as_app_parse_file (AsApp *app, AS_APP_ERROR_INVALID_TYPE, "%s has an unrecognised extension", filename); - goto out; + return FALSE; } } /* parse */ switch (priv->source_kind) { case AS_APP_SOURCE_KIND_DESKTOP: - ret = as_app_parse_desktop_file (app, filename, flags, error); + if (!as_app_parse_desktop_file (app, filename, flags, error)) + return FALSE; break; case AS_APP_SOURCE_KIND_APPDATA: - ret = as_app_parse_appdata_file (app, filename, flags, error); + if (!as_app_parse_appdata_file (app, filename, flags, error)) + return FALSE; break; default: g_set_error (error, @@ -2875,10 +2776,10 @@ as_app_parse_file (AsApp *app, AS_APP_ERROR_INVALID_TYPE, "%s has an unhandled type", filename); + return FALSE; break; } -out: - return ret; + return TRUE; } /** diff --git a/libappstream-glib/as-cleanup.h b/libappstream-glib/as-cleanup.h new file mode 100644 index 0000000..a635d03 --- /dev/null +++ b/libappstream-glib/as-cleanup.h @@ -0,0 +1,97 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Colin Walters <walters@verbum.org>. + * Copyright (C) 2014 Richard Hughes <richard@hughsie.com> + * + * Licensed under the GNU Lesser General Public License Version 2.1 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __AS_CLEANUP_H__ +#define __AS_CLEANUP_H__ + +#include <gio/gio.h> +#include <libsoup/soup.h> + +#include "as-node.h" + +G_BEGIN_DECLS + +#define GS_DEFINE_CLEANUP_FUNCTION(Type, name, func) \ + static inline void name (void *v) \ + { \ + func (*(Type*)v); \ + } + +#define GS_DEFINE_CLEANUP_FUNCTION0(Type, name, func) \ + static inline void name (void *v) \ + { \ + if (*(Type*)v) \ + func (*(Type*)v); \ + } + +#define GS_DEFINE_CLEANUP_FUNCTIONt(Type, name, func) \ + static inline void name (void *v) \ + { \ + if (*(Type*)v) \ + func (*(Type*)v, TRUE); \ + } + +GS_DEFINE_CLEANUP_FUNCTION0(GArray*, gs_local_array_unref, g_array_unref) +GS_DEFINE_CLEANUP_FUNCTION0(GBytes*, gs_local_bytes_unref, g_bytes_unref) +GS_DEFINE_CLEANUP_FUNCTION0(GChecksum*, gs_local_checksum_free, g_checksum_free) +GS_DEFINE_CLEANUP_FUNCTION0(GDir*, gs_local_dir_close, g_dir_close) +GS_DEFINE_CLEANUP_FUNCTION0(GError*, gs_local_free_error, g_error_free) +GS_DEFINE_CLEANUP_FUNCTION0(GHashTable*, gs_local_hashtable_unref, g_hash_table_unref) +GS_DEFINE_CLEANUP_FUNCTION0(GKeyFile*, gs_local_keyfile_unref, g_key_file_unref) +GS_DEFINE_CLEANUP_FUNCTION0(GMarkupParseContext*, gs_local_markup_parse_context_unref, g_markup_parse_context_unref) +GS_DEFINE_CLEANUP_FUNCTION0(GNode*, gs_local_node_unref, as_node_unref) +GS_DEFINE_CLEANUP_FUNCTION0(GObject*, gs_local_obj_unref, g_object_unref) +GS_DEFINE_CLEANUP_FUNCTION0(GPtrArray*, gs_local_ptrarray_unref, g_ptr_array_unref) +GS_DEFINE_CLEANUP_FUNCTION0(GTimer*, gs_local_destroy_timer, g_timer_destroy) +GS_DEFINE_CLEANUP_FUNCTION0(GVariantBuilder*, gs_local_variant_builder_unref, g_variant_builder_unref) +GS_DEFINE_CLEANUP_FUNCTION0(GVariant*, gs_local_variant_unref, g_variant_unref) +GS_DEFINE_CLEANUP_FUNCTION0(GVariantIter*, gs_local_variant_iter_free, g_variant_iter_free) +GS_DEFINE_CLEANUP_FUNCTION0(SoupURI*, gs_local_uri_unref, soup_uri_free) + +GS_DEFINE_CLEANUP_FUNCTIONt(GString*, gs_local_free_string, g_string_free) + +GS_DEFINE_CLEANUP_FUNCTION(char**, gs_local_strfreev, g_strfreev) +GS_DEFINE_CLEANUP_FUNCTION(GList*, gs_local_free_list, g_list_free) +GS_DEFINE_CLEANUP_FUNCTION(void*, gs_local_free, g_free) + +#define _cleanup_close_dir __attribute__ ((cleanup(gs_local_dir_close))) +#define _cleanup_destroy_timer __attribute__ ((cleanup(gs_local_destroy_timer))) +#define _cleanup_free __attribute__ ((cleanup(gs_local_free))) +#define _cleanup_free_checksum __attribute__ ((cleanup(gs_local_checksum_free))) +#define _cleanup_free_error __attribute__ ((cleanup(gs_local_free_error))) +#define _cleanup_free_list __attribute__ ((cleanup(gs_local_free_list))) +#define _cleanup_free_string __attribute__ ((cleanup(gs_local_free_string))) +#define _cleanup_free_strv __attribute__ ((cleanup(gs_local_strfreev))) +#define _cleanup_unref_array __attribute__ ((cleanup(gs_local_array_unref))) +#define _cleanup_unref_bytes __attribute__ ((cleanup(gs_local_bytes_unref))) +#define _cleanup_unref_hashtable __attribute__ ((cleanup(gs_local_hashtable_unref))) +#define _cleanup_unref_keyfile __attribute__ ((cleanup(gs_local_keyfile_unref))) +#define _cleanup_unref_markup_parse_context __attribute__ ((cleanup(gs_local_markup_parse_context_unref))) +#define _cleanup_unref_node __attribute__ ((cleanup(gs_local_node_unref))) +#define _cleanup_unref_object __attribute__ ((cleanup(gs_local_obj_unref))) +#define _cleanup_unref_ptrarray __attribute__ ((cleanup(gs_local_ptrarray_unref))) +#define _cleanup_unref_uri __attribute__ ((cleanup(gs_local_uri_unref))) +#define _cleanup_unref_variant __attribute__ ((cleanup(gs_local_variant_unref))) + +G_END_DECLS + +#endif diff --git a/libappstream-glib/as-image.c b/libappstream-glib/as-image.c index b2e88d3..7c7b869 100644 --- a/libappstream-glib/as-image.c +++ b/libappstream-glib/as-image.c @@ -34,6 +34,7 @@ #include "config.h" +#include "as-cleanup.h" #include "as-image-private.h" #include "as-node-private.h" #include "as-utils-private.h" @@ -457,37 +458,28 @@ as_image_load_filename (AsImage *image, GError **error) { AsImagePrivate *priv = GET_PRIVATE (image); - GdkPixbuf *pixbuf = NULL; - gboolean ret = TRUE; - gchar *basename = NULL; - gchar *data = NULL; + _cleanup_free gchar *basename = NULL; + _cleanup_free gchar *data = NULL; + _cleanup_unref_object GdkPixbuf *pixbuf = NULL; gsize len; /* get the contents so we can hash the predictable file data, * rather than the unpredicatable (for JPEG) pixel data */ - ret = g_file_get_contents (filename, &data, &len, error); - if (!ret) - goto out; + if (!g_file_get_contents (filename, &data, &len, error)) + return FALSE; priv->md5 = g_compute_checksum_for_data (G_CHECKSUM_MD5, (guchar * )data, len); /* load the image */ pixbuf = gdk_pixbuf_new_from_file (filename, error); - if (pixbuf == NULL) { - ret = FALSE; - goto out; - } + if (pixbuf == NULL) + return FALSE; /* set */ basename = g_path_get_basename (filename); as_image_set_basename (image, basename); as_image_set_pixbuf (image, pixbuf); -out: - if (pixbuf != NULL) - g_object_unref (pixbuf); - g_free (basename); - g_free (data); - return ret; + return TRUE; } /** @@ -511,7 +503,7 @@ as_image_save_pixbuf (AsImage *image, { AsImagePrivate *priv = GET_PRIVATE (image); GdkPixbuf *pixbuf = NULL; - GdkPixbuf *pixbuf_tmp = NULL; + _cleanup_unref_object GdkPixbuf *pixbuf_tmp = NULL; guint tmp_height; guint tmp_width; guint pixbuf_height; @@ -555,7 +547,6 @@ as_image_save_pixbuf (AsImage *image, pixbuf, (width - tmp_width) / 2, (height - tmp_height) / 2); - g_object_unref (pixbuf_tmp); return pixbuf; } @@ -582,22 +573,15 @@ as_image_save_filename (AsImage *image, AsImageSaveFlags flags, GError **error) { - GdkPixbuf *pixbuf; - gboolean ret; + _cleanup_unref_object GdkPixbuf *pixbuf; /* save source file */ pixbuf = as_image_save_pixbuf (image, width, height, flags); - ret = gdk_pixbuf_save (pixbuf, - filename, - "png", - error, - NULL); - if (!ret) - goto out; -out: - if (pixbuf != NULL) - g_object_unref (pixbuf); - return ret; + return gdk_pixbuf_save (pixbuf, + filename, + "png", + error, + NULL); } /** diff --git a/libappstream-glib/as-node.c b/libappstream-glib/as-node.c index 5c5cb49..9facefa 100644 --- a/libappstream-glib/as-node.c +++ b/libappstream-glib/as-node.c @@ -37,6 +37,7 @@ #include <glib.h> #include <string.h> +#include "as-cleanup.h" #include "as-node-private.h" #include "as-utils-private.h" @@ -181,20 +182,17 @@ as_node_error_quark (void) static void as_node_string_replace (GString *string, const gchar *search, const gchar *replace) { - gchar **split = NULL; - gchar *tmp = NULL; + _cleanup_free gchar *tmp = NULL; + _cleanup_free_strv gchar **split = NULL; /* quick search */ if (g_strstr_len (string->str, -1, search) == NULL) - goto out; + return; /* replace */ split = g_strsplit (string->str, search, -1); tmp = g_strjoinv (replace, split); g_string_assign (string, tmp); -out: - g_strfreev (split); - g_free (tmp); } /** @@ -574,9 +572,9 @@ as_node_passthrough_cb (GMarkupParseContext *context, GError **error) { AsNodeToXmlHelper *helper = (AsNodeToXmlHelper *) user_data; + _cleanup_free gchar *text = NULL; const gchar *tmp; gchar *found; - gchar *text = NULL; /* only keep comments when told to */ if ((helper->flags & AS_NODE_FROM_XML_FLAG_KEEP_COMMENTS) == 0) @@ -584,23 +582,21 @@ as_node_passthrough_cb (GMarkupParseContext *context, /* xml header */ if (g_strstr_len (passthrough_text, passthrough_len, "<?xml") != NULL) - goto out; + return; /* get stripped comment without '<!--' and '-->' */ text = g_strndup (passthrough_text, passthrough_len); if (!g_str_has_prefix (text, "<!--")) { g_warning ("Unexpected input: %s", text); - goto out; + return; } found = g_strrstr (text, "-->"); if (found != NULL) *found = '\0'; tmp = g_strstrip (text + 4); if (tmp == NULL || tmp[0] == '\0') - goto out; + return; as_node_add_attribute (helper->current, "@comment-tmp", tmp, -1); -out: - g_free (text); } /** @@ -623,9 +619,9 @@ as_node_from_xml (const gchar *data, GError **error) { AsNodeToXmlHelper helper; - GError *error_local = NULL; - GMarkupParseContext *ctx; - GNode *root; + GNode *root = NULL; + _cleanup_unref_markup_parse_context GMarkupParseContext *ctx = NULL; + _cleanup_free_error GError *error_local = NULL; gboolean ret; const GMarkupParser parser = { as_node_start_element_cb, @@ -652,10 +648,8 @@ as_node_from_xml (const gchar *data, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, error_local->message); - g_error_free (error_local); as_node_unref (root); - root = NULL; - goto out; + return NULL; } /* more opening than closing */ @@ -665,11 +659,8 @@ as_node_from_xml (const gchar *data, AS_NODE_ERROR_FAILED, "Mismatched XML"); as_node_unref (root); - root = NULL; - goto out; + return NULL; } -out: - g_markup_parse_context_free (ctx); return root; } @@ -693,16 +684,16 @@ as_node_from_file (GFile *file, GError **error) { AsNodeToXmlHelper helper; - GConverter *conv = NULL; GError *error_local = NULL; - GFileInfo *info = NULL; - GInputStream *file_stream = NULL; - GInputStream *stream_data = NULL; - GMarkupParseContext *ctx = NULL; GNode *root = NULL; + _cleanup_free gchar *data = NULL; + _cleanup_unref_markup_parse_context GMarkupParseContext *ctx = NULL; + _cleanup_unref_object GConverter *conv = NULL; + _cleanup_unref_object GFileInfo *info = NULL; + _cleanup_unref_object GInputStream *file_stream = NULL; + _cleanup_unref_object GInputStream *stream_data = NULL; const gchar *content_type = NULL; gboolean ret = TRUE; - gchar *data = NULL; gsize chunk_size = 32 * 1024; gssize len; const GMarkupParser parser = { @@ -719,12 +710,12 @@ as_node_from_file (GFile *file, cancellable, error); if (info == NULL) - goto out; + return NULL; /* decompress if required */ file_stream = G_INPUT_STREAM (g_file_read (file, cancellable, error)); if (file_stream == NULL) - goto out; + return NULL; content_type = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE); if (g_strcmp0 (content_type, "application/gzip") == 0 || g_strcmp0 (content_type, "application/x-gzip") == 0) { @@ -738,7 +729,7 @@ as_node_from_file (GFile *file, AS_NODE_ERROR_FAILED, "cannot process file of type %s", content_type); - goto out; + return NULL; } /* parse */ @@ -767,14 +758,12 @@ as_node_from_file (GFile *file, error_local->message); g_error_free (error_local); as_node_unref (root); - root = NULL; - goto out; + return NULL; } } if (len < 0) { as_node_unref (root); - root = NULL; - goto out; + return NULL; } /* more opening than closing */ @@ -784,21 +773,8 @@ as_node_from_file (GFile *file, AS_NODE_ERROR_FAILED, "Mismatched XML"); as_node_unref (root); - root = NULL; - goto out; + return NULL; } -out: - if (info != NULL) - g_object_unref (info); - if (stream_data != NULL) - g_object_unref (stream_data); - if (conv != NULL) - g_object_unref (conv); - if (file_stream != NULL) - g_object_unref (file_stream); - g_free (data); - if (ctx != NULL) - g_markup_parse_context_free (ctx); return root; } @@ -1035,19 +1011,16 @@ as_node_get_attribute_as_int (const GNode *node, const gchar *key) const gchar *tmp; gchar *endptr = NULL; guint64 value_tmp; - guint value = G_MAXUINT; tmp = as_node_get_attribute (node, key); if (tmp == NULL) - goto out; + return G_MAXUINT; value_tmp = g_ascii_strtoll (tmp, &endptr, 10); if (value_tmp == 0 && tmp == endptr) - goto out; + return G_MAXUINT; if (value_tmp > G_MAXINT) - goto out; - value = value_tmp; -out: - return value; + return G_MAXUINT; + return value_tmp; } /** @@ -1151,8 +1124,8 @@ as_node_add_attribute (GNode *node, GNode * as_node_find (GNode *root, const gchar *path) { - gchar **split; GNode *node = root; + _cleanup_free_strv gchar **split = NULL; guint i; g_return_val_if_fail (path != NULL, NULL); @@ -1161,10 +1134,8 @@ as_node_find (GNode *root, const gchar *path) for (i = 0; split[i] != NULL; i++) { node = as_node_get_child_node (node, split[i]); if (node == NULL) - goto out; + return NULL; } -out: - g_strfreev (split); return node; } @@ -1243,12 +1214,12 @@ as_node_insert_localized (GNode *parent, GHashTable *localized, AsNodeInsertFlags insert_flags) { + AsNodeData *data; + GList *l; + _cleanup_free_list GList *list = NULL; const gchar *key; const gchar *value; const gchar *value_c; - AsNodeData *data; - GList *l; - GList *list; /* add the untranslated value first */ value_c = g_hash_table_lookup (localized, "C"); @@ -1292,7 +1263,6 @@ as_node_insert_localized (GNode *parent, } g_node_insert_data (parent, -1, data); } - g_list_free (list); } /** @@ -1366,7 +1336,7 @@ as_node_get_localized (const GNode *node, const gchar *key) /* does it exist? */ tmp = as_node_get_child_node (node, key); if (tmp == NULL) - goto out; + return NULL; data_unlocalized = as_node_get_data (tmp); /* find a node called name */ @@ -1389,7 +1359,6 @@ as_node_get_localized (const GNode *node, const gchar *key) g_strdup (xml_lang != NULL ? xml_lang : "C"), (gpointer) data_localized); } -out: return hash; } @@ -1407,19 +1376,11 @@ out: const gchar * as_node_get_localized_best (const GNode *node, const gchar *key) { - GHashTable *hash; - const gchar *tmp = NULL; - + _cleanup_unref_hashtable GHashTable *hash = NULL; hash = as_node_get_localized (node, key); if (hash == NULL) - goto out; - tmp = as_hash_lookup_by_locale (hash, NULL); - if (tmp == NULL) - goto out; -out: - if (hash != NULL) - g_hash_table_unref (hash); - return tmp; + return NULL; + return as_hash_lookup_by_locale (hash, NULL); } /** @@ -1439,10 +1400,10 @@ as_node_denorm_add_to_langs (GHashTable *hash, const gchar *data, gboolean is_start) { - const gchar *xml_lang; - GList *keys; GList *l; GString *str; + _cleanup_free_list GList *keys = NULL; + const gchar *xml_lang; keys = g_hash_table_get_keys (hash); for (l = keys; l != NULL; l = l->next) { @@ -1453,7 +1414,6 @@ as_node_denorm_add_to_langs (GHashTable *hash, else g_string_append_printf (str, "</%s>", data); } - g_list_free (keys); } /** @@ -1505,7 +1465,6 @@ as_node_get_localized_unwrap_type_li (const GNode *node, AsNodeData *data; AsNodeData *data_c; GString *str; - gboolean ret = TRUE; for (tmp = node->children; tmp != NULL; tmp = tmp->next) { data = tmp->data; @@ -1544,29 +1503,26 @@ as_node_get_localized_unwrap_type_li (const GNode *node, data_c->cdata); } else { /* only <li> is valid in lists */ - ret = FALSE; g_set_error (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, "Tag %s in %s invalid", data_c->name, data->name); - goto out; + return FALSE; } } as_node_denorm_add_to_langs (hash, data->name, FALSE); } else { /* only <p>, <ul> and <ol> is valid here */ - ret = FALSE; g_set_error (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, "Unknown tag '%s'", data->name); - goto out; + return FALSE; } } -out: - return ret; + return TRUE; } /** @@ -1597,7 +1553,6 @@ as_node_get_localized_unwrap_type_ul (const GNode *node, AsNodeData *data; AsNodeData *data_c; GString *str; - gboolean ret = TRUE; for (tmp = node->children; tmp != NULL; tmp = tmp->next) { data = tmp->data; @@ -1624,29 +1579,26 @@ as_node_get_localized_unwrap_type_ul (const GNode *node, data_c->cdata); } else { /* only <li> is valid in lists */ - ret = FALSE; g_set_error (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, "Tag %s in %s invalid", data_c->name, data->name); - goto out; + return FALSE; } } g_string_append_printf (str, "</%s>", data->name); } else { /* only <p>, <ul> and <ol> is valid here */ - ret = FALSE; g_set_error (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, "Unknown tag '%s'", data->name); - goto out; + return FALSE; } } -out: - return ret; + return TRUE; } /** @@ -1681,16 +1633,15 @@ out: GHashTable * as_node_get_localized_unwrap (const GNode *node, GError **error) { - GNode *tmp; AsNodeData *data; - const gchar *xml_lang; - GHashTable *hash; - GString *str; - GList *keys = NULL; + GHashTable *results; GList *l; - GHashTable *results = NULL; + GNode *tmp; + GString *str; + _cleanup_free_list GList *keys = NULL; + _cleanup_unref_hashtable GHashTable *hash = NULL; + const gchar *xml_lang; gboolean is_li_translated = TRUE; - gboolean ret; /* work out what kind of normalization this is */ for (tmp = node->children; tmp != NULL; tmp = tmp->next) { @@ -1708,13 +1659,11 @@ as_node_get_localized_unwrap (const GNode *node, GError **error) hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) as_node_string_free); if (is_li_translated) { - ret = as_node_get_localized_unwrap_type_li (node, hash, error); - if (!ret) - goto out; + if (!as_node_get_localized_unwrap_type_li (node, hash, error)) + return NULL; } else { - ret = as_node_get_localized_unwrap_type_ul (node, hash, error); - if (!ret) - goto out; + if (!as_node_get_localized_unwrap_type_ul (node, hash, error)) + return NULL; } /* copy into a hash table of the correct size */ @@ -1727,8 +1676,5 @@ as_node_get_localized_unwrap (const GNode *node, GError **error) g_strdup (xml_lang), g_strdup (str->str)); } -out: - g_list_free (keys); - g_hash_table_unref (hash); return results; } diff --git a/libappstream-glib/as-release.c b/libappstream-glib/as-release.c index f1dcbdf..404bc1a 100644 --- a/libappstream-glib/as-release.c +++ b/libappstream-glib/as-release.c @@ -39,6 +39,7 @@ #include <stdlib.h> +#include "as-cleanup.h" #include "as-node-private.h" #include "as-release-private.h" #include "as-tag.h" @@ -227,7 +228,7 @@ as_release_node_insert (AsRelease *release, GNode *parent, gdouble api_version) { AsReleasePrivate *priv = GET_PRIVATE (release); GNode *n; - gchar *timestamp_str; + _cleanup_free gchar *timestamp_str; timestamp_str = g_strdup_printf ("%" G_GUINT64_FORMAT, priv->timestamp); @@ -241,7 +242,6 @@ as_release_node_insert (AsRelease *release, GNode *parent, gdouble api_version) AS_NODE_INSERT_FLAG_PRE_ESCAPED | AS_NODE_INSERT_FLAG_DEDUPE_LANG); } - g_free (timestamp_str); return n; } @@ -262,7 +262,6 @@ as_release_node_parse (AsRelease *release, GNode *node, GError **error) { AsReleasePrivate *priv = GET_PRIVATE (release); GNode *n; - GString *xml; const gchar *tmp; gchar *taken; @@ -277,13 +276,13 @@ as_release_node_parse (AsRelease *release, GNode *node, GError **error) /* descriptions are translated and optional */ for (n = node->children; n != NULL; n = n->next) { + _cleanup_free_string GString *xml = NULL; if (as_node_get_tag (n) != AS_TAG_DESCRIPTION) continue; xml = as_node_to_xml (n->children, AS_NODE_TO_XML_FLAG_NONE); as_release_set_description (release, as_node_get_attribute (n, "xml:lang"), xml->str, xml->len); - g_string_free (xml, TRUE); } return TRUE; } diff --git a/libappstream-glib/as-screenshot.c b/libappstream-glib/as-screenshot.c index a90e554..51d4411 100644 --- a/libappstream-glib/as-screenshot.c +++ b/libappstream-glib/as-screenshot.c @@ -33,6 +33,7 @@ #include "config.h" +#include "as-cleanup.h" #include "as-image-private.h" #include "as-node-private.h" #include "as-screenshot-private.h" @@ -317,14 +318,11 @@ as_screenshot_node_insert (AsScreenshot *screenshot, gboolean as_screenshot_node_parse (AsScreenshot *screenshot, GNode *node, GError **error) { - AsImage *image; AsScreenshotPrivate *priv = GET_PRIVATE (screenshot); - GHashTable *captions = NULL; - GList *keys; GList *l; GNode *c; + _cleanup_unref_hashtable GHashTable *captions = NULL; const gchar *tmp; - gboolean ret = TRUE; guint size; tmp = as_node_get_attribute (node, "type"); @@ -336,6 +334,7 @@ as_screenshot_node_parse (AsScreenshot *screenshot, GNode *node, GError **error) /* add captions */ captions = as_node_get_localized (node, "caption"); if (captions != NULL) { + _cleanup_free_list GList *keys; keys = g_hash_table_get_keys (captions); for (l = keys; l != NULL; l = l->next) { tmp = l->data; @@ -344,12 +343,12 @@ as_screenshot_node_parse (AsScreenshot *screenshot, GNode *node, GError **error) g_hash_table_lookup (captions, tmp), -1); } - g_list_free (keys); } /* AppData files does not have <image> tags */ tmp = as_node_get_data (node); if (tmp != NULL) { + AsImage *image; image = as_image_new (); as_image_set_kind (image, AS_IMAGE_KIND_SOURCE); size = as_node_get_attribute_as_int (node, "width"); @@ -364,20 +363,15 @@ as_screenshot_node_parse (AsScreenshot *screenshot, GNode *node, GError **error) /* add images */ for (c = node->children; c != NULL; c = c->next) { + _cleanup_unref_object AsImage *image = NULL; if (as_node_get_tag (c) != AS_TAG_IMAGE) continue; image = as_image_new (); - ret = as_image_node_parse (image, c, error); - if (!ret) { - g_object_unref (image); - goto out; - } - g_ptr_array_add (priv->images, image); + if (!as_image_node_parse (image, c, error)) + return FALSE; + g_ptr_array_add (priv->images, g_object_ref (image)); } -out: - if (captions != NULL) - g_hash_table_unref (captions); - return ret; + return TRUE; } /** diff --git a/libappstream-glib/as-self-test.c b/libappstream-glib/as-self-test.c index 1718b87..688ee73 100644 --- a/libappstream-glib/as-self-test.c +++ b/libappstream-glib/as-self-test.c @@ -25,6 +25,7 @@ #include <stdlib.h> #include "as-app-private.h" +#include "as-cleanup.h" #include "as-enums.h" #include "as-image-private.h" #include "as-node-private.h" @@ -43,18 +44,14 @@ static gchar * as_test_get_filename (const gchar *filename) { char full_tmp[PATH_MAX]; - gchar *full = NULL; - gchar *path; + _cleanup_free gchar *path = NULL; gchar *tmp; path = g_build_filename (TESTDATADIR, filename, NULL); tmp = realpath (path, full_tmp); if (tmp == NULL) - goto out; - full = g_strdup (full_tmp); -out: - g_free (path); - return full; + return NULL; + return g_strdup (full_tmp); } static void @@ -81,11 +78,11 @@ ch_test_tag_func (void) static void ch_test_release_func (void) { - AsRelease *release; GError *error = NULL; GNode *n; GNode *root; GString *xml; + _cleanup_unref_object AsRelease *release = NULL; const gchar *src = "<release version=\"0.1.2\" timestamp=\"123\"/>"; gboolean ret; @@ -113,18 +110,16 @@ ch_test_release_func (void) g_assert_cmpstr (xml->str, ==, src); g_string_free (xml, TRUE); as_node_unref (root); - - g_object_unref (release); } static void ch_test_provide_func (void) { - AsProvide *provide; GError *error = NULL; GNode *n; GNode *root; GString *xml; + _cleanup_unref_object AsProvide *provide = NULL; const gchar *src = "<binary>/usr/bin/gnome-shell</binary>"; gboolean ret; @@ -152,19 +147,17 @@ ch_test_provide_func (void) g_assert_cmpstr (xml->str, ==, src); g_string_free (xml, TRUE); as_node_unref (root); - - g_object_unref (provide); } static void ch_test_release_desc_func (void) { - AsRelease *release; GError *error = NULL; GNode *n; GNode *root; GString *xml; gboolean ret; + _cleanup_unref_object AsRelease *release; const gchar *src = "<release version=\"0.1.2\" timestamp=\"123\">" "<description><p>This is a new release</p></description>" @@ -197,24 +190,22 @@ ch_test_release_desc_func (void) g_assert_cmpstr (xml->str, ==, src); g_string_free (xml, TRUE); as_node_unref (root); - - g_object_unref (release); } static void ch_test_image_func (void) { - AsImage *image; - GdkPixbuf *pixbuf; GError *error = NULL; GNode *n; GNode *root; GString *xml; + _cleanup_free gchar *filename = NULL; + _cleanup_unref_object AsImage *image = NULL; + _cleanup_unref_object GdkPixbuf *pixbuf = NULL; const gchar *src = "<image type=\"thumbnail\" height=\"12\" width=\"34\">" "http://www.hughsie.com/a.jpg</image>"; gboolean ret; - gchar *filename; image = as_image_new (); @@ -259,7 +250,6 @@ ch_test_image_func (void) AS_IMAGE_SAVE_FLAG_PAD_16_9); g_assert_cmpint (gdk_pixbuf_get_width (pixbuf), ==, 752); g_assert_cmpint (gdk_pixbuf_get_height (pixbuf), ==, 423); - g_object_unref (pixbuf); /* save */ ret = as_image_save_filename (image, @@ -269,9 +259,6 @@ ch_test_image_func (void) &error); g_assert_no_error (error); g_assert (ret); - - g_free (filename); - g_object_unref (image); } static void @@ -279,11 +266,11 @@ ch_test_screenshot_func (void) { GPtrArray *images; AsImage *im; - AsScreenshot *screenshot; GError *error = NULL; GNode *n; GNode *root; GString *xml; + _cleanup_unref_object AsScreenshot *screenshot = NULL; const gchar *src = "<screenshot type=\"normal\">" "<caption>Hello</caption>" @@ -321,14 +308,12 @@ ch_test_screenshot_func (void) g_assert_cmpstr (xml->str, ==, src); g_string_free (xml, TRUE); as_node_unref (root); - - g_object_unref (screenshot); } static void ch_test_app_func (void) { - AsApp *app; + _cleanup_unref_object AsApp *app = NULL; GError *error = NULL; GNode *n; GNode *root; @@ -424,8 +409,6 @@ ch_test_app_func (void) /* test contact demunging */ as_app_set_update_contact (app, "richard_at_hughsie_dot_co_dot_uk", -1); g_assert_cmpstr (as_app_get_update_contact (app), ==, "richard@hughsie.co.uk"); - - g_object_unref (app); } static void @@ -454,7 +437,6 @@ ch_test_app_validate_check (GPtrArray *array, static void ch_test_app_validate_file_good_func (void) { - AsApp *app; AsImage *im; AsProblem *problem; AsScreenshot *ss; @@ -462,8 +444,9 @@ ch_test_app_validate_file_good_func (void) GPtrArray *images; GPtrArray *probs; GPtrArray *screenshots; + _cleanup_free gchar *filename = NULL; + _cleanup_unref_object AsApp *app = NULL; gboolean ret; - gchar *filename; guint i; /* open file */ @@ -507,20 +490,17 @@ ch_test_app_validate_file_good_func (void) g_assert_cmpint (as_image_get_width (im), ==, 355); g_assert_cmpint (as_image_get_height (im), ==, 134); g_assert_cmpint (as_image_get_kind (im), ==, AS_IMAGE_KIND_SOURCE); - - g_free (filename); - g_object_unref (app); } static void ch_test_app_validate_intltool_func (void) { - AsApp *app; AsProblem *problem; GError *error = NULL; GPtrArray *probs; + _cleanup_free gchar *filename = NULL; + _cleanup_unref_object AsApp *app = NULL; gboolean ret; - gchar *filename; guint i; /* open file */ @@ -544,18 +524,15 @@ ch_test_app_validate_intltool_func (void) } g_assert_cmpint (probs->len, ==, 0); g_ptr_array_unref (probs); - - g_free (filename); - g_object_unref (app); } static void ch_test_app_translated_func (void) { - AsApp *app; GError *error = NULL; gboolean ret; - gchar *filename; + _cleanup_free gchar *filename = NULL; + _cleanup_unref_object AsApp *app = NULL; /* open file */ app = as_app_new (); @@ -568,20 +545,17 @@ ch_test_app_translated_func (void) g_assert_cmpstr (as_app_get_description (app, "C"), ==, "<p>Awesome</p>"); g_assert_cmpstr (as_app_get_description (app, "pl"), ==, "<p>Asomeski</p>"); g_assert_cmpint (as_app_get_description_size (app), ==, 2); - - g_free (filename); - g_object_unref (app); } static void ch_test_app_validate_file_bad_func (void) { - AsApp *app; AsProblem *problem; GError *error = NULL; - GPtrArray *probs; gboolean ret; - gchar *filename; + _cleanup_free gchar *filename = NULL; + _cleanup_unref_object AsApp *app = NULL; + _cleanup_unref_ptrarray GPtrArray *probs = NULL; guint i; /* open file */ @@ -646,20 +620,16 @@ ch_test_app_validate_file_bad_func (void) "<release> has no version"); ch_test_app_validate_check (probs, AS_PROBLEM_KIND_ATTRIBUTE_MISSING, "<release> has no timestamp"); - - g_ptr_array_unref (probs); - g_free (filename); - g_object_unref (app); } static void ch_test_app_validate_style_func (void) { - AsApp *app; + AsProblem *problem; GError *error = NULL; - GPtrArray *probs; + _cleanup_unref_object AsApp *app = NULL; + _cleanup_unref_ptrarray GPtrArray *probs = NULL; guint i; - AsProblem *problem; app = as_app_new (); as_app_add_url (app, AS_URL_KIND_UNKNOWN, "dave.com", -1); @@ -702,18 +672,15 @@ ch_test_app_validate_style_func (void) ch_test_app_validate_check (probs, AS_PROBLEM_KIND_TAG_MISSING, "<url> is not present"); g_assert_cmpint (probs->len, ==, 11); - - g_ptr_array_unref (probs); - g_object_unref (app); } static void ch_test_app_parse_file_func (void) { - AsApp *app; GError *error = NULL; gboolean ret; - gchar *filename; + _cleanup_free gchar *filename = NULL; + _cleanup_unref_object AsApp *app = NULL; /* create an AsApp from a desktop file */ app = as_app_new (); @@ -753,20 +720,17 @@ ch_test_app_parse_file_func (void) g_assert_error (error, AS_APP_ERROR, AS_APP_ERROR_INVALID_TYPE); g_assert (!ret); g_clear_error (&error); - - g_free (filename); - g_object_unref (app); } static void ch_test_app_no_markup_func (void) { - AsApp *app; GError *error = NULL; GNode *n; GNode *root; GString *xml; gboolean ret; + _cleanup_unref_object AsApp *app = NULL; const gchar *src = "<application>" "<id type=\"desktop\">org.gnome.Software.desktop</id>" @@ -800,8 +764,6 @@ ch_test_app_no_markup_func (void) g_assert_cmpstr (xml->str, ==, src); g_string_free (xml, TRUE); as_node_unref (root); - - g_object_unref (app); } static void @@ -840,7 +802,7 @@ ch_test_node_func (void) { GNode *n1; GNode *n2; - GNode *root; + _cleanup_unref_node GNode *root = NULL; /* create a simple tree */ root = as_node_new (); @@ -876,8 +838,6 @@ ch_test_node_func (void) g_assert (n2 == NULL); n2 = as_node_find (root, "apps//id"); g_assert (n2 == NULL); - - as_node_unref (root); } static void @@ -1048,9 +1008,9 @@ static void ch_test_node_localized_wrap_func (void) { GError *error = NULL; - GHashTable *hash; GNode *n1; - GNode *root; + _cleanup_unref_hashtable GHashTable *hash = NULL; + _cleanup_unref_node GNode *root = NULL; const gchar *xml = "<description>" " <p>Hi</p>" @@ -1079,18 +1039,15 @@ ch_test_node_localized_wrap_func (void) "<p>Czesc</p><ul><li>Pierwszy</li></ul>"); g_assert_cmpstr (g_hash_table_lookup (hash, "en_GB"), ==, "<ul><li>Hi</li></ul>"); - g_hash_table_unref (hash); - - as_node_unref (root); } static void ch_test_node_localized_wrap2_func (void) { GError *error = NULL; - GHashTable *hash; GNode *n1; - GNode *root; + _cleanup_unref_hashtable GHashTable *hash = NULL; + _cleanup_unref_node GNode *root = NULL; const gchar *xml = "<description>" " <p>Hi</p>" @@ -1120,16 +1077,13 @@ ch_test_node_localized_wrap2_func (void) "<p>Hi</p><ul><li>First</li><li>Second</li></ul>"); g_assert_cmpstr (g_hash_table_lookup (hash, "pl"), ==, "<p>Czesc</p><ul><li>Pierwszy</li><li>Secondski</li></ul>"); - g_hash_table_unref (hash); - - as_node_unref (root); } static void ch_test_app_subsume_func (void) { - AsApp *app; - AsApp *donor; + _cleanup_unref_object AsApp *app = NULL; + _cleanup_unref_object AsApp *donor = NULL; GList *list; donor = as_app_new (); @@ -1160,15 +1114,12 @@ ch_test_app_subsume_func (void) g_assert_cmpstr (as_app_get_metadata_item (app, "recipient"), ==, "true"); g_assert_cmpstr (as_app_get_metadata_item (donor, "donor"), ==, "true"); g_assert_cmpstr (as_app_get_metadata_item (donor, "recipient"), ==, "true"); - - g_object_unref (app); - g_object_unref (donor); } static void ch_test_app_search_func (void) { - AsApp *app; + _cleanup_unref_object AsApp *app = NULL; const gchar *all[] = { "gnome", "install", "software", NULL }; const gchar *none[] = { "gnome", "xxx", "software", NULL }; const gchar *mime[] = { "application", "vnd", "oasis", "opendocument","text", NULL }; @@ -1184,16 +1135,14 @@ ch_test_app_search_func (void) g_assert_cmpint (as_app_search_matches_all (app, (gchar**) all), ==, 220); g_assert_cmpint (as_app_search_matches_all (app, (gchar**) none), ==, 0); g_assert_cmpint (as_app_search_matches_all (app, (gchar**) mime), ==, 5); - - g_object_unref (app); } static void ch_test_store_func (void) { AsApp *app; - AsStore *store; GString *xml; + _cleanup_unref_object AsStore *store = NULL; /* create a store and add a single app */ store = as_store_new (); @@ -1242,9 +1191,6 @@ ch_test_store_func (void) "</application>" "</applications>"); g_string_free (xml, TRUE); - - g_object_unref (store); - } static void @@ -1344,12 +1290,12 @@ ch_test_store_versions_func (void) static void ch_test_node_no_dup_c_func (void) { - AsApp *app; GError *error = NULL; GNode *n; GNode *root; GString *xml; gboolean ret; + _cleanup_unref_object AsApp *app = NULL; const gchar *src = "<application>" "<id type=\"desktop\">test.desktop</id>" @@ -1384,19 +1330,17 @@ ch_test_node_no_dup_c_func (void) "</application>"); g_string_free (xml, TRUE); as_node_unref (root); - - g_object_unref (app); } static void ch_test_store_origin_func (void) { AsApp *app; - AsStore *store; GError *error = NULL; - GFile *file; gboolean ret; - gchar *filename; + _cleanup_free gchar *filename = NULL; + _cleanup_unref_object AsStore *store = NULL; + _cleanup_unref_object GFile *file = NULL; /* load a file to the store */ store = as_store_new (); @@ -1413,21 +1357,16 @@ ch_test_store_origin_func (void) g_assert (app != NULL); g_assert_cmpstr (as_app_get_icon_path (app), ==, "/usr/share/app-info/icons/fedora-21"); - - g_free (filename); - g_object_unref (file); - g_object_unref (store); } static void ch_test_store_speed_func (void) { - AsStore *store; GError *error = NULL; - GFile *file; - GTimer *timer; + _cleanup_destroy_timer GTimer *timer = NULL; + _cleanup_free gchar *filename = NULL; + _cleanup_unref_object GFile *file = NULL; gboolean ret; - gchar *filename; guint i; guint loops = 10; @@ -1435,6 +1374,7 @@ ch_test_store_speed_func (void) file = g_file_new_for_path (filename); timer = g_timer_new (); for (i = 0; i < loops; i++) { + _cleanup_unref_object AsStore *store; store = as_store_new (); ret = as_store_from_file (store, file, NULL, NULL, &error); g_assert_no_error (error); @@ -1442,13 +1382,8 @@ ch_test_store_speed_func (void) g_assert_cmpint (as_store_get_apps (store)->len, >=, 1415); g_assert (as_store_get_app_by_id (store, "org.gnome.Software.desktop") != NULL); g_assert (as_store_get_app_by_pkgname (store, "gnome-software") != NULL); - g_object_unref (store); } g_print ("%.0f ms: ", g_timer_elapsed (timer, NULL) * 1000 / loops); - - g_free (filename); - g_object_unref (file); - g_timer_destroy (timer); } static void @@ -1577,8 +1512,8 @@ ch_test_utils_func (void) static void ch_test_store_app_install_func (void) { - AsStore *store; GError *error = NULL; + _cleanup_unref_object AsStore *store = NULL; gboolean ret; store = as_store_new (); @@ -1588,16 +1523,15 @@ ch_test_store_app_install_func (void) &error); g_assert_no_error (error); g_assert (ret); - g_object_unref (store); } static void ch_test_store_metadata_func (void) { - AsStore *store; GError *error = NULL; GPtrArray *apps; gboolean ret; + _cleanup_unref_object AsStore *store = NULL; const gchar *xml = "<applications version=\"0.3\">" "<application>" @@ -1622,8 +1556,6 @@ ch_test_store_metadata_func (void) apps = as_store_get_apps_by_metadata (store, "foo", "bar"); g_assert_cmpint (apps->len, ==, 2); g_ptr_array_unref (apps); - - g_object_unref (store); } int diff --git a/libappstream-glib/as-store.c b/libappstream-glib/as-store.c index d968287..3502b13 100644 --- a/libappstream-glib/as-store.c +++ b/libappstream-glib/as-store.c @@ -37,6 +37,7 @@ #include "config.h" #include "as-app-private.h" +#include "as-cleanup.h" #include "as-node-private.h" #include "as-store.h" #include "as-utils-private.h" @@ -355,9 +356,8 @@ as_store_from_root (AsStore *store, GError *error_local = NULL; GNode *apps; GNode *n; + _cleanup_free gchar *icon_path = NULL; const gchar *tmp; - gboolean ret = TRUE; - gchar *icon_path = NULL; g_return_val_if_fail (AS_IS_STORE (store), FALSE); @@ -365,12 +365,11 @@ as_store_from_root (AsStore *store, if (apps == NULL) { apps = as_node_find (root, "applications"); if (apps == NULL) { - ret = FALSE; g_set_error_literal (error, AS_STORE_ERROR, AS_STORE_ERROR_FAILED, "No valid root node specified"); - goto out; + return FALSE; } } @@ -399,8 +398,7 @@ as_store_from_root (AsStore *store, if (icon_path != NULL) as_app_set_icon_path (app, icon_path, -1); as_app_set_source_kind (app, AS_APP_SOURCE_KIND_APPSTREAM); - ret = as_app_node_parse (app, n, &error_local); - if (!ret) { + if (!as_app_node_parse (app, n, &error_local)) { g_set_error (error, AS_STORE_ERROR, AS_STORE_ERROR_FAILED, @@ -408,14 +406,12 @@ as_store_from_root (AsStore *store, error_local->message); g_error_free (error_local); g_object_unref (app); - goto out; + return FALSE; } as_store_add_app (store, app); g_object_unref (app); } -out: - g_free (icon_path); - return ret; + return TRUE; } /** @@ -443,9 +439,8 @@ as_store_from_file (AsStore *store, GCancellable *cancellable, GError **error) { - GError *error_local = NULL; - GNode *root; - gboolean ret = TRUE; + _cleanup_free_error GError *error_local = NULL; + _cleanup_unref_node GNode *root = NULL; g_return_val_if_fail (AS_IS_STORE (store), FALSE); @@ -454,22 +449,14 @@ as_store_from_file (AsStore *store, cancellable, &error_local); if (root == NULL) { - ret = FALSE; g_set_error (error, AS_STORE_ERROR, AS_STORE_ERROR_FAILED, "Failed to parse file: %s", error_local->message); - g_error_free (error_local); - goto out; + return FALSE; } - ret = as_store_from_root (store, root, icon_root, error); - if (!ret) - goto out; -out: - if (root != NULL) - as_node_unref (root); - return ret; + return as_store_from_root (store, root, icon_root, error); } /** @@ -497,9 +484,8 @@ as_store_from_xml (AsStore *store, const gchar *icon_root, GError **error) { - GError *error_local = NULL; - GNode *root; - gboolean ret = TRUE; + _cleanup_free_error GError *error_local = NULL; + _cleanup_unref_node GNode *root = NULL; g_return_val_if_fail (AS_IS_STORE (store), FALSE); @@ -507,22 +493,14 @@ as_store_from_xml (AsStore *store, AS_NODE_FROM_XML_FLAG_LITERAL_TEXT, &error_local); if (root == NULL) { - ret = FALSE; g_set_error (error, AS_STORE_ERROR, AS_STORE_ERROR_FAILED, "Failed to parse XML: %s", error_local->message); - g_error_free (error_local); - goto out; + return TRUE; } - ret = as_store_from_root (store, root, icon_root, error); - if (!ret) - goto out; -out: - if (root != NULL) - as_node_unref (root); - return ret; + return as_store_from_root (store, root, icon_root, error); } /** @@ -610,65 +588,53 @@ as_store_to_file (AsStore *store, GCancellable *cancellable, GError **error) { - GError *error_local = NULL; - GOutputStream *out; - GOutputStream *out2; - GString *xml; - GZlibCompressor *compressor; - gboolean ret; + _cleanup_free_error GError *error_local = NULL; + _cleanup_free_string GString *xml = NULL; + _cleanup_unref_object GOutputStream *out2 = NULL; + _cleanup_unref_object GOutputStream *out = NULL; + _cleanup_unref_object GZlibCompressor *compressor = NULL; /* compress as a gzip file */ compressor = g_zlib_compressor_new (G_ZLIB_COMPRESSOR_FORMAT_GZIP, -1); out = g_memory_output_stream_new_resizable (); out2 = g_converter_output_stream_new (out, G_CONVERTER (compressor)); xml = as_store_to_xml (store, flags); - ret = g_output_stream_write_all (out2, xml->str, xml->len, - NULL, NULL, &error_local); - if (!ret) { + if (!g_output_stream_write_all (out2, xml->str, xml->len, + NULL, NULL, &error_local)) { g_set_error (error, AS_STORE_ERROR, AS_STORE_ERROR_FAILED, "Failed to write stream: %s", error_local->message); - g_error_free (error_local); - goto out; + return FALSE; } - ret = g_output_stream_close (out2, NULL, &error_local); - if (!ret) { + if (!g_output_stream_close (out2, NULL, &error_local)) { g_set_error (error, AS_STORE_ERROR, AS_STORE_ERROR_FAILED, "Failed to close stream: %s", error_local->message); - g_error_free (error_local); - goto out; + return FALSE; } /* write file */ - ret = g_file_replace_contents (file, + if (!g_file_replace_contents (file, g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (out)), g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (out)), - NULL, - FALSE, - G_FILE_CREATE_NONE, - NULL, - cancellable, - &error_local); - if (!ret) { + NULL, + FALSE, + G_FILE_CREATE_NONE, + NULL, + cancellable, + &error_local)) { g_set_error (error, AS_STORE_ERROR, AS_STORE_ERROR_FAILED, "Failed to write file: %s", error_local->message); - g_error_free (error_local); - goto out; + return FALSE; } -out: - g_object_unref (compressor); - g_object_unref (out); - g_object_unref (out2); - g_string_free (xml, TRUE); - return ret; + return TRUE; } /** @@ -746,8 +712,7 @@ as_store_guess_origin_fallback (AsStore *store, const gchar *filename, GError **error) { - gboolean ret = TRUE; - gchar *origin_fallback; + _cleanup_free gchar *origin_fallback; gchar *tmp; /* the first component of the file (e.g. "fedora-20.xml.gz) @@ -756,22 +721,19 @@ as_store_guess_origin_fallback (AsStore *store, origin_fallback = g_path_get_basename (filename); tmp = g_strstr_len (origin_fallback, -1, ".xml"); if (tmp == NULL) { - ret = FALSE; g_set_error (error, AS_STORE_ERROR, AS_STORE_ERROR_FAILED, "AppStream metadata name %s not valid, " "expected .xml[.*]", filename); - goto out; + return FALSE; } tmp[0] = '\0'; /* load this specific file */ as_store_set_origin (store, origin_fallback); -out: - g_free (origin_fallback); - return ret; + return TRUE; } /** @@ -784,29 +746,21 @@ as_store_load_app_info_file (AsStore *store, GCancellable *cancellable, GError **error) { - GFile *file = NULL; - gboolean ret = FALSE; + _cleanup_unref_object GFile *file = NULL; /* guess this based on the name */ - ret = as_store_guess_origin_fallback (store, path_xml, error); - if (!ret) - goto out; + if (!as_store_guess_origin_fallback (store, path_xml, error)) + return FALSE; /* load this specific file */ g_debug ("Loading AppStream XML %s with icon path %s", path_xml, icon_root); file = g_file_new_for_path (path_xml); - ret = as_store_from_file (store, - file, - icon_root, - cancellable, - error); - if (!ret) - goto out; -out: - if (file != NULL) - g_object_unref (file); - return ret; + return as_store_from_file (store, + file, + icon_root, + cancellable, + error); } /** @@ -832,10 +786,9 @@ as_store_monitor_directory (AsStore *store, GError **error) { AsStorePrivate *priv = GET_PRIVATE (store); - GError *error_local = NULL; - GFile *file = NULL; - GFileMonitor *monitor = NULL; - gboolean ret = TRUE; + _cleanup_free_error GError *error_local = NULL; + _cleanup_unref_object GFile *file = NULL; + _cleanup_unref_object GFileMonitor *monitor = NULL; file = g_file_new_for_path (path); monitor = g_file_monitor_directory (file, @@ -843,25 +796,18 @@ as_store_monitor_directory (AsStore *store, cancellable, &error_local); if (monitor == NULL) { - ret = FALSE; g_set_error (error, AS_STORE_ERROR, AS_STORE_ERROR_FAILED, "Failed to monitor %s: %s", path, error_local->message); - g_error_free (error_local); - goto out; + return FALSE; } g_signal_connect (monitor, "changed", G_CALLBACK (as_store_cache_changed_cb), store); g_ptr_array_add (priv->file_monitors, g_object_ref (monitor)); -out: - if (monitor != NULL) - g_object_unref (monitor); - if (file != NULL) - g_object_unref (file); - return ret; + return TRUE; } /** @@ -873,52 +819,41 @@ as_store_load_app_info (AsStore *store, GCancellable *cancellable, GError **error) { - GDir *dir = NULL; - GError *error_local = NULL; + _cleanup_close_dir GDir *dir = NULL; + _cleanup_free_error GError *error_local = NULL; + _cleanup_free gchar *icon_root = NULL; + _cleanup_free gchar *path_xml = NULL; const gchar *tmp; - gboolean ret = TRUE; - gchar *filename_xml; - gchar *icon_root = NULL; - gchar *path_xml = NULL; /* watch the directory for changes */ - ret = as_store_monitor_directory (store, path, cancellable, error); - if (!ret) - goto out; + if (!as_store_monitor_directory (store, path, cancellable, error)) + return FALSE; /* search all files */ path_xml = g_build_filename (path, "xmls", NULL); if (!g_file_test (path_xml, G_FILE_TEST_EXISTS)) - goto out; + return TRUE; dir = g_dir_open (path_xml, 0, &error_local); if (dir == NULL) { - ret = FALSE; g_set_error (error, AS_STORE_ERROR, AS_STORE_ERROR_FAILED, "Failed to open %s: %s", path_xml, error_local->message); - g_error_free (error_local); - goto out; + return FALSE; } icon_root = g_build_filename (path, "icons", NULL); while ((tmp = g_dir_read_name (dir)) != NULL) { + _cleanup_free gchar *filename_xml; filename_xml = g_build_filename (path_xml, tmp, NULL); - ret = as_store_load_app_info_file (store, - filename_xml, - icon_root, - cancellable, - error); - g_free (filename_xml); - if (!ret) - goto out; + if (!as_store_load_app_info_file (store, + filename_xml, + icon_root, + cancellable, + error)) + return FALSE; } -out: - if (dir != NULL) - g_dir_close (dir); - g_free (path_xml); - g_free (icon_root); - return ret; + return TRUE; } /** @@ -927,16 +862,16 @@ out: static void as_store_add_app_install_screenshot (AsApp *app) { - AsImage *im = NULL; - AsScreenshot *ss = NULL; GPtrArray *pkgnames; + _cleanup_free gchar *url = NULL; + _cleanup_unref_object AsImage *im = NULL; + _cleanup_unref_object AsScreenshot *ss = NULL; const gchar *pkgname; - gchar *url = NULL; /* get the default package name */ pkgnames = as_app_get_pkgnames (app); if (pkgnames->len == 0) - goto out; + return; pkgname = g_ptr_array_index (pkgnames, 0); url = g_build_filename ("http://screenshots.debian.net/screenshot", pkgname, NULL); @@ -951,12 +886,6 @@ as_store_add_app_install_screenshot (AsApp *app) ss = as_screenshot_new (); as_screenshot_add_image (ss, im); as_app_add_screenshot (app, ss); -out: - if (im != NULL) - g_object_unref (im); - if (ss != NULL) - g_object_unref (ss); - g_free (url); } /** @@ -968,40 +897,34 @@ as_store_load_app_install_file (AsStore *store, const gchar *path_icons, GError **error) { - GError *error_local = NULL; - gboolean ret; - AsApp *app; + _cleanup_free_error GError *error_local = NULL; + _cleanup_unref_object AsApp *app; app = as_app_new (); - ret = as_app_parse_file (app, - filename, - AS_APP_PARSE_FLAG_USE_HEURISTICS, - &error_local); - if (!ret) { + if (!as_app_parse_file (app, + filename, + AS_APP_PARSE_FLAG_USE_HEURISTICS, + &error_local)) { if (g_error_matches (error_local, AS_APP_ERROR, AS_APP_ERROR_INVALID_TYPE)) { /* Ubuntu include non-apps here too... */ - ret = TRUE; - } else { - g_set_error (error, - AS_STORE_ERROR, - AS_STORE_ERROR_FAILED, - "Failed to parse %s: %s", - filename, - error_local->message); + return TRUE; } - g_error_free (error_local); - goto out; + g_set_error (error, + AS_STORE_ERROR, + AS_STORE_ERROR_FAILED, + "Failed to parse %s: %s", + filename, + error_local->message); + return FALSE; } if (as_app_get_icon_kind (app) == AS_ICON_KIND_UNKNOWN) as_app_set_icon_kind (app, AS_ICON_KIND_CACHED); as_app_set_icon_path (app, path_icons, -1); as_store_add_app_install_screenshot (app); as_store_add_app (store, app); -out: - g_object_unref (app); - return ret; + return TRUE; } /** @@ -1013,50 +936,39 @@ as_store_load_app_install (AsStore *store, GCancellable *cancellable, GError **error) { - GError *error_local = NULL; - GDir *dir = NULL; - gboolean ret = TRUE; - gchar *path_desktop = NULL; - gchar *path_icons = NULL; - gchar *filename; + _cleanup_free_error GError *error_local = NULL; + _cleanup_close_dir GDir *dir = NULL; + _cleanup_free gchar *path_desktop = NULL; + _cleanup_free gchar *path_icons = NULL; const gchar *tmp; path_desktop = g_build_filename (path, "desktop", NULL); if (!g_file_test (path_desktop, G_FILE_TEST_EXISTS)) - goto out; + return TRUE; dir = g_dir_open (path_desktop, 0, &error_local); if (dir == NULL) { - ret = FALSE; g_set_error (error, AS_STORE_ERROR, AS_STORE_ERROR_FAILED, "Failed to open %s: %s", path_desktop, error_local->message); - g_error_free (error_local); - goto out; + return FALSE; } path_icons = g_build_filename (path, "icons", NULL); while ((tmp = g_dir_read_name (dir)) != NULL) { + _cleanup_free gchar *filename = NULL; if (!g_str_has_suffix (tmp, ".desktop")) continue; filename = g_build_filename (path_desktop, tmp, NULL); - ret = as_store_load_app_install_file (store, - filename, - path_icons, - error); - g_free (filename); - if (!ret) - goto out; + if (!as_store_load_app_install_file (store, + filename, + path_icons, + error)) + return FALSE; } - -out: - if (dir != NULL) - g_dir_close (dir); - g_free (path_desktop); - g_free (path_icons); - return ret; + return TRUE; } /** @@ -1078,55 +990,50 @@ as_store_load (AsStore *store, GCancellable *cancellable, GError **error) { - GList *app_info = NULL; - GList *l; + _cleanup_unref_ptrarray GPtrArray *app_info = NULL; const gchar * const * data_dirs; const gchar *tmp; gchar *path; guint i; - gboolean ret = TRUE; /* system locations */ + app_info = g_ptr_array_new_with_free_func (g_free); if ((flags & AS_STORE_LOAD_FLAG_APP_INFO_SYSTEM) > 0) { data_dirs = g_get_system_data_dirs (); for (i = 0; data_dirs[i] != NULL; i++) { path = g_build_filename (data_dirs[i], "app-info", NULL); - app_info = g_list_prepend (app_info, path); + g_ptr_array_add (app_info, path); } path = g_build_filename (LOCALSTATEDIR, "lib", "app-info", NULL); - app_info = g_list_prepend (app_info, path); + g_ptr_array_add (app_info, path); path = g_build_filename (LOCALSTATEDIR, "cache", "app-info", NULL); - app_info = g_list_prepend (app_info, path); + g_ptr_array_add (app_info, path); } /* per-user locations */ if ((flags & AS_STORE_LOAD_FLAG_APP_INFO_USER) > 0) { path = g_build_filename (g_get_user_data_dir (), "app-info", NULL); - app_info = g_list_prepend (app_info, path); + g_ptr_array_add (app_info, path); } /* load each app-info path if it exists */ - for (l = app_info; l != NULL; l = l->next) { - tmp = l->data; + for (i = 0; i < app_info->len; i++) { + tmp = g_ptr_array_index (app_info, i); if (!g_file_test (tmp, G_FILE_TEST_EXISTS)) continue; - ret = as_store_load_app_info (store, tmp, cancellable, error); - if (!ret) - goto out; + if (!as_store_load_app_info (store, tmp, cancellable, error)) + return FALSE; } /* ubuntu specific */ if ((flags & AS_STORE_LOAD_FLAG_APP_INSTALL) > 0) { - ret = as_store_load_app_install (store, - "/usr/share/app-install", - cancellable, - error); - if (!ret) - goto out; + if (!as_store_load_app_install (store, + "/usr/share/app-install", + cancellable, + error)) + return FALSE; } -out: - g_list_free_full (app_info, g_free); - return ret; + return TRUE; } /** diff --git a/libappstream-glib/as-utils.c b/libappstream-glib/as-utils.c index 7401b9f..a1e3502 100644 --- a/libappstream-glib/as-utils.c +++ b/libappstream-glib/as-utils.c @@ -34,6 +34,7 @@ #include <string.h> #include <libsoup/soup.h> +#include "as-cleanup.h" #include "as-node.h" #include "as-resources.h" #include "as-utils.h" @@ -75,33 +76,27 @@ as_markup_convert_simple (const gchar *markup, gssize markup_len, GError **error) { - GNode *root = NULL; GNode *tmp; GNode *tmp_c; - GString *str = NULL; + _cleanup_free_string GString *str = NULL; + _cleanup_unref_node GNode *root = NULL; const gchar *tag; const gchar *tag_c; - gboolean ret = TRUE; - gchar *formatted = NULL; /* is this actually markup */ - if (g_strstr_len (markup, markup_len, "<") == NULL) { - formatted = as_strndup (markup, markup_len); - goto out; - } + if (g_strstr_len (markup, markup_len, "<") == NULL) + return as_strndup (markup, markup_len); /* load */ root = as_node_from_xml (markup, markup_len, AS_NODE_FROM_XML_FLAG_NONE, error); - if (root == NULL) { - ret = FALSE; - goto out; - } - str = g_string_sized_new (markup_len); + if (root == NULL) + return NULL; /* format */ + str = g_string_sized_new (markup_len); for (tmp = root->children; tmp != NULL; tmp = tmp->next) { tag = as_node_get_name (tmp); @@ -121,39 +116,28 @@ as_markup_convert_simple (const gchar *markup, as_node_get_data (tmp_c)); } else { /* only <li> is valid in lists */ - ret = FALSE; g_set_error (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, "Tag %s in %s invalid", tag_c, tag); - goto out; + return FALSE; } } } else { /* only <p>, <ul> and <ol> is valid here */ - ret = FALSE; g_set_error (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, "Unknown tag '%s'", tag); - goto out; + return NULL; } } /* success */ if (str->len > 0) g_string_truncate (str, str->len - 1); -out: - if (root != NULL) - as_node_unref (root); - if (str != NULL) { - if (!ret) - g_string_free (str, TRUE); - else - formatted = g_string_free (str, FALSE); - } - return formatted; + return g_strdup (str->str); } /** @@ -181,20 +165,17 @@ as_hash_lookup_by_locale (GHashTable *hash, const gchar *locale) g_return_val_if_fail (hash != NULL, NULL); /* the user specified a locale */ - if (locale != NULL) { - tmp = g_hash_table_lookup (hash, locale); - goto out; - } + if (locale != NULL) + return g_hash_table_lookup (hash, locale); /* use LANGUAGE, LC_ALL, LC_MESSAGES and LANG */ locales = g_get_language_names (); for (i = 0; locales[i] != NULL; i++) { tmp = g_hash_table_lookup (hash, locales[i]); if (tmp != NULL) - goto out; + return tmp; } -out: - return tmp; + return NULL; } /** @@ -211,9 +192,8 @@ out: gboolean as_utils_is_stock_icon_name (const gchar *name) { - GBytes *data; - gboolean ret = FALSE; - gchar *key = NULL; + _cleanup_free gchar *key = NULL; + _cleanup_unref_bytes GBytes *data; /* load the readonly data section and look for the icon name */ data = g_resource_lookup_data (as_get_resource (), @@ -221,14 +201,9 @@ as_utils_is_stock_icon_name (const gchar *name) G_RESOURCE_LOOKUP_FLAGS_NONE, NULL); if (data == NULL) - goto out; + return FALSE; key = g_strdup_printf ("\n%s\n", name); - ret = g_strstr_len (g_bytes_get_data (data, NULL), -1, key) != NULL; -out: - if (data != NULL) - g_bytes_unref (data); - g_free (key); - return ret; + return g_strstr_len (g_bytes_get_data (data, NULL), -1, key) != NULL; } /** @@ -244,9 +219,8 @@ out: gboolean as_utils_is_spdx_license_id (const gchar *license_id) { - GBytes *data; - gboolean ret = FALSE; - gchar *key = NULL; + _cleanup_free gchar *key = NULL; + _cleanup_unref_bytes GBytes *data; /* load the readonly data section and look for the icon name */ data = g_resource_lookup_data (as_get_resource (), @@ -254,14 +228,9 @@ as_utils_is_spdx_license_id (const gchar *license_id) G_RESOURCE_LOOKUP_FLAGS_NONE, NULL); if (data == NULL) - goto out; + return FALSE; key = g_strdup_printf ("\n%s\n", license_id); - ret = g_strstr_len (g_bytes_get_data (data, NULL), -1, key) != NULL; -out: - if (data != NULL) - g_bytes_unref (data); - g_free (key); - return ret; + return g_strstr_len (g_bytes_get_data (data, NULL), -1, key) != NULL; } /** @@ -388,30 +357,26 @@ as_util_get_possible_kudos (void) gboolean as_utils_check_url_exists (const gchar *url, guint timeout, GError **error) { - SoupMessage *msg = NULL; - SoupSession *session = NULL; - SoupURI *base_uri = NULL; - gboolean ret = TRUE; - gint status_code; + _cleanup_unref_object SoupMessage *msg = NULL; + _cleanup_unref_object SoupSession *session = NULL; + _cleanup_unref_uri SoupURI *base_uri = NULL; /* GET file */ base_uri = soup_uri_new (url); if (base_uri == NULL) { - ret = FALSE; g_set_error_literal (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, "URL not valid"); - goto out; + return FALSE; } msg = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri); if (msg == NULL) { - ret = FALSE; g_set_error_literal (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, "Failed to setup message"); - goto out; + return FALSE; } session = soup_session_sync_new_with_options (SOUP_SESSION_USER_AGENT, "libappstream-glib", @@ -419,40 +384,29 @@ as_utils_check_url_exists (const gchar *url, guint timeout, GError **error) timeout, NULL); if (session == NULL) { - ret = FALSE; g_set_error_literal (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, "Failed to set up networking"); - goto out; + return FALSE; } /* send sync */ - status_code = soup_session_send_message (session, msg); - if (status_code != SOUP_STATUS_OK) { - ret = FALSE; + if (soup_session_send_message (session, msg) != SOUP_STATUS_OK) { g_set_error_literal (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, msg->reason_phrase); - goto out; + return FALSE; } /* check if it's a zero sized file */ if (msg->response_body->length == 0) { - ret = FALSE; g_set_error (error, AS_NODE_ERROR, AS_NODE_ERROR_FAILED, "Returned a zero length file"); - goto out; + return FALSE; } -out: - if (session != NULL) - g_object_unref (session); - if (base_uri != NULL) - soup_uri_free (base_uri); - if (msg != NULL) - g_object_unref (msg); - return ret; + return TRUE; } |