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

```asm
<fnmatch>:
  endbr64
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  mov    %rdi,%rbx
  mov    %rsi,%r13
  mov    %edx,%r12d
  mov    %rsi,%rbp
  jmp    L587
L530:
  test   %al,%al
  je     L105
  cmp    $0x2a,%al
  jne    L43
  movzbl 0x1(%rbx),%eax
  cmp    $0x2a,%al
  jne    L251
L483:
  add    $0x1,%rdi
  movzbl (%rdi),%eax
  cmp    $0x2a,%al
  je     L483
  mov    %rdi,%rbx
L40:
  movzbl 0x0(%rbp),%r14d
  cmp    $0x2e,%r14b
  je     L165
L473:
  test   %al,%al
  je     L17
  cmp    $0x2f,%al
  jne    L508
  mov    D122(%rip),%rax
  mov    %r12d,%ecx
  and    (%rax),%ecx
  je     L508
  mov    $0x2f,%esi
  mov    %rbp,%rdi
  call   <index@plt>
  mov    %rax,%rbp
  test   %rax,%rax
  jne    L587
  mov    D206(%rip),%rax
  mov    (%rax),%eax
  jmp    L492
L43:
  mov    %rdi,%rbx
  jmp    L262
L428:
  mov    %rdi,%rbx
  jmp    L262
L105:
  mov    $0x0,%eax
  cmpb   $0x0,0x0(%rbp)
  je     L492
  mov    D206(%rip),%rax
  mov    (%rax),%eax
L492:
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  ret
L39:
  movzbl 0x0(%rbp),%eax
  test   %al,%al
  je     L228
  cmp    $0x2f,%al
  je     L212
  cmp    $0x2e,%al
  jne    L350
  mov    D162(%rip),%rax
  mov    %r12d,%ecx
  and    (%rax),%ecx
  je     L350
  cmp    %r13,%rbp
  je     L174
  mov    D122(%rip),%rax
  mov    %r12d,%ecx
  and    (%rax),%ecx
  je     L350
  cmpb   $0x2f,-0x1(%rbp)
  jne    L350
L174:
  mov    D206(%rip),%rax
  mov    (%rax),%eax
  jmp    L492
L228:
  mov    D206(%rip),%rax
  mov    (%rax),%eax
  jmp    L492
L212:
  mov    D122(%rip),%rax
  mov    %r12d,%ecx
  and    (%rax),%ecx
  jne    L517
L350:
  add    $0x1,%rbp
  mov    %rdi,%rbx
  jmp    L587
L517:
  mov    D206(%rip),%rax
  mov    (%rax),%eax
  jmp    L492
L251:
  mov    %rdi,%rbx
  jmp    L40
L165:
  mov    D162(%rip),%rdx
  mov    %r12d,%ecx
  and    (%rdx),%ecx
  je     L473
  cmp    %r13,%rbp
  je     L72
  mov    D122(%rip),%rdx
  mov    %r12d,%ecx
  and    (%rdx),%ecx
  je     L473
  cmpb   $0x2f,-0x1(%rbp)
  jne    L473
L72:
  mov    D206(%rip),%rax
  mov    (%rax),%eax
  jmp    L492
L17:
  mov    D122(%rip),%rax
  and    (%rax),%r12d
  mov    %r12d,%eax
  je     L492
  mov    $0x2f,%esi
  mov    %rbp,%rdi
  call   <index@plt>
  mov    %rax,%rdx
  mov    $0x0,%eax
  test   %rdx,%rdx
  je     L492
  mov    D206(%rip),%rax
  mov    (%rax),%eax
  jmp    L492
L508:
  test   %r14b,%r14b
  je     L68
  mov    D162(%rip),%r13
  jmp    L60
L580:
  add    $0x1,%rbp
  movzbl 0x0(%rbp),%r14d
  test   %r14b,%r14b
  je     L68
L60:
  mov    0x0(%r13),%edx
  not    %edx
  and    %r12d,%edx
  mov    %rbp,%rsi
  mov    %rbx,%rdi
  call   <fnmatch>
  test   %eax,%eax
  je     L492
  cmp    $0x2f,%r14b
  jne    L580
  mov    D122(%rip),%rax
  mov    %r12d,%ecx
  and    (%rax),%ecx
  je     L580
L68:
  mov    D206(%rip),%rax
  mov    (%rax),%eax
  jmp    L492
L249:
  movzbl 0x0(%rbp),%esi
  test   %sil,%sil
  je     L404
  cmp    $0x2f,%sil
  jne    L450
  mov    D122(%rip),%rax
  mov    %r12d,%ecx
  and    (%rax),%ecx
  jne    L198
L450:
  movsbl %sil,%esi
  mov    %r12d,%edx
  call   <rangematch@plt>
  mov    %rax,%rbx
  test   %rax,%rax
  je     L367
  add    $0x1,%rbp
  jmp    L587
L404:
  mov    D206(%rip),%rax
  mov    (%rax),%eax
  jmp    L492
L198:
  mov    D206(%rip),%rax
  mov    (%rax),%eax
  jmp    L492
L367:
  mov    D206(%rip),%rax
  mov    (%rax),%eax
  jmp    L492
L403:
  mov    %rdi,%rbx
L262:
  lea    0x1(%rbp),%rdx
  cmp    %al,0x0(%rbp)
  jne    L420
  mov    %rdx,%rbp
L587:
  lea    0x1(%rbx),%rdi
  movzbl (%rbx),%eax
  cmp    $0x3f,%al
  je     L39
  jle    L530
  cmp    $0x5b,%al
  je     L249
  cmp    $0x5c,%al
  jne    L428
  mov    D160(%rip),%rdx
  mov    %r12d,%ecx
  and    (%rdx),%ecx
  jne    L403
  movzbl 0x1(%rbx),%edx
  test   %dl,%dl
  je     L309
  add    $0x2,%rbx
  mov    %edx,%eax
  jmp    L262
L309:
  mov    %rdi,%rbx
  jmp    L262
L420:
  mov    D206(%rip),%rax
  mov    (%rax),%eax
  jmp    L492
```

assistant: ```c
int fnmatch(const char *pattern, const char *string, int flags) {
  const char *stringstart = string;
  char c;
  char test;
  for (;;) {
    switch (c = *pattern++) {
    case '\0':
      return (*string == '\0' ? 0 : FNM_NOMATCH);
    case '?':
      if (*string == '\0') {
        return (FNM_NOMATCH);
      }
      if (*string == '/' && (flags & FNM_PATHNAME)) {
        return (FNM_NOMATCH);
      }
      if (*string == '.' && (flags & FNM_PERIOD) && (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) {
        return (FNM_NOMATCH);
      }
      ++string;
      break;
    case '*':
      c = *pattern;
      while (c == '*') {
        c = *++pattern;
      }
      if (*string == '.' && (flags & FNM_PERIOD) && (string == stringstart || ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) {
        return (FNM_NOMATCH);
      }
      if (c == '\0') {
        if (flags & FNM_PATHNAME) {
          return (index(string, '/') == NULL ? 0 : FNM_NOMATCH);
        } else {
          return (0);
        }
      } else if (c == '/' && flags & FNM_PATHNAME) {
        if ((string = index(string, '/')) == NULL) {
          return (FNM_NOMATCH);
        }
        break;
      }
      while ((test = *string) != '\0') {
        if (!fnmatch(pattern, string, flags & ~FNM_PERIOD)) {
          return (0);
        }
        if (test == '/' && flags & FNM_PATHNAME) {
          break;
        }
        ++string;
      }
      return (FNM_NOMATCH);
    case '[':
      if (*string == '\0') {
        return (FNM_NOMATCH);
      }
      if (*string == '/' && flags & FNM_PATHNAME) {
        return (FNM_NOMATCH);
      }
      if ((pattern = rangematch(pattern, *string, flags)) == NULL) {
        return (FNM_NOMATCH);
      }
      ++string;
      break;
    case '\\':
      if (!(flags & FNM_NOESCAPE)) {
        if ((c = *pattern++) == '\0') {
          c = '\\';
          --pattern;
        }
      }
    default:
      if (c != *string++) {
        return (FNM_NOMATCH);
      }
      break;
    }
  }
}
```