//----------------------------------------------------------------------------// // OS on Kaleid // // // // Desc: C Runtime Library // // // // // // Copyright © 2018-2021 The OS/K Team // // // // This file is part of OS/K. // // // // OS/K is free software: you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation, either version 3 of the License, or // // any later version. // // // // OS/K is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY//without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with OS/K. If not, see . // //----------------------------------------------------------------------------// #ifndef _LIBC_H #define _LIBC_H #ifdef __cplusplus extern "C" { #endif //----------------------------------------------------------------------------// typedef unsigned char uchar; typedef signed char schar; typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; typedef signed long long llong; typedef unsigned long long ullong; typedef long double ldouble; typedef unsigned long size_t; typedef signed long ssize_t; typedef signed int wchar_t; typedef unsigned long off_t; typedef unsigned long time_t; typedef signed long ptrdiff_t; typedef signed long intptr_t; typedef unsigned long uintptr_t; typedef signed long intmax_t; typedef unsigned long uintmax_t; typedef uint error_t; typedef __builtin_va_list va_list; //----------------------------------------------------------------------------// #ifndef _KALEID_KERNEL extern error_t __errno; #define errno __errno #define geterrno(x) ((x) = errno) #define seterrno(x) (errno = (x)) #else #define errno #define geterrno(x) ((void)x) #define seterrno(x) ((void)x) #endif #include //----------------------------------------------------------------------------// #if defined(_NO_DEBUG) || defined(NDEBUG) #ifndef NDEBUG #define NDEBUG 1 #endif #ifndef _NO_DEBUG #define _NO_DEBUG 1 #endif #endif //----------------------------------------------------------------------------// #define alignof _Alignof #define alignas _Alignas #define static_assert _Static_assert #define noreturn __attribute__((__noreturn__)) #define likely(x) (__builtin_expect((x), 1)) #define unlikely(x) (__builtin_expect((x), 0)) #define va_start __builtin_va_start #define va_arg __builtin_va_arg #define va_copy __builtin_va_copy #define va_end __builtin_va_end //----------------------------------------------------------------------------// void *memset(void *, int, size_t); void *memsetw(void *, int, size_t); void *memsetd(void *, int, size_t); void *memsetq(void *, long, size_t); void *memrchr(const void *, int, size_t); void *memcpy(void *restrict, const void *restrict, size_t); void *memmove(void *, const void *, size_t); void *memzero(void *, size_t); int memcmp(const void *, const void *, size_t); //----------------------------------------------------------------------------// size_t strlen(const char *); size_t strspn(const char *, const char *); size_t strcspn(const char *, const char *); int strcmp(const char *, const char *); int strncmp(const char *, const char *, size_t); char *strchr(const char *, int); char *strrchr(const char *, int); char *strchrnul(const char *, int); char *strstr(const char *, const char *); char *strpbrk(const char *, const char *); char *strtok(char *restrict, const char *restrict); char *strtok_r(char *restrict, const char *restrict, char **restrict); char *strcpy(char *restrict, const char *restrict); char *strncpy(char *restrict, const char *restrict, size_t); char *strnzcpy(char *restrict, const char *restrict, size_t); char *strcat(char *restrict, const char *restrict); char *strncat(char *restrict, const char *restrict, size_t); char *strnzcat(char *restrict, const char *restrict, size_t); char *strrev(char *restrict, const char *restrict); char *strrev2(char *); size_t sprintf(char *, const char *, ...); size_t snprintf(char *, size_t, const char *, ...); size_t vsprintf(char *, const char *, va_list); size_t vsnprintf(char *, size_t, const char *, va_list); //----------------------------------------------------------------------------// char *itoa(int, char *, int); char *ltoa(long, char *, int); char *utoa(unsigned int, char *, int); char *ultoa(unsigned long, char *, int); int atoi(const char *); long atol(const char *); long strtol(const char *restrict, char **restrict, int); unsigned int atou(const char *); unsigned long atoul(const char *); unsigned long strtoul(const char *restrict, char **restrict, int); //----------------------------------------------------------------------------// void *calloc(size_t, size_t) __attribute__((__malloc__)); void *memalign(size_t n, size_t align) __attribute__((__malloc__)); void *malloc(size_t) __attribute__((__malloc__)); void free(void *); //----------------------------------------------------------------------------// int rand(void); void srand(unsigned long); //----------------------------------------------------------------------------// const char *strerror(error_t); const char *strsignal(int); //----------------------------------------------------------------------------// int toupper(int); int tolower(int); static inline int isascii(int __c) { return !(__c & ~0xff); } //----------------------------------------------------------------------------// extern int __ctype[]; #define _SH(x) (1 << (x)) enum { _CT = _SH(0), // control _PR = _SH(1), // printing _GR = _SH(2), // graphical _DX = _SH(3), // hex digit _DG = _SH(4), // decimal digit _SP = _SH(5), // space _BK = _SH(6), // blank _PT = _SH(7), // punctuation _AL = _SH(8), // alpha _UP = _SH(9), // upper alpha _LW = _SH(10), // lower alpha }; #define _DECF(name, flag) \ static inline int name(int __c) \ { return isascii(__c) ? !!(__ctype[__c] & flag) : 0; } _DECF(iscntrl, _CT); _DECF(isprint, _PR); _DECF(isgraph, _GR); _DECF(isdigit, _DG); _DECF(isspace, _SP); _DECF(isblank, _BK); _DECF(ispunct, _PT); _DECF(isalpha, _AL); _DECF(isupper, _UP); _DECF(islower, _LW); _DECF(isxdigit, _DX); _DECF(isalnum, (_AL|_DG)); #undef _SH #undef _DECF //----------------------------------------------------------------------------// static inline int min(int __x, int __y) { return __x < __y ? __x : __y; } static inline int max(int __x, int __y) { return __x > __y ? __x : __y; } static inline int abs(int __x) { return __x < 0 ? -__x : __x; } static inline long lmin(long __x, long __y) { return __x < __y ? __x : __y; } static inline long lmax(long __x, long __y) { return __x > __y ? __x : __y; } static inline long labs(long __x) { return __x < 0 ? -__x : __x; } //----------------------------------------------------------------------------// noreturn void __assert_handler(const char *, const char *, int, const char *); #define assert_always(x) do { if unlikely (!(x)) \ __assert_handler(#x, __FILE__, __LINE__, __func__); } while (0) #ifndef NDEBUG #define assert(x) assert_always(x) #else #define assert(x) ((void)0) #endif //----------------------------------------------------------------------------// #define _SA_MSG "Incompatible type sizes" static_assert(sizeof(char) == 1, _SA_MSG); static_assert(sizeof(short) == 2, _SA_MSG); static_assert(sizeof(int) == 4, _SA_MSG); static_assert(sizeof(long) == 8, _SA_MSG); static_assert(sizeof(void *) == 8, _SA_MSG); #undef _SA_MSG //----------------------------------------------------------------------------// #define KB (1UL << 10) #define MB (1UL << 20) #define GB (1UL << 30) #define TB (1UL << 40) #define TRUE 1 #define FALSE 0 #define NULL 0L #define BOOL int #ifndef __cplusplus #define bool int #define true 1 #define false 0 #endif #define RAND_MAX (1 << 30) #define INITOK ((unsigned int)0xCAFEBABE) #define _STR(x) #x #define _XSTR(x) _STR(x) #define _ALIGN_UP(x, s) (((x) + (s) - 1) & (~((s) - 1))) //----------------------------------------------------------------------------// #define BYTE unsigned char #define WORD unsigned short #define DWORD unsigned int #define QWORD unsigned long #define CHAR_BIT 8 #define BITS_IN(T) (sizeof(T) * CHAR_BIT) #define _ADDR_TO_MB(x) ((x)>>20) #define _ADDR_TO_KB(x) (((x)>>10)&(KB-1)) #define _ADDR_TO_B(x) ((x)&(KB-1)) #define SCHAR_MAX 0x7F #define SHRT_MAX 0x7FFF #define INT_MAX 0x7FFFFFFF #define LONG_MAX 0x7FFFFFFFFFFFFFFFL #define UCHAR_MAX 0xFFU #define USHRT_MAX 0xFFFFU #define UINT_MAX 0xFFFFFFFFU #define ULONG_MAX 0xFFFFFFFFFFFFFFFFUL #define SCHAR_MIN (-SCHAR_MAX - 1) #define SHRT_MIN (-SHRT_MAX - 1) #define INT_MIN (-INT_MAX - 1) #define LONG_MIN (-LONG_MAX - 1L) #ifdef __CHAR_UNSIGNED__ # define CHAR_MIN ((char)0) # define CHAR_MAX ((char)UCHAR_MAX) #else # define CHAR_MIN ((char)SCHAR_MIN) # define CHAR_MAX ((char)SCHAR_MAX) #endif #define SSIZE_T_MIN LONG_MIN #define SSIZE_T_MAX LONG_MAX #define SIZE_T_MAX ULONG_MAX //----------------------------------------------------------------------------// #define atomic_xadd(P, V) __sync_fetch_and_add((P), (V)) #define atomic_cmpxchg(P, O, N) __sync_val_compare_and_swap((P), (O), (N)) #define atomic_inc(P) __sync_add_and_fetch((P), 1) #define atomic_dec(P) __sync_add_and_fetch((P), -1) #define atomic_add(P, V) __sync_add_and_fetch((P), (V)) #define atomic_set_bit(P, V) __sync_or_and_fetch((P), 1<<(V)) #define atomic_clear_bit(P, V) __sync_and_and_fetch((P), ~(1<<(V))) #define atomic_barrier() __sync_synchronize() #define __relax_cpu() asm volatile("pause\n": : : "memory") static inline void *atomic_xchg_64(volatile void *ptr, void *x) { asm volatile ("xchgq %0,%1" :"=r" ((ulong) x) :"m" (*(volatile long *)ptr), "0" ((ulong) x) :"memory"); return x; } static inline unsigned atomic_xchg_32(volatile void *ptr, uint x) { asm volatile ("xchgl %0,%1" :"=r" ((uint) x) :"m" (*(volatile uint *)ptr), "0" (x) :"memory"); return x; } static inline unsigned short atomic_xchg_16(volatile void *ptr, ushort x) { asm volatile ("xchgw %0,%1" :"=r" ((unsigned short) x) :"m" (*(volatile ushort *)ptr), "0" (x) :"memory"); return x; } static inline char atomic_bitsetandtest(volatile void *ptr, int x) { char out; asm volatile ("lock; bts %2,%1\n" "sbb %0,%0\n" :"=r" (out), "=m" (*(volatile long *)ptr) :"Ir" (x) :"memory"); return out; } //----------------------------------------------------------------------------// #ifdef __cplusplus } #endif #endif