#pragma once
/* "feature tests" */
#define _POSIX_C_SOURCE 200112L
/* <unistd.h> seteuid
* <sys/socket.h netdb.h> getnameinfo */
#define _GNU_SOURCE
/* <net/if.h> IFNAMSIZ [linux]
* <unistd.h> getresuid [linux]*/
#define _DEFAULT_SOURCE
/* <unistd.h> daemon [glibc, BSD] */
/* arch headers */
#include <stdint.h>
#include <stddef.h>
#define _layout struct __attribute__((__packed__))
#define _zero(x) memset(&x, sizeof(x), 0)
#define _sz(x) (sizeof(x)/sizeof(x)[0])
#define __cat(a,b) a##b
#define _cat(a,b) __cat(a,b)
#define _strify(...) #__VA_ARGS__
#if __STDC_VERSION__ == 202000L
/* incomplete support */
#elif __STDC_VERSION__ > 202000L
# define null nullptr
#endif
#if __STDC_VERSION__ <= 202000L
# define null ((void*)0)
# define thread_local _Thread_local
# include <stdbool.h>
#endif
extern uint8_t g_loglevel;
extern thread_local char g_logbuf [2 * 1024];
#define _lprint(...) snprintf(g_logbuf, sizeof g_logbuf, __VA_ARGS__)
void msg(uint8_t lvl, char* tag, uint8_t color, char* msg);
#define _msgf(lvl, tag, color, ...) { \
if (g_loglevel >= lvl) { \
_lprint(__VA_ARGS__); \
msg(lvl, tag, color, g_logbuf); \
} \
}
#define _fatal(str) { msg(1, "fatal", 1, (str)); exit(1); }
#define _warn(str) msg(2, "warn", 3, (str))
#define _info(str) msg(3, "info", 4, (str))
#define _dbg(str) msg(4, "debug", 2, (str))
#define _fatalf(...) _msgf(1, "fatal", 1, __VA_ARGS__)
#define _warnf(...) _msgf(2, "warn", 3, __VA_ARGS__)
#define _infof(...) _msgf(3, "info", 4, __VA_ARGS__)
#define _dbgf(...) _msgf(4, "debug", 2, __VA_ARGS__)
typedef struct string {
size_t sz; char* ptr;
} string;