*: update code for Mu::MessageFlags

Migrate the code to use the new niceness
This commit is contained in:
Dirk-Jan C. Binnema 2022-02-16 22:06:00 +02:00
parent 473134a7b1
commit f6f17d5d6b
8 changed files with 136 additions and 237 deletions

View File

@ -17,6 +17,7 @@
**
*/
#include "mu-guile-message.hh"
#include "mu-message-flags.hh"
#include <config.h>
#include <glib-object.h>
@ -40,9 +41,7 @@ using namespace Mu;
/* some symbols */
static SCM SYMB_PRIO_LOW, SYMB_PRIO_NORMAL, SYMB_PRIO_HIGH;
static SCM SYMB_FLAG_NEW, SYMB_FLAG_PASSED, SYMB_FLAG_REPLIED, SYMB_FLAG_SEEN, SYMB_FLAG_TRASHED,
SYMB_FLAG_DRAFT, SYMB_FLAG_FLAGGED, SYMB_FLAG_SIGNED, SYMB_FLAG_ENCRYPTED, SYMB_FLAG_HAS_ATTACH,
SYMB_FLAG_UNREAD, SYMB_FLAG_LIST;
static std::array<SCM, AllMessageFlagInfos.size()> SYMB_FLAGS;
static SCM SYMB_CONTACT_TO, SYMB_CONTACT_CC, SYMB_CONTACT_BCC, SYMB_CONTACT_FROM;
struct _MuMsgWrapper {
@ -72,11 +71,10 @@ mu_guile_msg_to_scm(MuMsg* msg)
SCM_RETURN_NEWSMOB(MSG_TAG, msgwrap);
}
struct _FlagData {
MuFlags flags;
SCM lst;
};
typedef struct _FlagData FlagData;
typedef struct {
MessageFlags flags;
SCM lst;
} FlagData;
#define MU_GUILE_INITIALIZED_OR_ERROR \
do { \
@ -89,45 +87,20 @@ typedef struct _FlagData FlagData;
} \
} while (0)
static void
check_flag(MuFlags flag, FlagData* fdata)
{
SCM flag_scm;
if (!(fdata->flags & flag))
return;
switch (flag) {
case MU_FLAG_NONE: flag_scm = SCM_UNDEFINED; break;
case MU_FLAG_NEW: flag_scm = SYMB_FLAG_NEW; break;
case MU_FLAG_PASSED: flag_scm = SYMB_FLAG_PASSED; break;
case MU_FLAG_REPLIED: flag_scm = SYMB_FLAG_REPLIED; break;
case MU_FLAG_SEEN: flag_scm = SYMB_FLAG_SEEN; break;
case MU_FLAG_TRASHED: flag_scm = SYMB_FLAG_TRASHED; break;
case MU_FLAG_SIGNED: flag_scm = SYMB_FLAG_SIGNED; break;
case MU_FLAG_DRAFT: flag_scm = SYMB_FLAG_DRAFT; break;
case MU_FLAG_FLAGGED: flag_scm = SYMB_FLAG_FLAGGED; break;
case MU_FLAG_ENCRYPTED: flag_scm = SYMB_FLAG_ENCRYPTED; break;
case MU_FLAG_HAS_ATTACH: flag_scm = SYMB_FLAG_HAS_ATTACH; break;
case MU_FLAG_UNREAD: flag_scm = SYMB_FLAG_UNREAD; break;
case MU_FLAG_LIST: flag_scm = SYMB_FLAG_LIST; break;
default: flag_scm = SCM_UNDEFINED;
}
fdata->lst = scm_append_x(scm_list_2(fdata->lst, scm_list_1(flag_scm)));
}
static SCM
get_flags_scm(MuMsg* msg)
{
FlagData fdata;
SCM lst{SCM_EOL};
const auto flags{mu_msg_get_flags(msg)};
fdata.flags = mu_msg_get_flags(msg);
fdata.lst = SCM_EOL;
for (auto i = 0; i != AllMessageFlagInfos.size(); ++i) {
const auto& info{AllMessageFlagInfos.at(i)};
if (any_of(info.flag & flags))
scm_append_x(scm_list_2(lst, scm_list_1(SYMB_FLAGS.at(i))));
}
mu_flags_foreach((MuFlagsForeachFunc)check_flag, &fdata);
return fdata.lst;
return lst;
}
static SCM
@ -488,19 +461,11 @@ define_symbols(void)
SYMB_PRIO_NORMAL = register_symbol("mu:prio:normal");
SYMB_PRIO_HIGH = register_symbol("mu:prio:high");
SYMB_FLAG_NEW = register_symbol("mu:flag:new");
SYMB_FLAG_PASSED = register_symbol("mu:flag:passed");
SYMB_FLAG_REPLIED = register_symbol("mu:flag:replied");
SYMB_FLAG_SEEN = register_symbol("mu:flag:seen");
SYMB_FLAG_TRASHED = register_symbol("mu:flag:trashed");
SYMB_FLAG_DRAFT = register_symbol("mu:flag:draft");
SYMB_FLAG_FLAGGED = register_symbol("mu:flag:flagged");
SYMB_FLAG_SIGNED = register_symbol("mu:flag:signed");
SYMB_FLAG_ENCRYPTED = register_symbol("mu:flag:encrypted");
SYMB_FLAG_HAS_ATTACH = register_symbol("mu:flag:has-attach");
SYMB_FLAG_UNREAD = register_symbol("mu:flag:unread");
SYMB_FLAG_LIST = register_symbol("mu:flag:list");
for (auto i = 0U; i != AllMessageFlagInfos.size(); ++i) {
const auto& info{AllMessageFlagInfos.at(i)};
const auto name = "mu:flag:" + std::string{info.name};
SYMB_FLAGS[i] = register_symbol(name.c_str());
}
}
static struct {

View File

@ -344,15 +344,15 @@ looks_like_attachment(GMimeObject* part)
}
static void
msg_cflags_cb(GMimeObject* parent, GMimeObject* part, MuFlags* flags)
msg_cflags_cb(GMimeObject* parent, GMimeObject* part, MessageFlags* flags)
{
if (GMIME_IS_MULTIPART_SIGNED(part))
*flags |= MU_FLAG_SIGNED;
*flags |= MessageFlags::Signed;
/* FIXME: An encrypted part might be signed at the same time.
* In that case the signed flag is lost. */
if (GMIME_IS_MULTIPART_ENCRYPTED(part))
*flags |= MU_FLAG_ENCRYPTED;
*flags |= MessageFlags::Encrypted;
/* smime */
if (GMIME_IS_APPLICATION_PKCS7_MIME(part)) {
@ -361,10 +361,10 @@ msg_cflags_cb(GMimeObject* parent, GMimeObject* part, MuFlags* flags)
if (pkcs7) {
switch(pkcs7->smime_type) {
case GMIME_SECURE_MIME_TYPE_ENVELOPED_DATA:
*flags |= MU_FLAG_ENCRYPTED;
*flags |= MessageFlags::Encrypted;
break;
case GMIME_SECURE_MIME_TYPE_SIGNED_DATA:
*flags |= MU_FLAG_SIGNED;
*flags |= MessageFlags::Signed;
break;
default:
break;
@ -372,27 +372,20 @@ msg_cflags_cb(GMimeObject* parent, GMimeObject* part, MuFlags* flags)
}
}
if (*flags & MU_FLAG_HAS_ATTACH)
if (any_of(*flags & MessageFlags::HasAttachment))
return;
if (!GMIME_IS_PART(part))
return;
if (*flags & MU_FLAG_HAS_ATTACH)
return;
if (looks_like_attachment(part))
*flags |= MU_FLAG_HAS_ATTACH;
*flags |= MessageFlags::HasAttachment;
}
static MuFlags
static MessageFlags
get_content_flags(MuMsgFile* self)
{
MuFlags flags;
char* ml;
flags = MU_FLAG_NONE;
MessageFlags flags{MessageFlags::None};
if (GMIME_IS_MESSAGE(self->_mime_msg)) {
/* toplevel */
@ -404,29 +397,29 @@ get_content_flags(MuMsgFile* self)
&flags);
}
ml = get_mailing_list(self);
char *ml{get_mailing_list(self)};
if (ml) {
flags |= MU_FLAG_LIST;
flags |= MessageFlags::MailingList;
g_free(ml);
}
return flags;
}
static MuFlags
static MessageFlags
get_flags(MuMsgFile* self)
{
MuFlags flags;
g_return_val_if_fail(self, MessageFlags::None);
g_return_val_if_fail(self, MU_FLAG_INVALID);
flags = mu_maildir_get_flags_from_path(self->_path);
auto flags{mu_maildir_flags_from_path(self->_path)
.value_or(MessageFlags::None)};
flags |= get_content_flags(self);
/* pseudo-flag --> unread means either NEW or NOT SEEN, just
* for searching convenience */
if ((flags & MU_FLAG_NEW) || !(flags & MU_FLAG_SEEN))
flags |= MU_FLAG_UNREAD;
if (any_of(flags & MessageFlags::New) ||
none_of(flags & MessageFlags::Seen))
flags |= MessageFlags::Unread;
return flags;
}

View File

@ -19,6 +19,7 @@
#include <string.h>
#include <ctype.h>
#include "mu-message-flags.hh"
#include "mu-query-results.hh"
#include "utils/mu-str.h"
#include "mu-msg.hh"
@ -138,27 +139,19 @@ add_contacts(Sexp::List& list, MuMsg* msg)
add_list_post(list, msg);
}
typedef struct {
Sexp::List flaglist;
MuFlags msgflags;
} FlagData;
static void
each_flag(MuFlags flag, FlagData* fdata)
{
if (flag & fdata->msgflags)
fdata->flaglist.add(Sexp::make_symbol(mu_flag_name(flag)));
}
static void
add_flags(Sexp::List& list, MuMsg* msg)
{
FlagData fdata{};
fdata.msgflags = mu_msg_get_flags(msg);
Sexp::List flaglist;
const auto flags{mu_msg_get_flags(msg)};
for (auto&& info: AllMessageFlagInfos)
if (any_of(flags & info.flag))
flaglist.add(Sexp::make_symbol_sv(info.name));
mu_flags_foreach((MuFlagsForeachFunc)each_flag, &fdata);
if (!fdata.flaglist.empty())
list.add_prop(":flags", Sexp::make_list(std::move(fdata.flaglist)));
if (!flaglist.empty())
list.add_prop(":flags", Sexp::make_list(std::move(flaglist)));
}
static char*

View File

@ -20,9 +20,12 @@
#ifndef MU_MSG_HH__
#define MU_MSG_HH__
#include <mu-flags.hh>
#include <mu-msg-fields.h>
#include <utils/mu-result.hh>
#include <mu-message-flags.hh>
#include <mu-message-priority.hh>
#include <mu-msg-fields.h>
#include <utils/mu-util.h>
#include <utils/mu-utils.hh>
#include <utils/mu-option.hh>
@ -294,10 +297,10 @@ time_t mu_msg_get_date(MuMsg* msg);
*
* @param msg valid MuMsg* instance
*
* @return the file/content flags as logically OR'd #MuMsgFlags or 0
* if there are none. Non-standard flags are ignored.
* @return the file/content flags as logically OR'd #Mu::MessageFlags.
* Non-standard flags are ignored.
*/
MuFlags mu_msg_get_flags(MuMsg* msg);
MessageFlags mu_msg_get_flags(MuMsg* msg);
/**
* get the file size in bytes of this message
@ -417,39 +420,25 @@ gboolean mu_msg_is_readable(MuMsg* self);
*
* @param msg a message with an existing file system path in an actual
* maildir
* @param maildir the subdir where the message should go, relative to
* @param root_maildir_path file system path for the root-maildir for this message
* e.g., /home/user/Maildir
* @param target_maildir the subdir where the message should go, relative to
* rootmaildir. e.g. "/archive"
* @param flags to set for the target (influences the filename, path)
* @param silently ignore the src=target case (return TRUE)
* @param new_name whether to create a new unique name, or keep the
* old one
* @param err (may be NULL) may contain error information; note if the
* function return FALSE, err is not set for all error condition
* (ie. not for parameter error
* @param err receives error information
*
* @return TRUE if it worked, FALSE otherwise
*/
gboolean mu_msg_move_to_maildir(MuMsg* msg,
const char* maildir,
MuFlags flags,
gboolean ignore_dups,
gboolean new_name,
GError** err);
/**
* Tickle a message -- ie., rename a message to some new semi-random name,while
* maintaining the maildir and flags. This can be useful when dealing with
* third-party tools such as mbsync that depend on changed filenames.
*
* @param msg a message with an existing file system path in an actual
* maildir
* @param err (may be NULL) may contain error information; note if the
* function return FALSE, err is not set for all error condition
* (ie. not for parameter error
*
* @return TRUE if it worked, FALSE otherwise
*/
gboolean mu_msg_tickle(MuMsg* msg, GError** err);
bool mu_msg_move_to_maildir(MuMsg* msg,
const std::string& root_maildir_path,
const std::string& target_maildir,
MessageFlags flags,
bool ignore_dups,
bool new_name,
GError** err);
enum _MuMsgContactType { /* Reply-To:? */
MU_MSG_CONTACT_TYPE_TO = 0,
@ -545,24 +534,6 @@ void mu_msg_contact_foreach(MuMsg* msg, MuMsgContactForeachFunc func, gpointer u
const char* mu_str_display_contact_s(const char* str) G_GNUC_CONST;
char* mu_str_display_contact(const char* str) G_GNUC_WARN_UNUSED_RESULT;
/**
* get a display string for a given set of flags, OR'ed in
* @param flags; one character per flag:
* D=draft,F=flagged,N=new,P=passed,R=replied,S=seen,T=trashed
* a=has-attachment,s=signed, x=encrypted
*
* mu_str_file_flags_s returns a ptr to a static buffer,
* while mu_str_file_flags returns dynamically allocated
* memory that must be freed after use.
*
* @param flags file flags
*
* @return a string representation of the flags; see above
* for what to do with it
*/
const char* mu_str_flags_s(MuFlags flags) G_GNUC_CONST;
char* mu_str_flags(MuFlags flags) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
struct QueryMatch;
/**

View File

@ -116,13 +116,13 @@ process_value(const std::string& field, const std::string& value)
return std::string(1, value[0]);
} break;
case MU_MSG_FIELD_ID_FLAGS: {
const auto flag = mu_flag_char_from_name(value.c_str());
if (flag)
return std::string(1, tolower(flag));
} break;
case MU_MSG_FIELD_ID_FLAGS:
if (const auto info{message_flag_info(value)}; info)
return std::string(1, ::tolower(info->shortcut));
break;
default: break;
default:
break;
}
return value; // XXX prio/flags, etc. alias

View File

@ -35,6 +35,8 @@
#include <vector>
#include <xapian.h>
#include "mu-message-flags.hh"
#include "mu-msg-fields.h"
#include "mu-store.hh"
#include "mu-query.hh"
#include "utils/mu-str.h"
@ -62,6 +64,36 @@ constexpr auto DefaultMaxMessageSize = 100'000'000U;
constexpr auto ExpectedSchemaVersion = MU_STORE_SCHEMA_VERSION;
/**
* calculate a 64-bit hash for the given string, based on a combination of the
* DJB and BKDR hash functions.
*
* @param a string
*
* @return the hash
*/
size_t get_hash64 (const char* str)
{
guint32 djbhash;
guint32 bkdrhash;
guint32 bkdrseed;
guint64 hash;
djbhash = 5381;
bkdrhash = 0;
bkdrseed = 1313;
for(unsigned u = 0U; str[u]; ++u) {
djbhash = ((djbhash << 5) + djbhash) + str[u];
bkdrhash = bkdrhash * bkdrseed + str[u];
}
hash = djbhash;
return (hash<<32) | bkdrhash;
}
/* we cache these prefix strings, so we don't have to allocate them all
* the time; this should save 10-20 string allocs per message */
G_GNUC_CONST static const std::string&
@ -79,16 +111,6 @@ prefix(MuMsgFieldId mfid)
return fields[mfid];
}
static void
add_synonym_for_flag(MuFlags flag, Xapian::WritableDatabase* db)
{
static const std::string pfx(prefix(MU_MSG_FIELD_ID_FLAGS));
db->clear_synonyms(pfx + mu_flag_name(flag));
db->add_synonym(pfx + mu_flag_name(flag),
pfx + (std::string(1, (char)(tolower(mu_flag_char(flag))))));
}
struct Store::Private {
enum struct XapianOpts { ReadOnly, Open, CreateOverwrite, InMemory };
@ -207,8 +229,13 @@ struct Store::Private {
void add_synonyms()
{
mu_flags_foreach((MuFlagsForeachFunc)add_synonym_for_flag,
&writable_db());
for (auto&& info: AllMessageFlagInfos) {
const auto s1{prefix(MU_MSG_FIELD_ID_FLAGS) + std::string{info.name}};
const auto s2{prefix(MU_MSG_FIELD_ID_FLAGS) + std::string{1,info.shortcut}};
writable_db().clear_synonyms(s1);
writable_db().clear_synonyms(s2);
writable_db().add_synonym(s1, s2);
}
for (auto&& prio : AllMessagePriorities) {
const auto s1{prefix(MU_MSG_FIELD_ID_PRIO) + to_string(prio)};
@ -293,7 +320,7 @@ struct Store::Private {
static void
hash_str(char* buf, size_t buf_size, const char* data)
{
g_snprintf(buf, buf_size, "016%" PRIx64, mu_util_get_hash(data));
g_snprintf(buf, buf_size, "016%" PRIx64, get_hash64(data));
}
static std::string
@ -687,45 +714,6 @@ add_terms_values_size(Xapian::Document& doc, MuMsg* msg, MuMsgFieldId mfid)
doc.add_value((Xapian::valueno)mfid, szstr);
}
G_GNUC_CONST
static const std::string&
flag_val(char flagchar)
{
static const std::string pfx(prefix(MU_MSG_FIELD_ID_FLAGS)),
draftstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_DRAFT))),
flaggedstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_FLAGGED))),
passedstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_PASSED))),
repliedstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_REPLIED))),
seenstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_SEEN))),
trashedstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_TRASHED))),
newstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_NEW))),
signedstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_SIGNED))),
cryptstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_ENCRYPTED))),
attachstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_HAS_ATTACH))),
unreadstr(pfx + (char)tolower(mu_flag_char(MU_FLAG_UNREAD))),
liststr(pfx + (char)tolower(mu_flag_char(MU_FLAG_LIST)));
switch (flagchar) {
case 'D': return draftstr;
case 'F': return flaggedstr;
case 'P': return passedstr;
case 'R': return repliedstr;
case 'S': return seenstr;
case 'T': return trashedstr;
case 'N': return newstr;
case 'z': return signedstr;
case 'x': return cryptstr;
case 'a': return attachstr;
case 'l': return liststr;
case 'u': return unreadstr;
default: g_return_val_if_reached(flaggedstr); return flaggedstr;
}
}
static const std::string&
prio_val(MessagePriority prio)
{
@ -760,13 +748,12 @@ add_terms_values_number(Xapian::Document& doc, MuMsg* msg, MuMsgFieldId mfid)
doc.add_value((Xapian::valueno)mfid, numstr);
if (mfid == MU_MSG_FIELD_ID_FLAGS) {
const char* cur = mu_flags_to_str_s((MuFlags)num, (MuFlagType)MU_FLAG_TYPE_ANY);
g_return_if_fail(cur);
while (*cur) {
add_term(doc, flag_val(*cur));
++cur;
static const std::string pfx(prefix(MU_MSG_FIELD_ID_FLAGS));
const auto flags{static_cast<MessageFlags>(num)};
for (auto&& info: AllMessageFlagInfos) {
if (any_of(info.flag & flags))
add_term(doc, pfx + static_cast<char>(::tolower(info.shortcut)));
}
} else if (mfid == MU_MSG_FIELD_ID_PRIO)
add_term(doc, prio_val(static_cast<MessagePriority>(num)));
}
@ -893,7 +880,7 @@ add_terms_values_attach(Xapian::Document& doc, MuMsg* msg, MuMsgFieldId mfid)
static void
add_terms_values_body(Xapian::Document& doc, MuMsg* msg, MuMsgFieldId mfid)
{
if (mu_msg_get_flags(msg) & MU_FLAG_ENCRYPTED)
if (any_of(mu_msg_get_flags(msg) & MessageFlags::Encrypted))
return; /* ignore encrypted bodies */
auto str = mu_msg_get_body_text(msg, MU_MSG_OPTION_NONE);

View File

@ -43,11 +43,6 @@ test('test_query',
'test-query.cc',
install: false,
dependencies: [glib_dep, lib_mu_dep, lib_test_mu_common_dep]))
test('test_flags',
executable('test-flags',
'test-mu-flags.cc',
install: false,
dependencies: [glib_dep, lib_mu_dep, lib_test_mu_common_dep]))
test('test_tokenizer',
executable('test-tokenizer',

View File

@ -145,7 +145,8 @@ test_mu_msg_02(void)
i = 0;
mu_msg_contact_foreach(msg, (MuMsgContactForeachFunc)check_contact_02, &i);
g_assert_cmpint(i, ==, 2);
g_assert_cmpuint(mu_msg_get_flags(msg), ==, MU_FLAG_SEEN | MU_FLAG_LIST);
g_print("flags: %s\n", Mu::message_flags_to_string(mu_msg_get_flags(msg)).c_str());
g_assert_true(mu_msg_get_flags(msg) == (MessageFlags::Seen|MessageFlags::MailingList));
mu_msg_unref(msg);
}
@ -173,9 +174,7 @@ test_mu_msg_03(void)
g_assert_cmpstr((char*)params->data, ==, "charset");
params = g_slist_next(params);
g_assert_cmpstr((char*)params->data, ==, "UTF-8");
g_assert_cmpuint(mu_msg_get_flags(msg), ==, MU_FLAG_UNREAD); /* not seen => unread */
g_assert_true(mu_msg_get_flags(msg) == (MessageFlags::Unread));
mu_msg_unref(msg);
}
@ -191,7 +190,11 @@ test_mu_msg_04(void)
g_assert_true(mu_msg_get_prio(msg) /* 'low' */
== Mu::MessagePriority::Normal);
g_assert_cmpuint(mu_msg_get_date(msg), ==, 0);
g_assert_cmpuint(mu_msg_get_flags(msg), ==, MU_FLAG_HAS_ATTACH | MU_FLAG_UNREAD);
g_assert_true(mu_msg_get_flags(msg) ==
(MessageFlags::HasAttachment|MessageFlags::Unread));
g_assert_true(mu_msg_get_flags(msg) ==
(MessageFlags::HasAttachment|MessageFlags::Unread));
mu_msg_unref(msg);
}
@ -204,9 +207,9 @@ test_mu_msg_multimime(void)
/* ie., are text parts properly concatenated? */
g_assert_cmpstr(mu_msg_get_subject(msg), ==, "multimime");
g_assert_cmpstr(mu_msg_get_body_text(msg, MU_MSG_OPTION_NONE), ==, "abcdef");
g_assert_cmpuint(mu_msg_get_flags(msg),
==,
(MuFlags)(MU_FLAG_FLAGGED | MU_FLAG_SEEN | MU_FLAG_HAS_ATTACH));
g_assert_true(mu_msg_get_flags(msg) ==
(MessageFlags::HasAttachment|MessageFlags::Flagged|MessageFlags::Seen));
mu_msg_unref(msg);
}
@ -216,29 +219,21 @@ test_mu_msg_flags(void)
unsigned u;
struct {
const char* path;
MuFlags flags;
const char* path;
MessageFlags flags;
} msgflags[] = {{MU_TESTMAILDIR4 "/multimime!2,FS",
(MuFlags)(MU_FLAG_FLAGGED | MU_FLAG_SEEN | MU_FLAG_HAS_ATTACH)},
{MU_TESTMAILDIR4 "/special!2,Sabc", MU_FLAG_SEEN}
(MessageFlags::Flagged | MessageFlags::Seen |
MessageFlags::HasAttachment)},
{MU_TESTMAILDIR4 "/special!2,Sabc",
(MessageFlags::Seen|MessageFlags::HasAttachment)}
};
for (u = 0; u != G_N_ELEMENTS(msgflags); ++u) {
MuMsg* msg;
MuFlags flags;
g_assert((msg = get_msg(msgflags[u].path)));
flags = mu_msg_get_flags(msg);
if (g_test_verbose())
g_print("=> %s [ %s, %u] <=> [ %s, %u]\n",
msgflags[u].path,
mu_flags_to_str_s(msgflags[u].flags, MU_FLAG_TYPE_ANY),
(unsigned)msgflags[u].flags,
mu_flags_to_str_s(flags, MU_FLAG_TYPE_ANY),
(unsigned)flags);
g_assert_cmpuint(flags, ==, msgflags[u].flags);
const auto flags{mu_msg_get_flags(msg)};
//g_print("flags: %s\n", Mu::message_flags_to_string(flags).c_str());
g_assert_true(flags == msgflags[u].flags);
mu_msg_unref(msg);
}
}