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

v2 = *(void ***)(a1 + 8);
if ( (unsigned __int64)v2 >= *(_QWORD *)(a1 + 16) )
{
result = &unk_E16;
if ( a2 != 20 )
result = 0LL;
}
else
{
*(_QWORD *)(a1 + 8) = v2 + 1;
result = *v2;
}
return result;
}

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

v2 = *(void ***)(a1 + 8);
if ( (unsigned __int64)v2 >= *(_QWORD *)(a1 + 16) )
{
result = &unk_E16;
if ( a2 != 20 )
result = 0LL;
}
else
{
*(_QWORD *)(a1 + 8) = v2 + 1;
result = *v2;
}
return result;
}

original_code:
static const char *
ptest_getopnd(Test_env *te, Test_op op, int do_eval)
{
 if (te->pos.wp >= te->wp_end)
  return op == TO_FILTT ? "1" : ((void *)0);
 return *te->pos.wp++;
}

canonical_original_code:
static char *ptest_getopnd(struct test_env *te, enum Test_op op, int do_eval)
{
 if (te->pos.wp >= te->wp_end)
  return op == TO_FILTT ? "1" : ((void *)0);
 return *te->pos.wp++;
}

variable_types: struct test_env { int flags; union { char **wp; struct XPtrV { void **cur; void **beg; } *av; } pos; char **wp_end; int (*isa)(struct test_env *, enum Test_meta { TM_OR=0, TM_AND=1, TM_NOT=2, TM_OPAREN=3, TM_CPAREN=4, TM_UNOP=5, TM_BINOP=6, TM_END=7 }); char *(*getopnd)(struct test_env *, enum Test_op { TO_NONOP=0, TO_STNZE=1, TO_STZER=2, TO_OPTION=3, TO_FILAXST=4, TO_FILEXST=5, TO_FILREG=6, TO_FILBDEV=7, TO_FILCDEV=8, TO_FILSYM=9, TO_FILFIFO=10, TO_FILSOCK=11, TO_FILCDF=12, TO_FILID=13, TO_FILGID=14, TO_FILSETG=15, TO_FILSTCK=16, TO_FILUID=17, TO_FILRD=18, TO_FILGZ=19, TO_FILTT=20, TO_FILSETU=21, TO_FILWR=22, TO_FILEX=23, TO_STEQL=24, TO_STNEQ=25, TO_STLT=26, TO_STGT=27, TO_INTEQ=28, TO_INTNE=29, TO_INTGT=30, TO_INTGE=31, TO_INTLT=32, TO_INTLE=33, TO_FILEQ=34, TO_FILNT=35, TO_FILOT=36 }, int); int (*eval)(struct test_env *, enum Test_op { TO_NONOP=0, TO_STNZE=1, TO_STZER=2, TO_OPTION=3, TO_FILAXST=4, TO_FILEXST=5, TO_FILREG=6, TO_FILBDEV=7, TO_FILCDEV=8, TO_FILSYM=9, TO_FILFIFO=10, TO_FILSOCK=11, TO_FILCDF=12, TO_FILID=13, TO_FILGID=14, TO_FILSETG=15, TO_FILSTCK=16, TO_FILUID=17, TO_FILRD=18, TO_FILGZ=19, TO_FILTT=20, TO_FILSETU=21, TO_FILWR=22, TO_FILEX=23, TO_STEQL=24, TO_STNEQ=25, TO_STLT=26, TO_STGT=27, TO_INTEQ=28, TO_INTNE=29, TO_INTGT=30, TO_INTGE=31, TO_INTLT=32, TO_INTLE=33, TO_FILEQ=34, TO_FILNT=35, TO_FILOT=36 }, char *, char *, int); void (*error)(struct test_env *, int, char *); } *

return_type: char *

user_defined_types: struct test_env { int flags; union { char **wp; struct XPtrV *av; } pos; char **wp_end; int (*isa)(struct test_env *, enum Test_meta); char *(*getopnd)(struct test_env *, enum Test_op, int); int (*eval)(struct test_env *, enum Test_op, char *, char *, int); void (*error)(struct test_env *, int, char *); }


repo: levaidaniel/ksh-openbsd

decompiled_code:
__int64 __fastcall ptest_error(__int64 a1, int a2, const char *a3)
{
const char **v3; // rax
const char *v4; // rsi

v3 = (const char **)(*(_QWORD *)(a1 + 8) + 8LL * a2);
if ( (unsigned __int64)v3 >= *(_QWORD *)(a1 + 16) )
{
*(_DWORD *)a1 |= 1u;
}
else
{
v4 = *v3;
*(_DWORD *)a1 |= 1u;
if ( v4 )
return bi_errorf("%s: %s", v4, a3);
}
return bi_errorf("%s", a3);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, int a2, const char *a3)
{
const char **v3; // rax
const char *v4; // rsi

v3 = (const char **)(*(_QWORD *)(a1 + 8) + 8LL * a2);
if ( (unsigned __int64)v3 >= *(_QWORD *)(a1 + 16) )
{
*(_DWORD *)a1 |= 1u;
}
else
{
v4 = *v3;
*(_DWORD *)a1 |= 1u;
if ( v4 )
return bi_errorf("%s: %s", v4, a3);
}
return bi_errorf("%s", a3);
}

original_code:
static void
ptest_error(Test_env *te, int offset, const char *msg)
{
 const char *op = te->pos.wp + offset >= te->wp_end ?
     ((void *)0) : te->pos.wp[offset];
 te->flags |= (1<<(0));
 if (op)
  bi_errorf("%s: %s", op, msg);
 else
  bi_errorf("%s", msg);
}

canonical_original_code:
static void ptest_error(struct test_env *te, int offset, char *msg)
{
 char *op = te->pos.wp + offset >= te->wp_end ?
     ((void *)0) : te->pos.wp[offset];
 te->flags |= (1<<(0));
 if (op)
  bi_errorf("%s: %s", op, msg);
 else
  bi_errorf("%s", msg);
}

variable_types: offset int

variable_types:
msg
char *

variable_types:
op
char *

return_type: void

user_defined_types: struct XPtrV { void **cur; void **beg; }

user_defined_types: enum Test_meta { TM_OR=0, TM_AND=1, TM_NOT=2, TM_OPAREN=3, TM_CPAREN=4, TM_UNOP=5, TM_BINOP=6, TM_END=7 }

user_defined_types: enum Test_op { TO_NONOP=0, TO_STNZE=1, TO_STZER=2, TO_OPTION=3, TO_FILAXST=4, TO_FILEXST=5, TO_FILREG=6, TO_FILBDEV=7, TO_FILCDEV=8, TO_FILSYM=9, TO_FILFIFO=10, TO_FILSOCK=11, TO_FILCDF=12, TO_FILID=13, TO_FILGID=14, TO_FILSETG=15, TO_FILSTCK=16, TO_FILUID=17, TO_FILRD=18, TO_FILGZ=19, TO_FILTT=20, TO_FILSETU=21, TO_FILWR=22, TO_FILEX=23, TO_STEQL=24, TO_STNEQ=25, TO_STLT=26, TO_STGT=27, TO_INTEQ=28, TO_INTNE=29, TO_INTGT=30, TO_INTGE=31, TO_INTLT=32, TO_INTLE=33, TO_FILEQ=34, TO_FILNT=35, TO_FILOT=36 }


decompiled_code:
__int64 __fastcall test_eaccess(char *file, char a2)
{
unsigned int v2; // ebx
struct stat v4; // [rsp+0h] [rbp-A8h] BYREF

v2 = access(file, a2);
if ( !v2 && !ksheuid )
{
if ( (a2 & 1) != 0 )
{
if ( stat(file, &v4) == -1 )
{
v2 = -1;
}
else if ( (v4.st_mode & 0xF000) != 0x4000 )
{
v2 = -((v4.st_mode & 0x49) == 0);
}
}
else
{
v2 = 0;
}
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func2(char *file, char a2)
{
unsigned int v2; // ebx
struct stat v4; // [rsp+0h] [rbp-A8h] BYREF

v2 = access(file, a2);
if ( !v2 && !ksheuid )
{
if ( (a2 & 1) != 0 )
{
if ( stat(file, &v4) == -1 )
{
v2 = -1;
}
else if ( (v4.st_mode & 0xF000) != 0x4000 )
{
v2 = -((v4.st_mode & 0x49) == 0);
}
}
else
{
v2 = 0;
}
}
return v2;
}

original_code:
static int
test_eaccess(const char *path, int amode)
{
 int res;
 res = access(path, amode);
 if (res == 0 && ksheuid == 0 && (amode & 1)) {
  struct stat statb;
  if (stat(path, &statb) == -1)
   res = -1;
  else if (((((statb.st_mode)) & 0170000) == (0040000)))
   res = 0;
  else
   res = (statb.st_mode & (0100|(0100 >> 3)|((0100 >> 3) >> 3))) ?
       0 : -1;
 }
 return res;
}

canonical_original_code:
static int test_eaccess(char *path, int amode)
{
 int res;
 res = access(path, amode);
 if (res == 0 && ksheuid == 0 && (amode & 1)) {
  struct stat statb;
  if (stat(path, &statb) == -1)
   res = -1;
  else if (((((statb.st_mode)) & 0170000) == (0040000)))
   res = 0;
  else
   res = (statb.st_mode & (0100|(0100 >> 3)|((0100 >> 3) >> 3))) ?
       0 : -1;
 }
 return res;
}

variable_types:
path
char *

variable_types: amode int

variable_types: res int

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]; }

return_type: int

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


decompiled_code:
__int64 __fastcall test_isop(__int64 a1, int a2, __int64 a3)
{
const char *v3; // rbx
__int64 result; // rax
char v6; // bp

v3 = (const char *)&u_ops;
if ( a2 != 5 )
v3 = "=";
result = 0LL;
if ( *(_BYTE *)a3 )
{
v6 = *(_BYTE *)(a3 + 1);
do
{
if ( v3[1] == v6 && !strcmp((const char *)a3, v3) )
return *((unsigned int *)v3 + 1);
v3 += 8;
}
while ( *v3 );
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, int a2, __int64 a3)
{
const char *v3; // rbx
__int64 result; // rax
char v6; // bp

v3 = (const char *)&u_ops;
if ( a2 != 5 )
v3 = "=";
result = 0LL;
if ( *(_BYTE *)a3 )
{
v6 = *(_BYTE *)(a3 + 1);
do
{
if ( v3[1] == v6 && !strcmp((const char *)a3, v3) )
return *((unsigned int *)v3 + 1);
v3 += 8;
}
while ( *v3 );
result = 0LL;
}
return result;
}

original_code:
Test_op
test_isop(Test_env *te, Test_meta meta, const char *s)
{
 char sc1;
 const struct t_op *otab;
 otab = meta == TM_UNOP ? u_ops : b_ops;
 if (*s) {
  sc1 = s[1];
  for (; otab->op_text[0]; otab++)
   if (sc1 == otab->op_text[1] &&
       strcmp(s, otab->op_text) == 0)
    return otab->op_num;
 }
 return TO_NONOP;
}

canonical_original_code:
enum Test_op test_isop(struct test_env *te, enum Test_meta meta, char *s)
{
 char sc1;
 struct t_op *otab;
 otab = meta == TM_UNOP ? u_ops : b_ops;
 if (*s) {
  sc1 = s[1];
  for (; otab->op_text[0]; otab++)
   if (sc1 == otab->op_text[1] &&
       strcmp(s, otab->op_text) == 0)
    return otab->op_num;
 }
 return TO_NONOP;
}

variable_types: enum Test_meta { TM_OR=0, TM_AND=1, TM_NOT=2, TM_OPAREN=3, TM_CPAREN=4, TM_UNOP=5, TM_BINOP=6, TM_END=7 }

variable_types:
s
char *

variable_types: struct t_op { char op_text[4]; enum Test_op { TO_NONOP=0, TO_STNZE=1, TO_STZER=2, TO_OPTION=3, TO_FILAXST=4, TO_FILEXST=5, TO_FILREG=6, TO_FILBDEV=7, TO_FILCDEV=8, TO_FILSYM=9, TO_FILFIFO=10, TO_FILSOCK=11, TO_FILCDF=12, TO_FILID=13, TO_FILGID=14, TO_FILSETG=15, TO_FILSTCK=16, TO_FILUID=17, TO_FILRD=18, TO_FILGZ=19, TO_FILTT=20, TO_FILSETU=21, TO_FILWR=22, TO_FILEX=23, TO_STEQL=24, TO_STNEQ=25, TO_STLT=26, TO_STGT=27, TO_INTEQ=28, TO_INTNE=29, TO_INTGT=30, TO_INTGE=31, TO_INTLT=32, TO_INTLE=33, TO_FILEQ=34, TO_FILNT=35, TO_FILOT=36 } op_num; } *

user_defined_types: struct t_op { char op_text[4]; enum Test_op op_num; }


decompiled_code:
__int64 __fastcall ptest_isa(__int64 a1, int a2)
{
__int64 *v2; // rbp
__int64 result; // rax
int v4; // edx

v2 = *(__int64 **)(a1 + 8);
if ( (unsigned __int64)v2 >= *(_QWORD *)(a1 + 16) )
return a2 == 7;
if ( (unsigned int)(a2 - 5) <= 1 )
{
result = test_isop(a1, a2, *v2);
if ( (_DWORD)result )
goto LABEL_6;
}
else
{
result = 0LL;
if ( a2 != 7 )
{
v4 = strcmp((const char *)*v2, (&tokens_0)[a2]);
result = 0LL;
if ( !v4 )
{
result = 1LL;
LABEL_6:
*(_QWORD *)(a1 + 8) = v2 + 1;
return result;
}
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, int a2)
{
__int64 *v2; // rbp
__int64 result; // rax
int v4; // edx

v2 = *(__int64 **)(a1 + 8);
if ( (unsigned __int64)v2 >= *(_QWORD *)(a1 + 16) )
return a2 == 7;
if ( (unsigned int)(a2 - 5) <= 1 )
{
result = func3(a1, a2, *v2);
if ( (_DWORD)result )
goto LABEL_6;
}
else
{
result = 0LL;
if ( a2 != 7 )
{
v4 = strcmp((const char *)*v2, (&tokens_0)[a2]);
result = 0LL;
if ( !v4 )
{
result = 1LL;
LABEL_6:
*(_QWORD *)(a1 + 8) = v2 + 1;
return result;
}
}
}
return result;
}

original_code:
static int
ptest_isa(Test_env *te, Test_meta meta)
{
 static const char *const tokens[] = {
  "-o", "-a", "!", "(", ")"
 };
 int ret;
 if (te->pos.wp >= te->wp_end)
  return meta == TM_END;
 if (meta == TM_UNOP || meta == TM_BINOP)
  ret = (int) test_isop(te, meta, *te->pos.wp);
 else if (meta == TM_END)
  ret = 0;
 else
  ret = strcmp(*te->pos.wp, tokens[(int) meta]) == 0;
 if (ret)
  te->pos.wp++;
 return ret;
}

canonical_original_code:
static int ptest_isa(struct test_env *te, enum Test_meta meta)
{
 static char *tokens[] = {
  "-o", "-a", "!", "(", ")"
 };
 int ret;
 if (te->pos.wp >= te->wp_end)
  return meta == TM_END;
 if (meta == TM_UNOP || meta == TM_BINOP)
  ret = (int) test_isop(te, meta, *te->pos.wp);
 else if (meta == TM_END)
  ret = 0;
 else
  ret = strcmp(*te->pos.wp, tokens[(int) meta]) == 0;
 if (ret)
  te->pos.wp++;
 return ret;
}

variable_types:
tokens
char *[]

variable_types: ret int


original_code:
static int
test_primary(Test_env *te, int do_eval)
{
 const char *opnd1, *opnd2;
 int res;
 Test_op op;
 if (te->flags & (1<<(0)))
  return 0;
 if ((*te->isa)(te, TM_OPAREN)) {
  res = test_oexpr(te, do_eval);
  if (te->flags & (1<<(0)))
   return 0;
  if (!(*te->isa)(te, TM_CPAREN)) {
   (*te->error)(te, 0, "missing closing paren");
   return 0;
  }
  return res;
 }
 if ((te->flags & (1<<(1))) || (&te->pos.wp[1] < te->wp_end &&
     !test_isop(te, TM_BINOP, te->pos.wp[1]))) {
  if ((op = (Test_op) (*te->isa)(te, TM_UNOP))) {
   opnd1 = (*te->getopnd)(te, op, do_eval);
   if (!opnd1) {
    (*te->error)(te, -1, "missing argument");
    return 0;
   }
   return (*te->eval)(te, op, opnd1, ((void *)0),
       do_eval);
  }
 }
 opnd1 = (*te->getopnd)(te, TO_NONOP, do_eval);
 if (!opnd1) {
  (*te->error)(te, 0, "expression expected");
  return 0;
 }
 if ((op = (Test_op) (*te->isa)(te, TM_BINOP))) {
  opnd2 = (*te->getopnd)(te, op, do_eval);
  if (!opnd2) {
   (*te->error)(te, -1, "missing second argument");
   return 0;
  }
  return (*te->eval)(te, op, opnd1, opnd2, do_eval);
 }
 if (te->flags & (1<<(1))) {
  (*te->error)(te, -1, "missing expression operator");
  return 0;
 }
 return (*te->eval)(te, TO_STNZE, opnd1, ((void *)0), do_eval);
}

canonical_original_code:
static int test_primary(struct test_env *te, int do_eval)
{
 char *opnd1; char *opnd2;
 int res;
 enum Test_op op;
 if (te->flags & (1<<(0)))
  return 0;
 if ((*te->isa)(te, TM_OPAREN)) {
  res = test_oexpr(te, do_eval);
  if (te->flags & (1<<(0)))
   return 0;
  if (!(*te->isa)(te, TM_CPAREN)) {
   (*te->error)(te, 0, "missing closing paren");
   return 0;
  }
  return res;
 }
 if ((te->flags & (1<<(1))) || (&te->pos.wp[1] < te->wp_end &&
     !test_isop(te, TM_BINOP, te->pos.wp[1]))) {
  if ((op = (Test_op) (*te->isa)(te, TM_UNOP))) {
   opnd1 = (*te->getopnd)(te, op, do_eval);
   if (!opnd1) {
    (*te->error)(te, -1, "missing argument");
    return 0;
   }
   return (*te->eval)(te, op, opnd1, ((void *)0),
       do_eval);
  }
 }
 opnd1 = (*te->getopnd)(te, TO_NONOP, do_eval);
 if (!opnd1) {
  (*te->error)(te, 0, "expression expected");
  return 0;
 }
 if ((op = (Test_op) (*te->isa)(te, TM_BINOP))) {
  opnd2 = (*te->getopnd)(te, op, do_eval);
  if (!opnd2) {
   (*te->error)(te, -1, "missing second argument");
   return 0;
  }
  return (*te->eval)(te, op, opnd1, opnd2, do_eval);
 }
 if (te->flags & (1<<(1))) {
  (*te->error)(te, -1, "missing expression operator");
  return 0;
 }
 return (*te->eval)(te, TO_STNZE, opnd1, ((void *)0), do_eval);
}

variable_types: enum Test_op { TO_NONOP=0, TO_STNZE=1, TO_STZER=2, TO_OPTION=3, TO_FILAXST=4, TO_FILEXST=5, TO_FILREG=6, TO_FILBDEV=7, TO_FILCDEV=8, TO_FILSYM=9, TO_FILFIFO=10, TO_FILSOCK=11, TO_FILCDF=12, TO_FILID=13, TO_FILGID=14, TO_FILSETG=15, TO_FILSTCK=16, TO_FILUID=17, TO_FILRD=18, TO_FILGZ=19, TO_FILTT=20, TO_FILSETU=21, TO_FILWR=22, TO_FILEX=23, TO_STEQL=24, TO_STNEQ=25, TO_STLT=26, TO_STGT=27, TO_INTEQ=28, TO_INTNE=29, TO_INTGT=30, TO_INTGE=31, TO_INTLT=32, TO_INTLE=33, TO_FILEQ=34, TO_FILNT=35, TO_FILOT=36 }


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

if ( (*(_BYTE *)a1 & 1) == 0 && (*(unsigned int (__fastcall **)(__int64, __int64))(a1 + 24))(a1, 2LL) )
result = (unsigned int)test_nexpr(a1, a2) == 0;
else
result = test_primary(a1, a2);
return result;
}

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

if ( (*(_BYTE *)a1 & 1) == 0 && (*(unsigned int (__fastcall **)(__int64, __int64))(a1 + 24))(a1, 2LL) )
result = (unsigned int)func6(a1, a2) == 0;
else
result = func5(a1, a2);
return result;
}

original_code:
static int
test_nexpr(Test_env *te, int do_eval)
{
 if (!(te->flags & (1<<(0))) && (*te->isa)(te, TM_NOT))
  return !test_nexpr(te, do_eval);
 return test_primary(te, do_eval);
}

canonical_original_code:
static int test_nexpr(struct test_env *te, int do_eval)
{
 if (!(te->flags & (1<<(0))) && (*te->isa)(te, TM_NOT))
  return !test_nexpr(te, do_eval);
 return test_primary(te, do_eval);
}


decompiled_code:
__int64 __fastcall test_aexpr(__int64 a1, unsigned int a2)
{
unsigned int v2; // er12
unsigned int v3; // ebx

v2 = a2;
v3 = test_nexpr(a1, a2);
if ( !v3 )
v2 = 0;
if ( (*(_BYTE *)a1 & 1) == 0 && (*(unsigned int (__fastcall **)(__int64, __int64))(a1 + 24))(a1, 1LL) )
v3 = (v3 != 0) & ((unsigned int)test_aexpr(a1, v2) != 0);
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, unsigned int a2)
{
unsigned int v2; // er12
unsigned int v3; // ebx

v2 = a2;
v3 = func6(a1, a2);
if ( !v3 )
v2 = 0;
if ( (*(_BYTE *)a1 & 1) == 0 && (*(unsigned int (__fastcall **)(__int64, __int64))(a1 + 24))(a1, 1LL) )
v3 = (v3 != 0) & ((unsigned int)func7(a1, v2) != 0);
return v3;
}

original_code:
static int
test_aexpr(Test_env *te, int do_eval)
{
 int res;
 res = test_nexpr(te, do_eval);
 if (!res)
  do_eval = 0;
 if (!(te->flags & (1<<(0))) && (*te->isa)(te, TM_AND))
  return test_aexpr(te, do_eval) && res;
 return res;
}

canonical_original_code:
static int test_aexpr(struct test_env *te, int do_eval)
{
 int res;
 res = test_nexpr(te, do_eval);
 if (!res)
  do_eval = 0;
 if (!(te->flags & (1<<(0))) && (*te->isa)(te, TM_AND))
  return test_aexpr(te, do_eval) && res;
 return res;
}


decompiled_code:
__int64 __fastcall test_oexpr(__int64 a1, unsigned int a2)
{
unsigned int v2; // ebp
unsigned int v3; // er12

v2 = a2;
v3 = test_aexpr(a1, a2);
if ( v3 )
v2 = 0;
if ( (*(_BYTE *)a1 & 1) == 0 && (*(unsigned int (__fastcall **)(__int64, _QWORD))(a1 + 24))(a1, 0LL) )
v3 = (v3 | (unsigned int)test_oexpr(a1, v2)) != 0;
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1, unsigned int a2)
{
unsigned int v2; // ebp
unsigned int v3; // er12

v2 = a2;
v3 = func7(a1, a2);
if ( v3 )
v2 = 0;
if ( (*(_BYTE *)a1 & 1) == 0 && (*(unsigned int (__fastcall **)(__int64, _QWORD))(a1 + 24))(a1, 0LL) )
v3 = (v3 | (unsigned int)func8(a1, v2)) != 0;
return v3;
}

original_code:
static int
test_oexpr(Test_env *te, int do_eval)
{
 int res;
 res = test_aexpr(te, do_eval);
 if (res)
  do_eval = 0;
 if (!(te->flags & (1<<(0))) && (*te->isa)(te, TM_OR))
  return test_oexpr(te, do_eval) || res;
 return res;
}

canonical_original_code:
static int test_oexpr(struct test_env *te, int do_eval)
{
 int res;
 res = test_aexpr(te, do_eval);
 if (res)
  do_eval = 0;
 if (!(te->flags & (1<<(0))) && (*te->isa)(te, TM_OR))
  return test_oexpr(te, do_eval) || res;
 return res;
}


decompiled_code:
__int64 __fastcall test_eval(__int64 a1, int a2, char *a3, const char *a4, __mode_t a5)
{
__mode_t v5; // er14
int v9; // eax
int v10; // eax
int v11; // edi
__gid_t v12; // ebx
unsigned int v13; // eax
unsigned int v14; // eax
__int64 v15; // [rsp+0h] [rbp-168h] BYREF
__int64 v16; // [rsp+8h] [rbp-160h] BYREF
struct stat v17; // [rsp+10h] [rbp-158h] BYREF
struct stat v18; // [rsp+A0h] [rbp-C8h] BYREF
int fd[11]; // [rsp+13Ch] [rbp-2Ch] BYREF

v5 = a5;
if ( a5 )
{
switch ( a2 )
{
case 1:
return *a3 != 0;
case 2:
return *a3 == 0;
case 3:
if ( *a3 == 33 )
{
v10 = option(a3 + 1);
if ( v10 >= 0 )
{
fd[0] = *((_BYTE *)&shell_flags + v10) == 0;
return (__mode_t)fd[0];
}
}
else
{
v9 = option(a3);
if ( v9 >= 0 )
{
fd[0] = *((char *)&shell_flags + v9);
return (__mode_t)fd[0];
}
}
fd[0] = 0;
return (__mode_t)fd[0];
case 4:
case 5:
return stat(a3, &v18) == 0;
case 6:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode & 0xF000) == 0x8000;
return v5;
case 7:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode & 0xF000) == 24576;
return v5;
case 8:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode & 0xF000) == 0x2000;
return v5;
case 9:
v5 = 0;
if ( !lstat(a3, &v18) )
v5 = (v18.st_mode & 0xF000) == 40960;
return v5;
case 10:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode & 0xF000) == 4096;
return v5;
case 11:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode & 0xF000) == 49152;
return v5;
case 12:
return 0;
case 13:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode & 0xF000) == 0x4000;
return v5;
case 14:
v5 = 0;
if ( !stat(a3, &v18) )
{
v12 = v18.st_gid;
v5 = v12 == getegid();
}
return v5;
case 15:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode >> 10) & 1;
return v5;
case 16:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode >> 9) & 1;
return v5;
case 17:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = v18.st_uid == ksheuid;
return v5;
case 18:
return (unsigned int)test_eaccess(a3, 4) == 0;
case 19:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = v18.st_size > 0;
return v5;
case 20:
if ( a3 )
{
if ( !(unsigned int)bi_getn(a3, fd) )
{
*(_DWORD *)a1 |= 1u;
fd[0] = 0;
return (__mode_t)fd[0];
}
v11 = fd[0];
}
else
{
v11 = 0;
}
fd[0] = isatty(v11);
return (__mode_t)fd[0];
case 21:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode >> 11) & 1;
return v5;
case 22:
return (unsigned int)test_eaccess(a3, 2) == 0;
case 23:
return (unsigned int)test_eaccess(a3, 1) == 0;
case 24:
if ( (*(_BYTE *)a1 & 2) != 0 )
v5 = gmatch(a3, a4, 0LL);
else
v5 = strcmp(a3, a4) == 0;
return v5;
case 25:
if ( (*(_BYTE *)a1 & 2) != 0 )
v5 = gmatch(a3, a4, 0LL) == 0;
else
v5 = strcmp(a3, a4) != 0;
return v5;
case 26:
return (unsigned int)strcmp(a3, a4) >> 31;
case 27:
return strcmp(a3, a4) > 0;
case 28:
case 29:
case 30:
case 31:
case 32:
case 33:
if ( (unsigned int)evaluate(a3, &v15, 1LL, 0LL) && (unsigned int)evaluate(a4, &v16, 1LL, 0LL) )
{
switch ( a2 )
{
case 28:
v5 = v15 == v16;
break;
case 29:
v5 = v15 != v16;
break;
case 30:
v5 = v15 > v16;
break;
case 31:
v5 = v15 >= v16;
break;
case 32:
v5 = v15 < v16;
break;
case 33:
v5 = v15 <= v16;
break;
default:
goto LABEL_65;
}
}
else
{
*(_DWORD *)a1 |= 1u;
v5 = 1;
}
return v5;
case 34:
v5 = stat(a3, &v18);
if ( v5 )
return 0;
if ( !stat(a4, &v17) )
{
v5 = 0;
if ( v18.st_dev == v17.st_dev )
v5 = v18.st_ino == v17.st_ino;
}
return v5;
case 35:
LABEL_65:
v5 = 0;
if ( !stat(a3, &v18) )
{
v13 = stat(a4, &v17);
if ( v13 || (v5 = 1, v18.st_mtim.tv_sec <= v17.st_mtim.tv_sec) )
v5 = v13 >> 31;
}
return v5;
case 36:
v5 = 0;
if ( !stat(a4, &v17) )
{
v14 = stat(a3, &v18);
if ( v14 || (v5 = 1, v18.st_mtim.tv_sec >= v17.st_mtim.tv_sec) )
v5 = v14 >> 31;
}
return v5;
default:
(*(void (__fastcall **)(__int64, _QWORD, const char *))(a1 + 48))(a1, 0LL, "internal error: unknown op");
return 1;
}
}
return v5;
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1, int a2, char *a3, const char *a4, __mode_t a5)
{
__mode_t v5; // er14
int v9; // eax
int v10; // eax
int v11; // edi
__gid_t v12; // ebx
unsigned int v13; // eax
unsigned int v14; // eax
__int64 v15; // [rsp+0h] [rbp-168h] BYREF
__int64 v16; // [rsp+8h] [rbp-160h] BYREF
struct stat v17; // [rsp+10h] [rbp-158h] BYREF
struct stat v18; // [rsp+A0h] [rbp-C8h] BYREF
int fd[11]; // [rsp+13Ch] [rbp-2Ch] BYREF

v5 = a5;
if ( a5 )
{
switch ( a2 )
{
case 1:
return *a3 != 0;
case 2:
return *a3 == 0;
case 3:
if ( *a3 == 33 )
{
v10 = option(a3 + 1);
if ( v10 >= 0 )
{
fd[0] = *((_BYTE *)&shell_flags + v10) == 0;
return (__mode_t)fd[0];
}
}
else
{
v9 = option(a3);
if ( v9 >= 0 )
{
fd[0] = *((char *)&shell_flags + v9);
return (__mode_t)fd[0];
}
}
fd[0] = 0;
return (__mode_t)fd[0];
case 4:
case 5:
return stat(a3, &v18) == 0;
case 6:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode & 0xF000) == 0x8000;
return v5;
case 7:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode & 0xF000) == 24576;
return v5;
case 8:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode & 0xF000) == 0x2000;
return v5;
case 9:
v5 = 0;
if ( !lstat(a3, &v18) )
v5 = (v18.st_mode & 0xF000) == 40960;
return v5;
case 10:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode & 0xF000) == 4096;
return v5;
case 11:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode & 0xF000) == 49152;
return v5;
case 12:
return 0;
case 13:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode & 0xF000) == 0x4000;
return v5;
case 14:
v5 = 0;
if ( !stat(a3, &v18) )
{
v12 = v18.st_gid;
v5 = v12 == getegid();
}
return v5;
case 15:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode >> 10) & 1;
return v5;
case 16:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode >> 9) & 1;
return v5;
case 17:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = v18.st_uid == ksheuid;
return v5;
case 18:
return (unsigned int)func2(a3, 4) == 0;
case 19:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = v18.st_size > 0;
return v5;
case 20:
if ( a3 )
{
if ( !(unsigned int)bi_getn(a3, fd) )
{
*(_DWORD *)a1 |= 1u;
fd[0] = 0;
return (__mode_t)fd[0];
}
v11 = fd[0];
}
else
{
v11 = 0;
}
fd[0] = isatty(v11);
return (__mode_t)fd[0];
case 21:
v5 = 0;
if ( !stat(a3, &v18) )
v5 = (v18.st_mode >> 11) & 1;
return v5;
case 22:
return (unsigned int)func2(a3, 2) == 0;
case 23:
return (unsigned int)func2(a3, 1) == 0;
case 24:
if ( (*(_BYTE *)a1 & 2) != 0 )
v5 = gmatch(a3, a4, 0LL);
else
v5 = strcmp(a3, a4) == 0;
return v5;
case 25:
if ( (*(_BYTE *)a1 & 2) != 0 )
v5 = gmatch(a3, a4, 0LL) == 0;
else
v5 = strcmp(a3, a4) != 0;
return v5;
case 26:
return (unsigned int)strcmp(a3, a4) >> 31;
case 27:
return strcmp(a3, a4) > 0;
case 28:
case 29:
case 30:
case 31:
case 32:
case 33:
if ( (unsigned int)evaluate(a3, &v15, 1LL, 0LL) && (unsigned int)evaluate(a4, &v16, 1LL, 0LL) )
{
switch ( a2 )
{
case 28:
v5 = v15 == v16;
break;
case 29:
v5 = v15 != v16;
break;
case 30:
v5 = v15 > v16;
break;
case 31:
v5 = v15 >= v16;
break;
case 32:
v5 = v15 < v16;
break;
case 33:
v5 = v15 <= v16;
break;
default:
goto LABEL_65;
}
}
else
{
*(_DWORD *)a1 |= 1u;
v5 = 1;
}
return v5;
case 34:
v5 = stat(a3, &v18);
if ( v5 )
return 0;
if ( !stat(a4, &v17) )
{
v5 = 0;
if ( v18.st_dev == v17.st_dev )
v5 = v18.st_ino == v17.st_ino;
}
return v5;
case 35:
LABEL_65:
v5 = 0;
if ( !stat(a3, &v18) )
{
v13 = stat(a4, &v17);
if ( v13 || (v5 = 1, v18.st_mtim.tv_sec <= v17.st_mtim.tv_sec) )
v5 = v13 >> 31;
}
return v5;
case 36:
v5 = 0;
if ( !stat(a4, &v17) )
{
v14 = stat(a3, &v18);
if ( v14 || (v5 = 1, v18.st_mtim.tv_sec >= v17.st_mtim.tv_sec) )
v5 = v14 >> 31;
}
return v5;
default:
(*(void (__fastcall **)(__int64, _QWORD, const char *))(a1 + 48))(a1, 0LL, "internal error: unknown op");
return 1;
}
}
return v5;
}

original_code:
int
test_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2,
    int do_eval)
{
 int res;
 int not;
 struct stat b1, b2;
 if (!do_eval)
  return 0;
 switch ((int) op) {
 case TO_STNZE:
  return *opnd1 != '\0';
 case TO_STZER:
  return *opnd1 == '\0';
 case TO_OPTION:
  if ((not = *opnd1 == '!'))
   opnd1++;
  if ((res = option(opnd1)) < 0)
   res = 0;
  else {
   res = (shell_flags[(int) (res)]);
   if (not)
    res = !res;
  }
  return res;
 case TO_FILRD:
  return test_eaccess(opnd1, 4) == 0;
 case TO_FILWR:
  return test_eaccess(opnd1, 2) == 0;
 case TO_FILEX:
  return test_eaccess(opnd1, 1) == 0;
 case TO_FILAXST:
  return stat(opnd1, &b1) == 0;
 case TO_FILEXST:
  return stat(opnd1, &b1) == 0;
 case TO_FILREG:
  return stat(opnd1, &b1) == 0 && ((((b1.st_mode)) & 0170000) == (0100000));
 case TO_FILID:
  return stat(opnd1, &b1) == 0 && ((((b1.st_mode)) & 0170000) == (0040000));
 case TO_FILCDEV:
  return stat(opnd1, &b1) == 0 && ((((b1.st_mode)) & 0170000) == (0020000));
 case TO_FILBDEV:
  return stat(opnd1, &b1) == 0 && ((((b1.st_mode)) & 0170000) == (0060000));
 case TO_FILFIFO:
  return stat(opnd1, &b1) == 0 && ((((b1.st_mode)) & 0170000) == (0010000));
 case TO_FILSYM:
  return lstat(opnd1, &b1) == 0 && ((((b1.st_mode)) & 0170000) == (0120000));
 case TO_FILSOCK:
  return stat(opnd1, &b1) == 0 && ((((b1.st_mode)) & 0170000) == (0140000));
 case TO_FILCDF:
  return 0;
 case TO_FILSETU:
  return stat(opnd1, &b1) == 0 &&
      (b1.st_mode & 04000) == 04000;
 case TO_FILSETG:
  return stat(opnd1, &b1) == 0 &&
      (b1.st_mode & 02000) == 02000;
 case TO_FILSTCK:
  return stat(opnd1, &b1) == 0 &&
      (b1.st_mode & 01000) == 01000;
 case TO_FILGZ:
  return stat(opnd1, &b1) == 0 && b1.st_size > 0L;
 case TO_FILTT:
  if (opnd1 && !bi_getn(opnd1, &res)) {
   te->flags |= (1<<(0));
   res = 0;
  } else {
   res = isatty(opnd1 ? res : 0);
  }
  return res;
 case TO_FILUID:
  return stat(opnd1, &b1) == 0 && b1.st_uid == ksheuid;
 case TO_FILGID:
  return stat(opnd1, &b1) == 0 && b1.st_gid == getegid();
 case TO_STEQL:
  if (te->flags & (1<<(1)))
   return gmatch(opnd1, opnd2, 0);
  return strcmp(opnd1, opnd2) == 0;
 case TO_STNEQ:
  if (te->flags & (1<<(1)))
   return !gmatch(opnd1, opnd2, 0);
  return strcmp(opnd1, opnd2) != 0;
 case TO_STLT:
  return strcmp(opnd1, opnd2) < 0;
 case TO_STGT:
  return strcmp(opnd1, opnd2) > 0;
 case TO_INTEQ:
 case TO_INTNE:
 case TO_INTGE:
 case TO_INTGT:
 case TO_INTLE:
 case TO_INTLT:
  {
   int64_t v1, v2;
   if (!evaluate(opnd1, &v1, 0x1, 0) ||
       !evaluate(opnd2, &v2, 0x1, 0)) {
    te->flags |= (1<<(0));
    return 1;
   }
   switch ((int) op) {
   case TO_INTEQ:
    return v1 == v2;
   case TO_INTNE:
    return v1 != v2;
   case TO_INTGE:
    return v1 >= v2;
   case TO_INTGT:
    return v1 > v2;
   case TO_INTLE:
    return v1 <= v2;
   case TO_INTLT:
    return v1 < v2;
   }
  }
 case TO_FILNT:
  {
   int s2;
   return stat(opnd1, &b1) == 0 &&
       (((s2 = stat(opnd2, &b2)) == 0 &&
       b1.st_mtim.tv_sec > b2.st_mtim.tv_sec) || s2 < 0);
  }
 case TO_FILOT:
  {
   int s1;
   return stat(opnd2, &b2) == 0 &&
       (((s1 = stat(opnd1, &b1)) == 0 &&
       b1.st_mtim.tv_sec < b2.st_mtim.tv_sec) || s1 < 0);
  }
 case TO_FILEQ:
  return stat (opnd1, &b1) == 0 && stat (opnd2, &b2) == 0 &&
      b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino;
 }
 (*te->error)(te, 0, "internal error: unknown op");
 return 1;
}

canonical_original_code:
int test_eval(struct test_env *te, enum Test_op op, char *opnd1, char *opnd2, int do_eval)
{
 int res;
 int not;
 struct stat b1; struct stat b2;
 if (!do_eval)
  return 0;
 switch ((int) op) {
 case TO_STNZE:
  return *opnd1 != '\0';
 case TO_STZER:
  return *opnd1 == '\0';
 case TO_OPTION:
  if ((not = *opnd1 == '!'))
   opnd1++;
  if ((res = option(opnd1)) < 0)
   res = 0;
  else {
   res = (shell_flags[(int) (res)]);
   if (not)
    res = !res;
  }
  return res;
 case TO_FILRD:
  return test_eaccess(opnd1, 4) == 0;
 case TO_FILWR:
  return test_eaccess(opnd1, 2) == 0;
 case TO_FILEX:
  return test_eaccess(opnd1, 1) == 0;
 case TO_FILAXST:
  return stat(opnd1, &b1) == 0;
 case TO_FILEXST:
  return stat(opnd1, &b1) == 0;
 case TO_FILREG:
  return stat(opnd1, &b1) == 0 && ((((b1.st_mode)) & 0170000) == (0100000));
 case TO_FILID:
  return stat(opnd1, &b1) == 0 && ((((b1.st_mode)) & 0170000) == (0040000));
 case TO_FILCDEV:
  return stat(opnd1, &b1) == 0 && ((((b1.st_mode)) & 0170000) == (0020000));
 case TO_FILBDEV:
  return stat(opnd1, &b1) == 0 && ((((b1.st_mode)) & 0170000) == (0060000));
 case TO_FILFIFO:
  return stat(opnd1, &b1) == 0 && ((((b1.st_mode)) & 0170000) == (0010000));
 case TO_FILSYM:
  return lstat(opnd1, &b1) == 0 && ((((b1.st_mode)) & 0170000) == (0120000));
 case TO_FILSOCK:
  return stat(opnd1, &b1) == 0 && ((((b1.st_mode)) & 0170000) == (0140000));
 case TO_FILCDF:
  return 0;
 case TO_FILSETU:
  return stat(opnd1, &b1) == 0 &&
      (b1.st_mode & 04000) == 04000;
 case TO_FILSETG:
  return stat(opnd1, &b1) == 0 &&
      (b1.st_mode & 02000) == 02000;
 case TO_FILSTCK:
  return stat(opnd1, &b1) == 0 &&
      (b1.st_mode & 01000) == 01000;
 case TO_FILGZ:
  return stat(opnd1, &b1) == 0 && b1.st_size > 0L;
 case TO_FILTT:
  if (opnd1 && !bi_getn(opnd1, &res)) {
   te->flags |= (1<<(0));
   res = 0;
  } else {
   res = isatty(opnd1 ? res : 0);
  }
  return res;
 case TO_FILUID:
  return stat(opnd1, &b1) == 0 && b1.st_uid == ksheuid;
 case TO_FILGID:
  return stat(opnd1, &b1) == 0 && b1.st_gid == getegid();
 case TO_STEQL:
  if (te->flags & (1<<(1)))
   return gmatch(opnd1, opnd2, 0);
  return strcmp(opnd1, opnd2) == 0;
 case TO_STNEQ:
  if (te->flags & (1<<(1)))
   return !gmatch(opnd1, opnd2, 0);
  return strcmp(opnd1, opnd2) != 0;
 case TO_STLT:
  return strcmp(opnd1, opnd2) < 0;
 case TO_STGT:
  return strcmp(opnd1, opnd2) > 0;
 case TO_INTEQ:
 case TO_INTNE:
 case TO_INTGE:
 case TO_INTGT:
 case TO_INTLE:
 case TO_INTLT:
  {
   long v1; long v2;
   if (!evaluate(opnd1, &v1, 0x1, 0) ||
       !evaluate(opnd2, &v2, 0x1, 0)) {
    te->flags |= (1<<(0));
    return 1;
   }
   switch ((int) op) {
   case TO_INTEQ:
    return v1 == v2;
   case TO_INTNE:
    return v1 != v2;
   case TO_INTGE:
    return v1 >= v2;
   case TO_INTGT:
    return v1 > v2;
   case TO_INTLE:
    return v1 <= v2;
   case TO_INTLT:
    return v1 < v2;
   }
  }
 case TO_FILNT:
  {
   int s2;
   return stat(opnd1, &b1) == 0 &&
       (((s2 = stat(opnd2, &b2)) == 0 &&
       b1.st_mtim.tv_sec > b2.st_mtim.tv_sec) || s2 < 0);
  }
 case TO_FILOT:
  {
   int s1;
   return stat(opnd2, &b2) == 0 &&
       (((s1 = stat(opnd1, &b1)) == 0 &&
       b1.st_mtim.tv_sec < b2.st_mtim.tv_sec) || s1 < 0);
  }
 case TO_FILEQ:
  return stat (opnd1, &b1) == 0 && stat (opnd2, &b2) == 0 &&
      b1.st_dev == b2.st_dev && b1.st_ino == b2.st_ino;
 }
 (*te->error)(te, 0, "internal error: unknown op");
 return 1;
}

variable_types: not int

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


decompiled_code:
__int64 __fastcall ptest_eval(__int64 a1, int a2, char *a3, const char *a4, __mode_t a5)
{
return test_eval(a1, a2, a3, a4, a5);
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1, int a2, char *a3, const char *a4, __mode_t a5)
{
return func9(a1, a2, a3, a4, a5);
}

original_code:
static int
ptest_eval(Test_env *te, Test_op op, const char *opnd1, const char *opnd2,
    int do_eval)
{
 return test_eval(te, op, opnd1, opnd2, do_eval);
}

canonical_original_code:
static int ptest_eval(struct test_env *te, enum Test_op op, char *opnd1, char *opnd2, int do_eval)
{
 return test_eval(te, op, opnd1, opnd2, do_eval);
}


decompiled_code:
__int64 __fastcall test_parse(__int64 a1)
{
int v1; // ebp
__int64 result; // rax

v1 = test_oexpr(a1, 1u);
result = 2LL;
if ( (*(_BYTE *)a1 & 1) == 0 )
{
if ( !(*(unsigned int (__fastcall **)(__int64, __int64))(a1 + 24))(a1, 7LL) )
(*(void (__fastcall **)(__int64, _QWORD, const char *))(a1 + 48))(a1, 0LL, "unexpected operator/operand");
if ( (*(_BYTE *)a1 & 1) != 0 )
result = 2LL;
else
result = v1 == 0;
}
return result;
}

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

v1 = func8(a1, 1u);
result = 2LL;
if ( (*(_BYTE *)a1 & 1) == 0 )
{
if ( !(*(unsigned int (__fastcall **)(__int64, __int64))(a1 + 24))(a1, 7LL) )
(*(void (__fastcall **)(__int64, _QWORD, const char *))(a1 + 48))(a1, 0LL, "unexpected operator/operand");
if ( (*(_BYTE *)a1 & 1) != 0 )
result = 2LL;
else
result = v1 == 0;
}
return result;
}

original_code:
int
test_parse(Test_env *te)
{
 int res;
 res = test_oexpr(te, 1);
 if (!(te->flags & (1<<(0))) && !(*te->isa)(te, TM_END))
  (*te->error)(te, 0, "unexpected operator/operand");
 return (te->flags & (1<<(0))) ? 2 : !res;
}

canonical_original_code:
int test_parse(struct test_env *te)
{
 int res;
 res = test_oexpr(te, 1);
 if (!(te->flags & (1<<(0))) && !(*te->isa)(te, TM_END))
  (*te->error)(te, 0, "unexpected operator/operand");
 return (te->flags & (1<<(0))) ? 2 : !res;
}


usage

decompiled_code:
void __noreturn usage()
{
fprintf(stderr, "usage: %s [-abcflnostw] [-F foldwidth] [file ...]\n", (const char *)program_invocation_short_name);
exit(1);
}

canonical_decompiled_code:
void __noreturn func8()
{
fprintf(stderr, "usage: %s [-abcflnostw] [-F foldwidth] [file ...]\n", (const char *)program_invocation_short_name);
exit(1);
}

original_code:
void
usage(void)
{
 extern char *__progname;
 fprintf(stderr, "usage: %s [-abcflnostw] [-F foldwidth] [file ...]\n",
     __progname);
 exit(1);
}

canonical_original_code:
void usage()
{
 extern char *__progname;
 fprintf(stderr, "usage: %s [-abcflnostw] [-F foldwidth] [file ...]\n",
     __progname);
 exit(1);
}


foldit

decompiled_code:
__int64 __fastcall foldit(char *a1, unsigned int a2, int a3)
{
_BOOL4 v3; // ecx
signed int v4; // ebp
char v5; // al
char *v6; // rdx

v3 = a2 != 0;
v4 = a3 - 1;
while ( 1 )
{
v5 = *a1;
if ( !*a1 )
return a2;
v6 = a1;
while ( 1 )
{
if ( v5 == 9 )
{
a2 = (a2 + 8) & 0xFFFFFFF8;
goto LABEL_7;
}
if ( v5 <= 9 )
{
if ( v5 == 8 )
{
a2 = (a2 == 0) + a2 - 1;
goto LABEL_7;
}
goto LABEL_14;
}
if ( v5 != 10 )
{
if ( v5 == 13 )
{
a2 = 0;
goto LABEL_7;
}
LABEL_14:
++a2;
goto LABEL_7;
}
a2 = 0;
LABEL_7:
if ( v4 <= (int)a2 )
break;
v5 = *++v6;
if ( !*v6 )
return a2;
}
if ( !v3 )
return a2;
puts("\\");
v3 = 0;
a2 = 0;
}
}

canonical_decompiled_code:
__int64 __fastcall func9(char *a1, unsigned int a2, int a3)
{
_BOOL4 v3; // ecx
signed int v4; // ebp
char v5; // al
char *v6; // rdx

v3 = a2 != 0;
v4 = a3 - 1;
while ( 1 )
{
v5 = *a1;
if ( !*a1 )
return a2;
v6 = a1;
while ( 1 )
{
if ( v5 == 9 )
{
a2 = (a2 + 8) & 0xFFFFFFF8;
goto LABEL_7;
}
if ( v5 <= 9 )
{
if ( v5 == 8 )
{
a2 = (a2 == 0) + a2 - 1;
goto LABEL_7;
}
goto LABEL_14;
}
if ( v5 != 10 )
{
if ( v5 == 13 )
{
a2 = 0;
goto LABEL_7;
}
LABEL_14:
++a2;
goto LABEL_7;
}
a2 = 0;
LABEL_7:
if ( v4 <= (int)a2 )
break;
v5 = *++v6;
if ( !*v6 )
return a2;
}
if ( !v3 )
return a2;
puts("\\");
v3 = 0;
a2 = 0;
}
}

original_code:
int
foldit(char *chunk, int col, int max)
{
 char *cp;
 int first = (col != 0);
again:
 cp = chunk;
 while (*cp) {
  switch(*cp) {
  case '\n':
  case '\r':
   col = 0;
   break;
  case '\t':
   col = (col + 8) & ~07;
   break;
  case '\b':
   col = col ? col - 1 : 0;
   break;
  default:
   col++;
  }
  if (col > (max - 2)) {
   if (!first)
    return (col);
   printf("\\\n");
   col = 0;
   first = 0;
   goto again;
  }
  cp++;
 }
 return (col);
}

variable_types:
chunk
char *

variable_types: col int

variable_types: max int

variable_types:
cp
char *

variable_types: first int


aresize

decompiled_code:
__int64 __fastcall aresize(__int64 a1, unsigned __int64 a2, _QWORD **a3)
{
_QWORD *v3; // rbp
__int64 v5; // r12
_QWORD *v6; // rax

if ( !a1 )
return alloc(a2, a3);
if ( a2 > 0xFFFFFFFFFFFFFFEFLL )
{
internal_errorf("unable to allocate memory");
goto LABEL_11;
}
v5 = *(_QWORD *)(a1 - 16);
v3 = *(_QWORD **)(a1 - 8);
v6 = realloc((void *)(a1 - 16), a2 + 16);
if ( !v6 )
{
LABEL_11:
v6 = (_QWORD *)internal_errorf("unable to allocate memory");
goto LABEL_12;
}
if ( !v5 )
{
LABEL_12:
*a3 = v6;
goto LABEL_6;
}
*(_QWORD *)(v5 + 8) = v6;
LABEL_6:
if ( v3 )
*v3 = v6;
return (__int64)(v6 + 2);
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, unsigned __int64 a2, _QWORD **a3)
{
_QWORD *v3; // rbp
__int64 v5; // r12
_QWORD *v6; // rax

if ( !a1 )
return func1(a2, a3);
if ( a2 > 0xFFFFFFFFFFFFFFEFLL )
{
internal_errorf("unable to allocate memory");
goto LABEL_11;
}
v5 = *(_QWORD *)(a1 - 16);
v3 = *(_QWORD **)(a1 - 8);
v6 = realloc((void *)(a1 - 16), a2 + 16);
if ( !v6 )
{
LABEL_11:
v6 = (_QWORD *)internal_errorf("unable to allocate memory");
goto LABEL_12;
}
if ( !v5 )
{
LABEL_12:
*a3 = v6;
goto LABEL_6;
}
*(_QWORD *)(v5 + 8) = v6;
LABEL_6:
if ( v3 )
*v3 = v6;
return (__int64)(v6 + 2);
}

original_code:
void *
aresize(void *ptr, size_t size, Area *ap)
{
 struct link *l, *l2, *lprev, *lnext;
 if (ptr == ((void *)0))
  return alloc(size, ap);
 if (size > (18446744073709551615UL) - sizeof(struct link))
  internal_errorf("unable to allocate memory");
 l = ( (struct link *)(((char *)(ptr)) - sizeof(struct link)) );
 lprev = l->prev;
 lnext = l->next;
 l2 = realloc(l, sizeof(struct link) + size);
 if (l2 == ((void *)0))
  internal_errorf("unable to allocate memory");
 if (lprev)
  lprev->next = l2;
 else
  ap->freelist = l2;
 if (lnext)
  lnext->prev = l2;
 return ( (void *)(((char *)(l2)) + sizeof(struct link)) );
}

canonical_original_code:
void *aresize(void *ptr, unsigned long size, struct Area *ap)
{
 struct link *l; struct link *l2; struct link *lprev; struct link *lnext;
 if (ptr == ((void *)0))
  return alloc(size, ap);
 if (size > (18446744073709551615UL) - sizeof(struct link))
  internal_errorf("unable to allocate memory");
 l = ( (struct link *)(((char *)(ptr)) - sizeof(struct link)) );
 lprev = l->prev;
 lnext = l->next;
 l2 = realloc(l, sizeof(struct link) + size);
 if (l2 == ((void *)0))
  internal_errorf("unable to allocate memory");
 if (lprev)
  lprev->next = l2;
 else
  ap->freelist = l2;
 if (lnext)
  lnext->prev = l2;
 return ( (void *)(((char *)(l2)) + sizeof(struct link)) );
}

variable_types:
ptr
void *

variable_types:
size
unsigned long

variable_types: struct Area { struct link { struct link *prev; struct link *next; } *freelist; } *

return_type: void *


areallocarray

decompiled_code:
__int64 __fastcall areallocarray(__int64 a1, unsigned __int64 a2, unsigned __int64 a3, _QWORD **a4)
{
if ( a3 <= 0xFFFFFFFF && a2 <= 0xFFFFFFFF || !a2 || is_mul_ok(a2, a3) )
return aresize(a1, a3 * a2, a4);
internal_errorf("unable to allocate memory");
return afree();
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, unsigned __int64 a2, unsigned __int64 a3, _QWORD **a4)
{
if ( a3 <= 0xFFFFFFFF && a2 <= 0xFFFFFFFF || !a2 || is_mul_ok(a2, a3) )
return func2(a1, a3 * a2, a4);
internal_errorf("unable to allocate memory");
return func4();
}

original_code:
void *
areallocarray(void *ptr, size_t nmemb, size_t size, Area *ap)
{
 if ((nmemb >= (1UL << (sizeof(size_t) * 4)) || size >= (1UL << (sizeof(size_t) * 4))) &&
     nmemb > 0 && (18446744073709551615UL) / nmemb < size) {
  internal_errorf("unable to allocate memory");
 }
 return aresize(ptr, nmemb * size, ap);
}

canonical_original_code:
void *areallocarray(void *ptr, unsigned long nmemb, unsigned long size, struct Area *ap)
{
 if ((nmemb >= (1UL << (sizeof(unsigned long) * 4)) || size >= (1UL << (sizeof(unsigned long) * 4))) &&
     nmemb > 0 && (18446744073709551615UL) / nmemb < size) {
  internal_errorf("unable to allocate memory");
 }
 return aresize(ptr, nmemb * size, ap);
}

variable_types:
nmemb
unsigned long

user_defined_types: struct link { struct link *prev; struct link *next; }


afree

original_code:
void
afree(void *ptr, Area *ap)
{
 struct link *l;
 if (!ptr)
  return;
 l = ( (struct link *)(((char *)(ptr)) - sizeof(struct link)) );
 if (l->prev)
  l->prev->next = l->next;
 else
  ap->freelist = l->next;
 if (l->next)
  l->next->prev = l->prev;
 free(l);
}

canonical_original_code:
void afree(void *ptr, struct Area *ap)
{
 struct link *l;
 if (!ptr)
  return;
 l = ( (struct link *)(((char *)(ptr)) - sizeof(struct link)) );
 if (l->prev)
  l->prev->next = l->next;
 else
  ap->freelist = l->next;
 if (l->next)
  l->next->prev = l->prev;
 free(l);
}

variable_types: struct link { struct link *prev; struct link *next; } *


munset

decompiled_code:
__int64 __fastcall munset(_QWORD *a1)
{
_QWORD *v1; // rbx
_QWORD *v2; // rbp
__int64 result; // rax

v1 = a1;
if ( a1 )
{
while ( 1 )
{
v2 = (_QWORD *)*v1;
if ( !*v1 )
break;
afree(v1, &aperm);
v1 = v2;
}
afree(v1[1], &aperm);
result = afree(v1, &aperm);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(_QWORD *a1)
{
_QWORD *v1; // rbx
_QWORD *v2; // rbp
__int64 result; // rax

v1 = a1;
if ( a1 )
{
while ( 1 )
{
v2 = (_QWORD *)*v1;
if ( !*v1 )
break;
afree(v1, &aperm);
v1 = v2;
}
afree(v1[1], &aperm);
result = afree(v1, &aperm);
}
return result;
}

original_code:
static void
munset(mbox_t *mlist)
{
 mbox_t *mbp;
 while (mlist != ((void *)0)) {
  mbp = mlist;
  mlist = mbp->mb_next;
  if (!mlist)
   afree(mbp->mb_path, &aperm);
  afree(mbp, &aperm);
 }
}

canonical_original_code:
static void munset(struct mbox *mlist)
{
 struct mbox *mbp;
 while (mlist != ((void *)0)) {
  mbp = mlist;
  mlist = mbp->mb_next;
  if (!mlist)
   afree(mbp->mb_path, &aperm);
  afree(mbp, &aperm);
 }
}

variable_types: struct mbox { struct mbox *mb_next; char *mb_path; char *mb_msg; long mb_mtime; } *


mcset

decompiled_code:
void __fastcall mcset(__int64 a1)
{
mailcheck_interval = a1;
}

canonical_decompiled_code:
void __fastcall func3(__int64 a1)
{
mailcheck_interval = a1;
}

original_code:
void
mcset(int64_t interval)
{
 mailcheck_interval = interval;
}

canonical_original_code:
void mcset(long interval)
{
 mailcheck_interval = interval;
}

variable_types: interval long


mbset

decompiled_code:
__time_t __fastcall mbset(char *file)
{
__time_t result; // rax
int v2; // edx
struct stat v3; // [rsp+0h] [rbp-98h] BYREF

afree(qword_430, &aperm);
afree(qword_428, &aperm);
qword_428 = str_save(file, &aperm);
qword_430 = 0LL;
result = 0LL;
if ( file )
{
v2 = stat(file, &v3);
result = 0LL;
if ( !v2 )
{
result = 0LL;
if ( (v3.st_mode & 0xF000) == 0x8000 )
result = v3.st_mtim.tv_sec;
}
}
qword_438 = result;
return result;
}

canonical_decompiled_code:
__time_t __fastcall func4(char *file)
{
__time_t result; // rax
int v2; // edx
struct stat v3; // [rsp+0h] [rbp-98h] BYREF

afree(qword_430, &aperm);
afree(qword_428, &aperm);
qword_428 = str_save(file, &aperm);
qword_430 = 0LL;
result = 0LL;
if ( file )
{
v2 = stat(file, &v3);
result = 0LL;
if ( !v2 )
{
result = 0LL;
if ( (v3.st_mode & 0xF000) == 0x8000 )
result = v3.st_mtim.tv_sec;
}
}
qword_438 = result;
return result;
}

original_code:
void
mbset(char *p)
{
 struct stat stbuf;
 afree(mbox.mb_msg, &aperm);
 afree(mbox.mb_path, &aperm);
 mbox.mb_path = str_save(p, &aperm);
 mbox.mb_msg = ((void *)0);
 if (p && stat(p, &stbuf) == 0 && ((((stbuf.st_mode)) & 0170000) == (0100000)))
  mbox.mb_mtime = stbuf.st_mtim.tv_sec;
 else
  mbox.mb_mtime = 0;
}

variable_types:
p
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]; }


mpset

decompiled_code:
char *__fastcall mpset(__int64 a1)
{
char *result; // rax
char *v2; // r13
size_t v3; // rax
char *i; // rbx
char *v5; // rax
char *v6; // rbp

munset((_QWORD *)mplist);
mplist = 0LL;
result = (char *)str_save(a1, &aperm);
if ( result )
{
v2 = result;
while ( 2 )
{
v5 = strchr(v2, 58);
v6 = v5;
if ( v5 )
{
*v5 = 0;
v6 = v5 + 1;
}
for ( i = v2; ; memmove(i - 1, i, v3 + 1) )
{
result = strchr(i, 37);
i = result;
if ( result <= v2 || !result )
break;
if ( *(result - 1) != 92 )
goto LABEL_20;
v3 = strlen(result);
}
if ( !result )
{
if ( shell_flags[23] )
goto LABEL_10;
result = strchr(v2, 63);
i = result;
}
if ( i )
{
LABEL_20:
*i = 0;
if ( i[1] )
++i;
else
i = 0LL;
}
LABEL_10:
if ( *v2 )
{
result = (char *)mballoc(v2, (__int64)i);
*(_QWORD *)result = mplist;
mplist = (__int64)result;
}
if ( v6 )
{
v2 = v6;
continue;
}
break;
}
}
return result;
}

canonical_decompiled_code:
char *__fastcall func5(__int64 a1)
{
char *result; // rax
char *v2; // r13
size_t v3; // rax
char *i; // rbx
char *v5; // rax
char *v6; // rbp

func1((_QWORD *)mplist);
mplist = 0LL;
result = (char *)str_save(a1, &aperm);
if ( result )
{
v2 = result;
while ( 2 )
{
v5 = strchr(v2, 58);
v6 = v5;
if ( v5 )
{
*v5 = 0;
v6 = v5 + 1;
}
for ( i = v2; ; memmove(i - 1, i, v3 + 1) )
{
result = strchr(i, 37);
i = result;
if ( result <= v2 || !result )
break;
if ( *(result - 1) != 92 )
goto LABEL_20;
v3 = strlen(result);
}
if ( !result )
{
if ( shell_flags[23] )
goto LABEL_10;
result = strchr(v2, 63);
i = result;
}
if ( i )
{
LABEL_20:
*i = 0;
if ( i[1] )
++i;
else
i = 0LL;
}
LABEL_10:
if ( *v2 )
{
result = (char *)mballoc(v2, (__int64)i);
*(_QWORD *)result = mplist;
mplist = (__int64)result;
}
if ( v6 )
{
v2 = v6;
continue;
}
break;
}
}
return result;
}

original_code:
void
mpset(char *mptoparse)
{
 mbox_t *mbp;
 char *mpath, *mmsg, *mval;
 char *p;
 munset( mplist );
 mplist = ((void *)0);
 mval = str_save(mptoparse, &aperm);
 while (mval) {
  mpath = mval;
  if ((mval = strchr(mval, ':')) != ((void *)0)) {
   *mval = '\0';
   mval++;
  }
  for (p = mpath; (mmsg = strchr(p, '%')); ) {
   if (mmsg > mpath && mmsg[-1] == '\\') {
    memmove(mmsg - 1, mmsg, strlen(mmsg) + 1);
    p = mmsg;
    continue;
   }
   break;
  }
  if (!mmsg && !(shell_flags[(int) (FPOSIX)]))
   mmsg = strchr(mpath, '?');
  if (mmsg) {
   *mmsg = '\0';
   mmsg++;
   if (*mmsg == '\0')
    mmsg = ((void *)0);
  }
  if (*mpath == '\0')
   continue;
  mbp = mballoc(mpath, mmsg);
  mbp->mb_next = mplist;
  mplist = mbp;
 }
}

canonical_original_code:
void mpset(char *mptoparse)
{
 struct mbox *mbp;
 char *mpath; char *mmsg; char *mval;
 char *p;
 munset( mplist );
 mplist = ((void *)0);
 mval = str_save(mptoparse, &aperm);
 while (mval) {
  mpath = mval;
  if ((mval = strchr(mval, ':')) != ((void *)0)) {
   *mval = '\0';
   mval++;
  }
  for (p = mpath; (mmsg = strchr(p, '%')); ) {
   if (mmsg > mpath && mmsg[-1] == '\\') {
    memmove(mmsg - 1, mmsg, strlen(mmsg) + 1);
    p = mmsg;
    continue;
   }
   break;
  }
  if (!mmsg && !(shell_flags[(int) (FPOSIX)]))
   mmsg = strchr(mpath, '?');
  if (mmsg) {
   *mmsg = '\0';
   mmsg++;
   if (*mmsg == '\0')
    mmsg = ((void *)0);
  }
  if (*mpath == '\0')
   continue;
  mbp = mballoc(mpath, mmsg);
  mbp->mb_next = mplist;
  mplist = mbp;
 }
}

variable_types:
mptoparse
char *

variable_types:
mpath
char *

variable_types:
mmsg
char *

variable_types:
mval
char *

user_defined_types: struct mbox { struct mbox *mb_next; char *mb_path; char *mb_msg; long mb_mtime; }


original_code:
void
simplify_path(char *path)
{
 char *cur;
 char *t;
 int isrooted;
 char *very_start = path;
 char *start;
 if (!*path)
  return;
 if ((isrooted = (path[0] == '/')))
  very_start++;
 for (cur = t = start = very_start; ; ) {
  while (*t == '/')
   t++;
  if (*t == '\0') {
   if (cur == path)
    *cur++ = '.';
   *cur = '\0';
   break;
  }
  if (t[0] == '.') {
   if (!t[1] || t[1] == '/') {
    t += 1;
    continue;
   } else if (t[1] == '.' && (!t[2] || t[2] == '/')) {
    if (!isrooted && cur == start) {
     if (cur != very_start)
      *cur++ = '/';
     *cur++ = '.';
     *cur++ = '.';
     start = cur;
    } else if (cur != start)
     while (--cur > start && *cur != '/')
      ;
    t += 2;
    continue;
   }
  }
  if (cur != very_start)
   *cur++ = '/';
  while (*t && *t != '/')
   *cur++ = *t++;
 }
}

variable_types:
path
char *

variable_types:
cur
char *

variable_types:
t
char *

variable_types: isrooted int

variable_types:
start
char *


decompiled_code:
void *__fastcall set_current_wd(void *src)
{
const char *v1; // rbp
int v2; // ebx
void *result; // rax
const char *v4; // rax

v1 = (const char *)src;
if ( !src )
{
v4 = (const char *)ksh_get_wd(0LL, 0LL);
v1 = v4;
if ( v4 )
{
v2 = strlen(v4) + 1;
if ( current_wd_size >= v2 )
goto LABEL_8;
goto LABEL_7;
}
v1 = &null;
}
v2 = strlen(v1) + 1;
if ( v2 <= current_wd_size )
return memcpy(current_wd, v1, v2);
LABEL_7:
current_wd_size = v2;
current_wd = (void *)aresize(current_wd, v2, &aperm);
LABEL_8:
result = memcpy(current_wd, v1, v2);
if ( v1 != &null && src != v1 )
result = (void *)afree(v1, genv + 8LL);
return result;
}

canonical_decompiled_code:
void *__fastcall func3(void *src)
{
const char *v1; // rbp
int v2; // ebx
void *result; // rax
const char *v4; // rax

v1 = (const char *)src;
if ( !src )
{
v4 = (const char *)ksh_get_wd(0LL, 0LL);
v1 = v4;
if ( v4 )
{
v2 = strlen(v4) + 1;
if ( current_wd_size >= v2 )
goto LABEL_8;
goto LABEL_7;
}
v1 = &null;
}
v2 = strlen(v1) + 1;
if ( v2 <= current_wd_size )
return memcpy(current_wd, v1, v2);
LABEL_7:
current_wd_size = v2;
current_wd = (void *)aresize(current_wd, v2, &aperm);
LABEL_8:
result = memcpy(current_wd, v1, v2);
if ( v1 != &null && src != v1 )
result = (void *)afree(v1, genv + 8LL);
return result;
}

original_code:
void
set_current_wd(char *path)
{
 int len;
 char *p = path;
 if (!p && !(p = ksh_get_wd(((void *)0), 0)))
  p = null;
 len = strlen(p) + 1;
 if (len > current_wd_size)
  current_wd = aresize(current_wd, current_wd_size = len, &aperm);
 memcpy(current_wd, p, len);
 if (p != path && p != null)
  afree(p, &genv->area);
}

variable_types: len int


stravis

decompiled_code:
__int64 __fastcall stravis(_QWORD *a1, char *a2, __int16 a3)
{
size_t v4; // rax
_BYTE *v5; // rax
void *v6; // rbx
unsigned int v7; // ebp
int *v8; // r13
int v9; // er14
void *v10; // rax

v4 = strlen(a2);
v5 = (_BYTE *)reallocarray(0LL, 4LL, v4 + 1);
if ( !v5 )
return (unsigned int)-1;
v6 = v5;
v7 = (unsigned int)strvis(v5, a2, a3);
v8 = _errno_location();
v9 = *v8;
v10 = realloc(v6, (int)(v7 + 1));
*a1 = v10;
if ( !v10 )
{
*a1 = v6;
*v8 = v9;
}
return v7;
}

canonical_decompiled_code:
__int64 __fastcall func1(_QWORD *a1, char *a2, __int16 a3)
{
size_t v4; // rax
_BYTE *v5; // rax
void *v6; // rbx
unsigned int v7; // ebp
int *v8; // r13
int v9; // er14
void *v10; // rax

v4 = strlen(a2);
v5 = (_BYTE *)reallocarray(0LL, 4LL, v4 + 1);
if ( !v5 )
return (unsigned int)-1;
v6 = v5;
v7 = (unsigned int)strvis(v5, a2, a3);
v8 = _errno_location();
v9 = *v8;
v10 = realloc(v6, (int)(v7 + 1));
*a1 = v10;
if ( !v10 )
{
*a1 = v6;
*v8 = v9;
}
return v7;
}

original_code:
int
stravis(char **outp, const char *src, int flag)
{
 char *buf;
 int len, serrno;
 buf = reallocarray(((void *)0), 4, strlen(src) + 1);
 if (buf == ((void *)0))
  return -1;
 len = strvis(buf, src, flag);
 serrno = (*__errno_location ());
 *outp = realloc(buf, len + 1);
 if (*outp == ((void *)0)) {
  *outp = buf;
  (*__errno_location ()) = serrno;
 }
 return (len);
}

canonical_original_code:
int stravis(char **outp, char *src, int flag)
{
 char *buf;
 int len; int serrno;
 buf = reallocarray(((void *)0), 4, strlen(src) + 1);
 if (buf == ((void *)0))
  return -1;
 len = strvis(buf, src, flag);
 serrno = (*__errno_location ());
 *outp = realloc(buf, len + 1);
 if (*outp == ((void *)0)) {
  *outp = buf;
  (*__errno_location ()) = serrno;
 }
 return (len);
}

variable_types:
outp
char **

variable_types:
src
char *

variable_types: flag int

variable_types:
buf
char *

variable_types: serrno int


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

if ( tty_fd >= 0 )
{
result = close(tty_fd);
tty_fd = -1;
}
return result;
}

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

if ( tty_fd >= 0 )
{
result = close(tty_fd);
tty_fd = -1;
}
return result;
}

original_code:
void
tty_close(void)
{
 if (tty_fd >= 0) {
  close(tty_fd);
  tty_fd = -1;
 }
}

canonical_original_code:
void tty_close()
{
 if (tty_fd >= 0) {
  close(tty_fd);
  tty_fd = -1;
 }
}


decompiled_code:
int __fastcall tty_init(int a1)
{
int v1; // ebx
int v2; // ebp
int result; // eax
int *v4; // rax
char *v5; // rax
int *v6; // rax
char *v7; // rax

tty_close();
tty_devtty = 1;
v1 = open("/dev/tty", 2);
v2 = 1;
if ( v1 == -1 )
{
tty_devtty = 0;
v4 = _errno_location();
v5 = strerror(*v4);
warningf(0LL, "No controlling tty (open /dev/tty: %s)", v5);
v2 = isatty(0);
if ( v2 )
{
v1 = 0;
v2 = 0;
}
else
{
v1 = 2;
if ( !isatty(2) )
return warningf(0LL, "Can't find tty file descriptor");
}
}
result = fcntl(v1, 1030, 10LL);
tty_fd = result;
if ( result == -1 )
{
v6 = _errno_location();
v7 = strerror(*v6);
result = warningf(0LL, "%s: dup of tty fd failed: %s", "tty_init", v7);
}
else if ( a1 )
{
result = tcgetattr(result, &tty_state);
}
if ( v2 )
result = close(v1);
return result;
}

canonical_decompiled_code:
int __fastcall func1(int a1)
{
int v1; // ebx
int v2; // ebp
int result; // eax
int *v4; // rax
char *v5; // rax
int *v6; // rax
char *v7; // rax

func0();
tty_devtty = 1;
v1 = open("/dev/tty", 2);
v2 = 1;
if ( v1 == -1 )
{
tty_devtty = 0;
v4 = _errno_location();
v5 = strerror(*v4);
warningf(0LL, "No controlling tty (open /dev/tty: %s)", v5);
v2 = isatty(0);
if ( v2 )
{
v1 = 0;
v2 = 0;
}
else
{
v1 = 2;
if ( !isatty(2) )
return warningf(0LL, "Can't find tty file descriptor");
}
}
result = fcntl(v1, 1030, 10LL);
tty_fd = result;
if ( result == -1 )
{
v6 = _errno_location();
v7 = strerror(*v6);
result = warningf(0LL, "%s: dup of tty fd failed: %s", "tty_init", v7);
}
else if ( a1 )
{
result = tcgetattr(result, &tty_state);
}
if ( v2 )
result = close(v1);
return result;
}

original_code:
void
tty_init(int init_ttystate)
{
 int do_close = 1;
 int tfd;
 tty_close();
 tty_devtty = 1;
 tfd = open("/dev/tty", 02);
 if (tfd == -1) {
  tty_devtty = 0;
  warningf(0, "No controlling tty (open /dev/tty: %s)",
      strerror((*__errno_location ())));
  do_close = 0;
  if (isatty(0))
   tfd = 0;
  else if (isatty(2))
   tfd = 2;
  else {
   warningf(0, "Can't find tty file descriptor");
   return;
  }
 }
 if ((tty_fd = fcntl(tfd, 1030, 10)) == -1) {
  warningf(0, "%s: dup of tty fd failed: %s",
      __func__, strerror((*__errno_location ())));
 } else if (init_ttystate)
  tcgetattr(tty_fd, &tty_state);
 if (do_close)
  close(tfd);
}

variable_types: tfd int


decompiled_code:
void at_exit()
{
want_exit = 1;
}

canonical_decompiled_code:
void func7()
{
want_exit = 1;
}

original_code:
void at_exit(void) {
 want_exit = 1;
}

canonical_original_code:
void at_exit() {
 want_exit = 1;
}


output

decompiled_code:
int __fastcall output(unsigned int a1, const char *a2)
{
sem_wait(&guard_print);
printf("%2d %s\n", a1, a2);
return sem_post(&guard_print);
}

canonical_decompiled_code:
int __fastcall func8(unsigned int a1, const char *a2)
{
sem_wait(&guard_print);
printf("%2d %s\n", a1, a2);
return sem_post(&guard_print);
}

original_code:
void output(int i, char* text) {
 sem_wait(&(guard_print));
 printf("%2d %s\n", i, text);
 sem_post(&(guard_print));
}

canonical_original_code:
void output(int i, char *text) {
 sem_wait(&(guard_print));
 printf("%2d %s\n", i, text);
 sem_post(&(guard_print));
}

variable_types: i int

variable_types:
text
char *


idle

decompiled_code:
int idle()
{
return usleep(0);
}

canonical_decompiled_code:
int func9()
{
return usleep(0);
}

original_code:
void idle(int time) {
 usleep(time * (0));
}

variable_types: time int


eat

decompiled_code:
int __fastcall eat(signed int a1)
{
sem_t *v1; // r12
sem_t *v2; // rbx

sem_wait(&guard_deadlock);
v1 = (sem_t *)(32LL * a1 + 4211200);
sem_wait(v1);
v2 = (sem_t *)(32LL * ((a1 + 1) % 20) + 4211200);
sem_wait(v2);
output(a1, "eating");
idle();
++stats[a1];
sem_post(v1);
sem_post(v2);
return sem_post(&guard_deadlock);
}

canonical_decompiled_code:
int __fastcall func10(signed int a1)
{
sem_t *v1; // r12
sem_t *v2; // rbx

sem_wait(&guard_deadlock);
v1 = (sem_t *)(32LL * a1 + 4211200);
sem_wait(v1);
v2 = (sem_t *)(32LL * ((a1 + 1) % 20) + 4211200);
sem_wait(v2);
func8(a1, "eating");
func9();
++stats[a1];
sem_post(v1);
sem_post(v2);
return sem_post(&guard_deadlock);
}

original_code:
void eat(int i) {
 sem_wait(&guard_deadlock);
 sem_wait(&guard_fork[i]);
 sem_wait(&guard_fork[(i+1)%(20)]);
 output(i, "eating");
 idle(2);
 stats[i] += 1;
 sem_post(&guard_fork[i]);
 sem_post(&guard_fork[(i+1)%(20)]);
 sem_post(&guard_deadlock);
}


think

decompiled_code:
int __fastcall think(unsigned int a1)
{
output(a1, "thinking");
return idle();
}

canonical_decompiled_code:
int __fastcall func11(unsigned int a1)
{
func8(a1, "thinking");
return func9();
}

original_code:
void think(int i) {
 output(i, "thinking");
 idle(3);
}


dine

decompiled_code:
void __fastcall __noreturn dine(void *a1)
{
do
{
think((unsigned int)a1);
eat((signed int)a1);
}
while ( !want_exit );
pthread_exit(0LL);
}

canonical_decompiled_code:
void __fastcall __noreturn func12(void *a1)
{
do
{
func11((unsigned int)a1);
func10((signed int)a1);
}
while ( !want_exit );
pthread_exit(0LL);
}

original_code:
void dine(void* i) {
 int number = (int)i;
 while (1) {
  think(number);
  eat(number);
  if (want_exit) { pthread_exit(0); }
 }
 return;
}

canonical_original_code:
void dine(void *i) {
 int number = (int)i;
 while (1) {
  think(number);
  eat(number);
  if (want_exit) { pthread_exit(0); }
 }
 return;
}

variable_types:
i
void *

variable_types: number int


decompiled_code:
int print_statistics()
{
int *v0; // rax
__int64 i; // rbp
int result; // eax
int v3; // ebx
float v4; // [rsp+Ch] [rbp-1Ch]

puts("\nStatistics\n==========");
v0 = stats;
v4 = 0.0;
do
v4 = fmaxf((float)*v0++, v4);
while ( v0 != (int *)&unk_4041D0 );
for ( i = 0LL; i != 20; ++i )
{
printf("%2d: %5d ", (unsigned int)i, (unsigned int)stats[i]);
v3 = 0;
if ( (float)((float)(100 * stats[i]) / v4) > 0.0 )
{
do
{
putchar(43);
++v3;
}
while ( (float)((float)(100 * stats[i]) / v4) > (float)v3 );
}
result = putchar(10);
}
return result;
}

canonical_decompiled_code:
int func13()
{
int *v0; // rax
__int64 i; // rbp
int result; // eax
int v3; // ebx
float v4; // [rsp+Ch] [rbp-1Ch]

puts("\nStatistics\n==========");
v0 = stats;
v4 = 0.0;
do
v4 = fmaxf((float)*v0++, v4);
while ( v0 != (int *)&unk_4041D0 );
for ( i = 0LL; i != 20; ++i )
{
printf("%2d: %5d ", (unsigned int)i, (unsigned int)stats[i]);
v3 = 0;
if ( (float)((float)(100 * stats[i]) / v4) > 0.0 )
{
do
{
putchar(43);
++v3;
}
while ( (float)((float)(100 * stats[i]) / v4) > (float)v3 );
}
result = putchar(10);
}
return result;
}

original_code:
void print_statistics() {
 float max = 0;
 int c = 0;
  int i = 0;
  printf("\nStatistics\n==========\n");
 for (i=0; i<(20); i++) { if (max < stats[i]) { max = stats[i]; } }
 for (i=0; i<(20); i++) {
  printf("%2d: %5d ", i, stats[i]);
  for (c=0; c< 100 * stats[i]/max ; c++) { printf("+"); }
  printf("\n");
 }
}

variable_types: max float

variable_types: c int


main

canonical_name: main

decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
sem_t *v3; // rbx
int *v4; // rax
pthread_t *v5; // rbx
pthread_t *v6; // r12
char *v7; // rbp

__sysv_signal(2, (__sighandler_t)at_exit);
sem_init(&guard_print, 0, 1u);
sem_init(&guard_deadlock, 0, 0x13u);
v3 = &guard_fork;
do
sem_init(v3++, 0, 1u);
while ( v3 != &guard_print );
v4 = stats;
do
*v4++ = 0;
while ( v4 != (int *)&unk_4041D0 );
v5 = &dining_philosopher;
v6 = &dining_philosopher;
v7 = 0LL;
do
pthread_create(v6++, 0LL, (void *(*)(void *))dine, v7++);
while ( v7 != (char *)20 );
do
pthread_join(*v5++, 0LL);
while ( v5 != (pthread_t *)stats );
print_statistics();
exit(0);
}

canonical_decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
sem_t *v3; // rbx
int *v4; // rax
pthread_t *v5; // rbx
pthread_t *v6; // r12
char *v7; // rbp

__sysv_signal(2, (__sighandler_t)at_exit);
sem_init(&guard_print, 0, 1u);
sem_init(&guard_deadlock, 0, 0x13u);
v3 = &guard_fork;
do
sem_init(v3++, 0, 1u);
while ( v3 != &guard_print );
v4 = stats;
do
*v4++ = 0;
while ( v4 != (int *)&unk_4041D0 );
v5 = &dining_philosopher;
v6 = &dining_philosopher;
v7 = 0LL;
do
pthread_create(v6++, 0LL, (void *(*)(void *))dine, v7++);
while ( v7 != (char *)20 );
do
pthread_join(*v5++, 0LL);
while ( v5 != (pthread_t *)stats );
func13();
exit(0);
}

original_code:
int main(int argc, char** argv) {
 signal(2, (void*)at_exit);
 int i = 0;
 sem_init(&guard_print, 0, 1);
 sem_init(&guard_deadlock, 0, (20)-1);
 for (i=0; i<(20); i++) { sem_init(&guard_fork[i], 0, 1); }
 for (i=0; i<(20); i++) { stats[i] = 0; }
 for (i=0; i<(20); i++) {
  pthread_create(&dining_philosopher[i], 0, (void*)dine, (void*)i);
 }
  for (i=0; i<(20); i++) { pthread_join(dining_philosopher[i], ((void *)0)); }
  print_statistics();
  exit(0);
}

canonical_original_code:
int main(int argc, char **argv) {
 signal(2, (void *)at_exit);
 int i = 0;
 sem_init(&guard_print, 0, 1);
 sem_init(&guard_deadlock, 0, (20)-1);
 for (i=0; i<(20); i++) { sem_init(&guard_fork[i], 0, 1); }
 for (i=0; i<(20); i++) { stats[i] = 0; }
 for (i=0; i<(20); i++) {
  pthread_create(&dining_philosopher[i], 0, (void *)dine, (void *)i);
 }
  for (i=0; i<(20); i++) { pthread_join(dining_philosopher[i], ((void *)0)); }
  print_statistics();
  exit(0);
}

variable_types: argc int

variable_types:
argv
char **


compar

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

result = 0xFFFFFFFFLL;
if ( *(_DWORD *)a1 >= *(_DWORD *)a2 )
result = *(_DWORD *)a1 > *(_DWORD *)a2;
return result;
}

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

result = 0xFFFFFFFFLL;
if ( *(_DWORD *)a1 >= *(_DWORD *)a2 )
result = *(_DWORD *)a1 > *(_DWORD *)a2;
return result;
}

original_code:
int compar(const void* a, const void* b) {
 return (*(int*)a < *(int*)b) ? -1 : (*(int*)a > *(int*)b);
}

canonical_original_code:
int compar(void *a, void *b) {
 return (*(int *)a < *(int *)b) ? -1 : (*(int *)a > *(int *)b);
}

variable_types:
a
void *

variable_types:
b
void *


decompiled_code:
void __fastcall read_all(int fd, __int64 a2, size_t a3)
{
int v5; // ebx
__int64 v6; // rsi
int v7; // eax

if ( a3 )
{
v5 = 0;
v6 = 0LL;
do
{
v7 = read(fd, (void *)(a2 + v6), a3);
if ( v7 <= 0 )
exit(255);
v5 += v7;
v6 = v5;
}
while ( v5 < a3 );
}
}

canonical_decompiled_code:
void __fastcall func8(int fd, __int64 a2, size_t a3)
{
int v5; // ebx
__int64 v6; // rsi
int v7; // eax

if ( a3 )
{
v5 = 0;
v6 = 0LL;
do
{
v7 = read(fd, (void *)(a2 + v6), a3);
if ( v7 <= 0 )
exit(255);
v5 += v7;
v6 = v5;
}
while ( v5 < a3 );
}
}

original_code:
void read_all(int fd, void *buf, size_t nbyte) {
 int r = 0; int res = 0;
 while (r < nbyte) {
  res = read(fd, buf + r, nbyte);
  if (res > 0) {
   r += res;
  } else {
   exit(255);
  }
 }
}

canonical_original_code:
void read_all(int fd, void *buf, unsigned long nbyte) {
 int r = 0; int res = 0;
 while (r < nbyte) {
  res = read(fd, buf + r, nbyte);
  if (res > 0) {
   r += res;
  } else {
   exit(255);
  }
 }
}

variable_types: fd int

variable_types:
buf
void *

variable_types:
nbyte
unsigned long

variable_types: r int

variable_types: res int


sort

decompiled_code:
void __fastcall sort(void *a1, int a2)
{
qsort(a1, a2, 4uLL, (__compar_fn_t)compar);
}

canonical_decompiled_code:
void __fastcall func9(void *a1, int a2)
{
qsort(a1, a2, 4uLL, (__compar_fn_t)compar);
}

original_code:
void sort(int field[], int nelem) {
 qsort(field, nelem, sizeof(int), compar);
}

variable_types:
field
int []

variable_types: nelem int


merge

original_code:
void merge(int in[], int count) {
 int tmp[count];
 int center = count/2;
 int i = 0;
 int j = 0 + center;
 int k = 0;
 while (i < center && j < count) {
  if (in[i] < in[j]) {
   tmp[k] = in[i]; i++;
  } else {
   tmp[k] = in[j]; j++;
  }
  k++;
 }
 while (i < center) { tmp[k] = in[i]; i++; k++; }
 while (j < count) { tmp[k] = in[j]; j++; k++; }
 memcpy(in, tmp, sizeof(int)*count);
}

canonical_original_code:
void merge(int in[], int count) {
 int tmp[-1];
 int center = count/2;
 int i = 0;
 int j = 0 + center;
 int k = 0;
 while (i < center && j < count) {
  if (in[i] < in[j]) {
   tmp[k] = in[i]; i++;
  } else {
   tmp[k] = in[j]; j++;
  }
  k++;
 }
 while (i < center) { tmp[k] = in[i]; i++; k++; }
 while (j < count) { tmp[k] = in[j]; j++; k++; }
 memcpy(in, tmp, sizeof(int)*count);
}

variable_types:
in
int []

variable_types: count int

variable_types:
tmp
int [-1]

variable_types: center int

variable_types: i int

variable_types: j int

variable_types: k int


decompiled_code:
void __fastcall forking_mergesort(char *a1, int a2)
{
__pid_t v2; // eax
__pid_t v3; // er13
size_t v4; // r12
int stat_loc; // [rsp+0h] [rbp-34h] BYREF
int pipedes[2]; // [rsp+4h] [rbp-30h] BYREF

if ( a2 > 1 )
{
pipe(pipedes);
v2 = fork();
v3 = v2;
if ( v2 < 0 )
{
perror("fork");
exit(0);
}
if ( v2 <= 0 )
{
close(pipedes[0]);
v4 = 4LL * (a2 / 2);
sort(&a1[v4], a2 - a2 / 2);
write(pipedes[1], &a1[v4], v4);
close(pipedes[1]);
exit(0);
}
close(pipedes[1]);
sort(a1, a2 / 2);
read_all(pipedes[0], (__int64)&a1[4 * (a2 / 2)], 4LL * (a2 / 2));
waitpid(v3, &stat_loc, 0);
close(pipedes[0]);
merge(a1, a2);
}
}

canonical_decompiled_code:
void __fastcall func11(char *a1, int a2)
{
__pid_t v2; // eax
__pid_t v3; // er13
size_t v4; // r12
int stat_loc; // [rsp+0h] [rbp-34h] BYREF
int pipedes[2]; // [rsp+4h] [rbp-30h] BYREF

if ( a2 > 1 )
{
pipe(pipedes);
v2 = fork();
v3 = v2;
if ( v2 < 0 )
{
perror("fork");
exit(0);
}
if ( v2 <= 0 )
{
close(pipedes[0]);
v4 = 4LL * (a2 / 2);
func9(&a1[v4], a2 - a2 / 2);
write(pipedes[1], &a1[v4], v4);
close(pipedes[1]);
exit(0);
}
close(pipedes[1]);
func9(a1, a2 / 2);
func8(pipedes[0], (__int64)&a1[4 * (a2 / 2)], 4LL * (a2 / 2));
waitpid(v3, &stat_loc, 0);
close(pipedes[0]);
func10(a1, a2);
}
}

original_code:
void forking_mergesort(int field[], int nelem) {
 int fd[2];
 int pid;
 int stat;
 if (nelem <= 1) { return; }
 pipe(fd);
 if ((pid = fork()) < 0) {
  perror("fork");
  exit(0);
 } else {
  if (pid > 0) {
   close(fd[1]);
   sort(field, nelem/2);
   read_all(fd[0], field+nelem/2, nelem/2 * sizeof(int));
   waitpid(pid, &stat, 0);
   close(fd[0]);
  } else {
   close(fd[0]);
   sort(field+nelem/2, nelem - nelem/2);
   write(fd[1], field+nelem/2, nelem/2 * sizeof(int));
   close(fd[1]);
   exit(0);
  }
  merge(field, nelem);
 }
}

variable_types:
fd
int [2]

variable_types: pid int

variable_types: stat int


main

decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax
char *v4; // rbx
char *v5; // rbp
char v6[400]; // [rsp+0h] [rbp-1A8h] BYREF
char v7[24]; // [rsp+190h] [rbp-18h] BYREF

v3 = time(0LL);
srand(v3);
v4 = v6;
v5 = v6;
do
{
*(_DWORD *)v5 = rand() % 1000;
v5 += 4;
}
while ( v5 != v7 );
forking_mergesort(v6, 100);
do
{
printf("%i ", *(unsigned int *)v4);
v4 += 4;
}
while ( v4 != v7 );
putchar(10);
exit(0);
}

canonical_decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax
char *v4; // rbx
char *v5; // rbp
char v6[400]; // [rsp+0h] [rbp-1A8h] BYREF
char v7[24]; // [rsp+190h] [rbp-18h] BYREF

v3 = time(0LL);
srand(v3);
v4 = v6;
v5 = v6;
do
{
*(_DWORD *)v5 = rand() % 1000;
v5 += 4;
}
while ( v5 != v7 );
func11(v6, 100);
do
{
printf("%i ", *(unsigned int *)v4);
v4 += 4;
}
while ( v4 != v7 );
putchar(10);
exit(0);
}

original_code:
int main(int argc, char* argv[]) {
 int field[100];
 srand(time(((void *)0)));
 int i;
 for (i=0; i<100; i++) { field[i] = rand() % 1000; }
 forking_mergesort(field, 100);
 for (i=0; i<100; i++) { printf("%i ", field[i]); }
 printf("\n");
 exit(0);
}

canonical_original_code:
int main(int argc, char *argv[]) {
 int field[100];
 srand(time(((void *)0)));
 int i;
 for (i=0; i<100; i++) { field[i] = rand() % 1000; }
 forking_mergesort(field, 100);
 for (i=0; i<100; i++) { printf("%i ", field[i]); }
 printf("\n");
 exit(0);
}

variable_types: argc int

variable_types:
argv
char *[]

variable_types:
field
int [100]


reader

decompiled_code:
__int64 __fastcall reader(void *a1)
{
unsigned int v1; // er12
int v2; // ebx
int v3; // ebp

v1 = file_open_read(a1);
v2 = 0;
do
{
sem_wait(&buf_full);
v3 = file_read(v1, 1588LL * v2 + 4216832, 1588LL);
buffill[v2] = v3;
v2 = (v2 + 1) % 735;
sem_post(&buf_empty);
}
while ( v3 > 0 );
return file_close(v1);
}

canonical_decompiled_code:
__int64 __fastcall func7(void *a1)
{
unsigned int v1; // er12
int v2; // ebx
int v3; // ebp

v1 = func11(a1);
v2 = 0;
do
{
sem_wait(&buf_full);
v3 = func9(v1, 1588LL * v2 + 4216832, 1588LL);
buffill[v2] = v3;
v2 = (v2 + 1) % 735;
sem_post(&buf_empty);
}
while ( v3 > 0 );
return func13(v1);
}

original_code:
void reader(char* srcpath) {
  int srcfd = file_open_read(srcpath);
  int bufpos = 0;
  int rcount;
  do {
    sem_wait(&buf_full);
    rcount = file_read(srcfd, buffer[bufpos], sizeof(buffer[bufpos]));
    buffill[bufpos] = rcount;
    bufpos = (bufpos + 1) % (735);
    sem_post(&buf_empty);
  } while(rcount > 0);
  file_close(srcfd);
}

canonical_original_code:
void reader(char *srcpath) {
  int srcfd = file_open_read(srcpath);
  int bufpos = 0;
  int rcount;
  do {
    sem_wait(&buf_full);
    rcount = file_read(srcfd, buffer[bufpos], sizeof(buffer[bufpos]));
    buffill[bufpos] = rcount;
    bufpos = (bufpos + 1) % (735);
    sem_post(&buf_empty);
  } while(rcount > 0);
  file_close(srcfd);
}

variable_types:
srcpath
char *

variable_types: srcfd int

variable_types: bufpos int

variable_types: rcount int


writer

decompiled_code:
__int64 __fastcall writer(void *a1)
{
unsigned int v1; // ebp
int v2; // ebx
int v3; // er12

v1 = file_open_write(a1);
v2 = 0;
do
{
sem_wait(&buf_empty);
v3 = file_write(v1);
v2 = (v2 + 1) % 735;
sem_post(&buf_full);
}
while ( v3 > 0 );
return file_close(v1);
}

canonical_decompiled_code:
__int64 __fastcall func8(void *a1)
{
unsigned int v1; // ebp
int v2; // ebx
int v3; // er12

v1 = func12(a1);
v2 = 0;
do
{
sem_wait(&buf_empty);
v3 = func10(v1);
v2 = (v2 + 1) % 735;
sem_post(&buf_full);
}
while ( v3 > 0 );
return func13(v1);
}

original_code:
void writer(char* destpath) {
  int destfd = file_open_write(destpath);
  int bufpos = 0;
  int wcount;
  do {
    sem_wait(&buf_empty);
    wcount = file_write(destfd, buffer[bufpos], buffill[bufpos]);
    bufpos = (bufpos + 1) % (735);
    sem_post(&buf_full);
  } while(wcount > 0);
  file_close(destfd);
}

canonical_original_code:
void writer(char *destpath) {
  int destfd = file_open_write(destpath);
  int bufpos = 0;
  int wcount;
  do {
    sem_wait(&buf_empty);
    wcount = file_write(destfd, buffer[bufpos], buffill[bufpos]);
    bufpos = (bufpos + 1) % (735);
    sem_post(&buf_full);
  } while(wcount > 0);
  file_close(destfd);
}

variable_types:
destpath
char *

variable_types: destfd int

variable_types: wcount int


decompiled_code:
ssize_t __fastcall file_read(int a1, void *a2, size_t a3)
{
ssize_t result; // rax

result = read(a1, a2, a3);
if ( result < 0 )
{
perror("error while reading from source file");
exit(3);
}
return result;
}

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

result = read(a1, a2, a3);
if ( result < 0 )
{
perror("error while reading from source file");
exit(3);
}
return result;
}

original_code:
ssize_t file_read(int fd, void* buf, size_t count) {
  ssize_t n = read(fd, buf, count);
  if (n < 0) {
    perror("error while reading from source file");
    exit(3);
  }
  return n;
}

canonical_original_code:
long file_read(int fd, void *buf, unsigned long count) {
  long n = read(fd, buf, count);
  if (n < 0) {
    perror("error while reading from source file");
    exit(3);
  }
  return n;
}

variable_types: fd int

variable_types:
buf
void *

variable_types:
count
unsigned long

variable_types: n long

return_type: long


decompiled_code:
unsigned __int64 __fastcall file_write(int fd, __int64 a2, unsigned __int64 a3)
{
unsigned __int64 v5; // rbx
unsigned __int64 v6; // rsi
ssize_t v7; // rax

if ( !a3 )
return 0LL;
v5 = 0LL;
v6 = 0LL;
do
{
v7 = write(fd, (const void *)(a2 + v6), a3 - v6);
if ( v7 < 0 )
exit(-1);
v5 += v7;
v6 = v5;
}
while ( v5 < a3 );
return v5;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func10(int fd, __int64 a2, unsigned __int64 a3)
{
unsigned __int64 v5; // rbx
unsigned __int64 v6; // rsi
ssize_t v7; // rax

if ( !a3 )
return 0LL;
v5 = 0LL;
v6 = 0LL;
do
{
v7 = write(fd, (const void *)(a2 + v6), a3 - v6);
if ( v7 < 0 )
exit(-1);
v5 += v7;
v6 = v5;
}
while ( v5 < a3 );
return v5;
}

original_code:
ssize_t file_write(int fd, const void *buf, size_t count) {
  ssize_t wcount = 0;
  while (wcount < count) {
    ssize_t result = write(fd, buf + wcount, count - wcount);
    if (result < 0) { exit(-1); }
    wcount += result;
  }
  return wcount;
}

canonical_original_code:
long file_write(int fd, void *buf, unsigned long count) {
  long wcount = 0;
  while (wcount < count) {
    long result = write(fd, buf + wcount, count - wcount);
    if (result < 0) { exit(-1); }
    wcount += result;
  }
  return wcount;
}

variable_types: wcount long

variable_types: result long


decompiled_code:
int __fastcall file_open_read(const char *a1)
{
int result; // eax

result = open(a1, 0);
if ( result <= 0 )
{
perror("error opening input file for reading");
exit(2);
}
return result;
}

canonical_decompiled_code:
int __fastcall func11(const char *a1)
{
int result; // eax

result = open(a1, 0);
if ( result <= 0 )
{
perror("error opening input file for reading");
exit(2);
}
return result;
}

original_code:
int file_open_read(char* path) {
  int fd = open(path, 00);
  if (fd <= 0) {
    perror("error opening input file for reading");
    exit(2);
  }
  return fd;
}

canonical_original_code:
int file_open_read(char *path) {
  int fd = open(path, 00);
  if (fd <= 0) {
    perror("error opening input file for reading");
    exit(2);
  }
  return fd;
}

variable_types:
path
char *


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

result = close(a1);
if ( result < 0 )
{
perror("error closing file");
exit(2);
}
return result;
}

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

result = close(a1);
if ( result < 0 )
{
perror("error closing file");
exit(2);
}
return result;
}

original_code:
void file_close(int fd) {
  int result = close(fd);
  if (result < 0) {
    perror("error closing file");
    exit(2);
  }
}

variable_types: result int


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
pthread_t th; // [rsp+0h] [rbp-18h] BYREF
pthread_t newthread[2]; // [rsp+8h] [rbp-10h] BYREF

if ( argc != 3 )
{
printf("USAGE: %s <source> <dest>\n", *argv);
exit(1);
}
sem_init(&buf_empty, 0, 0);
sem_init(&buf_full, 0, 0x2DFu);
pthread_create(newthread, 0LL, (void *(*)(void *))reader, (void *)argv[1]);
pthread_create(&th, 0LL, (void *(*)(void *))writer, (void *)argv[2]);
pthread_join(newthread[0], 0LL);
pthread_join(th, 0LL);
return 0;
}

original_code:
int main(int argc, char* argv[]) {
  if (argc != 3) {
    printf("USAGE: %s <source> <dest>\n", argv[0]);
    exit(1);
  }
  sem_init(&buf_empty, 0, 0);
  sem_init(&buf_full, 0, (735));
  pthread_t reader_thread;
  pthread_t writer_thread;
  pthread_create(&reader_thread, 0, (void*)reader, (void*)argv[1]);
  pthread_create(&writer_thread, 0, (void*)writer, (void*)argv[2]);
  pthread_join(reader_thread, ((void *)0));
  pthread_join(writer_thread, ((void *)0));
  return 0;
}

canonical_original_code:
int main(int argc, char *argv[]) {
  if (argc != 3) {
    printf("USAGE: %s <source> <dest>\n", argv[0]);
    exit(1);
  }
  sem_init(&buf_empty, 0, 0);
  sem_init(&buf_full, 0, (735));
  unsigned long reader_thread;
  unsigned long writer_thread;
  pthread_create(&reader_thread, 0, (void *)reader, (void *)argv[1]);
  pthread_create(&writer_thread, 0, (void *)writer, (void *)argv[2]);
  pthread_join(reader_thread, ((void *)0));
  pthread_join(writer_thread, ((void *)0));
  return 0;
}

variable_types: argc int

variable_types:
argv
char *[]


repo: lexruee/Unifr-System-Programming

decompiled_code:
int print_usage()
{
return puts("p)put(i) g)get Q)Quit");
}

canonical_decompiled_code:
int func7()
{
return puts("p)put(i) g)get Q)Quit");
}

original_code:
void print_usage()
{
  printf("p)put(i)   g)get   Q)Quit\n");
}


decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // ebx
unsigned int v4; // ebp
char v5; // al
unsigned int v7; // [rsp+Ch] [rbp-1Ch]

print_usage();
printf("%i%s", 1LL, "> ");
for ( i = 3; ; ++i )
{
v4 = i - 1;
v5 = getchar();
if ( v5 == 81 )
break;
if ( v5 == 103 )
{
v7 = fifo_get();
printf("%i\n", v7);
}
else if ( v5 == 112 )
{
if ( (unsigned int)__isoc99_scanf() != 1 )
{
while ( getchar() != 10 )
;
printf("%s: ERROR: wrong scanf argument\n", *argv);
printf("%i%s", v4, "> ");
continue;
}
fifo_put(v7);
printf("%i\n", v7);
}
else
{
print_usage();
}
while ( getchar() != 10 )
;
printf("%i%s", v4, "> ");
}
puts("Quit");
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // ebx
unsigned int v4; // ebp
char v5; // al
unsigned int v7; // [rsp+Ch] [rbp-1Ch]

func7();
printf("%i%s", 1LL, "> ");
for ( i = 3; ; ++i )
{
v4 = i - 1;
v5 = getchar();
if ( v5 == 81 )
break;
if ( v5 == 103 )
{
v7 = func10();
printf("%i\n", v7);
}
else if ( v5 == 112 )
{
if ( (unsigned int)__isoc99_scanf() != 1 )
{
while ( getchar() != 10 )
;
printf("%s: ERROR: wrong scanf argument\n", *argv);
printf("%i%s", v4, "> ");
continue;
}
func9(v7);
printf("%i\n", v7);
}
else
{
func7();
}
while ( getchar() != 10 )
;
printf("%i%s", v4, "> ");
}
puts("Quit");
return 0;
}

original_code:
int main(int argc, char *argv[])
{
  int elt;
  char c;
  const char *prompt = "> ";
  int prompt_count = 1;
  print_usage();
  printf("%i%s", prompt_count++, prompt);
  while ( (c = getchar()) != 'Q')
  {
    switch(c)
    {
      case 'p':
        if (scanf("%i", &elt) != 1) goto error_scanf;
        fifo_put(elt);
        printf("%i\n", elt);
        break;
      case 'g':
        elt = fifo_get();
        printf("%i\n", elt);
        break;
      default:
        print_usage();
        break;
    }
    while (getchar() != '\n') {}
    printf("%i%s", prompt_count++, prompt);
    continue;
error_scanf:
    while (getchar() != '\n') {}
    printf("%s: ERROR: wrong scanf argument\n", argv[0]);
    printf("%i%s", prompt_count++, prompt);
    continue;
  }
  printf("Quit\n");
  return 0;
}

canonical_original_code:
int main(int argc, char *argv[])
{
  int elt;
  char c;
  char *prompt = "> ";
  int prompt_count = 1;
  print_usage();
  printf("%i%s", prompt_count++, prompt);
  while ( (c = getchar()) != 'Q')
  {
    switch(c)
    {
      case 'p':
        if (scanf("%i", &elt) != 1) goto error_scanf;
        fifo_put(elt);
        printf("%i\n", elt);
        break;
      case 'g':
        elt = fifo_get();
        printf("%i\n", elt);
        break;
      default:
        print_usage();
        break;
    }
    while (getchar() != '\n') {}
    printf("%i%s", prompt_count++, prompt);
    continue;
error_scanf:
    while (getchar() != '\n') {}
    printf("%s: ERROR: wrong scanf argument\n", argv[0]);
    printf("%i%s", prompt_count++, prompt);
    continue;
  }
  printf("Quit\n");
  return 0;
}

variable_types: elt int

variable_types: c char

variable_types:
prompt
char *


decompiled_code:
void shift_low_end()
{
int v0; // ecx
__int64 v1; // rdx
__int64 v2; // rax

v0 = tail - head;
if ( tail - head > 0 )
{
v1 = head;
v2 = 0LL;
do
{
base[v2] = base[v2 + v1];
++v2;
}
while ( v0 > (int)v2 );
}
tail = v0;
head = 0;
}

canonical_decompiled_code:
void func8()
{
int v0; // ecx
__int64 v1; // rdx
__int64 v2; // rax

v0 = tail - head;
if ( tail - head > 0 )
{
v1 = head;
v2 = 0LL;
do
{
base[v2] = base[v2 + v1];
++v2;
}
while ( v0 > (int)v2 );
}
tail = v0;
head = 0;
}

original_code:
static void shift_low_end()
{
  int i;
  for (i=0; i<tail-head; i++) base[i] = base[i+head];
  tail = tail - head;
  head=0;
}

variable_types: i int


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

if ( tail - head == 4 )
exit(1);
if ( tail == 4 )
shift_low_end();
LODWORD(result) = tail++;
result = (int)result;
base[(int)result] = a1;
return result;
}

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

if ( tail - head == 4 )
exit(1);
if ( tail == 4 )
func8();
LODWORD(result) = tail++;
result = (int)result;
base[(int)result] = a1;
return result;
}

original_code:
void fifo_put(int e)
{
  if (tail - head == 4) exit(1);
  if (tail == 4) shift_low_end();
  base[tail++] = e;
}

variable_types: e int


decompiled_code:
__int64 fifo_get()
{
int v0; // eax

v0 = head;
if ( head == tail )
exit(1);
++head;
return (unsigned int)base[v0];
}

canonical_decompiled_code:
__int64 func10()
{
int v0; // eax

v0 = head;
if ( head == tail )
exit(1);
++head;
return (unsigned int)base[v0];
}

original_code:
int fifo_get()
{
  if (head == tail) exit(1);
  return base[head++];
}


checkerr

repo: lexs/kjell

decompiled_code:
void __fastcall checkerr(int a1, const char *a2)
{
if ( a1 == -1 )
{
perror(a2);
exit(1);
}
}

canonical_decompiled_code:
void __fastcall func7(int a1, const char *a2)
{
if ( a1 == -1 )
{
perror(a2);
exit(1);
}
}

original_code:
void checkerr(int err, char *message) {
    if (err == -1) {
        perror(message);
        exit(1);
    }
}

variable_types: err int

variable_types:
message
char *


execute

decompiled_code:
void __fastcall __noreturn execute(char **argv)
{
execvp(*argv, argv);
if ( *__errno_location() == 2 )
printf("kjell: command not found: %s\n", *argv);
else
printf("kjell: failed to start command: %s\n", *argv);
exit(1);
}

canonical_decompiled_code:
void __fastcall __noreturn func8(char **argv)
{
execvp(*argv, argv);
if ( *__errno_location() == 2 )
printf("kjell: command not found: %s\n", *argv);
else
printf("kjell: failed to start command: %s\n", *argv);
exit(1);
}

original_code:
void execute(char **program) {
    execvp(program[0], program);
    if ((*__errno_location ()) == 2) {
        printf("kjell: command not found: %s\n", program[0]);
    } else {
        printf("kjell: failed to start command: %s\n", program[0]);
    }
    exit(1);
}

variable_types:
program
char **


decompiled_code:
void __fastcall run_foreground(char **argv)
{
int v1; // ebx
int v2; // eax
int stat_loc[7]; // [rsp+Ch] [rbp-1Ch] BYREF

v1 = fork();
checkerr(v1, "Cannot fork");
if ( !v1 )
{
__sysv_signal(2, 0LL);
execute(argv);
}
v2 = waitpid(v1, stat_loc, 0);
checkerr(v2, "waitpid() failed unexpectedly");
}

canonical_decompiled_code:
void __fastcall func9(char **argv)
{
int v1; // ebx
int v2; // eax
int stat_loc[7]; // [rsp+Ch] [rbp-1Ch] BYREF

v1 = fork();
func7(v1, "Cannot fork");
if ( !v1 )
{
__sysv_signal(2, 0LL);
func8(argv);
}
v2 = waitpid(v1, stat_loc, 0);
func7(v2, "waitpid() failed unexpectedly");
}

original_code:
void run_foreground(char** program) {
    pid_t pid = fork();
    checkerr(pid, "Cannot fork");
    if (pid == 0) {
        signal(2, ((__sighandler_t) 0));
        execute(program);
    } else {
        int status;
        int r = waitpid(pid, &status, 0);
        checkerr(r, "waitpid() failed unexpectedly");
    }
}

canonical_original_code:
void run_foreground(char **program) {
    int pid = fork();
    checkerr(pid, "Cannot fork");
    if (pid == 0) {
        signal(2, ((void (*)(int)) 0));
        execute(program);
    } else {
        int status;
        int r = waitpid(pid, &status, 0);
        checkerr(r, "waitpid() failed unexpectedly");
    }
}

variable_types: pid int

variable_types: status int

variable_types: r int


decompiled_code:
__int64 __fastcall run_background(char **argv)
{
unsigned int v1; // ebx

v1 = fork();
checkerr(v1, "Cannot fork");
if ( !v1 )
execute(argv);
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func10(char **argv)
{
unsigned int v1; // ebx

v1 = fork();
func7(v1, "Cannot fork");
if ( !v1 )
func8(argv);
return v1;
}

original_code:
pid_t run_background(char **program) {
    pid_t pid = fork();
    checkerr(pid, "Cannot fork");
    if (pid == 0) {
        execute(program);
    }
    return pid;
}

canonical_original_code:
int run_background(char **program) {
    int pid = fork();
    checkerr(pid, "Cannot fork");
    if (pid == 0) {
        execute(program);
    }
    return pid;
}


decompiled_code:
__int64 __fastcall read_command(__int64 a1)
{
_QWORD *v1; // rbx
int v2; // ebp
signed int v3; // eax
const char **v4; // rdx
char *stringp; // [rsp+8h] [rbp-30h] BYREF

if ( fgets((char *)a1, 128, stdin) )
{
stringp = (char *)a1;
v1 = (_QWORD *)(a1 + 128);
v2 = 0;
while ( 1 )
{
v3 = (unsigned int)strsep(&stringp, " \t\n");
*v1 = v3;
if ( !v3 )
break;
if ( *(_BYTE *)v3 )
{
++v2;
if ( (unsigned __int64)++v1 >= a1 + 768 )
break;
}
}
if ( v2 )
{
v4 = (const char **)(a1 + 128 + 8LL * v2 - 8);
if ( !strcmp(*v4, "&") )
{
*(_DWORD *)(a1 + 208) = 1;
*v4 = 0LL;
}
else
{
*(_DWORD *)(a1 + 208) = 0;
}
}
else
{
v2 = -1;
}
}
else
{
v2 = -1;
}
return (unsigned int)v2;
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1)
{
_QWORD *v1; // rbx
int v2; // ebp
signed int v3; // eax
const char **v4; // rdx
char *stringp; // [rsp+8h] [rbp-30h] BYREF

if ( fgets((char *)a1, 128, stdin) )
{
stringp = (char *)a1;
v1 = (_QWORD *)(a1 + 128);
v2 = 0;
while ( 1 )
{
v3 = (unsigned int)strsep(&stringp, " \t\n");
*v1 = v3;
if ( !v3 )
break;
if ( *(_BYTE *)v3 )
{
++v2;
if ( (unsigned __int64)++v1 >= a1 + 768 )
break;
}
}
if ( v2 )
{
v4 = (const char **)(a1 + 128 + 8LL * v2 - 8);
if ( !strcmp(*v4, "&") )
{
*(_DWORD *)(a1 + 208) = 1;
*v4 = 0LL;
}
else
{
*(_DWORD *)(a1 + 208) = 0;
}
}
else
{
v2 = -1;
}
}
else
{
v2 = -1;
}
return (unsigned int)v2;
}

original_code:
int read_command(command_t *command) {
    if (fgets(command->line, sizeof command->line, stdin)) {
        int argc = 0;
        char **ap, **argv = command->argv, *input = command->line;
        for (ap = argv; (*ap = strsep(&input, " \t\n")) != ((void *)0);)
            if (**ap != '\0') {
                argc++;
                if (++ap >= &argv[sizeof command->argv]) break;
            }
        if (argc == 0) {
            return -1;
        }
        if (strcmp(argv[argc - 1], "&") == 0) {
            command->background = 1;
            argv[argc - 1] = '\0';
        } else {
            command->background = 0;
        }
        return argc;
    }
    return -1;
}

canonical_original_code:
int read_command(struct command_t *command) {
    if (fgets(command->line, sizeof command->line, stdin)) {
        int argc = 0;
        char **ap; char **argv = command->argv; char *input = command->line;
        for (ap = argv; (*ap = strsep(&input, " \t\n")) != ((void *)0);)
            if (**ap != '\0') {
                argc++;
                if (++ap >= &argv[sizeof command->argv]) break;
            }
        if (argc == 0) {
            return -1;
        }
        if (strcmp(argv[argc - 1], "&") == 0) {
            command->background = 1;
            argv[argc - 1] = '\0';
        } else {
            command->background = 0;
        }
        return argc;
    }
    return -1;
}

variable_types: struct command_t { char line[128]; char *argv[10]; int background; } *

variable_types:
ap
char **

variable_types:
argv
char **

variable_types:
input
char *


decompiled_code:
__int64 __fastcall check_bg_processes(unsigned int a1)
{
int v1; // ebx
__int64 result; // rax
int stat_loc; // [rsp+Ch] [rbp-1Ch] BYREF

v1 = waitpid(-1, &stat_loc, 1);
checkerr(v1, "waitpid() failed unexpectedly");
result = a1;
if ( v1 > 0 )
{
if ( BYTE1(stat_loc) )
printf("[?] %d exit %d\n", (unsigned int)v1, BYTE1(stat_loc));
else
printf("[?] %d done\n", (unsigned int)v1);
result = a1 - 1;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func12(unsigned int a1)
{
int v1; // ebx
__int64 result; // rax
int stat_loc; // [rsp+Ch] [rbp-1Ch] BYREF

v1 = waitpid(-1, &stat_loc, 1);
func7(v1, "waitpid() failed unexpectedly");
result = a1;
if ( v1 > 0 )
{
if ( BYTE1(stat_loc) )
printf("[?] %d exit %d\n", (unsigned int)v1, BYTE1(stat_loc));
else
printf("[?] %d done\n", (unsigned int)v1);
result = a1 - 1;
}
return result;
}

original_code:
int check_bg_processes(int num_processes) {
    int status;
    pid_t pid = waitpid(-1, &status, 1);
    checkerr(pid, "waitpid() failed unexpectedly");
    if (pid > 0) {
        if ((((status) & 0xff00) >> 8) == 0) {
            printf("[?] %d done\n", pid);
        } else {
            printf("[?] %d exit %d\n", pid, (((status) & 0xff00) >> 8));
        }
        num_processes--;
    }
    return num_processes;
}

canonical_original_code:
int check_bg_processes(int num_processes) {
    int status;
    int pid = waitpid(-1, &status, 1);
    checkerr(pid, "waitpid() failed unexpectedly");
    if (pid > 0) {
        if ((((status) & 0xff00) >> 8) == 0) {
            printf("[?] %d done\n", pid);
        } else {
            printf("[?] %d exit %d\n", pid, (((status) & 0xff00) >> 8));
        }
        num_processes--;
    }
    return num_processes;
}


cd

decompiled_code:
int __fastcall cd(const char *a1)
{
int result; // eax

result = chdir(a1);
if ( result == -1 )
{
if ( *__errno_location() == 2 )
result = printf("kjell: no such file or directory: %s\n", a1);
else
result = puts("kjell: failed to change directory");
}
return result;
}

canonical_decompiled_code:
int __fastcall func13(const char *a1)
{
int result; // eax

result = chdir(a1);
if ( result == -1 )
{
if ( *__errno_location() == 2 )
result = printf("kjell: no such file or directory: %s\n", a1);
else
result = puts("kjell: failed to change directory");
}
return result;
}

original_code:
void cd(char *dir) {
    if (chdir(dir) == -1) {
        if ((*__errno_location ()) == 2) {
            printf("kjell: no such file or directory: %s\n", dir);
        } else {
            printf("kjell: failed to change directory\n");
        }
    }
}

variable_types:
dir
char *


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

if ( !strcmp(a1, "cd") )
{
cd(*(const char **)(a2 + 8));
result = 1LL;
}
else
{
if ( !strcmp(a1, "exit") )
exit(1);
result = 0LL;
}
return result;
}

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

if ( !strcmp(a1, "cd") )
{
func13(*(const char **)(a2 + 8));
result = 1LL;
}
else
{
if ( !strcmp(a1, "exit") )
exit(1);
result = 0LL;
}
return result;
}

original_code:
int execute_builtin(char *name, char **argv) {
    if (strcmp(name, "cd") == 0) {
        cd(argv[1]);
    } else if (strcmp(name, "exit") == 0) {
        exit(1);
    } else {
        return 0;
    }
    return 1;
}

variable_types:
name
char *


decompiled_code:
char *__fastcall resolve_home(char *s1)
{
char *v1; // rbx
char *v2; // rax
const char *v3; // rbp
size_t v4; // r12

v1 = s1;
v2 = getenv("HOME");
if ( v2 )
{
v3 = v2;
v4 = strlen(v2);
if ( !strncmp(s1, v3, v4) )
{
v1 = &s1[v4 - 1];
*v1 = 126;
}
}
return v1;
}

canonical_decompiled_code:
char *__fastcall func15(char *s1)
{
char *v1; // rbx
char *v2; // rax
const char *v3; // rbp
size_t v4; // r12

v1 = s1;
v2 = getenv("HOME");
if ( v2 )
{
v3 = v2;
v4 = strlen(v2);
if ( !strncmp(s1, v3, v4) )
{
v1 = &s1[v4 - 1];
*v1 = 126;
}
}
return v1;
}

original_code:
char* resolve_home(char* path) {
    char* home = getenv("HOME");
    if (home == ((void *)0)) {
        return path;
    }
    size_t home_len = strlen(home);
    if (strncmp(path, home, home_len) == 0) {
        path[home_len - 1] = '~';
        return &path[home_len - 1];
    } else {
        return path;
    }
}

canonical_original_code:
char *resolve_home(char *path) {
    char *home = getenv("HOME");
    if (home == ((void *)0)) {
        return path;
    }
    unsigned long home_len = strlen(home);
    if (strncmp(path, home, home_len) == 0) {
        path[home_len - 1] = '~';
        return &path[home_len - 1];
    } else {
        return path;
    }
}

variable_types:
path
char *

variable_types:
home
char *


decompiled_code:
int print_prompt()
{
char *v0; // rax
char v2[136]; // [rsp+0h] [rbp-88h] BYREF

if ( !getcwd(v2, 0x80uLL) )
return printf("$ ");
v0 = resolve_home(v2);
return printf("%s$ ", v0);
}

canonical_decompiled_code:
int func16()
{
char *v0; // rax
char v2[136]; // [rsp+0h] [rbp-88h] BYREF

if ( !getcwd(v2, 0x80uLL) )
return printf("$ ");
v0 = func15(v2);
return printf("%s$ ", v0);
}

original_code:
void print_prompt() {
    char path[128];
    if (getcwd(path, 128) != ((void *)0)) {
        printf("%s$ ", resolve_home(path));
    } else {
        printf("$ ");
    }
}

variable_types:
path
char [128]


main

decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
signed int v3; // ebx
unsigned int v4; // eax
__int64 v5; // [rsp+0h] [rbp-E8h] BYREF
char *argva[10]; // [rsp+80h] [rbp-68h] BYREF
int v7; // [rsp+D0h] [rbp-18h]

__sysv_signal(2, (__sighandler_t)1);
v3 = 0;
while ( 1 )
{
print_prompt();
if ( (unsigned int)read_command((__int64)&v5) != -1 && !(unsigned int)execute_builtin(argva[0], (__int64)argva) )
{
if ( v7 )
{
v4 = run_background(argva);
printf("[?] %d\n", v4);
++v3;
}
else
{
run_foreground(argva);
}
}
if ( v3 > 0 )
v3 = check_bg_processes(v3);
}
}

canonical_decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
signed int v3; // ebx
unsigned int v4; // eax
__int64 v5; // [rsp+0h] [rbp-E8h] BYREF
char *argva[10]; // [rsp+80h] [rbp-68h] BYREF
int v7; // [rsp+D0h] [rbp-18h]

__sysv_signal(2, (__sighandler_t)1);
v3 = 0;
while ( 1 )
{
func16();
if ( (unsigned int)func11((__int64)&v5) != -1 && !(unsigned int)func14(argva[0], (__int64)argva) )
{
if ( v7 )
{
v4 = func10(argva);
printf("[?] %d\n", v4);
++v3;
}
else
{
func9(argva);
}
}
if ( v3 > 0 )
v3 = func12(v3);
}
}

original_code:
int main(int argc, char** argv) {
    signal(2, ((__sighandler_t) 1));
    int bg_processes = 0;
    while (1) {
        command_t command;
        if (bg_processes > 0) {
            bg_processes = check_bg_processes(bg_processes);
        }
        print_prompt();
        if (read_command(&command) == -1) {
            continue;
        }
        if (!execute_builtin(command.argv[0], command.argv)) {
            if (command.background) {
                pid_t pid = run_background(command.argv);
                printf("[?] %d\n", pid);
                bg_processes++;
            } else {
                run_foreground(command.argv);
            }
        }
    }
    return 0;
}

canonical_original_code:
int main(int argc, char **argv) {
    signal(2, ((void (*)(int)) 1));
    int bg_processes = 0;
    while (1) {
        struct command_t command;
        if (bg_processes > 0) {
            bg_processes = check_bg_processes(bg_processes);
        }
        print_prompt();
        if (read_command(&command) == -1) {
            continue;
        }
        if (!execute_builtin(command.argv[0], command.argv)) {
            if (command.background) {
                int pid = run_background(command.argv);
                printf("[?] %d\n", pid);
                bg_processes++;
            } else {
                run_foreground(command.argv);
            }
        }
    }
    return 0;
}

variable_types: argc int

variable_types: struct command_t { char line[128]; char *argv[10]; int background; }


repo: leyafo/practice-algorithm

decompiled_code:
__int64 __fastcall cmp_int(_DWORD *a1, _DWORD *a2)
{
__int64 result; // rax

result = 1LL;
if ( *a1 <= *a2 )
result = (unsigned int)-(*a1 < *a2);
return result;
}

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

result = 1LL;
if ( *a1 <= *a2 )
result = (unsigned int)-(*a1 < *a2);
return result;
}

original_code:
static int
cmp_int(void *value1, void *value2)
{
    int A = *(int *) value1;
    int B = *(int *) value2;
    if(A > B)
        return 1;
    if(A < B)
        return -1;
    return 0;
}

variable_types: A int

variable_types: B int


decompiled_code:
int __fastcall print_int(unsigned int *a1)
{
return printf("node data is: %d\n", *a1);
}

canonical_decompiled_code:
int __fastcall func1(unsigned int *a1)
{
return printf("node data is: %d\n", *a1);
}

original_code:
static void
print_int(void *value)
{
    printf("node data is: %d\n", *(int *) value);
}

variable_types:
value
void *


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

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

original_code:
int
main(int argc, char* argv[])
{
    rb_tree_test();
    return 0;
}

canonical_original_code:
int main(int argc, char *argv[])
{
    rb_tree_test();
    return 0;
}

variable_types:
argv
char *[]


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

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

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

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

original_code:
int
is_red(struct tree_node *n)
{
    if(n == ((void *)0) || n->color == 0)
        return 0;
    return 1;
}

variable_types: struct tree_node { struct tree_node *left; struct tree_node *right; char color; void *data; } *