libc.src.string.memset
libc.src.string.stpcpy
libc.src.string.stpncpy
+ libc.src.string.strcasecmp
libc.src.string.strcat
libc.src.string.strchr
libc.src.string.strcmp
libc.src.string.strlcat
libc.src.string.strlcpy
libc.src.string.strlen
+ libc.src.string.strncasecmp
libc.src.string.strncat
libc.src.string.strncmp
libc.src.string.strncpy
libc.src.string.memset
libc.src.string.stpcpy
libc.src.string.stpncpy
+ libc.src.string.strcasecmp
libc.src.string.strcat
libc.src.string.strchr
libc.src.string.strcmp
libc.src.string.strlcat
libc.src.string.strlcpy
libc.src.string.strlen
+ libc.src.string.strncasecmp
libc.src.string.strncat
libc.src.string.strncmp
libc.src.string.strncpy
libc.src.string.memset
libc.src.string.stpcpy
libc.src.string.stpncpy
+ libc.src.string.strcasecmp
libc.src.string.strcat
libc.src.string.strchr
libc.src.string.strcmp
libc.src.string.strlcat
libc.src.string.strlcpy
libc.src.string.strlen
+ libc.src.string.strncasecmp
libc.src.string.strncat
libc.src.string.strncmp
libc.src.string.strncpy
libc.src.string.memset
libc.src.string.stpcpy
libc.src.string.stpncpy
+ libc.src.string.strcasecmp
libc.src.string.strcat
libc.src.string.strchr
libc.src.string.strcmp
libc.src.string.strlcat
libc.src.string.strlcpy
libc.src.string.strlen
+ libc.src.string.strncasecmp
libc.src.string.strncat
libc.src.string.strncmp
libc.src.string.strncpy
libc.src.string.memset
libc.src.string.stpcpy
libc.src.string.stpncpy
+ libc.src.string.strcasecmp
libc.src.string.strcat
libc.src.string.strchr
libc.src.string.strcmp
libc.src.string.strlcat
libc.src.string.strlcpy
libc.src.string.strlen
+ libc.src.string.strncasecmp
libc.src.string.strncat
libc.src.string.strncmp
libc.src.string.strncpy
libc.src.string.memset
libc.src.string.stpcpy
libc.src.string.stpncpy
+ libc.src.string.strcasecmp
libc.src.string.strcat
libc.src.string.strchr
libc.src.string.strcmp
libc.src.string.strlcat
libc.src.string.strlcpy
libc.src.string.strlen
+ libc.src.string.strncasecmp
libc.src.string.strncat
libc.src.string.strncmp
libc.src.string.strncpy
libc.src.string.memset
libc.src.string.stpcpy
libc.src.string.stpncpy
+ libc.src.string.strcasecmp
libc.src.string.strcat
libc.src.string.strchr
libc.src.string.strcmp
libc.src.string.strlcat
libc.src.string.strlcpy
libc.src.string.strlen
+ libc.src.string.strncasecmp
libc.src.string.strncat
libc.src.string.strncmp
libc.src.string.strncpy
]
>;
+ HeaderSpec Strings = HeaderSpec<
+ "strings.h",
+ [], // Macros
+ [], // Types
+ [], // Enumerations
+ [
+ FunctionSpec<
+ "strcasecmp",
+ RetValSpec<IntType>,
+ [ArgSpec<ConstCharPtr>, ArgSpec<ConstCharPtr>]
+ >,
+ FunctionSpec<
+ "strncasecmp",
+ RetValSpec<IntType>,
+ [ArgSpec<ConstCharPtr>, ArgSpec<ConstCharPtr>, ArgSpec<SizeTType>]
+ >,
+ ]
+ >;
+
HeaderSpec SysWait = HeaderSpec<
"sys/wait.h",
[], // Macros
let Headers = [
String,
+ Strings,
SysWait,
];
}
return ch == ' ' || (ch - '\t') < 5;
}
+static constexpr int tolower(int ch) {
+ if (isupper(ch))
+ return ch + ('a' - 'A');
+ return ch;
+}
+
} // namespace internal
} // namespace __llvm_libc
// TODO: Currently restricted to default locale.
// These should be extended using locale information.
-LLVM_LIBC_FUNCTION(int, tolower, (int c)) {
- if (internal::isupper(c))
- return c + ('a' - 'A');
- return c;
-}
+LLVM_LIBC_FUNCTION(int, tolower, (int c)) { return internal::tolower(c); }
} // namespace __llvm_libc
)
add_entrypoint_object(
+ strcasecmp
+ SRCS
+ strcasecmp.cpp
+ HDRS
+ strcasecmp.h
+ DEPENDS
+ .memory_utils.strcmp_implementation
+ libc.src.__support.ctype_utils
+)
+
+add_entrypoint_object(
strcoll
SRCS
strcoll.cpp
)
add_entrypoint_object(
+ strncasecmp
+ SRCS
+ strncasecmp.cpp
+ HDRS
+ strncasecmp.h
+ DEPENDS
+ .memory_utils.strcmp_implementation
+ libc.src.__support.ctype_utils
+)
+
+add_entrypoint_object(
strncpy
SRCS
strncpy.cpp
--- /dev/null
+//===-- Implementation of strcasecmp --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/string/strcasecmp.h"
+
+#include "src/__support/common.h"
+#include "src/__support/ctype_utils.h"
+#include "src/string/memory_utils/strcmp_implementations.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, strcasecmp, (const char *left, const char *right)) {
+ auto case_cmp = [](char a, char b) {
+ return __llvm_libc::internal::tolower(a) -
+ __llvm_libc::internal::tolower(b);
+ };
+ return strcmp_implementation(left, right, case_cmp);
+}
+
+} // namespace __llvm_libc
--- /dev/null
+//===-- Implementation header for strcasecmp --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STRING_STRCASECMP_H
+#define LLVM_LIBC_SRC_STRING_STRCASECMP_H
+
+namespace __llvm_libc {
+
+int strcasecmp(const char *left, const char *right);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STRING_STRCASECMP_H
--- /dev/null
+//===-- Implementation of strncasecmp -------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/string/strncasecmp.h"
+
+#include "src/__support/common.h"
+#include "src/__support/ctype_utils.h"
+#include "src/string/memory_utils/strcmp_implementations.h"
+
+namespace __llvm_libc {
+
+LLVM_LIBC_FUNCTION(int, strncasecmp,
+ (const char *left, const char *right, size_t n)) {
+ auto case_cmp = [](char a, char b) {
+ return __llvm_libc::internal::tolower(a) -
+ __llvm_libc::internal::tolower(b);
+ };
+ return strncmp_implementation(left, right, n, case_cmp);
+}
+
+} // namespace __llvm_libc
--- /dev/null
+//===-- Implementation header for strcasecmp --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STRING_STRCASECMP_H
+#define LLVM_LIBC_SRC_STRING_STRCASECMP_H
+
+#include <stddef.h>
+
+namespace __llvm_libc {
+
+int strncasecmp(const char *left, const char *right, size_t n);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STRING_STRCASECMP_H
)
add_libc_unittest(
+ strcasecmp_test
+ SUITE
+ libc_string_unittests
+ SRCS
+ strcasecmp_test.cpp
+ DEPENDS
+ libc.src.string.strcasecmp
+)
+
+add_libc_unittest(
strcoll_test
SUITE
libc_string_unittests
)
add_libc_unittest(
+ strncasecmp_test
+ SUITE
+ libc_string_unittests
+ SRCS
+ strncasecmp_test.cpp
+ DEPENDS
+ libc.src.string.strncasecmp
+)
+
+add_libc_unittest(
strncpy_test
SUITE
libc_string_unittests
--- /dev/null
+//===-- Unittests for strcasecmp ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/string/strcasecmp.h"
+#include "utils/UnitTest/Test.h"
+
+TEST(LlvmLibcStrCaseCmpTest, EmptyStringsShouldReturnZero) {
+ const char *s1 = "";
+ const char *s2 = "";
+ int result = __llvm_libc::strcasecmp(s1, s2);
+ ASSERT_EQ(result, 0);
+
+ // Verify operands reversed.
+ result = __llvm_libc::strcasecmp(s2, s1);
+ ASSERT_EQ(result, 0);
+}
+
+TEST(LlvmLibcStrCaseCmpTest, EmptyStringShouldNotEqualNonEmptyString) {
+ const char *empty = "";
+ const char *s2 = "abc";
+ int result = __llvm_libc::strcasecmp(empty, s2);
+ // This should be '\0' - 'a' = -97
+ ASSERT_LT(result, 0);
+
+ // Similar case if empty string is second argument.
+ const char *s3 = "123";
+ result = __llvm_libc::strcasecmp(s3, empty);
+ // This should be '1' - '\0' = 49
+ ASSERT_GT(result, 0);
+}
+
+TEST(LlvmLibcStrCaseCmpTest, Case) {
+ const char *s1 = "aB";
+ const char *s2 = "ab";
+ int result = __llvm_libc::strcasecmp(s1, s2);
+ ASSERT_EQ(result, 0);
+
+ // Verify operands reversed.
+ result = __llvm_libc::strcasecmp(s2, s1);
+ ASSERT_EQ(result, 0);
+}
// 'a' - 'b' = -1.
ASSERT_EQ(result, -1);
}
+
+TEST(LlvmLibcStrCmpTest, Case) {
+ const char *s1 = "aB";
+ const char *s2 = "ab";
+ int result = __llvm_libc::strcmp(s1, s2);
+ ASSERT_LT(result, 0);
+
+ // Verify operands reversed.
+ result = __llvm_libc::strcmp(s2, s1);
+ ASSERT_GT(result, 0);
+}
--- /dev/null
+//===-- Unittests for strncasecmp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/string/strncasecmp.h"
+#include "utils/UnitTest/Test.h"
+
+TEST(LlvmLibcStrNCaseCmpTest,
+ EmptyStringsShouldReturnZeroWithSufficientLength) {
+ const char *s1 = "";
+ const char *s2 = "";
+ int result = __llvm_libc::strncasecmp(s1, s2, 1);
+ ASSERT_EQ(result, 0);
+
+ // Verify operands reversed.
+ result = __llvm_libc::strncasecmp(s2, s1, 1);
+ ASSERT_EQ(result, 0);
+}
+
+TEST(LlvmLibcStrNCaseCmpTest,
+ EmptyStringShouldNotEqualNonEmptyStringWithSufficientLength) {
+ const char *empty = "";
+ const char *s2 = "abc";
+ int result = __llvm_libc::strncasecmp(empty, s2, 3);
+ // This should be '\0' - 'a' = -97
+ ASSERT_LT(result, 0);
+
+ // Similar case if empty string is second argument.
+ const char *s3 = "123";
+ result = __llvm_libc::strncasecmp(s3, empty, 3);
+ // This should be '1' - '\0' = 49
+ ASSERT_GT(result, 0);
+}
+
+TEST(LlvmLibcStrNCaseCmpTest, Case) {
+ const char *s1 = "aB";
+ const char *s2 = "ab";
+ int result = __llvm_libc::strncasecmp(s1, s2, 2);
+ ASSERT_EQ(result, 0);
+
+ // Verify operands reversed.
+ result = __llvm_libc::strncasecmp(s2, s1, 2);
+ ASSERT_EQ(result, 0);
+}
result = __llvm_libc::strncmp(s2, s1, 7);
ASSERT_EQ(result, 0);
}
+
+TEST(LlvmLibcStrNCmpTest, Case) {
+ const char *s1 = "aB";
+ const char *s2 = "ab";
+ int result = __llvm_libc::strncmp(s1, s2, 2);
+ ASSERT_LT(result, 0);
+
+ // Verify operands reversed.
+ result = __llvm_libc::strncmp(s2, s1, 2);
+ ASSERT_GT(result, 0);
+}