// File: /workspace/github_c_makefile_star2_O2/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 $0x38, %rsp
movq %rsi, %r14
movl 0x4(%rsi), %esi
cmpl 0xc(%r14), %esi
jle 0x9aaf
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jne 0x9ac1
cmpl $0x2, 0x10(%r14)
je 0x9ac1
movl (%r14), %eax
cmpl 0x8(%r14), %eax
jge 0x9a9b
xorl %ebx, %ebx
xorl %edx, %edx
callq 0x96e1
testq %rax, %rax
je 0x9a9d
movq (%rax), %rbp
testq %rbp, %rbp
je 0x9a9b
movl 0x10(%r14), %ecx
testl %ecx, %ecx
je 0x9c4f
cmpl $0x1, %ecx
je 0x9b11
cmpl $0x2, %ecx
jne 0x9a9b
movq 0x20(%rbp), %rsi
movl 0xc(%r14), %edx
subl 0x4(%r14), %edx
incl %edx
movq %rax, %rdi
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x9e51
movl (%r14), %r12d
movslq 0x8(%r14), %rax
cmpl %r12d, %eax
jl 0x9e32
movl 0xc(%r14), %r13d
movq %rax, 0x28(%rsp)
movl %eax, %eax
movl 0x4(%r14), %r14d
movslq %r12d, %rdx
movq %rax, 0x8(%rsp)
movq %rdx, 0x18(%rsp)
subl %edx, %eax
cltq
movq %rax, 0x20(%rsp)
xorl %ebx, %ebx
movq %r12, (%rsp)
movl %r13d, 0x10(%rsp)
cmpl %r13d, %r14d
jg 0x9a9d
testq %rbp, %rbp
je 0x9a9d
movq 0x8(%rbp), %r15
cmpq %r12, %r15
jbe 0x9bc3
cmpq 0x8(%rsp), %r15
jbe 0x9be8
movq (%rbp), %r15
movq 0x18(%rsp), %rax
leaq (%r15,%rax), %r13
movq %r13, %rdi
movq %rbx, 0x30(%rsp)
movq 0x20(%rsp), %rbx
movq %rbx, %rsi
callq 0x5690
movq %rax, %r12
movq 0x28(%rsp), %rax
addq %rax, %r15
movq 0x8(%rbp), %rdx
subq %rax, %rdx
movq %r13, %rdi
movq %r15, %rsi
callq 0x4400
movq 0x8(%rbp), %rax
subq %rbx, %rax
movq %rbx, %r15
movq 0x30(%rsp), %rbx
jmp 0x9c08
movq %rbx, %rdi
callq 0x9a32
movq %rax, %r15
xorl %edi, %edi
callq 0x9280
movq %rbx, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x9a44
movq %rax, %rbx
jmp 0x9c43
movq 0x18(%rsp), %r13
subq %r13, %r15
incq %r15
movq (%rbp), %rdi
addq %r13, %rdi
movq %r15, %rsi
callq 0x5690
movq %rax, %r12
movq %r13, %rax
movq %rax, 0x8(%rbp)
xorl %edi, %edi
callq 0x9280
movq %rax, %r13
movq %r12, (%rax)
movq %r15, 0x8(%rax)
movq %r15, 0x10(%rax)
movq %rbx, %rdi
callq 0x9a32
movq %rbx, %rdi
movq %rax, %rsi
movq %r13, %rdx
callq 0x9a44
movq %rax, %rbx
movq (%rsp), %r12
movl 0x10(%rsp), %r13d
incl %r14d
movq 0x18(%rbp), %rbp
jmp 0x9b51
movl 0x4(%r14), %eax
movl 0xc(%r14), %r13d
movl %r13d, %r12d
movl %eax, (%rsp)
subl %eax, %r12d
xorl %edi, %edi
callq 0x9280
movq %rax, %rbx
movl (%r14), %ecx
movq 0x8(%rbp), %r15
cmpq %rcx, %r15
jbe 0x9ca5
movslq %ecx, %rax
movq (%rbp), %rdi
cmpl (%rsp), %r13d
jne 0x9c8c
movl 0x8(%r14), %r15d
subl %ecx, %r15d
jmp 0x9c8f
subq %rax, %r15
addq %rax, %rdi
movq %r15, %rsi
callq 0x5690
movq %rax, (%rbx)
movq %r15, 0x10(%rbx)
movq %r15, 0x8(%rbx)
cmpl $0x2, %r12d
jb 0x9cda
movq %rbx, %rdi
callq 0x9a32
movq %rax, %r15
leaq 0x18(%rbp), %rdi
movq 0x20(%rbp), %rsi
decl %r12d
movl %r12d, %edx
callq 0x9e51
movq %rbx, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x9a44
movq %rax, %rbx
cmpl (%rsp), %r13d
jne 0x9d5f
movq 0x8(%rbp), %rax
testq %rax, %rax
je 0x9a9d
movl 0x8(%r14), %ecx
cmpq %rcx, %rax
jb 0x9a9d
movslq %ecx, %r15
movslq (%r14), %rax
subq %rax, %r15
xorl %edi, %edi
callq 0x9280
movq %rax, %r12
leaq 0x1(%r15), %r13
movq %r13, %rdi
callq 0x5648
movq %rax, (%r12)
movq %r15, 0x8(%r12)
movq %r13, 0x10(%r12)
movslq (%r14), %rsi
addq (%rbp), %rsi
movq %rax, %rdi
movq %r15, %rdx
callq 0x4360
movslq (%r14), %rdi
movq (%rbp), %rsi
movq 0x8(%rbp), %rdx
addq %rsi, %rdi
movslq 0x8(%r14), %rax
addq %rax, %rsi
subq %rax, %rdx
callq 0x4400
subq %r15, 0x8(%rbp)
jmp 0x9a9d
leaq 0x18(%rbp), %rax
movq %rax, (%rsp)
movq 0x18(%rbp), %rdx
movslq 0x8(%r14), %rax
movl %eax, %ecx
movq %rdx, 0x10(%rsp)
movq 0x8(%rdx), %rdx
movq %rdx, %rsi
subq %rax, %rsi
xorl %r12d, %r12d
cmpq %rcx, %rdx
cmovaq %rsi, %r12
movslq (%r14), %r13
addq %r12, %r13
cmpq %r13, 0x10(%rbp)
jae 0x9daa
movq (%rbp), %rdi
movq %r13, 0x10(%rbp)
movq %r13, %rsi
callq 0x5660
movq %rax, (%rbp)
xorl %edi, %edi
callq 0x9280
movq %rax, %r15
movq %rbx, %rdi
callq 0x9a32
movq %rbx, %rdi
movq %rax, %rsi
movq %r15, %rdx
callq 0x9a44
movl 0x8(%r14), %esi
movq 0x10(%rsp), %rbx
movq 0x8(%rbx), %rcx
cmpq %rsi, %rcx
cmovbq %rcx, %rsi
movq %rax, 0x8(%rsp)
movq %rsi, 0x8(%r15)
movq %rsi, 0x10(%r15)
movq (%rbx), %rdi
callq 0x5690
movq %rax, (%r15)
movslq (%r14), %rdi
addq (%rbp), %rdi
movslq 0x8(%r14), %rsi
addq (%rbx), %rsi
movq %r12, %rdx
callq 0x4360
movq %r13, 0x8(%rbp)
movq 0x20(%rbp), %rsi
pushq $0x1
popq %rdx
movq (%rsp), %rdi
callq 0x9e51
movq %rax, %rdi
callq 0x95f9
movq 0x8(%rsp), %rax
jmp 0x9aa0
leaq 0x47db(%rip), %rdi      # 0xe614
leaq 0x47b0(%rip), %rsi      # 0xe5f0
leaq 0x47de(%rip), %rcx      # 0xe625
movl $0x236, %edx            # imm = 0x236
callq 0x4210