|
@@ -0,0 +1,118 @@
|
|
|
+#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 buflen; /* Minimal buffer size for string if needed */
|
|
|
+ bool is_ptr; /* Type is an allocated pointer */
|
|
|
+};
|
|
|
+
|
|
|
+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 sysvars_enum first;
|
|
|
+ size_t count;
|
|
|
+} sysvar_ns_t;
|
|
|
+
|
|
|
+extern_c const sysvar_ns_t sysvar_ns[sysvar_nscount];
|
|
|
+extern_c enum sysvars_enum sysvar_changed;
|
|
|
+
|
|
|
+/* 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_reset(void);
|
|
|
+extern_c size_t sysvar_find(size_t ns, const char *name);
|
|
|
+
|
|
|
+/* 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 */
|