#pragma once #include "common/FFstrbuf.h" // For ffRegReadValue(s) // If length is 0, data will be allocated with malloc() and must be freed by the caller // Otherwise, data must point to a buffer of at least length bytes, and the actual length of the data will be written to length. typedef struct FFArgBuffer { void* data; uint32_t length; } FFArgBuffer; typedef enum FF_A_PACKED FFArgType { FF_ARG_TYPE_NULL = 0, FF_ARG_TYPE_UINT, FF_ARG_TYPE_UINT64, FF_ARG_TYPE_UINT16, FF_ARG_TYPE_UINT8, FF_ARG_TYPE_INT, FF_ARG_TYPE_STRING, FF_ARG_TYPE_STRBUF, FF_ARG_TYPE_FLOAT, FF_ARG_TYPE_DOUBLE, FF_ARG_TYPE_LIST, FF_ARG_TYPE_BOOL, FF_ARG_TYPE_BUFFER, } FFArgType; #define FF_ARG(variable, var_name) { _Generic((variable), \ uint32_t: FF_ARG_TYPE_UINT, \ uint64_t: FF_ARG_TYPE_UINT64, \ uint16_t: FF_ARG_TYPE_UINT16, \ uint8_t: FF_ARG_TYPE_UINT8, \ int32_t: FF_ARG_TYPE_INT, \ char*: FF_ARG_TYPE_STRING, \ const char*: FF_ARG_TYPE_STRING, \ FFstrbuf: FF_ARG_TYPE_STRBUF, \ float: FF_ARG_TYPE_FLOAT, \ double: FF_ARG_TYPE_DOUBLE, \ FFlist: FF_ARG_TYPE_LIST, \ bool: FF_ARG_TYPE_BOOL, \ FFArgBuffer: FF_ARG_TYPE_BUFFER), \ _Generic((variable), char*: (variable), const char*: (variable), default: &(variable)), \ (var_name) }