From bff9c3637d9e3c010be697a81d93e934c919d83c Mon Sep 17 00:00:00 2001 From: Sergey Poznyakoff Date: Sat, 17 Aug 2013 13:48:24 +0300 Subject: [PATCH] Improve error diagnostics * src/names.c (file_list_name): New static function. (add_file_id): If a filelist is being read twice, print the names of the files that caused it. * tests/T-rec.at: New test case. * tests/Makefile.am: Add new file. * tests/testsuite.at: Include new file. --- src/names.c | 26 ++++++++++++++++++++++++-- tests/Makefile.am | 1 + tests/T-rec.at | 46 ++++++++++++++++++++++++++++++++++++++++++++++ tests/testsuite.at | 1 + 4 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 tests/T-rec.at diff --git a/src/names.c b/src/names.c index 94663d5..0eff2b4 100644 --- a/src/names.c +++ b/src/names.c @@ -340,29 +340,51 @@ struct file_id_list struct file_id_list *next; ino_t ino; dev_t dev; + const char *from_file; }; static struct file_id_list *file_id_list; +/* Return the name of the file from which the file names and options + are being read. +*/ +static const char * +file_list_name () +{ + struct name_elt *elt; + + for (elt = name_head; elt; elt = elt->next) + if (elt->type == NELT_FILE && elt->v.file.fp) + return elt->v.file.name; + return _("command line"); +} + static int add_file_id (const char *filename) { struct file_id_list *p; struct stat st; + const char *reading_from; if (stat (filename, &st)) stat_fatal (filename); + reading_from = file_list_name (); for (p = file_id_list; p; p = p->next) if (p->ino == st.st_ino && p->dev == st.st_dev) { - ERROR ((0, 0, _("%s: file list already read"), - quotearg_colon (filename))); + int oldc = set_char_quoting (NULL, ':', 1); + ERROR ((0, 0, + _("%s: file list requested from %s already read from %s"), + quotearg_n (0, filename), + reading_from, p->from_file)); + set_char_quoting (NULL, ':', oldc); return 1; } p = xmalloc (sizeof *p); p->next = file_id_list; p->ino = st.st_ino; p->dev = st.st_dev; + p->from_file = reading_from; file_id_list = p; return 0; } diff --git a/tests/Makefile.am b/tests/Makefile.am index 2783f9a..b6bceea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -45,6 +45,7 @@ TESTSUITE_AT = \ T-cd.at\ T-empty.at\ T-null.at\ + T-rec.at\ T-zfile.at\ T-nonl.at\ T-mult.at\ diff --git a/tests/T-rec.at b/tests/T-rec.at new file mode 100644 index 0000000..29965a3 --- /dev/null +++ b/tests/T-rec.at @@ -0,0 +1,46 @@ +# Process this file with autom4te to create testsuite. -*- Autotest -*- +# +# Test suite for GNU tar. +# Copyright 2013 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([recursive file lists]) +AT_KEYWORDS([files-from T-rec]) + +AT_TAR_CHECK([ +>file1 +>file2 +AT_DATA([F1],[file1 +-T F2 +]) +AT_DATA([F2],[file2 +-T F1 +]) +tar cf archive -T F1 +echo $? +tar tf archive +], +[0], +[2 +file1 +file2 +], +[tar: F1: file list requested from F2 already read from command line +tar: Exiting with failure status due to previous errors +],[],[],[ustar]) + +AT_CLEANUP diff --git a/tests/testsuite.at b/tests/testsuite.at index 5f7e4ea..36868c0 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -199,6 +199,7 @@ m4_include([opcomp06.at]) AT_BANNER([The -T option]) m4_include([T-mult.at]) m4_include([T-nest.at]) +m4_include([T-rec.at]) m4_include([T-cd.at]) m4_include([T-empty.at]) m4_include([T-null.at]) -- 2.43.0