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

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 comment_list { struct string_list *Comment; struct comment_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()
{
_QWORD *v0; // rax
_QWORD *v1; // rdx

if ( !EcoTable )
{
v0 = (_QWORD *)MallocOrDie(0x8000LL);
EcoTable = (__int64)v0;
v1 = v0 + 4096;
do
*v0++ = 0LL;
while ( v0 != v1 );
}
}

canonical_decompiled_code:
void func0()
{
_QWORD *v0; // rax
_QWORD *v1; // rdx

if ( !EcoTable )
{
v0 = (_QWORD *)MallocOrDie(0x8000LL);
EcoTable = (__int64)v0;
v1 = v0 + 4096;
do
*v0++ = 0LL;
while ( v0 != v1 );
}
}

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


decompiled_code:
__int64 __fastcall eco_matches(__int64 a1, __int64 a2, unsigned int a3)
{
__int64 v5; // rcx
__int64 v6; // rax
unsigned int v7; // er10
int v8; // edx

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

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, __int64 a2, unsigned int a3)
{
__int64 v5; // rcx
__int64 v6; // rax
unsigned int v7; // er10
int v8; // edx

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

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

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


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

return_type: char *


decompiled_code:
__int64 __fastcall add_to_taglist(char *src, int *a2)
{
int v3; // eax
__int64 v4; // rax
void *v5; // rax
unsigned int v6; // er12
__int64 v7; // rbp
size_t v8; // rax
_QWORD *v9; // r14
char *v10; // rdi

v3 = *a2;
if ( *a2 == a2[1] )
{
if ( v3 )
{
v5 = realloc(*((void **)a2 + 1), 16LL * (unsigned int)(v3 + 6));
*((_QWORD *)a2 + 1) = v5;
if ( !v5 )
return 0xFFFFFFFFLL;
*a2 += 5;
}
else
{
v4 = MallocOrDie(176LL);
*((_QWORD *)a2 + 1) = v4;
if ( !v4 )
return 0xFFFFFFFFLL;
*a2 = 10;
a2[1] = 0;
}
}
v6 = a2[1];
v7 = 16LL * v6;
*(_DWORD *)(*((_QWORD *)a2 + 1) + v7 + 8) = 0;
v8 = strlen(src);
v9 = (_QWORD *)(*((_QWORD *)a2 + 1) + v7);
*v9 = MallocOrDie(v8 + 1);
v10 = *(char **)(*((_QWORD *)a2 + 1) + v7);
if ( !v10 )
return 0xFFFFFFFFLL;
strcpy(v10, src);
++a2[1];
*(_QWORD *)(*((_QWORD *)a2 + 1) + 16LL * (v6 + 1)) = 0LL;
return v6;
}

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

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)
{
_BOOL4 v2; // er12
unsigned int v3; // ebx
const char *v4; // r14
int v5; // er15
const char **v6; // rax
char v7; // dl
size_t v8; // rax
unsigned int v10; // [rsp+8h] [rbp-40h] BYREF
unsigned int v11; // [rsp+Ch] [rbp-3Ch] BYREF

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

canonical_decompiled_code:
_BOOL8 __fastcall func4(char *s1, __int64 a2)
{
_BOOL4 v2; // er12
unsigned int v3; // ebx
const char *v4; // r14
int v5; // er15
const char **v6; // rax
char v7; // dl
size_t v8; // rax
unsigned int v10; // [rsp+8h] [rbp-40h] BYREF
unsigned int v11; // [rsp+Ch] [rbp-3Ch] BYREF

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

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(const char *a1, __int64 a2)
{
_BOOL4 v2; // ebp
unsigned int v3; // ebx
const char **v4; // rax
const char *v5; // r12
int v6; // er14
size_t v7; // rax
unsigned int v9; // [rsp+18h] [rbp-40h] BYREF
unsigned int v10; // [rsp+1Ch] [rbp-3Ch] BYREF

if ( !*(_DWORD *)(a2 + 4) )
return 1;
v2 = 1;
v3 = 0;
do
{
v4 = (const char **)(*(_QWORD *)(a2 + 8) + 16LL * v3);
v5 = *v4;
v6 = *((_DWORD *)v4 + 2);
if ( v6 )
{
if ( (unsigned int)_isoc99_sscanf(*v4, "%u", &v10) == 1 )
{
if ( (unsigned int)_isoc99_sscanf(a1, "%u", &v9) == 1 )
{
switch ( v6 )
{
case 1:
v2 = v9 < v10;
break;
case 2:
v2 = v9 > v10;
break;
case 3:
v2 = v9 == v10;
break;
case 4:
v2 = v9 != v10;
break;
case 5:
v2 = v9 <= v10;
break;
case 6:
v2 = v9 >= v10;
break;
default:
break;
}
}
else
{
v2 = 0;
}
}
else
{
v2 = 0;
}
}
else
{
v7 = strlen(*v4);
if ( !strncmp(a1, v5, v7) )
v2 = 1;
}
++v3;
}
while ( *(_DWORD *)(a2 + 4) > v3 && v2 );
return v2;
}

canonical_decompiled_code:
_BOOL8 __fastcall func5(const char *a1, __int64 a2)
{
_BOOL4 v2; // ebp
unsigned int v3; // ebx
const char **v4; // rax
const char *v5; // r12
int v6; // er14
size_t v7; // rax
unsigned int v9; // [rsp+18h] [rbp-40h] BYREF
unsigned int v10; // [rsp+1Ch] [rbp-3Ch] BYREF

if ( !*(_DWORD *)(a2 + 4) )
return 1;
v2 = 1;
v3 = 0;
do
{
v4 = (const char **)(*(_QWORD *)(a2 + 8) + 16LL * v3);
v5 = *v4;
v6 = *((_DWORD *)v4 + 2);
if ( v6 )
{
if ( (unsigned int)_isoc99_sscanf(*v4, "%u", &v10) == 1 )
{
if ( (unsigned int)_isoc99_sscanf(a1, "%u", &v9) == 1 )
{
switch ( v6 )
{
case 1:
v2 = v9 < v10;
break;
case 2:
v2 = v9 > v10;
break;
case 3:
v2 = v9 == v10;
break;
case 4:
v2 = v9 != v10;
break;
case 5:
v2 = v9 <= v10;
break;
case 6:
v2 = v9 >= v10;
break;
default:
break;
}
}
else
{
v2 = 0;
}
}
else
{
v2 = 0;
}
}
else
{
v7 = strlen(*v4);
if ( !strncmp(a1, v5, v7) )
v2 = 1;
}
++v3;
}
while ( *(_DWORD *)(a2 + 4) > v3 && v2 );
return v2;
}

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];
do
{
v8 = *v6;
v9 = strlen(*v6);
if ( !strncmp(v3, v8, v9) )
return 1LL;
v6 += 2;
}
while ( (const char **)v7 != v6 );
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func6(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 = func2(a2);
}
result = *(unsigned int *)(a3 + 4);
if ( (_DWORD)result )
{
v6 = *(const char ***)(a3 + 8);
v7 = (__int64)&v6[2 * (unsigned int)(result - 1) + 2];
do
{
v8 = *v6;
v9 = strlen(*v6);
if ( !strncmp(v3, v8, v9) )
return 1LL;
v6 += 2;
}
while ( (const char **)v7 != v6 );
result = 0LL;
}
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 func7()
{
__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; // r12
__int64 v5; // rbx
__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_11:
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_11;
LABEL_3:
if ( GlobalState[8] && (unsigned int)soundex_tag(a1) )
v3 = soundex(a2);
v5 = 16LL * a1;
LODWORD(v6) = add_to_taglist(v3, (int *)(TagLists + v5));
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 func8(int a1, char *a2, int a3)
{
char *v3; // r12
__int64 v5; // rbx
__int64 v6; // rax

v3 = a2;
if ( tag_list_length <= a1 )
{
func1(a1 + 1);
if ( a1 >= 0 && tag_list_length > a1 )
goto LABEL_3;
LABEL_11:
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_11;
LABEL_3:
if ( GlobalState[8] && (unsigned int)func0(a1) )
v3 = func2(a2);
v5 = 16LL * a1;
LODWORD(v6) = func3(v3, (int *)(TagLists + v5));
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 func9(const char *a1)
{
char *v1; // rsi
int result; // eax

v1 = (char *)(a1 + 1);
switch ( *a1 )
{
case 'a':
result = func8(0, v1, 0);
break;
case 'b':
result = func8(1, v1, 0);
break;
case 'd':
result = func8(8, v1, 0);
break;
case 'e':
result = func8(9, v1, 0);
break;
case 'p':
result = func8(19, v1, 0);
break;
case 'r':
result = func8(21, v1, 0);
break;
case 'w':
result = func8(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)
{
char **v2; // rbp
int v3; // er13
__int64 v4; // r12
char *v5; // rsi
__int64 result; // rax
char *v7; // rsi
int v8; // ebx
char *v9; // rsi
const char *v10; // rdi
const char *v11; // rdi
const char *v12; // rdi
char *v13; // rdi

if ( !GlobalState[11] )
return 1LL;
v2 = a1;
v3 = 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);
}
v4 = TagLists;
if ( !*(_DWORD *)(TagLists + 308) )
{
if ( !*(_DWORD *)(TagLists + 164) )
{
result = 1LL;
goto LABEL_10;
}
v10 = a1[35];
if ( v10 )
{
result = CheckElo(v10, TagLists + 160);
if ( (_DWORD)result )
goto LABEL_10;
v11 = v2[2];
if ( v11 )
{
result = CheckElo(v11, v4 + 160);
goto LABEL_10;
}
}
else
{
v12 = v2[2];
if ( v12 )
{
result = CheckElo(v12, TagLists + 160);
goto LABEL_10;
}
}
return 0LL;
}
v5 = a1[34];
if ( !v5 )
{
v9 = a1[1];
if ( v9 )
{
result = CheckList(1, v9, TagLists + 304);
goto LABEL_10;
}
return 0LL;
}
result = CheckList(34, v5, TagLists + 304);
if ( !(_DWORD)result )
{
v7 = a1[1];
if ( v7 )
{
result = CheckList(1, v7, v4 + 304);
goto LABEL_10;
}
return 0LL;
}
LABEL_10:
if ( (_DWORD)result && v3 > 0 )
{
v8 = 0;
do
{
if ( (unsigned int)(v8 - 9) > 1 && v8 != 19 && *(_DWORD *)(v4 + 4) )
{
v13 = *v2;
if ( !*v2 )
return 0LL;
if ( v8 == 8 )
{
result = CheckDate(v13, v4);
}
else if ( v8 == 35 || v8 == 2 )
{
result = CheckElo(v13, v4);
}
else
{
result = CheckList(v8, *v2, v4);
}
}
++v8;
v4 += 16LL;
++v2;
}
while ( v3 > v8 && (_DWORD)result );
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func10(char **a1, int a2)
{
char **v2; // rbp
int v3; // er13
__int64 v4; // r12
char *v5; // rsi
__int64 result; // rax
char *v7; // rsi
int v8; // ebx
char *v9; // rsi
const char *v10; // rdi
const char *v11; // rdi
const char *v12; // rdi
char *v13; // rdi

if ( !GlobalState[11] )
return 1LL;
v2 = a1;
v3 = 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);
}
v4 = TagLists;
if ( !*(_DWORD *)(TagLists + 308) )
{
if ( !*(_DWORD *)(TagLists + 164) )
{
result = 1LL;
goto LABEL_10;
}
v10 = a1[35];
if ( v10 )
{
result = func5(v10, TagLists + 160);
if ( (_DWORD)result )
goto LABEL_10;
v11 = v2[2];
if ( v11 )
{
result = func5(v11, v4 + 160);
goto LABEL_10;
}
}
else
{
v12 = v2[2];
if ( v12 )
{
result = func5(v12, TagLists + 160);
goto LABEL_10;
}
}
return 0LL;
}
v5 = a1[34];
if ( !v5 )
{
v9 = a1[1];
if ( v9 )
{
result = func6(1, v9, TagLists + 304);
goto LABEL_10;
}
return 0LL;
}
result = func6(34, v5, TagLists + 304);
if ( !(_DWORD)result )
{
v7 = a1[1];
if ( v7 )
{
result = func6(1, v7, v4 + 304);
goto LABEL_10;
}
return 0LL;
}
LABEL_10:
if ( (_DWORD)result && v3 > 0 )
{
v8 = 0;
do
{
if ( (unsigned int)(v8 - 9) > 1 && v8 != 19 && *(_DWORD *)(v4 + 4) )
{
v13 = *v2;
if ( !*v2 )
return 0LL;
if ( v8 == 8 )
{
result = func4(v13, v4);
}
else if ( v8 == 35 || v8 == 2 )
{
result = func5(v13, v4);
}
else
{
result = func6(v8, *v2, v4);
}
}
++v8;
v4 += 16LL;
++v2;
}
while ( v3 > v8 && (_DWORD)result );
}
return result;
}

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)
{
__int64 result; // rax
char *v2; // rsi

result = 1LL;
if ( GlobalState[11] && *(_DWORD *)(TagLists + 148) )
{
v2 = *(char **)(a1 + 72);
result = 0LL;
if ( v2 )
result = CheckList(9, v2, TagLists + 144);
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func11(__int64 a1)
{
__int64 result; // rax
char *v2; // rsi

result = 1LL;
if ( GlobalState[11] && *(_DWORD *)(TagLists + 148) )
{
v2 = *(char **)(a1 + 72);
result = 0LL;
if ( v2 )
result = func6(9, v2, TagLists + 144);
}
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;
}


repo: natearn/Spong

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

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

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() {}


main

canonical_name: main

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 *[]


strupper

repo: nathanpc/coconut-basic

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

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

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

v1 = strdup(a1);
v2 = *__ctype_toupper_loc();
v3 = v1;
do
{
v4 = v2[*v3++];
*(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
char *v5; // rdx

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

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

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

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
size_t v9; // r12
size_t v10; // rax
char *v11; // rax

v6 = strtok(a1, " ");
strcpy(a2, v6);
v7 = strtok(0LL, " ");
v8 = strupper(v7);
strcpy(a3, v8);
v9 = strlen(a2);
v10 = strlen(a3);
v11 = strdup(&a1[v9 + 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
size_t v9; // r12
size_t v10; // rax
char *v11; // rax

v6 = strtok(a1, " ");
strcpy(a2, v6);
v7 = strtok(0LL, " ");
v8 = func7(v7);
strcpy(a3, v8);
v9 = strlen(a2);
v10 = strlen(a3);
v11 = strdup(&a1[v9 + 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() {
}


decompiled_code:
int __fastcall basic_print(char *a1)
{
char *v1; // rax
char *v2; // rbx
char v3; // bp
size_t v4; // rax
char *v5; // rax
char *v6; // rax
size_t v7; // rax
char *v8; // rax

v1 = strtok(a1, ",");
if ( v1 )
{
v2 = v1;
v3 = 0;
do
{
if ( *v2 == 32 )
v2 = strdup(v2 + 1);
if ( *v2 == 34 )
{
v4 = strlen(v2);
if ( v2[v4 - 1] == 34 )
{
v6 = strndup(v2 + 1, v4 - 2);
repl_print(v6);
}
else
{
v5 = strdup(v2 + 1);
repl_print(v5);
v3 = 1;
}
goto LABEL_9;
}
if ( v3 )
{
if ( v2[strlen(v2) - 1] == 34 )
{
LABEL_15:
repl_print(",");
v7 = strlen(v2);
v8 = strndup(v2, v7 - 1);
repl_print(v8);
v3 = 0;
goto LABEL_9;
}
repl_print(",");
repl_print(v2);
repl_print(",");
}
else
{
if ( v2[strlen(v2) - 1] == 34 )
goto LABEL_15;
repl_print(v2);
}
LABEL_9:
v2 = strtok(0LL, ",");
}
while ( v2 );
}
return repl_print("\n");
}

canonical_decompiled_code:
int __fastcall func13(char *a1)
{
char *v1; // rax
char *v2; // rbx
char v3; // bp
size_t v4; // rax
char *v5; // rax
char *v6; // rax
size_t v7; // rax
char *v8; // rax

v1 = strtok(a1, ",");
if ( v1 )
{
v2 = v1;
v3 = 0;
do
{
if ( *v2 == 32 )
v2 = strdup(v2 + 1);
if ( *v2 == 34 )
{
v4 = strlen(v2);
if ( v2[v4 - 1] == 34 )
{
v6 = strndup(v2 + 1, v4 - 2);
func10(v6);
}
else
{
v5 = strdup(v2 + 1);
func10(v5);
v3 = 1;
}
goto LABEL_9;
}
if ( v3 )
{
if ( v2[strlen(v2) - 1] == 34 )
{
LABEL_15:
func10(",");
v7 = strlen(v2);
v8 = strndup(v2, v7 - 1);
func10(v8);
v3 = 0;
goto LABEL_9;
}
func10(",");
func10(v2);
func10(",");
}
else
{
if ( v2[strlen(v2) - 1] == 34 )
goto LABEL_15;
func10(v2);
}
LABEL_9:
v2 = strtok(0LL, ",");
}
while ( v2 );
}
return func10("\n");
}

original_code:
void basic_print(char *args) {
 _Bool contains_quote = 0;
 char *token = strtok(args, ",");
 while (token != ((void *)0)) {
  if (token[0] == ' ') {
   token = strdup(token + 1);
  }
  if (token[0] == '"' && token[strlen(token) - 1] == '"') {
   repl_print(strndup(token + 1, strlen(token) - 2));
  } else if (token[0] == '"') {
   contains_quote = 1;
   repl_print(strdup(token + 1));
  } else if (contains_quote && token[strlen(token) - 1] != '"') {
   repl_print(",");
   repl_print(token);
   repl_print(",");
  } else if (token[strlen(token) - 1] == '"') {
   contains_quote = 0;
   repl_print(",");
   repl_print(strndup(token, strlen(token) - 1));
  } else {
   repl_print(token);
  }
  token = strtok(((void *)0), ",");
 }
 repl_print("\n");
}

variable_types:
token
char *


decompiled_code:
int __fastcall interpret_line(char *src)
{
char *v1; // r12
char *v2; // rbx
char *v3; // rbp
char v5[280]; // [rsp+0h] [rbp-118h] BYREF

strcpy(v5, src);
v1 = (char *)malloc(5uLL);
v2 = (char *)malloc(0x14uLL);
v3 = (char *)malloc(0xFFuLL);
function_parts(v5, v1, v2, v3);
if ( strcmp(v2, "PRINT") )
return repl_print("Error: Unknown command.\n");
if ( strtok(0LL, " ") )
return basic_print(v3);
return repl_print("Error: Not enough arguments.\n");
}

canonical_decompiled_code:
int __fastcall func14(char *src)
{
char *v1; // r12
char *v2; // rbx
char *v3; // rbp
char v5[280]; // [rsp+0h] [rbp-118h] BYREF

strcpy(v5, src);
v1 = (char *)malloc(5uLL);
v2 = (char *)malloc(0x14uLL);
v3 = (char *)malloc(0xFFuLL);
func9(v5, v1, v2, v3);
if ( strcmp(v2, "PRINT") )
return func10("Error: Unknown command.\n");
if ( strtok(0LL, " ") )
return func13(v3);
return func10("Error: Not enough arguments.\n");
}

original_code:
void interpret_line(const char *line, _Bool program) {
 char cline[256];
 strcpy(cline, line);
 char *linenum = (char*)malloc(5);
 char *keyword = (char*)malloc(20);
 char *args = (char*)malloc(255);
 function_parts(cline, linenum, keyword, args);
 if (strcmp(keyword, "PRINT") == 0) {
  if (strtok(((void *)0), " ") == ((void *)0)) {
   repl_print("Error: Not enough arguments.\n");
   return;
  }
  basic_print(args);
 } else {
  repl_print("Error: Unknown command.\n");
 }
}

canonical_original_code:
void interpret_line(char *line, _Bool program) {
 char cline[256];
 strcpy(cline, line);
 char *linenum = (char*)malloc(5);
 char *keyword = (char*)malloc(20);
 char *args = (char*)malloc(255);
 function_parts(cline, linenum, keyword, args);
 if (strcmp(keyword, "PRINT") == 0) {
  if (strtok(((void *)0), " ") == ((void *)0)) {
   repl_print("Error: Not enough arguments.\n");
   return;
  }
  basic_print(args);
 } else {
  repl_print("Error: Unknown command.\n");
 }
}

variable_types:
cline
char [256]


repl

decompiled_code:
void __noreturn repl()
{
char v0[264]; // [rsp+0h] [rbp-108h] BYREF

while ( 1 )
{
repl_print("> ");
repl_gets((__int64)v0);
interpret_line(v0);
}
}

original_code:
void repl() {
 while (1) {
  repl_print("> ");
  char line[256];
  repl_gets(line);
  interpret_line(line, 0);
 }
}

variable_types:
line
char [256]


main

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


parseURLField

repo: nathanwiegand/urlparser

decompiled_code:
__int64 __fastcall parseURLField(unsigned __int8 *a1, _QWORD *a2, int a3)
{
unsigned __int64 v5; // rdx
unsigned int v6; // ecx
unsigned __int8 *v7; // rax
unsigned __int64 v8; // rcx
unsigned __int64 v9; // r10
int v10; // esi
unsigned __int64 v11; // rdx
unsigned __int8 *v12; // rax
unsigned __int64 v13; // rsi
int v14; // edx
unsigned __int64 v15; // rcx
unsigned __int64 v16; // rsi
int v17; // eax
unsigned __int64 v18; // rsi
int v19; // ecx
unsigned __int64 v20; // rdx
int v21; // ecx
unsigned __int64 v22; // rdi
int v23; // esi
unsigned __int64 v24; // rdx
unsigned __int8 *v26; // rcx
unsigned __int8 v27; // al
int v28; // esi
int v29; // ecx
_BYTE *v30; // rax
int v31; // edx
int v32; // ecx
int v33; // [rsp+Ch] [rbp-44h]
int v34; // [rsp+Ch] [rbp-44h]
__int64 v35; // [rsp+10h] [rbp-40h]
int v36; // [rsp+1Ch] [rbp-34h]
__int64 v37; // [rsp+20h] [rbp-30h]
__int64 v38; // [rsp+28h] [rbp-28h]
int v39; // [rsp+34h] [rbp-1Ch]
__int64 v40; // [rsp+38h] [rbp-18h]
int v41; // [rsp+44h] [rbp-Ch]
__int64 v42; // [rsp+48h] [rbp-8h]

v33 = 0;
LODWORD(v35) = 0;
if ( !a1 )
return 1;
v5 = *a1;
v6 = 1;
if ( (_BYTE)v5 )
{
if ( (unsigned __int8)v5 > 0x3Fu || (v7 = a1, v8 = 0x8400800800000000LL, !_bittest64((const __int64 *)&v8, v5)) )
{
v7 = a1;
v9 = 0x8400800800000001LL;
do
{
do
{
v10 = 1 - (_DWORD)a1 + (_DWORD)v7++;
v5 = *v7;
}
while ( (unsigned __int8)v5 > 0x3Fu );
}
while ( !_bittest64((const __int64 *)&v9, v5) );
v33 = v10;
}
HIDWORD(v35) = v33;
if ( (_BYTE)v5 == 58 )
{
v34 = v33 + 1;
a1 = v7 + 1;
}
else
{
HIDWORD(v35) = 0;
v34 = 0;
}
*a2 = v35;
v6 = 0;
if ( a3 != 2 )
{
LODWORD(v37) = v34;
HIDWORD(v37) = v34;
if ( *a1 != 47 || a1[1] != 47 )
{
LABEL_13:
a2[1] = v37;
v6 = 0;
if ( a3 == 4 )
return v6;
HIDWORD(v38) = HIDWORD(v37);
LODWORD(v38) = HIDWORD(v37);
v11 = *a1;
if ( (unsigned __int8)v11 > 0x3Fu )
{
v12 = a1;
}
else
{
v12 = a1;
v13 = 0x8000000800000001LL;
if ( _bittest64((const __int64 *)&v13, v11) )
goto LABEL_33;
}
v21 = HIDWORD(v37) + 1 - (_DWORD)a1;
v22 = 0x8000000800000001LL;
do
{
do
{
v23 = v21 + (_DWORD)v12++;
v24 = *v12;
}
while ( (unsigned __int8)v24 > 0x3Fu );
}
while ( !_bittest64((const __int64 *)&v22, v24) );
HIDWORD(v38) = v23;
LABEL_33:
a2[2] = v38;
v6 = 0;
if ( a3 != 5 )
{
LODWORD(v40) = HIDWORD(v38);
HIDWORD(v40) = HIDWORD(v38);
if ( *v12 == 63 )
{
LODWORD(v40) = HIDWORD(v38) + 1;
v39 = HIDWORD(v38) + 1;
v26 = v12 + 1;
v27 = v12[1];
if ( v27 == 35 || !v27 )
{
v12 = v26;
}
else
{
v12 = v26;
do
v28 = HIDWORD(v38) + 2 - (_DWORD)v26 + (_DWORD)v12++;
while ( *v12 != 35 && *v12 );
v39 = v28;
}
HIDWORD(v40) = v39;
}
a2[3] = v40;
v6 = 0;
if ( a3 != 7 )
{
LODWORD(v42) = HIDWORD(v40);
HIDWORD(v42) = HIDWORD(v40);
if ( *v12 == 35 )
{
LODWORD(v42) = HIDWORD(v40) + 1;
v41 = HIDWORD(v40) + 1;
v29 = (_DWORD)v12 + 1;
if ( v12[1] )
{
v30 = v12 + 1;
v31 = HIDWORD(v40) + 2 - v29;
do
v32 = v31 + (_DWORD)v30++;
while ( *v30 );
v41 = v32;
}
HIDWORD(v42) = v41;
}
a2[4] = v42;
v6 = 0;
}
}
return v6;
}
LODWORD(v37) = v34 + 2;
v36 = v34 + 2;
v14 = (_DWORD)a1 + 2;
v15 = a1[2];
if ( (unsigned __int8)v15 > 0x3Fu )
{
a1 += 2;
}
else
{
a1 += 2;
v16 = 0x8000800800000001LL;
if ( _bittest64((const __int64 *)&v16, v15) )
{
LABEL_27:
HIDWORD(v37) = v36;
goto LABEL_13;
}
}
v17 = v34 + 3 - v14;
v18 = 0x8000800800000001LL;
do
{
do
{
v19 = v17 + (_DWORD)a1++;
v20 = *a1;
}
while ( (unsigned __int8)v20 > 0x3Fu );
}
while ( !_bittest64((const __int64 *)&v18, v20) );
v36 = v19;
goto LABEL_27;
}
}
return v6;
}

original_code:
int parseURLField(const char *url, URL *storage, URLField field) {
  URLGroup groups[10];
  const char *c = url;
  bzero(groups, sizeof(URLGroup)*10);
  if(!c || *c == '\0') {
    return 1;
  }
  while(*c != ':' && *c != '/' && *c != '?' && *c != '#' && *c != '\0') {
    groups[1].end++;
    c++;
  }
  groups[2].end = groups[1].end;
  if(*c == ':') {
    groups[1].end++;
    c++;
  } else {
    groups[1].start = groups[2].start = 0;
    groups[1].end = groups[2].end = 0;
    c = url;
  }
  storage->scheme = groups[2];
  if(field == URL_SCHEME) {
    return 0;
  }
  groups[3].end = groups[3].start = groups[1].end;
  groups[4].end = groups[4].start = groups[1].end;
  if(*c == '/' && *(c+1) == '/') {
    groups[4].start += 2;
    groups[3].end += 2;
    c += 2;
    while(*c != '/' && *c != '?' && *c != '#' && *c != '\0') {
      groups[3].end++;
      c++;
    }
    groups[4].end = groups[3].end;
  }
  storage->authority = groups[4];
  if(field == URL_AUTHORITY) {
    return 0;
  }
  groups[5].start = groups[5].end = groups[4].end;
  while(*c != '?' && *c != '#' && *c != '\0') {
    groups[5].end++;
    c++;
  }
  storage->path = groups[5];
  if(field == URL_PATH) {
    return 0;
  }
  groups[6].end = groups[6].start = groups[5].end;
  groups[7].end = groups[7].start = groups[5].end;
  if(*c == '?') {
    groups[7].start++;
    groups[6].end++;
    c++;
    while(*c != '#' && *c != '\0') {
      groups[6].end ++;
      c++;
    }
    groups[7].end = groups[6].end;
  }
  storage->query = groups[7];
  if(field == URL_QUERY) {
    return 0;
  }
  groups[8].end = groups[8].start = groups[7].end;
  groups[9].end = groups[9].start = groups[7].end;
  if(*c == '#') {
    groups[9].start++;
    groups[8].end++;
    c++;
    while(*c != '\0') {
      groups[8].end ++;
      c++;
    }
    groups[9].end = groups[8].end;
  }
  storage->fragment = groups[9];
  return 0;
}

canonical_original_code:
int parseURLField(char *url, struct URL *storage, enum URLField field) {
  struct URLGroup groups[10];
  char *c = url;
  bzero(groups, sizeof(URLGroup)*10);
  if(!c || *c == '\0') {
    return 1;
  }
  while(*c != ':' && *c != '/' && *c != '?' && *c != '#' && *c != '\0') {
    groups[1].end++;
    c++;
  }
  groups[2].end = groups[1].end;
  if(*c == ':') {
    groups[1].end++;
    c++;
  } else {
    groups[1].start = groups[2].start = 0;
    groups[1].end = groups[2].end = 0;
    c = url;
  }
  storage->scheme = groups[2];
  if(field == URL_SCHEME) {
    return 0;
  }
  groups[3].end = groups[3].start = groups[1].end;
  groups[4].end = groups[4].start = groups[1].end;
  if(*c == '/' && *(c+1) == '/') {
    groups[4].start += 2;
    groups[3].end += 2;
    c += 2;
    while(*c != '/' && *c != '?' && *c != '#' && *c != '\0') {
      groups[3].end++;
      c++;
    }
    groups[4].end = groups[3].end;
  }
  storage->authority = groups[4];
  if(field == URL_AUTHORITY) {
    return 0;
  }
  groups[5].start = groups[5].end = groups[4].end;
  while(*c != '?' && *c != '#' && *c != '\0') {
    groups[5].end++;
    c++;
  }
  storage->path = groups[5];
  if(field == URL_PATH) {
    return 0;
  }
  groups[6].end = groups[6].start = groups[5].end;
  groups[7].end = groups[7].start = groups[5].end;
  if(*c == '?') {
    groups[7].start++;
    groups[6].end++;
    c++;
    while(*c != '#' && *c != '\0') {
      groups[6].end ++;
      c++;
    }
    groups[7].end = groups[6].end;
  }
  storage->query = groups[7];
  if(field == URL_QUERY) {
    return 0;
  }
  groups[8].end = groups[8].start = groups[7].end;
  groups[9].end = groups[9].start = groups[7].end;
  if(*c == '#') {
    groups[9].start++;
    groups[8].end++;
    c++;
    while(*c != '\0') {
      groups[8].end ++;
      c++;
    }
    groups[9].end = groups[8].end;
  }
  storage->fragment = groups[9];
  return 0;
}

variable_types:
url
char *

variable_types: struct URL { struct URLGroup { int start; int end; } scheme; struct URLGroup authority; struct URLGroup path; struct URLGroup query; struct URLGroup fragment; } *

variable_types: enum URLField { URL_SCHEME=2, URL_AUTHORITY=4, URL_PATH=5, URL_QUERY=7, URL_FRAGMENT=9 }

variable_types: struct URLGroup { int start; int end; } [10]

variable_types:
c
char *

user_defined_types: struct URL { struct URLGroup scheme; struct URLGroup authority; struct URLGroup path; struct URLGroup query; struct URLGroup fragment; }


parseURL

decompiled_code:
__int64 __fastcall parseURL(unsigned __int8 *a1, _QWORD *a2)
{
return parseURLField(a1, a2, 0);
}

canonical_decompiled_code:
__int64 __fastcall func1(unsigned __int8 *a1, _QWORD *a2)
{
return func0(a1, a2, 0);
}

original_code:
int parseURL(const char *url, URL *storage) {
  return parseURLField(url, storage, 0);
}

canonical_original_code:
int parseURL(char *url, struct URL *storage) {
  return parseURLField(url, storage, 0);
}


readURLField

decompiled_code:
void *__fastcall readURLField(__int64 a1, __int64 a2)
{
int v2; // ebx
void *v3; // r12

v2 = HIDWORD(a2) - a2;
v3 = &unk_3AE;
if ( HIDWORD(a2) - (int)a2 > 0 )
{
v3 = malloc(v2 + 1);
memcpy(v3, (const void *)(a1 + (int)a2), v2);
*((_BYTE *)v3 + v2) = 0;
}
return v3;
}

canonical_decompiled_code:
void *__fastcall func2(__int64 a1, __int64 a2)
{
int v2; // ebx
void *v3; // r12

v2 = HIDWORD(a2) - a2;
v3 = &unk_3AE;
if ( HIDWORD(a2) - (int)a2 > 0 )
{
v3 = malloc(v2 + 1);
memcpy(v3, (const void *)(a1 + (int)a2), v2);
*((_BYTE *)v3 + v2) = 0;
}
return v3;
}

original_code:
char *readURLField(const char* url, URLGroup field) {
  char *response;
  if(field.end - field.start <= 0)
    return "";
  response = (char*) malloc((sizeof(char)) * (field.end - field.start + 1));
  bcopy(url + field.start, response, field.end - field.start);
  response[field.end - field.start] = '\0';
  return response;
}

canonical_original_code:
char *readURLField(char *url, struct URLGroup field) {
  char *response;
  if(field.end - field.start <= 0)
    return "";
  response = (char *) malloc((sizeof(char)) * (field.end - field.start + 1));
  bcopy(url + field.start, response, field.end - field.start);
  response[field.end - field.start] = '\0';
  return response;
}

variable_types:
field
struct URLGroup { int start; int end; }

variable_types:
response
char *


cmpURLField

decompiled_code:
int __fastcall cmpURLField(__int64 a1, __int64 a2, _BYTE *a3)
{
_BOOL4 v5; // edx

if ( SHIDWORD(a2) < (int)a2 )
return -1;
if ( HIDWORD(a2) != (_DWORD)a2 )
return memcmp(a3, (const void *)(a1 + (int)a2), HIDWORD(a2) - (int)a2);
v5 = 0;
if ( a3 )
v5 = *a3 != 0;
return v5;
}

canonical_decompiled_code:
int __fastcall func3(__int64 a1, __int64 a2, _BYTE *a3)
{
_BOOL4 v5; // edx

if ( SHIDWORD(a2) < (int)a2 )
return -1;
if ( HIDWORD(a2) != (_DWORD)a2 )
return memcmp(a3, (const void *)(a1 + (int)a2), HIDWORD(a2) - (int)a2);
v5 = 0;
if ( a3 )
v5 = *a3 != 0;
return v5;
}

original_code:
int cmpURLField(const char *url, URLGroup field, const char *to) {
  if(field.start > field.end) {
    return -1;
  }
  if(field.start == field.end) {
    return !(to == 0 || *to == '\0');
  }
  return bcmp(to, url + field.start, field.end - field.start);
}

canonical_original_code:
int cmpURLField(char *url, struct URLGroup field, char *to) {
  if(field.start > field.end) {
    return -1;
  }
  if(field.start == field.end) {
    return !(to == 0 || *to == '\0');
  }
  return bcmp(to, url + field.start, field.end - field.start);
}

variable_types:
to
char *


decompiled_code:
__int64 __fastcall My402ListLength(unsigned int *a1)
{
__int64 result; // rax

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

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

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

original_code:
int My402ListLength(My402List *pList){
 int length = 0;
 if( pList != ((void *)0)){
  length = pList->num_members;
 }
 return length;
}

canonical_original_code:
int My402ListLength(struct tagMy402List *pList){
 int length = 0;
 if( pList != ((void *)0)){
  length = pList->num_members;
 }
 return length;
}

variable_types: struct tagMy402List { int num_members; struct tagMy402ListElem { void *obj; struct tagMy402ListElem *next; struct tagMy402ListElem *prev; } anchor; int (*Length)(struct tagMy402List *); int (*Empty)(struct tagMy402List *); int (*Append)(struct tagMy402List *, void *); int (*Prepend)(struct tagMy402List *, void *); void (*Unlink)(struct tagMy402List *, struct tagMy402ListElem *); void (*UnlinkAll)(struct tagMy402List *); int (*InsertBefore)(struct tagMy402List *, void *, struct tagMy402ListElem *); int (*InsertAfter)(struct tagMy402List *, void *, struct tagMy402ListElem *); struct tagMy402ListElem *(*First)(struct tagMy402List *); struct tagMy402ListElem *(*Last)(struct tagMy402List *); struct tagMy402ListElem *(*Next)(struct tagMy402List *, struct tagMy402ListElem *cur); struct tagMy402ListElem *(*Prev)(struct tagMy402List *, struct tagMy402ListElem *cur); struct tagMy402ListElem *(*Find)(struct tagMy402List *, void *obj); } *

variable_types: length int

user_defined_types: struct tagMy402List { int num_members; struct tagMy402ListElem anchor; int (*Length)(struct tagMy402List *); int (*Empty)(struct tagMy402List *); int (*Append)(struct tagMy402List *, void *); int (*Prepend)(struct tagMy402List *, void *); void (*Unlink)(struct tagMy402List *, struct tagMy402ListElem *); void (*UnlinkAll)(struct tagMy402List *); int (*InsertBefore)(struct tagMy402List *, void *, struct tagMy402ListElem *); int (*InsertAfter)(struct tagMy402List *, void *, struct tagMy402ListElem *); struct tagMy402ListElem *(*First)(struct tagMy402List *); struct tagMy402ListElem *(*Last)(struct tagMy402List *); struct tagMy402ListElem *(*Next)(struct tagMy402List *, struct tagMy402ListElem *cur); struct tagMy402ListElem *(*Prev)(struct tagMy402List *, struct tagMy402ListElem *cur); struct tagMy402ListElem *(*Find)(struct tagMy402List *, void *obj); }