user: What is the c source code of the assembly code below:

```asm
<get_key_value>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x18,%rsp
  movq   $0x0,(%rdx)
  movq   $0x0,(%rsi)
  test   %rdi,%rdi
  je     L195
  mov    %rdi,%r13
  movsbl (%rdi),%edi
  mov    %rsi,%rbx
  mov    %rdx,%r14
  mov    %r13,%r12
  test   %dil,%dil
  jne    L262
  jmp    L394
  nopw   0x0(%rax,%rax,1)
L86:
  movsbl 0x1(%r12),%edi
  add    $0x1,%r12
  test   %dil,%dil
  je     L394
L262:
  call   <isspace@plt>
  test   %rax,%rax
  jne    L86
  movsbl (%r12),%edi
  test   %dil,%dil
  je     L394
  cmp    $0x23,%dil
  je     L394
  mov    %r12,%rbp
  cmp    $0x5b,%dil
  jne    L448
  movzbl 0x1(%r12),%eax
  lea    0x1(%r12),%rbp
  mov    %rbp,%rdx
  test   %al,%al
  je     L144
  cmp    $0x5d,%al
  jne    L304
L144:
  cmp    $0x5d,%al
  jne    L396
L392:
  movb   $0x0,(%rdx)
  mov    %rbp,%rdi
  call   <strlen@plt>
  mov    $0x5,%edi
  call   <malloc@plt>
  mov    %rax,(%rbx)
  mov    %rax,%rdi
  test   %rax,%rax
  je     L36
  mov    %rbp,%rsi
  call   <strcpy@plt>
  add    $0x18,%rsp
  xor    %eax,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   (%rax)
L184:
  movsbl 0x1(%rbp),%edi
  add    $0x1,%rbp
  test   %dil,%dil
  je     L338
L448:
  call   <isalnum@plt>
  test   %rax,%rax
  jne    L184
  movsbl 0x0(%rbp),%edi
  test   %dil,%dil
  je     L338
  mov    %rbp,%rax
  sub    %r12,%rax
  mov    %rax,(%rsp)
  mov    %eax,0xc(%rsp)
  jmp    L39
L161:
  movsbl 0x0(%rbp),%edi
  test   %dil,%dil
  je     L338
L39:
  call   <isspace@plt>
  mov    %rbp,%rdx
  add    $0x1,%rbp
  test   %rax,%rax
  jne    L161
  cmpb   $0x3d,(%rdx)
  jne    L338
  movsbl 0x1(%rdx),%edi
  test   %dil,%dil
  jne    L219
  jmp    L241
  nopw   0x0(%rax,%rax,1)
L243:
  movsbl 0x1(%rbp),%edi
  add    $0x1,%rbp
  test   %dil,%dil
  je     L241
L219:
  call   <isspace@plt>
  test   %rax,%rax
  jne    L243
  movsbl 0x0(%rbp),%edi
L241:
  call   <isalnum@plt>
  test   %rax,%rax
  je     L338
  movsbl 0x0(%rbp),%edi
  cmp    $0x23,%dil
  je     L338
  mov    %rbp,%r15
  test   %dil,%dil
  jne    L417
  jmp    L283
  nopl   0x0(%rax)
L85:
  movsbl (%r15),%edi
  cmp    $0x23,%dil
  je     L486
  movsbl 0x1(%r15),%edi
  add    $0x1,%r15
  test   %dil,%dil
  je     L234
L417:
  call   <isalnum@plt>
  test   %rax,%rax
  jne    L85
  mov    %r15d,%eax
  sub    %ebp,%eax
  mov    %eax,0x8(%rsp)
  movsbl (%r15),%edi
  test   %dil,%dil
  jne    L228
  jmp    L308
  xchg   %ax,%ax
L114:
  movsbl 0x1(%r15),%edi
  add    $0x1,%r15
  test   %dil,%dil
  je     L308
L228:
  call   <isspace@plt>
  test   %rax,%rax
  jne    L114
  movzbl (%r15),%eax
  test   %al,%al
  je     L308
  cmp    $0x23,%al
  jne    L338
  nopl   0x0(%rax,%rax,1)
L308:
  mov    (%rsp),%eax
  lea    0x1(%rax),%edi
  call   <malloc@plt>
  mov    %rax,(%rbx)
  test   %rax,%rax
  je     L251
  mov    0x8(%rsp),%eax
  lea    0x1(%rax),%edi
  call   <malloc@plt>
  mov    %rax,(%r14)
  test   %rax,%rax
  je     L222
  mov    0xc(%rsp),%edx
  mov    (%rbx),%rdi
  mov    %r12,%rsi
  call   <memcpy@plt>
  movslq 0x8(%rsp),%r15
  mov    (%r14),%rdi
  mov    %rbp,%rsi
  mov    %r15d,%edx
  call   <memcpy@plt>
  movslq (%rsp),%rax
  mov    (%rbx),%rdx
  movb   $0x0,(%rdx,%rax,1)
  mov    (%r14),%rax
  movb   $0x0,(%rax,%r15,1)
  xor    %eax,%eax
L313:
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   (%rax)
L202:
  cmp    $0x5d,%al
  je     L392
L304:
  movzbl 0x1(%rdx),%eax
  add    $0x1,%rdx
  test   %al,%al
  jne    L202
  jmp    L144
  nopl   0x0(%rax)
L394:
  add    $0x18,%rsp
  xor    %eax,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   0x0(%rax)
L486:
  mov    %r15d,%eax
  sub    %ebp,%eax
  mov    %eax,0x8(%rsp)
  jmp    L228
  xchg   %ax,%ax
L234:
  mov    %r15d,%eax
  sub    %ebp,%eax
  mov    %eax,0x8(%rsp)
  jmp    L308
L396:
  mov    %r13,%rsi
  lea    D58(%rip),%rdi
  xor    %eax,%eax
  call   <printf@plt>
  mov    $0xffffffff,%eax
  jmp    L313
  cs nopw 0x0(%rax,%rax,1)
L338:
  mov    %r13,%rsi
  lea    D5(%rip),%rdi
  xor    %eax,%eax
  call   <printf@plt>
  mov    $0xffffffff,%eax
  jmp    L313
L283:
  movl   $0x0,0x8(%rsp)
  jmp    L308
L251:
  lea    D52(%rip),%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L313
L222:
  mov    (%rbx),%rdi
  call   <free@plt>
  movq   $0x0,(%rbx)
  lea    D45(%rip),%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L313
L36:
  lea    D7(%rip),%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L313
L195:
  lea    D4(%rip),%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L313
```

tool_calls: name: parse_data
arguments: data_tag: D58
datatype: string
name: parse_data
arguments: data_tag: D5
datatype: string
name: parse_data
arguments: data_tag: D52
datatype: string
name: parse_data
arguments: data_tag: D45
datatype: string
name: parse_data
arguments: data_tag: D7
datatype: string
name: parse_data
arguments: data_tag: D4
datatype: string

tool: D58: invalid line, line[%s]


tool: D5: invalid line[%s]


tool: D52: malloc ppkey failed.

tool: D45: malloc ppval failed.

tool: D7: malloc key failed.

tool: D4: buf is null

assistant: ```c
int get_key_value(char *buf, char **ppkey, char **ppval) {
  char *saveptr, *key, *value, *line;
  int keylen, vallen;
  line = buf;
  *ppkey = *ppval = NULL;
  if (line == NULL) {
    printf("buf is null\n");
    return -1;
  }
  for (; *line && isspace(*line); line++)
    ;
  if (*line == 0 || *line == '#') {
    return 0;
  }
  if (*line == '[') {
    key = ++line;
    while (*line && *line != ']')
      line++;
    if (*line == ']')
      *line = 0;
    else {
      printf("invalid line, line[%s]\n", buf);
      return -1;
    }
    keylen = strlen(key);
    *ppkey = (char *)malloc(sizeof(keylen) + 1);
    if (*ppkey == NULL) {
      printf("malloc key failed.\n");
      return -1;
    }
    strcpy(*ppkey, key);
    return 0;
  }
  key = line;
  while (*line && isalnum(*line))
    line++;
  if (*line == 0) {
    printf("invalid line[%s]\n", buf);
    return -1;
  }
  keylen = line - key;
  while (*line && isspace(*line))
    line++;
  if (*line++ != '=') {
    printf("invalid line[%s]\n", buf);
    return -1;
  }
  while (*line && isspace(*line))
    line++;
  if (!isalnum(*line) || *line == '#') {
    printf("invalid line[%s]\n", buf);
    return -1;
  }
  value = line;
  while (*line && isalnum(*line) && *line != '#')
    line++;
  vallen = line - value;
  while (*line && isspace(*line))
    line++;
  if (*line != 0 && *line != '#') {
    printf("invalid line[%s]\n", buf);
    return -1;
  }
  *ppkey = (char *)malloc(keylen + 1);
  if (*ppkey == NULL) {
    printf("malloc ppkey failed.\n");
    return -1;
  }
  *ppval = (char *)malloc(vallen + 1);
  if (*ppval == NULL) {
    free(*ppkey);
    *ppkey = NULL;
    printf("malloc ppval failed.\n");
    return -1;
  }
  memcpy(*ppkey, key, keylen);
  memcpy(*ppval, value, vallen);
  *(*ppkey + keylen) = 0;
  *(*ppval + vallen) = 0;
  return 0;
}
```