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.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-02-03 21:18:37 +01:00
parent 57db0757f4
commit c76899a0ea
5 changed files with 257 additions and 201 deletions

View file

@ -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> 2012-02-03 Vladimir Serbinenko <phcoder@gmail.com>
* util/grub-mkrescue.in: Use same message as * util/grub-mkrescue.in: Use same message as

View file

@ -142,6 +142,8 @@ program = {
common = util/grub-mkimage.c; common = util/grub-mkimage.c;
common = util/resolve.c; common = util/resolve.c;
common = util/argp_common.c;
extra_dist = util/grub-mkimagexx.c; extra_dist = util/grub-mkimagexx.c;
ldadd = libgrubmods.a; ldadd = libgrubmods.a;
@ -314,6 +316,7 @@ program = {
mansection = 8; mansection = 8;
common = util/grub-setup.c; common = util/grub-setup.c;
common = util/lvm.c; common = util/lvm.c;
common = util/argp_common.c;
common = grub-core/lib/reed_solomon.c; common = grub-core/lib/reed_solomon.c;
sparc64_ieee1275 = util/ieee1275/ofpath.c; sparc64_ieee1275 = util/ieee1275/ofpath.c;
@ -349,6 +352,7 @@ program = {
mansection = 1; mansection = 1;
common = util/grub-mklayout.c; common = util/grub-mklayout.c;
common = util/argp_common.c;
ldadd = libgrubmods.a; ldadd = libgrubmods.a;
ldadd = libgrubgcry.a; ldadd = libgrubgcry.a;
@ -502,6 +506,7 @@ script = {
script = { script = {
name = grub-kbdcomp; name = grub-kbdcomp;
common = util/grub-kbdcomp.in; common = util/grub-kbdcomp.in;
mansection = 1;
}; };
script = { script = {

35
util/argp_common.c Normal file
View file

@ -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">";

View file

@ -42,7 +42,7 @@
#include <grub/efi/pe32.h> #include <grub/efi/pe32.h>
#define _GNU_SOURCE 1 #define _GNU_SOURCE 1
#include <getopt.h> #include <argp.h>
#include "progname.h" #include "progname.h"
@ -1631,33 +1631,34 @@ generate_image (const char *dir, char *prefix, FILE *out, char *mods[],
static struct option options[] = static struct argp_option options[] = {
{ {"directory", 'd', N_("DIR"), 0, N_("use images and modules under DIR [default=%s/@platform@]"), 0},
{"directory", required_argument, 0, 'd'}, {"prefix", 'p', N_("DIR"), 0, N_("set grub_prefix directory [default=%s]"), 0},
{"prefix", required_argument, 0, 'p'}, {"memdisk", 'm', N_("FILE"), 0, N_("embed FILE as a memdisk image"), 0},
{"memdisk", required_argument, 0, 'm'}, {"config", 'c', N_("FILE"), 0, N_("embed FILE as boot config"), 0},
{"font", required_argument, 0, 'f'}, {"note", 'n', 0, 0, N_("add NOTE segment for CHRP Open Firmware"), 0},
{"config", required_argument, 0, 'c'}, {"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0},
{"output", required_argument, 0, 'o'}, {"format", 'O', N_("FORMAT"), 0, N_("generate an image in format.\navailable formats: %s"), 0},
{"note", no_argument, 0, 'n'}, {"compression", 'C', "(xz|none|auto)", 0, N_("choose the compression to use"), 0},
{"format", required_argument, 0, 'O'}, {"verbose", 'v', 0, 0, N_("Print verbose messages."), 0},
{"compression", required_argument, 0, 'C'}, { 0, 0, 0, 0, 0, 0 }
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
{"verbose", no_argument, 0, 'v'},
{0, 0, 0, 0}
}; };
static void static char *
usage (int status) help_filter (int key, const char *text, void *input __attribute__ ((unused)))
{ {
if (status) switch (key)
fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name); {
else case 'd':
return xasprintf (text, GRUB_PKGLIBROOTDIR);
case 'p':
return xasprintf (text, DEFAULT_DIRECTORY);
case 'O':
{ {
int format_len = 0; int format_len = 0;
char *formats; char *formats;
char *ptr; char *ptr;
char *ret;
unsigned i; unsigned i;
for (i = 0; i < ARRAY_SIZE (image_targets); i++) for (i = 0; i < ARRAY_SIZE (image_targets); i++)
format_len += strlen (image_targets[i].names[0]) + 2; format_len += strlen (image_targets[i].names[0]) + 2;
@ -1670,67 +1671,47 @@ usage (int status)
*ptr++ = ' '; *ptr++ = ' ';
} }
ptr[-2] = 0; ptr[-2] = 0;
ret = xasprintf (text, formats);
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); free (formats);
return ret;
}
default:
return (char *) text;
} }
exit (status);
} }
int struct arguments
main (int argc, char *argv[])
{ {
char *output = NULL; size_t nmodules;
char *dir = NULL; size_t modules_max;
char *prefix = NULL; char **modules;
char *memdisk = NULL; char *output;
char *font = NULL; char *dir;
char *config = NULL; char *prefix;
FILE *fp = stdout; char *memdisk;
int note = 0; char *font;
struct image_target_desc *image_target = NULL; char *config;
grub_compression_t comp = COMPRESSION_AUTO; 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)
grub_util_init_nls ();
while (1)
{ {
int c = getopt_long (argc, argv, "d:p:m:c:o:O:f:C:hVvn", options, 0); /* Get the input argument from argp_parse, which we
know is a pointer to our arguments structure. */
struct arguments *arguments = state->input;
if (c == -1) char *p;
break;
else switch (key)
switch (c)
{ {
case 'o': case 'o':
if (output) if (arguments->output)
free (output); free (arguments->output);
output = xstrdup (optarg); arguments->output = xstrdup (arg);
break; break;
case 'O': case 'O':
@ -1739,119 +1720,151 @@ main (int argc, char *argv[])
for (i = 0; i < ARRAY_SIZE (image_targets); i++) for (i = 0; i < ARRAY_SIZE (image_targets); i++)
for (j = 0; image_targets[i].names[j] for (j = 0; image_targets[i].names[j]
&& j < ARRAY_SIZE (image_targets[i].names); j++) && j < ARRAY_SIZE (image_targets[i].names); j++)
if (strcmp (optarg, image_targets[i].names[j]) == 0) if (strcmp (arg, image_targets[i].names[j]) == 0)
image_target = &image_targets[i]; arguments->image_target = &image_targets[i];
if (!image_target) if (!arguments->image_target)
{ {
printf (_("unknown target format %s\n"), optarg); printf (_("unknown target format %s\n"), arg);
usage (1); argp_usage (state);
exit (1);
} }
break; break;
} }
case 'd': case 'd':
if (dir) if (arguments->dir)
free (dir); free (arguments->dir);
dir = xstrdup (optarg); arguments->dir = xstrdup (arg);
break; break;
case 'n': case 'n':
note = 1; arguments->note = 1;
break; break;
case 'm': case 'm':
if (memdisk) if (arguments->memdisk)
free (memdisk); free (arguments->memdisk);
memdisk = xstrdup (optarg); arguments->memdisk = xstrdup (arg);
if (prefix) if (arguments->prefix)
free (prefix); free (arguments->prefix);
prefix = xstrdup ("(memdisk)/boot/grub"); arguments->prefix = xstrdup ("(memdisk)/boot/grub");
break; break;
case 'c': case 'c':
if (config) if (arguments->config)
free (config); free (arguments->config);
config = xstrdup (optarg); arguments->config = xstrdup (arg);
break; break;
case 'C': case 'C':
if (grub_strcmp (optarg, "xz") == 0) if (grub_strcmp (arg, "xz") == 0)
{ {
#ifdef HAVE_LIBLZMA #ifdef HAVE_LIBLZMA
comp = COMPRESSION_XZ; arguments->comp = COMPRESSION_XZ;
#else #else
grub_util_error (_("grub-mkimage is compiled without XZ support"), grub_util_error (_("grub-mkimage is compiled without XZ support"));
optarg);
#endif #endif
} }
else if (grub_strcmp (optarg, "none") == 0) else if (grub_strcmp (arg, "none") == 0)
comp = COMPRESSION_NONE; arguments->comp = COMPRESSION_NONE;
else else
grub_util_error (_("Unknown compression format %s"), optarg); grub_util_error (_("Unknown compression format %s"), arg);
break;
case 'h':
usage (0);
break; break;
case 'p': case 'p':
if (prefix) if (arguments->prefix)
free (prefix); free (arguments->prefix);
prefix = xstrdup (optarg); arguments->prefix = xstrdup (arg);
break; break;
case 'V':
printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
return 0;
case 'v': case 'v':
verbosity++; verbosity++;
break; break;
case ARGP_KEY_ARG:
assert (arguments->nmodules < arguments->modules_max);
arguments->modules[arguments->nmodules++] = xstrdup(arg);
break;
default: default:
usage (1); return ARGP_ERR_UNKNOWN;
break;
} }
return 0;
} }
if (!image_target) 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;
set_program_name (argv[0]);
grub_util_init_nls ();
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]));
if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
{
fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
exit(1);
}
if (!arguments.image_target)
{
char *program = xstrdup(program_name);
printf ("%s", _("Target format not specified (use the -O option).\n")); 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) if (! fp)
grub_util_error (_("cannot open %s"), output); grub_util_error (_("cannot open %s"), arguments.output);
free (output); free (arguments.output);
} }
if (!dir) if (!arguments.dir)
{ {
dir = xmalloc (sizeof (GRUB_PKGLIBROOTDIR) arguments.dir = xmalloc (sizeof (GRUB_PKGLIBROOTDIR)
+ grub_strlen (image_target->dirname) + 1); + grub_strlen (arguments.image_target->dirname)
memcpy (dir, GRUB_PKGLIBROOTDIR, sizeof (GRUB_PKGLIBROOTDIR) - 1); + 1);
*(dir + sizeof (GRUB_PKGLIBROOTDIR) - 1) = '/'; memcpy (arguments.dir, GRUB_PKGLIBROOTDIR,
strcpy (dir + sizeof (GRUB_PKGLIBROOTDIR), image_target->dirname); 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, generate_image (arguments.dir, arguments.prefix ? : DEFAULT_DIRECTORY, fp,
argv + optind, memdisk, config, arguments.modules, arguments.memdisk, arguments.config,
image_target, note, comp); arguments.image_target, arguments.note, arguments.comp);
fflush (fp); fflush (fp);
fsync (fileno (fp)); fsync (fileno (fp));
fclose (fp); fclose (fp);
if (dir) if (arguments.dir)
free (dir); free (arguments.dir);
return 0; return 0;
} }

View file

@ -746,8 +746,7 @@ static struct argp_option options[] = {
N_("Install even if problems are detected"), 0}, N_("Install even if problems are detected"), 0},
{"skip-fs-probe",'s',0, 0, {"skip-fs-probe",'s',0, 0,
N_("Do not probe for filesystems in DEVICE"), 0}, N_("Do not probe for filesystems in DEVICE"), 0},
{"verbose", 'v', 0, 0, {"verbose", 'v', 0, 0, N_("Print verbose messages."), 0},
N_("Print verbose messages."), 0},
{"allow-floppy", 'a', 0, 0, {"allow-floppy", 'a', 0, 0,
N_("Make the drive also bootable as floppy (default for fdX devices). May break on some BIOSes."), 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; 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 static error_t
argp_parser (int key, char *arg, struct argp_state *state) 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: case ARGP_KEY_NO_ARGS:
fprintf (stderr, "%s", _("No device is specified.\n")); fprintf (stderr, "%s", _("No device is specified.\n"));
argp_usage (state); argp_usage (state);
exit (1);
break; break;
default: default: