X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/e0714781a68d957e9b136bee9dd7d637ddf59618..6db45651:/h/mh.h?ds=inline diff --git a/h/mh.h b/h/mh.h index c0c7daf7..dda0c3d2 100644 --- a/h/mh.h +++ b/h/mh.h @@ -8,9 +8,8 @@ */ #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 Nbby 8 /* number of bits/byte */ #define MAXARGS 1000 /* max arguments to exec */ #define NFOLDERS 1000 /* max folder arguments on command line */ @@ -21,7 +20,7 @@ * This macro is for use by scan, for example, so that platforms with * a small BUFSIZ can easily allocate larger buffers. */ -#define NMH_BUFSIZ (BUFSIZ>=8192 ? BUFSIZ : 8192) +#define NMH_BUFSIZ max(BUFSIZ, 8192) #ifndef FALSE #define FALSE false @@ -31,14 +30,15 @@ #endif typedef unsigned char boolean; /* not int so we can pack in a structure */ -/* If we're using gcc then give it some information about - * functions that abort. - */ +/* If we're using gcc then tell it extra information so it can do more + * compile-time checks. */ #if __GNUC__ > 2 #define NORETURN __attribute__((__noreturn__)) +#define CHECK_PRINTF(fmt, arg) __attribute__((format(printf, fmt, arg))) #define NMH_UNUSED(i) (void) i #else #define NORETURN +#define CHECK_PRINTF(fmt, arg) #define NMH_UNUSED(i) i #endif @@ -49,6 +49,9 @@ typedef unsigned char boolean; /* not int so we can pack in a structure */ * terminating NUL. */ #define LEN(s) (sizeof (s) - 1) +/* FENDNULL fends off NULL by giving an empty string instead. */ +#define FENDNULL(s) ((s) ? (s) : "") + /* * char array that keeps track of size in both bytes and characters * Usage note: @@ -176,32 +179,39 @@ extern struct swit anoyes[]; /* standard yes/no switches */ * first free slot for user defined sequences * and attributes */ -#define FFATTRSLOT 5 +#define FFATTRSLOT 4 /* * internal messages attributes (sequences) */ #define EXISTS (0) /* exists */ -#define SELECTED (2) /* selected for use */ -#define SELECT_EMPTY (3) /* "new" message */ -#define SELECT_UNSEEN (4) /* inc/show "unseen" */ - -#define MBITS "\020\01EXISTS\02!BUG!\03SELECTED\04NEW\05UNSEEN" - -/* - * type for holding the sequence set of a message - */ +#define SELECTED (1) /* selected for use */ +#define SELECT_EMPTY (2) /* "new" message */ +#define SELECT_UNSEEN (3) /* inc/show "unseen" */ + +#define MBITS "\020\01EXISTS\02SELECTED\03NEW\04UNSEEN" + +/* 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 (size_t /* initial size in bits, can be 0 */); +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); unsigned int bvector_at (bvector_t, size_t); -const unsigned long *bvector_bits (bvector_t); -size_t bvector_maxsize (bvector_t); +unsigned long bvector_first_bits (bvector_t); typedef struct svector *svector_t; @@ -220,7 +230,6 @@ void ivector_free (ivector_t); int ivector_push_back (ivector_t, int); int ivector_at (ivector_t, size_t); int *ivector_atp (ivector_t, size_t); -size_t ivector_size (ivector_t); /* * Primary structure of folder/message information @@ -266,7 +275,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 @@ -292,7 +301,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)) @@ -332,7 +341,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 @@ -345,8 +354,6 @@ struct msgs { #define other_files(mp) ((mp)->msgflags & OTHERS) #define set_other_files(mp) ((mp)->msgflags |= OTHERS) -#define NULLMP ((struct msgs *) 0) - /* * m_getfld() message parsing */ @@ -361,24 +368,31 @@ struct msgs { followed by a colon. Add one for terminating NULL. */ -#define LENERR (-2) /* Name too long error from getfld */ -#define FMTERR (-3) /* Message Format error */ -#define FLD 0 /* Field returned */ -#define FLDPLUS 1 /* Field returned with more to come */ -#define BODY 3 /* Body returned with more to come */ -#define FILEEOF 5 /* Reached end of input file */ +/* Token type or error returned from m_getfld(), and its internal state + * for the next call. */ +/* FLD detects the header's name is too long to fit in the fixed size + * array. */ +#define LENERR (-2) +/* FLD reaches EOF after the header's name, or the name is followed by + * a linefeed rather than a colon and the body buffer isn't large enough + * to pretend this header line starts the body. */ +#define FMTERR (-3) +/* The initial state, looking for headers. Returned when the header's + * value finishes. */ +#define FLD 0 +/* Another chunk of the header's value has been returned, but there's + * more to come. */ +#define FLDPLUS 1 +/* A chunk of the email's body has been returned. */ +#define BODY 3 +/* Either the end of the input file has been reached, or the delimiter + * between emails has been found and the caller should + * m_getfld_state_reset() to reset the state to FLD for continuing + * through the file. */ +#define FILEEOF 5 -struct m_getfld_state; typedef struct m_getfld_state *m_getfld_state_t; -/* - * Maildrop styles - */ -#define MS_DEFAULT 0 /* default (one msg per file) */ -#define MS_UNKNOWN 1 /* type not known yet */ -#define MS_MBOX 2 /* Unix-style "from" lines */ -#define MS_MMDF 3 /* string mmdlm2 */ - #define NOUSE 0 /* draft being re-used */ #define TFOLDER 0 /* path() given a +folder */ @@ -393,7 +407,6 @@ typedef struct m_getfld_state *m_getfld_state_t; /* * credentials management */ -struct nmh_creds; typedef struct nmh_creds *nmh_creds_t; /* @@ -426,13 +439,6 @@ extern char *defpath; /* pathname of user's profile */ extern char *ctxpath; /* pathname of user's context */ extern struct node *m_defs; /* list of profile/context entries */ -/* What style to use for generated Message-ID and Content-ID header - fields. The localname style is pid.time@localname, where time is - in seconds. The random style replaces the localname with some - (pseudo)random bytes and uses microsecond-resolution time. */ -int save_message_id_style (const char *); -char *message_id (time_t, int); - /* * These standard strings are defined in config.c. They are the * only system-dependent parameters in nmh, and thus by redefining