repo: Sojourn/parallel-game-of-life

decompiled_code:
__int64 __fastcall init_parameters(_QWORD *a1, int a2, __int64 a3)
{
__int64 v3; // r15
const char **v4; // r13
_BYTE *v5; // r8
__int64 result; // rax
__int64 v7; // rax
__int64 v8; // rax

*a1 = 0LL;
a1[1] = 0LL;
a1[2] = 0LL;
a1[3] = 0LL;
a1[4] = 0LL;
if ( (unsigned __int64)a2 <= 1 )
{
LABEL_30:
fwrite("Grid size must be at least 1\n", 1uLL, 0x1DuLL, stderr);
return 0xFFFFFFFFLL;
}
if ( a2 != 2LL )
{
v3 = 1LL;
v4 = (const char **)(a3 + 16);
while ( 1 )
{
v5 = *(v4 - 1);
if ( *v5 != 45 )
{
LABEL_5:
fprintf(stderr, "Unrecognized option: %s\n", *(v4 - 1));
return 0xFFFFFFFFLL;
}
if ( v5[1] != 110 || v5[2] )
{
if ( v5[1] != 116 || v5[2] )
{
if ( v5[1] != 114 || v5[2] )
{
if ( v5[1] != 105 || v5[2] )
{
if ( v5[1] != 111 || v5[2] )
goto LABEL_5;
a1[4] = *v4;
v7 = v3 + 2;
if ( v3 + 2 >= (unsigned __int64)a2 )
goto LABEL_13;
goto LABEL_20;
}
a1[3] = *v4;
}
else
{
a1[2] = atoi(*v4);
}
}
else
{
a1[1] = atoi(*v4);
}
}
else
{
*a1 = atoi(*v4);
}
v7 = v3 + 2;
if ( v3 + 2 >= (unsigned __int64)a2 )
{
LABEL_13:
if ( !*a1 )
goto LABEL_30;
if ( a1[1] )
{
if ( a1[2] )
{
result = 0LL;
}
else
{
fwrite("Number of generations must be at least 1\n", 1uLL, 0x29uLL, stderr);
result = 0xFFFFFFFFLL;
}
}
else
{
fwrite("Number of threads must be at least 1\n", 1uLL, 0x25uLL, stderr);
result = 0xFFFFFFFFLL;
}
return result;
}
LABEL_20:
v4 += 2;
if ( v3 + 3 == a2 )
{
v8 = 8 * v7;
goto LABEL_29;
}
v3 = v7;
}
}
v8 = 8LL;
LABEL_29:
fprintf(stderr, "Missing argument for: %s\n", *(const char **)(a3 + v8));
return 0xFFFFFFFFLL;
}

canonical_decompiled_code:
__int64 __fastcall func0(_QWORD *a1, int a2, __int64 a3)
{
__int64 v3; // r15
const char **v4; // r13
_BYTE *v5; // r8
__int64 result; // rax
__int64 v7; // rax
__int64 v8; // rax

*a1 = 0LL;
a1[1] = 0LL;
a1[2] = 0LL;
a1[3] = 0LL;
a1[4] = 0LL;
if ( (unsigned __int64)a2 <= 1 )
{
LABEL_30:
fwrite("Grid size must be at least 1\n", 1uLL, 0x1DuLL, stderr);
return 0xFFFFFFFFLL;
}
if ( a2 != 2LL )
{
v3 = 1LL;
v4 = (const char **)(a3 + 16);
while ( 1 )
{
v5 = *(v4 - 1);
if ( *v5 != 45 )
{
LABEL_5:
fprintf(stderr, "Unrecognized option: %s\n", *(v4 - 1));
return 0xFFFFFFFFLL;
}
if ( v5[1] != 110 || v5[2] )
{
if ( v5[1] != 116 || v5[2] )
{
if ( v5[1] != 114 || v5[2] )
{
if ( v5[1] != 105 || v5[2] )
{
if ( v5[1] != 111 || v5[2] )
goto LABEL_5;
a1[4] = *v4;
v7 = v3 + 2;
if ( v3 + 2 >= (unsigned __int64)a2 )
goto LABEL_13;
goto LABEL_20;
}
a1[3] = *v4;
}
else
{
a1[2] = atoi(*v4);
}
}
else
{
a1[1] = atoi(*v4);
}
}
else
{
*a1 = atoi(*v4);
}
v7 = v3 + 2;
if ( v3 + 2 >= (unsigned __int64)a2 )
{
LABEL_13:
if ( !*a1 )
goto LABEL_30;
if ( a1[1] )
{
if ( a1[2] )
{
result = 0LL;
}
else
{
fwrite("Number of generations must be at least 1\n", 1uLL, 0x29uLL, stderr);
result = 0xFFFFFFFFLL;
}
}
else
{
fwrite("Number of threads must be at least 1\n", 1uLL, 0x25uLL, stderr);
result = 0xFFFFFFFFLL;
}
return result;
}
LABEL_20:
v4 += 2;
if ( v3 + 3 == a2 )
{
v8 = 8 * v7;
goto LABEL_29;
}
v3 = v7;
}
}
v8 = 8LL;
LABEL_29:
fprintf(stderr, "Missing argument for: %s\n", *(const char **)(a3 + v8));
return 0xFFFFFFFFLL;
}

original_code:
int init_parameters(parameters_t *params, int argc, char **argv)
{
 size_t i;
 params->size = 0;
 params->thread_count = 0;
 params->max_gen = 0;
 params->file_in = ((void *)0);
 params->file_out = ((void *)0);
 for(i = 1; i < argc; i += 2)
 {
  if(i + 1 == argc)
  {
   fprintf(stderr, "Missing argument for: %s\n", argv[i]);
   return -1;
  }
  if(strcmp("-n", argv[i]) == 0)
  {
   params->size = atoi(argv[i + 1]);
  }
  else if(strcmp("-t", argv[i]) == 0)
  {
   params->thread_count = atoi(argv[i + 1]);
  }
  else if(strcmp("-r", argv[i]) == 0)
  {
   params->max_gen = atoi(argv[i + 1]);
  }
  else if(strcmp("-i", argv[i]) == 0)
  {
   params->file_in = argv[i + 1];
  }
  else if(strcmp("-o", argv[i]) == 0)
  {
   params->file_out = argv[i + 1];
  }
  else
  {
   fprintf(stderr, "Unrecognized option: %s\n", argv[i]);
   return -1;
  }
 }
 if(params->size < 1)
 {
  fprintf(stderr, "Grid size must be at least 1\n");
  return -1;
 }
 if(params->thread_count < 1)
 {
  fprintf(stderr, "Number of threads must be at least 1\n");
  return -1;
 }
 if(params->max_gen < 1)
 {
  fprintf(stderr, "Number of generations must be at least 1\n");
  return -1;
 }
 return 0;
}

canonical_original_code:
int init_parameters(struct parameters_t *params, int argc, char **argv)
{
 unsigned long i;
 params->size = 0;
 params->thread_count = 0;
 params->max_gen = 0;
 params->file_in = ((void *)0);
 params->file_out = ((void *)0);
 for(i = 1; i < argc; i += 2)
 {
  if(i + 1 == argc)
  {
   fprintf(stderr, "Missing argument for: %s\n", argv[i]);
   return -1;
  }
  if(strcmp("-n", argv[i]) == 0)
  {
   params->size = atoi(argv[i + 1]);
  }
  else if(strcmp("-t", argv[i]) == 0)
  {
   params->thread_count = atoi(argv[i + 1]);
  }
  else if(strcmp("-r", argv[i]) == 0)
  {
   params->max_gen = atoi(argv[i + 1]);
  }
  else if(strcmp("-i", argv[i]) == 0)
  {
   params->file_in = argv[i + 1];
  }
  else if(strcmp("-o", argv[i]) == 0)
  {
   params->file_out = argv[i + 1];
  }
  else
  {
   fprintf(stderr, "Unrecognized option: %s\n", argv[i]);
   return -1;
  }
 }
 if(params->size < 1)
 {
  fprintf(stderr, "Grid size must be at least 1\n");
  return -1;
 }
 if(params->thread_count < 1)
 {
  fprintf(stderr, "Number of threads must be at least 1\n");
  return -1;
 }
 if(params->max_gen < 1)
 {
  fprintf(stderr, "Number of generations must be at least 1\n");
  return -1;
 }
 return 0;
}

variable_types: struct parameters_t { unsigned long size; unsigned long thread_count; unsigned long max_gen; char *file_in; char *file_out; } *

variable_types:
i
unsigned long


decompiled_code:
unsigned __int64 __fastcall spawn_workers(void *arg, pthread_t **a2)
{
unsigned __int64 result; // rax
unsigned __int64 v3; // rbx
pthread_t *v4; // rax

result = *((_QWORD *)arg + 23);
if ( result > 1 )
{
v3 = 0LL;
v4 = (pthread_t *)malloc(8 * result - 8);
for ( *a2 = v4; ; v4 = *a2 )
{
pthread_create(&v4[v3++], 0LL, worker_start, arg);
result = *((_QWORD *)arg + 23) - 1LL;
if ( result <= v3 )
break;
}
}
else
{
*a2 = 0LL;
}
return result;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func1(void *arg, pthread_t **a2)
{
unsigned __int64 result; // rax
unsigned __int64 v3; // rbx
pthread_t *v4; // rax

result = *((_QWORD *)arg + 23);
if ( result > 1 )
{
v3 = 0LL;
v4 = (pthread_t *)malloc(8 * result - 8);
for ( *a2 = v4; ; v4 = *a2 )
{
pthread_create(&v4[v3++], 0LL, worker_start, arg);
result = *((_QWORD *)arg + 23) - 1LL;
if ( result <= v3 )
break;
}
}
else
{
*a2 = 0LL;
}
return result;
}

original_code:
void spawn_workers(synch_t *synch, pthread_t **workers)
{
 size_t i;
 if(synch->params.thread_count > 1)
 {
  *workers = (pthread_t*)
   malloc(sizeof(pthread_t) * (synch->params.thread_count - 1));
  for(i = 0; i < (synch->params.thread_count - 1); i++)
  {
   pthread_create(
    &((*workers)[i]),
    ((void *)0),
    worker_start,
    (void*) synch);
  }
 }
 else
 {
  *workers = ((void *)0);
 }
}

canonical_original_code:
void spawn_workers(struct synch_t *synch, unsigned long **workers)
{
 unsigned long i;
 if(synch->params.thread_count > 1)
 {
  *workers = (unsigned long *)
   malloc(sizeof(pthread_t) * (synch->params.thread_count - 1));
  for(i = 0; i < (synch->params.thread_count - 1); i++)
  {
   pthread_create(
    &((*workers)[i]),
    ((void *)0),
    worker_start,
    (void *) synch);
  }
 }
 else
 {
  *workers = ((void *)0);
 }
}

variable_types: struct synch_t { union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } gen_mutex; union pthread_mutex_t alloc_mutex; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } synch_cv; union pthread_cond_t worker_cv; struct parameters_t { unsigned long size; unsigned long thread_count; unsigned long max_gen; char *file_in; char *file_out; } params; struct grid_t { unsigned long size; char **cells; } *src; struct grid_t *dst; unsigned long work_index; unsigned long work_mod; unsigned long current_gen; unsigned long gen_done; } *

variable_types:
workers
unsigned long **

return_type: void

user_defined_types: struct synch_t { union pthread_mutex_t gen_mutex; union pthread_mutex_t alloc_mutex; union pthread_cond_t synch_cv; union pthread_cond_t worker_cv; struct parameters_t params; struct grid_t *src; struct grid_t *dst; unsigned long work_index; unsigned long work_mod; unsigned long current_gen; unsigned long gen_done; }

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

user_defined_types: union pthread_cond_t { struct __pthread_cond_s __data; char __size[48]; long long __align; }

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


decompiled_code:
void __fastcall despawn_workers(__int64 a1, void **a2)
{
unsigned __int64 v3; // rbx
pthread_t v4; // rdi

if ( *(_QWORD *)(a1 + 184) > 1uLL )
{
v3 = 0LL;
do
{
v4 = *((_QWORD *)*a2 + v3++);
pthread_join(v4, 0LL);
}
while ( *(_QWORD *)(a1 + 184) - 1LL > v3 );
free(*a2);
*a2 = 0LL;
}
}

canonical_decompiled_code:
void __fastcall func2(__int64 a1, void **a2)
{
unsigned __int64 v3; // rbx
pthread_t v4; // rdi

if ( *(_QWORD *)(a1 + 184) > 1uLL )
{
v3 = 0LL;
do
{
v4 = *((_QWORD *)*a2 + v3++);
pthread_join(v4, 0LL);
}
while ( *(_QWORD *)(a1 + 184) - 1LL > v3 );
free(*a2);
*a2 = 0LL;
}
}

original_code:
void despawn_workers(synch_t *synch, pthread_t **workers)
{
 size_t i;
 if(synch->params.thread_count > 1)
 {
  for(i = 0; i < (synch->params.thread_count - 1); i++)
   pthread_join((*workers)[i], ((void *)0));
  free(*workers);
  *workers = ((void *)0);
 }
}

canonical_original_code:
void despawn_workers(struct synch_t *synch, unsigned long **workers)
{
 unsigned long i;
 if(synch->params.thread_count > 1)
 {
  for(i = 0; i < (synch->params.thread_count - 1); i++)
   pthread_join((*workers)[i], ((void *)0));
  free(*workers);
  *workers = ((void *)0);
 }
}

user_defined_types: struct parameters_t { unsigned long size; unsigned long thread_count; unsigned long max_gen; char *file_in; char *file_out; }

user_defined_types: struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; }

user_defined_types: struct grid_t { unsigned long size; char **cells; }

user_defined_types: struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; }


original_code:
work_t allocate_work(synch_t *synch)
{
 work_t work;
 pthread_mutex_lock(&synch->alloc_mutex);
 work.first_index = work.last_index = synch->work_index;
 work.last_index += (synch->params.size * synch->params.size) / synch->params.thread_count - 1;
 if(synch->work_mod > 0)
 {
  work.last_index++;
  synch->work_mod--;
 }
 synch->work_index = work.last_index + 1;
 pthread_mutex_unlock(&synch->alloc_mutex);
 return work;
}

canonical_original_code:
struct work_t allocate_work(struct synch_t *synch)
{
 struct work_t work;
 pthread_mutex_lock(&synch->alloc_mutex);
 work.first_index = work.last_index = synch->work_index;
 work.last_index += (synch->params.size * synch->params.size) / synch->params.thread_count - 1;
 if(synch->work_mod > 0)
 {
  work.last_index++;
  synch->work_mod--;
 }
 synch->work_index = work.last_index + 1;
 pthread_mutex_unlock(&synch->alloc_mutex);
 return work;
}

variable_types: struct work_t { unsigned long first_index; unsigned long last_index; }


decompiled_code:
__int64 __fastcall worker_eval(_QWORD *a1, unsigned __int64 *a2)
{
unsigned __int64 i; // rbx
unsigned __int64 v3; // rax
__int64 result; // rax

for ( i = *a2; a2[1] >= i; result = grid_eval(a1[28], a1[27], v3 % a1[22], v3 / a1[22]) )
v3 = i++;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(_QWORD *a1, unsigned __int64 *a2)
{
unsigned __int64 i; // rbx
unsigned __int64 v3; // rax
__int64 result; // rax

for ( i = *a2; a2[1] >= i; result = grid_eval(a1[28], a1[27], v3 % a1[22], v3 / a1[22]) )
v3 = i++;
return result;
}

original_code:
void worker_eval(synch_t *synch, work_t *work)
{
 size_t i;
 size_t x;
 size_t y;
 for(i = work->first_index; i <= work->last_index; i++)
 {
  x = i % synch->params.size;
  y = i / synch->params.size;
  grid_eval(synch->dst, synch->src, x, y);
 }
}

canonical_original_code:
void worker_eval(struct synch_t *synch, struct work_t *work)
{
 unsigned long i;
 unsigned long x;
 unsigned long y;
 for(i = work->first_index; i <= work->last_index; i++)
 {
  x = i % synch->params.size;
  y = i / synch->params.size;
  grid_eval(synch->dst, synch->src, x, y);
 }
}

variable_types: struct work_t { unsigned long first_index; unsigned long last_index; } *

variable_types:
x
unsigned long

variable_types:
y
unsigned long


decompiled_code:
void *__fastcall worker_start(void *a1)
{
__int64 v1; // rax
bool v2; // zf
unsigned __int64 v3; // rdx
__int64 v4; // rbp
unsigned __int64 v6[7]; // [rsp+0h] [rbp-38h] BYREF

v1 = allocate_work((__int64)a1);
v2 = *((_QWORD *)a1 + 24) == 0LL;
v6[0] = v1;
v6[1] = v3;
if ( !v2 )
{
v4 = 0LL;
do
{
pthread_mutex_lock((pthread_mutex_t *)a1);
while ( *((_QWORD *)a1 + 31) == v4 )
pthread_cond_wait((pthread_cond_t *)((char *)a1 + 128), (pthread_mutex_t *)a1);
++v4;
pthread_mutex_unlock((pthread_mutex_t *)a1);
worker_eval(a1, v6);
pthread_mutex_lock((pthread_mutex_t *)a1);
++*((_QWORD *)a1 + 32);
pthread_cond_signal((pthread_cond_t *)((char *)a1 + 80));
pthread_mutex_unlock((pthread_mutex_t *)a1);
}
while ( *((_QWORD *)a1 + 24) != v4 );
}
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func5(void *a1)
{
__int64 v1; // rax
bool v2; // zf
unsigned __int64 v3; // rdx
__int64 v4; // rbp
unsigned __int64 v6[7]; // [rsp+0h] [rbp-38h] BYREF

v1 = func3((__int64)a1);
v2 = *((_QWORD *)a1 + 24) == 0LL;
v6[0] = v1;
v6[1] = v3;
if ( !v2 )
{
v4 = 0LL;
do
{
pthread_mutex_lock((pthread_mutex_t *)a1);
while ( *((_QWORD *)a1 + 31) == v4 )
pthread_cond_wait((pthread_cond_t *)((char *)a1 + 128), (pthread_mutex_t *)a1);
++v4;
pthread_mutex_unlock((pthread_mutex_t *)a1);
func4(a1, v6);
pthread_mutex_lock((pthread_mutex_t *)a1);
++*((_QWORD *)a1 + 32);
pthread_cond_signal((pthread_cond_t *)((char *)a1 + 80));
pthread_mutex_unlock((pthread_mutex_t *)a1);
}
while ( *((_QWORD *)a1 + 24) != v4 );
}
return 0LL;
}

original_code:
void *worker_start(void *args)
{
 size_t last_gen = 0;
 synch_t *synch = (synch_t*) args;
 work_t work = allocate_work(synch);
 while(last_gen != synch->params.max_gen)
 {
  pthread_mutex_lock(&synch->gen_mutex);
  while(last_gen == synch->current_gen)
   pthread_cond_wait(
    &synch->worker_cv,
    &synch->gen_mutex);
  pthread_mutex_unlock(&synch->gen_mutex);
  worker_eval(args, &work);
  last_gen++;
  pthread_mutex_lock(&synch->gen_mutex);
  synch->gen_done++;
  pthread_cond_signal(&synch->synch_cv);
  pthread_mutex_unlock(&synch->gen_mutex);
 }
 return 0;
}

canonical_original_code:
void *worker_start(void *args)
{
 unsigned long last_gen = 0;
 struct synch_t *synch = (synch_t*) args;
 struct work_t work = allocate_work(synch);
 while(last_gen != synch->params.max_gen)
 {
  pthread_mutex_lock(&synch->gen_mutex);
  while(last_gen == synch->current_gen)
   pthread_cond_wait(
    &synch->worker_cv,
    &synch->gen_mutex);
  pthread_mutex_unlock(&synch->gen_mutex);
  worker_eval(args, &work);
  last_gen++;
  pthread_mutex_lock(&synch->gen_mutex);
  synch->gen_done++;
  pthread_cond_signal(&synch->synch_cv);
  pthread_mutex_unlock(&synch->gen_mutex);
 }
 return 0;
}

variable_types:
args
void *

return_type: void *

user_defined_types: struct work_t { unsigned long first_index; unsigned long last_index; }


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // er8
int result; // eax
unsigned __int64 v5; // rdx
__int64 v6; // rax
__int64 v7; // rdx
unsigned __int64 i; // rdx
__int64 v9; // rcx
void *v10; // [rsp+8h] [rbp-150h] BYREF
unsigned __int64 v11[2]; // [rsp+10h] [rbp-148h] BYREF
char v12; // [rsp+20h] [rbp-138h] BYREF
char v13; // [rsp+30h] [rbp-128h] BYREF
pthread_mutex_t mutex; // [rsp+40h] [rbp-118h] BYREF
pthread_mutex_t v15; // [rsp+68h] [rbp-F0h] BYREF
pthread_cond_t cond; // [rsp+90h] [rbp-C8h] BYREF
pthread_cond_t v17; // [rsp+C0h] [rbp-98h] BYREF
__int64 v18; // [rsp+F0h] [rbp-68h] BYREF
unsigned __int64 v19; // [rsp+F8h] [rbp-60h]
__int64 v20; // [rsp+100h] [rbp-58h]
__int64 v21; // [rsp+108h] [rbp-50h]
__int64 v22; // [rsp+110h] [rbp-48h]
char *v23; // [rsp+118h] [rbp-40h]
char *v24; // [rsp+120h] [rbp-38h]
__int64 v25; // [rsp+128h] [rbp-30h]
unsigned __int64 v26; // [rsp+130h] [rbp-28h]
__int64 v27; // [rsp+138h] [rbp-20h]
__int64 v28; // [rsp+140h] [rbp-18h]

v27 = 1LL;
v23 = &v12;
v28 = 0LL;
v25 = 0LL;
v24 = &v13;
v3 = init_parameters(&v18, argc, (__int64)argv);
result = 1;
if ( v3 != -1 )
{
if ( (unsigned int)grid_init(v23, v18) == -1 )
{
result = 2;
}
else if ( (unsigned int)grid_init(v24, v18) == -1 )
{
grid_deinit(v23);
result = 2;
}
else if ( (unsigned int)grid_read(v21, v23) == -1 )
{
grid_deinit(v23);
grid_deinit(v24);
result = 4;
}
else
{
pthread_cond_init(&cond, 0LL);
pthread_cond_init(&v17, 0LL);
pthread_mutex_init(&mutex, 0LL);
pthread_mutex_init(&v15, 0LL);
v26 = v18 * v18 % v19;
spawn_workers(&mutex, (pthread_t **)&v10);
v11[0] = allocate_work((__int64)&mutex);
v11[1] = v5;
LABEL_6:
v6 = v27;
while ( v20 + 1 != v6 )
{
worker_eval(&mutex, v11);
if ( v19 > 1 )
{
pthread_mutex_lock(&mutex);
for ( i = v19; v28 != v19 - 1; i = v19 )
pthread_cond_wait(&cond, &mutex);
v9 = (__int64)v24;
v28 = 0LL;
v24 = v23;
v23 = (char *)v9;
v6 = ++v27;
if ( i > 1 )
{
pthread_cond_broadcast(&v17);
pthread_mutex_unlock(&mutex);
goto LABEL_6;
}
}
else
{
v7 = (__int64)v24;
v28 = 0LL;
v24 = v23;
v23 = (char *)v7;
v6 = ++v27;
}
}
despawn_workers((__int64)&mutex, &v10);
if ( (unsigned int)grid_write(v22, v23) == -1 )
{
grid_deinit(v23);
grid_deinit(v24);
result = 8;
}
else
{
grid_deinit(v23);
grid_deinit(v24);
result = 0;
}
}
}
return result;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // er8
int result; // eax
unsigned __int64 v5; // rdx
__int64 v6; // rax
__int64 v7; // rdx
unsigned __int64 i; // rdx
__int64 v9; // rcx
void *v10; // [rsp+8h] [rbp-150h] BYREF
unsigned __int64 v11[2]; // [rsp+10h] [rbp-148h] BYREF
char v12; // [rsp+20h] [rbp-138h] BYREF
char v13; // [rsp+30h] [rbp-128h] BYREF
pthread_mutex_t mutex; // [rsp+40h] [rbp-118h] BYREF
pthread_mutex_t v15; // [rsp+68h] [rbp-F0h] BYREF
pthread_cond_t cond; // [rsp+90h] [rbp-C8h] BYREF
pthread_cond_t v17; // [rsp+C0h] [rbp-98h] BYREF
__int64 v18; // [rsp+F0h] [rbp-68h] BYREF
unsigned __int64 v19; // [rsp+F8h] [rbp-60h]
__int64 v20; // [rsp+100h] [rbp-58h]
__int64 v21; // [rsp+108h] [rbp-50h]
__int64 v22; // [rsp+110h] [rbp-48h]
char *v23; // [rsp+118h] [rbp-40h]
char *v24; // [rsp+120h] [rbp-38h]
__int64 v25; // [rsp+128h] [rbp-30h]
unsigned __int64 v26; // [rsp+130h] [rbp-28h]
__int64 v27; // [rsp+138h] [rbp-20h]
__int64 v28; // [rsp+140h] [rbp-18h]

v27 = 1LL;
v23 = &v12;
v28 = 0LL;
v25 = 0LL;
v24 = &v13;
v3 = func0(&v18, argc, (__int64)argv);
result = 1;
if ( v3 != -1 )
{
if ( (unsigned int)grid_init(v23, v18) == -1 )
{
result = 2;
}
else if ( (unsigned int)grid_init(v24, v18) == -1 )
{
grid_deinit(v23);
result = 2;
}
else if ( (unsigned int)grid_read(v21, v23) == -1 )
{
grid_deinit(v23);
grid_deinit(v24);
result = 4;
}
else
{
pthread_cond_init(&cond, 0LL);
pthread_cond_init(&v17, 0LL);
pthread_mutex_init(&mutex, 0LL);
pthread_mutex_init(&v15, 0LL);
v26 = v18 * v18 % v19;
func1(&mutex, (pthread_t **)&v10);
v11[0] = func3((__int64)&mutex);
v11[1] = v5;
LABEL_6:
v6 = v27;
while ( v20 + 1 != v6 )
{
func4(&mutex, v11);
if ( v19 > 1 )
{
pthread_mutex_lock(&mutex);
for ( i = v19; v28 != v19 - 1; i = v19 )
pthread_cond_wait(&cond, &mutex);
v9 = (__int64)v24;
v28 = 0LL;
v24 = v23;
v23 = (char *)v9;
v6 = ++v27;
if ( i > 1 )
{
pthread_cond_broadcast(&v17);
pthread_mutex_unlock(&mutex);
goto LABEL_6;
}
}
else
{
v7 = (__int64)v24;
v28 = 0LL;
v24 = v23;
v23 = (char *)v7;
v6 = ++v27;
}
}
func2((__int64)&mutex, &v10);
if ( (unsigned int)grid_write(v22, v23) == -1 )
{
grid_deinit(v23);
grid_deinit(v24);
result = 8;
}
else
{
grid_deinit(v23);
grid_deinit(v24);
result = 0;
}
}
}
return result;
}

original_code:
int main(int argc, char **argv) {
 pthread_t *workers;
 grid_t grids[2];
 grid_t *swap;
 synch_t synch;
 work_t work;
 synch.current_gen = 1;
 synch.gen_done = 0;
 synch.work_index = 0;
 synch.src = &grids[0];
 synch.dst = &grids[1];
 if(init_parameters(&synch.params, argc, argv) == -1)
  return LIFE_BAD_PARAMS;
 if(grid_init(synch.src, synch.params.size) == -1)
 {
  return LIFE_ALLOC_FAILED;
 }
 if(grid_init(synch.dst, synch.params.size) == -1)
 {
  grid_deinit(synch.src);
  return LIFE_ALLOC_FAILED;
 }
 if(grid_read(synch.params.file_in, synch.src) == -1)
 {
  grid_deinit(synch.src);
  grid_deinit(synch.dst);
  return LIFE_READ_FAILED;
 }
 pthread_cond_init(&synch.synch_cv, ((void *)0));
 pthread_cond_init(&synch.worker_cv, ((void *)0));
 pthread_mutex_init(&synch.gen_mutex, ((void *)0));
 pthread_mutex_init(&synch.alloc_mutex, ((void *)0));
 synch.work_mod = (synch.params.size * synch.params.size) % synch.params.thread_count;
 spawn_workers(&synch, &workers);
 work = allocate_work(&synch);
 while(synch.current_gen != synch.params.max_gen + 1)
 {
  worker_eval(&synch, &work);
  if(synch.params.thread_count > 1)
  {
   pthread_mutex_lock(&synch.gen_mutex);
   while(synch.gen_done != (synch.params.thread_count - 1))
    pthread_cond_wait(&synch.synch_cv, &synch.gen_mutex);
  }
  swap = synch.src;
  synch.src = synch.dst;
  synch.dst = swap;
  synch.current_gen++;
  synch.gen_done = 0;
  if(synch.params.thread_count > 1)
  {
   pthread_cond_broadcast(&synch.worker_cv);
   pthread_mutex_unlock(&synch.gen_mutex);
  }
 }
 despawn_workers(&synch, &workers);
 if(grid_write(synch.params.file_out, synch.src) == -1)
 {
  grid_deinit(synch.src);
  grid_deinit(synch.dst);
  return LIFE_WRITE_FAILED;
 }
 grid_deinit(synch.src);
 grid_deinit(synch.dst);
 return LIFE_SUCCESS;
}

canonical_original_code:
int main(int argc, char **argv) {
 unsigned long *workers;
 struct grid_t grids[2];
 struct grid_t *swap;
 struct synch_t synch;
 struct work_t work;
 synch.current_gen = 1;
 synch.gen_done = 0;
 synch.work_index = 0;
 synch.src = &grids[0];
 synch.dst = &grids[1];
 if(init_parameters(&synch.params, argc, argv) == -1)
  return LIFE_BAD_PARAMS;
 if(grid_init(synch.src, synch.params.size) == -1)
 {
  return LIFE_ALLOC_FAILED;
 }
 if(grid_init(synch.dst, synch.params.size) == -1)
 {
  grid_deinit(synch.src);
  return LIFE_ALLOC_FAILED;
 }
 if(grid_read(synch.params.file_in, synch.src) == -1)
 {
  grid_deinit(synch.src);
  grid_deinit(synch.dst);
  return LIFE_READ_FAILED;
 }
 pthread_cond_init(&synch.synch_cv, ((void *)0));
 pthread_cond_init(&synch.worker_cv, ((void *)0));
 pthread_mutex_init(&synch.gen_mutex, ((void *)0));
 pthread_mutex_init(&synch.alloc_mutex, ((void *)0));
 synch.work_mod = (synch.params.size * synch.params.size) % synch.params.thread_count;
 spawn_workers(&synch, &workers);
 work = allocate_work(&synch);
 while(synch.current_gen != synch.params.max_gen + 1)
 {
  worker_eval(&synch, &work);
  if(synch.params.thread_count > 1)
  {
   pthread_mutex_lock(&synch.gen_mutex);
   while(synch.gen_done != (synch.params.thread_count - 1))
    pthread_cond_wait(&synch.synch_cv, &synch.gen_mutex);
  }
  swap = synch.src;
  synch.src = synch.dst;
  synch.dst = swap;
  synch.current_gen++;
  synch.gen_done = 0;
  if(synch.params.thread_count > 1)
  {
   pthread_cond_broadcast(&synch.worker_cv);
   pthread_mutex_unlock(&synch.gen_mutex);
  }
 }
 despawn_workers(&synch, &workers);
 if(grid_write(synch.params.file_out, synch.src) == -1)
 {
  grid_deinit(synch.src);
  grid_deinit(synch.dst);
  return LIFE_WRITE_FAILED;
 }
 grid_deinit(synch.src);
 grid_deinit(synch.dst);
 return LIFE_SUCCESS;
}

variable_types: argc int

variable_types:
argv
char **

variable_types:
workers
unsigned long *

variable_types: struct grid_t { unsigned long size; char **cells; } [2]

variable_types: struct synch_t { union pthread_mutex_t { struct __pthread_mutex_s { int __lock; unsigned int __count; int __owner; unsigned int __nusers; int __kind; short __spins; short __elision; struct __pthread_internal_list { struct __pthread_internal_list *__prev; struct __pthread_internal_list *__next; } __list; } __data; char __size[40]; long __align; } gen_mutex; union pthread_mutex_t alloc_mutex; union pthread_cond_t { struct __pthread_cond_s { union { unsigned long long __wseq; struct { unsigned int __low; unsigned int __high; } __wseq32; }; union { unsigned long long __g1_start; struct { unsigned int __low; unsigned int __high; } __g1_start32; }; unsigned int __g_refs[2]; unsigned int __g_size[2]; unsigned int __g1_orig_size; unsigned int __wrefs; unsigned int __g_signals[2]; } __data; char __size[48]; long long __align; } synch_cv; union pthread_cond_t worker_cv; struct parameters_t { unsigned long size; unsigned long thread_count; unsigned long max_gen; char *file_in; char *file_out; } params; struct grid_t { unsigned long size; char **cells; } *src; struct grid_t *dst; unsigned long work_index; unsigned long work_mod; unsigned long current_gen; unsigned long gen_done; }

return_type: int


decompiled_code:
__int64 __fastcall grid_init(_QWORD *a1, __int64 a2)
{
_QWORD *v3; // rax
_QWORD *v4; // r12
char *v5; // r8
__int64 i; // rdi
char *v7; // rcx
__int64 j; // rax
__int64 result; // rax

*a1 = a2;
v3 = malloc(8 * a2);
a1[1] = v3;
if ( v3 && (v4 = v3, (v5 = (char *)malloc(a2 * a2)) != 0LL) )
{
if ( a2 )
{
for ( i = 0LL; ; ++i )
{
v4[i] = v5;
v7 = v5;
for ( j = 0LL; ; ++j )
{
v7[j] = 0;
if ( a2 == j + 1 )
break;
v7 = *(char **)(a1[1] + 8 * i);
}
v5 += a2;
if ( j == i )
break;
v4 = (_QWORD *)a1[1];
}
}
result = 0LL;
}
else
{
fwrite("Insufficient memory\n", 1uLL, 0x14uLL, stderr);
result = 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(_QWORD *a1, __int64 a2)
{
_QWORD *v3; // rax
_QWORD *v4; // r12
char *v5; // r8
__int64 i; // rdi
char *v7; // rcx
__int64 j; // rax
__int64 result; // rax

*a1 = a2;
v3 = malloc(8 * a2);
a1[1] = v3;
if ( v3 && (v4 = v3, (v5 = (char *)malloc(a2 * a2)) != 0LL) )
{
if ( a2 )
{
for ( i = 0LL; ; ++i )
{
v4[i] = v5;
v7 = v5;
for ( j = 0LL; ; ++j )
{
v7[j] = 0;
if ( a2 == j + 1 )
break;
v7 = *(char **)(a1[1] + 8 * i);
}
v5 += a2;
if ( j == i )
break;
v4 = (_QWORD *)a1[1];
}
}
result = 0LL;
}
else
{
fwrite("Insufficient memory\n", 1uLL, 0x14uLL, stderr);
result = 0xFFFFFFFFLL;
}
return result;
}

original_code:
int grid_init(grid_t *grid, size_t size)
{
 size_t x;
 size_t y;
 life_state *cells;
 grid->size = size;
 grid->cells = (life_state **) malloc(sizeof(life_state *) * size);
 if(grid->cells == ((void *)0))
 {
  fprintf(stderr, "Insufficient memory\n");
  return -1;
 }
 cells = (life_state *) malloc(sizeof(life_state) * size * size);
 if(cells == ((void *)0))
 {
  fprintf(stderr, "Insufficient memory\n");
  return -1;
 }
 for(y = 0; y < size; y++)
 {
  grid->cells[y] = &cells[y * size];
  for(x = 0; x < size; x++)
  {
   grid->cells[y][x] = ((life_state) 0);
  }
 }
 return 0;
}

canonical_original_code:
int grid_init(struct grid_t *grid, unsigned long size)
{
 unsigned long x;
 unsigned long y;
 char *cells;
 grid->size = size;
 grid->cells = (char **) malloc(sizeof(char *) * size);
 if(grid->cells == ((void *)0))
 {
  fprintf(stderr, "Insufficient memory\n");
  return -1;
 }
 cells = (char *) malloc(sizeof(life_state) * size * size);
 if(cells == ((void *)0))
 {
  fprintf(stderr, "Insufficient memory\n");
  return -1;
 }
 for(y = 0; y < size; y++)
 {
  grid->cells[y] = &cells[y * size];
  for(x = 0; x < size; x++)
  {
   grid->cells[y][x] = ((char) 0);
  }
 }
 return 0;
}

variable_types: struct grid_t { unsigned long size; char **cells; } *

variable_types:
size
unsigned long

variable_types:
cells
char *


original_code:
void grid_deinit(grid_t *grid)
{
 free(grid->cells[0]);
 free(grid->cells);
 grid->cells = ((void *)0);
 grid->size = 0;
}

canonical_original_code:
void grid_deinit(struct grid_t *grid)
{
 free(grid->cells[0]);
 free(grid->cells);
 grid->cells = ((void *)0);
 grid->size = 0;
}


isAlive

decompiled_code:
_BOOL8 __fastcall isAlive(unsigned __int64 *a1, unsigned __int64 a2, unsigned __int64 a3)
{
unsigned __int64 v3; // rcx
_BOOL8 result; // rax

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

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

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

original_code:
size_t isAlive(grid_t *grid, size_t x, size_t y)
{
 if(x >= grid->size || x < 0) return 0;
 if(y >= grid->size || y < 0) return 0;
 return (grid->cells[y][x] == ((life_state) 1));
}

canonical_original_code:
unsigned long isAlive(struct grid_t *grid, unsigned long x, unsigned long y)
{
 if(x >= grid->size || x < 0) return 0;
 if(y >= grid->size || y < 0) return 0;
 return (grid->cells[y][x] == ((char) 1));
}

return_type: unsigned long


decompiled_code:
unsigned __int64 __fastcall grid_eval(__int64 a1, unsigned __int64 *a2, unsigned __int64 a3, __int64 a4)
{
unsigned __int64 v4; // r12
__int64 v6; // r9
unsigned __int64 v7; // rsi
unsigned __int64 v8; // rdx
unsigned __int64 v9; // r11
__int64 v10; // r11
unsigned __int64 v11; // rdx
unsigned __int64 v12; // r9
__int64 v13; // r9
unsigned __int64 v14; // rsi
unsigned __int64 v15; // rdx
unsigned __int64 v16; // r11
_BOOL8 v17; // rax
__int64 v18; // r10
__int64 v19; // r8
unsigned __int64 result; // rax
__int64 v21; // r11
__int64 v22; // r9
bool *v23; // rdx

v4 = a4 - 1;
isAlive(a2, a3, a4 - 1);
v7 = v6 + 1;
isAlive(a2, v6 + 1, v8);
isAlive(a2, v7, v9);
isAlive(a2, v7, v10 + 1);
isAlive(a2, v12, v11);
v14 = v13 - 1;
isAlive(a2, v13 - 1, v15);
isAlive(a2, v14, v16);
v17 = isAlive(a2, v14, v4);
result = v19 + v17;
v23 = (bool *)(v22 + *(_QWORD *)(*(_QWORD *)(v18 + 8) + 8 * v21));
if ( *(_BYTE *)(*(_QWORD *)(a2[1] + 8 * v21) + v22) )
{
if ( result <= 3 )
*v23 = result > 1;
else
*v23 = 0;
}
else
{
*v23 = result == 3;
}
return result;
}

original_code:
void grid_eval(grid_t *dst, grid_t *src, size_t x, size_t y)
{
 size_t alive = 0;
 alive += isAlive(src, x , y - 1);
 alive += isAlive(src, x + 1, y - 1);
 alive += isAlive(src, x + 1, y );
 alive += isAlive(src, x + 1, y + 1);
 alive += isAlive(src, x , y + 1);
 alive += isAlive(src, x - 1, y + 1);
 alive += isAlive(src, x - 1, y );
 alive += isAlive(src, x - 1, y - 1);
 if(src->cells[y][x] == ((life_state) 0))
 {
  if(alive == 3)
  {
   dst->cells[y][x] = ((life_state) 1);
  }
  else
  {
   dst->cells[y][x] = ((life_state) 0);
  }
 }
 else
 {
  if(alive >= 4)
  {
   dst->cells[y][x] = ((life_state) 0);
  }
  else if(alive <= 1)
  {
   dst->cells[y][x] = ((life_state) 0);
  }
  else
  {
   dst->cells[y][x] = ((life_state) 1);
  }
 }
}

canonical_original_code:
void grid_eval(struct grid_t *dst, struct grid_t *src, unsigned long x, unsigned long y)
{
 unsigned long alive = 0;
 alive += isAlive(src, x , y - 1);
 alive += isAlive(src, x + 1, y - 1);
 alive += isAlive(src, x + 1, y );
 alive += isAlive(src, x + 1, y + 1);
 alive += isAlive(src, x , y + 1);
 alive += isAlive(src, x - 1, y + 1);
 alive += isAlive(src, x - 1, y );
 alive += isAlive(src, x - 1, y - 1);
 if(src->cells[y][x] == ((char) 0))
 {
  if(alive == 3)
  {
   dst->cells[y][x] = ((char) 1);
  }
  else
  {
   dst->cells[y][x] = ((char) 0);
  }
 }
 else
 {
  if(alive >= 4)
  {
   dst->cells[y][x] = ((char) 0);
  }
  else if(alive <= 1)
  {
   dst->cells[y][x] = ((char) 0);
  }
  else
  {
   dst->cells[y][x] = ((char) 1);
  }
 }
}

variable_types:
src
struct grid_t *

variable_types:
alive
unsigned long


repo: Solomoriah/WAR

decompiled_code:
int __fastcall curs_hilite(int a1)
{
int result; // eax

if ( a1 )
result = wattrset(stdscr, 0x10000);
else
result = wattrset(stdscr, 0);
return result;
}

canonical_decompiled_code:
int __fastcall func0(int a1)
{
int result; // eax

if ( a1 )
result = wattrset(stdscr, 0x10000);
else
result = wattrset(stdscr, 0);
return result;
}

original_code:
int curs_hilite(int mode)
{
    if(mode)
        (wattrset(stdscr,((chtype)((1U)) << ((8) + 8))));
    else
        (wattrset(stdscr,(1U - 1U)));
}

variable_types: mode int


decompiled_code:
int curs_initscr()
{
initscr();
cbreak();
noecho();
nonl();
intrflush(stdscr, 0);
return keypad(stdscr, 1);
}

canonical_decompiled_code:
int func1()
{
initscr();
cbreak();
noecho();
nonl();
intrflush(stdscr, 0);
return keypad(stdscr, 1);
}

original_code:
int curs_initscr()
{
    initscr();
 cbreak();
 noecho();
 nonl();
 intrflush(stdscr,0);
    keypad(stdscr,1);
}


decompiled_code:
// attributes: thunk
int curs_endwin(void)
{
return endwin();
}

canonical_decompiled_code:
int func2(void)
{
return endwin();
}

original_code:
int curs_endwin()
{
    endwin();
}

canonical_original_code:
int curs_endwin()
{
    endwin();
}


decompiled_code:
int __fastcall curs_move(int a1, int a2)
{
return wmove(stdscr, a1, a2);
}

canonical_decompiled_code:
int __fastcall func3(int a1, int a2)
{
return wmove(stdscr, a1, a2);
}

original_code:
int curs_move(int r, int c)
{
    wmove(stdscr,(r),(c));
}

variable_types: r int

variable_types: c int


decompiled_code:
int __fastcall curs_erase(int a1)
{
int result; // eax

if ( a1 )
result = wclear(stdscr);
else
result = werase(stdscr);
return result;
}

canonical_decompiled_code:
int __fastcall func4(int a1)
{
int result; // eax

if ( a1 )
result = wclear(stdscr);
else
result = werase(stdscr);
return result;
}

original_code:
int curs_erase(int mode)
{
    if(mode)
        wclear(stdscr);
    else
        werase(stdscr);
}


decompiled_code:
int curs_clrtoeol()
{
return wclrtoeol(stdscr);
}

canonical_decompiled_code:
int func5()
{
return wclrtoeol(stdscr);
}

original_code:
int curs_clrtoeol()
{
    wclrtoeol(stdscr);
}


decompiled_code:
int __fastcall curs_addch(unsigned int a1)
{
return waddch(stdscr, a1);
}

canonical_decompiled_code:
int __fastcall func6(unsigned int a1)
{
return waddch(stdscr, a1);
}

original_code:
int curs_addch(int ch)
{
    waddch(stdscr,(ch));
}

variable_types: ch int


decompiled_code:
int curs_refresh()
{
return wrefresh(stdscr);
}

canonical_decompiled_code:
int func7()
{
return wrefresh(stdscr);
}

original_code:
int curs_refresh()
{
    wrefresh(stdscr);
}


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

result = wgetch(stdscr);
if ( result > 263 )
{
if ( result == 339 )
{
result = 261;
}
else if ( result <= 339 )
{
if ( result == 330 )
{
LABEL_13:
result = 8;
}
else if ( result == 338 )
{
result = 262;
}
}
else if ( result == 360 )
{
result = 264;
}
}
else if ( result > 257 )
{
switch ( result )
{
case 259:
return result;
case 260:
result = 257;
break;
case 261:
result = 258;
break;
case 262:
result = 263;
break;
case 263:
goto LABEL_13;
default:
result = 260;
break;
}
}
return result;
}

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

result = wgetch(stdscr);
if ( result > 263 )
{
if ( result == 339 )
{
result = 261;
}
else if ( result <= 339 )
{
if ( result == 330 )
{
LABEL_13:
result = 8;
}
else if ( result == 338 )
{
result = 262;
}
}
else if ( result == 360 )
{
result = 264;
}
}
else if ( result > 257 )
{
switch ( result )
{
case 259:
return result;
case 260:
result = 257;
break;
case 261:
result = 258;
break;
case 262:
result = 263;
break;
case 263:
goto LABEL_13;
default:
result = 260;
break;
}
}
return result;
}

original_code:
int curs_getch()
{
    int rc;
    rc = wgetch(stdscr);
    switch(rc) {
    case 0406:
        rc = (256+7);
        break;
    case 0550:
        rc = (256+8);
        break;
    case 0404:
        rc = (256+1);
        break;
    case 0405:
        rc = (256+2);
        break;
    case 0403:
        rc = (256+3);
        break;
    case 0402:
        rc = (256+4);
        break;
    case 0522:
        rc = (256+6);
        break;
    case 0523:
        rc = (256+5);
        break;
    case 0407:
    case 0512:
        rc = '\b';
        break;
    }
    return rc;
}

variable_types: rc int


decompiled_code:
__int64 get_key()
{
char *v0; // rbx
int v1; // er8

v0 = (char *)keys;
LABEL_2:
v1 = getchar();
if ( v1 >= 0 )
{
while ( v0 )
{
if ( *v0 == v1 )
{
if ( *((_QWORD *)v0 + 1) )
{
v0 = (char *)*((_QWORD *)v0 + 1);
goto LABEL_2;
}
return *((unsigned int *)v0 + 1);
}
v0 = (char *)*((_QWORD *)v0 + 2);
}
}
return (unsigned int)v1;
}

canonical_decompiled_code:
__int64 func0()
{
char *v0; // rbx
int v1; // er8

v0 = (char *)keys;
LABEL_2:
v1 = getchar();
if ( v1 >= 0 )
{
while ( v0 )
{
if ( *v0 == v1 )
{
if ( *((_QWORD *)v0 + 1) )
{
v0 = (char *)*((_QWORD *)v0 + 1);
goto LABEL_2;
}
return *((unsigned int *)v0 + 1);
}
v0 = (char *)*((_QWORD *)v0 + 2);
}
}
return (unsigned int)v1;
}

original_code:
static int get_key()
{
 struct node *k;
 int ch;
 k = keys;
 while(1) {
  ch = getchar();
  if(ch < 0)
   return ch;
  for(; k != ((void *)0) && k->ch != ch; k = k->nomatch);
  if(k == ((void *)0))
   return ch;
  if(k->match == ((void *)0))
   return k->result;
  else
   k = k->match;
 }
}

variable_types: struct node { char ch; int result; struct node *match; } *


isinput

decompiled_code:
int isinput()
{
struct timeval v1; // [rsp+0h] [rbp-98h] BYREF
fd_set readfds; // [rsp+10h] [rbp-88h] BYREF

memset(&readfds, 0, sizeof(readfds));
readfds.fds_bits[0] |= 1uLL;
v1.tv_sec = 0LL;
v1.tv_usec = 200LL;
return select(1, &readfds, 0LL, 0LL, &v1);
}

canonical_decompiled_code:
int func1()
{
struct timeval v1; // [rsp+0h] [rbp-98h] BYREF
fd_set readfds; // [rsp+10h] [rbp-88h] BYREF

memset(&readfds, 0, sizeof(readfds));
readfds.fds_bits[0] |= 1uLL;
v1.tv_sec = 0LL;
v1.tv_usec = 200LL;
return select(1, &readfds, 0LL, 0LL, &v1);
}

original_code:
static int isinput()
{
    fd_set in_set;
    struct timeval timeout;
    int rc;
    do { int __d0, __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&in_set)->__fds_bits)[0]) : "memory"); } while (0);
    ((void) (((&in_set)->__fds_bits)[((0) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((0) % (8 * (int) sizeof (__fd_mask)))))));
    timeout.tv_sec = 0;
    timeout.tv_usec = 200;
    return select(1, &in_set, ((void *)0), ((void *)0), &timeout);
}

canonical_original_code:
static int isinput()
{
    struct fd_set in_set;
    struct timeval timeout;
    int rc;
    do { int __d0; int __d1; __asm__ __volatile__ ("cld; rep; " "stosq" : "=c" (__d0), "=D" (__d1) : "a" (0), "0" (sizeof (fd_set) / sizeof (__fd_mask)), "1" (&((&in_set)->__fds_bits)[0]) : "memory"); } while (0);
    ((void) (((&in_set)->__fds_bits)[((0) / (8 * (int) sizeof (__fd_mask)))] |= ((__fd_mask) (1UL << ((0) % (8 * (int) sizeof (__fd_mask)))))));
    timeout.tv_sec = 0;
    timeout.tv_usec = 200;
    return select(1, &in_set, ((void *)0), ((void *)0), &timeout);
}

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


decompiled_code:
void *make_node()
{
return calloc(0x18uLL, 1uLL);
}

canonical_decompiled_code:
void *func4()
{
return calloc(0x18uLL, 1uLL);
}

original_code:
struct node *make_node()
{
    struct node *n;
    n = malloc(sizeof(struct node));
    memset(n, 0, sizeof(struct node));
    return n;
}

return_type: struct node { char ch; int result; struct node *match; } *


addkey

decompiled_code:
__int64 __fastcall addkey(const char *a1, int a2)
{
const char *v2; // rbp
int v3; // edx
__int64 result; // rax
__int64 i; // rbx
__int64 v6; // r12
_QWORD *v7; // rax
bool v8; // zf
_QWORD *v9; // rax

v2 = a1;
v3 = strlen(a1);
result = keys;
if ( v3 <= 0 )
{
*(_DWORD *)(keys + 4) = a2;
}
else
{
i = keys;
v6 = (__int64)&a1[v3 - 1 + 1];
LABEL_3:
while ( 2 )
{
while ( !result )
{
v7 = make_node();
v8 = keys == 0;
*(_BYTE *)v7 = *v2;
if ( v8 )
{
i = (__int64)v7;
++v2;
keys = (__int64)v7;
result = v7[1];
if ( v2 == (const char *)v6 )
goto LABEL_9;
}
else
{
*(_QWORD *)(i + 8) = v7;
++v2;
i = (__int64)v7;
result = v7[1];
if ( v2 == (const char *)v6 )
goto LABEL_9;
}
}
for ( i = result; ; i = *(_QWORD *)(i + 16) )
{
if ( *(_BYTE *)i == *v2 )
{
++v2;
result = *(_QWORD *)(i + 8);
if ( v2 != (const char *)v6 )
goto LABEL_3;
goto LABEL_9;
}
if ( !*(_QWORD *)(i + 16) )
break;
}
++v2;
v9 = make_node();
*(_QWORD *)(i + 16) = v9;
i = (__int64)v9;
*(_BYTE *)v9 = *(v2 - 1);
result = v9[1];
if ( v2 != (const char *)v6 )
continue;
break;
}
LABEL_9:
*(_DWORD *)(i + 4) = a2;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(const char *a1, int a2)
{
const char *v2; // rbp
int v3; // edx
__int64 result; // rax
__int64 i; // rbx
__int64 v6; // r12
_QWORD *v7; // rax
bool v8; // zf
_QWORD *v9; // rax

v2 = a1;
v3 = strlen(a1);
result = keys;
if ( v3 <= 0 )
{
*(_DWORD *)(keys + 4) = a2;
}
else
{
i = keys;
v6 = (__int64)&a1[v3 - 1 + 1];
LABEL_3:
while ( 2 )
{
while ( !result )
{
v7 = func4();
v8 = keys == 0;
*(_BYTE *)v7 = *v2;
if ( v8 )
{
i = (__int64)v7;
++v2;
keys = (__int64)v7;
result = v7[1];
if ( v2 == (const char *)v6 )
goto LABEL_9;
}
else
{
*(_QWORD *)(i + 8) = v7;
++v2;
i = (__int64)v7;
result = v7[1];
if ( v2 == (const char *)v6 )
goto LABEL_9;
}
}
for ( i = result; ; i = *(_QWORD *)(i + 16) )
{
if ( *(_BYTE *)i == *v2 )
{
++v2;
result = *(_QWORD *)(i + 8);
if ( v2 != (const char *)v6 )
goto LABEL_3;
goto LABEL_9;
}
if ( !*(_QWORD *)(i + 16) )
break;
}
++v2;
v9 = func4();
*(_QWORD *)(i + 16) = v9;
i = (__int64)v9;
*(_BYTE *)v9 = *(v2 - 1);
result = v9[1];
if ( v2 != (const char *)v6 )
continue;
break;
}
LABEL_9:
*(_DWORD *)(i + 4) = a2;
}
return result;
}

original_code:
void addkey(char *match, int result)
{
 int i, len;
 struct node *k, *pk;
    len = strlen(match);
 k = pk = keys;
 for(i = 0; i < len; i++, pk = k, k = k->match) {
  if(k == ((void *)0)) {
   k = make_node();
   k->ch = match[i];
   if(keys == ((void *)0))
    keys = k;
   else
    pk->match = k;
  } else {
   for(; k->ch != match[i] && k->nomatch != ((void *)0); k = k->nomatch);
   if(k->ch != match[i]) {
    k->nomatch = make_node();
    k = k->nomatch;
    k->ch = match[i];
   }
  }
 }
 pk->result = result;
}

canonical_original_code:
void addkey(char *match, int result)
{
 int i; int len;
 struct node *k; struct node *pk;
    len = strlen(match);
 k = pk = keys;
 for(i = 0; i < len; i++, pk = k, k = k->match) {
  if(k == ((void *)0)) {
   k = make_node();
   k->ch = match[i];
   if(keys == ((void *)0))
    keys = k;
   else
    pk->match = k;
  } else {
   for(; k->ch != match[i] && k->nomatch != ((void *)0); k = k->nomatch);
   if(k->ch != match[i]) {
    k->nomatch = make_node();
    k = k->nomatch;
    k->ch = match[i];
   }
  }
 }
 pk->result = result;
}

variable_types:
match
char *

variable_types: result int

variable_types: i int

variable_types: len int

user_defined_types: struct node { char ch; int result; struct node *match; }


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

cur_y = a1;
result = 0LL;
cur_x = a2;
return result;
}

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

cur_y = a1;
result = 0LL;
cur_x = a2;
return result;
}

original_code:
int ansi_move(int r, int c)
{
 cur_y = r;
 cur_x = c;
    return 0;
}


decompiled_code:
__int64 ansi_erase()
{
char v0; // dl
__int64 v1; // rcx
__int64 v2; // rax
__int64 result; // rax

ansi_attr_isra_0((unsigned __int8)cur_attr);
fwrite("\x1B[H\x1B[2J", 1uLL, 7uLL, stdout);
fflush(stdout);
v0 = cur_attr;
v1 = 3840LL;
do
{
v2 = v1 - 3840;
do
{
ascreen[v2] = 32;
v2 += 160LL;
byte_1601[v2] = v0;
*((_BYTE *)&save.c_iflag + v2) = 32;
*((_BYTE *)&save.c_iflag + v2 + 1) = v0;
}
while ( v2 != v1 );
v1 = v2 + 2;
}
while ( v2 != 3998 );
cur_x = 0;
result = 0LL;
cur_y = 0;
return result;
}

canonical_decompiled_code:
__int64 func7()
{
char v0; // dl
__int64 v1; // rcx
__int64 v2; // rax
__int64 result; // rax

func2((unsigned __int8)cur_attr);
fwrite("\x1B[H\x1B[2J", 1uLL, 7uLL, stdout);
fflush(stdout);
v0 = cur_attr;
v1 = 3840LL;
do
{
v2 = v1 - 3840;
do
{
ascreen[v2] = 32;
v2 += 160LL;
byte_1601[v2] = v0;
*((_BYTE *)&save.c_iflag + v2) = 32;
*((_BYTE *)&save.c_iflag + v2 + 1) = v0;
}
while ( v2 != v1 );
v1 = v2 + 2;
}
while ( v2 != 3998 );
cur_x = 0;
result = 0LL;
cur_y = 0;
return result;
}

original_code:
int ansi_erase()
{
 ansi_attr(cur_attr);
 fputs("\033[H\033[2J", stdout);
 fflush(stdout);
 for(cur_x = 0; cur_x < 80; cur_x++)
  for(cur_y = 0; cur_y < 24; cur_y++) {
   ascreen[cur_y][cur_x].ch = ' ';
   ascreen[cur_y][cur_x].attr = cur_attr;
   vscreen[cur_y][cur_x].ch = ' ';
   vscreen[cur_y][cur_x].attr = cur_attr;
  }
 cur_x = 0;
 cur_y = 0;
    return 0;
}


decompiled_code:
__int64 ansi_initscr()
{
tcflag_t v0; // eax
__int64 result; // rax
const char **v2; // rbx
int v3; // esi
const char *v4; // rdi

if ( !keys )
{
v2 = (const char **)&off_25F0;
v3 = 259;
v4 = "[A";
while ( 1 )
{
addkey(v4, v3);
v4 = *v2;
v2 += 2;
if ( !v4 )
break;
v3 = *((_DWORD *)v2 - 2);
}
}
cur_attr = 0;
setbuf(stdin, 0LL);
ansi_erase();
tcgetattr(0, &save);
v0 = save.c_iflag;
*(_QWORD *)&term.c_cc[31] = *(_QWORD *)&save.c_cc[31];
BYTE1(v0) = BYTE1(save.c_iflag) & 0xFE;
*(__m128i *)&term.c_iflag = _mm_load_si128((const __m128i *)&save);
term.c_ospeed = save.c_ospeed;
*(__m128i *)&term.c_line = _mm_load_si128((const __m128i *)&save.c_line);
term.c_iflag = v0;
result = 0LL;
term.c_cc[2] = -1;
*(_WORD *)&term.c_cc[5] = 262;
term.c_lflag = 0;
*(__m128i *)&term.c_cc[15] = _mm_load_si128((const __m128i *)&save.c_cc[15]);
return result;
}

canonical_decompiled_code:
__int64 func8()
{
tcflag_t v0; // eax
__int64 result; // rax
const char **v2; // rbx
int v3; // esi
const char *v4; // rdi

if ( !keys )
{
v2 = (const char **)&off_25F0;
v3 = 259;
v4 = "[A";
while ( 1 )
{
func5(v4, v3);
v4 = *v2;
v2 += 2;
if ( !v4 )
break;
v3 = *((_DWORD *)v2 - 2);
}
}
cur_attr = 0;
setbuf(stdin, 0LL);
func7();
tcgetattr(0, &save);
v0 = save.c_iflag;
*(_QWORD *)&term.c_cc[31] = *(_QWORD *)&save.c_cc[31];
BYTE1(v0) = BYTE1(save.c_iflag) & 0xFE;
*(__m128i *)&term.c_iflag = _mm_load_si128((const __m128i *)&save);
term.c_ospeed = save.c_ospeed;
*(__m128i *)&term.c_line = _mm_load_si128((const __m128i *)&save.c_line);
term.c_iflag = v0;
result = 0LL;
term.c_cc[2] = -1;
*(_WORD *)&term.c_cc[5] = 262;
term.c_lflag = 0;
*(__m128i *)&term.c_cc[15] = _mm_load_si128((const __m128i *)&save.c_cc[15]);
return result;
}

original_code:
int ansi_initscr()
{
    int i;
    if(keys == ((void *)0))
        for(i = 0; keymap[i].match != ((void *)0); i++)
            addkey(keymap[i].match, keymap[i].result);
 cur_attr = 0;
 setbuf(stdin, ((void *)0));
 ansi_erase();
 tcgetattr(0, &save);
 term = save;
 term.c_cc[2] = '\377';
 term.c_cc[6] = 1;
 term.c_cc[5] = 6;
 term.c_iflag = term.c_iflag & (~0000400);
 term.c_lflag = 0;
    return 0;
}


decompiled_code:
__int64 ansi_clrtoeol()
{
int v0; // edi
char v1; // si
__int64 v2; // rax
__int64 v3; // rcx
__int64 v4; // rax

v0 = cur_x;
if ( cur_x <= 79 )
{
v1 = cur_attr;
v2 = cur_x + 80LL * cur_y;
v3 = v2 + 1;
v4 = 2 * v2;
do
{
vscreen[v4] = 32;
v4 += 2LL;
byte_79F[v4] = v1;
}
while ( v4 != 2 * (v3 + (unsigned int)(79 - v0)) );
}
return 0LL;
}

original_code:
int ansi_clrtoeol()
{
 int cx;
 for(cx = cur_x; cx < 80; cx++) {
  vscreen[cur_y][cx].ch = ' ';
  vscreen[cur_y][cx].attr = cur_attr;
 }
    return 0;
}

variable_types: cx int


decompiled_code:
__int64 __fastcall ansi_putch(char a1)
{
int v1; // ecx
char v2; // si
int v3; // edx
__int64 v4; // rax
int v6; // eax

if ( a1 == 10 )
{
cur_x = 0;
if ( ++cur_y <= 23 )
return 0LL;
LABEL_13:
cur_y = 23;
return 0LL;
}
if ( a1 == 13 )
{
cur_x = 0;
return 0LL;
}
if ( a1 != 8 )
{
if ( (unsigned __int8)a1 <= 0x1Fu )
return 0LL;
v1 = cur_y;
v2 = cur_attr;
v3 = cur_x + 1;
v4 = cur_x + 80LL * cur_y;
vscreen[2 * v4] = a1;
byte_7A1[2 * v4] = v2;
if ( v3 <= 79 )
{
cur_x = v3;
return 0LL;
}
cur_x = 0;
cur_y = v1 + 1;
if ( v1 + 1 <= 23 )
return 0LL;
goto LABEL_13;
}
v6 = cur_x - 1;
if ( cur_x - 1 < 0 )
v6 = 0;
cur_x = v6;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func10(char a1)
{
int v1; // ecx
char v2; // si
int v3; // edx
__int64 v4; // rax
int v6; // eax

if ( a1 == 10 )
{
cur_x = 0;
if ( ++cur_y <= 23 )
return 0LL;
LABEL_13:
cur_y = 23;
return 0LL;
}
if ( a1 == 13 )
{
cur_x = 0;
return 0LL;
}
if ( a1 != 8 )
{
if ( (unsigned __int8)a1 <= 0x1Fu )
return 0LL;
v1 = cur_y;
v2 = cur_attr;
v3 = cur_x + 1;
v4 = cur_x + 80LL * cur_y;
vscreen[2 * v4] = a1;
byte_7A1[2 * v4] = v2;
if ( v3 <= 79 )
{
cur_x = v3;
return 0LL;
}
cur_x = 0;
cur_y = v1 + 1;
if ( v1 + 1 <= 23 )
return 0LL;
goto LABEL_13;
}
v6 = cur_x - 1;
if ( cur_x - 1 < 0 )
v6 = 0;
cur_x = v6;
return 0LL;
}

original_code:
int ansi_putch(int c)
{
 unsigned char cc;
 cc = c;
 switch(cc) {
  case '\n' :
   cur_x = 0;
   if(++cur_y >= 24)
    cur_y = 23;
   break;
  case '\r' :
   cur_x = 0;
   break;
  case '\b' :
   cur_x--;
            if(cur_x < 0)
                cur_x = 0;
   break;
  default :
   if(cc >= ' ') {
    vscreen[cur_y][cur_x].ch = cc;
    vscreen[cur_y][cur_x].attr = cur_attr;
    if(++cur_x >= 80) {
     cur_x = 0;
     if(++cur_y >= 24)
      cur_y = 23;
    }
   }
   break;
 }
    return 0;
}

variable_types:
cc
unsigned char


decompiled_code:
__int64 __fastcall ansi_hilite(unsigned int a1)
{
cur_attr = a1 != 0 ? 7 : 0;
return a1;
}

canonical_decompiled_code:
__int64 __fastcall func11(unsigned int a1)
{
cur_attr = a1 != 0 ? 7 : 0;
return a1;
}

original_code:
int ansi_hilite(int mode)
{
 cur_attr = (mode == 0 ? 0 : 7);
    return mode;
}


decompiled_code:
__int64 ansi_refresh()
{
__int64 v0; // r14
unsigned int v1; // er15
int v2; // ecx
int v3; // edx
int v4; // ebp
__int64 v5; // rbx
unsigned int v6; // er12
int v7; // edi

v0 = 0LL;
v1 = byte_7A1[0];
ansi_attr_isra_0(byte_7A1[0]);
ansi_goto_isra_0(0, 0);
v2 = 0;
v3 = 0;
do
{
v4 = 0;
v5 = 160 * v0;
do
{
v7 = v4++;
if ( vscreen[v5] == ascreen[v5] )
{
if ( byte_7A1[v5] == byte_16A1[v5] )
goto LABEL_10;
if ( v7 != v3 )
{
LABEL_14:
ansi_goto_isra_0(v7, v0);
goto LABEL_5;
}
}
else if ( v7 != v3 )
{
goto LABEL_14;
}
if ( v2 != (_DWORD)v0 )
goto LABEL_14;
LABEL_5:
v6 = byte_7A1[v5];
if ( v6 != v1 )
ansi_attr_isra_0(v6);
putchar(vscreen[v5]);
if ( v4 == 80 )
{
v2 = v0 + 1;
v3 = 0;
}
else
{
v2 = v0;
v3 = v4;
}
v1 = v6;
ascreen[v5] = vscreen[v5];
byte_16A1[v5] = byte_7A1[v5];
LABEL_10:
v5 += 2LL;
}
while ( v4 != 80 );
++v0;
}
while ( v0 != 24 );
ansi_goto_isra_0(cur_x, cur_y);
fflush(stdout);
return 0LL;
}

canonical_decompiled_code:
__int64 func12()
{
__int64 v0; // r14
unsigned int v1; // er15
int v2; // ecx
int v3; // edx
int v4; // ebp
__int64 v5; // rbx
unsigned int v6; // er12
int v7; // edi

v0 = 0LL;
v1 = byte_7A1[0];
func2(byte_7A1[0]);
func3(0, 0);
v2 = 0;
v3 = 0;
do
{
v4 = 0;
v5 = 160 * v0;
do
{
v7 = v4++;
if ( vscreen[v5] == ascreen[v5] )
{
if ( byte_7A1[v5] == byte_16A1[v5] )
goto LABEL_10;
if ( v7 != v3 )
{
LABEL_14:
func3(v7, v0);
goto LABEL_5;
}
}
else if ( v7 != v3 )
{
goto LABEL_14;
}
if ( v2 != (_DWORD)v0 )
goto LABEL_14;
LABEL_5:
v6 = byte_7A1[v5];
if ( v6 != v1 )
func2(v6);
putchar(vscreen[v5]);
if ( v4 == 80 )
{
v2 = v0 + 1;
v3 = 0;
}
else
{
v2 = v0;
v3 = v4;
}
v1 = v6;
ascreen[v5] = vscreen[v5];
byte_16A1[v5] = byte_7A1[v5];
LABEL_10:
v5 += 2LL;
}
while ( v4 != 80 );
++v0;
}
while ( v0 != 24 );
func3(cur_x, cur_y);
fflush(stdout);
return 0LL;
}

original_code:
int ansi_refresh()
{
 int rx, ry, ra, px, py;
 ra = vscreen[0][0].attr;
 ansi_attr(ra);
 ansi_goto(0, 0);
 px = py = 0;
 for(ry = 0; ry < 24; ry++)
  for(rx = 0; rx < 80; rx++)
   if(vscreen[ry][rx].ch != ascreen[ry][rx].ch
   || vscreen[ry][rx].attr != ascreen[ry][rx].attr) {
    if(px != rx || py != ry)
     ansi_goto(rx, ry);
    px = rx;
    py = ry;
    if(ra != vscreen[ry][rx].attr) {
     ra = vscreen[ry][rx].attr;
     ansi_attr(ra);
    }
    putchar(vscreen[ry][rx].ch);
    if(++px >= 80) {
     px = 0;
     py++;
    }
    ascreen[ry][rx].ch = vscreen[ry][rx].ch;
    ascreen[ry][rx].attr = vscreen[ry][rx].attr;
   }
 ansi_goto(cur_x, cur_y);
 fflush(stdout);
    return 0;
}

canonical_original_code:
int ansi_refresh()
{
 int rx; int ry; int ra; int px; int py;
 ra = vscreen[0][0].attr;
 ansi_attr(ra);
 ansi_goto(0, 0);
 px = py = 0;
 for(ry = 0; ry < 24; ry++)
  for(rx = 0; rx < 80; rx++)
   if(vscreen[ry][rx].ch != ascreen[ry][rx].ch
   || vscreen[ry][rx].attr != ascreen[ry][rx].attr) {
    if(px != rx || py != ry)
     ansi_goto(rx, ry);
    px = rx;
    py = ry;
    if(ra != vscreen[ry][rx].attr) {
     ra = vscreen[ry][rx].attr;
     ansi_attr(ra);
    }
    putchar(vscreen[ry][rx].ch);
    if(++px >= 80) {
     px = 0;
     py++;
    }
    ascreen[ry][rx].ch = vscreen[ry][rx].ch;
    ascreen[ry][rx].attr = vscreen[ry][rx].attr;
   }
 ansi_goto(cur_x, cur_y);
 fflush(stdout);
    return 0;
}

variable_types: rx int

variable_types: ry int

variable_types: ra int

variable_types: px int

variable_types: py int


decompiled_code:
__int64 ansi_endwin()
{
ansi_refresh();
ansi_goto_isra_0(0, 23);
return 0LL;
}

original_code:
int ansi_endwin()
{
 ansi_refresh();
 ansi_goto(0, 23);
    return 0;
}


decompiled_code:
__int64 ansi_getch()
{
unsigned int v0; // er12

if ( isinput() <= 0 )
ansi_refresh();
tcsetattr(0, 2, &term);
v0 = getchar();
if ( v0 == 27 && isinput() > 0 )
v0 = get_key();
tcsetattr(0, 2, &save);
return v0;
}

canonical_decompiled_code:
__int64 func14()
{
unsigned int v0; // er12

if ( func1() <= 0 )
func12();
tcsetattr(0, 2, &term);
v0 = getchar();
if ( v0 == 27 && func1() > 0 )
v0 = func0();
tcsetattr(0, 2, &save);
return v0;
}

original_code:
int ansi_getch()
{
    int ch;
    struct node *k;
    if(isinput() < 1)
        ansi_refresh();
 tcsetattr(0, 2, &term);
    ch = getchar();
    if(ch == '\033')
        if(isinput() > 0)
            ch = get_key();
 tcsetattr(0, 2, &save);
    return ch;
}


gsetdriver

decompiled_code:
__int64 __fastcall gsetdriver(char *s1)
{
unsigned int v1; // er12
const char *v2; // rsi
char **v3; // rbx
__int64 result; // rax

v1 = initialized;
if ( initialized )
return 0xFFFFFFFFLL;
v2 = drivers;
if ( !drivers )
{
LABEL_7:
driver = -1;
return 0xFFFFFFFFLL;
}
v3 = &drivers;
while ( strcmp(s1, v2) )
{
v2 = v3[12];
v3 += 12;
++v1;
if ( !v2 )
goto LABEL_7;
}
result = v1;
driver = v1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(char *s1)
{
unsigned int v1; // er12
const char *v2; // rsi
char **v3; // rbx
__int64 result; // rax

v1 = initialized;
if ( initialized )
return 0xFFFFFFFFLL;
v2 = drivers;
if ( !drivers )
{
LABEL_7:
driver = -1;
return 0xFFFFFFFFLL;
}
v3 = &drivers;
while ( strcmp(s1, v2) )
{
v2 = v3[12];
v3 += 12;
++v1;
if ( !v2 )
goto LABEL_7;
}
result = v1;
driver = v1;
return result;
}

original_code:
static int gsetdriver(char *dname)
{
    int i;
    if(initialized)
        return -1;
    for(i = 0; drivers[i].term != ((void *)0); i++)
        if(strcmp(dname, drivers[i].term) == 0)
            return (driver = i);
    return (driver = -1);
}

variable_types:
dname
char *


ginit

decompiled_code:
__int64 ginit()
{
char *v0; // rdi

if ( initialized )
return 0xFFFFFFFFLL;
v0 = getenv("GENIODRV");
if ( v0 && (unsigned int)gsetdriver(v0) == -1 )
return 0xFFFFFFFFLL;
initialized = 1;
return ((__int64 (__fastcall *)(char *))(&drivers)[12 * driver + 1])(v0);
}

canonical_decompiled_code:
__int64 func1()
{
char *v0; // rdi

if ( initialized )
return 0xFFFFFFFFLL;
v0 = getenv("GENIODRV");
if ( v0 && (unsigned int)func0(v0) == -1 )
return 0xFFFFFFFFLL;
initialized = 1;
return ((__int64 (__fastcall *)(char *))(&drivers)[12 * driver + 1])(v0);
}

original_code:
int ginit()
{
    char *p;
    if(initialized)
        return -1;
    p = getenv("GENIODRV");
    if(p != ((void *)0))
        if(gsetdriver(p) == -1)
            return -1;
    initialized = 1;
 return drivers[driver].init();
}

variable_types:
p
char *


gend

decompiled_code:
__int64 gend()
{
if ( !initialized )
return 0xFFFFFFFFLL;
initialized = 0;
return ((__int64 (*)(void))(&drivers)[12 * driver + 2])();
}

canonical_decompiled_code:
__int64 func2()
{
if ( !initialized )
return 0xFFFFFFFFLL;
initialized = 0;
return ((__int64 (*)(void))(&drivers)[12 * driver + 2])();
}

original_code:
int gend()
{
    if(!initialized)
        return -1;
    initialized = 0;
 return drivers[driver].end();
}


gmove

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

if ( initialized )
result = ((__int64 (*)(void))(&drivers)[12 * driver + 3])();
else
result = 0xFFFFFFFFLL;
return result;
}

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

if ( initialized )
result = ((__int64 (*)(void))(&drivers)[12 * driver + 3])();
else
result = 0xFFFFFFFFLL;
return result;
}

original_code:
int gmove(int r, int c)
{
    if(!initialized)
        return -1;
 return drivers[driver].move(r, c);
}

variable_types: r int

variable_types: c int


gerase

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

if ( initialized )
result = ((__int64 (*)(void))(&drivers)[12 * driver + 4])();
else
result = 0xFFFFFFFFLL;
return result;
}

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

if ( initialized )
result = ((__int64 (*)(void))(&drivers)[12 * driver + 4])();
else
result = 0xFFFFFFFFLL;
return result;
}

original_code:
int gerase(int mode)
{
    if(!initialized)
        return -1;
 drivers[driver].erase(mode);
}

variable_types: mode int


gclrline

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

if ( initialized )
result = ((__int64 (*)(void))(&drivers)[12 * driver + 5])();
else
result = 0xFFFFFFFFLL;
return result;
}

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

if ( initialized )
result = ((__int64 (*)(void))(&drivers)[12 * driver + 5])();
else
result = 0xFFFFFFFFLL;
return result;
}

original_code:
int gclrline()
{
    if(!initialized)
        return -1;
 drivers[driver].clrline();
}


gputs

decompiled_code:
__int64 __fastcall gputs(_BYTE *a1)
{
__int64 v1; // rax
_BYTE *v2; // rbp
__int64 (*v3)(void); // rdx
unsigned int v5; // er12

if ( !initialized )
return (unsigned int)-1;
v1 = driver;
v2 = a1;
v3 = (__int64 (*)(void))(&drivers)[12 * driver + 10];
if ( v3 )
return v3();
v5 = 0;
if ( *a1 )
{
while ( 1 )
{
++v2;
v5 += ((__int64 (*)(void))(&drivers)[12 * v1 + 6])();
if ( !*v2 )
break;
v1 = driver;
}
}
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func6(_BYTE *a1)
{
__int64 v1; // rax
_BYTE *v2; // rbp
__int64 (*v3)(void); // rdx
unsigned int v5; // er12

if ( !initialized )
return (unsigned int)-1;
v1 = driver;
v2 = a1;
v3 = (__int64 (*)(void))(&drivers)[12 * driver + 10];
if ( v3 )
return v3();
v5 = 0;
if ( *a1 )
{
while ( 1 )
{
++v2;
v5 += ((__int64 (*)(void))(&drivers)[12 * v1 + 6])();
if ( !*v2 )
break;
v1 = driver;
}
}
return v5;
}

original_code:
int gputs(char *s)
{
    int cnt;
    if(!initialized)
        return -1;
    if(drivers[driver].puts != ((void *)0))
        return drivers[driver].puts(s);
    cnt = 0;
 while(*s)
  cnt += drivers[driver].addch(*s++);
    return cnt;
}

variable_types:
s
char *

variable_types: cnt int


gputch

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

if ( initialized )
result = ((__int64 (*)(void))(&drivers)[12 * driver + 6])();
else
result = 0xFFFFFFFFLL;
return result;
}

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

if ( initialized )
result = ((__int64 (*)(void))(&drivers)[12 * driver + 6])();
else
result = 0xFFFFFFFFLL;
return result;
}

original_code:
int gputch(int c)
{
    if(!initialized)
        return -1;
 return drivers[driver].addch(c);
}


ggetch

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

if ( initialized )
result = ((__int64 (*)(void))(&drivers)[12 * driver + 9])();
else
result = 0xFFFFFFFFLL;
return result;
}

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

if ( initialized )
result = ((__int64 (*)(void))(&drivers)[12 * driver + 9])();
else
result = 0xFFFFFFFFLL;
return result;
}

original_code:
int ggetch()
{
    if(!initialized)
        return -1;
 return drivers[driver].getch();
}


gprintf

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

if ( !initialized )
return (unsigned int)-1;
va_start(arg, format);
v1 = vsprintf(s, format, arg);
gputs(s);
return v1;
}

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

if ( !initialized )
return (unsigned int)-1;
va_start(arg, format);
v1 = vsprintf(s, format, arg);
func6(s);
return v1;
}

original_code:
int gprintf(char *fmt, ...)
{
    char buffer[256];
    va_list argptr;
    int cnt;
    if(!initialized)
        return -1;
    __builtin_va_start(argptr,fmt);
    cnt = vsprintf(buffer, fmt, argptr);
    __builtin_va_end(argptr);
    gputs(buffer);
    return cnt;
}

canonical_original_code:
int gprintf(char *fmt, ...)
{
    char buffer[256];
    __builtin_va_list argptr;
    int cnt;
    if(!initialized)
        return -1;
    __builtin_va_start(argptr,fmt);
    cnt = vsprintf(buffer, fmt, argptr);
    __builtin_va_end(argptr);
    gputs(buffer);
    return cnt;
}

variable_types:
fmt
char *

variable_types:
buffer
char [256]


ghilite

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

if ( initialized )
result = ((__int64 (*)(void))(&drivers)[12 * driver + 7])();
else
result = 0xFFFFFFFFLL;
return result;
}

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

if ( initialized )
result = ((__int64 (*)(void))(&drivers)[12 * driver + 7])();
else
result = 0xFFFFFFFFLL;
return result;
}

original_code:
int ghilite(int mode)
{
    if(!initialized)
        return -1;
 return drivers[driver].hilite(mode);
}


grefresh

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

if ( initialized )
result = ((__int64 (*)(void))(&drivers)[12 * driver + 8])();
else
result = 0xFFFFFFFFLL;
return result;
}

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

if ( initialized )
result = ((__int64 (*)(void))(&drivers)[12 * driver + 8])();
else
result = 0xFFFFFFFFLL;
return result;
}

original_code:
int grefresh()
{
    if(!initialized)
        return -1;
 return drivers[driver].refresh();
}


gmapspot

decompiled_code:
__int64 __fastcall gmapspot(__int64 a1, __int64 a2, char a3, char a4)
{
char *v4; // rax
unsigned int v6; // er12
unsigned int v7; // ebp
char v8; // bl
__int64 v9; // rdi

if ( !initialized )
return 0xFFFFFFFFLL;
v4 = (&drivers)[12 * driver + 11];
if ( v4 )
return ((__int64 (__fastcall *)(__int64, __int64, _QWORD, _QWORD))v4)(a1, a2, (unsigned int)a3, (unsigned int)a4);
v6 = 2 * a2 + 3;
v7 = a1 + 1;
v8 = a3;
v9 = (unsigned int)(a1 + 1);
if ( a4 != 32 )
v8 = a4;
if ( v8 == 126 )
v8 = 32;
gmove(v9, v6);
gputch((unsigned int)v8);
gmove(v7, v6);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func12(__int64 a1, __int64 a2, char a3, char a4)
{
char *v4; // rax
unsigned int v6; // er12
unsigned int v7; // ebp
char v8; // bl
__int64 v9; // rdi

if ( !initialized )
return 0xFFFFFFFFLL;
v4 = (&drivers)[12 * driver + 11];
if ( v4 )
return ((__int64 (__fastcall *)(__int64, __int64, _QWORD, _QWORD))v4)(a1, a2, (unsigned int)a3, (unsigned int)a4);
v6 = 2 * a2 + 3;
v7 = a1 + 1;
v8 = a3;
v9 = (unsigned int)(a1 + 1);
if ( a4 != 32 )
v8 = a4;
if ( v8 == 126 )
v8 = 32;
func3(v9, v6);
func7((unsigned int)v8);
func3(v7, v6);
return 0LL;
}

original_code:
int gmapspot(int r, int c, char terr, char mark, int focus)
{
    if(!initialized)
        return -1;
    if(drivers[driver].mapspot != ((void *)0))
        return drivers[driver].mapspot(r, c, terr, mark, focus);
    if(mark != ' ')
        terr = mark;
    if(terr == '~')
        terr = ' ';
    gmove(r + 1, c * 2 + 3);
    gputch(terr);
    gmove(r + 1, c * 2 + 3);
    return 0;
}

variable_types: terr char

variable_types: mark char

variable_types: focus int


mapspot

decompiled_code:
__int64 __fastcall mapspot(int a1, int a2)
{
__int64 v2; // rdx
__int64 result; // rax

v2 = 160LL * a1;
result = (unsigned int)*(char *)(v2 + mapovl + a2);
if ( *(_BYTE *)(v2 + mapovl + a2) == 32 )
{
result = (unsigned int)*(char *)(map + v2 + a2);
if ( *(_BYTE *)(map + v2 + a2) == 126 )
result = 32LL;
}
return result;
}

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

v2 = 160LL * a1;
result = (unsigned int)*(char *)(v2 + mapovl + a2);
if ( *(_BYTE *)(v2 + mapovl + a2) == 32 )
{
result = (unsigned int)*(char *)(map + v2 + a2);
if ( *(_BYTE *)(map + v2 + a2) == 126 )
result = 32LL;
}
return result;
}

original_code:
int mapspot(int r, int c)
{
    if(mapovl[r][c] != ' ')
        return mapovl[r][c];
    return (map[r][c] == '~' ? ' ' : map[r][c]);
}


original_code:
void do_overlay()
{
    int i, j;
    for(i = 0; i < map_height; i++)
        for(j = 0; j < map_height; j++)
            mapovl[i][j] = ' ';
    for(i = 0; i < armycnt; i++) {
        if(mapovl[armies[i].r][armies[i].c] == ' '
        || mapovl[armies[i].r][armies[i].c] ==
           marks[1][nations[armies[i].nation].mark])
            mapovl[armies[i].r][armies[i].c] =
                marks[1][nations[armies[i].nation].mark];
        else
            mapovl[armies[i].r][armies[i].c] = '!';
    }
    for(i = 0; i < citycnt; i++) {
        if(mapovl[cities[i].r][cities[i].c] == ' '
        || strchr(marks[1], mapovl[cities[i].r][cities[i].c]) != ((void *)0))
            mapovl[cities[i].r][cities[i].c] =
                marks[0][nations[cities[i].nation].mark];
        else
            mapovl[cities[i].r][cities[i].c] = '!';
    }
}

canonical_original_code:
void do_overlay()
{
    int i; int j;
    for(i = 0; i < map_height; i++)
        for(j = 0; j < map_height; j++)
            mapovl[i][j] = ' ';
    for(i = 0; i < armycnt; i++) {
        if(mapovl[armies[i].r][armies[i].c] == ' '
        || mapovl[armies[i].r][armies[i].c] ==
           marks[1][nations[armies[i].nation].mark])
            mapovl[armies[i].r][armies[i].c] =
                marks[1][nations[armies[i].nation].mark];
        else
            mapovl[armies[i].r][armies[i].c] = '!';
    }
    for(i = 0; i < citycnt; i++) {
        if(mapovl[cities[i].r][cities[i].c] == ' '
        || strchr(marks[1], mapovl[cities[i].r][cities[i].c]) != ((void *)0))
            mapovl[cities[i].r][cities[i].c] =
                marks[0][nations[cities[i].nation].mark];
        else
            mapovl[cities[i].r][cities[i].c] = '!';
    }
}

variable_types: i int

variable_types: j int


main

decompiled_code:
// local variable allocation has failed, the output may be wrong!
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
int v3; // eax
int v4; // eax
int v5; // er12
unsigned int v6; // er13
FILE *v7; // rbp
unsigned int v8; // eax
int v9; // ebx
int v10; // ebx
unsigned int v11; // edi
int v12; // ebp
int v13; // ebx
int v14; // esi
int v15; // eax
__int64 v16; // rcx
int *v17; // rdi
__int64 v18; // rcx
int *v19; // rdi
__int64 v20; // rcx
int *v21; // rdi
__int64 v22; // rcx
__int64 v23; // rax
__int64 v24; // rdx
__int16 *v25; // rax
__int64 v26; // rcx
__int64 v27; // rdx
__int64 v28; // r15
__int64 v29; // rbx
const char *v30; // rax
const char *v31; // rcx
__int64 v32; // rcx
__int64 v33; // rdx
__int64 v34; // rsi
const char *v35; // rbx
__int64 v36; // rax
const char *v37; // rcx
unsigned int v38; // [rsp+Ch] [rbp-20Ch]
int v39[28]; // [rsp+10h] [rbp-208h] BYREF
int v40[28]; // [rsp+80h] [rbp-198h] BYREF
int v41[28]; // [rsp+F0h] [rbp-128h] BYREF
char s[184]; // [rsp+160h] [rbp-B8h] BYREF

if ( argc > 1 && (*(_QWORD *)&argc = argv[1], chdir(*(const char **)&argc) == -1) )
{
fprintf(stderr, "Error Setting Directory %s\n", argv[1]);
}
else
{
v3 = loadmap(*(_QWORD *)&argc, argv, envp);
if ( v3 )
{
fprintf(stderr, "Error Loading Map (%s)\n", *((_QWORD *)&errors + v3));
}
else
{
v4 = loadsave();
v5 = v4;
if ( !v4 )
{
v6 = 0;
v7 = fopen("master.cmd", "r");
if ( v7 )
{
while ( fgets(s, 128, v7) )
{
++v6;
v8 = execpriv(s);
if ( v8 )
{
fprintf(stderr, "Master Cmd Failed, Line %d, Code %d\n", v6, v8);
exit(2);
}
}
fclose(v7);
}
v9 = 0;
do_overlay();
fwrite(" ", 1uLL, 3uLL, stdout);
if ( map_width > 0 )
{
do
{
if ( __ROR4__(-858993459 * v9, 1) <= 0x19999999u )
putchar(v9 / 10 % 10 + 48);
else
putchar(32);
++v9;
}
while ( map_width > v9 );
}
v10 = 0;
fwrite("\n ", 1uLL, 4uLL, stdout);
if ( map_width > 0 )
{
do
{
v11 = v10++;
putchar(v11 % 0xA + 48);
}
while ( map_width > v10 );
}
v12 = 0;
putchar(10);
if ( map_height > 0 )
{
do
{
if ( v12 == 10 * (v12 / 0xAu) )
putchar(v12 / 10 % 10 + 48);
else
putchar(32);
v13 = 0;
putchar(v12 % 0xAu + 48);
putchar(32);
if ( map_width > 0 )
{
do
{
v14 = v13++;
v15 = mapspot(v12, v14);
putchar(v15);
}
while ( map_width > v13 );
}
++v12;
putchar(10);
}
while ( map_height > v12 );
}
v16 = 27LL;
v17 = v39;
while ( v16 )
{
*v17++ = 0;
--v16;
}
v18 = 27LL;
v19 = v40;
while ( v18 )
{
*v19++ = 0;
--v18;
}
v20 = 27LL;
v21 = v41;
while ( v20 )
{
*v21++ = 0;
--v20;
}
if ( citycnt > 0 )
{
v22 = 96LL * citycnt;
v23 = 0LL;
do
{
v24 = *(int *)((char *)&cities + v23 + 24);
v23 += 96LL;
++v39[v24];
}
while ( v22 != v23 );
}
if ( armycnt > 0 )
{
v25 = (__int16 *)(armies + 16LL);
v26 = armies + 30LL * (unsigned int)(armycnt - 1) + 46;
do
{
v27 = *v25;
if ( *((_BYTE *)v25 + 7) )
++v41[v27];
else
++v40[v27];
v25 += 15;
}
while ( (__int16 *)v26 != v25 );
}
v28 = (unsigned int)((_DWORD)&nations + 32);
v29 = 1LL;
puts("\nNations:\n");
fwrite("No. Nation Ruler Mark ", 1uLL, 0x2BuLL, stdout);
fwrite("Cities Heros Armies\n", 1uLL, 0x17uLL, stdout);
fwrite("=== ============== ============== ==== ", 1uLL, 0x2BuLL, stdout);
fwrite("====== ====== ======\n", 1uLL, 0x17uLL, stdout);
if ( nationcnt > 1 )
{
do
{
v38 = *(char *)(marks + *(int *)(v28 + 16));
v30 = (const char *)nationcity((unsigned int)v29);
v31 = (const char *)v28;
v28 += 32LL;
printf("%3d %-14.14s %-14.14s %c ", (unsigned int)v29, v30, v31, v38);
v32 = (unsigned int)v40[v29];
v33 = (unsigned int)v41[v29];
v34 = (unsigned int)v39[v29++];
printf(" %3d %3d %3d\n", v34, v33, v32);
}
while ( nationcnt > (int)v29 );
}
v35 = (const char *)&cities;
puts("\nCities:\n");
if ( citycnt > 0 )
{
do
{
v36 = *((int *)v35 + 6);
v37 = (const char *)&unk_1B0;
if ( (_DWORD)v36 )
v37 = (char *)&cities + 96 * *((int *)&nations + 8 * v36 + 5);
printf(
"%3d %-14.14s %-14.14s R%02d C%02d\n",
(unsigned int)v5++,
v35,
v37,
*((unsigned int *)v35 + 4),
*((unsigned int *)v35 + 5));
v35 += 96;
}
while ( citycnt > v5 );
}
exit(0);
}
fprintf(stderr, "Error Loading Game Save (%s)\n", *((_QWORD *)&errors + v4));
}
}
exit(1);
}

canonical_decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
int v3; // eax
int v4; // eax
int v5; // er12
unsigned int v6; // er13
FILE *v7; // rbp
unsigned int v8; // eax
int v9; // ebx
int v10; // ebx
unsigned int v11; // edi
int v12; // ebp
int v13; // ebx
int v14; // esi
int v15; // eax
__int64 v16; // rcx
int *v17; // rdi
__int64 v18; // rcx
int *v19; // rdi
__int64 v20; // rcx
int *v21; // rdi
__int64 v22; // rcx
__int64 v23; // rax
__int64 v24; // rdx
__int16 *v25; // rax
__int64 v26; // rcx
__int64 v27; // rdx
__int64 v28; // r15
__int64 v29; // rbx
const char *v30; // rax
const char *v31; // rcx
__int64 v32; // rcx
__int64 v33; // rdx
__int64 v34; // rsi
const char *v35; // rbx
__int64 v36; // rax
const char *v37; // rcx
unsigned int v38; // [rsp+Ch] [rbp-20Ch]
int v39[28]; // [rsp+10h] [rbp-208h] BYREF
int v40[28]; // [rsp+80h] [rbp-198h] BYREF
int v41[28]; // [rsp+F0h] [rbp-128h] BYREF
char s[184]; // [rsp+160h] [rbp-B8h] BYREF

if ( argc > 1 && (*(_QWORD *)&argc = argv[1], chdir(*(const char **)&argc) == -1) )
{
fprintf(stderr, "Error Setting Directory %s\n", argv[1]);
}
else
{
v3 = loadmap(*(_QWORD *)&argc, argv, envp);
if ( v3 )
{
fprintf(stderr, "Error Loading Map (%s)\n", *((_QWORD *)&errors + v3));
}
else
{
v4 = loadsave();
v5 = v4;
if ( !v4 )
{
v6 = 0;
v7 = fopen("master.cmd", "r");
if ( v7 )
{
while ( fgets(s, 128, v7) )
{
++v6;
v8 = execpriv(s);
if ( v8 )
{
fprintf(stderr, "Master Cmd Failed, Line %d, Code %d\n", v6, v8);
exit(2);
}
}
fclose(v7);
}
v9 = 0;
func1();
fwrite(" ", 1uLL, 3uLL, stdout);
if ( map_width > 0 )
{
do
{
if ( __ROR4__(-858993459 * v9, 1) <= 0x19999999u )
putchar(v9 / 10 % 10 + 48);
else
putchar(32);
++v9;
}
while ( map_width > v9 );
}
v10 = 0;
fwrite("\n ", 1uLL, 4uLL, stdout);
if ( map_width > 0 )
{
do
{
v11 = v10++;
putchar(v11 % 0xA + 48);
}
while ( map_width > v10 );
}
v12 = 0;
putchar(10);
if ( map_height > 0 )
{
do
{
if ( v12 == 10 * (v12 / 0xAu) )
putchar(v12 / 10 % 10 + 48);
else
putchar(32);
v13 = 0;
putchar(v12 % 0xAu + 48);
putchar(32);
if ( map_width > 0 )
{
do
{
v14 = v13++;
v15 = func0(v12, v14);
putchar(v15);
}
while ( map_width > v13 );
}
++v12;
putchar(10);
}
while ( map_height > v12 );
}
v16 = 27LL;
v17 = v39;
while ( v16 )
{
*v17++ = 0;
--v16;
}
v18 = 27LL;
v19 = v40;
while ( v18 )
{
*v19++ = 0;
--v18;
}
v20 = 27LL;
v21 = v41;
while ( v20 )
{
*v21++ = 0;
--v20;
}
if ( citycnt > 0 )
{
v22 = 96LL * citycnt;
v23 = 0LL;
do
{
v24 = *(int *)((char *)&cities + v23 + 24);
v23 += 96LL;
++v39[v24];
}
while ( v22 != v23 );
}
if ( armycnt > 0 )
{
v25 = (__int16 *)(armies + 16LL);
v26 = armies + 30LL * (unsigned int)(armycnt - 1) + 46;
do
{
v27 = *v25;
if ( *((_BYTE *)v25 + 7) )
++v41[v27];
else
++v40[v27];
v25 += 15;
}
while ( (__int16 *)v26 != v25 );
}
v28 = (unsigned int)((_DWORD)&nations + 32);
v29 = 1LL;
puts("\nNations:\n");
fwrite("No. Nation Ruler Mark ", 1uLL, 0x2BuLL, stdout);
fwrite("Cities Heros Armies\n", 1uLL, 0x17uLL, stdout);
fwrite("=== ============== ============== ==== ", 1uLL, 0x2BuLL, stdout);
fwrite("====== ====== ======\n", 1uLL, 0x17uLL, stdout);
if ( nationcnt > 1 )
{
do
{
v38 = *(char *)(marks + *(int *)(v28 + 16));
v30 = (const char *)nationcity((unsigned int)v29);
v31 = (const char *)v28;
v28 += 32LL;
printf("%3d %-14.14s %-14.14s %c ", (unsigned int)v29, v30, v31, v38);
v32 = (unsigned int)v40[v29];
v33 = (unsigned int)v41[v29];
v34 = (unsigned int)v39[v29++];
printf(" %3d %3d %3d\n", v34, v33, v32);
}
while ( nationcnt > (int)v29 );
}
v35 = (const char *)&cities;
puts("\nCities:\n");
if ( citycnt > 0 )
{
do
{
v36 = *((int *)v35 + 6);
v37 = (const char *)&unk_1B0;
if ( (_DWORD)v36 )
v37 = (char *)&cities + 96 * *((int *)&nations + 8 * v36 + 5);
printf(
"%3d %-14.14s %-14.14s R%02d C%02d\n",
(unsigned int)v5++,
v35,
v37,
*((unsigned int *)v35 + 4),
*((unsigned int *)v35 + 5));
v35 += 96;
}
while ( citycnt > v5 );
}
exit(0);
}
fprintf(stderr, "Error Loading Game Save (%s)\n", *((_QWORD *)&errors + v4));
}
}
exit(1);
}

original_code:
int main(int argc, char *argv[])
{
    struct stat st_buf;
    char *gamedir, *p;
    if(chdir("/war") == -1) {
        gmove(20,18);
        gprintf("Error Setting Directory %s\n", "/war");
        ggetch();
        gend();
        exit(1);
    }
    if(argc > 1) {
        gamedir = argv[1];
        if(gamedir[0] == '.' && gamedir[1] == '.' && gamedir[2] == '\0') {
            gmove(20,18);
            gprintf("Invalid Directory Name %s\n", gamedir);
            ggetch();
            gend();
            exit(1);
        }
        for(p = gamedir; *p; p++) {
            if(*p == '/' || *p == '\\' || *p == ':') {
                gmove(20,18);
                gprintf("Invalid Directory Name %s\n", gamedir);
                ggetch();
                gend();
                exit(1);
            }
        }
        if(chdir(gamedir) == -1) {
            gmove(20,18);
            gprintf("Error Setting Directory %s\n", gamedir);
            ggetch();
            gend();
            exit(1);
        }
    }
    ginit();
    reader("news", 0);
    gend();
    exit(0);
}

canonical_original_code:
int main(int argc, char *argv[])
{
    struct stat st_buf;
    char *gamedir; char *p;
    if(chdir("/war") == -1) {
        gmove(20,18);
        gprintf("Error Setting Directory %s\n", "/war");
        ggetch();
        gend();
        exit(1);
    }
    if(argc > 1) {
        gamedir = argv[1];
        if(gamedir[0] == '.' && gamedir[1] == '.' && gamedir[2] == '\0') {
            gmove(20,18);
            gprintf("Invalid Directory Name %s\n", gamedir);
            ggetch();
            gend();
            exit(1);
        }
        for(p = gamedir; *p; p++) {
            if(*p == '/' || *p == '\\' || *p == ':') {
                gmove(20,18);
                gprintf("Invalid Directory Name %s\n", gamedir);
                ggetch();
                gend();
                exit(1);
            }
        }
        if(chdir(gamedir) == -1) {
            gmove(20,18);
            gprintf("Error Setting Directory %s\n", gamedir);
            ggetch();
            gend();
            exit(1);
        }
    }
    ginit();
    reader("news", 0);
    gend();
    exit(0);
}

variable_types: argc int

variable_types:
argv
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:
gamedir
char *

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


decompiled_code:
void nation_news()
{
;
}

canonical_decompiled_code:
void func2()
{
;
}

original_code:
void nation_news(char *name, int city)
{
    ;
}

variable_types:
name
char *

variable_types: city int


changearmy

original_code:
static int changearmy(int argc, char *argv[])
{
    int a, c, h;
    a = atoi(argv[1]);
    c = atoi(argv[2]);
    h = atoi(argv[3]);
    if(armies[a].nation == -1)
        return 0;
    if(c >= 0) armies[a].combat = c;
    if(h >= 0) armies[a].hero = h;
    return 0;
}

canonical_original_code:
static int changearmy(int argc, char *argv[])
{
    int a; int c; int h;
    a = atoi(argv[1]);
    c = atoi(argv[2]);
    h = atoi(argv[3]);
    if(armies[a].nation == -1)
        return 0;
    if(c >= 0) armies[a].combat = c;
    if(h >= 0) armies[a].hero = h;
    return 0;
}

variable_types: a int

variable_types: c int

variable_types: h int


killarmy

original_code:
static int killarmy(int argc, char *argv[])
{
    int a, i, n;
    a = atoi(argv[1]);
    if(a == -2) {
        i = atoi(argv[2]);
        n = atoi(argv[3]);
        if(n > 0) {
            armies[i].nation = n;
            if(armies[i].hero > 1)
                armies[i].hero--;
            return 0;
        }
        a = i;
    }
    if(a == -1) {
        n = atoi(argv[2]);
        if(n < 1 || n > nationcnt)
            return 0;
        for(i = 0; i < armycnt; i++)
            if(armies[i].nation == n) {
                armies[i].nation = -1;
                armies[i].r = -1;
                armies[i].c = -1;
            }
        return 0;
    }
    armies[a].nation = -1;
    armies[a].r = -1;
    armies[a].c = -1;
    return 0;
}

canonical_original_code:
static int killarmy(int argc, char *argv[])
{
    int a; int i; int n;
    a = atoi(argv[1]);
    if(a == -2) {
        i = atoi(argv[2]);
        n = atoi(argv[3]);
        if(n > 0) {
            armies[i].nation = n;
            if(armies[i].hero > 1)
                armies[i].hero--;
            return 0;
        }
        a = i;
    }
    if(a == -1) {
        n = atoi(argv[2]);
        if(n < 1 || n > nationcnt)
            return 0;
        for(i = 0; i < armycnt; i++)
            if(armies[i].nation == n) {
                armies[i].nation = -1;
                armies[i].r = -1;
                armies[i].c = -1;
            }
        return 0;
    }
    armies[a].nation = -1;
    armies[a].r = -1;
    armies[a].c = -1;
    return 0;
}

variable_types: n int


contcity

decompiled_code:
__int64 __fastcall contcity(__int64 a1, const char **a2)
{
const char *v2; // r12
int v3; // ebx
int v4; // eax
const char *v5; // rdi
__int64 v6; // r12
__int64 v7; // rbx
_DWORD *v8; // rbx

v2 = a2[1];
v3 = atoi(a2[2]);
v4 = atoi(v2);
v5 = a2[3];
v6 = 3LL * v3;
v7 = 24LL * v3;
cities[v7 + 6] = v4;
v8 = &cities[v7];
if ( v5 && atoi(v5) > 0 )
v8[22] = cities[8 * v6 + 13 + (int)v8[21]] + 1;
return 0LL;
}

original_code:
static int contcity(int argc, char *argv[])
{
    int c;
    cities[c = atoi(argv[2])].nation = atoi(argv[1]);
    if(argv[3] != ((void *)0) && atoi(argv[3]) > 0)
        cities[c].turns_left = cities[c].times[cities[c].prod_type] + 1;
    return 0;
}


seteparm

decompiled_code:
__int64 __fastcall seteparm(__int64 a1, __int64 a2)
{
unsigned int v2; // eax
__int64 v3; // rbp
__int64 result; // rax

v2 = atoi(*(const char **)(a2 + 8));
if ( v2 > 0x7CF )
{
fprintf(stdout, "ERROR set-eparm %d %s\n", v2, *(const char **)(a2 + 16));
result = 0LL;
}
else
{
v3 = 30LL * (int)v2;
if ( *(_WORD *)(armies + v3 + 16) != 0xFFFF )
*(_BYTE *)(armies + v3 + 24) = atoi(*(const char **)(a2 + 16));
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, __int64 a2)
{
unsigned int v2; // eax
__int64 v3; // rbp
__int64 result; // rax

v2 = atoi(*(const char **)(a2 + 8));
if ( v2 > 0x7CF )
{
fprintf(stdout, "ERROR set-eparm %d %s\n", v2, *(const char **)(a2 + 16));
result = 0LL;
}
else
{
v3 = 30LL * (int)v2;
if ( *(_WORD *)(armies + v3 + 16) != 0xFFFF )
*(_BYTE *)(armies + v3 + 24) = atoi(*(const char **)(a2 + 16));
result = 0LL;
}
return result;
}

original_code:
static int seteparm(int argc, char *argv[])
{
    int a;
    a = atoi(argv[1]);
    if(a < 0 || a >= 2000) {
        fprintf(stdout, "ERROR set-eparm %d %s\n", a, argv[2]);
        return 0;
    }
    if(armies[a].nation == -1)
        return 0;
    armies[a].eparm1 = atoi(argv[2]);
    return 0;
}


newnation

decompiled_code:
__int64 __fastcall newnation(__int64 a1, const char **a2)
{
unsigned int v2; // eax
char *v3; // rbp
int v4; // eax
const char *v5; // rdi
__int64 v6; // rbp
int v7; // eax
const char *v8; // rdi
__int64 v9; // rbp
int v10; // eax
int v11; // edx
int v12; // edi
__int64 v13; // rax
int v14; // ecx
int v15; // er8
_WORD *v16; // rax
__int64 v17; // rsi
__int64 result; // rax

v2 = atoi(a2[3]);
nation_news(a2[1], v2);
v3 = (char *)&nations[8 * nationcnt];
strcpy(v3, a2[1]);
v4 = atoi(a2[2]);
v5 = a2[3];
*((_DWORD *)v3 + 7) = v4;
v6 = 8LL * nationcnt;
v7 = atoi(v5);
v8 = a2[4];
nations[v6 + 5] = v7;
v9 = nationcnt;
v10 = atoi(v8);
v11 = armycnt;
nations[8 * v9 + 4] = v10;
v12 = nationcnt;
v13 = 24LL * nations[8 * nationcnt + 5];
v14 = cities[v13 + 4];
v15 = cities[v13 + 5];
if ( v11 > 0 )
{
v16 = (_WORD *)(armies + 16LL);
v17 = armies + 30LL * (unsigned int)(v11 - 1) + 46;
do
{
while ( (__int16)v16[1] != v14 || (__int16)v16[2] != v15 || *v16 )
{
v16 += 15;
if ( v16 == (_WORD *)v17 )
goto LABEL_8;
}
*v16 = v12;
v16 += 15;
}
while ( v16 != (_WORD *)v17 );
}
LABEL_8:
result = 0LL;
nationcnt = v12 + 1;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1, const char **a2)
{
unsigned int v2; // eax
char *v3; // rbp
int v4; // eax
const char *v5; // rdi
__int64 v6; // rbp
int v7; // eax
const char *v8; // rdi
__int64 v9; // rbp
int v10; // eax
int v11; // edx
int v12; // edi
__int64 v13; // rax
int v14; // ecx
int v15; // er8
_WORD *v16; // rax
__int64 v17; // rsi
__int64 result; // rax

v2 = atoi(a2[3]);
nation_news(a2[1], v2);
v3 = (char *)&nations[8 * nationcnt];
strcpy(v3, a2[1]);
v4 = atoi(a2[2]);
v5 = a2[3];
*((_DWORD *)v3 + 7) = v4;
v6 = 8LL * nationcnt;
v7 = atoi(v5);
v8 = a2[4];
nations[v6 + 5] = v7;
v9 = nationcnt;
v10 = atoi(v8);
v11 = armycnt;
nations[8 * v9 + 4] = v10;
v12 = nationcnt;
v13 = 24LL * nations[8 * nationcnt + 5];
v14 = cities[v13 + 4];
v15 = cities[v13 + 5];
if ( v11 > 0 )
{
v16 = (_WORD *)(armies + 16LL);
v17 = armies + 30LL * (unsigned int)(v11 - 1) + 46;
do
{
while ( (__int16)v16[1] != v14 || (__int16)v16[2] != v15 || *v16 )
{
v16 += 15;
if ( v16 == (_WORD *)v17 )
goto LABEL_8;
}
*v16 = v12;
v16 += 15;
}
while ( v16 != (_WORD *)v17 );
}
LABEL_8:
result = 0LL;
nationcnt = v12 + 1;
return result;
}

original_code:
static int newnation(int argc, char *argv[])
{
    int i, r, c;
    nation_news(argv[1], atoi(argv[3]));
    strcpy(nations[nationcnt].name, argv[1]);
    nations[nationcnt].uid = atoi(argv[2]);
    nations[nationcnt].city = atoi(argv[3]);
    nations[nationcnt].mark = atoi(argv[4]);
    r = cities[nations[nationcnt].city].r;
    c = cities[nations[nationcnt].city].c;
    for(i = 0; i < armycnt; i++)
        if(armies[i].r == r
        && armies[i].c == c
        && armies[i].nation == 0)
            armies[i].nation = nationcnt;
    nationcnt++;
    return 0;
}

canonical_original_code:
static int newnation(int argc, char *argv[])
{
    int i; int r; int c;
    nation_news(argv[1], atoi(argv[3]));
    strcpy(nations[nationcnt].name, argv[1]);
    nations[nationcnt].uid = atoi(argv[2]);
    nations[nationcnt].city = atoi(argv[3]);
    nations[nationcnt].mark = atoi(argv[4]);
    r = cities[nations[nationcnt].city].r;
    c = cities[nations[nationcnt].city].c;
    for(i = 0; i < armycnt; i++)
        if(armies[i].r == r
        && armies[i].c == c
        && armies[i].nation == 0)
            armies[i].nation = nationcnt;
    nationcnt++;
    return 0;
}

variable_types: r int


update

original_code:
static int update(int argc, char *argv[])
{
    int i, k, n, t, cnt, xch, max;
    do {
        xch = 0;
        for(k = 0; k < armycnt; k++)
            if(armies[k].nation == -1)
                break;
        if(k < armycnt) {
            for(i = armycnt - 1; i >= k; i--)
                if(armies[i].nation != -1)
                    break;
                else
                    armycnt--;
            if(i > k) {
                strcpy(armies[k].name, armies[i].name);
                armies[k].nation = armies[i].nation;
                armies[k].r = armies[i].r;
                armies[k].c = armies[i].c;
                armies[k].combat = armies[i].combat;
                armies[k].hero = armies[i].hero;
                armies[k].move_rate = armies[i].move_rate;
                armies[k].move_tbl = armies[i].move_tbl;
                armies[k].special_mv = armies[i].special_mv;
                armies[k].eparm1 = armies[i].eparm1;
                armycnt--;
                xch = 1;
            }
        }
    } while(xch);
    for(i = 0; i < citycnt; i++) {
        cnt = 0;
        for(k = 0; k < armycnt; k++)
            if(armies[k].nation == cities[i].nation
            && armies[k].r == cities[i].r
            && armies[k].c == cities[i].c)
                cnt++;
        max = cities[i].defense * 2;
        if(max > 10)
            max = 10;
        if(cities[i].nation != 0) {
            max = 12;
            k = cities[i].nation;
            if(nations[k].idle_turns >= 7)
                max = 0;
        }
        if(cnt < max) {
            n = cities[i].prod_type;
            if(n >= 0 && n < 4) {
                cities[i].turns_left--;
                if(cities[i].turns_left < 1) {
                    if(armycnt < 2000 - 1) {
                        t = cities[i].types[n];
                        sprintf(armies[armycnt].name,
                            ".%03d/%03d/%03d", i, t,
                            ++cities[i].instance[n]);
                        armies[armycnt].nation = cities[i].nation;
                        armies[armycnt].r = cities[i].r;
                        armies[armycnt].c = cities[i].c;
                        armies[armycnt].combat = ttypes[t].combat;
                        armies[armycnt].hero = 0;
                        armies[armycnt].move_rate = ttypes[t].move_rate;
                        armies[armycnt].move_tbl = ttypes[t].move_tbl;
                        armies[armycnt].special_mv =
                                            ttypes[t].special_mv;
                        armies[armycnt].eparm1 = 0;
                        armycnt++;
                        cities[i].turns_left = cities[i].times[n];
                    } else
                        cities[i].turns_left = 0;
                }
            }
        }
    }
    for(i = 0; i < armycnt; i++)
        armies[i].move_left = armies[i].move_rate;
    gen++;
    return 0;
}

canonical_original_code:
static int update(int argc, char *argv[])
{
    int i; int k; int n; int t; int cnt; int xch; int max;
    do {
        xch = 0;
        for(k = 0; k < armycnt; k++)
            if(armies[k].nation == -1)
                break;
        if(k < armycnt) {
            for(i = armycnt - 1; i >= k; i--)
                if(armies[i].nation != -1)
                    break;
                else
                    armycnt--;
            if(i > k) {
                strcpy(armies[k].name, armies[i].name);
                armies[k].nation = armies[i].nation;
                armies[k].r = armies[i].r;
                armies[k].c = armies[i].c;
                armies[k].combat = armies[i].combat;
                armies[k].hero = armies[i].hero;
                armies[k].move_rate = armies[i].move_rate;
                armies[k].move_tbl = armies[i].move_tbl;
                armies[k].special_mv = armies[i].special_mv;
                armies[k].eparm1 = armies[i].eparm1;
                armycnt--;
                xch = 1;
            }
        }
    } while(xch);
    for(i = 0; i < citycnt; i++) {
        cnt = 0;
        for(k = 0; k < armycnt; k++)
            if(armies[k].nation == cities[i].nation
            && armies[k].r == cities[i].r
            && armies[k].c == cities[i].c)
                cnt++;
        max = cities[i].defense * 2;
        if(max > 10)
            max = 10;
        if(cities[i].nation != 0) {
            max = 12;
            k = cities[i].nation;
            if(nations[k].idle_turns >= 7)
                max = 0;
        }
        if(cnt < max) {
            n = cities[i].prod_type;
            if(n >= 0 && n < 4) {
                cities[i].turns_left--;
                if(cities[i].turns_left < 1) {
                    if(armycnt < 2000 - 1) {
                        t = cities[i].types[n];
                        sprintf(armies[armycnt].name,
                            ".%03d/%03d/%03d", i, t,
                            ++cities[i].instance[n]);
                        armies[armycnt].nation = cities[i].nation;
                        armies[armycnt].r = cities[i].r;
                        armies[armycnt].c = cities[i].c;
                        armies[armycnt].combat = ttypes[t].combat;
                        armies[armycnt].hero = 0;
                        armies[armycnt].move_rate = ttypes[t].move_rate;
                        armies[armycnt].move_tbl = ttypes[t].move_tbl;
                        armies[armycnt].special_mv =
                                            ttypes[t].special_mv;
                        armies[armycnt].eparm1 = 0;
                        armycnt++;
                        cities[i].turns_left = cities[i].times[n];
                    } else
                        cities[i].turns_left = 0;
                }
            }
        }
    }
    for(i = 0; i < armycnt; i++)
        armies[i].move_left = armies[i].move_rate;
    gen++;
    return 0;
}

variable_types: k int

variable_types: t int

variable_types: cnt int

variable_types: xch int

variable_types: max int


execpriv

decompiled_code:
__int64 execpriv()
{
const char **v0; // rax
const char *v1; // rbp
const char **v2; // r12
__int64 v3; // rbx
const char *v4; // rdi
__int64 (__fastcall *v5)(_QWORD, const char **); // rbx
unsigned int v6; // eax

v0 = (const char **)parseline();
v1 = *v0;
if ( !*v0 )
return 5LL;
v2 = v0;
v3 = 0LL;
v4 = "global-update";
do
{
if ( !strcmp(v4, v1) )
{
v5 = (__int64 (__fastcall *)(_QWORD, const char **))*(&off_C28 + 2 * (int)v3);
v6 = countargs(v2);
return v5(v6, v2);
}
++v3;
v4 = (&table)[2 * v3];
}
while ( v4 );
return 6LL;
}

canonical_decompiled_code:
__int64 func10()
{
const char **v0; // rax
const char *v1; // rbp
const char **v2; // r12
__int64 v3; // rbx
const char *v4; // rdi
__int64 (__fastcall *v5)(_QWORD, const char **); // rbx
unsigned int v6; // eax

v0 = (const char **)parseline();
v1 = *v0;
if ( !*v0 )
return 5LL;
v2 = v0;
v3 = 0LL;
v4 = "global-update";
do
{
if ( !strcmp(v4, v1) )
{
v5 = (__int64 (__fastcall *)(_QWORD, const char **))*(&off_C28 + 2 * (int)v3);
v6 = countargs(v2);
return v5(v6, v2);
}
++v3;
v4 = (&table)[2 * v3];
}
while ( v4 );
return 6LL;
}

original_code:
int execpriv(char *line)
{
    char **args;
    int n;
    args = parseline(line);
    if(args[0] == ((void *)0))
        return 5;
    for(n = 0; table[n].command != ((void *)0); n++)
        if(strcmp(table[n].command, args[0]) == 0)
            break;
    if(table[n].command == ((void *)0))
        return 6;
    return table[n].func(countargs(args), args);
}

variable_types:
line
char *

variable_types:
args
char **


setprod

decompiled_code:
__int64 __fastcall setprod(__int64 a1, __int64 a2)
{
int v2; // ebx
int v3; // eax
__int64 v4; // rdx

v2 = atoi(*(const char **)(a2 + 8));
v3 = atoi(*(const char **)(a2 + 16));
v4 = 24LL * v2;
cities[v4 + 21] = v3;
cities[v4 + 22] = cities[24 * v2 + 13 + v3];
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2)
{
int v2; // ebx
int v3; // eax
__int64 v4; // rdx

v2 = atoi(*(const char **)(a2 + 8));
v3 = atoi(*(const char **)(a2 + 16));
v4 = 24LL * v2;
cities[v4 + 21] = v3;
cities[v4 + 22] = cities[24 * v2 + 13 + v3];
return 0LL;
}

original_code:
static int setprod(int argc, char *argv[])
{
    int c;
    c = atoi(argv[1]);
    cities[c].prod_type = atoi(argv[2]);
    cities[c].turns_left = cities[c].times[cities[c].prod_type];
    return 0;
}

variable_types: argc int

variable_types:
argv
char *[]


movearmy

decompiled_code:
__int64 __fastcall movearmy(__int64 a1, const char **a2)
{
__int64 v2; // rbx
int v3; // er12
int v4; // er12
__int16 v5; // ax
const char *v6; // rdi

v2 = 30LL * atoi(a2[1]);
if ( *(_WORD *)(v2 + armies + 16) != 0xFFFF )
{
v3 = *(unsigned __int8 *)(v2 + armies + 27);
v4 = v3 - atoi(a2[2]);
if ( v4 < 0 )
LOBYTE(v4) = 0;
*(_BYTE *)(armies + v2 + 27) = v4;
v5 = atoi(a2[3]);
v6 = a2[4];
*(_WORD *)(armies + v2 + 18) = v5;
*(_WORD *)(armies + v2 + 20) = atoi(v6);
}
return 0LL;
}

original_code:
static int movearmy(int argc, char *argv[])
{
    int a, b;
    a = atoi(argv[1]);
    if(armies[a].nation == -1)
        return 0;
    b = armies[a].move_left;
    b -= atoi(argv[2]);
    if(b < 0)
        b = 0;
    armies[a].move_left = b;
    armies[a].r = atoi(argv[3]);
    armies[a].c = atoi(argv[4]);
    return 0;
}

canonical_original_code:
static int movearmy(int argc, char *argv[])
{
    int a; int b;
    a = atoi(argv[1]);
    if(armies[a].nation == -1)
        return 0;
    b = armies[a].move_left;
    b -= atoi(argv[2]);
    if(b < 0)
        b = 0;
    armies[a].move_left = b;
    armies[a].r = atoi(argv[3]);
    armies[a].c = atoi(argv[4]);
    return 0;
}

variable_types: b int


namearmy

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

v2 = 30LL * atoi(*(const char **)(a2 + 8));
if ( *(_WORD *)(v2 + armies + 16) != 0xFFFF )
{
strncpy((char *)(v2 + armies), *(const char **)(a2 + 16), 0xEuLL);
*(_BYTE *)(armies + v2 + 14) = 0;
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func6(__int64 a1, __int64 a2)
{
__int64 v2; // rbx

v2 = 30LL * atoi(*(const char **)(a2 + 8));
if ( *(_WORD *)(v2 + armies + 16) != 0xFFFF )
{
strncpy((char *)(v2 + armies), *(const char **)(a2 + 16), 0xEuLL);
*(_BYTE *)(armies + v2 + 14) = 0;
}
return 0LL;
}

original_code:
static int namearmy(int argc, char *argv[])
{
    int a;
    a = atoi(argv[1]);
    if(armies[a].nation == -1)
        return 0;
    strncpy(armies[a].name, argv[2], 14);
    armies[a].name[14] = '\0';
    return 0;
}