// File: exrok[P]evdoublebind/./src/make_config.cc
// Function: gen(Settings&)
int gen(Settings &settings) {
    char * buffer = file_contents(settings.input_conf);
    if (!buffer) {
        fprintf(stderr,"Error Reading Config File [%s]: ", settings.input_conf);
        perror("");
        exit(1);
    }
    Config config;

    struct xkb_keymap *keymap;
    struct xkb_context *ctx;

    ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
    if (!ctx) {
        exit(1);
    }
    keymap = xkb_keymap_new_from_names(ctx, &settings.xkb_names,
                                       XKB_KEYMAP_COMPILE_NO_FLAGS);
    if (!keymap) {
        exit(1);
    }
    struct xkb_state *state;
    state = xkb_state_new(keymap);

    if (!state) {
        exit(1);
    }

    auto entry = ConfigParser(buffer);
    while (entry.next()) {
        if (strcmp(entry.key, "unused") == 0)  {
            parse_unused_keys(keymap, config, entry.value);
        } else if (strcmp(entry.key, "kbd") == 0) {
            config.keyboards.push(entry.value);
        } else {
            char *symtap_sep = strchr(entry.value, '|');
            char *evtap_sep = strchr(entry.value, '@');
            if (symtap_sep && evtap_sep) {
                fprintf(stderr,"CONFIG ERROR[line:%d]: Both symkey and raw keycode taps specfied.\n",
                        entry.line);
                exit(1);
            }
            auto map = config.mappings.top_new();
            map->keycode = parse_keycode(keymap, entry.key);
            if (symtap_sep != NULL){
                *symtap_sep = '\0';
                symtap_sep++;
                int i = parse_symlevel(map->tap_map, symtap_sep);
                for (int i = 0; i < 2; i++) map->tap_raw[i] = -1;
            } else if (evtap_sep != NULL) {
                *evtap_sep = '\0';
                evtap_sep++;
                parse_raw_tap(entry.line, keymap,map->tap_raw, evtap_sep);
                for (int i = 0; i < 4; i++) map->tap_map[i] = NULL;
            }
            int count = parse_symlevel(map->hold_map, entry.value);
            if (count == 0 && symtap_sep == NULL && evtap_sep == NULL) {
                fprintf(stderr,"CONFIG ERROR[line:%d]: No mappings Specified\n",
                        entry.line);
                exit(1);
            }
        }
    }
    generate_hfile(config,settings);
    if (!settings.only_arguments) {
        generate_xkb_file(keymap,config, settings);
    }
    free(buffer);

    xkb_state_unref(state);
    xkb_keymap_unref(keymap);
    xkb_context_unref(ctx);
    return 0;
}

// Assembly:
subq $0xa8, %rsp
movq %rdi, 0xa0(%rsp)
movq 0xa0(%rsp), %rax
movq 0x30(%rax), %rdi
callq 0x3b30
movq %rax, 0x98(%rsp)
cmpq $0x0, 0x98(%rsp)
jne 0x440d
movq 0x5c1e(%rip), %rax      # 0x9ff8
movq (%rax), %rdi
movq 0xa0(%rsp), %rax
movq 0x30(%rax), %rdx
leaq 0x2e30(%rip), %rsi      # 0x7220
movb $0x0, %al
callq 0x3130
leaq 0x2d15(%rip), %rdi      # 0x7113
callq 0x31e0
movl $0x1, %edi
callq 0x3220
leaq 0x68(%rsp), %rdi
callq 0x4c10
xorl %edi, %edi
callq 0x3140
movq %rax, 0x58(%rsp)
cmpq $0x0, 0x58(%rsp)
jne 0x4435
movl $0x1, %edi
callq 0x3220
movq 0x58(%rsp), %rdi
movq 0xa0(%rsp), %rsi
xorl %edx, %edx
callq 0x30e0
movq %rax, 0x60(%rsp)
cmpq $0x0, 0x60(%rsp)
jne 0x4460
movl $0x1, %edi
callq 0x3220
movq 0x60(%rsp), %rdi
callq 0x3110
movq %rax, 0x50(%rsp)
cmpq $0x0, 0x50(%rsp)
jne 0x4481
movl $0x1, %edi
callq 0x3220
movq 0x98(%rsp), %rsi
leaq 0x30(%rsp), %rdi
callq 0x4c50
leaq 0x30(%rsp), %rdi
callq 0x4c90
testb $0x1, %al
jne 0x44a6
jmp 0x46b7
movq 0x38(%rsp), %rdi
leaq 0x2d8f(%rip), %rsi      # 0x7241
callq 0x3120
cmpl $0x0, %eax
jne 0x44d5
movq 0x60(%rsp), %rdi
movq 0x40(%rsp), %rdx
leaq 0x68(%rsp), %rsi
callq 0x3910
jmp 0x46b2
movq 0x38(%rsp), %rdi
leaq 0x2d67(%rip), %rsi      # 0x7248
callq 0x3120
cmpl $0x0, %eax
jne 0x4503
leaq 0x68(%rsp), %rdi
addq $0x10, %rdi
movq 0x40(%rsp), %rsi
callq 0x4eb0
jmp 0x46b0
movq 0x40(%rsp), %rdi
movl $0x7c, %esi
callq 0x3090
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rdi
movl $0x40, %esi
callq 0x3090
movq %rax, 0x20(%rsp)
cmpq $0x0, 0x28(%rsp)
je 0x4561
cmpq $0x0, 0x20(%rsp)
je 0x4561
movq 0x5ab6(%rip), %rax      # 0x9ff8
movq (%rax), %rdi
movl 0x48(%rsp), %edx
leaq 0x2cfc(%rip), %rsi      # 0x724c
movb $0x0, %al
callq 0x3130
movl $0x1, %edi
callq 0x3220
leaq 0x68(%rsp), %rdi
callq 0x4f00
movq %rax, 0x18(%rsp)
movq 0x60(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0x3720
movl %eax, %ecx
movq 0x18(%rsp), %rax
movl %ecx, (%rax)
cmpq $0x0, 0x28(%rsp)
je 0x45ed
movq 0x28(%rsp), %rax
movb $0x0, (%rax)
movq 0x28(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x28(%rsp)
movq 0x18(%rsp), %rdi
addq $0x28, %rdi
movq 0x28(%rsp), %rsi
callq 0x3660
movl %eax, 0x14(%rsp)
movl $0x0, 0x10(%rsp)
cmpl $0x2, 0x10(%rsp)
jge 0x45eb
movq 0x18(%rsp), %rax
movslq 0x10(%rsp), %rcx
movl $0xffffffff, 0x48(%rax,%rcx,4) # imm = 0xFFFFFFFF
movl 0x10(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x10(%rsp)
jmp 0x45c5
jmp 0x465a
cmpq $0x0, 0x20(%rsp)
je 0x4658
movq 0x20(%rsp), %rax
movb $0x0, (%rax)
movq 0x20(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x20(%rsp)
movl 0x48(%rsp), %edi
movq 0x60(%rsp), %rsi
movq 0x18(%rsp), %rdx
addq $0x48, %rdx
movq 0x20(%rsp), %rcx
callq 0x3800
movl $0x0, 0xc(%rsp)
cmpl $0x4, 0xc(%rsp)
jge 0x4656
movq 0x18(%rsp), %rax
movslq 0xc(%rsp), %rcx
movq $0x0, 0x28(%rax,%rcx,8)
movl 0xc(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xc(%rsp)
jmp 0x462f
jmp 0x4658
jmp 0x465a
movq 0x18(%rsp), %rdi
addq $0x8, %rdi
movq 0x40(%rsp), %rsi
callq 0x3660
movl %eax, 0x8(%rsp)
cmpl $0x0, 0x8(%rsp)
jne 0x46ae
cmpq $0x0, 0x28(%rsp)
jne 0x46ae
cmpq $0x0, 0x20(%rsp)
jne 0x46ae
movq 0x5969(%rip), %rax      # 0x9ff8
movq (%rax), %rdi
movl 0x48(%rsp), %edx
leaq 0x2bf2(%rip), %rsi      # 0x728f
movb $0x0, %al
callq 0x3130
movl $0x1, %edi
callq 0x3220
jmp 0x46b0
jmp 0x46b2
jmp 0x4493
movq 0xa0(%rsp), %rsi
leaq 0x68(%rsp), %rdi
callq 0x40f0
movq 0xa0(%rsp), %rax
testb $0x1, 0x28(%rax)
jne 0x46ee
movq 0x60(%rsp), %rdi
movq 0xa0(%rsp), %rdx
leaq 0x68(%rsp), %rsi
callq 0x3cc0
movq 0x98(%rsp), %rdi
callq 0x3040
movq 0x50(%rsp), %rdi
callq 0x3200
movq 0x60(%rsp), %rdi
callq 0x3170
movq 0x58(%rsp), %rdi
callq 0x3060
leaq 0x68(%rsp), %rdi
callq 0x4f40
xorl %eax, %eax
addq $0xa8, %rsp
retq
nopl (%rax)