update to use fmt-based apis

Not complete, but a first big stab converting users of Mu::Error and
various g_warning & friends, format to the new libfmt-based APIs.
This commit is contained in:
Dirk-Jan C. Binnema
2023-07-05 23:10:13 +03:00
parent 742ca33740
commit 4920b56671
46 changed files with 435 additions and 449 deletions

View File

@ -80,7 +80,5 @@ test('test-lang-detector',
executable('test-lang-detector', 'mu-lang-detector.cc',
install: false,
cpp_args: ['-DBUILD_TESTS'],
dependencies: [glib_dep, lib_mu_utils_dep, cld2_dep, config_h_dep]))
subdir('tests')

View File

@ -36,8 +36,8 @@ Command::string_vec_arg(const std::string& name) const
std::vector<std::string> vec;
for (const auto& item : val->list()) {
if (!item.stringp()) {
// g_warning("command: non-string in string-list for %s: %s",
// name.c_str(), to_string().c_str());
// mu_warning("command: non-string in string-list for {}: {}",
// name, to_string());
return Nothing;
} else
vec.emplace_back(item.string());
@ -68,19 +68,17 @@ validate(const CommandHandler::CommandInfoMap& cmap,
if (param_it == cmd.cend()) {
if (arginfo.required)
return Err(Error::Code::Command,
"missing required parameter %s in command '%s'",
argname.c_str(), cmd.to_string().c_str());
"missing required parameter {} in command '{}'",
argname, cmd.to_string());
continue; // not required
}
// the types must match, but the 'nil' symbol is acceptable as "no value"
if (param_val->type() != arginfo.type && !(param_val->nilp()))
return Err(Error::Code::Command,
"parameter %s expects type %s, but got %s in command '%s'",
argname.c_str(),
to_string(arginfo.type).c_str(),
to_string(param_val->type()).c_str(),
cmd.to_string().c_str());
"parameter {} expects type {}, but got {} in command '{}'",
argname, to_string(arginfo.type),
to_string(param_val->type()), cmd.to_string());
}
// all parameters must be known
@ -89,7 +87,7 @@ validate(const CommandHandler::CommandInfoMap& cmap,
if (std::none_of(cmd_info.args.cbegin(), cmd_info.args.cend(),
[&](auto&& arg) { return cmdargname == arg.first; }))
return Err(Error::Code::Command,
"unknown parameter '%s 'in command '%s'",
"unknown parameter '{} 'in command '{}'",
cmdargname.name.c_str(), cmd.to_string().c_str());
}
@ -103,7 +101,7 @@ CommandHandler::invoke(const Command& cmd, bool do_validate) const
const auto cmit{cmap_.find(cmd.name())};
if (cmit == cmap_.cend())
return Err(Error::Code::Command,
"unknown command '%s'", cmd.to_string().c_str());
"unknown command '{}'", cmd.to_string().c_str());
const auto& cmd_info{cmit->second};
if (do_validate) {
@ -142,8 +140,6 @@ test_args()
assert_equal(cmd->string_arg(":bar").value_or("abc"), "abc"); // wrong type
g_assert_false(cmd->boolean_arg(":boo"));
g_assert_true(cmd->boolean_arg(":bah"));
}
@ -164,7 +160,7 @@ call(const CommandInfoMap& cmap, const std::string& str) try {
return !!res;
} catch (const Error& err) {
g_warning("%s", err.what());
mu_warning("{}", err.what());
return false;
}

View File

@ -1,15 +1,21 @@
/*
* Created on 2020-11-08 by Dirk-Jan C. Binnema <dbinnema@logitech.com>
*
* Copyright (c) 2020 Logitech, Inc. All Rights Reserved
* This program is a trade secret of LOGITECH, and it is not to be reproduced,
* published, disclosed to others, copied, adapted, distributed or displayed
* without the prior authorization of LOGITECH.
*
* Licensee agrees to attach or embed this notice on all copies of the program,
* including partial copies or modified versions thereof.
*
*/
** Copyright (C) 2023 Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
**
** 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 3, 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, Fifth Floor, Boston, MA 02110-1301, USA.
**
*/
#ifndef MU_OPTION__
#define MU_OPTION__
@ -28,7 +34,7 @@ Some(T&& t)
{
return std::move(t);
}
constexpr auto Nothing = tl::nullopt; // 'None' is take already
constexpr auto Nothing = tl::nullopt; // 'None' is already taken.
/**
* Maybe create a string from a const char pointer.

View File

@ -103,13 +103,13 @@ Err(Error::Code code, GError **err, fmt::format_string<T...> frm, T&&... args)
*
* @param R some result
*/
#define assert_valid_result(R) do { \
if(!R) { \
g_printerr("%s:%u: error-result: %s\n", \
__FILE__, __LINE__, \
(R).error().what()); \
g_assert_true(!!R); \
} \
#define assert_valid_result(R) do { \
if(!R) { \
mu_printerrln("{}:{}: error-result: {}", \
__FILE__, __LINE__, \
(R).error().what()); \
g_assert_true(!!R); \
} \
} while(0)
}// namespace Mu

View File

@ -36,9 +36,9 @@ parsing_error(size_t pos, const char* frm, ...)
va_end(args);
if (pos == 0)
return Mu::Error(Error::Code::Parsing, "%s", msg.c_str());
return Mu::Error(Error::Code::Parsing, "{}", msg);
else
return Mu::Error(Error::Code::Parsing, "%zu: %s", pos, msg.c_str());
return Mu::Error(Error::Code::Parsing, "{}: {}", pos, msg);
}
static size_t
skip_whitespace(const std::string& s, size_t pos)
@ -58,7 +58,7 @@ static Result<Sexp>
parse_list(const std::string& expr, size_t& pos)
{
if (expr[pos] != '(') // sanity check.
return Err(parsing_error(pos, "expected: '(' but got '%c", expr[pos]));
return Err(parsing_error(pos, "expected: '(' but got '{}", expr[pos]));
Sexp lst{};
@ -71,7 +71,7 @@ parse_list(const std::string& expr, size_t& pos)
}
if (expr[pos] != ')')
return Err(parsing_error(pos, "expected: ')' but got '%c'", expr[pos]));
return Err(parsing_error(pos, "expected: ')' but got '{}'", expr[pos]));
++pos;
return Ok(std::move(lst));
}
@ -80,7 +80,7 @@ static Result<Sexp>
parse_string(const std::string& expr, size_t& pos)
{
if (expr[pos] != '"') // sanity check.
return Err(parsing_error(pos, "expected: '\"'' but got '%c", expr[pos]));
return Err(parsing_error(pos, "expected: '\"'' but got '{}", expr[pos]));
bool escape{};
std::string str;
@ -101,7 +101,7 @@ parse_string(const std::string& expr, size_t& pos)
}
if (escape || expr[pos] != '"')
return Err(parsing_error(pos, "unterminated string '%s'", str.c_str()));
return Err(parsing_error(pos, "unterminated string '{}'", str));
++pos;
return Ok(Sexp{std::move(str)});
@ -112,7 +112,7 @@ static Result<Sexp>
parse_integer(const std::string& expr, size_t& pos)
{
if (!isdigit(expr[pos]) && expr[pos] != '-') // sanity check.
return Err(parsing_error(pos, "expected: <digit> but got '%c", expr[pos]));
return Err(parsing_error(pos, "expected: <digit> but got '{}", expr[pos]));
std::string num; // negative number?
if (expr[pos] == '-') {
@ -130,7 +130,7 @@ static Result<Sexp>
parse_symbol(const std::string& expr, size_t& pos)
{
if (!isalpha(expr[pos]) && expr[pos] != ':') // sanity check.
return Err(parsing_error(pos, "expected: <alpha>|: but got '%c", expr[pos]));
return Err(parsing_error(pos, "expected: <alpha>|: but got '{}", expr[pos]));
std::string symb(1, expr[pos]);
for (++pos; isalnum(expr[pos]) || expr[pos] == '-'; ++pos)
@ -145,7 +145,7 @@ parse(const std::string& expr, size_t& pos)
pos = skip_whitespace(expr, pos);
if (pos == expr.size())
return Err(parsing_error(pos, "expected: character '%c", expr[pos]));
return Err(parsing_error(pos, "expected: character '{}", expr[pos]));
const auto kar = expr[pos];
const auto sexp = std::invoke([&]() -> Result<Sexp> {
@ -158,7 +158,7 @@ parse(const std::string& expr, size_t& pos)
else if (isalpha(kar) || kar == ':')
return parse_symbol(expr, pos);
else
return Err(parsing_error(pos, "unexpected character '%c", kar));
return Err(parsing_error(pos, "unexpected character '{}", kar));
});
if (sexp)
@ -175,7 +175,7 @@ Sexp::parse(const std::string& expr)
if (!res)
return res;
else if (pos != expr.size())
return Err(parsing_error(pos, "trailing data starting with '%c'", expr[pos]));
return Err(parsing_error(pos, "trailing data starting with '{}'", expr[pos]));
else
return res;
}

View File

@ -133,16 +133,16 @@ Mu::TempDir::~TempDir()
return; /* nothing to do */
if (!autodelete_) {
g_debug("_not_ deleting %s", path_.c_str());
mu_debug("_not_ deleting {}", path_);
return;
}
/* ugly */
GError *err{};
const auto cmd{format("/bin/rm -rf '%s'", path_.c_str())};
const auto cmd{fmt::format("/bin/rm -rf '{}'", path_)};
if (!g_spawn_command_line_sync(cmd.c_str(), NULL, NULL, NULL, &err)) {
g_warning("error: %s\n", err ? err->message : "?");
mu_warning("error: {}", err ? err->message : "?");
g_clear_error(&err);
} else
g_debug("removed '%s'", path_.c_str());
mu_debug("removed '{}'", path_);
}

View File

@ -60,7 +60,7 @@ Mu::play (const std::string& path)
auto is_native = g_file_is_native(gf);
g_object_unref(gf);
if (!is_native)
return Err(Error::Code::File, "'%s' is not a native file", path.c_str());
return Err(Error::Code::File, "'{}' is not a native file", path);
const char *prog{g_getenv ("MU_PLAY_PROGRAM")};
if (!prog) {
@ -73,7 +73,7 @@ Mu::play (const std::string& path)
const auto program_path{program_in_path(prog)};
if (!program_path)
return Err(Error::Code::File, "cannot find '%s' in path", prog);
return Err(Error::Code::File, "cannot find '{}' in path", prog);
const gchar *argv[3]{};
argv[0] = program_path->c_str();
@ -83,9 +83,8 @@ Mu::play (const std::string& path)
GError *err{};
if (!g_spawn_async ({}, (gchar**)&argv, {}, G_SPAWN_SEARCH_PATH, maybe_setsid,
{}, {}, &err))
return Err(Error::Code::File, &err/*consumes*/, "failed to open '%s' with '%s'",
path. c_str(), program_path->c_str());
return Err(Error::Code::File, &err/*consumes*/,
"failed to open '{}' with '{}'", path, *program_path);
return Ok();
}
@ -117,8 +116,8 @@ Mu::determine_dtype (const std::string& path, bool use_lstat)
res = ::stat(path.c_str(), &statbuf);
if (res != 0) {
g_warning ("%sstat failed on %s: %s",
use_lstat ? "l" : "", path.c_str(), g_strerror(errno));
mu_warning ("{}stat failed on {}: {}",
use_lstat ? "l" : "", path, g_strerror(errno));
return DT_UNKNOWN;
}

View File

@ -347,8 +347,7 @@ Mu::time_to_string(const char *frm, time_t t, bool utc)
});
if (!dt) {
g_warning("time_t out of range: <%" G_GUINT64_FORMAT ">",
static_cast<guint64>(t));
mu_warning("time_t out of range: <{}>", t);
return {};
}
@ -356,7 +355,7 @@ Mu::time_to_string(const char *frm, time_t t, bool utc)
auto datestr{to_string_opt_gchar(g_date_time_format(dt, frm))};
g_date_time_unref(dt);
if (!datestr)
g_warning("failed to format time with format '%s'", frm);
mu_warning("failed to format time with format '{}'", frm);
return datestr.value_or("");
}
@ -692,7 +691,7 @@ __attribute__((format(printf, 2, 0)))
static bool
print_args (FILE *stream, const char *frm, va_list args)
{
gchar *str;
char *str;
gboolean rv;
str = g_strdup_vprintf (frm, args);

View File

@ -47,7 +47,12 @@
namespace Mu {
/*
* Logging functions connect libfmt with the Glib logging system
* Logging/printing/formatting functions connect libfmt with the Glib logging
* system. We wrap so perhaps at some point (C++23?) we can use std:: instead.
*/
/*
* Debug/error/warning logging
*/
template<typename...T>
@ -81,6 +86,35 @@ inline void mu_error(fmt::format_string<T...> frm, T&&... args) noexcept {
fmt::format(frm, std::forward<T>(args)...).c_str());
}
/*
* Printing
*/
template<typename...T>
inline void mu_print(fmt::format_string<T...> frm, T&&... args) noexcept {
fmt::print(frm, std::forward<T>(args)...);
}
template<typename...T>
inline void mu_println(fmt::format_string<T...> frm, T&&... args) noexcept {
fmt::println(frm, std::forward<T>(args)...);
}
template<typename...T>
inline void mu_printerr(fmt::format_string<T...> frm, T&&... args) noexcept {
fmt::print(stderr, frm, std::forward<T>(args)...);
}
template<typename...T>
inline void mu_printerrln(fmt::format_string<T...> frm, T&&... args) noexcept {
fmt::println(stderr, frm, std::forward<T>(args)...);
}
/*
* Fprmatting
*/
template<typename...T>
inline std::string mu_format(fmt::format_string<T...> frm, T&&... args) noexcept {
return fmt::format(frm, std::forward<T>(args)...);
}
using StringVec = std::vector<std::string>;
/**
@ -207,7 +241,6 @@ std::string date_to_time_t_string(int64_t t);
*/
std::string time_to_string(const char *frm, time_t t, bool utc = false) G_GNUC_CONST;
/**
* Hack to avoid locale crashes
*