Merge branch 'main' into 'network'

This commit is contained in:
2024-01-01 19:46:52 +06:00
117 changed files with 2676 additions and 1451 deletions

View File

@@ -2,15 +2,26 @@
Array_define(char)
Array_define(bool)
Array_define(float32)
Array_define(float64)
Array_define(int8)
Array_define(uint8)
Array_define(int16)
Array_define(uint16)
Array_define(int32)
Array_define(uint32)
Array_define(int64)
Array_define(uint64)
Array_define(f32)
Array_define(f64)
Array_define(i8)
Array_define(u8)
Array_define(i16)
Array_define(u16)
Array_define(i32)
Array_define(u32)
Array_define(i64)
Array_define(u64)
Array_define(Pointer)
Array_define(Unitype)
void Array_Unitype_free_(Array_Unitype* array, bool freeMembers){
if(freeMembers) for (u32 i=0; i<array->length; i++)
Unitype_free(array->values[i]);
if(array->allocatedOnHeap)
free(array->values);
}
void __Array_Unitype_free_(void* ar)
{ Array_Unitype_free_(ar, true); }

View File

@@ -9,19 +9,24 @@ extern "C" {
Array_declare(char)
Array_declare(bool)
Array_declare(float32)
Array_declare(float64)
Array_declare(int8)
Array_declare(uint8)
Array_declare(int16)
Array_declare(uint16)
Array_declare(int32)
Array_declare(uint32)
Array_declare(int64)
Array_declare(uint64)
Array_declare(f32)
Array_declare(f64)
Array_declare(i8)
Array_declare(u8)
Array_declare(i16)
Array_declare(u16)
Array_declare(i32)
Array_declare(u32)
Array_declare(i64)
Array_declare(u64)
Array_declare(Pointer)
Array_declare(Unitype)
/// use this function instead of auto generated
void Array_Unitype_free_(Array_Unitype* array, bool freeMembers);
void __Array_Unitype_free_(void* ar);
#if __cplusplus
}
#endif

View File

@@ -6,34 +6,32 @@ extern "C" {
#include "../base/base.h"
#define Array_declare(type)\
typedef struct Array_##type{\
type* values;\
uint32 length;\
bool allocatedOnHeap;\
} Array_##type;\
#define Array_declare(type) \
STRUCT(Array_##type, \
type* values; \
u32 length; \
bool allocatedOnHeap; \
) \
\
ktid_declare(Array_##type);\
static inline Array_##type Array_##type##_allocValues(u32 length){ \
return (Array_##type) { \
.values=(type*)malloc(sizeof(type)*length), \
.length=length, \
.allocatedOnHeap=true \
}; \
} \
\
static inline Array_##type Array_##type##_allocValues(uint32 length){\
return (Array_##type) {\
.values=(type*)malloc(sizeof(type)*length),\
.length=length,\
.allocatedOnHeap=true\
};\
}\
static inline Array_##type Array_##type##_fromBuffer(type* buffer, u32 bufferLength, bool allocatedOnHeap){ \
return (Array_##type) { \
.values=buffer, \
.length=bufferLength, \
.allocatedOnHeap=allocatedOnHeap \
}; \
} \
\
static inline Array_##type Array_##type##_fromBuffer(type* buffer, uint32 bufferLength, bool allocatedOnHeap){\
return (Array_##type) {\
.values=buffer,\
.length=bufferLength,\
.allocatedOnHeap=allocatedOnHeap\
};\
}\
\
static inline void Array_##type##_freeValues(Array_##type* array){\
if(array->allocatedOnHeap)\
free(array->values);\
static inline void Array_##type##_free(Array_##type* array){ \
if(array->allocatedOnHeap) \
free(array->values); \
}
#if __cplusplus

View File

@@ -6,8 +6,8 @@ extern "C" {
#include "../base/base.h"
#define Array_define(type)\
ktid_define(Array_##type);
#define Array_define(type) \
kt_define(Array_##type, (freeMembers_t)Array_##type##_free, NULL);
#if __cplusplus
}

View File

@@ -1,14 +1,17 @@
#include "Autoarr.h"
Autoarr_define(char)
Autoarr_define(bool)
Autoarr_define(float32)
Autoarr_define(float64)
Autoarr_define(uint8)
Autoarr_define(int8)
Autoarr_define(uint16)
Autoarr_define(int16)
Autoarr_define(uint32)
Autoarr_define(int32)
Autoarr_define(uint64)
Autoarr_define(int64)
Autoarr_define(Pointer, true)
Autoarr_define(char, false)
Autoarr_define(bool, false)
Autoarr_define(f32, false)
Autoarr_define(f64, false)
Autoarr_define(u8, false)
Autoarr_define(i8, false)
Autoarr_define(u16, false)
Autoarr_define(i16, false)
Autoarr_define(u32, false)
Autoarr_define(i32, false)
Autoarr_define(u64, false)
Autoarr_define(i64, false)
Autoarr_define(Unitype, false)

View File

@@ -6,21 +6,37 @@ extern "C" {
#include "Autoarr_declare.h"
#include "Autoarr_define.h"
#include "Autoarr_Unitype.h"
Autoarr_declare(Pointer)
Autoarr_declare(char)
Autoarr_declare(bool)
Autoarr_declare(float32)
Autoarr_declare(float64)
Autoarr_declare(int8)
Autoarr_declare(uint8)
Autoarr_declare(int16)
Autoarr_declare(uint16)
Autoarr_declare(int32)
Autoarr_declare(uint32)
Autoarr_declare(int64)
Autoarr_declare(uint64)
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
}

View File

@@ -5,7 +5,7 @@ extern "C" {
#include "Autoarr.h"
#include "../Hashtable/KeyValuePair.h"
EXPORT void CALL kerep_Autoarr_KVPair_create(uint16 max_blocks_count, uint16 max_block_length, Autoarr_KVPair** output){
EXPORT void CALL kerep_Autoarr_KVPair_create(u16 max_blocks_count, u16 max_block_length, Autoarr_KVPair** output){
*output=Autoarr_create(KVPair, max_blocks_count, max_block_length);
}
@@ -13,7 +13,7 @@ EXPORT void CALL kerep_Autoarr_KVPair_free(Autoarr_KVPair* ar){
Autoarr_free(ar, true);
}
EXPORT void CALL kerep_Autoarr_KVPair_get(Autoarr_KVPair* ar, uint32 index, KVPair* output){
EXPORT void CALL kerep_Autoarr_KVPair_get(Autoarr_KVPair* ar, u32 index, KVPair* output){
*output=Autoarr_get(ar, index);
}
@@ -21,15 +21,15 @@ EXPORT void CALL kerep_Autoarr_KVPair_add(Autoarr_KVPair* ar, KVPair element){
Autoarr_add(ar, element);
}
EXPORT void CALL kerep_Autoarr_KVPair_set(Autoarr_KVPair* ar, uint32 index, KVPair element){
EXPORT void CALL kerep_Autoarr_KVPair_set(Autoarr_KVPair* ar, u32 index, KVPair element){
Autoarr_set(ar, index, element);
}
EXPORT void CALL kerep_Autoarr_KVPair_length(Autoarr_KVPair* ar, uint32* output){
EXPORT void CALL kerep_Autoarr_KVPair_length(Autoarr_KVPair* ar, u32* output){
*output=Autoarr_length(ar);
}
EXPORT void CALL kerep_Autoarr_KVPair_max_length(Autoarr_KVPair* ar, uint32* output){
EXPORT void CALL kerep_Autoarr_KVPair_max_length(Autoarr_KVPair* ar, u32* output){
*output=Autoarr_max_length(ar);
}

View File

@@ -1,12 +0,0 @@
#include "Autoarr.h"
Autoarr_define(Unitype);
// right func to clear array of unitype values
void __Autoarr_free_Unitype_(Autoarr(Unitype)* ar, bool freePtr){
Autoarr_foreach(ar, u,Unitype_free(u));
__Autoarr_free_Unitype(ar, freePtr);
}
void ____Autoarr_free_Unitype_(void* ar) {
__Autoarr_free_Unitype_((Autoarr(Unitype)*)ar, false);
}

View File

@@ -1,33 +0,0 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "Autoarr_declare.h"
#include "Autoarr_define.h"
Autoarr_declare(Unitype)
// this function is injected in kerep_init()
void __Autoarr_free_Unitype_(Autoarr(Unitype)* ar, bool freePtr);
void ____Autoarr_free_Unitype_(void* ar);
#define Autoarr_foreach(ar,elem,codeblock)({\
if(ar->blocks_count>0) {\
typeof(**ar->values) elem;\
for(uint32 blockI=0;blockI<ar->blocks_count-1;blockI++)\
for(uint32 elemI=0;elemI<ar->max_block_length;elemI++){\
elem=ar->values[blockI][elemI];\
(codeblock);\
}\
for(uint32 elemI=0;elemI<ar->block_length;elemI++){\
elem=ar->values[ar->blocks_count-1][elemI];\
(codeblock);\
}\
}\
})
#if __cplusplus
}
#endif

View File

@@ -4,7 +4,7 @@ extern "C" {
#include "Autoarr.h"
EXPORT void CALL kerep_Autoarr_Unitype_create(uint16 max_blocks_count, uint16 max_block_length, Autoarr_Unitype** output){
EXPORT void CALL kerep_Autoarr_Unitype_create(u16 max_blocks_count, u16 max_block_length, Autoarr_Unitype** output){
*output=Autoarr_create(Unitype, max_blocks_count, max_block_length);
}
@@ -12,7 +12,7 @@ EXPORT void CALL kerep_Autoarr_Unitype_free(Autoarr_Unitype* ar){
Autoarr_free(ar, true);
}
EXPORT void CALL kerep_Autoarr_Unitype_get(Autoarr_Unitype* ar, uint32 index, Unitype* output){
EXPORT void CALL kerep_Autoarr_Unitype_get(Autoarr_Unitype* ar, u32 index, Unitype* output){
*output=Autoarr_get(ar, index);
}
@@ -20,15 +20,15 @@ EXPORT void CALL kerep_Autoarr_Unitype_add(Autoarr_Unitype* ar, Unitype element)
Autoarr_add(ar, element);
}
EXPORT void CALL kerep_Autoarr_Unitype_set(Autoarr_Unitype* ar, uint32 index, Unitype element){
EXPORT void CALL kerep_Autoarr_Unitype_set(Autoarr_Unitype* ar, u32 index, Unitype element){
Autoarr_set(ar, index, element);
}
EXPORT void CALL kerep_Autoarr_Unitype_length(Autoarr_Unitype* ar, uint32* output){
EXPORT void CALL kerep_Autoarr_Unitype_length(Autoarr_Unitype* ar, u32* output){
*output=Autoarr_length(ar);
}
EXPORT void CALL kerep_Autoarr_Unitype_max_length(Autoarr_Unitype* ar, uint32* output){
EXPORT void CALL kerep_Autoarr_Unitype_max_length(Autoarr_Unitype* ar, u32* output){
*output=Autoarr_max_length(ar);
}

View File

@@ -6,64 +6,67 @@ extern "C" {
#include "../base/base.h"
#define Autoarr_declare(type)\
#define Autoarr_declare(type) \
\
struct Autoarr_##type;\
struct Autoarr_##type; \
\
typedef struct {\
void (*add)(struct Autoarr_##type* ar, type element);\
type (*get)(struct Autoarr_##type* ar, uint32 index);\
type* (*getptr)(struct Autoarr_##type* ar, uint32 index);\
void (*set)(struct Autoarr_##type* ar, uint32 index, type element);\
void (*freear)(struct Autoarr_##type* ar, bool freePtr);\
type* (*toArray)(struct Autoarr_##type* ar);\
} __functions_list_t_##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; \
\
typedef struct Autoarr_##type{\
uint16 blocks_count;\
uint16 max_blocks_count;\
uint16 block_length;\
uint16 max_block_length;\
type** values;\
__functions_list_t_##type* functions;\
} Autoarr_##type;\
extern __Autoarr_##type##_functions_list_t __Autoarr_##type##_functions_list; \
\
ktid_declare(Autoarr_##type);\
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_create_##type(uint16 max_blocks_count, uint16 max_block_length);\
void __Autoarr_free_##type(Autoarr_##type* ar, bool freePtr);\
void ____Autoarr_free_##type(void* ar);
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_create_##type(max_blocks_count, max_block_length)
#define Autoarr_add(autoarr, element)\
#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)\
#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)\
#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->freear(autoarr, freePtr)
#define Autoarr_toArray(autoarr)\
#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) \
(uint32)(!autoarr->blocks_count ? 0 : \
(u32)(!autoarr->blocks_count ? 0 : \
autoarr->max_block_length*(autoarr->blocks_count-1)+autoarr->block_length)
#define Autoarr_max_length(autoarr)\
(uint32)(autoarr->max_block_length*autoarr->max_blocks_count)
#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--;\
#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

View File

@@ -6,79 +6,93 @@ extern "C" {
#include "../base/base.h"
#define Autoarr_define(type)\
#define Autoarr_define(type, TYPE_IS_PTR) \
\
ktid_define(Autoarr_##type);\
kt_define(Autoarr_##type, ____Autoarr_##type##_freeWithMembers, NULL); \
\
void __Autoarr_add_##type(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++;\
}\
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_get_##type(Autoarr_##type* ar, uint32 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##_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_getptr_##type(Autoarr_##type* ar, uint32 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_set_##type(Autoarr_##type* ar, uint32 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##_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_free_##type(Autoarr_##type* ar, bool freePtr){\
for(uint16 i=0; i<ar->blocks_count;i++)\
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_free_##type(void* ar){\
__Autoarr_free_##type((Autoarr_##type*)ar, false);\
}\
free(ar->values); \
if(freePtr) free(ar); \
} \
\
type* __Autoarr_toArray_##type(Autoarr_##type* ar){\
uint32 length=Autoarr_length(ar);\
type* array=malloc(length * sizeof(type));\
for(uint32 i=0; i<length; i++)\
array[i]=__Autoarr_get_##type(ar, i);\
return array;\
}\
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); \
} \
\
__functions_list_t_##type __functions_list_##type={\
&__Autoarr_add_##type,\
&__Autoarr_get_##type,\
&__Autoarr_getptr_##type,\
&__Autoarr_set_##type,\
&__Autoarr_free_##type,\
&__Autoarr_toArray_##type\
};\
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* __Autoarr_create_##type(uint16 max_blocks_count, uint16 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=&__functions_list_##type\
};\
return ar;\
__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

View File

@@ -12,13 +12,13 @@ void DtsodV24_addOrSet(Hashtable* dtsod, char* key, Unitype value){
// checks for dtsod contains value or dont
bool DtsodV24_contains(Hashtable* dtsod, char* key){
Unitype* val=Hashtable_getptr(dtsod, key);
Unitype* val=Hashtable_getPtr(dtsod, key);
return val!=NULL;
}
// replaces value with UniNull if key exists in dtsod
bool DtsodV24_remove(Hashtable* dtsod, char* key){
Unitype* val=Hashtable_getptr(dtsod, key);
Unitype* val=Hashtable_getPtr(dtsod, key);
if (!val) return false;
*val=UniNull;
return true;

View File

@@ -18,17 +18,17 @@ typedef struct DeserializeSharedData{
// special func for throwing error messages about wrong characters in deserializing text
Maybe ERROR_WRONGCHAR(const char c, char* _text, char* text_first, const char* srcfile, int line, const char* funcname){
Maybe ERROR_WRONGCHAR(const char c, char* _text, char* text_first, const char* srcfile, i32 line, const char* funcname){
char errBuf[68];
for(uint8 n=0; n<sizeof(errBuf);n++)
for(u8 n=0; n<sizeof(errBuf);n++)
errBuf[n]='\0';
char* errText=_text-32;
uint8 cplace=32;
u8 cplace=32;
if(errText<text_first) {
cplace=_text-text_first;
errText=text_first;
}
uint8 i=0;
u8 i=0;
for(; i<cplace; i++){
// writes 32 chars before the wrongchar
errBuf[i]=errText[i];
@@ -154,10 +154,10 @@ Maybe __ReadList(DeserializeSharedData* shared){
Autoarr(Unitype)* list=Autoarr_create(Unitype,ARR_BC,ARR_BL);
bool readingList=true;
while (true){
try(ReadValue((&readingList)), val, Autoarr_free(list, true))
Autoarr_add(list,val.value);
try(ReadValue((&readingList)), m_val, Autoarr_free(list, true))
Autoarr_add(list,m_val.value);
if (!readingList){
if(val.value.typeId==ktid_Null)
if(Unitype_isUniNull(m_val.value))
Autoarr_pop(list);
break;
}
@@ -188,7 +188,7 @@ Maybe __ParseValue(DeserializeSharedData* shared, string str){
}
// UInt64
case 'u': {
uint64 lu=0;
u64 lu=0;
char* _c=string_extract(str);
if(sscanf(_c, IFWIN("%llu", "%lu"), &lu)!=1){
char err[64];
@@ -204,7 +204,7 @@ Maybe __ParseValue(DeserializeSharedData* shared, string str){
// Int64
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': {
int64 li=0;
i64 li=0;
char* _c=string_extract(str);
if(sscanf(_c, IFWIN("%lli", "%li"), &li)!=1){
char err[64];
@@ -272,10 +272,12 @@ Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList){
case ']':
if(!readingList) safethrow_wrongchar(c,Unitype_free(value));
*readingList=false;
goto return_value;
case ';':
case ',':
return_value:
if(valueStr.length!=0){
if(value.typeId!=ktid_Null)
if(!Unitype_isUniNull(value))
safethrow_wrongchar(c,Unitype_free(value));
try(ParseValue(valueStr),maybeParsed,;)
value=maybeParsed.value;
@@ -316,8 +318,11 @@ Maybe __deserialize(char** _text, bool _calledRecursively) {
partOfDollarList=false;
Autoarr(Unitype)* list;
Unitype lu;
if(Hashtable_try_get(dict,nameCPtr, &lu)){
if(Hashtable_tryGet(dict,nameCPtr, &lu)){
list=(Autoarr(Unitype)*)lu.VoidPtr;
// Key is not used in that case, because it is already added
// to the table with the first dollar list item.
free(nameCPtr);
}
else{
list=Autoarr_create(Unitype,ARR_BC,ARR_BL);

View File

@@ -49,11 +49,11 @@ EXPORT void CALL kerep_DtsodV24_free(Hashtable* dtsod){
DtsodV24_free(dtsod);
}
EXPORT void CALL kerep_DtsodV24_height(Hashtable* dtsod, uint16* heigth){
EXPORT void CALL kerep_DtsodV24_height(Hashtable* dtsod, u16* heigth){
*heigth=Hashtable_height(dtsod);
}
EXPORT void CALL kerep_DtsodV24_getrow(Hashtable* dtsod, uint16 h, Autoarr_KVPair** row){
EXPORT void CALL kerep_DtsodV24_getrow(Hashtable* dtsod, u16 h, Autoarr_KVPair** row){
*row=dtsod->rows[h];
}

View File

@@ -2,20 +2,20 @@
#include "../String/StringBuilder.h"
typedef struct SerializeSharedData{
STRUCT(SerializeSharedData,
StringBuilder* sh_builder;
uint8 sh_tabs;
} SerializeSharedData;
u8 sh_tabs;
)
#define b shared->sh_builder
#define tabs shared->sh_tabs
Maybe __serialize(StringBuilder* _b, uint8 _tabs, Hashtable* dtsod);
Maybe __serialize(StringBuilder* _b, u8 _tabs, Hashtable* dtsod);
#define addc(C) StringBuilder_append_char(b,C)
void __AppendTabs(SerializeSharedData* shared) {
for (uint8 t = 0; t < tabs; t++)
for (u8 t = 0; t < tabs; t++)
addc( '\t');
};
#define AppendTabs() __AppendTabs(shared)
@@ -23,15 +23,15 @@ void __AppendTabs(SerializeSharedData* shared) {
Maybe __AppendValue(SerializeSharedData* shared, Unitype u);
#define AppendValue(UNI) __AppendValue(shared, UNI)
Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
if(u.typeId==ktid_name(int64)){
StringBuilder_append_int64(b,u.Int64);
if(u.typeId==ktid_name(i64)){
StringBuilder_append_i64(b,u.Int64);
}
else if(u.typeId==ktid_name(uint64)){
StringBuilder_append_uint64(b,u.UInt64);
else if(u.typeId==ktid_name(u64)){
StringBuilder_append_u64(b,u.UInt64);
addc('u');
}
else if(u.typeId==ktid_name(float64)){
StringBuilder_append_float64(b,u.Float64);
else if(u.typeId==ktid_name(f64)){
StringBuilder_append_f64(b,u.Float64);
addc('f');
}
else if(u.typeId==ktid_ptrName(char)){
@@ -46,7 +46,7 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
else if(u.typeId==ktid_name(bool)){
StringBuilder_append_cptr(b, u.Bool ? "true" : "false");
}
else if(u.typeId==ktid_Null){
else if(Unitype_isUniNull(u)){
safethrow("Null isn't supported in DtsodV24",;);
}
else if(u.typeId==ktid_ptrName(Autoarr_Unitype)){
@@ -55,12 +55,12 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
AppendTabs();
addc('[');
tabs++;
Autoarr_foreach(((Autoarr_Unitype*)(u.VoidPtr)), e, ({
Autoarr_foreach(((Autoarr_Unitype*)(u.VoidPtr)), e,
addc('\n');
AppendTabs();
try(AppendValue(e),__,;);
addc(',');
}));
);
StringBuilder_rmchar(b);
addc('\n');
tabs--;
@@ -75,11 +75,11 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
else if(u.typeId==ktid_ptrName(Hashtable)){
// check hashtable is blank
bool hashtableNotBlank=false;
Hashtable_foreach(((Hashtable*)u.VoidPtr), __, ({
Hashtable_foreach(((Hashtable*)u.VoidPtr), __,
hashtableNotBlank=true;
if(__.key); // weird way to disable warning
if(__.key) {} // weird way to disable warning
break;
}));
);
if(hashtableNotBlank){
addc('\n');
@@ -102,14 +102,14 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
return MaybeNull;
};
Maybe __serialize(StringBuilder* _b, uint8 _tabs, Hashtable* dtsod){
Maybe __serialize(StringBuilder* _b, u8 _tabs, Hashtable* dtsod){
SerializeSharedData _shared={
.sh_builder=_b,
.sh_tabs=_tabs
};
SerializeSharedData* shared=&_shared;
Hashtable_foreach(dtsod, p, ({
Hashtable_foreach(dtsod, p,
AppendTabs();
StringBuilder_append_cptr(b,p.key);
addc(':');
@@ -117,7 +117,7 @@ Maybe __serialize(StringBuilder* _b, uint8 _tabs, Hashtable* dtsod){
try(AppendValue(p.value),__,;);
addc(';');
addc('\n');
}));
);
return MaybeNull;
}

View File

@@ -1 +1,69 @@
#include "dir.h"
#include "filesystem.h"
#include "io_includes.h"
#include "../kprint/kprint.h"
bool dir_exists(const char* path){
if(path[0]=='.'){
if(path[1]==0 || (path[1]==path_sep && path[1]==0))
return true; // dir . or ./ always exists
// else if(path[1]=='.' && path[2]==path_sep)
//TODO path_resolve because windows doesnt recognize .\ pattern
}
#if KFS_USE_WINDOWS_H
DWORD dwAttrib = GetFileAttributes(path);
return (bool)(
(dwAttrib != INVALID_FILE_ATTRIBUTES) && // file exists
(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); // file is a directory
#else
struct stat stats;
i32 rez=stat(path, &stats);
return (bool)(
(rez!=-1) && // file exists
(S_ISDIR(stats.st_mode))); // file is a directory
#endif
}
Maybe dir_create(const char* path){
if (dir_exists(path))
return MaybeNull;
char* parentDir=path_parentDir(path);
dir_create(parentDir);
free(parentDir);
#if KFS_USE_WINDOWS_H
if(!CreateDirectory(path, NULL))
#else
if(mkdir(path, 0777) == -1)
#endif
{
char err[512];
IFWIN(
sprintf_s(err, 512, "can't create dicectory <%s>", path),
sprintf(err, "can't create dicectory <%s>", path));
safethrow(err,;);
}
return MaybeNull;
}
Maybe dir_delete(const char* path){
throw(ERR_NOTIMPLEMENTED);
return MaybeNull;
}
Maybe dir_getFiles(const char* path, bool recursive){
throw(ERR_NOTIMPLEMENTED);
return MaybeNull;
}
Maybe dir_getDirs(const char* path, bool recursive){
throw(ERR_NOTIMPLEMENTED);
return MaybeNull;
}
Maybe dir_findFiles(const char* path, char* searchPattern, bool recursive){
throw(ERR_NOTIMPLEMENTED);
return MaybeNull;
}
Maybe dir_findDirs(const char* path, char* searchPattern, bool recursive){
throw(ERR_NOTIMPLEMENTED);
return MaybeNull;
}

View File

@@ -7,11 +7,21 @@ extern "C" {
#include "../base/base.h"
#include "file.h"
typedef char* DirPath;
Array_declare(DirPath);
bool dir_exists(const char* path);
///@return Maybe<void>
Maybe dir_create(const char* path);
///@return Maybe<void>
Maybe dir_delete(const char* path);
Array_FilePath dir_getFiles(DirPath path);
Array_FilePath dir_findFiles(DirPath path, FilePath searchPattern);
///@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
}

View File

@@ -1,7 +1,37 @@
#include "file.h"
#include "filesystem.h"
#include "../String/StringBuilder.h"
#include "io_includes.h"
ktid_define(File);
void __file_freeMembers(void* _f){ fclose((FileHandle)_f); }
kt_define(FileHandle, __file_freeMembers, NULL)
bool file_exists(const char* path){
if(path[0]=='.'){
if(path[1]==0 || (path[1]==path_sep && path[2]==0))
return false; // . or ./ is not a file
// else if(path[1]=='.' && path[2]==path_sep)
//TODO path_resolve because windows doesnt recognize .\ pattern
}
#if KFS_USE_WINDOWS_H
DWORD dwAttrib = GetFileAttributes(path);
return (bool)(
(dwAttrib != INVALID_FILE_ATTRIBUTES) && // file exists
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); // file is not directory
#else
struct stat stats;
i32 rez=stat(path, &stats);
return (bool)(
(rez!=-1) && // file exists
!(S_ISDIR(stats.st_mode))); // file is not directory
#endif
}
Maybe file_delete(const char* path, bool recursive){
throw(ERR_NOTIMPLEMENTED);
return MaybeNull;
}
char* FileOpenMode_toStr(FileOpenMode m){
char* p;
@@ -18,14 +48,14 @@ char* FileOpenMode_toStr(FileOpenMode m){
return p;
}
Maybe file_open(FilePath path, FileOpenMode mode){
File* file=fopen(path, FileOpenMode_toStr(mode));
Maybe file_open(const char* path, FileOpenMode mode){
FileHandle file=fopen(path, FileOpenMode_toStr(mode));
if(!file)
safethrow(cptr_concat("can't open file ", (char*)path),;);
return SUCCESS(UniHeapPtr(File,file));
return SUCCESS(UniHeapPtr(FileHandle,file));
}
Maybe file_close(File* file){
Maybe file_close(FileHandle file){
if(!file)
safethrow(ERR_NULLPTR,;);
if(fclose(file))
@@ -33,43 +63,43 @@ Maybe file_close(File* file){
return MaybeNull;
}
#define ioWriteCheck()\
if(rezult==EOF)\
safethrow(ERR_IO_EOF,;);\
if(rezult!=0)\
#define ioWriteCheck() \
if(rezult==EOF) \
safethrow(ERR_IO_EOF,;); \
if(rezult!=0) \
safethrow(ERR_IO,;);
Maybe file_writeChar(File* file, char byte){
int rezult=fputc(byte, file);
Maybe file_writeChar(FileHandle file, char byte){
i32 rezult=fputc(byte, file);
ioWriteCheck();
return MaybeNull;
}
Maybe file_writeBuffer(File* file, char* buffer, uint64 length){
int rezult=0;
for(uint64 i=0; i<length && !rezult; i++)
Maybe file_writeBuffer(FileHandle file, char* buffer, u64 length){
i32 rezult=0;
for(u64 i=0; i<length && !rezult; i++)
rezult=fputc(buffer[i], file);
ioWriteCheck();
return MaybeNull;
}
Maybe file_writeCptr(File* file, char* cptr){
int rezult=fputs(cptr, file);
Maybe file_writeCptr(FileHandle file, char* cptr){
i32 rezult=fputs(cptr, file);
ioWriteCheck();
return MaybeNull;
}
Maybe file_readChar(File* file){
int rezult=fgetc(file);
Maybe file_readChar(FileHandle file){
i32 rezult=fgetc(file);
if(feof(file)) safethrow(ERR_IO_EOF,;);
if(ferror(file)) safethrow(ERR_IO,;);
return SUCCESS(UniUInt64(rezult));
}
Maybe file_readBuffer(File* file, char* buffer, uint64 length){
int rezult=0;
uint64 i=0;
Maybe file_readBuffer(FileHandle file, char* buffer, u64 length){
i32 rezult=0;
u64 i=0;
for(; i<length && rezult!=EOF; i++){
rezult=fgetc(file);
buffer[i]=(char)rezult;
@@ -78,20 +108,20 @@ Maybe file_readBuffer(File* file, char* buffer, uint64 length){
return SUCCESS(UniUInt64(i));
}
Maybe file_readAll(File* file, char** allBytes){
int rezult=0;
Maybe file_readAll(FileHandle file, char** allBytes){
i32 rezult=0;
char buffer[256];
string bufStr={.ptr=buffer, .length=sizeof(buffer)};
StringBuilder* sb=StringBuilder_create();
uint64 i=0;
u64 i=0;
while(true){
rezult=fgetc(file);
if(rezult!=EOF){
if(rezult==EOF){
if(ferror(file))
safethrow(ERR_IO,; StringBuilder_free(sb));
safethrow(ERR_IO, StringBuilder_free(sb));
break;
}
buffer[i]=(char)rezult;
buffer[i%sizeof(buffer)]=(char)rezult;
i++;
if(!(i%sizeof(buffer)))
StringBuilder_append_string(sb,bufStr);

View File

@@ -8,12 +8,15 @@ extern "C" {
#include "../Array/Array.h"
#include "../String/string.h"
typedef char* FilePath;
Array_declare(FilePath);
typedef FILE File;
ktid_declare(File);
typedef FILE* FileHandle;
kt_declare(FileHandle);
PACK_ENUM(FileOpenMode,
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
@@ -24,50 +27,49 @@ PACK_ENUM(FileOpenMode,
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<File*>
Maybe file_open(FilePath path, FileOpenMode mode);
/// @return Maybe<FileHandle>
Maybe file_open(const char* path, FileOpenMode mode);
/// @brief closes file descriptor
/// @return Maybe<void>
Maybe file_close(File* file);
Maybe file_close(FileHandle file);
/// @brief closes file descriptor
/// @param byte byte to write
/// @return Maybe<void>
Maybe file_writeChar(File* file, char byte);
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(File* file, char* buffer, uint64 length);
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(File* file, char* cptr);
Maybe file_writeCptr(FileHandle file, char* cptr);
/// @brief reads single byte from file
/// @return Maybe<char>
Maybe file_readChar(File* file);
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<uint64> total number of successfully read bytes (<=length)
Maybe file_readBuffer(File* file, char* buffer, uint64 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<uint64> total number of successfully read bytes
Maybe file_readAll(File* file, char** allBytes);
/// @return Maybe<u64> total number of successfully read bytes
Maybe file_readAll(FileHandle file, char** allBytes);
#if __cplusplus
}

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

@@ -1,16 +1,16 @@
#include "filesystem.h"
char* __path_concat(uint16 n, ...){
char* __path_concat(u32 n, ...){
char** parts=(char**)malloc(n*sizeof(char*));
uint32* lengths=malloc(n*sizeof(uint32));
uint32 totalLength=0;
u32* lengths=malloc(n*sizeof(u32));
u32 totalLength=0;
// reading args from va_list
va_list vl;
va_start(vl, n);
for(uint16 i=0; i<n; i++){
for(u16 i=0; i<n; i++){
char* part=va_arg(vl,char*);
int16 length=cptr_length(part);
i16 length=cptr_length(part);
parts[i]=part;
lengths[i]=length;
totalLength+=length;
@@ -23,7 +23,7 @@ char* __path_concat(uint16 n, ...){
totality[totalLength]=0;
// copying content of all strings to rezult
uint16 k=0;
u16 k=0;
for(; k<n-1; k++){
memcopy(parts[k], totality, lengths[k]);
totality+=lengths[k];
@@ -37,7 +37,7 @@ char* __path_concat(uint16 n, ...){
return output;
}
char* path_fixSeparators(char* path){
char* path_fixSeparators(const char* path){
char* pathCopy=cptr_copy(path);
char c;
while((c=*pathCopy)){
@@ -48,8 +48,37 @@ char* path_fixSeparators(char* path){
return pathCopy;
}
Maybe path_throwIfEscapes(char* path){
Maybe path_throwIfEscapes(const char* path){
if(cptr_contains(path,".."))
safethrow(cptr_concat("path <",path,"> uses <..>, that's not allowed"),);
return MaybeNull;
}
char* path_parentDir(char* dir){
char* copy=cptr_copy(dir);
i32 length=cptr_length(copy);
i32 i=cptr_lastIndexOfChar(copy,path_sep);
if(i!=-1 && i==length-1){
copy[length-1]=0;
i=cptr_lastIndexOfChar(copy,path_sep);
}
if(i==-1){
free(copy);
copy=malloc(2);
copy[0]='.';
copy[1]=0;
}
return copy;
}
char* path_basename(char* path, bool with_extension){
i32 nameIndex=cptr_lastIndexOfChar(path, path_sep)+1;
string rezult=string_fromCptr(path+nameIndex);
if(!with_extension){
i32 extIndex=cptr_lastIndexOfChar(rezult.ptr, '.');
if(extIndex!=0 && extIndex!=-1)
rezult.length=extIndex;
}
return string_extract(rezult);
}

View File

@@ -14,22 +14,28 @@ static const char path_sep='/';
static const char path_notSep='\\';
#endif
char* __path_concat(uint16 n, ...);
/// @brief merges path parts together and places <path_sep> between them
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(char* path);
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(char* path);
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
}

View File

@@ -1,14 +1,14 @@
#include "hash.h"
uint32 hash_sdbm32(uint32 oldhash, void* buf, uint32 len){
uint8* ubuf=(uint8*)buf;
register uint32 hash=oldhash;
u32 hash_sdbm32(u32 oldhash, void* buf, u32 len){
u8* ubuf=(u8*)buf;
register u32 hash=oldhash;
for (; len ; len--, ubuf++)
hash=(hash<<6)+(hash<<16)-hash+*ubuf;
return hash;
}
static const uint32 crc_32_tab[]={
static const u32 crc_32_tab[]={
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
@@ -75,19 +75,19 @@ static const uint32 crc_32_tab[]={
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
uint32 hash_crc32(uint32 oldhash, void* buf, uint32 len){
uint8* ubuf=(uint8*)buf;
register uint32 crc=oldhash;
u32 hash_crc32(u32 oldhash, void* buf, u32 len){
u8* ubuf=(u8*)buf;
register u32 crc=oldhash;
for (; len; --len, ++ubuf)
crc=crc_32_tab[(crc^(*ubuf)) & 0xff] ^ (crc>>8);
return ~crc;
}
// bool hashf_crc32c(char *name, uint32 *crc, long *charcnt) {
// bool hashf_crc32c(char *name, u32 *crc, long *charcnt) {
// register FILE *fin;
// register uint32 oldcrc32;
// register int c;
// register u32 oldcrc32;
// register i32 c;
// oldcrc32 = 0xFFFFFFFF; *charcnt = 0;
// if ((fin=fopen(name, "r"))==NULL) {

View File

@@ -9,8 +9,8 @@ extern "C" {
#define hashb(FUNC, BUF, LEN) FUNC(0xFFFFFFFF, BUF, LEN)
#define hashs(FUNC, STR) FUNC(0xFFFFFFFF, STR, cptr_length(STR))
uint32 hash_sdbm32(uint32 oldhash, void* buf, uint32 len);
uint32 hash_crc32(uint32 oldhash, void* buf, uint32 len);
u32 hash_sdbm32(u32 oldhash, void* buf, u32 len);
u32 hash_crc32(u32 oldhash, void* buf, u32 len);
#if __cplusplus
}

View File

@@ -1,9 +1,9 @@
#include "Hashtable.h"
ktid_define(Hashtable);
kt_define(Hashtable, __Hashtable_free, NULL);
// amount of rows
static const uint16 HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521};
static const u16 HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521};
#define HT_HEIN_MIN 0
#define HT_HEIN_MAX 6
@@ -14,14 +14,14 @@ Hashtable* Hashtable_create(){
Hashtable* ht=malloc(sizeof(Hashtable));
ht->hein=HT_HEIN_MIN;
ht->rows=malloc(HT_HEIGHTS[HT_HEIN_MIN]*sizeof(Autoarr(KVPair)*));
for(uint16 i=0;i<HT_HEIGHTS[HT_HEIN_MIN];i++)
for(u16 i=0;i<HT_HEIGHTS[HT_HEIN_MIN];i++)
ht->rows[i]=Autoarr_create(KVPair,ARR_BC,ARR_BL);
return ht;
}
void __Hashtable_free(void* _ht){
Hashtable* ht=_ht;
for(uint16 i=0;i<HT_HEIGHTS[ht->hein];i++)
for(u16 i=0;i<HT_HEIGHTS[ht->hein];i++)
Autoarr_free(ht->rows[i], true);
free(ht->rows);
}
@@ -30,27 +30,28 @@ void Hashtable_free(Hashtable* ht){
free(ht);
}
uint16 Hashtable_height(Hashtable* ht) { return HT_HEIGHTS[ht->hein]; }
u16 Hashtable_height(Hashtable* ht) { return HT_HEIGHTS[ht->hein]; }
void Hashtable_expand(Hashtable* ht){
if(ht->hein>=HT_HEIN_MAX) throw(ERR_MAXLENGTH);
Autoarr(KVPair)** newrows=malloc(HT_HEIGHTS[++ht->hein]*sizeof(Autoarr(KVPair)*));
for(uint16 i=0;i<HT_HEIGHTS[ht->hein];i++)
for(u16 i=0;i<HT_HEIGHTS[ht->hein];i++)
newrows[i]=Autoarr_create(KVPair,ARR_BC,ARR_BL);
for(uint16 i=0;i<HT_HEIGHTS[ht->hein-1];i++){
for(u16 i=0;i<HT_HEIGHTS[ht->hein-1];i++){
Autoarr(KVPair)* ar=ht->rows[i];
uint32 arlen=Autoarr_length(ar);
for(uint32 k=0;k<arlen;k++){
u32 arlen=Autoarr_length(ar);
for(u32 k=0;k<arlen;k++){
KVPair p=Autoarr_get(ar,k);
uint16 newrown=hashs(hash_sdbm32, p.key)%HT_HEIGHTS[ht->hein];
u16 newrown=hashs(hash_sdbm32, p.key)%HT_HEIGHTS[ht->hein];
Autoarr(KVPair)* newar=newrows[newrown];
Autoarr_add(newar,p);
}
// there is no need to free array values, because they are copied into new array
__Autoarr_free_KVPair(ar, true);
// so dont replace this incorrect auto-generated function
Autoarr_freeWithoutMembers(ar, true);
}
free(ht->rows);
@@ -58,7 +59,7 @@ void Hashtable_expand(Hashtable* ht){
}
Autoarr(KVPair)* getrow(Hashtable* ht, char* key, bool can_expand){
uint32 hash=hashs(hash_sdbm32, key);
u32 hash=hashs(hash_sdbm32, key);
Autoarr(KVPair)* ar=ht->rows[hash%HT_HEIGHTS[ht->hein]];
if(can_expand && Autoarr_length(ar)==Autoarr_max_length(ar))
Hashtable_expand(ht);
@@ -66,40 +67,67 @@ Autoarr(KVPair)* getrow(Hashtable* ht, char* key, bool can_expand){
return ar;
}
/// @param key must be heap allocated
/// Hashtable_free will free this pointer
void Hashtable_add(Hashtable* ht, char* key, Unitype u){
KVPair p={ .key=key, .value=u };
Autoarr_add(getrow(ht,key,true),p);
}
void Hashtable_addMany(Hashtable* ht, KVPair* pair_array, u32 count){
for(u32 i=0; i<count; i++){
Hashtable_add(ht, pair_array[i].key, pair_array[i].value);
}
}
// returns null or pointer to value in hashtable
Unitype* Hashtable_getptr(Hashtable* ht, char* key){
Unitype* Hashtable_getPtr(Hashtable* ht, char* key){
Autoarr(KVPair)* ar=getrow(ht,key,false);
uint32 arlen=Autoarr_length(ar);
for(uint32 i=0;i<arlen;i++){
KVPair* p=Autoarr_getptr(ar,i);
if(cptr_compare(key,p->key)) return &p->value;
u32 arlen=Autoarr_length(ar);
for(u32 i=0;i<arlen;i++){
KVPair* p=Autoarr_getPtr(ar,i);
if(cptr_equals(key,p->key)) return &p->value;
}
return NULL;
}
Unitype Hashtable_get(Hashtable* ht, char* key){
Autoarr(KVPair)* ar=getrow(ht,key,false);
uint32 arlen=Autoarr_length(ar);
for(uint32 i=0;i<arlen;i++){
u32 arlen=Autoarr_length(ar);
for(u32 i=0;i<arlen;i++){
KVPair p=Autoarr_get(ar,i);
if(cptr_compare(key,p.key)) return p.value;
if(cptr_equals(key,p.key)) return p.value;
}
return UniNull;
}
bool Hashtable_try_get(Hashtable* ht, char* key, Unitype* output){
bool Hashtable_tryGet(Hashtable* ht, char* key, Unitype* output){
Unitype u=Hashtable_get(ht,key);
*output=u;
return u.typeId!=ktid_Null;
return !Unitype_isUniNull(u);
}
bool Hashtable_trySet(Hashtable* ht, char* key, Unitype u){
Unitype* val=Hashtable_getPtr(ht,key);
if(val==NULL)
return false;
*val=u;
return true;
}
bool Hashtable_tryAdd(Hashtable* ht, char* key, Unitype u){
Unitype* val=Hashtable_getPtr(ht,key);
if(val==NULL){
Hashtable_add(ht, key, u);
return true;
}
return false;
}
void Hashtable_addOrSet(Hashtable* ht, char* key, Unitype u){
Unitype* val=Hashtable_getptr(ht, key);
if(val) *val=u;
else Hashtable_add(ht, key, u);
Unitype* val=Hashtable_getPtr(ht, key);
if(val==NULL)
Hashtable_add(ht, key, u); // add
else *val=u; // set
}

View File

@@ -4,21 +4,21 @@
extern "C" {
#endif
#include "../base/base.h"
#include "../HashFunctions/hash.h"
#include "KeyValuePair.h"
typedef struct Hashtable{
uint8 hein; // height=HT_HEIGHTS[hein]
STRUCT(Hashtable,
u8 hein; // height=HT_HEIGHTS[hein]
Autoarr(KVPair)** rows; // Autoarr[height]
} Hashtable;
ktid_declare(Hashtable);
)
Hashtable* Hashtable_create();
void Hashtable_free(Hashtable* ht);
void __Hashtable_free(void* ht);
// amount of rows
uint16 Hashtable_height(Hashtable* ht);
u16 Hashtable_height(Hashtable* ht);
// don't add pairs with the same keys,
// or something weird will happen
@@ -26,20 +26,23 @@ uint16 Hashtable_height(Hashtable* ht);
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_getPtr(Hashtable* ht, char* key);
Unitype Hashtable_get(Hashtable* ht, char* key);
bool Hashtable_try_get(Hashtable* ht, char* key, Unitype* output);
bool Hashtable_tryGet(Hashtable* ht, char* key, Unitype* output);
#define Hashtable_foreach(HT, EL, codeblock)({\
uint16 hmax=Hashtable_height(HT);\
for(uint16 h=0; h<hmax; h++){\
Autoarr(KVPair)* AR=HT->rows[h];\
Autoarr_foreach(AR, EL, codeblock);\
}\
})
#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
}

View File

@@ -1,25 +1,16 @@
#include "KeyValuePair.h"
ktid_define(KVPair);
kt_define(KVPair, __KVPair_free, NULL);
Autoarr_define(KVPair)
Autoarr_define(KVPair, false)
// proper way to clear a KVP
// proper way to clean a KVP
void KVPair_free(KVPair p){
free(p.key);
Unitype_free(p.value);
}
void __KVPair_free(void* p){ KVPair_free(*(KVPair*)p); }
// func for KVP array clearing
void __Autoarr_free_KVPair_(Autoarr_KVPair* ar, bool freePtr){
Autoarr_foreach(ar,k,KVPair_free(k));
__Autoarr_free_KVPair(ar, freePtr);
}
void ____Autoarr_free_KVPair_(void* ar){
__Autoarr_free_KVPair_((Autoarr_KVPair*)ar, false);
}
void printkvp(KVPair p){
kprintf("{\"%s\", ",p.key);
printuni(p.value);

View File

@@ -7,22 +7,17 @@ extern "C" {
#include "../base/base.h"
#include "../Autoarr/Autoarr.h"
typedef struct KVPair{
STRUCT(KVPair,
char* key;
Unitype value;
} KVPair;
ktid_declare(KVPair);
)
Autoarr_declare(KVPair)
// proper way to clear a KVP
// proper way to clean a KVP
void KVPair_free(KVPair p);
void __KVPair_free(void* p);
// func to clear KVP array
void __Autoarr_free_KVPair_(Autoarr_KVPair* ar, bool freePtr);
void ____Autoarr_free_KVPair_(void* ar);
void printkvp(KVPair p);
#if __cplusplus

View File

@@ -0,0 +1,68 @@
#include "LinkedList.h"
LinkedList_define(Pointer, true)
void LinkedList_addToBeginning(void* _llist, void* _new_node) {
LinkedList(Pointer)* llist=_llist;
LLNode(Pointer)* new_node=_new_node;
llist->count++;
if(llist->last_node==NULL){
if(llist->first_node!=NULL)
throw(ERR_NULLPTR); // last_node can't be null if first_node != null
llist->last_node=new_node;
}
else {
llist->first_node->prev=new_node;
new_node->next=llist->first_node;
}
llist->first_node=new_node;
}
void LinkedList_addToEnd(void* _llist, void* _new_node) {
LinkedList(Pointer)* llist=_llist;
LLNode(Pointer)* new_node=_new_node;
llist->count++;
if(llist->first_node==NULL) {
if(llist->last_node!=NULL)
throw(ERR_NULLPTR); // first_node can't be null if last_node != null
llist->first_node=new_node;
}
else {
llist->last_node->next=new_node;
new_node->prev=llist->last_node;
}
llist->last_node=new_node;
}
static inline void _insertNode(LinkedList(Pointer)* llist,
LLNode(Pointer)* prev_node, LLNode(Pointer)* new_node, LLNode(Pointer)* next_node){
if(prev_node==NULL){
if(next_node==llist->first_node)
LinkedList_addToBeginning(llist, new_node);
else throw(ERR_NULLPTR); // prev_node is null, but it isn't insertion before first_node
}
else if(next_node==NULL){
if(prev_node==llist->last_node)
LinkedList_addToEnd(llist, new_node);
else throw(ERR_NULLPTR); // next_node is null, but it isn't insertion after last_node
}
else {
prev_node->next=new_node;
new_node->prev=prev_node;
new_node->next=next_node;
next_node->prev=new_node;
llist->count++;
}
}
void LinkedList_insertPrev(void* _llist, void* _new_node, void* _next_node){
LLNode(Pointer)* next_node=_next_node;
LLNode(Pointer)* prev_node=next_node->prev;
_insertNode(_llist, prev_node, _new_node, next_node);
}
void LinkedList_insertNext(void* _llist, void* _new_node, void* _prev_node){
LLNode(Pointer)* prev_node=_prev_node;
LLNode(Pointer)* next_node=prev_node->next;
_insertNode(_llist, prev_node, _new_node, next_node);
}

View File

@@ -0,0 +1,83 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../base/base.h"
#include "LinkedList_declare.h"
#include "LinkedList_define.h"
// LinkedListNode
#define LLNode(TYPE) LLNode_##TYPE
#define LinkedList(TYPE) LinkedList_##TYPE
#define LLNode_create(TYPE, VALUE) LLNode_##TYPE##_create(VALUE)
#define LinkedList_create(TYPE) LinkedList_##TYPE##_create()
#define LinkedList_free(LLIST) ({ LLIST->_functions->freeMembers(LLIST); free(LLIST); })
void LinkedList_addToBeginning(void* _llist, void* _new_node);
void LinkedList_addToEnd(void* _llist, void* _new_node);
/// inserts NEW_NODE before NEXT_NODE in LLIST
void LinkedList_insertPrev(void* _llist, void* _new_node, void* _next_node);
/// inserts NEW_NODE after PREV_NODE in LLIST
void LinkedList_insertNext(void* _llist, void* _new_node, void* _prev_node);
/// removes node before NEXT_NODE in LLIST
/// if FREE_REMOVED then frees removed node
#define LinkedList_removePrev(LLIST, NEXT_NODE, FREE_REMOVED) LLIST->_functions->removePrev(LLIST, NEXT_NODE, FREE_REMOVED)
/// removes node after PREV_NODE in LLIST
/// if FREE_REMOVED then frees removed node
#define LinkedList_removeNext(LLIST, PREV_NODE, FREE_REMOVED) LLIST->_functions->removeNext(LLIST, PREV_NODE, FREE_REMOVED)
///@param FIRST_N first node in enumeration
///@param CURR_N name of iteration variable
///@param CODE code todo in every iteration
#define LLNode_foreach(FIRST_N, CURR_N, CODE...) { \
typeof(FIRST_N) CURR_N=FIRST_N; \
typeof(FIRST_N) NEXT_N=FIRST_N; \
while(CURR_N!=NULL) { \
NEXT_N=CURR_N->next; \
CODE; \
CURR_N=NEXT_N; \
} \
}
///@param FIRST_N first node in enumeration
///@param CURR_N name of iteration variable
///@param CODE code todo in every iteration
#define LLNode_foreachReverse(FIRST_N, CURR_N, CODE...) { \
typeof(FIRST_N) CURR_N=FIRST_N; \
typeof(FIRST_N) PREV_N=FIRST_N; \
while(CURR_N!=NULL) { \
PREV_N=CURR_N->prev; \
CODE; \
CURR_N=PREV_N; \
} \
}
///@param LLIST LinkedList
///@param CURR_N name of iteration variable
///@param CODE code todo in every iteration
#define LinkedList_foreach(LLIST, CURR_N, CODE...) \
LLNode_foreach(LLIST->first_node, CURR_N, CODE)
///@param LLIST LinkedList
///@param CURR_N name of iteration variable
///@param CODE code todo in every iteration
#define LinkedList_foreachReverse(LLIST, CURR_N, CODE...) \
LLNode_foreachReverse(LLIST->last_node, CURR_N, CODE)
LinkedList_declare(Pointer)
#if __cplusplus
}
#endif

View File

@@ -0,0 +1,42 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#define LLNode_declare(TYPE)\
STRUCT(LLNode(TYPE), \
LLNode(TYPE)* prev; \
LLNode(TYPE)* next; \
TYPE value; \
) \
\
LLNode(TYPE)* LLNode_##TYPE##_create(TYPE value); \
void LLNode_##TYPE##_free(LLNode(TYPE)* node, bool free_value);
#define LinkedList_declare(TYPE)\
LLNode_declare(TYPE) \
typedef struct LinkedList_##TYPE##_functions_t LinkedList_##TYPE##_functions_t; \
\
STRUCT(LinkedList(TYPE), \
LinkedList_##TYPE##_functions_t* _functions; \
LLNode(TYPE)* first_node; \
LLNode(TYPE)* last_node; \
u32 count; \
) \
\
typedef struct LinkedList_##TYPE##_functions_t { \
freeMembers_t freeMembers; \
void (*removePrev)(LinkedList(TYPE)* llist, LLNode(TYPE)* nextNode, bool freeRemoved); \
void (*removeNext)(LinkedList(TYPE)* llist, LLNode(TYPE)* prevNode, bool freeRemoved); \
} LinkedList_##TYPE##_functions_t; \
\
extern LinkedList_##TYPE##_functions_t _LinkedList_##TYPE##_functions; \
\
LinkedList(TYPE)* LinkedList_##TYPE##_create(); \
#if __cplusplus
}
#endif

View File

@@ -0,0 +1,82 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#define LLNode_define(TYPE, TYPE_IS_PTR)\
\
LLNode(TYPE)* LLNode_##TYPE##_create(TYPE value){ \
LLNode(TYPE)* node= (LLNode(TYPE)*)malloc(sizeof(*node)); \
node->prev=NULL; \
node->next=NULL; \
node->value=value; \
return node; \
} \
\
void LLNode_##TYPE##_freeMembers(void* _node){ \
LLNode(TYPE)* node=(LLNode(TYPE)*)_node; \
void* value_ptr=&node->value; \
if(TYPE_IS_PTR) value_ptr=*(TYPE**)value_ptr; \
ktDescriptor_##TYPE.freeMembers(value_ptr); \
} \
\
void LLNode_##TYPE##_free(LLNode(TYPE)* node, bool free_value){ \
if(free_value) LLNode_##TYPE##_freeMembers(node); \
free(node); \
} \
\
kt_define(LLNode_##TYPE, LLNode_##TYPE##_freeMembers, NULL)
#define LinkedList_define(TYPE, VALUE_IS_PTR)\
LLNode_define(TYPE, VALUE_IS_PTR) \
\
LinkedList(TYPE)* LinkedList_##TYPE##_create(){ \
LinkedList(TYPE)* l=malloc(sizeof(*l)); \
l->_functions=&_LinkedList_##TYPE##_functions; \
l->first_node=NULL; \
l->last_node=NULL; \
l->count=0; \
return l; \
} \
\
void LinkedList_##TYPE##_freeMembers(void* _l){ \
LinkedList(TYPE)* l=(LinkedList(TYPE)*)_l; \
if(l->first_node!=NULL) \
LinkedList_foreach(l, node, LLNode_##TYPE##_free(node, true)); \
l->first_node=NULL; l->last_node=NULL; l->count=0; \
} \
\
void LinkedList_##TYPE##_removePrev(LinkedList(TYPE)* llist, LLNode(TYPE)* nextNode, bool freeRemoved){ \
llist->count--; \
LLNode(TYPE)* removedNode=nextNode->prev; \
LLNode(TYPE)* prevNode=removedNode->prev; \
nextNode->prev=prevNode; \
prevNode->next=nextNode; \
if(freeRemoved) \
LLNode_##TYPE##_free(removedNode, true); \
} \
\
void LinkedList_##TYPE##_removeNext(LinkedList(TYPE)* llist, LLNode(TYPE)* prevNode, bool freeRemoved){ \
llist->count--; \
LLNode(TYPE)* removedNode=prevNode->next; \
LLNode(TYPE)* nextNode=removedNode->next; \
prevNode->next=nextNode; \
nextNode->prev=prevNode; \
if(freeRemoved) \
LLNode_##TYPE##_free(removedNode, true); \
} \
\
LinkedList_##TYPE##_functions_t _LinkedList_##TYPE##_functions={ \
.freeMembers=LinkedList_##TYPE##_freeMembers, \
.removePrev=LinkedList_##TYPE##_removePrev, \
.removeNext=LinkedList_##TYPE##_removeNext \
}; \
\
kt_define(LinkedList_##TYPE, LinkedList_##TYPE##_freeMembers, NULL)
#if __cplusplus
}
#endif

View File

@@ -6,11 +6,11 @@ ktid_define(knIPV4Endpoint);
Maybe knIPV4Address_fromStr(char* addrStr){
char* addrStr_src=addrStr;
char* errmsg_extra="wrong char";
uint8 c;
u8 c;
knIPV4Address addr;
addr.u32=0;
uint16 n=0;
for(uint8 i=0; i<4; ){
u16 n=0;
for(u8 i=0; i<4; ){
c=*addrStr++;
switch (c){
case '\0':
@@ -18,6 +18,10 @@ Maybe knIPV4Address_fromStr(char* addrStr){
errmsg_extra="end of string";
goto default_case;
}
addr.bytes[i++]=n;
n=0;
break;
case '.':
addr.bytes[i++]=n;
n=0;
@@ -32,7 +36,7 @@ Maybe knIPV4Address_fromStr(char* addrStr){
break;
default_case:
default:
uint32 errmsgL=cptr_length(addrStr) + 80;
u32 errmsgL=cptr_length(addrStr) + 80;
char* errmsg=malloc(errmsgL);
IFMSC(sprintf_s(errmsg, errmsgL, "wrong ip address string: %s\n %s", addrStr_src, errmsg_extra),
sprintf( errmsg, "wrong ip address string: %s\n %s", addrStr_src, errmsg_extra));

View File

@@ -7,10 +7,10 @@ extern "C" {
#include "../base/base.h"
typedef uint16 knPort;
typedef u16 knPort;
typedef union knIPV4Address {
uint32 u32;
u32 u32;
char bytes[4];
} knIPV4Address;
ktid_declare(knIPV4Address);

View File

@@ -38,7 +38,7 @@ knChannel* __createChannel(){
Maybe knSocketChanneled_createChannel(knSocketChanneled* socket){
if(socket->channelsAmount == 65535)
safethrow("max amount of channels",;);
uint16 channelsAmountPrev=socket->channelsAmount;
u16 channelsAmountPrev=socket->channelsAmount;
socket->channelsAmount++;
if(channelsAmountPrev==0)
socket->channels=malloc(sizeof(knChannel*));
@@ -54,6 +54,6 @@ Maybe knSocketChanneled_connect(knSocketChanneled* socket, knIPV4Endpoint remote
Maybe knSocketChanneled_accept(knSocketChanneled* socket);
Maybe knSocketChanneled_send(knSocketChanneled* socket, uint16 destinationIndex, uint8* data, uint32 dataLength);
Maybe knSocketChanneled_send(knSocketChanneled* socket, u16 destinationIndex, u8* data, u32 dataLength);
Maybe knSocketChanneled_recieve(knSocketChanneled* socket, uint16 destinationIndex, uint8* buffer, uint32 bufferLength);
Maybe knSocketChanneled_recieve(knSocketChanneled* socket, u16 destinationIndex, u8* buffer, u32 bufferLength);

View File

@@ -7,7 +7,7 @@ extern "C" {
#include "../../base/base.h"
#include "../knAddress.h"
#define KNPAC_MAX_DATA_SIZE (65535-sizeof(knPackage)+sizeof(uint8*))
#define KNPAC_MAX_DATA_SIZE (65535-sizeof(knPackage)+sizeof(u8*))
typedef enum __attribute__((__packed__)) knPacVersion {
@@ -19,11 +19,11 @@ static const char knPacHeader[5]={'k','n','p','a','c'};
typedef struct knPackage {
char header[5]; // knpac
knPacVersion version; // protocol version
uint16 data_size; // size of data block in bytes (1-KNPAC_MAX_DATA_SIZE)
uint32 channel_id; // id of knChannel in socket
uint32 package_num; // number in sequence of sent packages
uint64 data_hash; // hash64 of data
uint8* data; // ptr to data
u16 data_size; // size of data block in bytes (1-KNPAC_MAX_DATA_SIZE)
u32 channel_id; // id of knChannel in socket
u32 package_num; // number in sequence of sent packages
u64 data_hash; // hash64 of data
u8* data; // ptr to data
} knPackage;
ktid_declare(knPackage);
@@ -41,10 +41,10 @@ typedef struct knChannel {
ktid_declare(knChannel);
typedef struct knSocketChanneled{
int64 socketfd;
i64 socketfd;
knIPV4Endpoint localEndpoint;
knIPV4Endpoint remoteEndpoint;
uint16 channelsAmount;
u16 channelsAmount;
knChannel** channels;
} knSocketChanneled;
ktid_declare(knSocketChanneled);
@@ -56,7 +56,7 @@ Maybe knSocketChanneled_open();
///@return Maybe<void> error or nothing
Maybe knSocketChanneled_close(knSocketChanneled* socket);
///@return Maybe<uint64> channel index
///@return Maybe<u64> channel index
Maybe knSocketChanneled_createChannel(knSocketChanneled* socket);
///start listening at local endpoint
@@ -72,12 +72,12 @@ Maybe knSocketChanneled_accept(knSocketChanneled* socket);
///@param dataLength 0-4294967295
///@return Maybe<void>
Maybe knSocketChanneled_send(knSocketChanneled* socket, uint16 destinationIndex, uint8* data, uint32 dataLength);
Maybe knSocketChanneled_send(knSocketChanneled* socket, u16 destinationIndex, u8* data, u32 dataLength);
///@param buffer buffer for recieving data
///@param bufferLength 0-4294967295
///@return Maybe<uint64> recieved bytes amount
Maybe knSocketChanneled_recieve(knSocketChanneled* socket, uint16 destinationIndex, uint8* buffer, uint32 bufferLength);
///@return Maybe<u64> recieved bytes amount
Maybe knSocketChanneled_recieve(knSocketChanneled* socket, u16 destinationIndex, u8* buffer, u32 bufferLength);
#if __cplusplus
}

View File

@@ -65,9 +65,9 @@ Maybe knSocketTCP_accept(knSocketTCP* socket);
///@param dataLength 0-4294967295
///@return Maybe<void>
Maybe knSocketTCP_send(knSocketTCP* socket, char* data, uint32 dataLength);
Maybe knSocketTCP_send(knSocketTCP* socket, char* data, u32 dataLength);
///@param buffer buffer for recieving data
///@param bufferLength 0-4294967295
///@return Maybe<uint64> recieved bytes amount
Maybe knSocketTCP_recieve(knSocketTCP* socket, char* buffer, uint32 bufferLength);
///@return Maybe<u64> recieved bytes amount
Maybe knSocketTCP_recieve(knSocketTCP* socket, char* buffer, u32 bufferLength);

View File

@@ -8,7 +8,7 @@ extern "C" {
#include "../knAddress.h"
typedef struct knSocketTCP {
int64 socketfd;
i64 socketfd;
knIPV4Endpoint localEndpoint;
knIPV4Endpoint remoteEndpoint;
} knSocketTCP;
@@ -33,12 +33,12 @@ Maybe knSocketTCP_accept(knSocketTCP* socket);
///@param dataLength 0-4294967295
///@return Maybe<void>
Maybe knSocketTCP_send(knSocketTCP* socket, char* data, uint32 dataLength);
Maybe knSocketTCP_send(knSocketTCP* socket, char* data, u32 dataLength);
///@param buffer buffer for recieving data
///@param bufferLength 0-4294967295
///@return Maybe<uint64> recieved bytes amount
Maybe knSocketTCP_recieve(knSocketTCP* socket, char* buffer, uint32 bufferLength);
///@return Maybe<u64> recieved bytes amount
Maybe knSocketTCP_recieve(knSocketTCP* socket, char* buffer, u32 bufferLength);
#if __cplusplus
}

View File

@@ -21,9 +21,9 @@ Maybe knSocketUDP_accept(knSocketUDP* socket);
///@param dataLength 0-4294967295
///@return Maybe<void>
Maybe knSocketUDP_sendto(knSocketUDP* socket, char* data, uint32 dataLength, knIPV4Endpoint destination);
Maybe knSocketUDP_sendto(knSocketUDP* socket, char* data, u32 dataLength, knIPV4Endpoint destination);
///@param buffer buffer for recieving data
///@param bufferLength 0-4294967295
///@return Maybe<uint64> recieved bytes amount
Maybe knSocketUDP_recieve(knSocketUDP* socket, char* buffer, uint32 bufferLength);
///@return Maybe<u64> recieved bytes amount
Maybe knSocketUDP_recieve(knSocketUDP* socket, char* buffer, u32 bufferLength);

View File

@@ -7,7 +7,7 @@ extern "C" {
#include "knSocketUDP.h"
typedef struct knSocketUDP {
int64 socketfd;
i64 socketfd;
knIPV4Endpoint localEndpoint;
} knSocketUDP;
ktid_declare(knSocketUDP);
@@ -27,12 +27,12 @@ Maybe knSocketUDP_accept(knSocketUDP* socket);
///@param dataLength 0-4294967295
///@return Maybe<void>
Maybe knSocketUDP_sendto(knSocketUDP* socket, char* data, uint32 dataLength, knIPV4Endpoint destination);
Maybe knSocketUDP_sendto(knSocketUDP* socket, char* data, u32 dataLength, knIPV4Endpoint destination);
///@param buffer buffer for recieving data
///@param bufferLength 0-4294967295
///@return Maybe<uint64> recieved bytes amount
Maybe knSocketUDP_recieve(knSocketUDP* socket, char* buffer, uint32 bufferLength);
///@return Maybe<u64> recieved bytes amount
Maybe knSocketUDP_recieve(knSocketUDP* socket, char* buffer, u32 bufferLength);
#if __cplusplus

View File

@@ -1,12 +1,11 @@
#include "SearchTree.h"
ktid_define(STNode);
kt_define(STNode, __STNode_free, NULL);
STNode* STNode_create(){
STNode* node=malloc(sizeof(STNode));
node->branches=NULL;
node->value.typeId=ktid_Null;
node->value.UInt64=0;
node->value=UniNull;
return node;
}
@@ -14,13 +13,13 @@ void __STNode_free(void* _node){
STNode* node=_node;
if (!node) throw(ERR_NULLPTR);
if(node->branches){
for(uint8 n32 = 0;n32<8;n32++){
for(u8 n32 = 0;n32<8;n32++){
STNode*** ptrn32=(STNode***)node->branches[n32];
if(ptrn32){
for(uint8 n4 = 0;n4<8;n4++){
for(u8 n4 = 0;n4<8;n4++){
STNode** ptrn4=ptrn32[n4];
if (ptrn4){
for(uint8 rem=0;rem<4;rem++){
for(u8 rem=0;rem<4;rem++){
STNode* ptrrem=ptrn4[rem];
if(ptrrem)
STNode_free(ptrrem);
@@ -41,9 +40,9 @@ void STNode_free(STNode* node){
free(node);
}
typedef struct {uint8 n32, n4, rem;} indexes3;
typedef struct {u8 n32, n4, rem;} indexes3;
indexes3 splitindex(uint8 i){
indexes3 splitindex(u8 i){
return (indexes3){
.n32=i/32,
.n4=i%32/4,
@@ -60,20 +59,20 @@ void ST_pushString(STNode* node_first, string key, Unitype value){
if (!node_first) throw(ERR_NULLPTR);
STNode* node_last=node_first;
while(key.length--){
indexes3 i3=splitindex((uint8)*key.ptr);
indexes3 i3=splitindex((u8)*key.ptr);
if(!node_last->branches){
node_last->branches=(STNode****)malloc(8*sizeof(STNode***));
for(uint8 i=0;i<8;i++)
for(u8 i=0;i<8;i++)
node_last->branches[i]=(STNode***)NULL;
}
if(!node_last->branches[i3.n32]){
node_last->branches[i3.n32]=(STNode***)malloc(8*sizeof(STNode**));
for(uint8 i=0;i<8;i++)
for(u8 i=0;i<8;i++)
node_last->branches[i3.n32][i]=(STNode**)NULL;
}
if(!node_last->branches[i3.n32][i3.n4]){
node_last->branches[i3.n32][i3.n4]=(STNode**)malloc(4*sizeof(STNode*));
for(uint8 i=0;i<4;i++)
for(u8 i=0;i<4;i++)
node_last->branches[i3.n32][i3.n4][i]=(STNode*)NULL;
}
if(!node_last->branches[i3.n32][i3.n4][i3.rem])
@@ -93,7 +92,7 @@ Unitype ST_pullString(STNode* node_first, string key){
if (!node_first) throw(ERR_NULLPTR);
STNode* node_last=node_first;
while (key.length--){
indexes3 i3=splitindex((uint8)*key.ptr);
indexes3 i3=splitindex((u8)*key.ptr);
if(!node_last->branches) return UniNull;
STNode*** ptrn32=(STNode***)node_last->branches[i3.n32];
if(!ptrn32) return UniNull;

View File

@@ -7,11 +7,10 @@ extern "C" {
#include "../base/base.h"
#include "../String/string.h"
typedef struct SearchTreeNode{
struct SearchTreeNode**** branches; // *STNode[8][8][4]
STRUCT(STNode,
struct STNode**** branches; // *STNode[8][8][4]
Unitype value;
} STNode;
ktid_declare(STNode);
)
STNode* STNode_create();
void STNode_free(STNode* node);

View File

@@ -1,8 +1,6 @@
#include "StringBuilder.h"
Autoarr_define(string)
ktid_define(StringBuilder);
kt_define(StringBuilder, __StringBuilder_free, NULL);
#define BL_C 32
#define BL_L 1024
@@ -11,16 +9,16 @@ ktid_define(StringBuilder);
void complete_buf(StringBuilder* b){
if(!b->compl_bufs)
b->compl_bufs=Autoarr_create(string,BL_C,BL_L);
uint32 len=Autoarr_length(b->curr_buf);
u32 len=Autoarr_length(b->curr_buf);
if(!len) return;
string str={.length=len, .ptr=malloc(len)};
uint32 i=0;
Autoarr_foreach(b->curr_buf, c, ({
u32 i=0;
Autoarr_foreach(b->curr_buf, c,
str.ptr[i++]=c;
}));
);
Autoarr_add(b->compl_bufs,str);
Autoarr_free(b->curr_buf, true);
b->curr_buf=Autoarr_create(int8,BL_C,BL_L);
b->curr_buf=Autoarr_create(i8,BL_C,BL_L);
}
void try_complete_buf(StringBuilder* b){
@@ -32,7 +30,7 @@ void try_complete_buf(StringBuilder* b){
StringBuilder* StringBuilder_create(){
StringBuilder* b=malloc(sizeof(StringBuilder));
b->compl_bufs=NULL;
b->curr_buf=Autoarr_create(int8,BL_C,BL_L);
b->curr_buf=Autoarr_create(i8,BL_C,BL_L);
return b;
}
@@ -48,18 +46,18 @@ void StringBuilder_free(StringBuilder* b){
string StringBuilder_build(StringBuilder* b){
complete_buf(b);
uint32 len=0;
Autoarr_foreach(b->compl_bufs, cs, ({
u32 len=0;
Autoarr_foreach(b->compl_bufs, cs,
len+=cs.length;
}));
);
string str= { .length=len, .ptr=malloc(len+1) };
str.ptr[len]='\0';
uint32 i=0;
Autoarr_foreach(b->compl_bufs, cs, ({
for(uint32 n=0;n<cs.length;n++)
u32 i=0;
Autoarr_foreach(b->compl_bufs, cs,
for(u32 n=0;n<cs.length;n++)
str.ptr[i++]=cs.ptr[n];
free(cs.ptr);
}));
);
StringBuilder_free(b);
return str;
}
@@ -70,7 +68,7 @@ void StringBuilder_rmchar(StringBuilder* b){
Autoarr_pop(b->curr_buf)
else {
if(!b->compl_bufs) throw(ERR_NULLPTR);
string* lastcb=Autoarr_getptr(b->compl_bufs, (Autoarr_length(b->compl_bufs)-1));
string* lastcb=Autoarr_getPtr(b->compl_bufs, (Autoarr_length(b->compl_bufs)-1));
lastcb->length--;
}
}
@@ -96,13 +94,13 @@ void StringBuilder_append_cptr(StringBuilder* b, char* s){
}
void curr_buf_add_string(StringBuilder* b, string s){
for(uint32 i=0; i<s.length; i++)
for(u32 i=0; i<s.length; i++)
Autoarr_add(b->curr_buf,s.ptr[i]);
}
void StringBuilder_append_int64(StringBuilder* b, int64 a){
void StringBuilder_append_i64(StringBuilder* b, i64 a){
try_complete_buf(b);
uint8 i=0;
u8 i=0;
if(a==0){
Autoarr_add(b->curr_buf,'0');
return;
@@ -121,9 +119,9 @@ void StringBuilder_append_int64(StringBuilder* b, int64 a){
free(rev.ptr);
}
void StringBuilder_append_uint64(StringBuilder* b, uint64 a){
void StringBuilder_append_u64(StringBuilder* b, u64 a){
try_complete_buf(b);
uint8 i=0;
u8 i=0;
if(a==0){
Autoarr_add(b->curr_buf,'0');
return;
@@ -138,7 +136,7 @@ void StringBuilder_append_uint64(StringBuilder* b, uint64 a){
free(rev.ptr);
}
void StringBuilder_append_float64(StringBuilder* b, double a){
void StringBuilder_append_f64(StringBuilder* b, f64 a){
try_complete_buf(b);
char buf[32];
IFMSC(

View File

@@ -7,13 +7,10 @@ extern "C" {
#include "../Autoarr/Autoarr.h"
#include "string.h"
Autoarr_declare(string)
typedef struct StringBuilder{
STRUCT(StringBuilder,
Autoarr(string)* compl_bufs;
Autoarr(int8)* curr_buf;
} StringBuilder;
ktid_declare(StringBuilder);
Autoarr(i8)* curr_buf;
)
StringBuilder* StringBuilder_create(void);
void StringBuilder_free(StringBuilder* b);
@@ -28,9 +25,9 @@ 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_int64(StringBuilder* b, int64 a);
void StringBuilder_append_uint64(StringBuilder* b, uint64 a);
void StringBuilder_append_float64(StringBuilder* b, double a);
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
}

View File

@@ -1,6 +1,8 @@
#include "string.h"
ktid_define(string);
kt_define(string, NULL, NULL);
Array_define(string)
Autoarr_define(string, false)
// copies str content to new char pointer value (adding '\0' at the end)
char* string_extract(string str){
@@ -12,14 +14,16 @@ char* string_extract(string str){
return cptr;
}
// copies src.ptr content to new string
// copies src.ptr content to new string and adds \0 at the end
string string_copy(string src){
if(!src.ptr) return src;
if(!src.ptr)
return src;
string nstr;
nstr.length=src.length;
nstr.ptr=malloc(nstr.length);
for(uint32 i=0;i<nstr.length;i++)
nstr.ptr=malloc(nstr.length+1);
for(u32 i=0;i<nstr.length;i++)
nstr.ptr[i]=src.ptr[i];
nstr.ptr[nstr.length]='\0';
return nstr;
}
@@ -38,7 +42,7 @@ bool string_compare(string str0, string str1){
string string_reverse(string s){
if(s.length==0) return s;
string r={malloc(s.length), s.length};
for(uint32 i=0; i<s.length; i++)
for(u32 i=0; i<s.length; i++)
r.ptr[i]=s.ptr[s.length-i-1];
return r;
}

View File

@@ -5,21 +5,28 @@ extern "C" {
#endif
#include "../base/base.h"
#include "../Array/Array.h"
#include "../Autoarr/Autoarr.h"
// my fixed length string struct
// doesn't store '\0' at the end
typedef struct string{
STRUCT(string,
char* ptr; // char pointer
uint64 length; // amount of chars in ptr value
} string;
ktid_declare(string);
u64 length; // amount of chars in ptr value
)
Array_declare(string)
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
// copies src.ptr content to new string and adds \0 at the end
string string_copy(string src);
// compares two strings, NullPtr-friendly

View File

@@ -1,33 +1,26 @@
#include "base.h"
#include "../String/StringBuilder.h"
#include <ctype.h>
// returns length of char buffer (without \0)
uint32 cptr_length(char* str){
uint32 len=0;
while(*(str++)) len++;
return len;
u32 cptr_length(const char* str){
const char *const str_first=str;
while(*str)
str++;
return str-str_first;
}
// allocates new char[] and copies src there
char* cptr_copy(char* src){
uint32 len=cptr_length(src)+1;
char* cptr_copy(const char* src){
u32 len=cptr_length(src)+1;
char* dst=malloc(len);
while(len--!=0)
dst[len]=src[len];
return dst;
}
// compares two char buffers, NullPtr-friendly
bool cptr_compare(char* key0, char* key1){
if(!key0) return key1 ? false : true;
if(!key1) return false;
while(*key0&&*key1)
if(*key0++ != *key1++)
return false;
return true;
}
// multiplies char n times
char* char_multiply(char c, uint32 n){
char* char_multiply(char c, u32 n){
char* rez=malloc(n+1);
rez[n]=0;
while(n--!=0)
@@ -35,50 +28,127 @@ char* char_multiply(char c, uint32 n){
return rez;
}
bool cptr_startsWith(char* ptr, char* fragment){
for(char cs=*ptr, cf=*fragment; cf; cs=*++ptr, cf=*++fragment)
if(cs!=cf) return false;
return true;
bool cptr_equals(const char* key0, const char* key1){
char c0=*key0;
char c1=*key1;
bool eq=c0==c1;
while(c0 && c1 && eq) {
c0=*++key0;
c1=*++key1;
eq=c0==c1;
}
return eq;
}
bool cptr_endsWith(char* ptr, char* fragment){
ptr+=cptr_length(ptr)-cptr_length(fragment);
for(char cs=*ptr, cf=*fragment; cf; cs=*++ptr, cf=*++fragment)
if(cs!=cf) return false;
return true;
bool cptr_startsWith(const char* src, const char* fragment){
char c0=*src;
char c1=*fragment;
bool eq=c0==c1 && c0 !=0 && c1!=0;
while(c0 && c1 && eq) {
c0=*++src;
c1=*++fragment;
eq=c0==c1;
if(c1==0)
return true;
}
return eq;
}
uint32 cptr_indexOf(char* ptr, char* fragment){
char sc=*ptr;
for(int si=0, fi=0; sc!=0; si++){
sc=ptr[si];
if(sc==fragment[fi]){
fi++;
if(fragment[fi]==0)
return si-fi+1;
bool cptr_endsWith(const char* src, const char* fragment){
u32 src_len=cptr_length(src);
u32 fr_len=cptr_length(fragment);
if(src_len<fr_len || src_len==0 || fr_len==0)
return false;
src+=src_len-fr_len;
return cptr_equals(src, fragment);
}
i32 cptr_seek(const char* src, const char* fragment, u32 startIndex, u32 seekLength){
char sc=*src, fc=*fragment;
if(sc==0 || fc==0)
return -1;
u32 fr_start=startIndex;
for(u32 si=startIndex; si-startIndex<seekLength && sc!=0; si++){
sc=src[si];
fc=fragment[si-fr_start];
if(fc==0)
return fr_start;
if(sc!=fc)
fr_start++;
}
return -1;
}
i32 cptr_seekReverse(const char* src, const char* fragment, u32 startIndex, u32 seekLength){
char sc=*src, fc=*fragment;
if(sc==0 || fc==0)
return -1;
i32 len=cptr_length(src);
if(startIndex==(u32)-1)
startIndex=len-1;
u32 fr_len=cptr_length(fragment);
for(u32 si=startIndex; si<(u32)-1 && si!=len-1-seekLength; si--){
if(si+1<fr_len)
return -1;
sc=src[si];
fc=fragment[0];
u32 fr_start=si;
for(u32 fi=0; fc==sc ; fi++){
if(fi==fr_len)
return fr_start;
fc=fragment[fi];
sc=src[si--];
}
}
return -1;
}
void memcopy(void* from, void* to, uint32 size){
i32 cptr_seekChar(const char* src, char fragment, u32 startIndex, u32 seekLength){
char sc=*src;
if(sc==0 || fragment==0)
return -1;
for(u32 si=startIndex; si-startIndex<seekLength && sc!=0; si++){
sc=src[si];
if(sc==fragment)
return si;
}
return -1;
}
i32 cptr_seekCharReverse(const char* src, char fragment, u32 startIndex, u32 seekLength){
char sc=*src;
if(sc==0 || fragment==0)
return -1;
i32 len=cptr_length(src);
if(startIndex==(u32)-1)
startIndex=len-1;
for(u32 si=startIndex; si<(u32)-1 && si!=len-1-seekLength; si--){
sc=src[si];
if(sc==fragment)
return si;
}
return -1;
}
void memcopy(void* from, void* to, u32 size){
if(from==NULL || to==NULL)
throw(ERR_NULLPTR);
for(uint32 i=0; i<size; i++)
for(u32 i=0; i<size; i++)
((char*)to)[i]=((char*)from)[i];
}
char* __cptr_concat(uint16 n, ...){
char* __cptr_concat(u32 n, ...){
char** strs=(char**)malloc(n*sizeof(char*));
uint32* lengths=malloc(n*sizeof(uint32));
uint32 totalLength=0;
u32* lengths=malloc(n*sizeof(u32));
u32 totalLength=0;
// reading args from va_list
va_list vl;
va_start(vl, n);
for(uint16 i=0; i<n; i++){
for(u16 i=0; i<n; i++){
char* str=va_arg(vl,char*);
int16 length=cptr_length(str);
i16 length=cptr_length(str);
strs[i]=str;
lengths[i]=length;
totalLength+=length;
@@ -87,11 +157,11 @@ char* __cptr_concat(uint16 n, ...){
// allocating memory for output value
char* totality=malloc(totalLength+1);
const char* output=totality;
char* output=totality;
totality[totalLength]=0;
// copying content of all strings to rezult
for(uint16 k=0; k<n; k++){
for(u16 k=0; k<n; k++){
memcopy(strs[k], totality, lengths[k]);
totality+=lengths[k];
}
@@ -100,3 +170,48 @@ char* __cptr_concat(uint16 n, ...){
free(lengths);
return output;
}
char* cptr_toLower(const char* src) {
u32 length=cptr_length(src);
char *p=malloc(length+1);
p[length]=0;
for(u32 i=0; i<length; i++)
p[i]=tolower(src[i]);
return p;
}
char* cptr_toUpper(const char* src) {
u32 length=cptr_length(src);
char *p=malloc(length+1);
p[length]=0;
for(u32 i=0; i<length; i++)
p[i]=toupper(src[i]);
return p;
}
char* cptr_replaceCharIn(const char* src, char c_old, char c_new, u32 startIndex, u32 seekLength){
char* rzlt=cptr_copy(src);
for(u32 i=startIndex; i!=seekLength && src[i]!=0; i++){
if(src[i]==c_old)
rzlt[i]=c_new;
}
return rzlt;
}
char* cptr_replaceIn(const char* src, const char* str_old, const char* str_new, u32 startIndex, u32 seekLength){
StringBuilder* sb=StringBuilder_create();
const u32 str_old_len=cptr_length(str_old);
const u32 str_new_len=cptr_length(str_new);
i32 i=startIndex;
while( (i=cptr_seek(src, str_old, startIndex, seekLength)) !=-1 ){
if(i!=0)
StringBuilder_append_string(sb, (string){.ptr=(char*)src, .length=i});
StringBuilder_append_string(sb, (string){.ptr=str_new, .length=str_new_len});
src+=i+str_old_len;
}
u32 src_remains_len=cptr_length(src);
if(src_remains_len>0)
StringBuilder_append_string(sb, (string){.ptr=(char*)src, .length=src_remains_len});
string rezult=StringBuilder_build(sb);
return rezult.ptr;
}

View File

@@ -7,37 +7,88 @@ extern "C" {
#include "std.h"
// returns length of char buffer (without \0)
uint32 cptr_length(char* str);
u32 cptr_length(const char* str);
// allocates new char[] and copies src there
char* cptr_copy(char* src);
char* cptr_copy(const char* src);
// compares two char buffers, NullPtr-friendly
bool cptr_compare(char* key0, char* key1);
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, uint32 n);
char* char_multiply(char c, u32 n);
bool cptr_startsWith(char* ptr, char* fragment);
/// @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);
bool cptr_endsWith(char* ptr, char* fragment);
/// @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
uint32 cptr_indexOf(char* ptr, char* fragment);
static inline i32 cptr_indexOf(const char* src, const char* fragment)
{ return cptr_seek(src, fragment, 0, -1); }
static inline bool cptr_contains(char* ptr, char* fragment){
// if(cptr_indexOf(ptr, fragment)==-1)
// return false;
// return true;
return cptr_indexOf(ptr, fragment) +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, uint32 size);
void memcopy(void* from, void* to, u32 size);
char* __cptr_concat(uint16 n, ...);
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

@@ -2,7 +2,7 @@
static const union
{
uint16 number;
u16 number;
Endian bytes[2];
} _endian_union={ .number=0x0102 };

View File

@@ -1,9 +1,20 @@
#include "std.h"
#pragma once
PACK_ENUM(Endian,
#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

@@ -5,25 +5,25 @@
char* errname(ErrorId err){
switch(err){
case SUCCESS: return "SUCCESS";
case ERR_MAXLENGTH: return "ERR_MAXLENGTH";
case ERR_WRONGTYPE: return "ERR_WRONGTYPE";
case ERR_WRONGINDEX: return "ERR_WRONGINDEX";
case ERR_NOTIMPLEMENTED: return "ERR_NOTIMPLEMENTED";
case ERR_NULLPTR: return "ERR_NULLPTR";
case ERR_ENDOFSTR: return "ERR_ENDOFSTR";
case ERR_KEYNOTFOUND: return "ERR_KEYNOTFOUND";
case ERR_FORMAT: return "ERR_FORMAT";
case ERR_UNEXPECTEDVAL: return "ERR_UNEXPECTEDVAL";
case ERR_IO: return "ERR_IO";
case ERR_IO_EOF: return "ERR_IO_EOF";
case SUCCESS: return nameof(SUCCESS);
case ERR_MAXLENGTH: return nameof(ERR_MAXLENGTH);
case ERR_WRONGTYPE: return nameof(ERR_WRONGTYPE);
case ERR_WRONGINDEX: return nameof(ERR_WRONGINDEX);
case ERR_NOTIMPLEMENTED: return nameof(ERR_NOTIMPLEMENTED);
case ERR_NULLPTR: return nameof(ERR_NULLPTR);
case ERR_ENDOFSTR: return nameof(ERR_ENDOFSTR);
case ERR_KEYNOTFOUND: return nameof(ERR_KEYNOTFOUND);
case ERR_FORMAT: return nameof(ERR_FORMAT);
case ERR_UNEXPECTEDVAL: return nameof(ERR_UNEXPECTEDVAL);
case ERR_IO: return nameof(ERR_IO);
case ERR_IO_EOF: return nameof(ERR_IO_EOF);
default: return "UNKNOWN_ERROR";
}
}
#define ERRMSG_MAXLENGTH 1024
char* __genErrMsg(const char* errmsg, const char* srcfile, int line, const char* funcname){
char* __genErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){
size_t bufsize=ERRMSG_MAXLENGTH;
char* rezult=malloc(bufsize);
IFMSC(
@@ -33,7 +33,7 @@ char* __genErrMsg(const char* errmsg, const char* srcfile, int line, const char*
return rezult;
}
char* __extendErrMsg(const char* errmsg, const char* srcfile, int line, const char* funcname){
char* __extendErrMsg(const char* errmsg, const char* srcfile, i32 line, const char* funcname){
size_t bufsize=cptr_length(errmsg)+ERRMSG_MAXLENGTH;
char* rezult=malloc(bufsize);
IFMSC(

View File

@@ -5,9 +5,9 @@ extern "C" {
#endif
#include "std.h"
#include "type_system/unitype.h"
#include "type_system/type_system.h"
PACK_ENUM(ErrorId,
PACKED_ENUM(ErrorId,
SUCCESS, // not an error
ERR_MAXLENGTH, ERR_WRONGTYPE, ERR_WRONGINDEX,
ERR_NOTIMPLEMENTED, ERR_NULLPTR, ERR_ENDOFSTR,
@@ -17,13 +17,13 @@ PACK_ENUM(ErrorId,
char* errname(ErrorId err);
char* __genErrMsg(const char* errmsg, const char* srcfile, int line, const char* funcname);
char* __extendErrMsg(const char* errmsg, const char* srcfile, int line, const char* funcname);
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);
typedef struct Maybe{
STRUCT(Maybe,
Unitype value;
char* errmsg;
} Maybe;
)
// return it if func doesn't return anything
// .value .errmsg
@@ -37,38 +37,54 @@ void printMaybe(Maybe e);
#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); })
#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\
#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 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 throw(E) __EXIT(((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;\
}
#define safethrow(E, FREEMEM) { FREEMEM; \
__RETURN_EXCEPTION(((char*)__genErrMsg((__stringify_err(E)), __FILE__,__LINE__,__func__))); \
}
#define tryLast(_funcCall, _rezult) Maybe _rezult=_funcCall; if(_rezult.errmsg){\
_rezult.errmsg=__extendErrMsg(_rezult.errmsg, __FILE__,__LINE__,__func__);\
__EXIT(_rezult.errmsg);\
}
#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

@@ -2,40 +2,40 @@
#include "std.h"
#define __optime_print(opname, t)\
char tnames[3][3]={"s\0","ms","us"};\
int 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",\
#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
/// uint64 op_i is counter of the internal loop
/// 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(uint64 op_i=0;op_i<(uint64)repeats;op_i++)\
(codeblock);\
clock_gettime(CLOCK_REALTIME, &stop);\
double t=(double)(stop.tv_sec-start.tv_sec)*1000000+(double)(stop.tv_nsec-start.tv_nsec)/1000;\
__optime_print(opname,t)\
})
#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(uint64 op_i=0;op_i<(uint64)repeats;op_i++)\
(codeblock);\
clock_t stop=clock();\
double t=(double)(stop-start)/CLOCKS_PER_SEC*1000000;\
__optime_print(opname,t)\
})
#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

View File

@@ -8,32 +8,40 @@ extern "C" {
#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;
typedef int8_t int8;
typedef uint8_t uint8;
typedef int16_t int16;
typedef uint16_t uint16;
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
typedef float float32;
typedef double float64;
// 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 uint8 bool;
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
@@ -71,27 +79,27 @@ typedef uint8 bool;
#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,\
#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,\
#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)
/*
@@ -111,16 +119,16 @@ You can even embed it into macro in header (see kprint.h)
#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;\
#define WARNING_DISABLE(WARNING, CODE...) \
PRAGMA_WARNING_PUSH \
PRAGMA_WARNING_DISABLE(WARNING) \
CODE; \
PRAGMA_WARNING_POP
#define PACK_ENUM(ENUM_NAME, ENUM_MEMBERS...) typedef enum ENUM_NAME {\
ENUM_MEMBERS\
} __attribute__((__packed__)) ENUM_NAME;
/// gcc throws warning on unused function return value
#define WARN_UNUSED_REZULT __attribute__((warn_unused_result))
#if __cplusplus
}

View File

@@ -4,17 +4,21 @@ For using some kerep capabilities, such as generic structs, unitype, and kprint,
## type id
Every registered type has its own id (`ktid`), which should be declared in header file and defined in source file.
Example:
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
typedef struct { } someStruct;
ktid_declare(someStruct);
STRUCT(someStruct,
i32 i; i32 j; i32 k;
);
```
then you need to define descriptor in a source file
```c
//someStruct.c
ktid_define(someStruct);
kt_define(someStruct);
```
and register it.
## type descriptors
@@ -22,9 +26,9 @@ Every registered type should have it's own descriptor (`ktDescriptor`). It's a s
## type registration
To finally register a type, you should call macro `kt_register()` between `ktDescriptors_beginInit()` and `ktDescriptors_endInit()`. Better do it at the start of your program. To register all types from kerep, call `ktDescriptors_initKerepTypes()`.
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 `ktDescriptors_free()` at exit, if your debugger (valgrind in my case) sees a memory leak.
You can free internal ktDescriptors storage by calling `kt_free()` at exit, if your debugger (valgrind in my case) sees a memory leak.
Examples:
+ [ktDescriptors_initKerepTypes()](src/base/type_system/init.c)
+ [kerep types registration](tests/main.cpp)
+ [kerep types registration](src/base/type_system/init.c)
+ [kt_initKerepTypes()](tests/main.cpp)

View File

@@ -2,24 +2,27 @@
#include "../base.h"
#include "../../kprint/kprint_format.h"
char* __toString_char(void* c, uint32 fmt) {
//*c=char
// 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) {
// *c=char*
if(kp_fmt_dataFormat(fmt)==kp_s){
return cptr_copy((char*)c); // to avoid segmentation fault on free() when *c allocalet on stack
}
// *c=char
if(kp_fmt_dataFormat(fmt)==kp_c){
char* cc=malloc(2);
cc[0]=*(char*)c;
cc[1]=0;
return cc;
}
// *c=cstring
else if(kp_fmt_dataFormat(fmt)==kp_s){
return cptr_copy(*(char**)c);
}
else throw(ERR_FORMAT);
}
char* __toString_bool(void* c, uint32 fmt) {
char* __toString_bool(void* c, u32 fmt) {
static const char _strbool[4][6]={ "false", "true\0", "False", "True\0" };
uint8 strind=*(bool*)c==1 + kp_fmt_isUpper(fmt)*2;
u8 strind=*(bool*)c==1 + kp_fmt_isUpper(fmt)*2;
char* rez=malloc(6);
rez[0]=_strbool[strind][0];
rez[1]=_strbool[strind][1];
@@ -30,10 +33,10 @@ char* __toString_bool(void* c, uint32 fmt) {
return rez;
}
char* toString_int(int64 n){
int64 d=n<0 ? -1*n : n;
char* toString_i64(i64 n){
i64 d=n<0 ? -1*n : n;
char str[32];
uint8 i=sizeof(str);
u8 i=sizeof(str);
str[--i]=0;
if(d==0)
str[--i]='0';
@@ -46,9 +49,9 @@ char* toString_int(int64 n){
return cptr_copy((char*)str+i);
}
char* toString_uint(uint64 n, bool withPostfix, bool uppercase){
char* toString_u64(u64 n, bool withPostfix, bool uppercase){
char str[32];
uint8 i=sizeof(str);
u8 i=sizeof(str);
str[--i]=0;
if(withPostfix)
str[--i]= uppercase ? 'U' : 'u';
@@ -61,53 +64,56 @@ char* toString_uint(uint64 n, bool withPostfix, bool uppercase){
return cptr_copy((char*)str+i);
}
#define _toString_float_impl(bufsize, maxPrecision) {\
char str[bufsize];\
if(precision>maxPrecision)\
throw("too big precision");\
if(precision==0)\
precision=toString_float_default_precision;\
int cn=sprintf(str, "%.*f", precision, n);\
/* remove trailing zeroes except .0*/\
while(str[cn-1]=='0' && str[cn-2]!='.')\
cn--;\
if(withPostfix)\
str[cn++]= uppercase ? 'F' : 'f';\
str[cn]='\0';\
return cptr_copy(str);\
#define _toString_float_impl(bufsize, maxPrecision) { \
char str[bufsize]; \
if(precision>maxPrecision) \
throw("too big precision"); \
if(precision==0) \
precision=toString_float_default_precision; \
i32 cn=IFMSC( \
sprintf_s(str, bufsize, "%.*f", precision, n), \
sprintf(str, "%.*f", precision, n) \
); \
/* remove trailing zeroes except .0*/ \
while(str[cn-1]=='0' && str[cn-2]!='.') \
cn--; \
if(withPostfix) \
str[cn++]= uppercase ? 'F' : 'f'; \
str[cn]='\0'; \
return cptr_copy(str); \
}
char* toString_float32(float32 n, uint8 precision, bool withPostfix, bool uppercase)
_toString_float_impl(48, toString_float32_max_precision)
char* toString_f32(f32 n, u8 precision, bool withPostfix, bool uppercase)
_toString_float_impl(48, toString_f32_max_precision)
char* toString_float64(float64 n, uint8 precision, bool withPostfix, bool uppercase)
_toString_float_impl(512, toString_float64_max_precision)
char* toString_f64(f64 n, u8 precision, bool withPostfix, bool uppercase)
_toString_float_impl(512, toString_f64_max_precision)
#define byte_to_bits(byte) {\
str[cn++]='0' + (uint8)((byte>>7)&1); /* 8th bit */\
str[cn++]='0' + (uint8)((byte>>6)&1); /* 7th bit */\
str[cn++]='0' + (uint8)((byte>>5)&1); /* 6th bit */\
str[cn++]='0' + (uint8)((byte>>4)&1); /* 5th bit */\
str[cn++]='0' + (uint8)((byte>>3)&1); /* 4th bit */\
str[cn++]='0' + (uint8)((byte>>2)&1); /* 3th bit */\
str[cn++]='0' + (uint8)((byte>>1)&1); /* 2th bit */\
str[cn++]='0' + (uint8)((byte>>0)&1); /* 1th bit */\
#define byte_to_bits(byte) { \
str[cn++]='0' + (u8)((byte>>7)&1); /* 8th bit */ \
str[cn++]='0' + (u8)((byte>>6)&1); /* 7th bit */ \
str[cn++]='0' + (u8)((byte>>5)&1); /* 6th bit */ \
str[cn++]='0' + (u8)((byte>>4)&1); /* 5th bit */ \
str[cn++]='0' + (u8)((byte>>3)&1); /* 4th bit */ \
str[cn++]='0' + (u8)((byte>>2)&1); /* 3th bit */ \
str[cn++]='0' + (u8)((byte>>1)&1); /* 2th bit */ \
str[cn++]='0' + (u8)((byte>>0)&1); /* 1th bit */ \
}
char* toString_bin(void* _bytes, uint32 size, bool inverse, bool withPrefix){
char* toString_bin(void* _bytes, u32 size, bool inverse, bool withPrefix){
char* bytes=_bytes;
char* str=malloc(size*8 + (withPrefix?2:0) +1);
uint32 cn=0; // char number
u32 cn=0; // char number
if(withPrefix){
str[cn++]='0';
str[cn++]='b';
}
if(inverse){
// byte number
for(int32 bn=size-1; bn>=0; bn--)
for(i32 bn=size-1; bn>=0; bn--)
byte_to_bits(bytes[bn])
} else {
for(int32 bn=0; bn<size; bn++)
for(u32 bn=0; bn<size; bn++)
byte_to_bits(bytes[bn])
}
str[cn]=0;
@@ -115,7 +121,7 @@ char* toString_bin(void* _bytes, uint32 size, bool inverse, bool withPrefix){
}
// converts number from 0 to F to char
char _4bitsHex(uint8 u, bool uppercase){
char _4bitsHex(u8 u, bool uppercase){
switch(u){
case 0: case 1: case 2: case 3: case 4:
case 5: case 6: case 7: case 8: case 9:
@@ -130,10 +136,10 @@ char _4bitsHex(uint8 u, bool uppercase){
}
}
char* toString_hex(void* _bytes, uint32 size, bool inverse, bool withPrefix, bool uppercase){
char* toString_hex(void* _bytes, u32 size, bool inverse, bool withPrefix, bool uppercase){
char* bytes=_bytes;
char* str=malloc(size*2 + (withPrefix?2:0) + 1);
uint32 cn=0; // char number
u32 cn=0; // char number
if(withPrefix){
str[cn++]='0';
str[cn++]='x';
@@ -141,7 +147,7 @@ char* toString_hex(void* _bytes, uint32 size, bool inverse, bool withPrefix, boo
// left to right
if(inverse){
// byte number
for(int32 bn=size-1; bn>=0; bn--){
for(i32 bn=size-1; bn>=0; bn--){
unsigned char byte=bytes[bn];
str[cn++]=_4bitsHex(byte/16, uppercase);
str[cn++]=_4bitsHex(byte%16, uppercase);
@@ -149,7 +155,7 @@ char* toString_hex(void* _bytes, uint32 size, bool inverse, bool withPrefix, boo
}
// right to left
else {
for(int32 bn=0; bn<size; bn++){ // byte number
for(u32 bn=0; bn<size; bn++){ // byte number
unsigned char byte=bytes[bn];
str[cn++]=_4bitsHex(byte/16, uppercase);
str[cn++]=_4bitsHex(byte%16, uppercase);
@@ -160,60 +166,72 @@ char* toString_hex(void* _bytes, uint32 size, bool inverse, bool withPrefix, boo
}
#define __toString_int_def(BITS) char* __toString_int##BITS(void* _n, uint32 f){\
switch(kp_fmt_dataFormat(f)){\
case kp_i: ;\
int##BITS n=*(int##BITS*)_n;\
return toString_int(n);\
case kp_b:\
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f));\
case kp_h:\
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f));\
default:\
kprintf("\n%u\n", kp_fmt_dataFormat(f));\
throw(ERR_FORMAT);\
return NULL;\
}\
#define __toString_i32_def(BITS) char* __toString_i##BITS(void* _n, u32 f){ \
switch(kp_fmt_dataFormat(f)){ \
case kp_i: ; \
i##BITS n=*(i##BITS*)_n; \
return toString_i64(n); \
case kp_b: \
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \
case kp_h: \
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \
default: \
kprintf("\n%u\n", kp_fmt_dataFormat(f)); \
throw(ERR_FORMAT); \
return NULL; \
} \
}
__toString_int_def(8)
__toString_int_def(16)
__toString_int_def(32)
__toString_int_def(64)
__toString_i32_def(8)
__toString_i32_def(16)
__toString_i32_def(32)
__toString_i32_def(64)
#define __toString_uint_def(BITS) char* __toString_uint##BITS(void* _n, uint32 f){\
switch(kp_fmt_dataFormat(f)){\
case kp_u: ;\
uint##BITS n=*(uint##BITS*)_n;\
return toString_uint(n, kp_fmt_withPostfix(f), kp_fmt_isUpper(f));\
case kp_b:\
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f));\
case kp_h:\
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f));\
default:\
kprintf("\n%u\n", kp_fmt_dataFormat(f));\
throw(ERR_FORMAT);\
return NULL;\
}\
#define __toString_u_def(BITS) char* __toString_u##BITS(void* _n, u32 f){ \
switch(kp_fmt_dataFormat(f)){ \
case kp_u: ; \
u##BITS n=*(u##BITS*)_n; \
return toString_u64(n, kp_fmt_withPostfix(f), kp_fmt_isUpper(f)); \
case kp_b: \
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \
case kp_h: \
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \
default: \
kprintf("\n%u\n", kp_fmt_dataFormat(f)); \
throw(ERR_FORMAT); \
return NULL; \
} \
}
__toString_u_def(8)
__toString_u_def(16)
__toString_u_def(32)
// __toString_u_def(64)
char* __toString_u64(void* _n, u32 f){
switch(kp_fmt_dataFormat(f)){
case kp_u: ;
u64 n=*(u64*)_n;
return toString_u64(n, kp_fmt_withPostfix(f), kp_fmt_isUpper(f));
case kp_b:
return toString_bin(_n, 64/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f));
case kp_h:
return toString_hex(_n, 64/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f));
default:
kprintf("\n%u\n", kp_fmt_dataFormat(f)); throw(ERR_FORMAT); return NULL; }
}
__toString_uint_def(8)
__toString_uint_def(16)
__toString_uint_def(32)
__toString_uint_def(64)
#define __toString_float_def(BITS) char* __toString_float##BITS(void* _n, uint32 f){\
switch(kp_fmt_dataFormat(f)){\
case kp_f: ;\
float##BITS n=*(float##BITS*)_n;\
return toString_float64(n, toString_float_default_precision, kp_fmt_withPostfix(f), kp_fmt_isUpper(f));\
case kp_b:\
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f));\
case kp_h:\
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f));\
default:\
kprintf("\n%u\n", kp_fmt_dataFormat(f));\
throw(ERR_FORMAT);\
return NULL;\
}\
#define __toString_float_def(BITS) char* __toString_f##BITS(void* _n, u32 f){ \
switch(kp_fmt_dataFormat(f)){ \
case kp_f: ; \
f##BITS n=*(f##BITS*)_n; \
return toString_f64(n, toString_float_default_precision, kp_fmt_withPostfix(f), kp_fmt_isUpper(f)); \
case kp_b: \
return toString_bin(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f)); \
case kp_h: \
return toString_hex(_n, BITS/8, getEndian()==LittleEndian, kp_fmt_withPrefix(f), kp_fmt_isUpper(f)); \
default: \
kprintf("\n%u\n", kp_fmt_dataFormat(f)); \
throw(ERR_FORMAT); \
return NULL; \
} \
}
__toString_float_def(32)

View File

@@ -6,41 +6,41 @@ extern "C" {
#include "../errors.h"
// char and cstring
// has different output for fmtChar and fmtString
char* __toString_char(void* c, uint32 fmt);
// 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, uint32 fmt);
char* __toString_bool(void* c, u32 fmt);
// signed int
char* toString_int(int64 n);
char* __toString_int8(void* n, uint32 fmt);
char* __toString_int16(void* n, uint32 fmt);
char* __toString_int32(void* n, uint32 fmt);
char* __toString_int64(void* n, uint32 fmt);
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_uint(uint64 n, bool withPostfix, bool uppercase);
char* __toString_uint8(void* n, uint32 fmt);
char* __toString_uint16(void* n, uint32 fmt);
char* __toString_uint32(void* n, uint32 fmt);
char* __toString_uint64(void* n, uint32 fmt);
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_float32_max_precision 6
#define toString_float64_max_precision 15
#define toString_f32_max_precision 6
#define toString_f64_max_precision 15
#define toString_float_default_precision 6
char* toString_float32(float32 n, uint8 precision, bool withPostfix, bool uppercase); // uses sprintf
char* toString_float64(float64 n, uint8 precision, bool withPostfix, bool uppercase); // uses sprintf
char* __toString_float32(void* n, uint32 fmt);
char* __toString_float64(void* n, uint32 fmt);
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, uint32 size, bool inverse, bool withPrefix);
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, uint32 size, bool inverse, bool withPrefix, bool uppercase);
char* toString_hex(void* bytes, u32 size, bool inverse, bool withPrefix, bool uppercase);
#if __cplusplus
}

View File

@@ -4,84 +4,84 @@
#include "../../SearchTree/SearchTree.h"
#include "../../Hashtable/Hashtable.h"
#include "../../String/StringBuilder.h"
#include "../../Filesystem/filesystem.h"
#include "base_toString.h"
void ktDescriptors_initKerepTypes(){
// null
__kt_register("Null", sizeof(NULL), NULL, NULL);
ktid_Null=ktid_last;
void kt_initKerepTypes(){
// base types
kt_register(char, NULL, __toString_char);
kt_register(bool, NULL, __toString_bool);
kt_register(float32, NULL, __toString_float32);
kt_register(float64, NULL, __toString_float64);
kt_register(int8, NULL, __toString_int8);
kt_register(uint8, NULL, __toString_uint8);
kt_register(int16, NULL, __toString_int16);
kt_register(uint16, NULL, __toString_uint16);
kt_register(int32, NULL, __toString_int32);
kt_register(uint32, NULL, __toString_uint32);
kt_register(int64, NULL, __toString_int64);
kt_register(uint64, NULL, __toString_uint64);
kt_register(Pointer);
if(ktid_Pointer!=0) // this can break UnitypeNull
throw("ktid_Pointer!=0, you must init kerep types before any other types");
kt_register(char);
kt_register(bool);
kt_register(f32);
kt_register(f64);
kt_register(i8);
kt_register(u8);
kt_register(i16);
kt_register(u16);
kt_register(i32);
kt_register(u32);
kt_register(i64);
kt_register(u64);
// ktDescriptor
kt_register(ktDescriptor, NULL, NULL);
kt_register(ktDescriptor);
// base type arrays
kt_register(Array_char, (freeMembers_t)Array_char_freeValues, NULL);
kt_register(Array_bool, (freeMembers_t)Array_bool_freeValues, NULL);
kt_register(Array_float32, (freeMembers_t)Array_float32_freeValues, NULL);
kt_register(Array_float64, (freeMembers_t)Array_float64_freeValues, NULL);
kt_register(Array_int8, (freeMembers_t)Array_int8_freeValues, NULL);
kt_register(Array_uint8, (freeMembers_t)Array_uint8_freeValues, NULL);
kt_register(Array_int16, (freeMembers_t)Array_int16_freeValues, NULL);
kt_register(Array_uint16, (freeMembers_t)Array_uint16_freeValues, NULL);
kt_register(Array_int32, (freeMembers_t)Array_int32_freeValues, NULL);
kt_register(Array_uint32, (freeMembers_t)Array_uint32_freeValues, NULL);
kt_register(Array_int64, (freeMembers_t)Array_int64_freeValues, NULL);
kt_register(Array_uint64, (freeMembers_t)Array_uint64_freeValues, NULL);
kt_register(Array_char);
kt_register(Array_bool);
kt_register(Array_f32);
kt_register(Array_f64);
kt_register(Array_i8);
kt_register(Array_u8);
kt_register(Array_i16);
kt_register(Array_u16);
kt_register(Array_i32);
kt_register(Array_u32);
kt_register(Array_i64);
kt_register(Array_u64);
kt_register(Array_Pointer);
// base type autoarrs
kt_register(Autoarr_char, ____Autoarr_free_char, NULL);
kt_register(Autoarr_bool, ____Autoarr_free_bool, NULL);
kt_register(Autoarr_float32, ____Autoarr_free_float32, NULL);
kt_register(Autoarr_float64, ____Autoarr_free_float64, NULL);
kt_register(Autoarr_int8, ____Autoarr_free_int8, NULL);
kt_register(Autoarr_uint8, ____Autoarr_free_uint8, NULL);
kt_register(Autoarr_int16, ____Autoarr_free_int16, NULL);
kt_register(Autoarr_uint16, ____Autoarr_free_uint16, NULL);
kt_register(Autoarr_int32, ____Autoarr_free_int32, NULL);
kt_register(Autoarr_uint32, ____Autoarr_free_uint32, NULL);
kt_register(Autoarr_int64, ____Autoarr_free_int64, NULL);
kt_register(Autoarr_uint64, ____Autoarr_free_uint64, NULL);
kt_register(Autoarr_Pointer);
kt_register(Autoarr_char);
kt_register(Autoarr_bool);
kt_register(Autoarr_f32);
kt_register(Autoarr_f64);
kt_register(Autoarr_i8);
kt_register(Autoarr_u8);
kt_register(Autoarr_i16);
kt_register(Autoarr_u16);
kt_register(Autoarr_i32);
kt_register(Autoarr_u32);
kt_register(Autoarr_i64);
kt_register(Autoarr_u64);
// Unitype
kt_register(Unitype, __UnitypePtr_free, NULL);
kt_register(Array_Unitype, (freeMembers_t)Array_Unitype_freeValues, NULL);
kt_register(Autoarr_Unitype, ____Autoarr_free_Unitype_, NULL);
// replacing autogenerated freear() function to custom
Autoarr_Unitype* _uar=Autoarr_create(Unitype, 1, 1);
_uar->functions->freear=__Autoarr_free_Unitype_;
Autoarr_free(_uar, true);
kt_register(Unitype);
kt_register(Array_Unitype);
kt_register(Autoarr_Unitype);
// SearchTreeNode
kt_register(STNode, __STNode_free, NULL);
// STNode
kt_register(STNode);
// KeyValuePair
kt_register(KVPair, __KVPair_free, NULL);
kt_register(Autoarr_KVPair, ____Autoarr_free_KVPair_, NULL);
// replacing autogenerated freear() function to custom
Autoarr_KVPair* _kvpar=Autoarr_create(KVPair, 1, 1);
_kvpar->functions->freear=__Autoarr_free_KVPair_;
Autoarr_free(_kvpar, true);
kt_register(KVPair);
kt_register(Autoarr_KVPair);
// Hashtable
kt_register(Hashtable, __Hashtable_free, NULL);
kt_register(Hashtable);
// string
kt_register(string, NULL, NULL);
kt_register(Autoarr_string, ____Autoarr_free_string, NULL);
kt_register(string);
kt_register(Array_string);
kt_register(Autoarr_string);
// StringBuilder
kt_register(StringBuilder, __StringBuilder_free, NULL);
kt_register(StringBuilder);
//File
kt_register(FileHandle);
}

View File

@@ -4,8 +4,8 @@
extern "C" {
#endif
// call this between ktDescriptors_beginInit() and ktDescriptors_endInit()
void ktDescriptors_initKerepTypes();
// call this between kt_beginInit() and kt_endInit()
void kt_initKerepTypes();
#if __cplusplus
}

View File

@@ -6,16 +6,45 @@ extern "C" {
#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, uint32 fmt);
typedef struct ktDescriptor{
typedef char* (*toString_t)(void* obj, u32 fmt);
STRUCT(ktDescriptor,
char* name;
ktid id;
uint16 size;
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
} ktDescriptor;
)
/// 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
}

View File

@@ -1,68 +1,86 @@
#include "../../Autoarr/Autoarr.h"
#include "type_system.h"
#include "base_toString.h"
Autoarr_declare(ktDescriptor)
Autoarr_define(ktDescriptor)
kt_define(Pointer, NULL, __toString_u64);
kt_define(char,NULL, __toString_char);
kt_define(bool,NULL, __toString_bool);
kt_define(f32, NULL, __toString_f32);
kt_define(f64, NULL, __toString_f64);
kt_define(i8, NULL, __toString_i8);
kt_define(u8, NULL, __toString_u8);
kt_define(i16, NULL, __toString_i16);
kt_define(u16, NULL, __toString_u16);
kt_define(i32, NULL, __toString_i32);
kt_define(u32, NULL, __toString_u32);
kt_define(i64, NULL, __toString_i64);
kt_define(u64, NULL, __toString_u64);
ktid ktid_Null=-1;
ktid_define(char);
ktid_define(bool);
ktid_define(float32);
ktid_define(float64);
ktid_define(int8);
ktid_define(uint8);
ktid_define(int16);
ktid_define(uint16);
ktid_define(int32);
ktid_define(uint32);
ktid_define(int64);
ktid_define(uint64);
ktid_define(ktDescriptor);
// type descriptors are stored here during initialization
Autoarr(ktDescriptor)* __ktDescriptors=NULL;
// here type descriptors are stored when initialization is complited
ktDescriptor* typeDescriptors=NULL;
ktid ktid_last=-1;
typedef enum{
NotInitialized, Initializing, Initialized
} ktDescriptorsState;
ktDescriptorsState initState=NotInitialized;
void ktDescriptors_beginInit(){
kprintf("\e[94mtype descriptors initializing...\n");
__ktDescriptors=Autoarr_create(ktDescriptor, 256, 256);
if(__ktDescriptors==NULL) throw(ERR_NULLPTR);
char* ktDescriptor_toString(ktDescriptor* d){
const char* n="null";
char *s0 = toString_u64(d->id, 0,0);
char *s1 = toString_u64(d->size, 0,0);
char *s2 = d->toString ? toString_hex(d->toString, sizeof(void*), 0,1,0) : n;
char *s3 = d->freeMembers ? toString_hex(d->freeMembers, sizeof(void*), 0,1,0) : n;
char *rez=cptr_concat("ktDescriptor {"
" name:", d->name,
" id:",s0,
" size:",s1,
" toString:",s2,
" freeMembers:",s3,
" }");
free(s0);
free(s1);
if(s2!=n) free(s2);
if(s3!=n) free(s3);
return rez;
}
void ktDescriptors_endInit(){
typeDescriptors=Autoarr_toArray(__ktDescriptors);
Autoarr_free(__ktDescriptors,true);
char* _ktDescriptor_toString(void* _d, u32 fmt) { return ktDescriptor_toString(_d); }
kt_define(ktDescriptor, NULL, _ktDescriptor_toString);
typedef ktDescriptor* ktDescriptor_Ptr;
// type descriptors are stored here during initialization
Autoarr(Pointer)* __descriptorPointers=NULL;
// here type descriptors are stored when initialization is complited
ktDescriptor** typeDescriptors=NULL;
ktid ktid_last=-1;
ENUM(ktDescriptorsState,
NotInitialized, Initializing, Initialized
)
ktDescriptorsState initState=NotInitialized;
void kt_beginInit(){
kprintf("\e[94mtype descriptors initializing...\n");
__descriptorPointers=Autoarr_create(Pointer, 256, 256);
}
void kt_endInit(){
if(__descriptorPointers==NULL)
throw(ERR_NULLPTR);
typeDescriptors=(ktDescriptor**)Autoarr_toArray(__descriptorPointers);
Autoarr_free(__descriptorPointers,true);
if(typeDescriptors==NULL) throw(ERR_NULLPTR);
kprintf("\e[92minitialized %u type descriptors\n", ktid_last);
}
void __kt_register(char* name, int16 size, void (*freeMembers)(void*), char* (*toString)(void*, uint32)){
ktDescriptor typeDesc={
.name=name,
.size=size,
.id=++ktid_last,
.freeMembers=freeMembers,
.toString=toString
};
Autoarr_add(__ktDescriptors, typeDesc);
void __kt_register(ktDescriptor* descriptor){
descriptor->id=++ktid_last;
Autoarr_add(__descriptorPointers, descriptor);
}
ktDescriptor ktDescriptor_get(ktid id){
if(id>ktid_last) {
ktDescriptor* ktDescriptor_get(ktid id){
if(id>ktid_last || id==ktid_undefined) {
kprintf("\ntype id: %u\n",id);
throw("invalid type id");
}
return typeDescriptors[id];
}
void ktDescriptors_free(){
void kt_free(){
free(typeDescriptors);
}

View File

@@ -9,39 +9,40 @@ extern "C" {
#include "ktDescriptor.h"
extern ktid ktid_last;
void __kt_register(char* name, int16 size, void (*freeMembers)(void*), char* (*toString)(void*, uint32));
void __kt_register(ktDescriptor* descriptor);
#define kt_register(TYPE, FREE_MEMBERS_FUNC, TO_STRING_FUNC)\
__kt_register(#TYPE, sizeof(TYPE), FREE_MEMBERS_FUNC, TO_STRING_FUNC);\
ktid_##TYPE=ktid_last;\
__kt_register(#TYPE "*", sizeof(TYPE), FREE_MEMBERS_FUNC, TO_STRING_FUNC);\
#define kt_register(TYPE) \
__kt_register(&ktDescriptor_##TYPE); \
ktid_##TYPE=ktid_last; \
__kt_register(&ktDescriptor_##TYPE##_Ptr); \
ktid_##TYPE##_Ptr=ktid_last;
void ktDescriptors_beginInit();
void ktDescriptors_endInit();
void kt_beginInit();
void kt_endInit();
/// @param id id of registered type
ktDescriptor ktDescriptor_get(ktid id);
ktDescriptor* ktDescriptor_get(ktid id);
char* ktDescriptor_toString(ktDescriptor* d);
// call it to free heap-allocated ktDescriptors array
void ktDescriptors_free();
void kt_free();
extern ktid ktid_Null;
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);
ktid_declare(char);
ktid_declare(bool);
ktid_declare(float32);
ktid_declare(float64);
ktid_declare(int8);
ktid_declare(uint8);
ktid_declare(int16);
ktid_declare(uint16);
ktid_declare(int32);
ktid_declare(uint32);
ktid_declare(int64);
ktid_declare(uint64);
ktid_declare(ktDescriptor);
kt_declare(ktDescriptor);
#if __cplusplus
}

View File

@@ -5,17 +5,22 @@ extern "C" {
#endif
#include "../std.h"
typedef uint16 ktid;
#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;\
#define ktid_declare(TYPE) \
extern ktid ktid_##TYPE; \
extern ktid ktid_##TYPE##_Ptr;
#define ktid_define(TYPE)\
ktid ktid_##TYPE=-1;\
#define ktid_define(TYPE) \
ktid ktid_##TYPE=-1; \
ktid ktid_##TYPE##_Ptr=-1;
#if __cplusplus

View File

@@ -1,5 +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

@@ -1,52 +1,100 @@
#include "../../kprint/kprint_format.h"
#include "../base.h"
ktid_define(Unitype);
char *__Unitype_toString(void *_u, u32 fmt)
{
return Unitype_toString(*(Unitype *)_u, fmt);
}
void Unitype_free(Unitype u){
ktDescriptor type=ktDescriptor_get(u.typeId);
if(type.freeMembers)
type.freeMembers(u.VoidPtr);
if(u.allocatedInHeap)
kt_define(Unitype, __UnitypePtr_free, __Unitype_toString);
void Unitype_free(Unitype u)
{
if (u.typeId == ktid_undefined)
{
if (u.VoidPtr != NULL)
throw("unitype with undefined typeId has value");
return;
}
ktDescriptor *type = ktDescriptor_get(u.typeId);
if (type->freeMembers)
type->freeMembers(u.VoidPtr);
if (u.allocatedInHeap)
free(u.VoidPtr);
}
void __UnitypePtr_free(void* u) { Unitype_free(*(Unitype*)u); }
void __UnitypePtr_free(void *u)
{
Unitype_free(*(Unitype *)u);
}
char* toString_Unitype(void* _u, uint32 fmt){
Unitype* u=_u;
ktDescriptor type=ktDescriptor_get(u->typeId);
char* valuestr=type.toString(_u, fmt);
char* rezult=cptr_concat("{ type: ", type.name,
", allocated on heap: ", (u->allocatedInHeap ? "true" : "false"),
", value:", valuestr, " }");
free(valuestr);
char *Unitype_toString(Unitype u, u32 fmt)
{
if (u.typeId == ktid_undefined)
{
if (u.VoidPtr != NULL)
throw("unitype with undefined typeId has value");
return cptr_copy("{ERROR_TYPE}");
}
if (fmt == 0)
{
if (u.typeId == ktid_name(bool) || u.typeId == ktid_name(i8) || u.typeId == ktid_name(i16) ||
u.typeId == ktid_name(i32) || u.typeId == ktid_name(i64))
{
// auto format set
fmt = kp_i;
// replaces value with pointer to value to pass into toString_i64(void*, u32)
i64 value = u.Int64;
u.VoidPtr = &value;
}
else if (u.typeId == ktid_name(u8) || u.typeId == ktid_name(u16) || u.typeId == ktid_name(u32) ||
u.typeId == ktid_name(u64))
{
fmt = kp_u;
u64 value = u.UInt64;
u.VoidPtr = &value;
}
else if (u.typeId == ktid_name(f32) || u.typeId == ktid_name(f64))
{
fmt = kp_f;
f64 value = u.Float64;
u.VoidPtr = &value;
}
else if (u.typeId == ktid_name(char))
{
fmt = kp_c;
i64 value = u.Int64;
u.VoidPtr = &value;
}
else if (u.typeId == ktid_ptrName(char))
{
fmt = kp_s;
}
else if (u.typeId == ktid_name(Pointer))
{
if (u.VoidPtr == NULL)
return cptr_copy("{ UniNull }");
fmt = kp_h;
}
}
ktDescriptor *type = ktDescriptor_get(u.typeId);
char *valuestr;
if (type->toString)
valuestr = type->toString(u.VoidPtr, fmt);
else
valuestr = "ERR_NO_TOSTRING_FUNC";
char *rezult = cptr_concat("{ type: ", type->name, ", allocated on heap: ", (u.allocatedInHeap ? "true" : "false"),
", value:", valuestr, " }");
if (type->toString)
free(valuestr);
return rezult;
}
#define BUFSIZE 64
char* sprintuni(Unitype v){
char* buf=malloc(BUFSIZE);
ktDescriptor type=ktDescriptor_get(v.typeId);
if(v.typeId==ktid_Null)
sprintf_s(buf, BUFSIZE, "{Null}");
else if(v.typeId==ktid_name(float64))
sprintf_s(buf, BUFSIZE, "{%s : %lf}", type.name,v.Float64);
else if(v.typeId==ktid_name(bool) || v.typeId==ktid_name(uint64))
sprintf_s(buf, BUFSIZE, "{%s : " IFWIN("%llu", "%lu") "}", type.name,v.UInt64);
else if(v.typeId==ktid_name(int64))
sprintf_s(buf, BUFSIZE, "{%s : " IFWIN("%lld", "%ld") "}", type.name,v.Int64);
else if(v.typeId==ktid_ptrName(char)){
size_t newBUFSIZE=cptr_length(v.VoidPtr) + BUFSIZE/2;
buf=realloc(buf, newBUFSIZE);
sprintf_s(buf, BUFSIZE, "{%s : \"%s\"}", type.name,(char*)v.VoidPtr);
}
else sprintf_s(buf, BUFSIZE, "{%s : %p}", type.name,v.VoidPtr);
return buf;
}
void printuni(Unitype v){
char* s=sprintuni(v);
void printuni(Unitype v)
{
char *s = Unitype_toString(v, 0);
fputs(s, stdout);
free(s);
}

View File

@@ -5,44 +5,50 @@ extern "C" {
#endif
#include "ktid.h"
#include "typedef_macros.h"
typedef struct Unitype{
STRUCT(Unitype,
union {
int64 Int64;
uint64 UInt64;
double Float64;
i64 Int64;
u64 UInt64;
f64 Float64;
bool Bool;
void* VoidPtr;
char Bytes[8];
};
ktid typeId;
bool allocatedInHeap; // should Unitype_free call free() to VoidPtr*
} Unitype;
ktid_declare(Unitype);
)
#define __UniDef(FIELD, TYPE, VAL) (Unitype){\
.FIELD=VAL, .typeId=ktid_name(TYPE), .allocatedInHeap=false}
#define __UniDef(FIELD, TYPE, VAL) ((Unitype){ \
.FIELD=VAL, .typeId=ktid_name(TYPE), .allocatedInHeap=false})
#define UniInt64(VAL) __UniDef(Int64, int64, VAL)
#define UniUInt64(VAL) __UniDef(UInt64, uint64, VAL)
#define UniFloat64(VAL) __UniDef(Float64, float64, VAL)
#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 UniStackPtr(TYPE, VAL) (Unitype){\
.VoidPtr=VAL, .typeId=ktid_ptrName(TYPE), .allocatedInHeap=false}
#define UniHeapPtr(TYPE, VAL) (Unitype){\
.VoidPtr=VAL, .typeId=ktid_ptrName(TYPE), .allocatedInHeap=true}
#define UniNull (Unitype){.Int64=0, .typeId=ktid_Null, .allocatedInHeap=false}
#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);
char* sprintuni(Unitype v);
#if __cplusplus
}

View File

@@ -2,16 +2,18 @@
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 |
|-------------------------|-------------------------|
| int8 / int16 / int32 | %i / %d |
| int64 | %li / %ld / %lld / %lli |
| uint8 / uint16 / uint32 | %u |
| uint64 | %lu / %llu |
| float32 / float64 | %f |
| char | %c |
| char[] | %s |
| void\* | %p / %x |
| 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>
@@ -27,7 +29,7 @@ I don't really like printf function (and its variants), so i made safer and more
## how to use it:
+ **format construction:**
```
kp_fmt fmt= kp_fgColor | kp_bgColor | kprint_fdataFmt | flags | ktid;
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
@@ -47,4 +49,4 @@ I don't really like printf function (and its variants), so i made safer and more
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={0, ktid_Null}}</span>
output: <span style="color:blue">Maybe:</span> <span style="color:lightgreen">{value: { Pointer, 0x0 }}</span>

View File

@@ -9,42 +9,46 @@ ktid __typeFromFormat(kp_fmt f){
case kp_i:
case kp_h:
case kp_b:
return ktid_name(int64);
return ktid_name(i64);
case kp_u:
return ktid_name(uint64);
return ktid_name(u64);
case kp_f:
return ktid_name(float64);
return ktid_name(f64);
case kp_c:
return ktid_char;
return ktid_name(char);
case kp_s:
return ktid_ptrName(char);
default:
return -1;
return ktid_undefined;
}
}
Maybe __next_toString(kp_fmt f, __kp_value_union* object){
Maybe __next_toString(kp_fmt f, void* object){
// detecting type
ktid typeId=__typeFromFormat(f);
if(typeId==-1)
safethrow("typeId is not set, can't autodetect type",;);
ktDescriptor typeDesc=ktDescriptor_get(typeId);
if(!typeDesc.toString)
if(typeId==ktid_undefined)
safethrow("typeId is undefined, can't autodetect type",;);
if(typeId==ktid_ptrName(char))
object=*(char**)object; // dereferencing char** to char*
ktDescriptor* type=ktDescriptor_get(typeId);
if(!type->toString)
safethrow("type descriptor doesnt have toString() func",;);
return SUCCESS(UniHeapPtr(char, typeDesc.toString(object, f)));
return SUCCESS(UniHeapPtr(char, type->toString(object, f)));
}
Maybe check_argsN(uint8 n){
Maybe check_argsN(u8 n){
if(n%2 != 0) safethrow("kprint recieved non-even number of arguments",;);
if(n > 32) safethrow("kprint recieved >32 number of arguments",;);
return MaybeNull;
}
Maybe __ksprint(uint8 n, kp_fmt* formats, __kp_value_union* objects){
Maybe __ksprint(u8 n, kp_fmt* formats, __kp_value_union* objects){
try(check_argsN(n), _,;);
n/=2;
StringBuilder* strb=StringBuilder_create();
for(uint8 i=0; i<n; i++){
for(u8 i=0; i<n; i++){
try(__next_toString(formats[i], &objects[i]),mStr,;);
StringBuilder_append_cptr(strb, mStr.value.VoidPtr);
Unitype_free(mStr.value);
@@ -53,10 +57,10 @@ Maybe __ksprint(uint8 n, kp_fmt* formats, __kp_value_union* objects){
return SUCCESS(UniHeapPtr(char, rezult));
}
Maybe __kfprint(FILE* file, uint8 n, kp_fmt* formats, __kp_value_union* objects){
Maybe __kfprint(FILE* file, u8 n, kp_fmt* formats, __kp_value_union* objects){
try(check_argsN(n), _,;);
n/=2;
for(uint8 i=0; i<n; i++){
for(u8 i=0; i<n; i++){
try(__next_toString(formats[i], &objects[i]),maybeStr,;);
if(fputs(maybeStr.value.VoidPtr, file)==EOF)
safethrow("can't write string to file", Unitype_free(maybeStr.value));
@@ -66,14 +70,14 @@ Maybe __kfprint(FILE* file, uint8 n, kp_fmt* formats, __kp_value_union* objects)
return MaybeNull;
}
void __kprint(uint8 n, kp_fmt* formats, __kp_value_union* objects){
tryLast(check_argsN(n), _);
void __kprint(u8 n, kp_fmt* formats, __kp_value_union* objects){
tryLast(check_argsN(n), _,;);
n/=2;
for(uint8 i=0; i<n; i++){
for(u8 i=0; i<n; i++){
kp_fmt fmt=formats[i];
kprint_setColor(fmt);
tryLast(__next_toString(fmt, &objects[i]),maybeStr);
if(fputs(maybeStr.value.VoidPtr, stdout)==EOF)\
tryLast(__next_toString(fmt, &objects[i]),maybeStr, kprint_setColor(kp_bgBlack|kp_fgGray));
if(fputs(maybeStr.value.VoidPtr, stdout)==EOF) \
throw("can't write string to stdout");
//, Unitype_free(maybeStr.value)
Unitype_free(maybeStr.value);
@@ -145,13 +149,13 @@ void kprint_setColor(kp_fmt f){
#else
void kprint_setColor(kp_fmt f){
if(kp_fmt_fgColorSet(f)){
uint8 fg=(f&0x0f000000)>>24;
u8 fg=(f&0x0f000000)>>24;
if(fg<8) fg+=30;
else fg+=90-8;
printf("\e[%um", fg);
}
if(kp_fmt_bgColorSet(f)){
uint8 bg=(f&0x00f00000)>>20;
u8 bg=(f&0x00f00000)>>20;
if(bg<8) bg+=40;
else bg+=100-8;
printf("\e[%um", bg);
@@ -159,15 +163,15 @@ void kprint_setColor(kp_fmt f){
}
#endif
/* Maybe ksprint_ar(uint32 count, kp_fmt format, ktid typeId, void* array){
ktDescriptor typeDesc=ktDescriptor_get(format.typeId);
if(!typeDesc.toString)
/* Maybe ksprint_ar(u32 count, kp_fmt format, ktid typeId, void* array){
ktDescriptor* type=ktDescriptor_get(format.typeId);
if(!type->toString)
safethrow("type descriptor doesnt have toString() func",;);
StringBuilder* strb=StringBuilder_create();
StringBuilder_append_char(strb, '[');
for (uint16 e=1; e<count; e++){
for (u16 e=1; e<count; e++){
StringBuilder_append_char(strb, ' ');
char* elStr=typeDesc.toString(array+typeDesc.size*e, &format);
char* elStr=type->toString(array+type->size*e, &format);
StringBuilder_append_cptr(strb, elStr);
StringBuilder_append_char(strb, ',');
}
@@ -175,3 +179,33 @@ void kprint_setColor(kp_fmt f){
StringBuilder_append_char(strb, ' ');
StringBuilder_append_char(strb, ']');
} */
static const char* _kp_colorNames[16]={
"black",
"dark_red",
"dark_green",
"dark_yellow",
"dark_blue",
"dark_magenta",
"dark_cyan",
"gray",
"dark_gray",
"red",
"green",
"yellow",
"blue",
"magenta",
"cyan",
"white"
};
char* kp_bgColor_toString(kp_bgColor c){
u32 color_index=(c&0x00f00000)>>20;
if(color_index>15) throw(ERR_WRONGINDEX);
return _kp_colorNames[color_index];
}
char* kp_fgColor_toString(kp_fgColor c){
u32 color_index=(c&0x00f00000)>>24;
if(color_index>15) throw(ERR_WRONGINDEX);
return _kp_colorNames[color_index];
}

View File

@@ -5,7 +5,6 @@ extern "C" {
#endif
#include "../base/errors.h"
#include "kprint_colors.h"
#include "kprint_format.h"
/*
@@ -15,91 +14,88 @@ This file looks like a mess, but all cotnent here just solves the problem of put
*/
typedef union {
int64 i64;
uint64 u64;
float64 f64;
i64 i64;
u64 u64;
f64 f64;
void* ptr;
} __kp_value_union;
static inline __kp_value_union __kpVU_f(float64 f) { return (__kp_value_union){ .f64=f }; }
inline __kp_value_union __kpVU_i(int64 f) { return (__kp_value_union){ .i64=f }; }
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, double: __kpVU_f, default: __kpVU_i)(V)
#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,...)\
((int32[]){ a0,a2,a4,a6 })
#define __kp_argsToObjs8(\
a0, a1, a2, a3, a4, a5, a6, a7,...)\
#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,...)\
((int32[]){ 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,...)\
#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,...)\
((int32[]){ 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,...)\
#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) :\
#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(uint8 n, kp_fmt* formats, __kp_value_union* objects);
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))\
#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, uint8 n, kp_fmt* formats, __kp_value_union* objects);
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))\
#define kfprint(FD, ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \
__kfprint(FD, count_args(ARGS), __kp_argsToArrs(count_args(ARGS),ARGS, __32zeroes)) \
)
void __kprint(uint8 n, kp_fmt* formats, __kp_value_union* objects);
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))\
#define kprint(ARGS...) WARNING_DISABLE( W_INT_CONVERSION, \
__kprint(count_args(ARGS), __kp_argsToArrs(count_args(ARGS),ARGS, __32zeroes)) \
)
///@param f bgColor | fgColor
void kprint_setColor(kp_fmt f);
#if __cplusplus
}

View File

@@ -8,7 +8,7 @@ extern "C" {
// ^ ^^^^
// | color num
// fgColorSet flag
PACK_ENUM(kp_fgColor,
PACKED_ENUM(kp_fgColor,
/// black foreground
kp_fgBlack = 0x80000000,
/// dark red foreground
@@ -46,7 +46,7 @@ PACK_ENUM(kp_fgColor,
// 01000000 00000000 00000000 00000000
// ^ ^^^^
// bgColorSet flag color num
PACK_ENUM(kp_bgColor,
PACKED_ENUM(kp_bgColor,
/// black background
kp_bgBlack = 0x40000000,
/// dark red background
@@ -81,6 +81,9 @@ PACK_ENUM(kp_bgColor,
kp_bgWhite = 0x40f00000
)
char* kp_bgColor_toString(kp_bgColor c);
char* kp_fgColor_toString(kp_fgColor c);
#if __cplusplus
}
#endif

View File

@@ -6,11 +6,12 @@ extern "C" {
#include "../base/std.h"
#include "../base/type_system/ktid.h"
#include "kprint_colors.h"
/// kprint_format
typedef uint32 kp_fmt;
typedef u32 kp_fmt;
PACK_ENUM(kp_dataFmt,
PACKED_ENUM(kp_dataFmt,
// 00000000 00000000 00000000 00000000
// ^^^^
// type
@@ -44,6 +45,9 @@ PACK_ENUM(kp_dataFmt,
#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

@@ -54,15 +54,17 @@ bgColorSet─┘││ │ bgColor └data format
## Data format
| format | possible flags | data types | hex value | bin value |
|-----------|----------------|------------|-----------|-----------|
| kp_i | | int8... int64 | 0x00000000 | 00000000 00000000... |
| kp_u | Postfix, Upper | uint8... uint64 | 0x00010000 | 00000000 00000001... |
| kp_h | Prefix, Upper | any | 0x00020000 | 00000000 00000010... |
| kp_b | Prefix | any | 0x00030000 | 00000000 00000011... |
| kp_f | Postfix, Upper | float32, float64 | 0x00040000 | 00000000 00000100... |
| kp_c | | char | 0x00050000 | 00000000 00000101... |
| kp_sing | | char* | 0x00060000 | 00000000 00000110... |
| 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 |

View File

@@ -1,11 +1,10 @@
#include "kprintf.h"
#include "../base/base.h"
#include "../base/type_system/base_toString.h"
#if defined(_WIN64) || defined(_WIN32)
#include <windows.h>
WORD unixColorToWin(uint8 c){
WORD unixColorToWin(u8 c){
switch(c){
//foreground
case 30: return 0;
@@ -49,8 +48,9 @@ WORD unixColorToWin(uint8 c){
void kprintf(const char* format, ...){
va_list vl;
va_start(vl, format);
uint32 i=0;
u32 i=0;
for(char c=format[i++]; c!=0; c=format[i++]){
// value format specifiers
if(c=='%'){
char* argstr=NULL;
bool l=false;
@@ -58,28 +58,37 @@ void kprintf(const char* format, ...){
format_escape_seq:
switch (c) {
case 'u':
argstr=toString_uint(
l ? va_arg(vl, uint64) : va_arg(vl, uint32)
argstr=toString_u64(
l ? va_arg(vl, u64) : va_arg(vl, u32)
,0,0);
break;
case 'i': case 'd':
argstr=toString_int(
l ? va_arg(vl, int64) : va_arg(vl, int32)
argstr=toString_i64(
l ? va_arg(vl, i64) : va_arg(vl, i32)
);
break;
case 'f':
// float32 is promoted to float64 when passed through '...'
argstr=toString_float64(va_arg(vl, float64), toString_float_default_precision,0,0);
// f32 is promoted to f64 when passed through '...'
argstr=toString_f64(va_arg(vl, f64), toString_float_default_precision,0,0);
break;
case 'l':
l=true;
if((c=format[i++]))
goto format_escape_seq;
break;
case 'p':
case 'p': ;
void* phex=va_arg(vl, void*);
argstr=toString_hex(&phex,getEndian()==LittleEndian,sizeof(phex),1,0);
break;
case 'x': ;
uint64 px=va_arg(vl, uint64);
argstr=toString_hex(&px,getEndian()==LittleEndian,sizeof(px),1,0);
if(l){
u64 xhex=va_arg(vl, u64);
argstr=toString_hex(&xhex,getEndian()==LittleEndian,sizeof(xhex),0,1);
}
else {
u32 xhex=va_arg(vl, u32);
argstr=toString_hex(&xhex,getEndian()==LittleEndian,sizeof(xhex),0,1);
}
break;
case 's': ;
char* cptr=va_arg(vl,char*);
@@ -104,19 +113,22 @@ void kprintf(const char* format, ...){
fputs(argstr, stdout);
free(argstr);
}
} else if(c=='\e'){
}
// escape sequences
else if(c=='\e'){
IFWIN(
/* WINDOWS */
({
if((c=format[i++])=='['){
uint8 colorUnix=0;
for(int8 n=0; n<6 && c!=0; n++){
u8 colorUnix=0;
for(i8 n=0; n<6 && c!=0; n++){
c=format[i++];
switch (c){
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
colorUnix=colorUnix*10+c-'0';
break;
case 'm':
case 'm': ;
WORD colorWin=unixColorToWin(colorUnix);
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsole, colorWin);
@@ -127,13 +139,16 @@ void kprintf(const char* format, ...){
}
}
}),
/* UNIX */
putc(c,stdout);
);
} else {
}
// common characters
else {
putc(c,stdout);
}
#if defined(_WIN64) || defined(_WIN32)
end_iteration:
end_iteration:;
#endif
}
va_end(vl);

View File

@@ -4,6 +4,8 @@
extern "C" {
#endif
#include "../base/type_system/base_toString.h"
// cross-platform printf analog
void kprintf(const char* format, ...);

View File

@@ -12,8 +12,8 @@ extern "C" {
/*
You can choose any algorithm that has required functions:
some_alg32_statePtr some_alg32_init(uint32 seed);
uint32 some_alg32_next(some_alg32_statePtr);
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
@@ -51,19 +51,19 @@ typedef void* krand_statePtr;
#define __krand_next_definition(VALUE_SIZE) { return from+KRAND_ALG##VALUE_SIZE##_next(state)%(to-from); }
// ready-to-use functions
static inline int8 krand_next8 (krand_statePtr state, int8 from, int8 to) __krand_next_definition(32)
static inline int16 krand_next16(krand_statePtr state, int16 from, int16 to) __krand_next_definition(32)
static inline int32 krand_next32(krand_statePtr state, int32 from, int32 to) __krand_next_definition(32)
static inline int64 krand_next64(krand_statePtr state, int64 from, int64 to) __krand_next_definition(64)
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 float32 krand_nextFloat32(krand_statePtr state) {return (uint32)KRAND_ALG32_next(state)/0xffffffff; }
static inline float64 krand_nextFloat64(krand_statePtr state) {return KRAND_ALG64_next(state)/0xffffffff; }
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){
int limit=1/chance + 0.01f;
i32 limit=1/chance + 0.01f;
return KRAND_ALG32_next(state)%limit == 0;
}

View File

@@ -13,18 +13,18 @@ generator.
// The state can be seeded with any (upto) 64 bit integer value.
void* splitmix64_init(uint64 seed){
void* splitmix64_init(u64 seed){
splitmix64_state* state=malloc(sizeof(splitmix64_state));
*state=seed;
return state;
}
uint64 splitmix64_next(void* _state) {
u64 splitmix64_next(void* _state) {
splitmix64_state* state=_state;
// increment the state variable
*state += 0x9e3779b97f4a7c15;
// copy the state to a working variable
uint64 z = *state;
u64 z = *state;
// xor the variable with the variable right bit shifted 30 then multiply by a constant
z = (z ^ (z>>30)) * 0xbf58476d1ce4e5b9;
// xor the variable with the variable right bit shifted 27 then multiply by a constant

View File

@@ -6,13 +6,13 @@ extern "C" {
#include "../../base/base.h"
typedef uint64 splitmix64_state;
typedef u64 splitmix64_state;
typedef void* splitmix64_statePtr;
splitmix64_statePtr splitmix64_init(uint64 seed);
splitmix64_statePtr splitmix64_init(u64 seed);
static inline splitmix64_statePtr splitmix64_initFromTime(void) { return splitmix64_init(time(NULL)); }
uint64 splitmix64_next(splitmix64_statePtr);
u64 splitmix64_next(splitmix64_statePtr);
static inline void splitmix64_free(splitmix64_statePtr state) {
free(state);
}

View File

@@ -8,12 +8,12 @@ extern "C" {
#include "../../splitmix64/splitmix64.h"
typedef union {
uint64 merged;
uint32 s[2];
u64 merged;
u32 s[2];
} xoroshiro64_state;
typedef void* xoroshiro64_statePtr;
xoroshiro64_statePtr xoroshiro64_init(uint64 seed);
xoroshiro64_statePtr xoroshiro64_init(u64 seed);
#define xoroshiro64star_init xoroshiro64_init
#define xoroshiro64starstar_init xoroshiro64_init
@@ -21,8 +21,8 @@ static inline xoroshiro64_statePtr xoroshiro64_initFromTime(void) { return xoros
#define xoroshiro64star_initFromTime xoroshiro64_initFromTime
#define xoroshiro64starstar_initFromTime xoroshiro64_initFromTime
uint32 xoroshiro64star_next(xoroshiro64_statePtr);
uint32 xoroshiro64starstar_next(xoroshiro64_statePtr);
u32 xoroshiro64star_next(xoroshiro64_statePtr);
u32 xoroshiro64starstar_next(xoroshiro64_statePtr);
static inline void xoroshiro64_free(xoroshiro64_statePtr state) {
free(state);

View File

@@ -10,8 +10,8 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
/*
This is xoroshiro64* 1.0, our best and fastest 32-bit small-state
generator for 32-bit floating-point numbers. We suggest to use its
upper bits for floating-point generation, as it is slightly faster than
generator for 32-bit floating-poi32 numbers. We suggest to use its
upper bits for floating-poi32 generation, as it is slightly faster than
xoroshiro64**. It passes all tests we are aware of except for linearity
tests, as the lowest six bits have low linear complexity, so if low
linear complexity is not considered an issue (as it is usually the
@@ -23,15 +23,15 @@ right shifts to extract subsets of bits.
The state must be seeded so that it is not everywhere zero.
*/
static inline uint32 rotl(const uint32 x, int k) {
static inline u32 rotl(const u32 x, i32 k) {
return (x << k) | (x >> (32 - k));
}
uint32 xoroshiro64star_next(void* _state) {
u32 xoroshiro64star_next(void* _state) {
xoroshiro64_state* state=_state;
const uint32 s0 = state->s[0];
uint32 s1 = state->s[1];
const uint32 result = s0 * 0x9E3779BB;
const u32 s0 = state->s[0];
u32 s1 = state->s[1];
const u32 result = s0 * 0x9E3779BB;
s1 ^= s0;
state->s[0] = rotl(s0, 26) ^ s1 ^ (s1 << 9); // a, b
@@ -40,7 +40,7 @@ uint32 xoroshiro64star_next(void* _state) {
return result;
}
void* xoroshiro64_init(uint64 seed){
void* xoroshiro64_init(u64 seed){
xoroshiro64_state* state=malloc(sizeof(xoroshiro64_state));
splitmix64_state* splitmix=splitmix64_init(seed);
state->merged=splitmix64_next(splitmix);

View File

@@ -19,15 +19,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
The state must be seeded so that it is not everywhere zero. */
static inline uint32 rotl(const uint32 x, int k) {
static inline u32 rotl(const u32 x, i32 k) {
return (x << k) | (x >> (32 - k));
}
uint32 xoroshiro64starstar_next(void* _state) {
u32 xoroshiro64starstar_next(void* _state) {
xoroshiro64_state* state=_state;
const uint32 s0 = state->s[0];
uint32 s1 = state->s[1];
const uint32 result = rotl(s0 * 0x9E3779BB, 5) * 5;
const u32 s0 = state->s[0];
u32 s1 = state->s[1];
const u32 result = rotl(s0 * 0x9E3779BB, 5) * 5;
s1 ^= s0;
state->s[0] = rotl(s0, 26) ^ s1 ^ (s1 << 9); // a, b

View File

@@ -9,11 +9,11 @@ extern "C" {
typedef union {
uint32 s[2];
u32 s[2];
} xoroshiro128_state;
typedef void* xoroshiro128_statePtr;
xoroshiro128_statePtr xoroshiro128_init(uint64 seed);
xoroshiro128_statePtr xoroshiro128_init(u64 seed);
#define xoroshiro128plus_init xoroshiro128_init
#define xoroshiro128plusplus_init xoroshiro128_init
#define xoroshiro128starstar_init xoroshiro128_init
@@ -23,9 +23,9 @@ static inline xoroshiro128_statePtr xoroshiro128_initFromTime(void) { return xor
#define xoroshiro128plusplus_initFromTime xoroshiro128_initFromTime
#define xoroshiro128starstar_initFromTime xoroshiro128_initFromTime
uint64 xoroshiro128plus_next(xoroshiro128_statePtr);
uint64 xoroshiro128plusplus_next(xoroshiro128_statePtr);
uint64 xoroshiro128starstar_next(xoroshiro128_statePtr);
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);

View File

@@ -9,9 +9,9 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
#include "xoroshiro128.h"
/* This is xoroshiro128+ 1.0, our best and fastest small-state generator
for floating-point numbers, but its state space is large enough only
for floating-poi32 numbers, but its state space is large enough only
for mild parallelism. We suggest to use its upper bits for
floating-point generation, as it is slightly faster than
floating-poi32 generation, as it is slightly faster than
xoroshiro128++/xoroshiro128**. It passes all tests we are aware of
except for the four lower bits, which might fail linearity tests (and
just those), so if low linear complexity is not considered an issue (as
@@ -32,15 +32,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
better results in our test than the 2016 version (a=55, b=14, c=36).
*/
static inline uint64 rotl(const uint64 x, int k) {
static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x >> (64 - k));
}
uint64 xoroshiro128plus_next(void* _state){
u64 xoroshiro128plus_next(void* _state){
xoroshiro128_state* state=_state;
const uint64 s0 = state->s[0];
uint64 s1 = state->s[1];
const uint64 result = s0 + s1;
const u64 s0 = state->s[0];
u64 s1 = state->s[1];
const u64 result = s0 + s1;
s1 ^= s0;
state->s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b
@@ -49,7 +49,7 @@ uint64 xoroshiro128plus_next(void* _state){
return result;
}
void* xoroshiro128_init(uint64 seed){
void* xoroshiro128_init(u64 seed){
xoroshiro128_state* state=malloc(sizeof(xoroshiro128_state));
splitmix64_state* splitmix=splitmix64_init(seed);
state->s[0]=splitmix64_next(splitmix);

View File

@@ -13,7 +13,7 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
tests we are aware of, but its state space is large enough only for
mild parallelism.
For generating just floating-point numbers, xoroshiro128+ is even
For generating just floating-poi32 numbers, xoroshiro128+ is even
faster (but it has a very mild bias, see notes in the comments).
The state must be seeded so that it is not everywhere zero. If you have
@@ -21,15 +21,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
output to fill s. */
static inline uint64 rotl(const uint64 x, int k) {
static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x >> (64 - k));
}
uint64 xoroshiro128plusplus_next(void* _state){
u64 xoroshiro128plusplus_next(void* _state){
xoroshiro128_state* state=_state;
const uint64 s0 = state->s[0];
uint64 s1 = state->s[1];
const uint64 result = rotl(s0 + s1, 17) + s0;
const u64 s0 = state->s[0];
u64 s1 = state->s[1];
const u64 result = rotl(s0 + s1, 17) + s0;
s1 ^= s0;
state->s[0] = rotl(s0, 49) ^ s1 ^ (s1 << 21); // a, b

View File

@@ -13,7 +13,7 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
tests we are aware of, but its state space is large enough only for
mild parallelism.
For generating just floating-point numbers, xoroshiro128+ is even
For generating just floating-poi32 numbers, xoroshiro128+ is even
faster (but it has a very mild bias, see notes in the comments).
The state must be seeded so that it is not everywhere zero. If you have
@@ -21,15 +21,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
output to fill s. */
static inline uint64 rotl(const uint64 x, int k) {
static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x >> (64 - k));
}
uint64 xoroshiro128starstar_next(void* _state){
u64 xoroshiro128starstar_next(void* _state){
xoroshiro128_state* state=_state;
const uint64 s0 = state->s[0];
uint64 s1 = state->s[1];
const uint64 result = rotl(s0 * 5, 7) * 9;
const u64 s0 = state->s[0];
u64 s1 = state->s[1];
const u64 result = rotl(s0 * 5, 7) * 9;
s1 ^= s0;
state->s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b

View File

@@ -9,12 +9,12 @@ extern "C" {
typedef union {
uint64 merged[2];
uint32 s[4];
u64 merged[2];
u32 s[4];
} xoshiro128_state;
typedef void* xoshiro128_statePtr;
xoshiro128_statePtr xoshiro128_init(uint64 seed);
xoshiro128_statePtr xoshiro128_init(u64 seed);
#define xoshiro128plus_init xoshiro128_init
#define xoshiro128plusplus_init xoshiro128_init
#define xoshiro128starstar_init xoshiro128_init
@@ -24,9 +24,9 @@ static inline xoshiro128_statePtr xoshiro128_initFromTime(void) { return xoshiro
#define xoshiro128plusplus_initFromTime xoshiro128_initFromTime
#define xoshiro128starstar_initFromTime xoshiro128_initFromTime
uint32 xoshiro128plus_next(xoshiro128_statePtr);
uint32 xoshiro128plusplus_next(xoshiro128_statePtr);
uint32 xoshiro128starstar_next(xoshiro128_statePtr);
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);

View File

@@ -9,8 +9,8 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
#include "xoshiro128.h"
/* This is xoshiro128+ 1.0, our best and fastest 32-bit generator for 32-bit
floating-point numbers. We suggest to use its upper bits for
floating-point generation, as it is slightly faster than xoshiro128**.
floating-poi32 numbers. We suggest to use its upper bits for
floating-poi32 generation, as it is slightly faster than xoshiro128**.
It passes all tests we are aware of except for
linearity tests, as the lowest four bits have low linear complexity, so
if low linear complexity is not considered an issue (as it is usually
@@ -22,15 +22,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
The state must be seeded so that it is not everywhere zero. */
static inline uint32 rotl(const uint32 x, int k) {
static inline u32 rotl(const u32 x, i32 k) {
return (x << k) | (x >> (32 - k));
}
uint32 xoshiro128plus_next(void* _state){
u32 xoshiro128plus_next(void* _state){
xoshiro128_state* state=_state;
const uint32 result = state->s[0] + state->s[3];
const u32 result = state->s[0] + state->s[3];
const uint32 t = state->s[1] << 9;
const u32 t = state->s[1] << 9;
state->s[2] ^= state->s[0];
state->s[3] ^= state->s[1];
@@ -44,7 +44,7 @@ uint32 xoshiro128plus_next(void* _state){
return result;
}
void* xoshiro128_init(uint64 seed){
void* xoshiro128_init(u64 seed){
xoshiro128_state* state=malloc(sizeof(xoshiro128_state));
splitmix64_state* splitmix=splitmix64_init(seed);
state->merged[0]=splitmix64_next(splitmix);

View File

@@ -19,15 +19,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
The state must be seeded so that it is not everywhere zero. */
static inline uint32 rotl(const uint32 x, int k) {
static inline u32 rotl(const u32 x, i32 k) {
return (x << k) | (x >> (32 - k));
}
uint32 xoshiro128plusplus_next(void* _state){
u32 xoshiro128plusplus_next(void* _state){
xoshiro128_state* state=_state;
const uint32 result = rotl(state->s[0] + state->s[3], 7) + state->s[0];
const u32 result = rotl(state->s[0] + state->s[3], 7) + state->s[0];
const uint32 t = state->s[1] << 9;
const u32 t = state->s[1] << 9;
state->s[2] ^= state->s[0];
state->s[3] ^= state->s[1];

View File

@@ -22,15 +22,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
The state must be seeded so that it is not everywhere zero. */
static inline uint32 rotl(const uint32 x, int k) {
static inline u32 rotl(const u32 x, i32 k) {
return (x << k) | (x >> (32 - k));
}
uint32 xoshiro128starstar_next(void* _state){
u32 xoshiro128starstar_next(void* _state){
xoshiro128_state* state=_state;
const uint32 result = rotl(state->s[1] * 5, 7) * 9;
const u32 result = rotl(state->s[1] * 5, 7) * 9;
const uint32 t = state->s[1] << 9;
const u32 t = state->s[1] << 9;
state->s[2] ^= state->s[0];
state->s[3] ^= state->s[1];

View File

@@ -9,11 +9,11 @@ extern "C" {
typedef union {
uint64 s[4];
u64 s[4];
} xoshiro256_state;
typedef void* xoshiro256_statePtr;
xoshiro256_statePtr xoshiro256_init(uint64 seed);
xoshiro256_statePtr xoshiro256_init(u64 seed);
#define xoshiro256plus_init xoshiro256_init
#define xoshiro256plusplus_init xoshiro256_init
#define xoshiro256starstar_init xoshiro256_init
@@ -23,9 +23,9 @@ static inline xoshiro256_statePtr xoshiro256_initFromTime(void) { return xoshiro
#define xoshiro256plusplus_initFromTime xoshiro256_initFromTime
#define xoshiro256starstar_initFromTime xoshiro256_initFromTime
uint64 xoshiro256plus_next(xoshiro256_statePtr);
uint64 xoshiro256plusplus_next(xoshiro256_statePtr);
uint64 xoshiro256starstar_next(xoshiro256_statePtr);
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);

View File

@@ -24,15 +24,15 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
output to fill s. */
static inline uint64 rotl(const uint64 x, int k) {
static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x >> (64 - k));
}
uint64 xoshiro256plus_next(void* _state){
u64 xoshiro256plus_next(void* _state){
xoshiro256_state* state=_state;
const uint64 result = state->s[0] + state->s[3];
const u64 result = state->s[0] + state->s[3];
const uint64 t = state->s[1] << 17;
const u64 t = state->s[1] << 17;
state->s[2] ^= state->s[0];
state->s[3] ^= state->s[1];
@@ -46,7 +46,7 @@ uint64 xoshiro256plus_next(void* _state){
return result;
}
void* xoshiro256_init(uint64 seed){
void* xoshiro256_init(u64 seed){
xoshiro256_state* state=malloc(sizeof(xoshiro256_state));
splitmix64_state* splitmix=splitmix64_init(seed);
state->s[0]=splitmix64_next(splitmix);

View File

@@ -13,20 +13,20 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
enough for any parallel application, and it passes all tests we are
aware of.
For generating just floating-point numbers, xoshiro256+ is even faster.
For generating just floating-poi32 numbers, xoshiro256+ is even faster.
The state must be seeded so that it is not everywhere zero. If you have
a 64-bit seed, we suggest to seed a splitmix64 generator and use its
output to fill s. */
static inline uint64 rotl(const uint64 x, int k) {
static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x>>(64 - k));
}
uint64 xoshiro256plusplus_next(void* _state) {
u64 xoshiro256plusplus_next(void* _state) {
xoshiro256_state* state=_state;
const uint64 result=rotl(state->s[0] + state->s[3], 23) + state->s[0];
const uint64 t=state->s[1] << 17;
const u64 result=rotl(state->s[0] + state->s[3], 23) + state->s[0];
const u64 t=state->s[1] << 17;
state->s[2] ^= state->s[0];
state->s[3] ^= state->s[1];
state->s[1] ^= state->s[2];

View File

@@ -13,21 +13,21 @@ See <http://creativecommons.org/publicdomain/zero/1.0/>. */
large enough for any parallel application, and it passes all tests we
are aware of.
For generating just floating-point numbers, xoshiro256+ is even faster.
For generating just floating-poi32 numbers, xoshiro256+ is even faster.
The state must be seeded so that it is not everywhere zero. If you have
a 64-bit seed, we suggest to seed a splitmix64 generator and use its
output to fill s. */
static inline uint64 rotl(const uint64 x, int k) {
static inline u64 rotl(const u64 x, i32 k) {
return (x << k) | (x >> (64 - k));
}
uint64 xoshiro256starstar_next(void* _state){
u64 xoshiro256starstar_next(void* _state){
xoshiro256_state* state=_state;
const uint64 result = rotl(state->s[1] * 5, 7) * 9;
const u64 result = rotl(state->s[1] * 5, 7) * 9;
const uint64 t = state->s[1] << 17;
const u64 t = state->s[1] << 17;
state->s[2] ^= state->s[0];
state->s[3] ^= state->s[1];