char *onion_c_quote(const char *str, char *ret, int l) {
  const unsigned char *p = (const unsigned char *)str;
  char *r = ret;
  *r++ = '"';
  l -= 3;
  while (*p != '\0') {
    if (*p == '\n') {
      *r = '\\';
      r++;
      *r = 'n';
      r++;
      *r = '"';
      r++;
      *r = '\n';
      r++;
      *r = '"';
    } else if (*p == '\r') {
      *r = '\\';
      r++;
      *r = 'n';
    } else if (*p == '"') {
      *r = '\\';
      r++;
      *r = '"';
    } else if (*p == '\\') {
      *r = '\\';
      r++;
      *r = '\\';
    } else if (*p == '\t') {
      *r = '\\';
      r++;
      *r = 't';
    } else if (*p > 127) {
      int c = *p;
      if (l < 4) {
        *r = '\0';
        return ret;
      }
      *r = '\\';
      r++;
      *r = '0' + ((c >> 6) & 0x03);
      r++;
      *r = '0' + ((c >> 3) & 0x07);
      r++;
      *r = '0' + (c & 0x07);
    } else {
      *r = *p;
    }
    r++;
    p++;
    l--;
    if (l <= 0) {
      *r = '\0';
      break;
    }
  }
  *r++ = '"';
  *r++ = '\0';
  return ret;
}


x86 assembly (clang, -O0):
<onion_c_quote>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %edx,-0x1c(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x30(%rbp)
movb   $0x22,(%rax)
mov    -0x1c(%rbp),%eax
sub    $0x3,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x28(%rbp),%rax
movzbl (%rax),%eax
cmp    $0x0,%eax
je     1370 <onion_c_quote+0x270>
mov    -0x28(%rbp),%rax
movzbl (%rax),%eax
cmp    $0xa,%eax
jne    11b2 <onion_c_quote+0xb2>
mov    -0x30(%rbp),%rax
movb   $0x5c,(%rax)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
movb   $0x6e,(%rax)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
movb   $0x22,(%rax)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
movb   $0xa,(%rax)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
movb   $0x22,(%rax)
jmp    1334 <onion_c_quote+0x234>
mov    -0x28(%rbp),%rax
movzbl (%rax),%eax
cmp    $0xd,%eax
jne    11e1 <onion_c_quote+0xe1>
mov    -0x30(%rbp),%rax
movb   $0x5c,(%rax)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
movb   $0x6e,(%rax)
jmp    132f <onion_c_quote+0x22f>
mov    -0x28(%rbp),%rax
movzbl (%rax),%eax
cmp    $0x22,%eax
jne    1210 <onion_c_quote+0x110>
mov    -0x30(%rbp),%rax
movb   $0x5c,(%rax)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
movb   $0x22,(%rax)
jmp    132a <onion_c_quote+0x22a>
mov    -0x28(%rbp),%rax
movzbl (%rax),%eax
cmp    $0x5c,%eax
jne    123f <onion_c_quote+0x13f>
mov    -0x30(%rbp),%rax
movb   $0x5c,(%rax)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
movb   $0x5c,(%rax)
jmp    1325 <onion_c_quote+0x225>
mov    -0x28(%rbp),%rax
movzbl (%rax),%eax
cmp    $0x9,%eax
jne    126e <onion_c_quote+0x16e>
mov    -0x30(%rbp),%rax
movb   $0x5c,(%rax)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
movb   $0x74,(%rax)
jmp    1320 <onion_c_quote+0x220>
mov    -0x28(%rbp),%rax
movzbl (%rax),%eax
cmp    $0x7f,%eax
jle    130f <onion_c_quote+0x20f>
mov    -0x28(%rbp),%rax
movzbl (%rax),%eax
mov    %eax,-0x34(%rbp)
cmpl   $0x4,-0x1c(%rbp)
jge    12a6 <onion_c_quote+0x1a6>
mov    -0x30(%rbp),%rax
movb   $0x0,(%rax)
mov    -0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    139c <onion_c_quote+0x29c>
mov    -0x30(%rbp),%rax
movb   $0x5c,(%rax)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x34(%rbp),%eax
sar    $0x6,%eax
and    $0x3,%eax
add    $0x30,%eax
mov    %al,%cl
mov    -0x30(%rbp),%rax
mov    %cl,(%rax)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x34(%rbp),%eax
sar    $0x3,%eax
and    $0x7,%eax
add    $0x30,%eax
mov    %al,%cl
mov    -0x30(%rbp),%rax
mov    %cl,(%rax)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x34(%rbp),%eax
and    $0x7,%eax
add    $0x30,%eax
mov    %al,%cl
mov    -0x30(%rbp),%rax
mov    %cl,(%rax)
jmp    131b <onion_c_quote+0x21b>
mov    -0x28(%rbp),%rax
mov    (%rax),%cl
mov    -0x30(%rbp),%rax
mov    %cl,(%rax)
jmp    1320 <onion_c_quote+0x220>
jmp    1325 <onion_c_quote+0x225>
jmp    132a <onion_c_quote+0x22a>
jmp    132f <onion_c_quote+0x22f>
jmp    1334 <onion_c_quote+0x234>
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
mov    -0x1c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x1c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jg     136b <onion_c_quote+0x26b>
mov    -0x30(%rbp),%rax
movb   $0x0,(%rax)
jmp    1370 <onion_c_quote+0x270>
jmp    113a <onion_c_quote+0x3a>
mov    -0x30(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x30(%rbp)
movb   $0x22,(%rax)
mov    -0x30(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x30(%rbp)
movb   $0x0,(%rax)
mov    -0x18(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<onion_c_quote>:
mov    %rsi,%rax
lea    0x1(%rsi),%r10
movb   $0x22,(%rsi)
add    $0xfffffffd,%edx
lea    0xeec(%rip),%r8
jmp    1136 <onion_c_quote+0x36>
movw   $0x745c,(%r10)
add    $0x1,%r10
add    $0x1,%r10
add    $0x1,%rdi
lea    -0x1(%rdx),%ecx
cmp    $0x1,%edx
mov    %ecx,%edx
jle    11c3 <onion_c_quote+0xc3>
movzbl (%rdi),%r9d
cmp    $0x22,%r9
ja     1160 <onion_c_quote+0x60>
movslq (%r8,%r9,4),%rsi
add    %r8,%rsi
jmp    *%rsi
movl   $0xa226e5c,(%r10)
movb   $0x22,0x4(%r10)
add    $0x4,%r10
jmp    1120 <onion_c_quote+0x20>
nopl   0x0(%rax,%rax,1)
cmp    $0x5c,%r9b
jne    116e <onion_c_quote+0x6e>
movw   $0x5c5c,(%r10)
jmp    111c <onion_c_quote+0x1c>
test   %r9b,%r9b
js     1188 <onion_c_quote+0x88>
mov    %r9b,(%r10)
jmp    1120 <onion_c_quote+0x20>
movw   $0x6e5c,(%r10)
jmp    111c <onion_c_quote+0x1c>
movw   $0x225c,(%r10)
jmp    111c <onion_c_quote+0x1c>
cmp    $0x4,%edx
jl     11cf <onion_c_quote+0xcf>
movb   $0x5c,(%r10)
mov    %r9d,%ecx
shr    $0x6,%cl
or     $0x30,%cl
mov    %cl,0x1(%r10)
mov    %r9d,%ecx
shr    $0x3,%cl
and    $0x7,%cl
or     $0x30,%cl
mov    %cl,0x2(%r10)
and    $0x7,%r9b
or     $0x30,%r9b
mov    %r9b,0x3(%r10)
add    $0x3,%r10
jmp    1120 <onion_c_quote+0x20>
movb   $0x0,(%r10)
movb   $0x22,(%r10)
add    $0x1,%r10
movb   $0x0,(%r10)
ret

LLVM IR (-O0):
define i8* @onion_c_quote(i8* %0, i8* %1, i32 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i8*
%9 = alloca i8*
%10 = alloca i32
store i8* %0, i8** %5
store i8* %1, i8** %6
store i32 %2, i32* %7
%11 = load i8*, i8** %5
store i8* %11, i8** %8
%12 = load i8*, i8** %6
store i8* %12, i8** %9
%13 = load i8*, i8** %9
%14 = getelementptr inbounds i8, i8* %13, i32 1
store i8* %14, i8** %9
store i8 34, i8* %13
%15 = load i32, i32* %7
%16 = sub nsw i32 %15, 3
store i32 %16, i32* %7
br label %17
17: ; preds = %140, %3
%18 = load i8*, i8** %8
%19 = load i8, i8* %18
%20 = zext i8 %19 to i32
%21 = icmp ne i32 %20, 0
br i1 %21, label %22, label %141
22: ; preds = %17
%23 = load i8*, i8** %8
%24 = load i8, i8* %23
%25 = zext i8 %24 to i32
%26 = icmp eq i32 %25, 10
br i1 %26, label %27, label %41
27: ; preds = %22
%28 = load i8*, i8** %9
store i8 92, i8* %28
%29 = load i8*, i8** %9
%30 = getelementptr inbounds i8, i8* %29, i32 1
store i8* %30, i8** %9
%31 = load i8*, i8** %9
store i8 110, i8* %31
%32 = load i8*, i8** %9
%33 = getelementptr inbounds i8, i8* %32, i32 1
store i8* %33, i8** %9
%34 = load i8*, i8** %9
store i8 34, i8* %34
%35 = load i8*, i8** %9
%36 = getelementptr inbounds i8, i8* %35, i32 1
store i8* %36, i8** %9
%37 = load i8*, i8** %9
store i8 10, i8* %37
%38 = load i8*, i8** %9
%39 = getelementptr inbounds i8, i8* %38, i32 1
store i8* %39, i8** %9
%40 = load i8*, i8** %9
store i8 34, i8* %40
br label %129
41: ; preds = %22
%42 = load i8*, i8** %8
%43 = load i8, i8* %42
%44 = zext i8 %43 to i32
%45 = icmp eq i32 %44, 13
br i1 %45, label %46, label %51
46: ; preds = %41
%47 = load i8*, i8** %9
store i8 92, i8* %47
%48 = load i8*, i8** %9
%49 = getelementptr inbounds i8, i8* %48, i32 1
store i8* %49, i8** %9
%50 = load i8*, i8** %9
store i8 110, i8* %50
br label %128
51: ; preds = %41
%52 = load i8*, i8** %8
%53 = load i8, i8* %52
%54 = zext i8 %53 to i32
%55 = icmp eq i32 %54, 34
br i1 %55, label %56, label %61
56: ; preds = %51
%57 = load i8*, i8** %9
store i8 92, i8* %57
%58 = load i8*, i8** %9
%59 = getelementptr inbounds i8, i8* %58, i32 1
store i8* %59, i8** %9
%60 = load i8*, i8** %9
store i8 34, i8* %60
br label %127
61: ; preds = %51
%62 = load i8*, i8** %8
%63 = load i8, i8* %62
%64 = zext i8 %63 to i32
%65 = icmp eq i32 %64, 92
br i1 %65, label %66, label %71
66: ; preds = %61
%67 = load i8*, i8** %9
store i8 92, i8* %67
%68 = load i8*, i8** %9
%69 = getelementptr inbounds i8, i8* %68, i32 1
store i8* %69, i8** %9
%70 = load i8*, i8** %9
store i8 92, i8* %70
br label %126
71: ; preds = %61
%72 = load i8*, i8** %8
%73 = load i8, i8* %72
%74 = zext i8 %73 to i32
%75 = icmp eq i32 %74, 9
br i1 %75, label %76, label %81
76: ; preds = %71
%77 = load i8*, i8** %9
store i8 92, i8* %77
%78 = load i8*, i8** %9
%79 = getelementptr inbounds i8, i8* %78, i32 1
store i8* %79, i8** %9
%80 = load i8*, i8** %9
store i8 116, i8* %80
br label %125
81: ; preds = %71
%82 = load i8*, i8** %8
%83 = load i8, i8* %82
%84 = zext i8 %83 to i32
%85 = icmp sgt i32 %84, 127
br i1 %85, label %86, label %120
86: ; preds = %81
%87 = load i8*, i8** %8
%88 = load i8, i8* %87
%89 = zext i8 %88 to i32
store i32 %89, i32* %10
%90 = load i32, i32* %7
%91 = icmp slt i32 %90, 4
br i1 %91, label %92, label %95
92: ; preds = %86
%93 = load i8*, i8** %9
store i8 0, i8* %93
%94 = load i8*, i8** %6
store i8* %94, i8** %4
br label %147
95: ; preds = %86
%96 = load i8*, i8** %9
store i8 92, i8* %96
%97 = load i8*, i8** %9
%98 = getelementptr inbounds i8, i8* %97, i32 1
store i8* %98, i8** %9
%99 = load i32, i32* %10
%100 = ashr i32 %99, 6
%101 = and i32 %100, 3
%102 = add nsw i32 48, %101
%103 = trunc i32 %102 to i8
%104 = load i8*, i8** %9
store i8 %103, i8* %104
%105 = load i8*, i8** %9
%106 = getelementptr inbounds i8, i8* %105, i32 1
store i8* %106, i8** %9
%107 = load i32, i32* %10
%108 = ashr i32 %107, 3
%109 = and i32 %108, 7
%110 = add nsw i32 48, %109
%111 = trunc i32 %110 to i8
%112 = load i8*, i8** %9
store i8 %111, i8* %112
%113 = load i8*, i8** %9
%114 = getelementptr inbounds i8, i8* %113, i32 1
store i8* %114, i8** %9
%115 = load i32, i32* %10
%116 = and i32 %115, 7
%117 = add nsw i32 48, %116
%118 = trunc i32 %117 to i8
%119 = load i8*, i8** %9
store i8 %118, i8* %119
br label %124
120: ; preds = %81
%121 = load i8*, i8** %8
%122 = load i8, i8* %121
%123 = load i8*, i8** %9
store i8 %122, i8* %123
br label %124
124: ; preds = %120, %95
br label %125
125: ; preds = %124, %76
br label %126
126: ; preds = %125, %66
br label %127
127: ; preds = %126, %56
br label %128
128: ; preds = %127, %46
br label %129
129: ; preds = %128, %27
%130 = load i8*, i8** %9
%131 = getelementptr inbounds i8, i8* %130, i32 1
store i8* %131, i8** %9
%132 = load i8*, i8** %8
%133 = getelementptr inbounds i8, i8* %132, i32 1
store i8* %133, i8** %8
%134 = load i32, i32* %7
%135 = add nsw i32 %134, -1
store i32 %135, i32* %7
%136 = load i32, i32* %7
%137 = icmp sle i32 %136, 0
br i1 %137, label %138, label %140
138: ; preds = %129
%139 = load i8*, i8** %9
store i8 0, i8* %139
br label %141
140: ; preds = %129
br label %17
141: ; preds = %138, %17
%142 = load i8*, i8** %9
%143 = getelementptr inbounds i8, i8* %142, i32 1
store i8* %143, i8** %9
store i8 34, i8* %142
%144 = load i8*, i8** %9
%145 = getelementptr inbounds i8, i8* %144, i32 1
store i8* %145, i8** %9
store i8 0, i8* %144
%146 = load i8*, i8** %6
store i8* %146, i8** %4
br label %147
147: ; preds = %141, %92
%148 = load i8*, i8** %4
ret i8* %148
}

LLVM IR (-O2):
define i8* @onion_c_quote(i8* nocapture %0, i8* writeonly %1, i32 %2) {
%4 = getelementptr inbounds i8, i8* %1, i64 1
store i8 34, i8* %1
%5 = add nsw i32 %2, -3
br label %6
6: ; preds = %40, %3
%7 = phi i32 [ %5, %3 ], [ %44, %40 ]
%8 = phi i8* [ %0, %3 ], [ %43, %40 ]
%9 = phi i8* [ %4, %3 ], [ %42, %40 ]
%10 = load i8, i8* %8
switch i8 %10, label %24 [
i8 0, label %47
i8 10, label %11
i8 13, label %16
i8 34, label %18
i8 92, label %20
i8 9, label %22
]
11: ; preds = %6
store i8 92, i8* %9
%12 = getelementptr inbounds i8, i8* %9, i64 1
store i8 110, i8* %12
%13 = getelementptr inbounds i8, i8* %9, i64 2
store i8 34, i8* %13
%14 = getelementptr inbounds i8, i8* %9, i64 3
store i8 10, i8* %14
%15 = getelementptr inbounds i8, i8* %9, i64 4
store i8 34, i8* %15
br label %40
16: ; preds = %6
store i8 92, i8* %9
%17 = getelementptr inbounds i8, i8* %9, i64 1
store i8 110, i8* %17
br label %40
18: ; preds = %6
store i8 92, i8* %9
%19 = getelementptr inbounds i8, i8* %9, i64 1
store i8 34, i8* %19
br label %40
20: ; preds = %6
store i8 92, i8* %9
%21 = getelementptr inbounds i8, i8* %9, i64 1
store i8 92, i8* %21
br label %40
22: ; preds = %6
store i8 92, i8* %9
%23 = getelementptr inbounds i8, i8* %9, i64 1
store i8 116, i8* %23
br label %40
24: ; preds = %6
%25 = icmp slt i8 %10, 0
br i1 %25, label %26, label %39
26: ; preds = %24
%27 = icmp slt i32 %7, 4
br i1 %27, label %50, label %28
28: ; preds = %26
store i8 92, i8* %9
%29 = getelementptr inbounds i8, i8* %9, i64 1
%30 = lshr i8 %10, 6
%31 = or i8 %30, 48
store i8 %31, i8* %29
%32 = getelementptr inbounds i8, i8* %9, i64 2
%33 = lshr i8 %10, 3
%34 = and i8 %33, 7
%35 = or i8 %34, 48
store i8 %35, i8* %32
%36 = getelementptr inbounds i8, i8* %9, i64 3
%37 = and i8 %10, 7
%38 = or i8 %37, 48
store i8 %38, i8* %36
br label %40
39: ; preds = %24
store i8 %10, i8* %9
br label %40
40: ; preds = %28, %16, %20, %39, %22, %18, %11
%41 = phi i8* [ %15, %11 ], [ %17, %16 ], [ %19, %18 ], [ %21, %20 ], [ %23, %22 ], [ %36, %28 ], [ %9, %39 ]
%42 = getelementptr inbounds i8, i8* %41, i64 1
%43 = getelementptr inbounds i8, i8* %8, i64 1
%44 = add nsw i32 %7, -1
%45 = icmp slt i32 %7, 2
br i1 %45, label %46, label %6
46: ; preds = %40
store i8 0, i8* %42
br label %47
47: ; preds = %6, %46
%48 = phi i8* [ %42, %46 ], [ %9, %6 ]
%49 = getelementptr inbounds i8, i8* %48, i64 1
store i8 34, i8* %48
br label %50
50: ; preds = %26, %47
%51 = phi i8* [ %49, %47 ], [ %9, %26 ]
store i8 0, i8* %51
ret i8* %1
}