]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Migrate grub-mkimage.c to argp.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 3 Feb 2012 20:18:37 +0000 (21:18 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 3 Feb 2012 20:18:37 +0000 (21:18 +0100)
* Makefile.util.def (grub-mkimage): Add util/argp_common.c.
(grub-setup): Likewise.
* util/grub-setup.c (print_version): Move to ...
* util/argp_common.c (print_version): ... here.
* util/grub-setup.c (argp_program_version_hook): Move to ...
* util/argp_common.c (argp_program_version_hook): ... here.
* util/grub-setup.c (argp_parser): Add exit (1) on fatal error for
safety.
* util/grub-mkimage.c (main): Migrate to argp.

ChangeLog
Makefile.util.def
util/argp_common.c [new file with mode: 0644]
util/grub-mkimage.c
util/grub-setup.c

index e5a5d728254d026f45c2662edc937079f7b619b8..431adb41aed65a5e04f8c3ac4750493733708149 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2012-02-03  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Migrate grub-mkimage.c to argp.
+
+       * Makefile.util.def (grub-mkimage): Add util/argp_common.c.
+       (grub-setup): Likewise.
+       * util/grub-setup.c (print_version): Move to ...
+       * util/argp_common.c (print_version): ... here.
+       * util/grub-setup.c (argp_program_version_hook): Move to ...
+       * util/argp_common.c (argp_program_version_hook): ... here.
+       * util/grub-setup.c (argp_parser): Add exit (1) on fatal error for
+       safety.
+       * util/grub-mkimage.c (main): Migrate to argp.
+
 2012-02-03  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * util/grub-mkrescue.in: Use same message as
index 9902584ba911026c7e1c8a4491ad7ce8dea31a6c..2ba7febc6893643fe721f8852b8b85584e0dc756 100644 (file)
@@ -142,6 +142,8 @@ program = {
 
   common = util/grub-mkimage.c;
   common = util/resolve.c;
+  common = util/argp_common.c;
+
   extra_dist = util/grub-mkimagexx.c;
 
   ldadd = libgrubmods.a;
@@ -314,6 +316,7 @@ program = {
   mansection = 8;
   common = util/grub-setup.c;
   common = util/lvm.c;
+  common = util/argp_common.c;
   common = grub-core/lib/reed_solomon.c;
 
   sparc64_ieee1275 = util/ieee1275/ofpath.c;
@@ -349,6 +352,7 @@ program = {
   mansection = 1;
 
   common = util/grub-mklayout.c;
+  common = util/argp_common.c;
 
   ldadd = libgrubmods.a;
   ldadd = libgrubgcry.a;
@@ -502,6 +506,7 @@ script = {
 script = {
   name = grub-kbdcomp;
   common = util/grub-kbdcomp.in;
+  mansection = 1;
 };
 
 script = {
diff --git a/util/argp_common.c b/util/argp_common.c
new file mode 100644 (file)
index 0000000..b1caf1b
--- /dev/null
@@ -0,0 +1,35 @@
+/* grub-setup.c - make GRUB usable */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012  Free Software Foundation, Inc.
+ *
+ *  GRUB is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#define _GNU_SOURCE    1
+#include "progname.h"
+#include <argp.h>
+
+/* Print the version information.  */
+static void
+print_version (FILE *stream, struct argp_state *state)
+{
+  fprintf (stream, "%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
+}
+void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
+
+/* Set the bug report address */
+const char *argp_program_bug_address = "<"PACKAGE_BUGREPORT">";
index 87b15ad1b99231c6c4b3b3cc4759d3c8e334d4fd..72ddb529640cc69bc2cfc2b4ce9d663c6c614047 100644 (file)
@@ -42,7 +42,7 @@
 #include <grub/efi/pe32.h>
 
 #define _GNU_SOURCE    1
-#include <getopt.h>
+#include <argp.h>
 
 #include "progname.h"
 
@@ -1631,227 +1631,240 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
 
 \f
 
-static struct option options[] =
-  {
-    {"directory", required_argument, 0, 'd'},
-    {"prefix", required_argument, 0, 'p'},
-    {"memdisk", required_argument, 0, 'm'},
-    {"font", required_argument, 0, 'f'},
-    {"config", required_argument, 0, 'c'},
-    {"output", required_argument, 0, 'o'},
-    {"note", no_argument, 0, 'n'},
-    {"format", required_argument, 0, 'O'},
-    {"compression", required_argument, 0, 'C'},
-    {"help", no_argument, 0, 'h'},
-    {"version", no_argument, 0, 'V'},
-    {"verbose", no_argument, 0, 'v'},
-    {0, 0, 0, 0}
-  };
+static struct argp_option options[] = {
+  {"directory",  'd', N_("DIR"), 0, N_("use images and modules under DIR [default=%s/@platform@]"), 0},
+  {"prefix",  'p', N_("DIR"), 0, N_("set grub_prefix directory [default=%s]"), 0},
+  {"memdisk",  'm', N_("FILE"), 0, N_("embed FILE as a memdisk image"), 0},
+  {"config",   'c', N_("FILE"), 0, N_("embed FILE as boot config"), 0},
+  {"note",   'n', 0, 0, N_("add NOTE segment for CHRP Open Firmware"), 0},
+  {"output",  'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0},
+  {"format",  'O', N_("FORMAT"), 0, N_("generate an image in format.\navailable formats: %s"), 0},
+  {"compression",  'C', "(xz|none|auto)", 0, N_("choose the compression to use"), 0},
+  {"verbose",     'v', 0,      0, N_("Print verbose messages."), 0},
+  { 0, 0, 0, 0, 0, 0 }
+};
 
-static void
-usage (int status)
+static char *
+help_filter (int key, const char *text, void *input __attribute__ ((unused)))
 {
-  if (status)
-    fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name);
-  else
+  switch (key)
     {
-      int format_len = 0;
-      char *formats;
-      char *ptr;
-      unsigned i;
-      for (i = 0; i < ARRAY_SIZE (image_targets); i++)
-       format_len += strlen (image_targets[i].names[0]) + 2;
-      ptr = formats = xmalloc (format_len);
-      for (i = 0; i < ARRAY_SIZE (image_targets); i++)
-       {
-         strcpy (ptr, image_targets[i].names[0]);
-         ptr += strlen (image_targets[i].names[0]);
-         *ptr++ = ',';
-         *ptr++ = ' ';
-       }
-      ptr[-2] = 0;
-
-      printf (_("\
-Usage: %s [OPTION]... [MODULES]\n\
-\n\
-Make a bootable image of GRUB.\n\
-\n\
-  -d, --directory=DIR     use images and modules under DIR [default=%s/@platform@]\n\
-  -p, --prefix=DIR        set grub_prefix directory [default=%s]\n\
-  -m, --memdisk=FILE      embed FILE as a memdisk image\n\
-  -c, --config=FILE       embed FILE as boot config\n\
-  -n, --note              add NOTE segment for CHRP Open Firmware\n\
-  -o, --output=FILE       output a generated image to FILE [default=stdout]\n\
-  -O, --format=FORMAT     generate an image in format\n\
-                          available formats: %s\n\
-  -C, --compression=(xz|none|auto)  choose the compression to use\n\
-  -h, --help              display this message and exit\n\
-  -V, --version           print version information and exit\n\
-  -v, --verbose           print verbose messages\n\
-\n\
-Report bugs to <%s>.\n\
-"), 
-             program_name, GRUB_PKGLIBROOTDIR, DEFAULT_DIRECTORY,
-             formats,
-             PACKAGE_BUGREPORT);
-      free (formats);
+    case 'd':
+      return xasprintf (text, GRUB_PKGLIBROOTDIR);
+    case 'p':
+      return xasprintf (text, DEFAULT_DIRECTORY);
+    case 'O':
+      {
+       int format_len = 0;
+       char *formats;
+       char *ptr;
+       char *ret;
+       unsigned i;
+       for (i = 0; i < ARRAY_SIZE (image_targets); i++)
+         format_len += strlen (image_targets[i].names[0]) + 2;
+       ptr = formats = xmalloc (format_len);
+       for (i = 0; i < ARRAY_SIZE (image_targets); i++)
+         {
+           strcpy (ptr, image_targets[i].names[0]);
+           ptr += strlen (image_targets[i].names[0]);
+           *ptr++ = ',';
+           *ptr++ = ' ';
+         }
+       ptr[-2] = 0;
+       ret = xasprintf (text, formats);
+       free (formats);
+       return ret;
+      }
+    default:
+      return (char *) text;
     }
-  exit (status);
 }
 
-int
-main (int argc, char *argv[])
+struct arguments
 {
-  char *output = NULL;
-  char *dir = NULL;
-  char *prefix = NULL;
-  char *memdisk = NULL;
-  char *font = NULL;
-  char *config = NULL;
-  FILE *fp = stdout;
-  int note = 0;
-  struct image_target_desc *image_target = NULL;
-  grub_compression_t comp = COMPRESSION_AUTO;
+  size_t nmodules;
+  size_t modules_max;
+  char **modules;
+  char *output;
+  char *dir;
+  char *prefix;
+  char *memdisk;
+  char *font;
+  char *config;
+  int note;
+  struct image_target_desc *image_target;
+  grub_compression_t comp;
+};
 
-  set_program_name (argv[0]);
+static error_t
+argp_parser (int key, char *arg, struct argp_state *state)
+{
+  /* Get the input argument from argp_parse, which we
+     know is a pointer to our arguments structure. */
+  struct arguments *arguments = state->input;
 
-  grub_util_init_nls ();
+  char *p;
 
-  while (1)
+  switch (key)
     {
-      int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:C:hVvn", options, 0);
+    case 'o':
+      if (arguments->output)
+       free (arguments->output);
 
-      if (c == -1)
-       break;
-      else
-       switch (c)
+      arguments->output = xstrdup (arg);
+      break;
+
+    case 'O':
+      {
+       unsigned i, j;
+       for (i = 0; i < ARRAY_SIZE (image_targets); i++)
+         for (j = 0; image_targets[i].names[j]
+                && j < ARRAY_SIZE (image_targets[i].names); j++)
+           if (strcmp (arg, image_targets[i].names[j]) == 0)
+             arguments->image_target = &image_targets[i];
+       if (!arguments->image_target)
          {
-         case 'o':
-           if (output)
-             free (output);
-
-           output = xstrdup (optarg);
-           break;
-
-         case 'O':
-           {
-             unsigned i, j;
-             for (i = 0; i < ARRAY_SIZE (image_targets); i++)
-               for (j = 0; image_targets[i].names[j]
-                      && j < ARRAY_SIZE (image_targets[i].names); j++)
-                 if (strcmp (optarg, image_targets[i].names[j]) == 0)
-                   image_target = &image_targets[i];
-             if (!image_target)
-               {
-                 printf (_("unknown target format %s\n"), optarg);
-                 usage (1);
-               }
-             break;
-           }
-         case 'd':
-           if (dir)
-             free (dir);
+           printf (_("unknown target format %s\n"), arg);
+           argp_usage (state);
+           exit (1);
+         }
+       break;
+      }
+    case 'd':
+      if (arguments->dir)
+       free (arguments->dir);
 
-           dir = xstrdup (optarg);
-           break;
+      arguments->dir = xstrdup (arg);
+      break;
 
-         case 'n':
-           note = 1;
-           break;
+    case 'n':
+      arguments->note = 1;
+      break;
 
-         case 'm':
-           if (memdisk)
-             free (memdisk);
+    case 'm':
+      if (arguments->memdisk)
+       free (arguments->memdisk);
 
-           memdisk = xstrdup (optarg);
+      arguments->memdisk = xstrdup (arg);
 
-           if (prefix)
-             free (prefix);
+      if (arguments->prefix)
+       free (arguments->prefix);
 
-           prefix = xstrdup ("(memdisk)/boot/grub");
-           break;
+      arguments->prefix = xstrdup ("(memdisk)/boot/grub");
+      break;
 
-         case 'c':
-           if (config)
-             free (config);
+    case 'c':
+      if (arguments->config)
+       free (arguments->config);
 
-           config = xstrdup (optarg);
-           break;
+      arguments->config = xstrdup (arg);
+      break;
 
-         case 'C':
-           if (grub_strcmp (optarg, "xz") == 0)
-             {
+    case 'C':
+      if (grub_strcmp (arg, "xz") == 0)
+       {
 #ifdef HAVE_LIBLZMA
-               comp = COMPRESSION_XZ;
+         arguments->comp = COMPRESSION_XZ;
 #else
-               grub_util_error (_("grub-mkimage is compiled without XZ support"),
-                                optarg);
+         grub_util_error (_("grub-mkimage is compiled without XZ support"));
 #endif
-             }
-           else if (grub_strcmp (optarg, "none") == 0)
-             comp = COMPRESSION_NONE;
-           else
-             grub_util_error (_("Unknown compression format %s"), optarg);
-           break;
+       }
+      else if (grub_strcmp (arg, "none") == 0)
+       arguments->comp = COMPRESSION_NONE;
+      else
+       grub_util_error (_("Unknown compression format %s"), arg);
+      break;
+
+    case 'p':
+      if (arguments->prefix)
+       free (arguments->prefix);
+
+      arguments->prefix = xstrdup (arg);
+      break;
+
+    case 'v':
+      verbosity++;
+      break;
+    case ARGP_KEY_ARG:
+      assert (arguments->nmodules < arguments->modules_max);
+      arguments->modules[arguments->nmodules++] = xstrdup(arg);
+      break;
 
-         case 'h':
-           usage (0);
-           break;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
 
-         case 'p':
-           if (prefix)
-             free (prefix);
+static struct argp argp = {
+  options, argp_parser, N_("[OPTION]... [MODULES]"),
+  N_("Make a bootable image of GRUB."),
+  NULL, help_filter, NULL
+};
+
+int
+main (int argc, char *argv[])
+{
+  FILE *fp = stdout;
+  struct arguments arguments;
 
-           prefix = xstrdup (optarg);
-           break;
+  set_program_name (argv[0]);
 
-         case 'V':
-           printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
-           return 0;
+  grub_util_init_nls ();
 
-         case 'v':
-           verbosity++;
-           break;
+  memset (&arguments, 0, sizeof (struct arguments));
+  arguments.comp = COMPRESSION_AUTO;
+  arguments.modules_max = argc + 1;
+  arguments.modules = xmalloc ((arguments.modules_max + 1)
+                            * sizeof (arguments.modules[0]));
+  memset (arguments.modules, 0, (arguments.modules_max + 1)
+         * sizeof (arguments.modules[0]));
 
-         default:
-           usage (1);
-           break;
-         }
+  if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
+    {
+      fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
+      exit(1);
     }
 
-  if (!image_target)
+  if (!arguments.image_target)
     {
+      char *program = xstrdup(program_name);
       printf ("%s", _("Target format not specified (use the -O option).\n"));
-      usage (1);
+      argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program);
+      free (program);
+      exit(1);
     }
 
-  if (output)
+  if (arguments.output)
     {
-      fp = fopen (output, "wb");
+      fp = fopen (arguments.output, "wb");
       if (! fp)
-       grub_util_error (_("cannot open %s"), output);
-      free (output);
+       grub_util_error (_("cannot open %s"), arguments.output);
+      free (arguments.output);
     }
 
-  if (!dir)
+  if (!arguments.dir)
     {
-      dir = xmalloc (sizeof (GRUB_PKGLIBROOTDIR)
-                    + grub_strlen (image_target->dirname) + 1);
-      memcpy (dir, GRUB_PKGLIBROOTDIR, sizeof (GRUB_PKGLIBROOTDIR) - 1);
-      *(dir + sizeof (GRUB_PKGLIBROOTDIR) - 1) = '/';
-      strcpy (dir + sizeof (GRUB_PKGLIBROOTDIR), image_target->dirname);
+      arguments.dir = xmalloc (sizeof (GRUB_PKGLIBROOTDIR)
+                              + grub_strlen (arguments.image_target->dirname)
+                              + 1);
+      memcpy (arguments.dir, GRUB_PKGLIBROOTDIR,
+             sizeof (GRUB_PKGLIBROOTDIR) - 1);
+      *(arguments.dir + sizeof (GRUB_PKGLIBROOTDIR) - 1) = '/';
+      strcpy (arguments.dir + sizeof (GRUB_PKGLIBROOTDIR),
+             arguments.image_target->dirname);
     }
 
-  generate_image (dir, prefix ? : DEFAULT_DIRECTORY, fp,
-                 argv + optind, memdisk, config,
-                 image_target, note, comp);
+  generate_image (arguments.dir, arguments.prefix ? : DEFAULT_DIRECTORY, fp,
+                 arguments.modules, arguments.memdisk, arguments.config,
+                 arguments.image_target, arguments.note, arguments.comp);
 
   fflush (fp);
   fsync (fileno (fp));
   fclose (fp);
 
-  if (dir)
-    free (dir);
+  if (arguments.dir)
+    free (arguments.dir);
 
   return 0;
 }
index 558283dea3247c0148b390ac2f40afacfc9979da..e5a8ced9577d2ad00a6a51e6ec60258b47dde2c2 100644 (file)
@@ -746,8 +746,7 @@ static struct argp_option options[] = {
    N_("Install even if problems are detected"), 0},
   {"skip-fs-probe",'s',0,      0,
    N_("Do not probe for filesystems in DEVICE"), 0},
-  {"verbose",     'v', 0,      0,
-   N_("Print verbose messages."), 0},
+  {"verbose",     'v', 0,      0, N_("Print verbose messages."), 0},
   {"allow-floppy", 'a', 0,      0,
    N_("Make the drive also bootable as floppy (default for fdX devices). May break on some BIOSes."), 0},
 
@@ -788,17 +787,6 @@ struct arguments
   char *device;
 };
 
-/* Print the version information.  */
-static void
-print_version (FILE *stream, struct argp_state *state)
-{
-  fprintf (stream, "%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
-}
-void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
-
-/* Set the bug report address */
-const char *argp_program_bug_address = "<"PACKAGE_BUGREPORT">";
-
 static error_t
 argp_parser (int key, char *arg, struct argp_state *state)
 {
@@ -868,6 +856,7 @@ argp_parser (int key, char *arg, struct argp_state *state)
       case ARGP_KEY_NO_ARGS:
           fprintf (stderr, "%s", _("No device is specified.\n"));
           argp_usage (state);
+         exit (1);
           break;
 
       default: