From 4920b5667128a33eba6cca3b55a945cff0da3e8b Mon Sep 17 00:00:00 2001 From: "Dirk-Jan C. Binnema" Date: Wed, 5 Jul 2023 23:10:13 +0300 Subject: [PATCH] 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. --- guile/mu-guile-message.cc | 6 +-- guile/mu-guile.cc | 29 +++++------ guile/mu-guile.hh | 7 ++- lib/index/mu-indexer.cc | 75 +++++++++++++--------------- lib/index/mu-scanner.cc | 28 +++++------ lib/message/mu-document.cc | 6 +-- lib/message/mu-fields.cc | 5 +- lib/message/mu-message-file.cc | 14 +++--- lib/message/mu-message.cc | 63 ++++++++++++------------ lib/message/mu-mime-object.cc | 47 +++++++++--------- lib/message/mu-mime-object.hh | 3 +- lib/message/test-mu-message.cc | 2 +- lib/mu-contacts-cache.cc | 21 ++++---- lib/mu-maildir.cc | 63 +++++++++++------------- lib/mu-parser.cc | 2 +- lib/mu-query.cc | 6 +-- lib/mu-script.cc | 22 ++++----- lib/mu-server.cc | 87 ++++++++++++++------------------- lib/mu-store.cc | 26 +++++----- lib/mu-xapian-db.cc | 10 ++-- lib/mu-xapian-db.hh | 24 ++++----- lib/tests/bench-indexer.cc | 2 +- lib/tests/test-mu-msg.cc | 7 +-- lib/utils/meson.build | 2 - lib/utils/mu-command-handler.cc | 24 ++++----- lib/utils/mu-option.hh | 30 +++++++----- lib/utils/mu-result.hh | 14 +++--- lib/utils/mu-sexp.cc | 22 ++++----- lib/utils/mu-test-utils.cc | 8 +-- lib/utils/mu-utils-file.cc | 13 +++-- lib/utils/mu-utils.cc | 7 ++- lib/utils/mu-utils.hh | 37 +++++++++++++- meson.build | 1 + mu/mu-cmd-cfind.cc | 28 +++++------ mu/mu-cmd-extract.cc | 12 ++--- mu/mu-cmd-find.cc | 32 ++++++------ mu/mu-cmd-index.cc | 4 +- mu/mu-cmd-remove.cc | 3 +- mu/mu-cmd-script.cc | 2 +- mu/mu-cmd-server.cc | 24 +++++---- mu/mu-cmd-verify.cc | 14 +++--- mu/mu-cmd-view.cc | 11 ++--- mu/mu-cmd.cc | 20 ++++---- mu/mu-options.cc | 6 +-- mu/mu-options.hh | 1 - mu/tests/test-mu-query.cc | 14 +++--- 46 files changed, 435 insertions(+), 449 deletions(-) diff --git a/guile/mu-guile-message.cc b/guile/mu-guile-message.cc index 32f3717c..03342292 100644 --- a/guile/mu-guile-message.cc +++ b/guile/mu-guile-message.cc @@ -1,5 +1,5 @@ /* -** Copyright (C) 2011-2021 Dirk-Jan C. Binnema +** Copyright (C) 2011-2023 Dirk-Jan C. Binnema ** ** 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 @@ -16,17 +16,17 @@ ** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** */ +#include #include "mu-guile-message.hh" -#include #include "message/mu-message.hh" #include "utils/mu-utils.hh" -#include #include #include #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wredundant-decls" +#pragma GCC diagnostic ignored "-Wvolatile" #include #pragma GCC diagnostic pop diff --git a/guile/mu-guile.cc b/guile/mu-guile.cc index d311036c..44659aa0 100644 --- a/guile/mu-guile.cc +++ b/guile/mu-guile.cc @@ -1,5 +1,5 @@ /* -** Copyright (C) 2011-2022 Dirk-Jan C. Binnema +** Copyright (C) 2011-2023 Dirk-Jan C. Binnema ** ** 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 @@ -16,18 +16,13 @@ ** Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ** */ +#include #include "mu-guile.hh" -#include #include #include -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wredundant-decls" -#include -#pragma GCC diagnostic pop - #include #include @@ -81,30 +76,30 @@ mu_guile_init_instance(const std::string& muhome) try { const auto path{runtime_path(RuntimePath::XapianDb, muhome)}; auto store = Store::make(path); if (!store) { - g_critical("error creating store @ %s: %s", path.c_str(), - store.error().what()); + mu_critical("error creating store @ %s: %s", path, + store.error().what()); throw store.error(); } else StoreSingleton.emplace(std::move(store.value())); - g_debug("mu-guile: opened store @ %s (n=%zu); maildir: %s", - StoreSingleton->path().c_str(), + mu_debug("mu-guile: opened store @ {} (n={}); maildir: {}", + StoreSingleton->path(), StoreSingleton->size(), - StoreSingleton->root_maildir().c_str()); + StoreSingleton->root_maildir()); return true; } catch (const Xapian::Error& xerr) { - g_critical("%s: xapian error '%s'", __func__, xerr.get_msg().c_str()); + mu_critical("{}: xapian error '{}'", __func__, xerr.get_msg()); return false; } catch (const std::runtime_error& re) { - g_critical("%s: error: %s", __func__, re.what()); + mu_critical("{}: error: {}", __func__, re.what()); return false; } catch (const std::exception& e) { - g_critical("%s: caught exception: %s", __func__, e.what()); + mu_critical("{}: caught exception: {}", __func__, e.what()); return false; } catch (...) { - g_critical("%s: caught exception", __func__); + mu_critical("{}: caught exception", __func__); return false; } @@ -118,7 +113,7 @@ Mu::Store& mu_guile_store() { if (!StoreSingleton) - g_error("mu guile not initialized"); + mu_error("mu guile not initialized"); return StoreSingleton.value(); } diff --git a/guile/mu-guile.hh b/guile/mu-guile.hh index 6265995e..579857de 100644 --- a/guile/mu-guile.hh +++ b/guile/mu-guile.hh @@ -21,9 +21,14 @@ #define __MU_GUILE_H__ #include -#include #include +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wredundant-decls" +#pragma GCC diagnostic ignored "-Wvolatile" +#include +#pragma GCC diagnostic pop + /** * get the singleton Store instance */ diff --git a/lib/index/mu-indexer.cc b/lib/index/mu-indexer.cc index 756fcda5..2b56b3f4 100644 --- a/lib/index/mu-indexer.cc +++ b/lib/index/mu-indexer.cc @@ -67,7 +67,7 @@ struct IndexState { return state_.load() != rhs; } void change_to(State new_state) { - g_debug("changing indexer state %s->%s", name((State)state_), + mu_debug("changing indexer state {}->{}", name((State)state_), name((State)new_state)); state_.store(new_state); } @@ -84,9 +84,9 @@ struct Indexer::Private { return handler(path, statbuf, info); }}, max_message_size_{store_.config().get()} { - g_message("created indexer for %s -> %s (batch-size: %zu)", - store.root_maildir().c_str(), - store.path().c_str(), store.config().get()); + mu_message("created indexer for {} -> {} (batch-size: {})", + store.root_maildir(), store.path(), + store.config().get()); } ~Private() { @@ -148,16 +148,16 @@ Indexer::Private::handler(const std::string& fullpath, struct stat* statbuf, dirstamp_ = store_.dirstamp(fullpath); if (conf_.lazy_check && dirstamp_ >= statbuf->st_ctime && htype == Scanner::HandleType::EnterNewCur) { - g_debug("skip %s (seems up-to-date: %s >= %s)", fullpath.c_str(), - time_to_string("%FT%T", dirstamp_).c_str(), - time_to_string("%FT%T", statbuf->st_ctime).c_str()); + mu_debug("skip {} (seems up-to-date: {} >= {})", fullpath, + time_to_string("%FT%T", dirstamp_), + time_to_string("%FT%T", statbuf->st_ctime)); return false; } // don't index dirs with '.noindex' auto noindex = ::access((fullpath + "/.noindex").c_str(), F_OK) == 0; if (noindex) { - g_debug("skip %s (has .noindex)", fullpath.c_str()); + mu_debug("skip {} (has .noindex)", fullpath); return false; // don't descend into this dir. } @@ -166,12 +166,12 @@ Indexer::Private::handler(const std::string& fullpath, struct stat* statbuf, if (!conf_.ignore_noupdate) { auto noupdate = ::access((fullpath + "/.noupdate").c_str(), F_OK) == 0; if (noupdate) { - g_debug("skip %s (has .noupdate)", fullpath.c_str()); + mu_debug("skip {} (has .noupdate)", fullpath); return false; } } - g_debug("checked %s", fullpath.c_str()); + mu_debug("checked {}", fullpath); return true; } case Scanner::HandleType::LeaveDir: { @@ -183,17 +183,14 @@ Indexer::Private::handler(const std::string& fullpath, struct stat* statbuf, ++progress_.checked; if ((size_t)statbuf->st_size > max_message_size_) { - g_debug("skip %s (too big: %" G_GINT64_FORMAT " bytes)", fullpath.c_str(), - (gint64)statbuf->st_size); + mu_debug("skip {} (too big: {} bytes)", fullpath, statbuf->st_size); return false; } // if the message is not in the db yet, or not up-to-date, queue // it for updating/inserting. - if (statbuf->st_ctime <= dirstamp_ && store_.contains_message(fullpath)) { - // g_debug ("skip %s: already up-to-date"); + if (statbuf->st_ctime <= dirstamp_ && store_.contains_message(fullpath)) return false; - } // push the remaining messages to our "todo" queue for // (re)parsing and adding/updating to the database. @@ -213,7 +210,7 @@ Indexer::Private::maybe_start_worker() if (todos_.size() > workers_.size() && workers_.size() < max_workers_) { workers_.emplace_back(std::thread([this] { item_worker(); })); - g_debug("added worker %zu", workers_.size()); + mu_debug("added worker {}", workers_.size()); } } @@ -231,14 +228,12 @@ Indexer::Private::add_message(const std::string& path) */ auto msg{Message::make_from_path(path)}; if (!msg) { - g_warning("failed to create message from %s: %s", - path.c_str(), msg.error().what()); + mu_warning("failed to create message from {}: {}", path, msg.error().what()); return false; } auto res = store_.add_message(msg.value(), true /*use-transaction*/); if (!res) { - g_warning("failed to add message @ %s: %s", - path.c_str(), res.error().what()); + mu_warning("failed to add message @ {}: {}", path, res.error().what()); return false; } @@ -250,7 +245,7 @@ Indexer::Private::item_worker() { WorkItem item; - g_debug("started worker"); + mu_debug("started worker"); while (state_ == IndexState::Scanning) { if (!todos_.pop(item, 250ms)) @@ -269,8 +264,7 @@ Indexer::Private::item_worker() break; } } catch (const Mu::Error& er) { - g_warning("error adding message @ %s: %s", - item.full_path.c_str(), er.what()); + mu_warning("error adding message @ {}: {}", item.full_path, er.what()); } maybe_start_worker(); @@ -281,15 +275,15 @@ Indexer::Private::item_worker() bool Indexer::Private::cleanup() { - g_debug("starting cleanup"); + mu_debug("starting cleanup"); size_t n{}; std::vector orphans; // store messages without files. store_.for_each_message_path([&](Store::Id id, const std::string& path) { ++n; if (::access(path.c_str(), R_OK) != 0) { - g_debug("cannot read %s (id=%u); queueing for removal from store", - path.c_str(), id); + mu_debug("cannot read {} (id={}); queuing for removal from store", + path, id); orphans.emplace_back(id); } @@ -297,9 +291,9 @@ Indexer::Private::cleanup() }); if (orphans.empty()) - g_debug("nothing to clean up"); + mu_debug("nothing to clean up"); else { - g_debug("removing up %zu stale message(s) from store", orphans.size()); + mu_debug("removing {} stale message(s) from store", orphans.size()); store_.remove_messages(orphans); progress_.removed += orphans.size(); } @@ -313,13 +307,13 @@ Indexer::Private::scan_worker() progress_.reset(); if (conf_.scan) { - g_debug("starting scanner"); + mu_debug("starting scanner"); if (!scanner_.start()) { // blocks. - g_warning("failed to start scanner"); + mu_warning("failed to start scanner"); state_.change_to(IndexState::Idle); return; } - g_debug("scanner finished with %zu file(s) in queue", todos_.size()); + mu_debug("scanner finished with {} file(s) in queue", todos_.size()); } // now there may still be messages in the work queue... @@ -331,7 +325,7 @@ Indexer::Private::scan_worker() std::lock_guard lock{w_lock_}; return workers_.size(); }); - g_debug("process %zu remaining message(s) with %zu worker(s)", + mu_debug("process {} remaining message(s) with {} worker(s)", todos_.size(), workers_size); while (!todos_.empty()) std::this_thread::sleep_for(100ms); @@ -343,11 +337,10 @@ Indexer::Private::scan_worker() w.join(); if (conf_.cleanup) { - g_debug("starting cleanup"); - + mu_debug("starting cleanup"); state_.change_to(IndexState::Cleaning); cleanup(); - g_debug("cleanup finished"); + mu_debug("cleanup finished"); } completed_ = ::time({}); @@ -369,9 +362,9 @@ Indexer::Private::start(const Indexer::Config& conf) } else max_workers_ = conf.max_threads; - g_debug("starting indexer with <= %zu worker thread(s)", max_workers_); - g_debug("indexing: %s; clean-up: %s", conf_.scan ? "yes" : "no", - conf_.cleanup ? "yes" : "no"); + mu_debug("starting indexer with <= {} worker thread(s)", max_workers_); + mu_debug("indexing: {}; clean-up: {}", conf_.scan ? "yes" : "no", + conf_.cleanup ? "yes" : "no"); state_.change_to(IndexState::Scanning); /* kick off the first worker, which will spawn more if needed. */ @@ -379,7 +372,7 @@ Indexer::Private::start(const Indexer::Config& conf) /* kick the disk-scanner thread */ scanner_worker_ = std::thread([this] { scan_worker(); }); - g_debug("started indexer"); + mu_debug("started indexer"); return true; } @@ -413,7 +406,7 @@ Indexer::start(const Indexer::Config& conf) { const auto mdir{priv_->store_.root_maildir()}; if (G_UNLIKELY(access(mdir.c_str(), R_OK) != 0)) { - g_critical("'%s' is not readable: %s", mdir.c_str(), g_strerror(errno)); + mu_critical("'{}' is not readable: {}", mdir, g_strerror(errno)); return false; } @@ -432,7 +425,7 @@ Indexer::stop() if (!is_running()) return true; - g_debug("stopping indexer"); + mu_debug("stopping indexer"); return priv_->stop(); } diff --git a/lib/index/mu-scanner.cc b/lib/index/mu-scanner.cc index 30157c0d..5072eb9b 100644 --- a/lib/index/mu-scanner.cc +++ b/lib/index/mu-scanner.cc @@ -96,14 +96,14 @@ Scanner::Private::process_dentry(const std::string& path, struct dirent *dentry, if (is_dotdir(d_name) || std::strcmp(d_name, "tmp") == 0) return true; // ignore. if (do_ignore(d_name)) { - g_debug("skip %s/%s (ignore)", path.c_str(), d_name); + mu_debug("skip {}/{} (ignore)", path, d_name); return true; // ignore } const auto fullpath{join_paths(path, d_name)}; struct stat statbuf {}; if (::stat(fullpath.c_str(), &statbuf) != 0) { - g_warning("failed to stat %s: %s", fullpath.c_str(), g_strerror(errno)); + mu_warning("failed to stat {}: {}", fullpath, g_strerror(errno)); return false; } @@ -123,7 +123,7 @@ Scanner::Private::process_dentry(const std::string& path, struct dirent *dentry, } else if (S_ISREG(statbuf.st_mode) && is_maildir) return handler_(fullpath, &statbuf, Scanner::HandleType::File); - g_debug("skip %s (neither maildir-file nor directory)", fullpath.c_str()); + mu_debug("skip {} (neither maildir-file nor directory)", fullpath); return true; } @@ -136,7 +136,7 @@ Scanner::Private::process_dir(const std::string& path, bool is_maildir) const auto dir = opendir(path.c_str()); if (G_UNLIKELY(!dir)) { - g_warning("failed to scan dir %s: %s", path.c_str(), g_strerror(errno)); + mu_warning("failed to scan dir {}: {}", path, g_strerror(errno)); return false; } @@ -153,7 +153,7 @@ Scanner::Private::process_dir(const std::string& path, bool is_maildir) } if (errno != 0) { - g_warning("failed to read %s: %s", path.c_str(), g_strerror(errno)); + mu_warning("failed to read {}: {}", path, g_strerror(errno)); continue; } @@ -169,30 +169,29 @@ Scanner::Private::start() { const auto& path{root_dir_}; if (G_UNLIKELY(path.length() > PATH_MAX)) { - g_warning("path too long"); + mu_warning("path too long"); return false; } const auto mode{F_OK | R_OK}; if (G_UNLIKELY(access(path.c_str(), mode) != 0)) { - g_warning("'%s' is not readable: %s", path.c_str(), g_strerror(errno)); + mu_warning("'{}' is not readable: {}", path, g_strerror(errno)); return false; } - struct stat statbuf { - }; + struct stat statbuf {}; if (G_UNLIKELY(stat(path.c_str(), &statbuf) != 0)) { - g_warning("'%s' is not stat'able: %s", path.c_str(), g_strerror(errno)); + mu_warning("'{}' is not stat'able: {}", path, g_strerror(errno)); return false; } if (G_UNLIKELY(!S_ISDIR(statbuf.st_mode))) { - g_warning("'%s' is not a directory", path.c_str()); + mu_warning("'{}' is not a directory", path); return false; } running_ = true; - g_debug("starting scan @ %s", root_dir_.c_str()); + mu_debug("starting scan @ {}", root_dir_); auto basename{g_path_get_basename(root_dir_.c_str())}; const auto is_maildir = @@ -202,8 +201,7 @@ Scanner::Private::start() const auto start{std::chrono::steady_clock::now()}; process_dir(root_dir_, is_maildir); const auto elapsed = std::chrono::steady_clock::now() - start; - g_debug("finished scan of %s in %" G_GINT64_FORMAT " ms", root_dir_.c_str(), - to_ms(elapsed)); + mu_debug("finished scan of {} in {} ms", root_dir_, to_ms(elapsed)); running_ = false; return true; @@ -215,7 +213,7 @@ Scanner::Private::stop() if (!running_) return true; // nothing to do - g_debug("stopping scan"); + mu_debug("stopping scan"); running_ = false; return true; diff --git a/lib/message/mu-document.cc b/lib/message/mu-document.cc index ee366c3e..0d93bb45 100644 --- a/lib/message/mu-document.cc +++ b/lib/message/mu-document.cc @@ -208,7 +208,7 @@ Document::contacts_value(Field::Id id) const noexcept const auto ctype{contact_type_from_field_id(id)}; if (G_UNLIKELY(!ctype)) { - g_critical("invalid field-id for contact-type: <%zu>", + mu_critical("invalid field-id for contact-type: <{}>", static_cast(id)); return {}; } @@ -217,7 +217,7 @@ Document::contacts_value(Field::Id id) const noexcept const auto pos = s.find(SepaChar2); if (G_UNLIKELY(pos == std::string::npos)) { - g_critical("invalid contact data '%s'", s.c_str()); + mu_critical("invalid contact data '{}'", s); break; } @@ -348,7 +348,7 @@ Document::remove(Field::Id field_id) try { xdoc_.remove_term(term); } catch(const Xapian::InvalidArgumentError& xe) { - g_critical("failed to remove '%s'", term.c_str()); + mu_critical("failed to remove '{}'", term); } } }); diff --git a/lib/message/mu-fields.cc b/lib/message/mu-fields.cc index d5ce4d23..8515636e 100644 --- a/lib/message/mu-fields.cc +++ b/lib/message/mu-fields.cc @@ -77,8 +77,7 @@ validate_field_shortcuts() #ifdef BUILD_TESTS if (shortcut != 0) { if (++no_dups[static_cast(shortcut-'a')] > 1) { - g_critical("shortcut '%c' is duplicated", - shortcut); + mu_critical("shortcut '{}' is duplicated", shortcut); return false; } } @@ -105,7 +104,7 @@ validate_field_flags() ++flagnum; if (flagnum > 1) { - //g_warning("invalid field %*.s", STR_V(field.name)); + //mu_warning("invalid field {}", field.name); return false; } } diff --git a/lib/message/mu-message-file.cc b/lib/message/mu-message-file.cc index b9ac2163..15e12cf8 100644 --- a/lib/message/mu-message-file.cc +++ b/lib/message/mu-message-file.cc @@ -27,21 +27,19 @@ Mu::maildir_from_path(const std::string& path, const std::string& root) const auto pos = path.find(root); if (pos != 0 || path[root.length()] != '/') return Err(Error{Error::Code::InvalidArgument, - "root '%s' is not a root for path '%s'", - root.c_str(), path.c_str()}); + "root '{}' is not a root for path '{}'", root, path}); auto mdir{path.substr(root.length())}; auto slash{mdir.rfind('/')}; if (G_UNLIKELY(slash == std::string::npos) || slash < 4) return Err(Error{Error::Code::InvalidArgument, - "invalid path: %s", path.c_str()}); + "invalid path: {}", path}); mdir.erase(slash); auto subdir = mdir.data() + slash - 4; if (G_UNLIKELY(strncmp(subdir, "/cur", 4) != 0 && strncmp(subdir, "/new", 4))) return Err(Error::Code::InvalidArgument, - "cannot find '/new' or '/cur' - invalid path: %s", - path.c_str()); + "cannot find '/new' or '/cur' - invalid path: {}", path); if (mdir.length() == 4) return "/"; @@ -109,7 +107,7 @@ Mu::flags_from_path(const std::string& path) if (!flags) { /* LCOV_EXCL_START*/ return Err(Error{Error::Code::InvalidArgument, - "invalid flags ('%s')", parts.flags_suffix.c_str()}); + "invalid flags ('{}')", parts.flags_suffix}); /* LCOV_EXCL_STOP*/ } @@ -182,8 +180,8 @@ test_flags_from_path() assert_valid_result(res); /* LCOV_EXCL_START*/ if (g_test_verbose()) { - g_print("%s -> <%s>\n", tcase.first.c_str(), - to_string(res.value()).c_str()); + mu_println("{} -> <{}>", tcase.first, + to_string(res.value())); g_assert_true(res.value() == tcase.second); } /*LCOV_EXCL_STOP*/ diff --git a/lib/message/mu-message.cc b/lib/message/mu-message.cc index 06335f9d..cbbbbdf3 100644 --- a/lib/message/mu-message.cc +++ b/lib/message/mu-message.cc @@ -80,20 +80,18 @@ get_statbuf(const std::string& path, Message::Options opts = Message::Options::N { if (none_of(opts & Message::Options::AllowRelativePath) && !g_path_is_absolute(path.c_str())) - return Err(Error::Code::File, "path '%s' is not absolute", - path.c_str()); + return Err(Error::Code::File, "path '{}' is not absolute", path); if (::access(path.c_str(), R_OK) != 0) - return Err(Error::Code::File, "file @ '%s' is not readable", - path.c_str()); + return Err(Error::Code::File, "file @ '{}' is not readable", path); struct stat statbuf{}; if (::stat(path.c_str(), &statbuf) < 0) - return Err(Error::Code::File, "cannot stat %s: %s", path.c_str(), - g_strerror(errno)); + return Err(Error::Code::File, "cannot stat {}: {}", path, + g_strerror(errno)); if (!S_ISREG(statbuf.st_mode)) - return Err(Error::Code::File, "not a regular file: %s", path.c_str()); + return Err(Error::Code::File, "not a regular file: {}", path); return Ok(std::move(statbuf)); } @@ -200,13 +198,13 @@ Message::set_maildir(const std::string& maildir) maildir.at(0) != '/' || (maildir.size() > 1 && maildir.at(maildir.length()-1) == '/')) return Err(Error::Code::Message, - "'%s' is not a valid maildir", maildir.c_str()); + "'{}' is not a valid maildir", maildir.c_str()); const auto path{document().string_value(Field::Id::Path)}; if (path == maildir || path.find(maildir) == std::string::npos) return Err(Error::Code::Message, - "'%s' is not a valid maildir for message @ %s", - maildir.c_str(), path.c_str()); + "'{}' is not a valid maildir for message @ {}", + maildir, path); priv_->doc.remove(Field::Id::Maildir); priv_->doc.add(Field::Id::Maildir, maildir); @@ -229,8 +227,8 @@ Message::load_mime_message(bool reload) const const auto path{document().string_value(Field::Id::Path)}; if (auto mime_msg{MimeMessage::make_from_file(path)}; !mime_msg) { - g_warning("failed to load '%s': %s", - path.c_str(), mime_msg.error().what()); + mu_warning("failed to load '{}': {}", + path, mime_msg.error().what()); return false; } else { priv_->mime_msg = std::move(mime_msg.value()); @@ -258,17 +256,17 @@ get_priority(const MimeMessage& mime_msg) constexpr std::array, 10> prio_alist = {{ {"high", Priority::High}, - {"1", Priority::High}, - {"2", Priority::High}, + {"1", Priority::High}, + {"2", Priority::High}, {"normal", Priority::Normal}, - {"3", Priority::Normal}, + {"3", Priority::Normal}, - {"low", Priority::Low}, + {"low", Priority::Low}, {"list", Priority::Low}, {"bulk", Priority::Low}, - {"4", Priority::Low}, - {"5", Priority::Low} + {"4", Priority::Low}, + {"5", Priority::Low} }}; const auto opt_str = mime_msg.header("Precedence") @@ -440,14 +438,13 @@ handle_encrypted(const MimeMultipartEncrypted& part, Message::Private& info) const auto proto{part.content_type_parameter("protocol").value_or("unknown")}; const auto ctx = MimeCryptoContext::make(proto); if (!ctx) { - g_warning("failed to create context for protocol <%s>", - proto.c_str()); + mu_warning("failed to create context for protocol <{}>", proto); return; } auto res{part.decrypt(*ctx)}; if (!res) { - g_warning("failed to decrypt: %s", res.error().what()); + mu_warning("failed to decrypt: {}", res.error().what()); return; } @@ -538,9 +535,9 @@ process_message(const MimeMessage& mime_msg, const std::string& path, if (info.body_txt) { /* attempt to get the body-language */ if (const auto lang{detect_language(info.body_txt.value())}; lang) { info.language = lang->code; - g_debug("detected language: %s", lang->code); + mu_debug("detected language: {}", lang->code); } else - g_debug("could not detect language"); + mu_debug("could not detect language"); } } @@ -551,8 +548,8 @@ calculate_sha256(const std::string& path) FILE *file{::fopen(path.c_str(), "r")}; if (!file) - return Err(Error{Error::Code::File, "failed to open %s: %s", - path.c_str(), ::strerror(errno)}); + return Err(Error{Error::Code::File, "failed to open {}: {}", + path, ::strerror(errno)}); std::array buf{}; while (true) { @@ -566,7 +563,7 @@ calculate_sha256(const std::string& path) ::fclose(file); if (has_err) - return Err(Error{Error::Code::File, "failed to read %s", path.c_str()}); + return Err(Error{Error::Code::File, "failed to read {}", path}); return Ok(g_checksum_get_string(checksum)); } @@ -585,18 +582,19 @@ fake_message_id(const std::string& path) // not a very good message-id, only for testing. if (path.empty() || ::access(path.c_str(), R_OK) != 0) - return format("%08x%s", g_str_hash(path.c_str()), mu_suffix); + return mu_format("{:08x}{}", g_str_hash(path.c_str()), mu_suffix); if (const auto sha256_res{calculate_sha256(path)}; !sha256_res) - return format("%08x%s", g_str_hash(path.c_str()), mu_suffix); + return mu_format("{:08x}{}", g_str_hash(path.c_str()), mu_suffix); else - return format("%s%s", sha256_res.value().c_str(), mu_suffix); + return mu_format("{}{}", sha256_res.value(), mu_suffix); } -/* many of the doc.add(fiels ....) automatically update the sexp-list as well; +/* many of the doc.add(fields ....) automatically update the sexp-list as well; * however, there are some _extra_ values in the sexp-list that are not * based on a field. So we add them here. */ + static void doc_add_list_post(Document& doc, const MimeMessage& mime_msg) { @@ -797,11 +795,10 @@ Message::cache_path(Option index) const if (index) { GError *err{}; - auto tpath = format("%s/%zu", priv_->cache_path.c_str(), *index); + auto tpath = mu_format("{}/{}", priv_->cache_path, *index); if (g_mkdir(tpath.c_str(), 0700) != 0) return Err(Error::Code::File, &err, - "failed to create cache dir '%s'; err=%d", - tpath.c_str(), errno); + "failed to create cache dir '{}'; err={}", tpath, errno); return Ok(std::move(tpath)); } else diff --git a/lib/message/mu-mime-object.cc b/lib/message/mu-mime-object.cc index c1cc8e56..f7cf3736 100644 --- a/lib/message/mu-mime-object.cc +++ b/lib/message/mu-mime-object.cc @@ -49,7 +49,7 @@ Mu::init_gmime(void) if (gmime_initialized) return; // already - g_debug("initializing gmime %u.%u.%u", + mu_debug("initializing gmime {}.{}.{}", gmime_major_version, gmime_minor_version, gmime_micro_version); @@ -58,7 +58,7 @@ Mu::init_gmime(void) gmime_initialized = true; std::atexit([] { - g_debug("shutting down gmime"); + mu_debug("shutting down gmime"); g_mime_shutdown(); gmime_initialized = false; }); @@ -146,7 +146,7 @@ MimeObject::to_file(const std::string& path, bool overwrite) const noexcept S_IRUSR|S_IWUSR, &err)}; if (!strm) - return Err(Error::Code::File, &err, "failed to open '%s'", path.c_str()); + return Err(Error::Code::File, &err, "failed to open '{}'", path); MimeStream stream{MimeStream::make_from_stream(strm)}; return write_to_stream({}, stream); @@ -158,14 +158,14 @@ MimeObject::to_string_opt() const noexcept { auto stream{MimeStream::make_mem()}; if (!stream) { - g_warning("failed to create mem stream"); + mu_warning("failed to create mem stream"); return Nothing; } const auto written = g_mime_object_write_to_stream( self(), {}, GMIME_STREAM(stream.object())); if (written < 0) { - g_warning("failed to write object to stream"); + mu_warning("failed to write object to stream"); return Nothing; } @@ -246,16 +246,15 @@ MimeCryptoContext::setup_gpg_test(const std::string& testpath) if (g_mkdir_with_parents((testpath + "/.gnupg").c_str(), 0700) != 0) return Err(Error::Code::File, - "failed to create gnupg dir; err=%d", errno); + "failed to create gnupg dir; err={}", errno); auto write_gpgfile=[&](const std::string& fname, const std::string& data) -> Result { GError *err{}; - std::string path{format("%s/%s", testpath.c_str(), fname.c_str())}; + std::string path{mu_format("{}/{}", testpath, fname)}; if (!g_file_set_contents(path.c_str(), data.c_str(), data.size(), &err)) - return Err(Error::Code::File, &err, - "failed to write %s", path.c_str()); + return Err(Error::Code::File, &err, "failed to write {}", path); else return Ok(); }; @@ -303,7 +302,7 @@ MimeMessage::make_from_file(const std::string& path) init_gmime(); if (auto&& stream{g_mime_stream_file_open(path.c_str(), "r", &err)}; !stream) return Err(Error::Code::Message, &err, - "failed to open stream for %s", path.c_str()); + "failed to open stream for {}", path); else return make_from_stream(std::move(stream)); } @@ -480,13 +479,13 @@ MimePart::size() const noexcept { auto wrapper{g_mime_part_get_content(self())}; if (!wrapper) { - g_warning("failed to get content wrapper"); + mu_warning("failed to get content wrapper"); return 0; } auto stream{g_mime_data_wrapper_get_stream(wrapper)}; if (!stream) { - g_warning("failed to get stream"); + mu_warning("failed to get stream"); return 0; } @@ -510,13 +509,13 @@ MimePart::to_string() const noexcept */ GMimeDataWrapper *wrapper{g_mime_part_get_content(self())}; if (!wrapper) { /* this happens with invalid mails */ - g_debug("failed to create data wrapper"); + mu_warning("failed to create data wrapper"); return Nothing; } GMimeStream *stream{g_mime_stream_mem_new()}; if (!stream) { - g_warning("failed to create mem stream"); + mu_warning("failed to create mem stream"); return Nothing; } @@ -554,7 +553,7 @@ MimePart::to_file(const std::string& path, bool overwrite) const noexcept S_IRUSR|S_IWUSR, &err)}; if (!strm) - return Err(Error::Code::File, &err, "failed to open '%s'", path.c_str()); + return Err(Error::Code::File, &err, "failed to open '{}'", path); MimeStream stream{MimeStream::make_from_stream(strm)}; ssize_t written{g_mime_data_wrapper_write_to_stream( @@ -563,7 +562,7 @@ MimePart::to_file(const std::string& path, bool overwrite) const noexcept if (written < 0) { return Err(Error::Code::File, &err, - "failed to write to '%s'", path.c_str()); + "failed to write to '{}'", path); } return Ok(static_cast(written)); @@ -635,7 +634,7 @@ MimeMultipartSigned::verify(const MimeCryptoContext& ctx, VerifyFlags vflags) co const auto sign_proto{ctx.signature_protocol()}; if (!proto || !sign_proto || !mime_types_equal(*proto, *sign_proto)) - return Err(Error::Code::Crypto, "unsupported protocol " + + return Err(Error::Code::Crypto, "unsupported protocol {}", proto.value_or("")); const auto sig{signed_signature_part()}; @@ -734,7 +733,7 @@ MimeMultipartEncrypted::decrypt(const MimeCryptoContext& ctx, DecryptFlags dflag const auto enc_proto{ctx.encryption_protocol()}; if (!proto || !enc_proto || !mime_types_equal(*proto, *enc_proto)) - return Err(Error::Code::Crypto, "unsupported protocol " + + return Err(Error::Code::Crypto, "unsupported protocol {}", proto.value_or("")); const auto version{encrypted_version_part()}; @@ -744,14 +743,14 @@ MimeMultipartEncrypted::decrypt(const MimeCryptoContext& ctx, DecryptFlags dflag if (!mime_types_equal(version->mime_type().value_or(""), proto.value())) return Err(Error::Code::Crypto, - "cannot decrypt; unexpected version content-type '%s' != '%s'", - version->mime_type().value_or("").c_str(), - proto.value().c_str()); + "cannot decrypt; unexpected version content-type '{}' != '{}'", + version->mime_type().value_or(""), proto.value()); - if (!mime_types_equal(encrypted->mime_type().value_or(""), "application/octet-stream")) + if (!mime_types_equal(encrypted->mime_type().value_or(""), + "application/octet-stream")) return Err(Error::Code::Crypto, - "cannot decrypt; unexpected encrypted content-type '%s'", - encrypted->mime_type().value_or("").c_str()); + "cannot decrypt; unexpected encrypted content-type '{}'", + encrypted->mime_type().value_or("")); const auto content{encrypted->content()}; auto ciphertext{MimeStream::make_mem()}; diff --git a/lib/message/mu-mime-object.hh b/lib/message/mu-mime-object.hh index d89c4b4d..bfb2867f 100644 --- a/lib/message/mu-mime-object.hh +++ b/lib/message/mu-mime-object.hh @@ -674,7 +674,8 @@ struct MimeCryptoContext : public Object { make(const std::string& protocol) { auto ctx = g_mime_crypto_context_new(protocol.c_str()); if (!ctx) - return Err(Error::Code::Crypto, "unsupported protocol " + protocol); + return Err(Error::Code::Crypto, + "unsupported protocol {}", protocol); MimeCryptoContext mctx{ctx}; mctx.unref(); /* remove extra ref */ return Ok(std::move(mctx)); diff --git a/lib/message/test-mu-message.cc b/lib/message/test-mu-message.cc index 22eeca5e..d9432978 100644 --- a/lib/message/test-mu-message.cc +++ b/lib/message/test-mu-message.cc @@ -369,7 +369,7 @@ Q46aYjxe0As6AP90bcAZ3dcn5RcTJaM0UhZssguawZ+tnriD3+5DPkMMCg== const auto mpart{MimeMultipartSigned(mobj)}; const auto sigs{mpart.verify(*ctx)}; if (!sigs) - g_warning("%s", sigs.error().what()); + mu_warning("{}", sigs.error().what()); g_assert_true(!!sigs); g_assert_cmpuint(sigs->size(), ==, 1); diff --git a/lib/mu-contacts-cache.cc b/lib/mu-contacts-cache.cc index 61bbb2be..3f48778d 100644 --- a/lib/mu-contacts-cache.cc +++ b/lib/mu-contacts-cache.cc @@ -114,9 +114,8 @@ private: throw rx.error(); rxvec.emplace_back(rx.value()); } catch (const Error& rex) { - g_warning("invalid personal address regexp '%s': %s", - p.c_str(), - rex.what()); + mu_warning("invalid personal address regexp '{}': {}", + p, rex.what()); } } return rxvec; @@ -136,7 +135,7 @@ ContactsCache::Private::deserialize(const std::string& serialized) const while (getline(ss, line)) { const auto parts = Mu::split(line, Separator); if (G_UNLIKELY(parts.size() != 5)) { - g_warning("error: '%s'", line.c_str()); + mu_warning("error: '{}'", line); continue; } Contact ci(parts[0], // email @@ -157,7 +156,7 @@ ContactsCache::Private::serialize() const { if (config_db_.read_only()) { if (dirty_ > 0) - g_critical("dirty data in read-only ccache!"); // bug + mu_critical("dirty data in read-only ccache!"); // bug return; } @@ -209,7 +208,7 @@ ContactsCache::add(Contact&& contact) /* we do _not_ cache invalid email addresses, so we won't offer them in completions etc. It * should be _rare_, but we've seen cases ( broken local messages) */ if (!contact.has_valid_email()) { - g_warning("not caching invalid e-mail address '%s'", contact.email.c_str()); + mu_warning("not caching invalid e-mail address '{}'", contact.email); return; } @@ -234,7 +233,7 @@ ContactsCache::add(Contact&& contact) auto email{contact.email}; // return priv_->contacts_.emplace(ContactUMap::value_type(email, std::move(contact))) // .first->second; - g_debug("adding contact %s <%s>", contact.name.c_str(), contact.email.c_str()); + mu_debug("adding contact {} <{}>", contact.name.c_str(), contact.email.c_str()); priv_->contacts_.emplace(ContactUMap::value_type(email, std::move(contact))); } else { // existing contact. @@ -248,8 +247,8 @@ ContactsCache::add(Contact&& contact) existing.tstamp = g_get_monotonic_time(); existing.message_date = contact.message_date; } - g_debug("updating contact %s <%s> (%zu)", - contact.name.c_str(), contact.email.c_str(), existing.frequency); + mu_debug("updating contact {} <{}> ({})", + contact.name, contact.email, existing.frequency); } } @@ -528,11 +527,11 @@ test_mu_contacts_cache_sort() auto result_chars = [](const Mu::ContactsCache& ccache)->std::string { std::string str; if (g_test_verbose()) - g_print("contacts-cache:\n"); + fmt::print("contacts-cache:\n"); ccache.for_each([&](auto&& contact) { if (g_test_verbose()) - g_print("\t- %s\n", contact.display_name().c_str()); + fmt::print("\t- {}\n", contact.display_name()); str += contact.name; return true; }); diff --git a/lib/mu-maildir.cc b/lib/mu-maildir.cc index ca2546ac..c916e395 100644 --- a/lib/mu-maildir.cc +++ b/lib/mu-maildir.cc @@ -88,8 +88,8 @@ create_maildir(const std::string& path, mode_t mode) * permissions; so we need to check */ if (rv != 0 || !check_dir(fullpath, true/*readable*/, true/*writable*/)) return Err(Error{Error::Code::File, - "creating dir failed for %s: %s", - fullpath.c_str(), g_strerror(errno)}); + "creating dir failed for {}: {}", + fullpath, g_strerror(errno)}); } return Ok(); @@ -104,7 +104,7 @@ create_noindex(const std::string& path) int fd = ::creat(noindexpath.c_str(), 0644); if (fd < 0 || ::close(fd) != 0) return Err(Error{Error::Code::File, - "error creating .noindex: %s", g_strerror(errno)}); + "error creating .noindex: {}", g_strerror(errno)}); else return Ok(); } @@ -141,8 +141,7 @@ check_subdir(const std::string& src, bool& in_cur) g_free(srcpath); if (invalid) - return Err(Error{Error::Code::File, "invalid source message '%s'", - src.c_str()}); + return Err(Error{Error::Code::File, "invalid source message '{}'", src}); else return Ok(); } @@ -186,10 +185,8 @@ Mu::maildir_link(const std::string& src, const std::string& targetpath, auto rv{::symlink(src.c_str(), path_res->c_str())}; if (rv != 0) return Err(Error{Error::Code::File, - "error creating link %s => %s: %s", - path_res->c_str(), - src.c_str(), - g_strerror(errno)}); + "error creating link {} => {}: {}", + *path_res, src, g_strerror(errno)}); return Ok(); } @@ -209,19 +206,20 @@ clear_links(const std::string& path, DIR* dir) continue; /* ignore .,.. other dotdirs */ const auto fullpath{join_paths(path, dentry->d_name)}; - const auto d_type = get_dtype(dentry, fullpath.c_str(), true/*lstat*/); + const auto d_type = get_dtype(dentry, fullpath.c_str(), + true/*lstat*/); switch(d_type) { case DT_LNK: if (::unlink(fullpath.c_str()) != 0) { - g_warning("error unlinking %s: %s", - fullpath.c_str(), g_strerror(errno)); + mu_warning("error unlinking {}: {}", + fullpath, g_strerror(errno)); res = false; } break; case DT_DIR: { DIR* subdir{::opendir(fullpath.c_str())}; if (!subdir) { - g_warning("failed to open dir %s: %s", fullpath.c_str(), + mu_warning("failed to open dir {}: {}", fullpath, g_strerror(errno)); res = false; } @@ -243,8 +241,8 @@ Mu::maildir_clear_links(const std::string& path) { const auto dir{::opendir(path.c_str())}; if (!dir) - return Err(Error{Error::Code::File, "failed to open %s: %s", - path.c_str(), g_strerror(errno)}); + return Err(Error{Error::Code::File, "failed to open {}: {}", + path, g_strerror(errno)}); clear_links(path, dir); ::closedir(dir); @@ -258,16 +256,15 @@ msg_move_verify(const std::string& src, const std::string& dst) /* double check -- is the target really there? */ if (::access(dst.c_str(), F_OK) != 0) return Err(Error{Error::Code::File, - "can't find target (%s->%s)", - src.c_str(), dst.c_str()}); + "can't find target ({}->{})", src, dst}); if (::access(src.c_str(), F_OK) == 0) { if (src == dst) { - g_warning("moved %s to itself", src.c_str()); + mu_warning("moved {} to itself", src); } /* this could happen if some other tool (for mail syncing) is * interfering */ - g_debug("the source is still there (%s->%s)", src.c_str(), dst.c_str()); + mu_debug("source is still there ({}->{})", src, dst); } return Ok(); @@ -292,15 +289,14 @@ msg_move_g_file(const std::string& src, const std::string& dst) return Ok(); else return Err(Error{Error::Code::File, &err/*consumed*/, - "error moving %s -> %s", - src.c_str(), dst.c_str()}); + "error moving {} -> {}", src, dst}); } static Mu::Result msg_move(const std::string& src, const std::string& dst, bool force_gio) { if (::access(src.c_str(), R_OK) != 0) - return Err(Error{Error::Code::File, "cannot read %s", src.c_str()}); + return Err(Error{Error::Code::File, "cannot read {}", src}); if (!force_gio) { /* for testing */ @@ -308,8 +304,8 @@ msg_move(const std::string& src, const std::string& dst, bool force_gio) return msg_move_verify(src, dst); if (errno != EXDEV) /* some unrecoverable error occurred */ - return Err(Error{Error::Code::File, "error moving %s -> %s: %s", - src.c_str(), dst.c_str(), strerror(errno)}); + return Err(Error{Error::Code::File, "error moving {} -> {}: {}", + src, dst, strerror(errno)}); } /* the EXDEV / force-gio case -- source and target live on different @@ -330,7 +326,7 @@ Mu::maildir_move_message(const std::string& oldpath, if (oldpath == newpath) return Ok(); // nothing to do. - g_debug("moving %s --> %s", oldpath.c_str(), newpath.c_str()); + mu_debug("moving {} --> {}", oldpath, newpath); return msg_move(oldpath, newpath, force_gio); } @@ -387,27 +383,26 @@ check_determine_target_params (const std::string& old_path, { if (!g_path_is_absolute(old_path.c_str())) return Err(Error{Error::Code::File, - "old_path is not absolute (%s)", old_path.c_str()}); + "old_path is not absolute ({})", old_path}); if (!g_path_is_absolute(root_maildir_path.c_str())) return Err(Error{Error::Code::File, - "root maildir path is not absolute", - root_maildir_path.c_str()}); + "root maildir path is not absolute ({})", + root_maildir_path}); if (!target_maildir.empty() && target_maildir[0] != '/') return Err(Error{Error::Code::File, - "target maildir must be empty or start with / (%s)", - target_maildir.c_str()}); + "target maildir must be empty or start with / ({})", + target_maildir}); if (old_path.find(root_maildir_path) != 0) return Err(Error{Error::Code::File, - "old-path must be below root-maildir (%s) (%s)", - old_path.c_str(), root_maildir_path.c_str()}); + "old-path must be below root-maildir ({}) ({})", + old_path, root_maildir_path}); if (any_of(newflags & Flags::New) && newflags != Flags::New) return Err(Error{Error::Code::File, - "if ::New is specified, " - "it must be the only flag"}); + "if ::New is specified, it must be the only flag"}); return Ok(); } diff --git a/lib/mu-parser.cc b/lib/mu-parser.cc index 3349330a..7b190b94 100644 --- a/lib/mu-parser.cc +++ b/lib/mu-parser.cc @@ -43,7 +43,7 @@ using namespace Mu; // -> [field:]/regex/ #define BUG(...) \ - Mu::Error(Error::Code::Internal, format("%u: BUG: ", __LINE__) + format(__VA_ARGS__)) + Mu::Error(Error::Code::Internal, "BUG @ line {}", __LINE__); /** * Get the "shortcut"/internal fields for the the given fieldstr or empty if there is none diff --git a/lib/mu-query.cc b/lib/mu-query.cc index 1147319b..c4a61848 100644 --- a/lib/mu-query.cc +++ b/lib/mu-query.cc @@ -91,9 +91,9 @@ Query::Private::make_enquire(const std::string& expr, WarningVec warns; const auto tree{parser_.parse(expr, warns)}; for (auto&& w : warns) - g_warning("query warning: %s", to_string(w).c_str()); + mu_warning("query warning: {}", to_string(w)); enq.set_query(xapian_query(tree)); - g_debug("qtree: %s", to_string(tree).c_str()); + mu_debug("qtree: {}", to_string(tree)); } sort_enquire(enq, sortfield_id, qflags); @@ -291,7 +291,7 @@ Query::parse(const std::string& expr, bool xapian) const WarningVec warns; const auto tree{priv_->parser_.parse(expr, warns)}; for (auto&& w : warns) - g_warning("query warning: %s", to_string(w).c_str()); + mu_warning("query warning: {}", to_string(w)); if (xapian) return xapian_query(tree).get_description(); diff --git a/lib/mu-script.cc b/lib/mu-script.cc index 61b71ca7..b5393e64 100644 --- a/lib/mu-script.cc +++ b/lib/mu-script.cc @@ -1,5 +1,5 @@ /* -** Copyright (C) 2022 Dirk-Jan C. Binnema +** Copyright (C) 2022-2023 Dirk-Jan C. Binnema ** ** 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 @@ -19,14 +19,6 @@ #include "config.h" #include "mu-script.hh" - -#ifdef BUILD_GUILE -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wredundant-decls" -#include -#pragma GCC diagnostic pop -#endif /*BUILD_GUILE*/ - #include "mu/mu-options.hh" #include "utils/mu-utils.hh" #include "utils/mu-option.hh" @@ -34,6 +26,14 @@ #include #include +#ifdef BUILD_GUILE +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wredundant-decls" +#pragma GCC diagnostic ignored "-Wvolatile" +#include +#pragma GCC diagnostic pop +#endif /*BUILD_GUILE*/ + using namespace Mu; static std::string @@ -58,7 +58,7 @@ get_info(std::string&& path, const std::string& prefix) { std::ifstream file{path}; if (!file.is_open()) { - g_warning ("failed to open %s", path.c_str()); + mu_warning ("failed to open {}", path); return Nothing; } @@ -93,7 +93,7 @@ script_infos_in_dir(const std::string& scriptdir, Mu::ScriptInfos& infos) { DIR *dir = opendir(scriptdir.c_str()); if (!dir) { - g_debug("failed to open '%s': %s", scriptdir.c_str(), + mu_debug("failed to open '{}': {}", scriptdir, g_strerror(errno)); return; } diff --git a/lib/mu-server.cc b/lib/mu-server.cc index d4a6a65c..282344ec 100644 --- a/lib/mu-server.cc +++ b/lib/mu-server.cc @@ -1,5 +1,5 @@ /* -** Copyright (C) 2020-2022 Dirk-Jan C. Binnema +** Copyright (C) 2020-2023 Dirk-Jan C. Binnema ** ** 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 @@ -337,23 +337,15 @@ Server::Private::make_command_map() return cmap; } -G_GNUC_PRINTF(2, 3) -static Sexp -make_error(Error::Code code, const char* frm, ...) -{ - va_list ap; - va_start(ap, frm); - auto err = Sexp().put_props( - ":error", Error::error_number(code), - ":message", vformat(frm, ap)); - va_end(ap); - - return err; -} - bool Server::Private::invoke(const std::string& expr) noexcept { + auto make_error=[](auto&& code, auto&& msg) { + return Sexp().put_props( + ":error", Error::error_number(code), + ":message", msg); + }; + if (!keep_going_) return false; try { @@ -366,17 +358,20 @@ Server::Private::invoke(const std::string& expr) noexcept throw res.error(); } catch (const Mu::Error& me) { - output_sexp(make_error(me.code(), "%s", me.what())); + output_sexp(make_error(me.code(), mu_format("{}", me.what()))); keep_going_ = true; } catch (const Xapian::Error& xerr) { - output_sexp(make_error(Error::Code::Internal, "xapian error: %s: %s", - xerr.get_type(), xerr.get_description().c_str())); + output_sexp(make_error(Error::Code::Internal, + mu_format("xapian error: {}: {}", + xerr.get_type(), xerr.get_description()))); keep_going_ = false; } catch (const std::runtime_error& re) { - output_sexp(make_error(Error::Code::Internal, "caught exception: %s", re.what())); + output_sexp(make_error(Error::Code::Internal, + mu_format("caught exception: {}", re.what()))); keep_going_ = false; } catch (...) { - output_sexp(make_error(Error::Code::Internal, "something went wrong: quiting")); + output_sexp(make_error(Error::Code::Internal, + mu_format("something went wrong: quitting"))); keep_going_ = false; } @@ -405,8 +400,7 @@ Server::Private::add_handler(const Command& cmd) auto msg_res{store().find_message(docid)}; if (!msg_res) throw Error(Error::Code::Store, - "failed to get message at %s (docid=%u): %s", - path->c_str(), docid); + "failed to get message at {} (docid={})", *path, docid); output_sexp(Sexp().put_props(":update", build_message_sexp(msg_res.value(), docid, {}))); @@ -470,7 +464,7 @@ Server::Private::compose_handler(const Command& cmd) const unsigned docid{static_cast(cmd.number_arg(":docid").value_or(0))}; auto msg{store().find_message(docid)}; if (!msg) - throw Error{Error::Code::Store, "failed to get message %u", docid}; + throw Error{Error::Code::Store, "failed to get message {}", docid}; comp_lst.put_props(":original", build_message_sexp(msg.value(), docid, {})); @@ -492,8 +486,7 @@ Server::Private::compose_handler(const Command& cmd) } } else if (ctype != "new") - throw Error(Error::Code::InvalidArgument, "invalid compose type '%s'", - ctype.c_str()); + throw Error(Error::Code::InvalidArgument, "invalid compose type '{}'", ctype); output_sexp(comp_lst); } @@ -510,10 +503,8 @@ Server::Private::contacts_handler(const Command& cmd) parse_date_time(afterstr, true).value_or(0)}; const auto tstamp = g_ascii_strtoll(tstampstr.c_str(), NULL, 10); - g_debug("find %s contacts last seen >= %s (tstamp: %zu)", - personal ? "personal" : "any", - time_to_string("%c", after).c_str(), - static_cast(tstamp)); + mu_debug("find {} contacts last seen >= {} (tstamp: {})", + personal ? "personal" : "any", time_to_string("%c", after), tstamp); auto n{0}; Sexp contacts; @@ -540,7 +531,7 @@ Server::Private::contacts_handler(const Command& cmd) ":tstamp", format("%" G_GINT64_FORMAT, g_get_monotonic_time())); /* dump the contacts cache as a giant sexp */ - g_debug("sending %d of %zu contact(s)", n, store().contacts_cache().size()); + mu_debug("sending {} of {} contact(s)", n, store().contacts_cache().size()); output_sexp(seq, Server::OutputFlags::SplitList); } @@ -549,8 +540,7 @@ static std::vector docids_for_msgid(const Store& store, const std::string& msgid, size_t max = 100) { if (msgid.size() > MaxTermLength) { - throw Error(Error::Code::InvalidArgument, - "invalid message-id '%s'", msgid.c_str()); + throw Error(Error::Code::InvalidArgument, "invalid message-id '{}'", msgid); } else if (msgid.empty()) return {}; @@ -566,10 +556,10 @@ docids_for_msgid(const Store& store, const std::string& msgid, size_t max = 100) g_free(expr); if (!res) throw Error(Error::Code::Store, &gerr, - "failed to run message-id-query: %s", res.error().what()); + "failed to run message-id-query: {}", res.error().what()); else if (res->empty()) throw Error(Error::Code::NotFound, - "could not find message(s) for msgid %s", msgid.c_str()); + "could not find message(s) for msgid {}", msgid); std::vector docids{}; for (auto&& mi : *res) @@ -590,7 +580,7 @@ path_from_docid(const Store& store, Store::Id docid) throw Error(Error::Code::Store, "could not get message from store"); if (auto path{msg->path()}; path.empty()) - throw Error(Error::Code::Store, "could not get path for message %u", + throw Error(Error::Code::Store, "could not get path for message {}", docid); else return path; @@ -667,17 +657,17 @@ Server::Private::find_handler(const Command& cmd) if (const auto arg = cmd.symbol_arg(":sortfield"); !arg) return Field::Id::Date; else if (arg->length() < 2) - throw Error{Error::Code::InvalidArgument, "invalid sort field '%s'", - arg->c_str()}; + throw Error{Error::Code::InvalidArgument, "invalid sort field '{}'", + *arg}; else if (const auto field{field_from_name(arg->substr(1))}; !field) - throw Error{Error::Code::InvalidArgument, "invalid sort field '%s'", - arg->c_str()}; + throw Error{Error::Code::InvalidArgument, "invalid sort field '{}'", + *arg}; else return field->id; }); if (batch_size < 1) - throw Error{Error::Code::InvalidArgument, "invalid batch-size %d", batch_size}; + throw Error{Error::Code::InvalidArgument, "invalid batch-size {}", batch_size}; auto qflags{QueryFlags::SkipUnreadable}; // don't show unreadables. if (descending) @@ -695,7 +685,7 @@ Server::Private::find_handler(const Command& cmd) std::lock_guard l{store_.lock()}; auto qres{store_.run_query(q, sort_field_id, qflags, maxnum)}; if (!qres) - throw Error(Error::Code::Query, "failed to run query: %s", qres.error().what()); + throw Error(Error::Code::Query, "failed to run query: {}", qres.error().what()); /* before sending new results, send an 'erase' message, so the frontend * knows it should erase the headers buffer. this will ensure that the @@ -864,7 +854,7 @@ calculate_message_flags(const Message& msg, Option flagopt) if (!flags) throw Error{Error::Code::InvalidArgument, - "invalid flags '%s'", flagopt.value_or("").c_str()}; + "invalid flags '{}'", flagopt.value_or("")}; else return flags.value(); } @@ -913,7 +903,7 @@ Server::Private::move_handler(const Command& cmd) const auto docid{docids.at(0)}; auto msg = store().find_message(docid) .or_else([&]{throw Error{Error::Code::InvalidArgument, - "cannot find message %u", docid};}).value(); + "cannot find message {}", docid};}).value(); /* if maildir was not specified, take the current one */ if (maildir.empty()) @@ -982,12 +972,10 @@ Server::Private::remove_handler(const Command& cmd) if (::unlink(path.c_str()) != 0 && errno != ENOENT) throw Error(Error::Code::File, - "could not delete %s: %s", - path.c_str(), - g_strerror(errno)); + "could not delete {}: {}", path, g_strerror(errno)); if (!store().remove_message(path)) - g_warning("failed to remove message @ %s (%d) from store", path.c_str(), docid); + mu_warning("failed to remove message @ {} ({}) from store", path, docid); output_sexp(Sexp().put_props(":remove", docid)); // act as if it worked. } @@ -997,8 +985,9 @@ Server::Private::sent_handler(const Command& cmd) const auto path{cmd.string_arg(":path").value_or("")}; const auto docid = store().add_message(path); if (!docid) - throw Error{Error::Code::Store, "failed to add path: %s", - docid.error().what()}; + throw Error{Error::Code::Store, "failed to add path: {}: {}", + path, docid.error().what()}; + output_sexp(Sexp().put_props( ":sent", Sexp::t_sym, ":path", path, diff --git a/lib/mu-store.cc b/lib/mu-store.cc index 77c9b913..980a7198 100644 --- a/lib/mu-store.cc +++ b/lib/mu-store.cc @@ -71,18 +71,18 @@ struct Store::Private { {} ~Private() try { - g_debug("closing store @ %s", xapian_db_.path().c_str()); + mu_debug("closing store @ {}", xapian_db_.path()); if (!xapian_db_.read_only()) { transaction_maybe_commit(true /*force*/); } } catch (...) { - g_critical("caught exception in store dtor"); + mu_critical("caught exception in store dtor"); } // If not started yet, start a transaction. Otherwise, just update the transaction size. void transaction_inc() noexcept { if (transaction_size_ == 0) { - g_debug("starting transaction"); + mu_debug("starting transaction"); xapian_db_.begin_transaction(); } ++transaction_size_; @@ -102,16 +102,12 @@ struct Store::Private { if (transaction_size_ == 0) return; // nothing more to do here. - g_debug("committing transaction (n=%zu)", transaction_size_); + mu_debug("committing transaction (n={})", transaction_size_); xapian_db_.commit_transaction(); transaction_size_ = 0; } } - time_t metadata_time_t(const std::string& key) const { - return static_cast(::atoll(xapian_db_.metadata(key).c_str())); - } - XapianDb make_db(const std::string& path, XapianDb::Flavor flavor) { if (auto&& res{XapianDb::make(path, flavor)}; res) return std::move(res.value()); @@ -193,7 +189,7 @@ Store::Store(const std::string& path, Store::Options opts) /* don't try to recover from version with an incompatible scheme */ if (s_version < 500) throw Mu::Error(Error::Code::CannotReinit, - "old schema (%zu) is too old to re-initialize from", + "old schema ({}) is too old to re-initialize from", s_version); const auto old_root_maildir{root_maildir()}; @@ -210,7 +206,7 @@ Store::Store(const std::string& path, Store::Options opts) /* otherwise, the schema version should match. */ if (s_version != ExpectedSchemaVersion) throw Mu::Error(Error::Code::SchemaMismatch, - "expected schema-version %zu, but got %zu", + "expected schema-version {}, but got {}", ExpectedSchemaVersion, s_version); } @@ -433,7 +429,7 @@ static Store::IdMessageVec messages_with_msgid(const Store& store, const std::string& msgid, size_t max=100) { if (msgid.size() > MaxTermLength) { - g_warning("invalid message-id '%s'", msgid.c_str()); + mu_warning("invalid message-id '{}'", msgid.c_str()); return {}; } else if (msgid.empty()) return {}; @@ -447,11 +443,11 @@ messages_with_msgid(const Store& store, const std::string& msgid, size_t max=100 const auto res{store.run_query(expr, {}, QueryFlags::None, max)}; g_free(expr); if (!res) { - g_warning("failed to run message-id-query: %s", res.error().what()); + mu_warning("failed to run message-id-query: {}", res.error().what()); return {}; } if (res->empty()) { - g_warning("could not find message(s) for msgid %s", msgid.c_str()); + mu_warning("could not find message(s) for msgid {}", msgid); return {}; } @@ -483,7 +479,7 @@ Store::move_message(Store::Id id, auto msg{priv_->find_message_unlocked(id)}; if (!msg) - return Err(Error::Code::Store, "cannot find message <%u>", id); + return Err(Error::Code::Store, "cannot find message <{}>", id); auto res{priv_->move_message_unlocked(std::move(*msg), target_mdir, new_flags, opts)}; if (!res) @@ -513,7 +509,7 @@ Store::move_message(Store::Id id, if (dup_res) imvec.emplace_back(docid, std::move(*dup_res)); else - g_warning("failed to move dup: %s", dup_res.error().what()); + mu_warning("failed to move dup: {}", dup_res.error().what()); } return Ok(std::move(imvec)); diff --git a/lib/mu-xapian-db.cc b/lib/mu-xapian-db.cc index 68c25920..ca9cd8d5 100644 --- a/lib/mu-xapian-db.cc +++ b/lib/mu-xapian-db.cc @@ -102,8 +102,8 @@ XapianDb::make(const std::string& db_path, Flavor flavor) noexcept try { g_setenv("XAPIAN_FLUSH_THRESHOLD", "500000", 1); /* create path if needed */ if (g_mkdir_with_parents(db_path.c_str(), 0700) != 0) - return Err(Error::Code::File, "failed to create database dir %s: %s", - db_path.c_str(), ::strerror(errno)); + return Err(Error::Code::File, "failed to create database dir {}: {}", + db_path, ::strerror(errno)); } switch (flavor) { @@ -125,12 +125,12 @@ XapianDb::make(const std::string& db_path, Flavor flavor) noexcept try { } } catch (const Xapian::DatabaseLockError& xde) { - return Err(Error::Code::StoreLock, "%s", xde.get_msg().c_str()); + return Err(Error::Code::StoreLock, "{}", xde.get_msg()); } catch (const Xapian::DatabaseError& xde) { - return Err(Error::Code::Store, "%s", xde.get_msg().c_str()); + return Err(Error::Code::Store, "{}", xde.get_msg()); } catch (const Mu::Error& me) { return Err(me); } catch (...) { return Err(Error::Code::Internal, - "something went wrong when opening store @ %s", db_path.c_str()); + "something went wrong when opening store @ {}", db_path); } diff --git a/lib/mu-xapian-db.hh b/lib/mu-xapian-db.hh index 5daf363d..2e57f779 100644 --- a/lib/mu-xapian-db.hh +++ b/lib/mu-xapian-db.hh @@ -31,6 +31,7 @@ #include #include +#include namespace Mu { @@ -42,13 +43,13 @@ xapian_try(Func&& func) noexcept try { func(); } catch (const Xapian::Error& xerr) { - g_critical("%s: xapian error '%s'", __func__, xerr.get_msg().c_str()); + mu_critical("{}: xapian error '{}'", __func__, xerr.get_msg()); } catch (const std::runtime_error& re) { - g_critical("%s: runtime error: %s", __func__, re.what()); + mu_critical("{}: runtime error: {}", __func__, re.what()); } catch (const std::exception& e) { - g_critical("%s: caught std::exception: %s", __func__, e.what()); + mu_critical("{}: caught std::exception: {}", __func__, e.what()); } catch (...) { - g_critical("%s: caught exception", __func__); + mu_critical("{}: caught exception", __func__); } template > auto @@ -58,30 +59,29 @@ try { } catch (const Xapian::DocNotFoundError& xerr) { return static_cast(def); } catch (const Xapian::Error& xerr) { - g_warning("%s: xapian error '%s'", __func__, xerr.get_msg().c_str()); + mu_warning("{}: xapian error '{}'", __func__, xerr.get_msg()); return static_cast(def); } catch (const std::runtime_error& re) { - g_critical("%s: runtime error: %s", __func__, re.what()); + mu_critical("{}: runtime error: {}", __func__, re.what()); return static_cast(def); } catch (const std::exception& e) { - g_critical("%s: caught std::exception: %s", __func__, e.what()); + mu_critical("{}: caught std::exception: {}", __func__, e.what()); return static_cast(def); } catch (...) { - g_critical("%s: caught exception", __func__); + mu_critical("{}: caught exception", __func__); return static_cast(def); } - template auto xapian_try_result(Func&& func) noexcept -> std::decay_t try { return func(); } catch (const Xapian::Error& xerr) { - return Err(Error::Code::Xapian, "%s", xerr.get_error_string()); + return Err(Error::Code::Xapian, "{}", xerr.get_error_string()); } catch (const std::runtime_error& re) { - return Err(Error::Code::Internal, "runtime error: %s", re.what()); + return Err(Error::Code::Internal, "runtime error: {}", re.what()); } catch (const std::exception& e) { - return Err(Error::Code::Internal, "caught std::exception: %s", e.what()); + return Err(Error::Code::Internal, "caught std::exception: {}", e.what()); } catch (...) { return Err(Error::Code::Internal, "caught exception"); } diff --git a/lib/tests/bench-indexer.cc b/lib/tests/bench-indexer.cc index ea0ebe22..abd46845 100644 --- a/lib/tests/bench-indexer.cc +++ b/lib/tests/bench-indexer.cc @@ -443,7 +443,7 @@ tear_down() GError *err{}; const auto cmd{format("/bin/rm -rf '%s' '%s'", BENCH_MAILDIRS, BENCH_STORE)}; 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); } } diff --git a/lib/tests/test-mu-msg.cc b/lib/tests/test-mu-msg.cc index 12a64cef..1e5d82dc 100644 --- a/lib/tests/test-mu-msg.cc +++ b/lib/tests/test-mu-msg.cc @@ -47,12 +47,13 @@ assert_contacts_equal(const Contacts& contacts, size_t n{}; for (auto&& contact: contacts) { if (g_test_verbose()) - g_message("{ \"%s\", \"%s\"},\n", contact.name.c_str(), contact.email.c_str()); + mu_message("{{ \"{}\", \"{}\"}},\n", + contact.name, contact.email); assert_equal(contact.name, expected.at(n).first); assert_equal(contact.email, expected.at(n).second); ++n; } - g_print("\n"); + mu_print("\n"); } @@ -97,7 +98,7 @@ test_mu_msg_02(void) g_assert_true(msg.priority() /* 'low' */ == Priority::Low); g_assert_cmpuint(msg.date(), ==, 1218051515); - g_print("flags: %s\n", Mu::to_string(msg.flags()).c_str()); + mu_println("flags: {}", Mu::to_string(msg.flags())); g_assert_true(msg.flags() == (Flags::Seen|Flags::MailingList)); assert_contacts_equal(msg.all_contacts(), { diff --git a/lib/utils/meson.build b/lib/utils/meson.build index c9dcd249..453ddc1a 100644 --- a/lib/utils/meson.build +++ b/lib/utils/meson.build @@ -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') diff --git a/lib/utils/mu-command-handler.cc b/lib/utils/mu-command-handler.cc index 7b04eb8b..610d489f 100644 --- a/lib/utils/mu-command-handler.cc +++ b/lib/utils/mu-command-handler.cc @@ -36,8 +36,8 @@ Command::string_vec_arg(const std::string& name) const std::vector 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; } diff --git a/lib/utils/mu-option.hh b/lib/utils/mu-option.hh index 6af72e1b..c2885486 100644 --- a/lib/utils/mu-option.hh +++ b/lib/utils/mu-option.hh @@ -1,15 +1,21 @@ /* - * Created on 2020-11-08 by Dirk-Jan C. Binnema - * - * 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 +** +** 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. diff --git a/lib/utils/mu-result.hh b/lib/utils/mu-result.hh index 428b88a5..557102c3 100644 --- a/lib/utils/mu-result.hh +++ b/lib/utils/mu-result.hh @@ -103,13 +103,13 @@ Err(Error::Code code, GError **err, fmt::format_string 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 diff --git a/lib/utils/mu-sexp.cc b/lib/utils/mu-sexp.cc index 34ecdfb9..f760fb0d 100644 --- a/lib/utils/mu-sexp.cc +++ b/lib/utils/mu-sexp.cc @@ -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 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 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 parse_integer(const std::string& expr, size_t& pos) { if (!isdigit(expr[pos]) && 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])); std::string num; // negative number? if (expr[pos] == '-') { @@ -130,7 +130,7 @@ static Result parse_symbol(const std::string& expr, size_t& pos) { if (!isalpha(expr[pos]) && 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])); 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 { @@ -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; } diff --git a/lib/utils/mu-test-utils.cc b/lib/utils/mu-test-utils.cc index fb82b4f7..694ddd0e 100644 --- a/lib/utils/mu-test-utils.cc +++ b/lib/utils/mu-test-utils.cc @@ -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_); } diff --git a/lib/utils/mu-utils-file.cc b/lib/utils/mu-utils-file.cc index f8468859..4922a789 100644 --- a/lib/utils/mu-utils-file.cc +++ b/lib/utils/mu-utils-file.cc @@ -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; } diff --git a/lib/utils/mu-utils.cc b/lib/utils/mu-utils.cc index 151b2213..9840c83f 100644 --- a/lib/utils/mu-utils.cc +++ b/lib/utils/mu-utils.cc @@ -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(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); diff --git a/lib/utils/mu-utils.hh b/lib/utils/mu-utils.hh index b1bce24c..0d7a5b1e 100644 --- a/lib/utils/mu-utils.hh +++ b/lib/utils/mu-utils.hh @@ -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 @@ -81,6 +86,35 @@ inline void mu_error(fmt::format_string frm, T&&... args) noexcept { fmt::format(frm, std::forward(args)...).c_str()); } +/* + * Printing + */ + +template +inline void mu_print(fmt::format_string frm, T&&... args) noexcept { + fmt::print(frm, std::forward(args)...); +} +template +inline void mu_println(fmt::format_string frm, T&&... args) noexcept { + fmt::println(frm, std::forward(args)...); +} +template +inline void mu_printerr(fmt::format_string frm, T&&... args) noexcept { + fmt::print(stderr, frm, std::forward(args)...); +} +template +inline void mu_printerrln(fmt::format_string frm, T&&... args) noexcept { + fmt::println(stderr, frm, std::forward(args)...); +} + +/* + * Fprmatting + */ +template +inline std::string mu_format(fmt::format_string frm, T&&... args) noexcept { + return fmt::format(frm, std::forward(args)...); +} + using StringVec = std::vector; /** @@ -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 * diff --git a/meson.build b/meson.build index ca6c6aa5..4742958d 100644 --- a/meson.build +++ b/meson.build @@ -55,6 +55,7 @@ extra_flags = [ '-Wstack-protector', '-Wno-switch-enum', '-Wno-keyword-macro', + '-Wno-volatile', '-Wno-#warnings'] if get_option('buildtype') == 'debug' diff --git a/mu/mu-cmd-cfind.cc b/mu/mu-cmd-cfind.cc index 25fb1298..e0151df0 100644 --- a/mu/mu-cmd-cfind.cc +++ b/mu/mu-cmd-cfind.cc @@ -137,7 +137,7 @@ static void output_mutt_address_book(ItemType itype, OptContact contact, const Options& opts) { if (itype == ItemType::Header) - g_print ("Matching addresses in the mu database:\n"); + mu_print ("Matching addresses in the mu database:\n"); if (!contact) return; @@ -176,8 +176,8 @@ static void output_bbdb(ItemType itype, OptContact contact, const Options& opts) { if (itype == ItemType::Header) - g_print (";; -*-coding: utf-8-emacs;-*-\n" - ";;; file-version: 6\n"); + mu_println (";; -*-coding: utf-8-emacs;-*-\n" + ";;; file-version: 6"); if (!contact) return; @@ -185,13 +185,9 @@ output_bbdb(ItemType itype, OptContact contact, const Options& opts) const auto now{time_to_string("%Y-%m-%d", ::time(NULL))}; const auto timestamp{time_to_string("%Y-%m-%d", contact->message_date)}; - g_print("[\"%s\" \"%s\" nil nil nil nil (\"%s\") " - "((creation-date . \"%s\") (time-stamp . \"%s\")) nil]\n", - names.first.c_str(), - names.second.c_str(), - contact->email.c_str(), - now.c_str(), - timestamp.c_str()); + mu_println("[\"{}\" \"{}\" nil nil nil nil (\"{}\") " + "((creation-date . \"{}\") (time-stamp . \"{}\")) nil]", + names.first, names.second, contact->email, now, timestamp); } static void @@ -209,10 +205,10 @@ static void output_json(ItemType itype, OptContact contact, const Options& opts) { if (itype == ItemType::Header) - g_print("[\n"); + mu_println("["); if (contact) { - g_print("%s", itype == ItemType::Header ? "" : ",\n"); - g_print (" {\n"); + mu_print("{}", itype == ItemType::Header ? "" : ",\n"); + mu_println (" {{"); const std::string name = contact->name.empty() ? "null" : Mu::quote(contact->name); print_encoded( @@ -230,11 +226,11 @@ output_json(ItemType itype, OptContact contact, const Options& opts) time_to_string("%FT%TZ", contact->message_date, true/*utc*/).c_str(), contact->personal ? "true" : "false", contact->frequency); - g_print (" }"); + mu_print (" }}"); } if (itype == ItemType::Footer) - g_print("\n]\n"); + mu_println("\n]"); } static OutputFunc @@ -260,7 +256,7 @@ find_output_func(Format format) case Format::Json: return output_json; default: - g_warning("unsupported format"); + mu_warning("unsupported format"); return {}; } #pragma GCC diagnostic pop diff --git a/mu/mu-cmd-extract.cc b/mu/mu-cmd-extract.cc index 0f271f05..b5b94cbb 100644 --- a/mu/mu-cmd-extract.cc +++ b/mu/mu-cmd-extract.cc @@ -86,7 +86,7 @@ save_parts(const Message& message, const std::string& filename_rx, if (saved_num == 0) return Err(Error::Code::File, - "no %s extracted from this message", + "no {} extracted from this message", opts.extract.save_attachments ? "attachments" : "parts"); else return Ok(); @@ -102,7 +102,7 @@ static void show_part(const MessagePart& part, size_t index, bool color) { /* index */ - g_print(" %zu ", index); + mu_print(" {} ", index); /* filename */ color_maybe(MU_COLOR_GREEN); @@ -122,7 +122,7 @@ show_part(const MessagePart& part, size_t index, bool color) /* size */ if (part.size() > 0) { color_maybe(MU_COLOR_CYAN); - g_print(" (%zu bytes)", part.size()); + mu_print(" ({} bytes)", part.size()); } color_maybe(MU_COLOR_DEFAULT); @@ -133,7 +133,7 @@ static Mu::Result show_parts(const Message& message, const Options& opts) { size_t index{}; - g_print("MIME-parts in this message:\n"); + mu_println("MIME-parts in this message:"); for (auto&& part: message.parts()) show_part(part, ++index, !opts.nocolor); @@ -164,8 +164,8 @@ Mu::mu_cmd_extract(const Options& opts) if (!check_dir(opts.extract.targetdir, false/*!readable*/, true/*writeable*/)) return Err(Error::Code::File, - "target '%s' is not a writable directory", - opts.extract.targetdir.c_str()); + "target '{}' is not a writable directory", + opts.extract.targetdir); return save_parts(*message, opts.extract.filename_rx, opts); } diff --git a/mu/mu-cmd-find.cc b/mu/mu-cmd-find.cc index e340a6d8..de4cbc03 100644 --- a/mu/mu-cmd-find.cc +++ b/mu/mu-cmd-find.cc @@ -116,14 +116,14 @@ resolve_bookmark(const Options& opts) auto bm = mu_bookmarks_new(bmfile.c_str()); if (!bm) return Err(Error::Code::File, - "failed to open bookmarks file '%s'", bmfile.c_str()); + "failed to open bookmarks file '{}'", bmfile); const auto bookmark{opts.find.bookmark}; const auto val = mu_bookmarks_lookup(bm, bookmark.c_str()); if (!val) { mu_bookmarks_destroy(bm); return Err(Error::Code::NoMatches, - "bookmark '%s' not found", bookmark.c_str()); + "bookmark '{}' not found", bookmark); } mu_bookmarks_destroy(bm); @@ -263,9 +263,9 @@ print_summary(const Message& msg, const Options& opts) const auto summ{summarize(body->c_str(), opts.find.summary_len.value_or(0))}; - g_print("Summary: "); + mu_print("Summary: "); fputs_encoded(summ, stdout); - g_print("\n"); + mu_println(""); } static void @@ -361,21 +361,19 @@ static bool output_json(const Option& msg, const OutputInfo& info, const Options& opts, GError** err) { if (info.header) { - g_print("[\n"); + mu_println("["); return true; } if (info.footer) { - g_print("]\n"); + mu_println("]"); return true; } if (!msg) return true; - g_print("%s%s\n", - msg->sexp().to_json_string().c_str(), - info.last ? "" : ","); + mu_println("{}{}", msg->sexp().to_json_string(), info.last ? "" : ","); return true; } @@ -387,34 +385,34 @@ print_attr_xml(const std::string& elm, const std::string& str) return; /* empty: don't include */ auto&& esc{to_string_opt_gchar(g_markup_escape_text(str.c_str(), -1))}; - g_print("\t\t<%s>%s\n", elm.c_str(), esc.value_or("").c_str(), elm.c_str()); + mu_println("\t\t<{}>{}", elm, esc.value_or(""), elm); } static bool output_xml(const Option& msg, const OutputInfo& info, const Options& opts, GError** err) { if (info.header) { - g_print("\n"); - g_print("\n"); + mu_println(""); + mu_println(""); return true; } if (info.footer) { - g_print("\n"); + mu_println(""); return true; } - g_print("\t\n"); + mu_println("\t"); print_attr_xml("from", to_string(msg->from())); print_attr_xml("to", to_string(msg->to())); print_attr_xml("cc", to_string(msg->cc())); print_attr_xml("subject", msg->subject()); - g_print("\t\t%u\n", (unsigned)msg->date()); - g_print("\t\t%u\n", (unsigned)msg->size()); + mu_println("\t\t{}", (unsigned)msg->date()); + mu_println("\t\t{}", (unsigned)msg->size()); print_attr_xml("msgid", msg->message_id()); print_attr_xml("path", msg->path()); print_attr_xml("maildir", msg->maildir()); - g_print("\t\n"); + mu_println("\t"); return true; } diff --git a/mu/mu-cmd-index.cc b/mu/mu-cmd-index.cc index f8cf6f33..3a026217 100644 --- a/mu/mu-cmd-index.cc +++ b/mu/mu-cmd-index.cc @@ -55,7 +55,7 @@ install_sig_handler(void) for (i = 0; i != G_N_ELEMENTS(sigs); ++i) if (sigaction(sigs[i], &action, NULL) != 0) - g_critical("set sigaction for %d failed: %s", + mu_critical("set sigaction for {} failed: {}", sigs[i], g_strerror(errno)); } @@ -79,7 +79,7 @@ Mu::mu_cmd_index(Store& store, const Options& opts) { const auto mdir{store.root_maildir()}; if (G_UNLIKELY(access(mdir.c_str(), R_OK) != 0)) - return Err(Error::Code::File, "'%s' is not readable: %s", + return Err(Error::Code::File, "'{}' is not readable: {}", mdir.c_str(), g_strerror(errno)); MaybeAnsi col{!opts.nocolor}; diff --git a/mu/mu-cmd-remove.cc b/mu/mu-cmd-remove.cc index 8e0455b1..b7849989 100644 --- a/mu/mu-cmd-remove.cc +++ b/mu/mu-cmd-remove.cc @@ -28,11 +28,10 @@ Mu::mu_cmd_remove(Mu::Store& store, const Options& opts) for (auto&& file: opts.remove.files) { const auto res = store.remove_message(file); if (!res) - return Err(Error::Code::File, "failed to remove %s", file.c_str()); + return Err(Error::Code::File, "failed to remove {}", file.c_str()); else g_debug("removed message @ %s", file.c_str()); } return Ok(); } - diff --git a/mu/mu-cmd-script.cc b/mu/mu-cmd-script.cc index d1b281d3..2302dd75 100644 --- a/mu/mu-cmd-script.cc +++ b/mu/mu-cmd-script.cc @@ -36,7 +36,7 @@ Mu::mu_cmd_script(const Options& opts) if (script_it == scriptinfos.cend()) return Err(Error::Code::InvalidArgument, - "cannot find script '%s'", opts.script.name.c_str()); + "cannot find script '{}'", opts.script.name); std::vector params{opts.script.params}; if (!opts.muhome.empty()) { diff --git a/mu/mu-cmd-server.cc b/mu/mu-cmd-server.cc index 6c55a097..3d2f8a10 100644 --- a/mu/mu-cmd-server.cc +++ b/mu/mu-cmd-server.cc @@ -57,7 +57,7 @@ install_sig_handler(void) for (i = 0; i != G_N_ELEMENTS(sigs); ++i) if (sigaction(sigs[i], &action, NULL) != 0) - g_critical("set sigaction for %d failed: %s", + mu_critical("set sigaction for {} failed: {}", sigs[i], g_strerror(errno)); } @@ -92,7 +92,7 @@ output_sexp_stdout(const Sexp& sexp, Server::OutputFlags flags) const auto str{sexp.to_string(fopts)}; cookie(str.size() + 1); if (G_UNLIKELY(::puts(str.c_str()) < 0)) { - g_critical("failed to write output '%s'", str.c_str()); + mu_critical("failed to write output '{}'", str); ::raise(SIGTERM); /* terminate ourselves */ } @@ -118,12 +118,11 @@ Mu::mu_cmd_server(const Mu::Options& opts) try { return Err(store.error()); Server server{*store, output_sexp_stdout}; - g_message("created server with store @ %s; maildir @ %s; debug-mode %s;" - "readline: %s", - store->path().c_str(), - store->root_maildir().c_str(), - opts.debug ? "yes" : "no", - have_readline() ? "yes" : "no"); + mu_message("created server with store @ {}; maildir @ {}; debug-mode {};" + "readline: {}", + store->path(), store->root_maildir(), + opts.debug ? "yes" : "no", + have_readline() ? "yes" : "no"); tty = ::isatty(::fileno(stdout)); const auto eval = std::string{opts.server.commands ? "(help :full t)" : opts.server.eval}; @@ -153,18 +152,17 @@ Mu::mu_cmd_server(const Mu::Options& opts) try { } if (MuTerminate != 0) - g_message ("shutting down due to signal %d", MuTerminate.load()); + mu_message ("shutting down due to signal {}", MuTerminate.load()); shutdown_readline(); return Ok(); -} catch (const Error& er) { - /* note: user-level error, "OK" for mu */ +} catch (const Error& er) { /* note: user-level error, "OK" for mu */ report_error(er); - g_warning("server caught exception: %s", er.what()); + mu_warning("server caught exception: {}", er.what()); return Ok(); } catch (...) { - g_critical("server caught exception"); + mu_critical("server caught exception"); return Err(Error::Code::Internal, "caught exception"); } diff --git a/mu/mu-cmd-verify.cc b/mu/mu-cmd-verify.cc index 28df0993..163e0d88 100644 --- a/mu/mu-cmd-verify.cc +++ b/mu/mu-cmd-verify.cc @@ -34,13 +34,11 @@ key_val(const Mu::MaybeAnsi& col, const std::string& key, T val) { using Color = Mu::MaybeAnsi::Color; - std::cout << col.fg(Color::BrightBlue) << std::left << std::setw(18) << key << col.reset() - << ": "; - - std::cout << col.fg(Color::Green) << val << col.reset() << "\n"; + mu_println("{}{:<18}{}: {}{}{}", + col.fg(Color::BrightBlue), key, col.reset(), + col.fg(Color::Green), val, col.reset()); } - static void print_signature(const Mu::MimeSignature& sig, const Options& opts) { @@ -90,7 +88,7 @@ verify(const MimeMultipartSigned& sigpart, const Options& opts) if (!sigs || sigs->empty()) { if (!opts.quiet) - g_print("cannot find signatures in part\n"); + mu_println("cannot find signatures in part"); return true; } @@ -119,7 +117,7 @@ verify_message(const Message& message, const Options& opts, const std::string& n { if (none_of(message.flags() & Flags::Signed)) { if (!opts.quiet) - g_print("%s: no signed parts found\n", name.c_str()); + mu_println("{}: no signed parts found", name); return false; } @@ -155,7 +153,7 @@ Mu::mu_cmd_verify(const Options& opts) return Err(message.error()); if (!opts.quiet && opts.verify.files.size() > 1) - g_print("verifying %s\n", file.c_str()); + mu_println("verifying {}", file); if (!verify_message(*message, opts, file)) all_ok = false; diff --git a/mu/mu-cmd-view.cc b/mu/mu-cmd-view.cc index 2758442d..d2bf9e0c 100644 --- a/mu/mu-cmd-view.cc +++ b/mu/mu-cmd-view.cc @@ -93,11 +93,10 @@ body_or_summary(const Message& message, const Options& opts) if (!body || body->empty()) { if (any_of(message.flags() & Flags::Encrypted)) { color_maybe(MU_COLOR_CYAN); - g_print("[No text body found; " - "message has encrypted parts]\n"); + mu_println("[No text body found; message has encrypted parts]"); } else { color_maybe(MU_COLOR_MAGENTA); - g_print("[No text body found]\n"); + mu_println("[No text body found]"); } color_maybe(MU_COLOR_DEFAULT); return; @@ -109,7 +108,7 @@ body_or_summary(const Message& message, const Options& opts) } else { print_encoded("%s", body->c_str()); if (!g_str_has_suffix(body->c_str(), "\n")) - g_print("\n"); + mu_println(""); } } @@ -148,7 +147,7 @@ handle_msg(const Message& message, const Options& opts) case Format::Sexp: return view_msg_sexp(message, opts); default: - g_critical("bug: should not be reached"); + mu_critical("bug: should not be reached"); return Err(Error::Code::Internal, "error"); } } @@ -166,7 +165,7 @@ Mu::mu_cmd_view(const Options& opts) return res; /* add a separator between two messages? */ if (opts.view.terminate) - g_print("%c", VIEW_TERMINATOR); + mu_print("{}", VIEW_TERMINATOR); } // no files? read from stding diff --git a/mu/mu-cmd.cc b/mu/mu-cmd.cc index 52d7ced7..aa9982ee 100644 --- a/mu/mu-cmd.cc +++ b/mu/mu-cmd.cc @@ -47,13 +47,14 @@ using namespace Mu; static Result cmd_fields(const Options& opts) { - g_printerr("the 'mu fields' command has been superseded by 'mu info'; try:\n" + mu_printerrln("the 'mu fields' command has been superseded by 'mu info'; try:\n" " mu info fields\n" - " mu info flags\n"); + " mu info flags"); return Ok(); } + static Result cmd_find(const Options& opts) { @@ -64,14 +65,15 @@ cmd_find(const Options& opts) return mu_cmd_find(*store, opts); } + static void show_usage(void) { - g_print("usage: mu command [options] [parameters]\n"); - g_print("where command is one of index, find, cfind, view, mkdir, " - "extract, add, remove, script, verify or server\n"); - g_print("see the mu, mu- or mu-easy manpages for " - "more information\n"); + mu_println("usage: mu command [options] [parameters]"); + mu_println("where command is one of index, find, cfind, view, mkdir, " + "extract, add, remove, script, verify or server"); + mu_println("see the mu, mu- or mu-easy manpages for " + "more information"); } @@ -157,9 +159,9 @@ Mu::mu_cmd_execute(const Options& opts) try { } catch (const Mu::Error& er) { return Err(er); } catch (const std::runtime_error& re) { - return Err(Error::Code::Internal, "runtime-error: %s", re.what()); + return Err(Error::Code::Internal, "runtime-error: {}", re.what()); } catch (const std::exception& ex) { - return Err(Error::Code::Internal, "error: %s", ex.what()); + return Err(Error::Code::Internal, "error: {}", ex.what()); } catch (...) { return Err(Error::Code::Internal, "caught exception"); } diff --git a/mu/mu-options.cc b/mu/mu-options.cc index 150b50af..de2e368a 100644 --- a/mu/mu-options.cc +++ b/mu/mu-options.cc @@ -623,7 +623,7 @@ cmd_help(const CLI::App& app, Options& opts) return show_manpage(opts, "mu-" + opts.help.command); return Err(Error::Code::Command, - "no help available for '%s'", opts.help.command.c_str()); + "no help available for '{}'", opts.help.command); } bool @@ -660,7 +660,7 @@ Options::make(int argc, char *argv[]) CLI::App app{"mu mail indexer/searcher", "mu"}; app.description(R"(mu mail indexer/searcher -Copyright (C) 2008-2022 Dirk-Jan C. Binnema +Copyright (C) 2008-2023 Dirk-Jan C. Binnema License GPLv3+: GNU GPL version 3 or later . This is free software: you are free to change and redistribute it. @@ -743,7 +743,7 @@ There is NO WARRANTY, to the extent permitted by law. } catch (const CLI::CallForVersion&) { std::cout << "version " << PACKAGE_VERSION << "\n"; } catch (const CLI::ParseError& pe) { - return Err(Error::Code::InvalidArgument, "%s", pe.what()); + return Err(Error::Code::InvalidArgument, "{}", pe.what()); } catch (...) { return Err(Error::Code::Internal, "error parsing arguments"); } diff --git a/mu/mu-options.hh b/mu/mu-options.hh index 9adfbcbd..73868722 100644 --- a/mu/mu-options.hh +++ b/mu/mu-options.hh @@ -284,7 +284,6 @@ struct Options { std::string runtime_path(RuntimePath path) const { return Mu::runtime_path(path, muhome); } - }; } // namepace Mu diff --git a/mu/tests/test-mu-query.cc b/mu/tests/test-mu-query.cc index 4db678c8..a377e4d2 100644 --- a/mu/tests/test-mu-query.cc +++ b/mu/tests/test-mu-query.cc @@ -56,7 +56,7 @@ make_database(const std::string& testdir) MU_PROGRAM, testdir, MU_PROGRAM)}; if (g_test_verbose()) - g_printerr("\n%s\n", cmdline.c_str()); + mu_printerrln("\n{}", cmdline); g_assert(g_spawn_command_line_sync(cmdline.c_str(), NULL, NULL, NULL, NULL)); auto xpath = mu_format("{}{}{}", @@ -106,7 +106,7 @@ run_and_count_matches(const std::string& xpath, if (g_test_verbose()) - g_print("'%s' => %zu\n", expr.c_str(), qres->size()); + mu_println("'{}' => {}\n", expr, qres->size()); return qres->size(); } @@ -247,7 +247,7 @@ test_mu_query_accented_chars_01(void) const auto msg{qres->begin().message()}; if (!msg) { - g_warning("error getting message"); + mu_warning("error getting message"); g_assert_not_reached(); } @@ -269,7 +269,7 @@ test_mu_query_accented_chars_02(void) for (i = 0; i != G_N_ELEMENTS(queries); ++i) { auto count = run_and_count_matches(DB_PATH1, queries[i].query); if (count != queries[i].count) - g_warning("query '%s'; expect %zu but got %zu", + mu_warning("query '{}'; expected {} but got {}", queries[i].query, queries[i].count, count); g_assert_cmpuint(run_and_count_matches(DB_PATH1, queries[i].query), ==, @@ -292,7 +292,7 @@ test_mu_query_accented_chars_fraiche(void) for (i = 0; i != G_N_ELEMENTS(queries); ++i) { if (g_test_verbose()) - g_print("'%s'\n", queries[i].query); + mu_println("{}", queries[i].query); g_assert_cmpuint(run_and_count_matches(DB_PATH2, queries[i].query), ==, @@ -439,7 +439,7 @@ test_mu_query_attach(void) for (i = 0; i != G_N_ELEMENTS(queries); ++i) { if (g_test_verbose()) - g_print("query: %s\n", queries[i].query); + mu_println("query: {}", queries[i].query); g_assert_cmpuint(run_and_count_matches(DB_PATH2, queries[i].query), ==, queries[i].count); @@ -462,7 +462,7 @@ test_mu_query_msgid(void) for (i = 0; i != G_N_ELEMENTS(queries); ++i) { if (g_test_verbose()) - g_print("query: %s\n", queries[i].query); + mu_println("query: {}", queries[i].query); g_assert_cmpuint(run_and_count_matches(DB_PATH2, queries[i].query), ==, queries[i].count);