kerep sources

This commit is contained in:
2023-07-12 13:53:20 +03:00
parent 683395983c
commit 44ee9e210f
88 changed files with 3051 additions and 98 deletions

View File

@@ -0,0 +1,52 @@
# kprintf
It is just my cross-plaform variant of printf.
Unlike in standard printf, `%l...` and `%ll...` placeholders dont depend on size of `long int` and `long long int`. And you can change terminal colors by unix codes (`\e[92m`) even on Windows.
| type | placeholder |
|----------------|-------------------------|
| i8 / i16 / i32 | %i / %d |
| i64 | %li / %ld / %lld / %lli |
| u8 / u16 / u32 | %u |
| u64 | %lu / %llu |
| f32 / f64 | %f |
| char | %c |
| char[] | %s |
| void\* | %p |
| 32bit or less | %x |
| 64bit | %lx |
<br>
# kprint
I don't really like printf function (and its variants), so i made safer and more convinient replacement.
| function | returns | arguments |
|----------|---------|-----------|
| kprint | void/throw | kp_fmt, void\*, kp_fmt, void\*... |
| ksprint | Maybe<char\*>| kp_fmt, void\*, kp_fmt, void\*... |
| kfprint | Maybe<void> | FILE\*, kp_fmt, void\*, kp_fmt, void\*... |
## how to use it:
+ **format construction:**
```
kp_fmt fmt= kp_fgColor | kp_bgColor | kp_dataFmt | flags | ktid;
```
[more about `kp_fmt`](kp_fmt.md)
+ fgColor and bgColor can be set to change console output color
+ you should set dataFormat for `int`/`uint`/`float`/`char\*` arguments and ktid for other types
+ flags can be set to modify TypeDescriptor.toString() behavior
+ don't forget to set TypeDescriptor.toString when registering type, or kprint will crash
+ **using base type arguments:**
you can just put them into a function
```
kprint(kp_h|kp_upper|kp_prefix, 255);
```
output: 0xFF
+ **using other registered types:**
should be sent as pointers
```
Maybe m=MaybeNull;
kprint(kp_fgBlue|kp_s, "Maybe: ", kp_fgGreen|ktid_MaybePtr, &m);
```
output: <span style="color:blue">Maybe:</span> <span style="color:lightgreen">{value: { Pointer, 0x0 }}</span>

211
kerep/src/kprint/kprint.c Normal file
View File

@@ -0,0 +1,211 @@
#include "../String/StringBuilder.h"
#include "kprint.h"
ktid __typeFromFormat(kp_fmt f){
ktid typeId=kp_fmt_ktid(f);
if(typeId)
return typeId;
switch(kp_fmt_dataFormat(f)){
case kp_i:
case kp_h:
case kp_b:
return ktid_name(i64);
case kp_u:
return ktid_name(u64);
case kp_f:
return ktid_name(f64);
case kp_c:
return ktid_name(char);
case kp_s:
return ktid_ptrName(char);
default:
return ktid_undefined;
}
}
Maybe __next_toString(kp_fmt f, void* object){
// detecting type
ktid typeId=__typeFromFormat(f);
if(typeId==ktid_undefined)
safethrow("typeId is undefined, can't autodetect type",;);
if(typeId==ktid_ptrName(char))
object=*(char**)object; // dereferencing char** to char*
ktDescriptor* type=ktDescriptor_get(typeId);
if(!type->toString)
safethrow("type descriptor doesnt have toString() func",;);
return SUCCESS(UniHeapPtr(char, type->toString(object, f)));
}
Maybe check_argsN(u8 n){
if(n%2 != 0) safethrow("kprint recieved non-even number of arguments",;);
if(n > 32) safethrow("kprint recieved >32 number of arguments",;);
return MaybeNull;
}
Maybe __ksprint(u8 n, kp_fmt* formats, __kp_value_union* objects){
try(check_argsN(n), _,;);
n/=2;
StringBuilder* strb=StringBuilder_create();
for(u8 i=0; i<n; i++){
try(__next_toString(formats[i], &objects[i]),mStr,;);
StringBuilder_append_cptr(strb, mStr.value.VoidPtr);
Unitype_free(mStr.value);
}
char* rezult=StringBuilder_build(strb).ptr;
return SUCCESS(UniHeapPtr(char, rezult));
}
Maybe __kfprint(FILE* file, u8 n, kp_fmt* formats, __kp_value_union* objects){
try(check_argsN(n), _,;);
n/=2;
for(u8 i=0; i<n; i++){
try(__next_toString(formats[i], &objects[i]),maybeStr,;);
if(fputs(maybeStr.value.VoidPtr, file)==EOF)
safethrow("can't write string to file", Unitype_free(maybeStr.value));
Unitype_free(maybeStr.value);
}
fflush(file);
return MaybeNull;
}
void __kprint(u8 n, kp_fmt* formats, __kp_value_union* objects){
tryLast(check_argsN(n), _,;);
n/=2;
for(u8 i=0; i<n; i++){
kp_fmt fmt=formats[i];
kprint_setColor(fmt);
tryLast(__next_toString(fmt, &objects[i]),maybeStr, kprint_setColor(kp_bgBlack|kp_fgGray));
if(fputs(maybeStr.value.VoidPtr, stdout)==EOF) \
throw("can't write string to stdout");
//, Unitype_free(maybeStr.value)
Unitype_free(maybeStr.value);
}
fflush(stdout);
}
#if defined(_WIN32)|| defined(_WIN64)
#include <windows.h>
#define FOREGROUND_YELLOW FOREGROUND_GREEN | FOREGROUND_RED
DWORD kp_fgColor_toWin(kp_fgColor f){
//kprintf("fg: %x\n", f);
switch(f){
case kp_fgBlack: return 0;
case kp_fgRedD: return FOREGROUND_RED;
case kp_fgGreenD: return FOREGROUND_GREEN;
case kp_fgYellowD: return FOREGROUND_GREEN | FOREGROUND_RED;
case kp_fgBlueD: return FOREGROUND_BLUE;
case kp_fgMagentaD: return FOREGROUND_RED | FOREGROUND_BLUE;
case kp_fgCyanD: return FOREGROUND_BLUE | FOREGROUND_GREEN;
case kp_fgGray: return FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
case kp_fgGrayD: return FOREGROUND_INTENSITY;
case kp_fgRed: return FOREGROUND_RED | FOREGROUND_INTENSITY;
case kp_fgGreen: return FOREGROUND_GREEN | FOREGROUND_INTENSITY;
case kp_fgYellow: return FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
case kp_fgBlue: return FOREGROUND_BLUE | FOREGROUND_INTENSITY;
case kp_fgMagenta: return FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY;
case kp_fgCyan: return FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
case kp_fgWhite: return FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
default: throw(ERR_FORMAT);
}
}
DWORD kp_bgColor_toWin(kp_bgColor f){
//kprintf("bg: %x\n", f);
switch(f){
case kp_bgBlack: return 0;
case kp_bgRedD: return BACKGROUND_RED;
case kp_bgGreenD: return BACKGROUND_GREEN;
case kp_bgYellowD: return BACKGROUND_GREEN | BACKGROUND_RED;
case kp_bgBlueD: return BACKGROUND_BLUE;
case kp_bgMagentaD: return BACKGROUND_RED | BACKGROUND_BLUE;
case kp_bgCyanD: return BACKGROUND_BLUE | BACKGROUND_GREEN;
case kp_bgGray: return BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
case kp_bgGrayD: return BACKGROUND_INTENSITY;
case kp_bgRed: return BACKGROUND_RED | BACKGROUND_INTENSITY;
case kp_bgGreen: return BACKGROUND_GREEN | BACKGROUND_INTENSITY;
case kp_bgYellow: return BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY;
case kp_bgBlue: return BACKGROUND_BLUE | BACKGROUND_INTENSITY;
case kp_bgMagenta: return BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY;
case kp_bgCyan: return BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
case kp_bgWhite: return BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
default: throw(ERR_FORMAT);
}
}
void kprint_setColor(kp_fmt f){
DWORD color=0;
if(!kp_fmt_fgColorSet(f) & !kp_fmt_bgColorSet(f))
return;
if(kp_fmt_fgColorSet(f))
color+=kp_fgColor_toWin(kp_fmt_fgColor(f));
if(kp_fmt_bgColorSet(f))
color+=kp_bgColor_toWin(kp_fmt_bgColor(f));
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, color);
}
#else
void kprint_setColor(kp_fmt f){
if(kp_fmt_fgColorSet(f)){
u8 fg=(f&0x0f000000)>>24;
if(fg<8) fg+=30;
else fg+=90-8;
printf("\e[%um", fg);
}
if(kp_fmt_bgColorSet(f)){
u8 bg=(f&0x00f00000)>>20;
if(bg<8) bg+=40;
else bg+=100-8;
printf("\e[%um", bg);
}
}
#endif
/* Maybe ksprint_ar(u32 count, kp_fmt format, ktid typeId, void* array){
ktDescriptor* type=ktDescriptor_get(format.typeId);
if(!type->toString)
safethrow("type descriptor doesnt have toString() func",;);
StringBuilder* strb=StringBuilder_create();
StringBuilder_append_char(strb, '[');
for (u16 e=1; e<count; e++){
StringBuilder_append_char(strb, ' ');
char* elStr=type->toString(array+type->size*e, &format);
StringBuilder_append_cptr(strb, elStr);
StringBuilder_append_char(strb, ',');
}
StringBuilder_rmchar(strb);
StringBuilder_append_char(strb, ' ');
StringBuilder_append_char(strb, ']');
} */
static const char* _kp_colorNames[16]={
"black",
"dark_red",
"dark_green",
"dark_yellow",
"dark_blue",
"dark_magenta",
"dark_cyan",
"gray",
"dark_gray",
"red",
"green",
"yellow",
"blue",
"magenta",
"cyan",
"white"
};
char* kp_bgColor_toString(kp_bgColor c){
u32 color_index=(c&0x00f00000)>>20;
if(color_index>15) throw(ERR_WRONGINDEX);
return _kp_colorNames[color_index];
}
char* kp_fgColor_toString(kp_fgColor c){
u32 color_index=(c&0x00f00000)>>24;
if(color_index>15) throw(ERR_WRONGINDEX);
return _kp_colorNames[color_index];
}

102
kerep/src/kprint/kprint.h Normal file
View File

@@ -0,0 +1,102 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/errors.h"
#include "kprint_format.h"
/*
This file looks like a mess, but all cotnent here just solves the problem of putting variadic arguments to array of formats and array of objects.
*/
typedef union {
i64 i64;
u64 u64;
f64 f64;
void* ptr;
} __kp_value_union;
static inline __kp_value_union __kpVU_f(f64 f) { return (__kp_value_union){ .f64=f }; }
static inline __kp_value_union __kpVU_i(i64 f) { return (__kp_value_union){ .i64=f }; }
#define __kpVU_selectType(V) _Generic(V, float: __kpVU_f, f64: __kpVU_f, default: __kpVU_i)(V)
#define __kpVU(V) __kpVU_selectType(V)
#define __kp_argsToFmts8( \
a0, a1, a2, a3, a4, a5, a6, a7,...) \
((i32[]){ a0,a2,a4,a6 })
#define __kp_argsToObjs8( \
a0, a1, a2, a3, a4, a5, a6, a7,...) \
((__kp_value_union[]){ __kpVU(a1),__kpVU(a3),__kpVU(a5),__kpVU(a7) })
#define __kp_argsToFmts16( \
a0, a1, a2, a3, a4, a5, a6, a7, \
a8, a9, a10,a11,a12,a13,a14,a15,...) \
((i32[]){ a0,a2,a4,a6,a8,a10,a12,a14 })
#define __kp_argsToObjs16( \
a0, a1, a2, a3, a4, a5, a6, a7, \
a8, a9, a10,a11,a12,a13,a14,a15,...) \
((__kp_value_union[]){ __kpVU(a1),__kpVU(a3),__kpVU(a5),__kpVU(a7),__kpVU(a9),__kpVU(a11),__kpVU(a13),__kpVU(a15) })
#define __kp_argsToFmts32( \
a0, a1, a2, a3, a4, a5, a6, a7, \
a8, a9, a10,a11,a12,a13,a14,a15, \
a16,a17,a18,a19,a20,a21,a22,a23, \
a24,a25,a26,a27,a28,a29,a30,a31,...) \
((i32[]){ a0,a2,a4,a6,a8,a10,a12,a14,a16,a18,a20,a22,a24,a26,a28,a30 })
#define __kp_argsToObjs32( \
a0, a1, a2, a3, a4, a5, a6, a7, \
a8, a9, a10,a11,a12,a13,a14,a15, \
a16,a17,a18,a19,a20,a21,a22,a23, \
a24,a25,a26,a27,a28,a29,a30,a31,...) \
((__kp_value_union[]){ __kpVU(a1),__kpVU(a3),__kpVU(a5),__kpVU(a7),__kpVU(a9),__kpVU(a11),__kpVU(a13),__kpVU(a15),__kpVU(a17),__kpVU(a19),__kpVU(a21),__kpVU(a23),__kpVU(a25),__kpVU(a27),__kpVU(a29),__kpVU(a31) })
#define __32zeroes 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
#define __kp_argsToArrs(COUNT,ARGS...) \
(kp_fmt*)( \
COUNT<=8 ? __kp_argsToFmts8(ARGS) : \
COUNT<=16 ? __kp_argsToFmts16(ARGS) : \
__kp_argsToFmts32(ARGS)), \
(__kp_value_union*)( \
COUNT<=8 ? __kp_argsToObjs8(ARGS) : \
COUNT<=16 ? __kp_argsToObjs16(ARGS) : \
__kp_argsToObjs32(ARGS))
Maybe __ksprint(u8 n, kp_fmt* formats, __kp_value_union* objects);
/// @param ARGS kp_fmt, value, kp_fmt, value...
///@returns Maybe<char*>
#define ksprint(ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \
__ksprint(count_args(ARGS), __kp_argsToArrs(count_args(ARGS),ARGS, __32zeroes)) \
)
/*-Wint-conversion warning was produced during value to __kp_value_union conversion*/
Maybe __kfprint(FILE* fd, u8 n, kp_fmt* formats, __kp_value_union* objects);
/// @param FD FILE*
/// @param ARGS kp_fmt, value, kp_fmt, value...
///@returns Maybe<void>
#define kfprint(FD, ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \
__kfprint(FD, count_args(ARGS), __kp_argsToArrs(count_args(ARGS),ARGS, __32zeroes)) \
)
void __kprint(u8 n, kp_fmt* formats, __kp_value_union* objects);
///can use non-catchable throw !!!
///@param ARGS kp_fmt, value, kp_fmt, value...
///@returns void
#define kprint(ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \
__kprint(count_args(ARGS), __kp_argsToArrs(count_args(ARGS),ARGS, __32zeroes)) \
)
#if __cplusplus
}
#endif

View File

@@ -0,0 +1,89 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
// 10000000 00000000 00000000 00000000
// ^ ^^^^
// | color num
// fgColorSet flag
PACKED_ENUM(kp_fgColor,
/// black foreground
kp_fgBlack = 0x80000000,
/// dark red foreground
kp_fgRedD = 0x81000000,
/// dark green foreground
kp_fgGreenD = 0x82000000,
/// dark yellow foreground
kp_fgYellowD = 0x83000000,
/// dark blue foreground
kp_fgBlueD = 0x84000000,
/// dark magenta foreground
kp_fgMagentaD= 0x85000000,
/// dark cyan foreground
kp_fgCyanD = 0x86000000,
/// gray foreground
kp_fgGray = 0x87000000,
/// dark gray foreground
kp_fgGrayD = 0x88000000,
/// red foreground
kp_fgRed = 0x89000000,
/// green foreground
kp_fgGreen = 0x8a000000,
/// yellow foreground
kp_fgYellow = 0x8b000000,
/// blue foreground
kp_fgBlue = 0x8c000000,
/// magenta foreground
kp_fgMagenta = 0x8d000000,
/// cyan foreground
kp_fgCyan = 0x8e000000,
/// white foreground
kp_fgWhite = 0x8f000000
)
// 01000000 00000000 00000000 00000000
// ^ ^^^^
// bgColorSet flag color num
PACKED_ENUM(kp_bgColor,
/// black background
kp_bgBlack = 0x40000000,
/// dark red background
kp_bgRedD = 0x40100000,
/// dark green background
kp_bgGreenD = 0x40200000,
/// dark yellow background
kp_bgYellowD = 0x40300000,
/// dark blue background
kp_bgBlueD = 0x40400000,
/// dark magenta background
kp_bgMagentaD= 0x40500000,
/// dark cyan background
kp_bgCyanD = 0x40600000,
/// gray background
kp_bgGray = 0x40700000,
/// dark gray background
kp_bgGrayD = 0x40800000,
/// red background
kp_bgRed = 0x40900000,
/// green background
kp_bgGreen = 0x40a00000,
/// yellow background
kp_bgYellow = 0x40b00000,
/// blue background
kp_bgBlue = 0x40c00000,
/// magenta background
kp_bgMagenta = 0x40d00000,
/// cyan background
kp_bgCyan = 0x40e00000,
/// white background
kp_bgWhite = 0x40f00000
)
char* kp_bgColor_toString(kp_bgColor c);
char* kp_fgColor_toString(kp_fgColor c);
#if __cplusplus
}
#endif

View File

@@ -0,0 +1,53 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/std.h"
#include "../base/type_system/ktid.h"
#include "kprint_colors.h"
/// kprint_format
typedef u32 kp_fmt;
PACKED_ENUM(kp_dataFmt,
// 00000000 00000000 00000000 00000000
// ^^^^
// type
kp_i = 0x00000000,
kp_u = 0x00010000,
kp_h = 0x00020000,
kp_b = 0x00030000,
kp_f = 0x00040000,
kp_c = 0x00050000,
kp_s = 0x00060000,
// 00100000 00000000 00000000 00000000
// ^
// prefix/postfix flag
kp_pre=0x20000000,
kp_post=kp_pre,
// 00010000 00000000 00000000 00000000
// ^
// uppercase flag
kp_upper=0x10000000
)
#define kp_fmt_fgColorSet(FMT) (bool)((FMT&0x80000000)!=0)
#define kp_fmt_bgColorSet(FMT) (bool)((FMT&0x40000000)!=0)
#define kp_fmt_withPrefix(FMT) (bool)((FMT&kp_pre)!=0)
#define kp_fmt_withPostfix(FMT) (bool)((FMT&kp_post)!=0)
#define kp_fmt_isUpper(FMT) (bool)((FMT&kp_upper)!=0)
#define kp_fmt_fgColor(FMT) (kp_fgColor)(FMT&0x8f000000)
#define kp_fmt_bgColor(FMT) (kp_bgColor)(FMT&0x40f00000)
#define kp_fmt_dataFormat(FMT) (kp_dataFmt)(FMT&0x000f0000)
#define kp_fmt_ktid(FMT) (ktid)(FMT&0x0000ffff)
///@param f bgColor | fgColor
void kprint_setColor(kp_fmt f);
#if __cplusplus
}
#endif

View File

@@ -0,0 +1,74 @@
# kerep_format
```
00000000 00000000 00000000 00000000
fgColorSet┘│││└┼┴┘ └┼┴┘└┴┴┤ ktid
bgColorSet─┘││ │ bgColor └data format
prefix┬────┘│ └fgColor
postfix └uppercase
```
## Console colors
### *Foreground*
| kp_fg | hex | bin |
|-------|-----|-----|
| Black | 0x80000000 | 10000000 00000000... |
| RedD | 0x81000000 | 10000001 00000000... |
| GreenD | 0x82000000 | 10000010 00000000... |
| YellowD | 0x83000000 | 10000011 00000000... |
| BlueD | 0x84000000 | 10000100 00000000... |
| MagentaD | 0x85000000 | 10000101 00000000... |
| CyanD | 0x86000000 | 10000110 00000000... |
| Gray | 0x87000000 | 10000111 00000000... |
| GrayD | 0x88000000 | 10001000 00000000... |
| Red | 0x89000000 | 10001001 00000000... |
| Green | 0x8a000000 | 10001010 00000000... |
| Yellow | 0x8b000000 | 10001011 00000000... |
| Blue | 0x8c000000 | 10001100 00000000... |
| Magenta | 0x8d000000 | 10001101 00000000... |
| Cyan | 0x8e000000 | 10001110 00000000... |
| White | 0x8f000000 | 10001111 00000000... |
### *Background*
| kp_bg | hex | bin |
|-------|-----|-----|
| Black | 0x40000000 | 01000000 00000000... |
| RedD | 0x40100000 | 01000000 00010000... |
| GreenD | 0x40200000 | 01000000 00100000... |
| YellowD | 0x40300000 | 01000000 00110000... |
| BlueD | 0x40400000 | 01000000 01000000... |
| MagentaD | 0x40500000 | 01000000 01010000... |
| CyanD | 0x40600000 | 01000000 01100000... |
| Gray | 0x40700000 | 01000000 01110000... |
| GrayD | 0x40800000 | 01000000 10000000... |
| Red | 0x40900000 | 01000000 10010000... |
| Green | 0x40a00000 | 01000000 10100000... |
| Yellow | 0x40b00000 | 01000000 10110000... |
| Blue | 0x40c00000 | 01000000 11000000... |
| Magenta | 0x40d00000 | 01000000 11010000... |
| Cyan | 0x40e00000 | 01000000 11100000... |
| White | 0x40f00000 | 01000000 11110000... |
## Data format
| format | possible flags | data types | hex value | bin value |
|-----------|----------------|------------|------------|-----------|
| kp_i | | i8... i64 | 0x00000000 | 00000000 00000000... |
| kp_u | Postfix, Upper | u8... u64 | 0x00010000 | 00000000 00000001... |
| kp_h | Prefix, Upper | any | 0x00020000 | 00000000 00000010... |
| kp_b | Prefix | any | 0x00030000 | 00000000 00000011... |
| kp_f | Postfix, Upper | f32, f64 | 0x00040000 | 00000000 00000100... |
| kp_c | | char | 0x00050000 | 00000000 00000101... |
| kp_string | | char* | 0x00060000 | 00000000 00000110... |
P.S. `any` means you must add `kpid` to `kp_fmt` if data type is not base type
### *Flags*
| flag | hex value | bin value |
|------|------------|-----------|
| kp_pre | 0x20000000 | 00100000 00000000... |
| kp_post | 0x20000000 | 00100000 00000000... |
| kp_upper | 0x10000000 | 00010000 00000000... |

155
kerep/src/kprint/kprintf.c Normal file
View File

@@ -0,0 +1,155 @@
#include "kprintf.h"
#include "../base/base.h"
#if defined(_WIN64) || defined(_WIN32)
#include <windows.h>
WORD unixColorToWin(u8 c){
switch(c){
//foreground
case 30: return 0;
case 31: return FOREGROUND_RED;
case 32: return FOREGROUND_GREEN;
case 33: return FOREGROUND_GREEN | FOREGROUND_RED;
case 34: return FOREGROUND_BLUE;
case 35: return FOREGROUND_RED | FOREGROUND_BLUE;
case 36: return FOREGROUND_BLUE | FOREGROUND_GREEN;
case 37: return FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
case 90: return FOREGROUND_INTENSITY;
case 91: return FOREGROUND_RED | FOREGROUND_INTENSITY;
case 92: return FOREGROUND_GREEN | FOREGROUND_INTENSITY;
case 93: return FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
case 94: return FOREGROUND_BLUE | FOREGROUND_INTENSITY;
case 95: return FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY;
case 96: return FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
case 97: return FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
//background
case 40: return 0;
case 41: return BACKGROUND_RED;
case 42: return BACKGROUND_GREEN;
case 43: return BACKGROUND_GREEN | BACKGROUND_RED;
case 44: return BACKGROUND_BLUE;
case 45: return BACKGROUND_RED | BACKGROUND_BLUE;
case 46: return BACKGROUND_BLUE | BACKGROUND_GREEN;
case 47: return BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
case 100: return BACKGROUND_INTENSITY;
case 101: return BACKGROUND_RED | BACKGROUND_INTENSITY;
case 102: return BACKGROUND_GREEN | BACKGROUND_INTENSITY;
case 103: return BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY;
case 104: return BACKGROUND_BLUE | BACKGROUND_INTENSITY;
case 105: return BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY;
case 106: return BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
case 107: return BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
default: return 0;
}
}
#endif
void kprintf(const char* format, ...){
va_list vl;
va_start(vl, format);
u32 i=0;
for(char c=format[i++]; c!=0; c=format[i++]){
// value format specifiers
if(c=='%'){
char* argstr=NULL;
bool l=false;
c=format[i++];
format_escape_seq:
switch (c) {
case 'u':
argstr=toString_u64(
l ? va_arg(vl, u64) : va_arg(vl, u32)
,0,0);
break;
case 'i': case 'd':
argstr=toString_i64(
l ? va_arg(vl, i64) : va_arg(vl, i32)
);
break;
case 'f':
// f32 is promoted to f64 when passed through '...'
argstr=toString_f64(va_arg(vl, f64), toString_float_default_precision,0,0);
break;
case 'l':
l=true;
if((c=format[i++]))
goto format_escape_seq;
break;
case 'p': ;
void* phex=va_arg(vl, void*);
argstr=toString_hex(&phex,getEndian()==LittleEndian,sizeof(phex),1,0);
break;
case 'x': ;
if(l){
u64 xhex=va_arg(vl, u64);
argstr=toString_hex(&xhex,getEndian()==LittleEndian,sizeof(xhex),0,1);
}
else {
u32 xhex=va_arg(vl, u32);
argstr=toString_hex(&xhex,getEndian()==LittleEndian,sizeof(xhex),0,1);
}
break;
case 's': ;
char* cptr=va_arg(vl,char*);
if(!cptr)
cptr="<nullstr>";
if(*cptr)
fputs(cptr, stdout);
break;
case 'c':
argstr=malloc(2);
argstr[0]=(char)va_arg(vl,int);
argstr[1]=0;
break;
default:
putc('\n',stdout);
putc('<',stdout);
putc(c,stdout);
putc('>',stdout);
throw(ERR_FORMAT);
}
if(argstr){
fputs(argstr, stdout);
free(argstr);
}
}
// escape sequences
else if(c=='\e'){
IFWIN(
/* WINDOWS */
({
if((c=format[i++])=='['){
u8 colorUnix=0;
for(i8 n=0; n<6 && c!=0; n++){
c=format[i++];
switch (c){
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
colorUnix=colorUnix*10+c-'0';
break;
case 'm': ;
WORD colorWin=unixColorToWin(colorUnix);
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, colorWin);
goto end_iteration;
default:
goto end_iteration;
}
}
}
}),
/* UNIX */
putc(c,stdout);
);
}
// common characters
else {
putc(c,stdout);
}
#if defined(_WIN64) || defined(_WIN32)
end_iteration:;
#endif
}
va_end(vl);
}

View File

@@ -0,0 +1,14 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/type_system/base_toString.h"
// cross-platform printf analog
void kprintf(const char* format, ...);
#if __cplusplus
}
#endif