Runtime/math matches; better libc headers

This commit is contained in:
2022-08-25 23:46:24 -04:00
parent e50328cd89
commit bef7db1748
116 changed files with 5434 additions and 973 deletions

20
libc/assert.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef _ASSERT_H_
#define _ASSERT_H_
#ifdef __cplusplus
extern "C" {
#endif
#if __STDC_VERSION__ >= 201112L
// The C11 way
#define static_assert(cond, msg) _Static_assert(cond, #msg)
#else
// The old, hacky way
#define static_assert(cond, msg) typedef char static_assertion_##msg[(cond) ? 1 : -1]
#endif
#ifdef __cplusplus
}
#endif
#endif

84
libc/ctype.h Normal file
View File

@@ -0,0 +1,84 @@
#ifndef _CTYPE_H_
#define _CTYPE_H_
#ifdef __cplusplus
extern "C" {
#endif
// eof.h
#define EOF -1L
extern unsigned char __ctype_map[];
extern unsigned char __lower_map[];
extern unsigned char __upper_map[];
#define __control_char 0x01
#define __motion_char 0x02
#define __space_char 0x04
#define __punctuation 0x08
#define __digit 0x10
#define __hex_digit 0x20
#define __lower_case 0x40
#define __upper_case 0x80
#define __letter (__lower_case | __upper_case)
#define __alphanumeric (__letter | __digit)
#define __graphic (__alphanumeric | __punctuation)
#define __printable (__graphic | __space_char)
#define __whitespace (__motion_char | __space_char)
#define __control (__motion_char | __control_char)
#define __zero_fill(c) ((int)(unsigned char)(c))
int isalnum(int);
int isalpha(int);
int iscntrl(int);
int isdigit(int);
int isgraph(int);
int islower(int);
int isprint(int);
int ispunct(int);
int isspace(int);
int isupper(int);
int isxdigit(int);
int tolower(int);
int toupper(int);
int iswblank(int);
#ifndef _CTYPE_INLINE
#define _CTYPE_INLINE static inline
#endif
_CTYPE_INLINE
int isalnum(int c) { return __ctype_map[__zero_fill(c)] & __alphanumeric; }
_CTYPE_INLINE
int isalpha(int c) { return __ctype_map[__zero_fill(c)] & __letter; }
_CTYPE_INLINE
int iscntrl(int c) { return __ctype_map[__zero_fill(c)] & __control; }
_CTYPE_INLINE
int isdigit(int c) { return __ctype_map[__zero_fill(c)] & __digit; }
_CTYPE_INLINE
int isgraph(int c) { return __ctype_map[__zero_fill(c)] & __graphic; }
_CTYPE_INLINE
int islower(int c) { return __ctype_map[__zero_fill(c)] & __lower_case; }
_CTYPE_INLINE
int isprint(int c) { return __ctype_map[__zero_fill(c)] & __printable; }
_CTYPE_INLINE
int ispunct(int c) { return __ctype_map[__zero_fill(c)] & __punctuation; }
_CTYPE_INLINE
int isspace(int c) { return __ctype_map[__zero_fill(c)] & __whitespace; }
_CTYPE_INLINE
int isupper(int c) { return __ctype_map[__zero_fill(c)] & __upper_case; }
_CTYPE_INLINE
int isxdigit(int c) { return __ctype_map[__zero_fill(c)] & __hex_digit; }
_CTYPE_INLINE
int tolower(int c) { return ((c == EOF) ? EOF : ((int)__lower_map[__zero_fill(c)])); }
_CTYPE_INLINE
int toupper(int c) { return ((c == EOF) ? EOF : ((int)__upper_map[__zero_fill(c)])); }
_CTYPE_INLINE
int iswblank(int c) { return ((c == (int)L' ') || (c == (int)L'\t')); }
#ifdef __cplusplus
}
#endif
#endif

20
libc/errno.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef _ERRNO_H_
#define _ERRNO_H_
#ifdef __cplusplus
extern "C" {
#endif
extern int errno;
#define ENOERR 0
#define EDOM 33
#define ERANGE 34
#define EFPOS 35
#define ESIGPARM 36
#ifdef __cplusplus
}
#endif
#endif

14
libc/float.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef _FLOAT_H_
#define _FLOAT_H_
#ifdef __cplusplus
extern "C" {
#endif
#define FLT_EPSILON 1.1920928955078125e-07f
#ifdef __cplusplus
}
#endif
#endif

24
libc/limits.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef _LIMITS_H_
#define _LIMITS_H_
#define SCHAR_MAX 0x7f
#define UCHAR_MAX 0xffU
#if defined(__MWERKS__) && __option(unsigned_char)
#define CHAR_MIN 0U
#define CHAR_MAX UCHAR_MAX
#else
#define CHAR_MIN SCHAR_MIN
#define CHAR_MAX SCHAR_MAX
#endif
#define SHRT_MAX 0x7fff
#define USHRT_MAX 0xffffU
#define INT_MAX 0x7fffffff
#define UINT_MAX 0xffffffffU
#define LONG_MAX 0x7fffffffL
#define ULONG_MAX 0xffffffffUL
#endif

39
libc/locale.h Normal file
View File

@@ -0,0 +1,39 @@
#ifndef _LOCALE_H_
#define _LOCALE_H_
#ifdef __cplusplus
extern "C" {
#endif
struct lconv {
char* decimal_point;
char* thousands_sep;
char* grouping;
char* mon_decimal_point;
char* mon_thousands_sep;
char* mon_grouping;
char* positive_sign;
char* negative_sign;
char* currency_symbol;
char frac_digits;
char p_cs_precedes;
char n_cs_precedes;
char p_sep_by_space;
char n_sep_by_space;
char p_sign_posn;
char n_sign_posn;
char* int_curr_symbol;
char int_frac_digits;
char int_p_cs_precedes;
char int_n_cs_precedes;
char int_p_sep_by_space;
char int_n_sep_by_space;
char int_p_sign_posn;
char int_n_sign_posn;
};
#ifdef __cplusplus
}
#endif
#endif

198
libc/math.h Normal file
View File

@@ -0,0 +1,198 @@
#ifndef _MATH_H_
#define _MATH_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __MWERKS__
/* Metrowerks */
#if __option(little_endian)
#define __IEEE_LITTLE_ENDIAN
#else
#define __IEEE_BIG_ENDIAN
#endif
#else
/* GCC */
#ifdef __BIG_ENDIAN__
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __LITTLE_ENDIAN__
#define __IEEE_LITTLE_ENDIAN
#endif
#endif
#ifndef __IEEE_BIG_ENDIAN
#ifndef __IEEE_LITTLE_ENDIAN
#error Must define endianness
#endif
#endif
#ifndef _INT32
typedef int _INT32;
typedef unsigned int _UINT32;
#endif
#ifdef __MWERKS__
#define abs(n) __abs(n)
#define labs(n) __labs(n)
static inline double fabs(double x) { return __fabs(x); }
static inline float fabsf(float x) { return (float)fabs((double)x); }
#else
static inline int abs(int n) {
int mask = n >> 31;
return (n + mask) ^ mask;
}
#endif
extern _INT32 __float_huge[];
extern _INT32 __float_nan[];
extern _INT32 __double_huge[];
extern _INT32 __extended_huge[];
#define HUGE_VAL (*(double*)__double_huge)
#define INFINITY (*(float*)__float_huge)
#define NAN (*(float*)__float_nan)
#define HUGE_VALF (*(float*)__float_huge)
#define HUGE_VALL (*(long double*)__extended_huge)
double fabs(double x);
double sin(double x);
double cos(double x);
double atan(double x);
float sinf(float x);
float cosf(float x);
float tanf(float x);
float acosf(float x);
double ldexp(double x, int exp);
double copysign(double x, double y);
double floor(double x);
double fabs(double x);
#ifdef __MWERKS__
#pragma cplusplus on
#endif
#ifdef __IEEE_LITTLE_ENDIAN
#define __HI(x) (sizeof(x) == 8 ? *(1 + (_INT32*)&x) : (*(_INT32*)&x))
#define __LO(x) (*(_INT32*)&x)
#define __UHI(x) (sizeof(x) == 8 ? *(1 + (_UINT32*)&x) : (*(_UINT32*)&x))
#define __ULO(x) (*(_UINT32*)&x)
#else
#define __LO(x) (sizeof(x) == 8 ? *(1 + (_INT32*)&x) : (*(_INT32*)&x))
#define __HI(x) (*(_INT32*)&x)
#define __ULO(x) (sizeof(x) == 8 ? *(1 + (_UINT32*)&x) : (*(_UINT32*)&x))
#define __UHI(x) (*(_UINT32*)&x)
#endif
#define FP_NAN 1
#define FP_INFINITE 2
#define FP_ZERO 3
#define FP_NORMAL 4
#define FP_SUBNORMAL 5
static inline int __fpclassifyf(float x) {
switch ((*(_INT32*)&x) & 0x7f800000) {
case 0x7f800000: {
if ((*(_INT32*)&x) & 0x007fffff)
return FP_NAN;
else
return FP_INFINITE;
break;
}
case 0: {
if ((*(_INT32*)&x) & 0x007fffff)
return FP_SUBNORMAL;
else
return FP_ZERO;
break;
}
}
return FP_NORMAL;
}
static inline int __fpclassifyd(double x) {
switch (__HI(x) & 0x7ff00000) {
case 0x7ff00000: {
if ((__HI(x) & 0x000fffff) || (__LO(x) & 0xffffffff))
return FP_NAN;
else
return FP_INFINITE;
break;
}
case 0: {
if ((__HI(x) & 0x000fffff) || (__LO(x) & 0xffffffff))
return FP_SUBNORMAL;
else
return FP_ZERO;
break;
}
}
return FP_NORMAL;
}
#define fpclassify(x) (sizeof(x) == sizeof(float) ? __fpclassifyf((float)(x)) : __fpclassifyd((double)(x)))
#define isnormal(x) (fpclassify(x) == FP_NORMAL)
#define isnan(x) (fpclassify(x) == FP_NAN)
#define isinf(x) (fpclassify(x) == FP_INFINITE)
#define isfinite(x) ((fpclassify(x) > FP_INFINITE))
static inline float sqrtf(float x) {
static const double _half = .5;
static const double _three = 3.0;
if (x > 0.0f) {
double xd = (double)x;
double guess = __frsqrte(xd); /* returns an approximation to */
guess = _half * guess * (_three - guess * guess * xd); /* now have 12 sig bits */
guess = _half * guess * (_three - guess * guess * xd); /* now have 24 sig bits */
guess = _half * guess * (_three - guess * guess * xd); /* now have 32 sig bits */
return (float)(xd * guess);
} else if (x < 0.0)
return NAN;
else if (isnan(x))
return NAN;
else
return x;
}
static inline double sqrt(double x) {
if (x > 0.0) {
double guess = __frsqrte(x); /* returns an approximation to */
guess = .5 * guess * (3.0 - guess * guess * x); /* now have 8 sig bits */
guess = .5 * guess * (3.0 - guess * guess * x); /* now have 16 sig bits */
guess = .5 * guess * (3.0 - guess * guess * x); /* now have 32 sig bits */
guess = .5 * guess * (3.0 - guess * guess * x); /* now have > 53 sig bits */
return x * guess;
} else if (x == 0.0) {
return 0;
} else if (x) {
return NAN;
}
return INFINITY;
}
static inline float ldexpf(float x, int exp) { return (float)ldexp((double)x, exp); }
static inline double scalbn(double x, int n) { return ldexp(x, n); }
static inline float scalbnf(float x, int n) { return (float)ldexpf(x, n); }
#ifdef __MWERKS__
#pragma cplusplus reset
#endif
#ifdef __cplusplus
}
#endif
#endif

22
libc/mem_funcs.h Normal file
View File

@@ -0,0 +1,22 @@
#ifndef _MEM_FUNCS_H_
#define _MEM_FUNCS_H_
#ifdef __cplusplus
extern "C" {
#endif
#define __min_bytes_for_long_copy 32
void __copy_mem(void* dst, const void* src, unsigned long n);
void __move_mem(void* dst, const void* src, unsigned long n);
void __copy_longs_aligned(void* dst, const void* src, unsigned long n);
void __copy_longs_rev_aligned(void* dst, const void* src, unsigned long n);
void __copy_longs_unaligned(void* dst, const void* src, unsigned long n);
void __copy_longs_rev_unaligned(void* dst, const void* src, unsigned long n);
void __fill_mem(void* dst, int val, unsigned long n);
#ifdef __cplusplus
}
#endif
#endif

39
libc/stdarg.h Normal file
View File

@@ -0,0 +1,39 @@
#ifndef _STDARG_H_
#define _STDARG_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __MWERKS__
typedef struct {
char gpr;
char fpr;
char reserved[2];
char* input_arg_area;
char* reg_save_area;
} __va_list[1];
typedef __va_list va_list;
#ifndef __MWERKS__
extern void __builtin_va_info(va_list*);
#endif
void* __va_arg(va_list v_list, unsigned char type);
#define va_start(ap, fmt) ((void)fmt, __builtin_va_info(&ap))
#define va_arg(ap, t) (*((t*)__va_arg(ap, _var_arg_typeof(t))))
#define va_end(ap) (void)0
#else
typedef __builtin_va_list va_list;
#define va_start(v, l) __builtin_va_start(v, l)
#define va_end(v) __builtin_va_end(v)
#define va_arg(v, l) __builtin_va_arg(v, l)
#endif
#ifdef __cplusplus
}
#endif
#endif

20
libc/stddef.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef _STDDEF_H_
#define _STDDEF_H_
#ifdef __cplusplus
extern "C" {
#endif
#define offsetof(type, member) ((size_t) & (((type*)0)->member))
typedef unsigned int size_t;
#ifndef NULL
#define NULL 0L
#endif
#ifdef __cplusplus
}
#endif
#endif

14
libc/stdint.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef _STDINT_H_
#define _STDINT_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned long int uintptr_t;
#ifdef __cplusplus
}
#endif
#endif

76
libc/stdio.h Normal file
View File

@@ -0,0 +1,76 @@
#ifndef _STDIO_H_
#define _STDIO_H_
#include <stddef.h>
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif
#define __ungetc_buffer_size 2
typedef unsigned long __file_handle;
typedef unsigned long fpos_t;
typedef unsigned short wchar_t;
enum __file_kinds { __closed_file, __disk_file, __console_file, __unavailable_file };
enum __file_orientation { __unoriented, __char_oriented, __wide_oriented };
typedef struct {
unsigned int open_mode : 2;
unsigned int io_mode : 3;
unsigned int buffer_mode : 2;
unsigned int file_kind : 3;
unsigned int file_orientation : 2;
unsigned int binary_io : 1;
} __file_modes;
typedef struct {
unsigned int io_state : 3;
unsigned int free_buffer : 1;
unsigned char eof;
unsigned char error;
} __file_state;
typedef void* __ref_con;
typedef int (*__pos_proc)(__file_handle file, fpos_t* position, int mode, __ref_con ref_con);
typedef int (*__io_proc)(__file_handle file, unsigned char* buff, size_t* count, __ref_con ref_con);
typedef int (*__close_proc)(__file_handle file);
typedef struct _FILE {
__file_handle handle;
__file_modes mode;
__file_state state;
unsigned char is_dynamically_allocated;
unsigned char char_buffer;
unsigned char char_buffer_overflow;
unsigned char ungetc_buffer[__ungetc_buffer_size];
wchar_t ungetwc_buffer[__ungetc_buffer_size];
unsigned long position;
unsigned char* buffer;
unsigned long buffer_size;
unsigned char* buffer_ptr;
unsigned long buffer_len;
unsigned long buffer_alignment;
unsigned long saved_buffer_len;
unsigned long buffer_pos;
__pos_proc position_proc;
__io_proc read_proc;
__io_proc write_proc;
__close_proc close_proc;
__ref_con ref_con;
struct _FILE* next_file_struct;
} FILE;
int puts(const char* s);
int printf(const char*, ...);
int sprintf(char* s, const char* format, ...);
int vprintf(const char* format, va_list arg);
int vsprintf(char* s, const char* format, va_list arg);
#ifdef __cplusplus
}
#endif
#endif

25
libc/stdlib.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef _STDLIB_H_
#define _STDLIB_H_
#include <stddef.h>
#include <wchar.h>
#define RAND_MAX 32767
#ifdef __cplusplus
extern "C" {
#endif
void srand(unsigned int seed);
int rand(void);
void exit(int status);
size_t wcstombs(char* dest, const wchar_t* src, size_t max);
typedef int (*_compare_function)(const void*, const void*);
void qsort(void*, size_t, size_t, _compare_function);
#ifdef __cplusplus
}
#endif
#endif

24
libc/string.h Normal file
View File

@@ -0,0 +1,24 @@
#ifndef _STRING_H_
#define _STRING_H_
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
void* memcpy(void* dest, const void* src, size_t num);
void* memset(void* dest, int ch, size_t count);
size_t strlen(const char* s);
char* strcpy(char* dest, const char* src);
char* strncpy(char* dest, const char* src, size_t num);
int strcmp(const char* s1, const char* s2);
int strncmp(const char* s1, const char* s2, size_t n);
char* strncat(char* dest, const char* src, size_t n);
#ifdef __cplusplus
}
#endif
#endif

16
libc/wchar.h Normal file
View File

@@ -0,0 +1,16 @@
#ifndef _WCHAR_H_
#define _WCHAR_H_
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
int fwide(FILE* stream, int mode);
#ifdef __cplusplus
}
#endif
#endif