summaryrefslogtreecommitdiff
path: root/src/lib/ecore/Ecore_Getopt.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/ecore/Ecore_Getopt.h')
-rw-r--r--src/lib/ecore/Ecore_Getopt.h419
1 files changed, 419 insertions, 0 deletions
diff --git a/src/lib/ecore/Ecore_Getopt.h b/src/lib/ecore/Ecore_Getopt.h
new file mode 100644
index 0000000000..0a11787d4d
--- /dev/null
+++ b/src/lib/ecore/Ecore_Getopt.h
@@ -0,0 +1,419 @@
+#ifndef _ECORE_GETOPT_H
+#define _ECORE_GETOPT_H
+
+#include <stdio.h>
+#include <Eina.h>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef _WIN32
+# ifdef EFL_ECORE_BUILD
+# ifdef DLL_EXPORT
+# define EAPI __declspec(dllexport)
+# else
+# define EAPI
+# endif /* ! DLL_EXPORT */
+# else
+# define EAPI __declspec(dllimport)
+# endif /* ! EFL_ECORE_BUILD */
+#else
+# ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+# else
+# define EAPI
+# endif
+#endif /* ! _WIN32 */
+
+/**
+ * @file Ecore_Getopt.h
+ * @brief Contains powerful getopt replacement.
+ *
+ * This replacement handles both short (-X) or long options (--ABC)
+ * options, with various actions supported, like storing one value and
+ * already converting to required type, counting number of
+ * occurrences, setting true or false values, show help, license,
+ * copyright and even support user-defined callbacks.
+ *
+ * It is provided a set of C Pre Processor macros so definition is
+ * straightforward.
+ *
+ * Values will be stored elsewhere indicated by an array of pointers
+ * to values, it is given in separate to parser description so you can
+ * use multiple values with the same parser.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ ECORE_GETOPT_ACTION_STORE,
+ ECORE_GETOPT_ACTION_STORE_CONST,
+ ECORE_GETOPT_ACTION_STORE_TRUE,
+ ECORE_GETOPT_ACTION_STORE_FALSE,
+ ECORE_GETOPT_ACTION_CHOICE,
+ ECORE_GETOPT_ACTION_APPEND,
+ ECORE_GETOPT_ACTION_COUNT,
+ ECORE_GETOPT_ACTION_CALLBACK,
+ ECORE_GETOPT_ACTION_HELP,
+ ECORE_GETOPT_ACTION_VERSION,
+ ECORE_GETOPT_ACTION_COPYRIGHT,
+ ECORE_GETOPT_ACTION_LICENSE
+} Ecore_Getopt_Action;
+
+typedef enum {
+ ECORE_GETOPT_TYPE_STR,
+ ECORE_GETOPT_TYPE_BOOL,
+ ECORE_GETOPT_TYPE_SHORT,
+ ECORE_GETOPT_TYPE_INT,
+ ECORE_GETOPT_TYPE_LONG,
+ ECORE_GETOPT_TYPE_USHORT,
+ ECORE_GETOPT_TYPE_UINT,
+ ECORE_GETOPT_TYPE_ULONG,
+ ECORE_GETOPT_TYPE_DOUBLE
+} Ecore_Getopt_Type;
+
+typedef enum {
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO = 0,
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES = 1,
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL = 3
+} Ecore_Getopt_Desc_Arg_Requirement;
+
+typedef union _Ecore_Getopt_Value Ecore_Getopt_Value;
+
+typedef struct _Ecore_Getopt_Desc_Store Ecore_Getopt_Desc_Store;
+typedef struct _Ecore_Getopt_Desc_Callback Ecore_Getopt_Desc_Callback;
+typedef struct _Ecore_Getopt_Desc Ecore_Getopt_Desc;
+typedef struct _Ecore_Getopt Ecore_Getopt;
+
+union _Ecore_Getopt_Value
+{
+ char **strp;
+ unsigned char *boolp;
+ short *shortp;
+ int *intp;
+ long *longp;
+ unsigned short *ushortp;
+ unsigned int *uintp;
+ unsigned long *ulongp;
+ double *doublep;
+ Eina_List **listp;
+ void **ptrp;
+};
+
+struct _Ecore_Getopt_Desc_Store
+{
+ Ecore_Getopt_Type type; /**< type of data being handled */
+ Ecore_Getopt_Desc_Arg_Requirement arg_req;
+ union
+ {
+ const char *strv;
+ Eina_Bool boolv;
+ short shortv;
+ int intv;
+ long longv;
+ unsigned short ushortv;
+ unsigned int uintv;
+ unsigned long ulongv;
+ double doublev;
+ } def;
+};
+
+struct _Ecore_Getopt_Desc_Callback
+{
+ Eina_Bool (*func)(const Ecore_Getopt *parser,
+ const Ecore_Getopt_Desc *desc,
+ const char *str,
+ void *data,
+ Ecore_Getopt_Value *storage);
+ const void *data;
+ Ecore_Getopt_Desc_Arg_Requirement arg_req;
+ const char *def;
+};
+
+struct _Ecore_Getopt_Desc
+{
+ char shortname; /**< used with a single dash */
+ const char *longname; /**< used with double dashes */
+ const char *help; /**< used by --help/ecore_getopt_help() */
+ const char *metavar; /**< used by ecore_getopt_help() with nargs > 0 */
+
+ Ecore_Getopt_Action action; /**< define how to handle it */
+ union
+ {
+ const Ecore_Getopt_Desc_Store store;
+ const void *store_const;
+ const char *const *choices; /* NULL terminated. */
+ const Ecore_Getopt_Type append_type;
+ const Ecore_Getopt_Desc_Callback callback;
+ const void *dummy;
+ } action_param;
+};
+
+struct _Ecore_Getopt
+{
+ const char *prog; /**< to be used when ecore_app_args_get() fails */
+ const char *usage; /**< usage example, %prog is replaced */
+ const char *version; /**< if exists, --version will work */
+ const char *copyright; /**< if exists, --copyright will work */
+ const char *license; /**< if exists, --license will work */
+ const char *description; /**< long description, possible multiline */
+ Eina_Bool strict : 1; /**< fail on errors */
+ const Ecore_Getopt_Desc descs[]; /* NULL terminated. */
+};
+
+#define ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type, arg_requirement, default_value) \
+ {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_STORE, \
+ {.store = {type, arg_requirement, default_value}}}
+
+#define ECORE_GETOPT_STORE(shortname, longname, help, type) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, NULL, type, \
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, {})
+
+#define ECORE_GETOPT_STORE_STR(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_STR)
+#define ECORE_GETOPT_STORE_BOOL(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_BOOL)
+#define ECORE_GETOPT_STORE_SHORT(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_SHORT)
+#define ECORE_GETOPT_STORE_INT(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_INT)
+#define ECORE_GETOPT_STORE_LONG(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_LONG)
+#define ECORE_GETOPT_STORE_USHORT(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_USHORT)
+#define ECORE_GETOPT_STORE_UINT(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_UINT)
+#define ECORE_GETOPT_STORE_ULONG(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_ULONG)
+#define ECORE_GETOPT_STORE_DOUBLE(shortname, longname, help) \
+ ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_DOUBLE)
+
+#define ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, type) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type, \
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, {})
+
+#define ECORE_GETOPT_STORE_METAVAR_STR(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_STR)
+#define ECORE_GETOPT_STORE_METAVAR_BOOL(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_BOOL)
+#define ECORE_GETOPT_STORE_METAVAR_SHORT(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_SHORT)
+#define ECORE_GETOPT_STORE_METAVAR_INT(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_INT)
+#define ECORE_GETOPT_STORE_METAVAR_LONG(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_LONG)
+#define ECORE_GETOPT_STORE_METAVAR_USHORT(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_USHORT)
+#define ECORE_GETOPT_STORE_METAVAR_UINT(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_UINT)
+#define ECORE_GETOPT_STORE_METAVAR_ULONG(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_ULONG)
+#define ECORE_GETOPT_STORE_METAVAR_DOUBLE(shortname, longname, help, metavar) \
+ ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_DOUBLE)
+
+#define ECORE_GETOPT_STORE_DEF(shortname, longname, help, type, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, NULL, type, \
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL, \
+ default_value)
+
+#define ECORE_GETOPT_STORE_DEF_STR(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_STR, \
+ {.strv = default_value})
+#define ECORE_GETOPT_STORE_DEF_BOOL(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_BOOL, \
+ {.boolv = default_value})
+#define ECORE_GETOPT_STORE_DEF_SHORT(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_SHORT, \
+ {.shortv = default_value})
+#define ECORE_GETOPT_STORE_DEF_INT(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_INT, \
+ {.intv = default_value})
+#define ECORE_GETOPT_STORE_DEF_LONG(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_LONG, \
+ {.longv = default_value})
+#define ECORE_GETOPT_STORE_DEF_USHORT(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_USHORT, \
+ {.ushortv = default_value})
+#define ECORE_GETOPT_STORE_DEF_UINT(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_UINT, \
+ {.uintv = default_value})
+#define ECORE_GETOPT_STORE_DEF_ULONG(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_ULONG, \
+ {.ulongv = default_value})
+#define ECORE_GETOPT_STORE_DEF_DOUBLE(shortname, longname, help, default_value) \
+ ECORE_GETOPT_STORE_DEF(shortname, longname, help, \
+ ECORE_GETOPT_TYPE_DOUBLE, \
+ {.doublev = default_value})
+
+#define ECORE_GETOPT_STORE_FULL_STR(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_STR, \
+ arg_requirement, \
+ {.strv = default_value})
+#define ECORE_GETOPT_STORE_FULL_BOOL(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_BOOL, \
+ arg_requirement, \
+ {.boolv = default_value})
+#define ECORE_GETOPT_STORE_FULL_SHORT(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_SHORT, \
+ arg_requirement, \
+ {.shortv = default_value})
+#define ECORE_GETOPT_STORE_FULL_INT(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_INT, \
+ arg_requirement, \
+ {.intv = default_value})
+#define ECORE_GETOPT_STORE_FULL_LONG(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_LONG, \
+ arg_requirement, \
+ {.longv = default_value})
+#define ECORE_GETOPT_STORE_FULL_USHORT(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_USHORT, \
+ arg_requirement, \
+ {.ushortv = default_value})
+#define ECORE_GETOPT_STORE_FULL_UINT(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_UINT, \
+ arg_requirement, \
+ {.uintv = default_value})
+#define ECORE_GETOPT_STORE_FULL_ULONG(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_ULONG, \
+ arg_requirement, \
+ {.ulongv = default_value})
+#define ECORE_GETOPT_STORE_FULL_DOUBLE(shortname, longname, help, metavar, arg_requirement, default_value) \
+ ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, \
+ ECORE_GETOPT_TYPE_DOUBLE, \
+ arg_requirement, \
+ {.doublev = default_value})
+
+#define ECORE_GETOPT_STORE_CONST(shortname, longname, help, value) \
+ {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_CONST, \
+ {.store_const = value}}
+#define ECORE_GETOPT_STORE_TRUE(shortname, longname, help) \
+ {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_TRUE, \
+ {.dummy = NULL}}
+#define ECORE_GETOPT_STORE_FALSE(shortname, longname, help) \
+ {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_FALSE, \
+ {.dummy = NULL}}
+
+#define ECORE_GETOPT_CHOICE(shortname, longname, help, choices_array) \
+ {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_CHOICE, \
+ {.choices = choices_array}}
+#define ECORE_GETOPT_CHOICE_METAVAR(shortname, longname, help, metavar, choices_array) \
+ {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_CHOICE, \
+ {.choices = choices_array}}
+
+#define ECORE_GETOPT_APPEND(shortname, longname, help, sub_type) \
+ {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_APPEND, \
+ {.append_type = sub_type}}
+#define ECORE_GETOPT_APPEND_METAVAR(shortname, longname, help, metavar, type) \
+ {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_APPEND, \
+ {.append_type = type}}
+
+#define ECORE_GETOPT_COUNT(shortname, longname, help) \
+ {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_COUNT, \
+ {.dummy = NULL}}
+
+#define ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, metavar, callback_func, callback_data, argument_requirement, default_value) \
+ {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_CALLBACK, \
+ {.callback = {callback_func, callback_data, \
+ argument_requirement, default_value}}}
+#define ECORE_GETOPT_CALLBACK_NOARGS(shortname, longname, help, callback_func, callback_data) \
+ ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, NULL, \
+ callback_func, callback_data, \
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO, \
+ NULL)
+#define ECORE_GETOPT_CALLBACK_ARGS(shortname, longname, help, metavar, callback_func, callback_data) \
+ ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, metavar, \
+ callback_func, callback_data, \
+ ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, \
+ NULL)
+
+#define ECORE_GETOPT_HELP(shortname, longname) \
+ {shortname, longname, "show this message.", NULL, \
+ ECORE_GETOPT_ACTION_HELP, \
+ {.dummy = NULL}}
+
+#define ECORE_GETOPT_VERSION(shortname, longname) \
+ {shortname, longname, "show program version.", NULL, \
+ ECORE_GETOPT_ACTION_VERSION, \
+ {.dummy = NULL}}
+
+#define ECORE_GETOPT_COPYRIGHT(shortname, longname) \
+ {shortname, longname, "show copyright.", NULL, \
+ ECORE_GETOPT_ACTION_COPYRIGHT, \
+ {.dummy = NULL}}
+
+#define ECORE_GETOPT_LICENSE(shortname, longname) \
+ {shortname, longname, "show license.", NULL, \
+ ECORE_GETOPT_ACTION_LICENSE, \
+ {.dummy = NULL}}
+
+#define ECORE_GETOPT_SENTINEL {0, NULL, NULL, NULL, 0, {.dummy = NULL}}
+
+#define ECORE_GETOPT_VALUE_STR(val) {.strp = &(val)}
+#define ECORE_GETOPT_VALUE_BOOL(val) {.boolp = &(val)}
+#define ECORE_GETOPT_VALUE_SHORT(val) {.shortp = &(val)}
+#define ECORE_GETOPT_VALUE_INT(val) {.intp = &(val)}
+#define ECORE_GETOPT_VALUE_LONG(val) {.longp = &(val)}
+#define ECORE_GETOPT_VALUE_USHORT(val) {.ushortp = &(val)}
+#define ECORE_GETOPT_VALUE_UINT(val) {.uintp = &(val)}
+#define ECORE_GETOPT_VALUE_ULONG(val) {.ulongp = &(val)}
+#define ECORE_GETOPT_VALUE_DOUBLE(val) {.doublep = &(val)}
+#define ECORE_GETOPT_VALUE_PTR(val) {.ptrp = &(val)}
+#define ECORE_GETOPT_VALUE_PTR_CAST(val) {.ptrp = (void **)&(val)}
+#define ECORE_GETOPT_VALUE_LIST(val) {.listp = &(val)}
+#define ECORE_GETOPT_VALUE_NONE {.ptrp = NULL}
+
+EAPI void
+ecore_getopt_help(FILE *fp,
+ const Ecore_Getopt *info);
+
+EAPI Eina_Bool
+ ecore_getopt_parser_has_duplicates(const Ecore_Getopt *parser);
+EAPI int
+ ecore_getopt_parse(const Ecore_Getopt *parser,
+ Ecore_Getopt_Value *values,
+ int argc,
+ char **argv);
+
+EAPI Eina_List *ecore_getopt_list_free(Eina_List *list);
+
+/* helper functions to be used with ECORE_GETOPT_CALLBACK_*() */
+EAPI Eina_Bool
+ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser,
+ const Ecore_Getopt_Desc *desc,
+ const char *str,
+ void *data,
+ Ecore_Getopt_Value *storage);
+EAPI Eina_Bool
+ecore_getopt_callback_size_parse(const Ecore_Getopt *parser,
+ const Ecore_Getopt_Desc *desc,
+ const char *str,
+ void *data,
+ Ecore_Getopt_Value *storage);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _ECORE_GETOPT_H */