X-Git-Url: https://diplodocus.org/git/nmh/blobdiff_plain/8b10463acb041e438ca60a760ea176fc5a1623f4..94187a80bd60baab4b9c4b949ad820d730578123:/h/mh.h diff --git a/h/mh.h b/h/mh.h index 2723a42a..ebd124d1 100644 --- a/h/mh.h +++ b/h/mh.h @@ -3,6 +3,19 @@ #include +/* 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 */ @@ -16,39 +29,21 @@ #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 #define NORETURN __attribute__((__noreturn__)) -#define CHECK_PRINTF(fmt, arg) __attribute__((format(printf, fmt, arg))) -#define ALLOC_SIZE(...) __attribute__((alloc_size(__VA_ARGS__))) #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) @@ -58,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))) @@ -71,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: @@ -124,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; /* @@ -517,6 +574,4 @@ extern char *version_str; extern char *whatnowproc; extern char *whomproc; -extern void (*done) (int) NORETURN; - #include