kerep sources
This commit is contained in:
52
kerep/src/kprint/README.md
Normal file
52
kerep/src/kprint/README.md
Normal 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
211
kerep/src/kprint/kprint.c
Normal 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
102
kerep/src/kprint/kprint.h
Normal 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
|
||||
89
kerep/src/kprint/kprint_colors.h
Normal file
89
kerep/src/kprint/kprint_colors.h
Normal 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
|
||||
53
kerep/src/kprint/kprint_format.h
Normal file
53
kerep/src/kprint/kprint_format.h
Normal 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
|
||||
74
kerep/src/kprint/kprint_format.md
Normal file
74
kerep/src/kprint/kprint_format.md
Normal 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
155
kerep/src/kprint/kprintf.c
Normal 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);
|
||||
}
|
||||
14
kerep/src/kprint/kprintf.h
Normal file
14
kerep/src/kprint/kprintf.h
Normal 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
|
||||
Reference in New Issue
Block a user