user: Translate the below assembly code into C programming language:

```asm
<string_match>:
  endbr64
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x8,%rsp
  test   %rsi,%rsi
  je     L196
  cmpb   $0x0,(%rsi)
  mov    %rsi,%rbp
  jne    L155
L196:
  xor    %r12d,%r12d
L108:
  add    $0x8,%rsp
  mov    %r12d,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  ret
  nopl   0x0(%rax)
L155:
  mov    %rdi,%r13
  lea    D4(%rip),%rsi
  mov    %rbp,%rdi
  mov    %edx,%ebx
  call   <strcmp@plt>
  mov    $0x1,%r12d
  test   %rax,%rax
  je     L108
  mov    %r13,%rdi
  call   <strlen@plt>
  mov    %rbp,%rdi
  movslq %eax,%r12
  call   <strlen@plt>
  cmpb   $0x2a,0x0(%rbp)
  movslq %eax,%rdx
  movzbl -0x1(%rbp,%rdx,1),%ecx
  je     L70
  cmp    $0x2a,%cl
  je     L82
  mov    %rbp,%rsi
  mov    %r13,%rdi
  test   %ebx,%ebx
  jne    L51
L98:
  call   <string_strcasecmp@plt>
  xor    %r12d,%r12d
  test   %rax,%rax
  sete   %r12b
  jmp    L108
  nopl   0x0(%rax)
L70:
  lea    -0x1(%rax),%esi
  cmp    $0x2a,%cl
  je     L118
  cmp    %esi,%r12d
  jl     L196
  mov    %r13,%rdi
  lea    0x1(%rbp),%rsi
  sub    %rdx,%rdi
  lea    0x1(%rdi,%r12,1),%rdi
  test   %ebx,%ebx
  je     L98
L51:
  call   <strcmp@plt>
  xor    %r12d,%r12d
  test   %rax,%rax
  sete   %r12b
  jmp    L108
L118:
  cmp    %esi,%r12d
  jl     L196
  lea    0x1(%rbp),%rdi
  lea    -0x2(%rax),%esi
  call   <string_strndup@plt>
  mov    %rax,%rbp
  test   %rax,%rax
  je     L196
  mov    %rax,%rsi
  mov    %r13,%rdi
  test   %ebx,%ebx
  jne    L52
  call   <string_strcasestr@plt>
  xor    %r12d,%r12d
  test   %rax,%rax
  setne  %r12b
L88:
  mov    %rbp,%rdi
  call   <free@plt>
  jmp    L108
  nopw   0x0(%rax,%rax,1)
L82:
  lea    -0x1(%rax),%edx
  cmp    %r12d,%edx
  jg     L196
  mov    %rbp,%rsi
  mov    %r13,%rdi
  test   %ebx,%ebx
  jne    L45
  call   <string_strncasecmp@plt>
  xor    %r12d,%r12d
  test   %rax,%rax
  sete   %r12b
  jmp    L108
L45:
  call   <strncmp@plt>
  xor    %r12d,%r12d
  test   %rax,%rax
  sete   %r12b
  jmp    L108
L52:
  call   <strstr@plt>
  xor    %r12d,%r12d
  test   %rax,%rax
  setne  %r12b
  jmp    L88
```

tool_calls: name: read_data
arguments: label: D4
type: string

tool: D4: *

assistant: ```c
int string_match(const char *string, const char *mask, int case_sensitive) {
  char last, *mask2;
  int len_string, len_mask, rc;
  if (!mask || !mask[0])
    return 0;
  if (strcmp(mask, "*") == 0)
    return 1;
  len_string = strlen(string);
  len_mask = strlen(mask);
  last = mask[len_mask - 1];
  if ((mask[0] == '*') && (last != '*')) {
    if (len_string < len_mask - 1)
      return 0;
    if ((case_sensitive && (strcmp(string + len_string - (len_mask - 1), mask + 1) == 0)) || (!case_sensitive && (string_strcasecmp(string + len_string - (len_mask - 1), mask + 1) == 0)))
      return 1;
    return 0;
  }
  if ((mask[0] != '*') && (last == '*')) {
    if (len_string < len_mask - 1)
      return 0;
    if ((case_sensitive && (strncmp(string, mask, len_mask - 1) == 0)) || (!case_sensitive && (string_strncasecmp(string, mask, len_mask - 1) == 0)))
      return 1;
    return 0;
  }
  if ((mask[0] == '*') && (last == '*')) {
    if (len_string < len_mask - 1)
      return 0;
    mask2 = string_strndup(mask + 1, len_mask - 2);
    if (!mask2)
      return 0;
    rc = ((case_sensitive && strstr(string, mask2)) || (!case_sensitive && string_strcasestr(string, mask2))) ? 1 : 0;
    free(mask2);
    return rc;
  }
  if ((case_sensitive && (strcmp(string, mask) == 0)) || (!case_sensitive && (string_strcasecmp(string, mask) == 0)))
    return 1;
  return 0;
}
```