user: Please show me the C implementation that matches the assembly code listed below:

```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     L126
  movb   $0x0,(%rcx)
  cmpb   $0x20,(%rdi)
  movb   $0x0,0x60(%rsp)
  movb   $0x0,0xb0(%rsp)
  jne    L498
  lea    0x1(%rdi),%rax
  nopl   0x0(%rax)
L346:
  mov    %rax,%rsi
  add    $0x1,%rax
  cmpb   $0x20,-0x1(%rax)
  je     L346
L191:
  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     L548
  lea    -0x1(%r13,%rax,1),%rax
  cmpb   $0x20,(%rax)
  jne    L738
  xchg   %ax,%ax
L347:
  movb   $0x0,(%rax)
  sub    $0x1,%rax
  cmpb   $0x20,(%rax)
  je     L347
L738:
  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    L228
  cmp    $0x8,%rbx
  jbe    L591
L318:
  movzbl 0x60(%rsp),%eax
  cmp    $0x48,%al
  je     L330
L560:
  cmp    $0x68,%al
  je     L274
L428:
  lea    0xb0(%rsp),%rbp
  mov    $0x4a,%edx
  mov    %r13,%rsi
  mov    %rbp,%rdi
  lea    D77(%rip),%r14
  call   <strncat@plt>
  mov    %r14,%rsi
  mov    %rbp,%rdi
  call   <strtok@plt>
  mov    %rax,%r12
  test   %rax,%rax
  je     L83
  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    L602
  nopl   0x0(%rax)
L584:
  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     L292
L602:
  mov    %r13,%rdi
  call   <strlen@plt>
  cmp    %r15d,%eax
  jle    L584
  mov    %r13,%rdi
  call   <strlen@plt>
  mov    %eax,%r15d
  jmp    L584
  nopl   (%rax)
L292:
  mov    0x8(%rsp),%rax
  movl   $0xffffffff,0x5c(%rsp)
  mov    0x40(%rsp),%r13
  lea    0xb(%rax),%r14
  cmp    $0x50,%r14
  ja     L232
  mov    0x10(%rsp),%r15
  lea    D81(%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     L64
  mov    0x10(%rsp),%rdi
  lea    D66(%rip),%rsi
  call   <strcat@plt>
  mov    0x8(%rsp),%r14
  add    $0xc,%r14
L743:
  cmpq   $0x0,0x28(%rsp)
  je     L32
L750:
  mov    0x18(%rsp),%rax
  cmpb   $0x27,(%rax)
  je     L106
L61:
  mov    0x28(%rsp),%rax
  add    %r14,%rax
  cmp    $0x50,%rax
  ja     L540
  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    L27
  mov    0x18(%rsp),%rsi
  mov    0x10(%rsp),%rdi
  mov    %r13d,%edx
  call   <strncat@plt>
  cmpq   $0x0,0x30(%rsp)
  je     L726
L43:
  cmp    $0x4c,%r12
  jbe    L57
L726:
  test   %bl,%bl
  je     L581
  lea    D82(%rip),%rdi
  call   <ffpmsg@plt>
  mov    0x10(%rsp),%rdi
  call   <ffpmsg@plt>
L581:
  mov    0x20(%rsp),%rax
  mov    (%rax),%eax
L126:
  mov    0x108(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L345
  add    $0x118,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   0x0(%rax,%rax,1)
L548:
  mov    $0x3d,%esi
  mov    %r13,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  jne    L228
  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>
L613:
  mov    0x8(%rsp),%rdx
  mov    $0x8,%eax
  movabs $0x2020202020202020,%rcx
  sub    %rdx,%rax
  add    0x10(%rsp),%rdx
  cmp    $0x8,%eax
  jae    L429
  test   $0x4,%al
  jne    L360
  test   %eax,%eax
  je     L435
  movb   $0x20,(%rdx)
  test   $0x2,%al
  jne    L222
L435:
  mov    0x10(%rsp),%rax
  mov    $0x203d,%edx
  cmpq   $0x0,0x28(%rsp)
  mov    %dx,0x8(%rax)
  movb   $0x0,0xa(%rax)
  je     L784
  mov    0x18(%rsp),%rax
  cmpb   $0x27,(%rax)
  je     L21
  xor    %ebx,%ebx
  xor    %ebp,%ebp
  mov    $0xa,%r14d
  jmp    L61
  nopl   0x0(%rax,%rax,1)
L64:
  lea    D5(%rip),%rsi
  mov    %r15,%rdi
  call   <strcat@plt>
  cmpq   $0x0,0x28(%rsp)
  jne    L750
L32:
  cmp    $0x1,%ebp
  sete   %al
  and    $0x1,%ebx
  or     %eax,%ebx
  cmp    $0xa,%r14
  jne    L726
  mov    0x10(%rsp),%rdi
  mov    0x30(%rsp),%rax
  movb   $0x20,0x8(%rdi)
  test   %rax,%rax
  je     L726
  mov    $0x46,%edx
  mov    %rax,%rsi
  call   <strncat@plt>
  jmp    L726
L83:
  lea    0x5c(%rsp),%rsi
  mov    %r13,%rdi
  movl   $0xffffffff,0x5c(%rsp)
  call   <fftkey@plt>
  test   %rax,%rax
  jg     L257
  mov    0x10(%rsp),%rbx
  mov    %r13,%rsi
  mov    $0x4a,%edx
  mov    %rbx,%rdi
  call   <strncat@plt>
  lea    D5(%rip),%rsi
  mov    %rbx,%rdi
L432:
  call   <strcat@plt>
  mov    0x8(%rsp),%r14
  xor    %ebx,%ebx
  xor    %ebp,%ebp
  add    $0x2,%r14
  jmp    L743
  nopl   (%rax)
L228:
  lea    D145(%rip),%rdi
L785:
  call   <ffpmsg@plt>
  mov    %r13,%rdi
  call   <ffpmsg@plt>
  mov    0x20(%rsp),%rax
  movl   $0xcf,(%rax)
  mov    $0xcf,%eax
  jmp    L126
  nopl   0x0(%rax)
L498:
  mov    %rdi,%rsi
  jmp    L191
  nopl   0x0(%rax,%rax,1)
L106:
  cmp    $0x4d,%r14
  ja     L540
  mov    $0x50,%edx
  mov    %ebx,%eax
  sub    %r14d,%edx
  cmp    $0x1,%ebp
  sete   %cl
  and    $0x1,%eax
  or     %eax,%ecx
  mov    %ecx,%ebx
L177:
  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    L629
  cmpq   $0x0,0x30(%rsp)
  movb   $0x27,0x4f(%r15)
  jne    L43
  jmp    L726
  nopl   (%rax)
L274:
  mov    $0x9,%edx
  lea    D74(%rip),%rsi
  mov    %r13,%rdi
  call   <strncmp@plt>
  test   %eax,%eax
  jne    L428
L112:
  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    L424
  mov    0x10(%rsp),%rdi
  lea    D5(%rip),%rsi
  jmp    L432
  nopw   0x0(%rax,%rax,1)
L232:
  lea    D2(%rip),%rdi
  call   <ffpmsg@plt>
  mov    0x38(%rsp),%rdi
  call   <ffpmsg@plt>
  mov    0x20(%rsp),%rax
  movl   $0xcf,(%rax)
  mov    $0xcf,%eax
  jmp    L126
L424:
  mov    0x10(%rsp),%rdi
  lea    D66(%rip),%rsi
  xor    %ebx,%ebx
  xor    %ebp,%ebp
  call   <strcat@plt>
  mov    0x8(%rsp),%r14
  add    $0x3,%r14
  jmp    L743
L540:
  lea    D7(%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    L126
L330:
  mov    $0x9,%edx
  lea    D81(%rip),%rsi
  mov    %r13,%rdi
  call   <strncmp@plt>
  test   %eax,%eax
  je     L112
  movzbl 0x60(%rsp),%eax
  jmp    L560
L27:
  mov    $0x1e,%edx
  sub    0x4c(%rsp),%edx
  lea    D108(%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     L726
L57:
  mov    0x30(%rsp),%r14
  mov    %r14,%rdi
  call   <strlen@plt>
  test   %eax,%eax
  jle    L726
  mov    0x10(%rsp),%r15
  lea    D64(%rip),%rsi
  mov    %r15,%rdi
  call   <strcat@plt>
  mov    $0x4d,%edx
  mov    %r14,%rsi
  mov    %r15,%rdi
  sub    %r12d,%edx
  call   <strncat@plt>
  jmp    L726
L257:
  lea    D151(%rip),%rdi
  jmp    L785
L629:
  mov    0x30(%rsp),%rax
  test   %rax,%rax
  je     L726
  cmpb   $0x0,(%rax)
  je     L43
  cmp    $0x1d,%r14
  ja     L43
  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    L417
  test   $0x4,%al
  jne    L398
  test   %rax,%rax
  je     L34
  movb   $0x20,(%r12)
  test   $0x2,%al
  jne    L495
L34:
  mov    0x10(%rsp),%rax
  mov    $0x1e,%r12d
  movb   $0x0,0x1e(%rax)
  jmp    L57
L784:
  movb   $0x20,0x8(%rax)
  mov    %rax,%rdi
  mov    0x30(%rsp),%rax
  test   %rax,%rax
  je     L581
  mov    $0x46,%edx
  mov    %rax,%rsi
  call   <strncat@plt>
  jmp    L581
L429:
  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     L435
  and    $0xfffffff8,%eax
  xor    %edx,%edx
L169:
  mov    %edx,%edi
  add    $0x8,%edx
  mov    %rcx,(%rsi,%rdi,1)
  cmp    %eax,%edx
  jb     L169
  jmp    L435
L21:
  xor    %ebx,%ebx
  mov    $0x46,%edx
  mov    $0xa,%r14d
  jmp    L177
L417:
  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     L34
  and    $0xfffffffffffffff8,%rax
  xor    %edx,%edx
L359:
  mov    %rsi,(%rcx,%rdx,1)
  add    $0x8,%rdx
  cmp    %rax,%rdx
  jb     L359
  jmp    L34
L360:
  mov    %eax,%eax
  movl   $0x20202020,(%rdx)
  movl   $0x20202020,-0x4(%rdx,%rax,1)
  jmp    L435
L222:
  mov    %eax,%eax
  movw   $0x2020,-0x2(%rdx,%rax,1)
  jmp    L435
L398:
  movl   $0x20202020,(%r12)
  movl   $0x20202020,-0x4(%r12,%rax,1)
  jmp    L34
L345:
  call   <__stack_chk_fail@plt>
L591:
  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     L435
  jmp    L613
L495:
  movw   $0x2020,-0x2(%r12,%rax,1)
  jmp    L34
```

tool_calls: name: read_data
arguments: data_label: D77
type_guessed: string
name: read_data
arguments: data_label: D81
type_guessed: string
name: read_data
arguments: data_label: D66
type_guessed: string
name: read_data
arguments: data_label: D82
type_guessed: string
name: read_data
arguments: data_label: D5
type_guessed: string
name: read_data
arguments: data_label: D145
type_guessed: string
name: read_data
arguments: data_label: D74
type_guessed: string
name: read_data
arguments: data_label: D2
type_guessed: string
name: read_data
arguments: data_label: D7
type_guessed: string
name: read_data
arguments: data_label: D108
type_guessed: string
name: read_data
arguments: data_label: D64
type_guessed: string
name: read_data
arguments: data_label: D151
type_guessed: string

tool: D77:  

tool: D81: HIERARCH 

tool: D66:  = 

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

tool: D5: = 

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

tool: D74: hierarch 

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

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

tool: D108:                     

tool: D64:  / 

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