commit 7b567164fff524b8d9ddbe09a8ffa78f66c6f8b5
Author: Oswald Buddenhagen <o...@users.sf.net>
Date:   Fri Nov 4 21:48:58 2016 +0100

    abstract growable arrays somewhat
    
    ... and sneak in a C99 requirement on the way. just because.

 configure.ac      |    4 +-
 src/common.h      |   31 ++++++++++++++++-
 src/driver.h      |    2 +-
 src/drv_imap.c    |   18 +++++-----
 src/drv_maildir.c |   83 ++++++++++++++++++++------------------------
 src/sync.c        |   27 ++++++---------
 src/util.c        |    4 +-
 7 files changed, 93 insertions(+), 76 deletions(-)

diff --git a/configure.ac b/configure.ac
index b103f71..2eab91a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4,9 +4,9 @@ AM_INIT_AUTOMAKE
 
 AM_MAINTAINER_MODE
 
-AC_PROG_CC
+AC_PROG_CC_C99
 if test "$GCC" = yes; then
-    CFLAGS="$CFLAGS -pipe -W -Wall -Wshadow -Wstrict-prototypes -ansi 
-pedantic -Wno-overlength-strings"
+    CFLAGS="$CFLAGS -pipe -W -Wall -Wshadow -Wstrict-prototypes -std=c99 
-pedantic -Wno-overlength-strings"
 fi
 
 CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
diff --git a/src/common.h b/src/common.h
index 18390f3..a2f80de 100644
--- a/src/common.h
+++ b/src/common.h
@@ -43,10 +43,12 @@ typedef unsigned int uint;
 # define ATTR_UNUSED __attribute__((unused))
 # define ATTR_NORETURN __attribute__((noreturn))
 # define ATTR_PRINTFLIKE(fmt,var) __attribute__((format(printf,fmt,var)))
+# define ATTR_PACKED(ref) __attribute__((packed,aligned(sizeof(ref))))
 #else
 # define ATTR_UNUSED
 # define ATTR_NORETURN
 # define ATTR_PRINTFLIKE(fmt,var)
+# define ATTR_PACKED(ref)
 #endif
 
 #ifdef __GNUC__
@@ -137,7 +139,34 @@ char *expand_strdup( const char *s );
 
 int map_name( const char *arg, char **result, int reserve, const char *in, 
const char *out );
 
-void sort_ints( int *arr, int len );
+#define DEFINE_ARRAY_TYPE(T) \
+       typedef struct T##_array { \
+               T *data; \
+               int size; \
+       } ATTR_PACKED(T *) T##_array_t; \
+       typedef struct T##_array_alloc { \
+               T##_array_t array; \
+               int alloc; \
+       } ATTR_PACKED(T *) T##_array_alloc_t; \
+       static INLINE T *T##_array_append( T##_array_alloc_t *arr ) \
+       { \
+               if (arr->array.size == arr->alloc) { \
+                       arr->alloc = arr->alloc * 2 + 100; \
+                       arr->array.data = nfrealloc( arr->array.data, 
arr->alloc * sizeof(T) ); \
+               } \
+               return &arr->array.data[arr->array.size++]; \
+       }
+
+#define ARRAY_INIT(arr) \
+       do { (arr)->array.data = 0; (arr)->array.size = (arr)->alloc = 0; } 
while (0)
+
+#define ARRAY_SQUEEZE(arr) \
+       do { \
+               (arr)->data = nfrealloc( (arr)->data, (arr)->size * 
sizeof((arr)->data[0]) ); \
+       } while (0)
+
+DEFINE_ARRAY_TYPE(int)
+void sort_int_array( int_array_t array );
 
 void arc4_init( void );
 uchar arc4_getbyte( void );
diff --git a/src/driver.h b/src/driver.h
index 1abf671..42000e8 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -207,7 +207,7 @@ struct driver {
         * and those named in the excs array (smaller than minuid).
         * The driver takes ownership of the excs array. Messages below newuid 
do not need
         * to have the TUID populated even if OPEN_FIND is set. */
-       void (*load_box)( store_t *ctx, int minuid, int maxuid, int newuid, int 
*excs, int nexcs,
+       void (*load_box)( store_t *ctx, int minuid, int maxuid, int newuid, 
int_array_t excs,
                          void (*cb)( int sts, void *aux ), void *aux );
 
        /* Fetch the contents and flags of the given message from the current 
mailbox. */
diff --git a/src/drv_imap.c b/src/drv_imap.c
index 4911f18..e2ae985 100644
--- a/src/drv_imap.c
+++ b/src/drv_imap.c
@@ -2292,7 +2292,7 @@ imap_prepare_load_box( store_t *gctx, int opts )
 static void imap_submit_load( imap_store_t *, const char *, int, struct 
imap_cmd_refcounted_state * );
 
 static void
-imap_load_box( store_t *gctx, int minuid, int maxuid, int newuid, int *excs, 
int nexcs,
+imap_load_box( store_t *gctx, int minuid, int maxuid, int newuid, int_array_t 
excs,
                void (*cb)( int sts, void *aux ), void *aux )
 {
        imap_store_t *ctx = (imap_store_t *)gctx;
@@ -2300,21 +2300,21 @@ imap_load_box( store_t *gctx, int minuid, int maxuid, 
int newuid, int *excs, int
        char buf[1000];
 
        if (!ctx->gen.count) {
-               free( excs );
+               free( excs.data );
                cb( DRV_OK, aux );
        } else {
                struct imap_cmd_refcounted_state *sts = 
imap_refcounted_new_state( cb, aux );
 
-               sort_ints( excs, nexcs );
-               for (i = 0; i < nexcs; ) {
-                       for (bl = 0; i < nexcs && bl < 960; i++) {
+               sort_int_array( excs );
+               for (i = 0; i < excs.size; ) {
+                       for (bl = 0; i < excs.size && bl < 960; i++) {
                                if (bl)
                                        buf[bl++] = ',';
-                               bl += sprintf( buf + bl, "%d", excs[i] );
+                               bl += sprintf( buf + bl, "%d", excs.data[i] );
                                j = i;
-                               for (; i + 1 < nexcs && excs[i + 1] == excs[i] 
+ 1; i++) {}
+                               for (; i + 1 < excs.size && excs.data[i + 1] == 
excs.data[i] + 1; i++) {}
                                if (i != j)
-                                       bl += sprintf( buf + bl, ":%d", excs[i] 
);
+                                       bl += sprintf( buf + bl, ":%d", 
excs.data[i] );
                        }
                        imap_submit_load( ctx, buf, 0, sts );
                }
@@ -2333,7 +2333,7 @@ imap_load_box( store_t *gctx, int minuid, int maxuid, int 
newuid, int *excs, int
                        imap_submit_load( ctx, buf, (ctx->gen.opts & 
OPEN_FIND), sts );
                }
          done:
-               free( excs );
+               free( excs.data );
                imap_refcounted_done( sts );
        }
 }
diff --git a/src/drv_maildir.c b/src/drv_maildir.c
index f97ac82..6e99d22 100644
--- a/src/drv_maildir.c
+++ b/src/drv_maildir.c
@@ -70,7 +70,8 @@ typedef struct maildir_message {
 typedef struct maildir_store {
        store_t gen;
        int uvfd, uvok, nuid, is_inbox, fresh[3];
-       int minuid, maxuid, newuid, nexcs, *excs;
+       int minuid, maxuid, newuid;
+       int_array_t excs;
        char *trash;
 #ifdef USE_DB
        DB *db;
@@ -262,7 +263,7 @@ maildir_cleanup( store_t *gctx )
        free( ctx->usedb );
 #endif /* USE_DB */
        free( gctx->path );
-       free( ctx->excs );
+       free( ctx->excs.data );
        if (ctx->uvfd >= 0)
                close( ctx->uvfd );
        conf_wakeup( &ctx->lcktmr, -1 );
@@ -446,20 +447,17 @@ typedef struct {
        char tuid[TUIDL];
 } msg_t;
 
-typedef struct {
-       msg_t *ents;
-       int nents, nalloc;
-} msglist_t;
+DEFINE_ARRAY_TYPE(msg_t)
 
 static void
-maildir_free_scan( msglist_t *msglist )
+maildir_free_scan( msg_t_array_alloc_t *msglist )
 {
        int i;
 
-       if (msglist->ents) {
-               for (i = 0; i < msglist->nents; i++)
-                       free( msglist->ents[i].base );
-               free( msglist->ents );
+       if (msglist->array.data) {
+               for (i = 0; i < msglist->array.size; i++)
+                       free( msglist->array.data[i].base );
+               free( msglist->array.data );
        }
 }
 
@@ -821,7 +819,7 @@ maildir_compare( const void *l, const void *r )
 }
 
 static int
-maildir_scan( maildir_store_t *ctx, msglist_t *msglist )
+maildir_scan( maildir_store_t *ctx, msg_t_array_alloc_t *msglist )
 {
        maildir_store_conf_t *conf = (maildir_store_conf_t *)ctx->gen.conf;
        DIR *d;
@@ -839,8 +837,7 @@ maildir_scan( maildir_store_t *ctx, msglist_t *msglist )
        char buf[_POSIX_PATH_MAX], nbuf[_POSIX_PATH_MAX];
 
   again:
-       msglist->ents = 0;
-       msglist->nents = msglist->nalloc = 0;
+       ARRAY_INIT( msglist );
        ctx->gen.count = ctx->gen.recent = 0;
        if (ctx->uvok || ctx->maxuid == INT_MAX) {
 #ifdef USE_DB
@@ -926,17 +923,13 @@ maildir_scan( maildir_store_t *ctx, msglist_t *msglist )
                                }
                                if (uid <= ctx->maxuid) {
                                        if (uid < ctx->minuid) {
-                                               for (j = 0; j < ctx->nexcs; j++)
-                                                       if (ctx->excs[j] == uid)
+                                               for (j = 0; j < ctx->excs.size; 
j++)
+                                                       if (ctx->excs.data[j] 
== uid)
                                                                goto oke;
                                                continue;
                                          oke: ;
                                        }
-                                       if (msglist->nalloc == msglist->nents) {
-                                               msglist->nalloc = 
msglist->nalloc * 2 + 100;
-                                               msglist->ents = nfrealloc( 
msglist->ents, msglist->nalloc * sizeof(msg_t) );
-                                       }
-                                       entry = 
&msglist->ents[msglist->nents++];
+                                       entry = msg_t_array_append( msglist );
                                        entry->base = nfstrdup( e->d_name );
                                        entry->uid = uid;
                                        entry->recent = i;
@@ -992,9 +985,9 @@ maildir_scan( maildir_store_t *ctx, msglist_t *msglist )
                        tdb->close( tdb, 0 );
                }
 #endif /* USE_DB */
-               qsort( msglist->ents, msglist->nents, sizeof(msg_t), 
maildir_compare );
-               for (uid = i = 0; i < msglist->nents; i++) {
-                       entry = &msglist->ents[i];
+               qsort( msglist->array.data, msglist->array.size, sizeof(msg_t), 
maildir_compare );
+               for (uid = i = 0; i < msglist->array.size; i++) {
+                       entry = &msglist->array.data[i];
                        if (entry->uid != INT_MAX) {
                                if (uid == entry->uid) {
 #if 1
@@ -1134,7 +1127,7 @@ maildir_select_box( store_t *gctx, const char *name )
 
        maildir_cleanup( gctx );
        gctx->msgs = 0;
-       ctx->excs = 0;
+       ctx->excs.data = 0;
        ctx->uvfd = -1;
 #ifdef USE_DB
        ctx->db = 0;
@@ -1215,9 +1208,9 @@ static int
 maildir_confirm_box_empty( store_t *gctx )
 {
        maildir_store_t *ctx = (maildir_store_t *)gctx;
-       msglist_t msglist;
+       msg_t_array_alloc_t msglist;
 
-       ctx->nexcs = ctx->minuid = ctx->maxuid = ctx->newuid = 0;
+       ctx->excs.size = ctx->minuid = ctx->maxuid = ctx->newuid = 0;
 
        if (maildir_scan( ctx, &msglist ) != DRV_OK)
                return DRV_BOX_BAD;
@@ -1289,27 +1282,27 @@ maildir_prepare_load_box( store_t *gctx, int opts )
 }
 
 static void
-maildir_load_box( store_t *gctx, int minuid, int maxuid, int newuid, int 
*excs, int nexcs,
+maildir_load_box( store_t *gctx, int minuid, int maxuid, int newuid, 
int_array_t excs,
                   void (*cb)( int sts, void *aux ), void *aux )
 {
        maildir_store_t *ctx = (maildir_store_t *)gctx;
        message_t **msgapp;
-       msglist_t msglist;
+       msg_t_array_alloc_t msglist;
        int i;
 
        ctx->minuid = minuid;
        ctx->maxuid = maxuid;
        ctx->newuid = newuid;
-       ctx->excs = nfrealloc( excs, nexcs * sizeof(int) );
-       ctx->nexcs = nexcs;
+       ARRAY_SQUEEZE( &excs );
+       ctx->excs = excs;
 
        if (maildir_scan( ctx, &msglist ) != DRV_OK) {
                cb( DRV_BOX_BAD, aux );
                return;
        }
        msgapp = &ctx->gen.msgs;
-       for (i = 0; i < msglist.nents; i++)
-               maildir_app_msg( ctx, &msgapp, msglist.ents + i );
+       for (i = 0; i < msglist.array.size; i++)
+               maildir_app_msg( ctx, &msgapp, msglist.array.data + i );
        maildir_free_scan( &msglist );
 
        cb( DRV_OK, aux );
@@ -1320,37 +1313,37 @@ maildir_rescan( maildir_store_t *ctx )
 {
        message_t **msgapp;
        maildir_message_t *msg;
-       msglist_t msglist;
+       msg_t_array_alloc_t msglist;
        int i;
 
        ctx->fresh[0] = ctx->fresh[1] = 0;
        if (maildir_scan( ctx, &msglist ) != DRV_OK)
                return DRV_BOX_BAD;
        for (msgapp = &ctx->gen.msgs, i = 0;
-            (msg = (maildir_message_t *)*msgapp) || i < msglist.nents; )
+            (msg = (maildir_message_t *)*msgapp) || i < msglist.array.size; )
        {
                if (!msg) {
 #if 0
-                       debug( "adding new message %d\n", msglist.ents[i].uid );
-                       maildir_app_msg( ctx, &msgapp, msglist.ents + i );
+                       debug( "adding new message %d\n", 
msglist.array.data[i].uid );
+                       maildir_app_msg( ctx, &msgapp, msglist.array.data + i );
 #else
-                       debug( "ignoring new message %d\n", msglist.ents[i].uid 
);
+                       debug( "ignoring new message %d\n", 
msglist.array.data[i].uid );
 #endif
                        i++;
-               } else if (i >= msglist.nents) {
+               } else if (i >= msglist.array.size) {
                        debug( "purging deleted message %d\n", msg->gen.uid );
                        msg->gen.status = M_DEAD;
                        msgapp = &msg->gen.next;
-               } else if (msglist.ents[i].uid < msg->gen.uid) {
+               } else if (msglist.array.data[i].uid < msg->gen.uid) {
                        /* this should not happen, actually */
 #if 0
-                       debug( "adding new message %d\n", msglist.ents[i].uid );
-                       maildir_app_msg( ctx, &msgapp, msglist.ents + i );
+                       debug( "adding new message %d\n", 
msglist.array.data[i].uid );
+                       maildir_app_msg( ctx, &msgapp, msglist.array.data + i );
 #else
-                       debug( "ignoring new message %d\n", msglist.ents[i].uid 
);
+                       debug( "ignoring new message %d\n", 
msglist.array.data[i].uid );
 #endif
                        i++;
-               } else if (msglist.ents[i].uid > msg->gen.uid) {
+               } else if (msglist.array.data[i].uid > msg->gen.uid) {
                        debug( "purging deleted message %d\n", msg->gen.uid );
                        msg->gen.status = M_DEAD;
                        msgapp = &msg->gen.next;
@@ -1358,7 +1351,7 @@ maildir_rescan( maildir_store_t *ctx )
                        debug( "updating message %d\n", msg->gen.uid );
                        msg->gen.status &= ~(M_FLAGS|M_RECENT);
                        free( msg->base );
-                       maildir_init_msg( ctx, msg, msglist.ents + i );
+                       maildir_init_msg( ctx, msg, msglist.array.data + i );
                        i++, msgapp = &msg->gen.next;
                }
        }
diff --git a/src/sync.c b/src/sync.c
index 5ec377c..a6ebea8 100644
--- a/src/sync.c
+++ b/src/sync.c
@@ -938,7 +938,7 @@ static void box_deleted( int sts, void *aux );
 static void box_created( int sts, void *aux );
 static void box_opened( int sts, void *aux );
 static void box_opened2( sync_vars_t *svars, int t );
-static void load_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int 
nmexcs );
+static void load_box( sync_vars_t *svars, int t, int minwuid, int_array_t 
mexcs );
 
 void
 sync_boxes( store_t *ctx[], const char *names[], int present[], channel_conf_t 
*chan,
@@ -1138,8 +1138,8 @@ box_opened2( sync_vars_t *svars, int t )
        store_t *ctx[2];
        channel_conf_t *chan;
        sync_rec_t *srec;
-       int opts[2], fails;
-       int *mexcs, nmexcs, rmexcs, minwuid;
+       int_array_alloc_t mexcs;
+       int opts[2], fails, minwuid;
 
        svars->state[t] |= ST_SELECTED;
        if (!(svars->state[1-t] & ST_SELECTED))
@@ -1224,8 +1224,7 @@ box_opened2( sync_vars_t *svars, int t )
        svars->drv[M]->prepare_load_box( ctx[M], opts[M] );
        svars->drv[S]->prepare_load_box( ctx[S], opts[S] );
 
-       mexcs = 0;
-       nmexcs = rmexcs = 0;
+       ARRAY_INIT( &mexcs );
        if (svars->ctx[M]->opts & OPEN_OLD) {
                if (chan->max_messages) {
                        /* When messages have been expired on the slave, the 
master fetch is split into
@@ -1263,16 +1262,12 @@ box_opened2( sync_vars_t *svars, int t )
                                if (srec->uid[M] > 0 && srec->uid[S] > 0 && 
minwuid > srec->uid[M] &&
                                    (!(svars->ctx[M]->opts & OPEN_NEW) || 
svars->maxuid[M] >= srec->uid[M])) {
                                        /* The pair is alive, but outside the 
bulk range. */
-                                       if (nmexcs == rmexcs) {
-                                               rmexcs = rmexcs * 2 + 100;
-                                               mexcs = nfrealloc( mexcs, 
rmexcs * sizeof(int) );
-                                       }
-                                       mexcs[nmexcs++] = srec->uid[M];
+                                       *int_array_append( &mexcs ) = 
srec->uid[M];
                                }
                        }
                        debugn( "  exception list is:" );
-                       for (t = 0; t < nmexcs; t++)
-                               debugn( " %d", mexcs[t] );
+                       for (t = 0; t < mexcs.array.size; t++)
+                               debugn( " %d", mexcs.array.data[t] );
                        debug( "\n" );
                } else {
                        minwuid = 1;
@@ -1281,16 +1276,16 @@ box_opened2( sync_vars_t *svars, int t )
                minwuid = INT_MAX;
        }
        sync_ref( svars );
-       load_box( svars, M, minwuid, mexcs, nmexcs );
+       load_box( svars, M, minwuid, mexcs.array );
        if (!check_cancel( svars ))
-               load_box( svars, S, (ctx[S]->opts & OPEN_OLD) ? 1 : INT_MAX, 0, 
0 );
+               load_box( svars, S, (ctx[S]->opts & OPEN_OLD) ? 1 : INT_MAX, 
(int_array_t){ 0, 0 } );
        sync_deref( svars );
 }
 
 static void box_loaded( int sts, void *aux );
 
 static void
-load_box( sync_vars_t *svars, int t, int minwuid, int *mexcs, int nmexcs )
+load_box( sync_vars_t *svars, int t, int minwuid, int_array_t mexcs )
 {
        sync_rec_t *srec;
        int maxwuid;
@@ -1308,7 +1303,7 @@ load_box( sync_vars_t *svars, int t, int minwuid, int 
*mexcs, int nmexcs )
                maxwuid = 0;
        info( "Loading %s...\n", str_ms[t] );
        debug( maxwuid == INT_MAX ? "loading %s [%d,inf]\n" : "loading %s 
[%d,%d]\n", str_ms[t], minwuid, maxwuid );
-       svars->drv[t]->load_box( svars->ctx[t], minwuid, maxwuid, 
svars->newuid[t], mexcs, nmexcs, box_loaded, AUX );
+       svars->drv[t]->load_box( svars->ctx[t], minwuid, maxwuid, 
svars->newuid[t], mexcs, box_loaded, AUX );
 }
 
 typedef struct {
diff --git a/src/util.c b/src/util.c
index e5a6632..726054f 100644
--- a/src/util.c
+++ b/src/util.c
@@ -540,9 +540,9 @@ compare_ints( const void *l, const void *r )
 }
 
 void
-sort_ints( int *arr, int len )
+sort_int_array( int_array_t array )
 {
-       qsort( arr, len, sizeof(int), compare_ints );
+       qsort( array.data, array.size, sizeof(int), compare_ints );
 }
 
 

------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi
_______________________________________________
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to