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

```asm
<wildmatch>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x28,%rsp
  mov    %rdi,%r14
  mov    %rsi,%r15
  mov    %edx,%r12d
  mov    %fs:0x28,%rax
  mov    %rax,0x18(%rsp)
  xor    %eax,%eax
  mov    %edx,%eax
  or     $0x2,%eax
  test   $0x40,%dl
  cmovne %eax,%r12d
  mov    %rsi,%r13
  mov    %r12d,%eax
  and    $0x4,%eax
  mov    %eax,0xc(%rsp)
L447:
  lea    0x1(%r14),%rbx
  movzbl (%r14),%ebp
  cmp    $0x3f,%bpl
  je     L143
  jle    L948
  cmp    $0x5b,%bpl
  je     L339
  cmp    $0x5c,%bpl
  jne    L473
  test   $0x1,%r12b
  jne    L330
  movzbl 0x1(%r14),%eax
  test   %al,%al
  je     L760
  add    $0x2,%r14
  mov    %eax,%ebp
  jmp    L486
L948:
  test   %bpl,%bpl
  je     L978
  cmp    $0x2a,%bpl
  jne    L169
  movzbl 0x1(%r14),%edx
  test   $0x40,%r12b
  je     L1016
  cmp    $0x2a,%dl
  je     L718
L1016:
  cmp    $0x2a,%dl
  jne    L361
L1008:
  add    $0x1,%rbx
  movzbl (%rbx),%edx
  cmp    $0x2a,%dl
  je     L1008
L361:
  cmpb   $0x2e,0x0(%r13)
  je     L493
L951:
  test   %dl,%dl
  je     L489
L909:
  cmp    $0x2f,%dl
  je     L10
L972:
  movzbl 0x0(%r13),%ebp
  mov    %r12d,%r14d
  and    $0xfffffffb,%r14d
  mov    $0x1,%eax
  test   %bpl,%bpl
  jne    L766
  jmp    L290
L169:
  mov    %rbx,%r14
  jmp    L486
L473:
  mov    %rbx,%r14
  jmp    L486
L978:
  test   $0x8,%r12b
  je     L726
  mov    $0x0,%eax
  cmpb   $0x2f,0x0(%r13)
  je     L290
L726:
  cmpb   $0x0,0x0(%r13)
  setne  %al
  movzbl %al,%eax
L290:
  mov    0x18(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L164
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L143:
  movzbl 0x0(%r13),%eax
  test   %al,%al
  je     L57
  cmp    $0x2f,%al
  je     L139
  cmp    $0x2e,%al
  jne    L738
  cmpl   $0x0,0xc(%rsp)
  je     L738
  cmp    %r15,%r13
  je     L121
  test   $0x2,%r12b
  je     L738
  cmpb   $0x2f,-0x1(%r13)
  jne    L738
  mov    $0x1,%eax
  jmp    L290
L139:
  test   $0x2,%r12b
  jne    L373
L738:
  add    $0x1,%r13
  mov    %rbx,%r14
  jmp    L447
L718:
  movzbl -0x1(%r14),%ecx
L764:
  add    $0x1,%rbx
  movzbl (%rbx),%edx
  cmp    $0x2a,%dl
  je     L764
  cmp    $0x2f,%dl
  je     L594
  mov    %edx,%eax
  mov    %ecx,%edx
L992:
  test   %al,%al
  jne    L917
  mov    $0x0,%eax
  cmp    $0x2f,%dl
  je     L290
L489:
  mov    %r12d,%eax
  and    $0x2,%eax
  je     L290
L230:
  mov    $0x0,%eax
  test   $0x8,%r12b
  jne    L290
  mov    $0x2f,%esi
  mov    %r13,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  setne  %al
  movzbl %al,%eax
  jmp    L290
L913:
  cmp    $0x2f,%al
  jne    L992
L594:
  cmpb   $0x2a,0x1(%rbx)
  jne    L324
  cmpb   $0x2a,0x2(%rbx)
  jne    L324
  add    $0x1,%rbx
L529:
  add    $0x1,%rbx
  movzbl (%rbx),%eax
  cmp    $0x2a,%al
  je     L529
  jmp    L913
L324:
  lea    0x1(%rbx),%rdi
  mov    %r12d,%edx
  mov    %r13,%rsi
  call   <wildmatch>
  test   %eax,%eax
  jne    L264
  jmp    L290
L493:
  test   $0x4,%r12b
  je     L951
  cmp    %r15,%r13
  je     L550
  mov    %r12d,%eax
  and    $0x2,%eax
  je     L735
  mov    $0x1,%eax
  cmpb   $0x2f,-0x1(%r13)
  je     L290
  test   %dl,%dl
  je     L230
  jmp    L909
L10:
  test   $0x2,%r12b
  je     L972
  mov    $0x2f,%esi
  mov    %r13,%rdi
  call   <strchr@plt>
  mov    %rax,%r13
  test   %rax,%rax
  jne    L972
  mov    $0x1,%eax
  jmp    L290
L142:
  add    $0x1,%r13
  movzbl 0x0(%r13),%ebp
  test   %bpl,%bpl
  je     L876
L766:
  mov    %r14d,%edx
  mov    %r13,%rsi
  mov    %rbx,%rdi
  call   <wildmatch>
  test   %eax,%eax
  je     L290
  cmp    $0x2f,%bpl
  jne    L142
  test   $0x2,%r12b
  je     L142
  mov    $0x1,%eax
  jmp    L290
L876:
  mov    $0x1,%eax
  jmp    L290
L339:
  movzbl 0x0(%r13),%esi
  test   %sil,%sil
  je     L852
  cmp    $0x2f,%sil
  je     L308
  cmp    $0x2e,%sil
  jne    L244
  cmpl   $0x0,0xc(%rsp)
  je     L244
  cmp    %r15,%r13
  je     L627
  test   $0x2,%r12b
  je     L244
  cmpb   $0x2f,-0x1(%r13)
  jne    L244
  mov    $0x1,%eax
  jmp    L290
L308:
  test   $0x2,%r12b
  jne    L147
L244:
  lea    0x10(%rsp),%rcx
  movsbl %sil,%esi
  mov    %r12d,%edx
  mov    %rbx,%rdi
  call   <rangematch@plt>
  test   %eax,%eax
  je     L119
  cmp    $0x1,%eax
  je     L205
  cmp    $0xffffffff,%eax
  je     L60
L695:
  add    $0x1,%r13
  mov    %rbx,%r14
  jmp    L447
L60:
  add    $0x1,%r13
  mov    %rbx,%r14
  jmp    L486
L205:
  mov    0x10(%rsp),%rbx
  jmp    L695
L760:
  cmpb   $0x0,0x1(%r13)
  je     L17
  mov    %rbx,%r14
  jmp    L486
L330:
  mov    %rbx,%r14
L486:
  cmp    %bpl,0x0(%r13)
  je     L512
  test   $0x10,%r12b
  je     L293
  movzbl %bpl,%edi
  call   <tolower@plt>
  mov    %eax,%ebx
  movzbl 0x0(%r13),%edi
  call   <tolower@plt>
  cmp    %eax,%ebx
  jne    L1004
L512:
  add    $0x1,%r13
  jmp    L447
L57:
  mov    $0x1,%eax
  jmp    L290
L373:
  mov    $0x1,%eax
  jmp    L290
L121:
  mov    $0x1,%eax
  jmp    L290
L550:
  mov    $0x1,%eax
  jmp    L290
L326:
  mov    $0x1,%eax
  jmp    L290
L852:
  mov    $0x1,%eax
  jmp    L290
L147:
  mov    $0x1,%eax
  jmp    L290
L627:
  mov    $0x1,%eax
  jmp    L290
L119:
  mov    $0x1,%eax
  jmp    L290
L17:
  mov    $0x1,%eax
  jmp    L290
L293:
  mov    $0x1,%eax
  jmp    L290
L1004:
  mov    $0x1,%eax
  jmp    L290
L917:
  cmp    $0x2f,%al
  jne    L807
L264:
  mov    $0x2f,%esi
  mov    %r15,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  je     L326
  lea    0x1(%rbx),%r14
L848:
  lea    0x1(%rax),%rbp
  mov    %r12d,%edx
  mov    %rbp,%rsi
  mov    %r14,%rdi
  call   <wildmatch>
  test   %eax,%eax
  je     L290
  mov    $0x2f,%esi
  mov    %rbp,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  jne    L848
  jmp    L972
L807:
  mov    $0x1,%eax
  jmp    L290
L735:
  test   %dl,%dl
  jne    L909
  jmp    L290
L164:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
int wildmatch(const char *pattern, const char *string, int flags) {
  const char *stringstart;
  const char *newp;
  const char *slash;
  char c, test;
  char prev;
  int wild = 0;
  if (((flags) & (0x40))) {
    flags |= 0x02;
  }
  for (stringstart = string;;) {
    switch (c = *pattern++) {
    case '\0':
      if (((flags) & (0x08)) && *string == '/')
        return 0;
      return (*string == '\0') ? 0 : 1;
    case '?':
      if (*string == '\0')
        return 1;
      if (*string == '/' && ((flags) & (0x02)))
        return 1;
      if (*string == '.' && ((flags) & (0x04)) && (string == stringstart || (((flags) & (0x02)) && *(string - 1) == '/')))
        return 1;
      ++string;
      break;
    case '*':
      c = *pattern;
      wild = ((flags) & (0x40)) && c == '*';
      if (wild) {
        prev = pattern[-2];
        while (c == '*') {
          c = *++pattern;
        }
        while (c == '/' && pattern[1] == '*' && pattern[2] == '*') {
          prev = c;
          c = *++pattern;
          while (c == '*') {
            c = *++pattern;
          }
        }
        if (c == '/' && wildmatch(pattern + 1, string, flags) == 0) {
          return 0;
        }
      } else {
        while (c == '*') {
          c = *++pattern;
        }
      }
      if (!wild && *string == '.' && ((flags) & (0x04)) && (string == stringstart || (((flags) & (0x02)) && *(string - 1) == '/'))) {
        return 1;
      }
      if (c == '\0') {
        if (wild && prev == '/') {
          return 0;
        }
        if (((flags) & (0x02))) {
          return (((flags) & (0x08)) || strchr(string, '/') == NULL ? 0 : 1);
        } else {
          return 0;
        }
      } else if (c == '/') {
        if (wild) {
          slash = strchr(stringstart, '/');
          if (!slash) {
            return 1;
          }
          while (slash) {
            if (wildmatch(pattern + 1, slash + 1, flags) == 0) {
              return 0;
            }
            slash = strchr(slash + 1, '/');
          }
        } else {
          if (((flags) & (0x02))) {
            if ((string = strchr(string, '/')) == NULL) {
              return 1;
            }
          }
        }
      } else if (wild) {
        return 1;
      }
      while ((test = *string) != '\0') {
        if (!wildmatch(pattern, string, flags & ~0x04))
          return 0;
        if (test == '/' && ((flags) & (0x02)))
          break;
        ++string;
      }
      return 1;
    case '[':
      if (*string == '\0')
        return 1;
      if (*string == '/' && ((flags) & (0x02)))
        return 1;
      if (*string == '.' && ((flags) & (0x04)) && (string == stringstart || (((flags) & (0x02)) && *(string - 1) == '/')))
        return 1;
      switch (rangematch(pattern, *string, flags, &newp)) {
      case -1:
        ++string;
        goto normal;
      case 1:
        pattern = newp;
        break;
      case 0:
        return (1);
      }
      ++string;
      break;
    case '\\':
      if (!((flags) & (0x01))) {
        if ((c = *pattern++) == '\0') {
          c = '\\';
          --pattern;
          if (*(string + 1) == '\0') {
            return 1;
          }
        }
      }
    default:
    normal:
      if (c != *string && !(((flags) & (0x10)) && (tolower((unsigned char)c) == tolower((unsigned char)*string))))
        return 1;
      ++string;
      break;
    }
  }
}
```