Skip to content

Commit

Permalink
Fallback to std::format for c++20, fixed some warns
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeMirzayanov committed Sep 22, 2024
1 parent 7b15e65 commit 5f898aa
Showing 1 changed file with 67 additions and 45 deletions.
112 changes: 67 additions & 45 deletions testlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
* Copyright (c) 2005-2024
*/

#define VERSION "0.9.43"
#define VERSION "0.9.44-SNAPSHOT"

/*
* Mike Mirzayanov
Expand Down Expand Up @@ -63,6 +63,7 @@
*/

const char *latestFeatures[] = {
"Fallback to std::format for c++20, fixed some warns",
"Added ConstantBoundsLog, VariablesLog to validator testOverviewLogFile",
"Use setAppesModeEncoding to change xml encoding from windows-1251 to other",
"rnd.any/wany use distance/advance instead of -/+: now they support sets/multisets",
Expand Down Expand Up @@ -330,6 +331,12 @@ static int __testlib_format_buffer_usage_count = 0;
result = std::string(__testlib_format_buffer); \
__testlib_format_buffer_usage_count--; \

#ifdef __GNUC__
__attribute__ ((format (printf, 1, 2)))
#endif
std::string testlib_format_(const char *fmt, ...);
std::string testlib_format_(const std::string fmt, ...);

const long long __TESTLIB_LONGLONG_MAX = 9223372036854775807LL;
const int __TESTLIB_MAX_TEST_CASE = 1073741823;

Expand Down Expand Up @@ -430,19 +437,6 @@ inline std::string lowerCase(std::string s) {
return s;
}

#ifdef __GNUC__
__attribute__ ((format (printf, 1, 2)))
#endif
std::string format(const char *fmt, ...) {
FMT_TO_RESULT(fmt, fmt, result);
return result;
}

std::string format(const std::string fmt, ...) {
FMT_TO_RESULT(fmt, fmt.c_str(), result);
return result;
}

#ifdef __GNUC__
__attribute__((const))
#endif
Expand Down Expand Up @@ -1805,7 +1799,7 @@ class FileInputStreamReader : public InputStreamReader {

void setTestCase(int testCase) {
if (testCase < 0 || testCase > __TESTLIB_MAX_TEST_CASE)
__testlib_fail(format("testCase expected fit in [1,%d], but %d doesn't", __TESTLIB_MAX_TEST_CASE, testCase));
__testlib_fail(testlib_format_("testCase expected fit in [1,%d], but %d doesn't", __TESTLIB_MAX_TEST_CASE, testCase));
readChars.push_back(testCase + 256);
}

Expand Down Expand Up @@ -3127,7 +3121,7 @@ NORETURN void InStream::quit(TResult result, const char *msg) {
break;
default:
if (result >= _partially) {
errorName = format("partially correct (%d) ", pctype);
errorName = testlib_format_("partially correct (%d) ", pctype);
isPartial = true;
quitscrS(LightYellow, errorName);
} else
Expand All @@ -3151,7 +3145,7 @@ NORETURN void InStream::quit(TResult result, const char *msg) {
else {
if (__testlib_points == std::numeric_limits<float>::infinity())
quit(_fail, "Expected points, but infinity found");
std::string stringPoints = removeDoubleTrailingZeroes(format("%.10f", __testlib_points));
std::string stringPoints = removeDoubleTrailingZeroes(testlib_format_("%.10f", __testlib_points));
std::fprintf(resultFile, "<result outcome = \"%s\" points = \"%s\">",
outcomes[(int) result].c_str(), stringPoints.c_str());
}
Expand Down Expand Up @@ -3483,9 +3477,9 @@ std::string InStream::readWord(const pattern &p, const std::string &variableName

std::vector<std::string>
InStream::readWords(int size, const pattern &p, const std::string &variablesName, int indexBase) {
__testlib_readMany(readWords, readWord(p, variablesName), std::string, true);
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readWords, readWord(p, variablesName), std::string, true);
}

std::vector<std::string> InStream::readWords(int size, int indexBase) {
Expand All @@ -3499,9 +3493,9 @@ std::string InStream::readWord(const std::string &ptrn, const std::string &varia
std::vector<std::string>
InStream::readWords(int size, const std::string &ptrn, const std::string &variablesName, int indexBase) {
pattern p(ptrn);
__testlib_readMany(readWords, readWord(p, variablesName), std::string, true);
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readWords, readWord(p, variablesName), std::string, true);
}

std::string InStream::readToken(const pattern &p, const std::string &variableName) {
Expand All @@ -3510,9 +3504,9 @@ std::string InStream::readToken(const pattern &p, const std::string &variableNam

std::vector<std::string>
InStream::readTokens(int size, const pattern &p, const std::string &variablesName, int indexBase) {
__testlib_readMany(readTokens, readToken(p, variablesName), std::string, true);
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readTokens, readToken(p, variablesName), std::string, true);
}

std::vector<std::string> InStream::readTokens(int size, int indexBase) {
Expand All @@ -3526,9 +3520,9 @@ std::string InStream::readToken(const std::string &ptrn, const std::string &vari
std::vector<std::string>
InStream::readTokens(int size, const std::string &ptrn, const std::string &variablesName, int indexBase) {
pattern p(ptrn);
__testlib_readMany(readTokens, readWord(p, variablesName), std::string, true);
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readTokens, readWord(p, variablesName), std::string, true);
}

void InStream::readWordTo(std::string &result, const pattern &p, const std::string &variableName) {
Expand Down Expand Up @@ -3893,9 +3887,9 @@ long long InStream::readLong(long long minv, long long maxv, const std::string &

std::vector<long long>
InStream::readLongs(int size, long long minv, long long maxv, const std::string &variablesName, int indexBase) {
__testlib_readMany(readLongs, readLong(minv, maxv, variablesName), long long, true)
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readLongs, readLong(minv, maxv, variablesName), long long, true)
}

std::vector<long long> InStream::readLongs(int size, int indexBase) {
Expand Down Expand Up @@ -3939,9 +3933,9 @@ InStream::readUnsignedLong(unsigned long long minv, unsigned long long maxv, con

std::vector<unsigned long long> InStream::readUnsignedLongs(int size, unsigned long long minv, unsigned long long maxv,
const std::string &variablesName, int indexBase) {
__testlib_readMany(readUnsignedLongs, readUnsignedLong(minv, maxv, variablesName), unsigned long long, true)
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readUnsignedLongs, readUnsignedLong(minv, maxv, variablesName), unsigned long long, true)
}

std::vector<unsigned long long> InStream::readUnsignedLongs(int size, int indexBase) {
Expand Down Expand Up @@ -3993,19 +3987,19 @@ int InStream::readInteger(int minv, int maxv, const std::string &variableName) {
}

std::vector<int> InStream::readInts(int size, int minv, int maxv, const std::string &variablesName, int indexBase) {
__testlib_readMany(readInts, readInt(minv, maxv, variablesName), int, true)
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readInts, readInt(minv, maxv, variablesName), int, true)
}

std::vector<int> InStream::readInts(int size, int indexBase) {
__testlib_readMany(readInts, readInt(), int, true)
}

std::vector<int> InStream::readIntegers(int size, int minv, int maxv, const std::string &variablesName, int indexBase) {
__testlib_readMany(readIntegers, readInt(minv, maxv, variablesName), int, true)
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readIntegers, readInt(minv, maxv, variablesName), int, true)
}

std::vector<int> InStream::readIntegers(int size, int indexBase) {
Expand Down Expand Up @@ -4059,9 +4053,9 @@ double InStream::readReal(double minv, double maxv, const std::string &variableN

std::vector<double>
InStream::readReals(int size, double minv, double maxv, const std::string &variablesName, int indexBase) {
__testlib_readMany(readReals, readReal(minv, maxv, variablesName), double, true)
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readReals, readReal(minv, maxv, variablesName), double, true)
}

std::vector<double> InStream::readReals(int size, int indexBase) {
Expand All @@ -4074,9 +4068,9 @@ double InStream::readDouble(double minv, double maxv, const std::string &variabl

std::vector<double>
InStream::readDoubles(int size, double minv, double maxv, const std::string &variablesName, int indexBase) {
__testlib_readMany(readDoubles, readDouble(minv, maxv, variablesName), double, true)
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readDoubles, readDouble(minv, maxv, variablesName), double, true)
}

std::vector<double> InStream::readDoubles(int size, int indexBase) {
Expand Down Expand Up @@ -4126,11 +4120,11 @@ double InStream::readStrictReal(double minv, double maxv,
std::vector<double> InStream::readStrictReals(int size, double minv, double maxv,
int minAfterPointDigitCount, int maxAfterPointDigitCount,
const std::string &variablesName, int indexBase) {
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readStrictReals,
readStrictReal(minv, maxv, minAfterPointDigitCount, maxAfterPointDigitCount, variablesName),
double, true)
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
}

double InStream::readStrictDouble(double minv, double maxv,
Expand All @@ -4144,11 +4138,11 @@ double InStream::readStrictDouble(double minv, double maxv,
std::vector<double> InStream::readStrictDoubles(int size, double minv, double maxv,
int minAfterPointDigitCount, int maxAfterPointDigitCount,
const std::string &variablesName, int indexBase) {
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readStrictDoubles,
readStrictDouble(minv, maxv, minAfterPointDigitCount, maxAfterPointDigitCount, variablesName),
double, true)
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
}

bool InStream::eof() {
Expand Down Expand Up @@ -4322,9 +4316,9 @@ std::string InStream::readString(const pattern &p, const std::string &variableNa

std::vector<std::string>
InStream::readStrings(int size, const pattern &p, const std::string &variablesName, int indexBase) {
__testlib_readMany(readStrings, readString(p, variablesName), std::string, false)
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readStrings, readString(p, variablesName), std::string, false)
}

std::string InStream::readString(const std::string &ptrn, const std::string &variableName) {
Expand All @@ -4335,9 +4329,9 @@ std::string InStream::readString(const std::string &ptrn, const std::string &var
std::vector<std::string>
InStream::readStrings(int size, const std::string &ptrn, const std::string &variablesName, int indexBase) {
pattern p(ptrn);
__testlib_readMany(readStrings, readString(p, variablesName), std::string, false)
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readStrings, readString(p, variablesName), std::string, false)
}

void InStream::readLineTo(std::string &result) {
Expand Down Expand Up @@ -4366,9 +4360,9 @@ std::string InStream::readLine(const pattern &p, const std::string &variableName

std::vector<std::string>
InStream::readLines(int size, const pattern &p, const std::string &variablesName, int indexBase) {
__testlib_readMany(readLines, readString(p, variablesName), std::string, false)
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readLines, readString(p, variablesName), std::string, false)
}

std::string InStream::readLine(const std::string &ptrn, const std::string &variableName) {
Expand All @@ -4378,9 +4372,9 @@ std::string InStream::readLine(const std::string &ptrn, const std::string &varia
std::vector<std::string>
InStream::readLines(int size, const std::string &ptrn, const std::string &variablesName, int indexBase) {
pattern p(ptrn);
__testlib_readMany(readLines, readString(p, variablesName), std::string, false)
if (strict && !variablesName.empty())
validator.addVariable(variablesName);
__testlib_readMany(readLines, readString(p, variablesName), std::string, false)
}

#ifdef __GNUC__
Expand Down Expand Up @@ -4435,7 +4429,7 @@ double __testlib_preparePoints(double points_) {

NORETURN void __testlib_quitp(double points, const char *message) {
__testlib_points = __testlib_preparePoints(points);
std::string stringPoints = removeDoubleTrailingZeroes(format("%.10f", __testlib_points));
std::string stringPoints = removeDoubleTrailingZeroes(testlib_format_("%.10f", __testlib_points));

std::string quitMessage;
if (NULL == message || 0 == strlen(message))
Expand All @@ -4448,7 +4442,7 @@ NORETURN void __testlib_quitp(double points, const char *message) {

NORETURN void __testlib_quitp(int points, const char *message) {
__testlib_points = __testlib_preparePoints(points);
std::string stringPoints = format("%d", points);
std::string stringPoints = testlib_format_("%d", points);

std::string quitMessage;
if (NULL == message || 0 == strlen(message))
Expand Down Expand Up @@ -4764,7 +4758,7 @@ void registerValidation(int argc, char *argv[]) {
if (i + 1 < argc) {
long long testCase = stringToLongLong(inf, argv[++i]);
if (testCase < 1 || testCase >= __TESTLIB_MAX_TEST_CASE)
quit(_fail, format("Argument testCase should be between 1 and %d, but ", __TESTLIB_MAX_TEST_CASE)
quit(_fail, testlib_format_("Argument testCase should be between 1 and %d, but ", __TESTLIB_MAX_TEST_CASE)
+ toString(testCase) + " found");
validator.setTestCase(int(testCase));
} else
Expand Down Expand Up @@ -5182,17 +5176,17 @@ std::vector<std::string> tokenize(const std::string &s, const std::string &separ
NORETURN void __testlib_expectedButFound(TResult result, std::string expected, std::string found, const char *prepend) {
std::string message;
if (strlen(prepend) != 0)
message = format("%s: expected '%s', but found '%s'",
message = testlib_format_("%s: expected '%s', but found '%s'",
compress(prepend).c_str(), compress(expected).c_str(), compress(found).c_str());
else
message = format("expected '%s', but found '%s'",
message = testlib_format_("expected '%s', but found '%s'",
compress(expected).c_str(), compress(found).c_str());
quit(result, message);
}

NORETURN void __testlib_expectedButFound(TResult result, double expected, double found, const char *prepend) {
std::string expectedString = removeDoubleTrailingZeroes(format("%.12f", expected));
std::string foundString = removeDoubleTrailingZeroes(format("%.12f", found));
std::string expectedString = removeDoubleTrailingZeroes(testlib_format_("%.12f", expected));
std::string foundString = removeDoubleTrailingZeroes(testlib_format_("%.12f", found));
__testlib_expectedButFound(result, expectedString, foundString, prepend);
}

Expand Down Expand Up @@ -5223,8 +5217,8 @@ __attribute__ ((format (printf, 4, 5)))
#endif
NORETURN void expectedButFound<double>(TResult result, double expected, double found, const char *prependFormat, ...) {
FMT_TO_RESULT(prependFormat, prependFormat, prepend);
std::string expectedString = removeDoubleTrailingZeroes(format("%.12f", expected));
std::string foundString = removeDoubleTrailingZeroes(format("%.12f", found));
std::string expectedString = removeDoubleTrailingZeroes(testlib_format_("%.12f", expected));
std::string foundString = removeDoubleTrailingZeroes(testlib_format_("%.12f", found));
__testlib_expectedButFound(result, expectedString, foundString, prepend.c_str());
}

Expand Down Expand Up @@ -6199,7 +6193,7 @@ std::string opt(const std::string &key, const std::string &default_value) {
void ensureNoUnusedOpts() {
for (const auto &opt: __testlib_opts) {
if (!opt.second.used) {
__testlib_fail(format("Opts: unused key '%s'", compress(opt.first).c_str()));
__testlib_fail(testlib_format_("Opts: unused key '%s'", compress(opt.first).c_str()));
}
}
}
Expand All @@ -6217,4 +6211,32 @@ void TestlibFinalizeGuard::autoEnsureNoUnusedOpts() {
TestlibFinalizeGuard testlibFinalizeGuard;

#endif

#ifdef __GNUC__
__attribute__ ((format (printf, 1, 2)))
#endif
std::string testlib_format_(const char *fmt, ...) {
FMT_TO_RESULT(fmt, fmt, result);
return result;
}

std::string testlib_format_(const std::string fmt, ...) {
FMT_TO_RESULT(fmt, fmt.c_str(), result);
return result;
}

#if __cplusplus >= 202002L && __has_include(<format>)
# include <format>
#else
std::string format(const char *fmt, ...) {
FMT_TO_RESULT(fmt, fmt, result);
return result;
}

std::string format(const std::string fmt, ...) {
FMT_TO_RESULT(fmt, fmt.c_str(), result);
return result;
}
#endif

#endif

0 comments on commit 5f898aa

Please sign in to comment.