common: use compile-time format string checking

This commit is contained in:
Eric Wasylishen 2023-06-26 01:17:22 -06:00
parent 1c85bb882a
commit 5616fd97f4
6 changed files with 42 additions and 17 deletions

View File

@ -508,7 +508,7 @@ bool ParseEntity(parser_t &parser, map_entity_t &entity)
}
if (parser.token != "{") {
FError("{}: Invalid entity format, { not found", parser.location);
FError("{}: Invalid entity format, {{ not found", parser.location);
}
do {

View File

@ -548,7 +548,7 @@ void Face_DebugPrint(const mbsp_t *bsp, const mface_t *face)
const char *texname = Face_TextureName(bsp, face);
logging::print("face {}, texture '{}', {} edges; vectors:\n"
"{: 3.3}\n",
"{}\n",
Face_GetNum(bsp, face), texname, face->numedges, tex->vecs);
for (int i = 0; i < face->numedges; i++) {

View File

@ -149,7 +149,7 @@ void entdict_t::parse(parser_base_t &parser)
if (!parser.parse_token())
return;
if (parser.token != "{")
FError("found {} when expecting {", parser.token);
FError("found {} when expecting {{", parser.token);
/* go through all the keys in this entity */
while (1) {

View File

@ -140,11 +140,23 @@ void print(flag logflag, const char *str)
print_mutex.unlock();
}
void vprint(flag logflag, fmt::string_view format, fmt::format_args args)
{
// see https://fmt.dev/10.0.0/api.html#argument-lists
print(logflag, fmt::vformat(format, args).c_str());
}
void print(const char *str)
{
print(flag::DEFAULT, str);
}
void vprint(fmt::string_view format, fmt::format_args args)
{
vprint(flag::DEFAULT, format, args);
}
static time_point start_time;
static bool is_timing = false;
static uint64_t last_count = -1;
@ -386,3 +398,9 @@ ericwtools_error::ericwtools_error(const char *what)
#endif
throw ericwtools_error(error);
}
[[noreturn]] void VError(fmt::string_view format, fmt::format_args args)
{
auto formatted = fmt::vformat(format, args);
Error(formatted.c_str());
}

View File

@ -73,23 +73,30 @@ void close();
// print to respective targets based on log flag
void print(flag logflag, const char *str);
// print to respective targets based on log flag
void vprint(flag logflag, fmt::string_view format, fmt::format_args args);
// print to default targets
void print(const char *str);
// print to default targets
void vprint(fmt::string_view format, fmt::format_args args);
// format print to specified targets
template<typename... Args>
inline void print(flag type, const char *fmt, const Args &...args)
// see: https://fmt.dev/10.0.0/api.html#argument-lists
template<typename... T>
inline void print(flag type, fmt::format_string<T...> format, T &&...args)
{
if (mask & type) {
print(type, fmt::format(fmt::runtime(fmt), std::forward<const Args &>(args)...).c_str());
vprint(type, format, fmt::make_format_args(args...));
}
}
// format print to default targets
template<typename... Args>
inline void print(const char *formt, const Args &...args)
template<typename... T>
inline void print(fmt::format_string<T...> format, T &&...args)
{
print(flag::DEFAULT, fmt::format(fmt::runtime(formt), std::forward<const Args &>(args)...).c_str());
vprint(flag::DEFAULT, format, fmt::make_format_args(args...));
}
// set print callback
@ -209,12 +216,12 @@ public:
* lightpreview can catch this to avoid crashing the whole UI.
*/
[[noreturn]] void Error(const char *error);
[[noreturn]] void VError(fmt::string_view format, fmt::format_args args);
template<typename... Args>
[[noreturn]] inline void Error(const char *fmt, const Args &...args)
template<typename... T>
[[noreturn]] inline void Error(fmt::format_string<T...> format, T &&...args)
{
auto formatted = fmt::format(fmt::runtime(fmt), std::forward<const Args &>(args)...);
Error(formatted.c_str());
VError(format, fmt::make_format_args(args...));
}
#define FError(fmt, ...) Error("{}: " fmt, __func__, ##__VA_ARGS__)

View File

@ -2496,7 +2496,7 @@ static mapbrush_t ParseBrush(parser_t &parser, mapentity_t &entity, texture_def_
// ericw -- brush primitives
if (!parser.parse_token(PARSE_PEEK))
FError("{}: unexpected EOF after { beginning brush", parser.location);
FError("{}: unexpected EOF after {{ beginning brush", parser.location);
if (parser.token == "(") {
brush.format = brushformat_t::NORMAL;
@ -2512,7 +2512,7 @@ static mapbrush_t ParseBrush(parser_t &parser, mapentity_t &entity, texture_def_
// mandatory
if (parser.token != "{")
FError("Brush primitives: expected second { at beginning of brush, got \"{}\"", parser.token);
FError("Brush primitives: expected second {{ at beginning of brush, got \"{}\"", parser.token);
}
// ericw -- end brush primitives
@ -2675,7 +2675,7 @@ static mapbrush_t ParseBrush(parser_t &parser, mapentity_t &entity, texture_def_
if (!parser.parse_token())
FError("Brush primitives: unexpected EOF (no closing brace)");
if (parser.token != "}")
FError("Brush primitives: Expected }, got: {}", parser.token);
FError("Brush primitives: Expected }}, got: {}", parser.token);
}
// ericw -- end brush primitives
@ -2693,7 +2693,7 @@ bool ParseEntity(parser_t &parser, mapentity_t &entity, texture_def_issues_t &is
}
if (parser.token != "{") {
FError("{}: Invalid entity format, { not found", parser.location);
FError("{}: Invalid entity format, {{ not found", parser.location);
}
entity.mapbrushes.clear();