streamline pretty-printing of message flags

wrap make_flags() into fmt_flags() which returns a (struct-wrapped)
string, so the calls can be inlined into the printf statements, without
reserving buffers.

we locally force optimization, so copy elision is always done, as debug
builds would otherwise suffer a somewhat unreasonable performance hit.
This commit is contained in:
Oswald Buddenhagen 2022-06-15 17:17:23 +02:00
parent a5dc1baedf
commit a49017f481
6 changed files with 25 additions and 32 deletions

View File

@ -53,10 +53,12 @@ typedef unsigned long ulong;
# define ATTR_UNUSED __attribute__((unused)) # define ATTR_UNUSED __attribute__((unused))
# define ATTR_NORETURN __attribute__((noreturn)) # define ATTR_NORETURN __attribute__((noreturn))
# define ATTR_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var))) # define ATTR_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var)))
# define ATTR_OPTIMIZE __attribute__((optimize("2")))
#else #else
# define ATTR_UNUSED # define ATTR_UNUSED
# define ATTR_NORETURN # define ATTR_NORETURN
# define ATTR_PRINTFLIKE(fmt,var) # define ATTR_PRINTFLIKE(fmt,var)
# define ATTR_OPTIMIZE
#endif #endif
#if defined(__clang__) #if defined(__clang__)

View File

@ -21,7 +21,7 @@ cleanup_drivers( void )
// Keep the MESSAGE_FLAGS in sync (grep that)! // Keep the MESSAGE_FLAGS in sync (grep that)!
const char MsgFlags[] = { 'D', 'F', 'P', 'R', 'S', 'T' }; const char MsgFlags[] = { 'D', 'F', 'P', 'R', 'S', 'T' };
void static void
make_flags( uchar flags, char *buf ) make_flags( uchar flags, char *buf )
{ {
uint i, d; uint i, d;
@ -32,6 +32,15 @@ make_flags( uchar flags, char *buf )
buf[d] = 0; buf[d] = 0;
} }
flag_str_t
fmt_flags( uchar flags )
{
flag_str_t buf;
make_flags( flags, buf.str );
return buf;
}
uint uint
count_generic_messages( message_t *msgs ) count_generic_messages( message_t *msgs )
{ {

View File

@ -46,7 +46,8 @@ BIT_ENUM(
) )
extern const char MsgFlags[F__NUM_BITS]; extern const char MsgFlags[F__NUM_BITS];
void make_flags( uchar flags, char *buf ); typedef struct { char str[F__NUM_BITS + 1]; } flag_str_t;
flag_str_t ATTR_OPTIMIZE /* force RVO */ fmt_flags( uchar flags );
/* For message->status */ /* For message->status */
BIT_ENUM( BIT_ENUM(

View File

@ -198,7 +198,6 @@ proxy_do_@name@_cb( gen_cmd_t *gcmd )
{ {
@name@_cmd_t *cmd = (@name@_cmd_t *)gcmd; @name@_cmd_t *cmd = (@name@_cmd_t *)gcmd;
@pre_print_cb_args@
debug( "%s[% 2d] Callback enter @name@@print_fmt_cb_args@\n", cmd->ctx->label, cmd->tag@print_pass_cb_args@ ); debug( "%s[% 2d] Callback enter @name@@print_fmt_cb_args@\n", cmd->ctx->label, cmd->tag@print_pass_cb_args@ );
@print_cb_args@ @print_cb_args@
cmd->callback( @pass_cb_args@cmd->callback_aux ); cmd->callback( @pass_cb_args@cmd->callback_aux );
@ -257,10 +256,9 @@ static @type@proxy_@name@( store_t *gctx@decl_args@, void (*cb)( @decl_cb_args@v
//# DEFINE load_box_print_pass_cb_args , cmd->sts, cmd->total_msgs, cmd->recent_msgs //# DEFINE load_box_print_pass_cb_args , cmd->sts, cmd->total_msgs, cmd->recent_msgs
//# DEFINE load_box_print_cb_args //# DEFINE load_box_print_cb_args
if (cmd->sts == DRV_OK) { if (cmd->sts == DRV_OK) {
char fbuf[as(MsgFlags) + 1];
for (message_t *msg = cmd->msgs; msg; msg = msg->next) for (message_t *msg = cmd->msgs; msg; msg = msg->next)
debug( " uid=%-5u flags=%-4s size=%-6u tuid=%." stringify(TUIDL) "s\n", debug( " uid=%-5u flags=%-4s size=%-6u tuid=%." stringify(TUIDL) "s\n",
msg->uid, (msg->status & M_FLAGS) ? (make_flags( msg->flags, fbuf ), fbuf) : "?", msg->size, *msg->tuid ? msg->tuid : "?" ); msg->uid, (msg->status & M_FLAGS) ? fmt_flags( msg->flags ).str : "?", msg->size, *msg->tuid ? msg->tuid : "?" );
} }
//# END //# END
@ -281,12 +279,8 @@ static @type@proxy_@name@( store_t *gctx@decl_args@, void (*cb)( @decl_cb_args@v
//# END //# END
//# DEFINE fetch_msg_print_fmt_args , uid=%u, want_flags=%s, want_date=%s //# DEFINE fetch_msg_print_fmt_args , uid=%u, want_flags=%s, want_date=%s
//# DEFINE fetch_msg_print_pass_args , msg->uid, !(msg->status & M_FLAGS) ? "yes" : "no", data->date ? "yes" : "no" //# DEFINE fetch_msg_print_pass_args , msg->uid, !(msg->status & M_FLAGS) ? "yes" : "no", data->date ? "yes" : "no"
//# DEFINE fetch_msg_pre_print_cb_args
char fbuf[as(MsgFlags) + 1];
make_flags( cmd->data->flags, fbuf );
//# END
//# DEFINE fetch_msg_print_fmt_cb_args , flags=%s, date=%lld, size=%u //# DEFINE fetch_msg_print_fmt_cb_args , flags=%s, date=%lld, size=%u
//# DEFINE fetch_msg_print_pass_cb_args , fbuf, (long long)cmd->data->date, cmd->data->len //# DEFINE fetch_msg_print_pass_cb_args , fmt_flags( cmd->data->flags ).str, (long long)cmd->data->date, cmd->data->len
//# DEFINE fetch_msg_print_cb_args //# DEFINE fetch_msg_print_cb_args
if (cmd->sts == DRV_OK && (DFlags & DEBUG_DRV_ALL)) { if (cmd->sts == DRV_OK && (DFlags & DEBUG_DRV_ALL)) {
printf( "%s=========\n", cmd->ctx->label ); printf( "%s=========\n", cmd->ctx->label );
@ -296,12 +290,8 @@ static @type@proxy_@name@( store_t *gctx@decl_args@, void (*cb)( @decl_cb_args@v
} }
//# END //# END
//# DEFINE store_msg_pre_print_args
char fbuf[as(MsgFlags) + 1];
make_flags( data->flags, fbuf );
//# END
//# DEFINE store_msg_print_fmt_args , flags=%s, date=%lld, size=%u, to_trash=%s //# DEFINE store_msg_print_fmt_args , flags=%s, date=%lld, size=%u, to_trash=%s
//# DEFINE store_msg_print_pass_args , fbuf, (long long)data->date, data->len, to_trash ? "yes" : "no" //# DEFINE store_msg_print_pass_args , fmt_flags( data->flags ).str, (long long)data->date, data->len, to_trash ? "yes" : "no"
//# DEFINE store_msg_print_args //# DEFINE store_msg_print_args
if (DFlags & DEBUG_DRV_ALL) { if (DFlags & DEBUG_DRV_ALL) {
printf( "%s>>>>>>>>>\n", ctx->label ); printf( "%s>>>>>>>>>\n", ctx->label );
@ -311,13 +301,8 @@ static @type@proxy_@name@( store_t *gctx@decl_args@, void (*cb)( @decl_cb_args@v
} }
//# END //# END
//# DEFINE set_msg_flags_pre_print_args
char fbuf1[as(MsgFlags) + 1], fbuf2[as(MsgFlags) + 1];
make_flags( add, fbuf1 );
make_flags( del, fbuf2 );
//# END
//# DEFINE set_msg_flags_print_fmt_args , uid=%u, add=%s, del=%s //# DEFINE set_msg_flags_print_fmt_args , uid=%u, add=%s, del=%s
//# DEFINE set_msg_flags_print_pass_args , uid, fbuf1, fbuf2 //# DEFINE set_msg_flags_print_pass_args , uid, fmt_flags( add ).str, fmt_flags( del ).str
//# DEFINE set_msg_flags_checked sts == DRV_OK //# DEFINE set_msg_flags_checked sts == DRV_OK
//# DEFINE trash_msg_print_fmt_args , uid=%u //# DEFINE trash_msg_print_fmt_args , uid=%u

View File

@ -71,9 +71,8 @@ sanitize_flags( uchar tflags, sync_vars_t *svars, int t )
// each mailbox can support different flags according to the IMAP spec. // each mailbox can support different flags according to the IMAP spec.
uchar bflags = tflags & ~(svars->good_flags[t] | svars->bad_flags[t]); uchar bflags = tflags & ~(svars->good_flags[t] | svars->bad_flags[t]);
if (bflags) { if (bflags) {
char bfbuf[16]; notice( "Notice: %s store does not support flag(s) '%s'; not propagating.\n",
make_flags( bflags, bfbuf ); str_fn[t], fmt_flags( bflags ).str );
notice( "Notice: %s store does not support flag(s) '%s'; not propagating.\n", str_fn[t], bfbuf );
svars->bad_flags[t] |= bflags; svars->bad_flags[t] |= bflags;
} }
} }
@ -1014,11 +1013,9 @@ box_loaded( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux
} }
srec->aflags[t] = sflags & ~srec->flags; srec->aflags[t] = sflags & ~srec->flags;
srec->dflags[t] = ~sflags & srec->flags; srec->dflags[t] = ~sflags & srec->flags;
if ((DFlags & DEBUG_SYNC) && (srec->aflags[t] || srec->dflags[t])) { if (srec->aflags[t] || srec->dflags[t]) {
char afbuf[16], dfbuf[16]; /* enlarge when support for keywords is added */ debug( " %sing flags: +%s -%s\n", str_hl[t],
make_flags( srec->aflags[t], afbuf ); fmt_flags( srec->aflags[t] ).str, fmt_flags( srec->dflags[t] ).str );
make_flags( srec->dflags[t], dfbuf );
debug( " %sing flags: +%s -%s\n", str_hl[t], afbuf, dfbuf );
} }
} }
} }

View File

@ -467,11 +467,10 @@ save_state( sync_vars_t *svars )
for (sync_rec_t *srec = svars->srecs; srec; srec = srec->next) { for (sync_rec_t *srec = svars->srecs; srec; srec = srec->next) {
if (srec->status & S_DEAD) if (srec->status & S_DEAD)
continue; continue;
char fbuf[16]; // enlarge when support for keywords is added
make_flags( srec->flags, fbuf );
Fprintf( svars->nfp, "%u %u %s%s%s\n", srec->uid[F], srec->uid[N], Fprintf( svars->nfp, "%u %u %s%s%s\n", srec->uid[F], srec->uid[N],
(srec->status & S_DUMMY(F)) ? "<" : (srec->status & S_DUMMY(N)) ? ">" : "", (srec->status & S_DUMMY(F)) ? "<" : (srec->status & S_DUMMY(N)) ? ">" : "",
(srec->status & S_SKIPPED) ? "^" : (srec->status & S_EXPIRED) ? "~" : "", fbuf ); (srec->status & S_SKIPPED) ? "^" : (srec->status & S_EXPIRED) ? "~" : "",
fmt_flags( srec->flags ).str );
} }
Fclose( svars->nfp, 1 ); Fclose( svars->nfp, 1 );