base_toString

This commit is contained in:
timerix 2022-09-28 22:07:17 +06:00
parent d5a60953c3
commit a0a35b30a6
14 changed files with 316 additions and 70 deletions

View File

@ -46,4 +46,42 @@ bool cptr_endsWith(char* ptr, char* fragment){
for(char cs=*ptr, cf=*fragment; cf; cs=*++ptr, cf=*++fragment)
if(cs!=cf) return false;
return true;
}
}
void memcopy(void* from, void* to, uint32 size){
if(from==NULL || to==NULL)
throw(ERR_NULLPTR);
for(uint32 i=0; i<size; i++)
((char*)to)[i]=*(char*)from+i;
}
char* __cptr_concat(uint16 n, ...){
char** strs=(char**)malloc(n*8);
uint32* lengths=malloc(n*4);
uint32 totalLength=0;
// reading args from va_list
va_list vl;
va_start(vl, n);
for(uint16 i=0; i<n; i++){
char* str=va_arg(vl,char*);
int16 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);
const char* output=totality;
totality[totalLength]=0;
// copying content of all strings to rezult
for(uint16 k=0; k<n; k++){
memcopy(strs[k], totality, lengths[k]);
totality+=lengths[k];
}
return output;
}

View File

@ -22,6 +22,11 @@ bool cptr_startsWith(char* ptr, char* fragment);
bool cptr_endsWith(char* ptr, char* fragment);
void memcopy(void* from, void* to, uint32 size);
char* __cptr_concat(uint16 n, ...);
#define cptr_concat(STR...) __cptr_concat(count_args(STR), STR)
#if __cplusplus
}
#endif

View File

@ -11,7 +11,7 @@ typedef enum ErrorId {
SUCCESS, // not an error
ERR_MAXLENGTH, ERR_WRONGTYPE, ERR_WRONGINDEX,
ERR_NOTIMPLEMENTED, ERR_NULLPTR, ERR_ENDOFSTR,
ERR_KEYNOTFOUND
ERR_KEYNOTFOUND, ERR_FORMAT
} ErrorId;
char* errname(ErrorId err);

View File

@ -19,8 +19,7 @@ Maybe __next_toString(kprint_format format, void* object){
default:
safethrow("typeId is not set, can't autodetect type",;);
}
try(ktDescriptor_get(format.typeId),mtd,;);
ktDescriptor typeDesc=*(ktDescriptor*)mtd.value.VoidPtr;
ktDescriptor typeDesc=ktDescriptor_get(format.typeId);
if(!typeDesc.toString)
safethrow("type descriptor doesnt have toString() func",;);
try(typeDesc.toString(object, &format), mStr,;);
@ -69,8 +68,7 @@ void kprint_setColor(kprint_format f){
Maybe ksprint_ar(uint32 count, kprint_format format, ktId typeId, void* array){
try(ktDescriptor_get(format.typeId),mtd,;);
ktDescriptor typeDesc=*(ktDescriptor*)mtd.value.VoidPtr;
ktDescriptor typeDesc=ktDescriptor_get(format.typeId);
if(!typeDesc.toString)
safethrow("type descriptor doesnt have toString() func",;);
StringBuilder* strb=StringBuilder_create();

View File

@ -8,67 +8,54 @@ extern "C" {
#include "kprint_colors.h"
#include "kprint_format.h"
#define __count_args(\
a0, a1, a2, a3, a4, a5, a6, a7,\
a8, a9, a10,a11,a12,a13,a14,a15,\
a16,a17,a18,a19,a20,a21,a22,a23,\
a24,a25,a26,a27,a28,a29,a30,a31,\
a32) a32
#define count_args(ARGS...) __count_args(\
ARGS,\
32,31,30,29,28,27,26,25,\
24,23,22,21,20,19,18,17,\
16,15,14,13,12,11,10,9,\
8, 7, 6, 5, 4, 3, 2, 1, 0)
#define __kprint_argsToFormats8(\
a0, a1, a2, a3, a4, a5, a6, a7)\
(kprint_format[]{ a0,a2,a4,a6 })
a0, a1, a2, a3, a4, a5, a6, a7,...)\
((int32[]){ a0,a2,a4,a6 })
#define __kprint_argsToObjects8(\
a0, a1, a2, a3, a4, a5, a6, a7)\
(void*[]{ a1,a3,a5,a7 })
a0, a1, a2, a3, a4, a5, a6, a7,...)\
((void*[]){ &a1,&a3,&a5,&a7 })
#define __kprint_argsToFormats16(\
a0, a1, a2, a3, a4, a5, a6, a7,\
a8, a9, a10,a11,a12,a13,a14,a15)\
(kprint_format[]{ a0,a2,a4,a6,a8,a10,a12,a14 })
a8, a9, a10,a11,a12,a13,a14,a15,...)\
((int32[]){ a0,a2,a4,a6,a8,a10,a12,a14 })
#define __kprint_argsToObjects16(\
a0, a1, a2, a3, a4, a5, a6, a7,\
a8, a9, a10,a11,a12,a13,a14,a15)\
(void*[]{ a1,a3,a5,a7,a9,a11,a13,a15 })
a8, a9, a10,a11,a12,a13,a14,a15,...)\
((void*[]){ &a1,&a3,&a5,&a7,&a9,&a11,&a13,&a15 })
#define __kprint_argsToFormats32(\
a0, a1, a2, a3, a4, a5, a6, a7,\
a8, a9, a10,a11,a12,a13,a14,a15,\
a16,a17,a18,a19,a20,a21,a22,a23,\
a24,a25,a26,a27,a28,a29,a30,a31)\
(kprint_format[]{ a0,a2,a4,a6,a8,a10,a12,a14,a16,a18,a20,a22,a24,a26,a28,a30 }
a24,a25,a26,a27,a28,a29,a30,a31,...)\
((int32[]){ a0,a2,a4,a6,a8,a10,a12,a14,a16,a18,a20,a22,a24,a26,a28,a30 })
#define __kprint_argsToObjects32(\
a0, a1, a2, a3, a4, a5, a6, a7,\
a8, a9, a10,a11,a12,a13,a14,a15,\
a16,a17,a18,a19,a20,a21,a22,a23,\
a24,a25,a26,a27,a28,a29,a30,a31)\
(void*[]{ a1,a3,a5,a7,a9,a11,a13,a15,a17,a19,a21,a23,a25,a27,a29,a31 })
a24,a25,a26,a27,a28,a29,a30,a31,...)\
((void*[]){ &a1,&a3,&a5,&a7,&a9,&a11,&a13,&a15,&a17,&a19,&a21,&a23,&a25,&a27,&a29,&a31 })
#define __32zeroes 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
#define __kprint_argsToArrs(COUNT,ARGS...)(\
(COUNT<=8 __kprint_argsToFormats8(ARGS,__32zeroes) :\
COUNT<=16 __kprint_argsToFormats16(ARGS,__32zeroes) :\
__kprint_argsToFormats32(ARGS,__32zeroes)),\
(COUNT<=8 __kprint_argsToObjects8(ARGS,__32zeroes) :\
COUNT<=16 __kprint_argsToObjects16(ARGS) :\
__kprint_argsToObjects32(ARGS,__32zeroes))
#define __kprint_argsToArrs(COUNT,ARGS...)\
(COUNT<=8 ? __kprint_argsToFormats8(ARGS) :\
COUNT<=16 ? __kprint_argsToFormats16(ARGS) :\
__kprint_argsToFormats32(ARGS)),\
(COUNT<=8 ? __kprint_argsToObjects8(ARGS) :\
COUNT<=16 ? __kprint_argsToObjects16(ARGS) :\
__kprint_argsToObjects32(ARGS))
Maybe __ksprint(uint8 n, kprint_format* formats, void** objects);
#define ksprint(ARGS...) __ksprint(count_args(ARGS), __kprint_argsToArrs(count_args(ARGS),ARGS))
Maybe __ksprint(uint8 n, int32* formats, void** objects);
#define ksprint(ARGS...) __ksprint(count_args(ARGS), __kprint_argsToArrs(count_args(ARGS),ARGS, __32zeroes))
Maybe __kfprint(FILE* fd, uint8 n, kprint_format* formats, void** objects);
#define kfprint(FD, ARGS...) __kfprint(FD, count_args(ARGS), __kprint_argsToArrs(count_args(ARGS),ARGS))
Maybe __kfprint(FILE* fd, uint8 n, int32* formats, void** objects);
#define kfprint(FD, ARGS...) __kfprint(FD, count_args(ARGS), __kprint_argsToArrs(count_args(ARGS),ARGS, __32zeroes))
void __kprint(uint8 n, kprint_format* formats, void** objects);
#define kprint(ARGS...) __kprint(count_args(ARGS), __kprint_argsToArrs(count_args(ARGS),ARGS))
void __kprint(uint8 n, int32* formats, void** objects);
#define kprint(ARGS...) __kprint(count_args(ARGS), __kprint_argsToArrs(count_args(ARGS),ARGS, __32zeroes))
// can take (bgColor | fgColor)
void kprint_setColor(kprint_format f);

View File

@ -4,6 +4,7 @@
extern "C" {
#endif
#include "../std.h"
#include "../type_system/ktId.h"
typedef enum kprint_dataFormat{
@ -30,16 +31,18 @@ typedef enum kprint_dataFormat{
kprint_fmtUppercase=0x10000000
} kprint_dataFormat;
typedef struct {
unsigned char fgColorChanged : 1;
unsigned char bgColorChanged : 1;
unsigned char withPrefix : 1;
unsigned char uppercase : 1;
unsigned char fgColor : 4;
unsigned char bgColor : 4;
unsigned char dataFmt : 4;
ktId typeId;
typedef union {
int32 i32;
struct {
unsigned char fgColorChanged : 1;
unsigned char bgColorChanged : 1;
unsigned char withPrefix : 1;
unsigned char uppercase : 1;
unsigned char fgColor : 4;
unsigned char bgColor : 4;
unsigned char dataFmt : 4;
ktId typeId;
};
} kprint_format;
#if __cplusplus

View File

@ -62,6 +62,20 @@ typedef double float64;
#define sprintf_s(BUF, BUFSIZE, FORMAT, ...) sprintf(BUF, FORMAT, ## __VA_ARGS__)
#endif
#define __count_args(\
a0, a1, a2, a3, a4, a5, a6, a7,\
a8, a9, a10,a11,a12,a13,a14,a15,\
a16,a17,a18,a19,a20,a21,a22,a23,\
a24,a25,a26,a27,a28,a29,a30,a31,\
a32,...) a32
#define count_args(ARGS...) __count_args(\
ARGS,\
32,31,30,29,28,27,26,25,\
24,23,22,21,20,19,18,17,\
16,15,14,13,12,11,10,9,\
8, 7, 6, 5, 4, 3, 2, 1, 0)
#if __cplusplus
}
#endif

View File

@ -0,0 +1,156 @@
#include "base_toString.h"
#include "../cptr.h"
#include "../kprint/kprint_format.h"
char* toString_int(int64 n){
int64 d=n;
char str[32];
uint8 i=sizeof(str);
str[--i]=0;
while(d!=0){
str[--i]='0' + d%10;
d/=10;
}
if(n>>63)
str[--i]='-';
return cptr_copy((char*)str+i);
}
char* toString_uint(uint64 n, bool withPostfix, bool uppercase){
uint64 d=n;
char str[32];
uint8 i=sizeof(str);
str[--i]=0;
if(withPostfix)
str[--i]= uppercase ? 'U' : 'u';
while(d!=0){
str[--i]='0' + d%10;
d/=10;
}
return cptr_copy((char*)str+i);
}
char* toString_float(float64 n, bool withPostfix, bool uppercase){
int64 d=n;
float64 r=n-d;
char* strint=toString_int(d);
char strfract[32];
uint8 i=0;
strfract[i++]='.';
while(r!=0){
r*=10.0;
char fc=r;
strfract[i++]=fc;
r-=fc;
}
if(withPostfix)
strfract[i++]= uppercase ? 'F' : 'f';
strfract[i]=0;
char* str=cptr_concat(strint, strfract);
free(strint);
return str;
}
char* toString_bin(char* bytes, uint32 size, bool withPrefix){
char* str=malloc(size*8+1);
uint32 cn=0;
if(withPrefix){
str[cn++]='0';
str[cn++]='b';
}
for(uint32 bn=0; bn<size; bn++){
char byte=bytes[bn];
for(uint8 i=0; i<8; i++)
str[cn++]='0' + (byte & (char)128>>i);
}
str[cn]=0;
return str;
}
char _4bitsHex(uint8 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'-10 : 'a'-10) + u;
default: return 219;
}
}
char* toString_hex(char* bytes, uint32 size, bool withPrefix, bool uppercase){
char* str=malloc(size*2);
uint32 cn=0;
if(withPrefix){
str[cn++]='0';
str[cn++]='x';
}
for(uint32 bn=0; bn<size; bn++){
char byte=bytes[bn];
str[cn++]=_4bitsHex(byte%16, uppercase);
str[cn++]=_4bitsHex(byte/16, uppercase);
}
str[cn]=0;
return str;
}
#define __toString_int_def(BITS) char* __toString_int##BITS(void* _n, int32 _f){\
kprint_format f=*(kprint_format*)&_f;\
switch(f.dataFmt | (uint32)0){\
case kprint_fmtInt:\
int##BITS n=*(int##BITS*)_n;\
return toString_int(n);\
case kprint_fmtBin:\
return toString_bin(_n, BITS/8, f.withPrefix);\
case kprint_fmtHex:\
return toString_hex(_n, BITS/8, f.withPrefix, f.uppercase);\
default:\
printf("\n%u\n", f.dataFmt);\
throw(ERR_FORMAT);\
return NULL;\
}\
}
__toString_int_def(8)
__toString_int_def(16)
__toString_int_def(32)
__toString_int_def(64)
#define __toString_uint_def(BITS) char* __toString_uint##BITS(void* _n, int32 _f){\
kprint_format f=*(kprint_format*)&_f;\
switch(f.dataFmt | (uint32)0){\
case kprint_fmtUInt:\
uint##BITS n=*(uint##BITS*)_n;\
return toString_uint(n, f.withPrefix, f.uppercase);\
case kprint_fmtBin:\
return toString_bin(_n, BITS/8, f.withPrefix);\
case kprint_fmtHex:\
return toString_hex(_n, BITS/8, f.withPrefix, f.uppercase);\
default:\
printf("\n%u\n", f.dataFmt);\
throw(ERR_FORMAT);\
return NULL;\
}\
}
__toString_uint_def(8)
__toString_uint_def(16)
__toString_uint_def(32)
__toString_uint_def(64)
#define __toString_float_def(BITS) char* __toString_float##BITS(void* _n, int32 _f){\
kprint_format f=*(kprint_format*)&_f;\
switch(f.dataFmt | (uint32)0){\
case kprint_fmtFloat:\
float##BITS n=*(float##BITS*)_n;\
return toString_float(n, f.withPrefix, f.uppercase);\
case kprint_fmtBin:\
return toString_bin(_n, BITS/8, f.withPrefix);\
case kprint_fmtHex:\
return toString_hex(_n, BITS/8, f.withPrefix, f.uppercase);\
default:\
printf("\n%u\n", f.dataFmt);\
throw(ERR_FORMAT);\
return NULL;\
}\
}

View File

@ -0,0 +1,32 @@
#pragma once
#if __cplusplus
extern "C" {
#endif
#include "../errors.h"
// functions for base types
char* toString_int(int64 n);
char* __toString_int8(void* n, int32 fmt);
char* __toString_int16(void* n, int32 fmt);
char* __toString_int32(void* n, int32 fmt);
char* __toString_int64(void* n, int32 fmt);
char* toString_uint(uint64 n, bool withPostfix, bool uppercase);
char* __toString_uint8(void* n, int32 fmt);
char* __toString_uint16(void* n, int32 fmt);
char* __toString_uint32(void* n, int32 fmt);
char* __toString_uint64(void* n, int32 fmt);
char* toString_float(float64 n, bool withPostfix, bool uppercase); // very bad implimentation
char* __toString_float32(void* n, int32 fmt);
char* __toString_float64(void* n, int32 fmt);
// universal functions
char* toString_bin(char* bytes, uint32 size, bool withPrefix);
char* toString_hex(char* bytes, uint32 size, bool withPrefix, bool uppercase);
#if __cplusplus
}
#endif

View File

@ -3,6 +3,7 @@
#include "../../SearchTree/SearchTree.h"
#include "../../Hashtable/Hashtable.h"
#include "../../String/StringBuilder.h"
#include "base_toString.h"
void ktDescriptors_initKerepTypes(){
// null

View File

@ -5,7 +5,6 @@ extern "C" {
#endif
#include "../std.h"
#include "../errors.h"
#include "ktId.h"
typedef struct ktDescriptor{
@ -13,8 +12,7 @@ typedef struct ktDescriptor{
ktId id;
uint16 size;
void (*freeMembers)(void*); // NULL or function which frees all struct members
///@return Maybe<char*>
Maybe (*toString)(void*, int32); // NULL or function which generates string representaion of object
char* (*toString)(void* obj, int32 fmt); // NULL or function which generates string representaion of object
} ktDescriptor;
#if __cplusplus

View File

@ -58,7 +58,7 @@ void ktDescriptors_endInit(){
printf("\e[92minitialized %u type descriptors\n", ktId_last);
}
void __kt_register(char* name, int16 size, void (*freeMembers)(void*), Maybe (*toString)(void*, int32)){
void __kt_register(char* name, int16 size, void (*freeMembers)(void*), char* (*toString)(void*, int32)){
ktDescriptor typeDesc={
.name=name,
.size=size,
@ -69,7 +69,10 @@ void __kt_register(char* name, int16 size, void (*freeMembers)(void*), Maybe (*t
Autoarr_add(__ktDescriptors, typeDesc);
}
Maybe ktDescriptor_get(ktId id){
if(id>ktId_last) safethrow("invalid type id",;);
return SUCCESS(UniStack(ktId_ktDescriptorPtr, &typeDescriptors[id]));
ktDescriptor ktDescriptor_get(ktId id){
if(id>ktId_last) {
printf("\n%u\n",id);
throw("invalid type id");
}
return typeDescriptors[id];
}

View File

@ -10,7 +10,7 @@ extern "C" {
extern ktId ktId_last;
void __kt_register(char* name, int16 size, void (*freeMembers)(void*), Maybe (*toString)(void*, int32));
void __kt_register(char* name, int16 size, void (*freeMembers)(void*), char* (*toString)(void*, int32));
#define kt_register(TYPE, ID_VAR_NAME, FREE_MEMBERS_FUNC, TO_STRING_FUNC)\
__kt_register(#ID_VAR_NAME, sizeof(TYPE), FREE_MEMBERS_FUNC, TO_STRING_FUNC);\
@ -18,9 +18,9 @@ void __kt_register(char* name, int16 size, void (*freeMembers)(void*), Maybe (*t
void ktDescriptors_beginInit();
void ktDescriptors_endInit();
/// @param id id of registered type
/// @return Maybe<ktDescriptor*>
Maybe ktDescriptor_get(ktId id);
/// @param id id of registered type
ktDescriptor ktDescriptor_get(ktId id);
ktId_declare(Null);

View File

@ -4,8 +4,7 @@ ktId_define(Unitype);
ktId_define(UnitypePtr);
void Unitype_free(Unitype u){
tryLast(ktDescriptor_get(u.typeId), mType);
ktDescriptor type=*(ktDescriptor*)mType.value.VoidPtr;
ktDescriptor type=ktDescriptor_get(u.typeId);
if(type.freeMembers)
type.freeMembers(u.VoidPtr);
if(u.allocatedInHeap)
@ -13,11 +12,23 @@ void Unitype_free(Unitype u){
}
void __UnitypePtr_free(void* u) { Unitype_free(*(Unitype*)u); }
char* toString_Unitype(void* _u, int32 fmt){
Unitype* u=_u;
ktDescriptor type=ktDescriptor_get(u->typeId);
char* valuestr=type.toString(_u, fmt);
char* rezult=cptr_concat("{ type: ", type.name,
", allocated on heap: ", (u->allocatedInHeap ? "true" : "false"),
", value:", valuestr, " }");
free(valuestr);
return rezult;
}
#define BUFSIZE 64
char* sprintuni(Unitype v){
char* buf=malloc(BUFSIZE);
tryLast(ktDescriptor_get(v.typeId), mType);
ktDescriptor type=*(ktDescriptor*)mType.value.VoidPtr;
ktDescriptor type=ktDescriptor_get(v.typeId);
if(v.typeId==ktId_Null)
sprintf_s(buf, BUFSIZE, "{Null}");
else if(v.typeId==ktId_Float64)