From f77e0b578f71edb6f9105d5af8d54c8237cd9078 Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Wed, 26 Apr 2017 13:41:27 +0100 Subject: [PATCH 01/16] sbr/vector.c: Change bvector_bits() to return first word. Rename it to bvector_first_bits() to represent its new behaviour. It has only one caller that uses it to produce debug. Tighten the API so other callers don't get access to the location of the bvector's bits. --- h/mh.h | 2 +- sbr/vector.c | 6 +++--- uip/mark.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/h/mh.h b/h/mh.h index 774d336e..1edf4822 100644 --- a/h/mh.h +++ b/h/mh.h @@ -199,7 +199,7 @@ void bvector_clear (bvector_t, size_t); void bvector_clear_all (bvector_t); void bvector_set (bvector_t, size_t); unsigned int bvector_at (bvector_t, size_t); -const unsigned long *bvector_bits (bvector_t); +unsigned long bvector_first_bits (bvector_t); typedef struct svector *svector_t; diff --git a/sbr/vector.c b/sbr/vector.c index e975e271..1167fa24 100644 --- a/sbr/vector.c +++ b/sbr/vector.c @@ -141,9 +141,9 @@ bvector_resize (bvector_t vec, size_t maxsize) { bvector_clear (vec, i); } -const unsigned long * -bvector_bits (bvector_t vec) { - return vec->bits; +unsigned long +bvector_first_bits (bvector_t vec) { + return *vec->bits; } diff --git a/uip/mark.c b/uip/mark.c index c882a17b..3972508f 100644 --- a/uip/mark.c +++ b/uip/mark.c @@ -259,7 +259,7 @@ seq_printdebug (struct msgs *mp) if (is_selected (mp, msgnum)) printf ("%*d: %s\n", DMAXFOLDER, msgnum, snprintb (buf, sizeof buf, - (unsigned) *bvector_bits (msgstat (mp, msgnum)), + (unsigned) bvector_first_bits (msgstat (mp, msgnum)), seq_bits (mp))); } } -- 2.48.1 From c8caafcb4a39516eaec330f9ea229ea52e5fe46b Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Thu, 27 Apr 2017 00:14:28 +0100 Subject: [PATCH 02/16] sbr/vector.c: Zero the growth with memset(3), not loop. When the resize functions grow the vectors, as they always do, zero the new slots with memset(3) rather than a for loop. Particularly of note for the bit vector where it was bvector_clear()ing one bit at a time. Although a NULL pointer needn't have a representation of all-zero bits, the code was already assuming that, e.g. on the initial allocation, so we're no worse off. --- sbr/vector.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sbr/vector.c b/sbr/vector.c index 1167fa24..3bf4c1f0 100644 --- a/sbr/vector.c +++ b/sbr/vector.c @@ -29,6 +29,8 @@ * constants in the code below must also be changed to a 1 that's at * least as wide as the new type. */ + +/* The *sizeof* struct bvector's bits member. Not its size in bits. */ #define BVEC_SIZEOF_BITS (sizeof *(((bvector_t)NULL)->bits)) #define BVEC_WORD(max) ((max) / (BVEC_SIZEOF_BITS * CHAR_BIT)) #define BVEC_OFFSET(max) ((max) % (BVEC_SIZEOF_BITS * CHAR_BIT)) @@ -127,7 +129,6 @@ static void bvector_resize (bvector_t vec, size_t maxsize) { size_t old_maxsize = vec->maxsize; size_t bytes; - size_t i; while ((vec->maxsize *= 2) < maxsize) ; @@ -137,8 +138,9 @@ bvector_resize (bvector_t vec, size_t maxsize) { memcpy(vec->bits, vec->tiny, sizeof vec->tiny); } else vec->bits = mh_xrealloc(vec->bits, bytes); - for (i = old_maxsize; i < vec->maxsize; ++i) - bvector_clear (vec, i); + + memset(vec->bits + (old_maxsize / (BVEC_SIZEOF_BITS * CHAR_BIT)), + 0, (vec->maxsize - old_maxsize) / CHAR_BIT); } unsigned long @@ -220,13 +222,12 @@ svector_size (svector_t vec) { static void svector_resize (svector_t vec, size_t maxsize) { size_t old_maxsize = vec->maxsize; - size_t i; while ((vec->maxsize *= 2) < maxsize) ; vec->strs = mh_xrealloc (vec->strs, vec->maxsize * sizeof (char *)); - for (i = old_maxsize; i < vec->maxsize; ++i) - vec->strs[i] = NULL; + memset(vec->strs + old_maxsize, 0, + (vec->maxsize - old_maxsize) * sizeof *vec->strs); } @@ -282,11 +283,10 @@ ivector_atp (ivector_t vec, size_t i) { static void ivector_resize (ivector_t vec, size_t maxsize) { size_t old_maxsize = vec->maxsize; - size_t i; while ((vec->maxsize *= 2) < maxsize) ; vec->ints = mh_xrealloc (vec->ints, vec->maxsize * sizeof (int)); - for (i = old_maxsize; i < vec->maxsize; ++i) - vec->ints[i] = 0; + memset(vec->ints + old_maxsize, 0, + (vec->maxsize - old_maxsize) * sizeof *vec->ints); } -- 2.48.1 From b5a92b55eb5670e982899e5dfd9aaa1d35db002f Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Fri, 28 Apr 2017 12:12:15 +0100 Subject: [PATCH 03/16] sbr/vector.c: Use new BVEC_BITS_BITS macro. Factors out a common expression from a few other places. --- sbr/vector.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sbr/vector.c b/sbr/vector.c index 3bf4c1f0..c2bd0df9 100644 --- a/sbr/vector.c +++ b/sbr/vector.c @@ -32,8 +32,10 @@ /* The *sizeof* struct bvector's bits member. Not its size in bits. */ #define BVEC_SIZEOF_BITS (sizeof *(((bvector_t)NULL)->bits)) -#define BVEC_WORD(max) ((max) / (BVEC_SIZEOF_BITS * CHAR_BIT)) -#define BVEC_OFFSET(max) ((max) % (BVEC_SIZEOF_BITS * CHAR_BIT)) +/* The number of bits held in one element of the bits member. */ +#define BVEC_BITS_BITS (BVEC_SIZEOF_BITS * CHAR_BIT) +#define BVEC_WORD(max) ((max) / BVEC_BITS_BITS) +#define BVEC_OFFSET(max) ((max) % BVEC_BITS_BITS) #define BVEC_BYTES(n) \ ((BVEC_WORD(n) + (BVEC_OFFSET(n) == 0 ? 0 : 1)) * BVEC_SIZEOF_BITS) @@ -139,8 +141,8 @@ bvector_resize (bvector_t vec, size_t maxsize) { } else vec->bits = mh_xrealloc(vec->bits, bytes); - memset(vec->bits + (old_maxsize / (BVEC_SIZEOF_BITS * CHAR_BIT)), - 0, (vec->maxsize - old_maxsize) / CHAR_BIT); + memset(vec->bits + (old_maxsize / BVEC_BITS_BITS), 0, + (vec->maxsize - old_maxsize) / CHAR_BIT); } unsigned long -- 2.48.1 From c687e5bdd1da1a27b72cc9a4e94a1a2641fcf0d5 Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Fri, 28 Apr 2017 12:16:01 +0100 Subject: [PATCH 04/16] sbr/vector.c: Rewrite BVEC_BYTES(n) macro to remove branch. Use the idiom of integer truncation. --- sbr/vector.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbr/vector.c b/sbr/vector.c index c2bd0df9..84c717e5 100644 --- a/sbr/vector.c +++ b/sbr/vector.c @@ -36,8 +36,8 @@ #define BVEC_BITS_BITS (BVEC_SIZEOF_BITS * CHAR_BIT) #define BVEC_WORD(max) ((max) / BVEC_BITS_BITS) #define BVEC_OFFSET(max) ((max) % BVEC_BITS_BITS) -#define BVEC_BYTES(n) \ - ((BVEC_WORD(n) + (BVEC_OFFSET(n) == 0 ? 0 : 1)) * BVEC_SIZEOF_BITS) +/* The number of elements bits needs to cover bit n, measured in bytes. */ +#define BVEC_BYTES(n) (((n) / BVEC_BITS_BITS + 1) * BVEC_SIZEOF_BITS) struct bvector { unsigned long *bits; -- 2.48.1 From d7b80252561bfbdaacf37e6026e74690a08c2c9c Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Fri, 28 Apr 2017 12:27:44 +0100 Subject: [PATCH 05/16] sbr/vector.c: Add bvector comments, tidy identifiers. --- sbr/vector.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/sbr/vector.c b/sbr/vector.c index 84c717e5..b7103b79 100644 --- a/sbr/vector.c +++ b/sbr/vector.c @@ -19,8 +19,14 @@ #include #include +/* The default size of a struct bvector's bits, measured in bits. + * The struct's tiny member is used for storage. */ #define BVEC_INIT_SIZE (sizeof *(((bvector_t)NULL)->tiny) * CHAR_BIT) + +/* The default number of char pointers in a struct svector. */ #define SVEC_INIT_SIZE 256 + +/* The default number of ints in a struct ivector. */ #define IVEC_INIT_SIZE 256 /* @@ -34,18 +40,24 @@ #define BVEC_SIZEOF_BITS (sizeof *(((bvector_t)NULL)->bits)) /* The number of bits held in one element of the bits member. */ #define BVEC_BITS_BITS (BVEC_SIZEOF_BITS * CHAR_BIT) -#define BVEC_WORD(max) ((max) / BVEC_BITS_BITS) -#define BVEC_OFFSET(max) ((max) % BVEC_BITS_BITS) +/* The index of bit n in struct bvector's bits member. */ +#define BVEC_WORD(n) ((n) / BVEC_BITS_BITS) +/* The index of bit n within a single struct bvector's bits member. */ +#define BVEC_OFFSET(n) ((n) % BVEC_BITS_BITS) /* The number of elements bits needs to cover bit n, measured in bytes. */ #define BVEC_BYTES(n) (((n) / BVEC_BITS_BITS + 1) * BVEC_SIZEOF_BITS) struct bvector { unsigned long *bits; size_t maxsize; - unsigned long tiny[2]; + unsigned long tiny[2]; /* Default fixed-size storage for bits. */ }; -static void bvector_resize (bvector_t, size_t); +/* bvector_resize ensures the storage used for bits can cover bit + * newsize. It always increases the size of the storage used for bits, + * even if newsize would have been covered by the existing storage. + * Thus it's normally only called when it's known the storage must grow. */ +static void bvector_resize (bvector_t vec, size_t newsize); bvector_t bvector_create (size_t init_size) { @@ -128,11 +140,11 @@ bvector_at (bvector_t vec, size_t i) { } static void -bvector_resize (bvector_t vec, size_t maxsize) { - size_t old_maxsize = vec->maxsize; +bvector_resize (bvector_t vec, size_t newsize) { + size_t oldsize = vec->maxsize; size_t bytes; - while ((vec->maxsize *= 2) < maxsize) + while ((vec->maxsize *= 2) < newsize) ; bytes = BVEC_BYTES(vec->maxsize); if (vec->bits == vec->tiny) { @@ -141,8 +153,8 @@ bvector_resize (bvector_t vec, size_t maxsize) { } else vec->bits = mh_xrealloc(vec->bits, bytes); - memset(vec->bits + (old_maxsize / BVEC_BITS_BITS), 0, - (vec->maxsize - old_maxsize) / CHAR_BIT); + memset(vec->bits + (oldsize / BVEC_BITS_BITS), 0, + (vec->maxsize - oldsize) / CHAR_BIT); } unsigned long -- 2.48.1 From 4d3c5111a2a7716e957547cb80a1efe7accabf6f Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Fri, 28 Apr 2017 12:45:26 +0100 Subject: [PATCH 06/16] sbr/vector.c: Only allocate bvector storage for set bits. Now that a pointer to all the bit storage doesn't escape vector.c, there's no need to allocate storage, that's initialised to 0, just to then clear a bit in it. Only extend the bits's storage for set bits. Remove the unused initial size parameter from bvector_create() as it simplifies the implementation. --- h/mh.h | 4 ++-- sbr/folder_read.c | 2 +- sbr/folder_realloc.c | 4 ++-- sbr/vector.c | 34 +++++++++------------------------- uip/sortm.c | 2 +- 5 files changed, 15 insertions(+), 31 deletions(-) diff --git a/h/mh.h b/h/mh.h index 1edf4822..0a62f586 100644 --- a/h/mh.h +++ b/h/mh.h @@ -192,7 +192,7 @@ extern struct swit anoyes[]; /* standard yes/no switches */ */ typedef struct bvector *bvector_t; -bvector_t bvector_create (size_t /* initial size in bits, can be 0 */); +bvector_t bvector_create (void); void bvector_copy (bvector_t, bvector_t); void bvector_free (bvector_t); void bvector_clear (bvector_t, size_t); @@ -329,7 +329,7 @@ struct msgs { #define make_seq_private(mp,seqnum) \ bvector_set (mp->attrstats, FFATTRSLOT + seqnum) #define make_all_public(mp) \ - mp->attrstats = bvector_create(0); bvector_clear_all (mp->attrstats) + mp->attrstats = bvector_create(); bvector_clear_all (mp->attrstats) /* * macros for folder attributes diff --git a/sbr/folder_read.c b/sbr/folder_read.c index e742153c..e157dd25 100644 --- a/sbr/folder_read.c +++ b/sbr/folder_read.c @@ -136,7 +136,7 @@ folder_read (char *name, int lockflag) mp->num_msgstats = MSGSTATNUM (mp->lowoff, mp->hghoff); mp->msgstats = mh_xmalloc (MSGSTATSIZE(mp)); for (i = 0, v = mp->msgstats; i < mp->num_msgstats; ++i, ++v) { - *v = bvector_create (0); + *v = bvector_create (); } mp->msgattrs = svector_create (0); diff --git a/sbr/folder_realloc.c b/sbr/folder_realloc.c index fbef8549..2084e0ee 100644 --- a/sbr/folder_realloc.c +++ b/sbr/folder_realloc.c @@ -58,7 +58,7 @@ folder_realloc (struct msgs *mp, int lo, int hi) mh_xrealloc (mp->msgstats, MSGSTATSIZE(mp)); for (i = old_size, v = &mp->msgstats[old_size]; i < new_size; ++i, ++v) { - *v = bvector_create (0); + *v = bvector_create (); } } else { /* @@ -72,7 +72,7 @@ folder_realloc (struct msgs *mp, int lo, int hi) mp->num_msgstats = MSGSTATNUM (lo, hi); tmpstats = mh_xmalloc (MSGSTATSIZE(mp)); for (i = 0, t = tmpstats; i < mp->num_msgstats; ++i, ++t) { - *t = bvector_create (0); + *t = bvector_create (); } /* then copy messages status array with shift */ diff --git a/sbr/vector.c b/sbr/vector.c index b7103b79..e3760651 100644 --- a/sbr/vector.c +++ b/sbr/vector.c @@ -60,25 +60,16 @@ struct bvector { static void bvector_resize (bvector_t vec, size_t newsize); bvector_t -bvector_create (size_t init_size) { +bvector_create (void) { bvector_t vec; - size_t bytes; /* See "wider than unsigned long" comment above. */ assert (sizeof *vec->bits <= sizeof 1ul); NEW(vec); - - if (init_size <= BVEC_INIT_SIZE) { - vec->bits = vec->tiny; - vec->maxsize = BVEC_INIT_SIZE; - memset(vec->tiny, 0, sizeof vec->tiny); - return vec; - } - - bytes = BVEC_BYTES(init_size); - vec->bits = mh_xcalloc (1, bytes); - vec->maxsize = bytes * CHAR_BIT; + vec->bits = vec->tiny; + vec->maxsize = BVEC_INIT_SIZE; + memset(vec->tiny, 0, sizeof vec->tiny); return vec; } @@ -103,13 +94,8 @@ bvector_free (bvector_t vec) { void bvector_clear (bvector_t vec, size_t n) { - size_t word = BVEC_WORD(n); - size_t offset = BVEC_OFFSET(n); - - if (n >= vec->maxsize) - bvector_resize (vec, n); - - vec->bits[word] &= ~(1ul << offset); + if (n < vec->maxsize) + vec->bits[BVEC_WORD(n)] &= ~(1ul << BVEC_OFFSET(n)); } @@ -131,12 +117,10 @@ bvector_set (bvector_t vec, size_t n) { unsigned int bvector_at (bvector_t vec, size_t i) { - size_t word = BVEC_WORD(i); - size_t offset = BVEC_OFFSET(i); + if (i < vec->maxsize) + return !!(vec->bits[BVEC_WORD(i)] & (1ul << BVEC_OFFSET(i))); - return i < vec->maxsize - ? (vec->bits[word] & (1ul << offset) ? 1 : 0) - : 0; + return 0; } static void diff --git a/uip/sortm.c b/uip/sortm.c index f07e7863..4f5602fe 100644 --- a/uip/sortm.c +++ b/uip/sortm.c @@ -540,7 +540,7 @@ static void rename_msgs (struct msgs *mp, struct smsg **mlist) { int i, j, old, new; - bvector_t tmpset = bvector_create (0); + bvector_t tmpset = bvector_create (); char f1[BUFSIZ], tmpfil[BUFSIZ]; char newbuf[PATH_MAX + 1]; struct smsg *sp; -- 2.48.1 From d07c6759a3b5b936e790834147ab7bd867645d4f Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Fri, 28 Apr 2017 17:00:54 +0100 Subject: [PATCH 07/16] valgrind: Add suppression for dbm_open(3)'s write(2). It writes bytes from an area it mallocs, but doesn't set all of those bytes first. See with gdbm 1.13-1 on Arch Linux. --- test/valgrind.supp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/valgrind.supp b/test/valgrind.supp index 2726f42e..4da69de8 100644 --- a/test/valgrind.supp +++ b/test/valgrind.supp @@ -46,6 +46,20 @@ fun:getaddrinfo } +{ + gdbm 1.13-1 writes uninitialised bytes from malloc'd area to file + Memcheck:Param + write(buf) + fun:__write_nocancel + fun:_gdbm_full_write + fun:gdbm_fd_open + fun:dbm_open + fun:suppress_duplicates + fun:localmail + fun:main +} + + { dyld libraryLocator on MacOS 10.11.6 (El Capitan) Memcheck:Cond -- 2.48.1 From 159b2a1ede7bd581508e8704112d83efd44e0dfa Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Fri, 28 Apr 2017 17:12:31 +0100 Subject: [PATCH 08/16] sbr/folder_read.c: Don't malloc() once per message. Instead of struct msgs having a pointer to a malloc'd array of pointers, each to a malloc'd struct bvector, 1+N, it now has a pointer to a malloc'd array of struct bvector; one malloc for all of them. This avoids the large number of calls to malloc() and free() that's linear with the size of the folder. But there are some downsides. In order to step through an array of struct bvector, code outside of sbr/vector.c needs to know the struct's size. The simplest way to do this is to make the struct's definition public, with a comment that access should be through vector.c. New functions are needed to initialise the content of an already allocated bvector, and to finish with its content prior to deallocation. bvector_create() and bvector_free() now also use these new functions. Before, it was the array of pointers to bvector that would be realloc'd. That doesn't work for the array of bvectors as they may contain pointers to within themselves. The solution is to malloc a new array and bvector_copy() the ones to keep across, as folder_realloc() now does. The other half of its logic that coped with growth at the end of the array, has been deleted. Also deleted, is the code to clear the bvectors before and after the old ones as they start in that state. --- h/mh.h | 18 ++++++++--- sbr/folder_free.c | 4 +-- sbr/folder_read.c | 4 +-- sbr/folder_realloc.c | 74 +++++++++----------------------------------- sbr/vector.c | 26 +++++++++------- 5 files changed, 46 insertions(+), 80 deletions(-) diff --git a/h/mh.h b/h/mh.h index 0a62f586..8829eb4c 100644 --- a/h/mh.h +++ b/h/mh.h @@ -187,14 +187,22 @@ extern struct swit anoyes[]; /* standard yes/no switches */ #define MBITS "\020\01EXISTS\02SELECTED\03NEW\04UNSEEN" -/* - * type for holding the sequence set of a message - */ +/* A vector of bits for tracking the sequence membership of a single + * message. Do not access the struct members; use vector.c. + * Do not move or copy this struct as it may contain a pointer to + * itself; use bvector_copy(). */ +struct bvector { + unsigned long *bits; + size_t maxsize; + unsigned long tiny[2]; /* Default fixed-size storage for bits. */ +}; typedef struct bvector *bvector_t; bvector_t bvector_create (void); +void bvector_init(struct bvector *bv); void bvector_copy (bvector_t, bvector_t); void bvector_free (bvector_t); +void bvector_fini(struct bvector *bv); void bvector_clear (bvector_t, size_t); void bvector_clear_all (bvector_t); void bvector_set (bvector_t, size_t); @@ -263,7 +271,7 @@ struct msgs { * in a particular sequence. */ size_t num_msgstats; - bvector_t *msgstats; /* msg status */ + struct bvector *msgstats; /* msg status */ /* * A FILE handle containing an open filehandle for the sequence file @@ -289,7 +297,7 @@ struct msgs { /* * macros for message and sequence manipulation */ -#define msgstat(mp,n) (mp)->msgstats[(n) - mp->lowoff] +#define msgstat(mp,n) ((mp)->msgstats + (n) - mp->lowoff) #define clear_msg_flags(mp,msgnum) bvector_clear_all (msgstat(mp, msgnum)) #define copy_msg_flags(mp,i,j) bvector_copy (msgstat(mp,i), msgstat(mp,j)) #define get_msg_flags(mp,ptr,msgnum) bvector_copy (ptr, msgstat(mp, msgnum)) diff --git a/sbr/folder_free.c b/sbr/folder_free.c index 0b008194..be2771f7 100644 --- a/sbr/folder_free.c +++ b/sbr/folder_free.c @@ -13,7 +13,7 @@ void folder_free (struct msgs *mp) { size_t i; - bvector_t *v; + struct bvector *v; if (!mp) return; @@ -26,7 +26,7 @@ folder_free (struct msgs *mp) svector_free (mp->msgattrs); for (i = 0, v = mp->msgstats; i < mp->num_msgstats; ++i, ++v) { - bvector_free (*v); + bvector_fini(v); } free (mp->msgstats); diff --git a/sbr/folder_read.c b/sbr/folder_read.c index e157dd25..eab1e1f4 100644 --- a/sbr/folder_read.c +++ b/sbr/folder_read.c @@ -27,7 +27,7 @@ folder_read (char *name, int lockflag) struct msgs *mp; struct dirent *dp; DIR *dd; - bvector_t *v; + struct bvector *v; size_t i; name = m_mailpath (name); @@ -136,7 +136,7 @@ folder_read (char *name, int lockflag) mp->num_msgstats = MSGSTATNUM (mp->lowoff, mp->hghoff); mp->msgstats = mh_xmalloc (MSGSTATSIZE(mp)); for (i = 0, v = mp->msgstats; i < mp->num_msgstats; ++i, ++v) { - *v = bvector_create (); + bvector_init(v); } mp->msgattrs = svector_create (0); diff --git a/sbr/folder_realloc.c b/sbr/folder_realloc.c index 2084e0ee..8ed95e2e 100644 --- a/sbr/folder_realloc.c +++ b/sbr/folder_realloc.c @@ -19,6 +19,8 @@ struct msgs * folder_realloc (struct msgs *mp, int lo, int hi) { + struct bvector *tmpstats, *t; + size_t i; int msgnum; /* sanity checks */ @@ -37,70 +39,22 @@ folder_realloc (struct msgs *mp, int lo, int hi) if (lo == mp->lowoff && hi == mp->hghoff) return mp; - if (lo == mp->lowoff) { - bvector_t *v; - size_t old_size = mp->num_msgstats; - size_t new_size = hi - lo + 1; - size_t i; - - /* - * We are just extending (or shrinking) the end of message - * status array. So we don't have to move anything and can - * just realloc the message status array. - */ - - for (i = old_size, v = &mp->msgstats[old_size-1]; i > new_size; - --i, --v) { - bvector_free (*v); - } - mp->num_msgstats = MSGSTATNUM (lo, hi); - mp->msgstats = - mh_xrealloc (mp->msgstats, MSGSTATSIZE(mp)); - for (i = old_size, v = &mp->msgstats[old_size]; i < new_size; - ++i, ++v) { - *v = bvector_create (); - } - } else { - /* - * We are changing the offset of the message status - * array. So we will need to shift everything. - */ - bvector_t *tmpstats, *t; - size_t i; - - /* first allocate the new message status space */ - mp->num_msgstats = MSGSTATNUM (lo, hi); - tmpstats = mh_xmalloc (MSGSTATSIZE(mp)); - for (i = 0, t = tmpstats; i < mp->num_msgstats; ++i, ++t) { - *t = bvector_create (); - } - - /* then copy messages status array with shift */ - if (mp->nummsg > 0) { - for (msgnum = mp->lowmsg; msgnum <= mp->hghmsg; msgnum++) - bvector_copy (tmpstats[msgnum - lo], msgstat (mp, msgnum)); - } - free(mp->msgstats); - mp->msgstats = tmpstats; + /* first allocate the new message status space */ + mp->num_msgstats = MSGSTATNUM (lo, hi); + tmpstats = mh_xmalloc (MSGSTATSIZE(mp)); + for (i = 0, t = tmpstats; i < mp->num_msgstats; ++i, ++t) { + bvector_init(t); } - mp->lowoff = lo; - mp->hghoff = hi; - - /* - * Clear all the flags for entries outside - * the current message range for this folder. - */ + /* then copy messages status array with shift */ if (mp->nummsg > 0) { - for (msgnum = mp->lowoff; msgnum < mp->lowmsg; msgnum++) - clear_msg_flags (mp, msgnum); - for (msgnum = mp->hghmsg + 1; msgnum <= mp->hghoff; msgnum++) - clear_msg_flags (mp, msgnum); - } else { - /* no messages, so clear entire range */ - for (msgnum = mp->lowoff; msgnum <= mp->hghoff; msgnum++) - clear_msg_flags (mp, msgnum); + for (msgnum = mp->lowmsg; msgnum <= mp->hghmsg; msgnum++) + bvector_copy (tmpstats + msgnum - lo, msgstat (mp, msgnum)); } + free(mp->msgstats); + mp->msgstats = tmpstats; + mp->lowoff = lo; + mp->hghoff = hi; return mp; } diff --git a/sbr/vector.c b/sbr/vector.c index e3760651..7df36187 100644 --- a/sbr/vector.c +++ b/sbr/vector.c @@ -47,12 +47,6 @@ /* The number of elements bits needs to cover bit n, measured in bytes. */ #define BVEC_BYTES(n) (((n) / BVEC_BITS_BITS + 1) * BVEC_SIZEOF_BITS) -struct bvector { - unsigned long *bits; - size_t maxsize; - unsigned long tiny[2]; /* Default fixed-size storage for bits. */ -}; - /* bvector_resize ensures the storage used for bits can cover bit * newsize. It always increases the size of the storage used for bits, * even if newsize would have been covered by the existing storage. @@ -67,13 +61,18 @@ bvector_create (void) { assert (sizeof *vec->bits <= sizeof 1ul); NEW(vec); - vec->bits = vec->tiny; - vec->maxsize = BVEC_INIT_SIZE; - memset(vec->tiny, 0, sizeof vec->tiny); + bvector_init(vec); return vec; } +void bvector_init(struct bvector *bv) +{ + bv->bits = bv->tiny; + bv->maxsize = BVEC_INIT_SIZE; + memset(bv->tiny, 0, sizeof bv->tiny); +} + void bvector_copy (bvector_t dest, bvector_t src) { size_t bytes = BVEC_BYTES(src->maxsize); @@ -87,11 +86,16 @@ bvector_copy (bvector_t dest, bvector_t src) { void bvector_free (bvector_t vec) { - if (vec->bits != vec->tiny) - free(vec->bits); + bvector_fini(vec); free (vec); } +void bvector_fini(struct bvector *bv) +{ + if (bv->bits != bv->tiny) + free(bv->bits); +} + void bvector_clear (bvector_t vec, size_t n) { if (n < vec->maxsize) -- 2.48.1 From 213e031dda6a34c50c04de0d6041f45ab2db0a91 Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Fri, 28 Apr 2017 22:08:26 +0100 Subject: [PATCH 09/16] sbr/oauth.c: Remove const to avoid curl's debug_callback warning. The curl_debug_callback typedef doesn't use const for any of the function's parameters. On one of the compilation platforms here, oauth.c's debug_callback having const specifiers for some parameters causes compilation warnings, and -Werror stops the compilation. Remove them. --- sbr/oauth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbr/oauth.c b/sbr/oauth.c index 3becfdef..741cacb0 100755 --- a/sbr/oauth.c +++ b/sbr/oauth.c @@ -878,7 +878,7 @@ make_query_url(char *s, size_t size, CURL *curl, const char *base_url, ...) } static int -debug_callback(const CURL *handle, curl_infotype type, const char *data, +debug_callback(CURL *handle, curl_infotype type, char *data, size_t size, void *userptr) { FILE *fp = userptr; -- 2.48.1 From 24867fa77c867a444670cf484d32188ae0808777 Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Fri, 28 Apr 2017 22:42:46 +0100 Subject: [PATCH 10/16] bvector_copy: Use bvector's tiny storage if big enough. Otherwise a source bvector that's using tiny storage has its bits duplicated into a malloc'd area when the destination's tiny storage was sufficient. --- sbr/vector.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sbr/vector.c b/sbr/vector.c index 7df36187..6afe62aa 100644 --- a/sbr/vector.c +++ b/sbr/vector.c @@ -79,7 +79,10 @@ bvector_copy (bvector_t dest, bvector_t src) { if (dest->bits != dest->tiny) free(dest->bits); - dest->bits = mh_xmalloc (bytes); + if (bytes <= sizeof dest->tiny) + dest->bits = dest->tiny; + else + dest->bits = mh_xmalloc (bytes); memcpy (dest->bits, src->bits, bytes); dest->maxsize = src->maxsize; } -- 2.48.1 From 9514ca81bd12a47df977822efc14ff285bd5bc10 Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Sat, 29 Apr 2017 00:01:58 +0100 Subject: [PATCH 11/16] Fix spelling in C comments. --- h/addrsbr.h | 2 +- h/aliasbr.h | 4 ++-- h/fmt_compile.h | 6 +++--- h/fmt_scan.h | 2 +- h/mh.h | 2 +- h/mhparse.h | 4 ++-- h/oauth.h | 2 +- h/prototypes.h | 4 ++-- h/tws.h | 4 ++-- mts/smtp/smtp.h | 2 +- sbr/addrsbr.c | 4 ++-- sbr/context_read.c | 4 ++-- sbr/datetime.c | 2 +- sbr/dtime.c | 10 +++++----- sbr/dtimep.l | 2 +- sbr/escape_addresses.c | 2 +- sbr/fmt_compile.c | 2 +- sbr/m_getfld.c | 4 ++-- sbr/netsec.c | 2 +- sbr/utils.c | 2 +- uip/annosbr.c | 2 +- uip/fmttest.c | 4 ++-- uip/folder.c | 2 +- uip/forw.c | 4 ++-- uip/inc.c | 2 +- uip/mark.c | 2 +- uip/mhbuildsbr.c | 6 +++--- uip/mhfixmsg.c | 2 +- uip/mhlsbr.c | 6 +++--- uip/mhparse.c | 10 +++++----- uip/mhstoresbr.c | 2 +- uip/popsbr.c | 2 +- uip/post.c | 2 +- uip/refile.c | 2 +- uip/sendsbr.c | 2 +- uip/sortm.c | 2 +- 36 files changed, 59 insertions(+), 59 deletions(-) diff --git a/h/addrsbr.h b/h/addrsbr.h index fac8318f..3e6bffd2 100644 --- a/h/addrsbr.h +++ b/h/addrsbr.h @@ -102,7 +102,7 @@ char *auxformat(struct mailname *mp, int extras); * * This function used to have an argument called 'wanthost' which would * control whether or not it would canonicalize hostnames in email - * addresses. This functionalit was removed for nmh 1.5, and eventually + * addresses. This functionality was removed for nmh 1.5, and eventually * all of the code that used this argument was garbage collected. */ struct mailname *getm(char *str, char *dfhost, int dftype, char *eresult, diff --git a/h/aliasbr.h b/h/aliasbr.h index 1ac4faab..65542205 100644 --- a/h/aliasbr.h +++ b/h/aliasbr.h @@ -18,7 +18,7 @@ struct adr { }; /* - * incore version of /etc/passwd + * in-core version of /etc/passwd */ struct home { char *h_name; /* user name */ @@ -42,7 +42,7 @@ char *akerror (int); /* codes returned by alias() */ -#define AK_OK 0 /* file parsed ok */ +#define AK_OK 0 /* file parsed OK */ #define AK_NOFILE 1 /* couldn't read file */ #define AK_ERROR 2 /* error parsing file */ #define AK_LIMIT 3 /* memory limit exceeded */ diff --git a/h/fmt_compile.h b/h/fmt_compile.h index a4858825..532ccd17 100644 --- a/h/fmt_compile.h +++ b/h/fmt_compile.h @@ -6,7 +6,7 @@ #define FT_COMPF 2 /* comp text, filled */ #define FT_LIT 3 /* literal text */ #define FT_LITF 4 /* literal text, filled */ -#define FT_CHAR 5 /* a single ascii character */ +#define FT_CHAR 5 /* a single ASCII character */ #define FT_NUM 6 /* "value" as decimal number */ #define FT_NUMF 7 /* "value" as filled dec number */ #define FT_STR 8 /* "str" as text */ @@ -76,7 +76,7 @@ /* Date Coercion */ #define FT_LOCALDATE 68 /* Coerce date to local timezone */ -#define FT_GMTDATE 69 /* Coerce date to gmt */ +#define FT_GMTDATE 69 /* Coerce date to GMT */ /* pre-format processing */ #define FT_PARSEDATE 70 /* parse comp into a date (tws) struct */ @@ -91,7 +91,7 @@ #define FT_SAVESTR 77 /* save current str reg */ #define FT_DONE 78 /* stop formatting */ #define FT_PAUSE 79 /* pause */ -#define FT_NOP 80 /* nop */ +#define FT_NOP 80 /* no-op */ #define FT_GOTO 81 /* (relative) goto */ #define FT_IF_S_NULL 82 /* test if "str" null */ #define FT_IF_S 83 /* test if "str" non-null */ diff --git a/h/fmt_scan.h b/h/fmt_scan.h index 8c1d3fe3..faedecda 100644 --- a/h/fmt_scan.h +++ b/h/fmt_scan.h @@ -148,7 +148,7 @@ int fmt_compile (char *fstring, struct format **fmt, int reset); * format instructions. Is always terminated with a * newline (\n). * width - Maximum number of displayed characters. Does not include - * characters marked as nonprinting or (depending on the + * characters marked as non-printing or (depending on the * encoding) bytes in a multibyte encoding that exceed the * character's column width. * dat - An integer array that contains data used by certain format diff --git a/h/mh.h b/h/mh.h index 8829eb4c..a72971df 100644 --- a/h/mh.h +++ b/h/mh.h @@ -8,7 +8,7 @@ */ #define NOTOK (-1) /* syscall()s return this on error */ #define OK 0 /* ditto on success */ -#define DONE 1 /* trinary logic */ +#define DONE 1 /* ternary logic */ #define ALL "" #define MAXARGS 1000 /* max arguments to exec */ diff --git a/h/mhparse.h b/h/mhparse.h index 12137cba..00802d13 100644 --- a/h/mhparse.h +++ b/h/mhparse.h @@ -159,7 +159,7 @@ struct Content { SizeCEFunc c_cesizefnx; /* size of decoded contents */ int c_umask; /* associated umask */ - int c_rfc934; /* rfc934 compatibility flag */ + int c_rfc934; /* RFC 934 compatibility flag */ char *c_showproc; /* default, if not in profile */ char *c_termproc; /* for charset madness... */ @@ -415,7 +415,7 @@ int list_content(CT ct, int toplevel, int realsize, int verbose, int debug, int dispo); /* - * Display content-appropriate information on MIME parts, decending recursively + * Display content-appropriate information on MIME parts, descending recursively * into multipart content if appropriate. Uses list_content() for displaying * generic information. * diff --git a/h/oauth.h b/h/oauth.h index 605008a1..42c9ce7c 100644 --- a/h/oauth.h +++ b/h/oauth.h @@ -19,7 +19,7 @@ * 1. User runs mhlogin which prints a URL the user must visit, and prompts for * a code retrieved from that page. * - * 2. User vists this URL in browser, signs in with some Google account, and + * 2. User visits this URL in browser, signs in with some Google account, and * copies and pastes the resulting code back to mhlogin. * * 3. mhlogin does HTTP POST to Google to exchange the user-provided code for a diff --git a/h/prototypes.h b/h/prototypes.h index f1d1d69f..18b87586 100644 --- a/h/prototypes.h +++ b/h/prototypes.h @@ -203,7 +203,7 @@ char *get_term_stringcap(char *capability); * arg1..argN - Arguments 1-N. * * Returns a tparm and tputs-processed string, or NULL if there was a problem - * initializating the terminal or retrieving the capability. + * initialising the terminal or retrieving the capability. */ char *get_term_stringparm(char *capability, long arg1, long arg2); @@ -534,7 +534,7 @@ nmh_creds_t nmh_get_credentials (const char *host, const char *user); * * creds - Structure from previous nmh_get_credentials() call * - * Returns NULL on error, otherwise a NUL-termined string containing + * Returns NULL on error, otherwise a NUL-terminated string containing * the username. Points to allocated memory in the credentials structure * that is free()d by nmh_free_credentials(). */ diff --git a/h/tws.h b/h/tws.h index 9acda6a6..17a01a2d 100644 --- a/h/tws.h +++ b/h/tws.h @@ -5,7 +5,7 @@ be treated specially if it's in a zone that observes Daylight Saving Time. For instance, during DST, a Date: like "Mon, 24 Jul 2000 12:31:44 -0700" will be printed as "Mon, 24 Jul 2000 12:31:44 PDT". Without the code activated by - the following #define, that'd be incorrectly printed as "...MST". */ + the following #define, that would be incorrectly printed as "...MST". */ struct tws { int tw_sec; /* seconds after the minute - [0, 61] */ @@ -13,7 +13,7 @@ struct tws { int tw_hour; /* hour since midnight - [0, 23] */ int tw_mday; /* day of the month - [1, 31] */ int tw_mon; /* months since January - [0, 11] */ - int tw_year; /* 4 digit year (ie, 1997) */ + int tw_year; /* 4 digit year (e.g. 1997) */ int tw_wday; /* days since Sunday - [0, 6] */ int tw_yday; /* days since January 1 - [0, 365] */ int tw_zone; diff --git a/mts/smtp/smtp.h b/mts/smtp/smtp.h index f2d09d7e..6de4e514 100644 --- a/mts/smtp/smtp.h +++ b/mts/smtp/smtp.h @@ -135,7 +135,7 @@ char *rp_string (int); /* - * SPECIFIC FALURE VALUES + * SPECIFIC FAILURE VALUES */ /* diff --git a/sbr/addrsbr.c b/sbr/addrsbr.c index 466d8cca..68bb6dec 100644 --- a/sbr/addrsbr.c +++ b/sbr/addrsbr.c @@ -21,10 +21,10 @@ REALLYDUMB are now the default in the code. If #ifdef DUMB is in effect, a full 822-style parser is called - for syntax recongition. This breaks each address into its components. + for syntax recognition. This breaks each address into its components. Note however that no semantics are assumed about the parts or their totality. This means that implicit hostnames aren't made explicit, - and explicit hostnames aren't expanded to their "official" represenations. + and explicit hostnames aren't expanded to their "official" representations. If DUMB is not in effect, then this module does some high-level thinking about what the addresses are. diff --git a/sbr/context_read.c b/sbr/context_read.c index 778d4a35..668fdc3b 100644 --- a/sbr/context_read.c +++ b/sbr/context_read.c @@ -36,7 +36,7 @@ context_read (void) int failed_to_lock = 0; /* - * If this routine _is_ called again (despite the wanings in the + * If this routine _is_ called again (despite the warnings in the * comments above), return immediately. */ if ( m_defs != 0 ) @@ -128,7 +128,7 @@ context_read (void) /* context is NULL if context_foil() was called to disable use of context * We also support users setting explicitly setting MHCONTEXT to /dev/null. - * (if this wasn't specialcased then the locking would be liable to fail) + * (if this wasn't special-cased then the locking would be liable to fail) */ if (!cp || (strcmp(cp,"/dev/null") == 0)) { ctxpath = NULL; diff --git a/sbr/datetime.c b/sbr/datetime.c index 20b4be66..48f02d45 100644 --- a/sbr/datetime.c +++ b/sbr/datetime.c @@ -369,7 +369,7 @@ format_datetime (tzdesc_t timezones, const contentline *node) { /* Find the corresponding tzdesc. */ for (tz = timezones; dt_timezone && tz; tz = tz->next) { - /* Property parameter values are case insenstive (RFC 5545 + /* Property parameter values are case insensitive (RFC 5545 Sec. 2) and time zone identifiers are property parameters (RFC 5545 Sec. 3.8.2.4), though it would seem odd to use different case in the same file for identifiers that are diff --git a/sbr/dtime.c b/sbr/dtime.c index b4aaed8d..5a61f9ae 100644 --- a/sbr/dtime.c +++ b/sbr/dtime.c @@ -198,8 +198,8 @@ dctime (struct tws *tw) * Mon, 16 Jun 1992 15:30:48 -700 (or) * Mon, 16 Jun 1992 15:30:48 EDT * - * for the current time, as specified by rfc822. - * The first form is required by rfc1123. + * for the current time, as specified by RFC 822. + * The first form is required by RFC 1123. */ char * @@ -219,8 +219,8 @@ dtimenow (int alpha_timezone) * Mon, 16 Jun 1992 15:30:48 -700 (or) * Mon, 16 Jun 1992 15:30:48 EDT * - * as specified by rfc822. The first form is required - * by rfc1123 for outgoing messages. + * as specified by RFC 822. The first form is required + * by RFC 1123 for outgoing messages. */ char * @@ -241,7 +241,7 @@ dtime (time_t *clock, int alpha_timezone) * * Mon, 16 Jun 1992 15:30:48 -0700 * - * as specified by rfc822 and rfc1123. + * as specified by RFC 822 and RFC 1123. */ char * diff --git a/sbr/dtimep.l b/sbr/dtimep.l index 35c455db..2b6df175 100644 --- a/sbr/dtimep.l +++ b/sbr/dtimep.l @@ -35,7 +35,7 @@ */ #define YY_DECL struct tws *dparsetime(char *lexstr) - /* yyerminate() is called after the input string is matched to + /* yyterminate() is called after the input string is matched to * completion (actually, when the lexer reaches an EOF). The only * thing that really needs to be in this macro function is the * return call, which must be substituted inline into dparsetime. diff --git a/sbr/escape_addresses.c b/sbr/escape_addresses.c index 0d898dbd..a484a11e 100644 --- a/sbr/escape_addresses.c +++ b/sbr/escape_addresses.c @@ -42,7 +42,7 @@ escape_component (char *name, size_t namesize, char *chars_to_escape) { if (strpbrk(name, chars_to_escape)) { char *destp, *srcp; /* Maximum space requirement would be if each character had - to be escaped, plus enclosing double quotes, plus null termintor. + to be escaped, plus enclosing double quotes, plus NUL terminator. E.g., 2 characters, "", would require 7, "\"\""0, where that 0 is '\0'. */ char *tmp = mh_xmalloc (2*strlen(name) + 3); diff --git a/sbr/fmt_compile.c b/sbr/fmt_compile.c index 27359d9b..f4c8d5dc 100644 --- a/sbr/fmt_compile.c +++ b/sbr/fmt_compile.c @@ -797,7 +797,7 @@ do_expr (char *sp, int preprocess) * * Okay, got some more information on this from John L. Romine! From an * email he sent to the nmh-workers mailing list on December 2, 2010, he - * explains it thusly: + * explains it so: * * In this case (scan, formatsbr) it has to do with an extension to * the mh-format syntax to allow for looping. diff --git a/sbr/m_getfld.c b/sbr/m_getfld.c index a7af3b1a..fe8e927b 100644 --- a/sbr/m_getfld.c +++ b/sbr/m_getfld.c @@ -775,7 +775,7 @@ m_unknown(m_getfld_state_t *gstate, FILE *iob) s = *gstate; /* - * Figure out what the message delimitter string is for this + * Figure out what the message delimiter string is for this * maildrop. (This used to be part of m_Eom but I didn't like * the idea of an "if" statement that could only succeed on the * first call to m_Eom getting executed on each call, i.e., at @@ -885,7 +885,7 @@ m_Eom (m_getfld_state_t s) strncmp (text, (char *)s->edelim, s->edelimlen)) { if (i == 0 && s->msg_style == MS_MBOX) /* the final newline in the (brain damaged) unix-format - * maildrop is part of the delimitter - delete it. + * maildrop is part of the delimiter - delete it. */ return 1; diff --git a/sbr/netsec.c b/sbr/netsec.c index b85fa146..e0dd0c28 100644 --- a/sbr/netsec.c +++ b/sbr/netsec.c @@ -1015,7 +1015,7 @@ netsec_set_sasl_params(netsec_context *nsc, const char *service, /* * According to the RFC, mechanisms can only be uppercase letter, numbers, - * and a hypen or underscore. So make sure we uppercase any letters + * and a hyphen or underscore. So make sure we uppercase any letters * in case the user passed in lowercase. */ diff --git a/sbr/utils.c b/sbr/utils.c index 5784e4ce..aa344b99 100644 --- a/sbr/utils.c +++ b/sbr/utils.c @@ -469,7 +469,7 @@ nmh_init(const char *argv0, int read_context) { } /* Check to see if the user is running a different (or older, if - specified) version of nmh than they had run bfore, and notify them + specified) version of nmh than they had run before, and notify them if so. But only if read_context was set to a value to enable. */ if (allow_version_check && isatty (fileno (stdin)) && isatty (fileno (stdout)) && isatty (fileno (stderr))) { diff --git a/uip/annosbr.c b/uip/annosbr.c index aaf3aad1..c2aa8652 100644 --- a/uip/annosbr.c +++ b/uip/annosbr.c @@ -68,7 +68,7 @@ annotate (char *file, char *comp, char *text, int inplace, int datesw, int delet /* * Produce a listing of all header fields (annotations) whose field name matches - * comp. Number the listing if number is set. Treate the field bodies as path + * comp. Number the listing if number is set. Treat the field bodies as path * names and just output the last component unless text is non-NULL. We don't * care what text is set to. */ diff --git a/uip/fmttest.c b/uip/fmttest.c index d3d36497..5f52fdc3 100644 --- a/uip/fmttest.c +++ b/uip/fmttest.c @@ -510,7 +510,7 @@ process_messages(struct format *fmt, struct msgs_array *comps, done(1); seq_setprev(mp); /* set the Previous-Sequence */ - context_replace(pfolder, folder); /* update curren folder */ + context_replace(pfolder, folder); /* update current folder */ seq_save(mp); /* synchronize message sequences */ context_save(); /* save the context file */ @@ -602,7 +602,7 @@ process_single_file(FILE *in, struct msgs_array *comps, int *dat, int msgsize, } /* - * Initialize everyting else + * Initialize everything else */ if (dat[0] == -1) diff --git a/uip/folder.c b/uip/folder.c index a3cc4ec6..bfeee8fa 100644 --- a/uip/folder.c +++ b/uip/folder.c @@ -599,7 +599,7 @@ print_folders (void) } /* - * Set the current message and sychronize sequences + * Set the current message and synchronize sequences */ static int diff --git a/uip/forw.c b/uip/forw.c index 93ddf631..8746d45d 100644 --- a/uip/forw.c +++ b/uip/forw.c @@ -246,10 +246,10 @@ main (int argc, char **argv) continue; case BITSTUFFSW: - dashstuff = 1; /* trinary logic */ + dashstuff = 1; /* ternary logic */ continue; case NBITSTUFFSW: - dashstuff = -1; /* trinary logic */ + dashstuff = -1; /* ternary logic */ continue; case FROMSW: diff --git a/uip/inc.c b/uip/inc.c index 8650b8b0..790c5c5c 100644 --- a/uip/inc.c +++ b/uip/inc.c @@ -402,7 +402,7 @@ main (int argc, char **argv) if (host && !*host) host = NULL; - /* guarantee dropping group priveleges; we might not have done so earlier */ + /* guarantee dropping group privileges; we might not have done so earlier */ DROPGROUPPRIVS(); /* diff --git a/uip/mark.c b/uip/mark.c index 3972508f..7c137a10 100644 --- a/uip/mark.c +++ b/uip/mark.c @@ -244,7 +244,7 @@ print_debug (struct msgs *mp) /* * Print debugging info about all the SELECTED * messages and the sequences they are in. - * Due limitattions of snprintb(), only a limited + * Due to limitations of snprintb(), only a limited * number of sequences will be printed. See the * comments in sbr/seq_bits.c. */ diff --git a/uip/mhbuildsbr.c b/uip/mhbuildsbr.c index 51185eee..f26c81be 100644 --- a/uip/mhbuildsbr.c +++ b/uip/mhbuildsbr.c @@ -375,7 +375,7 @@ finish_field: } /* - * We initally assume we will find multiple contents in the + * We initially assume we will find multiple contents in the * draft. So create a multipart/mixed content to hold everything. * We can remove this later, if it is not needed. */ @@ -1977,7 +1977,7 @@ setup_attach_content(CT ct, char *filename) /* * Parse the Content-Type. get_ctinfo() parses MIME parameters, but - * since we're just feeding it a MIME type we have to add those ourself. + * since we're just feeding it a MIME type we have to add those ourselves. * Map that to a valid content-type label and call any initialization * function. */ @@ -2078,7 +2078,7 @@ set_disposition (CT ct) { /* * Set text content charset if it was unspecified. contains8bit - * selctions: + * selections: * 0: content does not contain 8-bit characters * 1: content contains 8-bit characters * -1: ignore content and use user's locale to determine charset diff --git a/uip/mhfixmsg.c b/uip/mhfixmsg.c index e1057887..47ae44b4 100644 --- a/uip/mhfixmsg.c +++ b/uip/mhfixmsg.c @@ -1067,7 +1067,7 @@ replace_substring (char **str, const char *old, const char *new) { char * remove_parameter (char *str, const char *name) { /* It looks to me, based on the BNF in RFC 2045, than there can't - be whitespace betwwen the parameter name and the "=", or + be whitespace between the parameter name and the "=", or between the "=" and the parameter value. */ char *param_name = concat (name, "=", NULL); char *cp; diff --git a/uip/mhlsbr.c b/uip/mhlsbr.c index cd8da99d..1cc472b5 100644 --- a/uip/mhlsbr.c +++ b/uip/mhlsbr.c @@ -20,7 +20,7 @@ * set, then addresses get split wrong (not at the spaces between commas). * To fix this correctly, putstr() should know about "atomic" strings that * must NOT be broken across lines. That's too difficult for right now - * (it turns out that there are a number of degernate cases), so in + * (it turns out that there are a number of degenerate cases), so in * oneline(), instead of * * (*onelp == '\n' && !onelp[1]) @@ -459,10 +459,10 @@ mhl (int argc, char **argv) continue; case BITSTUFFSW: - dashstuff = 1; /* trinary logic */ + dashstuff = 1; /* ternary logic */ continue; case NBITSTUFFSW: - dashstuff = -1; /* trinary logic */ + dashstuff = -1; /* ternary logic */ continue; case NBODYSW: diff --git a/uip/mhparse.c b/uip/mhparse.c index e10cd193..73296ca1 100644 --- a/uip/mhparse.c +++ b/uip/mhparse.c @@ -55,8 +55,8 @@ int npreferred; */ struct k2v SubText[] = { { "plain", TEXT_PLAIN }, - { "richtext", TEXT_RICHTEXT }, /* defined in RFC-1341 */ - { "enriched", TEXT_ENRICHED }, /* defined in RFC-1896 */ + { "richtext", TEXT_RICHTEXT }, /* defined in RFC 1341 */ + { "enriched", TEXT_ENRICHED }, /* defined in RFC 1896 */ { NULL, TEXT_UNKNOWN } /* this one must be last! */ }; @@ -1089,7 +1089,7 @@ InitMultiPart (CT ct) /* * The encoding for multipart messages must be either - * 7bit, 8bit, or binary (per RFC2045). + * 7bit, 8bit, or binary (per RFC 2045). */ if (! skip_mp_cte_check && ct->c_encoding != CE_7BIT && ct->c_encoding != CE_8BIT && ct->c_encoding != CE_BINARY) { @@ -1286,7 +1286,7 @@ last_part: * ease of choosing/displaying it later on. from a mail message on * nmh-workers, from kenh: * "Stock" MH 6.8.5 did not have a reverse_parts() function, but I - * see code in mhn that did the same thing... Acccording to the RCS + * see code in mhn that did the same thing... According to the RCS * logs, that code was around from the initial checkin of mhn.c by * John Romine in 1992, which is as far back as we have." */ @@ -3754,7 +3754,7 @@ output_params(size_t initialwidth, PM params, int *offsetout, int external) } /* - * At this point, we're either finishing a contined parameter, or + * At this point, we're either finishing a continued parameter, or * we're working on a new one. */ diff --git a/uip/mhstoresbr.c b/uip/mhstoresbr.c index 21ab2ef8..d5917211 100644 --- a/uip/mhstoresbr.c +++ b/uip/mhstoresbr.c @@ -994,7 +994,7 @@ parse_format_string (CT ct, char *cp, char *buffer, int buflen, char *dir) break; case 'p': - /* insert part number withouth leading dot */ + /* insert part number without leading dot */ if (ct->c_partno) strncpy (bp, ct->c_partno, buflen); break; diff --git a/uip/popsbr.c b/uip/popsbr.c index 591832d2..a0229576 100644 --- a/uip/popsbr.c +++ b/uip/popsbr.c @@ -730,7 +730,7 @@ pop_getline (char *s, int n, netsec_context *ns) * * We get a length back from netsec_readline, but the rest of the POP * code doesn't handle it; the assumptions are that everything from - * the network can be respresented as C strings. That should get fixed + * the network can be represented as C strings. That should get fixed * someday. */ diff --git a/uip/post.c b/uip/post.c index abd89b72..c0d10f66 100644 --- a/uip/post.c +++ b/uip/post.c @@ -169,7 +169,7 @@ struct headers { #define MVIS 0x0008 /* we've seen sighted addrs */ #define MINV 0x0010 /* we've seen blind addrs */ #define MSND 0x0020 /* we've seen a Sender: */ -#define MRSN 0x0040 /* We've seen a Resent-Sendr:*/ +#define MRSN 0x0040 /* We've seen a Resent-Sender: */ #define MEFM 0x0080 /* We've seen Envelope-From: */ #define MMIM 0x0100 /* We've seen Mime-Version: */ diff --git a/uip/refile.c b/uip/refile.c index ec539013..05a533e2 100644 --- a/uip/refile.c +++ b/uip/refile.c @@ -310,7 +310,7 @@ opnfolds (struct msgs *src_folder, struct st_fold *folders, int nfolders) /* - * Set the Previous-Sequence and then sychronize the + * Set the Previous-Sequence and then synchronize the * sequence file, for each destination folder. */ diff --git a/uip/sendsbr.c b/uip/sendsbr.c index a7c398af..792ac12f 100644 --- a/uip/sendsbr.c +++ b/uip/sendsbr.c @@ -452,7 +452,7 @@ sendaux (char **vec, int vecp, char *program, char *drft, struct stat *st) /* * child process -- send it * - * If fd is ok, then we are pushing and fd points to temp + * If fd is OK, then we are pushing and fd points to temp * file, so capture anything on stdout and stderr there. */ if (fd != NOTOK) { diff --git a/uip/sortm.c b/uip/sortm.c index 4f5602fe..2a711199 100644 --- a/uip/sortm.c +++ b/uip/sortm.c @@ -585,7 +585,7 @@ rename_msgs (struct msgs *mp, struct smsg **mlist) rename_chain (mp, mlist, j, i); /* - * Run the external hook to refile the temorary message number + * Run the external hook to refile the temporary message number * to the real place. */ -- 2.48.1 From 301b187592add311148572a2a13833a86daa92cf Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Sun, 30 Apr 2017 15:14:46 +0100 Subject: [PATCH 12/16] README.developers: Add blank lines for consistent headers. --- docs/README.developers | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/README.developers b/docs/README.developers index 692f352b..fb7ad979 100644 --- a/docs/README.developers +++ b/docs/README.developers @@ -8,6 +8,7 @@ local info best encoded in a comment) are encouraged to share their wisdom here. Following a commit checklist, the topics are organized alphabetically. + ---------------- commit checklist ---------------- @@ -30,6 +31,7 @@ platform, contact the nmh-workers list.) --------------------------------- C library/system call usage notes --------------------------------- + * Use m_mktemp2() or m_mktemp() instead of mkstemp(3) (see section on nmh temporary files below). * Use m_unlink() instead of unlink(3). -- 2.48.1 From ab6e546854f67cf582fd67a3d54813fce5aa34ac Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Sun, 30 Apr 2017 15:25:20 +0100 Subject: [PATCH 13/16] README.developers: Add pointers to Debian's Lintian's complaints. --- docs/README.developers | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/README.developers b/docs/README.developers index fb7ad979..d834b5e9 100644 --- a/docs/README.developers +++ b/docs/README.developers @@ -315,3 +315,19 @@ here; the convention for release candidates is to use something like it assumes that we tag with nmh-x_x-release from now on]: http://git.savannah.gnu.org/cgit/nmh.git/diff/?h=nmh-1_5-release?h=nmh-1_4-release + + +--------------- +after a release +--------------- + +Keep an eye on Debian's packaging, especially what patches they have to +apply, and the results of their Lintian checker, which even includes +spelling errors in man pages and binaries. + + https://sources.debian.net/src/nmh/1.6-16/debian/patches/ + https://lintian.debian.org/full/az@debian.org.html#nmh + +Perhaps some nmh developer that uses Debian, or Ubuntu?, could provide +package-building commands, including lintian(1), for Makefile.am so +Lintian's complaints are known before release. -- 2.48.1 From 00c626ff05455c94d926c31371ea966abf7abc1e Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Mon, 1 May 2017 18:33:15 +0100 Subject: [PATCH 14/16] sortm.c: Flip get_fields()'s logic to simplify. --- uip/sortm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/uip/sortm.c b/uip/sortm.c index 2a711199..6c436ba7 100644 --- a/uip/sortm.c +++ b/uip/sortm.c @@ -431,10 +431,9 @@ get_fields (char *datesw, int msg, struct smsg *smsg) if (strcmp (subjsort, "subject") == 0) { while ((c = *cp)) { if (! isspace((unsigned char) c)) { - if(uprf(cp, "re:")) - cp += 2; - else + if(!uprf(cp, "re:")) break; + cp += 2; } cp++; } -- 2.48.1 From e631a8958f0d7e0dfff45b83de861fe81301f899 Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Mon, 1 May 2017 18:42:07 +0100 Subject: [PATCH 15/16] fmt_rfc2047.c: Remove else after decode_rfc2047()'s break. --- sbr/fmt_rfc2047.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sbr/fmt_rfc2047.c b/sbr/fmt_rfc2047.c index 899b2c48..2f2c3c4f 100644 --- a/sbr/fmt_rfc2047.c +++ b/sbr/fmt_rfc2047.c @@ -189,9 +189,9 @@ decode_rfc2047 (char *str, char *dst, size_t dstlen) */ endofmime = NULL; for (pp = startofmime; *pp && *(pp+1); pp++) { - if (is_lws(*pp)) { + if (is_lws(*pp)) break; - } else if (*pp == '?' && pp[1] == '=') { + if (*pp == '?' && pp[1] == '=') { endofmime = pp; break; } -- 2.48.1 From 582d5e802ceb8e0c7f0dc5b83fdbf2a62fc10fb3 Mon Sep 17 00:00:00 2001 From: Ralph Corderoy Date: Mon, 1 May 2017 21:42:59 +0100 Subject: [PATCH 16/16] picksbr.c: Remove some else after break in plist(). --- uip/picksbr.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/uip/picksbr.c b/uip/picksbr.c index c29e669b..c0799bd9 100644 --- a/uip/picksbr.c +++ b/uip/picksbr.c @@ -681,21 +681,18 @@ plist --p2; break; } - else - lf = 0; + lf = 0; } if (c == '\n') { if (body) break; - else { - if (lf) { - body++; - break; - } - lf++; - /* Unfold by skipping the newline. */ - c = 0; - } + if (lf) { + body++; + break; + } + lf++; + /* Unfold by skipping the newline. */ + c = 0; } if (c && p1 < &linebuf[LBSIZE - 1]) *p1++ = c; -- 2.48.1