1 //===-- Unittests for strtok_r -------------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "src/string/strtok_r.h"
10 #include "utils/UnitTest/Test.h"
11
TEST(StrTokReentrantTest,NoTokenFound)12 TEST(StrTokReentrantTest, NoTokenFound) {
13 { // Empty source and delimiter string.
14 char empty[] = "";
15 char *reserve = nullptr;
16 ASSERT_STREQ(__llvm_libc::strtok_r(empty, "", &reserve), nullptr);
17 // Another call to ensure that 'reserve' is not in a bad state.
18 ASSERT_STREQ(__llvm_libc::strtok_r(empty, "", &reserve), nullptr);
19 ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, "", &reserve), nullptr);
20 }
21 { // Empty source and single character delimiter string.
22 char empty[] = "";
23 char *reserve = nullptr;
24 ASSERT_STREQ(__llvm_libc::strtok_r(empty, "_", &reserve), nullptr);
25 // Another call to ensure that 'reserve' is not in a bad state.
26 ASSERT_STREQ(__llvm_libc::strtok_r(empty, "_", &reserve), nullptr);
27 ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, "_", &reserve), nullptr);
28 }
29 { // Same character source and delimiter string.
30 char single[] = "_";
31 char *reserve = nullptr;
32 ASSERT_STREQ(__llvm_libc::strtok_r(single, "_", &reserve), nullptr);
33 // Another call to ensure that 'reserve' is not in a bad state.
34 ASSERT_STREQ(__llvm_libc::strtok_r(single, "_", &reserve), nullptr);
35 ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, "_", &reserve), nullptr);
36 }
37 { // Multiple character source and single character delimiter string.
38 char multiple[] = "1,2";
39 char *reserve = nullptr;
40 ASSERT_STREQ(__llvm_libc::strtok_r(multiple, ":", &reserve), "1,2");
41 // Another call to ensure that 'reserve' is not in a bad state.
42 ASSERT_STREQ(__llvm_libc::strtok_r(multiple, ":", &reserve), "1,2");
43 ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, ":", &reserve), nullptr);
44 }
45 }
46
TEST(StrTokReentrantTest,DelimiterAsFirstCharacterShouldBeIgnored)47 TEST(StrTokReentrantTest, DelimiterAsFirstCharacterShouldBeIgnored) {
48 char src[] = ".123";
49 char *reserve = nullptr;
50 ASSERT_STREQ(__llvm_libc::strtok_r(src, ".", &reserve), "123");
51 // Another call to ensure that 'reserve' is not in a bad state.
52 ASSERT_STREQ(__llvm_libc::strtok_r(src, ".", &reserve), "123");
53 ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, ".", &reserve), nullptr);
54 }
55
TEST(StrTokReentrantTest,DelimiterIsMiddleCharacter)56 TEST(StrTokReentrantTest, DelimiterIsMiddleCharacter) {
57 char src[] = "12,34";
58 char *reserve = nullptr;
59 ASSERT_STREQ(__llvm_libc::strtok_r(src, ",", &reserve), "12");
60 // Another call to ensure that 'reserve' is not in a bad state.
61 ASSERT_STREQ(__llvm_libc::strtok_r(src, ",", &reserve), "12");
62 ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, ",", &reserve), nullptr);
63 }
64
TEST(StrTokReentrantTest,DelimiterAsLastCharacterShouldBeIgnored)65 TEST(StrTokReentrantTest, DelimiterAsLastCharacterShouldBeIgnored) {
66 char src[] = "1234:";
67 char *reserve = nullptr;
68 ASSERT_STREQ(__llvm_libc::strtok_r(src, ":", &reserve), "1234");
69 // Another call to ensure that 'reserve' is not in a bad state.
70 ASSERT_STREQ(__llvm_libc::strtok_r(src, ":", &reserve), "1234");
71 ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, ":", &reserve), nullptr);
72 }
73
TEST(StrTokReentrantTest,ShouldNotGoPastNullTerminator)74 TEST(StrTokReentrantTest, ShouldNotGoPastNullTerminator) {
75 char src[] = {'1', '2', '\0', ',', '3'};
76 char *reserve = nullptr;
77 ASSERT_STREQ(__llvm_libc::strtok_r(src, ",", &reserve), "12");
78 // Another call to ensure that 'reserve' is not in a bad state.
79 ASSERT_STREQ(__llvm_libc::strtok_r(src, ",", &reserve), "12");
80 ASSERT_STREQ(__llvm_libc::strtok_r(nullptr, ",", &reserve), nullptr);
81 }
82
TEST(StrTokReentrantTest,SubsequentCallsShouldFindFollowingDelimiters)83 TEST(StrTokReentrantTest, SubsequentCallsShouldFindFollowingDelimiters) {
84 char src[] = "12,34.56";
85 char *reserve = nullptr;
86 char *token = __llvm_libc::strtok_r(src, ",.", &reserve);
87 ASSERT_STREQ(token, "12");
88 token = __llvm_libc::strtok_r(nullptr, ",.", &reserve);
89 ASSERT_STREQ(token, "34");
90 token = __llvm_libc::strtok_r(nullptr, ",.", &reserve);
91 ASSERT_STREQ(token, "56");
92 token = __llvm_libc::strtok_r(nullptr, "_:,_", &reserve);
93 ASSERT_STREQ(token, nullptr);
94 // Subsequent calls after hitting the end of the string should also return
95 // nullptr.
96 token = __llvm_libc::strtok_r(nullptr, "_:,_", &reserve);
97 ASSERT_STREQ(token, nullptr);
98 }
99
TEST(StrTokReentrantTest,DelimitersShouldNotBeIncludedInToken)100 TEST(StrTokReentrantTest, DelimitersShouldNotBeIncludedInToken) {
101 char src[] = "__ab__:_cd__:__ef__:__";
102 char *reserve = nullptr;
103 char *token = __llvm_libc::strtok_r(src, "_:", &reserve);
104 ASSERT_STREQ(token, "ab");
105 token = __llvm_libc::strtok_r(nullptr, ":_", &reserve);
106 ASSERT_STREQ(token, "cd");
107 token = __llvm_libc::strtok_r(nullptr, "_:,", &reserve);
108 ASSERT_STREQ(token, "ef");
109 token = __llvm_libc::strtok_r(nullptr, "_:,_", &reserve);
110 ASSERT_STREQ(token, nullptr);
111 }
112