isync

mailbox synchronization program
git clone https://git.code.sf.net/p/isync/isync
Log | Files | Refs | README | LICENSE

commit a49017f481a7da71af1bcfdad8f9a517f88ac1e0
parent a5dc1baedf7d486b15554575f695b8a513a60364
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date:   Wed, 15 Jun 2022 17:17:23 +0200

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.

Diffstat:
Msrc/common.h | 2++
Msrc/driver.c | 11++++++++++-
Msrc/driver.h | 3++-
Msrc/drv_proxy.c | 23++++-------------------
Msrc/sync.c | 13+++++--------
Msrc/sync_state.c | 5++---
6 files changed, 25 insertions(+), 32 deletions(-)

diff --git a/src/common.h b/src/common.h @@ -53,10 +53,12 @@ typedef unsigned long ulong; # define ATTR_UNUSED __attribute__((unused)) # define ATTR_NORETURN __attribute__((noreturn)) # define ATTR_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var))) +# define ATTR_OPTIMIZE __attribute__((optimize("2"))) #else # define ATTR_UNUSED # define ATTR_NORETURN # define ATTR_PRINTFLIKE(fmt,var) +# define ATTR_OPTIMIZE #endif #if defined(__clang__) diff --git a/src/driver.c b/src/driver.c @@ -21,7 +21,7 @@ cleanup_drivers( void ) // Keep the MESSAGE_FLAGS in sync (grep that)! const char MsgFlags[] = { 'D', 'F', 'P', 'R', 'S', 'T' }; -void +static void make_flags( uchar flags, char *buf ) { uint i, d; @@ -32,6 +32,15 @@ make_flags( uchar flags, char *buf ) buf[d] = 0; } +flag_str_t +fmt_flags( uchar flags ) +{ + flag_str_t buf; + + make_flags( flags, buf.str ); + return buf; +} + uint count_generic_messages( message_t *msgs ) { diff --git a/src/driver.h b/src/driver.h @@ -46,7 +46,8 @@ BIT_ENUM( ) 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 */ BIT_ENUM( diff --git a/src/drv_proxy.c b/src/drv_proxy.c @@ -198,7 +198,6 @@ proxy_do_@name@_cb( gen_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@ ); @print_cb_args@ 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_cb_args if (cmd->sts == DRV_OK) { - char fbuf[as(MsgFlags) + 1]; for (message_t *msg = cmd->msgs; msg; msg = msg->next) 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 @@ -281,12 +279,8 @@ static @type@proxy_@name@( store_t *gctx@decl_args@, void (*cb)( @decl_cb_args@v //# END //# 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_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_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 if (cmd->sts == DRV_OK && (DFlags & DEBUG_DRV_ALL)) { 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 -//# 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_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 if (DFlags & DEBUG_DRV_ALL) { 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 -//# 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_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 trash_msg_print_fmt_args , uid=%u diff --git a/src/sync.c b/src/sync.c @@ -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. uchar bflags = tflags & ~(svars->good_flags[t] | svars->bad_flags[t]); if (bflags) { - char bfbuf[16]; - make_flags( bflags, bfbuf ); - notice( "Notice: %s store does not support flag(s) '%s'; not propagating.\n", str_fn[t], bfbuf ); + notice( "Notice: %s store does not support flag(s) '%s'; not propagating.\n", + str_fn[t], fmt_flags( bflags ).str ); 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->dflags[t] = ~sflags & srec->flags; - if ((DFlags & DEBUG_SYNC) && (srec->aflags[t] || srec->dflags[t])) { - char afbuf[16], dfbuf[16]; /* enlarge when support for keywords is added */ - make_flags( srec->aflags[t], afbuf ); - make_flags( srec->dflags[t], dfbuf ); - debug( " %sing flags: +%s -%s\n", str_hl[t], afbuf, dfbuf ); + if (srec->aflags[t] || srec->dflags[t]) { + debug( " %sing flags: +%s -%s\n", str_hl[t], + fmt_flags( srec->aflags[t] ).str, fmt_flags( srec->dflags[t] ).str ); } } } diff --git a/src/sync_state.c b/src/sync_state.c @@ -467,11 +467,10 @@ save_state( sync_vars_t *svars ) for (sync_rec_t *srec = svars->srecs; srec; srec = srec->next) { if (srec->status & S_DEAD) 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], (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 );