X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/3e7c0fe01050063cd415e667e7b99f537d41f689..b3d4a4452c332fc3550db3fbdf9e02027b41e985:/h/mh.h?ds=sidebyside diff --git a/h/mh.h b/h/mh.h index abec7c88..bf746f18 100644 --- a/h/mh.h +++ b/h/mh.h @@ -1,7 +1,20 @@ /* mh.h -- main header file for all of nmh */ -#include +#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 @@ -22,14 +35,6 @@ */ #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 @@ -39,7 +44,6 @@ typedef unsigned char boolean; /* not int so we can pack in a structure */ #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) @@ -49,7 +53,6 @@ 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) @@ -60,6 +63,9 @@ typedef unsigned char boolean; /* not int so we can pack in a structure */ #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))) @@ -126,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; /* @@ -519,6 +574,4 @@ extern char *version_str; extern char *whatnowproc; extern char *whomproc; -extern void (*done) (int) NORETURN; - -#include +#include "prototypes.h"