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

result = HIDWORD(GlobalState[8]);
if ( result )
{
if ( hash_file )
{
fclose(hash_file);
result = unlink(VIRTUAL_FILE);
}
}
return result;
}

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

result = HIDWORD(GlobalState[8]);
if ( result )
{
if ( hash_file )
{
fclose(hash_file);
result = unlink(VIRTUAL_FILE);
}
}
return result;
}

original_code:
void
clear_duplicate_hash_table(void)
{
   if(GlobalState.use_virtual_hash_table){
      if(hash_file != ((void *)0)){
        (void) fclose(hash_file);
        unlink(VIRTUAL_FILE);
      }
   }
}

canonical_original_code:
void clear_duplicate_hash_table()
{
   if(GlobalState.use_virtual_hash_table){
      if(hash_file != ((void *)0)){
        (void) fclose(hash_file);
        unlink(VIRTUAL_FILE);
      }
   }
}


decompiled_code:
__int64 __fastcall previous_occurance(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, int a7, int a8, int a9, unsigned __int64 a10, __int64 *a11)
{
unsigned __int64 v11; // rdx
__int64 v12; // rbp
__int64 v13; // rbx
__int64 v14; // rdx
__int64 *v16; // rax
__int64 *v17; // r12
int v18; // eax
__int64 **v19; // rbp

if ( HIDWORD(GlobalState[8]) )
return previous_virtual_occurance_isra_0(a10, a11);
v11 = a10 % 0x1FFF;
if ( !*(_QWORD *)((char *)&GlobalState[4] + 4) && !GlobalState[24] )
return 0LL;
v12 = 8 * v11;
v13 = (unsigned __int64)a11 ^ a10;
v14 = *(_QWORD *)(LogTable + 8 * v11);
if ( !v14 )
{
LABEL_9:
v16 = (__int64 *)MallocOrDie(24LL);
*v16 = v13;
v17 = v16;
v18 = current_file_number(24LL, a11);
v19 = (__int64 **)(LogTable + v12);
*((_DWORD *)v17 + 2) = v18;
v17[2] = (__int64)*v19;
*v19 = v17;
return 0LL;
}
while ( *(_QWORD *)v14 != v13 )
{
v14 = *(_QWORD *)(v14 + 16);
if ( !v14 )
goto LABEL_9;
}
return input_file_name(*(unsigned int *)(v14 + 8));
}

original_code:
const char *
previous_occurance(Game game_details)
{
  const char *original_filename = ((void *)0);
  if(GlobalState.use_virtual_hash_table){
    original_filename = previous_virtual_occurance(game_details);
  }
  else{
    unsigned ix = game_details.final_hash_value % 8191;
    HashLog *entry = ((void *)0);
    Boolean duplicate = FALSE;
    if(GlobalState.suppress_duplicates || GlobalState.suppress_originals ||
                GlobalState.duplicate_file != ((void *)0)){
        for(entry = LogTable[ix]; !duplicate && (entry != ((void *)0));
                                        entry = entry->next){
            if(entry->combined_hash_value ==
                        (game_details.final_hash_value ^
                                        game_details.cumulative_hash_value)){
                original_filename = input_file_name(entry->file_number);
                duplicate = TRUE;
            }
        }
        if(!duplicate){
            entry = (HashLog *)MallocOrDie(sizeof(*entry));
            entry->combined_hash_value =
                game_details.final_hash_value ^ game_details.cumulative_hash_value;
            entry->file_number = current_file_number();
            entry->next = LogTable[ix];
            LogTable[ix] = entry;
        }
    }
  }
  return original_filename;
}

canonical_original_code:
char *previous_occurance(struct Game game_details)
{
  char *original_filename = ((void *)0);
  if(GlobalState.use_virtual_hash_table){
    original_filename = previous_virtual_occurance(game_details);
  }
  else{
    unsigned int ix = game_details.final_hash_value % 8191;
    struct HashLog *entry = ((void *)0);
    enum Boolean duplicate = FALSE;
    if(GlobalState.suppress_duplicates || GlobalState.suppress_originals ||
                GlobalState.duplicate_file != ((void *)0)){
        for(entry = LogTable[ix]; !duplicate && (entry != ((void *)0));
                                        entry = entry->next){
            if(entry->combined_hash_value ==
                        (game_details.final_hash_value ^
                                        game_details.cumulative_hash_value)){
                original_filename = input_file_name(entry->file_number);
                duplicate = TRUE;
            }
        }
        if(!duplicate){
            entry = (struct HashLog *)MallocOrDie(sizeof(*entry));
            entry->combined_hash_value =
                game_details.final_hash_value ^ game_details.cumulative_hash_value;
            entry->file_number = current_file_number();
            entry->next = LogTable[ix];
            LogTable[ix] = entry;
        }
    }
  }
  return original_filename;
}

variable_types: struct Game { char **tags; int tags_length; struct comment_list { struct string_list { char *str; struct string_list *next; } *Comment; struct comment_list *next; } *prefix_comment; unsigned long final_hash_value; unsigned long cumulative_hash_value; struct move { unsigned char move[-1]; enum MoveClass { PAWN_MOVE=0, PAWN_MOVE_WITH_PROMOTION=1, ENPASSANT_PAWN_MOVE=2, PIECE_MOVE=3, KINGSIDE_CASTLE=4, QUEENSIDE_CASTLE=5, UNKNOWN_MOVE=6 } class; char from_col; char from_rank; char to_col; char to_rank; enum Piece { OFF=0, EMPTY=1, PAWN=2, KNIGHT=3, BISHOP=4, ROOK=5, QUEEN=6, KING=7, NUM_PIECE_VALUES=8 } piece_to_move; enum Piece { OFF=0, EMPTY=1, PAWN=2, KNIGHT=3, BISHOP=4, ROOK=5, QUEEN=6, KING=7, NUM_PIECE_VALUES=8 } captured_piece; enum Piece { OFF=0, EMPTY=1, PAWN=2, KNIGHT=3, BISHOP=4, ROOK=5, QUEEN=6, KING=7, NUM_PIECE_VALUES=8 } promoted_piece; enum CheckStatus { NOCHECK=0, CHECK=1, CHECKMATE=2 } check_status; char *epd; struct string_list *Nags; struct comment_list *Comment; char *terminating_result; struct variation { struct comment_list *prefix_comment; struct move *moves; struct comment_list *suffix_comment; struct variation *next; } *Variants; struct move *prev; } *moves; enum Boolean { FALSE=0, TRUE=1 } moves_checked; enum Boolean { FALSE=0, TRUE=1 } moves_ok; }

variable_types:
ix
unsigned int

variable_types: struct HashLog { unsigned long combined_hash_value; int file_number; struct HashLog *next; } *

variable_types:
duplicate
enum Boolean { FALSE=0, TRUE=1 }

return_type: char *

user_defined_types: struct Game { char **tags; int tags_length; struct comment_list *prefix_comment; unsigned long final_hash_value; unsigned long cumulative_hash_value; struct move *moves; enum Boolean moves_checked; enum Boolean moves_ok; }

user_defined_types: struct comment_list { struct string_list *Comment; struct comment_list *next; }

user_defined_types: struct move { unsigned char move[-1]; enum MoveClass class; char from_col; char from_rank; char to_col; char to_rank; enum Piece piece_to_move; enum Piece captured_piece; enum Piece promoted_piece; enum CheckStatus check_status; char *epd; struct string_list *Nags; struct comment_list *Comment; char *terminating_result; struct variation *Variants; struct move *prev; }


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

result = 1LL;
if ( (a1 & 0xDF) != 88 )
result = (a1 == 45) | (unsigned __int8)(a1 == 58);
return result;
}

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

result = 1LL;
if ( (a1 & 0xDF) != 88 )
result = (a1 == 45) | (unsigned __int8)(a1 == 58);
return result;
}

original_code:
static Boolean
is_capture(char c)
{
    return (c == 'x') || (c == 'X') || (c == ':') || (c == '-');
}

canonical_original_code:
static enum Boolean is_capture(char c)
{
    return (c == 'x') || (c == 'X') || (c == ':') || (c == '-');
}

variable_types: c char

return_type: enum Boolean { FALSE=0, TRUE=1 }


decompiled_code:
__int64 __fastcall is_castling_character(char a1)
{
return (a1 == 48) | (unsigned __int8)((a1 & 0xDF) == 79);
}

canonical_decompiled_code:
__int64 __fastcall func1(char a1)
{
return (a1 == 48) | (unsigned __int8)((a1 & 0xDF) == 79);
}

original_code:
static Boolean
is_castling_character(char c)
{
    return (c == 'O') || (c == '0') || (c == 'o');
}

canonical_original_code:
static enum Boolean is_castling_character(char c)
{
    return (c == 'O') || (c == '0') || (c == 'o');
}


decompiled_code:
_BOOL8 __fastcall is_col(char a1)
{
return (unsigned __int8)(a1 - 97) <= 7u;
}

canonical_decompiled_code:
_BOOL8 __fastcall func2(char a1)
{
return (unsigned __int8)(a1 - 97) <= 7u;
}

canonical_original_code:
enum Boolean is_col(char c)
{
    return (('a') <= c) && (c <= ('a'+8 -1));
}


decompiled_code:
_BOOL8 __fastcall is_rank(char a1)
{
return (unsigned __int8)(a1 - 49) <= 7u;
}

canonical_decompiled_code:
_BOOL8 __fastcall func3(char a1)
{
return (unsigned __int8)(a1 - 49) <= 7u;
}

canonical_original_code:
enum Boolean is_rank(char c)
{
    return (('1') <= c) && (c <= ('1'+8 -1));
}


decompiled_code:
__int64 __fastcall is_piece(_BYTE *a1)
{
__int64 result; // rax

switch ( *a1 )
{
case 0x42:
case 0x4C:
case 0x91:
result = 4LL;
break;
case 0x44:
case 0x51:
case 0x71:
case 0x94:
result = 6LL;
break;
case 0x4B:
case 0x6B:
result = 7LL;
break;
case 0x4E:
case 0x50:
case 0x53:
case 0x6E:
result = 3LL;
break;
case 0x52:
case 0x54:
case 0x72:
case 0x8B:
result = 5LL;
break;
case 0x8A:
result = 4 * (unsigned int)(a1[1] == 0xE0) + 3;
break;
default:
result = 1LL;
break;
}
return result;
}

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

switch ( *a1 )
{
case 0x42:
case 0x4C:
case 0x91:
result = 4LL;
break;
case 0x44:
case 0x51:
case 0x71:
case 0x94:
result = 6LL;
break;
case 0x4B:
case 0x6B:
result = 7LL;
break;
case 0x4E:
case 0x50:
case 0x53:
case 0x6E:
result = 3LL;
break;
case 0x52:
case 0x54:
case 0x72:
case 0x8B:
result = 5LL;
break;
case 0x8A:
result = 4 * (unsigned int)(a1[1] == 0xE0) + 3;
break;
default:
result = 1LL;
break;
}
return result;
}

original_code:
Piece
is_piece(const unsigned char *move)
{ Piece piece = EMPTY;
    switch(*move){
        case 'K': case 'k':
            piece = KING;
            break;
        case 'Q': case 'q':
        case 'D':
        case (0x0094):
            piece = QUEEN;
            break;
        case 'R': case 'r':
        case 'T':
        case (0x008b):
            piece = ROOK;
            break;
        case 'N': case 'n':
        case 'P':
        case 'S':
            piece = KNIGHT;
            break;
        case 'B':
        case 'L':
        case (0x0091):
            piece = BISHOP;
            break;
        case (0x008a):
            if(((*(move+1)) & 0x00ff) == (0x00e0)){
                piece = KING;
            }
            else{
                piece = KNIGHT;
            }
            break;
    }
    return piece;
}

canonical_original_code:
enum Piece is_piece(unsigned char *move)
{ enum Piece piece = EMPTY;
    switch(*move){
        case 'K': case 'k':
            piece = KING;
            break;
        case 'Q': case 'q':
        case 'D':
        case (0x0094):
            piece = QUEEN;
            break;
        case 'R': case 'r':
        case 'T':
        case (0x008b):
            piece = ROOK;
            break;
        case 'N': case 'n':
        case 'P':
        case 'S':
            piece = KNIGHT;
            break;
        case 'B':
        case 'L':
        case (0x0091):
            piece = BISHOP;
            break;
        case (0x008a):
            if(((*(move+1)) & 0x00ff) == (0x00e0)){
                piece = KING;
            }
            else{
                piece = KNIGHT;
            }
            break;
    }
    return piece;
}

variable_types:
move
unsigned char *

variable_types: enum Piece { OFF=0, EMPTY=1, PAWN=2, KNIGHT=3, BISHOP=4, ROOK=5, QUEEN=6, KING=7, NUM_PIECE_VALUES=8 }


decompiled_code:
_BOOL8 __fastcall is_check(char a1)
{
return (a1 & 0xF7) == 35;
}

canonical_decompiled_code:
_BOOL8 __fastcall func5(char a1)
{
return (a1 & 0xF7) == 35;
}

canonical_original_code:
enum Boolean is_check(char c)
{
    return (c == '+') || (c == '#');
}


decompiled_code:
_QWORD *new_move_structure()
{
_QWORD *result; // rax

result = (_QWORD *)MallocOrDie(96LL);
result[8] = 0LL;
result[5] = 0LL;
result[6] = 0LL;
result[7] = 0LL;
result[9] = 0LL;
result[11] = 0LL;
return result;
}

canonical_decompiled_code:
_QWORD *func6()
{
_QWORD *result; // rax

result = (_QWORD *)MallocOrDie(96LL);
result[8] = 0LL;
result[5] = 0LL;
result[6] = 0LL;
result[7] = 0LL;
result[9] = 0LL;
result[11] = 0LL;
return result;
}

original_code:
Move *
new_move_structure(void)
{ Move *move = (Move *)MallocOrDie(sizeof(Move));
    move->terminating_result = ((void *)0);
    move->epd = ((void *)0);
    move->Nags = ((void *)0);
    move->Comment = ((void *)0);
    move->Variants = ((void *)0);
    move->next = ((void *)0);
    return move;
}

canonical_original_code:
struct move *new_move_structure()
{ struct move *move = (Move *)MallocOrDie(sizeof(Move));
    move->terminating_result = ((void *)0);
    move->epd = ((void *)0);
    move->Nags = ((void *)0);
    move->Comment = ((void *)0);
    move->Variants = ((void *)0);
    move->next = ((void *)0);
    return move;
}

variable_types: struct move { unsigned char move[-1]; enum MoveClass { PAWN_MOVE=0, PAWN_MOVE_WITH_PROMOTION=1, ENPASSANT_PAWN_MOVE=2, PIECE_MOVE=3, KINGSIDE_CASTLE=4, QUEENSIDE_CASTLE=5, UNKNOWN_MOVE=6 } class; char from_col; char from_rank; char to_col; char to_rank; enum Piece { OFF=0, EMPTY=1, PAWN=2, KNIGHT=3, BISHOP=4, ROOK=5, QUEEN=6, KING=7, NUM_PIECE_VALUES=8 } piece_to_move; enum Piece { OFF=0, EMPTY=1, PAWN=2, KNIGHT=3, BISHOP=4, ROOK=5, QUEEN=6, KING=7, NUM_PIECE_VALUES=8 } captured_piece; enum Piece { OFF=0, EMPTY=1, PAWN=2, KNIGHT=3, BISHOP=4, ROOK=5, QUEEN=6, KING=7, NUM_PIECE_VALUES=8 } promoted_piece; enum CheckStatus { NOCHECK=0, CHECK=1, CHECKMATE=2 } check_status; char *epd; struct string_list { char *str; struct string_list *next; } *Nags; struct comment_list { struct string_list *Comment; struct comment_list *next; } *Comment; char *terminating_result; struct variation { struct comment_list *prefix_comment; struct move *moves; struct comment_list *suffix_comment; struct variation *next; } *Variants; struct move *prev; } *


decompiled_code:
char *__fastcall decode_move(char *src)
{
char v2; // bl
char v3; // r13
char v4; // cl
char v5; // di
char v6; // r14
char *v7; // rdx
char v8; // si
char v9; // r15
char *v10; // rdx
char *v11; // r12
char v12; // cl
char *v13; // rax
char *result; // rax
int v15; // eax
char v16; // r8
char *v17; // rcx
__int64 v18; // rcx
char v19; // r8
char v20; // di
__int64 v21; // rcx
__int64 v22; // rdx
__int64 v23; // rdx
char v24; // di
char v25; // cl
__int64 v26; // r9
int v27; // ecx
int v28; // er8
__int64 v29; // r9
char v30; // di
char *v31; // rsi
char v32; // cl
char v33; // di
__int64 v34; // rcx
__int64 v35; // rcx
__int64 v36; // rcx
__int64 v37; // rdx
__int64 v38; // rcx
__int64 v39; // rsi
__int64 v40; // rcx
char v41; // r8
char v42; // r8
char v43; // dl
char v44; // dl
int v45; // [rsp+4h] [rbp-44h]
int v46; // [rsp+8h] [rbp-40h]
char v47; // [rsp+Ch] [rbp-3Ch]
char v48; // [rsp+Ch] [rbp-3Ch]

v2 = *src;
if ( !is_col(*src) )
{
v15 = is_piece(src);
v46 = v15;
if ( v15 == 1 )
{
if ( (unsigned int)is_castling_character(v16) )
{
v30 = src[1];
v31 = src + 1;
if ( src[1] == 45 )
{
v30 = src[2];
v31 = src + 2;
}
if ( (unsigned int)is_castling_character(v30) )
{
v32 = v31[1];
v11 = v31 + 1;
if ( v32 == 45 )
{
v32 = v31[2];
v11 = v31 + 2;
}
v24 = v32;
if ( (unsigned int)is_castling_character(v32) )
{
v24 = v11[1];
v6 = 0;
++v11;
v2 = 0;
v45 = 5;
}
else
{
v45 = 4;
v6 = 0;
v2 = 0;
}
v9 = 0;
v3 = 0;
goto LABEL_26;
}
print_error_context(*((_QWORD *)&GlobalState + 23));
fprintf(*((FILE **)&GlobalState + 23), "Unknown castling move %s.\n", src);
}
else
{
print_error_context(*((_QWORD *)&GlobalState + 23));
fprintf(*((FILE **)&GlobalState + 23), "Unknown move %s.\n", src);
}
}
else
{
if ( v15 != 7 || (v17 = src + 1, v16 != -118) )
v17 = src;
v3 = v17[1];
if ( is_rank(v3) )
{
v20 = *(_BYTE *)(v18 + 2);
v6 = v20;
if ( (unsigned int)is_capture(v20) )
{
v20 = *(_BYTE *)(v21 + 3);
v6 = v20;
}
if ( is_col(v20) )
{
v47 = *(_BYTE *)(v22 + 1);
v9 = v47;
if ( is_rank(v47) )
{
v24 = *(_BYTE *)(v23 + 2);
v45 = 3;
v11 = (char *)(v23 + 2);
v2 = 0;
}
else
{
v24 = v47;
v11 = (char *)(v23 + 1);
v2 = 0;
v9 = 0;
v45 = 3;
}
goto LABEL_26;
}
v6 = 0;
v2 = 0;
v9 = 0;
print_error_context(*((_QWORD *)&GlobalState + 23));
fprintf(*((FILE **)&GlobalState + 23), "Unknown piece move %s.\n", src);
v45 = 6;
goto LABEL_14;
}
v33 = v19;
if ( (unsigned int)is_capture(v19) )
{
v6 = *(_BYTE *)(v34 + 2);
if ( is_col(v6) )
{
v9 = *(_BYTE *)(v35 + 3);
if ( is_rank(v9) )
{
v24 = *(_BYTE *)(v36 + 4);
v11 = (char *)(v36 + 4);
v2 = 0;
v3 = 0;
v45 = 3;
goto LABEL_26;
}
v2 = 0;
v9 = 0;
v3 = 0;
print_error_context(*((_QWORD *)&GlobalState + 23));
fprintf(*((FILE **)&GlobalState + 23), "Unknown piece move %s.\n", src);
v45 = 6;
goto LABEL_14;
}
}
else if ( is_col(v33) )
{
v39 = v38 + 2;
v9 = *(_BYTE *)(v38 + 2);
if ( (unsigned int)is_capture(v9) )
{
v41 = *(_BYTE *)(v40 + 3);
v39 = v40 + 3;
v9 = v41;
}
if ( is_rank(v41) )
{
v24 = *(_BYTE *)(v39 + 1);
v11 = (char *)(v39 + 1);
v6 = v24;
if ( (unsigned int)is_capture(v24) )
{
v24 = *(_BYTE *)(v39 + 2);
v11 = (char *)(v39 + 2);
v6 = v24;
}
if ( !is_col(v24) )
{
v6 = v3;
v45 = 3;
v2 = 0;
v3 = 0;
goto LABEL_26;
}
if ( is_rank(v11[1]) )
{
v24 = v11[2];
v2 = v3;
v11 += 2;
v3 = v9;
v45 = 3;
v9 = v43;
goto LABEL_26;
}
v2 = v3;
v3 = v9;
v9 = 0;
print_error_context(*((_QWORD *)&GlobalState + 23));
fprintf(*((FILE **)&GlobalState + 23), "Unknown piece move %s.\n", src);
v45 = 6;
goto LABEL_14;
}
if ( is_col(v42) )
{
v48 = *(_BYTE *)(v39 + 1);
if ( is_rank(v48) )
{
v24 = *(_BYTE *)(v39 + 2);
v6 = v9;
v2 = v3;
v11 = (char *)(v39 + 2);
v45 = 3;
v9 = v44;
}
else
{
v6 = v9;
v2 = v3;
v24 = v48;
v11 = (char *)(v39 + 1);
v45 = 3;
v9 = 0;
}
v3 = 0;
goto LABEL_26;
}
}
print_error_context(*((_QWORD *)&GlobalState + 23));
fprintf(*((FILE **)&GlobalState + 23), "Unknown piece move %s.\n", src);
}
goto LABEL_60;
}
v3 = src[1];
if ( !is_rank(v3) )
{
if ( (unsigned int)is_capture(v4) )
v25 = src[2];
v6 = v25;
if ( is_col(v25) )
{
v9 = *(_BYTE *)(v26 + 1);
v8 = v9;
if ( is_rank(v9) )
{
v7 = (char *)(v29 + 2);
if ( v2 != 98 && v28 != v27 + 1 && v28 != v27 - 1 )
{
v46 = 2;
v3 = 0;
v45 = 6;
goto LABEL_14;
}
v8 = *(_BYTE *)(v29 + 2);
v3 = 0;
}
else
{
if ( v28 != v27 + 1 && v28 != v27 - 1 )
{
v46 = 2;
v9 = 0;
v3 = 0;
v45 = 6;
goto LABEL_14;
}
v9 = 0;
v3 = 0;
}
goto LABEL_6;
}
print_error_context(*((_QWORD *)&GlobalState + 23));
fprintf(*((FILE **)&GlobalState + 23), "Unknown pawn move %s.\n", src);
v46 = 2;
LABEL_60:
v45 = 6;
v6 = 0;
v2 = 0;
v9 = 0;
v3 = 0;
goto LABEL_14;
}
v5 = src[2];
v6 = v5;
if ( (unsigned int)is_capture(src[2]) )
{
v6 = src[3];
if ( !is_col(v6) )
goto LABEL_5;
LABEL_50:
v8 = v7[1];
v9 = v8;
if ( is_rank(v8) )
{
v8 = *(_BYTE *)(v37 + 2);
v7 = (char *)(v37 + 2);
}
else
{
v7 = (char *)(v37 + 1);
v9 = 0;
}
goto LABEL_6;
}
if ( is_col(v5) )
goto LABEL_50;
LABEL_5:
v8 = *v7;
v6 = v2;
v9 = v3;
v2 = 0;
v3 = 0;
LABEL_6:
if ( (unsigned int)is_piece(&v7[v8 == 61]) == 1 )
{
v24 = *v10;
v46 = 2;
v11 = v10;
v45 = 0;
goto LABEL_26;
}
v46 = 2;
v11 = v10 + 1;
v45 = 1;
if ( is_check(v10[1]) )
{
do
{
v24 = *++v11;
LABEL_26:
;
}
while ( is_check(v24) );
}
if ( v12 )
{
if ( (*v11 == 101 && v11[1] == 112 && !v11[2] || !strcmp(v11, "e.p.")) && !v45 )
{
v45 = 2;
}
else
{
print_error_context(*((_QWORD *)&GlobalState + 23));
fprintf(*((FILE **)&GlobalState + 23), "Unknown text trailing move %s <%s>.\n", src, v11);
v45 = 6;
}
}
LABEL_14:
v13 = (char *)new_move_structure();
result = strcpy(v13, src);
result[20] = v2;
*((_DWORD *)result + 4) = v45;
result[21] = v3;
*((_DWORD *)result + 6) = v46;
result[22] = v6;
result[23] = v9;
*((_DWORD *)result + 7) = 1;
*((_DWORD *)result + 9) = 0;
return result;
}

original_code:
Move *
decode_move(const unsigned char *move_string)
{
    Rank from_rank = 0, to_rank = 0;
    Col from_col = 0, to_col = 0;
    MoveClass class;
    Boolean Ok = TRUE;
    Col col = 0;
    Rank rank = 0;
    const unsigned char *move = move_string;
    Move *move_details;
    Piece piece_to_move = EMPTY;
    if(is_col(*move)){
        class = PAWN_MOVE;
        piece_to_move = PAWN;
        col = *move;
        move++;
        if(is_rank(*move)){
            rank = *move;
            move++;
            if(is_capture(*move)){
                move++;
            }
            if(is_col(*move)){
                from_col = col;
                from_rank = rank;
                to_col = *move;
                move++;
                if(is_rank(*move)){
                    to_rank = *move;
                    move++;
                }
            }
            else{
                to_col = col;
                to_rank = rank;
            }
        }
        else{
            if(is_capture(*move)){
                move++;
            }
            if(is_col(*move)){
                from_col = col;
                to_col = *move;
                move++;
                if(is_rank(*move)){
                    to_rank = *move;
                    move++;
                    if((from_col != 'b') &&
                            (from_col != (to_col+1)) && (from_col != (to_col-1))){
                        Ok = FALSE;
                    }
                }
                else{
                    if((from_col != (to_col+1)) && (from_col != (to_col-1))){
                        Ok = FALSE;
                    }
                }
            }
            else{
                print_error_context(GlobalState.logfile);
                fprintf(GlobalState.logfile,"Unknown pawn move %s.\n",move_string);
                Ok = FALSE;
            }
        }
        if(Ok){
            if(*move == '='){
                move++;
            }
            if(is_piece(move) != EMPTY){
                class = PAWN_MOVE_WITH_PROMOTION;
                move++;
            }
        }
    }
    else if((piece_to_move = is_piece(move)) != EMPTY){
        class = PIECE_MOVE;
        if((((*move) & 0x00ff) == (0x008a)) &&
                                (piece_to_move == KING)){
            move++;
        }
        move++;
        if(is_rank(*move)){
            from_rank = *move;
            move++;
            if(is_capture(*move)){
                move++;
            }
            if(is_col(*move)){
                to_col = *move;
                move++;
                if(is_rank(*move)){
                    to_rank = *move;
                    move++;
                }
            }
            else{
                Ok = FALSE;
                print_error_context(GlobalState.logfile);
                fprintf(GlobalState.logfile,"Unknown piece move %s.\n",move_string);
            }
        }
        else{
            if(is_capture(*move)){
                move++;
                if(is_col(*move)){
                    to_col = *move;
                    move++;
                    if(is_rank(*move)){
                        to_rank = *move;
                        move++;
                    }
                    else{
                        Ok = FALSE;
                        print_error_context(GlobalState.logfile);
                        fprintf(GlobalState.logfile,
                                        "Unknown piece move %s.\n",move_string);
                    }
                }
                else{
                    Ok = FALSE;
                    print_error_context(GlobalState.logfile);
                    fprintf(GlobalState.logfile,"Unknown piece move %s.\n",move_string);
                }
            }
            else if(is_col(*move)){
                col = *move;
                move++;
                if(is_capture(*move)){
                    move++;
                }
                if(is_rank(*move)){
                    rank = *move;
                    move++;
                    if(is_capture(*move)){
                        move++;
                    }
                    if(is_col(*move)){
                        from_col = col;
                        from_rank = rank;
                        to_col = *move;
                        move++;
                        if(is_rank(*move)){
                            to_rank = *move;
                            move++;
                        }
                        else{
                            Ok = FALSE;
                            print_error_context(GlobalState.logfile);
                            fprintf(GlobalState.logfile,
                                        "Unknown piece move %s.\n",move_string);
                        }
                    }
                    else{
                        to_col = col;
                        to_rank = rank;
                    }
                }
                else if(is_col(*move)){
                    from_col = col;
                    to_col = *move;
                    move++;
                    if(is_rank(*move)){
                        to_rank = *move;
                        move++;
                    }
                }
                else{
                    Ok = FALSE;
                    print_error_context(GlobalState.logfile);
                    fprintf(GlobalState.logfile,"Unknown piece move %s.\n",move_string);
                }
            }
            else{
                Ok = FALSE;
                print_error_context(GlobalState.logfile);
                fprintf(GlobalState.logfile,"Unknown piece move %s.\n",move_string);
            }
        }
    }
    else if(is_castling_character(*move)){
         move++;
         if(*move == '-'){
             move++;
         }
         if(is_castling_character(*move)){
             move++;
             if(*move == '-'){
                 move++;
             }
             if(is_castling_character(*move)){
                 class = QUEENSIDE_CASTLE;
                 move++;
             }
             else{
                 class = KINGSIDE_CASTLE;
             }
         }
         else{
             print_error_context(GlobalState.logfile);
             fprintf(GlobalState.logfile,"Unknown castling move %s.\n",move_string);
             Ok = FALSE;
         }
    }
    else{
        print_error_context(GlobalState.logfile);
        fprintf(GlobalState.logfile,"Unknown move %s.\n",move_string);
        Ok = FALSE;
    }
    if(Ok){
        while(is_check(*move)){
            move++;
        }
        if(*move == '\0'){
        }
        else if(((strcmp((const char *) move,"ep") == 0) ||
                            (strcmp((const char *) move,"e.p.") == 0)) &&
                (class == PAWN_MOVE)){
            class = ENPASSANT_PAWN_MOVE;
        }
        else{
            Ok = FALSE;
            print_error_context(GlobalState.logfile);
            fprintf(GlobalState.logfile,
                "Unknown text trailing move %s <%s>.\n",move_string,move);
        }
    }
    if(!Ok){
        class = UNKNOWN_MOVE;
    }
    move_details = new_move_structure();
    strcpy((char *) move_details->move,(const char *) move_string);
    move_details->class = class;
    move_details->piece_to_move = piece_to_move;
    move_details->from_col = from_col;
    move_details->from_rank = from_rank;
    move_details->to_col = to_col;
    move_details->to_rank = to_rank;
    move_details->captured_piece = EMPTY;
    move_details->check_status = NOCHECK;
    return move_details;
}

canonical_original_code:
struct move *decode_move(unsigned char *move_string)
{
    char from_rank = 0; char to_rank = 0;
    char from_col = 0; char to_col = 0;
    enum MoveClass class;
    enum Boolean Ok = TRUE;
    char col = 0;
    char rank = 0;
    unsigned char *move = move_string;
    struct move *move_details;
    enum Piece piece_to_move = EMPTY;
    if(is_col(*move)){
        class = PAWN_MOVE;
        piece_to_move = PAWN;
        col = *move;
        move++;
        if(is_rank(*move)){
            rank = *move;
            move++;
            if(is_capture(*move)){
                move++;
            }
            if(is_col(*move)){
                from_col = col;
                from_rank = rank;
                to_col = *move;
                move++;
                if(is_rank(*move)){
                    to_rank = *move;
                    move++;
                }
            }
            else{
                to_col = col;
                to_rank = rank;
            }
        }
        else{
            if(is_capture(*move)){
                move++;
            }
            if(is_col(*move)){
                from_col = col;
                to_col = *move;
                move++;
                if(is_rank(*move)){
                    to_rank = *move;
                    move++;
                    if((from_col != 'b') &&
                            (from_col != (to_col+1)) && (from_col != (to_col-1))){
                        Ok = FALSE;
                    }
                }
                else{
                    if((from_col != (to_col+1)) && (from_col != (to_col-1))){
                        Ok = FALSE;
                    }
                }
            }
            else{
                print_error_context(GlobalState.logfile);
                fprintf(GlobalState.logfile,"Unknown pawn move %s.\n",move_string);
                Ok = FALSE;
            }
        }
        if(Ok){
            if(*move == '='){
                move++;
            }
            if(is_piece(move) != EMPTY){
                class = PAWN_MOVE_WITH_PROMOTION;
                move++;
            }
        }
    }
    else if((piece_to_move = is_piece(move)) != EMPTY){
        class = PIECE_MOVE;
        if((((*move) & 0x00ff) == (0x008a)) &&
                                (piece_to_move == KING)){
            move++;
        }
        move++;
        if(is_rank(*move)){
            from_rank = *move;
            move++;
            if(is_capture(*move)){
                move++;
            }
            if(is_col(*move)){
                to_col = *move;
                move++;
                if(is_rank(*move)){
                    to_rank = *move;
                    move++;
                }
            }
            else{
                Ok = FALSE;
                print_error_context(GlobalState.logfile);
                fprintf(GlobalState.logfile,"Unknown piece move %s.\n",move_string);
            }
        }
        else{
            if(is_capture(*move)){
                move++;
                if(is_col(*move)){
                    to_col = *move;
                    move++;
                    if(is_rank(*move)){
                        to_rank = *move;
                        move++;
                    }
                    else{
                        Ok = FALSE;
                        print_error_context(GlobalState.logfile);
                        fprintf(GlobalState.logfile,
                                        "Unknown piece move %s.\n",move_string);
                    }
                }
                else{
                    Ok = FALSE;
                    print_error_context(GlobalState.logfile);
                    fprintf(GlobalState.logfile,"Unknown piece move %s.\n",move_string);
                }
            }
            else if(is_col(*move)){
                col = *move;
                move++;
                if(is_capture(*move)){
                    move++;
                }
                if(is_rank(*move)){
                    rank = *move;
                    move++;
                    if(is_capture(*move)){
                        move++;
                    }
                    if(is_col(*move)){
                        from_col = col;
                        from_rank = rank;
                        to_col = *move;
                        move++;
                        if(is_rank(*move)){
                            to_rank = *move;
                            move++;
                        }
                        else{
                            Ok = FALSE;
                            print_error_context(GlobalState.logfile);
                            fprintf(GlobalState.logfile,
                                        "Unknown piece move %s.\n",move_string);
                        }
                    }
                    else{
                        to_col = col;
                        to_rank = rank;
                    }
                }
                else if(is_col(*move)){
                    from_col = col;
                    to_col = *move;
                    move++;
                    if(is_rank(*move)){
                        to_rank = *move;
                        move++;
                    }
                }
                else{
                    Ok = FALSE;
                    print_error_context(GlobalState.logfile);
                    fprintf(GlobalState.logfile,"Unknown piece move %s.\n",move_string);
                }
            }
            else{
                Ok = FALSE;
                print_error_context(GlobalState.logfile);
                fprintf(GlobalState.logfile,"Unknown piece move %s.\n",move_string);
            }
        }
    }
    else if(is_castling_character(*move)){
         move++;
         if(*move == '-'){
             move++;
         }
         if(is_castling_character(*move)){
             move++;
             if(*move == '-'){
                 move++;
             }
             if(is_castling_character(*move)){
                 class = QUEENSIDE_CASTLE;
                 move++;
             }
             else{
                 class = KINGSIDE_CASTLE;
             }
         }
         else{
             print_error_context(GlobalState.logfile);
             fprintf(GlobalState.logfile,"Unknown castling move %s.\n",move_string);
             Ok = FALSE;
         }
    }
    else{
        print_error_context(GlobalState.logfile);
        fprintf(GlobalState.logfile,"Unknown move %s.\n",move_string);
        Ok = FALSE;
    }
    if(Ok){
        while(is_check(*move)){
            move++;
        }
        if(*move == '\0'){
        }
        else if(((strcmp((char *) move,"ep") == 0) ||
                            (strcmp((char *) move,"e.p.") == 0)) &&
                (class == PAWN_MOVE)){
            class = ENPASSANT_PAWN_MOVE;
        }
        else{
            Ok = FALSE;
            print_error_context(GlobalState.logfile);
            fprintf(GlobalState.logfile,
                "Unknown text trailing move %s <%s>.\n",move_string,move);
        }
    }
    if(!Ok){
        class = UNKNOWN_MOVE;
    }
    move_details = new_move_structure();
    strcpy((char *) move_details->move,(char *) move_string);
    move_details->class = class;
    move_details->piece_to_move = piece_to_move;
    move_details->from_col = from_col;
    move_details->from_rank = from_rank;
    move_details->to_col = to_col;
    move_details->to_rank = to_rank;
    move_details->captured_piece = EMPTY;
    move_details->check_status = NOCHECK;
    return move_details;
}

variable_types:
Ok
enum Boolean { FALSE=0, TRUE=1 }

variable_types: col char

variable_types: rank char

return_type: struct move { unsigned char move[-1]; enum MoveClass { PAWN_MOVE=0, PAWN_MOVE_WITH_PROMOTION=1, ENPASSANT_PAWN_MOVE=2, PIECE_MOVE=3, KINGSIDE_CASTLE=4, QUEENSIDE_CASTLE=5, UNKNOWN_MOVE=6 } class; char from_col; char from_rank; char to_col; char to_rank; enum Piece { OFF=0, EMPTY=1, PAWN=2, KNIGHT=3, BISHOP=4, ROOK=5, QUEEN=6, KING=7, NUM_PIECE_VALUES=8 } piece_to_move; enum Piece { OFF=0, EMPTY=1, PAWN=2, KNIGHT=3, BISHOP=4, ROOK=5, QUEEN=6, KING=7, NUM_PIECE_VALUES=8 } captured_piece; enum Piece { OFF=0, EMPTY=1, PAWN=2, KNIGHT=3, BISHOP=4, ROOK=5, QUEEN=6, KING=7, NUM_PIECE_VALUES=8 } promoted_piece; enum CheckStatus { NOCHECK=0, CHECK=1, CHECKMATE=2 } check_status; char *epd; struct string_list { char *str; struct string_list *next; } *Nags; struct comment_list { struct string_list *Comment; struct comment_list *next; } *Comment; char *terminating_result; struct variation { struct comment_list *prefix_comment; struct move *moves; struct comment_list *suffix_comment; struct variation *next; } *Variants; struct move *prev; } *


original_code:
Move *
decode_algebraic(Move *move_details, Board *board)
{ short from_r = ((('1') <= (move_details->from_rank)) && ((move_details->from_rank) <= ('1'+8 -1))? ((move_details->from_rank)-'1'+2):0);
    short from_c = ((('a') <= (move_details->from_col)) && ((move_details->from_col) <= ('a'+8 -1))? ((move_details->from_col)-'a'+2):0);
    Piece piece_to_move = ((board->board[from_r][from_c]) >> 3);
    if(piece_to_move != EMPTY){
        if((piece_to_move == KING) && (move_details->from_col == 'e')){
           if(move_details->to_col == 'g'){
                move_details->class = KINGSIDE_CASTLE;
            }
            else if(move_details->to_col == 'c'){
                move_details->class = QUEENSIDE_CASTLE;
            }
            else{
                move_details->class = PIECE_MOVE;
                move_details->piece_to_move = piece_to_move;
            }
        }
        else{
            if(piece_to_move == PAWN){
                move_details->class = PAWN_MOVE;
            }
            else{
                move_details->class = PIECE_MOVE;
            }
            move_details->piece_to_move = piece_to_move;
        }
        move_details->captured_piece = EMPTY;
        move_details->check_status = NOCHECK;
    }
    return move_details;
}

canonical_original_code:
struct move *decode_algebraic(struct move *move_details, struct Board *board)
{ short from_r = ((('1') <= (move_details->from_rank)) && ((move_details->from_rank) <= ('1'+8 -1))? ((move_details->from_rank)-'1'+2):0);
    short from_c = ((('a') <= (move_details->from_col)) && ((move_details->from_col) <= ('a'+8 -1))? ((move_details->from_col)-'a'+2):0);
    enum Piece piece_to_move = ((board->board[from_r][from_c]) >> 3);
    if(piece_to_move != EMPTY){
        if((piece_to_move == KING) && (move_details->from_col == 'e')){
           if(move_details->to_col == 'g'){
                move_details->class = KINGSIDE_CASTLE;
            }
            else if(move_details->to_col == 'c'){
                move_details->class = QUEENSIDE_CASTLE;
            }
            else{
                move_details->class = PIECE_MOVE;
                move_details->piece_to_move = piece_to_move;
            }
        }
        else{
            if(piece_to_move == PAWN){
                move_details->class = PAWN_MOVE;
            }
            else{
                move_details->class = PIECE_MOVE;
            }
            move_details->piece_to_move = piece_to_move;
        }
        move_details->captured_piece = EMPTY;
        move_details->check_status = NOCHECK;
    }
    return move_details;
}

variable_types: struct Board { enum Piece { OFF=0, EMPTY=1, PAWN=2, KNIGHT=3, BISHOP=4, ROOK=5, QUEEN=6, KING=7, NUM_PIECE_VALUES=8 } board[-1][-1]; enum Colour { BLACK=0, WHITE=1 } to_move; unsigned int move_number; enum Boolean { FALSE=0, TRUE=1 } WKingCastle; enum Boolean { FALSE=0, TRUE=1 } BKingCastle; char WKingCol; char WKingRank; char BKingCol; char BKingRank; enum Boolean { FALSE=0, TRUE=1 } EnPassant; char ep_rank; char ep_col; unsigned long hash_value; unsigned int halfmove_clock; } *

user_defined_types: struct Board { enum Piece board[-1][-1]; enum Colour to_move; unsigned int move_number; enum Boolean WKingCastle; enum Boolean BKingCastle; char WKingCol; char WKingRank; char BKingCol; char BKingRank; enum Boolean EnPassant; char ep_rank; char ep_col; unsigned long hash_value; unsigned int halfmove_clock; }

user_defined_types: enum MoveClass { PAWN_MOVE=0, PAWN_MOVE_WITH_PROMOTION=1, ENPASSANT_PAWN_MOVE=2, PIECE_MOVE=3, KINGSIDE_CASTLE=4, QUEENSIDE_CASTLE=5, UNKNOWN_MOVE=6 }

user_defined_types: enum CheckStatus { NOCHECK=0, CHECK=1, CHECKMATE=2 }

user_defined_types: struct string_list { char *str; struct string_list *next; }

user_defined_types: struct variation { struct comment_list *prefix_comment; struct move *moves; struct comment_list *suffix_comment; struct variation *next; }


initEcoTable

decompiled_code:
void initEcoTable()
{
if ( !EcoTable )
{
EcoTable = MallocOrDie(0x8000LL);
memset((void *)EcoTable, 0, 0x8000uLL);
}
}

canonical_decompiled_code:
void func0()
{
if ( !EcoTable )
{
EcoTable = MallocOrDie(0x8000LL);
memset((void *)EcoTable, 0, 0x8000uLL);
}
}

original_code:
void initEcoTable(void)
{
    if(EcoTable == ((void *)0)){
        int i;
        EcoTable = (EcoLog **) MallocOrDie(4096*sizeof(EcoLog *));
        for(i = 0; i < 4096; i++){
            EcoTable[i] = ((void *)0);
        }
    }
}

canonical_original_code:
void initEcoTable()
{
    if(EcoTable == ((void *)0)){
        int i;
        EcoTable = (struct EcoLog **) MallocOrDie(4096*sizeof(struct EcoLog *));
        for(i = 0; i < 4096; i++){
            EcoTable[i] = ((void *)0);
        }
    }
}

variable_types: i int

return_type: void

user_defined_types: struct EcoLog { unsigned long required_hash_value; unsigned long cumulative_hash_value; int half_moves; char *ECO_tag; char *Opening_tag; char *Variation_tag; char *Sub_Variation_tag; struct EcoLog *next; }


original_code:
void
save_eco_details(Game game_details,unsigned number_of_half_moves)
{ unsigned ix = game_details.final_hash_value % 4096;
    EcoLog *entry = ((void *)0);
    Boolean can_save = TRUE;
    static EcoLog *last_entry = ((void *)0);
    for(entry = EcoTable[ix]; (entry != ((void *)0)) && can_save; entry = entry->next){
        if((entry->required_hash_value == game_details.final_hash_value) &&
            (entry->half_moves == number_of_half_moves) &&
            (entry->cumulative_hash_value == game_details.cumulative_hash_value)){
            const char *tag = entry->ECO_tag,
                       *opening = entry->Opening_tag,
                       *variation = entry->Variation_tag;
            if(tag == ((void *)0)){
                tag = "";
            }
            if(opening == ((void *)0)){
                opening = "";
            }
            if(variation == ((void *)0)){
                variation = "";
            }
            fprintf(GlobalState.logfile,"ECO hash collision of ");
            fprintf(GlobalState.logfile,"%s %s %s",tag,opening,variation);
            fprintf(GlobalState.logfile," against ");
            tag = game_details.tags[ECO_TAG];
            opening = game_details.tags[OPENING_TAG];
            variation = game_details.tags[VARIATION_TAG];
            if(tag == ((void *)0)){
                tag = "";
            }
            if(opening == ((void *)0)){
                opening = "";
            }
            if(variation == ((void *)0)){
                variation = "";
            }
            fprintf(GlobalState.logfile,"%s %s %s\n",tag,opening,variation);
            fprintf(GlobalState.logfile,"Possible duplicate move sequences.\n");
            can_save = FALSE;
        }
    }
    if(can_save){
        entry = (EcoLog *)MallocOrDie(sizeof(*entry));
        entry->required_hash_value = game_details.final_hash_value;
        entry->cumulative_hash_value = game_details.cumulative_hash_value;
        entry->half_moves = number_of_half_moves;
        if(number_of_half_moves+6 > maximum_half_moves){
            maximum_half_moves = number_of_half_moves+6;
        }
        if(game_details.tags[ECO_TAG] != ((void *)0)){
            if((last_entry != ((void *)0)) && (last_entry->ECO_tag != ((void *)0)) &&
                    (strcmp(last_entry->ECO_tag,game_details.tags[ECO_TAG]) == 0)){
                entry->ECO_tag = last_entry->ECO_tag;
            }
            else{
                entry->ECO_tag = StringCopy(game_details.tags[ECO_TAG]);
            }
        }
        else{
            entry->ECO_tag = ((void *)0);
        }
        if(game_details.tags[OPENING_TAG] != ((void *)0)){
            if((last_entry != ((void *)0)) && (last_entry->Opening_tag != ((void *)0)) &&
                    (strcmp(last_entry->Opening_tag,
                                        game_details.tags[OPENING_TAG]) == 0)){
                entry->Opening_tag = last_entry->Opening_tag;
            }
            else{
                entry->Opening_tag = StringCopy(game_details.tags[OPENING_TAG]);
            }
        }
        else{
            entry->Opening_tag = ((void *)0);
        }
        if(game_details.tags[VARIATION_TAG] != ((void *)0)){
            entry->Variation_tag = StringCopy(game_details.tags[VARIATION_TAG]);
        }
        else{
            entry->Variation_tag = ((void *)0);
        }
        if(game_details.tags[SUB_VARIATION_TAG] != ((void *)0)){
            entry->Sub_Variation_tag =
                        StringCopy(game_details.tags[SUB_VARIATION_TAG]);
        }
        else{
            entry->Sub_Variation_tag = ((void *)0);
        }
        entry->next = EcoTable[ix];
        EcoTable[ix] = entry;
        last_entry = entry;
    }
}

canonical_original_code:
void save_eco_details(struct Game game_details, unsigned int number_of_half_moves)
{ unsigned int ix = game_details.final_hash_value % 4096;
    struct EcoLog *entry = ((void *)0);
    enum Boolean can_save = TRUE;
    static struct EcoLog *last_entry = ((void *)0);
    for(entry = EcoTable[ix]; (entry != ((void *)0)) && can_save; entry = entry->next){
        if((entry->required_hash_value == game_details.final_hash_value) &&
            (entry->half_moves == number_of_half_moves) &&
            (entry->cumulative_hash_value == game_details.cumulative_hash_value)){
            char *tag = entry->ECO_tag; char *opening = entry->Opening_tag; char *variation = entry->Variation_tag;
            if(tag == ((void *)0)){
                tag = "";
            }
            if(opening == ((void *)0)){
                opening = "";
            }
            if(variation == ((void *)0)){
                variation = "";
            }
            fprintf(GlobalState.logfile,"ECO hash collision of ");
            fprintf(GlobalState.logfile,"%s %s %s",tag,opening,variation);
            fprintf(GlobalState.logfile," against ");
            tag = game_details.tags[ECO_TAG];
            opening = game_details.tags[OPENING_TAG];
            variation = game_details.tags[VARIATION_TAG];
            if(tag == ((void *)0)){
                tag = "";
            }
            if(opening == ((void *)0)){
                opening = "";
            }
            if(variation == ((void *)0)){
                variation = "";
            }
            fprintf(GlobalState.logfile,"%s %s %s\n",tag,opening,variation);
            fprintf(GlobalState.logfile,"Possible duplicate move sequences.\n");
            can_save = FALSE;
        }
    }
    if(can_save){
        entry = (struct EcoLog *)MallocOrDie(sizeof(*entry));
        entry->required_hash_value = game_details.final_hash_value;
        entry->cumulative_hash_value = game_details.cumulative_hash_value;
        entry->half_moves = number_of_half_moves;
        if(number_of_half_moves+6 > maximum_half_moves){
            maximum_half_moves = number_of_half_moves+6;
        }
        if(game_details.tags[ECO_TAG] != ((void *)0)){
            if((last_entry != ((void *)0)) && (last_entry->ECO_tag != ((void *)0)) &&
                    (strcmp(last_entry->ECO_tag,game_details.tags[ECO_TAG]) == 0)){
                entry->ECO_tag = last_entry->ECO_tag;
            }
            else{
                entry->ECO_tag = StringCopy(game_details.tags[ECO_TAG]);
            }
        }
        else{
            entry->ECO_tag = ((void *)0);
        }
        if(game_details.tags[OPENING_TAG] != ((void *)0)){
            if((last_entry != ((void *)0)) && (last_entry->Opening_tag != ((void *)0)) &&
                    (strcmp(last_entry->Opening_tag,
                                        game_details.tags[OPENING_TAG]) == 0)){
                entry->Opening_tag = last_entry->Opening_tag;
            }
            else{
                entry->Opening_tag = StringCopy(game_details.tags[OPENING_TAG]);
            }
        }
        else{
            entry->Opening_tag = ((void *)0);
        }
        if(game_details.tags[VARIATION_TAG] != ((void *)0)){
            entry->Variation_tag = StringCopy(game_details.tags[VARIATION_TAG]);
        }
        else{
            entry->Variation_tag = ((void *)0);
        }
        if(game_details.tags[SUB_VARIATION_TAG] != ((void *)0)){
            entry->Sub_Variation_tag =
                        StringCopy(game_details.tags[SUB_VARIATION_TAG]);
        }
        else{
            entry->Sub_Variation_tag = ((void *)0);
        }
        entry->next = EcoTable[ix];
        EcoTable[ix] = entry;
        last_entry = entry;
    }
}

variable_types: struct EcoLog { unsigned long required_hash_value; unsigned long cumulative_hash_value; int half_moves; char *ECO_tag; char *Opening_tag; char *Variation_tag; char *Sub_Variation_tag; struct EcoLog *next; } *

variable_types:
tag
char *

variable_types:
opening
char *

variable_types:
variation
char *

user_defined_types: enum Piece { OFF=0, EMPTY=1, PAWN=2, KNIGHT=3, BISHOP=4, ROOK=5, QUEEN=6, KING=7, NUM_PIECE_VALUES=8 }


decompiled_code:
__int64 __fastcall eco_matches(__int64 a1, __int64 a2, unsigned int a3)
{
__int64 v3; // r8
__int64 v5; // rax
int v6; // edx

v3 = 0LL;
if ( maximum_half_moves >= a3 )
{
v5 = *(_QWORD *)(EcoTable + 8 * (a1 & 0xFFF));
if ( v5 )
{
while ( 1 )
{
if ( *(_QWORD *)v5 != a1 )
goto LABEL_4;
v6 = *(_DWORD *)(v5 + 16);
if ( v6 == a3 )
{
v3 = v5;
if ( *(_QWORD *)(v5 + 8) == a2 )
return v3;
LABEL_4:
v5 = *(_QWORD *)(v5 + 56);
if ( !v5 )
return v3;
}
else
{
if ( a3 + 6 - v6 <= 0xC )
v3 = v5;
v5 = *(_QWORD *)(v5 + 56);
if ( !v5 )
return v3;
}
}
}
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __int64 a2, unsigned int a3)
{
__int64 v3; // r8
__int64 v5; // rax
int v6; // edx

v3 = 0LL;
if ( maximum_half_moves >= a3 )
{
v5 = *(_QWORD *)(EcoTable + 8 * (a1 & 0xFFF));
if ( v5 )
{
while ( 1 )
{
if ( *(_QWORD *)v5 != a1 )
goto LABEL_4;
v6 = *(_DWORD *)(v5 + 16);
if ( v6 == a3 )
{
v3 = v5;
if ( *(_QWORD *)(v5 + 8) == a2 )
return v3;
LABEL_4:
v5 = *(_QWORD *)(v5 + 56);
if ( !v5 )
return v3;
}
else
{
if ( a3 + 6 - v6 <= 0xC )
v3 = v5;
v5 = *(_QWORD *)(v5 + 56);
if ( !v5 )
return v3;
}
}
}
}
return v3;
}

original_code:
EcoLog *
eco_matches(HashCode current_hash_value, HashCode cumulative_hash_value,
            unsigned half_moves_played)
{
    EcoLog *possible = ((void *)0);
    if(half_moves_played <= maximum_half_moves){
        unsigned ix = current_hash_value % 4096;
        EcoLog *entry;
        for(entry = EcoTable[ix]; entry != ((void *)0); entry = entry->next){
            if(entry->required_hash_value == current_hash_value){
                if(half_moves_played == entry->half_moves &&
                       entry->cumulative_hash_value == cumulative_hash_value){
                    return entry;
                }
                else if(abs(half_moves_played-entry->half_moves) <=
                            6){
                        possible = entry;
                }
                else{
                }
            }
        }
    }
    return possible;
}

canonical_original_code:
struct EcoLog *eco_matches(unsigned long current_hash_value, unsigned long cumulative_hash_value, unsigned int half_moves_played)
{
    struct EcoLog *possible = ((void *)0);
    if(half_moves_played <= maximum_half_moves){
        unsigned int ix = current_hash_value % 4096;
        struct EcoLog *entry;
        for(entry = EcoTable[ix]; entry != ((void *)0); entry = entry->next){
            if(entry->required_hash_value == current_hash_value){
                if(half_moves_played == entry->half_moves &&
                       entry->cumulative_hash_value == cumulative_hash_value){
                    return entry;
                }
                else if(abs(half_moves_played-entry->half_moves) <=
                            6){
                        possible = entry;
                }
                else{
                }
            }
        }
    }
    return possible;
}

return_type: struct EcoLog { unsigned long required_hash_value; unsigned long cumulative_hash_value; int half_moves; char *ECO_tag; char *Opening_tag; char *Variation_tag; char *Sub_Variation_tag; struct EcoLog *next; } *


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

switch ( a1 )
{
case 0:
case 1:
case 11:
case 19:
case 25:
case 34:
result = 1LL;
break;
default:
result = 0LL;
break;
}
return result;
}

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

switch ( a1 )
{
case 0:
case 1:
case 11:
case 19:
case 25:
case 34:
result = 1LL;
break;
default:
result = 0LL;
break;
}
return result;
}

original_code:
static Boolean
soundex_tag(int tag)
{ Boolean use_soundex = FALSE;
    switch(tag){
        case WHITE_TAG:
        case BLACK_TAG:
        case PSEUDO_PLAYER_TAG:
        case EVENT_TAG:
        case SITE_TAG:
        case ANNOTATOR_TAG:
            use_soundex = TRUE;
            break;
    }
    return use_soundex;
}

canonical_original_code:
static enum Boolean soundex_tag(int tag)
{ enum Boolean use_soundex = FALSE;
    switch(tag){
        case WHITE_TAG:
        case BLACK_TAG:
        case PSEUDO_PLAYER_TAG:
        case EVENT_TAG:
        case SITE_TAG:
        case ANNOTATOR_TAG:
            use_soundex = TRUE;
            break;
    }
    return use_soundex;
}

variable_types: tag int


soundex

original_code:
static char *
soundex(const char *str)
{ static char sbuf[50 +1];
    unsigned sindex = 0;
    char lastc = ' ';
    const char *mapping = "01230120002455012622011202";
    char initial_letter = *str;
    if(((*__ctype_b_loc ())[(int) (((int) initial_letter))] & (unsigned short int) _ISlower)){
        initial_letter = toupper(initial_letter);
    }
    if((initial_letter == 'Y') || (initial_letter == 'J')){
          sbuf[sindex] = '7';
          str++;
          sindex++;
    }
    while((*str != '\0') && (sindex < 50)){
        char ch = *str;
        if(((*__ctype_b_loc ())[(int) (((int) ch))] & (unsigned short int) _ISalpha) && (ch != lastc)){
             char translation;
             if(((*__ctype_b_loc ())[(int) (((int) ch))] & (unsigned short int) _ISlower)){
                 ch = toupper(ch);
             }
             translation = mapping[ch - 'A'];
             if((translation != '0') && (translation != lastc)){
                sbuf[sindex] = translation;
                sindex++;
                lastc = translation;
             }
        }
        str++;
    }
    sbuf[sindex] = '\0';
    return(sbuf);
}

canonical_original_code:
static char *soundex(char *str)
{ static char sbuf[-1];
    unsigned int sindex = 0;
    char lastc = ' ';
    char *mapping = "01230120002455012622011202";
    char initial_letter = *str;
    if(((*__ctype_b_loc ())[(int) (((int) initial_letter))] & (unsigned short) _ISlower)){
        initial_letter = toupper(initial_letter);
    }
    if((initial_letter == 'Y') || (initial_letter == 'J')){
          sbuf[sindex] = '7';
          str++;
          sindex++;
    }
    while((*str != '\0') && (sindex < 50)){
        char ch = *str;
        if(((*__ctype_b_loc ())[(int) (((int) ch))] & (unsigned short) _ISalpha) && (ch != lastc)){
             char translation;
             if(((*__ctype_b_loc ())[(int) (((int) ch))] & (unsigned short) _ISlower)){
                 ch = toupper(ch);
             }
             translation = mapping[ch - 'A'];
             if((translation != '0') && (translation != lastc)){
                sbuf[sindex] = translation;
                sindex++;
                lastc = translation;
             }
        }
        str++;
    }
    sbuf[sindex] = '\0';
    return(sbuf);
}

variable_types:
str
char *

variable_types:
sbuf
char [-1]

variable_types:
sindex
unsigned int

variable_types: lastc char

variable_types:
mapping
char *

variable_types: ch char

variable_types: translation char


original_code:
static int
add_to_taglist(const char *str,StringArray *list)
{ Boolean everything_ok = TRUE;
    if(list->num_allocated_elements == list->num_used_elements){
        if(list->num_allocated_elements == 0){
            list->tag_strings = (TagSelection *)MallocOrDie((10 +1)*
                                                sizeof(TagSelection));
            if(list->tag_strings != ((void *)0)){
                list->num_allocated_elements = 10;
                list->num_used_elements = 0;
            }
            else{
                everything_ok = FALSE;
            }
        }
        else{
            list->tag_strings = (TagSelection *)realloc((void *)list->tag_strings,
                                (list->num_allocated_elements+5 +1)*
                                                        sizeof(TagSelection));
            if(list->tag_strings != ((void *)0)){
                list->num_allocated_elements += 5;
            }
            else{
                everything_ok = FALSE;
            }
        }
    }
    if(everything_ok){
        unsigned ix = list->num_used_elements;
        list->tag_strings[ix].operator = NONE;
        list->tag_strings[ix].tag_string = (char *) MallocOrDie(strlen(str)+1);
        if(list->tag_strings[ix].tag_string != ((void *)0)){
            strcpy(list->tag_strings[ix].tag_string,str);
            list->num_used_elements++;
            list->tag_strings[ix+1].tag_string = ((void *)0);
            return (int) ix;
        }
        else{
            return -1;
        }
    }
    else{
        return -1;
    }
}

canonical_original_code:
static int add_to_taglist(char *str, struct StringArray *list)
{ enum Boolean everything_ok = TRUE;
    if(list->num_allocated_elements == list->num_used_elements){
        if(list->num_allocated_elements == 0){
            list->tag_strings = (struct TagSelection *)MallocOrDie((10 +1)*
                                                sizeof(TagSelection));
            if(list->tag_strings != ((void *)0)){
                list->num_allocated_elements = 10;
                list->num_used_elements = 0;
            }
            else{
                everything_ok = FALSE;
            }
        }
        else{
            list->tag_strings = (struct TagSelection *)realloc((void *)list->tag_strings,
                                (list->num_allocated_elements+5 +1)*
                                                        sizeof(TagSelection));
            if(list->tag_strings != ((void *)0)){
                list->num_allocated_elements += 5;
            }
            else{
                everything_ok = FALSE;
            }
        }
    }
    if(everything_ok){
        unsigned int ix = list->num_used_elements;
        list->tag_strings[ix].operator = NONE;
        list->tag_strings[ix].tag_string = (char *) MallocOrDie(strlen(str)+1);
        if(list->tag_strings[ix].tag_string != ((void *)0)){
            strcpy(list->tag_strings[ix].tag_string,str);
            list->num_used_elements++;
            list->tag_strings[ix+1].tag_string = ((void *)0);
            return (int) ix;
        }
        else{
            return -1;
        }
    }
    else{
        return -1;
    }
}

variable_types: struct StringArray { unsigned int num_allocated_elements; unsigned int num_used_elements; struct TagSelection { char *tag_string; enum TagOperator { NONE=0, LESS_THAN=1, GREATER_THAN=2, EQUAL_TO=3, NOT_EQUAL_TO=4, LESS_THAN_OR_EQUAL_TO=5, GREATER_THAN_OR_EQUAL_TO=6 } operator; } *tag_strings; } *

variable_types:
ix
unsigned int

return_type: int

user_defined_types: struct StringArray { unsigned int num_allocated_elements; unsigned int num_used_elements; struct TagSelection *tag_strings; }

user_defined_types: struct TagSelection { char *tag_string; enum TagOperator operator; }


CheckDate

decompiled_code:
_BOOL8 __fastcall CheckDate(char *s1, __int64 a2)
{
unsigned int i; // er13
int v3; // er14
size_t v4; // rax
_BOOL8 result; // rax
const char **v6; // rax
const char *v7; // rbp
char v8; // dl
unsigned int v9; // [rsp+0h] [rbp-30h] BYREF
unsigned int v10; // [rsp+4h] [rbp-2Ch] BYREF

if ( !*(_DWORD *)(a2 + 4) )
return 1LL;
for ( i = 1; ; ++i )
{
v6 = (const char **)(*(_QWORD *)(a2 + 8) + 16LL * (i - 1));
v7 = *v6;
v8 = **v6;
if ( v8 == 98 )
{
++v7;
v3 = 1;
}
else if ( v8 == 97 )
{
++v7;
v3 = 2;
}
else
{
v3 = *((_DWORD *)v6 + 2);
if ( !v3 )
{
v4 = strlen(*v6);
result = strncmp(s1, v7, v4) == 0;
LABEL_6:
if ( *(_DWORD *)(a2 + 4) <= i || !result )
return result;
continue;
}
}
if ( (unsigned int)_isoc99_sscanf(v7, "%u", &v10) == 1 && (unsigned int)_isoc99_sscanf(s1, "%u", &v9) == 1 )
break;
if ( *(_DWORD *)(a2 + 4) <= i )
return 1LL;
LABEL_8:
;
}
if ( v9 - 101 <= 0xB52 )
{
switch ( v3 )
{
case 1:
result = v9 < v10;
goto LABEL_6;
case 2:
result = v9 > v10;
goto LABEL_6;
case 3:
result = v10 == v9;
goto LABEL_6;
case 4:
result = v10 != v9;
goto LABEL_6;
case 5:
result = v9 <= v10;
goto LABEL_6;
case 6:
result = v9 >= v10;
goto LABEL_6;
default:
break;
}
}
if ( i < *(_DWORD *)(a2 + 4) )
goto LABEL_8;
return 1LL;
}

canonical_decompiled_code:
_BOOL8 __fastcall func3(char *s1, __int64 a2)
{
unsigned int i; // er13
int v3; // er14
size_t v4; // rax
_BOOL8 result; // rax
const char **v6; // rax
const char *v7; // rbp
char v8; // dl
unsigned int v9; // [rsp+0h] [rbp-30h] BYREF
unsigned int v10; // [rsp+4h] [rbp-2Ch] BYREF

if ( !*(_DWORD *)(a2 + 4) )
return 1LL;
for ( i = 1; ; ++i )
{
v6 = (const char **)(*(_QWORD *)(a2 + 8) + 16LL * (i - 1));
v7 = *v6;
v8 = **v6;
if ( v8 == 98 )
{
++v7;
v3 = 1;
}
else if ( v8 == 97 )
{
++v7;
v3 = 2;
}
else
{
v3 = *((_DWORD *)v6 + 2);
if ( !v3 )
{
v4 = strlen(*v6);
result = strncmp(s1, v7, v4) == 0;
LABEL_6:
if ( *(_DWORD *)(a2 + 4) <= i || !result )
return result;
continue;
}
}
if ( (unsigned int)_isoc99_sscanf(v7, "%u", &v10) == 1 && (unsigned int)_isoc99_sscanf(s1, "%u", &v9) == 1 )
break;
if ( *(_DWORD *)(a2 + 4) <= i )
return 1LL;
LABEL_8:
;
}
if ( v9 - 101 <= 0xB52 )
{
switch ( v3 )
{
case 1:
result = v9 < v10;
goto LABEL_6;
case 2:
result = v9 > v10;
goto LABEL_6;
case 3:
result = v10 == v9;
goto LABEL_6;
case 4:
result = v10 != v9;
goto LABEL_6;
case 5:
result = v9 <= v10;
goto LABEL_6;
case 6:
result = v9 >= v10;
goto LABEL_6;
default:
break;
}
}
if ( i < *(_DWORD *)(a2 + 4) )
goto LABEL_8;
return 1LL;
}

original_code:
static Boolean
CheckDate(const char *date_string,StringArray *list)
{ unsigned list_index;
    Boolean wanted = TRUE;
    for(list_index = 0; (list_index < list->num_used_elements) && wanted;
                                list_index++){
        const char *list_string = list->tag_strings[list_index].tag_string;
        TagOperator operator = list->tag_strings[list_index].operator;
        if(*list_string == 'b'){
            operator = LESS_THAN;
            list_string++;
        }
        else if(*list_string == 'a'){
            operator = GREATER_THAN;
            list_string++;
        }
        else{
        }
        if(operator != NONE){
            unsigned game_date, list_date;
            if((sscanf(list_string,"%u",&list_date) == 1) &&
                  (sscanf(date_string,"%u",&game_date) == 1) &&
                  (game_date > 100) && (game_date < 3000)){
                switch(operator){
                    case LESS_THAN:
                        wanted = game_date < list_date;
                        break;
                    case LESS_THAN_OR_EQUAL_TO:
                        wanted = game_date <= list_date;
                        break;
                    case GREATER_THAN:
                        wanted = game_date > list_date;
                        break;
                    case GREATER_THAN_OR_EQUAL_TO:
                        wanted = game_date >= list_date;
                        break;
                    case EQUAL_TO:
                        wanted = game_date == list_date;
                        break;
                    case NOT_EQUAL_TO:
                        wanted = game_date != list_date;
                        break;
                    case NONE:
                        break;
                }
            }
            else{
            }
        }
        else{
            wanted = strncmp(date_string,list_string,strlen(list_string)) == 0;
        }
    }
    return wanted;
}

canonical_original_code:
static enum Boolean CheckDate(char *date_string, struct StringArray *list)
{ unsigned int list_index;
    enum Boolean wanted = TRUE;
    for(list_index = 0; (list_index < list->num_used_elements) && wanted;
                                list_index++){
        char *list_string = list->tag_strings[list_index].tag_string;
        enum TagOperator operator = list->tag_strings[list_index].operator;
        if(*list_string == 'b'){
            operator = LESS_THAN;
            list_string++;
        }
        else if(*list_string == 'a'){
            operator = GREATER_THAN;
            list_string++;
        }
        else{
        }
        if(operator != NONE){
            unsigned int game_date; unsigned int list_date;
            if((sscanf(list_string,"%u",&list_date) == 1) &&
                  (sscanf(date_string,"%u",&game_date) == 1) &&
                  (game_date > 100) && (game_date < 3000)){
                switch(operator){
                    case LESS_THAN:
                        wanted = game_date < list_date;
                        break;
                    case LESS_THAN_OR_EQUAL_TO:
                        wanted = game_date <= list_date;
                        break;
                    case GREATER_THAN:
                        wanted = game_date > list_date;
                        break;
                    case GREATER_THAN_OR_EQUAL_TO:
                        wanted = game_date >= list_date;
                        break;
                    case EQUAL_TO:
                        wanted = game_date == list_date;
                        break;
                    case NOT_EQUAL_TO:
                        wanted = game_date != list_date;
                        break;
                    case NONE:
                        break;
                }
            }
            else{
            }
        }
        else{
            wanted = strncmp(date_string,list_string,strlen(list_string)) == 0;
        }
    }
    return wanted;
}

variable_types:
wanted
enum Boolean { FALSE=0, TRUE=1 }

variable_types: enum TagOperator { NONE=0, LESS_THAN=1, GREATER_THAN=2, EQUAL_TO=3, NOT_EQUAL_TO=4, LESS_THAN_OR_EQUAL_TO=5, GREATER_THAN_OR_EQUAL_TO=6 }


CheckElo

decompiled_code:
_BOOL8 __fastcall CheckElo(__int64 a1, __int64 a2)
{
unsigned int v2; // er13
__int64 v3; // rbp
__int64 v4; // rax
int v5; // er15
_BOOL8 result; // rax
unsigned int v7; // edx
unsigned int v8; // [rsp+0h] [rbp-40h] BYREF
unsigned int v9; // [rsp+4h] [rbp-3Ch] BYREF

if ( !*(_DWORD *)(a2 + 4) )
return 1LL;
v2 = 0;
v3 = *(_QWORD *)(a2 + 8);
while ( 1 )
{
while ( 1 )
{
v4 = v3 + 16LL * v2;
v5 = *(_DWORD *)(v4 + 8);
if ( v5 )
break;
if ( ++v2 >= *(_DWORD *)(a2 + 4) )
return 1LL;
}
if ( (unsigned int)_isoc99_sscanf(*(_QWORD *)v4, "%u", &v9) != 1 || (unsigned int)_isoc99_sscanf(a1, "%u", &v8) != 1 )
return 0LL;
v7 = *(_DWORD *)(a2 + 4);
++v2;
switch ( v5 )
{
case 1:
result = v8 < v9;
goto LABEL_12;
case 2:
result = v8 > v9;
goto LABEL_12;
case 3:
result = v8 == v9;
goto LABEL_12;
case 4:
result = v8 != v9;
goto LABEL_12;
case 5:
result = v8 <= v9;
goto LABEL_12;
case 6:
result = v8 >= v9;
LABEL_12:
if ( v7 > v2 && result )
goto LABEL_14;
return result;
default:
if ( v7 <= v2 )
return 1LL;
LABEL_14:
v3 = *(_QWORD *)(a2 + 8);
break;
}
}
}

canonical_decompiled_code:
_BOOL8 __fastcall func4(__int64 a1, __int64 a2)
{
unsigned int v2; // er13
__int64 v3; // rbp
__int64 v4; // rax
int v5; // er15
_BOOL8 result; // rax
unsigned int v7; // edx
unsigned int v8; // [rsp+0h] [rbp-40h] BYREF
unsigned int v9; // [rsp+4h] [rbp-3Ch] BYREF

if ( !*(_DWORD *)(a2 + 4) )
return 1LL;
v2 = 0;
v3 = *(_QWORD *)(a2 + 8);
while ( 1 )
{
while ( 1 )
{
v4 = v3 + 16LL * v2;
v5 = *(_DWORD *)(v4 + 8);
if ( v5 )
break;
if ( ++v2 >= *(_DWORD *)(a2 + 4) )
return 1LL;
}
if ( (unsigned int)_isoc99_sscanf(*(_QWORD *)v4, "%u", &v9) != 1 || (unsigned int)_isoc99_sscanf(a1, "%u", &v8) != 1 )
return 0LL;
v7 = *(_DWORD *)(a2 + 4);
++v2;
switch ( v5 )
{
case 1:
result = v8 < v9;
goto LABEL_12;
case 2:
result = v8 > v9;
goto LABEL_12;
case 3:
result = v8 == v9;
goto LABEL_12;
case 4:
result = v8 != v9;
goto LABEL_12;
case 5:
result = v8 <= v9;
goto LABEL_12;
case 6:
result = v8 >= v9;
LABEL_12:
if ( v7 > v2 && result )
goto LABEL_14;
return result;
default:
if ( v7 <= v2 )
return 1LL;
LABEL_14:
v3 = *(_QWORD *)(a2 + 8);
break;
}
}
}

original_code:
static Boolean
CheckElo(const char *elo_string,StringArray *list)
{ unsigned list_index;
    Boolean wanted = TRUE;
    for(list_index = 0; (list_index < list->num_used_elements) && wanted;
                                list_index++){
        const char *list_string = list->tag_strings[list_index].tag_string;
        TagOperator operator = list->tag_strings[list_index].operator;
        if(operator != NONE){
            unsigned game_elo, list_elo;
            if((sscanf(list_string,"%u",&list_elo) == 1) &&
                  (sscanf(elo_string,"%u",&game_elo) == 1)){
                switch(operator){
                    case LESS_THAN:
                        wanted = game_elo < list_elo;
                        break;
                    case LESS_THAN_OR_EQUAL_TO:
                        wanted = game_elo <= list_elo;
                        break;
                    case GREATER_THAN:
                        wanted = game_elo > list_elo;
                        break;
                    case GREATER_THAN_OR_EQUAL_TO:
                        wanted = game_elo >= list_elo;
                        break;
                    case EQUAL_TO:
                        wanted = game_elo == list_elo;
                        break;
                    case NOT_EQUAL_TO:
                        wanted = game_elo != list_elo;
                        break;
                    case NONE:
                        break;
                }
            }
            else{
                wanted = FALSE;
            }
        }
        else{
            if(strncmp(elo_string,list_string,strlen(list_string)) == 0){
                wanted = TRUE;
            }
        }
    }
    return wanted;
}

canonical_original_code:
static enum Boolean CheckElo(char *elo_string, struct StringArray *list)
{ unsigned int list_index;
    enum Boolean wanted = TRUE;
    for(list_index = 0; (list_index < list->num_used_elements) && wanted;
                                list_index++){
        char *list_string = list->tag_strings[list_index].tag_string;
        enum TagOperator operator = list->tag_strings[list_index].operator;
        if(operator != NONE){
            unsigned int game_elo; unsigned int list_elo;
            if((sscanf(list_string,"%u",&list_elo) == 1) &&
                  (sscanf(elo_string,"%u",&game_elo) == 1)){
                switch(operator){
                    case LESS_THAN:
                        wanted = game_elo < list_elo;
                        break;
                    case LESS_THAN_OR_EQUAL_TO:
                        wanted = game_elo <= list_elo;
                        break;
                    case GREATER_THAN:
                        wanted = game_elo > list_elo;
                        break;
                    case GREATER_THAN_OR_EQUAL_TO:
                        wanted = game_elo >= list_elo;
                        break;
                    case EQUAL_TO:
                        wanted = game_elo == list_elo;
                        break;
                    case NOT_EQUAL_TO:
                        wanted = game_elo != list_elo;
                        break;
                    case NONE:
                        break;
                }
            }
            else{
                wanted = FALSE;
            }
        }
        else{
            if(strncmp(elo_string,list_string,strlen(list_string)) == 0){
                wanted = TRUE;
            }
        }
    }
    return wanted;
}

user_defined_types: enum TagOperator { NONE=0, LESS_THAN=1, GREATER_THAN=2, EQUAL_TO=3, NOT_EQUAL_TO=4, LESS_THAN_OR_EQUAL_TO=5, GREATER_THAN_OR_EQUAL_TO=6 }


CheckList

decompiled_code:
__int64 __fastcall CheckList(int a1, char *a2, __int64 a3)
{
char *v3; // r12
__int64 result; // rax
const char **v6; // rbx
__int64 v7; // r13
const char *v8; // rbp
size_t v9; // rax

v3 = a2;
if ( GlobalState[8] )
{
if ( (unsigned int)soundex_tag(a1) )
v3 = soundex(a2);
}
result = *(unsigned int *)(a3 + 4);
if ( (_DWORD)result )
{
v6 = *(const char ***)(a3 + 8);
v7 = (__int64)&v6[2 * (unsigned int)(result - 1) + 2];
while ( 1 )
{
v8 = *v6;
v9 = strlen(*v6);
if ( !strncmp(v3, v8, v9) )
break;
v6 += 2;
if ( (const char **)v7 == v6 )
return 0LL;
}
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func5(int a1, char *a2, __int64 a3)
{
char *v3; // r12
__int64 result; // rax
const char **v6; // rbx
__int64 v7; // r13
const char *v8; // rbp
size_t v9; // rax

v3 = a2;
if ( GlobalState[8] )
{
if ( (unsigned int)func0(a1) )
v3 = func1(a2);
}
result = *(unsigned int *)(a3 + 4);
if ( (_DWORD)result )
{
v6 = *(const char ***)(a3 + 8);
v7 = (__int64)&v6[2 * (unsigned int)(result - 1) + 2];
while ( 1 )
{
v8 = *v6;
v9 = strlen(*v6);
if ( !strncmp(v3, v8, v9) )
break;
v6 += 2;
if ( (const char **)v7 == v6 )
return 0LL;
}
result = 1LL;
}
return result;
}

original_code:
static Boolean
CheckList(int tag,const char *tag_string,StringArray *list)
{ unsigned list_index;
    Boolean wanted = FALSE;
    const char *search_str;
    if(GlobalState.use_soundex && soundex_tag(tag)){
        search_str = soundex(tag_string);
    }
    else{
        search_str = tag_string;
    }
    for(list_index = 0; (list_index < list->num_used_elements) && !wanted;
                                list_index++){
        const char *list_string = list->tag_strings[list_index].tag_string;
        if(strncmp(search_str,list_string,strlen(list_string)) == 0){
            wanted = TRUE;
        }
    }
    return wanted;
}

canonical_original_code:
static enum Boolean CheckList(int tag, char *tag_string, struct StringArray *list)
{ unsigned int list_index;
    enum Boolean wanted = FALSE;
    char *search_str;
    if(GlobalState.use_soundex && soundex_tag(tag)){
        search_str = soundex(tag_string);
    }
    else{
        search_str = tag_string;
    }
    for(list_index = 0; (list_index < list->num_used_elements) && !wanted;
                                list_index++){
        char *list_string = list->tag_strings[list_index].tag_string;
        if(strncmp(search_str,list_string,strlen(list_string)) == 0){
            wanted = TRUE;
        }
    }
    return wanted;
}


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

tag_list_length = 40;
result = MallocOrDie(640LL);
TagLists = result;
return result;
}

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

tag_list_length = 40;
result = MallocOrDie(640LL);
TagLists = result;
return result;
}

original_code:
void init_tag_lists(void)
{
    tag_list_length = ORIGINAL_NUMBER_OF_TAGS;
    TagLists = (StringArray *) MallocOrDie(tag_list_length*sizeof(*TagLists));
}

canonical_original_code:
void init_tag_lists()
{
    tag_list_length = ORIGINAL_NUMBER_OF_TAGS;
    TagLists = (struct StringArray *) MallocOrDie(tag_list_length*sizeof(*TagLists));
}


decompiled_code:
int __fastcall add_tag_to_list(int a1, char *a2, int a3)
{
char *v3; // rbp
__int64 v5; // r12
__int64 v6; // rax

v3 = a2;
if ( tag_list_length <= a1 )
{
extend_tag_list_length(a1 + 1);
if ( a1 >= 0 && tag_list_length > a1 )
goto LABEL_3;
LABEL_9:
LODWORD(v6) = fprintf(*(FILE **)&GlobalState[46], "Illegal tag number %d in add_tag_to_list.\n", (unsigned int)a1);
return v6;
}
if ( a1 < 0 )
goto LABEL_9;
LABEL_3:
if ( GlobalState[8] && (unsigned int)soundex_tag(a1) )
v3 = soundex(a2);
v5 = 16LL * a1;
LODWORD(v6) = add_to_taglist(v3, v5 + TagLists);
if ( (int)v6 >= 0 )
{
v6 = *(_QWORD *)(TagLists + v5 + 8) + 16LL * (int)v6;
*(_DWORD *)(v6 + 8) = a3;
}
GlobalState[11] = 1;
return v6;
}

canonical_decompiled_code:
int __fastcall func7(int a1, char *a2, int a3)
{
char *v3; // rbp
__int64 v5; // r12
__int64 v6; // rax

v3 = a2;
if ( tag_list_length <= a1 )
{
extend_tag_list_length(a1 + 1);
if ( a1 >= 0 && tag_list_length > a1 )
goto LABEL_3;
LABEL_9:
LODWORD(v6) = fprintf(*(FILE **)&GlobalState[46], "Illegal tag number %d in add_tag_to_list.\n", (unsigned int)a1);
return v6;
}
if ( a1 < 0 )
goto LABEL_9;
LABEL_3:
if ( GlobalState[8] && (unsigned int)func0(a1) )
v3 = func1(a2);
v5 = 16LL * a1;
LODWORD(v6) = func2(v3, v5 + TagLists);
if ( (int)v6 >= 0 )
{
v6 = *(_QWORD *)(TagLists + v5 + 8) + 16LL * (int)v6;
*(_DWORD *)(v6 + 8) = a3;
}
GlobalState[11] = 1;
return v6;
}

original_code:
void
add_tag_to_list(int tag,const char *tagstr,TagOperator operator)
{
    if(tag >= tag_list_length){
        extend_tag_list_length(tag+1);
    }
    if((tag >= 0) && (tag < tag_list_length)){
        const char *string_to_store = tagstr;
        int ix;
        if(GlobalState.use_soundex){
            if(soundex_tag(tag)){
                string_to_store = soundex(tagstr);
            }
        }
        ix = add_to_taglist(string_to_store,&TagLists[tag]);
        if(ix >= 0){
            TagLists[tag].tag_strings[ix].operator = operator;
        }
        GlobalState.check_tags = TRUE;
    }
    else{
        fprintf(GlobalState.logfile,
                "Illegal tag number %d in add_tag_to_list.\n",tag);
    }
}

canonical_original_code:
void add_tag_to_list(int tag, char *tagstr, enum TagOperator operator)
{
    if(tag >= tag_list_length){
        extend_tag_list_length(tag+1);
    }
    if((tag >= 0) && (tag < tag_list_length)){
        char *string_to_store = tagstr;
        int ix;
        if(GlobalState.use_soundex){
            if(soundex_tag(tag)){
                string_to_store = soundex(tagstr);
            }
        }
        ix = add_to_taglist(string_to_store,&TagLists[tag]);
        if(ix >= 0){
            TagLists[tag].tag_strings[ix].operator = operator;
        }
        GlobalState.check_tags = TRUE;
    }
    else{
        fprintf(GlobalState.logfile,
                "Illegal tag number %d in add_tag_to_list.\n",tag);
    }
}

variable_types:
tagstr
char *

variable_types: ix int


decompiled_code:
int __fastcall extract_tag_argument(const char *a1)
{
char *v1; // rsi
int result; // eax

v1 = (char *)(a1 + 1);
switch ( *a1 )
{
case 'a':
result = add_tag_to_list(0, v1, 0);
break;
case 'b':
result = add_tag_to_list(1, v1, 0);
break;
case 'd':
result = add_tag_to_list(8, v1, 0);
break;
case 'e':
result = add_tag_to_list(9, v1, 0);
break;
case 'p':
result = add_tag_to_list(19, v1, 0);
break;
case 'r':
result = add_tag_to_list(21, v1, 0);
break;
case 'w':
result = add_tag_to_list(34, v1, 0);
break;
default:
fprintf(*(FILE **)&GlobalState[46], "Unknown type of tag extraction argument: %s\n", a1);
exit(1);
}
return result;
}

canonical_decompiled_code:
int __fastcall func8(const char *a1)
{
char *v1; // rsi
int result; // eax

v1 = (char *)(a1 + 1);
switch ( *a1 )
{
case 'a':
result = func7(0, v1, 0);
break;
case 'b':
result = func7(1, v1, 0);
break;
case 'd':
result = func7(8, v1, 0);
break;
case 'e':
result = func7(9, v1, 0);
break;
case 'p':
result = func7(19, v1, 0);
break;
case 'r':
result = func7(21, v1, 0);
break;
case 'w':
result = func7(34, v1, 0);
break;
default:
fprintf(*(FILE **)&GlobalState[46], "Unknown type of tag extraction argument: %s\n", a1);
exit(1);
}
return result;
}

original_code:
void
extract_tag_argument(const char *argstr)
{ const char *arg = &(argstr[1]);
    switch(*argstr){
        case 'a':
            add_tag_to_list(ANNOTATOR_TAG,arg,NONE);
            break;
        case 'b':
            add_tag_to_list(BLACK_TAG,arg,NONE);
            break;
        case 'd':
            add_tag_to_list(DATE_TAG,arg,NONE);
            break;
        case 'e':
            add_tag_to_list(ECO_TAG,arg,NONE);
            break;
        case 'p':
            add_tag_to_list(PSEUDO_PLAYER_TAG,arg,NONE);
            break;
        case 'r':
            add_tag_to_list(RESULT_TAG,arg,NONE);
            break;
        case 'w':
            add_tag_to_list(WHITE_TAG,arg,NONE);
            break;
        default:
            fprintf(GlobalState.logfile,
                    "Unknown type of tag extraction argument: %s\n",
                        argstr);
            exit(1);
            break;
    }
}

canonical_original_code:
void extract_tag_argument(char *argstr)
{ char *arg = &(argstr[1]);
    switch(*argstr){
        case 'a':
            add_tag_to_list(ANNOTATOR_TAG,arg,NONE);
            break;
        case 'b':
            add_tag_to_list(BLACK_TAG,arg,NONE);
            break;
        case 'd':
            add_tag_to_list(DATE_TAG,arg,NONE);
            break;
        case 'e':
            add_tag_to_list(ECO_TAG,arg,NONE);
            break;
        case 'p':
            add_tag_to_list(PSEUDO_PLAYER_TAG,arg,NONE);
            break;
        case 'r':
            add_tag_to_list(RESULT_TAG,arg,NONE);
            break;
        case 'w':
            add_tag_to_list(WHITE_TAG,arg,NONE);
            break;
        default:
            fprintf(GlobalState.logfile,
                    "Unknown type of tag extraction argument: %s\n",
                        argstr);
            exit(1);
            break;
    }
}

variable_types:
argstr
char *

variable_types:
arg
char *


CheckTagDetailsNotECO

decompiled_code:
__int64 __fastcall CheckTagDetailsNotECO(char **a1, int a2)
{
int v2; // er13
__int64 v3; // rbp
char **v4; // r12
char *v5; // rsi
unsigned int v6; // er8
char *v7; // rsi
__int64 v9; // rdi
__int64 v10; // rdi
int v11; // ebx
char *v12; // rdi
char *v13; // rsi
__int64 v14; // rdi

if ( !GlobalState[11] )
return 1LL;
v2 = tag_list_length;
if ( tag_list_length > a2 )
{
fwrite("Internal error: mismatch in tag set lengths in ", 1uLL, 0x2FuLL, *(FILE **)&GlobalState[46]);
fprintf(
*(FILE **)&GlobalState[46],
"CheckTagDetailsNotECO: %d vs %d\n",
(unsigned int)a2,
(unsigned int)tag_list_length);
exit(1);
}
v3 = TagLists;
v4 = a1;
if ( *(_DWORD *)(TagLists + 308) )
{
v5 = a1[34];
if ( v5 )
{
v6 = CheckList(34, v5, TagLists + 304);
if ( !v6 )
{
v7 = a1[1];
if ( v7 )
{
v6 = CheckList(1, v7, v3 + 304);
goto LABEL_32;
}
return 0;
}
goto LABEL_35;
}
v13 = a1[1];
if ( !v13 )
return 0;
v6 = CheckList(1, v13, TagLists + 304);
goto LABEL_32;
}
if ( *(_DWORD *)(TagLists + 164) )
{
v9 = (__int64)a1[35];
if ( v9 )
{
v6 = CheckElo(v9, TagLists + 160);
if ( v6 )
{
LABEL_35:
if ( v2 <= 0 )
return v6;
goto LABEL_15;
}
v10 = (__int64)v4[2];
if ( !v10 )
return 0;
v6 = CheckElo(v10, v3 + 160);
}
else
{
v14 = (__int64)v4[2];
if ( !v14 )
return 0;
v6 = CheckElo(v14, TagLists + 160);
}
LABEL_32:
if ( v2 <= 0 )
return v6;
if ( !v6 )
return 0;
goto LABEL_15;
}
v6 = 1;
if ( tag_list_length > 0 )
{
LABEL_15:
v11 = 0;
while ( 1 )
{
while ( (unsigned int)(v11 - 9) <= 1 || v11 == 19 || !*(_DWORD *)(v3 + 4) )
{
if ( v2 <= ++v11 )
return v6;
v3 += 16LL;
++v4;
}
v12 = *v4;
if ( !*v4 )
break;
if ( v11 == 8 )
{
v6 = CheckDate(v12, v3);
}
else if ( v11 == 35 || v11 == 2 )
{
v6 = CheckElo((__int64)v12, v3);
}
else
{
v6 = CheckList(v11, *v4, v3);
}
if ( v2 <= ++v11 )
return v6;
v3 += 16LL;
++v4;
if ( !v6 )
return 0;
}
return 0;
}
return v6;
}

canonical_decompiled_code:
__int64 __fastcall func9(char **a1, int a2)
{
int v2; // er13
__int64 v3; // rbp
char **v4; // r12
char *v5; // rsi
unsigned int v6; // er8
char *v7; // rsi
__int64 v9; // rdi
__int64 v10; // rdi
int v11; // ebx
char *v12; // rdi
char *v13; // rsi
__int64 v14; // rdi

if ( !GlobalState[11] )
return 1LL;
v2 = tag_list_length;
if ( tag_list_length > a2 )
{
fwrite("Internal error: mismatch in tag set lengths in ", 1uLL, 0x2FuLL, *(FILE **)&GlobalState[46]);
fprintf(
*(FILE **)&GlobalState[46],
"CheckTagDetailsNotECO: %d vs %d\n",
(unsigned int)a2,
(unsigned int)tag_list_length);
exit(1);
}
v3 = TagLists;
v4 = a1;
if ( *(_DWORD *)(TagLists + 308) )
{
v5 = a1[34];
if ( v5 )
{
v6 = func5(34, v5, TagLists + 304);
if ( !v6 )
{
v7 = a1[1];
if ( v7 )
{
v6 = func5(1, v7, v3 + 304);
goto LABEL_32;
}
return 0;
}
goto LABEL_35;
}
v13 = a1[1];
if ( !v13 )
return 0;
v6 = func5(1, v13, TagLists + 304);
goto LABEL_32;
}
if ( *(_DWORD *)(TagLists + 164) )
{
v9 = (__int64)a1[35];
if ( v9 )
{
v6 = func4(v9, TagLists + 160);
if ( v6 )
{
LABEL_35:
if ( v2 <= 0 )
return v6;
goto LABEL_15;
}
v10 = (__int64)v4[2];
if ( !v10 )
return 0;
v6 = func4(v10, v3 + 160);
}
else
{
v14 = (__int64)v4[2];
if ( !v14 )
return 0;
v6 = func4(v14, TagLists + 160);
}
LABEL_32:
if ( v2 <= 0 )
return v6;
if ( !v6 )
return 0;
goto LABEL_15;
}
v6 = 1;
if ( tag_list_length > 0 )
{
LABEL_15:
v11 = 0;
while ( 1 )
{
while ( (unsigned int)(v11 - 9) <= 1 || v11 == 19 || !*(_DWORD *)(v3 + 4) )
{
if ( v2 <= ++v11 )
return v6;
v3 += 16LL;
++v4;
}
v12 = *v4;
if ( !*v4 )
break;
if ( v11 == 8 )
{
v6 = func3(v12, v3);
}
else if ( v11 == 35 || v11 == 2 )
{
v6 = func4((__int64)v12, v3);
}
else
{
v6 = func5(v11, *v4, v3);
}
if ( v2 <= ++v11 )
return v6;
v3 += 16LL;
++v4;
if ( !v6 )
return 0;
}
return 0;
}
return v6;
}

original_code:
Boolean
CheckTagDetailsNotECO(char *Details[],int num_details)
{ Boolean wanted = TRUE;
    int tag;
    if(GlobalState.check_tags){
        if(num_details < tag_list_length){
            fprintf(GlobalState.logfile,
                   "Internal error: mismatch in tag set lengths in ");
            fprintf(GlobalState.logfile,
                   "CheckTagDetailsNotECO: %d vs %d\n",
                   num_details,tag_list_length);
            exit(1);
        }
        if(TagLists[PSEUDO_PLAYER_TAG].num_used_elements != 0){
            if(Details[WHITE_TAG] != ((void *)0)){
                wanted = CheckList(WHITE_TAG,Details[WHITE_TAG],
                                    &TagLists[PSEUDO_PLAYER_TAG]);
                if(!wanted && (Details[BLACK_TAG] != ((void *)0))){
                    wanted = CheckList(BLACK_TAG,Details[BLACK_TAG],
                                    &TagLists[PSEUDO_PLAYER_TAG]);
                }
            }
            else if(Details[BLACK_TAG] != ((void *)0)){
                wanted = CheckList(BLACK_TAG,Details[BLACK_TAG],
                                    &TagLists[PSEUDO_PLAYER_TAG]);
            }
            else{
                wanted = FALSE;
            }
        }
        else if(TagLists[PSEUDO_ELO_TAG].num_used_elements != 0){
            if(Details[WHITE_ELO_TAG] != ((void *)0)){
                wanted = CheckElo(Details[WHITE_ELO_TAG],
                                    &TagLists[PSEUDO_ELO_TAG]);
                if(!wanted && (Details[BLACK_ELO_TAG] != ((void *)0))){
                    wanted = CheckElo(Details[BLACK_ELO_TAG],
                                    &TagLists[PSEUDO_ELO_TAG]);
                }
            }
            else if(Details[BLACK_ELO_TAG] != ((void *)0)){
                wanted = CheckElo(Details[BLACK_ELO_TAG],
                                    &TagLists[PSEUDO_ELO_TAG]);
            }
            else{
                wanted = FALSE;
            }
        }
        else{
        }
        for(tag = 0; (tag < tag_list_length) && wanted; tag++){
            if(tag == PSEUDO_PLAYER_TAG){
            }
            else if(tag == PSEUDO_ELO_TAG){
            }
            else if(tag == ECO_TAG){
            }
            else if(TagLists[tag].num_used_elements != 0){
                if(Details[tag] != ((void *)0)){
                    if(tag == DATE_TAG){
                        wanted = CheckDate(Details[tag],&TagLists[tag]);
                    }
                    else if((tag == WHITE_ELO_TAG) || (tag == BLACK_ELO_TAG)){
                        wanted = CheckElo(Details[tag],&TagLists[tag]);
                    }
                    else{
                        wanted = CheckList(tag,Details[tag],&TagLists[tag]);
                    }
                }
                else{
                    wanted = FALSE;
                }
            }
            else{
            }
        }
    }
    return wanted;
}

canonical_original_code:
enum Boolean CheckTagDetailsNotECO(char *Details[], int num_details)
{ enum Boolean wanted = TRUE;
    int tag;
    if(GlobalState.check_tags){
        if(num_details < tag_list_length){
            fprintf(GlobalState.logfile,
                   "Internal error: mismatch in tag set lengths in ");
            fprintf(GlobalState.logfile,
                   "CheckTagDetailsNotECO: %d vs %d\n",
                   num_details,tag_list_length);
            exit(1);
        }
        if(TagLists[PSEUDO_PLAYER_TAG].num_used_elements != 0){
            if(Details[WHITE_TAG] != ((void *)0)){
                wanted = CheckList(WHITE_TAG,Details[WHITE_TAG],
                                    &TagLists[PSEUDO_PLAYER_TAG]);
                if(!wanted && (Details[BLACK_TAG] != ((void *)0))){
                    wanted = CheckList(BLACK_TAG,Details[BLACK_TAG],
                                    &TagLists[PSEUDO_PLAYER_TAG]);
                }
            }
            else if(Details[BLACK_TAG] != ((void *)0)){
                wanted = CheckList(BLACK_TAG,Details[BLACK_TAG],
                                    &TagLists[PSEUDO_PLAYER_TAG]);
            }
            else{
                wanted = FALSE;
            }
        }
        else if(TagLists[PSEUDO_ELO_TAG].num_used_elements != 0){
            if(Details[WHITE_ELO_TAG] != ((void *)0)){
                wanted = CheckElo(Details[WHITE_ELO_TAG],
                                    &TagLists[PSEUDO_ELO_TAG]);
                if(!wanted && (Details[BLACK_ELO_TAG] != ((void *)0))){
                    wanted = CheckElo(Details[BLACK_ELO_TAG],
                                    &TagLists[PSEUDO_ELO_TAG]);
                }
            }
            else if(Details[BLACK_ELO_TAG] != ((void *)0)){
                wanted = CheckElo(Details[BLACK_ELO_TAG],
                                    &TagLists[PSEUDO_ELO_TAG]);
            }
            else{
                wanted = FALSE;
            }
        }
        else{
        }
        for(tag = 0; (tag < tag_list_length) && wanted; tag++){
            if(tag == PSEUDO_PLAYER_TAG){
            }
            else if(tag == PSEUDO_ELO_TAG){
            }
            else if(tag == ECO_TAG){
            }
            else if(TagLists[tag].num_used_elements != 0){
                if(Details[tag] != ((void *)0)){
                    if(tag == DATE_TAG){
                        wanted = CheckDate(Details[tag],&TagLists[tag]);
                    }
                    else if((tag == WHITE_ELO_TAG) || (tag == BLACK_ELO_TAG)){
                        wanted = CheckElo(Details[tag],&TagLists[tag]);
                    }
                    else{
                        wanted = CheckList(tag,Details[tag],&TagLists[tag]);
                    }
                }
                else{
                    wanted = FALSE;
                }
            }
            else{
            }
        }
    }
    return wanted;
}

variable_types:
Details
char *[]


CheckECOTag

decompiled_code:
__int64 __fastcall CheckECOTag(__int64 a1)
{
char *v1; // rsi
__int64 result; // rax

if ( !GlobalState[11] || !*(_DWORD *)(TagLists + 148) )
return 1LL;
v1 = *(char **)(a1 + 72);
if ( v1 )
result = CheckList(9, v1, TagLists + 144);
else
result = 0LL;
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1)
{
char *v1; // rsi
__int64 result; // rax

if ( !GlobalState[11] || !*(_DWORD *)(TagLists + 148) )
return 1LL;
v1 = *(char **)(a1 + 72);
if ( v1 )
result = func5(9, v1, TagLists + 144);
else
result = 0LL;
return result;
}

original_code:
Boolean
CheckECOTag(char *Details[])
{ Boolean wanted = TRUE;
    if(GlobalState.check_tags){
        if(TagLists[ECO_TAG].num_used_elements != 0){
            if(Details[ECO_TAG] != ((void *)0)){
                wanted = CheckList(ECO_TAG,Details[ECO_TAG],&TagLists[ECO_TAG]);
            }
            else{
                wanted = FALSE;
            }
        }
    }
    return wanted;
}

canonical_original_code:
enum Boolean CheckECOTag(char *Details[])
{ enum Boolean wanted = TRUE;
    if(GlobalState.check_tags){
        if(TagLists[ECO_TAG].num_used_elements != 0){
            if(Details[ECO_TAG] != ((void *)0)){
                wanted = CheckList(ECO_TAG,Details[ECO_TAG],&TagLists[ECO_TAG]);
            }
            else{
                wanted = FALSE;
            }
        }
    }
    return wanted;
}


main

canonical_name: main

repo: natearn/Spong

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

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

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

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

variable_types: argc int

variable_types:
argv
char *[]


decompiled_code:
int __fastcall Spong_Score(int a1)
{
__int64 v1; // rdx
__int64 v2; // rcx

v1 = (unsigned int)player1_2;
v2 = (unsigned int)player2_1;
if ( a1 == 1 )
{
v1 = (unsigned int)++player1_2;
}
else if ( a1 == 2 )
{
v2 = (unsigned int)++player2_1;
}
return fprintf(stderr, "Score: %d to %d\n", v1, v2);
}

canonical_decompiled_code:
int __fastcall func11(int a1)
{
__int64 v1; // rdx
__int64 v2; // rcx

v1 = (unsigned int)player1_2;
v2 = (unsigned int)player2_1;
if ( a1 == 1 )
{
v1 = (unsigned int)++player1_2;
}
else if ( a1 == 2 )
{
v2 = (unsigned int)++player2_1;
}
return fprintf(stderr, "Score: %d to %d\n", v1, v2);
}

original_code:
void Spong_Score(int player)
{
 static int player1=0;
 static int player2=0;
 switch(player)
 {
  case 1:
   player1++;
   break;
  case 2:
   player2++;
   break;
  default:
   break;
 }
 fprintf(stderr,"Score: %d to %d\n", player1, player2 );
}

canonical_original_code:
void Spong_Score(int player)
{
 static int player1 = 0;
 static int player2 = 0;
 switch(player)
 {
  case 1:
   player1++;
   break;
  case 2:
   player2++;
   break;
  default:
   break;
 }
 fprintf(stderr,"Score: %d to %d\n", player1, player2 );
}

variable_types: player int


decompiled_code:
void Spong_CleanUp()
{
;
}

canonical_decompiled_code:
void func14()
{
;
}

original_code: void Spong_CleanUp() {}

canonical_original_code: void Spong_CleanUp() {}


repo: nathanpc/coconut-basic

decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
repl(argc, argv, envp);
}

canonical_decompiled_code:
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
func15(argc, argv, envp);
}

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


strupper

decompiled_code:
char *__fastcall strupper(const char *a1)
{
char *v1; // r12
const __int32_t *v2; // rcx
char *v3; // rax
__int64 v4; // rdx

v1 = strdup(a1);
v2 = *__ctype_toupper_loc();
v3 = v1;
do
{
v4 = *v3++;
LODWORD(v4) = v2[v4];
*(v3 - 1) = v4;
}
while ( (_BYTE)v4 );
return v1;
}

canonical_decompiled_code:
char *__fastcall func7(const char *a1)
{
char *v1; // r12
const __int32_t *v2; // rcx
char *v3; // rax
__int64 v4; // rdx

v1 = strdup(a1);
v2 = *__ctype_toupper_loc();
v3 = v1;
do
{
v4 = *v3++;
LODWORD(v4) = v2[v4];
*(v3 - 1) = v4;
}
while ( (_BYTE)v4 );
return v1;
}

original_code:
char* strupper(char *str) {
 char *newstr, *p;
 p = newstr = strdup(str);
 while (*p++ = toupper(*p));
 return newstr;
}

canonical_original_code:
char *strupper(char *str) {
 char *newstr; char *p;
 p = newstr = strdup(str);
 while (*p++ = toupper(*p));
 return newstr;
}

variable_types:
str
char *

variable_types:
newstr
char *

variable_types:
p
char *


substr

decompiled_code:
char *__fastcall substr(const char *a1, size_t a2, size_t a3)
{
size_t v4; // rax

if ( !a1 )
return 0LL;
if ( *a1 )
{
v4 = strlen(a1);
if ( v4 >= a2 && v4 >= a2 + a3 )
return strndup(&a1[a2], a3);
}
return 0LL;
}

canonical_decompiled_code:
char *__fastcall func8(const char *a1, size_t a2, size_t a3)
{
size_t v4; // rax

if ( !a1 )
return 0LL;
if ( *a1 )
{
v4 = strlen(a1);
if ( v4 >= a2 && v4 >= a2 + a3 )
return strndup(&a1[a2], a3);
}
return 0LL;
}

original_code:
char* substr(const char *str, size_t begin, size_t len) {
 if (str == 0 || strlen(str) == 0 || strlen(str) < begin || strlen(str) < (begin + len)) {
  return ((void *)0);
 }
 return strndup(str + begin, len);
}

canonical_original_code:
char *substr(char *str, unsigned long begin, unsigned long len) {
 if (str == 0 || strlen(str) == 0 || strlen(str) < begin || strlen(str) < (begin + len)) {
  return ((void *)0);
 }
 return strndup(str + begin, len);
}

variable_types:
begin
unsigned long

variable_types:
len
unsigned long


decompiled_code:
char *__fastcall function_parts(char *a1, char *a2, char *a3, char *a4)
{
char *v6; // rax
char *v7; // rax
char *v8; // rax
char *v9; // rbp
size_t v10; // rax
char *v11; // rax

v6 = strtok(a1, " ");
strcpy(a2, v6);
v7 = strtok(0LL, " ");
v8 = strupper(v7);
v9 = stpcpy(a3, v8);
v10 = strlen(a2);
v11 = strdup(&a1[v9 - a3 + 2 + v10]);
return strcpy(a4, v11);
}

canonical_decompiled_code:
char *__fastcall func9(char *a1, char *a2, char *a3, char *a4)
{
char *v6; // rax
char *v7; // rax
char *v8; // rax
char *v9; // rbp
size_t v10; // rax
char *v11; // rax

v6 = strtok(a1, " ");
strcpy(a2, v6);
v7 = strtok(0LL, " ");
v8 = func7(v7);
v9 = stpcpy(a3, v8);
v10 = strlen(a2);
v11 = strdup(&a1[v9 - a3 + 2 + v10]);
return strcpy(a4, v11);
}

original_code:
void function_parts(char *line, char *linenum, char *keyword, char *args) {
 strcpy(linenum, strtok(line, " "));
 strcpy(keyword, strupper(strtok(((void *)0), " ")));
 strcpy(args, strdup(line + strlen(linenum) + strlen(keyword) + 2));
}

variable_types:
line
char *

variable_types:
linenum
char *

variable_types:
keyword
char *

variable_types:
args
char *


decompiled_code:
int __fastcall repl_print(const char *a1)
{
return printf("%s", a1);
}

canonical_decompiled_code:
int __fastcall func10(const char *a1)
{
return printf("%s", a1);
}

original_code:
void repl_print(const char *string) {
  printf("%s", string);
}

canonical_original_code:
void repl_print(char *string) {
  printf("%s", string);
}

variable_types:
string
char *


decompiled_code:
void basic_let()
{
;
}

canonical_decompiled_code:
void func12()
{
;
}

original_code:
void basic_let() {
}

canonical_original_code:
void basic_let() {
}