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
- #endif
- typedef 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 */
|