#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int /*<<< orphan*/ rsbuf;
typedef int /*<<< orphan*/ lsbuf;
typedef int /*<<< orphan*/ fsbuf;

/* Variables and functions */
int ERR_GET_FUNC(unsigned long);
int ERR_GET_LIB(unsigned long);
int ERR_GET_REASON(unsigned long);
char *ERR_func_error_string(unsigned long);
char *ERR_lib_error_string(unsigned long);
char *ERR_reason_error_string(unsigned long);
int snprintf(char *, size_t, char *, unsigned long, ...);
char *strchr(char *, char);
void ERR_error_string_n(unsigned long e, char *buf, size_t len) {
  char lsbuf[30], fsbuf[30], rsbuf[30];
  const char *ls, *fs, *rs;
  int l, f, r, ret;
  l = ERR_GET_LIB(e);
  f = ERR_GET_FUNC(e);
  r = ERR_GET_REASON(e);
  ls = ERR_lib_error_string(e);
  fs = ERR_func_error_string(e);
  rs = ERR_reason_error_string(e);
  if (ls == NULL) {
    (void)snprintf(lsbuf, sizeof(lsbuf), "lib(%d)", l);
    ls = lsbuf;
  }
  if (fs == NULL) {
    (void)snprintf(fsbuf, sizeof(fsbuf), "func(%d)", f);
    fs = fsbuf;
  }
  if (rs == NULL) {
    (void)snprintf(rsbuf, sizeof(rsbuf), "reason(%d)", r);
    rs = rsbuf;
  }
  ret = snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls, fs, rs);
  if (ret == -1)
    return;
  if (ret >= len) {
    if (len > 4) {
      int i;
      char *s = buf;
      for (i = 0; i < 4; i++) {
        char *colon = strchr(s, ':');
        if (colon == NULL || colon > &buf[len - 1] - 4 + i) {
          colon = &buf[len - 1] - 4 + i;
          *colon = ':';
        }
        s = colon + 1;
      }
    }
  }
}


x86 assembly (clang, -O0):
<ERR_error_string_n>:
push   %rbp
mov    %rsp,%rbp
sub    $0xd0,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rdi
call   1070 <ERR_GET_LIB@plt>
mov    %eax,-0x9c(%rbp)
mov    -0x8(%rbp),%rdi
call   1090 <ERR_GET_FUNC@plt>
mov    %eax,-0xa0(%rbp)
mov    -0x8(%rbp),%rdi
call   10a0 <ERR_GET_REASON@plt>
mov    %eax,-0xa4(%rbp)
mov    -0x8(%rbp),%rdi
call   1060 <ERR_lib_error_string@plt>
mov    %rax,-0x88(%rbp)
mov    -0x8(%rbp),%rdi
call   1080 <ERR_func_error_string@plt>
mov    %rax,-0x90(%rbp)
mov    -0x8(%rbp),%rdi
call   1050 <ERR_reason_error_string@plt>
mov    %rax,-0x98(%rbp)
cmpq   $0x0,-0x88(%rbp)
jne    122b <ERR_error_string_n+0xab>
lea    -0x40(%rbp),%rdi
movslq -0x9c(%rbp),%rcx
mov    $0x1e,%esi
lea    0xde7(%rip),%rdx
mov    $0x0,%al
call   1040 <snprintf@plt>
lea    -0x40(%rbp),%rax
mov    %rax,-0x88(%rbp)
cmpq   $0x0,-0x90(%rbp)
jne    1262 <ERR_error_string_n+0xe2>
lea    -0x60(%rbp),%rdi
movslq -0xa0(%rbp),%rcx
mov    $0x1e,%esi
lea    0xdb8(%rip),%rdx
mov    $0x0,%al
call   1040 <snprintf@plt>
lea    -0x60(%rbp),%rax
mov    %rax,-0x90(%rbp)
cmpq   $0x0,-0x98(%rbp)
jne    1299 <ERR_error_string_n+0x119>
lea    -0x80(%rbp),%rdi
movslq -0xa4(%rbp),%rcx
mov    $0x1e,%esi
lea    0xd8a(%rip),%rdx
mov    $0x0,%al
call   1040 <snprintf@plt>
lea    -0x80(%rbp),%rax
mov    %rax,-0x98(%rbp)
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
mov    -0x8(%rbp),%rcx
mov    -0x88(%rbp),%r8
mov    -0x90(%rbp),%r9
mov    -0x98(%rbp),%rax
lea    0xd5b(%rip),%rdx
mov    %rax,(%rsp)
mov    $0x0,%al
call   1040 <snprintf@plt>
mov    %eax,-0xa8(%rbp)
cmpl   $0xffffffff,-0xa8(%rbp)
jne    12e4 <ERR_error_string_n+0x164>
jmp    13d3 <ERR_error_string_n+0x253>
movslq -0xa8(%rbp),%rax
cmp    -0x18(%rbp),%rax
jb     13d3 <ERR_error_string_n+0x253>
cmpq   $0x4,-0x18(%rbp)
jbe    13ce <ERR_error_string_n+0x24e>
mov    -0x10(%rbp),%rax
mov    %rax,-0xb8(%rbp)
movl   $0x0,-0xac(%rbp)
cmpl   $0x4,-0xac(%rbp)
jge    13c9 <ERR_error_string_n+0x249>
mov    -0xb8(%rbp),%rdi
mov    $0x3a,%esi
call   1030 <strchr@plt>
mov    %rax,-0xc0(%rbp)
cmpq   $0x0,-0xc0(%rbp)
je     1375 <ERR_error_string_n+0x1f5>
mov    -0xc0(%rbp),%rax
mov    -0x10(%rbp),%rcx
mov    -0x18(%rbp),%rdx
sub    $0x1,%rdx
add    %rdx,%rcx
add    $0xfffffffffffffffc,%rcx
movslq -0xac(%rbp),%rdx
add    %rdx,%rcx
cmp    %rcx,%rax
jbe    13a3 <ERR_error_string_n+0x223>
mov    -0x10(%rbp),%rax
mov    -0x18(%rbp),%rcx
sub    $0x1,%rcx
add    %rcx,%rax
add    $0xfffffffffffffffc,%rax
movslq -0xac(%rbp),%rcx
add    %rcx,%rax
mov    %rax,-0xc0(%rbp)
mov    -0xc0(%rbp),%rax
movb   $0x3a,(%rax)
mov    -0xc0(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0xb8(%rbp)
mov    -0xac(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0xac(%rbp)
jmp    1315 <ERR_error_string_n+0x195>
jmp    13ce <ERR_error_string_n+0x24e>
jmp    13d3 <ERR_error_string_n+0x253>
add    $0xd0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ERR_error_string_n>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x88,%rsp
mov    %rdx,%r15
mov    %rsi,0x18(%rsp)
mov    %rdi,%rbx
call   1070 <ERR_GET_LIB@plt>
mov    %eax,%r14d
mov    %rbx,%rdi
call   1090 <ERR_GET_FUNC@plt>
mov    %eax,0x10(%rsp)
mov    %rbx,%rdi
call   10a0 <ERR_GET_REASON@plt>
mov    %eax,0x14(%rsp)
mov    %rbx,%rdi
call   1060 <ERR_lib_error_string@plt>
mov    %rax,%r12
mov    %rbx,%rdi
call   1080 <ERR_func_error_string@plt>
mov    %rax,%r13
mov    %rbx,%rdi
call   1050 <ERR_reason_error_string@plt>
mov    %rax,%rbp
test   %r12,%r12
je     1317 <ERR_error_string_n+0x197>
test   %r13,%r13
jne    120b <ERR_error_string_n+0x8b>
lea    0x40(%rsp),%r13
movslq 0x10(%rsp),%rcx
lea    0xe0c(%rip),%rdx
mov    $0x1e,%esi
mov    %r13,%rdi
xor    %eax,%eax
call   1040 <snprintf@plt>
test   %rbp,%rbp
mov    0x18(%rsp),%r14
jne    1235 <ERR_error_string_n+0xb5>
lea    0x20(%rsp),%rbp
movslq 0x14(%rsp),%rcx
lea    0xdeb(%rip),%rdx
mov    $0x1e,%esi
mov    %rbp,%rdi
xor    %eax,%eax
call   1040 <snprintf@plt>
mov    %rbp,(%rsp)
lea    0xddc(%rip),%rdx
mov    %r14,%rdi
mov    %r15,%rsi
mov    %rbx,%rcx
mov    %r12,%r8
mov    %r13,%r9
xor    %eax,%eax
call   1040 <snprintf@plt>
cmp    $0xffffffff,%eax
je     1305 <ERR_error_string_n+0x185>
cmp    $0x5,%r15
jb     1305 <ERR_error_string_n+0x185>
cltq
cmp    %r15,%rax
jb     1305 <ERR_error_string_n+0x185>
lea    (%r15,%r14,1),%rbx
add    $0xfffffffffffffffb,%rbx
mov    %r14,%rdi
mov    $0x3a,%esi
call   1030 <strchr@plt>
test   %rax,%rax
je     1293 <ERR_error_string_n+0x113>
cmp    %rbx,%rax
jbe    1299 <ERR_error_string_n+0x119>
movb   $0x3a,(%rbx)
mov    %rbx,%rax
add    $0x1,%rax
mov    %rax,%rdi
mov    $0x3a,%esi
call   1030 <strchr@plt>
lea    0x1(%rbx),%rcx
test   %rax,%rax
je     12b8 <ERR_error_string_n+0x138>
cmp    %rcx,%rax
jbe    12be <ERR_error_string_n+0x13e>
movb   $0x3a,(%rcx)
mov    %rcx,%rax
add    $0x1,%rax
mov    %rax,%rdi
mov    $0x3a,%esi
call   1030 <strchr@plt>
lea    0x2(%rbx),%rcx
test   %rax,%rax
je     12dd <ERR_error_string_n+0x15d>
cmp    %rcx,%rax
jbe    12e3 <ERR_error_string_n+0x163>
movb   $0x3a,(%rcx)
mov    %rcx,%rax
add    $0x1,%rax
mov    %rax,%rdi
mov    $0x3a,%esi
call   1030 <strchr@plt>
add    $0x3,%rbx
test   %rax,%rax
je     1302 <ERR_error_string_n+0x182>
cmp    %rbx,%rax
jbe    1305 <ERR_error_string_n+0x185>
movb   $0x3a,(%rbx)
add    $0x88,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
lea    0x60(%rsp),%r12
movslq %r14d,%rcx
lea    0xcda(%rip),%rdx
mov    $0x1e,%esi
mov    %r12,%rdi
xor    %eax,%eax
call   1040 <snprintf@plt>
test   %r13,%r13
jne    120b <ERR_error_string_n+0x8b>
jmp    11eb <ERR_error_string_n+0x6b>

LLVM IR (-O0):
@.str = [8 x i8] c"lib(%d)\00"
@.str.1 = [9 x i8] c"func(%d)\00"
@.str.2 = [11 x i8] c"reason(%d)\00"
@.str.3 = [21 x i8] c"error:%08lX:%s:%s:%s\00"
define void @ERR_error_string_n(i64 %0, i8* %1, i64 %2) {
%4 = alloca i64
%5 = alloca i8*
%6 = alloca i64
%7 = alloca [30 x i8]
%8 = alloca [30 x i8]
%9 = alloca [30 x i8]
%10 = alloca i8*
%11 = alloca i8*
%12 = alloca i8*
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca i32
%17 = alloca i32
%18 = alloca i8*
%19 = alloca i8*
store i64 %0, i64* %4
store i8* %1, i8** %5
store i64 %2, i64* %6
%20 = load i64, i64* %4
%21 = call i32 @ERR_GET_LIB(i64 %20)
store i32 %21, i32* %13
%22 = load i64, i64* %4
%23 = call i32 @ERR_GET_FUNC(i64 %22)
store i32 %23, i32* %14
%24 = load i64, i64* %4
%25 = call i32 @ERR_GET_REASON(i64 %24)
store i32 %25, i32* %15
%26 = load i64, i64* %4
%27 = call i8* @ERR_lib_error_string(i64 %26)
store i8* %27, i8** %10
%28 = load i64, i64* %4
%29 = call i8* @ERR_func_error_string(i64 %28)
store i8* %29, i8** %11
%30 = load i64, i64* %4
%31 = call i8* @ERR_reason_error_string(i64 %30)
store i8* %31, i8** %12
%32 = load i8*, i8** %10
%33 = icmp eq i8* %32, null
br i1 %33, label %34, label %40
34: ; preds = %3
%35 = getelementptr inbounds [30 x i8], [30 x i8]* %7, i64 0, i64 0
%36 = load i32, i32* %13
%37 = sext i32 %36 to i64
%38 = call i32 (i8*, i64, i8*, i64, ...) @snprintf(i8* %35, i64 30, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i64 %37)
%39 = getelementptr inbounds [30 x i8], [30 x i8]* %7, i64 0, i64 0
store i8* %39, i8** %10
br label %40
40: ; preds = %34, %3
%41 = load i8*, i8** %11
%42 = icmp eq i8* %41, null
br i1 %42, label %43, label %49
43: ; preds = %40
%44 = getelementptr inbounds [30 x i8], [30 x i8]* %8, i64 0, i64 0
%45 = load i32, i32* %14
%46 = sext i32 %45 to i64
%47 = call i32 (i8*, i64, i8*, i64, ...) @snprintf(i8* %44, i64 30, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0), i64 %46)
%48 = getelementptr inbounds [30 x i8], [30 x i8]* %8, i64 0, i64 0
store i8* %48, i8** %11
br label %49
49: ; preds = %43, %40
%50 = load i8*, i8** %12
%51 = icmp eq i8* %50, null
br i1 %51, label %52, label %58
52: ; preds = %49
%53 = getelementptr inbounds [30 x i8], [30 x i8]* %9, i64 0, i64 0
%54 = load i32, i32* %15
%55 = sext i32 %54 to i64
%56 = call i32 (i8*, i64, i8*, i64, ...) @snprintf(i8* %53, i64 30, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i64 0, i64 0), i64 %55)
%57 = getelementptr inbounds [30 x i8], [30 x i8]* %9, i64 0, i64 0
store i8* %57, i8** %12
br label %58
58: ; preds = %52, %49
%59 = load i8*, i8** %5
%60 = load i64, i64* %6
%61 = load i64, i64* %4
%62 = load i8*, i8** %10
%63 = load i8*, i8** %11
%64 = load i8*, i8** %12
%65 = call i32 (i8*, i64, i8*, i64, ...) @snprintf(i8* %59, i64 %60, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.3, i64 0, i64 0), i64 %61, i8* %62, i8* %63, i8* %64)
store i32 %65, i32* %16
%66 = load i32, i32* %16
%67 = icmp eq i32 %66, -1
br i1 %67, label %68, label %69
68: ; preds = %58
br label %116
69: ; preds = %58
%70 = load i32, i32* %16
%71 = sext i32 %70 to i64
%72 = load i64, i64* %6
%73 = icmp uge i64 %71, %72
br i1 %73, label %74, label %116
74: ; preds = %69
%75 = load i64, i64* %6
%76 = icmp ugt i64 %75, 4
br i1 %76, label %77, label %115
77: ; preds = %74
%78 = load i8*, i8** %5
store i8* %78, i8** %18
store i32 0, i32* %17
br label %79
79: ; preds = %111, %77
%80 = load i32, i32* %17
%81 = icmp slt i32 %80, 4
br i1 %81, label %82, label %114
82: ; preds = %79
%83 = load i8*, i8** %18
%84 = call i8* @strchr(i8* %83, i8 signext 58)
store i8* %84, i8** %19
%85 = load i8*, i8** %19
%86 = icmp eq i8* %85, null
br i1 %86, label %98, label %87
87: ; preds = %82
%88 = load i8*, i8** %19
%89 = load i8*, i8** %5
%90 = load i64, i64* %6
%91 = sub i64 %90, 1
%92 = getelementptr inbounds i8, i8* %89, i64 %91
%93 = getelementptr inbounds i8, i8* %92, i64 -4
%94 = load i32, i32* %17
%95 = sext i32 %94 to i64
%96 = getelementptr inbounds i8, i8* %93, i64 %95
%97 = icmp ugt i8* %88, %96
br i1 %97, label %98, label %108
98: ; preds = %87, %82
%99 = load i8*, i8** %5
%100 = load i64, i64* %6
%101 = sub i64 %100, 1
%102 = getelementptr inbounds i8, i8* %99, i64 %101
%103 = getelementptr inbounds i8, i8* %102, i64 -4
%104 = load i32, i32* %17
%105 = sext i32 %104 to i64
%106 = getelementptr inbounds i8, i8* %103, i64 %105
store i8* %106, i8** %19
%107 = load i8*, i8** %19
store i8 58, i8* %107
br label %108
108: ; preds = %98, %87
%109 = load i8*, i8** %19
%110 = getelementptr inbounds i8, i8* %109, i64 1
store i8* %110, i8** %18
br label %111
111: ; preds = %108
%112 = load i32, i32* %17
%113 = add nsw i32 %112, 1
store i32 %113, i32* %17
br label %79
114: ; preds = %79
br label %115
115: ; preds = %114, %74
br label %116
116: ; preds = %68, %115, %69
ret void
}

LLVM IR (-O2):
@.str = [8 x i8] c"lib(%d)\00"
@.str.1 = [9 x i8] c"func(%d)\00"
@.str.2 = [11 x i8] c"reason(%d)\00"
@.str.3 = [21 x i8] c"error:%08lX:%s:%s:%s\00"
define void @ERR_error_string_n(i64 %0, i8* %1, i64 %2) {
%4 = alloca [30 x i8]
%5 = alloca [30 x i8]
%6 = alloca [30 x i8]
%7 = getelementptr inbounds [30 x i8], [30 x i8]* %4, i64 0, i64 0
%8 = getelementptr inbounds [30 x i8], [30 x i8]* %5, i64 0, i64 0
%9 = getelementptr inbounds [30 x i8], [30 x i8]* %6, i64 0, i64 0
%10 = tail call i32 @ERR_GET_LIB(i64 %0)
%11 = tail call i32 @ERR_GET_FUNC(i64 %0)
%12 = tail call i32 @ERR_GET_REASON(i64 %0)
%13 = tail call i8* @ERR_lib_error_string(i64 %0)
%14 = tail call i8* @ERR_func_error_string(i64 %0)
%15 = tail call i8* @ERR_reason_error_string(i64 %0)
%16 = icmp eq i8* %13, null
br i1 %16, label %17, label %20
17: ; preds = %3
%18 = sext i32 %10 to i64
%19 = call i32 (i8*, i64, i8*, i64, ...) @snprintf(i8* %7, i64 30, i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str, i64 0, i64 0), i64 %18)
br label %20
20: ; preds = %17, %3
%21 = phi i8* [ %7, %17 ], [ %13, %3 ]
%22 = icmp eq i8* %14, null
br i1 %22, label %23, label %26
23: ; preds = %20
%24 = sext i32 %11 to i64
%25 = call i32 (i8*, i64, i8*, i64, ...) @snprintf(i8* %8, i64 30, i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0), i64 %24)
br label %26
26: ; preds = %23, %20
%27 = phi i8* [ %8, %23 ], [ %14, %20 ]
%28 = icmp eq i8* %15, null
br i1 %28, label %29, label %32
29: ; preds = %26
%30 = sext i32 %12 to i64
%31 = call i32 (i8*, i64, i8*, i64, ...) @snprintf(i8* %9, i64 30, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.2, i64 0, i64 0), i64 %30)
br label %32
32: ; preds = %29, %26
%33 = phi i8* [ %9, %29 ], [ %15, %26 ]
%34 = call i32 (i8*, i64, i8*, i64, ...) @snprintf(i8* %1, i64 %2, i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.3, i64 0, i64 0), i64 %0, i8* %21, i8* %27, i8* %33)
%35 = icmp eq i32 %34, -1
br i1 %35, label %77, label %36
36: ; preds = %32
%37 = sext i32 %34 to i64
%38 = icmp uge i64 %37, %2
%39 = icmp ugt i64 %2, 4
%40 = and i1 %39, %38
br i1 %40, label %41, label %77
41: ; preds = %36
%42 = add i64 %2, -1
%43 = getelementptr inbounds i8, i8* %1, i64 %42
%44 = getelementptr inbounds i8, i8* %43, i64 -4
%45 = call i8* @strchr(i8* dereferenceable(1) %1, i8 signext 58)
%46 = icmp eq i8* %45, null
%47 = icmp ugt i8* %45, %44
%48 = select i1 %46, i1 true, i1 %47
br i1 %48, label %49, label %50
49: ; preds = %41
store i8 58, i8* %44
br label %50
50: ; preds = %41, %49
%51 = phi i8* [ %44, %49 ], [ %45, %41 ]
%52 = getelementptr inbounds i8, i8* %51, i64 1
%53 = call i8* @strchr(i8* dereferenceable(1) %52, i8 signext 58)
%54 = icmp eq i8* %53, null
%55 = getelementptr inbounds i8, i8* %44, i64 1
%56 = icmp ugt i8* %53, %55
%57 = select i1 %54, i1 true, i1 %56
br i1 %57, label %58, label %59
58: ; preds = %50
store i8 58, i8* %55
br label %59
59: ; preds = %58, %50
%60 = phi i8* [ %55, %58 ], [ %53, %50 ]
%61 = getelementptr inbounds i8, i8* %60, i64 1
%62 = call i8* @strchr(i8* dereferenceable(1) %61, i8 signext 58)
%63 = icmp eq i8* %62, null
%64 = getelementptr inbounds i8, i8* %44, i64 2
%65 = icmp ugt i8* %62, %64
%66 = select i1 %63, i1 true, i1 %65
br i1 %66, label %67, label %68
67: ; preds = %59
store i8 58, i8* %64
br label %68
68: ; preds = %67, %59
%69 = phi i8* [ %64, %67 ], [ %62, %59 ]
%70 = getelementptr inbounds i8, i8* %69, i64 1
%71 = call i8* @strchr(i8* dereferenceable(1) %70, i8 signext 58)
%72 = icmp eq i8* %71, null
%73 = getelementptr inbounds i8, i8* %44, i64 3
%74 = icmp ugt i8* %71, %73
%75 = select i1 %72, i1 true, i1 %74
br i1 %75, label %76, label %77
76: ; preds = %68
store i8 58, i8* %73
br label %77
77: ; preds = %68, %76, %36, %32
ret void
}