decompiled_code:
const char **__fastcall ct_sched(char *s2)
{
const char **v1; // r12
const char ***v2; // rbx

v1 = (const char **)g_ct_imps;
if ( g_ct_imps )
{
v2 = (const char ***)(&g_ct_imps + 1);
do
{
if ( *v1 && !strcmp(*v1, s2) )
break;
v1 = *v2++;
}
while ( v1 );
}
return v1;
}

canonical_decompiled_code:
const char **__fastcall func3(char *s2)
{
const char **v1; // r12
const char ***v2; // rbx

v1 = (const char **)g_ct_imps;
if ( g_ct_imps )
{
v2 = (const char ***)(&g_ct_imps + 1);
do
{
if ( *v1 && !strcmp(*v1, s2) )
break;
v1 = *v2++;
}
while ( v1 );
}
return v1;
}

original_code:
ct_imp* ct_sched(const char* name) {
    int i=0;
    while(g_ct_imps[i]) {
        const char* namei = g_ct_imps[i]->name;
        if(namei && strcmp(namei, name) == 0) {
            return g_ct_imps[i];
        }
        ++i;
    }
    return 0;
}

canonical_original_code:
struct ct_imp *ct_sched(char *name) {
    int i = 0;
    while(g_ct_imps[i]) {
        char *namei = g_ct_imps[i]->name;
        if(namei && strcmp(namei, name) == 0) {
            return g_ct_imps[i];
        }
        ++i;
    }
    return 0;
}

variable_types:
namei
char *

return_type: struct ct_imp { char *name; void (*imp_init)(struct ct_env_var { char *name; char *value; } *env); void (*imp_fini)(); void (*imp_for)(int n, void (*f)(int ind, void *context), void *context, struct ct_canceller { int cancelled; void *sched_data; } *c); void (*imp_canceller_init)(struct ct_canceller *c); void (*imp_canceller_fini)(struct ct_canceller *c); void (*imp_cancel)(struct ct_canceller *c); } *

user_defined_types: struct ct_imp { char *name; void (*imp_init)(struct ct_env_var *env); void (*imp_fini)(); void (*imp_for)(int n, void (*f)(int ind, void *context), void *context, struct ct_canceller *c); void (*imp_canceller_init)(struct ct_canceller *c); void (*imp_canceller_fini)(struct ct_canceller *c); void (*imp_cancel)(struct ct_canceller *c); }


repo: yosefk/checkedthreads

decompiled_code:
const char *ct_default_sched()
{
const char *v0; // rbp
_QWORD *v1; // r13
const char **v2; // r12
const char ***v3; // rbx
const char **v4; // rax
const char *v5; // r15
_QWORD v7[11]; // [rsp+0h] [rbp-58h] BYREF

v0 = "pthreads";
v7[1] = "tbb";
v1 = v7;
v7[2] = "openmp";
v2 = (const char **)g_ct_imps;
v7[3] = 0LL;
while ( 1 )
{
v3 = (const char ***)(&g_ct_imps + 1);
v4 = v2;
if ( v2 )
break;
LABEL_6:
v0 = (const char *)v1[1];
++v1;
if ( !v0 )
return "serial";
}
while ( 1 )
{
v5 = *v4;
if ( *v4 )
{
if ( !strcmp(*v4, v0) )
return v5;
}
v4 = *v3++;
if ( !v4 )
goto LABEL_6;
}
}

canonical_decompiled_code:
const char *func4()
{
const char *v0; // rbp
_QWORD *v1; // r13
const char **v2; // r12
const char ***v3; // rbx
const char **v4; // rax
const char *v5; // r15
_QWORD v7[11]; // [rsp+0h] [rbp-58h] BYREF

v0 = "pthreads";
v7[1] = "tbb";
v1 = v7;
v7[2] = "openmp";
v2 = (const char **)g_ct_imps;
v7[3] = 0LL;
while ( 1 )
{
v3 = (const char ***)(&g_ct_imps + 1);
v4 = v2;
if ( v2 )
break;
LABEL_6:
v0 = (const char *)v1[1];
++v1;
if ( !v0 )
return "serial";
}
while ( 1 )
{
v5 = *v4;
if ( *v4 )
{
if ( !strcmp(*v4, v0) )
return v5;
}
v4 = *v3++;
if ( !v4 )
goto LABEL_6;
}
}

original_code:
const char* ct_default_sched() {
    const char* prefs[] = {"pthreads","tbb","openmp",0};
    int j=0;
    while(prefs[j]) {
        int i=0;
        while(g_ct_imps[i]) {
            const char* namei = g_ct_imps[i]->name;
            if(namei && strcmp(namei,prefs[j]) == 0) {
                return namei;
            }
            ++i;
        }
        ++j;
    }
    return "serial";
}

canonical_original_code:
char *ct_default_sched() {
    char *prefs[] = {"pthreads","tbb","openmp",0};
    int j = 0;
    while(prefs[j]) {
        int i = 0;
        while(g_ct_imps[i]) {
            char *namei = g_ct_imps[i]->name;
            if(namei && strcmp(namei,prefs[j]) == 0) {
                return namei;
            }
            ++i;
        }
        ++j;
    }
    return "serial";
}

variable_types:
prefs
char *[]

variable_types: j int

variable_types: i int

return_type: char *


decompiled_code:
_DWORD *ct_alloc_canceller()
{
_DWORD *v0; // rax
_DWORD *v1; // r12
void (__fastcall *v2)(_DWORD *); // rax

v0 = malloc(0x10uLL);
*v0 = 0;
v1 = v0;
v2 = *(void (__fastcall **)(_DWORD *))(g_ct_pimpl + 32LL);
if ( v2 )
v2(v1);
return v1;
}

canonical_decompiled_code:
_DWORD *func5()
{
_DWORD *v0; // rax
_DWORD *v1; // r12
void (__fastcall *v2)(_DWORD *); // rax

v0 = malloc(0x10uLL);
*v0 = 0;
v1 = v0;
v2 = *(void (__fastcall **)(_DWORD *))(g_ct_pimpl + 32LL);
if ( v2 )
v2(v1);
return v1;
}

original_code:
ct_canceller* ct_alloc_canceller(void) {
    ct_canceller* c = (ct_canceller*)malloc(sizeof(ct_canceller));
    c->cancelled = 0;
    if(g_ct_pimpl->imp_canceller_init) {
        g_ct_pimpl->imp_canceller_init(c);
    }
    return c;
}

canonical_original_code:
struct ct_canceller *ct_alloc_canceller() {
    struct ct_canceller *c = (ct_canceller*)malloc(sizeof(ct_canceller));
    c->cancelled = 0;
    if(g_ct_pimpl->imp_canceller_init) {
        g_ct_pimpl->imp_canceller_init(c);
    }
    return c;
}

variable_types: struct ct_canceller { int cancelled; void *sched_data; } *


decompiled_code:
int __fastcall ct_init(const char **a1)
{
char *v1; // r12
char *v2; // r13
char *v3; // rax
int result; // eax

v1 = (char *)ct_default_sched();
v2 = ct_getenv(a1, "CT_SCHED", v1);
g_ct_pimpl = ct_sched(v2);
if ( !g_ct_pimpl )
{
printf("checkedthreads - WARNING: unknown scheduler (%s) specified, using %s instead\n", v2, v1);
g_ct_pimpl = ct_sched(v1);
}
v3 = ct_getenv(a1, "CT_VERBOSE", "0");
g_ct_verbose = atoi(v3);
(*(void (__fastcall **)(const char **))(g_ct_pimpl + 8LL))(a1);
g_ct_default_canceller = ct_alloc_canceller();
result = g_ct_verbose;
if ( g_ct_verbose )
result = puts("checkedthreads: initialized");
return result;
}

canonical_decompiled_code:
int __fastcall func6(const char **a1)
{
char *v1; // r12
char *v2; // r13
char *v3; // rax
int result; // eax

v1 = (char *)func4();
v2 = func2(a1, "CT_SCHED", v1);
g_ct_pimpl = func3(v2);
if ( !g_ct_pimpl )
{
printf("checkedthreads - WARNING: unknown scheduler (%s) specified, using %s instead\n", v2, v1);
g_ct_pimpl = func3(v1);
}
v3 = func2(a1, "CT_VERBOSE", "0");
g_ct_verbose = atoi(v3);
(*(void (__fastcall **)(const char **))(g_ct_pimpl + 8LL))(a1);
g_ct_default_canceller = func5();
result = g_ct_verbose;
if ( g_ct_verbose )
result = puts("checkedthreads: initialized");
return result;
}

original_code:
void ct_init(const ct_env_var* env) {
    const char* default_sched = ct_default_sched();
    const char* sched = ct_getenv(env, "CT_SCHED", default_sched);
    g_ct_pimpl = ct_sched(sched);
    if(!g_ct_pimpl) {
        printf("checkedthreads - WARNING: unknown scheduler (%s) specified, using %s instead\n",
                sched, default_sched);
        g_ct_pimpl = ct_sched(default_sched);
    }
    g_ct_verbose = atoi(ct_getenv(env, "CT_VERBOSE", "0"));
    g_ct_pimpl->imp_init(env);
    g_ct_default_canceller = ct_alloc_canceller();
    if(g_ct_verbose) {
        printf("checkedthreads: initialized\n");
    }
}

canonical_original_code:
void ct_init(struct ct_env_var *env) {
    char *default_sched = ct_default_sched();
    char *sched = ct_getenv(env, "CT_SCHED", default_sched);
    g_ct_pimpl = ct_sched(sched);
    if(!g_ct_pimpl) {
        printf("checkedthreads - WARNING: unknown scheduler (%s) specified, using %s instead\n",
                sched, default_sched);
        g_ct_pimpl = ct_sched(default_sched);
    }
    g_ct_verbose = atoi(ct_getenv(env, "CT_VERBOSE", "0"));
    g_ct_pimpl->imp_init(env);
    g_ct_default_canceller = ct_alloc_canceller();
    if(g_ct_verbose) {
        printf("checkedthreads: initialized\n");
    }
}

variable_types: struct ct_env_var { char *name; char *value; } *

variable_types:
sched
char *

return_type: void


decompiled_code:
void __fastcall ct_free_canceller(void *ptr)
{
void (*v1)(void); // rax

v1 = *(void (**)(void))(g_ct_pimpl + 40LL);
if ( v1 )
v1();
free(ptr);
}

canonical_decompiled_code:
void __fastcall func7(void *ptr)
{
void (*v1)(void); // rax

v1 = *(void (**)(void))(g_ct_pimpl + 40LL);
if ( v1 )
v1();
free(ptr);
}

original_code:
void ct_free_canceller(ct_canceller* c) {
    if(g_ct_pimpl->imp_canceller_fini) {
        g_ct_pimpl->imp_canceller_fini(c);
    }
    free(c);
}

canonical_original_code:
void ct_free_canceller(struct ct_canceller *c) {
    if(g_ct_pimpl->imp_canceller_fini) {
        g_ct_pimpl->imp_canceller_fini(c);
    }
    free(c);
}

user_defined_types: struct ct_canceller { int cancelled; void *sched_data; }


decompiled_code:
int ct_fini()
{
int result; // eax

ct_free_canceller(g_ct_default_canceller);
(*(void (**)(void))(g_ct_pimpl + 16LL))();
g_ct_pimpl = 0LL;
result = g_ct_verbose;
if ( g_ct_verbose )
result = puts("checkedthreads: finalized");
return result;
}

canonical_decompiled_code:
int func8()
{
int result; // eax

func7(g_ct_default_canceller);
(*(void (**)(void))(g_ct_pimpl + 16LL))();
g_ct_pimpl = 0LL;
result = g_ct_verbose;
if ( g_ct_verbose )
result = puts("checkedthreads: finalized");
return result;
}

original_code:
void ct_fini(void) {
    ct_free_canceller(g_ct_default_canceller);
    g_ct_pimpl->imp_fini();
    g_ct_pimpl = 0;
    if(g_ct_verbose) {
        printf("checkedthreads: finalized\n");
    }
}

canonical_original_code:
void ct_fini() {
    ct_free_canceller(g_ct_default_canceller);
    g_ct_pimpl->imp_fini();
    g_ct_pimpl = 0;
    if(g_ct_verbose) {
        printf("checkedthreads: finalized\n");
    }
}


decompiled_code:
__int64 __fastcall ct_cancelled(unsigned int *a1)
{
return *a1;
}

canonical_decompiled_code:
__int64 __fastcall func9(unsigned int *a1)
{
return *a1;
}

original_code:
int ct_cancelled(ct_canceller* c) {
    return c->cancelled;
}

canonical_original_code:
int ct_cancelled(struct ct_canceller *c) {
    return c->cancelled;
}

return_type: int


decompiled_code:
int __fastcall ct_for(unsigned int a1, __int64 a2, __int64 a3, int *a4)
{
__int64 (__fastcall *v4)(unsigned int, __int64); // r13
int result; // eax
__int64 *v6; // rdx
int *v8; // [rsp+8h] [rbp-30h]
__int64 v9[5]; // [rsp+10h] [rbp-28h] BYREF

v4 = (__int64 (__fastcall *)(unsigned int, __int64))a2;
if ( a4 )
{
result = *a4;
if ( *a4 )
return result;
if ( g_ct_verbose <= 0 )
return (*(__int64 (__fastcall **)(_QWORD, __int64))(g_ct_pimpl + 24LL))(a1, a2);
}
else
{
a4 = (int *)g_ct_default_canceller;
if ( g_ct_verbose <= 0 )
return (*(__int64 (__fastcall **)(_QWORD, __int64))(g_ct_pimpl + 24LL))(a1, a2);
}
v8 = a4;
printf("checkedthreads: ct_for(%d) entered\n", a1);
v6 = (__int64 *)a3;
if ( g_ct_verbose > 1 )
{
v9[0] = a2;
v4 = ct_verbose_ind_func;
v9[1] = a3;
v6 = v9;
}
(*(void (__fastcall **)(_QWORD, __int64 (__fastcall *)(unsigned int, __int64), __int64 *, int *))(g_ct_pimpl + 24LL))(
a1,
v4,
v6,
v8);
return printf("checkedthreads: ct_for(%d) ended\n", a1);
}

canonical_decompiled_code:
int __fastcall func10(unsigned int a1, __int64 a2, __int64 a3, int *a4)
{
__int64 (__fastcall *v4)(unsigned int, __int64); // r13
int result; // eax
__int64 *v6; // rdx
int *v8; // [rsp+8h] [rbp-30h]
__int64 v9[5]; // [rsp+10h] [rbp-28h] BYREF

v4 = (__int64 (__fastcall *)(unsigned int, __int64))a2;
if ( a4 )
{
result = *a4;
if ( *a4 )
return result;
if ( g_ct_verbose <= 0 )
return (*(__int64 (__fastcall **)(_QWORD, __int64))(g_ct_pimpl + 24LL))(a1, a2);
}
else
{
a4 = (int *)g_ct_default_canceller;
if ( g_ct_verbose <= 0 )
return (*(__int64 (__fastcall **)(_QWORD, __int64))(g_ct_pimpl + 24LL))(a1, a2);
}
v8 = a4;
printf("checkedthreads: ct_for(%d) entered\n", a1);
v6 = (__int64 *)a3;
if ( g_ct_verbose > 1 )
{
v9[0] = a2;
v4 = ct_verbose_ind_func;
v9[1] = a3;
v6 = v9;
}
(*(void (__fastcall **)(_QWORD, __int64 (__fastcall *)(unsigned int, __int64), __int64 *, int *))(g_ct_pimpl + 24LL))(
a1,
v4,
v6,
v8);
return printf("checkedthreads: ct_for(%d) ended\n", a1);
}

original_code:
void ct_for(int n, ct_ind_func f, void* context, ct_canceller* c) {
    if(c == 0) {
        c = g_ct_default_canceller;
    }
    else {
        if(c->cancelled) {
            return;
        }
    }
    if(g_ct_verbose>0) {
        ct_wrapped_func_context wc;
        printf("checkedthreads: ct_for(%d) entered\n",n);
        if(g_ct_verbose>1) {
            wc.next_func = f;
            wc.next_context = context;
            f = ct_verbose_ind_func;
            context = &wc;
        }
        g_ct_pimpl->imp_for(n, f, context, c);
        printf("checkedthreads: ct_for(%d) ended\n",n);
    }
    else {
        g_ct_pimpl->imp_for(n, f, context, c);
    }
}

canonical_original_code:
void ct_for(int n, void (*f)(int ind, void *context), void *context, struct ct_canceller *c) {
    if(c == 0) {
        c = g_ct_default_canceller;
    }
    else {
        if(c->cancelled) {
            return;
        }
    }
    if(g_ct_verbose>0) {
        struct ct_wrapped_func_context wc;
        printf("checkedthreads: ct_for(%d) entered\n",n);
        if(g_ct_verbose>1) {
            wc.next_func = f;
            wc.next_context = context;
            f = ct_verbose_ind_func;
            context = &wc;
        }
        g_ct_pimpl->imp_for(n, f, context, c);
        printf("checkedthreads: ct_for(%d) ended\n",n);
    }
    else {
        g_ct_pimpl->imp_for(n, f, context, c);
    }
}

variable_types: n int

variable_types:
f
void (*)(int ind, void *context)

variable_types:
context
void *

variable_types: struct ct_wrapped_func_context { void (*next_func)(int ind, void *context); void *next_context; }


decompiled_code:
int __fastcall ct_invoke(_QWORD *a1, int *a2)
{
_QWORD *v3; // rax
unsigned int v4; // edi

if ( !*a1 )
return ct_for(0, (__int64)ct_dispatch_task, (__int64)a1, a2);
v3 = a1 + 2;
v4 = 0;
do
{
v3 += 2;
++v4;
}
while ( *(v3 - 2) );
return ct_for(v4, (__int64)ct_dispatch_task, (__int64)a1, a2);
}

canonical_decompiled_code:
int __fastcall func11(_QWORD *a1, int *a2)
{
_QWORD *v3; // rax
unsigned int v4; // edi

if ( !*a1 )
return func10(0, (__int64)ct_dispatch_task, (__int64)a1, a2);
v3 = a1 + 2;
v4 = 0;
do
{
v3 += 2;
++v4;
}
while ( *(v3 - 2) );
return func10(v4, (__int64)ct_dispatch_task, (__int64)a1, a2);
}

original_code:
void ct_invoke(const ct_task tasks[], ct_canceller* c) {
    int i;
    for(i=0; tasks[i].func; ++i);
    ct_for(i, ct_dispatch_task, (void*)tasks, c);
}

canonical_original_code:
void ct_invoke(struct ct_task tasks[], struct ct_canceller *c) {
    int i;
    for(i=0; tasks[i].func; ++i);
    ct_for(i, ct_dispatch_task, (void *)tasks, c);
}

variable_types: struct ct_task { void (*func)(void *arg); void *arg; } []


decompiled_code:
__int64 __fastcall ct_locked_enqueue(pthread_mutex_t *mutex, __int64 a2, int a3)
{
unsigned int v3; // er13
int v7; // esi
int v8; // eax
__int64 v9; // r8
int v10; // edx
__int64 v11; // rcx

v3 = 0;
if ( a3 + mutex[1].__spins > mutex[1].__owner )
return 0LL;
pthread_mutex_lock(mutex);
v7 = mutex[1].__owner;
if ( a3 + mutex[1].__spins <= v7 )
{
v8 = mutex[1].__kind;
if ( a3 > 0 )
{
v9 = mutex[1].__align;
v10 = 0;
do
{
v11 = v8++;
*(_QWORD *)(v9 + 8 * v11) = a2;
if ( v7 <= v8 )
v8 = 0;
++v10;
}
while ( a3 != v10 );
}
mutex[1].__kind = v8;
v3 = 1;
mutex[1].__spins += a3;
}
pthread_mutex_unlock(mutex);
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func1(pthread_mutex_t *mutex, __int64 a2, int a3)
{
unsigned int v3; // er13
int v7; // esi
int v8; // eax
__int64 v9; // r8
int v10; // edx
__int64 v11; // rcx

v3 = 0;
if ( a3 + mutex[1].__spins > mutex[1].__owner )
return 0LL;
pthread_mutex_lock(mutex);
v7 = mutex[1].__owner;
if ( a3 + mutex[1].__spins <= v7 )
{
v8 = mutex[1].__kind;
if ( a3 > 0 )
{
v9 = mutex[1].__align;
v10 = 0;
do
{
v11 = v8++;
*(_QWORD *)(v9 + 8 * v11) = a2;
if ( v7 <= v8 )
v8 = 0;
++v10;
}
while ( a3 != v10 );
}
mutex[1].__kind = v8;
v3 = 1;
mutex[1].__spins += a3;
}
pthread_mutex_unlock(mutex);
return v3;
}

original_code:
int ct_locked_enqueue(ct_locked_queue* q, ct_work_item* item, int reps) {
    int ret = 0, capacity;
    if(q->size + reps > q->capacity) {
        return ret;
    }
    pthread_mutex_lock(&q->mutex);
    capacity = q->capacity;
    if(q->size + reps <= capacity) {
        int i, w=q->write_ind;
        for(i=0; i<reps; ++i) {
            q->work_items[w] = item;
            w++;
            if(w >= capacity) {
                w = 0;
            }
        }
        q->write_ind = w;
        q->size += reps;
        ret = 1;
    }
    pthread_mutex_unlock(&q->mutex);
    return ret;
}

canonical_original_code:
int ct_locked_enqueue(struct ct_locked_queue *q, struct ct_work_item *item, int reps) {
    int ret = 0; int capacity;
    if(q->size + reps > q->capacity) {
        return ret;
    }
    pthread_mutex_lock(&q->mutex);
    capacity = q->capacity;
    if(q->size + reps <= capacity) {
        int i; int w = q->write_ind;
        for(i=0; i<reps; ++i) {
            q->work_items[w] = item;
            w++;
            if(w >= capacity) {
                w = 0;
            }
        }
        q->write_ind = w;
        q->size += reps;
        ret = 1;
    }
    pthread_mutex_unlock(&q->mutex);
    return ret;
}

variable_types: struct ct_locked_queue { union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } mutex; struct ct_work_item { int next_ind; int to_do; int n; int ref_cnt; void (*f)(int ind, void *context); void *context; struct ct_canceller { int cancelled; void *sched_data; } *canceller; } **work_items; int capacity; int read_ind; int write_ind; int size; } *

variable_types:
item
struct ct_work_item *

variable_types: reps int

variable_types: ret int

variable_types: capacity int

variable_types: w int

user_defined_types: struct ct_locked_queue { union pthread_mutex_t mutex; struct ct_work_item **work_items; int capacity; int read_ind; int write_ind; int size; }

user_defined_types: union pthread_mutex_t { struct __pthread_mutex_s __data; char __size[40]; long __align; }

user_defined_types: struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list __list; }

user_defined_types: struct ct_work_item { int next_ind; int to_do; int n; int ref_cnt; void (*f)(int ind, void *context); void *context; struct ct_canceller *canceller; }


decompiled_code:
__int64 __fastcall ct_locked_dequeue(pthread_mutex_t *mutex)
{
__int64 v1; // r12
int v2; // eax

v1 = 0LL;
if ( mutex[1].__spins )
{
pthread_mutex_lock(mutex);
if ( mutex[1].__spins > 0 )
{
v1 = *(_QWORD *)(mutex[1].__align + 8LL * (int)mutex[1].__nusers);
v2 = mutex[1].__nusers + 1;
if ( mutex[1].__owner <= v2 )
v2 = 0;
mutex[1].__nusers = v2;
--mutex[1].__spins;
}
pthread_mutex_unlock(mutex);
}
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func2(pthread_mutex_t *mutex)
{
__int64 v1; // r12
int v2; // eax

v1 = 0LL;
if ( mutex[1].__spins )
{
pthread_mutex_lock(mutex);
if ( mutex[1].__spins > 0 )
{
v1 = *(_QWORD *)(mutex[1].__align + 8LL * (int)mutex[1].__nusers);
v2 = mutex[1].__nusers + 1;
if ( mutex[1].__owner <= v2 )
v2 = 0;
mutex[1].__nusers = v2;
--mutex[1].__spins;
}
pthread_mutex_unlock(mutex);
}
return v1;
}

original_code:
ct_work_item* ct_locked_dequeue(ct_locked_queue* q) {
    ct_work_item* ret = 0;
    if(q->size == 0) {
        return ret;
    }
    pthread_mutex_lock(&q->mutex);
    if(q->size > 0) {
        int r = q->read_ind;
        ret = q->work_items[r];
        r++;
        if(r >= q->capacity) {
            r = 0;
        }
        q->read_ind = r;
        q->size -= 1;
    }
    pthread_mutex_unlock(&q->mutex);
    return ret;
}

canonical_original_code:
struct ct_work_item *ct_locked_dequeue(struct ct_locked_queue *q) {
    struct ct_work_item *ret = 0;
    if(q->size == 0) {
        return ret;
    }
    pthread_mutex_lock(&q->mutex);
    if(q->size > 0) {
        int r = q->read_ind;
        ret = q->work_items[r];
        r++;
        if(r >= q->capacity) {
            r = 0;
        }
        q->read_ind = r;
        q->size -= 1;
    }
    pthread_mutex_unlock(&q->mutex);
    return ret;
}

variable_types: struct ct_locked_queue { union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } mutex; struct ct_work_item **work_items; int capacity; int read_ind; int write_ind; int size; } *

variable_types: struct ct_work_item { int next_ind; int to_do; int n; int ref_cnt; void (*f)(int ind, void *context); void *context; struct ct_canceller { int cancelled; void *sched_data; } *canceller; } *

variable_types: r int


decompiled_code:
void ct_valgrind_fini()
{
;
}

canonical_decompiled_code:
void func0()
{
;
}

original_code:
void ct_valgrind_fini(void) {
}

canonical_original_code:
void ct_valgrind_fini() {
}


decompiled_code:
// attributes: thunk
__int64 ct_valgrind_init()
{
return ct_shuffle_init();
}

canonical_decompiled_code:
__int64 func1()
{
return ct_shuffle_init();
}

original_code:
void ct_valgrind_init(const ct_env_var* env) {
    ct_shuffle_init(env);
}

canonical_original_code:
void ct_valgrind_init(struct ct_env_var *env) {
    ct_shuffle_init(env);
}

user_defined_types: struct ct_env_var { char *name; char *value; }


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

result = &g_ct_valgrind_cmd;
*(_QWORD *)((char *)&g_ct_valgrind_cmd + a1 + 20) = a2;
return result;
}

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

result = &g_ct_valgrind_cmd;
*(_QWORD *)((char *)&g_ct_valgrind_cmd + a1 + 20) = a2;
return result;
}

original_code:
void ct_valgrind_ptr(int oft, volatile const void* ptr) {
    *(volatile const void**)&g_ct_valgrind_cmd.payload[oft] = ptr;
}

canonical_original_code:
void ct_valgrind_ptr(int oft, void *ptr) {
    *(void **)&g_ct_valgrind_cmd.payload[oft] = ptr;
}

variable_types: oft int

variable_types:
ptr
void *


decompiled_code:
void __fastcall ct_valgrind_cmd(char *a1)
{
char v1; // dl
__int64 v2; // rax
__int64 v3; // rcx

v1 = *a1;
if ( *a1 )
{
v2 = 0LL;
do
{
v3 = (int)v2++;
*((_BYTE *)&g_ct_valgrind_cmd + v3 + 20) = v1;
v1 = a1[v2];
}
while ( v1 );
g_ct_valgrind_cmd = 305419896;
}
else
{
g_ct_valgrind_cmd = 305419896;
}
}

canonical_decompiled_code:
void __fastcall func3(char *a1)
{
char v1; // dl
__int64 v2; // rax
__int64 v3; // rcx

v1 = *a1;
if ( *a1 )
{
v2 = 0LL;
do
{
v3 = (int)v2++;
*((_BYTE *)&g_ct_valgrind_cmd + v3 + 20) = v1;
v1 = a1[v2];
}
while ( v1 );
g_ct_valgrind_cmd = 305419896;
}
else
{
g_ct_valgrind_cmd = 305419896;
}
}

original_code:
void ct_valgrind_cmd(const char* str) {
    int i;
    for(i=0; str[i]; ++i) {
        g_ct_valgrind_cmd.payload[i] = str[i];
    }
    g_ct_valgrind_cmd.stored_magic = 0x12345678;
}

canonical_original_code:
void ct_valgrind_cmd(char *str) {
    int i;
    for(i=0; str[i]; ++i) {
        g_ct_valgrind_cmd.payload[i] = str[i];
    }
    g_ct_valgrind_cmd.stored_magic = 0x12345678;
}

variable_types:
str
char *

variable_types: i int


decompiled_code:
void __fastcall ct_valgrind_for_loop(int a1, void (__fastcall *a2)(_QWORD, __int64), __int64 a3)
{
__int64 v4; // rax
signed int *v5; // r13
signed int *v6; // r14
signed int v7; // eax
unsigned int v8; // er15
void *ptr; // [rsp+8h] [rbp-40h]

ct_valgrind_int(8, 0);
ct_valgrind_cmd("setactiv");
v4 = ct_rand_perm((unsigned int)a1);
ptr = (void *)v4;
if ( a1 > 0 )
{
v5 = (signed int *)(v4 + 4LL * (unsigned int)a1);
v6 = (signed int *)v4;
do
{
v7 = *v6++;
v8 = v7;
ct_valgrind_int(4, v7 % 254);
ct_valgrind_cmd("thrd");
ct_valgrind_int(4, v8);
ct_valgrind_cmd("iter");
a2(v8, a3);
ct_valgrind_int(4, v8);
ct_valgrind_cmd("done");
}
while ( v6 != v5 );
}
free(ptr);
}

canonical_decompiled_code:
void __fastcall func4(int a1, void (__fastcall *a2)(_QWORD, __int64), __int64 a3)
{
__int64 v4; // rax
signed int *v5; // r13
signed int *v6; // r14
signed int v7; // eax
unsigned int v8; // er15
void *ptr; // [rsp+8h] [rbp-40h]

ct_valgrind_int(8, 0);
func3("setactiv");
v4 = ct_rand_perm((unsigned int)a1);
ptr = (void *)v4;
if ( a1 > 0 )
{
v5 = (signed int *)(v4 + 4LL * (unsigned int)a1);
v6 = (signed int *)v4;
do
{
v7 = *v6++;
v8 = v7;
ct_valgrind_int(4, v7 % 254);
func3("thrd");
ct_valgrind_int(4, v8);
func3("iter");
a2(v8, a3);
ct_valgrind_int(4, v8);
func3("done");
}
while ( v6 != v5 );
}
free(ptr);
}

original_code:
void ct_valgrind_for_loop(int n, ct_ind_func f, void* context, ct_canceller* c) {
    int i;
    int* perm;
    ct_valgrind_int(8, 0);
    ct_valgrind_cmd("setactiv");
    perm = ct_rand_perm(n);
    for(i=0; i<n; ++i) {
        int ind = perm[i];
        ct_valgrind_int(4, ind%254);
        ct_valgrind_cmd("thrd");
        ct_valgrind_int(4, ind);
        ct_valgrind_cmd("iter");
        f(ind, context);
        ct_valgrind_int(4, ind);
        ct_valgrind_cmd("done");
    }
    free(perm);
}

canonical_original_code:
void ct_valgrind_for_loop(int n, void (*f)(int ind, void *context), void *context, struct ct_canceller *c) {
    int i;
    int *perm;
    ct_valgrind_int(8, 0);
    ct_valgrind_cmd("setactiv");
    perm = ct_rand_perm(n);
    for(i=0; i<n; ++i) {
        int ind = perm[i];
        ct_valgrind_int(4, ind%254);
        ct_valgrind_cmd("thrd");
        ct_valgrind_int(4, ind);
        ct_valgrind_cmd("iter");
        f(ind, context);
        ct_valgrind_int(4, ind);
        ct_valgrind_cmd("done");
    }
    free(perm);
}

variable_types: n int

variable_types:
f
void (*)(int ind, void *context)

variable_types: struct ct_canceller { int cancelled; void *sched_data; } *

variable_types:
perm
int *

variable_types: ind int


decompiled_code:
void __fastcall ct_valgrind_for(unsigned int a1, __int64 a2, __int64 a3, __int64 a4)
{
int v6[11]; // [rsp+Ch] [rbp-2Ch] BYREF

v6[0] = 0;
ct_valgrind_cmd("begin_for");
ct_valgrind_ptr(8, (__int64)v6);
ct_valgrind_cmd("stackbot");
g_ct_valgrind_for(a1, a2, a3, a4);
ct_valgrind_cmd("end_for");
}

canonical_decompiled_code:
void __fastcall func5(unsigned int a1, __int64 a2, __int64 a3, __int64 a4)
{
int v6[11]; // [rsp+Ch] [rbp-2Ch] BYREF

v6[0] = 0;
func3("begin_for");
func2(8, (__int64)v6);
func3("stackbot");
g_ct_valgrind_for(a1, a2, a3, a4);
func3("end_for");
}

original_code:
void ct_valgrind_for(int n, ct_ind_func f, void* context, ct_canceller* c) {
    volatile int local=0;
    ct_valgrind_cmd("begin_for");
    ct_valgrind_ptr(8, &local);
    ct_valgrind_cmd("stackbot");
    (*g_ct_valgrind_for)(n,f,context,c);
    ct_valgrind_cmd("end_for");
}

canonical_original_code:
void ct_valgrind_for(int n, void (*f)(int ind, void *context), void *context, struct ct_canceller *c) {
    int local = 0;
    ct_valgrind_cmd("begin_for");
    ct_valgrind_ptr(8, &local);
    ct_valgrind_cmd("stackbot");
    (*g_ct_valgrind_for)(n,f,context,c);
    ct_valgrind_cmd("end_for");
}

variable_types:
context
void *

variable_types: local int


decompiled_code:
__int64 __fastcall ct_debug_get_owner(__int64 a1)
{
__int64 result; // rax
int i; // [rsp+8h] [rbp-10h]

ct_valgrind_ptr(8, a1);
ct_valgrind_cmd("getowner");
for ( i = 0; i <= 4; ++i )
;
if ( g_ct_valgrind_cmd[0] == 305419896 )
result = 4294967294LL;
else
result = g_ct_valgrind_cmd[0];
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1)
{
__int64 result; // rax
int i; // [rsp+8h] [rbp-10h]

func2(8, a1);
func3("getowner");
for ( i = 0; i <= 4; ++i )
;
if ( g_ct_valgrind_cmd[0] == 305419896 )
result = 4294967294LL;
else
result = g_ct_valgrind_cmd[0];
return result;
}

original_code:
int ct_debug_get_owner(const void* addr) {
    volatile int i,m;
    ct_valgrind_ptr(8, addr);
    ct_valgrind_cmd("getowner");
    for(i=0; i<5; ++i) {
        m = g_ct_valgrind_cmd.stored_magic;
    }
    return g_ct_valgrind_cmd.stored_magic == 0x12345678 ? (-2) : g_ct_valgrind_cmd.stored_magic;
}

canonical_original_code:
int ct_debug_get_owner(void *addr) {
    int i; int m;
    ct_valgrind_ptr(8, addr);
    ct_valgrind_cmd("getowner");
    for(i=0; i<5; ++i) {
        m = g_ct_valgrind_cmd.stored_magic;
    }
    return g_ct_valgrind_cmd.stored_magic == 0x12345678 ? (-2) : g_ct_valgrind_cmd.stored_magic;
}

variable_types:
addr
void *

variable_types: m int


decompiled_code:
void ct_serial_init()
{
;
}

original_code:
void ct_serial_init(const ct_env_var* env) {
    (void)env;
}

canonical_original_code:
void ct_serial_init(struct ct_env_var *env) {
    (void)env;
}

variable_types: struct ct_env_var { char *name; char *value; } *


decompiled_code:
void ct_serial_fini()
{
;
}

canonical_decompiled_code:
void func1()
{
;
}

original_code:
void ct_serial_fini(void) {
}

canonical_original_code:
void ct_serial_fini() {
}


decompiled_code:
__int64 __fastcall ct_serial_for(int a1, __int64 (__fastcall *a2)(__int64, __int64), __int64 a3, unsigned int *a4)
{
unsigned int v7; // ebx
__int64 v8; // rdi
__int64 result; // rax

if ( a1 > 0 )
{
v7 = 0;
do
{
result = *a4;
if ( (_DWORD)result )
break;
v8 = v7++;
result = a2(v8, a3);
}
while ( a1 != v7 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1, __int64 (__fastcall *a2)(__int64, __int64), __int64 a3, unsigned int *a4)
{
unsigned int v7; // ebx
__int64 v8; // rdi
__int64 result; // rax

if ( a1 > 0 )
{
v7 = 0;
do
{
result = *a4;
if ( (_DWORD)result )
break;
v8 = v7++;
result = a2(v8, a3);
}
while ( a1 != v7 );
}
return result;
}

original_code:
void ct_serial_for(int n, ct_ind_func f, void* context, ct_canceller* c) {
    int i;
    for(i=0; i<n; ++i) {
        if(c->cancelled) {
            break;
        }
        f(i, context);
    }
}

canonical_original_code:
void ct_serial_for(int n, void (*f)(int ind, void *context), void *context, struct ct_canceller *c) {
    int i;
    for(i=0; i<n; ++i) {
        if(c->cancelled) {
            break;
        }
        f(i, context);
    }
}


decompiled_code:
void *__fastcall child_fn(void *a1)
{
set_by_child = 1;
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func7(void *a1)
{
set_by_child = 1;
return 0LL;
}

original_code:
void* child_fn(void* arg) {
    set_by_child = 1;
    return 0;
}

canonical_original_code:
void *child_fn(void *arg) {
    set_by_child = 1;
    return 0;
}

variable_types:
arg
void *

return_type: void *


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
pthread_t newthread; // [rsp+8h] [rbp-50h] BYREF
pthread_attr_t attr; // [rsp+10h] [rbp-48h] BYREF

pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, 0);
pthread_create(&newthread, &attr, child_fn, 0LL);
pthread_join(newthread, 0LL);
if ( set_by_child == 1 )
puts("pthreads test passed");
else
puts("set_by_child not set by child!");
return 0;
}

original_code:
int main() {
    pthread_t child;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    pthread_create(&child, &attr, child_fn, 0);
    pthread_join(child, 0);
    if(set_by_child == 1) {
        printf("pthreads test passed\n");
    }
    else {
        printf("set_by_child not set by child!\n");
    }
}

canonical_original_code:
int main() {
    unsigned long child;
    union pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    pthread_create(&child, &attr, child_fn, 0);
    pthread_join(child, 0);
    if(set_by_child == 1) {
        printf("pthreads test passed\n");
    }
    else {
        printf("set_by_child not set by child!\n");
    }
}

variable_types:
child
unsigned long

variable_types: union pthread_attr_t { char __size[56]; long __align; }


decompiled_code:
__int64 run_omp_for()
{
return GOMP_parallel();
}

canonical_decompiled_code:
__int64 func8()
{
return GOMP_parallel();
}

original_code:
void run_omp_for(void) {
    int i;

#pragma omp parallel for
    for(i=0; i<100; ++i) {
        data_arr[i]=i;
        int tn = omp_get_thread_num();
        if(tn >= 0 && tn < 100) {
            thread_hist[tn]++;
        }
    }
}

canonical_original_code:
void run_omp_for() {
    int i;

#pragma omp parallel for
    for(i=0; i<100; ++i) {
        data_arr[i]=i;
        int tn = omp_get_thread_num();
        if(tn >= 0 && tn < 100) {
            thread_hist[tn]++;
        }
    }
}

variable_types: tn int


decompiled_code:
int test_omp_results()
{
__int64 i; // rsi
__int64 j; // rbx
__int64 v2; // rdx
__int64 v3; // rsi

for ( i = 0LL; i != 100; ++i )
{
if ( data_arr[i] != (_DWORD)i )
{
printf("wrong result at %d\n", i);
exit(1);
}
}
for ( j = 0LL; j != 100; ++j )
{
while ( 1 )
{
v2 = (unsigned int)thread_hist[j];
if ( (_DWORD)v2 )
break;
if ( ++j == 100 )
return puts("OpenMP test passed");
}
v3 = (unsigned int)j;
printf("OpenMP thread %d used %d times\n", v3, v2);
}
return puts("OpenMP test passed");
}

canonical_decompiled_code:
int func9()
{
__int64 i; // rsi
__int64 j; // rbx
__int64 v2; // rdx
__int64 v3; // rsi

for ( i = 0LL; i != 100; ++i )
{
if ( data_arr[i] != (_DWORD)i )
{
printf("wrong result at %d\n", i);
exit(1);
}
}
for ( j = 0LL; j != 100; ++j )
{
while ( 1 )
{
v2 = (unsigned int)thread_hist[j];
if ( (_DWORD)v2 )
break;
if ( ++j == 100 )
return puts("OpenMP test passed");
}
v3 = (unsigned int)j;
printf("OpenMP thread %d used %d times\n", v3, v2);
}
return puts("OpenMP test passed");
}

original_code:
void test_omp_results() {
    int i;
    for(i=0; i<100; ++i) {
        if(data_arr[i] != i) {
            printf("wrong result at %d\n", i);
            exit(1);
        }
    }
    for(i=0; i<100; ++i) {
        if(thread_hist[i] != 0) {
            printf("OpenMP thread %d used %d times\n", i, thread_hist[i]);
        }
    }
    printf("OpenMP test passed\n");
}


decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
run_omp_for(argc, argv, envp);
test_omp_results();
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
func8(argc, argv, envp);
func9();
return 0;
}

original_code:
int main() {
    run_omp_for();
    test_omp_results();
}


decompiled_code:
void ct_shuffle_fini()
{
;
}

original_code:
void ct_shuffle_fini(void) {
}

canonical_original_code:
void ct_shuffle_fini() {
}


decompiled_code:
int __fastcall ct_shuffle_init(__int64 a1)
{
const char *v1; // rax
int v2; // eax
const char *v3; // rax
int result; // eax

v1 = (const char *)ct_getenv(a1, "CT_RAND_SEED", "12345");
v2 = atoi(v1);
srand(v2);
v3 = (const char *)ct_getenv(a1, "CT_RAND_REV", "0");
result = atoi(v3);
g_ct_random_reverse = result;
return result;
}

canonical_decompiled_code:
int __fastcall func1(__int64 a1)
{
const char *v1; // rax
int v2; // eax
const char *v3; // rax
int result; // eax

v1 = (const char *)ct_getenv(a1, "CT_RAND_SEED", "12345");
v2 = atoi(v1);
srand(v2);
v3 = (const char *)ct_getenv(a1, "CT_RAND_REV", "0");
result = atoi(v3);
g_ct_random_reverse = result;
return result;
}

original_code:
void ct_shuffle_init(const ct_env_var* env) {
    srand(atoi(ct_getenv(env, "CT_RAND_SEED", "12345")));
    g_ct_random_reverse = atoi(ct_getenv(env, "CT_RAND_REV", "0"));
}

canonical_original_code:
void ct_shuffle_init(struct ct_env_var *env) {
    srand(atoi(ct_getenv(env, "CT_RAND_SEED", "12345")));
    g_ct_random_reverse = atoi(ct_getenv(env, "CT_RAND_REV", "0"));
}


original_code:
void ct_random_shuffle(int* p, int n) {
    int i;
    for(i=1; i<n; ++i) {
        int j = rand() % (i+1);
        int tmp = p[j];
        p[j] = p[i];
        p[i] = tmp;
    }
}

canonical_original_code:
void ct_random_shuffle(int *p, int n) {
    int i;
    for(i=1; i<n; ++i) {
        int j = rand() % (i+1);
        int tmp = p[j];
        p[j] = p[i];
        p[i] = tmp;
    }
}

variable_types:
p
int *

variable_types: j int

variable_types: tmp int


decompiled_code:
void __fastcall ct_shuffle_for(int a1, void (__fastcall *a2)(__int64, __int64), __int64 a3, _DWORD *a4)
{
_DWORD *v6; // rax
void *v7; // r15
unsigned int *v8; // rbx
unsigned int *v9; // r14
__int64 v10; // rdi

v6 = ct_rand_perm(a1);
v7 = v6;
if ( a1 > 0 )
{
v8 = v6;
v9 = &v6[a1];
do
{
if ( *a4 )
break;
v10 = *v8++;
a2(v10, a3);
}
while ( v8 != v9 );
}
free(v7);
}

canonical_decompiled_code:
void __fastcall func3(int a1, void (__fastcall *a2)(__int64, __int64), __int64 a3, _DWORD *a4)
{
_DWORD *v6; // rax
void *v7; // r15
unsigned int *v8; // rbx
unsigned int *v9; // r14
__int64 v10; // rdi

v6 = ct_rand_perm(a1);
v7 = v6;
if ( a1 > 0 )
{
v8 = v6;
v9 = &v6[a1];
do
{
if ( *a4 )
break;
v10 = *v8++;
a2(v10, a3);
}
while ( v8 != v9 );
}
free(v7);
}

original_code:
void ct_shuffle_for(int n, ct_ind_func f, void* context, ct_canceller* c) {
    int* perm = ct_rand_perm(n);
    int i;
    for(i=0; i<n; ++i) {
        if(c->cancelled) {
            break;
        }
        f(perm[i], context);
    }
    free(perm);
}

canonical_original_code:
void ct_shuffle_for(int n, void (*f)(int ind, void *context), void *context, struct ct_canceller *c) {
    int *perm = ct_rand_perm(n);
    int i;
    for(i=0; i<n; ++i) {
        if(c->cancelled) {
            break;
        }
        f(perm[i], context);
    }
    free(perm);
}

variable_types: n int

variable_types: i int


decompiled_code:
__int64 ct_nprocs()
{
return sysconf(84);
}

canonical_decompiled_code:
__int64 func0()
{
return sysconf(84);
}

original_code:
int ct_nprocs() {
    return sysconf( _SC_NPROCESSORS_ONLN );
}


decompiled_code:
__int64 __fastcall ct_work(int *a1)
{
int v2; // ebp
void (__fastcall *v3)(__int64, __int64); // r13
__int64 v4; // r12
__int64 v5; // rdi
__int64 result; // rax
unsigned int *v7; // rax

v2 = a1[2];
v3 = (void (__fastcall *)(__int64, __int64))*((_QWORD *)a1 + 2);
v4 = *((_QWORD *)a1 + 3);
while ( 1 )
{
result = (unsigned int)*a1;
if ( (int)result >= v2 )
break;
v5 = (unsigned int)_InterlockedExchangeAdd(a1, 1u);
if ( v2 > (int)v5 )
{
v7 = (unsigned int *)*((_QWORD *)a1 + 4);
if ( v7 )
{
result = *v7;
if ( (_DWORD)result )
{
a1[1] = 0;
*a1 = v2;
return result;
}
}
v3(v5, v4);
_InterlockedSub(a1 + 1, 1u);
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(int *a1)
{
int v2; // ebp
void (__fastcall *v3)(__int64, __int64); // r13
__int64 v4; // r12
__int64 v5; // rdi
__int64 result; // rax
unsigned int *v7; // rax

v2 = a1[2];
v3 = (void (__fastcall *)(__int64, __int64))*((_QWORD *)a1 + 2);
v4 = *((_QWORD *)a1 + 3);
while ( 1 )
{
result = (unsigned int)*a1;
if ( (int)result >= v2 )
break;
v5 = (unsigned int)_InterlockedExchangeAdd(a1, 1u);
if ( v2 > (int)v5 )
{
v7 = (unsigned int *)*((_QWORD *)a1 + 4);
if ( v7 )
{
result = *v7;
if ( (_DWORD)result )
{
a1[1] = 0;
*a1 = v2;
return result;
}
}
v3(v5, v4);
_InterlockedSub(a1 + 1, 1u);
}
}
return result;
}

original_code:
void ct_work(ct_work_item* item) {
    int n = item->n;
    ct_ind_func f = item->f;
    void* context = item->context;
    while(item->next_ind < n) {
        int next_ind = __sync_fetch_and_add(&item->next_ind,1);
        if(next_ind < n) {
            ct_canceller* canceller = item->canceller;
            if(canceller && canceller->cancelled) {
                item->to_do = 0;
                item->next_ind = n;
                break;
            }
            f(next_ind, context);
            __sync_fetch_and_sub(&item->to_do,1);
        }
    }
}

canonical_original_code:
void ct_work(struct ct_work_item *item) {
    int n = item->n;
    void (*f)(int ind, void *context) = item->f;
    void *context = item->context;
    while(item->next_ind < n) {
        int next_ind = __sync_fetch_and_add(&item->next_ind,1);
        if(next_ind < n) {
            struct ct_canceller *canceller = item->canceller;
            if(canceller && canceller->cancelled) {
                item->to_do = 0;
                item->next_ind = n;
                break;
            }
            f(next_ind, context);
            __sync_fetch_and_sub(&item->to_do,1);
        }
    }
}

variable_types: struct ct_work_item { int next_ind; int to_do; int n; int ref_cnt; void (*f)(int ind, void *context); void *context; struct ct_canceller { int cancelled; void *sched_data; } *canceller; } *

variable_types:
f
void (*)(int ind, void *context)


decompiled_code:
char *__fastcall get_message(__int64 a1)
{
char *result; // rax

if ( (int)a1 > 80 )
return 0LL;
if ( !loaded_language )
{
a1 = (int)a1;
return en_messages[a1];
}
a1 = (int)a1;
if ( !*(_QWORD *)loaded_language )
return en_messages[a1];
result = *(char **)(*(_QWORD *)loaded_language + 8LL * (int)a1);
if ( !result )
return en_messages[a1];
return result;
}

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

if ( (int)a1 > 80 )
return 0LL;
if ( !loaded_language )
{
a1 = (int)a1;
return en_messages[a1];
}
a1 = (int)a1;
if ( !*(_QWORD *)loaded_language )
return en_messages[a1];
result = *(char **)(*(_QWORD *)loaded_language + 8LL * (int)a1);
if ( !result )
return en_messages[a1];
return result;
}

original_code:
const char* get_message(int mesg_number) {
 if(mesg_number >= mesg_end) return ((void *)0);
 return ((loaded_language&&loaded_language->messages)?
  (loaded_language->messages[mesg_number]?
   loaded_language->messages[mesg_number]:en_messages[mesg_number]):
  en_messages[mesg_number]);
}

canonical_original_code:
char *get_message(int mesg_number) {
 if(mesg_number >= mesg_end) return ((void *)0);
 return ((loaded_language&&loaded_language->messages)?
  (loaded_language->messages[mesg_number]?
   loaded_language->messages[mesg_number]:en_messages[mesg_number]):
  en_messages[mesg_number]);
}


decompiled_code:
void unload_language()
{
char **v0; // rbp
char *v1; // r8
__int64 i; // rbx
void *v3; // rdi
void **v4; // rdi

if ( loaded_language_name )
{
free(loaded_language_name);
loaded_language_name = 0LL;
}
v0 = (char **)loaded_language;
if ( loaded_language )
{
v1 = *(char **)loaded_language;
if ( *(_QWORD *)loaded_language )
{
for ( i = 0LL; i != 648; i += 8LL )
{
v3 = *(void **)&v1[i];
if ( v3 )
{
free(v3);
v1 = *v0;
}
}
free(v1);
}
v4 = (void **)v0[1];
if ( v4 )
{
if ( v4[1] )
{
free(v4[1]);
v4 = (void **)v0[1];
}
if ( v4[2] )
{
free(v4[2]);
v4 = (void **)v0[1];
}
free(v4);
}
free(v0);
loaded_language = 0LL;
}
}

canonical_decompiled_code:
void func1()
{
char **v0; // rbp
char *v1; // r8
__int64 i; // rbx
void *v3; // rdi
void **v4; // rdi

if ( loaded_language_name )
{
free(loaded_language_name);
loaded_language_name = 0LL;
}
v0 = (char **)loaded_language;
if ( loaded_language )
{
v1 = *(char **)loaded_language;
if ( *(_QWORD *)loaded_language )
{
for ( i = 0LL; i != 648; i += 8LL )
{
v3 = *(void **)&v1[i];
if ( v3 )
{
free(v3);
v1 = *v0;
}
}
free(v1);
}
v4 = (void **)v0[1];
if ( v4 )
{
if ( v4[1] )
{
free(v4[1]);
v4 = (void **)v0[1];
}
if ( v4[2] )
{
free(v4[2]);
v4 = (void **)v0[1];
}
free(v4);
}
free(v0);
loaded_language = 0LL;
}
}

original_code:
void unload_language() {
 if(loaded_language_name) {
  free(loaded_language_name);
  loaded_language_name = ((void *)0);
 }
 if(!loaded_language) return;
 if(loaded_language->messages) {
  unsigned i;
  for(i = 0; i < mesg_end; ++i) {
   if(loaded_language->messages[i]) free(loaded_language->messages[i]);
  }
  free(loaded_language->messages);
 }
 if(loaded_language->ranges) {
  if(loaded_language->ranges->range_begins) free(loaded_language->ranges->range_begins);
  if(loaded_language->ranges->range_ends) free(loaded_language->ranges->range_ends);
  free(loaded_language->ranges);
 }
 free(loaded_language);
 loaded_language = ((void *)0);
}

canonical_original_code:
void unload_language() {
 if(loaded_language_name) {
  free(loaded_language_name);
  loaded_language_name = ((void *)0);
 }
 if(!loaded_language) return;
 if(loaded_language->messages) {
  unsigned int i;
  for(i = 0; i < mesg_end; ++i) {
   if(loaded_language->messages[i]) free(loaded_language->messages[i]);
  }
  free(loaded_language->messages);
 }
 if(loaded_language->ranges) {
  if(loaded_language->ranges->range_begins) free(loaded_language->ranges->range_begins);
  if(loaded_language->ranges->range_ends) free(loaded_language->ranges->range_ends);
  free(loaded_language->ranges);
 }
 free(loaded_language);
 loaded_language = ((void *)0);
}

variable_types:
i
unsigned int


decompiled_code:
__int64 __fastcall load_language(const char *a1)
{
__int64 *v1; // r13
void **v3; // rsi
void **v4; // rdi
char *v5; // rax
__int64 v6; // rdx
__int64 v7; // rcx
__int64 v8; // r8
__int64 v9; // r9
__int64 *v10; // rax
__int64 v11; // rax
char *v12; // rax
char *v13; // rax
__int64 v14; // [rsp+0h] [rbp-38h] BYREF

if ( !a1 )
return 0LL;
if ( !strcmp(a1, "builtin") )
{
LODWORD(v1) = 1;
if ( loaded_language )
unload_language();
return (unsigned int)v1;
}
v3 = (void **)malloc(0x18uLL);
if ( (unsigned __int8)get_language_ranges(a1, v3) )
{
if ( !v3 )
{
LABEL_10:
v5 = get_message(9LL);
error_message(v5);
return 0LL;
}
v4 = v3;
LABEL_9:
free(v4);
goto LABEL_10;
}
get_font_ranges(&v14);
LODWORD(v1) = ranges_compatible(&v14, v3, v6, v7, v8, v9);
if ( !(_BYTE)v1 )
{
free(v3[1]);
free(v3[2]);
free(v3);
v12 = get_message(11LL);
error_message(v12);
return (unsigned int)v1;
}
v10 = (__int64 *)malloc(0x10uLL);
v1 = v10;
if ( !v10 )
{
free(v3[1]);
free(v3[2]);
free(v3);
v13 = get_message(9LL);
error_message(v13);
return (unsigned int)v1;
}
v10[1] = (__int64)v3;
v11 = get_language_messages(a1);
*v1 = v11;
if ( !v11 )
{
free(v3[1]);
free(v3[2]);
free(v3);
v4 = (void **)v1;
goto LABEL_9;
}
if ( loaded_language )
unload_language();
loaded_language = v1;
loaded_language_name = (void *)make_string(a1);
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(const char *a1)
{
__int64 *v1; // r13
void **v3; // rsi
void **v4; // rdi
char *v5; // rax
__int64 v6; // rdx
__int64 v7; // rcx
__int64 v8; // r8
__int64 v9; // r9
__int64 *v10; // rax
__int64 v11; // rax
char *v12; // rax
char *v13; // rax
__int64 v14; // [rsp+0h] [rbp-38h] BYREF

if ( !a1 )
return 0LL;
if ( !strcmp(a1, "builtin") )
{
LODWORD(v1) = 1;
if ( loaded_language )
func1();
return (unsigned int)v1;
}
v3 = (void **)malloc(0x18uLL);
if ( (unsigned __int8)get_language_ranges(a1, v3) )
{
if ( !v3 )
{
LABEL_10:
v5 = func0(9LL);
error_message(v5);
return 0LL;
}
v4 = v3;
LABEL_9:
free(v4);
goto LABEL_10;
}
get_font_ranges(&v14);
LODWORD(v1) = ranges_compatible(&v14, v3, v6, v7, v8, v9);
if ( !(_BYTE)v1 )
{
free(v3[1]);
free(v3[2]);
free(v3);
v12 = func0(11LL);
error_message(v12);
return (unsigned int)v1;
}
v10 = (__int64 *)malloc(0x10uLL);
v1 = v10;
if ( !v10 )
{
free(v3[1]);
free(v3[2]);
free(v3);
v13 = func0(9LL);
error_message(v13);
return (unsigned int)v1;
}
v10[1] = (__int64)v3;
v11 = get_language_messages(a1);
*v1 = v11;
if ( !v11 )
{
free(v3[1]);
free(v3[2]);
free(v3);
v4 = (void **)v1;
goto LABEL_9;
}
if ( loaded_language )
func1();
loaded_language = v1;
loaded_language_name = (void *)make_string(a1);
return 1LL;
}

original_code:
char load_language(const char *lang) {
 if(!lang) return 0;
 if(strcmp(lang,"builtin") == 0) {
  if(loaded_language) unload_language();
  return 1;
 }
 char_ranges *ranges = malloc(sizeof(char_ranges));
 if(get_language_ranges(lang,ranges) != 0) {
  if(ranges) free(ranges);
  error_message(get_message(mesg_load_language_error));
  return 0;
 }
 if(!ranges_compatible(get_font_ranges(),*ranges)) {
  free(ranges->range_begins);
  free(ranges->range_ends);
  free(ranges);
  error_message(get_message(mesg_theme_too_short_error));
  return 0;
 }
 language *new_language = malloc(sizeof(language));
 if(!new_language) {
  free(ranges->range_begins);
  free(ranges->range_ends);
  free(ranges);
  error_message(get_message(mesg_load_language_error));
  return 0;
 }
 new_language->ranges = ranges;
 new_language->messages = get_language_messages(lang);
 if(!new_language->messages) {
  free(ranges->range_begins);
  free(ranges->range_ends);
  free(ranges);
  free(new_language);
  error_message(get_message(mesg_load_language_error));
  return 0;
 }
 if(loaded_language) unload_language();
 loaded_language = new_language;
 loaded_language_name = make_string(lang);
 return 1;
}

canonical_original_code:
char load_language(char *lang) {
 if(!lang) return 0;
 if(strcmp(lang,"builtin") == 0) {
  if(loaded_language) unload_language();
  return 1;
 }
 struct char_ranges *ranges = malloc(sizeof(char_ranges));
 if(get_language_ranges(lang,ranges) != 0) {
  if(ranges) free(ranges);
  error_message(get_message(mesg_load_language_error));
  return 0;
 }
 if(!ranges_compatible(get_font_ranges(),*ranges)) {
  free(ranges->range_begins);
  free(ranges->range_ends);
  free(ranges);
  error_message(get_message(mesg_theme_too_short_error));
  return 0;
 }
 struct language *new_language = malloc(sizeof(language));
 if(!new_language) {
  free(ranges->range_begins);
  free(ranges->range_ends);
  free(ranges);
  error_message(get_message(mesg_load_language_error));
  return 0;
 }
 new_language->ranges = ranges;
 new_language->messages = get_language_messages(lang);
 if(!new_language->messages) {
  free(ranges->range_begins);
  free(ranges->range_ends);
  free(ranges);
  free(new_language);
  error_message(get_message(mesg_load_language_error));
  return 0;
 }
 if(loaded_language) unload_language();
 loaded_language = new_language;
 loaded_language_name = make_string(lang);
 return 1;
}

variable_types:
lang
char *

variable_types: struct language { char **messages; struct char_ranges { unsigned int num_ranges; unsigned int *range_begins; unsigned int *range_ends; } *ranges; } *

return_type: char

user_defined_types: struct language { char **messages; struct char_ranges *ranges; }


decompiled_code:
const char *get_loaded_language_name()
{
const char *result; // rax

result = (const char *)loaded_language_name;
if ( !loaded_language_name )
result = "builtin";
return result;
}

canonical_decompiled_code:
const char *func3()
{
const char *result; // rax

result = (const char *)loaded_language_name;
if ( !loaded_language_name )
result = "builtin";
return result;
}

original_code:
const char* get_loaded_language_name() {
 if(loaded_language_name) return loaded_language_name;
 return "builtin";
}

canonical_original_code:
char *get_loaded_language_name() {
 if(loaded_language_name) return loaded_language_name;
 return "builtin";
}


hash

repo: yoshiomori/neighborhoods

decompiled_code:
__int64 __fastcall hash(char *a1)
{
unsigned int v1; // er8
char v2; // cl
int v3; // edx
int v4; // eax

v1 = length_vector;
if ( length_vector )
{
v2 = *a1;
if ( *a1 )
{
v3 = 0;
do
{
v4 = v2;
v2 = *++a1;
v3 = (254 * v3 + v4) % length_vector;
}
while ( v2 );
v1 = v3;
}
else
{
v1 = 0;
}
}
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func0(char *a1)
{
unsigned int v1; // er8
char v2; // cl
int v3; // edx
int v4; // eax

v1 = length_vector;
if ( length_vector )
{
v2 = *a1;
if ( *a1 )
{
v3 = 0;
do
{
v4 = v2;
v2 = *++a1;
v3 = (254 * v3 + v4) % length_vector;
}
while ( v2 );
v1 = v3;
}
else
{
v1 = 0;
}
}
return v1;
}

original_code:
static int hash(char *s){
  int h = 0;
  if(length_vector)
    for(h = 0; *s; s++)
      h = (254 * h + *s) % length_vector;
  return h;
}

variable_types:
s
char *

variable_types: h int


decompiled_code:
void __noreturn format_error()
{
puts(s);
exit(0);
}

canonical_decompiled_code:
void __noreturn func1()
{
puts(s);
exit(0);
}

original_code:
void format_error(){
  printf("Arquivo não está no formato correto, veja arquivo_padrão\n");
  exit(0);
}


decompiled_code:
void __noreturn memory_error()
{
puts(aMem);
exit(0);
}

canonical_decompiled_code:
void __noreturn func2()
{
puts(aMem);
exit(0);
}

original_code:
void memory_error(){
  printf("Memória insuficiente!\n");
  exit(0);
}


decompiled_code:
void alloc_alphabet()
{
int v0; // ebx
char **v1; // rbp
size_t v2; // rdi
char **v3; // r10
__int64 v4; // r11

v0 = length_vector;
if ( length_vector / 2 >= vector_free_space )
{
v1 = (char **)data;
v2 = prime[iprime++];
length_vector = v2;
vector_free_space = v2;
data = calloc(v2, 8uLL);
if ( !data )
memory_error();
if ( v0 > 0 )
{
v3 = v1;
v4 = (__int64)&v1[(unsigned int)(v0 - 1) + 1];
do
{
if ( *v3 )
insert_alphabet(*v3);
++v3;
}
while ( v3 != (char **)v4 );
}
if ( v1 )
free(v1);
}
}

canonical_decompiled_code:
void func3()
{
int v0; // ebx
char **v1; // rbp
size_t v2; // rdi
char **v3; // r10
__int64 v4; // r11

v0 = length_vector;
if ( length_vector / 2 >= vector_free_space )
{
v1 = (char **)data;
v2 = prime[iprime++];
length_vector = v2;
vector_free_space = v2;
data = calloc(v2, 8uLL);
if ( !data )
func2();
if ( v0 > 0 )
{
v3 = v1;
v4 = (__int64)&v1[(unsigned int)(v0 - 1) + 1];
do
{
if ( *v3 )
insert_alphabet(*v3);
++v3;
}
while ( v3 != (char **)v4 );
}
if ( v1 )
free(v1);
}
}

original_code:
void alloc_alphabet(){
  char **aux_alphabet = data.alphabet;
  int aux_length_vector = length_vector;
  int i = 0;
  if(vector_free_space <= length_vector / 2){
    vector_free_space = length_vector = prime[iprime++];
    if(!(data.alphabet = calloc(length_vector, sizeof(*data.alphabet))))
      memory_error();
    for(i = 0; i < aux_length_vector; i++)
      if(aux_alphabet[i])
 insert_alphabet(aux_alphabet[i]);
    if(aux_alphabet){
      free(aux_alphabet);
      aux_alphabet = ((void *)0);
    }
  }
}


decompiled_code:
const char *__fastcall search_alphabet(char *s1)
{
int v1; // eax
_QWORD *v2; // r13
int v3; // ebx
const char *v4; // r14
int v5; // ebp

v1 = hash(s1);
v2 = data;
if ( !data )
return 0LL;
v3 = v1;
v4 = (const char *)*((_QWORD *)data + v1);
if ( v4 )
{
v5 = length_vector;
do
{
if ( !strcmp(s1, v4) )
break;
v4 = (const char *)v2[(v3 + 1) % v5];
v3 = (v3 + 1) % v5;
}
while ( v4 );
}
return v4;
}

canonical_decompiled_code:
const char *__fastcall func4(char *s1)
{
int v1; // eax
_QWORD *v2; // r13
int v3; // ebx
const char *v4; // r14
int v5; // ebp

v1 = func0(s1);
v2 = data;
if ( !data )
return 0LL;
v3 = v1;
v4 = (const char *)*((_QWORD *)data + v1);
if ( v4 )
{
v5 = length_vector;
do
{
if ( !strcmp(s1, v4) )
break;
v4 = (const char *)v2[(v3 + 1) % v5];
v3 = (v3 + 1) % v5;
}
while ( v4 );
}
return v4;
}

original_code:
char *search_alphabet(char *symbol){
  int i = hash(symbol);
  if(data.alphabet)
    while(data.alphabet[i] != ((void *)0)){
      if(!strcmp(symbol, data.alphabet[i]))
 return data.alphabet[i];
      else
 i = (i + 1) % length_vector;
    }
  return ((void *)0);
}

variable_types:
symbol
char *


decompiled_code:
int __fastcall read_alphabet(__int64 a1)
{
char **v1; // rbx
char *v2; // rax
char *i; // rbp
char *v4; // rdi

data = 0LL;
*((_DWORD *)&data + 4) = 0;
if ( !a1 )
format_error();
v1 = (char **)chop();
symbol = v1;
v2 = *v1;
*(&data + 1) = *v1;
for ( i = *v1; *v1; i = *v1 )
{
while ( search_alphabet(i) )
{
++v1;
LODWORD(v2) = printf("Letra %s repetiu no alfabeto.\n", i);
i = *v1;
if ( !*v1 )
return (int)v2;
}
alloc_alphabet();
v4 = *v1++;
LODWORD(v2) = (unsigned int)insert_alphabet(v4);
}
return (int)v2;
}

canonical_decompiled_code:
int __fastcall func5(__int64 a1)
{
char **v1; // rbx
char *v2; // rax
char *i; // rbp
char *v4; // rdi

data = 0LL;
*((_DWORD *)&data + 4) = 0;
if ( !a1 )
func1();
v1 = (char **)chop();
symbol = v1;
v2 = *v1;
*(&data + 1) = *v1;
for ( i = *v1; *v1; i = *v1 )
{
while ( func4(i) )
{
++v1;
LODWORD(v2) = printf("Letra %s repetiu no alfabeto.\n", i);
i = *v1;
if ( !*v1 )
return (int)v2;
}
func3();
v4 = *v1++;
LODWORD(v2) = (unsigned int)insert_alphabet(v4);
}
return (int)v2;
}

original_code:
void read_alphabet(char *line){
  char **aux = ((void *)0);
  data.alphabet = ((void *)0);
  data.size_alphabet = 0;
  if(!line)
    format_error();
  symbol = chop(line);
  data.first_char = *symbol;
  for(aux = symbol; *aux; aux++){
    if(!search_alphabet(*aux)){
      alloc_alphabet();
      insert_alphabet(*aux);
    }
    else
      printf("Letra %s repetiu no alfabeto.\n", *aux);
  }
}

variable_types:
line
char *

variable_types:
aux
char **


decompiled_code:
void delete_alphabet()
{
if ( data )
{
free(data);
data = 0LL;
}
if ( symbol )
{
free(symbol);
symbol = 0LL;
}
}

canonical_decompiled_code:
void func6()
{
if ( data )
{
free(data);
data = 0LL;
}
if ( symbol )
{
free(symbol);
symbol = 0LL;
}
}

original_code:
void delete_alphabet(){
  if(data.alphabet){
    free(data.alphabet);
    data.alphabet = ((void *)0);
  }
  if(symbol){
    free(symbol);
    symbol = ((void *)0);
  }
}


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

result = calloc(a1, 0xCuLL);
if ( !result )
{
puts(s);
exit(0);
}
return result;
}

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

result = calloc(a1, 0xCuLL);
if ( !result )
{
puts(s);
exit(0);
}
return result;
}

original_code:
node node_init(int size){
  node aux;
  if(!(aux = calloc(size, sizeof *aux))){
    printf("Memória insuficiente\n");
    exit(0);
  }
  return aux;
}

canonical_original_code:
struct NODE *node_init(int size){
  struct NODE *aux;
  if(!(aux = calloc(size, sizeof *aux))){
    printf("Memória insuficiente\n");
    exit(0);
  }
  return aux;
}

variable_types: size int

variable_types: struct NODE { int not_null; int pos_word; int num_occur; } *


original_code:
long vert_neig_hash(int pos, word_table table){
  unsigned int h = 0;
  Vertice *c;
  for(c = table->set; *c; c++)
    h = (h * data.size_alphabet + ((*c)->info[pos] - data.first_char)) % table->length_vert_neig;
  return h;
}

canonical_original_code:
long vert_neig_hash(int pos, struct WORD_TABLE *table){
  unsigned int h = 0;
  struct VERTICE **c;
  for(c = table->set; *c; c++)
    h = (h * data.size_alphabet + ((*c)->info[pos] - data.first_char)) % table->length_vert_neig;
  return h;
}

variable_types: pos int

variable_types: struct WORD_TABLE { struct VERTICE { int line; char **info; unsigned long size_info; struct NEIGHBORHOOD { struct VERTICE **vertice; int size; struct WORD_TABLE *table; } neighborhood; } **set; struct NODE { int not_null; int pos_word; int num_occur; } *word_vert_neig; int length_vert_neig; int free_vert_neig; struct NODE *word_neig; int length_neig; int free_neig; double f; } *

variable_types:
h
unsigned int

variable_types: struct VERTICE { int line; char **info; unsigned long size_info; struct NEIGHBORHOOD { struct VERTICE **vertice; int size; struct WORD_TABLE { struct VERTICE **set; struct NODE { int not_null; int pos_word; int num_occur; } *word_vert_neig; int length_vert_neig; int free_vert_neig; struct NODE *word_neig; int length_neig; int free_neig; double f; } *table; } neighborhood; } **

return_type: long

user_defined_types: struct WORD_TABLE { struct VERTICE **set; struct NODE *word_vert_neig; int length_vert_neig; int free_vert_neig; struct NODE *word_neig; int length_neig; int free_neig; double f; }

user_defined_types: struct VERTICE { int line; char **info; unsigned long size_info; struct NEIGHBORHOOD neighborhood; }


original_code:
void expand_vert_neig(word_table table){
  node aux = table->word_vert_neig;
  int aux_length = table->length_vert_neig;
  int i, h;
  table->word_vert_neig = node_init(table->length_vert_neig = prime[vert_neig++]);
  table->free_vert_neig = table->length_vert_neig;
  for(i = 0; i < aux_length; i++)
    if(aux[i].not_null){
      h = vert_neig_hash(aux[i].pos_word, table);
      while(table->word_vert_neig[h].not_null)
 h = (h + 1) % table->length_vert_neig;
      table->word_vert_neig[h].not_null = 1;
      table->word_vert_neig[h].pos_word = aux[i].pos_word;
      table->word_vert_neig[h].num_occur = aux[i].num_occur;
      table->free_vert_neig--;
    }
  if(aux){
    free(aux);
    aux = ((void *)0);
  }
}

canonical_original_code:
void expand_vert_neig(struct WORD_TABLE *table){
  struct NODE *aux = table->word_vert_neig;
  int aux_length = table->length_vert_neig;
  int i; int h;
  table->word_vert_neig = node_init(table->length_vert_neig = prime[vert_neig++]);
  table->free_vert_neig = table->length_vert_neig;
  for(i = 0; i < aux_length; i++)
    if(aux[i].not_null){
      h = vert_neig_hash(aux[i].pos_word, table);
      while(table->word_vert_neig[h].not_null)
 h = (h + 1) % table->length_vert_neig;
      table->word_vert_neig[h].not_null = 1;
      table->word_vert_neig[h].pos_word = aux[i].pos_word;
      table->word_vert_neig[h].num_occur = aux[i].num_occur;
      table->free_vert_neig--;
    }
  if(aux){
    free(aux);
    aux = ((void *)0);
  }
}

variable_types: i int

user_defined_types: struct NODE { int not_null; int pos_word; int num_occur; }

user_defined_types: struct NEIGHBORHOOD { struct VERTICE **vertice; int size; struct WORD_TABLE *table; }


original_code:
void vert_neig_insert(int pos, word_table table){
  long h = vert_neig_hash(pos, table);
  node aux;
  if(!(aux = vert_neig_search(pos, table))){
    while(table->word_vert_neig[h].not_null)
      h = (h + 1) % table->length_vert_neig;
    table->word_vert_neig[h].not_null = 1;
    table->word_vert_neig[h].pos_word = pos;
    table->word_vert_neig[h].num_occur++;
    if(--table->free_vert_neig <= table->length_vert_neig / 2)
      expand_vert_neig(table);
  }
  else
    aux->num_occur++;
}

canonical_original_code:
void vert_neig_insert(int pos, struct WORD_TABLE *table){
  long h = vert_neig_hash(pos, table);
  struct NODE *aux;
  if(!(aux = vert_neig_search(pos, table))){
    while(table->word_vert_neig[h].not_null)
      h = (h + 1) % table->length_vert_neig;
    table->word_vert_neig[h].not_null = 1;
    table->word_vert_neig[h].pos_word = pos;
    table->word_vert_neig[h].num_occur++;
    if(--table->free_vert_neig <= table->length_vert_neig / 2)
      expand_vert_neig(table);
  }
  else
    aux->num_occur++;
}

variable_types: h long


original_code:
long neig_hash(int pos,word_table table){
  long h = 0;
  Vertice *c;
  for(c = table->set + 1; *c; c++)
    h = (h * data.size_alphabet + ((*c)->info[pos] - data.first_char)) % table->length_neig;
  return h;
}

canonical_original_code:
long neig_hash(int pos, struct WORD_TABLE *table){
  long h = 0;
  struct VERTICE **c;
  for(c = table->set + 1; *c; c++)
    h = (h * data.size_alphabet + ((*c)->info[pos] - data.first_char)) % table->length_neig;
  return h;
}


original_code:
void expand_neig(word_table table){
  node aux = table->word_neig;
  int aux_length = table->length_neig;
  int i, h;
  table->word_neig = node_init(table->length_neig = prime[neig++]);
  table->free_neig = table->length_neig;
  for(i = 0; i < aux_length; i++)
    if(aux[i].not_null){
      h = neig_hash(aux[i].pos_word, table);
      while(table->word_neig[h].not_null)
 h = (h + 1) % table->length_neig;
      table->word_neig[h].not_null = 1;
      table->word_neig[h].pos_word = aux[i].pos_word;
      table->word_neig[h].num_occur = aux[i].num_occur;
      table->free_neig--;
    }
  if(aux){
    free(aux);
    aux = ((void *)0);
  }
}

canonical_original_code:
void expand_neig(struct WORD_TABLE *table){
  struct NODE *aux = table->word_neig;
  int aux_length = table->length_neig;
  int i; int h;
  table->word_neig = node_init(table->length_neig = prime[neig++]);
  table->free_neig = table->length_neig;
  for(i = 0; i < aux_length; i++)
    if(aux[i].not_null){
      h = neig_hash(aux[i].pos_word, table);
      while(table->word_neig[h].not_null)
 h = (h + 1) % table->length_neig;
      table->word_neig[h].not_null = 1;
      table->word_neig[h].pos_word = aux[i].pos_word;
      table->word_neig[h].num_occur = aux[i].num_occur;
      table->free_neig--;
    }
  if(aux){
    free(aux);
    aux = ((void *)0);
  }
}


original_code:
void neig_insert(int pos, word_table table){
  long h = neig_hash(pos, table);
  node aux;
  if(!(aux = neig_search(pos, table))){
    while(table->word_neig[h].not_null)
      h = (h + 1) % table->length_neig;
    table->word_neig[h].not_null = 1;
    table->word_neig[h].pos_word = pos;
    table->word_neig[h].num_occur++;
    if(--table->free_neig <= table->length_neig / 2)
      expand_neig(table);
  }
  else
    aux->num_occur++;
}

canonical_original_code:
void neig_insert(int pos, struct WORD_TABLE *table){
  long h = neig_hash(pos, table);
  struct NODE *aux;
  if(!(aux = neig_search(pos, table))){
    while(table->word_neig[h].not_null)
      h = (h + 1) % table->length_neig;
    table->word_neig[h].not_null = 1;
    table->word_neig[h].pos_word = pos;
    table->word_neig[h].num_occur++;
    if(--table->free_neig <= table->length_neig / 2)
      expand_neig(table);
  }
  else
    aux->num_occur++;
}


processing

original_code:
void processing(){
  int i = 0, j = 0, k, l, m;
  int stop;
  int pos;
  int size;
  word_table cur, prev, aux_table;
  node aux, aux_stop;
  for(i = 0; i < data.vertice_head.first_free_pos; i++){
    size = 0;
    cur = word_table_init(data.vertice_head.vertice[i].neighborhood.size + 2);
    prev = word_table_init(data.vertice_head.vertice[i].neighborhood.size + 2);
    prev->set[0] = &data.vertice_head.vertice[i];
    prev->set[1] = ((void *)0);
    for(pos = 0; prev->set[0]->info[pos]; pos++)
      vert_neig_insert(pos, prev);
    for(k = 0; k < prev->length_vert_neig; k++)
      if(prev->word_vert_neig[k].not_null)
 prev->f += (double)prev->word_vert_neig[k].num_occur * log((double)prev->word_vert_neig[k].num_occur / (double)data.vertice_head.vertice[i].size_info);
    prev->f -= data.constant * log((double)data.vertice_head.vertice[i].size_info) / log((double)data.size_alphabet);
    for(j = 0, stop = 1; j < data.vertice_head.vertice[i].neighborhood.size; j++)
      stop <<= 1;
    for(k = 1; k != stop; k++){
      cur->f = 0;
      cur->free_neig = cur->length_neig;
      cur->free_vert_neig = cur->length_vert_neig;
      for(aux = cur->word_vert_neig, aux_stop = aux + cur->length_vert_neig; aux < aux_stop; aux++){
 if(aux->not_null){
   aux->not_null = 0;
   aux->num_occur = 0;
 }
      }
      for(aux = cur->word_neig, aux_stop = aux + cur->length_neig; aux < aux_stop; aux++){
 if(aux->not_null){
   aux->not_null = 0;
   aux->num_occur = 0;
 }
      }
      cur->set[0] = &data.vertice_head.vertice[i];
      for(l = 0, m = 1; k >> l; l++)
       if(k >> l & 1)
         cur->set[m++] = cur->set[0]->neighborhood.vertice[l];
      cur->set[m] = ((void *)0);
      for(pos = 0; cur->set[0]->info[pos]; pos++){
 neig_insert(pos, cur);
 vert_neig_insert(pos, cur);
      }
      for(l = 0; l < cur->length_vert_neig; l++)
       if(cur->word_vert_neig[l].not_null){
         aux = neig_search(cur->word_vert_neig[l].pos_word, cur);
         cur->f += (double)cur->word_vert_neig[l].num_occur * log((double)cur->word_vert_neig[l].num_occur / (double)aux->num_occur);
       }
      cur->f -= data.constant * pow((double)data.size_alphabet, (double)(m-1)) * log((double)data.vertice_head.vertice[i].size_info) / log((double)data.size_alphabet);
      if(prev->f <= cur->f){
       aux_table = cur;
       cur = prev;
       prev = aux_table;
       size = m - 1;
      }
    }
    if(cur){
      free(cur);
      cur = ((void *)0);
    }
    data.vertice_head.vertice[i].neighborhood.table = prev;
    if(data.vertice_head.vertice[i].neighborhood.vertice){
      free(data.vertice_head.vertice[i].neighborhood.vertice);
      data.vertice_head.vertice[i].neighborhood.vertice = ((void *)0);
    }
    data.vertice_head.vertice[i].neighborhood.vertice = (prev->set) + 1;
    data.vertice_head.vertice[i].neighborhood.size = size;
  }
}

canonical_original_code:
void processing(){
  int i = 0; int j = 0; int k; int l; int m;
  int stop;
  int pos;
  int size;
  struct WORD_TABLE *cur; struct WORD_TABLE *prev; struct WORD_TABLE *aux_table;
  struct NODE *aux; struct NODE *aux_stop;
  for(i = 0; i < data.vertice_head.first_free_pos; i++){
    size = 0;
    cur = word_table_init(data.vertice_head.vertice[i].neighborhood.size + 2);
    prev = word_table_init(data.vertice_head.vertice[i].neighborhood.size + 2);
    prev->set[0] = &data.vertice_head.vertice[i];
    prev->set[1] = ((void *)0);
    for(pos = 0; prev->set[0]->info[pos]; pos++)
      vert_neig_insert(pos, prev);
    for(k = 0; k < prev->length_vert_neig; k++)
      if(prev->word_vert_neig[k].not_null)
 prev->f += (double)prev->word_vert_neig[k].num_occur * log((double)prev->word_vert_neig[k].num_occur / (double)data.vertice_head.vertice[i].size_info);
    prev->f -= data.constant * log((double)data.vertice_head.vertice[i].size_info) / log((double)data.size_alphabet);
    for(j = 0, stop = 1; j < data.vertice_head.vertice[i].neighborhood.size; j++)
      stop <<= 1;
    for(k = 1; k != stop; k++){
      cur->f = 0;
      cur->free_neig = cur->length_neig;
      cur->free_vert_neig = cur->length_vert_neig;
      for(aux = cur->word_vert_neig, aux_stop = aux + cur->length_vert_neig; aux < aux_stop; aux++){
 if(aux->not_null){
   aux->not_null = 0;
   aux->num_occur = 0;
 }
      }
      for(aux = cur->word_neig, aux_stop = aux + cur->length_neig; aux < aux_stop; aux++){
 if(aux->not_null){
   aux->not_null = 0;
   aux->num_occur = 0;
 }
      }
      cur->set[0] = &data.vertice_head.vertice[i];
      for(l = 0, m = 1; k >> l; l++)
       if(k >> l & 1)
         cur->set[m++] = cur->set[0]->neighborhood.vertice[l];
      cur->set[m] = ((void *)0);
      for(pos = 0; cur->set[0]->info[pos]; pos++){
 neig_insert(pos, cur);
 vert_neig_insert(pos, cur);
      }
      for(l = 0; l < cur->length_vert_neig; l++)
       if(cur->word_vert_neig[l].not_null){
         aux = neig_search(cur->word_vert_neig[l].pos_word, cur);
         cur->f += (double)cur->word_vert_neig[l].num_occur * log((double)cur->word_vert_neig[l].num_occur / (double)aux->num_occur);
       }
      cur->f -= data.constant * pow((double)data.size_alphabet, (double)(m-1)) * log((double)data.vertice_head.vertice[i].size_info) / log((double)data.size_alphabet);
      if(prev->f <= cur->f){
       aux_table = cur;
       cur = prev;
       prev = aux_table;
       size = m - 1;
      }
    }
    if(cur){
      free(cur);
      cur = ((void *)0);
    }
    data.vertice_head.vertice[i].neighborhood.table = prev;
    if(data.vertice_head.vertice[i].neighborhood.vertice){
      free(data.vertice_head.vertice[i].neighborhood.vertice);
      data.vertice_head.vertice[i].neighborhood.vertice = ((void *)0);
    }
    data.vertice_head.vertice[i].neighborhood.vertice = (prev->set) + 1;
    data.vertice_head.vertice[i].neighborhood.size = size;
  }
}

variable_types: j int

variable_types: k int

variable_types: l int

variable_types: m int

variable_types: stop int


decompiled_code:
void __fastcall __noreturn format_error_vertice(__int64 a1)
{
printf(format, a1);
exit(0);
}

canonical_decompiled_code:
void __fastcall __noreturn func0(__int64 a1)
{
printf(format, a1);
exit(0);
}

original_code:
void format_error_vertice(char *symbol){
  printf("A letra %s não está presente no alfabeto!\n", symbol);
  exit(0);
}


decompiled_code:
char *read_vertice()
{
__int64 v0; // rbx
_QWORD *v1; // rbp
__int64 v2; // rax
__int64 v3; // r12
int v4; // edx
char *v5; // rdi
__int64 v6; // rax
int v7; // edx
char *result; // rax
int v9; // ecx
char *v10; // rax

v0 = 0LL;
v1 = (_QWORD *)chop();
if ( *v1 )
{
do
{
v2 = search_alphabet();
v1[v0] = v2;
if ( !v2 )
format_error_vertice(0LL);
if ( first_time_3 )
++size_info_vertice_2;
++v0;
}
while ( v1[v0] );
}
v3 = size_info_vertice_2;
if ( size_info_vertice_2 != v0 )
{
puts(s);
exit(0);
}
if ( first_time_3 )
{
result = (char *)malloc(0x1E0uLL);
*((_QWORD *)&data + 4) = result;
if ( !result )
{
puts(aMem_0);
exit(0);
}
*((_DWORD *)&data + 10) = 10;
v7 = 1;
}
else
{
v4 = *((_DWORD *)&data + 11);
v5 = (char *)*((_QWORD *)&data + 4);
if ( v4 == *((_DWORD *)&data + 10) )
{
*((_DWORD *)&data + 10) = 2 * v4;
v10 = (char *)realloc(v5, 96LL * v4);
*((_QWORD *)&data + 4) = v10;
if ( !v10 )
{
puts(aMem);
exit(0);
}
v7 = *((_DWORD *)&data + 11) + 1;
result = &v10[48 * *((int *)&data + 11)];
}
else
{
v6 = v4;
v7 = v4 + 1;
result = &v5[48 * v6];
}
}
v9 = count_1;
*((_QWORD *)result + 1) = v1;
first_time_3 = 0;
*(_DWORD *)result = v9;
count_1 = v9 + 1;
*((_DWORD *)&data + 11) = v7;
*((_QWORD *)result + 2) = v3;
return result;
}

canonical_decompiled_code:
char *func1()
{
__int64 v0; // rbx
_QWORD *v1; // rbp
__int64 v2; // rax
__int64 v3; // r12
int v4; // edx
char *v5; // rdi
__int64 v6; // rax
int v7; // edx
char *result; // rax
int v9; // ecx
char *v10; // rax

v0 = 0LL;
v1 = (_QWORD *)chop();
if ( *v1 )
{
do
{
v2 = search_alphabet();
v1[v0] = v2;
if ( !v2 )
func0(0LL);
if ( first_time_3 )
++size_info_vertice_2;
++v0;
}
while ( v1[v0] );
}
v3 = size_info_vertice_2;
if ( size_info_vertice_2 != v0 )
{
puts(s);
exit(0);
}
if ( first_time_3 )
{
result = (char *)malloc(0x1E0uLL);
*((_QWORD *)&data + 4) = result;
if ( !result )
{
puts(aMem_0);
exit(0);
}
*((_DWORD *)&data + 10) = 10;
v7 = 1;
}
else
{
v4 = *((_DWORD *)&data + 11);
v5 = (char *)*((_QWORD *)&data + 4);
if ( v4 == *((_DWORD *)&data + 10) )
{
*((_DWORD *)&data + 10) = 2 * v4;
v10 = (char *)realloc(v5, 96LL * v4);
*((_QWORD *)&data + 4) = v10;
if ( !v10 )
{
puts(aMem);
exit(0);
}
v7 = *((_DWORD *)&data + 11) + 1;
result = &v10[48 * *((int *)&data + 11)];
}
else
{
v6 = v4;
v7 = v4 + 1;
result = &v5[48 * v6];
}
}
v9 = count_1;
*((_QWORD *)result + 1) = v1;
first_time_3 = 0;
*(_DWORD *)result = v9;
count_1 = v9 + 1;
*((_DWORD *)&data + 11) = v7;
*((_QWORD *)result + 2) = v3;
return result;
}

original_code:
void read_vertice(char *line){
  char **info_vertice = ((void *)0);
  char **aux = ((void *)0);
  unsigned long int size = 0;
  static int first_time = 1;
  static unsigned long int size_info_vertice = 0;
  static int count = 0;
  info_vertice = chop(line);
  for(aux = info_vertice; *aux; aux++){
    if(!(*aux = search_alphabet(*aux)))
      format_error_vertice(*aux);
    if(first_time)
      size_info_vertice++;
    size++;
  }
  if(size_info_vertice != size){
    printf("Vertice com mais informação que outras!\n");
    exit(0);
  }
  if(first_time){
    if(!(data.vertice_head.vertice = malloc(10 * sizeof *data.vertice_head.vertice))){
      printf("Memória insuficiente!\n");
      exit(0);
    }
    data.vertice_head.length = 10;
    data.vertice_head.first_free_pos = 0;
  }
  else if(data.vertice_head.first_free_pos == data.vertice_head.length){
    data.vertice_head.length += data.vertice_head.length;
    if(!(data.vertice_head.vertice = realloc(data.vertice_head.vertice, data.vertice_head.length * sizeof *data.vertice_head.vertice))){
      printf("Memória insuficiente\n");
      exit(0);
    }
  }
  data.vertice_head.vertice[data.vertice_head.first_free_pos].line = count++;
  data.vertice_head.vertice[data.vertice_head.first_free_pos].info = info_vertice;
  data.vertice_head.vertice[data.vertice_head.first_free_pos++].size_info = size_info_vertice;
  first_time = 0;
}

canonical_original_code:
void read_vertice(char *line){
  char **info_vertice = ((void *)0);
  char **aux = ((void *)0);
  unsigned long size = 0;
  static int first_time = 1;
  static unsigned long size_info_vertice = 0;
  static int count = 0;
  info_vertice = chop(line);
  for(aux = info_vertice; *aux; aux++){
    if(!(*aux = search_alphabet(*aux)))
      format_error_vertice(*aux);
    if(first_time)
      size_info_vertice++;
    size++;
  }
  if(size_info_vertice != size){
    printf("Vertice com mais informação que outras!\n");
    exit(0);
  }
  if(first_time){
    if(!(data.vertice_head.vertice = malloc(10 * sizeof *data.vertice_head.vertice))){
      printf("Memória insuficiente!\n");
      exit(0);
    }
    data.vertice_head.length = 10;
    data.vertice_head.first_free_pos = 0;
  }
  else if(data.vertice_head.first_free_pos == data.vertice_head.length){
    data.vertice_head.length += data.vertice_head.length;
    if(!(data.vertice_head.vertice = realloc(data.vertice_head.vertice, data.vertice_head.length * sizeof *data.vertice_head.vertice))){
      printf("Memória insuficiente\n");
      exit(0);
    }
  }
  data.vertice_head.vertice[data.vertice_head.first_free_pos].line = count++;
  data.vertice_head.vertice[data.vertice_head.first_free_pos].info = info_vertice;
  data.vertice_head.vertice[data.vertice_head.first_free_pos++].size_info = size_info_vertice;
  first_time = 0;
}

variable_types:
size
unsigned long

variable_types: count int


decompiled_code:
__int64 read_neighborhood()
{
const char **v0; // rax
const char *v1; // r13
const char **v2; // r12
const char **v3; // r14
const char *v4; // rbx
int v5; // ebp
int v6; // ebx
const char **v7; // rax
const char *v8; // rdx
int v9; // ebp
_QWORD *v10; // rcx
__int64 v11; // rsi
const char **v12; // rdx
__int64 result; // rax
void *v14; // rdx

v0 = (const char **)chop();
v1 = *v0;
if ( !*v0 )
{
if ( !*((_DWORD *)&data + 11) )
{
v14 = malloc(0LL);
if ( v14 )
{
v6 = current_vertice_0;
result = *((_QWORD *)&data + 4) + 48LL * current_vertice_0;
*(_QWORD *)(result + 24) = v14;
*(_DWORD *)(result + 32) = 0;
goto LABEL_18;
}
LABEL_24:
puts(aMem_0);
exit(0);
}
LABEL_19:
puts(aErroDeSintaxeN);
puts(aIndica);
exit(0);
}
v2 = v0;
v3 = v0;
v4 = *v0;
v5 = 0;
do
{
if ( (unsigned int)strlen(v4) != 1 || (unsigned __int8)(*v4 - 48) > 1u )
{
puts(aErroDeSintaxeN);
puts("Permitido apenas 0 ou 1 na matriz.");
exit(0);
}
v4 = v3[1];
++v3;
++v5;
}
while ( v4 );
if ( v5 != *((_DWORD *)&data + 11) )
goto LABEL_19;
v6 = current_vertice_0;
v7 = v2;
v8 = v1;
v9 = 0;
do
{
if ( *v8 != 48 )
{
if ( current_vertice_0 == (unsigned int)(v7 - v2) )
{
puts(aErroDeSintaxeN);
puts("Diagonal deve ser zerada.");
exit(0);
}
++v9;
}
v8 = v7[1];
++v7;
}
while ( v8 );
v10 = malloc(8LL * v9);
if ( !v10 )
goto LABEL_24;
v11 = *((_QWORD *)&data + 4);
v12 = v2;
result = v11 + 48LL * v6;
*(_QWORD *)(result + 24) = v10;
*(_DWORD *)(result + 32) = v9;
do
{
if ( *v1 != 48 )
{
++v10;
result = v11 + 48LL * (int)(v12 - v2);
*(v10 - 1) = result;
}
v1 = v12[1];
++v12;
}
while ( v1 );
LABEL_18:
current_vertice_0 = v6 + 1;
return result;
}

canonical_decompiled_code:
__int64 func2()
{
const char **v0; // rax
const char *v1; // r13
const char **v2; // r12
const char **v3; // r14
const char *v4; // rbx
int v5; // ebp
int v6; // ebx
const char **v7; // rax
const char *v8; // rdx
int v9; // ebp
_QWORD *v10; // rcx
__int64 v11; // rsi
const char **v12; // rdx
__int64 result; // rax
void *v14; // rdx

v0 = (const char **)chop();
v1 = *v0;
if ( !*v0 )
{
if ( !*((_DWORD *)&data + 11) )
{
v14 = malloc(0LL);
if ( v14 )
{
v6 = current_vertice_0;
result = *((_QWORD *)&data + 4) + 48LL * current_vertice_0;
*(_QWORD *)(result + 24) = v14;
*(_DWORD *)(result + 32) = 0;
goto LABEL_18;
}
LABEL_24:
puts(aMem_0);
exit(0);
}
LABEL_19:
puts(aErroDeSintaxeN);
puts(aIndica);
exit(0);
}
v2 = v0;
v3 = v0;
v4 = *v0;
v5 = 0;
do
{
if ( (unsigned int)strlen(v4) != 1 || (unsigned __int8)(*v4 - 48) > 1u )
{
puts(aErroDeSintaxeN);
puts("Permitido apenas 0 ou 1 na matriz.");
exit(0);
}
v4 = v3[1];
++v3;
++v5;
}
while ( v4 );
if ( v5 != *((_DWORD *)&data + 11) )
goto LABEL_19;
v6 = current_vertice_0;
v7 = v2;
v8 = v1;
v9 = 0;
do
{
if ( *v8 != 48 )
{
if ( current_vertice_0 == (unsigned int)(v7 - v2) )
{
puts(aErroDeSintaxeN);
puts("Diagonal deve ser zerada.");
exit(0);
}
++v9;
}
v8 = v7[1];
++v7;
}
while ( v8 );
v10 = malloc(8LL * v9);
if ( !v10 )
goto LABEL_24;
v11 = *((_QWORD *)&data + 4);
v12 = v2;
result = v11 + 48LL * v6;
*(_QWORD *)(result + 24) = v10;
*(_DWORD *)(result + 32) = v9;
do
{
if ( *v1 != 48 )
{
++v10;
result = v11 + 48LL * (int)(v12 - v2);
*(v10 - 1) = result;
}
v1 = v12[1];
++v12;
}
while ( v1 );
LABEL_18:
current_vertice_0 = v6 + 1;
return result;
}

original_code:
void read_neighborhood(char *line){
  char **neighborhood = ((void *)0);
  char **aux = ((void *)0);
  int size = 0;
  static int current_vertice = 0;
  Vertice *current_neighborhood = ((void *)0);
  neighborhood = chop(line);
  for(aux = neighborhood, size = 0; *aux; aux++, size++)
    if((int)strlen(*aux) != 1 || (**aux != '0' && **aux != '1')){
      printf("Erro de sintaxe na matriz de vizinhança!\n");
      printf("Permitido apenas 0 ou 1 na matriz.\n");
      exit(0);
    }
  if(size != data.vertice_head.first_free_pos){
    printf("Erro de sintaxe na matriz de vizinhança!\n");
    printf("Indicação de vizinhaça a mais.\n");
    exit(0);
  }
  for(aux = neighborhood, size = 0; *aux; aux++)
    if(**aux - '0'){
      if(current_vertice == (int)(aux - neighborhood)){
 printf("Erro de sintaxe na matriz de vizinhança!\n");
 printf("Diagonal deve ser zerada.\n");
 exit(0);
      }
      size++;
    }
  if(!(current_neighborhood = malloc(size * sizeof *current_neighborhood))){
    printf("Memória insuficiente!\n");
    exit(0);
  }
  data.vertice_head.vertice[current_vertice].neighborhood.vertice = current_neighborhood;
  data.vertice_head.vertice[current_vertice].neighborhood.size = size;
  for(aux = neighborhood; *aux; aux++)
    if(**aux - '0')
      *(current_neighborhood++) = &data.vertice_head.vertice[(int)(aux - neighborhood)];
  current_vertice++;
}

canonical_original_code:
void read_neighborhood(char *line){
  char **neighborhood = ((void *)0);
  char **aux = ((void *)0);
  int size = 0;
  static int current_vertice = 0;
  struct VERTICE **current_neighborhood = ((void *)0);
  neighborhood = chop(line);
  for(aux = neighborhood, size = 0; *aux; aux++, size++)
    if((int)strlen(*aux) != 1 || (**aux != '0' && **aux != '1')){
      printf("Erro de sintaxe na matriz de vizinhança!\n");
      printf("Permitido apenas 0 ou 1 na matriz.\n");
      exit(0);
    }
  if(size != data.vertice_head.first_free_pos){
    printf("Erro de sintaxe na matriz de vizinhança!\n");
    printf("Indicação de vizinhaça a mais.\n");
    exit(0);
  }
  for(aux = neighborhood, size = 0; *aux; aux++)
    if(**aux - '0'){
      if(current_vertice == (int)(aux - neighborhood)){
 printf("Erro de sintaxe na matriz de vizinhança!\n");
 printf("Diagonal deve ser zerada.\n");
 exit(0);
      }
      size++;
    }
  if(!(current_neighborhood = malloc(size * sizeof *current_neighborhood))){
    printf("Memória insuficiente!\n");
    exit(0);
  }
  data.vertice_head.vertice[current_vertice].neighborhood.vertice = current_neighborhood;
  data.vertice_head.vertice[current_vertice].neighborhood.size = size;
  for(aux = neighborhood; *aux; aux++)
    if(**aux - '0')
      *(current_neighborhood++) = &data.vertice_head.vertice[(int)(aux - neighborhood)];
  current_vertice++;
}

variable_types:
line
char *

variable_types:
neighborhood
char **


decompiled_code:
unsigned __int64 __fastcall binary_search(unsigned __int64 a1, __int64 a2, int a3)
{
int v3; // eax
unsigned __int64 v4; // rcx

while ( 1 )
{
v3 = a3;
a3 /= 2;
v4 = *(_QWORD *)(a2 + 8LL * a3);
if ( v4 == a1 )
return a1;
if ( !a3 )
break;
if ( v4 <= a1 )
{
if ( v4 >= a1 )
return 0LL;
a2 += 8LL * (a3 + 1);
a3 = v3 - a3 - 1;
}
}
return 0LL;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func3(unsigned __int64 a1, __int64 a2, int a3)
{
int v3; // eax
unsigned __int64 v4; // rcx

while ( 1 )
{
v3 = a3;
a3 /= 2;
v4 = *(_QWORD *)(a2 + 8LL * a3);
if ( v4 == a1 )
return a1;
if ( !a3 )
break;
if ( v4 <= a1 )
{
if ( v4 >= a1 )
return 0LL;
a2 += 8LL * (a3 + 1);
a3 = v3 - a3 - 1;
}
}
return 0LL;
}

original_code:
Vertice binary_search(Vertice v, Vertice *n, int size){
  int p = size / 2;
  if(v == n[p])
    return v;
  else if(p){
    if(v < n[p])
      return binary_search(v, n, p);
    if(v > n[p])
      return binary_search(v, &n[p + 1], size - p - 1);
  }
  return ((void *)0);
}

canonical_original_code:
struct VERTICE *binary_search(struct VERTICE *v, struct VERTICE **n, int size){
  int p = size / 2;
  if(v == n[p])
    return v;
  else if(p){
    if(v < n[p])
      return binary_search(v, n, p);
    if(v > n[p])
      return binary_search(v, &n[p + 1], size - p - 1);
  }
  return ((void *)0);
}

variable_types:
v
struct VERTICE *

variable_types:
n
struct VERTICE **

variable_types: size int

variable_types: p int

return_type: struct VERTICE { int line; char **info; unsigned long size_info; struct NEIGHBORHOOD { struct VERTICE **vertice; int size; struct WORD_TABLE { struct VERTICE **set; struct NODE { int not_null; int pos_word; int num_occur; } *word_vert_neig; int length_vert_neig; int free_vert_neig; struct NODE *word_neig; int length_neig; int free_neig; double f; } *table; } neighborhood; } *


decompiled_code:
unsigned __int64 __fastcall neighborhood_search(unsigned __int64 a1, __int64 a2)
{
return binary_search(a1, *(_QWORD *)a2, *(_DWORD *)(a2 + 8));
}

canonical_decompiled_code:
unsigned __int64 __fastcall func4(unsigned __int64 a1, __int64 a2)
{
return func3(a1, *(_QWORD *)a2, *(_DWORD *)(a2 + 8));
}

original_code:
Vertice neighborhood_search(Vertice v, Neighborhood *n){
  return binary_search(v, n->vertice, n->size);
}

canonical_original_code:
struct VERTICE *neighborhood_search(struct VERTICE *v, struct NEIGHBORHOOD *n){
  return binary_search(v, n->vertice, n->size);
}

variable_types:
n
struct NEIGHBORHOOD *


error

decompiled_code:
void __fastcall __noreturn error(const char *a1)
{
perror(a1);
exit(0);
}

canonical_decompiled_code:
void __fastcall __noreturn func7(const char *a1)
{
perror(a1);
exit(0);
}

original_code:
void error(char *str){
  perror(str);
  exit(0);
}

variable_types:
str
char *


decompiled_code:
void *__fastcall safe_malloc(size_t a1)
{
void *result; // rax

result = malloc(a1);
if ( !result )
error("malloc");
return result;
}

canonical_decompiled_code:
void *__fastcall func8(size_t a1)
{
void *result; // rax

result = malloc(a1);
if ( !result )
func7("malloc");
return result;
}

original_code:
void *safe_malloc(size_t size){
  void *aux = malloc(size);
  if(!aux)
    error("malloc");
  return aux;
}

canonical_original_code:
void *safe_malloc(unsigned long size){
  void *aux = malloc(size);
  if(!aux)
    error("malloc");
  return aux;
}

variable_types:
aux
void *


decompiled_code:
void *__fastcall safe_realloc(void *a1, size_t a2)
{
void *result; // rax

result = realloc(a1, a2);
if ( !result )
error("realloc");
return result;
}

canonical_decompiled_code:
void *__fastcall func9(void *a1, size_t a2)
{
void *result; // rax

result = realloc(a1, a2);
if ( !result )
func7("realloc");
return result;
}

original_code:
void *safe_realloc(void *array, size_t size){
  if(!(array = realloc(array, size)))
    error("realloc");
  return array;
}

canonical_original_code:
void *safe_realloc(void *array, unsigned long size){
  if(!(array = realloc(array, size)))
    error("realloc");
  return array;
}

variable_types:
array
void *


decompiled_code:
_BOOL8 __fastcall end_read_block(_BYTE *a1)
{
_BOOL8 result; // rax

result = 1LL;
if ( a1 )
{
while ( *a1 == 32 )
++a1;
result = *a1 == 0;
}
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func0(_BYTE *a1)
{
_BOOL8 result; // rax

result = 1LL;
if ( a1 )
{
while ( *a1 == 32 )
++a1;
result = *a1 == 0;
}
return result;
}

original_code:
int end_read_block(char *line){
  if(line){
    while(*line == ' ')
      line++;
    if(*line)
      return 0;
  }
  return 1;
}


info

decompiled_code:
void __noreturn info()
{
puts(s);
exit(0);
}

original_code:
void info(){
  printf("USO:\n\t./neighborhood NOME_DO_ARQUIVO_DE_DADOS [nome_do_arquivo_de_saída_prob] [nome_do_arquivo_de_saída_neig]\n\n");
  exit(0);
}


decompiled_code:
void __noreturn format_error_constant()
{
puts("Erro no formato da constante no arquivo!");
exit(0);
}

canonical_decompiled_code:
void __noreturn func0()
{
puts("Erro no formato da constante no arquivo!");
exit(0);
}

original_code:
void format_error_constant(){
  printf("Erro no formato da constante no arquivo!\n");
  exit(0);
}


decompiled_code:
__int64 __fastcall read_constant(unsigned __int8 *a1, double a2, double a3)
{
__int64 result; // rax
unsigned __int8 *v4; // rcx
unsigned __int8 *v5; // rdx

data[3] = 0.0;
result = *a1;
if ( (_BYTE)result )
{
while ( (unsigned __int8)(result - 48) <= 9u )
{
++a1;
a3 = data[3] * 10.0;
data[3] = a3;
a2 = (double)((char)*(a1 - 1) - 48) + a3;
data[3] = a2;
result = *a1;
if ( !(_BYTE)result )
return result;
}
if ( (result & 0xFD) != 44 )
goto LABEL_19;
result = a1[1];
*(_QWORD *)&a2 = (unsigned int)LC1;
v4 = a1 + 1;
if ( !(_BYTE)result )
return result;
while ( (unsigned __int8)(result - 48) <= 9u )
{
++v4;
a2 = *(float *)&a2 * 0.1;
*(float *)&a2 = a2;
a3 = (float)((float)(char)(result - 48) * *(float *)&a2) + data[3];
data[3] = a3;
result = *v4;
if ( !(_BYTE)result )
return result;
}
if ( (_BYTE)result != 32 && (_BYTE)result != 10 )
LABEL_19:
format_error_constant(a2, a3, 10.0);
result = v4[1];
v5 = v4 + 1;
if ( (_BYTE)result )
{
while ( (_BYTE)result == 32 || (_BYTE)result == 10 )
{
result = *++v5;
if ( !(_BYTE)result )
return result;
}
goto LABEL_19;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned __int8 *a1, double a2, double a3)
{
__int64 result; // rax
unsigned __int8 *v4; // rcx
unsigned __int8 *v5; // rdx

data[3] = 0.0;
result = *a1;
if ( (_BYTE)result )
{
while ( (unsigned __int8)(result - 48) <= 9u )
{
++a1;
a3 = data[3] * 10.0;
data[3] = a3;
a2 = (double)((char)*(a1 - 1) - 48) + a3;
data[3] = a2;
result = *a1;
if ( !(_BYTE)result )
return result;
}
if ( (result & 0xFD) != 44 )
goto LABEL_19;
result = a1[1];
*(_QWORD *)&a2 = (unsigned int)LC1;
v4 = a1 + 1;
if ( !(_BYTE)result )
return result;
while ( (unsigned __int8)(result - 48) <= 9u )
{
++v4;
a2 = *(float *)&a2 * 0.1;
*(float *)&a2 = a2;
a3 = (float)((float)(char)(result - 48) * *(float *)&a2) + data[3];
data[3] = a3;
result = *v4;
if ( !(_BYTE)result )
return result;
}
if ( (_BYTE)result != 32 && (_BYTE)result != 10 )
LABEL_19:
func0(a2, a3, 10.0);
result = v4[1];
v5 = v4 + 1;
if ( (_BYTE)result )
{
while ( (_BYTE)result == 32 || (_BYTE)result == 10 )
{
result = *++v5;
if ( !(_BYTE)result )
return result;
}
goto LABEL_19;
}
}
return result;
}

original_code:
void read_constant(char *line){
  int state = 0;
  float decimal = 1;
  data.constant = 0;
  for(; *line; line++){
    switch(state){
    case 0:
      if('0' <= *line && *line <= '9')
 data.constant = (data.constant *= 10) + (float)(*line - '0');
      else if(*line == '.' || *line == ',')
 state = 1;
      else
 format_error_constant();
      break;
    case 1:
      if('0' <= *line && *line <= '9')
 data.constant += (float)(*line - '0') * (decimal *= 0.1);
      else if(*line == ' ' || *line == '\n')
 state = 2;
      else
 format_error_constant();
      break;
    case 2:
      if(*line != ' ' && *line != '\n')
 format_error_constant();
      break;
    }
  }
}

variable_types: state int

variable_types: decimal float


CharToDigit

decompiled_code:
__int64 __fastcall CharToDigit(char a1)
{
return (unsigned int)(a1 - 48);
}

canonical_decompiled_code:
__int64 __fastcall func7(char a1)
{
return (unsigned int)(a1 - 48);
}

original_code:
static int CharToDigit(char ch)
{
    return (ch - '0');
}

variable_types: ch char


decompiled_code:
__int64 __fastcall mt_get_addr_info(_QWORD *a1)
{
if ( !a1 || !__memory_trace_info_head_ )
return 0xFFFFFFFFLL;
*a1 = __memory_trace_info_head_;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(_QWORD *a1)
{
if ( !a1 || !__memory_trace_info_head_ )
return 0xFFFFFFFFLL;
*a1 = __memory_trace_info_head_;
return 0LL;
}

original_code:
int mt_get_addr_info(mti **mt)
{
 if(!mt || !___memory_trace_info_head___){
  return -1;
 }
 *mt = ___memory_trace_info_head___;
 return 0;
}

canonical_original_code:
int mt_get_addr_info(struct malloc_trace_info **mt)
{
 if(!mt || !___memory_trace_info_head___){
  return -1;
 }
 *mt = ___memory_trace_info_head___;
 return 0;
}

variable_types: struct malloc_trace_info { char *head; struct malloc_trace_info *prev; struct malloc_trace_info *next; unsigned long size; char *callfunc; char *file; int line; } **


decompiled_code:
__int64 __fastcall mt_get_addr_next_info(__int64 a1)
{
if ( !a1 || !*(_QWORD *)a1 )
return 0xFFFFFFFFLL;
*(_QWORD *)a1 = *(_QWORD *)(*(_QWORD *)a1 + 16LL);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
if ( !a1 || !*(_QWORD *)a1 )
return 0xFFFFFFFFLL;
*(_QWORD *)a1 = *(_QWORD *)(*(_QWORD *)a1 + 16LL);
return 0LL;
}

original_code:
int mt_get_addr_next_info(mti **mt)
{
 if(!mt || !*mt){
  return -1;
 }
 *mt = (*mt)->next;
 return 0;
}

canonical_original_code:
int mt_get_addr_next_info(struct malloc_trace_info **mt)
{
 if(!mt || !*mt){
  return -1;
 }
 *mt = (*mt)->next;
 return 0;
}

user_defined_types: struct malloc_trace_info { char *head; struct malloc_trace_info *prev; struct malloc_trace_info *next; unsigned long size; char *callfunc; char *file; int line; }


decompiled_code:
__int64 __fastcall mt_get_addr(__int64 a1, _QWORD *a2, _QWORD *a3, _QWORD *a4, _QWORD *a5, _DWORD *a6)
{
__int64 result; // rax

if ( !a1 )
return 0xFFFFFFFFLL;
if ( a2 )
*a2 = a1 + 56;
if ( a3 )
*a3 = *(_QWORD *)(a1 + 24);
if ( a4 )
*a4 = *(_QWORD *)(a1 + 32);
if ( a5 )
*a5 = *(_QWORD *)(a1 + 40);
result = 0LL;
if ( a6 )
*a6 = *(_DWORD *)(a1 + 48);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, _QWORD *a2, _QWORD *a3, _QWORD *a4, _QWORD *a5, _DWORD *a6)
{
__int64 result; // rax

if ( !a1 )
return 0xFFFFFFFFLL;
if ( a2 )
*a2 = a1 + 56;
if ( a3 )
*a3 = *(_QWORD *)(a1 + 24);
if ( a4 )
*a4 = *(_QWORD *)(a1 + 32);
if ( a5 )
*a5 = *(_QWORD *)(a1 + 40);
result = 0LL;
if ( a6 )
*a6 = *(_DWORD *)(a1 + 48);
return result;
}

original_code:
int mt_get_addr(mti *mt, void **addr, size_t *size, char **callfunc, char **file, int *line)
{
 if(!mt){
  return -1;
 }
 if(addr){
  *addr = (void *)(((char*)mt) + sizeof(mti));
 }
 if(size)*size = mt->size;
 if(callfunc)*callfunc = mt->callfunc;
 if(file)*file = mt->file;
 if(line)*line = mt->line;
 return 0;
}

canonical_original_code:
int mt_get_addr(struct malloc_trace_info *mt, void **addr, unsigned long *size, char **callfunc, char **file, int *line)
{
 if(!mt){
  return -1;
 }
 if(addr){
  *addr = (void *)(((char *)mt) + sizeof(mti));
 }
 if(size)*size = mt->size;
 if(callfunc)*callfunc = mt->callfunc;
 if(file)*file = mt->file;
 if(line)*line = mt->line;
 return 0;
}

variable_types: struct malloc_trace_info { char *head; struct malloc_trace_info *prev; struct malloc_trace_info *next; unsigned long size; char *callfunc; char *file; int line; } *

variable_types:
addr
void **

variable_types:
size
unsigned long *

variable_types:
callfunc
char **

variable_types:
file
char **

variable_types:
line
int *


decompiled_code:
__int64 mt_get_count()
{
unsigned int v0; // er8
__int64 v2; // [rsp+8h] [rbp-8h] BYREF

if ( !(unsigned int)mt_get_addr_info(&v2) )
{
do
mt_get_addr_next_info((__int64)&v2);
while ( v2 );
}
return v0;
}

canonical_decompiled_code:
__int64 func3()
{
unsigned int v0; // er8
__int64 v2; // [rsp+8h] [rbp-8h] BYREF

if ( !(unsigned int)func0(&v2) )
{
do
func1((__int64)&v2);
while ( v2 );
}
return v0;
}

original_code:
int mt_get_count(void)
{
 mti *mt;
 int i = 0;
 if(mt_get_addr_info(&mt) != 0){
  return 0;
 }
 i++;
 while(1){
  mt_get_addr_next_info(&mt);
  if(!mt){
   break;
  }
  i++;
 }
 return i;
}

canonical_original_code:
int mt_get_count()
{
 struct malloc_trace_info *mt;
 int i = 0;
 if(mt_get_addr_info(&mt) != 0){
  return 0;
 }
 i++;
 while(1){
  mt_get_addr_next_info(&mt);
  if(!mt){
   break;
  }
  i++;
 }
 return i;
}

variable_types: i int


decompiled_code:
__int64 __fastcall mt_get_addr_by_mti(__int64 a1)
{
_DWORD *v1; // rax
__int64 v2; // rdi
bool v3; // zf
__int64 result; // rax

v1 = *(_DWORD **)(a1 - 56);
v2 = a1 - 56;
v3 = *v1 == 4805709;
result = 0LL;
if ( v3 )
result = v2;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
_DWORD *v1; // rax
__int64 v2; // rdi
bool v3; // zf
__int64 result; // rax

v1 = *(_DWORD **)(a1 - 56);
v2 = a1 - 56;
v3 = *v1 == 4805709;
result = 0LL;
if ( v3 )
result = v2;
return result;
}

original_code:
mti* mt_get_addr_by_mti(void *addr)
{
 mti *mt;
 int i;
 mt = (mti*)(((char*)addr) - sizeof(mti));
 if(!mt){
  return ((void *)0);
 }
 i = memcmp(mt->head, ___mti_check_header___, strlen(___mti_check_header___) + 1);
 return (i == 0 ? mt : ((void *)0));
}

canonical_original_code:
struct malloc_trace_info *mt_get_addr_by_mti(void *addr)
{
 struct malloc_trace_info *mt;
 int i;
 mt = (struct malloc_trace_info *)(((char *)addr) - sizeof(mti));
 if(!mt){
  return ((void *)0);
 }
 i = memcmp(mt->head, ___mti_check_header___, strlen(___mti_check_header___) + 1);
 return (i == 0 ? mt : ((void *)0));
}

variable_types:
addr
void *

return_type: struct malloc_trace_info { char *head; struct malloc_trace_info *prev; struct malloc_trace_info *next; unsigned long size; char *callfunc; char *file; int line; } *