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

```asm
<print_string_ptr>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x30,%rsp
  mov    %rdi,-0x28(%rbp)
  movl   $0x0,-0x1c(%rbp)
  cmpq   $0x0,-0x28(%rbp)
  jne    L236
  lea    D34(%rip),%rax
  mov    %rax,%rdi
  call   <cJSON_strdup@plt>
  jmp    L167
L236:
  mov    -0x28(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  jmp    L80
L60:
  movzbl -0x1d(%rbp),%eax
  mov    %eax,%esi
  lea    D36(%rip),%rax
  mov    %rax,%rdi
  call   <strchr@plt>
  test   %rax,%rax
  je     L250
  addl   $0x1,-0x1c(%rbp)
  jmp    L40
L250:
  cmpb   $0x1f,-0x1d(%rbp)
  ja     L40
  addl   $0x5,-0x1c(%rbp)
L40:
  addq   $0x1,-0x18(%rbp)
L80:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  mov    %al,-0x1d(%rbp)
  cmpb   $0x0,-0x1d(%rbp)
  je     L108
  addl   $0x1,-0x1c(%rbp)
  cmpl   $0x0,-0x1c(%rbp)
  jne    L60
L108:
  mov    -0x1c(%rbp),%eax
  add    $0x3,%eax
  mov    %eax,%edi
  call   <cJSON_malloc@plt>
  mov    %rax,-0x8(%rbp)
  cmpq   $0x0,-0x8(%rbp)
  jne    L31
  mov    $0x0,%eax
  jmp    L167
L31:
  mov    -0x8(%rbp),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x28(%rbp),%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x10(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movb   $0x22,(%rax)
  jmp    L76
L263:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x1f,%al
  jbe    L267
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x22,%al
  je     L267
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0x5c,%al
  je     L267
  mov    -0x18(%rbp),%rdx
  lea    0x1(%rdx),%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x10(%rbp),%rax
  lea    0x1(%rax),%rcx
  mov    %rcx,-0x10(%rbp)
  movzbl (%rdx),%edx
  mov    %dl,(%rax)
  jmp    L76
L267:
  mov    -0x10(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movb   $0x5c,(%rax)
  mov    -0x18(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x18(%rbp)
  movzbl (%rax),%eax
  mov    %al,-0x1d(%rbp)
  movzbl -0x1d(%rbp),%eax
  cmp    $0x22,%eax
  jg     L184
  cmp    $0x8,%eax
  jl     L210
  sub    $0x8,%eax
  cmp    $0x1a,%eax
  ja     L210
  mov    %eax,%eax
  lea    0x0(,%rax,4),%rdx
  lea    D26(%rip),%rax
  mov    (%rdx,%rax,1),%eax
  cltq
  lea    D26(%rip),%rdx
  add    %rdx,%rax
  notrack jmp *%rax
L184:
  cmp    $0x5c,%eax
  jne    L210
  mov    -0x10(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movb   $0x5c,(%rax)
  jmp    L76
  mov    -0x10(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movb   $0x22,(%rax)
  jmp    L76
  mov    -0x10(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movb   $0x62,(%rax)
  jmp    L76
  mov    -0x10(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movb   $0x66,(%rax)
  jmp    L76
  mov    -0x10(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movb   $0x6e,(%rax)
  jmp    L76
  mov    -0x10(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movb   $0x72,(%rax)
  jmp    L76
  mov    -0x10(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movb   $0x74,(%rax)
  jmp    L76
L210:
  movzbl -0x1d(%rbp),%edx
  mov    -0x10(%rbp),%rax
  lea    D17(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  addq   $0x5,-0x10(%rbp)
  nop
L76:
  mov    -0x18(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  jne    L263
  mov    -0x10(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movb   $0x22,(%rax)
  mov    -0x10(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x10(%rbp)
  movb   $0x0,(%rax)
  mov    -0x8(%rbp),%rax
L167:
  leave
  ret
```

tool_calls: name: retrieve_data
arguments: data_tag: D34
type_infered: string
name: retrieve_data
arguments: data_tag: D36
type_infered: string
name: retrieve_data
arguments: data_tag: D17
type_infered: string

tool: 

tool: D36: "\
	

tool: D17: u%04x

assistant: ```c
char *print_string_ptr(const char *str) {
  const char *ptr;
  char *ptr2, *out;
  int len = 0;
  unsigned char token;
  if (!str)
    return cJSON_strdup("");
  ptr = str;
  while ((token = *ptr) && ++len) {
    if (strchr("\"\\\b\f\n\r\t", token))
      len++;
    else if (token < 32)
      len += 5;
    ptr++;
  }
  out = (char *)cJSON_malloc(len + 3);
  if (!out)
    return 0;
  ptr2 = out;
  ptr = str;
  *ptr2++ = '\"';
  while (*ptr) {
    if ((unsigned char)*ptr > 31 && *ptr != '\"' && *ptr != '\\')
      *ptr2++ = *ptr++;
    else {
      *ptr2++ = '\\';
      switch (token = *ptr++) {
      case '\\':
        *ptr2++ = '\\';
        break;
      case '\"':
        *ptr2++ = '\"';
        break;
      case '\b':
        *ptr2++ = 'b';
        break;
      case '\f':
        *ptr2++ = 'f';
        break;
      case '\n':
        *ptr2++ = 'n';
        break;
      case '\r':
        *ptr2++ = 'r';
        break;
      case '\t':
        *ptr2++ = 't';
        break;
      default:
        sprintf(ptr2, "u%04x", token);
        ptr2 += 5;
        break;
      }
    }
  }
  *ptr2++ = '\"';
  *ptr2++ = 0;
  return out;
}
```