libcdsb/src/vtype-extra.c

103 lines
4.3 KiB
C

/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include <stdio.h>
#include "__internal/include.h"
/*#####################################################################################################################*/
#define sh__(a) #a
#define s__(a) sh__(a)
#define fstring(v) _Generic((v),\
unsigned char: "%hhu", signed char: "%hhd",\
unsigned short: "%hu", signed short: "%hd",\
unsigned int: "%u", signed int: "%d",\
unsigned long: "%lu", signed long: "%ld",\
unsigned long long: "%llu", signed long long: "%lld",\
float: "%."s__(FLT_DIG)"g",\
double: "%."s__(DBL_DIG)"lg",\
long double: "%."s__(LDBL_DIG)"Lg")
#define stringify(v) sprintf(STRINGIFY_BUFFER, fstring(v), (v))
static _Thread_local char STRINGIFY_BUFFER[64];
/*#####################################################################################################################*/
const size_t LIBCDSB_VTYPE_SIZES[18] = {
sizeof(void*), sizeof(_Bool),
sizeof(u8_t), sizeof(u16_t), sizeof(u32_t), sizeof(u64_t),
sizeof(s8_t), sizeof(s16_t), sizeof(s32_t), sizeof(s64_t),
sizeof(fl_t), sizeof(dbl_t), sizeof(ldbl_t),
sizeof(str_t), sizeof(map_t), sizeof(arr_t),
sizeof(list_t), sizeof(set_t)
};
/*#####################################################################################################################*/
const char* libcdsb_vtype_name(vtype t) {
switch (t) { default: abort();
case VTYPE_POINTER: return "VTYPE_POINTER";
case VTYPE_BOOLEAN: return "VTYPE_BOOLEAN";
case VTYPE_UINT8: return "VTYPE_UINT8";
case VTYPE_UINT16: return "VTYPE_UINT16";
case VTYPE_UINT32: return "VTYPE_UINT32";
case VTYPE_UINT64: return "VTYPE_UINT64";
case VTYPE_INT8: return "VTYPE_INT8";
case VTYPE_INT16: return "VTYPE_INT16";
case VTYPE_INT32: return "VTYPE_INT32";
case VTYPE_INT64: return "VTYPE_INT64";
case VTYPE_FLOAT: return "VTYPE_FLOAT";
case VTYPE_DOUBLE: return "VTYPE_DOUBLE";
case VTYPE_LDOUBLE: return "VTYPE_LDOUBLE";
case VTYPE_STRING: return "VTYPE_STRING";
case VTYPE_MAP: return "VTYPE_MAP";
case VTYPE_ARRAY: return "VTYPE_ARRAY";
case VTYPE_LIST: return "VTYPE_LIST";
case VTYPE_SET: return "VTYPE_SET";
}
}
const char* libcdsb_vtype_stringify(const void* v, vtype t) {
if (is_null(v) || (t == VTYPE_POINTER && is_null(*(void**)v))) return "null";
if (t == VTYPE_BOOLEAN) return (*(vtype_bool*)v) ? "true" : "false";
if (t == VTYPE_STRING) return *(char**)v;
switch (t) {
case VTYPE_INT8: stringify(*( s8_t*)v); break;
case VTYPE_INT16: stringify(*( s16_t*)v); break;
case VTYPE_INT32: stringify(*( s32_t*)v); break;
case VTYPE_INT64: stringify(*( s64_t*)v); break;
case VTYPE_UINT8: stringify(*( u8_t*)v); break;
case VTYPE_UINT16: stringify(*( u16_t*)v); break;
case VTYPE_UINT32: stringify(*( u32_t*)v); break;
case VTYPE_UINT64: stringify(*( u64_t*)v); break;
case VTYPE_FLOAT: if (abs(*(fl_t*)v) <= FLT_EPSILON) {
STRINGIFY_BUFFER[0] = 0x30;
STRINGIFY_BUFFER[1] = 0x00;
} else stringify(*(fl_t*)v);
break;
case VTYPE_DOUBLE: if (abs(*(dbl_t*)v) <= DBL_EPSILON) {
STRINGIFY_BUFFER[0] = 0x30;
STRINGIFY_BUFFER[1] = 0x00;
} else stringify(*(dbl_t*)v);
break;
case VTYPE_LDOUBLE: if (abs(*(ldbl_t*)v) <= LDBL_EPSILON) {
STRINGIFY_BUFFER[0] = 0x30;
STRINGIFY_BUFFER[1] = 0x00;
} else stringify(*(ldbl_t*)v);
break;
case VTYPE_POINTER: sprintf(STRINGIFY_BUFFER, (sizeof(void*) == 8) ? "0x%016lx" : "0x%08x", (uintptr_t)*(void**)v); break;
default: sprintf(STRINGIFY_BUFFER, "<%s>", libcdsb_vtype_name(t));
break;
}
return STRINGIFY_BUFFER;
}