// File: princelab[P]emass/getopt.cpp
// Function: getopt(int, char**, char const*)
int getopt(int argc, char *argv[], const char *opts) {

    static int sp = 1;      // initialize and preserve from call to call

    if (sp == 1) {
        if ( 
               optind >= argc              // end of argv array
               || argv[optind][0] != '-'   // not an option
               || argv[optind][1] == '\0'  // - followed by whitespace
            )
            return -1;                     // argument processing done
        else if (strcmp(argv[optind], "--") == 0) {
            optind++;       // -- is end of options flag, go to next argv
            return -1;
        }
    }

    char c = (unsigned char) argv[optind][sp];   // char after -
    optopt = c;
    const char *cp;
    if (c == ':' || (cp = strchr(opts, c)) == NULL) {
        if (opterr) {
            cerr << argv[0] << error2 << c << endl;
        }
        if (argv[optind][++sp] == '\0') {
            optind++;
            sp = 1;
        }
        return '?';         // conventional return value for unknown option
    }

    if (*++cp == ':') {     // option which requires a value to follow
        if (argv[optind][sp+1] != '\0')    // value follows without whitespace
            optarg = &argv[optind++][sp+1];
        else if (++optind >= argc) {
            if (opterr) {
                cerr << argv[0] << error1 << c << endl;
            }
            sp = 1;
            return '?';
        } else
            optarg = argv[optind++];    // set next argv as option value
        sp = 1;
    } else {                // option which requires no value
        if (argv[optind][++sp] == '\0') {
            sp = 1;
            optind++;
        }
        optarg = NULL;      // set null pointer as option value
    }
    return c;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
cmpl $0x1, 0x9e0e(%rip)      # 0x1b3d8
jne 0x11655
movl 0x9dfa(%rip), %eax      # 0x1b3d0
cmpl -0x8(%rbp), %eax
jge 0x1160a
movq -0x10(%rbp), %rax
movslq 0x9dea(%rip), %rcx      # 0x1b3d0
movq (%rax,%rcx,8), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
jne 0x1160a
movq -0x10(%rbp), %rax
movslq 0x9dd3(%rip), %rcx      # 0x1b3d0
movq (%rax,%rcx,8), %rax
movsbl 0x1(%rax), %eax
cmpl $0x0, %eax
jne 0x11616
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x118a1
movq -0x10(%rbp), %rax
movslq 0x9daf(%rip), %rcx      # 0x1b3d0
movq (%rax,%rcx,8), %rdi
leaq 0xde6(%rip), %rsi       # 0x12412
callq 0x4510
cmpl $0x0, %eax
jne 0x11651
movl 0x9d94(%rip), %eax      # 0x1b3d0
addl $0x1, %eax
movl %eax, 0x9d8b(%rip)      # 0x1b3d0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x118a1
jmp 0x11653
jmp 0x11655
movq -0x10(%rbp), %rax
movslq 0x9d70(%rip), %rcx      # 0x1b3d0
movq (%rax,%rcx,8), %rax
movslq 0x9d6d(%rip), %rcx      # 0x1b3d8
movb (%rax,%rcx), %al
movb %al, -0x19(%rbp)
movsbl -0x19(%rbp), %eax
movl %eax, 0x9e29(%rip)      # 0x1b4a4
movsbl -0x19(%rbp), %eax
cmpl $0x3a, %eax
je 0x1169f
movq -0x18(%rbp), %rdi
movsbl -0x19(%rbp), %esi
callq 0x4100
movq %rax, -0x28(%rbp)
cmpq $0x0, %rax
jne 0x11734
cmpl $0x0, 0x9d2e(%rip)      # 0x1b3d4
je 0x116e5
movq -0x10(%rbp), %rax
movq (%rax), %rsi
movq 0x993a(%rip), %rdi      # 0x1aff0
callq 0x4370
movq %rax, %rdi
leaq 0x9d1b(%rip), %rsi      # 0x1b3e0
callq 0x4370
movq %rax, %rdi
movsbl -0x19(%rbp), %esi
callq 0x4450
movq %rax, %rdi
movq 0x98c8(%rip), %rsi      # 0x1afa8
callq 0x43d0
movq -0x10(%rbp), %rax
movslq 0x9ce0(%rip), %rcx      # 0x1b3d0
movq (%rax,%rcx,8), %rax
movl 0x9cde(%rip), %ecx      # 0x1b3d8
addl $0x1, %ecx
movl %ecx, 0x9cd5(%rip)      # 0x1b3d8
movslq %ecx, %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0x11728
movl 0x9cbb(%rip), %eax      # 0x1b3d0
addl $0x1, %eax
movl %eax, 0x9cb2(%rip)      # 0x1b3d0
movl $0x1, 0x9cb0(%rip)      # 0x1b3d8
movl $0x3f, -0x4(%rbp)
jmp 0x118a1
movq -0x28(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0x28(%rbp)
movsbl 0x1(%rax), %eax
cmpl $0x3a, %eax
jne 0x1184c
movq -0x10(%rbp), %rax
movslq 0x9c75(%rip), %rcx      # 0x1b3d0
movq (%rax,%rcx,8), %rax
movl 0x9c73(%rip), %ecx      # 0x1b3d8
addl $0x1, %ecx
movslq %ecx, %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
je 0x117ab
movq -0x10(%rbp), %rax
movl 0x9c52(%rip), %ecx      # 0x1b3d0
movl %ecx, %edx
addl $0x1, %edx
movl %edx, 0x9c47(%rip)      # 0x1b3d0
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movl 0x9c42(%rip), %ecx      # 0x1b3d8
addl $0x1, %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, 0x9d02(%rip)      # 0x1b4a8
jmp 0x11840
movl 0x9c1f(%rip), %eax      # 0x1b3d0
addl $0x1, %eax
movl %eax, 0x9c16(%rip)      # 0x1b3d0
cmpl -0x8(%rbp), %eax
jl 0x1181b
cmpl $0x0, 0x9c0e(%rip)      # 0x1b3d4
je 0x11805
movq -0x10(%rbp), %rax
movq (%rax), %rsi
movq 0x981a(%rip), %rdi      # 0x1aff0
callq 0x4370
movq %rax, %rdi
leaq 0x9c1b(%rip), %rsi      # 0x1b400
callq 0x4370
movq %rax, %rdi
movsbl -0x19(%rbp), %esi
callq 0x4450
movq %rax, %rdi
movq 0x97a8(%rip), %rsi      # 0x1afa8
callq 0x43d0
movl $0x1, 0x9bc9(%rip)      # 0x1b3d8
movl $0x3f, -0x4(%rbp)
jmp 0x118a1
movq -0x10(%rbp), %rax
movl 0x9bab(%rip), %ecx      # 0x1b3d0
movl %ecx, %edx
addl $0x1, %edx
movl %edx, 0x9ba0(%rip)      # 0x1b3d0
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x9c6a(%rip)      # 0x1b4a8
jmp 0x11840
movl $0x1, 0x9b8e(%rip)      # 0x1b3d8
jmp 0x1189a
movq -0x10(%rbp), %rax
movslq 0x9b79(%rip), %rcx      # 0x1b3d0
movq (%rax,%rcx,8), %rax
movl 0x9b77(%rip), %ecx      # 0x1b3d8
addl $0x1, %ecx
movl %ecx, 0x9b6e(%rip)      # 0x1b3d8
movslq %ecx, %rcx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0x1188f
movl $0x1, 0x9b58(%rip)      # 0x1b3d8
movl 0x9b4a(%rip), %eax      # 0x1b3d0
addl $0x1, %eax
movl %eax, 0x9b41(%rip)      # 0x1b3d0
movq $0x0, 0x9c0e(%rip) # 0x1b4a8
movsbl -0x19(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq