svn update: 48958 (latest:48959)
[framework/uifw/ecore.git] / src / lib / ecore / Ecore_Getopt.h
1 #ifndef _ECORE_GETOPT_H
2 #define _ECORE_GETOPT_H
3
4 #include <stdio.h>
5 #include <Eina.h>
6
7 #ifdef EAPI
8 # undef EAPI
9 #endif
10
11 #ifdef _WIN32
12 # ifdef EFL_ECORE_BUILD
13 #  ifdef DLL_EXPORT
14 #   define EAPI __declspec(dllexport)
15 #  else
16 #   define EAPI
17 #  endif /* ! DLL_EXPORT */
18 # else
19 #  define EAPI __declspec(dllimport)
20 # endif /* ! EFL_ECORE_BUILD */
21 #else
22 # ifdef __GNUC__
23 #  if __GNUC__ >= 4
24 #   define EAPI __attribute__ ((visibility("default")))
25 #  else
26 #   define EAPI
27 #  endif
28 # else
29 #  define EAPI
30 # endif
31 #endif /* ! _WIN32 */
32
33 /**
34  * @file Ecore_Getopt.h
35  * @brief Contains powerful getopt replacement.
36  *
37  * This replacement handles both short (-X) or long options (--ABC)
38  * options, with various actions supported, like storing one value and
39  * already converting to required type, counting number of
40  * occurrences, setting true or false values, show help, license,
41  * copyright and even support user-defined callbacks.
42  *
43  * It is provided a set of C Pre Processor macros so definition is
44  * straightforward.
45  *
46  * Values will be stored elsewhere indicated by an array of pointers
47  * to values, it is given in separate to parser description so you can
48  * use multiple values with the same parser.
49  */
50
51
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55
56   typedef enum {
57     ECORE_GETOPT_ACTION_STORE,
58     ECORE_GETOPT_ACTION_STORE_CONST,
59     ECORE_GETOPT_ACTION_STORE_TRUE,
60     ECORE_GETOPT_ACTION_STORE_FALSE,
61     ECORE_GETOPT_ACTION_CHOICE,
62     ECORE_GETOPT_ACTION_APPEND,
63     ECORE_GETOPT_ACTION_COUNT,
64     ECORE_GETOPT_ACTION_CALLBACK,
65     ECORE_GETOPT_ACTION_HELP,
66     ECORE_GETOPT_ACTION_VERSION,
67     ECORE_GETOPT_ACTION_COPYRIGHT,
68     ECORE_GETOPT_ACTION_LICENSE
69   } Ecore_Getopt_Action;
70
71   typedef enum {
72     ECORE_GETOPT_TYPE_STR,
73     ECORE_GETOPT_TYPE_BOOL,
74     ECORE_GETOPT_TYPE_SHORT,
75     ECORE_GETOPT_TYPE_INT,
76     ECORE_GETOPT_TYPE_LONG,
77     ECORE_GETOPT_TYPE_USHORT,
78     ECORE_GETOPT_TYPE_UINT,
79     ECORE_GETOPT_TYPE_ULONG,
80     ECORE_GETOPT_TYPE_DOUBLE
81   } Ecore_Getopt_Type;
82
83   typedef enum {
84     ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO = 0,
85     ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES = 1,
86     ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL = 3
87   } Ecore_Getopt_Desc_Arg_Requirement;
88
89   typedef union _Ecore_Getopt_Value             Ecore_Getopt_Value;
90
91   typedef struct _Ecore_Getopt_Desc_Store       Ecore_Getopt_Desc_Store;
92   typedef struct _Ecore_Getopt_Desc_Callback    Ecore_Getopt_Desc_Callback;
93   typedef struct _Ecore_Getopt_Desc             Ecore_Getopt_Desc;
94   typedef struct _Ecore_Getopt                  Ecore_Getopt;
95
96   union _Ecore_Getopt_Value
97   {
98      char **strp;
99      unsigned char *boolp;
100      short *shortp;
101      int *intp;
102      long *longp;
103      unsigned short *ushortp;
104      unsigned int *uintp;
105      unsigned long *ulongp;
106      double *doublep;
107      Eina_List **listp;
108      void **ptrp;
109   };
110
111   struct _Ecore_Getopt_Desc_Store
112   {
113      Ecore_Getopt_Type type;           /**< type of data being handled */
114      Ecore_Getopt_Desc_Arg_Requirement arg_req;
115      union
116      {
117         const char *strv;
118         unsigned char boolv;
119         short shortv;
120         int intv;
121         long longv;
122         unsigned short ushortv;
123         unsigned int uintv;
124         unsigned long ulongv;
125         double doublev;
126      } def;
127   };
128
129   struct _Ecore_Getopt_Desc_Callback
130   {
131      unsigned char (*func)(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, const char *str, void *data, Ecore_Getopt_Value *storage);
132      const void *data;
133      Ecore_Getopt_Desc_Arg_Requirement arg_req;
134      const char *def;
135   };
136
137   struct _Ecore_Getopt_Desc
138   {
139      char shortname;       /**< used with a single dash */
140      const char *longname; /**< used with double dashes */
141      const char *help;     /**< used by --help/ecore_getopt_help() */
142      const char *metavar;  /**< used by ecore_getopt_help() with nargs > 0 */
143
144      Ecore_Getopt_Action action; /**< define how to handle it */
145      union
146      {
147         const Ecore_Getopt_Desc_Store store;
148         const void *store_const;
149         const char *const *choices; /* NULL terminated. */
150         const Ecore_Getopt_Type append_type;
151         const Ecore_Getopt_Desc_Callback callback;
152         const void *dummy;
153      } action_param;
154   };
155
156   struct _Ecore_Getopt
157   {
158      const char *prog; /**< to be used when ecore_app_args_get() fails */
159      const char *usage; /**< usage example, %prog is replaced */
160      const char *version; /**< if exists, --version will work */
161      const char *copyright; /**< if exists, --copyright will work */
162      const char *license; /**< if exists, --license will work */
163      const char *description; /**< long description, possible multiline */
164      unsigned char strict : 1; /**< fail on errors */
165      const Ecore_Getopt_Desc descs[]; /* NULL terminated. */
166   };
167
168 #define ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type, arg_requirement, default_value) \
169   {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_STORE,       \
170        {.store = {type, arg_requirement, default_value}}}
171
172 #define ECORE_GETOPT_STORE(shortname, longname, help, type)             \
173   ECORE_GETOPT_STORE_FULL(shortname, longname, help, NULL, type,        \
174                           ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, {})
175
176 #define ECORE_GETOPT_STORE_STR(shortname, longname, help)               \
177   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_STR)
178 #define ECORE_GETOPT_STORE_BOOL(shortname, longname, help)              \
179   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_BOOL)
180 #define ECORE_GETOPT_STORE_SHORT(shortname, longname, help)             \
181   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_SHORT)
182 #define ECORE_GETOPT_STORE_INT(shortname, longname, help)               \
183   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_INT)
184 #define ECORE_GETOPT_STORE_LONG(shortname, longname, help)              \
185   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_LONG)
186 #define ECORE_GETOPT_STORE_USHORT(shortname, longname, help)            \
187   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_USHORT)
188 #define ECORE_GETOPT_STORE_UINT(shortname, longname, help)              \
189   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_UINT)
190 #define ECORE_GETOPT_STORE_ULONG(shortname, longname, help)             \
191   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_ULONG)
192 #define ECORE_GETOPT_STORE_DOUBLE(shortname, longname, help)            \
193   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_DOUBLE)
194
195
196 #define ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, type) \
197   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type,     \
198                           ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, {})
199
200 #define ECORE_GETOPT_STORE_METAVAR_STR(shortname, longname, help, metavar) \
201   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_STR)
202 #define ECORE_GETOPT_STORE_METAVAR_BOOL(shortname, longname, help, metavar) \
203   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_BOOL)
204 #define ECORE_GETOPT_STORE_METAVAR_SHORT(shortname, longname, help, metavar) \
205   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_SHORT)
206 #define ECORE_GETOPT_STORE_METAVAR_INT(shortname, longname, help, metavar) \
207   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_INT)
208 #define ECORE_GETOPT_STORE_METAVAR_LONG(shortname, longname, help, metavar) \
209   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_LONG)
210 #define ECORE_GETOPT_STORE_METAVAR_USHORT(shortname, longname, help, metavar) \
211   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_USHORT)
212 #define ECORE_GETOPT_STORE_METAVAR_UINT(shortname, longname, help, metavar) \
213   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_UINT)
214 #define ECORE_GETOPT_STORE_METAVAR_ULONG(shortname, longname, help, metavar) \
215   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_ULONG)
216 #define ECORE_GETOPT_STORE_METAVAR_DOUBLE(shortname, longname, help, metavar) \
217   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_DOUBLE)
218
219
220 #define ECORE_GETOPT_STORE_DEF(shortname, longname, help, type, default_value) \
221   ECORE_GETOPT_STORE_FULL(shortname, longname, help, NULL, type,        \
222                           ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL,   \
223                           default_value)
224
225 #define ECORE_GETOPT_STORE_DEF_STR(shortname, longname, help, default_value) \
226   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                     \
227                          ECORE_GETOPT_TYPE_STR,                         \
228                          {.strv = default_value})
229 #define ECORE_GETOPT_STORE_DEF_BOOL(shortname, longname, help, default_value) \
230   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                     \
231                          ECORE_GETOPT_TYPE_BOOL,                        \
232                          {.boolv = default_value})
233 #define ECORE_GETOPT_STORE_DEF_SHORT(shortname, longname, help, default_value) \
234   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                     \
235                          ECORE_GETOPT_TYPE_SHORT,                       \
236                          {.shortv = default_value})
237 #define ECORE_GETOPT_STORE_DEF_INT(shortname, longname, help, default_value) \
238   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                     \
239                          ECORE_GETOPT_TYPE_INT,                         \
240                          {.intv = default_value})
241 #define ECORE_GETOPT_STORE_DEF_LONG(shortname, longname, help, default_value) \
242   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                     \
243                          ECORE_GETOPT_TYPE_LONG,                        \
244                          {.longv = default_value})
245 #define ECORE_GETOPT_STORE_DEF_USHORT(shortname, longname, help, default_value) \
246   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                     \
247                          ECORE_GETOPT_TYPE_USHORT,                      \
248                          {.ushortv = default_value})
249 #define ECORE_GETOPT_STORE_DEF_UINT(shortname, longname, help, default_value) \
250   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                     \
251                          ECORE_GETOPT_TYPE_UINT,                        \
252                          {.uintv, default_value})
253 #define ECORE_GETOPT_STORE_DEF_ULONG(shortname, longname, help, default_value) \
254   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                     \
255                          ECORE_GETOPT_TYPE_ULONG,                       \
256                          {.ulongv = default_value})
257 #define ECORE_GETOPT_STORE_DEF_DOUBLE(shortname, longname, help, default_value) \
258   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                     \
259                          ECORE_GETOPT_TYPE_DOUBLE,                      \
260                          {.doublev = default_value})
261
262 #define ECORE_GETOPT_STORE_FULL_STR(shortname, longname, help, metavar, arg_requirement, default_value) \
263   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,           \
264                           ECORE_GETOPT_TYPE_STR,                        \
265                           arg_requirement,                              \
266                           {.strv = default_value})
267 #define ECORE_GETOPT_STORE_FULL_BOOL(shortname, longname, help, metavar, arg_requirement, default_value) \
268   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,           \
269                           ECORE_GETOPT_TYPE_BOOL,                       \
270                           arg_requirement,                              \
271                           {.boolv = default_value})
272 #define ECORE_GETOPT_STORE_FULL_SHORT(shortname, longname, help, metavar, arg_requirement, default_value) \
273   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,           \
274                           ECORE_GETOPT_TYPE_SHORT,                      \
275                           arg_requirement,                              \
276                           {.shortv = default_value})
277 #define ECORE_GETOPT_STORE_FULL_INT(shortname, longname, help, metavar, arg_requirement, default_value) \
278   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,           \
279                           ECORE_GETOPT_TYPE_INT,                        \
280                           arg_requirement,                              \
281                           {.intv = default_value})
282 #define ECORE_GETOPT_STORE_FULL_LONG(shortname, longname, help, metavar, arg_requirement, default_value) \
283   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,           \
284                           ECORE_GETOPT_TYPE_LONG,                       \
285                           arg_requirement,                              \
286                           {.longv = default_value})
287 #define ECORE_GETOPT_STORE_FULL_USHORT(shortname, longname, help, metavar, arg_requirement, default_value) \
288   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,           \
289                           ECORE_GETOPT_TYPE_USHORT,                     \
290                           arg_requirement,                              \
291                           {.ushortv = default_value})
292 #define ECORE_GETOPT_STORE_FULL_UINT(shortname, longname, help, metavar, arg_requirement, default_value) \
293   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,           \
294                           ECORE_GETOPT_TYPE_UINT,                       \
295                           arg_requirement,                              \
296                           {.uintv, default_value})
297 #define ECORE_GETOPT_STORE_FULL_ULONG(shortname, longname, help, metavar, arg_requirement, default_value) \
298   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,           \
299                           ECORE_GETOPT_TYPE_ULONG,                      \
300                           arg_requirement,                              \
301                           {.ulongv = default_value})
302 #define ECORE_GETOPT_STORE_FULL_DOUBLE(shortname, longname, help, metavar, arg_requirement, default_value) \
303   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,           \
304                           ECORE_GETOPT_TYPE_DOUBLE,                     \
305                           arg_requirement,                              \
306                           {.doublev = default_value})
307
308 #define ECORE_GETOPT_STORE_CONST(shortname, longname, help, value)      \
309   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_CONST,    \
310        {.store_const = value}}
311 #define ECORE_GETOPT_STORE_TRUE(shortname, longname, help)              \
312   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_TRUE,     \
313        {.dummy = NULL}}
314 #define ECORE_GETOPT_STORE_FALSE(shortname, longname, help)             \
315   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_FALSE,    \
316        {.dummy = NULL}}
317
318 #define ECORE_GETOPT_CHOICE(shortname, longname, help, choices_array)   \
319   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_CHOICE,         \
320        {.choices = choices_array}}
321 #define ECORE_GETOPT_CHOICE_METAVAR(shortname, longname, help, metavar, choices_array) \
322   {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_CHOICE,      \
323        {.choices = choices_array}}
324
325
326 #define ECORE_GETOPT_APPEND(shortname, longname, help, sub_type)        \
327   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_APPEND,         \
328        {.append_type = sub_type}}
329 #define ECORE_GETOPT_APPEND_METAVAR(shortname, longname, help, metavar, type) \
330   {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_APPEND,      \
331        {.append_type = type}}
332
333 #define ECORE_GETOPT_COUNT(shortname, longname, help)                   \
334   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_COUNT,          \
335        {.dummy = NULL}}
336
337 #define ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, metavar, callback_func, callback_data, argument_requirement, default_value) \
338   {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_CALLBACK,    \
339        {.callback = {callback_func, callback_data,                      \
340                      argument_requirement, default_value}}}
341 #define ECORE_GETOPT_CALLBACK_NOARGS(shortname, longname, help, callback_func, callback_data) \
342   ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, NULL,           \
343                              callback_func, callback_data,              \
344                              ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO,      \
345                              NULL)
346 #define ECORE_GETOPT_CALLBACK_ARGS(shortname, longname, help, metavar, callback_func, callback_data) \
347   ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, metavar,        \
348                              callback_func, callback_data,              \
349                              ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES,     \
350                              NULL)
351
352 #define ECORE_GETOPT_HELP(shortname, longname)                          \
353   {shortname, longname, "show this message.", NULL,                     \
354        ECORE_GETOPT_ACTION_HELP,                                        \
355        {.dummy = NULL}}
356
357 #define ECORE_GETOPT_VERSION(shortname, longname)                       \
358   {shortname, longname, "show program version.", NULL,                  \
359        ECORE_GETOPT_ACTION_VERSION,                                     \
360        {.dummy = NULL}}
361
362 #define ECORE_GETOPT_COPYRIGHT(shortname, longname)                     \
363   {shortname, longname, "show copyright.", NULL,                        \
364        ECORE_GETOPT_ACTION_COPYRIGHT,                                   \
365        {.dummy = NULL}}
366
367 #define ECORE_GETOPT_LICENSE(shortname, longname)                       \
368   {shortname, longname, "show license.", NULL,                          \
369        ECORE_GETOPT_ACTION_LICENSE,                                     \
370        {.dummy = NULL}}
371
372 #define ECORE_GETOPT_SENTINEL {0, NULL, NULL, NULL, 0, {.dummy = NULL}}
373
374 #define ECORE_GETOPT_VALUE_STR(val)      {.strp = &(val)}
375 #define ECORE_GETOPT_VALUE_BOOL(val)     {.boolp = &(val)}
376 #define ECORE_GETOPT_VALUE_SHORT(val)    {.shortp = &(val)}
377 #define ECORE_GETOPT_VALUE_INT(val)      {.intp = &(val)}
378 #define ECORE_GETOPT_VALUE_LONG(val)     {.longp = &(val)}
379 #define ECORE_GETOPT_VALUE_USHORT(val)   {.ushortp = &(val)}
380 #define ECORE_GETOPT_VALUE_UINT(val)     {.uintp = &(val)}
381 #define ECORE_GETOPT_VALUE_ULONG(val)    {.ulongp = &(val)}
382 #define ECORE_GETOPT_VALUE_DOUBLE(val)   {.doublep = &(val)}
383 #define ECORE_GETOPT_VALUE_PTR(val)      {.ptrp = &(val)}
384 #define ECORE_GETOPT_VALUE_PTR_CAST(val) {.ptrp = (void **)&(val)}
385 #define ECORE_GETOPT_VALUE_LIST(val)     {.listp = &(val)}
386 #define ECORE_GETOPT_VALUE_NONE          {.ptrp = NULL}
387
388   EAPI void ecore_getopt_help(FILE *fp, const Ecore_Getopt *info);
389
390   EAPI unsigned char ecore_getopt_parser_has_duplicates(const Ecore_Getopt *parser);
391   EAPI int ecore_getopt_parse(const Ecore_Getopt *parser, Ecore_Getopt_Value *values, int argc, char **argv);
392
393   EAPI Eina_List *ecore_getopt_list_free(Eina_List *list);
394
395   /* helper functions to be used with ECORE_GETOPT_CALLBACK_*() */
396   EAPI unsigned char ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, const char *str, void *data, Ecore_Getopt_Value *storage);
397   EAPI unsigned char ecore_getopt_callback_size_parse(const Ecore_Getopt *parser, const Ecore_Getopt_Desc *desc, const char *str, void *data, Ecore_Getopt_Value *storage);
398
399
400 #ifdef __cplusplus
401 }
402 #endif
403 #endif /* _ECORE_GETOPT_H */