// File: /workspace/github_c_makefile_star2_O1/bobrippling[P]tim/list.c
// Function: list_delregion
list_t *list_delregion(list_t **pl, const region_t *region)
{
	if(region->begin.y > region->end.y)
		return NULL;

	if(region->type != REGION_LINE
	&& region->begin.y == region->end.y
	&& region->begin.x >= region->end.x)
	{
		return NULL;
	}

	list_t **seeked = list_seekp(pl, region->begin.y, false);

	if(!seeked || !*seeked)
		return NULL;

	list_t *deleted = NULL;

	switch(region->type){
		case REGION_LINE:
			deleted = list_dellines(
					seeked, (*seeked)->prev,
					region->end.y - region->begin.y + 1);
			break;
		case REGION_CHAR:
		{
			list_t *l = *seeked;
			size_t line_change = region->end.y - region->begin.y;

			/* create `deleted' */
			{
				deleted = list_new(NULL);

				if((unsigned)region->begin.x < l->len_line){
					char *this_line = l->line;
					size_t len = line_change == 0
							? (unsigned)region->end.x - region->begin.x
							: l->len_line - region->begin.x;

					char *pulled_out = ustrdup_len(
							this_line + region->begin.x,
							len);

					deleted->line = pulled_out;
					deleted->len_line = deleted->len_malloc = len;
				}
				/* else we leave deleted empty */
			}

			if(line_change > 1){
				deleted = list_append(
						deleted,
						list_tail(deleted),
						list_dellines(
							&l->next, l->prev,
							line_change - 1));
			}


			/* wipe lines */
			if(line_change > 0){
				/* join the lines */
				list_t *next = l->next;
				size_t nextlen;
				if((unsigned)region->end.x >= next->len_line){
					nextlen = 0;
				}else{
					nextlen = next->len_line - region->end.x;
				}
				size_t fulllen = region->begin.x + nextlen;

				if(l->len_malloc < fulllen)
					l->line = urealloc(l->line, l->len_malloc = fulllen);

				{
					list_t *pullout = list_new(NULL);
					deleted = list_append(deleted, list_tail(deleted), pullout);

					size_t len = MIN((unsigned)region->end.x, next->len_line);
					pullout->len_malloc = pullout->len_line = len;

					pullout->line = ustrdup_len(next->line, len);
				}

				memcpy(l->line + region->begin.x,
						next->line + region->end.x,
						nextlen);
				l->len_line = fulllen;

				list_free(list_dellines(&l->next, l->prev, 1));

			}else{
				if(!l->len_line || (unsigned)region->end.x > l->len_line)
					return deleted;

				size_t diff = region->end.x - region->begin.x;

				list_t *part = list_new(NULL);
				part->line = umalloc(diff + 1);
				part->len_line = diff;
				part->len_malloc = diff + 1;
				memcpy(part->line, l->line + region->begin.x, diff);

				memmove(
						l->line + region->begin.x,
						l->line + region->end.x,
						l->len_line - region->end.x);

				l->len_line -= diff;
			}
			break;
		}
		case REGION_COL:
		{
			list_t *pos = *seeked;
			point_t begin = region->begin, end = region->end;

			/* should've been sorted also */
			assert(begin.x <= end.x);

			for(int i = begin.y;
					i <= end.y && pos;
					i++, pos = pos->next)
			{
				if((unsigned)begin.x < pos->len_line){
					struct
					{
						char *str;
						size_t len;
					} removed;

					if((unsigned)end.x >= pos->len_line){
						/* delete all */
						removed.len = pos->len_line - begin.x + 1;
						removed.str = ustrdup_len(
								pos->line + begin.x,
								removed.len);

						pos->len_line = begin.x;

					}else{
						char *str = pos->line;

						removed.len = end.x - begin.x;
						removed.str = ustrdup_len(
								str + begin.x,
								removed.len);

						memmove(
								str + begin.x,
								str + end.x,
								pos->len_line - end.x);

						pos->len_line -= end.x - begin.x;
					}

					/* removed text */
					list_t *new = list_new(NULL);
					new->line = removed.str;
					new->len_malloc = new->len_line = removed.len;
					deleted = list_append(deleted, list_tail(deleted), new);
				}else{
					deleted = list_append(
							deleted, list_tail(deleted),
							list_new(NULL));
				}
			}
			break;
		}
	}

	return deleted;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movl 0x4(%rsi), %r12d
movl 0xc(%rsi), %ebp
cmpl %r12d, %ebp
jl 0xa383
movq %rsi, %r14
movl 0x10(%rsi), %eax
cmpl $0x2, %eax
sete %cl
movl %ebp, 0x8(%rsp)
subl %r12d, %ebp
setne %dl
orb %cl, %dl
jne 0xa302
movl (%r14), %ecx
cmpl 0x8(%r14), %ecx
jge 0xa383
cmpq $0x0, (%rdi)
je 0xa329
testl %r12d, %r12d
jle 0xa32b
leal 0x1(%r12), %ecx
movq (%rdi), %rdi
cmpq $0x0, 0x18(%rdi)
je 0xa329
addq $0x18, %rdi
decl %ecx
cmpl $0x1, %ecx
jg 0xa312
jmp 0xa32b
xorl %edi, %edi
testq %rdi, %rdi
je 0xa383
movq (%rdi), %rbx
testq %rbx, %rbx
je 0xa383
testl %eax, %eax
je 0xa398
cmpl $0x1, %eax
je 0xa361
cmpl $0x2, %eax
jne 0xa383
movq 0x20(%rbx), %rsi
incl %ebp
movl %ebp, %edx
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xa7b8
movslq (%r14), %rcx
movslq 0x8(%r14), %rdx
movq %rcx, 0x28(%rsp)
movq %rdx, 0x20(%rsp)
cmpl %ecx, %edx
jl 0xa799
movl 0x8(%rsp), %ebp
cmpl %r12d, %ebp
jge 0xa3da
xorl %r13d, %r13d
movq %r13, %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x30, %edi
callq 0x5830
movq %rax, %r13
movq $0x0, 0x20(%rax)
movl (%r14), %ecx
movq 0x8(%rbx), %r15
cmpq %rcx, %r15
jbe 0xa582
movslq %ecx, %rax
movq (%rbx), %rdi
cmpl %r12d, 0x8(%rsp)
jne 0xa568
movl 0x8(%r14), %r15d
subl %ecx, %r15d
jmp 0xa56b
movq 0x28(%rsp), %rcx
movl %ecx, %edx
movl 0x20(%rsp), %eax
movq %rdx, 0x18(%rsp)
movslq %edx, %rdx
movq %rdx, 0x38(%rsp)
movq %rax, 0x40(%rsp)
subl %ecx, %eax
cltq
movq %rax, 0x30(%rsp)
xorl %r13d, %r13d
movq 0x8(%rbx), %r15
movq %r13, %rax
cmpq 0x18(%rsp), %r15
jbe 0xa46b
cmpq 0x40(%rsp), %r15
jbe 0xa4c3
movq (%rbx), %r15
movq %r13, 0x10(%rsp)
movq 0x28(%rsp), %rax
leaq (%r15,%rax), %r13
movq %r13, %rdi
movq 0x30(%rsp), %r14
movq %r14, %rsi
callq 0x58a8
movq %rax, %rbp
movq 0x20(%rsp), %rax
addq %rax, %r15
movq 0x8(%rbx), %rdx
subq %rax, %rdx
movq %r13, %rdi
movq 0x10(%rsp), %r13
movq %r15, %rsi
callq 0x4400
movq 0x8(%rbx), %rax
subq %r14, %rax
movq %r14, %r15
jmp 0xa4e2
movq %rax, %r15
testq %rax, %rax
je 0xa47c
movq 0x18(%r15), %rax
testq %rax, %rax
jne 0xa46b
movl $0x30, %edi
callq 0x5830
movq $0x0, 0x20(%rax)
testq %r13, %r13
je 0xa547
movq 0x18(%r15), %rcx
movq %rax, 0x18(%r15)
movq %r15, 0x20(%rax)
testq %rcx, %rcx
je 0xa54a
movq %rax, %rdx
testq %rax, %rax
je 0xa53d
movq 0x18(%rdx), %rax
testq %rax, %rax
jne 0xa4ac
jmp 0xa53d
movq 0x38(%rsp), %r14
subq %r14, %r15
incq %r15
movq (%rbx), %rdi
addq %r14, %rdi
movq %r15, %rsi
callq 0x58a8
movq %rax, %rbp
movq %r14, %rax
movq %rax, 0x8(%rbx)
movl $0x30, %edi
callq 0x5830
movq $0x0, 0x20(%rax)
movq %rbp, (%rax)
movq %r15, 0x8(%rax)
movq %r15, 0x10(%rax)
movq %r13, %rcx
movq %rcx, %rdx
testq %rcx, %rcx
je 0xa517
movq 0x18(%rdx), %rcx
testq %rcx, %rcx
jne 0xa506
testq %r13, %r13
movl 0x8(%rsp), %ebp
je 0xa547
movq 0x18(%rdx), %rcx
movq %rax, 0x18(%rdx)
movq %rdx, 0x20(%rax)
testq %rcx, %rcx
je 0xa54a
movq %rax, %rdx
movq 0x18(%rax), %rax
testq %rax, %rax
jne 0xa531
movq %rcx, 0x18(%rdx)
movq %rdx, 0x20(%rcx)
jmp 0xa54a
movq %rax, %r13
cmpl %ebp, %r12d
jge 0xa386
incl %r12d
movq 0x18(%rbx), %rbx
testq %rbx, %rbx
jne 0xa403
jmp 0xa386
subq %rax, %r15
addq %rax, %rdi
movq %r15, %rsi
callq 0x58a8
movq %rax, (%r13)
movq %r15, 0x10(%r13)
movq %r15, 0x8(%r13)
cmpl $0x2, %ebp
jb 0xa5e4
movq %r13, %rax
movq %rax, %r15
testq %rax, %rax
je 0xa59b
movq 0x18(%r15), %rax
testq %rax, %rax
jne 0xa58a
leaq 0x18(%rbx), %rdi
movq 0x20(%rbx), %rsi
decl %ebp
movl %ebp, %edx
callq 0xa7b8
testq %r13, %r13
je 0xa5e1
movq 0x18(%r15), %rcx
movq %rax, 0x18(%r15)
movq %r15, 0x20(%rax)
testq %rcx, %rcx
movl 0x8(%rsp), %esi
je 0xa5e8
movq %rax, %rdx
testq %rax, %rax
je 0xa5d7
movq 0x18(%rdx), %rax
testq %rax, %rax
jne 0xa5c6
movq %rcx, 0x18(%rdx)
movq %rdx, 0x20(%rcx)
jmp 0xa5e8
movq %rax, %r13
movl 0x8(%rsp), %esi
cmpl %r12d, %esi
jne 0xa67f
movq 0x8(%rbx), %rax
testq %rax, %rax
je 0xa386
movl 0x8(%r14), %ecx
cmpq %rcx, %rax
jb 0xa386
movslq %ecx, %r15
movslq (%r14), %rax
subq %rax, %r15
movl $0x30, %edi
callq 0x5830
movq %rax, %r12
movq $0x0, 0x20(%rax)
movq %r13, %rbp
leaq 0x1(%r15), %r13
movq %r13, %rdi
callq 0x5830
movq %rax, (%r12)
movq %r15, 0x8(%r12)
movq %r13, 0x10(%r12)
movq %rbp, %r13
movslq (%r14), %rsi
addq (%rbx), %rsi
movq %rax, %rdi
movq %r15, %rdx
callq 0x4350
movslq (%r14), %rdi
movq (%rbx), %rsi
movq 0x8(%rbx), %rdx
addq %rsi, %rdi
movslq 0x8(%r14), %rax
addq %rax, %rsi
subq %rax, %rdx
callq 0x4400
subq %r15, 0x8(%rbx)
jmp 0xa386
movq %r13, 0x10(%rsp)
movq 0x18(%rbx), %r13
movslq 0x8(%r14), %rax
movl %eax, %ecx
movq 0x8(%r13), %rdx
movq %rdx, %rsi
subq %rax, %rsi
xorl %r15d, %r15d
cmpq %rcx, %rdx
cmovaq %rsi, %r15
movslq (%r14), %r12
addq %r15, %r12
cmpq %r12, 0x10(%rbx)
jae 0xa6c0
movq (%rbx), %rdi
movq %r12, 0x10(%rbx)
movq %r12, %rsi
callq 0x5851
movq %rax, (%rbx)
leaq 0x18(%rbx), %rax
movq %rax, 0x8(%rsp)
movl $0x30, %edi
callq 0x5830
movq %rax, %rbp
movq $0x0, 0x20(%rax)
movq 0x10(%rsp), %rax
movq %rax, %rcx
testq %rax, %rax
je 0xa6f4
movq 0x18(%rcx), %rax
testq %rax, %rax
jne 0xa6e3
movq %rbp, %rax
cmpq $0x0, 0x10(%rsp)
je 0xa731
movq 0x18(%rcx), %rax
movq %rbp, 0x18(%rcx)
movq %rcx, 0x20(%rbp)
testq %rax, %rax
je 0xa72c
movq %rbp, %rdx
movq %rdx, %rcx
testq %rdx, %rdx
je 0xa724
movq 0x18(%rcx), %rdx
testq %rdx, %rdx
jne 0xa713
movq %rax, 0x18(%rcx)
movq %rcx, 0x20(%rax)
movq 0x10(%rsp), %rax
movq %rax, 0x18(%rsp)
movl 0x8(%r14), %esi
movq 0x8(%r13), %rax
cmpq %rsi, %rax
cmovbq %rax, %rsi
movq %rsi, 0x8(%rbp)
movq %rsi, 0x10(%rbp)
movq (%r13), %rdi
callq 0x58a8
movq %rax, (%rbp)
movslq (%r14), %rdi
addq (%rbx), %rdi
movslq 0x8(%r14), %rsi
addq (%r13), %rsi
movq %r15, %rdx
callq 0x4350
movq %r12, 0x8(%rbx)
movq 0x20(%rbx), %rsi
movq 0x8(%rsp), %rdi
movl $0x1, %edx
callq 0xa7b8
movq %rax, %rdi
callq 0x9d7b
movq 0x18(%rsp), %r13
jmp 0xa386
leaq 0x4e83(%rip), %rdi      # 0xf623
leaq 0x4e58(%rip), %rsi      # 0xf5ff
leaq 0x4e86(%rip), %rcx      # 0xf634
movl $0x236, %edx            # imm = 0x236
callq 0x4210