From: Gustavo Sverzut Barbieri Date: Tue, 17 Dec 2013 20:08:27 +0000 (-0200) Subject: add great ecore_getopt example. X-Git-Tag: v1.9.0-alpha1~392 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1c1f9ea0e1a2c4014d5cb5ca0f749164dcd384e5;p=platform%2Fupstream%2Fefl.git 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!) --- diff --git a/src/examples/ecore/.gitignore b/src/examples/ecore/.gitignore index a04eae9..d77145e 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 129601e..9edeb1f 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 30a9521..f8ac82d 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 0000000..dc91f0c --- /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 +#include +#include + +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: + * : 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; +}