user: Converte this assembly snippet into its equivalent C code:

```asm
<nip_count_tokens>:
  endbr64
  push   %r15
  mov    %rcx,%r15
  push   %r14
  push   %r13
  mov    %rdi,%r13
  push   %r12
  push   %rbp
  mov    %rsi,%rbp
  mov    %edx,%esi
  push   %rbx
  sub    $0x28,%rsp
  mov    0x60(%rsp),%ecx
  test   %rbp,%rbp
  je     L42
  movl   $0x0,0x0(%rbp)
L42:
  movzbl 0x0(%r13),%edx
  lea    -0x1(%r8),%eax
  xor    %r14d,%r14d
  xor    %r12d,%r12d
  xor    %r10d,%r10d
  lea    0x1(%r15,%rax,1),%rbx
  test   %dl,%dl
  je     L142
  nopl   0x0(%rax,%rax,1)
L69:
  mov    %r14d,%edi
  and    $0x1,%edi
  test   %r15,%r15
  jne    L288
L285:
  cmp    $0x2,%r12d
  setne  %al
  je     L277
  test   %dil,%dil
  je     L277
  test   %r9d,%r9d
  je     L286
  add    $0x1,%r10d
  xor    %r14d,%r14d
  lea    0x1(%r13),%rax
  xor    %r12d,%r12d
L49:
  mov    %rax,%r13
  test   %rbp,%rbp
  je     L157
L234:
  addl   $0x1,0x0(%rbp)
  movzbl (%rax),%edx
  test   %dl,%dl
  jne    L69
L142:
  add    $0x28,%rsp
  mov    %r10d,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   0x0(%rax)
L277:
  test   %esi,%esi
  setne  %r11b
  cmp    $0x22,%dl
  sete   %dil
  test   %al,%dil
  je     L116
  test   %r11b,%r11b
  jne    L32
L116:
  test   %r12d,%r12d
  jne    L74
  test   %ecx,%ecx
  jne    L290
  cmpb   $0xa,0x0(%r13)
  je     L229
L73:
  lea    0x1(%r13),%rax
  add    $0x1,%r10d
  mov    $0x1,%r12d
  mov    %rax,%r13
  test   %rbp,%rbp
  jne    L234
  nopl   (%rax)
L157:
  movzbl (%rax),%edx
  test   %dl,%dl
  je     L142
  mov    %r14d,%edi
  and    $0x1,%edi
  test   %r15,%r15
  je     L285
L288:
  mov    %r15,%rax
  test   %r8d,%r8d
  jg     L58
  jmp    L285
  nopl   0x0(%rax,%rax,1)
L348:
  add    $0x1,%rax
  cmp    %rax,%rbx
  je     L294
L58:
  cmp    %dl,(%rax)
  jne    L348
  mov    $0x1,%edi
  mov    $0x1,%r14d
  jmp    L285
  nopl   0x0(%rax)
L286:
  xor    %r14d,%r14d
  xor    %r12d,%r12d
  lea    0x1(%r13),%rax
  jmp    L49
  nop
L74:
  test   %ecx,%ecx
  je     L130
  cmp    $0x1,%r12d
  jne    L130
  movsbl %dl,%edi
  mov    %ecx,0x60(%rsp)
  mov    %r9d,0x18(%rsp)
  mov    %r8d,0x14(%rsp)
  mov    %esi,0x10(%rsp)
  mov    %r10d,0xc(%rsp)
  mov    %r11b,0x1f(%rsp)
  call   <isspace@plt>
  mov    0xc(%rsp),%r10d
  mov    0x10(%rsp),%esi
  test   %rax,%rax
  mov    0x14(%rsp),%r8d
  mov    0x18(%rsp),%r9d
  mov    0x60(%rsp),%ecx
  je     L93
L340:
  xor    %r12d,%r12d
L229:
  lea    0x1(%r13),%rax
  jmp    L49
  cs nopw 0x0(%rax,%rax,1)
L294:
  mov    %r14d,%edi
  and    $0x1,%edi
  jmp    L285
L93:
  movzbl 0x1f(%rsp),%r11d
  nopl   0x0(%rax)
L130:
  movzbl 0x0(%r13),%edx
  cmp    $0xa,%dl
  je     L340
  lea    0x1(%r13),%rax
  cmp    $0x2,%r12d
  jne    L49
  test   %r11b,%r11b
  je     L49
  xor    %r12d,%r12d
  cmp    $0x22,%dl
  setne  %r12b
  add    %r12d,%r12d
  jmp    L49
  nopl   0x0(%rax,%rax,1)
L290:
  movsbl %dl,%edi
  mov    %ecx,0x60(%rsp)
  mov    %r9d,0x18(%rsp)
  mov    %r8d,0x14(%rsp)
  mov    %esi,0x10(%rsp)
  mov    %r10d,0xc(%rsp)
  call   <isspace@plt>
  mov    0xc(%rsp),%r10d
  mov    0x10(%rsp),%esi
  mov    %rax,%r11
  mov    0x14(%rsp),%r8d
  mov    0x60(%rsp),%ecx
  lea    0x1(%r13),%rax
  test   %r11,%r11
  mov    0x18(%rsp),%r9d
  jne    L49
  jmp    L73
L32:
  lea    0x1(%r13),%rax
  mov    %rax,%rdx
  nopw   0x0(%rax,%rax,1)
L230:
  movzbl (%rdx),%edi
  test   %dil,%dil
  je     L49
  add    $0x1,%rdx
  cmp    $0x22,%dil
  jne    L230
  add    $0x1,%r10d
  mov    $0x2,%r12d
  jmp    L49
```

assistant: ```c
int nip_count_tokens(const char *s, int *chars, int q_strings, char *separators, int n_separators, int sep_tokens, int wspace_sep) {
  int i;
  int tokens = 0, state = 0;
  int separator_found = 0;
  char ch;
  if (chars)
    *chars = 0;
  while (*s != '\0') {
    if (separators)
      for (i = 0; i < n_separators; i++)
        if (*s == separators[i]) {
          separator_found = 1;
          break;
        }
    if (state != 2 && separator_found) {
      if (sep_tokens)
        tokens++;
      state = 0;
      separator_found = 0;
    } else if (q_strings && state != 2 && (*s == '"')) {
      i = 1;
      while ((ch = s[i++]) != '\0')
        if (ch == '"') {
          state = 2;
          tokens++;
          break;
        }
    } else if (state == 0) {
      if ((wspace_sep && !isspace((int)*s)) || (!wspace_sep && *s != '\n')) {
        tokens++;
        state = 1;
      }
    } else if ((wspace_sep && state == 1 && isspace((int)*s)) || *s == '\n')
      state = 0;
    else if (q_strings && state == 2 && (*s == '"'))
      state = 0;
    s++;
    if (chars)
      (*chars)++;
  }
  return tokens;
}
```