summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGustavo Sverzut Barbieri <barbieri@profusion.mobi>2013-12-17 18:08:27 -0200
committerGustavo Sverzut Barbieri <barbieri@profusion.mobi>2013-12-17 18:08:27 -0200
commit1c1f9ea0e1a2c4014d5cb5ca0f749164dcd384e5 (patch)
tree1a45360e5ed52b8c9d81be3ac3c9d2caa8867950
parent99ba5822c84c6716ee51af93115a0bb0984464ef (diff)
add great ecore_getopt example.
should cover and explain getopt usage and serve as base for applications that want to use it (all efl should!)
-rw-r--r--src/examples/ecore/.gitignore1
-rw-r--r--src/examples/ecore/Makefile.am9
-rw-r--r--src/examples/ecore/Makefile.examples3
-rw-r--r--src/examples/ecore/ecore_getopt_example.c339
4 files changed, 349 insertions, 3 deletions
diff --git a/src/examples/ecore/.gitignore b/src/examples/ecore/.gitignore
index a04eae980..d77145eaf 100644
--- a/src/examples/ecore/.gitignore
+++ b/src/examples/ecore/.gitignore
@@ -37,3 +37,4 @@
/ecore_file_download_example
/ecore_imf_example
/ecore_pipe_gstreamer_example
+/ecore_getopt_example
diff --git a/src/examples/ecore/Makefile.am b/src/examples/ecore/Makefile.am
index 129601eb7..9edeb1fc3 100644
--- a/src/examples/ecore/Makefile.am
+++ b/src/examples/ecore/Makefile.am
@@ -64,7 +64,8 @@ ecore_poller_example \
ecore_server_bench \
ecore_thread_example \
ecore_time_functions_example \
-ecore_timer_example
+ecore_timer_example \
+ecore_getopt_example
ECORE_COMMON_LDADD = \
$(top_builddir)/src/lib/ecore/libecore.la \
@@ -223,6 +224,9 @@ ecore_time_functions_example_LDADD = $(ECORE_COMMON_LDADD)
ecore_timer_example_SOURCES = ecore_timer_example.c
ecore_timer_example_LDADD = $(ECORE_COMMON_LDADD)
+ecore_getopt_example_SOURCES = ecore_getopt_example.c
+ecore_getopt_example_LDADD = $(ECORE_COMMON_LDADD)
+
SRCS = \
ecore_animator_example.c \
ecore_audio_custom.c \
@@ -263,7 +267,8 @@ ecore_poller_example.c \
ecore_server_bench.c \
ecore_thread_example.c \
ecore_time_functions_example.c \
-ecore_timer_example.c
+ecore_timer_example.c \
+ecore_getopt_example.c
DATA_FILES = red.png Makefile.examples
diff --git a/src/examples/ecore/Makefile.examples b/src/examples/ecore/Makefile.examples
index 30a952186..f8ac82d50 100644
--- a/src/examples/ecore/Makefile.examples
+++ b/src/examples/ecore/Makefile.examples
@@ -39,7 +39,8 @@ EXAMPLES= ecore_animator_example \
ecore_server_bench \
ecore_thread_example \
ecore_time_functions_example \
- ecore_timer_example
+ ecore_timer_example \
+ ecore_getopt_example
all: examples
examples: $(EXAMPLES)
diff --git a/src/examples/ecore/ecore_getopt_example.c b/src/examples/ecore/ecore_getopt_example.c
new file mode 100644
index 000000000..dc91f0c23
--- /dev/null
+++ b/src/examples/ecore/ecore_getopt_example.c
@@ -0,0 +1,339 @@
+//Compile with:
+// gcc -o ecore_getopt_example ecore_getopt_example.c `pkg-config --libs --cflags ecore eina`
+
+#include <Ecore.h>
+#include <Ecore_Getopt.h>
+#include <assert.h>
+
+static const char * available_choices[] = {
+ "banana",
+ "apple",
+ "orange",
+ NULL /* must be null terminated! */
+};
+
+static const Ecore_Getopt options = {
+ /* program name, usually a macro PACKAGE_NAME */
+ "ecore_getopt_example",
+ /* usage line */
+ "%prog [options]",
+ /* program version, usually a macro PACKAGE_VERSION */
+ "0.1",
+ /* copyright string */
+ "(C) 2013 Enlightenment Project",
+ /* license string */
+ "BSD 2-Clause",
+ /* long description, may be multiline and contain \n */
+ "Example of Ecore_Getopt usage.\n"
+ "\n"
+ "This usage may span over multiple lines of text, with automatic line "
+ "break based on $COLUMNS environment variable that is usually defined by "
+ "your shell.\n"
+ "You can have %%prog (expands to \"%prog\") or %%version (expands to \""
+ "%version\") in the description to get the program name "
+ "or version. Use double %% to get the percentage symbol.\n"
+ "OneCanHaveVeryLongWorksInDescriptionLinesSuchAsThisOneAndItWillBeBrokenWhenTheyGoPast${COLUMNS}Characters.\n"
+ "\tTab (\\t) is supported, like in the beginning of this line. They "
+ "will work as tabulation to columns multiple of 8 spaces, so you can do "
+ "tables such as:\n"
+ "1\tsomething\tsome description\n"
+ "23\totherthing\tsome description\n"
+ "456\tyetanother\tsome description\n"
+ "12345678\tthis is off\tthis is off\n",
+ /* we want strict parsing (any error aborts) */
+ EINA_TRUE,
+ /* an array of argument descriptions (must terminate with sentinel) */
+ {
+
+ /* block of options that store a single value in a variable of type */
+ ECORE_GETOPT_STORE_STR(0, "string", "Store a single string."),
+ ECORE_GETOPT_STORE_BOOL(0, "bool", "Store a single boolean."),
+ ECORE_GETOPT_STORE_SHORT(0, "short", "Store a single short."),
+ ECORE_GETOPT_STORE_INT(0, "int", "Store a single integer."),
+ ECORE_GETOPT_STORE_LONG(0, "long", "Store a single long integer."),
+ ECORE_GETOPT_STORE_USHORT(0, "unsigned-short",
+ "Store a single unsigned short integer."),
+ ECORE_GETOPT_STORE_UINT(0, "unsigned-int",
+ "Store a single unsigned integer."),
+ ECORE_GETOPT_STORE_ULONG(0, "unsigned-long",
+ "Store a single unsigned long integer."),
+ ECORE_GETOPT_STORE_DOUBLE(0, "double", "Store a single double."),
+
+ /* block of options that store a single value in a variable of type
+ * and use a default value if option IS SPECIFIED but no value is given
+ * using =VALUE.
+ * If option -o has default value of X, then the command lines produce:
+ * <empty>: nothing is set.
+ * -o: value is set to X.
+ * -o=Y: value is set to Y.
+ */
+ ECORE_GETOPT_STORE_DEF_STR(0, "default-string", "Store a single string.",
+ "default-string-value"),
+ ECORE_GETOPT_STORE_DEF_BOOL(0, "default-bool", "Store a single boolean.",
+ EINA_TRUE),
+ ECORE_GETOPT_STORE_DEF_SHORT(0, "default-short", "Store a single short.",
+ 123),
+ ECORE_GETOPT_STORE_DEF_INT(0, "default-int", "Store a single integer.",
+ 1234),
+ ECORE_GETOPT_STORE_DEF_LONG(0, "default-long",
+ "Store a single long integer.", 12345),
+ ECORE_GETOPT_STORE_DEF_USHORT(0, "default-unsigned-short",
+ "Store a single unsigned short integer.",
+ 123),
+ ECORE_GETOPT_STORE_DEF_UINT(0, "default-unsigned-int",
+ "Store a single unsigned integer.",
+ 1234),
+ ECORE_GETOPT_STORE_DEF_ULONG(0, "default-unsigned-long",
+ "Store a single unsigned long integer.",
+ 12345),
+ ECORE_GETOPT_STORE_DEF_DOUBLE(0, "default-double",
+ "Store a single double.",
+ 12.345),
+
+ /* you can specify the metavar so the --help will be more meaningful */
+ ECORE_GETOPT_STORE_METAVAR_STR(0, "output", "Specify output file.",
+ "FILENAME"),
+
+ /* Other than storing a given value (or default), it is common to
+ * have boolean options (ie: --debug, --daemon), those that set a
+ * constant value, counters (ie: --verbose) or option from a fixed
+ * set of choices.
+ */
+ ECORE_GETOPT_STORE_TRUE(0, "enable-x", "Enables X."),
+ ECORE_GETOPT_STORE_FALSE(0, "disable-y", "Disables Y."),
+ ECORE_GETOPT_STORE_CONST(0, "set-z", "Set z to constant XPTO.", "XPTO"),
+ ECORE_GETOPT_COUNT(0, "countme",
+ "Counts number of times this option is given."),
+ ECORE_GETOPT_CHOICE(0, "choose", "Choose from one of the options",
+ available_choices),
+
+ /* one can create a list of given values of a certain type */
+ ECORE_GETOPT_APPEND(0, "append-string", "Store multiple strings.",
+ ECORE_GETOPT_TYPE_STR),
+ ECORE_GETOPT_APPEND(0, "append-int", "Store multiple integers.",
+ ECORE_GETOPT_TYPE_INT),
+
+ /* break options will force everything that goes after it to be ignored
+ * by the option parser and they will go as arguments. This is the case
+ * for xterm's -e. Example:
+ * program --string=A: stores "A" into str_value.
+ * program --string=A --break: still stores "A" into str_value.
+ * program --break --string=A: str_value is untouched, --string=a
+ * is avaiable in argv[args], with
+ * args being the index returned by
+ * ecore_getopt_parse()
+ *
+ * Note that ecore_getopt will follow GNU and stop parsing arguments
+ * once -- is found, similar to "rm -- -fr /". In this case the
+ * return of ecore_getopt_parse() is to the index of "--" element in
+ * argv[].
+ */
+ ECORE_GETOPT_BREAK(0, "break"),
+
+ /* standard block to provide version, copyright, license and help */
+ ECORE_GETOPT_VERSION('V', "version"),
+ ECORE_GETOPT_COPYRIGHT('C', "copyright"),
+ ECORE_GETOPT_LICENSE('L', "license"),
+ ECORE_GETOPT_HELP('h', "help"),
+
+ /* the sentinel is required to notify end of descriptions */
+ ECORE_GETOPT_SENTINEL
+ }
+};
+
+int
+main(int argc, char **argv)
+{
+ char *str_value = NULL;
+ Eina_Bool bool_value = EINA_FALSE;
+ short short_value = 0;
+ int int_value = 0;
+ long long_value = 0;
+ unsigned short ushort_value = 0;
+ unsigned int uint_value = 0;
+ unsigned long ulong_value = 0;
+ double double_value = 0;
+ char *def_str_value = NULL;
+ Eina_Bool def_bool_value = EINA_FALSE;
+ short def_short_value = 0;
+ int def_int_value = 0;
+ long def_long_value = 0;
+ unsigned short def_ushort_value = 0;
+ unsigned int def_uint_value = 0;
+ unsigned long def_ulong_value = 0;
+ double def_double_value = 0;
+ char *output_value = NULL;
+ Eina_Bool use_x = EINA_FALSE; /* if stores true, then start with false */
+ Eina_Bool use_y = EINA_TRUE; /* if stores false, then start with true */
+ char *use_z = NULL; /* stores a pointer here */
+ int count = 0;
+ char *choice = NULL;
+ Eina_List *lst_strs = NULL;
+ Eina_List *lst_ints = NULL;
+ Eina_Bool break_given = EINA_FALSE;
+ Eina_Bool quit_option = EINA_FALSE;
+ Ecore_Getopt_Value values[] = {
+ /* block of options that store a single value in a variable of type */
+ ECORE_GETOPT_VALUE_STR(str_value),
+ ECORE_GETOPT_VALUE_BOOL(bool_value),
+ ECORE_GETOPT_VALUE_SHORT(short_value),
+ ECORE_GETOPT_VALUE_INT(int_value),
+ ECORE_GETOPT_VALUE_LONG(long_value),
+ ECORE_GETOPT_VALUE_USHORT(ushort_value),
+ ECORE_GETOPT_VALUE_UINT(uint_value),
+ ECORE_GETOPT_VALUE_ULONG(ulong_value),
+ ECORE_GETOPT_VALUE_DOUBLE(double_value),
+
+ /* you can use options with default value (if =VALUE is omitted) */
+ ECORE_GETOPT_VALUE_STR(def_str_value),
+ ECORE_GETOPT_VALUE_BOOL(def_bool_value),
+ ECORE_GETOPT_VALUE_SHORT(def_short_value),
+ ECORE_GETOPT_VALUE_INT(def_int_value),
+ ECORE_GETOPT_VALUE_LONG(def_long_value),
+ ECORE_GETOPT_VALUE_USHORT(def_ushort_value),
+ ECORE_GETOPT_VALUE_UINT(def_uint_value),
+ ECORE_GETOPT_VALUE_ULONG(def_ulong_value),
+ ECORE_GETOPT_VALUE_DOUBLE(def_double_value),
+
+ /* example of metavar usage */
+ ECORE_GETOPT_VALUE_STR(output_value),
+
+ /* example of store true, false, const */
+ ECORE_GETOPT_VALUE_BOOL(use_x),
+ ECORE_GETOPT_VALUE_BOOL(use_y),
+ ECORE_GETOPT_VALUE_STR(use_z),
+ ECORE_GETOPT_VALUE_INT(count),
+ ECORE_GETOPT_VALUE_STR(choice),
+
+ /* example of append multiple options */
+ ECORE_GETOPT_VALUE_LIST(lst_strs),
+ ECORE_GETOPT_VALUE_LIST(lst_ints),
+
+ /* example of break option */
+ ECORE_GETOPT_VALUE_BOOL(break_given),
+
+ /* standard block to provide version, copyright, license and help */
+ ECORE_GETOPT_VALUE_BOOL(quit_option), /* -V/--version quits */
+ ECORE_GETOPT_VALUE_BOOL(quit_option), /* -C/--copyright quits */
+ ECORE_GETOPT_VALUE_BOOL(quit_option), /* -L/--license quits */
+ ECORE_GETOPT_VALUE_BOOL(quit_option), /* -h/--help quits */
+
+ ECORE_GETOPT_VALUE_NONE /* sentinel */
+ };
+ int args, retval = EXIT_SUCCESS;
+
+ ecore_init();
+
+ /* during development is recommended to use the following to check
+ * for duplicated options.
+ */
+ assert(ecore_getopt_parser_has_duplicates(&options) == EINA_FALSE);
+
+ args = ecore_getopt_parse(&options, values, argc, argv);
+ if (args < 0)
+ {
+ fputs("ERROR: Could not parse command line options.\n", stderr);
+ retval = EXIT_FAILURE;
+ goto end;
+ }
+
+ /* options that set 'quit_option' to true requires us to exit. */
+ if (quit_option) goto end;
+
+ printf("given values:\n"
+ "string = %s\n"
+ "bool = %s\n"
+ "short = %hd\n"
+ "int = %d\n"
+ "long = %ld\n"
+ "unsigned-short = %hu\n"
+ "unsigned-int = %u\n"
+ "unsigned-long = %lu\n"
+ "double = %f\n"
+ "\n"
+ "default-string = %s\n"
+ "default-bool = %s\n"
+ "default-short = %hd\n"
+ "default-int = %d\n"
+ "default-long = %ld\n"
+ "default-unsigned-short = %hu\n"
+ "default-unsigned-int = %u\n"
+ "default-unsigned-long = %lu\n"
+ "default-double = %f\n"
+ "\n"
+ "output = %s\n"
+ "use-x = %s (disabled by default)\n"
+ "use-y = %s (enabled by default)\n"
+ "use-it = %s\n"
+ "counted = %d --countme\n"
+ "choice = %s\n"
+ "\n"
+ "--break = %s\n"
+ "\n",
+ str_value,
+ bool_value ? "true" : "false",
+ short_value,
+ int_value,
+ long_value,
+ ushort_value,
+ uint_value,
+ ulong_value,
+ double_value,
+ def_str_value,
+ def_bool_value ? "true" : "false",
+ def_short_value,
+ def_int_value,
+ def_long_value,
+ def_ushort_value,
+ def_uint_value,
+ def_ulong_value,
+ def_double_value,
+ output_value,
+ use_x ? "enabled" : "disabled",
+ use_y ? "enabled" : "disabled",
+ use_z,
+ count,
+ choice,
+ break_given ? "given" : "omitted");
+
+ if (!lst_strs)
+ puts("no --append-string=VALUE was given.");
+ else
+ {
+ char *str;
+ printf("%u strings given with --append-string=VALUE:\n",
+ eina_list_count(lst_strs));
+ EINA_LIST_FREE(lst_strs, str)
+ {
+ printf("\t%s\n", str);
+ free(str);
+ }
+ }
+
+ if (!lst_ints)
+ puts("no --append-int=VALUE was given.");
+ else
+ {
+ int *pi;
+ printf("%u integers given with --append-int=VALUE:\n",
+ eina_list_count(lst_ints));
+ EINA_LIST_FREE(lst_ints, pi)
+ {
+ printf("\t%d\n", *pi);
+ free(pi);
+ }
+ }
+
+ if (args == argc)
+ puts("no positional arguments were given.");
+ else
+ {
+ printf("%d positional arguments were given:\n", argc - args);
+ for (; args < argc; args++)
+ printf("\t%s\n", argv[args]);
+ }
+
+ end:
+ ecore_shutdown();
+ return retval;
+}