user: 请将以下的汇编代码转换成C语言代码：

```asm
<oauth_url_escape>:
  endbr64
  test   %rdi,%rdi
  je     L4
  push   %r15
  mov    %rdi,%r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x18,%rsp
  call   <strlen@plt>
  movslq %eax,%rbp
  lea    0x1(%rbp),%r10d
  movslq %r10d,%r12
  mov    %r12,%rdi
  call   <malloc@plt>
  mov    %rax,%r14
  cmp    $0x1,%r12
  je     L73
  mov    %r12,0x8(%rsp)
  xor    %r13d,%r13d
  add    %r15,%rbp
  jmp    L37
  nop
L126:
  cmp    $0x2c,%bl
  jg     L40
L94:
  add    $0x2,%r12
  cmp    0x8(%rsp),%r12
  ja     L16
L2:
  lea    (%r14,%r13,1),%rdi
  movzbl %bl,%ecx
  mov    $0x4,%esi
  add    $0x1,%r15
  lea    D18(%rip),%rdx
  add    $0x3,%r13
  call   <snprintf@plt>
  cmp    %rbp,%r15
  je     L58
L37:
  movzbl (%r15),%ebx
  cmp    $0x7f,%bl
  je     L94
  cmp    $0x40,%bl
  jg     L27
  cmp    $0x2e,%bl
  jle    L126
  lea    -0x30(%rbx),%eax
  cmp    $0x9,%al
  ja     L94
L40:
  add    $0x1,%r15
  mov    %bl,(%r14,%r13,1)
  add    $0x1,%r13
  cmp    %rbp,%r15
  jne    L37
L58:
  lea    (%r14,%r13,1),%r8
L8:
  movb   $0x0,(%r8)
  add    $0x18,%rsp
  mov    %r14,%rax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  xchg   %ax,%ax
L27:
  movabs $0x23ffffff43ffffff,%rdx
  lea    -0x41(%rbx),%eax
  bt     %rax,%rdx
  jb     L40
  add    $0x2,%r12
  cmp    0x8(%rsp),%r12
  jbe    L2
L16:
  shlq   0x8(%rsp)
  mov    0x8(%rsp),%rsi
  mov    %r14,%rdi
  call   <realloc@plt>
  mov    %rax,%r14
  jmp    L2
  nopl   0x0(%rax)
L4:
  lea    D5(%rip),%rdi
  jmp    10d0 <strdup@plt>
  nopl   0x0(%rax)
L73:
  mov    %rax,%r8
  jmp    L8
```

tool_calls: name: unpack_data
arguments: data_tag: D18
datatype: string
name: unpack_data
arguments: data_tag: D5
datatype: string

tool: D18: %%%02X

tool: 

assistant: ```c
char *oauth_url_escape(const char *string) {
  size_t alloc, newlen;
  char *ns = NULL, *testing_ptr = NULL;
  unsigned char in;
  size_t strindex = 0;
  size_t length;
  if (!string)
    return strdup("");
  alloc = strlen(string) + 1;
  newlen = alloc;
  ns = (char *)malloc(alloc);
  length = alloc - 1;
  while (length--) {
    in = *string;
    switch (in) {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
    case 'a':
    case 'b':
    case 'c':
    case 'd':
    case 'e':
    case 'f':
    case 'g':
    case 'h':
    case 'i':
    case 'j':
    case 'k':
    case 'l':
    case 'm':
    case 'n':
    case 'o':
    case 'p':
    case 'q':
    case 'r':
    case 's':
    case 't':
    case 'u':
    case 'v':
    case 'w':
    case 'x':
    case 'y':
    case 'z':
    case 'A':
    case 'B':
    case 'C':
    case 'D':
    case 'E':
    case 'F':
    case 'G':
    case 'H':
    case 'I':
    case 'J':
    case 'K':
    case 'L':
    case 'M':
    case 'N':
    case 'O':
    case 'P':
    case 'Q':
    case 'R':
    case 'S':
    case 'T':
    case 'U':
    case 'V':
    case 'W':
    case 'X':
    case 'Y':
    case 'Z':
    case '_':
    case '~':
    case '.':
    case '-':
      ns[strindex++] = in;
      break;
    default:
      newlen += 2;
      if (newlen > alloc) {
        alloc *= 2;
        testing_ptr = (char *)realloc(ns, alloc);
        ns = testing_ptr;
      }
      snprintf(&ns[strindex], 4, "%%%02X", in);
      strindex += 3;
      break;
    }
    string++;
  }
  ns[strindex] = 0;
  return ns;
}
```