decompiled_code:
int __fastcall cstr_subst(void *dest, char *s2, char *s)
{
char *v3; // rbx
char *v4; // r14
int v5; // er15
int v6; // er13
int result; // eax
int v8; // ebp
size_t v9; // rax
size_t v10; // rax

v3 = (char *)dest;
v4 = s;
v5 = strlen(s2);
v6 = strlen(v4);
result = (v5 - v6) >> 31;
v8 = abs32(v5 - v6);
while ( *v3 )
{
result = strncmp(v3, s2, v5);
if ( result )
{
++v3;
}
else if ( v5 >= v6 )
{
result = (unsigned int)memcpy(v3, s, v6);
v3 += v6;
if ( v8 > 0 )
{
v10 = strlen(v3);
result = (unsigned int)memmove(v3, &v3[v8], v10 + 1);
}
}
else
{
v9 = strlen(v3);
memmove(&v3[v8], v3, v9 + 1);
result = (unsigned int)memcpy(v3, s, v6);
}
}
return result;
}

canonical_decompiled_code:
int __fastcall func4(void *dest, char *s2, char *s)
{
char *v3; // rbx
char *v4; // r14
int v5; // er15
int v6; // er13
int result; // eax
int v8; // ebp
size_t v9; // rax
size_t v10; // rax

v3 = (char *)dest;
v4 = s;
v5 = strlen(s2);
v6 = strlen(v4);
result = (v5 - v6) >> 31;
v8 = abs32(v5 - v6);
while ( *v3 )
{
result = strncmp(v3, s2, v5);
if ( result )
{
++v3;
}
else if ( v5 >= v6 )
{
result = (unsigned int)memcpy(v3, s, v6);
v3 += v6;
if ( v8 > 0 )
{
v10 = strlen(v3);
result = (unsigned int)memmove(v3, &v3[v8], v10 + 1);
}
}
else
{
v9 = strlen(v3);
memmove(&v3[v8], v3, v9 + 1);
result = (unsigned int)memcpy(v3, s, v6);
}
}
return result;
}

original_code:
void cstr_subst(char * restrict cstr,
 char const * restrict a, char const * restrict b)
{
 char * iter = cstr;
 int const a_len = strlen(a);
 int const b_len = strlen(b);
 int const gap = abs(a_len - b_len);
 while(*iter != 0)
 {
  if(strncmp(iter, a, a_len) != 0)
  {
   iter++;
   continue;
  }
  if(a_len < b_len)
  {
   memmove(iter + gap, iter, strlen(iter) + 1);
   memcpy(iter, b, b_len);
  }
  else
  {
   memcpy(iter, b, b_len);
   iter += b_len;
   if(gap > 0)
    memmove(iter, iter + gap, strlen(iter) + 1);
  }
 }
}

canonical_original_code:
void cstr_subst(char *cstr, char *a, char *b)
{
 char *iter = cstr;
 int a_len = strlen(a);
 int b_len = strlen(b);
 int gap = abs(a_len - b_len);
 while(*iter != 0)
 {
  if(strncmp(iter, a, a_len) != 0)
  {
   iter++;
   continue;
  }
  if(a_len < b_len)
  {
   memmove(iter + gap, iter, strlen(iter) + 1);
   memcpy(iter, b, b_len);
  }
  else
  {
   memcpy(iter, b, b_len);
   iter += b_len;
   if(gap > 0)
    memmove(iter, iter + gap, strlen(iter) + 1);
  }
 }
}

variable_types:
a
char *

variable_types:
b
char *

variable_types:
iter
char *

variable_types: gap int


repo: ultramailman/iniparser

decompiled_code:
__int64 __fastcall cstr2uint(char *a1, unsigned int *a2)
{
char v2; // dl
unsigned int v3; // eax
int v4; // ecx
unsigned int v5; // eax
bool v6; // cf

v2 = *a1;
if ( !*a1 )
return 4294967293LL;
v3 = 0;
while ( 1 )
{
v4 = 10 * v3;
v5 = v2 - 48;
if ( v5 > 9 )
return 0xFFFFFFFFLL;
v6 = __CFADD__(v4, v5);
v3 = v4 + v5;
if ( v6 )
break;
v2 = *++a1;
if ( !*a1 )
{
*a2 = v3;
return 0LL;
}
}
return 4294967294LL;
}

canonical_decompiled_code:
__int64 __fastcall func5(char *a1, unsigned int *a2)
{
char v2; // dl
unsigned int v3; // eax
int v4; // ecx
unsigned int v5; // eax
bool v6; // cf

v2 = *a1;
if ( !*a1 )
return 4294967293LL;
v3 = 0;
while ( 1 )
{
v4 = 10 * v3;
v5 = v2 - 48;
if ( v5 > 9 )
return 0xFFFFFFFFLL;
v6 = __CFADD__(v4, v5);
v3 = v4 + v5;
if ( v6 )
break;
v2 = *++a1;
if ( !*a1 )
{
*a2 = v3;
return 0LL;
}
}
return 4294967294LL;
}

original_code:
int cstr2uint(char const * cstr, unsigned * uintptr)
{
 unsigned sum = 0;
 if(*cstr == 0)
  return -3;
 while(*cstr)
 {
  sum *= 10;
  unsigned digit = *cstr - '0';
  if(digit > 9)
   return -1;
  unsigned new_sum = sum + digit;
  if(new_sum < sum)
   return -2;
  sum = new_sum;
  cstr++;
 }
 *uintptr = sum;
 return 0;
}

canonical_original_code:
int cstr2uint(char *cstr, unsigned int *uintptr)
{
 unsigned int sum = 0;
 if(*cstr == 0)
  return -3;
 while(*cstr)
 {
  sum *= 10;
  unsigned int digit = *cstr - '0';
  if(digit > 9)
   return -1;
  unsigned int new_sum = sum + digit;
  if(new_sum < sum)
   return -2;
  sum = new_sum;
  cstr++;
 }
 *uintptr = sum;
 return 0;
}

variable_types:
cstr
char *

variable_types:
uintptr
unsigned int *

variable_types:
sum
unsigned int

variable_types:
digit
unsigned int

return_type: int


decompiled_code:
__int64 __fastcall cstr2int(char *a1, _DWORD *a2)
{
int v2; // ebx
__int64 result; // rax
unsigned int v4[5]; // [rsp+0h] [rbp-14h] BYREF

if ( !*a1 )
return 4294967293LL;
v2 = 1;
if ( *a1 == 45 )
{
++a1;
v2 = -1;
}
result = cstr2uint(a1, v4);
if ( (_DWORD)result )
return 0xFFFFFFFFLL;
if ( (v4[0] & 0x80000000) != 0 )
return 4294967294LL;
*a2 = v4[0] * v2;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(char *a1, _DWORD *a2)
{
int v2; // ebx
__int64 result; // rax
unsigned int v4[5]; // [rsp+0h] [rbp-14h] BYREF

if ( !*a1 )
return 4294967293LL;
v2 = 1;
if ( *a1 == 45 )
{
++a1;
v2 = -1;
}
result = func5(a1, v4);
if ( (_DWORD)result )
return 0xFFFFFFFFLL;
if ( (v4[0] & 0x80000000) != 0 )
return 4294967294LL;
*a2 = v4[0] * v2;
return result;
}

original_code:
int cstr2int(char const * cstr, int * intptr)
{
 if(*cstr == 0)
  return -3;
 int sign = 1;
 if(*cstr == '-')
 {
  sign = -1;
  cstr++;
 }
 unsigned magnitude;
 if(cstr2uint(cstr, &magnitude) != 0)
  return -1;
 int sum = (int)magnitude;
 if(sum < 0)
  return -2;
 *intptr = sum * sign;
 return 0;
}

canonical_original_code:
int cstr2int(char *cstr, int *intptr)
{
 if(*cstr == 0)
  return -3;
 int sign = 1;
 if(*cstr == '-')
 {
  sign = -1;
  cstr++;
 }
 unsigned int magnitude;
 if(cstr2uint(cstr, &magnitude) != 0)
  return -1;
 int sum = (int)magnitude;
 if(sum < 0)
  return -2;
 *intptr = sum * sign;
 return 0;
}

variable_types:
intptr
int *

variable_types: sign int

variable_types:
magnitude
unsigned int

variable_types: sum int


decompiled_code:
char *__fastcall cstr_dup(char *src)
{
char *v1; // rbp
int v2; // eax
char *v3; // rax

v1 = src;
if ( src )
{
v2 = strlen(src);
v3 = (char *)calloc((v2 + 4) & 0xFFFFFFFC, 1uLL);
v1 = v3;
if ( v3 )
strcpy(v3, src);
}
return v1;
}

canonical_decompiled_code:
char *__fastcall func7(char *src)
{
char *v1; // rbp
int v2; // eax
char *v3; // rax

v1 = src;
if ( src )
{
v2 = strlen(src);
v3 = (char *)calloc((v2 + 4) & 0xFFFFFFFC, 1uLL);
v1 = v3;
if ( v3 )
strcpy(v3, src);
}
return v1;
}

original_code:
char * cstr_dup(char const * src)
{
 char * new_str = ((void *)0);
 if(src)
 {
  unsigned len =
   (strlen(src) + sizeof(int)) / sizeof(int) * sizeof(int);
  new_str = calloc(len , 1);
  if(new_str)
   strcpy(new_str, src);
 }
 return new_str;
}

canonical_original_code:
char *cstr_dup(char *src)
{
 char *new_str = ((void *)0);
 if(src)
 {
  unsigned int len = (strlen(src) + sizeof(int)) / sizeof(int) * sizeof(int);
  new_str = calloc(len , 1);
  if(new_str)
   strcpy(new_str, src);
 }
 return new_str;
}

variable_types:
src
char *

variable_types:
len
unsigned int

return_type: char *


decompiled_code:
__int64 __fastcall is_whitespace(char a1)
{
return (a1 == 32) | (unsigned __int8)((unsigned __int8)(a1 - 9) <= 1u);
}

canonical_decompiled_code:
__int64 __fastcall func8(char a1)
{
return (a1 == 32) | (unsigned __int8)((unsigned __int8)(a1 - 9) <= 1u);
}

original_code:
int is_whitespace(char c)
{
 return (c == '\n') || (c == ' ') || (c == '\t');
}

variable_types: c char


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

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

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

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

original_code:
int is_int(char const * cstr)
{
 if(cstr == 0)
  return 0;
 if(*cstr == 0)
  return 0;
 for(int i = 0; cstr[i] == 0; i++)
 {
  if(cstr[i] < '0' || cstr[i] > '9')
  {
   if((i != 0) || (cstr[i] != '-' && cstr[i] != '+'))
    return 0;
  }
 }
 return 1;
}

canonical_original_code:
int is_int(char *cstr)
{
 if(cstr == 0)
  return 0;
 if(*cstr == 0)
  return 0;
 for(int i = 0; cstr[i] == 0; i++)
 {
  if(cstr[i] < '0' || cstr[i] > '9')
  {
   if((i != 0) || (cstr[i] != '-' && cstr[i] != '+'))
    return 0;
  }
 }
 return 1;
}

variable_types: i int


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

result = a1;
*(_DWORD *)a1 = a2;
*(_QWORD *)(a1 + 8) = 0LL;
*(_QWORD *)(a1 + 16) = 0LL;
return result;
}

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

result = a1;
*(_DWORD *)a1 = a2;
*(_QWORD *)(a1 + 8) = 0LL;
*(_QWORD *)(a1 + 16) = 0LL;
return result;
}

original_code:
static struct command command_new(enum command_type type)
{
 return (struct command){
  .type = type,
  .arg1 = ((void *)0),
  .arg2 = ((void *)0)
 };
}

return_type: struct command { enum command_type { COMMAND_NONE=0, COMMAND_SET_SECTION=1, COMMAND_INSERT_PAIR=2 } type; char *arg1; char *arg2; }

user_defined_types: struct command { enum command_type type; char *arg1; char *arg2; }


decompiled_code:
__int64 __fastcall entry_hash(char **a1)
{
char *v1; // rcx
char v2; // al
unsigned int v3; // edx

v1 = *a1;
v2 = **a1;
if ( !v2 )
return 0;
v3 = 0;
do
{
++v1;
v3 = v2 + 257 * v3;
v2 = *v1;
}
while ( *v1 );
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func1(char **a1)
{
char *v1; // rcx
char v2; // al
unsigned int v3; // edx

v1 = *a1;
v2 = **a1;
if ( !v2 )
return 0;
v3 = 0;
do
{
++v1;
v3 = v2 + 257 * v3;
v2 = *v1;
}
while ( *v1 );
return v3;
}

original_code:
static unsigned entry_hash(void const * a)
{
 unsigned sum = 0;
 char const * s = ((struct entry *)a)->name;
 while(*s)
  sum = (sum * 257) + *s++;
 return sum;
}

canonical_original_code:
static unsigned int entry_hash(void *a)
{
 unsigned int sum = 0;
 char *s = ((struct entry *)a)->name;
 while(*s)
  sum = (sum * 257) + *s++;
 return sum;
}

variable_types:
a
void *

variable_types:
s
char *

return_type: unsigned int


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

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

original_code:
static int entry_cmp(void const * a, void const * b)
{
 struct entry const * e1 = a;
 struct entry const * e2 = b;
 return strcmp(e1->name, e2->name);
}

canonical_original_code:
static int entry_cmp(void *a, void *b)
{
 struct entry *e1 = a;
 struct entry *e2 = b;
 return strcmp(e1->name, e2->name);
}

variable_types:
b
void *

variable_types: struct entry { char *name; void *val; } *


grow

original_code:
static int grow(struct hashset * hs)
{
 struct hashset bigger = *hs;
 bigger.size *= 2;
 if(bigger.size > hs->size)
 {
  bigger.buk = calloc(bigger.size, sizeof(void*));
  if(bigger.buk != ((void *)0))
  {
   for(unsigned i = 0; i < hs->size; i++)
   {
    while(hs->buk[i])
    {
     struct entry * top = hs->buk[i];
     hs->buk[i] = top->next;
     unsigned hash = (*hs->hash)(top->item);
     hash = ((hash) & ((bigger.size) - 1));
     top->next = bigger.buk[hash];
     bigger.buk[hash] = top;
    }
   }
   *hs = bigger;
   return 0;
  }
 }
 return -1;
}

canonical_original_code:
static int grow(struct hashset *hs)
{
 struct hashset bigger = *hs;
 bigger.size *= 2;
 if(bigger.size > hs->size)
 {
  bigger.buk = calloc(bigger.size, sizeof(void *));
  if(bigger.buk != ((void *)0))
  {
   for(unsigned int i = 0; i < hs->size; i++)
   {
    while(hs->buk[i])
    {
     struct entry *top = hs->buk[i];
     hs->buk[i] = top->next;
     unsigned int hash = (*hs->hash)(top->item);
     hash = ((hash) & ((bigger.size) - 1));
     top->next = bigger.buk[hash];
     bigger.buk[hash] = top;
    }
   }
   *hs = bigger;
   return 0;
  }
 }
 return -1;
}

variable_types: struct hashset { unsigned int size; unsigned int ele_size; unsigned int nitem; struct entry { struct entry *next; char item[1]; } **buk; int (*cmp)(void *, void *); unsigned int (*hash)(void *); } *

variable_types:
i
unsigned int

variable_types:
hash
unsigned int

user_defined_types: struct hashset { unsigned int size; unsigned int ele_size; unsigned int nitem; struct entry **buk; int (*cmp)(void *, void *); unsigned int (*hash)(void *); }


decompiled_code:
void __fastcall hashset_del(void *ptr)
{
char *v2; // r12
char *i; // rbp
_QWORD *j; // rdi

if ( ptr )
{
v2 = (char *)*((_QWORD *)ptr + 2);
if ( *(_DWORD *)ptr )
{
for ( i = &v2[8 * (*(_DWORD *)ptr - 1)]; ; i -= 8 )
{
for ( j = *(_QWORD **)i; *(_QWORD *)i; j = *(_QWORD **)i )
{
*(_QWORD *)i = *j;
free(j);
}
if ( i == v2 )
break;
}
}
free(v2);
free(ptr);
}
}

canonical_decompiled_code:
void __fastcall func1(void *ptr)
{
char *v2; // r12
char *i; // rbp
_QWORD *j; // rdi

if ( ptr )
{
v2 = (char *)*((_QWORD *)ptr + 2);
if ( *(_DWORD *)ptr )
{
for ( i = &v2[8 * (*(_DWORD *)ptr - 1)]; ; i -= 8 )
{
for ( j = *(_QWORD **)i; *(_QWORD *)i; j = *(_QWORD **)i )
{
*(_QWORD *)i = *j;
free(j);
}
if ( i == v2 )
break;
}
}
free(v2);
free(ptr);
}
}

original_code:
void hashset_del(struct hashset * hs)
{
 if(hs != ((void *)0))
 {
  struct entry ** buk = hs->buk;
  for(unsigned i = hs->size; i--;)
  {
   while(buk[i])
   {
    struct entry * deleted = buk[i];
    buk[i] = deleted->next;
    free(deleted);
   }
  }
  free(buk);
  hs->buk = ((void *)0);
  hs->nitem = 0;
  free(hs);
 }
}

canonical_original_code:
void hashset_del(struct hashset *hs)
{
 if(hs != ((void *)0))
 {
  struct entry **buk = hs->buk;
  for(unsigned int i = hs->size; i--;)
  {
   while(buk[i])
   {
    struct entry *deleted = buk[i];
    buk[i] = deleted->next;
    free(deleted);
   }
  }
  free(buk);
  hs->buk = ((void *)0);
  hs->nitem = 0;
  free(hs);
 }
}

variable_types: struct entry { struct entry *next; char item[1]; } **

return_type: void


decompiled_code:
__int64 __fastcall hashset_insert_s(__int64 a1, const void *a2, unsigned int a3)
{
int v4; // edx
__int64 result; // rax
size_t v6; // rbp
_QWORD *v7; // r14
unsigned int v8; // er13
_QWORD *v9; // rax

if ( (unsigned int)(2 * *(_DWORD *)(a1 + 8)) < *(_DWORD *)a1 )
{
v6 = a3;
v7 = calloc(1uLL, a3 + 8LL);
v8 = (*(__int64 (__fastcall **)(const void *))(a1 + 32))(a2) & (*(_DWORD *)a1 - 1);
memcpy(v7 + 1, a2, v6);
v9 = (_QWORD *)(*(_QWORD *)(a1 + 16) + 8LL * v8);
*v7 = *v9;
*v9 = v7;
++*(_DWORD *)(a1 + 8);
result = 0LL;
}
else
{
v4 = grow((unsigned int *)a1);
result = 1LL;
if ( !v4 )
result = hashset_insert_s(a1, a2, a3);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, const void *a2, unsigned int a3)
{
int v4; // edx
__int64 result; // rax
size_t v6; // rbp
_QWORD *v7; // r14
unsigned int v8; // er13
_QWORD *v9; // rax

if ( (unsigned int)(2 * *(_DWORD *)(a1 + 8)) < *(_DWORD *)a1 )
{
v6 = a3;
v7 = calloc(1uLL, a3 + 8LL);
v8 = (*(__int64 (__fastcall **)(const void *))(a1 + 32))(a2) & (*(_DWORD *)a1 - 1);
memcpy(v7 + 1, a2, v6);
v9 = (_QWORD *)(*(_QWORD *)(a1 + 16) + 8LL * v8);
*v7 = *v9;
*v9 = v7;
++*(_DWORD *)(a1 + 8);
result = 0LL;
}
else
{
v4 = func0((unsigned int *)a1);
result = 1LL;
if ( !v4 )
result = func2(a1, a2, a3);
}
return result;
}

original_code:
int hashset_insert_s(struct hashset * hs, void const * item, unsigned size)
{
 if(hs->nitem * 2 < hs->size)
 {
  struct entry * new_node = calloc(1, sizeof(void*) + size);
  unsigned i = (((*hs->hash)(item)) & ((hs->size) - 1));
  memcpy(new_node->item, item, size);
  new_node->next = hs->buk[i];
  hs->buk[i] = new_node;
  hs->nitem++;
  return 0;
 }
 else
 {
  if(grow(hs) == 0)
   return hashset_insert_s(hs, item, size);
  else
   return 1;
 }
}

canonical_original_code:
int hashset_insert_s(struct hashset *hs, void *item, unsigned int size)
{
 if(hs->nitem * 2 < hs->size)
 {
  struct entry *new_node = calloc(1, sizeof(void*) + size);
  unsigned int i = (((*hs->hash)(item)) & ((hs->size) - 1));
  memcpy(new_node->item, item, size);
  new_node->next = hs->buk[i];
  hs->buk[i] = new_node;
  hs->nitem++;
  return 0;
 }
 else
 {
  if(grow(hs) == 0)
   return hashset_insert_s(hs, item, size);
  else
   return 1;
 }
}

variable_types:
item
void *

variable_types:
size
unsigned int

variable_types: struct entry { struct entry *next; char item[1]; } *


decompiled_code:
__int64 __fastcall hashset_insert(__int64 a1, const void *a2)
{
return hashset_insert_s(a1, a2, *(_DWORD *)(a1 + 4));
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, const void *a2)
{
return func2(a1, a2, *(_DWORD *)(a1 + 4));
}

original_code:
int hashset_insert(struct hashset * hs, void const * item)
{
 return hashset_insert_s(hs, item, hs->ele_size);
}

canonical_original_code:
int hashset_insert(struct hashset *hs, void *item)
{
 return hashset_insert_s(hs, item, hs->ele_size);
}

user_defined_types: struct entry { struct entry *next; char item[1]; }


original_code:
int hashset_remove(struct hashset * hs, void const * item)
{
 unsigned i = (((*hs->hash)(item)) & ((hs->size) - 1));
 struct entry * iter = hs->buk[i];
 struct entry head = {.next = iter};
 struct entry * prev = &head;
 while(iter)
 {
  if(0 != (*hs->cmp)(item, iter->item))
  {
   prev = iter;
   iter = iter->next;
  }
  else
  {
   prev->next = iter->next;
   hs->buk[i] = head.next;
   free(iter);
   hs->nitem--;
   return 0;
  }
 }
 return -1;
}

canonical_original_code:
int hashset_remove(struct hashset *hs, void *item)
{
 unsigned int i = (((*hs->hash)(item)) & ((hs->size) - 1));
 struct entry *iter = hs->buk[i];
 struct entry head = {.next = iter};
 struct entry *prev = &head;
 while(iter)
 {
  if(0 != (*hs->cmp)(item, iter->item))
  {
   prev = iter;
   iter = iter->next;
  }
  else
  {
   prev->next = iter->next;
   hs->buk[i] = head.next;
   free(iter);
   hs->nitem--;
   return 0;
  }
 }
 return -1;
}

variable_types: struct entry { struct entry *next; char item[1]; }


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

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

original_code:
void hashset_iter_del(struct hashset_iter * iter)
{
 free(iter);
}

canonical_original_code:
void hashset_iter_del(struct hashset_iter *iter)
{
 free(iter);
}

variable_types: struct hashset_iter { struct hashset { unsigned int size; unsigned int ele_size; unsigned int nitem; struct entry { struct entry *next; char item[1]; } **buk; int (*cmp)(void *, void *); unsigned int (*hash)(void *); } *hs; struct entry *current; struct entry *next; int i; } *

user_defined_types: struct hashset_iter { struct hashset *hs; struct entry *current; struct entry *next; int i; }


original_code:
int hashset_iter_next(struct hashset_iter * iter)
{
 if(iter->next == ((void *)0))
 {
  struct entry ** buk = iter->hs->buk;
  unsigned size = iter->hs->size;
  for(unsigned i = iter->i + 1; i < size; i++)
  {
   if(buk[i] != ((void *)0))
   {
    iter->i = i;
    iter->next = buk[i];
    break;
   }
  }
  if(iter->next == ((void *)0))
   return 0;
 }
 iter->current = iter->next;
 iter->next = iter->next->next;
 return 1;
}

canonical_original_code:
int hashset_iter_next(struct hashset_iter *iter)
{
 if(iter->next == ((void *)0))
 {
  struct entry **buk = iter->hs->buk;
  unsigned int size = iter->hs->size;
  for(unsigned int i = iter->i + 1; i < size; i++)
  {
   if(buk[i] != ((void *)0))
   {
    iter->i = i;
    iter->next = buk[i];
    break;
   }
  }
  if(iter->next == ((void *)0))
   return 0;
 }
 iter->current = iter->next;
 iter->next = iter->next->next;
 return 1;
}


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

if ( !a1 )
return 0LL;
result = *(_QWORD *)(a1 + 8);
if ( result )
result += 8LL;
return result;
}

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

if ( !a1 )
return 0LL;
result = *(_QWORD *)(a1 + 8);
if ( result )
result += 8LL;
return result;
}

original_code:
void const * hashset_iter_get(struct hashset_iter * iter)
{
 if(iter != ((void *)0) && iter->current != ((void *)0))
  return iter->current->item;
 else
  return ((void *)0);
}

canonical_original_code:
void *hashset_iter_get(struct hashset_iter *iter)
{
 if(iter != ((void *)0) && iter->current != ((void *)0))
  return iter->current->item;
 else
  return ((void *)0);
}

return_type: void *


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

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

original_code:
static struct token token_new(enum token_type type)
{
 return (struct token){
  .type = type,
  .text = ((void *)0)
 };
}

return_type: struct token { enum token_type { TOKEN_TYPE_SECTION=0, TOKEN_TYPE_NAME=1, TOKEN_TYPE_ASSIGNMENT=2, TOKEN_TYPE_STRING=3, TOKEN_TYPE_NEWLINE=4, TOKEN_TYPE_END=5 } type; char *text; }

user_defined_types: struct token { enum token_type type; char *text; }


init

decompiled_code:
__int64 init()
{
__int64 result; // rax

bot = (__int64)&arena;
arena = 0LL;
qword_4040A8 = (__int64)&qword_414090;
qword_414090 = (__int64)&arena;
qword_414098 = 0LL;
result = (unsigned int)((_DWORD)&qword_414090 + 1);
LODWORD(qword_4040A8) = (_DWORD)&qword_414090 + 1;
return result;
}

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

bot = (__int64)&arena;
arena = 0LL;
qword_4040A8 = (__int64)&qword_414090;
qword_414090 = (__int64)&arena;
qword_414098 = 0LL;
result = (unsigned int)((_DWORD)&qword_414090 + 1);
LODWORD(qword_4040A8) = (_DWORD)&qword_414090 + 1;
return result;
}

original_code:
static void init(void)
{
  bot = &arena[0]; top = &arena[(65536/sizeof(CHUNK))-1];
  bot->s.l = 0; bot->s.r = top;
  top->s.l = bot; top->s.r = 0;
  ( *(unsigned *)&(bot)->s.r |= 0x1 ); ( *(unsigned *)&(top)->s.r &= ~0x1 );
}

canonical_original_code:
static void init()
{
  bot = &arena[0]; top = &arena[(65536/sizeof(CHUNK))-1];
  bot->s.l = 0; bot->s.r = top;
  top->s.l = bot; top->s.r = 0;
  ( *(unsigned int *)&(bot)->s.r |= 0x1 ); ( *(unsigned int *)&(top)->s.r &= ~0x1 );
}


tmalloc

decompiled_code:
__int64 __fastcall tmalloc(unsigned int a1)
{
__int64 v1; // rdx
unsigned int v2; // esi
unsigned int v3; // eax
__int64 v4; // rax
unsigned int v5; // ecx
__int64 **v6; // rcx
__int64 *v7; // rax
__int64 result; // rax

v1 = bot;
if ( bot )
{
v2 = 16 * ((((unsigned __int64)a1 + 15) >> 4) + 1);
LABEL_6:
while ( 1 )
{
v4 = *(_QWORD *)(v1 + 8);
if ( (v4 & 1) != 0 )
{
v5 = (v4 & 0xFFFFFFFE) - v1;
if ( v5 >= v2 )
break;
}
v3 = v4 & 0xFFFFFFFE;
v1 = v3;
if ( !v3 )
goto LABEL_11;
}
if ( v5 > v2 )
{
*(_DWORD *)(v1 + 8) &= 0xFFFFFFFE;
v6 = *(__int64 ***)(v1 + 8);
v7 = (__int64 *)(v1 + ((unsigned int)v6 & 0xFFFFFFFE) - (unsigned int)v1 - (unsigned __int64)v2);
*v7 = v1;
v7[1] = (__int64)v6;
*(_QWORD *)(v1 + 8) = v7;
*v6 = v7;
*(_DWORD *)(v1 + 8) |= 1u;
v1 = (__int64)v7;
}
*(_DWORD *)(v1 + 8) &= 0xFFFFFFFE;
result = v1 + 16;
}
else
{
init();
v1 = bot;
if ( bot )
{
v2 = 16 * ((((unsigned __int64)a1 + 15) >> 4) + 1);
goto LABEL_6;
}
LABEL_11:
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(unsigned int a1)
{
__int64 v1; // rdx
unsigned int v2; // esi
unsigned int v3; // eax
__int64 v4; // rax
unsigned int v5; // ecx
__int64 **v6; // rcx
__int64 *v7; // rax
__int64 result; // rax

v1 = bot;
if ( bot )
{
v2 = 16 * ((((unsigned __int64)a1 + 15) >> 4) + 1);
LABEL_6:
while ( 1 )
{
v4 = *(_QWORD *)(v1 + 8);
if ( (v4 & 1) != 0 )
{
v5 = (v4 & 0xFFFFFFFE) - v1;
if ( v5 >= v2 )
break;
}
v3 = v4 & 0xFFFFFFFE;
v1 = v3;
if ( !v3 )
goto LABEL_11;
}
if ( v5 > v2 )
{
*(_DWORD *)(v1 + 8) &= 0xFFFFFFFE;
v6 = *(__int64 ***)(v1 + 8);
v7 = (__int64 *)(v1 + ((unsigned int)v6 & 0xFFFFFFFE) - (unsigned int)v1 - (unsigned __int64)v2);
*v7 = v1;
v7[1] = (__int64)v6;
*(_QWORD *)(v1 + 8) = v7;
*v6 = v7;
*(_DWORD *)(v1 + 8) |= 1u;
v1 = (__int64)v7;
}
*(_DWORD *)(v1 + 8) &= 0xFFFFFFFE;
result = v1 + 16;
}
else
{
func9();
v1 = bot;
if ( bot )
{
v2 = 16 * ((((unsigned __int64)a1 + 15) >> 4) + 1);
goto LABEL_6;
}
LABEL_11:
result = 0LL;
}
return result;
}

original_code:
void *tmalloc(unsigned nbytes)
{
  CHUNK *p;
  unsigned size;
  if (bot == 0)
    init();
  size = sizeof(CHUNK) * ((nbytes+sizeof(CHUNK)-1)/sizeof(CHUNK) + 1);
  for (p = bot; p != 0; p = ((CHUNK *)(~0x1 & (unsigned)(p)->s.r)))
    if (( (unsigned)(p)->s.r & 0x1 ) && ((unsigned)((CHUNK *)(~0x1 & (unsigned)((p))->s.r)) - (unsigned)(p)) >= size)
      break;
  if (p == 0)
    return 0;
  if (((unsigned)((CHUNK *)(~0x1 & (unsigned)((p))->s.r)) - (unsigned)(p)) > size)
    {
      CHUNK *q, *pr;
      ( *(unsigned *)&(p)->s.r &= ~0x1 );
      q = (CHUNK *)((char *)p + ((unsigned)((CHUNK *)(~0x1 & (unsigned)((p))->s.r)) - (unsigned)(p)) - size);
      pr = p->s.r;
      q->s.l = p; q->s.r = pr;
      p->s.r = q; pr->s.l = q;
      ( *(unsigned *)&(p)->s.r |= 0x1 );
      p = q;
    }
  ( *(unsigned *)&(p)->s.r &= ~0x1 );
  return ((void *)(1 + (p)));
}

canonical_original_code:
void *tmalloc(unsigned int nbytes)
{
  union CHUNK_TAG *p;
  unsigned int size;
  if (bot == 0)
    init();
  size = sizeof(CHUNK) * ((nbytes+sizeof(CHUNK)-1)/sizeof(CHUNK) + 1);
  for (p = bot; p != 0; p = ((union CHUNK_TAG *)(~0x1 & (unsigned int)(p)->s.r)))
    if (( (unsigned int)(p)->s.r & 0x1 ) && ((unsigned int)((union CHUNK_TAG *)(~0x1 & (unsigned int)((p))->s.r)) - (unsigned int)(p)) >= size)
      break;
  if (p == 0)
    return 0;
  if (((unsigned int)((union CHUNK_TAG *)(~0x1 & (unsigned int)((p))->s.r)) - (unsigned int)(p)) > size)
    {
      union CHUNK_TAG *q; union CHUNK_TAG *pr;
      ( *(unsigned int *)&(p)->s.r &= ~0x1 );
      q = (union CHUNK_TAG *)((char *)p + ((unsigned int)((union CHUNK_TAG *)(~0x1 & (unsigned int)((p))->s.r)) - (unsigned int)(p)) - size);
      pr = p->s.r;
      q->s.l = p; q->s.r = pr;
      p->s.r = q; pr->s.l = q;
      ( *(unsigned int *)&(p)->s.r |= 0x1 );
      p = q;
    }
  ( *(unsigned int *)&(p)->s.r &= ~0x1 );
  return ((void *)(1 + (p)));
}

variable_types:
nbytes
unsigned int

variable_types: union CHUNK_TAG { struct { union CHUNK_TAG *l; union CHUNK_TAG *r; } s; double x; } *


tfree

canonical_original_code:
void tfree(void *vp)
{
  union CHUNK_TAG *p; union CHUNK_TAG *q;
  if (vp == 0)
    return;
  p = (-1 + (union CHUNK_TAG *)(vp));
  ( *(unsigned int *)&(p)->s.r &= ~0x1 );
  q = p->s.l;
  if (q != 0 && ( (unsigned int)(q)->s.r & 0x1 ))
    {
      ( *(unsigned int *)&(q)->s.r &= ~0x1 );
      q->s.r = p->s.r;
      p->s.r->s.l = q;
      ( *(unsigned int *)&(q)->s.r |= 0x1 );
      p = q;
    }
  q = ((union CHUNK_TAG *)(~0x1 & (unsigned int)(p)->s.r));
  if (q != 0 && ( (unsigned int)(q)->s.r & 0x1 ))
    {
      ( *(unsigned int *)&(q)->s.r &= ~0x1 );
      p->s.r = q->s.r;
      q->s.r->s.l = p;
      ( *(unsigned int *)&(q)->s.r |= 0x1 );
    }
  ( *(unsigned int *)&(p)->s.r |= 0x1 );
}

variable_types:
vp
void *

user_defined_types: union CHUNK_TAG { struct { union CHUNK_TAG *l; union CHUNK_TAG *r; } s; double x; }


trealloc

decompiled_code:
void *__fastcall trealloc(void *src, size_t n)
{
void *v2; // rax
void *v3; // r12
unsigned int v4; // edx

if ( !src )
return (void *)tmalloc(n);
if ( !(_DWORD)n )
{
v3 = 0LL;
LABEL_9:
tfree((__int64)src);
return v3;
}
v2 = (void *)tmalloc(n);
v3 = v2;
if ( v2 )
{
v4 = (*((_DWORD *)src - 2) & 0xFFFFFFFE) - (_DWORD)src;
if ( (unsigned int)n <= v4 )
v4 = n;
memcpy(v2, src, v4);
goto LABEL_9;
}
return v3;
}

canonical_decompiled_code:
void *__fastcall func12(void *src, size_t n)
{
void *v2; // rax
void *v3; // r12
unsigned int v4; // edx

if ( !src )
return (void *)func10(n);
if ( !(_DWORD)n )
{
v3 = 0LL;
LABEL_9:
func11((__int64)src);
return v3;
}
v2 = (void *)func10(n);
v3 = v2;
if ( v2 )
{
v4 = (*((_DWORD *)src - 2) & 0xFFFFFFFE) - (_DWORD)src;
if ( (unsigned int)n <= v4 )
v4 = n;
memcpy(v2, src, v4);
goto LABEL_9;
}
return v3;
}

original_code:
void *trealloc(void *vp, unsigned newbytes)
{
  void *newp = 0;
  if (vp == 0)
    return tmalloc(newbytes);
  if (newbytes != 0)
    {
      CHUNK *oldchunk;
      unsigned bytes;
      if ( (newp = tmalloc(newbytes)) == 0)
        return 0;
      oldchunk = (-1 + (CHUNK *)(vp));
      bytes = ((unsigned)((CHUNK *)(~0x1 & (unsigned)((oldchunk))->s.r)) - (unsigned)(oldchunk)) - sizeof(CHUNK);
      if (bytes > newbytes)
        bytes = newbytes;
      memcpy(newp, vp, bytes);
    }
  tfree(vp);
  return newp;
}

canonical_original_code:
void *trealloc(void *vp, unsigned int newbytes)
{
  void *newp = 0;
  if (vp == 0)
    return tmalloc(newbytes);
  if (newbytes != 0)
    {
      union CHUNK_TAG *oldchunk;
      unsigned int bytes;
      if ( (newp = tmalloc(newbytes)) == 0)
        return 0;
      oldchunk = (-1 + (union CHUNK_TAG *)(vp));
      bytes = ((unsigned int)((union CHUNK_TAG *)(~0x1 & (unsigned int)((oldchunk))->s.r)) - (unsigned int)(oldchunk)) - sizeof(CHUNK);
      if (bytes > newbytes)
        bytes = newbytes;
      memcpy(newp, vp, bytes);
    }
  tfree(vp);
  return newp;
}

variable_types:
newbytes
unsigned int

variable_types:
newp
void *

variable_types:
bytes
unsigned int


tcalloc

decompiled_code:
void *__fastcall tcalloc(int a1, int a2)
{
void *v2; // rax
void *v3; // rbp

v2 = (void *)tmalloc(a2 * a1);
v3 = v2;
if ( v2 )
memset(v2, 0, (unsigned int)(a2 * a1));
return v3;
}

canonical_decompiled_code:
void *__fastcall func13(int a1, int a2)
{
void *v2; // rax
void *v3; // rbp

v2 = (void *)func10(a2 * a1);
v3 = v2;
if ( v2 )
memset(v2, 0, (unsigned int)(a2 * a1));
return v3;
}

original_code:
void *tcalloc(unsigned nelem, unsigned elsize)
{
  void *vp;
  unsigned nbytes;
  nbytes = nelem * elsize;
  if ( (vp = tmalloc(nbytes)) == 0)
    return 0;
  memset(vp, '\0', nbytes);
  return vp;
}

canonical_original_code:
void *tcalloc(unsigned int nelem, unsigned int elsize)
{
  void *vp;
  unsigned int nbytes;
  nbytes = nelem * elsize;
  if ( (vp = tmalloc(nbytes)) == 0)
    return 0;
  memset(vp, '\0', nbytes);
  return vp;
}

variable_types:
nelem
unsigned int

variable_types:
elsize
unsigned int


nstrcpy

decompiled_code:
size_t __fastcall nstrcpy(__int64 a1, int a2, const char *a3)
{
size_t result; // rax
__int64 v5; // rcx

result = strlen(a3);
if ( (int)result > a2 )
result = (unsigned int)a2;
if ( (result & 0x80000000) == 0LL )
{
v5 = (unsigned int)(result + 1);
result = 0LL;
do
{
*(_BYTE *)(a1 + result) = a3[result];
++result;
}
while ( result != v5 );
}
return result;
}

canonical_decompiled_code:
size_t __fastcall func7(__int64 a1, int a2, const char *a3)
{
size_t result; // rax
__int64 v5; // rcx

result = strlen(a3);
if ( (int)result > a2 )
result = (unsigned int)a2;
if ( (result & 0x80000000) == 0LL )
{
v5 = (unsigned int)(result + 1);
result = 0LL;
do
{
*(_BYTE *)(a1 + result) = a3[result];
++result;
}
while ( result != v5 );
}
return result;
}

original_code:
void nstrcpy(char *out, int outl, char *in)
{
  int i, len;
  len = strlen(in);
  if (len > outl)
    len = outl;
  for (i = 0; i <= len; i++)
    out[i] = in[i];
}

canonical_original_code:
void nstrcpy(char *out, int outl, char *in)
{
  int i; int len;
  len = strlen(in);
  if (len > outl)
    len = outl;
  for (i = 0; i <= len; i++)
    out[i] = in[i];
}

variable_types:
out
char *

variable_types: outl int

variable_types:
in
char *

variable_types: i int

variable_types: len int


bar

decompiled_code:
size_t __fastcall bar(const char *a1)
{
__int64 v2; // [rsp+0h] [rbp-D8h] BYREF

return nstrcpy((__int64)&v2, 200, a1);
}

canonical_decompiled_code:
size_t __fastcall func8(const char *a1)
{
__int64 v2; // [rsp+0h] [rbp-D8h] BYREF

return func7((__int64)&v2, 200, a1);
}

original_code:
void bar(char *arg)
{
  char buf[200];
  nstrcpy(buf, sizeof buf, arg);
}

variable_types:
arg
char *

variable_types:
buf
char [200]


foo

decompiled_code:
size_t __fastcall foo(const char *a1)
{
return bar(a1);
}

canonical_decompiled_code:
size_t __fastcall func9(const char *a1)
{
return func8(a1);
}

original_code:
void foo(char *arg)
{
  bar(arg);
}

canonical_original_code:
void foo(char *arg)
{
  bar(arg);
}


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
if ( argc != 2 )
{
fwrite("target2: argc != 2\n", 1uLL, 0x13uLL, _bss_start);
exit(1);
}
foo(argv[1]);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
if ( argc != 2 )
{
fwrite("target2: argc != 2\n", 1uLL, 0x13uLL, _bss_start);
exit(1);
}
func9(argv[1]);
return 0;
}

original_code:
int main(int argc, char *argv[])
{
  if (argc != 2)
    {
      fprintf(stderr, "target2: argc != 2\n");
      exit(1);
    }
  foo(argv[1]);
  return 0;
}

variable_types: argc int

variable_types:
argv
char *[]


multimerge

repo: umbrant/extsort

decompiled_code:
void __fastcall multimerge(void **a1, const char *a2, int a3, int a4, int a5)
{
void *v6; // rsp
__int64 v7; // r15
__int64 i; // rbx
_QWORD *v9; // r12
int v10; // er13
void *v11; // rsp
void *v12; // rsp
void *v13; // rsp
void *v14; // rsp
int v15; // er8
int v16; // er9
__int64 v17; // rax
int v18; // edx
int v19; // ebx
int v20; // edi
int v21; // esi
__int64 v22; // rax
int v23; // eax
ssize_t v24; // rax
_DWORD *v25; // r12
int v26; // ecx
unsigned __int64 v27; // rbx
unsigned int v28; // edx
__int64 v29; // rdx
_DWORD *v30; // rcx
int *v31; // r12
int v32; // eax
int v33; // eax
unsigned __int64 v34; // rax
void **v35; // rbx
__int64 v36; // r12
ssize_t v37; // [rsp+0h] [rbp-A0h] BYREF
int v38; // [rsp+Ch] [rbp-94h]
int fd; // [rsp+10h] [rbp-90h]
int v40; // [rsp+14h] [rbp-8Ch]
const char *v41; // [rsp+18h] [rbp-88h]
__int64 *v42; // [rsp+20h] [rbp-80h]
int v43; // [rsp+28h] [rbp-78h]
int v44; // [rsp+2Ch] [rbp-74h]
void **v45; // [rsp+30h] [rbp-70h]
int v46; // [rsp+38h] [rbp-68h]
int v47; // [rsp+3Ch] [rbp-64h]
void *buf; // [rsp+40h] [rbp-60h]
signed __int64 v49; // [rsp+48h] [rbp-58h]
char s[80]; // [rsp+50h] [rbp-50h] BYREF

v41 = a2;
v47 = a3;
v40 = a4;
v43 = a5;
v49 = 4LL * a3;
v6 = alloca(v49);
v42 = &v37;
if ( a5 )
{
v13 = alloca(v49);
v14 = alloca(v49);
buf = malloc((unsigned int)(IO_BUF_PAGES << 12));
if ( v47 > 0 )
goto LABEL_7;
LABEL_42:
v19 = 0;
goto LABEL_43;
}
if ( a3 <= 0 )
{
buf = malloc((unsigned int)(IO_BUF_PAGES << 12));
goto LABEL_42;
}
v7 = (unsigned int)a3;
for ( i = 0LL; i != v7; ++i )
{
v9 = calloc(1uLL, 0x10uLL);
a1[i] = v9;
v9[1] = calloc(1uLL, (unsigned int)(IO_BUF_PAGES << 12));
snprintf(s, 0x14uLL, "%s%d.dat", v41, (unsigned int)i);
v10 = open(s, 0);
LODWORD(v9) = read(v10, *((void **)a1[i] + 1), (unsigned int)(IO_BUF_PAGES << 12));
close(v10);
*(_DWORD *)a1[i] = (unsigned __int64)(int)v9 >> 2;
*((_DWORD *)v42 + i) = (_DWORD)v9;
}
v11 = alloca(v49);
v12 = alloca(v49);
buf = malloc((unsigned int)(IO_BUF_PAGES << 12));
LABEL_7:
v15 = v47;
v16 = v47;
v17 = 0LL;
do
{
*((_DWORD *)&v37 + v17) = 0;
v18 = 0;
if ( *(int *)a1[v17] <= 0 )
{
--v16;
v18 = 1;
}
*((_DWORD *)&v37 + v17++) = v18;
}
while ( v15 > (int)v17 );
v46 = v16;
if ( v16 <= 0 )
{
v19 = 0;
}
else
{
v19 = 0;
v44 = v47 - 1;
do
{
if ( v47 <= 0 )
{
LODWORD(v49) = -1;
}
else
{
v22 = 0LL;
v21 = 0;
v20 = -13;
LODWORD(v49) = -1;
while ( 1 )
{
if ( !*((_DWORD *)&v37 + v22)
&& (!v21 || *(_DWORD *)(*((_QWORD *)a1[v22] + 1) + 4LL * *((int *)&v37 + v22)) < v20) )
{
v20 = *(_DWORD *)(*((_QWORD *)a1[v22] + 1) + 4LL * *((int *)&v37 + v22));
LODWORD(v49) = v22;
v21 = 1;
}
if ( v22 == v44 )
break;
++v22;
}
}
v29 = (int)v49;
v45 = &a1[(int)v49];
v30 = *v45;
v31 = (int *)&v37 + (int)v49;
v32 = *v31;
*((_DWORD *)buf + v19) = *(_DWORD *)(*((_QWORD *)*v45 + 1) + 4LL * *v31);
v33 = v32 + 1;
*v31 = v33;
if ( !*((_DWORD *)&v37 + v29) && v33 == *v30 )
{
if ( v43 )
{
*((_DWORD *)&v37 + v29) = 1;
--v46;
}
else
{
snprintf(s, 0x14uLL, "%s%d.dat", v41, (unsigned int)v49);
v23 = open(s, 0);
v38 = *((_DWORD *)v42 + (int)v49);
fd = v23;
lseek(v23, v38, 0);
v24 = read(fd, *((void **)*v45 + 1), (unsigned int)(IO_BUF_PAGES << 12));
v37 = v24;
if ( (int)v24 <= 0 )
{
*((_DWORD *)&v37 + (int)v49) = 1;
--v46;
}
else
{
*v31 = 0;
*(_DWORD *)*v45 = (unsigned __int64)(int)v24 >> 2;
}
close(fd);
*((_DWORD *)v42 + (int)v49) = v37 + v38;
}
}
++v19;
v28 = IO_BUF_PAGES << 12;
v34 = (unsigned int)(IO_BUF_PAGES << 12) >> 2;
if ( v19 == v34 )
{
v25 = buf;
v26 = *(_DWORD *)buf;
if ( v34 > 1 )
{
v27 = 1LL;
do
{
if ( v25[v27] < v26 )
printf("Error at index %d\n", (unsigned int)v27);
v26 = v25[v27];
v28 = IO_BUF_PAGES << 12;
++v27;
}
while ( (unsigned int)(IO_BUF_PAGES << 12) >> 2 > v27 );
}
v19 = 0;
if ( IO_BUF_PAGES << 12 != (unsigned int)write(v40, buf, v28) )
perror("Write size mismatch!\n");
}
}
while ( v46 > 0 );
}
LABEL_43:
if ( 4LL * v19 != (int)write(v40, buf, 4LL * v19) )
perror("Write size mismatch!\n");
if ( !v43 && v47 > 0 )
{
v35 = a1;
v36 = (__int64)&a1[(unsigned int)(v47 - 1) + 1];
do
{
free(*((void **)*v35 + 1));
free(*v35++);
}
while ( v35 != (void **)v36 );
}
free(buf);
}

canonical_decompiled_code:
void __fastcall func0(void **a1, const char *a2, int a3, int a4, int a5)
{
void *v6; // rsp
__int64 v7; // r15
__int64 i; // rbx
_QWORD *v9; // r12
int v10; // er13
void *v11; // rsp
void *v12; // rsp
void *v13; // rsp
void *v14; // rsp
int v15; // er8
int v16; // er9
__int64 v17; // rax
int v18; // edx
int v19; // ebx
int v20; // edi
int v21; // esi
__int64 v22; // rax
int v23; // eax
ssize_t v24; // rax
_DWORD *v25; // r12
int v26; // ecx
unsigned __int64 v27; // rbx
unsigned int v28; // edx
__int64 v29; // rdx
_DWORD *v30; // rcx
int *v31; // r12
int v32; // eax
int v33; // eax
unsigned __int64 v34; // rax
void **v35; // rbx
__int64 v36; // r12
ssize_t v37; // [rsp+0h] [rbp-A0h] BYREF
int v38; // [rsp+Ch] [rbp-94h]
int fd; // [rsp+10h] [rbp-90h]
int v40; // [rsp+14h] [rbp-8Ch]
const char *v41; // [rsp+18h] [rbp-88h]
__int64 *v42; // [rsp+20h] [rbp-80h]
int v43; // [rsp+28h] [rbp-78h]
int v44; // [rsp+2Ch] [rbp-74h]
void **v45; // [rsp+30h] [rbp-70h]
int v46; // [rsp+38h] [rbp-68h]
int v47; // [rsp+3Ch] [rbp-64h]
void *buf; // [rsp+40h] [rbp-60h]
signed __int64 v49; // [rsp+48h] [rbp-58h]
char s[80]; // [rsp+50h] [rbp-50h] BYREF

v41 = a2;
v47 = a3;
v40 = a4;
v43 = a5;
v49 = 4LL * a3;
v6 = alloca(v49);
v42 = &v37;
if ( a5 )
{
v13 = alloca(v49);
v14 = alloca(v49);
buf = malloc((unsigned int)(IO_BUF_PAGES << 12));
if ( v47 > 0 )
goto LABEL_7;
LABEL_42:
v19 = 0;
goto LABEL_43;
}
if ( a3 <= 0 )
{
buf = malloc((unsigned int)(IO_BUF_PAGES << 12));
goto LABEL_42;
}
v7 = (unsigned int)a3;
for ( i = 0LL; i != v7; ++i )
{
v9 = calloc(1uLL, 0x10uLL);
a1[i] = v9;
v9[1] = calloc(1uLL, (unsigned int)(IO_BUF_PAGES << 12));
snprintf(s, 0x14uLL, "%s%d.dat", v41, (unsigned int)i);
v10 = open(s, 0);
LODWORD(v9) = read(v10, *((void **)a1[i] + 1), (unsigned int)(IO_BUF_PAGES << 12));
close(v10);
*(_DWORD *)a1[i] = (unsigned __int64)(int)v9 >> 2;
*((_DWORD *)v42 + i) = (_DWORD)v9;
}
v11 = alloca(v49);
v12 = alloca(v49);
buf = malloc((unsigned int)(IO_BUF_PAGES << 12));
LABEL_7:
v15 = v47;
v16 = v47;
v17 = 0LL;
do
{
*((_DWORD *)&v37 + v17) = 0;
v18 = 0;
if ( *(int *)a1[v17] <= 0 )
{
--v16;
v18 = 1;
}
*((_DWORD *)&v37 + v17++) = v18;
}
while ( v15 > (int)v17 );
v46 = v16;
if ( v16 <= 0 )
{
v19 = 0;
}
else
{
v19 = 0;
v44 = v47 - 1;
do
{
if ( v47 <= 0 )
{
LODWORD(v49) = -1;
}
else
{
v22 = 0LL;
v21 = 0;
v20 = -13;
LODWORD(v49) = -1;
while ( 1 )
{
if ( !*((_DWORD *)&v37 + v22)
&& (!v21 || *(_DWORD *)(*((_QWORD *)a1[v22] + 1) + 4LL * *((int *)&v37 + v22)) < v20) )
{
v20 = *(_DWORD *)(*((_QWORD *)a1[v22] + 1) + 4LL * *((int *)&v37 + v22));
LODWORD(v49) = v22;
v21 = 1;
}
if ( v22 == v44 )
break;
++v22;
}
}
v29 = (int)v49;
v45 = &a1[(int)v49];
v30 = *v45;
v31 = (int *)&v37 + (int)v49;
v32 = *v31;
*((_DWORD *)buf + v19) = *(_DWORD *)(*((_QWORD *)*v45 + 1) + 4LL * *v31);
v33 = v32 + 1;
*v31 = v33;
if ( !*((_DWORD *)&v37 + v29) && v33 == *v30 )
{
if ( v43 )
{
*((_DWORD *)&v37 + v29) = 1;
--v46;
}
else
{
snprintf(s, 0x14uLL, "%s%d.dat", v41, (unsigned int)v49);
v23 = open(s, 0);
v38 = *((_DWORD *)v42 + (int)v49);
fd = v23;
lseek(v23, v38, 0);
v24 = read(fd, *((void **)*v45 + 1), (unsigned int)(IO_BUF_PAGES << 12));
v37 = v24;
if ( (int)v24 <= 0 )
{
*((_DWORD *)&v37 + (int)v49) = 1;
--v46;
}
else
{
*v31 = 0;
*(_DWORD *)*v45 = (unsigned __int64)(int)v24 >> 2;
}
close(fd);
*((_DWORD *)v42 + (int)v49) = v37 + v38;
}
}
++v19;
v28 = IO_BUF_PAGES << 12;
v34 = (unsigned int)(IO_BUF_PAGES << 12) >> 2;
if ( v19 == v34 )
{
v25 = buf;
v26 = *(_DWORD *)buf;
if ( v34 > 1 )
{
v27 = 1LL;
do
{
if ( v25[v27] < v26 )
printf("Error at index %d\n", (unsigned int)v27);
v26 = v25[v27];
v28 = IO_BUF_PAGES << 12;
++v27;
}
while ( (unsigned int)(IO_BUF_PAGES << 12) >> 2 > v27 );
}
v19 = 0;
if ( IO_BUF_PAGES << 12 != (unsigned int)write(v40, buf, v28) )
perror("Write size mismatch!\n");
}
}
while ( v46 > 0 );
}
LABEL_43:
if ( 4LL * v19 != (int)write(v40, buf, 4LL * v19) )
perror("Write size mismatch!\n");
if ( !v43 && v47 > 0 )
{
v35 = a1;
v36 = (__int64)&a1[(unsigned int)(v47 - 1) + 1];
do
{
free(*((void **)*v35 + 1));
free(*v35++);
}
while ( v35 != (void **)v36 );
}
free(buf);
}

original_code:
void multimerge(run_t** runs, char* input_prefix, int num_runs, int output_fd, int base)
{
    int run_offsets[num_runs];
    char filename[20];
    if(base == 0) {
        ;
        for(int i=0; i<num_runs; i++) {
            runs[i] = (run_t*)calloc(1, sizeof(run_t));
            runs[i]->items = (int*)calloc(1, IO_BUF_PAGES*(4*(1<<10)));
            snprintf(filename, 20, "%s%d.dat", input_prefix, i);
            int fd = open(filename, 00);
            int bytes = read(fd, runs[i]->items, IO_BUF_PAGES*(4*(1<<10)));
            close(fd);
            runs[i]->length = bytes/sizeof(int);
            run_offsets[i] = bytes;
        }
    }
    int idx[num_runs];
    int skip[num_runs];
    int* output = (int*)malloc(IO_BUF_PAGES*(4*(1<<10)));
    int output_idx = 0;
    int live_runs = num_runs;
    for(int i=0; i<num_runs; i++) {
        idx[i] = 0;
        if(runs[i]->length > 0) {
            skip[i] = 0;
        } else {
            skip[i] = 1;
            live_runs--;
        }
    }
    while(live_runs > 0) {
        int init = 0;
        int min = -13;
        int min_run = -1;
        for(int j=0; j<num_runs; j++) {
            if(!skip[j]) {
                if(!init || runs[j]->items[idx[j]] < min) {
                    min_run = j;
                    min = runs[j]->items[idx[j]];
                    init = 1;
                }
            }
        }
        output[output_idx] = runs[min_run]->items[idx[min_run]];
        idx[min_run]++;
        if(!skip[min_run] && idx[min_run] == runs[min_run]->length) {
            if(base) {
                skip[min_run] = 1;
                live_runs--;
            } else {
                snprintf(filename, 20, "%s%d.dat", input_prefix, min_run);
                int fd = open(filename, 00);
                lseek(fd, run_offsets[min_run], 0);
                int bytes = read(fd, runs[min_run]->items, IO_BUF_PAGES*(4*(1<<10)));
                if(bytes > 0) {
                    idx[min_run] = 0;
                    runs[min_run]->length = bytes / sizeof(int);
                } else {
                    skip[min_run] = 1;
                    live_runs--;
                }
                close(fd);
                run_offsets[min_run] += bytes;
            }
        }
        output_idx++;
        if(output_idx == IO_BUF_PAGES*(4*(1<<10))/sizeof(int)) {
            int check = output[0];
            for(int j=1; j<IO_BUF_PAGES*(4*(1<<10))/sizeof(int); j++) {
                if(output[j] < check) {
                    printf("Error at index %d\n", j);
                }
                check = output[j];
            }
            int rv = write(output_fd, output, IO_BUF_PAGES*(4*(1<<10)));
            if(rv != IO_BUF_PAGES*(4*(1<<10))) {
                perror("Write size mismatch!\n");
            }
            output_idx = 0;
        }
    }
    int bytes = write(output_fd, output, output_idx*sizeof(int));
    if(bytes != output_idx*sizeof(int)) {
        perror("Write size mismatch!\n");
    }
    if(base == 0) {
        for(int i=0; i<num_runs; i++) {
            free(runs[i]->items);
            free(runs[i]);
        }
    }
    free(output);
}

canonical_original_code:
void multimerge(struct run_t **runs, char *input_prefix, int num_runs, int output_fd, int base)
{
    int run_offsets[-1];
    char filename[20];
    if(base == 0) {
        ;
        for(int i = 0; i<num_runs; i++) {
            runs[i] = (struct run_t *)calloc(1, sizeof(run_t));
            runs[i]->items = (int *)calloc(1, IO_BUF_PAGES*(4*(1<<10)));
            snprintf(filename, 20, "%s%d.dat", input_prefix, i);
            int fd = open(filename, 00);
            int bytes = read(fd, runs[i]->items, IO_BUF_PAGES*(4*(1<<10)));
            close(fd);
            runs[i]->length = bytes/sizeof(int);
            run_offsets[i] = bytes;
        }
    }
    int idx[-1];
    int skip[-1];
    int *output = (int*)malloc(IO_BUF_PAGES*(4*(1<<10)));
    int output_idx = 0;
    int live_runs = num_runs;
    for(int i = 0; i<num_runs; i++) {
        idx[i] = 0;
        if(runs[i]->length > 0) {
            skip[i] = 0;
        } else {
            skip[i] = 1;
            live_runs--;
        }
    }
    while(live_runs > 0) {
        int init = 0;
        int min = -13;
        int min_run = -1;
        for(int j = 0; j<num_runs; j++) {
            if(!skip[j]) {
                if(!init || runs[j]->items[idx[j]] < min) {
                    min_run = j;
                    min = runs[j]->items[idx[j]];
                    init = 1;
                }
            }
        }
        output[output_idx] = runs[min_run]->items[idx[min_run]];
        idx[min_run]++;
        if(!skip[min_run] && idx[min_run] == runs[min_run]->length) {
            if(base) {
                skip[min_run] = 1;
                live_runs--;
            } else {
                snprintf(filename, 20, "%s%d.dat", input_prefix, min_run);
                int fd = open(filename, 00);
                lseek(fd, run_offsets[min_run], 0);
                int bytes = read(fd, runs[min_run]->items, IO_BUF_PAGES*(4*(1<<10)));
                if(bytes > 0) {
                    idx[min_run] = 0;
                    runs[min_run]->length = bytes / sizeof(int);
                } else {
                    skip[min_run] = 1;
                    live_runs--;
                }
                close(fd);
                run_offsets[min_run] += bytes;
            }
        }
        output_idx++;
        if(output_idx == IO_BUF_PAGES*(4*(1<<10))/sizeof(int)) {
            int check = output[0];
            for(int j = 1; j<IO_BUF_PAGES*(4*(1<<10))/sizeof(int); j++) {
                if(output[j] < check) {
                    printf("Error at index %d\n", j);
                }
                check = output[j];
            }
            int rv = write(output_fd, output, IO_BUF_PAGES*(4*(1<<10)));
            if(rv != IO_BUF_PAGES*(4*(1<<10))) {
                perror("Write size mismatch!\n");
            }
            output_idx = 0;
        }
    }
    int bytes = write(output_fd, output, output_idx*sizeof(int));
    if(bytes != output_idx*sizeof(int)) {
        perror("Write size mismatch!\n");
    }
    if(base == 0) {
        for(int i = 0; i<num_runs; i++) {
            free(runs[i]->items);
            free(runs[i]);
        }
    }
    free(output);
}

variable_types: struct run_t { int length; int *items; } **

variable_types: base int

variable_types:
filename
char [20]

variable_types: fd int

variable_types: bytes int

variable_types:
idx
int [-1]

variable_types:
skip
int [-1]

variable_types:
output
int *

variable_types: init int

variable_types: min int

variable_types: j int

variable_types: check int

variable_types: rv int


usage

decompiled_code:
void __noreturn usage()
{
puts("extsort <filename> <buffer_size_mb> <io_buf_pages>");
puts("\tfilename: filename of file to be sorted");
puts("\tbuffer_size_mb: MBs of buffer to use for sorting");
puts("\tio_buf_pages: number of 4k pages to use for per-run IO buffering");
exit(1);
}

canonical_decompiled_code:
void __noreturn func1()
{
puts("extsort <filename> <buffer_size_mb> <io_buf_pages>");
puts("\tfilename: filename of file to be sorted");
puts("\tbuffer_size_mb: MBs of buffer to use for sorting");
puts("\tio_buf_pages: number of 4k pages to use for per-run IO buffering");
exit(1);
}

original_code:
void usage()
{
    printf("extsort <filename> <buffer_size_mb> <io_buf_pages>\n");
    printf("\tfilename: filename of file to be sorted\n");
    printf("\tbuffer_size_mb: MBs of buffer to use for sorting\n");
    printf("\tio_buf_pages: number of 4k pages to use for per-run IO buffering\n");
    exit(1);
}


error

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

canonical_decompiled_code:
void __fastcall __noreturn func2(const char *a1)
{
perror(a1);
exit(-1);
}

original_code:
void error(const char* msg)
{
    perror(msg);
    exit(-1);
}

canonical_original_code:
void error(char *msg)
{
    perror(msg);
    exit(-1);
}

variable_types:
msg
char *


verify

decompiled_code:
void __fastcall verify(char *file)
{
int v1; // ebp
int v2; // er14
void *v3; // r12
int v4; // ebx
__int64 v5; // r15
unsigned __int64 v6; // rax
unsigned __int64 v7; // rsi
unsigned __int64 v8; // rdx
size_t nbytes; // [rsp+0h] [rbp-D8h]
int v10; // [rsp+8h] [rbp-D0h]
int fd; // [rsp+Ch] [rbp-CCh]
struct stat buf; // [rsp+10h] [rbp-C8h] BYREF

printf("Verifying sort (%s)...\n", file);
fd = open(file, 0);
if ( fstat(fd, &buf) )
error("Could not fstat file!");
v1 = 0;
v2 = buf.st_size / (IO_BUF_PAGES << 12) - ((buf.st_size % (IO_BUF_PAGES << 12) == 0) - 1);
nbytes = IO_BUF_PAGES << 12;
v3 = calloc(1uLL, nbytes);
if ( v2 <= 0 )
{
v5 = 0LL;
LABEL_19:
printf("Correctly sorted! %lu ints.\n", v5);
goto LABEL_17;
}
v10 = 0;
v4 = 0;
v5 = 0LL;
do
{
v7 = (int)read(fd, v3, nbytes);
v8 = v7 >> 2;
if ( v7 > 3 )
{
v6 = 0LL;
do
{
if ( v4 )
{
if ( *((_DWORD *)v3 + v6) >= v1 )
{
v1 = *((_DWORD *)v3 + v6);
}
else
{
v1 = *((_DWORD *)v3 + v6);
v10 = v4;
}
}
else
{
v1 = *((_DWORD *)v3 + v6);
}
++v6;
v4 = 1;
}
while ( v6 < v8 );
v5 += v8;
}
--v2;
}
while ( v2 );
if ( !v10 )
goto LABEL_19;
printf("Incorrect sort of %lu ints.\n", v5);
LABEL_17:
free(v3);
}

canonical_decompiled_code:
void __fastcall func3(char *file)
{
int v1; // ebp
int v2; // er14
void *v3; // r12
int v4; // ebx
__int64 v5; // r15
unsigned __int64 v6; // rax
unsigned __int64 v7; // rsi
unsigned __int64 v8; // rdx
size_t nbytes; // [rsp+0h] [rbp-D8h]
int v10; // [rsp+8h] [rbp-D0h]
int fd; // [rsp+Ch] [rbp-CCh]
struct stat buf; // [rsp+10h] [rbp-C8h] BYREF

printf("Verifying sort (%s)...\n", file);
fd = open(file, 0);
if ( fstat(fd, &buf) )
func2("Could not fstat file!");
v1 = 0;
v2 = buf.st_size / (IO_BUF_PAGES << 12) - ((buf.st_size % (IO_BUF_PAGES << 12) == 0) - 1);
nbytes = IO_BUF_PAGES << 12;
v3 = calloc(1uLL, nbytes);
if ( v2 <= 0 )
{
v5 = 0LL;
LABEL_19:
printf("Correctly sorted! %lu ints.\n", v5);
goto LABEL_17;
}
v10 = 0;
v4 = 0;
v5 = 0LL;
do
{
v7 = (int)read(fd, v3, nbytes);
v8 = v7 >> 2;
if ( v7 > 3 )
{
v6 = 0LL;
do
{
if ( v4 )
{
if ( *((_DWORD *)v3 + v6) >= v1 )
{
v1 = *((_DWORD *)v3 + v6);
}
else
{
v1 = *((_DWORD *)v3 + v6);
v10 = v4;
}
}
else
{
v1 = *((_DWORD *)v3 + v6);
}
++v6;
v4 = 1;
}
while ( v6 < v8 );
v5 += v8;
}
--v2;
}
while ( v2 );
if ( !v10 )
goto LABEL_19;
printf("Incorrect sort of %lu ints.\n", v5);
LABEL_17:
free(v3);
}

original_code:
void verify(char* filename)
{
    printf("Verifying sort (%s)...\n", filename);
    int input_fd = open(filename, 00);
    struct stat s;
    int rv = fstat(input_fd, &s);
    if(rv) {
        error("Could not fstat file!");
    }
    int buf_size = IO_BUF_PAGES*(4*(1<<10));
    int num_runs = s.st_size / (buf_size);
    if(s.st_size % buf_size) {
        num_runs++;
    }
    int* buf = (int*)calloc(1, buf_size);
    int current = 0;
    int init = 0;
    int error = 0;
    unsigned long count = 0;
    while(num_runs > 0) {
        int bytes = read(input_fd, buf, buf_size);
        for(int i=0; i<bytes/sizeof(int); i++) {
            if(!init) {
                current = buf[i];
                init = 1;
            }
            if(buf[i] < current) {
                error = 1;
            }
            current = buf[i];
            count++;
        }
        num_runs--;
    }
    if(error) {
        printf("Incorrect sort of %lu ints.\n", count);
    } else {
        printf("Correctly sorted! %lu ints.\n", count);
    }
    free(buf);
}

canonical_original_code:
void verify(char *filename)
{
    printf("Verifying sort (%s)...\n", filename);
    int input_fd = open(filename, 00);
    struct stat s;
    int rv = fstat(input_fd, &s);
    if(rv) {
        error("Could not fstat file!");
    }
    int buf_size = IO_BUF_PAGES*(4*(1<<10));
    int num_runs = s.st_size / (buf_size);
    if(s.st_size % buf_size) {
        num_runs++;
    }
    int *buf = (int*)calloc(1, buf_size);
    int current = 0;
    int init = 0;
    int error = 0;
    unsigned long count = 0;
    while(num_runs > 0) {
        int bytes = read(input_fd, buf, buf_size);
        for(int i = 0; i<bytes/sizeof(int); i++) {
            if(!init) {
                current = buf[i];
                init = 1;
            }
            if(buf[i] < current) {
                error = 1;
            }
            current = buf[i];
            count++;
        }
        num_runs--;
    }
    if(error) {
        printf("Incorrect sort of %lu ints.\n", count);
    } else {
        printf("Correctly sorted! %lu ints.\n", count);
    }
    free(buf);
}

variable_types:
filename
char *

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

variable_types:
buf
int *

variable_types: current int

variable_types: error int

variable_types:
count
unsigned long

variable_types: i int

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


decompiled_code:
__suseconds_t get_time_usecs()
{
struct timezone tz; // [rsp+8h] [rbp-20h] BYREF
struct timeval tv; // [rsp+10h] [rbp-18h] BYREF

tz = 0LL;
gettimeofday(&tv, &tz);
return tv.tv_usec + 1000000 * tv.tv_sec;
}

canonical_decompiled_code:
__suseconds_t func4()
{
struct timezone tz; // [rsp+8h] [rbp-20h] BYREF
struct timeval tv; // [rsp+10h] [rbp-18h] BYREF

tz = 0LL;
gettimeofday(&tv, &tz);
return tv.tv_usec + 1000000 * tv.tv_sec;
}

original_code:
long get_time_usecs()
{
    struct timeval time;
    struct timezone tz;
    memset(&tz, '\0', sizeof(timezone));
    gettimeofday(&time, &tz);
    long usecs = time.tv_sec*1000000 + time.tv_usec;
    return usecs;
}

variable_types: struct timeval { long tv_sec; long tv_usec; }

variable_types: struct timezone { int tz_minuteswest; int tz_dsttime; }

variable_types: usecs long

return_type: long


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char *v3; // rbp
unsigned __int64 v4; // rbx
char *v5; // r15
size_t v6; // rbp
int v7; // ebx
unsigned __int64 v8; // rbx
size_t v9; // r14
void **v10; // rax
void **v11; // r13
__int64 i; // r12
void *v13; // rbp
void *v14; // rax
int v15; // eax
unsigned __int64 v16; // rax
unsigned __int64 v17; // rdi
unsigned __int64 v18; // rax
int v19; // ebx
int v21; // ebp
int v22; // ebp
void **v23; // rbp
__int64 v24; // [rsp+8h] [rbp-120h]
unsigned __int64 v25; // [rsp+10h] [rbp-118h]
unsigned int v26; // [rsp+1Ch] [rbp-10Ch]
size_t nmemb; // [rsp+20h] [rbp-108h]
unsigned __int64 v28; // [rsp+28h] [rbp-100h]
unsigned __int64 v29; // [rsp+30h] [rbp-F8h]
int v30; // [rsp+40h] [rbp-E8h]
int fd; // [rsp+44h] [rbp-E4h]
int v32; // [rsp+48h] [rbp-E0h]
char src[5]; // [rsp+56h] [rbp-D2h] BYREF
char dest[5]; // [rsp+5Bh] [rbp-CDh] BYREF
struct stat buf; // [rsp+60h] [rbp-C8h] BYREF

if ( argc != 4 )
{
printf("Invalid number of arguments (%d)\n", (unsigned int)argc);
usage();
}
DATA_FILENAME = (char *)argv[1];
v3 = DATA_FILENAME;
BUF_SIZE = atoi(argv[2]) << 20;
IO_BUF_PAGES = atoi(argv[3]);
fd = open(v3, 0);
if ( fd < 0 )
error("Could not open sort_fd!");
if ( fstat(fd, &buf) )
{
puts(DATA_FILENAME);
error("Could not fstat file!");
}
v4 = buf.st_size;
v5 = (char *)calloc(1uLL, 0x64uLL);
v25 = (v4 >> 12) - (((v4 & 0xFFF) == 0) - 1LL);
printf("Sorting %lu ints (%.02f MB)...\n", v25 << 12 >> 2, (double)(int)v25 * 4096.0 * 0.00000095367431640625);
strcpy(dest, "foo_");
strcpy(src, "bar_");
v32 = get_time_usecs();
if ( v25 > 1 )
{
v30 = 1;
while ( 1 )
{
printf("Iterate: %lu runs left\n", v25);
v16 = ((unsigned __int64)BUF_SIZE >> 12) / (unsigned int)IO_BUF_PAGES - 1;
if ( v16 > v25 )
v16 = v25;
v17 = v16;
nmemb = v16;
v18 = v25 / v16;
v28 = v25 % v17;
v25 = v25 / v17 - ((v25 % v17 == 0) - 1LL);
if ( !v25 )
break;
v29 = v17 * v18;
v24 = 1LL;
v8 = 0LL;
while ( 1 )
{
v26 = v24 - 1;
printf("Merge %d of %lu (%lu ways)\n", (unsigned int)v24, v25, nmemb);
v9 = v28;
if ( v29 > v8 )
v9 = nmemb;
v10 = (void **)calloc(v9, 8uLL);
v11 = v10;
if ( v30 == 1 )
{
if ( v9 )
{
for ( i = 0LL; i != v9; ++i )
{
v13 = calloc(1uLL, 0x10uLL);
v11[i] = v13;
v14 = calloc(1uLL, 0x1000uLL);
*((_QWORD *)v13 + 1) = v14;
v15 = read(fd, v14, 0x1000uLL);
*(_DWORD *)v11[i] = (unsigned __int64)v15 >> 2;
if ( !v15 )
break;
}
v8 += v9;
parallel_qsort(v11, (unsigned int)v9);
snprintf(v5, 0x64uLL, "%s%d.dat", src, v26);
v22 = open(v5, 577, 504LL);
multimerge(v11, dest, v9, v22, 1);
close(v22);
v23 = v11;
do
{
free(*((void **)*v23 + 1));
free(*v23++);
}
while ( &v11[v9] != v23 );
}
else
{
parallel_qsort(v10, 0LL);
snprintf(v5, 0x64uLL, "%s%d.dat", src, v26);
v21 = open(v5, 577, 504LL);
multimerge(v11, dest, 0, v21, 1);
close(v21);
}
}
else
{
v6 = v9 + v8;
if ( v9 )
{
do
snprintf(v5, 0x64uLL, "%s%lu.dat", dest, v8++);
while ( v8 != v6 );
}
else
{
v6 = v8;
}
snprintf(v5, 0x64uLL, "%s%d.dat", src, v26);
v7 = open(v5, 577, 504LL);
multimerge(v11, dest, v9, v7, 0);
close(v7);
v8 = v6;
}
free(v11);
if ( v25 == v24 )
break;
++v24;
}
strcpy(v5, src);
strcpy(src, dest);
strcpy(dest, v5);
v30 *= (_DWORD)nmemb;
if ( v25 <= 1 )
goto LABEL_30;
}
strcpy(v5, src);
strcpy(src, dest);
strcpy(dest, v5);
}
LABEL_30:
v19 = get_time_usecs();
puts("Done sorting.");
printf("Sorting took %.02f seconds.\n", (double)(v19 - v32) / 1000000.0);
free(v5);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
const char *v3; // rbp
unsigned __int64 v4; // rbx
char *v5; // r15
size_t v6; // rbp
int v7; // ebx
unsigned __int64 v8; // rbx
size_t v9; // r14
void **v10; // rax
void **v11; // r13
__int64 i; // r12
void *v13; // rbp
void *v14; // rax
int v15; // eax
unsigned __int64 v16; // rax
unsigned __int64 v17; // rdi
unsigned __int64 v18; // rax
int v19; // ebx
int v21; // ebp
int v22; // ebp
void **v23; // rbp
__int64 v24; // [rsp+8h] [rbp-120h]
unsigned __int64 v25; // [rsp+10h] [rbp-118h]
unsigned int v26; // [rsp+1Ch] [rbp-10Ch]
size_t nmemb; // [rsp+20h] [rbp-108h]
unsigned __int64 v28; // [rsp+28h] [rbp-100h]
unsigned __int64 v29; // [rsp+30h] [rbp-F8h]
int v30; // [rsp+40h] [rbp-E8h]
int fd; // [rsp+44h] [rbp-E4h]
int v32; // [rsp+48h] [rbp-E0h]
char src[5]; // [rsp+56h] [rbp-D2h] BYREF
char dest[5]; // [rsp+5Bh] [rbp-CDh] BYREF
struct stat buf; // [rsp+60h] [rbp-C8h] BYREF

if ( argc != 4 )
{
printf("Invalid number of arguments (%d)\n", (unsigned int)argc);
func1();
}
DATA_FILENAME = (char *)argv[1];
v3 = DATA_FILENAME;
BUF_SIZE = atoi(argv[2]) << 20;
IO_BUF_PAGES = atoi(argv[3]);
fd = open(v3, 0);
if ( fd < 0 )
func2("Could not open sort_fd!");
if ( fstat(fd, &buf) )
{
puts(DATA_FILENAME);
func2("Could not fstat file!");
}
v4 = buf.st_size;
v5 = (char *)calloc(1uLL, 0x64uLL);
v25 = (v4 >> 12) - (((v4 & 0xFFF) == 0) - 1LL);
printf("Sorting %lu ints (%.02f MB)...\n", v25 << 12 >> 2, (double)(int)v25 * 4096.0 * 0.00000095367431640625);
strcpy(dest, "foo_");
strcpy(src, "bar_");
v32 = func4();
if ( v25 > 1 )
{
v30 = 1;
while ( 1 )
{
printf("Iterate: %lu runs left\n", v25);
v16 = ((unsigned __int64)BUF_SIZE >> 12) / (unsigned int)IO_BUF_PAGES - 1;
if ( v16 > v25 )
v16 = v25;
v17 = v16;
nmemb = v16;
v18 = v25 / v16;
v28 = v25 % v17;
v25 = v25 / v17 - ((v25 % v17 == 0) - 1LL);
if ( !v25 )
break;
v29 = v17 * v18;
v24 = 1LL;
v8 = 0LL;
while ( 1 )
{
v26 = v24 - 1;
printf("Merge %d of %lu (%lu ways)\n", (unsigned int)v24, v25, nmemb);
v9 = v28;
if ( v29 > v8 )
v9 = nmemb;
v10 = (void **)calloc(v9, 8uLL);
v11 = v10;
if ( v30 == 1 )
{
if ( v9 )
{
for ( i = 0LL; i != v9; ++i )
{
v13 = calloc(1uLL, 0x10uLL);
v11[i] = v13;
v14 = calloc(1uLL, 0x1000uLL);
*((_QWORD *)v13 + 1) = v14;
v15 = read(fd, v14, 0x1000uLL);
*(_DWORD *)v11[i] = (unsigned __int64)v15 >> 2;
if ( !v15 )
break;
}
v8 += v9;
parallel_qsort(v11, (unsigned int)v9);
snprintf(v5, 0x64uLL, "%s%d.dat", src, v26);
v22 = open(v5, 577, 504LL);
func0(v11, dest, v9, v22, 1);
close(v22);
v23 = v11;
do
{
free(*((void **)*v23 + 1));
free(*v23++);
}
while ( &v11[v9] != v23 );
}
else
{
parallel_qsort(v10, 0LL);
snprintf(v5, 0x64uLL, "%s%d.dat", src, v26);
v21 = open(v5, 577, 504LL);
func0(v11, dest, 0, v21, 1);
close(v21);
}
}
else
{
v6 = v9 + v8;
if ( v9 )
{
do
snprintf(v5, 0x64uLL, "%s%lu.dat", dest, v8++);
while ( v8 != v6 );
}
else
{
v6 = v8;
}
snprintf(v5, 0x64uLL, "%s%d.dat", src, v26);
v7 = open(v5, 577, 504LL);
func0(v11, dest, v9, v7, 0);
close(v7);
v8 = v6;
}
free(v11);
if ( v25 == v24 )
break;
++v24;
}
strcpy(v5, src);
strcpy(src, dest);
strcpy(dest, v5);
v30 *= (_DWORD)nmemb;
if ( v25 <= 1 )
goto LABEL_30;
}
strcpy(v5, src);
strcpy(src, dest);
strcpy(dest, v5);
}
LABEL_30:
v19 = func4();
puts("Done sorting.");
printf("Sorting took %.02f seconds.\n", (double)(v19 - v32) / 1000000.0);
free(v5);
return 0;
}

original_code:
int main(int argc, char* argv[])
{
    if(argc != 4) {
        printf("Invalid number of arguments (%d)\n", argc);
        usage();
    }
    DATA_FILENAME = argv[1];
    BUF_SIZE = atoi(argv[2])*(1<<20);
    IO_BUF_PAGES = atoi(argv[3]);
    int sort_fd = open(DATA_FILENAME, 00);
    if(sort_fd < 0) {
        error("Could not open sort_fd!");
    }
    struct stat s;
    int rv = fstat(sort_fd, &s);
    if(rv) {
        printf("%s\n", DATA_FILENAME);
        error("Could not fstat file!");
    }
    DATA_SIZE = s.st_size;
    char* filename = (char*)calloc(1, 100);
    int run_length = 1;
    unsigned long num_runs = DATA_SIZE / (4*(1<<10));
    if(DATA_SIZE % (4*(1<<10))) {
        num_runs++;
    }
    printf("Sorting %lu ints (%.02f MB)...\n",
            num_runs*(4*(1<<10))/sizeof(int),
            (double)num_runs*(4*(1<<10)) / (1<<20));
    char input_prefix[] = "foo_";
    char output_prefix[] = "bar_";
    long start_usecs = get_time_usecs();
    while(num_runs > 1) {
        printf("Iterate: %lu runs left\n", num_runs);
        unsigned long num_ways = ((BUF_SIZE / (4*(1<<10))) / IO_BUF_PAGES) - 1;
        if(num_ways > num_runs) {
            num_ways = num_runs;
        }
        unsigned long num_merges = num_runs / num_ways;
        if(num_runs % num_ways) {
            num_merges++;
        }
        unsigned long run_counter = 0;
        for(int i=0; i<num_merges; i++) {
            printf("Merge %d of %lu (%lu ways)\n", i+1, num_merges, num_ways);
            unsigned long num_runs_in_merge = num_ways;
            if(run_counter >= (num_runs/num_ways)*num_ways) {
                num_runs_in_merge = num_runs % num_ways;
            }
            run_t** runs = (run_t**)calloc(num_runs_in_merge, sizeof(run_t*));
            if(run_length == 1) {
                ;
                for(int i=0; i<num_runs_in_merge; i++) {
                    runs[i] = (run_t*)calloc(1, sizeof(run_t));
                    runs[i]->items = (int*)calloc(1, (4*(1<<10)));
                    int bytes = read(sort_fd, runs[i]->items, (4*(1<<10)));
                    runs[i]->length = bytes/sizeof(int);
                    if(bytes == 0) {
                        break;
                    }
                }
                run_counter += num_runs_in_merge;
                ;
                parallel_qsort(runs, num_runs_in_merge);
                ;
            }
            else {
                for(int i=0; i<num_runs_in_merge; i++) {
                    snprintf(filename, 100, "%s%lu.dat", input_prefix, run_counter);
                    ;
                    run_counter++;
                }
            }
            snprintf(filename, 100, "%s%d.dat", output_prefix, i);
            ;
            int output_fd = open(filename, 0100|01|01000,
                    (0400|0200|0100)|((0400|0200|0100) >> 3));
            int base = 0;
            if(run_length == 1) {
                base = 1;
            }
            multimerge(runs, input_prefix, num_runs_in_merge, output_fd, base);
            close(output_fd);
            if(base == 1) {
                for(int i=0; i<num_runs_in_merge; i++) {
                    free(runs[i]->items);
                    free(runs[i]);
                }
            }
            free(runs);
        }
        strcpy(filename, output_prefix);
        strcpy(output_prefix, input_prefix);
        strcpy(input_prefix, filename);
        run_length *= num_ways;
        num_runs = num_merges;
    }
    long end_usecs = get_time_usecs();
    double secs = (double)(end_usecs - start_usecs) / (double)1000000;
    printf("Done sorting.\n");
    printf("Sorting took %.02f seconds.\n", secs);
    free(filename);
    return 0;
}

canonical_original_code:
int main(int argc, char *argv[])
{
    if(argc != 4) {
        printf("Invalid number of arguments (%d)\n", argc);
        usage();
    }
    DATA_FILENAME = argv[1];
    BUF_SIZE = atoi(argv[2])*(1<<20);
    IO_BUF_PAGES = atoi(argv[3]);
    int sort_fd = open(DATA_FILENAME, 00);
    if(sort_fd < 0) {
        error("Could not open sort_fd!");
    }
    struct stat s;
    int rv = fstat(sort_fd, &s);
    if(rv) {
        printf("%s\n", DATA_FILENAME);
        error("Could not fstat file!");
    }
    DATA_SIZE = s.st_size;
    char *filename = (char*)calloc(1, 100);
    int run_length = 1;
    unsigned long num_runs = DATA_SIZE / (4*(1<<10));
    if(DATA_SIZE % (4*(1<<10))) {
        num_runs++;
    }
    printf("Sorting %lu ints (%.02f MB)...\n",
            num_runs*(4*(1<<10))/sizeof(int),
            (double)num_runs*(4*(1<<10)) / (1<<20));
    char input_prefix[] = "foo_";
    char output_prefix[] = "bar_";
    long start_usecs = get_time_usecs();
    while(num_runs > 1) {
        printf("Iterate: %lu runs left\n", num_runs);
        unsigned long num_ways = ((BUF_SIZE / (4*(1<<10))) / IO_BUF_PAGES) - 1;
        if(num_ways > num_runs) {
            num_ways = num_runs;
        }
        unsigned long num_merges = num_runs / num_ways;
        if(num_runs % num_ways) {
            num_merges++;
        }
        unsigned long run_counter = 0;
        for(int i = 0; i<num_merges; i++) {
            printf("Merge %d of %lu (%lu ways)\n", i+1, num_merges, num_ways);
            unsigned long num_runs_in_merge = num_ways;
            if(run_counter >= (num_runs/num_ways)*num_ways) {
                num_runs_in_merge = num_runs % num_ways;
            }
            struct run_t **runs = (run_t**)calloc(num_runs_in_merge, sizeof(run_t*));
            if(run_length == 1) {
                ;
                for(int i = 0; i<num_runs_in_merge; i++) {
                    runs[i] = (struct run_t *)calloc(1, sizeof(run_t));
                    runs[i]->items = (int *)calloc(1, (4*(1<<10)));
                    int bytes = read(sort_fd, runs[i]->items, (4*(1<<10)));
                    runs[i]->length = bytes/sizeof(int);
                    if(bytes == 0) {
                        break;
                    }
                }
                run_counter += num_runs_in_merge;
                ;
                parallel_qsort(runs, num_runs_in_merge);
                ;
            }
            else {
                for(int i = 0; i<num_runs_in_merge; i++) {
                    snprintf(filename, 100, "%s%lu.dat", input_prefix, run_counter);
                    ;
                    run_counter++;
                }
            }
            snprintf(filename, 100, "%s%d.dat", output_prefix, i);
            ;
            int output_fd = open(filename, 0100|01|01000,
                    (0400|0200|0100)|((0400|0200|0100) >> 3));
            int base = 0;
            if(run_length == 1) {
                base = 1;
            }
            multimerge(runs, input_prefix, num_runs_in_merge, output_fd, base);
            close(output_fd);
            if(base == 1) {
                for(int i = 0; i<num_runs_in_merge; i++) {
                    free(runs[i]->items);
                    free(runs[i]);
                }
            }
            free(runs);
        }
        strcpy(filename, output_prefix);
        strcpy(output_prefix, input_prefix);
        strcpy(input_prefix, filename);
        run_length *= num_ways;
        num_runs = num_merges;
    }
    long end_usecs = get_time_usecs();
    double secs = (double)(end_usecs - start_usecs) / (double)1000000;
    printf("Done sorting.\n");
    printf("Sorting took %.02f seconds.\n", secs);
    free(filename);
    return 0;
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types: struct run_t { int length; int *items; } **

variable_types: bytes int

variable_types: base int

variable_types: secs double

user_defined_types: struct timespec { long tv_sec; long tv_nsec; }


partition

original_code:
static int partition(run_t* data_ptr, int left, int right, int pivot_index)
{
    int pivot_value = data_ptr->items[pivot_index];
    swap(data_ptr, pivot_index, right);
    int store_index = left;
    int i;
    for(i=left; i<right; i++) {
        if(data_ptr->items[i] <= pivot_value) {
            swap(data_ptr, store_index, i);
            store_index++;
        }
        for(int i=0; i<data_ptr->length; i++) {
        }
    }
    swap(data_ptr, store_index, right);
    return store_index;
}

canonical_original_code:
static int partition(struct run_t *data_ptr, int left, int right, int pivot_index)
{
    int pivot_value = data_ptr->items[pivot_index];
    swap(data_ptr, pivot_index, right);
    int store_index = left;
    int i;
    for(i=left; i<right; i++) {
        if(data_ptr->items[i] <= pivot_value) {
            swap(data_ptr, store_index, i);
            store_index++;
        }
        for(int i = 0; i<data_ptr->length; i++) {
        }
    }
    swap(data_ptr, store_index, right);
    return store_index;
}

variable_types: struct run_t { int length; int *items; } *

variable_types: left int

variable_types: right int


bubble

decompiled_code:
__int64 __fastcall bubble(__int64 a1, int a2, int a3)
{
int v3; // er14
int i; // ebp
__int64 v5; // rax
int v6; // edx
__int64 v7; // rbx
__int64 result; // rax
int v10; // [rsp+Ch] [rbp-34h]

if ( a3 != a2 && a3 >= a2 )
{
v3 = a3 - 1;
v10 = a2 + a3 - 1;
do
{
v7 = 4LL * a2;
for ( i = a2; i <= v3; ++i )
{
v5 = *(_QWORD *)(a1 + 8);
v6 = *(_DWORD *)(v5 + v7);
v7 += 4LL;
if ( v6 > *(_DWORD *)(v5 + v7) )
swap(a1, i, i + 1);
}
--v3;
result = (unsigned int)(v10 - v3);
}
while ( a3 >= (int)result );
}
return result;
}

original_code:
static void bubble(run_t* data_ptr, int left, int right)
{
    int i,j;
    if(right == left) {
        return;
    }
    for(i=left; i<=right; i++) {
        for(j=left; j<=right-1-(i-left); j++) {
            if(data_ptr->items[j] > data_ptr->items[j+1]) {
                swap(data_ptr, j, j+1);
            }
        }
    }
}

canonical_original_code:
static void bubble(struct run_t *data_ptr, int left, int right)
{
    int i; int j;
    if(right == left) {
        return;
    }
    for(i=left; i<=right; i++) {
        for(j=left; j<=right-1-(i-left); j++) {
            if(data_ptr->items[j] > data_ptr->items[j+1]) {
                swap(data_ptr, j, j+1);
            }
        }
    }
}

variable_types: j int

user_defined_types: struct run_t { int length; int *items; }


decompiled_code:
void __fastcall qsort_recurse(__int64 a1, unsigned int a2, unsigned int a3)
{
unsigned int v4; // er13
unsigned int v5; // er14

if ( (int)a3 > (int)a2 )
{
if ( (int)(a3 - a2) <= 4 )
{
bubble(a1, a2, a3);
}
else
{
v4 = partition(a1, a2, a3, (int)(a3 + a2) / 2);
v5 = v4 - 1;
if ( (int)(v4 - 1 - a2) >= (int)(a3 - v4) )
{
qsort_recurse(a1, v4, a3);
qsort_recurse(a1, a2, v5);
}
else
{
qsort_recurse(a1, a2, v5);
qsort_recurse(a1, v4, a3);
}
}
}
}

canonical_decompiled_code:
void __fastcall func3(__int64 a1, unsigned int a2, unsigned int a3)
{
unsigned int v4; // er13
unsigned int v5; // er14

if ( (int)a3 > (int)a2 )
{
if ( (int)(a3 - a2) <= 4 )
{
func2(a1, a2, a3);
}
else
{
v4 = func1(a1, a2, a3, (int)(a3 + a2) / 2);
v5 = v4 - 1;
if ( (int)(v4 - 1 - a2) >= (int)(a3 - v4) )
{
func3(a1, v4, a3);
func3(a1, a2, v5);
}
else
{
func3(a1, a2, v5);
func3(a1, v4, a3);
}
}
}
}

original_code:
static void qsort_recurse(run_t* data_ptr, int left, int right)
{
    if(right > left)
    {
        if(right-left < 5) {
            return bubble(data_ptr, left, right);
        }
        int pivot_index = (right+left)/2;
        int new_pivot_index = partition(data_ptr, left, right, pivot_index);
        if(new_pivot_index-1-left < right-new_pivot_index) {
            qsort_recurse(data_ptr, left, new_pivot_index-1);
            return qsort_recurse(data_ptr, new_pivot_index, right);
        } else {
            qsort_recurse(data_ptr, new_pivot_index, right);
            return qsort_recurse(data_ptr, left, new_pivot_index-1);
        }
    }
}

canonical_original_code:
static void qsort_recurse(struct run_t *data_ptr, int left, int right)
{
    if(right > left)
    {
        if(right-left < 5) {
            return bubble(data_ptr, left, right);
        }
        int pivot_index = (right+left)/2;
        int new_pivot_index = partition(data_ptr, left, right, pivot_index);
        if(new_pivot_index-1-left < right-new_pivot_index) {
            qsort_recurse(data_ptr, left, new_pivot_index-1);
            return qsort_recurse(data_ptr, new_pivot_index, right);
        } else {
            qsort_recurse(data_ptr, new_pivot_index, right);
            return qsort_recurse(data_ptr, left, new_pivot_index-1);
        }
    }
}


decompiled_code:
void __fastcall ext_qsort(_DWORD *a1)
{
qsort_recurse((__int64)a1, 0, *a1 - 1);
}

canonical_decompiled_code:
void __fastcall func4(_DWORD *a1)
{
func3((__int64)a1, 0, *a1 - 1);
}

original_code:
void ext_qsort(run_t* data_ptr)
{
    qsort_recurse(data_ptr, 0, data_ptr->length-1);
}

canonical_original_code:
void ext_qsort(struct run_t *data_ptr)
{
    qsort_recurse(data_ptr, 0, data_ptr->length-1);
}


original_code:
static void* qsort_worker(void *worker_ptr)
{
    worker_data_t* data = (worker_data_t*)worker_ptr;
    for(int i=data->offset; i<data->offset+data->length; i++) {
        ext_qsort(data->runs[i]);
    }
    return ((void *)0);
}

canonical_original_code:
static void *qsort_worker(void *worker_ptr)
{
    struct worker_data *data = (worker_data_t*)worker_ptr;
    for(int i = data->offset; i<data->offset+data->length; i++) {
        ext_qsort(data->runs[i]);
    }
    return ((void *)0);
}

variable_types: struct worker_data { int offset; int length; struct run_t { int length; int *items; } **runs; } *

user_defined_types: struct worker_data { int offset; int length; struct run_t **runs; }


decompiled_code:
void __fastcall parallel_qsort(__int64 a1, int a2)
{
int v2; // er15
void **v3; // rbp
int v4; // er13
int v5; // esi
int v6; // er15
void **v7; // rbx
void **v8; // r14
int v9; // er12
_DWORD *v10; // rax
pthread_t *v11; // rbp
pthread_t *v12; // r12
void **v13; // r13
void **ptr; // [rsp+18h] [rbp-80h]
pthread_t newthread[8]; // [rsp+20h] [rbp-78h] BYREF
char v16[56]; // [rsp+60h] [rbp-38h] BYREF

v2 = a2;
v3 = (void **)calloc(1uLL, 0x40uLL);
ptr = v3;
v4 = a2 % 8;
v5 = a2 + 7;
if ( v2 < 0 )
v2 = v5;
v6 = v2 >> 3;
v7 = v3;
v8 = v3 + 8;
v9 = 0;
do
{
v10 = calloc(1uLL, 0x10uLL);
*v3 = v10;
*v10 = v9;
v10[1] = v6;
*((_QWORD *)v10 + 1) = a1;
if ( v4 )
{
v10[1] = v6 + 1;
--v4;
}
v9 += v10[1];
++v3;
}
while ( v3 != v8 );
v11 = newthread;
v12 = newthread;
v13 = ptr;
do
pthread_create(v12++, 0LL, qsort_worker, *v13++);
while ( v12 != (pthread_t *)v16 );
do
pthread_join(*v11++, 0LL);
while ( v11 != (pthread_t *)v16 );
do
free(*v7++);
while ( v7 != v8 );
free(ptr);
}

canonical_decompiled_code:
void __fastcall func6(__int64 a1, int a2)
{
int v2; // er15
void **v3; // rbp
int v4; // er13
int v5; // esi
int v6; // er15
void **v7; // rbx
void **v8; // r14
int v9; // er12
_DWORD *v10; // rax
pthread_t *v11; // rbp
pthread_t *v12; // r12
void **v13; // r13
void **ptr; // [rsp+18h] [rbp-80h]
pthread_t newthread[8]; // [rsp+20h] [rbp-78h] BYREF
char v16[56]; // [rsp+60h] [rbp-38h] BYREF

v2 = a2;
v3 = (void **)calloc(1uLL, 0x40uLL);
ptr = v3;
v4 = a2 % 8;
v5 = a2 + 7;
if ( v2 < 0 )
v2 = v5;
v6 = v2 >> 3;
v7 = v3;
v8 = v3 + 8;
v9 = 0;
do
{
v10 = calloc(1uLL, 0x10uLL);
*v3 = v10;
*v10 = v9;
v10[1] = v6;
*((_QWORD *)v10 + 1) = a1;
if ( v4 )
{
v10[1] = v6 + 1;
--v4;
}
v9 += v10[1];
++v3;
}
while ( v3 != v8 );
v11 = newthread;
v12 = newthread;
v13 = ptr;
do
pthread_create(v12++, 0LL, qsort_worker, *v13++);
while ( v12 != (pthread_t *)v16 );
do
pthread_join(*v11++, 0LL);
while ( v11 != (pthread_t *)v16 );
do
free(*v7++);
while ( v7 != v8 );
free(ptr);
}

original_code:
void parallel_qsort(run_t** runs, int num_runs)
{
    worker_data_t** runs_per_thread;
    runs_per_thread = (worker_data_t**)calloc(1, 8*sizeof(worker_data_t*));
    int remainder = num_runs % 8;
    int offset = 0;
    for(int i=0; i<8; i++) {
        runs_per_thread[i] = (worker_data_t*)calloc(1, sizeof(worker_data_t));
        runs_per_thread[i]->offset = offset;
        runs_per_thread[i]->length = num_runs / 8;
        runs_per_thread[i]->runs = runs;
        if(remainder) {
            runs_per_thread[i]->length++;
            remainder--;
        }
        offset += runs_per_thread[i]->length;
    }
    pthread_t workers[8];
    for(int i=0; i<8; i++) {
        pthread_create(&workers[i], ((void *)0), qsort_worker,
                runs_per_thread[i]);
    }
    for(int i=0; i<8; i++) {
        pthread_join(workers[i], ((void *)0));
    }
    for(int i=0; i<8; i++) {
        free(runs_per_thread[i]);
    }
    free(runs_per_thread);
}

canonical_original_code:
void parallel_qsort(struct run_t **runs, int num_runs)
{
    struct worker_data **runs_per_thread;
    runs_per_thread = (struct worker_data **)calloc(1, 8*sizeof(struct worker_data *));
    int remainder = num_runs % 8;
    int offset = 0;
    for(int i = 0; i<8; i++) {
        runs_per_thread[i] = (struct worker_data *)calloc(1, sizeof(worker_data_t));
        runs_per_thread[i]->offset = offset;
        runs_per_thread[i]->length = num_runs / 8;
        runs_per_thread[i]->runs = runs;
        if(remainder) {
            runs_per_thread[i]->length++;
            remainder--;
        }
        offset += runs_per_thread[i]->length;
    }
    unsigned long workers[8];
    for(int i = 0; i<8; i++) {
        pthread_create(&workers[i], ((void *)0), qsort_worker,
                runs_per_thread[i]);
    }
    for(int i = 0; i<8; i++) {
        pthread_join(workers[i], ((void *)0));
    }
    for(int i = 0; i<8; i++) {
        free(runs_per_thread[i]);
    }
    free(runs_per_thread);
}

variable_types: struct worker_data { int offset; int length; struct run_t { int length; int *items; } **runs; } **

variable_types: remainder int

variable_types: offset int

variable_types:
workers
unsigned long [8]


repo: umegaya/pfm

original_code:
void rbtree_insert_fixup(util_rbtree_t *rbtree, util_rbtree_node_t *node)
{
    util_rbtree_node_t *p, *u;
    while(((node->parent)->color == 0))
    {
        p = node->parent;
        if(p == p->parent->left)
        {
            u = p->parent->right;
            if(((u)->color == 0))
            {
                ((u)->color = 1);
                ((p)->color = 1);
                ((p->parent)->color = 0);
                node = p->parent;
            }
            else
            {
                if(node == p->right)
                {
                    node = p;
                    rbtree_left_rotate(rbtree, node);
                    p = node->parent;
                }
                ((p)->color = 1);
                ((p->parent)->color = 0);
                rbtree_right_rotate(rbtree, p->parent);
            }
        }
        else
        {
            u = p->parent->left;
   if(((u)->color == 0))
   {
    ((u)->color = 1);
    ((p)->color = 1);
    ((p->parent)->color = 0);
                node = p->parent;
   }
   else
   {
    if(p->left == node)
    {
     node = p;
     rbtree_right_rotate(rbtree, node);
     p = node->parent;
    }
    ((p)->color = 1);
    ((p->parent)->color = 0);
    rbtree_left_rotate(rbtree, p->parent);
   }
        }
    }
    ((rbtree->root)->color = 1);
}

canonical_original_code:
void rbtree_insert_fixup(struct util_rbtree_s *rbtree, struct util_rbtree_node_s *node)
{
    struct util_rbtree_node_s *p; struct util_rbtree_node_s *u;
    while(((node->parent)->color == 0))
    {
        p = node->parent;
        if(p == p->parent->left)
        {
            u = p->parent->right;
            if(((u)->color == 0))
            {
                ((u)->color = 1);
                ((p)->color = 1);
                ((p->parent)->color = 0);
                node = p->parent;
            }
            else
            {
                if(node == p->right)
                {
                    node = p;
                    rbtree_left_rotate(rbtree, node);
                    p = node->parent;
                }
                ((p)->color = 1);
                ((p->parent)->color = 0);
                rbtree_right_rotate(rbtree, p->parent);
            }
        }
        else
        {
            u = p->parent->left;
   if(((u)->color == 0))
   {
    ((u)->color = 1);
    ((p)->color = 1);
    ((p->parent)->color = 0);
                node = p->parent;
   }
   else
   {
    if(p->left == node)
    {
     node = p;
     rbtree_right_rotate(rbtree, node);
     p = node->parent;
    }
    ((p)->color = 1);
    ((p->parent)->color = 0);
    rbtree_left_rotate(rbtree, p->parent);
   }
        }
    }
    ((rbtree->root)->color = 1);
}

variable_types: struct util_rbtree_s { struct util_rbtree_node_s { long key; struct util_rbtree_node_s *parent; struct util_rbtree_node_s *right; struct util_rbtree_node_s *left; int color; void *data; } *root; struct util_rbtree_node_s null; unsigned int size; } *

variable_types:
node
struct util_rbtree_node_s *

user_defined_types: struct util_rbtree_s { struct util_rbtree_node_s *root; struct util_rbtree_node_s null; unsigned int size; }


original_code:
void rbtree_delete_fixup(util_rbtree_t *rbtree, util_rbtree_node_t *node)
{
    int h = 0;
    util_rbtree_node_t *w;
 while((node != rbtree->root) && ((node)->color == 1))
 {
        h++;
        if(node == node->parent->left)
        {
            w = node->parent->right;
            if(((w)->color == 0))
            {
                ((w)->color = 1);
                ((node->parent)->color = 0);
                rbtree_left_rotate(rbtree, node->parent);
                w = node->parent->right;
            }
            if(((w->left)->color == 1) && ((w->right)->color == 1))
            {
                ((w)->color = 0);
                node = node->parent;
            }
            else
            {
                if(((w->right)->color == 1))
                {
                    ((w->left)->color = 1);
                    ((w)->color = 0);
                    rbtree_right_rotate(rbtree, w);
                    w = node->parent->right;
                }
                w->color = node->parent->color;
                ((node->parent)->color = 1);
                ((w->right)->color = 1);
                rbtree_left_rotate(rbtree, node->parent);
                node = rbtree->root;
            }
        }
        else
        {
            w = node->parent->left;
            if(w == 0)
            {
                int t = 4;
            }
            if(((w)->color == 0))
            {
                ((w)->color = 1);
                ((node->parent)->color = 0);
                rbtree_right_rotate(rbtree, node->parent);
                w = node->parent->left;
            }
            if(((w->left)->color == 1) && ((w->right)->color == 1))
            {
                ((w)->color = 0);
                node = node->parent;
            }
            else
            {
                if(((w->left)->color == 1))
                {
                    ((w->right)->color = 1);
                    ((w)->color = 0);
                    rbtree_left_rotate(rbtree, w);
                    w = node->parent->left;
                }
                w->color = node->parent->color;
                ((node->parent)->color = 1);
                ((w->left)->color = 1);
                rbtree_right_rotate(rbtree, node->parent);
                node = rbtree->root;
            }
        }
 }
    ((node)->color = 1);
}

canonical_original_code:
void rbtree_delete_fixup(struct util_rbtree_s *rbtree, struct util_rbtree_node_s *node)
{
    int h = 0;
    struct util_rbtree_node_s *w;
 while((node != rbtree->root) && ((node)->color == 1))
 {
        h++;
        if(node == node->parent->left)
        {
            w = node->parent->right;
            if(((w)->color == 0))
            {
                ((w)->color = 1);
                ((node->parent)->color = 0);
                rbtree_left_rotate(rbtree, node->parent);
                w = node->parent->right;
            }
            if(((w->left)->color == 1) && ((w->right)->color == 1))
            {
                ((w)->color = 0);
                node = node->parent;
            }
            else
            {
                if(((w->right)->color == 1))
                {
                    ((w->left)->color = 1);
                    ((w)->color = 0);
                    rbtree_right_rotate(rbtree, w);
                    w = node->parent->right;
                }
                w->color = node->parent->color;
                ((node->parent)->color = 1);
                ((w->right)->color = 1);
                rbtree_left_rotate(rbtree, node->parent);
                node = rbtree->root;
            }
        }
        else
        {
            w = node->parent->left;
            if(w == 0)
            {
                int t = 4;
            }
            if(((w)->color == 0))
            {
                ((w)->color = 1);
                ((node->parent)->color = 0);
                rbtree_right_rotate(rbtree, node->parent);
                w = node->parent->left;
            }
            if(((w->left)->color == 1) && ((w->right)->color == 1))
            {
                ((w)->color = 0);
                node = node->parent;
            }
            else
            {
                if(((w->left)->color == 1))
                {
                    ((w->right)->color = 1);
                    ((w)->color = 0);
                    rbtree_left_rotate(rbtree, w);
                    w = node->parent->left;
                }
                w->color = node->parent->color;
                ((node->parent)->color = 1);
                ((w->left)->color = 1);
                rbtree_right_rotate(rbtree, node->parent);
                node = rbtree->root;
            }
        }
 }
    ((node)->color = 1);
}

variable_types: h int

variable_types: struct util_rbtree_node_s { long key; struct util_rbtree_node_s *parent; struct util_rbtree_node_s *right; struct util_rbtree_node_s *left; int color; void *data; } *

variable_types: t int


original_code:
static void rbtree_check_subtree(const util_rbtree_node_t *node, rbtree_check_t *check,
                         int level, int curheight)
{
    if(check->fini)
    {
        return;
    }
    if(((node)->color == 1))
    {
        curheight++;
    }
    else if(!((node)->color == 0))
    {
        check->fini = 2;
        return;
    }
    if(node->left != check->null)
    {
        if(((node)->color == 0) && ((node->left)->color == 0))
        {
            check->fini = 4;
            return;
        }
        if(node->key < node->left->key)
        {
            check->fini = 5;
            return;
        }
        rbtree_check_subtree(node->left, check, level+1, curheight);
    }
    else
    {
        goto __check_rb_height;
    }
    if(node->right != check->null)
    {
        if(((node)->color == 0) && ((node->right)->color == 0))
        {
            check->fini = 4;
            return;
        }
        if(node->key > node->right->key)
        {
            check->fini = 5;
            return;
        }
        rbtree_check_subtree(node->right, check, level+1, curheight);
    }
    else
    {
        goto __check_rb_height;
    }
    return;
__check_rb_height:
    if(check->rbh == 0)
    {
        check->rbh = curheight;
    }
    if(check->maxd < level)
    {
        check->maxd = level;
    }
    if(check->rbh != curheight)
    {
        check->fini = 3;
    }
}

canonical_original_code:
static void rbtree_check_subtree(struct util_rbtree_node_s *node, struct rbtree_check_s *check, int level, int curheight)
{
    if(check->fini)
    {
        return;
    }
    if(((node)->color == 1))
    {
        curheight++;
    }
    else if(!((node)->color == 0))
    {
        check->fini = 2;
        return;
    }
    if(node->left != check->null)
    {
        if(((node)->color == 0) && ((node->left)->color == 0))
        {
            check->fini = 4;
            return;
        }
        if(node->key < node->left->key)
        {
            check->fini = 5;
            return;
        }
        rbtree_check_subtree(node->left, check, level+1, curheight);
    }
    else
    {
        goto __check_rb_height;
    }
    if(node->right != check->null)
    {
        if(((node)->color == 0) && ((node->right)->color == 0))
        {
            check->fini = 4;
            return;
        }
        if(node->key > node->right->key)
        {
            check->fini = 5;
            return;
        }
        rbtree_check_subtree(node->right, check, level+1, curheight);
    }
    else
    {
        goto __check_rb_height;
    }
    return;
__check_rb_height:
    if(check->rbh == 0)
    {
        check->rbh = curheight;
    }
    if(check->maxd < level)
    {
        check->maxd = level;
    }
    if(check->rbh != curheight)
    {
        check->fini = 3;
    }
}

variable_types: struct rbtree_check_s { short rbh; short maxd; int fini; struct util_rbtree_node_s *null; } *

variable_types: level int

variable_types: curheight int

user_defined_types: struct util_rbtree_node_s { long key; struct util_rbtree_node_s *parent; struct util_rbtree_node_s *right; struct util_rbtree_node_s *left; int color; void *data; }


decompiled_code:
__int64 __fastcall rbtree_mid_travel(__int64 a1, __int64 a2, __int64 (__fastcall *a3)(__int64, __int64), __int64 a4)
{
__int64 result; // rax
__int64 v7; // rdi

if ( *(_QWORD *)(a1 + 24) != a2 )
((void (*)(void))rbtree_mid_travel)();
result = a3(a1, a4);
v7 = *(_QWORD *)(a1 + 16);
if ( v7 != a2 )
result = rbtree_mid_travel(v7, a2, a3, a4);
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, __int64 a2, __int64 (__fastcall *a3)(__int64, __int64), __int64 a4)
{
__int64 result; // rax
__int64 v7; // rdi

if ( *(_QWORD *)(a1 + 24) != a2 )
((void (*)(void))rbtree_mid_travel)();
result = a3(a1, a4);
v7 = *(_QWORD *)(a1 + 16);
if ( v7 != a2 )
result = func5(v7, a2, a3, a4);
return result;
}

original_code:
static void rbtree_mid_travel(util_rbtree_node_t *node, util_rbtree_node_t *sentinel,
                         void(*opera)(util_rbtree_node_t *, void *), void *data)
{
    if(node->left != sentinel)
    {
        rbtree_mid_travel(node->left, sentinel, opera, data);
    }
    opera(node, data);
    if(node->right != sentinel)
    {
        rbtree_mid_travel(node->right, sentinel, opera, data);
    }
}

canonical_original_code:
static void rbtree_mid_travel(struct util_rbtree_node_s *node, struct util_rbtree_node_s *sentinel, void (*opera)(struct util_rbtree_node_s *, void *), void *data)
{
    if(node->left != sentinel)
    {
        rbtree_mid_travel(node->left, sentinel, opera, data);
    }
    opera(node, data);
    if(node->right != sentinel)
    {
        rbtree_mid_travel(node->right, sentinel, opera, data);
    }
}

variable_types:
sentinel
struct util_rbtree_node_s *

variable_types: void (*)(struct util_rbtree_node_s *, void *)

variable_types:
data
void *


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

if ( a1 )
{
*(_DWORD *)(a1 + 40) = 1;
result = a1 + 8;
*(_QWORD *)a1 = a1 + 8;
*(_DWORD *)(a1 + 56) = 0;
}
return result;
}

original_code:
void util_rbtree_init(util_rbtree_t *rbtree)
{
 if(rbtree != ((void *)0))
 {
  (((&((rbtree)->null)))->color = 1);
  rbtree->root = (&((rbtree)->null));
  rbtree->size = 0;
 }
}

canonical_original_code:
void util_rbtree_init(struct util_rbtree_s *rbtree)
{
 if(rbtree != ((void *)0))
 {
  (((&((rbtree)->null)))->color = 1);
  rbtree->root = (&((rbtree)->null));
  rbtree->size = 0;
 }
}


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

if ( a1 == a2 )
return 0LL;
do
{
result = a1;
a1 = *(_QWORD *)(a1 + 24);
}
while ( a1 != a2 );
return result;
}

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

if ( a1 == a2 )
return 0LL;
do
{
result = a1;
a1 = *(_QWORD *)(a1 + 24);
}
while ( a1 != a2 );
return result;
}

original_code:
util_rbtree_node_t* util_rbsubtree_min(util_rbtree_node_t *node, util_rbtree_node_t *sentinel)
{
    if(node == sentinel) return ((void *)0);
    while(node->left != sentinel) node = node->left;
    return node;
}

canonical_original_code:
struct util_rbtree_node_s *util_rbsubtree_min(struct util_rbtree_node_s *node, struct util_rbtree_node_s *sentinel)
{
    if(node == sentinel) return ((void *)0);
    while(node->left != sentinel) node = node->left;
    return node;
}

return_type: struct util_rbtree_node_s { long key; struct util_rbtree_node_s *parent; struct util_rbtree_node_s *right; struct util_rbtree_node_s *left; int color; void *data; } *


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

if ( a1 == a2 )
return 0LL;
do
{
result = a1;
a1 = *(_QWORD *)(a1 + 16);
}
while ( a1 != a2 );
return result;
}

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

if ( a1 == a2 )
return 0LL;
do
{
result = a1;
a1 = *(_QWORD *)(a1 + 16);
}
while ( a1 != a2 );
return result;
}

original_code:
util_rbtree_node_t* util_rbsubtree_max(util_rbtree_node_t *node, util_rbtree_node_t *sentinel)
{
    if(node == sentinel) return ((void *)0);
    while(node->right != sentinel) node = node->right;
    return node;
}

canonical_original_code:
struct util_rbtree_node_s *util_rbsubtree_max(struct util_rbtree_node_s *node, struct util_rbtree_node_s *sentinel)
{
    if(node == sentinel) return ((void *)0);
    while(node->right != sentinel) node = node->right;
    return node;
}


original_code:
void util_rbtree_insert(util_rbtree_t *rbtree, util_rbtree_node_t *node)
{
    util_rbtree_node_t *x, *y;
 if((rbtree==((void *)0)) || (node==((void *)0)) || (node==(&((rbtree)->null))))
 {
  return;
 }
    if(rbtree->root == (&((rbtree)->null)))
    {
        rbtree->root = node;
        node->parent = (&((rbtree)->null));
    }
    else
    {
        x = rbtree->root;
        while(x != (&((rbtree)->null)))
        {
            y = x;
            if(node->key < x->key) x = x->left;
            else x = x->right;
        }
        node->parent = y;
        if(node->key < y->key) y->left = node;
        else y->right = node;
    }
    node->left = (&((rbtree)->null));
    node->right = (&((rbtree)->null));
    ((node)->color = 0);
    rbtree_insert_fixup(rbtree, node);
 rbtree->size++;
}

canonical_original_code:
void util_rbtree_insert(struct util_rbtree_s *rbtree, struct util_rbtree_node_s *node)
{
    struct util_rbtree_node_s *x; struct util_rbtree_node_s *y;
 if((rbtree==((void *)0)) || (node==((void *)0)) || (node==(&((rbtree)->null))))
 {
  return;
 }
    if(rbtree->root == (&((rbtree)->null)))
    {
        rbtree->root = node;
        node->parent = (&((rbtree)->null));
    }
    else
    {
        x = rbtree->root;
        while(x != (&((rbtree)->null)))
        {
            y = x;
            if(node->key < x->key) x = x->left;
            else x = x->right;
        }
        node->parent = y;
        if(node->key < y->key) y->left = node;
        else y->right = node;
    }
    node->left = (&((rbtree)->null));
    node->right = (&((rbtree)->null));
    ((node)->color = 0);
    rbtree_insert_fixup(rbtree, node);
 rbtree->size++;
}