// File: /workspace/github_c_makefile_star2_O3/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
movl 0x4(%rsi), %ebx
movl 0xc(%rsi), %eax
movl %eax, (%rsp)
cmpl %ebx, %eax
jl 0xa185
movq %rsi, %r15
movl 0x10(%rsi), %eax
cmpl $0x2, %eax
sete %cl
movl (%rsp), %r12d
subl %ebx, %r12d
setne %dl
orb %cl, %dl
jne 0xa12d
movl (%r15), %ecx
cmpl 0x8(%r15), %ecx
jge 0xa185
movq (%rdi), %rbp
testq %rbp, %rbp
je 0xa185
testl %ebx, %ebx
jle 0xa156
leal 0x1(%rbx), %ecx
xorl %r14d, %r14d
movq %rbp, %rdi
movq 0x18(%rbp), %rbp
testq %rbp, %rbp
je 0xa188
decl %ecx
cmpl $0x1, %ecx
jg 0xa13f
addq $0x18, %rdi
testl %eax, %eax
je 0xa328
cmpl $0x1, %eax
je 0xa19a
cmpl $0x2, %eax
jne 0xa185
movq 0x20(%rbp), %rsi
incl %r12d
movl %r12d, %edx
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0xa5b4
xorl %r14d, %r14d
movq %r14, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl (%r15), %r12d
movslq 0x8(%r15), %rax
cmpl %r12d, %eax
jl 0xa595
movq %rax, 0x20(%rsp)
movl %eax, %eax
movslq %r12d, %rdx
movq %rax, 0x30(%rsp)
movq %rdx, 0x10(%rsp)
subl %edx, %eax
cltq
movq %rax, 0x18(%rsp)
xorl %r14d, %r14d
movq %r12, 0x8(%rsp)
movq 0x8(%rbp), %r15
movq %r14, %rax
cmpq %r12, %r15
jbe 0xa236
cmpq 0x30(%rsp), %r15
jbe 0xa285
movq (%rbp), %r15
movq 0x10(%rsp), %rax
leaq (%r15,%rax), %r13
movq %r13, %rdi
movq %r14, 0x28(%rsp)
movq 0x18(%rsp), %r14
movq %r14, %rsi
callq 0x5889
movq %rax, %r12
movq 0x20(%rsp), %rax
addq %rax, %r15
movq 0x8(%rbp), %rdx
subq %rax, %rdx
movq %r13, %rdi
movq %r15, %rsi
callq 0x4400
movq 0x8(%rbp), %r13
subq %r14, %r13
movq %r14, %r15
movq 0x28(%rsp), %r14
jmp 0xa2a2
movq %rax, %r15
testq %rax, %rax
je 0xa247
movq 0x18(%r15), %rax
testq %rax, %rax
jne 0xa236
movl $0x30, %edi
callq 0x5830
movq $0x0, 0x20(%rax)
testq %r14, %r14
je 0xa308
movq 0x18(%r15), %rcx
movq %rax, 0x18(%r15)
movq %r15, 0x20(%rax)
testq %rcx, %rcx
je 0xa30b
movq %rax, %rdx
movq 0x18(%rax), %rax
testq %rax, %rax
jne 0xa277
jmp 0xa2fe
movq 0x10(%rsp), %r13
subq %r13, %r15
incq %r15
movq (%rbp), %rdi
addq %r13, %rdi
movq %r15, %rsi
callq 0x5889
movq %rax, %r12
movq %r13, 0x8(%rbp)
movl $0x30, %edi
callq 0x5830
movq $0x0, 0x20(%rax)
movq %r12, (%rax)
movq %r15, 0x8(%rax)
movq %r15, 0x10(%rax)
movq %r14, %rcx
movq %rcx, %rdx
testq %rcx, %rcx
je 0xa2d7
movq 0x18(%rdx), %rcx
testq %rcx, %rcx
jne 0xa2c6
testq %r14, %r14
movq 0x8(%rsp), %r12
je 0xa308
movq 0x18(%rdx), %rcx
movq %rax, 0x18(%rdx)
movq %rdx, 0x20(%rax)
testq %rcx, %rcx
je 0xa30b
movq %rax, %rdx
movq 0x18(%rax), %rax
testq %rax, %rax
jne 0xa2f2
movq %rcx, 0x18(%rdx)
movq %rdx, 0x20(%rcx)
jmp 0xa30b
movq %rax, %r14
cmpl (%rsp), %ebx
jge 0xa188
incl %ebx
movq 0x18(%rbp), %rbp
testq %rbp, %rbp
jne 0xa1cf
jmp 0xa188
movl $0x30, %edi
callq 0x5830
movq %rax, %rsi
movq $0x0, 0x20(%rax)
movl (%r15), %ecx
movq 0x8(%rbp), %r14
cmpq %rcx, %r14
movq %rax, 0x8(%rsp)
jbe 0xa381
movslq %ecx, %rax
movq (%rbp), %rdi
cmpl %ebx, (%rsp)
jne 0xa363
movl 0x8(%r15), %r14d
subl %ecx, %r14d
jmp 0xa366
subq %rax, %r14
addq %rax, %rdi
movq %r14, %rsi
callq 0x5889
movq 0x8(%rsp), %rsi
movq %rax, (%rsi)
movq %r14, 0x10(%rsi)
movq %r14, 0x8(%rsi)
cmpl $0x2, %r12d
jb 0xa3da
movq %rsi, %r14
movq 0x18(%rsi), %rsi
testq %rsi, %rsi
jne 0xa387
leaq 0x18(%rbp), %rdi
movq 0x20(%rbp), %rsi
decl %r12d
movl %r12d, %edx
callq 0xa5b4
movq 0x8(%rsp), %rsi
testq %rsi, %rsi
je 0xa3d7
movq 0x18(%r14), %rcx
movq %rax, 0x18(%r14)
movq %r14, 0x20(%rax)
testq %rcx, %rcx
je 0xa3da
movq %rax, %rdx
movq 0x18(%rax), %rax
testq %rax, %rax
jne 0xa3c1
movq %rcx, 0x18(%rdx)
movq %rdx, 0x20(%rcx)
jmp 0xa3da
movq %rax, %rsi
cmpl %ebx, (%rsp)
jne 0xa3fd
movq 0x8(%rbp), %rax
testq %rax, %rax
je 0xa3f5
movl 0x8(%r15), %ecx
cmpq %rcx, %rax
jae 0xa51f
movq %rsi, %r14
jmp 0xa188
movq %rsi, %r14
movq 0x18(%rbp), %rbx
movslq 0x8(%r15), %rax
movl %eax, %ecx
movq 0x8(%rbx), %rdx
movq %rdx, %rsi
subq %rax, %rsi
xorl %eax, %eax
cmpq %rcx, %rdx
cmovaq %rsi, %rax
movslq (%r15), %r13
movq %rax, (%rsp)
addq %rax, %r13
cmpq %r13, 0x10(%rbp)
jae 0xa441
movq (%rbp), %rdi
movq %r13, 0x10(%rbp)
movq %r13, %rsi
callq 0x584a
movq %rax, (%rbp)
movl $0x30, %edi
callq 0x5830
movq %rax, %r12
movq $0x0, 0x20(%rax)
movq %r14, %rsi
movq %r14, %rcx
movq %rcx, %rax
testq %rcx, %rcx
je 0xa46d
movq 0x18(%rax), %rcx
testq %rcx, %rcx
jne 0xa45c
movq %r12, %r14
testq %rsi, %rsi
je 0xa4a1
movq 0x18(%rax), %rcx
movq %r12, 0x18(%rax)
movq %rax, 0x20(%r12)
testq %rcx, %rcx
je 0xa49e
movq %r12, %rdx
movq %rdx, %rax
movq 0x18(%rdx), %rdx
testq %rdx, %rdx
jne 0xa48a
movq %rcx, 0x18(%rax)
movq %rax, 0x20(%rcx)
movq %rsi, %r14
movl 0x8(%r15), %esi
movq 0x8(%rbx), %rax
cmpq %rsi, %rax
cmovbq %rax, %rsi
movq %rsi, 0x8(%r12)
movq %rsi, 0x10(%r12)
movq (%rbx), %rdi
callq 0x5889
movq %rax, (%r12)
movslq (%r15), %rdi
addq (%rbp), %rdi
movslq 0x8(%r15), %rsi
addq (%rbx), %rsi
movq (%rsp), %rdx
callq 0x4360
movq %r13, 0x8(%rbp)
movq 0x18(%rbp), %rdi
testq %rdi, %rdi
je 0xa515
movq 0x20(%rbp), %rax
xorl %ecx, %ecx
movq %rcx, 0x20(%rdi)
movq 0x18(%rdi), %rdx
movq %rdx, 0x18(%rbp)
movq %rcx, 0x18(%rdi)
movq 0x18(%rbp), %rcx
testq %rcx, %rcx
je 0xa50d
movq %rax, 0x20(%rcx)
movq $0x0, 0x20(%rdi)
callq 0x9bd0
jmp 0xa188
movslq %ecx, %r14
movslq (%r15), %rax
subq %rax, %r14
movl $0x30, %edi
movq %rsi, %rbx
callq 0x5830
movq %rax, %r12
movq $0x0, 0x20(%rax)
leaq 0x1(%r14), %r13
movq %r13, %rdi
callq 0x5830
movq %rax, (%r12)
movq %r14, 0x8(%r12)
movq %r13, 0x10(%r12)
movslq (%r15), %rsi
addq (%rbp), %rsi
movq %rax, %rdi
movq %r14, %rdx
callq 0x4360
movslq (%r15), %rdi
movq (%rbp), %rsi
movq 0x8(%rbp), %rdx
addq %rsi, %rdi
movslq 0x8(%r15), %rax
addq %rax, %rsi
subq %rax, %rdx
callq 0x4400
subq %r14, 0x8(%rbp)
movq %rbx, %r14
jmp 0xa188
leaq 0x4078(%rip), %rdi      # 0xe614
leaq 0x404d(%rip), %rsi      # 0xe5f0
leaq 0x407b(%rip), %rcx      # 0xe625
movl $0x236, %edx            # imm = 0x236
callq 0x4210