diff --git a/exiv2.md b/exiv2.md index c3134ad0..6049327f 100644 --- a/exiv2.md +++ b/exiv2.md @@ -660,7 +660,7 @@ Extract target(s) for the [extract](#ex_extract) action. Possible targets are: | C | Extract ICC profile, to a file called *\.icc* (see [ICC PROFILES](#icc_profiles)) | | X | Extract metadata to an XMP sidecar file, \.xmp. Other targets cannot be used with this, as only XMP data is written. Extracted XMP tags include those converted from Exif and IPTC | | XX | Extract "raw" metadata to a sidecar file, \.exv. The remaining targets determine which metadata to include, possible are Exif and IPTC (XMP is always included) | -| - | Output to stdout (see [--insert tgt2](#insert_tgt2) for an example of this feature). This argument ignores [--verbose](#verbose) | +| - | Output to stdout (see example in [--insert tgt2](#insert_tgt2)). This ignores [--verbose](#verbose) and only allows extracting from 1 file | To extract to a location other than the current directory, use [--location dir](#location_dir). diff --git a/src/exiv2.cpp b/src/exiv2.cpp index c353ea04..8478278e 100644 --- a/src/exiv2.cpp +++ b/src/exiv2.cpp @@ -159,23 +159,28 @@ int main(int argc, char* const argv[]) // Process all files int n = 1; int s = static_cast(params.files_.size()); - int w = s > 9 ? s > 99 ? 3 : 2 : 1; - for (auto&& file : params.files_) { - // If extracting to stdout then ignore verbose - if (params.verbose_ && !(params.action_ & Action::extract && params.target_ & Params::ctStdInOut)) { - std::cout << _("File") << " " << std::setw(w) << std::right << n++ << "/" << s << ": " << file - << std::endl; - } - task->setBinary(params.binary_); - int ret = task->run(file); - if (rc == 0) - rc = ret; + if (params.action_ & Action::extract && params.target_ & Params::ctStdInOut && s > 1) { + std::cerr << params.progname() << ": " << _("Only one file is allowed when extracting to stdout") << std::endl; + rc = 1; } + else { + int w = s > 9 ? s > 99 ? 3 : 2 : 1; + for (auto&& file : params.files_) { + // If extracting to stdout then ignore verbose + if (params.verbose_ && !(params.action_ & Action::extract && params.target_ & Params::ctStdInOut)) { + std::cout << _("File") << " " << std::setw(w) << std::right << n++ << "/" << s << ": " << file + << std::endl; + } + task->setBinary(params.binary_); + int ret = task->run(file); + if (rc == 0) + rc = ret; + } - taskFactory.cleanup(); - Params::cleanup(); - Exiv2::XmpParser::terminate(); - + taskFactory.cleanup(); + Params::cleanup(); + Exiv2::XmpParser::terminate(); + } } catch (const std::exception& exc) { std::cerr << "Uncaught exception: " << exc.what() << std::endl; rc = 1; diff --git a/tests/bugfixes/github/test_pr_2068.py b/tests/bugfixes/github/test_pr_2068.py new file mode 100644 index 00000000..d25c1860 --- /dev/null +++ b/tests/bugfixes/github/test_pr_2068.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + +import system_tests +from system_tests import CaseMeta, path + +class TestVerboseExtractStdoutMultiFile(metaclass=CaseMeta): + + filename = path("$data_path/exiv2-empty.jpg") + commands = ["$exiv2 --verbose --extract X- $filename $filename"] + + stdout = [""""""] + + stderr = ["""exiv2: Only one file is allowed when extracting to stdout +"""] + retval = [1] +