/* This software is licensed by the MIT License, see LICENSE file */ /* Copyright © 2022 Gregory Lirent */ #include #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; }