decompiled_code:
__int64 __fastcall handy_allograph_add_point(__int64 a1, double a2, float a3)
{
__int64 v3; // rax
char *v4; // rax
__int64 v5; // r8
float *v6; // rax
__int64 result; // rax

v3 = (unsigned int)(*(_DWORD *)(a1 + 512) + 1);
*(_DWORD *)(a1 + 512) = v3;
v4 = (char *)realloc(*(void **)(a1 + 520), 12 * v3);
if ( v4 )
{
v5 = *(unsigned int *)(a1 + 512);
*(_QWORD *)(a1 + 520) = v4;
v6 = (float *)&v4[12 * (unsigned int)(v5 - 1)];
*(double *)v6 = a2;
v6[2] = a3;
verbose(
0LL,
109LL,
"src/handy_allograph.c",
"Added point %f, %f to the allograph, number of points: %d",
*(float *)&a2,
*((float *)&a2 + 1),
v5);
result = 1LL;
}
else
{
verbose(
2LL,
104LL,
"src/handy_allograph.c",
"Reallocating memory space for new points: %f, %f",
*(float *)&a2,
*((float *)&a2 + 1));
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, double a2, float a3)
{
__int64 v3; // rax
char *v4; // rax
__int64 v5; // r8
float *v6; // rax
__int64 result; // rax

v3 = (unsigned int)(*(_DWORD *)(a1 + 512) + 1);
*(_DWORD *)(a1 + 512) = v3;
v4 = (char *)realloc(*(void **)(a1 + 520), 12 * v3);
if ( v4 )
{
v5 = *(unsigned int *)(a1 + 512);
*(_QWORD *)(a1 + 520) = v4;
v6 = (float *)&v4[12 * (unsigned int)(v5 - 1)];
*(double *)v6 = a2;
v6[2] = a3;
verbose(
0LL,
109LL,
"src/handy_allograph.c",
"Added point %f, %f to the allograph, number of points: %d",
*(float *)&a2,
*((float *)&a2 + 1),
v5);
result = 1LL;
}
else
{
verbose(
2LL,
104LL,
"src/handy_allograph.c",
"Reallocating memory space for new points: %f, %f",
*(float *)&a2,
*((float *)&a2 + 1));
result = 0LL;
}
return result;
}

original_code:
int handy_allograph_add_point(handy_allograph* allograph, handy_point point) {
 handy_point* points = ((void *)0);
 allograph->num_points++;
 points = (handy_point*) realloc(allograph->points, sizeof(handy_point) * allograph->num_points);
 if(points == ((void *)0)) {
  verbose(ERROR, 104, "src/handy_allograph.c", "Reallocating memory space for new points: %f, %f", point.x, point.y);
  return 0;
 } else {
  allograph->points = points;
  allograph->points[allograph->num_points - 1] = point;
  verbose(INFO, 109, "src/handy_allograph.c", "Added point %f, %f to the allograph, number of points: %d", point.x, point.y, allograph->num_points);
  return 1;
 }
}

canonical_original_code:
int handy_allograph_add_point(struct handy_allograph *allograph, struct handy_point point) {
 struct handy_point *points = ((void *)0);
 allograph->num_points++;
 points = (struct handy_point *) realloc(allograph->points, sizeof(handy_point) * allograph->num_points);
 if(points == ((void *)0)) {
  verbose(ERROR, 104, "src/handy_allograph.c", "Reallocating memory space for new points: %f, %f", point.x, point.y);
  return 0;
 } else {
  allograph->points = points;
  allograph->points[allograph->num_points - 1] = point;
  verbose(INFO, 109, "src/handy_allograph.c", "Added point %f, %f to the allograph, number of points: %d", point.x, point.y, allograph->num_points);
  return 1;
 }
}

variable_types:
point
struct handy_point

variable_types:
points
struct handy_point { float x; } *


repo: jfcalvo/handy

decompiled_code:
__int64 __fastcall handy_allograph_set_symbol(char *dest, char *src)
{
__int64 result; // rax

verbose(0LL, 116LL, "src/handy_allograph.c", "Adding symbol %s to allograph", src);
if ( dest )
{
if ( src )
{
strncpy(dest, src, 0x200uLL);
dest[511] = 0;
verbose(0LL, 127LL, "src/handy_allograph.c", "Symbol %s assigned to allograph", src);
result = 1LL;
}
else
{
verbose(2LL, 122LL, "src/handy_allograph.c", "Trying to set a null symbol at allograph");
result = 0LL;
}
}
else
{
verbose(
2LL,
118LL,
"src/handy_allograph.c",
"Impossible to assign symbol %s to allograph, allograph not initiated",
src);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(char *dest, char *src)
{
__int64 result; // rax

verbose(0LL, 116LL, "src/handy_allograph.c", "Adding symbol %s to allograph", src);
if ( dest )
{
if ( src )
{
strncpy(dest, src, 0x200uLL);
dest[511] = 0;
verbose(0LL, 127LL, "src/handy_allograph.c", "Symbol %s assigned to allograph", src);
result = 1LL;
}
else
{
verbose(2LL, 122LL, "src/handy_allograph.c", "Trying to set a null symbol at allograph");
result = 0LL;
}
}
else
{
verbose(
2LL,
118LL,
"src/handy_allograph.c",
"Impossible to assign symbol %s to allograph, allograph not initiated",
src);
result = 0LL;
}
return result;
}

original_code:
int handy_allograph_set_symbol(handy_allograph* allograph, char* symbol) {
    verbose(INFO, 116, "src/handy_allograph.c", "Adding symbol %s to allograph", symbol);
    if(allograph == ((void *)0)) {
        verbose(ERROR, 118, "src/handy_allograph.c", "Impossible to assign symbol %s to allograph, allograph not initiated", symbol);
        return 0;
    } else {
        if(symbol == ((void *)0)) {
            verbose(ERROR, 122, "src/handy_allograph.c", "Trying to set a null symbol at allograph");
            return 0;
        } else {
            strncpy(allograph->symbol, symbol, 512);
            allograph->symbol[512 - 1] = '\0';
            verbose(INFO, 127, "src/handy_allograph.c", "Symbol %s assigned to allograph", symbol);
            return 1;
        }
    }
}

canonical_original_code:
int handy_allograph_set_symbol(struct handy_allograph *allograph, char *symbol) {
    verbose(INFO, 116, "src/handy_allograph.c", "Adding symbol %s to allograph", symbol);
    if(allograph == ((void *)0)) {
        verbose(ERROR, 118, "src/handy_allograph.c", "Impossible to assign symbol %s to allograph, allograph not initiated", symbol);
        return 0;
    } else {
        if(symbol == ((void *)0)) {
            verbose(ERROR, 122, "src/handy_allograph.c", "Trying to set a null symbol at allograph");
            return 0;
        } else {
            strncpy(allograph->symbol, symbol, 512);
            allograph->symbol[512 - 1] = '\0';
            verbose(INFO, 127, "src/handy_allograph.c", "Symbol %s assigned to allograph", symbol);
            return 1;
        }
    }
}

variable_types: struct handy_allograph { char symbol[512]; unsigned int num_points; struct handy_point { float x; } *points; } *

variable_types:
symbol
char *

return_type: int

user_defined_types: struct handy_allograph { char symbol[512]; unsigned int num_points; struct handy_point *points; }


decompiled_code:
__int64 __fastcall handy_allograph_copy(char *dest, char *src)
{
__int64 v2; // rax
__int64 result; // rax
size_t v4; // r12
void *v5; // rax

verbose(0LL, 50LL, "src/handy_allograph.c", "Creating a copy of an allograph");
if ( src )
{
if ( dest )
{
v2 = *((unsigned int *)src + 128);
if ( !(_DWORD)v2 )
{
*((_QWORD *)dest + 65) = 0LL;
LABEL_5:
verbose(0LL, 74LL, "src/handy_allograph.c", "Copying other fields of the source allograph");
handy_allograph_set_symbol(dest, src);
*((_DWORD *)dest + 128) = *((_DWORD *)src + 128);
return 1LL;
}
v4 = 12 * v2;
v5 = malloc(12 * v2);
*((_QWORD *)dest + 65) = v5;
if ( v5 )
{
memcpy(v5, *((const void **)src + 65), v4);
goto LABEL_5;
}
verbose(2LL, 65LL, "src/handy_allograph.c", "Impossible to allocate memory for new points");
result = 0LL;
}
else
{
verbose(2LL, 58LL, "src/handy_allograph.c", "Destiny allograph to copy is not initiated");
result = 0LL;
}
}
else
{
verbose(2LL, 53LL, "src/handy_allograph.c", "Source allograph to copy is not initiated");
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(char *dest, char *src)
{
__int64 v2; // rax
__int64 result; // rax
size_t v4; // r12
void *v5; // rax

verbose(0LL, 50LL, "src/handy_allograph.c", "Creating a copy of an allograph");
if ( src )
{
if ( dest )
{
v2 = *((unsigned int *)src + 128);
if ( !(_DWORD)v2 )
{
*((_QWORD *)dest + 65) = 0LL;
LABEL_5:
verbose(0LL, 74LL, "src/handy_allograph.c", "Copying other fields of the source allograph");
func3(dest, src);
*((_DWORD *)dest + 128) = *((_DWORD *)src + 128);
return 1LL;
}
v4 = 12 * v2;
v5 = malloc(12 * v2);
*((_QWORD *)dest + 65) = v5;
if ( v5 )
{
memcpy(v5, *((const void **)src + 65), v4);
goto LABEL_5;
}
verbose(2LL, 65LL, "src/handy_allograph.c", "Impossible to allocate memory for new points");
result = 0LL;
}
else
{
verbose(2LL, 58LL, "src/handy_allograph.c", "Destiny allograph to copy is not initiated");
result = 0LL;
}
}
else
{
verbose(2LL, 53LL, "src/handy_allograph.c", "Source allograph to copy is not initiated");
result = 0LL;
}
return result;
}

original_code:
int handy_allograph_copy(handy_allograph* dst, handy_allograph* src) {
    verbose(INFO, 50, "src/handy_allograph.c", "Creating a copy of an allograph");
    if(src == ((void *)0)) {
        verbose(ERROR, 53, "src/handy_allograph.c", "Source allograph to copy is not initiated");
        return 0;
    }
    if(dst == ((void *)0)) {
        verbose(ERROR, 58, "src/handy_allograph.c", "Destiny allograph to copy is not initiated");
        return 0;
    }
    if(src->num_points > 0) {
        dst->points = (handy_point*) malloc(sizeof(handy_point) * src->num_points);
        if(dst->points == ((void *)0)) {
            verbose(ERROR, 65, "src/handy_allograph.c", "Impossible to allocate memory for new points");
            return 0;
        } else {
            memcpy(dst->points, src->points, sizeof(handy_point) * src->num_points);
        }
    } else {
        dst->points = ((void *)0);
    }
    verbose(INFO, 74, "src/handy_allograph.c", "Copying other fields of the source allograph");
    handy_allograph_set_symbol(dst, src->symbol);
    dst->num_points = src->num_points;
    return 1;
}

canonical_original_code:
int handy_allograph_copy(struct handy_allograph *dst, struct handy_allograph *src) {
    verbose(INFO, 50, "src/handy_allograph.c", "Creating a copy of an allograph");
    if(src == ((void *)0)) {
        verbose(ERROR, 53, "src/handy_allograph.c", "Source allograph to copy is not initiated");
        return 0;
    }
    if(dst == ((void *)0)) {
        verbose(ERROR, 58, "src/handy_allograph.c", "Destiny allograph to copy is not initiated");
        return 0;
    }
    if(src->num_points > 0) {
        dst->points = (struct handy_point *) malloc(sizeof(handy_point) * src->num_points);
        if(dst->points == ((void *)0)) {
            verbose(ERROR, 65, "src/handy_allograph.c", "Impossible to allocate memory for new points");
            return 0;
        } else {
            memcpy(dst->points, src->points, sizeof(handy_point) * src->num_points);
        }
    } else {
        dst->points = ((void *)0);
    }
    verbose(INFO, 74, "src/handy_allograph.c", "Copying other fields of the source allograph");
    handy_allograph_set_symbol(dst, src->symbol);
    dst->num_points = src->num_points;
    return 1;
}

variable_types:
src
struct handy_allograph *


original_code:
handy_uint handy_allograph_points_contained(handy_allograph* allograph, handy_rect rect) {
  handy_point point;
  handy_uint points_contained = 0;
  handy_float maximum_x, maximum_y;
  maximum_x = rect.origin.x + rect.size.width;
  maximum_y = rect.origin.y + rect.size.height;
  unsigned int i;
  for (i = 0; i < allograph->num_points; i++) {
    point.x = allograph->points[i].x;
    if (point.x >= rect.origin.x && point.x <= maximum_x) {
      point.y = allograph->points[i].y;
      if (point.y >= rect.origin.y && point.y <= maximum_y) {
        points_contained++;
      }
    }
  }
  return points_contained;
}

canonical_original_code:
unsigned int handy_allograph_points_contained(struct handy_allograph *allograph, struct handy_rect rect) {
  struct handy_point point;
  unsigned int points_contained = 0;
  float maximum_x; float maximum_y;
  maximum_x = rect.origin.x + rect.size.width;
  maximum_y = rect.origin.y + rect.size.height;
  unsigned int i;
  for (i = 0; i < allograph->num_points; i++) {
    point.x = allograph->points[i].x;
    if (point.x >= rect.origin.x && point.x <= maximum_x) {
      point.y = allograph->points[i].y;
      if (point.y >= rect.origin.y && point.y <= maximum_y) {
        points_contained++;
      }
    }
  }
  return points_contained;
}

variable_types: struct handy_rect { struct handy_point origin; struct handy_size { float width; } size; }

variable_types:
point
struct handy_point { float x; }

variable_types:
i
unsigned int

return_type: unsigned int

user_defined_types: struct handy_rect { struct handy_point origin; struct handy_size size; }


decompiled_code:
__m128i __fastcall handy_allograph_get_smallest(__int64 a1)
{
int v1; // edx
float *v2; // rcx
float v3; // xmm1_4
float v4; // xmm0_4
float *v5; // rax
__int64 v6; // rdx
float v7; // xmm2_4
__m128i v9; // [rsp+14h] [rbp-14h] BYREF

v1 = *(_DWORD *)(a1 + 512);
if ( v1 )
{
v2 = *(float **)(a1 + 520);
v3 = *v2;
v4 = v2[1];
if ( v1 != 1 )
{
v5 = v2 + 3;
v6 = (__int64)&v2[3 * (v1 - 2) + 6];
do
{
v7 = *v5;
v5 += 3;
v3 = fminf(v7, v3);
v4 = fminf(*(v5 - 2), v4);
}
while ( v5 != (float *)v6 );
}
}
else
{
verbose(1LL, 205LL, "src/handy_allograph.c", "Trying to get smallest point values for an empty allograph");
v4 = 0.0;
v3 = 0.0;
}
v9.m128i_i64[0] = __PAIR64__(LODWORD(v4), LODWORD(v3));
return _mm_loadl_epi64(&v9);
}

canonical_decompiled_code:
__m128i __fastcall func6(__int64 a1)
{
int v1; // edx
float *v2; // rcx
float v3; // xmm1_4
float v4; // xmm0_4
float *v5; // rax
__int64 v6; // rdx
float v7; // xmm2_4
__m128i v9; // [rsp+14h] [rbp-14h] BYREF

v1 = *(_DWORD *)(a1 + 512);
if ( v1 )
{
v2 = *(float **)(a1 + 520);
v3 = *v2;
v4 = v2[1];
if ( v1 != 1 )
{
v5 = v2 + 3;
v6 = (__int64)&v2[3 * (v1 - 2) + 6];
do
{
v7 = *v5;
v5 += 3;
v3 = fminf(v7, v3);
v4 = fminf(*(v5 - 2), v4);
}
while ( v5 != (float *)v6 );
}
}
else
{
verbose(1LL, 205LL, "src/handy_allograph.c", "Trying to get smallest point values for an empty allograph");
v4 = 0.0;
v3 = 0.0;
}
v9.m128i_i64[0] = __PAIR64__(LODWORD(v4), LODWORD(v3));
return _mm_loadl_epi64(&v9);
}

original_code:
handy_point handy_allograph_get_smallest(handy_allograph* allograph) {
    handy_point point;
    if(allograph->num_points > 0) {
        point.x = allograph->points[0].x;
        point.y = allograph->points[0].y;
        int i;
        for(i = 1; i < allograph->num_points; i++) {
            if(allograph->points[i].x < point.x) {
                point.x = allograph->points[i].x;
            }
            if(allograph->points[i].y < point.y) {
                point.y = allograph->points[i].y;
            }
        }
    } else {
        point.x = 0;
        point.y = 0;
        verbose(WARNING, 205, "src/handy_allograph.c", "Trying to get smallest point values for an empty allograph");
    }
    return point;
}

canonical_original_code:
struct handy_point handy_allograph_get_smallest(struct handy_allograph *allograph) {
    struct handy_point point;
    if(allograph->num_points > 0) {
        point.x = allograph->points[0].x;
        point.y = allograph->points[0].y;
        int i;
        for(i = 1; i < allograph->num_points; i++) {
            if(allograph->points[i].x < point.x) {
                point.x = allograph->points[i].x;
            }
            if(allograph->points[i].y < point.y) {
                point.y = allograph->points[i].y;
            }
        }
    } else {
        point.x = 0;
        point.y = 0;
        verbose(WARNING, 205, "src/handy_allograph.c", "Trying to get smallest point values for an empty allograph");
    }
    return point;
}

variable_types: struct handy_allograph { char symbol[512]; unsigned int num_points; struct handy_point *points; } *

variable_types: i int

return_type: struct handy_point { float x; }


decompiled_code:
__m128i __fastcall handy_allograph_get_biggest(__int64 a1)
{
int v1; // edx
float *v2; // rcx
float v3; // xmm1_4
float v4; // xmm0_4
float *v5; // rax
__int64 v6; // rdx
float v7; // xmm2_4
__m128i v9; // [rsp+14h] [rbp-14h] BYREF

v1 = *(_DWORD *)(a1 + 512);
if ( v1 )
{
v2 = *(float **)(a1 + 520);
v3 = *v2;
v4 = v2[1];
if ( v1 != 1 )
{
v5 = v2 + 3;
v6 = (__int64)&v2[3 * (v1 - 2) + 6];
do
{
v7 = *v5;
v5 += 3;
v3 = fmaxf(v7, v3);
v4 = fmaxf(*(v5 - 2), v4);
}
while ( v5 != (float *)v6 );
}
}
else
{
verbose(1LL, 238LL, "src/handy_allograph.c", "Trying to get biggest point values for an empty allograph");
v4 = 0.0;
v3 = 0.0;
}
v9.m128i_i64[0] = __PAIR64__(LODWORD(v4), LODWORD(v3));
return _mm_loadl_epi64(&v9);
}

canonical_decompiled_code:
__m128i __fastcall func7(__int64 a1)
{
int v1; // edx
float *v2; // rcx
float v3; // xmm1_4
float v4; // xmm0_4
float *v5; // rax
__int64 v6; // rdx
float v7; // xmm2_4
__m128i v9; // [rsp+14h] [rbp-14h] BYREF

v1 = *(_DWORD *)(a1 + 512);
if ( v1 )
{
v2 = *(float **)(a1 + 520);
v3 = *v2;
v4 = v2[1];
if ( v1 != 1 )
{
v5 = v2 + 3;
v6 = (__int64)&v2[3 * (v1 - 2) + 6];
do
{
v7 = *v5;
v5 += 3;
v3 = fmaxf(v7, v3);
v4 = fmaxf(*(v5 - 2), v4);
}
while ( v5 != (float *)v6 );
}
}
else
{
verbose(1LL, 238LL, "src/handy_allograph.c", "Trying to get biggest point values for an empty allograph");
v4 = 0.0;
v3 = 0.0;
}
v9.m128i_i64[0] = __PAIR64__(LODWORD(v4), LODWORD(v3));
return _mm_loadl_epi64(&v9);
}

original_code:
handy_point handy_allograph_get_biggest(handy_allograph* allograph) {
    handy_point point;
    if(allograph->num_points > 0) {
        point.x = allograph->points[0].x;
        point.y = allograph->points[0].y;
        int i;
        for(i = 1; i < allograph->num_points; i++) {
            if(allograph->points[i].x > point.x) {
                point.x = allograph->points[i].x;
            }
            if(allograph->points[i].y > point.y) {
                point.y = allograph->points[i].y;
            }
        }
    } else {
        point.x = 0;
        point.y = 0;
        verbose(WARNING, 238, "src/handy_allograph.c", "Trying to get biggest point values for an empty allograph");
    }
    return point;
}

canonical_original_code:
struct handy_point handy_allograph_get_biggest(struct handy_allograph *allograph) {
    struct handy_point point;
    if(allograph->num_points > 0) {
        point.x = allograph->points[0].x;
        point.y = allograph->points[0].y;
        int i;
        for(i = 1; i < allograph->num_points; i++) {
            if(allograph->points[i].x > point.x) {
                point.x = allograph->points[i].x;
            }
            if(allograph->points[i].y > point.y) {
                point.y = allograph->points[i].y;
            }
        }
    } else {
        point.x = 0;
        point.y = 0;
        verbose(WARNING, 238, "src/handy_allograph.c", "Trying to get biggest point values for an empty allograph");
    }
    return point;
}


decompiled_code:
__m128i __fastcall handy_allograph_get_center(__int64 a1)
{
unsigned __int64 v2; // [rsp+2Ch] [rbp-2Ch]
unsigned __int64 v3; // [rsp+38h] [rbp-20h]
__m128i v4; // [rsp+44h] [rbp-14h] BYREF

v2 = handy_allograph_get_smallest(a1).m128i_u64[0];
v3 = handy_allograph_get_biggest(a1).m128i_u64[0];
verbose(
0LL,
173LL,
"src/handy_allograph.c",
"Center point of allograph is (%f, %f)",
(float)((float)((float)(*(float *)&v3 - *(float *)&v2) * 0.5) + *(float *)&v2),
(float)((float)((float)(*((float *)&v3 + 1) - *((float *)&v2 + 1)) * 0.5) + *((float *)&v2 + 1)));
*(float *)v4.m128i_i32 = (float)((float)(*(float *)&v3 - *(float *)&v2) * 0.5) + *(float *)&v2;
*(float *)&v4.m128i_i32[1] = (float)((float)(*((float *)&v3 + 1) - *((float *)&v2 + 1)) * 0.5) + *((float *)&v2 + 1);
return _mm_loadl_epi64(&v4);
}

original_code:
handy_point handy_allograph_get_center(handy_allograph* allograph) {
    handy_point center, smallest, biggest;
    smallest = handy_allograph_get_smallest(allograph);
    biggest = handy_allograph_get_biggest(allograph);
    center.x = (handy_float) ((biggest.x - smallest.x) / 2.0) + smallest.x;
    center.y = (handy_float) ((biggest.y - smallest.y) / 2.0) + smallest.y;
    verbose(INFO, 173, "src/handy_allograph.c", "Center point of allograph is (%f, %f)", center.x, center.y);
    return center;
}

canonical_original_code:
struct handy_point handy_allograph_get_center(struct handy_allograph *allograph) {
    struct handy_point center; struct handy_point smallest; struct handy_point biggest;
    smallest = handy_allograph_get_smallest(allograph);
    biggest = handy_allograph_get_biggest(allograph);
    center.x = (handy_float) ((biggest.x - smallest.x) / 2.0) + smallest.x;
    center.y = (handy_float) ((biggest.y - smallest.y) / 2.0) + smallest.y;
    verbose(INFO, 173, "src/handy_allograph.c", "Center point of allograph is (%f, %f)", center.x, center.y);
    return center;
}

variable_types:
center
struct handy_point { float x; }

variable_types:
smallest
struct handy_point { float x; }

variable_types:
biggest
struct handy_point { float x; }


decompiled_code:
// attributes: thunk
const char *__fastcall handy_allograph_load(const char *a1)
{
return handy_allograph_load_binary(a1);
}

canonical_decompiled_code:
const char *__fastcall func1(const char *a1)
{
return func0(a1);
}

original_code:
handy_allograph* handy_allograph_load(char* path, handy_serialize format) {
    switch(format) {
        case HANDY_SERIALIZE_BINARY:
            return handy_allograph_load_binary(path);
            break;
        default:
            return handy_allograph_load_binary(path);
            break;
    }
}

canonical_original_code:
struct handy_allograph *handy_allograph_load(char *path, enum handy_serialize format) {
    switch(format) {
        case HANDY_SERIALIZE_BINARY:
            return handy_allograph_load_binary(path);
            break;
        default:
            return handy_allograph_load_binary(path);
            break;
    }
}

variable_types:
path
char *

variable_types: enum handy_serialize { HANDY_SERIALIZE_YAML=0, HANDY_SERIALIZE_JSON=1, HANDY_SERIALIZE_UJI2=2, HANDY_SERIALIZE_BINARY=3 }

return_type: struct handy_allograph { char symbol[512]; unsigned int num_points; struct handy_point { float x; } *points; } *


decompiled_code:
__int64 __fastcall handy_allograph_save(_DWORD *a1, char *a2, int a3)
{
__int64 result; // rax

if ( a1 )
{
if ( a1[128] )
{
if ( a3 == 3 )
result = handy_allograph_save_binary(a1, a2);
else
result = 0LL;
}
else
{
verbose(
(char *)handy_allograph_load_binary + 1,
&loc_73,
"src/handy_serialize.c",
"The number of points in the Allograph is zero, save to disk has not effect");
result = 0LL;
}
}
else
{
verbose(1LL, 118LL, "src/handy_serialize.c", "Allograph has not been initiated, save to disk has not effect");
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func3(_DWORD *a1, char *a2, int a3)
{
__int64 result; // rax

if ( a1 )
{
if ( a1[128] )
{
if ( a3 == 3 )
result = func2(a1, a2);
else
result = 0LL;
}
else
{
verbose(
(char *)handy_allograph_load_binary + 1,
&loc_73,
"src/handy_serialize.c",
"The number of points in the Allograph is zero, save to disk has not effect");
result = 0LL;
}
}
else
{
verbose(1LL, 118LL, "src/handy_serialize.c", "Allograph has not been initiated, save to disk has not effect");
result = 0LL;
}
return result;
}

original_code:
int handy_allograph_save(handy_allograph* allograph, char* path, handy_serialize format) {
    if(allograph != ((void *)0)) {
        if(allograph->num_points > 0) {
            switch(format) {
                case HANDY_SERIALIZE_BINARY:
                    return handy_allograph_save_binary(allograph, path);
                    break;
            }
        } else {
            verbose(WARNING, 115, "src/handy_serialize.c", "The number of points in the Allograph is zero, save to disk has not effect");
        }
    } else {
        verbose(WARNING, 118, "src/handy_serialize.c", "Allograph has not been initiated, save to disk has not effect");
    }
    return 0;
}

canonical_original_code:
int handy_allograph_save(struct handy_allograph *allograph, char *path, enum handy_serialize format) {
    if(allograph != ((void *)0)) {
        if(allograph->num_points > 0) {
            switch(format) {
                case HANDY_SERIALIZE_BINARY:
                    return handy_allograph_save_binary(allograph, path);
                    break;
            }
        } else {
            verbose(WARNING, 115, "src/handy_serialize.c", "The number of points in the Allograph is zero, save to disk has not effect");
        }
    } else {
        verbose(WARNING, 118, "src/handy_serialize.c", "Allograph has not been initiated, save to disk has not effect");
    }
    return 0;
}

user_defined_types: enum handy_serialize { HANDY_SERIALIZE_YAML=0, HANDY_SERIALIZE_JSON=1, HANDY_SERIALIZE_UJI2=2, HANDY_SERIALIZE_BINARY=3 }


decompiled_code:
unsigned int *__fastcall handy_collection_load(char *filename, int a2)
{
unsigned int *result; // rax

if ( a2 == 2 )
result = handy_collection_load_uji2(filename);
else
result = handy_collection_load_binary(filename);
return result;
}

canonical_decompiled_code:
unsigned int *__fastcall func6(char *filename, int a2)
{
unsigned int *result; // rax

if ( a2 == 2 )
result = func4(filename);
else
result = func5(filename);
return result;
}

original_code:
handy_collection* handy_collection_load(char* path, handy_serialize format) {
    switch(format) {
        case HANDY_SERIALIZE_UJI2:
            return handy_collection_load_uji2(path);
            break;
        case HANDY_SERIALIZE_BINARY:
            return handy_collection_load_binary(path);
            break;
        default:
            return handy_collection_load_binary(path);
            break;
    }
}

canonical_original_code:
struct handy_collection *handy_collection_load(char *path, enum handy_serialize format) {
    switch(format) {
        case HANDY_SERIALIZE_UJI2:
            return handy_collection_load_uji2(path);
            break;
        case HANDY_SERIALIZE_BINARY:
            return handy_collection_load_binary(path);
            break;
        default:
            return handy_collection_load_binary(path);
            break;
    }
}

return_type: struct handy_collection { unsigned int num_allographs; struct handy_allograph { char symbol[512]; unsigned int num_points; struct handy_point { float x; } *points; } *allographs; } *

user_defined_types: struct handy_collection { unsigned int num_allographs; struct handy_allograph *allographs; }


decompiled_code:
__int64 __fastcall handy_collection_save(_DWORD *a1, char *a2, int a3)
{
__int64 result; // rax

if ( a1 )
{
if ( *a1 )
{
if ( a3 == 3 )
result = handy_collection_save_binary(a1, a2);
else
result = 0LL;
}
else
{
verbose(
(char *)handy_allograph_load_binary + 1,
&locret_15B,
"src/handy_serialize.c",
"The number of allographs in the Collection is zero, save to disk has not effect");
result = 0LL;
}
}
else
{
verbose(
1LL,
350LL,
"src/handy_serialize.c",
"Collection has not been initiated, binary save to disk has not effect");
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func8(_DWORD *a1, char *a2, int a3)
{
__int64 result; // rax

if ( a1 )
{
if ( *a1 )
{
if ( a3 == 3 )
result = func7(a1, a2);
else
result = 0LL;
}
else
{
verbose(
(char *)handy_allograph_load_binary + 1,
&locret_15B,
"src/handy_serialize.c",
"The number of allographs in the Collection is zero, save to disk has not effect");
result = 0LL;
}
}
else
{
verbose(
1LL,
350LL,
"src/handy_serialize.c",
"Collection has not been initiated, binary save to disk has not effect");
result = 0LL;
}
return result;
}

original_code:
int handy_collection_save(handy_collection* collection, char* path, handy_serialize format) {
    if(collection != ((void *)0)) {
        if(collection->num_allographs > 0) {
            switch(format) {
                case HANDY_SERIALIZE_BINARY:
                    return handy_collection_save_binary(collection, path);
                    break;
            }
        } else {
            verbose(WARNING, 347, "src/handy_serialize.c", "The number of allographs in the Collection is zero, save to disk has not effect");
        }
    } else {
        verbose(WARNING, 350, "src/handy_serialize.c", "Collection has not been initiated, binary save to disk has not effect");
    }
    return 0;
}

canonical_original_code:
int handy_collection_save(struct handy_collection *collection, char *path, enum handy_serialize format) {
    if(collection != ((void *)0)) {
        if(collection->num_allographs > 0) {
            switch(format) {
                case HANDY_SERIALIZE_BINARY:
                    return handy_collection_save_binary(collection, path);
                    break;
            }
        } else {
            verbose(WARNING, 347, "src/handy_serialize.c", "The number of allographs in the Collection is zero, save to disk has not effect");
        }
    } else {
        verbose(WARNING, 350, "src/handy_serialize.c", "Collection has not been initiated, binary save to disk has not effect");
    }
    return 0;
}

variable_types: struct handy_collection { unsigned int num_allographs; struct handy_allograph { char symbol[512]; unsigned int num_points; struct handy_point { float x; } *points; } *allographs; } *


decompiled_code:
__int64 __fastcall handy_allograph_recognize_dtw(__int64 a1, unsigned int *a2, __int64 a3, double a4, double a5, double a6)
{
unsigned int v6; // er14
unsigned int v7; // er12
__int64 v8; // rbx
double v9; // xmm0_8
double v10; // xmm0_8
__int64 v11; // rbx
__int64 v13; // [rsp+8h] [rbp-40h]

v6 = *a2;
if ( *a2 )
{
v7 = 0;
v6 = 0;
v13 = a3 + 4;
LODWORD(a6) = LC0;
do
{
v8 = 528LL * v7;
v9 = handy_allograph_distance_dtw(a1, v8 + *((_QWORD *)a2 + 1), v13);
verbose(
0LL,
82LL,
"src/handy_recognize.c",
"Distance with element %s (number %d at collection): %f",
(const char *)(*((_QWORD *)a2 + 1) + v8),
v7,
*(float *)&v9);
*(_QWORD *)&a5 = LODWORD(v9);
*(float *)&a5 = fminf(*(float *)&v9, *(float *)&a6);
if ( *(float *)&a6 > *(float *)&v9 )
v6 = v7;
a6 = a5;
++v7;
}
while ( *a2 > v7 );
v10 = *(float *)&a5;
v11 = 528LL * v6;
}
else
{
v10 = *(double *)&LC1;
v11 = 0LL;
}
verbose(
0LL,
91LL,
"src/handy_recognize.c",
"Allograph recognized!!!, asigned symbol is: %s, distance %f, element %d at collection",
(const char *)(v11 + *((_QWORD *)a2 + 1)),
v10,
v6);
handy_allograph_set_symbol(a1, v11 + *((_QWORD *)a2 + 1), v10, a5, a6);
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, unsigned int *a2, __int64 a3, double a4, double a5, double a6)
{
unsigned int v6; // er14
unsigned int v7; // er12
__int64 v8; // rbx
double v9; // xmm0_8
double v10; // xmm0_8
__int64 v11; // rbx
__int64 v13; // [rsp+8h] [rbp-40h]

v6 = *a2;
if ( *a2 )
{
v7 = 0;
v6 = 0;
v13 = a3 + 4;
LODWORD(a6) = LC0;
do
{
v8 = 528LL * v7;
v9 = handy_allograph_distance_dtw(a1, v8 + *((_QWORD *)a2 + 1), v13);
verbose(
0LL,
82LL,
"src/handy_recognize.c",
"Distance with element %s (number %d at collection): %f",
(const char *)(*((_QWORD *)a2 + 1) + v8),
v7,
*(float *)&v9);
*(_QWORD *)&a5 = LODWORD(v9);
*(float *)&a5 = fminf(*(float *)&v9, *(float *)&a6);
if ( *(float *)&a6 > *(float *)&v9 )
v6 = v7;
a6 = a5;
++v7;
}
while ( *a2 > v7 );
v10 = *(float *)&a5;
v11 = 528LL * v6;
}
else
{
v10 = *(double *)&LC1;
v11 = 0LL;
}
verbose(
0LL,
91LL,
"src/handy_recognize.c",
"Allograph recognized!!!, asigned symbol is: %s, distance %f, element %d at collection",
(const char *)(v11 + *((_QWORD *)a2 + 1)),
v10,
v6);
handy_allograph_set_symbol(a1, v11 + *((_QWORD *)a2 + 1), v10, a5, a6);
return 1LL;
}

original_code:
int handy_allograph_recognize_dtw(handy_allograph* allograph, handy_collection* collection, handy_recognize_config* config) {
    handy_float temp_distance;
    handy_float distance = 1000000;
    handy_uint best_match = 0;
    handy_uint i = 0;
    for(i = 0; i < collection->num_allographs; i++) {
        temp_distance = handy_allograph_distance_dtw(allograph, &collection->allographs[i], &config->distance_config);
        verbose(INFO, 82, "src/handy_recognize.c", "Distance with element %s (number %d at collection): %f", collection->allographs[i].symbol, i, temp_distance);
        if(temp_distance < distance) {
            distance = temp_distance;
            best_match = i;
        }
    }
    verbose(INFO, 91, "src/handy_recognize.c", "Allograph recognized!!!, asigned symbol is: %s, distance %f, element %d at collection", collection->allographs[best_match].symbol, distance, best_match);
    handy_allograph_set_symbol(allograph, &collection->allographs[best_match].symbol[0]);
    return 1;
}

canonical_original_code:
int handy_allograph_recognize_dtw(struct handy_allograph *allograph, struct handy_collection *collection, struct handy_recognize_config *config) {
    float temp_distance;
    float distance = 1000000;
    unsigned int best_match = 0;
    unsigned int i = 0;
    for(i = 0; i < collection->num_allographs; i++) {
        temp_distance = handy_allograph_distance_dtw(allograph, &collection->allographs[i], &config->distance_config);
        verbose(INFO, 82, "src/handy_recognize.c", "Distance with element %s (number %d at collection): %f", collection->allographs[i].symbol, i, temp_distance);
        if(temp_distance < distance) {
            distance = temp_distance;
            best_match = i;
        }
    }
    verbose(INFO, 91, "src/handy_recognize.c", "Allograph recognized!!!, asigned symbol is: %s, distance %f, element %d at collection", collection->allographs[best_match].symbol, distance, best_match);
    handy_allograph_set_symbol(allograph, &collection->allographs[best_match].symbol[0]);
    return 1;
}

variable_types: struct handy_collection { unsigned int num_allographs; struct handy_allograph *allographs; } *

variable_types: struct handy_recognize_config { enum handy_recognize { HANDY_RECOGNIZE_DTW=0 } recognize; struct handy_distance_config { float c; _Bool boundary; _Bool monotonicity; _Bool symmetry; enum handy_distance { HANDY_DISTANCE_DTW=0, HANDY_DISTANCE_EUCLIDEAN=1 } distance; } distance_config; } *

variable_types: distance float

user_defined_types: struct handy_recognize_config { enum handy_recognize recognize; struct handy_distance_config distance_config; }

user_defined_types: struct handy_distance_config { float c; _Bool boundary; _Bool monotonicity; _Bool symmetry; enum handy_distance distance; }


decompiled_code:
__int64 __fastcall handy_allograph_recognize(__int64 a1, unsigned int *a2, _DWORD *a3, double a4, double a5, double a6)
{
__int64 result; // rax

if ( !a1 )
{
verbose(
2LL,
37LL,
"src/handy_recognize.c",
"Allograph to be recognized has not been initiated, recognition aborted");
return 0LL;
}
if ( *(_DWORD *)(a1 + 512) )
{
if ( !a2 )
{
verbose(
2LL,
48LL,
"src/handy_recognize.c",
"Collection used to recognize allograph has not been initiated, recognition aborted");
return 0LL;
}
if ( *a2 )
{
if ( *a3 )
{
verbose(
2LL,
67LL,
"src/handy_recognize.c",
"Not recognition method indicated at recognizer configuration, recognition aborted");
return 0LL;
}
result = handy_allograph_recognize_dtw(a1, a2, (__int64)a3, a4, a5, a6);
}
else
{
verbose(
2LL,
52LL,
"src/handy_recognize.c",
"Collection used to recognize allograph has no allographs inside, recognition aborted");
result = 0LL;
}
}
else
{
verbose(2LL, 41LL, "src/handy_recognize.c", "Allograph to be recognized has no points, recognition aborted");
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, unsigned int *a2, _DWORD *a3, double a4, double a5, double a6)
{
__int64 result; // rax

if ( !a1 )
{
verbose(
2LL,
37LL,
"src/handy_recognize.c",
"Allograph to be recognized has not been initiated, recognition aborted");
return 0LL;
}
if ( *(_DWORD *)(a1 + 512) )
{
if ( !a2 )
{
verbose(
2LL,
48LL,
"src/handy_recognize.c",
"Collection used to recognize allograph has not been initiated, recognition aborted");
return 0LL;
}
if ( *a2 )
{
if ( *a3 )
{
verbose(
2LL,
67LL,
"src/handy_recognize.c",
"Not recognition method indicated at recognizer configuration, recognition aborted");
return 0LL;
}
result = func0(a1, a2, (__int64)a3, a4, a5, a6);
}
else
{
verbose(
2LL,
52LL,
"src/handy_recognize.c",
"Collection used to recognize allograph has no allographs inside, recognition aborted");
result = 0LL;
}
}
else
{
verbose(2LL, 41LL, "src/handy_recognize.c", "Allograph to be recognized has no points, recognition aborted");
result = 0LL;
}
return result;
}

original_code:
int handy_allograph_recognize(handy_allograph* allograph, handy_collection* collection, handy_recognize_config* config) {
    if(allograph == ((void *)0)) {
        verbose(ERROR, 37, "src/handy_recognize.c", "Allograph to be recognized has not been initiated, recognition aborted");
        return 0;
    } else {
        if(allograph->num_points == 0) {
            verbose(ERROR, 41, "src/handy_recognize.c", "Allograph to be recognized has no points, recognition aborted");
            return 0;
        }
    }
    if(collection == ((void *)0)) {
        verbose(ERROR, 48, "src/handy_recognize.c", "Collection used to recognize allograph has not been initiated, recognition aborted");
        return 0;
    } else {
        if(collection->num_allographs == 0) {
            verbose(ERROR, 52, "src/handy_recognize.c", "Collection used to recognize allograph has no allographs inside, recognition aborted");
            return 0;
        }
    }
    switch(config->recognize) {
        case HANDY_RECOGNIZE_DTW:
            return handy_allograph_recognize_dtw(allograph, collection, config);
            break;
        default:
            verbose(ERROR, 67, "src/handy_recognize.c", "Not recognition method indicated at recognizer configuration, recognition aborted");
            return 0;
            break;
    }
}

canonical_original_code:
int handy_allograph_recognize(struct handy_allograph *allograph, struct handy_collection *collection, struct handy_recognize_config *config) {
    if(allograph == ((void *)0)) {
        verbose(ERROR, 37, "src/handy_recognize.c", "Allograph to be recognized has not been initiated, recognition aborted");
        return 0;
    } else {
        if(allograph->num_points == 0) {
            verbose(ERROR, 41, "src/handy_recognize.c", "Allograph to be recognized has no points, recognition aborted");
            return 0;
        }
    }
    if(collection == ((void *)0)) {
        verbose(ERROR, 48, "src/handy_recognize.c", "Collection used to recognize allograph has not been initiated, recognition aborted");
        return 0;
    } else {
        if(collection->num_allographs == 0) {
            verbose(ERROR, 52, "src/handy_recognize.c", "Collection used to recognize allograph has no allographs inside, recognition aborted");
            return 0;
        }
    }
    switch(config->recognize) {
        case HANDY_RECOGNIZE_DTW:
            return handy_allograph_recognize_dtw(allograph, collection, config);
            break;
        default:
            verbose(ERROR, 67, "src/handy_recognize.c", "Not recognition method indicated at recognizer configuration, recognition aborted");
            return 0;
            break;
    }
}

variable_types: struct handy_allograph { char symbol[512]; unsigned int num_points; struct handy_point { float x; } *points; } *

user_defined_types: enum handy_recognize { HANDY_RECOGNIZE_DTW=0 }

user_defined_types: enum handy_distance { HANDY_DISTANCE_DTW=0, HANDY_DISTANCE_EUCLIDEAN=1 }


main

canonical_name: main

repo: jfenderico/fs-activity-notifier

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // rbp
int result; // eax
__int64 v5[2]; // [rsp+0h] [rbp-38h] BYREF
__int64 v6[5]; // [rsp+10h] [rbp-28h] BYREF

v3 = (char *)argv[1];
v6[0] = (__int64)"topo@test.com";
v6[1] = (__int64)"user@test.com";
v6[2] = (__int64)"fs activity notification";
v5[0] = (__int64)send_email;
v5[1] = (__int64)v6;
if ( v3 || (v3 = getcwd(0LL, 0LL)) != 0LL )
{
printf("working_dir: %s\n", v3);
dir_add_monitors(v3, 0LL, 768LL, v5);
free(v3);
result = 0;
}
else
{
perror("getcwd()");
result = -2;
}
return result;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *v3; // rbp
int result; // eax
__int64 v5[2]; // [rsp+0h] [rbp-38h] BYREF
__int64 v6[5]; // [rsp+10h] [rbp-28h] BYREF

v3 = (char *)argv[1];
v6[0] = (__int64)"topo@test.com";
v6[1] = (__int64)"user@test.com";
v6[2] = (__int64)"fs activity notification";
v5[0] = (__int64)send_email;
v5[1] = (__int64)v6;
if ( v3 || (v3 = getcwd(0LL, 0LL)) != 0LL )
{
printf("working_dir: %s\n", v3);
func10(v3, 0LL, 768LL, v5);
free(v3);
result = 0;
}
else
{
perror("getcwd()");
result = -2;
}
return result;
}

original_code:
int main(int argc, char **argv)
{
 char *working_dir = ((void *)0);
 struct dirent **namelist;
 notifier_param_t notif_param = {
  .from = "topo@test.com",
  .to = "user@test.com",
  .subject = "fs activity notification"
 };
 notifier_t notifier = {
  .oper = _send_email,
  .param = &notif_param
 };
 working_dir = argv[1] ? argv[1] : getcwd(((void *)0), 0);
 if (working_dir == ((void *)0)) {
  perror("getcwd()");
  return -2;
 }
 printf("working_dir: %s\n", working_dir);
 dir_add_monitors(working_dir, namelist, 0x00000100 | 0x00000200, &notifier);
 if (working_dir) free(working_dir);
 return 0;
}

canonical_original_code:
int main(int argc, char **argv)
{
 char *working_dir = ((void *)0);
 struct dirent **namelist;
 struct notifier_param_t notif_param = {
  .from = "topo@test.com",
  .to = "user@test.com",
  .subject = "fs activity notification"
 };
 struct notifier_t notifier = {
  .oper = _send_email,
  .param = &notif_param
 };
 working_dir = argv[1] ? argv[1] : getcwd(((void *)0), 0);
 if (working_dir == ((void *)0)) {
  perror("getcwd()");
  return -2;
 }
 printf("working_dir: %s\n", working_dir);
 dir_add_monitors(working_dir, namelist, 0x00000100 | 0x00000200, &notifier);
 if (working_dir) free(working_dir);
 return 0;
}

variable_types: argc int

variable_types:
argv
char **

variable_types: struct dirent { unsigned long d_ino; long d_off; unsigned short d_reclen; unsigned char d_type; char d_name[256]; } **

variable_types: struct notifier_t { int (*oper)(char *msg, struct notifier_param_t { char *from; char *to; char *subject; } *p); struct notifier_param_t *param; }

user_defined_types: struct notifier_t { int (*oper)(char *msg, struct notifier_param_t *p); struct notifier_param_t *param; }


decompiled_code:
_BOOL8 __fastcall filter_dir(const struct dirent *a1)
{
_BOOL8 result; // rax

result = 0LL;
if ( a1->d_name[0] != 46 )
result = a1->d_type == 4;
return result;
}

canonical_decompiled_code:
_BOOL8 __fastcall func8(const struct dirent *a1)
{
_BOOL8 result; // rax

result = 0LL;
if ( a1->d_name[0] != 46 )
result = a1->d_type == 4;
return result;
}

original_code:
static int filter_dir(const struct dirent *e)
{
 if (strncmp(e->d_name, ".", 1) == 0)
  return 0;
 if (e->d_type == DT_DIR)
  return 1;
 return 0;
}

canonical_original_code:
static int filter_dir(struct dirent *e)
{
 if (strncmp(e->d_name, ".", 1) == 0)
  return 0;
 if (e->d_type == DT_DIR)
  return 1;
 return 0;
}

variable_types: struct dirent { unsigned long d_ino; long d_off; unsigned short d_reclen; unsigned char d_type; char d_name[256]; } *


decompiled_code:
void __fastcall create_monitor(pthread_t *newthread, char *src, int a3, __int64 a4)
{
void *v6; // rax
_QWORD *v7; // r12

v6 = malloc(0x110uLL);
if ( v6 )
{
*(_DWORD *)v6 = a3;
v7 = v6;
strncpy((char *)v6 + 4, src, 0x100uLL);
v7[33] = a4;
pthread_create(newthread, 0LL, monitor, v7);
}
else
{
perror("malloc()");
}
}

canonical_decompiled_code:
void __fastcall func9(pthread_t *newthread, char *src, int a3, __int64 a4)
{
void *v6; // rax
_QWORD *v7; // r12

v6 = malloc(0x110uLL);
if ( v6 )
{
*(_DWORD *)v6 = a3;
v7 = v6;
strncpy((char *)v6 + 4, src, 0x100uLL);
v7[33] = a4;
pthread_create(newthread, 0LL, monitor, v7);
}
else
{
perror("malloc()");
}
}

original_code:
static void create_monitor(pthread_t *tid, char *dir_path, int flags,
 notifier_t *notifier)
{
 mon_params_t *m_param;
 if ((m_param = malloc(sizeof *m_param)) == ((void *)0)) {
  perror("malloc()");
  return;
 }
 m_param->flags = flags;
 strncpy(m_param->dir_path, dir_path, sizeof m_param->dir_path);
 m_param->notifier = notifier;
 pthread_create(tid, ((void *)0), monitor, (void *)m_param);
}

canonical_original_code:
static void create_monitor(unsigned long *tid, char *dir_path, int flags, struct notifier_t *notifier)
{
 struct mon_params *m_param;
 if ((m_param = malloc(sizeof *m_param)) == ((void *)0)) {
  perror("malloc()");
  return;
 }
 m_param->flags = flags;
 strncpy(m_param->dir_path, dir_path, sizeof m_param->dir_path);
 m_param->notifier = notifier;
 pthread_create(tid, ((void *)0), monitor, (void *)m_param);
}

variable_types:
tid
unsigned long *

variable_types: flags int

variable_types: struct mon_params { int flags; char dir_path[256]; struct notifier_t { int (*oper)(char *msg, struct notifier_param_t { char *from; char *to; char *subject; } *p); struct notifier_param_t *param; } *notifier; } *

return_type: void

user_defined_types: struct mon_params { int flags; char dir_path[256]; struct notifier_t *notifier; }


decompiled_code:
__int64 __fastcall dir_add_monitors(char *a1, struct dirent **a2, unsigned int a3, __int64 a4)
{
unsigned int v4; // er12
int v9; // eax
unsigned int v10; // ebx
__int64 v11; // r12
struct dirent *v12; // rdi
pthread_t *v13; // rdi
int v14; // ebx
int v15; // edx
int v16; // eax
pthread_t *v17; // rdi
char *v18; // [rsp+0h] [rbp-148h]
struct dirent **namelist; // [rsp+8h] [rbp-140h] BYREF
char s[312]; // [rsp+10h] [rbp-138h] BYREF

namelist = a2;
if ( rec_depth_3 <= 0 )
{
++rec_depth_3;
memset(s, 0, 0x100uLL);
memset(tid_2, 0, sizeof(tid_2));
v9 = scandir(a1, &namelist, (int (*)(const struct dirent *))filter_dir, alphasort);
v4 = v9;
if ( v9 < 0 )
{
v4 = -1;
perror("scandir");
}
else
{
printf("ndirs: %d\n", (unsigned int)v9);
printf("tidx: %d\n", (unsigned int)tidx_1);
if ( v4 )
{
++rec_count_0;
v10 = v4 - 1;
v11 = (int)(v4 - 1);
do
{
v18 = namelist[v11]->d_name;
printf("(%d) %s/%s\n", v10, a1, v18);
snprintf(s, 0x100uLL, "%s/%s", a1, v18);
dir_add_monitors(s, namelist, a3, a4);
v12 = namelist[v11];
if ( v12 )
free(v12);
--v10;
--v11;
v13 = &tid_2[tidx_1++];
create_monitor(v13, s, a3, a4);
}
while ( v10 != -1 );
v14 = --rec_count_0;
if ( namelist )
free(namelist);
if ( v14 )
{
v4 = 0;
}
else
{
while ( 1 )
{
v15 = tidx_1;
v16 = --tidx_1;
if ( !v15 )
break;
pthread_join(tid_2[v16], 0LL);
}
v4 = 0;
}
}
else
{
v17 = &tid_2[tidx_1++];
create_monitor(v17, a1, a3, a4);
}
}
}
else
{
v4 = 0;
--rec_depth_3;
}
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func10(char *a1, struct dirent **a2, unsigned int a3, __int64 a4)
{
unsigned int v4; // er12
int v9; // eax
unsigned int v10; // ebx
__int64 v11; // r12
struct dirent *v12; // rdi
pthread_t *v13; // rdi
int v14; // ebx
int v15; // edx
int v16; // eax
pthread_t *v17; // rdi
char *v18; // [rsp+0h] [rbp-148h]
struct dirent **namelist; // [rsp+8h] [rbp-140h] BYREF
char s[312]; // [rsp+10h] [rbp-138h] BYREF

namelist = a2;
if ( rec_depth_3 <= 0 )
{
++rec_depth_3;
memset(s, 0, 0x100uLL);
memset(tid_2, 0, sizeof(tid_2));
v9 = scandir(a1, &namelist, (int (*)(const struct dirent *))filter_dir, alphasort);
v4 = v9;
if ( v9 < 0 )
{
v4 = -1;
perror("scandir");
}
else
{
printf("ndirs: %d\n", (unsigned int)v9);
printf("tidx: %d\n", (unsigned int)tidx_1);
if ( v4 )
{
++rec_count_0;
v10 = v4 - 1;
v11 = (int)(v4 - 1);
do
{
v18 = namelist[v11]->d_name;
printf("(%d) %s/%s\n", v10, a1, v18);
snprintf(s, 0x100uLL, "%s/%s", a1, v18);
func10(s, namelist, a3, a4);
v12 = namelist[v11];
if ( v12 )
free(v12);
--v10;
--v11;
v13 = &tid_2[tidx_1++];
func9(v13, s, a3, a4);
}
while ( v10 != -1 );
v14 = --rec_count_0;
if ( namelist )
free(namelist);
if ( v14 )
{
v4 = 0;
}
else
{
while ( 1 )
{
v15 = tidx_1;
v16 = --tidx_1;
if ( !v15 )
break;
pthread_join(tid_2[v16], 0LL);
}
v4 = 0;
}
}
else
{
v17 = &tid_2[tidx_1++];
func9(v17, a1, a3, a4);
}
}
}
else
{
v4 = 0;
--rec_depth_3;
}
return v4;
}

original_code:
int dir_add_monitors(char *path, struct dirent **namelist, int flags,
    notifier_t *notifier)
{
 static int rec_depth = 0;
 static int rec_count = 0;
 char dir_path[256];
 char *dir_name;
 int ndirs;
 static int tidx = 0;
 static pthread_t tid[64];
 int i;
 if (rec_depth >= 1) {
  --rec_depth;
  return 0;
 }
 ++rec_depth;
 memset(dir_path, 0, sizeof dir_path);
 memset(tid, 0, sizeof tid);
 ndirs = scandir(path, &namelist, filter_dir, alphasort);
 if (ndirs < 0) {
  perror("scandir");
  return -1;
 }
 printf("ndirs: %d\n", ndirs);
 printf("tidx: %d\n", tidx);
 if (ndirs == 0) {
  create_monitor(&tid[tidx++], path, flags, notifier);
  return 0;
 }
 rec_count++;
 while (ndirs--) {
  dir_name = namelist[ndirs]->d_name;
  printf("(%d) %s/%s\n", ndirs, path, dir_name);
  snprintf(dir_path, sizeof dir_path, "%s/%s", path, dir_name);
  dir_add_monitors(dir_path, namelist, flags, notifier);
  if (namelist[ndirs]) free(namelist[ndirs]);
  create_monitor(&tid[tidx++], dir_path, flags, notifier);
 }
 rec_count--;
 if (namelist) free(namelist);
 if (rec_count == 0) {
  while (tidx--) {
   pthread_join(tid[tidx], ((void *)0));
  }
 }
 return 0;
}

canonical_original_code:
int dir_add_monitors(char *path, struct dirent **namelist, int flags, struct notifier_t *notifier)
{
 static int rec_depth = 0;
 static int rec_count = 0;
 char dir_path[256];
 char *dir_name;
 int ndirs;
 static int tidx = 0;
 static unsigned long tid[64];
 int i;
 if (rec_depth >= 1) {
  --rec_depth;
  return 0;
 }
 ++rec_depth;
 memset(dir_path, 0, sizeof dir_path);
 memset(tid, 0, sizeof tid);
 ndirs = scandir(path, &namelist, filter_dir, alphasort);
 if (ndirs < 0) {
  perror("scandir");
  return -1;
 }
 printf("ndirs: %d\n", ndirs);
 printf("tidx: %d\n", tidx);
 if (ndirs == 0) {
  create_monitor(&tid[tidx++], path, flags, notifier);
  return 0;
 }
 rec_count++;
 while (ndirs--) {
  dir_name = namelist[ndirs]->d_name;
  printf("(%d) %s/%s\n", ndirs, path, dir_name);
  snprintf(dir_path, sizeof dir_path, "%s/%s", path, dir_name);
  dir_add_monitors(dir_path, namelist, flags, notifier);
  if (namelist[ndirs]) free(namelist[ndirs]);
  create_monitor(&tid[tidx++], dir_path, flags, notifier);
 }
 rec_count--;
 if (namelist) free(namelist);
 if (rec_count == 0) {
  while (tidx--) {
   pthread_join(tid[tidx], ((void *)0));
  }
 }
 return 0;
}

variable_types: struct notifier_t { int (*oper)(char *msg, struct notifier_param_t { char *from; char *to; char *subject; } *p); struct notifier_param_t *param; } *

variable_types: ndirs int

variable_types: tidx int

variable_types:
tid
unsigned long [64]

variable_types: i int

user_defined_types: struct dirent { unsigned long d_ino; long d_off; unsigned short d_reclen; unsigned char d_type; char d_name[256]; }


monitor

decompiled_code:
void __fastcall __noreturn monitor(void *a1)
{
__int64 v1; // rbp
int v2; // er12
pthread_t v3; // rax
int v4; // er14
int i; // er15
char *v6; // rbx
int v7; // edx
int v8; // eax
int wd; // [rsp+Ch] [rbp-1803Ch]
char s[98360]; // [rsp+10h] [rbp-18038h] BYREF

v1 = *((_QWORD *)a1 + 33);
v2 = inotify_init();
if ( v2 < 0 )
{
perror("inotify_init");
}
else
{
v3 = pthread_self();
printf("tid: %ld\n", v3);
printf("path: %s\n", (const char *)a1 + 4);
printf("fd: %d\n", (unsigned int)v2);
printf("flags: %d\n", *(unsigned int *)a1);
memset(s, 0, 0x18000uLL);
wd = inotify_add_watch(v2, (const char *)a1 + 4, *(_DWORD *)a1);
if ( wd < 0 )
{
perror("inotify_add_watch");
}
else
{
while ( 1 )
{
v4 = read(v2, s, 0x18000uLL);
if ( v4 <= 0 )
break;
for ( i = 0; i < v4; i += v8 + 16 )
{
v6 = &s[i];
v8 = *((_DWORD *)v6 + 3);
if ( v8 )
{
v7 = *((_DWORD *)v6 + 1);
switch ( v7 )
{
case 256:
printf("file created ...");
(*(void (__fastcall **)(const char *, _QWORD))v1)("file created", *(_QWORD *)(v1 + 8));
v8 = *((_DWORD *)v6 + 3);
break;
case 512:
printf("file deleted ...");
(*(void (__fastcall **)(const char *, _QWORD))v1)("file deleted", *(_QWORD *)(v1 + 8));
v8 = *((_DWORD *)v6 + 3);
break;
case 32:
printf("The file %s was opened.\n", v6 + 16);
v8 = *((_DWORD *)v6 + 3);
break;
}
}
}
}
inotify_rm_watch(v2, wd);
}
}
free(a1);
close(v2);
pthread_exit(0LL);
}

canonical_decompiled_code:
void __fastcall __noreturn func11(void *a1)
{
__int64 v1; // rbp
int v2; // er12
pthread_t v3; // rax
int v4; // er14
int i; // er15
char *v6; // rbx
int v7; // edx
int v8; // eax
int wd; // [rsp+Ch] [rbp-1803Ch]
char s[98360]; // [rsp+10h] [rbp-18038h] BYREF

v1 = *((_QWORD *)a1 + 33);
v2 = inotify_init();
if ( v2 < 0 )
{
perror("inotify_init");
}
else
{
v3 = pthread_self();
printf("tid: %ld\n", v3);
printf("path: %s\n", (const char *)a1 + 4);
printf("fd: %d\n", (unsigned int)v2);
printf("flags: %d\n", *(unsigned int *)a1);
memset(s, 0, 0x18000uLL);
wd = inotify_add_watch(v2, (const char *)a1 + 4, *(_DWORD *)a1);
if ( wd < 0 )
{
perror("inotify_add_watch");
}
else
{
while ( 1 )
{
v4 = read(v2, s, 0x18000uLL);
if ( v4 <= 0 )
break;
for ( i = 0; i < v4; i += v8 + 16 )
{
v6 = &s[i];
v8 = *((_DWORD *)v6 + 3);
if ( v8 )
{
v7 = *((_DWORD *)v6 + 1);
switch ( v7 )
{
case 256:
printf("file created ...");
(*(void (__fastcall **)(const char *, _QWORD))v1)("file created", *(_QWORD *)(v1 + 8));
v8 = *((_DWORD *)v6 + 3);
break;
case 512:
printf("file deleted ...");
(*(void (__fastcall **)(const char *, _QWORD))v1)("file deleted", *(_QWORD *)(v1 + 8));
v8 = *((_DWORD *)v6 + 3);
break;
case 32:
printf("The file %s was opened.\n", v6 + 16);
v8 = *((_DWORD *)v6 + 3);
break;
}
}
}
}
inotify_rm_watch(v2, wd);
}
}
free(a1);
close(v2);
pthread_exit(0LL);
}

original_code:
void *monitor(void *arg)
{
 mon_params_t *mon_param = (mon_params_t *)arg;
 int wd;
 int fd;
 struct inotify_event *event;
 char buffer[(1024 * ((sizeof (struct inotify_event)) + 80))];
 int nevents = 0;
 int i;
 notifier_t *notifier = mon_param->notifier;
 if ((fd = inotify_init()) < 0) {
  perror("inotify_init");
  goto err;
 }
 printf("tid: %ld\n", pthread_self());
 printf("path: %s\n", mon_param->dir_path);
 printf("fd: %d\n", fd);
 printf("flags: %d\n", mon_param->flags);
 memset(buffer, 0, sizeof buffer);
 if ((wd = inotify_add_watch(fd, mon_param->dir_path, mon_param->flags)) < 0) {
  perror("inotify_add_watch");
  goto err;
 }
 while ((nevents = read(fd, buffer, sizeof buffer)) > 0) {
  for (i = 0; i < nevents; i += (sizeof (struct inotify_event)) + event->len) {
   event = (struct inotify_event *) &buffer[i];
   if (event->len) {
    switch (event->mask) {
    case 0x00000100:
     printf("file created ...");
     notifier->oper("file created", notifier->param);
     break;
    case 0x00000020:
     printf("The file %s was opened.\n", event->name);
     break;
    case 0x00000200:
     printf("file deleted ...");
     notifier->oper("file deleted", notifier->param);
     break;
    }
   }
  }
 }
 inotify_rm_watch(fd, wd);
err:
 if (arg) free(arg);
 close(fd);
 pthread_exit(((void *)0));
}

canonical_original_code:
void *monitor(void *arg)
{
 struct mon_params *mon_param = (mon_params_t *)arg;
 int wd;
 int fd;
 struct inotify_event *event;
 char buffer[-1];
 int nevents = 0;
 int i;
 struct notifier_t *notifier = mon_param->notifier;
 if ((fd = inotify_init()) < 0) {
  perror("inotify_init");
  goto err;
 }
 printf("tid: %ld\n", pthread_self());
 printf("path: %s\n", mon_param->dir_path);
 printf("fd: %d\n", fd);
 printf("flags: %d\n", mon_param->flags);
 memset(buffer, 0, sizeof buffer);
 if ((wd = inotify_add_watch(fd, mon_param->dir_path, mon_param->flags)) < 0) {
  perror("inotify_add_watch");
  goto err;
 }
 while ((nevents = read(fd, buffer, sizeof buffer)) > 0) {
  for (i = 0; i < nevents; i += (sizeof (struct inotify_event)) + event->len) {
   event = (struct inotify_event *) &buffer[i];
   if (event->len) {
    switch (event->mask) {
    case 0x00000100:
     printf("file created ...");
     notifier->oper("file created", notifier->param);
     break;
    case 0x00000020:
     printf("The file %s was opened.\n", event->name);
     break;
    case 0x00000200:
     printf("file deleted ...");
     notifier->oper("file deleted", notifier->param);
     break;
    }
   }
  }
 }
 inotify_rm_watch(fd, wd);
err:
 if (arg) free(arg);
 close(fd);
 pthread_exit(((void *)0));
}

variable_types:
arg
void *

variable_types: wd int

variable_types: fd int

variable_types: struct inotify_event { int wd; unsigned int mask; unsigned int cookie; unsigned int len; char name[]; } *

variable_types:
buffer
char [-1]

variable_types: nevents int

return_type: void *

user_defined_types: struct notifier_param_t { char *from; char *to; char *subject; }


repo: jff/mathspad

original_code:
static int read_integer_short(char **txt)
{
    int n=0;
    int neg=0;
    if (**txt=='-') { neg=1; (*txt)++;}
    while (((*__ctype_b_loc ())[(int) ((**txt))] & (unsigned short int) _ISdigit)) {
 n=n*10+ (**txt)-'0';
 (*txt)++;
    }
    return (neg? -n:n);
}

canonical_original_code:
static int read_integer_short(char **txt)
{
    int n = 0;
    int neg = 0;
    if (**txt=='-') { neg=1; (*txt)++;}
    while (((*__ctype_b_loc ())[(int) ((**txt))] & (unsigned short) _ISdigit)) {
 n=n*10+ (**txt)-'0';
 (*txt)++;
    }
    return (neg? -n:n);
}

variable_types:
txt
char **

variable_types: n int

variable_types: neg int


decompiled_code:
__int64 __fastcall read_integer(char **a1)
{
unsigned int v1; // er12
const unsigned __int16 *v2; // rcx
char *i; // rax
__int64 v4; // rdx

v1 = read_integer_short(a1);
v2 = *_ctype_b_loc();
for ( i = *a1; ; *a1 = i )
{
v4 = *i++;
if ( (v2[v4] & 0x2000) == 0 )
break;
}
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func1(char **a1)
{
unsigned int v1; // er12
const unsigned __int16 *v2; // rcx
char *i; // rax
__int64 v4; // rdx

v1 = func0(a1);
v2 = *_ctype_b_loc();
for ( i = *a1; ; *a1 = i )
{
v4 = *i++;
if ( (v2[v4] & 0x2000) == 0 )
break;
}
return v1;
}

original_code:
static int read_integer(char **txt)
{
    int n=read_integer_short(txt);
    while (((*__ctype_b_loc ())[(int) ((**txt))] & (unsigned short int) _ISspace)) (*txt)++;
    return n;
}

canonical_original_code:
static int read_integer(char **txt)
{
    int n = read_integer_short(txt);
    while (((*__ctype_b_loc ())[(int) ((**txt))] & (unsigned short) _ISspace)) (*txt)++;
    return n;
}


decompiled_code:
__int64 __fastcall new_fontfile(int a1, __int64 a2)
{
return (a1 > 100) & (unsigned __int8)(a2 == 0);
}

canonical_decompiled_code:
__int64 __fastcall func5(int a1, __int64 a2)
{
return (a1 > 100) & (unsigned __int8)(a2 == 0);
}

original_code:
int new_fontfile(int nr, Uchar *newname)
{
  return (nr>100 && !newname);
}

canonical_original_code:
int new_fontfile(int nr, unsigned short *newname)
{
  return (nr>100 && !newname);
}

variable_types: nr int

variable_types:
newname
unsigned short *


decompiled_code:
__int64 __fastcall char_width(unsigned __int16 a1)
{
__int64 v1; // rax
unsigned int v2; // er8

v1 = character_info(a1);
v2 = 0;
if ( v1 )
v2 = *(__int16 *)(*(_QWORD *)(v1 + 16) + 4LL);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func6(unsigned __int16 a1)
{
__int64 v1; // rax
unsigned int v2; // er8

v1 = character_info(a1);
v2 = 0;
if ( v1 )
v2 = *(__int16 *)(*(_QWORD *)(v1 + 16) + 4LL);
return v2;
}

original_code:
int char_width(Uchar data)
{
  CharInfo *ci;
  ci = character_info(data);
  if (ci) return ((ci->sysinfo)->width);
  else return 0;
}

canonical_original_code:
int char_width(unsigned short data)
{
  struct CharInfo *ci;
  ci = character_info(data);
  if (ci) return ((ci->sysinfo)->width);
  else return 0;
}

variable_types:
data
unsigned short

variable_types: struct CharInfo { unsigned long font; int pos; struct XCharStruct { short lbearing; short rbearing; short width; short ascent; short descent; unsigned short attributes; } *sysinfo; } *

user_defined_types: struct CharInfo { unsigned long font; int pos; struct XCharStruct *sysinfo; }


decompiled_code:
__int64 __fastcall push_attributes(unsigned int a1)
{
unsigned int v1; // ebp
unsigned int v2; // eax
int v3; // eax

if ( a1 > 4 )
v1 = font_get_attributes();
else
v1 = fontattributes[a1];
v2 = font_get_attributes();
push_int(&font_stack, v2);
font_set_attributes(v1);
v3 = char_width(0x6Eu);
return setsimpletabsize((unsigned int)(8 * v3));
}

canonical_decompiled_code:
__int64 __fastcall func7(unsigned int a1)
{
unsigned int v1; // ebp
unsigned int v2; // eax
int v3; // eax

if ( a1 > 4 )
v1 = font_get_attributes();
else
v1 = fontattributes[a1];
v2 = font_get_attributes();
push_int(&font_stack, v2);
font_set_attributes(v1);
v3 = func6(0x6Eu);
return setsimpletabsize((unsigned int)(8 * v3));
}

original_code:
void push_attributes(int nr)
{
    int i;
    i = (nr<0||nr>4 ? font_get_attributes() : fontattributes[nr]);
    push_int(&font_stack, font_get_attributes());
    font_set_attributes(i);
    setsimpletabsize(8*char_width('n'));
}


decompiled_code:
__int64 pop_attributes()
{
unsigned int v0; // ebp
int v1; // eax

v0 = 0;
if ( font_stack )
v0 = *(_DWORD *)(font_stack + 8);
pop_int(&font_stack);
font_set_attributes(v0);
v1 = char_width(0x6Eu);
return setsimpletabsize((unsigned int)(8 * v1));
}

canonical_decompiled_code:
__int64 func8()
{
unsigned int v0; // ebp
int v1; // eax

v0 = 0;
if ( font_stack )
v0 = *(_DWORD *)(font_stack + 8);
pop_int(&font_stack);
font_set_attributes(v0);
v1 = func6(0x6Eu);
return setsimpletabsize((unsigned int)(8 * v1));
}

original_code:
void pop_attributes(void)
{
    int i;
    i = ((font_stack)? (font_stack)->nr : 0);
    pop_int(&font_stack);
    font_set_attributes(i);
    setsimpletabsize(8*char_width('n'));
}

canonical_original_code:
void pop_attributes()
{
    int i;
    i = ((font_stack)? (font_stack)->nr : 0);
    pop_int(&font_stack);
    font_set_attributes(i);
    setsimpletabsize(8*char_width('n'));
}


decompiled_code:
__int64 font_width()
{
return char_width(0x57u);
}

canonical_decompiled_code:
__int64 func9()
{
return func6(0x57u);
}

original_code:
short font_width(void)
{
    return char_width('W');
}

canonical_original_code:
short font_width()
{
    return char_width('W');
}

return_type: short


decompiled_code:
__int64 __fastcall char_ascent(unsigned __int16 a1)
{
__int64 v1; // rax
unsigned int v2; // er8

v1 = character_info(a1);
v2 = 0;
if ( v1 )
v2 = *(__int16 *)(*(_QWORD *)(v1 + 16) + 6LL);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func10(unsigned __int16 a1)
{
__int64 v1; // rax
unsigned int v2; // er8

v1 = character_info(a1);
v2 = 0;
if ( v1 )
v2 = *(__int16 *)(*(_QWORD *)(v1 + 16) + 6LL);
return v2;
}

original_code:
int char_ascent(Uchar data)
{
  CharInfo *ci;
  ci = character_info(data);
  if (ci) return ((ci->sysinfo)->ascent);
  else return 0;
}

canonical_original_code:
int char_ascent(unsigned short data)
{
  struct CharInfo *ci;
  ci = character_info(data);
  if (ci) return ((ci->sysinfo)->ascent);
  else return 0;
}

user_defined_types: struct XCharStruct { short lbearing; short rbearing; short width; short ascent; short descent; unsigned short attributes; }


decompiled_code:
__int64 font_ascent()
{
return (unsigned int)((int)(12 * char_ascent(0x48u) + 5) / 10);
}

original_code:
int font_ascent(void)
{
    return (char_ascent('H')*12+5)/10;
}

canonical_original_code:
int font_ascent()
{
    return (char_ascent('H')*12+5)/10;
}


decompiled_code:
__int64 __fastcall char_descent(unsigned __int16 a1)
{
__int64 v1; // rax
unsigned int v2; // er8

v1 = character_info(a1);
v2 = 0;
if ( v1 )
v2 = *(__int16 *)(*(_QWORD *)(v1 + 16) + 8LL);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func12(unsigned __int16 a1)
{
__int64 v1; // rax
unsigned int v2; // er8

v1 = character_info(a1);
v2 = 0;
if ( v1 )
v2 = *(__int16 *)(*(_QWORD *)(v1 + 16) + 8LL);
return v2;
}

original_code:
int char_descent(Uchar data)
{
  CharInfo *ci;
  ci = character_info(data);
  if (ci) return ((ci->sysinfo)->descent);
  else return 0;
}

canonical_original_code:
int char_descent(unsigned short data)
{
  struct CharInfo *ci;
  ci = character_info(data);
  if (ci) return ((ci->sysinfo)->descent);
  else return 0;
}


decompiled_code:
__int64 font_descent()
{
return (unsigned int)((int)(12 * char_descent(0x67u) + 5) / 10);
}

original_code:
int font_descent(void)
{
    return (char_descent('g')*12+5)/10;
}

canonical_original_code:
int font_descent()
{
    return (char_descent('g')*12+5)/10;
}


decompiled_code:
__int64 font_height()
{
int v0; // ebx

v0 = font_ascent();
return v0 + (unsigned int)font_descent();
}

canonical_decompiled_code:
__int64 func14()
{
int v0; // ebx

v0 = func11();
return v0 + (unsigned int)func13();
}

original_code:
int font_height(void)
{
  return font_ascent()+font_descent();
}

canonical_original_code:
int font_height()
{
  return font_ascent()+font_descent();
}


decompiled_code:
__int64 __fastcall char_left(unsigned __int16 a1)
{
__int64 v1; // rax
unsigned int v2; // er8

v1 = character_info(a1);
v2 = 0;
if ( v1 )
v2 = **(__int16 **)(v1 + 16);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func15(unsigned __int16 a1)
{
__int64 v1; // rax
unsigned int v2; // er8

v1 = character_info(a1);
v2 = 0;
if ( v1 )
v2 = **(__int16 **)(v1 + 16);
return v2;
}

original_code:
int char_left(Uchar data)
{
  CharInfo *ci;
  ci = character_info(data);
  if (ci) return ((ci->sysinfo)->lbearing);
  else return 0;
}

canonical_original_code:
int char_left(unsigned short data)
{
  struct CharInfo *ci;
  ci = character_info(data);
  if (ci) return ((ci->sysinfo)->lbearing);
  else return 0;
}


decompiled_code:
__int64 __fastcall char_right(unsigned __int16 a1)
{
__int64 v1; // rax
unsigned int v2; // er8

v1 = character_info(a1);
v2 = 0;
if ( v1 )
v2 = *(__int16 *)(*(_QWORD *)(v1 + 16) + 2LL);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func16(unsigned __int16 a1)
{
__int64 v1; // rax
unsigned int v2; // er8

v1 = character_info(a1);
v2 = 0;
if ( v1 )
v2 = *(__int16 *)(*(_QWORD *)(v1 + 16) + 2LL);
return v2;
}

original_code:
int char_right(Uchar data)
{
  CharInfo *ci;
  ci = character_info(data);
  if (ci) return ((ci->sysinfo)->rbearing);
  else return 0;
}

canonical_original_code:
int char_right(unsigned short data)
{
  struct CharInfo *ci;
  ci = character_info(data);
  if (ci) return ((ci->sysinfo)->rbearing);
  else return 0;
}


decompiled_code:
__int64 __fastcall string_width(unsigned __int16 *a1, int a2)
{
unsigned __int16 *v2; // rbx
unsigned int v3; // er12
unsigned __int16 *v4; // rbp
unsigned __int16 v5; // di

if ( !a2 )
return 0;
v2 = a1;
v3 = 0;
v4 = &a1[a2];
do
{
v5 = *v2;
if ( !*v2 )
break;
++v2;
v3 += char_width(v5);
}
while ( v2 != v4 );
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func17(unsigned __int16 *a1, int a2)
{
unsigned __int16 *v2; // rbx
unsigned int v3; // er12
unsigned __int16 *v4; // rbp
unsigned __int16 v5; // di

if ( !a2 )
return 0;
v2 = a1;
v3 = 0;
v4 = &a1[a2];
do
{
v5 = *v2;
if ( !*v2 )
break;
++v2;
v3 += func6(v5);
}
while ( v2 != v4 );
return v3;
}

original_code:
int string_width(Uchar *string, int nr)
{
    int w;
    w=0;
    while (nr && *string) {
      w=w+char_width(*string);
      string++;
      nr--;
    }
    return w;
}

canonical_original_code:
int string_width(unsigned short *string, int nr)
{
    int w;
    w=0;
    while (nr && *string) {
      w=w+char_width(*string);
      string++;
      nr--;
    }
    return w;
}

variable_types:
string
unsigned short *

variable_types: w int


decompiled_code:
__int64 __fastcall get_operator(int a1, int a2, int a3)
{
__int64 v3; // r8
int v6[3]; // [rsp+4h] [rbp-Ch] BYREF

v3 = oplist;
v6[0] = a1;
v6[1] = a3;
for ( v6[2] = 0; v3; v3 = *(_QWORD *)(v3 + 32) )
{
if ( *(_DWORD *)v3 == a2 && typelisteq_constprop_0(v6, *(_DWORD **)(v3 + 16)) )
break;
}
return v3;
}

original_code:
static OpStruct *get_operator(Type t1, int op, Type t2)
{
  OpStruct *ol = oplist;
  Type tlist[3];
  tlist[0]=t1;
  tlist[1]=t2;
  tlist[2]=0;
  while (ol) {
    if ( ol->baseop==op && typelisteq(tlist, ol->list))
      return ol;
    ol=ol->next;
  }
  return 0;
}

canonical_original_code:
static struct OpStruct *get_operator(unsigned int t1, int op, unsigned int t2)
{
  struct OpStruct *ol = oplist;
  unsigned int tlist[3];
  tlist[0]=t1;
  tlist[1]=t2;
  tlist[2]=0;
  while (ol) {
    if ( ol->baseop==op && typelisteq(tlist, ol->list))
      return ol;
    ol=ol->next;
  }
  return 0;
}

variable_types: op int

variable_types: struct OpStruct { int baseop; struct FuncDef { char *name; char *description; char nr_args; char functype; unsigned int rettype; void *prototype; } *ifunc; unsigned int *list; unsigned int restype; struct OpStruct *next; } *

variable_types:
tlist
unsigned int [3]

user_defined_types: struct OpStruct { int baseop; struct FuncDef *ifunc; unsigned int *list; unsigned int restype; struct OpStruct *next; }


decompiled_code:
__int64 __fastcall make_expression(unsigned int a1)
{
__int64 v1; // r12
int v2; // eax

v1 = mm_malloc(24LL);
if ( v1 )
{
*(_WORD *)v1 = 2;
v2 = get_type(a1);
*(_DWORD *)(v1 + 8) = a1;
*(_DWORD *)(v1 + 4) = v2;
*(_QWORD *)(v1 + 16) = 0LL;
}
return v1;
}

original_code:
Expression *make_expression(Argument arg)
{
  Expression *te;
  te= (Expression*) mm_malloc(sizeof(Expression));
  if (!te) return ((void *)0);
  te->type=2;
  te->delta=0;
  te->restype=get_type(arg);
  te->val.arg=arg;
  te->next=((void *)0);
  return te;
}

canonical_original_code:
struct Expression *make_expression(int arg)
{
  struct Expression *te;
  te= (struct Expression *) mm_malloc(sizeof(Expression));
  if (!te) return ((void *)0);
  te->type=2;
  te->delta=0;
  te->restype=get_type(arg);
  te->val.arg=arg;
  te->next=((void *)0);
  return te;
}

variable_types: arg int

variable_types: struct Expression { char type; char delta; unsigned int restype; union { int op; int arg; struct Expression *le; struct FuncDef { char *name; char *description; char nr_args; char functype; unsigned int rettype; void *prototype; } *ifunc; struct FuncDef *ufunc; } val; struct Expression *next; } *

user_defined_types: struct Expression { char type; char delta; unsigned int restype; union { int op; int arg; struct Expression *le; struct FuncDef *ifunc; struct FuncDef *ufunc; } val; struct Expression *next; }


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

result = mm_malloc(24LL);
*(_WORD *)result = 5;
*(_DWORD *)(result + 4) = 4;
*(_QWORD *)(result + 8) = a1;
*(_QWORD *)(result + 16) = 0LL;
return result;
}

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

result = mm_malloc(24LL);
*(_WORD *)result = 5;
*(_DWORD *)(result + 4) = 4;
*(_QWORD *)(result + 8) = a1;
*(_QWORD *)(result + 16) = 0LL;
return result;
}

original_code:
Expression *make_lazy_expression(Expression *expr)
{
    Expression *e1;
    e1=mm_malloc(sizeof(Expression));
    e1->type=5;
    e1->delta=0;
    e1->restype=4;
    e1->val.le=expr;
    e1->next=((void *)0);
    return e1;
}

canonical_original_code:
struct Expression *make_lazy_expression(struct Expression *expr)
{
    struct Expression *e1;
    e1=mm_malloc(sizeof(Expression));
    e1->type=5;
    e1->delta=0;
    e1->restype=4;
    e1->val.le=expr;
    e1->next=((void *)0);
    return e1;
}

variable_types:
expr
struct Expression *

return_type: struct Expression { char type; char delta; unsigned int restype; union { int op; int arg; struct Expression *le; struct FuncDef { char *name; char *description; char nr_args; char functype; unsigned int rettype; void *prototype; } *ifunc; struct FuncDef *ufunc; } val; struct Expression *next; } *


original_code:
void calculate_expression(Expression *e)
{
    int d,i;
    ces->tos=0;
    expr_stack();
    while (e) {
 d=e->delta;
 switch (e->type) {
 case 2:
     ces->vl[ces->tos]=get_value(e->val.arg);
     if (e->restype) ces->tos++;
     ces->tos+=d;
     break;
 case 5:
     {
  LazyExpression *le;
  ces->vl[ces->tos]=ces->tv+ces->tos;
  le=ces->tv[ces->tos].val.stval=mm_malloc(sizeof(LazyExpression));
  le->expr=e->val.le;
  le->vlist=get_local_values(&le->len);
  ces->tv[ces->tos].type=e->restype;
  if (e->restype) ces->tos++;
     }
     break;
 case 1:
     if (e->delta==-1 && !e->val.op && e->restype) {
  if ((((ces->vl[ces->tos-1]->type)&0x8000)>0)) {
      ces->tv[ces->tos-1].type=e->restype;
  } else {
      ces->tv[ces->tos-1].type=ces->vl[ces->tos-1]->type;
  }
  CopyValue(&(ces->tv[ces->tos-1]),ces->vl[ces->tos-1]);
  break;
     }
 case 3:
     if (e->restype) {
  ces->vl[ces->tos]=ces->tv+ces->tos;
  ces->tv[ces->tos].type=e->restype;
  ConstructValue(&(ces->tv[ces->tos]));
     }
     call_function(e->val.ifunc, ces->vl+(ces->tos+e->delta));
     for (i=-1; i>=e->delta; i--) {
       if (ces->vl[ces->tos+i]== &(ces->tv[ces->tos+i])) {
  DestructValue(&(ces->tv[ces->tos+i]));
       }
     }
     if (e->restype) {
  ces->vl[ces->tos+d]=ces->tv+(ces->tos+d);
  ces->tv[ces->tos+d]=ces->tv[ces->tos];
  ces->tos++;
     }
     ces->tos+=d;
     break;
 case 4:
     if (e->restype) {
  ces->vl[ces->tos]=ces->tv+ces->tos;
  ces->tv[ces->tos].type=e->restype;
  ConstructValue(&(ces->tv[ces->tos]));
     }
     call_user_function(e->val.ufunc, ces->vl+(ces->tos+d));
     for (i=-1; i>=e->delta; i--) {
       if (ces->vl[ces->tos+i]== &(ces->tv[ces->tos+i])) {
  DestructValue(&(ces->tv[ces->tos+i]));
       }
     }
     if (e->restype) {
  ces->vl[ces->tos+d]=ces->tv+(ces->tos+d);
  ces->tv[ces->tos+d]=ces->tv[ces->tos];
  ces->tos++;
     }
     ces->tos+=d;
     break;
 default:
     break;
 }
 expr_stack();
 e=e->next;
    }
}

canonical_original_code:
void calculate_expression(struct Expression *e)
{
    int d; int i;
    ces->tos=0;
    expr_stack();
    while (e) {
 d=e->delta;
 switch (e->type) {
 case 2:
     ces->vl[ces->tos]=get_value(e->val.arg);
     if (e->restype) ces->tos++;
     ces->tos+=d;
     break;
 case 5:
     {
  struct LazyExpression *le;
  ces->vl[ces->tos]=ces->tv+ces->tos;
  le=ces->tv[ces->tos].val.stval=mm_malloc(sizeof(LazyExpression));
  le->expr=e->val.le;
  le->vlist=get_local_values(&le->len);
  ces->tv[ces->tos].type=e->restype;
  if (e->restype) ces->tos++;
     }
     break;
 case 1:
     if (e->delta==-1 && !e->val.op && e->restype) {
  if ((((ces->vl[ces->tos-1]->type)&0x8000)>0)) {
      ces->tv[ces->tos-1].type=e->restype;
  } else {
      ces->tv[ces->tos-1].type=ces->vl[ces->tos-1]->type;
  }
  CopyValue(&(ces->tv[ces->tos-1]),ces->vl[ces->tos-1]);
  break;
     }
 case 3:
     if (e->restype) {
  ces->vl[ces->tos]=ces->tv+ces->tos;
  ces->tv[ces->tos].type=e->restype;
  ConstructValue(&(ces->tv[ces->tos]));
     }
     call_function(e->val.ifunc, ces->vl+(ces->tos+e->delta));
     for (i=-1; i>=e->delta; i--) {
       if (ces->vl[ces->tos+i]== &(ces->tv[ces->tos+i])) {
  DestructValue(&(ces->tv[ces->tos+i]));
       }
     }
     if (e->restype) {
  ces->vl[ces->tos+d]=ces->tv+(ces->tos+d);
  ces->tv[ces->tos+d]=ces->tv[ces->tos];
  ces->tos++;
     }
     ces->tos+=d;
     break;
 case 4:
     if (e->restype) {
  ces->vl[ces->tos]=ces->tv+ces->tos;
  ces->tv[ces->tos].type=e->restype;
  ConstructValue(&(ces->tv[ces->tos]));
     }
     call_user_function(e->val.ufunc, ces->vl+(ces->tos+d));
     for (i=-1; i>=e->delta; i--) {
       if (ces->vl[ces->tos+i]== &(ces->tv[ces->tos+i])) {
  DestructValue(&(ces->tv[ces->tos+i]));
       }
     }
     if (e->restype) {
  ces->vl[ces->tos+d]=ces->tv+(ces->tos+d);
  ces->tv[ces->tos+d]=ces->tv[ces->tos];
  ces->tos++;
     }
     ces->tos+=d;
     break;
 default:
     break;
 }
 expr_stack();
 e=e->next;
    }
}

variable_types: d int

variable_types: i int

variable_types: struct LazyExpression { struct Value { unsigned int type; union TVal { int ival; double rval; void *stval; int *iref; double *rref; void **stref; } val; } *vlist; int len; struct Expression { char type; char delta; unsigned int restype; union { int op; int arg; struct Expression *le; struct FuncDef { char *name; char *description; char nr_args; char functype; unsigned int rettype; void *prototype; } *ifunc; struct FuncDef *ufunc; } val; struct Expression *next; } *expr; } *

user_defined_types: struct LazyExpression { struct Value *vlist; int len; struct Expression *expr; }

user_defined_types: struct Value { unsigned int type; union TVal val; }


decompiled_code:
__int64 clear_expr_stack()
{
__int64 v0; // rbx
__int64 result; // rax

v0 = ces;
result = *(int *)(ces + 1200);
if ( (_DWORD)result )
{
result = (__int64)memset(
(void *)(ces + 8 * (result - (unsigned int)(result - 1)) + 792),
0,
8LL * (unsigned int)(result - 1) + 8);
*(_DWORD *)(v0 + 1200) = 0;
}
return result;
}

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

v0 = ces;
result = *(int *)(ces + 1200);
if ( (_DWORD)result )
{
result = (__int64)memset(
(void *)(ces + 8 * (result - (unsigned int)(result - 1)) + 792),
0,
8LL * (unsigned int)(result - 1) + 8);
*(_DWORD *)(v0 + 1200) = 0;
}
return result;
}

original_code:
void clear_expr_stack(void)
{
    while (ces->tos) {
 ces->tos--;
 ces->vl[ces->tos]=((void *)0);
    }
}

canonical_original_code:
void clear_expr_stack()
{
    while (ces->tos) {
 ces->tos--;
 ces->vl[ces->tos]=((void *)0);
    }
}


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

result = *(unsigned int *)(ces + 1200);
if ( (_DWORD)result )
result = *(_DWORD *)(*(_QWORD *)(ces + 8LL * ((int)result - 1) + 800) + 8LL) != 0;
return result;
}

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

result = *(unsigned int *)(ces + 1200);
if ( (_DWORD)result )
result = *(_DWORD *)(*(_QWORD *)(ces + 8LL * ((int)result - 1) + 800) + 8LL) != 0;
return result;
}

original_code:
int non_zero_on_stack(void)
{
    if (ces->tos && ces->vl[ces->tos-1]->val.ival) {
 return 1;
    } else return 0;
}

canonical_original_code:
int non_zero_on_stack()
{
    if (ces->tos && ces->vl[ces->tos-1]->val.ival) {
 return 1;
    } else return 0;
}


decompiled_code:
__int64 push_eval_stack()
{
__int64 result; // rax
__int64 v1; // rdx

result = used_eestack;
if ( used_eestack )
used_eestack = *(_QWORD *)(used_eestack + 1208);
else
result = mm_malloc(1216LL);
v1 = ces;
*(_DWORD *)(result + 1200) = 0;
ces = result;
*(_QWORD *)(result + 1208) = v1;
return result;
}

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

result = used_eestack;
if ( used_eestack )
used_eestack = *(_QWORD *)(used_eestack + 1208);
else
result = mm_malloc(1216LL);
v1 = ces;
*(_DWORD *)(result + 1200) = 0;
ces = result;
*(_QWORD *)(result + 1208) = v1;
return result;
}

original_code:
void push_eval_stack(void)
{
    ExpEvaStack *h;
    if (used_eestack) {
 h=used_eestack;
 used_eestack=h->prev;
    } else {
 h=mm_malloc(sizeof(ExpEvaStack));
    }
    h->tos=0;
    h->prev=ces;
    ces=h;
}

canonical_original_code:
void push_eval_stack()
{
    struct ExpEvaStack *h;
    if (used_eestack) {
 h=used_eestack;
 used_eestack=h->prev;
    } else {
 h=mm_malloc(sizeof(ExpEvaStack));
    }
    h->tos=0;
    h->prev=ces;
    ces=h;
}

variable_types: struct ExpEvaStack { struct Value { unsigned int type; union TVal { int ival; double rval; void *stval; int *iref; double *rref; void **stref; } val; } tv[50]; struct Value *vl[50]; int tos; struct ExpEvaStack *prev; } *

user_defined_types: struct ExpEvaStack { struct Value tv[50]; struct Value *vl[50]; int tos; struct ExpEvaStack *prev; }


decompiled_code:
__int64 pop_eval_stack()
{
__int64 result; // rax
__int64 v1; // rcx
__int64 v2; // rdx

clear_expr_stack();
result = ces;
v1 = used_eestack;
v2 = *(_QWORD *)(ces + 1208);
used_eestack = ces;
*(_QWORD *)(ces + 1208) = v1;
ces = v2;
return result;
}

canonical_decompiled_code:
__int64 func8()
{
__int64 result; // rax
__int64 v1; // rcx
__int64 v2; // rdx

func5();
result = ces;
v1 = used_eestack;
v2 = *(_QWORD *)(ces + 1208);
used_eestack = ces;
*(_QWORD *)(ces + 1208) = v1;
ces = v2;
return result;
}

original_code:
void pop_eval_stack(void)
{
    ExpEvaStack *h;
    clear_expr_stack();
    h=ces->prev;
    ces->prev=used_eestack;
    used_eestack=ces;
    ces=h;
}

canonical_original_code:
void pop_eval_stack()
{
    struct ExpEvaStack *h;
    clear_expr_stack();
    h=ces->prev;
    ces->prev=used_eestack;
    used_eestack=ces;
    ces=h;
}

user_defined_types: union TVal { int ival; double rval; void *stval; int *iref; double *rref; void **stref; }


decompiled_code:
__int64 __fastcall calculate_lazy_expression(__int64 a1)
{
push_local_variables(*(_QWORD *)a1, *(unsigned int *)(a1 + 8));
push_eval_stack();
calculate_expression(*(_QWORD *)(a1 + 16));
clear_expr_stack();
pop_eval_stack();
return pop_local_variables();
}

canonical_decompiled_code:
__int64 __fastcall func9(__int64 a1)
{
push_local_variables(*(_QWORD *)a1, *(unsigned int *)(a1 + 8));
func7();
func4(*(_QWORD *)(a1 + 16));
func5();
func8();
return pop_local_variables();
}

original_code:
void calculate_lazy_expression(void *lazyexpr)
{
  LazyExpression *le = (LazyExpression*)lazyexpr;
  push_local_variables(le->vlist, le->len);
  push_eval_stack();
  calculate_expression(le->expr);
  clear_expr_stack();
  pop_eval_stack();
  pop_local_variables();
}

canonical_original_code:
void calculate_lazy_expression(void *lazyexpr)
{
  struct LazyExpression *le = (LazyExpression*)lazyexpr;
  push_local_variables(le->vlist, le->len);
  push_eval_stack();
  calculate_expression(le->expr);
  clear_expr_stack();
  pop_eval_stack();
  pop_local_variables();
}

variable_types:
lazyexpr
void *

user_defined_types: struct FuncDef { char *name; char *description; char nr_args; char functype; unsigned int rettype; void *prototype; }


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

for ( ; ces; result = pop_eval_stack() )
;
return result;
}

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

for ( ; ces; result = func8() )
;
return result;
}

original_code:
void clear_eval_stack(void)
{
    while (ces) {
 pop_eval_stack();
    }
}

canonical_original_code:
void clear_eval_stack()
{
    while (ces) {
 pop_eval_stack();
    }
}


decompiled_code:
int *__fastcall type_of_expression(__int64 a1)
{
int v1; // edx
int v2; // ecx
__int64 v3; // rsi
int v4; // eax
int v5; // eax
__int64 v6; // rcx
int *result; // rax

v1 = 0;
if ( !a1 )
{
LABEL_10:
result = tlist;
tlist[v1] = 0;
return result;
}
while ( 1 )
{
v4 = *(char *)(a1 + 1);
if ( *(char *)(a1 + 1) >= 0 )
{
v2 = *(_DWORD *)(a1 + 4);
if ( v2 )
{
v3 = v1;
v1 += v4 + 1;
tlist[v3] = v2;
}
goto LABEL_5;
}
if ( v4 > v1 )
return 0LL;
v1 += v4;
v5 = *(_DWORD *)(a1 + 4);
if ( v5 )
{
a1 = *(_QWORD *)(a1 + 16);
v6 = v1++;
tlist[v6] = v5;
if ( !a1 )
goto LABEL_10;
}
else
{
LABEL_5:
a1 = *(_QWORD *)(a1 + 16);
if ( !a1 )
goto LABEL_10;
}
}
}

canonical_decompiled_code:
int *__fastcall func11(__int64 a1)
{
int v1; // edx
int v2; // ecx
__int64 v3; // rsi
int v4; // eax
int v5; // eax
__int64 v6; // rcx
int *result; // rax

v1 = 0;
if ( !a1 )
{
LABEL_10:
result = tlist;
tlist[v1] = 0;
return result;
}
while ( 1 )
{
v4 = *(char *)(a1 + 1);
if ( *(char *)(a1 + 1) >= 0 )
{
v2 = *(_DWORD *)(a1 + 4);
if ( v2 )
{
v3 = v1;
v1 += v4 + 1;
tlist[v3] = v2;
}
goto LABEL_5;
}
if ( v4 > v1 )
return 0LL;
v1 += v4;
v5 = *(_DWORD *)(a1 + 4);
if ( v5 )
{
a1 = *(_QWORD *)(a1 + 16);
v6 = v1++;
tlist[v6] = v5;
if ( !a1 )
goto LABEL_10;
}
else
{
LABEL_5:
a1 = *(_QWORD *)(a1 + 16);
if ( !a1 )
goto LABEL_10;
}
}
}

original_code:
Type *type_of_expression(Expression *e)
{
    int i=0;
    while (e) {
 if (e->delta>=0 && e->restype) {
     tlist[i]=e->restype;
     i=i+1+e->delta;
 } else if (e->delta<0) {
     if (i<e->delta) {
  return ((void *)0);
     }
     i=i+e->delta;
     if (e->restype) {
  tlist[i++]=e->restype;
     }
 }
 e=e->next;
    }
    tlist[i]=0;
    return tlist;
}

canonical_original_code:
unsigned int *type_of_expression(struct Expression *e)
{
    int i = 0;
    while (e) {
 if (e->delta>=0 && e->restype) {
     tlist[i]=e->restype;
     i=i+1+e->delta;
 } else if (e->delta<0) {
     if (i<e->delta) {
  return ((void *)0);
     }
     i=i+e->delta;
     if (e->restype) {
  tlist[i++]=e->restype;
     }
 }
 e=e->next;
    }
    tlist[i]=0;
    return tlist;
}

return_type: unsigned int *


original_code:
Expression *combine_expression(Expression *e1, Expression *e2,
          int op)
{
  Expression *te, *tf;
  OpStruct *os;
  int i;
  Type *restype;
  Type t[3];
  if (!op) {
      i=1;
      te=e1;
      while (1) {
   if (te->type==2) i=1;
   else i=0;
   if (!te->next) break;
   te=te->next;
      }
      if (!e2 && i) {
   te->next=mm_malloc(sizeof(Expression));
   te->next->restype=((te->restype)&0x7fff);
   te=te->next;
   te->type=1;
   te->delta=-1;
   te->val.op=0;
   te->next=((void *)0);
      } else {
   te->next=e2;
      }
      return e1;
  }
  restype = type_of_expression(e1);
  for (i=0; restype[i]; i++);
  if (i) i--;
  t[0] = restype[i];
  if (e2) {
      restype = type_of_expression(e2);
      t[1]=restype[0];
      t[2]=0;
  } else t[1]=0;
  os=get_operator(t[0], op, t[1]);
  if (!os) {
      fprintf(stderr, "Operator not defined for combination (%s %s %s)\n",
       lookup_typename(t[0]), op_name[op], lookup_typename(t[1]));
      return ((void *)0);
  }
  te = (Expression*) mm_malloc(sizeof(Expression));
  te->type=1;
  te->delta=(t[1]>0)?-2:-1;
  te->val.ifunc=os->ifunc;
  te->restype=os->restype;
  tf=e1;
  while (tf->next) tf=tf->next;
  tf->next=e2;
  while (tf->next) tf=tf->next;
  tf->next=te;
  te->next=((void *)0);
  return e1;
}

canonical_original_code:
struct Expression *combine_expression(struct Expression *e1, struct Expression *e2, int op)
{
  struct Expression *te; struct Expression *tf;
  struct OpStruct *os;
  int i;
  unsigned int *restype;
  unsigned int t[3];
  if (!op) {
      i=1;
      te=e1;
      while (1) {
   if (te->type==2) i=1;
   else i=0;
   if (!te->next) break;
   te=te->next;
      }
      if (!e2 && i) {
   te->next=mm_malloc(sizeof(Expression));
   te->next->restype=((te->restype)&0x7fff);
   te=te->next;
   te->type=1;
   te->delta=-1;
   te->val.op=0;
   te->next=((void *)0);
      } else {
   te->next=e2;
      }
      return e1;
  }
  restype = type_of_expression(e1);
  for (i=0; restype[i]; i++);
  if (i) i--;
  t[0] = restype[i];
  if (e2) {
      restype = type_of_expression(e2);
      t[1]=restype[0];
      t[2]=0;
  } else t[1]=0;
  os=get_operator(t[0], op, t[1]);
  if (!os) {
      fprintf(stderr, "Operator not defined for combination (%s %s %s)\n",
       lookup_typename(t[0]), op_name[op], lookup_typename(t[1]));
      return ((void *)0);
  }
  te = (struct Expression *) mm_malloc(sizeof(Expression));
  te->type=1;
  te->delta=(t[1]>0)?-2:-1;
  te->val.ifunc=os->ifunc;
  te->restype=os->restype;
  tf=e1;
  while (tf->next) tf=tf->next;
  tf->next=e2;
  while (tf->next) tf=tf->next;
  tf->next=te;
  te->next=((void *)0);
  return e1;
}

variable_types:
restype
unsigned int *

variable_types:
t
unsigned int [3]


original_code:
Expression *func_expression(Expression *argexp,
       int num __attribute__((unused)),
       FuncRef func, int user_func)
{
    Expression *te;
    int i;
    Type *restype;
    Type fres;
    Prototype *p;
    restype = type_of_expression(argexp);
    i=0;
    while (restype[i]) i++;
    if (user_func) {
 p=proto_user(func);
 fres=restype_user_function(func);
    } else {
 p=proto_function(func);
 fres=restype_function(func);
    }
    if (i!=((p)->n) &&
 (i+1!=((p)->n) || (((i)<0||(i)>=(p)->n) ? 0 : (p)->type[i])!=((fres)|0x8000))) {
 return ((void *)0);
    }
    if (matches_prototype(restype,p,i)) {
      if (argexp) {
 te=argexp;
 while (te->next) te=te->next;
 te->next=mm_malloc(sizeof(Expression));
 te=te->next;
      } else {
 te = argexp = mm_malloc(sizeof(Expression));
      }
      te->type=(user_func?4:3);
      te->restype=(i!=((p)->n)?0:fres);
      te->delta=-i;
      te->next=((void *)0);
      if (user_func)
 te->val.ufunc=func;
      else te->val.ifunc=func;
      return argexp;
    } else return ((void *)0);
}

canonical_original_code:
struct Expression *func_expression(struct Expression *argexp, int num, struct FuncDef *func, int user_func)
{
    struct Expression *te;
    int i;
    unsigned int *restype;
    unsigned int fres;
    struct Prototype *p;
    restype = type_of_expression(argexp);
    i=0;
    while (restype[i]) i++;
    if (user_func) {
 p=proto_user(func);
 fres=restype_user_function(func);
    } else {
 p=proto_function(func);
 fres=restype_function(func);
    }
    if (i!=((p)->n) &&
 (i+1!=((p)->n) || (((i)<0||(i)>=(p)->n) ? 0 : (p)->type[i])!=((fres)|0x8000))) {
 return ((void *)0);
    }
    if (matches_prototype(restype,p,i)) {
      if (argexp) {
 te=argexp;
 while (te->next) te=te->next;
 te->next=mm_malloc(sizeof(Expression));
 te=te->next;
      } else {
 te = argexp = mm_malloc(sizeof(Expression));
      }
      te->type=(user_func?4:3);
      te->restype=(i!=((p)->n)?0:fres);
      te->delta=-i;
      te->next=((void *)0);
      if (user_func)
 te->val.ufunc=func;
      else te->val.ifunc=func;
      return argexp;
    } else return ((void *)0);
}

variable_types:
argexp
struct Expression *

variable_types: num int

variable_types:
func
struct FuncDef *

variable_types:
fres
unsigned int

variable_types: struct Prototype { unsigned int *type; int n; unsigned int restype; int max; int (*caller)(); } *


decompiled_code:
__int64 __fastcall left_on_stack(__int64 a1)
{
int v1; // eax
bool v2; // cf
__int64 result; // rax

if ( !a1 )
return 0LL;
v1 = *(char *)(a1 + 1);
if ( v1 < 0 )
return 0xFFFFFFFFLL;
while ( 1 )
{
v2 = *(_DWORD *)(a1 + 4) == 0;
a1 = *(_QWORD *)(a1 + 16);
result = v1 - ((unsigned int)v2 - 1);
if ( !a1 )
break;
v1 = *(char *)(a1 + 1) + (_DWORD)result;
if ( v1 < 0 )
return 0xFFFFFFFFLL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func14(__int64 a1)
{
int v1; // eax
bool v2; // cf
__int64 result; // rax

if ( !a1 )
return 0LL;
v1 = *(char *)(a1 + 1);
if ( v1 < 0 )
return 0xFFFFFFFFLL;
while ( 1 )
{
v2 = *(_DWORD *)(a1 + 4) == 0;
a1 = *(_QWORD *)(a1 + 16);
result = v1 - ((unsigned int)v2 - 1);
if ( !a1 )
break;
v1 = *(char *)(a1 + 1) + (_DWORD)result;
if ( v1 < 0 )
return 0xFFFFFFFFLL;
}
return result;
}

original_code:
int left_on_stack(Expression *e)
{
    int res=0;
    while (e && res>=0) {
 res=res+e->delta;
 if (res<0) return -1;
 if (e->restype) res++;
 e=e->next;
    }
    return res;
}

canonical_original_code:
int left_on_stack(struct Expression *e)
{
    int res = 0;
    while (e && res>=0) {
 res=res+e->delta;
 if (res<0) return -1;
 if (e->restype) res++;
 e=e->next;
    }
    return res;
}

variable_types: res int


decompiled_code:
__int64 __fastcall assign_expression(int a1, __int64 a2, __int64 a3)
{
int v3; // eax
int v4; // ecx
__int64 v5; // r15
int *v6; // r12
__int64 v7; // rbp
unsigned int v8; // er9
unsigned int v9; // eax
unsigned int v10; // er13
__int64 v12; // rbx
__int64 v13; // r12
unsigned int v14; // edi
__int64 v15; // rax
const char *v16; // r12
const char *v17; // rax

v3 = left_on_stack(a3);
if ( v3 != v4 )
return 0LL;
v5 = 0LL;
v6 = type_of_expression(a3);
if ( a1 > 0 )
{
while ( 1 )
{
v9 = get_type(*(unsigned int *)(a2 + 4 * v5));
v10 = v9;
if ( (v9 & 0x4000) != 0 )
{
fwrite("Unable to make assignments to constants.\n", 1uLL, 0x29uLL, stderr);
return 0LL;
}
v7 = get_operator(v6[v5], 1, v9 & 0x7FFF);
if ( !v7 )
break;
if ( ++v5 == a1 )
goto LABEL_10;
}
v16 = (const char *)lookup_typename(v8);
v17 = (const char *)lookup_typename(v10);
fprintf(stderr, "Assignment not defined for %s:=%s.\n", v17, v16);
}
else
{
LABEL_10:
v12 = a2 + 4LL * a1;
v7 = a3;
v13 = v12 - 4LL * (unsigned int)a1;
while ( v12 != v13 )
{
v14 = *(_DWORD *)(v12 - 4);
v12 -= 4LL;
v15 = make_expression(v14);
v7 = combine_expression(v7, v15, 1);
if ( !v7 )
return 0LL;
}
}
return v7;
}

canonical_decompiled_code:
__int64 __fastcall func15(int a1, __int64 a2, __int64 a3)
{
int v3; // eax
int v4; // ecx
__int64 v5; // r15
int *v6; // r12
__int64 v7; // rbp
unsigned int v8; // er9
unsigned int v9; // eax
unsigned int v10; // er13
__int64 v12; // rbx
__int64 v13; // r12
unsigned int v14; // edi
__int64 v15; // rax
const char *v16; // r12
const char *v17; // rax

v3 = func14(a3);
if ( v3 != v4 )
return 0LL;
v5 = 0LL;
v6 = func11(a3);
if ( a1 > 0 )
{
while ( 1 )
{
v9 = get_type(*(unsigned int *)(a2 + 4 * v5));
v10 = v9;
if ( (v9 & 0x4000) != 0 )
{
fwrite("Unable to make assignments to constants.\n", 1uLL, 0x29uLL, stderr);
return 0LL;
}
v7 = func1(v6[v5], 1, v9 & 0x7FFF);
if ( !v7 )
break;
if ( ++v5 == a1 )
goto LABEL_10;
}
v16 = (const char *)lookup_typename(v8);
v17 = (const char *)lookup_typename(v10);
fprintf(stderr, "Assignment not defined for %s:=%s.\n", v17, v16);
}
else
{
LABEL_10:
v12 = a2 + 4LL * a1;
v7 = a3;
v13 = v12 - 4LL * (unsigned int)a1;
while ( v12 != v13 )
{
v14 = *(_DWORD *)(v12 - 4);
v12 -= 4LL;
v15 = func2(v14);
v7 = func12(v7, v15, 1);
if ( !v7 )
return 0LL;
}
}
return v7;
}

original_code:
Expression *assign_expression(int nr, Argument *alist, Expression *elist)
{
    Type *tlist;
    Type ct;
    int i;
    Expression *e1;
    if ((i=left_on_stack(elist)) != nr) return 0;
    tlist = type_of_expression(elist);
    for (i=0; i<nr; i++) {
 ct = get_type(alist[i]);
 if ((((ct)&0x4000)>0)) {
     fprintf(stderr, "Unable to make assignments to constants.\n");
     return 0;
 }
 if (!get_operator(tlist[i], 1, ((ct)&0x7fff))) {
     fprintf(stderr, "Assignment not defined for %s:=%s.\n",
      lookup_typename(ct), lookup_typename(tlist[i]));
     return 0;
 }
    }
    i=nr;
    while (i) {
 i--;
 e1=make_expression(alist[i]);
 e1=combine_expression(elist, e1, 1);
 if (!e1) return 0;
 elist=e1;
    }
    return elist;
}

canonical_original_code:
struct Expression *assign_expression(int nr, int *alist, struct Expression *elist)
{
    unsigned int *tlist;
    unsigned int ct;
    int i;
    struct Expression *e1;
    if ((i=left_on_stack(elist)) != nr) return 0;
    tlist = type_of_expression(elist);
    for (i=0; i<nr; i++) {
 ct = get_type(alist[i]);
 if ((((ct)&0x4000)>0)) {
     fprintf(stderr, "Unable to make assignments to constants.\n");
     return 0;
 }
 if (!get_operator(tlist[i], 1, ((ct)&0x7fff))) {
     fprintf(stderr, "Assignment not defined for %s:=%s.\n",
      lookup_typename(ct), lookup_typename(tlist[i]));
     return 0;
 }
    }
    i=nr;
    while (i) {
 i--;
 e1=make_expression(alist[i]);
 e1=combine_expression(elist, e1, 1);
 if (!e1) return 0;
 elist=e1;
    }
    return elist;
}

variable_types: nr int

variable_types:
alist
int *

variable_types:
elist
struct Expression *

variable_types:
tlist
unsigned int *

variable_types:
ct
unsigned int


decompiled_code:
__int64 __fastcall free_expression(__int64 a1)
{
__int64 v1; // rbx
__int64 v2; // rdi
__int64 result; // rax

if ( a1 )
{
v1 = a1;
do
{
v2 = v1;
v1 = *(_QWORD *)(v1 + 16);
result = mm_free(v2);
}
while ( v1 );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func16(__int64 a1)
{
__int64 v1; // rbx
__int64 v2; // rdi
__int64 result; // rax

if ( a1 )
{
v1 = a1;
do
{
v2 = v1;
v1 = *(_QWORD *)(v1 + 16);
result = mm_free(v2);
}
while ( v1 );
}
return result;
}

original_code:
void free_expression(Expression *e)
{
    Expression *h;
    if (!e) return;
    while (e) {
 h=e;
 e=e->next;
 mm_free(h);
    }
}

canonical_original_code:
void free_expression(struct Expression *e)
{
    struct Expression *h;
    if (!e) return;
    while (e) {
 h=e;
 e=e->next;
 mm_free(h);
    }
}

variable_types: struct Expression { char type; char delta; unsigned int restype; union { int op; int arg; struct Expression *le; struct FuncDef { char *name; char *description; char nr_args; char functype; unsigned int rettype; void *prototype; } *ifunc; struct FuncDef *ufunc; } val; struct Expression *next; } *


decompiled_code:
__int64 __fastcall define_operator(int a1, __int64 a2)
{
__int64 v2; // rbx
__int64 v3; // rax
__int64 v4; // rax
__int64 v5; // rdx
__int64 result; // rax

v2 = mm_malloc(40LL);
v3 = oplist;
*(_QWORD *)(v2 + 8) = a2;
*(_QWORD *)(v2 + 32) = v3;
v4 = proto_function(a2);
oplist = v2;
v5 = *(_QWORD *)v4;
result = *(unsigned int *)(v4 + 12);
*(_DWORD *)v2 = a1;
*(_QWORD *)(v2 + 16) = v5;
*(_DWORD *)(v2 + 24) = result;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func17(int a1, __int64 a2)
{
__int64 v2; // rbx
__int64 v3; // rax
__int64 v4; // rax
__int64 v5; // rdx
__int64 result; // rax

v2 = mm_malloc(40LL);
v3 = oplist;
*(_QWORD *)(v2 + 8) = a2;
*(_QWORD *)(v2 + 32) = v3;
v4 = proto_function(a2);
oplist = v2;
v5 = *(_QWORD *)v4;
result = *(unsigned int *)(v4 + 12);
*(_DWORD *)v2 = a1;
*(_QWORD *)(v2 + 16) = v5;
*(_DWORD *)(v2 + 24) = result;
return result;
}

original_code:
void define_operator(int op, FuncRef function)
{
    OpStruct *no;
    Prototype *pr;
    no=mm_malloc(sizeof(OpStruct));
    no->next=oplist;
    no->ifunc=function;
    pr=proto_function(function);
    no->list=pr->type;
    no->restype=((pr)->restype);
    no->baseop=op;
    oplist=no;
}

canonical_original_code:
void define_operator(int op, struct FuncDef *function)
{
    struct OpStruct *no;
    struct Prototype *pr;
    no=mm_malloc(sizeof(OpStruct));
    no->next=oplist;
    no->ifunc=function;
    pr=proto_function(function);
    no->list=pr->type;
    no->restype=((pr)->restype);
    no->baseop=op;
    oplist=no;
}

variable_types: op int

variable_types: struct OpStruct { int baseop; struct FuncDef { char *name; char *description; char nr_args; char functype; unsigned int rettype; void *prototype; } *ifunc; unsigned int *list; unsigned int restype; struct OpStruct *next; } *

user_defined_types: struct Prototype { unsigned int *type; int n; unsigned int restype; int max; int (*caller)(); }


CallPayback

decompiled_code:
void CallPayback()
{
__int64 i; // rbx

for ( i = paybacklist; i; i = *(_QWORD *)(i + 8) )
{
if ( *(_QWORD *)i )
(*(void (**)(void))i)();
}
}

canonical_decompiled_code:
void func0()
{
__int64 i; // rbx

for ( i = paybacklist; i; i = *(_QWORD *)(i + 8) )
{
if ( *(_QWORD *)i )
(*(void (**)(void))i)();
}
}

original_code:
static void CallPayback(void)
{
  PaybackFunc *pbf;
  pbf=paybacklist;
  while (pbf) {
    if (pbf->function) (*(pbf->function))();
    pbf=pbf->next;
  }
}

canonical_original_code:
static void CallPayback()
{
  struct _PaybackFunc *pbf;
  pbf=paybacklist;
  while (pbf) {
    if (pbf->function) (*(pbf->function))();
    pbf=pbf->next;
  }
}

variable_types: struct _PaybackFunc { void (*function)(); struct _PaybackFunc *next; } *


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

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

original_code:
void mm_free(void *p)
{
    if (p) {
      if (0) {
 int size;
 size=1;
 if (size) memset(p, ((((char *)p)[0]^0xCC)|0x1), size);
      }
      free(p);
    }
}

variable_types:
p
void *

variable_types: size int


decompiled_code:
__int64 __fastcall reduce_freelist(__int64 a1, int a2)
{
__int64 result; // rax
_QWORD *v4; // rdi

for ( result = *(unsigned int *)(a1 + 8); (int)result > a2; result = *(unsigned int *)(a1 + 8) )
{
v4 = *(_QWORD **)a1;
*(_DWORD *)(a1 + 8) = result - 1;
*(_QWORD *)a1 = *v4;
mm_free(v4);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, int a2)
{
__int64 result; // rax
_QWORD *v4; // rdi

for ( result = *(unsigned int *)(a1 + 8); (int)result > a2; result = *(unsigned int *)(a1 + 8) )
{
v4 = *(_QWORD **)a1;
*(_DWORD *)(a1 + 8) = result - 1;
*(_QWORD *)a1 = *v4;
func1(v4);
}
return result;
}

original_code:
static void reduce_freelist(FreeList *fl, int len)
{
  FLItem *fli;
  while (fl->length>len) {
    fli=(FLItem*)fl->data;
    fl->length--;
    fl->data=fli->next;
    mm_free(fli);
  }
}

canonical_original_code:
static void reduce_freelist(struct FreeList *fl, int len)
{
  struct _FLItem *fli;
  while (fl->length>len) {
    fli=(struct _FLItem *)fl->data;
    fl->length--;
    fl->data=fli->next;
    mm_free(fli);
  }
}

variable_types: struct FreeList { void *data; int length; int regis; int size; int min; int max; } *

variable_types: len int

variable_types: struct _FLItem { struct _FLItem *next; } *