Annotation of embedaddon/strongswan/src/libstrongswan/utils/enum.h, revision 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>