diff --git a/rules/cstring/ir_unsafe.json b/rules/cstring/ir_unsafe.json index 91b7b08f..62e68909 100644 --- a/rules/cstring/ir_unsafe.json +++ b/rules/cstring/ir_unsafe.json @@ -66,10 +66,635 @@ "is_unsafe_pointer": true } }, + "f10": { + "body": [ + { + "text": "libc::memchr(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const ::libc::c_void, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": ", " + }, + { + "placeholder": { + "arg": 2, + "access": "read" + } + }, + { + "text": " as usize)" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "i32" + }, + "a2": { + "type": "usize" + } + }, + "return_type": { + "type": "*mut ::libc::c_void", + "is_unsafe_pointer": true + } + }, + "f11": { + "body": [ + { + "text": "libc::strrchr(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": ") as *mut u8" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "i32" + } + }, + "return_type": { + "type": "*mut u8", + "is_unsafe_pointer": true + } + }, + "f12": { + "body": [ + { + "text": "libc::memchr(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const ::libc::c_void, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": ", " + }, + { + "placeholder": { + "arg": 2, + "access": "read" + } + }, + { + "text": " as usize) as *const ::libc::c_void" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "i32" + }, + "a2": { + "type": "usize" + } + }, + "return_type": { + "type": "*const ::libc::c_void", + "is_unsafe_pointer": true + } + }, + "f13": { + "body": [ + { + "text": "libc::strrchr(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": ") as *const u8" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "i32" + } + }, + "return_type": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "f14": { + "body": [ + { + "text": "libc::strrchr(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": ") as *mut u8" + } + ], + "params": { + "a0": { + "type": "*mut u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "i32" + } + }, + "return_type": { + "type": "*mut u8", + "is_unsafe_pointer": true + } + }, + "f15": { + "body": [ + { + "text": "libc::strdup(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8) as *mut u8" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "*mut u8", + "is_unsafe_pointer": true + } + }, + "f16": { + "body": [ + { + "text": "libc::strcspn(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": " as *const i8) as u64" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "u64" + } + }, + "f17": { + "body": [ + { + "text": "libc::strspn(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": " as *const i8) as u64" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "u64" + } + }, + "f18": { + "body": [ + { + "text": "libc::strstr(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": " as *const i8) as *mut u8" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "*mut u8", + "is_unsafe_pointer": true + } + }, + "f19": { + "body": [ + { + "text": "libc::strstr(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": " as *const i8) as *const u8" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, "f2": { "body": [ { - "text": "let byte_0 = " + "text": "let byte_0 = " + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *mut u8;\n for offset in 0.." + }, + { + "placeholder": { + "arg": 2, + "access": "read" + } + }, + { + "text": " {\n *" + }, + { + "method_call": { + "receiver": [ + { + "text": "byte_0" + } + ], + "body": [ + { + "text": ".offset(offset as isize)" + } + ] + } + }, + { + "text": " = " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": " as u8;\n }\n " + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + } + ], + "multi_statement": true, + "params": { + "a0": { + "type": "*mut u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a2": { + "type": "usize" + } + }, + "return_type": { + "type": "*mut u8", + "is_unsafe_pointer": true + } + }, + "f20": { + "body": [ + { + "text": "libc::strstr(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": " as *const i8) as *mut u8" + } + ], + "params": { + "a0": { + "type": "*mut u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "*mut u8", + "is_unsafe_pointer": true + } + }, + "f21": { + "body": [ + { + "text": "libc::strpbrk(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": " as *const i8) as *mut u8" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "*mut u8", + "is_unsafe_pointer": true + } + }, + "f22": { + "body": [ + { + "text": "libc::strpbrk(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": " as *const i8) as *const u8" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "f23": { + "body": [ + { + "text": "libc::strpbrk(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": " as *const i8) as *mut u8" + } + ], + "params": { + "a0": { + "type": "*mut u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "*mut u8", + "is_unsafe_pointer": true + } + }, + "f24": { + "body": [ + { + "text": "libc::memrchr(" }, { "placeholder": { @@ -78,7 +703,16 @@ } }, { - "text": " as *mut u8;\n for offset in 0.." + "text": " as *const ::libc::c_void, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": ", " }, { "placeholder": { @@ -87,24 +721,40 @@ } }, { - "text": " {\n *" + "text": " as usize)" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "i32" }, + "a2": { + "type": "usize" + } + }, + "return_type": { + "type": "*mut ::libc::c_void", + "is_unsafe_pointer": true + }, + "target_os": "linux" + }, + "f25": { + "body": [ { - "method_call": { - "receiver": [ - { - "text": "byte_0" - } - ], - "body": [ - { - "text": ".offset(offset as isize)" - } - ] + "text": "libc::memrchr(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" } }, { - "text": " = " + "text": " as *const ::libc::c_void, " }, { "placeholder": { @@ -113,32 +763,123 @@ } }, { - "text": " as u8;\n }\n " + "text": ", " + }, + { + "placeholder": { + "arg": 2, + "access": "read" + } + }, + { + "text": " as usize) as *const ::libc::c_void" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "i32" + }, + "a2": { + "type": "usize" + } + }, + "return_type": { + "type": "*const ::libc::c_void", + "is_unsafe_pointer": true + }, + "target_os": "linux" + }, + "f26": { + "body": [ + { + "text": "libc::memrchr(" }, { "placeholder": { "arg": 0, "access": "read" } + }, + { + "text": " as *const ::libc::c_void, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": ", " + }, + { + "placeholder": { + "arg": 2, + "access": "read" + } + }, + { + "text": " as usize)" } ], - "multi_statement": true, "params": { "a0": { "type": "*mut u8", "is_unsafe_pointer": true }, "a1": { - "type": "*const u8", - "is_unsafe_pointer": true + "type": "i32" }, "a2": { "type": "usize" } }, "return_type": { - "type": "*mut u8", + "type": "*mut ::libc::c_void", "is_unsafe_pointer": true + }, + "target_os": "linux" + }, + "f27": { + "body": [ + { + "text": "libc::strcasecmp(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": " as *const i8)" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "i32" } }, "f3": { @@ -388,5 +1129,118 @@ "type": "*const u8", "is_unsafe_pointer": true } + }, + "f7": { + "body": [ + { + "text": "libc::strlen(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8) as u64" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "u64" + } + }, + "f8": { + "body": [ + { + "text": "libc::strcmp(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": " as *const i8)" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "*const u8", + "is_unsafe_pointer": true + } + }, + "return_type": { + "type": "i32" + } + }, + "f9": { + "body": [ + { + "text": "libc::strncmp(" + }, + { + "placeholder": { + "arg": 0, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 1, + "access": "read" + } + }, + { + "text": " as *const i8, " + }, + { + "placeholder": { + "arg": 2, + "access": "read" + } + }, + { + "text": " as usize)" + } + ], + "params": { + "a0": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a1": { + "type": "*const u8", + "is_unsafe_pointer": true + }, + "a2": { + "type": "usize" + } + }, + "return_type": { + "type": "i32" + } } } diff --git a/rules/cstring/src.c b/rules/cstring/src.c index 24cbd0e5..be329a8e 100644 --- a/rules/cstring/src.c +++ b/rules/cstring/src.c @@ -1,7 +1,9 @@ // Copyright (c) 2022-present INESC-ID. // Distributed under the MIT license that can be found in the LICENSE file. +#define _GNU_SOURCE #include +#include void *f1(void *dst, const void *src, size_t n) { return memcpy(dst, src, n); } @@ -12,3 +14,29 @@ int f3(const void *s1, const void *s2, size_t n) { return memcmp(s1, s2, n); } void *f4(void *dst, const void *src, size_t n) { return memmove(dst, src, n); } char *f5(const char *a0, int a1) { return strchr(a0, a1); } + +size_t f7(const char *a0) { return strlen(a0); } + +int f8(const char *a0, const char *a1) { return strcmp(a0, a1); } + +int f9(const char *a0, const char *a1, size_t a2) { return strncmp(a0, a1, a2); } + +void *f10(const void *a0, int a1, size_t a2) { return memchr(a0, a1, a2); } + +char *f11(const char *a0, int a1) { return strrchr(a0, a1); } + +char *f15(const char *a0) { return strdup(a0); } + +size_t f16(const char *a0, const char *a1) { return strcspn(a0, a1); } + +size_t f17(const char *a0, const char *a1) { return strspn(a0, a1); } + +char *f18(const char *a0, const char *a1) { return strstr(a0, a1); } + +char *f21(const char *a0, const char *a1) { return strpbrk(a0, a1); } + +#if defined(__linux__) +void *f24(const void *a0, int a1, size_t a2) { return memrchr(a0, a1, a2); } +#endif + +int f27(const char *a0, const char *a1) { return strcasecmp(a0, a1); } diff --git a/rules/cstring/src.cpp b/rules/cstring/src.cpp index 3e1c77cc..39704958 100644 --- a/rules/cstring/src.cpp +++ b/rules/cstring/src.cpp @@ -4,3 +4,23 @@ #include const char *f6(const char *a0, int a1) { return strchr(a0, a1); } + +const void *f12(const void *a0, int a1, size_t a2) { return memchr(a0, a1, a2); } + +const char *f13(const char *a0, int a1) { return strrchr(a0, a1); } + +char *f14(char *a0, int a1) { return strrchr(a0, a1); } + +const char *f19(const char *a0, const char *a1) { return strstr(a0, a1); } + +char *f20(char *a0, const char *a1) { return strstr(a0, a1); } + +const char *f22(const char *a0, const char *a1) { return strpbrk(a0, a1); } + +char *f23(char *a0, const char *a1) { return strpbrk(a0, a1); } + +#if defined(__linux__) +const void *f25(const void *a0, int a1, size_t a2) { return memrchr(a0, a1, a2); } + +void *f26(void *a0, int a1, size_t a2) { return memrchr(a0, a1, a2); } +#endif diff --git a/rules/cstring/tgt_unsafe.rs b/rules/cstring/tgt_unsafe.rs index 8e0ab804..192f0de3 100644 --- a/rules/cstring/tgt_unsafe.rs +++ b/rules/cstring/tgt_unsafe.rs @@ -43,3 +43,90 @@ unsafe fn f5(a0: *const u8, a1: i32) -> *mut u8 { unsafe fn f6(a0: *const u8, a1: i32) -> *const u8 { libc::strchr(a0 as *const i8, a1) as *const u8 } + +unsafe fn f7(a0: *const u8) -> u64 { + libc::strlen(a0 as *const i8) as u64 +} + +unsafe fn f8(a0: *const u8, a1: *const u8) -> i32 { + libc::strcmp(a0 as *const i8, a1 as *const i8) +} + +unsafe fn f9(a0: *const u8, a1: *const u8, a2: usize) -> i32 { + libc::strncmp(a0 as *const i8, a1 as *const i8, a2 as usize) +} + +unsafe fn f10(a0: *const u8, a1: i32, a2: usize) -> *mut ::libc::c_void { + libc::memchr(a0 as *const ::libc::c_void, a1, a2 as usize) +} + +unsafe fn f11(a0: *const u8, a1: i32) -> *mut u8 { + libc::strrchr(a0 as *const i8, a1) as *mut u8 +} + +unsafe fn f12(a0: *const u8, a1: i32, a2: usize) -> *const ::libc::c_void { + libc::memchr(a0 as *const ::libc::c_void, a1, a2 as usize) as *const ::libc::c_void +} + +unsafe fn f13(a0: *const u8, a1: i32) -> *const u8 { + libc::strrchr(a0 as *const i8, a1) as *const u8 +} + +unsafe fn f14(a0: *mut u8, a1: i32) -> *mut u8 { + libc::strrchr(a0 as *const i8, a1) as *mut u8 +} + +unsafe fn f15(a0: *const u8) -> *mut u8 { + libc::strdup(a0 as *const i8) as *mut u8 +} + +unsafe fn f16(a0: *const u8, a1: *const u8) -> u64 { + libc::strcspn(a0 as *const i8, a1 as *const i8) as u64 +} + +unsafe fn f17(a0: *const u8, a1: *const u8) -> u64 { + libc::strspn(a0 as *const i8, a1 as *const i8) as u64 +} + +unsafe fn f18(a0: *const u8, a1: *const u8) -> *mut u8 { + libc::strstr(a0 as *const i8, a1 as *const i8) as *mut u8 +} + +unsafe fn f19(a0: *const u8, a1: *const u8) -> *const u8 { + libc::strstr(a0 as *const i8, a1 as *const i8) as *const u8 +} + +unsafe fn f20(a0: *mut u8, a1: *const u8) -> *mut u8 { + libc::strstr(a0 as *const i8, a1 as *const i8) as *mut u8 +} + +unsafe fn f21(a0: *const u8, a1: *const u8) -> *mut u8 { + libc::strpbrk(a0 as *const i8, a1 as *const i8) as *mut u8 +} + +unsafe fn f22(a0: *const u8, a1: *const u8) -> *const u8 { + libc::strpbrk(a0 as *const i8, a1 as *const i8) as *const u8 +} + +unsafe fn f23(a0: *mut u8, a1: *const u8) -> *mut u8 { + libc::strpbrk(a0 as *const i8, a1 as *const i8) as *mut u8 +} + +#[cfg(target_os = "linux")] +unsafe fn f24(a0: *const u8, a1: i32, a2: usize) -> *mut ::libc::c_void { + libc::memrchr(a0 as *const ::libc::c_void, a1, a2 as usize) +} + +#[cfg(target_os = "linux")] +unsafe fn f25(a0: *const u8, a1: i32, a2: usize) -> *const ::libc::c_void { + libc::memrchr(a0 as *const ::libc::c_void, a1, a2 as usize) as *const ::libc::c_void +} + +#[cfg(target_os = "linux")] +unsafe fn f26(a0: *mut u8, a1: i32, a2: usize) -> *mut ::libc::c_void { + libc::memrchr(a0 as *const ::libc::c_void, a1, a2 as usize) +} + +unsafe fn f27(a0: *const u8, a1: *const u8) -> i32 { + libc::strcasecmp(a0 as *const i8, a1 as *const i8) +} diff --git a/tests/unit/cstring.cpp b/tests/unit/cstring.cpp new file mode 100644 index 00000000..e72c26df --- /dev/null +++ b/tests/unit/cstring.cpp @@ -0,0 +1,183 @@ +// no-compile: refcount +#define _GNU_SOURCE +#include +#include +#include +#include + +static void test_memcpy() { + const char src[] = "hello"; + char dst[6] = {0}; + void *r = std::memcpy(dst, src, 6); + assert(r == dst); + assert(dst[0] == 'h' && dst[1] == 'e' && dst[2] == 'l'); + assert(dst[3] == 'l' && dst[4] == 'o' && dst[5] == '\0'); +} + +static void test_memset() { + char buf[4]; + void *r = std::memset(buf, 'x', 4); + assert(r == buf); + assert(buf[0] == 'x' && buf[1] == 'x' && buf[2] == 'x' && buf[3] == 'x'); +} + +static void test_memcmp() { + const char a[] = {1, 2, 3, 4}; + const char b[] = {1, 2, 3, 4}; + const char c[] = {1, 2, 9, 4}; + assert(std::memcmp(a, b, 4) == 0); + assert(std::memcmp(a, c, 4) < 0); + assert(std::memcmp(c, a, 4) > 0); +} + +static void test_memmove() { + char buf[6] = {'a', 'b', 'c', 'd', 'e', '\0'}; + void *r = std::memmove(buf + 1, buf, 4); + assert(r == buf + 1); + assert(buf[0] == 'a' && buf[1] == 'a' && buf[2] == 'b'); + assert(buf[3] == 'c' && buf[4] == 'd' && buf[5] == '\0'); +} + +static void test_strchr() { + const char *s = "hello world"; + const char *r = std::strchr(s, 'w'); + assert(r != nullptr); + assert(*r == 'w'); + assert(std::strchr(s, 'z') == nullptr); +} + +static void test_strlen() { + assert(std::strlen("") == 0); + assert(std::strlen("hello") == 5); + assert(std::strlen("hello world") == 11); +} + +static void test_strcmp() { + assert(std::strcmp("abc", "abc") == 0); + assert(std::strcmp("abc", "abd") < 0); + assert(std::strcmp("abd", "abc") > 0); + const char *p = "abc"; + const char *q = "abd"; + char buf[] = {'a', 'b', 'c', '\0'}; + assert(std::strcmp(p, p) == 0); + assert(std::strcmp(p, q) < 0); + assert(std::strcmp(buf, p) == 0); +} + +static void test_strncmp() { + assert(std::strncmp("abcdef", "abcxyz", 3) == 0); + assert(std::strncmp("abcdef", "abcxyz", 4) < 0); + assert(std::strncmp("abcxyz", "abcdef", 4) > 0); + const char *p = "abcdef"; + const char *q = "abcxyz"; + char buf[] = {'a', 'b', 'c', 'd', 'e', 'f', '\0'}; + std::size_t n = 3; + assert(std::strncmp(p, q, n) == 0); + assert(std::strncmp(p, q, n + 1) < 0); + assert(std::strncmp(buf, p, 6) == 0); +} + +static void test_memchr() { + const char data[] = {0x10, 0x20, 0x30, 0x40}; + const void *r = std::memchr(data, 0x30, 4); + assert(r == &data[2]); + assert(std::memchr(data, 0x99, 4) == nullptr); + const void *p = data; + std::size_t n = 4; + assert(std::memchr(p, 0x10, n) == p); +} + +static void test_strrchr() { + const char *s = "hello world"; + const char *r = std::strrchr(s, 'l'); + assert(r != nullptr); + assert(*r == 'l'); + assert(r == s + 9); + assert(std::strrchr(s, 'z') == nullptr); + char buf[] = {'a', 'b', 'a', '\0'}; + assert(std::strrchr(buf, 'a') == &buf[2]); +} + +static void test_strdup() { + char *d = strdup("hello"); + assert(d != nullptr); + assert(std::strcmp(d, "hello") == 0); + std::free(d); + const char *p = "world"; + char buf[] = {'a', 'b', 'c', '\0'}; + char *d2 = strdup(p); + assert(d2 != nullptr); + assert(std::strcmp(d2, p) == 0); + std::free(d2); + char *d3 = strdup(buf); + assert(d3 != nullptr); + assert(std::strcmp(d3, buf) == 0); + std::free(d3); +} + +static void test_strcspn() { + assert(std::strcspn("hello", "el") == 1); + assert(std::strcspn("abc", "xyz") == 3); + assert(std::strcspn("", "abc") == 0); + const char *s = "hello"; + const char *rej = "el"; + assert(std::strcspn(s, rej) == 1); +} + +static void test_strspn() { + assert(std::strspn("hello", "hel") == 4); + assert(std::strspn("abc", "xyz") == 0); + assert(std::strspn("aaa", "a") == 3); + const char *s = "hello"; + const char *acc = "hel"; + assert(std::strspn(s, acc) == 4); +} + +static void test_strstr() { + const char *h = "hello world"; + const char *r = std::strstr(h, "world"); + assert(r != nullptr); + assert(r == h + 6); + assert(std::strstr(h, "xyz") == nullptr); + char buf[] = {'h', 'e', 'l', 'l', 'o', '\0'}; + assert(std::strstr(buf, "ll") == &buf[2]); +} + +static void test_strpbrk() { + const char *s = "hello world"; + const char *r = std::strpbrk(s, "wo"); + assert(r != nullptr); + assert(r == s + 4); + assert(std::strpbrk(s, "xyz") == nullptr); + char buf[] = {'a', 'b', 'c', '\0'}; + assert(std::strpbrk(buf, "b") == &buf[1]); +} + +static void test_strcasecmp() { + assert(strcasecmp("HELLO", "hello") == 0); + assert(strcasecmp("abc", "abd") < 0); + assert(strcasecmp("abd", "abc") > 0); + const char *p = "FOO"; + const char *q = "foo"; + assert(strcasecmp(p, q) == 0); +} + +int main() { + test_memcpy(); + test_memset(); + test_memcmp(); + test_memmove(); + test_strchr(); + test_strlen(); + test_strcmp(); + test_strncmp(); + test_memchr(); + test_strrchr(); + test_strdup(); + test_strcspn(); + test_strspn(); + test_strstr(); + test_strpbrk(); + test_strcasecmp(); + return 0; +} diff --git a/tests/unit/out/unsafe/cstring.rs b/tests/unit/out/unsafe/cstring.rs new file mode 100644 index 00000000..32afbc91 --- /dev/null +++ b/tests/unit/out/unsafe/cstring.rs @@ -0,0 +1,420 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub unsafe fn test_memcpy_0() { + let src: [u8; 6] = *b"hello\0"; + let mut dst: [u8; 6] = [0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8]; + let mut r: *mut ::libc::c_void = { + if 6_u64 != 0 { + ::std::ptr::copy_nonoverlapping( + (src.as_ptr() as *const u8 as *const ::libc::c_void), + (dst.as_mut_ptr() as *mut u8 as *mut ::libc::c_void), + 6_u64 as usize, + ) + } + (dst.as_mut_ptr() as *mut u8 as *mut ::libc::c_void) + }; + assert!(((r) == (dst.as_mut_ptr() as *mut u8 as *mut ::libc::c_void))); + assert!( + (((dst[(0) as usize] as i32) == (('h' as u8) as i32)) + && ((dst[(1) as usize] as i32) == (('e' as u8) as i32))) + && ((dst[(2) as usize] as i32) == (('l' as u8) as i32)) + ); + assert!( + (((dst[(3) as usize] as i32) == (('l' as u8) as i32)) + && ((dst[(4) as usize] as i32) == (('o' as u8) as i32))) + && ((dst[(5) as usize] as i32) == (('\0' as u8) as i32)) + ); +} +pub unsafe fn test_memset_1() { + let mut buf: [u8; 4] = [0_u8; 4]; + let mut r: *mut ::libc::c_void = { + let byte_0 = (buf.as_mut_ptr() as *mut u8 as *mut ::libc::c_void) as *mut u8; + for offset in 0..4_u64 { + *byte_0.offset(offset as isize) = (('x' as u8) as i32) as u8; + } + (buf.as_mut_ptr() as *mut u8 as *mut ::libc::c_void) + }; + assert!(((r) == (buf.as_mut_ptr() as *mut u8 as *mut ::libc::c_void))); + assert!( + ((((buf[(0) as usize] as i32) == (('x' as u8) as i32)) + && ((buf[(1) as usize] as i32) == (('x' as u8) as i32))) + && ((buf[(2) as usize] as i32) == (('x' as u8) as i32))) + && ((buf[(3) as usize] as i32) == (('x' as u8) as i32)) + ); +} +pub unsafe fn test_memcmp_2() { + let a: [u8; 4] = [1_u8, 2_u8, 3_u8, 4_u8]; + let b: [u8; 4] = [1_u8, 2_u8, 3_u8, 4_u8]; + let c: [u8; 4] = [1_u8, 2_u8, 9_u8, 4_u8]; + assert!( + (({ + let sa = core::slice::from_raw_parts( + (a.as_ptr() as *const u8 as *const ::libc::c_void) as *const u8, + 4_u64 as usize, + ); + let sb = core::slice::from_raw_parts( + (b.as_ptr() as *const u8 as *const ::libc::c_void) as *const u8, + 4_u64 as usize, + ); + let mut diff = 0_i32; + for (x, y) in sa.iter().zip(sb.iter()) { + if x != y { + diff = (*x as i32) - (*y as i32); + break; + } + } + diff + }) == (0)) + ); + assert!( + (({ + let sa = core::slice::from_raw_parts( + (a.as_ptr() as *const u8 as *const ::libc::c_void) as *const u8, + 4_u64 as usize, + ); + let sb = core::slice::from_raw_parts( + (c.as_ptr() as *const u8 as *const ::libc::c_void) as *const u8, + 4_u64 as usize, + ); + let mut diff = 0_i32; + for (x, y) in sa.iter().zip(sb.iter()) { + if x != y { + diff = (*x as i32) - (*y as i32); + break; + } + } + diff + }) < (0)) + ); + assert!( + (({ + let sa = core::slice::from_raw_parts( + (c.as_ptr() as *const u8 as *const ::libc::c_void) as *const u8, + 4_u64 as usize, + ); + let sb = core::slice::from_raw_parts( + (a.as_ptr() as *const u8 as *const ::libc::c_void) as *const u8, + 4_u64 as usize, + ); + let mut diff = 0_i32; + for (x, y) in sa.iter().zip(sb.iter()) { + if x != y { + diff = (*x as i32) - (*y as i32); + break; + } + } + diff + }) > (0)) + ); +} +pub unsafe fn test_memmove_3() { + let mut buf: [u8; 6] = [ + ('a' as u8), + ('b' as u8), + ('c' as u8), + ('d' as u8), + ('e' as u8), + ('\0' as u8), + ]; + let mut r: *mut ::libc::c_void = { + if 4_u64 != 0 { + ::std::ptr::copy_nonoverlapping( + (buf.as_mut_ptr() as *const u8 as *const ::libc::c_void), + (buf.as_mut_ptr().offset((1) as isize) as *mut u8 as *mut ::libc::c_void), + 4_u64 as usize, + ) + } + (buf.as_mut_ptr().offset((1) as isize) as *mut u8 as *mut ::libc::c_void) + }; + assert!(((r) == (buf.as_mut_ptr().offset((1) as isize) as *mut u8 as *mut ::libc::c_void))); + assert!( + (((buf[(0) as usize] as i32) == (('a' as u8) as i32)) + && ((buf[(1) as usize] as i32) == (('a' as u8) as i32))) + && ((buf[(2) as usize] as i32) == (('b' as u8) as i32)) + ); + assert!( + (((buf[(3) as usize] as i32) == (('c' as u8) as i32)) + && ((buf[(4) as usize] as i32) == (('d' as u8) as i32))) + && ((buf[(5) as usize] as i32) == (('\0' as u8) as i32)) + ); +} +pub unsafe fn test_strchr_4() { + let mut s: *const u8 = b"hello world\0".as_ptr(); + let mut r: *const u8 = libc::strchr(s as *const i8, (('w' as u8) as i32)) as *const u8; + assert!(!((r).is_null())); + assert!((((*r) as i32) == (('w' as u8) as i32))); + assert!((libc::strchr(s as *const i8, (('z' as u8) as i32)) as *const u8).is_null()); +} +pub unsafe fn test_strlen_5() { + assert!(((libc::strlen(b"\0".as_ptr() as *const i8) as u64) == (0_u64))); + assert!(((libc::strlen(b"hello\0".as_ptr() as *const i8) as u64) == (5_u64))); + assert!(((libc::strlen(b"hello world\0".as_ptr() as *const i8) as u64) == (11_u64))); +} +pub unsafe fn test_strcmp_6() { + assert!( + ((libc::strcmp( + b"abc\0".as_ptr() as *const i8, + b"abc\0".as_ptr() as *const i8 + )) == (0)) + ); + assert!( + ((libc::strcmp( + b"abc\0".as_ptr() as *const i8, + b"abd\0".as_ptr() as *const i8 + )) < (0)) + ); + assert!( + ((libc::strcmp( + b"abd\0".as_ptr() as *const i8, + b"abc\0".as_ptr() as *const i8 + )) > (0)) + ); + let mut p: *const u8 = b"abc\0".as_ptr(); + let mut q: *const u8 = b"abd\0".as_ptr(); + let mut buf: [u8; 4] = [('a' as u8), ('b' as u8), ('c' as u8), ('\0' as u8)]; + assert!(((libc::strcmp(p as *const i8, p as *const i8)) == (0))); + assert!(((libc::strcmp(p as *const i8, q as *const i8)) < (0))); + assert!(((libc::strcmp((buf.as_mut_ptr()).cast_const() as *const i8, p as *const i8)) == (0))); +} +pub unsafe fn test_strncmp_7() { + assert!( + ((libc::strncmp( + b"abcdef\0".as_ptr() as *const i8, + b"abcxyz\0".as_ptr() as *const i8, + 3_u64 as usize + )) == (0)) + ); + assert!( + ((libc::strncmp( + b"abcdef\0".as_ptr() as *const i8, + b"abcxyz\0".as_ptr() as *const i8, + 4_u64 as usize + )) < (0)) + ); + assert!( + ((libc::strncmp( + b"abcxyz\0".as_ptr() as *const i8, + b"abcdef\0".as_ptr() as *const i8, + 4_u64 as usize + )) > (0)) + ); + let mut p: *const u8 = b"abcdef\0".as_ptr(); + let mut q: *const u8 = b"abcxyz\0".as_ptr(); + let mut buf: [u8; 7] = [ + ('a' as u8), + ('b' as u8), + ('c' as u8), + ('d' as u8), + ('e' as u8), + ('f' as u8), + ('\0' as u8), + ]; + let mut n: u64 = 3_u64; + assert!(((libc::strncmp(p as *const i8, q as *const i8, n as usize)) == (0))); + assert!( + ((libc::strncmp( + p as *const i8, + q as *const i8, + (n).wrapping_add(1_u64) as usize + )) < (0)) + ); + assert!( + ((libc::strncmp( + (buf.as_mut_ptr()).cast_const() as *const i8, + p as *const i8, + 6_u64 as usize + )) == (0)) + ); +} +pub unsafe fn test_memchr_8() { + let data: [u8; 4] = [16_u8, 32_u8, 48_u8, 64_u8]; + let mut r: *const ::libc::c_void = libc::memchr( + (data.as_ptr() as *const u8 as *const ::libc::c_void) as *const ::libc::c_void, + 48, + 4_u64 as usize, + ) as *const ::libc::c_void; + assert!(((r) == ((&data[(2) as usize] as *const u8) as *const u8 as *const ::libc::c_void))); + assert!((libc::memchr( + (data.as_ptr() as *const u8 as *const ::libc::c_void) as *const ::libc::c_void, + 153, + 4_u64 as usize + ) as *const ::libc::c_void) + .is_null()); + let mut p: *const ::libc::c_void = (data.as_ptr() as *const u8 as *const ::libc::c_void); + let mut n: u64 = 4_u64; + assert!( + ((libc::memchr(p as *const ::libc::c_void, 16, n as usize) as *const ::libc::c_void) + == (p)) + ); +} +pub unsafe fn test_strrchr_9() { + let mut s: *const u8 = b"hello world\0".as_ptr(); + let mut r: *const u8 = libc::strrchr(s as *const i8, (('l' as u8) as i32)) as *const u8; + assert!(!((r).is_null())); + assert!((((*r) as i32) == (('l' as u8) as i32))); + assert!(((r) == (s.offset((9) as isize)))); + assert!((libc::strrchr(s as *const i8, (('z' as u8) as i32)) as *const u8).is_null()); + let mut buf: [u8; 4] = [('a' as u8), ('b' as u8), ('a' as u8), ('\0' as u8)]; + assert!( + ((libc::strrchr(buf.as_mut_ptr() as *const i8, (('a' as u8) as i32)) as *mut u8) + == (&mut buf[(2) as usize] as *mut u8)) + ); +} +pub unsafe fn test_strdup_10() { + let mut d: *mut u8 = libc::strdup(b"hello\0".as_ptr() as *const i8) as *mut u8; + assert!(!((d).is_null())); + assert!( + ((libc::strcmp( + (d).cast_const() as *const i8, + b"hello\0".as_ptr() as *const i8 + )) == (0)) + ); + libc::free((d as *mut u8 as *mut ::libc::c_void)); + let mut p: *const u8 = b"world\0".as_ptr(); + let mut buf: [u8; 4] = [('a' as u8), ('b' as u8), ('c' as u8), ('\0' as u8)]; + let mut d2: *mut u8 = libc::strdup(p as *const i8) as *mut u8; + assert!(!((d2).is_null())); + assert!(((libc::strcmp((d2).cast_const() as *const i8, p as *const i8)) == (0))); + libc::free((d2 as *mut u8 as *mut ::libc::c_void)); + let mut d3: *mut u8 = libc::strdup((buf.as_mut_ptr()).cast_const() as *const i8) as *mut u8; + assert!(!((d3).is_null())); + assert!( + ((libc::strcmp( + (d3).cast_const() as *const i8, + (buf.as_mut_ptr()).cast_const() as *const i8 + )) == (0)) + ); + libc::free((d3 as *mut u8 as *mut ::libc::c_void)); +} +pub unsafe fn test_strcspn_11() { + assert!( + ((libc::strcspn( + b"hello\0".as_ptr() as *const i8, + b"el\0".as_ptr() as *const i8 + ) as u64) + == (1_u64)) + ); + assert!( + ((libc::strcspn( + b"abc\0".as_ptr() as *const i8, + b"xyz\0".as_ptr() as *const i8 + ) as u64) + == (3_u64)) + ); + assert!( + ((libc::strcspn(b"\0".as_ptr() as *const i8, b"abc\0".as_ptr() as *const i8) as u64) + == (0_u64)) + ); + let mut s: *const u8 = b"hello\0".as_ptr(); + let mut rej: *const u8 = b"el\0".as_ptr(); + assert!(((libc::strcspn(s as *const i8, rej as *const i8) as u64) == (1_u64))); +} +pub unsafe fn test_strspn_12() { + assert!( + ((libc::strspn( + b"hello\0".as_ptr() as *const i8, + b"hel\0".as_ptr() as *const i8 + ) as u64) + == (4_u64)) + ); + assert!( + ((libc::strspn( + b"abc\0".as_ptr() as *const i8, + b"xyz\0".as_ptr() as *const i8 + ) as u64) + == (0_u64)) + ); + assert!( + ((libc::strspn(b"aaa\0".as_ptr() as *const i8, b"a\0".as_ptr() as *const i8) as u64) + == (3_u64)) + ); + let mut s: *const u8 = b"hello\0".as_ptr(); + let mut acc: *const u8 = b"hel\0".as_ptr(); + assert!(((libc::strspn(s as *const i8, acc as *const i8) as u64) == (4_u64))); +} +pub unsafe fn test_strstr_13() { + let mut h: *const u8 = b"hello world\0".as_ptr(); + let mut r: *const u8 = + libc::strstr(h as *const i8, b"world\0".as_ptr() as *const i8) as *const u8; + assert!(!((r).is_null())); + assert!(((r) == (h.offset((6) as isize)))); + assert!((libc::strstr(h as *const i8, b"xyz\0".as_ptr() as *const i8) as *const u8).is_null()); + let mut buf: [u8; 6] = [ + ('h' as u8), + ('e' as u8), + ('l' as u8), + ('l' as u8), + ('o' as u8), + ('\0' as u8), + ]; + assert!( + ((libc::strstr(buf.as_mut_ptr() as *const i8, b"ll\0".as_ptr() as *const i8) as *mut u8) + == (&mut buf[(2) as usize] as *mut u8)) + ); +} +pub unsafe fn test_strpbrk_14() { + let mut s: *const u8 = b"hello world\0".as_ptr(); + let mut r: *const u8 = + libc::strpbrk(s as *const i8, b"wo\0".as_ptr() as *const i8) as *const u8; + assert!(!((r).is_null())); + assert!(((r) == (s.offset((4) as isize)))); + assert!((libc::strpbrk(s as *const i8, b"xyz\0".as_ptr() as *const i8) as *const u8).is_null()); + let mut buf: [u8; 4] = [('a' as u8), ('b' as u8), ('c' as u8), ('\0' as u8)]; + assert!( + ((libc::strpbrk(buf.as_mut_ptr() as *const i8, b"b\0".as_ptr() as *const i8) as *mut u8) + == (&mut buf[(1) as usize] as *mut u8)) + ); +} +pub unsafe fn test_strcasecmp_15() { + assert!( + ((libc::strcasecmp( + b"HELLO\0".as_ptr() as *const i8, + b"hello\0".as_ptr() as *const i8 + )) == (0)) + ); + assert!( + ((libc::strcasecmp( + b"abc\0".as_ptr() as *const i8, + b"abd\0".as_ptr() as *const i8 + )) < (0)) + ); + assert!( + ((libc::strcasecmp( + b"abd\0".as_ptr() as *const i8, + b"abc\0".as_ptr() as *const i8 + )) > (0)) + ); + let mut p: *const u8 = b"FOO\0".as_ptr(); + let mut q: *const u8 = b"foo\0".as_ptr(); + assert!(((libc::strcasecmp(p as *const i8, q as *const i8)) == (0))); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + (unsafe { test_memcpy_0() }); + (unsafe { test_memset_1() }); + (unsafe { test_memcmp_2() }); + (unsafe { test_memmove_3() }); + (unsafe { test_strchr_4() }); + (unsafe { test_strlen_5() }); + (unsafe { test_strcmp_6() }); + (unsafe { test_strncmp_7() }); + (unsafe { test_memchr_8() }); + (unsafe { test_strrchr_9() }); + (unsafe { test_strdup_10() }); + (unsafe { test_strcspn_11() }); + (unsafe { test_strspn_12() }); + (unsafe { test_strstr_13() }); + (unsafe { test_strpbrk_14() }); + (unsafe { test_strcasecmp_15() }); + return 0; +} diff --git a/tests/unit/out/unsafe/strchr_c.rs b/tests/unit/out/unsafe/strchr_c.rs deleted file mode 100644 index 0acaf4ad..00000000 --- a/tests/unit/out/unsafe/strchr_c.rs +++ /dev/null @@ -1,21 +0,0 @@ -extern crate libc; -use libc::*; -extern crate libcc2rs; -use libcc2rs::*; -use std::collections::BTreeMap; -use std::io::{Read, Seek, Write}; -use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; -use std::rc::Rc; -pub fn main() { - unsafe { - std::process::exit(main_0() as i32); - } -} -unsafe fn main_0() -> i32 { - let mut s: *const u8 = (b"hello world\0".as_ptr().cast_mut()).cast_const(); - let mut r: *const u8 = (libc::strchr(s as *const i8, ('w' as i32)) as *mut u8).cast_const(); - assert!((((!((r).is_null())) as i32) != 0)); - assert!((((((*r) as i32) == ('w' as i32)) as i32) != 0)); - assert!(((((libc::strchr(s as *const i8, ('z' as i32)) as *mut u8).is_null()) as i32) != 0)); - return 0; -} diff --git a/tests/unit/out/unsafe/strchr_cpp.rs b/tests/unit/out/unsafe/strchr_cpp.rs deleted file mode 100644 index 309f23e6..00000000 --- a/tests/unit/out/unsafe/strchr_cpp.rs +++ /dev/null @@ -1,21 +0,0 @@ -extern crate libc; -use libc::*; -extern crate libcc2rs; -use libcc2rs::*; -use std::collections::BTreeMap; -use std::io::{Read, Seek, Write}; -use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; -use std::rc::Rc; -pub fn main() { - unsafe { - std::process::exit(main_0() as i32); - } -} -unsafe fn main_0() -> i32 { - let mut s: *const u8 = b"hello world\0".as_ptr(); - let mut r: *const u8 = libc::strchr(s as *const i8, (('w' as u8) as i32)) as *const u8; - assert!(!((r).is_null())); - assert!((((*r) as i32) == (('w' as u8) as i32))); - assert!((libc::strchr(s as *const i8, (('z' as u8) as i32)) as *const u8).is_null()); - return 0; -} diff --git a/tests/unit/out/unsafe/string_h.rs b/tests/unit/out/unsafe/string_h.rs new file mode 100644 index 00000000..1efd2498 --- /dev/null +++ b/tests/unit/out/unsafe/string_h.rs @@ -0,0 +1,547 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub unsafe fn test_memcpy_0() { + let src: [u8; 6] = *b"hello\0"; + let mut dst: [u8; 6] = [0_u8, 0_u8, 0_u8, 0_u8, 0_u8, 0_u8]; + let mut r: *mut ::libc::c_void = { + if 6_u64 != 0 { + ::std::ptr::copy_nonoverlapping( + (src.as_ptr() as *const u8 as *const ::libc::c_void), + (dst.as_mut_ptr() as *mut u8 as *mut ::libc::c_void), + 6_u64 as usize, + ) + } + (dst.as_mut_ptr() as *mut u8 as *mut ::libc::c_void) + }; + assert!(((((r) == (dst.as_mut_ptr() as *mut u8 as *mut ::libc::c_void)) as i32) != 0)); + assert!( + ((((((((((dst[(0) as usize] as i32) == ('h' as i32)) as i32) != 0) + && ((((dst[(1) as usize] as i32) == ('e' as i32)) as i32) != 0)) as i32) + != 0) + && ((((dst[(2) as usize] as i32) == ('l' as i32)) as i32) != 0)) as i32) + != 0) + ); + assert!( + ((((((((((dst[(3) as usize] as i32) == ('l' as i32)) as i32) != 0) + && ((((dst[(4) as usize] as i32) == ('o' as i32)) as i32) != 0)) as i32) + != 0) + && ((((dst[(5) as usize] as i32) == ('\0' as i32)) as i32) != 0)) as i32) + != 0) + ); +} +pub unsafe fn test_memset_1() { + let mut buf: [u8; 4] = [0_u8; 4]; + let mut r: *mut ::libc::c_void = { + let byte_0 = (buf.as_mut_ptr() as *mut u8 as *mut ::libc::c_void) as *mut u8; + for offset in 0..4_u64 { + *byte_0.offset(offset as isize) = ('x' as i32) as u8; + } + (buf.as_mut_ptr() as *mut u8 as *mut ::libc::c_void) + }; + assert!(((((r) == (buf.as_mut_ptr() as *mut u8 as *mut ::libc::c_void)) as i32) != 0)); + assert!( + (((((((((((((buf[(0) as usize] as i32) == ('x' as i32)) as i32) != 0) + && ((((buf[(1) as usize] as i32) == ('x' as i32)) as i32) != 0)) + as i32) + != 0) + && ((((buf[(2) as usize] as i32) == ('x' as i32)) as i32) != 0)) as i32) + != 0) + && ((((buf[(3) as usize] as i32) == ('x' as i32)) as i32) != 0)) as i32) + != 0) + ); +} +pub unsafe fn test_memcmp_2() { + let a: [u8; 4] = [1_u8, 2_u8, 3_u8, 4_u8]; + let b: [u8; 4] = [1_u8, 2_u8, 3_u8, 4_u8]; + let c: [u8; 4] = [1_u8, 2_u8, 9_u8, 4_u8]; + assert!( + (((({ + let sa = core::slice::from_raw_parts( + (a.as_ptr() as *const u8 as *const ::libc::c_void) as *const u8, + 4_u64 as usize, + ); + let sb = core::slice::from_raw_parts( + (b.as_ptr() as *const u8 as *const ::libc::c_void) as *const u8, + 4_u64 as usize, + ); + let mut diff = 0_i32; + for (x, y) in sa.iter().zip(sb.iter()) { + if x != y { + diff = (*x as i32) - (*y as i32); + break; + } + } + diff + }) == (0)) as i32) + != 0) + ); + assert!( + (((({ + let sa = core::slice::from_raw_parts( + (a.as_ptr() as *const u8 as *const ::libc::c_void) as *const u8, + 4_u64 as usize, + ); + let sb = core::slice::from_raw_parts( + (c.as_ptr() as *const u8 as *const ::libc::c_void) as *const u8, + 4_u64 as usize, + ); + let mut diff = 0_i32; + for (x, y) in sa.iter().zip(sb.iter()) { + if x != y { + diff = (*x as i32) - (*y as i32); + break; + } + } + diff + }) < (0)) as i32) + != 0) + ); + assert!( + (((({ + let sa = core::slice::from_raw_parts( + (c.as_ptr() as *const u8 as *const ::libc::c_void) as *const u8, + 4_u64 as usize, + ); + let sb = core::slice::from_raw_parts( + (a.as_ptr() as *const u8 as *const ::libc::c_void) as *const u8, + 4_u64 as usize, + ); + let mut diff = 0_i32; + for (x, y) in sa.iter().zip(sb.iter()) { + if x != y { + diff = (*x as i32) - (*y as i32); + break; + } + } + diff + }) > (0)) as i32) + != 0) + ); +} +pub unsafe fn test_memmove_3() { + let mut buf: [u8; 6] = [ + (('a' as i32) as u8), + (('b' as i32) as u8), + (('c' as i32) as u8), + (('d' as i32) as u8), + (('e' as i32) as u8), + (('\0' as i32) as u8), + ]; + let mut r: *mut ::libc::c_void = { + if 4_u64 != 0 { + ::std::ptr::copy_nonoverlapping( + (buf.as_mut_ptr() as *const u8 as *const ::libc::c_void), + (buf.as_mut_ptr().offset((1) as isize) as *mut u8 as *mut ::libc::c_void), + 4_u64 as usize, + ) + } + (buf.as_mut_ptr().offset((1) as isize) as *mut u8 as *mut ::libc::c_void) + }; + assert!( + ((((r) == (buf.as_mut_ptr().offset((1) as isize) as *mut u8 as *mut ::libc::c_void)) + as i32) + != 0) + ); + assert!( + ((((((((((buf[(0) as usize] as i32) == ('a' as i32)) as i32) != 0) + && ((((buf[(1) as usize] as i32) == ('a' as i32)) as i32) != 0)) as i32) + != 0) + && ((((buf[(2) as usize] as i32) == ('b' as i32)) as i32) != 0)) as i32) + != 0) + ); + assert!( + ((((((((((buf[(3) as usize] as i32) == ('c' as i32)) as i32) != 0) + && ((((buf[(4) as usize] as i32) == ('d' as i32)) as i32) != 0)) as i32) + != 0) + && ((((buf[(5) as usize] as i32) == ('\0' as i32)) as i32) != 0)) as i32) + != 0) + ); +} +pub unsafe fn test_strchr_4() { + let mut s: *const u8 = (b"hello world\0".as_ptr().cast_mut()).cast_const(); + let mut r: *mut u8 = + libc::strchr((s as *mut u8).cast_const() as *const i8, ('w' as i32)) as *mut u8; + assert!((((!((r).is_null())) as i32) != 0)); + assert!((((((*r) as i32) == ('w' as i32)) as i32) != 0)); + assert!( + ((((libc::strchr((s as *mut u8).cast_const() as *const i8, ('z' as i32)) as *mut u8) + .is_null()) as i32) + != 0) + ); +} +pub unsafe fn test_strlen_5() { + assert!( + ((((libc::strlen((b"\0".as_ptr().cast_mut()).cast_const() as *const i8) as u64) == (0_u64)) + as i32) + != 0) + ); + assert!( + ((((libc::strlen((b"hello\0".as_ptr().cast_mut()).cast_const() as *const i8) as u64) + == (5_u64)) as i32) + != 0) + ); + assert!( + ((((libc::strlen((b"hello world\0".as_ptr().cast_mut()).cast_const() as *const i8) as u64) + == (11_u64)) as i32) + != 0) + ); +} +pub unsafe fn test_strcmp_6() { + assert!( + ((((libc::strcmp( + (b"abc\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"abc\0".as_ptr().cast_mut()).cast_const() as *const i8 + )) == (0)) as i32) + != 0) + ); + assert!( + ((((libc::strcmp( + (b"abc\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"abd\0".as_ptr().cast_mut()).cast_const() as *const i8 + )) < (0)) as i32) + != 0) + ); + assert!( + ((((libc::strcmp( + (b"abd\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"abc\0".as_ptr().cast_mut()).cast_const() as *const i8 + )) > (0)) as i32) + != 0) + ); + let mut p: *const u8 = (b"abc\0".as_ptr().cast_mut()).cast_const(); + let mut q: *const u8 = (b"abd\0".as_ptr().cast_mut()).cast_const(); + let mut buf: [u8; 4] = [ + (('a' as i32) as u8), + (('b' as i32) as u8), + (('c' as i32) as u8), + (('\0' as i32) as u8), + ]; + assert!(((((libc::strcmp(p as *const i8, p as *const i8)) == (0)) as i32) != 0)); + assert!(((((libc::strcmp(p as *const i8, q as *const i8)) < (0)) as i32) != 0)); + assert!( + ((((libc::strcmp((buf.as_mut_ptr()).cast_const() as *const i8, p as *const i8)) == (0)) + as i32) + != 0) + ); +} +pub unsafe fn test_strncmp_7() { + assert!( + ((((libc::strncmp( + (b"abcdef\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"abcxyz\0".as_ptr().cast_mut()).cast_const() as *const i8, + 3_u64 as usize + )) == (0)) as i32) + != 0) + ); + assert!( + ((((libc::strncmp( + (b"abcdef\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"abcxyz\0".as_ptr().cast_mut()).cast_const() as *const i8, + 4_u64 as usize + )) < (0)) as i32) + != 0) + ); + assert!( + ((((libc::strncmp( + (b"abcxyz\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"abcdef\0".as_ptr().cast_mut()).cast_const() as *const i8, + 4_u64 as usize + )) > (0)) as i32) + != 0) + ); + let mut p: *const u8 = (b"abcdef\0".as_ptr().cast_mut()).cast_const(); + let mut q: *const u8 = (b"abcxyz\0".as_ptr().cast_mut()).cast_const(); + let mut buf: [u8; 7] = [ + (('a' as i32) as u8), + (('b' as i32) as u8), + (('c' as i32) as u8), + (('d' as i32) as u8), + (('e' as i32) as u8), + (('f' as i32) as u8), + (('\0' as i32) as u8), + ]; + let mut n: u64 = 3_u64; + assert!(((((libc::strncmp(p as *const i8, q as *const i8, n as usize)) == (0)) as i32) != 0)); + assert!( + ((((libc::strncmp( + p as *const i8, + q as *const i8, + (n).wrapping_add(1_u64) as usize + )) < (0)) as i32) + != 0) + ); + assert!( + ((((libc::strncmp( + (buf.as_mut_ptr()).cast_const() as *const i8, + p as *const i8, + 6_u64 as usize + )) == (0)) as i32) + != 0) + ); +} +pub unsafe fn test_memchr_8() { + let data: [u8; 4] = [16_u8, 32_u8, 48_u8, 64_u8]; + let mut r: *mut ::libc::c_void = libc::memchr( + (data.as_ptr() as *const u8 as *const ::libc::c_void) as *const ::libc::c_void, + 48, + 4_u64 as usize, + ); + assert!( + ((((r) == ((&data[(2) as usize] as *const u8) as *mut u8 as *mut ::libc::c_void)) as i32) + != 0) + ); + assert!( + ((((libc::memchr( + (data.as_ptr() as *const u8 as *const ::libc::c_void) as *const ::libc::c_void, + 153, + 4_u64 as usize + )) + .is_null()) as i32) + != 0) + ); + let mut p: *const ::libc::c_void = (data.as_ptr() as *const u8 as *const ::libc::c_void); + let mut n: u64 = 4_u64; + assert!( + ((((libc::memchr(p as *const ::libc::c_void, 16, n as usize)) + == (p as *mut ::libc::c_void as *mut ::libc::c_void)) as i32) + != 0) + ); +} +pub unsafe fn test_strrchr_9() { + let mut s: *const u8 = (b"hello world\0".as_ptr().cast_mut()).cast_const(); + let mut r: *mut u8 = + libc::strrchr((s as *mut u8).cast_const() as *const i8, ('l' as i32)) as *mut u8; + assert!((((!((r).is_null())) as i32) != 0)); + assert!((((((*r) as i32) == ('l' as i32)) as i32) != 0)); + assert!(((((r) == (s.offset((9) as isize) as *mut u8)) as i32) != 0)); + assert!( + ((((libc::strrchr((s as *mut u8).cast_const() as *const i8, ('z' as i32)) as *mut u8) + .is_null()) as i32) + != 0) + ); + let mut buf: [u8; 4] = [ + (('a' as i32) as u8), + (('b' as i32) as u8), + (('a' as i32) as u8), + (('\0' as i32) as u8), + ]; + assert!( + ((((libc::strrchr((buf.as_mut_ptr()).cast_const() as *const i8, ('a' as i32)) as *mut u8) + == (&mut buf[(2) as usize] as *mut u8)) as i32) + != 0) + ); +} +pub unsafe fn test_strdup_10() { + let mut d: *mut u8 = + libc::strdup((b"hello\0".as_ptr().cast_mut()).cast_const() as *const i8) as *mut u8; + assert!((((!((d).is_null())) as i32) != 0)); + assert!( + ((((libc::strcmp( + (d).cast_const() as *const i8, + (b"hello\0".as_ptr().cast_mut()).cast_const() as *const i8 + )) == (0)) as i32) + != 0) + ); + libc::free((d as *mut u8 as *mut ::libc::c_void)); + let mut p: *const u8 = (b"world\0".as_ptr().cast_mut()).cast_const(); + let mut buf: [u8; 4] = [ + (('a' as i32) as u8), + (('b' as i32) as u8), + (('c' as i32) as u8), + (('\0' as i32) as u8), + ]; + let mut d2: *mut u8 = libc::strdup(p as *const i8) as *mut u8; + assert!((((!((d2).is_null())) as i32) != 0)); + assert!( + ((((libc::strcmp((d2).cast_const() as *const i8, p as *const i8)) == (0)) as i32) != 0) + ); + libc::free((d2 as *mut u8 as *mut ::libc::c_void)); + let mut d3: *mut u8 = libc::strdup((buf.as_mut_ptr()).cast_const() as *const i8) as *mut u8; + assert!((((!((d3).is_null())) as i32) != 0)); + assert!( + ((((libc::strcmp( + (d3).cast_const() as *const i8, + (buf.as_mut_ptr()).cast_const() as *const i8 + )) == (0)) as i32) + != 0) + ); + libc::free((d3 as *mut u8 as *mut ::libc::c_void)); +} +pub unsafe fn test_strcspn_11() { + assert!( + ((((libc::strcspn( + (b"hello\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"el\0".as_ptr().cast_mut()).cast_const() as *const i8 + ) as u64) + == (1_u64)) as i32) + != 0) + ); + assert!( + ((((libc::strcspn( + (b"abc\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"xyz\0".as_ptr().cast_mut()).cast_const() as *const i8 + ) as u64) + == (3_u64)) as i32) + != 0) + ); + assert!( + ((((libc::strcspn( + (b"\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"abc\0".as_ptr().cast_mut()).cast_const() as *const i8 + ) as u64) + == (0_u64)) as i32) + != 0) + ); + let mut s: *const u8 = (b"hello\0".as_ptr().cast_mut()).cast_const(); + let mut rej: *const u8 = (b"el\0".as_ptr().cast_mut()).cast_const(); + assert!(((((libc::strcspn(s as *const i8, rej as *const i8) as u64) == (1_u64)) as i32) != 0)); +} +pub unsafe fn test_strspn_12() { + assert!( + ((((libc::strspn( + (b"hello\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"hel\0".as_ptr().cast_mut()).cast_const() as *const i8 + ) as u64) + == (4_u64)) as i32) + != 0) + ); + assert!( + ((((libc::strspn( + (b"abc\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"xyz\0".as_ptr().cast_mut()).cast_const() as *const i8 + ) as u64) + == (0_u64)) as i32) + != 0) + ); + assert!( + ((((libc::strspn( + (b"aaa\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"a\0".as_ptr().cast_mut()).cast_const() as *const i8 + ) as u64) + == (3_u64)) as i32) + != 0) + ); + let mut s: *const u8 = (b"hello\0".as_ptr().cast_mut()).cast_const(); + let mut acc: *const u8 = (b"hel\0".as_ptr().cast_mut()).cast_const(); + assert!(((((libc::strspn(s as *const i8, acc as *const i8) as u64) == (4_u64)) as i32) != 0)); +} +pub unsafe fn test_strstr_13() { + let mut h: *const u8 = (b"hello world\0".as_ptr().cast_mut()).cast_const(); + let mut r: *mut u8 = libc::strstr( + (h as *mut u8).cast_const() as *const i8, + (b"world\0".as_ptr().cast_mut()).cast_const() as *const i8, + ) as *mut u8; + assert!((((!((r).is_null())) as i32) != 0)); + assert!(((((r) == (h.offset((6) as isize) as *mut u8)) as i32) != 0)); + assert!( + ((((libc::strstr( + (h as *mut u8).cast_const() as *const i8, + (b"xyz\0".as_ptr().cast_mut()).cast_const() as *const i8 + ) as *mut u8) + .is_null()) as i32) + != 0) + ); + let mut buf: [u8; 6] = [ + (('h' as i32) as u8), + (('e' as i32) as u8), + (('l' as i32) as u8), + (('l' as i32) as u8), + (('o' as i32) as u8), + (('\0' as i32) as u8), + ]; + assert!( + ((((libc::strstr( + (buf.as_mut_ptr()).cast_const() as *const i8, + (b"ll\0".as_ptr().cast_mut()).cast_const() as *const i8 + ) as *mut u8) + == (&mut buf[(2) as usize] as *mut u8)) as i32) + != 0) + ); +} +pub unsafe fn test_strpbrk_14() { + let mut s: *const u8 = (b"hello world\0".as_ptr().cast_mut()).cast_const(); + let mut r: *mut u8 = libc::strpbrk( + (s as *mut u8).cast_const() as *const i8, + (b"wo\0".as_ptr().cast_mut()).cast_const() as *const i8, + ) as *mut u8; + assert!((((!((r).is_null())) as i32) != 0)); + assert!(((((r) == (s.offset((4) as isize) as *mut u8)) as i32) != 0)); + assert!( + ((((libc::strpbrk( + (s as *mut u8).cast_const() as *const i8, + (b"xyz\0".as_ptr().cast_mut()).cast_const() as *const i8 + ) as *mut u8) + .is_null()) as i32) + != 0) + ); + let mut buf: [u8; 4] = [ + (('a' as i32) as u8), + (('b' as i32) as u8), + (('c' as i32) as u8), + (('\0' as i32) as u8), + ]; + assert!( + ((((libc::strpbrk( + (buf.as_mut_ptr()).cast_const() as *const i8, + (b"b\0".as_ptr().cast_mut()).cast_const() as *const i8 + ) as *mut u8) + == (&mut buf[(1) as usize] as *mut u8)) as i32) + != 0) + ); +} +pub unsafe fn test_strcasecmp_15() { + assert!( + ((((libc::strcasecmp( + (b"HELLO\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"hello\0".as_ptr().cast_mut()).cast_const() as *const i8 + )) == (0)) as i32) + != 0) + ); + assert!( + ((((libc::strcasecmp( + (b"abc\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"abd\0".as_ptr().cast_mut()).cast_const() as *const i8 + )) < (0)) as i32) + != 0) + ); + assert!( + ((((libc::strcasecmp( + (b"abd\0".as_ptr().cast_mut()).cast_const() as *const i8, + (b"abc\0".as_ptr().cast_mut()).cast_const() as *const i8 + )) > (0)) as i32) + != 0) + ); + let mut p: *const u8 = (b"FOO\0".as_ptr().cast_mut()).cast_const(); + let mut q: *const u8 = (b"foo\0".as_ptr().cast_mut()).cast_const(); + assert!(((((libc::strcasecmp(p as *const i8, q as *const i8)) == (0)) as i32) != 0)); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + (unsafe { test_memcpy_0() }); + (unsafe { test_memset_1() }); + (unsafe { test_memcmp_2() }); + (unsafe { test_memmove_3() }); + (unsafe { test_strchr_4() }); + (unsafe { test_strlen_5() }); + (unsafe { test_strcmp_6() }); + (unsafe { test_strncmp_7() }); + (unsafe { test_memchr_8() }); + (unsafe { test_strrchr_9() }); + (unsafe { test_strdup_10() }); + (unsafe { test_strcspn_11() }); + (unsafe { test_strspn_12() }); + (unsafe { test_strstr_13() }); + (unsafe { test_strpbrk_14() }); + (unsafe { test_strcasecmp_15() }); + return 0; +} diff --git a/tests/unit/strchr_c.c b/tests/unit/strchr_c.c deleted file mode 100644 index e0285064..00000000 --- a/tests/unit/strchr_c.c +++ /dev/null @@ -1,12 +0,0 @@ -// no-compile: refcount -#include -#include - -int main() { - const char *s = "hello world"; - const char *r = strchr(s, 'w'); - assert(r != NULL); - assert(*r == 'w'); - assert(strchr(s, 'z') == NULL); - return 0; -} diff --git a/tests/unit/strchr_cpp.cpp b/tests/unit/strchr_cpp.cpp deleted file mode 100644 index 4a9e5be5..00000000 --- a/tests/unit/strchr_cpp.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// no-compile: refcount -#include -#include - -int main() { - const char *s = "hello world"; - const char *r = strchr(s, 'w'); - assert(r != NULL); - assert(*r == 'w'); - assert(strchr(s, 'z') == NULL); - return 0; -} diff --git a/tests/unit/string_h.c b/tests/unit/string_h.c new file mode 100644 index 00000000..9202874d --- /dev/null +++ b/tests/unit/string_h.c @@ -0,0 +1,183 @@ +// no-compile: refcount +#define _GNU_SOURCE +#include +#include +#include +#include + +static void test_memcpy(void) { + const char src[] = "hello"; + char dst[6] = {0}; + void *r = memcpy(dst, src, 6); + assert(r == dst); + assert(dst[0] == 'h' && dst[1] == 'e' && dst[2] == 'l'); + assert(dst[3] == 'l' && dst[4] == 'o' && dst[5] == '\0'); +} + +static void test_memset(void) { + char buf[4]; + void *r = memset(buf, 'x', 4); + assert(r == buf); + assert(buf[0] == 'x' && buf[1] == 'x' && buf[2] == 'x' && buf[3] == 'x'); +} + +static void test_memcmp(void) { + const char a[] = {1, 2, 3, 4}; + const char b[] = {1, 2, 3, 4}; + const char c[] = {1, 2, 9, 4}; + assert(memcmp(a, b, 4) == 0); + assert(memcmp(a, c, 4) < 0); + assert(memcmp(c, a, 4) > 0); +} + +static void test_memmove(void) { + char buf[6] = {'a', 'b', 'c', 'd', 'e', '\0'}; + void *r = memmove(buf + 1, buf, 4); + assert(r == buf + 1); + assert(buf[0] == 'a' && buf[1] == 'a' && buf[2] == 'b'); + assert(buf[3] == 'c' && buf[4] == 'd' && buf[5] == '\0'); +} + +static void test_strchr(void) { + const char *s = "hello world"; + char *r = strchr((char *)s, 'w'); + assert(r != NULL); + assert(*r == 'w'); + assert(strchr((char *)s, 'z') == NULL); +} + +static void test_strlen(void) { + assert(strlen("") == 0); + assert(strlen("hello") == 5); + assert(strlen("hello world") == 11); +} + +static void test_strcmp(void) { + assert(strcmp("abc", "abc") == 0); + assert(strcmp("abc", "abd") < 0); + assert(strcmp("abd", "abc") > 0); + const char *p = "abc"; + const char *q = "abd"; + char buf[] = {'a', 'b', 'c', '\0'}; + assert(strcmp(p, p) == 0); + assert(strcmp(p, q) < 0); + assert(strcmp(buf, p) == 0); +} + +static void test_strncmp(void) { + assert(strncmp("abcdef", "abcxyz", 3) == 0); + assert(strncmp("abcdef", "abcxyz", 4) < 0); + assert(strncmp("abcxyz", "abcdef", 4) > 0); + const char *p = "abcdef"; + const char *q = "abcxyz"; + char buf[] = {'a', 'b', 'c', 'd', 'e', 'f', '\0'}; + size_t n = 3; + assert(strncmp(p, q, n) == 0); + assert(strncmp(p, q, n + 1) < 0); + assert(strncmp(buf, p, 6) == 0); +} + +static void test_memchr(void) { + const char data[] = {0x10, 0x20, 0x30, 0x40}; + void *r = memchr(data, 0x30, 4); + assert(r == &data[2]); + assert(memchr(data, 0x99, 4) == NULL); + const void *p = data; + size_t n = 4; + assert(memchr(p, 0x10, n) == p); +} + +static void test_strrchr(void) { + const char *s = "hello world"; + char *r = strrchr((char *)s, 'l'); + assert(r != NULL); + assert(*r == 'l'); + assert(r == s + 9); + assert(strrchr((char *)s, 'z') == NULL); + char buf[] = {'a', 'b', 'a', '\0'}; + assert(strrchr(buf, 'a') == &buf[2]); +} + +static void test_strdup(void) { + char *d = strdup("hello"); + assert(d != NULL); + assert(strcmp(d, "hello") == 0); + free(d); + const char *p = "world"; + char buf[] = {'a', 'b', 'c', '\0'}; + char *d2 = strdup(p); + assert(d2 != NULL); + assert(strcmp(d2, p) == 0); + free(d2); + char *d3 = strdup(buf); + assert(d3 != NULL); + assert(strcmp(d3, buf) == 0); + free(d3); +} + +static void test_strcspn(void) { + assert(strcspn("hello", "el") == 1); + assert(strcspn("abc", "xyz") == 3); + assert(strcspn("", "abc") == 0); + const char *s = "hello"; + const char *rej = "el"; + assert(strcspn(s, rej) == 1); +} + +static void test_strspn(void) { + assert(strspn("hello", "hel") == 4); + assert(strspn("abc", "xyz") == 0); + assert(strspn("aaa", "a") == 3); + const char *s = "hello"; + const char *acc = "hel"; + assert(strspn(s, acc) == 4); +} + +static void test_strstr(void) { + const char *h = "hello world"; + char *r = strstr((char *)h, "world"); + assert(r != NULL); + assert(r == h + 6); + assert(strstr((char *)h, "xyz") == NULL); + char buf[] = {'h', 'e', 'l', 'l', 'o', '\0'}; + assert(strstr(buf, "ll") == &buf[2]); +} + +static void test_strpbrk(void) { + const char *s = "hello world"; + char *r = strpbrk((char *)s, "wo"); + assert(r != NULL); + assert(r == s + 4); + assert(strpbrk((char *)s, "xyz") == NULL); + char buf[] = {'a', 'b', 'c', '\0'}; + assert(strpbrk(buf, "b") == &buf[1]); +} + +static void test_strcasecmp(void) { + assert(strcasecmp("HELLO", "hello") == 0); + assert(strcasecmp("abc", "abd") < 0); + assert(strcasecmp("abd", "abc") > 0); + const char *p = "FOO"; + const char *q = "foo"; + assert(strcasecmp(p, q) == 0); +} + +int main(void) { + test_memcpy(); + test_memset(); + test_memcmp(); + test_memmove(); + test_strchr(); + test_strlen(); + test_strcmp(); + test_strncmp(); + test_memchr(); + test_strrchr(); + test_strdup(); + test_strcspn(); + test_strspn(); + test_strstr(); + test_strpbrk(); + test_strcasecmp(); + return 0; +}