decompiled_code:
__int64 test_start()
{
unsigned int v0; // ebx

v0 = setjmp(Landing_Pad);
if ( !v0 )
{
_sysv_signal(6, (__sighandler_t)handle_signal);
_sysv_signal(7, (__sighandler_t)handle_signal);
_sysv_signal(8, (__sighandler_t)handle_signal);
_sysv_signal(4, (__sighandler_t)handle_signal);
_sysv_signal(11, (__sighandler_t)handle_signal);
_sysv_signal(31, (__sighandler_t)handle_signal);
}
return v0;
}

canonical_decompiled_code:
__int64 func1()
{
unsigned int v0; // ebx

v0 = setjmp(Landing_Pad);
if ( !v0 )
{
_sysv_signal(6, (__sighandler_t)handle_signal);
_sysv_signal(7, (__sighandler_t)handle_signal);
_sysv_signal(8, (__sighandler_t)handle_signal);
_sysv_signal(4, (__sighandler_t)handle_signal);
_sysv_signal(11, (__sighandler_t)handle_signal);
_sysv_signal(31, (__sighandler_t)handle_signal);
}
return v0;
}

original_code:
int test_start(void) {
    int rval = _setjmp (Landing_Pad);
    if(0 == rval) {
        signal(6, handle_signal);
        signal(7, handle_signal);
        signal(8, handle_signal);
        signal(4, handle_signal);
        signal(11, handle_signal);
        signal(31, handle_signal);
    }
    return rval;
}

canonical_original_code:
int test_start() {
    int rval = _setjmp (Landing_Pad);
    if(0 == rval) {
        signal(6, handle_signal);
        signal(7, handle_signal);
        signal(8, handle_signal);
        signal(4, handle_signal);
        signal(11, handle_signal);
        signal(31, handle_signal);
    }
    return rval;
}

variable_types: rval int


repo: mikedlowis/libcds

decompiled_code:
__int64 test_print_results()
{
printf(
"\nUnit Test Summary\n-----------------\nTotal: %d\nPassed: %d\nFailed: %d\n\n",
(unsigned int)Test_Results,
(unsigned int)(Test_Results - *(&Test_Results + 2)),
(unsigned int)*(&Test_Results + 2));
return (unsigned int)*(&Test_Results + 2);
}

canonical_decompiled_code:
__int64 func2()
{
printf(
"\nUnit Test Summary\n-----------------\nTotal: %d\nPassed: %d\nFailed: %d\n\n",
(unsigned int)Test_Results,
(unsigned int)(Test_Results - *(&Test_Results + 2)),
(unsigned int)*(&Test_Results + 2));
return (unsigned int)*(&Test_Results + 2);
}

original_code:
int test_print_results(void) {
    (void)Loop_Var;
    (void)Curr_Test;
    printf(Results_String,
           Test_Results.total,
           Test_Results.total - Test_Results.failed,
           Test_Results.failed);
    return Test_Results.failed;
}

canonical_original_code:
int test_print_results() {
    (void)Loop_Var;
    (void)Curr_Test;
    printf(Results_String,
           Test_Results.total,
           Test_Results.total - Test_Results.failed,
           Test_Results.failed);
    return Test_Results.failed;
}

return_type: int


decompiled_code:
int __fastcall test_fail(const char *a1, const char *a2, __int64 a3)
{
++*(&Test_Results + 2);
return printf("%s:%d:0:%s:FAIL\n\t%s\n", a2, a3, (const char *)Curr_Test, a1);
}

canonical_decompiled_code:
int __fastcall func3(const char *a1, const char *a2, __int64 a3)
{
++*(&Test_Results + 2);
return printf("%s:%d:0:%s:FAIL\n\t%s\n", a2, a3, (const char *)Curr_Test, a1);
}

original_code:
void test_fail(char* expr, char* file, int line) {
    Test_Results.failed++;
    printf("%s:%d:0:%s:FAIL\n\t%s\n", file, line, Curr_Test, expr); }

canonical_original_code:
void test_fail(char *expr, char *file, int line) {
    Test_Results.failed++;
    printf("%s:%d:0:%s:FAIL\n\t%s\n", file, line, Curr_Test, expr); }

variable_types:
expr
char *

variable_types:
file
char *

variable_types: line int

return_type: void


decompiled_code:
__int64 __fastcall cmp_free(_QWORD *a1)
{
__int64 result; // rax

if ( a1 )
{
if ( *a1 )
result = mem_release();
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(_QWORD *a1)
{
__int64 result; // rax

if ( a1 )
{
if ( *a1 )
result = mem_release();
}
return result;
}

original_code:
static void cmp_free(void* obj)
{
    cmp_t* cmp = (cmp_t*)obj;
    if ((((void *)0) != obj) && (((void *)0) != cmp->env))
        mem_release(cmp->env);
}

canonical_original_code:
static void cmp_free(void *obj)
{
    struct cmp_t *cmp = (cmp_t*)obj;
    if ((((void *)0) != obj) && (((void *)0) != cmp->env))
        mem_release(cmp->env);
}

variable_types:
obj
void *

variable_types: struct cmp_t { void *env; int (*fn)(void *env, void *obja, void *objb); } *


decompiled_code:
__int64 __fastcall cmp_compare(__int64 a1)
{
return (*(__int64 (__fastcall **)(_QWORD))(a1 + 8))(*(_QWORD *)a1);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
return (*(__int64 (__fastcall **)(_QWORD))(a1 + 8))(*(_QWORD *)a1);
}

original_code:
int cmp_compare(cmp_t* cmp, void* obja, void* objb)
{
    return cmp->fn(cmp->env, obja, objb);
}

canonical_original_code:
int cmp_compare(struct cmp_t *cmp, void *obja, void *objb)
{
    return cmp->fn(cmp->env, obja, objb);
}

variable_types:
obja
void *

variable_types:
objb
void *

user_defined_types: struct cmp_t { void *env; int (*fn)(void *env, void *obja, void *objb); }


decompiled_code:
__int64 __fastcall str_size(__int64 a1)
{
exn_assert("source/string/str.c", 34LL, a1 != 0, "NULL != p_str");
return *(_QWORD *)a1;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
exn_assert("source/string/str.c", 34LL, a1 != 0, "NULL != p_str");
return *(_QWORD *)a1;
}

original_code:
size_t str_size(str_t* p_str)
{
    exn_assert("source/string/str.c",34,((void *)0) != p_str,"NULL != p_str");
    return p_str->size;
}

canonical_original_code:
unsigned long str_size(struct str_t *p_str)
{
    exn_assert("source/string/str.c",34,((void *)0) != p_str,"NULL != p_str");
    return p_str->size;
}

variable_types: struct str_t { unsigned long size; char data[]; } *

return_type: unsigned long


decompiled_code:
__int64 __fastcall str_cstr(__int64 a1)
{
exn_assert("source/string/str.c", 40LL, a1 != 0, "NULL != p_str");
return a1 + 8;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
exn_assert("source/string/str.c", 40LL, a1 != 0, "NULL != p_str");
return a1 + 8;
}

original_code:
const char* str_cstr(str_t* p_str)
{
    exn_assert("source/string/str.c",40,((void *)0) != p_str,"NULL != p_str");
    return p_str->data;
}

canonical_original_code:
char *str_cstr(struct str_t *p_str)
{
    exn_assert("source/string/str.c",40,((void *)0) != p_str,"NULL != p_str");
    return p_str->data;
}

return_type: char *

user_defined_types: struct str_t { unsigned long size; char data[]; }


decompiled_code:
__int64 __fastcall str_at(unsigned __int64 *a1, unsigned __int64 a2)
{
__int64 result; // rax

exn_assert("source/string/str.c", 52LL, a1 != 0LL, "NULL != p_str");
result = 0LL;
if ( *a1 > a2 )
result = *((unsigned __int8 *)a1 + a2 + 8);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(unsigned __int64 *a1, unsigned __int64 a2)
{
__int64 result; // rax

exn_assert("source/string/str.c", 52LL, a1 != 0LL, "NULL != p_str");
result = 0LL;
if ( *a1 > a2 )
result = *((unsigned __int8 *)a1 + a2 + 8);
return result;
}

original_code:
char str_at(str_t* p_str, size_t index)
{
    exn_assert("source/string/str.c",52,((void *)0) != p_str,"NULL != p_str");
    return (index >= p_str->size) ? '\0' : p_str->data[index];
}

canonical_original_code:
char str_at(struct str_t *p_str, unsigned long index)
{
    exn_assert("source/string/str.c",52,((void *)0) != p_str,"NULL != p_str");
    return (index >= p_str->size) ? '\0' : p_str->data[index];
}

variable_types:
index
unsigned long

return_type: char


decompiled_code:
int __fastcall str_compare(__int64 a1, __int64 a2)
{
exn_assert("source/string/str.c", 115LL, a1 != 0, "NULL != p_str1");
exn_assert("source/string/str.c", 116LL, a2 != 0, "NULL != p_str2");
return strcmp((const char *)(a1 + 8), (const char *)(a2 + 8));
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1, __int64 a2)
{
exn_assert("source/string/str.c", 115LL, a1 != 0, "NULL != p_str1");
exn_assert("source/string/str.c", 116LL, a2 != 0, "NULL != p_str2");
return strcmp((const char *)(a1 + 8), (const char *)(a2 + 8));
}

original_code:
int str_compare(str_t* p_str1, str_t* p_str2)
{
    exn_assert("source/string/str.c",115,((void *)0) != p_str1,"NULL != p_str1");
    exn_assert("source/string/str.c",116,((void *)0) != p_str2,"NULL != p_str2");
    return strcmp(p_str1->data, p_str2->data);
}

canonical_original_code:
int str_compare(struct str_t *p_str1, struct str_t *p_str2)
{
    exn_assert("source/string/str.c",115,((void *)0) != p_str1,"NULL != p_str1");
    exn_assert("source/string/str.c",116,((void *)0) != p_str2,"NULL != p_str2");
    return strcmp(p_str1->data, p_str2->data);
}


decompiled_code:
__int64 __fastcall str_find(const char *a1, __int64 a2)
{
__int64 v2; // r13
size_t v3; // r14
__int64 v4; // rbx

exn_assert("source/string/str.c", 123LL, a1 != 0LL, "NULL != p_str1");
exn_assert("source/string/str.c", 124LL, a2 != 0, "NULL != p_str2");
v2 = *(_QWORD *)a1;
if ( !*(_QWORD *)a1 )
return -1LL;
v3 = *(_QWORD *)a2;
v4 = 0LL;
while ( strncmp(&a1[v4 + 8], (const char *)(a2 + 8), v3) )
{
if ( ++v4 == v2 )
return -1LL;
}
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func4(const char *a1, __int64 a2)
{
__int64 v2; // r13
size_t v3; // r14
__int64 v4; // rbx

exn_assert("source/string/str.c", 123LL, a1 != 0LL, "NULL != p_str1");
exn_assert("source/string/str.c", 124LL, a2 != 0, "NULL != p_str2");
v2 = *(_QWORD *)a1;
if ( !*(_QWORD *)a1 )
return -1LL;
v3 = *(_QWORD *)a2;
v4 = 0LL;
while ( strncmp(&a1[v4 + 8], (const char *)(a2 + 8), v3) )
{
if ( ++v4 == v2 )
return -1LL;
}
return v4;
}

original_code:
size_t str_find(str_t* p_str1, str_t* p_str2)
{
    size_t idx = (18446744073709551615UL);
    exn_assert("source/string/str.c",123,((void *)0) != p_str1,"NULL != p_str1");
    exn_assert("source/string/str.c",124,((void *)0) != p_str2,"NULL != p_str2");
    for(size_t i = 0; i < p_str1->size; i++) {
        if(0 == strncmp(&(p_str1->data[i]), p_str2->data, p_str2->size))
        {
            idx = i;
            break;
        }
    }
    return idx;
}

canonical_original_code:
unsigned long str_find(struct str_t *p_str1, struct str_t *p_str2)
{
    unsigned long idx = (18446744073709551615UL);
    exn_assert("source/string/str.c",123,((void *)0) != p_str1,"NULL != p_str1");
    exn_assert("source/string/str.c",124,((void *)0) != p_str2,"NULL != p_str2");
    for(unsigned long i = 0; i < p_str1->size; i++) {
        if(0 == strncmp(&(p_str1->data[i]), p_str2->data, p_str2->size))
        {
            idx = i;
            break;
        }
    }
    return idx;
}

variable_types:
idx
unsigned long

variable_types:
i
unsigned long


decompiled_code:
__int64 __fastcall str_rfind(const char *a1, __int64 a2)
{
__int64 v2; // rbx

exn_assert("source/string/str.c", 138LL, a1 != 0LL, "NULL != p_str1");
exn_assert("source/string/str.c", 139LL, a2 != 0, "NULL != p_str2");
v2 = *(_QWORD *)a1;
while ( v2 )
{
if ( !strncmp(&a1[--v2 + 8], (const char *)(a2 + 8), *(_QWORD *)a2) )
return v2;
}
return -1LL;
}

canonical_decompiled_code:
__int64 __fastcall func5(const char *a1, __int64 a2)
{
__int64 v2; // rbx

exn_assert("source/string/str.c", 138LL, a1 != 0LL, "NULL != p_str1");
exn_assert("source/string/str.c", 139LL, a2 != 0, "NULL != p_str2");
v2 = *(_QWORD *)a1;
while ( v2 )
{
if ( !strncmp(&a1[--v2 + 8], (const char *)(a2 + 8), *(_QWORD *)a2) )
return v2;
}
return -1LL;
}

original_code:
size_t str_rfind(str_t* p_str1, str_t* p_str2)
{
    size_t idx = (18446744073709551615UL);
    exn_assert("source/string/str.c",138,((void *)0) != p_str1,"NULL != p_str1");
    exn_assert("source/string/str.c",139,((void *)0) != p_str2,"NULL != p_str2");
    for(size_t i = p_str1->size; i > 0; i--) {
        if(0 == strncmp(&(p_str1->data[i-1]), p_str2->data, p_str2->size))
        {
            idx = i-1;
            break;
        }
    }
    return idx;
}

canonical_original_code:
unsigned long str_rfind(struct str_t *p_str1, struct str_t *p_str2)
{
    unsigned long idx = (18446744073709551615UL);
    exn_assert("source/string/str.c",138,((void *)0) != p_str1,"NULL != p_str1");
    exn_assert("source/string/str.c",139,((void *)0) != p_str2,"NULL != p_str2");
    for(unsigned long i = p_str1->size; i > 0; i--) {
        if(0 == strncmp(&(p_str1->data[i-1]), p_str2->data, p_str2->size))
        {
            idx = i-1;
            break;
        }
    }
    return idx;
}


decompiled_code:
__int64 __fastcall str_split(const char *a1, __int64 a2)
{
__int64 v2; // rbp
__int64 v3; // rax
unsigned __int64 v5; // r13
__int64 v6; // r14
__int64 v7; // rax
_QWORD *v8; // r14
_QWORD *v9; // rax
__int64 v10; // r12
unsigned __int64 i; // rbx
__int64 v12; // rax
__int64 v13; // rax

v2 = vec_new(0LL);
v3 = str_find(a1, a2);
if ( v3 != -1 )
{
v5 = v3;
v6 = str_size((__int64)a1);
v7 = str_size(a2);
v8 = str_substr((__int64)a1, v7 + v5, v6);
v9 = str_substr((__int64)a1, 0LL, v5);
vec_push_back(v2, v9);
if ( str_find(a1, a2) == -1 )
{
vec_push_back(v2, v8);
}
else
{
v10 = str_split(v8, a2);
for ( i = 0LL; vec_size(v10) > i; ++i )
{
v12 = vec_at(v10, i);
v13 = mem_retain(v12);
vec_push_back(v2, v13);
}
mem_release(v10);
}
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func7(const char *a1, __int64 a2)
{
__int64 v2; // rbp
__int64 v3; // rax
unsigned __int64 v5; // r13
__int64 v6; // r14
__int64 v7; // rax
_QWORD *v8; // r14
_QWORD *v9; // rax
__int64 v10; // r12
unsigned __int64 i; // rbx
__int64 v12; // rax
__int64 v13; // rax

v2 = vec_new(0LL);
v3 = func4(a1, a2);
if ( v3 != -1 )
{
v5 = v3;
v6 = func0((__int64)a1);
v7 = func0(a2);
v8 = str_substr((__int64)a1, v7 + v5, v6);
v9 = str_substr((__int64)a1, 0LL, v5);
vec_push_back(v2, v9);
if ( func4(a1, a2) == -1 )
{
vec_push_back(v2, v8);
}
else
{
v10 = func7(v8, a2);
for ( i = 0LL; vec_size(v10) > i; ++i )
{
v12 = vec_at(v10, i);
v13 = mem_retain(v12);
vec_push_back(v2, v13);
}
mem_release(v10);
}
}
return v2;
}

original_code:
vec_t* str_split(str_t* str, str_t* splitstr) {
    vec_t* vec = vec_new(0);
    size_t index = str_find(str, splitstr);
    if (index != (18446744073709551615UL)) {
        str_t* therest = str_substr(str, index + str_size(splitstr), str_size(str));
        vec_push_back( vec, str_substr(str, 0, index) );
        if ((18446744073709551615UL) != str_find(str, splitstr)) {
            vec_t* nextsplit = str_split(therest, splitstr);
            for (size_t idx = 0; idx < vec_size(nextsplit); idx++) {
                vec_push_back( vec, mem_retain( vec_at(nextsplit, idx) ) );
            }
            mem_release(nextsplit);
        } else {
            vec_push_back( vec, therest );
        }
    }
    return vec;
}

canonical_original_code:
struct vec_t *str_split(struct str_t *str, struct str_t *splitstr) {
    struct vec_t *vec = vec_new(0);
    unsigned long index = str_find(str, splitstr);
    if (index != (18446744073709551615UL)) {
        struct str_t *therest = str_substr(str, index + str_size(splitstr), str_size(str));
        vec_push_back( vec, str_substr(str, 0, index) );
        if ((18446744073709551615UL) != str_find(str, splitstr)) {
            struct vec_t *nextsplit = str_split(therest, splitstr);
            for (unsigned long idx = 0; idx < vec_size(nextsplit); idx++) {
                vec_push_back( vec, mem_retain( vec_at(nextsplit, idx) ) );
            }
            mem_release(nextsplit);
        } else {
            vec_push_back( vec, therest );
        }
    }
    return vec;
}

variable_types:
splitstr
struct str_t *

variable_types: struct vec_t { unsigned long size; unsigned long capacity; void **p_buffer; } *


decompiled_code:
__int64 __fastcall vec_free_range(__int64 a1, unsigned __int64 a2, unsigned __int64 a3)
{
unsigned __int64 v3; // rbx
__int64 result; // rax

v3 = a2;
result = exn_assert("source/vector/vec.c", 212LL, a1 != 0, "NULL != p_buffer");
if ( a2 < a3 )
{
do
{
if ( *(_QWORD *)(a1 + 8 * v3) )
{
result = mem_release();
*(_QWORD *)(a1 + 8 * v3) = 0LL;
}
++v3;
}
while ( a3 != v3 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, unsigned __int64 a2, unsigned __int64 a3)
{
unsigned __int64 v3; // rbx
__int64 result; // rax

v3 = a2;
result = exn_assert("source/vector/vec.c", 212LL, a1 != 0, "NULL != p_buffer");
if ( a2 < a3 )
{
do
{
if ( *(_QWORD *)(a1 + 8 * v3) )
{
result = mem_release();
*(_QWORD *)(a1 + 8 * v3) = 0LL;
}
++v3;
}
while ( a3 != v3 );
}
return result;
}

original_code:
static void vec_free_range(void** p_buffer, size_t start_idx, size_t end_idx)
{
    size_t i;
    exn_assert("source/vector/vec.c",212,((void *)0) != p_buffer,"NULL != p_buffer");
    for(i = start_idx; i < end_idx; i++)
    {
        if (((void *)0) != p_buffer[i])
        {
            mem_release(p_buffer[i]);
            p_buffer[i] = ((void *)0);
        }
    }
}

canonical_original_code:
static void vec_free_range(void **p_buffer, unsigned long start_idx, unsigned long end_idx)
{
    unsigned long i;
    exn_assert("source/vector/vec.c",212,((void *)0) != p_buffer,"NULL != p_buffer");
    for(i = start_idx; i < end_idx; i++)
    {
        if (((void *)0) != p_buffer[i])
        {
            mem_release(p_buffer[i]);
            p_buffer[i] = ((void *)0);
        }
    }
}


decompiled_code:
__int64 __fastcall vec_size(__int64 a1)
{
exn_assert("source/vector/vec.c", 38LL, a1 != 0, "NULL != p_vec");
return *(_QWORD *)a1;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
exn_assert("source/vector/vec.c", 38LL, a1 != 0, "NULL != p_vec");
return *(_QWORD *)a1;
}

original_code:
size_t vec_size(vec_t* p_vec)
{
    exn_assert("source/vector/vec.c",38,((void *)0) != p_vec,"NULL != p_vec");
    return p_vec->size;
}

canonical_original_code:
unsigned long vec_size(struct vec_t *p_vec)
{
    exn_assert("source/vector/vec.c",38,((void *)0) != p_vec,"NULL != p_vec");
    return p_vec->size;
}

user_defined_types: struct vec_t { unsigned long size; unsigned long capacity; void **p_buffer; }


decompiled_code:
__int64 vec_max_size()
{
return -1LL;
}

canonical_decompiled_code:
__int64 func3()
{
return -1LL;
}

original_code:
size_t vec_max_size(void)
{
    return (size_t)-1;
}

canonical_original_code:
unsigned long vec_max_size()
{
    return (unsigned long)-1;
}


decompiled_code:
bool __fastcall vec_empty(__int64 a1)
{
exn_assert("source/vector/vec.c", 49LL, a1 != 0, "NULL != p_vec");
return vec_size(a1) == 0;
}

canonical_decompiled_code:
bool __fastcall func4(__int64 a1)
{
exn_assert("source/vector/vec.c", 49LL, a1 != 0, "NULL != p_vec");
return func2(a1) == 0;
}

original_code:
_Bool vec_empty(vec_t* p_vec)
{
    exn_assert("source/vector/vec.c",49,((void *)0) != p_vec,"NULL != p_vec");
    return (0 == vec_size(p_vec));
}

canonical_original_code:
_Bool vec_empty(struct vec_t *p_vec)
{
    exn_assert("source/vector/vec.c",49,((void *)0) != p_vec,"NULL != p_vec");
    return (0 == vec_size(p_vec));
}


decompiled_code:
unsigned __int64 __fastcall vec_next_capacity(__int64 a1)
{
unsigned __int64 v1; // rax
int v2; // edx
__int64 v3; // rcx

v1 = a1 - 1;
v2 = 6;
v3 = 1LL;
do
{
v1 |= v1 >> v3;
v3 *= 2LL;
--v2;
}
while ( v2 );
return v1 + 1;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func5(__int64 a1)
{
unsigned __int64 v1; // rax
int v2; // edx
__int64 v3; // rcx

v1 = a1 - 1;
v2 = 6;
v3 = 1LL;
do
{
v1 |= v1 >> v3;
v3 *= 2LL;
--v2;
}
while ( v2 );
return v1 + 1;
}

original_code:
size_t vec_next_capacity(size_t req_size)
{
    size_t next_power = req_size;
    size_t num_bits = sizeof(size_t) * 8;
    size_t bit_n;
    next_power--;
    for (bit_n = 1; bit_n < num_bits; bit_n = bit_n << 1)
    {
        next_power = next_power | (next_power >> bit_n);
    }
    next_power++;
    return next_power;
}

canonical_original_code:
unsigned long vec_next_capacity(unsigned long req_size)
{
    unsigned long next_power = req_size;
    unsigned long num_bits = sizeof(size_t) * 8;
    unsigned long bit_n;
    next_power--;
    for (bit_n = 1; bit_n < num_bits; bit_n = bit_n << 1)
    {
        next_power = next_power | (next_power >> bit_n);
    }
    next_power++;
    return next_power;
}


decompiled_code:
__int64 __fastcall vec_shrink_to_fit(__int64 *a1)
{
void *v1; // rax
__int64 result; // rax

exn_assert("source/vector/vec.c", 92LL, a1 != 0LL, "NULL != p_vec");
v1 = realloc((void *)a1[2], 8 * *a1);
a1[2] = (__int64)v1;
exn_assert("source/vector/vec.c", 94LL, v1 != 0LL, "p_vec->p_buffer != NULL");
result = *a1;
a1[1] = *a1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 *a1)
{
void *v1; // rax
__int64 result; // rax

exn_assert("source/vector/vec.c", 92LL, a1 != 0LL, "NULL != p_vec");
v1 = realloc((void *)a1[2], 8 * *a1);
a1[2] = (__int64)v1;
exn_assert("source/vector/vec.c", 94LL, v1 != 0LL, "p_vec->p_buffer != NULL");
result = *a1;
a1[1] = *a1;
return result;
}

original_code:
void vec_shrink_to_fit(vec_t* p_vec)
{
    exn_assert("source/vector/vec.c",92,((void *)0) != p_vec,"NULL != p_vec");
    p_vec->p_buffer = realloc( p_vec->p_buffer, sizeof(void*) * p_vec->size );
    exn_assert("source/vector/vec.c",94,p_vec->p_buffer != ((void *)0),"p_vec->p_buffer != NULL");
    p_vec->capacity = p_vec->size;
}

canonical_original_code:
void vec_shrink_to_fit(struct vec_t *p_vec)
{
    exn_assert("source/vector/vec.c",92,((void *)0) != p_vec,"NULL != p_vec");
    p_vec->p_buffer = realloc( p_vec->p_buffer, sizeof(void *) * p_vec->size );
    exn_assert("source/vector/vec.c",94,p_vec->p_buffer != ((void *)0),"p_vec->p_buffer != NULL");
    p_vec->capacity = p_vec->size;
}


decompiled_code:
__int64 __fastcall vec_capacity(__int64 a1)
{
return *(_QWORD *)(a1 + 8);
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1)
{
return *(_QWORD *)(a1 + 8);
}

original_code:
size_t vec_capacity(vec_t* p_vec)
{
    return p_vec->capacity;
}

canonical_original_code:
unsigned long vec_capacity(struct vec_t *p_vec)
{
    return p_vec->capacity;
}


decompiled_code:
__int64 __fastcall vec_reserve(__int64 a1, __int64 a2)
{
void *v2; // rax
__int64 result; // rax

exn_assert("source/vector/vec.c", 105LL, a1 != 0, "p_vec != NULL");
v2 = realloc(*(void **)(a1 + 16), 8 * a2);
*(_QWORD *)(a1 + 16) = v2;
result = exn_assert("source/vector/vec.c", 107LL, v2 != 0LL, "p_vec->p_buffer != NULL");
*(_QWORD *)(a1 + 8) = a2;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1, __int64 a2)
{
void *v2; // rax
__int64 result; // rax

exn_assert("source/vector/vec.c", 105LL, a1 != 0, "p_vec != NULL");
v2 = realloc(*(void **)(a1 + 16), 8 * a2);
*(_QWORD *)(a1 + 16) = v2;
result = exn_assert("source/vector/vec.c", 107LL, v2 != 0LL, "p_vec->p_buffer != NULL");
*(_QWORD *)(a1 + 8) = a2;
return result;
}

original_code:
void vec_reserve(vec_t* p_vec, size_t size)
{
    exn_assert("source/vector/vec.c",105,p_vec != ((void *)0),"p_vec != NULL");
    p_vec->p_buffer = realloc( p_vec->p_buffer, sizeof(void*) * size );
    exn_assert("source/vector/vec.c",107,p_vec->p_buffer != ((void *)0),"p_vec->p_buffer != NULL");
    p_vec->capacity = size;
}

canonical_original_code:
void vec_reserve(struct vec_t *p_vec, unsigned long size)
{
    exn_assert("source/vector/vec.c",105,p_vec != ((void *)0),"p_vec != NULL");
    p_vec->p_buffer = realloc( p_vec->p_buffer, sizeof(void *) * size );
    exn_assert("source/vector/vec.c",107,p_vec->p_buffer != ((void *)0),"p_vec->p_buffer != NULL");
    p_vec->capacity = size;
}

variable_types:
size
unsigned long


decompiled_code:
__int64 __fastcall vec_at(unsigned __int64 *a1, unsigned __int64 a2)
{
__int64 result; // rax

result = 0LL;
if ( *a1 > a2 )
result = *(_QWORD *)(a1[2] + 8 * a2);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(unsigned __int64 *a1, unsigned __int64 a2)
{
__int64 result; // rax

result = 0LL;
if ( *a1 > a2 )
result = *(_QWORD *)(a1[2] + 8 * a2);
return result;
}

original_code:
void* vec_at(vec_t* p_vec, size_t index)
{
    void* p_ret = ((void *)0);
    if (index < p_vec->size)
    {
        p_ret = p_vec->p_buffer[index];
    }
    return p_ret;
}

canonical_original_code:
void *vec_at(struct vec_t *p_vec, unsigned long index)
{
    void *p_ret = ((void *)0);
    if (index < p_vec->size)
    {
        p_ret = p_vec->p_buffer[index];
    }
    return p_ret;
}

return_type: void *


decompiled_code:
__int64 __fastcall vec_set(unsigned __int64 *a1, unsigned __int64 a2, __int64 a3)
{
__int64 result; // rax

result = 0LL;
if ( *a1 > a2 )
{
*(_QWORD *)(a1[2] + 8 * a2) = a3;
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func11(unsigned __int64 *a1, unsigned __int64 a2, __int64 a3)
{
__int64 result; // rax

result = 0LL;
if ( *a1 > a2 )
{
*(_QWORD *)(a1[2] + 8 * a2) = a3;
result = 1LL;
}
return result;
}

original_code:
_Bool vec_set(vec_t* p_vec, size_t index, void* data)
{
    _Bool ret = 0;
    if (index < p_vec->size)
    {
        p_vec->p_buffer[index] = data;
        ret = 1;
    }
    return ret;
}

canonical_original_code:
_Bool vec_set(struct vec_t *p_vec, unsigned long index, void *data)
{
    _Bool ret = 0;
    if (index < p_vec->size)
    {
        p_vec->p_buffer[index] = data;
        ret = 1;
    }
    return ret;
}

variable_types:
data
void *


decompiled_code:
__int64 __fastcall vec_erase(unsigned __int64 *a1, unsigned __int64 a2, unsigned __int64 a3)
{
unsigned __int64 v3; // rbp
unsigned __int64 v4; // rax
unsigned int v5; // er13

v3 = a3;
v4 = a3;
if ( a2 >= a3 )
v4 = a2;
LOBYTE(a3) = a2 <= a3 && *a1 > v4;
v5 = a3;
if ( (_BYTE)a3 )
{
vec_free_range(a1[2], a2, v3 + 1);
memmove((void *)(a1[2] + 8 * a2), (const void *)(a1[2] + 8 * (v3 + 1)), 8 * (*a1 + ~v3));
*a1 += a2 - v3 - 1;
}
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func13(unsigned __int64 *a1, unsigned __int64 a2, unsigned __int64 a3)
{
unsigned __int64 v3; // rbp
unsigned __int64 v4; // rax
unsigned int v5; // er13

v3 = a3;
v4 = a3;
if ( a2 >= a3 )
v4 = a2;
LOBYTE(a3) = a2 <= a3 && *a1 > v4;
v5 = a3;
if ( (_BYTE)a3 )
{
func0(a1[2], a2, v3 + 1);
memmove((void *)(a1[2] + 8 * a2), (const void *)(a1[2] + 8 * (v3 + 1)), 8 * (*a1 + ~v3));
*a1 += a2 - v3 - 1;
}
return v5;
}

original_code:
_Bool vec_erase(vec_t* p_vec, size_t start_idx, size_t end_idx)
{
    _Bool ret = 0;
    if ((start_idx < p_vec->size) && (end_idx < p_vec->size) && (start_idx <= end_idx))
    {
        vec_free_range(p_vec->p_buffer, start_idx, end_idx + 1);
        memmove(&(p_vec->p_buffer[start_idx]),
                &(p_vec->p_buffer[end_idx+1]),
                sizeof(void*) * (p_vec->size - end_idx - 1));
        p_vec->size = p_vec->size - ((end_idx - start_idx) + 1);
        ret = 1;
    }
    return ret;
}

canonical_original_code:
_Bool vec_erase(struct vec_t *p_vec, unsigned long start_idx, unsigned long end_idx)
{
    _Bool ret = 0;
    if ((start_idx < p_vec->size) && (end_idx < p_vec->size) && (start_idx <= end_idx))
    {
        vec_free_range(p_vec->p_buffer, start_idx, end_idx + 1);
        memmove(&(p_vec->p_buffer[start_idx]),
                &(p_vec->p_buffer[end_idx+1]),
                sizeof(void *) * (p_vec->size - end_idx - 1));
        p_vec->size = p_vec->size - ((end_idx - start_idx) + 1);
        ret = 1;
    }
    return ret;
}


original_code:
void* vec_pop_back(vec_t* p_vec)
{
    void* p_ret = ((void *)0);
    if (p_vec->size > 0)
    {
        p_vec->size = p_vec->size - 1;
        p_ret = p_vec->p_buffer[p_vec->size];
    }
    return p_ret;
}

canonical_original_code:
void *vec_pop_back(struct vec_t *p_vec)
{
    void *p_ret = ((void *)0);
    if (p_vec->size > 0)
    {
        p_vec->size = p_vec->size - 1;
        p_ret = p_vec->p_buffer[p_vec->size];
    }
    return p_ret;
}


decompiled_code:
void __fastcall vec_free(__int64 a1)
{
exn_assert("source/vector/vec.c", 202LL, a1 != 0, "NULL != p_vector");
exn_assert("source/vector/vec.c", 203LL, *(_QWORD *)(a1 + 16) != 0LL, "NULL != p_vector->p_buffer");
vec_clear(a1);
free(*(void **)(a1 + 16));
*(_QWORD *)(a1 + 16) = 0LL;
}

canonical_decompiled_code:
void __fastcall func17(__int64 a1)
{
exn_assert("source/vector/vec.c", 202LL, a1 != 0, "NULL != p_vector");
exn_assert("source/vector/vec.c", 203LL, *(_QWORD *)(a1 + 16) != 0LL, "NULL != p_vector->p_buffer");
func16(a1);
free(*(void **)(a1 + 16));
*(_QWORD *)(a1 + 16) = 0LL;
}

original_code:
static void vec_free(void* p_vec)
{
    vec_t* p_vector = (vec_t*)p_vec;
    exn_assert("source/vector/vec.c",202,((void *)0) != p_vector,"NULL != p_vector");
    exn_assert("source/vector/vec.c",203,((void *)0) != p_vector->p_buffer,"NULL != p_vector->p_buffer");
    vec_clear(p_vector);
    free(p_vector->p_buffer);
    p_vector->p_buffer = ((void *)0);
}

canonical_original_code:
static void vec_free(void *p_vec)
{
    struct vec_t *p_vector = (vec_t*)p_vec;
    exn_assert("source/vector/vec.c",202,((void *)0) != p_vector,"NULL != p_vector");
    exn_assert("source/vector/vec.c",203,((void *)0) != p_vector->p_buffer,"NULL != p_vector->p_buffer");
    vec_clear(p_vector);
    free(p_vector->p_buffer);
    p_vector->p_buffer = ((void *)0);
}


decompiled_code:
void exn_pop()
{
void *v0; // rdi

v0 = Exn_Handlers;
Exn_Handlers = *(void **)Exn_Handlers;
free(v0);
}

canonical_decompiled_code:
void func0()
{
void *v0; // rdi

v0 = Exn_Handlers;
Exn_Handlers = *(void **)Exn_Handlers;
free(v0);
}

original_code:
static void exn_pop(void) {
    exn_stack_t* p_prev = Exn_Handlers;
    Exn_Handlers = p_prev->p_next;
    free(p_prev);
}

canonical_original_code:
static void exn_pop() {
    struct exn_stack_t *p_prev = Exn_Handlers;
    Exn_Handlers = p_prev->p_next;
    free(p_prev);
}

variable_types: struct exn_stack_t { struct exn_stack_t *p_next; struct exn_handler_t { struct __jmp_buf_tag { long __jmpbuf[8]; int __mask_was_saved; struct __sigset_t { unsigned long __val[-1]; } __saved_mask; } context[1]; enum exn_state_t { EXN_BEGIN=0, EXN_TRY=1, EXN_CATCH=2, EXN_FINALLY=3, EXN_DONE=4 } state; } handler; } *

user_defined_types: struct exn_stack_t { struct exn_stack_t *p_next; struct exn_handler_t handler; }

user_defined_types: struct exn_handler_t { struct __jmp_buf_tag context[1]; enum exn_state_t state; }

user_defined_types: struct __jmp_buf_tag { long __jmpbuf[8]; int __mask_was_saved; struct __sigset_t __saved_mask; }


decompiled_code:
_DWORD *exn_prep()
{
void *v0; // rbx
_DWORD *result; // rax

v0 = Exn_Handlers;
result = malloc(0xD8uLL);
Exn_Handlers = result;
*(_QWORD *)result = v0;
result[52] = 0;
Exn_Handled = 1;
return result;
}

canonical_decompiled_code:
_DWORD *func2()
{
void *v0; // rbx
_DWORD *result; // rax

v0 = Exn_Handlers;
result = malloc(0xD8uLL);
Exn_Handlers = result;
*(_QWORD *)result = v0;
result[52] = 0;
Exn_Handled = 1;
return result;
}

original_code:
void exn_prep(void) {
    exn_stack_t* p_prev = Exn_Handlers;
    Exn_Handlers = (exn_stack_t*)malloc(sizeof(exn_stack_t));
    Exn_Handlers->p_next = p_prev;
    Exn_Handlers->handler.state = EXN_BEGIN;
    Exn_Handled = 1;
}

canonical_original_code:
void exn_prep() {
    struct exn_stack_t *p_prev = Exn_Handlers;
    Exn_Handlers = (struct exn_stack_t *)malloc(sizeof(exn_stack_t));
    Exn_Handlers->p_next = p_prev;
    Exn_Handlers->handler.state = EXN_BEGIN;
    Exn_Handled = 1;
}

user_defined_types: enum exn_state_t { EXN_BEGIN=0, EXN_TRY=1, EXN_CATCH=2, EXN_FINALLY=3, EXN_DONE=4 }

user_defined_types: struct __sigset_t { unsigned long __val[-1]; }


decompiled_code:
__int64 exn_current()
{
return Exn_Current;
}

canonical_decompiled_code:
__int64 func3()
{
return Exn_Current;
}

original_code:
const exn_t* exn_current(void) {
    return Exn_Current;
}

canonical_original_code:
struct exn_t *exn_current() {
    return Exn_Current;
}

return_type: struct exn_t { struct exn_t *p_parent; char *name; } *


decompiled_code:
__int64 __fastcall exn_catch(_QWORD *a1)
{
_QWORD *v1; // rax

v1 = (_QWORD *)exn_current();
if ( v1 )
{
if ( v1 == a1 )
{
LABEL_5:
Exn_Handled = 1;
}
else
{
while ( 1 )
{
v1 = (_QWORD *)*v1;
if ( !v1 )
break;
if ( a1 == v1 )
goto LABEL_5;
}
}
}
return (unsigned __int8)Exn_Handled;
}

canonical_decompiled_code:
__int64 __fastcall func4(_QWORD *a1)
{
_QWORD *v1; // rax

v1 = (_QWORD *)func3();
if ( v1 )
{
if ( v1 == a1 )
{
LABEL_5:
Exn_Handled = 1;
}
else
{
while ( 1 )
{
v1 = (_QWORD *)*v1;
if ( !v1 )
break;
if ( a1 == v1 )
goto LABEL_5;
}
}
}
return (unsigned __int8)Exn_Handled;
}

original_code:
_Bool exn_catch(const exn_t* p_type) {
    const exn_t* p_current;
    for(p_current = exn_current(); p_current != ((void *)0); p_current = p_current->p_parent)
    {
        if (p_current == p_type)
        {
            Exn_Handled = 1;
            break;
        }
    }
    return Exn_Handled;
}

canonical_original_code:
_Bool exn_catch(struct exn_t *p_type) {
    struct exn_t *p_current;
    for(p_current = exn_current(); p_current != ((void *)0); p_current = p_current->p_parent)
    {
        if (p_current == p_type)
        {
            Exn_Handled = 1;
            break;
        }
    }
    return Exn_Handled;
}

variable_types: struct exn_t { struct exn_t *p_parent; char *name; } *


decompiled_code:
char *exn_handler()
{
char *result; // rax

result = (char *)Exn_Handlers;
if ( Exn_Handlers )
result = (char *)Exn_Handlers + 8;
return result;
}

canonical_decompiled_code:
char *func5()
{
char *result; // rax

result = (char *)Exn_Handlers;
if ( Exn_Handlers )
result = (char *)Exn_Handlers + 8;
return result;
}

original_code:
exn_handler_t* exn_handler(void) {
    return (((void *)0) != Exn_Handlers) ? &(Exn_Handlers->handler) : ((void *)0);
}

canonical_original_code:
struct exn_handler_t *exn_handler() {
    return (((void *)0) != Exn_Handlers) ? &(Exn_Handlers->handler) : ((void *)0);
}

return_type: struct exn_handler_t { struct __jmp_buf_tag { long __jmpbuf[8]; int __mask_was_saved; struct __sigset_t { unsigned long __val[-1]; } __saved_mask; } context[1]; enum exn_state_t { EXN_BEGIN=0, EXN_TRY=1, EXN_CATCH=2, EXN_FINALLY=3, EXN_DONE=4 } state; } *


decompiled_code:
void __fastcall __noreturn exn_throw(__int64 a1, int a2, __int64 a3, __int64 a4)
{
char *v4; // rax

Exn_Current = a3;
Exn_Handled = 0;
Exn_File = a1;
Exn_Line = a2;
Exn_Msg = a4;
if ( Exn_Handlers )
{
v4 = exn_handler();
longjmp((struct __jmp_buf_tag *)v4, 1);
}
exn_uncaught(a3);
}

canonical_decompiled_code:
void __fastcall __noreturn func6(__int64 a1, int a2, __int64 a3, __int64 a4)
{
char *v4; // rax

Exn_Current = a3;
Exn_Handled = 0;
Exn_File = a1;
Exn_Line = a2;
Exn_Msg = a4;
if ( Exn_Handlers )
{
v4 = func5();
longjmp((struct __jmp_buf_tag *)v4, 1);
}
func1(a3);
}

original_code:
void exn_throw(const char* file, int line, const exn_t* p_type, const char* msg) {
    Exn_Current = p_type;
    Exn_Handled = 0;
    Exn_File = file;
    Exn_Line = line;
    Exn_Msg = msg;
    if (Exn_Handlers == ((void *)0)) {
        exn_uncaught(Exn_Current);
    } else {
        longjmp(exn_handler()->context,1);
    }
}

canonical_original_code:
void exn_throw(char *file, int line, struct exn_t *p_type, char *msg) {
    Exn_Current = p_type;
    Exn_Handled = 0;
    Exn_File = file;
    Exn_Line = line;
    Exn_Msg = msg;
    if (Exn_Handlers == ((void *)0)) {
        exn_uncaught(Exn_Current);
    } else {
        longjmp(exn_handler()->context,1);
    }
}

variable_types:
msg
char *

user_defined_types: struct exn_t { struct exn_t *p_parent; char *name; }


decompiled_code:
void __noreturn exn_rethrow()
{
exn_pop();
exn_throw(Exn_File, Exn_Line, Exn_Current, Exn_Msg);
}

canonical_decompiled_code:
void __noreturn func7()
{
func0();
func6(Exn_File, Exn_Line, Exn_Current, Exn_Msg);
}

original_code:
void exn_rethrow(void) {
    exn_pop();
    exn_throw(Exn_File, Exn_Line, Exn_Current, Exn_Msg);
}

canonical_original_code:
void exn_rethrow() {
    exn_pop();
    exn_throw(Exn_File, Exn_Line, Exn_Current, Exn_Msg);
}


decompiled_code:
__int64 exn_process()
{
char *v0; // rax
unsigned int v1; // edx

v0 = exn_handler();
switch ( *((_DWORD *)v0 + 50) )
{
case 0:
*((_DWORD *)v0 + 50) = 1;
v1 = 1;
break;
case 1:
*((_DWORD *)v0 + 50) = 2 - ((Exn_Handled == 0) - 1);
v1 = 1;
break;
case 2:
*((_DWORD *)v0 + 50) = 3;
v1 = 1;
break;
case 3:
v1 = (unsigned __int8)Exn_Handled;
if ( !Exn_Handled )
exn_rethrow();
*((_DWORD *)v0 + 50) = 4;
break;
case 4:
exn_pop();
v1 = 0;
break;
default:
fwrite("Error: Exception handler entered an invalid state\n", 1uLL, 0x32uLL, stderr);
exit(1);
}
return v1;
}

canonical_decompiled_code:
__int64 func8()
{
char *v0; // rax
unsigned int v1; // edx

v0 = func5();
switch ( *((_DWORD *)v0 + 50) )
{
case 0:
*((_DWORD *)v0 + 50) = 1;
v1 = 1;
break;
case 1:
*((_DWORD *)v0 + 50) = 2 - ((Exn_Handled == 0) - 1);
v1 = 1;
break;
case 2:
*((_DWORD *)v0 + 50) = 3;
v1 = 1;
break;
case 3:
v1 = (unsigned __int8)Exn_Handled;
if ( !Exn_Handled )
func7();
*((_DWORD *)v0 + 50) = 4;
break;
case 4:
func0();
v1 = 0;
break;
default:
fwrite("Error: Exception handler entered an invalid state\n", 1uLL, 0x32uLL, stderr);
exit(1);
}
return v1;
}

original_code:
_Bool exn_process(void) {
    _Bool ret = 1;
    switch(exn_handler()->state) {
        case EXN_BEGIN:
            exn_handler()->state = EXN_TRY;
            break;
        case EXN_TRY:
            exn_handler()->state = (!Exn_Handled) ? EXN_CATCH : EXN_FINALLY;
            break;
        case EXN_CATCH:
            exn_handler()->state = EXN_FINALLY;
            break;
        case EXN_FINALLY:
            if (!Exn_Handled)
                exn_rethrow();
            else
                exn_handler()->state = EXN_DONE;
            break;
        case EXN_DONE:
            exn_pop();
            ret = 0;
            break;
        default:
            fprintf(stderr, "Error: Exception handler entered an invalid state\n");
            exit(1);
            break;
    }
    return ret;
}

canonical_original_code:
_Bool exn_process() {
    _Bool ret = 1;
    switch(exn_handler()->state) {
        case EXN_BEGIN:
            exn_handler()->state = EXN_TRY;
            break;
        case EXN_TRY:
            exn_handler()->state = (!Exn_Handled) ? EXN_CATCH : EXN_FINALLY;
            break;
        case EXN_CATCH:
            exn_handler()->state = EXN_FINALLY;
            break;
        case EXN_FINALLY:
            if (!Exn_Handled)
                exn_rethrow();
            else
                exn_handler()->state = EXN_DONE;
            break;
        case EXN_DONE:
            exn_pop();
            ret = 0;
            break;
        default:
            fprintf(stderr, "Error: Exception handler entered an invalid state\n");
            exit(1);
            break;
    }
    return ret;
}


decompiled_code:
void __fastcall exn_assert(__int64 a1, int a2, char a3, __int64 a4)
{
if ( !a3 )
exn_throw(a1, a2, (__int64)&AssertionException, a4);
}

canonical_decompiled_code:
void __fastcall func9(__int64 a1, int a2, char a3, __int64 a4)
{
if ( !a3 )
func6(a1, a2, (__int64)&AssertionException, a4);
}

original_code:
void exn_assert(const char* file, int line, _Bool expr, const char* msg) {
    if(!expr) {
        exn_throw(file, line, &AssertionException, msg);
    }
}

canonical_original_code:
void exn_assert(char *file, int line, _Bool expr, char *msg) {
    if(!expr) {
        exn_throw(file, line, &AssertionException, msg);
    }
}

variable_types:
file
char *


decompiled_code:
__int64 __fastcall map_pair_new(int a1, __int64 a2, __int64 a3)
{
__int64 result; // rax

result = mem_allocate(24LL, map_pair_free);
*(_QWORD *)(result + 8) = a2;
*(_QWORD *)(result + 16) = a3;
*(_DWORD *)result = a1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1, __int64 a2, __int64 a3)
{
__int64 result; // rax

result = mem_allocate(24LL, map_pair_free);
*(_QWORD *)(result + 8) = a2;
*(_QWORD *)(result + 16) = a3;
*(_DWORD *)result = a1;
return result;
}

original_code:
static map_pair_t* map_pair_new(uint32_t hash, void* key, void* value)
{
    map_pair_t* pair = (map_pair_t*)mem_allocate(sizeof(map_pair_t), &map_pair_free);
    pair->key = key;
    pair->value = value;
    pair->hash = hash;
    return pair;
}

canonical_original_code:
static struct map_pair_t *map_pair_new(unsigned int hash, void *key, void *value)
{
    struct map_pair_t *pair = (map_pair_t*)mem_allocate(sizeof(map_pair_t), &map_pair_free);
    pair->key = key;
    pair->value = value;
    pair->hash = hash;
    return pair;
}

variable_types:
hash
unsigned int

variable_types:
key
void *

variable_types:
value
void *

variable_types: struct map_pair_t { unsigned int hash; void *key; void *value; } *


decompiled_code:
__int64 __fastcall map_compare_nodes(__int64 a1, unsigned int *a2, __int64 a3)
{
__int64 v3; // rcx
unsigned int v4; // er8

v3 = *a2;
if ( (unsigned int)v3 < *(_DWORD *)a3 )
return (unsigned int)-1;
v4 = 1;
if ( (unsigned int)v3 > *(_DWORD *)a3 )
return v4;
return cmp_compare(a1, *((_QWORD *)a2 + 1), *(_QWORD *)(a3 + 8), v3, 1LL);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, unsigned int *a2, __int64 a3)
{
__int64 v3; // rcx
unsigned int v4; // er8

v3 = *a2;
if ( (unsigned int)v3 < *(_DWORD *)a3 )
return (unsigned int)-1;
v4 = 1;
if ( (unsigned int)v3 > *(_DWORD *)a3 )
return v4;
return cmp_compare(a1, *((_QWORD *)a2 + 1), *(_QWORD *)(a3 + 8), v3, 1LL);
}

original_code:
static int map_compare_nodes(void* env, void* p_a, void* p_b)
{
    int cmp;
    cmp_t* user_comp = (cmp_t*)env;
    map_pair_t* pair_a = (map_pair_t*)p_a;
    map_pair_t* pair_b = (map_pair_t*)p_b;
    if (pair_a->hash < pair_b->hash) {
        cmp = -1;
    } else if (pair_a->hash > pair_b->hash) {
        cmp = 1;
    } else {
        cmp = cmp_compare(user_comp, pair_a->key, pair_b->key);
    }
    return cmp;
}

canonical_original_code:
static int map_compare_nodes(void *env, void *p_a, void *p_b)
{
    int cmp;
    struct cmp_t *user_comp = (cmp_t*)env;
    struct map_pair_t *pair_a = (map_pair_t*)p_a;
    struct map_pair_t *pair_b = (map_pair_t*)p_b;
    if (pair_a->hash < pair_b->hash) {
        cmp = -1;
    } else if (pair_a->hash > pair_b->hash) {
        cmp = 1;
    } else {
        cmp = cmp_compare(user_comp, pair_a->key, pair_b->key);
    }
    return cmp;
}

variable_types:
env
void *

variable_types: cmp int

variable_types: struct cmp_t { void *env; int (*fn)(void *env, void *obja, void *objb); } *

user_defined_types: struct map_pair_t { unsigned int hash; void *key; void *value; }


decompiled_code:
__int64 __fastcall map_free(__int64 a1)
{
return mem_release(*(_QWORD *)(a1 + 8));
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
return mem_release(*(_QWORD *)(a1 + 8));
}

original_code:
static void map_free(void* obj)
{
    mem_release(((map_t*)obj)->tree);
}

canonical_original_code:
static void map_free(void *obj)
{
    mem_release(((struct map_t *)obj)->tree);
}

variable_types:
obj
void *

user_defined_types: struct map_t { unsigned int (*hash_func)(void *obj); struct rbt_t *tree; }

user_defined_types: struct rbt_t { struct rbt_node_t *root; struct cmp_t *comp; }

user_defined_types: struct rbt_node_t { struct rbt_node_t *left; struct rbt_node_t *right; struct rbt_node_t *parent; enum rbt_color_t color; void *contents; }


decompiled_code:
__int64 __fastcall map_pair_free(__int64 a1)
{
__int64 v2; // rdi
__int64 result; // rax
__int64 v4; // rdi

v2 = *(_QWORD *)(a1 + 8);
if ( v2 )
result = mem_release(v2);
v4 = *(_QWORD *)(a1 + 16);
if ( v4 )
result = mem_release(v4);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1)
{
__int64 v2; // rdi
__int64 result; // rax
__int64 v4; // rdi

v2 = *(_QWORD *)(a1 + 8);
if ( v2 )
result = mem_release(v2);
v4 = *(_QWORD *)(a1 + 16);
if ( v4 )
result = mem_release(v4);
return result;
}

original_code:
static void map_pair_free(void* obj)
{
    if(((map_pair_t*)obj)->key)
        mem_release(((map_pair_t*)obj)->key);
    if(((map_pair_t*)obj)->value)
        mem_release(((map_pair_t*)obj)->value);
}

canonical_original_code:
static void map_pair_free(void *obj)
{
    if(((struct map_pair_t *)obj)->key)
        mem_release(((struct map_pair_t *)obj)->key);
    if(((struct map_pair_t *)obj)->value)
        mem_release(((struct map_pair_t *)obj)->value);
}


original_code:
_Bool map_has_key(map_t* map, void* key)
{
    map_pair_t pair = { map->hash_func(key), key, ((void *)0) };
    rbt_node_t* curr = rbt_lookup(map->tree, &pair);
    return (((void *)0) != curr);
}

canonical_original_code:
_Bool map_has_key(struct map_t *map, void *key)
{
    struct map_pair_t pair = { map->hash_func(key), key, ((void *)0) };
    struct rbt_node_t *curr = rbt_lookup(map->tree, &pair);
    return (((void *)0) != curr);
}

variable_types: struct map_t { unsigned int (*hash_func)(void *obj); struct rbt_t { struct rbt_node_t { struct rbt_node_t *left; struct rbt_node_t *right; struct rbt_node_t *parent; enum rbt_color_t { RED=0, BLACK=1 } color; void *contents; } *root; struct cmp_t { void *env; int (*fn)(void *env, void *obja, void *objb); } *comp; } *tree; } *

variable_types: struct map_pair_t { unsigned int hash; void *key; void *value; }


decompiled_code:
__int64 __fastcall map_size(__int64 a1)
{
return (int)rbt_size(*(_QWORD *)(a1 + 8));
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
return (int)rbt_size(*(_QWORD *)(a1 + 8));
}

original_code:
size_t map_size(map_t* map)
{
    return rbt_size(map->tree);
}

canonical_original_code:
unsigned long map_size(struct map_t *map)
{
    return rbt_size(map->tree);
}


decompiled_code:
__int64 __fastcall map_lookup(__int64 a1, __int64 a2)
{
__int64 result; // rax
int v3; // [rsp+0h] [rbp-38h] BYREF
__int64 v4; // [rsp+8h] [rbp-30h]
__int64 v5; // [rsp+10h] [rbp-28h]

v3 = (*(__int64 (__fastcall **)(__int64))a1)(a2);
v4 = a2;
v5 = 0LL;
result = rbt_lookup(*(_QWORD *)(a1 + 8), &v3);
if ( result )
result = *(_QWORD *)(*(_QWORD *)(result + 32) + 16LL);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, __int64 a2)
{
__int64 result; // rax
int v3; // [rsp+0h] [rbp-38h] BYREF
__int64 v4; // [rsp+8h] [rbp-30h]
__int64 v5; // [rsp+10h] [rbp-28h]

v3 = (*(__int64 (__fastcall **)(__int64))a1)(a2);
v4 = a2;
v5 = 0LL;
result = rbt_lookup(*(_QWORD *)(a1 + 8), &v3);
if ( result )
result = *(_QWORD *)(*(_QWORD *)(result + 32) + 16LL);
return result;
}

original_code:
void* map_lookup(map_t* map, void* key)
{
    map_pair_t pair = { map->hash_func(key), key, ((void *)0) };
    rbt_node_t* curr = rbt_lookup(map->tree, &pair);
    void* value = (((void *)0) == curr) ? ((void *)0) : ((map_pair_t*)curr->contents)->value;
    return value;
}

canonical_original_code:
void *map_lookup(struct map_t *map, void *key)
{
    struct map_pair_t pair = { map->hash_func(key), key, ((void *)0) };
    struct rbt_node_t *curr = rbt_lookup(map->tree, &pair);
    void *value = (((void *)0) == curr) ? ((void *)0) : ((map_pair_t*)curr->contents)->value;
    return value;
}

variable_types: struct rbt_node_t { struct rbt_node_t *left; struct rbt_node_t *right; struct rbt_node_t *parent; enum rbt_color_t { RED=0, BLACK=1 } color; void *contents; } *


decompiled_code:
__int64 __fastcall map_insert(__int64 a1, __int64 a2, __int64 a3)
{
int v4; // eax
__int64 v5; // rbp
__int64 result; // rax

v4 = (*(__int64 (__fastcall **)(__int64))a1)(a2);
v5 = map_pair_new(v4, a2, a3);
if ( rbt_lookup(*(_QWORD *)(a1 + 8), v5) )
result = mem_release(v5);
else
result = rbt_insert(*(_QWORD *)(a1 + 8), v5);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, __int64 a2, __int64 a3)
{
int v4; // eax
__int64 v5; // rbp
__int64 result; // rax

v4 = (*(__int64 (__fastcall **)(__int64))a1)(a2);
v5 = func0(v4, a2, a3);
if ( rbt_lookup(*(_QWORD *)(a1 + 8), v5) )
result = mem_release(v5);
else
result = rbt_insert(*(_QWORD *)(a1 + 8), v5);
return result;
}

original_code:
void map_insert(map_t* map, void* key, void* value)
{
    map_pair_t* pair = map_pair_new(map->hash_func(key), key, value);
    if (!rbt_lookup(map->tree, pair))
        rbt_insert(map->tree, pair);
    else
        mem_release(pair);
}

canonical_original_code:
void map_insert(struct map_t *map, void *key, void *value)
{
    struct map_pair_t *pair = map_pair_new(map->hash_func(key), key, value);
    if (!rbt_lookup(map->tree, pair))
        rbt_insert(map->tree, pair);
    else
        mem_release(pair);
}


original_code:
void map_delete(map_t* map, void* key)
{
    map_pair_t pair = { map->hash_func(key), key, ((void *)0) };
    rbt_delete(map->tree, &pair);
}

canonical_original_code:
void map_delete(struct map_t *map, void *key)
{
    struct map_pair_t pair = { map->hash_func(key), key, ((void *)0) };
    rbt_delete(map->tree, &pair);
}


decompiled_code:
__int64 __fastcall buf_size(__int64 a1)
{
return *(_QWORD *)(a1 + 8);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
return *(_QWORD *)(a1 + 8);
}

original_code:
size_t buf_size(buf_t* buf)
{
    return (size_t)buf->size;
}

canonical_original_code:
unsigned long buf_size(struct buf_t *buf)
{
    return (unsigned long)buf->size;
}

variable_types: struct buf_t { void **buffer; unsigned long size; unsigned long reads; unsigned long writes; } *


decompiled_code:
bool __fastcall buf_empty(__int64 a1)
{
return *(_QWORD *)(a1 + 16) == *(_QWORD *)(a1 + 24);
}

canonical_decompiled_code:
bool __fastcall func2(__int64 a1)
{
return *(_QWORD *)(a1 + 16) == *(_QWORD *)(a1 + 24);
}

original_code:
_Bool buf_empty(buf_t* buf)
{
    return (buf->reads == buf->writes);
}

canonical_original_code:
_Bool buf_empty(struct buf_t *buf)
{
    return (buf->reads == buf->writes);
}

user_defined_types: struct buf_t { void **buffer; unsigned long size; unsigned long reads; unsigned long writes; }


decompiled_code:
__int64 __fastcall buf_full(_QWORD *a1)
{
int v1; // eax
int v2; // esi
unsigned __int64 v3; // rcx
unsigned int v4; // eax

LOBYTE(v1) = buf_empty((__int64)a1);
v2 = v1;
v3 = a1[1];
v4 = a1[3] / v3;
LOBYTE(v4) = a1[2] % v3 == a1[3] % v3;
return (v2 ^ 1) & v4;
}

canonical_decompiled_code:
__int64 __fastcall func3(_QWORD *a1)
{
int v1; // eax
int v2; // esi
unsigned __int64 v3; // rcx
unsigned int v4; // eax

LOBYTE(v1) = func2((__int64)a1);
v2 = v1;
v3 = a1[1];
v4 = a1[3] / v3;
LOBYTE(v4) = a1[2] % v3 == a1[3] % v3;
return (v2 ^ 1) & v4;
}

original_code:
_Bool buf_full(buf_t* buf)
{
    int full = !buf_empty(buf);
    full &= ((buf->reads % buf->size) == (buf->writes % buf->size));
    return full;
}

canonical_original_code:
_Bool buf_full(struct buf_t *buf)
{
    int full = !buf_empty(buf);
    full &= ((buf->reads % buf->size) == (buf->writes % buf->size));
    return full;
}

variable_types: full int


decompiled_code:
__int64 __fastcall buf_read(_QWORD *a1)
{
bool v1; // dl
__int64 result; // rax

v1 = buf_empty((__int64)a1);
result = 0LL;
if ( !v1 )
{
result = *(_QWORD *)(*a1 + 8LL * (a1[2] % a1[1]));
++a1[2];
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(_QWORD *a1)
{
bool v1; // dl
__int64 result; // rax

v1 = func2((__int64)a1);
result = 0LL;
if ( !v1 )
{
result = *(_QWORD *)(*a1 + 8LL * (a1[2] % a1[1]));
++a1[2];
}
return result;
}

original_code:
void* buf_read(buf_t* buf)
{
    void* data = ((void *)0);
    if (!buf_empty(buf))
    {
        data = buf->buffer[ buf->reads % buf->size ];
        buf->reads++;
    }
    return data;
}

canonical_original_code:
void *buf_read(struct buf_t *buf)
{
    void *data = ((void *)0);
    if (!buf_empty(buf))
    {
        data = buf->buffer[ buf->reads % buf->size ];
        buf->reads++;
    }
    return data;
}

variable_types:
data
void *


decompiled_code:
bool __fastcall buf_clear(_QWORD *a1)
{
bool result; // al
__int64 v2; // rax

while ( 1 )
{
result = buf_empty((__int64)a1);
if ( result )
break;
v2 = buf_read(a1);
if ( v2 )
mem_release(v2);
}
a1[2] = 0LL;
a1[3] = 0LL;
return result;
}

canonical_decompiled_code:
bool __fastcall func5(_QWORD *a1)
{
bool result; // al
__int64 v2; // rax

while ( 1 )
{
result = func2((__int64)a1);
if ( result )
break;
v2 = func4(a1);
if ( v2 )
mem_release(v2);
}
a1[2] = 0LL;
a1[3] = 0LL;
return result;
}

original_code:
void buf_clear(buf_t* buf)
{
    void* entry;
    while ( !buf_empty(buf) )
    {
        entry = buf_read(buf);
        if (((void *)0) != entry)
            mem_release( entry );
    }
    buf->reads = 0;
    buf->writes = 0;
}

canonical_original_code:
void buf_clear(struct buf_t *buf)
{
    void *entry;
    while ( !buf_empty(buf) )
    {
        entry = buf_read(buf);
        if (((void *)0) != entry)
            mem_release( entry );
    }
    buf->reads = 0;
    buf->writes = 0;
}

variable_types:
entry
void *


decompiled_code:
void __fastcall buf_free(void **a1)
{
buf_clear(a1);
free(*a1);
}

canonical_decompiled_code:
void __fastcall func6(void **a1)
{
func5(a1);
free(*a1);
}

original_code:
static void buf_free(void* p_buf)
{
    buf_clear((buf_t*)p_buf);
    free( ((buf_t*)p_buf)->buffer );
}

canonical_original_code:
static void buf_free(void *p_buf)
{
    buf_clear((struct buf_t *)p_buf);
    free( ((struct buf_t *)p_buf)->buffer );
}


decompiled_code:
__int64 __fastcall buf_write(_QWORD *a1, __int64 a2)
{
char v2; // dl
__int64 result; // rax

v2 = buf_full(a1);
result = 0LL;
if ( !v2 )
{
*(_QWORD *)(*a1 + 8LL * (a1[3] % a1[1])) = a2;
++a1[3];
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(_QWORD *a1, __int64 a2)
{
char v2; // dl
__int64 result; // rax

v2 = func3(a1);
result = 0LL;
if ( !v2 )
{
*(_QWORD *)(*a1 + 8LL * (a1[3] % a1[1])) = a2;
++a1[3];
result = 1LL;
}
return result;
}

original_code:
_Bool buf_write(buf_t* buf, void* data)
{
    _Bool success = 0;
    if (!buf_full(buf))
    {
        buf->buffer[ buf->writes % buf->size ] = data;
        buf->writes++;
        success = 1;
    }
    return success;
}

canonical_original_code:
_Bool buf_write(struct buf_t *buf, void *data)
{
    _Bool success = 0;
    if (!buf_full(buf))
    {
        buf->buffer[ buf->writes % buf->size ] = data;
        buf->writes++;
        success = 1;
    }
    return success;
}


decompiled_code:
__int64 __fastcall rbt_default_compare(__int64 a1, unsigned __int64 a2, unsigned __int64 a3)
{
__int64 result; // rax

result = 0LL;
if ( a2 != a3 )
result = a2 < a3 ? -1 : 1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, unsigned __int64 a2, unsigned __int64 a3)
{
__int64 result; // rax

result = 0LL;
if ( a2 != a3 )
result = a2 < a3 ? -1 : 1;
return result;
}

original_code:
static int rbt_default_compare(void* env, void* v_a, void* v_b){
    uintptr_t a = (uintptr_t)v_a;
    uintptr_t b = (uintptr_t)v_b;
    (void)env;
    return (a == b ? 0 : (a<b ? -1 : 1 ));
}

canonical_original_code:
static int rbt_default_compare(void *env, void *v_a, void *v_b){
    unsigned long a = (uintptr_t)v_a;
    unsigned long b = (uintptr_t)v_b;
    (void)env;
    return (a == b ? 0 : (a<b ? -1 : 1 ));
}

variable_types:
a
unsigned long

variable_types:
b
unsigned long


decompiled_code:
__int64 __fastcall rightmost_descendant(__int64 a1)
{
__int64 result; // rax

result = a1;
if ( *(_QWORD *)(a1 + 8) )
result = rightmost_descendant();
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
__int64 result; // rax

result = a1;
if ( *(_QWORD *)(a1 + 8) )
result = func1();
return result;
}

original_code:
static rbt_node_t* rightmost_descendant(rbt_node_t* node){
    return (node->right) ? rightmost_descendant(node->right) : node;
}

canonical_original_code:
static struct rbt_node_t *rightmost_descendant(struct rbt_node_t *node){
    return (node->right) ? rightmost_descendant(node->right) : node;
}

variable_types:
node
struct rbt_node_t *

return_type: struct rbt_node_t { struct rbt_node_t *left; struct rbt_node_t *right; struct rbt_node_t *parent; enum rbt_color_t { RED=0, BLACK=1 } color; void *contents; } *


decompiled_code:
__int64 __fastcall rbt_count(_QWORD *a1)
{
__int64 result; // rax
int v2; // ebp

result = 0LL;
if ( a1 )
{
v2 = rbt_count(*a1);
result = v2 + (unsigned int)rbt_count(a1[1]) + 1;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(_QWORD *a1)
{
__int64 result; // rax
int v2; // ebp

result = 0LL;
if ( a1 )
{
v2 = func2(*a1);
result = v2 + (unsigned int)func2(a1[1]) + 1;
}
return result;
}

original_code:
static int rbt_count(rbt_node_t* node){
    return (!node ? 0 : (1 + rbt_count(node->left) + rbt_count(node->right)));
}

canonical_original_code:
static int rbt_count(struct rbt_node_t *node){
    return (!node ? 0 : (1 + rbt_count(node->left) + rbt_count(node->right)));
}


decompiled_code:
__int64 __fastcall rbt_free(_QWORD *a1)
{
__int64 result; // rax

result = exn_assert("source/rbt/rbt.c", 22LL, a1 != 0LL, "NULL != tree");
if ( *a1 )
result = mem_release();
if ( a1[1] )
result = mem_release();
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(_QWORD *a1)
{
__int64 result; // rax

result = exn_assert("source/rbt/rbt.c", 22LL, a1 != 0LL, "NULL != tree");
if ( *a1 )
result = mem_release();
if ( a1[1] )
result = mem_release();
return result;
}

original_code:
static void rbt_free(void* v_tree){
    rbt_t* tree = (rbt_t*) v_tree;
    exn_assert("source/rbt/rbt.c",22,((void *)0) != tree,"NULL != tree");
    if(tree->root) mem_release(tree->root);
    if(tree->comp) mem_release(tree->comp);
}

canonical_original_code:
static void rbt_free(void *v_tree){
    struct rbt_t *tree = (rbt_t*) v_tree;
    exn_assert("source/rbt/rbt.c",22,((void *)0) != tree,"NULL != tree");
    if(tree->root) mem_release(tree->root);
    if(tree->comp) mem_release(tree->comp);
}

variable_types: struct rbt_t { struct rbt_node_t { struct rbt_node_t *left; struct rbt_node_t *right; struct rbt_node_t *parent; enum rbt_color_t { RED=0, BLACK=1 } color; void *contents; } *root; struct cmp_t { void *env; int (*fn)(void *env, void *obja, void *objb); } *comp; } *


decompiled_code:
__int64 __fastcall rbt_node_free(__int64 *a1)
{
__int64 result; // rax
__int64 v3; // rdi
__int64 v4; // rdi

exn_assert("source/rbt/rbt.c", 37LL, a1 != 0LL, "NULL != node");
result = mem_release(a1[4]);
v3 = *a1;
if ( v3 )
result = mem_release(v3);
v4 = a1[1];
if ( v4 )
result = mem_release(v4);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 *a1)
{
__int64 result; // rax
__int64 v3; // rdi
__int64 v4; // rdi

exn_assert("source/rbt/rbt.c", 37LL, a1 != 0LL, "NULL != node");
result = mem_release(a1[4]);
v3 = *a1;
if ( v3 )
result = mem_release(v3);
v4 = a1[1];
if ( v4 )
result = mem_release(v4);
return result;
}

original_code:
static void rbt_node_free(void* v_node){
    rbt_node_t* node = (rbt_node_t*) v_node;
    exn_assert("source/rbt/rbt.c",37,((void *)0) != node,"NULL != node");
    mem_release(node->contents);
    if(node->left) mem_release(node->left);
    if(node->right) mem_release(node->right);
}

canonical_original_code:
static void rbt_node_free(void *v_node){
    struct rbt_node_t *node = (rbt_node_t*) v_node;
    exn_assert("source/rbt/rbt.c",37,((void *)0) != node,"NULL != node");
    mem_release(node->contents);
    if(node->left) mem_release(node->left);
    if(node->right) mem_release(node->right);
}


decompiled_code:
__int64 __fastcall rbt_node_new(__int64 a1)
{
__int64 result; // rax

result = mem_allocate(40LL, rbt_node_free);
*(_QWORD *)result = 0LL;
*(_QWORD *)(result + 8) = 0LL;
*(_QWORD *)(result + 16) = 0LL;
*(_QWORD *)(result + 32) = a1;
*(_DWORD *)(result + 24) = 0;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1)
{
__int64 result; // rax

result = mem_allocate(40LL, rbt_node_free);
*(_QWORD *)result = 0LL;
*(_QWORD *)(result + 8) = 0LL;
*(_QWORD *)(result + 16) = 0LL;
*(_QWORD *)(result + 32) = a1;
*(_DWORD *)(result + 24) = 0;
return result;
}

original_code:
rbt_node_t* rbt_node_new(void* contents){
    rbt_node_t* node = mem_allocate(sizeof(rbt_node_t), &rbt_node_free);
    node->left = ((void *)0);
    node->right = ((void *)0);
    node->parent = ((void *)0);
    node->contents = contents;
    node->color = RED;
    return node;
}

canonical_original_code:
struct rbt_node_t *rbt_node_new(void *contents){
    struct rbt_node_t *node = mem_allocate(sizeof(rbt_node_t), &rbt_node_free);
    node->left = ((void *)0);
    node->right = ((void *)0);
    node->parent = ((void *)0);
    node->contents = contents;
    node->color = RED;
    return node;
}

variable_types:
contents
void *


decompiled_code:
__int64 __fastcall rbt_node_color(__int64 a1)
{
__int64 result; // rax

result = 1LL;
if ( a1 )
result = *(unsigned int *)(a1 + 24);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1)
{
__int64 result; // rax

result = 1LL;
if ( a1 )
result = *(unsigned int *)(a1 + 24);
return result;
}

original_code:
rbt_color_t rbt_node_color(rbt_node_t* node){
    return (node ? node->color : BLACK);
}

canonical_original_code:
enum rbt_color_t rbt_node_color(struct rbt_node_t *node){
    return (node ? node->color : BLACK);
}

return_type: enum rbt_color_t { RED=0, BLACK=1 }


original_code:
static void rbt_ins_recolor(rbt_t* tree, rbt_node_t* node){
    rbt_node_t* parent = node->parent;
    rbt_node_t* grandparent = (parent ? parent->parent : ((void *)0));
    rbt_node_t* uncle = (grandparent ? (parent == grandparent->left ? grandparent->right : grandparent->left) : ((void *)0));
    if(((void *)0) == parent){
        node->color = BLACK;
    }else if(RED == rbt_node_color(parent)){
        if(rbt_node_color(uncle) == RED){
            grandparent->color = RED;
            parent->color = BLACK;
            uncle->color = BLACK;
            rbt_ins_recolor(tree, grandparent);
        }else{
            direction_t node_side = (node == parent->left ? LEFT : RIGHT);
            direction_t parent_side = (parent == grandparent->left ? LEFT : RIGHT);
            if(node_side != parent_side){
                rbt_rotate(tree, parent, parent_side);
                node = parent;
            }
            rbt_ins_rebalance(tree, node, parent_side);
        }
    }
}

canonical_original_code:
static void rbt_ins_recolor(struct rbt_t *tree, struct rbt_node_t *node){
    struct rbt_node_t *parent = node->parent;
    struct rbt_node_t *grandparent = (parent ? parent->parent : ((void *)0));
    struct rbt_node_t *uncle = (grandparent ? (parent == grandparent->left ? grandparent->right : grandparent->left) : ((void *)0));
    if(((void *)0) == parent){
        node->color = BLACK;
    }else if(RED == rbt_node_color(parent)){
        if(rbt_node_color(uncle) == RED){
            grandparent->color = RED;
            parent->color = BLACK;
            uncle->color = BLACK;
            rbt_ins_recolor(tree, grandparent);
        }else{
            enum direction_t node_side = (node == parent->left ? LEFT : RIGHT);
            enum direction_t parent_side = (parent == grandparent->left ? LEFT : RIGHT);
            if(node_side != parent_side){
                rbt_rotate(tree, parent, parent_side);
                node = parent;
            }
            rbt_ins_rebalance(tree, node, parent_side);
        }
    }
}


original_code:
static void rbt_insert_node(rbt_t* tree, rbt_node_t* node, rbt_node_t* parent){
    if(((void *)0) == parent){
        tree->root = node;
        rbt_ins_recolor(tree, node);
    }else{
        int c = cmp_compare(tree->comp, node->contents, parent->contents);
        rbt_node_t** relevant_child = (c<0 ? &(parent->left) : &(parent->right));
        if(*relevant_child){
            rbt_insert_node(tree, node, *relevant_child);
        }else{
            node->parent = parent;
            *relevant_child = node;
            rbt_ins_recolor(tree, node);
        }
    }
}

canonical_original_code:
static void rbt_insert_node(struct rbt_t *tree, struct rbt_node_t *node, struct rbt_node_t *parent){
    if(((void *)0) == parent){
        tree->root = node;
        rbt_ins_recolor(tree, node);
    }else{
        int c = cmp_compare(tree->comp, node->contents, parent->contents);
        struct rbt_node_t **relevant_child = (c<0 ? &(parent->left) : &(parent->right));
        if(*relevant_child){
            rbt_insert_node(tree, node, *relevant_child);
        }else{
            node->parent = parent;
            *relevant_child = node;
            rbt_ins_recolor(tree, node);
        }
    }
}

variable_types:
parent
struct rbt_node_t *

variable_types: c int

variable_types: struct rbt_node_t { struct rbt_node_t *left; struct rbt_node_t *right; struct rbt_node_t *parent; enum rbt_color_t { RED=0, BLACK=1 } color; void *contents; } **


decompiled_code:
__int64 __fastcall rbt_delete_node(_QWORD *a1, __int64 a2)
{
__int64 v2; // rbp
__int64 v3; // rax

v2 = *(_QWORD *)a2;
if ( *(_QWORD *)a2 && *(_QWORD *)(a2 + 8) )
{
v2 = rightmost_descendant(*(_QWORD *)a2);
mem_retain(v2);
rbt_delete_node(a1, v2);
if ( *(_QWORD *)a2 )
*(_QWORD *)(*(_QWORD *)a2 + 16LL) = v2;
v3 = *(_QWORD *)(a2 + 8);
if ( v3 )
*(_QWORD *)(v3 + 16) = v2;
*(_QWORD *)v2 = *(_QWORD *)a2;
*(_QWORD *)(v2 + 8) = *(_QWORD *)(a2 + 8);
*(_DWORD *)(v2 + 24) = *(_DWORD *)(a2 + 24);
}
else if ( (unsigned int)rbt_node_color(a2) == 1 )
{
if ( (unsigned int)rbt_node_color(v2) && (unsigned int)rbt_node_color(*(_QWORD *)(a2 + 8)) )
{
rbt_del_rebalance(a1, (__int64 *)a2);
v2 = 0LL;
}
else
{
if ( !v2 )
v2 = *(_QWORD *)(a2 + 8);
*(_DWORD *)(v2 + 24) = 1;
}
}
else
{
v2 = 0LL;
}
rbt_node_replace(a1, a2, v2);
*(_QWORD *)a2 = 0LL;
*(_QWORD *)(a2 + 8) = 0LL;
*(_QWORD *)(a2 + 16) = 0LL;
return mem_release(a2);
}

original_code:
static void rbt_delete_node(rbt_t* tree, rbt_node_t* node){
    rbt_node_t* descendant = ((void *)0);
    if(node->left && node->right){
        descendant = rightmost_descendant(node->left);
        mem_retain(descendant);
        rbt_delete_node(tree, descendant);
        if(node->left) node->left->parent = descendant;
        if(node->right) node->right->parent = descendant;
        descendant->left = node->left;
        descendant->right = node->right;
        descendant->color = node->color;
    }else if(BLACK == rbt_node_color(node)){
        if(RED == rbt_node_color(node->left) || RED == rbt_node_color(node->right)){
            descendant = node->left ? node->left : node->right;
            descendant->color = BLACK;
        } else {
            rbt_del_rebalance(tree, node);
        }
    }
    rbt_node_replace(tree, node, descendant);
    node->left = ((void *)0);
    node->right = ((void *)0);
    node->parent = ((void *)0);
    mem_release(node);
}

canonical_original_code:
static void rbt_delete_node(struct rbt_t *tree, struct rbt_node_t *node){
    struct rbt_node_t *descendant = ((void *)0);
    if(node->left && node->right){
        descendant = rightmost_descendant(node->left);
        mem_retain(descendant);
        rbt_delete_node(tree, descendant);
        if(node->left) node->left->parent = descendant;
        if(node->right) node->right->parent = descendant;
        descendant->left = node->left;
        descendant->right = node->right;
        descendant->color = node->color;
    }else if(BLACK == rbt_node_color(node)){
        if(RED == rbt_node_color(node->left) || RED == rbt_node_color(node->right)){
            descendant = node->left ? node->left : node->right;
            descendant->color = BLACK;
        } else {
            rbt_del_rebalance(tree, node);
        }
    }
    rbt_node_replace(tree, node, descendant);
    node->left = ((void *)0);
    node->right = ((void *)0);
    node->parent = ((void *)0);
    mem_release(node);
}


decompiled_code:
__int64 __fastcall rbt_size(_QWORD **a1)
{
return rbt_count(*a1);
}

canonical_decompiled_code:
__int64 __fastcall func15(_QWORD **a1)
{
return func2(*a1);
}

original_code:
int rbt_size(rbt_t* tree){
    return rbt_count(tree->root);
}

canonical_original_code:
int rbt_size(struct rbt_t *tree){
    return rbt_count(tree->root);
}


decompiled_code:
__int64 __fastcall rbt_insert(__int64 *a1, __int64 a2)
{
__int64 v2; // rbx

v2 = rbt_node_new(a2);
rbt_insert_node(a1, v2, (__int64 *)*a1);
return v2;
}

original_code:
rbt_node_t* rbt_insert(rbt_t* tree, void* value){
    rbt_node_t* new_node = rbt_node_new(value);
    rbt_insert_node(tree, new_node, tree->root);
    return new_node;
}

canonical_original_code:
struct rbt_node_t *rbt_insert(struct rbt_t *tree, void *value){
    struct rbt_node_t *new_node = rbt_node_new(value);
    rbt_insert_node(tree, new_node, tree->root);
    return new_node;
}

variable_types: struct rbt_t { struct rbt_node_t *root; struct cmp_t { void *env; int (*fn)(void *env, void *obja, void *objb); } *comp; } *

variable_types:
value
void *


decompiled_code:
__int64 __fastcall rbt_delete(_QWORD **a1, __int64 a2)
{
__int64 result; // rax

result = rbt_lookup(a1, a2);
if ( result )
result = rbt_delete_node(a1, result);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func17(_QWORD **a1, __int64 a2)
{
__int64 result; // rax

result = func14(a1, a2);
if ( result )
result = func13(a1, result);
return result;
}

original_code:
void rbt_delete(rbt_t* tree, void* value){
    rbt_node_t* doomed = rbt_lookup(tree, value);
    if(doomed) rbt_delete_node(tree, doomed);
}

canonical_original_code:
void rbt_delete(struct rbt_t *tree, void *value){
    struct rbt_node_t *doomed = rbt_lookup(tree, value);
    if(doomed) rbt_delete_node(tree, doomed);
}


decompiled_code:
__int64 __fastcall mem_refcount(__int64 a1)
{
exn_assert("source/mem/mem.c", 52LL, a1 != 0, "NULL != p_obj");
return *(unsigned int *)(a1 - 16);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
exn_assert("source/mem/mem.c", 52LL, a1 != 0, "NULL != p_obj");
return *(unsigned int *)(a1 - 16);
}

original_code:
int mem_refcount(void* p_obj)
{
    obj_t* p_hdr;
    exn_assert("source/mem/mem.c",52,((void *)0) != p_obj,"NULL != p_obj");
    p_hdr = (((obj_t*)p_obj)-1);
    return p_hdr->refcount;
}

canonical_original_code:
int mem_refcount(void *p_obj)
{
    struct obj_t *p_hdr;
    exn_assert("source/mem/mem.c",52,((void *)0) != p_obj,"NULL != p_obj");
    p_hdr = (((struct obj_t *)p_obj)-1);
    return p_hdr->refcount;
}

variable_types: struct obj_t { int refcount; void (*p_finalize)(void *p_val); } *


decompiled_code:
__int64 __fastcall mem_retain(__int64 a1)
{
exn_assert("source/mem/mem.c", 60LL, a1 != 0, "NULL != p_obj");
++*(_DWORD *)(a1 - 16);
return a1;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1)
{
exn_assert("source/mem/mem.c", 60LL, a1 != 0, "NULL != p_obj");
++*(_DWORD *)(a1 - 16);
return a1;
}

original_code:
void* mem_retain(void* p_obj)
{
    obj_t* p_hdr;
    exn_assert("source/mem/mem.c",60,((void *)0) != p_obj,"NULL != p_obj");
    p_hdr = (((obj_t*)p_obj)-1);
    p_hdr->refcount += 1;
    return p_obj;
}

canonical_original_code:
void *mem_retain(void *p_obj)
{
    struct obj_t *p_hdr;
    exn_assert("source/mem/mem.c",60,((void *)0) != p_obj,"NULL != p_obj");
    p_hdr = (((struct obj_t *)p_obj)-1);
    p_hdr->refcount += 1;
    return p_obj;
}

user_defined_types: struct obj_t { int refcount; void (*p_finalize)(void *p_val); }


original_code:
void mem_release(void* p_obj)
{
    obj_t* p_hdr;
    if (((void *)0) != p_obj) {
        p_hdr = (((obj_t*)p_obj)-1);
        p_hdr->refcount -= 1;
        if(p_hdr->refcount < 1)
        {
            if(p_hdr->p_finalize)
            {
                p_hdr->p_finalize(p_obj);
            }
            free(p_hdr);
        }
    }
}

canonical_original_code:
void mem_release(void *p_obj)
{
    struct obj_t *p_hdr;
    if (((void *)0) != p_obj) {
        p_hdr = (((struct obj_t *)p_obj)-1);
        p_hdr->refcount -= 1;
        if(p_hdr->refcount < 1)
        {
            if(p_hdr->p_finalize)
            {
                p_hdr->p_finalize(p_obj);
            }
            free(p_hdr);
        }
    }
}


decompiled_code:
void __fastcall mem_swap(__int64 *a1, __int64 a2)
{
__int64 v2; // rax

v2 = *a1;
*a1 = a2;
mem_release(v2);
}

original_code:
void mem_swap(void** loc, void* obj)
{
    void* old = *loc;
    *loc = obj;
    mem_release(old);
}

canonical_original_code:
void mem_swap(void **loc, void *obj)
{
    void *old = *loc;
    *loc = obj;
    mem_release(old);
}

variable_types:
loc
void **

variable_types:
obj
void *

variable_types:
old
void *


decompiled_code:
__int64 __fastcall mem_unbox(__int64 a1)
{
exn_assert("source/mem/mem.c", 102LL, a1 != 0, "NULL != p_box");
return *(_QWORD *)a1;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1)
{
exn_assert("source/mem/mem.c", 102LL, a1 != 0, "NULL != p_box");
return *(_QWORD *)a1;
}

original_code:
intptr_t mem_unbox(void* p_box)
{
    exn_assert("source/mem/mem.c",102,((void *)0) != p_box,"NULL != p_box");
    return ((box_t*)p_box)->val;
}

canonical_original_code:
long mem_unbox(void *p_box)
{
    exn_assert("source/mem/mem.c",102,((void *)0) != p_box,"NULL != p_box");
    return ((struct box_t *)p_box)->val;
}

return_type: long


original_code:
uint32_t murmur3_32(const uint8_t* data, size_t nbytes)
{
    uint32_t hash = 0;
    const uint32_t c1 = 0xcc9e2d51;
    const uint32_t c2 = 0x1b873593;
    const int nblocks = nbytes / sizeof(uint32_t);
    const uint32_t* blocks = (const uint32_t *) (data);
    const uint8_t* tail = (const uint8_t *) (data + (nblocks * 4));
    if (data != ((void *)0) || nbytes != 0) {
        uint32_t blk;
        for (int i = 0; i < nblocks; i++) {
            blk = blocks[i];
            blk = blk * c1;
            blk = (blk << 15) | (blk >> (32 - 15));
            blk = blk * c2;
            hash = hash ^ blk;
            hash = (hash << 13) | (hash >> (32 - 13));
            hash = (hash * 5) + 0xe6546b64;
        }
        blk = 0;
        switch (nbytes & 3) {
            case 3:
                blk ^= tail[2] << 16;
            case 2:
                blk ^= tail[1] << 8;
            case 1:
                blk ^= tail[0];
                blk *= c1;
                blk = (blk << 15) | (blk >> (32 - 15));
                blk *= c2;
                hash ^= blk;
        };
        hash = hash ^ nbytes;
        hash = hash ^ (hash >> 16);
        hash = hash * (0x85ebca6b);
        hash = hash ^ (hash >> 13);
        hash = hash * (0xc2b2ae35);
        hash = hash ^ (hash >> 16);
    }
    return hash;
}

canonical_original_code:
unsigned int murmur3_32(unsigned char *data, unsigned long nbytes)
{
    unsigned int hash = 0;
    unsigned int c1 = 0xcc9e2d51;
    unsigned int c2 = 0x1b873593;
    int nblocks = nbytes / sizeof(uint32_t);
    unsigned int *blocks = (const uint32_t *) (data);
    unsigned char *tail = (const uint8_t *) (data + (nblocks * 4));
    if (data != ((void *)0) || nbytes != 0) {
        unsigned int blk;
        for (int i = 0; i < nblocks; i++) {
            blk = blocks[i];
            blk = blk * c1;
            blk = (blk << 15) | (blk >> (32 - 15));
            blk = blk * c2;
            hash = hash ^ blk;
            hash = (hash << 13) | (hash >> (32 - 13));
            hash = (hash * 5) + 0xe6546b64;
        }
        blk = 0;
        switch (nbytes & 3) {
            case 3:
                blk ^= tail[2] << 16;
            case 2:
                blk ^= tail[1] << 8;
            case 1:
                blk ^= tail[0];
                blk *= c1;
                blk = (blk << 15) | (blk >> (32 - 15));
                blk *= c2;
                hash ^= blk;
        };
        hash = hash ^ nbytes;
        hash = hash ^ (hash >> 16);
        hash = hash * (0x85ebca6b);
        hash = hash ^ (hash >> 13);
        hash = hash * (0xc2b2ae35);
        hash = hash ^ (hash >> 16);
    }
    return hash;
}

variable_types:
data
unsigned char *

variable_types:
nbytes
unsigned long

variable_types:
hash
unsigned int

variable_types: nblocks int

variable_types:
blocks
unsigned int *

variable_types:
tail
unsigned char *

variable_types:
blk
unsigned int

variable_types: i int

return_type: unsigned int


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
Vector(argc, argv, envp);
List();
Buffer();
String();
RBT();
Exn();
Set();
Map();
return test_print_results();
}

original_code:
int main(int argc, char** argv)
{
    (void)argc;
    (void)argv;
    extern void Vector(void); Vector();;
    extern void List(void); List();;
    extern void Buffer(void); Buffer();;
    extern void String(void); String();;
    extern void RBT(void); RBT();;
    extern void Exn(void); Exn();;
    extern void Set(void); Set();;
    extern void Map(void); Map();;
    return test_print_results();
}

canonical_original_code:
int main(int argc, char **argv)
{
    (void)argc;
    (void)argv;
    extern void Vector(); Vector();;
    extern void List(); List();;
    extern void Buffer(); Buffer();;
    extern void String(); String();;
    extern void RBT(); RBT();;
    extern void Exn(); Exn();;
    extern void Set(); Set();;
    extern void Map(); Map();;
    return test_print_results();
}

variable_types: argc int

variable_types:
argv
char **

variable_types:
Vector
void ()

variable_types:
List
void ()

variable_types:
Buffer
void ()

variable_types:
String
void ()

variable_types:
RBT
void ()

variable_types:
Exn
void ()

variable_types:
Set
void ()

variable_types:
Map
void ()


decompiled_code:
__int64 __fastcall cmp_int(__int64 a1, __int64 a2, __int64 a3)
{
unsigned __int64 v4; // rbx
unsigned __int64 v5; // rax
unsigned int v6; // edx

v4 = mem_unbox(a2);
v5 = mem_unbox(a3);
v6 = -1;
if ( v4 >= v5 )
v6 = v4 > v5;
return v6;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2, __int64 a3)
{
unsigned __int64 v4; // rbx
unsigned __int64 v5; // rax
unsigned int v6; // edx

v4 = mem_unbox(a2);
v5 = mem_unbox(a3);
v6 = -1;
if ( v4 >= v5 )
v6 = v4 > v5;
return v6;
}

original_code:
static int cmp_int(void* env, void* obja, void* objb) {
    uintptr_t inta = mem_unbox(obja);
    uintptr_t intb = mem_unbox(objb);
    (void)env;
    if (inta < intb)
        return -1;
    else if (intb < inta)
        return 1;
    else
        return 0;
}

canonical_original_code:
static int cmp_int(void *env, void *obja, void *objb) {
    unsigned long inta = mem_unbox(obja);
    unsigned long intb = mem_unbox(objb);
    (void)env;
    if (inta < intb)
        return -1;
    else if (intb < inta)
        return 1;
    else
        return 0;
}

variable_types:
env
void *

variable_types:
obja
void *

variable_types:
objb
void *

variable_types:
inta
unsigned long

variable_types:
intb
unsigned long


decompiled_code:
__int64 __fastcall hash_int(__int64 a1)
{
__int64 v2; // [rsp+8h] [rbp-10h] BYREF

v2 = mem_unbox(a1);
return murmur3_32(&v2, 8LL);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
__int64 v2; // [rsp+8h] [rbp-10h] BYREF

v2 = mem_unbox(a1);
return murmur3_32(&v2, 8LL);
}

original_code:
static uint32_t hash_int(void* obj) {
    intptr_t val = mem_unbox(obj);
    return murmur3_32((uint8_t*)&val, sizeof(intptr_t));
}

canonical_original_code:
static unsigned int hash_int(void *obj) {
    long val = mem_unbox(obj);
    return murmur3_32((unsigned char *)&val, sizeof(long));
}

variable_types:
obj
void *

variable_types: val long


repo: mikedlowis/opts

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rdx

atf_run_suite(&Opts, argv, envp);
atf_run_suite(&Arg, argv, v3);
return atf_print_results();
}

original_code:
int main(int argc, char** argv)
{
    (void)argc;
    (void)argv;
    do { extern void Opts(void); atf_run_suite(&Opts); } while(0);
    do { extern void Arg(void); atf_run_suite(&Arg); } while(0);
    return atf_print_results();
}

canonical_original_code:
int main(int argc, char **argv)
{
    (void)argc;
    (void)argv;
    do { extern void Opts(); atf_run_suite(&Opts); } while(0);
    do { extern void Arg(); atf_run_suite(&Arg); } while(0);
    return atf_print_results();
}

variable_types: argc int

variable_types:
Opts
void ()

variable_types:
Arg
void ()


decompiled_code:
__int64 __fastcall opts_next_char(unsigned int *a1)
{
unsigned int v1; // edx
unsigned int v2; // eax
__int64 result; // rax

a1[6] = -1;
v1 = *a1;
if ( *a1 >= a1[2] )
return 0xFFFFFFFFLL;
v2 = a1[1] + 1;
a1[1] = v2;
result = *(unsigned __int8 *)(*(_QWORD *)(*((_QWORD *)a1 + 2) + 8LL * v1) + v2);
if ( (_BYTE)result )
{
if ( (_BYTE)result == 61 )
result = 32LL;
a1[6] = (char)result;
}
else
{
a1[1] = -1;
*a1 = v1 + 1;
a1[6] = 32;
result = 32LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(unsigned int *a1)
{
unsigned int v1; // edx
unsigned int v2; // eax
__int64 result; // rax

a1[6] = -1;
v1 = *a1;
if ( *a1 >= a1[2] )
return 0xFFFFFFFFLL;
v2 = a1[1] + 1;
a1[1] = v2;
result = *(unsigned __int8 *)(*(_QWORD *)(*((_QWORD *)a1 + 2) + 8LL * v1) + v2);
if ( (_BYTE)result )
{
if ( (_BYTE)result == 61 )
result = 32LL;
a1[6] = (char)result;
}
else
{
a1[1] = -1;
*a1 = v1 + 1;
a1[6] = 32;
result = 32LL;
}
return result;
}

original_code:
static char opts_next_char( stream_ctx_t* ctx ) {
    char current = (-1);
    ctx->current = (-1);
    if (ctx->line_idx < ctx->arg_count) {
        ctx->col_idx++;
        if (ctx->line_idx < ctx->arg_count) {
            char temp = ctx->arg_vect[ ctx->line_idx ][ ctx->col_idx ];
            if (temp == '\0') {
                ctx->col_idx = -1;
                ctx->line_idx++;
                current = ' ';
                ctx->current = current;
            } else {
                temp = (temp == '=') ? ' ' : temp;
                current = temp;
                ctx->current = current;
            }
        }
    }
    return current;
}

canonical_original_code:
static char opts_next_char(struct stream_ctx_t *ctx) {
    char current = (-1);
    ctx->current = (-1);
    if (ctx->line_idx < ctx->arg_count) {
        ctx->col_idx++;
        if (ctx->line_idx < ctx->arg_count) {
            char temp = ctx->arg_vect[ ctx->line_idx ][ ctx->col_idx ];
            if (temp == '\0') {
                ctx->col_idx = -1;
                ctx->line_idx++;
                current = ' ';
                ctx->current = current;
            } else {
                temp = (temp == '=') ? ' ' : temp;
                current = temp;
                ctx->current = current;
            }
        }
    }
    return current;
}

variable_types: struct stream_ctx_t { unsigned int line_idx; unsigned int col_idx; unsigned int arg_count; char **arg_vect; int current; struct opts_cfg_t { char *name; _Bool has_arg; char *tag; char *desc; } *options; } *

variable_types: current char

variable_types: temp char

user_defined_types: struct stream_ctx_t { unsigned int line_idx; unsigned int col_idx; unsigned int arg_count; char **arg_vect; int current; struct opts_cfg_t *options; }


decompiled_code:
__int64 __fastcall opts_consume_ws(unsigned int *a1)
{
__int64 result; // rax

for ( ; a1[6] == 32; result = opts_next_char(a1) )
;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned int *a1)
{
__int64 result; // rax

for ( ; a1[6] == 32; result = func0(a1) )
;
return result;
}

original_code:
static void opts_consume_ws( stream_ctx_t* ctx ) {
    while (' ' == ctx->current)
        (void)opts_next_char( ctx );
}

canonical_original_code:
static void opts_consume_ws(struct stream_ctx_t *ctx) {
    while (' ' == ctx->current)
        (void)opts_next_char( ctx );
}

user_defined_types: struct opts_cfg_t { char *name; _Bool has_arg; char *tag; char *desc; }


decompiled_code:
__int64 __fastcall opts_calc_padding(const char **a1)
{
const char **v1; // rbx
const char *v2; // rdi
size_t v3; // rbp
char v4; // r12
size_t v5; // rax
int v6; // eax

v1 = a1;
v2 = *a1;
if ( v2 )
{
v3 = 0LL;
v4 = 0;
do
{
v5 = strlen(v2);
if ( v3 < v5 )
v3 = v5;
if ( *((_BYTE *)v1 + 8) )
v4 = *((_BYTE *)v1 + 8);
v1 += 4;
v2 = *v1;
}
while ( *v1 );
v6 = 4 * (v4 != 0);
}
else
{
LODWORD(v3) = 0;
v6 = 0;
}
return (unsigned int)(v6 + v3 + 4);
}

canonical_decompiled_code:
__int64 __fastcall func2(const char **a1)
{
const char **v1; // rbx
const char *v2; // rdi
size_t v3; // rbp
char v4; // r12
size_t v5; // rax
int v6; // eax

v1 = a1;
v2 = *a1;
if ( v2 )
{
v3 = 0LL;
v4 = 0;
do
{
v5 = strlen(v2);
if ( v3 < v5 )
v3 = v5;
if ( *((_BYTE *)v1 + 8) )
v4 = *((_BYTE *)v1 + 8);
v1 += 4;
v2 = *v1;
}
while ( *v1 );
v6 = 4 * (v4 != 0);
}
else
{
LODWORD(v3) = 0;
v6 = 0;
}
return (unsigned int)(v6 + v3 + 4);
}

original_code:
static int opts_calc_padding(opts_cfg_t* opts) {
    _Bool opts_have_args = 0;
    size_t sz = 0;
    while (((void *)0) != opts->name) {
        size_t name_sz = strlen(opts->name);
        if (name_sz > sz) {
            sz = name_sz;
        }
        if (opts->has_arg) {
            opts_have_args = 1;
        }
        opts++;
    }
    return sz + 4 + ((opts_have_args) ? 4 : 0);
}

canonical_original_code:
static int opts_calc_padding(struct opts_cfg_t *opts) {
    _Bool opts_have_args = 0;
    unsigned long sz = 0;
    while (((void *)0) != opts->name) {
        unsigned long name_sz = strlen(opts->name);
        if (name_sz > sz) {
            sz = name_sz;
        }
        if (opts->has_arg) {
            opts_have_args = 1;
        }
        opts++;
    }
    return sz + 4 + ((opts_have_args) ? 4 : 0);
}

variable_types: struct opts_cfg_t { char *name; _Bool has_arg; char *tag; char *desc; } *

variable_types:
sz
unsigned long


decompiled_code:
void *__fastcall opts_parse_argument(unsigned int *a1)
{
void *result; // rax

result = opts_next_token(a1);
if ( result )
result = opts_add_argument((__int64)result);
return result;
}

canonical_decompiled_code:
void *__fastcall func3(unsigned int *a1)
{
void *result; // rax

result = opts_next_token(a1);
if ( result )
result = opts_add_argument((__int64)result);
return result;
}

original_code:
static void opts_parse_argument( stream_ctx_t* ctx ) {
    char* arg_val = opts_next_token( ctx );
    if (((void *)0) != arg_val)
        opts_add_argument(arg_val);
}

canonical_original_code:
static void opts_parse_argument(struct stream_ctx_t *ctx) {
    char *arg_val = opts_next_token( ctx );
    if (((void *)0) != arg_val)
        opts_add_argument(arg_val);
}


decompiled_code:
const char *__fastcall opts_get_option_config(const char **a1, int a2, const char *a3)
{
const char **v3; // rbp
const char *v5; // rbx

v3 = a1;
v5 = *a1;
if ( *a1 )
{
while ( strlen(v5) <= 1 != a2 || strcmp(v5, a3) )
{
v3 += 4;
v5 = *v3;
if ( !*v3 )
return v5;
}
v5 = (const char *)v3;
}
return v5;
}

canonical_decompiled_code:
const char *__fastcall func4(const char **a1, int a2, const char *a3)
{
const char **v3; // rbp
const char *v5; // rbx

v3 = a1;
v5 = *a1;
if ( *a1 )
{
while ( strlen(v5) <= 1 != a2 || strcmp(v5, a3) )
{
v3 += 4;
v5 = *v3;
if ( !*v3 )
return v5;
}
v5 = (const char *)v3;
}
return v5;
}

original_code:
static opts_cfg_t* opts_get_option_config( opts_cfg_t* opts, opt_type_t type, char* name ) {
    opts_cfg_t* cfg = ((void *)0);
    int i = 0;
    while( opts[i].name != ((void *)0) ) {
        opt_type_t curr_type = (strlen(opts[i].name) > 1) ? LONG : SHORT;
        if ((curr_type == type) && (0 == strcmp(opts[i].name, name))) {
            cfg = &(opts[i]);
            break;
        }
        i++;
    }
    return cfg;
}

canonical_original_code:
static struct opts_cfg_t *opts_get_option_config(struct opts_cfg_t *opts, enum opt_type_t type, char *name) {
    struct opts_cfg_t *cfg = ((void *)0);
    int i = 0;
    while( opts[i].name != ((void *)0) ) {
        enum opt_type_t curr_type = (strlen(opts[i].name) > 1) ? LONG : SHORT;
        if ((curr_type == type) && (0 == strcmp(opts[i].name, name))) {
            cfg = &(opts[i]);
            break;
        }
        i++;
    }
    return cfg;
}

variable_types:
opts
struct opts_cfg_t *

variable_types:
type
enum opt_type_t { LONG=0, SHORT=1 }

variable_types:
name
char *

variable_types: i int

return_type: struct opts_cfg_t { char *name; _Bool has_arg; char *tag; char *desc; } *


decompiled_code:
const char **__fastcall find_option(char *s1, char *a2)
{
const char ***v2; // rbx
const char **v3; // rbp

v2 = (const char ***)Options;
if ( !Options )
return (const char **)Options;
while ( 1 )
{
v3 = *v2;
if ( (!s1 || !strcmp(s1, *v3)) && (!a2 || !strcmp(a2, v3[1])) )
break;
v2 = (const char ***)v2[1];
if ( !v2 )
return 0LL;
}
return v3;
}

canonical_decompiled_code:
const char **__fastcall func5(char *s1, char *a2)
{
const char ***v2; // rbx
const char **v3; // rbp

v2 = (const char ***)Options;
if ( !Options )
return (const char **)Options;
while ( 1 )
{
v3 = *v2;
if ( (!s1 || !strcmp(s1, *v3)) && (!a2 || !strcmp(a2, v3[1])) )
break;
v2 = (const char ***)v2[1];
if ( !v2 )
return 0LL;
}
return v3;
}

original_code:
static option_t* find_option(const char* name, const char* tag) {
    option_t* p_opt = ((void *)0);
    entry_t* current = Options;
    while (current != ((void *)0)) {
        option_t* curr_opt = (option_t*)current->value;
        if (((((void *)0) == name) || (0 == strcmp(name, curr_opt->name))) &&
            ((((void *)0) == tag) || (0 == strcmp(tag, curr_opt->tag)))) {
            p_opt = curr_opt;
            break;
        }
        current = current->next;
    }
    return p_opt;
}

canonical_original_code:
static struct option_t *find_option(char *name, char *tag) {
    struct option_t *p_opt = ((void *)0);
    struct entry_t *current = Options;
    while (current != ((void *)0)) {
        struct option_t *curr_opt = (option_t*)current->value;
        if (((((void *)0) == name) || (0 == strcmp(name, curr_opt->name))) &&
            ((((void *)0) == tag) || (0 == strcmp(tag, curr_opt->tag)))) {
            p_opt = curr_opt;
            break;
        }
        current = current->next;
    }
    return p_opt;
}

variable_types:
tag
char *

variable_types: struct option_t { char *name; char *tag; char *value; } *

variable_types: struct entry_t { void *value; struct entry_t *next; } *


decompiled_code:
void *__fastcall opts_parse(__int64 a1, __int64 (__fastcall *a2)(_QWORD, _QWORD), int a3, void **a4)
{
void *result; // rax
unsigned int v6[4]; // [rsp+0h] [rbp-48h] BYREF
_QWORD *v7; // [rsp+10h] [rbp-38h]
int v8; // [rsp+18h] [rbp-30h]
__int64 v9; // [rsp+20h] [rbp-28h]

v6[0] = 0;
v6[1] = -1;
v6[2] = a3 - 1;
v7 = a4 + 1;
v9 = a1;
opts_next_char(v6);
if ( a2 )
Error_Callback = a2;
result = *a4;
Program_Name = (__int64)*a4;
while ( v8 != -1 )
{
opts_consume_ws(v6);
if ( v8 == 45 )
{
if ( (unsigned __int8)opts_next_char(v6) == 45 )
{
opts_next_char(v6);
result = opts_parse_long_option((__int64)v6);
}
else
{
result = opts_parse_short_option((__int64)v6);
}
}
else
{
result = opts_parse_argument(v6);
}
}
return result;
}

canonical_decompiled_code:
void *__fastcall func7(__int64 a1, __int64 (__fastcall *a2)(_QWORD, _QWORD), int a3, void **a4)
{
void *result; // rax
unsigned int v6[4]; // [rsp+0h] [rbp-48h] BYREF
_QWORD *v7; // [rsp+10h] [rbp-38h]
int v8; // [rsp+18h] [rbp-30h]
__int64 v9; // [rsp+20h] [rbp-28h]

v6[0] = 0;
v6[1] = -1;
v6[2] = a3 - 1;
v7 = a4 + 1;
v9 = a1;
func0(v6);
if ( a2 )
Error_Callback = a2;
result = *a4;
Program_Name = (__int64)*a4;
while ( v8 != -1 )
{
func1(v6);
if ( v8 == 45 )
{
if ( (unsigned __int8)func0(v6) == 45 )
{
func0(v6);
result = opts_parse_long_option((__int64)v6);
}
else
{
result = opts_parse_short_option((__int64)v6);
}
}
else
{
result = func3(v6);
}
}
return result;
}

original_code:
void opts_parse(opts_cfg_t* opts, opts_err_cbfn_t err_cb, int argc, char** argv) {
    stream_ctx_t ctx;
    ctx.line_idx = 0;
    ctx.col_idx = -1;
    ctx.arg_count = argc-1;
    ctx.arg_vect = &argv[1];
    ctx.options = opts;
    (void)opts_next_char( &ctx );
    if (((void *)0) != err_cb)
        Error_Callback = err_cb;
    Program_Name = argv[0];
    while (ctx.current != (-1)) {
        opts_consume_ws( &ctx );
        if ('-' == ctx.current) {
            if ('-' == opts_next_char( &ctx )) {
                opts_next_char( &ctx );
                opts_parse_long_option( &ctx );
            } else {
                opts_parse_short_option( &ctx );
            }
        } else {
            opts_parse_argument( &ctx );
        }
    }
}

canonical_original_code:
void opts_parse(struct opts_cfg_t *opts, void (*err_cb)(char *msg, char *opt_name), int argc, char **argv) {
    struct stream_ctx_t ctx;
    ctx.line_idx = 0;
    ctx.col_idx = -1;
    ctx.arg_count = argc-1;
    ctx.arg_vect = &argv[1];
    ctx.options = opts;
    (void)opts_next_char( &ctx );
    if (((void *)0) != err_cb)
        Error_Callback = err_cb;
    Program_Name = argv[0];
    while (ctx.current != (-1)) {
        opts_consume_ws( &ctx );
        if ('-' == ctx.current) {
            if ('-' == opts_next_char( &ctx )) {
                opts_next_char( &ctx );
                opts_parse_long_option( &ctx );
            } else {
                opts_parse_short_option( &ctx );
            }
        } else {
            opts_parse_argument( &ctx );
        }
    }
}

variable_types:
argv
char **

variable_types: struct stream_ctx_t { unsigned int line_idx; unsigned int col_idx; unsigned int arg_count; char **arg_vect; int current; struct opts_cfg_t { char *name; _Bool has_arg; char *tag; char *desc; } *options; }


decompiled_code:
void opts_reset()
{
__int64 *v0; // rbx
void **v1; // rbx
void *v2; // rdi
void **v3; // rbp
__int64 v4; // rbp
__int64 *v5; // r12
void *v6; // rdi

v0 = (__int64 *)Options;
if ( Options )
{
do
{
v4 = *v0;
v5 = v0;
v0 = (__int64 *)v0[1];
Options = v0;
free(*(void **)v4);
free(*(void **)(v4 + 8));
v6 = *(void **)(v4 + 16);
if ( *(void **)v4 != v6 )
free(v6);
free((void *)v4);
free(v5);
}
while ( v0 );
}
v1 = (void **)Arguments;
if ( Arguments )
{
do
{
v2 = *v1;
v3 = v1;
v1 = (void **)v1[1];
Arguments = v1;
free(v2);
free(v3);
}
while ( v1 );
}
}

canonical_decompiled_code:
void func8()
{
__int64 *v0; // rbx
void **v1; // rbx
void *v2; // rdi
void **v3; // rbp
__int64 v4; // rbp
__int64 *v5; // r12
void *v6; // rdi

v0 = (__int64 *)Options;
if ( Options )
{
do
{
v4 = *v0;
v5 = v0;
v0 = (__int64 *)v0[1];
Options = v0;
free(*(void **)v4);
free(*(void **)(v4 + 8));
v6 = *(void **)(v4 + 16);
if ( *(void **)v4 != v6 )
free(v6);
free((void *)v4);
free(v5);
}
while ( v0 );
}
v1 = (void **)Arguments;
if ( Arguments )
{
do
{
v2 = *v1;
v3 = v1;
v1 = (void **)v1[1];
Arguments = v1;
free(v2);
free(v3);
}
while ( v1 );
}
}

original_code:
void opts_reset(void) {
    while (Options != ((void *)0)) {
        entry_t* entry = Options;
        option_t* opt = (option_t*)entry->value;
        Options = entry->next;
        free(opt->name);
        free(opt->tag);
        if(opt->name != opt->value)
            free(opt->value);
        free(opt);
        free(entry);
    }
    while (Arguments != ((void *)0)) {
        entry_t* entry = Arguments;
        char* arg = (char*)entry->value;
        Arguments = entry->next;
        free(arg);
        free(entry);
    }
}

canonical_original_code:
void opts_reset() {
    while (Options != ((void *)0)) {
        struct entry_t *entry = Options;
        struct option_t *opt = (option_t*)entry->value;
        Options = entry->next;
        free(opt->name);
        free(opt->tag);
        if(opt->name != opt->value)
            free(opt->value);
        free(opt);
        free(entry);
    }
    while (Arguments != ((void *)0)) {
        struct entry_t *entry = Arguments;
        char *arg = (char*)entry->value;
        Arguments = entry->next;
        free(arg);
        free(entry);
    }
}

variable_types:
arg
char *

user_defined_types: struct entry_t { void *value; struct entry_t *next; }

user_defined_types: struct option_t { char *name; char *tag; char *value; }


decompiled_code:
void __fastcall __noreturn opts_parse_error(const char *a1, char *a2)
{
fprintf(stderr, "Option '%s' : %s\n", a2, a1);
free(a2);
opts_reset();
exit(1);
}

canonical_decompiled_code:
void __fastcall __noreturn func9(const char *a1, char *a2)
{
fprintf(stderr, "Option '%s' : %s\n", a2, a1);
free(a2);
func8();
exit(1);
}

original_code:
static void opts_parse_error(const char* msg, char* opt_name) {
    fprintf(stderr, "Option '%s' : %s\n", opt_name, msg);
    free(opt_name);
    opts_reset();
    exit(1);
}

canonical_original_code:
static void opts_parse_error(char *msg, char *opt_name) {
    fprintf(stderr, "Option '%s' : %s\n", opt_name, msg);
    free(opt_name);
    opts_reset();
    exit(1);
}

variable_types:
msg
char *


decompiled_code:
bool __fastcall opts_is_set(char *a1, char *a2)
{
return find_option(a1, a2) != 0LL;
}

canonical_decompiled_code:
bool __fastcall func10(char *a1, char *a2)
{
return func5(a1, a2) != 0LL;
}

original_code:
_Bool opts_is_set(const char* name, const char* tag) {
    return (((void *)0) != find_option(name,tag));
}

canonical_original_code:
_Bool opts_is_set(char *name, char *tag) {
    return (((void *)0) != find_option(name,tag));
}


decompiled_code:
const char **__fastcall opts_get_value(char *a1, char *a2)
{
const char **result; // rax

result = find_option(a1, a2);
if ( result )
result = (const char **)result[2];
return result;
}

canonical_decompiled_code:
const char **__fastcall func11(char *a1, char *a2)
{
const char **result; // rax

result = func5(a1, a2);
if ( result )
result = (const char **)result[2];
return result;
}

original_code:
const char* opts_get_value(const char* name, const char* tag) {
    option_t* p_opt = find_option(name,tag);
    return (((void *)0) == p_opt) ? ((void *)0) : p_opt->value;
}

canonical_original_code:
char *opts_get_value(char *name, char *tag) {
    struct option_t *p_opt = find_option(name,tag);
    return (((void *)0) == p_opt) ? ((void *)0) : p_opt->value;
}


decompiled_code:
bool __fastcall opts_equal(char *a1, char *a2, const char *a3)
{
const char **v4; // rax

v4 = opts_get_value(a1, a2);
return strcmp(a3, (const char *)v4) == 0;
}

canonical_decompiled_code:
bool __fastcall func12(char *a1, char *a2, const char *a3)
{
const char **v4; // rax

v4 = func11(a1, a2);
return strcmp(a3, (const char *)v4) == 0;
}

original_code:
_Bool opts_equal(const char* name, const char* tag, const char* value) {
    return (0 == strcmp(value, opts_get_value(name,tag)));
}

canonical_original_code:
_Bool opts_equal(char *name, char *tag, char *value) {
    return (0 == strcmp(value, opts_get_value(name,tag)));
}

variable_types:
value
char *


decompiled_code:
_QWORD *opts_arguments()
{
_QWORD *v0; // rdi
_QWORD *v1; // rbp
size_t v2; // rbx

v0 = malloc(8uLL);
*v0 = 0LL;
v1 = Arguments;
if ( Arguments )
{
v2 = 2LL;
do
{
v0 = realloc(v0, v2 * 8);
v0[v2 - 2] = *v1;
v0[v2 - 1] = 0LL;
v1 = (_QWORD *)v1[1];
++v2;
}
while ( v1 );
}
return v0;
}

canonical_decompiled_code:
_QWORD *func13()
{
_QWORD *v0; // rdi
_QWORD *v1; // rbp
size_t v2; // rbx

v0 = malloc(8uLL);
*v0 = 0LL;
v1 = Arguments;
if ( Arguments )
{
v2 = 2LL;
do
{
v0 = realloc(v0, v2 * 8);
v0[v2 - 2] = *v1;
v0[v2 - 1] = 0LL;
v1 = (_QWORD *)v1[1];
++v2;
}
while ( v1 );
}
return v0;
}

original_code:
const char** opts_arguments(void) {
    size_t index = 0;
    const char** ret = (const char**)malloc(sizeof(const char*));
    ret[0] = ((void *)0);
    entry_t* entry = Arguments;
    while (((void *)0) != entry) {
        ret = (const char**)realloc(ret, (index+2)*sizeof(const char*));
        ret[index++] = (const char*)entry->value;
        ret[index] = ((void *)0);
        entry = entry->next;
    }
    return ret;
}

canonical_original_code:
char **opts_arguments() {
    unsigned long index = 0;
    char **ret = (const char**)malloc(sizeof(const char*));
    ret[0] = ((void *)0);
    struct entry_t *entry = Arguments;
    while (((void *)0) != entry) {
        ret = (char **)realloc(ret, (index+2)*sizeof(char *));
        ret[index++] = (char *)entry->value;
        ret[index] = ((void *)0);
        entry = entry->next;
    }
    return ret;
}

variable_types:
index
unsigned long

variable_types:
ret
char **

return_type: char **