]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* util/grub-mkfont.c: Migrate to argp.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 3 Feb 2012 20:45:43 +0000 (21:45 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 3 Feb 2012 20:45:43 +0000 (21:45 +0100)
* util/grub-mklayout.c: Likewise.
* util/grub-mkpasswd-pbkdf2.c: Likewise.
* util/grub-mkrelpath.c: Likewise.
* util/grub-probe.c: Likewise.
* util/grub-script-check.c: Likewise.

ChangeLog
Makefile.util.def
util/grub-mkfont.c
util/grub-mklayout.c
util/grub-mkpasswd-pbkdf2.c
util/grub-mkrelpath.c
util/grub-probe.c
util/grub-script-check.c

index 8407efe0b10d66a0062792d8c2d5c88ab55c36a6..c2a12984f798d92ca5001d4b01d7ab651c463b03 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2012-02-03  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       * util/grub-mkfont.c: Migrate to argp.
+       * util/grub-mklayout.c: Likewise.
+       * util/grub-mkpasswd-pbkdf2.c: Likewise.
+       * util/grub-mkrelpath.c: Likewise.
+       * util/grub-probe.c: Likewise.
+       * util/grub-script-check.c: Likewise.
+
 2012-02-03  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * util/grub-reboot.in: Add missing datarootdir.
index 2ba7febc6893643fe721f8852b8b85584e0dc756..843c3ea60d5ab9ce2ba83b7b317ef9b604457bd8 100644 (file)
@@ -160,6 +160,7 @@ program = {
   mansection = 1;
 
   common = util/grub-mkrelpath.c;
+  common = util/argp_common.c;
 
   ldadd = libgrubmods.a;
   ldadd = libgrubgcry.a;
@@ -173,6 +174,7 @@ program = {
   mansection = 1;
 
   common = util/grub-script-check.c;
+  common = util/argp_common.c;
 
   ldadd = libgrubmods.a;
   ldadd = libgrubgcry.a;
@@ -199,6 +201,7 @@ program = {
   mansection = 1;
 
   common = util/grub-mkpasswd-pbkdf2.c;
+  common = util/argp_common.c;
 
   ldadd = libgrubmods.a;
   ldadd = libgrubgcry.a;
@@ -268,6 +271,7 @@ program = {
   mansection = 1;
   common = util/grub-mkfont.c;
   common = grub-core/unidata.c;
+  common = util/argp_common.c;
 
   cflags = '$(freetype_cflags)';
 
@@ -302,6 +306,7 @@ program = {
   mansection = 8;
   common = util/grub-probe.c;
   common = util/ieee1275/ofpath.c;
+  common = util/argp_common.c;
 
   ldadd = libgrubmods.a;
   ldadd = libgrubgcry.a;
index 1fad15660830101b9d8228ed01b198e9554c5e1b..58eca093a7d260bb34ef7a8a25ee63679065af11 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <getopt.h>
+
+#define _GNU_SOURCE    1
+#include <argp.h>
+#include <assert.h>
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
@@ -94,60 +97,7 @@ struct grub_font_info
   int num_glyphs;
 };
 
-static struct option options[] =
-{
-  {"output", required_argument, 0, 'o'},
-  {"name", required_argument, 0, 'n'},
-  {"index", required_argument, 0, 'i'},
-  {"range", required_argument, 0, 'r'},
-  {"size", required_argument, 0, 's'},
-  {"desc", required_argument, 0, 'd'},
-  {"asce", required_argument, 0, 'c'},
-  {"bold", no_argument, 0, 'b'},
-  {"no-bitmap", no_argument, 0, 0x100},
-  {"no-hinting", no_argument, 0, 0x101},
-  {"force-autohint", no_argument, 0, 'a'},
-  {"help", no_argument, 0, 'h'},
-  {"version", no_argument, 0, 'V'},
-  {"verbose", no_argument, 0, 'v'},
-  {"ascii-bitmaps", no_argument, 0, 0x102},
-  {"width-spec", no_argument, 0, 0x103},
-  {0, 0, 0, 0}
-};
-
-int font_verbosity;
-
-static void
-usage (int status)
-{
-  if (status)
-    fprintf (stderr, _("Try `%s --help' for more information.\n"),
-            program_name);
-  else
-    printf (_("\
-Usage: %s [OPTIONS] FONT_FILES\n\
-\nOptions:\n\
-  -o, --output=FILE_NAME    set output file name\n\
-  --ascii-bitmaps           save only the ASCII bitmaps\n\
-  --width-spec              create width summary file\n\
-  -i, --index=N             set face index\n\
-  -r, --range=A-B[,C-D]     set font range\n\
-  -n, --name=S              set font family name\n\
-  -s, --size=N              set font size\n\
-  -d, --desc=N              set font descent\n\
-  -c, --asce=N              set font ascent\n\
-  -b, --bold                convert to bold font\n\
-  -a, --force-autohint      force autohint\n\
-  --no-hinting              disable hinting\n\
-  --no-bitmap               ignore bitmap strikes when loading\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, PACKAGE_BUGREPORT);
-
-  exit (status);
-}
+static int font_verbosity;
 
 void
 add_pixel (grub_uint8_t **data, int *mask, int not_blank)
@@ -996,167 +946,213 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file)
   fclose (file);
 }
 
-int
-main (int argc, char *argv[])
+static struct argp_option options[] = {
+  {"output",  'o', N_("FILE"), 0, N_("set output file"), 0},
+  {"ascii-bitmaps",  0x102, 0, 0, N_("save only the ASCII bitmaps"), 0},
+  {"width-spec",  0x103, 0, 0, N_("create width summary file"), 0},
+  {"index",  'i', N_("NUM"), 0, N_("set face index"), 0},
+  {"range",  'r', N_("FROM-TO[,FROM-TO]"), 0, N_("set font range"), 0},
+  {"name",  'n', N_("NAME"), 0, N_("set font family name"), 0},
+  {"size",  's', N_("STR"), 0, N_("set font size"), 0},
+  {"desc",  'd', N_("NUM"), 0, N_("set font descent"), 0},
+  {"asce",  'c', N_("NUM"), 0, N_("set font ascent"), 0},
+  {"bold",  'b', 0, 0, N_("convert to bold font"), 0},
+  {"force-autohint",  'a', 0, 0, N_("force autohint"), 0},
+  {"no-hinting",  0x101, 0, 0, N_("disable hinting"), 0},
+  {"no-bitmap",  0x100, 0, 0, N_("ignore bitmap strikes when loading"), 0},
+  {"verbose",  'v', 0, 0, N_("print verbose messages."), 0},
+  { 0, 0, 0, 0, 0, 0 }
+};
+
+struct arguments
 {
   struct grub_font_info font_info;
-  FT_Library ft_lib;
-  int font_index = 0;
-  int font_size = 0;
-  char *output_file = NULL;
-  enum file_formats file_format = PF2;
-
-  memset (&font_info, 0, sizeof (font_info));
+  size_t nfiles;
+  size_t files_max;
+  char **files;
+  char *output_file;
+  int font_index;
+  int font_size;
+  enum file_formats file_format;
+};
 
-  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;
 
-  /* Check for options.  */
-  while (1)
+  switch (key)
     {
-      int c = getopt_long (argc, argv, "bao:n:i:s:d:r:hVv", options, 0);
-
-      if (c == -1)
-       break;
-      else
-       switch (c)
-         {
-         case 'b':
-           font_info.flags |= GRUB_FONT_FLAG_BOLD;
-           break;
+    case 'b':
+      arguments->font_info.flags |= GRUB_FONT_FLAG_BOLD;
+      break;
 
-         case 0x100:
-           font_info.flags |= GRUB_FONT_FLAG_NOBITMAP;
-           break;
+    case 0x100:
+      arguments->font_info.flags |= GRUB_FONT_FLAG_NOBITMAP;
+      break;
 
-         case 0x101:
-           font_info.flags |= GRUB_FONT_FLAG_NOHINTING;
-           break;
+    case 0x101:
+      arguments->font_info.flags |= GRUB_FONT_FLAG_NOHINTING;
+      break;
 
-         case 'a':
-           font_info.flags |= GRUB_FONT_FLAG_FORCEHINT;
-           break;
+    case 'a':
+      arguments->font_info.flags |= GRUB_FONT_FLAG_FORCEHINT;
+      break;
 
-         case 'o':
-           output_file = optarg;
-           break;
+    case 'o':
+      arguments->output_file = xstrdup (arg);
+      break;
 
-         case 'n':
-           font_info.name = optarg;
-           break;
+    case 'n':
+      arguments->font_info.name = xstrdup (arg);
+      break;
 
-         case 'i':
-           font_index = strtoul (optarg, NULL, 0);
-           break;
+    case 'i':
+      arguments->font_index = strtoul (arg, NULL, 0);
+      break;
 
-         case 's':
-           font_size = strtoul (optarg, NULL, 0);
-           break;
+    case 's':
+      arguments->font_size = strtoul (arg, NULL, 0);
+      break;
 
-         case 'r':
-           {
-             char *p = optarg;
+    case 'r':
+      {
+       char *p = arg;
 
-             while (1)
-               {
-                 grub_uint32_t a, b;
-
-                 a = strtoul (p, &p, 0);
-                 if (*p != '-')
-                   grub_util_error (_("invalid font range"));
-                 b = strtoul (p + 1, &p, 0);
-                 if ((font_info.num_range & (GRUB_FONT_RANGE_BLOCK - 1)) == 0)
-                   font_info.ranges = xrealloc (font_info.ranges,
-                                                (font_info.num_range +
-                                                 GRUB_FONT_RANGE_BLOCK) *
-                                                sizeof (grub_uint32_t) * 2);
-
-                 font_info.ranges[font_info.num_range * 2] = a;
-                 font_info.ranges[font_info.num_range * 2 + 1] = b;
-                 font_info.num_range++;
-
-                 if (*p)
-                   {
-                     if (*p != ',')
-                       grub_util_error (_("invalid font range"));
-                     else
-                       p++;
-                   }
-                 else
-                   break;
-               }
+       while (1)
+         {
+           grub_uint32_t a, b;
+
+           a = strtoul (p, &p, 0);
+           if (*p != '-')
+             grub_util_error (_("invalid font range"));
+           b = strtoul (p + 1, &p, 0);
+           if ((arguments->font_info.num_range
+                & (GRUB_FONT_RANGE_BLOCK - 1)) == 0)
+             arguments->font_info.ranges = xrealloc (arguments->font_info.ranges,
+                                                     (arguments->font_info.num_range +
+                                                      GRUB_FONT_RANGE_BLOCK) *
+                                                     sizeof (grub_uint32_t) * 2);
+
+           arguments->font_info.ranges[arguments->font_info.num_range * 2] = a;
+           arguments->font_info.ranges[arguments->font_info.num_range * 2 + 1] = b;
+           arguments->font_info.num_range++;
+
+           if (*p)
+             {
+               if (*p != ',')
+                 grub_util_error (_("invalid font range"));
+               else
+                 p++;
+             }
+           else
              break;
-           }
+         }
+       break;
+      }
 
-         case 'd':
-           font_info.desc = strtoul (optarg, NULL, 0);
-           break;
+    case 'd':
+      arguments->font_info.desc = strtoul (arg, NULL, 0);
+      break;
 
-         case 'e':
-           font_info.asce = strtoul (optarg, NULL, 0);
-           break;
+    case 'e':
+      arguments->font_info.asce = strtoul (arg, NULL, 0);
+      break;
 
-         case 'h':
-           usage (0);
-           break;
+    case 'v':
+      font_verbosity++;
+      break;
 
-         case 'V':
-           printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
-           return 0;
+    case 0x102:
+      arguments->file_format = ASCII_BITMAPS;
+      break;
 
-         case 'v':
-           font_verbosity++;
-           break;
+    case 0x103:
+      arguments->file_format = WIDTH_SPEC;
+      break;
 
-         case 0x102:
-            file_format = ASCII_BITMAPS;
-            break;
+    case ARGP_KEY_ARG:
+      assert (arguments->nfiles < arguments->files_max);
+      arguments->files[arguments->nfiles++] = xstrdup(arg);
+      break;
 
-         case 0x103:
-            file_format = WIDTH_SPEC;
-            break;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
 
-         default:
-           usage (1);
-           break;
-         }
+static struct argp argp = {
+  options, argp_parser, N_("[OPTIONS] FONT_FILES"),
+  N_("Convert common font file formats into PF2"),
+  NULL, NULL, NULL
+};
+
+int
+main (int argc, char *argv[])
+{
+  FT_Library ft_lib;
+  struct arguments arguments;
+  size_t i;
+
+  set_program_name (argv[0]);
+
+  grub_util_init_nls ();
+
+  memset (&arguments, 0, sizeof (struct arguments));
+  arguments.file_format = PF2;
+  arguments.files_max = argc + 1;
+  arguments.files = xmalloc ((arguments.files_max + 1)
+                            * sizeof (arguments.files[0]));
+  memset (arguments.files, 0, (arguments.files_max + 1)
+         * sizeof (arguments.files[0]));
+
+  if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
+    {
+      fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
+      exit(1);
     }
 
-  if (file_format == ASCII_BITMAPS && font_info.num_range > 0)
+  if (arguments.file_format == ASCII_BITMAPS
+      && arguments.font_info.num_range > 0)
     {
       grub_util_error (_("Option --ascii-bitmaps doesn't accept ranges (use ASCII)."));
       return 1;
     }
-
-  else if (file_format == ASCII_BITMAPS)
+  else if (arguments.file_format == ASCII_BITMAPS)
     {
-      font_info.ranges = xrealloc (font_info.ranges,
-                                  GRUB_FONT_RANGE_BLOCK *
-                                  sizeof (grub_uint32_t) * 2);
-
-      font_info.ranges[0] = (grub_uint32_t) 0x00;
-      font_info.ranges[1] = (grub_uint32_t) 0x7f;
-      font_info.num_range = 1;
+      arguments.font_info.ranges = xrealloc (arguments.font_info.ranges,
+                                            GRUB_FONT_RANGE_BLOCK *
+                                            sizeof (grub_uint32_t) * 2);
+         
+      arguments.font_info.ranges[0] = (grub_uint32_t) 0x00;
+      arguments.font_info.ranges[1] = (grub_uint32_t) 0x7f;
+      arguments.font_info.num_range = 1;
     }
 
-  if (! output_file)
+  if (! arguments.output_file)
     grub_util_error (_("no output file is specified"));
 
   if (FT_Init_FreeType (&ft_lib))
     grub_util_error (_("FT_Init_FreeType fails"));
-
-  for (; optind < argc; optind++)
+      
+  for (i = 0; i < arguments.nfiles; i++)
     {
       FT_Face ft_face;
       int size;
       FT_Error err;
 
-      err = FT_New_Face (ft_lib, argv[optind], font_index, &ft_face);
+      err = FT_New_Face (ft_lib, arguments.files[i],
+                        arguments.font_index, &ft_face);
       if (err)
        {
          grub_printf (_("can't open file %s, index %d: error %d"),
-                      argv[optind], font_index, err);
+                      arguments.files[i],
+                      arguments.font_index, err);
          if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs))
            printf (": %s\n", ft_errmsgs[err]);
          else
@@ -1165,10 +1161,10 @@ main (int argc, char *argv[])
          continue;
        }
 
-      if ((! font_info.name) && (ft_face->family_name))
-       font_info.name = xstrdup (ft_face->family_name);
+      if ((! arguments.font_info.name) && (ft_face->family_name))
+       arguments.font_info.name = xstrdup (ft_face->family_name);
 
-      size = font_size;
+      size = arguments.font_size;
       if (! size)
        {
          if ((ft_face->face_flags & FT_FACE_FLAG_SCALABLE) ||
@@ -1178,12 +1174,13 @@ main (int argc, char *argv[])
            size = ft_face->available_sizes[0].height;
        }
 
-      font_info.style = ft_face->style_flags;
-      font_info.size = size;
+      arguments.font_info.style = ft_face->style_flags;
+      arguments.font_info.size = size;
 
       if (FT_Set_Pixel_Sizes (ft_face, size, size))
-       grub_util_error (_("can't set %dx%d font size"), size, size);
-      add_font (&font_info, ft_face, file_format != PF2);
+       grub_util_error (_("can't set %dx%d font size"),
+                        size, size);
+      add_font (&arguments.font_info, ft_face, arguments.file_format != PF2);
       FT_Done_Face (ft_face);
     }
 
@@ -1196,46 +1193,52 @@ main (int argc, char *argv[])
 
     memset (counter, 0, sizeof (counter));
 
-    for (cur = font_info.glyphs_unsorted; cur; cur = cur->next)
+    for (cur = arguments.font_info.glyphs_unsorted; cur; cur = cur->next)
       counter[(cur->char_code & 0xffff) + 1]++;
     for (i = 0; i < 0x10000; i++)
       counter[i+1] += counter[i];
-    tmp = xmalloc (font_info.num_glyphs
+    tmp = xmalloc (arguments.font_info.num_glyphs
                   * sizeof (tmp[0]));
-    for (cur = font_info.glyphs_unsorted; cur; cur = cur->next)
+    for (cur = arguments.font_info.glyphs_unsorted; cur; cur = cur->next)
       tmp[counter[(cur->char_code & 0xffff)]++] = *cur;
 
     memset (counter, 0, sizeof (counter));
 
-    for (cur = tmp; cur < tmp + font_info.num_glyphs; cur++)
+    for (cur = tmp; cur < tmp + arguments.font_info.num_glyphs; cur++)
       counter[((cur->char_code & 0xffff0000) >> 16) + 1]++;
     for (i = 0; i < 0x10000; i++)
       counter[i+1] += counter[i];
-    font_info.glyphs_sorted = xmalloc (font_info.num_glyphs
-                                       * sizeof (font_info.glyphs_sorted[0]));
-    for (cur = tmp; cur < tmp + font_info.num_glyphs; cur++)
-      font_info.glyphs_sorted[counter[(cur->char_code & 0xffff0000) >> 16]++]
-       = *cur;
+    arguments.font_info.glyphs_sorted = xmalloc (arguments.font_info.num_glyphs
+                                                * sizeof (arguments.font_info.glyphs_sorted[0]));
+    for (cur = tmp; cur < tmp + arguments.font_info.num_glyphs; cur++)
+      arguments.font_info.glyphs_sorted[counter[(cur->char_code & 0xffff0000)
+                                               >> 16]++] = *cur;
     free (tmp);
   }
 
-  switch (file_format)
+  switch (arguments.file_format)
     {
     case PF2:
-      write_font_pf2 (&font_info, output_file);
+      write_font_pf2 (&arguments.font_info, arguments.output_file);
       break;
 
     case ASCII_BITMAPS:
-      write_font_ascii_bitmap (&font_info, output_file);
+      write_font_ascii_bitmap (&arguments.font_info, arguments.output_file);
       break;
 
     case WIDTH_SPEC:
-      write_font_width_spec (&font_info, output_file);
+      write_font_width_spec (&arguments.font_info, arguments.output_file);
       break;
     }
 
   if (font_verbosity > 1)
-    print_glyphs (&font_info);
+    print_glyphs (&arguments.font_info);
+
+  {
+    size_t i;
+    for (i = 0; i < arguments.nfiles; i++)
+      free (arguments.files[i]);
+  }
 
   return 0;
 }
index 8de07747dd715ae4b967913ef62f5ead91fbda91..f31b660a9da394758843e01415f41293880ac404 100644 (file)
 #include <grub/term.h>
 #include <grub/keyboard_layouts.h>
 
+#define _GNU_SOURCE    1
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <getopt.h>
+#include <argp.h>
 #include <unistd.h>
 #include <errno.h>
 
 #include "progname.h"
 
-#define CKBCOMP "ckbcomp"
+struct arguments
+{
+  char *input;
+  char *output;
+  int verbosity;
+};
 
-static struct option options[] = {
-  {"output", required_argument, 0, 'o'},
-  {"help", no_argument, 0, 'h'},
-  {"version", no_argument, 0, 'V'},
-  {"verbose", no_argument, 0, 'v'},
-  {0, 0, 0, 0}
+static struct argp_option options[] = {
+  {"input",  'i', N_("FILE"), 0,
+   N_("set input filename. Default is STDIN"), 0},
+  {"output",  'o', N_("FILE"), 0,
+   N_("set output filename. Default is STDOUT"), 0},
+  {"verbose",     'v', 0,      0, N_("Print verbose messages."), 0},
+  { 0, 0, 0, 0, 0, 0 }
 };
 
 struct console_grub_equivalence
@@ -264,11 +272,6 @@ usage (int status)
   else
     printf (_("\
 Usage: %s [OPTIONS]\n\
-  -i, --input          set input filename. Default is STDIN\n\
-  -o, --output         set output filename. Default is STDOUT\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, PACKAGE_BUGREPORT);
 
@@ -414,8 +417,7 @@ write_keymaps (FILE *in, FILE *out)
 
   if (ok == 0)
     {
-      fprintf (stderr, _("ERROR: no keycodes found. Check output of %s.\n"),
-              CKBCOMP);
+      fprintf (stderr, "%s", _("ERROR: no keycodes found. Check the input.\n"));
       exit (1);
     }
 
@@ -424,65 +426,68 @@ write_keymaps (FILE *in, FILE *out)
   write_file (out, &layout);
 }
 
+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;
+
+  char *p;
+
+  switch (key)
+    {
+    case 'i':
+      arguments->input = xstrdup (arg);
+      break;
+
+    case 'o':
+      arguments->output = xstrdup (arg);
+      break;
+
+    case 'v':
+      arguments->verbosity++;
+      break;
+
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+
+  return 0;
+}
+
+static struct argp argp = {
+  options, argp_parser, N_("[OPTIONS]"),
+  N_("Generate GRUB keyboard layout from Linux console one."),
+  NULL, NULL, NULL
+};
+
 int
 main (int argc, char *argv[])
 {
-  int verbosity;
-  char *infile_name = NULL;
-  char *outfile_name = NULL;
   FILE *in, *out;
+  struct arguments arguments;
 
   set_program_name (argv[0]);
 
-  verbosity = 0;
-
   /* Check for options.  */
-  while (1)
+  memset (&arguments, 0, sizeof (struct arguments));
+  if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
     {
-      int c = getopt_long (argc, argv, "o:i:hVv", options, 0);
-
-      if (c == -1)
-       break;
-      else
-       switch (c)
-         {
-         case 'h':
-           usage (0);
-           break;
-
-         case 'i':
-           infile_name = optarg;
-           break;
-
-         case 'o':
-           outfile_name = optarg;
-           break;
-
-         case 'V':
-           printf ("%s (%s) %s\n", program_name, PACKAGE_NAME,
-                   PACKAGE_VERSION);
-           return 0;
-
-         case 'v':
-           verbosity++;
-           break;
-
-         default:
-           usage (1);
-           break;
-         }
+      fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
+      exit(1);
     }
 
-  if (infile_name)
-    in = fopen (infile_name, "r");
+  if (arguments.input)
+    in = fopen (arguments.input, "r");
   else
     in = stdin;
 
   if (!in)
     grub_util_error (_("Couldn't open input file: %s\n"), strerror (errno));
 
-  if (outfile_name)
-    out = fopen (outfile_name, "wb");
+  if (arguments.output)
+    out = fopen (arguments.output, "wb");
   else
     out = stdout;
 
index 9c676a10054b6fb1392d6e7c614792203ce50fe1..2f5cc920a9735ed6bba71a39d5a2d0115a664770 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <getopt.h>
+
+#define _GNU_SOURCE    1
+
+#include <argp.h>
 
 #include "progname.h"
 
-static struct option options[] =
-  {
-    {"iteration_count", required_argument, 0, 'c'},
-    {"buflen", required_argument, 0, 'l'},
-    {"saltlen", required_argument, 0, 's'},
-    {"help", no_argument, 0, 'h'},
-    {"version", no_argument, 0, 'V'},
-  };
+static struct argp_option options[] = {
+  {"iteration-count",  'c', N_("NUM"), 0, N_("Number of PBKDF2 iterations"), 0},
+  {"buflen",  'l', N_("NUM"), 0, N_("Length of generated hash"), 0},
+  {"salt",  's', N_("NUM"), 0, N_("Length of salt"), 0},
+  { 0, 0, 0, 0, 0, 0 }
+};
 
-static void
-usage (int status)
+struct arguments
 {
-  if (status)
-    fprintf (stderr, _("Try `%s --help' for more information.\n"),
-            program_name);
-  else
-    printf (_("\
-Usage: %s [OPTIONS]\n\
-\nOptions:\n\
-     -c number, --iteration-count=number  Number of PBKDF2 iterations\n\
-     -l number, --buflen=number           Length of generated hash\n\
-     -s number, --salt=number             Length of salt\n\
-\n\
-Report bugs to <%s>.\n"), program_name, PACKAGE_BUGREPORT);
+  unsigned int count;
+  unsigned int buflen;
+  unsigned int saltlen;
+};
+
+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;
+
+  char *p;
+
+  switch (key)
+    {
+    case 'c':
+      arguments->count = strtoul (arg, NULL, 0);
+      break;
+
+    case 'l':
+      arguments->buflen = strtoul (arg, NULL, 0);
+      break;
 
-  exit (status);
+    case 's':
+      arguments->saltlen = strtoul (arg, NULL, 0);
+      break;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
 }
 
+static struct argp argp = {
+  options, argp_parser, N_("[OPTIONS]"),
+  N_("Generate PBKDF2 password hash."),
+  NULL, NULL, NULL
+};
+
+
 static void
 hexify (char *hex, grub_uint8_t *bin, grub_size_t n)
 {
@@ -85,7 +109,11 @@ hexify (char *hex, grub_uint8_t *bin, grub_size_t n)
 int
 main (int argc, char *argv[])
 {
-  unsigned int count = 10000, buflen = 64, saltlen = 64;
+  struct arguments arguments = {
+    .count = 10000,
+    .buflen = 64,
+    .saltlen = 64
+  };
   char *bufhex, *salthex;
   gcry_err_code_t gcry_err;
   grub_uint8_t *buf, *salt;
@@ -98,60 +126,30 @@ main (int argc, char *argv[])
   grub_util_init_nls ();
 
   /* Check for options.  */
-  while (1)
+  if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
     {
-      int c = getopt_long (argc, argv, "c:l:s:hvV", options, 0);
-
-      if (c == -1)
-       break;
-
-      switch (c)
-       {
-       case 'c':
-         count = strtoul (optarg, NULL, 0);
-         break;
-
-       case 'l':
-         buflen = strtoul (optarg, NULL, 0);
-         break;
-
-       case 's':
-         saltlen = strtoul (optarg, NULL, 0);
-         break;
-
-       case 'h':
-         usage (0);
-         return 0;
-         
-       case 'V':
-         printf ("%s (%s) %s\n", program_name,
-                 PACKAGE_NAME, PACKAGE_VERSION);
-         return 0;
-           
-       default:
-         usage (1);
-         return 1;
-       }
+      fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
+      exit(1);
     }
 
-  bufhex = malloc (buflen * 2 + 1);
+  bufhex = malloc (arguments.buflen * 2 + 1);
   if (!bufhex)
     grub_util_error (_("out of memory"));
-  buf = malloc (buflen);
+  buf = malloc (arguments.buflen);
   if (!buf)
     {
       free (bufhex);
       grub_util_error (_("out of memory"));
     }
 
-  salt = malloc (saltlen);
+  salt = malloc (arguments.saltlen);
   if (!salt)
     {
       free (bufhex);
       free (buf);
       grub_util_error (_("out of memory"));
     }
-  salthex = malloc (saltlen * 2 + 1);
+  salthex = malloc (arguments.saltlen * 2 + 1);
   if (!salthex)
     {
       free (salt);
@@ -209,8 +207,8 @@ main (int argc, char *argv[])
        fclose (f);
        grub_util_error (_("couldn't retrieve random data for salt"));
       }
-    rd = fread (salt, 1, saltlen, f);
-    if (rd != saltlen)
+    rd = fread (salt, 1, arguments.saltlen, f);
+    if (rd != arguments.saltlen)
       {
        fclose (f);
        memset (pass1, 0, sizeof (pass1));
@@ -225,34 +223,34 @@ main (int argc, char *argv[])
 
   gcry_err = grub_crypto_pbkdf2 (GRUB_MD_SHA512,
                                 (grub_uint8_t *) pass1, strlen (pass1),
-                                salt, saltlen,
-                                count, buf, buflen);
+                                salt, arguments.saltlen,
+                                arguments.count, buf, arguments.buflen);
   memset (pass1, 0, sizeof (pass1));
 
   if (gcry_err)
     {
-      memset (buf, 0, buflen);
-      memset (bufhex, 0, 2 * buflen);
+      memset (buf, 0, arguments.buflen);
+      memset (bufhex, 0, 2 * arguments.buflen);
       free (buf);
       free (bufhex);
-      memset (salt, 0, saltlen);
-      memset (salthex, 0, 2 * saltlen);
+      memset (salt, 0, arguments.saltlen);
+      memset (salthex, 0, 2 * arguments.saltlen);
       free (salt);
       free (salthex);
       grub_util_error (_("cryptographic error number %d"), gcry_err);
     }
 
-  hexify (bufhex, buf, buflen);
-  hexify (salthex, salt, saltlen);
+  hexify (bufhex, buf, arguments.buflen);
+  hexify (salthex, salt, arguments.saltlen);
 
   printf (_("Your PBKDF2 is grub.pbkdf2.sha512.%d.%s.%s\n"),
-         count, salthex, bufhex);
-  memset (buf, 0, buflen);
-  memset (bufhex, 0, 2 * buflen);
+         arguments.count, salthex, bufhex);
+  memset (buf, 0, arguments.buflen);
+  memset (bufhex, 0, 2 * arguments.buflen);
   free (buf);
   free (bufhex);
-  memset (salt, 0, saltlen);
-  memset (salthex, 0, 2 * saltlen);
+  memset (salt, 0, arguments.saltlen);
+  memset (salthex, 0, 2 * arguments.saltlen);
   free (salt);
   free (salthex);
 
index 56a38928c499ff869ac0a23346e52357d499f9d3..6b1674c39bcce27a0c69cc4d8939c835261cc177 100644 (file)
 #include <config.h>
 
 #include <stdio.h>
+#include <string.h>
 #include <grub/util/misc.h>
 #include <grub/emu/misc.h>
 #include <grub/i18n.h>
-#include <getopt.h>
+
+#define _GNU_SOURCE    1
+#include <argp.h>
 
 #include "progname.h"
 
-static struct option options[] =
-  {
-    {"help", no_argument, 0, 'h'},
-    {"version", no_argument, 0, 'V'},
-    {0, 0, 0, 0},
-  };
+struct arguments
+{
+  char *pathname;
+};
+
+static struct argp_option options[] = {
+  { 0, 0, 0, 0, 0, 0 }
+};
 
-static void
-usage (int status)
+static error_t
+argp_parser (int key, char *arg, struct argp_state *state)
 {
-  if (status)
-    fprintf (stderr, _("Try `%s --help' for more information.\n"), program_name);
-  else
-    printf (_("\
-Usage: %s [OPTIONS] PATH\n\
-\n\
-Make a system path relative to its root.\n\
-\n\
-Options:\n\
-  -h, --help                display this message and exit\n\
-  -V, --version             print version information and exit\n\
-\n\
-Report bugs to <%s>.\n"), program_name, PACKAGE_BUGREPORT);
-
-  exit (status);
+  /* Get the input argument from argp_parse, which we
+     know is a pointer to our arguments structure. */
+  struct arguments *arguments = state->input;
+
+  char *p;
+
+  switch (key)
+    {
+    case ARGP_KEY_ARG:
+      if (state->arg_num == 0)
+       arguments->pathname = xstrdup (arg);
+      else
+       {
+         /* Too many arguments. */
+         fprintf (stderr, _("Unknown extra argument `%s'.\n"), arg);
+         argp_usage (state);
+       }
+      break;
+    case ARGP_KEY_NO_ARGS:
+      fprintf (stderr, "%s", _("No path is specified.\n"));
+      argp_usage (state);
+      exit (1);
+      break;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
 }
 
+static struct argp argp = {
+  options, argp_parser, N_("PATH"),
+  N_("Make a system path relative to its root."),
+  NULL, NULL, NULL
+};
+
 int
 main (int argc, char *argv[])
 {
-  char *argument, *relpath;
+  char *relpath;
+  struct arguments arguments;
 
   set_program_name (argv[0]);
 
   grub_util_init_nls ();
 
-  /* Check for options.  */
-  while (1)
-    {
-      int c = getopt_long (argc, argv, "hV", options, 0);
-
-      if (c == -1)
-       break;
-      else
-       switch (c)
-         {
-         case 'h':
-           usage (0);
-           break;
-
-         case 'V':
-           printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
-           return 0;
-
-         default:
-           usage (1);
-           break;
-         }
-    }
+  memset (&arguments, 0, sizeof (struct arguments));
 
-  if (optind >= argc)
-    {
-      fprintf (stderr, "%s", _("No path is specified.\n"));
-      usage (1);
-    }
-
-  if (optind + 1 != argc)
+  /* Check for options.  */
+  if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
     {
-      fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]);
-      usage (1);
+      fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
+      exit(1);
     }
 
-  argument = argv[optind];
-
-  relpath = grub_make_system_path_relative_to_its_root (argument);
+  relpath = grub_make_system_path_relative_to_its_root (arguments.pathname);
   printf ("%s\n", relpath);
   free (relpath);
 
index bfbc3171a5f7f3c96866419088546801eacc2fd3..a99f5258dc2c016e17d8b0394e8ada4c34595480 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 #include <sys/stat.h>
+#include <assert.h>
 
 #define _GNU_SOURCE    1
-#include <getopt.h>
+#include <argp.h>
 
 #include "progname.h"
 
@@ -663,153 +664,169 @@ probe (const char *path, char **device_names, char delim)
   free (drives_names);
 }
 
-static struct option options[] =
-  {
-    {"device", no_argument, 0, 'd'},
-    {"device-map", required_argument, 0, 'm'},
-    {"target", required_argument, 0, 't'},
-    {"help", no_argument, 0, 'h'},
-    {"version", no_argument, 0, 'V'},
-    {"verbose", no_argument, 0, 'v'},
-    {0, 0, 0, 0}
-  };
+static struct argp_option options[] = {
+  {"device",  'd', 0, 0,
+   N_("given argument is a system device, not a path"), 0},
+  {"device-map",  'm', N_("FILE"), 0,
+   N_("use FILE as the device map [default=%s]"), 0},
+  {"target",  't', "(fs|fs_uuid|fs_label|drive|device|partmap|abstraction|cryptodisk_uuid|msdos_parttype)", 0,
+   N_("print filesystem module, GRUB drive, system device, partition map module, abstraction module or CRYPTO UUID [default=fs]"), 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
-    printf (_("\
-Usage: %s [OPTION]... [PATH|DEVICE]\n\
-\n\
-Probe device information for a given path (or device, if the -d option is given).\n\
-\n\
-  -d, --device              given argument is a system device, not a path\n\
-  -m, --device-map=FILE     use FILE as the device map [default=%s]\n\
-  -t, --target=(fs|fs_uuid|fs_label|drive|device|partmap|abstraction|cryptodisk_uuid|msdos_parttype)\n\
-                            print filesystem module, GRUB drive, system device, partition map module, abstraction module or CRYPTO UUID [default=fs]\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,
-           DEFAULT_DEVICE_MAP, PACKAGE_BUGREPORT);
-
-  exit (status);
+  switch (key)
+    {
+      case 'm':
+        return xasprintf (text, DEFAULT_DEVICE_MAP);
+
+      default:
+        return (char *) text;
+    }
 }
 
-int
-main (int argc, char *argv[])
+struct arguments
 {
-  char *dev_map = 0;
-  int zero_delim = 0;
-  char delim;
+  char **devices;
+  size_t device_max;
+  size_t ndevices;
+  char *dev_map;
+  int zero_delim;
+};
 
-  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;
 
-  /* Check for options.  */
-  while (1)
+  switch (key)
     {
-      int c = getopt_long (argc, argv, "dm:t:hVv0", options, 0);
-
-      if (c == -1)
-       break;
+    case 'd':
+      argument_is_device = 1;
+      break;
+
+    case 'm':
+      if (arguments->dev_map)
+       free (arguments->dev_map);
+
+      arguments->dev_map = xstrdup (arg);
+      break;
+
+    case 't':
+      if (!strcmp (arg, "fs"))
+       print = PRINT_FS;
+      else if (!strcmp (arg, "fs_uuid"))
+       print = PRINT_FS_UUID;
+      else if (!strcmp (arg, "fs_label"))
+       print = PRINT_FS_LABEL;
+      else if (!strcmp (arg, "drive"))
+       print = PRINT_DRIVE;
+      else if (!strcmp (arg, "device"))
+       print = PRINT_DEVICE;
+      else if (!strcmp (arg, "partmap"))
+       print = PRINT_PARTMAP;
+      else if (!strcmp (arg, "abstraction"))
+       print = PRINT_ABSTRACTION;
+      else if (!strcmp (arg, "cryptodisk_uuid"))
+       print = PRINT_CRYPTODISK_UUID;
+      else if (!strcmp (arg, "msdos_parttype"))
+       print = PRINT_MSDOS_PARTTYPE;
+      else if (!strcmp (arg, "hints_string"))
+       print = PRINT_HINT_STR;
+      else if (!strcmp (arg, "bios_hints"))
+       print = PRINT_BIOS_HINT;
+      else if (!strcmp (arg, "ieee1275_hints"))
+       print = PRINT_IEEE1275_HINT;
+      else if (!strcmp (arg, "baremetal_hints"))
+       print = PRINT_BAREMETAL_HINT;
+      else if (!strcmp (arg, "efi_hints"))
+       print = PRINT_EFI_HINT;
+      else if (!strcmp (arg, "arc_hints"))
+       print = PRINT_ARC_HINT;
+      else if (!strcmp (arg, "compatibility_hint"))
+       print = PRINT_COMPATIBILITY_HINT;
       else
-       switch (c)
-         {
-         case 'd':
-           argument_is_device = 1;
-           break;
+       argp_usage (state);
+      break;
 
-         case 'm':
-           if (dev_map)
-             free (dev_map);
+    case '0':
+      arguments->zero_delim = 1;
+      break;
 
-           dev_map = xstrdup (optarg);
-           break;
+    case 'v':
+      verbosity++;
+      break;
 
-         case 't':
-           if (!strcmp (optarg, "fs"))
-             print = PRINT_FS;
-           else if (!strcmp (optarg, "fs_uuid"))
-             print = PRINT_FS_UUID;
-           else if (!strcmp (optarg, "fs_label"))
-             print = PRINT_FS_LABEL;
-           else if (!strcmp (optarg, "drive"))
-             print = PRINT_DRIVE;
-           else if (!strcmp (optarg, "device"))
-             print = PRINT_DEVICE;
-           else if (!strcmp (optarg, "partmap"))
-             print = PRINT_PARTMAP;
-           else if (!strcmp (optarg, "abstraction"))
-             print = PRINT_ABSTRACTION;
-           else if (!strcmp (optarg, "cryptodisk_uuid"))
-             print = PRINT_CRYPTODISK_UUID;
-           else if (!strcmp (optarg, "msdos_parttype"))
-             print = PRINT_MSDOS_PARTTYPE;
-           else if (!strcmp (optarg, "hints_string"))
-             print = PRINT_HINT_STR;
-           else if (!strcmp (optarg, "bios_hints"))
-             print = PRINT_BIOS_HINT;
-           else if (!strcmp (optarg, "ieee1275_hints"))
-             print = PRINT_IEEE1275_HINT;
-           else if (!strcmp (optarg, "baremetal_hints"))
-             print = PRINT_BAREMETAL_HINT;
-           else if (!strcmp (optarg, "efi_hints"))
-             print = PRINT_EFI_HINT;
-           else if (!strcmp (optarg, "arc_hints"))
-             print = PRINT_ARC_HINT;
-           else if (!strcmp (optarg, "compatibility_hint"))
-             print = PRINT_COMPATIBILITY_HINT;
-           else
-             usage (1);
-           break;
+    case ARGP_KEY_NO_ARGS:
+      fprintf (stderr, "%s", _("No path or device is specified.\n"));
+      argp_usage (state);
+      break;
 
-         case 'h':
-           usage (0);
-           break;
+    case ARGP_KEY_ARG:
+      assert (arguments->ndevices < arguments->device_max);
+      arguments->devices[arguments->ndevices++] = xstrdup(arg);
+      break;
 
-         case '0':
-           zero_delim = 1;
-           break;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
+}
 
-         case 'V':
-           printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
-           return 0;
+static struct argp argp = {
+  options, argp_parser, N_("[OPTION]... [PATH|DEVICE]"),
+  N_("\
+Probe device information for a given path (or device, if the -d option is given)."),
+  NULL, help_filter, NULL
+};
 
-         case 'v':
-           verbosity++;
-           break;
+int
+main (int argc, char *argv[])
+{
+  char delim;
+  struct arguments arguments;
 
-         default:
-           usage (1);
-           break;
-         }
+  set_program_name (argv[0]);
+
+  grub_util_init_nls ();
+
+  memset (&arguments, 0, sizeof (struct arguments));
+  arguments.device_max = argc + 1;
+  arguments.devices = xmalloc ((arguments.device_max + 1)
+                              * sizeof (arguments.devices[0]));
+  memset (arguments.devices, 0, (arguments.device_max + 1)
+         * sizeof (arguments.devices[0]));
+
+  /* Parse our arguments */
+  if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
+    {
+      fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
+      exit(1);
     }
 
   if (verbosity > 1)
     grub_env_set ("debug", "all");
 
   /* Obtain ARGUMENT.  */
-  if (optind >= argc)
-    {
-      fprintf (stderr, "%s", _("No path or device is specified.\n"));
-      usage (1);
-    }
-
-  if (optind + 1 != argc && !argument_is_device)
+  if (arguments.ndevices != 1 && !argument_is_device)
     {
+      char *program = xstrdup(program_name);
       fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]);
-      usage (1);
+      argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program);
+      free (program);
+      exit(1);
     }
 
   /* Initialize the emulated biosdisk driver.  */
-  grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP);
+  grub_util_biosdisk_init (arguments.dev_map ? : DEFAULT_DEVICE_MAP);
 
   /* Initialize all modules. */
   grub_init_all ();
@@ -831,20 +848,21 @@ main (int argc, char *argv[])
   else
     delim = '\n';
 
-  if (zero_delim)
+  if (arguments.zero_delim)
     delim = '\0';
 
   /* Do it.  */
   if (argument_is_device)
-    probe (NULL, argv + optind, delim);
+    probe (NULL, arguments.devices, delim);
   else
-    probe (argv[optind], NULL, delim);
-
-  if (!zero_delim && (print == PRINT_COMPATIBILITY_HINT
-                     || print == PRINT_BIOS_HINT
-                     || print == PRINT_IEEE1275_HINT
-                     || print == PRINT_BAREMETAL_HINT
-                     || print == PRINT_EFI_HINT || print == PRINT_ARC_HINT))
+    probe (arguments.devices[0], NULL, delim);
+
+  if (!arguments.zero_delim && (print == PRINT_COMPATIBILITY_HINT
+                               || print == PRINT_BIOS_HINT
+                               || print == PRINT_IEEE1275_HINT
+                               || print == PRINT_BAREMETAL_HINT
+                               || print == PRINT_EFI_HINT
+                               || print == PRINT_ARC_HINT))
     putchar ('\n');
 
   /* Free resources.  */
@@ -852,7 +870,14 @@ main (int argc, char *argv[])
   grub_fini_all ();
   grub_util_biosdisk_fini ();
 
-  free (dev_map);
+  {
+    size_t i;
+    for (i = 0; i < arguments.ndevices; i++)
+      free (arguments.devices[i]);
+  }
+  free (arguments.devices);
+
+  free (arguments.dev_map);
 
   return 0;
 }
index 25358a5533247a128c1dab980100e8ee9732abf1..5fed01e23f78b735ec1fb65fa079c7385eadf684 100644 (file)
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <getopt.h>
+#include <argp.h>
 
 #include "progname.h"
 
-static struct option options[] =
-  {
-    {"help", no_argument, 0, 'h'},
-    {"version", no_argument, 0, 'V'},
-    {"verbose", no_argument, 0, 'v'},
-    {0, 0, 0, 0}
-  };
-
-static void
-usage (int status)
+struct arguments
 {
-  if (status)
-    fprintf (stderr,
-            _("Try ``%s --help'' for more information.\n"), program_name);
-  else
-    printf (_("\
-Usage: %s [PATH]\n\
-\n\
-Checks GRUB script configuration file for syntax errors.\n\
-\n\
-  -h, --help                display this message and exit\n\
-  -V, --version             print version information and exit\n\
-  -v, --verbose             print the script as it is being processed\n\
-\n\
-Report bugs to <%s>.\n\
-"), program_name,
-           PACKAGE_BUGREPORT);
-  exit (status);
+  int verbose;
+  char *filename;
+};
+
+static struct argp_option options[] = {
+  {"verbose",     'v', 0,      0, N_("Print verbose messages."), 0},
+  { 0, 0, 0, 0, 0, 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;
+
+  char *p;
+
+  switch (key)
+    {
+    case 'v':
+      arguments->verbose = 1;
+      break;
+
+    case ARGP_KEY_ARG:
+      if (state->arg_num == 0)
+       arguments->filename = xstrdup (arg);
+      else
+       {
+         /* Too many arguments. */
+         fprintf (stderr, _("Unknown extra argument `%s'.\n"), arg);
+         argp_usage (state);
+       }
+      break;
+    default:
+      return ARGP_ERR_UNKNOWN;
+    }
+  return 0;
 }
 
+static struct argp argp = {
+  options, argp_parser, N_("[PATH]"),
+  N_("Checks GRUB script configuration file for syntax errors."),
+  NULL, NULL, NULL
+};
+
 int
 main (int argc, char *argv[])
 {
-  char *argument;
   char *input;
   int lineno = 0;
   FILE *file = 0;
-  int verbose = 0;
+  struct arguments arguments;
   int found_input = 0;
   struct grub_script *script = NULL;
 
@@ -98,7 +115,7 @@ main (int argc, char *argv[])
        return grub_errno;
       }
 
-    if (verbose)
+    if (arguments.verbose)
       grub_printf("%s", cmdline);
 
     for (i = 0; cmdline[i] != '\0'; i++)
@@ -122,52 +139,31 @@ main (int argc, char *argv[])
   set_program_name (argv[0]);
   grub_util_init_nls ();
 
+  memset (&arguments, 0, sizeof (struct arguments));
+
   /* Check for options.  */
-  while (1)
+  if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
     {
-      int c = getopt_long (argc, argv, "hvV", options, 0);
-
-      if (c == -1)
-       break;
-      else
-       switch (c)
-         {
-         case 'h':
-           usage (0);
-           break;
-
-         case 'V':
-           printf ("%s (%s) %s\n", program_name, PACKAGE_NAME, PACKAGE_VERSION);
-           return 0;
-
-         case 'v':
-           verbose = 1;
-           break;
-
-         default:
-           usage (1);
-           break;
-         }
+      fprintf (stderr, "%s", _("Error in parsing command line arguments\n"));
+      exit(1);
     }
 
   /* Obtain ARGUMENT.  */
-  if (optind >= argc)
+  if (!arguments.filename)
     {
       file = 0; /* read from stdin */
     }
-  else if (optind + 1 != argc)
-    {
-      fprintf (stderr, _("Unknown extra argument `%s'.\n"), argv[optind + 1]);
-      usage (1);
-    }
   else
     {
-      argument = argv[optind];
-      file = fopen (argument, "r");
+      file = fopen (arguments.filename, "r");
       if (! file)
        {
-         fprintf (stderr, "%s: %s: %s\n", program_name, argument, strerror(errno));
-         usage (1);
+          char *program = xstrdup(program_name);
+         fprintf (stderr, "%s: %s: %s\n", program_name, 
+                  arguments.filename, strerror(errno));
+          argp_help (&argp, stderr, ARGP_HELP_STD_USAGE, program);
+          free(program);
+          exit(1);
        }
     }