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

```asm
<ffmkky>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x118,%rsp
  mov    %rdi,0x38(%rsp)
  mov    %rsi,0x18(%rsp)
  mov    %rdx,0x30(%rsp)
  mov    %rcx,0x10(%rsp)
  mov    %r8,0x20(%rsp)
  mov    %fs:0x28,%rax
  mov    %rax,0x108(%rsp)
  xor    %eax,%eax
  mov    (%r8),%eax
  movl   $0xffffffff,0x5c(%rsp)
  test   %eax,%eax
  jg     L560
  movb   $0x0,(%rcx)
  cmpb   $0x20,(%rdi)
  movb   $0x0,0x60(%rsp)
  movb   $0x0,0xb0(%rsp)
  jne    L463
  lea    0x1(%rdi),%rax
  nopl   0x0(%rax)
L534:
  mov    %rax,%rsi
  add    $0x1,%rax
  cmpb   $0x20,-0x1(%rax)
  je     L534
L331:
  lea    0x60(%rsp),%r13
  mov    $0x4a,%edx
  mov    %r13,%rdi
  call   <strncat@plt>
  mov    0x18(%rsp),%rdi
  call   <strlen@plt>
  mov    %r13,%rdi
  mov    %eax,0x4c(%rsp)
  cltq
  mov    %rax,0x28(%rsp)
  call   <strlen@plt>
  cltq
  mov    %rax,0x8(%rsp)
  test   %rax,%rax
  je     L162
  mov    0x8(%rsp),%rax
  lea    -0x1(%r13,%rax,1),%rax
  cmpb   $0x20,(%rax)
  jne    L56
  nopl   0x0(%rax,%rax,1)
L682:
  movb   $0x0,(%rax)
  sub    $0x1,%rax
  cmpb   $0x20,(%rax)
  je     L682
L56:
  sub    %r13,%rax
  mov    $0x3d,%esi
  mov    %r13,%rdi
  add    $0x1,%rax
  mov    %rax,0x8(%rsp)
  mov    %rax,%rbx
  call   <strchr@plt>
  test   %rax,%rax
  jne    L797
  cmp    $0x8,%rbx
  jbe    L155
L318:
  movzbl 0x60(%rsp),%eax
  cmp    $0x48,%al
  je     L215
L576:
  cmp    $0x68,%al
  je     L542
L146:
  lea    0xb0(%rsp),%rbp
  mov    $0x4a,%edx
  mov    %r13,%rsi
  mov    %rbp,%rdi
  lea    D29(%rip),%r14
  call   <strncat@plt>
  mov    %r14,%rsi
  mov    %rbp,%rdi
  call   <strtok@plt>
  mov    %rax,%r12
  test   %rax,%rax
  je     L532
  lea    0x5c(%rsp),%r15
  xor    %eax,%eax
  mov    %r13,0x40(%rsp)
  xor    %ebx,%ebx
  mov    %r12,%r13
  xor    %ebp,%ebp
  mov    %r15,%r12
  mov    %eax,%r15d
  jmp    L269
  nopl   0x0(%rax)
L533:
  mov    %r13,%rdi
  mov    %r12,%rsi
  movl   $0xffffffff,0x5c(%rsp)
  call   <fftkey@plt>
  mov    %r14,%rsi
  test   %rax,%rax
  mov    $0x1,%eax
  cmovg  %eax,%ebx
  xor    %edi,%edi
  add    $0x1,%ebp
  call   <strtok@plt>
  mov    %rax,%r13
  test   %rax,%rax
  je     L785
L269:
  mov    %r13,%rdi
  call   <strlen@plt>
  cmp    %r15d,%eax
  jle    L533
  mov    %r13,%rdi
  call   <strlen@plt>
  mov    %eax,%r15d
  jmp    L533
  nopl   (%rax)
L785:
  mov    0x8(%rsp),%rax
  movl   $0xffffffff,0x5c(%rsp)
  mov    0x40(%rsp),%r13
  lea    0xb(%rax),%r14
  cmp    $0x50,%r14
  ja     L808
  mov    0x10(%rsp),%r15
  lea    D66(%rip),%rsi
  mov    %r15,%rdi
  call   <strcat@plt>
  mov    %r13,%rsi
  mov    %r15,%rdi
  call   <strcat@plt>
  mov    0x28(%rsp),%rax
  mov    0x8(%rsp),%rdx
  lea    0xc(%rax,%rdx,1),%rax
  cmp    $0x50,%rax
  ja     L387
  mov    0x10(%rsp),%rdi
  lea    D67(%rip),%rsi
  call   <strcat@plt>
  mov    0x8(%rsp),%r14
  add    $0xc,%r14
L165:
  cmpq   $0x0,0x28(%rsp)
  je     L691
L340:
  mov    0x18(%rsp),%rax
  cmpb   $0x27,(%rax)
  je     L657
L164:
  mov    0x28(%rsp),%rax
  add    %r14,%rax
  cmp    $0x50,%rax
  ja     L407
  mov    $0x1e,%r12d
  mov    $0x50,%r13d
  mov    %ebx,%edx
  sub    %r14d,%r13d
  cmp    %r12,%rax
  cmovae %rax,%r12
  cmp    $0x1,%ebp
  sete   %cl
  and    $0x1,%edx
  or     %edx,%ecx
  mov    %ecx,%ebx
  cmp    $0x1d,%rax
  jbe    L391
  mov    0x18(%rsp),%rsi
  mov    0x10(%rsp),%rdi
  mov    %r13d,%edx
  call   <strncat@plt>
  cmpq   $0x0,0x30(%rsp)
  je     L284
L147:
  cmp    $0x4c,%r12
  jbe    L636
L284:
  test   %bl,%bl
  je     L465
  lea    D78(%rip),%rdi
  call   <ffpmsg@plt>
  mov    0x10(%rsp),%rdi
  call   <ffpmsg@plt>
L465:
  mov    0x20(%rsp),%rax
  mov    (%rax),%eax
L560:
  mov    0x108(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L737
  add    $0x118,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   0x0(%rax,%rax,1)
L162:
  mov    $0x3d,%esi
  mov    %r13,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  jne    L797
  lea    0x5c(%rsp),%r15
  mov    %r13,%rdi
  mov    %r15,%rsi
  call   <fftkey@plt>
  test   %rax,%rax
  jg     L318
  mov    0x10(%rsp),%rdi
  mov    %r13,%rsi
  call   <strcat@plt>
L160:
  mov    0x8(%rsp),%rdx
  mov    $0x8,%eax
  movabs $0x2020202020202020,%rcx
  sub    %rdx,%rax
  add    0x10(%rsp),%rdx
  cmp    $0x8,%eax
  jae    L622
  test   $0x4,%al
  jne    L419
  test   %eax,%eax
  je     L494
  movb   $0x20,(%rdx)
  test   $0x2,%al
  jne    L40
L494:
  mov    0x10(%rsp),%rax
  mov    $0x203d,%edx
  cmpq   $0x0,0x28(%rsp)
  mov    %dx,0x8(%rax)
  movb   $0x0,0xa(%rax)
  je     L0
  mov    0x18(%rsp),%rax
  cmpb   $0x27,(%rax)
  je     L646
  xor    %ebx,%ebx
  xor    %ebp,%ebp
  mov    $0xa,%r14d
  jmp    L164
  nopl   0x0(%rax,%rax,1)
L387:
  lea    D24(%rip),%rsi
  mov    %r15,%rdi
  call   <strcat@plt>
  cmpq   $0x0,0x28(%rsp)
  jne    L340
L691:
  cmp    $0x1,%ebp
  sete   %al
  and    $0x1,%ebx
  or     %eax,%ebx
  cmp    $0xa,%r14
  jne    L284
  mov    0x10(%rsp),%rdi
  mov    0x30(%rsp),%rax
  movb   $0x20,0x8(%rdi)
  test   %rax,%rax
  je     L284
  mov    $0x46,%edx
  mov    %rax,%rsi
  call   <strncat@plt>
  jmp    L284
L532:
  lea    0x5c(%rsp),%rsi
  mov    %r13,%rdi
  movl   $0xffffffff,0x5c(%rsp)
  call   <fftkey@plt>
  test   %rax,%rax
  jg     L208
  mov    0x10(%rsp),%rbx
  mov    %r13,%rsi
  mov    $0x4a,%edx
  mov    %rbx,%rdi
  call   <strncat@plt>
  lea    D24(%rip),%rsi
  mov    %rbx,%rdi
L212:
  call   <strcat@plt>
  mov    0x8(%rsp),%r14
  xor    %ebx,%ebx
  xor    %ebp,%ebp
  add    $0x2,%r14
  jmp    L165
  nopl   (%rax)
L797:
  lea    D43(%rip),%rdi
L709:
  call   <ffpmsg@plt>
  mov    %r13,%rdi
  call   <ffpmsg@plt>
  mov    0x20(%rsp),%rax
  movl   $0xcf,(%rax)
  mov    $0xcf,%eax
  jmp    L560
  nopl   0x0(%rax)
L463:
  mov    0x38(%rsp),%rsi
  jmp    L331
  nopw   0x0(%rax,%rax,1)
L657:
  cmp    $0x4d,%r14
  ja     L407
  mov    $0x50,%edx
  mov    %ebx,%eax
  sub    %r14d,%edx
  cmp    $0x1,%ebp
  sete   %cl
  and    $0x1,%eax
  or     %eax,%ecx
  mov    %ecx,%ebx
L648:
  mov    0x10(%rsp),%r15
  mov    0x18(%rsp),%rsi
  mov    $0x50,%r12d
  mov    %r15,%rdi
  call   <strncat@plt>
  add    0x28(%rsp),%r14
  cmp    %r12,%r14
  cmovbe %r14,%r12
  cmp    $0x4f,%r14
  jbe    L288
  cmpq   $0x0,0x30(%rsp)
  movb   $0x27,0x4f(%r15)
  jne    L147
  jmp    L284
  nopl   (%rax)
L542:
  mov    $0x9,%edx
  lea    D65(%rip),%rsi
  mov    %r13,%rdi
  call   <strncmp@plt>
  test   %eax,%eax
  jne    L146
L34:
  mov    0x10(%rsp),%rdi
  mov    %r13,%rsi
  call   <strcat@plt>
  mov    0x28(%rsp),%rax
  mov    0x8(%rsp),%rdx
  lea    0x3(%rax,%rdx,1),%rax
  cmp    $0x50,%rax
  jbe    L417
  mov    0x10(%rsp),%rdi
  lea    D24(%rip),%rsi
  jmp    L212
  nop
L808:
  lea    D151(%rip),%rdi
  call   <ffpmsg@plt>
  mov    0x38(%rsp),%rdi
  call   <ffpmsg@plt>
  mov    0x20(%rsp),%rax
  movl   $0xcf,(%rax)
  mov    $0xcf,%eax
  jmp    L560
L417:
  mov    0x10(%rsp),%rdi
  lea    D67(%rip),%rsi
  xor    %ebx,%ebx
  xor    %ebp,%ebp
  call   <strcat@plt>
  mov    0x8(%rsp),%r14
  add    $0x3,%r14
  jmp    L165
L407:
  lea    D6(%rip),%rdi
  call   <ffpmsg@plt>
  mov    0x38(%rsp),%rdi
  call   <ffpmsg@plt>
  mov    0x18(%rsp),%rdi
  call   <ffpmsg@plt>
  mov    0x20(%rsp),%rax
  movl   $0xcf,(%rax)
  mov    $0xcf,%eax
  jmp    L560
L215:
  mov    $0x9,%edx
  lea    D66(%rip),%rsi
  mov    %r13,%rdi
  call   <strncmp@plt>
  test   %eax,%eax
  je     L34
  movzbl 0x60(%rsp),%eax
  jmp    L576
L391:
  mov    $0x1e,%edx
  sub    0x4c(%rsp),%edx
  lea    D30(%rip),%rsi
  sub    %r14d,%edx
  mov    0x10(%rsp),%r14
  mov    %r14,%rdi
  call   <strncat@plt>
  mov    0x18(%rsp),%rsi
  mov    %r13d,%edx
  mov    %r14,%rdi
  call   <strncat@plt>
  cmpq   $0x0,0x30(%rsp)
  je     L284
L636:
  mov    0x30(%rsp),%r14
  mov    %r14,%rdi
  call   <strlen@plt>
  test   %eax,%eax
  jle    L284
  mov    0x10(%rsp),%r15
  lea    D18(%rip),%rsi
  mov    %r15,%rdi
  call   <strcat@plt>
  mov    $0x4d,%edx
  mov    %r14,%rsi
  mov    %r15,%rdi
  sub    %r12d,%edx
  call   <strncat@plt>
  jmp    L284
L208:
  lea    D153(%rip),%rdi
  jmp    L709
L288:
  mov    0x30(%rsp),%rax
  test   %rax,%rax
  je     L284
  cmpb   $0x0,(%rax)
  je     L147
  cmp    $0x1d,%r14
  ja     L147
  lea    0x1(%r12),%rdx
  mov    $0x1e,%eax
  movabs $0x2020202020202020,%rsi
  sub    %r12,%rax
  cmp    $0x1e,%rdx
  mov    $0x1,%edx
  cmova  %rdx,%rax
  add    0x10(%rsp),%r12
  cmp    $0x8,%rax
  jae    L154
  test   $0x4,%al
  jne    L239
  test   %rax,%rax
  je     L626
  movb   $0x20,(%r12)
  test   $0x2,%al
  jne    L663
L626:
  mov    0x10(%rsp),%rax
  mov    $0x1e,%r12d
  movb   $0x0,0x1e(%rax)
  jmp    L636
L0:
  mov    0x10(%rsp),%rdi
  mov    0x30(%rsp),%rax
  movb   $0x20,0x8(%rdi)
  test   %rax,%rax
  je     L465
  mov    $0x46,%edx
  mov    %rax,%rsi
  call   <strncat@plt>
  jmp    L465
L622:
  mov    %eax,%esi
  mov    %rcx,(%rdx)
  mov    %rcx,-0x8(%rdx,%rsi,1)
  lea    0x8(%rdx),%rsi
  and    $0xfffffffffffffff8,%rsi
  sub    %rsi,%rdx
  add    %edx,%eax
  and    $0xfffffff8,%eax
  cmp    $0x8,%eax
  jb     L494
  and    $0xfffffff8,%eax
  xor    %edx,%edx
L765:
  mov    %edx,%edi
  add    $0x8,%edx
  mov    %rcx,(%rsi,%rdi,1)
  cmp    %eax,%edx
  jb     L765
  jmp    L494
L646:
  xor    %ebx,%ebx
  mov    $0x46,%edx
  mov    $0xa,%r14d
  jmp    L648
L154:
  lea    0x8(%r12),%rcx
  mov    %rsi,(%r12)
  and    $0xfffffffffffffff8,%rcx
  mov    %rsi,-0x8(%r12,%rax,1)
  sub    %rcx,%r12
  add    %r12,%rax
  and    $0xfffffffffffffff8,%rax
  cmp    $0x8,%rax
  jb     L626
  and    $0xfffffffffffffff8,%rax
  xor    %edx,%edx
L104:
  mov    %rsi,(%rcx,%rdx,1)
  add    $0x8,%rdx
  cmp    %rax,%rdx
  jb     L104
  jmp    L626
L419:
  mov    %eax,%eax
  movl   $0x20202020,(%rdx)
  movl   $0x20202020,-0x4(%rdx,%rax,1)
  jmp    L494
L40:
  mov    %eax,%eax
  movw   $0x2020,-0x2(%rdx,%rax,1)
  jmp    L494
L239:
  movl   $0x20202020,(%r12)
  movl   $0x20202020,-0x4(%r12,%rax,1)
  jmp    L626
L737:
  call   <__stack_chk_fail@plt>
L155:
  lea    0x5c(%rsp),%r15
  mov    %r13,%rdi
  mov    %r15,%rsi
  call   <fftkey@plt>
  test   %rax,%rax
  jg     L318
  mov    0x10(%rsp),%rdi
  mov    %r13,%rsi
  call   <strcat@plt>
  cmpq   $0x8,0x8(%rsp)
  je     L494
  jmp    L160
L663:
  movw   $0x2020,-0x2(%r12,%rax,1)
  jmp    L626
```

tool_calls: name: parse_data
arguments: data_tag: D29
type: string
name: parse_data
arguments: data_tag: D66
type: string
name: parse_data
arguments: data_tag: D67
type: string
name: parse_data
arguments: data_tag: D78
type: string
name: parse_data
arguments: data_tag: D24
type: string
name: parse_data
arguments: data_tag: D43
type: string
name: parse_data
arguments: data_tag: D65
type: string
name: parse_data
arguments: data_tag: D151
type: string
name: parse_data
arguments: data_tag: D6
type: string
name: parse_data
arguments: data_tag: D30
type: string
name: parse_data
arguments: data_tag: D18
type: string
name: parse_data
arguments: data_tag: D153
type: string

tool: D29:  

tool: D66: HIERARCH 

tool: D67:  = 

tool: D78: Warning: the following keyword does not conform to the HIERARCH convention

tool: D24: = 

tool: D43: Illegal keyword name; contains an equals sign (=)

tool: D65: hierarch 

tool: D151: The following keyword is too long to fit on a card:

tool: D6: The following keyword + value is too long to fit on a card:

tool: D30:                     

tool: D18:  / 

tool: D153: Illegal keyword name:

assistant: ```c
int ffmkky(const char *keyname, char *value, const char *comm, char *card, int *status) {
  size_t namelen, len, ii;
  char tmpname[75], tmpname2[75], *cptr;
  char *saveptr;
  int tstatus = -1, nblank = 0, ntoken = 0, maxlen = 0, specialchar = 0;
  if (*status > 0)
    return (*status);
  *tmpname = '\0';
  *tmpname2 = '\0';
  *card = '\0';
  while (*(keyname + nblank) == ' ')
    nblank++;
  strncat(tmpname, keyname + nblank, 75 - 1);
  len = strlen(value);
  namelen = strlen(tmpname);
  if (namelen) {
    cptr = tmpname + namelen - 1;
    while (*cptr == ' ') {
      *cptr = '\0';
      cptr--;
    }
    namelen = cptr - tmpname + 1;
  }
  if (strchr(tmpname, '=')) {
    ffpmsg("Illegal keyword name; contains an equals sign (=)");
    ffpmsg(tmpname);
    return (*status = 207);
  }
  if (namelen <= 8 && fftkey(tmpname, &tstatus) <= 0) {
    strcat(card, tmpname);
    for (ii = namelen; ii < 8; ii++)
      card[ii] = ' ';
    card[8] = '=';
    card[9] = ' ';
    card[10] = '\0';
    namelen = 10;
  } else if ((((tmpname)[0] < ("HIERARCH ")[0] ? -1 : (tmpname)[0] > ("HIERARCH ")[0] ? 1 : strncmp((tmpname), ("HIERARCH "), (9))) == 0) || (((tmpname)[0] < ("hierarch ")[0] ? -1 : (tmpname)[0] > ("hierarch ")[0] ? 1 : strncmp((tmpname), ("hierarch "), (9))) == 0)) {
    strcat(card, tmpname);
    if (namelen + 3 + len > 80) {
      strcat(card, "= ");
      namelen += 2;
    } else {
      strcat(card, " = ");
      namelen += 3;
    }
  } else {
    strncat(tmpname2, tmpname, 75 - 1);
    cptr = strtok(tmpname2, " ");
    while (cptr) {
      if (strlen(cptr) > maxlen)
        maxlen = strlen(cptr);
      tstatus = -1;
      if (fftkey(cptr, &tstatus) > 0)
        specialchar = 1;
      cptr = strtok(NULL, " ");
      ntoken++;
    }
    tstatus = -1;
    if (ntoken > 0) {
      if (namelen + 11 > 81 - 1) {
        ffpmsg("The following keyword is too long to fit on a card:");
        ffpmsg(keyname);
        return (*status = 207);
      }
      strcat(card, "HIERARCH ");
      strcat(card, tmpname);
      namelen += 9;
      if (namelen + 3 + len > 80) {
        strcat(card, "= ");
        namelen += 2;
      } else {
        strcat(card, " = ");
        namelen += 3;
      }
    } else if ((fftkey(tmpname, &tstatus) <= 0)) {
      strncat(card, tmpname, 75 - 1);
      strcat(card, "= ");
      namelen += 2;
    } else {
      ffpmsg("Illegal keyword name:");
      ffpmsg(tmpname);
      return (*status = 207);
    }
  }
  if (len > 0) {
    if (value[0] == '\'') {
      if (namelen > 77) {
        ffpmsg("The following keyword + value is too long to fit on a card:");
        ffpmsg(keyname);
        ffpmsg(value);
        return (*status = 207);
      }
      strncat(card, value, 80 - namelen);
      len = ((80) < (namelen + len) ? (80) : (namelen + len));
      if (len == 80) {
        card[79] = '\'';
      }
      if (comm) {
        if (comm[0] != 0) {
          if (len < 30) {
            for (ii = len; ii < 30; ii++)
              card[ii] = ' ';
            card[30] = '\0';
            len = 30;
          }
        }
      }
    } else {
      if (namelen + len > 80) {
        ffpmsg("The following keyword + value is too long to fit on a card:");
        ffpmsg(keyname);
        ffpmsg(value);
        return (*status = 207);
      } else if (namelen + len < 30) {
        strncat(card, "                    ", 30 - (namelen + len));
      }
      strncat(card, value, 80 - namelen);
      len = ((80) < (namelen + len) ? (80) : (namelen + len));
      len = ((30) > (len) ? (30) : (len));
    }
    if (comm) {
      if ((len < 77) && (strlen(comm) > 0)) {
        strcat(card, " / ");
        strncat(card, comm, 77 - len);
      }
    }
  } else {
    if (namelen == 10) {
      card[8] = ' ';
      if (comm) {
        strncat(card, comm, 80 - namelen);
      }
    }
  }
  if (ntoken == 1 || specialchar == 1) {
    ffpmsg("Warning: the following keyword does not conform to the HIERARCH convention");
    ffpmsg(card);
  }
  return (*status);
}
```