Name/value mappings
Overview
Definition of the mapping functions. More…
// typedefs typedef struct te_enum_map te_enum_map; typedef struct te_enum_trn te_enum_trn; typedef struct te_enum_bitmask_conv te_enum_bitmask_conv; // structs struct te_enum_bitmask_conv; struct te_enum_map; struct te_enum_trn; // global functions int te_enum_map_from_str(const te_enum_map map[], const char* name, int unknown_val); const char* te_enum_map_from_any_value(const te_enum_map map[], int value, const char* unknown); static const char* te_enum_map_from_value(const te_enum_map map[], int value); int te_enum_parse_longest_match(const te_enum_map map[], int defval, bool exact_match, const char* str, char** next); void te_enum_map_fill_by_conversion(te_enum_map map[], int minval, int maxval, const char*(*)(int val) val2str); int te_enum_translate(const te_enum_trn trn[], int value, bool reverse, int unknown_val); te_errno te_enum_bitmask_convert(const te_enum_bitmask_conv bm_conv[], uint64_t bm, bool reverse, uint64_t* result); void te_enum_trn_fill_by_conversion(te_enum_trn trn[], int minval, int maxval, int(*)(int val) val2val); // macros #define TE_ENUM_BITMASK_CONV_END #define TE_ENUM_DISPATCH(table_, unknown_, name_, retval_, ...) #define TE_ENUM_MAP_ACTION(ftype_) #define TE_ENUM_MAP_END #define TE_ENUM_TRN_END
Detailed Documentation
Definition of the mapping functions.
Copyright (C) 2004-2022 OKTET Labs Ltd. All rights reserved.
Typedefs
typedef struct te_enum_map te_enum_map
A mapping between names and integral values.
An array of mappings should end with TE_ENUM_MAP_END
typedef struct te_enum_trn te_enum_trn
A translation between two sets of integral values
An array of translations should end with TE_ENUM_TRN_END
typedef struct te_enum_bitmask_conv te_enum_bitmask_conv
A mapping between two bitmasks corresponding to each other via named bits.
This structure permits the mapping of one or more bits from one side to one or more bits on the other side, with the constraint that the bits on each side do not overlap. This constraint results in the prohibition of mapping two or more set bits to the same corresponding bits on the other side.
An array of mappings should end with TE_ENUM_BITMASK_CONV_END and should not contain UINT64_MAX as a value of one of the fields.
Global Functions
int te_enum_map_from_str(const te_enum_map map[], const char* name, int unknown_val)
Convert a symbolic name into a value.
If there are several mappings with the same name, the first one is used.
Parameters:
map |
Mapping |
name |
Name |
unknown_val |
Value to return if the name is not found |
Returns:
the value corresponding to name or unknown_val
const char* te_enum_map_from_any_value(const te_enum_map map[], int value, const char* unknown)
Convert a value into a symbolic name.
If there are several mappings with the same value, the first one is used.
Parameters:
map |
Mapping |
value |
Value |
unknown |
Label to return if |
Returns:
A string matching the value or unknown
static const char* te_enum_map_from_value(const te_enum_map map[], int value)
Same as te_enum_map_from_any_value() but aborts the program if the value is not found.
This is to be used where a set of values is known to be closed, so any value not in that set results from the programmer’s error.
Parameters:
map |
Mapping |
value |
Value |
Returns:
A string matching the value
int te_enum_parse_longest_match(const te_enum_map map[], int defval, bool exact_match, const char* str, char** next)
Parse the longest label from map at the start of str.
If exact_match is true, str must start with one of the labels from map. If there are several candidate labels, the longest one is chosen.
If exact_match is false, str must have a non-empty common prefix with one of the labels from map. If there are several such labels, the one with the longest common prefix is chosen (i.e. in this case the length of the label does not matter as such).
If there are multiple matches of the same length, the first one is chosen.
If a match is found, a corresponding value from map is returned and if next is not NULL, it is set to point to the rest of str.
If no match is found, defval is returned and next would contain unchanged str.
For example:
static const te_enum_map map[] = { { "ERROR", LEVEL_ERROR }, { "WARNING", LEVEL_WARNING }, TE_ENUM_MAP_END }; ... val = te_enum_parse_longest_match(map, -1, false, "ERR message", &next); // val is LEVEL_ERROR, next is " message" // "ERR" and "ERROR" have a 3-character common prefix val = te_enum_parse_longest_match(map, -1, true, "ERR message", &next); // exact match is required, but "ERR message" does not start // with any of labels in map, val is -1, next is "ERR message" val = te_enum_parse_longest_match(map, -1, false, "WARN", &next); // val is LEVEL_WARNING, next is "" val = te_enum_parse_longest_match(map, -1, false, "INFO", &next); // even though match is not exact, there is no label in map // that would have a non-empty common prefix with "INFO", // so val is -1, next is "INFO"
This function may be used on non-zero terminated byte arrays, if it can be ensured there are always valid characters after the prefix:
char bytes[13] = "ERROR message"; // no terminating zero te_enum_parse_longest_match(map, -1, false, bytes, &next); // ok, we know there are valid characters after the label char bytes[3] = "ERR"; // no terminating zero te_enum_parse_longest_match(map, -1, false, bytes, &next); // not ok: the function will look past the last valid character
Parameters:
map |
Mapping. |
defval |
Default return value. |
exact_match |
If |
str |
Input string. |
next |
If not |
Returns:
A corresponding enum value from map or defval.
void te_enum_map_fill_by_conversion(te_enum_map map[], int minval, int maxval, const char*(*)(int val) val2str)
Fill in an enum mapping array based on the mapping function.
The purpose of the function is to bridge te_enum API and pre-existing value-to-string functions such as used in RPC libraries
Parameters:
map |
An array of sufficient size ( |
minval |
Minimal enum value |
maxval |
Maximum enum value |
val2str |
Conversion function |
int te_enum_translate(const te_enum_trn trn[], int value, bool reverse, int unknown_val)
Translate a value into a correpsonding value according to trn.
If there are several translations with the same value, the first one is used.
Parameters:
trn |
Translation table |
value |
Value |
reverse |
If |
unknown_val |
Value to return if |
Returns:
A value correspodning to the value or unknown_val
te_errno te_enum_bitmask_convert(const te_enum_bitmask_conv bm_conv[], uint64_t bm, bool reverse, uint64_t* result)
Convert a bm into a correpsonding bitmask according to bm_conv.
Parameters:
bm_conv |
Conversion table. |
bm |
Bitmask to convert. |
reverse |
If |
result |
Resulting bitmask. May be |
TE_EINVAL |
|
TE_ERANGE |
Conversion was done, but some bits of |
Returns:
Status code.
void te_enum_trn_fill_by_conversion(te_enum_trn trn[], int minval, int maxval, int(*)(int val) val2val)
Fill in an enum translation array based on the translation function.
The purpose of the function is to bridge te_enum API and pre-existing value-to-value conversion functions such as used in RPC libraries
Parameters:
trn |
An array of sufficient size ( |
minval |
Minimal source enum value |
maxval |
Maximum source enum value |
val2val |
Conversion function |
Macros
#define TE_ENUM_BITMASK_CONV_END
Terminating element of an enum bitmask conversion array.
#define TE_ENUM_DISPATCH(table_, unknown_, name_, retval_, ...)
Execute an action associated with a given name_.
The table_ should be an array of structures defined by TE_ENUM_MAP_ACTION terminated with TE_ENUM_MAP_END.
If name_ is not found in table_, unknown_ is called which may be a function, a pointer to function or a macro name.
Actions cannot be void functions.
typedef te_errno (*handler_fn)(int arg); static te_errno handler1(int arg) { ... } static te_errno handler2(int arg) { ... } ... static const TE_ENUM_ACTION(handler_fn) actions[] = { {.name= "handler1", .action = handler1}, {.name= "handler2", .action = handler2}, TE_ENUM_MAP_END }; te_errno rc; int arg; TE_ENUM_DISPATCH(actions, unknown_handler, rc, arg);
Parameters:
table_ |
a table of name-to-action mappings |
unknown_ |
a handler for unknown names |
retval_ |
lvalue to store the return value of an action |
… |
parameters passed to actions |
#define TE_ENUM_MAP_ACTION(ftype_)
Define a structure to map names to actions.
The structure will have two fields:
name
action
The structure is intended to be used with TE_ENUM_DISPATCH.
An array of such structures should be terminated with TE_ENUM_MAP_END.
Parameters:
ftype_ |
type of actions: a pointer to function type |
#define TE_ENUM_MAP_END
Terminating element of an enum mapping array
#define TE_ENUM_TRN_END
Terminating element of an enum translation array