// File: mgo1977[P]c---parsing-argument-options/./Parser.h
// Function: Parser::parse[abi:cxx11](int, char**)
std::vector<std::string>
Parser::parse(int argc, char** argv) {

    std::vector<std::string> otherArguments;

    // first argument is the program name
    if ( argc >= 1 )
        programName = argv[0];

    // now, start iterating over each argument
    for(int argNumber=1; argNumber < argc; ++argNumber) {

        std::string argument = argv[argNumber];

        // arguments start with "-"
        // if not, push it into "other inputs"
        if ( argument.empty() )
            continue;

        if ( argument[0] != '-' ) {
            // add it as other argument and continue with the next arg
            otherArguments.push_back( argument );
            continue;        
        }

        // this is a malformed argument:
        // "-"
        if ( argument.length() < 2 ) {
            std::stringstream error;
            error << "Malformed argument! (see arg number " << argNumber << ")";
            usage(error.str());
        }

        BaseOption* option = NULL;

        std::string possibleValue;

        // now, if the next char is a '-' it's a long option,
        // if not, it's a short one
        if ( argument[1] != '-' ) {

            option = findOption(argument[1]);

            // this looks like a short option, so let's check if there
            // are no more chars here, then we pick the value from here
            if ( argument.length() > 2 ) {
                possibleValue = argument.substr(2);
            }


        }
        else {
            
            // this looks like a long option, so let's check if there
            // are no more chars here, if not, that's malformed
            if ( argument.length() < 3 ) {
                std::stringstream error;
                error << "Malformed argument! (see arg number " << argNumber << ")";
                usage(error.str());
            }

            // let's allow the separation between key and value by '='
            // on long options
            std::string optionAndValueStr = argument.substr(2);

            // initially we suppose there is no value
            std::string optionStr = optionAndValueStr;

            int separator = optionStr.find('=');

            if ( separator != std::string::npos ) {
                optionStr     = optionAndValueStr.substr(0, separator);
                possibleValue = optionAndValueStr.substr(separator+1);
            }

            option = findOption( optionStr );

        }

        if ( option == NULL ) {
            std::stringstream error;
            error << "Unknown option '" << argument << "' (see arg number " << argNumber << ")";
            usage(error.str());
        }

        // let's see if this needs an argument
        if ( option->needArgument() ) {

            if ( possibleValue.empty() ) {

                // try to get the next one or fail
                if ( argNumber+1 < argc ) {

                    // let's move to the next argument
                    argNumber++;

                    option->setValue( argv[argNumber] );

                }
                else {
                    std::stringstream error;
                    error << "Option '" << argument << "' needs an additional argument";
                    usage(error.str());
                }

            }
            else {
                // the value we got directly from the option:
                //   --key=value or -kvalue
                option->setValue( possibleValue.c_str() );
            }

        }
        else {
            // set as read
            option->markAsFound();
        }

    }

    // now, let's do some basic checking

    // was the help option requested?
    if ( helpOption.isSet() ) {
        usage();
    }

    // let's go thru all the options to get all the
    // ones that are mandatories and that weren't
    // set
   
    std::string mandatoriesError; 

    for(std::vector<BaseOption*>::iterator iter = options.begin();
        iter != options.end();
        ++iter
    ) {

        BaseOption* option = *iter;

        if ( option->isMandatory() && !option->isSet() ) {

            if ( ! mandatoriesError.empty() )
                mandatoriesError += ", ";

            mandatoriesError += getSummaryOptionText(option);
        }

    }

    if ( ! mandatoriesError.empty() ) {
        usage("The following arguments are mandatory: " + mandatoriesError);
    }

    return otherArguments;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x930, %rsp            # imm = 0x930
movq %rdi, -0x880(%rbp)
movq %rdi, %rax
movq %rax, -0x878(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x870(%rbp)
movb $0x0, -0x21(%rbp)
callq 0x5670
cmpl $0x1, -0x14(%rbp)
jl 0x36a1
movq -0x870(%rbp), %rdi
movq -0x20(%rbp), %rax
movq (%rax), %rsi
addq $0x78, %rdi
callq 0x3390
jmp 0x368e
jmp 0x36a1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x4105
movl $0x1, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x3ec2
movq -0x20(%rbp), %rax
movslq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x890(%rbp)
leaq -0x59(%rbp), %rdi
movq %rdi, -0x888(%rbp)
callq 0x3490
movq -0x890(%rbp), %rsi
movq -0x888(%rbp), %rdx
leaq -0x58(%rbp), %rdi
callq 0x5690
jmp 0x36f0
leaq -0x59(%rbp), %rdi
callq 0x32c0
leaq -0x58(%rbp), %rdi
callq 0x3450
testb $0x1, %al
jne 0x3708
jmp 0x372e
movl $0x4, -0x60(%rbp)
jmp 0x3e84
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x59(%rbp), %rdi
callq 0x32c0
jmp 0x4105
xorl %eax, %eax
movl %eax, %esi
leaq -0x58(%rbp), %rdi
callq 0x34e0
movq %rax, -0x898(%rbp)
jmp 0x3744
movq -0x898(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
je 0x3782
movq -0x880(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x5740
jmp 0x3765
movl $0x4, -0x60(%rbp)
jmp 0x3e84
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x3eb4
leaq -0x58(%rbp), %rdi
callq 0x33e0
cmpq $0x2, %rax
jae 0x3867
leaq -0x1e8(%rbp), %rdi
callq 0x31a0
jmp 0x37a3
leaq -0x1d8(%rbp), %rdi
leaq 0x8853(%rip), %rsi      # 0xc004
callq 0x3260
movq %rax, -0x8a0(%rbp)
jmp 0x37bf
movq -0x8a0(%rbp), %rdi
movl -0x38(%rbp), %esi
callq 0x3470
movq %rax, -0x8a8(%rbp)
jmp 0x37d7
movq -0x8a8(%rbp), %rdi
leaq 0x8ad1(%rip), %rsi      # 0xc2b6
callq 0x3260
jmp 0x37ec
leaq -0x208(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x3250
jmp 0x3801
movq -0x870(%rbp), %rdi
leaq -0x208(%rbp), %rsi
callq 0x57b0
jmp 0x3816
leaq -0x208(%rbp), %rdi
callq 0x3160
leaq -0x1e8(%rbp), %rdi
callq 0x31d0
jmp 0x3867
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x3856
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x208(%rbp), %rdi
callq 0x3160
leaq -0x1e8(%rbp), %rdi
callq 0x31d0
jmp 0x3eb4
movq $0x0, -0x210(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x33a0
leaq -0x58(%rbp), %rdi
movl $0x1, %esi
callq 0x34e0
movq %rax, -0x8b0(%rbp)
jmp 0x3895
movq -0x8b0(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
je 0x3950
leaq -0x58(%rbp), %rdi
movl $0x1, %esi
callq 0x34e0
movq %rax, -0x8b8(%rbp)
jmp 0x38bf
movq -0x870(%rbp), %rdi
movq -0x8b8(%rbp), %rax
movsbl (%rax), %esi
callq 0x4120
movq %rax, -0x8c0(%rbp)
jmp 0x38de
movq -0x8c0(%rbp), %rax
movq %rax, -0x210(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x33e0
cmpq $0x2, %rax
jbe 0x394b
leaq -0x250(%rbp), %rdi
leaq -0x58(%rbp), %rsi
movl $0x2, %edx
movq $-0x1, %rcx
callq 0x3290
jmp 0x3919
leaq -0x230(%rbp), %rdi
leaq -0x250(%rbp), %rsi
callq 0x3320
leaq -0x250(%rbp), %rdi
callq 0x3160
jmp 0x394b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x3ea8
jmp 0x3bdb
leaq -0x58(%rbp), %rdi
callq 0x33e0
cmpq $0x3, %rax
jae 0x3a35
leaq -0x3d8(%rbp), %rdi
callq 0x31a0
jmp 0x3971
leaq -0x3c8(%rbp), %rdi
leaq 0x8685(%rip), %rsi      # 0xc004
callq 0x3260
movq %rax, -0x8c8(%rbp)
jmp 0x398d
movq -0x8c8(%rbp), %rdi
movl -0x38(%rbp), %esi
callq 0x3470
movq %rax, -0x8d0(%rbp)
jmp 0x39a5
movq -0x8d0(%rbp), %rdi
leaq 0x8903(%rip), %rsi      # 0xc2b6
callq 0x3260
jmp 0x39ba
leaq -0x3f8(%rbp), %rdi
leaq -0x3d8(%rbp), %rsi
callq 0x3250
jmp 0x39cf
movq -0x870(%rbp), %rdi
leaq -0x3f8(%rbp), %rsi
callq 0x57b0
jmp 0x39e4
leaq -0x3f8(%rbp), %rdi
callq 0x3160
leaq -0x3d8(%rbp), %rdi
callq 0x31d0
jmp 0x3a35
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x3a24
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x3f8(%rbp), %rdi
callq 0x3160
leaq -0x3d8(%rbp), %rdi
callq 0x31d0
jmp 0x3ea8
leaq -0x418(%rbp), %rdi
leaq -0x58(%rbp), %rsi
movl $0x2, %edx
movq $-0x1, %rcx
callq 0x3290
jmp 0x3a53
leaq -0x438(%rbp), %rdi
leaq -0x418(%rbp), %rsi
callq 0x30f0
jmp 0x3a68
leaq -0x438(%rbp), %rdi
movl $0x3d, %esi
xorl %eax, %eax
movl %eax, %edx
callq 0x3380
movl %eax, -0x43c(%rbp)
movslq -0x43c(%rbp), %rax
cmpq $-0x1, %rax
je 0x3b41
movslq -0x43c(%rbp), %rcx
xorl %eax, %eax
movl %eax, %edx
leaq -0x460(%rbp), %rdi
leaq -0x418(%rbp), %rsi
callq 0x3290
jmp 0x3ab4
leaq -0x438(%rbp), %rdi
leaq -0x460(%rbp), %rsi
movq %rsi, -0x8d8(%rbp)
callq 0x3320
movq -0x8d8(%rbp), %rdi
callq 0x3160
movl -0x43c(%rbp), %eax
incl %eax
movslq %eax, %rdx
leaq -0x480(%rbp), %rdi
leaq -0x418(%rbp), %rsi
movq $-0x1, %rcx
callq 0x3290
jmp 0x3b01
leaq -0x230(%rbp), %rdi
leaq -0x480(%rbp), %rsi
callq 0x3320
leaq -0x480(%rbp), %rdi
callq 0x3160
jmp 0x3b41
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x3bca
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x3bbe
leaq -0x4a0(%rbp), %rdi
leaq -0x438(%rbp), %rsi
callq 0x30f0
jmp 0x3b56
movq -0x870(%rbp), %rdi
leaq -0x4a0(%rbp), %rsi
callq 0x41c0
movq %rax, -0x8e0(%rbp)
jmp 0x3b72
movq -0x8e0(%rbp), %rax
movq %rax, -0x210(%rbp)
leaq -0x4a0(%rbp), %rdi
callq 0x3160
leaq -0x438(%rbp), %rdi
callq 0x3160
leaq -0x418(%rbp), %rdi
callq 0x3160
jmp 0x3bdb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x4a0(%rbp), %rdi
callq 0x3160
leaq -0x438(%rbp), %rdi
callq 0x3160
leaq -0x418(%rbp), %rdi
callq 0x3160
jmp 0x3ea8
cmpq $0x0, -0x210(%rbp)
jne 0x3cf0
leaq -0x628(%rbp), %rdi
callq 0x31a0
jmp 0x3bf7
leaq -0x618(%rbp), %rdi
leaq 0x8424(%rip), %rsi      # 0xc029
callq 0x3260
movq %rax, -0x8e8(%rbp)
jmp 0x3c13
movq -0x8e8(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x3230
movq %rax, -0x8f0(%rbp)
jmp 0x3c2c
movq -0x8f0(%rbp), %rdi
leaq 0x8400(%rip), %rsi      # 0xc03a
callq 0x3260
movq %rax, -0x8f8(%rbp)
jmp 0x3c48
movq -0x8f8(%rbp), %rdi
movl -0x38(%rbp), %esi
callq 0x3470
movq %rax, -0x900(%rbp)
jmp 0x3c60
movq -0x900(%rbp), %rdi
leaq 0x8648(%rip), %rsi      # 0xc2b6
callq 0x3260
jmp 0x3c75
leaq -0x648(%rbp), %rdi
leaq -0x628(%rbp), %rsi
callq 0x3250
jmp 0x3c8a
movq -0x870(%rbp), %rdi
leaq -0x648(%rbp), %rsi
callq 0x57b0
jmp 0x3c9f
leaq -0x648(%rbp), %rdi
callq 0x3160
leaq -0x628(%rbp), %rdi
callq 0x31d0
jmp 0x3cf0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x3cdf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x648(%rbp), %rdi
callq 0x3160
leaq -0x628(%rbp), %rdi
callq 0x31d0
jmp 0x3ea8
movq -0x210(%rbp), %rdi
callq 0x57f0
movb %al, -0x901(%rbp)
jmp 0x3d04
movb -0x901(%rbp), %al
testb $0x1, %al
jne 0x3d13
jmp 0x3e61
leaq -0x230(%rbp), %rdi
callq 0x3450
testb $0x1, %al
jne 0x3d28
jmp 0x3e2f
movl -0x38(%rbp), %eax
addl $0x1, %eax
cmpl -0x14(%rbp), %eax
jge 0x3d5d
movl -0x38(%rbp), %eax
incl %eax
movl %eax, -0x38(%rbp)
movq -0x210(%rbp), %rdi
movq -0x20(%rbp), %rax
movslq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
jmp 0x3d58
jmp 0x3e2d
leaq -0x7d0(%rbp), %rdi
callq 0x31a0
jmp 0x3d6b
leaq -0x7c0(%rbp), %rdi
leaq 0x82d4(%rip), %rsi      # 0xc04d
callq 0x3260
movq %rax, -0x910(%rbp)
jmp 0x3d87
movq -0x910(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x3230
movq %rax, -0x918(%rbp)
jmp 0x3da0
movq -0x918(%rbp), %rdi
leaq 0x82a8(%rip), %rsi      # 0xc056
callq 0x3260
jmp 0x3db5
leaq -0x7f0(%rbp), %rdi
leaq -0x7d0(%rbp), %rsi
callq 0x3250
jmp 0x3dca
movq -0x870(%rbp), %rdi
leaq -0x7f0(%rbp), %rsi
callq 0x57b0
jmp 0x3ddf
leaq -0x7f0(%rbp), %rdi
callq 0x3160
leaq -0x7d0(%rbp), %rdi
callq 0x31d0
jmp 0x3e2d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x3e1f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x7f0(%rbp), %rdi
callq 0x3160
leaq -0x7d0(%rbp), %rdi
callq 0x31d0
jmp 0x3ea8
jmp 0x3e5f
movq -0x210(%rbp), %rax
movq %rax, -0x920(%rbp)
leaq -0x230(%rbp), %rdi
callq 0x30e0
movq -0x920(%rbp), %rdi
movq %rax, %rsi
movq (%rdi), %rax
movq (%rax), %rax
callq *%rax
jmp 0x3e5d
jmp 0x3e5f
jmp 0x3e71
movq -0x210(%rbp), %rdi
callq 0x5810
jmp 0x3e6f
jmp 0x3e71
leaq -0x230(%rbp), %rdi
callq 0x3160
movl $0x0, -0x60(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x3160
movl -0x60(%rbp), %eax
testl %eax, %eax
je 0x3e98
jmp 0x3e96
jmp 0x3e9a
jmp 0x3e9a
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x36a8
leaq -0x230(%rbp), %rdi
callq 0x3160
leaq -0x58(%rbp), %rdi
callq 0x3160
jmp 0x4105
movq -0x870(%rbp), %rdi
callq 0x5830
movb %al, -0x921(%rbp)
jmp 0x3ed6
movb -0x921(%rbp), %al
testb $0x1, %al
jne 0x3ee2
jmp 0x3ef9
movq -0x870(%rbp), %rdi
leaq 0x81c5(%rip), %rsi      # 0xc0b5
callq 0x4590
jmp 0x3ef7
jmp 0x3ef9
leaq -0x810(%rbp), %rdi
callq 0x33a0
movq -0x870(%rbp), %rdi
addq $0x60, %rdi
callq 0x5850
movq %rax, -0x818(%rbp)
movq -0x870(%rbp), %rdi
addq $0x60, %rdi
callq 0x58c0
movq %rax, -0x820(%rbp)
leaq -0x818(%rbp), %rdi
leaq -0x820(%rbp), %rsi
callq 0x5880
testb $0x1, %al
jne 0x3f4f
jmp 0x4053
leaq -0x818(%rbp), %rdi
callq 0x58f0
movq (%rax), %rax
movq %rax, -0x828(%rbp)
movq -0x828(%rbp), %rdi
callq 0x5910
movb %al, -0x922(%rbp)
jmp 0x3f79
movb -0x922(%rbp), %al
testb $0x1, %al
jne 0x3f88
jmp 0x4040
movq -0x828(%rbp), %rdi
callq 0x5830
movb %al, -0x923(%rbp)
jmp 0x3f9c
movb -0x923(%rbp), %al
testb $0x1, %al
jne 0x4040
jmp 0x3fac
leaq -0x810(%rbp), %rdi
callq 0x3450
testb $0x1, %al
jne 0x3fe4
leaq 0x80b2(%rip), %rsi      # 0xc075
leaq -0x810(%rbp), %rdi
callq 0x3240
jmp 0x3fd1
jmp 0x3fe4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
jmp 0x40db
movq -0x870(%rbp), %rsi
movq -0x828(%rbp), %rdx
leaq -0x848(%rbp), %rdi
callq 0x5930
jmp 0x4000
leaq -0x810(%rbp), %rdi
leaq -0x848(%rbp), %rsi
callq 0x3360
jmp 0x4015
leaq -0x848(%rbp), %rdi
callq 0x3160
jmp 0x4040
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x848(%rbp), %rdi
callq 0x3160
jmp 0x40db
jmp 0x4042
leaq -0x818(%rbp), %rdi
callq 0x5970
jmp 0x3f1c
leaq -0x810(%rbp), %rdi
callq 0x3450
testb $0x1, %al
jne 0x40bc
leaq 0x800e(%rip), %rsi      # 0xc078
leaq -0x868(%rbp), %rdi
leaq -0x810(%rbp), %rdx
callq 0x5990
jmp 0x407f
movq -0x870(%rbp), %rdi
leaq -0x868(%rbp), %rsi
callq 0x57b0
jmp 0x4094
leaq -0x868(%rbp), %rdi
callq 0x3160
jmp 0x40bc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x30(%rbp)
movl %eax, -0x34(%rbp)
leaq -0x868(%rbp), %rdi
callq 0x3160
jmp 0x40db
movb $0x1, -0x21(%rbp)
movl $0x1, -0x60(%rbp)
leaq -0x810(%rbp), %rdi
callq 0x3160
testb $0x1, -0x21(%rbp)
jne 0x40f5
jmp 0x40e9
leaq -0x810(%rbp), %rdi
callq 0x3160
jmp 0x4105
movq -0x880(%rbp), %rdi
callq 0x5aa0
movq -0x878(%rbp), %rax
addq $0x930, %rsp            # imm = 0x930
popq %rbp
retq
movq -0x880(%rbp), %rdi
callq 0x5aa0
movq -0x30(%rbp), %rdi
callq 0x3480
nopw (%rax,%rax)