Replace long with int64_t in exiv2app.hpp
This commit is contained in:
parent
2e0ab1a037
commit
1ceddb2962
@ -179,7 +179,7 @@ int setModeAndPrintStructure(Exiv2::PrintStructureOption option, const std::stri
|
|||||||
ascii.write_uint8(str.size() * 3, 0);
|
ascii.write_uint8(str.size() * 3, 0);
|
||||||
std::copy(str.begin(), str.end(), iccProfile.begin());
|
std::copy(str.begin(), str.end(), iccProfile.begin());
|
||||||
if (Exiv2::base64encode(iccProfile.c_data(), str.size(), reinterpret_cast<char*>(ascii.data()), str.size() * 3)) {
|
if (Exiv2::base64encode(iccProfile.c_data(), str.size(), reinterpret_cast<char*>(ascii.data()), str.size() * 3)) {
|
||||||
long chunk = 60;
|
const size_t chunk = 60;
|
||||||
std::string code = std::string("data:") + ascii.c_str();
|
std::string code = std::string("data:") + ascii.c_str();
|
||||||
size_t length = code.size();
|
size_t length = code.size();
|
||||||
for (size_t start = 0; start < length; start += chunk) {
|
for (size_t start = 0; start < length; start += chunk) {
|
||||||
@ -364,8 +364,8 @@ int Print::printList() {
|
|||||||
auto image = Exiv2::ImageFactory::open(path_);
|
auto image = Exiv2::ImageFactory::open(path_);
|
||||||
image->readMetadata();
|
image->readMetadata();
|
||||||
// Set defaults for metadata types and data columns
|
// Set defaults for metadata types and data columns
|
||||||
if (Params::instance().printTags_ == Exiv2::mdNone) {
|
if (Params::instance().printTags_ == MetadataId::invalid) {
|
||||||
Params::instance().printTags_ = Exiv2::mdExif | Exiv2::mdIptc | Exiv2::mdXmp;
|
Params::instance().printTags_ = MetadataId::exif | MetadataId::iptc | MetadataId::xmp;
|
||||||
}
|
}
|
||||||
if (Params::instance().printItems_ == 0) {
|
if (Params::instance().printItems_ == 0) {
|
||||||
Params::instance().printItems_ = Params::prKey | Params::prType | Params::prCount | Params::prTrans;
|
Params::instance().printItems_ = Params::prKey | Params::prType | Params::prCount | Params::prTrans;
|
||||||
@ -376,7 +376,7 @@ int Print::printList() {
|
|||||||
int Print::printMetadata(const Exiv2::Image* image) {
|
int Print::printMetadata(const Exiv2::Image* image) {
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
bool noExif = false;
|
bool noExif = false;
|
||||||
if (Params::instance().printTags_ & Exiv2::mdExif) {
|
if ((Params::instance().printTags_ & MetadataId::exif) == MetadataId::exif) {
|
||||||
const Exiv2::ExifData& exifData = image->exifData();
|
const Exiv2::ExifData& exifData = image->exifData();
|
||||||
for (auto&& md : exifData) {
|
for (auto&& md : exifData) {
|
||||||
ret |= printMetadatum(md, image);
|
ret |= printMetadatum(md, image);
|
||||||
@ -386,7 +386,7 @@ int Print::printMetadata(const Exiv2::Image* image) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool noIptc = false;
|
bool noIptc = false;
|
||||||
if (Params::instance().printTags_ & Exiv2::mdIptc) {
|
if ((Params::instance().printTags_ & MetadataId::iptc) == MetadataId::iptc) {
|
||||||
const Exiv2::IptcData& iptcData = image->iptcData();
|
const Exiv2::IptcData& iptcData = image->iptcData();
|
||||||
for (auto&& md : iptcData) {
|
for (auto&& md : iptcData) {
|
||||||
ret |= printMetadatum(md, image);
|
ret |= printMetadatum(md, image);
|
||||||
@ -396,7 +396,7 @@ int Print::printMetadata(const Exiv2::Image* image) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool noXmp = false;
|
bool noXmp = false;
|
||||||
if (Params::instance().printTags_ & Exiv2::mdXmp) {
|
if ((Params::instance().printTags_ & MetadataId::xmp) == MetadataId::xmp) {
|
||||||
const Exiv2::XmpData& xmpData = image->xmpData();
|
const Exiv2::XmpData& xmpData = image->xmpData();
|
||||||
for (auto&& md : xmpData) {
|
for (auto&& md : xmpData) {
|
||||||
ret |= printMetadatum(md, image);
|
ret |= printMetadatum(md, image);
|
||||||
@ -1148,23 +1148,23 @@ int Modify::applyCommands(Exiv2::Image* pImage) {
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
for (auto&& cmd : modifyCmds) {
|
for (auto&& cmd : modifyCmds) {
|
||||||
switch (cmd.cmdId_) {
|
switch (cmd.cmdId_) {
|
||||||
case add:
|
case CmdId::add:
|
||||||
ret = addMetadatum(pImage, cmd);
|
ret = addMetadatum(pImage, cmd);
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
rc = ret;
|
rc = ret;
|
||||||
break;
|
break;
|
||||||
case set:
|
case CmdId::set:
|
||||||
ret = setMetadatum(pImage, cmd);
|
ret = setMetadatum(pImage, cmd);
|
||||||
if (rc == 0)
|
if (rc == 0)
|
||||||
rc = ret;
|
rc = ret;
|
||||||
break;
|
break;
|
||||||
case del:
|
case CmdId::del:
|
||||||
delMetadatum(pImage, cmd);
|
delMetadatum(pImage, cmd);
|
||||||
break;
|
break;
|
||||||
case reg:
|
case CmdId::reg:
|
||||||
regNamespace(cmd);
|
regNamespace(cmd);
|
||||||
break;
|
break;
|
||||||
case invalidCmdId:
|
case CmdId::invalid:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1184,13 +1184,13 @@ int Modify::addMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd) {
|
|||||||
auto value = Exiv2::Value::create(modifyCmd.typeId_);
|
auto value = Exiv2::Value::create(modifyCmd.typeId_);
|
||||||
int rc = value->read(modifyCmd.value_);
|
int rc = value->read(modifyCmd.value_);
|
||||||
if (0 == rc) {
|
if (0 == rc) {
|
||||||
if (modifyCmd.metadataId_ == exif) {
|
if (modifyCmd.metadataId_ == MetadataId::exif) {
|
||||||
exifData.add(Exiv2::ExifKey(modifyCmd.key_), value.get());
|
exifData.add(Exiv2::ExifKey(modifyCmd.key_), value.get());
|
||||||
}
|
}
|
||||||
if (modifyCmd.metadataId_ == iptc) {
|
if (modifyCmd.metadataId_ == MetadataId::iptc) {
|
||||||
iptcData.add(Exiv2::IptcKey(modifyCmd.key_), value.get());
|
iptcData.add(Exiv2::IptcKey(modifyCmd.key_), value.get());
|
||||||
}
|
}
|
||||||
if (modifyCmd.metadataId_ == xmp) {
|
if (modifyCmd.metadataId_ == MetadataId::xmp) {
|
||||||
xmpData.add(Exiv2::XmpKey(modifyCmd.key_), value.get());
|
xmpData.add(Exiv2::XmpKey(modifyCmd.key_), value.get());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1213,19 +1213,19 @@ int Modify::setMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd) {
|
|||||||
Exiv2::IptcData& iptcData = pImage->iptcData();
|
Exiv2::IptcData& iptcData = pImage->iptcData();
|
||||||
Exiv2::XmpData& xmpData = pImage->xmpData();
|
Exiv2::XmpData& xmpData = pImage->xmpData();
|
||||||
Exiv2::Metadatum* metadatum = nullptr;
|
Exiv2::Metadatum* metadatum = nullptr;
|
||||||
if (modifyCmd.metadataId_ == exif) {
|
if (modifyCmd.metadataId_ == MetadataId::exif) {
|
||||||
auto pos = exifData.findKey(Exiv2::ExifKey(modifyCmd.key_));
|
auto pos = exifData.findKey(Exiv2::ExifKey(modifyCmd.key_));
|
||||||
if (pos != exifData.end()) {
|
if (pos != exifData.end()) {
|
||||||
metadatum = &(*pos);
|
metadatum = &(*pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (modifyCmd.metadataId_ == iptc) {
|
if (modifyCmd.metadataId_ == MetadataId::iptc) {
|
||||||
auto pos = iptcData.findKey(Exiv2::IptcKey(modifyCmd.key_));
|
auto pos = iptcData.findKey(Exiv2::IptcKey(modifyCmd.key_));
|
||||||
if (pos != iptcData.end()) {
|
if (pos != iptcData.end()) {
|
||||||
metadatum = &(*pos);
|
metadatum = &(*pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (modifyCmd.metadataId_ == xmp) {
|
if (modifyCmd.metadataId_ == MetadataId::xmp) {
|
||||||
auto pos = xmpData.findKey(Exiv2::XmpKey(modifyCmd.key_));
|
auto pos = xmpData.findKey(Exiv2::XmpKey(modifyCmd.key_));
|
||||||
if (pos != xmpData.end()) {
|
if (pos != xmpData.end()) {
|
||||||
metadatum = &(*pos);
|
metadatum = &(*pos);
|
||||||
@ -1246,13 +1246,13 @@ int Modify::setMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd) {
|
|||||||
if (metadatum) {
|
if (metadatum) {
|
||||||
metadatum->setValue(value.get());
|
metadatum->setValue(value.get());
|
||||||
} else {
|
} else {
|
||||||
if (modifyCmd.metadataId_ == exif) {
|
if (modifyCmd.metadataId_ == MetadataId::exif) {
|
||||||
exifData.add(Exiv2::ExifKey(modifyCmd.key_), value.get());
|
exifData.add(Exiv2::ExifKey(modifyCmd.key_), value.get());
|
||||||
}
|
}
|
||||||
if (modifyCmd.metadataId_ == iptc) {
|
if (modifyCmd.metadataId_ == MetadataId::iptc) {
|
||||||
iptcData.add(Exiv2::IptcKey(modifyCmd.key_), value.get());
|
iptcData.add(Exiv2::IptcKey(modifyCmd.key_), value.get());
|
||||||
}
|
}
|
||||||
if (modifyCmd.metadataId_ == xmp) {
|
if (modifyCmd.metadataId_ == MetadataId::xmp) {
|
||||||
xmpData.add(Exiv2::XmpKey(modifyCmd.key_), value.get());
|
xmpData.add(Exiv2::XmpKey(modifyCmd.key_), value.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1273,21 +1273,21 @@ void Modify::delMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd) {
|
|||||||
Exiv2::ExifData& exifData = pImage->exifData();
|
Exiv2::ExifData& exifData = pImage->exifData();
|
||||||
Exiv2::IptcData& iptcData = pImage->iptcData();
|
Exiv2::IptcData& iptcData = pImage->iptcData();
|
||||||
Exiv2::XmpData& xmpData = pImage->xmpData();
|
Exiv2::XmpData& xmpData = pImage->xmpData();
|
||||||
if (modifyCmd.metadataId_ == exif) {
|
if (modifyCmd.metadataId_ == MetadataId::exif) {
|
||||||
Exiv2::ExifData::iterator pos;
|
Exiv2::ExifData::iterator pos;
|
||||||
const Exiv2::ExifKey exifKey(modifyCmd.key_);
|
const Exiv2::ExifKey exifKey(modifyCmd.key_);
|
||||||
while ((pos = exifData.findKey(exifKey)) != exifData.end()) {
|
while ((pos = exifData.findKey(exifKey)) != exifData.end()) {
|
||||||
exifData.erase(pos);
|
exifData.erase(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (modifyCmd.metadataId_ == iptc) {
|
if (modifyCmd.metadataId_ == MetadataId::iptc) {
|
||||||
Exiv2::IptcData::iterator pos;
|
Exiv2::IptcData::iterator pos;
|
||||||
const Exiv2::IptcKey iptcKey(modifyCmd.key_);
|
const Exiv2::IptcKey iptcKey(modifyCmd.key_);
|
||||||
while ((pos = iptcData.findKey(iptcKey)) != iptcData.end()) {
|
while ((pos = iptcData.findKey(iptcKey)) != iptcData.end()) {
|
||||||
iptcData.erase(pos);
|
iptcData.erase(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (modifyCmd.metadataId_ == xmp) {
|
if (modifyCmd.metadataId_ == MetadataId::xmp) {
|
||||||
Exiv2::XmpData::iterator pos;
|
Exiv2::XmpData::iterator pos;
|
||||||
const Exiv2::XmpKey xmpKey(modifyCmd.key_);
|
const Exiv2::XmpKey xmpKey(modifyCmd.key_);
|
||||||
if ((pos = xmpData.findKey(xmpKey)) != xmpData.end()) {
|
if ((pos = xmpData.findKey(xmpKey)) != xmpData.end()) {
|
||||||
@ -1617,7 +1617,7 @@ int str2Tm(const std::string& timeStr, struct tm* tm) {
|
|||||||
std::memset(tm, 0x0, sizeof(struct tm));
|
std::memset(tm, 0x0, sizeof(struct tm));
|
||||||
tm->tm_isdst = -1;
|
tm->tm_isdst = -1;
|
||||||
|
|
||||||
long tmp = 0;
|
int64_t tmp = 0;
|
||||||
if (!Util::strtol(timeStr.substr(0, 4).c_str(), tmp))
|
if (!Util::strtol(timeStr.substr(0, 4).c_str(), tmp))
|
||||||
return 5;
|
return 5;
|
||||||
// tmp is a 4-digit number so this cast cannot overflow
|
// tmp is a 4-digit number so this cast cannot overflow
|
||||||
@ -1759,7 +1759,7 @@ int metacopy(const std::string& source, const std::string& tgt, Exiv2::ImageType
|
|||||||
}
|
}
|
||||||
|
|
||||||
// #1148 use Raw XMP packet if there are no XMP modification commands
|
// #1148 use Raw XMP packet if there are no XMP modification commands
|
||||||
int tRawSidecar = Params::ctXmpSidecar | Params::ctXmpRaw; // option -eXX
|
Params::CommonTarget tRawSidecar = Params::ctXmpSidecar | Params::ctXmpRaw; // option -eXX
|
||||||
if (Params::instance().modifyCmds_.empty() && (Params::instance().target_ & tRawSidecar) == tRawSidecar) {
|
if (Params::instance().modifyCmds_.empty() && (Params::instance().target_ & tRawSidecar) == tRawSidecar) {
|
||||||
// std::cout << "short cut" << std::endl;
|
// std::cout << "short cut" << std::endl;
|
||||||
// http://www.cplusplus.com/doc/tutorial/files/
|
// http://www.cplusplus.com/doc/tutorial/files/
|
||||||
|
|||||||
@ -187,10 +187,10 @@ class Adjust : public Task {
|
|||||||
private:
|
private:
|
||||||
int adjustDateTime(Exiv2::ExifData& exifData, const std::string& key, const std::string& path) const;
|
int adjustDateTime(Exiv2::ExifData& exifData, const std::string& key, const std::string& path) const;
|
||||||
|
|
||||||
long adjustment_{0};
|
int64_t adjustment_{0};
|
||||||
long yearAdjustment_{0};
|
int64_t yearAdjustment_{0};
|
||||||
long monthAdjustment_{0};
|
int64_t monthAdjustment_{0};
|
||||||
long dayAdjustment_{0};
|
int64_t dayAdjustment_{0};
|
||||||
|
|
||||||
}; // class Adjust
|
}; // class Adjust
|
||||||
|
|
||||||
|
|||||||
@ -1,19 +1,26 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include "app_utils.hpp"
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
namespace Util {
|
namespace Util {
|
||||||
bool strtol(const char* nptr, long& n) {
|
bool strtol(const char* nptr, int64_t& n) {
|
||||||
if (!nptr || *nptr == '\0')
|
if (!nptr || *nptr == '\0')
|
||||||
return false;
|
return false;
|
||||||
char* endptr = nullptr;
|
char* endptr = nullptr;
|
||||||
long tmp = std::strtol(nptr, &endptr, 10);
|
long long tmp = std::strtoll(nptr, &endptr, 10);
|
||||||
if (*endptr != '\0')
|
if (*endptr != '\0')
|
||||||
return false;
|
return false;
|
||||||
if (tmp == LONG_MAX || tmp == LONG_MIN)
|
// strtoll returns LLONG_MAX or LLONG_MIN if an overflow occurs.
|
||||||
|
if (tmp == LLONG_MAX || tmp == LLONG_MIN)
|
||||||
return false;
|
return false;
|
||||||
n = tmp;
|
if (tmp < std::numeric_limits<int64_t>::min())
|
||||||
|
return false;
|
||||||
|
if (tmp > std::numeric_limits<int64_t>::max())
|
||||||
|
return false;
|
||||||
|
n = static_cast<int64_t>(tmp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,13 +3,15 @@
|
|||||||
#ifndef APP_UTILS_HPP_
|
#ifndef APP_UTILS_HPP_
|
||||||
#define APP_UTILS_HPP_
|
#define APP_UTILS_HPP_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace Util {
|
namespace Util {
|
||||||
/*!
|
/*!
|
||||||
@brief Convert a C string to a long value, which is returned in n.
|
@brief Convert a C string to an int64_t value, which is returned in n.
|
||||||
Returns true if the conversion is successful, else false.
|
Returns true if the conversion is successful, else false.
|
||||||
n is not modified if the conversion is unsuccessful. See strtol(2).
|
n is not modified if the conversion is unsuccessful. See strtol(2).
|
||||||
*/
|
*/
|
||||||
bool strtol(const char* nptr, long& n);
|
bool strtol(const char* nptr, int64_t& n);
|
||||||
} // namespace Util
|
} // namespace Util
|
||||||
|
|
||||||
#endif // #ifndef UTILS_HPP_
|
#endif // #ifndef UTILS_HPP_
|
||||||
|
|||||||
126
app/exiv2.cpp
126
app/exiv2.cpp
@ -42,7 +42,11 @@ const Params::YodAdjust emptyYodAdjust_[] = {
|
|||||||
|
|
||||||
//! List of all command identifiers and corresponding strings
|
//! List of all command identifiers and corresponding strings
|
||||||
const CmdIdAndString cmdIdAndString[] = {
|
const CmdIdAndString cmdIdAndString[] = {
|
||||||
{add, "add"}, {set, "set"}, {del, "del"}, {reg, "reg"}, {invalidCmdId, "invalidCmd"}, // End of list marker
|
{CmdId::add, "add"},
|
||||||
|
{CmdId::set, "set"},
|
||||||
|
{CmdId::del, "del"},
|
||||||
|
{CmdId::reg, "reg"},
|
||||||
|
{CmdId::invalid, "invalidCmd"}, // End of list marker
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return a command Id for a command string
|
// Return a command Id for a command string
|
||||||
@ -50,7 +54,7 @@ CmdId commandId(const std::string& cmdString);
|
|||||||
|
|
||||||
// Evaluate [-]HH[:MM[:SS]], returns true and sets time to the value
|
// Evaluate [-]HH[:MM[:SS]], returns true and sets time to the value
|
||||||
// in seconds if successful, else returns false.
|
// in seconds if successful, else returns false.
|
||||||
bool parseTime(const std::string& ts, long& time);
|
bool parseTime(const std::string& ts, int64_t& time);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief Parse the oparg string into a bitmap of common targets.
|
@brief Parse the oparg string into a bitmap of common targets.
|
||||||
@ -58,7 +62,7 @@ bool parseTime(const std::string& ts, long& time);
|
|||||||
@param action Action being processed
|
@param action Action being processed
|
||||||
@return A bitmap of common targets or -1 in case of a parse error
|
@return A bitmap of common targets or -1 in case of a parse error
|
||||||
*/
|
*/
|
||||||
int parseCommonTargets(const std::string& optArg, const std::string& action);
|
int64_t parseCommonTargets(const std::string& optArg, const std::string& action);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@brief Parse numbers separated by commas into container
|
@brief Parse numbers separated by commas into container
|
||||||
@ -672,13 +676,13 @@ int Params::evalPrintFlags(const std::string& optArg) {
|
|||||||
for (auto&& i : optArg) {
|
for (auto&& i : optArg) {
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 'E':
|
case 'E':
|
||||||
printTags_ |= Exiv2::mdExif;
|
printTags_ |= MetadataId::exif;
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
printTags_ |= Exiv2::mdIptc;
|
printTags_ |= MetadataId::iptc;
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
printTags_ |= Exiv2::mdXmp;
|
printTags_ |= MetadataId::xmp;
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
printItems_ |= prTag;
|
printItems_ |= prTag;
|
||||||
@ -735,81 +739,71 @@ int Params::evalPrintFlags(const std::string& optArg) {
|
|||||||
} // Params::evalPrintFlags
|
} // Params::evalPrintFlags
|
||||||
|
|
||||||
int Params::evalDelete(const std::string& optArg) {
|
int Params::evalDelete(const std::string& optArg) {
|
||||||
int rc = 0;
|
|
||||||
switch (action_) {
|
switch (action_) {
|
||||||
case Action::none:
|
case Action::none:
|
||||||
action_ = Action::erase;
|
action_ = Action::erase;
|
||||||
target_ = 0;
|
target_ = CommonTarget(0);
|
||||||
// fallthrough
|
// fallthrough
|
||||||
case Action::erase:
|
case Action::erase: {
|
||||||
rc = parseCommonTargets(optArg, "erase");
|
const auto rc = parseCommonTargets(optArg, "erase");
|
||||||
if (rc > 0) {
|
if (rc > 0) {
|
||||||
target_ |= rc;
|
target_ |= CommonTarget(rc);
|
||||||
rc = 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
rc = 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
default:
|
default:
|
||||||
std::cerr << progname() << ": " << _("Option -d is not compatible with a previous option\n");
|
std::cerr << progname() << ": " << _("Option -d is not compatible with a previous option\n");
|
||||||
rc = 1;
|
return 1;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return rc;
|
|
||||||
} // Params::evalDelete
|
} // Params::evalDelete
|
||||||
|
|
||||||
int Params::evalExtract(const std::string& optArg) {
|
int Params::evalExtract(const std::string& optArg) {
|
||||||
int rc = 0;
|
|
||||||
switch (action_) {
|
switch (action_) {
|
||||||
case Action::none:
|
case Action::none:
|
||||||
case Action::modify:
|
case Action::modify:
|
||||||
action_ = Action::extract;
|
action_ = Action::extract;
|
||||||
target_ = 0;
|
target_ = CommonTarget(0);
|
||||||
// fallthrough
|
// fallthrough
|
||||||
case Action::extract:
|
case Action::extract: {
|
||||||
rc = parseCommonTargets(optArg, "extract");
|
const auto rc = parseCommonTargets(optArg, "extract");
|
||||||
if (rc > 0) {
|
if (rc > 0) {
|
||||||
target_ |= rc;
|
target_ |= CommonTarget(rc);
|
||||||
rc = 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
rc = 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
default:
|
default:
|
||||||
std::cerr << progname() << ": " << _("Option -e is not compatible with a previous option\n");
|
std::cerr << progname() << ": " << _("Option -e is not compatible with a previous option\n");
|
||||||
rc = 1;
|
return 1;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return rc;
|
|
||||||
} // Params::evalExtract
|
} // Params::evalExtract
|
||||||
|
|
||||||
int Params::evalInsert(const std::string& optArg) {
|
int Params::evalInsert(const std::string& optArg) {
|
||||||
int rc = 0;
|
|
||||||
switch (action_) {
|
switch (action_) {
|
||||||
case Action::none:
|
case Action::none:
|
||||||
case Action::modify:
|
case Action::modify:
|
||||||
action_ = Action::insert;
|
action_ = Action::insert;
|
||||||
target_ = 0;
|
target_ = CommonTarget(0);
|
||||||
// fallthrough
|
// fallthrough
|
||||||
case Action::insert:
|
case Action::insert: {
|
||||||
rc = parseCommonTargets(optArg, "insert");
|
const auto rc = parseCommonTargets(optArg, "insert");
|
||||||
if (rc > 0) {
|
if (rc > 0) {
|
||||||
target_ |= rc;
|
target_ |= CommonTarget(rc);
|
||||||
rc = 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
rc = 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
default:
|
default:
|
||||||
std::cerr << progname() << ": " << _("Option -i is not compatible with a previous option\n");
|
std::cerr << progname() << ": " << _("Option -i is not compatible with a previous option\n");
|
||||||
rc = 1;
|
return 1;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return rc;
|
|
||||||
} // Params::evalInsert
|
} // Params::evalInsert
|
||||||
|
|
||||||
int Params::evalModify(int opt, const std::string& optArg) {
|
int Params::evalModify(int opt, const std::string& optArg) {
|
||||||
int rc = 0;
|
|
||||||
switch (action_) {
|
switch (action_) {
|
||||||
case Action::none:
|
case Action::none:
|
||||||
action_ = Action::modify;
|
action_ = Action::modify;
|
||||||
@ -823,14 +817,12 @@ int Params::evalModify(int opt, const std::string& optArg) {
|
|||||||
cmdFiles_.push_back(optArg); // parse the files later
|
cmdFiles_.push_back(optArg); // parse the files later
|
||||||
if (opt == 'M')
|
if (opt == 'M')
|
||||||
cmdLines_.push_back(optArg); // parse the commands later
|
cmdLines_.push_back(optArg); // parse the commands later
|
||||||
break;
|
return 0;
|
||||||
default:
|
default:
|
||||||
std::cerr << progname() << ": " << _("Option") << " -" << static_cast<char>(opt) << " "
|
std::cerr << progname() << ": " << _("Option") << " -" << static_cast<char>(opt) << " "
|
||||||
<< _("is not compatible with a previous option\n");
|
<< _("is not compatible with a previous option\n");
|
||||||
rc = 1;
|
return 1;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return rc;
|
|
||||||
} // Params::evalModify
|
} // Params::evalModify
|
||||||
|
|
||||||
int Params::nonoption(const std::string& argv) {
|
int Params::nonoption(const std::string& argv) {
|
||||||
@ -1090,7 +1082,7 @@ cleanup:
|
|||||||
// *****************************************************************************
|
// *****************************************************************************
|
||||||
// local implementations
|
// local implementations
|
||||||
namespace {
|
namespace {
|
||||||
bool parseTime(const std::string& ts, long& time) {
|
bool parseTime(const std::string& ts, int64_t& time) {
|
||||||
std::string hstr, mstr, sstr;
|
std::string hstr, mstr, sstr;
|
||||||
auto cts = new char[ts.length() + 1];
|
auto cts = new char[ts.length() + 1];
|
||||||
strcpy(cts, ts.c_str());
|
strcpy(cts, ts.c_str());
|
||||||
@ -1106,7 +1098,7 @@ bool parseTime(const std::string& ts, long& time) {
|
|||||||
delete[] cts;
|
delete[] cts;
|
||||||
|
|
||||||
int sign = 1;
|
int sign = 1;
|
||||||
long hh(0), mm(0), ss(0);
|
int64_t hh(0), mm(0), ss(0);
|
||||||
// [-]HH part
|
// [-]HH part
|
||||||
if (!Util::strtol(hstr.c_str(), hh))
|
if (!Util::strtol(hstr.c_str(), hh))
|
||||||
return false;
|
return false;
|
||||||
@ -1145,11 +1137,11 @@ void printUnrecognizedArgument(const char argc, const std::string& action) {
|
|||||||
<< argc << "'\n";
|
<< argc << "'\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
int parseCommonTargets(const std::string& optArg, const std::string& action) {
|
int64_t parseCommonTargets(const std::string& optArg, const std::string& action) {
|
||||||
int rc = 0;
|
int64_t rc = 0;
|
||||||
int target = 0;
|
Params::CommonTarget target = Params::CommonTarget(0);
|
||||||
int all = Params::ctExif | Params::ctIptc | Params::ctComment | Params::ctXmp;
|
Params::CommonTarget all = Params::ctExif | Params::ctIptc | Params::ctComment | Params::ctXmp;
|
||||||
int extra = Params::ctXmpSidecar | Params::ctExif | Params::ctIptc | Params::ctXmp;
|
Params::CommonTarget extra = Params::ctXmpSidecar | Params::ctExif | Params::ctIptc | Params::ctXmp;
|
||||||
for (size_t i = 0; rc == 0 && i < optArg.size(); ++i) {
|
for (size_t i = 0; rc == 0 && i < optArg.size(); ++i) {
|
||||||
switch (optArg[i]) {
|
switch (optArg[i]) {
|
||||||
case 'e':
|
case 'e':
|
||||||
@ -1183,7 +1175,7 @@ int parseCommonTargets(const std::string& optArg, const std::string& action) {
|
|||||||
target |= extra; // -eX
|
target |= extra; // -eX
|
||||||
if (i > 0) { // -eXX or -iXX
|
if (i > 0) { // -eXX or -iXX
|
||||||
target |= Params::ctXmpRaw;
|
target |= Params::ctXmpRaw;
|
||||||
target &= ~extra; // turn off those bits
|
target = Params::CommonTarget(target & ~extra); // turn off those bits
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1204,7 +1196,7 @@ int parseCommonTargets(const std::string& optArg, const std::string& action) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rc ? rc : target;
|
return rc ? rc : int64_t(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
int parsePreviewNumbers(Params::PreviewNumbers& previewNumbers, const std::string& optArg, int j) {
|
int parsePreviewNumbers(Params::PreviewNumbers& previewNumbers, const std::string& optArg, int j) {
|
||||||
@ -1334,38 +1326,38 @@ bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) {
|
|||||||
|
|
||||||
std::string cmd(line.substr(cmdStart, cmdEnd - cmdStart));
|
std::string cmd(line.substr(cmdStart, cmdEnd - cmdStart));
|
||||||
CmdId cmdId = commandId(cmd);
|
CmdId cmdId = commandId(cmd);
|
||||||
if (cmdId == invalidCmdId) {
|
if (cmdId == CmdId::invalid) {
|
||||||
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
|
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
|
||||||
Exiv2::toString(num) + ": " + _("Invalid command") + " `" + cmd + "'");
|
Exiv2::toString(num) + ": " + _("Invalid command") + " `" + cmd + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
Exiv2::TypeId defaultType = Exiv2::invalidTypeId;
|
Exiv2::TypeId defaultType = Exiv2::invalidTypeId;
|
||||||
std::string key(line.substr(keyStart, keyEnd - keyStart));
|
std::string key(line.substr(keyStart, keyEnd - keyStart));
|
||||||
MetadataId metadataId = invalidMetadataId;
|
MetadataId metadataId = MetadataId::invalid;
|
||||||
if (cmdId != reg) {
|
if (cmdId != CmdId::reg) {
|
||||||
try {
|
try {
|
||||||
Exiv2::IptcKey iptcKey(key);
|
Exiv2::IptcKey iptcKey(key);
|
||||||
metadataId = iptc;
|
metadataId = MetadataId::iptc;
|
||||||
defaultType = Exiv2::IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record());
|
defaultType = Exiv2::IptcDataSets::dataSetType(iptcKey.tag(), iptcKey.record());
|
||||||
} catch (const Exiv2::Error&) {
|
} catch (const Exiv2::Error&) {
|
||||||
}
|
}
|
||||||
if (metadataId == invalidMetadataId) {
|
if (metadataId == MetadataId::invalid) {
|
||||||
try {
|
try {
|
||||||
Exiv2::ExifKey exifKey(key);
|
Exiv2::ExifKey exifKey(key);
|
||||||
metadataId = exif;
|
metadataId = MetadataId::exif;
|
||||||
defaultType = exifKey.defaultTypeId();
|
defaultType = exifKey.defaultTypeId();
|
||||||
} catch (const Exiv2::Error&) {
|
} catch (const Exiv2::Error&) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (metadataId == invalidMetadataId) {
|
if (metadataId == MetadataId::invalid) {
|
||||||
try {
|
try {
|
||||||
Exiv2::XmpKey xmpKey(key);
|
Exiv2::XmpKey xmpKey(key);
|
||||||
metadataId = xmp;
|
metadataId = MetadataId::xmp;
|
||||||
defaultType = Exiv2::XmpProperties::propertyType(xmpKey);
|
defaultType = Exiv2::XmpProperties::propertyType(xmpKey);
|
||||||
} catch (const Exiv2::Error&) {
|
} catch (const Exiv2::Error&) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (metadataId == invalidMetadataId) {
|
if (metadataId == MetadataId::invalid) {
|
||||||
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
|
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
|
||||||
Exiv2::toString(num) + ": " + _("Invalid key") + " `" + key + "'");
|
Exiv2::toString(num) + ": " + _("Invalid key") + " `" + key + "'");
|
||||||
}
|
}
|
||||||
@ -1373,7 +1365,7 @@ bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) {
|
|||||||
std::string value;
|
std::string value;
|
||||||
Exiv2::TypeId type = defaultType;
|
Exiv2::TypeId type = defaultType;
|
||||||
bool explicitType = false;
|
bool explicitType = false;
|
||||||
if (cmdId != del) {
|
if (cmdId != CmdId::del) {
|
||||||
// Get type and value
|
// Get type and value
|
||||||
std::string::size_type typeStart = std::string::npos;
|
std::string::size_type typeStart = std::string::npos;
|
||||||
if (keyEnd != std::string::npos)
|
if (keyEnd != std::string::npos)
|
||||||
@ -1386,12 +1378,12 @@ bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) {
|
|||||||
if (valStart != std::string::npos)
|
if (valStart != std::string::npos)
|
||||||
valEnd = line.find_last_not_of(delim);
|
valEnd = line.find_last_not_of(delim);
|
||||||
|
|
||||||
if (cmdId == reg && (keyEnd == std::string::npos || valStart == std::string::npos)) {
|
if (cmdId == CmdId::reg && (keyEnd == std::string::npos || valStart == std::string::npos)) {
|
||||||
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
|
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
|
||||||
Exiv2::toString(num) + ": " + _("Invalid command line") + " ");
|
Exiv2::toString(num) + ": " + _("Invalid command line") + " ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmdId != reg && typeStart != std::string::npos && typeEnd != std::string::npos) {
|
if (cmdId != CmdId::reg && typeStart != std::string::npos && typeEnd != std::string::npos) {
|
||||||
std::string typeStr(line.substr(typeStart, typeEnd - typeStart));
|
std::string typeStr(line.substr(typeStart, typeEnd - typeStart));
|
||||||
Exiv2::TypeId tmpType = Exiv2::TypeInfo::typeId(typeStr);
|
Exiv2::TypeId tmpType = Exiv2::TypeInfo::typeId(typeStr);
|
||||||
if (tmpType != Exiv2::invalidTypeId) {
|
if (tmpType != Exiv2::invalidTypeId) {
|
||||||
@ -1421,7 +1413,7 @@ bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) {
|
|||||||
modifyCmd.explicitType_ = explicitType;
|
modifyCmd.explicitType_ = explicitType;
|
||||||
modifyCmd.value_ = value;
|
modifyCmd.value_ = value;
|
||||||
|
|
||||||
if (cmdId == reg) {
|
if (cmdId == CmdId::reg) {
|
||||||
if (value.empty()) {
|
if (value.empty()) {
|
||||||
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
|
throw Exiv2::Error(Exiv2::ErrorCode::kerErrorMessage,
|
||||||
Exiv2::toString(num) + ": " + _("Empty value for key") + +" `" + key + "'");
|
Exiv2::toString(num) + ": " + _("Empty value for key") + +" `" + key + "'");
|
||||||
@ -1437,7 +1429,7 @@ bool parseLine(ModifyCmd& modifyCmd, const std::string& line, int num) {
|
|||||||
|
|
||||||
CmdId commandId(const std::string& cmdString) {
|
CmdId commandId(const std::string& cmdString) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (cmdIdAndString[i].first != invalidCmdId && cmdIdAndString[i].second != cmdString) {
|
while (cmdIdAndString[i].first != CmdId::invalid && cmdIdAndString[i].second != cmdString) {
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
return cmdIdAndString[i].first;
|
return cmdIdAndString[i].first;
|
||||||
|
|||||||
@ -21,28 +21,40 @@
|
|||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
//! Command identifiers
|
//! Command identifiers
|
||||||
enum CmdId {
|
enum class CmdId {
|
||||||
invalidCmdId,
|
invalid,
|
||||||
add,
|
add,
|
||||||
set,
|
set,
|
||||||
del,
|
del,
|
||||||
reg,
|
reg,
|
||||||
};
|
};
|
||||||
//! Metadata identifiers
|
//! Metadata identifiers
|
||||||
enum MetadataId {
|
enum class MetadataId : uint32_t {
|
||||||
invalidMetadataId = Exiv2::mdNone, // 0
|
invalid = Exiv2::mdNone, // 0
|
||||||
exif = Exiv2::mdExif, // 1
|
exif = Exiv2::mdExif, // 1
|
||||||
iptc = Exiv2::mdIptc, // 2
|
iptc = Exiv2::mdIptc, // 2
|
||||||
xmp = Exiv2::mdXmp, // 8
|
xmp = Exiv2::mdXmp, // 8
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline MetadataId operator&(MetadataId x, MetadataId y) {
|
||||||
|
return (MetadataId)(uint32_t(x) & uint32_t(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MetadataId operator|(MetadataId x, MetadataId y) {
|
||||||
|
return (MetadataId)(uint32_t(x) | uint32_t(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline MetadataId& operator|=(MetadataId& x, MetadataId y) {
|
||||||
|
return x = x | y;
|
||||||
|
}
|
||||||
|
|
||||||
//! Structure for one parsed modification command
|
//! Structure for one parsed modification command
|
||||||
struct ModifyCmd {
|
struct ModifyCmd {
|
||||||
//! C'tor
|
//! C'tor
|
||||||
ModifyCmd() = default;
|
ModifyCmd() = default;
|
||||||
CmdId cmdId_{invalidCmdId}; //!< Command identifier
|
CmdId cmdId_{CmdId::invalid}; //!< Command identifier
|
||||||
std::string key_; //!< Exiv2 key string
|
std::string key_; //!< Exiv2 key string
|
||||||
MetadataId metadataId_{invalidMetadataId}; //!< Metadata identifier
|
MetadataId metadataId_{MetadataId::invalid}; //!< Metadata identifier
|
||||||
Exiv2::TypeId typeId_{Exiv2::invalidTypeId}; //!< Exiv2 type identifier
|
Exiv2::TypeId typeId_{Exiv2::invalidTypeId}; //!< Exiv2 type identifier
|
||||||
//! Flag to indicate if the type was explicitly specified (true)
|
//! Flag to indicate if the type was explicitly specified (true)
|
||||||
bool explicitType_{false};
|
bool explicitType_{false};
|
||||||
@ -125,7 +137,7 @@ class Params : public Util::Getopt {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! Individual items to print, bitmap
|
//! Individual items to print, bitmap
|
||||||
enum PrintItem {
|
enum PrintItem : uint32_t {
|
||||||
prTag = 1,
|
prTag = 1,
|
||||||
prGroup = 2,
|
prGroup = 2,
|
||||||
prKey = 4,
|
prKey = 4,
|
||||||
@ -141,7 +153,7 @@ class Params : public Util::Getopt {
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! Enumerates common targets, bitmap
|
//! Enumerates common targets, bitmap
|
||||||
enum CommonTarget {
|
enum CommonTarget : uint32_t {
|
||||||
ctExif = 1,
|
ctExif = 1,
|
||||||
ctIptc = 2,
|
ctIptc = 2,
|
||||||
ctComment = 4,
|
ctComment = 4,
|
||||||
@ -173,7 +185,7 @@ class Params : public Util::Getopt {
|
|||||||
struct YodAdjust {
|
struct YodAdjust {
|
||||||
bool flag_; //!< Adjustment flag.
|
bool flag_; //!< Adjustment flag.
|
||||||
const char* option_; //!< Adjustment option string.
|
const char* option_; //!< Adjustment option string.
|
||||||
long adjustment_; //!< Adjustment value.
|
int64_t adjustment_; //!< Adjustment value.
|
||||||
};
|
};
|
||||||
|
|
||||||
bool help_{false}; //!< Help option flag.
|
bool help_{false}; //!< Help option flag.
|
||||||
@ -188,13 +200,13 @@ class Params : public Util::Getopt {
|
|||||||
FileExistsPolicy fileExistsPolicy_{askPolicy}; //!< What to do if file to rename exists.
|
FileExistsPolicy fileExistsPolicy_{askPolicy}; //!< What to do if file to rename exists.
|
||||||
bool adjust_{false}; //!< Adjustment flag.
|
bool adjust_{false}; //!< Adjustment flag.
|
||||||
PrintMode printMode_{pmSummary}; //!< Print mode.
|
PrintMode printMode_{pmSummary}; //!< Print mode.
|
||||||
unsigned long printItems_{0}; //!< Print items.
|
PrintItem printItems_{0}; //!< Print items.
|
||||||
unsigned long printTags_{Exiv2::mdNone}; //!< Print tags (bitmap of MetadataId flags).
|
MetadataId printTags_{Exiv2::mdNone}; //!< Print tags (bitmap of MetadataId flags).
|
||||||
//! %Action (integer rather than TaskType to avoid dependency).
|
//! %Action (integer rather than TaskType to avoid dependency).
|
||||||
int action_{0};
|
int action_{0};
|
||||||
int target_; //!< What common target to process.
|
CommonTarget target_; //!< What common target to process.
|
||||||
|
|
||||||
long adjustment_{0}; //!< Adjustment in seconds.
|
int64_t adjustment_{0}; //!< Adjustment in seconds.
|
||||||
YodAdjust yodAdjust_[3]; //!< Year, month and day adjustment info.
|
YodAdjust yodAdjust_[3]; //!< Year, month and day adjustment info.
|
||||||
std::string format_; //!< Filename format (-r option arg).
|
std::string format_; //!< Filename format (-r option arg).
|
||||||
bool formatSet_{false}; //!< Whether the format is set with -r
|
bool formatSet_{false}; //!< Whether the format is set with -r
|
||||||
@ -270,4 +282,20 @@ class Params : public Util::Getopt {
|
|||||||
|
|
||||||
}; // class Params
|
}; // class Params
|
||||||
|
|
||||||
|
inline Params::CommonTarget operator|(Params::CommonTarget x, Params::CommonTarget y) {
|
||||||
|
return (Params::CommonTarget)(uint32_t(x) | uint32_t(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Params::CommonTarget& operator|=(Params::CommonTarget& x, Params::CommonTarget y) {
|
||||||
|
return x = x | y;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Params::PrintItem operator|(Params::PrintItem x, Params::PrintItem y) {
|
||||||
|
return (Params::PrintItem)(uint32_t(x) | uint32_t(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Params::PrintItem& operator|=(Params::PrintItem& x, Params::PrintItem y) {
|
||||||
|
return x = x | y;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // #ifndef EXIV2APP_HPP_
|
#endif // #ifndef EXIV2APP_HPP_
|
||||||
|
|||||||
36
tests/bugfixes/github/test_pr_2244.py
Normal file
36
tests/bugfixes/github/test_pr_2244.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from system_tests import CaseMeta, CopyTmpFiles, path
|
||||||
|
@CopyTmpFiles("$data_path/test_issue_1180.exv")
|
||||||
|
|
||||||
|
class test_pr_2244(metaclass=CaseMeta):
|
||||||
|
|
||||||
|
filename = path("$tmp_path/test_issue_1180.exv")
|
||||||
|
commands = [ "$exiv2 -Y 10000000000 $filename",
|
||||||
|
"$exiv2 -Y -10000000000 $filename",
|
||||||
|
"$exiv2 -O 10000000000 $filename",
|
||||||
|
"$exiv2 -O -10000000000 $filename",
|
||||||
|
"$exiv2 -D 1000000000000000 $filename",
|
||||||
|
"$exiv2 -D -1000000000000000 $filename"
|
||||||
|
]
|
||||||
|
stdout = [ "",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
stderr = [ "Uncaught exception: year adjustment too high\n",
|
||||||
|
"Uncaught exception: year adjustment too low\n",
|
||||||
|
"Uncaught exception: month adjustment too high\n",
|
||||||
|
"Uncaught exception: month adjustment too low\n",
|
||||||
|
"Uncaught exception: day adjustment too high\n",
|
||||||
|
"Uncaught exception: day adjustment too low\n"
|
||||||
|
]
|
||||||
|
retval = [ 1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
1
|
||||||
|
]
|
||||||
Loading…
Reference in New Issue
Block a user