1 //===-- Unittests for strtok_r -------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "src/string/strtok_r.h"
10 #include "test/UnitTest/Test.h"
12 TEST(LlvmLibcStrTokReentrantTest
, NoTokenFound
) {
13 { // Empty source and delimiter string.
15 char *reserve
= nullptr;
16 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(empty
, "", &reserve
), nullptr);
17 // Another call to ensure that 'reserve' is not in a bad state.
18 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(empty
, "", &reserve
), nullptr);
19 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(nullptr, "", &reserve
), nullptr);
21 { // Empty source and single character delimiter string.
23 char *reserve
= nullptr;
24 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(empty
, "_", &reserve
), nullptr);
25 // Another call to ensure that 'reserve' is not in a bad state.
26 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(empty
, "_", &reserve
), nullptr);
27 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(nullptr, "_", &reserve
), nullptr);
29 { // Same character source and delimiter string.
31 char *reserve
= nullptr;
32 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(single
, "_", &reserve
), nullptr);
33 // Another call to ensure that 'reserve' is not in a bad state.
34 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(single
, "_", &reserve
), nullptr);
35 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(nullptr, "_", &reserve
), nullptr);
37 { // Multiple character source and single character delimiter string.
38 char multiple
[] = "1,2";
39 char *reserve
= nullptr;
40 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(multiple
, ":", &reserve
), "1,2");
41 // Another call to ensure that 'reserve' is not in a bad state.
42 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(multiple
, ":", &reserve
), "1,2");
43 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(nullptr, ":", &reserve
), nullptr);
47 TEST(LlvmLibcStrTokReentrantTest
, DelimiterAsFirstCharacterShouldBeIgnored
) {
49 char *reserve
= nullptr;
50 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(src
, ".", &reserve
), "123");
51 // Another call to ensure that 'reserve' is not in a bad state.
52 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(src
, ".", &reserve
), "123");
53 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(nullptr, ".", &reserve
), nullptr);
56 TEST(LlvmLibcStrTokReentrantTest
, DelimiterIsMiddleCharacter
) {
58 char *reserve
= nullptr;
59 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(src
, ",", &reserve
), "12");
60 // Another call to ensure that 'reserve' is not in a bad state.
61 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(src
, ",", &reserve
), "12");
62 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(nullptr, ",", &reserve
), nullptr);
65 TEST(LlvmLibcStrTokReentrantTest
, DelimiterAsLastCharacterShouldBeIgnored
) {
67 char *reserve
= nullptr;
68 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(src
, ":", &reserve
), "1234");
69 // Another call to ensure that 'reserve' is not in a bad state.
70 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(src
, ":", &reserve
), "1234");
71 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(nullptr, ":", &reserve
), nullptr);
74 TEST(LlvmLibcStrTokReentrantTest
, ShouldNotGoPastNullTerminator
) {
75 char src
[] = {'1', '2', '\0', ',', '3'};
76 char *reserve
= nullptr;
77 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(src
, ",", &reserve
), "12");
78 // Another call to ensure that 'reserve' is not in a bad state.
79 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(src
, ",", &reserve
), "12");
80 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(nullptr, ",", &reserve
), nullptr);
83 TEST(LlvmLibcStrTokReentrantTest
,
84 ShouldReturnNullptrWhenBothSrcAndSaveptrAreNull
) {
86 char *reserve
= nullptr;
87 // Ensure that instead of crashing if src and reserve are null, nullptr is
89 ASSERT_STREQ(LIBC_NAMESPACE::strtok_r(src
, ",", &reserve
), nullptr);
90 // And that neither src nor reserve are changed when that happens
91 ASSERT_STREQ(src
, nullptr);
92 ASSERT_STREQ(reserve
, nullptr);
95 TEST(LlvmLibcStrTokReentrantTest
,
96 SubsequentCallsShouldFindFollowingDelimiters
) {
97 char src
[] = "12,34.56";
98 char *reserve
= nullptr;
99 char *token
= LIBC_NAMESPACE::strtok_r(src
, ",.", &reserve
);
100 ASSERT_STREQ(token
, "12");
101 token
= LIBC_NAMESPACE::strtok_r(nullptr, ",.", &reserve
);
102 ASSERT_STREQ(token
, "34");
103 token
= LIBC_NAMESPACE::strtok_r(nullptr, ",.", &reserve
);
104 ASSERT_STREQ(token
, "56");
105 token
= LIBC_NAMESPACE::strtok_r(nullptr, "_:,_", &reserve
);
106 ASSERT_STREQ(token
, nullptr);
107 // Subsequent calls after hitting the end of the string should also return
109 token
= LIBC_NAMESPACE::strtok_r(nullptr, "_:,_", &reserve
);
110 ASSERT_STREQ(token
, nullptr);
113 TEST(LlvmLibcStrTokReentrantTest
, DelimitersShouldNotBeIncludedInToken
) {
114 char src
[] = "__ab__:_cd__:__ef__:__";
115 char *reserve
= nullptr;
116 char *token
= LIBC_NAMESPACE::strtok_r(src
, "_:", &reserve
);
117 ASSERT_STREQ(token
, "ab");
118 token
= LIBC_NAMESPACE::strtok_r(nullptr, ":_", &reserve
);
119 ASSERT_STREQ(token
, "cd");
120 token
= LIBC_NAMESPACE::strtok_r(nullptr, "_:,", &reserve
);
121 ASSERT_STREQ(token
, "ef");
122 token
= LIBC_NAMESPACE::strtok_r(nullptr, "_:,_", &reserve
);
123 ASSERT_STREQ(token
, nullptr);