coreboot-libre-fam15h-rdimm/3rdparty/ffs/clib/value.h

566 lines
17 KiB
C
Raw Permalink Normal View History

2024-03-04 11:14:53 +01:00
/* IBM_PROLOG_BEGIN_TAG */
/* This is an automatically generated prolog. */
/* */
/* $Source: clib/value.h $ */
/* */
/* OpenPOWER FFS Project */
/* */
/* Contributors Listed Below - COPYRIGHT 2014,2015 */
/* [+] International Business Machines Corp. */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
/* You may obtain a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */
/* implied. See the License for the specific language governing */
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
/*!
* @file value.h
* @brief Value Container
* @details Values are a kind of variant structure that can contain
* values of different types
* @author Shaun Wetzstein <shaun@us.ibm.com>
* @date 2010-2011
*/
#ifndef __VALUE_H__
#define __VALUE_H__
#include <stdint.h>
#include <stdbool.h>
#include "libclib.h"
/* ======================================================================= */
typedef enum value_type_enum value_type_t; //!< Alias for the @em value_type_enum enum
typedef struct value value_t; //!< Alias for the @em value class
/*!
* @brief Value types
* @details Supported value type
*/
enum value_type_enum {
VT_UNKNOWN = 0, //!< Uninitialized or unknown type
VT_I8, //!< 8-bit signed integer type
VT_I16, //!< 16-bit signed integer type
VT_I32, //!< 32-bit signed integer type
VT_I64, //!< 64-bit signed integer type
VT_U8, //!< 8-bit unsigned integer type
VT_U16, //!< 16-bit unsigned integer type
VT_U32, //!< 32-bit unsigned integer type
VT_U64, //!< 64-bit unsigned integer type
VT_REAL32, //!< 32-bit float type
VT_REAL64, //!< 64-bit float type
VT_STR, //!< Character string type
VT_STR_INLINE, //!< Character string inline type
VT_STR_OFF, //!< Character string offset type
VT_STR_CONST, //!< Constant character string type
VT_BLOB, //!< Blob type
VT_BLOB_INLINE, //!< Blob inline type
VT_BLOB_OFF, //!< Blob offset type
VT_BLOB_FILE, //!< Blob file type
} /*! @cond */ __packed /*! @endcond */ ;
/*! @cond */
#ifndef VALUE_PAD_DEFAULT
#define VALUE_PAD_DEFAULT 12
#endif
/*! @endcond */ ;
/*!
* @brief value container
*/
struct value {
uint32_t type:8, //!< Value type
size:24; //!< Value size (in bytes)
union {
int8_t i8; //!< 8-bit signed integer
int16_t i16; //!< 16-bit signed integer
int32_t i32; //!< 32-bit signed integer
int64_t i64; //!< 64-bit signed integer
uint8_t u8; //!< 8-bit unsigned integer
uint16_t u16; //!< 16-bit unsigned integer
uint32_t u32; //!< 32-bit unsigned integer
uint64_t u64; //!< 64-bit unsigned integer
float r32; //!< 32-bit float
double r64; //!< 64-bit float
void *ptr; //!< pointer
uint8_t data[VALUE_PAD_DEFAULT];
}; //!< Anonymous variant record
};
/* ==================================================================== */
/*! @cond */
#define value_type(...) STRCAT(value_type, NARGS(__VA_ARGS__))(__VA_ARGS__)
static inline value_type_t value_type1(const value_t * self)
{
return self ? self->type : VT_UNKNOWN;
}
static inline void value_type2(value_t * self, value_type_t type)
{
if (self != NULL)
self->type = type;
}
/*! @endcond */
/*! @cond */
#define value_size(...) STRCAT(value_size, NARGS(__VA_ARGS__))(__VA_ARGS__)
static inline uint32_t value_size1(const value_t * self)
{
return self ? self->size : 0;
}
static inline void value_size2(value_t * self, uint32_t size)
{
if (self != NULL)
self->size = size;
}
/*! @endcond */
/*!
* @brief Clear the contents of a @em value
* @memberof value
* @param self [in] value object @em self pointer
*/
static inline void value_clear(value_t * self)
{
if (self != NULL) {
if (self->type == VT_BLOB || self->type == VT_STR)
if (self->ptr != NULL)
free(self->ptr);
memset(self, 0, sizeof *self);
}
}
#define value_i8(...) STRCAT(value_i8_, NARGS(__VA_ARGS__))(__VA_ARGS__)
static inline int8_t value_i8_1(const value_t * v)
{
assert(value_type(v) == VT_I8);
return v->i8;
}
static inline value_t *value_i8_2(value_t * v, const int8_t i8)
{
value_clear(v), v->type = VT_I8, v->i8 = i8, v->size = sizeof(i8);
return v;
}
#define value_i16(...) STRCAT(value_i16_, NARGS(__VA_ARGS__))(__VA_ARGS__)
static inline int16_t value_i16_1(const value_t * v)
{
assert(value_type(v) == VT_I16);
return v->i16;
}
static inline value_t *value_i16_2(value_t * v, const int16_t i16)
{
value_clear(v), v->type = VT_I16, v->i16 = i16, v->size = sizeof(i16);
return v;
}
#define value_i32(...) STRCAT(value_i32_, NARGS(__VA_ARGS__))(__VA_ARGS__)
static inline int32_t value_i32_1(const value_t * v)
{
assert(value_type(v) == VT_I32);
return v->i32;
}
static inline value_t *value_i32_2(value_t * v, const int32_t i32)
{
value_clear(v), v->type = VT_I32, v->i32 = i32, v->size = sizeof(i32);
return v;
}
#define value_i64(...) STRCAT(value_i64_, NARGS(__VA_ARGS__))(__VA_ARGS__)
static inline int64_t value_i64_1(const value_t * v)
{
assert(value_type(v) == VT_I64);
return v->i64;
}
static inline value_t *value_i64_2(value_t * v, const int64_t i64)
{
value_clear(v), v->type = VT_I64, v->i64 = i64, v->size = sizeof(i64);
return v;
}
#define value_u8(...) STRCAT(value_u8_, NARGS(__VA_ARGS__))(__VA_ARGS__)
static inline uint8_t value_u8_1(const value_t * v)
{
assert(value_type(v) == VT_U8);
return v->u8;
}
static inline value_t *value_u8_2(value_t * v, const uint8_t u8)
{
value_clear(v), v->type = VT_U8, v->u8 = u8, v->size = sizeof(u8);
return v;
}
#define value_u16(...) STRCAT(value_u16_, NARGS(__VA_ARGS__))(__VA_ARGS__)
static inline uint16_t value_u16_1(const value_t * v)
{
assert(value_type(v) == VT_U16);
return v->u16;
}
static inline value_t *value_u16_2(value_t * v, const uint16_t u16)
{
value_clear(v), v->type = VT_U16, v->u16 = u16, v->size = sizeof(u16);
return v;
}
#define value_u32(...) STRCAT(value_u32_, NARGS(__VA_ARGS__))(__VA_ARGS__)
static inline uint32_t value_u32_1(const value_t * v)
{
assert(value_type(v) == VT_U32);
return v->u32;
}
static inline value_t *value_u32_2(value_t * v, const uint32_t u32)
{
value_clear(v), v->type = VT_U32, v->u32 = u32, v->size = sizeof(u32);
return v;
}
#define value_u64(...) STRCAT(value_u64_, NARGS(__VA_ARGS__))(__VA_ARGS__)
static inline uint64_t value_u64_1(const value_t * v)
{
assert(value_type(v) == VT_U64);
return v->u64;
}
static inline value_t *value_u64_2(value_t * v, const uint64_t u64)
{
value_clear(v), v->type = VT_U64, v->u64 = u64, v->size = sizeof(u64);
return v;
}
#define value_float(...) STRCAT(value_float_, NARGS(__VA_ARGS__))(__VA_ARGS__)
static inline float value_float1(const value_t * v)
{
assert(value_type(v) == VT_REAL32);
return v->r32;
}
static inline value_t *value_float2(value_t * v, const float r32)
{
value_clear(v), v->type = VT_REAL32, v->r32 = r32, v->size =
sizeof(r32);
return v;
}
#define value_double(...) STRCAT(value_double, NARGS(__VA_ARGS__))(__VA_ARGS__)
static inline double value_double1(const value_t * v)
{
assert(value_type(v) == VT_REAL64);
return v->r64;
}
static inline value_t *value_double2(value_t * v, const double r64)
{
value_clear(v), v->type = VT_REAL64, v->r64 = r64, v->size =
sizeof(r64);
return v;
}
#define value_blob(...) STRCAT(value_blob, NARGS(__VA_ARGS__))(__VA_ARGS__)
/*! @cond */
static inline void *value_blob1(const value_t * v)
{
if (value_type(v) == VT_BLOB)
return v->ptr;
else if (value_type(v) == VT_BLOB_INLINE)
return (void *)v->data;
else if (value_type(v) == VT_BLOB_OFF)
return NULL;
else if (value_type(v) == VT_BLOB_FILE) ;
else {
UNEXPECTED("invalid value_t blob type '%d'", value_type(v));
}
return NULL;
}
static inline value_t *value_blob4(value_t * self, const void *blob, size_t len,
size_t pad)
{
value_clear(self);
if (pad <= len) {
self->ptr = malloc(len + 1);
self->type = VT_BLOB;
memcpy(self->ptr, blob, len);
memset(self->ptr + len, 0, 1);
} else {
self->type = VT_BLOB_INLINE;
memcpy(self->data, blob, len);
self->data[len] = '\0';
}
self->size = len;
return self;
}
static inline value_t *value_blob3(value_t * self, const void *blob, size_t len)
{
return value_blob4(self, blob, len, VALUE_PAD_DEFAULT);
}
static inline value_t *value_blob2(value_t * self, const char *path)
{
value_t *rc = value_blob4(self, path, strlen(path), VALUE_PAD_DEFAULT);
if (rc != NULL)
value_type(rc, VT_BLOB_FILE);
return rc;
}
/*! @endcond */
#define value_string(...) STRCAT(value_string, NARGS(__VA_ARGS__))(__VA_ARGS__)
/*! @cond */
static inline char *value_string1(const value_t * v)
{
if (value_type(v) == VT_STR)
return (char *)v->ptr;
else if (value_type(v) == VT_STR_INLINE)
return (char *)v->data;
else if (value_type(v) == VT_STR_OFF) ;
else {
UNEXPECTED("invalid value string type '%d'", value_type(v));
}
return NULL;
}
static inline value_t *value_string4(value_t * self, const char *str,
size_t len, size_t pad)
{
value_blob(self, (const char *)str, len, pad);
if (self->type == VT_BLOB)
self->type = VT_STR;
else if (self->type == VT_BLOB_INLINE)
self->type = VT_STR_INLINE;
return self;
}
static inline value_t *value_string3(value_t * self, const char *str,
size_t len)
{
return value_string4(self, str, len, VALUE_PAD_DEFAULT);
}
static inline value_t *value_string2(value_t * self, const char *str)
{
return value_string4(self, str, strlen(str), VALUE_PAD_DEFAULT);
}
static inline value_t *value_set_string_const(value_t * self, const char *str,
size_t len)
{
value_clear(self);
self->type = VT_STR_CONST;
self->ptr = (void *)str;
self->size = len;
return self;
}
static inline value_t *value_set_string_offset(value_t * self, size_t off,
size_t len)
{
value_clear(self);
self->type = VT_STR_OFF;
self->u32 = off;
self->size = len;
return self;
}
/*! @endcond */
/*!
* @brief Pretty print the contents of a @em value to stdout
* @memberof value
* @param self [in] value object @em self pointer
* @param out [in] output stream
*/
extern void value_dump(const value_t * self, FILE * out)
/*! @cond */
__nonnull((1, 2)) /*! @endcond */ ;
/*! @cond */
#define __choose__ __builtin_choose_expr
#define __compat__ __builtin_types_compatible_p
#define __const__ __builtin_constant_p
/*! @endcond */
/*!
* @fn T value_get(const value * self, T)
* @brief Return a @em value as primitive type @em T
* @note @em T can be one fo the following types:
* - @em char, @em int8_t
* - @em short, @em int16_t
* - @em int, @em long @em int32_t
* - @em long @em long, @em int64_t
* - @em unsigned @em char, @em uint8_t
* - @em unsigned @em short, @em uint16_t
* - @em unsigned @em int, @em long @em uint32_t
* - @em unsigned @em long @em long, @em uint64_t
* - @em float, @em double
* - @em char @em *, @em unsigned @em char @em *
* @memberof value
* @param self [in] value object @em self pointer
* @param T [in] Type to cast
* @throws ASSERTION if T is not equal to the object's type
*/
#if DELETE
/*! @cond */
#define value_get(v, T) ({ \
__choose__(__compat__(T, char), \
value_get_int8((v)), \
__choose__(__compat__(T, int8_t), \
value_get_int8((v)), \
__choose__(__compat__(T, short), \
value_get_int16((v)), \
__choose__(__compat__(T, int16_t), \
value_get_int16((v)), \
__choose__(__compat__(T, int), \
value_get_int32((v)), \
__choose__(__compat__(T, long), \
value_get_int32((v)), \
__choose__(__compat__(T, int32_t), \
value_get_int32((v)), \
__choose__(__compat__(T, long long), \
value_get_int64((v)), \
__choose__(__compat__(T, int64_t), \
value_get_int64((v)), \
__choose__(__compat__(T, unsigned char), \
value_get_uint8((v)), \
__choose__(__compat__(T, uint8_t), \
value_get_uint8((v)), \
__choose__(__compat__(T, unsigned short), \
value_get_uint16((v)), \
__choose__(__compat__(T, uint16_t), \
value_get_uint16((v)), \
__choose__(__compat__(T, unsigned int), \
value_get_uint32((v)), \
__choose__(__compat__(T, unsigned long), \
value_get_uint32((v)), \
__choose__(__compat__(T, uint32_t), \
value_get_uint32((v)), \
__choose__(__compat__(T, unsigned long long), \
value_get_uint64((v)), \
__choose__(__compat__(T, uint64_t), \
value_get_uint64((v)), \
__choose__(__compat__(T, float), \
value_get_float((v)), \
__choose__(__compat__(T, double), \
value_get_double((v)), \
__choose__(__compat__(T, char *), \
value_get_string((v)), \
__choose__(__compat__(T, unsigned char *), \
value_get_string((v)), \
0xDEADBEEF)))))))))))))))))))))); \
})
/*! @endcond */
#endif
/*!
* @fn void value_set(const value * self, T v)
* @brief Assign a @em value to @em T v
* @memberof value
* @param self [in] value object @em self pointer
* @param v [in] value to assign
*/
#if 0
/*! @cond */
#define value_set(v, x) ({ \
__choose__(__compat__(typeof (x), char), \
value_set_int8((v),(int8_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), int8_t), \
value_set_int8((v),(int8_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), short), \
value_set_int16((v),(int16_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), int16_t), \
value_set_int16((v),(int16_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), int), \
value_set_int32((v),(int32_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), long), \
value_set_int32((v),(int32_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), int32_t), \
value_set_int32((v),(int32_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), long long), \
value_set_int64((v),(int64_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), int64_t), \
value_set_int64((v),(int64_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), unsigned char), \
value_set_uint8((v),(uint8_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), uint8_t), \
value_set_uint8((v),(uint8_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), unsigned short), \
value_set_uint16((v),(uint16_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), uint16_t), \
value_set_uint16((v),(uint16_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), unsigned int), \
value_set_uint32((v),(uint32_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), unsigned long), \
value_set_uint32((v),(uint32_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), uint32_t), \
value_set_uint32((v),(uint32_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), unsigned long long), \
value_set_uint64((v),(uint64_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), uint64_t), \
value_set_uint64((v),(uint64_t)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), float), \
value_set_float((v),(float)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), double), \
value_set_double((v),(double)(intptr_t)(x)), \
__choose__(__compat__(typeof (x), char *), \
__choose__(__const__((x)), \
value_set_string_const((v),(const char *)(intptr_t)(x), \
strlen((const char *)(intptr_t)(x))),\
value_set_string((v),(char *)(intptr_t)(x), \
strlen((const char *)(intptr_t)(x)))), \
__choose__(__compat__(typeof (x), unsigned char *), \
__choose__(__const__((x)), \
value_set_string_const((v),(const char *)(intptr_t)(x), \
strlen((const char *)(intptr_t)(x))),\
value_set_string((v),(const char *)(intptr_t)(x), \
strlen((const char *)(intptr_t)(x)))), \
((void)0))))))))))))))))))))))); \
})
/*! @endcond */
#endif
/* ==================================================================== */
#endif /* __VALUE_H__ */