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

```asm
<_utils_searchexp>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %edx,-0x44(%rbp)
  mov    %rcx,-0x50(%rbp)
  movl   $0xfffffffc,-0x20(%rbp)
  cmpq   $0x0,-0x40(%rbp)
  je     L247
  mov    -0x40(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L121
L247:
  mov    -0x20(%rbp),%eax
  jmp    L358
L121:
  cmpq   $0x0,-0x38(%rbp)
  je     L284
  movl   $0xffffffff,-0x1c(%rbp)
  mov    -0x40(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  jmp    L136
L69:
  movl   $0x0,-0x1c(%rbp)
  movl   $0xfffffffe,-0x20(%rbp)
  mov    -0x1c(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x5e,%al
  jne    L102
  movq   $0x0,-0x10(%rbp)
  addq   $0x1,-0x18(%rbp)
L102:
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x8(%rbp)
L175:
  mov    -0x1c(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  mov    %al,-0x23(%rbp)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2a,%al
  jne    L90
  mov    -0x1c(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x10(%rbp)
  addq   $0x1,-0x18(%rbp)
L90:
  cmpl   $0x0,-0x44(%rbp)
  je     L285
  cmpb   $0x40,-0x23(%rbp)
  jle    L285
  cmpb   $0x5a,-0x23(%rbp)
  jg     L285
  movzbl -0x23(%rbp),%eax
  add    $0x20,%eax
  mov    %al,-0x23(%rbp)
L285:
  cmpq   $0x0,-0x10(%rbp)
  jne    L242
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  mov    %al,-0x22(%rbp)
  cmpl   $0x0,-0x44(%rbp)
  je     L204
  cmpb   $0x40,-0x22(%rbp)
  jle    L204
  cmpb   $0x5a,-0x22(%rbp)
  jg     L204
  movzbl -0x22(%rbp),%eax
  add    $0x20,%eax
  mov    %al,-0x22(%rbp)
L204:
  movzbl -0x22(%rbp),%eax
  cmp    -0x23(%rbp),%al
  je     L216
  mov    -0x8(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  movl   $0xfffffffc,-0x20(%rbp)
  jmp    L31
L216:
  movzbl -0x22(%rbp),%eax
  cmp    -0x23(%rbp),%al
  jne    L145
  movl   $0x0,-0x20(%rbp)
L145:
  addq   $0x1,-0x18(%rbp)
  jmp    L70
L242:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  mov    %al,-0x21(%rbp)
  cmpl   $0x0,-0x44(%rbp)
  je     L122
  cmpb   $0x40,-0x21(%rbp)
  jle    L122
  cmpb   $0x5a,-0x21(%rbp)
  jg     L122
  movzbl -0x21(%rbp),%eax
  add    $0x20,%eax
  mov    %al,-0x21(%rbp)
L122:
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  movl   $0x0,-0x20(%rbp)
  cmpb   $0x0,-0x23(%rbp)
  je     L70
  movzbl -0x21(%rbp),%eax
  cmp    -0x23(%rbp),%al
  jne    L70
  movq   $0x0,-0x10(%rbp)
  addq   $0x1,-0x18(%rbp)
L70:
  addl   $0x1,-0x1c(%rbp)
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2c,%al
  je     L31
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L31
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x24,%al
  je     L31
  mov    -0x1c(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L175
L31:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2a,%al
  jne    L153
  addq   $0x1,-0x18(%rbp)
L153:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x24,%al
  jne    L71
  mov    -0x1c(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L131
  movl   $0xfffffffc,-0x20(%rbp)
L131:
  addq   $0x1,-0x18(%rbp)
L71:
  cmpl   $0x0,-0x20(%rbp)
  jne    L130
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x2c,%al
  je     L0
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L0
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x24,%al
  jne    L68
L0:
  cmpq   $0x0,-0x10(%rbp)
  je     L229
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x24,%al
  je     L229
  cmpq   $0x0,-0x50(%rbp)
  je     L229
  mov    -0x50(%rbp),%rax
  mov    -0x10(%rbp),%rdx
  mov    %rdx,(%rax)
  jmp    L229
L68:
  movl   $0xfffffffc,-0x20(%rbp)
L130:
  mov    -0x18(%rbp),%rax
  mov    $0x2c,%esi
  mov    %rax,%rdi
  call   <strchr@plt>
  mov    %rax,-0x18(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  je     L304
  addq   $0x1,-0x18(%rbp)
L304:
  movq   $0x0,-0x10(%rbp)
L136:
  cmpq   $0x0,-0x18(%rbp)
  jne    L69
  jmp    L284
L229:
  nop
L284:
  mov    -0x20(%rbp),%eax
L358:
  leave
  ret
```

assistant: ```c
int _utils_searchexp(const char *haystack, const char *needleslist, int ignore_case, const char **rest) {
  int ret = -4;
  if (needleslist == NULL || needleslist[0] == '\0')
    return ret;
  if (haystack != NULL) {
    int i = -1;
    const char *needle = needleslist;
    while (needle != NULL) {
      i = 0;
      ret = -2;
      const char *wildcard = &(haystack[i]);
      if (*needle == '^') {
        wildcard = NULL;
        needle++;
      }
      const char *needle_entry = needle;
      do {
        ;
        char hay = haystack[i];
        if (*needle == '*') {
          wildcard = &(haystack[i]);
          needle++;
        }
        if (ignore_case && hay > 0x40 && hay < 0x5b)
          hay += 0x20;
        if (wildcard == NULL) {
          char lneedle = *needle;
          if (ignore_case && lneedle > 0x40 && lneedle < 0x5b)
            lneedle += 0x20;
          if (lneedle != hay) {
            ;
            needle = needle_entry;
            ret = -4;
            break;
          } else if (lneedle == hay) {
            ret = 0;
          }
          needle++;
        } else {
          char lneedle = *needle;
          if (ignore_case && lneedle > 0x40 && lneedle < 0x5b)
            lneedle += 0x20;
          needle_entry = needle;
          ret = 0;
          if (hay != '\0' && lneedle == hay) {
            wildcard = NULL;
            needle++;
          }
        }
        i++;
        if (*needle == ',' || *needle == '\0' || *needle == '$') {
          ;
          break;
        }
      } while (haystack[i] != '\0');
      if (*needle == '*')
        needle++;
      if (*needle == '$') {
        if (haystack[i] != '\0')
          ret = -4;
        needle++;
      };
      if (ret == 0) {
        if (*needle == ',' || *needle == '\0' || *needle == '$') {
          if (wildcard && (*needle != '$') && (rest != NULL))
            *rest = wildcard;
          break;
        } else
          ret = -4;
      }
      needle = strchr(needle, ',');
      if (needle != NULL)
        needle++;
      wildcard = 0;
    }
  }
  return ret;
}
```