Переглянути джерело

Restore extra help output.

* src/tar.c (tar_list_quoting_styles): Change first argument to
struct obstack.
(format_default_settings): New function.
(show_default_settings)
(show_default_settings_fs): Removed.
(tar_help): Removed.
(tar_help_filter): New function.
(argp): Set help_filter.
(parse_opt): Fix error message.
Sergey Poznyakoff 15 роки тому
батько
коміт
92773d860f
2 змінених файлів з 187 додано та 183 видалено
  1. 1 0
      gnulib.modules
  2. 186 183
      src/tar.c

+ 1 - 0
gnulib.modules

@@ -5,6 +5,7 @@ alloca
 argmatch
 argmatch
 argp
 argp
 argp-version-etc
 argp-version-etc
+asprintf
 backupfile
 backupfile
 canonicalize
 canonicalize
 closeout
 closeout

+ 186 - 183
src/tar.c

@@ -220,12 +220,18 @@ subcommand_string (enum subcommand c)
 }
 }
 
 
 void
 void
-tar_list_quoting_styles (argp_fmtstream_t fs, char *prefix)
+tar_list_quoting_styles (struct obstack *stk, char *prefix)
 {
 {
   int i;
   int i;
-
+  size_t prefixlen = strlen (prefix);
+  
   for (i = 0; quoting_style_args[i]; i++)
   for (i = 0; quoting_style_args[i]; i++)
-    argp_fmtstream_printf (fs, "%s%s\n", prefix, quoting_style_args[i]);
+    {
+      obstack_grow (stk, prefix, prefixlen);
+      obstack_grow (stk, quoting_style_args[i],
+		    strlen (quoting_style_args[i]));
+      obstack_1grow (stk, '\n');
+    }
 }
 }
 
 
 void
 void
@@ -894,39 +900,29 @@ add_exclude_array (char const * const * fv)
 }
 }
 
 
 
 
+static char *
+format_default_settings (void)
+{
+  char *s;
+  
+  asprintf (&s,
+	    "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s"
 #ifdef REMOTE_SHELL
 #ifdef REMOTE_SHELL
-# define DECL_SHOW_DEFAULT_SETTINGS(stream, printer)                      \
-{                                                                         \
-  printer (stream,                                                        \
-	   "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s",   \
-	   archive_format_string (DEFAULT_ARCHIVE_FORMAT),                \
-	   DEFAULT_ARCHIVE, DEFAULT_BLOCKING,                             \
-	   quoting_style_args[DEFAULT_QUOTING_STYLE],                     \
-	   DEFAULT_RMT_COMMAND);                                          \
-  printer (stream, " --rsh-command=%s", REMOTE_SHELL);                    \
-  printer (stream, "\n");                                                 \
-}
-#else
-# define DECL_SHOW_DEFAULT_SETTINGS(stream, printer)                      \
-{                                                                         \
-  printer (stream,                                                        \
-	   "--format=%s -f%s -b%d --quoting-style=%s --rmt-command=%s",   \
-	   archive_format_string (DEFAULT_ARCHIVE_FORMAT),                \
-	   DEFAULT_ARCHIVE, DEFAULT_BLOCKING,                             \
-	   quoting_style_args[DEFAULT_QUOTING_STYLE],                     \
-	   DEFAULT_RMT_COMMAND);                                          \
-  printer (stream, "\n");                                                 \
-}
+	    " --rsh-command=%s"
 #endif
 #endif
+	    ,
+	    archive_format_string (DEFAULT_ARCHIVE_FORMAT), 
+	    DEFAULT_ARCHIVE, DEFAULT_BLOCKING,              
+	    quoting_style_args[DEFAULT_QUOTING_STYLE],
+	    DEFAULT_RMT_COMMAND,
+#ifdef REMOTE_SHELL
+	    REMOTE_SHELL
+#endif
+	    );
+  return s;
+}
 
 
-static void
-show_default_settings (FILE *fp)
-     DECL_SHOW_DEFAULT_SETTINGS(fp, fprintf)
-
-static void
-show_default_settings_fs (argp_fmtstream_t fs)
-     DECL_SHOW_DEFAULT_SETTINGS(fs, argp_fmtstream_printf)
-
+
 static void
 static void
 set_subcommand_option (enum subcommand subcommand)
 set_subcommand_option (enum subcommand subcommand)
 {
 {
@@ -934,7 +930,7 @@ set_subcommand_option (enum subcommand subcommand)
       && subcommand_option != subcommand)
       && subcommand_option != subcommand)
     USAGE_ERROR ((0, 0,
     USAGE_ERROR ((0, 0,
 		  _("You may not specify more than one `-Acdtrux' option")));
 		  _("You may not specify more than one `-Acdtrux' option")));
-
+  
   subcommand_option = subcommand;
   subcommand_option = subcommand;
 }
 }
 
 
@@ -944,7 +940,7 @@ set_use_compress_program_option (const char *string)
   if (use_compress_program_option
   if (use_compress_program_option
       && strcmp (use_compress_program_option, string) != 0)
       && strcmp (use_compress_program_option, string) != 0)
     USAGE_ERROR ((0, 0, _("Conflicting compression options")));
     USAGE_ERROR ((0, 0, _("Conflicting compression options")));
-
+  
   use_compress_program_option = string;
   use_compress_program_option = string;
 }
 }
 
 
@@ -1096,7 +1092,7 @@ read_name_from_file (FILE *fp, struct obstack *stk, int term)
       obstack_1grow (stk, c);
       obstack_1grow (stk, c);
       counter++;
       counter++;
     }
     }
-
+  
   if (counter == 0 && c != EOF)
   if (counter == 0 && c != EOF)
     return file_list_skip;
     return file_list_skip;
 
 
@@ -1180,7 +1176,7 @@ update_argv (const char *filename, struct argp_state *state)
       if ((fp = fopen (filename, "r")) == NULL)
       if ((fp = fopen (filename, "r")) == NULL)
 	open_fatal (filename);
 	open_fatal (filename);
     }
     }
-
+  
   while ((read_state = read_name_from_file (fp, &argv_stk, term))
   while ((read_state = read_name_from_file (fp, &argv_stk, term))
 	 != file_list_end)
 	 != file_list_end)
     {
     {
@@ -1189,18 +1185,18 @@ update_argv (const char *filename, struct argp_state *state)
 	case file_list_success:
 	case file_list_success:
 	  count++;
 	  count++;
 	  break;
 	  break;
-
+	  
 	case file_list_end: /* won't happen, just to pacify gcc */
 	case file_list_end: /* won't happen, just to pacify gcc */
 	  break;
 	  break;
-
+	  
 	case file_list_zero:
 	case file_list_zero:
 	  {
 	  {
 	    size_t size;
 	    size_t size;
-
+	    
 	    WARNOPT (WARN_FILENAME_WITH_NULS,
 	    WARNOPT (WARN_FILENAME_WITH_NULS,
 		     (0, 0, N_("%s: file name read contains nul character"),
 		     (0, 0, N_("%s: file name read contains nul character"),
 		      quotearg_colon (filename)));
 		      quotearg_colon (filename)));
-
+	    
 	    /* Prepare new stack contents */
 	    /* Prepare new stack contents */
 	    size = obstack_object_size (&argv_stk);
 	    size = obstack_object_size (&argv_stk);
 	    p = obstack_finish (&argv_stk);
 	    p = obstack_finish (&argv_stk);
@@ -1215,34 +1211,34 @@ update_argv (const char *filename, struct argp_state *state)
 	    term = 0;
 	    term = 0;
 	    break;
 	    break;
 	  }
 	  }
-
+	  
 	case file_list_skip:
 	case file_list_skip:
 	  break;
 	  break;
 	}
 	}
     }
     }
-
+  
   if (!is_stdin)
   if (!is_stdin)
     fclose (fp);
     fclose (fp);
-
+  
   if (count == 0)
   if (count == 0)
     return;
     return;
-
+  
   start = obstack_finish (&argv_stk);
   start = obstack_finish (&argv_stk);
-
+  
   if (term == 0)
   if (term == 0)
     for (p = start; *p; p += strlen (p) + 1)
     for (p = start; *p; p += strlen (p) + 1)
       if (p[0] == '-')
       if (p[0] == '-')
 	count++;
 	count++;
-
+  
   new_argc = state->argc + count;
   new_argc = state->argc + count;
   new_argv = xmalloc (sizeof (state->argv[0]) * (new_argc + 1));
   new_argv = xmalloc (sizeof (state->argv[0]) * (new_argc + 1));
   memcpy (new_argv, state->argv, sizeof (state->argv[0]) * (state->argc + 1));
   memcpy (new_argv, state->argv, sizeof (state->argv[0]) * (state->argc + 1));
   state->argv = new_argv;
   state->argv = new_argv;
   memmove (&state->argv[state->next + count], &state->argv[state->next],
   memmove (&state->argv[state->next + count], &state->argv[state->next],
 	   (state->argc - state->next + 1) * sizeof (state->argv[0]));
 	   (state->argc - state->next + 1) * sizeof (state->argv[0]));
-
+  
   state->argc = new_argc;
   state->argc = new_argc;
-
+  
   for (i = state->next, p = start; *p; p += strlen (p) + 1, i++)
   for (i = state->next, p = start; *p; p += strlen (p) + 1, i++)
     {
     {
       if (term == 0 && p[0] == '-')
       if (term == 0 && p[0] == '-')
@@ -1252,26 +1248,29 @@ update_argv (const char *filename, struct argp_state *state)
 }
 }
 
 
 
 
-static void
-tar_help (struct argp_state *state)
+static char *
+tar_help_filter (int key, const char *text, void *input)
 {
 {
-  argp_fmtstream_t fs;
-  state->flags |= ARGP_NO_EXIT;
-  argp_state_help (state, state->out_stream,
-		   ARGP_HELP_STD_HELP & ~ARGP_HELP_BUG_ADDR);
-  /* FIXME: use struct uparams.rmargin (from argp-help.c) instead of 79 */
-  fs = argp_make_fmtstream (state->out_stream, 0, 79, 0);
-
-  argp_fmtstream_printf (fs, "\n%s\n\n",
-		       _("Valid arguments for --quoting-style options are:"));
-  tar_list_quoting_styles (fs, "  ");
-
-  argp_fmtstream_puts (fs, _("\n*This* tar defaults to:\n"));
-  show_default_settings_fs (fs);
-  argp_fmtstream_putc (fs, '\n');
-  argp_fmtstream_printf (fs, _("Report bugs to %s.\n"),
-			 argp_program_bug_address);
-  argp_fmtstream_free (fs);
+  struct obstack stk;
+  char *s;
+
+  if (key != ARGP_KEY_HELP_EXTRA)
+    return (char*) text;
+
+  obstack_init (&stk);
+  s = _("Valid arguments for the --quoting-style option are:");
+  obstack_grow (&stk, s, strlen (s));
+  obstack_grow (&stk, "\n\n", 2);
+  tar_list_quoting_styles (&stk, "  ");
+  s = _("\n*This* tar defaults to:\n");
+  obstack_grow (&stk, s, strlen (s));
+  s = format_default_settings ();
+  obstack_grow (&stk, s, strlen (s));
+  obstack_1grow (&stk, '\n');
+  obstack_1grow (&stk, 0);
+  s = xstrdup (obstack_finish (&stk));
+  obstack_free (&stk, NULL);
+  return s;
 }
 }
 
 
 static error_t
 static error_t
@@ -1286,15 +1285,15 @@ parse_opt (int key, char *arg, struct argp_state *state)
       name_add_name (arg, MAKE_INCL_OPTIONS (args));
       name_add_name (arg, MAKE_INCL_OPTIONS (args));
       args->input_files = true;
       args->input_files = true;
       break;
       break;
-
+      
     case 'A':
     case 'A':
       set_subcommand_option (CAT_SUBCOMMAND);
       set_subcommand_option (CAT_SUBCOMMAND);
       break;
       break;
-
+      
     case 'a':
     case 'a':
       args->compress_autodetect = true;
       args->compress_autodetect = true;
       break;
       break;
-
+      
     case NO_AUTO_COMPRESS_OPTION:
     case NO_AUTO_COMPRESS_OPTION:
       args->compress_autodetect = false;
       args->compress_autodetect = false;
       break;
       break;
@@ -1310,65 +1309,65 @@ parse_opt (int key, char *arg, struct argp_state *state)
 			_("Invalid blocking factor")));
 			_("Invalid blocking factor")));
       }
       }
       break;
       break;
-
+      
     case 'B':
     case 'B':
       /* Try to reblock input records.  For reading 4.2BSD pipes.  */
       /* Try to reblock input records.  For reading 4.2BSD pipes.  */
-
+      
       /* It would surely make sense to exchange -B and -R, but it seems
       /* It would surely make sense to exchange -B and -R, but it seems
 	 that -B has been used for a long while in Sun tar and most
 	 that -B has been used for a long while in Sun tar and most
 	 BSD-derived systems.  This is a consequence of the block/record
 	 BSD-derived systems.  This is a consequence of the block/record
 	 terminology confusion.  */
 	 terminology confusion.  */
-
+      
       read_full_records_option = true;
       read_full_records_option = true;
       break;
       break;
-
+      
     case 'c':
     case 'c':
       set_subcommand_option (CREATE_SUBCOMMAND);
       set_subcommand_option (CREATE_SUBCOMMAND);
       break;
       break;
-
+      
     case 'C':
     case 'C':
       name_add_dir (arg);
       name_add_dir (arg);
       break;
       break;
-
+      
     case 'd':
     case 'd':
       set_subcommand_option (DIFF_SUBCOMMAND);
       set_subcommand_option (DIFF_SUBCOMMAND);
       break;
       break;
-
+      
     case 'f':
     case 'f':
       if (archive_names == allocated_archive_names)
       if (archive_names == allocated_archive_names)
 	archive_name_array = x2nrealloc (archive_name_array,
 	archive_name_array = x2nrealloc (archive_name_array,
 					 &allocated_archive_names,
 					 &allocated_archive_names,
 					 sizeof (archive_name_array[0]));
 					 sizeof (archive_name_array[0]));
-
+      
       archive_name_array[archive_names++] = arg;
       archive_name_array[archive_names++] = arg;
       break;
       break;
-
+      
     case 'F':
     case 'F':
       /* Since -F is only useful with -M, make it implied.  Run this
       /* Since -F is only useful with -M, make it implied.  Run this
 	 script at the end of each tape.  */
 	 script at the end of each tape.  */
-
+      
       info_script_option = arg;
       info_script_option = arg;
       multi_volume_option = true;
       multi_volume_option = true;
       break;
       break;
-
+      
     case 'g':
     case 'g':
       listed_incremental_option = arg;
       listed_incremental_option = arg;
       after_date_option = true;
       after_date_option = true;
       /* Fall through.  */
       /* Fall through.  */
-
+      
     case 'G':
     case 'G':
       /* We are making an incremental dump (FIXME: are we?); save
       /* We are making an incremental dump (FIXME: are we?); save
 	 directories at the beginning of the archive, and include in each
 	 directories at the beginning of the archive, and include in each
 	 directory its contents.  */
 	 directory its contents.  */
-
+      
       incremental_option = true;
       incremental_option = true;
       break;
       break;
-
+      
     case 'h':
     case 'h':
       /* Follow symbolic links.  */
       /* Follow symbolic links.  */
       dereference_option = true;
       dereference_option = true;
       break;
       break;
-
+      
     case HARD_DEREFERENCE_OPTION:
     case HARD_DEREFERENCE_OPTION:
       hard_dereference_option = true;
       hard_dereference_option = true;
       break;
       break;
@@ -1377,14 +1376,14 @@ parse_opt (int key, char *arg, struct argp_state *state)
       /* Ignore zero blocks (eofs).  This can't be the default,
       /* Ignore zero blocks (eofs).  This can't be the default,
 	 because Unix tar writes two blocks of zeros, then pads out
 	 because Unix tar writes two blocks of zeros, then pads out
 	 the record with garbage.  */
 	 the record with garbage.  */
-
+      
       ignore_zeros_option = true;
       ignore_zeros_option = true;
       break;
       break;
-
+      
     case 'j':
     case 'j':
       set_use_compress_program_option ("bzip2");
       set_use_compress_program_option ("bzip2");
       break;
       break;
-
+      
     case 'J':
     case 'J':
       set_use_compress_program_option ("xz");
       set_use_compress_program_option ("xz");
       break;
       break;
@@ -1393,22 +1392,22 @@ parse_opt (int key, char *arg, struct argp_state *state)
       /* Don't replace existing files.  */
       /* Don't replace existing files.  */
       old_files_option = KEEP_OLD_FILES;
       old_files_option = KEEP_OLD_FILES;
       break;
       break;
-
+      
     case 'K':
     case 'K':
       starting_file_option = true;
       starting_file_option = true;
       addname (arg, 0, true, NULL);
       addname (arg, 0, true, NULL);
       break;
       break;
-
+      
     case ONE_FILE_SYSTEM_OPTION:
     case ONE_FILE_SYSTEM_OPTION:
       /* When dumping directories, don't dump files/subdirectories
       /* When dumping directories, don't dump files/subdirectories
 	 that are on other filesystems. */
 	 that are on other filesystems. */
       one_file_system_option = true;
       one_file_system_option = true;
       break;
       break;
-
+      
     case 'l':
     case 'l':
       check_links_option = 1;
       check_links_option = 1;
       break;
       break;
-
+      
     case 'L':
     case 'L':
       {
       {
 	uintmax_t u;
 	uintmax_t u;
@@ -1419,7 +1418,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
 	multi_volume_option = true;
 	multi_volume_option = true;
       }
       }
       break;
       break;
-
+      
     case LEVEL_OPTION:
     case LEVEL_OPTION:
       {
       {
 	char *p;
 	char *p;
@@ -1440,23 +1439,23 @@ parse_opt (int key, char *arg, struct argp_state *state)
     case 'm':
     case 'm':
       touch_option = true;
       touch_option = true;
       break;
       break;
-
+      
     case 'M':
     case 'M':
       /* Make multivolume archive: when we can't write any more into
       /* Make multivolume archive: when we can't write any more into
 	 the archive, re-open it, and continue writing.  */
 	 the archive, re-open it, and continue writing.  */
-
+      
       multi_volume_option = true;
       multi_volume_option = true;
       break;
       break;
-
+      
     case MTIME_OPTION:
     case MTIME_OPTION:
       get_date_or_file (args, "--mtime", arg, &mtime_option);
       get_date_or_file (args, "--mtime", arg, &mtime_option);
       set_mtime_option = true;
       set_mtime_option = true;
       break;
       break;
-
+      
     case 'n':
     case 'n':
       seek_option = 1;
       seek_option = 1;
       break;
       break;
-
+      
     case NO_SEEK_OPTION:
     case NO_SEEK_OPTION:
       seek_option = 0;
       seek_option = 0;
       break;
       break;
@@ -1464,56 +1463,56 @@ parse_opt (int key, char *arg, struct argp_state *state)
     case 'N':
     case 'N':
       after_date_option = true;
       after_date_option = true;
       /* Fall through.  */
       /* Fall through.  */
-
+      
     case NEWER_MTIME_OPTION:
     case NEWER_MTIME_OPTION:
       if (NEWER_OPTION_INITIALIZED (newer_mtime_option))
       if (NEWER_OPTION_INITIALIZED (newer_mtime_option))
 	USAGE_ERROR ((0, 0, _("More than one threshold date")));
 	USAGE_ERROR ((0, 0, _("More than one threshold date")));
       get_date_or_file (args,
       get_date_or_file (args,
 			key == NEWER_MTIME_OPTION ? "--newer-mtime"
 			key == NEWER_MTIME_OPTION ? "--newer-mtime"
-			  : "--after-date", arg, &newer_mtime_option);
+			: "--after-date", arg, &newer_mtime_option);
       break;
       break;
-
+      
     case 'o':
     case 'o':
       args->o_option = true;
       args->o_option = true;
       break;
       break;
-
+      
     case 'O':
     case 'O':
       to_stdout_option = true;
       to_stdout_option = true;
       break;
       break;
-
+      
     case 'p':
     case 'p':
       same_permissions_option = true;
       same_permissions_option = true;
       break;
       break;
-
+      
     case 'P':
     case 'P':
       absolute_names_option = true;
       absolute_names_option = true;
       break;
       break;
-
+      
     case 'r':
     case 'r':
       set_subcommand_option (APPEND_SUBCOMMAND);
       set_subcommand_option (APPEND_SUBCOMMAND);
       break;
       break;
-
+      
     case 'R':
     case 'R':
       /* Print block numbers for debugging bad tar archives.  */
       /* Print block numbers for debugging bad tar archives.  */
-
+      
       /* It would surely make sense to exchange -B and -R, but it seems
       /* It would surely make sense to exchange -B and -R, but it seems
 	 that -B has been used for a long while in Sun tar and most
 	 that -B has been used for a long while in Sun tar and most
 	 BSD-derived systems.  This is a consequence of the block/record
 	 BSD-derived systems.  This is a consequence of the block/record
 	 terminology confusion.  */
 	 terminology confusion.  */
-
+      
       block_number_option = true;
       block_number_option = true;
       break;
       break;
-
+      
     case 's':
     case 's':
       /* Names to extract are sorted.  */
       /* Names to extract are sorted.  */
-
+      
       same_order_option = true;
       same_order_option = true;
       break;
       break;
-
+      
     case 'S':
     case 'S':
       sparse_option = true;
       sparse_option = true;
       break;
       break;
-
+      
     case SPARSE_VERSION_OPTION:
     case SPARSE_VERSION_OPTION:
       sparse_option = true;
       sparse_option = true;
       {
       {
@@ -1529,17 +1528,17 @@ parse_opt (int key, char *arg, struct argp_state *state)
 	  }
 	  }
       }
       }
       break;
       break;
-
+      
     case 't':
     case 't':
       set_subcommand_option (LIST_SUBCOMMAND);
       set_subcommand_option (LIST_SUBCOMMAND);
       verbose_option++;
       verbose_option++;
       break;
       break;
-
+      
     case TEST_LABEL_OPTION:
     case TEST_LABEL_OPTION:
       set_subcommand_option (LIST_SUBCOMMAND);
       set_subcommand_option (LIST_SUBCOMMAND);
       test_label_option = true;
       test_label_option = true;
       break;
       break;
-
+      
     case 'T':
     case 'T':
       update_argv (arg, state);
       update_argv (arg, state);
       /* Indicate we've been given -T option. This is for backward
       /* Indicate we've been given -T option. This is for backward
@@ -1547,40 +1546,40 @@ parse_opt (int key, char *arg, struct argp_state *state)
 	 succeed */
 	 succeed */
       files_from_option = true;
       files_from_option = true;
       break;
       break;
-
+      
     case 'u':
     case 'u':
       set_subcommand_option (UPDATE_SUBCOMMAND);
       set_subcommand_option (UPDATE_SUBCOMMAND);
       break;
       break;
-
+      
     case 'U':
     case 'U':
       old_files_option = UNLINK_FIRST_OLD_FILES;
       old_files_option = UNLINK_FIRST_OLD_FILES;
       break;
       break;
-
+      
     case UTC_OPTION:
     case UTC_OPTION:
       utc_option = true;
       utc_option = true;
       break;
       break;
-
+      
     case 'v':
     case 'v':
       verbose_option++;
       verbose_option++;
       warning_option |= WARN_VERBOSE_WARNINGS;
       warning_option |= WARN_VERBOSE_WARNINGS;
       break;
       break;
-
+      
     case 'V':
     case 'V':
       volume_label_option = arg;
       volume_label_option = arg;
       break;
       break;
-
+      
     case 'w':
     case 'w':
       interactive_option = true;
       interactive_option = true;
       break;
       break;
-
+      
     case 'W':
     case 'W':
       verify_option = true;
       verify_option = true;
       break;
       break;
-
+      
     case 'x':
     case 'x':
       set_subcommand_option (EXTRACT_SUBCOMMAND);
       set_subcommand_option (EXTRACT_SUBCOMMAND);
       break;
       break;
-
+      
     case 'X':
     case 'X':
       if (add_exclude_file (add_exclude, excluded, arg,
       if (add_exclude_file (add_exclude, excluded, arg,
 			    MAKE_EXCL_OPTIONS (args), '\n')
 			    MAKE_EXCL_OPTIONS (args), '\n')
@@ -1590,19 +1589,19 @@ parse_opt (int key, char *arg, struct argp_state *state)
 	  FATAL_ERROR ((0, e, "%s", quotearg_colon (arg)));
 	  FATAL_ERROR ((0, e, "%s", quotearg_colon (arg)));
 	}
 	}
       break;
       break;
-
+      
     case 'z':
     case 'z':
       set_use_compress_program_option ("gzip");
       set_use_compress_program_option ("gzip");
       break;
       break;
-
+      
     case 'Z':
     case 'Z':
       set_use_compress_program_option ("compress");
       set_use_compress_program_option ("compress");
       break;
       break;
-
+      
     case ANCHORED_OPTION:
     case ANCHORED_OPTION:
       args->matching_flags |= EXCLUDE_ANCHORED;
       args->matching_flags |= EXCLUDE_ANCHORED;
       break;
       break;
-
+      
     case ATIME_PRESERVE_OPTION:
     case ATIME_PRESERVE_OPTION:
       atime_preserve_option =
       atime_preserve_option =
 	(arg
 	(arg
@@ -1614,7 +1613,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
 		      _("--atime-preserve='system' is not supported"
 		      _("--atime-preserve='system' is not supported"
 			" on this platform")));
 			" on this platform")));
       break;
       break;
-
+      
     case CHECK_DEVICE_OPTION:
     case CHECK_DEVICE_OPTION:
       check_device_option = true;
       check_device_option = true;
       break;
       break;
@@ -1627,7 +1626,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
       if (arg)
       if (arg)
 	{
 	{
 	  char *p;
 	  char *p;
-
+	  
 	  if (*arg == '.')
 	  if (*arg == '.')
 	    {
 	    {
 	      checkpoint_compile_action (".");
 	      checkpoint_compile_action (".");
@@ -1641,7 +1640,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
       else
       else
 	checkpoint_option = DEFAULT_CHECKPOINT;
 	checkpoint_option = DEFAULT_CHECKPOINT;
       break;
       break;
-
+      
     case CHECKPOINT_ACTION_OPTION:
     case CHECKPOINT_ACTION_OPTION:
       checkpoint_compile_action (arg);
       checkpoint_compile_action (arg);
       break;
       break;
@@ -1651,19 +1650,19 @@ parse_opt (int key, char *arg, struct argp_state *state)
       if (arg)
       if (arg)
 	args->version_control_string = arg;
 	args->version_control_string = arg;
       break;
       break;
-
+      
     case DELAY_DIRECTORY_RESTORE_OPTION:
     case DELAY_DIRECTORY_RESTORE_OPTION:
       delay_directory_restore_option = true;
       delay_directory_restore_option = true;
       break;
       break;
-
+      
     case NO_DELAY_DIRECTORY_RESTORE_OPTION:
     case NO_DELAY_DIRECTORY_RESTORE_OPTION:
       delay_directory_restore_option = false;
       delay_directory_restore_option = false;
       break;
       break;
-
+      
     case DELETE_OPTION:
     case DELETE_OPTION:
       set_subcommand_option (DELETE_SUBCOMMAND);
       set_subcommand_option (DELETE_SUBCOMMAND);
       break;
       break;
-
+      
     case EXCLUDE_BACKUPS_OPTION:
     case EXCLUDE_BACKUPS_OPTION:
       add_exclude_array (backup_file_table);
       add_exclude_array (backup_file_table);
       break;
       break;
@@ -1671,34 +1670,34 @@ parse_opt (int key, char *arg, struct argp_state *state)
     case EXCLUDE_OPTION:
     case EXCLUDE_OPTION:
       add_exclude (excluded, arg, MAKE_EXCL_OPTIONS (args));
       add_exclude (excluded, arg, MAKE_EXCL_OPTIONS (args));
       break;
       break;
-
+      
     case EXCLUDE_CACHES_OPTION:
     case EXCLUDE_CACHES_OPTION:
       add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_contents,
       add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_contents,
 			 cachedir_file_p);
 			 cachedir_file_p);
       break;
       break;
-
+      
     case EXCLUDE_CACHES_UNDER_OPTION:
     case EXCLUDE_CACHES_UNDER_OPTION:
       add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_under,
       add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_under,
 			 cachedir_file_p);
 			 cachedir_file_p);
       break;
       break;
-
+      
     case EXCLUDE_CACHES_ALL_OPTION:
     case EXCLUDE_CACHES_ALL_OPTION:
       add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_all,
       add_exclusion_tag ("CACHEDIR.TAG", exclusion_tag_all,
 			 cachedir_file_p);
 			 cachedir_file_p);
       break;
       break;
-
+      
     case EXCLUDE_TAG_OPTION:
     case EXCLUDE_TAG_OPTION:
       add_exclusion_tag (arg, exclusion_tag_contents, NULL);
       add_exclusion_tag (arg, exclusion_tag_contents, NULL);
       break;
       break;
-
+      
     case EXCLUDE_TAG_UNDER_OPTION:
     case EXCLUDE_TAG_UNDER_OPTION:
       add_exclusion_tag (arg, exclusion_tag_under, NULL);
       add_exclusion_tag (arg, exclusion_tag_under, NULL);
       break;
       break;
-
+      
     case EXCLUDE_TAG_ALL_OPTION:
     case EXCLUDE_TAG_ALL_OPTION:
       add_exclusion_tag (arg, exclusion_tag_all, NULL);
       add_exclusion_tag (arg, exclusion_tag_all, NULL);
       break;
       break;
-
+      
     case EXCLUDE_VCS_OPTION:
     case EXCLUDE_VCS_OPTION:
       add_exclude_array (vcs_file_table);
       add_exclude_array (vcs_file_table);
       break;
       break;
@@ -1706,31 +1705,31 @@ parse_opt (int key, char *arg, struct argp_state *state)
     case FORCE_LOCAL_OPTION:
     case FORCE_LOCAL_OPTION:
       force_local_option = true;
       force_local_option = true;
       break;
       break;
-
+      
     case 'H':
     case 'H':
       set_archive_format (arg);
       set_archive_format (arg);
       break;
       break;
-
+      
     case INDEX_FILE_OPTION:
     case INDEX_FILE_OPTION:
       index_file_name = arg;
       index_file_name = arg;
       break;
       break;
-
+      
     case IGNORE_CASE_OPTION:
     case IGNORE_CASE_OPTION:
       args->matching_flags |= FNM_CASEFOLD;
       args->matching_flags |= FNM_CASEFOLD;
       break;
       break;
-
+      
     case IGNORE_COMMAND_ERROR_OPTION:
     case IGNORE_COMMAND_ERROR_OPTION:
       ignore_command_error_option = true;
       ignore_command_error_option = true;
       break;
       break;
-
+      
     case IGNORE_FAILED_READ_OPTION:
     case IGNORE_FAILED_READ_OPTION:
       ignore_failed_read_option = true;
       ignore_failed_read_option = true;
       break;
       break;
-
+      
     case KEEP_NEWER_FILES_OPTION:
     case KEEP_NEWER_FILES_OPTION:
       old_files_option = KEEP_NEWER_FILES;
       old_files_option = KEEP_NEWER_FILES;
       break;
       break;
-
+      
     case GROUP_OPTION:
     case GROUP_OPTION:
       if (! (strlen (arg) < GNAME_FIELD_SIZE
       if (! (strlen (arg) < GNAME_FIELD_SIZE
 	     && gname_to_gid (arg, &group_option)))
 	     && gname_to_gid (arg, &group_option)))
@@ -1741,10 +1740,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
 	    group_option = g;
 	    group_option = g;
 	  else
 	  else
 	    FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
 	    FATAL_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
-			  _("%s: Invalid group")));
+			  _("Invalid group")));
 	}
 	}
       break;
       break;
-
+      
     case MODE_OPTION:
     case MODE_OPTION:
       mode_option = mode_compile (arg);
       mode_option = mode_compile (arg);
       if (!mode_option)
       if (!mode_option)
@@ -1752,49 +1751,49 @@ parse_opt (int key, char *arg, struct argp_state *state)
       initial_umask = umask (0);
       initial_umask = umask (0);
       umask (initial_umask);
       umask (initial_umask);
       break;
       break;
-
+      
     case NO_ANCHORED_OPTION:
     case NO_ANCHORED_OPTION:
       args->include_anchored = 0; /* Clear the default for comman line args */
       args->include_anchored = 0; /* Clear the default for comman line args */
       args->matching_flags &= ~ EXCLUDE_ANCHORED;
       args->matching_flags &= ~ EXCLUDE_ANCHORED;
       break;
       break;
-
+      
     case NO_IGNORE_CASE_OPTION:
     case NO_IGNORE_CASE_OPTION:
       args->matching_flags &= ~ FNM_CASEFOLD;
       args->matching_flags &= ~ FNM_CASEFOLD;
       break;
       break;
-
+      
     case NO_IGNORE_COMMAND_ERROR_OPTION:
     case NO_IGNORE_COMMAND_ERROR_OPTION:
       ignore_command_error_option = false;
       ignore_command_error_option = false;
       break;
       break;
-
+      
     case NO_OVERWRITE_DIR_OPTION:
     case NO_OVERWRITE_DIR_OPTION:
       old_files_option = NO_OVERWRITE_DIR_OLD_FILES;
       old_files_option = NO_OVERWRITE_DIR_OLD_FILES;
       break;
       break;
-
+      
     case NO_QUOTE_CHARS_OPTION:
     case NO_QUOTE_CHARS_OPTION:
       for (;*arg; arg++)
       for (;*arg; arg++)
 	set_char_quoting (NULL, *arg, 0);
 	set_char_quoting (NULL, *arg, 0);
       break;
       break;
-
+      
     case NO_WILDCARDS_OPTION:
     case NO_WILDCARDS_OPTION:
       args->wildcards = disable_wildcards;
       args->wildcards = disable_wildcards;
       break;
       break;
-
+      
     case NO_WILDCARDS_MATCH_SLASH_OPTION:
     case NO_WILDCARDS_MATCH_SLASH_OPTION:
       args->matching_flags |= FNM_FILE_NAME;
       args->matching_flags |= FNM_FILE_NAME;
       break;
       break;
-
+      
     case NULL_OPTION:
     case NULL_OPTION:
       filename_terminator = '\0';
       filename_terminator = '\0';
       break;
       break;
-
+      
     case NO_NULL_OPTION:
     case NO_NULL_OPTION:
       filename_terminator = '\n';
       filename_terminator = '\n';
       break;
       break;
-
+      
     case NUMERIC_OWNER_OPTION:
     case NUMERIC_OWNER_OPTION:
       numeric_owner_option = true;
       numeric_owner_option = true;
       break;
       break;
-
+      
     case OCCURRENCE_OPTION:
     case OCCURRENCE_OPTION:
       if (!arg)
       if (!arg)
 	occurrence_option = 1;
 	occurrence_option = 1;
@@ -1808,15 +1807,15 @@ parse_opt (int key, char *arg, struct argp_state *state)
 			  _("Invalid number")));
 			  _("Invalid number")));
 	}
 	}
       break;
       break;
-
+      
     case OVERWRITE_DIR_OPTION:
     case OVERWRITE_DIR_OPTION:
       old_files_option = DEFAULT_OLD_FILES;
       old_files_option = DEFAULT_OLD_FILES;
       break;
       break;
-
+      
     case OVERWRITE_OPTION:
     case OVERWRITE_OPTION:
       old_files_option = OVERWRITE_OLD_FILES;
       old_files_option = OVERWRITE_OLD_FILES;
       break;
       break;
-
+      
     case OWNER_OPTION:
     case OWNER_OPTION:
       if (! (strlen (arg) < UNAME_FIELD_SIZE
       if (! (strlen (arg) < UNAME_FIELD_SIZE
 	     && uname_to_uid (arg, &owner_option)))
 	     && uname_to_uid (arg, &owner_option)))
@@ -1830,25 +1829,25 @@ parse_opt (int key, char *arg, struct argp_state *state)
 			  _("Invalid owner")));
 			  _("Invalid owner")));
 	}
 	}
       break;
       break;
-
+      
     case QUOTE_CHARS_OPTION:
     case QUOTE_CHARS_OPTION:
       for (;*arg; arg++)
       for (;*arg; arg++)
 	set_char_quoting (NULL, *arg, 1);
 	set_char_quoting (NULL, *arg, 1);
       break;
       break;
-
+      
     case QUOTING_STYLE_OPTION:
     case QUOTING_STYLE_OPTION:
       tar_set_quoting_style (arg);
       tar_set_quoting_style (arg);
       break;
       break;
-
+      
     case PAX_OPTION:
     case PAX_OPTION:
       args->pax_option = true;
       args->pax_option = true;
       xheader_set_option (arg);
       xheader_set_option (arg);
       break;
       break;
-
+      
     case POSIX_OPTION:
     case POSIX_OPTION:
       set_archive_format ("posix");
       set_archive_format ("posix");
       break;
       break;
-
+      
     case PRESERVE_OPTION:
     case PRESERVE_OPTION:
       /* FIXME: What it is good for? */
       /* FIXME: What it is good for? */
       same_permissions_option = true;
       same_permissions_option = true;
@@ -1856,7 +1855,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
       WARN ((0, 0, _("The --preserve option is deprecated, "
       WARN ((0, 0, _("The --preserve option is deprecated, "
 		     "use --preserve-permissions --preserve-order instead")));
 		     "use --preserve-permissions --preserve-order instead")));
       break;
       break;
-
+      
     case RECORD_SIZE_OPTION:
     case RECORD_SIZE_OPTION:
       {
       {
 	uintmax_t u;
 	uintmax_t u;
@@ -1871,32 +1870,36 @@ parse_opt (int key, char *arg, struct argp_state *state)
 	blocking_factor = record_size / BLOCKSIZE;
 	blocking_factor = record_size / BLOCKSIZE;
       }
       }
       break;
       break;
-
+      
     case RECURSIVE_UNLINK_OPTION:
     case RECURSIVE_UNLINK_OPTION:
       recursive_unlink_option = true;
       recursive_unlink_option = true;
       break;
       break;
-
+      
     case REMOVE_FILES_OPTION:
     case REMOVE_FILES_OPTION:
       remove_files_option = true;
       remove_files_option = true;
       break;
       break;
-
+      
     case RESTRICT_OPTION:
     case RESTRICT_OPTION:
       restrict_option = true;
       restrict_option = true;
       break;
       break;
-
+      
     case RMT_COMMAND_OPTION:
     case RMT_COMMAND_OPTION:
       rmt_command = arg;
       rmt_command = arg;
       break;
       break;
-
+      
     case RSH_COMMAND_OPTION:
     case RSH_COMMAND_OPTION:
       rsh_command_option = arg;
       rsh_command_option = arg;
       break;
       break;
-
+      
     case SHOW_DEFAULTS_OPTION:
     case SHOW_DEFAULTS_OPTION:
-      show_default_settings (stdout);
-      close_stdout ();
-      exit (0);
-
+      {
+	char *s = format_default_settings ();
+	printf ("%s\n", s);
+	close_stdout ();
+	free (s);
+	exit (0);
+      }
+      
     case STRIP_COMPONENTS_OPTION:
     case STRIP_COMPONENTS_OPTION:
       {
       {
 	uintmax_t u;
 	uintmax_t u;
@@ -2062,7 +2065,7 @@ static struct argp argp = {
   N_("[FILE]..."),
   N_("[FILE]..."),
   doc,
   doc,
   NULL,
   NULL,
-  NULL,
+  tar_help_filter,
   NULL
   NULL
 };
 };