Skip to content

Commit 66e0cb3

Browse files
committed
add rcutils_strncasecmp with test.
Signed-off-by: Tomoya.Fujita <[email protected]>
1 parent 5a6a26c commit 66e0cb3

File tree

4 files changed

+97
-3
lines changed

4 files changed

+97
-3
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ set(rcutils_sources
6464
src/repl_str.c
6565
src/shared_library.c
6666
src/snprintf.c
67-
src/strcasecmp.c
6867
src/split.c
68+
src/strcasecmp.c
6969
src/strdup.c
7070
src/strerror.c
7171
src/string_array.c

include/rcutils/strcasecmp.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@ extern "C"
2020
{
2121
#endif
2222

23-
#include <string.h>
24-
2523
#include "rcutils/macros.h"
2624
#include "rcutils/visibility_control.h"
2725

@@ -42,6 +40,25 @@ RCUTILS_WARN_UNUSED
4240
int
4341
rcutils_strcasecmp(const char * s1, const char * s2);
4442

43+
/// Case insensitive string compare up to count characters.
44+
/**
45+
* This function compares two strings ignoring case which just wraps strncasecmp()
46+
* or strnicmp() in a portable way. This performs a byte-by-byte comparison of the
47+
* strings s1 and s2 up to count characters of s1 and s2, ignoring the case of the
48+
* characters.
49+
*
50+
* \param[in] s1 String with null terminated to compare.
51+
* \param[in] s2 String with null terminated to compare.
52+
* \param[in] n Count characters to compare.
53+
* \return An integer less than, equal to, or greater than zero if s1 is, after
54+
* ignoring case, found to be less than, to match, or be greater than s2,
55+
* respectively.
56+
*/
57+
RCUTILS_PUBLIC
58+
RCUTILS_WARN_UNUSED
59+
int
60+
rcutils_strncasecmp(const char * s1, const char * s2, size_t n);
61+
4562
#ifdef __cplusplus
4663
}
4764
#endif

src/strcasecmp.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,43 @@ extern "C"
1717
{
1818
#endif
1919

20+
#include <errno.h>
21+
#include <string.h>
22+
2023
#include "rcutils/strcasecmp.h"
2124

2225
int
2326
rcutils_strcasecmp(const char * s1, const char * s2)
2427
{
28+
RCUTILS_CAN_FAIL_WITH({errno = EINVAL; return -1;});
29+
30+
if (s1 == NULL || s2 == NULL) {
31+
errno = EINVAL;
32+
return -1;
33+
}
2534
#ifndef _WIN32
2635
return strcasecmp(s1, s2);
2736
#else
2837
return stricmp(s1, s2);
2938
#endif
3039
}
3140

41+
int
42+
rcutils_strncasecmp(const char * s1, const char * s2, size_t n)
43+
{
44+
RCUTILS_CAN_FAIL_WITH({errno = EINVAL; return -1;});
45+
46+
if (s1 == NULL || s2 == NULL) {
47+
errno = EINVAL;
48+
return -1;
49+
}
50+
#ifndef _WIN32
51+
return strncasecmp(s1, s2, n);
52+
#else
53+
return strnicmp(s1, s2, n);
54+
#endif
55+
}
56+
3257
#ifdef __cplusplus
3358
}
3459
#endif

test/test_strcasecmp.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818

1919
// Tests the rcutils_strcasecmp() function.
2020
TEST(TestStrcasecmp, test_strcasecmp) {
21+
EXPECT_EQ(-1, rcutils_strcasecmp(NULL, NULL));
22+
EXPECT_EQ(-1, rcutils_strcasecmp(NULL, ""));
23+
EXPECT_EQ(-1, rcutils_strcasecmp("", NULL));
24+
2125
EXPECT_EQ(0, rcutils_strcasecmp("", ""));
2226
EXPECT_EQ(0, rcutils_strcasecmp("abc", "abc"));
2327
EXPECT_EQ(0, rcutils_strcasecmp("ABC", "ABC"));
@@ -56,3 +60,51 @@ TEST(TestStrcasecmp, test_strcasecmp) {
5660
EXPECT_NE(0, rcutils_strcasecmp("ab1C", "abc"));
5761
EXPECT_NE(0, rcutils_strcasecmp("abc", "ab1C"));
5862
}
63+
64+
// Tests the rcutils_strncasecmp() function.
65+
TEST(TestStrcasecmp, test_strncasecmp) {
66+
EXPECT_EQ(-1, rcutils_strncasecmp(NULL, NULL, 0));
67+
EXPECT_EQ(-1, rcutils_strncasecmp(NULL, "", 1));
68+
EXPECT_EQ(-1, rcutils_strncasecmp("", NULL, 1));
69+
70+
EXPECT_EQ(0, rcutils_strncasecmp("", "", 0));
71+
EXPECT_EQ(0, rcutils_strncasecmp("", "", 1));
72+
EXPECT_EQ(0, rcutils_strncasecmp("abc", "", 0));
73+
EXPECT_EQ(0, rcutils_strncasecmp("", "abc", 0));
74+
EXPECT_EQ(0, rcutils_strncasecmp("abc", "abc", 3));
75+
EXPECT_EQ(0, rcutils_strncasecmp("ABC", "ABC", 3));
76+
EXPECT_EQ(0, rcutils_strncasecmp("1abc", "1abc", 4));
77+
EXPECT_EQ(0, rcutils_strncasecmp("abc1", "abc1", 4));
78+
EXPECT_EQ(0, rcutils_strncasecmp("1ABC", "1ABC", 4));
79+
EXPECT_EQ(0, rcutils_strncasecmp("ABC1", "ABC1", 4));
80+
EXPECT_EQ(0, rcutils_strncasecmp("ABC", "abc", 1));
81+
EXPECT_EQ(0, rcutils_strncasecmp("abc", "ABC", 1));
82+
EXPECT_EQ(0, rcutils_strncasecmp("Abc", "abc", 2));
83+
EXPECT_EQ(0, rcutils_strncasecmp("abc", "Abc", 2));
84+
EXPECT_EQ(0, rcutils_strncasecmp("Abc", "Abc", 2));
85+
EXPECT_EQ(0, rcutils_strncasecmp("aBc", "abc", 3));
86+
EXPECT_EQ(0, rcutils_strncasecmp("abc", "aBc", 3));
87+
EXPECT_EQ(0, rcutils_strncasecmp("aBc", "aBc", 3));
88+
EXPECT_EQ(0, rcutils_strncasecmp("abC", "abc", 4));
89+
EXPECT_EQ(0, rcutils_strncasecmp("abc", "abC", 4));
90+
EXPECT_EQ(0, rcutils_strncasecmp("abC", "abC", 4));
91+
92+
EXPECT_NE(0, rcutils_strncasecmp("", "abc", 1));
93+
EXPECT_NE(0, rcutils_strncasecmp("abc", "", 1));
94+
EXPECT_NE(0, rcutils_strncasecmp("abcd", "abc", 4));
95+
EXPECT_NE(0, rcutils_strncasecmp("abc", "abcd", 4));
96+
EXPECT_NE(0, rcutils_strncasecmp("abcD", "abc", 4));
97+
EXPECT_NE(0, rcutils_strncasecmp("abc", "abcD", 4));
98+
EXPECT_NE(0, rcutils_strncasecmp("1abc", "abc", 4));
99+
EXPECT_NE(0, rcutils_strncasecmp("abc", "1abc", 4));
100+
EXPECT_NE(0, rcutils_strncasecmp("abc1", "abc", 4));
101+
EXPECT_NE(0, rcutils_strncasecmp("abc", "abc1", 4));
102+
EXPECT_NE(0, rcutils_strncasecmp("ABCd", "abc", 4));
103+
EXPECT_NE(0, rcutils_strncasecmp("abc", "ABCd", 4));
104+
EXPECT_NE(0, rcutils_strncasecmp("1Abc", "abc", 4));
105+
EXPECT_NE(0, rcutils_strncasecmp("abc", "1Abc", 4));
106+
EXPECT_NE(0, rcutils_strncasecmp("a1Bc", "abc", 4));
107+
EXPECT_NE(0, rcutils_strncasecmp("abc", "a1Bc", 4));
108+
EXPECT_NE(0, rcutils_strncasecmp("ab1C", "abc", 4));
109+
EXPECT_NE(0, rcutils_strncasecmp("abc", "ab1C", 4));
110+
}

0 commit comments

Comments
 (0)