From a8bb38ab6f485c8954bd21d7886ff7e1b1036bb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Mon, 14 Feb 2022 18:58:09 +0100 Subject: [PATCH 01/14] Move exiv2 app into its own folder --- CMakeLists.txt | 63 +++++++++++++++++++------------------ app/CMakeLists.txt | 57 ++++++++++++++++++++++++++++++++++ {src => app}/actions.cpp | 0 {src => app}/actions.hpp | 0 {src => app}/exiv2.cpp | 0 {src => app}/exiv2app.hpp | 0 {src => app}/getopt.cpp | 0 {src => app}/getopt.hpp | 0 samples/CMakeLists.txt | 21 +++++++++---- src/CMakeLists.txt | 65 --------------------------------------- 10 files changed, 103 insertions(+), 103 deletions(-) create mode 100644 app/CMakeLists.txt rename {src => app}/actions.cpp (100%) rename {src => app}/actions.hpp (100%) rename {src => app}/exiv2.cpp (100%) rename {src => app}/exiv2app.hpp (100%) rename {src => app}/getopt.cpp (100%) rename {src => app}/getopt.hpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3083b3e0..020a429a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,39 +99,38 @@ if( EXIV2_BUILD_FUZZ_TESTS ) add_subdirectory ( fuzz ) endif() -if( EXIV2_BUILD_SAMPLES ) - add_subdirectory( samples ) - get_directory_property(SAMPLES DIRECTORY samples DEFINITION APPLICATIONS) - - if (Python3_Interpreter_FOUND) - add_test(NAME bashTests - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests - COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose bash_tests - ) - endif() -endif() +if(EXIV2_BUILD_EXIV2_COMMAND) + add_subdirectory ( app ) + + if( EXIV2_BUILD_SAMPLES ) + add_subdirectory( samples ) + get_directory_property(SAMPLES DIRECTORY samples DEFINITION APPLICATIONS) + + if (Python3_Interpreter_FOUND) + add_test(NAME bashTests + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests + COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose bash_tests) + endif() + endif() + + if (Python3_Interpreter_FOUND) + add_test(NAME bugfixTests + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests + COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose bugfixes) + add_test(NAME lensTests + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests + COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose lens_tests) + add_test(NAME tiffTests + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests + COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose tiff_test) + add_test(NAME versionTests + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests + COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose bash_tests/version_test.py ) + add_test(NAME regressionTests + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests + COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose regression_tests) + endif() -if (Python3_Interpreter_FOUND) - add_test(NAME bugfixTests - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests - COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose bugfixes - ) - add_test(NAME lensTests - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests - COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose lens_tests - ) - add_test(NAME tiffTests - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests - COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose tiff_test - ) - add_test(NAME versionTests - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests - COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose bash_tests/version_test.py - ) - add_test(NAME regressionTests - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests - COMMAND cmake -E env EXIV2_BINDIR=${CMAKE_RUNTIME_OUTPUT_DIRECTORY} ${Python3_EXECUTABLE} runner.py --verbose regression_tests - ) endif() if( EXIV2_ENABLE_NLS ) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt new file mode 100644 index 00000000..7b679bf2 --- /dev/null +++ b/app/CMakeLists.txt @@ -0,0 +1,57 @@ +add_executable( exiv2 + exiv2.cpp + exiv2app.hpp + actions.cpp actions.hpp + getopt.cpp getopt.hpp + $ +) + +target_include_directories(exiv2 PRIVATE ${CMAKE_SOURCE_DIR}/src) # To find utils.hpp + +set_target_properties( exiv2 PROPERTIES + COMPILE_FLAGS ${EXTRA_COMPILE_FLAGS} + XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS[variant=Debug] "YES" +) +if (MSVC) + set_target_properties(exiv2 PROPERTIES LINK_FLAGS "/ignore:4099") # Ignore missing PDBs +endif() + +target_link_libraries( exiv2 PRIVATE exiv2lib ) + +if( EXIV2_ENABLE_NLS ) + target_link_libraries(exiv2 PRIVATE ${Intl_LIBRARIES}) + target_include_directories(exiv2 PRIVATE ${Intl_INCLUDE_DIRS}) +endif() + +target_link_libraries(exiv2 PRIVATE std::filesystem) + +if(MSVC OR MINGW) + # Trick to get properly UTF-8 encoded argv + # More info at: https://github.com/huangqinjin/wmain + add_library(wmain STATIC wmain.c) + target_link_libraries(exiv2 PRIVATE wmain) +endif() + +if (MSVC) + target_link_options(wmain INTERFACE /WHOLEARCHIVE:$) + target_link_options(exiv2 PRIVATE "/ENTRY:wWinMainCRTStartup") +endif() + +if (MINGW) + target_compile_options(exiv2 PRIVATE -municode) + target_link_options(exiv2 PRIVATE -municode) +endif() + +if (USING_CONAN AND WIN32 AND EXISTS ${PROJECT_BINARY_DIR}/conanDlls) + # In case of using conan recipes with their 'shared' option turned on, we will have dlls of + # the 3rd party dependencies in the conanDlls folder. + + # Copy 3rd party DLLs the bin folder. [build step] + add_custom_command(TARGET exiv2 POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_BINARY_DIR}/conanDlls ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) + + # Copy 3rd party DLLs the bin folder. [install step] + install(DIRECTORY ${PROJECT_BINARY_DIR}/conanDlls/ DESTINATION bin) +endif() + +install(TARGETS exiv2 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/src/actions.cpp b/app/actions.cpp similarity index 100% rename from src/actions.cpp rename to app/actions.cpp diff --git a/src/actions.hpp b/app/actions.hpp similarity index 100% rename from src/actions.hpp rename to app/actions.hpp diff --git a/src/exiv2.cpp b/app/exiv2.cpp similarity index 100% rename from src/exiv2.cpp rename to app/exiv2.cpp diff --git a/src/exiv2app.hpp b/app/exiv2app.hpp similarity index 100% rename from src/exiv2app.hpp rename to app/exiv2app.hpp diff --git a/src/getopt.cpp b/app/getopt.cpp similarity index 100% rename from src/getopt.cpp rename to app/getopt.cpp diff --git a/src/getopt.hpp b/app/getopt.hpp similarity index 100% rename from src/getopt.hpp rename to app/getopt.hpp diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index a6e1e524..c8442d52 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -52,18 +52,27 @@ if (MSVC) link_directories(${CMAKE_INSTALL_PREFIX}/lib) endif() -add_executable( getopt-test getopt-test.cpp ../src/utils.cpp ../src/getopt.cpp) +add_executable( getopt-test getopt-test.cpp ../app/getopt.cpp ../src/utils.cpp) list(APPEND APPLICATIONS getopt-test) -target_include_directories(getopt-test PRIVATE ${CMAKE_SOURCE_DIR}/src) # To find utils.hpp +target_include_directories(getopt-test PRIVATE + ${CMAKE_SOURCE_DIR}/app + ${CMAKE_SOURCE_DIR}/src +) # To find utils.hpp & getopt.hpp -add_executable( metacopy metacopy.cpp ../src/utils.cpp ../src/getopt.cpp) +add_executable( metacopy metacopy.cpp ../app/getopt.cpp ../src/utils.cpp) list(APPEND APPLICATIONS metacopy) -target_include_directories(metacopy PRIVATE ${CMAKE_SOURCE_DIR}/src) # To find utils.hpp +target_include_directories(metacopy PRIVATE + ${CMAKE_SOURCE_DIR}/app + ${CMAKE_SOURCE_DIR}/src +) # To find utils.hpp & getopt.hpp -add_executable( path-test path-test.cpp ../src/utils.cpp ../src/getopt.cpp) +add_executable( path-test path-test.cpp ../app/getopt.cpp ../src/utils.cpp) list(APPEND APPLICATIONS path-test) set_target_properties( path-test PROPERTIES OUTPUT_NAME path-test ) -target_include_directories(path-test PRIVATE ${CMAKE_SOURCE_DIR}/src) # To find utils.hpp +target_include_directories(path-test PRIVATE + ${CMAKE_SOURCE_DIR}/app + ${CMAKE_SOURCE_DIR}/src +) # To find utils.hpp & getopt.hpp add_executable( exiv2json exiv2json.cpp Jzon.cpp Jzon.h) list(APPEND APPLICATIONS exiv2json) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d418f600..b6f75c84 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,3 @@ -# CMakeLists.txt for exiv2 library and command-line program - # Note that this is a hack for testing the internals of the library. If EXIV2_BUILD_UNIT_TESTS==OFF # Then we only export the symbols that are explicitly exported if( EXIV2_BUILD_UNIT_TESTS ) @@ -261,66 +259,3 @@ install(EXPORT exiv2Config DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/exiv2") install(FILES ${CMAKE_CURRENT_BINARY_DIR}/exiv2ConfigVersion.cmake DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/exiv2") -# ****************************************************************************** -# exiv2 application - -if(EXIV2_BUILD_EXIV2_COMMAND) - add_executable( exiv2 - exiv2.cpp - exiv2app.hpp - actions.cpp actions.hpp - getopt.cpp getopt.hpp - utils.cpp utils.hpp - ) - - set_target_properties( exiv2 PROPERTIES - COMPILE_FLAGS ${EXTRA_COMPILE_FLAGS} - XCODE_ATTRIBUTE_GCC_GENERATE_DEBUGGING_SYMBOLS[variant=Debug] "YES" - ) - if (MSVC) - set_target_properties(exiv2 PROPERTIES LINK_FLAGS "/ignore:4099") # Ignore missing PDBs - endif() - - target_link_libraries( exiv2 PRIVATE exiv2lib ) - - if( EXIV2_ENABLE_NLS ) - target_link_libraries(exiv2 PRIVATE ${Intl_LIBRARIES}) - target_include_directories(exiv2 PRIVATE ${Intl_INCLUDE_DIRS}) - endif() - - target_link_libraries(exiv2 PRIVATE std::filesystem) - - if(MSVC OR MINGW) - # Trick to get properly UTF-8 encoded argv - # More info at: https://github.com/huangqinjin/wmain - add_library(wmain STATIC wmain.c) - target_link_libraries(exiv2 PRIVATE wmain) - endif() - - if (MSVC) - target_link_options(wmain INTERFACE /WHOLEARCHIVE:$) - target_link_options(exiv2 PRIVATE "/ENTRY:wWinMainCRTStartup") - endif() - - if (MINGW) - target_compile_options(exiv2 PRIVATE -municode) - target_link_options(exiv2 PRIVATE -municode) - endif() - - if (USING_CONAN AND WIN32 AND EXISTS ${PROJECT_BINARY_DIR}/conanDlls) - # In case of using conan recipes with their 'shared' option turned on, we will have dlls of - # the 3rd party dependencies in the conanDlls folder. - - # Copy 3rd party DLLs the bin folder. [build step] - add_custom_command(TARGET exiv2 POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy_directory ${PROJECT_BINARY_DIR}/conanDlls ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) - - # Copy 3rd party DLLs the bin folder. [install step] - install(DIRECTORY ${PROJECT_BINARY_DIR}/conanDlls/ DESTINATION bin) - endif() - - install(TARGETS exiv2 RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) -endif() - -# That's all Folks! -## From a725d22ea5a2a36787f080cc9f84a5c7c9753cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Mon, 14 Feb 2022 19:35:16 +0100 Subject: [PATCH 02/14] add characterisation tests for utils --- src/ini.cpp | 2 +- unitTests/CMakeLists.txt | 11 ++--- unitTests/test_utils.cpp | 91 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 6 deletions(-) create mode 100644 unitTests/test_utils.cpp diff --git a/src/ini.cpp b/src/ini.cpp index d946552c..827bd510 100755 --- a/src/ini.cpp +++ b/src/ini.cpp @@ -249,7 +249,7 @@ long INIReader::GetInteger(const string& section, const string& name, long defau const char* value = valstr.c_str(); char* end; // This parses "1234" (decimal) and also "0x4D2" (hex) - long n = strtol(value, &end, 0); + long n = std::strtol(value, &end, 0); return end > value ? n : default_value; } diff --git a/unitTests/CMakeLists.txt b/unitTests/CMakeLists.txt index 7e209a62..704d84a0 100644 --- a/unitTests/CMakeLists.txt +++ b/unitTests/CMakeLists.txt @@ -2,13 +2,11 @@ find_package(GTest REQUIRED) add_executable(unit_tests mainTestRunner.cpp + test_basicio.cpp test_bmpimage.cpp + test_cr2header_int.cpp test_datasets.cpp test_DateValue.cpp - test_TimeValue.cpp - test_XmpKey.cpp - test_basicio.cpp - test_cr2header_int.cpp test_enforce.cpp test_FileIo.cpp test_futils.cpp @@ -16,12 +14,15 @@ add_executable(unit_tests test_image_int.cpp test_ImageFactory.cpp test_IptcKey.cpp + test_LangAltValueRead.cpp test_pngimage.cpp test_safe_op.cpp test_slice.cpp test_tiffheader.cpp test_types.cpp - test_LangAltValueRead.cpp + test_TimeValue.cpp + test_utils.cpp + test_XmpKey.cpp $ ) diff --git a/unitTests/test_utils.cpp b/unitTests/test_utils.cpp new file mode 100644 index 00000000..530d5b1a --- /dev/null +++ b/unitTests/test_utils.cpp @@ -0,0 +1,91 @@ +#include + +// Auxiliary headers + +#include + +namespace { + const std::string pathLinux("/home/luis/file.txt"); + const std::string pathWindows("c:\\luis\\file.txt"); +} + +TEST(dirname, returnsDirNameWithValidPathOnLinux) +{ + ASSERT_EQ("/home/luis", Util::dirname(pathLinux)); +} + +TEST(dirname, returnsDirNameWithValidPathOnWindows) +{ + ASSERT_EQ("c:\\luis", Util::dirname(pathWindows)); +} + +TEST(dirname, returnsDotWithRelativePath) +{ + ASSERT_EQ(".", Util::dirname("file.txt")); +} + +TEST(dirname, returnsDotEmptyString) +{ + ASSERT_EQ(".", Util::dirname("")); +} + +/// \bug the logic for delsuffix is actually reverted +TEST(basename, returnsStemWithExtensionWithValidPathOnLinux) +{ + const bool delSuffix = false; + ASSERT_EQ("file.txt", Util::basename(pathLinux, delSuffix)); +} + +TEST(basename, returnsStemWithoutExtensionWithValidPathOnLinux) +{ + const bool delSuffix = true; + ASSERT_EQ("file", Util::basename(pathLinux, delSuffix)); +} + +TEST(basename, returnsStemWithExtensionWithValidPathOnWindows) +{ + const bool delSuffix = false; + ASSERT_EQ("file.txt", Util::basename(pathWindows, delSuffix)); +} + +TEST(basename, returnsStemWithoutExtensionWithValidPathOnWindows) +{ + const bool delSuffix = true; + ASSERT_EQ("file", Util::basename(pathWindows, delSuffix)); +} + +TEST(suffix, returnsExtensionWithValidLinuxPath) +{ + ASSERT_EQ(".txt", Util::suffix(pathLinux)); +} + + +TEST(suffix, returnsExtensionWithValidWindowsPath) +{ + ASSERT_EQ(".txt", Util::suffix(pathWindows)); +} + +TEST(suffix, returnsEmptyStringWithFilesWithoutExtension) +{ + ASSERT_EQ("", Util::suffix("/home/luis/file")); + ASSERT_EQ("", Util::suffix("c:\\luis\\file")); +} + +TEST(startsWith, returnsTrueWhenReferenceStringStartsWithSpecifiedString) +{ + ASSERT_TRUE(Util::startsWith("aabbccdd", "aab")); + ASSERT_TRUE(Util::startsWith("aabbccdd", "aa")); + ASSERT_TRUE(Util::startsWith("aabbccdd", "a")); +} + +TEST(startsWith, returnsFalseWhenReferenceStringDoesNotStartWithSpecifiedString) +{ + ASSERT_FALSE(Util::startsWith("aabbccdd", "b")); + ASSERT_FALSE(Util::startsWith("aabbccdd", "ab")); + ASSERT_FALSE(Util::startsWith("aabbccdd", "aac")); +} + +TEST(startsWith, returnsFalseWhenTargetStringIsLongerThanReference) +{ + ASSERT_FALSE(Util::startsWith("aabb", "aabbC")); +} From d1524e3d96cbd99de2ce4e4c7cfa74a5252f168f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Mon, 14 Feb 2022 19:38:45 +0100 Subject: [PATCH 03/14] simpler implementation of startsWith --- src/utils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.cpp b/src/utils.cpp index 389e4710..097954c8 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -121,7 +121,7 @@ namespace Util { bool startsWith(const std::string& s, const std::string& start) { - return s.size() >= start.size() && std::memcmp(s.data(), start.data(), start.size()) == 0; + return s.find(start) == 0; } From 49fbfb44a3494b19b034da93217538b95d73b40d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Mon, 14 Feb 2022 19:43:03 +0100 Subject: [PATCH 04/14] Remove startsWith from utils --- src/epsimage.cpp | 5 +++++ src/makernote_int.cpp | 4 +++- src/sonymn_int.cpp | 2 +- src/utils.cpp | 7 ------- src/utils.hpp | 9 --------- unitTests/test_utils.cpp | 19 ------------------- 6 files changed, 9 insertions(+), 37 deletions(-) diff --git a/src/epsimage.cpp b/src/epsimage.cpp index 1358faea..9fcaeea6 100644 --- a/src/epsimage.cpp +++ b/src/epsimage.cpp @@ -105,6 +105,11 @@ namespace { // closing part of all valid XMP trailers const std::string xmpTrailerEnd = "?>"; + bool startsWith(const std::string& s, const std::string& start) + { + return s.find(start) == 0; + } + //! Write data into temp file, taking care of errors void writeTemp(BasicIo& tempIo, const byte* data, size_t size) { diff --git a/src/makernote_int.cpp b/src/makernote_int.cpp index 164b5bb8..cf8a0444 100644 --- a/src/makernote_int.cpp +++ b/src/makernote_int.cpp @@ -1219,16 +1219,18 @@ namespace Exiv2 { }; return std::find(std::begin(models), std::end(models), getExifModel(pRoot)) != std::end(models) ? 0 : -1; } + int sony2FpSelector(uint16_t /*tag*/, const byte* /*pData*/, uint32_t /*size*/, TiffComponent* const pRoot) { // Not valid for models beginning std::string model = getExifModel(pRoot); for (auto& m : { "SLT-", "HV", "ILCA-" }) { - if (Util::startsWith(model, m)) + if (model.find(m) == 0) return -1; } return 0; } + int sonyMisc2bSelector(uint16_t /*tag*/, const byte* /*pData*/, uint32_t /*size*/, TiffComponent* const pRoot) { // From Exiftool: https://github.com/exiftool/exiftool/blob/master/lib/Image/ExifTool/Sony.pm diff --git a/src/sonymn_int.cpp b/src/sonymn_int.cpp index 0cc2f0bc..b168170d 100644 --- a/src/sonymn_int.cpp +++ b/src/sonymn_int.cpp @@ -905,7 +905,7 @@ namespace Exiv2 { // Ranges of models that do not support this tag std::string model = pos->toString(); for (auto& m : { "DSC-", "Stellar" }) { - if (Util::startsWith(model, m)) { + if (model.find(m) == 0) { os << N_("n/a"); return os; } diff --git a/src/utils.cpp b/src/utils.cpp index 097954c8..20f05bbd 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -118,11 +118,4 @@ namespace Util { index++; } } - - bool startsWith(const std::string& s, const std::string& start) - { - return s.find(start) == 0; - } - - } // namespace Util diff --git a/src/utils.hpp b/src/utils.hpp index 22beeb57..3a23099a 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -77,15 +77,6 @@ namespace Util { */ void replace(std::string& text, const std::string& searchText, const std::string& replaceText); - // TODO: When using C++20, replace with std::basic_string::starts_with() - // (suggested in https://github.com/Exiv2/exiv2/pull/1777). - /*! - @brief Tests if \em start occurs at the beginning of \em s. - Returns true if found, else false. - When Exiv2 uses C++20, this will be replaced with - std::basic_string::starts_with(). - */ - bool startsWith(const std::string& s, const std::string& start); } // namespace Util #endif // #ifndef UTILS_HPP_ diff --git a/unitTests/test_utils.cpp b/unitTests/test_utils.cpp index 530d5b1a..711176f5 100644 --- a/unitTests/test_utils.cpp +++ b/unitTests/test_utils.cpp @@ -70,22 +70,3 @@ TEST(suffix, returnsEmptyStringWithFilesWithoutExtension) ASSERT_EQ("", Util::suffix("/home/luis/file")); ASSERT_EQ("", Util::suffix("c:\\luis\\file")); } - -TEST(startsWith, returnsTrueWhenReferenceStringStartsWithSpecifiedString) -{ - ASSERT_TRUE(Util::startsWith("aabbccdd", "aab")); - ASSERT_TRUE(Util::startsWith("aabbccdd", "aa")); - ASSERT_TRUE(Util::startsWith("aabbccdd", "a")); -} - -TEST(startsWith, returnsFalseWhenReferenceStringDoesNotStartWithSpecifiedString) -{ - ASSERT_FALSE(Util::startsWith("aabbccdd", "b")); - ASSERT_FALSE(Util::startsWith("aabbccdd", "ab")); - ASSERT_FALSE(Util::startsWith("aabbccdd", "aac")); -} - -TEST(startsWith, returnsFalseWhenTargetStringIsLongerThanReference) -{ - ASSERT_FALSE(Util::startsWith("aabb", "aabbC")); -} From 8c6e22e6aa8453f952101a1937a77a9d29f0b5fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Mon, 14 Feb 2022 20:02:20 +0100 Subject: [PATCH 05/14] replace is only used in actions.cpp --- app/actions.cpp | 16 +++++++++++++--- src/utils.cpp | 9 --------- src/utils.hpp | 7 ------- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/app/actions.cpp b/app/actions.cpp index b75c74af..a58d467f 100644 --- a/app/actions.cpp +++ b/app/actions.cpp @@ -1958,13 +1958,23 @@ namespace { } }; + void replace(std::string& text, const std::string& searchText, const std::string& replaceText) + { + std::string::size_type index = 0; + while ((index = text.find(searchText, index)) != std::string::npos) + { + text.replace(index, searchText.length(), replaceText.c_str(), replaceText.length()); + index++; + } + } + int renameFile(std::string& newPath, const struct tm* tm) { std::string path = newPath; std::string format = Params::instance().format_; - Util::replace(format, ":basename:", Util::basename(path, true)); - Util::replace(format, ":dirname:", Util::basename(Util::dirname(path))); - Util::replace(format, ":parentname:", Util::basename(Util::dirname(Util::dirname(path)))); + replace(format, ":basename:", Util::basename(path, true)); + replace(format, ":dirname:", Util::basename(Util::dirname(path))); + replace(format, ":parentname:", Util::basename(Util::dirname(Util::dirname(path)))); const size_t max = 1024; char basename[max]; diff --git a/src/utils.cpp b/src/utils.cpp index 20f05bbd..0ef0f203 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -109,13 +109,4 @@ namespace Util { return true; } - void replace(std::string& text, const std::string& searchText, const std::string& replaceText) - { - std::string::size_type index = 0; - while ((index = text.find(searchText, index)) != std::string::npos) - { - text.replace(index, searchText.length(), replaceText.c_str(), replaceText.length()); - index++; - } - } } // namespace Util diff --git a/src/utils.hpp b/src/utils.hpp index 3a23099a..5f63b7d5 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -70,13 +70,6 @@ namespace Util { n is not modified if the conversion is unsuccessful. See strtol(2). */ bool strtol(const char* nptr, long& n); - - /*! - @brief Replaces all occurrences of \em searchText in the \em text string - by \em replaceText. - */ - void replace(std::string& text, const std::string& searchText, const std::string& replaceText); - } // namespace Util #endif // #ifndef UTILS_HPP_ From 7c6a7aefc22d82df1473c3160bedd07b41f07bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Mon, 14 Feb 2022 20:12:46 +0100 Subject: [PATCH 06/14] Utils::strtol only used in the app --- app/CMakeLists.txt | 1 + app/actions.cpp | 2 ++ app/app_utils.cpp | 22 ++++++++++++++++++++++ app/app_utils.hpp | 13 +++++++++++++ app/exiv2.cpp | 4 +++- src/utils.cpp | 11 ----------- src/utils.hpp | 7 ------- 7 files changed, 41 insertions(+), 19 deletions(-) create mode 100644 app/app_utils.cpp create mode 100644 app/app_utils.hpp diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 7b679bf2..2df7ff82 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -3,6 +3,7 @@ add_executable( exiv2 exiv2app.hpp actions.cpp actions.hpp getopt.cpp getopt.hpp + app_utils.cpp app_utils.hpp $ ) diff --git a/app/actions.cpp b/app/actions.cpp index a58d467f..d1f601ae 100644 --- a/app/actions.cpp +++ b/app/actions.cpp @@ -24,8 +24,10 @@ // included header files #include "config.h" +#include "app_utils.hpp" #include "actions.hpp" #include "exiv2app.hpp" + #include "image.hpp" #include "jpgimage.hpp" #include "xmpsidecar.hpp" diff --git a/app/app_utils.cpp b/app/app_utils.cpp new file mode 100644 index 00000000..dec2955c --- /dev/null +++ b/app/app_utils.cpp @@ -0,0 +1,22 @@ +#include "utils.hpp" + +#include +#include + +namespace Util +{ + bool strtol(const char* nptr, long& n) + { + if (!nptr || *nptr == '\0') + return false; + char* endptr = nullptr; + long tmp = std::strtol(nptr, &endptr, 10); + if (*endptr != '\0') + return false; + if (tmp == LONG_MAX || tmp == LONG_MIN) + return false; + n = tmp; + return true; + } + +} // namespace Util diff --git a/app/app_utils.hpp b/app/app_utils.hpp new file mode 100644 index 00000000..be8db686 --- /dev/null +++ b/app/app_utils.hpp @@ -0,0 +1,13 @@ +#ifndef APP_UTILS_HPP_ +#define APP_UTILS_HPP_ + +namespace Util { + /*! + @brief Convert a C string to a long value, which is returned in n. + Returns true if the conversion is successful, else false. + n is not modified if the conversion is unsuccessful. See strtol(2). + */ + bool strtol(const char* nptr, long& n); +} // namespace Util + +#endif // #ifndef UTILS_HPP_ diff --git a/app/exiv2.cpp b/app/exiv2.cpp index fe97449d..87fb2f99 100644 --- a/app/exiv2.cpp +++ b/app/exiv2.cpp @@ -22,8 +22,10 @@ // include local header files which are not part of libexiv2 #include "actions.hpp" -#include "convert.hpp" +#include "app_utils.hpp" #include "exiv2app.hpp" + +#include "convert.hpp" #include "futils.hpp" #include "getopt.hpp" #include "i18n.h" // NLS support. diff --git a/src/utils.cpp b/src/utils.cpp index 0ef0f203..72124f6a 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -98,15 +98,4 @@ namespace Util { return b.substr(idx); } - bool strtol(const char* nptr, long& n) - { - if (!nptr || *nptr == '\0') return false; - char* endptr = nullptr; - long tmp = std::strtol(nptr, &endptr, 10); - if (*endptr != '\0') return false; - if (tmp == LONG_MAX || tmp == LONG_MIN) return false; - n = tmp; - return true; - } - } // namespace Util diff --git a/src/utils.hpp b/src/utils.hpp index 5f63b7d5..42517a7f 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -63,13 +63,6 @@ namespace Util { to the end of the string. */ std::string suffix(const std::string& path); - - /*! - @brief Convert a C string to a long value, which is returned in n. - Returns true if the conversion is successful, else false. - n is not modified if the conversion is unsuccessful. See strtol(2). - */ - bool strtol(const char* nptr, long& n); } // namespace Util #endif // #ifndef UTILS_HPP_ From f1c8d5bbb4a417f728b48953390f47bce5c1b5da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Mon, 14 Feb 2022 20:14:08 +0100 Subject: [PATCH 07/14] Remove unused headers --- src/utils.cpp | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/utils.cpp b/src/utils.cpp index 72124f6a..62b454e9 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -18,29 +18,9 @@ * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. */ // ***************************************************************************** -// included header files -#include "config.h" #include "utils.hpp" -#if defined(_MSC_VER) -# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif - -// + standard includes -#ifdef EXV_HAVE_UNISTD_H -# include // for stat() -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include namespace Util { From d64c2aad672d3255e4b44597189d09c97bba3b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Mon, 14 Feb 2022 21:15:51 +0100 Subject: [PATCH 08/14] Replace dirname implementation with std::filesystem --- app/actions.cpp | 10 ++++----- src/utils.cpp | 24 +++++--------------- unitTests/test_utils.cpp | 47 +++++++++++++++++++++++----------------- 3 files changed, 38 insertions(+), 43 deletions(-) diff --git a/app/actions.cpp b/app/actions.cpp index d1f601ae..583371fc 100644 --- a/app/actions.cpp +++ b/app/actions.cpp @@ -2067,11 +2067,11 @@ namespace { std::string newFilePath(const std::string& path, const std::string& ext) { std::string directory = Params::instance().directory_; - if (directory.empty()) directory = Util::dirname(path); - directory = Exiv2::fileProtocol(path) == Exiv2::pFile - ? directory + EXV_SEPARATOR_STR - : "" // use current directory for remote files - ; + if (directory.empty()) + directory = Util::dirname(path); + directory = Exiv2::fileProtocol(path) == Exiv2::pFile ? directory + EXV_SEPARATOR_STR + : "" // use current directory for remote files + ; return directory + Util::basename(path, true) + ext; } diff --git a/src/utils.cpp b/src/utils.cpp index 62b454e9..7e89c1bf 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -21,6 +21,9 @@ #include "utils.hpp" +#include + +namespace fs = std::filesystem; namespace Util { @@ -29,25 +32,10 @@ namespace Util { std::string dirname(const std::string& path) { - if (path.empty()) + auto p = fs::path(path).parent_path(); + if (p.empty()) return "."; - // Strip trailing slashes or backslashes - std::string p = path; - while ( p.length() > 1 - && (p[p.length()-1] == '\\' || p[p.length()-1] == '/')) { - p = p.substr(0, p.length()-1); - } - if (p == "\\" || p == "/") return p; - if (p.length() == 2 && p[1] == ':') return p; // For Windows paths - std::string::size_type idx = p.find_last_of("\\/"); - if (idx == std::string::npos) return "."; - if (idx == 1 && p.at(0) == '\\' && p.at(1) == '\\') return p; // For Windows paths - p = p.substr(0, idx == 0 ? 1 : idx); - while ( p.length() > 1 - && (p[p.length()-1] == '\\' || p[p.length()-1] == '/')) { - p = p.substr(0, p.length()-1); - } - return p; + return p.string(); } std::string basename(const std::string& path, bool delsuffix) diff --git a/unitTests/test_utils.cpp b/unitTests/test_utils.cpp index 711176f5..137b04fe 100644 --- a/unitTests/test_utils.cpp +++ b/unitTests/test_utils.cpp @@ -6,18 +6,39 @@ namespace { const std::string pathLinux("/home/luis/file.txt"); - const std::string pathWindows("c:\\luis\\file.txt"); + const std::string pathWindows("c:/luis/file.txt"); } -TEST(dirname, returnsDirNameWithValidPathOnLinux) -{ - ASSERT_EQ("/home/luis", Util::dirname(pathLinux)); -} +#ifdef _WIN32 TEST(dirname, returnsDirNameWithValidPathOnWindows) { ASSERT_EQ("c:\\luis", Util::dirname(pathWindows)); } +TEST(basename, returnsStemWithExtensionWithValidPathOnWindows) +{ + const bool delSuffix = false; + ASSERT_EQ("file.txt", Util::basename(pathWindows, delSuffix)); +} + +TEST(basename, returnsStemWithoutExtensionWithValidPathOnWindows) +{ + const bool delSuffix = true; + ASSERT_EQ("file", Util::basename(pathWindows, delSuffix)); +} +TEST(suffix, returnsExtensionWithValidWindowsPath) +{ + ASSERT_EQ(".txt", Util::suffix(pathWindows)); +} + +#else + +TEST(dirname, returnsDirNameWithValidPathOnLinux) +{ + ASSERT_EQ("/home/luis", Util::dirname(pathLinux)); + ASSERT_EQ("/tmp", Util::dirname("/tmp/file.jpg")); +} + TEST(dirname, returnsDotWithRelativePath) { @@ -42,28 +63,14 @@ TEST(basename, returnsStemWithoutExtensionWithValidPathOnLinux) ASSERT_EQ("file", Util::basename(pathLinux, delSuffix)); } -TEST(basename, returnsStemWithExtensionWithValidPathOnWindows) -{ - const bool delSuffix = false; - ASSERT_EQ("file.txt", Util::basename(pathWindows, delSuffix)); -} - -TEST(basename, returnsStemWithoutExtensionWithValidPathOnWindows) -{ - const bool delSuffix = true; - ASSERT_EQ("file", Util::basename(pathWindows, delSuffix)); -} TEST(suffix, returnsExtensionWithValidLinuxPath) { ASSERT_EQ(".txt", Util::suffix(pathLinux)); } +#endif -TEST(suffix, returnsExtensionWithValidWindowsPath) -{ - ASSERT_EQ(".txt", Util::suffix(pathWindows)); -} TEST(suffix, returnsEmptyStringWithFilesWithoutExtension) { From 2c512086229ab5245670039afe4d93035f59210c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Mon, 14 Feb 2022 21:19:30 +0100 Subject: [PATCH 09/14] Replace basename implementation with std::filesystem --- src/utils.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/utils.cpp b/src/utils.cpp index 7e89c1bf..3abbed74 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -40,20 +40,10 @@ namespace Util { std::string basename(const std::string& path, bool delsuffix) { - if (path.empty()) - return "."; - // Strip trailing slashes or backslashes - std::string p = path; - while ( p.length() > 1 - && (p[p.length()-1] == '\\' || p[p.length()-1] == '/')) { - p = p.substr(0, p.length()-1); - } - if (p.length() == 2 && p[1] == ':') return ""; // For Windows paths - std::string::size_type idx = p.find_last_of("\\/"); - if (idx == 1 && p.at(0) == '\\' && p.at(1) == '\\') return ""; // For Windows paths - if (idx != std::string::npos) p = p.substr(idx+1); - if (delsuffix) p = p.substr(0, p.length() - suffix(p).length()); - return p; + auto p = fs::path(path); + if (delsuffix) + return p.stem().string(); + return p.filename().string(); } std::string suffix(const std::string& path) From dad3e7f5c4e4fd9c2fe27870ac6592058d5fec56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Mon, 14 Feb 2022 21:21:33 +0100 Subject: [PATCH 10/14] Replace suffix implementation with std::filesystem --- src/utils.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/utils.cpp b/src/utils.cpp index 3abbed74..c26df17b 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -48,12 +48,7 @@ namespace Util { std::string suffix(const std::string& path) { - std::string b = basename(path); - std::string::size_type idx = b.rfind('.'); - if (idx == std::string::npos || idx == 0 || idx == b.length()-1) { - return ""; - } - return b.substr(idx); + return fs::path(path).extension().string(); } } // namespace Util From 1b912fa887225bb2d370d1d5b7b9bb4d06fb4094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Mon, 14 Feb 2022 21:32:02 +0100 Subject: [PATCH 11/14] get rid of suffix --- app/actions.cpp | 20 ++++++------- src/utils.cpp | 6 ---- src/utils.hpp | 6 ---- test/data/test_reference_files/exiv2-test.out | 30 +++++++++---------- unitTests/test_utils.cpp | 17 ----------- 5 files changed, 25 insertions(+), 54 deletions(-) diff --git a/app/actions.cpp b/app/actions.cpp index 583371fc..11153ed9 100644 --- a/app/actions.cpp +++ b/app/actions.cpp @@ -1972,6 +1972,7 @@ namespace { int renameFile(std::string& newPath, const struct tm* tm) { + auto p = fs::path(newPath); std::string path = newPath; std::string format = Params::instance().format_; replace(format, ":basename:", Util::basename(path, true)); @@ -1986,8 +1987,9 @@ namespace { << path << "\n"; return 1; } - newPath = Util::dirname(path) + EXV_SEPARATOR_STR - + basename + Util::suffix(path); + + newPath = p.parent_path() / (basename + p.extension().string()); + if ( Util::dirname(newPath) == Util::dirname(path) && Util::basename(newPath) == Util::basename(path)) { if (Params::instance().verbose_) { @@ -2008,10 +2010,9 @@ namespace { go = false; break; case Params::renamePolicy: - newPath = Util::dirname(path) - + EXV_SEPARATOR_STR + basename - + "_" + Exiv2::toString(seq++) - + Util::suffix(path); + newPath = p.parent_path() / (std::string(basename) + "_" + + Exiv2::toString(seq++) + + p.extension().string()); break; case Params::askPolicy: std::cout << Params::instance().progname() @@ -2027,10 +2028,9 @@ namespace { case 'r': case 'R': fileExistsPolicy = Params::renamePolicy; - newPath = Util::dirname(path) - + EXV_SEPARATOR_STR + basename - + "_" + Exiv2::toString(seq++) - + Util::suffix(path); + newPath = p.parent_path() / (std::string(basename) + "_" + + Exiv2::toString(seq++) + + p.extension().string()); break; default: // skip return -1; diff --git a/src/utils.cpp b/src/utils.cpp index c26df17b..dbe3325f 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -45,10 +45,4 @@ namespace Util { return p.stem().string(); return p.filename().string(); } - - std::string suffix(const std::string& path) - { - return fs::path(path).extension().string(); - } - } // namespace Util diff --git a/src/utils.hpp b/src/utils.hpp index 42517a7f..8c081601 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -57,12 +57,6 @@ namespace Util { */ std::string basename(const std::string& path, bool delsuffix =false); - /*! - @brief Get the suffix from the path string. Normally, the suffix - is the substring of the basename of path from the last '.' - to the end of the string. - */ - std::string suffix(const std::string& path); } // namespace Util #endif // #ifndef UTILS_HPP_ diff --git a/test/data/test_reference_files/exiv2-test.out b/test/data/test_reference_files/exiv2-test.out index 11d52471..ec42d606 100644 --- a/test/data/test_reference_files/exiv2-test.out +++ b/test/data/test_reference_files/exiv2-test.out @@ -224,36 +224,36 @@ Rename ------------------------------------------------------------------- File 1/16: exiv2-empty.jpg exiv2-empty.jpg: No Exif data found in the file File 2/16: exiv2-canon-powershot-s40.jpg -Renaming file to ./20031214_000043.jpg +Renaming file to 20031214_000043.jpg File 3/16: exiv2-nikon-e990.jpg -Renaming file to ./20000506_020544.jpg +Renaming file to 20000506_020544.jpg File 4/16: exiv2-nikon-d70.jpg -Renaming file to ./20040329_224245.jpg +Renaming file to 20040329_224245.jpg File 5/16: exiv2-nikon-e950.jpg -Renaming file to ./20010405_235039.jpg +Renaming file to 20010405_235039.jpg File 6/16: exiv2-canon-eos-300d.jpg -Renaming file to ./20030925_201850.jpg +Renaming file to 20030925_201850.jpg File 7/16: exiv2-kodak-dc210.jpg -Renaming file to ./20001026_044550.jpg +Renaming file to 20001026_044550.jpg File 8/16: exiv2-fujifilm-finepix-s2pro.jpg -Renaming file to ./20030926_111535.jpg +Renaming file to 20030926_111535.jpg File 9/16: exiv2-sigma-d10.jpg -Renaming file to ./20040316_075137.jpg +Renaming file to 20040316_075137.jpg File 10/16: exiv2-olympus-c8080wz.jpg -Renaming file to ./20040208_093744.jpg +Renaming file to 20040208_093744.jpg File 11/16: exiv2-panasonic-dmc-fz5.jpg -Renaming file to ./20050218_212016.jpg +Renaming file to 20050218_212016.jpg File 12/16: exiv2-sony-dsc-w7.jpg -Renaming file to ./20050527_051833.jpg +Renaming file to 20050527_051833.jpg File 13/16: exiv2-canon-eos-20d.jpg Warning: Directory Canon has an unexpected next pointer; ignored. -Renaming file to ./20060802_095200.jpg +Renaming file to 20060802_095200.jpg File 14/16: exiv2-canon-eos-d30.jpg -Renaming file to ./20001004_015404.jpg +Renaming file to 20001004_015404.jpg File 15/16: exiv2-canon-powershot-a520.jpg -Renaming file to ./20060127_225027.jpg +Renaming file to 20060127_225027.jpg File 16/16: exiv2-photoshop.psd -Renaming file to ./20110627_094001.psd +Renaming file to 20110627_094001.psd Print -------------------------------------------------------------------- File 1/16: exiv2-empty.jpg diff --git a/unitTests/test_utils.cpp b/unitTests/test_utils.cpp index 137b04fe..c04f655b 100644 --- a/unitTests/test_utils.cpp +++ b/unitTests/test_utils.cpp @@ -26,10 +26,6 @@ TEST(basename, returnsStemWithoutExtensionWithValidPathOnWindows) const bool delSuffix = true; ASSERT_EQ("file", Util::basename(pathWindows, delSuffix)); } -TEST(suffix, returnsExtensionWithValidWindowsPath) -{ - ASSERT_EQ(".txt", Util::suffix(pathWindows)); -} #else @@ -63,17 +59,4 @@ TEST(basename, returnsStemWithoutExtensionWithValidPathOnLinux) ASSERT_EQ("file", Util::basename(pathLinux, delSuffix)); } - -TEST(suffix, returnsExtensionWithValidLinuxPath) -{ - ASSERT_EQ(".txt", Util::suffix(pathLinux)); -} - #endif - - -TEST(suffix, returnsEmptyStringWithFilesWithoutExtension) -{ - ASSERT_EQ("", Util::suffix("/home/luis/file")); - ASSERT_EQ("", Util::suffix("c:\\luis\\file")); -} From 405f4b5f1ba9eda23e1acfceabf8d73d7c210868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Mon, 14 Feb 2022 22:03:38 +0100 Subject: [PATCH 12/14] Remove Util::dirname and finally the util files --- app/CMakeLists.txt | 2 +- app/actions.cpp | 24 ++--- app/app_utils.cpp | 2 - app/exiv2.cpp | 1 - app/exiv2app.hpp | 1 - app/getopt.cpp | 8 +- samples/CMakeLists.txt | 15 ++- samples/path-test.cpp | 8 +- src/CMakeLists.txt | 1 - src/epsimage.cpp | 2 - src/makernote_int.cpp | 1 - src/sonymn_int.cpp | 1 - src/utils.cpp | 48 --------- src/utils.hpp | 62 ----------- test/data/test_reference_files/exiv2-test.out | 100 +++++++++--------- unitTests/CMakeLists.txt | 1 - unitTests/test_utils.cpp | 62 ----------- 17 files changed, 79 insertions(+), 260 deletions(-) delete mode 100644 src/utils.cpp delete mode 100644 src/utils.hpp delete mode 100644 unitTests/test_utils.cpp diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 2df7ff82..a06bc53d 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -7,7 +7,7 @@ add_executable( exiv2 $ ) -target_include_directories(exiv2 PRIVATE ${CMAKE_SOURCE_DIR}/src) # To find utils.hpp +target_include_directories(exiv2 PRIVATE ${CMAKE_SOURCE_DIR}/src) # To find i18n.hpp set_target_properties( exiv2 PROPERTIES COMPILE_FLAGS ${EXTRA_COMPILE_FLAGS} diff --git a/app/actions.cpp b/app/actions.cpp index 11153ed9..f8cefa07 100644 --- a/app/actions.cpp +++ b/app/actions.cpp @@ -31,7 +31,6 @@ #include "image.hpp" #include "jpgimage.hpp" #include "xmpsidecar.hpp" -#include "utils.hpp" #include "types.hpp" #include "exif.hpp" #include "easyaccess.hpp" @@ -1974,10 +1973,11 @@ namespace { { auto p = fs::path(newPath); std::string path = newPath; + auto oldFsPath = fs::path(path); std::string format = Params::instance().format_; - replace(format, ":basename:", Util::basename(path, true)); - replace(format, ":dirname:", Util::basename(Util::dirname(path))); - replace(format, ":parentname:", Util::basename(Util::dirname(Util::dirname(path)))); + replace(format, ":basename:", p.stem().string()); + replace(format, ":dirname:", p.parent_path().filename().string()); + replace(format, ":parentname:", p.parent_path().parent_path().filename().string()); const size_t max = 1024; char basename[max]; @@ -1989,9 +1989,9 @@ namespace { } newPath = p.parent_path() / (basename + p.extension().string()); + p = fs::path(newPath); - if ( Util::dirname(newPath) == Util::dirname(path) - && Util::basename(newPath) == Util::basename(path)) { + if (p.parent_path() == oldFsPath.parent_path() && p.filename() == oldFsPath.filename()) { if (Params::instance().verbose_) { std::cout << _("This file already has the correct name") << std::endl; } @@ -2066,13 +2066,13 @@ namespace { std::string newFilePath(const std::string& path, const std::string& ext) { - std::string directory = Params::instance().directory_; + auto p = fs::path(path); + auto directory = fs::path(Params::instance().directory_); if (directory.empty()) - directory = Util::dirname(path); - directory = Exiv2::fileProtocol(path) == Exiv2::pFile ? directory + EXV_SEPARATOR_STR - : "" // use current directory for remote files - ; - return directory + Util::basename(path, true) + ext; + directory = p.parent_path(); + if (Exiv2::fileProtocol(path) != Exiv2::pFile) + directory.clear(); // use current directory for remote files + return directory / (p.stem().string() + ext); } int dontOverwrite(const std::string& path) diff --git a/app/app_utils.cpp b/app/app_utils.cpp index dec2955c..09aaf144 100644 --- a/app/app_utils.cpp +++ b/app/app_utils.cpp @@ -1,5 +1,3 @@ -#include "utils.hpp" - #include #include diff --git a/app/exiv2.cpp b/app/exiv2.cpp index 87fb2f99..182ab7ae 100644 --- a/app/exiv2.cpp +++ b/app/exiv2.cpp @@ -29,7 +29,6 @@ #include "futils.hpp" #include "getopt.hpp" #include "i18n.h" // NLS support. -#include "utils.hpp" #include "xmp_exiv2.hpp" #include diff --git a/app/exiv2app.hpp b/app/exiv2app.hpp index 35b22c1c..97230021 100644 --- a/app/exiv2app.hpp +++ b/app/exiv2app.hpp @@ -31,7 +31,6 @@ // included header files #include -#include "utils.hpp" #include "types.hpp" #include "getopt.hpp" diff --git a/app/getopt.cpp b/app/getopt.cpp index b176971e..4fd54d2e 100644 --- a/app/getopt.cpp +++ b/app/getopt.cpp @@ -25,15 +25,17 @@ // included header files #include #include +#include +#include #include #include #include #include -#include -#include "utils.hpp" #include "getopt.hpp" +namespace fs = std::filesystem; + namespace Util { // https://raw.githubusercontent.com/skeeto/getopt/master/getopt.h @@ -113,7 +115,7 @@ namespace Util { int Getopt::getopt(int argc, char* const argv[], const std::string& optstring) { - progname_ = Util::basename(argv[0]); + progname_ = fs::path(argv[0]).filename().string(); Util::optind = 0; // reset the Util::Getopt scanner for (;!errcnt_;) { diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index c8442d52..566f0ab2 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -52,27 +52,24 @@ if (MSVC) link_directories(${CMAKE_INSTALL_PREFIX}/lib) endif() -add_executable( getopt-test getopt-test.cpp ../app/getopt.cpp ../src/utils.cpp) +add_executable( getopt-test getopt-test.cpp ../app/getopt.cpp) list(APPEND APPLICATIONS getopt-test) target_include_directories(getopt-test PRIVATE ${CMAKE_SOURCE_DIR}/app - ${CMAKE_SOURCE_DIR}/src -) # To find utils.hpp & getopt.hpp +) # To find getopt.hpp -add_executable( metacopy metacopy.cpp ../app/getopt.cpp ../src/utils.cpp) +add_executable( metacopy metacopy.cpp ../app/getopt.cpp) list(APPEND APPLICATIONS metacopy) target_include_directories(metacopy PRIVATE ${CMAKE_SOURCE_DIR}/app - ${CMAKE_SOURCE_DIR}/src -) # To find utils.hpp & getopt.hpp +) # To find getopt.hpp -add_executable( path-test path-test.cpp ../app/getopt.cpp ../src/utils.cpp) +add_executable( path-test path-test.cpp ../app/getopt.cpp) list(APPEND APPLICATIONS path-test) set_target_properties( path-test PROPERTIES OUTPUT_NAME path-test ) target_include_directories(path-test PRIVATE ${CMAKE_SOURCE_DIR}/app - ${CMAKE_SOURCE_DIR}/src -) # To find utils.hpp & getopt.hpp +) # To find getopt.hpp add_executable( exiv2json exiv2json.cpp Jzon.cpp Jzon.h) list(APPEND APPLICATIONS exiv2json) diff --git a/samples/path-test.cpp b/samples/path-test.cpp index 7dd5abd5..4f7a8d4a 100644 --- a/samples/path-test.cpp +++ b/samples/path-test.cpp @@ -20,12 +20,13 @@ */ #include +#include #include #include #include #include -#include "utils.hpp" +namespace fs = std::filesystem; int main(int argc, char* const argv[]) { @@ -49,8 +50,9 @@ int main(int argc, char* const argv[]) std::string path, dir, base; std::istringstream is(line); is >> path >> dir >> base; - std::string d = Util::dirname(path); - std::string b = Util::basename(path); + auto p = fs::path(path); + std::string d = p.parent_path().string(); + std::string b = p.filename().string(); if (d != dir || b != base) { std::cout << path << "\t'" << d << "'\t '" << b diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b6f75c84..a4990b4e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -36,7 +36,6 @@ add_library( exiv2lib_int OBJECT tifffwd_int.hpp timegm.h unused.h - utils.cpp utils.hpp ) set(PUBLIC_HEADERS diff --git a/src/epsimage.cpp b/src/epsimage.cpp index 9fcaeea6..e0434fec 100644 --- a/src/epsimage.cpp +++ b/src/epsimage.cpp @@ -33,7 +33,6 @@ #include "error.hpp" #include "futils.hpp" #include "version.hpp" -#include "utils.hpp" // + standard includes #include @@ -49,7 +48,6 @@ namespace { using namespace Exiv2; - using namespace Util; using Exiv2::byte; // signature of DOS EPS diff --git a/src/makernote_int.cpp b/src/makernote_int.cpp index cf8a0444..5863eb01 100644 --- a/src/makernote_int.cpp +++ b/src/makernote_int.cpp @@ -32,7 +32,6 @@ #include "tiffvisitor_int.hpp" #include "tiffimage.hpp" #include "tiffimage_int.hpp" -#include "utils.hpp" // + standard includes #include diff --git a/src/sonymn_int.cpp b/src/sonymn_int.cpp index b168170d..e59b5e99 100644 --- a/src/sonymn_int.cpp +++ b/src/sonymn_int.cpp @@ -27,7 +27,6 @@ #include "value.hpp" #include "exif.hpp" #include "i18n.h" // NLS support. -#include "utils.hpp" // + standard includes #include diff --git a/src/utils.cpp b/src/utils.cpp deleted file mode 100644 index dbe3325f..00000000 --- a/src/utils.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// ***************************************************************** -*- C++ -*- -/* - * Copyright (C) 2004-2021 Exiv2 authors - * This program is part of the Exiv2 distribution. - * - * This program 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 2 - * of the License, or (at your option) any later version. - * - * This program 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. - */ -// ***************************************************************************** - -#include "utils.hpp" - -#include - -namespace fs = std::filesystem; - -namespace Util { - -// ***************************************************************************** -// free functions - - std::string dirname(const std::string& path) - { - auto p = fs::path(path).parent_path(); - if (p.empty()) - return "."; - return p.string(); - } - - std::string basename(const std::string& path, bool delsuffix) - { - auto p = fs::path(path); - if (delsuffix) - return p.stem().string(); - return p.filename().string(); - } -} // namespace Util diff --git a/src/utils.hpp b/src/utils.hpp deleted file mode 100644 index 8c081601..00000000 --- a/src/utils.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// ***************************************************************** -*- C++ -*- -/* - * Copyright (C) 2004-2021 Exiv2 authors - * This program is part of the Exiv2 distribution. - * - * This program 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 2 - * of the License, or (at your option) any later version. - * - * This program 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. - */ -#ifndef UTILS_HPP_ -#define UTILS_HPP_ - -// ********************************************************************* -// included header files - -// + standard includes -#include - -// ********************************************************************* -// namespace extensions -/*! - @brief Contains utility classes and functions. Most of these are - wrappers for common C functions that do not require pointers - and memory considerations. -*/ -namespace Util { - -// ********************************************************************* -// free functions - - /*! - @brief Get the directory component from the \em path string. - See %dirname(3). - - This function can handle Windows paths to some extent: c:\\bar should - be fine, \\\\bigsrv\\foo also, but \\\\bigsrv alone doesn't work. - */ - std::string dirname(const std::string& path); - - /*! - @brief Get the filename component from the \em path string. - See %basename(3). If the \em delsuffix parameter is true, - the suffix will be removed. - - This function can handle Windows paths to some extent: c:\\bar should - be fine, \\\\bigsrv\\foo also, but \\\\bigsrv alone doesn't work. - */ - std::string basename(const std::string& path, bool delsuffix =false); - -} // namespace Util - -#endif // #ifndef UTILS_HPP_ diff --git a/test/data/test_reference_files/exiv2-test.out b/test/data/test_reference_files/exiv2-test.out index ec42d606..6023f884 100644 --- a/test/data/test_reference_files/exiv2-test.out +++ b/test/data/test_reference_files/exiv2-test.out @@ -2223,72 +2223,72 @@ Warning: Directory Canon has an unexpected next pointer; ignored. Extract Exif data -------------------------------------------------------- File 1/16: exiv2-empty.jpg File 2/16: 20031214_000043.jpg -Writing Exif data from 20031214_000043.jpg to ./20031214_000043.exv +Writing Exif data from 20031214_000043.jpg to 20031214_000043.exv File 3/16: 20000506_020544.jpg -Writing Exif data from 20000506_020544.jpg to ./20000506_020544.exv +Writing Exif data from 20000506_020544.jpg to 20000506_020544.exv File 4/16: 20040329_224245.jpg -Writing Exif data from 20040329_224245.jpg to ./20040329_224245.exv +Writing Exif data from 20040329_224245.jpg to 20040329_224245.exv File 5/16: 20010405_235039.jpg -Writing Exif data from 20010405_235039.jpg to ./20010405_235039.exv +Writing Exif data from 20010405_235039.jpg to 20010405_235039.exv File 6/16: 20030925_201850.jpg -Writing Exif data from 20030925_201850.jpg to ./20030925_201850.exv +Writing Exif data from 20030925_201850.jpg to 20030925_201850.exv File 7/16: 20001026_044550.jpg -Writing Exif data from 20001026_044550.jpg to ./20001026_044550.exv -Writing JPEG comment from 20001026_044550.jpg to ./20001026_044550.exv +Writing Exif data from 20001026_044550.jpg to 20001026_044550.exv +Writing JPEG comment from 20001026_044550.jpg to 20001026_044550.exv File 8/16: 20030926_111535.jpg -Writing Exif data from 20030926_111535.jpg to ./20030926_111535.exv +Writing Exif data from 20030926_111535.jpg to 20030926_111535.exv File 9/16: 20040316_075137.jpg -Writing Exif data from 20040316_075137.jpg to ./20040316_075137.exv +Writing Exif data from 20040316_075137.jpg to 20040316_075137.exv File 10/16: 20040208_093744.jpg -Writing Exif data from 20040208_093744.jpg to ./20040208_093744.exv +Writing Exif data from 20040208_093744.jpg to 20040208_093744.exv File 11/16: 20050218_212016.jpg -Writing Exif data from 20050218_212016.jpg to ./20050218_212016.exv +Writing Exif data from 20050218_212016.jpg to 20050218_212016.exv File 12/16: 20050527_051833.jpg -Writing Exif data from 20050527_051833.jpg to ./20050527_051833.exv +Writing Exif data from 20050527_051833.jpg to 20050527_051833.exv File 13/16: 20060802_095200.jpg Warning: Directory Canon has an unexpected next pointer; ignored. -Writing Exif data from 20060802_095200.jpg to ./20060802_095200.exv +Writing Exif data from 20060802_095200.jpg to 20060802_095200.exv File 14/16: 20001004_015404.jpg -Writing Exif data from 20001004_015404.jpg to ./20001004_015404.exv +Writing Exif data from 20001004_015404.jpg to 20001004_015404.exv File 15/16: 20060127_225027.jpg -Writing Exif data from 20060127_225027.jpg to ./20060127_225027.exv +Writing Exif data from 20060127_225027.jpg to 20060127_225027.exv File 16/16: 20110626_213900.psd -Writing Exif data from 20110626_213900.psd to ./20110626_213900.exv -Writing IPTC data from 20110626_213900.psd to ./20110626_213900.exv -Writing XMP data from 20110626_213900.psd to ./20110626_213900.exv +Writing Exif data from 20110626_213900.psd to 20110626_213900.exv +Writing IPTC data from 20110626_213900.psd to 20110626_213900.exv +Writing XMP data from 20110626_213900.psd to 20110626_213900.exv Extract Thumbnail -------------------------------------------------------- File 1/16: exiv2-empty.jpg exiv2-empty.jpg: No Exif data found in the file File 2/16: 20031214_000043.jpg -Writing thumbnail (image/jpeg, 5448 Bytes) to file ./20031214_000043-thumb.jpg +Writing thumbnail (image/jpeg, 5448 Bytes) to file 20031214_000043-thumb.jpg File 3/16: 20000506_020544.jpg -Writing thumbnail (image/jpeg, 7829 Bytes) to file ./20000506_020544-thumb.jpg +Writing thumbnail (image/jpeg, 7829 Bytes) to file 20000506_020544-thumb.jpg File 4/16: 20040329_224245.jpg -Writing thumbnail (image/jpeg, 8930 Bytes) to file ./20040329_224245-thumb.jpg +Writing thumbnail (image/jpeg, 8930 Bytes) to file 20040329_224245-thumb.jpg File 5/16: 20010405_235039.jpg -Writing thumbnail (image/jpeg, 4662 Bytes) to file ./20010405_235039-thumb.jpg +Writing thumbnail (image/jpeg, 4662 Bytes) to file 20010405_235039-thumb.jpg File 6/16: 20030925_201850.jpg -Writing thumbnail (image/jpeg, 9728 Bytes) to file ./20030925_201850-thumb.jpg +Writing thumbnail (image/jpeg, 9728 Bytes) to file 20030925_201850-thumb.jpg File 7/16: 20001026_044550.jpg -Writing thumbnail (image/tiff, 20916 Bytes) to file ./20001026_044550-thumb.tif +Writing thumbnail (image/tiff, 20916 Bytes) to file 20001026_044550-thumb.tif File 8/16: 20030926_111535.jpg -Writing thumbnail (image/jpeg, 9573 Bytes) to file ./20030926_111535-thumb.jpg +Writing thumbnail (image/jpeg, 9573 Bytes) to file 20030926_111535-thumb.jpg File 9/16: 20040316_075137.jpg -Writing thumbnail (image/jpeg, 11998 Bytes) to file ./20040316_075137-thumb.jpg +Writing thumbnail (image/jpeg, 11998 Bytes) to file 20040316_075137-thumb.jpg File 10/16: 20040208_093744.jpg -Writing thumbnail (image/jpeg, 7306 Bytes) to file ./20040208_093744-thumb.jpg +Writing thumbnail (image/jpeg, 7306 Bytes) to file 20040208_093744-thumb.jpg File 11/16: 20050218_212016.jpg -Writing thumbnail (image/jpeg, 10308 Bytes) to file ./20050218_212016-thumb.jpg +Writing thumbnail (image/jpeg, 10308 Bytes) to file 20050218_212016-thumb.jpg File 12/16: 20050527_051833.jpg -Writing thumbnail (image/jpeg, 15605 Bytes) to file ./20050527_051833-thumb.jpg +Writing thumbnail (image/jpeg, 15605 Bytes) to file 20050527_051833-thumb.jpg File 13/16: 20060802_095200.jpg Warning: Directory Canon has an unexpected next pointer; ignored. -Writing thumbnail (image/jpeg, 6260 Bytes) to file ./20060802_095200-thumb.jpg +Writing thumbnail (image/jpeg, 6260 Bytes) to file 20060802_095200-thumb.jpg File 14/16: 20001004_015404.jpg -Writing thumbnail (image/jpeg, 13824 Bytes) to file ./20001004_015404-thumb.jpg +Writing thumbnail (image/jpeg, 13824 Bytes) to file 20001004_015404-thumb.jpg File 15/16: 20060127_225027.jpg -Writing thumbnail (image/jpeg, 6137 Bytes) to file ./20060127_225027-thumb.jpg +Writing thumbnail (image/jpeg, 6137 Bytes) to file 20060127_225027-thumb.jpg File 16/16: 20110626_213900.psd 20110626_213900.psd: Exif data doesn't contain a thumbnail exiv2-empty.exv: No Exif data found in the file @@ -5623,38 +5623,38 @@ File 16/16: 20110626_213900.psd Insert Exif data --------------------------------------------------------- File 1/16: exiv2-empty.jpg File 2/16: 20031214_000043.jpg -Writing Exif data from ./20031214_000043.exv to 20031214_000043.jpg +Writing Exif data from 20031214_000043.exv to 20031214_000043.jpg File 3/16: 20000506_020544.jpg -Writing Exif data from ./20000506_020544.exv to 20000506_020544.jpg +Writing Exif data from 20000506_020544.exv to 20000506_020544.jpg File 4/16: 20040329_224245.jpg -Writing Exif data from ./20040329_224245.exv to 20040329_224245.jpg +Writing Exif data from 20040329_224245.exv to 20040329_224245.jpg File 5/16: 20010405_235039.jpg -Writing Exif data from ./20010405_235039.exv to 20010405_235039.jpg +Writing Exif data from 20010405_235039.exv to 20010405_235039.jpg File 6/16: 20030925_201850.jpg -Writing Exif data from ./20030925_201850.exv to 20030925_201850.jpg +Writing Exif data from 20030925_201850.exv to 20030925_201850.jpg File 7/16: 20001026_044550.jpg -Writing Exif data from ./20001026_044550.exv to 20001026_044550.jpg -Writing JPEG comment from ./20001026_044550.exv to 20001026_044550.jpg +Writing Exif data from 20001026_044550.exv to 20001026_044550.jpg +Writing JPEG comment from 20001026_044550.exv to 20001026_044550.jpg File 8/16: 20030926_111535.jpg -Writing Exif data from ./20030926_111535.exv to 20030926_111535.jpg +Writing Exif data from 20030926_111535.exv to 20030926_111535.jpg File 9/16: 20040316_075137.jpg -Writing Exif data from ./20040316_075137.exv to 20040316_075137.jpg +Writing Exif data from 20040316_075137.exv to 20040316_075137.jpg File 10/16: 20040208_093744.jpg -Writing Exif data from ./20040208_093744.exv to 20040208_093744.jpg +Writing Exif data from 20040208_093744.exv to 20040208_093744.jpg File 11/16: 20050218_212016.jpg -Writing Exif data from ./20050218_212016.exv to 20050218_212016.jpg +Writing Exif data from 20050218_212016.exv to 20050218_212016.jpg File 12/16: 20050527_051833.jpg -Writing Exif data from ./20050527_051833.exv to 20050527_051833.jpg +Writing Exif data from 20050527_051833.exv to 20050527_051833.jpg File 13/16: 20060802_095200.jpg -Writing Exif data from ./20060802_095200.exv to 20060802_095200.jpg +Writing Exif data from 20060802_095200.exv to 20060802_095200.jpg File 14/16: 20001004_015404.jpg -Writing Exif data from ./20001004_015404.exv to 20001004_015404.jpg +Writing Exif data from 20001004_015404.exv to 20001004_015404.jpg File 15/16: 20060127_225027.jpg -Writing Exif data from ./20060127_225027.exv to 20060127_225027.jpg +Writing Exif data from 20060127_225027.exv to 20060127_225027.jpg File 16/16: 20110626_213900.psd -Writing Exif data from ./20110626_213900.exv to 20110626_213900.psd -Writing IPTC data from ./20110626_213900.exv to 20110626_213900.psd -Writing XMP data from ./20110626_213900.exv to 20110626_213900.psd +Writing Exif data from 20110626_213900.exv to 20110626_213900.psd +Writing IPTC data from 20110626_213900.exv to 20110626_213900.psd +Writing XMP data from 20110626_213900.exv to 20110626_213900.psd exiv2-empty.exv: No Exif data found in the file Compare original and inserted image data --------------------------------- diff --git a/unitTests/CMakeLists.txt b/unitTests/CMakeLists.txt index 704d84a0..ca0372fa 100644 --- a/unitTests/CMakeLists.txt +++ b/unitTests/CMakeLists.txt @@ -21,7 +21,6 @@ add_executable(unit_tests test_tiffheader.cpp test_types.cpp test_TimeValue.cpp - test_utils.cpp test_XmpKey.cpp $ ) diff --git a/unitTests/test_utils.cpp b/unitTests/test_utils.cpp deleted file mode 100644 index c04f655b..00000000 --- a/unitTests/test_utils.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include - -// Auxiliary headers - -#include - -namespace { - const std::string pathLinux("/home/luis/file.txt"); - const std::string pathWindows("c:/luis/file.txt"); -} - -#ifdef _WIN32 - -TEST(dirname, returnsDirNameWithValidPathOnWindows) -{ - ASSERT_EQ("c:\\luis", Util::dirname(pathWindows)); -} -TEST(basename, returnsStemWithExtensionWithValidPathOnWindows) -{ - const bool delSuffix = false; - ASSERT_EQ("file.txt", Util::basename(pathWindows, delSuffix)); -} - -TEST(basename, returnsStemWithoutExtensionWithValidPathOnWindows) -{ - const bool delSuffix = true; - ASSERT_EQ("file", Util::basename(pathWindows, delSuffix)); -} - -#else - -TEST(dirname, returnsDirNameWithValidPathOnLinux) -{ - ASSERT_EQ("/home/luis", Util::dirname(pathLinux)); - ASSERT_EQ("/tmp", Util::dirname("/tmp/file.jpg")); -} - - -TEST(dirname, returnsDotWithRelativePath) -{ - ASSERT_EQ(".", Util::dirname("file.txt")); -} - -TEST(dirname, returnsDotEmptyString) -{ - ASSERT_EQ(".", Util::dirname("")); -} - -/// \bug the logic for delsuffix is actually reverted -TEST(basename, returnsStemWithExtensionWithValidPathOnLinux) -{ - const bool delSuffix = false; - ASSERT_EQ("file.txt", Util::basename(pathLinux, delSuffix)); -} - -TEST(basename, returnsStemWithoutExtensionWithValidPathOnLinux) -{ - const bool delSuffix = true; - ASSERT_EQ("file", Util::basename(pathLinux, delSuffix)); -} - -#endif From f5c89a4e62d1404624bdfde5f35833f1efcd6dfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= Date: Mon, 14 Feb 2022 22:14:55 +0100 Subject: [PATCH 13/14] Fix build on Windows --- app/CMakeLists.txt | 1 - app/actions.cpp | 77 ++++++++++++++++++++------------------------ {src => app}/wmain.c | 0 3 files changed, 35 insertions(+), 43 deletions(-) rename {src => app}/wmain.c (100%) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index a06bc53d..e3bbf0f3 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -4,7 +4,6 @@ add_executable( exiv2 actions.cpp actions.hpp getopt.cpp getopt.hpp app_utils.cpp app_utils.hpp - $ ) target_include_directories(exiv2 PRIVATE ${CMAKE_SOURCE_DIR}/src) # To find i18n.hpp diff --git a/app/actions.cpp b/app/actions.cpp index f8cefa07..6175a982 100644 --- a/app/actions.cpp +++ b/app/actions.cpp @@ -1975,20 +1975,19 @@ namespace { std::string path = newPath; auto oldFsPath = fs::path(path); std::string format = Params::instance().format_; - replace(format, ":basename:", p.stem().string()); - replace(format, ":dirname:", p.parent_path().filename().string()); + replace(format, ":basename:", p.stem().string()); + replace(format, ":dirname:", p.parent_path().filename().string()); replace(format, ":parentname:", p.parent_path().parent_path().filename().string()); const size_t max = 1024; char basename[max]; std::memset(basename, 0x0, max); if (strftime(basename, max, format.c_str(), tm) == 0) { - std::cerr << _("Filename format yields empty filename for the file") << " " - << path << "\n"; + std::cerr << _("Filename format yields empty filename for the file") << " " << path << "\n"; return 1; } - newPath = p.parent_path() / (basename + p.extension().string()); + newPath = (p.parent_path() / (basename + p.extension().string())).string(); p = fs::path(newPath); if (p.parent_path() == oldFsPath.parent_path() && p.filename() == oldFsPath.filename()) { @@ -2001,44 +2000,40 @@ namespace { bool go = true; int seq = 1; std::string s; - Params::FileExistsPolicy fileExistsPolicy - = Params::instance().fileExistsPolicy_; + Params::FileExistsPolicy fileExistsPolicy = Params::instance().fileExistsPolicy_; while (go) { if (Exiv2::fileExists(newPath)) { switch (fileExistsPolicy) { - case Params::overwritePolicy: - go = false; - break; - case Params::renamePolicy: - newPath = p.parent_path() / (std::string(basename) + "_" - + Exiv2::toString(seq++) - + p.extension().string()); - break; - case Params::askPolicy: - std::cout << Params::instance().progname() - << ": " << _("File") << " `" << newPath - << "' " << _("exists. [O]verwrite, [r]ename or [s]kip?") - << " "; - std::cin >> s; - switch (s.at(0)) { - case 'o': - case 'O': + case Params::overwritePolicy: go = false; break; - case 'r': - case 'R': - fileExistsPolicy = Params::renamePolicy; - newPath = p.parent_path() / (std::string(basename) + "_" - + Exiv2::toString(seq++) - + p.extension().string()); + case Params::renamePolicy: + newPath = (p.parent_path() / + (std::string(basename) + "_" + Exiv2::toString(seq++) + p.extension().string())) + .string(); break; - default: // skip - return -1; - break; - } + case Params::askPolicy: + std::cout << Params::instance().progname() << ": " << _("File") << " `" << newPath << "' " + << _("exists. [O]verwrite, [r]ename or [s]kip?") << " "; + std::cin >> s; + switch (s.at(0)) { + case 'o': + case 'O': + go = false; + break; + case 'r': + case 'R': + fileExistsPolicy = Params::renamePolicy; + newPath = (p.parent_path() / (std::string(basename) + "_" + Exiv2::toString(seq++) + + p.extension().string())) + .string(); + break; + default: // skip + return -1; + break; + } } - } - else { + } else { go = false; } } @@ -2054,15 +2049,13 @@ namespace { // Workaround for MinGW rename which does not overwrite existing files remove(newPath.c_str()); if (std::rename(path.c_str(), newPath.c_str()) == -1) { - std::cerr << Params::instance().progname() - << ": " << _("Failed to rename") << " " - << path << " " << _("to") << " " << newPath << ": " - << Exiv2::strError() << "\n"; + std::cerr << Params::instance().progname() << ": " << _("Failed to rename") << " " << path << " " << _("to") + << " " << newPath << ": " << Exiv2::strError() << "\n"; return 1; } return 0; - } // renameFile + } std::string newFilePath(const std::string& path, const std::string& ext) { @@ -2072,7 +2065,7 @@ namespace { directory = p.parent_path(); if (Exiv2::fileProtocol(path) != Exiv2::pFile) directory.clear(); // use current directory for remote files - return directory / (p.stem().string() + ext); + return (directory / (p.stem().string() + ext)).string(); } int dontOverwrite(const std::string& path) diff --git a/src/wmain.c b/app/wmain.c similarity index 100% rename from src/wmain.c rename to app/wmain.c From 8e0e00c45924b60e4ad956cfadd9f0c02c4c3dc3 Mon Sep 17 00:00:00 2001 From: Luis Diaz Date: Wed, 16 Feb 2022 09:14:33 +0100 Subject: [PATCH 14/14] make startsWith constexpr and use string_view --- src/epsimage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/epsimage.cpp b/src/epsimage.cpp index e0434fec..eba0c7fe 100644 --- a/src/epsimage.cpp +++ b/src/epsimage.cpp @@ -103,7 +103,7 @@ namespace { // closing part of all valid XMP trailers const std::string xmpTrailerEnd = "?>"; - bool startsWith(const std::string& s, const std::string& start) + constexpr bool startsWith(const std::string_view& s, const std::string_view& start) { return s.find(start) == 0; }