]> diplodocus.org Git - nmh/blobdiff - h/mh.h
Add basic support for the STLS command in POP
[nmh] / h / mh.h
diff --git a/h/mh.h b/h/mh.h
index 6b4466bf6cac3aef55bef16b8a7375b616cb7c12..bc3766e4c7d676425d9eab6e94c3900445457c25 100644 (file)
--- a/h/mh.h
+++ b/h/mh.h
@@ -1,7 +1,20 @@
 /* mh.h -- main header file for all of nmh
  */
 
-#include <h/nmh.h>
+#include "nmh.h"
+
+/* It's undefined behaviour in C99 to convert from a function pointer to
+ * a data-object pointer, e.g. void pointer.  gcc's -pedantic warns of
+ * this and can stop compilation.  POSIX requires the operation however,
+ * e.g. for dlsym(3), and so we know it's safe on POSIX platforms, e.g.
+ * the pointers are of the same size.  Thus use a union to subvert gcc's
+ * check.  The function-pointer equivalent of a void pointer is any
+ * function-pointer type as all function pointers are defined to be
+ * convertible from one another;  use the simplest available. */
+typedef union {
+    void *v;
+    void (*f)(void);
+} generic_pointer;
 
 /*
  * Well-used constants
 #define DMAXFOLDER     4       /* typical number of digits             */
 #define MAXFOLDER   1000       /* message increment                    */
 
-/* non-zero exit(3) values indicating the number of errors need to be
- * capped else they interfere with the shell's use of high seven-bit
- * values, and the shell's mapping of signals onto top-bit-set values.
- * Plus, every so often the eight-bit value will wrap to zero, wrongly
- * indicating success. */
-#define MAX_EXIT 120
-
 /*
  * This macro is for use by scan, for example, so that platforms with
  * a small BUFSIZ can easily allocate larger buffers.
  */
 #define NMH_BUFSIZ  max(BUFSIZ, 8192)
 
-#ifndef FALSE
-#define FALSE false
-#endif
-#ifndef TRUE
-#define TRUE true
-#endif
-typedef unsigned char  boolean;  /* not int so we can pack in a structure */
-
 /* If we're using gcc then tell it extra information so it can do more
  * compile-time checks. */
 #if __GNUC__ > 2
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
-#define ALLOC_SIZE(...) __attribute__((alloc_size(__VA_ARGS__)))
-#define CHECK_PRINTF(fmt, arg) __attribute__((format(printf, fmt, arg)))
-#else  /* gcc < 4.3.0 */
-#define ALLOC_SIZE(...)
-#define CHECK_PRINTF(fmt, arg)
-#endif /* gcc < 4.3.0 */
 #define NORETURN __attribute__((__noreturn__))
 #define CONST __attribute__((const))
 #define MALLOC __attribute__((malloc))
 #define NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
 #define PURE __attribute__((pure))
 #define ENDNULL __attribute__((sentinel))
-#define NMH_UNUSED(i) (void) i
 #else
 #define NORETURN
 #define CHECK_PRINTF(fmt, arg)
@@ -63,9 +53,19 @@ typedef unsigned char  boolean;  /* not int so we can pack in a structure */
 #define NONNULL(...)
 #define PURE
 #define ENDNULL
-#define NMH_UNUSED(i) i
 #endif
 
+#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+#define ALLOC_SIZE(...) __attribute__((alloc_size(__VA_ARGS__)))
+#define CHECK_PRINTF(fmt, arg) __attribute__((format(printf, fmt, arg)))
+#else
+#define ALLOC_SIZE(...)
+#define CHECK_PRINTF(fmt, arg)
+#endif
+
+/* Silence the compiler's "unused variable" warning. */
+#define NMH_UNUSED(i) (void)i
+
 /* DIM gives the number of elements in the one-dimensional array a. */
 #define DIM(a) (sizeof (a) / sizeof (*(a)))
 
@@ -76,6 +76,9 @@ typedef unsigned char  boolean;  /* not int so we can pack in a structure */
 /* FENDNULL fends off NULL by giving an empty string instead. */
 #define FENDNULL(s) ((s) ? (s) : "")
 
+/* If not specified in a file and PAGER is NULL or empty. */
+#define DEFAULT_PAGER "more"
+
 /*
  * char array that keeps track of size in both bytes and characters
  * Usage note:
@@ -129,11 +132,60 @@ struct swit {
 
     char *sw;
 
-    /* The minchars field is apparently used like this:
+    /*
+     * The previous comments here about minchars was incorrect; this is
+     * (AFAIK) the correct information.
+     *
+     * A minchars of "0" means this switch can be abbreviated to any number
+     * of characters (assuming the abbreviation does not match any other
+     * switches).
+     *
+     * A positive value for minchars means that when the user specifies
+     * the switch on the command line, it MUST be at least that many
+     * characters.
+     *
+     * A negative value for minchars means that the user-given switch must
+     * be that many characters, but will NOT be shown in -help output.
+     *
+     * So what should I use?  Well, for nearly all switches you want to specify
+     * a minchars of 0.  smatch will report an error if the switch given
+     * matches more than one entry.  Let's say you have the following
+     * two switches: -append and -apply.  -app will return AMBIGSW from
+     * smatch. -appe and -appl will work fine.  So 0 is the correct choice
+     * here.
+     *
+     * The only time you want to specify a minimum length is if you have
+     * a switch who's name is a substring of a longer switch.  The example
+     * you see sometimes in the code is -form and -format.  If you gave a
+     * minchars of 0 for both, -form would match both -form AND -format,
+     * and you'd always get AMBIGSW.  The solution is to specify a minchars
+     * of 5 for -format; that way just -form will just match -form.  When
+     * a minchars is given, the -help output will specify the minimum
+     * switch length, like this:
+     *
+     * -(forma)t string
+     *
+     * A negative value works the same way, except the switch isn't printed
+     * in -help.  Why would you do that?  Well, there are a few instances
+     * of internal switches and some switches which only appear if a particular
+     * feature is enabled (such as SASL or TLS).  Lately I've been of the
+     * opinion that all switches should be specified, even if they are
+     * internal or use non-available features, but currently the smatch
+     * code still supports this.
+     *
+     * This isn't the appropriate place to make this note, but since I was
+     * here ... when creating switches, you should make a negation switch
+     * right after the enabling switch.  E.g. you should have:
+     *
+     * X("sasl", 0, SASLSW) \
+     * X("nosasl", 0, NOSASLSW) \
+     *
+     * in the switch array, because when you run -help, print_sw will detect
+     * this and output:
+     *
+     * -[no]sasl
+     */
 
-       -# : Switch can be abbreviated to # characters; switch hidden in -help.
-       0  : Switch can't be abbreviated;               switch shown in -help.
-       #  : Switch can be abbreviated to # characters; switch shown in -help. */
     int minchars;
 
     /*
@@ -215,45 +267,7 @@ extern struct swit anoyes[];       /* standard yes/no switches */
 
 #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 (void);
-void bvector_init(struct bvector *bv) NONNULL(1);
-void bvector_copy (bvector_t, bvector_t) NONNULL(1, 2);
-void bvector_free (bvector_t) NONNULL(1);
-void bvector_fini(struct bvector *bv) NONNULL(1);
-void bvector_clear (bvector_t, size_t) NONNULL(1);
-void bvector_clear_all (bvector_t) NONNULL(1);
-void bvector_set (bvector_t, size_t) NONNULL(1);
-unsigned int bvector_at (bvector_t, size_t) NONNULL(1) PURE;
-unsigned long bvector_first_bits (bvector_t) NONNULL(1) PURE;
-
-typedef struct svector *svector_t;
-
-svector_t svector_create (size_t);
-void svector_free (svector_t) NONNULL(1);
-char *svector_push_back (svector_t, char *) NONNULL(1);
-char *svector_at (svector_t, size_t) NONNULL(1);
-char **svector_find(svector_t, const char *) NONNULL(1) PURE;
-char **svector_strs (svector_t) NONNULL(1) PURE;
-size_t svector_size (svector_t) NONNULL(1) PURE;
-
-typedef struct ivector *ivector_t;
-
-ivector_t ivector_create (size_t);
-void ivector_free (ivector_t) NONNULL(1);
-int ivector_push_back (ivector_t, int) NONNULL(1);
-int ivector_at (ivector_t, size_t) NONNULL(1);
-int *ivector_atp (ivector_t, size_t) NONNULL(1);
+#include "sbr/vector.h"
 
 /*
  * Primary structure of folder/message information
@@ -522,6 +536,4 @@ extern char *version_str;
 extern char *whatnowproc;
 extern char *whomproc;
 
-extern void (*done) (int) NORETURN;
-
-#include <h/prototypes.h>
+#include "prototypes.h"