Browse Source

sysvars: call ->update after string update (fixes TZ)

The whole point of the ->update method is to call it no matter what
the cause of the change. Thus, need to call it after setvar_fromstr()
as well.

Remove obsolete sysvars.[ch] in the project root.
H. Peter Anvin 1 year ago
parent
commit
9cd6517ac9

+ 6 - 3
common/sysvars.c

@@ -362,13 +362,16 @@ bool setvar_fromstr(size_t var, const char *str)
     if (!type->fromstr(to, str))
 	return false;
 
-    if (var < (size_t)sysvar_changed)
-	sysvar_changed = (enum sysvar_enum)var;
-
     if (free_ptr)
 	free(free_ptr);
 
+    if (var < (size_t)sysvar_changed)
+	sysvar_changed = (enum sysvar_enum)var;
+
     sysvar_isset[var] = true;
+    if (type->update)
+	type->update(*to, true);
+
     return true;
 }
 

+ 2 - 0
esp32/max80/httpd.c

@@ -536,6 +536,8 @@ static void httpd_get_status_extra(FILE *f, httpd_req_t *req)
     }
     fprintf(f, "http.status.refresh=%lu\n", statref);
 
+    fprintf(f, "TZ=%s\n", notempty(getenv("TZ")));
+
     gettimeofday(&tv,NULL);
     const struct tm *tm = localtime(&tv.tv_sec);
     len = strftime(timebuf, sizeof timebuf, "localtime=%Y-%m-%d %H:%M:%S.", tm);

+ 6 - 3
esp32/max80/src/common/sysvars.c

@@ -362,13 +362,16 @@ bool setvar_fromstr(size_t var, const char *str)
     if (!type->fromstr(to, str))
 	return false;
 
-    if (var < (size_t)sysvar_changed)
-	sysvar_changed = (enum sysvar_enum)var;
-
     if (free_ptr)
 	free(free_ptr);
 
+    if (var < (size_t)sysvar_changed)
+	sysvar_changed = (enum sysvar_enum)var;
+
     sysvar_isset[var] = true;
+    if (type->update)
+	type->update(*to, true);
+
     return true;
 }
 

BIN
esp32/output/max80.ino.bin


+ 3 - 3
fpga/max80.qpf

@@ -19,15 +19,15 @@
 #
 # Quartus Prime
 # Version 22.1std.2 Build 922 07/20/2023 SC Lite Edition
-# Date created = 15:41:59  October 01, 2023
+# Date created = 16:13:11  October 01, 2023
 #
 # -------------------------------------------------------------------------- #
 
 QUARTUS_VERSION = "22.1"
-DATE = "15:41:59  October 01, 2023"
+DATE = "16:13:11  October 01, 2023"
 
 # Revisions
 
-PROJECT_REVISION = "v2"
 PROJECT_REVISION = "v1"
+PROJECT_REVISION = "v2"
 PROJECT_REVISION = "bypass"

BIN
fpga/output/max80.fw


BIN
fpga/output/v1.fw


BIN
fpga/output/v1.jic


BIN
fpga/output/v1.sof


BIN
fpga/output/v2.fw


BIN
fpga/output/v2.jic


BIN
fpga/output/v2.sof


+ 0 - 419
sysvars.c

@@ -1,419 +0,0 @@
-#include "common.h"
-#include "sysvars.h"
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <time.h>
-
-#define DEBUG 1
-
-#ifndef DEBUG
-# define DEBUG 0
-#endif
-
-static const char *sysvar_bool_tostr(sysvar_t from, char *buf)
-{
-    buf[0] = '0' + from.v_bool;
-    buf[1] = '\0';
-    return buf;
-}
-
-static bool sysvar_bool_fromstr(sysvar_t *to, const char *from)
-{
-    char c = from[0] | 0x20;
-    switch (c) {
-    case '1':
-    case 't':
-    case 'y':
-    case 'j':
-    case 's':
-	to->v_bool = true;
-	return true;
-    case ' ':			/* Blank or null */
-    case '0':
-    case 'f':
-    case 'n':
-	to->v_bool = false;
-	return true;
-    default:
-	return false;
-    }
-}
-
-const struct sysvar_ops sysvar_bool_ops = {
-    .tostr = sysvar_bool_tostr,
-    .fromstr = sysvar_bool_fromstr,
-    .buflen = BOOL_BUFLEN
-};
-
-static const char *sysvar_int_tostr(sysvar_t from, char *buf)
-{
-    snprintf(buf, INT_BUFLEN, "%ld", from.v_int);
-    return buf;
-}
-
-static bool sysvar_int_fromstr(sysvar_t *to, const char *from)
-{
-    char *ep;
-    long v = strtol(from, &ep, 0);
-    if (ep == from || *ep)
-	return false;
-    to->v_int = v;
-    return true;
-}
-
-const struct sysvar_ops sysvar_int_ops = {
-    .tostr = sysvar_int_tostr,
-    .fromstr = sysvar_int_fromstr,
-    .buflen = INT_BUFLEN
-};
-
-static const char *sysvar_uint_tostr(sysvar_t from, char *buf)
-{
-    snprintf(buf, UINT_BUFLEN, "%lu", from.v_uint);
-    return buf;
-}
-
-static bool sysvar_uint_fromstr(sysvar_t *to, const char *from)
-{
-    char *ep;
-    unsigned long v = strtoul(from, &ep, 0);
-    if (ep == from || *ep)
-	return false;
-    to->v_uint = v;
-    return true;
-}
-
-const struct sysvar_ops sysvar_uint_ops = {
-    .tostr = sysvar_uint_tostr,
-    .fromstr = sysvar_uint_fromstr,
-    .buflen = UINT_BUFLEN
-};
-
-static const char *sysvar_str_tostr(sysvar_t from, char *buf)
-{
-    (void)buf;
-    return from.v_str;
-}
-
-static bool sysvar_str_fromstr(sysvar_t *to, const char *from)
-{
-    char *ns;
-
-    if (!from) {
-	ns = NULL;
-    } else {
-	ns = strdup(from);
-	if (!ns)
-	    return false;
-    }
-    to->v_str = ns;
-    return true;
-}
-
-static bool sysvar_str_set(sysvar_t *to, sysvar_t from)
-{
-    return sysvar_str_fromstr(to, from.v_str);
-}
-
-static size_t sysvar_str_datasize(sysvar_t val)
-{
-    return (val.v_str ? strlen(val.v_str) : 0) + 1;
-}
-
-const struct sysvar_ops sysvar_str_ops = {
-    .set = sysvar_str_set,
-    .tostr = sysvar_str_tostr,
-    .fromstr = sysvar_str_fromstr,
-    .datasize = sysvar_str_datasize
-};
-
-static void sysvar_tz_update(sysvar_t val, bool isset)
-{
-    if (isset)
-	setenv("TZ", val.v_tz, 1);
-    else
-	unsetenv("TZ");
-    tzset();
-}
-
-const struct sysvar_ops sysvar_tz_ops = {
-    .set = sysvar_str_set,
-    .tostr = sysvar_str_tostr,
-    .fromstr = sysvar_str_fromstr,
-    .update = sysvar_tz_update,
-    .datasize = sysvar_str_datasize
-};
-
-static const char *sysvar_ip_tostr(sysvar_t from, char *buf)
-{
-    union ip_bytes {
-	uint8_t b[4];
-	uint32_t l;
-    } ip;
-
-    ip.l = from.v_ip;
-    snprintf(buf, IP_BUFLEN,
-	     "%u.%u.%u.%u", ip.b[0], ip.b[1], ip.b[2], ip.b[3]);
-    return buf;
-}
-
-static bool sysvar_ip_fromstr(sysvar_t *to, const char *str)
-{
-    union ip_bytes {
-	uint8_t b[4];
-	uint32_t l;
-    } ip;
-
-    ip.l = 0;
-    for (int i = 0; i < 4; i++) {
-	char *ep;
-	unsigned long v = strtoul(str, &ep, 10);
-	if (ep == str || *ep != (i == 3) ? '\0' : '.' || v > 255)
-	    return false;
-	str = ep + 1;
-	ip.b[i] = v;
-    }
-
-    to->v_ip = ip.l;
-    return true;
-}
-
-const struct sysvar_ops sysvar_ip_ops = {
-    .tostr = sysvar_ip_tostr,
-    .fromstr = sysvar_ip_fromstr,
-    .buflen = IP_BUFLEN
-};
-
-static bool sysvar_mac_set(sysvar_t *to, sysvar_t from)
-{
-    uint8_t *buf;
-
-    if (!from.v_mac) {
-	buf = NULL;
-    } else {
-	buf = malloc(6);
-	if (!buf)
-	    return false;
-
-	memcpy(buf, from.v_mac, 6);
-    }
-    to->v_mac = buf;
-    return true;
-}
-
-static const char *sysvar_mac_tostr(sysvar_t from, char *buf)
-{
-    const uint8_t *m = from.v_mac;
-    if (!m)
-	return NULL;
-
-    snprintf(buf, MAC_BUFLEN, "%x:%x:%x:%x:%x:%x",
-	     m[0], m[1], m[2], m[3], m[4], m[5]);
-    return buf;
-}
-
-static bool sysvar_mac_fromstr(sysvar_t *to, const char *str)
-{
-    sysvar_t from;
-    uint8_t m[6];
-
-    if (!str) {
-	from.v_mac = NULL;
-    } else {
-	for (int i = 0; i < 6; i++) {
-	    char *ep;
-	    unsigned long v = strtoul(str, &ep, 16);
-	    if (ep == str || *ep != (i == 5) ? '\0' : ':' || v > 255)
-		return false;
-	    str = ep + 1;
-	    m[i] = v;
-	}
-
-	from.v_mac = m;
-    }
-
-    return sysvar_mac_set(to, from);
-}
-
-static size_t sysvar_mac_datasize(sysvar_t val)
-{
-    (void)val;
-    return 6;
-}
-
-const struct sysvar_ops sysvar_mac_ops = {
-    .set = sysvar_mac_set,
-    .tostr = sysvar_mac_tostr,
-    .fromstr = sysvar_mac_fromstr,
-    .buflen = MAC_BUFLEN,
-    .datasize = sysvar_mac_datasize
-};
-
-/* --- Generic getters/setters --- */
-
-/* Contains the lowest numbered sysvar changed; or sysvar_count if nothing */
-enum sysvar_enum sysvar_changed;
-
-sysvar_t getvar(size_t var)
-{
-    if (var >= (size_t)sysvar_count)
-	return sysvar_defval[sysvar_null];
-
-    return sysvar_val[var];
-}
-
-static bool do_setvar(size_t var, sysvar_t val, bool is_set)
-{
-    const struct sysvar_ops *type = sysvar_types[var];
-    sysvar_t *to = &sysvar_val[var];
-    void *free_ptr = NULL;
-
-    if (type->datasize)
-	free_ptr = to->v_ptr;
-
-    if (DEBUG) {
-	char tostr_buf[SYSVAR_BUFLEN];
-	printf("%ssetvar %zu %s <- %s\n", is_set ? "" : "un",
-	       var, sysvar_name[var],
-	       notempty(type->tostr(val, tostr_buf)));
-    }
-
-    if (!type->set || (type->datasize && !val.v_ptr)) {
-	sysvar_val[var] = val;
-    } else {
-	if (!type->set(to, val))
-	    return false;
-    }
-
-    if (free_ptr)
-	free(free_ptr);
-
-    if (var < (size_t)sysvar_changed)
-	sysvar_changed = (enum sysvar_enum)var;
-
-    sysvar_isset[var] = is_set;
-    if (type->update)
-	type->update(*to, is_set);
-
-    return true;
-}
-
-bool setvar(size_t var, sysvar_t val)
-{
-    if (var >= (size_t)sysvar_count)
-	return false;
-
-    return do_setvar(var, val, true);
-}
-
-bool unsetvar(size_t var)
-{
-    if (var >= (size_t)sysvar_count)
-	return false;
-
-    return do_setvar(var, sysvar_defval[var], false);
-}
-
-/* --- Getters/setters converting to/from strings --- */
-
-const char *getvar_tostr(size_t var)
-{
-    static char buf[SYSVAR_BUFLEN];
-    return getvar_tostr_r(var, buf);
-}
-
-const char *getvar_tostr_r(size_t var, char *buf)
-{
-    if (var >= (size_t)sysvar_count)
-	return NULL;
-
-    const struct sysvar_ops *type = sysvar_types[var];
-
-    /* A tostr method is required */
-    return type->tostr(sysvar_val[var], buf);
-}
-
-bool setvar_fromstr(size_t var, const char *str)
-{
-    if (var >= (size_t)sysvar_count)
-	return NULL;
-
-    if (!str)
-	return unsetvar(var);
-
-    const struct sysvar_ops *type = sysvar_types[var];
-    sysvar_t *to = &sysvar_val[var];
-    void *free_ptr = NULL;
-
-    if (type->datasize)
-	free_ptr = to->v_ptr;
-
-    if (DEBUG) {
-	printf("setvar_fromstr %zu %s <- %s\n", var, sysvar_name[var], str);
-    }
-
-    /* A fromstr method is required */
-    if (!type->fromstr(to, str))
-	return false;
-
-    if (var < (size_t)sysvar_changed)
-	sysvar_changed = (enum sysvar_enum)var;
-
-    if (free_ptr)
-	free(free_ptr);
-
-    sysvar_isset[var] = true;
-    return true;
-}
-
-/* --- Find the index of a specific variable --- */
-
-static int string_ptr_compare(const void *a, const void *b)
-{
-    const char * const *aa = a;
-    const char * const *bb = b;
-    return strcmp(*aa, *bb);
-}
-
-size_t sysvar_find(size_t ns, const char *name)
-{
-    if (ns >= (size_t)sysvar_nscount)
-	return 0;
-
-    const sysvar_ns_t *nsi = &sysvar_ns[ns];
-    const char * const *varname;
-    const size_t count = nsi[1].first - nsi->first;
-
-    varname = bsearch(&name, sysvar_name + nsi->first,
-		      count, sizeof *sysvar_name,
-		      string_ptr_compare);
-    if (!varname)
-	return 0;
-
-    return varname - sysvar_name;
-}
-
-/* --- Initialization/reset to defaults --- */
-
-void sysvar_reset(size_t ns)
-{
-    if (ns >= (size_t)sysvar_nscount)
-	return;
-
-    enum sysvar_enum i;
-    for (i = sysvar_ns[ns].first; i < sysvar_ns[ns+1].first; i++)
-	unsetvar(i);
-
-    if (sysvar_changed < i)
-	sysvar_changed = i;
-}
-
-void sysvar_init(void)
-{
-    for (enum sysvar_enum i = sysvar_null+1; i < sysvar_count; i++)
-	unsetvar(i);
-
-    sysvar_changed = sysvar_count;
-}

+ 0 - 120
sysvars.h

@@ -1,120 +0,0 @@
-#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;
-
-/* 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 */