summaryrefslogtreecommitdiff
path: root/include/libHX/option.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/libHX/option.h')
-rw-r--r--include/libHX/option.h260
1 files changed, 260 insertions, 0 deletions
diff --git a/include/libHX/option.h b/include/libHX/option.h
new file mode 100644
index 0000000..3b8187f
--- /dev/null
+++ b/include/libHX/option.h
@@ -0,0 +1,260 @@
+#ifndef _LIBHX_OPTION_H
+#define _LIBHX_OPTION_H 1
+
+#ifdef __cplusplus
+# include <cstddef>
+# include <cstdio>
+#else
+# include <stddef.h>
+# include <stdio.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __libhx_internal_hxmc_t_defined
+#define __libhx_internal_hxmc_t_defined 1
+typedef char hxmc_t;
+#endif
+
+struct HXoption;
+
+/*
+ * FORMAT.C
+ */
+extern struct HXformat_map *HXformat_init(void);
+extern void HXformat_free(struct HXformat_map *);
+extern int HXformat_add(struct HXformat_map *, const char *, const void *,
+ unsigned int);
+extern int HXformat_aprintf(const struct HXformat_map *,
+ hxmc_t **, const char *);
+extern int HXformat_sprintf(const struct HXformat_map *,
+ char *, size_t, const char *);
+extern int HXformat_fprintf(const struct HXformat_map *,
+ FILE *, const char *);
+
+/*
+ * OPT.C
+ */
+
+/**
+ * Available types for struct HXoption.type.
+ * %HXTYPE_NONE: [-o] (int *) No argument; counts presence.
+ * %HXTYPE_VAL: [-o] (int *) Set to value in .val.
+ * %HXTYPE_SVAL: [-o] (const char *) Set to value in .uptr.
+ * %HXTYPE_BOOL: [fo] (int *) Parse argument as boolean
+ * ("yes", "no", "true", "false", 0 or non-zero)
+ * %HXTYPE_BYTE: [fo] (unsigned char *) Take first char of argument
+ * %HXTYPE_UCHAR: [fo] (unsigned char *) An integer.
+ * %HXTYPE_CHAR: [fo] (char *) An integer.
+ * %HXTYPE_USHORT: [fo] (unsigned short *) An integer.
+ * %HXTYPE_SHORT: [fo] (short *) An integer.
+ * %HXTYPE_UINT: [fo] (unsigned int *) An integer.
+ * %HXTYPE_INT: [fo] (int *) An integer.
+ * %HXTYPE_ULONG: [fo] (unsigned long *) An integer.
+ * %HXTYPE_LONG: [fo] (long *) An integer.
+ * %HXTYPE_ULLONG: [fo] (unsigned long long *) An integer.
+ * %HXTYPE_LLONG: [fo] (long long *) An integer.
+ * %HXTYPE_FLOAT: [fo] (float *) Read a floating point number
+ * %HXTYPE_DOUBLE: [fo] (double *) Read a floating point number
+ * %HXTYPE_STRING: [fo] (char **) Any string.
+ * %HXTYPE_STRP: [f-] (const char *const *) A string.
+ * %HXTYPE_STRDQ: [-o] (struct HXdeque *) A string.
+ * %HXTYPE_UINT8: [-o] (uint8_t *) An integer.
+ * %HXTYPE_UINT16: [-o] (uint8_t *) An integer.
+ * %HXTYPE_UINT32: [-o] (uint8_t *) An integer.
+ * %HXTYPE_UINT64: [-o] (uint8_t *) An integer.
+ * %HXTYPE_INT8: [-o] (uint8_t *) An integer.
+ * %HXTYPE_INT16: [-o] (uint8_t *) An integer.
+ * %HXTYPE_INT32: [-o] (uint8_t *) An integer.
+ * %HXTYPE_INT64: [-o] (uint8_t *) An integer.
+ * %HXTYPE_MCSTR: [-o] (hxmc_t *) A string.
+ * %HXTYPE_XSNTMARK: [-o] Internal sentinal marker (used in HXOPT_TABLEEND)
+ * %HXTYPE_XHELP: [-o] Internal helper marker (used in HXOPT_AUTOHELP)
+ * %HXTYPE_SIZE_T: [-o] (size_t *) An integer.
+ *
+ * Type expected of struct HXoption.ptr is given in ().
+ * HX_getopt (o) and HXformat_* (f) support different sets, marked with [].
+ */
+enum HX_option_type {
+ HXTYPE_NONE = 0,
+ HXTYPE_VAL,
+ HXTYPE_SVAL,
+ HXTYPE_BOOL,
+ HXTYPE_BYTE,
+ HXTYPE_UCHAR, /* 5 */
+ HXTYPE_CHAR,
+ HXTYPE_USHORT,
+ HXTYPE_SHORT,
+ HXTYPE_UINT,
+ HXTYPE_INT, /* 10 */
+ HXTYPE_ULONG,
+ HXTYPE_LONG,
+ HXTYPE_ULLONG,
+ HXTYPE_LLONG,
+ HXTYPE_FLOAT, /* 15 */
+ HXTYPE_DOUBLE,
+ HXTYPE_STRING,
+ HXTYPE_STRP, /* (const char **) */
+ HXTYPE_STRDQ,
+ HXTYPE_UINT8, /* 20 */
+ HXTYPE_UINT16,
+ HXTYPE_UINT32,
+ HXTYPE_UINT64,
+ HXTYPE_INT8,
+ HXTYPE_INT16, /* 25 */
+ HXTYPE_INT32,
+ HXTYPE_INT64,
+ HXTYPE_MCSTR,
+ HXTYPE_XSNTMARK,
+ HXTYPE_XHELP, /* 30 */
+ HXTYPE_SIZE_T,
+};
+
+/**
+ * Extra flags to be OR'ed into struct HXoption.type.
+ * %HXOPT_OPTIONAL: argument to option is optional
+ * (it's bad taste to use this)
+ * %HXOPT_INC: increase variable pointed to by .ptr.
+ * (only applies to %HXTYPE_NONE)
+ * %HXOPT_DEC: increase variable pointed to by .ptr.
+ * (only applies to %HXTYPE_NONE)
+ * %HXOPT_NOT: negate input (*ptr), this is done before OR/AND
+ * %HXOPT_OR: OR *ptr by argument
+ * %HXOPT_AND: AND *ptr by argument
+ * %HXOPT_XOR: XOR *ptr by argument
+ */
+enum {
+ HXOPT_OPTIONAL = 1 << 6,
+ HXOPT_INC = 1 << 7,
+ HXOPT_DEC = 1 << 8,
+ HXOPT_NOT = 1 << 9,
+ HXOPT_OR = 1 << 10,
+ HXOPT_AND = 1 << 11,
+ HXOPT_XOR = 1 << 12,
+};
+
+/**
+ * Flags (4th arg) to HX_getopt.
+ * %HXOPT_PTHRU: pass-through unknown options to new argv
+ * %HXOPT_DESTROY_OLD: destroy old argv after parsing is successful
+ * %HXOPT_QUIET: do not output any warnings to stderr
+ * %HXOPT_HELPONERR: print out help when a parsing error occurs
+ * %HXOPT_USAGEONERR: print out short usage when a parsing error occurs
+ * %HXOPT_RQ_ORDER: require option order/POSIX mode:
+ * first non-option terminates option processing
+ */
+enum {
+ HXOPT_PTHRU = 1 << 0,
+ HXOPT_DESTROY_OLD = 1 << 1,
+ HXOPT_QUIET = 1 << 2,
+ HXOPT_HELPONERR = 1 << 3,
+ HXOPT_USAGEONERR = 1 << 4,
+ HXOPT_RQ_ORDER = 1 << 5,
+};
+
+/**
+ * (Positive-ranged) return values for HX_getopt.
+ * %HXOPT_ERR_SUCCESS: success
+ * %HXOPT_ERR_UNKN: unknown option was encountered
+ * %HXOPT_ERR_VOID: long option takes no value
+ * %HXOPT_ERR_MIS: option requires a value argument
+ */
+enum {
+ HXOPT_ERR_SUCCESS = 0,
+ HXOPT_ERR_UNKN,
+ HXOPT_ERR_VOID,
+ HXOPT_ERR_MIS,
+};
+
+/**
+ * Extra flags to be OR'ed into HXformat_add()'s 4th arg.
+ * %HXFORMAT_IMMED: do not dereference the 4th arg to get at the value
+ */
+enum {
+ HXFORMAT_IMMED = 1 << 13,
+};
+
+/**
+ * Flags for HX_shconfig_pv()
+ * %SHCONF_ONE: only read one configuration file
+ */
+enum {
+ SHCONF_ONE = 1 << 0,
+};
+
+/**
+ * Flags in struct HXoptcb.flags
+ * %HXOPTCB_BY_LONG: cb was called by invocation of @current->ln
+ * %HXOPTCB_BY_SHORT: cb was called by invocation of @current->sh
+ */
+enum {
+ HXOPTCB_BY_LONG = 1 << 0,
+ HXOPTCB_BY_SHORT = 1 << 1,
+};
+
+struct HXoptcb {
+ const struct HXoption *table, *current;
+ const char *data;
+ union {
+ double data_dbl;
+ long data_long;
+ };
+ unsigned int flags;
+};
+
+/**
+ * @ln: long option string (without "--"), or %NULL
+ * @sh: short option character, or '\0'
+ * @type: type of variable pointed to by .ptr
+ * @ptr: pointer to variable to set/update
+ * @uptr: freeform user-supplied pointer;
+ * in case of %HXTYPE_SVAL, this is the specific value to set
+ * @cb: callback function to invoke, or %NULL
+ * @val: specific value to set if type == HXTYPE_VAL
+ * @help: help string to display
+ * @htyp: type string to show in option's help
+ */
+struct HXoption {
+ const char *ln;
+ char sh;
+ unsigned int type;
+ void *ptr, *uptr;
+ void (*cb)(const struct HXoptcb *);
+ int val;
+ const char *help, *htyp;
+};
+
+extern int HX_getopt(const struct HXoption *, int *, const char ***,
+ unsigned int);
+extern void HX_getopt_help(const struct HXoptcb *, FILE *);
+extern void HX_getopt_help_cb(const struct HXoptcb *);
+extern void HX_getopt_usage(const struct HXoptcb *, FILE *);
+extern void HX_getopt_usage_cb(const struct HXoptcb *);
+extern int HX_shconfig(const char *, const struct HXoption *);
+extern struct HXmap *HX_shconfig_map(const char *);
+extern int HX_shconfig_pv(const char **, const char *,
+ const struct HXoption *, unsigned int);
+extern void HX_shconfig_free(const struct HXoption *);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#ifndef __cplusplus
+# define HXOPT_AUTOHELP \
+ {.ln = "help", .sh = '?', .type = HXTYPE_XHELP, \
+ .cb = HX_getopt_help_cb, .help = "Show this help message"}, \
+ {.ln = "usage", .type = HXTYPE_NONE, \
+ .cb = HX_getopt_usage_cb, \
+ .help = "Display brief usage message"}
+# define HXOPT_TABLEEND {.type = HXTYPE_XSNTMARK}
+#else
+# define HXOPT_AUTOHELP \
+ {NULL, '?', HXTYPE_XHELP, NULL, NULL, HX_getopt_help_cb, \
+ 0, "Show this help message"}
+# define HXOPT_TABLEEND {NULL, 0, HXTYPE_XSNTMARK}
+#endif
+
+#endif /* _LIBHX_OPTION_H */