[gcab] trivial: Use the new autoptr macros to improve the gcab tool



commit 818cff7e4f18f6ca4e6daaa864722c32145b76cf
Author: Richard Hughes <richard hughsie com>
Date:   Thu Dec 14 11:48:53 2017 +0000

    trivial: Use the new autoptr macros to improve the gcab tool
    
    This changes the error handling to correctly deallocate memory and return
    from main() rather than just exit()ing with an error code.

 src/gcab.c |  203 +++++++++++++++++++++++++++++-------------------------------
 1 files changed, 98 insertions(+), 105 deletions(-)
---
diff --git a/src/gcab.c b/src/gcab.c
index 18f5842..4d04ae3 100644
--- a/src/gcab.c
+++ b/src/gcab.c
@@ -1,6 +1,7 @@
 /*
  * LibGCab
  * Copyright (c) 2012, Marc-André Lureau <marcandre lureau gmail com>
+ * Copyright (c) 2017, Richard Hughes <richard hughsie com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -26,20 +27,6 @@
 #include <locale.h>
 #include <glib/gi18n.h>
 
-G_GNUC_PRINTF(1, 2) static void
-gcab_error (const gchar *format, ...)
-{
-    va_list args;
-
-    g_fprintf (stderr, PACKAGE_NAME ": ");
-    va_start(args, format);
-    g_vfprintf (stderr, format, args);
-    va_end(args);
-    g_fprintf (stderr, "\n");
-
-    exit (1);
-}
-
 int verbose = 0;
 
 static gboolean
@@ -52,11 +39,10 @@ file_callback (GCabFile *cabfile, gpointer data)
         return TRUE;
 
     if (file) {
-        gchar *path =  g_file_get_relative_path (cwd, file);
+        g_autofree gchar *path =  g_file_get_relative_path (cwd, file);
         if (!path)
             path = g_file_get_parse_name (file);
         g_print ("%s\n", path);
-        g_free (path);
     } else {
         g_print ("%s\n", gcab_file_get_name (cabfile));
     }
@@ -86,35 +72,35 @@ remove_leading_path (gchar *name)
     return name + i;
 }
 
-static
-void save_array_to_file (const GByteArray *array, const gchar *base, const gchar *suffix)
+static gboolean
+save_array_to_file (const GByteArray *array, const gchar *base, const gchar *suffix, GError **error)
 {
-    GError *error = NULL;
-    gchar *resname = g_strdup_printf ("%s.%s", base, suffix);
+    g_autofree gchar *resname = NULL;
+    g_autoptr(GFile) outputfile = NULL;
+    g_autoptr(GOutputStream) output = NULL;
+    resname = g_strdup_printf ("%s.%s", base, suffix);
     g_print (_("Dumping %s data to: %s ...\n"), suffix, resname);
-    GFile *outputfile = g_file_new_for_commandline_arg (resname);
-    GOutputStream *output = G_OUTPUT_STREAM (g_file_replace (outputfile, NULL, FALSE, 0, NULL, &error));
-
-    if (!error)
-        g_output_stream_write_all (output, array->data, array->len, NULL, NULL, &error);
-
-    if (error)
-        gcab_error (_("can't write file %s: %s"), resname, error->message);
-
-    g_object_unref (output);
-    g_object_unref (outputfile);
-    g_free (resname);
-    g_clear_error (&error);
+    outputfile = g_file_new_for_commandline_arg (resname);
+    output = G_OUTPUT_STREAM (g_file_replace (outputfile, NULL, FALSE, 0, NULL, error));
+    if (output == NULL) {
+        g_prefix_error (error, _("Cannot write file %s: "), resname);
+        return FALSE;
+    }
+    if (!g_output_stream_write_all (output, array->data, array->len, NULL, NULL, error)) {
+        g_prefix_error (error, _("Cannot write file %s: "), resname);
+        return FALSE;
+    }
+    return TRUE;
 }
 
 int
 main (int argc, char *argv[])
 {
-    GError *error = NULL;
-    GOptionContext *context;
+    g_autoptr(GError) error = NULL;
+    g_autoptr(GOptionContext) context = NULL;
 
-    gchar **args = NULL;
-    gchar *change = NULL;
+    g_auto(GStrv) args = NULL;
+    g_autofree gchar *change = NULL;
     gboolean version = FALSE;
     gboolean nopath = FALSE;
     gboolean space = FALSE;
@@ -151,50 +137,59 @@ main (int argc, char *argv[])
     g_set_prgname (PACKAGE_NAME);
 
     context = g_option_context_new (_("- create a Cabinet file"));
-    gchar *s = g_strdup_printf (_("Report bugs to <%s>"), PACKAGE_BUGREPORT);
+    g_autofree gchar *s = g_strdup_printf (_("Report bugs to <%s>"), PACKAGE_BUGREPORT);
     g_option_context_set_description (context, s);
-    g_free(s);
     g_option_context_set_summary (context, _("\
 gcab saves many files together into a cabinet archive, and can restore\n\
 individual files from the archive.\
 "));
     g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
     g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
-    if (!g_option_context_parse (context, &argc, &argv, &error))
-        gcab_error (_("option parsing failed: %s\n"), (error && error->message) ? error->message : "unknown 
error");
-    g_option_context_free(context);
+    if (!g_option_context_parse (context, &argc, &argv, &error)) {
+        g_printerr ("%s: %s\n", _("Option parsing failed"), error->message);
+        return EXIT_FAILURE;
+    }
 
     if (version) {
         g_printf (PACKAGE_STRING "\n");
         return 0;
     }
 
-    if ((list + extract + create + dump_reserved + list_details) != 1)
-        gcab_error (_("Please specify a single operation."));
+    if ((list + extract + create + dump_reserved + list_details) != 1) {
+        g_printerr ("%s\n", _("Please specify a single operation"));
+        return EXIT_FAILURE;
+    }
 
-    if (!args || args[0] == NULL)
-        gcab_error (_("cabinet file must be specified."));
+    if (!args || args[0] == NULL) {
+        g_printerr ("%s\n", _("Cabinet file must be specified"));
+        return EXIT_FAILURE;
+    }
 
-    GCancellable *cancellable = g_cancellable_new ();
-    GCabCabinet *cabinet = gcab_cabinet_new ();
-    GCabFolder *folder;
-    GFile *outputfile;
-    GOutputStream *output;
-    GFile *cwd;
+    g_autoptr(GCabCabinet) cabinet = gcab_cabinet_new ();
+    g_autoptr(GCabFolder) folder = NULL;
+    g_autoptr(GCancellable) cancellable = g_cancellable_new ();
+    g_autoptr(GFile) cwd = NULL;
+    g_autoptr(GFile) outputfile = NULL;
+    g_autoptr(GOutputStream) output = NULL;
 
     if (list || list_details || extract || dump_reserved) {
-        GFile *file = g_file_new_for_commandline_arg (args[0]);
-        GInputStream *in = G_INPUT_STREAM (g_file_read (file, cancellable, &error));
+        g_autoptr(GFile) file = g_file_new_for_commandline_arg (args[0]);
+        g_autoptr(GInputStream) in = G_INPUT_STREAM (g_file_read (file, cancellable, &error));
 
-        if (!in)
-            gcab_error (_("can't open %s for reading: %s\n"), args[0], (error && error->message) ? 
error->message : "unknown error");
-        if (!gcab_cabinet_load (cabinet, in, cancellable, &error))
-            gcab_error (_("error reading %s: %s\n"), args[0], (error && error->message) ? error->message : 
"unknown error");
+        if (in == NULL) {
+            g_printerr ("%s %s: %s\n", _("Cannot open file for reading"), args[0], error->message);
+            return EXIT_FAILURE;
+        }
+        if (!gcab_cabinet_load (cabinet, in, cancellable, &error)) {
+            g_printerr ("%s %s: %s\n", _("Error reading"), args[0], error->message);
+            return EXIT_FAILURE;
+        }
 
         if (list || list_details) {
             GPtrArray *folders = gcab_cabinet_get_folders (cabinet);
             for (guint i = 0; i < folders->len; i++) {
-                GSList *l, *files = gcab_folder_get_files (g_ptr_array_index (folders, i));
+                GSList *l;
+                g_autoptr(GSList) files = gcab_folder_get_files (g_ptr_array_index (folders, i));
 
                 for (l = files; l != NULL; l = l->next) {
                     if (list_details) {
@@ -215,93 +210,91 @@ individual files from the archive.\
                         g_print ("%s\n", gcab_file_get_name (GCAB_FILE (l->data)));
                     }
                 }
-                g_slist_free (files);
             }
         } else if (extract) {
-            g_object_unref (file);
+            g_autoptr(GFile) file2 = NULL;
             if (change == NULL)
                 change = g_get_current_dir ();
-            file = g_file_new_for_path (change);
-
-            if (!gcab_cabinet_extract (cabinet, file, file_callback, NULL, NULL, cancellable, &error))
-                gcab_error (_("error during extraction: %s"), (error && error->message) ? error->message : 
"unknown error");
+            file2 = g_file_new_for_path (change);
+            if (!gcab_cabinet_extract (cabinet, file2, file_callback, NULL, NULL, cancellable, &error)) {
+                g_printerr ("%s: %s\n", _("Error during extraction"), error->message);
+                return EXIT_FAILURE;
+            }
         } else if (dump_reserved) {
-            GByteArray *reserved;
-
+            g_autoptr(GByteArray) reserved = NULL;
             g_object_get (cabinet, "reserved", &reserved, NULL);
             if (reserved != NULL) {
-                save_array_to_file (reserved, args[0], "header");
-                g_byte_array_unref (reserved);
+                if (!save_array_to_file (reserved, args[0], "header", &error)) {
+                    g_printerr ("%s\n", error->message);
+                    return EXIT_FAILURE;
+                }
             }
 
             reserved = (GByteArray *)gcab_cabinet_get_signature (cabinet, cancellable, &error);
-            if (error)
-                gcab_error (_("error while reading signature: %s"), (error && error->message) ? 
error->message : "unknown error");
+            if (reserved == NULL)
+                g_printerr ("%s: %s\n", _("Error while reading signature"), error->message);
             if (reserved != NULL)
-                save_array_to_file (reserved, args[0], "signature");
+                if (!save_array_to_file (reserved, args[0], "signature", &error)) {
+                    g_printerr ("%s\n", error->message);
+                    return EXIT_FAILURE;
+                }
         }
-
-        g_object_unref (in);
-        g_object_unref (file);
-        goto end;
+        return EXIT_SUCCESS;
     }
 
-    if (args[1] == NULL)
-        gcab_error (_("please specify input files."));
+    if (args[1] == NULL) {
+        g_printerr ("%s\n", _("No input files specified"));
+        return EXIT_FAILURE;
+    }
 
     if (space) {
-        GByteArray *reserved = g_byte_array_sized_new (space);
+        g_autoptr(GByteArray) reserved = g_byte_array_sized_new (space);
         g_byte_array_set_size (reserved, space);
         g_object_set (cabinet, "reserved", reserved, NULL);
-        g_byte_array_unref (reserved);
     }
 
     folder = gcab_folder_new (compress ? GCAB_COMPRESSION_MSZIP : 0);
 
     for (gint i = 1; args[i]; i++) {
-        GFile *file = g_file_new_for_commandline_arg (args[i]);
-        gchar *name = nopath ? g_path_get_basename (args[i]) : g_strdup (args[i]);
-        GCabFile *cabfile = gcab_file_new_with_file (
+        g_autoptr(GFile) file = g_file_new_for_commandline_arg (args[i]);
+        g_autofree gchar *name = nopath ? g_path_get_basename (args[i]) : g_strdup (args[i]);
+        g_autoptr(GCabFile) cabfile = gcab_file_new_with_file (
                                  remove_leading_path (name), file);
 
         if (!gcab_folder_add_file (folder, cabfile, TRUE, NULL, &error)) {
-            g_warning (_("Can't add file %s: %s"), args[i], (error && error->message) ? error->message : 
"unknown error");
+            g_warning ("%s %s: %s", _("Cannot add file"), args[i], error->message);
             g_clear_error (&error);
         }
-
-        g_object_unref (cabfile);
-        g_free (name);
-        g_object_unref (file);
     }
 
-    if (gcab_folder_get_nfiles (folder) == 0)
-        gcab_error (_("no files to be archived."));
+    if (gcab_folder_get_nfiles (folder) == 0) {
+        g_printerr ("%s\n", _("No files to be archived"));
+        return EXIT_FAILURE;
+    }
 
     outputfile = g_file_new_for_commandline_arg (args[0]);
     output = G_OUTPUT_STREAM (g_file_replace (outputfile, NULL, FALSE,
                                               0, NULL, &error));
-    if (error)
-        gcab_error (_("can't create cab file %s: %s"), args[0], (error && error->message) ? error->message : 
"unknown error");
+    if (output == NULL) {
+        g_printerr ("%s %s: %s\n", _("Cannot create cab file"), args[0], error->message);
+        return EXIT_FAILURE;
+    }
 
     cwd = g_file_new_for_commandline_arg (".");
-    if (!gcab_cabinet_add_folder (cabinet, folder, &error))
-        gcab_error (_("can't add folder to cab file %s: %s"), args[0], (error && error->message) ? 
error->message : "unknown error");
+    if (!gcab_cabinet_add_folder (cabinet, folder, &error)) {
+        g_printerr ("%s %s: %s\n", _("Cannot add folder to cab file"), args[0], error->message);
+        return EXIT_FAILURE;
+    }
 
     if (!gcab_cabinet_write (cabinet, output,
                              file_callback,
                              NULL,
                              cwd,
                              NULL,
-                             &error))
-        gcab_error (_("can't write cab file %s: %s"), args[0], (error && error->message) ? error->message : 
"unknown error");
-
-    g_object_unref (cwd);
-    g_object_unref (output);
-    g_object_unref (outputfile);
-
-end:
-    g_object_unref (cabinet);
-    g_object_unref (cancellable);
+                             &error)) {
+        g_printerr ("%s %s: %s\n", _("Cannot write cab file"), args[0], error->message);
+        return EXIT_FAILURE;
+    }
 
-    return 0;
+    return EXIT_SUCCESS;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]