user: Translate the below assembly code into C programming language:

```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     L209
  mov    %rdi,%r13
  movsbl (%rdi),%edi
  mov    %rsi,%rbx
  mov    %rdx,%r14
  mov    %r13,%r12
  test   %dil,%dil
  jne    L472
  jmp    L172
  nopw   0x0(%rax,%rax,1)
L29:
  movsbl 0x1(%r12),%edi
  add    $0x1,%r12
  test   %dil,%dil
  je     L172
L472:
  call   <isspace@plt>
  test   %rax,%rax
  jne    L29
  movsbl (%r12),%edi
  test   %dil,%dil
  je     L172
  cmp    $0x23,%dil
  je     L172
  mov    %r12,%rbp
  cmp    $0x5b,%dil
  jne    L313
  movzbl 0x1(%r12),%eax
  lea    0x1(%r12),%rbp
  mov    %rbp,%rdx
  test   %al,%al
  je     L114
  cmp    $0x5d,%al
  jne    L276
L114:
  cmp    $0x5d,%al
  jne    L492
L158:
  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     L127
  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)
L333:
  movsbl 0x1(%rbp),%edi
  add    $0x1,%rbp
  test   %dil,%dil
  je     L36
L313:
  call   <isalnum@plt>
  test   %rax,%rax
  jne    L333
  movsbl 0x0(%rbp),%edi
  test   %dil,%dil
  je     L36
  mov    %rbp,%rax
  sub    %r12,%rax
  mov    %rax,(%rsp)
  mov    %eax,0xc(%rsp)
  jmp    L411
L244:
  movsbl 0x0(%rbp),%edi
  test   %dil,%dil
  je     L36
L411:
  call   <isspace@plt>
  mov    %rbp,%rdx
  add    $0x1,%rbp
  test   %rax,%rax
  jne    L244
  cmpb   $0x3d,(%rdx)
  jne    L36
  movsbl 0x1(%rdx),%edi
  test   %dil,%dil
  jne    L373
  jmp    L173
  nopw   0x0(%rax,%rax,1)
L358:
  movsbl 0x1(%rbp),%edi
  add    $0x1,%rbp
  test   %dil,%dil
  je     L173
L373:
  call   <isspace@plt>
  test   %rax,%rax
  jne    L358
  movsbl 0x0(%rbp),%edi
L173:
  call   <isalnum@plt>
  test   %rax,%rax
  je     L36
  movsbl 0x0(%rbp),%edi
  cmp    $0x23,%dil
  je     L36
  mov    %rbp,%r15
  test   %dil,%dil
  jne    L397
  jmp    L402
  nopl   0x0(%rax)
L302:
  movsbl (%r15),%edi
  cmp    $0x23,%dil
  je     L423
  movsbl 0x1(%r15),%edi
  add    $0x1,%r15
  test   %dil,%dil
  je     L435
L397:
  call   <isalnum@plt>
  test   %rax,%rax
  jne    L302
  mov    %r15d,%eax
  sub    %ebp,%eax
  mov    %eax,0x8(%rsp)
  movsbl (%r15),%edi
  test   %dil,%dil
  jne    L163
  jmp    L335
  xchg   %ax,%ax
L236:
  movsbl 0x1(%r15),%edi
  add    $0x1,%r15
  test   %dil,%dil
  je     L335
L163:
  call   <isspace@plt>
  test   %rax,%rax
  jne    L236
  movzbl (%r15),%eax
  test   %al,%al
  je     L335
  cmp    $0x23,%al
  jne    L36
  nopl   0x0(%rax,%rax,1)
L335:
  mov    (%rsp),%eax
  lea    0x1(%rax),%edi
  call   <malloc@plt>
  mov    %rax,(%rbx)
  test   %rax,%rax
  je     L331
  mov    0x8(%rsp),%eax
  lea    0x1(%rax),%edi
  call   <malloc@plt>
  mov    %rax,(%r14)
  test   %rax,%rax
  je     L24
  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
L132:
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   (%rax)
L425:
  cmp    $0x5d,%al
  je     L158
L276:
  movzbl 0x1(%rdx),%eax
  add    $0x1,%rdx
  test   %al,%al
  jne    L425
  jmp    L114
  nopl   0x0(%rax)
L172:
  add    $0x18,%rsp
  xor    %eax,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   0x0(%rax)
L423:
  mov    %r15d,%eax
  sub    %ebp,%eax
  mov    %eax,0x8(%rsp)
  jmp    L163
  xchg   %ax,%ax
L435:
  mov    %r15d,%eax
  sub    %ebp,%eax
  mov    %eax,0x8(%rsp)
  jmp    L335
L492:
  mov    %r13,%rsi
  lea    D58(%rip),%rdi
  xor    %eax,%eax
  call   <printf@plt>
  mov    $0xffffffff,%eax
  jmp    L132
  cs nopw 0x0(%rax,%rax,1)
L36:
  mov    %r13,%rsi
  lea    D35(%rip),%rdi
  xor    %eax,%eax
  call   <printf@plt>
  mov    $0xffffffff,%eax
  jmp    L132
L402:
  movl   $0x0,0x8(%rsp)
  jmp    L335
L331:
  lea    D37(%rip),%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L132
L24:
  mov    (%rbx),%rdi
  call   <free@plt>
  movq   $0x0,(%rbx)
  lea    D50(%rip),%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L132
L127:
  lea    D31(%rip),%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L132
L209:
  lea    D40(%rip),%rdi
  call   <puts@plt>
  mov    $0xffffffff,%eax
  jmp    L132
```

tool_calls: name: parse_data
arguments: data_label: D58
type_guessed: string
name: parse_data
arguments: data_label: D35
type_guessed: string
name: parse_data
arguments: data_label: D37
type_guessed: string
name: parse_data
arguments: data_label: D50
type_guessed: string
name: parse_data
arguments: data_label: D31
type_guessed: string
name: parse_data
arguments: data_label: D40
type_guessed: string

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


tool: D35: invalid line[%s]


tool: D37: malloc ppkey failed.

tool: D50: malloc ppval failed.

tool: D31: malloc key failed.

tool: D40: 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;
}
```