// File: /workspace/github_cpp_makefile_star2_O2/AndreRenaud[P]simple_uart/simple_uart_term.c
// Function: main
int main(int argc, char *argv[])
{
    const char *port = NULL;
    int baudrate;
    const char *flags = "8N1";
    int opt;

    while ((opt = getopt(argc, argv, "p:b:f:lh")) != -1) {
        switch (opt) {
        case 'p': port = optarg; break;
        case 'b': baudrate = atoi(optarg); break;
        case 'f': flags = optarg; break;
        case 'l': {
            char **names;
            ssize_t nuarts = simple_uart_list(&names);
            printf("Found %zd ports\n", nuarts);
            for (ssize_t i = 0; i < nuarts; i++) {
                printf("Port %zd: %s\n", i, names[i]);
            }

            for (ssize_t i = 0; i < nuarts; i++) {
                if (names[i])
                    free(names[i]);
            }
            free(names);
            exit(0);
        }
        default:
        case 'h': print_usage(argv[0]); exit(1);
        }
    }

    if (!port) {
        print_usage(argv[0]);
        exit(1);
    }

    struct simple_uart *uart;

    uart = simple_uart_open(port, baudrate, flags);
    if (!uart) {
        fprintf(stderr, "Unable to open %s:%d:%s\n", port, baudrate, flags);
        exit(1);
    }

    /* Disable buffering on stdin */
    struct termios term;

    if (tcgetattr(STDIN_FILENO, &term)) {
        fprintf(stderr, "tcgetattr\n");
        exit(-1);
    }

    term.c_lflag &= ~(ICANON | ECHO);
    term.c_cc[VMIN] = 0;
    term.c_cc[VTIME] = 0;

    if (tcsetattr(STDIN_FILENO, TCSANOW, &term)) {
        fprintf(stderr, "tcsetattr\n");
        exit(-1);
    }

    while (1) {
        fd_set fds;
        int nfds = STDIN_FILENO;
        struct timeval tv = {1, 0};
        char buffer[128];

        /* Wait for bytes on either serial port or stdin */
        FD_ZERO(&fds);
        FD_SET(STDIN_FILENO, &fds);
        FD_SET(simple_uart_get_fd(uart), &fds);
        if (simple_uart_get_fd(uart) > nfds)
            nfds = simple_uart_get_fd(uart);

        select(nfds + 1, &fds, NULL, NULL, &tv);

        /* Move bytes from one to the other */
        if (FD_ISSET(STDIN_FILENO, &fds)) {
            int len = read(STDIN_FILENO, buffer, sizeof(buffer));
            if (len > 0)
                simple_uart_write(uart, buffer, len);
        }
        if (FD_ISSET(simple_uart_get_fd(uart), &fds)) {
            int len = simple_uart_read(uart, buffer, sizeof(buffer));
            if (len > 0)
                write(STDOUT_FILENO, buffer, len);
        }
    }

    simple_uart_close(uart);
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x168, %rsp            # imm = 0x168
movq %rsi, %rbx
movl %edi, %r12d
leaq 0x1c2a(%rip), %rax      # 0x4024
movq %rax, 0x8(%rsp)
xorl %r15d, %r15d
leaq 0x1c1f(%rip), %r13      # 0x4028
leaq 0x1bf4(%rip), %rbp      # 0x4004
movq 0x3bc1(%rip), %r14      # 0x5fd8
movl %r12d, %edi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x2250
cmpl $-0x1, %eax
je 0x245f
addl $-0x62, %eax
rorl %eax
cmpl $0x7, %eax
ja 0x25d3
movslq (%rbp,%rax,4), %rax
addq %rbp, %rax
jmpq *%rax
movq (%r14), %r15
jmp 0x2417
movq (%r14), %rax
movq %rax, 0x8(%rsp)
jmp 0x2417
movq (%r14), %rdi
callq 0x2260
movl %eax, 0x4(%rsp)
jmp 0x2417
testq %r15, %r15
je 0x25d3
movq %r15, %rdi
movl 0x4(%rsp), %ebp
movl %ebp, %esi
movq 0x8(%rsp), %r14
movq %r14, %rdx
callq 0x2914
testq %rax, %rax
je 0x265c
movq %rax, %rbx
leaq 0xa4(%rsp), %rsi
xorl %edi, %edi
callq 0x2200
testl %eax, %eax
jne 0x2681
leaq 0xa4(%rsp), %rdx
andb $-0xb, 0xc(%rdx)
andw $0x0, 0x16(%rdx)
xorl %edi, %edi
xorl %esi, %esi
callq 0x2210
testl %eax, %eax
jne 0x2694
pushq $0x40
popq %r13
pushq $0x1
popq %rbp
leaq 0x10(%rsp), %r15
leaq 0xe0(%rsp), %r12
movups 0x1bd2(%rip), %xmm0     # 0x40b0
movaps %xmm0, 0x10(%rsp)
xorl %eax, %eax
cmpq $0x10, %rax
je 0x24f6
andq $0x0, 0x20(%rsp,%rax,8)
incq %rax
jmp 0x24e5
orb $0x1, 0x20(%rsp)
movq %rbx, %rdi
callq 0x3694
cltd
idivl %r13d
movl %edx, %ecx
pushq $0x1
popq %r14
shlq %cl, %r14
movq %rbx, %rdi
callq 0x3694
cltd
idivl %r13d
cltq
orq %r14, 0x20(%rsp,%rax,8)
movq %rbx, %rdi
callq 0x3694
movl %ebp, %edi
testl %eax, %eax
jle 0x253d
movq %rbx, %rdi
callq 0x3694
movl %eax, %edi
incl %edi
leaq 0x20(%rsp), %rsi
xorl %edx, %edx
xorl %ecx, %ecx
movq %r15, %r8
callq 0x21d0
testb $0x1, 0x20(%rsp)
je 0x257b
movl $0x80, %edx
xorl %edi, %edi
movq %r12, %rsi
callq 0x2160
testl %eax, %eax
jle 0x257b
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movq %rbx, %rdi
movq %r12, %rsi
movq %rax, %rdx
callq 0x2810
movq %rbx, %rdi
callq 0x3694
cltd
idivl %r13d
cltq
movq 0x20(%rsp,%rax,8), %r14
movq %rbx, %rdi
callq 0x3694
cltd
idivl %r13d
btq %rdx, %r14
jae 0x24d7
movl $0x80, %edx
movq %rbx, %rdi
movq %r12, %rsi
callq 0x26d4
testl %eax, %eax
jle 0x24d7
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movl %ebp, %edi
movq %r12, %rsi
movq %rax, %rdx
callq 0x20b0
jmp 0x24d7
movq (%rbx), %rdi
callq 0x26b7
pushq $0x1
popq %rdi
callq 0x2280
leaq 0x20(%rsp), %rdi
callq 0x2eec
movq %rax, %rbx
leaq 0x1a3a(%rip), %rdi      # 0x4031
xorl %r14d, %r14d
movq %rax, %rsi
xorl %eax, %eax
callq 0x2120
testq %rbx, %rbx
cmovleq %r14, %rbx
leaq 0x1a30(%rip), %r14      # 0x4042
xorl %r15d, %r15d
cmpq %r15, %rbx
je 0x2635
movq 0x20(%rsp), %rax
movq (%rax,%r15,8), %rdx
movq %r14, %rdi
movq %r15, %rsi
xorl %eax, %eax
callq 0x2120
incq %r15
jmp 0x2615
xorl %r14d, %r14d
movq 0x20(%rsp), %rdi
cmpq %r14, %rbx
je 0x2650
movq (%rdi,%r14,8), %rdi
callq 0x2040
incq %r14
jmp 0x2638
callq 0x2040
xorl %edi, %edi
callq 0x2280
movq 0x3995(%rip), %rax      # 0x5ff8
movq (%rax), %rdi
leaq 0x19e3(%rip), %rsi      # 0x4050
movq %r15, %rdx
movl %ebp, %ecx
movq %r14, %r8
xorl %eax, %eax
callq 0x21a0
jmp 0x25db
movq 0x3970(%rip), %rax      # 0x5ff8
movq (%rax), %rcx
leaq 0x19d7(%rip), %rdi      # 0x4069
jmp 0x26a5
movq 0x395d(%rip), %rax      # 0x5ff8
movq (%rax), %rcx
leaq 0x19cf(%rip), %rdi      # 0x4074
pushq $0xa
popq %rsi
pushq $0x1
popq %rdx
callq 0x2290
pushq $-0x1
jmp 0x25dd