summaryrefslogtreecommitdiff
path: root/src/examples/ecore/ecore_getopt_example.c
blob: dc91f0c237e7df3cf3d2d2015489850d2ddbe515 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
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;
}