// File: /workspace/github_c_makefile_star2_O2/bobrippling[P]tim/motion.c
// Function: m_paren
int m_paren(
		motion_arg const *arg, unsigned repeat,
		window *win, point_t *to)
{
	list_t *l = window_current_line(win, false);
	if(!l)
		return MOTION_FAILURE;

	if(arg->i == '%'){
		/* look forward for a paren on this line, then match */
		char paren = 0, opp;
		unsigned x = win->ui_pos->x;
		unsigned y = win->ui_pos->y;

		if(x >= l->len_line)
			x = l->len_line - 1;
		for(unsigned i = x; i < l->len_line; i++)
			if(paren_match(l->line[i], &opp)){
				paren = l->line[i];
				x = i;
				break;
			}

		if(!paren)
			return MOTION_FAILURE;

		const int dir = paren_left(paren) ? 1 : -1;
		point_t pos = { .y = y, .x = x + dir };

		if(find_unnested_paren(opp, paren, dir, &l, &pos)){
			*to = pos;
			return MOTION_SUCCESS;
		}
		return MOTION_FAILURE;
	}

	if(paren_match(arg->i, &(char){ 0 })){
		repeat = DEFAULT_REPEAT(repeat);

		/* look for an unmatched `arg->i' */
		char paren = arg->i, opp = paren_opposite(paren);

		point_t pos = *win->ui_pos;

		int dir = paren_left(paren) ? -1 : 1;
		bool done_one = false;

		for(; repeat > 0; repeat--){
			const point_t before_move = pos;

			if((unsigned)pos.x < l->len_line &&
			(l->line[pos.x] == paren || l->line[pos.x] == opp))
			{
				/* "[{" while on a '{' - step out so we don't stay on it
				 * or
				 * "[{" while on a '}' - step in so we match the other paren
				 */
				l = list_advance_x(l, dir, &pos.y, &pos.x);
			}

			if(!find_unnested_paren(paren, opp,
						dir, &l, &pos))
			{
				if(done_one){
					pos = before_move;
					break;
				}
				return MOTION_FAILURE;
			}

			done_one = true;
		}

		*to = pos;
		return MOTION_SUCCESS;
	}

	return MOTION_FAILURE;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rcx, %r13
movq %rdx, %r15
movl %esi, %ebp
movq %rdi, %r12
xorl %r14d, %r14d
movq %rdx, %rdi
xorl %esi, %esi
callq 0xcef6
movq %rax, 0x18(%rsp)
testq %rax, %rax
je 0xb120
movq %rax, %rbx
movl (%r12), %eax
cmpl $0x25, %eax
jne 0xaff7
movq 0x30(%r15), %rax
movl (%rax), %ecx
movl 0x4(%rax), %ebp
movq 0x8(%rbx), %rax
leal -0x1(%rax), %r12d
cmpq %rcx, %rax
cmoval %ecx, %r12d
leaq 0xe(%rsp), %r15
xorl %r14d, %r14d
movl %r12d, %r12d
cmpq %r12, %rax
jbe 0xb120
movq (%rbx), %rax
movsbl (%rax,%r12), %edi
movq %r15, %rsi
callq 0xb64a
testb %al, %al
jne 0xb0d1
incl %r12d
movq 0x8(%rbx), %rax
jmp 0xafca
leaq 0xf(%rsp), %rsi
movb $0x0, (%rsi)
movsbl %al, %edi
callq 0xb64a
testb %al, %al
je 0xb120
movq %r13, 0x20(%rsp)
cmpl $0x1, %ebp
adcl $0x1, %ebp
movsbl (%r12), %r14d
movl %r14d, %edi
callq 0xb686
movl %eax, %ebx
movq 0x30(%r15), %rax
movq (%rax), %rax
leaq 0x14(%rsp), %rcx
movq %rax, -0x4(%rcx)
movl %r14d, %edi
callq 0xb66b
movzbl %al, %r12d
negl %r12d
orl $0x1, %r12d
movsbl %bl, %r13d
xorl %ecx, %ecx
movq 0x10(%rsp), %rbx
decl %ebp
je 0xb0c7
movl %ecx, %r15d
movl %ebx, %eax
movq 0x18(%rsp), %rdi
cmpq %rax, 0x8(%rdi)
jbe 0xb0a0
movq (%rdi), %rax
movslq %ebx, %rcx
movb (%rax,%rcx), %al
movsbl %al, %eax
cmpl %eax, %r14d
sete %cl
cmpb %r13b, %al
sete %al
orb %cl, %al
cmpb $0x1, %al
jne 0xb0a0
movl %r12d, %esi
leaq 0x14(%rsp), %rdx
leaq 0x10(%rsp), %rcx
callq 0xa38f
movq %rax, 0x18(%rsp)
movl %r14d, %edi
movl %r13d, %esi
movl %r12d, %edx
leaq 0x18(%rsp), %rcx
leaq 0x10(%rsp), %r8
callq 0xb132
movb $0x1, %cl
testb %al, %al
jne 0xb052
xorl %r14d, %r14d
testb $0x1, %r15b
je 0xb120
movq 0x20(%rsp), %rax
movq %rbx, (%rax)
jmp 0xb11c
movq (%rbx), %rax
movsbl (%rax,%r12), %ebx
testl %ebx, %ebx
je 0xb120
movl %ebx, %edi
callq 0xb66b
movzbl %al, %edx
decl %edx
orl $0x1, %edx
addl %edx, %r12d
leaq 0x10(%rsp), %r8
movl %r12d, (%r8)
movl %ebp, 0x4(%r8)
movsbl 0xe(%rsp), %edi
leaq 0x18(%rsp), %rcx
movl %ebx, %esi
callq 0xb132
xorl %r14d, %r14d
testb %al, %al
je 0xb120
movq 0x10(%rsp), %rax
movq %rax, (%r13)
pushq $0x1
popq %r14
movl %r14d, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq