decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbp
void *v4; // r15
int v5; // ecx
const char *v6; // r14
size_t v7; // r12
int v8; // er13
FILE *v9; // rax
FILE *v10; // r12
int v11; // ebp
const char *v12; // rcx
int v13; // er15
int v15; // ebx
size_t v16; // rax
size_t v17; // r8
int v18; // er10
char *v19; // rsi
__int64 v20; // rdi
__int64 v21; // rax
int v22; // edx
__int64 v23; // rbx
__int64 v24; // r13
bool v25; // zf
_BOOL4 v26; // er15
size_t v27; // rax
int v28; // edi
int v29; // edx
unsigned __int8 *v30; // rax
int v31; // ecx
int v32; // edx
char *v33; // rax
__int64 v34; // rcx
int v35; // ebx
__int64 v36; // r12
__int64 v37; // r14
unsigned __int8 v38; // r13
size_t v39; // rax
__int64 v40; // r8
size_t v41; // r9
int v42; // ebx
__int64 v43; // rdi
__int64 v44; // rax
int v45; // edx
int v46; // [rsp+0h] [rbp-1088h]
__int64 v47; // [rsp+0h] [rbp-1088h]
char *ptr; // [rsp+8h] [rbp-1080h]
int v49; // [rsp+14h] [rbp-1074h]
int v50; // [rsp+18h] [rbp-1070h]
FILE *v51; // [rsp+20h] [rbp-1068h]
int v53; // [rsp+3Ch] [rbp-104Ch] BYREF
int v54; // [rsp+40h] [rbp-1048h] BYREF
int v55; // [rsp+44h] [rbp-1044h] BYREF
char *v56; // [rsp+48h] [rbp-1040h] BYREF
char s1[1024]; // [rsp+50h] [rbp-1038h] BYREF
char v58[1024]; // [rsp+450h] [rbp-C38h] BYREF
char s; // [rsp+850h] [rbp-838h] BYREF
char v60; // [rsp+851h] [rbp-837h]
char v61[1081]; // [rsp+C4Fh] [rbp-439h]

v56 = 0LL;
v54 = 0;
v55 = 0;
if ( (unsigned int)(argc - 2) > 1 || !argv )
{
v13 = 1;
fputc(10, stderr);
fwrite("Byte tester 2.1\n", 1uLL, 0x10uLL, stderr);
fputc(10, stderr);
fprintf(stderr, "USAGE: %s [-s] <TESTS FILE / SOURCE FILE>\n", *argv);
fputc(10, stderr);
fwrite(
"If -s is given then we read tests file data from the comments of a source code file.\n",
1uLL,
0x55uLL,
stderr);
fputc(10, stderr);
fwrite("TESTS FILE FORMAT:\n", 1uLL, 0x13uLL, stderr);
fputc(10, stderr);
fwrite("...\n", 1uLL, 4uLL, stderr);
fwrite("<BINARY FILE NAME>\n", 1uLL, 0x13uLL, stderr);
fwrite(
"<TEST ID> <TAG ID> START <BYTE 1> <BYTE 2> ... <BYTE N> END /* Require the bytes to be between the tags */\n",
1uLL,
0x6BuLL,
stderr);
fwrite(
"<TEST ID> -a <INTEGER ADDRESS> START <BYTE 1> <BYTE 2> ... <BYTE N> END /* Require the bytes to be at the address */\n",
1uLL,
0x75uLL,
stderr);
fwrite("<TEST ID> -y <STRING> /* Require that the string is found */\n", 1uLL, 0x3DuLL, stderr);
fwrite("<TEST ID> -n <STRING> /* Require that the string is not found */\n", 1uLL, 0x41uLL, stderr);
fwrite("...\n", 1uLL, 4uLL, stderr);
fputc(10, stderr);
fwrite(
"If <TAG ID> is \"01\", then we test if the bytes between \"01>\" and \"<01\" match with bytes 1...n\n",
1uLL,
0x5EuLL,
stderr);
fputc(10, stderr);
return v13;
}
v3 = 1LL;
v4 = 0LL;
v5 = 0;
do
{
v6 = argv[v3];
if ( *(_WORD *)v6 != 29485 || v6[2] )
{
v46 = v5;
v7 = strlen(argv[v3]) + 1;
v4 = calloc(v7, 1uLL);
memcpy(v4, v6, v7);
v5 = v46;
}
else
{
v5 = 1;
}
++v3;
}
while ( argc > (int)v3 );
v8 = v5;
v9 = fopen((const char *)v4, "rb");
v10 = v9;
if ( !v9 )
{
v13 = 1;
fprintf(stderr, "Error opening file \"%s\".\n", argv[1]);
return v13;
}
fseek(v9, 0LL, 2);
v11 = ftell(v10);
fseek(v10, 0LL, 0);
ptr = (char *)calloc(v11 + 1, 1uLL);
v56 = ptr;
if ( v11 != fread(ptr, 1uLL, v11, v10) )
{
v12 = (const char *)v4;
v13 = 0;
fprintf(stderr, "Could not read all %d bytes of \"%s\"!", (unsigned int)v11, v12);
return v13;
}
free(v4);
if ( v8 )
extract_comments(ptr, v11);
get_token((const char **)&v56, (__int64)s1);
if ( !(unsigned int)read_binary_file(s1, &v55, v10, &v53) )
return 1;
v50 = 0;
v49 = 0;
while ( 1 )
{
do
{
if ( !(unsigned int)get_token((const char **)&v56, (__int64)v58) )
{
LABEL_76:
v13 = v49;
goto LABEL_77;
}
if ( !(unsigned int)read_binary_file(v58, &v55, v10, &v53) )
return 1;
}
while ( v55 == 1 );
if ( !(unsigned int)get_token((const char **)&v56, (__int64)&s) )
goto LABEL_76;
if ( strlen(&s) != 2 )
{
v13 = 1;
fprintf(stderr, "Test \"%s\" FAILED - TAG ID must be exactly two characters long. Error in \"%s\".\n", v58, &s);
goto LABEL_77;
}
if ( !strcmp(&s, "-a") )
break;
if ( !strcmp(&s, "-y") )
{
if ( !(unsigned int)get_token((const char **)&v56, (__int64)s1) )
goto LABEL_76;
v39 = strlen(s1);
v40 = 0LL;
v41 = v39;
v42 = v39;
v43 = (unsigned int)(v39 + 1);
while ( 2 )
{
if ( v53 > (int)v40 )
{
if ( v41 )
{
v44 = 1LL;
do
{
if ( (unsigned __int8)*((char *)g_binary_file + v40 + v44 - 1) != *((char *)&v56 + v44 + 7) )
goto LABEL_91;
v45 = v44++;
}
while ( v44 != v43 );
if ( v42 != v45 )
{
LABEL_91:
++v40;
continue;
}
}
goto LABEL_34;
}
break;
}
LABEL_40:
v23 = 0LL;
do
{
v24 = (unsigned int)v23;
if ( !(unsigned int)get_token((const char **)&v56, (__int64)s1) )
{
v26 = 1;
goto LABEL_49;
}
v25 = strcmp(s1, "END") == 0;
v26 = !v25;
if ( v25 )
goto LABEL_49;
v27 = strlen(s1);
if ( v27 == 1 )
{
v61[v23 + 1] = s1[0];
}
else
{
if ( v27 != 2 )
{
v26 = 1;
fprintf(
stderr,
"Test \"%s\" FAILED - Unknown data \"%s\" in test \"%s\"! Must either be a character, two character hexadec"
"imal value or END.\n",
v58,
s1,
v58);
v49 = 1;
goto LABEL_49;
}
v61[v23 + 1] = strtol(s1, 0LL, 16);
}
++v23;
}
while ( v23 != 1024 );
v24 = 1024LL;
v26 = 1;
fprintf(stderr, "Test \"%s\" FAILED - Each test can contain max %d bytes.\n", v58, 1024LL);
v49 = 1;
LABEL_49:
if ( v50 )
{
v32 = v54;
if ( !(_DWORD)v24 )
goto LABEL_78;
LABEL_65:
v35 = 0;
v47 = (unsigned int)(v24 + 1);
v51 = v10;
v36 = 1LL;
v37 = v32 - 1LL;
do
{
v38 = v61[v36];
if ( v38 != *((_BYTE *)g_binary_file + v37 + v36) )
{
if ( v35 )
fprintf(stderr, ", %d", (unsigned int)v36);
else
fprintf(stderr, "Test \"%s\" FAILED - Bytes that don't match: %d", v58, (unsigned int)v36);
++v35;
fprintf(stderr, " (GOT: $%.2x EXPECTED: $%.2x)", *((unsigned __int8 *)g_binary_file + v37 + v36), v38);
}
++v36;
}
while ( v47 != v36 );
v10 = v51;
if ( v35 )
{
fputc(10, stderr);
v49 = 1;
}
else
{
LABEL_78:
fprintf(stderr, "Test \"%s\" SUCCEEDED!\n", v58);
}
goto LABEL_75;
}
v28 = v53 - 2;
if ( v53 - 2 <= 0 )
{
if ( v53 == 2 )
{
LABEL_98:
fprintf(stderr, "Test \"%s\" FAILED - Could not find tag \"%s>\".\n", v58, &s);
v49 = 1;
goto LABEL_75;
}
v34 = 4294967293LL;
}
else
{
v29 = 0;
v30 = (unsigned __int8 *)g_binary_file;
while ( 1 )
{
v31 = v29++;
if ( *v30 == s && v30[1] == v60 && v30[2] == 62 )
break;
++v30;
if ( v28 == v29 )
goto LABEL_98;
}
v32 = v31 + 3;
if ( v31 >= v28 )
{
LABEL_96:
if ( v31 == v28 )
{
fprintf(stderr, "Test \"%s\" FAILED - Could not find tag \"<%s\".\n", v58, &s);
v49 = 1;
goto LABEL_75;
}
}
else
{
v33 = (char *)g_binary_file + v31;
while ( *v33 != 60 || (unsigned __int8)v33[1] != s || (unsigned __int8)v33[2] != v60 )
{
++v31;
++v33;
if ( v31 >= v28 )
goto LABEL_96;
}
}
v34 = (unsigned int)(v31 - v32);
if ( (_DWORD)v24 == (_DWORD)v34 )
goto LABEL_65;
}
fprintf(
stderr,
"Test \"%s\" FAILED - There is %d bytes between the tags \"%s\", but the test \"%s\" defines %d bytes.\n",
v58,
v34,
&s,
v58,
v24);
v49 = 1;
LABEL_75:
if ( v26 )
goto LABEL_76;
}
else
{
v15 = strcmp(&s, "-n");
if ( v15 )
{
if ( !(unsigned int)get_token((const char **)&v56, (__int64)s1) )
goto LABEL_76;
if ( strcmp(s1, "START") )
{
v13 = 1;
fprintf(stderr, "Test \"%s\" FAILED - START/-a/-y/-n is missing in \"%s\".\n", v58, argv[1]);
goto LABEL_77;
}
goto LABEL_40;
}
if ( !(unsigned int)get_token((const char **)&v56, (__int64)s1) )
goto LABEL_76;
v16 = strlen(s1);
v17 = v16;
v18 = v16;
if ( v53 > 0 )
{
v19 = (char *)g_binary_file;
v20 = (unsigned int)(v16 + 1);
while ( 2 )
{
if ( !v17 )
return 1;
v21 = 1LL;
while ( (unsigned __int8)v19[v21 - 1] == *((char *)&v56 + v21 + 7) )
{
v22 = v21++;
if ( v21 == v20 )
{
if ( v18 == v22 )
return 1;
break;
}
}
++v15;
++v19;
if ( v53 != v15 )
continue;
break;
}
}
LABEL_34:
fprintf(stderr, "Test \"%s\" SUCCEEDED!\n", v58);
}
}
if ( !(unsigned int)get_token((const char **)&v56, (__int64)s1) )
goto LABEL_76;
if ( (unsigned int)get_next_number(s1, &v54) )
{
if ( !(unsigned int)get_token((const char **)&v56, (__int64)s1) )
goto LABEL_76;
if ( strcmp(s1, "START") )
{
v13 = 1;
fprintf(stderr, "Test \"%s\" FAILED - START is missing in \"%s\".\n", v58, argv[1]);
goto LABEL_77;
}
v50 = 1;
goto LABEL_40;
}
v13 = 1;
fprintf(stderr, "\"%s\" is not a number.\n", s1);
LABEL_77:
fclose(v10);
free(ptr);
free(g_binary_file);
return v13;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbp
void *v4; // r15
int v5; // ecx
const char *v6; // r14
size_t v7; // r12
int v8; // er13
FILE *v9; // rax
FILE *v10; // r12
int v11; // ebp
const char *v12; // rcx
int v13; // er15
int v15; // ebx
size_t v16; // rax
size_t v17; // r8
int v18; // er10
char *v19; // rsi
__int64 v20; // rdi
__int64 v21; // rax
int v22; // edx
__int64 v23; // rbx
__int64 v24; // r13
bool v25; // zf
_BOOL4 v26; // er15
size_t v27; // rax
int v28; // edi
int v29; // edx
unsigned __int8 *v30; // rax
int v31; // ecx
int v32; // edx
char *v33; // rax
__int64 v34; // rcx
int v35; // ebx
__int64 v36; // r12
__int64 v37; // r14
unsigned __int8 v38; // r13
size_t v39; // rax
__int64 v40; // r8
size_t v41; // r9
int v42; // ebx
__int64 v43; // rdi
__int64 v44; // rax
int v45; // edx
int v46; // [rsp+0h] [rbp-1088h]
__int64 v47; // [rsp+0h] [rbp-1088h]
char *ptr; // [rsp+8h] [rbp-1080h]
int v49; // [rsp+14h] [rbp-1074h]
int v50; // [rsp+18h] [rbp-1070h]
FILE *v51; // [rsp+20h] [rbp-1068h]
int v53; // [rsp+3Ch] [rbp-104Ch] BYREF
int v54; // [rsp+40h] [rbp-1048h] BYREF
int v55; // [rsp+44h] [rbp-1044h] BYREF
char *v56; // [rsp+48h] [rbp-1040h] BYREF
char s1[1024]; // [rsp+50h] [rbp-1038h] BYREF
char v58[1024]; // [rsp+450h] [rbp-C38h] BYREF
char s; // [rsp+850h] [rbp-838h] BYREF
char v60; // [rsp+851h] [rbp-837h]
char v61[1081]; // [rsp+C4Fh] [rbp-439h]

v56 = 0LL;
v54 = 0;
v55 = 0;
if ( (unsigned int)(argc - 2) > 1 || !argv )
{
v13 = 1;
fputc(10, stderr);
fwrite("Byte tester 2.1\n", 1uLL, 0x10uLL, stderr);
fputc(10, stderr);
fprintf(stderr, "USAGE: %s [-s] <TESTS FILE / SOURCE FILE>\n", *argv);
fputc(10, stderr);
fwrite(
"If -s is given then we read tests file data from the comments of a source code file.\n",
1uLL,
0x55uLL,
stderr);
fputc(10, stderr);
fwrite("TESTS FILE FORMAT:\n", 1uLL, 0x13uLL, stderr);
fputc(10, stderr);
fwrite("...\n", 1uLL, 4uLL, stderr);
fwrite("<BINARY FILE NAME>\n", 1uLL, 0x13uLL, stderr);
fwrite(
"<TEST ID> <TAG ID> START <BYTE 1> <BYTE 2> ... <BYTE N> END /* Require the bytes to be between the tags */\n",
1uLL,
0x6BuLL,
stderr);
fwrite(
"<TEST ID> -a <INTEGER ADDRESS> START <BYTE 1> <BYTE 2> ... <BYTE N> END /* Require the bytes to be at the address */\n",
1uLL,
0x75uLL,
stderr);
fwrite("<TEST ID> -y <STRING> /* Require that the string is found */\n", 1uLL, 0x3DuLL, stderr);
fwrite("<TEST ID> -n <STRING> /* Require that the string is not found */\n", 1uLL, 0x41uLL, stderr);
fwrite("...\n", 1uLL, 4uLL, stderr);
fputc(10, stderr);
fwrite(
"If <TAG ID> is \"01\", then we test if the bytes between \"01>\" and \"<01\" match with bytes 1...n\n",
1uLL,
0x5EuLL,
stderr);
fputc(10, stderr);
return v13;
}
v3 = 1LL;
v4 = 0LL;
v5 = 0;
do
{
v6 = argv[v3];
if ( *(_WORD *)v6 != 29485 || v6[2] )
{
v46 = v5;
v7 = strlen(argv[v3]) + 1;
v4 = calloc(v7, 1uLL);
memcpy(v4, v6, v7);
v5 = v46;
}
else
{
v5 = 1;
}
++v3;
}
while ( argc > (int)v3 );
v8 = v5;
v9 = fopen((const char *)v4, "rb");
v10 = v9;
if ( !v9 )
{
v13 = 1;
fprintf(stderr, "Error opening file \"%s\".\n", argv[1]);
return v13;
}
fseek(v9, 0LL, 2);
v11 = ftell(v10);
fseek(v10, 0LL, 0);
ptr = (char *)calloc(v11 + 1, 1uLL);
v56 = ptr;
if ( v11 != fread(ptr, 1uLL, v11, v10) )
{
v12 = (const char *)v4;
v13 = 0;
fprintf(stderr, "Could not read all %d bytes of \"%s\"!", (unsigned int)v11, v12);
return v13;
}
free(v4);
if ( v8 )
func3(ptr, v11);
func2((const char **)&v56, (__int64)s1);
if ( !(unsigned int)func1(s1, &v55, v10, &v53) )
return 1;
v50 = 0;
v49 = 0;
while ( 1 )
{
do
{
if ( !(unsigned int)func2((const char **)&v56, (__int64)v58) )
{
LABEL_76:
v13 = v49;
goto LABEL_77;
}
if ( !(unsigned int)func1(v58, &v55, v10, &v53) )
return 1;
}
while ( v55 == 1 );
if ( !(unsigned int)func2((const char **)&v56, (__int64)&s) )
goto LABEL_76;
if ( strlen(&s) != 2 )
{
v13 = 1;
fprintf(stderr, "Test \"%s\" FAILED - TAG ID must be exactly two characters long. Error in \"%s\".\n", v58, &s);
goto LABEL_77;
}
if ( !strcmp(&s, "-a") )
break;
if ( !strcmp(&s, "-y") )
{
if ( !(unsigned int)func2((const char **)&v56, (__int64)s1) )
goto LABEL_76;
v39 = strlen(s1);
v40 = 0LL;
v41 = v39;
v42 = v39;
v43 = (unsigned int)(v39 + 1);
while ( 2 )
{
if ( v53 > (int)v40 )
{
if ( v41 )
{
v44 = 1LL;
do
{
if ( (unsigned __int8)*((char *)g_binary_file + v40 + v44 - 1) != *((char *)&v56 + v44 + 7) )
goto LABEL_91;
v45 = v44++;
}
while ( v44 != v43 );
if ( v42 != v45 )
{
LABEL_91:
++v40;
continue;
}
}
goto LABEL_34;
}
break;
}
LABEL_40:
v23 = 0LL;
do
{
v24 = (unsigned int)v23;
if ( !(unsigned int)func2((const char **)&v56, (__int64)s1) )
{
v26 = 1;
goto LABEL_49;
}
v25 = strcmp(s1, "END") == 0;
v26 = !v25;
if ( v25 )
goto LABEL_49;
v27 = strlen(s1);
if ( v27 == 1 )
{
v61[v23 + 1] = s1[0];
}
else
{
if ( v27 != 2 )
{
v26 = 1;
fprintf(
stderr,
"Test \"%s\" FAILED - Unknown data \"%s\" in test \"%s\"! Must either be a character, two character hexadec"
"imal value or END.\n",
v58,
s1,
v58);
v49 = 1;
goto LABEL_49;
}
v61[v23 + 1] = strtol(s1, 0LL, 16);
}
++v23;
}
while ( v23 != 1024 );
v24 = 1024LL;
v26 = 1;
fprintf(stderr, "Test \"%s\" FAILED - Each test can contain max %d bytes.\n", v58, 1024LL);
v49 = 1;
LABEL_49:
if ( v50 )
{
v32 = v54;
if ( !(_DWORD)v24 )
goto LABEL_78;
LABEL_65:
v35 = 0;
v47 = (unsigned int)(v24 + 1);
v51 = v10;
v36 = 1LL;
v37 = v32 - 1LL;
do
{
v38 = v61[v36];
if ( v38 != *((_BYTE *)g_binary_file + v37 + v36) )
{
if ( v35 )
fprintf(stderr, ", %d", (unsigned int)v36);
else
fprintf(stderr, "Test \"%s\" FAILED - Bytes that don't match: %d", v58, (unsigned int)v36);
++v35;
fprintf(stderr, " (GOT: $%.2x EXPECTED: $%.2x)", *((unsigned __int8 *)g_binary_file + v37 + v36), v38);
}
++v36;
}
while ( v47 != v36 );
v10 = v51;
if ( v35 )
{
fputc(10, stderr);
v49 = 1;
}
else
{
LABEL_78:
fprintf(stderr, "Test \"%s\" SUCCEEDED!\n", v58);
}
goto LABEL_75;
}
v28 = v53 - 2;
if ( v53 - 2 <= 0 )
{
if ( v53 == 2 )
{
LABEL_98:
fprintf(stderr, "Test \"%s\" FAILED - Could not find tag \"%s>\".\n", v58, &s);
v49 = 1;
goto LABEL_75;
}
v34 = 4294967293LL;
}
else
{
v29 = 0;
v30 = (unsigned __int8 *)g_binary_file;
while ( 1 )
{
v31 = v29++;
if ( *v30 == s && v30[1] == v60 && v30[2] == 62 )
break;
++v30;
if ( v28 == v29 )
goto LABEL_98;
}
v32 = v31 + 3;
if ( v31 >= v28 )
{
LABEL_96:
if ( v31 == v28 )
{
fprintf(stderr, "Test \"%s\" FAILED - Could not find tag \"<%s\".\n", v58, &s);
v49 = 1;
goto LABEL_75;
}
}
else
{
v33 = (char *)g_binary_file + v31;
while ( *v33 != 60 || (unsigned __int8)v33[1] != s || (unsigned __int8)v33[2] != v60 )
{
++v31;
++v33;
if ( v31 >= v28 )
goto LABEL_96;
}
}
v34 = (unsigned int)(v31 - v32);
if ( (_DWORD)v24 == (_DWORD)v34 )
goto LABEL_65;
}
fprintf(
stderr,
"Test \"%s\" FAILED - There is %d bytes between the tags \"%s\", but the test \"%s\" defines %d bytes.\n",
v58,
v34,
&s,
v58,
v24);
v49 = 1;
LABEL_75:
if ( v26 )
goto LABEL_76;
}
else
{
v15 = strcmp(&s, "-n");
if ( v15 )
{
if ( !(unsigned int)func2((const char **)&v56, (__int64)s1) )
goto LABEL_76;
if ( strcmp(s1, "START") )
{
v13 = 1;
fprintf(stderr, "Test \"%s\" FAILED - START/-a/-y/-n is missing in \"%s\".\n", v58, argv[1]);
goto LABEL_77;
}
goto LABEL_40;
}
if ( !(unsigned int)func2((const char **)&v56, (__int64)s1) )
goto LABEL_76;
v16 = strlen(s1);
v17 = v16;
v18 = v16;
if ( v53 > 0 )
{
v19 = (char *)g_binary_file;
v20 = (unsigned int)(v16 + 1);
while ( 2 )
{
if ( !v17 )
return 1;
v21 = 1LL;
while ( (unsigned __int8)v19[v21 - 1] == *((char *)&v56 + v21 + 7) )
{
v22 = v21++;
if ( v21 == v20 )
{
if ( v18 == v22 )
return 1;
break;
}
}
++v15;
++v19;
if ( v53 != v15 )
continue;
break;
}
}
LABEL_34:
fprintf(stderr, "Test \"%s\" SUCCEEDED!\n", v58);
}
}
if ( !(unsigned int)func2((const char **)&v56, (__int64)s1) )
goto LABEL_76;
if ( (unsigned int)func0(s1, &v54) )
{
if ( !(unsigned int)func2((const char **)&v56, (__int64)s1) )
goto LABEL_76;
if ( strcmp(s1, "START") )
{
v13 = 1;
fprintf(stderr, "Test \"%s\" FAILED - START is missing in \"%s\".\n", v58, argv[1]);
goto LABEL_77;
}
v50 = 1;
goto LABEL_40;
}
v13 = 1;
fprintf(stderr, "\"%s\" is not a number.\n", s1);
LABEL_77:
fclose(v10);
free(ptr);
free(g_binary_file);
return v13;
}

variable_types: i int


main

canonical_name: main

repo: vhelin/wla-dx

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char **i; // rbx
const char *v4; // rbp
int v5; // eax
__int64 v6; // rcx
__int64 j; // rax
unsigned __int64 v8; // rax
__int64 v9; // rdx
unsigned __int16 v10; // ax

for ( i = &g_instructions_table; ; i += 2 )
{
v4 = *i;
if ( **i == 69 && !v4[1] )
break;
v5 = strlen(*i);
if ( v5 <= 0 )
goto LABEL_12;
v6 = (unsigned int)(v5 - 1);
for ( j = 0LL; v4[j] != 46; ++j )
{
if ( v6 == j )
goto LABEL_12;
}
v8 = (unsigned int)(unsigned __int8)v4[j + 1] - 66;
if ( (unsigned __int8)v8 <= 0x15u )
{
v9 = 2098177LL;
if ( _bittest64(&v9, v8) )
continue;
}
LABEL_12:
printf("\"%s\" ", v4);
v10 = *((_WORD *)i + 4);
if ( (v10 & 0xFF00) != 0 )
printf("$%.2X%.2X\n", (unsigned __int8)v10, HIBYTE(v10));
else
printf("$%.2X\n", v10);
}
return 0;
}

original_code:
int main(int argc, char *argv[]) {
  int i, l, n;
  i = 0;
  while (1) {
    if (strcmp(g_instructions_table[i].string, "E") == 0)
      break;
    l = strlen(g_instructions_table[i].string);
    for (n = 0; n < l; n++) {
      if (g_instructions_table[i].string[n] == '.')
        break;
    }
    if (n < l && (g_instructions_table[i].string[n+1] == 'B' || g_instructions_table[i].string[n+1] == 'W' || g_instructions_table[i].string[n+1] == 'L')) {
      i++;
      continue;
    }
    printf("\"%s\" ", g_instructions_table[i].string);
    if (g_instructions_table[i].hex & 0xFF00)
      printf("$%.2X%.2X\n", g_instructions_table[i].hex & 0xFF, (g_instructions_table[i].hex >> 8) & 0xFF);
    else
      printf("$%.2X\n", g_instructions_table[i].hex);
    i++;
  }
  return 0;
}

canonical_original_code:
int main(int argc, char *argv[]) {
  int i; int l; int n;
  i = 0;
  while (1) {
    if (strcmp(g_instructions_table[i].string, "E") == 0)
      break;
    l = strlen(g_instructions_table[i].string);
    for (n = 0; n < l; n++) {
      if (g_instructions_table[i].string[n] == '.')
        break;
    }
    if (n < l && (g_instructions_table[i].string[n+1] == 'B' || g_instructions_table[i].string[n+1] == 'W' || g_instructions_table[i].string[n+1] == 'L')) {
      i++;
      continue;
    }
    printf("\"%s\" ", g_instructions_table[i].string);
    if (g_instructions_table[i].hex & 0xFF00)
      printf("$%.2X%.2X\n", g_instructions_table[i].hex & 0xFF, (g_instructions_table[i].hex >> 8) & 0xFF);
    else
      printf("$%.2X\n", g_instructions_table[i].hex);
    i++;
  }
  return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: l int

variable_types: n int

return_type: int


repo: vhmth/Lego-Box

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

if ( a1 )
{
*(_DWORD *)(a1 + 32) = 0;
((void (*)(void))stack_init)();
result = stack_init(a1 + 16);
}
return result;
}

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

if ( a1 )
{
*(_DWORD *)(a1 + 32) = 0;
((void (*)(void))stack_init)();
result = func16(a1 + 16);
}
return result;
}

original_code:
void queue_init(queue_t *q){
    if (!q)
        return;
    q->size = 0;
    stack_init(&(q->in));
    stack_init(&(q->out));
}

canonical_original_code:
void queue_init(struct _queue_t *q){
    if (!q)
        return;
    q->size = 0;
    stack_init(&(q->in));
    stack_init(&(q->out));
}

variable_types: struct _queue_t { struct _stack { void **items; int size; int capacity; } in; int size; } *

return_type: void

user_defined_types: struct _queue_t { struct _stack in; int size; }


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

if ( a1 )
result = *(_DWORD *)(a1 + 32) == 0;
else
result = 1LL;
return result;
}

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

if ( a1 )
result = *(_DWORD *)(a1 + 32) == 0;
else
result = 1LL;
return result;
}

original_code:
int queue_empty(queue_t *q){
    if (!q)
        return 1;
    return (q->size == 0);
}

canonical_original_code:
int queue_empty(struct _queue_t *q){
    if (!q)
        return 1;
    return (q->size == 0);
}

user_defined_types: struct _stack { void **items; int size; int capacity; }


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

if ( a1 )
result = *(unsigned int *)(a1 + 32);
else
result = 0LL;
return result;
}

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

if ( a1 )
result = *(unsigned int *)(a1 + 32);
else
result = 0LL;
return result;
}

original_code:
int queue_size(queue_t *q){
    if (!q)
        return 0;
    return q->size;
}

canonical_original_code:
int queue_size(struct _queue_t *q){
    if (!q)
        return 0;
    return q->size;
}


decompiled_code:
__int64 __fastcall queue_front(__int64 a1)
{
__int64 v1; // r13
int v2; // ebp
int i; // ebx
__int64 v4; // rax

if ( !a1 )
return 0LL;
v1 = a1 + 16;
LABEL_3:
if ( !*(_DWORD *)(a1 + 32) )
return 0LL;
while ( (int)stack_size(v1) <= 0 )
{
v2 = stack_size(a1);
if ( v2 <= 0 )
goto LABEL_3;
for ( i = 0; i != v2; ++i )
{
v4 = stack_pop(a1);
stack_push(v1, v4);
}
if ( !*(_DWORD *)(a1 + 32) )
return 0LL;
}
return stack_peek(v1);
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1)
{
__int64 v1; // r13
int v2; // ebp
int i; // ebx
__int64 v4; // rax

if ( !a1 )
return 0LL;
v1 = a1 + 16;
LABEL_3:
if ( !*(_DWORD *)(a1 + 32) )
return 0LL;
while ( (int)func21(v1) <= 0 )
{
v2 = func21(a1);
if ( v2 <= 0 )
goto LABEL_3;
for ( i = 0; i != v2; ++i )
{
v4 = func19(a1);
func18(v1, v4);
}
if ( !*(_DWORD *)(a1 + 32) )
return 0LL;
}
return func20(v1);
}

original_code:
void *queue_front(queue_t *q){
    if (!q || (q->size == 0))
        return ((void *)0);
    if (stack_size(&(q->out)) > 0)
        return stack_peek(&(q->out));
    int inSize = stack_size(&(q->in));
    int i;
    for (i = 0; i < inSize; i++)
        stack_push(&(q->out), stack_pop(&(q->in)));
    return queue_front(q);
}

canonical_original_code:
void *queue_front(struct _queue_t *q){
    if (!q || (q->size == 0))
        return ((void *)0);
    if (stack_size(&(q->out)) > 0)
        return stack_peek(&(q->out));
    int inSize = stack_size(&(q->in));
    int i;
    for (i = 0; i < inSize; i++)
        stack_push(&(q->out), stack_pop(&(q->in)));
    return queue_front(q);
}

variable_types: inSize int

return_type: void *


decompiled_code:
__int64 __fastcall queue_back(__int64 a1)
{
int v1; // ebx
int v2; // er12
int i; // er14
__int64 v4; // rax
__int64 v5; // r14
__int64 v6; // rax

if ( !a1 || !*(_DWORD *)(a1 + 32) )
return 0LL;
v1 = stack_size(a1);
if ( v1 )
return stack_peek(a1);
v2 = stack_size(a1 + 16) - 1;
if ( v2 <= 0 )
{
a1 += 16LL;
return stack_peek(a1);
}
for ( i = 0; i != v2; ++i )
{
v4 = stack_pop(a1 + 16);
stack_push(a1, v4);
}
v5 = stack_peek(a1 + 16);
do
{
++v1;
v6 = stack_pop(a1);
stack_push(a1 + 16, v6);
}
while ( v1 != v2 );
return v5;
}

original_code:
void *queue_back(queue_t *q){
    if (!q || (q->size == 0))
        return ((void *)0);
    if (stack_size(&(q->in)))
        return stack_peek(&(q->in));
    int outSize = stack_size(&(q->out));
    int i;
    for (i = 0; i < (outSize - 1); i++)
        stack_push(&(q->in), stack_pop(&(q->out)));
    void *item = stack_peek(&(q->out));
    for (i = 0; i < (outSize - 1); i++)
        stack_push(&(q->out), stack_pop(&(q->in)));
    return item;
}

canonical_original_code:
void *queue_back(struct _queue_t *q){
    if (!q || (q->size == 0))
        return ((void *)0);
    if (stack_size(&(q->in)))
        return stack_peek(&(q->in));
    int outSize = stack_size(&(q->out));
    int i;
    for (i = 0; i < (outSize - 1); i++)
        stack_push(&(q->in), stack_pop(&(q->out)));
    void *item = stack_peek(&(q->out));
    for (i = 0; i < (outSize - 1); i++)
        stack_push(&(q->out), stack_pop(&(q->in)));
    return item;
}

variable_types: outSize int

variable_types:
item
void *


decompiled_code:
__int64 __fastcall queue_enqueue(__int64 a1, __int64 a2)
{
__int64 result; // rax

if ( a1 )
{
result = stack_push(a1, a2);
++*(_DWORD *)(a1 + 32);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func12(__int64 a1, __int64 a2)
{
__int64 result; // rax

if ( a1 )
{
result = func18(a1, a2);
++*(_DWORD *)(a1 + 32);
}
return result;
}

original_code:
void queue_enqueue(queue_t *q, void *item){
    if (!q)
        return;
    stack_push(&(q->in), item);
    (q->size)++;
}

canonical_original_code:
void queue_enqueue(struct _queue_t *q, void *item){
    if (!q)
        return;
    stack_push(&(q->in), item);
    (q->size)++;
}


decompiled_code:
__int64 __fastcall queue_dequeue(__int64 a1)
{
__int64 v1; // r13
int v2; // ebp
int i; // ebx
__int64 v4; // rax

if ( !a1 )
return 0LL;
v1 = a1 + 16;
LABEL_3:
if ( !*(_DWORD *)(a1 + 32) )
return 0LL;
while ( (int)stack_size(v1) <= 0 )
{
v2 = stack_size(a1);
if ( v2 <= 0 )
goto LABEL_3;
for ( i = 0; i != v2; ++i )
{
v4 = stack_pop(a1);
stack_push(v1, v4);
}
if ( !*(_DWORD *)(a1 + 32) )
return 0LL;
}
--*(_DWORD *)(a1 + 32);
return stack_pop(v1);
}

original_code:
void *queue_dequeue(queue_t *q){
    if (!q || (q->size == 0))
        return ((void *)0);
    if (stack_size(&(q->out)) > 0){
        (q->size)--;
        return stack_pop(&(q->out));
    }
    int inSize = stack_size(&(q->in));
    int i;
    for (i = 0; i < inSize; i++)
        stack_push(&(q->out), stack_pop(&(q->in)));
    return queue_dequeue(q);
}

canonical_original_code:
void *queue_dequeue(struct _queue_t *q){
    if (!q || (q->size == 0))
        return ((void *)0);
    if (stack_size(&(q->out)) > 0){
        (q->size)--;
        return stack_pop(&(q->out));
    }
    int inSize = stack_size(&(q->in));
    int i;
    for (i = 0; i < inSize; i++)
        stack_push(&(q->out), stack_pop(&(q->in)));
    return queue_dequeue(q);
}


decompiled_code:
void __fastcall queue_print(__int64 a1)
{
int v1; // er12
const char *v2; // rbp

if ( a1 )
{
if ( *(_DWORD *)(a1 + 32) )
{
printf("front--> ");
if ( *(int *)(a1 + 32) > 0 )
{
v1 = 0;
do
{
v2 = (const char *)queue_dequeue(a1);
if ( *(_DWORD *)(a1 + 32) == v1 )
printf("(%s) <--back\n", v2);
else
printf("(%s), ", v2);
++v1;
queue_enqueue(a1, (__int64)v2);
}
while ( *(_DWORD *)(a1 + 32) > v1 );
}
}
}
}

original_code:
void queue_print(queue_t *q){
    if (!q || (q->size == 0))
        return;
    printf("front--> ");
    int i;
    for (i = 0; i < q->size; i++){
        void *tmp = queue_dequeue(q);
        if (i == q->size)
            printf("(%s) <--back\n", (char *)tmp);
        else
            printf("(%s), ", (char *)tmp);
        queue_enqueue(q, tmp);
    }
}

canonical_original_code:
void queue_print(struct _queue_t *q){
    if (!q || (q->size == 0))
        return;
    printf("front--> ");
    int i;
    for (i = 0; i < q->size; i++){
        void *tmp = queue_dequeue(q);
        if (i == q->size)
            printf("(%s) <--back\n", (char *)tmp);
        else
            printf("(%s), ", (char *)tmp);
        queue_enqueue(q, tmp);
    }
}

variable_types:
tmp
void *


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

if ( a1 )
{
((void (*)(void))stack_destroy)();
result = stack_destroy(a1 + 16);
}
return result;
}

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

if ( a1 )
{
((void (*)(void))stack_destroy)();
result = func22(a1 + 16);
}
return result;
}

original_code:
void queue_destroy(queue_t *q){
    if (!q)
        return;
    stack_destroy(&(q->in));
    stack_destroy(&(q->out));
}

canonical_original_code:
void queue_destroy(struct _queue_t *q){
    if (!q)
        return;
    stack_destroy(&(q->in));
    stack_destroy(&(q->out));
}


decompiled_code:
void __fastcall stack_init(void **a1)
{
if ( a1 )
{
a1[1] = (void *)0x1000000000LL;
*a1 = malloc(0x80uLL);
}
}

original_code:
void stack_init(stack* s){
    if(s == ((void *)0)) return;
    s->size = 0;
    s->capacity = 16;
    s->items = malloc(s->capacity * sizeof(void*));
}

canonical_original_code:
void stack_init(struct _stack *s){
    if(s == ((void *)0)) return;
    s->size = 0;
    s->capacity = 16;
    s->items = malloc(s->capacity * sizeof(void *));
}

variable_types: struct _stack { void **items; int size; int capacity; } *


decompiled_code:
void *__fastcall stack_resize(__int64 a1)
{
int v1; // eax
void *result; // rax

v1 = *(_DWORD *)(a1 + 12);
*(_DWORD *)(a1 + 12) = 2 * v1;
result = realloc(*(void **)a1, 16LL * v1);
*(_QWORD *)a1 = result;
return result;
}

canonical_decompiled_code:
void *__fastcall func17(__int64 a1)
{
int v1; // eax
void *result; // rax

v1 = *(_DWORD *)(a1 + 12);
*(_DWORD *)(a1 + 12) = 2 * v1;
result = realloc(*(void **)a1, 16LL * v1);
*(_QWORD *)a1 = result;
return result;
}

original_code:
void stack_resize(stack* s){
    s->capacity *= 2;
    s->items = realloc(s->items, s->capacity * sizeof(void*));
}

canonical_original_code:
void stack_resize(struct _stack *s){
    s->capacity *= 2;
    s->items = realloc(s->items, s->capacity * sizeof(void *));
}


decompiled_code:
__int64 __fastcall stack_push(__int64 a1, __int64 a2)
{
int v2; // eax
__int64 v3; // rcx
__int64 result; // rax

v2 = *(_DWORD *)(a1 + 8);
if ( v2 == *(_DWORD *)(a1 + 12) )
{
stack_resize(a1);
v2 = *(_DWORD *)(a1 + 8);
}
v3 = v2;
result = (unsigned int)(v2 + 1);
*(_QWORD *)(*(_QWORD *)a1 + 8 * v3) = a2;
*(_DWORD *)(a1 + 8) = result;
return result;
}

original_code:
void stack_push(stack* s, void* ptr){
    if(s->size == s->capacity) stack_resize(s);
    int top_index = s->size;
    s->items[top_index] = ptr;
    s->size++;
}

canonical_original_code:
void stack_push(struct _stack *s, void *ptr){
    if(s->size == s->capacity) stack_resize(s);
    int top_index = s->size;
    s->items[top_index] = ptr;
    s->size++;
}

variable_types:
ptr
void *


original_code:
void* stack_pop(stack* s){
    if(s->size == 0) return ((void *)0);
    int top_index = s->size - 1;
    void* top_item = s->items[top_index];
    s->items[top_index] = ((void *)0);
    s->size--;
    return top_item;
}

canonical_original_code:
void *stack_pop(struct _stack *s){
    if(s->size == 0) return ((void *)0);
    int top_index = s->size - 1;
    void *top_item = s->items[top_index];
    s->items[top_index] = ((void *)0);
    s->size--;
    return top_item;
}


decompiled_code:
__int64 __fastcall stack_peek(__int64 a1)
{
int v1; // eax
__int64 result; // rax

v1 = *(_DWORD *)(a1 + 8);
if ( v1 )
result = *(_QWORD *)(*(_QWORD *)a1 + 8LL * (v1 - 1));
else
result = 0LL;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func20(__int64 a1)
{
int v1; // eax
__int64 result; // rax

v1 = *(_DWORD *)(a1 + 8);
if ( v1 )
result = *(_QWORD *)(*(_QWORD *)a1 + 8LL * (v1 - 1));
else
result = 0LL;
return result;
}

original_code:
void* stack_peek(stack* s){
    if(s->size == 0) return ((void *)0);
    int top_index = s->size - 1;
    void* top_item = s->items[top_index];
    return top_item;
}

canonical_original_code:
void *stack_peek(struct _stack *s){
    if(s->size == 0) return ((void *)0);
    int top_index = s->size - 1;
    void *top_item = s->items[top_index];
    return top_item;
}


decompiled_code:
__int64 __fastcall stack_size(__int64 a1)
{
return *(unsigned int *)(a1 + 8);
}

canonical_decompiled_code:
__int64 __fastcall func21(__int64 a1)
{
return *(unsigned int *)(a1 + 8);
}

original_code:
int stack_size(stack* s){
    return s->size;
}

canonical_original_code:
int stack_size(struct _stack *s){
    return s->size;
}


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

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

original_code:
void stack_destroy(stack* s){
    free(s->items);
}

canonical_original_code:
void stack_destroy(struct _stack *s){
    free(s->items);
}


decompiled_code:
void __fastcall dsjsets_init(__int64 a1)
{
if ( a1 )
{
*(_QWORD *)a1 = 0LL;
*(_DWORD *)(a1 + 8) = 0;
}
}

original_code:
void dsjsets_init(dsjsets *d){
    if (!d)
        return;
    d->dsets = ((void *)0);
    d->size = 0;
}

canonical_original_code:
void dsjsets_init(struct _dsjsets *d){
    if (!d)
        return;
    d->dsets = ((void *)0);
    d->size = 0;
}

variable_types: struct _dsjsets { int *dsets; int size; } *


original_code:
void dsjsets_addelems(dsjsets *d, int n){
    if (!d || (n <= 0))
        return;
    if (!(d->dsets)){
        d->dsets = (int *)malloc(n*sizeof(int));
        int i;
        for (i = 0; i < n; i++)
            d->dsets[i] = -1;
        d->size = n;
        return;
    }
    d->dsets = (int *)realloc(d->dsets, (n + d->size)*sizeof(int));
    int i;
    for (i = n; i < (d->size + n); i++)
        d->dsets[i] = -1;
    d->size += n;
}

canonical_original_code:
void dsjsets_addelems(struct _dsjsets *d, int n){
    if (!d || (n <= 0))
        return;
    if (!(d->dsets)){
        d->dsets = (int *)malloc(n*sizeof(int));
        int i;
        for (i = 0; i < n; i++)
            d->dsets[i] = -1;
        d->size = n;
        return;
    }
    d->dsets = (int *)realloc(d->dsets, (n + d->size)*sizeof(int));
    int i;
    for (i = n; i < (d->size + n); i++)
        d->dsets[i] = -1;
    d->size += n;
}

user_defined_types: struct _dsjsets { int *dsets; int size; }


decompiled_code:
__int64 __fastcall dsjsets_find(__int64 *a1, int a2)
{
__int64 result; // rax
__int64 v3; // rdx
__int64 v4; // rbp
__int64 v5; // rsi

if ( !a1 )
return 0xFFFFFFFFLL;
result = (unsigned int)a2;
v3 = *a1;
if ( a2 < 0 || !v3 || *((_DWORD *)a1 + 2) <= a2 )
return 0xFFFFFFFFLL;
v4 = a2;
v5 = *(unsigned int *)(v3 + 4LL * a2);
if ( (int)v5 >= 0 )
{
result = dsjsets_find(a1, v5);
*(_DWORD *)(*a1 + 4 * v4) = result;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 *a1, int a2)
{
__int64 result; // rax
__int64 v3; // rdx
__int64 v4; // rbp
__int64 v5; // rsi

if ( !a1 )
return 0xFFFFFFFFLL;
result = (unsigned int)a2;
v3 = *a1;
if ( a2 < 0 || !v3 || *((_DWORD *)a1 + 2) <= a2 )
return 0xFFFFFFFFLL;
v4 = a2;
v5 = *(unsigned int *)(v3 + 4LL * a2);
if ( (int)v5 >= 0 )
{
result = func9(a1, v5);
*(_DWORD *)(*a1 + 4 * v4) = result;
}
return result;
}

original_code:
int dsjsets_find(dsjsets *d, int n){
    if (!d || !(d->dsets) || n < 0 || n >= d->size)
        return -1;
    if (d->dsets[n] < 0)
        return n;
    int rootSet = dsjsets_find(d, d->dsets[n]);
    d->dsets[n] = rootSet;
    return rootSet;
}

canonical_original_code:
int dsjsets_find(struct _dsjsets *d, int n){
    if (!d || !(d->dsets) || n < 0 || n >= d->size)
        return -1;
    if (d->dsets[n] < 0)
        return n;
    int rootSet = dsjsets_find(d, d->dsets[n]);
    d->dsets[n] = rootSet;
    return rootSet;
}

variable_types: rootSet int


original_code:
void dsjsets_union(dsjsets *d, int a, int b){
    if (!d || !(d->dsets) || a < 0 || a >= d->size
        || b < 0 || b >= d->size)
        return;
    int aRoot = dsjsets_find(d, a);
    int bRoot = dsjsets_find(d, b);
    int aSize = d->dsets[aRoot];
    int bSize = d->dsets[bRoot];
    if (bSize < aSize){
        d->dsets[aRoot] = bRoot;
        d->dsets[bRoot] += aSize;
        return;
    }
    d->dsets[bRoot] = aRoot;
    d->dsets[aRoot] += bSize;
}

canonical_original_code:
void dsjsets_union(struct _dsjsets *d, int a, int b){
    if (!d || !(d->dsets) || a < 0 || a >= d->size
        || b < 0 || b >= d->size)
        return;
    int aRoot = dsjsets_find(d, a);
    int bRoot = dsjsets_find(d, b);
    int aSize = d->dsets[aRoot];
    int bSize = d->dsets[bRoot];
    if (bSize < aSize){
        d->dsets[aRoot] = bRoot;
        d->dsets[bRoot] += aSize;
        return;
    }
    d->dsets[bRoot] = aRoot;
    d->dsets[aRoot] += bSize;
}

variable_types: a int

variable_types: b int

variable_types: aRoot int

variable_types: bRoot int

variable_types: aSize int

variable_types: bSize int


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

if ( a1 )
result = *(unsigned int *)(a1 + 8);
else
result = 0LL;
return result;
}

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

if ( a1 )
result = *(unsigned int *)(a1 + 8);
else
result = 0LL;
return result;
}

original_code:
int dsjsets_size(dsjsets *d){
    if (!d)
        return 0;
    return d->size;
}

canonical_original_code:
int dsjsets_size(struct _dsjsets *d){
    if (!d)
        return 0;
    return d->size;
}


original_code:
void dsjsets_print(dsjsets *d){
    if (!d || !(d->dsets) || !(d->size))
        return;
    int i;
    for (i = 0; i < d->size; i++){
        if (i != (d->size -1))
            printf("(set %d: %d) ", i, d->dsets[i]);
        else
            printf("(set %d: %d)\n", i, d->dsets[i]);
    }
}

canonical_original_code:
void dsjsets_print(struct _dsjsets *d){
    if (!d || !(d->dsets) || !(d->size))
        return;
    int i;
    for (i = 0; i < d->size; i++){
        if (i != (d->size -1))
            printf("(set %d: %d) ", i, d->dsets[i]);
        else
            printf("(set %d: %d)\n", i, d->dsets[i]);
    }
}

variable_types: i int


decompiled_code:
void __fastcall dsjsets_destroy(__int64 a1)
{
void *v2; // rdi

if ( a1 )
{
v2 = *(void **)a1;
if ( v2 )
{
free(v2);
*(_QWORD *)a1 = 0LL;
*(_DWORD *)(a1 + 8) = 0;
}
}
}

original_code:
void dsjsets_destroy(dsjsets *d){
    if (!d || !(d->dsets))
        return;
    free(d->dsets);
    d->dsets = ((void *)0);
    d->size = 0;
}

canonical_original_code:
void dsjsets_destroy(struct _dsjsets *d){
    if (!d || !(d->dsets))
        return;
    free(d->dsets);
    d->dsets = ((void *)0);
    d->size = 0;
}


SuperFastHash

original_code:
uint32_t SuperFastHash (const char * data, int len) {
    uint32_t hash = len, tmp;
    int rem;
    if (len <= 0 || data == ((void *)0)) return 0;
    rem = len & 3;
    len >>= 2;
    for (;len > 0; len--){
        hash += ((((uint32_t)(((const uint8_t *)(data))[1])) << 8) +(uint32_t)(((const uint8_t *)(data))[0]) );
        tmp = (((((uint32_t)(((const uint8_t *)(data+2))[1])) << 8) +(uint32_t)(((const uint8_t *)(data+2))[0]) ) << 11) ^ hash;
        hash = (hash << 16) ^ tmp;
        data += 2*sizeof (uint16_t);
        hash += hash >> 11;
    }
    switch (rem){
        case 3: hash += ((((uint32_t)(((const uint8_t *)(data))[1])) << 8) +(uint32_t)(((const uint8_t *)(data))[0]) );
                hash ^= hash << 16;
                hash ^= ((signed char)data[sizeof (uint16_t)]) << 18;
                hash += hash >> 11;
                break;
        case 2: hash += ((((uint32_t)(((const uint8_t *)(data))[1])) << 8) +(uint32_t)(((const uint8_t *)(data))[0]) );
                hash ^= hash << 11;
                hash += hash >> 17;
                break;
        case 1: hash += (signed char)*data;
                hash ^= hash << 10;
                hash += hash >> 1;
    }
    hash ^= hash << 3;
    hash += hash >> 5;
    hash ^= hash << 4;
    hash += hash >> 17;
    hash ^= hash << 25;
    hash += hash >> 6;
    return hash;
}

canonical_original_code:
unsigned int SuperFastHash(char *data, int len) {
    unsigned int hash = len; unsigned int tmp;
    int rem;
    if (len <= 0 || data == ((void *)0)) return 0;
    rem = len & 3;
    len >>= 2;
    for (;len > 0; len--){
        hash += ((((unsigned int)(((unsigned char *)(data))[1])) << 8) +(unsigned int)(((unsigned char *)(data))[0]) );
        tmp = (((((unsigned int)(((unsigned char *)(data+2))[1])) << 8) +(unsigned int)(((unsigned char *)(data+2))[0]) ) << 11) ^ hash;
        hash = (hash << 16) ^ tmp;
        data += 2*sizeof (unsigned short);
        hash += hash >> 11;
    }
    switch (rem){
        case 3: hash += ((((unsigned int)(((unsigned char *)(data))[1])) << 8) +(unsigned int)(((unsigned char *)(data))[0]) );
                hash ^= hash << 16;
                hash ^= ((char)data[sizeof (unsigned short)]) << 18;
                hash += hash >> 11;
                break;
        case 2: hash += ((((unsigned int)(((unsigned char *)(data))[1])) << 8) +(unsigned int)(((unsigned char *)(data))[0]) );
                hash ^= hash << 11;
                hash += hash >> 17;
                break;
        case 1: hash += (char)*data;
                hash ^= hash << 10;
                hash += hash >> 1;
    }
    hash ^= hash << 3;
    hash += hash >> 5;
    hash ^= hash << 4;
    hash += hash >> 17;
    hash ^= hash << 25;
    hash += hash >> 6;
    return hash;
}

variable_types:
data
char *

variable_types: len int

variable_types:
hash
unsigned int

variable_types:
tmp
unsigned int

variable_types: rem int

return_type: unsigned int


decompiled_code:
void __fastcall hashtable_init(_QWORD *a1)
{
void *v1; // rax

if ( a1 )
{
v1 = calloc(0x100uLL, 1uLL);
*a1 = 1060320051LL;
a1[2] = v1;
a1[1] = 32LL;
}
}

original_code:
void hashtable_init(hashtable_t *h){
    if (!h)
        return;
    h->MAX_ALPHA = .7;
    h->alpha = 0;
    h->capacity = 32;
    h->table = (node_t **)malloc((h->capacity)*sizeof(node_t *));
    int i;
    for (i = 0; i < h->capacity; i++)
        h->table[i] = ((void *)0);
    h->numItems = 0;
}

canonical_original_code:
void hashtable_init(struct _hashtable_t *h){
    if (!h)
        return;
    h->MAX_ALPHA = .7;
    h->alpha = 0;
    h->capacity = 32;
    h->table = (struct _node_t **)malloc((h->capacity)*sizeof(struct _node_t *));
    int i;
    for (i = 0; i < h->capacity; i++)
        h->table[i] = ((void *)0);
    h->numItems = 0;
}

variable_types: struct _hashtable_t { float MAX_ALPHA; float alpha; int capacity; int numItems; struct _node_t { char *key; void *value; struct _node_t *next; } **table; } *

user_defined_types: struct _hashtable_t { float MAX_ALPHA; float alpha; int capacity; int numItems; struct _node_t **table; }


original_code:
void hashtable_insert(hashtable_t *h, char *key, void *value){
    if (!h || !(h->table) || !key || !value)
        return;
    if (h->alpha >= h->MAX_ALPHA){
        int size = h->numItems;
        char *keys[size];
        void *values[size];
        int i;
        int j;
        j = 0;
        for (i = 0; i < h->capacity; i++){
            if (h->table[i]){
                node_t *stepper = h->table[i];
                while (stepper){
                    node_t *tmp = stepper->next;
                    keys[j] = stepper->key;
                    values[j] = stepper->value;
                    j++;
                    free(stepper);
                    stepper = tmp;
                }
                h->table[i] = ((void *)0);
            }
        }
        h->capacity *= 2;
        h->table = realloc(h->table, h->capacity*sizeof(node_t *));
        h->numItems = 0;
        h->alpha = 0;
        for (i = 0; i < h->capacity; i++)
            h->table[i] = ((void *)0);
        for (i = 0; i < size; i++)
            hashtable_insert(h, keys[i], values[i]);
    }
    unsigned int index = SuperFastHash(key, h->capacity) % h->capacity;
    if (!h->table[index]){
        h->table[index] = (node_t *)malloc(sizeof(node_t));
        (h->table[index])->key = key;
        (h->table[index])->value = value;
        (h->table[index])->next = ((void *)0);
    } else {
        node_t *tmp = (node_t *)malloc(sizeof(node_t));
        tmp->value = value;
        tmp->key = key;
        tmp->next = h->table[index];
        h->table[index] = tmp;
    }
    (h->numItems)++;
    h->alpha = (float)h->numItems/(h->capacity);
}

canonical_original_code:
void hashtable_insert(struct _hashtable_t *h, char *key, void *value){
    if (!h || !(h->table) || !key || !value)
        return;
    if (h->alpha >= h->MAX_ALPHA){
        int size = h->numItems;
        char *keys[-1];
        void *values[-1];
        int i;
        int j;
        j = 0;
        for (i = 0; i < h->capacity; i++){
            if (h->table[i]){
                struct _node_t *stepper = h->table[i];
                while (stepper){
                    struct _node_t *tmp = stepper->next;
                    keys[j] = stepper->key;
                    values[j] = stepper->value;
                    j++;
                    free(stepper);
                    stepper = tmp;
                }
                h->table[i] = ((void *)0);
            }
        }
        h->capacity *= 2;
        h->table = realloc(h->table, h->capacity*sizeof(struct _node_t *));
        h->numItems = 0;
        h->alpha = 0;
        for (i = 0; i < h->capacity; i++)
            h->table[i] = ((void *)0);
        for (i = 0; i < size; i++)
            hashtable_insert(h, keys[i], values[i]);
    }
    unsigned int index = SuperFastHash(key, h->capacity) % h->capacity;
    if (!h->table[index]){
        h->table[index] = (struct _node_t *)malloc(sizeof(node_t));
        (h->table[index])->key = key;
        (h->table[index])->value = value;
        (h->table[index])->next = ((void *)0);
    } else {
        struct _node_t *tmp = (node_t *)malloc(sizeof(node_t));
        tmp->value = value;
        tmp->key = key;
        tmp->next = h->table[index];
        h->table[index] = tmp;
    }
    (h->numItems)++;
    h->alpha = (float)h->numItems/(h->capacity);
}

variable_types:
key
char *

variable_types:
value
void *

variable_types: size int

variable_types:
keys
char *[-1]

variable_types:
values
void *[-1]

variable_types: j int

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

variable_types:
index
unsigned int


decompiled_code:
__int64 __fastcall hashtable_find(__int64 a1, char *a2)
{
unsigned int v2; // eax
unsigned int v3; // er9
__int64 v4; // r10
__int64 v5; // r12

if ( !a1 || !*(_QWORD *)(a1 + 16) || !a2 )
return 0LL;
v2 = SuperFastHash(a2, *(_DWORD *)(a1 + 8));
v5 = *(_QWORD *)(v4 + 8LL * (v2 % v3));
if ( v5 )
{
while ( strcmp(a2, *(const char **)v5) )
{
v5 = *(_QWORD *)(v5 + 16);
if ( !v5 )
return v5;
}
v5 = *(_QWORD *)(v5 + 8);
}
return v5;
}

original_code:
void *hashtable_find(hashtable_t *h, char *key){
    if(!h || !(h->table) | !key)
        return ((void *)0);
    unsigned int index = SuperFastHash(key, h->capacity) % h->capacity;
    node_t *stepper = h->table[index];
    while (stepper){
        if (!strcmp(key, stepper->key))
            return stepper->value;
        stepper = stepper->next;
    }
    return ((void *)0);
}

canonical_original_code:
void *hashtable_find(struct _hashtable_t *h, char *key){
    if(!h || !(h->table) | !key)
        return ((void *)0);
    unsigned int index = SuperFastHash(key, h->capacity) % h->capacity;
    struct _node_t *stepper = h->table[index];
    while (stepper){
        if (!strcmp(key, stepper->key))
            return stepper->value;
        stepper = stepper->next;
    }
    return ((void *)0);
}

user_defined_types: struct _node_t { char *key; void *value; struct _node_t *next; }


decompiled_code:
void __fastcall hashtable_remove(__int64 a1, char *a2)
{
signed int v2; // er14
unsigned int v3; // eax
__int64 v4; // r9
const char ***v5; // r13
const char **v6; // rbp
int v7; // eax
const char **v8; // r13

if ( a1 && *(_QWORD *)(a1 + 16) && a2 )
{
v2 = *(_DWORD *)(a1 + 8);
v3 = SuperFastHash(a2, v2);
v5 = (const char ***)(v4 + 8LL * (v3 % v2));
v6 = *v5;
if ( !strcmp(a2, **v5) )
{
*v5 = (const char **)v6[2];
}
else
{
do
{
v8 = v6;
v6 = (const char **)v6[2];
if ( !v6 )
{
v7 = *(_DWORD *)(a1 + 12);
goto LABEL_10;
}
}
while ( strcmp(*v6, a2) );
v8[2] = v6[2];
}
free(v6);
v2 = *(_DWORD *)(a1 + 8);
v7 = *(_DWORD *)(a1 + 12) - 1;
*(_DWORD *)(a1 + 12) = v7;
LABEL_10:
*(float *)(a1 + 4) = (float)v7 / (float)v2;
}
}

original_code:
void hashtable_remove(hashtable_t *h, char *key){
    if (!h || !(h->table) || !key)
        return;
    unsigned int index = SuperFastHash(key, h->capacity) % h->capacity;
    node_t *stepper = h->table[index];
    if (!strcmp(key, stepper->key)){
        h->table[index] = stepper->next;
        free(stepper);
        (h->numItems)--;
    } else {
        while(stepper->next){
            if (!strcmp(stepper->next->key, key)){
                node_t *tmp = stepper->next;
                stepper->next = stepper->next->next;
                free(tmp);
                (h->numItems)--;
                break;
            }
            stepper = stepper->next;
        }
    }
    h->alpha = (float)h->numItems/(h->capacity);
}

canonical_original_code:
void hashtable_remove(struct _hashtable_t *h, char *key){
    if (!h || !(h->table) || !key)
        return;
    unsigned int index = SuperFastHash(key, h->capacity) % h->capacity;
    struct _node_t *stepper = h->table[index];
    if (!strcmp(key, stepper->key)){
        h->table[index] = stepper->next;
        free(stepper);
        (h->numItems)--;
    } else {
        while(stepper->next){
            if (!strcmp(stepper->next->key, key)){
                struct _node_t *tmp = stepper->next;
                stepper->next = stepper->next->next;
                free(tmp);
                (h->numItems)--;
                break;
            }
            stepper = stepper->next;
        }
    }
    h->alpha = (float)h->numItems/(h->capacity);
}


original_code:
void hashtable_destroy(hashtable_t *h){
    if (!h || !(h->table))
        return;
    node_t *stepper;
    int i;
    for (i = 0; i < h->capacity; i++){
        stepper = h->table[i];
        while(stepper){
            node_t *tmp = stepper->next;
            free(stepper);
            stepper = tmp;
        }
        h->table[i] = ((void *)0);
    }
    free(h->table);
    h->table = ((void *)0);
    h->alpha = 0;
    h->numItems = 0;
    h->capacity = 0;
}

canonical_original_code:
void hashtable_destroy(struct _hashtable_t *h){
    if (!h || !(h->table))
        return;
    struct _node_t *stepper;
    int i;
    for (i = 0; i < h->capacity; i++){
        stepper = h->table[i];
        while(stepper){
            struct _node_t *tmp = stepper->next;
            free(stepper);
            stepper = tmp;
        }
        h->table[i] = ((void *)0);
    }
    free(h->table);
    h->table = ((void *)0);
    h->alpha = 0;
    h->numItems = 0;
    h->capacity = 0;
}


decompiled_code:
void __fastcall hashtable_clear(__int64 a1)
{
if ( a1 && *(_QWORD *)(a1 + 16) )
{
if ( *(_DWORD *)(a1 + 12) )
{
hashtable_destroy(a1);
hashtable_init((_QWORD *)a1);
}
}
}

original_code:
void hashtable_clear(hashtable_t *h){
    if (!h || !(h->table) || !(h->numItems))
        return;
    hashtable_destroy(h);
    hashtable_init(h);
}

canonical_original_code:
void hashtable_clear(struct _hashtable_t *h){
    if (!h || !(h->table) || !(h->numItems))
        return;
    hashtable_destroy(h);
    hashtable_init(h);
}


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

if ( a1 )
result = *(unsigned int *)(a1 + 8);
else
result = 0LL;
return result;
}

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

if ( a1 )
result = *(unsigned int *)(a1 + 8);
else
result = 0LL;
return result;
}

original_code:
int hashtable_size(hashtable_t *h){
    if (!h)
        return 0;
    return h->capacity;
}

canonical_original_code:
int hashtable_size(struct _hashtable_t *h){
    if (!h)
        return 0;
    return h->capacity;
}


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

if ( a1 )
result = *(unsigned int *)(a1 + 12);
else
result = 0LL;
return result;
}

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

if ( a1 )
result = *(unsigned int *)(a1 + 12);
else
result = 0LL;
return result;
}

original_code:
int hashtable_numelems(hashtable_t *h){
    if (!h)
        return 0;
    return h->numItems;
}

canonical_original_code:
int hashtable_numelems(struct _hashtable_t *h){
    if (!h)
        return 0;
    return h->numItems;
}


decompiled_code:
__m64 __fastcall hashtable_loadfactor(_DWORD *a1)
{
__m64 result; // xmm0_8

if ( !a1 )
return 0LL;
*((_DWORD *)&result + 1) = 0;
*(float *)&result.m64_u64 = (float)(int)a1[3] / (float)(int)a1[2];
a1[1] = result.m64_i32[0];
return result;
}

canonical_decompiled_code:
__m64 __fastcall func16(_DWORD *a1)
{
__m64 result; // xmm0_8

if ( !a1 )
return 0LL;
*((_DWORD *)&result + 1) = 0;
*(float *)&result.m64_u64 = (float)(int)a1[3] / (float)(int)a1[2];
a1[1] = result.m64_i32[0];
return result;
}

original_code:
float hashtable_loadfactor(hashtable_t *h){
    if (!h)
        return 0;
    h->alpha = (float)h->numItems/(h->capacity);
    return h->alpha;
}

canonical_original_code:
float hashtable_loadfactor(struct _hashtable_t *h){
    if (!h)
        return 0;
    h->alpha = (float)h->numItems/(h->capacity);
    return h->alpha;
}

return_type: float


compare

decompiled_code:
_BOOL8 __fastcall compare(_DWORD *a1, _DWORD *a2)
{
return *a1 < *a2;
}

canonical_decompiled_code:
_BOOL8 __fastcall func7(_DWORD *a1, _DWORD *a2)
{
return *a1 < *a2;
}

original_code:
int compare(const void* a, const void* b){
    int* A = (int*)a;
    int* B = (int*)b;
    return *A < *B;
}

canonical_original_code:
int compare(void *a, void *b){
    int *A = (int*)a;
    int *B = (int*)b;
    return *A < *B;
}

variable_types:
a
void *

variable_types:
b
void *

variable_types:
A
int *

variable_types:
B
int *


decompiled_code:
__int64 __fastcall swap_positions(__int64 a1, int a2, int a3)
{
__int64 v3; // rcx
__int64 *v4; // rax
__int64 v5; // rsi
__int64 result; // rax

v3 = *(_QWORD *)(a1 + 8);
v4 = (__int64 *)(v3 + 8LL * a2);
v5 = *v4;
*v4 = *(_QWORD *)(v3 + 8LL * a3);
result = *(_QWORD *)(a1 + 8);
*(_QWORD *)(result + 8LL * a3) = v5;
return result;
}

original_code:
void swap_positions(heap* h, int pos1, int pos2){
    void* temp = h->items[pos1];
    h->items[pos1] = h->items[pos2];
    h->items[pos2] = temp;
}

canonical_original_code:
void swap_positions(struct _heap *h, int pos1, int pos2){
    void *temp = h->items[pos1];
    h->items[pos1] = h->items[pos2];
    h->items[pos2] = temp;
}

variable_types: struct _heap { int (*compare)(void *, void *); void **items; int size; int capacity; } *

variable_types:
temp
void *


decompiled_code:
__int64 __fastcall heapify_up(__int64 a1, int a2)
{
int v3; // edx
unsigned int v4; // ebx
__int64 result; // rax

while ( 1 )
{
v4 = (a2 - 1) / 2;
result = (*(__int64 (__fastcall **)(_QWORD, _QWORD))a1)(
*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL * a2),
*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL * v4));
if ( !(_DWORD)result )
break;
v3 = a2;
a2 = (a2 - 1) / 2;
swap_positions(a1, v4, v3);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, int a2)
{
int v3; // edx
unsigned int v4; // ebx
__int64 result; // rax

while ( 1 )
{
v4 = (a2 - 1) / 2;
result = (*(__int64 (__fastcall **)(_QWORD, _QWORD))a1)(
*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL * a2),
*(_QWORD *)(*(_QWORD *)(a1 + 8) + 8LL * v4));
if ( !(_DWORD)result )
break;
v3 = a2;
a2 = (a2 - 1) / 2;
func8(a1, v4, v3);
}
return result;
}

original_code:
void heapify_up(heap* h, int index){
    unsigned int parent_index = (index-1)/2;
    void* parent = h->items[parent_index];
    void* child = h->items[index];
    if(h->compare(child, parent)){
        swap_positions(h, parent_index, index);
        heapify_up(h, parent_index);
    }
}

canonical_original_code:
void heapify_up(struct _heap *h, int index){
    unsigned int parent_index = (index-1)/2;
    void *parent = h->items[parent_index];
    void *child = h->items[index];
    if(h->compare(child, parent)){
        swap_positions(h, parent_index, index);
        heapify_up(h, parent_index);
    }
}

variable_types: index int

variable_types:
parent
void *

variable_types:
child
void *

user_defined_types: struct _heap { int (*compare)(void *, void *); void **items; int size; int capacity; }


original_code:
void heapify_down(heap* h, int index){
    unsigned int left_index = 2*index + 1;
    unsigned int right_index = 2*index + 2;
    int has_left = left_index < h->size;
    int has_right = right_index < h->size;
    if(!has_left && !has_right)
        return;
    void* parent = h->items[index];
    void* left = h->items[left_index];
    void* right = h->items[right_index];
    if(has_left && h->compare(parent, left)
       && has_right && h->compare(parent, right)){
        return;
    }
    if(has_left && has_right){
        if(h->compare(left, right)){
            swap_positions(h, index, left_index);
            heapify_down(h, left_index);
        }
        else{
            swap_positions(h, index, right_index);
            heapify_down(h, right_index);
        }
    }
    else if(has_left){
        if(h->compare(left, parent)){
            swap_positions(h, index, left_index);
            heapify_down(h, left_index);
        }
    }
}

canonical_original_code:
void heapify_down(struct _heap *h, int index){
    unsigned int left_index = 2*index + 1;
    unsigned int right_index = 2*index + 2;
    int has_left = left_index < h->size;
    int has_right = right_index < h->size;
    if(!has_left && !has_right)
        return;
    void *parent = h->items[index];
    void *left = h->items[left_index];
    void *right = h->items[right_index];
    if(has_left && h->compare(parent, left)
       && has_right && h->compare(parent, right)){
        return;
    }
    if(has_left && has_right){
        if(h->compare(left, right)){
            swap_positions(h, index, left_index);
            heapify_down(h, left_index);
        }
        else{
            swap_positions(h, index, right_index);
            heapify_down(h, right_index);
        }
    }
    else if(has_left){
        if(h->compare(left, parent)){
            swap_positions(h, index, left_index);
            heapify_down(h, left_index);
        }
    }
}

variable_types:
left
void *

variable_types:
right
void *


decompiled_code:
void __fastcall build_heap(__int64 a1)
{
int v1; // ebx

v1 = *(_DWORD *)(a1 + 16) / 2;
if ( *(int *)(a1 + 16) >= -1 )
{
do
heapify_down(a1, v1);
while ( v1-- != 0 );
}
}

original_code:
void build_heap(heap* h){
    int i;
    for(i=h->size/2; i >= 0; i--){
        heapify_down(h, i);
    }
}

canonical_original_code:
void build_heap(struct _heap *h){
    int i;
    for(i=h->size/2; i >= 0; i--){
        heapify_down(h, i);
    }
}

variable_types: i int


original_code:
void heap_init_with_items(heap* h, int(*compare)(const void *, const void *), void** items, int item_count){
    h->compare = compare;
    h->size = item_count;
    h->capacity = 16;
    while(h->capacity < item_count) h->capacity*=2;
    if(items != ((void *)0)) {
        h->items = malloc( h->capacity * sizeof(void*));
        int i;
        for(i=0; i < item_count; i++){
            h->items[i] = items[i];
        }
        build_heap(h);
    }
}

canonical_original_code:
void heap_init_with_items(struct _heap *h, int (*compare)(void *, void *), void **items, int item_count){
    h->compare = compare;
    h->size = item_count;
    h->capacity = 16;
    while(h->capacity < item_count) h->capacity*=2;
    if(items != ((void *)0)) {
        h->items = malloc( h->capacity * sizeof(void *));
        int i;
        for(i=0; i < item_count; i++){
            h->items[i] = items[i];
        }
        build_heap(h);
    }
}

variable_types:
compare
int (*)(void *, void *)

variable_types:
items
void **


decompiled_code:
void *__fastcall heap_resize(__int64 a1)
{
int v1; // eax
void *result; // rax

v1 = *(_DWORD *)(a1 + 20);
*(_DWORD *)(a1 + 20) = 2 * v1;
result = realloc(*(void **)(a1 + 8), 16LL * v1);
*(_QWORD *)(a1 + 8) = result;
return result;
}

canonical_decompiled_code:
void *__fastcall func14(__int64 a1)
{
int v1; // eax
void *result; // rax

v1 = *(_DWORD *)(a1 + 20);
*(_DWORD *)(a1 + 20) = 2 * v1;
result = realloc(*(void **)(a1 + 8), 16LL * v1);
*(_QWORD *)(a1 + 8) = result;
return result;
}

original_code:
void heap_resize(heap* h){
    h->capacity *= 2;
    h->items = realloc(h->items, h->capacity * sizeof(void*));
}

canonical_original_code:
void heap_resize(struct _heap *h){
    h->capacity *= 2;
    h->items = realloc(h->items, h->capacity * sizeof(void *));
}


original_code:
void heap_insert(heap* h, void* item){
    if(h->size == h->capacity) heap_resize(h);
    h->size++;
    h->items[h->size-1] = item;
    heapify_up(h, h->size-1);
}

canonical_original_code:
void heap_insert(struct _heap *h, void *item){
    if(h->size == h->capacity) heap_resize(h);
    h->size++;
    h->items[h->size-1] = item;
    heapify_up(h, h->size-1);
}

variable_types:
item
void *


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

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

original_code:
void* heap_peek(heap* h){
    return h->items[0];
}

canonical_original_code:
void *heap_peek(struct _heap *h){
    return h->items[0];
}


original_code:
void* heap_remove(heap* h){
    if(h->size == 0) return ((void *)0);
    void* top = h->items[0];
    h->size--;
    if(h->size > 0){
        h->items[0] = h->items[h->size];
        heapify_down(h, 0);
    }
    return top;
}

canonical_original_code:
void *heap_remove(struct _heap *h){
    if(h->size == 0) return ((void *)0);
    void *top = h->items[0];
    h->size--;
    if(h->size > 0){
        h->items[0] = h->items[h->size];
        heapify_down(h, 0);
    }
    return top;
}

variable_types:
top
void *


decompiled_code:
__int64 __fastcall heap_size(__int64 a1)
{
return *(unsigned int *)(a1 + 16);
}

canonical_decompiled_code:
__int64 __fastcall func18(__int64 a1)
{
return *(unsigned int *)(a1 + 16);
}

original_code:
int heap_size(heap* h){
    return h->size;
}

canonical_original_code:
int heap_size(struct _heap *h){
    return h->size;
}


decompiled_code:
void __fastcall heap_destroy(__int64 a1)
{
free(*(void **)(a1 + 8));
}

canonical_decompiled_code:
void __fastcall func19(__int64 a1)
{
free(*(void **)(a1 + 8));
}

original_code:
void heap_destroy(heap* h){
    free(h->items);
}

canonical_original_code:
void heap_destroy(struct _heap *h){
    free(h->items);
}


original_code:
void heap_print(heap* h){
    int i;
    int nodes_for_level = 1;
    int node_at = 0;
    for(i=0; i < h->size; i++){
        printf("%d  ", *(int*)h->items[i]);
        node_at++;
        if(node_at == nodes_for_level){
            printf("\n");
            nodes_for_level *= 2;
            node_at = 0;
        }
    }
    if(node_at != 0) printf("\n");
    printf("\n");
}

canonical_original_code:
void heap_print(struct _heap *h){
    int i;
    int nodes_for_level = 1;
    int node_at = 0;
    for(i=0; i < h->size; i++){
        printf("%d  ", *(int *)h->items[i]);
        node_at++;
        if(node_at == nodes_for_level){
            printf("\n");
            nodes_for_level *= 2;
            node_at = 0;
        }
    }
    if(node_at != 0) printf("\n");
    printf("\n");
}


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbp
__int64 *v4; // rbx
_DWORD *v5; // rax
int v6; // edx
int v7; // ebp
unsigned int *v8; // rax
unsigned int *v9; // rax
__int64 *v10; // rbp
__int64 v11; // rsi
_BYTE v13[32]; // [rsp+0h] [rbp-78h] BYREF
__int64 v14[6]; // [rsp+20h] [rbp-58h]
int v15; // [rsp+50h] [rbp-28h]

v3 = 0LL;
v14[0] = 0xF00000014LL;
v14[1] = 0x160000000CLL;
v14[2] = 0xA0000001ELL;
v14[3] = 0x2A00000008LL;
v14[4] = 0x1300000032LL;
v14[5] = 1LL;
v15 = 45;
v4 = (__int64 *)malloc(0x68uLL);
puts("Building heap of size 13 \n");
do
{
v5 = malloc(4uLL);
v6 = *((_DWORD *)v14 + v3);
v4[v3++] = (__int64)v5;
*v5 = v6;
}
while ( v3 != 13 );
heap_init_with_items(v13, compare, v4, 13LL);
v7 = 4;
heap_print(v13);
do
{
v8 = (unsigned int *)heap_remove(v13);
printf("Removed %d\n", *v8);
--v7;
}
while ( v7 );
putchar(10);
heap_print(v13);
while ( (int)heap_size(v13) > 0 )
{
v9 = (unsigned int *)heap_remove(v13);
printf("Removed %d\n", *v9);
}
heap_print(v13);
v10 = v4 + 13;
do
{
v11 = *v4++;
heap_insert(v13, v11);
}
while ( v10 != v4 );
heap_print(v13);
heap_destroy(v13);
return 0;
}

original_code:
int main(){
    int numbers[] = {20, 15, 12, 22, 30, 10, 8, 42, 50 , 19, 1, 0, 45};
    void** items = malloc(13*sizeof(int*));
    printf("Building heap of size 13 \n\n");
    int i;
    for(i=0; i < 13; i++){
        items[i] = malloc(sizeof(int));
        *(int*)items[i] = numbers[i];
    }
    heap h;
    heap_init_with_items(&h, compare, items, 13);
    heap_print(&h);
    int* top;
    for(i=0; i<4; i++){
        top = heap_remove(&h);
        printf("Removed %d\n", *top);
    }
    printf("\n");
    heap_print(&h);
    while(heap_size(&h) > 0){
        top = heap_remove(&h);
        printf("Removed %d\n", *top);
    }
    heap_print(&h);
    for(i=0; i<13; i++){
        heap_insert(&h, items[i]);
    }
    heap_print(&h);
    heap_destroy(&h);
 return 0;
}

canonical_original_code:
int main(){
    int numbers[] = {20, 15, 12, 22, 30, 10, 8, 42, 50 , 19, 1, 0, 45};
    void **items = malloc(13*sizeof(int*));
    printf("Building heap of size 13 \n\n");
    int i;
    for(i=0; i < 13; i++){
        items[i] = malloc(sizeof(int));
        *(int *)items[i] = numbers[i];
    }
    struct _heap h;
    heap_init_with_items(&h, compare, items, 13);
    heap_print(&h);
    int *top;
    for(i=0; i<4; i++){
        top = heap_remove(&h);
        printf("Removed %d\n", *top);
    }
    printf("\n");
    heap_print(&h);
    while(heap_size(&h) > 0){
        top = heap_remove(&h);
        printf("Removed %d\n", *top);
    }
    heap_print(&h);
    for(i=0; i<13; i++){
        heap_insert(&h, items[i]);
    }
    heap_print(&h);
    heap_destroy(&h);
 return 0;
}

variable_types:
numbers
int []

variable_types: struct _heap { int (*compare)(void *, void *); void **items; int size; int capacity; }

variable_types:
top
int *


decompiled_code:
void __fastcall single_ll_init(__int64 a1)
{
*(_DWORD *)a1 = 0;
*(_QWORD *)(a1 + 8) = 0LL;
}

canonical_decompiled_code:
void __fastcall func7(__int64 a1)
{
*(_DWORD *)a1 = 0;
*(_QWORD *)(a1 + 8) = 0LL;
}

original_code:
void single_ll_init(single_ll *l){
    l->size = 0;
    l->head = ((void *)0);
}

canonical_original_code:
void single_ll_init(struct _single_ll *l){
    l->size = 0;
    l->head = ((void *)0);
}

variable_types: struct _single_ll { int size; struct _node_t { void *key; void *data; struct _node_t *next; } *head; } *

user_defined_types: struct _single_ll { int size; struct _node_t *head; }


original_code:
int single_ll_add(single_ll *l, void *key, void *data){
    if (!l || !key || !data)
        return 0;
    if (!(l->head)){
        l->head = (node_t*)malloc(sizeof(node_t));
        l->head->key = key;
        l->head->data = data;
        l->head->next = ((void *)0);
        (l->size)++;
        return 1;
    }
    node_t *stepper = l->head;
    while (stepper){
        if (stepper->key == key)
            return 0;
        if (!(stepper->next)){
            stepper->next = (node_t*)malloc(sizeof(node_t));
            stepper->next->key = key;
            stepper->next->data = data;
            (l->size)++;
            return 1;
        }
        stepper = stepper->next;
    }
    return 0;
}

canonical_original_code:
int single_ll_add(struct _single_ll *l, void *key, void *data){
    if (!l || !key || !data)
        return 0;
    if (!(l->head)){
        l->head = (struct _node_t *)malloc(sizeof(node_t));
        l->head->key = key;
        l->head->data = data;
        l->head->next = ((void *)0);
        (l->size)++;
        return 1;
    }
    struct _node_t *stepper = l->head;
    while (stepper){
        if (stepper->key == key)
            return 0;
        if (!(stepper->next)){
            stepper->next = (struct _node_t *)malloc(sizeof(node_t));
            stepper->next->key = key;
            stepper->next->data = data;
            (l->size)++;
            return 1;
        }
        stepper = stepper->next;
    }
    return 0;
}

variable_types:
key
void *

variable_types:
data
void *

variable_types: struct _node_t { void *key; void *data; struct _node_t *next; } *


original_code:
const void *single_ll_get_at(single_ll *l, int index){
    if (!l || (index < 0) || (index >= l->size))
        return ((void *)0);
    node_t *stepper = l->head;
    int i = 0;
    while (i < index){
        stepper = stepper->next;
        i++;
    }
    return stepper->data;
}

canonical_original_code:
void *single_ll_get_at(struct _single_ll *l, int index){
    if (!l || (index < 0) || (index >= l->size))
        return ((void *)0);
    struct _node_t *stepper = l->head;
    int i = 0;
    while (i < index){
        stepper = stepper->next;
        i++;
    }
    return stepper->data;
}

variable_types: index int

user_defined_types: struct _node_t { void *key; void *data; struct _node_t *next; }


original_code:
int single_ll_remove(single_ll *l, const void *key){
    if (!l || !(l->head) || !key)
        return 0;
    if (l->head->key == key){
        node_t *tmp = l->head;
        l->head = l->head->next;
        (l->size)--;
        free(tmp);
        return 1;
    }
    node_t *stepper = l->head;
    while (stepper->next){
        if (stepper->next->key == key){
            node_t *tmp = stepper->next;
            stepper->next = stepper->next->next;
            free(tmp);
            (l->size)--;
            return 1;
        }
        stepper = stepper->next;
    }
    return 0;
}

canonical_original_code:
int single_ll_remove(struct _single_ll *l, void *key){
    if (!l || !(l->head) || !key)
        return 0;
    if (l->head->key == key){
        struct _node_t *tmp = l->head;
        l->head = l->head->next;
        (l->size)--;
        free(tmp);
        return 1;
    }
    struct _node_t *stepper = l->head;
    while (stepper->next){
        if (stepper->next->key == key){
            struct _node_t *tmp = stepper->next;
            stepper->next = stepper->next->next;
            free(tmp);
            (l->size)--;
            return 1;
        }
        stepper = stepper->next;
    }
    return 0;
}


decompiled_code:
__int64 __fastcall single_ll_remove_at(__int64 a1, int a2)
{
__int64 result; // rax
_QWORD *v4; // rdi
int v5; // esi
int i; // eax
_QWORD *v7; // r8

if ( !a1 || a2 < 0 )
return 0LL;
result = 0LL;
if ( *(_DWORD *)a1 > a2 )
{
v4 = *(_QWORD **)(a1 + 8);
if ( a2 )
{
v5 = a2 - 1;
if ( v5 )
{
for ( i = 0; i != v5; ++i )
v4 = (_QWORD *)v4[2];
}
v7 = (_QWORD *)v4[2];
v4[2] = v7[2];
free(v7);
--*(_DWORD *)a1;
result = 1LL;
}
else
{
*(_QWORD *)(a1 + 8) = v4[2];
free(v4);
--*(_DWORD *)a1;
result = 1LL;
}
}
return result;
}

original_code:
int single_ll_remove_at(single_ll *l, int index){
    if (!l || (index < 0) || (index >= l->size))
        return 0;
    if (index == 0){
        node_t *tmp = l->head;
        l->head = l->head->next;
        free(tmp);
        (l->size)--;
        return 1;
    }
    node_t *stepper = l->head;
    int i = 0;
    while (i < (index-1)){
        stepper = stepper->next;
        i++;
    }
    node_t *tmp = stepper->next;
    stepper->next = stepper->next->next;
    free(tmp);
    (l->size)--;
    return 1;
}

canonical_original_code:
int single_ll_remove_at(struct _single_ll *l, int index){
    if (!l || (index < 0) || (index >= l->size))
        return 0;
    if (index == 0){
        struct _node_t *tmp = l->head;
        l->head = l->head->next;
        free(tmp);
        (l->size)--;
        return 1;
    }
    struct _node_t *stepper = l->head;
    int i = 0;
    while (i < (index-1)){
        stepper = stepper->next;
        i++;
    }
    struct _node_t *tmp = stepper->next;
    stepper->next = stepper->next->next;
    free(tmp);
    (l->size)--;
    return 1;
}


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

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

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

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

original_code:
int single_ll_size(single_ll *l){
    if (!l)
        return 0;
    return l->size;
}

canonical_original_code:
int single_ll_size(struct _single_ll *l){
    if (!l)
        return 0;
    return l->size;
}


decompiled_code:
_BOOL8 __fastcall single_ll_empty(_DWORD *a1)
{
_BOOL8 result; // rax

if ( a1 )
result = *a1 == 0;
else
result = 1LL;
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func13(_DWORD *a1)
{
_BOOL8 result; // rax

if ( a1 )
result = *a1 == 0;
else
result = 1LL;
return result;
}

original_code:
int single_ll_empty(single_ll *l){
    if (!l)
        return 1;
    return (l->size == 0);
}

canonical_original_code:
int single_ll_empty(struct _single_ll *l){
    if (!l)
        return 1;
    return (l->size == 0);
}


original_code:
void single_ll_print(single_ll *l){
    if (!l)
        return;
    int i;
    node_t *stepper = l->head;
    for (i = 0; i < l->size; i++){
        if (i != (l->size -1))
            printf("(%s, %s)  ", (char *)stepper->key, (char *)stepper->data);
        else
            printf("(%s, %s)\n", (char *)stepper->key, (char *)stepper->data);
        stepper = stepper->next;
    }
}

canonical_original_code:
void single_ll_print(struct _single_ll *l){
    if (!l)
        return;
    int i;
    struct _node_t *stepper = l->head;
    for (i = 0; i < l->size; i++){
        if (i != (l->size -1))
            printf("(%s, %s)  ", (char *)stepper->key, (char *)stepper->data);
        else
            printf("(%s, %s)\n", (char *)stepper->key, (char *)stepper->data);
        stepper = stepper->next;
    }
}


decompiled_code:
void __fastcall single_ll_destroy(__int64 a1)
{
_QWORD *v2; // rbx
void *v3; // rdi

if ( a1 )
{
v2 = *(_QWORD **)(a1 + 8);
while ( v2 )
{
v3 = v2;
v2 = (_QWORD *)v2[2];
free(v3);
}
*(_QWORD *)(a1 + 8) = 0LL;
*(_DWORD *)a1 = 0;
}
}

original_code:
void single_ll_destroy(single_ll *l){
    if (!l)
        return;
    node_t *stepper = l->head;
    while(stepper){
        node_t *tmp = stepper->next;
        free(stepper);
        stepper = tmp;
    }
    l->head = ((void *)0);
    l->size = 0;
}

canonical_original_code:
void single_ll_destroy(struct _single_ll *l){
    if (!l)
        return;
    struct _node_t *stepper = l->head;
    while(stepper){
        struct _node_t *tmp = stepper->next;
        free(stepper);
        stepper = tmp;
    }
    l->head = ((void *)0);
    l->size = 0;
}


original_code:
void bintree_makenode(tree_node_t *n, void *key, void *value){
    if (!key || !value)
        return;
    if (!n)
        n = (tree_node_t *)malloc(sizeof(tree_node_t));
    n->key = key;
    n->value = value;
    n->right = ((void *)0);
    n->left = ((void *)0);
}

canonical_original_code:
void bintree_makenode(struct _tree_node_t *n, void *key, void *value){
    if (!key || !value)
        return;
    if (!n)
        n = (struct _tree_node_t *)malloc(sizeof(tree_node_t));
    n->key = key;
    n->value = value;
    n->right = ((void *)0);
    n->left = ((void *)0);
}

variable_types: struct _tree_node_t { void *key; void *value; struct _tree_node_t *left; struct _tree_node_t *right; } *

variable_types:
value
void *


decompiled_code:
__int64 __fastcall bintree_getrealheight(__int64 a1)
{
int v1; // ebp
int v2; // eax
bool v3; // cc
unsigned int v4; // edx
__int64 result; // rax

if ( !a1 )
return 0xFFFFFFFFLL;
v1 = bintree_getrealheight(*(_QWORD *)(a1 + 16));
v2 = bintree_getrealheight(*(_QWORD *)(a1 + 24));
v3 = v1 <= v2;
v4 = v2 + 1;
result = (unsigned int)(v1 + 1);
if ( v3 )
result = v4;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1)
{
int v1; // ebp
int v2; // eax
bool v3; // cc
unsigned int v4; // edx
__int64 result; // rax

if ( !a1 )
return 0xFFFFFFFFLL;
v1 = func1(*(_QWORD *)(a1 + 16));
v2 = func1(*(_QWORD *)(a1 + 24));
v3 = v1 <= v2;
v4 = v2 + 1;
result = (unsigned int)(v1 + 1);
if ( v3 )
result = v4;
return result;
}

original_code:
int bintree_getrealheight(tree_node_t *n){
    if (!n)
        return -1;
    int left = bintree_getrealheight(n->left);
    int right = bintree_getrealheight(n->right);
    if (left > right)
        return left + 1;
    return right + 1;
}

canonical_original_code:
int bintree_getrealheight(struct _tree_node_t *n){
    if (!n)
        return -1;
    int left = bintree_getrealheight(n->left);
    int right = bintree_getrealheight(n->right);
    if (left > right)
        return left + 1;
    return right + 1;
}

variable_types: left int

variable_types: right int

user_defined_types: struct _tree_node_t { void *key; void *value; struct _tree_node_t *left; struct _tree_node_t *right; }


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

for ( result = a1; result && *(_QWORD *)(result + 24); result = *(_QWORD *)(result + 24) )
;
return result;
}

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

for ( result = a1; result && *(_QWORD *)(result + 24); result = *(_QWORD *)(result + 24) )
;
return result;
}

original_code:
tree_node_t *bintree_inorderpred(tree_node_t *n){
    if (!n || !(n->right))
        return n;
    return bintree_inorderpred(n->right);
}

canonical_original_code:
struct _tree_node_t *bintree_inorderpred(struct _tree_node_t *n){
    if (!n || !(n->right))
        return n;
    return bintree_inorderpred(n->right);
}

variable_types:
n
struct _tree_node_t *

return_type: struct _tree_node_t { void *key; void *value; struct _tree_node_t *left; struct _tree_node_t *right; } *


original_code:
void bintree_init(bintree_t *b, int(*comparer)(const void *, const void *)){
    if (!b || !comparer)
        return;
    b->root = ((void *)0);
    b->height = -1;
    b->compare = comparer;
}

canonical_original_code:
void bintree_init(struct _bintree_t *b, int (*comparer)(void *, void *)){
    if (!b || !comparer)
        return;
    b->root = ((void *)0);
    b->height = -1;
    b->compare = comparer;
}

variable_types: struct _bintree_t { struct _tree_node_t { void *key; void *value; struct _tree_node_t *left; struct _tree_node_t *right; } *root; int height; int (*compare)(void *, void *); } *

variable_types:
comparer
int (*)(void *, void *)

user_defined_types: struct _bintree_t { struct _tree_node_t *root; int height; int (*compare)(void *, void *); }


original_code:
int bintree_insert(bintree_t *b, void *key, void *value){
    if (!b || !key || !value)
        return 0;
    if (!(b->root)){
        b->root = (tree_node_t *)malloc(sizeof(tree_node_t));
        bintree_makenode(b->root, key, value);
        b->height = 0;
        return 1;
    }
    int currHeight = 0;
    tree_node_t *stepper = b->root;
    while (stepper){
        int comp = b->compare(key, stepper->key);
        if (comp == 0)
            return 0;
        if (!(stepper->left) && (comp < 0)){
            stepper->left = (tree_node_t *)malloc(sizeof(tree_node_t));
            bintree_makenode(stepper->left, key, value);
            if (currHeight == b->height)
                (b->height)++;
            return 1;
        }
        if (!(stepper->right) && (comp > 0)){
            stepper->right = (tree_node_t *)malloc(sizeof(tree_node_t));
            bintree_makenode(stepper->right, key, value);
            if (currHeight == b->height)
                (b->height)++;
            return 1;
        }
        if (comp < 0)
            stepper = stepper->left;
        else
            stepper = stepper->right;
        currHeight++;
    }
    return 0;
}

canonical_original_code:
int bintree_insert(struct _bintree_t *b, void *key, void *value){
    if (!b || !key || !value)
        return 0;
    if (!(b->root)){
        b->root = (struct _tree_node_t *)malloc(sizeof(tree_node_t));
        bintree_makenode(b->root, key, value);
        b->height = 0;
        return 1;
    }
    int currHeight = 0;
    struct _tree_node_t *stepper = b->root;
    while (stepper){
        int comp = b->compare(key, stepper->key);
        if (comp == 0)
            return 0;
        if (!(stepper->left) && (comp < 0)){
            stepper->left = (struct _tree_node_t *)malloc(sizeof(tree_node_t));
            bintree_makenode(stepper->left, key, value);
            if (currHeight == b->height)
                (b->height)++;
            return 1;
        }
        if (!(stepper->right) && (comp > 0)){
            stepper->right = (struct _tree_node_t *)malloc(sizeof(tree_node_t));
            bintree_makenode(stepper->right, key, value);
            if (currHeight == b->height)
                (b->height)++;
            return 1;
        }
        if (comp < 0)
            stepper = stepper->left;
        else
            stepper = stepper->right;
        currHeight++;
    }
    return 0;
}

variable_types: currHeight int

variable_types: comp int


original_code:
int bintree_remove(bintree_t *b, const void *key){
    if (!b || !key)
        return 0;
    tree_node_t *stepper = b->root;
    while (stepper) {
        int comp = b->compare(key, stepper->key);
        if (comp == 0){
            if ( (!(stepper->left) && stepper->right) ||
                 (stepper->left && !(stepper->right)) ){
                if (stepper->left){
                    tree_node_t *tmp = stepper->left;
                    stepper->key = stepper->left->key;
                    stepper->value = stepper->left->value;
                    stepper->right = stepper->left->right;
                    stepper->left = stepper->left->left;
                    free(tmp);
                } else {
                    tree_node_t *tmp = stepper->right;
                    stepper->key = stepper->right->key;
                    stepper->value = stepper->right->value;
                    stepper->left = stepper->right->left;
                    stepper->right = stepper->right->right;
                    free(tmp);
                }
            } else if (!(stepper->left) && !(stepper->right)) {
                tree_node_t *parent = bintree_getparent(b, stepper);
                if (!parent)
                    b->root = ((void *)0);
                else {
                    if (parent->left == stepper)
                        parent->left = ((void *)0);
                    else
                        parent->right = ((void *)0);
                }
                free(stepper);
            } else {
                tree_node_t *iop = bintree_inorderpred(stepper->left);
                if (iop == stepper->left){
                    stepper->key = iop->key;
                    stepper->value = iop->value;
                    stepper->left = iop->left;
                    free(iop);
                } else {
                    stepper->key = iop->key;
                    stepper->value = iop->value;
                    if (iop->left){
                        tree_node_t *tmp = iop->left;
                        iop->key = iop->left->key;
                        iop->value = iop->left->value;
                        iop->right = iop->left->right;
                        iop->left = iop->left->left;
                        free(tmp);
                    } else {
                        tree_node_t *iopparent = bintree_getparent(b, iop);
                        iopparent->right = ((void *)0);
                        free(iop);
                    }
                }
            }
            b->height = bintree_getrealheight(b->root);
            return 1;
        }
        if (comp < 0)
            stepper = stepper->left;
        else
            stepper = stepper->right;
    }
    return 0;
}

canonical_original_code:
int bintree_remove(struct _bintree_t *b, void *key){
    if (!b || !key)
        return 0;
    struct _tree_node_t *stepper = b->root;
    while (stepper) {
        int comp = b->compare(key, stepper->key);
        if (comp == 0){
            if ( (!(stepper->left) && stepper->right) ||
                 (stepper->left && !(stepper->right)) ){
                if (stepper->left){
                    struct _tree_node_t *tmp = stepper->left;
                    stepper->key = stepper->left->key;
                    stepper->value = stepper->left->value;
                    stepper->right = stepper->left->right;
                    stepper->left = stepper->left->left;
                    free(tmp);
                } else {
                    struct _tree_node_t *tmp = stepper->right;
                    stepper->key = stepper->right->key;
                    stepper->value = stepper->right->value;
                    stepper->left = stepper->right->left;
                    stepper->right = stepper->right->right;
                    free(tmp);
                }
            } else if (!(stepper->left) && !(stepper->right)) {
                struct _tree_node_t *parent = bintree_getparent(b, stepper);
                if (!parent)
                    b->root = ((void *)0);
                else {
                    if (parent->left == stepper)
                        parent->left = ((void *)0);
                    else
                        parent->right = ((void *)0);
                }
                free(stepper);
            } else {
                struct _tree_node_t *iop = bintree_inorderpred(stepper->left);
                if (iop == stepper->left){
                    stepper->key = iop->key;
                    stepper->value = iop->value;
                    stepper->left = iop->left;
                    free(iop);
                } else {
                    stepper->key = iop->key;
                    stepper->value = iop->value;
                    if (iop->left){
                        struct _tree_node_t *tmp = iop->left;
                        iop->key = iop->left->key;
                        iop->value = iop->left->value;
                        iop->right = iop->left->right;
                        iop->left = iop->left->left;
                        free(tmp);
                    } else {
                        struct _tree_node_t *iopparent = bintree_getparent(b, iop);
                        iopparent->right = ((void *)0);
                        free(iop);
                    }
                }
            }
            b->height = bintree_getrealheight(b->root);
            return 1;
        }
        if (comp < 0)
            stepper = stepper->left;
        else
            stepper = stepper->right;
    }
    return 0;
}


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

if ( a1 )
result = *(unsigned int *)(a1 + 8);
else
result = 0xFFFFFFFFLL;
return result;
}

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

if ( a1 )
result = *(unsigned int *)(a1 + 8);
else
result = 0xFFFFFFFFLL;
return result;
}

original_code:
int bintree_height(bintree_t *b){
    if (!b)
        return -1;
    return b->height;
}

canonical_original_code:
int bintree_height(struct _bintree_t *b){
    if (!b)
        return -1;
    return b->height;
}


decompiled_code:
void __fastcall bintree_print(_QWORD *a1)
{
unsigned int v1; // ebp
__int64 v2; // rax
__int64 v3; // rsi
const char **v4; // rbx
const char *v5; // rsi
__int64 v6; // rax
__int64 v7; // rsi
const char **v8; // rbx
const char *v9; // rsi
_BYTE v10[48]; // [rsp-30h] [rbp-78h] BYREF
char v11[72]; // [rsp+0h] [rbp-48h] BYREF

if ( a1 && *a1 )
{
v1 = 0;
queue_init(v10);
queue_init(v11);
queue_enqueue(v10, *a1);
LABEL_4:
while ( !(unsigned int)queue_empty(v10) || !(unsigned int)queue_empty(v11) )
{
if ( !(unsigned int)queue_empty(v10) )
printf("Level %d: ", v1);
while ( !(unsigned int)queue_empty(v10) )
{
while ( 1 )
{
v2 = queue_dequeue(v10);
v3 = *(_QWORD *)(v2 + 16);
v4 = (const char **)v2;
if ( v3 )
queue_enqueue(v11, v3);
v5 = v4[3];
if ( v5 )
queue_enqueue(v11, v5);
if ( !(unsigned int)queue_empty(v10) )
break;
++v1;
printf("(%s, %s)\n", *v4, v4[1]);
if ( (unsigned int)queue_empty(v10) )
goto LABEL_15;
}
printf("(%s, %s) ", *v4, v4[1]);
}
LABEL_15:
if ( !(unsigned int)queue_empty(v11) )
printf("Level %d: ", v1);
while ( !(unsigned int)queue_empty(v11) )
{
while ( 1 )
{
v6 = queue_dequeue(v11);
v7 = *(_QWORD *)(v6 + 16);
v8 = (const char **)v6;
if ( v7 )
queue_enqueue(v10, v7);
v9 = v8[3];
if ( v9 )
queue_enqueue(v10, v9);
if ( !(unsigned int)queue_empty(v11) )
break;
++v1;
printf("(%s, %s)\n", *v8, v8[1]);
if ( (unsigned int)queue_empty(v11) )
goto LABEL_4;
}
printf("(%s, %s) ", *v8, v8[1]);
}
}
}
}

canonical_decompiled_code:
void __fastcall func8(_QWORD *a1)
{
unsigned int v1; // ebp
__int64 v2; // rax
__int64 v3; // rsi
const char **v4; // rbx
const char *v5; // rsi
__int64 v6; // rax
__int64 v7; // rsi
const char **v8; // rbx
const char *v9; // rsi
_BYTE v10[48]; // [rsp-30h] [rbp-78h] BYREF
char v11[72]; // [rsp+0h] [rbp-48h] BYREF

if ( a1 && *a1 )
{
v1 = 0;
queue_init(v10);
queue_init(v11);
queue_enqueue(v10, *a1);
LABEL_4:
while ( !(unsigned int)queue_empty(v10) || !(unsigned int)queue_empty(v11) )
{
if ( !(unsigned int)queue_empty(v10) )
printf("Level %d: ", v1);
while ( !(unsigned int)queue_empty(v10) )
{
while ( 1 )
{
v2 = queue_dequeue(v10);
v3 = *(_QWORD *)(v2 + 16);
v4 = (const char **)v2;
if ( v3 )
queue_enqueue(v11, v3);
v5 = v4[3];
if ( v5 )
queue_enqueue(v11, v5);
if ( !(unsigned int)queue_empty(v10) )
break;
++v1;
printf("(%s, %s)\n", *v4, v4[1]);
if ( (unsigned int)queue_empty(v10) )
goto LABEL_15;
}
printf("(%s, %s) ", *v4, v4[1]);
}
LABEL_15:
if ( !(unsigned int)queue_empty(v11) )
printf("Level %d: ", v1);
while ( !(unsigned int)queue_empty(v11) )
{
while ( 1 )
{
v6 = queue_dequeue(v11);
v7 = *(_QWORD *)(v6 + 16);
v8 = (const char **)v6;
if ( v7 )
queue_enqueue(v10, v7);
v9 = v8[3];
if ( v9 )
queue_enqueue(v10, v9);
if ( !(unsigned int)queue_empty(v11) )
break;
++v1;
printf("(%s, %s)\n", *v8, v8[1]);
if ( (unsigned int)queue_empty(v11) )
goto LABEL_4;
}
printf("(%s, %s) ", *v8, v8[1]);
}
}
}
}

original_code:
void bintree_print(bintree_t *b){
    if (!b || !(b->root))
        return;
    queue_t q1, q2;
    queue_init(&q1);
    queue_init(&q2);
    int level = 0;
    queue_enqueue(&q1, b->root);
    while (!queue_empty(&q1) || !queue_empty(&q2)){
        if (!queue_empty(&q1))
            printf("Level %d: ", level);
        while (!queue_empty(&q1)){
            tree_node_t *tmp = queue_dequeue(&q1);
            if (tmp->left)
                queue_enqueue(&q2, tmp->left);
            if (tmp->right)
                queue_enqueue(&q2, tmp->right);
            if (queue_empty(&q1)){
                level++;
                printf("(%s, %s)\n", (char *)tmp->key, (char *)tmp->value);
            } else
                printf("(%s, %s) ", (char *)tmp->key, (char *)tmp->value);
        }
        if (!queue_empty(&q2))
            printf("Level %d: ", level);
        while (!queue_empty(&q2)){
            tree_node_t *tmp = queue_dequeue(&q2);
            if (tmp->left)
                queue_enqueue(&q1, tmp->left);
            if (tmp->right)
                queue_enqueue(&q1, tmp->right);
            if (queue_empty(&q2)){
                level++;
                printf("(%s, %s)\n", (char *)tmp->key, (char *)tmp->value);
            } else
                printf("(%s, %s) ", (char *)tmp->key, (char *)tmp->value);
        }
    }
}

canonical_original_code:
void bintree_print(struct _bintree_t *b){
    if (!b || !(b->root))
        return;
    struct _queue_t q1; struct _queue_t q2;
    queue_init(&q1);
    queue_init(&q2);
    int level = 0;
    queue_enqueue(&q1, b->root);
    while (!queue_empty(&q1) || !queue_empty(&q2)){
        if (!queue_empty(&q1))
            printf("Level %d: ", level);
        while (!queue_empty(&q1)){
            struct _tree_node_t *tmp = queue_dequeue(&q1);
            if (tmp->left)
                queue_enqueue(&q2, tmp->left);
            if (tmp->right)
                queue_enqueue(&q2, tmp->right);
            if (queue_empty(&q1)){
                level++;
                printf("(%s, %s)\n", (char *)tmp->key, (char *)tmp->value);
            } else
                printf("(%s, %s) ", (char *)tmp->key, (char *)tmp->value);
        }
        if (!queue_empty(&q2))
            printf("Level %d: ", level);
        while (!queue_empty(&q2)){
            struct _tree_node_t *tmp = queue_dequeue(&q2);
            if (tmp->left)
                queue_enqueue(&q1, tmp->left);
            if (tmp->right)
                queue_enqueue(&q1, tmp->right);
            if (queue_empty(&q2)){
                level++;
                printf("(%s, %s)\n", (char *)tmp->key, (char *)tmp->value);
            } else
                printf("(%s, %s) ", (char *)tmp->key, (char *)tmp->value);
        }
    }
}

variable_types: struct _queue_t { struct _stack { void **items; int size; int capacity; } in; int size; }

variable_types: level int


decompiled_code:
void __fastcall bintree_destroy_helper(_QWORD *a1)
{
if ( a1 )
{
if ( a1[2] )
bintree_destroy_helper();
if ( a1[3] )
bintree_destroy_helper();
free(a1);
}
}

canonical_decompiled_code:
void __fastcall func9(_QWORD *a1)
{
if ( a1 )
{
if ( a1[2] )
func9();
if ( a1[3] )
func9();
free(a1);
}
}

original_code:
void bintree_destroy_helper(tree_node_t *curr){
    if (!curr)
        return;
    if (curr->left)
        bintree_destroy_helper(curr->left);
    if (curr->right)
        bintree_destroy_helper(curr->right);
    free(curr);
}

canonical_original_code:
void bintree_destroy_helper(struct _tree_node_t *curr){
    if (!curr)
        return;
    if (curr->left)
        bintree_destroy_helper(curr->left);
    if (curr->right)
        bintree_destroy_helper(curr->right);
    free(curr);
}


decompiled_code:
void __fastcall bintree_destroy(_QWORD **a1)
{
_QWORD *v1; // rdi

if ( a1 )
{
v1 = *a1;
if ( v1 )
bintree_destroy_helper(v1);
}
}

canonical_decompiled_code:
void __fastcall func10(_QWORD **a1)
{
_QWORD *v1; // rdi

if ( a1 )
{
v1 = *a1;
if ( v1 )
func9(v1);
}
}

original_code:
void bintree_destroy(bintree_t *b){
    if (!b || !(b->root))
        return;
    bintree_destroy_helper(b->root);
}

canonical_original_code:
void bintree_destroy(struct _bintree_t *b){
    if (!b || !(b->root))
        return;
    bintree_destroy_helper(b->root);
}


comparer

decompiled_code:
// attributes: thunk
int comparer(const char *s1, const char *s2)
{
return strcmp(s1, s2);
}

canonical_decompiled_code:
int func0(const char *s1, const char *s2)
{
return strcmp(s1, s2);
}

original_code:
int comparer(const void *a, const void *b){
    return strcmp((char *)a, (char *)b);
}

canonical_original_code:
int comparer(void *a, void *b){
    return strcmp((char *)a, (char *)b);
}

variable_types:
a
void *

variable_types:
b
void *


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax
const char *v4; // rax
const char *v5; // rax
const char *v6; // rax
_BYTE v8[40]; // [rsp+0h] [rbp-28h] BYREF

bintree_init(v8, comparer, envp);
bintree_insert(v8, "key 2", "value 1");
bintree_insert(v8, "key 1", "value 2");
bintree_insert(v8, "key 3", "value 3");
bintree_insert(v8, "key 4", "value 4");
bintree_insert(v8, "key 0", "value 5");
bintree_insert(v8, "key 9", "value 6");
bintree_print(v8);
bintree_remove(v8, "key 9");
bintree_remove(v8, "key 0");
puts("After removing 'key 9' and 'key 0':");
bintree_print(v8);
bintree_remove(v8, "key 2");
puts("After removing the root (key 2):");
bintree_print(v8);
v3 = bintree_height(v8);
printf("Height of tree: %d\n", v3);
v4 = (const char *)bintree_find(v8, "key 1");
printf("value of 'key 1': %s\n", v4);
v5 = (const char *)bintree_find(v8, "key 3");
printf("value of 'key 3': %s\n", v5);
v6 = (const char *)bintree_find(v8, "key 4");
printf("value of 'key 4': %s\n", v6);
bintree_destroy(v8);
return 0;
}

original_code:
int main() {
    bintree_t testBT;
    bintree_init(&testBT, &comparer);
    bintree_insert(&testBT, "key 2", "value 1");
    bintree_insert(&testBT, "key 1", "value 2");
    bintree_insert(&testBT, "key 3", "value 3");
    bintree_insert(&testBT, "key 4", "value 4");
    bintree_insert(&testBT, "key 0", "value 5");
    bintree_insert(&testBT, "key 9", "value 6");
    bintree_print(&testBT);
    bintree_remove(&testBT, "key 9");
    bintree_remove(&testBT, "key 0");
    printf("After removing 'key 9' and 'key 0':\n");
    bintree_print(&testBT);
    bintree_remove(&testBT, "key 2");
    printf("After removing the root (key 2):\n");
    bintree_print(&testBT);
    printf("Height of tree: %d\n", bintree_height(&testBT));
    printf("value of 'key 1': %s\n", (char *)bintree_find(&testBT, "key 1"));
    printf("value of 'key 3': %s\n", (char *)bintree_find(&testBT, "key 3"));
    printf("value of 'key 4': %s\n", (char *)bintree_find(&testBT, "key 4"));
    bintree_destroy(&testBT);
    return 0;
}

canonical_original_code:
int main() {
    struct _bintree_t testBT;
    bintree_init(&testBT, &comparer);
    bintree_insert(&testBT, "key 2", "value 1");
    bintree_insert(&testBT, "key 1", "value 2");
    bintree_insert(&testBT, "key 3", "value 3");
    bintree_insert(&testBT, "key 4", "value 4");
    bintree_insert(&testBT, "key 0", "value 5");
    bintree_insert(&testBT, "key 9", "value 6");
    bintree_print(&testBT);
    bintree_remove(&testBT, "key 9");
    bintree_remove(&testBT, "key 0");
    printf("After removing 'key 9' and 'key 0':\n");
    bintree_print(&testBT);
    bintree_remove(&testBT, "key 2");
    printf("After removing the root (key 2):\n");
    bintree_print(&testBT);
    printf("Height of tree: %d\n", bintree_height(&testBT));
    printf("value of 'key 1': %s\n", (char *)bintree_find(&testBT, "key 1"));
    printf("value of 'key 3': %s\n", (char *)bintree_find(&testBT, "key 3"));
    printf("value of 'key 4': %s\n", (char *)bintree_find(&testBT, "key 4"));
    bintree_destroy(&testBT);
    return 0;
}

variable_types: struct _bintree_t { struct _tree_node_t { void *key; void *value; struct _tree_node_t *left; struct _tree_node_t *right; } *root; int height; int (*compare)(void *, void *); }