Skip to content

Commit

Permalink
Fix exiv2: verbose extract stdout mutli-file (#2068)
Browse files Browse the repository at this point in the history
When using `exiv2 --verbose --extract` with stdout and multiple files, the output is concatenated together.
  • Loading branch information
postscript-dev authored Feb 5, 2022
1 parent fde0f9e commit 46c3290
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 16 deletions.
2 changes: 1 addition & 1 deletion exiv2.md
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ Extract target(s) for the [extract](#ex_extract) action. Possible targets are:
| C | Extract ICC profile, to a file called *\<file\>.icc* (see [ICC PROFILES](#icc_profiles)) |
| X | Extract metadata to an XMP sidecar file, \<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, \<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).

Expand Down
35 changes: 20 additions & 15 deletions src/exiv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,23 +159,28 @@ int main(int argc, char* const argv[])
// Process all files
int n = 1;
int s = static_cast<int>(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;
Expand Down
16 changes: 16 additions & 0 deletions tests/bugfixes/github/test_pr_2068.py
Original file line number Diff line number Diff line change
@@ -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]

0 comments on commit 46c3290

Please sign in to comment.