os-k/include/libc.h

398 lines
12 KiB
C

//----------------------------------------------------------------------------//
// OS on Kaleid //
// //
// Desc: C Runtime Library //
// //
// //
// Copyright © 2018-2020 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 <https://www.gnu.org/licenses/>. //
//----------------------------------------------------------------------------//
#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 <errno.h>
//----------------------------------------------------------------------------//
#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