Turn the parameter force of ia32_create_address_mode() into a bitflag.
[libfirm] / ir / libcore / lc_opts_enum.c
1 /**
2  * @file   lc_opts_enum.c
3  * @date   24.11.2005
4  * @author Sebastian Hack
5  *
6  * Copyright (C) 2005 Universitaet Karlsruhe
7  * Released under the GPL
8  *
9  * Enum callback and dump implementation.
10  */
11 #include "config.h"
12
13 #include <stdlib.h>
14 #include <stdarg.h>
15 #include <stdio.h>
16 #include <string.h>
17
18 #if defined(__FreeBSD__)
19 #include <stdlib.h>
20 #elif defined(_WIN32)
21 #include <malloc.h>
22 #else
23 #include <alloca.h>
24 #endif
25
26 #include "lc_opts_t.h"
27 #include "lc_opts_enum.h"
28
29 static const char *delim                        = " \t|,";
30
31 #define DECL_CB(N, op) \
32 int lc_opt_enum_ ## N ## _cb(LC_UNUSED(const char *name), LC_UNUSED(lc_opt_type_t type), void *data, size_t len, ...) \
33 { \
34         lc_opt_enum_ ## N ## _var_t *var                                                = data; \
35         const lc_opt_enum_ ## N ## _items_t *items      = var->items; \
36  \
37         va_list args; \
38         char *s, *tmp; \
39         size_t begin, end; \
40         const char *arg; \
41         int res = 0; \
42  \
43         va_start(args, len); \
44         arg = va_arg(args, const char *); \
45         va_end(args); \
46         \
47         end     = strlen(arg); \
48         tmp = s = malloc((end + 1) * sizeof(arg[0])); \
49         strcpy(s, arg); \
50         s[end]  = '\0'; \
51         \
52         end = 0; \
53         while(arg[end] != '\0') { \
54                 unsigned int i; \
55                 \
56                 begin  = end + strspn(arg + end, delim); \
57                 end    = begin + strcspn(arg + begin, delim); \
58                 s      = tmp + begin; \
59                 s[end - begin] = '\0'; \
60                 \
61                 for(i = 0; items[i].name != NULL; ++i) { \
62                         if(strcmp(s, items[i].name) == 0) { \
63                                 *var->value op items[i].value; \
64                                 res = 1; \
65                         } \
66                 } \
67         } \
68         free(tmp); \
69         return res; \
70 } \
71
72 DECL_CB(int, =)
73 DECL_CB(mask, |=)
74 DECL_CB(ptr, =)
75 DECL_CB(const_ptr, =)
76 DECL_CB(func_ptr, =)
77
78 #define DECL_DUMP(T, N, cond) \
79 int lc_opt_enum_ ## N ## _dump(char *buf, size_t n, LC_UNUSED(const char *name), LC_UNUSED(lc_opt_type_t type), void *data, LC_UNUSED(size_t len)) \
80 { \
81         lc_opt_enum_ ## N ## _var_t *var                                                = data; \
82         const lc_opt_enum_ ## N ## _items_t *items      = var->items; \
83         const char *prefix                                                              = "";                    \
84         TYPE(value) = *var->value; \
85         int i; \
86  \
87         for(i = 0; items[i].name != NULL; ++i) { \
88                 TYPE(item_value) = items[i].value; \
89                 if(cond) { \
90                         strncat(buf, prefix, n); \
91                         strncat(buf, items[i].name, n); \
92                         prefix = ", "; \
93                 } \
94         } \
95  \
96         return strlen(buf); \
97 } \
98
99
100 #define DECL_DUMP_VALS(T, N) \
101 int lc_opt_enum_ ## N ## _dump_vals(char *buf, size_t n, LC_UNUSED(const char *name), LC_UNUSED(lc_opt_type_t type), void *data, LC_UNUSED(size_t len)) \
102 { \
103         lc_opt_enum_ ## N ## _var_t *var                                                = data; \
104         const lc_opt_enum_ ## N ## _items_t *items      = var->items; \
105         const char *prefix                                                              = "";                    \
106         int i; \
107  \
108         for(i = 0; items[i].name != NULL; ++i) { \
109                 strncat(buf, prefix, n); \
110                 strncat(buf, items[i].name, n); \
111                 prefix = ", "; \
112         } \
113  \
114         return strlen(buf); \
115 } \
116
117
118
119 #define TYPE(x) int x
120 DECL_DUMP(int, int, item_value == value)
121 DECL_DUMP_VALS(int, int)
122 #undef TYPE
123
124 #define TYPE(x) unsigned x
125 DECL_DUMP(unsigned, mask, (item_value & value) == item_value)
126 DECL_DUMP_VALS(unsigned, mask)
127 #undef TYPE
128
129 #define TYPE(x) void *x
130 DECL_DUMP(void *, ptr, item_value == value)
131 DECL_DUMP_VALS(void *, ptr)
132 #undef TYPE
133
134 #define TYPE(x) const void *x
135 DECL_DUMP(const void *, const_ptr, item_value == value)
136 DECL_DUMP_VALS(const void *, const_ptr)
137 #undef TYPE
138
139 #define TYPE(x) int (*x)(void)
140 DECL_DUMP(int (*)(void), func_ptr, item_value == value)
141 DECL_DUMP_VALS(int (*)(void), func_ptr)
142 #undef TYPE