| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 | #ifndef SYSVARS_H#define SYSVARS_H#include <stddef.h>#include <stdbool.h>#include <inttypes.h>#ifndef extern_c# ifdef __cplusplus#  define extern_c extern "C"# else#  define extern_c extern# endif#endiftypedef union sysvar_value {    bool v_bool;    long int v_int;    unsigned long int v_uint;    const char *v_str;    const char *v_tz;		/* Timezone */    uint32_t v_ip;		/* IPv4 address */    const uint8_t *v_mac;	/* MAC address */    void *v_ptr;} sysvar_t;struct sysvar_ops {    bool (*set)(sysvar_t *, sysvar_t);    /* bool (*unset)(sysvar_t *); - not used */    const char * (*tostr)(sysvar_t, char *);    bool (*fromstr)(sysvar_t *, const char *);    void (*update)(sysvar_t, bool); /* Called after set or fromstr; bool = isset */    size_t (*datasize)(sysvar_t);   /* If pointer, return size of data */    size_t buflen;		/* Minimal buffer size for string if needed */};typedef const struct sysvar_ops *sysvar_type_t;extern_c const struct sysvar_ops sysvar_bool_ops;extern_c const struct sysvar_ops sysvar_int_ops;extern_c const struct sysvar_ops sysvar_uint_ops;extern_c const struct sysvar_ops sysvar_str_ops;extern_c const struct sysvar_ops sysvar_tz_ops;extern_c const struct sysvar_ops sysvar_ip_ops;extern_c const struct sysvar_ops sysvar_mac_ops;#define SYSVAR_NULLTYPE NULL#define SYSVAR_TYPE(x) (&sysvar ## x ## _ops)#include "sysvars_gen.h"typedef struct sysvar_namespace {    const char *name;    enum sysvar_enum first;} sysvar_ns_t;extern_c const sysvar_ns_t sysvar_ns[(size_t)sysvar_nscount+1];extern_c enum sysvar_enum sysvar_changed;extern_c bool sysvar_print_updates;/* Buffer size needed to represent some data types */#define BOOL_BUFLEN 2#define INT_BUFLEN  (3*sizeof(unsigned int)+2)#define UINT_BUFLEN INT_BUFLEN#define IP_BUFLEN   (4*4)#define MAC_BUFLEN  (3*6)#define SYSVAR_BUFLEN	32	/* Conservative minimum */extern_c sysvar_t getvar(size_t var);extern_c bool setvar(size_t var, sysvar_t val);extern_c bool unsetvar(size_t var);extern_c const char *getvar_tostr(size_t var);extern_c const char *getvar_tostr_r(size_t var, char *buf);extern_c bool setvar_fromstr(size_t var, const char *str);extern_c void sysvar_init(void);extern_c void sysvar_reset(size_t ns);extern_c size_t sysvar_find(size_t ns, const char *name);extern_c size_t sysvar_marshall(enum sysvar_enum first, size_t count,				void *buf, size_t *buflen, uintptr_t extaddr);/* Type-specific definitions/getters/setters *//* Note that t contains a leading underscore to avoid bool/_Bool issues */#define const_assert(cond, str)					     \    do {							     \	extern void fail(void) __attribute__((error(str)));	     \	if (__builtin_constant_p(cond) && !(cond))		     \	    fail();						     \    } while (0)#define TRY_ASSERT_TYPE(var,t)						\    const_assert(sysvar_type(var) == SYSVAR_TYPE(t),			\	"invalid type for sysvar " #var)#define SYSVAR_MKTYPE(t,c_type)						\    static inline c_type getvar ## t (size_t var)			\    {									\	TRY_ASSERT_TYPE(var,t);						\	/* If var is constant and >= sysvar_count, TRY_ASSERT_TYPE() fails */ \	if (__builtin_constant_p(var < (size_t)sysvar_count))		\	    return sysvar_val[var].v ## t;				\	return getvar(var).v ## t ;					\    }									\    static inline bool setvar ## t (size_t var, c_type v)		\    {									\	sysvar_t vv;							\	TRY_ASSERT_TYPE(var,t);						\	vv.v ## t = v;							\	return setvar(var, vv);						\    }SYSVAR_MKTYPE(_bool, bool);SYSVAR_MKTYPE(_int, long int);SYSVAR_MKTYPE(_uint, unsigned long int);SYSVAR_MKTYPE(_str, const char *);SYSVAR_MKTYPE(_tz, const char *);SYSVAR_MKTYPE(_ip, uint32_t);SYSVAR_MKTYPE(_mac, const uint8_t *);#endif /* SYSVARS_H */
 |