decompiled_code:
__int64 __fastcall irc_init(__int64 a1)
{
irc_set_nick(a1, *(const char **)(a1 + 1752));
irc_set_user(a1, "ircbot", "github.com/neuro-sys/neuro-bot");
*(_QWORD *)(a1 + 1720) = 0LL;
return plugin_start_daemons(a1);
}

canonical_decompiled_code:
__int64 __fastcall func14(__int64 a1)
{
func12(a1, *(const char **)(a1 + 1752));
func13(a1, "ircbot", "github.com/neuro-sys/neuro-bot");
*(_QWORD *)(a1 + 1720) = 0LL;
return plugin_start_daemons(a1);
}

original_code:
static void irc_init(struct irc_t * irc)
{
    irc_set_nick(irc, irc->nickname);
    irc_set_user(irc, "ircbot", "github.com/neuro-sys/neuro-bot");
    do { (&irc->channel_list_head)->lh_first = ((void *)0); } while ( 0);
    plugin_start_daemons(irc);
}

canonical_original_code:
static void irc_init(struct irc_t *irc)
{
    irc_set_nick(irc, irc->nickname);
    irc_set_user(irc, "ircbot", "github.com/neuro-sys/neuro-bot");
    do { (&irc->channel_list_head)->lh_first = ((void *)0); } while ( 0);
    plugin_start_daemons(irc);
}


repo: neuro-sys/neuro-bot

decompiled_code:
__int64 __fastcall irc_identify_to_auth(__int64 a1, const char *a2)
{
size_t v2; // rax
char v4[520]; // [rsp+0h] [rbp-208h] BYREF

sprintf(v4, "PRIVMSG NickServ :identify %s\r\n", a2);
v2 = strlen(v4);
return socket_write(*(_QWORD *)(a1 + 1728), v4, v2);
}

canonical_decompiled_code:
__int64 __fastcall func15(__int64 a1, const char *a2)
{
size_t v2; // rax
char v4[520]; // [rsp+0h] [rbp-208h] BYREF

sprintf(v4, "PRIVMSG NickServ :identify %s\r\n", a2);
v2 = strlen(v4);
return socket_write(*(_QWORD *)(a1 + 1728), v4, v2);
}

original_code:
void irc_identify_to_auth(struct irc_t * irc, char * password)
{
    char buffer[510];
    sprintf(buffer, "PRIVMSG NickServ :identify %s\r\n", password);
    socket_write(irc->sockfd, buffer, strlen(buffer));
}

canonical_original_code:
void irc_identify_to_auth(struct irc_t *irc, char *password)
{
    char buffer[510];
    sprintf(buffer, "PRIVMSG NickServ :identify %s\r\n", password);
    socket_write(irc->sockfd, buffer, strlen(buffer));
}

variable_types: struct irc_t { struct message_t { struct prefix_t { char servername[100]; struct nickname_t { char nickname[100]; char user[100]; char host[100]; } nickname; } prefix; char command[10]; char params[14][50]; char trailing[510]; } message; char from[100]; struct channel_list_t { struct channel_t { char *name; struct { struct user_t { char *name; struct { struct user_t *le_next; struct user_t **le_prev; } list; } *lh_first; } user_list_head; struct { struct channel_t *le_next; struct channel_t **le_prev; } list; } *lh_first; } channel_list_head; void *sockfd; char *hostname; char *port; char *nickname; char *password; char *admin; struct ajoin_channel_list_t { struct ajoin_channel_t { char *channel_name; struct { struct ajoin_channel_t *le_next; struct ajoin_channel_t **le_prev; } list; } *lh_first; } ajoin_channels_head; } *

variable_types:
password
char *

variable_types:
buffer
char [510]

return_type: void

user_defined_types: struct irc_t { struct message_t message; char from[100]; struct channel_list_t channel_list_head; void *sockfd; char *hostname; char *port; char *nickname; char *password; char *admin; struct ajoin_channel_list_t ajoin_channels_head; }

user_defined_types: struct message_t { struct prefix_t prefix; char command[10]; char params[14][50]; char trailing[510]; }

user_defined_types: struct channel_list_t { struct channel_t *lh_first; }

user_defined_types: struct ajoin_channel_list_t { struct ajoin_channel_t *lh_first; }

user_defined_types: struct prefix_t { char servername[100]; struct nickname_t nickname; }

user_defined_types: struct channel_t { char *name; struct { struct user_t *lh_first; } user_list_head; struct { struct channel_t *le_next; struct channel_t **le_prev; } list; }


decompiled_code:
__int64 __fastcall irc_join_channel(__int64 a1, const char *a2)
{
size_t v2; // rax
char v4[520]; // [rsp+0h] [rbp-208h] BYREF

sprintf(v4, "JOIN %s\r\n", a2);
v2 = strlen(v4);
return socket_write(*(_QWORD *)(a1 + 1728), v4, v2);
}

canonical_decompiled_code:
__int64 __fastcall func16(__int64 a1, const char *a2)
{
size_t v2; // rax
char v4[520]; // [rsp+0h] [rbp-208h] BYREF

sprintf(v4, "JOIN %s\r\n", a2);
v2 = strlen(v4);
return socket_write(*(_QWORD *)(a1 + 1728), v4, v2);
}

original_code:
void irc_join_channel(struct irc_t * irc, char * channel)
{
    char buffer[510];
    sprintf(buffer, "JOIN %s\r\n", channel);
    socket_write(irc->sockfd, buffer, strlen(buffer));
}

canonical_original_code:
void irc_join_channel(struct irc_t *irc, char *channel)
{
    char buffer[510];
    sprintf(buffer, "JOIN %s\r\n", channel);
    socket_write(irc->sockfd, buffer, strlen(buffer));
}

variable_types:
channel
char *

user_defined_types: struct nickname_t { char nickname[100]; char user[100]; char host[100]; }

user_defined_types: struct ajoin_channel_t { char *channel_name; struct { struct ajoin_channel_t *le_next; struct ajoin_channel_t **le_prev; } list; }

user_defined_types: struct user_t { char *name; struct { struct user_t *le_next; struct user_t **le_prev; } list; }


decompiled_code:
void __fastcall process_protocol_commands(__int64 a1)
{
const char *v1; // rdx
__int64 i; // rbx
size_t v3; // rax
const char *v4; // rsi
char v5[536]; // [rsp+0h] [rbp-218h] BYREF

v1 = (const char *)(a1 + 400);
if ( !strcmp("PRIVMSG", (const char *)(a1 + 400)) )
{
process_command_privmsg(a1);
return;
}
if ( !strcmp("PING", v1) )
{
snprintf(v5, 0x1FEuLL, "PONG %s\r\n", (const char *)(a1 + 1110));
v3 = strlen(v5);
socket_write(*(_QWORD *)(a1 + 1728), v5, v3);
return;
}
if ( !strcmp("001", v1) )
{
for ( i = *(_QWORD *)(a1 + 1776); i; i = *(_QWORD *)(i + 8) )
irc_join_channel(a1, *(const char **)i);
}
else
{
if ( !strcmp("353", v1) )
{
process_command_353(a1);
return;
}
if ( !strcmp("NOTICE", v1) )
{
if ( strstr((const char *)(a1 + 1110), "registered") )
{
if ( retry_count_0 <= 3 )
{
fwrite("This nickname seems to be registered. Trying to identify...\n", 1uLL, 0x3CuLL, stderr);
sleep(3u);
v4 = *(const char **)(a1 + 1760);
if ( *v4 )
{
irc_identify_to_auth(a1, v4);
++retry_count_0;
}
}
}
}
else
{
if ( strcmp(v1, "JOIN") )
{
if ( !strcmp(v1, "PART") )
{
if ( !strcmp((const char *)(a1 + 100), *(const char **)(a1 + 1752)) )
{
process_command_part_channel(a1);
return;
}
}
else if ( strcmp(v1, "QUIT") || !strcmp((const char *)(a1 + 100), *(const char **)(a1 + 1752)) )
{
return;
}
process_command_part_user(a1);
return;
}
if ( !strcmp((const char *)(a1 + 100), *(const char **)(a1 + 1752)) )
process_command_join_new_channel(a1);
else
process_command_join_new_user(a1);
}
}
}

canonical_decompiled_code:
void __fastcall func17(__int64 a1)
{
const char *v1; // rdx
__int64 i; // rbx
size_t v3; // rax
const char *v4; // rsi
char v5[536]; // [rsp+0h] [rbp-218h] BYREF

v1 = (const char *)(a1 + 400);
if ( !strcmp("PRIVMSG", (const char *)(a1 + 400)) )
{
func7(a1);
return;
}
if ( !strcmp("PING", v1) )
{
snprintf(v5, 0x1FEuLL, "PONG %s\r\n", (const char *)(a1 + 1110));
v3 = strlen(v5);
socket_write(*(_QWORD *)(a1 + 1728), v5, v3);
return;
}
if ( !strcmp("001", v1) )
{
for ( i = *(_QWORD *)(a1 + 1776); i; i = *(_QWORD *)(i + 8) )
func16(a1, *(const char **)i);
}
else
{
if ( !strcmp("353", v1) )
{
func8(a1);
return;
}
if ( !strcmp("NOTICE", v1) )
{
if ( strstr((const char *)(a1 + 1110), "registered") )
{
if ( retry_count_0 <= 3 )
{
fwrite("This nickname seems to be registered. Trying to identify...\n", 1uLL, 0x3CuLL, stderr);
sleep(3u);
v4 = *(const char **)(a1 + 1760);
if ( *v4 )
{
func15(a1, v4);
++retry_count_0;
}
}
}
}
else
{
if ( strcmp(v1, "JOIN") )
{
if ( !strcmp(v1, "PART") )
{
if ( !strcmp((const char *)(a1 + 100), *(const char **)(a1 + 1752)) )
{
func2(a1);
return;
}
}
else if ( strcmp(v1, "QUIT") || !strcmp((const char *)(a1 + 100), *(const char **)(a1 + 1752)) )
{
return;
}
func11(a1);
return;
}
if ( !strcmp((const char *)(a1 + 100), *(const char **)(a1 + 1752)) )
func10(a1);
else
func9(a1);
}
}
}

original_code:
static void process_protocol_commands (struct irc_t * irc)
{
    char response[512];
    if (strcmp("PRIVMSG", irc->message.command) == 0) {
        process_command_privmsg (irc);
    } else if (strcmp("PING", irc->message.command) == 0) {
        snprintf (response, 510, "PONG %s\r\n", irc->message.trailing);
        socket_write(irc->sockfd, response, strlen(response));
    } else if (strcmp("001", irc->message.command) == 0) {
        struct ajoin_channel_t * iterator;
        for ((iterator) = ((&irc->ajoin_channels_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
            irc_join_channel(irc, iterator->channel_name);
        }
    } else if (strcmp("353", irc->message.command) == 0) {
        process_command_353(irc);
    } else if (strcmp("NOTICE", irc->message.command) == 0) {
        if (strstr(irc->message.trailing, "registered" ) ) {
            static int retry_count = 0;
            if (retry_count > 3) {
                return;
            }
            fprintf(stderr, "This nickname seems to be registered. Trying to identify...\n");;
            sleep(3);
            if (strcmp(irc->password, "")) {
                irc_identify_to_auth(irc, irc->password);
                retry_count++;
            }
        }
    } else if (strcmp(irc->message.command, "JOIN") == 0) {
        if (strcmp(irc->message.prefix.nickname.nickname, irc->nickname) == 0) {
            process_command_join_new_channel(irc);
        } else {
            process_command_join_new_user(irc);
        }
    } else if (strcmp(irc->message.command, "PART") == 0) {
        if (strcmp(irc->message.prefix.nickname.nickname, irc->nickname) == 0) {
            process_command_part_channel(irc);
        } else {
            process_command_part_user(irc);
        }
    } else if (strcmp(irc->message.command, "QUIT") == 0) {
        if (strcmp(irc->message.prefix.nickname.nickname, irc->nickname) == 0) {
        } else {
            process_command_part_user(irc);
        }
    }
}

canonical_original_code:
static void process_protocol_commands(struct irc_t *irc)
{
    char response[512];
    if (strcmp("PRIVMSG", irc->message.command) == 0) {
        process_command_privmsg (irc);
    } else if (strcmp("PING", irc->message.command) == 0) {
        snprintf (response, 510, "PONG %s\r\n", irc->message.trailing);
        socket_write(irc->sockfd, response, strlen(response));
    } else if (strcmp("001", irc->message.command) == 0) {
        struct ajoin_channel_t *iterator;
        for ((iterator) = ((&irc->ajoin_channels_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
            irc_join_channel(irc, iterator->channel_name);
        }
    } else if (strcmp("353", irc->message.command) == 0) {
        process_command_353(irc);
    } else if (strcmp("NOTICE", irc->message.command) == 0) {
        if (strstr(irc->message.trailing, "registered" ) ) {
            static int retry_count = 0;
            if (retry_count > 3) {
                return;
            }
            fprintf(stderr, "This nickname seems to be registered. Trying to identify...\n");;
            sleep(3);
            if (strcmp(irc->password, "")) {
                irc_identify_to_auth(irc, irc->password);
                retry_count++;
            }
        }
    } else if (strcmp(irc->message.command, "JOIN") == 0) {
        if (strcmp(irc->message.prefix.nickname.nickname, irc->nickname) == 0) {
            process_command_join_new_channel(irc);
        } else {
            process_command_join_new_user(irc);
        }
    } else if (strcmp(irc->message.command, "PART") == 0) {
        if (strcmp(irc->message.prefix.nickname.nickname, irc->nickname) == 0) {
            process_command_part_channel(irc);
        } else {
            process_command_part_user(irc);
        }
    } else if (strcmp(irc->message.command, "QUIT") == 0) {
        if (strcmp(irc->message.prefix.nickname.nickname, irc->nickname) == 0) {
        } else {
            process_command_part_user(irc);
        }
    }
}

variable_types:
response
char [512]

variable_types: struct ajoin_channel_t { char *channel_name; struct { struct ajoin_channel_t *le_next; struct ajoin_channel_t **le_prev; } list; } *


decompiled_code:
void __fastcall irc_process_line(__int64 a1)
{
irc_parser();
print_message_t(a1);
process_protocol_commands(a1);
}

canonical_decompiled_code:
void __fastcall func18(__int64 a1)
{
irc_parser();
print_message_t(a1);
func17(a1);
}

original_code:
static void irc_process_line(struct irc_t * irc, const char * line)
{
    irc_parser(&irc->message, line);
    print_message_t(&irc->message);
    process_protocol_commands(irc);
}

canonical_original_code:
static void irc_process_line(struct irc_t *irc, char *line)
{
    irc_parser(&irc->message, line);
    print_message_t(&irc->message);
    process_protocol_commands(irc);
}

variable_types:
line
char *


decompiled_code:
__int64 __fastcall irc_quit_server(__int64 a1)
{
size_t v1; // rax
__m128i v3; // [rsp+0h] [rbp-208h] BYREF
char v4[8]; // [rsp+10h] [rbp-1F8h] BYREF

strcpy(v4, "it.\r\n");
v3 = _mm_load_si128((const __m128i *)&LC31);
v1 = strlen(v3.m128i_i8);
return socket_write(*(_QWORD *)(a1 + 1728), &v3, v1);
}

canonical_decompiled_code:
__int64 __fastcall func19(__int64 a1)
{
size_t v1; // rax
__m128i v3; // [rsp+0h] [rbp-208h] BYREF
char v4[8]; // [rsp+10h] [rbp-1F8h] BYREF

strcpy(v4, "it.\r\n");
v3 = _mm_load_si128((const __m128i *)&LC31);
v1 = strlen(v3.m128i_i8);
return socket_write(*(_QWORD *)(a1 + 1728), &v3, v1);
}

original_code:
void irc_quit_server(struct irc_t * irc)
{
    char buffer[510];
    snprintf(buffer, sizeof buffer, "QUIT :The bot quit.\r\n");
    socket_write(irc->sockfd, buffer, strlen(buffer));
}

canonical_original_code:
void irc_quit_server(struct irc_t *irc)
{
    char buffer[510];
    snprintf(buffer, sizeof buffer, "QUIT :The bot quit.\r\n");
    socket_write(irc->sockfd, buffer, strlen(buffer));
}


decompiled_code:
__int64 __fastcall irc_free(__int64 a1)
{
__int64 v2; // rdi
__int64 v3; // rbp
const char **v4; // rbp
const char **v5; // rdi

irc_quit_server(a1);
v2 = *(_QWORD *)(a1 + 1720);
if ( v2 )
{
while ( 1 )
{
v3 = *(_QWORD *)(v2 + 16);
if ( !v3 )
break;
channel_free(v2);
v2 = v3;
}
channel_free(v2);
}
v4 = *(const char ***)(a1 + 1776);
if ( v4 )
{
v5 = 0LL;
while ( 1 )
{
free(v5);
fprintf(stderr, "Removing ajoin channel: %s\n", *v4);
free((void *)*v4);
v5 = v4;
if ( !v4[1] )
break;
v4 = (const char **)v4[1];
}
}
free(v4);
free(*(void **)(a1 + 1768));
free(*(void **)(a1 + 1736));
free(*(void **)(a1 + 1752));
free(*(void **)(a1 + 1760));
free(*(void **)(a1 + 1744));
return socket_close(*(_QWORD *)(a1 + 1728));
}

original_code:
void irc_free(struct irc_t * irc)
{
    struct channel_t * iterator, * temp;
    struct ajoin_channel_t * ajoin_iterator, * a_temp;
    if (&irc->channel_list_head == ((void *)0)) {
        return;
    }
    irc_quit_server(irc);
    temp = ((void *)0);
    for ((iterator) = ((&irc->channel_list_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        if (temp) channel_free(temp);
        temp = iterator;
    }
    if (temp) channel_free(temp);
    a_temp = ((void *)0);
    for ((ajoin_iterator) = ((&irc->ajoin_channels_head)->lh_first); (ajoin_iterator); (ajoin_iterator) = ((ajoin_iterator)->list.le_next)) {
        free(a_temp);
        a_temp = ajoin_iterator;
        fprintf(stderr, "Removing ajoin channel: %s\n", ajoin_iterator->channel_name);;
        free(ajoin_iterator->channel_name);
    }
    free(a_temp);
    free(irc->admin);
    free(irc->hostname);
    free(irc->nickname);
    free(irc->password);
    free(irc->port);
    socket_close(irc->sockfd);
}

canonical_original_code:
void irc_free(struct irc_t *irc)
{
    struct channel_t *iterator; struct channel_t *temp;
    struct ajoin_channel_t *ajoin_iterator; struct ajoin_channel_t *a_temp;
    if (&irc->channel_list_head == ((void *)0)) {
        return;
    }
    irc_quit_server(irc);
    temp = ((void *)0);
    for ((iterator) = ((&irc->channel_list_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        if (temp) channel_free(temp);
        temp = iterator;
    }
    if (temp) channel_free(temp);
    a_temp = ((void *)0);
    for ((ajoin_iterator) = ((&irc->ajoin_channels_head)->lh_first); (ajoin_iterator); (ajoin_iterator) = ((ajoin_iterator)->list.le_next)) {
        free(a_temp);
        a_temp = ajoin_iterator;
        fprintf(stderr, "Removing ajoin channel: %s\n", ajoin_iterator->channel_name);;
        free(ajoin_iterator->channel_name);
    }
    free(a_temp);
    free(irc->admin);
    free(irc->hostname);
    free(irc->nickname);
    free(irc->password);
    free(irc->port);
    socket_close(irc->sockfd);
}

variable_types: struct channel_t { char *name; struct { struct user_t { char *name; struct { struct user_t *le_next; struct user_t **le_prev; } list; } *lh_first; } user_list_head; struct { struct channel_t *le_next; struct channel_t **le_prev; } list; } *


decompiled_code:
__int64 __fastcall irc_run(__int64 a1)
{
unsigned int v1; // eax
__int64 v3; // [rsp+0h] [rbp-208h] BYREF

v1 = atoi(*(const char **)(a1 + 1744));
*(_QWORD *)(a1 + 1728) = socket_connect(*(_QWORD *)(a1 + 1736), v1);
irc_init(a1);
while ( (int)socket_readline(*(_QWORD *)(a1 + 1728), &v3, 510LL) >= 0 )
irc_process_line(a1);
return 0xFFFFFFFFLL;
}

canonical_decompiled_code:
__int64 __fastcall func21(__int64 a1)
{
unsigned int v1; // eax
__int64 v3; // [rsp+0h] [rbp-208h] BYREF

v1 = atoi(*(const char **)(a1 + 1744));
*(_QWORD *)(a1 + 1728) = socket_connect(*(_QWORD *)(a1 + 1736), v1);
func14(a1);
while ( (int)socket_readline(*(_QWORD *)(a1 + 1728), &v3, 510LL) >= 0 )
func18(a1);
return 0xFFFFFFFFLL;
}

original_code:
int irc_run(struct irc_t * irc)
{
    if ( (irc->sockfd = socket_connect(irc->hostname, atoi(irc->port))) < 0 ) {
        fprintf(stderr, "Unable to connect to %s:%s\n", irc->hostname, irc->port);;
        exit(0);
    }
    irc_init(irc);
    for (;;)
    {
        char line[510];
        if (socket_readline(irc->sockfd, line, sizeof(line)) < 0) {
            return -1;
        }
        irc_process_line(irc, line);
    }
}

canonical_original_code:
int irc_run(struct irc_t *irc)
{
    if ( (irc->sockfd = socket_connect(irc->hostname, atoi(irc->port))) < 0 ) {
        fprintf(stderr, "Unable to connect to %s:%s\n", irc->hostname, irc->port);;
        exit(0);
    }
    irc_init(irc);
    for (;;)
    {
        char line[510];
        if (socket_readline(irc->sockfd, line, sizeof(line)) < 0) {
            return -1;
        }
        irc_process_line(irc, line);
    }
}

variable_types:
line
char [510]

return_type: int


decompiled_code:
__int64 __fastcall channel_find(__int64 *a1, const char *a2)
{
__int64 i; // r12

for ( i = *a1; i; i = *(_QWORD *)(i + 16) )
{
if ( !strcmp(*(const char **)i, a2) )
break;
}
return i;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 *a1, const char *a2)
{
__int64 i; // r12

for ( i = *a1; i; i = *(_QWORD *)(i + 16) )
{
if ( !strcmp(*(const char **)i, a2) )
break;
}
return i;
}

original_code:
struct channel_t * channel_find(struct channel_list_t * head, char * name)
{
    struct channel_t * iterator;
    for ((iterator) = ((head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        if (strcmp(iterator->name, name) == 0) {
            return iterator;
        }
    }
    return ((void *)0);
}

canonical_original_code:
struct channel_t *channel_find(struct channel_list_t *head, char *name)
{
    struct channel_t *iterator;
    for ((iterator) = ((head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        if (strcmp(iterator->name, name) == 0) {
            return iterator;
        }
    }
    return ((void *)0);
}

variable_types: struct channel_list_t { struct channel_t *lh_first; } *

variable_types:
name
char *

return_type: struct channel_t { char *name; struct { struct user_t { char *name; struct { struct user_t *le_next; struct user_t **le_prev; } list; } *lh_first; } user_list_head; struct { struct channel_t *le_next; struct channel_t **le_prev; } list; } *


decompiled_code:
void __fastcall channel_remove_user(__int64 a1, const char *a2)
{
const char **v2; // rbx
const char **v3; // rbp
const char *v4; // rax
char *v5; // rdi

v2 = *(const char ***)(a1 + 8);
if ( v2 )
{
v3 = 0LL;
do
{
if ( !strcmp(*v2, a2) )
v3 = v2;
v2 = (const char **)v2[1];
}
while ( v2 );
if ( v3 )
{
v4 = v3[1];
if ( v4 )
*((_QWORD *)v4 + 2) = v3[2];
v5 = (char *)*v3;
*(_QWORD *)v3[2] = v4;
free(v5);
free(v3);
}
}
}

canonical_decompiled_code:
void __fastcall func3(__int64 a1, const char *a2)
{
const char **v2; // rbx
const char **v3; // rbp
const char *v4; // rax
char *v5; // rdi

v2 = *(const char ***)(a1 + 8);
if ( v2 )
{
v3 = 0LL;
do
{
if ( !strcmp(*v2, a2) )
v3 = v2;
v2 = (const char **)v2[1];
}
while ( v2 );
if ( v3 )
{
v4 = v3[1];
if ( v4 )
*((_QWORD *)v4 + 2) = v3[2];
v5 = (char *)*v3;
*(_QWORD *)v3[2] = v4;
free(v5);
free(v3);
}
}
}

original_code:
void channel_remove_user(struct channel_t * channel, char * user)
{
    struct user_t * iterator, * temp;
    temp = ((void *)0);
    for ((iterator) = ((&channel->user_list_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        if (strcmp(iterator->name, user) == 0) {
            temp = iterator;
        }
    }
    if (temp) {
        do { if ((temp)->list.le_next != ((void *)0)) (temp)->list.le_next->list.le_prev = (temp)->list.le_prev; *(temp)->list.le_prev = (temp)->list.le_next; } while ( 0);
        free(temp->name);
        free(temp);
    }
}

canonical_original_code:
void channel_remove_user(struct channel_t *channel, char *user)
{
    struct user_t *iterator; struct user_t *temp;
    temp = ((void *)0);
    for ((iterator) = ((&channel->user_list_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        if (strcmp(iterator->name, user) == 0) {
            temp = iterator;
        }
    }
    if (temp) {
        do { if ((temp)->list.le_next != ((void *)0)) (temp)->list.le_next->list.le_prev = (temp)->list.le_prev; *(temp)->list.le_prev = (temp)->list.le_next; } while ( 0);
        free(temp->name);
        free(temp);
    }
}

variable_types:
user
char *

variable_types: struct user_t { char *name; struct { struct user_t *le_next; struct user_t **le_prev; } list; } *


decompiled_code:
void __fastcall channel_free(void *ptr)
{
__int64 v1; // rax
__int64 v2; // rbx
const char *v3; // rsi

if ( ptr )
{
v1 = *((_QWORD *)ptr + 1);
if ( v1 )
{
while ( 1 )
{
v2 = *(_QWORD *)(v1 + 8);
v3 = *(const char **)v1;
if ( !v2 )
break;
channel_remove_user((__int64)ptr, v3);
v1 = v2;
}
channel_remove_user((__int64)ptr, v3);
}
free(*(void **)ptr);
free(ptr);
}
}

canonical_decompiled_code:
void __fastcall func4(void *ptr)
{
__int64 v1; // rax
__int64 v2; // rbx
const char *v3; // rsi

if ( ptr )
{
v1 = *((_QWORD *)ptr + 1);
if ( v1 )
{
while ( 1 )
{
v2 = *(_QWORD *)(v1 + 8);
v3 = *(const char **)v1;
if ( !v2 )
break;
func3((__int64)ptr, v3);
v1 = v2;
}
func3((__int64)ptr, v3);
}
free(*(void **)ptr);
free(ptr);
}
}

original_code:
void channel_free(struct channel_t * channel)
{
    struct user_t * iterator, * temp;
    if (!channel) {
        return;
    }
    temp = ((void *)0);
    for ((iterator) = ((&channel->user_list_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        if (temp) {
            channel_remove_user(channel, temp->name);
        }
        temp = iterator;
    }
    if (temp) {
        channel_remove_user(channel, temp->name);
    }
    free(channel->name);
    free(channel);
}

canonical_original_code:
void channel_free(struct channel_t *channel)
{
    struct user_t *iterator; struct user_t *temp;
    if (!channel) {
        return;
    }
    temp = ((void *)0);
    for ((iterator) = ((&channel->user_list_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        if (temp) {
            channel_remove_user(channel, temp->name);
        }
        temp = iterator;
    }
    if (temp) {
        channel_remove_user(channel, temp->name);
    }
    free(channel->name);
    free(channel);
}


run

decompiled_code:
int run()
{
int result; // eax
char v1[512]; // [rsp+0h] [rbp-618h] BYREF
char s[512]; // [rsp+200h] [rbp-418h] BYREF
char v3[536]; // [rsp+400h] [rbp-218h] BYREF

v3[0] = 0;
s[0] = 0;
v1[0] = 0;
extract_url_constprop_0((const char *)(*(_QWORD *)(plugin + 32LL) + 1110LL), s);
if ( s[0] )
{
result = gris_search_constprop_0(s, v3);
if ( v3[0] )
{
sprintf(v1, "PRIVMSG %s :Guessing image: %s", (const char *)(*(_QWORD *)(plugin + 32LL) + 1620LL), v3);
result = (*(__int64 (__fastcall **)(_QWORD, char *))(plugin + 24LL))(*(_QWORD *)(plugin + 32LL), v1);
}
}
else
{
sprintf(v1, "PRIVMSG %s :URL can't be read.", (const char *)(*(_QWORD *)(plugin + 32LL) + 1620LL));
result = (*(__int64 (__fastcall **)(_QWORD, char *))(plugin + 24LL))(*(_QWORD *)(plugin + 32LL), v1);
}
return result;
}

canonical_decompiled_code:
int func8()
{
int result; // eax
char v1[512]; // [rsp+0h] [rbp-618h] BYREF
char s[512]; // [rsp+200h] [rbp-418h] BYREF
char v3[536]; // [rsp+400h] [rbp-218h] BYREF

v3[0] = 0;
s[0] = 0;
v1[0] = 0;
func6((const char *)(*(_QWORD *)(plugin + 32LL) + 1110LL), s);
if ( s[0] )
{
result = func7(s, v3);
if ( v3[0] )
{
sprintf(v1, "PRIVMSG %s :Guessing image: %s", (const char *)(*(_QWORD *)(plugin + 32LL) + 1620LL), v3);
result = (*(__int64 (__fastcall **)(_QWORD, char *))(plugin + 24LL))(*(_QWORD *)(plugin + 32LL), v1);
}
}
else
{
sprintf(v1, "PRIVMSG %s :URL can't be read.", (const char *)(*(_QWORD *)(plugin + 32LL) + 1620LL));
result = (*(__int64 (__fastcall **)(_QWORD, char *))(plugin + 24LL))(*(_QWORD *)(plugin + 32LL), v1);
}
return result;
}

original_code:
void run(int type)
{
    escape_quotes(plugin->irc->message.trailing);
    if (type == PLUGIN_TYPE_COMMAND) {
        handle_command();
    } else if (type == PLUGIN_TYPE_GREP) {
        handle_grep();
    }
}

variable_types: type int


init

decompiled_code:
__int64 init()
{
char *v0; // rax
unsigned int v1; // eax

v0 = (char *)malloc(0x40uLL);
*(_OWORD *)(v0 + 8) = 0LL;
*(_OWORD *)(v0 + 40) = 0LL;
*(_QWORD *)v0 = "gris";
*((_QWORD *)v0 + 5) = run;
*((_QWORD *)v0 + 7) = 0LL;
*((_DWORD *)v0 + 4) = 8;
*(_OWORD *)(v0 + 24) = 0LL;
plugin = v0;
v1 = system("java -jar plugins/gris.jar &");
fprintf(stderr, "gris.jar status: %d\n", v1);
return plugin;
}

canonical_decompiled_code:
__int64 func9()
{
char *v0; // rax
unsigned int v1; // eax

v0 = (char *)malloc(0x40uLL);
*(_OWORD *)(v0 + 8) = 0LL;
*(_OWORD *)(v0 + 40) = 0LL;
*(_QWORD *)v0 = "gris";
*((_QWORD *)v0 + 5) = run;
*((_QWORD *)v0 + 7) = 0LL;
*((_DWORD *)v0 + 4) = 8;
*(_OWORD *)(v0 + 24) = 0LL;
plugin = v0;
v1 = system("java -jar plugins/gris.jar &");
fprintf(stderr, "gris.jar status: %d\n", v1);
return plugin;
}

original_code:
struct plugin_t * init(void)
{
    plugin = malloc(sizeof (struct plugin_t));
    memset(plugin, 0, sizeof *plugin);
    plugin->run = run;
    plugin->name = "seen";
    plugin->type = PLUGIN_TYPE_COMMAND | PLUGIN_TYPE_GREP;
    plugin->keywords = keywords;
    create_tables();
    return plugin;
}

canonical_original_code:
struct plugin_t *init()
{
    plugin = malloc(sizeof (struct plugin_t));
    memset(plugin, 0, sizeof *plugin);
    plugin->run = run;
    plugin->name = "seen";
    plugin->type = PLUGIN_TYPE_COMMAND | PLUGIN_TYPE_GREP;
    plugin->keywords = keywords;
    create_tables();
    return plugin;
}

return_type: struct plugin_t { char *name; char **keywords; enum plugin_type { PLUGIN_TYPE_DAEMON=1, PLUGIN_TYPE_COMMAND=expr, PLUGIN_TYPE_GREP=expr } type; void (*send_message)(struct irc_t { struct message_t { struct prefix_t { char servername[100]; struct nickname_t { char nickname[100]; char user[100]; char host[100]; } nickname; } prefix; char command[10]; char params[14][50]; char trailing[510]; } message; char from[100]; struct channel_list_t { struct channel_t { char *name; struct { struct user_t { char *name; struct { struct user_t *le_next; struct user_t **le_prev; } list; } *lh_first; } user_list_head; struct { struct channel_t *le_next; struct channel_t **le_prev; } list; } *lh_first; } channel_list_head; void *sockfd; char *hostname; char *port; char *nickname; char *password; char *admin; struct ajoin_channel_list_t { struct ajoin_channel_t { char *channel_name; struct { struct ajoin_channel_t *le_next; struct ajoin_channel_t **le_prev; } list; } *lh_first; } ajoin_channels_head; } *, char *message); struct irc_t *irc; void (*run)(int type); struct { struct plugin_t *le_next; struct plugin_t **le_prev; } list; } *

user_defined_types: struct plugin_t { char *name; char **keywords; enum plugin_type type; void (*send_message)(struct irc_t *, char *message); struct irc_t *irc; void (*run)(int type); struct { struct plugin_t *le_next; struct plugin_t **le_prev; } list; }


decompiled_code:
__int64 __fastcall getchar_fd(void *buf)
{
int v1; // eax
int v2; // eax
unsigned __int8 *v3; // rax

v1 = *((_DWORD *)buf + 258);
if ( !v1 )
{
v1 = recv(*((_DWORD *)buf + 259), buf, 0x400uLL, 0);
*((_QWORD *)buf + 128) = buf;
}
v2 = v1 - 1;
*((_DWORD *)buf + 258) = v2;
if ( v2 < 0 )
return 0xFFFFFFFFLL;
v3 = (unsigned __int8 *)*((_QWORD *)buf + 128);
*((_QWORD *)buf + 128) = v3 + 1;
return *v3;
}

canonical_decompiled_code:
__int64 __fastcall func11(void *buf)
{
int v1; // eax
int v2; // eax
unsigned __int8 *v3; // rax

v1 = *((_DWORD *)buf + 258);
if ( !v1 )
{
v1 = recv(*((_DWORD *)buf + 259), buf, 0x400uLL, 0);
*((_QWORD *)buf + 128) = buf;
}
v2 = v1 - 1;
*((_DWORD *)buf + 258) = v2;
if ( v2 < 0 )
return 0xFFFFFFFFLL;
v3 = (unsigned __int8 *)*((_QWORD *)buf + 128);
*((_QWORD *)buf + 128) = v3 + 1;
return *v3;
}

original_code:
static int getchar_fd(socket_t sock)
{
    struct socket_t * socket = sock;
    if (socket->n == 0) {
        socket->n = recv(socket->sockfd, socket->buf, 1024, 0);
        socket->bufp = socket->buf;
    }
    return (--socket->n >= 0) ? (unsigned char) *socket->bufp++ : (-1);
}

canonical_original_code:
static int getchar_fd(void *sock)
{
    struct socket_t *socket = sock;
    if (socket->n == 0) {
        socket->n = recv(socket->sockfd, socket->buf, 1024, 0);
        socket->bufp = socket->buf;
    }
    return (--socket->n >= 0) ? (unsigned char) *socket->bufp++ : (-1);
}

variable_types:
sock
void *

variable_types: struct socket_t { char buf[1024]; char *bufp; int n; int sockfd; } *


decompiled_code:
int __fastcall socket_open(const char *file, int oflag)
{
return open(file, oflag);
}

canonical_decompiled_code:
int __fastcall func12(const char *file, int oflag)
{
return open(file, oflag);
}

original_code:
int socket_open (const char * path, int oflag)
{
    return open(path, oflag);
}

canonical_original_code:
int socket_open(char *path, int oflag)
{
    return open(path, oflag);
}

variable_types:
path
char *

variable_types: oflag int


decompiled_code:
ssize_t __fastcall socket_read(int a1, void *a2, unsigned int a3)
{
return read(a1, a2, a3);
}

canonical_decompiled_code:
ssize_t __fastcall func13(int a1, void *a2, unsigned int a3)
{
return read(a1, a2, a3);
}

original_code:
int socket_read (int handle, void * buffer, unsigned int nbyte)
{
    return read(handle, buffer, nbyte);
}

canonical_original_code:
int socket_read(int handle, void *buffer, unsigned int nbyte)
{
    return read(handle, buffer, nbyte);
}

variable_types: handle int

variable_types:
buffer
void *

variable_types:
nbyte
unsigned int


decompiled_code:
__int64 __fastcall socket_write(__int64 a1, const void *a2, int a3)
{
__int64 result; // rax
unsigned int v4; // ebx
int *v5; // rax
char *v6; // rax

LODWORD(result) = send(*(_DWORD *)(a1 + 1036), a2, a3, 0);
v4 = result;
if ( (int)result >= 0 )
return (unsigned int)result;
v5 = __errno_location();
v6 = strerror(*v5);
fprintf(stderr, "Send error: %s\n", v6);
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func14(__int64 a1, const void *a2, int a3)
{
__int64 result; // rax
unsigned int v4; // ebx
int *v5; // rax
char *v6; // rax

LODWORD(result) = send(*(_DWORD *)(a1 + 1036), a2, a3, 0);
v4 = result;
if ( (int)result >= 0 )
return (unsigned int)result;
v5 = __errno_location();
v6 = strerror(*v5);
fprintf(stderr, "Send error: %s\n", v6);
return v4;
}

original_code:
int socket_write(socket_t sock, char * buf, int buf_len)
{
    int n = send(((struct socket_t *) sock)->sockfd, buf, buf_len, 0);
    if (n < 0) {
        fprintf(stderr, "Send error: %s\n", strerror((*__errno_location ())));
    }
    return n;
}

canonical_original_code:
int socket_write(void *sock, char *buf, int buf_len)
{
    int n = send(((struct socket_t *) sock)->sockfd, buf, buf_len, 0);
    if (n < 0) {
        fprintf(stderr, "Send error: %s\n", strerror((*__errno_location ())));
    }
    return n;
}

variable_types:
buf
char *

variable_types: n int


decompiled_code:
__int64 __fastcall socket_readline(void *buf, _BYTE *a2, int a3)
{
_BYTE *i; // r14
int v5; // eax

for ( i = a2; ; ++i )
{
v5 = getchar_fd(buf);
if ( v5 == -1 || v5 == 10 || a3 <= (int)i + 1 - (int)a2 )
break;
*i = v5;
}
*i = 0;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func15(void *buf, _BYTE *a2, int a3)
{
_BYTE *i; // r14
int v5; // eax

for ( i = a2; ; ++i )
{
v5 = func11(buf);
if ( v5 == -1 || v5 == 10 || a3 <= (int)i + 1 - (int)a2 )
break;
*i = v5;
}
*i = 0;
return 0LL;
}

original_code:
int socket_readline(socket_t sock, char * buf, int buf_len)
{
    int ret, i = 0;
    while( (ret = getchar_fd(sock)) != '\n' && ret != (-1) && ++i < buf_len)
        *buf++ = ret;
    *buf = '\0';
    return 0;
}

canonical_original_code:
int socket_readline(void *sock, char *buf, int buf_len)
{
    int ret; int i = 0;
    while( (ret = getchar_fd(sock)) != '\n' && ret != (-1) && ++i < buf_len)
        *buf++ = ret;
    *buf = '\0';
    return 0;
}

variable_types: ret int

variable_types: i int


decompiled_code:
__int64 __fastcall socket_close(void *ptr)
{
close(*((_DWORD *)ptr + 259));
free(ptr);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func16(void *ptr)
{
close(*((_DWORD *)ptr + 259));
free(ptr);
return 0LL;
}

original_code:
int socket_close(socket_t sock)
{
    close(((struct socket_t *) sock)->sockfd);
    free(sock);
    return 0;
}

canonical_original_code:
int socket_close(void *sock)
{
    close(((struct socket_t *) sock)->sockfd);
    free(sock);
    return 0;
}

user_defined_types: struct socket_t { char buf[1024]; char *bufp; int n; int sockfd; }


decompiled_code:
__int64 __fastcall start_thread(__int64 a1)
{
(*(void (__fastcall **)(_QWORD))(a1 + 40))(0LL);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1)
{
(*(void (__fastcall **)(_QWORD))(a1 + 40))(0LL);
return 0LL;
}

original_code:
static void *start_thread(void * pdata)
{
    ((struct plugin_t *)pdata)->run(0);
    return ((void *)0);
}

canonical_original_code:
static void *start_thread(void *pdata)
{
    ((struct plugin_t *)pdata)->run(0);
    return ((void *)0);
}

variable_types:
pdata
void *

return_type: void *

user_defined_types: enum plugin_type { PLUGIN_TYPE_DAEMON=1, PLUGIN_TYPE_COMMAND=expr, PLUGIN_TYPE_GREP=expr }


decompiled_code:
__int64 __fastcall send_message(__int64 a1, const char *a2)
{
size_t v2; // rax
char v4[4104]; // [rsp+0h] [rbp-1008h] BYREF

snprintf(v4, 0x1000uLL, "%s\r\n", a2);
v2 = strlen(v4);
return socket_write(*(_QWORD *)(a1 + 1728), v4, v2);
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, const char *a2)
{
size_t v2; // rax
char v4[4104]; // [rsp+0h] [rbp-1008h] BYREF

snprintf(v4, 0x1000uLL, "%s\r\n", a2);
v2 = strlen(v4);
return socket_write(*(_QWORD *)(a1 + 1728), v4, v2);
}

original_code:
void send_message(struct irc_t * irc, char * response)
{
    char buffer[4096];
    snprintf(buffer, sizeof buffer, "%s\r\n", response);
    socket_write(irc->sockfd, buffer, strlen(buffer));
}

canonical_original_code:
void send_message(struct irc_t *irc, char *response)
{
    char buffer[4096];
    snprintf(buffer, sizeof buffer, "%s\r\n", response);
    socket_write(irc->sockfd, buffer, strlen(buffer));
}

variable_types: struct irc_t { struct message_t { struct prefix_t { char servername[100]; struct nickname_t { char nickname[100]; char user[100]; char host[100]; } nickname; } prefix; char command[10]; char params[14][50]; char trailing[510]; } message; char from[100]; struct channel_list_t { struct channel_t { char *name; struct { struct user_t { char *name; struct { struct user_t *le_next; struct user_t **le_prev; } list; } *lh_first; } user_list_head; struct { struct channel_t *le_next; struct channel_t **le_prev; } list; } *lh_first; } channel_list_head; void *sockfd; char *hostname; char *port; char *nickname; char *password; char *admin; struct ajoin_channel_list_t { struct ajoin_channel_t { char *channel_name; struct { struct ajoin_channel_t *le_next; struct ajoin_channel_t **le_prev; } list; } *lh_first; } ajoin_channels_head; } *

variable_types:
response
char *

variable_types:
buffer
char [4096]


decompiled_code:
int __fastcall plugin_load_file(const char *a1, __int64 a2)
{
__int64 v3; // rax
const char *v4; // rdx
const char *v5; // rsi
__int64 v6; // rbp
__int64 (*v7)(void); // rbx
__int64 v8; // rax
__int64 v9; // rdx
_QWORD *v10; // rbx
_QWORD *v11; // rax
_QWORD *v12; // rax
_QWORD *v13; // rdx
__int64 v14; // rax

fprintf(stderr, "Loading native plugin \"%s\"\n", a1);
v3 = dl_open(a1);
v4 = a1;
v5 = "The plugin file \"%s\" could not be opened.\n";
if ( !v3 )
goto LABEL_14;
v6 = v3;
v7 = (__int64 (*)(void))dl_sym(v3, "init", a1);
if ( !v7 )
fprintf(stderr, "The plugin \"%s\" has no exported init function symbol.\n", a1);
v8 = v7();
v10 = (_QWORD *)v8;
if ( !v8 )
{
LODWORD(v12) = fwrite(
"The plugin initialization is failed for reasons unknown. Hope it's last words were meaningful, if any.\n",
1uLL,
0x67uLL,
stderr);
return (int)v12;
}
*(_QWORD *)(v8 + 24) = send_message;
*(_QWORD *)(v8 + 32) = a2;
if ( (*(_BYTE *)(v8 + 16) & 8) == 0 )
goto LABEL_6;
v14 = dl_sym(v6, "keywords", v9);
if ( !v14 )
{
v4 = a1;
v5 = "The plugin \"%s\" is of type `grep', but has no exported grep keywords symbols found. Discarding.\n";
LABEL_14:
LODWORD(v12) = fprintf(stderr, v5, v4);
return (int)v12;
}
v10[1] = v14;
LABEL_6:
v11 = plugin_slist_head;
v10[6] = plugin_slist_head;
if ( v11 )
v11[7] = v10 + 6;
v10[7] = &plugin_slist_head;
plugin_slist_head = v10;
v12 = malloc(0x18uLL);
v13 = dl_library_holder_head;
*v12 = v6;
v12[1] = v13;
if ( v13 )
v13[2] = v12 + 1;
v12[2] = &dl_library_holder_head;
dl_library_holder_head = v12;
return (int)v12;
}

canonical_decompiled_code:
int __fastcall func2(const char *a1, __int64 a2)
{
__int64 v3; // rax
const char *v4; // rdx
const char *v5; // rsi
__int64 v6; // rbp
__int64 (*v7)(void); // rbx
__int64 v8; // rax
__int64 v9; // rdx
_QWORD *v10; // rbx
_QWORD *v11; // rax
_QWORD *v12; // rax
_QWORD *v13; // rdx
__int64 v14; // rax

fprintf(stderr, "Loading native plugin \"%s\"\n", a1);
v3 = dl_open(a1);
v4 = a1;
v5 = "The plugin file \"%s\" could not be opened.\n";
if ( !v3 )
goto LABEL_14;
v6 = v3;
v7 = (__int64 (*)(void))dl_sym(v3, "init", a1);
if ( !v7 )
fprintf(stderr, "The plugin \"%s\" has no exported init function symbol.\n", a1);
v8 = v7();
v10 = (_QWORD *)v8;
if ( !v8 )
{
LODWORD(v12) = fwrite(
"The plugin initialization is failed for reasons unknown. Hope it's last words were meaningful, if any.\n",
1uLL,
0x67uLL,
stderr);
return (int)v12;
}
*(_QWORD *)(v8 + 24) = send_message;
*(_QWORD *)(v8 + 32) = a2;
if ( (*(_BYTE *)(v8 + 16) & 8) == 0 )
goto LABEL_6;
v14 = dl_sym(v6, "keywords", v9);
if ( !v14 )
{
v4 = a1;
v5 = "The plugin \"%s\" is of type `grep', but has no exported grep keywords symbols found. Discarding.\n";
LABEL_14:
LODWORD(v12) = fprintf(stderr, v5, v4);
return (int)v12;
}
v10[1] = v14;
LABEL_6:
v11 = plugin_slist_head;
v10[6] = plugin_slist_head;
if ( v11 )
v11[7] = v10 + 6;
v10[7] = &plugin_slist_head;
plugin_slist_head = v10;
v12 = malloc(0x18uLL);
v13 = dl_library_holder_head;
*v12 = v6;
v12[1] = v13;
if ( v13 )
v13[2] = v12 + 1;
v12[2] = &dl_library_holder_head;
dl_library_holder_head = v12;
return (int)v12;
}

original_code:
static void plugin_load_file(char * file, struct irc_t * irc)
{
    struct dl_library_holder_t * library_holder;
    dl_library_t plugin_file;
    struct plugin_t * (*init)(void);
    struct plugin_t * plugin;
    fprintf(stderr, "Loading native plugin \"%s\"\n", file);;
    if ((plugin_file = dl_open(file)) == ((void *)0)) {
        fprintf(stderr, "The plugin file \"%s\" could not be opened.\n", file);;
        return;
    }
    if ((init = dl_sym(plugin_file, "init")) == ((void *)0)) {
        fprintf(stderr, "The plugin \"%s\" has no exported init function symbol.\n", file);;
    }
    if ((plugin = init()) == ((void *)0)) {
        fprintf(stderr, "The plugin initialization is failed for reasons unknown." " Hope it's last words were meaningful, if any.\n");;
        return;
    }
    plugin->send_message = send_message;
    plugin->irc = irc;
    if (plugin->type & PLUGIN_TYPE_GREP) {
        char ** keywords;
        if ((keywords = dl_sym(plugin_file, "keywords"))) {
            plugin->keywords = keywords;
        } else {
            fprintf(stderr, "The plugin \"%s\" is of type `grep', but has no " "exported grep keywords symbols found. Discarding.\n", file);;
            return;
        }
    }
    do { if (((plugin)->list.le_next = (&plugin_slist_head)->lh_first) != ((void *)0)) (&plugin_slist_head)->lh_first->list.le_prev = &(plugin)->list.le_next; (&plugin_slist_head)->lh_first = (plugin); (plugin)->list.le_prev = &(&plugin_slist_head)->lh_first; } while ( 0);
    library_holder = malloc (sizeof (*library_holder));
    library_holder->plugin = plugin_file;
    do { if (((library_holder)->list.le_next = (&dl_library_holder_head)->lh_first) != ((void *)0)) (&dl_library_holder_head)->lh_first->list.le_prev = &(library_holder)->list.le_next; (&dl_library_holder_head)->lh_first = (library_holder); (library_holder)->list.le_prev = &(&dl_library_holder_head)->lh_first; } while ( 0);
}

canonical_original_code:
static void plugin_load_file(char *file, struct irc_t *irc)
{
    struct dl_library_holder_t *library_holder;
    void *plugin_file;
    struct plugin_t *(*init)();
    struct plugin_t *plugin;
    fprintf(stderr, "Loading native plugin \"%s\"\n", file);;
    if ((plugin_file = dl_open(file)) == ((void *)0)) {
        fprintf(stderr, "The plugin file \"%s\" could not be opened.\n", file);;
        return;
    }
    if ((init = dl_sym(plugin_file, "init")) == ((void *)0)) {
        fprintf(stderr, "The plugin \"%s\" has no exported init function symbol.\n", file);;
    }
    if ((plugin = init()) == ((void *)0)) {
        fprintf(stderr, "The plugin initialization is failed for reasons unknown." " Hope it's last words were meaningful, if any.\n");;
        return;
    }
    plugin->send_message = send_message;
    plugin->irc = irc;
    if (plugin->type & PLUGIN_TYPE_GREP) {
        char **keywords;
        if ((keywords = dl_sym(plugin_file, "keywords"))) {
            plugin->keywords = keywords;
        } else {
            fprintf(stderr, "The plugin \"%s\" is of type `grep', but has no " "exported grep keywords symbols found. Discarding.\n", file);;
            return;
        }
    }
    do { if (((plugin)->list.le_next = (&plugin_slist_head)->lh_first) != ((void *)0)) (&plugin_slist_head)->lh_first->list.le_prev = &(plugin)->list.le_next; (&plugin_slist_head)->lh_first = (plugin); (plugin)->list.le_prev = &(&plugin_slist_head)->lh_first; } while ( 0);
    library_holder = malloc (sizeof (*library_holder));
    library_holder->plugin = plugin_file;
    do { if (((library_holder)->list.le_next = (&dl_library_holder_head)->lh_first) != ((void *)0)) (&dl_library_holder_head)->lh_first->list.le_prev = &(library_holder)->list.le_next; (&dl_library_holder_head)->lh_first = (library_holder); (library_holder)->list.le_prev = &(&dl_library_holder_head)->lh_first; } while ( 0);
}

variable_types:
file
char *

variable_types: struct dl_library_holder_t { void *plugin; struct { struct dl_library_holder_t *le_next; struct dl_library_holder_t **le_prev; } list; } *

variable_types: struct plugin_t { char *name; char **keywords; enum plugin_type { PLUGIN_TYPE_DAEMON=1, PLUGIN_TYPE_COMMAND=expr, PLUGIN_TYPE_GREP=expr } type; void (*send_message)(struct irc_t { struct message_t { struct prefix_t { char servername[100]; struct nickname_t { char nickname[100]; char user[100]; char host[100]; } nickname; } prefix; char command[10]; char params[14][50]; char trailing[510]; } message; char from[100]; struct channel_list_t { struct channel_t { char *name; struct { struct user_t { char *name; struct { struct user_t *le_next; struct user_t **le_prev; } list; } *lh_first; } user_list_head; struct { struct channel_t *le_next; struct channel_t **le_prev; } list; } *lh_first; } channel_list_head; void *sockfd; char *hostname; char *port; char *nickname; char *password; char *admin; struct ajoin_channel_list_t { struct ajoin_channel_t { char *channel_name; struct { struct ajoin_channel_t *le_next; struct ajoin_channel_t **le_prev; } list; } *lh_first; } ajoin_channels_head; } *, char *message); struct irc_t *irc; void (*run)(int type); struct { struct plugin_t *le_next; struct plugin_t **le_prev; } list; } *(*)()

variable_types:
keywords
char **


decompiled_code:
void plugin_free()
{
const char **v0; // rbp
const char **v1; // rdi
_QWORD *v2; // rbp
void *v3; // rdi
_QWORD *v4; // rbp
_QWORD *v5; // rbx

fwrite("Freeing plugin resources.\n", 1uLL, 0x1AuLL, stderr);
v0 = (const char **)plugin_slist_head;
if ( plugin_slist_head )
{
v1 = 0LL;
while ( 1 )
{
free(v1);
fprintf(stderr, "Freeing plugin: %s\n", *v0);
v1 = v0;
if ( !v0[6] )
break;
v0 = (const char **)v0[6];
}
}
free(v0);
fwrite("Killing threads.\n", 1uLL, 0x11uLL, stderr);
v2 = plugin_threads_head;
if ( plugin_threads_head )
{
v3 = 0LL;
while ( 1 )
{
free(v3);
thread_kill(*v2);
v3 = v2;
if ( !v2[1] )
break;
v2 = (_QWORD *)v2[1];
}
}
free(v2);
v4 = dl_library_holder_head;
if ( dl_library_holder_head )
{
while ( 1 )
{
dl_close(*v4);
v5 = (_QWORD *)v4[1];
if ( !v5 )
break;
free(v4);
v4 = v5;
}
free(v4);
}
}

canonical_decompiled_code:
void func3()
{
const char **v0; // rbp
const char **v1; // rdi
_QWORD *v2; // rbp
void *v3; // rdi
_QWORD *v4; // rbp
_QWORD *v5; // rbx

fwrite("Freeing plugin resources.\n", 1uLL, 0x1AuLL, stderr);
v0 = (const char **)plugin_slist_head;
if ( plugin_slist_head )
{
v1 = 0LL;
while ( 1 )
{
free(v1);
fprintf(stderr, "Freeing plugin: %s\n", *v0);
v1 = v0;
if ( !v0[6] )
break;
v0 = (const char **)v0[6];
}
}
free(v0);
fwrite("Killing threads.\n", 1uLL, 0x11uLL, stderr);
v2 = plugin_threads_head;
if ( plugin_threads_head )
{
v3 = 0LL;
while ( 1 )
{
free(v3);
thread_kill(*v2);
v3 = v2;
if ( !v2[1] )
break;
v2 = (_QWORD *)v2[1];
}
}
free(v2);
v4 = dl_library_holder_head;
if ( dl_library_holder_head )
{
while ( 1 )
{
dl_close(*v4);
v5 = (_QWORD *)v4[1];
if ( !v5 )
break;
free(v4);
v4 = v5;
}
free(v4);
}
}

original_code:
void plugin_free()
{
    struct plugin_t * iterator, * temp;
    struct dl_library_holder_t * library_it, * temp_it;
    fprintf(stderr, "Freeing plugin resources.\n");;
    temp = ((void *)0);
    for ((iterator) = ((&plugin_slist_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        free(temp);
        temp = ((void *)0);
        fprintf(stderr, "Freeing plugin: %s\n", iterator->name);;
        temp = iterator;
    }
    free(temp);
    struct plugin_threads_t * iterator_threads, * t_temp;
    fprintf(stderr, "Killing threads.\n");;
    t_temp = ((void *)0);
    for ((iterator_threads) = ((&plugin_threads_head)->lh_first); (iterator_threads); (iterator_threads) = ((iterator_threads)->list.le_next)) {
        free(t_temp);
        thread_kill(iterator_threads->thread);
        t_temp = iterator_threads;
    }
    free(t_temp);
    temp_it = ((void *)0);
    for ((library_it) = ((&dl_library_holder_head)->lh_first); (library_it); (library_it) = ((library_it)->list.le_next)) {
        if (temp_it) free(temp_it);
        dl_close(library_it->plugin);
        temp_it = library_it;
    }
    if (temp_it) free(temp_it);
}

canonical_original_code:
void plugin_free()
{
    struct plugin_t *iterator; struct plugin_t *temp;
    struct dl_library_holder_t *library_it; struct dl_library_holder_t *temp_it;
    fprintf(stderr, "Freeing plugin resources.\n");;
    temp = ((void *)0);
    for ((iterator) = ((&plugin_slist_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        free(temp);
        temp = ((void *)0);
        fprintf(stderr, "Freeing plugin: %s\n", iterator->name);;
        temp = iterator;
    }
    free(temp);
    struct plugin_threads_t *iterator_threads; struct plugin_threads_t *t_temp;
    fprintf(stderr, "Killing threads.\n");;
    t_temp = ((void *)0);
    for ((iterator_threads) = ((&plugin_threads_head)->lh_first); (iterator_threads); (iterator_threads) = ((iterator_threads)->list.le_next)) {
        free(t_temp);
        thread_kill(iterator_threads->thread);
        t_temp = iterator_threads;
    }
    free(t_temp);
    temp_it = ((void *)0);
    for ((library_it) = ((&dl_library_holder_head)->lh_first); (library_it); (library_it) = ((library_it)->list.le_next)) {
        if (temp_it) free(temp_it);
        dl_close(library_it->plugin);
        temp_it = library_it;
    }
    if (temp_it) free(temp_it);
}

variable_types: struct plugin_t { char *name; char **keywords; enum plugin_type { PLUGIN_TYPE_DAEMON=1, PLUGIN_TYPE_COMMAND=expr, PLUGIN_TYPE_GREP=expr } type; void (*send_message)(struct irc_t { struct message_t { struct prefix_t { char servername[100]; struct nickname_t { char nickname[100]; char user[100]; char host[100]; } nickname; } prefix; char command[10]; char params[14][50]; char trailing[510]; } message; char from[100]; struct channel_list_t { struct channel_t { char *name; struct { struct user_t { char *name; struct { struct user_t *le_next; struct user_t **le_prev; } list; } *lh_first; } user_list_head; struct { struct channel_t *le_next; struct channel_t **le_prev; } list; } *lh_first; } channel_list_head; void *sockfd; char *hostname; char *port; char *nickname; char *password; char *admin; struct ajoin_channel_list_t { struct ajoin_channel_t { char *channel_name; struct { struct ajoin_channel_t *le_next; struct ajoin_channel_t **le_prev; } list; } *lh_first; } ajoin_channels_head; } *, char *message); struct irc_t *irc; void (*run)(int type); struct { struct plugin_t *le_next; struct plugin_t **le_prev; } list; } *

variable_types: struct plugin_threads_t { void *thread; struct { struct plugin_threads_t *le_next; struct plugin_threads_t **le_prev; } list; } *

user_defined_types: struct dl_library_holder_t { void *plugin; struct { struct dl_library_holder_t *le_next; struct dl_library_holder_t **le_prev; } list; }


decompiled_code:
void plugin_start_daemons()
{
const char **v0; // rbx
_QWORD *v1; // rax
_QWORD *v2; // rbp
unsigned int v3; // eax

v0 = (const char **)plugin_slist_head;
plugin_threads_head = 0LL;
if ( plugin_slist_head )
{
do
{
if ( ((_BYTE)v0[2] & 1) != 0 )
{
v2 = calloc(0x18uLL, 1uLL);
fprintf(stderr, "Looper plugin [%s] is started\n", *v0);
v3 = thread_create(v2, start_thread, v0);
if ( v3 )
fprintf(stderr, "Thread could not be started. pthread_create, errno = %d\n", v3);
v1 = plugin_threads_head;
v2[1] = plugin_threads_head;
if ( v1 )
v1[2] = v2 + 1;
plugin_threads_head = v2;
v2[2] = &plugin_threads_head;
}
v0 = (const char **)v0[6];
}
while ( v0 );
}
}

canonical_decompiled_code:
void func4()
{
const char **v0; // rbx
_QWORD *v1; // rax
_QWORD *v2; // rbp
unsigned int v3; // eax

v0 = (const char **)plugin_slist_head;
plugin_threads_head = 0LL;
if ( plugin_slist_head )
{
do
{
if ( ((_BYTE)v0[2] & 1) != 0 )
{
v2 = calloc(0x18uLL, 1uLL);
fprintf(stderr, "Looper plugin [%s] is started\n", *v0);
v3 = thread_create(v2, start_thread, v0);
if ( v3 )
fprintf(stderr, "Thread could not be started. pthread_create, errno = %d\n", v3);
v1 = plugin_threads_head;
v2[1] = plugin_threads_head;
if ( v1 )
v1[2] = v2 + 1;
plugin_threads_head = v2;
v2[2] = &plugin_threads_head;
}
v0 = (const char **)v0[6];
}
while ( v0 );
}
}

original_code:
void plugin_start_daemons(struct irc_t * irc)
{
    int err;
    struct plugin_t * iterator;
    do { (&plugin_threads_head)->lh_first = ((void *)0); } while ( 0);
    for ((iterator) = ((&plugin_slist_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        struct plugin_t * plugin = iterator;
        struct plugin_threads_t * plugin_thread;
        if (!(plugin->type & PLUGIN_TYPE_DAEMON))
            continue;
        plugin_thread = malloc(sizeof(struct plugin_threads_t));
        memset(plugin_thread, 0, sizeof(struct plugin_threads_t));
        fprintf(stderr, "Looper plugin [%s] is started\n", plugin->name);;
        if ((err = thread_create(&plugin_thread->thread, start_thread, plugin)) != 0) {
            fprintf(stderr, "Thread could not be started. pthread_create, errno = %d\n", err);;
        }
        do { if (((plugin_thread)->list.le_next = (&plugin_threads_head)->lh_first) != ((void *)0)) (&plugin_threads_head)->lh_first->list.le_prev = &(plugin_thread)->list.le_next; (&plugin_threads_head)->lh_first = (plugin_thread); (plugin_thread)->list.le_prev = &(&plugin_threads_head)->lh_first; } while ( 0);
    }
}

canonical_original_code:
void plugin_start_daemons(struct irc_t *irc)
{
    int err;
    struct plugin_t *iterator;
    do { (&plugin_threads_head)->lh_first = ((void *)0); } while ( 0);
    for ((iterator) = ((&plugin_slist_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        struct plugin_t *plugin = iterator;
        struct plugin_threads_t *plugin_thread;
        if (!(plugin->type & PLUGIN_TYPE_DAEMON))
            continue;
        plugin_thread = malloc(sizeof(struct plugin_threads_t));
        memset(plugin_thread, 0, sizeof(struct plugin_threads_t));
        fprintf(stderr, "Looper plugin [%s] is started\n", plugin->name);;
        if ((err = thread_create(&plugin_thread->thread, start_thread, plugin)) != 0) {
            fprintf(stderr, "Thread could not be started. pthread_create, errno = %d\n", err);;
        }
        do { if (((plugin_thread)->list.le_next = (&plugin_threads_head)->lh_first) != ((void *)0)) (&plugin_threads_head)->lh_first->list.le_prev = &(plugin_thread)->list.le_next; (&plugin_threads_head)->lh_first = (plugin_thread); (plugin_thread)->list.le_prev = &(&plugin_threads_head)->lh_first; } while ( 0);
    }
}

variable_types: err int

user_defined_types: struct plugin_threads_t { void *thread; struct { struct plugin_threads_t *le_next; struct plugin_threads_t **le_prev; } list; }


decompiled_code:
char *__fastcall plugin_find_commands(char *s2, char *a2)
{
const char **v2; // rbx
const char *v4; // rax
FILE *v5; // rdi

v2 = (const char **)plugin_slist_head;
for ( *(_QWORD *)a2 = 0LL; v2; v2 = (const char **)v2[6] )
{
if ( ((_BYTE)v2[2] & 4) != 0 && !strcmp(*v2, s2) )
{
v4 = *(const char **)a2;
v2[6] = *(const char **)a2;
if ( v4 )
*((_QWORD *)v4 + 7) = v2 + 6;
*(_QWORD *)a2 = v2;
v5 = stderr;
v2[7] = a2;
fprintf(v5, "Found plugin %s\n", s2);
}
}
return a2;
}

canonical_decompiled_code:
char *__fastcall func5(char *s2, char *a2)
{
const char **v2; // rbx
const char *v4; // rax
FILE *v5; // rdi

v2 = (const char **)plugin_slist_head;
for ( *(_QWORD *)a2 = 0LL; v2; v2 = (const char **)v2[6] )
{
if ( ((_BYTE)v2[2] & 4) != 0 && !strcmp(*v2, s2) )
{
v4 = *(const char **)a2;
v2[6] = *(const char **)a2;
if ( v4 )
*((_QWORD *)v4 + 7) = v2 + 6;
*(_QWORD *)a2 = v2;
v5 = stderr;
v2[7] = a2;
fprintf(v5, "Found plugin %s\n", s2);
}
}
return a2;
}

original_code:
struct plugin_list_t * plugin_find_commands(char * name, struct plugin_list_t * temp_plugin_list)
{
    struct plugin_t * iterator;
    do { (temp_plugin_list)->lh_first = ((void *)0); } while ( 0);
    for ((iterator) = ((&plugin_slist_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        struct plugin_t * plugin = iterator;
        if (!(plugin->type & PLUGIN_TYPE_COMMAND))
            continue;
        if (strcmp(plugin->name, name) == 0) {
            do { if (((plugin)->list.le_next = (temp_plugin_list)->lh_first) != ((void *)0)) (temp_plugin_list)->lh_first->list.le_prev = &(plugin)->list.le_next; (temp_plugin_list)->lh_first = (plugin); (plugin)->list.le_prev = &(temp_plugin_list)->lh_first; } while ( 0);
            fprintf(stderr, "Found plugin %s\n", name);;
        }
    }
    return temp_plugin_list;
}

canonical_original_code:
struct plugin_list_t *plugin_find_commands(char *name, struct plugin_list_t *temp_plugin_list)
{
    struct plugin_t *iterator;
    do { (temp_plugin_list)->lh_first = ((void *)0); } while ( 0);
    for ((iterator) = ((&plugin_slist_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        struct plugin_t *plugin = iterator;
        if (!(plugin->type & PLUGIN_TYPE_COMMAND))
            continue;
        if (strcmp(plugin->name, name) == 0) {
            do { if (((plugin)->list.le_next = (temp_plugin_list)->lh_first) != ((void *)0)) (temp_plugin_list)->lh_first->list.le_prev = &(plugin)->list.le_next; (temp_plugin_list)->lh_first = (plugin); (plugin)->list.le_prev = &(temp_plugin_list)->lh_first; } while ( 0);
            fprintf(stderr, "Found plugin %s\n", name);;
        }
    }
    return temp_plugin_list;
}

variable_types:
name
char *

return_type: struct plugin_list_t { struct plugin_t { char *name; char **keywords; enum plugin_type { PLUGIN_TYPE_DAEMON=1, PLUGIN_TYPE_COMMAND=expr, PLUGIN_TYPE_GREP=expr } type; void (*send_message)(struct irc_t { struct message_t { struct prefix_t { char servername[100]; struct nickname_t { char nickname[100]; char user[100]; char host[100]; } nickname; } prefix; char command[10]; char params[14][50]; char trailing[510]; } message; char from[100]; struct channel_list_t { struct channel_t { char *name; struct { struct user_t { char *name; struct { struct user_t *le_next; struct user_t **le_prev; } list; } *lh_first; } user_list_head; struct { struct channel_t *le_next; struct channel_t **le_prev; } list; } *lh_first; } channel_list_head; void *sockfd; char *hostname; char *port; char *nickname; char *password; char *admin; struct ajoin_channel_list_t { struct ajoin_channel_t { char *channel_name; struct { struct ajoin_channel_t *le_next; struct ajoin_channel_t **le_prev; } list; } *lh_first; } ajoin_channels_head; } *, char *message); struct irc_t *irc; void (*run)(int type); struct { struct plugin_t *le_next; struct plugin_t **le_prev; } list; } *lh_first; } *

user_defined_types: struct plugin_list_t { struct plugin_t *lh_first; }


decompiled_code:
unsigned int *__fastcall argv_parse(const char *a1)
{
unsigned int *v1; // rax
unsigned int *v2; // r12
char *v3; // rax
const char *v4; // rbp
_QWORD *v5; // rbx
char *v6; // rax
_QWORD *v7; // rbx
char *v8; // rax
_QWORD *v9; // rax
char *v10; // rbp
char v12[1064]; // [rsp+0h] [rbp-428h] BYREF

v1 = (unsigned int *)calloc(0x18uLL, 1uLL);
*v1 = 1;
v2 = v1;
snprintf(v12, 0x400uLL, "%s", a1);
v3 = strtok(v12, " ");
if ( !v3 )
return 0LL;
v4 = v3;
*((_QWORD *)v2 + 1) = 0LL;
*((_QWORD *)v2 + 2) = v2 + 2;
v5 = malloc(0x18uLL);
v6 = strdup(v4);
v5[1] = 0LL;
*v5 = v6;
v5[2] = v2 + 2;
*((_QWORD *)v2 + 1) = v5;
for ( *((_QWORD *)v2 + 2) = v5 + 1; ; *((_QWORD *)v2 + 2) = v7 + 1 )
{
v10 = strtok(0LL, " ");
if ( !v10 )
break;
v7 = malloc(0x18uLL);
v8 = strdup(v10);
v7[1] = 0LL;
*v7 = v8;
v9 = (_QWORD *)*((_QWORD *)v2 + 2);
++*v2;
v7[2] = v9;
*v9 = v7;
}
printf("argc: %d\n", *v2);
return v2;
}

canonical_decompiled_code:
unsigned int *__fastcall func0(const char *a1)
{
unsigned int *v1; // rax
unsigned int *v2; // r12
char *v3; // rax
const char *v4; // rbp
_QWORD *v5; // rbx
char *v6; // rax
_QWORD *v7; // rbx
char *v8; // rax
_QWORD *v9; // rax
char *v10; // rbp
char v12[1064]; // [rsp+0h] [rbp-428h] BYREF

v1 = (unsigned int *)calloc(0x18uLL, 1uLL);
*v1 = 1;
v2 = v1;
snprintf(v12, 0x400uLL, "%s", a1);
v3 = strtok(v12, " ");
if ( !v3 )
return 0LL;
v4 = v3;
*((_QWORD *)v2 + 1) = 0LL;
*((_QWORD *)v2 + 2) = v2 + 2;
v5 = malloc(0x18uLL);
v6 = strdup(v4);
v5[1] = 0LL;
*v5 = v6;
v5[2] = v2 + 2;
*((_QWORD *)v2 + 1) = v5;
for ( *((_QWORD *)v2 + 2) = v5 + 1; ; *((_QWORD *)v2 + 2) = v7 + 1 )
{
v10 = strtok(0LL, " ");
if ( !v10 )
break;
v7 = malloc(0x18uLL);
v8 = strdup(v10);
v7[1] = 0LL;
*v7 = v8;
v9 = (_QWORD *)*((_QWORD *)v2 + 2);
++*v2;
v7[2] = v9;
*v9 = v7;
}
printf("argc: %d\n", *v2);
return v2;
}

original_code:
struct argv_s * argv_parse(char * str)
{
    struct argv_s * param;
    char tokenize_buffer[1024];
    char * token;
    struct argv_t * argv;
    param = malloc(sizeof (struct argv_s));
    memset(param, 0, sizeof(struct argv_s));
    param->argc = 1;
    snprintf(tokenize_buffer, sizeof tokenize_buffer, "%s", str);
    token = strtok(tokenize_buffer, " ");
    if (token == ((void *)0)) {
        return ((void *)0);
    }
    do { (&param->argv_list)->tqh_first = ((void *)0); (&param->argv_list)->tqh_last = &(&param->argv_list)->tqh_first; } while ( 0);
    argv = malloc(sizeof *argv);
    argv->value = strdup(token);
    do { (argv)->list.tqe_next = ((void *)0); (argv)->list.tqe_prev = (&param->argv_list)->tqh_last; *(&param->argv_list)->tqh_last = (argv); (&param->argv_list)->tqh_last = &(argv)->list.tqe_next; } while ( 0);
    while ((token = strtok(((void *)0), " ")) != ((void *)0)) {
        argv = malloc(sizeof *argv);
        argv->value = strdup(token);
        param->argc++;
        do { (argv)->list.tqe_next = ((void *)0); (argv)->list.tqe_prev = (&param->argv_list)->tqh_last; *(&param->argv_list)->tqh_last = (argv); (&param->argv_list)->tqh_last = &(argv)->list.tqe_next; } while ( 0);
    }
    printf("argc: %d\n", param->argc);
    return param;
}

canonical_original_code:
struct argv_s *argv_parse(char *str)
{
    struct argv_s *param;
    char tokenize_buffer[1024];
    char *token;
    struct argv_t *argv;
    param = malloc(sizeof (struct argv_s));
    memset(param, 0, sizeof(struct argv_s));
    param->argc = 1;
    snprintf(tokenize_buffer, sizeof tokenize_buffer, "%s", str);
    token = strtok(tokenize_buffer, " ");
    if (token == ((void *)0)) {
        return ((void *)0);
    }
    do { (&param->argv_list)->tqh_first = ((void *)0); (&param->argv_list)->tqh_last = &(&param->argv_list)->tqh_first; } while ( 0);
    argv = malloc(sizeof *argv);
    argv->value = strdup(token);
    do { (argv)->list.tqe_next = ((void *)0); (argv)->list.tqe_prev = (&param->argv_list)->tqh_last; *(&param->argv_list)->tqh_last = (argv); (&param->argv_list)->tqh_last = &(argv)->list.tqe_next; } while ( 0);
    while ((token = strtok(((void *)0), " ")) != ((void *)0)) {
        argv = malloc(sizeof *argv);
        argv->value = strdup(token);
        param->argc++;
        do { (argv)->list.tqe_next = ((void *)0); (argv)->list.tqe_prev = (&param->argv_list)->tqh_last; *(&param->argv_list)->tqh_last = (argv); (&param->argv_list)->tqh_last = &(argv)->list.tqe_next; } while ( 0);
    }
    printf("argc: %d\n", param->argc);
    return param;
}

variable_types:
str
char *

variable_types: struct argv_s { int argc; struct argv_list_t { struct argv_t { char *value; struct { struct argv_t *tqe_next; struct argv_t **tqe_prev; } list; } *tqh_first; struct argv_t **tqh_last; } argv_list; } *

variable_types:
token
char *

user_defined_types: struct argv_s { int argc; struct argv_list_t argv_list; }

user_defined_types: struct argv_list_t { struct argv_t *tqh_first; struct argv_t **tqh_last; }


decompiled_code:
void __fastcall argv_free(void *ptr)
{
__int64 v2; // rbp
void *v3; // rdi

v2 = *((_QWORD *)ptr + 1);
if ( v2 )
{
v3 = 0LL;
while ( 1 )
{
free(v3);
free(*(void **)v2);
v3 = (void *)v2;
if ( !*(_QWORD *)(v2 + 8) )
break;
v2 = *(_QWORD *)(v2 + 8);
}
}
free((void *)v2);
free(ptr);
}

canonical_decompiled_code:
void __fastcall func1(void *ptr)
{
__int64 v2; // rbp
void *v3; // rdi

v2 = *((_QWORD *)ptr + 1);
if ( v2 )
{
v3 = 0LL;
while ( 1 )
{
free(v3);
free(*(void **)v2);
v3 = (void *)v2;
if ( !*(_QWORD *)(v2 + 8) )
break;
v2 = *(_QWORD *)(v2 + 8);
}
}
free((void *)v2);
free(ptr);
}

original_code:
void argv_free(struct argv_s * arg)
{
    struct argv_t * iterator, * temp;
    temp = ((void *)0);
    for ((iterator) = ((&arg->argv_list)->tqh_first); (iterator); (iterator) = ((iterator)->list.tqe_next)) {
        free(temp);
        free(iterator->value);
        temp = iterator;
    }
    free(temp);
    free(arg);
}

canonical_original_code:
void argv_free(struct argv_s *arg)
{
    struct argv_t *iterator; struct argv_t *temp;
    temp = ((void *)0);
    for ((iterator) = ((&arg->argv_list)->tqh_first); (iterator); (iterator) = ((iterator)->list.tqe_next)) {
        free(temp);
        free(iterator->value);
        temp = iterator;
    }
    free(temp);
    free(arg);
}

variable_types: struct argv_t { char *value; struct { struct argv_t *tqe_next; struct argv_t **tqe_prev; } list; } *


decompiled_code:
void *__fastcall dl_open(const char *a1)
{
return dlopen(a1, 1);
}

canonical_decompiled_code:
void *__fastcall func0(const char *a1)
{
return dlopen(a1, 1);
}

original_code:
dl_library_t dl_open(char * dl)
{
    return dlopen(dl, 0x00001);
}

canonical_original_code:
void *dl_open(char *dl)
{
    return dlopen(dl, 0x00001);
}

variable_types:
dl
char *


decompiled_code:
// attributes: thunk
int dl_close(void *handle)
{
return dlclose(handle);
}

canonical_decompiled_code:
int func1(void *handle)
{
return dlclose(handle);
}

original_code:
void dl_close(dl_library_t library)
{
    dlclose(library);
}

canonical_original_code:
void dl_close(void *library)
{
    dlclose(library);
}

variable_types:
library
void *


decompiled_code:
// attributes: thunk
void *dl_sym(void *handle, const char *name)
{
return dlsym(handle, name);
}

canonical_decompiled_code:
void *func2(void *handle, const char *name)
{
return dlsym(handle, name);
}

original_code:
void * dl_sym(dl_library_t library, char * sym)
{
    return dlsym(library, sym);
}

canonical_original_code:
void *dl_sym(void *library, char *sym)
{
    return dlsym(library, sym);
}

variable_types:
sym
char *


decompiled_code:
__int64 __fastcall db_does_name_exist(_DWORD *a1)
{
*a1 = 1;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func7(_DWORD *a1)
{
*a1 = 1;
return 0LL;
}

original_code:
int db_does_name_exist(void * param, int argc, char ** argv, char ** column_names)
{
    *((int *) param) = 1;
    return 0;
}

canonical_original_code:
int db_does_name_exist(void *param, int argc, char **argv, char **column_names)
{
    *((int *) param) = 1;
    return 0;
}

variable_types:
param
void *

variable_types: argc int

variable_types:
argv
char **


decompiled_code:
__int64 __fastcall db_read_seen(char *s, int a2, const char **a3, const char **a4)
{
__int64 v5; // r13
const char **v6; // rbx
const char *v7; // r8
const char *v8; // rcx
const char *v10; // [rsp+0h] [rbp-48h]

if ( a2 <= 0 )
return 0LL;
v5 = (__int64)&a4[(unsigned int)(a2 - 1) + 1];
v6 = a4;
do
{
while ( 1 )
{
v7 = *v6;
if ( !strcmp(*v6, "lastmsg") )
{
v10 = *v6;
snprintf(s, 0xC8uLL, "%s", *a3);
v7 = v10;
}
if ( !strcmp(v7, "lasttime") )
break;
++v6;
++a3;
if ( v6 == (const char **)v5 )
return 0LL;
}
v8 = *a3;
++v6;
++a3;
snprintf(s + 200, 0xC8uLL, "%s", v8);
}
while ( v6 != (const char **)v5 );
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func8(char *s, int a2, const char **a3, const char **a4)
{
__int64 v5; // r13
const char **v6; // rbx
const char *v7; // r8
const char *v8; // rcx
const char *v10; // [rsp+0h] [rbp-48h]

if ( a2 <= 0 )
return 0LL;
v5 = (__int64)&a4[(unsigned int)(a2 - 1) + 1];
v6 = a4;
do
{
while ( 1 )
{
v7 = *v6;
if ( !strcmp(*v6, "lastmsg") )
{
v10 = *v6;
snprintf(s, 0xC8uLL, "%s", *a3);
v7 = v10;
}
if ( !strcmp(v7, "lasttime") )
break;
++v6;
++a3;
if ( v6 == (const char **)v5 )
return 0LL;
}
v8 = *a3;
++v6;
++a3;
snprintf(s + 200, 0xC8uLL, "%s", v8);
}
while ( v6 != (const char **)v5 );
return 0LL;
}

original_code:
int db_read_seen(void * param, int argc, char ** argv, char ** column_names)
{
    struct seen_t * seen = (struct seen_t *) param;
    int i;
    for (i = 0; i < argc; i++) {
        char * col_name = column_names[i];
        if (strcmp(col_name, "lastmsg") == 0) {
            snprintf(seen->lastmsg, 200, "%s", argv[i]);
        }
        if (strcmp(col_name, "lasttime") == 0) {
            snprintf(seen->lasttime, 200, "%s", argv[i]);
        }
    }
    return 0;
}

canonical_original_code:
int db_read_seen(void *param, int argc, char **argv, char **column_names)
{
    struct seen_t *seen = (struct seen_t *) param;
    int i;
    for (i = 0; i < argc; i++) {
        char *col_name = column_names[i];
        if (strcmp(col_name, "lastmsg") == 0) {
            snprintf(seen->lastmsg, 200, "%s", argv[i]);
        }
        if (strcmp(col_name, "lasttime") == 0) {
            snprintf(seen->lasttime, 200, "%s", argv[i]);
        }
    }
    return 0;
}

variable_types: struct seen_t { char lastmsg[200]; char lasttime[200]; } *

variable_types: i int


decompiled_code:
__int64 init()
{
_OWORD *v0; // rax

v0 = malloc(0x40uLL);
v0[2] = 0LL;
*((_QWORD *)v0 + 5) = run;
v0[1] = 0LL;
*(_QWORD *)v0 = "seen";
*((_DWORD *)v0 + 4) = 12;
*((_QWORD *)v0 + 1) = &keywords;
v0[3] = 0LL;
plugin = v0;
create_tables();
return plugin;
}

original_code:
struct plugin_t * init(void)
{
    plugin = malloc(sizeof (struct plugin_t));
    memset(plugin, 0, sizeof *plugin);
    plugin->run = run;
    plugin->name = "seen";
    plugin->type = PLUGIN_TYPE_COMMAND | PLUGIN_TYPE_GREP;
    plugin->keywords = keywords;
    create_tables();
    return plugin;
}

canonical_original_code:
struct plugin_t *init()
{
    plugin = malloc(sizeof (struct plugin_t));
    memset(plugin, 0, sizeof *plugin);
    plugin->run = run;
    plugin->name = "seen";
    plugin->type = PLUGIN_TYPE_COMMAND | PLUGIN_TYPE_GREP;
    plugin->keywords = keywords;
    create_tables();
    return plugin;
}

user_defined_types: struct irc_t { struct message_t message; char from[100]; struct channel_list_t channel_list_head; void *sockfd; char *hostname; char *port; char *nickname; char *password; char *admin; struct ajoin_channel_list_t ajoin_channels_head; }


original_code:
void config_free(struct irc_t * irc)
{
    struct ajoin_channel_t * iterator;
    for ((iterator) = ((&irc->ajoin_channels_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        free(iterator->channel_name);
        free (iterator);
    }
    free(irc->nickname);
    free(irc->password);
    free(irc->admin);
    free(irc->hostname);
    free(irc->port);
}

canonical_original_code:
void config_free(struct irc_t *irc)
{
    struct ajoin_channel_t *iterator;
    for ((iterator) = ((&irc->ajoin_channels_head)->lh_first); (iterator); (iterator) = ((iterator)->list.le_next)) {
        free(iterator->channel_name);
        free (iterator);
    }
    free(irc->nickname);
    free(irc->password);
    free(irc->admin);
    free(irc->hostname);
    free(irc->port);
}

variable_types: struct irc_t { struct message_t { struct prefix_t { char servername[100]; struct nickname_t { char nickname[100]; char user[100]; char host[100]; } nickname; } prefix; char command[10]; char params[14][50]; char trailing[510]; } message; char from[100]; struct channel_list_t { struct channel_t { char *name; struct { struct user_t { char *name; struct { struct user_t *le_next; struct user_t **le_prev; } list; } *lh_first; } user_list_head; struct { struct channel_t *le_next; struct channel_t **le_prev; } list; } *lh_first; } channel_list_head; void *sockfd; char *hostname; char *port; char *nickname; char *password; char *admin; struct ajoin_channel_list_t { struct ajoin_channel_t { char *channel_name; struct { struct ajoin_channel_t *le_next; struct ajoin_channel_t **le_prev; } list; } *lh_first; } ajoin_channels_head; } *

user_defined_types: struct message_t { struct prefix_t prefix; char command[10]; char params[14][50]; char trailing[510]; }


repo: neuschaefer/llfalse

decompiled_code:
int __fastcall lf_printnum(unsigned int a1)
{
return printf("%ld", a1);
}

canonical_decompiled_code:
int __fastcall func6(unsigned int a1)
{
return printf("%ld", a1);
}

original_code:
void lf_printnum(uint32_t num)
{
 printf("%ld", (long) num);
}

canonical_original_code:
void lf_printnum(unsigned int num)
{
 printf("%ld", (long) num);
}

variable_types:
num
unsigned int


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

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

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

canonical_original_code:
void lf_printstring(char *str)
{
 printf("%s", str);
}


decompiled_code:
// attributes: thunk
int lf_putchar(int c)
{
return putchar(c);
}

canonical_decompiled_code:
int func8(int c)
{
return putchar(c);
}

original_code:
void lf_putchar(uint32_t ch)
{
 putchar((int)ch);
}

canonical_original_code:
void lf_putchar(unsigned int ch)
{
 putchar((int)ch);
}

variable_types:
ch
unsigned int


decompiled_code:
int lf_getchar()
{
return getchar();
}

canonical_decompiled_code:
int func9()
{
return getchar();
}

original_code:
uint32_t lf_getchar(void)
{
 int ch = getchar();
 if (ch == (-1))
  return ~0;
 return (uint32_t) ch;
}

canonical_original_code:
unsigned int lf_getchar()
{
 int ch = getchar();
 if (ch == (-1))
  return ~0;
 return (unsigned int) ch;
}

variable_types: ch int

return_type: unsigned int


decompiled_code:
int lf_flush()
{
fflush(stdin);
return fflush(stdout);
}

canonical_decompiled_code:
int func10()
{
fflush(stdin);
return fflush(stdout);
}

original_code:
void lf_flush(void)
{
 fflush(stdin);
 fflush(stdout);
}

canonical_original_code:
void lf_flush()
{
 fflush(stdin);
 fflush(stdout);
}


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax

if ( argc != 2 )
help_die(*argv);
v3 = atoi(argv[1]);
flatten(v3);
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int v3; // eax

if ( argc != 2 )
func8(*argv);
v3 = atoi(argv[1]);
func11(v3);
return 0;
}

original_code:
int main (int argc, char ** argv)
{
 if (argc != 2)
  help_die(argv[0]);
 flatten(atoi(argv[1]));
}

canonical_original_code:
int main(int argc, char **argv)
{
 if (argc != 2)
  help_die(argv[0]);
 flatten(atoi(argv[1]));
}


help

decompiled_code:
int __fastcall help(const char *a1)
{
return printf(
"This is falseflat, an equivalent of topformflat for the False programming\n"
"language. See https://web.archive.org/web/20200701152100/http://delta.tigris.org/\n"
"and https://strlen.com/false for more information.\n"
"\n"
"Usage: %s [level] <in_file.f >out_file.f\n",
a1);
}

canonical_decompiled_code:
int __fastcall func7(const char *a1)
{
return printf(
"This is falseflat, an equivalent of topformflat for the False programming\n"
"language. See https://web.archive.org/web/20200701152100/http://delta.tigris.org/\n"
"and https://strlen.com/false for more information.\n"
"\n"
"Usage: %s [level] <in_file.f >out_file.f\n",
a1);
}

original_code:
static void help(const char *argv0)
{
 printf(
"This is falseflat, an equivalent of topformflat for the False programming\n"
"language. See https://web.archive.org/web/20200701152100/http://delta.tigris.org/\n"
"and https://strlen.com/false for more information.\n\n"
"Usage: %s [level] <in_file.f >out_file.f\n", argv0);
}

canonical_original_code:
static void help(char *argv0)
{
 printf(
"This is falseflat, an equivalent of topformflat for the False programming\n"
"language. See https://web.archive.org/web/20200701152100/http://delta.tigris.org/\n"
"and https://strlen.com/false for more information.\n\n"
"Usage: %s [level] <in_file.f >out_file.f\n", argv0);
}


decompiled_code:
void __fastcall __noreturn help_die(const char *a1)
{
help(a1);
exit(1);
}

canonical_decompiled_code:
void __fastcall __noreturn func8(const char *a1)
{
func7(a1);
exit(1);
}

original_code:
static void help_die(const char *argv0)
{
 help(argv0);
 exit(1);
}

canonical_original_code:
static void help_die(char *argv0)
{
 help(argv0);
 exit(1);
}


die

decompiled_code:
void __fastcall __noreturn die(const char *a1)
{
fprintf(stderr, "%s\n", a1);
exit(1);
}

canonical_decompiled_code:
void __fastcall __noreturn func9(const char *a1)
{
fprintf(stderr, "%s\n", a1);
exit(1);
}

original_code:
static void die(const char *msg)
{
 fprintf(stderr, "%s\n", msg);
 exit(1);
}

canonical_original_code:
static void die(char *msg)
{
 fprintf(stderr, "%s\n", msg);
 exit(1);
}

variable_types:
msg
char *


decompiled_code:
void __noreturn die_unex_eof()
{
die("unexpected end of file");
}

canonical_decompiled_code:
void __noreturn func10()
{
func9("unexpected end of file");
}

original_code:
static void die_unex_eof(void)
{
 die("unexpected end of file");
}

canonical_original_code:
static void die_unex_eof()
{
 die("unexpected end of file");
}


flatten

decompiled_code:
int __fastcall flatten(int a1)
{
int v2; // ebx
int result; // eax
int i; // ebp
const unsigned __int16 **v5; // r14
int v6; // edi
const unsigned __int16 *v7; // r15
int v8; // eax
int v9; // er13
int v10; // eax

v2 = 0;
LABEL_2:
result = getchar();
for ( i = result; result != -1; i = result )
{
v5 = __ctype_b_loc();
if ( ((*v5)[i] & 0x2000) != 0 )
goto LABEL_2;
if ( v2 > a1 || (v9 = i == 93, v2 <= v9) )
{
if ( i == 123 )
goto LABEL_29;
}
else
{
do
{
++v9;
putchar(32);
}
while ( v2 != v9 );
if ( i == 123 )
{
LABEL_29:
putchar(123);
while ( 1 )
{
v6 = getchar();
if ( v6 == 125 )
goto LABEL_12;
if ( v6 != 10 )
break;
LABEL_35:
printf(" // ");
}
while ( v6 != -1 )
{
putchar(v6);
v6 = getchar();
if ( v6 == 125 )
goto LABEL_12;
if ( v6 == 10 )
goto LABEL_35;
}
LABEL_25:
die_unex_eof();
}
}
if ( i == 91 )
{
++v2;
putchar(91);
}
else if ( i == 93 )
{
if ( !v2 )
die("unexpected end of lambda");
--v2;
putchar(93);
}
else if ( ((*v5)[i] & 0x800) != 0 )
{
do
{
if ( i != -1 )
putchar(i);
v7 = *v5;
i = getchar();
}
while ( (v7[i] & 0x800) != 0 );
if ( i != -1 )
ungetc(i, stdin);
}
else if ( i == 39 )
{
putchar(39);
v10 = getchar();
putchar(v10);
}
else
{
if ( i == 34 )
{
while ( 1 )
{
putchar(i);
v8 = getchar();
i = v8;
if ( v8 == 34 )
break;
if ( v8 == -1 )
goto LABEL_25;
}
}
v6 = i;
LABEL_12:
putchar(v6);
}
if ( v2 > a1 )
goto LABEL_2;
putchar(10);
result = getchar();
}
if ( v2 )
goto LABEL_25;
return result;
}

canonical_decompiled_code:
int __fastcall func11(int a1)
{
int v2; // ebx
int result; // eax
int i; // ebp
const unsigned __int16 **v5; // r14
int v6; // edi
const unsigned __int16 *v7; // r15
int v8; // eax
int v9; // er13
int v10; // eax

v2 = 0;
LABEL_2:
result = getchar();
for ( i = result; result != -1; i = result )
{
v5 = __ctype_b_loc();
if ( ((*v5)[i] & 0x2000) != 0 )
goto LABEL_2;
if ( v2 > a1 || (v9 = i == 93, v2 <= v9) )
{
if ( i == 123 )
goto LABEL_29;
}
else
{
do
{
++v9;
putchar(32);
}
while ( v2 != v9 );
if ( i == 123 )
{
LABEL_29:
putchar(123);
while ( 1 )
{
v6 = getchar();
if ( v6 == 125 )
goto LABEL_12;
if ( v6 != 10 )
break;
LABEL_35:
printf(" // ");
}
while ( v6 != -1 )
{
putchar(v6);
v6 = getchar();
if ( v6 == 125 )
goto LABEL_12;
if ( v6 == 10 )
goto LABEL_35;
}
LABEL_25:
func10();
}
}
if ( i == 91 )
{
++v2;
putchar(91);
}
else if ( i == 93 )
{
if ( !v2 )
func9("unexpected end of lambda");
--v2;
putchar(93);
}
else if ( ((*v5)[i] & 0x800) != 0 )
{
do
{
if ( i != -1 )
putchar(i);
v7 = *v5;
i = getchar();
}
while ( (v7[i] & 0x800) != 0 );
if ( i != -1 )
ungetc(i, stdin);
}
else if ( i == 39 )
{
putchar(39);
v10 = getchar();
putchar(v10);
}
else
{
if ( i == 34 )
{
while ( 1 )
{
putchar(i);
v8 = getchar();
i = v8;
if ( v8 == 34 )
break;
if ( v8 == -1 )
goto LABEL_25;
}
}
v6 = i;
LABEL_12:
putchar(v6);
}
if ( v2 > a1 )
goto LABEL_2;
putchar(10);
result = getchar();
}
if ( v2 )
goto LABEL_25;
return result;
}

original_code:
static void flatten(int threshold)
{
 int level = 0;
 int ch, i;
 while (1) {
  ch = getchar();
  if (ch == (-1)) {
   if (level > 0)
    die_unex_eof();
   break;
  }
  if (((*__ctype_b_loc ())[(int) ((ch))] & (unsigned short int) _ISspace))
   continue;
  if (level <= threshold)
   for (i = (ch == ']'); i < level; i++)
    putchar(' ');
  if (ch == '{') {
   putchar(ch);
   while ((ch = getchar()) != '}') {
    if (ch == '\n')
     printf(" // ");
    else if (ch == (-1))
     die_unex_eof();
    else
     putchar(ch);
   }
   putchar(ch);
  } else if (ch == '[') {
   putchar(ch);
   level++;
  } else if (ch == ']') {
   if (level == 0)
    die("unexpected end of lambda");
   level--;
   putchar(ch);
  } else if (((*__ctype_b_loc ())[(int) ((ch))] & (unsigned short int) _ISdigit)) {
   do {
    if (ch != (-1))
     putchar(ch);
   } while (((*__ctype_b_loc ())[(int) (((ch = getchar())))] & (unsigned short int) _ISdigit));
   if (ch != (-1))
    ungetc(ch, stdin);
  } else if (ch == '\'') {
   putchar(ch);
   putchar(getchar());
  } else if (ch == '"') {
   do {
    putchar(ch);
    ch = getchar();
   } while (ch != '"' && ch != (-1));
   if (ch == (-1))
    die_unex_eof();
   putchar(ch);
  } else {
   putchar(ch);
  }
  if (level <= threshold)
   putchar('\n');
 }
}

canonical_original_code:
static void flatten(int threshold)
{
 int level = 0;
 int ch; int i;
 while (1) {
  ch = getchar();
  if (ch == (-1)) {
   if (level > 0)
    die_unex_eof();
   break;
  }
  if (((*__ctype_b_loc ())[(int) ((ch))] & (unsigned short) _ISspace))
   continue;
  if (level <= threshold)
   for (i = (ch == ']'); i < level; i++)
    putchar(' ');
  if (ch == '{') {
   putchar(ch);
   while ((ch = getchar()) != '}') {
    if (ch == '\n')
     printf(" // ");
    else if (ch == (-1))
     die_unex_eof();
    else
     putchar(ch);
   }
   putchar(ch);
  } else if (ch == '[') {
   putchar(ch);
   level++;
  } else if (ch == ']') {
   if (level == 0)
    die("unexpected end of lambda");
   level--;
   putchar(ch);
  } else if (((*__ctype_b_loc ())[(int) ((ch))] & (unsigned short) _ISdigit)) {
   do {
    if (ch != (-1))
     putchar(ch);
   } while (((*__ctype_b_loc ())[(int) (((ch = getchar())))] & (unsigned short) _ISdigit));
   if (ch != (-1))
    ungetc(ch, stdin);
  } else if (ch == '\'') {
   putchar(ch);
   putchar(getchar());
  } else if (ch == '"') {
   do {
    putchar(ch);
    ch = getchar();
   } while (ch != '"' && ch != (-1));
   if (ch == (-1))
    die_unex_eof();
   putchar(ch);
  } else {
   putchar(ch);
  }
  if (level <= threshold)
   putchar('\n');
 }
}

variable_types: threshold int

variable_types: level int


oom

decompiled_code:
void __fastcall __noreturn oom(__int64 a1)
{
fprintf(stderr, "fatal error: Can't allocate %lu bytes of memory!\n", a1);
exit(1);
}

canonical_decompiled_code:
void __fastcall __noreturn func0(__int64 a1)
{
fprintf(stderr, "fatal error: Can't allocate %lu bytes of memory!\n", a1);
exit(1);
}

original_code:
static void oom(size_t sz)
{
 fprintf(stderr, "fatal error: Can't allocate %lu bytes of memory!\n",
   (unsigned long) sz);
 exit(1);
}

canonical_original_code:
static void oom(unsigned long sz)
{
 fprintf(stderr, "fatal error: Can't allocate %lu bytes of memory!\n",
   (unsigned long) sz);
 exit(1);
}

variable_types:
sz
unsigned long


xmalloc

decompiled_code:
void *__fastcall xmalloc(size_t a1)
{
void *result; // rax

result = malloc(a1);
if ( !result )
oom(a1);
return result;
}

canonical_decompiled_code:
void *__fastcall func1(size_t a1)
{
void *result; // rax

result = malloc(a1);
if ( !result )
func0(a1);
return result;
}

original_code:
void *xmalloc(size_t sz)
{
 void *p = malloc(sz);
 if (!p)
  oom(sz);
 return p;
}

canonical_original_code:
void *xmalloc(unsigned long sz)
{
 void *p = malloc(sz);
 if (!p)
  oom(sz);
 return p;
}

variable_types:
p
void *


decompiled_code:
_QWORD *growbuf_new_node()
{
_QWORD *v0; // rax
_QWORD *v1; // r12

v0 = xmalloc(0x20uLL);
*v0 = 0LL;
v1 = v0;
v0[1] = 256LL;
v0[2] = 0LL;
v0[3] = xmalloc(0x100uLL);
return v1;
}

original_code:
static struct growbuf_node *growbuf_new_node(void)
{
 struct growbuf_node *node = xmalloc(sizeof(*node));
 node->next = ((void *)0);
 node->size = 256;
 node->filled = 0;
 node->buf = xmalloc(node->size);
 return node;
}

canonical_original_code:
static struct growbuf_node *growbuf_new_node()
{
 struct growbuf_node *node = xmalloc(sizeof(*node));
 node->next = ((void *)0);
 node->size = 256;
 node->filled = 0;
 node->buf = xmalloc(node->size);
 return node;
}

variable_types: struct growbuf_node { struct growbuf_node *next; unsigned long size; char *buf; } *


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

result = xmalloc(0x10uLL);
*result = 0LL;
result[1] = 0LL;
return result;
}

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

result = func1(0x10uLL);
*result = 0LL;
result[1] = 0LL;
return result;
}

original_code:
struct growbuf *growbuf_new(void)
{
 struct growbuf *buf = xmalloc(sizeof(*buf));
 buf->first = ((void *)0);
 buf->last = ((void *)0);
 return buf;
}

canonical_original_code:
struct growbuf *growbuf_new()
{
 struct growbuf *buf = xmalloc(sizeof(*buf));
 buf->first = ((void *)0);
 buf->last = ((void *)0);
 return buf;
}

variable_types: struct growbuf { struct growbuf_node { struct growbuf_node *next; unsigned long size; char *buf; } *first; } *

user_defined_types: struct growbuf { struct growbuf_node *first; }


decompiled_code:
void __fastcall growbuf_free(void *ptr)
{
_QWORD *v1; // rbx
_QWORD *v3; // rbp
void *v4; // rdi

if ( !ptr )
_assert_fail("buf", "util.c", 0x4Bu, "growbuf_free");
v1 = *(_QWORD **)ptr;
if ( *(_QWORD *)ptr )
{
do
{
v3 = v1;
v1 = (_QWORD *)*v1;
v4 = (void *)v3[3];
if ( !v4 )
_assert_fail("node->buf", "util.c", 0x50u, "growbuf_free");
free(v4);
free(v3);
}
while ( v1 );
}
free(ptr);
}

canonical_decompiled_code:
void __fastcall func4(void *ptr)
{
_QWORD *v1; // rbx
_QWORD *v3; // rbp
void *v4; // rdi

if ( !ptr )
_assert_fail("buf", "util.c", 0x4Bu, "growbuf_free");
v1 = *(_QWORD **)ptr;
if ( *(_QWORD *)ptr )
{
do
{
v3 = v1;
v1 = (_QWORD *)*v1;
v4 = (void *)v3[3];
if ( !v4 )
_assert_fail("node->buf", "util.c", 0x50u, "growbuf_free");
free(v4);
free(v3);
}
while ( v1 );
}
free(ptr);
}

original_code:
void growbuf_free(struct growbuf *buf)
{
 struct growbuf_node *node, *next;
 ((buf) ? (void) (0) : __assert_fail ("buf", "util.c", 75, __extension__ __PRETTY_FUNCTION__));
 for (node = buf->first; node; node = next) {
  next = node->next;
  ((node->buf) ? (void) (0) : __assert_fail ("node->buf", "util.c", 80, __extension__ __PRETTY_FUNCTION__));
  free(node->buf);
  free(node);
 }
 free(buf);
}

canonical_original_code:
void growbuf_free(struct growbuf *buf)
{
 struct growbuf_node *node; struct growbuf_node *next;
 ((buf) ? (void) (0) : __assert_fail ("buf", "util.c", 75, __extension__ __PRETTY_FUNCTION__));
 for (node = buf->first; node; node = next) {
  next = node->next;
  ((node->buf) ? (void) (0) : __assert_fail ("node->buf", "util.c", 80, __extension__ __PRETTY_FUNCTION__));
  free(node->buf);
  free(node);
 }
 free(buf);
}

user_defined_types: struct growbuf_node { struct growbuf_node *next; unsigned long size; char *buf; }


decompiled_code:
void __fastcall growbuf_add(_QWORD *a1, char *a2, size_t a3)
{
size_t v5; // rbp
_QWORD *v6; // rax
const void *v7; // rsi
__int64 v8; // rdi
size_t v9; // rbx

if ( a3 )
{
v5 = a3;
do
{
growbuf_check_node(a1);
v6 = (_QWORD *)a1[1];
v7 = a2;
v8 = v6[2];
v9 = v6[1] - v8;
if ( v9 > v5 )
v9 = v5;
a2 += v9;
memcpy((void *)(v6[3] + v8), v7, v9);
*(_QWORD *)(a1[1] + 16LL) += v9;
v5 -= v9;
}
while ( v5 );
}
}

canonical_decompiled_code:
void __fastcall func5(_QWORD *a1, char *a2, size_t a3)
{
size_t v5; // rbp
_QWORD *v6; // rax
const void *v7; // rsi
__int64 v8; // rdi
size_t v9; // rbx

if ( a3 )
{
v5 = a3;
do
{
growbuf_check_node(a1);
v6 = (_QWORD *)a1[1];
v7 = a2;
v8 = v6[2];
v9 = v6[1] - v8;
if ( v9 > v5 )
v9 = v5;
a2 += v9;
memcpy((void *)(v6[3] + v8), v7, v9);
*(_QWORD *)(a1[1] + 16LL) += v9;
v5 -= v9;
}
while ( v5 );
}
}

original_code:
void growbuf_add(struct growbuf *buf, const char *text, size_t len)
{
 while (len) {
  growbuf_check_node(buf);
  size_t to_copy = (((len) < (buf->last->size - buf->last->filled))? (len):(buf->last->size - buf->last->filled));
  memcpy(buf->last->buf + buf->last->filled, text, to_copy);
  text += to_copy;
  len -= to_copy;
  buf->last->filled += to_copy;
 }
}

canonical_original_code:
void growbuf_add(struct growbuf *buf, char *text, unsigned long len)
{
 while (len) {
  growbuf_check_node(buf);
  unsigned long to_copy = (((len) < (buf->last->size - buf->last->filled))? (len):(buf->last->size - buf->last->filled));
  memcpy(buf->last->buf + buf->last->filled, text, to_copy);
  text += to_copy;
  len -= to_copy;
  buf->last->filled += to_copy;
 }
}

variable_types:
text
char *

variable_types:
len
unsigned long


decompiled_code:
__int64 __fastcall growbuf_len(_QWORD *a1)
{
_QWORD *v1; // rax
__int64 v2; // r8

if ( !a1 )
_assert_fail("buf != NULL", "util.c", 0x86u, "growbuf_len");
v1 = (_QWORD *)*a1;
v2 = 0LL;
if ( *a1 )
{
do
{
v2 += v1[2];
v1 = (_QWORD *)*v1;
}
while ( v1 );
}
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func6(_QWORD *a1)
{
_QWORD *v1; // rax
__int64 v2; // r8

if ( !a1 )
_assert_fail("buf != NULL", "util.c", 0x86u, "growbuf_len");
v1 = (_QWORD *)*a1;
v2 = 0LL;
if ( *a1 )
{
do
{
v2 += v1[2];
v1 = (_QWORD *)*v1;
}
while ( v1 );
}
return v2;
}

original_code:
size_t growbuf_len(struct growbuf *buf)
{
 size_t len = 0;
 struct growbuf_node *node;
 ((buf != ((void *)0)) ? (void) (0) : __assert_fail ("buf != NULL", "util.c", 134, __extension__ __PRETTY_FUNCTION__));
 for (node = buf->first; node; node = node->next)
  len += node->filled;
 return len;
}

canonical_original_code:
unsigned long growbuf_len(struct growbuf *buf)
{
 unsigned long len = 0;
 struct growbuf_node *node;
 ((buf != ((void *)0)) ? (void) (0) : __assert_fail ("buf != NULL", "util.c", 134, __extension__ __PRETTY_FUNCTION__));
 for (node = buf->first; node; node = node->next)
  len += node->filled;
 return len;
}

return_type: unsigned long


decompiled_code:
void *__fastcall growbuf_buf(_QWORD *a1)
{
void *result; // rax

if ( !a1 )
_assert_fail("buf != NULL", "util.c", 0xAFu, "growbuf_buf");
growbuf_concat(a1);
result = &EMPTY_STRING;
if ( *a1 )
result = *(void **)(*a1 + 24LL);
return result;
}

canonical_decompiled_code:
void *__fastcall func7(_QWORD *a1)
{
void *result; // rax

if ( !a1 )
_assert_fail("buf != NULL", "util.c", 0xAFu, "growbuf_buf");
growbuf_concat(a1);
result = &EMPTY_STRING;
if ( *a1 )
result = *(void **)(*a1 + 24LL);
return result;
}

original_code:
const char *growbuf_buf(struct growbuf *buf)
{
 ((buf != ((void *)0)) ? (void) (0) : __assert_fail ("buf != NULL", "util.c", 175, __extension__ __PRETTY_FUNCTION__));
 growbuf_concat(buf);
 if (buf->first)
  return buf->first->buf;
 return EMPTY_STRING;
}

return_type: char *


main

repo: neuschaefer/mind

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx
__int64 v4; // rsi
int v5; // eax
int *v6; // rbx
__int64 v7; // rsi
char v9[12]; // [rsp+Ch] [rbp-Ch] BYREF

parse_args(argc, (char **)argv);
if ( !chances )
chances = 10;
atexit(exit_term);
init_term();
mkanswer();
if ( chances <= 0 )
goto LABEL_8;
v3 = 1;
do
{
v4 = (unsigned int)v3++;
printf(" %2d. ", v4);
get_choice(v9);
v5 = print_test(v9);
if ( chances < v3 )
break;
}
while ( !v5 );
if ( !v5 )
{
LABEL_8:
v6 = (int *)&answer;
printf(" answer:");
do
{
v7 = (unsigned int)*(char *)v6;
v6 = (int *)((char *)v6 + 1);
printf(" %c", v7);
}
while ( v6 != &chances );
putchar(10);
}
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx
__int64 v4; // rsi
int v5; // eax
int *v6; // rbx
__int64 v7; // rsi
char v9[12]; // [rsp+Ch] [rbp-Ch] BYREF

func11(argc, (char **)argv);
if ( !chances )
chances = 10;
func18(exit_term);
func13();
func14();
if ( chances <= 0 )
goto LABEL_8;
v3 = 1;
do
{
v4 = (unsigned int)v3++;
printf(" %2d. ", v4);
func15(v9);
v5 = func9(v9);
if ( chances < v3 )
break;
}
while ( !v5 );
if ( !v5 )
{
LABEL_8:
v6 = (int *)&answer;
printf(" answer:");
do
{
v7 = (unsigned int)*(char *)v6;
v6 = (int *)((char *)v6 + 1);
printf(" %c", v7);
}
while ( v6 != &chances );
putchar(10);
}
return 0;
}

original_code:
int main(int argc, char **argv)
{
 int i, done = 0;
 char choice[4];
 parse_args(argc, argv);
 if (!chances)
  chances = 10;
 atexit(exit_term);
 init_term();
 mkanswer();
 for (i = 1; i <= chances && !done; i++) {
  printf(" %2d. ", i);
  get_choice(choice);
  done = print_test(choice);
 }
 if (!done) {
  printf(" answer:");
  for (i = 0; i < 4; i++)
   printf(" %c", answer[i]);
  putchar('\n');
 }
 return 0;
}

canonical_original_code:
int main(int argc, char **argv)
{
 int i; int done = 0;
 char choice[4];
 parse_args(argc, argv);
 if (!chances)
  chances = 10;
 atexit(exit_term);
 init_term();
 mkanswer();
 for (i = 1; i <= chances && !done; i++) {
  printf(" %2d. ", i);
  get_choice(choice);
  done = print_test(choice);
 }
 if (!done) {
  printf(" answer:");
  for (i = 0; i < 4; i++)
   printf(" %c", answer[i]);
  putchar('\n');
 }
 return 0;
}

variable_types: argc int

variable_types: done int

variable_types:
choice
char [4]


decompiled_code:
_BOOL8 __fastcall is_valid(char a1)
{
return (unsigned __int8)(a1 - 48) <= 9u;
}

canonical_decompiled_code:
_BOOL8 __fastcall func7(char a1)
{
return (unsigned __int8)(a1 - 48) <= 9u;
}

original_code:
static int is_valid(char c) {
 return (c >= '0' && c <= '9');
}

variable_types: c char


decompiled_code:
int __fastcall choice_back(int a1)
{
int i; // ebx

if ( a1 > 0 )
{
for ( i = 0; i != a1; ++i )
{
putchar(8);
putchar(8);
}
}
return printf("\x1B[K");
}

canonical_decompiled_code:
int __fastcall func8(int a1)
{
int i; // ebx

if ( a1 > 0 )
{
for ( i = 0; i != a1; ++i )
{
putchar(8);
putchar(8);
}
}
return printf("\x1B[K");
}

original_code:
static void choice_back(int n)
{
 int i;
 for (i = 0; i < n; i++) {
  putchar('\010');
  putchar('\010');
 }
 printf("\033[K");
}

variable_types: n int

variable_types: i int


decompiled_code:
_BOOL8 __fastcall print_test(__int64 a1)
{
int v1; // er12
__int64 v2; // rbx
char v3; // dl
const char *v4; // rsi
__int64 i; // rax

v1 = 0;
v2 = 0LL;
putchar(32);
do
{
v3 = *(_BYTE *)(a1 + v2);
if ( v3 == answer[v2] )
{
v4 = *(const char **)(colors + 16);
++v1;
}
else
{
v4 = *(const char **)colors;
for ( i = 0LL; i != 4; ++i )
{
if ( (_DWORD)i != (_DWORD)v2 && v3 == answer[i] )
v4 = *(const char **)(colors + 8);
}
}
++v2;
printf("%s ", v4);
}
while ( v2 != 4 );
putchar(10);
return v1 == 4;
}

canonical_decompiled_code:
_BOOL8 __fastcall func9(__int64 a1)
{
int v1; // er12
__int64 v2; // rbx
char v3; // dl
const char *v4; // rsi
__int64 i; // rax

v1 = 0;
v2 = 0LL;
putchar(32);
do
{
v3 = *(_BYTE *)(a1 + v2);
if ( v3 == answer[v2] )
{
v4 = *(const char **)(colors + 16);
++v1;
}
else
{
v4 = *(const char **)colors;
for ( i = 0LL; i != 4; ++i )
{
if ( (_DWORD)i != (_DWORD)v2 && v3 == answer[i] )
v4 = *(const char **)(colors + 8);
}
}
++v2;
printf("%s ", v4);
}
while ( v2 != 4 );
putchar(10);
return v1 == 4;
}

original_code:
static int print_test(char *choice)
{
 int i, j, right = 0;
 const char *match;
 putchar(' ');
 for (i = 0; i < 4; i++) {
  match = colors->red;
  if (choice[i] == answer[i]) {
   match = colors->green;
   right++;
  } else for (j = 0; j < 4; j++) {
   if (j == i)
    continue;
   if (choice[i] == answer[j])
    match = colors->yellow;
  }
  printf("%s ", match);
 }
 putchar('\n');
 return right == 4;
}

canonical_original_code:
static int print_test(char *choice)
{
 int i; int j; int right = 0;
 char *match;
 putchar(' ');
 for (i = 0; i < 4; i++) {
  match = colors->red;
  if (choice[i] == answer[i]) {
   match = colors->green;
   right++;
  } else for (j = 0; j < 4; j++) {
   if (j == i)
    continue;
   if (choice[i] == answer[j])
    match = colors->yellow;
  }
  printf("%s ", match);
 }
 putchar('\n');
 return right == 4;
}

variable_types:
choice
char *

variable_types: j int

variable_types: right int

variable_types:
match
char *


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

result = isterm;
if ( isterm )
result = tcsetattr(0, 0, &saved_tios);
return result;
}

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

result = isterm;
if ( isterm )
result = tcsetattr(0, 0, &saved_tios);
return result;
}

original_code:
static void exit_term(void)
{
 if (isterm) {
  tcsetattr(0, 0, &saved_tios);
 }
}

canonical_original_code:
static void exit_term()
{
 if (isterm) {
  tcsetattr(0, 0, &saved_tios);
 }
}


decompiled_code:
int __fastcall parse_args(int argc, char **argv)
{
int result; // eax
int v3; // ebx

opterr = 0;
while ( 1 )
{
result = getopt(argc, argv, "C:c:");
v3 = result;
if ( result == -1 )
break;
if ( result == 67 )
{
colormode = (*__ctype_tolower_loc())[*optarg];
}
else
{
if ( result != 99 )
{
fprintf(stderr, "usage: %s [-c <chances>] [-C <color>]\n", *argv);
exit(v3 != 104);
}
chances = atoi(optarg);
}
}
return result;
}

canonical_decompiled_code:
int __fastcall func11(int argc, char **argv)
{
int result; // eax
int v3; // ebx

opterr = 0;
while ( 1 )
{
result = getopt(argc, argv, "C:c:");
v3 = result;
if ( result == -1 )
break;
if ( result == 67 )
{
colormode = (*__ctype_tolower_loc())[*optarg];
}
else
{
if ( result != 99 )
{
fprintf(stderr, "usage: %s [-c <chances>] [-C <color>]\n", *argv);
exit(v3 != 104);
}
chances = atoi(optarg);
}
}
return result;
}

original_code:
static void parse_args(int argc, char **argv)
{
 int opt;
 opterr = 0;
 while (1) {
  opt = getopt(argc, argv, "C:c:");
  if (opt == -1)
   break;
  switch (opt) {
  case 'C':
   colormode = tolower(optarg[0]);
   break;
  case 'c':
   chances = atoi(optarg);
   break;
  default:
   fprintf(stderr, "usage: %s [-c <chances>] "
     "[-C <color>]\n", argv[0]);
   exit((opt == 'h')? 0 : 1);
  }
 }
}

variable_types:
argv
char **

variable_types: opt int


decompiled_code:
char **get_colors()
{
__int16 **v0; // r8

if ( colormode == 108 )
return colors_light;
if ( colormode > 108 )
{
v0 = &colors_mono;
if ( colormode == 109 )
return (char **)v0;
}
else
{
v0 = (__int16 **)colors_dark;
if ( colormode == 100 )
return (char **)v0;
if ( colormode == 103 )
return colors_grey;
}
fwrite("invalid color mode, falling back to mono\n", 1uLL, 0x29uLL, stderr);
return (char **)&colors_mono;
}

canonical_decompiled_code:
char **func12()
{
__int16 **v0; // r8

if ( colormode == 108 )
return colors_light;
if ( colormode > 108 )
{
v0 = &colors_mono;
if ( colormode == 109 )
return (char **)v0;
}
else
{
v0 = (__int16 **)colors_dark;
if ( colormode == 100 )
return (char **)v0;
if ( colormode == 103 )
return colors_grey;
}
fwrite("invalid color mode, falling back to mono\n", 1uLL, 0x29uLL, stderr);
return (char **)&colors_mono;
}

original_code:
static struct colors *get_colors(void)
{
 switch (colormode) {
 case 'm': return &colors_mono;
 case 'd': return &colors_dark;
 case 'l': return &colors_light;
 case 'g': return &colors_grey;
 }
 fprintf(stderr, "invalid color mode, falling back to mono\n");
 return &colors_mono;
}

canonical_original_code:
static struct colors *get_colors()
{
 switch (colormode) {
 case 'm': return &colors_mono;
 case 'd': return &colors_dark;
 case 'l': return &colors_light;
 case 'g': return &colors_grey;
 }
 fprintf(stderr, "invalid color mode, falling back to mono\n");
 return &colors_mono;
}

return_type: struct colors { char *red; char *yellow; char *green; } *