Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

switch from custom stringFormat to fmtlib #2769

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Install dependencies
run: |
sudo eatmydata apt-get -y install libexpat1-dev zlib1g-dev libbrotli-dev libinih-dev
sudo eatmydata apt-get -y install libfmt-dev libexpat1-dev zlib1g-dev libbrotli-dev libinih-dev

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/on_PR_mac_matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:

- name: Install dependencies
run: |
brew install ninja inih googletest
brew install ninja fmt inih googletest

- name: Build
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/on_PR_mac_special_builds.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:

- name: Install dependencies
run: |
brew install ninja inih googletest
brew install ninja fmt inih googletest

- name: Build
run: |
Expand Down
26 changes: 24 additions & 2 deletions .github/workflows/on_PR_meson.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ jobs:
cc:p
cmake:p
curl:p
fmt:p
gtest:p
libinih:p
meson:p
Expand All @@ -126,6 +127,27 @@ jobs:
meson setup "${{github.workspace}}/build" -Dauto_features=${{matrix.deps}} -Dwarning_level=3 -Dcpp_std=c++20
meson compile -C "${{github.workspace}}/build" --verbose
meson test -C "${{github.workspace}}/build" --verbose
Cygwin:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this can be removed if we're happy w/ the other Cygwin action now that could be reverted. Although MSYS is somewhat equivalent, no one really uses it to build/ship exiv2 AFAIK...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use MSYS here as it’s less verbose than Cygwin. Plus meson has its own subprojects.

runs-on: windows-latest
defaults:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v4
- uses: msys2/setup-msys2@v2
with:
msystem: 'MSYS'
install: >-
cmake
gcc
meson
ninja
pkgconf
- name: Compile and Test
run: |
meson setup build -Dwarning_level=3 -Dcpp_std=gnu++20
meson compile -C build --verbose
meson test -C build --verbose
MacOS:
runs-on: macos-latest
name: macOS-deps=${{matrix.deps}}
Expand All @@ -141,7 +163,7 @@ jobs:

- name: Compile and Test
run: |
meson setup "${{github.workspace}}/build" -Dauto_features=${{matrix.deps}} -Dwarning_level=3 -Dnls=disabled -Db_sanitize=address,undefined
meson setup "${{github.workspace}}/build" -Dauto_features=${{matrix.deps}} -Dwarning_level=3 -Dcpp_std=c++20 -Dnls=disabled -Db_sanitize=address,undefined
meson compile -C "${{github.workspace}}/build" --verbose
meson test -C "${{github.workspace}}/build" --verbose
FreeBSD:
Expand All @@ -151,7 +173,7 @@ jobs:
- uses: vmactions/freebsd-vm@v1
with:
prepare: |
pkg install -y cmake curl ninja meson gettext pkgconf googletest expat inih brotli
pkg install -y cmake curl ninja meson gettext pkgconf googletest expat inih brotli libfmt
run: |
meson setup "${{github.workspace}}/build" -Dwarning_level=3 -Dcpp_std=c++20
meson compile -C "${{github.workspace}}/build" --verbose
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/on_PR_windows_matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ jobs:
libiconv:p
libinih:p
zlib:p
fmt:p

- name: Build
run: |
Expand Down Expand Up @@ -176,6 +177,7 @@ jobs:
cmake --preset base_windows \
-DCMAKE_BUILD_TYPE=${{matrix.build_type}} \
-DBUILD_SHARED_LIBS=${{matrix.shared_libraries}} \
-DCMAKE_CXX_STANDARD=20 \
-DCONAN_AUTO_INSTALL=OFF \
-DEXIV2_BUILD_SAMPLES=OFF \
-DEXIV2_BUILD_UNIT_TESTS=OFF \
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/on_push_BasicWinLinMac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ jobs:

- name: Install dependencies
run: |
brew install ninja inih googletest
brew install ninja fmt inih googletest

- name: Build
run: |
Expand Down
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ endif()

include_directories(${CMAKE_BINARY_DIR}) # Make the exv_conf.h file visible for the full project

check_cxx_symbol_exists(__cpp_lib_format "format" HAVE_STD_FORMAT)
if(NOT HAVE_STD_FORMAT)
find_package(fmt REQUIRED)
endif()

if(EXIV2_ENABLE_XMP)
add_subdirectory(xmpsdk)
endif()
Expand Down
16 changes: 8 additions & 8 deletions ci/install_dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,46 +41,46 @@ distro_id=$(grep '^ID=' /etc/os-release|awk -F = '{print $2}'|sed 's/\"//g')

case "$distro_id" in
'fedora')
dnf -y --refresh install gcc-c++ clang cmake ninja-build expat-devel zlib-devel brotli-devel libssh-devel libcurl-devel gmock-devel glibc-langpack-en inih-devel
dnf -y --refresh install gcc-c++ clang cmake ninja-build expat-devel zlib-devel brotli-devel libssh-devel libcurl-devel gmock-devel glibc-langpack-en inih-devel fmt-devel
;;

'debian')
apt-get update
apt-get install -y cmake ninja-build g++ clang libexpat1-dev zlib1g-dev libbrotli-dev libssh-dev libcurl4-openssl-dev libgmock-dev libxml2-utils libinih-dev
apt-get install -y cmake ninja-build g++ clang libexpat1-dev zlib1g-dev libbrotli-dev libssh-dev libcurl4-openssl-dev libgmock-dev libxml2-utils libinih-dev libfmt-dev
# debian_build_gtest
;;

'arch')
pacman --noconfirm -Syu
pacman --noconfirm --needed -S gcc clang cmake ninja expat zlib brotli libssh curl gtest libinih
pacman --noconfirm --needed -S gcc clang cmake ninja expat zlib brotli libssh curl gtest libinih fmt
;;

'ubuntu')
apt-get update
apt-get install -y cmake ninja-build g++ clang libexpat1-dev zlib1g-dev libbrotli-dev libssh-dev libcurl4-openssl-dev libgmock-dev libxml2-utils libinih-dev
apt-get install -y cmake ninja-build g++ clang libexpat1-dev zlib1g-dev libbrotli-dev libssh-dev libcurl4-openssl-dev libgmock-dev libxml2-utils libinih-dev libfmt-dev
# debian_build_gtest
;;

'alpine')
apk update
apk add gcc g++ clang cmake samurai expat-dev zlib-dev brotli-dev libssh-dev curl-dev gtest gtest-dev gmock libintl gettext-dev libxml2-utils inih-dev inih-inireader-dev
apk add gcc g++ clang cmake samurai expat-dev zlib-dev brotli-dev libssh-dev curl-dev gtest gtest-dev gmock libintl gettext-dev libxml2-utils inih-dev inih-inireader-dev fmt-dev
;;

'rhel')
dnf clean all
dnf -y install gcc-c++ clang cmake ninja-build expat-devel zlib-devel brotli-devel libssh-devel libcurl-devel inih-devel
dnf -y install gcc-c++ clang cmake ninja-build expat-devel zlib-devel brotli-devel libssh-devel libcurl-devel inih-devel fmt-devel
;;

'centos')
dnf clean all
dnf -y install gcc-c++ clang cmake expat-devel zlib-devel brotli-devel libssh-devel libcurl-devel git
dnf -y install gcc-c++ clang cmake expat-devel zlib-devel brotli-devel libssh-devel libcurl-devel git fmt-devel
dnf -y --enablerepo=crb install ninja-build meson
centos_build_inih
;;

'opensuse-tumbleweed')
zypper --non-interactive refresh
zypper --non-interactive install gcc-c++ clang cmake ninja libexpat-devel zlib-devel libbrotli-devel libssh-devel libcurl-devel gmock libxml2-tools libinih-devel
zypper --non-interactive install gcc-c++ clang cmake ninja libexpat-devel zlib-devel libbrotli-devel libssh-devel libcurl-devel gmock libxml2-tools libinih-devel libfmt-devel
;;
*)
echo "Sorry, no predefined dependencies for your distribution $distro_id exist yet"
Expand Down
2 changes: 2 additions & 0 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ def requirements(self):

self.requires('inih/55')

self.requires('fmt/10.1.1')

if self.options.webready:
self.requires('libcurl/7.85.0')

Expand Down
2 changes: 1 addition & 1 deletion include/exiv2/asfvideo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ class EXIV2API AsfVideo : public Image {
// Constructor to create a GUID object from a byte array
explicit GUIDTag(const uint8_t* bytes);

std::string to_string();
std::string to_string() const;

bool operator<(const GUIDTag& other) const;
};
Expand Down
8 changes: 6 additions & 2 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ project(
default_options: ['warning_level=0', 'cpp_std=c++17'],
)

cargs = []
cargs = ['-D_GNU_SOURCE']
cpp = meson.get_compiler('cpp')
if host_machine.system() == 'windows' and get_option('default_library') != 'static'
cargs += '-DEXIV2API=__declspec(dllexport)'
Expand Down Expand Up @@ -44,7 +44,7 @@ cdata.set('EXV_PACKAGE_VERSION', '@0@.@1@'.format(meson.project_version(), cdata
cdata.set('EXV_PACKAGE_STRING', '@0@ @1@'.format(meson.project_name(), cdata.get('PROJECT_VERSION')))

cdata.set('EXV_HAVE_STRERROR_R', cpp.has_function('strerror_r'))
cdata.set('EXV_STRERROR_R_CHAR_P', not cpp.compiles('#include <string.h>\nint strerror_r(int,char*,size_t);int main(){}'))
cdata.set('EXV_STRERROR_R_CHAR_P', not cpp.compiles('#define _GNU_SOURCE\n#include <string.h>\nint strerror_r(int,char*,size_t);int main(){}'))

cdata.set('EXV_ENABLE_BMFF', get_option('bmff'))
cdata.set('EXV_HAVE_LENSDATA', get_option('lensdata'))
Expand All @@ -54,6 +54,10 @@ deps = []
deps += cpp.find_library('ws2_32', required: host_machine.system() == 'windows')
deps += cpp.find_library('procstat', required: host_machine.system() == 'freebsd')

if not cpp.has_header_symbol('format', '__cpp_lib_format')
deps += dependency('fmt')
endif

if cpp.get_argument_syntax() == 'gcc' and cpp.version().version_compare('<9')
if host_machine.system() == 'linux' and cpp.get_define('_LIBCPP_VERSION', prefix: '#include <new>') == ''
deps += cpp.find_library('stdc++fs')
Expand Down
6 changes: 6 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,12 @@ else()
target_link_libraries(exiv2lib PRIVATE psapi ws2_32 shell32)
endif()

if(NOT HAVE_STD_FORMAT)
target_link_libraries(exiv2lib PRIVATE fmt::fmt)
target_link_libraries(exiv2lib_int PRIVATE fmt::fmt)
list(APPEND requires_private_list "fmt")
endif()

if(EXIV2_ENABLE_PNG)
target_link_libraries(exiv2lib PRIVATE ZLIB::ZLIB)
target_include_directories(exiv2lib_int PRIVATE ${ZLIB_INCLUDE_DIR})
Expand Down
19 changes: 4 additions & 15 deletions src/asfvideo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "error.hpp"
#include "futils.hpp"
#include "helper_functions.hpp"
#include "image_int.hpp"
#include "utils.hpp"
// *****************************************************************************
// class member definitions
Expand Down Expand Up @@ -58,24 +59,12 @@ AsfVideo::GUIDTag::GUIDTag(const uint8_t* bytes) {
}
}

std::string AsfVideo::GUIDTag::to_string() {
// Convert each field of the GUID structure to a string
std::stringstream ss;
ss << std::hex << std::setw(8) << std::setfill('0') << data1_ << "-";
ss << std::hex << std::setw(4) << std::setfill('0') << data2_ << "-";
ss << std::hex << std::setw(4) << std::setfill('0') << data3_ << "-";

for (size_t i = 0; i < 8; i++) {
if (i == 2) {
ss << "-";
}
ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(data4_[i]);
}

std::string AsfVideo::GUIDTag::to_string() const {
// Concatenate all strings into a single string
// Convert the string to uppercase
// Example of output 399595EC-8667-4E2D-8FDB-98814CE76C1E
return Internal::upper(ss.str());
return stringFormat("{:08X}-{:04X}-{:04X}-{:02X}{:02X}-{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}", data1_, data2_, data3_,
data4_[0], data4_[1], data4_[2], data4_[3], data4_[4], data4_[5], data4_[6], data4_[7]);
}

bool AsfVideo::GUIDTag::operator<(const GUIDTag& other) const {
Expand Down
28 changes: 6 additions & 22 deletions src/basicio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -930,9 +930,7 @@ std::string XPathIo::writeDataToFile(const std::string& orgPath) {

// generating the name for temp file.
std::time_t timestamp = std::time(nullptr);
std::stringstream ss;
ss << timestamp << XPathIo::TEMP_FILE_EXT;
std::string path = ss.str();
auto path = stringFormat("{}{}", timestamp, XPathIo::TEMP_FILE_EXT);

if (prot == pStdin) {
if (isatty(fileno(stdin)))
Expand Down Expand Up @@ -1437,9 +1435,7 @@ void HttpIo::HttpImpl::getDataByRange(size_t lowBlock, size_t highBlock, std::st
request["verb"] = "GET";
std::string errors;
if (lowBlock != std::numeric_limits<size_t>::max() && highBlock != std::numeric_limits<size_t>::max()) {
std::stringstream ss;
ss << "Range: bytes=" << lowBlock * blockSize_ << "-" << (((highBlock + 1) * blockSize_) - 1) << "\r\n";
request["header"] = ss.str();
request["header"] = stringFormat("Range: bytes={}-{}", lowBlock * blockSize_, (highBlock + 1) * (blockSize_ - 1));
}

int serverCode = http(request, responseDic, errors);
Expand Down Expand Up @@ -1480,15 +1476,10 @@ void HttpIo::HttpImpl::writeRemote(const byte* data, size_t size, size_t from, s
// url encode
const std::string urlencodeData = urlencode(encodeData.data());

std::stringstream ss;
ss << "path=" << hostInfo_.Path << "&"
<< "from=" << from << "&"
<< "to=" << to << "&"
<< "data=" << urlencodeData;
std::string postData = ss.str();
auto postData = stringFormat("path={}&from={}&to={}&data={}", hostInfo_.Path, from, to, urlencodeData);

// create the header
ss.str("");
std::stringstream ss;
ss << "Content-Length: " << postData.length() << "\n"
<< "Content-Type: application/x-www-form-urlencoded\n"
<< "\n"
Expand Down Expand Up @@ -1616,9 +1607,7 @@ void CurlIo::CurlImpl::getDataByRange(size_t lowBlock, size_t highBlock, std::st
// curl_easy_setopt(curl_, CURLOPT_VERBOSE, 1); // debugging mode

if (lowBlock != std::numeric_limits<size_t>::max() && highBlock != std::numeric_limits<size_t>::max()) {
std::stringstream ss;
ss << lowBlock * blockSize_ << "-" << (((highBlock + 1) * blockSize_) - 1);
std::string range = ss.str();
auto range = stringFormat("{}-{}", lowBlock * blockSize_, (highBlock + 1) * (blockSize_ - 1));
curl_easy_setopt(curl_, CURLOPT_RANGE, range.c_str());
}

Expand Down Expand Up @@ -1662,12 +1651,7 @@ void CurlIo::CurlImpl::writeRemote(const byte* data, size_t size, size_t from, s
base64encode(data, size, encodeData.data(), encodeLength);
// url encode
const std::string urlencodeData = urlencode(encodeData.data());
std::stringstream ss;
ss << "path=" << hostInfo.Path << "&"
<< "from=" << from << "&"
<< "to=" << to << "&"
<< "data=" << urlencodeData;
std::string postData = ss.str();
auto postData = stringFormat("path={}&from={}&to={}&data={}", hostInfo.Path, from, to, urlencodeData);

curl_easy_setopt(curl_, CURLOPT_POSTFIELDS, postData.c_str());
// Perform the request, res will get the return code.
Expand Down
15 changes: 7 additions & 8 deletions src/bmffimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ bool enableBMFF(bool) {
}

std::string Iloc::toString() const {
return Internal::stringFormat("ID = %u from,length = %u,%u", ID_, start_, length_);
return stringFormat("ID = {} from,length = {},{}", ID_, start_, length_);
}

BmffImage::BmffImage(BasicIo::UniquePtr io, bool /* create */, size_t max_box_depth) :
Expand Down Expand Up @@ -276,7 +276,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
if (bTrace) {
bLF = true;
out << Internal::indent(depth) << "Exiv2::BmffImage::boxHandler: " << toAscii(box_type)
<< Internal::stringFormat(" %8zd->%" PRIu64 " ", address, box_length);
<< stringFormat(" {:8}->{} ", address, box_length);
}

if (box_length == 1) {
Expand Down Expand Up @@ -373,7 +373,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
id = " *** XMP ***";
}
if (bTrace) {
out << Internal::stringFormat("ID = %3d ", ID) << name << " " << id;
out << stringFormat("ID = {:3} {} {}", ID, name, id);
}
} break;

Expand Down Expand Up @@ -451,8 +451,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
uint32_t ldata = data.read_uint32(skip + step - 4, endian_);
if (bTrace) {
out << Internal::indent(depth)
<< Internal::stringFormat("%8zd | %8zd | ID | %4u | %6u,%6u", address + skip, step, ID, offset, ldata)
<< '\n';
<< stringFormat("{:8} | {:8} | ID | {:4} | {:6},{:6}\n", address + skip, step, ID, offset, ldata);
}
// save data for post-processing in meta box
if (offset && ldata && ID != unknownID_) {
Expand All @@ -470,7 +469,7 @@ uint64_t BmffImage::boxHandler(std::ostream& out /* = std::cout*/, Exiv2::PrintS
uint32_t height = data.read_uint32(skip, endian_);
skip += 4;
if (bTrace) {
out << "pixelWidth_, pixelHeight_ = " << Internal::stringFormat("%d, %d", width, height);
out << stringFormat("pixelWidth_, pixelHeight_ = {}, {}", width, height);
}
// HEIC files can have multiple ispe records
// Store largest width/height
Expand Down Expand Up @@ -685,8 +684,8 @@ void BmffImage::parseCr3Preview(const DataBuf& data, std::ostream& out, bool bTr
return "application/octet-stream";
}();
if (bTrace) {
out << Internal::stringFormat("width,height,size = %zu,%zu,%zu", nativePreview.width_, nativePreview.height_,
nativePreview.size_);
out << stringFormat("width,height,size = {},{},{}", nativePreview.width_, nativePreview.height_,
nativePreview.size_);
}
nativePreviews_.push_back(std::move(nativePreview));
}
Expand Down
Loading
Loading