Skip to content

Instantly share code, notes, and snippets.

@Xe

Xe/hello.c Secret

Created June 23, 2019 18:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Xe/1afdd4c7e7c9cfa23d1aa87194ee5190 to your computer and use it in GitHub Desktop.
Save Xe/1afdd4c7e7c9cfa23d1aa87194ee5190 to your computer and use it in GitHub Desktop.
// Generated by V
#define linux (1)
#include <pthread.h>
#include <stdio.h> // TODO remove all these includes, define all function signatures and types manually
#include <stdlib.h>
#include <signal.h>
#include <stdarg.h> // for va_list
#include <inttypes.h> // int64_t etc
//================================== TYPEDEFS ================================*/
typedef unsigned char byte;
typedef unsigned int uint;
typedef int64_t i64;
typedef int32_t i32;
typedef int16_t i16;
typedef int8_t i8;
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
typedef uint32_t rune;
typedef float f32;
typedef double f64;
typedef unsigned char* byteptr;
typedef int* intptr;
typedef void* voidptr;
typedef struct array array;
typedef struct map map;
typedef array array_string;
typedef array array_int;
typedef array array_byte;
typedef array array_uint;
typedef array array_float;
typedef map map_int;
typedef map map_string;
#ifndef bool
typedef int bool;
#define true 1
#define false 0
#endif
//============================== HELPER C MACROS =============================*/
#define _PUSH(arr, val, tmp, tmp_typ) {tmp_typ tmp = (val); array__push(arr, &tmp);}
#define _IN(typ, val, arr) array_##typ##_contains(arr, val)
#define ALLOC_INIT(type, ...) (type *)memdup((type[]){ __VA_ARGS__ }, sizeof(type))
#define UTF8_CHAR_LEN( byte ) (( 0xE5000000 >> (( byte >> 3 ) & 0x1e )) & 3 ) + 1
//================================== GLOBALS =================================*/
//int V_ZERO = 0;
byteptr g_str_buf;
int load_so(byteptr);
void reload_so();
void init_consts();
i64 total_m = 0; // For counting total RAM allocated
int g_test_ok = 1;
/*================================== FNS =================================*/
typedef struct array array;
typedef array array_int;
typedef array array_string;
typedef struct string string;
typedef struct ustring ustring;
typedef array array_byte;
typedef struct map map;
typedef array array_Entry;
typedef struct Entry Entry;
typedef struct Entry2 Entry2;
typedef struct smap smap;
typedef array array_Entry2;
typedef struct Option Option;
typedef struct StringBuilder StringBuilder;
struct array {
void* data;
int len;
int cap;
int element_size;
};
struct string {
byte* str;
int len;
};
struct ustring {
string s;
array_int runes;
int len;
};
struct map {
int element_size;
array_Entry entries;
bool is_sorted;
};
struct Entry {
string key;
void* val;
};
struct Entry2 {
string key;
string val;
};
struct smap {
array_Entry2 entries;
bool is_sorted;
};
struct Option {
void* data;
string error;
bool ok;
};
struct StringBuilder {
array_byte buf;
int len;
};
string _STR(const char*, ...);
string _STR_TMP(const char*, ...);
array new_array(int mylen, int cap, int elm_size);
array new_array_from_c_array(int len, int cap, int elm_size, void* c_array);
array new_array_from_c_array_no_alloc(int len, int cap, int elm_size, void* c_array);
array array_repeat(void* val, int nr_repeats, int elm_size);
void array_append_array(array* a, array b);
void array_sort_with_compare(array* a, void* compare);
void array_insert(array* a, int i, void* val);
void array_prepend(array* a, void* val);
void array_delete(array* a, int idx);
void* array__get(array a, int i);
void* array_first(array a);
void* array_last(array a);
array array_left(array s, int n);
array array_right(array s, int n);
array array_slice(array s, int start, int _end);
void array_set(array* a, int idx, void* val);
void array__push(array* arr, void* val);
void array__push_many(array* arr, void* val, int size);
string array_int_str(array_int a);
void v_array_int_free(array_int a);
string array_string_str(array_string a);
void v_free(void* a);
string tos_clone(byte* s);
string tos2(byte* s);
string tos_no_len(byte* s);
string string_clone(string a);
byte* string_cstr(string s);
string string_replace(string s, string rep, string with);
int string_to_i(string s);
float string_to_float(string s);
bool string_eq(string s, string a);
bool string_ne(string s, string a);
bool string_ge(string s, string a);
bool string_le(string s, string a);
bool string_lt(string s, string a);
bool string_gt(string s, string a);
string string_add(string s, string a);
array_string string_split(string s, string delim);
array_string string_split_single(string s, byte delim);
array_string string_split_into_lines(string s);
string string_left(string s, int n);
string string_right(string s, int n);
string string_substr(string s, int start, int end);
int string_index(string s, string p);
int string_last_index(string s, string p);
int string_index_after(string s, string p, int start);
bool string_contains(string s, string p);
bool string_starts_with(string s, string p);
bool string_ends_with(string s, string p);
string string_to_lower(string s);
string string_to_upper(string s);
string string_find_between(string s, string start, string end);
bool array_string_contains(array_string ar, string val);
bool array_int_contains(array_int ar, int val);
void* array_string_to_c(array_string a);
bool is_space(byte c);
bool byte_is_space(byte c);
string string_trim_space(string s);
string string_trim(string s, byte c);
string string_trim_left(string s, string cutset);
string string_trim_right(string s, string cutset);
int compare_strings(string* a, string* b);
int compare_strings_by_len(string* a, string* b);
int compare_lower_strings(string* a, string* b);
void array_string_sort(array_string* s);
void array_string_sort_ignore_case(array_string* s);
void array_string_sort_by_len(array_string* s);
ustring string_ustring(string s);
ustring string_ustring_tmp(string s);
string ustring_substr(ustring u, int start, int end);
string ustring_left(ustring u, int pos);
string ustring_right(ustring u, int pos);
byte string_at(string s, int idx);
string ustring_at(ustring u, int idx);
void v_ustring_free(ustring u);
int abs(int a);
bool byte_is_digit(byte c);
bool byte_is_letter(byte c);
void v_string_free(string s);
void v_array_string_free(array_string arr);
string string_all_before(string s, string dot);
string string_all_before_last(string s, string dot);
string string_all_after(string s, string dot);
string array_string_join(array_string a, string del);
string array_string_join_lines(array_string s);
string string_limit(string s, int max);
bool byte_is_white(byte c);
string repeat_char(byte c, int n);
int string_hash(string s);
void v_exit(int code);
bool isnil(void* v);
void on_panic(int (*f)( int /*FFF*/ ));
void print_backtrace();
void v_panic(string s);
void println(string s);
void eprintln(string s);
void v_print(string s);
byte* v_malloc(int n);
byte* v_calloc(int n);
int _strlen(byte* s);
Option opt_ok(void* data);
void* memdup(void* src, int sz);
Option v_error(string s);
array_int range_int(int start, int end);
string double_str(double d);
string float_str(float d);
string f64_str(f64 d);
string f32_str(f32 d);
string ptr_str(void* ptr);
string int_str(int nn);
string u8_str(u8 nn);
string i64_str(i64 nn);
string bool_str(bool b);
string int_hex(int n);
string i64_hex(i64 n);
bool array_byte_contains(array_byte a, byte val);
string byte_str(byte c);
int string_is_utf8(string s);
string utf32_to_str(u32 code);
string utf32_to_str_no_malloc(u32 code, void* buf);
int string_utf32_code(string _rune);
map new_map(int cap, int elm_size);
Entry map_new_entry(map* m, string key, void* val);
void map__set(map* m, string key, void* val);
int volt_abs(int n);
void map_bs(map m, string query, int start, int end, void* out);
int compare_map(Entry* a, Entry* b);
void map_sort(map* m);
bool map_get(map m, string key, void* out);
void v_map_print(map m);
void v_map_free(map m);
string map_string_str(map_string m);
smap new_smap();
void smap_set(smap* m, string key, string val);
string smap_get(smap m, string key);
string smap_bs(smap m, string query, int start, int end);
int compare_smap(Entry2* a, Entry2* b);
void smap_sort(smap* m);
void v_smap_free(smap m);
string smap_str(smap m);
StringBuilder new_string_builder(int initial_size);
void StringBuilder_write(StringBuilder* b, string s);
void StringBuilder_writeln(StringBuilder* b, string s);
string StringBuilder_str(StringBuilder b);
void StringBuilder_cut(StringBuilder b, int n);
array new_array(int mylen, int cap, int elm_size) {
array arr= (array){ .len = mylen , .cap = cap , .element_size = elm_size , .data = v_malloc ( cap * elm_size ) } ;
return arr ;
}
array new_array_from_c_array(int len, int cap, int elm_size, void* c_array) {
array arr= (array){ .len = len , .cap = cap , .element_size = elm_size , .data = v_malloc ( cap * elm_size ) } ;
memcpy ( arr .data , c_array , len * elm_size ) ;
return arr ;
}
array new_array_from_c_array_no_alloc(int len, int cap, int elm_size, void* c_array) {
array arr= (array){ .len = len , .cap = cap , .element_size = elm_size , .data = c_array } ;
return arr ;
}
array array_repeat(void* val, int nr_repeats, int elm_size) {
array arr= (array){ .len = nr_repeats , .cap = nr_repeats , .element_size = elm_size , .data = v_malloc ( nr_repeats * elm_size ) } ;
for (
int i= 0 ; i < nr_repeats ; i ++ ) {
memcpy ( arr .data + i * elm_size , val , elm_size ) ;
}
;
return arr ;
}
void array_append_array(array* a, array b) {
for (
int i= 0 ; i < b .len ; i ++ ) {
void* val= ( *(void**) array__get( b , i) ) ;
array__push( a , val ) ;
}
;
}
void array_sort_with_compare(array* a, void* compare) {
qsort ( a ->data , a ->len , a ->element_size , compare ) ;
}
void array_insert(array* a, int i, void* val) {
if ( i >= a ->len ) {
/*if*/
v_panic ( tos2("array.insert: index larger than length") ) ;
return ;
}
;
array__push( a , val ) ;
int size= a ->element_size ;
memmove ( a ->data + (/*lpar*/ i + 1 ) * size , a ->data + i * size , (/*lpar*/ a ->len - i ) * size ) ;
array_set( a , i , val ) ;
}
void array_prepend(array* a, void* val) {
array_insert( a , 0 , val ) ;
}
void array_delete(array* a, int idx) {
int size= a ->element_size ;
memmove ( a ->data + idx * size , a ->data + (/*lpar*/ idx + 1 ) * size , (/*lpar*/ a ->len - idx ) * size ) ;
a ->len -- ;
a ->cap -- ;
}
void* array__get(array a, int i) {
if ( i < 0 || i >= a .len ) {
/*if*/
v_panic ( _STR("array index out of range: %d/%d", i, a .len) ) ;
}
;
return a .data + i * a .element_size ;
}
void* array_first(array a) {
if ( a .len == 0 ) {
/*if*/
v_panic ( tos2("array.first: empty array") ) ;
}
;
return a .data + 0 ;
}
void* array_last(array a) {
if ( a .len == 0 ) {
/*if*/
v_panic ( tos2("array.last: empty array") ) ;
}
;
return a .data + (/*lpar*/ a .len - 1 ) * a .element_size ;
}
array array_left(array s, int n) {
if ( n >= s .len ) {
/*if*/
return s ;
}
;
return array_slice( s , 0 , n ) ;
}
array array_right(array s, int n) {
if ( n >= s .len ) {
/*if*/
return s ;
}
;
return array_slice( s , n , s .len ) ;
}
array array_slice(array s, int start, int _end) {
int end= _end ;
if ( start > end ) {
/*if*/
v_panic ( _STR("invalid slice index: %d > %d", start, end) ) ;
}
;
if ( end >= s .len ) {
/*if*/
end = s .len ;
}
;
int l= end - start ;
array res= (array){ .element_size = s .element_size , .data = s .data + start * s .element_size , .len = l , .cap = l } ;
return res ;
}
void array_set(array* a, int idx, void* val) {
if ( idx < 0 || idx >= a ->len ) {
/*if*/
v_panic ( _STR("array index out of range: %d / %d", idx, a ->len) ) ;
}
;
memcpy ( a ->data + a ->element_size * idx , val , a ->element_size ) ;
}
void array__push(array* arr, void* val) {
if ( arr ->len >= arr ->cap - 1 ) {
/*if*/
int cap= (/*lpar*/ arr ->len + 1 ) * 2 ;
if ( arr ->cap == 0 ) {
/*if*/
arr ->data = v_malloc ( cap * arr ->element_size ) ;
}
else {
/*else if*/
arr ->data = realloc ( arr ->data , cap * arr ->element_size ) ;
}
;
arr ->cap = cap ;
}
;
memcpy ( arr ->data + arr ->element_size * arr ->len , val , arr ->element_size ) ;
arr ->len ++ ;
}
void array__push_many(array* arr, void* val, int size) {
if ( arr ->len >= arr ->cap - size ) {
/*if*/
int cap= (/*lpar*/ arr ->len + size ) * 2 ;
if ( arr ->cap == 0 ) {
/*if*/
arr ->data = v_malloc ( cap * arr ->element_size ) ;
}
else {
/*else if*/
arr ->data = realloc ( arr ->data , cap * arr ->element_size ) ;
}
;
arr ->cap = cap ;
}
;
memcpy ( arr ->data + arr ->element_size * arr ->len , val , arr ->element_size * size ) ;
arr ->len += size ;
}
string array_int_str(array_int a) {
string res= tos2("[") ;
for (
int i= 0 ; i < a .len ; i ++ ) {
int val= ( *(int*) array__get( a , i) ) ;
res = string_add(res, _STR("%d", val) ) ;
if ( i < a .len - 1 ) {
/*if*/
res = string_add(res, tos2(", ") ) ;
}
;
}
;
res = string_add(res, tos2("]") ) ;
return res ;
}
void v_array_int_free(array_int a) {
free ( a .data ) ;
}
string array_string_str(array_string a) {
string res= tos2("[") ;
for (
int i= 0 ; i < a .len ; i ++ ) {
string val= ( *(string*) array__get( a , i) ) ;
res = string_add(res, _STR("\"%.*s\"", val.len, val.str) ) ;
if ( i < a .len - 1 ) {
/*if*/
res = string_add(res, tos2(", ") ) ;
}
;
}
;
res = string_add(res, tos2("]") ) ;
return res ;
}
void v_free(void* a) {
free ( a ) ;
}
string tos(byte* s, int len) {
if ( isnil ( s ) ) {
/*if*/
v_panic ( tos2("tos(): nil string") ) ;
}
;
return (string){ .str = s , .len = len } ;
}
string tos_clone(byte* s) {
if ( isnil ( s ) ) {
/*if*/
v_panic ( tos2("tos: nil string") ) ;
return (string){ .str = 0 , .len = 0 } ;
}
;
int len= strlen ( s ) ;
string res= tos ( s , len ) ;
return string_clone( res ) ;
}
string tos2(byte* s) {
if ( isnil ( s ) ) {
/*if*/
v_panic ( tos2("tos2: nil string") ) ;
return (string){ .str = 0 , .len = 0 } ;
}
;
int len= strlen ( s ) ;
string res= tos ( s , len ) ;
return res ;
}
string tos_no_len(byte* s) {
return tos2 ( s ) ;
}
string string_clone(string a) {
string b= (string){ .len = a .len , .str = v_malloc ( a .len + 1 ) } ;
for (
int i= 0 ; i < a .len ; i ++ ) {
b .str[ i ]/*rbyte 1*/ = a .str[ i ]/*rbyte 0*/ ;
}
;
b .str[ a .len ]/*rbyte 1*/ = '\0' ;
return b ;
}
byte* string_cstr(string s) {
string clone= string_clone( s ) ;
return clone .str ;
}
string string_replace(string s, string rep, string with) {
if ( s .len == 0 || rep .len == 0 ) {
/*if*/
return tos2("") ;
}
;
if ( ! string_contains( s , rep ) ) {
/*if*/
return s ;
}
;
array_int idxs=new_array_from_c_array(0, 0, sizeof(int), (int[]) { }) ;
{
}
for (
int i= 0 ; i < s .len ; i ++ ) {
int rep_i= 0 ;
int j= i ;
while ( rep_i < rep .len && j < s .len && s .str[ j ]/*rbyte 0*/ == rep .str[ rep_i ]/*rbyte 0*/ ) {
rep_i ++ ;
j ++ ;
}
;
if ( rep_i == rep .len ) {
/*if*/
_PUSH(& idxs , ( i ), tmp12, int) ;
}
;
}
;
if ( idxs .len == 0 ) {
/*if*/
return s ;
}
;
int new_len= s .len + idxs .len * (/*lpar*/ with .len - rep .len ) ;
byte* b= v_malloc ( new_len + 1 ) ;
int idx_pos= 0 ;
int cur_idx= ( *(int*) array__get( idxs , idx_pos) ) ;
int b_i= 0 ;
for (
int i= 0 ; i < s .len ; i ++ ) {
if ( i == cur_idx ) {
/*if*/
for (
int j= 0 ; j < with .len ; j ++ ) {
b [/*ptr*/ b_i ]/*rbyte 1*/ = with .str[ j ]/*rbyte 0*/ ;
b_i ++ ;
}
;
i += rep .len - 1 ;
idx_pos ++ ;
if ( idx_pos < idxs .len ) {
/*if*/
cur_idx = ( *(int*) array__get( idxs , idx_pos) ) ;
}
;
}
else {
/*else if*/
b [/*ptr*/ b_i ]/*rbyte 1*/ = s .str[ i ]/*rbyte 0*/ ;
b_i ++ ;
}
;
}
;
b [/*ptr*/ new_len ]/*rbyte 1*/ = '\0' ;
return tos ( b , new_len ) ;
}
int string_to_i(string s) {
return atoi ( s .str ) ;
}
float string_to_float(string s) {
return atof ( s .str ) ;
}
bool string_eq(string s, string a) {
if ( isnil ( s .str ) ) {
/*if*/
v_panic ( tos2("string.eq(): nil string") ) ;
}
;
if ( s .len != a .len ) {
/*if*/
return 0 ;
}
;
for (
int i= 0 ; i < s .len ; i ++ ) {
if ( s .str[ i ]/*rbyte 0*/ != a .str[ i ]/*rbyte 0*/ ) {
/*if*/
return 0 ;
}
;
}
;
return 1 ;
}
bool string_ne(string s, string a) {
return ! string_eq( s , a ) ;
}
bool string_ge(string s, string a) {
int j= 0 ;
for (
int i= 0 ; i < s .len ; i ++ ) {
if ( i >= a .len ) {
/*if*/
return 1 ;
}
;
if ( (/*casttt*/ (int)( /*77*/ s .str[ i ]/*rbyte 0*/ ) ) < (/*casttt*/ (int)( /*77*/ a .str[ j ]/*rbyte 0*/ ) ) ) {
/*if*/
return 0 ;
}
else if ( (/*casttt*/ (int)( /*77*/ s .str[ i ]/*rbyte 0*/ ) ) > (/*casttt*/ (int)( /*77*/ a .str[ j ]/*rbyte 0*/ ) ) ) {
/*if*/
return 1 ;
}
;
j ++ ;
}
;
return 1 ;
}
bool string_le(string s, string a) {
return ! string_ge( s , a ) || string_eq( s , a ) ;
}
bool string_lt(string s, string a) {
return string_le( s , a ) && string_ne( s , a ) ;
}
bool string_gt(string s, string a) {
return string_ge( s , a ) && string_ne( s , a ) ;
}
string string_add(string s, string a) {
int new_len= a .len + s .len ;
string res= (string){ .len = new_len , .str = v_malloc ( new_len + 1 ) } ;
for (
int j= 0 ; j < s .len ; j ++ ) {
res .str[ j ]/*rbyte 1*/ = s .str[ j ]/*rbyte 0*/ ;
}
;
for (
int j= 0 ; j < a .len ; j ++ ) {
res .str[ s .len + j ]/*rbyte 1*/ = a .str[ j ]/*rbyte 0*/ ;
}
;
res .str[ new_len ]/*rbyte 1*/ = '\0' ;
return res ;
}
array_string string_split(string s, string delim) {
array_string res=new_array_from_c_array(0, 0, sizeof(string), (string[]) { }) ;
if ( delim .len == 0 ) {
/*if*/
_PUSH(& res , ( s ), tmp32, string) ;
return res ;
}
;
if ( delim .len == 1 ) {
/*if*/
return string_split_single( s , delim .str[ 0 ]/*rbyte 0*/ ) ;
}
;
int i= 0 ;
int start= 0 ;
while ( i < s .len ) {
bool a= s .str[ i ]/*rbyte 0*/ == delim .str[ 0 ]/*rbyte 0*/ ;
int j= 1 ;
while ( j < delim .len && a ) {
a = a && s .str[ i + j ]/*rbyte 0*/ == delim .str[ j ]/*rbyte 0*/ ;
j ++ ;
}
;
bool last= i == s .len - 1 ;
if ( a || last ) {
/*if*/
if ( last ) {
/*if*/
i ++ ;
}
;
string val= string_substr( s , start , i ) ;
if ( val .len > 0 ) {
/*if*/
if ( string_starts_with( val , delim ) ) {
/*if*/
val = string_right( val , delim .len ) ;
}
;
_PUSH(& res , ( string_trim_space( val ) ), tmp39, string) ;
}
;
start = i ;
}
;
i ++ ;
}
;
return res ;
}
array_string string_split_single(string s, byte delim) {
array_string res=new_array_from_c_array(0, 0, sizeof(string), (string[]) { }) ;
if ( (/*casttt*/ (int)( /*77*/ delim ) ) == 0 ) {
/*if*/
_PUSH(& res , ( s ), tmp41, string) ;
return res ;
}
;
int i= 0 ;
int start= 0 ;
while ( i < s .len ) {
bool a= s .str[ i ]/*rbyte 0*/ == delim ;
bool b= i == s .len - 1 ;
if ( a || b ) {
/*if*/
if ( i == s .len - 1 ) {
/*if*/
i ++ ;
}
;
string val= string_substr( s , start , i ) ;
if ( val .len > 0 ) {
/*if*/
_PUSH(& res , ( string_trim_space( val ) ), tmp47, string) ;
}
;
start = i + 1 ;
}
;
i ++ ;
}
;
return res ;
}
array_string string_split_into_lines(string s) {
array_string res=new_array_from_c_array(0, 0, sizeof(string), (string[]) { }) ;
if ( s .len == 0 ) {
/*if*/
return res ;
}
;
int start= 0 ;
for (
int i= 0 ; i < s .len ; i ++ ) {
bool last= i == s .len - 1 ;
if ( (/*casttt*/ (int)( /*77*/ s .str[ i ]/*rbyte 0*/ ) ) == 10 || last ) {
/*if*/
if ( last ) {
/*if*/
i ++ ;
}
;
string line= string_substr( s , start , i ) ;
_PUSH(& res , ( line ), tmp53, string) ;
start = i + 1 ;
}
;
}
;
return res ;
}
string string_left(string s, int n) {
if ( n >= s .len ) {
/*if*/
return s ;
}
;
return string_substr( s , 0 , n ) ;
}
string string_right(string s, int n) {
if ( n >= s .len ) {
/*if*/
return tos2("") ;
}
;
return string_substr( s , n , s .len ) ;
}
string string_substr(string s, int start, int end) {
if ( start >= s .len ) {
/*if*/
return tos2("") ;
}
;
int len= end - start ;
string res= (string){ .str = s .str + start , .len = len } ;
return res ;
}
int string_index(string s, string p) {
if ( p .len > s .len ) {
/*if*/
return - 1 ;
}
;
int i= 0 ;
while ( i < s .len ) {
int j= 0 ;
int ii= i ;
while ( j < p .len && s .str[ ii ]/*rbyte 0*/ == p .str[ j ]/*rbyte 0*/ ) {
j ++ ;
ii ++ ;
}
;
if ( j == p .len ) {
/*if*/
return i ;
}
;
i ++ ;
}
;
return - 1 ;
}
int string_last_index(string s, string p) {
if ( p .len > s .len ) {
/*if*/
return - 1 ;
}
;
int i= s .len - p .len ;
while ( i >= 0 ) {
int j= 0 ;
while ( j < p .len && s .str[ i + j ]/*rbyte 0*/ == p .str[ j ]/*rbyte 0*/ ) {
j ++ ;
}
;
if ( j == p .len ) {
/*if*/
return i ;
}
;
i -- ;
}
;
return - 1 ;
}
int string_index_after(string s, string p, int start) {
if ( p .len > s .len ) {
/*if*/
return - 1 ;
}
;
int strt= start ;
if ( start < 0 ) {
/*if*/
strt = 0 ;
}
;
if ( start >= s .len ) {
/*if*/
return - 1 ;
}
;
int i= strt ;
while ( i < s .len ) {
int j= 0 ;
int ii= i ;
while ( j < p .len && s .str[ ii ]/*rbyte 0*/ == p .str[ j ]/*rbyte 0*/ ) {
j ++ ;
ii ++ ;
}
;
if ( j == p .len ) {
/*if*/
return i ;
}
;
i ++ ;
}
;
return - 1 ;
}
bool string_contains(string s, string p) {
bool res= string_index( s , p ) > 0 - 1 ;
return res ;
}
bool string_starts_with(string s, string p) {
bool res= string_index( s , p ) == 0 ;
return res ;
}
bool string_ends_with(string s, string p) {
if ( p .len > s .len ) {
/*if*/
return 0 ;
}
;
bool res= string_last_index( s , p ) == s .len - p .len ;
return res ;
}
string string_to_lower(string s) {
byte* b= v_malloc ( s .len ) ;
for (
int i= 0 ; i < s .len ; i ++ ) {
b [/*ptr*/ i ]/*rbyte 1*/ = tolower ( s .str [/*ptr*/ i ]/*rbyte 0*/ ) ;
}
;
return tos ( b , s .len ) ;
}
string string_to_upper(string s) {
byte* b= v_malloc ( s .len ) ;
for (
int i= 0 ; i < s .len ; i ++ ) {
b [/*ptr*/ i ]/*rbyte 1*/ = toupper ( s .str [/*ptr*/ i ]/*rbyte 0*/ ) ;
}
;
return tos ( b , s .len ) ;
}
string string_find_between(string s, string start, string end) {
int start_pos= string_index( s , start ) ;
if ( start_pos == - 1 ) {
/*if*/
return tos2("") ;
}
;
string val= string_right( s , start_pos + start .len ) ;
int end_pos= string_index( val , end ) ;
if ( end_pos == - 1 ) {
/*if*/
return val ;
}
;
return string_left( val , end_pos ) ;
}
bool array_string_contains(array_string ar, string val) {
array_string tmp75 = ar;
;
for (int tmp76 = 0; tmp76 < tmp75 .len; tmp76 ++) {
string s = ((string *) tmp75.data)[tmp76];
if (string_eq( s , val ) ) {
/*if*/
return 1 ;
}
;
}
;
return 0 ;
}
bool array_int_contains(array_int ar, int val) {
array_int tmp77 = ar ;
;
for (int i = 0; i < tmp77 .len; i ++) {
int s = ((int *) tmp77 . data)[i];
if ( s == val ) {
/*if*/
return 1 ;
}
;
}
;
return 0 ;
}
void* array_string_to_c(array_string a) {
char ** res = malloc(sizeof(char*) * a.len);
for (
int i= 0 ; i < a .len ; i ++ ) {
string val= ( *(string*) array__get( a , i) ) ;
res[i] = val.str;
}
;
return res;
return 0 ;
}
bool is_space(byte c) {
return isspace ( c ) ;
}
bool byte_is_space(byte c) {
return is_space ( c ) ;
}
string string_trim_space(string s) {
if (string_eq( s , tos2("") ) ) {
/*if*/
return tos2("") ;
}
;
int i= 0 ;
while ( i < s .len && is_space ( s .str[ i ]/*rbyte 0*/ ) ) {
i ++ ;
}
;
string res= string_right( s , i ) ;
int end= res .len - 1 ;
while ( end >= 0 && is_space ( res .str[ end ]/*rbyte 1*/ ) ) {
end -- ;
}
;
res = string_left( res , end + 1 ) ;
return res ;
}
string string_trim(string s, byte c) {
if (string_eq( s , tos2("") ) ) {
/*if*/
return tos2("") ;
}
;
int i= 0 ;
while ( i < s .len && c == s .str[ i ]/*rbyte 0*/ ) {
i ++ ;
}
;
string res= string_right( s , i ) ;
int end= res .len - 1 ;
while ( end >= 0 && c == res .str[ end ]/*rbyte 1*/ ) {
end -- ;
}
;
res = string_left( res , end + 1 ) ;
return res ;
}
string string_trim_left(string s, string cutset) {
int start= string_index( s , cutset ) ;
if ( start != 0 ) {
/*if*/
return s ;
}
;
while ( start < s .len - 1 && s .str[ start ]/*rbyte 0*/ == cutset .str[ 0 ]/*rbyte 0*/ ) {
start ++ ;
}
;
return string_right( s , start ) ;
}
string string_trim_right(string s, string cutset) {
return s ;
int pos= string_last_index( s , cutset ) ;
if ( pos == - 1 ) {
/*if*/
return s ;
}
;
return string_left( s , pos ) ;
}
int compare_strings(string* a, string* b) {
if ( string_le(* a ,* b ) ) {
/*if*/
return - 1 ;
}
;
if ( string_ge(* a ,* b ) ) {
/*if*/
return 1 ;
}
;
return 0 ;
}
int compare_strings_by_len(string* a, string* b) {
if ( a ->len < b ->len ) {
/*if*/
return - 1 ;
}
;
if ( a ->len > b ->len ) {
/*if*/
return 1 ;
}
;
return 0 ;
}
int compare_lower_strings(string* a, string* b) {
string aa= string_to_lower(* a ) ;
string bb= string_to_lower(* a ) ;
return compare_strings (& /*11 EXP:"string*" GOT:"string" */ aa ,& /*11 EXP:"string*" GOT:"string" */ bb ) ;
}
void array_string_sort(array_string* s) {
array_sort_with_compare( s , compare_strings ) ;
}
void array_string_sort_ignore_case(array_string* s) {
array_sort_with_compare( s , compare_lower_strings ) ;
}
void array_string_sort_by_len(array_string* s) {
array_sort_with_compare( s , compare_strings_by_len ) ;
}
ustring string_ustring(string s) {
ustring res= (ustring){ .s = s , .runes = new_array ( 0 , s .len , sizeof( int) ) , .len = 0 } ;
for (
int i= 0 ; i < s .len ; i ++ ) {
int char_len= 0 ;
char_len =UTF8_CHAR_LEN(s.str[i]);
_PUSH(& res .runes , ( i ), tmp95, int) ;
i += char_len - 1 ;
res .len ++ ;
}
;
return res ;
}
array_int g_ustring_runes;
ustring string_ustring_tmp(string s) {
ustring res= (ustring){ .s = s , .runes = 0 , .len = 0 } ;
res.runes = g_ustring_runes ;
res.runes.len = s.len ;
int j= 0 ;
for (
int i= 0 ; i < s .len ; i ++ ) {
int char_len= 0 ;
char_len =UTF8_CHAR_LEN(s.str[i]);
int tmp100 = i;
array_set(&/*q*/ res .runes , j , & tmp100) ;
j ++ ;
i += char_len - 1 ;
res .len ++ ;
}
;
return res ;
}
string ustring_substr(ustring u, int start, int end) {
start = ( *(int*) array__get( u .runes , start) ) ;
if ( end >= u .runes .len ) {
/*if*/
end = u .s .len ;
}
else {
/*else if*/
end = ( *(int*) array__get( u .runes , end) ) ;
}
;
return string_substr( u .s , start , end ) ;
}
string ustring_left(ustring u, int pos) {
return ustring_substr( u , 0 , pos ) ;
}
string ustring_right(ustring u, int pos) {
return ustring_substr( u , pos , u .len ) ;
}
byte string_at(string s, int idx) {
if ( idx < 0 || idx >= s .len ) {
/*if*/
v_panic ( _STR("string index out of range: %d / %d", idx, s .len) ) ;
}
;
return s .str [/*ptr*/ idx ]/*rbyte 0*/ ;
}
string ustring_at(ustring u, int idx) {
return ustring_substr( u , idx , idx + 1 ) ;
}
void v_ustring_free(ustring u) {
v_array_int_free( u .runes ) ;
}
int abs(int a) {
if ( a >= 0 ) {
/*if*/
return a ;
}
;
return - a ;
}
bool byte_is_digit(byte c) {
return c >= '0' && c <= '9' ;
}
bool byte_is_letter(byte c) {
return (/*lpar*/ c >= 'a' && c <= 'z' ) || (/*lpar*/ c >= 'A' && c <= 'Z' ) ;
}
void v_string_free(string s) {
free ( s .str ) ;
}
void v_array_string_free(array_string arr) {
array_string tmp105 = arr;
;
for (int tmp106 = 0; tmp106 < tmp105 .len; tmp106 ++) {
string s = ((string *) tmp105.data)[tmp106];
v_string_free( s ) ;
}
;
free ( arr .data ) ;
}
string string_all_before(string s, string dot) {
int pos= string_index( s , dot ) ;
if ( pos == - 1 ) {
/*if*/
return s ;
}
;
return string_left( s , pos ) ;
}
string string_all_before_last(string s, string dot) {
int pos= string_last_index( s , dot ) ;
if ( pos == - 1 ) {
/*if*/
return s ;
}
;
return string_left( s , pos ) ;
}
string string_all_after(string s, string dot) {
int pos= string_last_index( s , dot ) ;
if ( pos == - 1 ) {
/*if*/
return s ;
}
;
return string_right( s , pos + dot .len ) ;
}
string array_string_join(array_string a, string del) {
if ( a .len == 0 ) {
/*if*/
return tos2("") ;
}
;
int len= 0 ;
array_string tmp111 = a ;
;
for (int i = 0; i < tmp111 .len; i ++) {
string val = ((string *) tmp111 . data)[i];
len += val .len + del .len ;
}
;
len -= del .len ;
string res= tos2("") ;
res .len = len ;
res .str = v_malloc ( res .len + 1 ) ;
int idx= 0 ;
array_string tmp114 = a ;
;
for (int i = 0; i < tmp114 .len; i ++) {
string val = ((string *) tmp114 . data)[i];
for (
int j= 0 ; j < val .len ; j ++ ) {
byte c= val .str[ j ]/*rbyte 0*/ ;
res .str [/*ptr*/ idx ]/*rbyte 1*/ = val .str [/*ptr*/ j ]/*rbyte 0*/ ;
idx ++ ;
}
;
if ( i != a .len - 1 ) {
/*if*/
for (
int k= 0 ; k < del .len ; k ++ ) {
res .str [/*ptr*/ idx ]/*rbyte 1*/ = del .str [/*ptr*/ k ]/*rbyte 0*/ ;
idx ++ ;
}
;
}
;
}
;
res .str [/*ptr*/ res .len ]/*rbyte 1*/ = '\0' ;
return res ;
}
string array_string_join_lines(array_string s) {
return array_string_join( s , tos2("\n") ) ;
}
string string_limit(string s, int max) {
ustring u= string_ustring( s ) ;
if ( u .len <= max ) {
/*if*/
return s ;
}
;
return ustring_substr( u , 0 , max ) ;
}
bool byte_is_white(byte c) {
int i= (/*casttt*/ (int)( /*77*/ c ) ) ;
return i == 10 || i == 32 || i == 9 || i == 13 || c == '\r' ;
}
string repeat_char(byte c, int n) {
if ( n <= 0 ) {
/*if*/
return tos2("") ;
}
;
byte* arr= v_malloc ( n + 1 ) ;
for (
int i= 0 ; i < n ; i ++ ) {
arr [/*ptr*/ i ]/*rbyte 1*/ = c ;
}
;
arr [/*ptr*/ n ]/*rbyte 1*/ = '\0' ;
return tos ( arr , n ) ;
}
int string_hash(string s) {
int hash= (/*casttt*/ (int)( /*77*/ 0 ) ) ;
for (
int i= 0 ; i < s .len ; i ++ ) {
hash = hash * (/*casttt*/ (int)( /*77*/ 31 ) ) + (/*casttt*/ (int)( /*77*/ s .str [/*ptr*/ i ]/*rbyte 0*/ ) ) ;
}
;
return hash ;
}
void v_exit(int code) {
exit ( code ) ;
}
bool isnil(void* v) {
return v == 0 ;
}
void on_panic(int (*f)( int /*FFF*/ )) {
}
void print_backtrace() {
return ;
#ifdef mac
voidptr buffer [100 ]= {} /* arkek init*/ ;
void* nr_ptrs= backtrace ( buffer , 100 ) ;
backtrace_symbols_fd ( buffer , nr_ptrs , 1 ) ;
#endif
;
}
void v_panic(string s) {
println ( _STR("V panic: %.*s", s.len, s.str) ) ;
print_backtrace ( ) ;
exit ( 1 ) ;
}
void println(string s) {
if ( isnil ( s .str ) ) {
/*if*/
v_panic ( tos2("println(NIL)") ) ;
}
;
printf ( "%.*s\n" , s .len , s .str ) ;
}
void eprintln(string s) {
if ( isnil ( s .str ) ) {
/*if*/
v_panic ( tos2("eprintln(NIL)") ) ;
}
;
#ifdef mac
fprintf ( stderr , "%.*s\n" , s .len , s .str ) ;
;
#else
println ( s ) ;
#endif
;
}
void v_print(string s) {
printf ( "%.*s" , s .len , s .str ) ;
}
byte* v_malloc(int n) {
if ( n < 0 ) {
/*if*/
v_panic ( tos2("malloc(<0)") ) ;
}
;
#ifdef VPLAY
if ( n > 10000 ) {
/*if*/
v_panic ( tos2("allocating more than 10 KB is not allowed in the playground") ) ;
}
;
#endif
#ifdef DEBUG_ALLOC
i64 total= (/*casttt*/ (i64)( /*77*/ 0 ) ) ;
total_m += n;
total = total_m;
println ( _STR("\n\n\nmalloc(%d) total=%lld", n, total) ) ;
print_backtrace ( ) ;
#endif
byte* ptr= malloc ( n ) ;
if ( isnil ( ptr ) ) {
/*if*/
v_panic ( _STR("malloc(%d) failed", n) ) ;
}
;
return ptr ;
}
byte* v_calloc(int n) {
if ( n < 0 ) {
/*if*/
v_panic ( tos2("calloc(<0)") ) ;
}
;
return calloc ( sizeof( float) * n , sizeof( float) ) ;
}
int _strlen(byte* s) {
return strlen ( s ) ;
}
Option opt_ok(void* data) {
return (Option){ .data = data , .ok = 1 , .error = tos("", 0) , } ;
}
void* memdup(void* src, int sz) {
byte* mem= v_malloc ( sz ) ;
return memcpy ( mem , src , sz ) ;
}
Option v_error(string s) {
return (Option){ .error = s , .data = 0 , .ok = 0 } ;
}
array_int range_int(int start, int end) {
int len= end - start ;
int tmp7 = 0;
array_int res= array_repeat(&tmp7, len , sizeof(int) ) ;
for (
int i= 0 ; i < len ; i ++ ) {
int tmp10 = start + i;
array_set(&/*q*/ res , i , & tmp10) ;
}
;
return res ;
}
string double_str(double d) {
byte* buf= v_malloc ( sizeof( double) * 5 + 1 ) ;
sprintf ( buf , "%f" , d ) ;
return tos ( buf , _strlen ( buf ) ) ;
}
string float_str(float d) {
byte* buf= v_malloc ( sizeof( double) * 5 + 1 ) ;
sprintf ( buf , "%f" , d ) ;
return tos ( buf , _strlen ( buf ) ) ;
}
string f64_str(f64 d) {
byte* buf= v_malloc ( sizeof( double) * 5 + 1 ) ;
sprintf ( buf , "%f" , d ) ;
return tos ( buf , _strlen ( buf ) ) ;
}
string f32_str(f32 d) {
byte* buf= v_malloc ( sizeof( double) * 5 + 1 ) ;
sprintf ( buf , "%f" , d ) ;
return tos ( buf , _strlen ( buf ) ) ;
}
string ptr_str(void* ptr) {
byte* buf= v_malloc ( sizeof( double) * 5 + 1 ) ;
sprintf ( buf , "%p" , ptr ) ;
return tos ( buf , _strlen ( buf ) ) ;
}
string int_str(int nn) {
int n= nn ;
if ( n == 0 ) {
/*if*/
return tos2("0") ;
}
;
int max= 16 ;
byte* buf= v_malloc ( max ) ;
int len= 0 ;
bool is_neg= 0 ;
if ( n < 0 ) {
/*if*/
n = - n ;
is_neg = 1 ;
}
;
while ( n > 0 ) {
int d= n % 10 ;
buf [/*ptr*/ max - len - 1 ]/*rbyte 1*/ = d + (/*casttt*/ (int)( /*77*/ '0' ) ) ;
len ++ ;
n = n / 10 ;
}
;
if ( is_neg ) {
/*if*/
buf [/*ptr*/ max - len - 1 ]/*rbyte 1*/ = '-' ;
len ++ ;
}
;
return tos ( buf + max - len , len ) ;
}
string u8_str(u8 nn) {
u8 n= nn ;
if ( n == (/*casttt*/ (u8)( /*77*/ 0 ) ) ) {
/*if*/
return tos2("0") ;
}
;
int max= 5 ;
byte* buf= v_malloc ( max ) ;
int len= 0 ;
bool is_neg= 0 ;
if ( n < (/*casttt*/ (u8)( /*77*/ 0 ) ) ) {
/*if*/
n = - n ;
is_neg = 1 ;
}
;
while ( n > (/*casttt*/ (u8)( /*77*/ 0 ) ) ) {
u8 d= n % (/*casttt*/ (u8)( /*77*/ 10 ) ) ;
buf [/*ptr*/ max - len - 1 ]/*rbyte 1*/ = d + (/*casttt*/ (u8)( /*77*/ '0' ) ) ;
len ++ ;
n = n / (/*casttt*/ (u8)( /*77*/ 10 ) ) ;
}
;
if ( is_neg ) {
/*if*/
buf [/*ptr*/ max - len - 1 ]/*rbyte 1*/ = '-' ;
len ++ ;
}
;
return tos ( buf + max - len , len ) ;
}
string i64_str(i64 nn) {
i64 n= nn ;
if ( n == (/*casttt*/ (i64)( /*77*/ 0 ) ) ) {
/*if*/
return tos2("0") ;
}
;
int max= 32 ;
byte* buf= v_malloc ( max ) ;
int len= 0 ;
bool is_neg= 0 ;
if ( n < (/*casttt*/ (i64)( /*77*/ 0 ) ) ) {
/*if*/
n = - n ;
is_neg = 1 ;
}
;
while ( n > (/*casttt*/ (i64)( /*77*/ 0 ) ) ) {
int d= (/*casttt*/ (int)( /*77*/ n % (/*casttt*/ (i64)( /*77*/ 10 ) ) ) ) ;
buf [/*ptr*/ max - len - 1 ]/*rbyte 1*/ = d + (/*casttt*/ (int)( /*77*/ '0' ) ) ;
len ++ ;
n = n / (/*casttt*/ (i64)( /*77*/ 10 ) ) ;
}
;
if ( is_neg ) {
/*if*/
buf [/*ptr*/ max - len - 1 ]/*rbyte 1*/ = '-' ;
len ++ ;
}
;
return tos ( buf + max - len , len ) ;
}
string bool_str(bool b) {
if ( b ) {
/*if*/
return tos2("true") ;
}
;
return tos2("false") ;
}
string int_hex(int n) {
string s= int_str( n ) ;
byte* hex= v_malloc ( s .len + 2 ) ;
sprintf ( hex , "0x%x" , n ) ;
return tos ( hex , s .len + 2 ) ;
}
string i64_hex(i64 n) {
string s= i64_str( n ) ;
byte* hex= v_malloc ( s .len + 2 ) ;
sprintf ( hex , "0x%x" , n ) ;
return tos ( hex , s .len + 2 ) ;
}
bool array_byte_contains(array_byte a, byte val) {
array_byte tmp28 = a;
;
for (int tmp29 = 0; tmp29 < tmp28 .len; tmp29 ++) {
byte aa = ((byte *) tmp28.data)[tmp29];
if ( aa == val ) {
/*if*/
return 1 ;
}
;
}
;
return 0 ;
}
string byte_str(byte c) {
string str= (string){ .len = 1 , .str = v_malloc ( 2 ) } ;
str .str [/*ptr*/ 0 ]/*rbyte 1*/ = c ;
str .str [/*ptr*/ 1 ]/*rbyte 1*/ = '\0' ;
return str ;
}
int string_is_utf8(string s) {
int faulty_bytes= 0 ;
int len= s .len ;
int i= 0 ;
byte * str = s.str;
while (i < len) {
if (str[i] <= 0x7F) /* 00..7F */ {
i += 1;
}
else if (str[i] >= 0xC2 && str[i] <= 0xDF) /* C2..DF 80..BF */ {
if (i + 1 < len) /* Expect a 2nd byte */ {
if (str[i + 1] < 0x80 || str[i + 1] > 0xBF) {
printf( "After a first byte between C2 and DF, expecting a 2nd byte between 80 and BF");
faulty_bytes = 2;
goto end;
}
}
else {
printf( "After a first byte between C2 and DF, expecting a 2nd byte.");
faulty_bytes = 1;
goto end;
}
i += 2;
}
else if (str[i] == 0xE0) /* E0 A0..BF 80..BF */ {
if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
if (str[i + 1] < 0xA0 || str[i + 1] > 0xBF) {
printf( "After a first byte of E0, expecting a 2nd byte between A0 and BF.");
faulty_bytes = 2;
goto end;
}
if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
printf( "After a first byte of E0, expecting a 3nd byte between 80 and BF.");
faulty_bytes = 3;
goto end;
}
}
else {
printf( "After a first byte of E0, expecting two following bytes.");
faulty_bytes = 1;
goto end;
}
i += 3;
}
else if (str[i] >= 0xE1 && str[i] <= 0xEC) /* E1..EC 80..BF 80..BF */ {
if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
if (str[i + 1] < 0x80 || str[i + 1] > 0xBF) {
printf( "After a first byte between E1 and EC, expecting the 2nd byte between 80 and BF.");
faulty_bytes = 2;
goto end;
}
if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
printf( "After a first byte between E1 and EC, expecting the 3rd byte between 80 and BF.");
faulty_bytes = 3;
goto end;
}
}
else {
printf( "After a first byte between E1 and EC, expecting two following bytes.");
faulty_bytes = 1;
goto end;
}
i += 3;
}
else if (str[i] == 0xED) /* ED 80..9F 80..BF */ {
if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
if (str[i + 1] < 0x80 || str[i + 1] > 0x9F) {
printf( "After a first byte of ED, expecting 2nd byte between 80 and 9F.");
faulty_bytes = 2;
goto end;
}
if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
printf( "After a first byte of ED, expecting 3rd byte between 80 and BF.");
faulty_bytes = 3;
goto end;
}
}
else {
printf( "After a first byte of ED, expecting two following bytes.");
faulty_bytes = 1;
goto end;
}
i += 3;
}
else if (str[i] >= 0xEE && str[i] <= 0xEF) /* EE..EF 80..BF 80..BF */ {
if (i + 2 < len) /* Expect a 2nd and 3rd byte */ {
if (str[i + 1] < 0x80 || str[i + 1] > 0xBF) {
printf( "After a first byte between EE and EF, expecting 2nd byte between 80 and BF.");
faulty_bytes = 2;
goto end;
}
if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
printf( "After a first byte between EE and EF, expecting 3rd byte between 80 and BF.");
faulty_bytes = 3;
goto end;
}
}
else {
printf( "After a first byte between EE and EF, two following bytes.");
faulty_bytes = 1;
goto end;
}
i += 3;
}
else if (str[i] == 0xF0) /* F0 90..BF 80..BF 80..BF */ {
if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ {
if (str[i + 1] < 0x90 || str[i + 1] > 0xBF) {
printf( "After a first byte of F0, expecting 2nd byte between 90 and BF.");
faulty_bytes = 2;
goto end;
}
if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
printf( "After a first byte of F0, expecting 3rd byte between 80 and BF.");
faulty_bytes = 3;
goto end;
}
if (str[i + 3] < 0x80 || str[i + 3] > 0xBF) {
printf( "After a first byte of F0, expecting 4th byte between 80 and BF.");
faulty_bytes = 4;
goto end;
}
}
else {
printf( "After a first byte of F0, expecting three following bytes.");
faulty_bytes = 1;
goto end;
}
i += 4;
}
else if (str[i] >= 0xF1 && str[i] <= 0xF3) /* F1..F3 80..BF 80..BF 80..BF */ {
if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ {
if (str[i + 1] < 0x80 || str[i + 1] > 0xBF) {
printf( "After a first byte of F1, F2, or F3, expecting a 2nd byte between 80 and BF.");
faulty_bytes = 2;
goto end;
}
if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
printf( "After a first byte of F1, F2, or F3, expecting a 3rd byte between 80 and BF.");
faulty_bytes = 3;
goto end;
}
if (str[i + 3] < 0x80 || str[i + 3] > 0xBF) {
printf( "After a first byte of F1, F2, or F3, expecting a 4th byte between 80 and BF.");
faulty_bytes = 4;
goto end;
}
}
else {
printf( "After a first byte of F1, F2, or F3, expecting three following bytes.");
faulty_bytes = 1;
goto end;
}
i += 4;
}
else if (str[i] == 0xF4) /* F4 80..8F 80..BF 80..BF */ {
if (i + 3 < len) /* Expect a 2nd, 3rd 3th byte */ {
if (str[i + 1] < 0x80 || str[i + 1] > 0x8F) {
printf( "After a first byte of F4, expecting 2nd byte between 80 and 8F.");
faulty_bytes = 2;
goto end;
}
if (str[i + 2] < 0x80 || str[i + 2] > 0xBF) {
printf( "After a first byte of F4, expecting 3rd byte between 80 and BF.");
faulty_bytes = 3;
goto end;
}
if (str[i + 3] < 0x80 || str[i + 3] > 0xBF) {
printf( "After a first byte of F4, expecting 4th byte between 80 and BF.");
faulty_bytes = 4;
goto end;
}
}
else {
printf( "After a first byte of F4, expecting three following bytes.");
faulty_bytes = 1;
goto end;
}
i += 4;
}
else {
printf( "i=%d Expecting bytes in the following ranges: 00..7F C2..F4.",
i);
faulty_bytes = 1;
goto end;
}
}
end: ;
bool ok= faulty_bytes == 0 ;
if ( ok ) {
/*if*/
return - 1 ;
}
;
if ( ! ok ) {
/*if*/
println ( _STR("utf is bad dalen=%d KEK %.*s sdf", len, s.len, s.str) ) ;
}
;
return i ;
}
string utf32_to_str(u32 code) {
byte* buffer= v_malloc ( 5 ) ;
if (code <= 0x7F) {
buffer[0] = code;
return tos(buffer, 1);
}
if (code <= 0x7FF) {
buffer[0] = 0xC0 | (code >> 6); /* 110xxxxx */
buffer[1] = 0x80 | (code & 0x3F); /* 10xxxxxx */
return tos(buffer, 2);
}
if (code <= 0xFFFF) {
buffer[0] = 0xE0 | (code >> 12); /* 1110xxxx */
buffer[1] = 0x80 | ((code >> 6) & 0x3F); /* 10xxxxxx */
buffer[2] = 0x80 | (code & 0x3F); /* 10xxxxxx */
return tos(buffer, 3);
}
if (code <= 0x10FFFF) {
buffer[0] = 0xF0 | (code >> 18); /* 11110xxx */
buffer[1] = 0x80 | ((code >> 12) & 0x3F); /* 10xxxxxx */
buffer[2] = 0x80 | ((code >> 6) & 0x3F); /* 10xxxxxx */
buffer[3] = 0x80 | (code & 0x3F); /* 10xxxxxx */
return tos(buffer, 4);
}
return tos2("") ;
}
string utf32_to_str_no_malloc(u32 code, void* buf) {
char* buffer = buf;
if (code <= 0x7F) {
buffer[0] = code;
return tos(buffer, 1);
}
if (code <= 0x7FF) {
buffer[0] = 0xC0 | (code >> 6); /* 110xxxxx */
buffer[1] = 0x80 | (code & 0x3F); /* 10xxxxxx */
return tos(buffer, 2);
}
if (code <= 0xFFFF) {
buffer[0] = 0xE0 | (code >> 12); /* 1110xxxx */
buffer[1] = 0x80 | ((code >> 6) & 0x3F); /* 10xxxxxx */
buffer[2] = 0x80 | (code & 0x3F); /* 10xxxxxx */
return tos(buffer, 3);
}
if (code <= 0x10FFFF) {
buffer[0] = 0xF0 | (code >> 18); /* 11110xxx */
buffer[1] = 0x80 | ((code >> 12) & 0x3F); /* 10xxxxxx */
buffer[2] = 0x80 | ((code >> 6) & 0x3F); /* 10xxxxxx */
buffer[3] = 0x80 | (code & 0x3F); /* 10xxxxxx */
return tos(buffer, 4);
}
return tos2("") ;
}
int string_utf32_code(string _rune) {
if ( _rune .len == 0 ) {
/*if*/
return 0 ;
}
;
if ( _rune .len == 1 ) {
/*if*/
return (/*casttt*/ (int)( /*77*/ _rune .str[ 0 ]/*rbyte 0*/ ) ) ;
}
;
byte b= (/*casttt*/ (byte)( /*77*/ (/*casttt*/ (int)( /*77*/ _rune .str[ 0 ]/*rbyte 0*/ ) ) ) ) ;
b <<= _rune.len;
int res= (/*casttt*/ (int)( /*77*/ b ) ) ;
int shift= 6 - _rune .len ;
for (
int i= 1 ; i < _rune .len ; i ++ ) {
int c= (/*casttt*/ (int)( /*77*/ _rune .str[ i ]/*rbyte 0*/ ) ) ;
res <<= shift;
res |= c & 0x3f;
shift = 6 ;
}
;
return res ;
}
map new_map(int cap, int elm_size) {
map res= (map){ .element_size = elm_size , .entries = new_array(0, 1, sizeof(Entry)) , .is_sorted = 0 } ;
return res ;
}
Entry map_new_entry(map* m, string key, void* val) {
Entry new_e= (Entry){ .key = key , .val = v_malloc ( m ->element_size ) } ;
memcpy ( new_e .val , val , m ->element_size ) ;
return new_e ;
}
void map__set(map* m, string key, void* val) {
Entry e= map_new_entry(& /* ? */* m , key , val ) ;
for (
int i= 0 ; i < m ->entries .len ; i ++ ) {
Entry entry= ( *(Entry*) array__get( m ->entries , i) ) ;
if (string_eq( entry .key , key ) ) {
/*if*/
Entry tmp8 = e;
array_set(&/*q*/ m ->entries , i , & tmp8) ;
return ;
}
;
}
;
_PUSH(& m ->entries , ( e ), tmp9, Entry) ;
m ->is_sorted = 0 ;
}
int volt_abs(int n) {
if ( n < 0 ) {
/*if*/
return - n ;
}
;
return n ;
}
void map_bs(map m, string query, int start, int end, void* out) {
int mid= start + (/*lpar*/ (/*lpar*/ end - start ) / 2 ) ;
if ( end - start == 0 ) {
/*if*/
Entry last= ( *(Entry*) array__get( m .entries , end) ) ;
memcpy ( out , last .val , m .element_size ) ;
return ;
}
;
if ( end - start == 1 ) {
/*if*/
Entry first= ( *(Entry*) array__get( m .entries , start) ) ;
memcpy ( out , first .val , m .element_size ) ;
return ;
}
;
if ( mid >= m .entries .len ) {
/*if*/
return ;
}
;
Entry mid_msg= ( *(Entry*) array__get( m .entries , mid) ) ;
if (string_lt( query , mid_msg .key ) ) {
/*if*/
map_bs( m , query , start , mid , out ) ;
return ;
}
;
map_bs( m , query , mid , end , out ) ;
}
int compare_map(Entry* a, Entry* b) {
if (string_lt( a ->key , b ->key ) ) {
/*if*/
return - 1 ;
}
;
if (string_gt( a ->key , b ->key ) ) {
/*if*/
return 1 ;
}
;
return 0 ;
}
void map_sort(map* m) {
array_sort_with_compare(& /* ? */ m ->entries , compare_map ) ;
m ->is_sorted = 1 ;
}
bool map_get(map m, string key, void* out) {
if ( m .is_sorted ) {
/*if*/
map_bs( m , key , 0 , m .entries .len , out ) ;
return 1 ;
}
;
for (
int i= 0 ; i < m .entries .len ; i ++ ) {
Entry entry= ( *(Entry*) array__get( m .entries , i) ) ;
if (string_eq( entry .key , key ) ) {
/*if*/
memcpy ( out , entry .val , m .element_size ) ;
return 1 ;
}
;
}
;
return 0 ;
}
void v_map_print(map m) {
println ( tos2("<<<<<<<<") ) ;
for (
int i= 0 ; i < m .entries .len ; i ++ ) {
}
;
println ( tos2(">>>>>>>>>>") ) ;
}
void v_map_free(map m) {
}
string map_string_str(map_string m) {
if ( m .entries .len == 0 ) {
/*if*/
return tos2("{}") ;
}
;
string s= tos2("{\n") ;
array_Entry tmp26 = m .entries;
;
for (int tmp27 = 0; tmp27 < tmp26 .len; tmp27 ++) {
Entry entry = ((Entry *) tmp26.data)[tmp27];
string tmp28 = tos("", 0); bool tmp29 = map_get( m , entry .key, & tmp28);
if (!tmp29) tmp28 = tos("", 0);
string val= tmp28 ;
s = string_add(s, _STR(" \"%.*s\" => \"%.*s\"\n", entry .key.len, entry .key.str, val.len, val.str) ) ;
}
;
s = string_add(s, tos2("}") ) ;
return s ;
}
smap new_smap() {
smap res= (smap){ .entries = new_array(0, 1, sizeof(Entry2)) , .is_sorted = 0 } ;
return res ;
}
void smap_set(smap* m, string key, string val) {
Entry2 e= (Entry2){ .key = key , .val = val } ;
_PUSH(& m ->entries , ( e ), tmp3, Entry2) ;
}
string smap_get(smap m, string key) {
if ( m .is_sorted ) {
/*if*/
return smap_bs( m , key , 0 , m .entries .len ) ;
}
;
for (
int i= 0 ; i < m .entries .len ; i ++ ) {
Entry2 entry= ( *(Entry2*) array__get( m .entries , i) ) ;
if (string_eq( entry .key , key ) ) {
/*if*/
return entry .val ;
}
;
}
;
return tos2("") ;
}
string smap_bs(smap m, string query, int start, int end) {
int mid= start + (/*lpar*/ (/*lpar*/ end - start ) / 2 ) ;
if ( end - start == 0 ) {
/*if*/
Entry2 last= ( *(Entry2*) array__get( m .entries , end) ) ;
return last .val ;
}
;
if ( end - start == 1 ) {
/*if*/
Entry2 first= ( *(Entry2*) array__get( m .entries , start) ) ;
return first .val ;
}
;
if ( mid >= m .entries .len ) {
/*if*/
return tos2("") ;
}
;
Entry2 mid_msg= ( *(Entry2*) array__get( m .entries , mid) ) ;
if (string_lt( query , mid_msg .key ) ) {
/*if*/
return smap_bs( m , query , start , mid ) ;
}
;
return smap_bs( m , query , mid , end ) ;
}
int compare_smap(Entry2* a, Entry2* b) {
if (string_lt( a ->key , b ->key ) ) {
/*if*/
return - 1 ;
}
;
if (string_gt( a ->key , b ->key ) ) {
/*if*/
return 1 ;
}
;
return 0 ;
}
void smap_sort(smap* m) {
array_sort_with_compare(& /* ? */ m ->entries , compare_smap ) ;
m ->is_sorted = 1 ;
}
void v_smap_free(smap m) {
}
string smap_str(smap m) {
if ( m .entries .len == 0 ) {
/*if*/
return tos2("{}") ;
}
;
string s= tos2("{\n") ;
array_Entry2 tmp19 = m .entries;
;
for (int tmp20 = 0; tmp20 < tmp19 .len; tmp20 ++) {
Entry2 entry = ((Entry2 *) tmp19.data)[tmp20];
s = string_add(s, _STR(" \"%.*s\" => \"%.*s\"\n", entry .key.len, entry .key.str, entry .val.len, entry .val.str) ) ;
}
;
s = string_add(s, tos2("}") ) ;
return s ;
}
StringBuilder new_string_builder(int initial_size) {
return (StringBuilder){ .buf = new_array ( 0 , initial_size , sizeof( byte) ) , .len = 0 } ;
}
void StringBuilder_write(StringBuilder* b, string s) {
array__push_many(& /* ? */ b ->buf , s .str , s .len ) ;
b ->len += s .len ;
}
void StringBuilder_writeln(StringBuilder* b, string s) {
array__push_many(& /* ? */ b ->buf , s .str , s .len ) ;
_PUSH(& b ->buf , ( '\n' ), tmp1, byte) ;
b ->len += s .len + 1 ;
}
string StringBuilder_str(StringBuilder b) {
return tos ( b .buf .data , b .len ) ;
}
void StringBuilder_cut(StringBuilder b, int n) {
b .len -= n ;
}
int main(int argc, char** argv) {
init_consts();
println ( tos2("hello, world") ) ;
}
void init_consts() { g_str_buf=malloc(1000); }
string _STR(const char *fmt, ...) {
va_list argptr;
va_start(argptr, fmt);
size_t len = vsnprintf(0, 0, fmt, argptr) + 1;
va_end(argptr);
byte* buf = malloc(len);
va_start(argptr, fmt);
vsprintf(buf, fmt, argptr);
va_end(argptr);
#ifdef DEBUG_ALLOC
puts("_STR:");
puts(buf);
#endif
return tos2(buf);
}
string _STR_TMP(const char *fmt, ...) {
va_list argptr;
va_start(argptr, fmt);
size_t len = vsnprintf(0, 0, fmt, argptr) + 1;
va_end(argptr);
va_start(argptr, fmt);
vsprintf(g_str_buf, fmt, argptr);
va_end(argptr);
#ifdef DEBUG_ALLOC
//puts("_STR_TMP:");
//puts(g_str_buf);
#endif
return tos2(g_str_buf);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment