Fixing more broken stuff
This commit is contained in:
parent
27e6b9f69f
commit
b7fa7a30d0
|
@ -0,0 +1,33 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Arithmetical functions //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
// do not mask anything
|
||||||
|
#define _KALEID_UNMASKED
|
||||||
|
#include <kalbase.h>
|
||||||
|
|
||||||
|
int _osk_abs(int x)
|
||||||
|
{
|
||||||
|
return abs(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
long _osk_labs(long x)
|
||||||
|
{
|
||||||
|
return labs(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
div_t _osk_div(int x, int y)
|
||||||
|
{
|
||||||
|
return div(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
ldiv_t _osk_ldiv(long x, long y)
|
||||||
|
{
|
||||||
|
return ldiv(x, y);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Conversion utilities - atoi family //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include <kalbase.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// String to integer
|
||||||
|
// Do not change errno
|
||||||
|
//
|
||||||
|
#define _ATOI_IMPL(_Name, _Type, _Func) \
|
||||||
|
_Type _Name(const char *str) { \
|
||||||
|
__get_errno(old); \
|
||||||
|
_Type ret = (_Type)_Func(str, NULL, 0); \
|
||||||
|
__set_errno(old); \
|
||||||
|
return ret; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ISO C does not allow extra ‘;’ outside of a function
|
||||||
|
#if defined(_NEED_ATOI)
|
||||||
|
_ATOI_IMPL(atoi, int, strtol)
|
||||||
|
#elif defined(_NEED_ATOL)
|
||||||
|
_ATOI_IMPL(atol, long, strtol)
|
||||||
|
#elif defined(_NEED_ATOU)
|
||||||
|
_ATOI_IMPL(atou, uint, strtoul)
|
||||||
|
#elif defined(_NEED_ATOUL)
|
||||||
|
_ATOI_IMPL(atoul, ulong, strtoul)
|
||||||
|
#else
|
||||||
|
#error "What am I supposed to declare?"
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Conversion utilities - itoa family //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include <kalbase.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Digits table for bases <=36 (unused)
|
||||||
|
//
|
||||||
|
#if 0
|
||||||
|
static const char digits[] =
|
||||||
|
"0123456789abcdefghijklmnopqrstuvwxyz";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Integer to string in any base between 2 and 36 (included)
|
||||||
|
//
|
||||||
|
|
||||||
|
#if defined(_NEED_ITOA)
|
||||||
|
|
||||||
|
#define _IL_MIN INT_MIN
|
||||||
|
#define _IL_MIN_STRING "-2147483648"
|
||||||
|
char *itoa(int i, char *str, int base)
|
||||||
|
{
|
||||||
|
int rem;
|
||||||
|
|
||||||
|
#elif defined(_NEED_LTOA)
|
||||||
|
|
||||||
|
#define _IL_MIN LONG_MIN
|
||||||
|
#define _IL_MIN_STRING "-9223372036854775808"
|
||||||
|
char *ltoa(long i, char *str, int base)
|
||||||
|
{
|
||||||
|
long rem;
|
||||||
|
|
||||||
|
#elif defined(_NEED_UTOA)
|
||||||
|
|
||||||
|
char *utoa(uint i, char *str, int base)
|
||||||
|
{
|
||||||
|
uint rem;
|
||||||
|
|
||||||
|
#elif defined(_NEED_ULTOA)
|
||||||
|
|
||||||
|
char *ultoa(ulong i, char *str, int base)
|
||||||
|
{
|
||||||
|
ulong rem;
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "What am I supposed to declare?"
|
||||||
|
#endif
|
||||||
|
char *orig = str;
|
||||||
|
|
||||||
|
#if defined(_NEED_ITOA) || defined(_NEED_LTOA)
|
||||||
|
//
|
||||||
|
// Deal with negatives
|
||||||
|
//
|
||||||
|
int neg = 0;
|
||||||
|
if (i < 0 && base == 10) {
|
||||||
|
//
|
||||||
|
// Handle INT_MIN and LONG_MIN...
|
||||||
|
//
|
||||||
|
if (__builtin_expect(i == _IL_MIN, 0)) {
|
||||||
|
strcpy(orig, _IL_MIN_STRING);
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
neg = 1;
|
||||||
|
i = -i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Only handle base 2 -> 36
|
||||||
|
//
|
||||||
|
if (base < 2 || base > 36) {
|
||||||
|
__set_errno(EINVAL);
|
||||||
|
*orig = '\0';
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deal with zero separately
|
||||||
|
//
|
||||||
|
if (i == 0) {
|
||||||
|
*str++ = '0';
|
||||||
|
*str = '\0';
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compute digits... in reverse order
|
||||||
|
//
|
||||||
|
while (i > 0) {
|
||||||
|
rem = i % base;
|
||||||
|
*str++ = (rem > 9)
|
||||||
|
? (rem - 10) + 'a'
|
||||||
|
: rem + '0';
|
||||||
|
i /= base;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_NEED_ITOA) || defined(_NEED_LTOA)
|
||||||
|
if (neg) *str++ = '-';
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*str = '\0';
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reverse the string
|
||||||
|
//
|
||||||
|
orig = strrev2(orig);
|
||||||
|
|
||||||
|
//
|
||||||
|
// End of conversion
|
||||||
|
//
|
||||||
|
leave:
|
||||||
|
return orig;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,245 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: mem*() functions //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include <kalbase.h>
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// memset() family //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set "bytes"-many bytes starting from ptr to val
|
||||||
|
//
|
||||||
|
void *memset(void *ptr, int val, size_t bytes)
|
||||||
|
{
|
||||||
|
uchar *uptr = (uchar *)ptr;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deal with bytes before start of the first aligned qword
|
||||||
|
//
|
||||||
|
while (((ulong)uptr % QWORD_ALIGN) > 0 && bytes--) {
|
||||||
|
*uptr++ = (uchar)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// At this point we're qword-aligned
|
||||||
|
//
|
||||||
|
if (bytes > QWORD_SIZE) {
|
||||||
|
const ulong uval = ((ulong)val << 56) | ((ulong)val << 48)
|
||||||
|
| ((ulong)val << 40) | ((ulong)val << 32)
|
||||||
|
| ((ulong)val << 24) | ((ulong)val << 16)
|
||||||
|
| ((ulong)val << 8) | ((ulong)val);
|
||||||
|
|
||||||
|
ulong *uqptr = (ulong *)ptr;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Moving fast, qword by qword
|
||||||
|
//
|
||||||
|
while (bytes > QWORD_SIZE) {
|
||||||
|
*uqptr++ = uval;
|
||||||
|
bytes -= QWORD_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uptr = (uchar *)(ulong)uqptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deal with the few remaining bytes
|
||||||
|
//
|
||||||
|
while (bytes--) *uptr++ = (uchar)val;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set "words"-many words starting from ptr to val
|
||||||
|
//
|
||||||
|
void *memsetw(void *ptr, int val, size_t words)
|
||||||
|
{
|
||||||
|
ushort *uptr = (ushort *)ptr;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check whether we can we do this an aligned way
|
||||||
|
//
|
||||||
|
if unlikely (((ulong)uptr % WORD_ALIGN) > 0) {
|
||||||
|
//
|
||||||
|
// We can't, so we write word by word all the way up
|
||||||
|
//
|
||||||
|
while (words--) *uptr++ = (ushort)val;
|
||||||
|
return uptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (((ulong)uptr % QWORD_ALIGN) > 0 && words--) {
|
||||||
|
*uptr++ = (ushort)val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (words > QWORDS_TO_WORDS(1)) {
|
||||||
|
const ulong uval = ((ulong)val << 48) | ((ulong)val << 32)
|
||||||
|
| ((ulong)val << 16) | ((ulong)val);
|
||||||
|
|
||||||
|
ulong *uqptr = (ulong *)uptr;
|
||||||
|
|
||||||
|
while (words > QWORDS_TO_WORDS(1)) {
|
||||||
|
words -= QWORDS_TO_WORDS(1);
|
||||||
|
*uqptr++ = uval;
|
||||||
|
}
|
||||||
|
|
||||||
|
uptr = (ushort *)(ulong)uqptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (words--) *uptr++ = (ushort)val;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set "dwords"-many dwords starting from ptr to val
|
||||||
|
// XXX unimplemented
|
||||||
|
//
|
||||||
|
void *memsetd(void *ptr, int val, size_t dwords)
|
||||||
|
{
|
||||||
|
(void)val;
|
||||||
|
(void)dwords;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set "qwords"-many qwords starting from ptr to val
|
||||||
|
//
|
||||||
|
void *memsetq(void *ptr, long val, size_t qwords)
|
||||||
|
{
|
||||||
|
ulong *uptr = (ulong *)ptr;
|
||||||
|
|
||||||
|
//
|
||||||
|
// There's no need to check for alignment
|
||||||
|
//
|
||||||
|
while (qwords--) *uptr++ = (ulong)val;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Other mem*() functions //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Set "bytes"-many bytes starting from ptr to 0
|
||||||
|
//
|
||||||
|
void *memzero(void *ptr, size_t bytes)
|
||||||
|
{
|
||||||
|
return memsetb(ptr, 0, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy "bytes"-many bytes of src to dst
|
||||||
|
// Does not deal with overlapping blocks (memmove's job)
|
||||||
|
//
|
||||||
|
void *memcpy(void *restrict dst, const void *restrict src, size_t bytes)
|
||||||
|
{
|
||||||
|
const ulong *usrc = (const ulong *)src;
|
||||||
|
ulong *udst = (ulong *)dst;
|
||||||
|
|
||||||
|
if unlikely (bytes == 0) return dst;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Can align both src and dst at once at once?
|
||||||
|
//
|
||||||
|
if unlikely ((ulong)src % WORD_ALIGN == 1
|
||||||
|
&& (ulong)dst % WORD_ALIGN == 1) {
|
||||||
|
const uchar *ubsrc = (const uchar *)usrc;
|
||||||
|
uchar *ubdst = (uchar *)udst;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Yes we can, we're guaranteed to be word-aligned now
|
||||||
|
//
|
||||||
|
*ubdst++ = *ubsrc++;
|
||||||
|
bytes--;
|
||||||
|
|
||||||
|
udst = (ulong *)ubdst;
|
||||||
|
usrc = (ulong *)ubsrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ushort *uwsrc = (const ushort *)usrc;
|
||||||
|
ushort *uwdst = (ushort *)udst;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Align either dst or src for qword access
|
||||||
|
//
|
||||||
|
while ((ulong)dst % QWORD_ALIGN > 0
|
||||||
|
&& (ulong)src % QWORD_ALIGN > 0
|
||||||
|
&& bytes > WORD_SIZE) {
|
||||||
|
|
||||||
|
*uwdst++ = *uwsrc++;
|
||||||
|
bytes -= WORD_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
udst = (ulong *)uwdst;
|
||||||
|
usrc = (ulong *)uwsrc;
|
||||||
|
|
||||||
|
//
|
||||||
|
// This should be most of the job
|
||||||
|
//
|
||||||
|
while (bytes > QWORD_SIZE) {
|
||||||
|
*udst++ = *usrc++;
|
||||||
|
bytes -= QWORD_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uchar *ubsrc = (const uchar *)usrc;
|
||||||
|
ushort *ubdst = (ushort *)udst;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Deal with the few bytes left
|
||||||
|
//
|
||||||
|
while (bytes--) *ubdst ++ = *ubsrc++;
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Move memory from src to dest, even if they overlap
|
||||||
|
//
|
||||||
|
void *memmove(void *dst, const void *src, size_t bytes)
|
||||||
|
{
|
||||||
|
const uchar *usrc = src;
|
||||||
|
uchar *udst = dst;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Can we use memcpy() safely?
|
||||||
|
//
|
||||||
|
if (udst < usrc) {
|
||||||
|
return memcpy(dst, src, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// No, so we go backwards
|
||||||
|
//
|
||||||
|
uchar *usrc_end = (uchar *)usrc + bytes - 1;
|
||||||
|
uchar *udst_end = udst + bytes - 1;
|
||||||
|
while (bytes--) *udst_end-- = *usrc_end--;
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compare memory areas
|
||||||
|
//
|
||||||
|
int memcmp(const void *ptr1, const void *ptr2, size_t bytes)
|
||||||
|
{
|
||||||
|
const uchar *uptr1 = ptr1;
|
||||||
|
const uchar *uptr2 = ptr2;
|
||||||
|
|
||||||
|
while (bytes--) {
|
||||||
|
if (*uptr1++ != *uptr2++) {
|
||||||
|
return uptr1[-1] < uptr2[-1] ? -1 : 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: RNG related functions //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include <kalbase.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Seed value
|
||||||
|
//
|
||||||
|
static ulong next = 7756;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Returns a pseudo-random integer
|
||||||
|
// To be improved
|
||||||
|
//
|
||||||
|
int rand(void)
|
||||||
|
{
|
||||||
|
next = next * 1103515245 + 12347;
|
||||||
|
return (uint)(next / 65536);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// (Re)Set the random seed
|
||||||
|
//
|
||||||
|
void srand(uint seed)
|
||||||
|
{
|
||||||
|
next = (ulong)seed;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: sprintf()-related functions //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include <kalbase.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Format str according to fmt using ellipsed arguments
|
||||||
|
//
|
||||||
|
// BE CAREFUL when using this
|
||||||
|
// you need to know for sure an overflow won't happen
|
||||||
|
//
|
||||||
|
int sprintf(char *str, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap);
|
||||||
|
ret = vsnprintf(str, SIZE_T_MAX, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vsprintf(char *str, const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
return vsnprintf(str, SIZE_T_MAX, fmt, ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// (v)sprintf() but with a size limit: no more than n bytes are written in str
|
||||||
|
// Always null-terminate str
|
||||||
|
//
|
||||||
|
int snprintf(char *str, size_t n, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap);
|
||||||
|
ret = vsnprintf(str, n, fmt, ap)
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Go throught the format string
|
||||||
|
//
|
||||||
|
while (*fmt) {
|
||||||
|
if (*fmt != '%') {
|
||||||
|
//
|
||||||
|
// Even if we don't have any more room we still increase ret
|
||||||
|
//
|
||||||
|
if (ret++ < n) {
|
||||||
|
*str++ = *fmt++;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*fmt) {
|
||||||
|
case 'd':
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Implementation of describe_status() //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include <kalbase.h>
|
||||||
|
|
||||||
|
error_t __errno = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
static const char *descriptions[] = {
|
||||||
|
[-SUCCESS] = "Success",
|
||||||
|
[-FAILED] = "Failed (no precision)",
|
||||||
|
[-NOT_PERMITTED] = "Operation not permitted",
|
||||||
|
[-ACCESS_DENIED] = "Access denied",
|
||||||
|
|
||||||
|
[-BAD_ARGUMENT] = "Bad argument",
|
||||||
|
[-BAD_ARG_RANGE] = "Bad argument (not in range)",
|
||||||
|
[-BAD_ARG_NULL] = "Bad argument (null pointer)",
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *describe_status(status_t status)
|
||||||
|
{
|
||||||
|
(void)descriptions;
|
||||||
|
(void)status;
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
*/
|
|
@ -0,0 +1,330 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: String-related functions //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include <kalbase.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compare two strings
|
||||||
|
//
|
||||||
|
int strcmp(const char *str1, const char *str2)
|
||||||
|
{
|
||||||
|
while (*str1 == *str2 && *str2) str1++, str2++;
|
||||||
|
|
||||||
|
return *(uchar *)str1 - *(uchar *)str2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Compare at most n bytes of two strings
|
||||||
|
//
|
||||||
|
int strncmp(const char *str1, const char *str2, size_t n)
|
||||||
|
{
|
||||||
|
size_t it = 0;
|
||||||
|
|
||||||
|
while (*str1 == *str2 && *str2 && it < n) str1++, str2++, it++;
|
||||||
|
|
||||||
|
return *(uchar *)str1 - *(uchar *)str2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return str's length
|
||||||
|
//
|
||||||
|
size_t strlen(const char *str)
|
||||||
|
{
|
||||||
|
const char *base = str;
|
||||||
|
|
||||||
|
while (*str) str++;
|
||||||
|
|
||||||
|
return str - base;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return a pointer to the first occurence of ch in str,
|
||||||
|
// or str's null-terminator if none is found
|
||||||
|
//
|
||||||
|
char *strchrnul(const char *str, int ch)
|
||||||
|
{
|
||||||
|
while ((*str && *str != (char)ch)) str++;
|
||||||
|
|
||||||
|
return (char *)str;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return a pointer to the first occurence of ch in str,
|
||||||
|
// NULL if none is found
|
||||||
|
//
|
||||||
|
char *strchr(const char *str, int ch)
|
||||||
|
{
|
||||||
|
while ((*str && *str != (char)ch)) str++;
|
||||||
|
|
||||||
|
return *str ? (char *)str : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return a point to the last occurence of ch in str,
|
||||||
|
// NULL if none is found
|
||||||
|
//
|
||||||
|
char *strrchr(const char *str, int ch)
|
||||||
|
{
|
||||||
|
char *ptr = NULL;
|
||||||
|
|
||||||
|
while (*str) {
|
||||||
|
if (*str == ch) {
|
||||||
|
ptr = (char *)str;
|
||||||
|
}
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the length of the longest inital segment of str
|
||||||
|
// that only contains characters in acc
|
||||||
|
//
|
||||||
|
size_t strspn(const char *str, const char *acc)
|
||||||
|
{
|
||||||
|
const char *ptr = str;
|
||||||
|
|
||||||
|
while (*ptr && strchr(acc, *ptr) != NULL) ptr++;
|
||||||
|
|
||||||
|
return ptr - str;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the length of the longest initial segment of str
|
||||||
|
// that does not contain any character in rej
|
||||||
|
//
|
||||||
|
size_t strcspn(const char *str, const char *rej)
|
||||||
|
{
|
||||||
|
const char *ptr = str;
|
||||||
|
|
||||||
|
while (*ptr && strchr(rej, *ptr) == NULL) ptr++;
|
||||||
|
|
||||||
|
return ptr - str;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the first occurence in str of any byte in acc
|
||||||
|
//
|
||||||
|
char *strpbrk(const char *str, const char *acc)
|
||||||
|
{
|
||||||
|
str += strcspn(str, acc);
|
||||||
|
|
||||||
|
return *str ? (char *)str : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Return the first occurence of the substring needle
|
||||||
|
// in the string haystack, NULL if none is found
|
||||||
|
// Null-terminators aren't compared
|
||||||
|
//
|
||||||
|
char *strstr(const char *haystack, const char *needle)
|
||||||
|
{
|
||||||
|
const size_t needle_size = strlen(needle);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Moves haystack to first occurence of the needle's first byte
|
||||||
|
//
|
||||||
|
while ((haystack = strchr(haystack, *needle)) != NULL) {
|
||||||
|
if (strncmp(haystack, needle, needle_size) == 0) {
|
||||||
|
return (char *)haystack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tokenize a string, using saveptr as a savestate
|
||||||
|
// We let a segmentation fault happen if *saveptr == NULL
|
||||||
|
//
|
||||||
|
char *strtok_r(char *restrict str, const char *restrict delim, char **restrict saveptr)
|
||||||
|
{
|
||||||
|
assert(*saveptr != NULL);
|
||||||
|
|
||||||
|
if (str == NULL) str = *saveptr;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Skip initial segments composed only of delimiters
|
||||||
|
//
|
||||||
|
str += strspn(str, delim);
|
||||||
|
|
||||||
|
//
|
||||||
|
// If str is empty, store it in saveptr so that next call
|
||||||
|
// still finds an empty strings and returns NULL
|
||||||
|
//
|
||||||
|
if (*str == 0) {
|
||||||
|
*saveptr = str;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *ptr = str, *tok_end = strpbrk(str, delim);
|
||||||
|
|
||||||
|
//
|
||||||
|
// If we found the last token, set *saveptr to a str's null-terminator
|
||||||
|
// Otherwise, null-terminate token and save next byte
|
||||||
|
//
|
||||||
|
|
||||||
|
if (tok_end == NULL) {
|
||||||
|
while (*ptr) ptr++;
|
||||||
|
*saveptr = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
*tok_end = 0;
|
||||||
|
*saveptr = tok_end + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tokenize a string in a very thread-unsafe way
|
||||||
|
//
|
||||||
|
char *strtok(char *restrict str, const char *restrict delim)
|
||||||
|
{
|
||||||
|
static char *saveptr = NULL;
|
||||||
|
|
||||||
|
KalAssert(FALSE);
|
||||||
|
|
||||||
|
if (str) saveptr = str;
|
||||||
|
|
||||||
|
return strtok_r(str, delim, &saveptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copy the string src into dest
|
||||||
|
//
|
||||||
|
char *strcpy(char *restrict dest, const char *restrict src)
|
||||||
|
{
|
||||||
|
char *base = dest;
|
||||||
|
|
||||||
|
while ((*dest++ = *src++));
|
||||||
|
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// strcpy() but always writes n bytes
|
||||||
|
// Will not null-terminate for strings longer than n bytes
|
||||||
|
//
|
||||||
|
char *strncpy(char *restrict dest, const char *restrict src, size_t n)
|
||||||
|
{
|
||||||
|
size_t it;
|
||||||
|
|
||||||
|
for (it = 0; it < n && src[it]; it++) {
|
||||||
|
dest[it] = src[it];
|
||||||
|
}
|
||||||
|
|
||||||
|
while (it < n) dest[it++] = 0;
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Copies at most n-1 bytes from src to dest
|
||||||
|
// Always null-terminates dest, but doesn't fill
|
||||||
|
// dest's contents past the null-terminator
|
||||||
|
//
|
||||||
|
// Returns the number of bytes written
|
||||||
|
//
|
||||||
|
size_t strnzcpy(char *restrict dest, const char *restrict src, size_t n)
|
||||||
|
{
|
||||||
|
size_t it;
|
||||||
|
|
||||||
|
for (it = 0; it < n - 1 && src[it]; it++) {
|
||||||
|
dest[it] = src[it];
|
||||||
|
}
|
||||||
|
|
||||||
|
dest[it++] = 0;
|
||||||
|
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Appends a copy of src at the end of dest
|
||||||
|
//
|
||||||
|
char *strcat(char *restrict dest, const char *restrict src)
|
||||||
|
{
|
||||||
|
char *base = dest;
|
||||||
|
while (*dest) dest++;
|
||||||
|
while ((*dest++ = *src++));
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Appends a copy of at most n bytes of src at the end of dest
|
||||||
|
//
|
||||||
|
char *strncat(char *restrict dest, const char *restrict src, size_t n)
|
||||||
|
{
|
||||||
|
size_t it, off = 0;
|
||||||
|
|
||||||
|
while (dest[off]) off++;
|
||||||
|
|
||||||
|
for (it = 0; it < n && src[it]; it++) {
|
||||||
|
dest[it+off] = src[it];
|
||||||
|
}
|
||||||
|
|
||||||
|
while (it++ < n) dest[it+off] = 0;
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Appends a copy of at most n bytes of src at the end of dest
|
||||||
|
// Always null-terminates, and returne TRUE or FALSE depending on whether
|
||||||
|
// regular strcat() would have null-terminated this string, or not
|
||||||
|
//
|
||||||
|
size_t strnzcat(char *restrict dest, const char *restrict src, size_t n)
|
||||||
|
{
|
||||||
|
size_t it, off = 0;
|
||||||
|
|
||||||
|
while (dest[off]) off++;
|
||||||
|
|
||||||
|
for (it = 0; it < n - 1 && src[it]; it++) {
|
||||||
|
dest[it+off] = src[it];
|
||||||
|
}
|
||||||
|
|
||||||
|
dest[it+off] = 0;
|
||||||
|
|
||||||
|
return it+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reverses the string src, putting the result into dest
|
||||||
|
//
|
||||||
|
char *strrev(char *restrict dest, const char *restrict src)
|
||||||
|
{
|
||||||
|
char *orig = dest;
|
||||||
|
size_t n = strlen(src);
|
||||||
|
|
||||||
|
dest[n--] = '\0';
|
||||||
|
|
||||||
|
while ((*dest++ = src[n--]));
|
||||||
|
|
||||||
|
return orig;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Reverses a string, modifying it
|
||||||
|
//
|
||||||
|
char *strrev2(char *str)
|
||||||
|
{
|
||||||
|
char ch, *orig = str;
|
||||||
|
size_t n = strlen(str);
|
||||||
|
char *temp = str + n - 1;
|
||||||
|
|
||||||
|
while (temp > str) {
|
||||||
|
ch = *temp;
|
||||||
|
*temp-- = *str;
|
||||||
|
*str++ = ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
return orig;
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: strto(u)l functions //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include <kalbase.h>
|
||||||
|
|
||||||
|
long strtol(const char *str, char **endp, int base) {
|
||||||
|
(void)str;
|
||||||
|
(void)endp;
|
||||||
|
(void)base;
|
||||||
|
__set_errno(ENOSYS);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulong strtoul(const char *str, char **endp, int base) {
|
||||||
|
(void)str;
|
||||||
|
(void)endp;
|
||||||
|
(void)base;
|
||||||
|
__set_errno(ENOSYS);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Command line parsing utilities //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include <kalbase.h>
|
||||||
|
#include <extras/prog.h>
|
||||||
|
#include <extras/argv.h>
|
||||||
|
#if 0
|
||||||
|
error_t KalCmdLineToArgV(const char *cmdLine,
|
||||||
|
int argcMax,
|
||||||
|
int *argcPtr,
|
||||||
|
const char **argv);
|
||||||
|
|
||||||
|
error_t KalArgVToCmdLine(const char *cmdLine,
|
||||||
|
size_t lengthMax,
|
||||||
|
int argc,
|
||||||
|
const char **argv);
|
||||||
|
#endif
|
|
@ -0,0 +1,48 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Program utilities //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#include <kalbase.h>
|
||||||
|
#include <extras/prog.h>
|
||||||
|
|
||||||
|
#ifdef _KALEID_KERNEL
|
||||||
|
|
||||||
|
const char *__progname = "kaleid-kernel";
|
||||||
|
const char *__progvers = "alpha-0.0.1";
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
const char *__progname = "kaleid-test";
|
||||||
|
const char *__progvers = "(n/a)";
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char *KalGetProgName(void)
|
||||||
|
{
|
||||||
|
return __progname;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *KalGetProgVersion(void)
|
||||||
|
{
|
||||||
|
return __progvers;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KalSetProgVers(const char *vers)
|
||||||
|
{
|
||||||
|
(void)vers;
|
||||||
|
__set_errno(ENOSYS);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KalSetProgName(const char *name)
|
||||||
|
{
|
||||||
|
(void)name;
|
||||||
|
__set_errno(ENOSYS);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Kaleid assert() support //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALBASE_ASSERT_H
|
||||||
|
#define _KALBASE_ASSERT_H
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Macros //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef noreturn
|
||||||
|
#define noreturn __attribute__((__noreturn__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef unlikely
|
||||||
|
#define unlikely(x) (__builtin_expect((x), 0))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef static_assert
|
||||||
|
#define static_assert _Static_assert
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// API compatibility checks //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Assert core //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Failed assert handler
|
||||||
|
//
|
||||||
|
noreturn void __assert_handler(const char *, const char *, int, const char *);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Unconditional assert
|
||||||
|
//
|
||||||
|
#define KalAlwaysAssert(x) \
|
||||||
|
do { \
|
||||||
|
if unlikely (!(x)) \
|
||||||
|
__assert_handler(#x, __FILE__, __LINE__, __func__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// When debugging //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#if !defined(_NO_DEBUG) && !defined(NDEBUG) && !defined(KalAssert)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check whether (x) holds, if not call __assert_handler
|
||||||
|
//
|
||||||
|
#define KalAssert KalAlwaysAssert
|
||||||
|
|
||||||
|
#ifndef _OSK_SOURCE
|
||||||
|
|
||||||
|
//
|
||||||
|
// When not building for OS/K, use the system's assert
|
||||||
|
//
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#undef KalAwaysAssert
|
||||||
|
#define KalAlwaysAssert assert
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// When not debugging //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
#define NDEBUG 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _NO_DEBUG
|
||||||
|
#define _NO_DEBUG 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef KalAssert
|
||||||
|
#define KalAssert(x) ((void)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Aliases and extensions //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef assert
|
||||||
|
#define assert KalAssert
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define KalAssertEx(x,m) KalAssert(x && m)
|
||||||
|
#define KalAlwaysAssertEx(x,m) KalAlwaysAssert(x && m)
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,100 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Kaleid general preprocessor constants //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALBASE_BDEFS_H
|
||||||
|
#define _KALDEFS_BDEFS_H
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Actual constants //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0L
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef INITOK
|
||||||
|
#define INITOK ((unsigned int)0xCAFEBABE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Keywords //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef __alignof_is_defined
|
||||||
|
#define __alignof_is_defined
|
||||||
|
#define alignof _Alignof
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __alignas_is_defined
|
||||||
|
#define __alignas_is_defined
|
||||||
|
#define alignas _Alignas
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __bool_true_false_are_defined
|
||||||
|
#define __bool_true_false_are_defined
|
||||||
|
# define bool _Bool
|
||||||
|
# define true 1
|
||||||
|
# define false 0
|
||||||
|
# ifndef TRUE
|
||||||
|
# define TRUE 1
|
||||||
|
# endif
|
||||||
|
# ifndef FALSE
|
||||||
|
# define FALSE 0
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Attributes and macros //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _PACKED
|
||||||
|
#define _PACKED __attribute__((__packed__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef noreturn
|
||||||
|
#define noreturn __attribute__((__noreturn__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef likely
|
||||||
|
#define likely(x) (__builtin_expect((x), 1))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef unlikely
|
||||||
|
#define unlikely(x) (__builtin_expect((x), 0))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _STR
|
||||||
|
#define _STR(x) #x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _XSTR
|
||||||
|
#define _XSTR(x) _STR(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// API specific macros //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef KALAPI
|
||||||
|
# define KALAPI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,242 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Kaleid C runtime library //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALBASE_CRTLIB_H
|
||||||
|
#define _KALBASE_CRTLIB_H
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Typedefs //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef __error_t_defined
|
||||||
|
#define __error_t_defined
|
||||||
|
typedef int error_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __size_t_defined
|
||||||
|
#define __size_t_defined
|
||||||
|
typedef unsigned long size_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __va_list_defined
|
||||||
|
#define __va_list_defined
|
||||||
|
typedef __builtin_va_list va_list;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __div_t_defined
|
||||||
|
#define __div_t_defined
|
||||||
|
typedef struct { int quot, rem; } div_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __ldiv_t_defined
|
||||||
|
#define __ldiv_t_defined
|
||||||
|
typedef struct { long quot, rem; } ldiv_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Global variables //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALEID_KERNEL
|
||||||
|
|
||||||
|
extern error_t __errno;
|
||||||
|
|
||||||
|
#ifndef errno
|
||||||
|
#define errno __errno
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __get_errno(x) error_t x = errno;
|
||||||
|
#define __set_errno(x) (errno = (x))
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define errno
|
||||||
|
#define __get_errno(x)
|
||||||
|
#define __set_errno(x)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Macros //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _NO_MASK
|
||||||
|
#define _NO_MASK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// va_list utilities //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef va_start
|
||||||
|
#define va_start __builtin_va_start
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef va_arg
|
||||||
|
#define va_arg __builtin_va_arg
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef va_copy
|
||||||
|
#define va_copy __builtin_va_copy
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef va_end
|
||||||
|
#define va_end __builtin_va_end
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Memory management utilities //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef memsetb
|
||||||
|
#define memsetb memset
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef memchrb
|
||||||
|
#define memchrb memchr
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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 *memchr(const void *, int, size_t);
|
||||||
|
void *memchrw(const void *, int, size_t);
|
||||||
|
void *memchrd(const void *, int, size_t);
|
||||||
|
void *memchrq(const 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);
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// String manipulation utilities //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
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);
|
||||||
|
size_t strnzcpy(char *restrict, const char *restrict, size_t);
|
||||||
|
|
||||||
|
char *strcat (char *restrict, const char *restrict);
|
||||||
|
char *strncat (char *restrict, const char *restrict, size_t);
|
||||||
|
size_t strnzcat(char *restrict, const char *restrict, size_t);
|
||||||
|
|
||||||
|
char *strrev(char *restrict, const char *restrict);
|
||||||
|
char *strrev2(char *);
|
||||||
|
|
||||||
|
int sprintf(char *, const char *, ...);
|
||||||
|
int snprintf(char *, size_t, const char *, ...);
|
||||||
|
int vsprintf(char *, const char *, va_list);
|
||||||
|
int vsnprintf(char *, size_t, const char *, va_list);
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Type conversion utilities //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
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 *);
|
||||||
|
unsigned int atou(const char *);
|
||||||
|
unsigned long atoul(const char *);
|
||||||
|
|
||||||
|
long strtol (const char *restrict, char **restrict, int);
|
||||||
|
unsigned long strtoul(const char *restrict, char **restrict, int);
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// RNG utilities //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
int rand(void);
|
||||||
|
void srand(unsigned int);
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Time utilities //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Diverse utilities //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
char *strerror(int);
|
||||||
|
char *strsignal(int);
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Arithmetical macros //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef __abs
|
||||||
|
#define __abs
|
||||||
|
static inline int abs(int __x)
|
||||||
|
{
|
||||||
|
return __x < 0 ? -__x : __x;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __labs
|
||||||
|
#define __labs
|
||||||
|
static inline long labs(long __x)
|
||||||
|
{
|
||||||
|
return __x < 0 ? -__x : __x;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __div
|
||||||
|
#define __div
|
||||||
|
static inline div_t div(int __x, int __y)
|
||||||
|
{
|
||||||
|
div_t __res;
|
||||||
|
__res.quot = __x/__y;
|
||||||
|
__res.rem = __x%__y;
|
||||||
|
return __res;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __ldiv
|
||||||
|
#define __ldiv
|
||||||
|
static inline ldiv_t ldiv(long __x, long __y)
|
||||||
|
{
|
||||||
|
ldiv_t __res;
|
||||||
|
__res.quot = __x/__y;
|
||||||
|
__res.rem = __x%__y;
|
||||||
|
return __res;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Values for errno_t and errno //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALBASE_ERRNO_H
|
||||||
|
#define _KALBASE_ERRNO_H
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// "errno" values //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
// Everything went fine
|
||||||
|
#define EOK 0
|
||||||
|
|
||||||
|
// Operation not permitted
|
||||||
|
#define EPERM 1
|
||||||
|
|
||||||
|
// No such file or directory
|
||||||
|
#define ENOENT 2
|
||||||
|
|
||||||
|
// No such process
|
||||||
|
#define ESRCH 3
|
||||||
|
|
||||||
|
// Syscall interrupted (e.g. by signal)
|
||||||
|
#define EINTR 4
|
||||||
|
|
||||||
|
// I/0 error
|
||||||
|
#define EIO 5
|
||||||
|
|
||||||
|
// No such device or address
|
||||||
|
#define ENXIO 6
|
||||||
|
|
||||||
|
// Argument list too long
|
||||||
|
#define E2BIG 7
|
||||||
|
|
||||||
|
// Not an executable format
|
||||||
|
#define ENOEXEC 8
|
||||||
|
|
||||||
|
// Bad file number
|
||||||
|
#define EBADF 9
|
||||||
|
|
||||||
|
// Invalid argument
|
||||||
|
#define EINVAL 22
|
||||||
|
|
||||||
|
// Functionality not implemented
|
||||||
|
#define ENOSYS 38
|
||||||
|
|
||||||
|
// Component crashed
|
||||||
|
#define ECRASH 500
|
||||||
|
|
||||||
|
// System is panicking
|
||||||
|
#define EPANIC 600
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,117 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Kaleid type limits definitions //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALBASE_LIMITS_H
|
||||||
|
#define _KALBASE_LIMITS_H
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Data sizes blocks //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef DATA_SIZE_BLOCK
|
||||||
|
#define DATA_SIZE_BLOCK
|
||||||
|
# define BYTE_SIZE sizeof(char)
|
||||||
|
# define WORD_SIZE sizeof(short)
|
||||||
|
# define DWORD_SIZE sizeof(int)
|
||||||
|
# define QWORD_SIZE sizeof(long)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DATA_ALIGN_BLOCK
|
||||||
|
#define DATA_ALIGN_BLOCK
|
||||||
|
# define BYTE_ALIGN alignof(char)
|
||||||
|
# define WORD_ALIGN alignof(short)
|
||||||
|
# define DWORD_ALIGN alignof(int)
|
||||||
|
# define QWORD_ALIGN alignof(long)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DATA_BITS_BLOCK
|
||||||
|
#define DATA_BITS_BLOCK
|
||||||
|
# define BYTE_BIT 8
|
||||||
|
# define CHAR_BIT (BYTE_SIZE * BYTE_BIT)
|
||||||
|
# define WORD_BIT (WORD_SIZE * BYTE_BIT)
|
||||||
|
# define DWORD_BIT (DWORD_SIZE * BYTE_BIT)
|
||||||
|
# define QWORD_BIT (QWORD_SIZE * BYTE_BIT)
|
||||||
|
# define SHORT_BIT WORD_BIT
|
||||||
|
# define INT_BIT DWORD_BIT
|
||||||
|
# define LONG_BIT QWORD_BIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DATA_SHIFTS_BLOCK
|
||||||
|
#define DATA_SHIFTS_BLOCK
|
||||||
|
# define BYTES_TO_WORDS(B) ((B) >> 1)
|
||||||
|
# define BYTES_TO_DWORDS(B) ((B) >> 2)
|
||||||
|
# define BYTES_TO_QWORDS(B) ((B) >> 3)
|
||||||
|
# define WORDS_TO_BYTES(W) ((W) << 1)
|
||||||
|
# define WORDS_TO_DWORDS(W) ((W) >> 1)
|
||||||
|
# define WORDS_TO_QWORDS(W) ((W) >> 2)
|
||||||
|
# define DWORDS_TO_BYTES(D) ((D) << 2)
|
||||||
|
# define DWORDS_TO_WORDS(D) ((D) << 1)
|
||||||
|
# define DWORDS_TO_QWORDS(D) ((D) >> 1)
|
||||||
|
# define QWORDS_TO_BYTES(Q) ((Q) << 3)
|
||||||
|
# define QWORDS_TO_WORDS(Q) ((Q) << 2)
|
||||||
|
# define QWORDS_TO_DWORDS(Q) ((Q) << 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Numeric data limits //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef DATA_MAX_LIMITS_BLOCK
|
||||||
|
#define DATA_MAX_LIMITS_BLOCK
|
||||||
|
# define SCHAR_MAX ((signed char) 0x7F)
|
||||||
|
# define SHRT_MAX ((short) 0x7FFF)
|
||||||
|
# define INT_MAX ((int) 0x7FFFFFFF)
|
||||||
|
# define LONG_MAX ((long) 0x7FFFFFFFFFFFFFFF)
|
||||||
|
# define UCHAR_MAX ((unsigned char) 0xFF
|
||||||
|
# define USHRT_MAX ((unsigned short) 0xFFFF)
|
||||||
|
# define UINT_MAX ((unsigned int) 0xFFFFFFFF)
|
||||||
|
# define ULONG_MAX ((unsigned long) 0xFFFFFFFFFFFFFFFF)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DATA_MIN_LIMITS_BLOCK
|
||||||
|
#define DATA_MIN_LIMITS_BLOCK
|
||||||
|
# define SCHAR_MIN ((signed char) -SCHAR_MAX - 1)
|
||||||
|
# define SHRT_MIN ((short) -SHRT_MAX - 1)
|
||||||
|
# define INT_MIN ((int) -INT_MAX - 1)
|
||||||
|
# define LONG_MIN ((long) -LONG_MAX - 1L)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DATA_CHAR_LIMITS_BLOCK
|
||||||
|
#define DATA_CHAR_LIMITS_BLOCK
|
||||||
|
# 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
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DATA_SPTYPES_LIMITS_BLOCK
|
||||||
|
#define DATA_SPTYPES_LIMITS_BLOCK
|
||||||
|
# define SSIZE_T_MIN LONG_MIN
|
||||||
|
# define SSIZE_T_MAX LONG_MAX
|
||||||
|
# define SIZE_T_MAX ULONG_MAX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NEED_MORE_USELESS_DATA
|
||||||
|
# define UCHAR_MIN ((unsigned char)0)
|
||||||
|
# define USHRT_MIN ((unsigned short)0)
|
||||||
|
# define UINT_MIN ((unsigned int)0)
|
||||||
|
# define ULONG_MIN ((unsigned long)0)
|
||||||
|
# ifdef STILL_NEED_MORE_USELESS_DATA
|
||||||
|
# error "Not enough useless data!"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,119 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Masks for the functions in the KCRL //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALBASE_MASKS_H
|
||||||
|
#define _KALBASE_MASKS_H
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#define div_t _osk_div_t
|
||||||
|
#define ldiv_t _osk_ldiv_t
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#define memset _osk_memsetb
|
||||||
|
#define memchr _osk_memchrb
|
||||||
|
|
||||||
|
#define memsetb _osk_memsetb
|
||||||
|
#define memsetw _osk_memsetw
|
||||||
|
#define memsetd _osk_memsetd
|
||||||
|
#define memsetq _osk_memsetq
|
||||||
|
|
||||||
|
#define memchr _osk_memchrb
|
||||||
|
#define memchrw _osk_memchrw
|
||||||
|
#define memchrd _osk_memchrd
|
||||||
|
#define memchrq _osk_memchrq
|
||||||
|
|
||||||
|
#define memcpy _osk_memcpy
|
||||||
|
#define memmove _osk_memmove
|
||||||
|
|
||||||
|
#define memcmp _osk_memcmp
|
||||||
|
#define memzero _osk_memzero
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#define strlen _osk_strlen
|
||||||
|
#define strspn _osk_strspn
|
||||||
|
#define strcspn _osk_strcspn
|
||||||
|
|
||||||
|
#define strcmp _osk_strcmp
|
||||||
|
#define strncmp _osk_strncmp
|
||||||
|
|
||||||
|
#define strchr _osk_strchr
|
||||||
|
#define strrchr _osk_strrchr
|
||||||
|
|
||||||
|
#define strstr _osk_strstr
|
||||||
|
#define strpbrk _osk_strpbrk
|
||||||
|
|
||||||
|
#define strtok _osk_strtok
|
||||||
|
#define strtok_r _osk_strtok_r
|
||||||
|
|
||||||
|
#define strcpy _osk_strcpy
|
||||||
|
#define strncpy _osk_strncpy
|
||||||
|
#define strnzcpy _osk_strnzcpy
|
||||||
|
|
||||||
|
#define strcat _osk_strcat
|
||||||
|
#define strncat _osk_strncat
|
||||||
|
#define strnzcat _osk_strnzcat
|
||||||
|
|
||||||
|
#define strrev _osk_strrev
|
||||||
|
#define strrev2 _osk_strrev2
|
||||||
|
|
||||||
|
#define sprintf _osk_sprintf
|
||||||
|
#define snprintf _osk_snprintf
|
||||||
|
#define vsprintf _osk_vsprintf
|
||||||
|
#define vsnprintf _osk_vsnprintf
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
|
||||||
|
#define itoa _osk_itoa
|
||||||
|
#define ltoa _osk_ltoa
|
||||||
|
#define utoa _osk_utoa
|
||||||
|
#define ultoa _osk_ultoa
|
||||||
|
|
||||||
|
#define atoi _osk_atoi
|
||||||
|
#define atol _osk_atol
|
||||||
|
#define atou _osk_atou
|
||||||
|
#define atoul _osk_atoul
|
||||||
|
|
||||||
|
#define strtol _osk_strtol
|
||||||
|
#define strtoul _osk_strtoul
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#define rand _osk_rand
|
||||||
|
#define srand _osk_srand
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#define abs _osk_abs
|
||||||
|
#define labs _osk_labs
|
||||||
|
|
||||||
|
#define min _osk_min
|
||||||
|
#define lmin _osk_lmin
|
||||||
|
|
||||||
|
#define max _osk_max
|
||||||
|
#define lmax _osk_lmax
|
||||||
|
|
||||||
|
#define __div
|
||||||
|
#define __ldiv
|
||||||
|
|
||||||
|
#define div _osk_div
|
||||||
|
#define ldiv _osk_ldiv
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#define strerror _osk_strerror
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,120 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Kaleid C common types //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALBASE_TYPES_H
|
||||||
|
#define _KALBASE_TYPES_H
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Basic integer types aliases //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef __base_types_aliases
|
||||||
|
#define __base_types_aliases
|
||||||
|
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;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Miscellaneous types //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef __size_t_defined
|
||||||
|
#define __size_t_defined
|
||||||
|
typedef unsigned long size_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __ssize_t_defined
|
||||||
|
#define __ssize_t_defined
|
||||||
|
typedef signed long ssize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __wchar_t_defined
|
||||||
|
#define __wchar_t_defined
|
||||||
|
typedef signed int wchar_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __off_t_defined
|
||||||
|
#define __off_t_defined
|
||||||
|
typedef unsigned long off_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Standard fixed-width integer types //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef __ptrdiff_t_defined
|
||||||
|
#define __ptrdiff_t_defined
|
||||||
|
typedef signed long ptrdiff_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __intptr_t_defined
|
||||||
|
#define __intptr_t_defined
|
||||||
|
typedef signed long intptr_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __uintptr_t_defined
|
||||||
|
#define __uintptr_t_defined
|
||||||
|
typedef unsigned long uintptr_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __intmax_t_defined
|
||||||
|
#define __intmax_t_defined
|
||||||
|
typedef signed long intmax_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __uintmax_t_defined
|
||||||
|
#define __uintmax_t_defined
|
||||||
|
typedef unsigned long uintmax_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Special types //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef __va_list_defined
|
||||||
|
#define __va_list_defined
|
||||||
|
typedef __builtin_va_list va_list;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __div_t_defined
|
||||||
|
#define __div_t_defined
|
||||||
|
typedef struct { int quot, rem; } div_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __ldiv_t_defined
|
||||||
|
#define __ldiv_t_defined
|
||||||
|
typedef struct { long quot, rem; } ldiv_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Kaleid-specific types //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef __error_t_defined
|
||||||
|
#define __error_t_defined
|
||||||
|
typedef int error_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __port_t_defined
|
||||||
|
#define __port_t_defined
|
||||||
|
typedef ushort port_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,126 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Command line parsing utilities //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALBASE_H
|
||||||
|
#include <kalbase.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Start of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALEXTRAS_ARGV_H
|
||||||
|
#define _KALEXTRAS_ARGV_H
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Types //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Option types
|
||||||
|
//
|
||||||
|
typedef enum {
|
||||||
|
//
|
||||||
|
// A flag option, without any more parameters
|
||||||
|
//
|
||||||
|
CMDOPT_FLAG,
|
||||||
|
|
||||||
|
//
|
||||||
|
// An option that expects a parameter
|
||||||
|
//
|
||||||
|
CMDOPT_PARAM,
|
||||||
|
|
||||||
|
} CmdOptType_t;
|
||||||
|
|
||||||
|
//
|
||||||
|
// An option for a command, e.g. "-o file" in "cc -o file"
|
||||||
|
//
|
||||||
|
typedef struct {
|
||||||
|
//
|
||||||
|
// The option's name, e.g. "help" for "--help"
|
||||||
|
// May be 0, but only if letter is not zero
|
||||||
|
//
|
||||||
|
const char *longName;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The option's letter, e.g. 'h' for '-h'
|
||||||
|
//
|
||||||
|
int letter;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The option's group, for sorting during --help
|
||||||
|
// Must be positive and < 256, or option won't shop up
|
||||||
|
// during help texts
|
||||||
|
//
|
||||||
|
int group;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The option's type, see above
|
||||||
|
//
|
||||||
|
CmdOptType_t type;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Address of the variable to put the parameter into
|
||||||
|
// Should be an int point for flag arguments, string
|
||||||
|
// pointer for parameter arguments
|
||||||
|
//
|
||||||
|
void *param;
|
||||||
|
|
||||||
|
//
|
||||||
|
// The option's help text
|
||||||
|
// If this is 0, this option is hidden
|
||||||
|
//
|
||||||
|
const char *helpText;
|
||||||
|
|
||||||
|
} CmdOption_t;
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Functions //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
int KalComputeArgC(const char *argv[]);
|
||||||
|
|
||||||
|
size_t KalComputeArgVSize(const char *argv[]);
|
||||||
|
|
||||||
|
error_t KalCmdLineToArgV(const char *cmdLine,
|
||||||
|
int *argcPtr,
|
||||||
|
const char *argv[]);
|
||||||
|
|
||||||
|
error_t KalArgVToCmdLine(const char *cmdLine,
|
||||||
|
size_t lengthMax,
|
||||||
|
int argc,
|
||||||
|
const char *argv[]);
|
||||||
|
|
||||||
|
error_t KalParseCmdLine(const char *cmdLine,
|
||||||
|
CmdOption_t *options);
|
||||||
|
|
||||||
|
error_t KalParseArgV(int argc,
|
||||||
|
const char *argv[],
|
||||||
|
CmdOption_t *options);
|
||||||
|
|
||||||
|
//
|
||||||
|
// The "Ex" variants reacts to "--help" and "--version" by themselves
|
||||||
|
//
|
||||||
|
|
||||||
|
error_t KalParseCmdLineEx(const char *cmdLine,
|
||||||
|
CmdOption_t *options,
|
||||||
|
const char *progDesc,
|
||||||
|
const char *groupDescs[]);
|
||||||
|
|
||||||
|
error_t KalParseArgVEx(int argc,
|
||||||
|
const char *argv[],
|
||||||
|
CmdOption_t *options,
|
||||||
|
const char *progDesc,
|
||||||
|
const char *groupDescs[]);
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,273 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Doubly linked lists implementation //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifdef _KALEID_KERNEL
|
||||||
|
#error "extra/list.h - Not ready for kernel compilation"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _KALBASE_H
|
||||||
|
#include <kalbase.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Start of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALEXTRAS_LIST_H
|
||||||
|
#define _KALEXTRAS_LIST_H
|
||||||
|
|
||||||
|
//
|
||||||
|
// XXX ¯\_(ツ)_/¯
|
||||||
|
//
|
||||||
|
#ifndef _STDLIB_H
|
||||||
|
void *malloc(long);
|
||||||
|
void free(void *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define AllocMemory malloc
|
||||||
|
#define FreeMemory free
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Data structures //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
typedef struct sListHead_t {
|
||||||
|
Lock_t *lock;
|
||||||
|
unsigned long length;
|
||||||
|
struct sListNode_t *first;
|
||||||
|
struct sListNode_t *last;
|
||||||
|
} ListHead_t;
|
||||||
|
|
||||||
|
typedef struct sListNode_t {
|
||||||
|
void *data;
|
||||||
|
ListHead_t *head;
|
||||||
|
struct sListNode_t *prev;
|
||||||
|
struct sListNode_t *next;
|
||||||
|
} ListNode_t;
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Functions //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create a list head with an extern lock
|
||||||
|
//
|
||||||
|
static inline ListHead_t
|
||||||
|
*CreateListHeadWithLock(Lock_t *lock)
|
||||||
|
{
|
||||||
|
ListHead_t *head = AllocMemory(sizeof(ListHead_t));
|
||||||
|
|
||||||
|
if (head == NULL) return NULL;
|
||||||
|
|
||||||
|
head->first = head->last = NULL;
|
||||||
|
head->length = 0;
|
||||||
|
|
||||||
|
head->lock = lock;
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create a liste head
|
||||||
|
//
|
||||||
|
static inline ListHead_t
|
||||||
|
*CreateListHead(void)
|
||||||
|
{
|
||||||
|
return CreateListHeadWithLock(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create a node
|
||||||
|
//
|
||||||
|
static inline ListNode_t
|
||||||
|
*CreateNode(void *data)
|
||||||
|
{
|
||||||
|
ListNode_t *node = AllocMemory(sizeof(ListNode_t));
|
||||||
|
|
||||||
|
if (node == NULL) return NULL;
|
||||||
|
|
||||||
|
node->data = data;
|
||||||
|
node->head = NULL;
|
||||||
|
node->prev = node->next = NULL;
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Prepend node at beginning of list
|
||||||
|
//
|
||||||
|
static inline ListHead_t
|
||||||
|
*PrependNode(ListHead_t *head, ListNode_t *node)
|
||||||
|
{
|
||||||
|
KalAssert(head && node);
|
||||||
|
|
||||||
|
node->head = head;
|
||||||
|
node->prev = NULL;
|
||||||
|
|
||||||
|
if (head->length > 0) {
|
||||||
|
node->next = head->first;
|
||||||
|
head->first->prev = node;
|
||||||
|
head->first = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
head->first = node;
|
||||||
|
head->last = node;
|
||||||
|
node->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
head->length++;
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Append node at end of list
|
||||||
|
//
|
||||||
|
static inline ListHead_t
|
||||||
|
*AppendNode(ListHead_t *head, ListNode_t *node)
|
||||||
|
{
|
||||||
|
KalAssert(head && node);
|
||||||
|
|
||||||
|
node->head = head;
|
||||||
|
node->next = NULL;
|
||||||
|
|
||||||
|
if (head->length > 0) {
|
||||||
|
node->prev = head->last;
|
||||||
|
head->last->next = node;
|
||||||
|
head->last = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
head->first = node;
|
||||||
|
head->last = node;
|
||||||
|
node->prev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
head->length++;
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Insert node2 before node1
|
||||||
|
//
|
||||||
|
static inline ListHead_t
|
||||||
|
*AddNodeBefore(ListHead_t *head, ListNode_t *node1, ListNode_t *node2)
|
||||||
|
{
|
||||||
|
KalAssert(head && node1 && node2 && node1->head == head);
|
||||||
|
|
||||||
|
if (head->first == node1) {
|
||||||
|
return PrependNode(head, node2);
|
||||||
|
}
|
||||||
|
|
||||||
|
node2->head = head;
|
||||||
|
node2->next = node1;
|
||||||
|
node2->prev = node1->prev;
|
||||||
|
|
||||||
|
// node1->prev does exist
|
||||||
|
// or node1 would be first
|
||||||
|
node1->prev->next = node2;
|
||||||
|
node1->prev = node2;
|
||||||
|
|
||||||
|
head->length++;
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Insert node2 after node1
|
||||||
|
//
|
||||||
|
static inline ListHead_t
|
||||||
|
*AddNodeAfter(ListHead_t *head, ListNode_t *node1, ListNode_t *node2)
|
||||||
|
{
|
||||||
|
KalAssert(head && node1 && node2 && node1->head == head);
|
||||||
|
|
||||||
|
if (head->last == node1) {
|
||||||
|
return AppendNode(head, node2);
|
||||||
|
}
|
||||||
|
|
||||||
|
node2->head = head;
|
||||||
|
node2->prev = node1;
|
||||||
|
node2->next = node1->next;
|
||||||
|
|
||||||
|
node1->next->prev = node2;
|
||||||
|
node1->next = node2;
|
||||||
|
|
||||||
|
head->length++;
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Remove node of list (and frees it)
|
||||||
|
//
|
||||||
|
static inline ListHead_t
|
||||||
|
*RemoveNode(ListHead_t *head, ListNode_t *node)
|
||||||
|
{
|
||||||
|
KalAssert(head && node && head->length > 0 && node->head == head);
|
||||||
|
|
||||||
|
if (head->length == 1) {
|
||||||
|
head->first = head->last = NULL;
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (head->first == node) {
|
||||||
|
head->first = node->next;
|
||||||
|
node->next->prev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (head->last == node) {
|
||||||
|
head->last = node->prev;
|
||||||
|
node->prev->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
node->prev->next = node->next;
|
||||||
|
node->next->prev = node->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
leave:
|
||||||
|
head->length--;
|
||||||
|
FreeMemory(node);
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Free a node
|
||||||
|
//
|
||||||
|
static inline void
|
||||||
|
DestroyNode(ListNode_t *node)
|
||||||
|
{
|
||||||
|
KalAssert(node);
|
||||||
|
FreeMemory(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Free a list head
|
||||||
|
//
|
||||||
|
static inline void
|
||||||
|
DestroyListHead(ListHead_t *head)
|
||||||
|
{
|
||||||
|
KalAssert(head);
|
||||||
|
FreeMemory(head);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Access a node's data
|
||||||
|
//
|
||||||
|
#define GetNodeData(node, type) ((type)(node)->data)
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Spinlocks and mutexes //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALBASE_H
|
||||||
|
#include <kalbase.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _KALEID_KERNEL
|
||||||
|
#ifndef _KALKERN_BASE_H
|
||||||
|
#include <kernel/base.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Start of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALEXTRAS_LOCKS_H
|
||||||
|
#define _KALEXTRAS_LOCKS_H
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Types //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
typedef enum eLockType_t {
|
||||||
|
//
|
||||||
|
// Mutex-type lock
|
||||||
|
//
|
||||||
|
// WARNING
|
||||||
|
// AquireLock() panics when used on a mutex while not running a process
|
||||||
|
//
|
||||||
|
KLOCK_MUTEX,
|
||||||
|
|
||||||
|
//
|
||||||
|
// Spinlock-type lock
|
||||||
|
//
|
||||||
|
KLOCK_SPINLOCK,
|
||||||
|
|
||||||
|
} LockType_t;
|
||||||
|
|
||||||
|
//
|
||||||
|
// "volatile" may not be actually needed
|
||||||
|
//
|
||||||
|
typedef struct sLock_t {
|
||||||
|
unsigned int initDone; // initialized?
|
||||||
|
int locked; // is locked?
|
||||||
|
LockType_t type; // lock type?
|
||||||
|
#ifdef _KALEID_KERNEL
|
||||||
|
Thread_t *ownerThread; // unused
|
||||||
|
Thread_t *waitingThread; // unused
|
||||||
|
#endif
|
||||||
|
} volatile Lock_t;
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Functions //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Linux syscall vs unimplemented syscall...
|
||||||
|
//
|
||||||
|
#ifndef _KALEID_KERNEL
|
||||||
|
#ifdef _OSK_SOURCE
|
||||||
|
int KalYieldCPU(void),
|
||||||
|
#else
|
||||||
|
int sched_yield(void);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize a lock
|
||||||
|
//
|
||||||
|
static inline
|
||||||
|
void InitLock(Lock_t *lock, LockType_t type)
|
||||||
|
{
|
||||||
|
lock->type = type;
|
||||||
|
lock->locked = FALSE;
|
||||||
|
lock->initDone = INITOK;
|
||||||
|
#ifdef _KALEID_KERNEL
|
||||||
|
lock->ownerThread = NULL;
|
||||||
|
lock->waitingThread = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Alternative way to initalize a lock
|
||||||
|
//
|
||||||
|
#ifdef _KALEID_KERNEL
|
||||||
|
# define INITLOCK(type) { INITOK, FALSE, (type), NULL, NULL }
|
||||||
|
#else
|
||||||
|
# define INITLOCK(type) { INITOK, FALSE, (type) }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Destroy a lock
|
||||||
|
//
|
||||||
|
static inline
|
||||||
|
void DestroyLock(Lock_t *lock)
|
||||||
|
{
|
||||||
|
KalAssert(lock->initDone);
|
||||||
|
|
||||||
|
__sync_synchronize();
|
||||||
|
lock->initDone = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Aquire the lock
|
||||||
|
// Panic on double aquisition since that should never happen
|
||||||
|
// until we have at least a basic scheduler
|
||||||
|
//
|
||||||
|
static inline
|
||||||
|
void AquireLock(Lock_t *lock)
|
||||||
|
{
|
||||||
|
KalAssert(lock->initDone == INITOK);
|
||||||
|
|
||||||
|
while (!__sync_bool_compare_and_swap(&lock->locked, 0, 1)) {
|
||||||
|
#ifdef _KALEID_KERNEL
|
||||||
|
StartPanic("AquireLock on an already locked object");
|
||||||
|
#else
|
||||||
|
if likely (lock->type == KLOCK_SPINLOCK) continue;
|
||||||
|
#ifdef _OSK_SOURCE
|
||||||
|
else KalYieldCPU();
|
||||||
|
#else
|
||||||
|
else sched_yield();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
__sync_synchronize();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Release an already aquired lock
|
||||||
|
// Panic if the lock was never aquired
|
||||||
|
//
|
||||||
|
static inline
|
||||||
|
void ReleaseLock(Lock_t *lock)
|
||||||
|
{
|
||||||
|
#ifdef _KALEID_KERNEL
|
||||||
|
KalAssert(lock->ownerThread == GetCurThread());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__sync_synchronize();
|
||||||
|
lock->locked = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Tries to aquire lock
|
||||||
|
//
|
||||||
|
static inline
|
||||||
|
bool AttemptLock(Lock_t *lock)
|
||||||
|
{
|
||||||
|
KalAssert(lock->initDone == INITOK);
|
||||||
|
|
||||||
|
bool retval = __sync_bool_compare_and_swap(&lock->locked, 0, 1);
|
||||||
|
|
||||||
|
__sync_synchronize();
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,42 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Program utilities //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALBASE_H
|
||||||
|
#include <kalbase.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Start of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALEXTRAS_PROG_H
|
||||||
|
#define _KALEXTRAS_PROG_H
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Constants //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
extern const char *__progname;
|
||||||
|
extern const char *__progvers;
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Functions //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
const char *KalGetProgName(void);
|
||||||
|
const char *KalGetProgVersion(void);
|
||||||
|
|
||||||
|
bool KalSetProgVers(const char *);
|
||||||
|
bool KalSetProgName(const char *);
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,61 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Kaleid API base minimal include file //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALBASE_H
|
||||||
|
#define _KALBASE_H
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Building for OS/K //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#if !defined(_OSK_SOURCE)
|
||||||
|
# if defined(_KALEID_KERNEL) || defined(_KALEID_SYSTEM)
|
||||||
|
# define _OSK_SOURCE 1
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(_OSK_SOURCE) && !defined(_KALEID_UNMASKED)
|
||||||
|
#ifndef _KALBASE_MASKS_H
|
||||||
|
#include <base/masks.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Include common part of API //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALBASE_BDEFS_H
|
||||||
|
#include <base/bdefs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _KALBASE_ERRNO_H
|
||||||
|
#include <base/errno.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _KALBASE_TYPES_H
|
||||||
|
#include <base/types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _KALBASE_LIMITS_H
|
||||||
|
#include <base/limits.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _KALBASE_ASSERT_H
|
||||||
|
#include <base/assert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _KALBASE_CRTLIB_H
|
||||||
|
#include <base/crtlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,48 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Kaleid extras main include file //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALBASE_H
|
||||||
|
#include <kalbase.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Start of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALEXT_H
|
||||||
|
#define _KALEXT_H
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Extra headers //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALEXTRAS_LOCKS_H
|
||||||
|
#include <extras/locks.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _KALEXTRAS_PROG_H
|
||||||
|
#include <extras/prog.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _KALEXTRAS_ARGV_H
|
||||||
|
#include <extras/argv.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _KALEID_KERNEL
|
||||||
|
#ifndef _KALEXTRAS_LIST_H
|
||||||
|
#include <extras/list.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,199 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Kaleid Kernel base types and functionalities //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALBASE_H
|
||||||
|
#include <kalbase.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Start of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALKERN_BASE_H
|
||||||
|
#define _KALKERN_BASE_H
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Elementary types //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
typedef struct sLock_t volatile Lock_t;
|
||||||
|
typedef struct sThread_t Thread_t;
|
||||||
|
typedef struct sProcess_t Process_t;
|
||||||
|
typedef struct sTerminal_t Terminal_t;
|
||||||
|
typedef struct sListHead_t ListHead_t;
|
||||||
|
typedef struct sListNode_t ListNode_t;
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Values for __kstate //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Current state of the kernel
|
||||||
|
//
|
||||||
|
typedef enum {
|
||||||
|
// the kernel is booting
|
||||||
|
KSTATE_INIT,
|
||||||
|
|
||||||
|
// the kernel is not running a process
|
||||||
|
KSTATE_KERNEL,
|
||||||
|
|
||||||
|
// a process is running in kernel mode
|
||||||
|
KSTATE_PROCESS,
|
||||||
|
|
||||||
|
// the kernel is panicking
|
||||||
|
KSTATE_PANIC,
|
||||||
|
|
||||||
|
} KernelState_t;
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Multiprocessor misc. //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef INITOK
|
||||||
|
#define INITOK ((unsigned int)0xCAFEBABE)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NCPUS
|
||||||
|
#define NCPUS 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GetCurCPU() 0
|
||||||
|
|
||||||
|
//
|
||||||
|
// Declare an (extern) CPU-local variable
|
||||||
|
//
|
||||||
|
#define __DECLARE_PER_CPU(_X, _Tp, _Qual) \
|
||||||
|
_Qual _Tp __ ## _X [NCPUS]; \
|
||||||
|
static inline _Tp Get ## _X (void) \
|
||||||
|
{ return __ ## _X [GetCurCPU()]; } \
|
||||||
|
static inline void _Set ## _X (_Tp _Y) \
|
||||||
|
{ (__ ## _X [GetCurCPU()] = _Y); }
|
||||||
|
|
||||||
|
#define DECLARE_PER_CPU(_X, _Tp) \
|
||||||
|
__DECLARE_PER_CPU(_X, _Tp, extern)
|
||||||
|
|
||||||
|
#define LOCAL_DEC_PER_CPU(_X, _Tp) \
|
||||||
|
__DECLARE_PER_CPU(_X, _Tp, static)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Actually creates a CPU-local variable
|
||||||
|
//
|
||||||
|
#define CREATE_PER_CPU(_X, _Tp) \
|
||||||
|
_Tp __ ## _X [NCPUS] = { (_Tp) 0 }
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Global constants //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
// XXX
|
||||||
|
DECLARE_PER_CPU(PanicStr, const char *);
|
||||||
|
|
||||||
|
DECLARE_PER_CPU(KernState, KernelState_t);
|
||||||
|
|
||||||
|
DECLARE_PER_CPU(_StdOut, Terminal_t *);
|
||||||
|
DECLARE_PER_CPU(_StdDbg, Terminal_t *);
|
||||||
|
|
||||||
|
DECLARE_PER_CPU(CurProc, Process_t *);
|
||||||
|
DECLARE_PER_CPU(CurThread, Thread_t *);
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Macros for manipulating said //
|
||||||
|
// global constants //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#define SetKernState(x) \
|
||||||
|
do { \
|
||||||
|
_SetKernState(x); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define GetStdOut() (GetCurProc() == NULL ? Get_StdOut() : NULL)
|
||||||
|
#define SetStdOut(tm) \
|
||||||
|
do { \
|
||||||
|
if (GetCurProc() == NULL) \
|
||||||
|
_Set_StdOut(tm); \
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
#define GetStdDbg() (GetCurProc() == NULL ? Get_StdDbg() : NULL)
|
||||||
|
#define SetStdDbg(tm) \
|
||||||
|
do { \
|
||||||
|
if (GetCurProc() == NULL) \
|
||||||
|
_Set_StdDbg(tm); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Other Macros //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Size of a tabulation in spaces
|
||||||
|
// Default: 4 spaces/tab
|
||||||
|
//
|
||||||
|
#define KTABSIZE 4
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disable IRQs
|
||||||
|
//
|
||||||
|
#define DisableIRQs() asm volatile ("cli")
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enable IRQs
|
||||||
|
//
|
||||||
|
#define EnableIRQs() asm volatile ("sti")
|
||||||
|
|
||||||
|
//
|
||||||
|
// Pause CPU until next interuption
|
||||||
|
// !!! Enables IRQs !!!
|
||||||
|
//
|
||||||
|
#define PauseCPU() asm volatile("sti\n\thlt")
|
||||||
|
|
||||||
|
//
|
||||||
|
// Halt the CPU indefinitely
|
||||||
|
//
|
||||||
|
#define HaltCPU() do { asm volatile ("hlt"); } while (1)
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Some base functions //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
noreturn void StartPanic(const char *);
|
||||||
|
noreturn void CrashSystem(void);
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Useful I/O inlines //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
static inline
|
||||||
|
void WriteByteOnPort(port_t port, port_t val)
|
||||||
|
{
|
||||||
|
asm volatile ("out %0, %1" : : "dN" (port), "a" (val));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
uchar ReadByteFromPort(port_t port)
|
||||||
|
{
|
||||||
|
KalAssert(FALSE && ENOSYS);
|
||||||
|
(void)port;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
ushort ReadWordFromPort(port_t port)
|
||||||
|
{
|
||||||
|
KalAssert(FALSE && ENOSYS);
|
||||||
|
(void)port;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Scheduler header //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALKERN_BASE_H
|
||||||
|
#include <kernel/base.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Start of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALKERN_SCHED_H
|
||||||
|
#define _KALKERN_SCHED_H
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Preprocessor //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
//
|
||||||
|
// Debug stuff
|
||||||
|
//
|
||||||
|
#define printdbg printf
|
||||||
|
|
||||||
|
//
|
||||||
|
// States for a process
|
||||||
|
//
|
||||||
|
#define STATE_RUNNING 0
|
||||||
|
#define STATE_RUNNABLE 1
|
||||||
|
#define STATE_BLOCKED 2
|
||||||
|
|
||||||
|
//
|
||||||
|
// Time in ticks a process should be run
|
||||||
|
//
|
||||||
|
#define DEF_PROC_TSLICE 5 // 20 ticks
|
||||||
|
#define TCR_PROC_TSLICE 20000 // 20000 ticks (time critical)
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// List heads //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
DECLARE_PER_CPU(IdlePrioProcs, ListHead_t *);
|
||||||
|
DECLARE_PER_CPU(ReglPrioProcs, ListHead_t *);
|
||||||
|
DECLARE_PER_CPU(ServPrioProcs, ListHead_t *);
|
||||||
|
DECLARE_PER_CPU(TimeCritProcs, ListHead_t *);
|
||||||
|
|
||||||
|
extern const char *PrioClassesNames[];
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Data types //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
//
|
||||||
|
// A process
|
||||||
|
//
|
||||||
|
typedef struct sProcess_t {
|
||||||
|
|
||||||
|
// Identifier
|
||||||
|
int pid;
|
||||||
|
|
||||||
|
// Current priority class
|
||||||
|
int prioClass;
|
||||||
|
|
||||||
|
// Default priority class (without boosts)
|
||||||
|
int defPrioClass;
|
||||||
|
|
||||||
|
// Current priority level
|
||||||
|
int prioLevel;
|
||||||
|
|
||||||
|
// Default priority level
|
||||||
|
int defPrioLevel;
|
||||||
|
|
||||||
|
// Current state
|
||||||
|
int procState;
|
||||||
|
|
||||||
|
// Remaining time running
|
||||||
|
ulong timeSlice;
|
||||||
|
|
||||||
|
// Default time-slice
|
||||||
|
ulong defTimeSlice;
|
||||||
|
|
||||||
|
// Scheduler internals
|
||||||
|
ListNode_t *schedNode;
|
||||||
|
|
||||||
|
} Process_t;
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Functions //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
void SchedInit(void);
|
||||||
|
void SchedFini(void);
|
||||||
|
|
||||||
|
void SchedThisProc(Process_t *);
|
||||||
|
void SchedOnTick(void);
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
// GNU GPL OS/K //
|
||||||
|
// //
|
||||||
|
// Authors: spectral` //
|
||||||
|
// NeoX //
|
||||||
|
// //
|
||||||
|
// Desc: Terminal functions //
|
||||||
|
//----------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALKERN_BASE_H
|
||||||
|
#include <kernel/base.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Start of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _KALKERN_TERMINAL_H
|
||||||
|
#define _KALKERN_TERMINAL_H
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Types //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
//
|
||||||
|
// The VGA colors
|
||||||
|
//
|
||||||
|
typedef enum {
|
||||||
|
KTERM_COLOR_BLACK, KTERM_COLOR_BLUE,
|
||||||
|
KTERM_COLOR_GREEN, KTERM_COLOR_CYAN,
|
||||||
|
KTERM_COLOR_RED, KTERM_COLOR_MAGENTA,
|
||||||
|
KTERM_COLOR_BROWN, KTERM_COLOR_LGREY,
|
||||||
|
KTERM_COLOR_DARK_GREY, KTERM_COLOR_LBLUE,
|
||||||
|
KTERM_COLOR_LGREEN, KTERM_COLOR_LCYAN,
|
||||||
|
KTERM_COLOR_LRED, KTERM_COLOR_LMAGENTA,
|
||||||
|
KTERM_COLOR_LBROWN, KTERM_COLOR_WHITE
|
||||||
|
} TermColor_t;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Terminal structure, right now VGA and output only
|
||||||
|
//
|
||||||
|
typedef struct sTerminal_t {
|
||||||
|
|
||||||
|
uint initDone;
|
||||||
|
Lock_t lock;
|
||||||
|
|
||||||
|
const char *name;
|
||||||
|
const char *type;
|
||||||
|
|
||||||
|
void *data;
|
||||||
|
|
||||||
|
size_t width;
|
||||||
|
size_t height;
|
||||||
|
off_t currentX;
|
||||||
|
off_t currentY;
|
||||||
|
|
||||||
|
uint tabSize;
|
||||||
|
TermColor_t fgColor;
|
||||||
|
TermColor_t bgColor;
|
||||||
|
|
||||||
|
error_t (*ClearTermUnlocked)(Terminal_t *);
|
||||||
|
error_t (*PutOnTermUnlocked)(Terminal_t *, char);
|
||||||
|
error_t (*PrintOnTermUnlocked)(Terminal_t *, const char *);
|
||||||
|
|
||||||
|
} Terminal_t;
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Functions //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
void InitTerms(void);
|
||||||
|
error_t ClearTerm(Terminal_t *);
|
||||||
|
error_t PutOnTerm(Terminal_t *, char);
|
||||||
|
error_t PrintOnTerm(Terminal_t *, const char *);
|
||||||
|
error_t ChTermColor(Terminal_t *, TermColor_t, TermColor_t);
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// Macros //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#ifndef _NO_DEBUG
|
||||||
|
# define DebugLog(...) PrintOnTerm(GetStdDbg(), __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
# define DebugLog(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------------------------------------//
|
||||||
|
// End of header //
|
||||||
|
//------------------------------------------//
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue