diff --git a/kerep-headers/Autoarr/Autoarr.h b/kerep-headers/Autoarr/Autoarr.h new file mode 100644 index 0000000..b059d00 --- /dev/null +++ b/kerep-headers/Autoarr/Autoarr.h @@ -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;blockIblocks_count-1;blockI++) \ + for(u32 elemI=0;elemImax_block_length;elemI++){ \ + elem=ar->values[blockI][elemI]; \ + { codeblock; } \ + } \ + for(u16 elemI=0;elemIblock_length;elemI++){ \ + elem=ar->values[ar->blocks_count-1][elemI]; \ + { codeblock; } \ + } \ + } \ +} + +#if __cplusplus +} +#endif \ No newline at end of file diff --git a/kerep-headers/Autoarr/Autoarr_declare.h b/kerep-headers/Autoarr/Autoarr_declare.h new file mode 100644 index 0000000..d996063 --- /dev/null +++ b/kerep-headers/Autoarr/Autoarr_declare.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/Autoarr/Autoarr_define.h b/kerep-headers/Autoarr/Autoarr_define.h new file mode 100644 index 0000000..a7badc4 --- /dev/null +++ b/kerep-headers/Autoarr/Autoarr_define.h @@ -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; iblocks_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=⪙ \ + 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 + + +## Building on Linux +**Required packages:** gcc + +```bash +make build +```` diff --git a/kerep-headers/Filesystem/dir.h b/kerep-headers/Filesystem/dir.h new file mode 100644 index 0000000..3821229 --- /dev/null +++ b/kerep-headers/Filesystem/dir.h @@ -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 +Maybe dir_create(const char* path); +///@return Maybe +Maybe dir_delete(const char* path); + +///@return Maybe +Maybe dir_getFiles(const char* path, bool recursive); +///@return Maybe +Maybe dir_getDirs(const char* path, bool recursive); + +///@return Maybe +Maybe dir_findFiles(const char* path, char* searchPattern, bool recursive); +///@return Maybe +Maybe dir_findDirs(const char* path, char* searchPattern, bool recursive); + +#if __cplusplus +} +#endif \ No newline at end of file diff --git a/kerep-headers/Filesystem/file.h b/kerep-headers/Filesystem/file.h new file mode 100644 index 0000000..1951c77 --- /dev/null +++ b/kerep-headers/Filesystem/file.h @@ -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 +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 +Maybe file_open(const char* path, FileOpenMode mode); + +/// @brief closes file descriptor +/// @return Maybe +Maybe file_close(FileHandle file); + +/// @brief closes file descriptor +/// @param byte byte to write +/// @return Maybe +Maybe file_writeChar(FileHandle file, char byte); + +/// @brief closes file descriptor +/// @param buffer bytes to write +/// @param length buffer length +/// @return Maybe +Maybe file_writeBuffer(FileHandle file, char* buffer, u64 length); + +/// @brief writes all cstring array content to file +/// @param cptr zero-terminated cstring +/// @return Maybe +Maybe file_writeCptr(FileHandle file, char* cptr); + + +/// @brief reads single byte from file +/// @return Maybe +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 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 total number of successfully read bytes +Maybe file_readAll(FileHandle file, char** allBytes); + +#if __cplusplus +} +#endif \ No newline at end of file diff --git a/kerep-headers/Filesystem/filesystem.h b/kerep-headers/Filesystem/filesystem.h new file mode 100644 index 0000000..9e68038 --- /dev/null +++ b/kerep-headers/Filesystem/filesystem.h @@ -0,0 +1,3 @@ +#include "path.h" +#include "dir.h" +#include "file.h" diff --git a/kerep-headers/Filesystem/io_includes.h b/kerep-headers/Filesystem/io_includes.h new file mode 100644 index 0000000..033adf6 --- /dev/null +++ b/kerep-headers/Filesystem/io_includes.h @@ -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 +#else +#include +#include +#include +#endif diff --git a/kerep-headers/Filesystem/path.h b/kerep-headers/Filesystem/path.h new file mode 100644 index 0000000..65e0f31 --- /dev/null +++ b/kerep-headers/Filesystem/path.h @@ -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 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 +/// @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 +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 \ No newline at end of file diff --git a/kerep-headers/HashFunctions/hash.h b/kerep-headers/HashFunctions/hash.h new file mode 100644 index 0000000..c4b71ef --- /dev/null +++ b/kerep-headers/HashFunctions/hash.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/Hashtable/Hashtable.h b/kerep-headers/Hashtable/Hashtable.h new file mode 100644 index 0000000..726f4b1 --- /dev/null +++ b/kerep-headers/Hashtable/Hashtable.h @@ -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; hrows[h]; \ + Autoarr_foreach(AR, EL, codeblock); \ + } \ +} + +#if __cplusplus +} +#endif \ No newline at end of file diff --git a/kerep-headers/Hashtable/KeyValuePair.h b/kerep-headers/Hashtable/KeyValuePair.h new file mode 100644 index 0000000..99d8117 --- /dev/null +++ b/kerep-headers/Hashtable/KeyValuePair.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/String/StringBuilder.h b/kerep-headers/String/StringBuilder.h new file mode 100644 index 0000000..e860f8e --- /dev/null +++ b/kerep-headers/String/StringBuilder.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/String/string.h b/kerep-headers/String/string.h new file mode 100644 index 0000000..e7cdc26 --- /dev/null +++ b/kerep-headers/String/string.h @@ -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 +string string_reverse(string s); + +#if __cplusplus +} +#endif \ No newline at end of file diff --git a/kerep-headers/base/base.h b/kerep-headers/base/base.h new file mode 100644 index 0000000..cbcb3cf --- /dev/null +++ b/kerep-headers/base/base.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/base/cptr.h b/kerep-headers/base/cptr.h new file mode 100644 index 0000000..509577c --- /dev/null +++ b/kerep-headers/base/cptr.h @@ -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 inclusion in 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 inclusion in 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 inclusion in 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 inclusion in or -1 if not found +i32 cptr_seekCharReverse(const char* src, char fragment, u32 startIndex, u32 seekLength); + +/// @brief search for in +/// @return index of first 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 in +/// @return index of first 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 in +/// @return index of last 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 in +/// @return index of last 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 with replaced by or empty cstring if 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 with replaced by or empty cstring if 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 \ No newline at end of file diff --git a/kerep-headers/base/endian.h b/kerep-headers/base/endian.h new file mode 100644 index 0000000..5863309 --- /dev/null +++ b/kerep-headers/base/endian.h @@ -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 diff --git a/kerep-headers/base/errors.h b/kerep-headers/base/errors.h new file mode 100644 index 0000000..a0e228a --- /dev/null +++ b/kerep-headers/base/errors.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/base/optime.h b/kerep-headers/base/optime.h new file mode 100644 index 0000000..d6a65ae --- /dev/null +++ b/kerep-headers/base/optime.h @@ -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 diff --git a/kerep-headers/base/std.h b/kerep-headers/base/std.h new file mode 100644 index 0000000..816d328 --- /dev/null +++ b/kerep-headers/base/std.h @@ -0,0 +1,135 @@ +#pragma once + +#if __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 \ No newline at end of file diff --git a/kerep-headers/base/type_system/README.md b/kerep-headers/base/type_system/README.md new file mode 100644 index 0000000..c0066e9 --- /dev/null +++ b/kerep-headers/base/type_system/README.md @@ -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) diff --git a/kerep-headers/base/type_system/base_toString.h b/kerep-headers/base/type_system/base_toString.h new file mode 100644 index 0000000..0446ce9 --- /dev/null +++ b/kerep-headers/base/type_system/base_toString.h @@ -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 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 \ No newline at end of file diff --git a/kerep-headers/base/type_system/init.h b/kerep-headers/base/type_system/init.h new file mode 100644 index 0000000..df787ca --- /dev/null +++ b/kerep-headers/base/type_system/init.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/base/type_system/ktDescriptor.h b/kerep-headers/base/type_system/ktDescriptor.h new file mode 100644 index 0000000..189160a --- /dev/null +++ b/kerep-headers/base/type_system/ktDescriptor.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/base/type_system/kt_functions.h b/kerep-headers/base/type_system/kt_functions.h new file mode 100644 index 0000000..435e28f --- /dev/null +++ b/kerep-headers/base/type_system/kt_functions.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/base/type_system/ktid.h b/kerep-headers/base/type_system/ktid.h new file mode 100644 index 0000000..be08484 --- /dev/null +++ b/kerep-headers/base/type_system/ktid.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/base/type_system/type_system.h b/kerep-headers/base/type_system/type_system.h new file mode 100644 index 0000000..28d80e4 --- /dev/null +++ b/kerep-headers/base/type_system/type_system.h @@ -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" diff --git a/kerep-headers/base/type_system/typedef_macros.h b/kerep-headers/base/type_system/typedef_macros.h new file mode 100644 index 0000000..ccaab8d --- /dev/null +++ b/kerep-headers/base/type_system/typedef_macros.h @@ -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); diff --git a/kerep-headers/base/type_system/unitype.h b/kerep-headers/base/type_system/unitype.h new file mode 100644 index 0000000..1fef31f --- /dev/null +++ b/kerep-headers/base/type_system/unitype.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/kprint/README.md b/kerep-headers/kprint/README.md new file mode 100644 index 0000000..0cba7db --- /dev/null +++ b/kerep-headers/kprint/README.md @@ -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 | + +
+ +# 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| kp_fmt, void\*, kp_fmt, void\*... | +| kfprint | Maybe | 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: Maybe: {value: { Pointer, 0x0 }} diff --git a/kerep-headers/kprint/kprint.h b/kerep-headers/kprint/kprint.h new file mode 100644 index 0000000..69cc63c --- /dev/null +++ b/kerep-headers/kprint/kprint.h @@ -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 +#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 +#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 \ No newline at end of file diff --git a/kerep-headers/kprint/kprint_colors.h b/kerep-headers/kprint/kprint_colors.h new file mode 100644 index 0000000..5131651 --- /dev/null +++ b/kerep-headers/kprint/kprint_colors.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/kprint/kprint_format.h b/kerep-headers/kprint/kprint_format.h new file mode 100644 index 0000000..33e8aea --- /dev/null +++ b/kerep-headers/kprint/kprint_format.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/kprint/kprint_format.md b/kerep-headers/kprint/kprint_format.md new file mode 100644 index 0000000..e4d811b --- /dev/null +++ b/kerep-headers/kprint/kprint_format.md @@ -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... | diff --git a/kerep-headers/kprint/kprintf.h b/kerep-headers/kprint/kprintf.h new file mode 100644 index 0000000..d4df677 --- /dev/null +++ b/kerep-headers/kprint/kprintf.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/random/krandom.h b/kerep-headers/random/krandom.h new file mode 100644 index 0000000..2072260 --- /dev/null +++ b/kerep-headers/random/krandom.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/random/splitmix64/splitmix64.h b/kerep-headers/random/splitmix64/splitmix64.h new file mode 100644 index 0000000..3ffeb1a --- /dev/null +++ b/kerep-headers/random/splitmix64/splitmix64.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/random/xoroshiro/32bitValue/xoroshiro64.h b/kerep-headers/random/xoroshiro/32bitValue/xoroshiro64.h new file mode 100644 index 0000000..680a926 --- /dev/null +++ b/kerep-headers/random/xoroshiro/32bitValue/xoroshiro64.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/random/xoroshiro/64bitValue/xoroshiro128.h b/kerep-headers/random/xoroshiro/64bitValue/xoroshiro128.h new file mode 100644 index 0000000..33b7116 --- /dev/null +++ b/kerep-headers/random/xoroshiro/64bitValue/xoroshiro128.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/random/xoroshiro/xoroshiro.h b/kerep-headers/random/xoroshiro/xoroshiro.h new file mode 100644 index 0000000..127c937 --- /dev/null +++ b/kerep-headers/random/xoroshiro/xoroshiro.h @@ -0,0 +1,2 @@ +#include "32bitValue/xoroshiro64.h" +#include "64bitValue/xoroshiro128.h" diff --git a/kerep-headers/random/xoshiro-xoroshiro.md b/kerep-headers/random/xoshiro-xoroshiro.md new file mode 100644 index 0000000..269477c --- /dev/null +++ b/kerep-headers/random/xoshiro-xoroshiro.md @@ -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 +``` diff --git a/kerep-headers/random/xoshiro/32bitValue/xoshiro128.h b/kerep-headers/random/xoshiro/32bitValue/xoshiro128.h new file mode 100644 index 0000000..daf2333 --- /dev/null +++ b/kerep-headers/random/xoshiro/32bitValue/xoshiro128.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/random/xoshiro/64bitValue/xoshiro256.h b/kerep-headers/random/xoshiro/64bitValue/xoshiro256.h new file mode 100644 index 0000000..263d75e --- /dev/null +++ b/kerep-headers/random/xoshiro/64bitValue/xoshiro256.h @@ -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 \ No newline at end of file diff --git a/kerep-headers/random/xoshiro/xoshiro.h b/kerep-headers/random/xoshiro/xoshiro.h new file mode 100644 index 0000000..121ed3a --- /dev/null +++ b/kerep-headers/random/xoshiro/xoshiro.h @@ -0,0 +1,2 @@ +#include "32bitValue/xoshiro128.h" +#include "64bitValue/xoshiro256.h" diff --git a/src/CompilationScenario.c b/src/CompilationScenario.c index 9a1364c..9b27881 100644 --- a/src/CompilationScenario.c +++ b/src/CompilationScenario.c @@ -1,20 +1,17 @@ #include "CompilationScenario.h" +#include "unistd.h" void CompilationScenario_construct(CompilationScenario* ptr){ ptr->compiler = "UNDEFINED_COMPILER"; ptr->obj_dir = "obj"; - ptr->out_dir = "bin"; - ptr->args_pre = Autoarr_create(Pointer, 32, 32); + ptr->out_file = "bin/out"; + ptr->args = 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){ - Autoarr_freeWithoutMembers(ptr->args_pre, true); + Autoarr_freeWithoutMembers(ptr->args, true); Autoarr_freeWithoutMembers(ptr->sources, true); - Autoarr_freeWithoutMembers(ptr->args_post, true); - Autoarr_freeWithoutMembers(ptr->defines, true); } #define Dtsod_setStrField(FIELD) \ @@ -40,11 +37,9 @@ Maybe CompilationScenario_tryApplyOptions(CompilationScenario* sc, Hashtable* dt Unitype val = UniNull; Dtsod_setStrField(compiler); Dtsod_setStrField(obj_dir); - Dtsod_setStrField(out_dir); - Dtsod_addArrField(args_pre, char); + Dtsod_setStrField(out_file); + Dtsod_addArrField(args, char); Dtsod_addArrField(sources, char); - Dtsod_addArrField(args_post, char); - Dtsod_addArrField(defines, char); try(CompilationScenario_tryApplyPlatformSpecificOptions(sc, dtsod), _m0, ;); @@ -101,3 +96,34 @@ Maybe CompilationScenario_applyProjectOptions(CompilationScenario* sc, Hashtable try(CompilationScenario_applyTaskOptions(sc, dtsod, task), _m2, ;); 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; +} diff --git a/src/CompilationScenario.h b/src/CompilationScenario.h index 237f3ae..5f6626e 100644 --- a/src/CompilationScenario.h +++ b/src/CompilationScenario.h @@ -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* arch; typedef struct { + const char* language; const char* compiler; const char* obj_dir; - const char* out_dir; - Autoarr(Pointer)* args_pre; + const char* out_file; + Autoarr(Pointer)* args; Autoarr(Pointer)* sources; - Autoarr(Pointer)* args_post; - Autoarr(Pointer)* defines; } CompilationScenario; /* Public Functions */ @@ -23,6 +22,10 @@ void CompilationScenario_destruct(CompilationScenario* ptr); ///@return Maybe Maybe CompilationScenario_applyProjectOptions(CompilationScenario* sc, Hashtable* dtsod, const char* configuration, const char* task); +/// compiles project using given scenario +/// @return Maybe +Maybe CompilationScenario_exec(CompilationScenario* sc); + /* Internal Functions */ diff --git a/src/cbuilld.c b/src/cbuilld.c index d212346..909d5d4 100644 --- a/src/cbuilld.c +++ b/src/cbuilld.c @@ -1,6 +1,6 @@ -#include "../../GraphC/dependencies/kerep/src/base/base.h" -#include "../../GraphC/dependencies/kerep/src/Filesystem/filesystem.h" -#include "../../GraphC/dependencies/kerep/src/DtsodParser/DtsodV24.h" +#include "../kerep-headers/base/base.h" +#include "../kerep-headers/Filesystem/filesystem.h" +#include "../kerep-headers/DtsodParser/DtsodV24.h" #include "CompilationScenario.h" #ifndef OS @@ -93,8 +93,10 @@ int main(const int argc, const char** argv){ Hashtable* proj_dtsod = _m3.value.VoidPtr; CompilationScenario proj_sc; CompilationScenario_construct(&proj_sc); - 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); Hashtable_free(proj_dtsod);