Annotation of embedaddon/strongswan/src/libstrongswan/utils/enum.h, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2009-2019 Tobias Brunner
3: * Copyright (C) 2006-2008 Martin Willi
4: * HSR Hochschule fuer Technik Rapperswil
5: *
6: * This program is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2 of the License, or (at your
9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10: *
11: * This program is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14: * for more details.
15: */
16:
17: /**
18: * @defgroup enum enum
19: * @{ @ingroup utils
20: */
21:
22: #ifndef ENUM_H_
23: #define ENUM_H_
24:
25: #include <utils/printf_hook/printf_hook.h>
26:
27: typedef struct enum_name_t enum_name_t;
28:
29: /**
30: * Magic enum_name_t pointer indicating this is an enum name for flags
31: */
32: #define ENUM_FLAG_MAGIC ((enum_name_t*)~(uintptr_t)0)
33:
34: /**
35: * Struct to store names for enums.
36: *
37: * To print the string representation of enumeration values, the strings
38: * are stored in these structures. Every enum_name contains a range
39: * of strings, multiple ranges are linked together.
40: * Use the convenience macros to define these linked ranges.
41: *
42: * For a single range, use:
43: * @code
44: ENUM(name, first, last, string1, string2, ...)
45: @endcode
46: * For multiple linked ranges, use:
47: * @code
48: ENUM_BEGIN(name, first, last, string1, string2, ...)
49: ENUM_NEXT(name, first, last, last_from_previous, string3, ...)
50: ENUM_NEXT(name, first, last, last_from_previous, string4, ...)
51: ENUM_END(name, last_from_previous)
52: @endcode
53: * The ENUM and the ENUM_END define a enum_name_t pointer with the name supplied
54: * in "name".
55: *
56: * Resolving of enum names is done using a printf hook. A printf format
57: * character %N is replaced by the enum string. Printf needs two arguments to
58: * resolve a %N, the enum_name_t* (the defined name in ENUM_BEGIN) followed
59: * by the numerical enum value.
60: */
61: struct enum_name_t {
62: /** value of the first enum string, values are expected to be (u_)int, using
63: * int64_t here instead, however, avoids warnings for large unsigned ints */
64: int64_t first;
65: /** value of the last enum string */
66: int64_t last;
67: /** next enum_name_t in list, or ENUM_FLAG_MAGIC */
68: enum_name_t *next;
69: /** array of strings containing names from first to last */
70: char *names[];
71: };
72:
73: /**
74: * Begin a new enum_name list.
75: *
76: * @param name name of the enum_name list
77: * @param first enum value of the first enum string
78: * @param last enum value of the last enum string
79: * @param ... a list of strings
80: */
81: #define ENUM_BEGIN(name, first, last, ...) \
82: static enum_name_t name##last = {first, last + \
83: BUILD_ASSERT(((last)-(first)+1) == countof(((char*[]){__VA_ARGS__}))), \
84: NULL, { __VA_ARGS__ }}
85:
86: /**
87: * Continue a enum name list started with ENUM_BEGIN.
88: *
89: * @param name name of the enum_name list
90: * @param first enum value of the first enum string
91: * @param last enum value of the last enum string
92: * @param prev enum value of the "last" defined in ENUM_BEGIN/previous ENUM_NEXT
93: * @param ... a list of strings
94: */
95: #define ENUM_NEXT(name, first, last, prev, ...) \
96: static enum_name_t name##last = {first, last + \
97: BUILD_ASSERT(((last)-(first)+1) == countof(((char*[]){__VA_ARGS__}))), \
98: &name##prev, { __VA_ARGS__ }}
99:
100: /**
101: * Complete enum name list started with ENUM_BEGIN.
102: *
103: * @param name name of the enum_name list
104: * @param prev enum value of the "last" defined in ENUM_BEGIN/previous ENUM_NEXT
105: */
106: #define ENUM_END(name, prev) enum_name_t *name = &name##prev;
107:
108: /**
109: * Define a enum name with only one range.
110: *
111: * This is a convenience macro to use when a enum_name list contains only
112: * one range, and is equal as defining ENUM_BEGIN followed by ENUM_END.
113: *
114: * @param name name of the enum_name list
115: * @param first enum value of the first enum string
116: * @param last enum value of the last enum string
117: * @param ... a list of strings
118: */
119: #define ENUM(name, first, last, ...) \
120: ENUM_BEGIN(name, first, last, __VA_ARGS__); ENUM_END(name, last)
121:
122: /**
123: * Define a enum name with only one range for flags.
124: *
125: * Using an enum list for flags would be overkill. Hence we use a single
126: * range with all values in range. The next pointer is abused to mark
127: * that the enum name is for flags only. Use NULL if a particular flag
128: * is not meant to be printed.
129: *
130: * @param name name of the enum_name list
131: * @param first enum value of the first enum string
132: * @param last enum value of the last enum string
133: * @param ... a list of strings
134: */
135: #define ENUM_FLAGS(name, first, last, ...) \
136: static enum_name_t name##last = {first, last + \
137: BUILD_ASSERT((__builtin_ffs(last)-__builtin_ffs(first)+1) == \
138: countof(((char*[]){__VA_ARGS__}))), \
139: ENUM_FLAG_MAGIC, { __VA_ARGS__ }}; ENUM_END(name, last)
140:
141: /**
142: * Convert a enum value to its string representation.
143: *
144: * @param e enum names for this enum value
145: * @param val enum value to get string for
146: * @return string for enum, NULL if not found
147: */
148: char *enum_to_name(enum_name_t *e, int val);
149:
150: /**
151: * Convert a enum string back to its enum value.
152: *
153: * @param e enum names for this enum value
154: * @param name name to get enum value for
155: * @param valp variable sized pointer receiving value
156: * @return TRUE if enum name found, FALSE otherwise
157: */
158: #define enum_from_name(e, name, valp) ({ \
159: int _val; \
160: int _found = enum_from_name_as_int(e, name, &_val); \
161: if (_found) \
162: { \
163: *(valp) = _val; \
164: } \
165: _found; })
166:
167: /**
168: * Convert a enum string back to its enum value, integer pointer variant.
169: *
170: * This variant takes integer pointer only, use enum_from_name() to pass
171: * enum type pointers for the result.
172: *
173: * @param e enum names for this enum value
174: * @param name name to get enum value for
175: * @param val integer pointer receiving value
176: * @return TRUE if enum name found, FALSE otherwise
177: */
178: bool enum_from_name_as_int(enum_name_t *e, const char *name, int *val);
179:
180: /**
181: * Convert a enum value containing flags to its string representation.
182: *
183: * @param e enum names for this enum value suitable for flags
184: * @param val enum value to get string for
185: * @param buf buffer to write flag string to
186: * @param len buffer size
187: * @return buf, NULL if buffer too small
188: */
189: char *enum_flags_to_string(enum_name_t *e, u_int val, char *buf, size_t len);
190:
191: /**
192: * printf hook function for enum_names_t.
193: *
194: * Arguments are:
195: * enum_names_t *names, int value
196: */
197: int enum_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
198: const void *const *args);
199:
200: #endif /** ENUM_H_ @}*/
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>