tizen 2.3.1 release
[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  * @internal
35  * @file Ecore_Getopt.h
36  * @brief Contains powerful getopt replacement.
37  *
38  * This replacement handles both short (-X) or long options (--ABC)
39  * options, with various actions supported, like storing one value and
40  * already converting to required type, counting number of
41  * occurrences, setting true or false values, showing help, license,
42  * copyright, and even supporting user-defined callbacks.
43  *
44  * It is provided a set of C Pre Processor macros. So definition is
45  * straightforward.
46  *
47  * Values are stored elsewhere indicated by an array of pointers
48  * to values. It is given separately to parser description. So you can
49  * use multiple values with the same parser.
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       Eina_Bool      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    Eina_Bool                         (*func)(const Ecore_Getopt *parser,
132                                              const Ecore_Getopt_Desc *desc,
133                                              const char *str,
134                                              void *data,
135                                              Ecore_Getopt_Value *storage);
136    const void                       *data;
137    Ecore_Getopt_Desc_Arg_Requirement arg_req;
138    const char                       *def;
139 };
140
141 struct _Ecore_Getopt_Desc
142 {
143    char                shortname; /**< Used with a single dash */
144    const char         *longname; /**< Used with double dashes */
145    const char         *help; /**< Used by -- help/ecore_getopt_help() */
146    const char         *metavar; /**< Used by ecore_getopt_help() with nargs > 0 */
147
148    Ecore_Getopt_Action action;   /**< Define how to handle it */
149    union
150    {
151       const Ecore_Getopt_Desc_Store    store;
152       const void                      *store_const;
153       const char *const               *choices; /* NULL terminated. */
154       const Ecore_Getopt_Type          append_type;
155       const Ecore_Getopt_Desc_Callback callback;
156       const void                      *dummy;
157    } action_param;
158 };
159
160 struct _Ecore_Getopt
161 {
162    const char             *prog; /**< To be used when ecore_app_args_get() fails */
163    const char             *usage; /**< Usage example, %prog is replaced */
164    const char             *version; /**< If exists, --version works */
165    const char             *copyright; /**< If exists, --copyright works */
166    const char             *license; /**< If exists, --license works */
167    const char             *description; /**< Long description, possible multiline */
168    Eina_Bool               strict : 1; /**< Fail on errors */
169    const Ecore_Getopt_Desc descs[];   /**< @c NULL terminated */
170 };
171
172 #define ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type, arg_requirement, default_value) \
173   {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_STORE,                                         \
174    {.store = {type, arg_requirement, default_value}}}
175
176 #define ECORE_GETOPT_STORE(shortname, longname, help, type)      \
177   ECORE_GETOPT_STORE_FULL(shortname, longname, help, NULL, type, \
178                           ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, {})
179
180 #define ECORE_GETOPT_STORE_STR(shortname, longname, help) \
181   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_STR)
182 #define ECORE_GETOPT_STORE_BOOL(shortname, longname, help) \
183   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_BOOL)
184 #define ECORE_GETOPT_STORE_SHORT(shortname, longname, help) \
185   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_SHORT)
186 #define ECORE_GETOPT_STORE_INT(shortname, longname, help) \
187   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_INT)
188 #define ECORE_GETOPT_STORE_LONG(shortname, longname, help) \
189   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_LONG)
190 #define ECORE_GETOPT_STORE_USHORT(shortname, longname, help) \
191   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_USHORT)
192 #define ECORE_GETOPT_STORE_UINT(shortname, longname, help) \
193   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_UINT)
194 #define ECORE_GETOPT_STORE_ULONG(shortname, longname, help) \
195   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_ULONG)
196 #define ECORE_GETOPT_STORE_DOUBLE(shortname, longname, help) \
197   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_DOUBLE)
198
199 #define ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, type) \
200   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type,          \
201                           ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, {})
202
203 #define ECORE_GETOPT_STORE_METAVAR_STR(shortname, longname, help, metavar) \
204   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_STR)
205 #define ECORE_GETOPT_STORE_METAVAR_BOOL(shortname, longname, help, metavar) \
206   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_BOOL)
207 #define ECORE_GETOPT_STORE_METAVAR_SHORT(shortname, longname, help, metavar) \
208   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_SHORT)
209 #define ECORE_GETOPT_STORE_METAVAR_INT(shortname, longname, help, metavar) \
210   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_INT)
211 #define ECORE_GETOPT_STORE_METAVAR_LONG(shortname, longname, help, metavar) \
212   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_LONG)
213 #define ECORE_GETOPT_STORE_METAVAR_USHORT(shortname, longname, help, metavar) \
214   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_USHORT)
215 #define ECORE_GETOPT_STORE_METAVAR_UINT(shortname, longname, help, metavar) \
216   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_UINT)
217 #define ECORE_GETOPT_STORE_METAVAR_ULONG(shortname, longname, help, metavar) \
218   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_ULONG)
219 #define ECORE_GETOPT_STORE_METAVAR_DOUBLE(shortname, longname, help, metavar) \
220   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_DOUBLE)
221
222 #define ECORE_GETOPT_STORE_DEF(shortname, longname, help, type, default_value) \
223   ECORE_GETOPT_STORE_FULL(shortname, longname, help, NULL, type,               \
224                           ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL,          \
225                           default_value)
226
227 #define ECORE_GETOPT_STORE_DEF_STR(shortname, longname, help, default_value) \
228   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                          \
229                          ECORE_GETOPT_TYPE_STR,                              \
230                          {.strv = default_value})
231 #define ECORE_GETOPT_STORE_DEF_BOOL(shortname, longname, help, default_value) \
232   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                           \
233                          ECORE_GETOPT_TYPE_BOOL,                              \
234                          {.boolv = default_value})
235 #define ECORE_GETOPT_STORE_DEF_SHORT(shortname, longname, help, default_value) \
236   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                            \
237                          ECORE_GETOPT_TYPE_SHORT,                              \
238                          {.shortv = default_value})
239 #define ECORE_GETOPT_STORE_DEF_INT(shortname, longname, help, default_value) \
240   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                          \
241                          ECORE_GETOPT_TYPE_INT,                              \
242                          {.intv = default_value})
243 #define ECORE_GETOPT_STORE_DEF_LONG(shortname, longname, help, default_value) \
244   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                           \
245                          ECORE_GETOPT_TYPE_LONG,                              \
246                          {.longv = default_value})
247 #define ECORE_GETOPT_STORE_DEF_USHORT(shortname, longname, help, default_value) \
248   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                             \
249                          ECORE_GETOPT_TYPE_USHORT,                              \
250                          {.ushortv = default_value})
251 #define ECORE_GETOPT_STORE_DEF_UINT(shortname, longname, help, default_value) \
252   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                           \
253                          ECORE_GETOPT_TYPE_UINT,                              \
254                          {.uintv = default_value})
255 #define ECORE_GETOPT_STORE_DEF_ULONG(shortname, longname, help, default_value) \
256   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                            \
257                          ECORE_GETOPT_TYPE_ULONG,                              \
258                          {.ulongv = default_value})
259 #define ECORE_GETOPT_STORE_DEF_DOUBLE(shortname, longname, help, default_value) \
260   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                             \
261                          ECORE_GETOPT_TYPE_DOUBLE,                              \
262                          {.doublev = default_value})
263
264 #define ECORE_GETOPT_STORE_FULL_STR(shortname, longname, help, metavar, arg_requirement, default_value) \
265   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                           \
266                           ECORE_GETOPT_TYPE_STR,                                                        \
267                           arg_requirement,                                                              \
268                           {.strv = default_value})
269 #define ECORE_GETOPT_STORE_FULL_BOOL(shortname, longname, help, metavar, arg_requirement, default_value) \
270   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                            \
271                           ECORE_GETOPT_TYPE_BOOL,                                                        \
272                           arg_requirement,                                                               \
273                           {.boolv = default_value})
274 #define ECORE_GETOPT_STORE_FULL_SHORT(shortname, longname, help, metavar, arg_requirement, default_value) \
275   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                             \
276                           ECORE_GETOPT_TYPE_SHORT,                                                        \
277                           arg_requirement,                                                                \
278                           {.shortv = default_value})
279 #define ECORE_GETOPT_STORE_FULL_INT(shortname, longname, help, metavar, arg_requirement, default_value) \
280   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                           \
281                           ECORE_GETOPT_TYPE_INT,                                                        \
282                           arg_requirement,                                                              \
283                           {.intv = default_value})
284 #define ECORE_GETOPT_STORE_FULL_LONG(shortname, longname, help, metavar, arg_requirement, default_value) \
285   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                            \
286                           ECORE_GETOPT_TYPE_LONG,                                                        \
287                           arg_requirement,                                                               \
288                           {.longv = default_value})
289 #define ECORE_GETOPT_STORE_FULL_USHORT(shortname, longname, help, metavar, arg_requirement, default_value) \
290   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                              \
291                           ECORE_GETOPT_TYPE_USHORT,                                                        \
292                           arg_requirement,                                                                 \
293                           {.ushortv = default_value})
294 #define ECORE_GETOPT_STORE_FULL_UINT(shortname, longname, help, metavar, arg_requirement, default_value) \
295   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                            \
296                           ECORE_GETOPT_TYPE_UINT,                                                        \
297                           arg_requirement,                                                               \
298                           {.uintv = default_value})
299 #define ECORE_GETOPT_STORE_FULL_ULONG(shortname, longname, help, metavar, arg_requirement, default_value) \
300   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                             \
301                           ECORE_GETOPT_TYPE_ULONG,                                                        \
302                           arg_requirement,                                                                \
303                           {.ulongv = default_value})
304 #define ECORE_GETOPT_STORE_FULL_DOUBLE(shortname, longname, help, metavar, arg_requirement, default_value) \
305   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                              \
306                           ECORE_GETOPT_TYPE_DOUBLE,                                                        \
307                           arg_requirement,                                                                 \
308                           {.doublev = default_value})
309
310 #define ECORE_GETOPT_STORE_CONST(shortname, longname, help, value)   \
311   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_CONST, \
312    {.store_const = value}}
313 #define ECORE_GETOPT_STORE_TRUE(shortname, longname, help)          \
314   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_TRUE, \
315    {.dummy = NULL}}
316 #define ECORE_GETOPT_STORE_FALSE(shortname, longname, help)          \
317   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_FALSE, \
318    {.dummy = NULL}}
319
320 #define ECORE_GETOPT_CHOICE(shortname, longname, help, choices_array) \
321   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_CHOICE,       \
322    {.choices = choices_array}}
323 #define ECORE_GETOPT_CHOICE_METAVAR(shortname, longname, help, metavar, choices_array) \
324   {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_CHOICE,                     \
325    {.choices = choices_array}}
326
327 #define ECORE_GETOPT_APPEND(shortname, longname, help, sub_type) \
328   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_APPEND,  \
329    {.append_type = sub_type}}
330 #define ECORE_GETOPT_APPEND_METAVAR(shortname, longname, help, metavar, type) \
331   {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_APPEND,            \
332    {.append_type = type}}
333
334 #define ECORE_GETOPT_COUNT(shortname, longname, help)          \
335   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_COUNT, \
336    {.dummy = NULL}}
337
338 #define ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, metavar, callback_func, callback_data, argument_requirement, default_value) \
339   {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_CALLBACK,                                                                      \
340    {.callback = {callback_func, callback_data,                                                                                            \
341                  argument_requirement, default_value}}}
342 #define ECORE_GETOPT_CALLBACK_NOARGS(shortname, longname, help, callback_func, callback_data) \
343   ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, NULL,                                 \
344                              callback_func, callback_data,                                    \
345                              ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO,                            \
346                              NULL)
347 #define ECORE_GETOPT_CALLBACK_ARGS(shortname, longname, help, metavar, callback_func, callback_data) \
348   ECORE_GETOPT_CALLBACK_FULL(shortname, longname, help, metavar,                                     \
349                              callback_func, callback_data,                                           \
350                              ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES,                                  \
351                              NULL)
352
353 #define ECORE_GETOPT_HELP(shortname, longname)      \
354   {shortname, longname, "show this message.", NULL, \
355    ECORE_GETOPT_ACTION_HELP,                        \
356    {.dummy = NULL}}
357
358 #define ECORE_GETOPT_VERSION(shortname, longname)      \
359   {shortname, longname, "show program version.", NULL, \
360    ECORE_GETOPT_ACTION_VERSION,                        \
361    {.dummy = NULL}}
362
363 #define ECORE_GETOPT_COPYRIGHT(shortname, longname) \
364   {shortname, longname, "show copyright.", NULL,    \
365    ECORE_GETOPT_ACTION_COPYRIGHT,                   \
366    {.dummy = NULL}}
367
368 #define ECORE_GETOPT_LICENSE(shortname, longname) \
369   {shortname, longname, "show license.", NULL,    \
370    ECORE_GETOPT_ACTION_LICENSE,                   \
371    {.dummy = NULL}}
372
373 #define ECORE_GETOPT_SENTINEL {0, NULL, NULL, NULL, 0, {.dummy = NULL}}
374
375 #define ECORE_GETOPT_VALUE_STR(val)      {.strp = &(val)}
376 #define ECORE_GETOPT_VALUE_BOOL(val)     {.boolp = &(val)}
377 #define ECORE_GETOPT_VALUE_SHORT(val)    {.shortp = &(val)}
378 #define ECORE_GETOPT_VALUE_INT(val)      {.intp = &(val)}
379 #define ECORE_GETOPT_VALUE_LONG(val)     {.longp = &(val)}
380 #define ECORE_GETOPT_VALUE_USHORT(val)   {.ushortp = &(val)}
381 #define ECORE_GETOPT_VALUE_UINT(val)     {.uintp = &(val)}
382 #define ECORE_GETOPT_VALUE_ULONG(val)    {.ulongp = &(val)}
383 #define ECORE_GETOPT_VALUE_DOUBLE(val)   {.doublep = &(val)}
384 #define ECORE_GETOPT_VALUE_PTR(val)      {.ptrp = &(val)}
385 #define ECORE_GETOPT_VALUE_PTR_CAST(val) {.ptrp = (void **)&(val)}
386 #define ECORE_GETOPT_VALUE_LIST(val)     {.listp = &(val)}
387 #define ECORE_GETOPT_VALUE_NONE {.ptrp = NULL}
388
389 EAPI void
390 ecore_getopt_help(FILE *fp,
391                   const Ecore_Getopt *info);
392
393 EAPI Eina_Bool
394  ecore_getopt_parser_has_duplicates(const Ecore_Getopt *parser);
395 EAPI int
396  ecore_getopt_parse(const Ecore_Getopt *parser,
397                    Ecore_Getopt_Value *values,
398                    int argc,
399                    char **argv);
400
401 EAPI Eina_List *ecore_getopt_list_free(Eina_List *list);
402
403 /* Helper functions to be used with ECORE_GETOPT_CALLBACK_*() */
404 EAPI Eina_Bool
405 ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser,
406                                      const Ecore_Getopt_Desc *desc,
407                                      const char *str,
408                                      void *data,
409                                      Ecore_Getopt_Value *storage);
410 EAPI Eina_Bool
411 ecore_getopt_callback_size_parse(const Ecore_Getopt *parser,
412                                  const Ecore_Getopt_Desc *desc,
413                                  const char *str,
414                                  void *data,
415                                  Ecore_Getopt_Value *storage);
416
417 #ifdef __cplusplus
418 }
419 #endif
420 #endif /* _ECORE_GETOPT_H */