// File: /workspace/github_c_makefile_star2_O0/justy989[P]ce/ce.c
// Function: ce_buffer_remove_string
bool ce_buffer_remove_string(CeBuffer_t* buffer, CePoint_t point, int64_t length){
     if(buffer->status == CE_BUFFER_STATUS_READONLY) return false;
     if(!ce_buffer_point_is_valid(buffer, point)) return false;

     char* first_line_start = ce_utf8_iterate_to(buffer->lines[point.y], point.x);
     int64_t length_left_on_line = ce_utf8_strlen(first_line_start) + 1;

     if(length_left_on_line > length){
          // case: glue together left and right sides and cut out the middle
          char* end_of_start = ce_utf8_iterate_to(buffer->lines[point.y], point.x);
          assert(end_of_start);
          char* beginning_of_end = ce_utf8_iterate_to(buffer->lines[point.y], point.x + length);
          assert(beginning_of_end);

          // figure out how big of a line to allocate
          size_t start_line_len = end_of_start - buffer->lines[point.y];
          size_t end_line_len = strlen(beginning_of_end);
          size_t full_line_len = start_line_len + end_line_len;
          char* new_line = calloc(full_line_len + 1, sizeof(*new_line));
          if(!new_line) return false;

          // copy over the data to our new line
          memcpy(new_line, buffer->lines[point.y], start_line_len);
          memcpy(new_line + start_line_len, beginning_of_end, end_line_len);
          new_line[full_line_len] = 0;

          // free and overwrite our new line
          free(buffer->lines[point.y]);
          buffer->lines[point.y] = new_line;

          buffer->status = CE_BUFFER_STATUS_MODIFIED;
          return true;
     }else if(length_left_on_line == length){
          if(point.x == 0){
               buffer->status = CE_BUFFER_STATUS_MODIFIED;
               return ce_buffer_remove_lines(buffer, point.y, 1);
          }

          // remove characters left on current line
          int64_t keep_length = (first_line_start - buffer->lines[point.y]);
          buffer->lines[point.y] = realloc(buffer->lines[point.y], keep_length + 1);
          buffer->lines[point.y][keep_length] = 0;

          // perform a join with the next line
          int64_t next_line_index = point.y + 1;
          if(next_line_index > buffer->line_count) return false;
          if(next_line_index < buffer->line_count){
               int64_t cur_line_len = strlen(buffer->lines[point.y]);
               int64_t next_line_len = strlen(buffer->lines[next_line_index]);
               int64_t new_line_len = next_line_len + cur_line_len;
               buffer->lines[point.y] = realloc(buffer->lines[point.y], new_line_len + 1);
               strncpy(buffer->lines[point.y] + cur_line_len, buffer->lines[next_line_index], next_line_len);
               buffer->lines[point.y][new_line_len] = 0;
          }

          buffer->status = CE_BUFFER_STATUS_MODIFIED;
          return ce_buffer_remove_lines(buffer, next_line_index, 1);
     }

     // case: cut the end of the initial line, N lines in the middle and N leftover characters in the final
     //       line, and join the remaining characters in the last line to the initial line
     int64_t length_left = length - length_left_on_line;
     int64_t current_line = point.y + 1;
     int64_t save_current_line = current_line;
     int64_t line_len = 0;
     int64_t last_line_offset = 0;
     bool do_join = false;

     // how many lines do we have to delete?
     for(; current_line < buffer->line_count; current_line++){
          line_len = ce_utf8_strlen(buffer->lines[current_line]) + 1;

          if(length_left >= line_len){
               length_left -= line_len;
               if(length_left == 0){
                    if(point.x == 0 && point.y == 0){
                         // pass
                    }else if(current_line == (buffer->line_count - 1)){
                         current_line++;
                         break;
                    }else{
                         do_join = true;
                         current_line++;
                         break;
                    }
               }
          }else{
               last_line_offset = length_left;
               break;
          }
     }

     int64_t lines_to_delete = current_line - point.y;

     // join the rest of the last line in the deletion, to the first line
     if(last_line_offset || do_join){
          char* end_to_join = ce_utf8_iterate_to(buffer->lines[current_line], last_line_offset);
          int64_t join_len = strlen(end_to_join);
          int64_t new_len = point.x + join_len;
          buffer->lines[point.y] = realloc(buffer->lines[point.y], new_len + 1);
          memcpy(buffer->lines[point.y] + point.x, end_to_join, join_len);
          buffer->lines[point.y][new_len] = 0;
     }else{
          // if we aren't doing a join, then start with deleting the first line
          save_current_line--;
     }

     // remove the intermediate lines
     return ce_buffer_remove_lines(buffer, save_current_line, lines_to_delete);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movq %rsi, -0x18(%rbp)
movq %rdx, -0x10(%rbp)
movq %rdi, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x2, 0x18(%rax)
jne 0x101be
movb $0x0, -0x1(%rbp)
jmp 0x10777
movq -0x20(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x10(%rbp), %rdx
callq 0xeba0
cmpq $0x0, %rax
jne 0x101de
movb $0x0, -0x1(%rbp)
jmp 0x10777
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movq -0x18(%rbp), %rsi
callq 0xeca0
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
callq 0xea70
addq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
cmpq -0x28(%rbp), %rax
jle 0x10376
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movq -0x18(%rbp), %rsi
callq 0xeca0
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x1023e
jmp 0x1025d
leaq 0x32419(%rip), %rdi     # 0x4265e
leaq 0x323c8(%rip), %rsi     # 0x42614
movl $0x34b, %edx            # imm = 0x34B
leaq 0x32413(%rip), %rcx     # 0x4266b
callq 0xd270
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movq -0x18(%rbp), %rsi
addq -0x28(%rbp), %rsi
callq 0xeca0
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x10286
jmp 0x102a5
leaq 0x3241e(%rip), %rdi     # 0x426ab
leaq 0x32380(%rip), %rsi     # 0x42614
movl $0x34d, %edx            # imm = 0x34D
leaq 0x323cb(%rip), %rcx     # 0x4266b
callq 0xd270
movq -0x40(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rcx), %rcx
movq -0x10(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
subq %rcx, %rax
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
callq 0xd200
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rax
addq -0x58(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rdi
addq $0x1, %rdi
movl $0x1, %esi
callq 0xd360
movq %rax, -0x68(%rbp)
cmpq $0x0, -0x68(%rbp)
jne 0x102fe
movb $0x0, -0x1(%rbp)
jmp 0x10777
movq -0x68(%rbp), %rdi
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
movq -0x50(%rbp), %rdx
callq 0xd400
movq -0x68(%rbp), %rdi
addq -0x50(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0x58(%rbp), %rdx
callq 0xd400
movq -0x68(%rbp), %rax
movq -0x60(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xd090
movq -0x68(%rbp), %rdx
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x20(%rbp), %rax
movl $0x1, 0x18(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x10777
movq -0x38(%rbp), %rax
cmpq -0x28(%rbp), %rax
jne 0x1052b
cmpq $0x0, -0x18(%rbp)
jne 0x103b2
movq -0x20(%rbp), %rax
movl $0x1, 0x18(%rax)
movq -0x20(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl $0x1, %edx
callq 0x10790
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x10777
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rcx), %rcx
movq -0x10(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
subq %rcx, %rax
movq %rax, -0x70(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movq -0x70(%rbp), %rsi
addq $0x1, %rsi
callq 0xd500
movq %rax, %rdx
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq -0x70(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0x10(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
movq -0x20(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jle 0x10434
movb $0x0, -0x1(%rbp)
jmp 0x10777
movq -0x78(%rbp), %rax
movq -0x20(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jge 0x10504
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xd200
movq %rax, -0x80(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x78(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xd200
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
addq -0x80(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movq -0x90(%rbp), %rsi
addq $0x1, %rsi
callq 0xd500
movq %rax, %rdx
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
addq -0x80(%rbp), %rdi
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x78(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
movq -0x88(%rbp), %rdx
callq 0xd0b0
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq -0x90(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0x20(%rbp), %rax
movl $0x1, 0x18(%rax)
movq -0x20(%rbp), %rdi
movq -0x78(%rbp), %rsi
movl $0x1, %edx
callq 0x10790
andb $0x1, %al
movb %al, -0x1(%rbp)
jmp 0x10777
jmp 0x1052d
movq -0x28(%rbp), %rax
subq -0x38(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x10(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, -0xa8(%rbp)
movq $0x0, -0xb0(%rbp)
movq $0x0, -0xb8(%rbp)
movb $0x0, -0xb9(%rbp)
movq -0xa0(%rbp), %rax
movq -0x20(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jge 0x10663
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0xa0(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xea70
addq $0x1, %rax
movq %rax, -0xb0(%rbp)
movq -0x98(%rbp), %rax
cmpq -0xb0(%rbp), %rax
jl 0x1063a
movq -0xb0(%rbp), %rcx
movq -0x98(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x98(%rbp)
cmpq $0x0, -0x98(%rbp)
jne 0x10638
cmpq $0x0, -0x18(%rbp)
jne 0x105ef
cmpq $0x0, -0x10(%rbp)
jne 0x105ef
jmp 0x10636
movq -0xa0(%rbp), %rax
movq -0x20(%rbp), %rcx
movq 0x8(%rcx), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jne 0x1061b
movq -0xa0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa0(%rbp)
jmp 0x10663
movb $0x1, -0xb9(%rbp)
movq -0xa0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa0(%rbp)
jmp 0x10663
jmp 0x10638
jmp 0x1064a
movq -0x98(%rbp), %rax
movq %rax, -0xb8(%rbp)
jmp 0x10663
jmp 0x1064c
movq -0xa0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa0(%rbp)
jmp 0x10576
movq -0xa0(%rbp), %rax
subq -0x10(%rbp), %rax
movq %rax, -0xc8(%rbp)
cmpq $0x0, -0xb8(%rbp)
jne 0x1068c
testb $0x1, -0xb9(%rbp)
je 0x10749
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0xa0(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movq -0xb8(%rbp), %rsi
callq 0xeca0
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rdi
callq 0xd200
movq %rax, -0xd8(%rbp)
movq -0x18(%rbp), %rax
addq -0xd8(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movq -0xe0(%rbp), %rsi
addq $0x1, %rsi
callq 0xd500
movq %rax, %rdx
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
addq -0x18(%rbp), %rdi
movq -0xd0(%rbp), %rsi
movq -0xd8(%rbp), %rdx
callq 0xd400
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq -0xe0(%rbp), %rcx
movb $0x0, (%rax,%rcx)
jmp 0x1075b
movq -0xa8(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0xa8(%rbp)
movq -0x20(%rbp), %rdi
movq -0xa8(%rbp), %rsi
movq -0xc8(%rbp), %rdx
callq 0x10790
andb $0x1, %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xe0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)