mirror of
https://github.com/GerbilSoft/rom-properties.git
synced 2025-06-18 11:35:38 -04:00
[librpbase] Initial switch to libfmt for string formatting.
This will replace printf()-style functions in most cases, and will replace all uses of rp_sprintf() and related. NOTE: We need to use FMT_STRING() [which we're abbreviating FSTR] if compiling without C++20 support; otherwise, string format checking won't be done. We're not targetting C++20 at the moment. Also, string format checking can't be done when using gettext. This also applied to printf(), so it's not a big deal per se. NOTE: Support for C++-style format strings (std::print) was added in gettext-0.22, so gettext-0.22 will be required in order to update the .pot and .po files. FIXME: libfmt has its own "PACKED" definition, which conflicts with our own. We should rename our "PACKED" to "RP_PACKED". TODO: Add an internal copy of libfmt for Windows.
This commit is contained in:
parent
59816111fc
commit
64e860f545
@ -172,6 +172,7 @@ INCLUDE(CheckTinyXML2)
|
||||
INCLUDE(CheckZSTD)
|
||||
INCLUDE(CheckLZ4)
|
||||
INCLUDE(CheckLZO)
|
||||
INCLUDE(CheckLibfmt)
|
||||
|
||||
# Reference: https://cmake.org/Wiki/RecipeAddUninstallTarget
|
||||
########### Add uninstall target ###############
|
||||
|
54
cmake/libs/CheckLibfmt.cmake
Normal file
54
cmake/libs/CheckLibfmt.cmake
Normal file
@ -0,0 +1,54 @@
|
||||
# Check for libfmt.
|
||||
# If libfmt isn't found, extlib/libfmt/ will be used instead.
|
||||
|
||||
# TODO: Add internal libfmt.
|
||||
FIND_PACKAGE(Fmt REQUIRED)
|
||||
SET(Fmt_LIBRARY "fmt::fmt")
|
||||
|
||||
IF(0)
|
||||
IF(NOT USE_INTERNAL_FMT)
|
||||
IF(Fmt_LIBRARY MATCHES "^fmt$" OR Fmt_LIBRARY MATCHES "^fmt")
|
||||
# Internal libfmt was previously in use.
|
||||
UNSET(Fmt_FOUND)
|
||||
UNSET(HAVE_Fmt)
|
||||
UNSET(Fmt_LIBRARY CACHE)
|
||||
UNSET(Fmt_LIBRARIES CACHE)
|
||||
ENDIF()
|
||||
|
||||
# Check for libfmt.
|
||||
FIND_PACKAGE(Fmt)
|
||||
IF(Fmt_FOUND)
|
||||
# Found system libfmt.
|
||||
SET(HAVE_Fmt 1)
|
||||
ELSE()
|
||||
# System libfmt was not found.
|
||||
MESSAGE(STATUS "Using the internal copy of libfmt since a system version was not found.")
|
||||
SET(USE_INTERNAL_FMT ON CACHE BOOL "Use the internal copy of libfmt" FORCE)
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Using the internal copy of libfmt.")
|
||||
ENDIF(NOT USE_INTERNAL_FMT)
|
||||
|
||||
IF(USE_INTERNAL_FMT)
|
||||
# Using the internal libfmt library.
|
||||
SET(Fmt_FOUND 1)
|
||||
SET(HAVE_Fmt 1)
|
||||
SET(Fmt_VERSION 11.1.1 CACHE INTERNAL "libfmt version" FORCE)
|
||||
# FIXME: When was it changed from LIBRARY to LIBRARIES?
|
||||
IF(WIN32 OR APPLE)
|
||||
# Using DLLs on Windows and Mac OS X.
|
||||
SET(USE_INTERNAL_FMT_DLL ON)
|
||||
SET(Fmt_LIBRARY fmt CACHE INTERNAL "libfmt library" FORCE)
|
||||
ELSE()
|
||||
# Using static linking on other systems.
|
||||
SET(USE_INTERNAL_FMT_DLL OFF)
|
||||
SET(Fmt_LIBRARY fmt CACHE INTERNAL "libfmt library" FORCE)
|
||||
ENDIF()
|
||||
SET(Fmt_LIBRARIES ${Fmt_LIBRARY} CACHE INTERNAL "libfmt libraries" FORCE)
|
||||
# FIXME: When was it changed from DIR to DIRS?
|
||||
SET(Fmt_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/extlib/libfmt)
|
||||
SET(Fmt_INCLUDE_DIRS ${Fmt_INCLUDE_DIR})
|
||||
ELSE(USE_INTERNAL_FMT)
|
||||
SET(USE_INTERNAL_FMT_DLL OFF)
|
||||
ENDIF(USE_INTERNAL_FMT)
|
||||
ENDIF(0)
|
@ -63,6 +63,8 @@ CheckOptions:
|
||||
performance-inefficient-vector-operation.VectorLikeClasses: '::std::vector;QList;QByteARray;QByteArrayList;QItemSelection;QQueue;QStringList'
|
||||
misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic: '1'
|
||||
modernize-avoid-c-arrays.AllowStringArrays: 'true'
|
||||
modernize-use-std-print.PrintfLikeFunctions: 'printf;rp_sprintf'
|
||||
modernize-use-std-print.ReplacementPrintFunction: 'fmt::print'
|
||||
readability-function-cognitive-complexity.IgnoreMacros: 'true'
|
||||
readability-implicit-bool-conversion.AllowPointerConditions: 'true'
|
||||
readability-simplify-subscript-expr.Types: '::std::basic_string;::std::basic_string_view;::std::vector;::std::array;::std::span;QByteArray;QString'
|
||||
|
@ -257,6 +257,9 @@ FOREACH(_target ${TARGETS})
|
||||
TARGET_LINK_LIBRARIES(${_target} PRIVATE ${NETTLE_LIBRARY})
|
||||
TARGET_INCLUDE_DIRECTORIES(${_target} PRIVATE ${NETTLE_INCLUDE_DIRS})
|
||||
ENDIF(NETTLE_FOUND)
|
||||
IF(Fmt_FOUND)
|
||||
TARGET_LINK_LIBRARIES(${_target} PRIVATE ${Fmt_LIBRARY})
|
||||
ENDIF(Fmt_FOUND)
|
||||
|
||||
IF(WIN32)
|
||||
# libwin32common
|
||||
|
@ -97,7 +97,7 @@ string RomDataPrivate::getURL_GameTDB(
|
||||
const char *region, const char *gameID,
|
||||
const char *ext)
|
||||
{
|
||||
return rp_sprintf("https://art.gametdb.com/%s/%s/%s/%s%s",
|
||||
return fmt::format(FSTR("https://art.gametdb.com/{:s}/{:s}/{:s}/{:s}{:s}"),
|
||||
system, type, region, gameID, ext);
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@ string RomDataPrivate::getCacheKey_GameTDB(
|
||||
const char *region, const char *gameID,
|
||||
const char *ext)
|
||||
{
|
||||
return rp_sprintf("%s/%s/%s/%s%s",
|
||||
return fmt::format(FSTR("{:s}/{:s}/{:s}/{:s}{:s}"),
|
||||
system, type, region, gameID, ext);
|
||||
}
|
||||
|
||||
@ -135,9 +135,9 @@ string RomDataPrivate::getURL_RPDB(
|
||||
{
|
||||
// Game ID may need to be urlencoded.
|
||||
const string gameID_urlencode = LibCacheCommon::urlencode(gameID);
|
||||
return rp_sprintf("https://rpdb.gerbilsoft.com/%s/%s/%s%s%s%s",
|
||||
return fmt::format(FSTR("https://rpdb.gerbilsoft.com/{:s}/{:s}/{:s}{:s}{:s}{:s}"),
|
||||
system, type, (region ? region : ""), (region ? "/" : ""),
|
||||
gameID_urlencode.c_str(), ext);
|
||||
gameID_urlencode, ext);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -154,7 +154,7 @@ string RomDataPrivate::getCacheKey_RPDB(
|
||||
const char *region, const char *gameID,
|
||||
const char *ext)
|
||||
{
|
||||
return rp_sprintf("%s/%s/%s%s%s%s",
|
||||
return fmt::format(FSTR("{:s}/{:s}/{:s}{:s}{:s}{:s}"),
|
||||
system, type, (region ? region : ""), (region ? "/" : ""),
|
||||
gameID, ext);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ROM Properties Page shell extension. (librpbase) *
|
||||
* RomFields.cpp: ROM fields class. *
|
||||
* *
|
||||
* Copyright (c) 2016-2024 by David Korth. *
|
||||
* Copyright (c) 2016-2025 by David Korth. *
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later *
|
||||
***************************************************************************/
|
||||
|
||||
@ -462,7 +462,7 @@ string RomFields::ageRatingDecode(AgeRatingsCountry country, uint16_t rating)
|
||||
} else {
|
||||
// No string rating.
|
||||
// Print the numeric value.
|
||||
str = rp_sprintf("%u",
|
||||
str = fmt::format(FSTR("{:d}"),
|
||||
static_cast<unsigned int>(rating) & RomFields::AGEBF_MIN_AGE_MASK);
|
||||
}
|
||||
|
||||
@ -514,7 +514,7 @@ string RomFields::ageRatingsDecode(const age_ratings_t *age_ratings, bool newlin
|
||||
} else {
|
||||
// Invalid age rating organization.
|
||||
// Use the numeric index.
|
||||
str += rp_sprintf("%u", i);
|
||||
str += fmt::format(FSTR("{:d}"), i);
|
||||
}
|
||||
str += '=';
|
||||
str += ageRatingDecode((AgeRatingsCountry)i, rating);
|
||||
@ -956,23 +956,25 @@ int RomFields::addField_string_numeric(const char *name, uint32_t val, Base base
|
||||
if (!name)
|
||||
return -1;
|
||||
|
||||
const char *fmtstr;
|
||||
string s;
|
||||
switch (base) {
|
||||
case Base::Dec:
|
||||
default:
|
||||
fmtstr = "%0*u";
|
||||
s = fmt::format(FSTR("{:0>{}d}"), val, digits);
|
||||
break;
|
||||
case Base::Hex:
|
||||
fmtstr = (!(flags & STRF_HEX_LOWER)) ? "0x%0*X" : "0x%0*x";
|
||||
if (unlikely(flags & STRF_HEX_LOWER)) {
|
||||
s = fmt::format(FSTR("0x{:0>{}x}"), val, digits);
|
||||
} else {
|
||||
s = fmt::format(FSTR("0x{:0>{}X}"), val, digits);
|
||||
}
|
||||
break;
|
||||
case Base::Oct:
|
||||
fmtstr = "0%0*o";
|
||||
s = fmt::format(FSTR("0{:0>{}o}"), val, digits);
|
||||
break;
|
||||
}
|
||||
|
||||
char buf[64];
|
||||
snprintf(buf, sizeof(buf), fmtstr, digits, val);
|
||||
return addField_string(name, buf, flags);
|
||||
return addField_string(name, s, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1058,16 +1060,20 @@ int RomFields::addField_string_address_range(const char *name,
|
||||
}
|
||||
|
||||
// Address range
|
||||
char buf[128];
|
||||
int len = snprintf(buf, sizeof(buf),
|
||||
(!(flags & STRF_HEX_LOWER)) ? "0x%0*X - 0x%0*X" : "0x%0*x - 0x%0*x",
|
||||
digits, start, digits, end);
|
||||
if (suffix && suffix[0] != 0 && (len > 0 && len < 126)) {
|
||||
string s;
|
||||
s.reserve(digits * 2 + (suffix ? 8+4 : 4));
|
||||
if (unlikely(flags & STRF_HEX_LOWER)) {
|
||||
s = fmt::format(FSTR("0x{:0>{}x} - 0x{:0>{}x}"), start, digits, end, digits);
|
||||
} else {
|
||||
s = fmt::format(FSTR("0x{:0>{}X} - 0x{:0>{}X}"), start, digits, end, digits);
|
||||
}
|
||||
if (suffix && suffix[0] != 0 && !s.empty()) {
|
||||
// Append a space and the specified suffix.
|
||||
snprintf(&buf[len], sizeof(buf)-len, " %s", suffix);
|
||||
s += ' ';
|
||||
s += suffix;
|
||||
}
|
||||
|
||||
return addField_string(name, buf, flags);
|
||||
return addField_string(name, s, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ROM Properties Page shell extension. (librpbase) *
|
||||
* TextOut.hpp: Text output for RomData. (User-readable text) *
|
||||
* *
|
||||
* Copyright (c) 2016-2024 by David Korth. *
|
||||
* Copyright (c) 2016-2025 by David Korth. *
|
||||
* Copyright (c) 2016-2018 by Egor. *
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later *
|
||||
***************************************************************************/
|
||||
@ -889,7 +889,7 @@ public:
|
||||
if (name) {
|
||||
os << name;
|
||||
} else {
|
||||
os << rp_sprintf(C_("TextOut", "(tab %d)"), tabIdx);
|
||||
os << fmt::format(C_("TextOut", "(tab {:d})"), tabIdx);
|
||||
}
|
||||
os << " -----" << '\n';
|
||||
}
|
||||
@ -948,7 +948,7 @@ std::ostream& operator<<(std::ostream& os, const ROMOutput& fo) {
|
||||
// NOTE: RomDataView context is used for the "unknown" strings.
|
||||
{
|
||||
// tr: "[System] [FileType] detected."
|
||||
const string detectMsg = rp_sprintf_p(C_("TextOut", "%1$s %2$s detected"),
|
||||
const string detectMsg = fmt::format(C_("TextOut", "{0:s} {1:s} detected"),
|
||||
(systemName ? systemName : C_("RomDataView", "(unknown system)")),
|
||||
(fileType ? fileType : C_("RomDataView", "(unknown filetype)")));
|
||||
|
||||
@ -974,7 +974,7 @@ std::ostream& operator<<(std::ostream& os, const ROMOutput& fo) {
|
||||
auto image = romdata->image(static_cast<RomData::ImageType>(i));
|
||||
if (image && image->isValid()) {
|
||||
// tr: Image Type name, followed by Image Type ID
|
||||
os << "-- " << rp_sprintf_p(C_("TextOut", "%1$s is present (use -x%2$d to extract)"),
|
||||
os << "-- " << fmt::format(C_("TextOut", "{0:s} is present (use -x{1:d} to extract)"),
|
||||
RomData::getImageTypeName(static_cast<RomData::ImageType>(i)), i) << '\n';
|
||||
// TODO: After localizing, add enough spaces for alignment.
|
||||
os << " Format : " << rp_image::getFormatName(image->format()) << '\n';
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ROM Properties Page shell extension. (librpbase) *
|
||||
* RpJpeg.cpp: JPEG image handler. *
|
||||
* *
|
||||
* Copyright (c) 2016-2024 by David Korth. *
|
||||
* Copyright (c) 2016-2025 by David Korth. *
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later *
|
||||
***************************************************************************/
|
||||
|
||||
@ -101,7 +101,7 @@ static void JPEGCALL my_output_message(j_common_ptr cinfo)
|
||||
OutputDebugStringA(txtbuf);
|
||||
#else /* !_WIN32 */
|
||||
// Print to stderr.
|
||||
fprintf(stderr, "libjpeg error: %s\n", buffer);
|
||||
fmt::print(stderr, "libjpeg error: {:s}\n", buffer);
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
@ -285,14 +285,14 @@ rp_image_ptr load(IRpFile *file)
|
||||
if (try_ext_bgra && tried_ext_bgra) {
|
||||
// Tried using JCS_EXT_BGRA and it didn't work.
|
||||
// Try again with JCS_RGB.
|
||||
fputs("JCS_EXT_BGRA FAILED, trying JCS_RGB\n", stderr);
|
||||
fmt::print(stderr, "JCS_EXT_BGRA FAILED, trying JCS_RGB\n");
|
||||
try_ext_bgra = false;
|
||||
direct_copy = false;
|
||||
file->rewind();
|
||||
jmperr = setjmp(jerr.setjmp_buffer);
|
||||
}
|
||||
if (jmperr) {
|
||||
fputs("JPEG decoding FAILED\n", stderr);
|
||||
fmt::print(stderr, "JPEG decoding FAILED\n");
|
||||
// An error occurred while decoding the JPEG.
|
||||
// NOTE: buffer is allocated using JPEG allocation functions,
|
||||
// so it's automatically freed when we destroy cinfo.
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ROM Properties Page shell extension. (librpbase) *
|
||||
* stdafx.h: Common definitions and includes. *
|
||||
* *
|
||||
* Copyright (c) 2016-2024 by David Korth. *
|
||||
* Copyright (c) 2016-2025 by David Korth. *
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later *
|
||||
***************************************************************************/
|
||||
|
||||
@ -37,6 +37,11 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
// libfmt
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#define FSTR FMT_STRING
|
||||
|
||||
#else /* !__cplusplus */
|
||||
/** C **/
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ROM Properties Page shell extension. (librpbase/tests) *
|
||||
* AesCipherTest.cpp: AesCipher class test. *
|
||||
* *
|
||||
* Copyright (c) 2016-2024 by David Korth. *
|
||||
* Copyright (c) 2016-2025 by David Korth. *
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later *
|
||||
***************************************************************************/
|
||||
|
||||
@ -27,6 +27,13 @@ using std::ostringstream;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
// libfmt
|
||||
// FIXME: libfmt has its own "PACKED" definition.
|
||||
#undef PACKED
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#define FSTR FMT_STRING
|
||||
|
||||
namespace LibRpBase { namespace Tests {
|
||||
|
||||
typedef IAesCipher* (*PFNCREATEIAESCIPHER)(void);
|
||||
@ -170,11 +177,13 @@ void AesCipherTest::CompareByteArrays(
|
||||
// Output format: (assume ~64 bytes per line)
|
||||
// 0000: 01 23 45 67 89 AB CD EF 01 23 45 67 89 AB CD EF
|
||||
const size_t bufSize = ((size / 16) + !!(size % 16)) * 64;
|
||||
char printf_buf[16];
|
||||
string s_expected, s_actual;
|
||||
s_expected.reserve(bufSize);
|
||||
s_actual.reserve(bufSize);
|
||||
|
||||
string s_tmp;
|
||||
s_tmp.reserve(14);
|
||||
|
||||
const uint8_t *pE = expected, *pA = actual;
|
||||
for (size_t i = 0; i < size; i++, pE++, pA++) {
|
||||
if (i % 16 == 0) {
|
||||
@ -185,16 +194,14 @@ void AesCipherTest::CompareByteArrays(
|
||||
s_actual += '\n';
|
||||
}
|
||||
|
||||
snprintf(printf_buf, sizeof(printf_buf), "%04X: ", static_cast<unsigned int>(i));
|
||||
s_expected += printf_buf;
|
||||
s_actual += printf_buf;
|
||||
s_tmp = fmt::format(FSTR("{:0>4X}: "), static_cast<unsigned int>(i));
|
||||
s_expected += s_tmp;
|
||||
s_actual += s_tmp;
|
||||
}
|
||||
|
||||
// Print the byte.
|
||||
snprintf(printf_buf, sizeof(printf_buf), "%02X", *pE);
|
||||
s_expected += printf_buf;
|
||||
snprintf(printf_buf, sizeof(printf_buf), "%02X", *pA);
|
||||
s_actual += printf_buf;
|
||||
s_expected += fmt::format(FSTR("{:0>2X}"), *pE);
|
||||
s_actual += fmt::format(FSTR("{:0>2X}"), *pA);
|
||||
|
||||
if (i % 16 == 7) {
|
||||
s_expected += " ";
|
||||
@ -227,11 +234,11 @@ void AesCipherTest::SetUp(void)
|
||||
// Print the AesCipher implementation name.
|
||||
const char *name = m_cipher->name();
|
||||
ASSERT_TRUE(name != nullptr);
|
||||
printf("AesCipher implementation: %s\n", name);
|
||||
fmt::print(FSTR("AesCipher implementation: {:s}\n"), name);
|
||||
pfnLastCreateIAesCipher = mode.pfnCreateIAesCipher;
|
||||
|
||||
if (!mode.isRequired && !m_cipher->isInit()) {
|
||||
fputs("This implementation is not supported on this system; skipping tests.\n", stdout);
|
||||
fmt::print(FSTR("This implementation is not supported on this system; skipping tests.\n"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -708,7 +715,7 @@ AesDecryptTestSet(Nettle, true)
|
||||
*/
|
||||
extern "C" int gtest_main(int argc, TCHAR *argv[])
|
||||
{
|
||||
fputs("LibRpBase test suite: Crypto tests.\n\n", stderr);
|
||||
fmt::print(stderr, FSTR("LibRpBase test suite: Crypto tests.\n\n"));
|
||||
fflush(nullptr);
|
||||
|
||||
// coverity[fun_call_w_exception]: uncaught exceptions cause nonzero exit anyway, so don't warn.
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ROM Properties Page shell extension. (librpbase/tests) *
|
||||
* CBCReaderTest.cpp: CBCReader class test. *
|
||||
* *
|
||||
* Copyright (c) 2016-2024 by David Korth. *
|
||||
* Copyright (c) 2016-2025 by David Korth. *
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later *
|
||||
***************************************************************************/
|
||||
|
||||
@ -31,6 +31,13 @@ using std::array;
|
||||
using std::ostringstream;
|
||||
using std::string;
|
||||
|
||||
// libfmt
|
||||
// FIXME: libfmt has its own "PACKED" definition.
|
||||
#undef PACKED
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#define FSTR FMT_STRING
|
||||
|
||||
namespace LibRpBase { namespace Tests {
|
||||
|
||||
enum class CryptoMode {
|
||||
@ -195,11 +202,13 @@ void CBCReaderTest::CompareByteArrays(
|
||||
// Output format: (assume ~64 bytes per line)
|
||||
// 0000: 01 23 45 67 89 AB CD EF 01 23 45 67 89 AB CD EF
|
||||
const size_t bufSize = ((size / 16) + !!(size % 16)) * 64;
|
||||
char printf_buf[16];
|
||||
string s_expected, s_actual;
|
||||
s_expected.reserve(bufSize);
|
||||
s_actual.reserve(bufSize);
|
||||
|
||||
string s_tmp;
|
||||
s_tmp.reserve(14);
|
||||
|
||||
const uint8_t *pE = expected, *pA = actual;
|
||||
for (size_t i = 0; i < size; i++, pE++, pA++) {
|
||||
if (i % 16 == 0) {
|
||||
@ -210,16 +219,14 @@ void CBCReaderTest::CompareByteArrays(
|
||||
s_actual += '\n';
|
||||
}
|
||||
|
||||
snprintf(printf_buf, sizeof(printf_buf), "%04X: ", static_cast<unsigned int>(i));
|
||||
s_expected += printf_buf;
|
||||
s_actual += printf_buf;
|
||||
s_tmp = fmt::format(FSTR("{:0>4X}: "), static_cast<unsigned int>(i));
|
||||
s_expected += s_tmp;
|
||||
s_actual += s_tmp;
|
||||
}
|
||||
|
||||
// Print the byte.
|
||||
snprintf(printf_buf, sizeof(printf_buf), "%02X", *pE);
|
||||
s_expected += printf_buf;
|
||||
snprintf(printf_buf, sizeof(printf_buf), "%02X", *pA);
|
||||
s_actual += printf_buf;
|
||||
s_expected += fmt::format(FSTR("{:0>2X}"), *pE);
|
||||
s_actual += fmt::format(FSTR("{:0>2X}"), *pA);
|
||||
|
||||
if (i % 16 == 7) {
|
||||
s_expected += " ";
|
||||
@ -389,7 +396,7 @@ INSTANTIATE_TEST_SUITE_P(CBCReaderTest, CBCReaderTest,
|
||||
*/
|
||||
extern "C" int gtest_main(int argc, TCHAR *argv[])
|
||||
{
|
||||
fputs("LibRpBase test suite: CBCReader tests.\n\n", stderr);
|
||||
fmt::print(stderr, FSTR("LibRpBase test suite: CBCReader tests.\n\n"));
|
||||
fflush(nullptr);
|
||||
|
||||
// coverity[fun_call_w_exception]: uncaught exceptions cause nonzero exit anyway, so don't warn.
|
||||
|
@ -36,6 +36,9 @@ TARGET_COMPILE_DEFINITIONS(RpPngFormatTest PRIVATE RP_BUILDING_FOR_DLL=1)
|
||||
TARGET_LINK_LIBRARIES(RpPngFormatTest PRIVATE ${ZLIB_LIBRARIES} ${PNG_LIBRARY})
|
||||
TARGET_INCLUDE_DIRECTORIES(RpPngFormatTest PRIVATE ${ZLIB_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS})
|
||||
TARGET_COMPILE_DEFINITIONS(RpPngFormatTest PRIVATE ${ZLIB_DEFINITIONS} ${PNG_DEFINITIONS})
|
||||
IF(Fmt_FOUND)
|
||||
TARGET_LINK_LIBRARIES(RpPngFormatTest PRIVATE ${Fmt_LIBRARY})
|
||||
ENDIF(Fmt_FOUND)
|
||||
DO_SPLIT_DEBUG(RpPngFormatTest)
|
||||
SET_WINDOWS_SUBSYSTEM(RpPngFormatTest CONSOLE)
|
||||
SET_WINDOWS_ENTRYPOINT(RpPngFormatTest wmain OFF)
|
||||
@ -60,6 +63,9 @@ IF(ENABLE_DECRYPTION)
|
||||
TARGET_LINK_LIBRARIES(CryptoTests PRIVATE ${NETTLE_LIBRARY})
|
||||
TARGET_INCLUDE_DIRECTORIES(CryptoTests PRIVATE ${NETTLE_INCLUDE_DIRS})
|
||||
ENDIF(NETTLE_LIBRARY)
|
||||
IF(Fmt_FOUND)
|
||||
TARGET_LINK_LIBRARIES(CryptoTests PRIVATE ${Fmt_LIBRARY})
|
||||
ENDIF(Fmt_FOUND)
|
||||
DO_SPLIT_DEBUG(CryptoTests)
|
||||
SET_WINDOWS_SUBSYSTEM(CryptoTests CONSOLE)
|
||||
SET_WINDOWS_ENTRYPOINT(CryptoTests wmain OFF)
|
||||
@ -78,6 +84,9 @@ IF(NETTLE_LIBRARY)
|
||||
TARGET_LINK_LIBRARIES(CBCReaderTests PRIVATE ${NETTLE_LIBRARY})
|
||||
TARGET_INCLUDE_DIRECTORIES(CBCReaderTests PRIVATE ${NETTLE_INCLUDE_DIRS})
|
||||
ENDIF(NETTLE_LIBRARY)
|
||||
IF(Fmt_FOUND)
|
||||
TARGET_LINK_LIBRARIES(CBCReaderTests PRIVATE ${Fmt_LIBRARY})
|
||||
ENDIF(Fmt_FOUND)
|
||||
DO_SPLIT_DEBUG(CBCReaderTests)
|
||||
SET_WINDOWS_SUBSYSTEM(CBCReaderTests CONSOLE)
|
||||
SET_WINDOWS_ENTRYPOINT(CBCReaderTests wmain OFF)
|
||||
@ -91,3 +100,6 @@ DO_SPLIT_DEBUG(TimegmTest)
|
||||
SET_WINDOWS_SUBSYSTEM(TimegmTest CONSOLE)
|
||||
SET_WINDOWS_ENTRYPOINT(TimegmTest wmain OFF)
|
||||
ADD_TEST(NAME TimegmTest COMMAND TimegmTest --gtest_brief)
|
||||
IF(Fmt_FOUND)
|
||||
TARGET_LINK_LIBRARIES(TimegmTest PRIVATE ${Fmt_LIBRARY})
|
||||
ENDIF(Fmt_FOUND)
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ROM Properties Page shell extension. (librpbase/tests) *
|
||||
* HashTest.cpp: Hash class test. *
|
||||
* *
|
||||
* Copyright (c) 2016-2024 by David Korth. *
|
||||
* Copyright (c) 2016-2025 by David Korth. *
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later *
|
||||
***************************************************************************/
|
||||
|
||||
@ -15,16 +15,23 @@
|
||||
// Hash
|
||||
#include "../crypto/Hash.hpp"
|
||||
|
||||
// C includes. (C++ namespace)
|
||||
// C includes (C++ namespace)
|
||||
#include <cstdio>
|
||||
|
||||
// C++ includes.
|
||||
// C++ includes
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
using std::ostringstream;
|
||||
using std::string;
|
||||
|
||||
// libfmt
|
||||
// FIXME: libfmt has its own "PACKED" definition.
|
||||
#undef PACKED
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#define FSTR FMT_STRING
|
||||
|
||||
namespace LibRpBase { namespace Tests {
|
||||
|
||||
struct HashTest_mode
|
||||
@ -79,11 +86,13 @@ void HashTest::CompareByteArrays(
|
||||
// Output format: (assume ~64 bytes per line)
|
||||
// 0000: 01 23 45 67 89 AB CD EF 01 23 45 67 89 AB CD EF
|
||||
const size_t bufSize = ((size / 16) + !!(size % 16)) * 64;
|
||||
char printf_buf[16];
|
||||
string s_expected, s_actual;
|
||||
s_expected.reserve(bufSize);
|
||||
s_actual.reserve(bufSize);
|
||||
|
||||
string s_tmp;
|
||||
s_tmp.reserve(14);
|
||||
|
||||
const uint8_t *pE = expected, *pA = actual;
|
||||
for (size_t i = 0; i < size; i++, pE++, pA++) {
|
||||
if (i % 16 == 0) {
|
||||
@ -94,16 +103,14 @@ void HashTest::CompareByteArrays(
|
||||
s_actual += '\n';
|
||||
}
|
||||
|
||||
snprintf(printf_buf, sizeof(printf_buf), "%04X: ", static_cast<unsigned int>(i));
|
||||
s_expected += printf_buf;
|
||||
s_actual += printf_buf;
|
||||
s_tmp = fmt::format(FSTR("{:0>4X}: "), static_cast<unsigned int>(i));
|
||||
s_expected += s_tmp;
|
||||
s_actual += s_tmp;
|
||||
}
|
||||
|
||||
// Print the byte.
|
||||
snprintf(printf_buf, sizeof(printf_buf), "%02X", *pE);
|
||||
s_expected += printf_buf;
|
||||
snprintf(printf_buf, sizeof(printf_buf), "%02X", *pA);
|
||||
s_actual += printf_buf;
|
||||
s_expected += fmt::format(FSTR("{:0>2X}"), *pE);
|
||||
s_actual += fmt::format(FSTR("{:0>2X}"), *pA);
|
||||
|
||||
if (i % 16 == 7) {
|
||||
s_expected += " ";
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ROM Properties Page shell extension. (librpbase/tests) *
|
||||
* TimegmTest.cpp: timegm() test. *
|
||||
* *
|
||||
* Copyright (c) 2016-2024 by David Korth. *
|
||||
* Copyright (c) 2016-2025 by David Korth. *
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later *
|
||||
***************************************************************************/
|
||||
|
||||
@ -13,6 +13,11 @@
|
||||
// timegm() and/or replacement function.
|
||||
#include "time_r.h"
|
||||
|
||||
// libfmt
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#define FSTR FMT_STRING
|
||||
|
||||
// NOTE: MSVCRT's documentation for _mkgmtime64() says it has a limited range:
|
||||
// - Documented: [1970/01/01, 3000/12/31]
|
||||
// - Actual: [1969/01/01, 3001/01/01] ??? (may need more testing)
|
||||
@ -237,13 +242,14 @@ extern "C" int gtest_main(int argc, TCHAR *argv[])
|
||||
static constexpr char func_name[] = "timegm() (internal)";
|
||||
#endif
|
||||
|
||||
fputs("LibRpBase test suite: timegm() tests.\n", stderr);
|
||||
fprintf(stderr, "Time conversion function in use: %s\n", func_name);
|
||||
fmt::print(stderr, FSTR("LibRpBase test suite: timegm() tests.\n"));
|
||||
fmt::print(stderr, FSTR("Time conversion function in use: {:s}\n"), func_name);
|
||||
if (sizeof(time_t) < 8) {
|
||||
fputs("*** WARNING: 32-bit time_t is in use.\n"
|
||||
"*** Disabling tests known to fail with 32-bit time_t.\n", stderr);
|
||||
fmt::print(stderr,
|
||||
FSTR("*** WARNING: 32-bit time_t is in use.\n"
|
||||
"*** Disabling tests known to fail with 32-bit time_t.\n"));
|
||||
}
|
||||
fputc('\n', stderr);
|
||||
fmt::print(stderr, FSTR("\n"));
|
||||
|
||||
fflush(nullptr);
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ROM Properties Page shell extension. (librpbase/tests) *
|
||||
* gtest_init.cpp: Google Test initialization. *
|
||||
* *
|
||||
* Copyright (c) 2016-2024 by David Korth. *
|
||||
* Copyright (c) 2016-2025 by David Korth. *
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later *
|
||||
***************************************************************************/
|
||||
|
||||
@ -30,6 +30,11 @@ namespace Gdiplus {
|
||||
# include <gdiplus.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
// libfmt
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#define FSTR FMT_STRING
|
||||
|
||||
extern "C" int gtest_main(int argc, TCHAR *argv[]);
|
||||
|
||||
int RP_C_API _tmain(int argc, TCHAR *argv[])
|
||||
@ -126,7 +131,7 @@ int RP_C_API _tmain(int argc, TCHAR *argv[])
|
||||
ULONG_PTR gdipToken;
|
||||
Gdiplus::Status status = GdiplusStartup(&gdipToken, &gdipSI, nullptr);
|
||||
if (status != Gdiplus::Status::Ok) {
|
||||
fputs("*** ERROR: GDI+ initialization failed.\n", stderr);
|
||||
fmt::print(stderr, FSTR("*** ERROR: GDI+ initialization failed.\n"));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
* ROM Properties Page shell extension. (librpbase/tests) *
|
||||
* RpPngFormatTest.cpp: RpPng format test. *
|
||||
* *
|
||||
* Copyright (c) 2016-2024 by David Korth. *
|
||||
* Copyright (c) 2016-2025 by David Korth. *
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later *
|
||||
***************************************************************************/
|
||||
|
||||
@ -61,6 +61,13 @@ using std::array;
|
||||
using std::shared_ptr;
|
||||
using std::string;
|
||||
|
||||
// libfmt
|
||||
// FIXME: libfmt has its own "PACKED" definition.
|
||||
#undef PACKED
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/format.h>
|
||||
#define FSTR FMT_STRING
|
||||
|
||||
namespace LibRpBase { namespace Tests {
|
||||
|
||||
// tRNS chunk for CI8 paletted images.
|
||||
@ -1317,7 +1324,7 @@ INSTANTIATE_TEST_SUITE_P(happy_mac_mono_png, RpPngFormatTest,
|
||||
*/
|
||||
extern "C" int gtest_main(int argc, TCHAR *argv[])
|
||||
{
|
||||
fputs("LibRpBase test suite: RpPng format test.\n\n", stderr);
|
||||
fmt::print(stderr, FSTR("LibRpBase test suite: RpPng format test.\n\n"));
|
||||
fflush(nullptr);
|
||||
|
||||
// Make sure the CRC32 table is initialized.
|
||||
@ -1363,7 +1370,7 @@ extern "C" int gtest_main(int argc, TCHAR *argv[])
|
||||
}
|
||||
|
||||
if (!is_found) {
|
||||
fputs("*** ERROR: Cannot find the png_data test images directory.\n", stderr);
|
||||
fmt::print(stderr, FSTR("*** ERROR: Cannot find the png_data test images directory.\n"));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user