// File: /workspace/github_c_makefile_star2_O1/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %r8d, -0x34(%rbp)
movl %ecx, %r14d
movl %edx, %ebx
movq %rsi, -0x60(%rbp)
movl %edi, -0x74(%rbp)
movl %edx, %edx
movq %rsp, %rdi
leaq 0xf(%rdx), %rax
andq $-0x10, %rax
subq %rax, %rdi
movq %rdi, %rsp
testl %r9d, %r9d
movq %rdx, -0x50(%rbp)
movq %rdi, -0x48(%rbp)
js 0x6d6e
movl %r9d, %r15d
callq 0xde6c
movq -0x48(%rbp), %r10
movq -0x50(%rbp), %r9
testl %ebx, %ebx
movl -0x34(%rbp), %r8d
je 0x6d7c
movl 0x40(%rax), %eax
movl %r15d, %ecx
addq -0x60(%rbp), %rcx
xorl %edx, %edx
xorl %esi, %esi
movl %edx, %edi
testl %eax, (%rcx,%rdi)
setne (%r10,%rsi)
incq %rsi
addl %r8d, %edx
cmpq %rsi, %r9
jne 0x6d57
jmp 0x6d7c
movl $0x1, %esi
callq 0x4240
movl -0x34(%rbp), %r8d
movl %r14d, %eax
addq %rax, -0x60(%rbp)
movl $0xffffffff, -0x38(%rbp) # imm = 0xFFFFFFFF
xorl %r12d, %r12d
xorl %r13d, %r13d
movl %r8d, %r14d
movl %ebx, -0x30(%rbp)
movq %r13, %r15
xorl %edx, %edx
testl %r15d, %r15d
sete %dl
movl -0x74(%rbp), %edi
leaq -0x29(%rbp), %rsi
callq 0xc772
movl %eax, -0x54(%rbp)
cmpb $0x1, -0x29(%rbp)
jne 0x6dc5
movq -0x48(%rbp), %rdi
xorl %esi, %esi
movq -0x50(%rbp), %rdx
callq 0x4240
leaq 0x1(%r15), %rsi
movq %r12, %rdi
movq %rsi, -0x68(%rbp)
callq 0x5851
movq %rax, -0x70(%rbp)
movl -0x54(%rbp), %ecx
movb %cl, (%rax,%r15)
movl $0x0, -0x40(%rbp)
movl $0x0, -0x3c(%rbp)
testl %ebx, %ebx
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
je 0x6e69
movl %r15d, %r13d
xorl %ebx, %ebx
xorl %r12d, %r12d
movl $0x0, -0x3c(%rbp)
movl $0x0, -0x40(%rbp)
cmpb $0x1, (%rcx,%r12)
jne 0x6e5e
movl %ebx, %eax
movq -0x60(%rbp), %rcx
movq (%rcx,%rax), %r14
movq %r14, %rdi
callq 0x4170
cmpq %r13, %rax
jbe 0x6e4d
movsbl (%r14,%r13), %eax
cmpl %eax, -0x54(%rbp)
jne 0x6e4d
incl -0x40(%rbp)
movl %r12d, -0x3c(%rbp)
movl -0x34(%rbp), %r14d
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
jmp 0x6e5e
movq -0x48(%rbp), %rcx
movb $0x0, (%rcx,%r12)
movl -0x34(%rbp), %r14d
movq -0x50(%rbp), %rax
incq %r12
addl %r14d, %ebx
cmpq %r12, %rax
jne 0x6e10
movl -0x40(%rbp), %eax
cmpl $0x1, %eax
je 0x6e9e
testl %eax, %eax
jne 0x6ee3
movq -0x68(%rbp), %r13
testq %r13, %r13
movq -0x70(%rbp), %r12
je 0x6e94
movsbl (%r12,%r15), %edi
xorl %esi, %esi
callq 0xc8a5
addq $-0x1, %r15
jb 0x6e82
movl -0x30(%rbp), %ebx
movl $0xc, %ecx
jmp 0x6ef0
movl -0x3c(%rbp), %r12d
movl %r12d, %eax
imull %r14d, %eax
movq -0x60(%rbp), %rcx
movq (%rcx,%rax), %rdi
movl %r15d, %ebx
callq 0x4170
decq %rax
cmpq %rbx, %rax
movl -0x38(%rbp), %eax
cmovel %r12d, %eax
movl %eax, -0x38(%rbp)
movl $0x0, %ecx
movl $0xc, %eax
cmovel %eax, %ecx
movl -0x30(%rbp), %ebx
movq -0x70(%rbp), %r12
movq -0x68(%rbp), %r13
jmp 0x6ef0
movl -0x30(%rbp), %ebx
movq -0x70(%rbp), %r12
movq -0x68(%rbp), %r13
xorl %ecx, %ecx
testl %ecx, %ecx
je 0x6d96
cmpl $0xc, %ecx
jne 0x6f05
movq %r12, %rdi
callq 0x4080
movl -0x38(%rbp), %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq