user: 请显示与下面列出的汇编代码相匹配的C语言实现：

```asm
<get_keyword_visual>:
  endbr64
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x98,%rsp
  mov    %rdi,%rbp
  mov    %fs:0x28,%rax
  mov    %rax,0x88(%rsp)
  xor    %eax,%eax
  movzbl (%rdi),%edx
  cmp    $0x20,%dl
  jne    L208
  mov    $0x1,%eax
L275:
  mov    %eax,%r12d
  add    $0x1,%rax
  movzbl -0x1(%rbp,%rax,1),%edx
  cmp    $0x20,%dl
  je     L275
L235:
  cmp    $0x21,%dl
  jne    L379
L169:
  lea    0x1(%r12),%ebx
  movslq %ebx,%rax
  movzbl 0x0(%rbp,%rax,1),%edx
  cmp    $0x2c,%dl
  ja     L373
  mov    $0x0,%ecx
  movabs $0x100100000400,%rax
  bt     %rdx,%rax
  jb     L171
L373:
  lea    0x2(%r12),%eax
  cltq
  mov    %rsp,%rsi
  movslq %r12d,%rcx
  sub    %rcx,%rsi
  movabs $0x100100000400,%rdi
  jmp    L312
L208:
  mov    $0x0,%r12d
  jmp    L235
L379:
  lea    D80(%rip),%rdi
  call   <HECMW_vis_print_exit@plt>
  jmp    L169
L0:
  mov    %rsp,%rdi
  mov    $0x6,%edx
  lea    D45(%rip),%rsi
  call   <strncmp@plt>
  mov    %rax,%rdx
  mov    $0x0,%eax
  test   %rdx,%rdx
  je     L170
  jmp    L301
L2:
  lea    D1(%rip),%rdi
  call   <HECMW_vis_print_exit@plt>
  jmp    L268
L387:
  lea    D1(%rip),%rdi
  call   <HECMW_vis_print_exit@plt>
  jmp    L370
L266:
  mov    $0x1,%eax
L334:
  lea    -0x1(%rsp),%rsi
  movabs $0x2000100100000400,%rdi
  jmp    L198
L297:
  mov    %rsp,%rdi
  mov    $0x3,%edx
  lea    D32(%rip),%rsi
  call   <strncmp@plt>
  mov    %rax,%rdx
  mov    $0x1,%eax
  test   %rdx,%rdx
  je     L301
  mov    %rsp,%rdi
  mov    $0x3,%edx
  lea    D92(%rip),%rsi
  call   <strncmp@plt>
  mov    %rax,%rdx
  mov    $0x2,%eax
  test   %rdx,%rdx
  je     L301
  mov    %rsp,%rdi
  mov    $0x3,%edx
  lea    D26(%rip),%rsi
  call   <strncmp@plt>
  mov    %rax,%rdx
  mov    $0x2,%eax
  test   %rdx,%rdx
  je     L301
  lea    D63(%rip),%rdi
  call   <HECMW_vis_print_exit@plt>
  mov    $0x0,%eax
  jmp    L301
L369:
  add    $0x1,%rax
L198:
  mov    %dl,(%rsi,%rax,1)
  mov    %eax,%ecx
  movzbl 0x0(%rbp,%rax,1),%edx
  cmp    $0x3d,%dl
  ja     L369
  add    $0x1,%rax
  bt     %rdx,%rdi
  jae    L198
L283:
  movslq %ecx,%rcx
  movb   $0x0,(%rsp,%rcx,1)
  mov    %rsp,%rdi
  call   <strlen@plt>
  test   %eax,%eax
  jle    L215
  mov    %rsp,%rbx
  lea    -0x1(%rax),%eax
  lea    0x1(%rsp,%rax,1),%rbp
L199:
  movsbl (%rbx),%edi
  call   <tolower@plt>
  mov    %al,(%rbx)
  add    $0x1,%rbx
  cmp    %rbx,%rbp
  jne    L199
L215:
  mov    %rsp,%rdi
  mov    $0x3,%edx
  lea    D61(%rip),%rsi
  call   <strncmp@plt>
  mov    %rax,%rdx
  mov    $0x1,%eax
  test   %rdx,%rdx
  jne    L297
L301:
  mov    0x88(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L226
  add    $0x98,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  ret
L365:
  add    $0x1,%rax
L312:
  mov    %dl,-0x2(%rsi,%rax,1)
  mov    %eax,%ebx
  mov    %eax,%edx
  sub    %r12d,%edx
  lea    -0x1(%rdx),%ecx
  movzbl 0x0(%rbp,%rax,1),%edx
  cmp    $0x2c,%dl
  ja     L365
  add    $0x1,%rax
  bt     %rdx,%rdi
  jae    L312
L171:
  movslq %ecx,%rdx
  movb   $0x0,(%rsp,%rdx,1)
  mov    %rsp,%rdi
  call   <strlen@plt>
  test   %eax,%eax
  jle    L104
  mov    %rsp,%r12
  lea    -0x1(%rax),%eax
  lea    0x1(%rsp,%rax,1),%r13
L55:
  movsbl (%r12),%edi
  call   <tolower@plt>
  mov    %al,(%r12)
  add    $0x1,%r12
  cmp    %r13,%r12
  jne    L55
L104:
  mov    %rsp,%rdi
  mov    $0x6,%edx
  lea    D34(%rip),%rsi
  call   <strncmp@plt>
  test   %rax,%rax
  jne    L0
L170:
  movslq %ebx,%rax
  movzbl 0x0(%rbp,%rax,1),%edx
  cmp    $0x3d,%dl
  je     L212
  cmp    $0xa,%dl
  setne  %cl
  lea    0x1(%rbx),%eax
  cltq
  test   %cl,%cl
  je     L212
L358:
  mov    %eax,%ebx
  movzbl 0x0(%rbp,%rax,1),%edx
  add    $0x1,%rax
  cmp    $0x3d,%dl
  je     L212
  cmp    $0xa,%dl
  jne    L358
L212:
  cmp    $0xa,%dl
  je     L2
L268:
  lea    0x1(%rbx),%r12d
  movslq %r12d,%rax
  movzbl 0x0(%rbp,%rax,1),%edx
  cmp    $0x20,%dl
  jne    L5
  lea    0x2(%rbx),%eax
  cltq
L155:
  mov    %eax,%r12d
  add    $0x1,%rax
  movzbl -0x1(%rbp,%rax,1),%edx
  cmp    $0x20,%dl
  je     L155
L5:
  cmp    $0xa,%dl
  je     L387
L370:
  movslq %r12d,%r12
  add    %r12,%rbp
  movzbl 0x0(%rbp),%edx
  cmp    $0x3d,%dl
  ja     L266
  mov    $0x0,%ecx
  movabs $0x2000100100000400,%rax
  bt     %rdx,%rax
  jb     L283
  mov    $0x1,%eax
  jmp    L334
L226:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: parse_data
arguments: data_tag: D80
type_infered: string
name: parse_data
arguments: data_tag: D45
type_infered: string
name: parse_data
arguments: data_tag: D1
type_infered: string
name: parse_data
arguments: data_tag: D32
type_infered: string
name: parse_data
arguments: data_tag: D92
type_infered: string
name: parse_data
arguments: data_tag: D26
type_infered: string
name: parse_data
arguments: data_tag: D63
type_infered: string
name: parse_data
arguments: data_tag: D61
type_infered: string
name: parse_data
arguments: data_tag: D34
type_infered: string

tool: D80: ERROR: HEC-MW-VIS-E0002: The control parameter format error: should start from !

tool: D45: visual

tool: D1: ERROR: HEC-MW-VIS-E0006:The control parameter format error: visual ID

tool: D32: psr

tool: D92: PVR

tool: D26: pvr

tool: D63: ERROR: HEC-MW-VIS-E0007:The control parameter format error: method only can be PSR or PVR

tool: D61: PSR

tool: D34: VISUAL

assistant: ```c
int get_keyword_visual(char *buf) {
  int i, j, ii, len_tmp;
  int flag;
  char para[128];
  i = 0;
  while (buf[i] == ' ')
    i++;
  if (buf[i] != '!')
    HECMW_vis_print_exit("ERROR: HEC-MW-VIS-E0002: The control parameter format error: should "
                         "start from !");
  i = i + 1;
  j = 0;
  while ((buf[i] != ' ') && (buf[i] != ',') && (buf[i] != '\n')) {
    para[j] = buf[i];
    i++;
    j++;
  }
  flag = 0;
  para[j] = '\0';
  len_tmp = strlen(para);
  for (ii = 0; ii < len_tmp; ii++) {
    para[ii] = tolower(para[ii]);
  }
  if ((strncmp(para, "VISUAL", 6) != 0) && (strncmp(para, "visual", 6) != 0)) {
    flag = 0;
    return (flag);
  }
  while ((buf[i] != '=') && (buf[i] != '\n'))
    i++;
  if (buf[i] == '\n')
    HECMW_vis_print_exit("ERROR: HEC-MW-VIS-E0006:The control parameter format error: visual "
                         "ID");
  i++;
  while ((buf[i] == ' ') && (buf[i] != '\n'))
    i++;
  if (buf[i] == '\n')
    HECMW_vis_print_exit("ERROR: HEC-MW-VIS-E0006:The control parameter format error: visual "
                         "ID");
  j = 0;
  while ((buf[i] != ' ') && (buf[i] != ',') && (buf[i] != '=') && (buf[i] != '\n')) {
    para[j] = buf[i];
    i++;
    j++;
  }
  para[j] = '\0';
  len_tmp = strlen(para);
  for (ii = 0; ii < len_tmp; ii++) {
    para[ii] = tolower(para[ii]);
  }
  if ((strncmp(para, "PSR", 3) == 0) || (strncmp(para, "psr", 3) == 0)) {
    flag = 1;
    return (flag);
  }
  if ((strncmp(para, "PVR", 3) == 0) || (strncmp(para, "pvr", 3) == 0)) {
    flag = 2;
    return (flag);
  }
  HECMW_vis_print_exit("ERROR: HEC-MW-VIS-E0007:The control parameter format error: method only "
                       "can be PSR or PVR");
  return (flag);
}
```