Last active
June 3, 2023 23:06
-
-
Save dwilliamson/a51b6249af60416cad0bf69520c1ed22 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// TinyCRT, revamp and TinyWin support by Don Williamson, 2011 | |
// Based on http://www.codeproject.com/KB/library/tlibc.aspx and LIBCTINY by Matt Pietrek | |
// | |
#pragma once | |
#ifdef USE_DEFAULT_CRT | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <math.h> | |
#include <stdarg.h> | |
#include <float.h> | |
#include <cctype> | |
#define srandom srand | |
#define snprintf _snprintf | |
#else | |
#if defined(__clcpp_parse__) || (TINYCRT_NODLL) | |
#define TINYCRT_API | |
#else | |
#ifdef TINYCRT_IMPL | |
#define TINYCRT_API __declspec(dllexport) | |
#else | |
#define TINYCRT_API __declspec(dllimport) | |
#endif | |
#endif | |
#define NULL 0 | |
#define TCRT_RESTRICT __declspec(restrict) | |
#define TCRT_NOALIAS __declspec(noalias) | |
#define TCRT_INTRINSIC(fn) __pragma(intrinsic(fn)) | |
#define TCRT_GLOBAL | |
#ifdef __clang__ | |
#pragma clang diagnostic ignored "-Winvalid-offsetof" | |
#define offsetof(type,member) __builtin_offsetof(type, member) | |
#else | |
#define offsetof(type,member) ((size_t) &(((type*)0)->member)) | |
#endif | |
// ------------------------------------------------------------------------------------------------ | |
// Standard types | |
// ------------------------------------------------------------------------------------------------ | |
// stdint.h | |
typedef signed __int8 int8_t; | |
typedef signed __int16 int16_t; | |
typedef signed __int32 int32_t; | |
typedef signed __int64 int64_t; | |
typedef unsigned __int8 uint8_t; | |
typedef unsigned __int16 uint16_t; | |
typedef unsigned __int32 uint32_t; | |
typedef unsigned __int64 uint64_t; | |
// POSIX extensions | |
typedef unsigned char uchar_t; | |
typedef unsigned short ushort_t; | |
typedef unsigned int uint_t; | |
typedef unsigned long ulong_t; | |
// Wide types | |
typedef unsigned short wint_t; | |
typedef unsigned short wctype_t; | |
// The size of time_t is "unspecified" by the standard | |
// GCC defines it like this | |
typedef long int time_t; | |
#ifdef _WIN64 | |
typedef unsigned __int64 size_t; | |
typedef signed __int64 intptr_t; | |
typedef unsigned __int64 uintptr_t; | |
typedef __int64 ptrdiff_t; | |
#else | |
typedef __w64 unsigned int size_t; | |
typedef signed int intptr_t; | |
typedef unsigned int uintptr_t; | |
typedef __w64 int ptrdiff_t; | |
#endif | |
// printf-style macros | |
#define PRIx8 "x" // uint8_t | |
#define PRIx16 "x" // uint16_t | |
#define PRIx32 "x" // uint32_t | |
#define PRIx64 "llx" // uint64_t | |
// For isinf that aren't really in C library anyway | |
#ifndef __cplusplus | |
typedef unsigned int bool; | |
#endif | |
#ifdef __cplusplus | |
extern "C" | |
{ | |
#endif | |
// ------------------------------------------------------------------------------------------------ | |
// C atexit shutdown | |
// ------------------------------------------------------------------------------------------------ | |
typedef void(__cdecl *_PVFV)(); | |
int __cdecl atexit(_PVFV func); | |
void exit(int code); | |
TINYCRT_API char** _get_argv(); | |
// ------------------------------------------------------------------------------------------------ | |
// File handling | |
// ------------------------------------------------------------------------------------------------ | |
// File and seek constants | |
#define EOF (-1) | |
#define SEEK_CUR 1 | |
#define SEEK_END 2 | |
#define SEEK_SET 0 | |
// stdin/stdio/stderr access macros | |
#ifndef _STDSTREAM_DEFINED | |
#define stdin (&__iob_func()[0]) | |
#define stdout (&__iob_func()[1]) | |
#define stderr (&__iob_func()[2]) | |
#define _STDSTREAM_DEFINED | |
#endif | |
// The standard stdio.h FILE structure | |
#ifndef _FILE_DEFINED | |
struct _iobuf { | |
char *_ptr; | |
int _cnt; | |
char *_base; | |
int _flag; | |
int _file; | |
int _charbuf; | |
int _bufsiz; | |
char *_tmpfname; | |
}; | |
typedef struct _iobuf FILE; | |
#define _FILE_DEFINED | |
#endif | |
// stdio.h file access functions | |
TINYCRT_API FILE* __iob_func(); | |
TINYCRT_API FILE* fopen(const char* path, const char* attrs); | |
TINYCRT_API int fclose(FILE* fp); | |
TINYCRT_API int feof(FILE* fp); | |
TINYCRT_API int fprintf(FILE* fp, const char* format, ...); | |
TINYCRT_API int fseek(FILE* str, long offset, int origin); | |
TINYCRT_API long ftell(FILE* fp); | |
TINYCRT_API size_t fread(void* buffer, size_t size, size_t count, FILE* str); | |
TINYCRT_API size_t fwrite(const void* buffer, size_t size, size_t count, FILE* str); | |
TINYCRT_API char *fgets(char* str, int n, FILE* s); | |
TINYCRT_API int fgetc(FILE* s); | |
TINYCRT_API int fflush(FILE* fp); | |
// MSVC "safe" alternatives | |
TINYCRT_API int fopen_s(FILE** fp, const char* path, const char* attrs); | |
// Environment variable management | |
TINYCRT_API const char* getenv(const char* name); | |
TINYCRT_API void putenv(const char* name, const char* value); | |
// ------------------------------------------------------------------------------------------------ | |
// Maths | |
// ------------------------------------------------------------------------------------------------ | |
#define RAND_MAX ((1UL << 31) - 1) | |
#define DBL_DIG 15 /* # of decimal digits of precision */ | |
#define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that 1.0+DBL_EPSILON != 1.0 */ | |
#define DBL_MANT_DIG 53 /* # of bits in mantissa */ | |
#define DBL_MAX 1.7976931348623158e+308 /* max value */ | |
#define DBL_MAX_10_EXP 308 /* max decimal exponent */ | |
#define DBL_MAX_EXP 1024 /* max binary exponent */ | |
#define DBL_MIN 2.2250738585072014e-308 /* min positive value */ | |
#define DBL_MIN_10_EXP (-307) /* min decimal exponent */ | |
#define DBL_MIN_EXP (-1021) /* min binary exponent */ | |
#define DBL_MIN_10_UNIT 1e-307 | |
#define _DBL_RADIX 2 /* exponent radix */ | |
#define _DBL_ROUNDS 1 /* addition rounding: near */ | |
#define FLT_DIG 6 /* # of decimal digits of precision */ | |
#define FLT_EPSILON 1.192092896e-07F /* smallest such that 1.0+FLT_EPSILON != 1.0 */ | |
#define FLT_GUARD 0 | |
#define FLT_MANT_DIG 24 /* # of bits in mantissa */ | |
#define FLT_MAX 3.402823466e+38F /* max value */ | |
#define FLT_MAX_10_EXP 38 /* max decimal exponent */ | |
#define FLT_MAX_EXP 128 /* max binary exponent */ | |
#define FLT_MIN 1.175494351e-38F /* min positive value */ | |
#define FLT_MIN_10_EXP (-37) /* min decimal exponent */ | |
#define FLT_MIN_EXP (-125) /* min binary exponent */ | |
#define FLT_NORMALIZE 0 | |
#define FLT_RADIX 2 /* exponent radix */ | |
#define FLT_ROUNDS 1 /* addition rounding: near */ | |
#define FLT_MIN_10_UNIT 1e-37f | |
#define MB_LEN_MAX 5 /* max. # bytes in multibyte char */ | |
#define SHRT_MIN (-32768) /* minimum (signed) short value */ | |
#define SHRT_MAX 32767 /* maximum (signed) short value */ | |
#define USHRT_MAX 0xffff /* maximum unsigned short value */ | |
#define INT_MIN (-2147483647 - 1) /* minimum (signed) int value */ | |
#define INT_MAX 2147483647 /* maximum (signed) int value */ | |
#define UINT_MAX 0xffffffff /* maximum unsigned int value */ | |
#define LONG_MIN (-2147483647L - 1) /* minimum (signed) long value */ | |
#define LONG_MAX 2147483647L /* maximum (signed) long value */ | |
#define ULONG_MAX 0xffffffffUL /* maximum unsigned long value */ | |
#define LLONG_MAX 9223372036854775807i64 /* maximum signed long long int value */ | |
#define LLONG_MIN (-9223372036854775807i64 - 1) /* minimum signed long long int value */ | |
#define ULLONG_MAX 0xffffffffffffffffui64 /* maximum unsigned long long int value */ | |
#define I16_MIN SHRT_MIN | |
#define I16_MAX SHRT_MAX | |
#define U16_MIN 0 | |
#define U16_MAX USHRT_MAX | |
#define I32_MIN INT_MIN | |
#define I32_MAX INT_MAX | |
#define U32_MIN 0 | |
#define U32_MAX UINT_MAX | |
TINYCRT_API int abs(int n); | |
TINYCRT_API long strtol(const char* str, char** endptr, int base); | |
TINYCRT_API long long strtoll(const char* str, char** endptr, int base); | |
TINYCRT_API long atol(const char *str); | |
TINYCRT_API int atoi(const char *str); | |
TINYCRT_API void srandom(unsigned long seed); | |
TINYCRT_API unsigned long rand(); | |
TINYCRT_API double frexp(double value, int* eptr); | |
TINYCRT_API float frexpf(float value, int* eptr); | |
TINYCRT_API double ldexp(double x, int exp); | |
TINYCRT_API float ldexpf(float x, int exp); | |
TINYCRT_API double modf(double value, double* iptr); | |
TINYCRT_API float modff(float value, float* iptr); | |
TINYCRT_API double fmod(double x, double y); | |
TINYCRT_API float fmodf(float x, float y); | |
TINYCRT_API float floorf(float x); | |
TINYCRT_API float ceilf(float x); | |
TINYCRT_API double round(double x); | |
TINYCRT_API float roundf(float x); | |
TINYCRT_API double truncate(double x); | |
TINYCRT_API float truncatef(float x); | |
TINYCRT_API bool isinf(double value); | |
TINYCRT_API bool isinff(float value); | |
TINYCRT_API bool isnan(double value); | |
TINYCRT_API bool isnanf(float value); | |
TINYCRT_API double fabs(double val); | |
TINYCRT_API float fabsf(float val); | |
TINYCRT_API double sin(double angle); | |
TINYCRT_API float sinf(float angle); | |
TINYCRT_API double cos(double angle); | |
TINYCRT_API float cosf(float angle); | |
TINYCRT_API double tan(double angle); | |
TINYCRT_API float tanf(float angle); | |
TINYCRT_API double asin(double val); | |
TINYCRT_API float asinf(float val); | |
TINYCRT_API double acos(double val); | |
TINYCRT_API float acosf(float val); | |
TINYCRT_API double atan(double val); | |
TINYCRT_API float atanf(float val); | |
TINYCRT_API double atan2(double y, double x); | |
TINYCRT_API float atan2f(float y, float x); | |
float powf(float x, float y); | |
float expf(float x); | |
float sqrtf(float val); | |
TINYCRT_API int float_as_int(float f); | |
TINYCRT_API float int_as_float(int i); | |
TINYCRT_API uint32_t log2i(uint32_t x); | |
TINYCRT_API float logEf(float a); | |
TINYCRT_API float logf(float a, float b); | |
TINYCRT_API float log2f(float a); | |
TINYCRT_API float log10f(float a); | |
TINYCRT_API double cbrt(double val); | |
TINYCRT_API float cbrtf(float val); | |
TINYCRT_API int cbrti(int val); | |
// Visual C bit rotate functions | |
unsigned int _rotl(unsigned int value, int shift); TCRT_INTRINSIC(_rotl); | |
unsigned int _rotr(unsigned int value, int shift); TCRT_INTRINSIC(_rotr); | |
unsigned long _lrotl(unsigned long value, int shift); TCRT_INTRINSIC(_lrotl); | |
unsigned long _lrotr(unsigned long value, int shift); TCRT_INTRINSIC(_lrotr); | |
double floor(double x); | |
double ceil(double x); | |
double pow(double x, double y); TCRT_INTRINSIC(pow); | |
double exp(double x); TCRT_INTRINSIC(exp); | |
double sqrt(double val); TCRT_INTRINSIC(sqrt); | |
unsigned char _BitScanForward(unsigned long* Index, unsigned long Mask); TCRT_INTRINSIC(_BitScanForward); | |
__inline unsigned char bsf(unsigned long* Index, unsigned long Mask) | |
{ | |
return _BitScanForward(Index, Mask); | |
} | |
// ------------------------------------------------------------------------------------------------ | |
// Float/string conversion | |
// ------------------------------------------------------------------------------------------------ | |
char* dtoa_simple(double value, char* dest, int size); | |
TINYCRT_API double strtod(const char* s00, char** se); | |
TINYCRT_API char* dtoa(double d, int mode, int ndigits, int* decpt, int* sign, char** rve); | |
TINYCRT_API void freedtoa(char *s); | |
// ------------------------------------------------------------------------------------------------ | |
// Memory manipulation | |
// ------------------------------------------------------------------------------------------------ | |
TINYCRT_API int __cdecl memcmp(const void *b1, const void *b2, size_t n); | |
TINYCRT_API void * __cdecl memmove(void *dst, const void *src, size_t count); | |
void* __cdecl memset(void *dst, int val, size_t size); TCRT_INTRINSIC(memset); | |
void* __cdecl memcpy(void *dst, const void *src, size_t size); TCRT_INTRINSIC(memcpy); | |
// ------------------------------------------------------------------------------------------------ | |
// Variable argument support | |
// ------------------------------------------------------------------------------------------------ | |
// Standard vaarg stack pointer | |
typedef char * va_list; | |
// Variable argument macros | |
#define _ADDRESSOF(v) ( &(v) ) | |
#define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) ) | |
#define va_start(ap,v) ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) ) | |
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) | |
#define va_end(ap) ( ap = (va_list)0 ) | |
// Variable argument formatted printing | |
TINYCRT_API int vsnprintf(char* dest, size_t n, const char* format, va_list args); | |
TINYCRT_API int vsprintf(char* dest, const char* format, va_list args); // UNSAFE | |
TINYCRT_API int _snprintf(char* dest, size_t n, const char* fmt, ...); | |
TINYCRT_API int sprintf_s(char* dest, size_t n, const char* fmt, ...); | |
TINYCRT_API int sprintf(char* buffer, const char* format, ...); // UNSAFE | |
TINYCRT_API int vprintf(const char* format, va_list args); | |
TINYCRT_API int printf(const char* format, ...); | |
// TODO: Prefix underscore is the MSVC version (snprintf is non-standard). Do the same for the others... | |
#define snprintf _snprintf | |
// Unimplemented | |
__inline int sscanf(const char* src, const char* format, ...) | |
{ | |
return 0; | |
} | |
// ------------------------------------------------------------------------------------------------ | |
// String manipulation | |
// ------------------------------------------------------------------------------------------------ | |
TINYCRT_API int strcmp(const char *s1, const char *s2); | |
TINYCRT_API int strcmpi(const char *s1, const char *s2); | |
TINYCRT_API int stricmp(const char *s1, const char *s2); | |
TINYCRT_API int _stricmp(const char *s1, const char *s2); | |
TINYCRT_API int strncmp(const char *s1, const char *s2, size_t n); | |
TINYCRT_API int strnicmp(const char *s1, const char *s2, size_t n); | |
TINYCRT_API char* strcpy(char *dest, const char *src); | |
TINYCRT_API char *strncpy(char *dest, const char *src, size_t n); | |
TINYCRT_API size_t strlen(const char *str); | |
TINYCRT_API char *strchr(const char *str, int ch); | |
TINYCRT_API char *strrchr(const char *str, int ch); | |
TINYCRT_API char *strcat(char *dst, const char *src); | |
TINYCRT_API const char *strstr(const char *str, const char *substr); | |
TINYCRT_API char *_strupr(char *s); | |
TINYCRT_API char *_strlwr(char *s); | |
TINYCRT_API int toupper(int c); | |
TINYCRT_API int tolower(int c); | |
TINYCRT_API int isspace(int c); | |
TINYCRT_API int isupper(int c); | |
TINYCRT_API int islower(int c); | |
TINYCRT_API int isalpha(int c); | |
TINYCRT_API int isdigit(int c); | |
TINYCRT_API int isxdigit(int c); | |
TINYCRT_API int isalnum(int c); | |
TINYCRT_API int isprint(int c); | |
// ------------------------------------------------------------------------------------------------ | |
// Sorting | |
// ------------------------------------------------------------------------------------------------ | |
TINYCRT_API void qsort(void *a, size_t n, size_t es, int(*cmp)(const void *, const void *)); | |
TINYCRT_API void qsort_r(void *a, size_t n, size_t es, int(*cmp)(void*, const void *, const void *)); | |
// ------------------------------------------------------------------------------------------------ | |
// Assert | |
// ------------------------------------------------------------------------------------------------ | |
// Expressed as a macro so that the debugger breaks on the line of assertion | |
#define assert(expression) do { if (!(expression)) { pre_assert(#expression); __debugbreak(); post_assert(); } } while(0) | |
TINYCRT_API void set_assert_callback(void(*assert_callback)(const char*)); | |
TINYCRT_API void pre_assert(const char* expression_text); | |
TINYCRT_API void post_assert(void); | |
TINYCRT_API void assert_fn(int expression); | |
// Very simple implementation | |
TINYCRT_API uint64_t time(uint64_t* timer); | |
#ifdef __cplusplus | |
} | |
#endif | |
#ifdef __cplusplus | |
// min/max/swap unwrapped by std | |
template <typename TYPE> inline TYPE min(TYPE a, TYPE b) { return a < b ? a : b; } | |
template <typename TYPE> inline TYPE max(TYPE a, TYPE b) { return a > b ? a : b; } | |
template <typename TYPE> inline void swap(TYPE& a, TYPE& b) | |
{ | |
TYPE tmp; | |
tmp = a; | |
a = b; | |
b = tmp; | |
} | |
// Typed C++ wrappers around C stdlib functions | |
inline unsigned int abs(unsigned int val) { return val; } | |
inline float abs(float val) { return fabsf(val); } | |
inline double abs(double val) { return fabs(val); } | |
inline float fabs(float val) { return fabsf(val); } | |
inline float sin(float val) { return sinf(val); } | |
inline float cos(float val) { return cosf(val); } | |
inline float tan(float val) { return tanf(val); } | |
inline float asin(float val) { return asinf(val); } | |
inline float acos(float val) { return acosf(val); } | |
inline float atan(float val) { return atanf(val); } | |
inline float atan2(float y, float x) { return atan2f(y, x); } | |
inline int sqrt(int val) { return (int)sqrtf((float)val); } | |
inline unsigned int sqrt(unsigned int val) { return (unsigned int)sqrtf((float)val); } | |
inline float sqrt(float val) { return sqrtf(val); } | |
inline float floor(float val) { return floorf(val); } | |
inline float ceil(float val) { return ceilf(val); } | |
inline float pow(float x, float y) { return powf(x, y); } | |
inline float exp(float x) { return expf(x); } | |
inline float fmod(float x, float y) { return fmodf(x, y); } | |
// Custom implementation of C++ Standard Library list initialiser. | |
namespace std | |
{ | |
template <typename Type> | |
class initializer_list | |
{ | |
public: | |
#ifdef _MSC_VER | |
initializer_list(const Type* first, const Type* last) | |
: m_begin(first) | |
, m_end(last) | |
{ | |
} | |
#else | |
initializer_list(const Type* first, size_t len) | |
: m_begin(first) | |
, m_end(first + len) | |
{ | |
} | |
#endif | |
const Type* begin() const | |
{ | |
return m_begin; | |
} | |
const Type* end() const | |
{ | |
return m_end; | |
} | |
size_t size() const | |
{ | |
return m_end - m_begin; | |
} | |
private: | |
const Type* m_begin = nullptr; | |
const Type* m_end = nullptr; | |
}; | |
} | |
#endif | |
#endif // USE_DEFAULT_CRT |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment