From 62d92b0aa67ae31185a239e2cf10c9c1466f84c1 Mon Sep 17 00:00:00 2001 From: dimgigov Date: Wed, 10 Jun 2026 20:08:24 +0300 Subject: [PATCH] test: add error snippet formatting test --- _test_error_snippet/build/bux_out | Bin 0 -> 104920 bytes _test_error_snippet/build/main.c | 2612 +++++++++++++++++++++++++++++ _test_error_snippet/bux.toml | 4 + _test_error_snippet/src/Main.bux | 4 + 4 files changed, 2620 insertions(+) create mode 100755 _test_error_snippet/build/bux_out create mode 100644 _test_error_snippet/build/main.c create mode 100644 _test_error_snippet/bux.toml create mode 100644 _test_error_snippet/src/Main.bux diff --git a/_test_error_snippet/build/bux_out b/_test_error_snippet/build/bux_out new file mode 100755 index 0000000000000000000000000000000000000000..f4ab5ba9c3149675cb73deb44401294f82bea58f GIT binary patch literal 104920 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℘MIecJqn(CLFdO% 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 ubMWWt?TRJi%at9cxntlio5Qu& +#include +#include +#include +#include + +typedef const char* String; +typedef unsigned char uint8; +typedef unsigned short uint16; +typedef unsigned int uint32; +typedef unsigned long long uint64; +typedef signed char int8; +typedef short int16; +typedef long long int64; +typedef float float32; +typedef double float64; +typedef char char8; + +void* bux_alloc(unsigned int size); +void bux_free(void* ptr); + +typedef struct TaskHandle TaskHandle; +typedef struct Mutex Mutex; +typedef struct RwLock RwLock; +typedef struct JsonValue JsonValue; +typedef struct JsonParser JsonParser; +typedef struct StringBuilder StringBuilder; +typedef struct Channel_int Channel_int; +typedef struct Channel_float64 Channel_float64; + +typedef enum { + Result_Ok, + Result_Err +} Result_Tag; + +typedef union { + int Ok_0; + String Err_0; +} Result_Data; + +typedef struct { + Result_Tag tag; + Result_Data data; +} Result; + +typedef enum { + Option_Some, + Option_None +} Option_Tag; + +typedef union { + int Some_0; +} Option_Data; + +typedef struct { + Option_Tag tag; + Option_Data data; +} Option; + +typedef enum { + JwtAlg_HS256, + JwtAlg_HS384, + JwtAlg_HS512, + JwtAlg_RS256, + JwtAlg_RS384, + JwtAlg_RS512, + JwtAlg_ES256, + JwtAlg_ES384, + JwtAlg_EdDSA +} JwtAlg_Tag; + +typedef struct { + JwtAlg_Tag tag; +} JwtAlg; + +#define JsonTagNull 0 +#define JsonTagBool 1 +#define JsonTagNumber 2 +#define JsonTagString 3 +#define JsonTagArray 4 +#define JsonTagObject 5 +#define AES_KEY_SIZE 32 +#define AES_IV_SIZE 16 +#define AES_GCM_TAG_SIZE 16 +#define ED25519_PUBKEY_SIZE 32 +#define ED25519_PRIVKEY_SIZE 32 +#define ED25519_SIG_SIZE 64 + +struct TaskHandle { + void* handle; +}; + +struct Mutex { + void* handle; +}; + +struct RwLock { + void* handle; +}; + +struct JsonValue { + int tag; + bool boolVal; + float64 numVal; + String strVal; + JsonValue* arrData; + uint arrLen; + uint arrCap; + String* objKeys; + JsonValue* objValues; + uint objLen; + uint objCap; +}; + +struct JsonParser { + String src; + uint pos; + uint len; + String error; +}; + +struct StringBuilder { + void* handle; +}; + +struct Channel_int { + void* handle; +}; + +struct Channel_float64 { + void* handle; +}; + +bool DirExists(String path); +bool Mkdir(String path); +String* ListDir(String dir, String ext, int* count); +String ReadFile(String path); +bool WriteFile(String path, String content); +bool FileExists(String path); +float64 Sqrt(float64 x); +float64 Pow(float64 x, float64 y); +int64 Abs(int64 n); +float64 AbsF(float64 f); +int64 Min(int64 a, int64 b); +int64 Max(int64 a, int64 b); +float64 MinF(float64 a, float64 b); +float64 MaxF(float64 a, float64 b); +void* Alloc(uint size); +void* Realloc(void* ptr, uint size); +void Free(void* ptr); +bool MemEq(void* a, void* b, uint size); +String Path_Join(String a, String b); +String Path_Parent(String path); +String Path_Ext(String path); +void Task_Init(int num_workers); +TaskHandle Task_Spawn(void* fn, void* arg); +void Task_Wait(TaskHandle t); +void Task_Sleep(int64 ms); +void Task_Yield(); +int Task_CurrentId(); +void Task_Shutdown(); +int Os_ArgsCount(); +String Os_Args(int index); +String Os_GetEnv(String name); +bool Os_SetEnv(String name, String value); +String Os_GetCwd(); +bool Os_Chdir(String path); +int64 Time_NowMs(); +int64 Time_NowUs(); +void Time_SleepMs(int64 ms); +int Process_Run(String cmd); +String Process_Output(String cmd); +int Net_Create(); +bool Net_SetReuse(int fd); +bool Net_Bind(int fd, String addr, int port); +bool Net_Listen(int fd, int backlog); +int Net_Accept(int fd); +bool Net_Connect(int fd, String addr, int port); +int Net_Send(int fd, String data); +String Net_Recv(int fd, int maxLen); +bool Net_Close(int fd); +String Net_LastError(); +String Fmt_Fmt3(String tmpl, String a1, String a2, String a3); +String Fmt_Fmt2(String tmpl, String a1, String a2); +String Fmt_FmtFloat(String tmpl, float64 val); +String Fmt_FmtBool(String tmpl, bool val); +String Fmt_FmtInt(String tmpl, int64 val); +String Fmt_Fmt1(String tmpl, String a1); +String Fmt_Format(String tmpl, String* argStrs, int argCount); +String Crypto_Sha256(String data); +String Crypto_HmacSha256(String key, String message); +String Crypto_RandomBytes(int n); +String Crypto_Base64Encode(String s); +String Crypto_HmacSha256Raw(String key, String message); +String Crypto_Base64Decode(String s); +Mutex Mutex_New(); +void Mutex_Lock(Mutex* m); +void Mutex_Unlock(Mutex* m); +void Mutex_Free(Mutex* m); +RwLock RwLock_New(); +void RwLock_ReadLock(RwLock* rw); +void RwLock_WriteLock(RwLock* rw); +void RwLock_Unlock(RwLock* rw); +void RwLock_Free(RwLock* rw); +void Test_Exit(int code); +void Test_Assert(bool cond); +void Test_AssertEqInt(int a, int b); +void Test_AssertTrue(bool cond); +void Test_AssertFalse(bool cond); +void Test_Fail(String msg); +Result Result_NewOk(int value); +Result Result_NewErr(String msg); +bool Result_IsOk(Result r); +bool Result_IsErr(Result r); +int Result_Unwrap(Result r); +int Result_UnwrapOr(Result r, int fallback); +Option Option_NewSome(int value); +Option Option_NewNone(); +bool Option_IsSome(Option o); +bool Option_IsNone(Option o); +int Option_Unwrap(Option o); +int Option_UnwrapOr(Option o, int fallback); +JsonValue Json_Null(); +JsonValue Json_Bool(bool b); +JsonValue Json_Number(float64 n); +JsonValue Json_String(String s); +JsonValue Json_Array(); +JsonValue Json_Object(); +uint Json_ArrayLen(JsonValue v); +JsonValue Json_ArrayGet(JsonValue v, uint index); +void Json_ArrayPush(JsonValue* self, JsonValue val); +uint Json_ObjectLen(JsonValue v); +JsonValue Json_ObjectGet(JsonValue v, String key); +bool Json_ObjectHas(JsonValue v, String key); +void Json_ObjectSet(JsonValue* self, String key, JsonValue val); +bool Json_IsNull(JsonValue v); +bool Json_AsBool(JsonValue v); +float64 Json_AsNumber(JsonValue v); +String Json_AsString(JsonValue v); +int JsonParser_Peek(JsonParser* p); +void JsonParser_Advance(JsonParser* p); +void JsonParser_SkipWhitespace(JsonParser* p); +bool JsonParser_Match(JsonParser* p, String expected); +String JsonParser_ParseString(JsonParser* p); +JsonValue JsonParser_ParseNumber(JsonParser* p); +JsonValue JsonParser_ParseArray(JsonParser* p); +JsonValue JsonParser_ParseObject(JsonParser* p); +JsonValue JsonParser_ParseValue(JsonParser* p); +JsonValue Json_Parse(String s); +void Json_StringifyImpl(StringBuilder* sb, JsonValue v); +String Json_Stringify(JsonValue v); +String Hash_Sha1(String data); +String Hash_Sha256(String data); +String Hash_Sha384(String data); +String Hash_Sha512(String data); +void Hash_Sha256Raw(String data, void* out); +void Hash_Sha384Raw(String data, void* out); +void Hash_Sha512Raw(String data, void* out); +int Hash_Sha1Size(); +int Hash_Sha256Size(); +int Hash_Sha384Size(); +int Hash_Sha512Size(); +String Base64_Encode(String s); +String Base64_Decode(String s); +String Base64URL_Encode(String s); +String Base64URL_Decode(String s); +String Hmac_Sha256(String key, String message); +void Hmac_Sha256Raw(String key, String message, void* out); +String Hmac_Sha256Base64(String key, String message); +String Hmac_Sha384(String key, String message); +void Hmac_Sha384Raw(String key, String message, void* out); +String Hmac_Sha384Base64(String key, String message); +String Hmac_Sha512(String key, String message); +void Hmac_Sha512Raw(String key, String message, void* out); +String Hmac_Sha512Base64(String key, String message); +String Random_Bytes(int n); +String Random_Hex(int n); +String Random_Base64(int n); +uint Random_Uint32(); +String Aes_GenerateKey(); +String Aes_GenerateIV(); +String Aes_CbcEncrypt(String plain, String key, String iv); +String Aes_CbcDecrypt(String cipher, String key, String iv); +String Aes_GcmEncrypt(String plain, String key, String iv, void* tag); +String Aes_GcmDecrypt(String cipher, String key, String iv, String tag); +String Jwt_MakeHeader(JwtAlg alg); +String Jwt_Sign(JwtAlg alg, String signingInput, String key); +bool Jwt_Verify(JwtAlg alg, String signingInput, String signatureB64, String key); +String Jwt_Encode(String headerJson, String payloadJson, JwtAlg alg, String key); +bool Jwt_Decode(String token, JwtAlg alg, String key, String* headerOut, String* payloadOut); +String Jwt_EncodeHS256(String payloadJson, String secret); +String Jwt_EncodeHS384(String payloadJson, String secret); +String Jwt_EncodeHS512(String payloadJson, String secret); +String Jwt_EncodeRS256(String payloadJson, String pemPrivateKey); +String Jwt_EncodeES256(String payloadJson, String pemPrivateKey); +String Jwt_EncodeEdDSA(String payloadJson, String rawPrivKey); +String Ecdsa_SignP256(String pemPrivateKey, String data); +String Ecdsa_SignP256Base64(String pemPrivateKey, String data); +bool Ecdsa_VerifyP256(String pemPublicKey, String data, String signature); +bool Ecdsa_VerifyP256Base64(String pemPublicKey, String data, String signatureB64); +String Ecdsa_SignP384(String pemPrivateKey, String data); +String Ecdsa_SignP384Base64(String pemPrivateKey, String data); +bool Ecdsa_VerifyP384(String pemPublicKey, String data, String signature); +bool Ecdsa_VerifyP384Base64(String pemPublicKey, String data, String signatureB64); +bool Ed25519_Keypair(void* pubKey, void* privKey); +String Ed25519_KeypairBase64(); +String Ed25519_Sign(String privKey, String data); +String Ed25519_SignBase64(String privKey, String data); +bool Ed25519_Verify(String pubKey, String signature, String data); +bool Ed25519_VerifyBase64(String pubKey, String signatureB64, String data); +String Rsa_SignSha256(String pemPrivateKey, String data); +String Rsa_SignSha384(String pemPrivateKey, String data); +String Rsa_SignSha512(String pemPrivateKey, String data); +String Rsa_SignSha256Base64(String pemPrivateKey, String data); +String Rsa_SignSha384Base64(String pemPrivateKey, String data); +String Rsa_SignSha512Base64(String pemPrivateKey, String data); +bool Rsa_VerifySha256(String pemPublicKey, String data, String signature); +bool Rsa_VerifySha384(String pemPublicKey, String data, String signature); +bool Rsa_VerifySha512(String pemPublicKey, String data, String signature); +bool Rsa_VerifySha256Base64(String pemPublicKey, String data, String signatureB64); +bool Rsa_VerifySha384Base64(String pemPublicKey, String data, String signatureB64); +bool Rsa_VerifySha512Base64(String pemPublicKey, String data, String signatureB64); +uint String_Len(String s); +bool String_IsNull(String s); +bool String_Eq(String a, String b); +String String_Concat(String a, String b); +String String_Copy(String s); +bool String_StartsWith(String s, String prefix); +bool String_EndsWith(String s, String suffix); +bool String_Contains(String s, String substr); +String String_Slice(String s, uint start, uint len); +String String_Trim(String s); +String String_TrimLeft(String s); +String String_TrimRight(String s); +String String_FromInt(int64 n); +int64 String_ToInt(String s); +StringBuilder StringBuilder_New(); +StringBuilder StringBuilder_NewCap(uint cap); +void StringBuilder_Append(StringBuilder* sb, String s); +void StringBuilder_AppendInt(StringBuilder* sb, int64 n); +void StringBuilder_AppendFloat(StringBuilder* sb, float64 f); +void StringBuilder_AppendChar(StringBuilder* sb, char8 c); +String StringBuilder_Build(StringBuilder* sb); +void StringBuilder_Free(StringBuilder* sb); +uint String_SplitCount(String s, String delim); +String String_SplitPart(String s, String delim, uint index); +String String_Join2(String a, String b, String sep); +String String_Chars(String s, uint index); +String String_Find(String haystack, String needle); +uint String_Offset(String pos, String base); +String String_Replace(String s, String old, String new); +float64 String_ToFloat(String s); +String String_FromBool(bool b); +String String_FromFloat(float64 f); +String String_Format1(String pattern, String a0); +String String_Format2(String pattern, String a0, String a1); +String String_Format3(String pattern, String a0, String a1, String a2); +void Channel_SendInt(Channel_int* ch, int value); +int Channel_RecvInt(Channel_int* ch); +void Channel_SendFloat64(Channel_float64* ch, float64 value); +float64 Channel_RecvFloat64(Channel_float64* ch); +int Main(); + +int bux_dir_exists(String path); +int bux_mkdir_if_needed(String path); +String* bux_list_dir(String dir, String ext, int* out_count); +void PrintLine(String s); +void Print(String s); +void PrintInt(int n); +void PrintInt64(int64 n); +void PrintFloat(float64 f); +void PrintBool(bool b); +String ReadLine(); +String bux_read_file(String path); +int bux_write_file(String path, String content); +int bux_file_exists(String path); +float64 bux_sqrt(float64 x); +float64 bux_pow(float64 x, float64 y); +int64 bux_abs_i64(int64 x); +float64 bux_abs_f64(float64 x); +int64 bux_min_i64(int64 a, int64 b); +int64 bux_max_i64(int64 a, int64 b); +float64 bux_min_f64(float64 a, float64 b); +float64 bux_max_f64(float64 a, float64 b); +void* bux_alloc(uint size); +void* bux_realloc(void* ptr, uint size); +void bux_free(void* ptr); +int bux_mem_eq(void* a, void* b, uint size); +String bux_path_join(String a, String b); +String bux_path_parent(String path); +String bux_path_ext(String path); +void bux_task_init(int num_workers); +void* bux_task_spawn(void* fn, void* arg); +void bux_task_join(void* handle); +void bux_task_sleep(int64 ms); +void bux_task_yield(); +int bux_task_current_id(); +void bux_task_shutdown(); +int bux_argc(); +String bux_argv(int index); +String bux_getenv(String name); +int bux_setenv(String name, String value); +String bux_getcwd(); +int bux_chdir(String path); +int64 bux_time_ms(); +int64 bux_time_us(); +void bux_sleep_ms(int64 ms); +int bux_process_run(String cmd); +String bux_process_output(String cmd); +int bux_socket_create(); +int bux_socket_reuse(int fd); +int bux_socket_bind(int fd, String addr, int port); +int bux_socket_listen(int fd, int backlog); +int bux_socket_accept(int fd); +int bux_socket_connect(int fd, String addr, int port); +int bux_socket_send(int fd, String data, int len); +String bux_socket_recv(int fd, int maxLen); +int bux_socket_close(int fd); +String bux_socket_error(); +void* bux_alloc(uint size); +int64 bux_str_to_int(String s); +uint bux_strlen(String s); +void bux_sha256(String data, int len, void* out); +void bux_hmac_sha256(String key, int keylen, String msg, int msglen, void* out); +int bux_random_bytes(void* buf, int len); +String bux_base64_encode(String data, int len); +String bux_base64_decode(String data, int len, int* outlen); +String bux_bytes_to_hex(void* data, int len); +void* bux_mutex_new(); +void bux_mutex_lock(void* handle); +void bux_mutex_unlock(void* handle); +void bux_mutex_free(void* handle); +void* bux_rwlock_new(); +void bux_rwlock_rdlock(void* handle); +void bux_rwlock_wrlock(void* handle); +void bux_rwlock_unlock(void* handle); +void bux_rwlock_free(void* handle); +void bux_exit(int code); +void bux_assert(int cond, String file, int line, String expr); +void bux_sha1(String data, int len, void* out); +void bux_sha256(String data, int len, void* out); +void bux_sha384(String data, int len, void* out); +void bux_sha512(String data, int len, void* out); +String bux_bytes_to_hex(void* data, int len); +String bux_base64_encode(String data, int len); +String bux_base64_decode(String data, int len, int* outlen); +String bux_base64url_encode(String data, int len); +String bux_base64url_decode(String data, int len, int* outlen); +void bux_hmac_sha256(String key, int keylen, String msg, int msglen, void* out); +void bux_hmac_sha384(String key, int keylen, String msg, int msglen, void* out); +void bux_hmac_sha512(String key, int keylen, String msg, int msglen, void* out); +String bux_bytes_to_hex(void* data, int len); +String bux_base64_encode(String data, int len); +int bux_random_bytes(void* buf, int len); +String bux_base64_encode(String data, int len); +String bux_bytes_to_hex(void* data, int len); +int bux_random_bytes(void* buf, int len); +String bux_aes_256_cbc_encrypt(String plain, int plainlen, String key, String iv, int* outlen); +String bux_aes_256_cbc_decrypt(String cipher, int cipherlen, String key, String iv, int* outlen); +String bux_aes_256_gcm_encrypt(String plain, int plainlen, String key, String iv, void* tag, int* outlen); +String bux_aes_256_gcm_decrypt(String cipher, int cipherlen, String key, String iv, String tag, int* outlen); +String bux_base64_encode(String data, int len); +uint bux_str_split_count(String s, String delim); +String bux_str_split_part(String s, String delim, uint index); +String bux_ecdsa_sign_p256(String key, int keylen, String data, int datalen, int* outlen); +int bux_ecdsa_verify_p256(String key, int keylen, String data, int datalen, String sig, int siglen); +String bux_ecdsa_sign_p384(String key, int keylen, String data, int datalen, int* outlen); +int bux_ecdsa_verify_p384(String key, int keylen, String data, int datalen, String sig, int siglen); +String bux_base64_encode(String data, int len); +String bux_base64_decode(String data, int len, int* outlen); +int bux_ed25519_keypair(void* pubKey, void* privKey); +int bux_ed25519_sign(String privKey, String data, int datalen, void* sig); +int bux_ed25519_verify(String pubKey, String sig, String data, int datalen); +String bux_base64_encode(String data, int len); +String bux_base64_decode(String data, int len, int* outlen); +String bux_rsa_sign_sha256(String key, int keylen, String data, int datalen, int* outlen); +String bux_rsa_sign_sha384(String key, int keylen, String data, int datalen, int* outlen); +String bux_rsa_sign_sha512(String key, int keylen, String data, int datalen, int* outlen); +int bux_rsa_verify_sha256(String key, int keylen, String data, int datalen, String sig, int siglen); +int bux_rsa_verify_sha384(String key, int keylen, String data, int datalen, String sig, int siglen); +int bux_rsa_verify_sha512(String key, int keylen, String data, int datalen, String sig, int siglen); +String bux_base64_encode(String data, int len); +String bux_base64_decode(String data, int len, int* outlen); +uint bux_strlen(String s); +int bux_strcmp(String a, String b); +int bux_strncmp(String a, String b, uint n); +char8* bux_strcpy(char8* dest, String src); +char8* bux_strcat(char8* dest, String src); +char8* bux_strncpy(char8* dest, String src, uint n); +String bux_strstr(String haystack, String needle); +int bux_str_contains(String haystack, String needle); +uint bux_str_offset(String pos, String base); +int bux_str_is_null(String s); +String bux_str_slice(String s, uint start, uint len); +String bux_str_trim_left(String s); +String bux_str_trim_right(String s); +String bux_str_trim(String s); +String bux_int_to_str(int64 n); +int64 bux_str_to_int(String s); +void* bux_sb_new(uint initial_cap); +void bux_sb_append(void* sb, String s); +void bux_sb_append_int(void* sb, int64 n); +void bux_sb_append_float(void* sb, float64 f); +void bux_sb_append_char(void* sb, char8 c); +String bux_sb_build(void* sb); +void bux_sb_free(void* sb); +uint bux_str_split_count(String s, String delim); +String bux_str_split_part(String s, String delim, uint index); +String bux_str_join2(String a, String b, String sep); +String bux_float_to_string(float64 f); +String bux_str_format(String pattern, String a0, String a1, String a2, String a3, String a4, String a5, String a6, String a7); +float64 bux_str_to_float(String s); +void bux_bounds_check(uint index, uint len); +void* bux_alloc(uint size); +void* bux_realloc(void* ptr, uint size); +void bux_free(void* ptr); +void bux_bounds_check(uint index, uint len); +void* bux_channel_new(int64 capacity, int64 elem_size); +void bux_channel_send(void* handle, void* elem); +int bux_channel_recv(void* handle, void* out); +void bux_channel_close(void* handle); +void bux_channel_free(void* handle); +uint bux_hash_bytes(void* ptr, uint size); +uint bux_hash_string(String s); +uint bux_hash_bytes(void* ptr, uint size); +int bux_mem_eq(void* a, void* b, uint size); +void* bux_alloc(uint size); +void bux_free(void* ptr); + +bool DirExists(String path) { + return bux_dir_exists(path) != 0; + +} + +bool Mkdir(String path) { + return bux_mkdir_if_needed(path) != 0; + +} + +String* ListDir(String dir, String ext, int* count) { + return bux_list_dir(dir, ext, count); + +} + +String ReadFile(String path) { + return bux_read_file(path); + +} + +bool WriteFile(String path, String content) { + int r = bux_write_file(path, content); + return r != 0; + +} + +bool FileExists(String path) { + int r = bux_file_exists(path); + return r != 0; + +} + +float64 Sqrt(float64 x) { + return bux_sqrt(x); + +} + +float64 Pow(float64 x, float64 y) { + return bux_pow(x, y); + +} + +int64 Abs(int64 n) { + return bux_abs_i64(n); + +} + +float64 AbsF(float64 f) { + return bux_abs_f64(f); + +} + +int64 Min(int64 a, int64 b) { + return bux_min_i64(a, b); + +} + +int64 Max(int64 a, int64 b) { + return bux_max_i64(a, b); + +} + +float64 MinF(float64 a, float64 b) { + return bux_min_f64(a, b); + +} + +float64 MaxF(float64 a, float64 b) { + return bux_max_f64(a, b); + +} + +void* Alloc(uint size) { + return bux_alloc(size); + +} + +void* Realloc(void* ptr, uint size) { + return bux_realloc(ptr, size); + +} + +void Free(void* ptr) { + bux_free(ptr); + +} + +bool MemEq(void* a, void* b, uint size) { + return bux_mem_eq(a, b, size) != 0; + +} + +String Path_Join(String a, String b) { + return bux_path_join(a, b); + +} + +String Path_Parent(String path) { + return bux_path_parent(path); + +} + +String Path_Ext(String path) { + return bux_path_ext(path); + +} + +void Task_Init(int num_workers) { + bux_task_init(num_workers); + +} + +TaskHandle Task_Spawn(void* fn, void* arg) { + return ((TaskHandle){.handle = bux_task_spawn(fn, arg)}); + +} + +void Task_Wait(TaskHandle t) { + bux_task_join(t.handle); + +} + +void Task_Sleep(int64 ms) { + bux_task_sleep(ms); + +} + +void Task_Yield() { + bux_task_yield(); + +} + +int Task_CurrentId() { + return bux_task_current_id(); + +} + +void Task_Shutdown() { + bux_task_shutdown(); + +} + +int Os_ArgsCount() { + return bux_argc(); + +} + +String Os_Args(int index) { + return bux_argv(index); + +} + +String Os_GetEnv(String name) { + return bux_getenv(name); + +} + +bool Os_SetEnv(String name, String value) { + return bux_setenv(name, value) == 0; + +} + +String Os_GetCwd() { + return bux_getcwd(); + +} + +bool Os_Chdir(String path) { + return bux_chdir(path) == 0; + +} + +int64 Time_NowMs() { + return bux_time_ms(); + +} + +int64 Time_NowUs() { + return bux_time_us(); + +} + +void Time_SleepMs(int64 ms) { + bux_sleep_ms(ms); + +} + +int Process_Run(String cmd) { + return bux_process_run(cmd); + +} + +String Process_Output(String cmd) { + return bux_process_output(cmd); + +} + +int Net_Create() { + return bux_socket_create(); + +} + +bool Net_SetReuse(int fd) { + return bux_socket_reuse(fd) == 0; + +} + +bool Net_Bind(int fd, String addr, int port) { + return bux_socket_bind(fd, addr, port) == 0; + +} + +bool Net_Listen(int fd, int backlog) { + return bux_socket_listen(fd, backlog) == 0; + +} + +int Net_Accept(int fd) { + return bux_socket_accept(fd); + +} + +bool Net_Connect(int fd, String addr, int port) { + return bux_socket_connect(fd, addr, port) == 0; + +} + +int Net_Send(int fd, String data) { + return bux_socket_send(fd, data, ((int)bux_strlen(data))); + +} + +String Net_Recv(int fd, int maxLen) { + return bux_socket_recv(fd, maxLen); + +} + +bool Net_Close(int fd) { + return bux_socket_close(fd) == 0; + +} + +String Net_LastError() { + return bux_socket_error(); + +} + +String Fmt_Fmt3(String tmpl, String a1, String a2, String a3) { + String* args = ((String*)bux_alloc(3 * sizeof(String))); + args[0] = a1; + args[1] = a2; + args[2] = a3; + return Fmt_Format(tmpl, args, 3); + +} + +String Fmt_Fmt2(String tmpl, String a1, String a2) { + String* args = ((String*)bux_alloc(2 * sizeof(String))); + args[0] = a1; + args[1] = a2; + return Fmt_Format(tmpl, args, 2); + +} + +String Fmt_FmtFloat(String tmpl, float64 val) { + String s = String_FromFloat(val); + return Fmt_Fmt1(tmpl, s); + +} + +String Fmt_FmtBool(String tmpl, bool val) { + String s = String_FromBool(val); + return Fmt_Fmt1(tmpl, s); + +} + +String Fmt_FmtInt(String tmpl, int64 val) { + String s = String_FromInt(val); + return Fmt_Fmt1(tmpl, s); + +} + +String Fmt_Fmt1(String tmpl, String a1) { + String* args = ((String*)bux_alloc(sizeof(String))); + args[0] = a1; + return Fmt_Format(tmpl, args, 1); + +} + +String Fmt_Format(String tmpl, String* argStrs, int argCount) { + StringBuilder sb = StringBuilder_New(); + uint i = 0; + uint tmplLen = bux_strlen(tmpl); + while (i < tmplLen) { + String ch = String_Chars(tmpl, i); + if (String_Eq(ch, "{")) { + uint digitIdx = i + 1; + if (digitIdx < tmplLen) { + String digitCh = String_Chars(tmpl, digitIdx); + int64 d = bux_str_to_int(digitCh); + if (d >= 0 && d < ((int64)argCount)) { + i = i + 2; + if (i < tmplLen) { + String closeCh = String_Chars(tmpl, i); + if (String_Eq(closeCh, "}")) { + i = i + 1; + String argStr = argStrs[((uint)d)]; + StringBuilder_Append(&sb, argStr); + continue; + } + + } + + } + + } + + } + + StringBuilder_Append(&sb, ch); + i = i + 1; + } + return StringBuilder_Build(&sb); + +} + +String Crypto_Sha256(String data) { + int len = ((int)String_Len(data)); + void* hashBuf = Alloc(32); + bux_sha256(data, len, hashBuf); + String result = bux_bytes_to_hex(((void*)hashBuf), 32); + Free(hashBuf); + return result; + +} + +String Crypto_HmacSha256(String key, String message) { + int keylen = ((int)String_Len(key)); + int msglen = ((int)String_Len(message)); + void* hmacBuf = Alloc(32); + bux_hmac_sha256(key, keylen, message, msglen, hmacBuf); + String result = bux_bytes_to_hex(((void*)hmacBuf), 32); + Free(hmacBuf); + return result; + +} + +String Crypto_RandomBytes(int n) { + if (n <= 0) { + return ""; + } + + void* buf = Alloc(((uint)n)); + if (bux_random_bytes(buf, n) != 1) { + Free(buf); + return ""; + } + + String result = bux_base64_encode(((String)buf), n); + Free(buf); + return result; + +} + +String Crypto_Base64Encode(String s) { + return bux_base64_encode(s, ((int)String_Len(s))); + +} + +String Crypto_HmacSha256Raw(String key, String message) { + int keylen = ((int)String_Len(key)); + int msglen = ((int)String_Len(message)); + void* hmacBuf = Alloc(32); + bux_hmac_sha256(key, keylen, message, msglen, hmacBuf); + String result = bux_base64_encode(((String)hmacBuf), 32); + Free(hmacBuf); + return result; + +} + +String Crypto_Base64Decode(String s) { + int outlen = 0; + return bux_base64_decode(s, ((int)String_Len(s)), &outlen); + +} + +Mutex Mutex_New() { + return ((Mutex){.handle = bux_mutex_new()}); + +} + +void Mutex_Lock(Mutex* m) { + bux_mutex_lock(m->handle); + +} + +void Mutex_Unlock(Mutex* m) { + bux_mutex_unlock(m->handle); + +} + +void Mutex_Free(Mutex* m) { + bux_mutex_free(m->handle); + +} + +RwLock RwLock_New() { + return ((RwLock){.handle = bux_rwlock_new()}); + +} + +void RwLock_ReadLock(RwLock* rw) { + bux_rwlock_rdlock(rw->handle); + +} + +void RwLock_WriteLock(RwLock* rw) { + bux_rwlock_wrlock(rw->handle); + +} + +void RwLock_Unlock(RwLock* rw) { + bux_rwlock_unlock(rw->handle); + +} + +void RwLock_Free(RwLock* rw) { + bux_rwlock_free(rw->handle); + +} + +void Test_Exit(int code) { + bux_exit(code); + +} + +void Test_Assert(bool cond) { + bux_assert(((int)cond), "", 0, ""); + +} + +void Test_AssertEqInt(int a, int b) { + if (a != b) { + PrintLine("ASSERT_EQ FAILED:"); + PrintInt(a); + PrintLine(" != "); + PrintInt(b); + bux_exit(1); + } + + +} + +void Test_AssertTrue(bool cond) { + if (!cond) { + PrintLine("ASSERT_TRUE FAILED"); + bux_exit(1); + } + + +} + +void Test_AssertFalse(bool cond) { + if (cond) { + PrintLine("ASSERT_FALSE FAILED"); + bux_exit(1); + } + + +} + +void Test_Fail(String msg) { + PrintLine("FAIL:"); + PrintLine(msg); + bux_exit(1); + +} + +Result Result_NewOk(int value) { + Result r = ((Result){.tag = Result_Ok}); + r.data.Ok_0 = value; + return r; + +} + +Result Result_NewErr(String msg) { + Result r = ((Result){.tag = Result_Err}); + r.data.Err_0 = msg; + return r; + +} + +bool Result_IsOk(Result r) { + return r.tag == Result_Ok; + +} + +bool Result_IsErr(Result r) { + return r.tag == Result_Err; + +} + +int Result_Unwrap(Result r) { + if (r.tag != Result_Ok) { + PrintLine("panic: unwrap on Err"); + return 0; + } + + return r.data.Ok_0; + +} + +int Result_UnwrapOr(Result r, int fallback) { + if (r.tag == Result_Ok) { + return r.data.Ok_0; + } + + return fallback; + +} + +Option Option_NewSome(int value) { + Option o = ((Option){.tag = Option_Some}); + o.data.Some_0 = value; + return o; + +} + +Option Option_NewNone() { + return ((Option){.tag = Option_None}); + +} + +bool Option_IsSome(Option o) { + return o.tag == Option_Some; + +} + +bool Option_IsNone(Option o) { + return o.tag == Option_None; + +} + +int Option_Unwrap(Option o) { + if (o.tag != Option_Some) { + PrintLine("panic: unwrap on None"); + return 0; + } + + return o.data.Some_0; + +} + +int Option_UnwrapOr(Option o, int fallback) { + if (o.tag == Option_Some) { + return o.data.Some_0; + } + + return fallback; + +} + +JsonValue Json_Null() { + return ((JsonValue){.tag = JsonTagNull, .boolVal = false, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}); + +} + +JsonValue Json_Bool(bool b) { + return ((JsonValue){.tag = JsonTagBool, .boolVal = b, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}); + +} + +JsonValue Json_Number(float64 n) { + return ((JsonValue){.tag = JsonTagNumber, .boolVal = false, .numVal = n, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}); + +} + +JsonValue Json_String(String s) { + return ((JsonValue){.tag = JsonTagString, .boolVal = false, .numVal = 0.0, .strVal = s, .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}); + +} + +JsonValue Json_Array() { + return ((JsonValue){.tag = JsonTagArray, .boolVal = false, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}); + +} + +JsonValue Json_Object() { + return ((JsonValue){.tag = JsonTagObject, .boolVal = false, .numVal = 0.0, .strVal = "", .arrData = 0, .arrLen = 0, .arrCap = 0, .objKeys = 0, .objValues = 0, .objLen = 0, .objCap = 0}); + +} + +uint Json_ArrayLen(JsonValue v) { + if (v.tag != JsonTagArray) { + return 0; + } + + return v.arrLen; + +} + +JsonValue Json_ArrayGet(JsonValue v, uint index) { + if (v.tag != JsonTagArray) { + return Json_Null(); + } + + if (index >= v.arrLen) { + return Json_Null(); + } + + return v.arrData[index]; + +} + +void Json_ArrayPush(JsonValue* self, JsonValue val) { + if (self->tag != JsonTagArray) { + return; + } + + if (self->arrLen >= self->arrCap) { + uint arrNewCap = self->arrCap; + if (arrNewCap == 0) { + self->arrCap = 4; + self->arrData = ((JsonValue*)Alloc(4 * sizeof(JsonValue))); + } else { + uint doubleCap = arrNewCap * 2; + self->arrCap = doubleCap; + self->arrData = ((JsonValue*)Realloc(((void*)self->arrData), doubleCap * sizeof(JsonValue))); + } + + } + + self->arrData[self->arrLen] = val; + self->arrLen = self->arrLen + 1; + +} + +uint Json_ObjectLen(JsonValue v) { + if (v.tag != JsonTagObject) { + return 0; + } + + return v.objLen; + +} + +JsonValue Json_ObjectGet(JsonValue v, String key) { + if (v.tag != JsonTagObject) { + return Json_Null(); + } + + uint i = 0; + while (i < v.objLen) { + if (String_Eq(v.objKeys[i], key)) { + return v.objValues[i]; + } + + i = i + 1; + } + return Json_Null(); + +} + +bool Json_ObjectHas(JsonValue v, String key) { + if (v.tag != JsonTagObject) { + return false; + } + + uint i = 0; + while (i < v.objLen) { + if (String_Eq(v.objKeys[i], key)) { + return true; + } + + i = i + 1; + } + return false; + +} + +void Json_ObjectSet(JsonValue* self, String key, JsonValue val) { + if (self->tag != JsonTagObject) { + return; + } + + uint i = 0; + while (i < self->objLen) { + if (String_Eq(self->objKeys[i], key)) { + self->objValues[i] = val; + return; + } + + i = i + 1; + } + if (self->objLen >= self->objCap) { + uint objNewCap = self->objCap; + if (objNewCap == 0) { + self->objCap = 4; + self->objKeys = ((String*)Alloc(4 * sizeof(String))); + self->objValues = ((JsonValue*)Alloc(4 * sizeof(JsonValue))); + } else { + uint doubleCap = objNewCap * 2; + self->objCap = doubleCap; + self->objKeys = ((String*)Realloc(((void*)self->objKeys), doubleCap * sizeof(String))); + self->objValues = ((JsonValue*)Realloc(((void*)self->objValues), doubleCap * sizeof(JsonValue))); + } + + } + + self->objKeys[self->objLen] = key; + self->objValues[self->objLen] = val; + self->objLen = self->objLen + 1; + +} + +bool Json_IsNull(JsonValue v) { + return v.tag == JsonTagNull; + +} + +bool Json_AsBool(JsonValue v) { + if (v.tag == JsonTagBool) { + return v.boolVal; + } + + return false; + +} + +float64 Json_AsNumber(JsonValue v) { + if (v.tag == JsonTagNumber) { + return v.numVal; + } + + return 0.0; + +} + +String Json_AsString(JsonValue v) { + if (v.tag == JsonTagString) { + return v.strVal; + } + + return ""; + +} + +int JsonParser_Peek(JsonParser* p) { + if (p->pos >= p->len) { + return 0; + } + + return ((int)p->src[p->pos]); + +} + +void JsonParser_Advance(JsonParser* p) { + if (p->pos < p->len) { + p->pos = p->pos + 1; + } + + +} + +void JsonParser_SkipWhitespace(JsonParser* p) { + while (true) { + int c = JsonParser_Peek(p); + if (c == 32 || c == 9 || c == 10 || c == 13) { + JsonParser_Advance(p); + } else { + return; + } + + } + +} + +bool JsonParser_Match(JsonParser* p, String expected) { + uint elen = String_Len(expected); + if (p->pos + elen > p->len) { + return false; + } + + uint i = 0; + while (i < elen) { + if (p->src[p->pos + i] != expected[i]) { + return false; + } + + i = i + 1; + } + p->pos = p->pos + elen; + return true; + +} + +String JsonParser_ParseString(JsonParser* p) { + if (JsonParser_Peek(p) != 34) { + p->error = "Expected string"; + return ""; + } + + JsonParser_Advance(p); + StringBuilder sb = StringBuilder_New(); + while (true) { + int c = JsonParser_Peek(p); + if (c == 0 || c == 34) { + break; + } + + if (c == 92) { + JsonParser_Advance(p); + int esc = JsonParser_Peek(p); + if (esc == 0) { + p->error = "Unterminated string escape"; + StringBuilder_Free(&sb); + return ""; + } + + if (esc == 110) { + StringBuilder_AppendChar(&sb, ((char8)10)); + } else { + if (esc == 116) { + StringBuilder_AppendChar(&sb, ((char8)9)); + } else { + if (esc == 114) { + StringBuilder_AppendChar(&sb, ((char8)13)); + } else { + if (esc == 98) { + StringBuilder_AppendChar(&sb, ((char8)8)); + } else { + if (esc == 102) { + StringBuilder_AppendChar(&sb, ((char8)12)); + } else { + if (esc == 34) { + StringBuilder_AppendChar(&sb, ((char8)34)); + } else { + if (esc == 92) { + StringBuilder_AppendChar(&sb, ((char8)92)); + } else { + StringBuilder_AppendChar(&sb, ((char8)92)); + StringBuilder_AppendChar(&sb, ((char8)esc)); + } + + } + + } + + } + + } + + } + + } + + JsonParser_Advance(p); + } else { + StringBuilder_AppendChar(&sb, ((char8)c)); + JsonParser_Advance(p); + } + + } + if (JsonParser_Peek(p) != 34) { + p->error = "Unterminated string"; + StringBuilder_Free(&sb); + return ""; + } + + JsonParser_Advance(p); + String result = StringBuilder_Build(&sb); + StringBuilder_Free(&sb); + return result; + +} + +JsonValue JsonParser_ParseNumber(JsonParser* p) { + uint start = p->pos; + int c0 = JsonParser_Peek(p); + if (c0 == 45) { + JsonParser_Advance(p); + } + + while (true) { + int c = JsonParser_Peek(p); + if (c >= 48 && c <= 57) { + JsonParser_Advance(p); + } else { + break; + } + + } + if (JsonParser_Peek(p) == 46) { + JsonParser_Advance(p); + while (true) { + int c = JsonParser_Peek(p); + if (c >= 48 && c <= 57) { + JsonParser_Advance(p); + } else { + break; + } + + } + } + + String numStr = String_Slice(p->src, start, p->pos - start); + float64 n = String_ToFloat(numStr); + return Json_Number(n); + +} + +JsonValue JsonParser_ParseArray(JsonParser* p) { + JsonParser_Advance(p); + JsonValue arr = Json_Array(); + JsonParser_SkipWhitespace(p); + if (JsonParser_Peek(p) == 93) { + JsonParser_Advance(p); + return arr; + } + + while (true) { + JsonParser_SkipWhitespace(p); + JsonValue val = JsonParser_ParseValue(p); + if (p->error != "") { + return Json_Null(); + } + + Json_ArrayPush(&arr, val); + JsonParser_SkipWhitespace(p); + int c = JsonParser_Peek(p); + if (c == 93) { + JsonParser_Advance(p); + return arr; + } + + if (c == 44) { + JsonParser_Advance(p); + } else { + p->error = "Expected ',' or ']' in array"; + return Json_Null(); + } + + } + +} + +JsonValue JsonParser_ParseObject(JsonParser* p) { + JsonParser_Advance(p); + JsonValue obj = Json_Object(); + JsonParser_SkipWhitespace(p); + if (JsonParser_Peek(p) == 125) { + JsonParser_Advance(p); + return obj; + } + + while (true) { + JsonParser_SkipWhitespace(p); + String key = JsonParser_ParseString(p); + if (p->error != "") { + return Json_Null(); + } + + JsonParser_SkipWhitespace(p); + if (JsonParser_Peek(p) != 58) { + p->error = "Expected ':' after object key"; + return Json_Null(); + } + + JsonParser_Advance(p); + JsonParser_SkipWhitespace(p); + JsonValue val = JsonParser_ParseValue(p); + if (p->error != "") { + return Json_Null(); + } + + Json_ObjectSet(&obj, key, val); + JsonParser_SkipWhitespace(p); + int c = JsonParser_Peek(p); + if (c == 125) { + JsonParser_Advance(p); + return obj; + } + + if (c == 44) { + JsonParser_Advance(p); + } else { + p->error = "Expected ',' or '}' in object"; + return Json_Null(); + } + + } + +} + +JsonValue JsonParser_ParseValue(JsonParser* p) { + JsonParser_SkipWhitespace(p); + int c = JsonParser_Peek(p); + if (c == 0) { + p->error = "Unexpected end of input"; + return Json_Null(); + } + + if (c == 34) { + return Json_String(JsonParser_ParseString(p)); + } + + if (c == 123) { + return JsonParser_ParseObject(p); + } + + if (c == 91) { + return JsonParser_ParseArray(p); + } + + if (c == 116) { + if (JsonParser_Match(p, "true")) { + return Json_Bool(true); + } + + p->error = "Expected 'true'"; + return Json_Null(); + } + + if (c == 102) { + if (JsonParser_Match(p, "false")) { + return Json_Bool(false); + } + + p->error = "Expected 'false'"; + return Json_Null(); + } + + if (c == 110) { + if (JsonParser_Match(p, "null")) { + return Json_Null(); + } + + p->error = "Expected 'null'"; + return Json_Null(); + } + + if (c >= 48 && c <= 57 || c == 45) { + return JsonParser_ParseNumber(p); + } + + p->error = "Unexpected character"; + return Json_Null(); + +} + +JsonValue Json_Parse(String s) { + JsonParser p = ((JsonParser){.src = s, .pos = 0, .len = String_Len(s), .error = ""}); + JsonValue result = JsonParser_ParseValue(&p); + JsonParser_SkipWhitespace(&p); + if (p.error == "" && p.pos != p.len) { + p.error = "Trailing data after JSON value"; + return Json_Null(); + } + + return result; + +} + +void Json_StringifyImpl(StringBuilder* sb, JsonValue v) { + if (v.tag == JsonTagNull) { + StringBuilder_Append(sb, "null"); + return; + } + + if (v.tag == JsonTagBool) { + if (v.boolVal) { + StringBuilder_Append(sb, "true"); + } else { + StringBuilder_Append(sb, "false"); + } + + return; + } + + if (v.tag == JsonTagNumber) { + StringBuilder_AppendFloat(sb, v.numVal); + return; + } + + if (v.tag == JsonTagString) { + StringBuilder_AppendChar(sb, ((char8)34)); + StringBuilder_Append(sb, v.strVal); + StringBuilder_AppendChar(sb, ((char8)34)); + return; + } + + if (v.tag == JsonTagArray) { + StringBuilder_AppendChar(sb, ((char8)91)); + uint i = 0; + while (i < v.arrLen) { + if (i > 0) { + StringBuilder_AppendChar(sb, ((char8)44)); + } + + Json_StringifyImpl(sb, v.arrData[i]); + i = i + 1; + } + StringBuilder_AppendChar(sb, ((char8)93)); + return; + } + + if (v.tag == JsonTagObject) { + StringBuilder_AppendChar(sb, ((char8)123)); + uint i = 0; + while (i < v.objLen) { + if (i > 0) { + StringBuilder_AppendChar(sb, ((char8)44)); + } + + StringBuilder_AppendChar(sb, ((char8)34)); + StringBuilder_Append(sb, v.objKeys[i]); + StringBuilder_AppendChar(sb, ((char8)34)); + StringBuilder_AppendChar(sb, ((char8)58)); + Json_StringifyImpl(sb, v.objValues[i]); + i = i + 1; + } + StringBuilder_AppendChar(sb, ((char8)125)); + return; + } + + +} + +String Json_Stringify(JsonValue v) { + StringBuilder sb = StringBuilder_New(); + Json_StringifyImpl(&sb, v); + return StringBuilder_Build(&sb); + +} + +String Hash_Sha1(String data) { + int len = ((int)String_Len(data)); + void* buf = Alloc(20); + bux_sha1(data, len, buf); + String result = bux_bytes_to_hex(buf, 20); + Free(buf); + return result; + +} + +String Hash_Sha256(String data) { + int len = ((int)String_Len(data)); + void* buf = Alloc(32); + bux_sha256(data, len, buf); + String result = bux_bytes_to_hex(buf, 32); + Free(buf); + return result; + +} + +String Hash_Sha384(String data) { + int len = ((int)String_Len(data)); + void* buf = Alloc(48); + bux_sha384(data, len, buf); + String result = bux_bytes_to_hex(buf, 48); + Free(buf); + return result; + +} + +String Hash_Sha512(String data) { + int len = ((int)String_Len(data)); + void* buf = Alloc(64); + bux_sha512(data, len, buf); + String result = bux_bytes_to_hex(buf, 64); + Free(buf); + return result; + +} + +void Hash_Sha256Raw(String data, void* out) { + bux_sha256(data, ((int)String_Len(data)), out); + +} + +void Hash_Sha384Raw(String data, void* out) { + bux_sha384(data, ((int)String_Len(data)), out); + +} + +void Hash_Sha512Raw(String data, void* out) { + bux_sha512(data, ((int)String_Len(data)), out); + +} + +int Hash_Sha1Size() { + return 20; + +} + +int Hash_Sha256Size() { + return 32; + +} + +int Hash_Sha384Size() { + return 48; + +} + +int Hash_Sha512Size() { + return 64; + +} + +String Base64_Encode(String s) { + return bux_base64_encode(s, ((int)String_Len(s))); + +} + +String Base64_Decode(String s) { + int outlen = 0; + return bux_base64_decode(s, ((int)String_Len(s)), &outlen); + +} + +String Base64URL_Encode(String s) { + return bux_base64url_encode(s, ((int)String_Len(s))); + +} + +String Base64URL_Decode(String s) { + int outlen = 0; + return bux_base64url_decode(s, ((int)String_Len(s)), &outlen); + +} + +String Hmac_Sha256(String key, String message) { + int kl = ((int)String_Len(key)); + int ml = ((int)String_Len(message)); + void* buf = Alloc(32); + bux_hmac_sha256(key, kl, message, ml, buf); + String result = bux_bytes_to_hex(buf, 32); + Free(buf); + return result; + +} + +void Hmac_Sha256Raw(String key, String message, void* out) { + bux_hmac_sha256(key, ((int)String_Len(key)), message, ((int)String_Len(message)), out); + +} + +String Hmac_Sha256Base64(String key, String message) { + int kl = ((int)String_Len(key)); + int ml = ((int)String_Len(message)); + void* buf = Alloc(32); + bux_hmac_sha256(key, kl, message, ml, buf); + String result = bux_base64_encode(((String)buf), 32); + Free(buf); + return result; + +} + +String Hmac_Sha384(String key, String message) { + int kl = ((int)String_Len(key)); + int ml = ((int)String_Len(message)); + void* buf = Alloc(48); + bux_hmac_sha384(key, kl, message, ml, buf); + String result = bux_bytes_to_hex(buf, 48); + Free(buf); + return result; + +} + +void Hmac_Sha384Raw(String key, String message, void* out) { + bux_hmac_sha384(key, ((int)String_Len(key)), message, ((int)String_Len(message)), out); + +} + +String Hmac_Sha384Base64(String key, String message) { + int kl = ((int)String_Len(key)); + int ml = ((int)String_Len(message)); + void* buf = Alloc(48); + bux_hmac_sha384(key, kl, message, ml, buf); + String result = bux_base64_encode(((String)buf), 48); + Free(buf); + return result; + +} + +String Hmac_Sha512(String key, String message) { + int kl = ((int)String_Len(key)); + int ml = ((int)String_Len(message)); + void* buf = Alloc(64); + bux_hmac_sha512(key, kl, message, ml, buf); + String result = bux_bytes_to_hex(buf, 64); + Free(buf); + return result; + +} + +void Hmac_Sha512Raw(String key, String message, void* out) { + bux_hmac_sha512(key, ((int)String_Len(key)), message, ((int)String_Len(message)), out); + +} + +String Hmac_Sha512Base64(String key, String message) { + int kl = ((int)String_Len(key)); + int ml = ((int)String_Len(message)); + void* buf = Alloc(64); + bux_hmac_sha512(key, kl, message, ml, buf); + String result = bux_base64_encode(((String)buf), 64); + Free(buf); + return result; + +} + +String Random_Bytes(int n) { + if (n <= 0) { + return ""; + } + + void* buf = Alloc(((uint)n)); + if (bux_random_bytes(buf, n) != 1) { + Free(buf); + return ""; + } + + return ((String)buf); + +} + +String Random_Hex(int n) { + if (n <= 0) { + return ""; + } + + void* buf = Alloc(((uint)n)); + if (bux_random_bytes(buf, n) != 1) { + Free(buf); + return ""; + } + + String result = bux_bytes_to_hex(buf, n); + Free(buf); + return result; + +} + +String Random_Base64(int n) { + if (n <= 0) { + return ""; + } + + void* buf = Alloc(((uint)n)); + if (bux_random_bytes(buf, n) != 1) { + Free(buf); + return ""; + } + + String result = bux_base64_encode(((String)buf), n); + Free(buf); + return result; + +} + +uint Random_Uint32() { + void* buf = Alloc(4); + if (bux_random_bytes(buf, 4) != 1) { + Free(buf); + return 0; + } + + uint* ptr = ((uint*)buf); + uint val = *ptr; + Free(buf); + return val; + +} + +String Aes_GenerateKey() { + void* buf = Alloc(((uint)AES_KEY_SIZE)); + if (bux_random_bytes(buf, AES_KEY_SIZE) != 1) { + Free(buf); + return ""; + } + + return ((String)buf); + +} + +String Aes_GenerateIV() { + void* buf = Alloc(((uint)AES_IV_SIZE)); + if (bux_random_bytes(buf, AES_IV_SIZE) != 1) { + Free(buf); + return ""; + } + + return ((String)buf); + +} + +String Aes_CbcEncrypt(String plain, String key, String iv) { + int outlen = 0; + return bux_aes_256_cbc_encrypt(plain, ((int)String_Len(plain)), key, iv, &outlen); + +} + +String Aes_CbcDecrypt(String cipher, String key, String iv) { + int outlen = 0; + return bux_aes_256_cbc_decrypt(cipher, ((int)String_Len(cipher)), key, iv, &outlen); + +} + +String Aes_GcmEncrypt(String plain, String key, String iv, void* tag) { + int outlen = 0; + return bux_aes_256_gcm_encrypt(plain, ((int)String_Len(plain)), key, iv, tag, &outlen); + +} + +String Aes_GcmDecrypt(String cipher, String key, String iv, String tag) { + int outlen = 0; + return bux_aes_256_gcm_decrypt(cipher, ((int)String_Len(cipher)), key, iv, tag, &outlen); + +} + +String Jwt_MakeHeader(JwtAlg alg) { + if (alg.tag == JwtAlg_HS256) { + return "{\"alg\":\"HS256\",\"typ\":\"JWT\"}"; + } + + if (alg.tag == JwtAlg_HS384) { + return "{\"alg\":\"HS384\",\"typ\":\"JWT\"}"; + } + + if (alg.tag == JwtAlg_HS512) { + return "{\"alg\":\"HS512\",\"typ\":\"JWT\"}"; + } + + if (alg.tag == JwtAlg_RS256) { + return "{\"alg\":\"RS256\",\"typ\":\"JWT\"}"; + } + + if (alg.tag == JwtAlg_RS384) { + return "{\"alg\":\"RS384\",\"typ\":\"JWT\"}"; + } + + if (alg.tag == JwtAlg_RS512) { + return "{\"alg\":\"RS512\",\"typ\":\"JWT\"}"; + } + + if (alg.tag == JwtAlg_ES256) { + return "{\"alg\":\"ES256\",\"typ\":\"JWT\"}"; + } + + if (alg.tag == JwtAlg_ES384) { + return "{\"alg\":\"ES384\",\"typ\":\"JWT\"}"; + } + + if (alg.tag == JwtAlg_EdDSA) { + return "{\"alg\":\"EdDSA\",\"typ\":\"JWT\"}"; + } + + return "{\"alg\":\"none\",\"typ\":\"JWT\"}"; + +} + +String Jwt_Sign(JwtAlg alg, String signingInput, String key) { + if (alg.tag == JwtAlg_HS256) { + void* buf = Alloc(32); + Hmac_Sha256Raw(key, signingInput, buf); + String result = bux_base64_encode(((String)buf), 32); + Free(buf); + return result; + } + + if (alg.tag == JwtAlg_HS384) { + void* buf = Alloc(48); + Hmac_Sha384Raw(key, signingInput, buf); + String result = bux_base64_encode(((String)buf), 48); + Free(buf); + return result; + } + + if (alg.tag == JwtAlg_HS512) { + void* buf = Alloc(64); + Hmac_Sha512Raw(key, signingInput, buf); + String result = bux_base64_encode(((String)buf), 64); + Free(buf); + return result; + } + + if (alg.tag == JwtAlg_RS256) { + String raw = Rsa_SignSha256(key, signingInput); + return bux_base64_encode(raw, ((int)String_Len(raw))); + } + + if (alg.tag == JwtAlg_RS384) { + String raw = Rsa_SignSha384(key, signingInput); + return bux_base64_encode(raw, ((int)String_Len(raw))); + } + + if (alg.tag == JwtAlg_RS512) { + String raw = Rsa_SignSha512(key, signingInput); + return bux_base64_encode(raw, ((int)String_Len(raw))); + } + + if (alg.tag == JwtAlg_ES256) { + String raw = Ecdsa_SignP256(key, signingInput); + return bux_base64_encode(raw, ((int)String_Len(raw))); + } + + if (alg.tag == JwtAlg_ES384) { + String raw = Ecdsa_SignP384(key, signingInput); + return bux_base64_encode(raw, ((int)String_Len(raw))); + } + + if (alg.tag == JwtAlg_EdDSA) { + return Ed25519_Sign(key, signingInput); + } + + return ""; + +} + +bool Jwt_Verify(JwtAlg alg, String signingInput, String signatureB64, String key) { + if (alg.tag == JwtAlg_HS256) { + void* expectBuf = Alloc(32); + Hmac_Sha256Raw(key, signingInput, expectBuf); + String expectB64 = bux_base64_encode(((String)expectBuf), 32); + Free(expectBuf); + return String_Eq(expectB64, signatureB64); + } + + if (alg.tag == JwtAlg_HS384) { + void* expectBuf = Alloc(48); + Hmac_Sha384Raw(key, signingInput, expectBuf); + String expectB64 = bux_base64_encode(((String)expectBuf), 48); + Free(expectBuf); + return String_Eq(expectB64, signatureB64); + } + + if (alg.tag == JwtAlg_HS512) { + void* expectBuf = Alloc(64); + Hmac_Sha512Raw(key, signingInput, expectBuf); + String expectB64 = bux_base64_encode(((String)expectBuf), 64); + Free(expectBuf); + return String_Eq(expectB64, signatureB64); + } + + if (alg.tag == JwtAlg_RS256) { + return Rsa_VerifySha256(key, signingInput, signatureB64); + } + + if (alg.tag == JwtAlg_RS384) { + return Rsa_VerifySha384(key, signingInput, signatureB64); + } + + if (alg.tag == JwtAlg_RS512) { + return Rsa_VerifySha512(key, signingInput, signatureB64); + } + + if (alg.tag == JwtAlg_ES256) { + return Ecdsa_VerifyP256(key, signingInput, signatureB64); + } + + if (alg.tag == JwtAlg_ES384) { + return Ecdsa_VerifyP384(key, signingInput, signatureB64); + } + + if (alg.tag == JwtAlg_EdDSA) { + return Ed25519_Verify(key, signatureB64, signingInput); + } + + return false; + +} + +String Jwt_Encode(String headerJson, String payloadJson, JwtAlg alg, String key) { + String headerB64 = Base64URL_Encode(headerJson); + String payloadB64 = Base64URL_Encode(payloadJson); + String signingInput = String_Concat(headerB64, "."); + String signingInputFull = String_Concat(signingInput, payloadB64); + String sigB64 = Jwt_Sign(alg, signingInputFull, key); + String part1 = String_Concat(signingInputFull, "."); + return String_Concat(part1, sigB64); + +} + +bool Jwt_Decode(String token, JwtAlg alg, String key, String* headerOut, String* payloadOut) { + uint partCount = bux_str_split_count(token, "."); + if (partCount != 3) { + return false; + } + + String headerB64 = bux_str_split_part(token, ".", 0); + String payloadB64 = bux_str_split_part(token, ".", 1); + String sigB64 = bux_str_split_part(token, ".", 2); + String input = String_Concat(headerB64, "."); + String signingInput = String_Concat(input, payloadB64); + if (!Jwt_Verify(alg, signingInput, sigB64, key)) { + return false; + } + + headerOut[0] = Base64URL_Decode(headerB64); + payloadOut[0] = Base64URL_Decode(payloadB64); + return true; + +} + +String Jwt_EncodeHS256(String payloadJson, String secret) { + String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_HS256})); + return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_HS256}), secret); + +} + +String Jwt_EncodeHS384(String payloadJson, String secret) { + String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_HS384})); + return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_HS384}), secret); + +} + +String Jwt_EncodeHS512(String payloadJson, String secret) { + String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_HS512})); + return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_HS512}), secret); + +} + +String Jwt_EncodeRS256(String payloadJson, String pemPrivateKey) { + String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_RS256})); + return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_RS256}), pemPrivateKey); + +} + +String Jwt_EncodeES256(String payloadJson, String pemPrivateKey) { + String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_ES256})); + return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_ES256}), pemPrivateKey); + +} + +String Jwt_EncodeEdDSA(String payloadJson, String rawPrivKey) { + String header = Jwt_MakeHeader(((JwtAlg){.tag = JwtAlg_EdDSA})); + return Jwt_Encode(header, payloadJson, ((JwtAlg){.tag = JwtAlg_EdDSA}), rawPrivKey); + +} + +String Ecdsa_SignP256(String pemPrivateKey, String data) { + int siglen = 0; + return bux_ecdsa_sign_p256(pemPrivateKey, ((int)String_Len(pemPrivateKey)), data, ((int)String_Len(data)), &siglen); + +} + +String Ecdsa_SignP256Base64(String pemPrivateKey, String data) { + String raw = Ecdsa_SignP256(pemPrivateKey, data); + return bux_base64_encode(raw, ((int)String_Len(raw))); + +} + +bool Ecdsa_VerifyP256(String pemPublicKey, String data, String signature) { + int r = bux_ecdsa_verify_p256(pemPublicKey, ((int)String_Len(pemPublicKey)), data, ((int)String_Len(data)), signature, ((int)String_Len(signature))); + return r == 1; + +} + +bool Ecdsa_VerifyP256Base64(String pemPublicKey, String data, String signatureB64) { + int outlen = 0; + String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen); + return Ecdsa_VerifyP256(pemPublicKey, data, sig); + +} + +String Ecdsa_SignP384(String pemPrivateKey, String data) { + int siglen = 0; + return bux_ecdsa_sign_p384(pemPrivateKey, ((int)String_Len(pemPrivateKey)), data, ((int)String_Len(data)), &siglen); + +} + +String Ecdsa_SignP384Base64(String pemPrivateKey, String data) { + String raw = Ecdsa_SignP384(pemPrivateKey, data); + return bux_base64_encode(raw, ((int)String_Len(raw))); + +} + +bool Ecdsa_VerifyP384(String pemPublicKey, String data, String signature) { + int r = bux_ecdsa_verify_p384(pemPublicKey, ((int)String_Len(pemPublicKey)), data, ((int)String_Len(data)), signature, ((int)String_Len(signature))); + return r == 1; + +} + +bool Ecdsa_VerifyP384Base64(String pemPublicKey, String data, String signatureB64) { + int outlen = 0; + String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen); + return Ecdsa_VerifyP384(pemPublicKey, data, sig); + +} + +bool Ed25519_Keypair(void* pubKey, void* privKey) { + int r = bux_ed25519_keypair(pubKey, privKey); + return r == 1; + +} + +String Ed25519_KeypairBase64() { + void* pubBuf = Alloc(((uint)ED25519_PUBKEY_SIZE)); + void* priv = Alloc(((uint)ED25519_PRIVKEY_SIZE)); + if (bux_ed25519_keypair(pubBuf, priv) != 1) { + Free(pubBuf); + Free(priv); + return ""; + } + + String pubB64 = bux_base64_encode(((String)pubBuf), ED25519_PUBKEY_SIZE); + String privB64 = bux_base64_encode(((String)priv), ED25519_PRIVKEY_SIZE); + Free(pubBuf); + Free(priv); + String pair = String_Concat(pubB64, ":"); + return String_Concat(pair, privB64); + +} + +String Ed25519_Sign(String privKey, String data) { + void* sig = Alloc(((uint)ED25519_SIG_SIZE)); + if (bux_ed25519_sign(privKey, data, ((int)String_Len(data)), sig) != 1) { + Free(sig); + return ""; + } + + return ((String)sig); + +} + +String Ed25519_SignBase64(String privKey, String data) { + String sig = Ed25519_Sign(privKey, data); + if (String_Len(sig) == 0) { + return ""; + } + + return bux_base64_encode(sig, ED25519_SIG_SIZE); + +} + +bool Ed25519_Verify(String pubKey, String signature, String data) { + int r = bux_ed25519_verify(pubKey, signature, data, ((int)String_Len(data))); + return r == 1; + +} + +bool Ed25519_VerifyBase64(String pubKey, String signatureB64, String data) { + int outlen = 0; + String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen); + if (outlen != ED25519_SIG_SIZE) { + return false; + } + + return Ed25519_Verify(pubKey, sig, data); + +} + +String Rsa_SignSha256(String pemPrivateKey, String data) { + int siglen = 0; + return bux_rsa_sign_sha256(pemPrivateKey, ((int)String_Len(pemPrivateKey)), data, ((int)String_Len(data)), &siglen); + +} + +String Rsa_SignSha384(String pemPrivateKey, String data) { + int siglen = 0; + return bux_rsa_sign_sha384(pemPrivateKey, ((int)String_Len(pemPrivateKey)), data, ((int)String_Len(data)), &siglen); + +} + +String Rsa_SignSha512(String pemPrivateKey, String data) { + int siglen = 0; + return bux_rsa_sign_sha512(pemPrivateKey, ((int)String_Len(pemPrivateKey)), data, ((int)String_Len(data)), &siglen); + +} + +String Rsa_SignSha256Base64(String pemPrivateKey, String data) { + String raw = Rsa_SignSha256(pemPrivateKey, data); + return bux_base64_encode(raw, ((int)String_Len(raw))); + +} + +String Rsa_SignSha384Base64(String pemPrivateKey, String data) { + String raw = Rsa_SignSha384(pemPrivateKey, data); + return bux_base64_encode(raw, ((int)String_Len(raw))); + +} + +String Rsa_SignSha512Base64(String pemPrivateKey, String data) { + String raw = Rsa_SignSha512(pemPrivateKey, data); + return bux_base64_encode(raw, ((int)String_Len(raw))); + +} + +bool Rsa_VerifySha256(String pemPublicKey, String data, String signature) { + int r = bux_rsa_verify_sha256(pemPublicKey, ((int)String_Len(pemPublicKey)), data, ((int)String_Len(data)), signature, ((int)String_Len(signature))); + return r == 1; + +} + +bool Rsa_VerifySha384(String pemPublicKey, String data, String signature) { + int r = bux_rsa_verify_sha384(pemPublicKey, ((int)String_Len(pemPublicKey)), data, ((int)String_Len(data)), signature, ((int)String_Len(signature))); + return r == 1; + +} + +bool Rsa_VerifySha512(String pemPublicKey, String data, String signature) { + int r = bux_rsa_verify_sha512(pemPublicKey, ((int)String_Len(pemPublicKey)), data, ((int)String_Len(data)), signature, ((int)String_Len(signature))); + return r == 1; + +} + +bool Rsa_VerifySha256Base64(String pemPublicKey, String data, String signatureB64) { + int outlen = 0; + String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen); + return Rsa_VerifySha256(pemPublicKey, data, sig); + +} + +bool Rsa_VerifySha384Base64(String pemPublicKey, String data, String signatureB64) { + int outlen = 0; + String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen); + return Rsa_VerifySha384(pemPublicKey, data, sig); + +} + +bool Rsa_VerifySha512Base64(String pemPublicKey, String data, String signatureB64) { + int outlen = 0; + String sig = bux_base64_decode(signatureB64, ((int)String_Len(signatureB64)), &outlen); + return Rsa_VerifySha512(pemPublicKey, data, sig); + +} + +uint String_Len(String s) { + return bux_strlen(s); + +} + +bool String_IsNull(String s) { + return bux_str_is_null(s) != 0; + +} + +bool String_Eq(String a, String b) { + return bux_strcmp(a, b) == 0; + +} + +String String_Concat(String a, String b) { + uint len_a = bux_strlen(a); + uint len_b = bux_strlen(b); + uint total = len_a + len_b + 1; + char8* buf = ((char8*)bux_alloc(total)); + bux_strcpy(buf, a); + bux_strcat(buf, b); + return buf; + +} + +String String_Copy(String s) { + uint len = bux_strlen(s); + char8* buf = ((char8*)bux_alloc(len + 1)); + bux_strcpy(buf, s); + return buf; + +} + +bool String_StartsWith(String s, String prefix) { + uint s_len = bux_strlen(s); + uint p_len = bux_strlen(prefix); + if (p_len > s_len) { + return false; + } + + int r = bux_strncmp(s, prefix, p_len); + return r == 0; + +} + +bool String_EndsWith(String s, String suffix) { + uint s_len = bux_strlen(s); + uint suf_len = bux_strlen(suffix); + if (suf_len > s_len) { + return false; + } + + uint start = s_len - suf_len; + String tail = bux_str_slice(s, start, suf_len); + bool eq = bux_strcmp(tail, suffix) == 0; + return eq; + +} + +bool String_Contains(String s, String substr) { + int r = bux_str_contains(s, substr); + return r != 0; + +} + +String String_Slice(String s, uint start, uint len) { + return bux_str_slice(s, start, len); + +} + +String String_Trim(String s) { + return bux_str_trim(s); + +} + +String String_TrimLeft(String s) { + return bux_str_trim_left(s); + +} + +String String_TrimRight(String s) { + return bux_str_trim_right(s); + +} + +String String_FromInt(int64 n) { + return bux_int_to_str(n); + +} + +int64 String_ToInt(String s) { + return bux_str_to_int(s); + +} + +StringBuilder StringBuilder_New() { + return ((StringBuilder){.handle = bux_sb_new(64)}); + +} + +StringBuilder StringBuilder_NewCap(uint cap) { + return ((StringBuilder){.handle = bux_sb_new(cap)}); + +} + +void StringBuilder_Append(StringBuilder* sb, String s) { + bux_sb_append(sb->handle, s); + +} + +void StringBuilder_AppendInt(StringBuilder* sb, int64 n) { + bux_sb_append_int(sb->handle, n); + +} + +void StringBuilder_AppendFloat(StringBuilder* sb, float64 f) { + bux_sb_append_float(sb->handle, f); + +} + +void StringBuilder_AppendChar(StringBuilder* sb, char8 c) { + bux_sb_append_char(sb->handle, c); + +} + +String StringBuilder_Build(StringBuilder* sb) { + return bux_sb_build(sb->handle); + +} + +void StringBuilder_Free(StringBuilder* sb) { + bux_sb_free(sb->handle); + +} + +uint String_SplitCount(String s, String delim) { + return bux_str_split_count(s, delim); + +} + +String String_SplitPart(String s, String delim, uint index) { + return bux_str_split_part(s, delim, index); + +} + +String String_Join2(String a, String b, String sep) { + return bux_str_join2(a, b, sep); + +} + +String String_Chars(String s, uint index) { + return bux_str_slice(s, index, 1); + +} + +String String_Find(String haystack, String needle) { + return bux_strstr(haystack, needle); + +} + +uint String_Offset(String pos, String base) { + return bux_str_offset(pos, base); + +} + +String String_Replace(String s, String old, String new) { + String pos = bux_strstr(s, old); + if (String_IsNull(pos)) { + return s; + } + + uint oldLen = bux_strlen(old); + uint prefixLen = String_Offset(pos, s); + String prefix = bux_str_slice(s, 0, prefixLen); + String suffix = bux_str_slice(s, prefixLen + oldLen, bux_strlen(s) - prefixLen - oldLen); + String temp = String_Concat(prefix, new); + String result = String_Concat(temp, suffix); + return result; + +} + +float64 String_ToFloat(String s) { + return bux_str_to_float(s); + +} + +String String_FromBool(bool b) { + if (b) { + return "true"; + } + + return "false"; + +} + +String String_FromFloat(float64 f) { + return bux_float_to_string(f); + +} + +String String_Format1(String pattern, String a0) { + return bux_str_format(pattern, a0, "", "", "", "", "", "", ""); + +} + +String String_Format2(String pattern, String a0, String a1) { + return bux_str_format(pattern, a0, a1, "", "", "", "", "", ""); + +} + +String String_Format3(String pattern, String a0, String a1, String a2) { + return bux_str_format(pattern, a0, a1, a2, "", "", "", "", ""); + +} + +void Channel_SendInt(Channel_int* ch, int value) { + bux_channel_send(ch->handle, ((void*)&value)); + +} + +int Channel_RecvInt(Channel_int* ch) { + int result = 0; + bux_channel_recv(ch->handle, ((void*)&result)); + return result; + +} + +void Channel_SendFloat64(Channel_float64* ch, float64 value) { + bux_channel_send(ch->handle, ((void*)&value)); + +} + +float64 Channel_RecvFloat64(Channel_float64* ch) { + float64 result = 0.0; + bux_channel_recv(ch->handle, ((void*)&result)); + return result; + +} + +int Main() { + int x = "hello"; + return 0; + +} + +extern int g_argc; +extern char** g_argv; +int main(int argc, char** argv) { + g_argc = argc; + g_argv = argv; + return Main(); +} diff --git a/_test_error_snippet/bux.toml b/_test_error_snippet/bux.toml new file mode 100644 index 0000000..2189898 --- /dev/null +++ b/_test_error_snippet/bux.toml @@ -0,0 +1,4 @@ +[package] +name = "error_snippet_test" +version = "0.1.0" +pkgType = "bin" diff --git a/_test_error_snippet/src/Main.bux b/_test_error_snippet/src/Main.bux new file mode 100644 index 0000000..230e215 --- /dev/null +++ b/_test_error_snippet/src/Main.bux @@ -0,0 +1,4 @@ +func Main() -> int { + let x: int = undefined_variable; + return 0; +}