diff --git a/.gitignore b/.gitignore
index 49d6ef7..9fd0621 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,7 +23,7 @@ multiboot.pdf
grub.log
Makefile.out.2
build/bin/s**
-.stylehlp
+#.stylehlp
# Linker output
*.ilk
diff --git a/kaleid/crtlib/arith.c b/.stylehlp
similarity index 84%
rename from kaleid/crtlib/arith.c
rename to .stylehlp
index 150c37b..588d391 100644
--- a/kaleid/crtlib/arith.c
+++ b/.stylehlp
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------//
// GNU GPL OS/K //
// //
-// Desc: Arithmetic functions //
+// Desc: //
// //
// //
// Copyright © 2018-2019 The OS/K Team //
@@ -22,27 +22,5 @@
// along with OS/K. If not, see . //
//----------------------------------------------------------------------------//
-// do not mask anything
-#define _KALEID_UNMASKED
-#include
-
-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);
-}
+//------------------------------------------//
diff --git a/Makefile.in b/Makefile.in
index a791b0a..8e4c573 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -30,7 +30,7 @@
CCNAME="/opt/cross-cc/bin/x86_64-elf-gcc"
CC2NAME=gcc
COPTIM=-O2
-CWARNS=-Wall -Wextra -Werror=implicit-function-declaration
+CWARNS=-Wall -Wextra // -Werror=implicit-function-declaration
CINCLUDES=-Ikaleid/include
CFLAGS1=-nostdlib -ffreestanding -mcmodel=large // -std=gnu11
@@ -63,10 +63,10 @@ testing: bootloader pseudo_kern
COBJDIR=$(OBJDIR)/$(COMMDIR)
LOBJDIR=$(OBJDIR)/$(LINXDIR)
-COMMOBJS=COBJ6(string, status, rand, memory, arith, strtol) COBJ4(itoa, ltoa, utoa, ultoa) COBJ4(atoi, atol, atou, atoul) COBJ2(../extras/prog, ../extras/argv)
+COMMOBJS=COBJ6(string, status, rand, memory, strtol, sprintf) COBJ4(itoa, ltoa, utoa, ultoa) COBJ4(atoi, atol, atou, atoul) COBJ3(../extras/prog, ../extras/argv, ctype)
TCC=$(CC2NAME) $(COPTIM) $(CWARNS) $(CINCLUDES)
-KCC=$(CC) -D_KALEID_KERNEL
+KCC=$(CC) -D_OSK_SOURCE -D_KALEID_KERNEL
comm-convert:
COMPILE_CONVRT1(itoa) -D_NEED_ITOA
@@ -80,11 +80,12 @@ comm-convert:
common: comm-convert
COMPILE_COMMON(rand)
- COMPILE_COMMON(arith)
+ COMPILE_COMMON(ctype)
COMPILE_COMMON(string)
COMPILE_COMMON(status)
COMPILE_COMMON(memory) -fno-strict-aliasing
COMPILE_COMMON(strtol)
+ COMPILE_COMMON(sprintf)
COMPILE_COMMON(../extras/prog)
COMPILE_COMMON(../extras/argv)
diff --git a/kaleid/crtlib/ctype.c b/kaleid/crtlib/ctype.c
new file mode 100644
index 0000000..f35fcc3
--- /dev/null
+++ b/kaleid/crtlib/ctype.c
@@ -0,0 +1,74 @@
+//----------------------------------------------------------------------------//
+// GNU GPL OS/K //
+// //
+// Desc: Character types //
+// //
+// //
+// Copyright © 2018-2019 The OS/K Team //
+// //
+// This file is part of OS/K. //
+// //
+// OS/K is free software: you can redistribute it and/or modify //
+// it under the terms of the GNU General Public License as published by //
+// the Free Software Foundation, either version 3 of the License, or //
+// any later version. //
+// //
+// OS/K is distributed in the hope that it will be useful, //
+// but WITHOUT ANY WARRANTY//without even the implied warranty of //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
+// GNU General Public License for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with OS/K. If not, see . //
+//----------------------------------------------------------------------------//
+
+#include
+
+#define SH(x) (1 << x)
+
+enum
+{
+ CT = SH(0), // control
+ PR = SH(1), // printing
+ GR = SH(2)|PR, // graphical
+ DX = SH(3)|GR, // hex digit
+ DG = SH(4)|DX, // decimal digit
+ SP = SH(5), // space
+ BK = SH(6)|SP, // blank
+ PT = SH(7)|GR, // punctuation
+ AL = SH(8)|GR, // alpha
+ UP = SH(9)|AL, // upper alpha
+ LW = SH(10)|AL // lower alpha
+};
+
+int __ctype[] = {
+ // ASCII ctype table
+ /* 0 */ CT, CT, CT, CT, CT, CT, CT, CT, CT, BK|CT,
+ /* 10 */ SP|CT, SP|CT, SP|CT, SP|CT, CT, CT, CT, CT, CT, CT,
+ /* 20 */ CT, CT, CT, CT, CT, CT, CT, CT, CT, CT,
+ /* 30 */ CT, CT, BK|PR, PT, PT, PT, PT, PT, PT, PT,
+ /* 40 */ PT, PT, PT, PT, PT, PT, PT, PT, DG, DG,
+ /* 50 */ DG, DG, DG, DG, DG, DG, DG, DG, PT, PT,
+ /* 60 */ PT, PT, PT, PT, PT, UP|DX, UP|DX, UP|DX, UP|DX, UP|DX,
+ /* 70 */ UP|DX, UP, UP, UP, UP, UP, UP, UP, UP, UP,
+ /* 80 */ UP, UP, UP, UP, UP, UP, UP, UP, UP, UP,
+ /* 90 */ UP, PT, PT, PT, PT, PT, PT, LW|DX, LW|DX, LW|DX,
+ /* 100 */ LW|DX, LW|DX, LW|DX, LW, LW, LW, LW, LW, LW, LW,
+ /* 110 */ LW, LW, LW, LW, LW, LW, LW, LW, LW, LW,
+ /* 120 */ LW, LW, LW, PT, PT, PT, PT, CT,
+};
+
+static_assert(sizeof(__ctype) == 128 * sizeof(int), "ctype table - invalid size");
+
+int tolower(int c)
+{
+ if (isupper(c)) return c + ('a' - 'A');
+ return c;
+}
+
+int toupper(int c)
+{
+ if (islower(c)) return c - ('a' - 'A');
+ return c;
+}
+
diff --git a/kaleid/crtlib/itoa.c b/kaleid/crtlib/itoa.c
index 67572e1..95c1bd7 100644
--- a/kaleid/crtlib/itoa.c
+++ b/kaleid/crtlib/itoa.c
@@ -17,6 +17,7 @@ static const char digits[] =
//
// Integer to string in any base between 2 and 36 (included)
+// Returns str
//
#if defined(_NEED_ITOA)
diff --git a/kaleid/crtlib/sprintf.c b/kaleid/crtlib/sprintf.c
index f0e5e5e..5613434 100644
--- a/kaleid/crtlib/sprintf.c
+++ b/kaleid/crtlib/sprintf.c
@@ -22,27 +22,34 @@
// along with OS/K. If not, see . //
//----------------------------------------------------------------------------//
+//
+// TODO integer modifiers
+//
+
#include
//
// Format str according to fmt using ellipsed arguments
//
-// BE CAREFUL when using this
-// you need to know for sure an overflow won't happen
+// Standard is dumb so we won't follow it:
+// 1) we return a size_t instead of int
+// 2) for (v)snprintf we return the number of characters written
+// instead of the number of characters that would have been written
+// given large enough n
//
-int sprintf(char *str, const char *fmt, ...)
+size_t sprintf(char *str, const char *fmt, ...)
{
int ret;
va_list ap;
- va_start(ap);
+ va_start(ap, fmt);
ret = vsnprintf(str, SIZE_T_MAX, fmt, ap);
va_end(ap);
return ret;
}
-int vsprintf(char *str, const char *fmt, va_list ap)
+size_t vsprintf(char *str, const char *fmt, va_list ap)
{
return vsnprintf(str, SIZE_T_MAX, fmt, ap);
}
@@ -51,40 +58,188 @@ int vsprintf(char *str, const char *fmt, va_list 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, ...)
+size_t snprintf(char *str, size_t n, const char *fmt, ...)
{
int ret;
va_list ap;
- va_start(ap);
- ret = vsnprintf(str, n, fmt, ap)
+ va_start(ap, fmt);
+ 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;
+// Size of the buffer is for convertions
+#define CONVBUF 4096
- // Go throught the format string
- while (*fmt) {
+size_t vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
+{
+ size_t ret = 0;
+ bool lflag = 0, hflag = 0, hhflag = 0, altflag = 0;
+
+ int base;
+ char mod;
+ char convbuf[CONVBUF] = { 0 };
+
+ char c;
+ int d;
+ uint u;
+ char *s;
+
+ // For aesthetic reasons...
+ n--;
+
+ // Go through the format string
+ while (*fmt && ret < n) {
+
+ // Regular character
if (*fmt != '%') {
- // Even if we don't have any more room we still increase ret
- if (ret++ < n) {
- *str++ = *fmt++;
- }
+ *str++ = *fmt++;
+ ret++;
continue;
}
- switch (*fmt) {
- case 'd':
- default:
+ // Found a '%'
+ while (1) {
+ mod = *++fmt;
+
+ if (mod == '%') {
+ *str++ = '%';
+ ret++;
+ break;
+ }
+
+ if (mod == '#') {
+ altflag = 1;
+ continue;
+ }
+
+ if (mod == 'l' || mod == 'z' || mod == 't') {
+ // 'll'/'z'/'t' aliased to 'l'
+ lflag = 1;
+ continue;
+ }
+
+ if (mod == 'h') {
+ if (hflag) hhflag = 1;
+ else hflag = 1;
+ continue;
+ }
+
+ if (mod == 'c') {
+ c = (char)va_arg(ap, int);
+ *str++ = c;
+ ret++;
+ break;
+ }
+
+ if (mod == 's') {
+ s = va_arg(ap, char *);
+
+ while (*s && ret < n) {
+ *str++ = *s++;
+ ret++;
+ }
+
+ break;
+ }
+
+ if (mod == 'i') {
+ mod = 'd';
+ goto numeric;
+ }
+
+ if (mod == 'p') {
+ mod = 'x';
+ lflag = 1;
+ altflag = 1;
+ goto numeric;
+ }
+
+ if (mod == 'd' || mod == 'u' || mod == 'b' ||
+ mod == 'o' || mod == 'x' || mod == 'X') {
+
+ // Label to avoid some useless tests
+ numeric:
+
+ if (altflag && mod != 'd' && mod != 'u') {
+ // #d / #u is undefined behaviour
+
+ *str++ = '0';
+ if (++ret >= n) break;
+
+ if (mod != 'o') {
+ *str++ = mod;
+ ret++;
+ }
+ }
+
+ // "%d" is a special snowflake, deal with it separately
+ if (mod == 'd') {
+ if (lflag) {
+ ltoa(va_arg(ap, long), convbuf, 10);
+ }
+
+ else {
+ d = va_arg(ap, int);
+ if (hhflag) d &= 0xff; // char-ify
+ else if (hflag) d &= 0xffff; // short-ify
+ itoa(d, convbuf, 10);
+ }
+ }
+
+ // All unsigned mods
+ else {
+ base = (mod == 'u' ? 10 : (mod == 'b' ? 2 : (mod == 'o' ? 8 : 16)));
+
+ // Every other mod here is unsigned
+ if (lflag) {
+ ultoa(va_arg(ap, ulong), convbuf, base);
+ }
+
+ else {
+ u = va_arg(ap, uint);
+ if (hhflag) u &= 0xff; // char-ify
+ else if (hflag) u &= 0xffff; // short-ify
+ utoa(u, convbuf, base);
+ }
+
+ // "abcdef" => "ABCDEF"
+ if (mod == 'X') {
+ // Re-use s as an iterator for convbuf
+ s = convbuf;
+ while (*s) {
+ if (islower(*s))
+ *s = toupper(*s);
+ s++;
+ }
+ }
+ }
+
+ s = convbuf;
+ // Convertions happened, now we write into str
+ while (*s && ret < n) {
+ *str++ = *s++;
+ ret++;
+ }
+
+ // We're done dealing with this modifier
+ break;
+ }
+
+ // Unknown/unsupported modifier :|
+ *str++ = mod;
break;
}
+
+ // We fallthrough here from the "while (1)"
+ fmt++;
}
- return ret;
+ // Null-terminate no matter what
+ *str = 0;
+
+ return ret + 1;
}
-
diff --git a/kaleid/crtlib/string.c b/kaleid/crtlib/string.c
index 89ae054..71768c7 100644
--- a/kaleid/crtlib/string.c
+++ b/kaleid/crtlib/string.c
@@ -226,15 +226,12 @@ char *strcpy(char *restrict dest, const char *restrict src)
//
char *strncpy(char *restrict dest, const char *restrict src, size_t n)
{
- size_t it;
+ char *base = dest;
- for (it = 0; it < n && src[it]; it++) {
- dest[it] = src[it];
- }
+ while (n-- && (*dest++ = *src++));
+ while (n--) *dest++ = 0;
- while (it < n) dest[it++] = 0;
-
- return dest;
+ return base;
}
//
@@ -242,22 +239,16 @@ char *strncpy(char *restrict dest, const char *restrict src, size_t n)
// Always null-terminates dest, but doesn't fill
// dest's contents past the null-terminator
//
-// Returns the number of bytes NOT written, not counting null-terminators
+// Returns a pointer to the last character of src copied
+// (In particular it points to src's null-terminator if
+// and only if every character of src was successfuly copied)
//
-size_t strnzcpy(char *restrict dest, const char *restrict src, size_t n)
+char *strnzcpy(char *restrict dest, const char *restrict src, size_t n)
{
- size_t it, loss;
+ while (n-- > 1 && (*dest = *src)) dest++, src++;
+ if (*src) *++dest = 0;
- for (it = 0; it < n - 1 && src[it]; it++) {
- dest[it] = src[it];
- }
-
- dest[it] = 0;
-
- // Compute how many bytes were not copied
- for (loss = it; src[loss]; loss++);
-
- return loss - it;
+ return (char *)src;
}
//
@@ -276,17 +267,13 @@ char *strcat(char *restrict dest, const char *restrict src)
//
char *strncat(char *restrict dest, const char *restrict src, size_t n)
{
- size_t it, off = 0;
+ char *base = dest;
- while (dest[off]) off++;
+ while (*dest) dest++;
+ while (n-- && (*dest++ = *src++));
+ while (n--) *dest++ = 0;
- for (it = 0; it < n && src[it]; it++) {
- dest[it+off] = src[it];
- }
-
- while (it++ < n) dest[it+off] = 0;
-
- return dest;
+ return base;
}
//
@@ -294,24 +281,18 @@ char *strncat(char *restrict dest, const char *restrict src, size_t n)
// Always null-terminates dest, but doesn't fill
// dest's contents past the null-terminator
//
-// Returns the number of bytes NOT written, not counting null-terminators
+// Returns a pointer to the last character of src copied
+// (In particular it points to src's null-terminator if
+// and only if every character of src was successfuly copied)
//
-size_t strnzcat(char *restrict dest, const char *restrict src, size_t n)
+char *strnzcat(char *restrict dest, const char *restrict src, size_t n)
{
- size_t it, loss, off = 0;
+ while (*dest) dest++;
- while (dest[off]) off++;
+ while (n-- > 1 && (*dest = *src)) dest++, src++;
+ if (*src) *++dest = 0;
- for (it = 0; it < n - 1 && src[it]; it++) {
- dest[it+off] = src[it];
- }
-
- dest[it+off] = 0;
-
- // Compute how many bytes were not copied
- for (loss = it; src[loss+off]; loss++);
-
- return loss - it;
+ return (char *)src;
}
//
diff --git a/kaleid/extras/argv.c b/kaleid/extras/argv.c
index 70b1704..9af8ff2 100644
--- a/kaleid/extras/argv.c
+++ b/kaleid/extras/argv.c
@@ -67,7 +67,7 @@ size_t KalComputeArgVecSize(const char *argv[])
// ARG_MAX bytes are available
//
// That available space, however, remains strictly higher than 4KB,
-// which is the POSIX minimum; in case of doubt, safely use 4KB
+// which is the POSIX minimum; the current ARG_MAX guarantees 16KB available
//
// TODO long escape sequences
// get program command line if cmdLine == NULL
@@ -112,6 +112,8 @@ error_t KalCmdLineToArgVecEx(const char *cmdLine,
// Make sure we don't go beyond ARG_MAX bytes
if (written >= ARG_MAX - (1 + sizeof(char *))) {
+ // Sanity check
+ KalAssert(written == ARG_MAX - (1 + sizeof(char *)));
// All we have left is one byte for the null-terminator of the current slot
// and sizeof(char *) bytes for the NULL at the end of argv
@@ -168,7 +170,6 @@ error_t KalCmdLineToArgVecEx(const char *cmdLine,
if (!quotes && !started) {
quotes = *cmdLine;
started = true;
-
continue;
}
@@ -176,7 +177,6 @@ error_t KalCmdLineToArgVecEx(const char *cmdLine,
if (quotes == *cmdLine && ISBLANK(cmdLine[1])) {
quotes = 0;
started = false;
-
NULLTERM_AND_SAVE;
continue;
}
diff --git a/kaleid/include/base/assert.h b/kaleid/include/base/assert.h
index 9f0ca0d..a6986d2 100644
--- a/kaleid/include/base/assert.h
+++ b/kaleid/include/base/assert.h
@@ -100,14 +100,6 @@ noreturn void __assert_handler(const char *, const char *, int, const char *);
#else
-#ifndef NDEBUG
-#define NDEBUG 1
-#endif
-
-#ifndef _NO_DEBUG
-#define _NO_DEBUG 1
-#endif
-
#ifndef KalAssert
#define KalAssert(x) ((void)0)
#endif
diff --git a/kaleid/include/base/bdefs.h b/kaleid/include/base/bdefs.h
index 4cd4379..0229f41 100644
--- a/kaleid/include/base/bdefs.h
+++ b/kaleid/include/base/bdefs.h
@@ -59,6 +59,17 @@
//------------------------------------------//
+#if defined(_NO_DEBUG) || defined(NDEBUG)
+#ifndef NDEBUG
+#define NDEBUG 1
+#endif
+#ifndef _NO_DEBUG
+#define _NO_DEBUG 1
+#endif
+#endif
+
+//------------------------------------------//
+
#ifndef __alignof_is_defined
#define __alignof_is_defined
#define alignof _Alignof
@@ -69,19 +80,26 @@
#define alignas _Alignas
#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
#ifndef __bool_true_false_are_defined
#define __bool_true_false_are_defined
+#ifndef __cplusplus
# define bool _Bool
# define true 1
# define false 0
-# ifndef TRUE
-# define TRUE 1
-# endif
-# ifndef FALSE
-# define FALSE 0
-# endif
+#else
+# define bool bool
+# define true true
+# define false false
+#endif
#endif
-
//------------------------------------------//
#ifndef _PACKED
diff --git a/kaleid/include/base/crtlib.h b/kaleid/include/base/crtlib.h
index 9e3ac86..04654af 100644
--- a/kaleid/include/base/crtlib.h
+++ b/kaleid/include/base/crtlib.h
@@ -46,13 +46,13 @@ typedef unsigned long size_t;
typedef __builtin_va_list va_list;
#endif
-#ifndef __div_t_defined
-#define __div_t_defined
+#ifndef __osk_div_t_defined
+#define __osk_div_t_defined
typedef struct { int quot, rem; } div_t;
#endif
-#ifndef __ldiv_t_defined
-#define __ldiv_t_defined
+#ifndef __osk_ldiv_t_defined
+#define __osk_ldiv_t_defined
typedef struct { long quot, rem; } ldiv_t;
#endif
@@ -150,36 +150,36 @@ 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 *strcpy(char *restrict, const char *restrict);
+char *strncpy(char *restrict, const char *restrict, size_t);
+char *strnzcpy(char *restrict, const char *restrict, size_t);
-char *strcat (char *restrict, const char *restrict);
-char *strncat (char *restrict, const char *restrict, size_t);
-size_t strnzcat(char *restrict, const char *restrict, size_t);
+char *strcat(char *restrict, const char *restrict);
+char *strncat(char *restrict, const char *restrict, size_t);
+char *strnzcat(char *restrict, const char *restrict, size_t);
char *strrev(char *restrict, const char *restrict);
char *strrev2(char *);
-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);
+size_t sprintf(char *, const char *, ...);
+size_t snprintf(char *, size_t, const char *, ...);
+size_t vsprintf(char *, const char *, va_list);
+size_t vsnprintf(char *, size_t, const char *, va_list);
//------------------------------------------//
-char *itoa(int, char *, int);
-char *ltoa(long, char *, int);
-char *utoa(unsigned int, char *, int);
-char *ultoa(unsigned long, char *, int);
+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 *);
+int atoi(const char *);
+long atol(const char *);
+long strtol(const char *restrict, char **restrict, int);
-long strtol (const char *restrict, char **restrict, int);
-unsigned long strtoul(const char *restrict, char **restrict, int);
+unsigned int atou(const char *);
+unsigned long atoul(const char *);
+unsigned long strtoul(const char *restrict, char **restrict, int);
//------------------------------------------//
@@ -193,26 +193,67 @@ char *strsignal(int);
//------------------------------------------//
+int toupper(int);
+int tolower(int);
+
+static inline int isascii(int __c)
+{ return !(__c & ~0xff); }
+
+//------------------------------------------//
+
+extern int __ctype[];
+
+#define _SH(x) (1 << (x))
+
+enum
+{
+ _CT = _SH(0), // control
+ _PR = _SH(1), // printing
+ _GR = _SH(2), // graphical
+ _DX = _SH(3), // hex digit
+ _DG = _SH(4), // decimal digit
+ _SP = _SH(5), // space
+ _BK = _SH(6), // blank
+ _PT = _SH(7), // punctuation
+ _AL = _SH(8), // alpha
+ _UP = _SH(9), // upper alpha
+ _LW = _SH(10), // lower alpha
+};
+
+#define DEC_CTYPE_FUNC(name, flag) \
+static inline bool name(int __c) \
+{ return isascii(__c) ? !!(__ctype[__c] & flag) : 0; }
+
+DEC_CTYPE_FUNC(iscntrl, _CT);
+DEC_CTYPE_FUNC(isprint, _PR);
+DEC_CTYPE_FUNC(isgraph, _GR);
+DEC_CTYPE_FUNC(isdigit, _DG);
+DEC_CTYPE_FUNC(isspace, _SP);
+DEC_CTYPE_FUNC(isblank, _BK);
+DEC_CTYPE_FUNC(ispunct, _PT);
+DEC_CTYPE_FUNC(isalpha, _AL);
+DEC_CTYPE_FUNC(isupper, _UP);
+DEC_CTYPE_FUNC(islower, _LW);
+DEC_CTYPE_FUNC(isxdigit, _DX);
+DEC_CTYPE_FUNC(isalnum, (_AL|_DG));
+
+//------------------------------------------//
+
#ifndef __abs_defined
#define __abs_defined
static inline int abs(int __x)
-{
- return __x < 0 ? -__x : __x;
-}
+{ return __x < 0 ? -__x : __x; }
#endif
#ifndef __labs_defined
#define __labs_defined
static inline long labs(long __x)
-{
- return __x < 0 ? -__x : __x;
-}
+{ return __x < 0 ? -__x : __x; }
#endif
#ifndef __div_defined
#define __div_defined
-static inline div_t div(int __x, int __y)
-{
+static inline div_t div(int __x, int __y) {
div_t __res;
__res.quot = __x/__y;
__res.rem = __x%__y;
@@ -222,8 +263,7 @@ static inline div_t div(int __x, int __y)
#ifndef __ldiv_defined
#define __ldiv_defined
-static inline ldiv_t ldiv(long __x, long __y)
-{
+static inline ldiv_t ldiv(long __x, long __y) {
ldiv_t __res;
__res.quot = __x/__y;
__res.rem = __x%__y;
diff --git a/kaleid/include/base/masks.h b/kaleid/include/base/masks.h
index 5166275..38d3ae7 100644
--- a/kaleid/include/base/masks.h
+++ b/kaleid/include/base/masks.h
@@ -25,6 +25,11 @@
#ifndef _KALBASE_MASKS_H
#define _KALBASE_MASKS_H
+//
+// This file is only used for testing purposes
+// It will be deleted at some point
+//
+
//------------------------------------------//
#define div_t _osk_div_t
@@ -121,6 +126,27 @@
//------------------------------------------//
+#define toupper _osk_toupper
+#define tolower _osk_tolower
+
+#define isascii _osk_isascii
+#define iscntrl _osk_iscntrl
+#define isprint _osk_isprint
+#define isgraph _osk_isgraph
+#define isdigit _osk_isdigit
+#define isspace _osk_isspace
+#define isblank _osk_isblank
+#define ispunct _osk_ispunct
+#define isalpha _osk_isalpha
+#define isupper _osk_isupper
+#define islower _osk_islower
+#define isalnum _osk_isalnum
+#define isxdigit _osk_isxdigit
+
+#define __ctype __osk_ctype
+
+//------------------------------------------//
+
#define abs _osk_abs
#define labs _osk_labs
@@ -130,9 +156,6 @@
#define max _osk_max
#define lmax _osk_lmax
-#define __div
-#define __ldiv
-
#define div _osk_div
#define ldiv _osk_ldiv
diff --git a/kaleid/include/base/types.h b/kaleid/include/base/types.h
index 27d947f..0a1815a 100644
--- a/kaleid/include/base/types.h
+++ b/kaleid/include/base/types.h
@@ -65,6 +65,11 @@ typedef signed int wchar_t;
typedef unsigned long off_t;
#endif
+#ifndef __time_t_defined
+#define __time_t_defined
+typedef unsigned long time_t;
+#endif
+
//------------------------------------------//
#ifndef __ptrdiff_t_defined
@@ -99,13 +104,13 @@ typedef unsigned long uintmax_t;
typedef __builtin_va_list va_list;
#endif
-#ifndef __div_t_defined
-#define __div_t_defined
+#ifndef __osk_div_t_defined
+#define __osk_div_t_defined
typedef struct { int quot, rem; } div_t;
#endif
-#ifndef __ldiv_t_defined
-#define __ldiv_t_defined
+#ifndef __osk_ldiv_t_defined
+#define __osk_ldiv_t_defined
typedef struct { long quot, rem; } ldiv_t;
#endif
diff --git a/kaleid/include/extras/argv.h b/kaleid/include/extras/argv.h
index 32f67f4..84b2954 100644
--- a/kaleid/include/extras/argv.h
+++ b/kaleid/include/extras/argv.h
@@ -26,13 +26,6 @@
#include
#endif
-#ifdef _KALEID_KERNEL
-#define FILE FILE
-typedef void* FILE;
-#else
-#include
-#endif
-
#ifndef _KALEXTRAS_ARGV_H
#define _KALEXTRAS_ARGV_H
@@ -46,6 +39,7 @@ typedef enum CmdParserReturn_t CmdParserReturn_t;
typedef struct CmdOption_t CmdOption_t;
typedef struct CmdDocStrings_t CmdDocStrings_t;
+typedef struct CmdParserState_t CmdParserState_t;
//------------------------------------------//
@@ -54,7 +48,7 @@ typedef struct CmdDocStrings_t CmdDocStrings_t;
// the pointed-to strings and their null-terminators
// This is a 32-bit integer
//
-#define ARG_MAX (1 << 16) // 16 KB
+#define ARG_MAX (1 << 16) // 64 KB
//------------------------------------------//
@@ -103,7 +97,7 @@ enum CmdParserFlags_t
// Use KalGetProgName() instead of argv[0]
// as program name
- KALOPT_USE_ARGV0 = (1 << 5),
+ KALOPT_DONT_USE_ARGV0 = (1 << 5),
// Call argument parser for non-options
// Non-options arguments will be indicated by
@@ -202,7 +196,7 @@ struct CmdDocStrings_t
//
// The state variable passed to the parser containing useful infos
//
-typedef struct {
+struct CmdParserState_t {
// Option we're currently parsing
const CmdOption_t *option;
@@ -217,14 +211,14 @@ typedef struct {
bool shownHelp;
bool shownVersion;
- // Standard output streams
- FILE *outStream;
- FILE *errStream;
+ // Output streams (may be NULL)
+ /*FILE*/ void *outStream;
+ /*FILE*/ void *errStream;
// Private, internal data; do not touch
void *priv;
-} CmdParserState_t;
+};
//
// The argument parser function
@@ -242,7 +236,7 @@ int KalComputeArgCount(const char **argv);
size_t KalComputeArgVecSize(const char **argv);
//
-// Command line to argument vector utility
+// Command line to argument vector
//
error_t KalCmdLineToArgVecEx(const char *cmdLine,
int *argcPtr,
@@ -255,10 +249,9 @@ error_t KalCmdLineToArgVecEx(const char *cmdLine,
error_t KalCmdLineToArgVec(const char *cmdLine,
int *argcPtr,
char **argv);
-/*
//
-// Argument vector to command line utility
+// Argument vector to command line
//
error_t KalArgVecToCmdLineEx(char *cmdLine,
size_t lengthMax,
@@ -285,8 +278,8 @@ error_t KalParseArgVecEx(int argc,
const CmdDocStrings_t *docStrings,
CmdParserFlags_t *flags,
CmdParser_t *parser,
- FILE *outStream,
- FILE *errStream);
+ /*FILE*/ void *outStream,
+ /*FILE*/ void *errStream);
//
// KalParseArgVecEx(argc, argv, options, docString, stdin, stdout, parser, NULL)
//
@@ -297,8 +290,6 @@ error_t KalParseArgVec(int argc,
CmdParserFlags_t *flags,
CmdParser_t *parser);
-*/
-
//------------------------------------------//
#ifdef __cplusplus
diff --git a/kaleid/include/extras/list.h b/kaleid/include/extras/list.h
index 46ce377..c8c62c6 100644
--- a/kaleid/include/extras/list.h
+++ b/kaleid/include/extras/list.h
@@ -52,18 +52,18 @@ typedef struct ListNode_t ListNode_t;
struct ListHead_t
{
- Lock_t *lock;
- ulong length;
- ListNode_t *first;
- ListNode_t *last;
+ Lock_t *lock;
+ ulong length;
+ ListNode_t *first;
+ ListNode_t *last;
};
struct ListNode_t
{
- void *data;
- ListHead_t *head;
- ListNode_t *prev;
- ListNode_t *next;
+ void *data;
+ ListHead_t *head;
+ ListNode_t *prev;
+ ListNode_t *next;
};
//------------------------------------------//
diff --git a/kaleid/include/extras/malloc.h b/kaleid/include/extras/malloc.h
index 694aefc..4e2d30a 100644
--- a/kaleid/include/extras/malloc.h
+++ b/kaleid/include/extras/malloc.h
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------//
// GNU GPL OS/K //
// //
-// Desc: Memory allocation function //
+// Desc: Memory allocation functions //
// //
// //
// Copyright © 2018-2019 The OS/K Team //
diff --git a/kaleid/include/kaleid.h b/kaleid/include/kaleid.h
index 791447c..0d953f0 100644
--- a/kaleid/include/kaleid.h
+++ b/kaleid/include/kaleid.h
@@ -35,12 +35,6 @@
#include
#endif
-#ifdef _KALEID_KERNEL
-#ifndef _KALKERN_H
-#include
-#endif
-#endif
-
//------------------------------------------//
#endif
diff --git a/kaleid/include/kalkern.h b/kaleid/include/kalkern.h
deleted file mode 100644
index 6b97706..0000000
--- a/kaleid/include/kalkern.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//----------------------------------------------------------------------------//
-// GNU GPL OS/K //
-// //
-// Desc: Includes all Kaleid Kernel include files //
-// //
-// //
-// Copyright © 2018-2019 The OS/K Team //
-// //
-// This file is part of OS/K. //
-// //
-// OS/K is free software: you can redistribute it and/or modify //
-// it under the terms of the GNU General Public License as published by //
-// the Free Software Foundation, either version 3 of the License, or //
-// any later version. //
-// //
-// OS/K is distributed in the hope that it will be useful, //
-// but WITHOUT ANY WARRANTY//without even the implied warranty of //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
-// GNU General Public License for more details. //
-// //
-// You should have received a copy of the GNU General Public License //
-// along with OS/K. If not, see . //
-//----------------------------------------------------------------------------//
-
-#ifndef _KALBASE_H
-#include
-#endif
-
-#ifndef _KALEXT_H
-#include
-#endif
-
-//------------------------------------------//
-
-#ifndef _KALKERN_H
-#define _KALKERN_H
-
-//------------------------------------------//
-// Kernel headers //
-//------------------------------------------//
-
-#ifndef _KALKERN_BASE_H
-#include
-#endif
-
-#ifndef _KALKERN_TERM_H
-#include
-#endif
-
-#ifndef _KALKERN_SCHED_H
-#include
-#endif
-
-//------------------------------------------//
-
-#endif
diff --git a/kaleid/include/kernel/base.h b/kaleid/include/kernel/base.h
index d0b70ea..507a7ce 100644
--- a/kaleid/include/kernel/base.h
+++ b/kaleid/include/kernel/base.h
@@ -27,7 +27,7 @@
#endif
#ifdef __cplusplus
-#error "Kaleid's kernel won't compile in C++ :("
+#error "Kaleid's kernel won't compile in C++"
#endif
#ifndef _KALKERN_BASE_H
@@ -41,6 +41,7 @@ typedef struct Process_t Process_t;
typedef struct Terminal_t Terminal_t;
typedef struct ListHead_t ListHead_t;
typedef struct ListNode_t ListNode_t;
+typedef struct Processor_t Processor_t;
typedef enum ProcState_t ProcState_t;
typedef enum TermColor_t TermColor_t;
@@ -50,37 +51,60 @@ typedef enum KernelState_t KernelState_t;
// Multiprocessor misc. //
//------------------------------------------//
-#ifndef INITOK
-#define INITOK ((unsigned int)0xCAFEBABE)
-#endif
-
#ifndef NCPUS
-#define NCPUS 4
+#define NCPUS 1
#endif
-#define GetCurCPU() 0
+// Current CPU number
+// Will return a CPU-local variable later
+#define _GetCurCPU() 0
+
+// Get Process_t structure of current CPU
+#define GetCurCPU() (cpuTable[_GetCurCPU()])
+
+//------------------------------------------//
//
-// Declare an (extern) CPU-local variable
+// Holds all CPU-local variables
//
-#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); }
+struct Processor_t
+{
+ // CPU number, index in CPU list
+ int index;
-#define DECLARE_PER_CPU(_X, _Tp) \
- __DECLARE_PER_CPU(_X, _Tp, extern)
+ // Panic string
+ char panicStr[1024];
-#define LOCAL_DEC_PER_CPU(_X, _Tp) \
- __DECLARE_PER_CPU(_X, _Tp, static)
+ // Number of ticks since boot time
+ ulong ticks;
-//
-// Actually creates a CPU-local variable
-//
-#define CREATE_PER_CPU(_X, _Tp) \
- _Tp __ ## _X [NCPUS] = { (_Tp) 0 }
+ // Current process & thread
+ Process_t *process;
+ Thread_t *thread;
+
+ // Need re-schedule?
+ bool needReSched;
+
+ // Is preemption ON? ("PREEMPT_ON" in sched.h)
+ ulong preemptCount;
+
+ // List heads for the four priority classes
+ ListHead_t *idlePrioProcs;
+ ListHead_t *reglPrioProcs;
+ ListHead_t *servPrioProcs;
+ ListHead_t *timeCritProcs;
+};
+
+//------------------------------------------//
+
+extern int cpuCount;
+extern Processor_t cpuTable[NCPUS];
+
+//------------------------------------------//
+
+#define DEC_PER_CPU(name, field, type) \
+ static inline type Get##name() { return GetCurCPU().field; } \
+ static inline void _Set##name(type __val) { GetCurCPU().field = __val; }
//------------------------------------------//
@@ -92,3 +116,4 @@ typedef enum KernelState_t KernelState_t;
//------------------------------------------//
#endif
+
diff --git a/kaleid/include/kernel/panic.h b/kaleid/include/kernel/panic.h
index 0c90810..4c7607b 100644
--- a/kaleid/include/kernel/panic.h
+++ b/kaleid/include/kernel/panic.h
@@ -31,7 +31,9 @@
//------------------------------------------//
-DECLARE_PER_CPU(PanicStr, const char *);
+// Can't use the macro because panicStr is an array
+static inline char *GetPanicStr(void)
+{ return GetCurCPU().panicStr; }
//------------------------------------------//
@@ -58,7 +60,7 @@ DECLARE_PER_CPU(PanicStr, const char *);
//------------------------------------------//
-noreturn void StartPanic(const char *);
+noreturn void StartPanic(const char *, ...);
noreturn void CrashSystem(void);
//------------------------------------------//
diff --git a/kaleid/include/kernel/proc.h b/kaleid/include/kernel/proc.h
index b591aed..e7de0b7 100644
--- a/kaleid/include/kernel/proc.h
+++ b/kaleid/include/kernel/proc.h
@@ -77,8 +77,8 @@ struct Process_t
//------------------------------------------//
-DECLARE_PER_CPU(CurProc, Process_t *);
-DECLARE_PER_CPU(CurThread, Thread_t *);
+DEC_PER_CPU(CurProc, process, Process_t *);
+DEC_PER_CPU(CurThread, thread, Thread_t *);
//------------------------------------------//
diff --git a/kaleid/include/kernel/sched.h b/kaleid/include/kernel/sched.h
index 5c4e2d6..27ad978 100644
--- a/kaleid/include/kernel/sched.h
+++ b/kaleid/include/kernel/sched.h
@@ -34,7 +34,7 @@
//
// Value of the preemption count indicating that preemption is activated
//
-enum { PREEMPT_ON };
+enum { PREEMPT_ON = 0 };
// Time in ticks a process should be run
enum
@@ -57,15 +57,13 @@ extern const char *PrioClassesNames[];
//------------------------------------------//
-DECLARE_PER_CPU(ReSchedFlag, bool);
-DECLARE_PER_CPU(PreemptCount, ulong);
+DEC_PER_CPU(ReSchedFlag, needReSched, bool);
+DEC_PER_CPU(PreemptCount, preemptCount, ulong);
-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[];
+DEC_PER_CPU(IdlePrioProcs, idlePrioProcs, ListHead_t *);
+DEC_PER_CPU(ReglPrioProcs, reglPrioProcs, ListHead_t *);
+DEC_PER_CPU(ServPrioProcs, servPrioProcs, ListHead_t *);
+DEC_PER_CPU(TimeCritProcs, timeCritProcs, ListHead_t *);
//------------------------------------------//
diff --git a/kaleid/include/kernel/term.h b/kaleid/include/kernel/term.h
index bae24c0..83d2bb2 100644
--- a/kaleid/include/kernel/term.h
+++ b/kaleid/include/kernel/term.h
@@ -74,6 +74,7 @@ struct Terminal_t
TermColor_t fgColor;
TermColor_t bgColor;
+ // Defined in driver
error_t (*ClearTermUnlocked)(Terminal_t *);
error_t (*PutOnTermUnlocked)(Terminal_t *, char);
error_t (*PrintOnTermUnlocked)(Terminal_t *, const char *);
@@ -87,27 +88,30 @@ error_t PutOnTerm(Terminal_t *, char);
error_t PrintOnTerm(Terminal_t *, const char *);
error_t ChTermColor(Terminal_t *, TermColor_t, TermColor_t);
+error_t KernLog(const char *, ...);
//------------------------------------------//
-DECLARE_PER_CPU(_StdOut, Terminal_t *);
-DECLARE_PER_CPU(_StdDbg, Terminal_t *);
-
-//------------------------------------------//
-
-#define GetStdOut() (GetCurProc() == NULL ? Get_StdOut() : GetCurProc()->stdOut)
-#define GetStdDbg() (GetCurProc() == NULL ? Get_StdDbg() : GetCurProc()->stdDbg)
-#define SetStdOut(tm) do { if (GetCurProc() == NULL) _Set_StdOut(tm); \
- else GetCurProc()->stdOut = (tm); } while (0)
-#define SetStdDbg(tm) do { if (GetCurProc() == NULL) _Set_StdDbg(tm); \
- else GetCurProc()->stdDbg = (tm); } while (0)
+extern Terminal_t *stdOut;
+#define GetStdOut() (stdOut)
+#define SetStdOut(x) (stdOut = (x))
//------------------------------------------//
#ifndef _NO_DEBUG
-# define DebugLog(...) PrintOnTerm(GetStdDbg(), __VA_ARGS__)
-#else
-# define DebugLog(...) ((void)0)
+
+extern Terminal_t *stdDbg;
+#define GetStdDbg() (stdDbg)
+#define SetStdDbg(x) (stdDbg = (x))
+
+error_t DebugLog(const char *, ...);
+
+#else // _NO_DEBUG
+
+#define GetStdDbg() NULL
+#define SetStdDbg(x) ((void)0)
+#define DebugLog(fmt, ...) EOK
+
#endif
//------------------------------------------//
diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c
index cc7c438..d28a79d 100644
--- a/kaleid/kernel/init/init.c
+++ b/kaleid/kernel/init/init.c
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------//
// GNU GPL OS/K //
// //
-// Desc: Kernel entry point //
+// Desc: Kernel entry point //
// //
// //
// Copyright © 2018-2019 The OS/K Team //
diff --git a/kaleid/kernel/init/table.c b/kaleid/kernel/init/table.c
index d753b30..273105a 100644
--- a/kaleid/kernel/init/table.c
+++ b/kaleid/kernel/init/table.c
@@ -24,14 +24,8 @@
#include
-CREATE_PER_CPU(PanicStr, const char *);
+int cpuCount = 1;
+Processor_t cpuTable[NCPUS] = {0};
-CREATE_PER_CPU(_StdOut, Terminal_t *);
-CREATE_PER_CPU(_StdDbg, Terminal_t *);
-
-CREATE_PER_CPU(CurProc, Process_t *);
-CREATE_PER_CPU(CurThread, Thread_t *);
-
-CREATE_PER_CPU(PreemptCount, ulong);
-CREATE_PER_CPU(ReSchedFlag, bool);
+Terminal_t *stdOut, *stdDbg;
diff --git a/kaleid/kernel/ke/panic.c b/kaleid/kernel/ke/panic.c
index c71f790..3127321 100644
--- a/kaleid/kernel/ke/panic.c
+++ b/kaleid/kernel/ke/panic.c
@@ -37,16 +37,18 @@ noreturn void __assert_handler(const char *msg,
(void)file; (void)line; (void)func;
- // XXX sprintf() to create a proper panicstr
- StartPanic(msg);
+ StartPanic("cpu%d: In function '%s', from %s line %s - assert() failed: '%s'",
+ _GetCurCPU(), func, file, line, msg);
}
//
// Your best boy panic()
// This is CPU local...
//
-noreturn void StartPanic(const char *str)
+noreturn void StartPanic(const char *fmt, ...)
{
+ va_list ap;
+
DisableIRQs();
if (GetCurProc()) _SetCurProc(NULL);
@@ -54,19 +56,21 @@ noreturn void StartPanic(const char *str)
GetStdOut()->ClearTermUnlocked(GetStdOut());
- if (str == NULL) {
- str = "(no message given)";
+ if (fmt == NULL) {
+ fmt = "(no message given)";
}
if (GetPanicStr()) {
- GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "\nDouble panic!\n");
+ GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "\ndouble panic!");
HaltCPU();
}
- _SetPanicStr(str);
+ va_start(ap, fmt);
+ vsnprintf(GetPanicStr(), sizeof GetPanicStr(), fmt, ap);
+ va_end(ap);
- GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "PANIC! - ");
- GetStdOut()->PrintOnTermUnlocked(GetStdOut(), str);
+ GetStdOut()->PrintOnTermUnlocked(GetStdOut(), "\npanic!\n\n");
+ GetStdOut()->PrintOnTermUnlocked(GetStdOut(), GetPanicStr());
HaltCPU();
}
diff --git a/kaleid/kernel/proc/sched.c b/kaleid/kernel/proc/sched.c
index 6dffd89..d8ba70d 100644
--- a/kaleid/kernel/proc/sched.c
+++ b/kaleid/kernel/proc/sched.c
@@ -82,7 +82,6 @@ void SchedUnlock(void) {
//
// The four priority classes of OS/2
//
-
CREATE_PER_CPU(TimeCritProcs, ListHead_t *);
CREATE_PER_CPU(ServPrioProcs, ListHead_t *);
CREATE_PER_CPU(ReglPrioProcs, ListHead_t *);