isync

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

commit 17db5de0cadf15dd52ebead3e45a0507e8c774c9
parent c902f69c6fe0814f9f536a3e84d3f186ddef91d1
Author: Oswald Buddenhagen <ossi@users.sf.net>
Date:   Thu, 23 Dec 2021 17:43:59 +0100

add debug pretty-printing for sync record status flags as well

Diffstat:
Msrc/bit_enum_gen.pl | 19+++++++++++++++++--
Msrc/common.h | 24++++++++++++++++++++++++
Msrc/sync_state.c | 9+++++----
Msrc/util.c | 15+++++++++++++++
4 files changed, 61 insertions(+), 6 deletions(-)

diff --git a/src/bit_enum_gen.pl b/src/bit_enum_gen.pl @@ -18,22 +18,33 @@ while (<>) { $conts =~ s/\s//g; $conts =~ s/,$//; my @vals = split(/,/, $conts); - my $pfx; + my ($pfx, $pfx1); for my $e (@vals) { if (!defined($pfx)) { - $pfx = ($e =~ /^([A-Z]+_)/) ? $1 : ""; + $pfx1 = $pfx = ($e =~ /^([A-Z]+_)/) ? $1 : ""; } elsif (length($pfx)) { $pfx = "" if ((($e =~ /^([A-Z]+_)/) ? $1 : "") ne $pfx); } } my $bit = 1; my $bitn = 0; + my (@names, @nameos); + my $nameo = 0; for my $e (@vals) { my $bits = ($e =~ s/\((\d+)\)$//) ? $1 : 1; + my $n = substr($e, length($pfx)); if ($bits != 1) { + die("Unsupported field size $bits\n") if ($bits != 2); print "#define $e(b) ($bit << (b))\n"; + push @names, "F-".$n, "N-".$n; + my $nl = length($n) + 3; + push @nameos, $nameo, $nameo + $nl; + $nameo += $nl * 2; } else { print "#define $e $bit\n"; + push @names, $n; + push @nameos, $nameo; + $nameo += length($n) + 1; } $bit <<= $bits; $bitn += $bits; @@ -41,6 +52,10 @@ while (<>) { if (length($pfx)) { print "#define ${pfx}_NUM_BITS $bitn\n"; } + if (length($pfx1)) { + print "#define ${pfx1}_STRINGS \"".join("\\0", @names)."\"\n"; + print "#define ${pfx1}_OFFSETS ".join(", ", @nameos)."\n"; + } print "\n"; $in_enum = 0; } else { diff --git a/src/common.h b/src/common.h @@ -193,6 +193,30 @@ int equals( const char *str, int strl, const char *cmp, uint cmpl ); time_t timegm( struct tm *tm ); #endif +void fmt_bits( uint bits, uint num_bits, const char *bit_str, const int *bit_off, char *buf ); + +#define BIT_FORMATTER_RET(name, pfx) \ + struct name##_str { char str[sizeof(pfx##__STRINGS)]; }; + +#define BIT_FORMATTER_PROTO(name, pfx, storage) \ + storage struct name##_str ATTR_OPTIMIZE /* force RVO */ \ + fmt_##name( uint bits ) + +#define BIT_FORMATTER_IMPL(name, pfx, storage) \ + BIT_FORMATTER_PROTO(name, pfx, storage) \ + { \ + static const char strings[] = pfx##__STRINGS; \ + static const int offsets[] = { pfx##__OFFSETS }; \ + \ + struct name##_str buf; \ + fmt_bits( bits, as(offsets), strings, offsets, buf.str ); \ + return buf; \ + } + +#define BIT_FORMATTER_FUNCTION(name, pfx) \ + BIT_FORMATTER_RET(name, pfx) \ + BIT_FORMATTER_IMPL(name, pfx, static) + void *nfmalloc( size_t sz ); void *nfzalloc( size_t sz ); void *nfrealloc( void *mem, size_t sz ); diff --git a/src/sync_state.c b/src/sync_state.c @@ -17,6 +17,8 @@ const char *str_fn[] = { "far side", "near side" }, *str_hl[] = { "push", "pull" }; +BIT_FORMATTER_FUNCTION(sts, S) + static char * clean_strdup( const char *s ) { @@ -208,9 +210,8 @@ load_state( sync_vars_t *svars ) srec->status = S_SKIPPED; } srec->flags = parse_flags( s ); - debug( " entry (%u,%u,%s,%s%s)\n", srec->uid[F], srec->uid[N], fmt_flags( srec->flags ).str, - (srec->status & S_SKIPPED) ? "SKIP" : (srec->status & S_EXPIRED) ? "XPIRE" : "", - (srec->status & S_DUMMY(F)) ? ",F-DUMMY" : (srec->status & S_DUMMY(N)) ? ",N-DUMMY" : "" ); + debug( " entry (%u,%u,%s,%s)\n", srec->uid[F], srec->uid[N], + fmt_flags( srec->flags ).str, fmt_sts( srec->status ).str ); *svars->srecadd = srec; svars->srecadd = &srec->next; svars->nsrecs++; @@ -384,7 +385,7 @@ load_state( sync_vars_t *svars ) srec->status = (srec->status & ~S_LOGGED) | t3; if ((srec->status & S_EXPIRED) && svars->maxxfuid < srec->uid[F]) svars->maxxfuid = srec->uid[F]; - debug( "status now %#x\n", srec->status ); + debug( "status now %s\n", fmt_sts( srec->status ).str ); break; case '_': debug( "has placeholder now\n" ); diff --git a/src/util.c b/src/util.c @@ -379,6 +379,21 @@ timegm( struct tm *t ) #endif void +fmt_bits( uint bits, uint num_bits, const char *bit_str, const int *bit_off, char *buf ) +{ + uint d = 0; + for (uint i = 0, val = 1; i < num_bits; i++, val <<= 1) { + if (bits & val) { + if (d) + buf[d++] = ','; + for (const char *s = bit_str + bit_off[i]; *s; s++) + buf[d++] = *s; + } + } + buf[d] = 0; +} + +void oob( void ) { fputs( "Fatal: buffer too small. Please report a bug.\n", stderr );