// File: /workspace/github_c_makefile_star2_O1/justy989[P]ce/ce_app.c
// Function: extract_completion_from_response
CeComplete_t* _extract_completion_from_response(CeJsonObj_t* obj, CePoint_t* start){
     CeComplete_t* result = NULL;

     CeJsonFindResult_t result_find = ce_json_obj_find(obj, "result");
     if(result_find.type != CE_JSON_TYPE_OBJECT){
          return result;
     }

     // TODO: check isIncomplete

     CeJsonObj_t* result_obj = ce_json_obj_get_obj(obj, &result_find);

     CeJsonFindResult_t items_find = ce_json_obj_find(result_obj, "items");
     if(items_find.type != CE_JSON_TYPE_ARRAY){
          return result;
     }

     CeJsonArray_t* items_array = ce_json_obj_get_array(result_obj, &items_find);
     if(items_array == NULL){
          return result;
     }

     int64_t completion_count = 0;
     char** completions = NULL;
     char** descriptions = NULL;

     for(int64_t i = 0; i < items_array->count; i++){
          CeJsonValue_t* value = items_array->values + i;
          if(value->type != CE_JSON_TYPE_OBJECT){
               continue;
          }

          CeJsonFindResult_t insert_text_find = ce_json_obj_find(&value->obj, "insertText");
          if(insert_text_find.type != CE_JSON_TYPE_STRING){
               continue;
          }

          CeJsonFindResult_t detail_find = ce_json_obj_find(&value->obj, "detail");

          char* completion = strdup(ce_json_obj_get_string(&value->obj, &insert_text_find));


          CeJsonFindResult_t label_find = ce_json_obj_find(&value->obj, "label");

          char* description = NULL;
          if(label_find.type == CE_JSON_TYPE_STRING){
               int64_t completion_len = strlen(completion);
               char* match = strstr(ce_json_obj_get_string(&value->obj, &label_find),
                                    completion);
               if(match && strlen(match + completion_len) > 0){
                    char buffer[BUFSIZ];
                    if(detail_find.type == CE_JSON_TYPE_STRING){
                         snprintf(buffer, BUFSIZ, "%s%s",
                                  ce_json_obj_get_string(&value->obj, &detail_find),
                                  match + completion_len);
                    }else{
                         snprintf(buffer, BUFSIZ, "%s", match + completion_len);
                    }
                    description = strdup(buffer);
               }else if(detail_find.type == CE_JSON_TYPE_STRING){
                    description = strdup(ce_json_obj_get_string(&value->obj, &detail_find));
               }
          }else{
               description = strdup(ce_json_obj_get_string(&value->obj, &detail_find));
          }

          int64_t new_completion_count = completion_count + 1;
          completions = realloc(completions, new_completion_count * sizeof(completions[0]));
          descriptions = realloc(descriptions, new_completion_count * sizeof(descriptions[0]));
          completions[completion_count] = completion;
          descriptions[completion_count] = description;
          completion_count = new_completion_count;

          CeJsonFindResult_t text_edit_find = ce_json_obj_find(&value->obj, "textEdit");
          if(text_edit_find.type != CE_JSON_TYPE_OBJECT){
               continue;
          }
          CeJsonObj_t* text_edit_obj = ce_json_obj_get_obj(&value->obj, &text_edit_find);
          if(text_edit_obj == NULL){
               continue;
          }
          CeJsonFindResult_t range_find = ce_json_obj_find(text_edit_obj, "range");
          if(range_find.type != CE_JSON_TYPE_OBJECT){
               continue;
          }
          CeJsonObj_t* range_obj = ce_json_obj_get_obj(text_edit_obj, &range_find);
          if(range_obj == NULL){
               continue;
          }
          CeJsonFindResult_t start_find = ce_json_obj_find(range_obj, "start");
          if(start_find.type != CE_JSON_TYPE_OBJECT){
               continue;
          }
          CeJsonObj_t* start_obj = ce_json_obj_get_obj(range_obj, &start_find);
          if(start_obj == NULL){
               continue;
          }
          CeJsonFindResult_t line_find = ce_json_obj_find(start_obj, "line");
          if(line_find.type != CE_JSON_TYPE_NUMBER){
               continue;
          }
          CeJsonFindResult_t character_find = ce_json_obj_find(start_obj, "character");
          if(character_find.type != CE_JSON_TYPE_NUMBER){
               continue;
          }
          start->x = *ce_json_obj_get_number(start_obj, &character_find);
          start->y = *ce_json_obj_get_number(start_obj, &line_find);
     }

     result = malloc(sizeof(*result));
     memset(result, 0, sizeof(*result));
     ce_complete_init(result, (const char**)completions, (const char**)descriptions, completion_count);
     for(int64_t i = 0; i < completion_count; i++){
          free(completions[i]);
          free(descriptions[i]);
     }
     free(completions);
     free(descriptions);
     return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x20d8, %rsp           # imm = 0x20D8
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x1d18b(%rip), %rsi     # 0x2fbb7
callq 0x1c543
movl %eax, 0xc0(%rsp)
movq %rdx, 0xc8(%rsp)
cmpl $0x1, %eax
jne 0x12dc7
leaq 0xc0(%rsp), %rsi
movq %rbx, %rdi
callq 0x1c596
movq %rax, %rbx
leaq 0x1d15b(%rip), %rsi     # 0x2fbbe
movq %rax, %rdi
callq 0x1c543
movl %eax, 0xb0(%rsp)
movq %rdx, 0xb8(%rsp)
cmpl $0x2, %eax
jne 0x12dc7
leaq 0xb0(%rsp), %rsi
movq %rbx, %rdi
callq 0x1c5b1
testq %rax, %rax
je 0x12dc7
movq %rax, %rbx
cmpq $0x0, 0x8(%rax)
jle 0x12dde
movq %r14, 0x30(%rsp)
movl $0x8, %r13d
leaq 0x1d108(%rip), %r14     # 0x2fbc4
movq $0x0, 0x18(%rsp)
movq $0x0, 0x10(%rsp)
xorl %r12d, %r12d
xorl %r15d, %r15d
movq %rbx, 0x38(%rsp)
movq (%rbx), %rbp
cmpl $0x1, -0x8(%rbp,%r13)
jne 0x12db4
addq %r13, %rbp
movq %rbp, %rdi
movq %r14, %rsi
callq 0x1c543
movl %eax, 0xa0(%rsp)
movq %rdx, 0xa8(%rsp)
cmpl $0x3, %eax
jne 0x12db4
movq %r12, 0x48(%rsp)
movq %rbp, %rdi
leaq 0x1d0b2(%rip), %rsi     # 0x2fbcf
callq 0x1c543
movl %eax, 0x20(%rsp)
movq %rdx, 0x28(%rsp)
movq %rbp, %rdi
leaq 0xa0(%rsp), %rsi
callq 0x1c5cc
movq %rax, %rdi
callq 0xd640
movq %rax, %rbx
movq %rbp, %rdi
leaq 0x1d086(%rip), %rsi     # 0x2fbd6
callq 0x1c543
movl %eax, 0x90(%rsp)
movq %rdx, 0x98(%rsp)
cmpl $0x3, %eax
movq %rbx, 0x40(%rsp)
jne 0x12be7
movq %rbx, %rdi
callq 0xd210
movq %rax, %r12
movq %rbp, %rdi
leaq 0x90(%rsp), %rsi
callq 0x1c5cc
movq %rax, %rdi
movq %rbx, %rsi
callq 0xd6f0
testq %rax, %rax
je 0x12be0
movq %rax, %r14
cmpb $0x0, (%rax,%r12)
je 0x12be0
addq %r12, %r14
cmpl $0x3, 0x20(%rsp)
jne 0x12c04
movq %rbp, %rdi
leaq 0x20(%rsp), %rsi
callq 0x1c5cc
movl $0x2000, %esi           # imm = 0x2000
leaq 0xd0(%rsp), %rbx
movq %rbx, %rdi
leaq 0x1d00b(%rip), %rdx     # 0x2fbdc
movq %rax, %rcx
movq %r14, %r8
xorl %eax, %eax
callq 0xd260
jmp 0x12c25
cmpl $0x3, 0x20(%rsp)
jne 0x12bf9
movq %rbp, %rdi
leaq 0x20(%rsp), %rsi
callq 0x1c5cc
movq %rax, %rdi
jmp 0x12c28
movq $0x0, 0x8(%rsp)
jmp 0x12c32
movl $0x2000, %esi           # imm = 0x2000
leaq 0xd0(%rsp), %rbx
movq %rbx, %rdi
leaq 0x1eca1(%rip), %rdx     # 0x318bc
movq %r14, %rcx
xorl %eax, %eax
callq 0xd260
movq %rbx, %rdi
callq 0xd640
movq %rax, 0x8(%rsp)
movq 0x18(%rsp), %rbx
leaq 0x8(,%rbx,8), %r12
movq 0x10(%rsp), %rdi
movq %r12, %rsi
callq 0xd520
movq %rax, %r14
movq 0x48(%rsp), %rdi
movq %r12, %rsi
callq 0xd520
movq %rax, %r12
movq %r14, 0x10(%rsp)
movq 0x40(%rsp), %rax
movq %rax, (%r14,%rbx,8)
movq 0x8(%rsp), %rax
movq %rax, (%r12,%rbx,8)
movq %rbp, %rdi
leaq 0x1cf61(%rip), %rsi     # 0x2fbe1
callq 0x1c543
movl %eax, 0xd0(%rsp)
movq %rdx, 0xd8(%rsp)
cmpl $0x1, %eax
leaq 0x1cf26(%rip), %r14     # 0x2fbc4
jne 0x12daa
movq %rbp, %rdi
leaq 0xd0(%rsp), %rsi
callq 0x1c596
testq %rax, %rax
je 0x12daa
movq %rax, %rbx
movq %rax, %rdi
leaq 0x1cf20(%rip), %rsi     # 0x2fbea
callq 0x1c543
movl %eax, 0x80(%rsp)
movq %rdx, 0x88(%rsp)
cmpl $0x1, %eax
jne 0x12daa
movq %rbx, %rdi
leaq 0x80(%rsp), %rsi
callq 0x1c596
testq %rax, %rax
je 0x12daa
movq %rax, %rbx
movq %rax, %rdi
leaq 0x1b9bc(%rip), %rsi     # 0x2e6c9
callq 0x1c543
movl %eax, 0x70(%rsp)
movq %rdx, 0x78(%rsp)
cmpl $0x1, %eax
jne 0x12daa
movq %rbx, %rdi
leaq 0x70(%rsp), %rsi
callq 0x1c596
testq %rax, %rax
je 0x12daa
movq %rax, %rbx
movq %rax, %rdi
leaq 0x1bf78(%rip), %rsi     # 0x2ecbb
callq 0x1c543
movl %eax, 0x60(%rsp)
movq %rdx, 0x68(%rsp)
cmpl $0x4, %eax
jne 0x12daa
movq %rbx, %rdi
leaq 0x1ce90(%rip), %rsi     # 0x2fbf0
callq 0x1c543
movl %eax, 0x50(%rsp)
movq %rdx, 0x58(%rsp)
cmpl $0x4, %eax
jne 0x12daa
movq %rbx, %rdi
leaq 0x50(%rsp), %rsi
callq 0x1c5e5
cvttsd2si (%rax), %rax
movq 0x30(%rsp), %r14
movq %rax, (%r14)
movq %rbx, %rdi
leaq 0x60(%rsp), %rsi
callq 0x1c5e5
cvttsd2si (%rax), %rax
movq %rax, 0x8(%r14)
leaq 0x1ce1a(%rip), %r14     # 0x2fbc4
incq 0x18(%rsp)
movq 0x38(%rsp), %rbx
incq %r15
addq $0x18, %r13
cmpq 0x8(%rbx), %r15
jl 0x12ad9
jmp 0x12df3
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x20d8, %rsp           # imm = 0x20D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %r12d, %r12d
movq $0x0, 0x10(%rsp)
movq $0x0, 0x18(%rsp)
movl $0x20, %edi
callq 0xd4c0
movq %rax, %rbx
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movups %xmm0, 0x10(%rax)
movq %rax, %rdi
movq 0x10(%rsp), %r13
movq %r13, %rsi
movq %r12, %rdx
movq 0x18(%rsp), %r15
movq %r15, %rcx
callq 0x19fd4
testq %r15, %r15
jle 0x12e48
xorl %r14d, %r14d
movq (%r13,%r14,8), %rdi
callq 0xd090
movq (%r12,%r14,8), %rdi
callq 0xd090
incq %r14
cmpq %r14, %r15
jne 0x12e2d
movq %r13, %rdi
callq 0xd090
movq %r12, %rdi
callq 0xd090
jmp 0x12dc9