#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*/ err_msg;

/* Variables and functions */
int /*<<< orphan*/ strncpy(char *, char const *, size_t);
int ulz77_error_description_cpy(char *buf, size_t buf_len, int err_no) {
  static const char *err_msg[] = {
      "Unknown error",       "Null Pointer",
      "Invalid argument",    "Memory allocation failed",
      "File opening failed", "File reading failed",
      "Buffer full",         "Undefined operation",
      "Unknown reader",      "Invalid reader",
      "Unknown writter",     "Invalid writter",
      "Narrow buffer size",  "Undefined error",
  };
  if ((err_no >= 0) ||
      ((unsigned int)(-err_no) >= sizeof(err_msg) / sizeof(char *))) {
    return 0;
  }
  strncpy(buf, err_msg[err_no], buf_len);
  return 0;
}


x86 assembly (clang, -O0):
<ulz77_error_description_cpy>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %edx,-0x1c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jge    113e <ulz77_error_description_cpy+0x2e>
xor    %eax,%eax
sub    -0x1c(%rbp),%eax
mov    %eax,%eax
cmp    $0xe,%rax
jb     114a <ulz77_error_description_cpy+0x3a>
movl   $0x0,-0x4(%rbp)
jmp    116d <ulz77_error_description_cpy+0x5d>
mov    -0x10(%rbp),%rdi
movslq -0x1c(%rbp),%rcx
lea    0x2ed7(%rip),%rax
mov    (%rax,%rcx,8),%rsi
mov    -0x18(%rbp),%rdx
call   1030 <strncpy@plt>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ulz77_error_description_cpy>:
test   %edx,%edx
jns    113d <ulz77_error_description_cpy+0x2d>
lea    -0x1(%rdx),%ecx
cmp    $0xfffffff2,%ecx
jb     113d <ulz77_error_description_cpy+0x2d>
push   %rax
mov    %rsi,%rax
movslq %edx,%rcx
lea    0xed6(%rip),%rdx
movslq (%rdx,%rcx,4),%rsi
add    %rdx,%rsi
mov    %rax,%rdx
call   1030 <strncpy@plt>
add    $0x8,%rsp
xor    %eax,%eax
ret

LLVM IR (-O0):
@ulz77_error_description_cpy.err_msg = internal global [14 x i8*] [i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.1, i32 0, i32 0), i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.2, i32 0, i32 0), i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str.3, i32 0, i32 0), i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.4, i32 0, i32 0), i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.5, i32 0, i32 0), i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.6, i32 0, i32 0), i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.7, i32 0, i32 0), i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.8, i32 0, i32 0), i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.9, i32 0, i32 0), i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.10, i32 0, i32 0), i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.11, i32 0, i32 0), i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.12, i32 0, i32 0), i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.13, i32 0, i32 0)]
@.str = [14 x i8] c"Unknown error\00"
@.str.1 = [13 x i8] c"Null Pointer\00"
@.str.2 = [17 x i8] c"Invalid argument\00"
@.str.3 = [25 x i8] c"Memory allocation failed\00"
@.str.4 = [20 x i8] c"File opening failed\00"
@.str.5 = [20 x i8] c"File reading failed\00"
@.str.6 = [12 x i8] c"Buffer full\00"
@.str.7 = [20 x i8] c"Undefined operation\00"
@.str.8 = [15 x i8] c"Unknown reader\00"
@.str.9 = [15 x i8] c"Invalid reader\00"
@.str.10 = [16 x i8] c"Unknown writter\00"
@.str.11 = [16 x i8] c"Invalid writter\00"
@.str.12 = [19 x i8] c"Narrow buffer size\00"
@.str.13 = [16 x i8] c"Undefined error\00"
define i32 @ulz77_error_description_cpy(i8* %0, i64 %1, i32 %2) {
%4 = alloca i32
%5 = alloca i8*
%6 = alloca i64
%7 = alloca i32
store i8* %0, i8** %5
store i64 %1, i64* %6
store i32 %2, i32* %7
%8 = load i32, i32* %7
%9 = icmp sge i32 %8, 0
br i1 %9, label %15, label %10
10: ; preds = %3
%11 = load i32, i32* %7
%12 = sub nsw i32 0, %11
%13 = zext i32 %12 to i64
%14 = icmp uge i64 %13, 14
br i1 %14, label %15, label %16
15: ; preds = %10, %3
store i32 0, i32* %4
br label %24
16: ; preds = %10
%17 = load i8*, i8** %5
%18 = load i32, i32* %7
%19 = sext i32 %18 to i64
%20 = getelementptr inbounds [14 x i8*], [14 x i8*]* @ulz77_error_description_cpy.err_msg, i64 0, i64 %19
%21 = load i8*, i8** %20
%22 = load i64, i64* %6
%23 = call i32 @strncpy(i8* %17, i8* %21, i64 %22)
store i32 0, i32* %4
br label %24
24: ; preds = %16, %15
%25 = load i32, i32* %4
ret i32 %25
}

LLVM IR (-O2):
@reltable.ulz77_error_description_cpy = internal unnamed_addr constant [14 x i32] [i32 trunc (i64 sub (i64 ptrtoint ([14 x i8]* @.str to i64), i64 ptrtoint ([14 x i32]* @reltable.ulz77_error_description_cpy to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([13 x i8]* @.str.1 to i64), i64 ptrtoint ([14 x i32]* @reltable.ulz77_error_description_cpy to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([17 x i8]* @.str.2 to i64), i64 ptrtoint ([14 x i32]* @reltable.ulz77_error_description_cpy to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([25 x i8]* @.str.3 to i64), i64 ptrtoint ([14 x i32]* @reltable.ulz77_error_description_cpy to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([20 x i8]* @.str.4 to i64), i64 ptrtoint ([14 x i32]* @reltable.ulz77_error_description_cpy to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([20 x i8]* @.str.5 to i64), i64 ptrtoint ([14 x i32]* @reltable.ulz77_error_description_cpy to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([12 x i8]* @.str.6 to i64), i64 ptrtoint ([14 x i32]* @reltable.ulz77_error_description_cpy to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([20 x i8]* @.str.7 to i64), i64 ptrtoint ([14 x i32]* @reltable.ulz77_error_description_cpy to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([15 x i8]* @.str.8 to i64), i64 ptrtoint ([14 x i32]* @reltable.ulz77_error_description_cpy to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([15 x i8]* @.str.9 to i64), i64 ptrtoint ([14 x i32]* @reltable.ulz77_error_description_cpy to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([16 x i8]* @.str.10 to i64), i64 ptrtoint ([14 x i32]* @reltable.ulz77_error_description_cpy to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([16 x i8]* @.str.11 to i64), i64 ptrtoint ([14 x i32]* @reltable.ulz77_error_description_cpy to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([19 x i8]* @.str.12 to i64), i64 ptrtoint ([14 x i32]* @reltable.ulz77_error_description_cpy to i64)) to i32), i32 trunc (i64 sub (i64 ptrtoint ([16 x i8]* @.str.13 to i64), i64 ptrtoint ([14 x i32]* @reltable.ulz77_error_description_cpy to i64)) to i32)]
@.str = [14 x i8] c"Unknown error\00"
@.str.1 = [13 x i8] c"Null Pointer\00"
@.str.2 = [17 x i8] c"Invalid argument\00"
@.str.3 = [25 x i8] c"Memory allocation failed\00"
@.str.4 = [20 x i8] c"File opening failed\00"
@.str.5 = [20 x i8] c"File reading failed\00"
@.str.6 = [12 x i8] c"Buffer full\00"
@.str.7 = [20 x i8] c"Undefined operation\00"
@.str.8 = [15 x i8] c"Unknown reader\00"
@.str.9 = [15 x i8] c"Invalid reader\00"
@.str.10 = [16 x i8] c"Unknown writter\00"
@.str.11 = [16 x i8] c"Invalid writter\00"
@.str.12 = [19 x i8] c"Narrow buffer size\00"
@.str.13 = [16 x i8] c"Undefined error\00"
define i32 @ulz77_error_description_cpy(i8* %0, i64 %1, i32 %2) {
%4 = icmp sgt i32 %2, -1
%5 = add nsw i32 %2, -1
%6 = icmp ult i32 %5, -14
%7 = select i1 %4, i1 true, i1 %6
br i1 %7, label %13, label %8
8: ; preds = %3
%9 = sext i32 %2 to i64
%10 = shl i64 %9, 2
%11 = call i8* @llvm.load.relative.i64(i8* bitcast ([14 x i32]* @reltable.ulz77_error_description_cpy to i8*), i64 %10)
%12 = tail call i32 @strncpy(i8* %0, i8* %11, i64 %1)
br label %13
13: ; preds = %3, %8
ret i32 0
}