From: Sergey Poznyakoff Date: Thu, 13 Feb 2014 17:11:36 +0000 (+0200) Subject: Fix --one-top-level used together with --list. X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Ftar;a=commitdiff_plain;h=c86b0c21494752dc3fccda8f160af68d1135b13e 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. --- diff --git a/src/extract.c b/src/extract.c index 2cc1f7b..ca25603 100644 --- a/src/extract.c +++ b/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. */ diff --git a/src/tar.c b/src/tar.c index cd28495..7cd25c0 100644 --- a/src/tar.c +++ b/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. */ diff --git a/tests/Makefile.am b/tests/Makefile.am index 1f17a23..be00446 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -147,6 +147,7 @@ TESTSUITE_AT = \ onetop01.at\ onetop02.at\ onetop03.at\ + onetop04.at\ opcomp01.at\ opcomp02.at\ opcomp03.at\ diff --git a/tests/onetop04.at b/tests/onetop04.at new file mode 100644 index 0000000..37fba19 --- /dev/null +++ b/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 . +# +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 diff --git a/tests/testsuite.at b/tests/testsuite.at index 7123ce6..0e8eebc 100644 --- a/tests/testsuite.at +++ b/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])