// File: /workspace/github_c_makefile_star2_O0/bobrippling[P]tim/keys.c
// Function: keys_filter
int keys_filter(
		enum io io_m,
		char *struc, unsigned n_ents,
		unsigned st_off, unsigned st_sz,
		int mode_off)
{
#define STRUCT_STR(i, st, off) *(const char **)(struc + i * st_sz + st_off)
	int ret = -1;

	bool potential[n_ents];

	if(mode_off >= 0){
		enum buf_mode curmode = windows_cur()->ui_mode;

		for(unsigned i = 0; i < n_ents; i++){
			enum buf_mode mode = *(enum buf_mode *)(
					struc + i * st_sz + mode_off);

			potential[i] = mode & curmode;
		}
	}else{
		memset(potential, true, sizeof potential);
	}

	unsigned ch_idx = 0;
	char *sofar = NULL;
	size_t nsofar = 0;
	for(;; ch_idx++){
		bool raw;
		int ch = io_getch(io_m, &raw, /*map:*/ch_idx == 0); /* dl shouldn't map l */
		if(raw){
			/* raw char, doesn't match any, get out */
			memset(potential, 0, sizeof potential);
		}

		sofar = urealloc(sofar, ++nsofar);
		sofar[nsofar-1] = ch;

		unsigned npotential = 0;
		unsigned last_potential = 0;

		for(unsigned i = 0; i < sizeof potential; i++){
			if(potential[i]){
				const char *const kstr = STRUCT_STR(i, struc, str_off);
				size_t keys_len = strlen(kstr);

				if(ch_idx >= keys_len || kstr[ch_idx] != ch){
					potential[i] = false;
				}else{
					npotential++;
					last_potential = i;
				}
			}
		}

		switch(npotential){
			case 1:
			{
				/* only accept once we have the full string */
				const char *kstr = STRUCT_STR(last_potential, struc, str_off);
				if(ch_idx == strlen(kstr) - 1){
					ret = last_potential;
					goto out;
				}
				break;
			}
			case 0:
				for(size_t i = nsofar; i > 0; i--)
					io_ungetch(sofar[i - 1], false);
				goto out;
		}
	}

out:
	free(sofar);
	return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movl %edi, -0x4(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movl %r8d, -0x1c(%rbp)
movl %r9d, -0x20(%rbp)
movl $0xffffffff, -0x24(%rbp) # imm = 0xFFFFFFFF
movl -0x14(%rbp), %eax
movq %rax, -0xa0(%rbp)
movq %rsp, %rcx
movq %rcx, -0x30(%rbp)
movq %rax, %rdx
addq $0xf, %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x98(%rbp)
movq %rcx, %rsp
movq %rax, -0x38(%rbp)
cmpl $0x0, -0x20(%rbp)
jl 0x7e2a
callq 0x13c60
movl 0x40(%rax), %eax
movl %eax, -0x3c(%rbp)
movl $0x0, -0x40(%rbp)
movl -0x40(%rbp), %eax
cmpl -0x14(%rbp), %eax
jae 0x7e28
movq -0x98(%rbp), %rax
movq -0x10(%rbp), %rcx
movl -0x40(%rbp), %edx
imull -0x1c(%rbp), %edx
movl %edx, %edx
addq %rdx, %rcx
movslq -0x20(%rbp), %rdx
movl (%rcx,%rdx), %ecx
movl %ecx, -0x44(%rbp)
movl -0x44(%rbp), %ecx
andl -0x3c(%rbp), %ecx
cmpl $0x0, %ecx
setne %dl
movl -0x40(%rbp), %ecx
andb $0x1, %dl
movb %dl, (%rax,%rcx)
movl -0x40(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x40(%rbp)
jmp 0x7ddf
jmp 0x7e42
movq -0xa0(%rbp), %rdx
movq -0x98(%rbp), %rdi
movl $0x1, %esi
callq 0x4240
movl $0x0, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
movq $0x0, -0x58(%rbp)
movl -0x4(%rbp), %edi
cmpl $0x0, -0x48(%rbp)
sete %al
movzbl %al, %edx
andl $0x1, %edx
leaq -0x59(%rbp), %rsi
callq 0x11310
movl %eax, -0x60(%rbp)
testb $0x1, -0x59(%rbp)
je 0x7e90
movq -0xa0(%rbp), %rdx
movq -0x98(%rbp), %rdi
xorl %esi, %esi
callq 0x4240
movq -0x50(%rbp), %rdi
movq -0x58(%rbp), %rsi
addq $0x1, %rsi
movq %rsi, -0x58(%rbp)
callq 0x5f60
movq %rax, -0x50(%rbp)
movl -0x60(%rbp), %eax
movb %al, %dl
movq -0x50(%rbp), %rax
movq -0x58(%rbp), %rcx
subq $0x1, %rcx
movb %dl, (%rax,%rcx)
movl $0x0, -0x64(%rbp)
movl $0x0, -0x68(%rbp)
movl $0x0, -0x6c(%rbp)
movq -0xa0(%rbp), %rcx
movl -0x6c(%rbp), %eax
cmpq %rcx, %rax
jae 0x7f67
movq -0x98(%rbp), %rax
movl -0x6c(%rbp), %ecx
testb $0x1, (%rax,%rcx)
je 0x7f57
movq -0x10(%rbp), %rax
movl -0x6c(%rbp), %ecx
imull -0x1c(%rbp), %ecx
movl %ecx, %ecx
addq %rcx, %rax
movl -0x18(%rbp), %ecx
movq (%rax,%rcx), %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
callq 0x4170
movq %rax, -0x80(%rbp)
movl -0x48(%rbp), %eax
cmpq -0x80(%rbp), %rax
jae 0x7f36
movq -0x78(%rbp), %rax
movl -0x48(%rbp), %ecx
movsbl (%rax,%rcx), %eax
cmpl -0x60(%rbp), %eax
je 0x7f46
movq -0x98(%rbp), %rax
movl -0x6c(%rbp), %ecx
movb $0x0, (%rax,%rcx)
jmp 0x7f55
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
movl -0x6c(%rbp), %eax
movl %eax, -0x68(%rbp)
jmp 0x7f57
jmp 0x7f59
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x7ed2
movl -0x64(%rbp), %eax
movl %eax, -0xa4(%rbp)
testl %eax, %eax
je 0x7fd8
jmp 0x7f76
movl -0xa4(%rbp), %eax
subl $0x1, %eax
jne 0x801d
jmp 0x7f87
movq -0x10(%rbp), %rax
movl -0x68(%rbp), %ecx
imull -0x1c(%rbp), %ecx
movl %ecx, %ecx
addq %rcx, %rax
movl -0x18(%rbp), %ecx
movq (%rax,%rcx), %rax
movq %rax, -0x88(%rbp)
movl -0x48(%rbp), %eax
movq %rax, -0xb0(%rbp)
movq -0x88(%rbp), %rdi
callq 0x4170
movq %rax, %rcx
movq -0xb0(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jne 0x7fd6
movl -0x68(%rbp), %eax
movl %eax, -0x24(%rbp)
jmp 0x802d
jmp 0x801d
movq -0x58(%rbp), %rax
movq %rax, -0x90(%rbp)
cmpq $0x0, -0x90(%rbp)
jbe 0x801b
movq -0x50(%rbp), %rax
movq -0x90(%rbp), %rcx
subq $0x1, %rcx
movsbl (%rax,%rcx), %edi
xorl %esi, %esi
callq 0x11540
movq -0x90(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0x7fe3
jmp 0x802d
jmp 0x801f
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x7e59
movq -0x50(%rbp), %rdi
callq 0x4080
movl -0x24(%rbp), %eax
movq -0x30(%rbp), %rcx
movq %rcx, %rsp
movq %rbp, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)