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>