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 value is not found

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 true, prefixes of map labels are matched.

str

Input string.

next

If not NULL, the rest of str is stored here.

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 (maxval - minval + 2) to be filled. The terminating TE_ENUM_MAP_END will be appended

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 true, the to field of the translation is used as a key, i.e. a reverse translation is performed.

unknown_val

Value to return if value is not found

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 true, the to_bits field of the conversion is used as a key, i.e. a reverse conversion is performed.

result

Resulting bitmask. May be NULL to check that there are no bits that can not be converted.

TE_EINVAL

bm_conv contains zero values or overlapped bits.

TE_ERANGE

Conversion was done, but some bits of bm can not be converted using conv_map.

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 (maxval - minval + 2) to be filled. The terminating TE_ENUM_TRN_END will be appended

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