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

```asm
<wild_match_per>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %rbx
  sub    $0x38,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  movq   $0x0,-0x18(%rbp)
  movl   $0x0,-0x28(%rbp)
  movl   $0x0,-0x24(%rbp)
  movl   $0x0,-0x20(%rbp)
  movl   $0x0,-0x1c(%rbp)
  cmpq   $0x0,-0x40(%rbp)
  je     L346
  cmpq   $0x0,-0x38(%rbp)
  jne    L257
L346:
  mov    $0x0,%eax
  jmp    L401
L70:
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  cmp    $0x7e,%eax
  je     L134
  cmp    $0x7e,%eax
  jg     L448
  cmp    $0x3f,%eax
  je     L240
  cmp    $0x3f,%eax
  jg     L448
  cmp    $0x25,%eax
  je     L280
  cmp    $0x2a,%eax
  je     L404
  jmp    L448
L280:
  mov    -0x38(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x38(%rbp)
  mov    %rax,-0x18(%rbp)
  movl   $0x1,-0x28(%rbp)
  nop
L461:
  mov    -0x38(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x38(%rbp)
  movzbl (%rax),%eax
  cmp    $0x25,%al
  je     L461
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x5c,%al
  jne    L279
  addq   $0x1,-0x38(%rbp)
  jmp    L279
L251:
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x20,%al
  jne    L6
  movl   $0x0,-0x28(%rbp)
  jmp    L143
L6:
  addq   $0x1,-0x40(%rbp)
L279:
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L257
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <toupper@plt>
  mov    %eax,%ebx
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <toupper@plt>
  cmp    %eax,%ebx
  jne    L251
L143:
  jmp    L257
L240:
  addq   $0x1,-0x38(%rbp)
  addq   $0x1,-0x40(%rbp)
  jmp    L257
L134:
  addq   $0x1,-0x38(%rbp)
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x20,%al
  je     L425
  mov    -0x24(%rbp),%eax
  mov    %eax,-0x20(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  jne    L299
  mov    $0x0,%eax
  jmp    L401
L299:
  mov    -0x18(%rbp),%rax
  sub    $0x1,%rax
  mov    %rax,-0x38(%rbp)
  jmp    L257
L425:
  nop
L271:
  mov    -0x40(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x40(%rbp)
  movzbl (%rax),%eax
  cmp    $0x20,%al
  je     L271
  addl   $0x1,-0x20(%rbp)
  jmp    L257
L404:
  addq   $0x1,-0x38(%rbp)
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L361
  mov    -0x20(%rbp),%edx
  mov    -0x24(%rbp),%eax
  add    %edx,%eax
  add    $0x1,%eax
  jmp    L401
L361:
  movl   $0x1,-0x1c(%rbp)
  jmp    L257
L448:
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x5c,%al
  jne    L187
  addq   $0x1,-0x38(%rbp)
L187:
  cmpl   $0x0,-0x1c(%rbp)
  je     L1
  mov    -0x20(%rbp),%eax
  mov    %eax,-0x24(%rbp)
  movl   $0x0,-0x20(%rbp)
  mov    -0x20(%rbp),%eax
  mov    %eax,-0x28(%rbp)
  mov    -0x38(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  jmp    L102
L391:
  addq   $0x1,-0x40(%rbp)
L102:
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L8
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <toupper@plt>
  mov    %eax,%ebx
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <toupper@plt>
  cmp    %eax,%ebx
  jne    L391
L8:
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L1
  movl   $0x1,-0x28(%rbp)
  jmp    L257
L1:
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <toupper@plt>
  mov    %eax,%ebx
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  mov    %eax,%edi
  call   <toupper@plt>
  cmp    %eax,%ebx
  je     L428
  cmpq   $0x0,-0x18(%rbp)
  jne    L37
  mov    $0x0,%eax
  jmp    L401
L37:
  mov    -0x24(%rbp),%eax
  mov    %eax,-0x20(%rbp)
  mov    -0x18(%rbp),%rax
  sub    $0x1,%rax
  mov    %rax,-0x38(%rbp)
  jmp    L257
L428:
  addl   $0x1,-0x20(%rbp)
  movl   $0x0,-0x1c(%rbp)
  movl   $0x1,-0x28(%rbp)
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L183
  addq   $0x1,-0x38(%rbp)
L183:
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L257
  addq   $0x1,-0x40(%rbp)
L257:
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L21
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L70
L21:
  cmpl   $0x0,-0x28(%rbp)
  je     L242
  mov    -0x38(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L242
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L242
  mov    -0x20(%rbp),%edx
  mov    -0x24(%rbp),%eax
  add    %edx,%eax
  add    $0x1,%eax
  jmp    L401
L242:
  mov    $0x0,%eax
L401:
  mov    -0x8(%rbp),%rbx
  leave
  ret
```

assistant: ```c
int wild_match_per(char *wild, char *matchtext) {
  char *fallback = 0;
  int match = 0, saved = 0, count = 0, wildcard = 0;
  if (!matchtext || !wild)
    return 0;
  while (*matchtext && *wild) {
    switch (*wild) {
    case '%':
      fallback = wild++;
      match = 1;
      while ((*(wild++) == '%'))
        ;
      if (*wild == '\\')
        wild++;
      while (*matchtext && (toupper(*wild) != toupper(*matchtext)))
        if (*matchtext == ' ') {
          match = 0;
          break;
        } else
          matchtext++;
      break;
    case '?':
      wild++;
      matchtext++;
      break;
    case '~':
      wild++;
      if (*matchtext != ' ') {
        count = saved;
        if (!fallback)
          return 0;
        wild = fallback - 1;
        break;
      }
      while ((*(matchtext++) == ' '))
        ;
      count++;
      break;
    case '*':
      if (!*++wild)
        return (count + saved + 1);
      wildcard = 1;
      break;
    default:
      if (*wild == '\\')
        wild++;
      if (wildcard) {
        saved = count;
        match = count = 0;
        fallback = wild;
        while (*matchtext && (toupper(*wild) != toupper(*matchtext)))
          matchtext++;
        if (!*matchtext) {
          match = 1;
          break;
        }
      }
      if (toupper(*wild) != toupper(*matchtext)) {
        if (!fallback)
          return 0;
        count = saved;
        wild = fallback - 1;
        break;
      }
      count++;
      wildcard = 0;
      match = 1;
      if (*wild)
        wild++;
      if (*matchtext)
        matchtext++;
    }
  }
  return (!match || *wild || *matchtext) ? 0 : (count + saved + 1);
}
```