decompiled_code:
__int64 __fastcall execute_file(__int64 a1, __int64 a2)
{
__int64 v2; // rax

v2 = read_file();
return execute(v2, a2);
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, __int64 a2)
{
__int64 v2; // rax

v2 = read_file();
return execute(v2, a2);
}

original_code:
void execute_file(const struct byte_array* filename, find_c_var *find)
{
    struct byte_array *program = read_file(filename);
    execute(program, find);
}

canonical_original_code:
void execute_file(struct byte_array *filename, struct variable *(*find)(struct context *context, struct byte_array *name))
{
    struct byte_array *program = read_file(filename);
    execute(program, find);
}

user_defined_types: struct byte_array { unsigned char *data; unsigned int length; }

user_defined_types: enum VarType { VAR_NIL=0, VAR_INT=1, VAR_FLT=2, VAR_BOOL=3, VAR_STR=4, VAR_FNC=5, VAR_LST=6, VAR_MAP=7, VAR_SRC=8, VAR_ERR=9, VAR_BYT=10, VAR_C=11 }

user_defined_types: enum Visited { VISITED_NOT=0, VISITED_ONCE=1, VISITED_MORE=2, VISITED_X=3 }

user_defined_types: struct array { void **data; unsigned int current; unsigned int length; }

user_defined_types: struct hash_node { void *key; void *data; struct hash_node *next; }

user_defined_types: struct stack_node { void *data; struct stack_node *next; }


decompiled_code:
int __fastcall run_file(__int64 a1, __int64 a2)
{
__int64 v2; // rbx
__int64 v3; // rax
__int64 v4; // rax
int result; // eax

v2 = byte_array_from_string(a1);
v3 = byte_array_from_string(".fgbc");
if ( (int)byte_array_find(v2, v3, 0LL) > 0 )
return execute_file(v2, a2);
v4 = byte_array_from_string(".fg");
if ( (int)byte_array_find(v2, v4, 0LL) <= 0 )
result = puts("invalid file name");
else
result = interpret_file(v2, a2);
return result;
}

canonical_decompiled_code:
int __fastcall func4(__int64 a1, __int64 a2)
{
__int64 v2; // rbx
__int64 v3; // rax
__int64 v4; // rax
int result; // eax

v2 = byte_array_from_string(a1);
v3 = byte_array_from_string(".fgbc");
if ( (int)byte_array_find(v2, v3, 0LL) > 0 )
return func3(v2, a2);
v4 = byte_array_from_string(".fg");
if ( (int)byte_array_find(v2, v4, 0LL) <= 0 )
result = puts("invalid file name");
else
result = func2(v2, a2);
return result;
}

original_code:
void run_file(const char* str, find_c_var *find, struct map *env)
{
    struct byte_array *filename = byte_array_from_string(str);
    struct byte_array *dotfgbc = byte_array_from_string(".fgbc");
    int fgbc = byte_array_find(filename, dotfgbc, 0);
    if (fgbc > 0) {
        execute_file(filename, find);
        return;
    }
    struct byte_array *dotfg = byte_array_from_string(".fg");
    int fg = byte_array_find(filename, dotfg, 0);
    if (fg > 0)
        interpret_file(filename, find);
    else
        printf("invalid file name\n");
}

canonical_original_code:
void run_file(char *str, struct variable *(*find)(struct context *context, struct byte_array *name), struct map *env)
{
    struct byte_array *filename = byte_array_from_string(str);
    struct byte_array *dotfgbc = byte_array_from_string(".fgbc");
    int fgbc = byte_array_find(filename, dotfgbc, 0);
    if (fgbc > 0) {
        execute_file(filename, find);
        return;
    }
    struct byte_array *dotfg = byte_array_from_string(".fg");
    int fg = byte_array_find(filename, dotfg, 0);
    if (fg > 0)
        interpret_file(filename, find);
    else
        printf("invalid file name\n");
}

variable_types:
str
char *

variable_types: struct variable { enum VarType { VAR_NIL=0, VAR_INT=1, VAR_FLT=2, VAR_BOOL=3, VAR_STR=4, VAR_FNC=5, VAR_LST=6, VAR_MAP=7, VAR_SRC=8, VAR_ERR=9, VAR_BYT=10, VAR_C=11 } type; enum Visited { VISITED_NOT=0, VISITED_ONCE=1, VISITED_MORE=2, VISITED_X=3 } visited; unsigned int mark; union { struct byte_array { unsigned char *data; unsigned int length; } *str; struct array { void **data; unsigned int current; unsigned int length; } *list; int integer; float floater; _Bool boolean; struct variable *(*cfnc)(struct context { struct variable *vm_exception; struct variable *error; struct stack { struct stack_node { void *data; struct stack_node *next; } *head; struct stack_node *tail; } *program_stack; struct stack *operand_stack; struct byte_array *program; _Bool runtime; unsigned int num_vars; unsigned char indent; struct variable *(*find)(struct context *context, struct byte_array *name); } *); }; struct map { _Bool (*comparator)(void *a, void *b); unsigned long size; struct hash_node { void *key; void *data; struct hash_node *next; } **nodes; int (*hash_func)(void *x); void (*deletor)(void *x); void *(*copyor)(void *x); } *map; } *(*)(struct context *context, struct byte_array *name)

variable_types:
env
struct map *

variable_types: fgbc int

variable_types: fg int

return_type: void

user_defined_types: struct variable { enum VarType type; enum Visited visited; unsigned int mark; union { struct byte_array *str; struct array *list; int integer; float floater; _Bool boolean; struct variable *(*cfnc)(struct context *); }; struct map *map; }

user_defined_types: struct map { _Bool (*comparator)(void *a, void *b); unsigned long size; struct hash_node **nodes; int (*hash_func)(void *x); void (*deletor)(void *x); void *(*copyor)(void *x); }

user_defined_types: struct context { struct variable *vm_exception; struct variable *error; struct stack *program_stack; struct stack *operand_stack; struct byte_array *program; _Bool runtime; unsigned int num_vars; unsigned char indent; struct variable *(*find)(struct context *context, struct byte_array *name); }

user_defined_types: struct stack { struct stack_node *head; struct stack_node *tail; }


decompiled_code:
__int64 __fastcall interpret_string(__int64 a1, __int64 a2)
{
__int64 v2; // rax
__int64 v3; // rax

v2 = byte_array_from_string(a1);
v3 = build_string(v2);
return execute(v3, a2);
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1, __int64 a2)
{
__int64 v2; // rax
__int64 v3; // rax

v2 = byte_array_from_string(a1);
v3 = build_string(v2);
return execute(v3, a2);
}

original_code:
void interpret_string(const char *str, find_c_var *find)
{
    struct byte_array *input = byte_array_from_string(str);
    struct byte_array *program = build_string(input);
    execute(program, find);
}

canonical_original_code:
void interpret_string(char *str, struct variable *(*find)(struct context *context, struct byte_array *name))
{
    struct byte_array *input = byte_array_from_string(str);
    struct byte_array *program = build_string(input);
    execute(program, find);
}

variable_types: struct byte_array { unsigned char *data; unsigned int length; } *


main

canonical_name: main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
struct sigaction v4; // [rsp+0h] [rbp-158h] BYREF
struct sigaction v5; // [rsp+A0h] [rbp-B8h] BYREF

v5.sa_handler = (__sighandler_t)sig_handler;
sigemptyset(&v5.sa_mask);
v5.sa_flags = 0;
sigaction(2, &v5, &v4);
switch ( argc )
{
case 2:
run_file((__int64)argv[1], 0LL);
break;
case 3:
compile_file(argv[1]);
break;
case 1:
repl();
break;
default:
exit_message("usage: filagree [file]");
break;
}
return 0;
}

canonical_decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
struct sigaction v4; // [rsp+0h] [rbp-158h] BYREF
struct sigaction v5; // [rsp+A0h] [rbp-B8h] BYREF

v5.sa_handler = (__sighandler_t)sig_handler;
sigemptyset(&v5.sa_mask);
v5.sa_flags = 0;
sigaction(2, &v5, &v4);
switch ( argc )
{
case 2:
func4((__int64)argv[1], 0LL);
break;
case 3:
compile_file(argv[1]);
break;
case 1:
func1();
break;
default:
exit_message("usage: filagree [file]");
break;
}
return 0;
}

original_code:
int main (int argc, char** argv)
{
 struct sigaction act, oact;
 act.__sigaction_handler.sa_handler = sig_handler;
 sigemptyset(&act.sa_mask);
 act.sa_flags = 0;
 sigaction(2, &act, &oact);
    switch (argc) {
        case 1: repl(); break;
        case 2: run_file(argv[1], ((void *)0), ((void *)0)); break;
        case 3: compile_file(argv[1]); break;
        default: exit_message("usage: filagree [file]"); break;
    }
}

canonical_original_code:
int main(int argc, char **argv)
{
 struct sigaction act; struct sigaction oact;
 act.__sigaction_handler.sa_handler = sig_handler;
 sigemptyset(&act.sa_mask);
 act.sa_flags = 0;
 sigaction(2, &act, &oact);
    switch (argc) {
        case 1: repl(); break;
        case 2: run_file(argv[1], ((void *)0), ((void *)0)); break;
        case 3: compile_file(argv[1]); break;
        default: exit_message("usage: filagree [file]"); break;
    }
}

variable_types: argc int

variable_types:
argv
char **

variable_types: struct sigaction { union { void (*sa_handler)(int); void (*sa_sigaction)(int, struct siginfo_t { int si_signo; int si_errno; int si_code; int __pad0; union { int _pad[-1]; struct { int si_pid; unsigned int si_uid; } _kill; struct { int si_tid; int si_overrun; union sigval { int sival_int; void *sival_ptr; } si_sigval; } _timer; struct { int si_pid; unsigned int si_uid; union sigval si_sigval; } _rt; struct { int si_pid; unsigned int si_uid; int si_status; long si_utime; long si_stime; } _sigchld; struct { void *si_addr; short si_addr_lsb; union { struct { void *_lower; void *_upper; } _addr_bnd; unsigned int _pkey; } _bounds; } _sigfault; struct { long si_band; int si_fd; } _sigpoll; struct { void *_call_addr; int _syscall; unsigned int _arch; } _sigsys; } _sifields; } *, void *); } __sigaction_handler; struct __sigset_t { unsigned long __val[-1]; } sa_mask; int sa_flags; void (*sa_restorer)(); }

return_type: int

user_defined_types: struct sigaction { union { void (*sa_handler)(int); void (*sa_sigaction)(int, struct siginfo_t *, void *); } __sigaction_handler; struct __sigset_t sa_mask; int sa_flags; void (*sa_restorer)(); }

user_defined_types: struct siginfo_t { int si_signo; int si_errno; int si_code; int __pad0; union { int _pad[-1]; struct { int si_pid; unsigned int si_uid; } _kill; struct { int si_tid; int si_overrun; union sigval si_sigval; } _timer; struct { int si_pid; unsigned int si_uid; union sigval si_sigval; } _rt; struct { int si_pid; unsigned int si_uid; int si_status; long si_utime; long si_stime; } _sigchld; struct { void *si_addr; short si_addr_lsb; union { struct { void *_lower; void *_upper; } _addr_bnd; unsigned int _pkey; } _bounds; } _sigfault; struct { long si_band; int si_fd; } _sigpoll; struct { void *_call_addr; int _syscall; unsigned int _arch; } _sigsys; } _sifields; }


xstrnlen

decompiled_code:
__int64 __fastcall xstrnlen(__int64 a1, __int64 a2)
{
__int64 result; // rax

result = 0LL;
if ( !a2 )
return 0LL;
do
{
if ( !*(_BYTE *)(a1 + result) )
break;
++result;
}
while ( a2 != result );
return result;
}

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

result = 0LL;
if ( !a2 )
return 0LL;
do
{
if ( !*(_BYTE *)(a1 + result) )
break;
++result;
}
while ( a2 != result );
return result;
}

original_code:
size_t xstrnlen(char *s, size_t maxlen)
{
 size_t i;
 for (i= 0; i<maxlen && *s; i++, s++);
 return i;
}

canonical_original_code:
unsigned long xstrnlen(char *s, unsigned long maxlen)
{
 unsigned long i;
 for (i= 0; i<maxlen && *s; i++, s++);
 return i;
}

variable_types:
s
char *

variable_types:
maxlen
unsigned long

variable_types:
i
unsigned long

return_type: unsigned long


strnstr

decompiled_code:
const char *__fastcall strnstr(const char *a1, char *a2, __int64 a3)
{
char v4; // r12
size_t v6; // r15
size_t v7; // rbp
const char *v8; // r14
char v9; // al

v4 = *a2;
if ( *a2 )
{
v6 = strlen(a2 + 1);
v7 = a3 - 1;
if ( a3 )
{
while ( 1 )
{
v8 = a1++;
v9 = *(a1 - 1);
if ( !v9 )
return 0LL;
if ( v4 == v9 )
{
if ( v6 > v7 )
return 0LL;
if ( !strncmp(a1, a2 + 1, v6) )
return v8;
}
if ( --v7 == -1LL )
return 0LL;
}
}
a1 = 0LL;
}
return a1;
}

canonical_decompiled_code:
const char *__fastcall func1(const char *a1, char *a2, __int64 a3)
{
char v4; // r12
size_t v6; // r15
size_t v7; // rbp
const char *v8; // r14
char v9; // al

v4 = *a2;
if ( *a2 )
{
v6 = strlen(a2 + 1);
v7 = a3 - 1;
if ( a3 )
{
while ( 1 )
{
v8 = a1++;
v9 = *(a1 - 1);
if ( !v9 )
return 0LL;
if ( v4 == v9 )
{
if ( v6 > v7 )
return 0LL;
if ( !strncmp(a1, a2 + 1, v6) )
return v8;
}
if ( --v7 == -1LL )
return 0LL;
}
}
a1 = 0LL;
}
return a1;
}

original_code:
char *strnstr(const char *s, const char *find, size_t slen)
{
 char c, sc;
 size_t len;
 if ((c = *find++) != '\0') {
  len = strlen(find);
  do {
   do {
    if (slen-- < 1 || (sc = *s++) == '\0')
     return (((void *)0));
   } while (sc != c);
   if (len > slen)
    return (((void *)0));
  } while (strncmp(s, find, len) != 0);
  s--;
 }
 return ((char *)s);
}

canonical_original_code:
char *strnstr(char *s, char *find, unsigned long slen)
{
 char c; char sc;
 unsigned long len;
 if ((c = *find++) != '\0') {
  len = strlen(find);
  do {
   do {
    if (slen-- < 1 || (sc = *s++) == '\0')
     return (((void *)0));
   } while (sc != c);
   if (len > slen)
    return (((void *)0));
  } while (strncmp(s, find, len) != 0);
  s--;
 }
 return ((char *)s);
}

variable_types:
find
char *

variable_types:
slen
unsigned long

variable_types: c char

variable_types: sc char

variable_types:
len
unsigned long

return_type: char *


decompiled_code:
char *__fastcall make_message(char *format, __gnuc_va_list arg)
{
vsnprintf(message_0, 0x64uLL, format, arg);
return message_0;
}

canonical_decompiled_code:
char *__fastcall func2(char *format, __gnuc_va_list arg)
{
vsnprintf(message_0, 0x64uLL, format, arg);
return message_0;
}

original_code:
const char *make_message(const char *format, va_list ap)
{
    static char message[100];
    vsnprintf(message, 100, format, ap);
    return message;
}

canonical_original_code:
char *make_message(char *format, __builtin_va_list ap)
{
    static char message[100];
    vsnprintf(message, 100, format, ap);
    return message;
}

variable_types:
format
char *

variable_types:
message
char [100]


decompiled_code:
_BYTE *log_print(char *a1, ...)
{
char *v1; // rbx
size_t v2; // rax
size_t v3; // rbp
_BYTE *result; // rax
_BYTE *v5; // rbx
signed __int64 v6; // r12
gcc_va_list arg; // [rsp+8h] [rbp-150h] BYREF
char dest[112]; // [rsp+20h] [rbp-138h] BYREF

va_start(arg, a1);
v1 = make_message(a1, arg);
v2 = strnlen(log_message_1, 0x64uLL);
strncat(log_message_1, v1, 100 - v2);
v3 = strnlen(log_message_1, 0x64uLL);
if ( v3 == 100 )
byte_763 = 10;
result = strnstr(log_message_1, "\n", 100LL);
v5 = result;
if ( result )
{
v6 = result - log_message_1;
memcpy(dest, log_message_1, result - log_message_1);
dest[v6] = 0;
puts(dest);
result = memmove(log_message_1, v5 + 1, v3 - v6);
}
return result;
}

canonical_decompiled_code:
_BYTE *func3(char *a1, ...)
{
char *v1; // rbx
size_t v2; // rax
size_t v3; // rbp
_BYTE *result; // rax
_BYTE *v5; // rbx
signed __int64 v6; // r12
gcc_va_list arg; // [rsp+8h] [rbp-150h] BYREF
char dest[112]; // [rsp+20h] [rbp-138h] BYREF

va_start(arg, a1);
v1 = func2(a1, arg);
v2 = strnlen(log_message_1, 0x64uLL);
strncat(log_message_1, v1, 100 - v2);
v3 = strnlen(log_message_1, 0x64uLL);
if ( v3 == 100 )
byte_763 = 10;
result = func1(log_message_1, "\n", 100LL);
v5 = result;
if ( result )
{
v6 = result - log_message_1;
memcpy(dest, log_message_1, result - log_message_1);
dest[v6] = 0;
puts(dest);
result = memmove(log_message_1, v5 + 1, v3 - v6);
}
return result;
}

original_code:
void log_print(const char *format, ...)
{
    static char log_message[100 +1] = "";
    char one_line[100];
    char *newline;
    va_list list;
    __builtin_va_start(list,format);
    const char *message = make_message(format, list);
    __builtin_va_end(list);
    size_t log_len = strnlen(log_message, 100);
    strncat(log_message, message, 100 - log_len);
    log_len = strnlen(log_message, 100);
    if (log_len == 100)
        log_message[100 -1] = '\n';
    if (!(newline = strnstr(log_message, "\n", 100)))
        return;
    size_t line_len = newline - log_message;
    memcpy(one_line, log_message, line_len);
    one_line[line_len] = 0;
    printf("%s\n", one_line);
    memmove(log_message, newline+1, log_len-line_len);
}

canonical_original_code:
void log_print(char *format, ...)
{
    static char log_message[-1] = "";
    char one_line[100];
    char *newline;
    __builtin_va_list list;
    __builtin_va_start(list,format);
    char *message = make_message(format, list);
    __builtin_va_end(list);
    unsigned long log_len = strnlen(log_message, 100);
    strncat(log_message, message, 100 - log_len);
    log_len = strnlen(log_message, 100);
    if (log_len == 100)
        log_message[100 -1] = '\n';
    if (!(newline = strnstr(log_message, "\n", 100)))
        return;
    unsigned long line_len = newline - log_message;
    memcpy(one_line, log_message, line_len);
    one_line[line_len] = 0;
    printf("%s\n", one_line);
    memmove(log_message, newline+1, log_len-line_len);
}

variable_types:
newline
char *

variable_types:
message
char *


decompiled_code:
void __fastcall __noreturn exit_message2(char *a1, void *a2)
{
char *v2; // rax

v2 = make_message(a1, a2);
log_print("\n%s\n", v2);
exit(1);
}

canonical_decompiled_code:
void __fastcall __noreturn func4(char *a1, void *a2)
{
char *v2; // rax

v2 = func2(a1, a2);
func3("\n%s\n", v2);
exit(1);
}

original_code:
void exit_message2(const char *format, va_list list)
{
    const char *message = make_message(format, list);
    log_print("\n%s\n", message);
    __builtin_va_end(list);
    exit(1);
}

canonical_original_code:
void exit_message2(char *format, __builtin_va_list list)
{
    char *message = make_message(format, list);
    log_print("\n%s\n", message);
    __builtin_va_end(list);
    exit(1);
}


decompiled_code:
void assert_message(char a1, char *a2, ...)
{
gcc_va_list va; // [rsp+8h] [rbp-D0h] BYREF

if ( !a1 )
{
va_start(va, a2);
exit_message2(a2, va);
}
}

canonical_decompiled_code:
void func5(char a1, char *a2, ...)
{
gcc_va_list va; // [rsp+8h] [rbp-D0h] BYREF

if ( !a1 )
{
va_start(va, a2);
func4(a2, va);
}
}

original_code:
void assert_message(_Bool assertion, const char *format, ...)
{
    if (assertion)
        return;
    va_list list;
    __builtin_va_start(list,format);
    exit_message2(format, list);
}

canonical_original_code:
void assert_message(_Bool assertion, char *format, ...)
{
    if (assertion)
        return;
    __builtin_va_list list;
    __builtin_va_start(list,format);
    exit_message2(format, list);
}


decompiled_code:
void __noreturn exit_message(char *a1, ...)
{
gcc_va_list va; // [rsp+8h] [rbp-D0h] BYREF

va_start(va, a1);
exit_message2(a1, va);
}

canonical_decompiled_code:
void __noreturn func6(char *a1, ...)
{
gcc_va_list va; // [rsp+8h] [rbp-D0h] BYREF

va_start(va, a1);
func4(a1, va);
}

original_code:
void *exit_message(const char *format, ...)
{
    va_list list;
    __builtin_va_start(list,format);
    exit_message2(format, list);
    return ((void *)0);
}

canonical_original_code:
void *exit_message(char *format, ...)
{
    __builtin_va_list list;
    __builtin_va_start(list,format);
    exit_message2(format, list);
    return ((void *)0);
}

return_type: void *


decompiled_code:
void __fastcall null_check(__int64 a1)
{
if ( !a1 )
exit_message("null pointer");
}

canonical_decompiled_code:
void __fastcall func7(__int64 a1)
{
if ( !a1 )
func6("null pointer");
}

original_code:
void null_check(const void *pointer) {
    if (!pointer)
        exit_message("null pointer");
}

canonical_original_code:
void null_check(void *pointer) {
    if (!pointer)
        exit_message("null pointer");
}

variable_types:
pointer
void *


decompiled_code:
__int64 __fastcall num_to_string(unsigned __int8 *a1, int a2, int a3)
{
unsigned __int8 *v3; // rax
__int64 v4; // rdi

if ( a2 <= 0 )
LABEL_5:
exit_message("num not found");
v3 = a1;
v4 = (__int64)&a1[16 * (a2 - 1) + 16];
while ( *v3 != a3 )
{
v3 += 16;
if ( v3 == (unsigned __int8 *)v4 )
goto LABEL_5;
}
return *((_QWORD *)v3 + 1);
}

canonical_decompiled_code:
__int64 __fastcall func8(unsigned __int8 *a1, int a2, int a3)
{
unsigned __int8 *v3; // rax
__int64 v4; // rdi

if ( a2 <= 0 )
LABEL_5:
func6("num not found");
v3 = a1;
v4 = (__int64)&a1[16 * (a2 - 1) + 16];
while ( *v3 != a3 )
{
v3 += 16;
if ( v3 == (unsigned __int8 *)v4 )
goto LABEL_5;
}
return *((_QWORD *)v3 + 1);
}

original_code:
const char* num_to_string(const struct number_string *ns, int num_items, int num)
{
    for (int i=0; i<num_items; i++)
        if (num == ns[i].number)
            return ns[i].chars;
    exit_message("num not found");
    return ((void *)0);
}

canonical_original_code:
char *num_to_string(struct number_string *ns, int num_items, int num)
{
    for (int i = 0; i<num_items; i++)
        if (num == ns[i].number)
            return ns[i].chars;
    exit_message("num not found");
    return ((void *)0);
}

variable_types: struct number_string { unsigned char number; char *chars; } *

variable_types: num int

variable_types: i int


decompiled_code:
char *__fastcall build_path(const char *a1, const char *a2)
{
const char *v2; // rbx
int v3; // er13
size_t v4; // rax
char *v5; // rbp
const char *v6; // rcx
size_t v8; // rax

if ( a1 )
{
v2 = a1;
v3 = strlen(a1);
v4 = strlen(a2);
v5 = (char *)malloc(v4 + v3 + 1);
v6 = (const char *)&unk_83F;
if ( v3 && a1[v3] != 47 )
v6 = "/";
}
else
{
v8 = strlen(a2);
v5 = (char *)malloc(v8 + 1);
v6 = (const char *)&unk_83F;
v2 = (const char *)&unk_83F;
}
sprintf(v5, "%s%s%s", v2, v6, a2);
return v5;
}

canonical_decompiled_code:
char *__fastcall func13(const char *a1, const char *a2)
{
const char *v2; // rbx
int v3; // er13
size_t v4; // rax
char *v5; // rbp
const char *v6; // rcx
size_t v8; // rax

if ( a1 )
{
v2 = a1;
v3 = strlen(a1);
v4 = strlen(a2);
v5 = (char *)malloc(v4 + v3 + 1);
v6 = (const char *)&unk_83F;
if ( v3 && a1[v3] != 47 )
v6 = "/";
}
else
{
v8 = strlen(a2);
v5 = (char *)malloc(v8 + 1);
v6 = (const char *)&unk_83F;
v2 = (const char *)&unk_83F;
}
sprintf(v5, "%s%s%s", v2, v6, a2);
return v5;
}

original_code:
char* build_path(const char* dir, const char* name)
{
    int dirlen = dir ? strlen(dir) : 0;
    char* path = (char*)malloc(dirlen + 1 + strlen(name));
    const char* slash = (dir && dirlen && (dir[dirlen] != '/')) ? "/" : "";
    sprintf(path, "%s%s%s", dir ? dir : "", slash, name);
    return path;
}

canonical_original_code:
char *build_path(char *dir, char *name)
{
    int dirlen = dir ? strlen(dir) : 0;
    char *path = (char*)malloc(dirlen + 1 + strlen(name));
    char *slash = (dir && dirlen && (dir[dirlen] != '/')) ? "/" : "";
    sprintf(path, "%s%s%s", dir ? dir : "", slash, name);
    return path;
}

variable_types:
dir
char *

variable_types:
name
char *

variable_types: dirlen int

variable_types:
path
char *

variable_types:
slash
char *


decompiled_code:
__int64 __fastcall encode_int_size(int a1)
{
int v1; // edi
__int64 result; // rax

v1 = (int)abs32(a1) >> 6;
if ( !v1 )
return 1LL;
LODWORD(result) = 1;
do
{
result = (unsigned int)(result + 1);
v1 >>= 7;
}
while ( v1 );
return result;
}

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

v1 = (int)abs32(a1) >> 6;
if ( !v1 )
return 1LL;
LODWORD(result) = 1;
do
{
result = (unsigned int)(result + 1);
v1 >>= 7;
}
while ( v1 );
return result;
}

original_code:
uint8_t encode_int_size(int32_t value)
{
    uint8_t i;
    value = (value >= 0 ? value : -value) >> 6;
    for (i=1; value; i++, value >>=7);
    return i;
}

canonical_original_code:
unsigned char encode_int_size(int value)
{
    unsigned char i;
    value = (value >= 0 ? value : -value) >> 6;
    for (i=1; value; i++, value >>=7);
    return i;
}

variable_types: value int

variable_types:
i
unsigned char

return_type: unsigned char


original_code:
struct byte_array *encode_int(struct byte_array *buf, int32_t value)
{
    if (!buf)
  buf = byte_array_new();
    uint8_t growth = encode_int_size(value);
    byte_array_resize(buf, buf->length + growth);
    _Bool neg = value < 0;
    value = abs(value);
    uint8_t byte = (value & 0x3F) | ((value >= 0x40) ? 0x80 : 0) | (neg ? 0x40 : 0);
    *buf->current++ = byte;
    value >>= 6;
    while (value) {
        byte = (value & 0x7F) | ((value >= 0x80) ? 0x80 : 0);
        *buf->current++ = byte;
        value >>= 7;
    }
    return buf;
}

canonical_original_code:
struct byte_array *encode_int(struct byte_array *buf, int value)
{
    if (!buf)
  buf = byte_array_new();
    unsigned char growth = encode_int_size(value);
    byte_array_resize(buf, buf->length + growth);
    _Bool neg = value < 0;
    value = abs(value);
    unsigned char byte = (value & 0x3F) | ((value >= 0x40) ? 0x80 : 0) | (neg ? 0x40 : 0);
    *buf->current++ = byte;
    value >>= 6;
    while (value) {
        byte = (value & 0x7F) | ((value >= 0x80) ? 0x80 : 0);
        *buf->current++ = byte;
        value >>= 7;
    }
    return buf;
}

variable_types:
buf
struct byte_array *

variable_types:
growth
unsigned char

variable_types:
byte
unsigned char

return_type: struct byte_array { unsigned char *data; unsigned int length; } *


decompiled_code:
__int64 __fastcall serial_encode_int(__int64 a1, int a2)
{
__int64 v2; // rbx

v2 = a1;
if ( !a1 )
v2 = byte_array_new();
encode_int(v2, a2);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, int a2)
{
__int64 v2; // rbx

v2 = a1;
if ( !a1 )
v2 = byte_array_new();
func1(v2, a2);
return v2;
}

original_code:
struct byte_array* serial_encode_int(struct byte_array* buf, int32_t value) {
    if (!buf)
        buf = byte_array_new();
    encode_int(buf, value);
    return buf;
}

canonical_original_code:
struct byte_array *serial_encode_int(struct byte_array *buf, int value) {
    if (!buf)
        buf = byte_array_new();
    encode_int(buf, value);
    return buf;
}


original_code:
int32_t serial_decode_int(struct byte_array* buf)
{
    _Bool neg = *buf->current & 0x40;
    int32_t ret = *buf->current & 0x3F;
    int bitpos = 6;
    while ((*buf->current++ & 0x80) && (bitpos < (sizeof(int32_t)*8))) {
        ret |= (*buf->current & 0x7F) << bitpos;
        bitpos += 7;
    }
    return neg ? -ret : ret;
}

canonical_original_code:
int serial_decode_int(struct byte_array *buf)
{
    _Bool neg = *buf->current & 0x40;
    int ret = *buf->current & 0x3F;
    int bitpos = 6;
    while ((*buf->current++ & 0x80) && (bitpos < (sizeof(int)*8))) {
        ret |= (*buf->current & 0x7F) << bitpos;
        bitpos += 7;
    }
    return neg ? -ret : ret;
}

variable_types: struct byte_array { unsigned char *data; unsigned int length; } *

variable_types: ret int

variable_types: bitpos int


decompiled_code:
float __fastcall serial_decode_float(__int64 a1)
{
void **v1; // rdx
_BYTE *v2; // rax
float v4; // [rsp+0h] [rbp-4h] BYREF
void *retaddr; // [rsp+4h] [rbp+0h] BYREF

v1 = (void **)&v4;
do
{
v2 = *(_BYTE **)(a1 + 8);
*(_BYTE *)v1 = *v2;
v1 = (void **)((char *)v1 + 1);
*(_QWORD *)(a1 + 8) = v2 + 1;
}
while ( v1 != &retaddr );
return v4;
}

canonical_decompiled_code:
float __fastcall func4(__int64 a1)
{
void **v1; // rdx
_BYTE *v2; // rax
float v4; // [rsp+0h] [rbp-4h] BYREF
void *retaddr; // [rsp+4h] [rbp+0h] BYREF

v1 = (void **)&v4;
do
{
v2 = *(_BYTE **)(a1 + 8);
*(_BYTE *)v1 = *v2;
v1 = (void **)((char *)v1 + 1);
*(_QWORD *)(a1 + 8) = v2 + 1;
}
while ( v1 != &retaddr );
return v4;
}

original_code:
float serial_decode_float(struct byte_array* buf)
{
    float f;
    uint8_t *uf = (uint8_t*)&f;
    for (int i=4; i; i--) {
        *uf = *buf->current;
        uf++;
        buf->current++;
    }
    return f;
}

canonical_original_code:
float serial_decode_float(struct byte_array *buf)
{
    float f;
    unsigned char *uf = (uint8_t*)&f;
    for (int i = 4; i; i--) {
        *uf = *buf->current;
        uf++;
        buf->current++;
    }
    return f;
}

variable_types: f float

variable_types:
uf
unsigned char *

return_type: float


decompiled_code:
__int64 __fastcall serial_decode_string(__int64 a1)
{
unsigned int v1; // ebx
__int64 v2; // r12
void *v3; // rax

((void (*)(void))null_check)();
v1 = serial_decode_int(a1);
assert_message((v1 & 0x80000000) == 0, "negative malloc");
v2 = byte_array_new_size(v1);
v3 = malloc((int)v1);
*(_QWORD *)(v2 + 8) = v3;
*(_QWORD *)v2 = v3;
null_check(v3);
memcpy(*(void **)v2, *(const void **)(a1 + 8), (int)v1);
*(_QWORD *)(a1 + 8) += (int)v1;
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func5(__int64 a1)
{
unsigned int v1; // ebx
__int64 v2; // r12
void *v3; // rax

((void (*)(void))null_check)();
v1 = func3(a1);
assert_message((v1 & 0x80000000) == 0, "negative malloc");
v2 = byte_array_new_size(v1);
v3 = malloc((int)v1);
*(_QWORD *)(v2 + 8) = v3;
*(_QWORD *)v2 = v3;
null_check(v3);
memcpy(*(void **)v2, *(const void **)(a1 + 8), (int)v1);
*(_QWORD *)(a1 + 8) += (int)v1;
return v2;
}

original_code:
struct byte_array* serial_decode_string(struct byte_array* buf)
{
 null_check(buf);
    int32_t len = serial_decode_int(buf);
 assert_message(len>=0, "negative malloc");
    struct byte_array* ba = byte_array_new_size(len);
    ba->data = ba->current = (uint8_t*)malloc(len);
 null_check(ba->data);
    memcpy(ba->data, buf->current, len);
    buf->current += len;
    return ba;
}

canonical_original_code:
struct byte_array *serial_decode_string(struct byte_array *buf)
{
 null_check(buf);
    int len = serial_decode_int(buf);
 assert_message(len>=0, "negative malloc");
    struct byte_array *ba = byte_array_new_size(len);
    ba->data = ba->current = (unsigned char *)malloc(len);
 null_check(ba->data);
    memcpy(ba->data, buf->current, len);
    buf->current += len;
    return ba;
}

variable_types: len int


decompiled_code:
unsigned __int64 __fastcall serial_decode(__int64 a1, __int64 (__fastcall *a2)(int *, __int64, __int64), __int64 a3)
{
unsigned __int64 result; // rax
int v5; // eax
int v6; // eax
int v7[2]; // [rsp+0h] [rbp-28h] BYREF
__int64 v8; // [rsp+8h] [rbp-20h]

result = *(_QWORD *)a1 + *(unsigned int *)(a1 + 16);
if ( *(_QWORD *)(a1 + 8) < result )
{
while ( 1 )
{
v5 = serial_decode_int(a1);
v8 = 0LL;
v7[0] = v5 >> 2;
v6 = v5 & 3;
v7[1] = v6;
if ( v6 == 3 )
goto LABEL_4;
if ( v6 == 1 )
{
LODWORD(v8) = serial_decode_int(a1);
goto LABEL_5;
}
if ( v6 == 2 )
break;
log_print("serial_decode ?\n");
LABEL_5:
result = a2(v7, a1, a3);
if ( !(_BYTE)result )
{
result = *(_QWORD *)a1 + *(unsigned int *)(a1 + 16);
if ( *(_QWORD *)(a1 + 8) < result )
continue;
}
return result;
}
LODWORD(v8) = serial_decode_float(a1);
LABEL_4:
v8 = serial_decode_string(a1);
goto LABEL_5;
}
return result;
}

canonical_decompiled_code:
unsigned __int64 __fastcall func6(__int64 a1, __int64 (__fastcall *a2)(int *, __int64, __int64), __int64 a3)
{
unsigned __int64 result; // rax
int v5; // eax
int v6; // eax
int v7[2]; // [rsp+0h] [rbp-28h] BYREF
__int64 v8; // [rsp+8h] [rbp-20h]

result = *(_QWORD *)a1 + *(unsigned int *)(a1 + 16);
if ( *(_QWORD *)(a1 + 8) < result )
{
while ( 1 )
{
v5 = func3(a1);
v8 = 0LL;
v7[0] = v5 >> 2;
v6 = v5 & 3;
v7[1] = v6;
if ( v6 == 3 )
goto LABEL_4;
if ( v6 == 1 )
{
LODWORD(v8) = func3(a1);
goto LABEL_5;
}
if ( v6 == 2 )
break;
log_print("serial_decode ?\n");
LABEL_5:
result = a2(v7, a1, a3);
if ( !(_BYTE)result )
{
result = *(_QWORD *)a1 + *(unsigned int *)(a1 + 16);
if ( *(_QWORD *)(a1 + 8) < result )
continue;
}
return result;
}
LODWORD(v8) = func4(a1);
LABEL_4:
v8 = func5(a1);
goto LABEL_5;
}
return result;
}

original_code:
void serial_decode(struct byte_array* buf, serial_element se, const void* extra)
{
    while (buf->current < buf->data + buf->length)
    {
        int32_t keyWire = serial_decode_int(buf);
        struct key_value_pair pair = {
            .key = keyWire >> 2,
            .wire_type = (enum serial_type)(keyWire & 0x03)
        };
        switch(pair.wire_type) {
            case SERIAL_INT:
                pair.value.integer = serial_decode_int(buf);
                break;
            case SERIAL_FLOAT:
                pair.value.floater = serial_decode_float(buf);
            case SERIAL_STRING:
                pair.value.bytes = serial_decode_string(buf);
                break;
            case SERIAL_ARRAY:
                break;
            default:
                log_print( "serial_decode ?\n" );;
                break;
        }
        if (se(&pair, buf, extra)) {
            break;
        }
    }
}

canonical_original_code:
void serial_decode(struct byte_array *buf, _Bool se(struct key_value_pair *, struct byte_array *bytes, void *extra), void *extra)
{
    while (buf->current < buf->data + buf->length)
    {
        int keyWire = serial_decode_int(buf);
        struct key_value_pair pair = {
            .key = keyWire >> 2,
            .wire_type = (enum serial_type)(keyWire & 0x03)
        };
        switch(pair.wire_type) {
            case SERIAL_INT:
                pair.value.integer = serial_decode_int(buf);
                break;
            case SERIAL_FLOAT:
                pair.value.floater = serial_decode_float(buf);
            case SERIAL_STRING:
                pair.value.bytes = serial_decode_string(buf);
                break;
            case SERIAL_ARRAY:
                break;
            default:
                log_print( "serial_decode ?\n" );;
                break;
        }
        if (se(&pair, buf, extra)) {
            break;
        }
    }
}

variable_types: _Bool (struct key_value_pair { int key; enum serial_type { SERIAL_ERROR=0, SERIAL_INT=1, SERIAL_FLOAT=2, SERIAL_STRING=3, SERIAL_ARRAY=4 } wire_type; union { int integer; float floater; struct byte_array *bytes; enum { SOMETHING_HAS_GONE_HORRIBLY_WRONG=0 } serialError; } value; } *, struct byte_array *bytes, void *extra)

variable_types:
extra
void *

variable_types: keyWire int

variable_types: struct key_value_pair { int key; enum serial_type { SERIAL_ERROR=0, SERIAL_INT=1, SERIAL_FLOAT=2, SERIAL_STRING=3, SERIAL_ARRAY=4 } wire_type; union { int integer; float floater; struct byte_array { unsigned char *data; unsigned int length; } *bytes; enum { SOMETHING_HAS_GONE_HORRIBLY_WRONG=0 } serialError; } value; }

user_defined_types: struct key_value_pair { int key; enum serial_type wire_type; union { int integer; float floater; struct byte_array *bytes; enum { SOMETHING_HAS_GONE_HORRIBLY_WRONG=0 } serialError; } value; }


decompiled_code:
__int64 __fastcall encode_float(__int64 a1, float a2)
{
char *v2; // rbx
float v4; // [rsp+Ch] [rbp-1Ch] BYREF
char v5; // [rsp+10h] [rbp-18h] BYREF

v4 = a2;
assert_message(1LL, "bad float size");
v2 = (char *)&v4;
do
byte_array_add_byte(a1, (unsigned __int8)*v2++);
while ( v2 != &v5 );
return a1;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, float a2)
{
char *v2; // rbx
float v4; // [rsp+Ch] [rbp-1Ch] BYREF
char v5; // [rsp+10h] [rbp-18h] BYREF

v4 = a2;
assert_message(1LL, "bad float size");
v2 = (char *)&v4;
do
byte_array_add_byte(a1, (unsigned __int8)*v2++);
while ( v2 != &v5 );
return a1;
}

original_code:
struct byte_array *encode_float(struct byte_array *buf, float f)
{
    assert_message(sizeof(float)==4, "bad float size");
    uint8_t *uf = (uint8_t*)&f;
    for (int i=4; i; i--) {
        byte_array_add_byte(buf, *uf);
        uf++;
    }
    return buf;
}

canonical_original_code:
struct byte_array *encode_float(struct byte_array *buf, float f)
{
    assert_message(sizeof(float)==4, "bad float size");
    unsigned char *uf = (uint8_t*)&f;
    for (int i = 4; i; i--) {
        byte_array_add_byte(buf, *uf);
        uf++;
    }
    return buf;
}

variable_types: i int


decompiled_code:
__int64 __fastcall serial_encode_float(__int64 a1, float a2)
{
__int64 v2; // rbx

v2 = a1;
if ( !a1 )
v2 = byte_array_new();
encode_float(v2, a2);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func8(__int64 a1, float a2)
{
__int64 v2; // rbx

v2 = a1;
if ( !a1 )
v2 = byte_array_new();
func7(v2, a2);
return v2;
}

original_code:
struct byte_array* serial_encode_float(struct byte_array* buf, float value) {
    if (!buf)
        buf = byte_array_new();
    encode_float(buf, value);
    return buf;
}

canonical_original_code:
struct byte_array *serial_encode_float(struct byte_array *buf, float value) {
    if (!buf)
        buf = byte_array_new();
    encode_float(buf, value);
    return buf;
}

variable_types: value float


decompiled_code:
__int64 __fastcall serial_encode_string_size(int a1, __int64 a2)
{
int v2; // ebp
int v3; // ebx

if ( !a2 )
return 0LL;
v2 = 0;
if ( a1 )
v2 = encode_int_size(a1);
v3 = *(_DWORD *)(a2 + 16);
return v3 + v2 + (unsigned int)encode_int_size(v3);
}

canonical_decompiled_code:
__int64 __fastcall func9(int a1, __int64 a2)
{
int v2; // ebp
int v3; // ebx

if ( !a2 )
return 0LL;
v2 = 0;
if ( a1 )
v2 = func0(a1);
v3 = *(_DWORD *)(a2 + 16);
return v3 + v2 + (unsigned int)func0(v3);
}

original_code:
uint8_t serial_encode_string_size(int32_t key, const struct byte_array* string) {
    if (!string)
        return 0;
    return (key ? encode_int_size(key) : 0) +
           encode_int_size(string->length) +
           string->length;
}

canonical_original_code:
unsigned char serial_encode_string_size(int key, struct byte_array *string) {
    if (!string)
        return 0;
    return (key ? encode_int_size(key) : 0) +
           encode_int_size(string->length) +
           string->length;
}

variable_types: key int


decompiled_code:
__int64 __fastcall serial_encode_string(__int64 a1, __int64 a2)
{
__int64 v2; // rbx

v2 = a1;
if ( !a2 )
return a1;
if ( !a1 )
v2 = byte_array_new();
encode_int(v2, *(_DWORD *)(a2 + 16));
byte_array_resize(v2, (unsigned int)(*(_DWORD *)(v2 + 16) + *(_DWORD *)(a2 + 16)));
memcpy(*(void **)(v2 + 8), *(const void **)a2, *(unsigned int *)(a2 + 16));
*(_QWORD *)(v2 + 8) = *(_QWORD *)v2 + *(unsigned int *)(v2 + 16);
return v2;
}

canonical_decompiled_code:
__int64 __fastcall func10(__int64 a1, __int64 a2)
{
__int64 v2; // rbx

v2 = a1;
if ( !a2 )
return a1;
if ( !a1 )
v2 = byte_array_new();
func1(v2, *(_DWORD *)(a2 + 16));
byte_array_resize(v2, (unsigned int)(*(_DWORD *)(v2 + 16) + *(_DWORD *)(a2 + 16)));
memcpy(*(void **)(v2 + 8), *(const void **)a2, *(unsigned int *)(a2 + 16));
*(_QWORD *)(v2 + 8) = *(_QWORD *)v2 + *(unsigned int *)(v2 + 16);
return v2;
}

original_code:
struct byte_array* serial_encode_string(struct byte_array* buf, const struct byte_array* bytes)
{
    if (!bytes)
        return buf;
    if (!buf)
        buf = byte_array_new();
    encode_int(buf, bytes->length);
    byte_array_resize(buf, buf->length + bytes->length);
    memcpy(buf->current, bytes->data, bytes->length);
    buf->current = buf->data + buf->length;
    return buf;
}

canonical_original_code:
struct byte_array *serial_encode_string(struct byte_array *buf, struct byte_array *bytes)
{
    if (!bytes)
        return buf;
    if (!buf)
        buf = byte_array_new();
    encode_int(buf, bytes->length);
    byte_array_resize(buf, buf->length + bytes->length);
    memcpy(buf->current, bytes->data, bytes->length);
    buf->current = buf->data + buf->length;
    return buf;
}

variable_types:
bytes
struct byte_array *


decompiled_code:
__int64 __fastcall display_serial(unsigned int *a1)
{
__int64 v1; // r12
unsigned int v2; // ebp
void *v3; // rbx

log_print("serialElementDebug %d:\t", *a1);
switch ( a1[1] )
{
case 0u:
log_print("error %d\n", a1[2]);
break;
case 1u:
log_print("int %d\n", a1[2]);
break;
case 2u:
log_print("float %f\n", *((float *)a1 + 2));
goto LABEL_5;
case 3u:
LABEL_5:
v1 = *((_QWORD *)a1 + 1);
v2 = *(_DWORD *)(v1 + 16);
v3 = malloc(v2 + 1);
memcpy(v3, *(const void **)v1, v2);
*((_BYTE *)v3 + *(unsigned int *)(v1 + 16)) = 0;
log_print("bytes %s\n", (const char *)v3);
break;
case 4u:
log_print("array\n");
break;
default:
return 1LL;
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func11(unsigned int *a1)
{
__int64 v1; // r12
unsigned int v2; // ebp
void *v3; // rbx

log_print("serialElementDebug %d:\t", *a1);
switch ( a1[1] )
{
case 0u:
log_print("error %d\n", a1[2]);
break;
case 1u:
log_print("int %d\n", a1[2]);
break;
case 2u:
log_print("float %f\n", *((float *)a1 + 2));
goto LABEL_5;
case 3u:
LABEL_5:
v1 = *((_QWORD *)a1 + 1);
v2 = *(_DWORD *)(v1 + 16);
v3 = malloc(v2 + 1);
memcpy(v3, *(const void **)v1, v2);
*((_BYTE *)v3 + *(unsigned int *)(v1 + 16)) = 0;
log_print("bytes %s\n", (const char *)v3);
break;
case 4u:
log_print("array\n");
break;
default:
return 1LL;
}
return 1LL;
}

original_code:
_Bool display_serial(const struct key_value_pair* kvp) {
    log_print( "serialElementDebug %d:\t", kvp->key );;
    char* str;
    switch (kvp->wire_type) {
        case SERIAL_ERROR:
            log_print( "error %d\n", kvp->value.serialError );;
            break;
        case SERIAL_INT:
            log_print( "int %d\n", kvp->value.integer );;
            break;
        case SERIAL_FLOAT:
            log_print( "float %f\n", kvp->value.floater );;
        case SERIAL_STRING:
            str = (char*)malloc(kvp->value.bytes->length + 1);
            memcpy(str, kvp->value.bytes->data, kvp->value.bytes->length);
            str[kvp->value.bytes->length] = 0;
            log_print( "bytes %s\n", str );;
            break;
        case SERIAL_ARRAY:
            log_print( "array\n" );;
            break;
    }
    return 1;
}

canonical_original_code:
_Bool display_serial(struct key_value_pair *kvp) {
    log_print( "serialElementDebug %d:\t", kvp->key );;
    char *str;
    switch (kvp->wire_type) {
        case SERIAL_ERROR:
            log_print( "error %d\n", kvp->value.serialError );;
            break;
        case SERIAL_INT:
            log_print( "int %d\n", kvp->value.integer );;
            break;
        case SERIAL_FLOAT:
            log_print( "float %f\n", kvp->value.floater );;
        case SERIAL_STRING:
            str = (char *)malloc(kvp->value.bytes->length + 1);
            memcpy(str, kvp->value.bytes->data, kvp->value.bytes->length);
            str[kvp->value.bytes->length] = 0;
            log_print( "bytes %s\n", str );;
            break;
        case SERIAL_ARRAY:
            log_print( "array\n" );;
            break;
    }
    return 1;
}

variable_types: struct key_value_pair { int key; enum serial_type { SERIAL_ERROR=0, SERIAL_INT=1, SERIAL_FLOAT=2, SERIAL_STRING=3, SERIAL_ARRAY=4 } wire_type; union { int integer; float floater; struct byte_array { unsigned char *data; unsigned int length; } *bytes; enum { SOMETHING_HAS_GONE_HORRIBLY_WRONG=0 } serialError; } value; } *

variable_types:
str
char *


decompiled_code:
void hal_loop()
{
;
}

canonical_decompiled_code:
void func0()
{
;
}

original_code: void hal_loop() {}

canonical_original_code: void hal_loop() {}


decompiled_code:
void hal_graphics()
{
;
}

canonical_decompiled_code:
void func1()
{
;
}

original_code: void hal_graphics(const struct variable *shape) {}

canonical_original_code: void hal_graphics(struct variable *shape) {}

variable_types: struct variable { enum VarType { VAR_NIL=0, VAR_INT=1, VAR_FLT=2, VAR_BOOL=3, VAR_STR=4, VAR_FNC=5, VAR_LST=6, VAR_MAP=7, VAR_SRC=8, VAR_ERR=9, VAR_BYT=10, VAR_C=11 } type; enum Visited { VISITED_NOT=0, VISITED_ONCE=1, VISITED_MORE=2, VISITED_X=3 } visited; unsigned int mark; union { struct byte_array { unsigned char *data; unsigned int length; } *str; struct array { void **data; unsigned int current; unsigned int length; } *list; int integer; float floater; _Bool boolean; struct variable *(*cfnc)(struct context { struct variable *vm_exception; struct variable *error; struct stack { struct stack_node { void *data; struct stack_node *next; } *head; struct stack_node *tail; } *program_stack; struct stack *operand_stack; struct byte_array *program; _Bool runtime; unsigned int num_vars; unsigned char indent; struct variable *(*find)(struct context *context, struct byte_array *name); } *); }; struct map { _Bool (*comparator)(void *a, void *b); unsigned long size; struct hash_node { void *key; void *data; struct hash_node *next; } **nodes; int (*hash_func)(void *x); void (*deletor)(void *x); void *(*copyor)(void *x); } *map; } *


decompiled_code:
void hal_image()
{
;
}

canonical_decompiled_code:
void func2()
{
;
}

original_code: void hal_image() {}

canonical_original_code: void hal_image() {}


decompiled_code:
void hal_sound()
{
;
}

canonical_decompiled_code:
void func3()
{
;
}

original_code: void hal_sound() {}

canonical_original_code: void hal_sound() {}


decompiled_code:
void hal_synth()
{
;
}

canonical_decompiled_code:
void func4()
{
;
}

original_code: void hal_synth(const uint8_t *bytes, uint32_t length) {}

canonical_original_code: void hal_synth(unsigned char *bytes, unsigned int length) {}

variable_types:
bytes
unsigned char *

variable_types:
length
unsigned int


decompiled_code:
void hal_audioloop()
{
;
}

canonical_decompiled_code:
void func5()
{
;
}

original_code: void hal_audioloop() {}

canonical_original_code: void hal_audioloop() {}


decompiled_code:
void hal_window()
{
;
}

canonical_decompiled_code:
void func6()
{
;
}

original_code:
void hal_window(struct context *context,
                struct variable *uictx,
          int32_t *w, int32_t *h,
          struct variable *logic) {}

canonical_original_code: void hal_window(struct context *context, struct variable *uictx, int *w, int *h, struct variable *logic) {}

variable_types: struct context { struct variable { enum VarType { VAR_NIL=0, VAR_INT=1, VAR_FLT=2, VAR_BOOL=3, VAR_STR=4, VAR_FNC=5, VAR_LST=6, VAR_MAP=7, VAR_SRC=8, VAR_ERR=9, VAR_BYT=10, VAR_C=11 } type; enum Visited { VISITED_NOT=0, VISITED_ONCE=1, VISITED_MORE=2, VISITED_X=3 } visited; unsigned int mark; union { struct byte_array { unsigned char *data; unsigned int length; } *str; struct array { void **data; unsigned int current; unsigned int length; } *list; int integer; float floater; _Bool boolean; struct variable *(*cfnc)(struct context *); }; struct map { _Bool (*comparator)(void *a, void *b); unsigned long size; struct hash_node { void *key; void *data; struct hash_node *next; } **nodes; int (*hash_func)(void *x); void (*deletor)(void *x); void *(*copyor)(void *x); } *map; } *vm_exception; struct variable *error; struct stack { struct stack_node { void *data; struct stack_node *next; } *head; struct stack_node *tail; } *program_stack; struct stack *operand_stack; struct byte_array *program; _Bool runtime; unsigned int num_vars; unsigned char indent; struct variable *(*find)(struct context *context, struct byte_array *name); } *

variable_types:
uictx
struct variable *

variable_types:
w
int *

variable_types:
h
int *

variable_types:
logic
struct variable *


decompiled_code:
void hal_label()
{
;
}

canonical_decompiled_code:
void func7()
{
;
}

original_code:
void hal_label (int32_t x, int32_t y,
                int32_t *w, int32_t *h,
                const char *str) {}

canonical_original_code: void hal_label(int x, int y, int *w, int *h, char *str) {}

variable_types: x int

variable_types: y int


decompiled_code:
void hal_input()
{
;
}

canonical_decompiled_code:
void func8()
{
;
}

original_code:
void hal_input (struct variable *uictx,
                int32_t x, int32_t y,
                int32_t *w, int32_t *h,
                const char *str, _Bool multiline) {}

canonical_original_code: void hal_input(struct variable *uictx, int x, int y, int *w, int *h, char *str, _Bool multiline) {}


decompiled_code:
void hal_button()
{
;
}

canonical_decompiled_code:
void func9()
{
;
}

original_code:
void hal_button(struct context *context,
                struct variable *uictx,
                int32_t x, int32_t y, int32_t *w, int32_t *h,
                struct variable *logic,
                const char *str, const char *img) {}

canonical_original_code: void hal_button(struct context *context, struct variable *uictx, int x, int y, int *w, int *h, struct variable *logic, char *str, char *img) {}

variable_types:
img
char *


decompiled_code:
void hal_table()
{
;
}

canonical_decompiled_code:
void func10()
{
;
}

original_code:
void hal_table (struct context *context,
                struct variable *uictx,
                int x, int y, int w, int h,
                struct variable *list, struct variable *logic) {}

canonical_original_code: void hal_table(struct context *context, struct variable *uictx, int x, int y, int w, int h, struct variable *list, struct variable *logic) {}

variable_types: w int

variable_types: h int

variable_types:
list
struct variable *


decompiled_code:
void hal_sound_url()
{
;
}

canonical_decompiled_code:
void func11()
{
;
}

original_code: void hal_sound_url(const char *address) {}

canonical_original_code: void hal_sound_url(char *address) {}

variable_types:
address
char *


decompiled_code:
void hal_sound_bytes()
{
;
}

canonical_decompiled_code:
void func12()
{
;
}

original_code: void hal_sound_bytes(const uint8_t *bytes, uint32_t length) {}

canonical_original_code: void hal_sound_bytes(unsigned char *bytes, unsigned int length) {}


decompiled_code:
void hal_save()
{
;
}

canonical_decompiled_code:
void func13()
{
;
}

original_code: void hal_save(struct context *context, const struct byte_array *key, const struct variable *value) {}

canonical_original_code: void hal_save(struct context *context, struct byte_array *key, struct variable *value) {}

variable_types:
key
struct byte_array *

variable_types:
value
struct variable *


decompiled_code:
__int64 hal_load()
{
return 0LL;
}

canonical_decompiled_code:
__int64 func14()
{
return 0LL;
}

original_code: struct variable *hal_load(struct context *context, const struct byte_array *key) { return ((void *)0); }

canonical_original_code: struct variable *hal_load(struct context *context, struct byte_array *key) { return ((void *)0); }

variable_types:
context
struct context *

return_type: struct variable { enum VarType { VAR_NIL=0, VAR_INT=1, VAR_FLT=2, VAR_BOOL=3, VAR_STR=4, VAR_FNC=5, VAR_LST=6, VAR_MAP=7, VAR_SRC=8, VAR_ERR=9, VAR_BYT=10, VAR_C=11 } type; enum Visited { VISITED_NOT=0, VISITED_ONCE=1, VISITED_MORE=2, VISITED_X=3 } visited; unsigned int mark; union { struct byte_array { unsigned char *data; unsigned int length; } *str; struct array { void **data; unsigned int current; unsigned int length; } *list; int integer; float floater; _Bool boolean; struct variable *(*cfnc)(struct context { struct variable *vm_exception; struct variable *error; struct stack { struct stack_node { void *data; struct stack_node *next; } *head; struct stack_node *tail; } *program_stack; struct stack *operand_stack; struct byte_array *program; _Bool runtime; unsigned int num_vars; unsigned char indent; struct variable *(*find)(struct context *context, struct byte_array *name); } *); }; struct map { _Bool (*comparator)(void *a, void *b); unsigned long size; struct hash_node { void *key; void *data; struct hash_node *next; } **nodes; int (*hash_func)(void *x); void (*deletor)(void *x); void *(*copyor)(void *x); } *map; } *


decompiled_code:
void hal_save_form()
{
;
}

canonical_decompiled_code:
void func15()
{
;
}

original_code: void hal_save_form(struct context *context, const struct byte_array *key) {}

canonical_original_code: void hal_save_form(struct context *context, struct byte_array *key) {}


decompiled_code:
void hal_load_form()
{
;
}

canonical_decompiled_code:
void func16()
{
;
}

original_code: void hal_load_form(struct context *context, const struct byte_array *key) {}

canonical_original_code: void hal_load_form(struct context *context, struct byte_array *key) {}


repo: wkleiminger/pylon

decompiled_code:
__time_t timer_now()
{
__time_t result; // rax
int *v1; // rax
char *v2; // rax
struct timespec v3; // [rsp+0h] [rbp-18h] BYREF

v3.tv_sec = 0LL;
v3.tv_nsec = 0LL;
if ( clock_gettime(1, &v3) != -1 )
return 1000 * v3.tv_sec + v3.tv_nsec / 1000000;
result = 0LL;
if ( log_level >= 0 )
{
v1 = _errno_location();
v2 = strerror(*v1);
log_message("pylon/timer.c", "timer_now", 0LL, "Failed to get timestamp: %s\n", v2);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__time_t func0()
{
__time_t result; // rax
int *v1; // rax
char *v2; // rax
struct timespec v3; // [rsp+0h] [rbp-18h] BYREF

v3.tv_sec = 0LL;
v3.tv_nsec = 0LL;
if ( clock_gettime(1, &v3) != -1 )
return 1000 * v3.tv_sec + v3.tv_nsec / 1000000;
result = 0LL;
if ( log_level >= 0 )
{
v1 = _errno_location();
v2 = strerror(*v1);
log_message("pylon/timer.c", "timer_now", 0LL, "Failed to get timestamp: %s\n", v2);
result = 0LL;
}
return result;
}

original_code:
uint64_t timer_now(void) {
 struct timespec ts = {0};
 if (clock_gettime(1, &ts) == -1) {
  if (0 <= log_level) log_message("pylon/timer.c", __func__, 0, "Failed to get timestamp: %s\n", strerror((*__errno_location ())));
  return 0;
 }
 return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}

canonical_original_code:
unsigned long timer_now() {
 struct timespec ts = {0};
 if (clock_gettime(1, &ts) == -1) {
  if (0 <= log_level) log_message("pylon/timer.c", __func__, 0, "Failed to get timestamp: %s\n", strerror((*__errno_location ())));
  return 0;
 }
 return (unsigned long)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}

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


decompiled_code:
__time_t timer_start()
{
__time_t result; // rax

result = timer_now();
startTime = result;
return result;
}

canonical_decompiled_code:
__time_t func1()
{
__time_t result; // rax

result = func0();
startTime = result;
return result;
}

original_code:
void timer_start(void)
{
 startTime = timer_now();
}

canonical_original_code:
void timer_start()
{
 startTime = timer_now();
}


decompiled_code:
__int64 timer_stop()
{
return (unsigned int)timer_now() - (unsigned int)startTime;
}

canonical_decompiled_code:
__int64 func2()
{
return (unsigned int)func0() - (unsigned int)startTime;
}

original_code:
int timer_stop(void)
{
 int elapsed = timer_now() - startTime;
 return elapsed;
}

canonical_original_code:
int timer_stop()
{
 int elapsed = timer_now() - startTime;
 return elapsed;
}

variable_types: elapsed int


decompiled_code:
__int64 timer_restart()
{
unsigned int v0; // ebx

v0 = timer_stop();
timer_start();
return v0;
}

canonical_decompiled_code:
__int64 func3()
{
unsigned int v0; // ebx

v0 = func2();
func1();
return v0;
}

original_code:
int timer_restart(void)
{
 int elapsed = timer_stop();
 timer_start();
 return elapsed;
}

canonical_original_code:
int timer_restart()
{
 int elapsed = timer_stop();
 timer_start();
 return elapsed;
}


decompiled_code:
__int64 __fastcall timer_sleep(int a1)
{
struct timespec v2; // [rsp+0h] [rbp-18h] BYREF

v2.tv_sec = a1 / 1000;
v2.tv_nsec = 1000000 * (a1 % 1000);
while ( nanosleep(&v2, &v2) == -1 )
{
if ( *_errno_location() != 4 )
return 0LL;
}
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func4(int a1)
{
struct timespec v2; // [rsp+0h] [rbp-18h] BYREF

v2.tv_sec = a1 / 1000;
v2.tv_nsec = 1000000 * (a1 % 1000);
while ( nanosleep(&v2, &v2) == -1 )
{
if ( *_errno_location() != 4 )
return 0LL;
}
return 1LL;
}

original_code:
int timer_sleep(int interval)
{
 struct timespec ts;
 ts.tv_sec = interval / 1000;
 ts.tv_nsec = (interval % 1000) * 1000000;
 while (nanosleep(&ts, &ts) == -1) {
  if ((*__errno_location ()) != 4) return 0;
 }
 return 1;
}

variable_types: interval int

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


decompiled_code:
__int64 __fastcall timer_barrier(_DWORD *a1, int a2, _DWORD *a3)
{
unsigned int v4; // ebp
int v6; // eax

if ( *(_QWORD *)a1 )
{
v6 = timer_now() - *a1;
*a3 = v6;
v4 = 0;
if ( v6 < a2 )
v4 = timer_sleep(a2 - v6);
}
else
{
*a3 = 0;
v4 = 1;
}
*(_QWORD *)a1 = timer_now();
return v4;
}

canonical_decompiled_code:
__int64 __fastcall func5(_DWORD *a1, int a2, _DWORD *a3)
{
unsigned int v4; // ebp
int v6; // eax

if ( *(_QWORD *)a1 )
{
v6 = func0() - *a1;
*a3 = v6;
v4 = 0;
if ( v6 < a2 )
v4 = func4(a2 - v6);
}
else
{
*a3 = 0;
v4 = 1;
}
*(_QWORD *)a1 = func0();
return v4;
}

original_code:
int timer_barrier(uint64_t* barrier, int interval, int* elapsed)
{
 int ret = 0;
 if (*barrier > 0) {
  *elapsed = timer_now() - *barrier;
  if (*elapsed < interval) {
   ret = timer_sleep(interval - *elapsed);
  }
 } else {
  *elapsed = 0;
  ret = 1;
 }
 *barrier = timer_now();
 return ret;
}

canonical_original_code:
int timer_barrier(unsigned long *barrier, int interval, int *elapsed)
{
 int ret = 0;
 if (*barrier > 0) {
  *elapsed = timer_now() - *barrier;
  if (*elapsed < interval) {
   ret = timer_sleep(interval - *elapsed);
  }
 } else {
  *elapsed = 0;
  ret = 1;
 }
 *barrier = timer_now();
 return ret;
}

variable_types:
barrier
unsigned long *

variable_types:
elapsed
int *

variable_types: ret int


nullWriteFunction

decompiled_code:
__int64 __fastcall nullWriteFunction(__int64 a1, __int64 a2, __int64 a3)
{
return a3 * a2;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, __int64 a2, __int64 a3)
{
return a3 * a2;
}

original_code:
size_t nullWriteFunction(char* ptr, size_t size, size_t nmemb, void* userdata)
{
 return size*nmemb;
}

canonical_original_code:
unsigned long nullWriteFunction(char *ptr, unsigned long size, unsigned long nmemb, void *userdata)
{
 return size*nmemb;
}

variable_types:
ptr
char *

variable_types:
size
unsigned long

variable_types:
nmemb
unsigned long

variable_types:
userdata
void *


uploadProc

decompiled_code:
void *__fastcall uploadProc(void *a1, __int64 a2)
{
__int64 v2; // rdx
__int64 v3; // rax
__int64 v4; // rbx
void *v6; // rsi
__int64 v7; // rdx
__int64 v8; // rdx
void *ptr[4]; // [rsp+8h] [rbp-20h] BYREF

v2 = (unsigned int)((m_interval * (int)a1) >> 31);
LODWORD(v2) = m_interval * (int)a1 % m_numThreads;
timer_sleep((unsigned int)(m_interval * (int)a1 / m_numThreads), a2, v2);
v3 = curl_easy_init();
if ( v3 )
{
v4 = v3;
while ( m_running )
{
ptr[0] = 0LL;
if ( (unsigned int)queue_dequeue(m_queue, ptr) && ptr[0] )
{
while ( 1 )
{
v6 = ptr[0];
if ( (unsigned int)performPOST(v4, (__int64)ptr[0]) )
break;
timer_sleep((unsigned int)m_interval, v6, v7);
}
if ( log_level > 2 )
log_message(
"pylon/uploader.c",
"uploadProc",
3LL,
"Thread %d sent measurement successfully\n",
(unsigned int)a1);
free(ptr[0]);
}
else
{
timer_sleep((unsigned int)m_interval, ptr, v8);
}
}
curl_easy_cleanup(v4);
}
else if ( log_level >= 0 )
{
log_message("pylon/uploader.c", "uploadProc", 0LL, "Failed to initialize curl for thread %d\n", (unsigned int)a1);
}
return 0LL;
}

canonical_decompiled_code:
void *__fastcall func2(void *a1, __int64 a2)
{
__int64 v2; // rdx
__int64 v3; // rax
__int64 v4; // rbx
void *v6; // rsi
__int64 v7; // rdx
__int64 v8; // rdx
void *ptr[4]; // [rsp+8h] [rbp-20h] BYREF

v2 = (unsigned int)((m_interval * (int)a1) >> 31);
LODWORD(v2) = m_interval * (int)a1 % m_numThreads;
timer_sleep((unsigned int)(m_interval * (int)a1 / m_numThreads), a2, v2);
v3 = curl_easy_init();
if ( v3 )
{
v4 = v3;
while ( m_running )
{
ptr[0] = 0LL;
if ( (unsigned int)queue_dequeue(m_queue, ptr) && ptr[0] )
{
while ( 1 )
{
v6 = ptr[0];
if ( (unsigned int)func1(v4, (__int64)ptr[0]) )
break;
timer_sleep((unsigned int)m_interval, v6, v7);
}
if ( log_level > 2 )
log_message(
"pylon/uploader.c",
"uploadProc",
3LL,
"Thread %d sent measurement successfully\n",
(unsigned int)a1);
free(ptr[0]);
}
else
{
timer_sleep((unsigned int)m_interval, ptr, v8);
}
}
curl_easy_cleanup(v4);
}
else if ( log_level >= 0 )
{
log_message("pylon/uploader.c", "uploadProc", 0LL, "Failed to initialize curl for thread %d\n", (unsigned int)a1);
}
return 0LL;
}

original_code:
void* uploadProc(void* arg)
{
 int threadNum = (int)arg;
 timer_sleep(m_interval * threadNum / m_numThreads);
 CURL* curl = curl_easy_init();
 if (!curl) {
  if (0 <= log_level) log_message("pylon/uploader.c", __func__, 0, "Failed to initialize curl for thread %d\n", threadNum);
  return ((void *)0);
 }
 while (m_running) {
  char* data = ((void *)0);
  if (!queue_dequeue(m_queue, &data) || !data) {
   timer_sleep(m_interval);
   continue;
  }
  while (!performPOST(curl, data)) {
   timer_sleep(m_interval);
  }
  if (3 <= log_level) log_message("pylon/uploader.c", __func__, 3, "Thread %d sent measurement successfully\n", threadNum);
  free(data);
 }
 curl_easy_cleanup(curl);
 return ((void *)0);
}

canonical_original_code:
void *uploadProc(void *arg)
{
 int threadNum = (int)arg;
 timer_sleep(m_interval * threadNum / m_numThreads);
 void *curl = curl_easy_init();
 if (!curl) {
  if (0 <= log_level) log_message("pylon/uploader.c", __func__, 0, "Failed to initialize curl for thread %d\n", threadNum);
  return ((void *)0);
 }
 while (m_running) {
  char *data = ((void *)0);
  if (!queue_dequeue(m_queue, &data) || !data) {
   timer_sleep(m_interval);
   continue;
  }
  while (!performPOST(curl, data)) {
   timer_sleep(m_interval);
  }
  if (3 <= log_level) log_message("pylon/uploader.c", __func__, 3, "Thread %d sent measurement successfully\n", threadNum);
  free(data);
 }
 curl_easy_cleanup(curl);
 return ((void *)0);
}

variable_types:
arg
void *

variable_types: threadNum int

variable_types:
curl
void *

variable_types:
data
char *


decompiled_code:
__int64 uploader_cleanup()
{
__int64 v0; // rbx
int v1; // eax
char *v2; // rax

m_running = 0;
if ( m_numThreads > 0 )
{
v0 = 0LL;
do
{
v1 = pthread_join(*((_QWORD *)m_threads + v0), 0LL);
if ( v1 && log_level >= 0 )
{
v2 = strerror(v1);
log_message(
"pylon/uploader.c",
"uploader_cleanup",
0LL,
"Failed to join sender thread %d: %s\n",
(unsigned int)v0,
v2);
}
++v0;
}
while ( m_numThreads > (int)v0 );
}
free(m_threads);
queue_free(m_queue);
return curl_global_cleanup();
}

canonical_decompiled_code:
__int64 func3()
{
__int64 v0; // rbx
int v1; // eax
char *v2; // rax

m_running = 0;
if ( m_numThreads > 0 )
{
v0 = 0LL;
do
{
v1 = pthread_join(*((_QWORD *)m_threads + v0), 0LL);
if ( v1 && log_level >= 0 )
{
v2 = strerror(v1);
log_message(
"pylon/uploader.c",
"uploader_cleanup",
0LL,
"Failed to join sender thread %d: %s\n",
(unsigned int)v0,
v2);
}
++v0;
}
while ( m_numThreads > (int)v0 );
}
free(m_threads);
queue_free(m_queue);
return curl_global_cleanup();
}

original_code:
void uploader_cleanup(void)
{
 m_running = 0;
 for (int threadNum = 0; threadNum < m_numThreads; threadNum++) {
  int error = pthread_join(m_threads[threadNum], ((void *)0));
  if (error) {
   if (0 <= log_level) log_message("pylon/uploader.c", __func__, 0, "Failed to join sender thread %d: %s\n", threadNum, strerror(error));
  }
 }
 free(m_threads);
 queue_free(m_queue);
 curl_global_cleanup();
}

canonical_original_code:
void uploader_cleanup()
{
 m_running = 0;
 for (int threadNum = 0; threadNum < m_numThreads; threadNum++) {
  int error = pthread_join(m_threads[threadNum], ((void *)0));
  if (error) {
   if (0 <= log_level) log_message("pylon/uploader.c", __func__, 0, "Failed to join sender thread %d: %s\n", threadNum, strerror(error));
  }
 }
 free(m_threads);
 queue_free(m_queue);
 curl_global_cleanup();
}

variable_types: error int


decompiled_code:
__int64 __fastcall uploader_send(__int64 a1)
{
unsigned int v1; // ebx
__int64 v3; // [rsp+8h] [rbp-10h] BYREF

v3 = a1;
v1 = 1;
if ( !(unsigned int)queue_enqueue(m_queue, &v3) )
{
v1 = 0;
if ( log_level >= 0 )
log_message("pylon/uploader.c", "uploader_send", 0LL, "Upload queue full\n");
}
return v1;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1)
{
unsigned int v1; // ebx
__int64 v3; // [rsp+8h] [rbp-10h] BYREF

v3 = a1;
v1 = 1;
if ( !(unsigned int)queue_enqueue(m_queue, &v3) )
{
v1 = 0;
if ( log_level >= 0 )
log_message("pylon/uploader.c", "uploader_send", 0LL, "Upload queue full\n");
}
return v1;
}

original_code:
int uploader_send(const char* payload)
{
 if (!queue_enqueue(m_queue, &payload)) {
  if (0 <= log_level) log_message("pylon/uploader.c", __func__, 0, "Upload queue full\n");
  return 0;
 }
 return 1;
}

canonical_original_code:
int uploader_send(char *payload)
{
 if (!queue_enqueue(m_queue, &payload)) {
  if (0 <= log_level) log_message("pylon/uploader.c", __func__, 0, "Upload queue full\n");
  return 0;
 }
 return 1;
}

variable_types:
payload
char *


decompiled_code:
__int64 uploader_queueSize()
{
return queue_count(m_queue);
}

canonical_decompiled_code:
__int64 func5()
{
return queue_count(m_queue);
}

original_code:
int uploader_queueSize(void)
{
 return queue_count(m_queue);
}

canonical_original_code:
int uploader_queueSize()
{
 return queue_count(m_queue);
}


decompiled_code:
void __fastcall uploader_setInterval(int a1)
{
m_interval = a1;
}

canonical_decompiled_code:
void __fastcall func6(int a1)
{
m_interval = a1;
}

original_code:
void uploader_setInterval(int interval)
{
 m_interval = interval;
}


decompiled_code:
__int64 __fastcall uploader_init(__int64 a1, __int64 a2, __int64 a3, int a4)
{
unsigned int v6; // eax
__int64 v7; // rdi
__int64 result; // rax
const char *v9; // rbx
const char *v10; // rax
char *v11; // rbx
int v12; // eax
int *v13; // rax
char *v14; // rax
char *v15; // rax

m_url = a1;
m_token = a2;
m_numThreads = a4;
uploader_setInterval(1000);
v6 = curl_global_init(3LL);
if ( v6 )
{
v7 = v6;
result = 0LL;
if ( log_level >= 0 )
{
v9 = (const char *)curl_easy_strerror(v7);
v10 = (const char *)curl_version();
log_message("pylon/uploader.c", "uploader_init", 0LL, "Failed to initialize CURL (%s): %s\n", v10, v9);
result = 0LL;
}
}
else
{
result = queue_create(a3, 8LL);
m_queue = result;
if ( result )
{
m_threads = calloc(a4, 8uLL);
if ( m_threads )
{
m_running = 1;
if ( m_numThreads > 0 )
{
v11 = 0LL;
while ( 1 )
{
v12 = pthread_create((pthread_t *)m_threads + (_QWORD)v11, 0LL, (void *(*)(void *))uploadProc, v11);
if ( v12 )
break;
if ( m_numThreads <= (int)++v11 )
goto LABEL_20;
}
if ( log_level > 0 )
{
v15 = strerror(v12);
log_message(
"pylon/uploader.c",
"uploader_init",
1LL,
"Failed to create sender thread %d: %s\n",
(unsigned int)v11,
v15);
}
m_numThreads = (int)v11;
}
LABEL_20:
result = 1LL;
if ( log_level > 1 )
{
log_message(
"pylon/uploader.c",
"uploader_init",
2LL,
"Sending data to %s with token '%s' using %d threads and queue with capacity %d\n",
(const char *)m_url,
(const char *)m_token,
(unsigned int)m_numThreads,
a3);
result = 1LL;
}
}
else
{
if ( log_level >= 0 )
log_message("pylon/uploader.c", "uploader_init", 0LL, "Failed to allocate thread array\n");
queue_free(m_queue);
result = 0LL;
}
}
else if ( log_level >= 0 )
{
v13 = _errno_location();
v14 = strerror(*v13);
log_message("pylon/uploader.c", "uploader_init", 0LL, "Failed to create upload queue: %s\n", v14);
result = 0LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func7(__int64 a1, __int64 a2, __int64 a3, int a4)
{
unsigned int v6; // eax
__int64 v7; // rdi
__int64 result; // rax
const char *v9; // rbx
const char *v10; // rax
char *v11; // rbx
int v12; // eax
int *v13; // rax
char *v14; // rax
char *v15; // rax

m_url = a1;
m_token = a2;
m_numThreads = a4;
func6(1000);
v6 = curl_global_init(3LL);
if ( v6 )
{
v7 = v6;
result = 0LL;
if ( log_level >= 0 )
{
v9 = (const char *)curl_easy_strerror(v7);
v10 = (const char *)curl_version();
log_message("pylon/uploader.c", "uploader_init", 0LL, "Failed to initialize CURL (%s): %s\n", v10, v9);
result = 0LL;
}
}
else
{
result = queue_create(a3, 8LL);
m_queue = result;
if ( result )
{
m_threads = calloc(a4, 8uLL);
if ( m_threads )
{
m_running = 1;
if ( m_numThreads > 0 )
{
v11 = 0LL;
while ( 1 )
{
v12 = pthread_create((pthread_t *)m_threads + (_QWORD)v11, 0LL, (void *(*)(void *))uploadProc, v11);
if ( v12 )
break;
if ( m_numThreads <= (int)++v11 )
goto LABEL_20;
}
if ( log_level > 0 )
{
v15 = strerror(v12);
log_message(
"pylon/uploader.c",
"uploader_init",
1LL,
"Failed to create sender thread %d: %s\n",
(unsigned int)v11,
v15);
}
m_numThreads = (int)v11;
}
LABEL_20:
result = 1LL;
if ( log_level > 1 )
{
log_message(
"pylon/uploader.c",
"uploader_init",
2LL,
"Sending data to %s with token '%s' using %d threads and queue with capacity %d\n",
(const char *)m_url,
(const char *)m_token,
(unsigned int)m_numThreads,
a3);
result = 1LL;
}
}
else
{
if ( log_level >= 0 )
log_message("pylon/uploader.c", "uploader_init", 0LL, "Failed to allocate thread array\n");
queue_free(m_queue);
result = 0LL;
}
}
else if ( log_level >= 0 )
{
v13 = _errno_location();
v14 = strerror(*v13);
log_message("pylon/uploader.c", "uploader_init", 0LL, "Failed to create upload queue: %s\n", v14);
result = 0LL;
}
}
return result;
}

original_code:
int uploader_init(const char* url, const char* token, size_t queueSize, int numThreads)
{
 m_url = url;
 m_token = token;
 m_numThreads = numThreads;
 uploader_setInterval(1000);
 CURLcode code = curl_global_init(((1<<0)|(1<<1)));
 if (code != CURLE_OK) {
  if (0 <= log_level) log_message("pylon/uploader.c", __func__, 0, "Failed to initialize CURL (%s): %s\n", curl_version(), curl_easy_strerror(code));
  return 0;
 }
 m_queue = queue_create(queueSize, sizeof(char*));
 if (!m_queue) {
  if (0 <= log_level) log_message("pylon/uploader.c", __func__, 0, "Failed to create upload queue: %s\n", strerror((*__errno_location ())));
  return 0;
 }
 m_threads = calloc(numThreads, sizeof(pthread_t));
 if (!m_threads) {
  if (0 <= log_level) log_message("pylon/uploader.c", __func__, 0, "Failed to allocate thread array\n");
  queue_free(m_queue);
  return 0;
 }
 m_running = 1;
 for (int threadNum = 0; threadNum < m_numThreads; threadNum++) {
  int error = pthread_create(&m_threads[threadNum], ((void *)0), uploadProc, (void*)threadNum);
  if (error) {
   if (1 <= log_level) log_message("pylon/uploader.c", __func__, 1, "Failed to create sender thread %d: %s\n", threadNum, strerror(error));
   m_numThreads = threadNum;
   break;
  }
 }
 if (2 <= log_level) log_message("pylon/uploader.c", __func__, 2, "Sending data to %s with token '%s' using %d threads and queue with capacity %d\n", m_url, m_token, m_numThreads, queueSize);
 return 1;
}

canonical_original_code:
int uploader_init(char *url, char *token, unsigned long queueSize, int numThreads)
{
 m_url = url;
 m_token = token;
 m_numThreads = numThreads;
 uploader_setInterval(1000);
 enum CURLcode code = curl_global_init(((1<<0)|(1<<1)));
 if (code != CURLE_OK) {
  if (0 <= log_level) log_message("pylon/uploader.c", __func__, 0, "Failed to initialize CURL (%s): %s\n", curl_version(), curl_easy_strerror(code));
  return 0;
 }
 m_queue = queue_create(queueSize, sizeof(char *));
 if (!m_queue) {
  if (0 <= log_level) log_message("pylon/uploader.c", __func__, 0, "Failed to create upload queue: %s\n", strerror((*__errno_location ())));
  return 0;
 }
 m_threads = calloc(numThreads, sizeof(pthread_t));
 if (!m_threads) {
  if (0 <= log_level) log_message("pylon/uploader.c", __func__, 0, "Failed to allocate thread array\n");
  queue_free(m_queue);
  return 0;
 }
 m_running = 1;
 for (int threadNum = 0; threadNum < m_numThreads; threadNum++) {
  int error = pthread_create(&m_threads[threadNum], ((void *)0), uploadProc, (void*)threadNum);
  if (error) {
   if (1 <= log_level) log_message("pylon/uploader.c", __func__, 1, "Failed to create sender thread %d: %s\n", threadNum, strerror(error));
   m_numThreads = threadNum;
   break;
  }
 }
 if (2 <= log_level) log_message("pylon/uploader.c", __func__, 2, "Sending data to %s with token '%s' using %d threads and queue with capacity %d\n", m_url, m_token, m_numThreads, queueSize);
 return 1;
}

variable_types:
url
char *

variable_types:
token
char *

variable_types:
queueSize
unsigned long

variable_types: numThreads int

variable_types: enum CURLcode { CURLE_OK=0, CURLE_UNSUPPORTED_PROTOCOL=1, CURLE_FAILED_INIT=2, CURLE_URL_MALFORMAT=3, CURLE_NOT_BUILT_IN=4, CURLE_COULDNT_RESOLVE_PROXY=5, CURLE_COULDNT_RESOLVE_HOST=6, CURLE_COULDNT_CONNECT=7, CURLE_WEIRD_SERVER_REPLY=8, CURLE_REMOTE_ACCESS_DENIED=9, CURLE_FTP_ACCEPT_FAILED=10, CURLE_FTP_WEIRD_PASS_REPLY=11, CURLE_FTP_ACCEPT_TIMEOUT=12, CURLE_FTP_WEIRD_PASV_REPLY=13, CURLE_FTP_WEIRD_227_FORMAT=14, CURLE_FTP_CANT_GET_HOST=15, CURLE_HTTP2=16, CURLE_FTP_COULDNT_SET_TYPE=17, CURLE_PARTIAL_FILE=18, CURLE_FTP_COULDNT_RETR_FILE=19, CURLE_OBSOLETE20=20, CURLE_QUOTE_ERROR=21, CURLE_HTTP_RETURNED_ERROR=22, CURLE_WRITE_ERROR=23, CURLE_OBSOLETE24=24, CURLE_UPLOAD_FAILED=25, CURLE_READ_ERROR=26, CURLE_OUT_OF_MEMORY=27, CURLE_OPERATION_TIMEDOUT=28, CURLE_OBSOLETE29=29, CURLE_FTP_PORT_FAILED=30, CURLE_FTP_COULDNT_USE_REST=31, CURLE_OBSOLETE32=32, CURLE_RANGE_ERROR=33, CURLE_HTTP_POST_ERROR=34, CURLE_SSL_CONNECT_ERROR=35, CURLE_BAD_DOWNLOAD_RESUME=36, CURLE_FILE_COULDNT_READ_FILE=37, CURLE_LDAP_CANNOT_BIND=38, CURLE_LDAP_SEARCH_FAILED=39, CURLE_OBSOLETE40=40, CURLE_FUNCTION_NOT_FOUND=41, CURLE_ABORTED_BY_CALLBACK=42, CURLE_BAD_FUNCTION_ARGUMENT=43, CURLE_OBSOLETE44=44, CURLE_INTERFACE_FAILED=45, CURLE_OBSOLETE46=46, CURLE_TOO_MANY_REDIRECTS=47, CURLE_UNKNOWN_OPTION=48, CURLE_TELNET_OPTION_SYNTAX=49, CURLE_OBSOLETE50=50, CURLE_OBSOLETE51=51, CURLE_GOT_NOTHING=52, CURLE_SSL_ENGINE_NOTFOUND=53, CURLE_SSL_ENGINE_SETFAILED=54, CURLE_SEND_ERROR=55, CURLE_RECV_ERROR=56, CURLE_OBSOLETE57=57, CURLE_SSL_CERTPROBLEM=58, CURLE_SSL_CIPHER=59, CURLE_PEER_FAILED_VERIFICATION=60, CURLE_BAD_CONTENT_ENCODING=61, CURLE_LDAP_INVALID_URL=62, CURLE_FILESIZE_EXCEEDED=63, CURLE_USE_SSL_FAILED=64, CURLE_SEND_FAIL_REWIND=65, CURLE_SSL_ENGINE_INITFAILED=66, CURLE_LOGIN_DENIED=67, CURLE_TFTP_NOTFOUND=68, CURLE_TFTP_PERM=69, CURLE_REMOTE_DISK_FULL=70, CURLE_TFTP_ILLEGAL=71, CURLE_TFTP_UNKNOWNID=72, CURLE_REMOTE_FILE_EXISTS=73, CURLE_TFTP_NOSUCHUSER=74, CURLE_CONV_FAILED=75, CURLE_CONV_REQD=76, CURLE_SSL_CACERT_BADFILE=77, CURLE_REMOTE_FILE_NOT_FOUND=78, CURLE_SSH=79, CURLE_SSL_SHUTDOWN_FAILED=80, CURLE_AGAIN=81, CURLE_SSL_CRL_BADFILE=82, CURLE_SSL_ISSUER_ERROR=83, CURLE_FTP_PRET_FAILED=84, CURLE_RTSP_CSEQ_ERROR=85, CURLE_RTSP_SESSION_ERROR=86, CURLE_FTP_BAD_FILE_LIST=87, CURLE_CHUNK_FAILED=88, CURLE_NO_CONNECTION_AVAILABLE=89, CURLE_SSL_PINNEDPUBKEYNOTMATCH=90, CURLE_SSL_INVALIDCERTSTATUS=91, CURLE_HTTP2_STREAM=92, CURLE_RECURSIVE_API_CALL=93, CURL_LAST=94 }


processMeasurement

decompiled_code:
__int64 __fastcall processMeasurement(double *a1)
{
int v1; // ebx
double *v2; // r12
__int64 i; // rbx
double v4; // r12
const char *v5; // rax
unsigned __int64 v6; // rdx
void *v7; // rbx
__int64 result; // rax
unsigned int v9; // eax

if ( !m_quiet )
{
v1 = m_smart;
v2 = a1;
if ( m_smart )
{
for ( i = 0LL; i != 17; ++i )
{
v4 = a1[i];
if ( v4 != -1.0 && v4 != 0.0 )
{
v5 = (const char *)smartmeter_getVarName((unsigned int)i);
printf("%s: %f; ", v5, v4);
}
}
putchar(10);
}
else
{
while ( 1 )
{
printf("%f%c", *v2, 9LL);
if ( ++v1 > 16 )
break;
++v2;
if ( v1 > 15 )
{
printf("%f%c", a1[v1], 10LL);
break;
}
}
}
}
if ( m_url )
{
strbuilder_reset(m_sb);
strbuilder_printf(m_sb, "{\"measurement\":{");
strbuilder_printf(m_sb, "\"powerAllPhases\": %.4f,\t", a1[1]);
strbuilder_printf(m_sb, "\"powerL1\": %.4f,", a1[2]);
strbuilder_printf(m_sb, "\"powerL2\": %.4f,", a1[3]);
strbuilder_printf(m_sb, "\"powerL3\": %.4f,", a1[4]);
strbuilder_printf(m_sb, "\"currentNeutral\": %.4f,", a1[5]);
strbuilder_printf(m_sb, "\"currentL1\": %.4f,", a1[6]);
strbuilder_printf(m_sb, "\"currentL2\": %.4f,", a1[7]);
strbuilder_printf(m_sb, "\"currentL3\": %.4f,", a1[8]);
strbuilder_printf(m_sb, "\"voltageL1\": %.4f,\t", a1[9]);
strbuilder_printf(m_sb, "\"voltageL2\": %.4f,", a1[10]);
strbuilder_printf(m_sb, "\"voltageL3\": %.4f,", a1[11]);
strbuilder_printf(m_sb, "\"phaseAngleVoltageL2L1\": %.4f,", a1[12]);
strbuilder_printf(m_sb, "\"phaseAngleVoltageL3L1\": %.4f,", a1[13]);
strbuilder_printf(m_sb, "\"phaseAngleCurrentVoltageL1\": %.4f,", a1[14]);
strbuilder_printf(m_sb, "\"phaseAngleCurrentVoltageL2\": %.4f,", a1[15]);
strbuilder_printf(m_sb, "\"phaseAngleCurrentVoltageL3\": %.4f,\t", a1[16]);
v6 = *a1 >= 9.223372036854776e18 ? (unsigned int)(int)(*a1 - 9.223372036854776e18) ^ 0x8000000000000000LL : (unsigned __int64)(unsigned int)(int)*a1;
strbuilder_printf(m_sb, "\"createdOn\": %llu,\t", v6);
strbuilder_printf(m_sb, "\"smartMeterId\": 1,");
strbuilder_printf(m_sb, "\"smartMeterToken\": \"%s\"\t", (const char *)m_token);
strbuilder_printf(m_sb, "}}");
v7 = (void *)strbuilder_copy(m_sb);
if ( !(unsigned int)uploader_send(v7) )
{
if ( log_level > 0 )
log_message("smlogger.c", "processMeasurement", 1LL, "Unable to upload data\n");
free(v7);
}
}
++m_numMeasurements;
if ( m_numMeasurements == 60 * (m_numMeasurements / 60) && log_level > 1 )
{
v9 = uploader_queueSize();
log_message(
"smlogger.c",
"processMeasurement",
2LL,
"numMeasurements: %d, buffered: %d\n",
(unsigned int)m_numMeasurements,
v9);
}
result = (unsigned int)m_count;
if ( m_count > 0 && m_count <= m_numMeasurements )
{
if ( m_onboard )
result = fluksometer_stop();
else
result = smartmeter_stop();
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(double *a1)
{
int v1; // ebx
double *v2; // r12
__int64 i; // rbx
double v4; // r12
const char *v5; // rax
unsigned __int64 v6; // rdx
void *v7; // rbx
__int64 result; // rax
unsigned int v9; // eax

if ( !m_quiet )
{
v1 = m_smart;
v2 = a1;
if ( m_smart )
{
for ( i = 0LL; i != 17; ++i )
{
v4 = a1[i];
if ( v4 != -1.0 && v4 != 0.0 )
{
v5 = (const char *)smartmeter_getVarName((unsigned int)i);
printf("%s: %f; ", v5, v4);
}
}
putchar(10);
}
else
{
while ( 1 )
{
printf("%f%c", *v2, 9LL);
if ( ++v1 > 16 )
break;
++v2;
if ( v1 > 15 )
{
printf("%f%c", a1[v1], 10LL);
break;
}
}
}
}
if ( m_url )
{
strbuilder_reset(m_sb);
strbuilder_printf(m_sb, "{\"measurement\":{");
strbuilder_printf(m_sb, "\"powerAllPhases\": %.4f,\t", a1[1]);
strbuilder_printf(m_sb, "\"powerL1\": %.4f,", a1[2]);
strbuilder_printf(m_sb, "\"powerL2\": %.4f,", a1[3]);
strbuilder_printf(m_sb, "\"powerL3\": %.4f,", a1[4]);
strbuilder_printf(m_sb, "\"currentNeutral\": %.4f,", a1[5]);
strbuilder_printf(m_sb, "\"currentL1\": %.4f,", a1[6]);
strbuilder_printf(m_sb, "\"currentL2\": %.4f,", a1[7]);
strbuilder_printf(m_sb, "\"currentL3\": %.4f,", a1[8]);
strbuilder_printf(m_sb, "\"voltageL1\": %.4f,\t", a1[9]);
strbuilder_printf(m_sb, "\"voltageL2\": %.4f,", a1[10]);
strbuilder_printf(m_sb, "\"voltageL3\": %.4f,", a1[11]);
strbuilder_printf(m_sb, "\"phaseAngleVoltageL2L1\": %.4f,", a1[12]);
strbuilder_printf(m_sb, "\"phaseAngleVoltageL3L1\": %.4f,", a1[13]);
strbuilder_printf(m_sb, "\"phaseAngleCurrentVoltageL1\": %.4f,", a1[14]);
strbuilder_printf(m_sb, "\"phaseAngleCurrentVoltageL2\": %.4f,", a1[15]);
strbuilder_printf(m_sb, "\"phaseAngleCurrentVoltageL3\": %.4f,\t", a1[16]);
v6 = *a1 >= 9.223372036854776e18 ? (unsigned int)(int)(*a1 - 9.223372036854776e18) ^ 0x8000000000000000LL : (unsigned __int64)(unsigned int)(int)*a1;
strbuilder_printf(m_sb, "\"createdOn\": %llu,\t", v6);
strbuilder_printf(m_sb, "\"smartMeterId\": 1,");
strbuilder_printf(m_sb, "\"smartMeterToken\": \"%s\"\t", (const char *)m_token);
strbuilder_printf(m_sb, "}}");
v7 = (void *)strbuilder_copy(m_sb);
if ( !(unsigned int)uploader_send(v7) )
{
if ( log_level > 0 )
log_message("smlogger.c", "processMeasurement", 1LL, "Unable to upload data\n");
free(v7);
}
}
++m_numMeasurements;
if ( m_numMeasurements == 60 * (m_numMeasurements / 60) && log_level > 1 )
{
v9 = uploader_queueSize();
log_message(
"smlogger.c",
"processMeasurement",
2LL,
"numMeasurements: %d, buffered: %d\n",
(unsigned int)m_numMeasurements,
v9);
}
result = (unsigned int)m_count;
if ( m_count > 0 && m_count <= m_numMeasurements )
{
if ( m_onboard )
result = fluksometer_stop();
else
result = smartmeter_stop();
}
return result;
}

original_code:
void processMeasurement(const SmartMeter_Data* m)
{
 if (!m_quiet) {
  if (m_smart) {
   for (SmartMeter_VarID id = 0; id < NUM_VARIABLES; id++) {
    if (m->val[id] != 0 && m->val[id] != -1) {
     printf("%s: %f; ", smartmeter_getVarName(id), m->val[id]);
    }
   }
   printf("\n");
  } else {
   for (SmartMeter_VarID id = 0; id < NUM_VARIABLES; id++) {
    printf("%f%c", m->val[id], id < NUM_VARIABLES-1 ? '\t' : '\n');
   }
  }
 }
 if (m_url) {
  strbuilder_reset(m_sb);
  strbuilder_printf(m_sb, "{\"measurement\":{");
  strbuilder_printf(m_sb, "\"powerAllPhases\": %.4f,	", m->val[POWER_ALL_PHASES]);
  strbuilder_printf(m_sb, "\"powerL1\": %.4f,", m->val[POWER_L1]);
  strbuilder_printf(m_sb, "\"powerL2\": %.4f,", m->val[POWER_L2]);
  strbuilder_printf(m_sb, "\"powerL3\": %.4f,", m->val[POWER_L3]);
  strbuilder_printf(m_sb, "\"currentNeutral\": %.4f,", m->val[CURRENT_NEUTRAL]);
  strbuilder_printf(m_sb, "\"currentL1\": %.4f,", m->val[CURRENT_L1]);
  strbuilder_printf(m_sb, "\"currentL2\": %.4f,", m->val[CURRENT_L2]);
  strbuilder_printf(m_sb, "\"currentL3\": %.4f,", m->val[CURRENT_L3]);
  strbuilder_printf(m_sb, "\"voltageL1\": %.4f,	", m->val[VOLTAGE_L1]);
  strbuilder_printf(m_sb, "\"voltageL2\": %.4f,", m->val[VOLTAGE_L2]);
  strbuilder_printf(m_sb, "\"voltageL3\": %.4f,", m->val[VOLTAGE_L3]);
  strbuilder_printf(m_sb, "\"phaseAngleVoltageL2L1\": %.4f,", m->val[PHASE_ANGLE_VOLTAGE_L2_L1]);
  strbuilder_printf(m_sb, "\"phaseAngleVoltageL3L1\": %.4f,", m->val[PHASE_ANGLE_VOLTAGE_L3_L1]);
  strbuilder_printf(m_sb, "\"phaseAngleCurrentVoltageL1\": %.4f,", m->val[PHASE_ANGLE_CURRENT_VOLTAGE_L1]);
  strbuilder_printf(m_sb, "\"phaseAngleCurrentVoltageL2\": %.4f,", m->val[PHASE_ANGLE_CURRENT_VOLTAGE_L2]);
  strbuilder_printf(m_sb, "\"phaseAngleCurrentVoltageL3\": %.4f,	", m->val[PHASE_ANGLE_CURRENT_VOLTAGE_L3]);
  strbuilder_printf(m_sb, "\"createdOn\": %llu,	", (uint64_t)m->val[TIMESTAMP]);
  strbuilder_printf(m_sb, "\"smartMeterId\": 1,");
  strbuilder_printf(m_sb, "\"smartMeterToken\": \"%s\"	", m_token);
  strbuilder_printf(m_sb, "}}");
  char* str = strbuilder_copy(m_sb);
  if (!uploader_send(str)) {
   if (1 <= log_level) log_message("smlogger.c", __func__, 1, "Unable to upload data\n");
   free(str);
  }
 }
 ++m_numMeasurements;
 if (m_numMeasurements % 60 == 0) {
  if (2 <= log_level) log_message("smlogger.c", __func__, 2, "numMeasurements: %d, buffered: %d\n", m_numMeasurements, uploader_queueSize());
 }
 if (m_count > 0 && m_numMeasurements >= m_count) {
  if (!m_onboard) {
   smartmeter_stop();
  } else {
   fluksometer_stop();
  }
 }
}

canonical_original_code:
void processMeasurement(struct SmartMeter_Data_s *m)
{
 if (!m_quiet) {
  if (m_smart) {
   for (enum SmartMeter_VarID id = 0; id < NUM_VARIABLES; id++) {
    if (m->val[id] != 0 && m->val[id] != -1) {
     printf("%s: %f; ", smartmeter_getVarName(id), m->val[id]);
    }
   }
   printf("\n");
  } else {
   for (enum SmartMeter_VarID id = 0; id < NUM_VARIABLES; id++) {
    printf("%f%c", m->val[id], id < NUM_VARIABLES-1 ? '\t' : '\n');
   }
  }
 }
 if (m_url) {
  strbuilder_reset(m_sb);
  strbuilder_printf(m_sb, "{\"measurement\":{");
  strbuilder_printf(m_sb, "\"powerAllPhases\": %.4f,	", m->val[POWER_ALL_PHASES]);
  strbuilder_printf(m_sb, "\"powerL1\": %.4f,", m->val[POWER_L1]);
  strbuilder_printf(m_sb, "\"powerL2\": %.4f,", m->val[POWER_L2]);
  strbuilder_printf(m_sb, "\"powerL3\": %.4f,", m->val[POWER_L3]);
  strbuilder_printf(m_sb, "\"currentNeutral\": %.4f,", m->val[CURRENT_NEUTRAL]);
  strbuilder_printf(m_sb, "\"currentL1\": %.4f,", m->val[CURRENT_L1]);
  strbuilder_printf(m_sb, "\"currentL2\": %.4f,", m->val[CURRENT_L2]);
  strbuilder_printf(m_sb, "\"currentL3\": %.4f,", m->val[CURRENT_L3]);
  strbuilder_printf(m_sb, "\"voltageL1\": %.4f,	", m->val[VOLTAGE_L1]);
  strbuilder_printf(m_sb, "\"voltageL2\": %.4f,", m->val[VOLTAGE_L2]);
  strbuilder_printf(m_sb, "\"voltageL3\": %.4f,", m->val[VOLTAGE_L3]);
  strbuilder_printf(m_sb, "\"phaseAngleVoltageL2L1\": %.4f,", m->val[PHASE_ANGLE_VOLTAGE_L2_L1]);
  strbuilder_printf(m_sb, "\"phaseAngleVoltageL3L1\": %.4f,", m->val[PHASE_ANGLE_VOLTAGE_L3_L1]);
  strbuilder_printf(m_sb, "\"phaseAngleCurrentVoltageL1\": %.4f,", m->val[PHASE_ANGLE_CURRENT_VOLTAGE_L1]);
  strbuilder_printf(m_sb, "\"phaseAngleCurrentVoltageL2\": %.4f,", m->val[PHASE_ANGLE_CURRENT_VOLTAGE_L2]);
  strbuilder_printf(m_sb, "\"phaseAngleCurrentVoltageL3\": %.4f,	", m->val[PHASE_ANGLE_CURRENT_VOLTAGE_L3]);
  strbuilder_printf(m_sb, "\"createdOn\": %llu,	", (unsigned long)m->val[TIMESTAMP]);
  strbuilder_printf(m_sb, "\"smartMeterId\": 1,");
  strbuilder_printf(m_sb, "\"smartMeterToken\": \"%s\"	", m_token);
  strbuilder_printf(m_sb, "}}");
  char *str = strbuilder_copy(m_sb);
  if (!uploader_send(str)) {
   if (1 <= log_level) log_message("smlogger.c", __func__, 1, "Unable to upload data\n");
   free(str);
  }
 }
 ++m_numMeasurements;
 if (m_numMeasurements % 60 == 0) {
  if (2 <= log_level) log_message("smlogger.c", __func__, 2, "numMeasurements: %d, buffered: %d\n", m_numMeasurements, uploader_queueSize());
 }
 if (m_count > 0 && m_numMeasurements >= m_count) {
  if (!m_onboard) {
   smartmeter_stop();
  } else {
   fluksometer_stop();
  }
 }
}

variable_types: struct SmartMeter_Data_s { double val[-1]; } *

variable_types: enum SmartMeter_VarID { INVALID_VARIABLE=-1, TIMESTAMP=0, POWER_ALL_PHASES=1, POWER_L1=2, POWER_L2=3, POWER_L3=4, CURRENT_NEUTRAL=5, CURRENT_L1=6, CURRENT_L2=7, CURRENT_L3=8, VOLTAGE_L1=9, VOLTAGE_L2=10, VOLTAGE_L3=11, PHASE_ANGLE_VOLTAGE_L2_L1=12, PHASE_ANGLE_VOLTAGE_L3_L1=13, PHASE_ANGLE_CURRENT_VOLTAGE_L1=14, PHASE_ANGLE_CURRENT_VOLTAGE_L2=15, PHASE_ANGLE_CURRENT_VOLTAGE_L3=16, NUM_VARIABLES=17 }

variable_types:
str
char *


main

decompiled_code:
int __cdecl main(int argc, const char **argv, const char **envp)
{
int result; // eax
const char *v4; // rax
const char *v5; // rax
const char *v6; // rax
unsigned int v7; // ebp
__int64 v8; // rbx
__int64 v9; // rax
__int64 v10; // rax
const char *v11; // rax
unsigned int v12; // ebx
const char *v13; // rax
int v14; // eax
int v15; // ebx
unsigned int i; // ebp
const char *v17; // rax

if ( !(unsigned int)args_parse(args, (unsigned int)argc, argv) || args_value(args, "help") )
{
args_printUsage(args, *argv);
args_printInfo(args);
return 0;
}
v4 = (const char *)args_value(args, "verbose");
log_level = atoi(v4);
v5 = (const char *)args_value(args, "count");
m_count = atoi(v5);
v6 = (const char *)args_value(args, "interval");
m_interval = atoi(v6);
m_smart = args_value(args, "smart") != 0;
m_quiet = args_value(args, "quiet") != 0;
m_token = args_value(args, "token");
m_url = args_value(args, "url");
m_onboard = args_value(args, "onboard") != 0;
io_init();
if ( m_onboard )
{
v10 = args_value(args, "address");
if ( !(unsigned int)fluksometer_init(v10, processMeasurement) )
{
puts("Failed to initialize onboard sensors");
return 1;
}
}
else
{
v7 = m_interval;
v8 = args_value(args, "port");
v9 = args_value(args, "address");
if ( !(unsigned int)smartmeter_init(v9, v8, v7, processMeasurement) )
{
puts("Failed to initialize Smart Meter");
return 1;
}
if ( !m_token )
m_token = smartmeter_address();
}
if ( !m_url )
goto LABEL_13;
m_sb = strbuilder_create();
if ( !m_sb )
{
puts("Failed to create string builder");
return 1;
}
v11 = (const char *)args_value(args, "upload_threads");
v12 = atoi(v11);
v13 = (const char *)args_value(args, "buffer_size");
v14 = atoi(v13);
if ( !(unsigned int)uploader_init(m_url, m_token, v14, v12) )
{
puts("Failed to initialize uploader module");
result = 1;
}
else
{
LABEL_13:
v15 = m_smart | m_quiet;
if ( !(m_smart | m_quiet) )
{
putchar(35);
for ( i = 9; ; i = (v15 >= 16) + 9 )
{
v17 = (const char *)smartmeter_getVarName((unsigned int)v15);
printf("%s%c", v17, i);
if ( ++v15 > 16 )
break;
}
}
if ( m_count )
{
if ( m_onboard )
{
fluksometer_start();
fluksometer_join();
}
else
{
smartmeter_start();
smartmeter_join();
}
}
if ( m_url )
{
uploader_cleanup();
strbuilder_free(m_sb);
}
io_deinit();
result = 0;
}
return result;
}

original_code:
int main(int argc, char **argv)
{
 if (!args_parse(args, argc, argv) || args_value(args, "help")) {
  args_printUsage(args, argv[0]);
  args_printInfo(args);
  return 0;
 }
 log_level = atoi(args_value(args, "verbose"));
 m_count = atoi(args_value(args, "count"));
 m_interval = atoi(args_value(args, "interval"));
 m_smart = args_value(args, "smart") != ((void *)0);
 m_quiet = args_value(args, "quiet") != ((void *)0);
 m_token = args_value(args, "token");
 m_url = args_value(args, "url");
 m_onboard = args_value(args, "onboard") != ((void *)0);
 io_init();
 if (!m_onboard) {
  int init = smartmeter_init(
   args_value(args, "address"),
   args_value(args, "port"),
   m_interval,
   processMeasurement);
  if (!init) {
   printf("Failed to initialize Smart Meter\n");
   return 1;
  }
  if (!m_token) {
   m_token = smartmeter_address();
  }
 } else {
  int init = fluksometer_init(args_value(args, "address"), processMeasurement);
  if (!init) {
   printf("Failed to initialize onboard sensors\n");
   return 1;
  }
 }
 if (m_url) {
  m_sb = strbuilder_create();
  if (!m_sb) {
   printf("Failed to create string builder\n");
   return 1;
  }
  if (!uploader_init(m_url, m_token,
   atoi(args_value(args, "buffer_size")),
   atoi(args_value(args, "upload_threads"))))
  {
   printf("Failed to initialize uploader module\n");
   return 1;
  }
 }
 if (!m_quiet && !m_smart) {
  printf("#");
  for (SmartMeter_VarID id = 0; id < NUM_VARIABLES; id++) {
   printf("%s%c", smartmeter_getVarName(id), id < NUM_VARIABLES-1 ? '\t' : '\n');
  }
 }
 if (m_count != 0) {
  if (!m_onboard) {
   smartmeter_start();
   smartmeter_join();
  } else {
   fluksometer_start();
   fluksometer_join();
  }
 }
 if (m_url) {
  uploader_cleanup();
  strbuilder_free(m_sb);
 }
 io_deinit();
 return 0;
}

canonical_original_code:
int main(int argc, char **argv)
{
 if (!args_parse(args, argc, argv) || args_value(args, "help")) {
  args_printUsage(args, argv[0]);
  args_printInfo(args);
  return 0;
 }
 log_level = atoi(args_value(args, "verbose"));
 m_count = atoi(args_value(args, "count"));
 m_interval = atoi(args_value(args, "interval"));
 m_smart = args_value(args, "smart") != ((void *)0);
 m_quiet = args_value(args, "quiet") != ((void *)0);
 m_token = args_value(args, "token");
 m_url = args_value(args, "url");
 m_onboard = args_value(args, "onboard") != ((void *)0);
 io_init();
 if (!m_onboard) {
  int init = smartmeter_init(
   args_value(args, "address"),
   args_value(args, "port"),
   m_interval,
   processMeasurement);
  if (!init) {
   printf("Failed to initialize Smart Meter\n");
   return 1;
  }
  if (!m_token) {
   m_token = smartmeter_address();
  }
 } else {
  int init = fluksometer_init(args_value(args, "address"), processMeasurement);
  if (!init) {
   printf("Failed to initialize onboard sensors\n");
   return 1;
  }
 }
 if (m_url) {
  m_sb = strbuilder_create();
  if (!m_sb) {
   printf("Failed to create string builder\n");
   return 1;
  }
  if (!uploader_init(m_url, m_token,
   atoi(args_value(args, "buffer_size")),
   atoi(args_value(args, "upload_threads"))))
  {
   printf("Failed to initialize uploader module\n");
   return 1;
  }
 }
 if (!m_quiet && !m_smart) {
  printf("#");
  for (enum SmartMeter_VarID id = 0; id < NUM_VARIABLES; id++) {
   printf("%s%c", smartmeter_getVarName(id), id < NUM_VARIABLES-1 ? '\t' : '\n');
  }
 }
 if (m_count != 0) {
  if (!m_onboard) {
   smartmeter_start();
   smartmeter_join();
  } else {
   fluksometer_start();
   fluksometer_join();
  }
 }
 if (m_url) {
  uploader_cleanup();
  strbuilder_free(m_sb);
 }
 io_deinit();
 return 0;
}

variable_types: argc int

variable_types:
argv
char **

variable_types: init int

user_defined_types: enum SmartMeter_VarID { INVALID_VARIABLE=-1, TIMESTAMP=0, POWER_ALL_PHASES=1, POWER_L1=2, POWER_L2=3, POWER_L3=4, CURRENT_NEUTRAL=5, CURRENT_L1=6, CURRENT_L2=7, CURRENT_L3=8, VOLTAGE_L1=9, VOLTAGE_L2=10, VOLTAGE_L3=11, PHASE_ANGLE_VOLTAGE_L2_L1=12, PHASE_ANGLE_VOLTAGE_L3_L1=13, PHASE_ANGLE_CURRENT_VOLTAGE_L1=14, PHASE_ANGLE_CURRENT_VOLTAGE_L2=15, PHASE_ANGLE_CURRENT_VOLTAGE_L3=16, NUM_VARIABLES=17 }


decompiled_code:
__int64 __fastcall ip_fromStr(void *buf, const char *a2)
{
unsigned int v2; // eax
unsigned int v3; // ebx

v2 = inet_pton(2, a2, buf);
v3 = v2;
if ( v2 )
{
if ( v2 != 1 )
{
if ( v2 == -1 )
{
v3 = 0;
if ( log_level >= 0 )
log_message("pylon/ip.c", "ip_fromStr", 0LL, "Invalid address family\n");
}
else
{
if ( log_level >= 0 )
log_message("pylon/ip.c", "ip_fromStr", 0LL, "inet_pton returned %d\n", v2);
v3 = 0;
}
}
}
else if ( log_level > 0 )
{
log_message("pylon/ip.c", "ip_fromStr", 1LL, "Invalid network address: %s\n", a2);
}
return v3;
}

canonical_decompiled_code:
__int64 __fastcall func0(void *buf, const char *a2)
{
unsigned int v2; // eax
unsigned int v3; // ebx

v2 = inet_pton(2, a2, buf);
v3 = v2;
if ( v2 )
{
if ( v2 != 1 )
{
if ( v2 == -1 )
{
v3 = 0;
if ( log_level >= 0 )
log_message("pylon/ip.c", "ip_fromStr", 0LL, "Invalid address family\n");
}
else
{
if ( log_level >= 0 )
log_message("pylon/ip.c", "ip_fromStr", 0LL, "inet_pton returned %d\n", v2);
v3 = 0;
}
}
}
else if ( log_level > 0 )
{
log_message("pylon/ip.c", "ip_fromStr", 1LL, "Invalid network address: %s\n", a2);
}
return v3;
}

original_code:
int ip_fromStr(IP_Address* ip, const char* str)
{
 int ret = inet_pton(2, str, ip);
 switch (ret) {
 case 1:
  return 1;
 case 0:
  if (1 <= log_level) log_message("pylon/ip.c", __func__, 1, "Invalid network address: %s\n", str);
  return 0;
 case -1:
  if (0 <= log_level) log_message("pylon/ip.c", __func__, 0, "Invalid address family\n");
  return 0;
 default:
  if (0 <= log_level) log_message("pylon/ip.c", __func__, 0, "inet_pton returned %d\n", ret);
  return 0;
 }
}

canonical_original_code:
int ip_fromStr(struct in_addr *ip, char *str)
{
 int ret = inet_pton(2, str, ip);
 switch (ret) {
 case 1:
  return 1;
 case 0:
  if (1 <= log_level) log_message("pylon/ip.c", __func__, 1, "Invalid network address: %s\n", str);
  return 0;
 case -1:
  if (0 <= log_level) log_message("pylon/ip.c", __func__, 0, "Invalid address family\n");
  return 0;
 default:
  if (0 <= log_level) log_message("pylon/ip.c", __func__, 0, "inet_pton returned %d\n", ret);
  return 0;
 }
}

variable_types: struct in_addr { unsigned int s_addr; } *

variable_types: ret int


decompiled_code:
__int64 __fastcall ip_toStr(void *cp, char *buf, socklen_t len)
{
const char *v3; // rdx
__int64 result; // rax
int *v5; // rax
char *v6; // rax

v3 = inet_ntop(2, cp, buf, len);
result = 1LL;
if ( !v3 )
{
result = 0LL;
if ( log_level >= 0 )
{
v5 = _errno_location();
v6 = strerror(*v5);
log_message("pylon/ip.c", "ip_toStr", 0LL, "inet_ntop: %s\n", v6);
result = 0LL;
}
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(void *cp, char *buf, socklen_t len)
{
const char *v3; // rdx
__int64 result; // rax
int *v5; // rax
char *v6; // rax

v3 = inet_ntop(2, cp, buf, len);
result = 1LL;
if ( !v3 )
{
result = 0LL;
if ( log_level >= 0 )
{
v5 = _errno_location();
v6 = strerror(*v5);
log_message("pylon/ip.c", "ip_toStr", 0LL, "inet_ntop: %s\n", v6);
result = 0LL;
}
}
return result;
}

original_code:
int ip_toStr(const IP_Address* ip, char* buffer, size_t size)
{
 if (!inet_ntop(2, ip, buffer, size)) {
  if (0 <= log_level) log_message("pylon/ip.c", __func__, 0, "inet_ntop: %s\n", strerror((*__errno_location ())));
  return 0;
 }
 return 1;
}

canonical_original_code:
int ip_toStr(struct in_addr *ip, char *buffer, unsigned long size)
{
 if (!inet_ntop(2, ip, buffer, size)) {
  if (0 <= log_level) log_message("pylon/ip.c", __func__, 0, "inet_ntop: %s\n", strerror((*__errno_location ())));
  return 0;
 }
 return 1;
}

variable_types:
buffer
char *

variable_types:
size
unsigned long


decompiled_code:
_BOOL8 __fastcall mac_fromStr(__int64 a1, const char *a2)
{
return sscanf(a2, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", a1, a1 + 1, a1 + 2, a1 + 3, a1 + 4, a1 + 5) == 6;
}

original_code:
int mac_fromStr(MAC_Address* mac, const char* str)
{
 int cnt = sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
  &mac->raw[0],&mac->raw[1],&mac->raw[2],&mac->raw[3],&mac->raw[4],&mac->raw[5]);
 return cnt == sizeof(mac->raw);
}

canonical_original_code:
int mac_fromStr(union MAC_Address_s *mac, char *str)
{
 int cnt = sscanf(str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
  &mac->raw[0],&mac->raw[1],&mac->raw[2],&mac->raw[3],&mac->raw[4],&mac->raw[5]);
 return cnt == sizeof(mac->raw);
}

variable_types: union MAC_Address_s { unsigned char raw[6]; struct { unsigned char vendor[3]; unsigned char serial[3]; } fields; } *

variable_types: cnt int


decompiled_code:
__int64 __fastcall mac_toStr(unsigned __int8 *a1, char *a2, size_t a3)
{
snprintf(a2, a3, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", *a1, a1[1], a1[2], a1[3], a1[4], a1[5]);
return 1LL;
}

original_code:
int mac_toStr(const MAC_Address* mac, char* buffer, size_t size)
{
 snprintf(buffer, size, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
  mac->raw[0],mac->raw[1],mac->raw[2],mac->raw[3],mac->raw[4],mac->raw[5]);
 return 1;
}

canonical_original_code:
int mac_toStr(union MAC_Address_s *mac, char *buffer, unsigned long size)
{
 snprintf(buffer, size, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
  mac->raw[0],mac->raw[1],mac->raw[2],mac->raw[3],mac->raw[4],mac->raw[5]);
 return 1;
}

user_defined_types: union MAC_Address_s { unsigned char raw[6]; struct { unsigned char vendor[3]; unsigned char serial[3]; } fields; }


decompiled_code:
_BOOL8 __fastcall mac_isValid(const char *a1)
{
char v2[14]; // [rsp+Ah] [rbp-Eh] BYREF

return mac_fromStr((__int64)v2, a1);
}

canonical_decompiled_code:
_BOOL8 __fastcall func4(const char *a1)
{
char v2[14]; // [rsp+Ah] [rbp-Eh] BYREF

return func2((__int64)v2, a1);
}

original_code:
int mac_isValid(const char* str)
{
 MAC_Address mac;
 return mac_fromStr(&mac, str);
}

canonical_original_code:
int mac_isValid(char *str)
{
 union MAC_Address_s mac;
 return mac_fromStr(&mac, str);
}

variable_types: union MAC_Address_s { unsigned char raw[6]; struct { unsigned char vendor[3]; unsigned char serial[3]; } fields; }


matches

decompiled_code:
_BOOL8 __fastcall matches(char *a1, _BYTE *a2)
{
char v2; // al

v2 = *a1;
if ( !*a1 )
return *a2 == 0;
while ( v2 == 35 || *a2 == v2 )
{
++a1;
++a2;
v2 = *a1;
if ( !*a1 )
return *a2 == 0;
}
return 0LL;
}

original_code:
int matches(const char* fmt, const char* str)
{
 while (*fmt) {
  if (*fmt != '#' && *str != *fmt) return 0;
  ++fmt;
  ++str;
 }
 return !*str;
}

canonical_original_code:
int matches(char *fmt, char *str)
{
 while (*fmt) {
  if (*fmt != '#' && *str != *fmt) return 0;
  ++fmt;
  ++str;
 }
 return !*str;
}

variable_types:
fmt
char *