// File: AndreRenaud[P]simple_uart/simple_uart.c
// Function: simple_uart_list
ssize_t simple_uart_list(char ***namesp)
{
#if defined(__linux__) || defined(__APPLE__)
    glob_t g;
    char **names = NULL;
    size_t count = 0;

#ifdef __linux__
    char *path_globs[] = {"/sys/class/tty/ttyS[0-9]*", "/dev/ttyUSB*", "/dev/ttyACM*"};
#endif

#ifdef __APPLE__
    char *path_globs[] = {"/dev/tty.*"};
#endif

    for (size_t path = 0; path < sizeof(path_globs) / sizeof(path_globs[0]); path++) {
        if (glob(path_globs[path], 0, NULL, &g) >= 0) {
            char buffer[100];
            char **new_names;
            if ((count + g.gl_pathc) > SSIZE_MAX) {
                globfree(&g);
                break; // abort to avoid memory leakage
            }
            new_names = realloc(names, (count + g.gl_pathc) * sizeof(char *));
            if (!new_names) {
                /* Free previously allocated strings to prevent memory leak */
                for (size_t j = 0; j < count; j++) {
                    free(names[j]);
                }
                free(names);
                globfree(&g);
                return -ENOMEM;
            }
            names = new_names;
            for (size_t i = count; i < count + g.gl_pathc; i++) {
                /* Use snprintf to prevent buffer overflow */
                snprintf(buffer, sizeof(buffer), "/dev/%s", basename(g.gl_pathv[i - count]));
                names[i] = strdup(buffer);
                if (!names[i]) {
                    /* Handle strdup failure */
                    for (size_t j = 0; j < i; j++) {
                        free(names[j]);
                    }
                    free(names);
                    globfree(&g);
                    return -ENOMEM;
                }
            }
            count += g.gl_pathc;
            globfree(&g);
        }
    }
    *namesp = names;
    return (ssize_t)count;

#else
    int pos = 0;
    char **names = NULL;

    for (int i = 0; i < 255; i++) {
        char buffer[10];
        char target[255];
        sprintf(buffer, "COM%d", i + 1);
        if (QueryDosDevice(buffer, target, sizeof(target)) > 0) {
            char **new_names = realloc(names, (DWORD)(pos + 1) * sizeof(char *));
            if (!new_names)
                continue;
            names = new_names;
            names[pos] = malloc(strlen(buffer) + 1);
            if (!names[pos]) {
                continue;
            }
            strcpy(names[pos], buffer);
            pos++;
        }
    }
    *namesp = names;
    return pos;
#endif
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x10(%rbp)
movq $0x0, -0x60(%rbp)
movq $0x0, -0x68(%rbp)
movq 0x59da(%rip), %rax      # 0xcdd0
movq %rax, -0x80(%rbp)
movq 0x59d7(%rip), %rax      # 0xcdd8
movq %rax, -0x78(%rbp)
movq 0x59d4(%rip), %rax      # 0xcde0
movq %rax, -0x70(%rbp)
movq $0x0, -0x88(%rbp)
cmpq $0x3, -0x88(%rbp)
jae 0x763e
movq -0x88(%rbp), %rax
movq -0x80(%rbp,%rax,8), %rdi
xorl %esi, %esi
xorl %eax, %eax
movl %eax, %edx
leaq -0x58(%rbp), %rcx
callq 0x2350
cmpl $0x0, %eax
jl 0x7625
movq -0x68(%rbp), %rax
addq -0x58(%rbp), %rax
movabsq $0x7fffffffffffffff, %rcx # imm = 0x7FFFFFFFFFFFFFFF
cmpq %rcx, %rax
jbe 0x7472
leaq -0x58(%rbp), %rdi
callq 0x2030
jmp 0x763e
movq -0x60(%rbp), %rdi
movq -0x68(%rbp), %rsi
addq -0x58(%rbp), %rsi
shlq $0x3, %rsi
callq 0x22b0
movq %rax, -0xf8(%rbp)
cmpq $0x0, -0xf8(%rbp)
jne 0x74f7
movq $0x0, -0x100(%rbp)
movq -0x100(%rbp), %rax
cmpq -0x68(%rbp), %rax
jae 0x74d8
movq -0x60(%rbp), %rax
movq -0x100(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x2040
movq -0x100(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x100(%rbp)
jmp 0x74a3
movq -0x60(%rbp), %rdi
callq 0x2040
leaq -0x58(%rbp), %rdi
callq 0x2030
movq $-0xc, -0x8(%rbp)
jmp 0x7651
movq -0xf8(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x68(%rbp), %rax
movq %rax, -0x108(%rbp)
movq -0x108(%rbp), %rax
movq -0x68(%rbp), %rcx
addq -0x58(%rbp), %rcx
cmpq %rcx, %rax
jae 0x7610
leaq -0xf0(%rbp), %rax
movq %rax, -0x118(%rbp)
movq -0x50(%rbp), %rax
movq -0x108(%rbp), %rcx
subq -0x68(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x2260
movq -0x118(%rbp), %rdi
movq %rax, %rcx
movl $0x64, %esi
leaq 0x2ddf(%rip), %rdx      # 0xa340
movb $0x0, %al
callq 0x2170
leaq -0xf0(%rbp), %rdi
callq 0x2380
movq %rax, %rdx
movq -0x60(%rbp), %rax
movq -0x108(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x60(%rbp), %rax
movq -0x108(%rbp), %rcx
cmpq $0x0, (%rax,%rcx,8)
jne 0x75f7
movq $0x0, -0x110(%rbp)
movq -0x110(%rbp), %rax
cmpq -0x108(%rbp), %rax
jae 0x75db
movq -0x60(%rbp), %rax
movq -0x110(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x2040
movq -0x110(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x110(%rbp)
jmp 0x75a3
movq -0x60(%rbp), %rdi
callq 0x2040
leaq -0x58(%rbp), %rdi
callq 0x2030
movq $-0xc, -0x8(%rbp)
jmp 0x7651
jmp 0x75f9
movq -0x108(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x108(%rbp)
jmp 0x750d
movq -0x58(%rbp), %rax
addq -0x68(%rbp), %rax
movq %rax, -0x68(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x2030
jmp 0x7627
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
jmp 0x741b
movq -0x60(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
movq -0x68(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
nop