Tizen 2.1 base
[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 #ifdef __cplusplus
52 extern "C" {
53 #endif
54
55 typedef enum {
56    ECORE_GETOPT_ACTION_STORE,
57    ECORE_GETOPT_ACTION_STORE_CONST,
58    ECORE_GETOPT_ACTION_STORE_TRUE,
59    ECORE_GETOPT_ACTION_STORE_FALSE,
60    ECORE_GETOPT_ACTION_CHOICE,
61    ECORE_GETOPT_ACTION_APPEND,
62    ECORE_GETOPT_ACTION_COUNT,
63    ECORE_GETOPT_ACTION_CALLBACK,
64    ECORE_GETOPT_ACTION_HELP,
65    ECORE_GETOPT_ACTION_VERSION,
66    ECORE_GETOPT_ACTION_COPYRIGHT,
67    ECORE_GETOPT_ACTION_LICENSE
68 } Ecore_Getopt_Action;
69
70 typedef enum {
71    ECORE_GETOPT_TYPE_STR,
72    ECORE_GETOPT_TYPE_BOOL,
73    ECORE_GETOPT_TYPE_SHORT,
74    ECORE_GETOPT_TYPE_INT,
75    ECORE_GETOPT_TYPE_LONG,
76    ECORE_GETOPT_TYPE_USHORT,
77    ECORE_GETOPT_TYPE_UINT,
78    ECORE_GETOPT_TYPE_ULONG,
79    ECORE_GETOPT_TYPE_DOUBLE
80 } Ecore_Getopt_Type;
81
82 typedef enum {
83    ECORE_GETOPT_DESC_ARG_REQUIREMENT_NO = 0,
84    ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES = 1,
85    ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL = 3
86 } Ecore_Getopt_Desc_Arg_Requirement;
87
88 typedef union _Ecore_Getopt_Value          Ecore_Getopt_Value;
89
90 typedef struct _Ecore_Getopt_Desc_Store    Ecore_Getopt_Desc_Store;
91 typedef struct _Ecore_Getopt_Desc_Callback Ecore_Getopt_Desc_Callback;
92 typedef struct _Ecore_Getopt_Desc          Ecore_Getopt_Desc;
93 typedef struct _Ecore_Getopt               Ecore_Getopt;
94
95 union _Ecore_Getopt_Value
96 {
97    char          **strp;
98    unsigned char  *boolp;
99    short          *shortp;
100    int            *intp;
101    long           *longp;
102    unsigned short *ushortp;
103    unsigned int   *uintp;
104    unsigned long  *ulongp;
105    double         *doublep;
106    Eina_List     **listp;
107    void          **ptrp;
108 };
109
110 struct _Ecore_Getopt_Desc_Store
111 {
112    Ecore_Getopt_Type                 type; /**< type of data being handled */
113    Ecore_Getopt_Desc_Arg_Requirement arg_req;
114    union
115    {
116       const char    *strv;
117       Eina_Bool      boolv;
118       short          shortv;
119       int            intv;
120       long           longv;
121       unsigned short ushortv;
122       unsigned int   uintv;
123       unsigned long  ulongv;
124       double         doublev;
125    } def;
126 };
127
128 struct _Ecore_Getopt_Desc_Callback
129 {
130    Eina_Bool                         (*func)(const Ecore_Getopt *parser,
131                                              const Ecore_Getopt_Desc *desc,
132                                              const char *str,
133                                              void *data,
134                                              Ecore_Getopt_Value *storage);
135    const void                       *data;
136    Ecore_Getopt_Desc_Arg_Requirement arg_req;
137    const char                       *def;
138 };
139
140 struct _Ecore_Getopt_Desc
141 {
142    char                shortname; /**< used with a single dash */
143    const char         *longname; /**< used with double dashes */
144    const char         *help; /**< used by --help/ecore_getopt_help() */
145    const char         *metavar; /**< used by ecore_getopt_help() with nargs > 0 */
146
147    Ecore_Getopt_Action action;   /**< define how to handle it */
148    union
149    {
150       const Ecore_Getopt_Desc_Store    store;
151       const void                      *store_const;
152       const char *const               *choices; /* NULL terminated. */
153       const Ecore_Getopt_Type          append_type;
154       const Ecore_Getopt_Desc_Callback callback;
155       const void                      *dummy;
156    } action_param;
157 };
158
159 struct _Ecore_Getopt
160 {
161    const char             *prog; /**< to be used when ecore_app_args_get() fails */
162    const char             *usage; /**< usage example, %prog is replaced */
163    const char             *version; /**< if exists, --version will work */
164    const char             *copyright; /**< if exists, --copyright will work */
165    const char             *license; /**< if exists, --license will work */
166    const char             *description; /**< long description, possible multiline */
167    Eina_Bool               strict : 1; /**< fail on errors */
168    const Ecore_Getopt_Desc descs[];   /* NULL terminated. */
169 };
170
171 #define ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type, arg_requirement, default_value) \
172   {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_STORE,                                         \
173    {.store = {type, arg_requirement, default_value}}}
174
175 #define ECORE_GETOPT_STORE(shortname, longname, help, type)      \
176   ECORE_GETOPT_STORE_FULL(shortname, longname, help, NULL, type, \
177                           ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, {})
178
179 #define ECORE_GETOPT_STORE_STR(shortname, longname, help) \
180   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_STR)
181 #define ECORE_GETOPT_STORE_BOOL(shortname, longname, help) \
182   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_BOOL)
183 #define ECORE_GETOPT_STORE_SHORT(shortname, longname, help) \
184   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_SHORT)
185 #define ECORE_GETOPT_STORE_INT(shortname, longname, help) \
186   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_INT)
187 #define ECORE_GETOPT_STORE_LONG(shortname, longname, help) \
188   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_LONG)
189 #define ECORE_GETOPT_STORE_USHORT(shortname, longname, help) \
190   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_USHORT)
191 #define ECORE_GETOPT_STORE_UINT(shortname, longname, help) \
192   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_UINT)
193 #define ECORE_GETOPT_STORE_ULONG(shortname, longname, help) \
194   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_ULONG)
195 #define ECORE_GETOPT_STORE_DOUBLE(shortname, longname, help) \
196   ECORE_GETOPT_STORE(shortname, longname, help, ECORE_GETOPT_TYPE_DOUBLE)
197
198 #define ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, type) \
199   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar, type,          \
200                           ECORE_GETOPT_DESC_ARG_REQUIREMENT_YES, {})
201
202 #define ECORE_GETOPT_STORE_METAVAR_STR(shortname, longname, help, metavar) \
203   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_STR)
204 #define ECORE_GETOPT_STORE_METAVAR_BOOL(shortname, longname, help, metavar) \
205   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_BOOL)
206 #define ECORE_GETOPT_STORE_METAVAR_SHORT(shortname, longname, help, metavar) \
207   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_SHORT)
208 #define ECORE_GETOPT_STORE_METAVAR_INT(shortname, longname, help, metavar) \
209   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_INT)
210 #define ECORE_GETOPT_STORE_METAVAR_LONG(shortname, longname, help, metavar) \
211   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_LONG)
212 #define ECORE_GETOPT_STORE_METAVAR_USHORT(shortname, longname, help, metavar) \
213   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_USHORT)
214 #define ECORE_GETOPT_STORE_METAVAR_UINT(shortname, longname, help, metavar) \
215   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_UINT)
216 #define ECORE_GETOPT_STORE_METAVAR_ULONG(shortname, longname, help, metavar) \
217   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_ULONG)
218 #define ECORE_GETOPT_STORE_METAVAR_DOUBLE(shortname, longname, help, metavar) \
219   ECORE_GETOPT_STORE_METAVAR(shortname, longname, help, metavar, ECORE_GETOPT_TYPE_DOUBLE)
220
221 #define ECORE_GETOPT_STORE_DEF(shortname, longname, help, type, default_value) \
222   ECORE_GETOPT_STORE_FULL(shortname, longname, help, NULL, type,               \
223                           ECORE_GETOPT_DESC_ARG_REQUIREMENT_OPTIONAL,          \
224                           default_value)
225
226 #define ECORE_GETOPT_STORE_DEF_STR(shortname, longname, help, default_value) \
227   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                          \
228                          ECORE_GETOPT_TYPE_STR,                              \
229                          {.strv = default_value})
230 #define ECORE_GETOPT_STORE_DEF_BOOL(shortname, longname, help, default_value) \
231   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                           \
232                          ECORE_GETOPT_TYPE_BOOL,                              \
233                          {.boolv = default_value})
234 #define ECORE_GETOPT_STORE_DEF_SHORT(shortname, longname, help, default_value) \
235   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                            \
236                          ECORE_GETOPT_TYPE_SHORT,                              \
237                          {.shortv = default_value})
238 #define ECORE_GETOPT_STORE_DEF_INT(shortname, longname, help, default_value) \
239   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                          \
240                          ECORE_GETOPT_TYPE_INT,                              \
241                          {.intv = default_value})
242 #define ECORE_GETOPT_STORE_DEF_LONG(shortname, longname, help, default_value) \
243   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                           \
244                          ECORE_GETOPT_TYPE_LONG,                              \
245                          {.longv = default_value})
246 #define ECORE_GETOPT_STORE_DEF_USHORT(shortname, longname, help, default_value) \
247   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                             \
248                          ECORE_GETOPT_TYPE_USHORT,                              \
249                          {.ushortv = default_value})
250 #define ECORE_GETOPT_STORE_DEF_UINT(shortname, longname, help, default_value) \
251   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                           \
252                          ECORE_GETOPT_TYPE_UINT,                              \
253                          {.uintv = default_value})
254 #define ECORE_GETOPT_STORE_DEF_ULONG(shortname, longname, help, default_value) \
255   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                            \
256                          ECORE_GETOPT_TYPE_ULONG,                              \
257                          {.ulongv = default_value})
258 #define ECORE_GETOPT_STORE_DEF_DOUBLE(shortname, longname, help, default_value) \
259   ECORE_GETOPT_STORE_DEF(shortname, longname, help,                             \
260                          ECORE_GETOPT_TYPE_DOUBLE,                              \
261                          {.doublev = default_value})
262
263 #define ECORE_GETOPT_STORE_FULL_STR(shortname, longname, help, metavar, arg_requirement, default_value) \
264   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                           \
265                           ECORE_GETOPT_TYPE_STR,                                                        \
266                           arg_requirement,                                                              \
267                           {.strv = default_value})
268 #define ECORE_GETOPT_STORE_FULL_BOOL(shortname, longname, help, metavar, arg_requirement, default_value) \
269   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                            \
270                           ECORE_GETOPT_TYPE_BOOL,                                                        \
271                           arg_requirement,                                                               \
272                           {.boolv = default_value})
273 #define ECORE_GETOPT_STORE_FULL_SHORT(shortname, longname, help, metavar, arg_requirement, default_value) \
274   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                             \
275                           ECORE_GETOPT_TYPE_SHORT,                                                        \
276                           arg_requirement,                                                                \
277                           {.shortv = default_value})
278 #define ECORE_GETOPT_STORE_FULL_INT(shortname, longname, help, metavar, arg_requirement, default_value) \
279   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                           \
280                           ECORE_GETOPT_TYPE_INT,                                                        \
281                           arg_requirement,                                                              \
282                           {.intv = default_value})
283 #define ECORE_GETOPT_STORE_FULL_LONG(shortname, longname, help, metavar, arg_requirement, default_value) \
284   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                            \
285                           ECORE_GETOPT_TYPE_LONG,                                                        \
286                           arg_requirement,                                                               \
287                           {.longv = default_value})
288 #define ECORE_GETOPT_STORE_FULL_USHORT(shortname, longname, help, metavar, arg_requirement, default_value) \
289   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                              \
290                           ECORE_GETOPT_TYPE_USHORT,                                                        \
291                           arg_requirement,                                                                 \
292                           {.ushortv = default_value})
293 #define ECORE_GETOPT_STORE_FULL_UINT(shortname, longname, help, metavar, arg_requirement, default_value) \
294   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                            \
295                           ECORE_GETOPT_TYPE_UINT,                                                        \
296                           arg_requirement,                                                               \
297                           {.uintv = default_value})
298 #define ECORE_GETOPT_STORE_FULL_ULONG(shortname, longname, help, metavar, arg_requirement, default_value) \
299   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                             \
300                           ECORE_GETOPT_TYPE_ULONG,                                                        \
301                           arg_requirement,                                                                \
302                           {.ulongv = default_value})
303 #define ECORE_GETOPT_STORE_FULL_DOUBLE(shortname, longname, help, metavar, arg_requirement, default_value) \
304   ECORE_GETOPT_STORE_FULL(shortname, longname, help, metavar,                                              \
305                           ECORE_GETOPT_TYPE_DOUBLE,                                                        \
306                           arg_requirement,                                                                 \
307                           {.doublev = default_value})
308
309 #define ECORE_GETOPT_STORE_CONST(shortname, longname, help, value)   \
310   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_CONST, \
311    {.store_const = value}}
312 #define ECORE_GETOPT_STORE_TRUE(shortname, longname, help)          \
313   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_TRUE, \
314    {.dummy = NULL}}
315 #define ECORE_GETOPT_STORE_FALSE(shortname, longname, help)          \
316   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_STORE_FALSE, \
317    {.dummy = NULL}}
318
319 #define ECORE_GETOPT_CHOICE(shortname, longname, help, choices_array) \
320   {shortname, longname, help, NULL, ECORE_GETOPT_ACTION_CHOICE,       \
321    {.choices = choices_array}}
322 #define ECORE_GETOPT_CHOICE_METAVAR(shortname, longname, help, metavar, choices_array) \
323   {shortname, longname, help, metavar, ECORE_GETOPT_ACTION_CHOICE,                     \
324    {.choices = choices_array}}
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
389 ecore_getopt_help(FILE *fp,
390                   const Ecore_Getopt *info);
391
392 EAPI Eina_Bool
393  ecore_getopt_parser_has_duplicates(const Ecore_Getopt *parser);
394 EAPI int
395  ecore_getopt_parse(const Ecore_Getopt *parser,
396                    Ecore_Getopt_Value *values,
397                    int argc,
398                    char **argv);
399
400 EAPI Eina_List *ecore_getopt_list_free(Eina_List *list);
401
402 /* helper functions to be used with ECORE_GETOPT_CALLBACK_*() */
403 EAPI Eina_Bool
404 ecore_getopt_callback_geometry_parse(const Ecore_Getopt *parser,
405                                      const Ecore_Getopt_Desc *desc,
406                                      const char *str,
407                                      void *data,
408                                      Ecore_Getopt_Value *storage);
409 EAPI Eina_Bool
410 ecore_getopt_callback_size_parse(const Ecore_Getopt *parser,
411                                  const Ecore_Getopt_Desc *desc,
412                                  const char *str,
413                                  void *data,
414                                  Ecore_Getopt_Value *storage);
415
416 #ifdef __cplusplus
417 }
418 #endif
419 #endif /* _ECORE_GETOPT_H */