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>