main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char **v4; // rbx
const char *v5; // rdi
const char *v6; // rax
__int64 *v8; // rbx
int v9; // ebp
void *v10; // rcx
__int64 v11; // rdi
const char *v12; // rax

if ( (int)Str_find(*argv, 1LL, 0LL, "dirname") <= 0 )
{
if ( argc > 1 )
{
v8 = (__int64 *)(argv + 1);
v9 = 2;
do
{
v10 = &unk_A5;
if ( argc > v9 )
v10 = (void *)v8[1];
v11 = *v8;
v9 += 2;
v8 += 2;
v12 = (const char *)basename(v11, 1LL, 0LL, (__int64)v10);
Fmt_print("%s\n", v12);
}
while ( v9 != ((argc - 2) & 0xFFFFFFFE) + 4 );
}
}
else if ( argc > 1 )
{
v4 = argv + 1;
do
{
v5 = *v4;
v4 += 2;
v6 = (const char *)dirname((__int64)v5, 1LL, 0LL);
Fmt_print("%s\n", v6);
}
while ( v4 != &argv[2 * ((unsigned int)(argc - 2) >> 1) + 3] );
}
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char **v4; // rbx
const char *v5; // rdi
const char *v6; // rax
__int64 *v8; // rbx
int v9; // ebp
void *v10; // rcx
__int64 v11; // rdi
const char *v12; // rax

if ( (int)Str_find(*argv, 1LL, 0LL, "dirname") <= 0 )
{
if ( argc > 1 )
{
v8 = (__int64 *)(argv + 1);
v9 = 2;
do
{
v10 = &unk_A5;
if ( argc > v9 )
v10 = (void *)v8[1];
v11 = *v8;
v9 += 2;
v8 += 2;
v12 = (const char *)func1(v11, 1LL, 0LL, (__int64)v10);
Fmt_print("%s\n", v12);
}
while ( v9 != ((argc - 2) & 0xFFFFFFFE) + 4 );
}
}
else if ( argc > 1 )
{
v4 = argv + 1;
do
{
v5 = *v4;
v4 += 2;
v6 = (const char *)func0((__int64)v5, 1LL, 0LL);
Fmt_print("%s\n", v6);
}
while ( v4 != &argv[2 * ((unsigned int)(argc - 2) >> 1) + 3] );
}
return 0;
}

original_code:
int main(int argc, char *argv[]) {
 int i;
 if (Str_find(argv[0], 1, 0, "dirname") > 0)
  for (i = 1; i < argc; i += 2)
   Fmt_print("%s\n", dirname(argv[i], 1, 0));
 else
  for (i = 1; i < argc; i += 2)
   Fmt_print("%s\n", basename(argv[i], 1, 0, i+1 < argc ? argv[i+1] : ""));
 return 0;
}

variable_types: argc int

variable_types:
argv
char *[]


pop

decompiled_code:
__int64 pop()
{
if ( !(unsigned int)Stack_empty(qword_48) )
return Stack_pop(qword_48);
Fmt_fprint(stderr, "?stack underflow\n");
return AP_new(0LL);
}

canonical_decompiled_code:
__int64 func0()
{
if ( !(unsigned int)Stack_empty(qword_48) )
return Stack_pop(qword_48);
Fmt_fprint(stderr, "?stack underflow\n");
return AP_new(0LL);
}

original_code:
MP_T pop(void) {
 if (Seq_length(sp) > 0)
  return Seq_remhi(sp);
 else {
  Fmt_fprint(stderr, "?stack underflow\n");
  return MP_new(0);
 }
}

canonical_original_code:
unsigned char *pop() {
 if (Seq_length(sp) > 0)
  return Seq_remhi(sp);
 else {
  Fmt_fprint(stderr, "?stack underflow\n");
  return MP_new(0);
 }
}

return_type: unsigned char *


first

decompiled_code:
__int64 __fastcall first(int a1)
{
return (*_ctype_b_loc())[a1] & 0x400;
}

canonical_decompiled_code:
__int64 __fastcall func1(int a1)
{
return (*_ctype_b_loc())[a1] & 0x400;
}

original_code:
int first(int c) {
 return ((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISalpha);
}

canonical_original_code:
int first(int c) {
 return ((*__ctype_b_loc ())[(int) ((c))] & (unsigned short) _ISalpha);
}

variable_types: c int

return_type: int


rest

original_code:
int rest(int c) {
 return ((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISalpha) || c == '_';
}

canonical_original_code:
int rest(int c) {
 return ((*__ctype_b_loc ())[(int) ((c))] & (unsigned short) _ISalpha) || c == '_';
}


compare

decompiled_code:
int __fastcall compare(const void *a1, const void *a2)
{
return strcmp(*(const char **)a1, *(const char **)a2);
}

canonical_decompiled_code:
int __fastcall func3(const void *a1, const void *a2)
{
return strcmp(*(const char **)a1, *(const char **)a2);
}

original_code:
int compare(const void *x, const void *y) {
 return strcmp(*(char **)x, *(char **)y);
}

canonical_original_code:
int compare(void *x, void *y) {
 return strcmp(*(char **)x, *(char **)y);
}

variable_types:
x
void *

variable_types:
y
void *


texthash

original_code:
unsigned texthash(const void *x) {
 int i;
 unsigned h = 0;
 const Text_T *t = x;
 for (i = 0; i < t->len; i++)
  h = (h<<1) + t->str[i];
 return h;
}

canonical_original_code:
unsigned int texthash(void *x) {
 int i;
 unsigned int h = 0;
 struct Text_T *t = x;
 for (i = 0; i < t->len; i++)
  h = (h<<1) + t->str[i];
 return h;
}

variable_types: i int

variable_types:
h
unsigned int

variable_types:
t
struct Text_T { int len; char *str; } *

return_type: unsigned int


textcmp

decompiled_code:
__int64 __fastcall textcmp(unsigned int *a1, unsigned int *a2)
{
return Text_cmp(*a1, *((_QWORD *)a1 + 1), *a2, *((_QWORD *)a2 + 1));
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned int *a1, unsigned int *a2)
{
return Text_cmp(*a1, *((_QWORD *)a1 + 1), *a2, *((_QWORD *)a2 + 1));
}

original_code:
int textcmp(const void *x, const void *y) {
 return Text_cmp(*(Text_T *)x, *(Text_T *)y);
}

canonical_original_code:
int textcmp(void *x, void *y) {
 return Text_cmp(*(struct Text_T *)x, *(struct Text_T *)y);
}


repo: niedbalski/libbacktesting

decompiled_code:
__int64 __fastcall add_condition(int a1, __m128i a2)
{
int v2; // er14
_QWORD *v4; // rbx
void *v5; // rdi
__int64 v6; // rdx
__int64 v7; // rax
_DWORD *v8; // rdx
_DWORD *v10; // rax

v2 = _mm_cvtsi128_si32(a2);
v4 = context;
v5 = (void *)*((_QWORD *)context + 2);
if ( !v5 )
{
v10 = malloc(8uLL);
v4[2] = v10;
if ( v10 )
{
*v10 = a1;
v10[1] = v2;
v7 = v4[4];
goto LABEL_4;
}
return 0xFFFFFFFFLL;
}
v4[2] = realloc(v5, 8LL * *((_QWORD *)context + 4) + 8);
v4 = context;
v6 = *((_QWORD *)context + 2);
if ( !v6 )
return 0xFFFFFFFFLL;
v7 = *((_QWORD *)context + 4);
v8 = (_DWORD *)(v6 + 8 * v7);
*v8 = a1;
v8[1] = v2;
LABEL_4:
v4[4] = v7 + 1;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(int a1, __m128i a2)
{
int v2; // er14
_QWORD *v4; // rbx
void *v5; // rdi
__int64 v6; // rdx
__int64 v7; // rax
_DWORD *v8; // rdx
_DWORD *v10; // rax

v2 = _mm_cvtsi128_si32(a2);
v4 = context;
v5 = (void *)*((_QWORD *)context + 2);
if ( !v5 )
{
v10 = malloc(8uLL);
v4[2] = v10;
if ( v10 )
{
*v10 = a1;
v10[1] = v2;
v7 = v4[4];
goto LABEL_4;
}
return 0xFFFFFFFFLL;
}
v4[2] = realloc(v5, 8LL * *((_QWORD *)context + 4) + 8);
v4 = context;
v6 = *((_QWORD *)context + 2);
if ( !v6 )
return 0xFFFFFFFFLL;
v7 = *((_QWORD *)context + 4);
v8 = (_DWORD *)(v6 + 8 * v7);
*v8 = a1;
v8[1] = v2;
LABEL_4:
v4[4] = v7 + 1;
return 0LL;
}

original_code:
static inline int add_condition(enum PRICE_CONDITION type, float value)
{
    if(context->conditions == ((void *)0)) {
        context->conditions = malloc(sizeof(price_condition));
        if(context->conditions == ((void *)0))
            return -1;
        context->conditions[0].type = type;
        context->conditions[0].value = value;
    } else {
        context->conditions = realloc(context->conditions, sizeof(price_condition) * (context->current_conditions + 1));
        if(context->conditions == ((void *)0))
            return -1;
        context->conditions[context->current_conditions].type = type;
        context->conditions[context->current_conditions].value = value;
    }
    context->current_conditions += 1;
    return 0;
}

variable_types: enum PRICE_CONDITION { LOWER_THAN=0, LOWER_AND_EQUALS_TO=1, GREATER_THAN=2, GREATER_AND_EQUALS_TO=3, EQUALS_TO=4 }

variable_types: value float


decompiled_code:
__int64 __fastcall add_lower_than_condition(__m128i a1)
{
__int64 v1; // rdx
__int64 result; // rax

if ( *((_QWORD *)context + 4) == 1LL
&& (v1 = *((_QWORD *)context + 2), (unsigned int)(*(_DWORD *)v1 - 2) <= 1)
&& *(float *)(v1 + 4) > *(float *)a1.m128i_i32 )
{
result = 0xFFFFFFFFLL;
}
else
{
result = add_condition(0, a1);
}
return result;
}

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

if ( *((_QWORD *)context + 4) == 1LL
&& (v1 = *((_QWORD *)context + 2), (unsigned int)(*(_DWORD *)v1 - 2) <= 1)
&& *(float *)(v1 + 4) > *(float *)a1.m128i_i32 )
{
result = 0xFFFFFFFFLL;
}
else
{
result = func0(0, a1);
}
return result;
}

original_code:
static inline int add_lower_than_condition(float value)
{
    struct price_condition previous_condition;
    if ( context->current_conditions == 1 ) {
        previous_condition = context->conditions[0];
        if ( previous_condition.type == GREATER_THAN || previous_condition.type == GREATER_AND_EQUALS_TO) {
            if ( value < previous_condition.value )
                return -1;
        }
    }
    return add_condition(LOWER_THAN, value);
}

variable_types: struct price_condition { enum PRICE_CONDITION { LOWER_THAN=0, LOWER_AND_EQUALS_TO=1, GREATER_THAN=2, GREATER_AND_EQUALS_TO=3, EQUALS_TO=4 } type; float value; }

user_defined_types: struct price_condition { enum PRICE_CONDITION type; float value; }


decompiled_code:
__int64 __fastcall add_greater_than_condition(__m128i a1)
{
__int64 v1; // rax
__int64 result; // rax

if ( *((_QWORD *)context + 4)
&& (v1 = *((_QWORD *)context + 2), *(_DWORD *)v1 <= 1u)
&& *(float *)a1.m128i_i32 > *(float *)(v1 + 4) )
{
result = 0xFFFFFFFFLL;
}
else
{
result = add_condition(2, a1);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__m128i a1)
{
__int64 v1; // rax
__int64 result; // rax

if ( *((_QWORD *)context + 4)
&& (v1 = *((_QWORD *)context + 2), *(_DWORD *)v1 <= 1u)
&& *(float *)a1.m128i_i32 > *(float *)(v1 + 4) )
{
result = 0xFFFFFFFFLL;
}
else
{
result = func0(2, a1);
}
return result;
}

original_code:
static inline int add_greater_than_condition(float value)
{
    struct price_condition previous_condition;
    if( context->current_conditions ) {
        previous_condition = context->conditions[0];
        if ( previous_condition.type == LOWER_THAN || previous_condition.type == LOWER_AND_EQUALS_TO) {
            if ( value > previous_condition.value ) {
                return -1;
            }
        }
    }
    return add_condition(GREATER_THAN, value);
}

user_defined_types: enum PRICE_CONDITION { LOWER_THAN=0, LOWER_AND_EQUALS_TO=1, GREATER_THAN=2, GREATER_AND_EQUALS_TO=3, EQUALS_TO=4 }


decompiled_code:
__int64 __fastcall add_greater_and_equals_condition(__m128i a1)
{
__int64 v1; // rax
__int64 result; // rax

if ( *((_QWORD *)context + 4) == 1LL
&& (v1 = *((_QWORD *)context + 2), *(_DWORD *)v1 <= 1u)
&& *(float *)a1.m128i_i32 >= *(float *)(v1 + 4) )
{
result = 0xFFFFFFFFLL;
}
else
{
result = add_condition(3, a1);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__m128i a1)
{
__int64 v1; // rax
__int64 result; // rax

if ( *((_QWORD *)context + 4) == 1LL
&& (v1 = *((_QWORD *)context + 2), *(_DWORD *)v1 <= 1u)
&& *(float *)a1.m128i_i32 >= *(float *)(v1 + 4) )
{
result = 0xFFFFFFFFLL;
}
else
{
result = func0(3, a1);
}
return result;
}

original_code:
static inline int add_greater_and_equals_condition(float value)
{
    struct price_condition previous_condition;
    if( context->current_conditions == 1) {
        previous_condition = context->conditions[0];
        if ( previous_condition.type == LOWER_THAN || previous_condition.type == LOWER_AND_EQUALS_TO){
            if ( value >= previous_condition.value )
                return -1;
        }
    }
    return add_condition(GREATER_AND_EQUALS_TO, value);
}


decompiled_code:
__int64 __fastcall add_equals_condition(__m128i a1)
{
return add_condition(4, a1);
}

canonical_decompiled_code:
__int64 __fastcall func4(__m128i a1)
{
return func0(4, a1);
}

original_code:
static inline int add_equals_condition(float value) {
    return add_condition(EQUALS_TO, value);
}


decompiled_code:
void **backtest_file_get_ctx()
{
return &context;
}

canonical_decompiled_code:
void **func6()
{
return &context;
}

original_code:
file_context *backtest_file_get_ctx(void) {
    return (file_context *)&context;
}

canonical_original_code:
struct file_context *backtest_file_get_ctx() {
    return (struct file_context *)&context;
}

return_type: struct file_context { char *filename; enum FILE_TYPE { BACKTEST_FILE_CSV=0, BACKTEST_FILE_TXT=1 } file_type; struct price_condition { enum PRICE_CONDITION { LOWER_THAN=0, LOWER_AND_EQUALS_TO=1, GREATER_THAN=2, GREATER_AND_EQUALS_TO=3, EQUALS_TO=4 } type; float value; } *conditions; char *mapped; unsigned long current_conditions; unsigned long mapped_size; } *

user_defined_types: struct file_context { char *filename; enum FILE_TYPE file_type; struct price_condition *conditions; char *mapped; unsigned long current_conditions; unsigned long mapped_size; }


decompiled_code:
__int64 __fastcall backtest_evaluate_conditions(float a1)
{
__int64 v2; // rdi
__int64 v3; // rcx
__int64 v4; // rax
float v5; // xmm0_4
__int64 result; // rax

v2 = *((_QWORD *)context + 4);
if ( !v2 )
return 0xFFFFFFFFLL;
v3 = *((_QWORD *)context + 2);
v4 = 0LL;
while ( 2 )
{
v5 = *(float *)(v3 + 8 * v4 + 4);
switch ( *(_DWORD *)(v3 + 8 * v4) )
{
case 0:
if ( v5 <= a1 )
return 0xFFFFFFFFLL;
goto LABEL_5;
case 1:
if ( v5 < a1 )
return 0xFFFFFFFFLL;
goto LABEL_5;
case 2:
if ( a1 <= v5 )
return 0xFFFFFFFFLL;
goto LABEL_5;
case 3:
if ( a1 >= v5 )
goto LABEL_5;
return 0xFFFFFFFFLL;
case 4:
if ( v5 != a1 )
return 0xFFFFFFFFLL;
LABEL_5:
if ( v2 != ++v4 )
continue;
result = 0LL;
break;
default:
JUMPOUT(0x3F8LL);
}
return result;
}
}

canonical_decompiled_code:
__int64 __fastcall func7(float a1)
{
__int64 v2; // rdi
__int64 v3; // rcx
__int64 v4; // rax
float v5; // xmm0_4
__int64 result; // rax

v2 = *((_QWORD *)context + 4);
if ( !v2 )
return 0xFFFFFFFFLL;
v3 = *((_QWORD *)context + 2);
v4 = 0LL;
while ( 2 )
{
v5 = *(float *)(v3 + 8 * v4 + 4);
switch ( *(_DWORD *)(v3 + 8 * v4) )
{
case 0:
if ( v5 <= a1 )
return 0xFFFFFFFFLL;
goto LABEL_5;
case 1:
if ( v5 < a1 )
return 0xFFFFFFFFLL;
goto LABEL_5;
case 2:
if ( a1 <= v5 )
return 0xFFFFFFFFLL;
goto LABEL_5;
case 3:
if ( a1 >= v5 )
goto LABEL_5;
return 0xFFFFFFFFLL;
case 4:
if ( v5 != a1 )
return 0xFFFFFFFFLL;
LABEL_5:
if ( v2 != ++v4 )
continue;
result = 0LL;
break;
default:
JUMPOUT(0x3F8LL);
}
return result;
}
}

original_code:
int backtest_evaluate_conditions(float value)
{
    price_condition condition;
    int i;
    if(! context->current_conditions ) {
        return -1;
    }
    for(i = 0; i <= context->current_conditions - 1; i++) {
        condition = context->conditions[i];
        switch(condition.type) {
        case LOWER_THAN:
            if(!(value < condition.value)) {
                return -1;
            }
            break;
        case LOWER_AND_EQUALS_TO:
            if(!(value <= condition.value)) {
                return -1;
            }
            break;
        case GREATER_THAN:
            if(!(value > condition.value)) {
                return -1;
            }
            break;
        case GREATER_AND_EQUALS_TO:
            if(!(value >= condition.value)) {
                return -1;
            }
            break;
        case EQUALS_TO:
            if(!(value == condition.value)) {
                return -1;
            }
            break;
        default:
            return -1;
        }
    }
    return 0;
}

canonical_original_code:
int backtest_evaluate_conditions(float value)
{
    struct price_condition condition;
    int i;
    if(! context->current_conditions ) {
        return -1;
    }
    for(i = 0; i <= context->current_conditions - 1; i++) {
        condition = context->conditions[i];
        switch(condition.type) {
        case LOWER_THAN:
            if(!(value < condition.value)) {
                return -1;
            }
            break;
        case LOWER_AND_EQUALS_TO:
            if(!(value <= condition.value)) {
                return -1;
            }
            break;
        case GREATER_THAN:
            if(!(value > condition.value)) {
                return -1;
            }
            break;
        case GREATER_AND_EQUALS_TO:
            if(!(value >= condition.value)) {
                return -1;
            }
            break;
        case EQUALS_TO:
            if(!(value == condition.value)) {
                return -1;
            }
            break;
        default:
            return -1;
        }
    }
    return 0;
}


decompiled_code:
__int64 __fastcall backtest_add_price_condition(int a1, __m128i a2)
{
__int64 result; // rax

if ( *((_QWORD *)context + 4) <= 1uLL )
{
switch ( a1 )
{
case 0:
result = add_lower_than_condition(a2);
break;
case 1:
add_lower_and_equals_condition_isra_0(a2);
result = add_greater_than_condition((__m128i)a2.m128i_u32[0]);
break;
case 2:
result = add_greater_than_condition(a2);
break;
case 3:
result = add_greater_and_equals_condition(a2);
break;
case 4:
goto LABEL_3;
default:
goto LABEL_10;
}
}
else if ( a1 == 4 )
{
LABEL_3:
result = add_equals_condition(a2);
}
else
{
LABEL_10:
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(int a1, __m128i a2)
{
__int64 result; // rax

if ( *((_QWORD *)context + 4) <= 1uLL )
{
switch ( a1 )
{
case 0:
result = func1(a2);
break;
case 1:
func5(a2);
result = func2((__m128i)a2.m128i_u32[0]);
break;
case 2:
result = func2(a2);
break;
case 3:
result = func3(a2);
break;
case 4:
goto LABEL_3;
default:
goto LABEL_10;
}
}
else if ( a1 == 4 )
{
LABEL_3:
result = func4(a2);
}
else
{
LABEL_10:
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int backtest_add_price_condition(enum PRICE_CONDITION price_condition, float value)
{
    int ret;
    if ( context->current_conditions >= 2 && price_condition != EQUALS_TO)
        return -1;
    switch(price_condition) {
    case LOWER_THAN:
        ret = add_lower_than_condition(value);
        break;
    case LOWER_AND_EQUALS_TO:
        ret = add_lower_and_equals_condition(value);
    case GREATER_THAN:
        ret = add_greater_than_condition(value);
        break;
    case GREATER_AND_EQUALS_TO:
        ret = add_greater_and_equals_condition(value);
        break;
    case EQUALS_TO:
        ret = add_equals_condition(value);
        break;
    default:
        ret = -1;
        break;
    }
    return ret;
}

variable_types: ret int


decompiled_code:
__int64 __fastcall backtest_file_init(char *file, int a2)
{
unsigned int v2; // er12
int v3; // ebp
_QWORD *v4; // rbx
_QWORD *v5; // rax
__off_t v6; // rdx
struct stat v8; // [rsp+0h] [rbp-B8h] BYREF

if ( stat(file, &v8) )
return (unsigned int)-1;
if ( !v8.st_size )
return (unsigned int)-1;
v2 = 0;
v3 = open(file, 0);
if ( v3 == -1 )
return (unsigned int)-1;
context = malloc(0x30uLL);
if ( (v4 = context) == 0LL )
return (unsigned int)-1;
v4[3] = mmap(0LL, v8.st_size, 1, 2, v3, 0LL);
v5 = context;
if ( !*((_QWORD *)context + 3) )
return (unsigned int)-1;
v6 = v8.st_size;
*((_DWORD *)context + 2) = a2;
v5[2] = 0LL;
v5[5] = v6;
v5[4] = 0LL;
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func9(char *file, int a2)
{
unsigned int v2; // er12
int v3; // ebp
_QWORD *v4; // rbx
_QWORD *v5; // rax
__off_t v6; // rdx
struct stat v8; // [rsp+0h] [rbp-B8h] BYREF

if ( stat(file, &v8) )
return (unsigned int)-1;
if ( !v8.st_size )
return (unsigned int)-1;
v2 = 0;
v3 = open(file, 0);
if ( v3 == -1 )
return (unsigned int)-1;
context = malloc(0x30uLL);
if ( (v4 = context) == 0LL )
return (unsigned int)-1;
v4[3] = mmap(0LL, v8.st_size, 1, 2, v3, 0LL);
v5 = context;
if ( !*((_QWORD *)context + 3) )
return (unsigned int)-1;
v6 = v8.st_size;
*((_DWORD *)context + 2) = a2;
v5[2] = 0LL;
v5[5] = v6;
v5[4] = 0LL;
return v2;
}

original_code:
int backtest_file_init(const char *filename, enum FILE_TYPE file_type)
{
    struct stat st;
    int r, fd;
    if( (r = stat(filename, &st)) != 0) {
        ;
        return -1;
    }
    if ( st.st_size == 0 ) {
        ;
        return -1;
    }
    fd = open(filename, 00);
    if ( fd == -1 ) {
        ;
        return -1;
    }
    context = malloc(sizeof(file_context));
    if(context == ((void *)0))
        return -1;
    context->mapped = (char *)mmap(((void *)0), st.st_size, 0x1, 0x02, fd, 0);
    if(context->mapped == ((void *)0)) {
        ;
        return -1;
    }
    context->mapped_size = st.st_size;
    context->file_type = file_type;
    context->conditions = ((void *)0);
    context->current_conditions = 0;
    return 0;
}

canonical_original_code:
int backtest_file_init(char *filename, enum FILE_TYPE file_type)
{
    struct stat st;
    int r; int fd;
    if( (r = stat(filename, &st)) != 0) {
        ;
        return -1;
    }
    if ( st.st_size == 0 ) {
        ;
        return -1;
    }
    fd = open(filename, 00);
    if ( fd == -1 ) {
        ;
        return -1;
    }
    context = malloc(sizeof(file_context));
    if(context == ((void *)0))
        return -1;
    context->mapped = (char *)mmap(((void *)0), st.st_size, 0x1, 0x02, fd, 0);
    if(context->mapped == ((void *)0)) {
        ;
        return -1;
    }
    context->mapped_size = st.st_size;
    context->file_type = file_type;
    context->conditions = ((void *)0);
    context->current_conditions = 0;
    return 0;
}

variable_types:
filename
char *

variable_types: enum FILE_TYPE { BACKTEST_FILE_CSV=0, BACKTEST_FILE_TXT=1 }

variable_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec { long tv_sec; long tv_nsec; } st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }

variable_types: r int

variable_types: fd int

user_defined_types: struct stat { unsigned long st_dev; unsigned long st_ino; unsigned long st_nlink; unsigned int st_mode; unsigned int st_uid; unsigned int st_gid; int __pad0; unsigned long st_rdev; long st_size; long st_blksize; long st_blocks; struct timespec st_atim; struct timespec st_mtim; struct timespec st_ctim; long __glibc_reserved[3]; }


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

v0 = (void **)context;
if ( *((_QWORD *)context + 3) )
{
munmap(*((void **)context + 3), *((_QWORD *)context + 5));
v0 = (void **)context;
}
if ( v0[2] )
{
free(v0[2]);
v0 = (void **)context;
}
free(v0);
}

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

v0 = (void **)context;
if ( *((_QWORD *)context + 3) )
{
munmap(*((void **)context + 3), *((_QWORD *)context + 5));
v0 = (void **)context;
}
if ( v0[2] )
{
free(v0[2]);
v0 = (void **)context;
}
free(v0);
}

original_code:
void backtest_file_destroy(void) {
    if(context->mapped)
        munmap(context->mapped, context->mapped_size);
    if(context->conditions != ((void *)0))
        free(context->conditions);
    free(context);
}

canonical_original_code:
void backtest_file_destroy() {
    if(context->mapped)
        munmap(context->mapped, context->mapped_size);
    if(context->conditions != ((void *)0))
        free(context->conditions);
    free(context);
}

return_type: void


decompiled_code:
__int64 __fastcall list_find(_QWORD *a1, __int64 a2, __int64 (__fastcall *a3)(_QWORD, __int64))
{
_QWORD *v4; // rbx
__int64 result; // rax

if ( !a1 )
return 0xFFFFFFFFLL;
v4 = a1;
for ( result = a3(*a1, a2); (_DWORD)result; result = a3(*v4, a2) )
{
v4 = (_QWORD *)v4[2];
if ( !v4 )
return 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(_QWORD *a1, __int64 a2, __int64 (__fastcall *a3)(_QWORD, __int64))
{
_QWORD *v4; // rbx
__int64 result; // rax

if ( !a1 )
return 0xFFFFFFFFLL;
v4 = a1;
for ( result = a3(*a1, a2); (_DWORD)result; result = a3(*v4, a2) )
{
v4 = (_QWORD *)v4[2];
if ( !v4 )
return 0xFFFFFFFFLL;
}
return result;
}

original_code:
int list_find(list *head, const char *key, compare_function compare)
{
    list *current;
    current = head;
    while(current != ((void *)0)) {
        if((int)compare(current->key, key) == 0)
            return 0;
        current = current->next;
    }
    return -1;
}

canonical_original_code:
int list_find(struct list *head, char *key, int (*compare)(char *primary, char *secondary))
{
    struct list *current;
    current = head;
    while(current != ((void *)0)) {
        if((int)compare(current->key, key) == 0)
            return 0;
        current = current->next;
    }
    return -1;
}

variable_types: struct list { char *key; void *value; struct list *next; } *

variable_types:
key
char *

variable_types:
compare
int (*)(char *primary, char *secondary)


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // r13
__int64 v4; // rdx
__int64 v5; // r12
__int64 v6; // rdx
__int64 v7; // rbp
__int64 i; // rax
__int64 j; // rax
__int64 v10; // rdx
__int64 v11; // rbp
__int64 v12; // rdx
__int64 v13; // r12
__int64 k; // rax
__int64 l; // rax

v3 = niel_malloc(400LL, argv, envp);
v5 = niel_malloc(400LL, argv, v4);
v7 = niel_malloc(400LL, argv, v6);
for ( i = 0LL; i != 100; ++i )
{
*(_DWORD *)(v3 + 4 * i) = i;
*(_DWORD *)(v5 + 4 * i) = i;
*(_DWORD *)(v7 + 4 * i) = i;
}
for ( j = 0LL; j != 100; ++j )
{
if ( *(_DWORD *)(v3 + 4 * j) != (_DWORD)j )
__assert_fail("arr1[i] == i", "tests/test_malloc.c", 0x15u, "main");
if ( *(_DWORD *)(v5 + 4 * j) != (_DWORD)j )
__assert_fail("arr2[i] == i", "tests/test_malloc.c", 0x16u, "main");
if ( *(_DWORD *)(v7 + 4 * j) != (_DWORD)j )
__assert_fail("arr3[i] == i", "tests/test_malloc.c", 0x17u, "main");
}
niel_free(v3);
niel_free(v5);
niel_free(v7);
v11 = niel_malloc(600LL, argv, v10);
v13 = niel_malloc(600LL, argv, v12);
for ( k = 0LL; k != 150; ++k )
{
*(_DWORD *)(v11 + 4 * k) = k;
*(_DWORD *)(v13 + 4 * k) = k;
}
for ( l = 0LL; l != 150; ++l )
{
if ( *(_DWORD *)(v11 + 4 * l) != (_DWORD)l )
__assert_fail("arr1[i] == i", "tests/test_malloc.c", 0x29u, "main");
if ( *(_DWORD *)(v13 + 4 * l) != (_DWORD)l )
__assert_fail("arr2[i] == i", "tests/test_malloc.c", 0x2Au, "main");
}
niel_free(v11);
niel_free(v13);
return 0;
}

original_code:
int main(int argc, char *argv[])
{
    int *arr1, *arr2, *arr3;
    arr1 = (int *)niel_malloc(sizeof(int) * 100);
    arr2 = (int *)niel_malloc(sizeof(int) * 100);
    arr3 = (int *)niel_malloc(sizeof(int) * 100);
    for (int i = 0; i < 100; i++)
    {
        arr1[i] = i;
        arr2[i] = i;
        arr3[i] = i;
    }
    for (int i = 0; i < 100; i++)
    {
        ((void) sizeof ((arr1[i] == i) ? 1 : 0), __extension__ ({ if (arr1[i] == i) ; else __assert_fail ("arr1[i] == i", "tests/test_malloc.c", 21, __extension__ __PRETTY_FUNCTION__); }));
        ((void) sizeof ((arr2[i] == i) ? 1 : 0), __extension__ ({ if (arr2[i] == i) ; else __assert_fail ("arr2[i] == i", "tests/test_malloc.c", 22, __extension__ __PRETTY_FUNCTION__); }));
        ((void) sizeof ((arr3[i] == i) ? 1 : 0), __extension__ ({ if (arr3[i] == i) ; else __assert_fail ("arr3[i] == i", "tests/test_malloc.c", 23, __extension__ __PRETTY_FUNCTION__); }));
    }
    niel_free(arr1);
    niel_free(arr2);
    niel_free(arr3);
    arr1 = (int *)niel_malloc(sizeof(int) * 150);
    arr2 = (int *)niel_malloc(sizeof(int) * 150);
    for (int i = 0; i < 150; i++)
    {
        arr1[i] = i;
        arr2[i] = i;
    }
    for (int i = 0; i < 150; i++)
    {
        ((void) sizeof ((arr1[i] == i) ? 1 : 0), __extension__ ({ if (arr1[i] == i) ; else __assert_fail ("arr1[i] == i", "tests/test_malloc.c", 41, __extension__ __PRETTY_FUNCTION__); }));
        ((void) sizeof ((arr2[i] == i) ? 1 : 0), __extension__ ({ if (arr2[i] == i) ; else __assert_fail ("arr2[i] == i", "tests/test_malloc.c", 42, __extension__ __PRETTY_FUNCTION__); }));
    }
    niel_free(arr1);
    niel_free(arr2);
}

canonical_original_code:
int main(int argc, char *argv[])
{
    int *arr1; int *arr2; int *arr3;
    arr1 = (int *)niel_malloc(sizeof(int) * 100);
    arr2 = (int *)niel_malloc(sizeof(int) * 100);
    arr3 = (int *)niel_malloc(sizeof(int) * 100);
    for (int i = 0; i < 100; i++)
    {
        arr1[i] = i;
        arr2[i] = i;
        arr3[i] = i;
    }
    for (int i = 0; i < 100; i++)
    {
        ((void) sizeof ((arr1[i] == i) ? 1 : 0), __extension__ ({ if (arr1[i] == i) ; else __assert_fail ("arr1[i] == i", "tests/test_malloc.c", 21, __extension__ __PRETTY_FUNCTION__); }));
        ((void) sizeof ((arr2[i] == i) ? 1 : 0), __extension__ ({ if (arr2[i] == i) ; else __assert_fail ("arr2[i] == i", "tests/test_malloc.c", 22, __extension__ __PRETTY_FUNCTION__); }));
        ((void) sizeof ((arr3[i] == i) ? 1 : 0), __extension__ ({ if (arr3[i] == i) ; else __assert_fail ("arr3[i] == i", "tests/test_malloc.c", 23, __extension__ __PRETTY_FUNCTION__); }));
    }
    niel_free(arr1);
    niel_free(arr2);
    niel_free(arr3);
    arr1 = (int *)niel_malloc(sizeof(int) * 150);
    arr2 = (int *)niel_malloc(sizeof(int) * 150);
    for (int i = 0; i < 150; i++)
    {
        arr1[i] = i;
        arr2[i] = i;
    }
    for (int i = 0; i < 150; i++)
    {
        ((void) sizeof ((arr1[i] == i) ? 1 : 0), __extension__ ({ if (arr1[i] == i) ; else __assert_fail ("arr1[i] == i", "tests/test_malloc.c", 41, __extension__ __PRETTY_FUNCTION__); }));
        ((void) sizeof ((arr2[i] == i) ? 1 : 0), __extension__ ({ if (arr2[i] == i) ; else __assert_fail ("arr2[i] == i", "tests/test_malloc.c", 42, __extension__ __PRETTY_FUNCTION__); }));
    }
    niel_free(arr1);
    niel_free(arr2);
}

variable_types: argc int

variable_types:
argv
char *[]


original_code:
mem_blk_header *allocate_new_blk(mem_blk_header *last_blk, size_t size)
{
    size_t size_to_allocate = mem_blk_header_size + size;
    mem_blk_header *new_blk = sbrk(size_to_allocate);
    if (new_blk == (mem_blk_header *)-1)
        return ((void *)0);
    new_blk->mem_blk = (void *)((char *)(new_blk) + mem_blk_header_size);
    new_blk->blk_size = size;
    new_blk->next = ((void *)0);
    new_blk->prev = last_blk;
    new_blk->assigned_flag = 1;
    if (last_blk != ((void *)0))
    {
        last_blk->next = new_blk;
    }
    return new_blk->mem_blk;
}

canonical_original_code:
struct mem_blk_header *allocate_new_blk(struct mem_blk_header *last_blk, unsigned long size)
{
    unsigned long size_to_allocate = mem_blk_header_size + size;
    struct mem_blk_header *new_blk = sbrk(size_to_allocate);
    if (new_blk == (struct mem_blk_header *)-1)
        return ((void *)0);
    new_blk->mem_blk = (void *)((char *)(new_blk) + mem_blk_header_size);
    new_blk->blk_size = size;
    new_blk->next = ((void *)0);
    new_blk->prev = last_blk;
    new_blk->assigned_flag = 1;
    if (last_blk != ((void *)0))
    {
        last_blk->next = new_blk;
    }
    return new_blk->mem_blk;
}

variable_types:
size
unsigned long

variable_types: struct mem_blk_header { struct mem_blk_header *next; struct mem_blk_header *prev; void *mem_blk; unsigned long blk_size; int assigned_flag; } *


original_code:
mem_blk_header *assign_blk(mem_blk_header *blk, size_t size)
{
    size_t size_diff = blk->blk_size - size - mem_blk_header_size;
    if (size_diff > mem_blk_header_size)
    {
        blk->blk_size = size;
        blk->assigned_flag = 1;
        mem_blk_header *new_blk = (mem_blk_header *)((char *)blk + mem_blk_header_size + size);
        new_blk->mem_blk = (void *)((char *)(new_blk) + mem_blk_header_size);
        new_blk->blk_size = size_diff;
        new_blk->assigned_flag = 0;
        new_blk->next = blk->next;
        new_blk->prev = blk;
        blk->next = new_blk;
        return blk->mem_blk;
    }
    else
    {
        blk->assigned_flag = 1;
        return blk->mem_blk;
    }
}

canonical_original_code:
struct mem_blk_header *assign_blk(struct mem_blk_header *blk, unsigned long size)
{
    unsigned long size_diff = blk->blk_size - size - mem_blk_header_size;
    if (size_diff > mem_blk_header_size)
    {
        blk->blk_size = size;
        blk->assigned_flag = 1;
        struct mem_blk_header *new_blk = (mem_blk_header *)((char *)blk + mem_blk_header_size + size);
        new_blk->mem_blk = (void *)((char *)(new_blk) + mem_blk_header_size);
        new_blk->blk_size = size_diff;
        new_blk->assigned_flag = 0;
        new_blk->next = blk->next;
        new_blk->prev = blk;
        blk->next = new_blk;
        return blk->mem_blk;
    }
    else
    {
        blk->assigned_flag = 1;
        return blk->mem_blk;
    }
}

variable_types:
blk
struct mem_blk_header *

return_type: struct mem_blk_header { struct mem_blk_header *next; struct mem_blk_header *prev; void *mem_blk; unsigned long blk_size; int assigned_flag; } *


decompiled_code:
char *__fastcall niel_malloc(__int64 a1)
{
__int64 v1; // rsi
intptr_t v2; // rdi
unsigned __int64 v3; // rsi
char *result; // rax

v1 = a1 - 1;
v2 = heap_start;
v3 = (v1 & 0xFFFFFFFFFFFFFFF8LL) + 8;
if ( heap_start )
{
while ( *(_DWORD *)(v2 + 32) || *(_QWORD *)(v2 + 24) < v3 )
{
if ( !*(_QWORD *)v2 )
return allocate_new_blk((_QWORD *)v2, v3);
v2 = *(_QWORD *)v2;
}
result = (char *)assign_blk((__int64 *)v2, v3);
}
else
{
heap_start = (intptr_t)sbrk(heap_start);
result = allocate_new_blk(0LL, v3);
}
return result;
}

canonical_decompiled_code:
char *__fastcall func9(__int64 a1)
{
__int64 v1; // rsi
intptr_t v2; // rdi
unsigned __int64 v3; // rsi
char *result; // rax

v1 = a1 - 1;
v2 = heap_start;
v3 = (v1 & 0xFFFFFFFFFFFFFFF8LL) + 8;
if ( heap_start )
{
while ( *(_DWORD *)(v2 + 32) || *(_QWORD *)(v2 + 24) < v3 )
{
if ( !*(_QWORD *)v2 )
return func7((_QWORD *)v2, v3);
v2 = *(_QWORD *)v2;
}
result = (char *)func8((__int64 *)v2, v3);
}
else
{
heap_start = (intptr_t)sbrk(heap_start);
result = func7(0LL, v3);
}
return result;
}

original_code:
void *niel_malloc(size_t size)
{
    size_t aligned_size = (((((size) - 1)>>3)<<3)+8);
    if (heap_start == ((void *)0))
    {
        heap_start = sbrk(0);
        return allocate_new_blk(((void *)0), aligned_size);
    }
    else
    {
        mem_blk_header *prev = heap_start;
        mem_blk_header *current = heap_start;
        while(current != ((void *)0))
        {
            if (current->assigned_flag == 0 && current->blk_size >= aligned_size)
            {
                return assign_blk(current, aligned_size);
            }
            prev = current;
            current = current->next;
        }
        return allocate_new_blk(prev, aligned_size);
    }
}

canonical_original_code:
void *niel_malloc(unsigned long size)
{
    unsigned long aligned_size = (((((size) - 1)>>3)<<3)+8);
    if (heap_start == ((void *)0))
    {
        heap_start = sbrk(0);
        return allocate_new_blk(((void *)0), aligned_size);
    }
    else
    {
        struct mem_blk_header *prev = heap_start;
        struct mem_blk_header *current = heap_start;
        while(current != ((void *)0))
        {
            if (current->assigned_flag == 0 && current->blk_size >= aligned_size)
            {
                return assign_blk(current, aligned_size);
            }
            prev = current;
            current = current->next;
        }
        return allocate_new_blk(prev, aligned_size);
    }
}

return_type: void *

user_defined_types: struct mem_blk_header { struct mem_blk_header *next; struct mem_blk_header *prev; void *mem_blk; unsigned long blk_size; int assigned_flag; }


decompiled_code:
void *__fastcall niel_calloc(__int64 a1, __int64 a2)
{
size_t v2; // rdi
char *v3; // rax

v2 = a2 * a1;
v3 = niel_malloc(v2);
return memset(v3, 0, v2);
}

canonical_decompiled_code:
void *__fastcall func12(__int64 a1, __int64 a2)
{
size_t v2; // rdi
char *v3; // rax

v2 = a2 * a1;
v3 = func9(v2);
return memset(v3, 0, v2);
}

original_code:
void *niel_calloc(size_t nr, size_t size)
{
    void *mem_ptr = ((void *)0);
    mem_ptr = niel_malloc(nr * size);
    memset(mem_ptr, '\0', nr * size);
    return mem_ptr;
}

canonical_original_code:
void *niel_calloc(unsigned long nr, unsigned long size)
{
    void *mem_ptr = ((void *)0);
    mem_ptr = niel_malloc(nr * size);
    memset(mem_ptr, '\0', nr * size);
    return mem_ptr;
}

variable_types:
nr
unsigned long


decompiled_code:
int cConfig_error(char *format, ...)
{
gcc_va_list arg; // [rsp+8h] [rbp-1D0h] BYREF
char s[256]; // [rsp+20h] [rbp-1B8h] BYREF

va_start(arg, format);
vsprintf(s, format, arg);
return fprintf(stderr, "cConfig error: %s\n", s);
}

canonical_decompiled_code:
int func0(char *format, ...)
{
gcc_va_list arg; // [rsp+8h] [rbp-1D0h] BYREF
char s[256]; // [rsp+20h] [rbp-1B8h] BYREF

va_start(arg, format);
vsprintf(s, format, arg);
return fprintf(stderr, "cConfig error: %s\n", s);
}

original_code:
void
cConfig_error(const char *format, ...)
{
    char buf[255];
    va_list vl;
    __builtin_va_start(vl,format);
    vsprintf(buf, format, vl);
    fprintf(stderr, "cConfig error: %s\n", buf);
    __builtin_va_end(vl);
}

canonical_original_code:
void cConfig_error(char *format, ...)
{
    char buf[255];
    __builtin_va_list vl;
    __builtin_va_start(vl,format);
    vsprintf(buf, format, vl);
    fprintf(stderr, "cConfig error: %s\n", buf);
    __builtin_va_end(vl);
}

variable_types:
format
char *

variable_types:
buf
char [255]


decompiled_code:
void cConfig_init()
{
if ( !config_table )
config_table = new_hash_table(150LL);
}

canonical_decompiled_code:
void func1()
{
if ( !config_table )
config_table = new_hash_table(150LL);
}

original_code:
void
cConfig_init(void)
{
    if (!config_table)
        config_table = new_hash_table(150);
}

canonical_original_code:
void cConfig_init()
{
    if (!config_table)
        config_table = new_hash_table(150);
}


decompiled_code:
__int64 __fastcall new_config_opt(__int64 a1, __int64 a2)
{
__int64 v2; // rbp
__int64 v3; // r12
__int64 result; // rax

v2 = a2;
v3 = xmalloc(40LL);
*(_QWORD *)v3 = dupstr(a1);
if ( a2 )
v2 = dupstr(a2);
*(_QWORD *)(v3 + 8) = v2;
result = v3;
*(_DWORD *)(v3 + 16) = 0;
*(_QWORD *)(v3 + 32) = 1LL;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __int64 a2)
{
__int64 v2; // rbp
__int64 v3; // r12
__int64 result; // rax

v2 = a2;
v3 = xmalloc(40LL);
*(_QWORD *)v3 = dupstr(a1);
if ( a2 )
v2 = dupstr(a2);
*(_QWORD *)(v3 + 8) = v2;
result = v3;
*(_DWORD *)(v3 + 16) = 0;
*(_QWORD *)(v3 + 32) = 1LL;
return result;
}

original_code:
cConfig_opt *
new_config_opt(const char *name, const char *value)
{
    cConfig_opt *opt;
    opt = xmalloc(sizeof(cConfig_opt));
    opt->name = dupstr(name);
    opt->value = value == ((void *)0) ? ((void *)0) : dupstr(value);
    opt->is_array = 0;
    opt->size = 1;
    return opt;
}

canonical_original_code:
struct config_opt *new_config_opt(char *name, char *value)
{
    struct config_opt *opt;
    opt = xmalloc(sizeof(cConfig_opt));
    opt->name = dupstr(name);
    opt->value = value == ((void *)0) ? ((void *)0) : dupstr(value);
    opt->is_array = 0;
    opt->size = 1;
    return opt;
}

variable_types:
name
char *

variable_types:
value
char *

variable_types: struct config_opt { char *name; char *value; unsigned int is_array; char **values; unsigned long size; } *


decompiled_code:
__int64 __fastcall cConfig_add_opt(__int64 a1, __int64 a2)
{
__int64 v2; // r12

v2 = new_config_opt(a1, a2);
insert_hash_node(a1, v2, config_table);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, __int64 a2)
{
__int64 v2; // r12

v2 = func2(a1, a2);
insert_hash_node(a1, v2, config_table);
return v2;
}

original_code:
cConfig_opt *
cConfig_add_opt(const char *name, const char *value)
{
    cConfig_opt *opt;
    opt = new_config_opt(name, value);
    insert_hash_node(name, (void *)opt, config_table);
    return opt;
}

canonical_original_code:
struct config_opt *cConfig_add_opt(char *name, char *value)
{
    struct config_opt *opt;
    opt = new_config_opt(name, value);
    insert_hash_node(name, (void *)opt, config_table);
    return opt;
}

return_type: struct config_opt { char *name; char *value; unsigned int is_array; char **values; unsigned long size; } *


decompiled_code:
__int64 __fastcall cConfig_add_opt_array(__int64 a1, __int64 a2, __int64 a3)
{
__int64 v4; // rax
__int64 v5; // rdx
__int64 v6; // r12

v4 = new_config_opt(a1, 0LL);
v5 = config_table;
*(_QWORD *)(v4 + 24) = a2;
v6 = v4;
*(_QWORD *)(v4 + 32) = a3;
*(_DWORD *)(v4 + 16) = 1;
insert_hash_node(a1, v4, v5);
return v6;
}

original_code:
cConfig_opt *
cConfig_add_opt_array(const char *name, char **values, const size_t size)
{
    cConfig_opt *opt;
    opt = new_config_opt(name, ((void *)0));
    opt->values = values;
    opt->is_array = 1;
    opt->size = size;
    insert_hash_node(name, (void *)opt, config_table);
    return opt;
}

canonical_original_code:
struct config_opt *cConfig_add_opt_array(char *name, char **values, unsigned long size)
{
    struct config_opt *opt;
    opt = new_config_opt(name, ((void *)0));
    opt->values = values;
    opt->is_array = 1;
    opt->size = size;
    insert_hash_node(name, (void *)opt, config_table);
    return opt;
}

variable_types:
values
char **

user_defined_types: struct config_opt { char *name; char *value; unsigned int is_array; char **values; unsigned long size; }


decompiled_code:
__int64 __fastcall parse_line(char *a1)
{
char v1; // al
char *v2; // rdx
__int64 v3; // rsi
char v4; // di
unsigned int v5; // ebx
int v6; // ecx
unsigned int v7; // er12
char v8; // al
char v10; // al
__int64 v11; // [rsp+0h] [rbp-228h] BYREF
__int64 v12; // [rsp+8h] [rbp-220h] BYREF
char v13[256]; // [rsp+10h] [rbp-218h] BYREF
char v14[280]; // [rsp+110h] [rbp-118h] BYREF

v1 = *a1;
if ( !*a1 )
return 1LL;
v2 = a1 + 1;
v3 = 0LL;
v4 = delim;
v5 = 0;
v6 = 0;
v7 = 0;
do
{
while ( v1 != 34 )
{
if ( v1 == 32 )
{
if ( v6 )
v13[v3++] = 32;
}
else if ( v4 == v1 )
{
if ( v7 )
{
v7 = 0;
cConfig_error("unexpected '%c'", (unsigned int)v4);
return v7;
}
v14[v3] = 0;
v7 = 1;
v3 = 0LL;
}
else
{
switch ( v1 )
{
case 10:
goto LABEL_18;
case 40:
if ( !v7 )
{
cConfig_error("unexpected '%c'", 40LL);
return v7;
}
v5 = v7;
break;
case 41:
if ( v5 )
{
v10 = *v2;
if ( *v2 != 10 )
{
if ( v10 )
{
v7 = 0;
cConfig_error("unexpected '%c' after '%c'", (unsigned int)v10, 41LL);
return v7;
}
}
}
break;
default:
if ( v7 )
v13[v3] = v1;
else
v14[v3] = v1;
++v3;
break;
}
}
v1 = *v2++;
if ( !v1 )
goto LABEL_18;
}
if ( !v7 )
{
cConfig_error("unexpected '%c'", 34LL);
return 0LL;
}
if ( v6 )
{
v8 = *v2;
if ( *v2 != 10 )
{
if ( v8 )
{
v7 = 0;
cConfig_error("unexpected '%c' after '%c'", (unsigned int)v8, 34LL);
return v7;
}
}
}
v1 = *v2++;
v6 ^= 1u;
}
while ( v1 );
LABEL_18:
v13[v3] = 0;
if ( !v7 )
return 1LL;
if ( v5 )
{
v7 = v5;
explode(v13, ",", &v11, &v12);
cConfig_add_opt_array((__int64)v14, v11, v12);
return v7;
}
cConfig_add_opt((__int64)v14, (__int64)v13);
return v7;
}

canonical_decompiled_code:
__int64 __fastcall func5(char *a1)
{
char v1; // al
char *v2; // rdx
__int64 v3; // rsi
char v4; // di
unsigned int v5; // ebx
int v6; // ecx
unsigned int v7; // er12
char v8; // al
char v10; // al
__int64 v11; // [rsp+0h] [rbp-228h] BYREF
__int64 v12; // [rsp+8h] [rbp-220h] BYREF
char v13[256]; // [rsp+10h] [rbp-218h] BYREF
char v14[280]; // [rsp+110h] [rbp-118h] BYREF

v1 = *a1;
if ( !*a1 )
return 1LL;
v2 = a1 + 1;
v3 = 0LL;
v4 = delim;
v5 = 0;
v6 = 0;
v7 = 0;
do
{
while ( v1 != 34 )
{
if ( v1 == 32 )
{
if ( v6 )
v13[v3++] = 32;
}
else if ( v4 == v1 )
{
if ( v7 )
{
v7 = 0;
func0("unexpected '%c'", (unsigned int)v4);
return v7;
}
v14[v3] = 0;
v7 = 1;
v3 = 0LL;
}
else
{
switch ( v1 )
{
case 10:
goto LABEL_18;
case 40:
if ( !v7 )
{
func0("unexpected '%c'", 40LL);
return v7;
}
v5 = v7;
break;
case 41:
if ( v5 )
{
v10 = *v2;
if ( *v2 != 10 )
{
if ( v10 )
{
v7 = 0;
func0("unexpected '%c' after '%c'", (unsigned int)v10, 41LL);
return v7;
}
}
}
break;
default:
if ( v7 )
v13[v3] = v1;
else
v14[v3] = v1;
++v3;
break;
}
}
v1 = *v2++;
if ( !v1 )
goto LABEL_18;
}
if ( !v7 )
{
func0("unexpected '%c'", 34LL);
return 0LL;
}
if ( v6 )
{
v8 = *v2;
if ( *v2 != 10 )
{
if ( v8 )
{
v7 = 0;
func0("unexpected '%c' after '%c'", (unsigned int)v8, 34LL);
return v7;
}
}
}
v1 = *v2++;
v6 ^= 1u;
}
while ( v1 );
LABEL_18:
v13[v3] = 0;
if ( !v7 )
return 1LL;
if ( v5 )
{
v7 = v5;
explode(v13, ",", &v11, &v12);
func4((__int64)v14, v11, v12);
return v7;
}
func3((__int64)v14, (__int64)v13);
return v7;
}

original_code:
static unsigned int
parse_line(char *string)
{
    char value[255], name[255], c;
    unsigned int have_name, have_quote, have_paren;
    char **values;
    size_t i = 0, len;
    have_name = have_quote = have_paren = 0;
    while ((c = *string++) != '\0')
    {
        if (c == '"')
        {
            if (!have_name)
            {
                cConfig_error("unexpected '%c'", '"');
                return 0;
            }
            if (have_quote && !(*string == '\n' || *string == '\0'))
            {
                cConfig_error("unexpected '%c' after '%c'", *string, '"');
                return 0;
            }
            have_quote = !have_quote;
        }
        else
        if (c == ' ')
        {
            if (have_quote)
                value[i++] = c;
        }
        else
        if (c == delim)
        {
            if (have_name)
            {
                cConfig_error("unexpected '%c'", delim);
                return 0;
            }
            have_name = 1;
            name[i] = '\0';
            i = 0;
        }
        else
        if (c == '\n')
            break;
        else
        if (c == '(')
        {
            if (!have_name)
            {
                cConfig_error("unexpected '%c'", '(');
                return 0;
            }
            have_paren = 1;
        }
        else
        if (c == ')')
        {
            if (have_paren && !(*string == '\n' || *string == '\0'))
            {
                cConfig_error("unexpected '%c' after '%c'", *string, ')');
                return 0;
            }
        }
        else
        {
            if (have_name)
                value[i++] = c;
            else
                name[i++] = c;
        }
    }
    value[i] = '\0';
    if (!have_name)
        return 1;
    if (have_paren)
    {
        explode(value, ",", &values, &len);
        cConfig_add_opt_array(name, values, len);
    }
    else
        cConfig_add_opt(name, value);
    return 1;
}

canonical_original_code:
static unsigned int parse_line(char *string)
{
    char value[255]; char name[255]; char c;
    unsigned int have_name; unsigned int have_quote; unsigned int have_paren;
    char **values;
    unsigned long i = 0; unsigned long len;
    have_name = have_quote = have_paren = 0;
    while ((c = *string++) != '\0')
    {
        if (c == '"')
        {
            if (!have_name)
            {
                cConfig_error("unexpected '%c'", '"');
                return 0;
            }
            if (have_quote && !(*string == '\n' || *string == '\0'))
            {
                cConfig_error("unexpected '%c' after '%c'", *string, '"');
                return 0;
            }
            have_quote = !have_quote;
        }
        else
        if (c == ' ')
        {
            if (have_quote)
                value[i++] = c;
        }
        else
        if (c == delim)
        {
            if (have_name)
            {
                cConfig_error("unexpected '%c'", delim);
                return 0;
            }
            have_name = 1;
            name[i] = '\0';
            i = 0;
        }
        else
        if (c == '\n')
            break;
        else
        if (c == '(')
        {
            if (!have_name)
            {
                cConfig_error("unexpected '%c'", '(');
                return 0;
            }
            have_paren = 1;
        }
        else
        if (c == ')')
        {
            if (have_paren && !(*string == '\n' || *string == '\0'))
            {
                cConfig_error("unexpected '%c' after '%c'", *string, ')');
                return 0;
            }
        }
        else
        {
            if (have_name)
                value[i++] = c;
            else
                name[i++] = c;
        }
    }
    value[i] = '\0';
    if (!have_name)
        return 1;
    if (have_paren)
    {
        explode(value, ",", &values, &len);
        cConfig_add_opt_array(name, values, len);
    }
    else
        cConfig_add_opt(name, value);
    return 1;
}

variable_types:
string
char *

variable_types:
value
char [255]

variable_types:
name
char [255]

variable_types: c char

variable_types:
i
unsigned long

variable_types:
len
unsigned long


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

result = find_hash_node(a1, config_table);
if ( result )
result = *(_QWORD *)(result + 8);
return result;
}

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

result = find_hash_node(a1, config_table);
if ( result )
result = *(_QWORD *)(result + 8);
return result;
}

original_code:
cConfig_opt *
cConfig_get_opt(const char *name)
{
    cConfig_opt *opt;
    Hash_node *node;
    node = find_hash_node(name, config_table);
    if (node)
        opt = node->data;
    else
        opt = ((void *)0);
    return opt;
}

canonical_original_code:
struct config_opt *cConfig_get_opt(char *name)
{
    struct config_opt *opt;
    struct hash_node *node;
    node = find_hash_node(name, config_table);
    if (node)
        opt = node->data;
    else
        opt = ((void *)0);
    return opt;
}

variable_types: struct hash_node { char *key; void *data; struct hash_node *next; } *


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

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

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

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

original_code:
char *
cConfig_get_value(const char *name)
{
    char *value;
    cConfig_opt *opt;
    opt = cConfig_get_opt(name);
    if (opt)
        value = opt->value;
    else
        value = ((void *)0);
    return value;
}

canonical_original_code:
char *cConfig_get_value(char *name)
{
    char *value;
    struct config_opt *opt;
    opt = cConfig_get_opt(name);
    if (opt)
        value = opt->value;
    else
        value = ((void *)0);
    return value;
}

return_type: char *


decompiled_code:
void __fastcall cConfig_set_delim(char a1)
{
delim = a1;
}

canonical_decompiled_code:
void __fastcall func8(char a1)
{
delim = a1;
}

original_code:
void
cConfig_set_delim(char d)
{
    delim = d;
}

variable_types: d char


decompiled_code:
__int64 __fastcall cConfig_find_opt_value(__int64 a1, __int64 a2)
{
__int64 v2; // rax
__int64 v3; // rbp
__int64 v4; // rbx

v2 = cConfig_get_opt(a1);
if ( !v2 )
return 0LL;
v3 = v2;
if ( !*(_DWORD *)(v2 + 16) || !*(_QWORD *)(v2 + 32) )
return 0LL;
v4 = 0LL;
while ( !(unsigned int)streq(*(_QWORD *)(*(_QWORD *)(v3 + 24) + 8 * v4), a2) )
{
if ( *(_QWORD *)(v3 + 32) <= (unsigned __int64)++v4 )
return 0LL;
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, __int64 a2)
{
__int64 v2; // rax
__int64 v3; // rbp
__int64 v4; // rbx

v2 = func6(a1);
if ( !v2 )
return 0LL;
v3 = v2;
if ( !*(_DWORD *)(v2 + 16) || !*(_QWORD *)(v2 + 32) )
return 0LL;
v4 = 0LL;
while ( !(unsigned int)streq(*(_QWORD *)(*(_QWORD *)(v3 + 24) + 8 * v4), a2) )
{
if ( *(_QWORD *)(v3 + 32) <= (unsigned __int64)++v4 )
return 0LL;
}
return 1LL;
}

original_code:
unsigned int
cConfig_find_opt_value(char *name, char *value)
{
    size_t i;
    cConfig_opt *opt;
    opt = cConfig_get_opt(name);
    if (opt == ((void *)0))
        return 0;
    if (!opt->is_array)
        return 0;
    for (i = 0; i < opt->size; ++i)
    {
        if (streq(opt->values[i], value))
            return 1;
    }
    return 0;
}

canonical_original_code:
unsigned int cConfig_find_opt_value(char *name, char *value)
{
    unsigned long i;
    struct config_opt *opt;
    opt = cConfig_get_opt(name);
    if (opt == ((void *)0))
        return 0;
    if (!opt->is_array)
        return 0;
    for (i = 0; i < opt->size; ++i)
    {
        if (streq(opt->values[i], value))
            return 1;
    }
    return 0;
}


decompiled_code:
int __fastcall cConfig_print_opt(__int64 a1)
{
__int64 v1; // rbp
const char *v2; // rdx
int result; // eax
unsigned __int64 i; // rbx
__int64 v5; // rdx
const char *v6; // rcx

v1 = cConfig_get_opt(a1);
if ( !v1 )
puts("NULL ==> NULL");
v2 = *(const char **)v1;
if ( *(_DWORD *)(v1 + 16) )
{
result = fprintf(stdout, "NAME ==> %s\n", v2);
for ( i = 0LL; *(_QWORD *)(v1 + 32) > i; result = fprintf(stdout, "VALUE [%d] ==> %s\n", v5, v6) )
{
v5 = i;
v6 = *(const char **)(*(_QWORD *)(v1 + 24) + 8 * i++);
}
}
else
{
fprintf(stdout, "NAME ==> %s\n", v2);
result = fprintf(stdout, "VALUE ==> %s\n", *(const char **)(v1 + 8));
}
return result;
}

canonical_decompiled_code:
int __fastcall func10(__int64 a1)
{
__int64 v1; // rbp
const char *v2; // rdx
int result; // eax
unsigned __int64 i; // rbx
__int64 v5; // rdx
const char *v6; // rcx

v1 = func6(a1);
if ( !v1 )
puts("NULL ==> NULL");
v2 = *(const char **)v1;
if ( *(_DWORD *)(v1 + 16) )
{
result = fprintf(stdout, "NAME ==> %s\n", v2);
for ( i = 0LL; *(_QWORD *)(v1 + 32) > i; result = fprintf(stdout, "VALUE [%d] ==> %s\n", v5, v6) )
{
v5 = i;
v6 = *(const char **)(*(_QWORD *)(v1 + 24) + 8 * i++);
}
}
else
{
fprintf(stdout, "NAME ==> %s\n", v2);
result = fprintf(stdout, "VALUE ==> %s\n", *(const char **)(v1 + 8));
}
return result;
}

original_code:
void
cConfig_print_opt(char *name)
{
    char **values;
    size_t i;
    cConfig_opt *opt;
    opt = cConfig_get_opt(name);
    if (opt == ((void *)0))
        puts("NULL ==> NULL");
    if (!opt->is_array)
    {
        fprintf(stdout, "NAME ==> %s\n", opt->name);
        fprintf(stdout, "VALUE ==> %s\n", opt->value);
        return;
    }
    values = opt->values;
    fprintf(stdout, "NAME ==> %s\n", opt->name);
    for (i = 0; i < opt->size; ++i)
        fprintf(stdout, "VALUE [%d] ==> %s\n", i, opt->values[i]);
}

canonical_original_code:
void cConfig_print_opt(char *name)
{
    char **values;
    unsigned long i;
    struct config_opt *opt;
    opt = cConfig_get_opt(name);
    if (opt == ((void *)0))
        puts("NULL ==> NULL");
    if (!opt->is_array)
    {
        fprintf(stdout, "NAME ==> %s\n", opt->name);
        fprintf(stdout, "VALUE ==> %s\n", opt->value);
        return;
    }
    values = opt->values;
    fprintf(stdout, "NAME ==> %s\n", opt->name);
    for (i = 0; i < opt->size; ++i)
        fprintf(stdout, "VALUE [%d] ==> %s\n", i, opt->values[i]);
}


original_code:
void
cConfig_free_opt(cConfig_opt *opt)
{
    size_t i;
    if (opt->is_array)
    {
        for (i = 0; i < opt->size; ++i)
            xfree(opt->values[i]);
        xfree(opt->values);
    }
    else
        xfree(opt->value);
    xfree(opt->name);
    xfree(opt);
}

canonical_original_code:
void cConfig_free_opt(struct config_opt *opt)
{
    unsigned long i;
    if (opt->is_array)
    {
        for (i = 0; i < opt->size; ++i)
            xfree(opt->values[i]);
        xfree(opt->values);
    }
    else
        xfree(opt->value);
    xfree(opt->name);
    xfree(opt);
}


decompiled_code:
__int64 cConfig_free()
{
unsigned __int64 *v0; // rax
unsigned __int64 v1; // rdi
unsigned __int64 v2; // r12
_QWORD *v3; // rbx
__int64 v4; // r13
_QWORD *v5; // rbp
__int64 v6; // rdi

v0 = (unsigned __int64 *)config_table;
v1 = *(_QWORD *)(config_table + 16);
if ( *(_QWORD *)config_table )
{
v2 = 0LL;
do
{
v3 = *(_QWORD **)(v1 + 8 * v2);
v4 = 8 * v2;
if ( v3 )
{
do
{
v5 = v3;
cConfig_free_opt(v3[1]);
v6 = *v3;
v3 = (_QWORD *)v3[2];
xfree(v6);
xfree(v5);
}
while ( v3 );
v0 = (unsigned __int64 *)config_table;
}
v1 = v0[2];
++v2;
*(_QWORD *)(v1 + v4) = 0LL;
}
while ( *v0 > v2 );
}
xfree(v1);
return xfree(config_table);
}

canonical_decompiled_code:
__int64 func13()
{
unsigned __int64 *v0; // rax
unsigned __int64 v1; // rdi
unsigned __int64 v2; // r12
_QWORD *v3; // rbx
__int64 v4; // r13
_QWORD *v5; // rbp
__int64 v6; // rdi

v0 = (unsigned __int64 *)config_table;
v1 = *(_QWORD *)(config_table + 16);
if ( *(_QWORD *)config_table )
{
v2 = 0LL;
do
{
v3 = *(_QWORD **)(v1 + 8 * v2);
v4 = 8 * v2;
if ( v3 )
{
do
{
v5 = v3;
func12(v3[1]);
v6 = *v3;
v3 = (_QWORD *)v3[2];
xfree(v6);
xfree(v5);
}
while ( v3 );
v0 = (unsigned __int64 *)config_table;
}
v1 = v0[2];
++v2;
*(_QWORD *)(v1 + v4) = 0LL;
}
while ( *v0 > v2 );
}
xfree(v1);
return xfree(config_table);
}

original_code:
void
cConfig_free(void)
{
    size_t i;
    Hash_node *node, *temp;
    cConfig_opt *opt;
    for (i = 0; i < config_table->size; ++i)
    {
        node = config_table->nodes[i];
        while (node)
        {
            opt = (cConfig_opt *)node->data;
            cConfig_free_opt(opt);
            temp = node;
            node = node->next;
            xfree(temp->key);
            xfree(temp);
        }
        config_table->nodes[i] = ((void *)0);
    }
    xfree(config_table->nodes);
    xfree(config_table);
}

canonical_original_code:
void cConfig_free()
{
    unsigned long i;
    struct hash_node *node; struct hash_node *temp;
    struct config_opt *opt;
    for (i = 0; i < config_table->size; ++i)
    {
        node = config_table->nodes[i];
        while (node)
        {
            opt = (struct config_opt *)node->data;
            cConfig_free_opt(opt);
            temp = node;
            node = node->next;
            xfree(temp->key);
            xfree(temp);
        }
        config_table->nodes[i] = ((void *)0);
    }
    xfree(config_table->nodes);
    xfree(config_table);
}

user_defined_types: struct hash_node { char *key; void *data; struct hash_node *next; }


xmalloc

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

result = malloc(a1);
if ( !result )
{
fprintf(stderr, "fatal: memory exhausted (malloc of %d bytes).\n", a1);
exit(1);
}
return result;
}

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

result = malloc(a1);
if ( !result )
{
fprintf(stderr, "fatal: memory exhausted (malloc of %d bytes).\n", a1);
exit(1);
}
return result;
}

original_code:
void *
xmalloc(const size_t size)
{
    void *ptr = malloc(size);
    if (ptr == ((void *)0))
    {
        fprintf (stderr, "fatal: memory exhausted (malloc of %d bytes).\n", size);
        exit (1);
    }
    return ptr;
}

canonical_original_code:
void *xmalloc(unsigned long size)
{
    void *ptr = malloc(size);
    if (ptr == ((void *)0))
    {
        fprintf (stderr, "fatal: memory exhausted (malloc of %d bytes).\n", size);
        exit (1);
    }
    return ptr;
}

variable_types:
size
unsigned long

variable_types:
ptr
void *


xcalloc

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

result = calloc(a1, a2);
if ( !result )
{
fprintf(stderr, "fatal: memory exhausted (xmalloc of %d bytes).\n", a2);
exit(1);
}
return result;
}

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

result = calloc(a1, a2);
if ( !result )
{
fprintf(stderr, "fatal: memory exhausted (xmalloc of %d bytes).\n", a2);
exit(1);
}
return result;
}

original_code:
void *
xcalloc(const size_t count, const size_t size)
{
    void *ptr;
    if (!(ptr = calloc(count, size)))
    {
        fprintf(stderr, "fatal: memory exhausted (xmalloc of %d bytes).\n", size);
        exit(1);
    }
    return ptr;
}

canonical_original_code:
void *xcalloc(unsigned long count, unsigned long size)
{
    void *ptr;
    if (!(ptr = calloc(count, size)))
    {
        fprintf(stderr, "fatal: memory exhausted (xmalloc of %d bytes).\n", size);
        exit(1);
    }
    return ptr;
}

variable_types:
count
unsigned long


xrealloc

decompiled_code:
void *__fastcall xrealloc(void *ptr, size_t a2)
{
void *result; // rax

result = realloc(ptr, a2);
if ( !result )
{
free(ptr);
fprintf(stderr, "fatal: memory exhausted (realloc of %d bytes).\n", a2);
exit(1);
}
return result;
}

canonical_decompiled_code:
void *__fastcall func2(void *ptr, size_t a2)
{
void *result; // rax

result = realloc(ptr, a2);
if ( !result )
{
free(ptr);
fprintf(stderr, "fatal: memory exhausted (realloc of %d bytes).\n", a2);
exit(1);
}
return result;
}

original_code:
void *
xrealloc(void *p, const size_t size)
{
    void *ptr = realloc(p, size);
    if (ptr == ((void *)0))
    {
        free(p);
        fprintf (stderr, "fatal: memory exhausted (realloc of %d bytes).\n", size);
        exit (1);
    }
    return ptr;
}

canonical_original_code:
void *xrealloc(void *p, unsigned long size)
{
    void *ptr = realloc(p, size);
    if (ptr == ((void *)0))
    {
        free(p);
        fprintf (stderr, "fatal: memory exhausted (realloc of %d bytes).\n", size);
        exit (1);
    }
    return ptr;
}

variable_types:
p
void *


xfree

decompiled_code:
void __fastcall xfree(void *a1)
{
if ( a1 )
free(a1);
}

canonical_decompiled_code:
void __fastcall func3(void *a1)
{
if ( a1 )
free(a1);
}

original_code:
void xfree(void *ptr)
{
    if (ptr != ((void *)0))
        free(ptr);
}


dupstr

decompiled_code:
char *__fastcall dupstr(char *src)
{
size_t v1; // rbx
char *v2; // rax
char *result; // rax

v1 = strlen(src);
v2 = (char *)xmalloc(v1 + 1);
result = strncpy(v2, src, v1);
result[v1] = 0;
return result;
}

canonical_decompiled_code:
char *__fastcall func4(char *src)
{
size_t v1; // rbx
char *v2; // rax
char *result; // rax

v1 = strlen(src);
v2 = (char *)func0(v1 + 1);
result = strncpy(v2, src, v1);
result[v1] = 0;
return result;
}

original_code:
char *
dupstr(const char *string)
{
    char *dup;
    size_t len;
    len = strlen(string);
    dup = xmalloc(len + 1);
    strncpy(dup, string, len);
    dup[len] = '\0';
    return dup;
}

canonical_original_code:
char *dupstr(char *string)
{
    char *dup;
    unsigned long len;
    len = strlen(string);
    dup = xmalloc(len + 1);
    strncpy(dup, string, len);
    dup[len] = '\0';
    return dup;
}

variable_types:
dup
char *


explode

decompiled_code:
__int64 __fastcall explode(char *a1, const char *a2, _QWORD *a3, _QWORD *a4)
{
char *v6; // r12
char *v7; // rbp
char **v8; // r15
char *v9; // r12
__int64 result; // rax
char *v11; // [rsp+0h] [rbp-48h]
char **v12; // [rsp+8h] [rbp-40h]

if ( a4 == 0LL || a3 == 0LL || !a1 )
return 0LL;
*a3 = 0LL;
*a4 = 0LL;
v11 = dupstr(a1);
v6 = strtok(v11, a2);
if ( v6 )
{
v7 = (char *)xmalloc(8uLL);
v12 = (char **)&v7[8 * *a4];
*v12 = dupstr(v6);
++*a4;
while ( 1 )
{
v9 = strtok(0LL, a2);
if ( !v9 )
break;
v7 = (char *)xrealloc(v7, 8LL * *a4 + 8);
v8 = (char **)&v7[8 * *a4];
*v8 = dupstr(v9);
++*a4;
}
*a3 = v7;
xfree(v11);
result = 1LL;
}
else
{
xfree(v11);
result = 0LL;
}
return result;
}

original_code:
unsigned int
explode(const char *src, const char *tokens, char ***list, size_t *len)
{
    char *str, *copy, **_list = ((void *)0);
    if (src == ((void *)0) || list == ((void *)0) || len == ((void *)0))
        return 0;
    *list = ((void *)0);
    *len = 0;
    copy = dupstr(src);
    str = strtok(copy, tokens);
    if (str == ((void *)0))
    {
        xfree(copy);
        return 0;
    }
    _list = xmalloc(sizeof(*_list));
    _list[*len] = dupstr(str);
    (*len)++;
    while((str = strtok(((void *)0), tokens)) != ((void *)0))
    {
        _list = xrealloc(_list, (*len + 1) * sizeof(*_list));
        _list[*len] = dupstr(str);
        (*len)++;
    }
    *list = _list;
    xfree(copy);
    return 1;
}

canonical_original_code:
unsigned int explode(char *src, char *tokens, char ***list, unsigned long *len)
{
    char *str; char *copy; char **_list = ((void *)0);
    if (src == ((void *)0) || list == ((void *)0) || len == ((void *)0))
        return 0;
    *list = ((void *)0);
    *len = 0;
    copy = dupstr(src);
    str = strtok(copy, tokens);
    if (str == ((void *)0))
    {
        xfree(copy);
        return 0;
    }
    _list = xmalloc(sizeof(*_list));
    _list[*len] = dupstr(str);
    (*len)++;
    while((str = strtok(((void *)0), tokens)) != ((void *)0))
    {
        _list = xrealloc(_list, (*len + 1) * sizeof(*_list));
        _list[*len] = dupstr(str);
        (*len)++;
    }
    *list = _list;
    xfree(copy);
    return 1;
}

variable_types:
src
char *

variable_types:
tokens
char *

variable_types:
list
char ***

variable_types:
len
unsigned long *

variable_types:
str
char *

variable_types:
copy
char *


streq

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

if ( *a1 == *a2 )
result = strcmp(a1, a2) == 0;
else
result = 0LL;
return result;
}

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

if ( *a1 == *a2 )
result = strcmp(a1, a2) == 0;
else
result = 0LL;
return result;
}

original_code:
unsigned int
streq(const char *string1, const char *string2)
{
    return (*string1 == *string2 && strcmp(string1, string2) == 0);
}

canonical_original_code:
unsigned int streq(char *string1, char *string2)
{
    return (*string1 == *string2 && strcmp(string1, string2) == 0);
}


hash

decompiled_code:
__int64 __fastcall hash(_BYTE *a1)
{
int v1; // eax
unsigned int i; // er8

v1 = (char)*a1;
for ( i = 0; *a1; v1 = (char)*a1 )
{
++a1;
i += 32 * i + v1;
}
return i;
}

canonical_decompiled_code:
__int64 __fastcall func0(_BYTE *a1)
{
int v1; // eax
unsigned int i; // er8

v1 = (char)*a1;
for ( i = 0; *a1; v1 = (char)*a1 )
{
++a1;
i += 32 * i + v1;
}
return i;
}

original_code:
static unsigned int
hash(const char *string)
{
    unsigned int hashval = 0;
    while (*string)
        hashval = ((hashval << 5) + hashval) + *string++;
    return hashval;
}

canonical_original_code:
static unsigned int hash(char *string)
{
    unsigned int hashval = 0;
    while (*string)
        hashval = ((hashval << 5) + hashval) + *string++;
    return hashval;
}

variable_types:
string
char *

variable_types:
hashval
unsigned int


decompiled_code:
__int64 __fastcall free_hash_node(_QWORD *a1)
{
xfree(*a1);
xfree(a1[1]);
return xfree(a1);
}

canonical_decompiled_code:
__int64 __fastcall func1(_QWORD *a1)
{
xfree(*a1);
xfree(a1[1]);
return xfree(a1);
}

original_code:
void
free_hash_node(Hash_node *node)
{
    xfree(node->key);
    xfree(node->data);
    xfree(node);
}

canonical_original_code:
void free_hash_node(struct hash_node *node)
{
    xfree(node->key);
    xfree(node->data);
    xfree(node);
}


decompiled_code:
__int64 __fastcall remove_hash_node(_BYTE *a1, _QWORD *a2)
{
_QWORD *v2; // r13
unsigned int v3; // eax
_QWORD *v4; // rbp
unsigned __int64 v5; // r14
bool v6; // zf
__int64 v7; // rax

v2 = 0LL;
v3 = hash(a1);
v4 = *(_QWORD **)(a2[2] + 8 * ((unsigned __int64)v3 % *a2));
v5 = (unsigned __int64)v3 % *a2;
if ( !v4 )
return 0LL;
while ( 1 )
{
v6 = (unsigned int)streq(*v4, a1) == 0;
v7 = v4[2];
if ( !v6 )
break;
v2 = v4;
if ( !v7 )
return 0LL;
v4 = (_QWORD *)v4[2];
}
if ( v2 )
v2[2] = v7;
else
*(_QWORD *)(a2[2] + 8 * v5) = v7;
free_hash_node(v4);
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(_BYTE *a1, _QWORD *a2)
{
_QWORD *v2; // r13
unsigned int v3; // eax
_QWORD *v4; // rbp
unsigned __int64 v5; // r14
bool v6; // zf
__int64 v7; // rax

v2 = 0LL;
v3 = func0(a1);
v4 = *(_QWORD **)(a2[2] + 8 * ((unsigned __int64)v3 % *a2));
v5 = (unsigned __int64)v3 % *a2;
if ( !v4 )
return 0LL;
while ( 1 )
{
v6 = (unsigned int)streq(*v4, a1) == 0;
v7 = v4[2];
if ( !v6 )
break;
v2 = v4;
if ( !v7 )
return 0LL;
v4 = (_QWORD *)v4[2];
}
if ( v2 )
v2[2] = v7;
else
*(_QWORD *)(a2[2] + 8 * v5) = v7;
func1(v4);
return 1LL;
}

original_code:
unsigned int
remove_hash_node(const char *key, Hash_table *table)
{
    Hash_node *node, *prev = ((void *)0);
    unsigned int hashkey;
    hashkey = hash(key) % table->size;
    node = table->nodes[hashkey];
    while (node)
    {
        if (!streq(node->key, key))
        {
            prev = node;
            node = node->next;
            continue;
        }
        if (prev)
            prev->next = node->next;
        else
            table->nodes[hashkey] = node->next;
        free_hash_node(node);
        return 1;
    }
    return 0;
}

canonical_original_code:
unsigned int remove_hash_node(char *key, struct hash_table *table)
{
    struct hash_node *node; struct hash_node *prev = ((void *)0);
    unsigned int hashkey;
    hashkey = hash(key) % table->size;
    node = table->nodes[hashkey];
    while (node)
    {
        if (!streq(node->key, key))
        {
            prev = node;
            node = node->next;
            continue;
        }
        if (prev)
            prev->next = node->next;
        else
            table->nodes[hashkey] = node->next;
        free_hash_node(node);
        return 1;
    }
    return 0;
}

variable_types:
key
char *

variable_types: struct hash_table { unsigned long size; unsigned long count; struct hash_node { char *key; void *data; struct hash_node *next; } **nodes; } *

variable_types:
hashkey
unsigned int

user_defined_types: struct hash_table { unsigned long size; unsigned long count; struct hash_node **nodes; }


decompiled_code:
__int64 __fastcall resize_hash_table(__int64 a1, unsigned __int64 **a2)
{
unsigned __int64 *v2; // rax
unsigned __int64 *v3; // r12
unsigned __int64 *v4; // r13
unsigned __int64 v5; // rdi
unsigned __int64 v6; // r14
__int64 v7; // rbx
_BYTE **v8; // rbp
__int64 result; // rax

v2 = new_hash_table(a1);
v3 = *a2;
v4 = v2;
v5 = (*a2)[2];
if ( **a2 )
{
v6 = 0LL;
do
{
v7 = *(_QWORD *)(v5 + 8 * v6);
if ( v7 )
{
do
{
v8 = (_BYTE **)v7;
v7 = *(_QWORD *)(v7 + 16);
insert_hash_node(*v8, (__int64)v8[1], v4);
remove_hash_node(*v8, v3);
}
while ( v7 );
v5 = v3[2];
}
++v6;
}
while ( *v3 > v6 );
}
xfree(v5);
result = xfree(v3);
*a2 = v4;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, unsigned __int64 **a2)
{
unsigned __int64 *v2; // rax
unsigned __int64 *v3; // r12
unsigned __int64 *v4; // r13
unsigned __int64 v5; // rdi
unsigned __int64 v6; // r14
__int64 v7; // rbx
_BYTE **v8; // rbp
__int64 result; // rax

v2 = new_hash_table(a1);
v3 = *a2;
v4 = v2;
v5 = (*a2)[2];
if ( **a2 )
{
v6 = 0LL;
do
{
v7 = *(_QWORD *)(v5 + 8 * v6);
if ( v7 )
{
do
{
v8 = (_BYTE **)v7;
v7 = *(_QWORD *)(v7 + 16);
insert_hash_node(*v8, (__int64)v8[1], v4);
func2(*v8, v3);
}
while ( v7 );
v5 = v3[2];
}
++v6;
}
while ( *v3 > v6 );
}
xfree(v5);
result = xfree(v3);
*a2 = v4;
return result;
}

original_code:
void
resize_hash_table(const size_t size, Hash_table **table)
{
    Hash_table *new_table, *old_table;
    Hash_node *node, *next;
    size_t i;
    new_table = new_hash_table(size);
    old_table = *table;
    for (i = 0; i < old_table->size; ++i)
        for (node = old_table->nodes[i]; node != ((void *)0); node = next)
        {
            next = node->next;
            insert_hash_node(node->key, node->data, new_table);
            remove_hash_node(node->key, old_table);
        }
    xfree(old_table->nodes);
    xfree(old_table);
    *table = new_table;
}

canonical_original_code:
void resize_hash_table(unsigned long size, struct hash_table **table)
{
    struct hash_table *new_table; struct hash_table *old_table;
    struct hash_node *node; struct hash_node *next;
    unsigned long i;
    new_table = new_hash_table(size);
    old_table = *table;
    for (i = 0; i < old_table->size; ++i)
        for (node = old_table->nodes[i]; node != ((void *)0); node = next)
        {
            next = node->next;
            insert_hash_node(node->key, node->data, new_table);
            remove_hash_node(node->key, old_table);
        }
    xfree(old_table->nodes);
    xfree(old_table);
    *table = new_table;
}

variable_types: struct hash_table { unsigned long size; unsigned long count; struct hash_node { char *key; void *data; struct hash_node *next; } **nodes; } **

variable_types:
i
unsigned long


decompiled_code:
__int64 __fastcall free_hash_table(unsigned __int64 *a1)
{
bool v2; // zf
unsigned __int64 v3; // rdi
unsigned __int64 v4; // rbp
_QWORD *v5; // rbx
_QWORD *v6; // rdi

v2 = *a1 == 0;
v3 = a1[2];
if ( !v2 )
{
v4 = 0LL;
do
{
v5 = *(_QWORD **)(v3 + 8 * v4);
if ( v5 )
{
do
{
v6 = v5;
v5 = (_QWORD *)v5[2];
free_hash_node(v6);
}
while ( v5 );
v3 = a1[2];
}
++v4;
}
while ( *a1 > v4 );
}
xfree(v3);
return xfree(a1);
}

canonical_decompiled_code:
__int64 __fastcall func4(unsigned __int64 *a1)
{
bool v2; // zf
unsigned __int64 v3; // rdi
unsigned __int64 v4; // rbp
_QWORD *v5; // rbx
_QWORD *v6; // rdi

v2 = *a1 == 0;
v3 = a1[2];
if ( !v2 )
{
v4 = 0LL;
do
{
v5 = *(_QWORD **)(v3 + 8 * v4);
if ( v5 )
{
do
{
v6 = v5;
v5 = (_QWORD *)v5[2];
func1(v6);
}
while ( v5 );
v3 = a1[2];
}
++v4;
}
while ( *a1 > v4 );
}
xfree(v3);
return xfree(a1);
}

original_code:
void
free_hash_table(Hash_table *table)
{
    size_t i;
    Hash_node *node, *prev;
    for (i = 0; i < table->size; ++i)
    {
        node = table->nodes[i];
        while (node)
        {
            prev = node;
            node = node->next;
            free_hash_node(prev);
        }
    }
    xfree(table->nodes);
    xfree(table);
}

canonical_original_code:
void free_hash_table(struct hash_table *table)
{
    unsigned long i;
    struct hash_node *node; struct hash_node *prev;
    for (i = 0; i < table->size; ++i)
    {
        node = table->nodes[i];
        while (node)
        {
            prev = node;
            node = node->next;
            free_hash_node(prev);
        }
    }
    xfree(table->nodes);
    xfree(table);
}

variable_types: struct hash_node { char *key; void *data; struct hash_node *next; } *


main

repo: nijel/polld

decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
int *v3; // rax
char *v4; // rax
__int64 v5; // rbx
int v6; // eax
int v7; // ebp
__int64 v8; // rbx
void *v9; // rdi

parse_params(argc, (char **)argv);
load_config();
check_lock();
do_lock();
if ( daemon(0, 0) )
{
v3 = __errno_location();
v4 = strerror(*v3);
fprintf(stderr, "polld: Failed to start daemon: %s\n", v4);
exit(1);
}
do_lock();
signal(2, interrupt);
signal(3, interrupt);
signal(15, interrupt);
signal(1, hup);
while ( !shutdown )
{
while ( 1 )
{
sleep(sleeptime);
if ( reload )
{
if ( listlen > 0 )
{
v8 = 0LL;
do
{
v9 = (void *)*((_QWORD *)filelist + v8++);
free(v9);
}
while ( listlen > (int)v8 );
}
free(filelist);
filelist = 0LL;
listlen = 0;
alloclen = 0;
load_config();
}
if ( listlen <= 0 )
break;
v5 = 0LL;
do
{
v6 = open(*((const char **)filelist + v5), 0);
v7 = v6;
if ( v6 != -1 )
{
ioctl(v6, 0x125FuLL);
close(v7);
}
++v5;
}
while ( listlen > (int)v5 );
if ( shutdown )
goto LABEL_12;
}
}
LABEL_12:
bye();
}

canonical_decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
int *v3; // rax
char *v4; // rax
__int64 v5; // rbx
int v6; // eax
int v7; // ebp
__int64 v8; // rbx
void *v9; // rdi

func10(argc, (char **)argv);
func11();
func12();
func13();
if ( daemon(0, 0) )
{
v3 = __errno_location();
v4 = strerror(*v3);
fprintf(stderr, "polld: Failed to start daemon: %s\n", v4);
exit(1);
}
func13();
signal(2, interrupt);
signal(3, interrupt);
signal(15, interrupt);
signal(1, hup);
while ( !shutdown )
{
while ( 1 )
{
sleep(sleeptime);
if ( reload )
{
if ( listlen > 0 )
{
v8 = 0LL;
do
{
v9 = (void *)*((_QWORD *)filelist + v8++);
free(v9);
}
while ( listlen > (int)v8 );
}
free(filelist);
filelist = 0LL;
listlen = 0;
alloclen = 0;
func11();
}
if ( listlen <= 0 )
break;
v5 = 0LL;
do
{
v6 = open(*((const char **)filelist + v5), 0);
v7 = v6;
if ( v6 != -1 )
{
ioctl(v6, 0x125FuLL);
close(v7);
}
++v5;
}
while ( listlen > (int)v5 );
if ( shutdown )
goto LABEL_12;
}
}
LABEL_12:
func14();
}

original_code:
int main(int argc, char **argv) {
    int i;
 int file;
    parse_params(argc, argv);
    load_config();
    check_lock();
    do_lock();
    if (daemon(0, 0) != 0) {
        fprintf(stderr, "polld: " "Failed to start daemon: %s\n", strerror((*__errno_location ())));
        exit(1);
    }
    do_lock();
    signal(2, interrupt);
    signal(3, interrupt);
    signal(15, interrupt);
    signal(1, hup);
    while (!shutdown) {
        sleep(sleeptime);
        if (reload) {
            for (i = 0; i < listlen; i++) {
                free(filelist[i]);
            }
            free(filelist);
            filelist = ((void *)0);
            listlen = 0;
            alloclen = 0;
            load_config();
        }
        for (i = 0; i < listlen; i++) {
            file = open(filelist[i], 00);
            if (file != -1) {
    ioctl(file, (((0U) << (((0 +8)+8)+14)) | (((0x12)) << (0 +8)) | (((95)) << 0) | ((0) << ((0 +8)+8))));
    close(file);
   }
        }
    }
    bye();
    return 0;
}

variable_types: argc int

variable_types:
argv
char **

variable_types: i int

variable_types: file int


hup

decompiled_code:
void __fastcall hup(int a1)
{
reload = a1;
}

canonical_decompiled_code:
void __fastcall func7(int a1)
{
reload = a1;
}

original_code:
void hup(int sign)
{
    reload = sign;
}

canonical_original_code:
void hup(int sign)
{
    reload = sign;
}

variable_types: sign int


decompiled_code:
void __noreturn show_version()
{
puts(
"polld version 0.2\n"
"Copyright (C) 2004-2006 Michal Cihar <michal@cihar.com>\n"
"This is free software. You may redistribute copies of it under the terms of\n"
"the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.\n"
"There is NO WARRANTY, to the extent permitted by law.");
exit(0);
}

canonical_decompiled_code:
void __noreturn func8()
{
puts(
"polld version 0.2\n"
"Copyright (C) 2004-2006 Michal Cihar <michal@cihar.com>\n"
"This is free software. You may redistribute copies of it under the terms of\n"
"the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.\n"
"There is NO WARRANTY, to the extent permitted by law.");
exit(0);
}

original_code:
void show_version(void) {
    printf("polld version " "0.2" "\n"
            "Copyright (C) 2004-2006 Michal Cihar <michal@cihar.com>\n"
            "This is free software.  You may redistribute copies of it under the terms of\n"
            "the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.\n"
            "There is NO WARRANTY, to the extent permitted by law.\n");
    exit(0);
}

canonical_original_code:
void show_version() {
    printf("polld version " "0.2" "\n"
            "Copyright (C) 2004-2006 Michal Cihar <michal@cihar.com>\n"
            "This is free software.  You may redistribute copies of it under the terms of\n"
            "the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.\n"
            "There is NO WARRANTY, to the extent permitted by law.\n");
    exit(0);
}


decompiled_code:
void __noreturn show_help()
{
puts(
"Usage: polld [params]\n"
"Parameters\n"
" -h --help show this help\n"
" -v --version show version information\n"
" -c --config file configuration file to use\n"
" -p --pid file lock file for storing pid, empty for no locking\n"
" -s --sleep seconds number of seconds to sleep in sleep cycle\n");
exit(0);
}

canonical_decompiled_code:
void __noreturn func9()
{
puts(
"Usage: polld [params]\n"
"Parameters\n"
" -h --help show this help\n"
" -v --version show version information\n"
" -c --config file configuration file to use\n"
" -p --pid file lock file for storing pid, empty for no locking\n"
" -s --sleep seconds number of seconds to sleep in sleep cycle\n");
exit(0);
}

original_code:
void show_help(void) {
    printf( "Usage: polld [params]\n"
            "Parameters\n"
            " -h --help             show this help\n"
            " -v --version          show version information\n"
            " -c --config file      configuration file to use\n"
            " -p --pid file         lock file for storing pid, empty for no locking\n"
            " -s --sleep seconds    number of seconds to sleep in sleep cycle\n"
            "\n");
    exit(0);
}

canonical_original_code:
void show_help() {
    printf( "Usage: polld [params]\n"
            "Parameters\n"
            " -h --help             show this help\n"
            " -v --version          show version information\n"
            " -c --config file      configuration file to use\n"
            " -p --pid file         lock file for storing pid, empty for no locking\n"
            " -s --sleep seconds    number of seconds to sleep in sleep cycle\n"
            "\n");
    exit(0);
}


decompiled_code:
int __fastcall parse_params(int argc, char **argv)
{
char *v2; // rax
int result; // eax
int longind; // [rsp+Ch] [rbp-DCh] BYREF
struct option longopts; // [rsp+10h] [rbp-D8h] BYREF
const char *v6; // [rsp+30h] [rbp-B8h]
int v7; // [rsp+38h] [rbp-B0h]
__int64 v8; // [rsp+40h] [rbp-A8h]
int v9; // [rsp+48h] [rbp-A0h]
const char *v10; // [rsp+50h] [rbp-98h]
int v11; // [rsp+58h] [rbp-90h]
__int64 v12; // [rsp+60h] [rbp-88h]
int v13; // [rsp+68h] [rbp-80h]
const char *v14; // [rsp+70h] [rbp-78h]
int v15; // [rsp+78h] [rbp-70h]
__int64 v16; // [rsp+80h] [rbp-68h]
int v17; // [rsp+88h] [rbp-60h]
const char *v18; // [rsp+90h] [rbp-58h]
int v19; // [rsp+98h] [rbp-50h]
__int64 v20; // [rsp+A0h] [rbp-48h]
int v21; // [rsp+A8h] [rbp-40h]
__int64 v22; // [rsp+B0h] [rbp-38h]
int v23; // [rsp+B8h] [rbp-30h]
__int64 v24; // [rsp+C0h] [rbp-28h]
int v25; // [rsp+C8h] [rbp-20h]

opterr = 0;
longopts.name = "help";
longopts.has_arg = 0;
longopts.flag = 0LL;
longopts.val = 104;
v6 = "version";
v7 = 0;
v8 = 0LL;
v9 = 118;
v10 = "config";
v11 = 1;
v12 = 0LL;
v13 = 99;
v14 = "sleep";
v15 = 1;
v16 = 0LL;
v17 = 115;
v18 = "pid";
v19 = 1;
v20 = 0LL;
v21 = 112;
v22 = 0LL;
v23 = 0;
v24 = 0LL;
v25 = 0;
while ( 2 )
{
LODWORD(v2) = getopt_long(argc, argv, "hvc:s:p:", &longopts, &longind);
if ( (_DWORD)v2 != -1 )
{
switch ( (int)v2 )
{
case 'c':
if ( config )
free(config);
config = strdup(optarg);
continue;
case 'h':
show_help();
return result;
case 'p':
if ( pid )
free(pid);
pid = strdup(optarg);
continue;
case 's':
sleeptime = atoi(optarg);
if ( (int)sleeptime <= 0 )
{
fwrite("polld: Invalid sleep time!\n", 1uLL, 0x1BuLL, stderr);
exit(1);
}
continue;
case 'v':
show_version();
return result;
default:
goto LABEL_18;
}
}
break;
}
if ( optind < argc )
{
LABEL_18:
fwrite("polld: Invalid parameters, use --help for help.\n", 1uLL, 0x30uLL, stderr);
exit(1);
}
if ( config )
{
if ( pid )
return (int)v2;
}
else
{
v2 = strdup("/etc/polld");
config = v2;
if ( pid )
return (int)v2;
}
v2 = strdup("/var/run/polld.pid");
pid = v2;
return (int)v2;
}

canonical_decompiled_code:
int __fastcall func10(int argc, char **argv)
{
char *v2; // rax
int result; // eax
int longind; // [rsp+Ch] [rbp-DCh] BYREF
struct option longopts; // [rsp+10h] [rbp-D8h] BYREF
const char *v6; // [rsp+30h] [rbp-B8h]
int v7; // [rsp+38h] [rbp-B0h]
__int64 v8; // [rsp+40h] [rbp-A8h]
int v9; // [rsp+48h] [rbp-A0h]
const char *v10; // [rsp+50h] [rbp-98h]
int v11; // [rsp+58h] [rbp-90h]
__int64 v12; // [rsp+60h] [rbp-88h]
int v13; // [rsp+68h] [rbp-80h]
const char *v14; // [rsp+70h] [rbp-78h]
int v15; // [rsp+78h] [rbp-70h]
__int64 v16; // [rsp+80h] [rbp-68h]
int v17; // [rsp+88h] [rbp-60h]
const char *v18; // [rsp+90h] [rbp-58h]
int v19; // [rsp+98h] [rbp-50h]
__int64 v20; // [rsp+A0h] [rbp-48h]
int v21; // [rsp+A8h] [rbp-40h]
__int64 v22; // [rsp+B0h] [rbp-38h]
int v23; // [rsp+B8h] [rbp-30h]
__int64 v24; // [rsp+C0h] [rbp-28h]
int v25; // [rsp+C8h] [rbp-20h]

opterr = 0;
longopts.name = "help";
longopts.has_arg = 0;
longopts.flag = 0LL;
longopts.val = 104;
v6 = "version";
v7 = 0;
v8 = 0LL;
v9 = 118;
v10 = "config";
v11 = 1;
v12 = 0LL;
v13 = 99;
v14 = "sleep";
v15 = 1;
v16 = 0LL;
v17 = 115;
v18 = "pid";
v19 = 1;
v20 = 0LL;
v21 = 112;
v22 = 0LL;
v23 = 0;
v24 = 0LL;
v25 = 0;
while ( 2 )
{
LODWORD(v2) = getopt_long(argc, argv, "hvc:s:p:", &longopts, &longind);
if ( (_DWORD)v2 != -1 )
{
switch ( (int)v2 )
{
case 'c':
if ( config )
free(config);
config = strdup(optarg);
continue;
case 'h':
func9();
return result;
case 'p':
if ( pid )
free(pid);
pid = strdup(optarg);
continue;
case 's':
sleeptime = atoi(optarg);
if ( (int)sleeptime <= 0 )
{
fwrite("polld: Invalid sleep time!\n", 1uLL, 0x1BuLL, stderr);
exit(1);
}
continue;
case 'v':
func8();
return result;
default:
goto LABEL_18;
}
}
break;
}
if ( optind < argc )
{
LABEL_18:
fwrite("polld: Invalid parameters, use --help for help.\n", 1uLL, 0x30uLL, stderr);
exit(1);
}
if ( config )
{
if ( pid )
return (int)v2;
}
else
{
v2 = strdup("/etc/polld");
config = v2;
if ( pid )
return (int)v2;
}
v2 = strdup("/var/run/polld.pid");
pid = v2;
return (int)v2;
}

original_code:
void parse_params(int argc, char **argv) {
    struct option long_options[] = {
       {"help" , 0, 0, 'h'},
       {"version" , 0, 0, 'v'},
       {"config" , 1, 0, 'c'},
       {"sleep" , 1, 0, 's'},
       {"pid" , 1, 0, 'p'},
       {0 , 0, 0, 0}
    };
    int c;
    int option_index;
    opterr = 0;
    while ((c = getopt_long (argc, argv, "hvc:s:p:", long_options, &option_index)) != -1) {
        switch (c) {
            case 'h':
                show_help();
                break;
            case 'v':
                show_version();
                break;
            case 'c':
                if (config != ((void *)0)) free(config);
                config = strdup(optarg);
                break;
            case 'p':
                if (pid != ((void *)0)) free(pid);
                pid = strdup(optarg);
                break;
            case 's':
                sleeptime = atoi(optarg);
                if (sleeptime <= 0) {
                    fprintf(stderr, "polld: " "Invalid sleep time!\n");
                    exit(1);
                }
                break;
            default:
                fprintf(stderr, "polld: " "Invalid parameters, use --help for help.\n");
                exit(1);
                break;
        }
    }
    if (optind < argc) {
        fprintf(stderr, "polld: " "Invalid parameters, use --help for help.\n");
        exit(1);
    }
    if (config == ((void *)0)) {
        config = strdup("/etc/polld");
    }
    if (pid == ((void *)0)) {
        pid = strdup("/var/run/polld.pid");
    }
}

variable_types: struct option { char *name; int has_arg; int *flag; int val; } []

variable_types: c int


bye

decompiled_code:
void __noreturn bye()
{
if ( *pid )
unlink(pid);
exit(0);
}

canonical_decompiled_code:
void __noreturn func14()
{
if ( *pid )
unlink(pid);
exit(0);
}

original_code:
void bye(void) {
    if (strlen(pid) != 0) {
        unlink(pid);
    }
    exit(0);
}

canonical_original_code:
void bye() {
    if (strlen(pid) != 0) {
        unlink(pid);
    }
    exit(0);
}


interrupt

decompiled_code:
void __fastcall __noreturn interrupt(int a1)
{
signal(a1, (__sighandler_t)1);
shutdown = 1;
bye();
}

canonical_decompiled_code:
void __fastcall __noreturn func15(int a1)
{
signal(a1, (__sighandler_t)1);
shutdown = 1;
func14();
}

original_code:
void interrupt(int sign)
{
    signal(sign, ((__sighandler_t) 1));
    shutdown = 1;
    bye();
}

canonical_original_code:
void interrupt(int sign)
{
    signal(sign, ((void (*)(int)) 1));
    shutdown = 1;
    bye();
}


decompiled_code:
__int64 __fastcall parser_string_to_directive_type(const char *a1)
{
unsigned int v1; // er8

if ( !a1 )
return 4LL;
v1 = 0;
if ( strcmp("data", a1) )
{
v1 = 1;
if ( strcmp("string", a1) )
{
v1 = 2;
if ( strcmp("entry", a1) )
v1 = 3 - ((strcmp("extern", a1) == 0) - 1);
}
}
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func0(const char *a1)
{
unsigned int v1; // er8

if ( !a1 )
return 4LL;
v1 = 0;
if ( strcmp("data", a1) )
{
v1 = 1;
if ( strcmp("string", a1) )
{
v1 = 2;
if ( strcmp("entry", a1) )
v1 = 3 - ((strcmp("extern", a1) == 0) - 1);
}
}
return v1;
}

original_code:
directive_type_t parser_string_to_directive_type(const char* szDirective)
{
 if (szDirective == ((void *)0))
  return DIRECTIVE_ILLEGAL;
 if (strcmp("data", szDirective) == 0)
 {
  return DIRECTIVE_DATA;
 }
 else if (strcmp("string", szDirective) == 0)
 {
  return DIRECTIVE_STRING;
 }
 else if (strcmp("entry", szDirective) == 0)
 {
  return DIRECTIVE_ENTRY;
 }
 else if (strcmp("extern", szDirective) == 0)
 {
  return DIRECTIVE_EXTERN;
 }
 else
 {
  return DIRECTIVE_ILLEGAL;
 }
}

canonical_original_code:
enum directive_type_t parser_string_to_directive_type(char *szDirective)
{
 if (szDirective == ((void *)0))
  return DIRECTIVE_ILLEGAL;
 if (strcmp("data", szDirective) == 0)
 {
  return DIRECTIVE_DATA;
 }
 else if (strcmp("string", szDirective) == 0)
 {
  return DIRECTIVE_STRING;
 }
 else if (strcmp("entry", szDirective) == 0)
 {
  return DIRECTIVE_ENTRY;
 }
 else if (strcmp("extern", szDirective) == 0)
 {
  return DIRECTIVE_EXTERN;
 }
 else
 {
  return DIRECTIVE_ILLEGAL;
 }
}

variable_types:
szDirective
char *

return_type: enum directive_type_t { DIRECTIVE_DATA=0, DIRECTIVE_STRING=1, DIRECTIVE_ENTRY=2, DIRECTIVE_EXTERN=3, DIRECTIVE_ILLEGAL=4 }


decompiled_code:
__int64 __fastcall parser_string_to_instruction_type(char *s1)
{
__int64 v1; // rbx

if ( !s1 )
return 16LL;
v1 = 0LL;
while ( strcmp(s1, *((const char **)&g_arrInstructionSyntax + 4 * v1 + 1)) )
{
if ( ++v1 == 16 )
return 16LL;
}
return *((unsigned int *)&g_arrInstructionSyntax + 8 * (unsigned int)v1);
}

canonical_decompiled_code:
__int64 __fastcall func1(char *s1)
{
__int64 v1; // rbx

if ( !s1 )
return 16LL;
v1 = 0LL;
while ( strcmp(s1, *((const char **)&g_arrInstructionSyntax + 4 * v1 + 1)) )
{
if ( ++v1 == 16 )
return 16LL;
}
return *((unsigned int *)&g_arrInstructionSyntax + 8 * (unsigned int)v1);
}

original_code:
opcode_t parser_string_to_instruction_type(const char* szInstruction)
{
 unsigned i;
 if (szInstruction == ((void *)0))
  return (STOP+1);
 for (i = 0; i < (STOP+1); i++)
 {
  if (strcmp(szInstruction,
       g_arrInstructionSyntax[i].name) == 0)
  {
   return g_arrInstructionSyntax[i].opcode;
  }
 }
 return (STOP+1);
}

canonical_original_code:
enum opcode_t parser_string_to_instruction_type(char *szInstruction)
{
 unsigned int i;
 if (szInstruction == ((void *)0))
  return (STOP+1);
 for (i = 0; i < (STOP+1); i++)
 {
  if (strcmp(szInstruction,
       g_arrInstructionSyntax[i].name) == 0)
  {
   return g_arrInstructionSyntax[i].opcode;
  }
 }
 return (STOP+1);
}

variable_types:
szInstruction
char *

variable_types:
i
unsigned int

return_type: enum opcode_t { MOV=0, CMP=1, ADD=2, SUB=3, NOT=4, CLR=5, LEA=6, INC=7, DEC=8, JMP=9, BNE=10, RED=11, PRN=12, JSR=13, RTS=14, STOP=15 }


decompiled_code:
__int64 __fastcall parser_string_to_register_type(char *s1)
{
__int64 v1; // rbx
const char *i; // rsi
unsigned int v3; // er12

if ( !s1 )
return 16LL;
v1 = 0LL;
for ( i = "r0"; ; i = arrRegisterNames_0[v1] )
{
v3 = v1;
if ( !strcmp(s1, i) )
break;
if ( ++v1 == 8 )
return 8;
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func2(char *s1)
{
__int64 v1; // rbx
const char *i; // rsi
unsigned int v3; // er12

if ( !s1 )
return 16LL;
v1 = 0LL;
for ( i = "r0"; ; i = arrRegisterNames_0[v1] )
{
v3 = v1;
if ( !strcmp(s1, i) )
break;
if ( ++v1 == 8 )
return 8;
}
return v3;
}

original_code:
machine_registers_t parser_string_to_register_type(const char* szRegister)
{
 static const char* arrRegisterNames[(R7+1)] =
  {
  "r0",
  "r1",
  "r2",
  "r3",
  "r4",
  "r5",
  "r6",
  "r7"
  };
 machine_registers_t currRegister;
 if (szRegister == ((void *)0))
  return (STOP+1);
 for (currRegister = (opcode_t)0;
   currRegister < (R7+1);
   currRegister++)
 {
  if (strcmp(szRegister, arrRegisterNames[currRegister]) == 0)
  {
   return currRegister;
  }
 }
 return (R7+1);
}

canonical_original_code:
enum machine_registers_t parser_string_to_register_type(char *szRegister)
{
 static char *arrRegisterNames[-1] = {
  "r0",
  "r1",
  "r2",
  "r3",
  "r4",
  "r5",
  "r6",
  "r7"
  };
 enum machine_registers_t currRegister;
 if (szRegister == ((void *)0))
  return (STOP+1);
 for (currRegister = (enum opcode_t)0;
   currRegister < (R7+1);
   currRegister++)
 {
  if (strcmp(szRegister, arrRegisterNames[currRegister]) == 0)
  {
   return currRegister;
  }
 }
 return (R7+1);
}

variable_types:
szRegister
char *

variable_types:
arrRegisterNames
char *[-1]

user_defined_types: enum opcode_t { MOV=0, CMP=1, ADD=2, SUB=3, NOT=4, CLR=5, LEA=6, INC=7, DEC=8, JMP=9, BNE=10, RED=11, PRN=12, JSR=13, RTS=14, STOP=15 }


decompiled_code:
__int64 __fastcall parser_check_symbol_syntax(char *s1)
{
size_t v1; // rax
unsigned int v2; // er12
int v3; // er8
__int64 result; // rax

if ( !s1 )
return 0LL;
if ( ((*_ctype_b_loc())[*s1] & 0x400) != 0 )
{
v1 = strlen(s1);
v2 = v1;
if ( v1 )
{
if ( v1 > 0x1E )
{
printf("Error! symbol '%s' is %u characters long, max length is %u.\n", s1, v1, 30LL);
result = 0LL;
}
else if ( (unsigned int)parser_string_to_instruction_type(s1) == 16 )
{
v3 = parser_string_to_register_type(s1);
result = v2;
if ( v3 != 8 )
{
printf("Error! name '%s' is a register name, cannot be a symbol.\n", s1);
result = 0LL;
}
}
else
{
printf("Error! name '%s' is an instruction name, cannot be a symbol.\n", s1);
result = 0LL;
}
}
else
{
puts("Error! symbol must contain at least 1 character.");
result = 0LL;
}
}
else
{
printf("Error! symbol '%s' doesn't begin with a letter.\n", s1);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(char *s1)
{
size_t v1; // rax
unsigned int v2; // er12
int v3; // er8
__int64 result; // rax

if ( !s1 )
return 0LL;
if ( ((*_ctype_b_loc())[*s1] & 0x400) != 0 )
{
v1 = strlen(s1);
v2 = v1;
if ( v1 )
{
if ( v1 > 0x1E )
{
printf("Error! symbol '%s' is %u characters long, max length is %u.\n", s1, v1, 30LL);
result = 0LL;
}
else if ( (unsigned int)func1(s1) == 16 )
{
v3 = func2(s1);
result = v2;
if ( v3 != 8 )
{
printf("Error! name '%s' is a register name, cannot be a symbol.\n", s1);
result = 0LL;
}
}
else
{
printf("Error! name '%s' is an instruction name, cannot be a symbol.\n", s1);
result = 0LL;
}
}
else
{
puts("Error! symbol must contain at least 1 character.");
result = 0LL;
}
}
else
{
printf("Error! symbol '%s' doesn't begin with a letter.\n", s1);
result = 0LL;
}
return result;
}

original_code:
int parser_check_symbol_syntax(const char* szSymbol)
{
 size_t nSymbolLength = 0;
 if (szSymbol == ((void *)0))
  return 0;
 if (((*__ctype_b_loc ())[(int) ((szSymbol[0]))] & (unsigned short int) _ISalpha) == 0)
 {
  printf("Error! symbol '%s' doesn't begin with a letter.\n",
    szSymbol);
  return 0;
 }
 nSymbolLength = strlen(szSymbol);
 if (nSymbolLength == 0)
 {
  printf("Error! symbol must contain at least 1 character.\n");
  return 0;
 }
 else
 {
  if (nSymbolLength > ((unsigned int)30))
  {
   printf("Error! symbol '%s' is %u characters long, max length is %u.\n",
     szSymbol,
     nSymbolLength,
     ((unsigned int)30));
   return 0;
  }
 }
 if (parser_string_to_instruction_type(szSymbol) != (STOP+1))
 {
  printf("Error! name '%s' is an instruction name, cannot be a symbol.\n",
    szSymbol);
  return 0;
 }
 if (parser_string_to_register_type(szSymbol) != (R7+1))
 {
  printf("Error! name '%s' is a register name, cannot be a symbol.\n",
    szSymbol);
  return 0;
 }
 return nSymbolLength;
}

canonical_original_code:
int parser_check_symbol_syntax(char *szSymbol)
{
 unsigned long nSymbolLength = 0;
 if (szSymbol == ((void *)0))
  return 0;
 if (((*__ctype_b_loc ())[(int) ((szSymbol[0]))] & (unsigned short) _ISalpha) == 0)
 {
  printf("Error! symbol '%s' doesn't begin with a letter.\n",
    szSymbol);
  return 0;
 }
 nSymbolLength = strlen(szSymbol);
 if (nSymbolLength == 0)
 {
  printf("Error! symbol must contain at least 1 character.\n");
  return 0;
 }
 else
 {
  if (nSymbolLength > ((unsigned int)30))
  {
   printf("Error! symbol '%s' is %u characters long, max length is %u.\n",
     szSymbol,
     nSymbolLength,
     ((unsigned int)30));
   return 0;
  }
 }
 if (parser_string_to_instruction_type(szSymbol) != (STOP+1))
 {
  printf("Error! name '%s' is an instruction name, cannot be a symbol.\n",
    szSymbol);
  return 0;
 }
 if (parser_string_to_register_type(szSymbol) != (R7+1))
 {
  printf("Error! name '%s' is a register name, cannot be a symbol.\n",
    szSymbol);
  return 0;
 }
 return nSymbolLength;
}

variable_types:
szSymbol
char *

variable_types:
nSymbolLength
unsigned long