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

```asm
<yuri_query_parse>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x30,%rsp
  mov    %rdi,-0x18(%rbp)
  mov    %rsi,-0x20(%rbp)
  mov    %rdx,-0x28(%rbp)
  cmpq   $0x0,-0x18(%rbp)
  je     L42
  mov    -0x18(%rbp),%rax
  mov    (%rax),%rax
  test   %rax,%rax
  je     L42
  mov    -0x18(%rbp),%rax
  mov    (%rax),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L196
L42:
  mov    $0x0,%eax
  jmp    L0
L196:
  mov    -0x18(%rbp),%rax
  mov    (%rax),%rax
  mov    %rax,-0x8(%rbp)
  jmp    L83
L84:
  addq   $0x1,-0x8(%rbp)
L83:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L208
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x3d,%al
  je     L208
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x3b,%al
  je     L208
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x26,%al
  jne    L84
L208:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L118
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x3b,%al
  je     L118
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x26,%al
  jne    L202
L118:
  mov    -0x18(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x20(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x28(%rbp),%rax
  mov    -0x8(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L159
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  jmp    L5
L159:
  mov    -0x8(%rbp),%rax
L5:
  mov    -0x18(%rbp),%rdx
  mov    %rax,(%rdx)
  mov    -0x8(%rbp),%rax
  movb   $0x0,(%rax)
  mov    -0x20(%rbp),%rax
  mov    (%rax),%rax
  mov    %rax,%rdi
  call   <yuri__query_unescape@plt>
  mov    $0x1,%eax
  jmp    L0
L202:
  mov    -0x8(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x8(%rbp)
  movb   $0x0,(%rax)
  mov    -0x18(%rbp),%rax
  mov    (%rax),%rdx
  mov    -0x20(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x20(%rbp),%rax
  mov    (%rax),%rax
  mov    %rax,%rdi
  call   <yuri__query_unescape@plt>
  mov    -0x28(%rbp),%rax
  mov    -0x8(%rbp),%rdx
  mov    %rdx,(%rax)
  jmp    L169
L66:
  addq   $0x1,-0x8(%rbp)
L169:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L77
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x3b,%al
  je     L77
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x26,%al
  jne    L66
L77:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L15
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  jmp    L206
L15:
  mov    -0x8(%rbp),%rax
L206:
  mov    -0x18(%rbp),%rdx
  mov    %rax,(%rdx)
  mov    -0x8(%rbp),%rax
  movb   $0x0,(%rax)
  mov    -0x28(%rbp),%rax
  mov    (%rax),%rax
  mov    %rax,%rdi
  call   <yuri__query_unescape@plt>
  mov    $0x1,%eax
L0:
  leave
  ret
```

assistant: ```c
int yuri_query_parse(char **str, char **key, char **value) {
  if (!str || !*str || !**str)
    return 0;
  char *sep = *str;
  while (*sep && *sep != '=' && *sep != ';' && *sep != '&')
    sep++;
  if (!*sep || *sep == ';' || *sep == '&') {
    *key = *str;
    *value = sep;
    *str = *sep ? sep + 1 : sep;
    *sep = 0;
    yuri__query_unescape(*key);
    return 1;
  }
  *(sep++) = 0;
  *key = *str;
  yuri__query_unescape(*key);
  *value = sep;
  while (*sep && *sep != ';' && *sep != '&')
    sep++;
  *str = *sep ? sep + 1 : sep;
  *sep = 0;
  yuri__query_unescape(*value);
  return 1;
}
```