kerep-headers

This commit is contained in:
timerix 2023-07-12 11:34:41 +03:00
parent d3525f66d4
commit 683395983c
49 changed files with 2003 additions and 20 deletions

View File

@ -0,0 +1,43 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "Autoarr_declare.h"
#include "Autoarr_define.h"
Autoarr_declare(Pointer)
Autoarr_declare(char)
Autoarr_declare(bool)
Autoarr_declare(f32)
Autoarr_declare(f64)
Autoarr_declare(i8)
Autoarr_declare(u8)
Autoarr_declare(i16)
Autoarr_declare(u16)
Autoarr_declare(i32)
Autoarr_declare(u32)
Autoarr_declare(i64)
Autoarr_declare(u64)
Autoarr_declare(Unitype)
#define Autoarr_foreach(ar, elem, codeblock...) { \
if(ar->blocks_count>0) { \
typeof(**ar->values) elem; \
for(u16 blockI=0;blockI<ar->blocks_count-1;blockI++) \
for(u32 elemI=0;elemI<ar->max_block_length;elemI++){ \
elem=ar->values[blockI][elemI]; \
{ codeblock; } \
} \
for(u16 elemI=0;elemI<ar->block_length;elemI++){ \
elem=ar->values[ar->blocks_count-1][elemI]; \
{ codeblock; } \
} \
} \
}
#if __cplusplus
}
#endif

View File

@ -0,0 +1,74 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#define Autoarr_declare(type) \
\
struct Autoarr_##type; \
\
typedef struct __Autoarr_##type##_functions_list_t { \
void (*add)(struct Autoarr_##type* ar, type element); \
type (*get)(struct Autoarr_##type* ar, u32 index); \
type* (*getPtr)(struct Autoarr_##type* ar, u32 index); \
void (*set)(struct Autoarr_##type* ar, u32 index, type element); \
void (*freeWithMembers)(struct Autoarr_##type* ar, bool freePtr); \
void (*freeWithoutMembers)(struct Autoarr_##type* ar, bool freePtr); \
type* (*toArray)(struct Autoarr_##type* ar); \
} __Autoarr_##type##_functions_list_t; \
\
extern __Autoarr_##type##_functions_list_t __Autoarr_##type##_functions_list; \
\
STRUCT(Autoarr_##type, \
u16 blocks_count; \
u16 max_blocks_count; \
u16 block_length; \
u16 max_block_length; \
type** values; \
__Autoarr_##type##_functions_list_t* functions; \
) \
\
Autoarr_##type* __Autoarr_##type##_create(u16 max_blocks_count, u16 max_block_length); \
void __Autoarr_##type##_freeWithMembers(Autoarr_##type* ar, bool freePtr); \
void ____Autoarr_##type##_freeWithMembers(void* ar);
#define Autoarr(type) Autoarr_##type
#define Autoarr_create(type, max_blocks_count, max_block_length) \
__Autoarr_##type##_create(max_blocks_count, max_block_length)
#define Autoarr_add(autoarr, element) \
autoarr->functions->add(autoarr, element)
#define Autoarr_get(autoarr, index) \
autoarr->functions->get(autoarr,index)
#define Autoarr_getPtr(autoarr, index) \
autoarr->functions->getPtr(autoarr,index)
#define Autoarr_set(autoarr, index, element) \
autoarr->functions->set(autoarr, index, element)
#define Autoarr_free(autoarr, freePtr) \
autoarr->functions->freeWithMembers(autoarr, freePtr)
#define Autoarr_freeWithoutMembers(autoarr, freePtr) \
autoarr->functions->freeWithoutMembers(autoarr, freePtr)
#define Autoarr_toArray(autoarr) \
autoarr->functions->toArray(autoarr)
#define Autoarr_length(autoarr) \
(u32)(!autoarr->blocks_count ? 0 : \
autoarr->max_block_length*(autoarr->blocks_count-1)+autoarr->block_length)
#define Autoarr_max_length(autoarr) \
(u32)(autoarr->max_block_length*autoarr->max_blocks_count)
#define Autoarr_pop(AR){ \
if(AR->block_length==1){ \
AR->blocks_count--; \
AR->block_length=AR->max_block_length; \
free(AR->values[AR->blocks_count]); \
} \
else AR->block_length--; \
}
#if __cplusplus
}
#endif

View File

@ -0,0 +1,100 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#define Autoarr_define(type, TYPE_IS_PTR) \
\
kt_define(Autoarr_##type, ____Autoarr_##type##_freeWithMembers, NULL); \
\
void __Autoarr_##type##_add(Autoarr_##type* ar, type element){ \
if(!ar->values){ \
ar->values=malloc(ar->max_blocks_count*sizeof(type*)); \
goto create_block; \
} \
if(ar->block_length==ar->max_block_length){ \
if (ar->blocks_count>=ar->max_blocks_count) throw(ERR_MAXLENGTH); \
ar->block_length=0; \
create_block: \
ar->values[ar->blocks_count]=malloc(ar->max_block_length*sizeof(type)); \
ar->blocks_count++; \
} \
ar->values[ar->blocks_count-1][ar->block_length]=element; \
ar->block_length++; \
} \
\
type __Autoarr_##type##_get(Autoarr_##type* ar, u32 index){ \
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
return ar->values[index/ar->max_block_length][index%ar->max_block_length]; \
} \
\
type* __Autoarr_##type##_getPtr(Autoarr_##type* ar, u32 index){ \
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
return ar->values[index/ar->max_block_length]+(index%ar->max_block_length); \
} \
\
void __Autoarr_##type##_set(Autoarr_##type* ar, u32 index, type element){ \
if(index>=Autoarr_length(ar)) throw(ERR_WRONGINDEX); \
ar->values[index/ar->max_block_length][index%ar->max_block_length]=element; \
} \
\
void __Autoarr_##type##_freeWithoutMembers(Autoarr_##type* ar, bool freePtr){ \
for(u16 i=0; i<ar->blocks_count;i++) \
free(ar->values[i]); \
free(ar->values); \
if(freePtr) free(ar); \
} \
\
void __Autoarr_##type##_freeWithMembers(Autoarr_##type* ar, bool freePtr){ \
if(ktDescriptor_##type.freeMembers!=NULL) { \
Autoarr_foreach(ar, el, \
void* members_ptr=&el; \
if(TYPE_IS_PTR) members_ptr=*(type**)members_ptr; \
ktDescriptor_##type.freeMembers(members_ptr); \
); \
} \
__Autoarr_##type##_freeWithoutMembers(ar, freePtr);\
} \
void ____Autoarr_##type##_freeWithMembers(void* ar){ \
__Autoarr_##type##_freeWithMembers((Autoarr_##type*)ar, false); \
} \
\
type* __Autoarr_##type##_toArray(Autoarr_##type* ar){ \
u32 length=Autoarr_length(ar); \
if(length==0) \
return NULL; \
type* array=malloc(length * sizeof(type)); \
for(u32 i=0; i<length; i++) \
array[i]=__Autoarr_##type##_get(ar, i); \
return array; \
} \
\
__Autoarr_##type##_functions_list_t __Autoarr_##type##_functions_list={ \
&__Autoarr_##type##_add, \
&__Autoarr_##type##_get, \
&__Autoarr_##type##_getPtr, \
&__Autoarr_##type##_set, \
&__Autoarr_##type##_freeWithMembers, \
&__Autoarr_##type##_freeWithoutMembers, \
&__Autoarr_##type##_toArray \
}; \
\
Autoarr_##type* __Autoarr_##type##_create(u16 max_blocks_count, u16 max_block_length){ \
Autoarr_##type* ar=malloc(sizeof(Autoarr_##type)); \
*ar=(Autoarr_##type){ \
.max_blocks_count=max_blocks_count, \
.blocks_count=0, \
.max_block_length=max_block_length, \
.block_length=0, \
.values=NULL, \
.functions=&__Autoarr_##type##_functions_list \
}; \
return ar; \
}
#if __cplusplus
}
#endif

View File

@ -0,0 +1,9 @@
# Autoarr struct
`Autoarr` means Automatically resizing array. It is my implementation of dyynamic array. If you want to use `Autoarr` of some type, it should be declared in header file by macro `Autoarr_declare` and defined in source file by `Autoarr_define`.
Examples:
[Hashtable.h](src/Hashtable/Hashtable.h)
[Hashtable.c](src/Hashtable/Hashtable.c)
### Autoarr_*_exported
Contains definitions for functions, exported for using in C# kerep wrapper.

View File

@ -0,0 +1,32 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../Hashtable/Hashtable.h"
// parses text to binary values
Maybe DtsodV24_deserialize(char* text);
// creates text representation of dtsod
Maybe DtsodV24_serialize(Hashtable* dtsod);
// returns value or UniNull if key not found
Unitype DtsodV24_get(Hashtable* dtsod, char* key);
// adds or sets value
void DtsodV24_addOrSet(Hashtable* dtsod, char* key, Unitype value);
// checks for dtsod contains value or dont
bool DtsodV24_contains(Hashtable* dtsod, char* key);
// replaces value with UniNull if key exists in dtsod
bool DtsodV24_remove(Hashtable* dtsod, char* key);
// frees memory including memory of elements (hashtables, autoarrs, etc.)
void DtsodV24_free(Hashtable* dtsod);
#if __cplusplus
}
#endif

View File

@ -0,0 +1,13 @@
# DtsodC
DtsodV23 parser in C# works too slow, so i wrote V24 parser in C
<br>
## Building on Linux
**Required packages:** gcc
```bash
make build
````

View File

@ -0,0 +1,28 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#include "file.h"
bool dir_exists(const char* path);
///@return Maybe<void>
Maybe dir_create(const char* path);
///@return Maybe<void>
Maybe dir_delete(const char* path);
///@return Maybe<Array_string>
Maybe dir_getFiles(const char* path, bool recursive);
///@return Maybe<Array_string>
Maybe dir_getDirs(const char* path, bool recursive);
///@return Maybe<Array_string>
Maybe dir_findFiles(const char* path, char* searchPattern, bool recursive);
///@return Maybe<Array_string>
Maybe dir_findDirs(const char* path, char* searchPattern, bool recursive);
#if __cplusplus
}
#endif

View File

@ -0,0 +1,75 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#include "../String/string.h"
typedef FILE* FileHandle;
kt_declare(FileHandle);
bool file_exists(const char* path);
///@return Maybe<void>
Maybe file_delete(const char* path, bool recursive);
PACKED_ENUM(FileOpenMode,
// open a file for reading
FileOpenMode_Read=1,
// (re)create a file for writing
FileOpenMode_Write=2,
// opens file for writing additional data to the end / creates new file
FileOpenMode_Append=4,
// (re)creates file for reading/writing
FileOpenMode_ReadWrite=FileOpenMode_Read|FileOpenMode_Write,
// opens file for readng/writing additional data to the end / creates new file
FileOpenMode_ReadAppend=FileOpenMode_Read|FileOpenMode_Append
)
/// @brief opens file
/// @param path path to file
/// @param mode Read/Write/Append/ReadWrite/ReadAppend
/// @return Maybe<FileHandle>
Maybe file_open(const char* path, FileOpenMode mode);
/// @brief closes file descriptor
/// @return Maybe<void>
Maybe file_close(FileHandle file);
/// @brief closes file descriptor
/// @param byte byte to write
/// @return Maybe<void>
Maybe file_writeChar(FileHandle file, char byte);
/// @brief closes file descriptor
/// @param buffer bytes to write
/// @param length buffer length
/// @return Maybe<void>
Maybe file_writeBuffer(FileHandle file, char* buffer, u64 length);
/// @brief writes all cstring array content to file
/// @param cptr zero-terminated cstring
/// @return Maybe<void>
Maybe file_writeCptr(FileHandle file, char* cptr);
/// @brief reads single byte from file
/// @return Maybe<char>
Maybe file_readChar(FileHandle file);
/// @brief reads byte array of specofied length
/// @param buffer buffer that will be filled with file bytes
/// @param length buffer length
/// @return Maybe<u64> total number of successfully read bytes (<=length)
Maybe file_readBuffer(FileHandle file, char* buffer, u64 length);
/// @brief reads all bytes from file
/// @param allBytes ptr to the file's content will be pushed there
/// @return Maybe<u64> total number of successfully read bytes
Maybe file_readAll(FileHandle file, char** allBytes);
#if __cplusplus
}
#endif

View File

@ -0,0 +1,3 @@
#include "path.h"
#include "dir.h"
#include "file.h"

View File

@ -0,0 +1,15 @@
#include "../base/std.h"
#if defined(_WIN64) || defined(_WIN32)
#define KFS_USE_WINDOWS_H 1
#else
#define KFS_USE_WINDOWS_H 0
#endif
#if KFS_USE_WINDOWS_H
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif

View File

@ -0,0 +1,42 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#if defined(_WIN32) || defined (_WIN64)
static const char path_sep='\\';
static const char path_notSep='/';
#else
static const char path_sep='/';
static const char path_notSep='\\';
#endif
char* __path_concat(u32 n, ...);
/// @brief merges path parts together and puts <path_sep> between them
/// @return new cstr
#define path_concat(PATH_PARTS...) __path_concat(count_args(PATH_PARTS), PATH_PARTS)
/// @brief fixes path separators
/// @param cstr where can be <path_notSep>
/// @return new cstr with correct separators
char* path_fixSeparators(const char* path);
#define path_resolve(PATH_PARTS...) path_fixSeparators(path_concat(PATH_PARTS))
/// @brief calls safethrow() if finds escape sequense in path
/// @param path cstr where can be <..>
/// @return Maybe<void>
Maybe path_throwIfEscapes(const char* path);
///@return path of parent dir
char* path_parentDir(char* path);
///@return file name
char* path_basename(char* path, bool with_extension);
#if __cplusplus
}
#endif

View File

@ -0,0 +1,17 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#define hashb(FUNC, BUF, LEN) FUNC(0xFFFFFFFF, BUF, LEN)
#define hashs(FUNC, STR) FUNC(0xFFFFFFFF, STR, cptr_length(STR))
u32 hash_sdbm32(u32 oldhash, void* buf, u32 len);
u32 hash_crc32(u32 oldhash, void* buf, u32 len);
#if __cplusplus
}
#endif

View File

@ -0,0 +1,49 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#include "../HashFunctions/hash.h"
#include "KeyValuePair.h"
STRUCT(Hashtable,
u8 hein; // height=HT_HEIGHTS[hein]
Autoarr(KVPair)** rows; // Autoarr[height]
)
Hashtable* Hashtable_create();
void Hashtable_free(Hashtable* ht);
void __Hashtable_free(void* ht);
// amount of rows
u16 Hashtable_height(Hashtable* ht);
// don't add pairs with the same keys,
// or something weird will happen
// if not sure, use Hashtable_addOrSet()
void Hashtable_add(Hashtable* ht, char* key, Unitype u);
void Hashtable_addOrSet(Hashtable* ht, char* key, Unitype u);
void Hashtable_addMany(Hashtable* ht, KVPair* pair_array, u32 count);
bool Hashtable_tryAdd(Hashtable* ht, char* key, Unitype u);
bool Hashtable_trySet(Hashtable* ht, char* key, Unitype u);
// returns null or pointer to value in hashtable
Unitype* Hashtable_getPtr(Hashtable* ht, char* key);
Unitype Hashtable_get(Hashtable* ht, char* key);
bool Hashtable_tryGet(Hashtable* ht, char* key, Unitype* output);
#define Hashtable_foreach(HT, EL, codeblock...) { \
u16 hmax=Hashtable_height(HT); \
for(u16 h=0; h<hmax; h++){ \
Autoarr(KVPair)* AR=HT->rows[h]; \
Autoarr_foreach(AR, EL, codeblock); \
} \
}
#if __cplusplus
}
#endif

View File

@ -0,0 +1,25 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#include "../Autoarr/Autoarr.h"
STRUCT(KVPair,
char* key;
Unitype value;
)
Autoarr_declare(KVPair)
// proper way to clean a KVP
void KVPair_free(KVPair p);
void __KVPair_free(void* p);
void printkvp(KVPair p);
#if __cplusplus
}
#endif

View File

@ -0,0 +1,34 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../Autoarr/Autoarr.h"
#include "string.h"
STRUCT(StringBuilder,
Autoarr(string)* compl_bufs;
Autoarr(i8)* curr_buf;
)
StringBuilder* StringBuilder_create(void);
void StringBuilder_free(StringBuilder* b);
void __StringBuilder_free(void* b);
// Joins all strings from compl_bufs.
// Returns zero-terminated string.
// No need to call string_extract()!
// Frees StringBuilder.
string StringBuilder_build(StringBuilder* b);
// removes last char
void StringBuilder_rmchar(StringBuilder* b);
void StringBuilder_append_char(StringBuilder* b, char c);
void StringBuilder_append_cptr(StringBuilder* b, char* s);
void StringBuilder_append_string(StringBuilder* b, string s);
void StringBuilder_append_i64(StringBuilder* b, i64 a);
void StringBuilder_append_u64(StringBuilder* b, u64 a);
void StringBuilder_append_f64(StringBuilder* b, f64 a);
#if __cplusplus
}
#endif

View File

@ -0,0 +1,38 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#include "../Autoarr/Autoarr.h"
// my fixed length string struct
// doesn't store '\0' at the end
STRUCT(string,
char* ptr; // char pointer
u64 length; // amount of chars in ptr value
)
Autoarr_declare(string)
static const string stringNull={NULL,0};
/// wraps pointer without copy
#define string_fromCptr(CPTR) (string){ .ptr=CPTR, .length=cptr_length(CPTR) }
// copies str content to new char pointer value (adding '\0' at the end)
char* string_extract(string str);
// copies src.ptr content to new string and adds \0 at the end
string string_copy(string src);
// compares two strings, NullPtr-friendly
bool string_compare(string str0, string str1);
// creates new string which is reversed variant of <s>
string string_reverse(string s);
#if __cplusplus
}
#endif

17
kerep-headers/base/base.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "std.h"
#include "errors.h"
#include "cptr.h"
#include "optime.h"
#include "type_system/type_system.h"
#include "../kprint/kprintf.h"
#include "endian.h"
#if __cplusplus
}
#endif

94
kerep-headers/base/cptr.h Normal file
View File

@ -0,0 +1,94 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "std.h"
// returns length of char buffer (without \0)
u32 cptr_length(const char* str);
// allocates new char[] and copies src there
char* cptr_copy(const char* src);
bool cptr_equals(const char* key0, const char* key1);
bool cptr_startsWith(const char* src, const char* fragment);
bool cptr_endsWith(const char* src, const char* fragment);
// multiplies char n times
char* char_multiply(char c, u32 n);
/// @param startIndex 0 ... src length
/// @param seekLength 0 ... -1
/// @return pos of first <fragment> inclusion in <src> or -1 if not found
i32 cptr_seek(const char* src, const char* fragment, u32 startIndex, u32 seekLength);
/// @param startIndex -1 ... src length
/// @param seekLength 0 ... -1
/// @return pos of first <fragment> inclusion in <src> or -1 if not found
i32 cptr_seekReverse(const char* src, const char* fragment, u32 startIndex, u32 seekLength);
/// @param startIndex 0 ... src length
/// @param seekLength 0 ... -1
/// @return pos of first <fragment> inclusion in <src> or -1 if not found
i32 cptr_seekChar(const char* src, char fragment, u32 startIndex, u32 seekLength);
/// @param startIndex -1 ... src length
/// @param seekLength 0 ... -1
/// @return pos of first <fragment> inclusion in <src> or -1 if not found
i32 cptr_seekCharReverse(const char* src, char fragment, u32 startIndex, u32 seekLength);
/// @brief search for <fragment> in <ptr>
/// @return index of first <fragment> inclusion or -1 if not found
static inline i32 cptr_indexOf(const char* src, const char* fragment)
{ return cptr_seek(src, fragment, 0, -1); }
/// @brief search for <fragment> in <ptr>
/// @return index of first <fragment> inclusion or -1 if not found
static inline i32 cptr_indexOfChar(const char* src, char fragment)
{ return cptr_seekChar(src, fragment, 0, -1); }
/// @brief search for <fragment> in <ptr>
/// @return index of last <fragment> inclusion or -1 if not found
static inline i32 cptr_lastIndexOf(const char* src, const char* fragment)
{ return cptr_seekReverse(src, fragment, -1, -1); }
/// @brief search for <fragment> in <ptr>
/// @return index of last <fragment> inclusion or -1 if not found
static inline i32 cptr_lastIndexOfChar(const char* src, char fragment)
{ return cptr_seekCharReverse(src, fragment, -1, -1); }
static inline bool cptr_contains(const char* src, const char* fragment){
return cptr_seek(src, fragment, 0, -1) +1;
}
void memcopy(void* from, void* to, u32 size);
char* __cptr_concat(u32 n, ...);
#define cptr_concat(STR...) __cptr_concat(count_args(STR), STR)
char* cptr_toLower(const char* src);
char* cptr_toUpper(const char* src);
/// @param startIndex 0 ... src length
/// @param seekLength 0 ... -1
/// @return <src> with <str_old> replaced by <str_new> or empty cstring if <str_old> not found
char* cptr_replaceIn(const char* src, const char* str_old, const char* str_new, u32 startIndex, u32 seekLength);
/// @param startIndex 0 ... src length
/// @param seekLength 0 ... -1
/// @return <src> with <c_old> replaced by <c_new> or empty cstring if <str_old> not found
char* cptr_replaceCharIn(const char* src, char c_old, char c_new, u32 startIndex, u32 seekLength);
static inline char* cptr_replace(const char* src, const char* str_old, const char* str_new)
{ return cptr_replaceIn(src, str_old, str_new, 0, -1); }
static inline char* cptr_replaceChar(const char* src, char c_old, char c_new)
{ return cptr_replaceCharIn(src, c_old, c_new, 0, -1); }
#if __cplusplus
}
#endif

View File

@ -0,0 +1,20 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "std.h"
#include "type_system/typedef_macros.h"
PACKED_ENUM(Endian,
UnknownEndian=0,
LittleEndian=1,
BigEndian=2
)
Endian getEndian();
#if __cplusplus
}
#endif

View File

@ -0,0 +1,90 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "std.h"
#include "type_system/type_system.h"
PACKED_ENUM(ErrorId,
SUCCESS, // not an error
ERR_MAXLENGTH, ERR_WRONGTYPE, ERR_WRONGINDEX,
ERR_NOTIMPLEMENTED, ERR_NULLPTR, ERR_ENDOFSTR,
ERR_KEYNOTFOUND, ERR_FORMAT, ERR_UNEXPECTEDVAL,
ERR_IO, ERR_IO_EOF
)
char* errname(ErrorId err);
char* __genErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname);
char* __extendErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname);
STRUCT(Maybe,
Unitype value;
char* errmsg;
)
// return it if func doesn't return anything
// .value .errmsg
#define MaybeNull (Maybe){UniNull, NULL}
void Maybe_free(Maybe e);
void printMaybe(Maybe e);
#define SUCCESS(REZLT) (Maybe){.errmsg=NULL, .value=REZLT}
#define __RETURN_EXCEPTION(ERRMSG) return (Maybe){.value=UniNull, .errmsg=ERRMSG}
#define __EXIT(ERRMSG) ({ kprintf("\e[91m%s\e[0m \n", ERRMSG); free(ERRMSG); exit(128); })
char* __doNothing(char* a);
char* __unknownErr( );
#define __stringify_err(E) _Generic( \
(E), \
char*: __doNothing, \
int: errname, \
default: __unknownErr \
)(E)
#if __cplusplus
#define throw_id(E) __EXIT(((char*)__genErrMsg(errname(E), __FILE__,__LINE__,__func__)))
#define throw_msg(E) __EXIT(((char*)__genErrMsg(E, __FILE__,__LINE__,__func__)))
#define safethrow_id(E, FREEMEM) { FREEMEM; \
__RETURN_EXCEPTION(((char*)__genErrMsg(errname(E), __FILE__,__LINE__,__func__))); \
}
#define safethrow_msg(E, FREEMEM) { FREEMEM; \
__RETURN_EXCEPTION(((char*)__genErrMsg(E, __FILE__,__LINE__,__func__))); \
}
#define try_cpp(_funcCall, _rezult, freeMem) Maybe _rezult=_funcCall; if(_rezult.errmsg){ \
freeMem; \
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__); \
return _rezult; \
}
#else
#define throw(E) __EXIT(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__)))
#define safethrow(E, FREEMEM) { FREEMEM; \
__RETURN_EXCEPTION(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__))); \
}
#define try(_funcCall, _rezult, freeMem) Maybe _rezult=_funcCall; if(_rezult.errmsg){ \
freeMem; \
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__); \
return _rezult; \
}
#endif
#define tryLast(_funcCall, _rezult, ON_EXIT) Maybe _rezult=_funcCall; if(_rezult.errmsg){ \
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__); \
__EXIT(_rezult.errmsg); \
}
#if __cplusplus
}
#endif

View File

@ -0,0 +1,41 @@
#pragma once
#include "std.h"
#define __optime_print(opname, t) \
char tnames[3][3]={"s\0","ms","us"}; \
i32 tni=0; \
if(t>1000000){ \
t/=1000000; \
tni=0; \
} else if(t>1000){ \
t/=1000; \
tni=1; \
} else tni=2; \
kprintf("\e[93moperation \e[94m%s\e[93m lasted \e[94m%f \e[93m%s\n", \
opname, t, tnames[tni]);
#ifdef CLOCK_REALTIME
/// executes codeblock and prints execution time
/// u64 op_i is counter of the internal loop
/// uses non-standard high-precision clock
#define optime(opname, repeats, codeblock...) { \
struct timespec start, stop; \
clock_gettime(CLOCK_REALTIME, &start); \
for(u64 op_i=0;op_i<(u64)repeats;op_i++) \
{ codeblock; } \
clock_gettime(CLOCK_REALTIME, &stop); \
f64 t=(f64)(stop.tv_sec-start.tv_sec)*1000000+(f64)(stop.tv_nsec-start.tv_nsec)/1000; \
__optime_print(opname,t); \
}
#else
/// uses standard low precision clock
#define optime(opname, repeats, codeblock...) { \
clock_t start=clock(); \
for(u64 op_i=0;op_i<(u64)repeats;op_i++) \
{ codeblock; } \
clock_t stop=clock(); \
f64 t=(f64)(stop-start)/CLOCKS_PER_SEC*1000000; \
__optime_print(opname,t); \
}
#endif

135
kerep-headers/base/std.h Normal file
View File

@ -0,0 +1,135 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
#include <locale.h>
#include <time.h>
#include <setjmp.h>
#include <signal.h>
#include <math.h>
typedef int8_t i8;
typedef uint8_t u8;
typedef int16_t i16;
typedef uint16_t u16;
typedef int32_t i32;
typedef uint32_t u32;
typedef int64_t i64;
typedef uint64_t u64;
typedef float f32;
typedef double f64;
/// anonymous pointer without specified freeMembers() func
typedef void* Pointer;
// Usually bool from stdbool.h is defined as macro,
// so in other macros like ktid_##TYPE it will be replaced by _Bool.
// ktid__Bool will be created instead of ktid_bool
// In C++ bool is a keyword, so there is no need to redefine it.
#if !__cplusplus
typedef u8 bool;
#define true 1
#define false 0
#endif
#define dbg(N) kprintf("\e[95m%d\n",N)
#define nameof(V) #V
#ifdef _MSC_VER
#pragma comment(lib, "mincore_downlevel.lib") // Support OS older than SDK
#define _CRT_SECURE_NO_WARNINGS 1
#define EXPORT __declspec(dllexport)
#define CALL __cdecl
#elif defined(__GNUC__)
#define EXPORT __attribute__((visibility("default")))
#if __SIZEOF_POINTER__ == 4
#define CALL __attribute__((__cdecl__))
#else
#define CALL
#endif
#ifndef typeof
#define typeof(X) __typeof__(X)
#endif
#else
#pragma GCC error "unknown compiler"
#endif
#ifdef _MSC_VER
#define IFWIN(YES, NO) YES
#define IFMSC(YES, NO) YES
#elif defined(_WIN64) || defined(_WIN32)
#define IFWIN(YES, NO) YES
#define IFMSC(YES, NO) NO
#elif defined(__GNUC__)
#define IFWIN(YES, NO) NO
#define IFMSC(YES, NO) NO
#else
#pragma GCC error "unknown compiler"
#endif
#ifndef sprintf_s
#define sprintf_s(BUF, BUFSIZE, FORMAT, ...) sprintf(BUF, FORMAT, ## __VA_ARGS__)
#endif
#define __count_args( \
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, \
a32,a33,a34,a35,a36,a37,a38,a39, \
a40,a41,a42,a43,a44,a45,a46,a47, \
a48,a49,a50,a51,a52,a53,a54,a55, \
a56,a57,a58,a59,a60,a61,a62,a63, \
a64,...) a64
// Macro for counting variadic arguments (max 64)
// (see usage in kprint.h)
#define count_args(ARGS...) __count_args( \
ARGS, \
64,63,62,61,60,59,58,57, \
56,55,54,53,52,51,50,49, \
48,47,46,45,44,43,42,41, \
40,39,38,37,36,35,34,33, \
32,31,30,29,28,27,26,25, \
24,23,22,21,20,19,18,17, \
16,15,14,13,12,11,10,9, \
8, 7, 6, 5, 4, 3, 2, 1, 0)
/*
Cross-platform warning supression.
WARNING_DISABLE( W_EXAMPLE,
some code producing W_EXAMPLE;
);
You can even embed it into macro in header (see kprint.h)
*/
#ifdef _MSC_VER
#define PRAGMA_WARNING_PUSH __pragma(warning( push ))
#define DISABLE_WARNING(wNumber) __pragma(warning( disable : wNumber ))
#define PRAGMA_WARNING_POP __pragma(warning( pop ))
#else
#define _PRAGMA(P) _Pragma(#P)
#define PRAGMA_WARNING_PUSH _PRAGMA(GCC diagnostic push)
#define PRAGMA_WARNING_DISABLE(wName) _PRAGMA(GCC diagnostic ignored wName)
#define PRAGMA_WARNING_POP _PRAGMA(GCC diagnostic pop)
#define W_INT_CONVERSION "-Wint-conversion"
#define W_IMPLICIT_FALLTHROUGH "-Wimplicit-fallthrough"
#endif
#define WARNING_DISABLE(WARNING, CODE...) \
PRAGMA_WARNING_PUSH \
PRAGMA_WARNING_DISABLE(WARNING) \
CODE; \
PRAGMA_WARNING_POP
/// gcc throws warning on unused function return value
#define WARN_UNUSED_REZULT __attribute__((warn_unused_result))
#if __cplusplus
}
#endif

View File

@ -0,0 +1,34 @@
# kerep type system
For using some kerep capabilities, such as generic structs, unitype, and kprint, types should be *registered*.
## type id
Every registered type has its own `ktDescriptor` and `ktid` is an index of the descriptor in descriptors array.
Descriptor should be declared in header file.
Following macro declares `typedef struct` and `ktDescriptor`
```c
//someStruct.h
STRUCT(someStruct,
i32 i; i32 j; i32 k;
);
```
then you need to define descriptor in a source file
```c
//someStruct.c
kt_define(someStruct);
```
and register it.
## type descriptors
Every registered type should have it's own descriptor (`ktDescriptor`). It's a struct, which contains some information about type and pointers to some specific functions for this type (`toString`, `freeMembers`).
## type registration
To finally register a type, you should call macro `kt_register()` between `kt_beginInit()` and `kt_endInit()`. Better do it at the start of your program. To register all types from kerep, call `kt_initKerepTypes()`.
You can free internal ktDescriptors storage by calling `kt_free()` at exit, if your debugger (valgrind in my case) sees a memory leak.
Examples:
+ [kerep types registration](src/base/type_system/init.c)
+ [kt_initKerepTypes()](tests/main.cpp)

View File

@ -0,0 +1,47 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../errors.h"
// accepts char* (ptr to char) and char* (ptr to string)
// uses format kp_s and kp_c to determine what type is <c> argument
char* __toString_char(void* c, u32 fmt);
// bool
char* __toString_bool(void* c, u32 fmt);
// signed int
char* toString_i64(i64 n);
char* __toString_i8(void* n, u32 fmt);
char* __toString_i16(void* n, u32 fmt);
char* __toString_i32(void* n, u32 fmt);
char* __toString_i64(void* n, u32 fmt);
// unsigned int
char* toString_u64(u64 n, bool withPostfix, bool uppercase);
char* __toString_u8(void* n, u32 fmt);
char* __toString_u16(void* n, u32 fmt);
char* __toString_u32(void* n, u32 fmt);
char* __toString_u64(void* n, u32 fmt);
// float
#define toString_f32_max_precision 6
#define toString_f64_max_precision 15
#define toString_float_default_precision 6
char* toString_f32(f32 n, u8 precision, bool withPostfix, bool uppercase); // uses sprintf
char* toString_f64(f64 n, u8 precision, bool withPostfix, bool uppercase); // uses sprintf
char* __toString_f32(void* n, u32 fmt);
char* __toString_f64(void* n, u32 fmt);
///@param inverse set to true for little endian numbers (their bytes are in reverse order)
char* toString_bin(void* bytes, u32 size, bool inverse, bool withPrefix);
///@param inverse set to true for little endian numbers (their bytes are in reverse order)
char* toString_hex(void* bytes, u32 size, bool inverse, bool withPrefix, bool uppercase);
#if __cplusplus
}
#endif

View File

@ -0,0 +1,12 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
// call this between kt_beginInit() and kt_endInit()
void kt_initKerepTypes();
#if __cplusplus
}
#endif

View File

@ -0,0 +1,51 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../std.h"
#include "ktid.h"
#include "typedef_macros.h"
#define kt_declare(TYPE)\
ktid_declare(TYPE);\
extern ktDescriptor ktDescriptor_##TYPE; \
extern ktDescriptor ktDescriptor_##TYPE##_Ptr;
#define kt_define(TYPE, FREE_MEMBERS_F, TOSTRING_F)\
ktid_define(TYPE); \
ktDescriptor ktDescriptor_##TYPE={ \
.name=#TYPE, \
.id=ktid_undefined, \
.size=sizeof(TYPE), \
.freeMembers=FREE_MEMBERS_F, \
.toString=TOSTRING_F \
}; \
ktDescriptor ktDescriptor_##TYPE##_Ptr={\
.name=#TYPE "_Ptr", \
.id=ktid_undefined, \
.size=sizeof(TYPE), \
.freeMembers=FREE_MEMBERS_F, \
.toString=TOSTRING_F \
};
typedef void (*freeMembers_t)(void*);
typedef char* (*toString_t)(void* obj, u32 fmt);
STRUCT(ktDescriptor,
char* name;
ktid id;
u16 size;
freeMembers_t freeMembers; // NULL or function which frees all struct members
toString_t toString; // NULL or function which generates string representaion of object
)
/// gets descriptor for TYPE
#define ktDescriptor_name(TYPE) ktDescriptor_##TYPE
/// gets descriptor for pointer to TYPE
#define ktDescriptor_namePtr(TYPE) ktDescriptor_##TYPE##_Ptr
#if __cplusplus
}
#endif

View File

@ -0,0 +1,49 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../std.h"
#include "ktid.h"
#include "ktDescriptor.h"
extern ktid ktid_last;
void __kt_register(ktDescriptor* descriptor);
#define kt_register(TYPE) \
__kt_register(&ktDescriptor_##TYPE); \
ktid_##TYPE=ktid_last; \
__kt_register(&ktDescriptor_##TYPE##_Ptr); \
ktid_##TYPE##_Ptr=ktid_last;
void kt_beginInit();
void kt_endInit();
/// @param id id of registered type
ktDescriptor* ktDescriptor_get(ktid id);
char* ktDescriptor_toString(ktDescriptor* d);
// call it to free heap-allocated ktDescriptors array
void kt_free();
kt_declare(Pointer);
kt_declare(char);
kt_declare(bool);
kt_declare(f32);
kt_declare(f64);
kt_declare(i8);
kt_declare(u8);
kt_declare(i16);
kt_declare(u16);
kt_declare(i32);
kt_declare(u32);
kt_declare(i64);
kt_declare(u64);
kt_declare(ktDescriptor);
#if __cplusplus
}
#endif

View File

@ -0,0 +1,28 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../std.h"
#include "typedef_macros.h"
typedef u16 ktid;
static const ktid ktid_undefined=-1;
/// gets descriptor id for TYPE
#define ktid_name(TYPE) ktid_##TYPE
/// gets descriptor id for pointer to TYPE
#define ktid_ptrName(TYPE) ktid_##TYPE##_Ptr
#define ktid_declare(TYPE) \
extern ktid ktid_##TYPE; \
extern ktid ktid_##TYPE##_Ptr;
#define ktid_define(TYPE) \
ktid ktid_##TYPE=-1; \
ktid ktid_##TYPE##_Ptr=-1;
#if __cplusplus
}
#endif

View File

@ -0,0 +1,8 @@
#pragma once
#include "init.h"
#include "ktid.h"
#include "ktDescriptor.h"
#include "kt_functions.h"
#include "unitype.h"
#include "typedef_macros.h"

View File

@ -0,0 +1,15 @@
#pragma once
#define ENUM(ENUM_NAME, ENUM_MEMBERS...) typedef enum ENUM_NAME { \
ENUM_MEMBERS \
} ENUM_NAME;
#define PACKED_ENUM(ENUM_NAME, ENUM_MEMBERS...) typedef enum ENUM_NAME { \
ENUM_MEMBERS \
} __attribute__((__packed__)) ENUM_NAME;
#define STRUCT(STRUCT_NAME, STRUCT_MEMBERS...) typedef struct STRUCT_NAME STRUCT_NAME; \
typedef struct STRUCT_NAME { \
STRUCT_MEMBERS \
} STRUCT_NAME; \
kt_declare(STRUCT_NAME);

View File

@ -0,0 +1,55 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "ktid.h"
#include "typedef_macros.h"
STRUCT(Unitype,
union {
i64 Int64;
u64 UInt64;
f64 Float64;
bool Bool;
void* VoidPtr;
char Bytes[8];
};
ktid typeId;
bool allocatedInHeap; // should Unitype_free call free() to VoidPtr*
)
#define __UniDef(FIELD, TYPE, VAL) ((Unitype){ \
.FIELD=VAL, .typeId=ktid_name(TYPE), .allocatedInHeap=false})
#define UniInt64(VAL) __UniDef(Int64, i64, VAL)
#define UniUInt64(VAL) __UniDef(UInt64, u64, VAL)
#define UniFloat64(VAL) __UniDef(Float64, f64, VAL)
#define UniBool(VAL) __UniDef(Bool, bool, VAL)
#define UniPtr(TYPE_ID, VAL, ALLOCATED_ON_HEAP)((Unitype){ \
.VoidPtr=VAL, .typeId=TYPE_ID, .allocatedInHeap=ALLOCATED_ON_HEAP })
#define UniStackPtr(TYPE, VAL) UniPtr(ktid_ptrName(TYPE), VAL, false)
#define UniHeapPtr(TYPE, VAL) UniPtr(ktid_ptrName(TYPE), VAL, true)
// 0==ktid_Pointer
#define UniNull ((Unitype){.Int64=0, .typeId=0, .allocatedInHeap=false})
#define UniTrue UniBool(true)
#define UniFalse UniBool(false)
#define Unitype_isUniNull(UNI) (UNI.typeId==0 && UNI.Int64==0)
#define UniCheckTypeId(UNI, TYPE_ID) (UNI.typeId==TYPE_ID)
#define UniCheckType(UNI, TYPE) UniCheckTypeId(UNI, ktid_name(TYPE))
#define UniCheckTypePtr(UNI, TYPE) UniCheckTypeId(UNI, ktid_ptrName(TYPE))
// frees VoidPtr value or does nothing if type isn't pointer
void Unitype_free(Unitype u);
void __UnitypePtr_free(void* u);
char* Unitype_toString(Unitype v, u32 fmt);
void printuni(Unitype v);
#if __cplusplus
}
#endif

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>

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... |

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

View File

@ -0,0 +1,72 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/std.h"
#include "splitmix64/splitmix64.h"
#include "xoroshiro/xoroshiro.h"
#include "xoshiro/xoshiro.h"
/*
You can choose any algorithm that has required functions:
some_alg32_statePtr some_alg32_init(u32 seed);
u32 some_alg32_next(some_alg32_statePtr);
void some_alg32_free(some_alg32_statePtr);
#define KRAND_ALG32_init some_alg32_init
#define KRAND_ALG32_next some_alg32_next
#define KRAND_ALG32_free some_alg32_free
#include "kerep/random/krandom.h"
The same way it works for 64-bit RNGs
*/
// default rng_next function
#ifndef KRAND_ALG32_next
#define KRAND_ALG32_next xoshiro128plus##_next
#endif
#ifndef KRAND_ALG32_init
#define KRAND_ALG32_init xoshiro128plus##_init
#endif
#ifndef KRAND_ALG32_free
#define KRAND_ALG32_free xoshiro128plus##_free
#endif
#ifndef KRAND_ALG64_next
#define KRAND_ALG64_next xoshiro256plus##_next
#endif
#ifndef KRAND_ALG64_init
#define KRAND_ALG64_init xoshiro256plus##_init
#endif
#ifndef KRAND_ALG64_free
#define KRAND_ALG64_free xoshiro256plus##_free
#endif
typedef void* krand_statePtr;
#define KRAND_ALG32_initFromTime xoshiro128plus##_initFromTime
#define KRAND_ALG64_initFromTime xoshiro256plus##_initFromTime
#define __krand_next_definition(VALUE_SIZE) { return from+KRAND_ALG##VALUE_SIZE##_next(state)%(to-from); }
// ready-to-use functions
static inline i8 krand_next8 (krand_statePtr state, i8 from, i8 to) __krand_next_definition(32)
static inline i16 krand_next16(krand_statePtr state, i16 from, i16 to) __krand_next_definition(32)
static inline i32 krand_next32(krand_statePtr state, i32 from, i32 to) __krand_next_definition(32)
static inline i64 krand_next64(krand_statePtr state, i64 from, i64 to) __krand_next_definition(64)
// divides random number by 2^64 to return a value between 0 and 1
static inline f32 krand_nextFloat32(krand_statePtr state) {return (u32)KRAND_ALG32_next(state)/0xffffffff; }
static inline f64 krand_nextFloat64(krand_statePtr state) {return KRAND_ALG64_next(state)/0xffffffff; }
///@param chance (0-1.0) is probability of success
static inline bool fate(krand_statePtr state,float chance){
i32 limit=1/chance + 0.01f;
return KRAND_ALG32_next(state)%limit == 0;
}
#if __cplusplus
}
#endif

View File

@ -0,0 +1,22 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../../base/base.h"
typedef u64 splitmix64_state;
typedef void* splitmix64_statePtr;
splitmix64_statePtr splitmix64_init(u64 seed);
static inline splitmix64_statePtr splitmix64_initFromTime(void) { return splitmix64_init(time(NULL)); }
u64 splitmix64_next(splitmix64_statePtr);
static inline void splitmix64_free(splitmix64_statePtr state) {
free(state);
}
#if __cplusplus
}
#endif

View File

@ -0,0 +1,35 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../../../base/std.h"
#include "../../splitmix64/splitmix64.h"
typedef union {
u64 merged;
u32 s[2];
} xoroshiro64_state;
typedef void* xoroshiro64_statePtr;
xoroshiro64_statePtr xoroshiro64_init(u64 seed);
#define xoroshiro64star_init xoroshiro64_init
#define xoroshiro64starstar_init xoroshiro64_init
static inline xoroshiro64_statePtr xoroshiro64_initFromTime(void) { return xoroshiro64_init(time(NULL)); }
#define xoroshiro64star_initFromTime xoroshiro64_initFromTime
#define xoroshiro64starstar_initFromTime xoroshiro64_initFromTime
u32 xoroshiro64star_next(xoroshiro64_statePtr);
u32 xoroshiro64starstar_next(xoroshiro64_statePtr);
static inline void xoroshiro64_free(xoroshiro64_statePtr state) {
free(state);
}
#define xoroshiro64star_free xoroshiro64_free
#define xoroshiro64starstar_free xoroshiro64_free
#if __cplusplus
}
#endif

View File

@ -0,0 +1,39 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../../../base/std.h"
#include "../../splitmix64/splitmix64.h"
typedef union {
u32 s[2];
} xoroshiro128_state;
typedef void* xoroshiro128_statePtr;
xoroshiro128_statePtr xoroshiro128_init(u64 seed);
#define xoroshiro128plus_init xoroshiro128_init
#define xoroshiro128plusplus_init xoroshiro128_init
#define xoroshiro128starstar_init xoroshiro128_init
static inline xoroshiro128_statePtr xoroshiro128_initFromTime(void) { return xoroshiro128_init(time(NULL)); }
#define xoroshiro128plus_initFromTime xoroshiro128_initFromTime
#define xoroshiro128plusplus_initFromTime xoroshiro128_initFromTime
#define xoroshiro128starstar_initFromTime xoroshiro128_initFromTime
u64 xoroshiro128plus_next(xoroshiro128_statePtr);
u64 xoroshiro128plusplus_next(xoroshiro128_statePtr);
u64 xoroshiro128starstar_next(xoroshiro128_statePtr);
static inline void xoroshiro128_free(xoroshiro128_statePtr state) {
free(state);
}
#define xoroshiro128plus_free xoroshiro128_free
#define xoroshiro128plusplus_free xoroshiro128_free
#define xoroshiro128starstar_free xoroshiro128_free
#if __cplusplus
}
#endif

View File

@ -0,0 +1,2 @@
#include "32bitValue/xoroshiro64.h"
#include "64bitValue/xoroshiro128.h"

View File

@ -0,0 +1,24 @@
# Xoshiro/Xoroshiro RNG algorithms
There are a bunch of versions of xoshiro/xoroshiro algorithms, which are created by [David Blackman and Sebastiano Vigna](https://prng.di.unimi.it/)
```
xoroshiro
├── 32bitValue
| ├── xoroshiro64star.c
| └── xoroshiro64starstar.c
└── 64bitValue
├── xoroshiro128plus.c
├── xoroshiro128plusplus.c
└── xoroshiro128starstar.c
xoshiro
├── 32bitValue
│ ├── xoshiro128plus.c
│ ├── xoshiro128plusplus.c
│ └── xoshiro128starstar.c
└── 64bitValue
├── xoshiro256plus.c
├── xoshiro256plusplus.c
└── xoshiro256starstar.c
```

View File

@ -0,0 +1,40 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../../../base/std.h"
#include "../../splitmix64/splitmix64.h"
typedef union {
u64 merged[2];
u32 s[4];
} xoshiro128_state;
typedef void* xoshiro128_statePtr;
xoshiro128_statePtr xoshiro128_init(u64 seed);
#define xoshiro128plus_init xoshiro128_init
#define xoshiro128plusplus_init xoshiro128_init
#define xoshiro128starstar_init xoshiro128_init
static inline xoshiro128_statePtr xoshiro128_initFromTime(void) { return xoshiro128_init(time(NULL)); }
#define xoshiro128plus_initFromTime xoshiro128_initFromTime
#define xoshiro128plusplus_initFromTime xoshiro128_initFromTime
#define xoshiro128starstar_initFromTime xoshiro128_initFromTime
u32 xoshiro128plus_next(xoshiro128_statePtr);
u32 xoshiro128plusplus_next(xoshiro128_statePtr);
u32 xoshiro128starstar_next(xoshiro128_statePtr);
static inline void xoshiro128_free(xoshiro128_statePtr state) {
free(state);
}
#define xoshiro128plus_free xoshiro128_free
#define xoshiro128plusplus_free xoshiro128_free
#define xoshiro128starstar_free xoshiro128_free
#if __cplusplus
}
#endif

View File

@ -0,0 +1,39 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../../../base/std.h"
#include "../../splitmix64/splitmix64.h"
typedef union {
u64 s[4];
} xoshiro256_state;
typedef void* xoshiro256_statePtr;
xoshiro256_statePtr xoshiro256_init(u64 seed);
#define xoshiro256plus_init xoshiro256_init
#define xoshiro256plusplus_init xoshiro256_init
#define xoshiro256starstar_init xoshiro256_init
static inline xoshiro256_statePtr xoshiro256_initFromTime(void) { return xoshiro256_init(time(NULL)); }
#define xoshiro256plus_initFromTime xoshiro256_initFromTime
#define xoshiro256plusplus_initFromTime xoshiro256_initFromTime
#define xoshiro256starstar_initFromTime xoshiro256_initFromTime
u64 xoshiro256plus_next(xoshiro256_statePtr);
u64 xoshiro256plusplus_next(xoshiro256_statePtr);
u64 xoshiro256starstar_next(xoshiro256_statePtr);
static inline void xoshiro256_free(xoshiro256_statePtr state) {
free(state);
}
#define xoshiro256plus_free xoshiro256_free
#define xoshiro256plusplus_free xoshiro256_free
#define xoshiro256starstar_free xoshiro256_free
#if __cplusplus
}
#endif

View File

@ -0,0 +1,2 @@
#include "32bitValue/xoshiro128.h"
#include "64bitValue/xoshiro256.h"

View File

@ -1,20 +1,17 @@
#include "CompilationScenario.h" #include "CompilationScenario.h"
#include "unistd.h"
void CompilationScenario_construct(CompilationScenario* ptr){ void CompilationScenario_construct(CompilationScenario* ptr){
ptr->compiler = "UNDEFINED_COMPILER"; ptr->compiler = "UNDEFINED_COMPILER";
ptr->obj_dir = "obj"; ptr->obj_dir = "obj";
ptr->out_dir = "bin"; ptr->out_file = "bin/out";
ptr->args_pre = Autoarr_create(Pointer, 32, 32); ptr->args = Autoarr_create(Pointer, 32, 32);
ptr->sources = Autoarr_create(Pointer, 32, 32); ptr->sources = Autoarr_create(Pointer, 32, 32);
ptr->args_post = Autoarr_create(Pointer, 32, 32);
ptr->defines = Autoarr_create(Pointer, 32, 32);
} }
void CompilationScenario_destruct(CompilationScenario* ptr){ void CompilationScenario_destruct(CompilationScenario* ptr){
Autoarr_freeWithoutMembers(ptr->args_pre, true); Autoarr_freeWithoutMembers(ptr->args, true);
Autoarr_freeWithoutMembers(ptr->sources, true); Autoarr_freeWithoutMembers(ptr->sources, true);
Autoarr_freeWithoutMembers(ptr->args_post, true);
Autoarr_freeWithoutMembers(ptr->defines, true);
} }
#define Dtsod_setStrField(FIELD) \ #define Dtsod_setStrField(FIELD) \
@ -40,11 +37,9 @@ Maybe CompilationScenario_tryApplyOptions(CompilationScenario* sc, Hashtable* dt
Unitype val = UniNull; Unitype val = UniNull;
Dtsod_setStrField(compiler); Dtsod_setStrField(compiler);
Dtsod_setStrField(obj_dir); Dtsod_setStrField(obj_dir);
Dtsod_setStrField(out_dir); Dtsod_setStrField(out_file);
Dtsod_addArrField(args_pre, char); Dtsod_addArrField(args, char);
Dtsod_addArrField(sources, char); Dtsod_addArrField(sources, char);
Dtsod_addArrField(args_post, char);
Dtsod_addArrField(defines, char);
try(CompilationScenario_tryApplyPlatformSpecificOptions(sc, dtsod), _m0, ;); try(CompilationScenario_tryApplyPlatformSpecificOptions(sc, dtsod), _m0, ;);
@ -101,3 +96,34 @@ Maybe CompilationScenario_applyProjectOptions(CompilationScenario* sc, Hashtable
try(CompilationScenario_applyTaskOptions(sc, dtsod, task), _m2, ;); try(CompilationScenario_applyTaskOptions(sc, dtsod, task), _m2, ;);
return MaybeNull; return MaybeNull;
} }
/*
universal compilation:
pre-compilation tools
parallel foreach src
apply proj settings
apply lang settings
apply dir settings
if platform, settings or src were changed
compile object to onj/lang
concurrent add obj to obj_ar
post-compilation tools
example: if linkage enabled
apply proj linker settings
link
post-link tools
move files to general_out_dir
*/
Maybe CompilationScenario_exec(CompilationScenario* sc){
/*const char ** compiler_args;
Autoarr_foreach(sc->sources, arg,
int rzlt = -1;
if(rzlt != 0){
kprintf("\nprocess exited with code %i\n", rzlt);
return false;
}
);*/
return true;
}

View File

@ -1,16 +1,15 @@
#include "../../GraphC/dependencies/kerep/src/DtsodParser/DtsodV24.h" #include "../kerep-headers/DtsodParser/DtsodV24.h"
extern const char* os; extern const char* os;
extern const char* arch; extern const char* arch;
typedef struct { typedef struct {
const char* language;
const char* compiler; const char* compiler;
const char* obj_dir; const char* obj_dir;
const char* out_dir; const char* out_file;
Autoarr(Pointer)* args_pre; Autoarr(Pointer)* args;
Autoarr(Pointer)* sources; Autoarr(Pointer)* sources;
Autoarr(Pointer)* args_post;
Autoarr(Pointer)* defines;
} CompilationScenario; } CompilationScenario;
/* Public Functions */ /* Public Functions */
@ -23,6 +22,10 @@ void CompilationScenario_destruct(CompilationScenario* ptr);
///@return Maybe<void> ///@return Maybe<void>
Maybe CompilationScenario_applyProjectOptions(CompilationScenario* sc, Hashtable* dtsod, const char* configuration, const char* task); Maybe CompilationScenario_applyProjectOptions(CompilationScenario* sc, Hashtable* dtsod, const char* configuration, const char* task);
/// compiles project using given scenario
/// @return Maybe<void>
Maybe CompilationScenario_exec(CompilationScenario* sc);
/* Internal Functions */ /* Internal Functions */

View File

@ -1,6 +1,6 @@
#include "../../GraphC/dependencies/kerep/src/base/base.h" #include "../kerep-headers/base/base.h"
#include "../../GraphC/dependencies/kerep/src/Filesystem/filesystem.h" #include "../kerep-headers/Filesystem/filesystem.h"
#include "../../GraphC/dependencies/kerep/src/DtsodParser/DtsodV24.h" #include "../kerep-headers/DtsodParser/DtsodV24.h"
#include "CompilationScenario.h" #include "CompilationScenario.h"
#ifndef OS #ifndef OS
@ -93,9 +93,11 @@ int main(const int argc, const char** argv){
Hashtable* proj_dtsod = _m3.value.VoidPtr; Hashtable* proj_dtsod = _m3.value.VoidPtr;
CompilationScenario proj_sc; CompilationScenario proj_sc;
CompilationScenario_construct(&proj_sc); CompilationScenario_construct(&proj_sc);
tryLast(CompilationScenario_applyProjectOptions(&proj_sc, proj_dtsod, configuration, task), _m4, free(proj_file_text)) tryLast(CompilationScenario_applyProjectOptions(&proj_sc, proj_dtsod, configuration, task), _m4, free(proj_file_text))
if(!CompilationScenario_exec(&proj_sc))
throw("compilation error");
CompilationScenario_destruct(&proj_sc); CompilationScenario_destruct(&proj_sc);
Hashtable_free(proj_dtsod); Hashtable_free(proj_dtsod);
free(proj_file_text); free(proj_file_text);