kerep sources
This commit is contained in:
29
build.sh
29
build.sh
@@ -1,31 +1,38 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -eo pipefail
|
set -eo pipefail
|
||||||
|
|
||||||
CMP="gcc"
|
CMP="gcc"
|
||||||
ARGS="-Wall -Wno-discarded-qualifiers -O2"
|
WARN="-Wall -Wextra -Wno-discarded-qualifiers -Wno-unused-parameter"
|
||||||
SRC="$(find . -name '*.c')"
|
ARGS="-O2 -flto -fdata-sections -ffunction-sections -Wl,--gc-sections"
|
||||||
LINK="-L. -lkerep"
|
SRC="$(find src -name '*.c')"
|
||||||
|
|
||||||
OS=$(./detect_os.sh)
|
OS="$(./detect_os.sh)"
|
||||||
ARCH=$(./detect_arch.sh)
|
ARCH="$(./detect_arch.sh)"
|
||||||
|
LINK="-Lkerep/bin -lkerep-$OS-$ARCH"
|
||||||
|
|
||||||
if [[ OS == "windows" ]]; then
|
if [[ OS -eq "windows" ]]; then
|
||||||
OUT_FILE="cbuild.exe"
|
OUT_FILE="cbuild.exe"
|
||||||
else
|
else
|
||||||
OUT_FILE="cbuild"
|
OUT_FILE="cbuild"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
command="$CMP $ARGS
|
command="$CMP $ARGS
|
||||||
-DOS=$OS -DARCH=$ARCH
|
$WARN
|
||||||
|
-DOS=\"$OS\" -DARCH=\"$ARCH\"
|
||||||
$SRC
|
$SRC
|
||||||
$LINK
|
$LINK
|
||||||
-o bin/$OUT_FILE"
|
-o bin/$OUT_FILE"
|
||||||
|
|
||||||
|
if [ ! -f "kerep/bin/libkerep-$OS-$ARCH.a" ]; then
|
||||||
|
echo "libkerep-$OS-$ARCH.a not found"
|
||||||
|
cd kerep
|
||||||
|
./build.sh
|
||||||
|
cd ..
|
||||||
|
fi
|
||||||
|
|
||||||
rm -rf bin
|
rm -rf bin
|
||||||
mkdir bin
|
mkdir bin
|
||||||
|
echo "----------------[cbuild]----------------"
|
||||||
echo "$command"
|
echo "$command"
|
||||||
|
|
||||||
tar xJf libkerep.a.tar.xz
|
|
||||||
|
|
||||||
$($command)
|
$($command)
|
||||||
|
|
||||||
rm libkerep.a
|
|
||||||
|
|||||||
@@ -20,4 +20,4 @@ case "$uname_rezult" in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
echo "\"$ARCH\""
|
echo "$ARCH"
|
||||||
|
|||||||
@@ -23,4 +23,4 @@ case "$uname_rezult" in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
echo "\"$OS\""
|
echo "$OS"
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#if __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "../Hashtable/Hashtable.h"
|
|
||||||
|
|
||||||
// parses text to binary values
|
|
||||||
Maybe DtsodV24_deserialize(char* text);
|
|
||||||
|
|
||||||
// creates text representation of dtsod
|
|
||||||
Maybe DtsodV24_serialize(Hashtable* dtsod);
|
|
||||||
|
|
||||||
// returns value or UniNull if key not found
|
|
||||||
Unitype DtsodV24_get(Hashtable* dtsod, char* key);
|
|
||||||
|
|
||||||
// adds or sets value
|
|
||||||
void DtsodV24_addOrSet(Hashtable* dtsod, char* key, Unitype value);
|
|
||||||
|
|
||||||
// checks for dtsod contains value or dont
|
|
||||||
bool DtsodV24_contains(Hashtable* dtsod, char* key);
|
|
||||||
|
|
||||||
// replaces value with UniNull if key exists in dtsod
|
|
||||||
bool DtsodV24_remove(Hashtable* dtsod, char* key);
|
|
||||||
|
|
||||||
// frees memory including memory of elements (hashtables, autoarrs, etc.)
|
|
||||||
void DtsodV24_free(Hashtable* dtsod);
|
|
||||||
|
|
||||||
#if __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
2
kerep/.gitignore
vendored
Normal file
2
kerep/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
obj/
|
||||||
|
libkerep.*
|
||||||
41
kerep/build.sh
Normal file
41
kerep/build.sh
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -eo pipefail
|
||||||
|
|
||||||
|
CMP="gcc"
|
||||||
|
WARN="-std=c11 -Wall -Wno-discarded-qualifiers -Wno-unused-parameter"
|
||||||
|
ARGS="-O2 -flto -fpic -fdata-sections -ffunction-sections"
|
||||||
|
SRC="$(find src -name '*.c')"
|
||||||
|
|
||||||
|
OS=$(../detect_os.sh)
|
||||||
|
ARCH=$(../detect_arch.sh)
|
||||||
|
OUTFILE="bin/libkerep-$OS-$ARCH.a"
|
||||||
|
|
||||||
|
rm -rf obj
|
||||||
|
mkdir obj
|
||||||
|
mkdir -p bin
|
||||||
|
|
||||||
|
echo "----------------[kerep]-----------------"
|
||||||
|
compiler_call="$CMP $WARN $ARGS -c"
|
||||||
|
echo "$compiler_call"
|
||||||
|
OBJECTS=
|
||||||
|
for srcfile in $SRC
|
||||||
|
do
|
||||||
|
echo " $srcfile"
|
||||||
|
object="obj/$(basename $srcfile).o"
|
||||||
|
OBJECTS="$OBJECTS
|
||||||
|
$object"
|
||||||
|
command="$compiler_call $srcfile -o $object"
|
||||||
|
if ! $($command); then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
command="ar rcs $OUTFILE $OBJECTS"
|
||||||
|
echo "$command"
|
||||||
|
if $($command)
|
||||||
|
then
|
||||||
|
echo "static lib $OUTFILE created"
|
||||||
|
rm -r obj
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
17
kerep/src/Autoarr/Autoarr.c
Normal file
17
kerep/src/Autoarr/Autoarr.c
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#include "Autoarr.h"
|
||||||
|
|
||||||
|
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)
|
||||||
17
kerep/src/DtsodParser/DtsodV24.h
Normal file
17
kerep/src/DtsodParser/DtsodV24.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../Hashtable/Hashtable.h"
|
||||||
|
|
||||||
|
// parses text to binary values
|
||||||
|
Maybe DtsodV24_deserialize(char* text);
|
||||||
|
|
||||||
|
// creates text representation of dtsod
|
||||||
|
Maybe DtsodV24_serialize(Hashtable* dtsod);
|
||||||
|
|
||||||
|
#if __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
344
kerep/src/DtsodParser/DtsodV24_deserialize.c
Normal file
344
kerep/src/DtsodParser/DtsodV24_deserialize.c
Normal file
@@ -0,0 +1,344 @@
|
|||||||
|
#include "DtsodV24.h"
|
||||||
|
#include "../String/StringBuilder.h"
|
||||||
|
|
||||||
|
#define ARR_BC 64
|
||||||
|
#define ARR_BL 1024
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct DeserializeSharedData{
|
||||||
|
const char* sh_text_first;
|
||||||
|
char* sh_text;
|
||||||
|
bool sh_partOfDollarList;
|
||||||
|
bool sh_calledRecursively;
|
||||||
|
} DeserializeSharedData;
|
||||||
|
|
||||||
|
#define text shared->sh_text
|
||||||
|
#define partOfDollarList shared->sh_partOfDollarList
|
||||||
|
#define calledRecursively shared->sh_calledRecursively
|
||||||
|
|
||||||
|
|
||||||
|
// 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, i32 line, const char* funcname){
|
||||||
|
char errBuf[68];
|
||||||
|
for(u8 n=0; n<sizeof(errBuf);n++)
|
||||||
|
errBuf[n]='\0';
|
||||||
|
char* errText=_text-32;
|
||||||
|
u8 cplace=32;
|
||||||
|
if(errText<text_first) {
|
||||||
|
cplace=_text-text_first;
|
||||||
|
errText=text_first;
|
||||||
|
}
|
||||||
|
u8 i=0;
|
||||||
|
for(; i<cplace; i++){
|
||||||
|
// writes 32 chars before the wrongchar
|
||||||
|
errBuf[i]=errText[i];
|
||||||
|
}
|
||||||
|
//prints wrongchar in braces
|
||||||
|
errBuf[i++]='<';
|
||||||
|
errBuf[i++]=c;
|
||||||
|
errBuf[i++]='>';
|
||||||
|
for(; i<cplace+3+32; i++){
|
||||||
|
// writes 32 chars after the wrongchar
|
||||||
|
char _c=errText[i-2];
|
||||||
|
errBuf[i]=_c;
|
||||||
|
if(!_c) break;
|
||||||
|
}
|
||||||
|
char errmsg[1024];
|
||||||
|
IFMSC(
|
||||||
|
sprintf_s(errmsg,1024, "unexpected <%c> at:\n"
|
||||||
|
" \"%s\"\n"
|
||||||
|
"\\___[%s:%d] %s()",
|
||||||
|
c,errBuf, srcfile,line,funcname),
|
||||||
|
sprintf(errmsg, "unexpected <%c> at:\n"
|
||||||
|
" \"%s\"\n"
|
||||||
|
" \\___[%s:%d] %s()",
|
||||||
|
c,errBuf, srcfile,line,funcname)
|
||||||
|
);
|
||||||
|
safethrow(errmsg,;);
|
||||||
|
}
|
||||||
|
#define safethrow_wrongchar(C, freeMem) { freeMem; return ERROR_WRONGCHAR(C, text, shared->sh_text_first, __FILE__,__LINE__,__func__); }
|
||||||
|
|
||||||
|
|
||||||
|
Maybe __SkipComment(DeserializeSharedData* shared) {
|
||||||
|
char c;
|
||||||
|
|
||||||
|
while ((c=*++text) != '\n')
|
||||||
|
if (!c) safethrow(ERR_ENDOFSTR,;);
|
||||||
|
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
#define SkipComment() __SkipComment(shared)
|
||||||
|
|
||||||
|
Maybe __ReadName(DeserializeSharedData* shared){
|
||||||
|
char c;
|
||||||
|
string nameStr={text+1,0};
|
||||||
|
|
||||||
|
while ((c=*++text)) switch (c){
|
||||||
|
case ' ': case '\t':
|
||||||
|
case '\r': case '\n':
|
||||||
|
if(nameStr.length!=0)
|
||||||
|
safethrow_wrongchar(c,;);
|
||||||
|
nameStr.ptr++;
|
||||||
|
break;
|
||||||
|
case '=': case ';':
|
||||||
|
case '\'': case '"':
|
||||||
|
case '[': case ']':
|
||||||
|
case '{':
|
||||||
|
safethrow_wrongchar(c,;);
|
||||||
|
case '#': ;
|
||||||
|
char _c=c;
|
||||||
|
char* _text=text;
|
||||||
|
try(SkipComment(),_,;);
|
||||||
|
if(nameStr.length!=0){
|
||||||
|
text=_text;
|
||||||
|
safethrow_wrongchar(_c,;);
|
||||||
|
}
|
||||||
|
nameStr.ptr=text+1; // skips '\n'
|
||||||
|
break;
|
||||||
|
case '}':
|
||||||
|
if(!calledRecursively || nameStr.length!=0)
|
||||||
|
safethrow_wrongchar(c,;);
|
||||||
|
return SUCCESS(UniHeapPtr(char,NULL));
|
||||||
|
case ':':
|
||||||
|
return SUCCESS(UniHeapPtr(char,string_extract(nameStr)));
|
||||||
|
case '$':
|
||||||
|
if(nameStr.length!=0)
|
||||||
|
safethrow_wrongchar(c,;);
|
||||||
|
nameStr.ptr++;
|
||||||
|
partOfDollarList=true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
nameStr.length++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nameStr.length>0) safethrow(ERR_ENDOFSTR,;);
|
||||||
|
return SUCCESS(UniHeapPtr(char,NULL));
|
||||||
|
}
|
||||||
|
#define ReadName() __ReadName(shared)
|
||||||
|
|
||||||
|
Maybe __deserialize(char** _text, bool _calledRecursively);
|
||||||
|
Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList);
|
||||||
|
#define ReadValue(rL) __ReadValue(shared, rL)
|
||||||
|
|
||||||
|
// returns part of <text> without quotes
|
||||||
|
Maybe __ReadString(DeserializeSharedData* shared){
|
||||||
|
char c;
|
||||||
|
bool prevIsBackslash=false;
|
||||||
|
StringBuilder* b=StringBuilder_create();
|
||||||
|
|
||||||
|
while ((c=*++text)){
|
||||||
|
if(c=='"') {
|
||||||
|
if(prevIsBackslash) {
|
||||||
|
// replacing <\"> with <">
|
||||||
|
StringBuilder_rmchar(b);
|
||||||
|
StringBuilder_append_char(b,c);
|
||||||
|
prevIsBackslash=false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char* str=StringBuilder_build(b).ptr;
|
||||||
|
return SUCCESS(UniHeapPtr(char,str));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
prevIsBackslash= c=='\\' && !prevIsBackslash;
|
||||||
|
StringBuilder_append_char(b,c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
safethrow(ERR_ENDOFSTR, StringBuilder_free(b));
|
||||||
|
}
|
||||||
|
#define ReadString() __ReadString(shared)
|
||||||
|
|
||||||
|
Maybe __ReadList(DeserializeSharedData* shared){
|
||||||
|
Autoarr(Unitype)* list=Autoarr_create(Unitype,ARR_BC,ARR_BL);
|
||||||
|
bool readingList=true;
|
||||||
|
while (true){
|
||||||
|
try(ReadValue((&readingList)), m_val, Autoarr_free(list, true))
|
||||||
|
Autoarr_add(list,m_val.value);
|
||||||
|
if (!readingList){
|
||||||
|
if(Unitype_isUniNull(m_val.value))
|
||||||
|
Autoarr_pop(list);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS(UniHeapPtr(Autoarr_Unitype,list));
|
||||||
|
};
|
||||||
|
#define ReadList() __ReadList(shared)
|
||||||
|
|
||||||
|
Maybe __ParseValue(DeserializeSharedData* shared, string str){
|
||||||
|
const string trueStr={"true",4};
|
||||||
|
const string falseStr={"false",5};
|
||||||
|
|
||||||
|
switch(str.ptr[str.length-1]){
|
||||||
|
// Bool
|
||||||
|
case 'e':
|
||||||
|
if(string_compare(str,trueStr))
|
||||||
|
return SUCCESS(UniTrue);
|
||||||
|
else if(string_compare(str,falseStr))
|
||||||
|
return SUCCESS(UniFalse);
|
||||||
|
else safethrow_wrongchar(*str.ptr,;);
|
||||||
|
// Float64
|
||||||
|
case 'f': {
|
||||||
|
char* _c=string_extract(str);
|
||||||
|
Unitype rez=UniFloat64(strtod(_c,NULL));
|
||||||
|
free(_c);
|
||||||
|
return SUCCESS(rez);
|
||||||
|
}
|
||||||
|
// UInt64
|
||||||
|
case 'u': {
|
||||||
|
u64 lu=0;
|
||||||
|
char* _c=string_extract(str);
|
||||||
|
if(sscanf(_c, IFWIN("%llu", "%lu"), &lu)!=1){
|
||||||
|
char err[64];
|
||||||
|
IFMSC(
|
||||||
|
sprintf_s(err,64,"can't parse to int: <%s>",_c),
|
||||||
|
sprintf(err,"can't parse to int: <%s>",_c)
|
||||||
|
);
|
||||||
|
safethrow(err,free(_c));
|
||||||
|
}
|
||||||
|
free(_c);
|
||||||
|
return SUCCESS(UniUInt64(lu));
|
||||||
|
}
|
||||||
|
// Int64
|
||||||
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
|
case '5': case '6': case '7': case '8': case '9': {
|
||||||
|
i64 li=0;
|
||||||
|
char* _c=string_extract(str);
|
||||||
|
if(sscanf(_c, IFWIN("%lli", "%li"), &li)!=1){
|
||||||
|
char err[64];
|
||||||
|
IFMSC(
|
||||||
|
sprintf_s(err,64,"can't parse to int: <%s>",_c),
|
||||||
|
sprintf(err,"can't parse to int: <%s>",_c)
|
||||||
|
);
|
||||||
|
safethrow(err,free(_c));
|
||||||
|
}
|
||||||
|
free(_c);
|
||||||
|
return SUCCESS(UniInt64(li));
|
||||||
|
}
|
||||||
|
// wrong type
|
||||||
|
default:
|
||||||
|
safethrow_wrongchar(str.ptr[str.length-1],;);
|
||||||
|
}
|
||||||
|
|
||||||
|
safethrow(ERR_ENDOFSTR,;);
|
||||||
|
};
|
||||||
|
#define ParseValue(str) __ParseValue(shared, str)
|
||||||
|
|
||||||
|
Maybe __ReadValue(DeserializeSharedData* shared, bool* readingList){
|
||||||
|
char c;
|
||||||
|
string valueStr={text+1,0};
|
||||||
|
Unitype value=UniNull;
|
||||||
|
bool spaceAfterVal=false;
|
||||||
|
|
||||||
|
while ((c=*++text)) switch (c){
|
||||||
|
case ' ': case '\t':
|
||||||
|
case '\r': case '\n':
|
||||||
|
if(valueStr.length!=0)
|
||||||
|
spaceAfterVal=true;
|
||||||
|
else valueStr.ptr++;
|
||||||
|
break;
|
||||||
|
case '=': case ':':
|
||||||
|
case '}': case '$':
|
||||||
|
case '\'':
|
||||||
|
safethrow_wrongchar(c,Unitype_free(value));
|
||||||
|
case '#':;
|
||||||
|
char _c=c;
|
||||||
|
char* _text=text;
|
||||||
|
try(SkipComment(),_,;);
|
||||||
|
if(valueStr.length!=0){
|
||||||
|
text=_text;
|
||||||
|
safethrow_wrongchar(_c,Unitype_free(value));
|
||||||
|
}
|
||||||
|
valueStr.ptr=text+1; // skips '\n'
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
if(valueStr.length!=0) safethrow_wrongchar(c,Unitype_free(value));
|
||||||
|
try(ReadString(),maybeString,;)
|
||||||
|
value=maybeString.value;
|
||||||
|
break;
|
||||||
|
case '{':
|
||||||
|
if(valueStr.length!=0) safethrow_wrongchar(c,Unitype_free(value));
|
||||||
|
++text; // skips '{'
|
||||||
|
try(__deserialize(&text,true), val,Unitype_free(value))
|
||||||
|
value=val.value;
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
if(valueStr.length!=0) safethrow_wrongchar(c,Unitype_free(value));
|
||||||
|
try(ReadList(),maybeList,Unitype_free(value))
|
||||||
|
value=maybeList.value;
|
||||||
|
break;
|
||||||
|
case ']':
|
||||||
|
if(!readingList) safethrow_wrongchar(c,Unitype_free(value));
|
||||||
|
*readingList=false;
|
||||||
|
goto return_value;
|
||||||
|
case ';':
|
||||||
|
case ',':
|
||||||
|
return_value:
|
||||||
|
if(valueStr.length!=0){
|
||||||
|
if(!Unitype_isUniNull(value))
|
||||||
|
safethrow_wrongchar(c,Unitype_free(value));
|
||||||
|
try(ParseValue(valueStr),maybeParsed,;)
|
||||||
|
value=maybeParsed.value;
|
||||||
|
}
|
||||||
|
return SUCCESS(value);
|
||||||
|
default:
|
||||||
|
if(spaceAfterVal)
|
||||||
|
safethrow_wrongchar(c,Unitype_free(value));
|
||||||
|
valueStr.length++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
safethrow(ERR_ENDOFSTR,;);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Maybe __deserialize(char** _text, bool _calledRecursively) {
|
||||||
|
DeserializeSharedData _shared={
|
||||||
|
.sh_text_first=*_text,
|
||||||
|
.sh_text=*_text,
|
||||||
|
.sh_partOfDollarList=false,
|
||||||
|
.sh_calledRecursively=_calledRecursively
|
||||||
|
};
|
||||||
|
DeserializeSharedData* shared=&_shared;
|
||||||
|
Hashtable* dict=Hashtable_create();
|
||||||
|
|
||||||
|
text--;
|
||||||
|
while(true){
|
||||||
|
try(ReadName(), maybeName, Hashtable_free(dict))
|
||||||
|
if(!maybeName.value.VoidPtr) // end of file or '}' in recursive call
|
||||||
|
goto END;
|
||||||
|
char* nameCPtr=maybeName.value.VoidPtr;
|
||||||
|
try(ReadValue(NULL), val, {
|
||||||
|
Hashtable_free(dict);
|
||||||
|
free(nameCPtr);
|
||||||
|
}) {
|
||||||
|
if(partOfDollarList){
|
||||||
|
partOfDollarList=false;
|
||||||
|
Autoarr(Unitype)* list;
|
||||||
|
Unitype 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);
|
||||||
|
Hashtable_add(dict,nameCPtr,UniHeapPtr(Autoarr_Unitype,list));
|
||||||
|
}
|
||||||
|
Autoarr_add(list,val.value);
|
||||||
|
}
|
||||||
|
else Hashtable_add(dict,nameCPtr,val.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
END:
|
||||||
|
*_text=text;
|
||||||
|
return SUCCESS(UniHeapPtr(Hashtable,dict));
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe DtsodV24_deserialize(char* _text) {
|
||||||
|
return __deserialize(&_text, false);
|
||||||
|
}
|
||||||
130
kerep/src/DtsodParser/DtsodV24_serialize.c
Normal file
130
kerep/src/DtsodParser/DtsodV24_serialize.c
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
#include "DtsodV24.h"
|
||||||
|
#include "../String/StringBuilder.h"
|
||||||
|
|
||||||
|
|
||||||
|
STRUCT(SerializeSharedData,
|
||||||
|
StringBuilder* sh_builder;
|
||||||
|
u8 sh_tabs;
|
||||||
|
)
|
||||||
|
#define b shared->sh_builder
|
||||||
|
#define tabs shared->sh_tabs
|
||||||
|
|
||||||
|
Maybe __serialize(StringBuilder* _b, u8 _tabs, Hashtable* dtsod);
|
||||||
|
|
||||||
|
#define addc(C) StringBuilder_append_char(b,C)
|
||||||
|
|
||||||
|
|
||||||
|
void __AppendTabs(SerializeSharedData* shared) {
|
||||||
|
for (u8 t = 0; t < tabs; t++)
|
||||||
|
addc( '\t');
|
||||||
|
};
|
||||||
|
#define AppendTabs() __AppendTabs(shared)
|
||||||
|
|
||||||
|
Maybe __AppendValue(SerializeSharedData* shared, Unitype u);
|
||||||
|
#define AppendValue(UNI) __AppendValue(shared, UNI)
|
||||||
|
Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
|
||||||
|
if(u.typeId==ktid_name(i64)){
|
||||||
|
StringBuilder_append_i64(b,u.Int64);
|
||||||
|
}
|
||||||
|
else if(u.typeId==ktid_name(u64)){
|
||||||
|
StringBuilder_append_u64(b,u.UInt64);
|
||||||
|
addc('u');
|
||||||
|
}
|
||||||
|
else if(u.typeId==ktid_name(f64)){
|
||||||
|
StringBuilder_append_f64(b,u.Float64);
|
||||||
|
addc('f');
|
||||||
|
}
|
||||||
|
else if(u.typeId==ktid_ptrName(char)){
|
||||||
|
addc('"');
|
||||||
|
char c;
|
||||||
|
while((c=*(char*)(u.VoidPtr++))){
|
||||||
|
if(c=='\"') addc('\\');
|
||||||
|
addc(c);
|
||||||
|
}
|
||||||
|
addc('"');
|
||||||
|
}
|
||||||
|
else if(u.typeId==ktid_name(bool)){
|
||||||
|
StringBuilder_append_cptr(b, u.Bool ? "true" : "false");
|
||||||
|
}
|
||||||
|
else if(Unitype_isUniNull(u)){
|
||||||
|
safethrow("Null isn't supported in DtsodV24",;);
|
||||||
|
}
|
||||||
|
else if(u.typeId==ktid_ptrName(Autoarr_Unitype)){
|
||||||
|
if(Autoarr_length(((Autoarr_Unitype*)(u.VoidPtr)))){
|
||||||
|
addc('\n');
|
||||||
|
AppendTabs();
|
||||||
|
addc('[');
|
||||||
|
tabs++;
|
||||||
|
Autoarr_foreach(((Autoarr_Unitype*)(u.VoidPtr)), e,
|
||||||
|
addc('\n');
|
||||||
|
AppendTabs();
|
||||||
|
try(AppendValue(e),__,;);
|
||||||
|
addc(',');
|
||||||
|
);
|
||||||
|
StringBuilder_rmchar(b);
|
||||||
|
addc('\n');
|
||||||
|
tabs--;
|
||||||
|
AppendTabs();
|
||||||
|
addc(']');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addc('[');
|
||||||
|
addc(']');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(u.typeId==ktid_ptrName(Hashtable)){
|
||||||
|
// check hashtable is blank
|
||||||
|
bool hashtableNotBlank=false;
|
||||||
|
Hashtable_foreach(((Hashtable*)u.VoidPtr), __,
|
||||||
|
hashtableNotBlank=true;
|
||||||
|
if(__.key) {} // weird way to disable warning
|
||||||
|
break;
|
||||||
|
);
|
||||||
|
|
||||||
|
if(hashtableNotBlank){
|
||||||
|
addc('\n');
|
||||||
|
AppendTabs();
|
||||||
|
addc('{');
|
||||||
|
addc('\n');
|
||||||
|
try(__serialize(b,tabs+1,u.VoidPtr),___,;);
|
||||||
|
AppendTabs();
|
||||||
|
addc('}');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addc('{');
|
||||||
|
addc('}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dbg((u.typeId));
|
||||||
|
safethrow(ERR_WRONGTYPE,;);
|
||||||
|
}
|
||||||
|
return MaybeNull;
|
||||||
|
};
|
||||||
|
|
||||||
|
Maybe __serialize(StringBuilder* _b, u8 _tabs, Hashtable* dtsod){
|
||||||
|
SerializeSharedData _shared={
|
||||||
|
.sh_builder=_b,
|
||||||
|
.sh_tabs=_tabs
|
||||||
|
};
|
||||||
|
SerializeSharedData* shared=&_shared;
|
||||||
|
|
||||||
|
Hashtable_foreach(dtsod, p,
|
||||||
|
AppendTabs();
|
||||||
|
StringBuilder_append_cptr(b,p.key);
|
||||||
|
addc(':');
|
||||||
|
addc(' ');
|
||||||
|
try(AppendValue(p.value),__,;);
|
||||||
|
addc(';');
|
||||||
|
addc('\n');
|
||||||
|
);
|
||||||
|
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe DtsodV24_serialize(Hashtable* dtsod){
|
||||||
|
StringBuilder* sb=StringBuilder_create();
|
||||||
|
try(__serialize(sb,0,dtsod),__, StringBuilder_free(sb));
|
||||||
|
char* str=StringBuilder_build(sb).ptr;
|
||||||
|
return SUCCESS(UniHeapPtr(char, str));
|
||||||
|
}
|
||||||
69
kerep/src/Filesystem/dir.c
Normal file
69
kerep/src/Filesystem/dir.c
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
#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;
|
||||||
|
}
|
||||||
@@ -13,14 +13,14 @@ Maybe dir_create(const char* path);
|
|||||||
///@return Maybe<void>
|
///@return Maybe<void>
|
||||||
Maybe dir_delete(const char* path);
|
Maybe dir_delete(const char* path);
|
||||||
|
|
||||||
///@return Maybe<Array_string>
|
///@return Maybe<char**>
|
||||||
Maybe dir_getFiles(const char* path, bool recursive);
|
Maybe dir_getFiles(const char* path, bool recursive);
|
||||||
///@return Maybe<Array_string>
|
///@return Maybe<char**>
|
||||||
Maybe dir_getDirs(const char* path, bool recursive);
|
Maybe dir_getDirs(const char* path, bool recursive);
|
||||||
|
|
||||||
///@return Maybe<Array_string>
|
///@return Maybe<char**>
|
||||||
Maybe dir_findFiles(const char* path, char* searchPattern, bool recursive);
|
Maybe dir_findFiles(const char* path, char* searchPattern, bool recursive);
|
||||||
///@return Maybe<Array_string>
|
///@return Maybe<char**>
|
||||||
Maybe dir_findDirs(const char* path, char* searchPattern, bool recursive);
|
Maybe dir_findDirs(const char* path, char* searchPattern, bool recursive);
|
||||||
|
|
||||||
#if __cplusplus
|
#if __cplusplus
|
||||||
138
kerep/src/Filesystem/file.c
Normal file
138
kerep/src/Filesystem/file.c
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
#include "filesystem.h"
|
||||||
|
#include "../String/StringBuilder.h"
|
||||||
|
#include "io_includes.h"
|
||||||
|
|
||||||
|
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;
|
||||||
|
switch(m){
|
||||||
|
case FileOpenMode_Read: p="rb"; break;
|
||||||
|
case FileOpenMode_Write: p="wb"; break;
|
||||||
|
case FileOpenMode_Append: p="ab"; break;
|
||||||
|
case FileOpenMode_ReadWrite: p="wb+"; break;
|
||||||
|
case FileOpenMode_ReadAppend: p="ab+"; break;
|
||||||
|
default:
|
||||||
|
dbg(m);
|
||||||
|
throw(ERR_UNEXPECTEDVAL);
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(FileHandle,file));
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe file_close(FileHandle file){
|
||||||
|
if(!file)
|
||||||
|
safethrow(ERR_NULLPTR,;);
|
||||||
|
if(fclose(file))
|
||||||
|
safethrow(ERR_IO,;);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ioWriteCheck() \
|
||||||
|
if(rezult==EOF) \
|
||||||
|
safethrow(ERR_IO_EOF,;); \
|
||||||
|
if(rezult!=0) \
|
||||||
|
safethrow(ERR_IO,;);
|
||||||
|
|
||||||
|
Maybe file_writeChar(FileHandle file, char byte){
|
||||||
|
i32 rezult=fputc(byte, file);
|
||||||
|
ioWriteCheck();
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(FileHandle file, char* cptr){
|
||||||
|
i32 rezult=fputs(cptr, file);
|
||||||
|
ioWriteCheck();
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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(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;
|
||||||
|
}
|
||||||
|
if(ferror(file)) safethrow(ERR_IO,;);
|
||||||
|
return SUCCESS(UniUInt64(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe file_readAll(FileHandle file, char** allBytes){
|
||||||
|
i32 rezult=0;
|
||||||
|
char buffer[256];
|
||||||
|
string bufStr={.ptr=buffer, .length=sizeof(buffer)};
|
||||||
|
StringBuilder* sb=StringBuilder_create();
|
||||||
|
u64 i=0;
|
||||||
|
while(true){
|
||||||
|
rezult=fgetc(file);
|
||||||
|
if(rezult==EOF){
|
||||||
|
if(ferror(file))
|
||||||
|
safethrow(ERR_IO, StringBuilder_free(sb));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buffer[i%sizeof(buffer)]=(char)rezult;
|
||||||
|
i++;
|
||||||
|
if(!(i%sizeof(buffer)))
|
||||||
|
StringBuilder_append_string(sb,bufStr);
|
||||||
|
}
|
||||||
|
bufStr.length=i%sizeof(buffer);
|
||||||
|
if(bufStr.length!=0)
|
||||||
|
StringBuilder_append_string(sb,bufStr);
|
||||||
|
string str=StringBuilder_build(sb);
|
||||||
|
*allBytes=str.ptr;
|
||||||
|
// i dont know how can it happen, but if it will have, it will be very dangerous
|
||||||
|
if(i!=str.length)
|
||||||
|
throw(ERR_UNEXPECTEDVAL);
|
||||||
|
return SUCCESS(UniUInt64(i));
|
||||||
|
}
|
||||||
84
kerep/src/Filesystem/path.c
Normal file
84
kerep/src/Filesystem/path.c
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#include "filesystem.h"
|
||||||
|
|
||||||
|
char* __path_concat(u32 n, ...){
|
||||||
|
char** parts=(char**)malloc(n*sizeof(char*));
|
||||||
|
u32* lengths=malloc(n*sizeof(u32));
|
||||||
|
u32 totalLength=0;
|
||||||
|
|
||||||
|
// reading args from va_list
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, n);
|
||||||
|
for(u16 i=0; i<n; i++){
|
||||||
|
char* part=va_arg(vl,char*);
|
||||||
|
i16 length=cptr_length(part);
|
||||||
|
parts[i]=part;
|
||||||
|
lengths[i]=length;
|
||||||
|
totalLength+=length;
|
||||||
|
}
|
||||||
|
va_end(vl);
|
||||||
|
|
||||||
|
// allocating memory for output value
|
||||||
|
char* totality=malloc(totalLength+1);
|
||||||
|
const char* output=totality;
|
||||||
|
totality[totalLength]=0;
|
||||||
|
|
||||||
|
// copying content of all strings to rezult
|
||||||
|
u16 k=0;
|
||||||
|
for(; k<n-1; k++){
|
||||||
|
memcopy(parts[k], totality, lengths[k]);
|
||||||
|
totality+=lengths[k];
|
||||||
|
*totality=path_sep;
|
||||||
|
totality++;
|
||||||
|
}
|
||||||
|
memcopy(parts[k], totality, lengths[k]);
|
||||||
|
|
||||||
|
free(parts);
|
||||||
|
free(lengths);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* path_fixSeparators(const char* path){
|
||||||
|
char* pathCopy=cptr_copy(path);
|
||||||
|
char c;
|
||||||
|
while((c=*pathCopy)){
|
||||||
|
if(c==path_notSep)
|
||||||
|
*pathCopy=path_sep;
|
||||||
|
pathCopy++;
|
||||||
|
}
|
||||||
|
return pathCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
111
kerep/src/HashFunctions/hash.c
Normal file
111
kerep/src/HashFunctions/hash.c
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
#include "hash.h"
|
||||||
|
|
||||||
|
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 u32 crc_32_tab[]={
|
||||||
|
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
|
||||||
|
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||||||
|
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||||
|
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||||
|
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
|
||||||
|
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||||
|
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
|
||||||
|
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||||||
|
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||||
|
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||||
|
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
|
||||||
|
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||||
|
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
|
||||||
|
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
||||||
|
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||||
|
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||||||
|
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
|
||||||
|
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||||
|
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
|
||||||
|
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||||
|
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||||
|
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
|
||||||
|
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
|
||||||
|
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||||
|
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
|
||||||
|
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
|
||||||
|
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||||
|
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||||||
|
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
|
||||||
|
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||||
|
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
|
||||||
|
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||||||
|
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||||
|
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
||||||
|
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
|
||||||
|
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||||
|
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
|
||||||
|
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
|
||||||
|
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||||
|
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||||
|
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
|
||||||
|
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||||
|
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
|
||||||
|
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||||
|
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||||
|
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
|
||||||
|
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
|
||||||
|
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||||
|
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
|
||||||
|
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||||
|
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||||
|
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||||||
|
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
|
||||||
|
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||||
|
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
|
||||||
|
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||||||
|
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||||
|
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
|
||||||
|
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
|
||||||
|
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||||
|
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
|
||||||
|
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
|
||||||
|
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||||
|
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||||
|
};
|
||||||
|
|
||||||
|
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, u32 *crc, long *charcnt) {
|
||||||
|
// register FILE *fin;
|
||||||
|
// register u32 oldcrc32;
|
||||||
|
// register i32 c;
|
||||||
|
|
||||||
|
// oldcrc32 = 0xFFFFFFFF; *charcnt = 0;
|
||||||
|
// if ((fin=fopen(name, "r"))==NULL) {
|
||||||
|
// perror(name);
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// while ((c=getc(fin))!=EOF) {
|
||||||
|
// ++*charcnt;
|
||||||
|
// oldcrc32 = UPDC32(c, oldcrc32);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (ferror(fin)) {
|
||||||
|
// perror(name);
|
||||||
|
// *charcnt = -1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// fclose(fin);
|
||||||
|
|
||||||
|
// *crc = oldcrc32 = ~oldcrc32;
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
133
kerep/src/Hashtable/Hashtable.c
Normal file
133
kerep/src/Hashtable/Hashtable.c
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
#include "Hashtable.h"
|
||||||
|
|
||||||
|
kt_define(Hashtable, __Hashtable_free, NULL);
|
||||||
|
|
||||||
|
// amount of rows
|
||||||
|
static const u16 HT_HEIGHTS[]={17,61,257,1021,4099,16381,65521};
|
||||||
|
#define HT_HEIN_MIN 0
|
||||||
|
#define HT_HEIN_MAX 6
|
||||||
|
|
||||||
|
#define ARR_BC 2
|
||||||
|
#define ARR_BL 8
|
||||||
|
|
||||||
|
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(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(u16 i=0;i<HT_HEIGHTS[ht->hein];i++)
|
||||||
|
Autoarr_free(ht->rows[i], true);
|
||||||
|
free(ht->rows);
|
||||||
|
}
|
||||||
|
void Hashtable_free(Hashtable* ht){
|
||||||
|
__Hashtable_free(ht);
|
||||||
|
free(ht);
|
||||||
|
}
|
||||||
|
|
||||||
|
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(u16 i=0;i<HT_HEIGHTS[ht->hein];i++)
|
||||||
|
newrows[i]=Autoarr_create(KVPair,ARR_BC,ARR_BL);
|
||||||
|
|
||||||
|
for(u16 i=0;i<HT_HEIGHTS[ht->hein-1];i++){
|
||||||
|
Autoarr(KVPair)* ar=ht->rows[i];
|
||||||
|
u32 arlen=Autoarr_length(ar);
|
||||||
|
for(u32 k=0;k<arlen;k++){
|
||||||
|
KVPair p=Autoarr_get(ar,k);
|
||||||
|
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
|
||||||
|
// so dont replace this incorrect auto-generated function
|
||||||
|
Autoarr_freeWithoutMembers(ar, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(ht->rows);
|
||||||
|
ht->rows=newrows;
|
||||||
|
}
|
||||||
|
|
||||||
|
Autoarr(KVPair)* getrow(Hashtable* ht, char* key, bool can_expand){
|
||||||
|
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);
|
||||||
|
ar=ht->rows[hash%HT_HEIGHTS[ht->hein]];
|
||||||
|
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){
|
||||||
|
Autoarr(KVPair)* ar=getrow(ht,key,false);
|
||||||
|
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);
|
||||||
|
u32 arlen=Autoarr_length(ar);
|
||||||
|
for(u32 i=0;i<arlen;i++){
|
||||||
|
KVPair p=Autoarr_get(ar,i);
|
||||||
|
if(cptr_equals(key,p.key)) return p.value;
|
||||||
|
}
|
||||||
|
return UniNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Hashtable_tryGet(Hashtable* ht, char* key, Unitype* output){
|
||||||
|
Unitype u=Hashtable_get(ht,key);
|
||||||
|
*output=u;
|
||||||
|
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==NULL)
|
||||||
|
Hashtable_add(ht, key, u); // add
|
||||||
|
else *val=u; // set
|
||||||
|
}
|
||||||
18
kerep/src/Hashtable/KeyValuePair.c
Normal file
18
kerep/src/Hashtable/KeyValuePair.c
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#include "KeyValuePair.h"
|
||||||
|
|
||||||
|
kt_define(KVPair, __KVPair_free, NULL);
|
||||||
|
|
||||||
|
Autoarr_define(KVPair, false)
|
||||||
|
|
||||||
|
// 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); }
|
||||||
|
|
||||||
|
void printkvp(KVPair p){
|
||||||
|
kprintf("{\"%s\", ",p.key);
|
||||||
|
printuni(p.value);
|
||||||
|
kprintf("}");
|
||||||
|
}
|
||||||
147
kerep/src/String/StringBuilder.c
Normal file
147
kerep/src/String/StringBuilder.c
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
#include "StringBuilder.h"
|
||||||
|
|
||||||
|
kt_define(StringBuilder, __StringBuilder_free, NULL);
|
||||||
|
|
||||||
|
#define BL_C 32
|
||||||
|
#define BL_L 1024
|
||||||
|
|
||||||
|
|
||||||
|
void complete_buf(StringBuilder* b){
|
||||||
|
if(!b->compl_bufs)
|
||||||
|
b->compl_bufs=Autoarr_create(string,BL_C,BL_L);
|
||||||
|
u32 len=Autoarr_length(b->curr_buf);
|
||||||
|
if(!len) return;
|
||||||
|
string str={.length=len, .ptr=malloc(len)};
|
||||||
|
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(i8,BL_C,BL_L);
|
||||||
|
}
|
||||||
|
|
||||||
|
void try_complete_buf(StringBuilder* b){
|
||||||
|
if(b->curr_buf->blocks_count==BL_C)
|
||||||
|
complete_buf(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
StringBuilder* StringBuilder_create(){
|
||||||
|
StringBuilder* b=malloc(sizeof(StringBuilder));
|
||||||
|
b->compl_bufs=NULL;
|
||||||
|
b->curr_buf=Autoarr_create(i8,BL_C,BL_L);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __StringBuilder_free(void* _b){
|
||||||
|
StringBuilder* b=_b;
|
||||||
|
if(b->compl_bufs) Autoarr_free(b->compl_bufs, true);
|
||||||
|
Autoarr_free(b->curr_buf, true);
|
||||||
|
}
|
||||||
|
void StringBuilder_free(StringBuilder* b){
|
||||||
|
__StringBuilder_free(b);
|
||||||
|
free(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
string StringBuilder_build(StringBuilder* b){
|
||||||
|
complete_buf(b);
|
||||||
|
u32 len=0;
|
||||||
|
Autoarr_foreach(b->compl_bufs, cs,
|
||||||
|
len+=cs.length;
|
||||||
|
);
|
||||||
|
string str= { .length=len, .ptr=malloc(len+1) };
|
||||||
|
str.ptr[len]='\0';
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StringBuilder_rmchar(StringBuilder* b){
|
||||||
|
if(b->curr_buf->block_length!=0)
|
||||||
|
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));
|
||||||
|
lastcb->length--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StringBuilder_append_char(StringBuilder* b, char c){
|
||||||
|
try_complete_buf(b);
|
||||||
|
Autoarr_add(b->curr_buf,c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StringBuilder_append_string(StringBuilder* b, string s){
|
||||||
|
complete_buf(b);
|
||||||
|
Autoarr_add(b->compl_bufs, string_copy(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringBuilder_append_cptr(StringBuilder* b, char* s){
|
||||||
|
string str={
|
||||||
|
.ptr=s,
|
||||||
|
.length=cptr_length(s)
|
||||||
|
};
|
||||||
|
StringBuilder_append_string(b,str);
|
||||||
|
}
|
||||||
|
|
||||||
|
void curr_buf_add_string(StringBuilder* b, string s){
|
||||||
|
for(u32 i=0; i<s.length; i++)
|
||||||
|
Autoarr_add(b->curr_buf,s.ptr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringBuilder_append_i64(StringBuilder* b, i64 a){
|
||||||
|
try_complete_buf(b);
|
||||||
|
u8 i=0;
|
||||||
|
if(a==0){
|
||||||
|
Autoarr_add(b->curr_buf,'0');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(a<0){
|
||||||
|
Autoarr_add(b->curr_buf,'-');
|
||||||
|
a=-a;
|
||||||
|
}
|
||||||
|
char buf[24];
|
||||||
|
while(a!=0){
|
||||||
|
buf[i++]='0'+a%10;
|
||||||
|
a/=10;
|
||||||
|
}
|
||||||
|
string rev=string_reverse((string){buf,i});
|
||||||
|
curr_buf_add_string(b,rev);
|
||||||
|
free(rev.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringBuilder_append_u64(StringBuilder* b, u64 a){
|
||||||
|
try_complete_buf(b);
|
||||||
|
u8 i=0;
|
||||||
|
if(a==0){
|
||||||
|
Autoarr_add(b->curr_buf,'0');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
char buf[24];
|
||||||
|
while(a!=0){
|
||||||
|
buf[i++]='0'+a%10;
|
||||||
|
a/=10;
|
||||||
|
}
|
||||||
|
string rev=string_reverse((string){buf,i});
|
||||||
|
curr_buf_add_string(b,rev);
|
||||||
|
free(rev.ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringBuilder_append_f64(StringBuilder* b, f64 a){
|
||||||
|
try_complete_buf(b);
|
||||||
|
char buf[32];
|
||||||
|
IFMSC(
|
||||||
|
sprintf_s(buf,32,"%lf",a),
|
||||||
|
sprintf(buf,"%lf",a)
|
||||||
|
);
|
||||||
|
curr_buf_add_string(b, (string){.ptr=buf, .length=cptr_length(buf)});
|
||||||
|
}
|
||||||
47
kerep/src/String/string.c
Normal file
47
kerep/src/String/string.c
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
kt_define(string, NULL, NULL);
|
||||||
|
Autoarr_define(string, false);
|
||||||
|
|
||||||
|
// copies str content to new char pointer value (adding '\0' at the end)
|
||||||
|
char* string_extract(string str){
|
||||||
|
if(str.length==0) return NULL;
|
||||||
|
char* cptr=malloc(str.length*sizeof(char)+1);
|
||||||
|
cptr[str.length]=0;
|
||||||
|
while(str.length-->0)
|
||||||
|
cptr[str.length]=str.ptr[str.length];
|
||||||
|
return cptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copies src.ptr content to new string and adds \0 at the end
|
||||||
|
string string_copy(string src){
|
||||||
|
if(!src.ptr)
|
||||||
|
return src;
|
||||||
|
string nstr;
|
||||||
|
nstr.length=src.length;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compares two strings, NullPtr-friendly
|
||||||
|
bool string_compare(string str0, string str1){
|
||||||
|
if(str0.length!=str1.length) return false;
|
||||||
|
if(!str0.ptr) return str1.ptr ? false : true;
|
||||||
|
else if(!str1.ptr) return false;
|
||||||
|
while(str0.length-->0)
|
||||||
|
if(*str0.ptr++ != *str1.ptr++)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// creates new string which is reversed variant of <s>
|
||||||
|
string string_reverse(string s){
|
||||||
|
if(s.length==0) return s;
|
||||||
|
string r={malloc(s.length), s.length};
|
||||||
|
for(u32 i=0; i<s.length; i++)
|
||||||
|
r.ptr[i]=s.ptr[s.length-i-1];
|
||||||
|
return r;
|
||||||
|
}
|
||||||
217
kerep/src/base/cptr.c
Normal file
217
kerep/src/base/cptr.c
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
#include "base.h"
|
||||||
|
#include "../String/StringBuilder.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
// returns length of char buffer (without \0)
|
||||||
|
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(const char* src){
|
||||||
|
u32 len=cptr_length(src)+1;
|
||||||
|
char* dst=malloc(len);
|
||||||
|
while(len--!=0)
|
||||||
|
dst[len]=src[len];
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
// multiplies char n times
|
||||||
|
char* char_multiply(char c, u32 n){
|
||||||
|
char* rez=malloc(n+1);
|
||||||
|
rez[n]=0;
|
||||||
|
while(n--!=0)
|
||||||
|
rez[n]=c;
|
||||||
|
return rez;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(u32 i=0; i<size; i++)
|
||||||
|
((char*)to)[i]=((char*)from)[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
char* __cptr_concat(u32 n, ...){
|
||||||
|
char** strs=(char**)malloc(n*sizeof(char*));
|
||||||
|
u32* lengths=malloc(n*sizeof(u32));
|
||||||
|
u32 totalLength=0;
|
||||||
|
|
||||||
|
// reading args from va_list
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, n);
|
||||||
|
for(u16 i=0; i<n; i++){
|
||||||
|
char* str=va_arg(vl,char*);
|
||||||
|
i16 length=cptr_length(str);
|
||||||
|
strs[i]=str;
|
||||||
|
lengths[i]=length;
|
||||||
|
totalLength+=length;
|
||||||
|
}
|
||||||
|
va_end(vl);
|
||||||
|
|
||||||
|
// allocating memory for output value
|
||||||
|
char* totality=malloc(totalLength+1);
|
||||||
|
char* output=totality;
|
||||||
|
totality[totalLength]=0;
|
||||||
|
|
||||||
|
// copying content of all strings to rezult
|
||||||
|
for(u16 k=0; k<n; k++){
|
||||||
|
memcopy(strs[k], totality, lengths[k]);
|
||||||
|
totality+=lengths[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
free(strs);
|
||||||
|
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;
|
||||||
|
}
|
||||||
13
kerep/src/base/endian.c
Normal file
13
kerep/src/base/endian.c
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#include "endian.h"
|
||||||
|
|
||||||
|
static const union
|
||||||
|
{
|
||||||
|
u16 number;
|
||||||
|
Endian bytes[2];
|
||||||
|
} _endian_union={ .number=0x0102 };
|
||||||
|
|
||||||
|
Endian getEndian(){
|
||||||
|
// if 0x0102 == { 1, 2 } then BigEndian
|
||||||
|
// if 0x0102 == { 2, 1 } then LittleEndian
|
||||||
|
return _endian_union.bytes[1];
|
||||||
|
}
|
||||||
59
kerep/src/base/errors.c
Normal file
59
kerep/src/base/errors.c
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#include "std.h"
|
||||||
|
#include "errors.h"
|
||||||
|
#include "cptr.h"
|
||||||
|
#include "../kprint/kprintf.h"
|
||||||
|
|
||||||
|
char* errname(ErrorId err){
|
||||||
|
switch(err){
|
||||||
|
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, i32 line, const char* funcname){
|
||||||
|
size_t bufsize=ERRMSG_MAXLENGTH;
|
||||||
|
char* rezult=malloc(bufsize);
|
||||||
|
IFMSC(
|
||||||
|
sprintf_s(rezult,bufsize,"[%s:%d] %s() throwed error: %s",srcfile,line,funcname,errmsg),
|
||||||
|
sprintf(rezult,"[%s:%d] %s() throwed error: %s",srcfile,line,funcname,errmsg)
|
||||||
|
);
|
||||||
|
return rezult;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(
|
||||||
|
sprintf_s(rezult,bufsize,"%s\n \\___[%s:%d] %s()",errmsg,srcfile,line,funcname),
|
||||||
|
sprintf(rezult,"%s\n \\___[%s:%d] %s()",errmsg,srcfile,line,funcname)
|
||||||
|
);
|
||||||
|
free(errmsg);
|
||||||
|
return rezult;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Maybe_free(Maybe e){
|
||||||
|
free(e.errmsg);
|
||||||
|
Unitype_free(e.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void printMaybe(Maybe e){
|
||||||
|
if(e.errmsg) kprintf("%s\n",e.errmsg);
|
||||||
|
else printuni(e.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* __doNothing(char* a) {return a;}
|
||||||
|
|
||||||
|
char* __unknownErr() {return "UNKNOWN ERROR";}
|
||||||
@@ -38,6 +38,10 @@ typedef u8 bool;
|
|||||||
#define false 0
|
#define false 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef typeof
|
||||||
|
#define typeof __typeof__
|
||||||
|
#endif
|
||||||
|
|
||||||
#define dbg(N) kprintf("\e[95m%d\n",N)
|
#define dbg(N) kprintf("\e[95m%d\n",N)
|
||||||
|
|
||||||
#define nameof(V) #V
|
#define nameof(V) #V
|
||||||
238
kerep/src/base/type_system/base_toString.c
Normal file
238
kerep/src/base/type_system/base_toString.c
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
#include "base_toString.h"
|
||||||
|
#include "../base.h"
|
||||||
|
#include "../../kprint/kprint_format.h"
|
||||||
|
|
||||||
|
|
||||||
|
// accepts char* (ptr to char) and char* (ptr to string)
|
||||||
|
// uses format kp_s and kp_c to determine what type is <c> argument
|
||||||
|
char* __toString_char(void* c, u32 fmt) {
|
||||||
|
// *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;
|
||||||
|
}
|
||||||
|
else throw(ERR_FORMAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* __toString_bool(void* c, u32 fmt) {
|
||||||
|
static const char _strbool[4][6]={ "false", "true\0", "False", "True\0" };
|
||||||
|
u8 strind=*(bool*)c==1 + kp_fmt_isUpper(fmt)*2;
|
||||||
|
char* rez=malloc(6);
|
||||||
|
rez[0]=_strbool[strind][0];
|
||||||
|
rez[1]=_strbool[strind][1];
|
||||||
|
rez[2]=_strbool[strind][2];
|
||||||
|
rez[3]=_strbool[strind][3];
|
||||||
|
rez[4]=_strbool[strind][4];
|
||||||
|
rez[5]=0;
|
||||||
|
return rez;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* toString_i64(i64 n){
|
||||||
|
i64 d=n<0 ? -1*n : n;
|
||||||
|
char str[32];
|
||||||
|
u8 i=sizeof(str);
|
||||||
|
str[--i]=0;
|
||||||
|
if(d==0)
|
||||||
|
str[--i]='0';
|
||||||
|
else while(d!=0){
|
||||||
|
str[--i]='0' + d%10;
|
||||||
|
d/=10;
|
||||||
|
}
|
||||||
|
if(n<0)
|
||||||
|
str[--i]='-';
|
||||||
|
return cptr_copy((char*)str+i);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* toString_u64(u64 n, bool withPostfix, bool uppercase){
|
||||||
|
char str[32];
|
||||||
|
u8 i=sizeof(str);
|
||||||
|
str[--i]=0;
|
||||||
|
if(withPostfix)
|
||||||
|
str[--i]= uppercase ? 'U' : 'u';
|
||||||
|
if(n==0)
|
||||||
|
str[--i]='0';
|
||||||
|
else while(n!=0){
|
||||||
|
str[--i]='0' + n%10;
|
||||||
|
n/=10;
|
||||||
|
}
|
||||||
|
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; \
|
||||||
|
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_f32(f32 n, u8 precision, bool withPostfix, bool uppercase)
|
||||||
|
_toString_float_impl(48, toString_f32_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' + (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, u32 size, bool inverse, bool withPrefix){
|
||||||
|
char* bytes=_bytes;
|
||||||
|
char* str=malloc(size*8 + (withPrefix?2:0) +1);
|
||||||
|
u32 cn=0; // char number
|
||||||
|
if(withPrefix){
|
||||||
|
str[cn++]='0';
|
||||||
|
str[cn++]='b';
|
||||||
|
}
|
||||||
|
if(inverse){
|
||||||
|
// byte number
|
||||||
|
for(i32 bn=size-1; bn>=0; bn--)
|
||||||
|
byte_to_bits(bytes[bn])
|
||||||
|
} else {
|
||||||
|
for(u32 bn=0; bn<size; bn++)
|
||||||
|
byte_to_bits(bytes[bn])
|
||||||
|
}
|
||||||
|
str[cn]=0;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
// converts number from 0 to F to char
|
||||||
|
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:
|
||||||
|
return '0'+u;
|
||||||
|
case 0xA: case 0xB: case 0xC:
|
||||||
|
case 0xD: case 0xE: case 0xF:
|
||||||
|
return (uppercase ? 'A' : 'a') + u -10;
|
||||||
|
default:
|
||||||
|
dbg(u);
|
||||||
|
throw("incorrect number");
|
||||||
|
return 219;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
u32 cn=0; // char number
|
||||||
|
if(withPrefix){
|
||||||
|
str[cn++]='0';
|
||||||
|
str[cn++]='x';
|
||||||
|
}
|
||||||
|
// left to right
|
||||||
|
if(inverse){
|
||||||
|
// byte number
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// right to left
|
||||||
|
else {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
str[cn]=0;
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#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_i32_def(8)
|
||||||
|
__toString_i32_def(16)
|
||||||
|
__toString_i32_def(32)
|
||||||
|
__toString_i32_def(64)
|
||||||
|
|
||||||
|
#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; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#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)
|
||||||
|
__toString_float_def(64)
|
||||||
65
kerep/src/base/type_system/init.c
Normal file
65
kerep/src/base/type_system/init.c
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#include "../base.h"
|
||||||
|
#include "../../Autoarr/Autoarr.h"
|
||||||
|
#include "../../Hashtable/Hashtable.h"
|
||||||
|
#include "../../String/StringBuilder.h"
|
||||||
|
#include "../../Filesystem/filesystem.h"
|
||||||
|
#include "base_toString.h"
|
||||||
|
|
||||||
|
void kt_initKerepTypes(){
|
||||||
|
// base types
|
||||||
|
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);
|
||||||
|
|
||||||
|
// base type autoarrs
|
||||||
|
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);
|
||||||
|
kt_register(Autoarr_Unitype);
|
||||||
|
|
||||||
|
// KeyValuePair
|
||||||
|
kt_register(KVPair);
|
||||||
|
kt_register(Autoarr_KVPair);
|
||||||
|
|
||||||
|
// Hashtable
|
||||||
|
kt_register(Hashtable);
|
||||||
|
|
||||||
|
// string
|
||||||
|
kt_register(string);
|
||||||
|
kt_register(Autoarr_string);
|
||||||
|
|
||||||
|
// StringBuilder
|
||||||
|
kt_register(StringBuilder);
|
||||||
|
|
||||||
|
//File
|
||||||
|
kt_register(FileHandle);
|
||||||
|
}
|
||||||
90
kerep/src/base/type_system/kt_functions.c
Normal file
90
kerep/src/base/type_system/kt_functions.c
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
#include "../../Autoarr/Autoarr.h"
|
||||||
|
#include "type_system.h"
|
||||||
|
#include "base_toString.h"
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(){
|
||||||
|
#if DEBUG
|
||||||
|
kprintf("\e[94mtype descriptors initializing...\n");
|
||||||
|
#endif
|
||||||
|
__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);
|
||||||
|
#if DEBUG
|
||||||
|
kprintf("\e[92minitialized %u type descriptors\n", ktid_last);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void __kt_register(ktDescriptor* descriptor){
|
||||||
|
descriptor->id=++ktid_last;
|
||||||
|
Autoarr_add(__descriptorPointers, descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 kt_free(){
|
||||||
|
free(typeDescriptors);
|
||||||
|
}
|
||||||
100
kerep/src/base/type_system/unitype.c
Normal file
100
kerep/src/base/type_system/unitype.c
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
#include "../../kprint/kprint_format.h"
|
||||||
|
#include "../base.h"
|
||||||
|
|
||||||
|
char *__Unitype_toString(void *_u, u32 fmt)
|
||||||
|
{
|
||||||
|
return Unitype_toString(*(Unitype *)_u, fmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printuni(Unitype v)
|
||||||
|
{
|
||||||
|
char *s = Unitype_toString(v, 0);
|
||||||
|
fputs(s, stdout);
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
211
kerep/src/kprint/kprint.c
Normal file
211
kerep/src/kprint/kprint.c
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
#include "../String/StringBuilder.h"
|
||||||
|
#include "kprint.h"
|
||||||
|
|
||||||
|
ktid __typeFromFormat(kp_fmt f){
|
||||||
|
ktid typeId=kp_fmt_ktid(f);
|
||||||
|
if(typeId)
|
||||||
|
return typeId;
|
||||||
|
switch(kp_fmt_dataFormat(f)){
|
||||||
|
case kp_i:
|
||||||
|
case kp_h:
|
||||||
|
case kp_b:
|
||||||
|
return ktid_name(i64);
|
||||||
|
case kp_u:
|
||||||
|
return ktid_name(u64);
|
||||||
|
case kp_f:
|
||||||
|
return ktid_name(f64);
|
||||||
|
case kp_c:
|
||||||
|
return ktid_name(char);
|
||||||
|
case kp_s:
|
||||||
|
return ktid_ptrName(char);
|
||||||
|
default:
|
||||||
|
return ktid_undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe __next_toString(kp_fmt f, void* object){
|
||||||
|
// detecting type
|
||||||
|
ktid typeId=__typeFromFormat(f);
|
||||||
|
if(typeId==ktid_undefined)
|
||||||
|
safethrow("typeId is undefined, can't autodetect type",;);
|
||||||
|
|
||||||
|
if(typeId==ktid_ptrName(char))
|
||||||
|
object=*(char**)object; // dereferencing char** to char*
|
||||||
|
|
||||||
|
ktDescriptor* type=ktDescriptor_get(typeId);
|
||||||
|
if(!type->toString)
|
||||||
|
safethrow("type descriptor doesnt have toString() func",;);
|
||||||
|
return SUCCESS(UniHeapPtr(char, type->toString(object, f)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe check_argsN(u8 n){
|
||||||
|
if(n%2 != 0) safethrow("kprint recieved non-even number of arguments",;);
|
||||||
|
if(n > 32) safethrow("kprint recieved >32 number of arguments",;);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe __ksprint(u8 n, kp_fmt* formats, __kp_value_union* objects){
|
||||||
|
try(check_argsN(n), _,;);
|
||||||
|
n/=2;
|
||||||
|
StringBuilder* strb=StringBuilder_create();
|
||||||
|
for(u8 i=0; i<n; i++){
|
||||||
|
try(__next_toString(formats[i], &objects[i]),mStr,;);
|
||||||
|
StringBuilder_append_cptr(strb, mStr.value.VoidPtr);
|
||||||
|
Unitype_free(mStr.value);
|
||||||
|
}
|
||||||
|
char* rezult=StringBuilder_build(strb).ptr;
|
||||||
|
return SUCCESS(UniHeapPtr(char, rezult));
|
||||||
|
}
|
||||||
|
|
||||||
|
Maybe __kfprint(FILE* file, u8 n, kp_fmt* formats, __kp_value_union* objects){
|
||||||
|
try(check_argsN(n), _,;);
|
||||||
|
n/=2;
|
||||||
|
for(u8 i=0; i<n; i++){
|
||||||
|
try(__next_toString(formats[i], &objects[i]),maybeStr,;);
|
||||||
|
if(fputs(maybeStr.value.VoidPtr, file)==EOF)
|
||||||
|
safethrow("can't write string to file", Unitype_free(maybeStr.value));
|
||||||
|
Unitype_free(maybeStr.value);
|
||||||
|
}
|
||||||
|
fflush(file);
|
||||||
|
return MaybeNull;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __kprint(u8 n, kp_fmt* formats, __kp_value_union* objects){
|
||||||
|
tryLast(check_argsN(n), _,;);
|
||||||
|
n/=2;
|
||||||
|
for(u8 i=0; i<n; i++){
|
||||||
|
kp_fmt fmt=formats[i];
|
||||||
|
kprint_setColor(fmt);
|
||||||
|
tryLast(__next_toString(fmt, &objects[i]),maybeStr, kprint_setColor(kp_bgBlack|kp_fgGray));
|
||||||
|
if(fputs(maybeStr.value.VoidPtr, stdout)==EOF) \
|
||||||
|
throw("can't write string to stdout");
|
||||||
|
//, Unitype_free(maybeStr.value)
|
||||||
|
Unitype_free(maybeStr.value);
|
||||||
|
}
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_WIN32)|| defined(_WIN64)
|
||||||
|
#include <windows.h>
|
||||||
|
#define FOREGROUND_YELLOW FOREGROUND_GREEN | FOREGROUND_RED
|
||||||
|
|
||||||
|
DWORD kp_fgColor_toWin(kp_fgColor f){
|
||||||
|
//kprintf("fg: %x\n", f);
|
||||||
|
switch(f){
|
||||||
|
case kp_fgBlack: return 0;
|
||||||
|
case kp_fgRedD: return FOREGROUND_RED;
|
||||||
|
case kp_fgGreenD: return FOREGROUND_GREEN;
|
||||||
|
case kp_fgYellowD: return FOREGROUND_GREEN | FOREGROUND_RED;
|
||||||
|
case kp_fgBlueD: return FOREGROUND_BLUE;
|
||||||
|
case kp_fgMagentaD: return FOREGROUND_RED | FOREGROUND_BLUE;
|
||||||
|
case kp_fgCyanD: return FOREGROUND_BLUE | FOREGROUND_GREEN;
|
||||||
|
case kp_fgGray: return FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
|
||||||
|
case kp_fgGrayD: return FOREGROUND_INTENSITY;
|
||||||
|
case kp_fgRed: return FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||||
|
case kp_fgGreen: return FOREGROUND_GREEN | FOREGROUND_INTENSITY;
|
||||||
|
case kp_fgYellow: return FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||||
|
case kp_fgBlue: return FOREGROUND_BLUE | FOREGROUND_INTENSITY;
|
||||||
|
case kp_fgMagenta: return FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||||
|
case kp_fgCyan: return FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
|
||||||
|
case kp_fgWhite: return FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
|
||||||
|
default: throw(ERR_FORMAT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD kp_bgColor_toWin(kp_bgColor f){
|
||||||
|
//kprintf("bg: %x\n", f);
|
||||||
|
switch(f){
|
||||||
|
case kp_bgBlack: return 0;
|
||||||
|
case kp_bgRedD: return BACKGROUND_RED;
|
||||||
|
case kp_bgGreenD: return BACKGROUND_GREEN;
|
||||||
|
case kp_bgYellowD: return BACKGROUND_GREEN | BACKGROUND_RED;
|
||||||
|
case kp_bgBlueD: return BACKGROUND_BLUE;
|
||||||
|
case kp_bgMagentaD: return BACKGROUND_RED | BACKGROUND_BLUE;
|
||||||
|
case kp_bgCyanD: return BACKGROUND_BLUE | BACKGROUND_GREEN;
|
||||||
|
case kp_bgGray: return BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
|
||||||
|
case kp_bgGrayD: return BACKGROUND_INTENSITY;
|
||||||
|
case kp_bgRed: return BACKGROUND_RED | BACKGROUND_INTENSITY;
|
||||||
|
case kp_bgGreen: return BACKGROUND_GREEN | BACKGROUND_INTENSITY;
|
||||||
|
case kp_bgYellow: return BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY;
|
||||||
|
case kp_bgBlue: return BACKGROUND_BLUE | BACKGROUND_INTENSITY;
|
||||||
|
case kp_bgMagenta: return BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY;
|
||||||
|
case kp_bgCyan: return BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
|
||||||
|
case kp_bgWhite: return BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
|
||||||
|
default: throw(ERR_FORMAT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void kprint_setColor(kp_fmt f){
|
||||||
|
DWORD color=0;
|
||||||
|
if(!kp_fmt_fgColorSet(f) & !kp_fmt_bgColorSet(f))
|
||||||
|
return;
|
||||||
|
if(kp_fmt_fgColorSet(f))
|
||||||
|
color+=kp_fgColor_toWin(kp_fmt_fgColor(f));
|
||||||
|
if(kp_fmt_bgColorSet(f))
|
||||||
|
color+=kp_bgColor_toWin(kp_fmt_bgColor(f));
|
||||||
|
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
SetConsoleTextAttribute(hConsole, color);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void kprint_setColor(kp_fmt f){
|
||||||
|
if(kp_fmt_fgColorSet(f)){
|
||||||
|
u8 fg=(f&0x0f000000)>>24;
|
||||||
|
if(fg<8) fg+=30;
|
||||||
|
else fg+=90-8;
|
||||||
|
printf("\e[%um", fg);
|
||||||
|
}
|
||||||
|
if(kp_fmt_bgColorSet(f)){
|
||||||
|
u8 bg=(f&0x00f00000)>>20;
|
||||||
|
if(bg<8) bg+=40;
|
||||||
|
else bg+=100-8;
|
||||||
|
printf("\e[%um", bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Maybe ksprint_ar(u32 count, kp_fmt format, ktid typeId, void* array){
|
||||||
|
ktDescriptor* type=ktDescriptor_get(format.typeId);
|
||||||
|
if(!type->toString)
|
||||||
|
safethrow("type descriptor doesnt have toString() func",;);
|
||||||
|
StringBuilder* strb=StringBuilder_create();
|
||||||
|
StringBuilder_append_char(strb, '[');
|
||||||
|
for (u16 e=1; e<count; e++){
|
||||||
|
StringBuilder_append_char(strb, ' ');
|
||||||
|
char* elStr=type->toString(array+type->size*e, &format);
|
||||||
|
StringBuilder_append_cptr(strb, elStr);
|
||||||
|
StringBuilder_append_char(strb, ',');
|
||||||
|
}
|
||||||
|
StringBuilder_rmchar(strb);
|
||||||
|
StringBuilder_append_char(strb, ' ');
|
||||||
|
StringBuilder_append_char(strb, ']');
|
||||||
|
} */
|
||||||
|
|
||||||
|
static const char* _kp_colorNames[16]={
|
||||||
|
"black",
|
||||||
|
"dark_red",
|
||||||
|
"dark_green",
|
||||||
|
"dark_yellow",
|
||||||
|
"dark_blue",
|
||||||
|
"dark_magenta",
|
||||||
|
"dark_cyan",
|
||||||
|
"gray",
|
||||||
|
"dark_gray",
|
||||||
|
"red",
|
||||||
|
"green",
|
||||||
|
"yellow",
|
||||||
|
"blue",
|
||||||
|
"magenta",
|
||||||
|
"cyan",
|
||||||
|
"white"
|
||||||
|
};
|
||||||
|
|
||||||
|
char* kp_bgColor_toString(kp_bgColor c){
|
||||||
|
u32 color_index=(c&0x00f00000)>>20;
|
||||||
|
if(color_index>15) throw(ERR_WRONGINDEX);
|
||||||
|
return _kp_colorNames[color_index];
|
||||||
|
}
|
||||||
|
char* kp_fgColor_toString(kp_fgColor c){
|
||||||
|
u32 color_index=(c&0x00f00000)>>24;
|
||||||
|
if(color_index>15) throw(ERR_WRONGINDEX);
|
||||||
|
return _kp_colorNames[color_index];
|
||||||
|
}
|
||||||
155
kerep/src/kprint/kprintf.c
Normal file
155
kerep/src/kprint/kprintf.c
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
#include "kprintf.h"
|
||||||
|
#include "../base/base.h"
|
||||||
|
|
||||||
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
WORD unixColorToWin(u8 c){
|
||||||
|
switch(c){
|
||||||
|
//foreground
|
||||||
|
case 30: return 0;
|
||||||
|
case 31: return FOREGROUND_RED;
|
||||||
|
case 32: return FOREGROUND_GREEN;
|
||||||
|
case 33: return FOREGROUND_GREEN | FOREGROUND_RED;
|
||||||
|
case 34: return FOREGROUND_BLUE;
|
||||||
|
case 35: return FOREGROUND_RED | FOREGROUND_BLUE;
|
||||||
|
case 36: return FOREGROUND_BLUE | FOREGROUND_GREEN;
|
||||||
|
case 37: return FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
|
||||||
|
case 90: return FOREGROUND_INTENSITY;
|
||||||
|
case 91: return FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||||
|
case 92: return FOREGROUND_GREEN | FOREGROUND_INTENSITY;
|
||||||
|
case 93: return FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||||
|
case 94: return FOREGROUND_BLUE | FOREGROUND_INTENSITY;
|
||||||
|
case 95: return FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||||
|
case 96: return FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
|
||||||
|
case 97: return FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY;
|
||||||
|
//background
|
||||||
|
case 40: return 0;
|
||||||
|
case 41: return BACKGROUND_RED;
|
||||||
|
case 42: return BACKGROUND_GREEN;
|
||||||
|
case 43: return BACKGROUND_GREEN | BACKGROUND_RED;
|
||||||
|
case 44: return BACKGROUND_BLUE;
|
||||||
|
case 45: return BACKGROUND_RED | BACKGROUND_BLUE;
|
||||||
|
case 46: return BACKGROUND_BLUE | BACKGROUND_GREEN;
|
||||||
|
case 47: return BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED;
|
||||||
|
case 100: return BACKGROUND_INTENSITY;
|
||||||
|
case 101: return BACKGROUND_RED | BACKGROUND_INTENSITY;
|
||||||
|
case 102: return BACKGROUND_GREEN | BACKGROUND_INTENSITY;
|
||||||
|
case 103: return BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_INTENSITY;
|
||||||
|
case 104: return BACKGROUND_BLUE | BACKGROUND_INTENSITY;
|
||||||
|
case 105: return BACKGROUND_BLUE | BACKGROUND_RED | BACKGROUND_INTENSITY;
|
||||||
|
case 106: return BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
|
||||||
|
case 107: return BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_INTENSITY;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void kprintf(const char* format, ...){
|
||||||
|
va_list vl;
|
||||||
|
va_start(vl, format);
|
||||||
|
u32 i=0;
|
||||||
|
for(char c=format[i++]; c!=0; c=format[i++]){
|
||||||
|
// value format specifiers
|
||||||
|
if(c=='%'){
|
||||||
|
char* argstr=NULL;
|
||||||
|
bool l=false;
|
||||||
|
c=format[i++];
|
||||||
|
format_escape_seq:
|
||||||
|
switch (c) {
|
||||||
|
case 'u':
|
||||||
|
argstr=toString_u64(
|
||||||
|
l ? va_arg(vl, u64) : va_arg(vl, u32)
|
||||||
|
,0,0);
|
||||||
|
break;
|
||||||
|
case 'i': case 'd':
|
||||||
|
argstr=toString_i64(
|
||||||
|
l ? va_arg(vl, i64) : va_arg(vl, i32)
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
// f32 is promoted to f64 when passed through '...'
|
||||||
|
argstr=toString_f64(va_arg(vl, f64), toString_float_default_precision,0,0);
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
l=true;
|
||||||
|
if((c=format[i++]))
|
||||||
|
goto format_escape_seq;
|
||||||
|
break;
|
||||||
|
case 'p': ;
|
||||||
|
void* phex=va_arg(vl, void*);
|
||||||
|
argstr=toString_hex(&phex,getEndian()==LittleEndian,sizeof(phex),1,0);
|
||||||
|
break;
|
||||||
|
case 'x': ;
|
||||||
|
if(l){
|
||||||
|
u64 xhex=va_arg(vl, u64);
|
||||||
|
argstr=toString_hex(&xhex,getEndian()==LittleEndian,sizeof(xhex),0,1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
u32 xhex=va_arg(vl, u32);
|
||||||
|
argstr=toString_hex(&xhex,getEndian()==LittleEndian,sizeof(xhex),0,1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 's': ;
|
||||||
|
char* cptr=va_arg(vl,char*);
|
||||||
|
if(!cptr)
|
||||||
|
cptr="<nullstr>";
|
||||||
|
if(*cptr)
|
||||||
|
fputs(cptr, stdout);
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
argstr=malloc(2);
|
||||||
|
argstr[0]=(char)va_arg(vl,int);
|
||||||
|
argstr[1]=0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
putc('\n',stdout);
|
||||||
|
putc('<',stdout);
|
||||||
|
putc(c,stdout);
|
||||||
|
putc('>',stdout);
|
||||||
|
throw(ERR_FORMAT);
|
||||||
|
}
|
||||||
|
if(argstr){
|
||||||
|
fputs(argstr, stdout);
|
||||||
|
free(argstr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// escape sequences
|
||||||
|
else if(c=='\e'){
|
||||||
|
IFWIN(
|
||||||
|
/* WINDOWS */
|
||||||
|
({
|
||||||
|
if((c=format[i++])=='['){
|
||||||
|
u8 colorUnix=0;
|
||||||
|
for(i8 n=0; n<6 && c!=0; n++){
|
||||||
|
c=format[i++];
|
||||||
|
switch (c){
|
||||||
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
|
colorUnix=colorUnix*10+c-'0';
|
||||||
|
break;
|
||||||
|
case 'm': ;
|
||||||
|
WORD colorWin=unixColorToWin(colorUnix);
|
||||||
|
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
SetConsoleTextAttribute(hConsole, colorWin);
|
||||||
|
goto end_iteration;
|
||||||
|
default:
|
||||||
|
goto end_iteration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
/* UNIX */
|
||||||
|
putc(c,stdout);
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// common characters
|
||||||
|
else {
|
||||||
|
putc(c,stdout);
|
||||||
|
}
|
||||||
|
#if defined(_WIN64) || defined(_WIN32)
|
||||||
|
end_iteration:;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
va_end(vl);
|
||||||
|
}
|
||||||
34
kerep/src/random/splitmix64/splitmix64.c
Normal file
34
kerep/src/random/splitmix64/splitmix64.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#include "splitmix64.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is a fixed-increment version of Java 8's SplittableRandom generator
|
||||||
|
See http://dx.doi.org/10.1145/2714064.2660195 and
|
||||||
|
http://docs.oracle.com/javase/8/docs/api/java/util/SplittableRandom.html
|
||||||
|
It is a very fast generator passing BigCrush, and it can be useful if
|
||||||
|
for some reason you absolutely want 64 bits of state; otherwise, we
|
||||||
|
rather suggest to use a xoroshiro128+ (for moderately parallel
|
||||||
|
computations) or xorshift1024* (for massively parallel computations)
|
||||||
|
generator.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// The state can be seeded with any (upto) 64 bit integer value.
|
||||||
|
|
||||||
|
void* splitmix64_init(u64 seed){
|
||||||
|
splitmix64_state* state=malloc(sizeof(splitmix64_state));
|
||||||
|
*state=seed;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 splitmix64_next(void* _state) {
|
||||||
|
splitmix64_state* state=_state;
|
||||||
|
// increment the state variable
|
||||||
|
*state += 0x9e3779b97f4a7c15;
|
||||||
|
// copy the state to a working variable
|
||||||
|
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
|
||||||
|
z = (z ^ (z>>27)) * 0x94d049bb133111eb;
|
||||||
|
// return the variable xored with itself right bit shifted 31
|
||||||
|
return z ^ (z>>31);
|
||||||
|
}
|
||||||
49
kerep/src/random/xoroshiro/32bitValue/xoroshiro64star.c
Normal file
49
kerep/src/random/xoroshiro/32bitValue/xoroshiro64star.c
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/* Written in 2016 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||||
|
|
||||||
|
To the extent possible under law, the author has dedicated all copyright
|
||||||
|
and related and neighboring rights to this software to the public domain
|
||||||
|
worldwide. This software is distributed without any warranty.
|
||||||
|
|
||||||
|
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
||||||
|
|
||||||
|
#include "xoroshiro64.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is xoroshiro64* 1.0, our best and fastest 32-bit small-state
|
||||||
|
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
|
||||||
|
case) it can be used to generate 32-bit outputs, too.
|
||||||
|
|
||||||
|
We suggest to use a sign test to extract a random Boolean value, and
|
||||||
|
right shifts to extract subsets of bits.
|
||||||
|
|
||||||
|
The state must be seeded so that it is not everywhere zero.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline u32 rotl(const u32 x, i32 k) {
|
||||||
|
return (x << k) | (x >> (32 - k));
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 xoroshiro64star_next(void* _state) {
|
||||||
|
xoroshiro64_state* state=_state;
|
||||||
|
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
|
||||||
|
state->s[1] = rotl(s1, 13); // c
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* xoroshiro64_init(u64 seed){
|
||||||
|
xoroshiro64_state* state=malloc(sizeof(xoroshiro64_state));
|
||||||
|
splitmix64_state* splitmix=splitmix64_init(seed);
|
||||||
|
state->merged=splitmix64_next(splitmix);
|
||||||
|
splitmix64_free(splitmix);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
37
kerep/src/random/xoroshiro/32bitValue/xoroshiro64starstar.c
Normal file
37
kerep/src/random/xoroshiro/32bitValue/xoroshiro64starstar.c
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||||
|
|
||||||
|
To the extent possible under law, the author has dedicated all copyright
|
||||||
|
and related and neighboring rights to this software to the public domain
|
||||||
|
worldwide. This software is distributed without any warranty.
|
||||||
|
|
||||||
|
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
||||||
|
|
||||||
|
#include "xoroshiro64.h"
|
||||||
|
|
||||||
|
/* This is xoroshiro64** 1.0, our 32-bit all-purpose, rock-solid,
|
||||||
|
small-state generator. It is extremely fast and it passes all tests we
|
||||||
|
are aware of, but its state space is not large enough for any parallel
|
||||||
|
application.
|
||||||
|
|
||||||
|
For generating just single-precision (i.e., 32-bit) floating-point
|
||||||
|
numbers, xoroshiro64* is even faster.
|
||||||
|
|
||||||
|
The state must be seeded so that it is not everywhere zero. */
|
||||||
|
|
||||||
|
|
||||||
|
static inline u32 rotl(const u32 x, i32 k) {
|
||||||
|
return (x << k) | (x >> (32 - k));
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 xoroshiro64starstar_next(void* _state) {
|
||||||
|
xoroshiro64_state* state=_state;
|
||||||
|
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
|
||||||
|
state->s[1] = rotl(s1, 13); // c
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
59
kerep/src/random/xoroshiro/64bitValue/xoroshiro128plus.c
Normal file
59
kerep/src/random/xoroshiro/64bitValue/xoroshiro128plus.c
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/* Written in 2016-2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||||
|
|
||||||
|
To the extent possible under law, the author has dedicated all copyright
|
||||||
|
and related and neighboring rights to this software to the public domain
|
||||||
|
worldwide. This software is distributed without any warranty.
|
||||||
|
|
||||||
|
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-poi32 numbers, but its state space is large enough only
|
||||||
|
for mild parallelism. We suggest to use its upper bits for
|
||||||
|
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
|
||||||
|
it is usually the case) it can be used to generate 64-bit outputs, too;
|
||||||
|
moreover, this generator has a very mild Hamming-weight dependency
|
||||||
|
making our test (http://prng.di.unimi.it/hwd.php) fail after 5 TB of
|
||||||
|
output; we believe this slight bias cannot affect any application. If
|
||||||
|
you are concerned, use xoroshiro128++, xoroshiro128** or xoshiro256+.
|
||||||
|
|
||||||
|
We suggest to use a sign test to extract a random Boolean value, and
|
||||||
|
right shifts to extract subsets of bits.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
NOTE: the parameters (a=24, b=16, b=37) of this version give slightly
|
||||||
|
better results in our test than the 2016 version (a=55, b=14, c=36).
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline u64 rotl(const u64 x, i32 k) {
|
||||||
|
return (x << k) | (x >> (64 - k));
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 xoroshiro128plus_next(void* _state){
|
||||||
|
xoroshiro128_state* state=_state;
|
||||||
|
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
|
||||||
|
state->s[1] = rotl(s1, 37); // c
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* xoroshiro128_init(u64 seed){
|
||||||
|
xoroshiro128_state* state=malloc(sizeof(xoroshiro128_state));
|
||||||
|
splitmix64_state* splitmix=splitmix64_init(seed);
|
||||||
|
state->s[0]=splitmix64_next(splitmix);
|
||||||
|
state->s[1]=splitmix64_next(splitmix);
|
||||||
|
splitmix64_free(splitmix);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
39
kerep/src/random/xoroshiro/64bitValue/xoroshiro128plusplus.c
Normal file
39
kerep/src/random/xoroshiro/64bitValue/xoroshiro128plusplus.c
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/* Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||||
|
|
||||||
|
To the extent possible under law, the author has dedicated all copyright
|
||||||
|
and related and neighboring rights to this software to the public domain
|
||||||
|
worldwide. This software is distributed without any warranty.
|
||||||
|
|
||||||
|
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
||||||
|
|
||||||
|
#include "xoroshiro128.h"
|
||||||
|
|
||||||
|
/* This is xoroshiro128++ 1.0, one of our all-purpose, rock-solid,
|
||||||
|
small-state generators. It is extremely (sub-ns) fast and it passes all
|
||||||
|
tests we are aware of, but its state space is large enough only for
|
||||||
|
mild parallelism.
|
||||||
|
|
||||||
|
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
|
||||||
|
a 64-bit seed, we suggest to seed a splitmix64 generator and use its
|
||||||
|
output to fill s. */
|
||||||
|
|
||||||
|
|
||||||
|
static inline u64 rotl(const u64 x, i32 k) {
|
||||||
|
return (x << k) | (x >> (64 - k));
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 xoroshiro128plusplus_next(void* _state){
|
||||||
|
xoroshiro128_state* state=_state;
|
||||||
|
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
|
||||||
|
state->s[1] = rotl(s1, 28); // c
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
39
kerep/src/random/xoroshiro/64bitValue/xoroshiro128starstar.c
Normal file
39
kerep/src/random/xoroshiro/64bitValue/xoroshiro128starstar.c
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||||
|
|
||||||
|
To the extent possible under law, the author has dedicated all copyright
|
||||||
|
and related and neighboring rights to this software to the public domain
|
||||||
|
worldwide. This software is distributed without any warranty.
|
||||||
|
|
||||||
|
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
||||||
|
|
||||||
|
#include "xoroshiro128.h"
|
||||||
|
|
||||||
|
/* This is xoroshiro128** 1.0, one of our all-purpose, rock-solid,
|
||||||
|
small-state generators. It is extremely (sub-ns) fast and it passes all
|
||||||
|
tests we are aware of, but its state space is large enough only for
|
||||||
|
mild parallelism.
|
||||||
|
|
||||||
|
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
|
||||||
|
a 64-bit seed, we suggest to seed a splitmix64 generator and use its
|
||||||
|
output to fill s. */
|
||||||
|
|
||||||
|
|
||||||
|
static inline u64 rotl(const u64 x, i32 k) {
|
||||||
|
return (x << k) | (x >> (64 - k));
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 xoroshiro128starstar_next(void* _state){
|
||||||
|
xoroshiro128_state* state=_state;
|
||||||
|
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
|
||||||
|
state->s[1] = rotl(s1, 37); // c
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
54
kerep/src/random/xoshiro/32bitValue/xoshiro128plus.c
Normal file
54
kerep/src/random/xoshiro/32bitValue/xoshiro128plus.c
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||||
|
|
||||||
|
To the extent possible under law, the author has dedicated all copyright
|
||||||
|
and related and neighboring rights to this software to the public domain
|
||||||
|
worldwide. This software is distributed without any warranty.
|
||||||
|
|
||||||
|
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-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
|
||||||
|
the case) it can be used to generate 32-bit outputs, too.
|
||||||
|
|
||||||
|
We suggest to use a sign test to extract a random Boolean value, and
|
||||||
|
right shifts to extract subsets of bits.
|
||||||
|
|
||||||
|
The state must be seeded so that it is not everywhere zero. */
|
||||||
|
|
||||||
|
|
||||||
|
static inline u32 rotl(const u32 x, i32 k) {
|
||||||
|
return (x << k) | (x >> (32 - k));
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 xoshiro128plus_next(void* _state){
|
||||||
|
xoshiro128_state* state=_state;
|
||||||
|
const u32 result = state->s[0] + state->s[3];
|
||||||
|
|
||||||
|
const u32 t = state->s[1] << 9;
|
||||||
|
|
||||||
|
state->s[2] ^= state->s[0];
|
||||||
|
state->s[3] ^= state->s[1];
|
||||||
|
state->s[1] ^= state->s[2];
|
||||||
|
state->s[0] ^= state->s[3];
|
||||||
|
|
||||||
|
state->s[2] ^= t;
|
||||||
|
|
||||||
|
state->s[3] = rotl(state->s[3], 11);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* xoshiro128_init(u64 seed){
|
||||||
|
xoshiro128_state* state=malloc(sizeof(xoshiro128_state));
|
||||||
|
splitmix64_state* splitmix=splitmix64_init(seed);
|
||||||
|
state->merged[0]=splitmix64_next(splitmix);
|
||||||
|
state->merged[1]=splitmix64_next(splitmix);
|
||||||
|
splitmix64_free(splitmix);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
42
kerep/src/random/xoshiro/32bitValue/xoshiro128plusplus.c
Normal file
42
kerep/src/random/xoshiro/32bitValue/xoshiro128plusplus.c
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/* Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||||
|
|
||||||
|
To the extent possible under law, the author has dedicated all copyright
|
||||||
|
and related and neighboring rights to this software to the public domain
|
||||||
|
worldwide. This software is distributed without any warranty.
|
||||||
|
|
||||||
|
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
||||||
|
|
||||||
|
#include "xoshiro128.h"
|
||||||
|
|
||||||
|
/* This is xoshiro128++ 1.0, one of our 32-bit all-purpose, rock-solid
|
||||||
|
generators. It has excellent speed, a state size (128 bits) that is
|
||||||
|
large enough for mild parallelism, and it passes all tests we are aware
|
||||||
|
of.
|
||||||
|
|
||||||
|
For generating just single-precision (i.e., 32-bit) floating-point
|
||||||
|
numbers, xoshiro128+ is even faster.
|
||||||
|
|
||||||
|
The state must be seeded so that it is not everywhere zero. */
|
||||||
|
|
||||||
|
|
||||||
|
static inline u32 rotl(const u32 x, i32 k) {
|
||||||
|
return (x << k) | (x >> (32 - k));
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 xoshiro128plusplus_next(void* _state){
|
||||||
|
xoshiro128_state* state=_state;
|
||||||
|
const u32 result = rotl(state->s[0] + state->s[3], 7) + state->s[0];
|
||||||
|
|
||||||
|
const u32 t = state->s[1] << 9;
|
||||||
|
|
||||||
|
state->s[2] ^= state->s[0];
|
||||||
|
state->s[3] ^= state->s[1];
|
||||||
|
state->s[1] ^= state->s[2];
|
||||||
|
state->s[0] ^= state->s[3];
|
||||||
|
|
||||||
|
state->s[2] ^= t;
|
||||||
|
|
||||||
|
state->s[3] = rotl(state->s[3], 11);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
45
kerep/src/random/xoshiro/32bitValue/xoshiro128starstar.c
Normal file
45
kerep/src/random/xoshiro/32bitValue/xoshiro128starstar.c
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||||
|
|
||||||
|
To the extent possible under law, the author has dedicated all copyright
|
||||||
|
and related and neighboring rights to this software to the public domain
|
||||||
|
worldwide. This software is distributed without any warranty.
|
||||||
|
|
||||||
|
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
||||||
|
|
||||||
|
#include "xoshiro128.h"
|
||||||
|
|
||||||
|
/* This is xoshiro128** 1.1, one of our 32-bit all-purpose, rock-solid
|
||||||
|
generators. It has excellent speed, a state size (128 bits) that is
|
||||||
|
large enough for mild parallelism, and it passes all tests we are aware
|
||||||
|
of.
|
||||||
|
|
||||||
|
Note that version 1.0 had mistakenly state->s[0] instead of state->s[1] as state
|
||||||
|
word passed to the scrambler.
|
||||||
|
|
||||||
|
For generating just single-precision (i.e., 32-bit) floating-point
|
||||||
|
numbers, xoshiro128+ is even faster.
|
||||||
|
|
||||||
|
The state must be seeded so that it is not everywhere zero. */
|
||||||
|
|
||||||
|
|
||||||
|
static inline u32 rotl(const u32 x, i32 k) {
|
||||||
|
return (x << k) | (x >> (32 - k));
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 xoshiro128starstar_next(void* _state){
|
||||||
|
xoshiro128_state* state=_state;
|
||||||
|
const u32 result = rotl(state->s[1] * 5, 7) * 9;
|
||||||
|
|
||||||
|
const u32 t = state->s[1] << 9;
|
||||||
|
|
||||||
|
state->s[2] ^= state->s[0];
|
||||||
|
state->s[3] ^= state->s[1];
|
||||||
|
state->s[1] ^= state->s[2];
|
||||||
|
state->s[0] ^= state->s[3];
|
||||||
|
|
||||||
|
state->s[2] ^= t;
|
||||||
|
|
||||||
|
state->s[3] = rotl(state->s[3], 11);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
58
kerep/src/random/xoshiro/64bitValue/xoshiro256plus.c
Normal file
58
kerep/src/random/xoshiro/64bitValue/xoshiro256plus.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||||
|
|
||||||
|
To the extent possible under law, the author has dedicated all copyright
|
||||||
|
and related and neighboring rights to this software to the public domain
|
||||||
|
worldwide. This software is distributed without any warranty.
|
||||||
|
|
||||||
|
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
||||||
|
|
||||||
|
#include "xoshiro256.h"
|
||||||
|
|
||||||
|
/* This is xoshiro256+ 1.0, our best and fastest generator for floating-point
|
||||||
|
numbers. We suggest to use its upper bits for floating-point
|
||||||
|
generation, as it is slightly faster than xoshiro256++/xoshiro256**. It
|
||||||
|
passes all tests we are aware of except for the lowest three bits,
|
||||||
|
which might fail linearity tests (and just those), so if low linear
|
||||||
|
complexity is not considered an issue (as it is usually the case) it
|
||||||
|
can be used to generate 64-bit outputs, too.
|
||||||
|
|
||||||
|
We suggest to use a sign test to extract a random Boolean value, and
|
||||||
|
right shifts to extract subsets of bits.
|
||||||
|
|
||||||
|
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 u64 rotl(const u64 x, i32 k) {
|
||||||
|
return (x << k) | (x >> (64 - k));
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 xoshiro256plus_next(void* _state){
|
||||||
|
xoshiro256_state* state=_state;
|
||||||
|
const u64 result = state->s[0] + state->s[3];
|
||||||
|
|
||||||
|
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];
|
||||||
|
state->s[0] ^= state->s[3];
|
||||||
|
|
||||||
|
state->s[2] ^= t;
|
||||||
|
|
||||||
|
state->s[3] = rotl(state->s[3], 45);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* xoshiro256_init(u64 seed){
|
||||||
|
xoshiro256_state* state=malloc(sizeof(xoshiro256_state));
|
||||||
|
splitmix64_state* splitmix=splitmix64_init(seed);
|
||||||
|
state->s[0]=splitmix64_next(splitmix);
|
||||||
|
state->s[1]=splitmix64_next(splitmix);
|
||||||
|
state->s[2]=splitmix64_next(splitmix);
|
||||||
|
state->s[3]=splitmix64_next(splitmix);
|
||||||
|
splitmix64_free(splitmix);
|
||||||
|
return state;
|
||||||
|
}
|
||||||
37
kerep/src/random/xoshiro/64bitValue/xoshiro256plusplus.c
Normal file
37
kerep/src/random/xoshiro/64bitValue/xoshiro256plusplus.c
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/* Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||||
|
|
||||||
|
To the extent possible under law, the author has dedicated all copyright
|
||||||
|
and related and neighboring rights to this software to the public domain
|
||||||
|
worldwide. This software is distributed without any warranty.
|
||||||
|
|
||||||
|
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
||||||
|
|
||||||
|
#include "xoshiro256.h"
|
||||||
|
|
||||||
|
/* This is xoshiro256++ 1.0, one of our all-purpose, rock-solid generators.
|
||||||
|
It has excellent (sub-ns) speed, a state (256 bits) that is large
|
||||||
|
enough for any parallel application, and it passes all tests we are
|
||||||
|
aware of.
|
||||||
|
|
||||||
|
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 u64 rotl(const u64 x, i32 k) {
|
||||||
|
return (x << k) | (x>>(64 - k));
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 xoshiro256plusplus_next(void* _state) {
|
||||||
|
xoshiro256_state* state=_state;
|
||||||
|
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];
|
||||||
|
state->s[0] ^= state->s[3];
|
||||||
|
state->s[2] ^= t;
|
||||||
|
state->s[3]=rotl(state->s[3], 45);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
42
kerep/src/random/xoshiro/64bitValue/xoshiro256starstar.c
Normal file
42
kerep/src/random/xoshiro/64bitValue/xoshiro256starstar.c
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
|
||||||
|
|
||||||
|
To the extent possible under law, the author has dedicated all copyright
|
||||||
|
and related and neighboring rights to this software to the public domain
|
||||||
|
worldwide. This software is distributed without any warranty.
|
||||||
|
|
||||||
|
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
|
||||||
|
|
||||||
|
#include "xoshiro256.h"
|
||||||
|
|
||||||
|
/* This is xoshiro256** 1.0, one of our all-purpose, rock-solid
|
||||||
|
generators. It has excellent (sub-ns) speed, a state (256 bits) that is
|
||||||
|
large enough for any parallel application, and it passes all tests we
|
||||||
|
are aware of.
|
||||||
|
|
||||||
|
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 u64 rotl(const u64 x, i32 k) {
|
||||||
|
return (x << k) | (x >> (64 - k));
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 xoshiro256starstar_next(void* _state){
|
||||||
|
xoshiro256_state* state=_state;
|
||||||
|
const u64 result = rotl(state->s[1] * 5, 7) * 9;
|
||||||
|
|
||||||
|
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];
|
||||||
|
state->s[0] ^= state->s[3];
|
||||||
|
|
||||||
|
state->s[2] ^= t;
|
||||||
|
|
||||||
|
state->s[3] = rotl(state->s[3], 45);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -125,5 +125,5 @@ Maybe CompilationScenario_exec(CompilationScenario* sc){
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
);*/
|
);*/
|
||||||
return true;
|
return MaybeNull;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "../kerep-headers/DtsodParser/DtsodV24.h"
|
#include "../kerep/src/DtsodParser/DtsodV24.h"
|
||||||
|
|
||||||
extern const char* os;
|
extern const char* os;
|
||||||
extern const char* arch;
|
extern const char* arch;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "../kerep-headers/base/base.h"
|
#include "../kerep/src/base/base.h"
|
||||||
#include "../kerep-headers/Filesystem/filesystem.h"
|
#include "../kerep/src/Filesystem/filesystem.h"
|
||||||
#include "../kerep-headers/DtsodParser/DtsodV24.h"
|
#include "../kerep/src/DtsodParser/DtsodV24.h"
|
||||||
#include "CompilationScenario.h"
|
#include "CompilationScenario.h"
|
||||||
|
|
||||||
#ifndef OS
|
#ifndef OS
|
||||||
@@ -15,9 +15,8 @@ const char* arch=ARCH;
|
|||||||
|
|
||||||
const char* global_out_dir="bin";
|
const char* global_out_dir="bin";
|
||||||
const char* configuration="release";
|
const char* configuration="release";
|
||||||
const char* task="exe";
|
const char* project_dir_or_file="./";
|
||||||
const char** projects=NULL;
|
Autoarr(Pointer)* tasks;
|
||||||
u16 project_count = 0;
|
|
||||||
|
|
||||||
int erri(ErrorId err_code){
|
int erri(ErrorId err_code){
|
||||||
throw(err_code);
|
throw(err_code);
|
||||||
@@ -37,72 +36,66 @@ int main(const int argc, const char** argv){
|
|||||||
kt_initKerepTypes();
|
kt_initKerepTypes();
|
||||||
kt_endInit();
|
kt_endInit();
|
||||||
|
|
||||||
if(cptr_equals(os, "UNDEFINED"))
|
tasks = Autoarr_create(Pointer, 16, 32);
|
||||||
throw("Operation system undefined. Recompile cbuild with flag -DOS=$(./detect_os.sh)");
|
|
||||||
if(cptr_equals(arch, "UNDEFINED"))
|
|
||||||
throw("CPU architecture undefined. Recompile cbuild with flag -DARCH=$(./detect_arch.sh)");
|
|
||||||
|
|
||||||
Autoarr(Pointer)* projects_ar = Autoarr_create(Pointer, 16, 32);
|
if(cptr_equals(os, "UNDEFINED"))
|
||||||
|
throw("Operation system undefined. Recompile cbuild with flag -DOS=\\\"$(./detect_os.sh)\\\"");
|
||||||
|
if(cptr_equals(arch, "UNDEFINED"))
|
||||||
|
throw("CPU architecture undefined. Recompile cbuild with flag -DARCH=\\\"$(./detect_arch.sh)\\\"");
|
||||||
|
|
||||||
for(int argi = 1; argi < argc; argi++){
|
for(int argi = 1; argi < argc; argi++){
|
||||||
const char* arg = argv[argi];
|
const char* arg = argv[argi];
|
||||||
kprintf("arg: %s\n", arg);
|
kprintf("arg: %s\n", arg);
|
||||||
if(argIs("-h") || argIs("--help") || argIs("/?"))
|
if(argIs("-h") || argIs("--help") || argIs("/?")){
|
||||||
kprintf("Usage: cbuild [options] [projects files/dirs]\n"
|
kprintf("Usage: cbuild [options] [tasks0 task1...]\n"
|
||||||
" Options:\n"
|
" Options:\n"
|
||||||
" -h, --help, /? Display this message.\n"
|
" -h, --help, /? Display this message.\n"
|
||||||
" -o, --out-dir Set global output directory (default=bin).\n"
|
" -o, --out-dir Set global output directory (default=bin).\n"
|
||||||
" -c, --configuration Select project configuration (default=release).\n"
|
" -c, --configuration Select project configuration (default=release).\n"
|
||||||
" -t, --task Select build task from project.\n");
|
" -p, --project Set project directory/file (default=./).\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if(argIs("-o") || argIs("--out-dir"))
|
else if(argIs("-o") || argIs("--out-dir"))
|
||||||
global_out_dir = argNext();
|
global_out_dir = argNext();
|
||||||
else if(argIs("-c") || argIs("--configuration"))
|
else if(argIs("-c") || argIs("--configuration"))
|
||||||
configuration = argNext();
|
configuration = argNext();
|
||||||
else if(argIs("-t") || argIs("--task"))
|
else if(argIs("-p") || argIs("--project"))
|
||||||
task = argNext();
|
project_dir_or_file = argNext();
|
||||||
else {
|
else {
|
||||||
if(arg[0] == '-')
|
if(arg[0] == '-')
|
||||||
throw(cptr_concat("invalid argument: ", arg));
|
throw(cptr_concat("invalid argument: ", arg));
|
||||||
Autoarr_add(projects_ar, arg);
|
Autoarr_add(tasks, arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
project_count = Autoarr_length(projects_ar);
|
|
||||||
projects = (const char**)Autoarr_toArray(projects_ar);
|
|
||||||
Autoarr_freeWithoutMembers(projects_ar, true);
|
|
||||||
if(project_count == 0){
|
|
||||||
projects = malloc(sizeof(char*));
|
|
||||||
projects[0] = projectFileFromDir(".");
|
|
||||||
}
|
|
||||||
|
|
||||||
for(u16 i=0; i < project_count; i++){
|
|
||||||
const char* proj = projects[i];
|
|
||||||
const char* proj_file_path = NULL;
|
const char* proj_file_path = NULL;
|
||||||
if(file_exists(proj))
|
if(file_exists(project_dir_or_file))
|
||||||
proj_file_path = proj;
|
proj_file_path = project_dir_or_file;
|
||||||
else if(dir_exists(proj))
|
else if(dir_exists(project_dir_or_file))
|
||||||
proj_file_path = projectFileFromDir(proj);
|
proj_file_path = projectFileFromDir(project_dir_or_file);
|
||||||
|
else throw(cptr_concat("can't find a project at path '", project_dir_or_file, "'"));
|
||||||
|
|
||||||
tryLast(file_open(proj_file_path, FileOpenMode_Read), _m1, ;);
|
tryLast(file_open(proj_file_path, FileOpenMode_Read), _m1, ;);
|
||||||
FileHandle proj_file = _m1.value.VoidPtr;
|
FileHandle proj_file = _m1.value.VoidPtr;
|
||||||
char* proj_file_text;
|
char* proj_file_text = NULL;
|
||||||
tryLast(file_readAll(proj_file, &proj_file_text), _m2, file_close(proj_file));
|
tryLast(file_readAll(proj_file, &proj_file_text), _m2, file_close(proj_file));
|
||||||
file_close(proj_file);
|
file_close(proj_file);
|
||||||
|
|
||||||
tryLast(DtsodV24_deserialize(proj_file_text), _m3, free(proj_file_text));
|
tryLast(DtsodV24_deserialize(proj_file_text), _m3, free(proj_file_text));
|
||||||
Hashtable* proj_dtsod = _m3.value.VoidPtr;
|
Hashtable* proj_dtsod = _m3.value.VoidPtr;
|
||||||
|
|
||||||
|
Autoarr_foreach(tasks, task,
|
||||||
CompilationScenario proj_sc;
|
CompilationScenario proj_sc;
|
||||||
CompilationScenario_construct(&proj_sc);
|
CompilationScenario_construct(&proj_sc);
|
||||||
tryLast(CompilationScenario_applyProjectOptions(&proj_sc, proj_dtsod, configuration, task), _m4, free(proj_file_text))
|
tryLast(CompilationScenario_applyProjectOptions(&proj_sc, proj_dtsod, configuration, task), _m4, )
|
||||||
|
tryLast(CompilationScenario_exec(&proj_sc), _m5, ;)
|
||||||
if(!CompilationScenario_exec(&proj_sc))
|
|
||||||
throw("compilation error");
|
|
||||||
|
|
||||||
CompilationScenario_destruct(&proj_sc);
|
CompilationScenario_destruct(&proj_sc);
|
||||||
|
)
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
Hashtable_free(proj_dtsod);
|
Hashtable_free(proj_dtsod);
|
||||||
free(proj_file_text);
|
free(proj_file_text);
|
||||||
}
|
|
||||||
|
|
||||||
kt_free();
|
kt_free();
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user