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

Fix --one-top-level used together with --list.

* src/extract.c: Move one_top_level stuff to tar.c (decode_options).
* src/tar.c (option_conflict_error): New function.
(decode_options): Use option_conflict_error to complain about
conflicting options in a uniform manner.
Process one_top_level options here.
(request_stdin): Fix error message.
* tests/onetop04.at: New testcase: check --one-top-level with --list.
* tests/Makefile.am: Add new testcase.
* tests/testsuite.at: Add new testcase.
Sergey Poznyakoff 11 роки тому
батько
коміт
c86b0c2149
5 змінених файлів з 85 додано та 32 видалено
  1. 0 13
      src/extract.c
  2. 45 19
      src/tar.c
  3. 1 0
      tests/Makefile.am
  4. 38 0
      tests/onetop04.at
  5. 1 0
      tests/testsuite.at

+ 0 - 13
src/extract.c

@@ -191,19 +191,6 @@ extr_init (void)
       umask (newdir_umask);	/* restore the kernel umask */
       current_umask = newdir_umask;
     }
-
-  /* If the user wants to guarantee that everything is under one directory,
-     determine its name now and let it be created later.  */
-  if (one_top_level_option && !one_top_level_dir)
-    {
-      char *base = base_name (archive_name_array[0]);
-
-      one_top_level_dir = strip_compression_suffix (base);
-      free (base);
-      
-      if (!one_top_level_dir)
-	USAGE_ERROR ((0, 0, _("Cannot deduce top-level directory name; please set it explicitly with --one-top-level=DIR")));
-    }
 }
 
 /* Use fchmod if possible, fchmodat otherwise.  */

+ 45 - 19
src/tar.c

@@ -83,7 +83,7 @@ void
 request_stdin (const char *option)
 {
   if (stdin_used_by)
-    USAGE_ERROR ((0, 0, _("Options '-%s' and '-%s' both want standard input"),
+    USAGE_ERROR ((0, 0, _("Options '%s' and '%s' both want standard input"),
 		  stdin_used_by, option));
 
   stdin_used_by = option;
@@ -2235,6 +2235,14 @@ static int subcommand_class[] = {
 
 static struct tar_args args;
 
+static void
+option_conflict_error (const char *a, const char *b)
+{
+  /* TRANSLATORS: Both %s in this statement are replaced with
+     option names. */
+  USAGE_ERROR ((0, 0, _("'%s' cannot be used with '%s'"), a, b));
+}
+
 static void
 decode_options (int argc, char **argv)
 {
@@ -2397,14 +2405,10 @@ decode_options (int argc, char **argv)
 	USAGE_ERROR ((0, 0,
 		      _("--occurrence is meaningless without a file list")));
       if (!IS_SUBCOMMAND_CLASS (SUBCL_OCCUR))
-	USAGE_ERROR ((0, 0,
-		      _("--occurrence cannot be used with %s"),
-		      subcommand_string (subcommand_option)));
+	option_conflict_error ("--occurrence",
+			       subcommand_string (subcommand_option));
     }
 
-  if (one_top_level_option && absolute_names_option)
-    USAGE_ERROR ((0, 0, _("--one-top-level cannot be used with --absolute-names")));
-
   if (archive_names == 0)
     {
       /* If no archive file name given, try TAPE from the environment, or
@@ -2424,8 +2428,8 @@ decode_options (int argc, char **argv)
 
   if (listed_incremental_option
       && NEWER_OPTION_INITIALIZED (newer_mtime_option))
-    USAGE_ERROR ((0, 0,
-		  _("Cannot combine --listed-incremental with --newer")));
+    option_conflict_error ("--listed-incremental", "--newer");
+  
   if (incremental_level != -1 && !listed_incremental_option)
     WARN ((0, 0,
 	   _("--level is meaningless without --listed-incremental")));
@@ -2462,8 +2466,8 @@ decode_options (int argc, char **argv)
       if (use_compress_program_option)
 	USAGE_ERROR ((0, 0, _("Cannot verify compressed archives")));
       if (!IS_SUBCOMMAND_CLASS (SUBCL_WRITE))
-	USAGE_ERROR ((0, 0, _("--verify cannot be used with %s"),
-		      subcommand_string (subcommand_option)));
+	option_conflict_error ("--verify",
+			       subcommand_string (subcommand_option));
     }
 
   if (use_compress_program_option)
@@ -2502,12 +2506,35 @@ decode_options (int argc, char **argv)
       && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
     USAGE_ERROR ((0, 0, _("--xattrs can be used only on POSIX archives")));
 
-  if ((starting_file_option || same_order_option)
-      && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
-    USAGE_ERROR ((0, 0,
-		  _("--%s option cannot be used with %s"),
-		  starting_file_option ? "starting-file" : "same-order",
-		  subcommand_string (subcommand_option)));
+  if (starting_file_option && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
+    option_conflict_error ("--starting-file",
+			   subcommand_string (subcommand_option));
+
+  if (same_order_option && !IS_SUBCOMMAND_CLASS (SUBCL_READ))
+    option_conflict_error ("--same-order",
+			   subcommand_string (subcommand_option));
+
+  if (one_top_level_option)
+    {
+      char *base;
+      
+      if (!IS_SUBCOMMAND_CLASS (SUBCL_READ))
+	option_conflict_error ("--one-top-level",
+			       subcommand_string (subcommand_option));
+      if (absolute_names_option)
+	option_conflict_error ("--one-top-level", "--absolute-names");
+      
+      /* If the user wants to guarantee that everything is under one directory,
+	 determine its name now and let it be created later.  */
+      base = base_name (archive_name_array[0]);
+      one_top_level_dir = strip_compression_suffix (base);
+      free (base);
+	  
+      if (!one_top_level_dir)
+	USAGE_ERROR ((0, 0,
+		      _("Cannot deduce top-level directory name; "
+			"please set it explicitly with --one-top-level=DIR")));
+    }
 
   /* If ready to unlink hierarchies, so we are for simpler files.  */
   if (recursive_unlink_option)
@@ -2540,8 +2567,7 @@ decode_options (int argc, char **argv)
     USAGE_ERROR ((0, 0, _("Volume length cannot be less than record size")));
 
   if (same_order_option && listed_incremental_option)
-    USAGE_ERROR ((0, 0, _("--preserve-order is not compatible with "
-			  "--listed-incremental")));
+    option_conflict_error ("--preserve-order", "--listed-incremental");
 
   /* Forbid using -c with no input files whatsoever.  Check that '-f -',
      explicit or implied, is used correctly.  */

+ 1 - 0
tests/Makefile.am

@@ -147,6 +147,7 @@ TESTSUITE_AT = \
  onetop01.at\
  onetop02.at\
  onetop03.at\
+ onetop04.at\
  opcomp01.at\
  opcomp02.at\
  opcomp03.at\

+ 38 - 0
tests/onetop04.at

@@ -0,0 +1,38 @@
+# Process this file with autom4te to create testsuite. -*- Autotest -*-
+#
+# Test suite for GNU tar.
+# Copyright 2014 Free Software Foundation, Inc.
+#
+# This file is part of GNU tar.
+#
+# GNU tar 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.
+#
+# GNU tar 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+AT_SETUP([tar --one-top-level --transform])
+AT_KEYWORDS([extract onetop onetop02])
+
+AT_TAR_CHECK([
+AT_SORT_PREREQ
+mkdir a
+genfile --file a/b
+genfile --file c
+tar cf a.tar a c
+tar -tf a.tar --one-top-level --transform 's/c/d/' --show-transformed | sort
+],
+[0],
+[a/
+a/b
+a/d
+])
+
+AT_CLEANUP

+ 1 - 0
tests/testsuite.at

@@ -417,6 +417,7 @@ AT_BANNER([One top level])
 m4_include([onetop01.at])
 m4_include([onetop02.at])
 m4_include([onetop03.at])
+m4_include([onetop04.at])
 
 AT_BANNER([Star tests])
 m4_include([star/gtarfail.at])