1 // Copyright (c) 2015-2016 The Khronos Group Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include <string>
16
17 #include "test/unit_spirv.h"
18
19 namespace spvtools {
20 namespace {
21
22 using spvtest::AutoText;
23
24 #define TAB "\t"
25 #define NEWLINE "\n"
26 #define BACKSLASH R"(\)"
27 #define QUOTE R"(")"
28
TEST(TextWordGet,NullTerminator)29 TEST(TextWordGet, NullTerminator) {
30 std::string word;
31 spv_position_t endPosition = {};
32 ASSERT_EQ(
33 SPV_SUCCESS,
34 AssemblyContext(AutoText("Word"), nullptr).getWord(&word, &endPosition));
35 ASSERT_EQ(4u, endPosition.column);
36 ASSERT_EQ(0u, endPosition.line);
37 ASSERT_EQ(4u, endPosition.index);
38 ASSERT_STREQ("Word", word.c_str());
39 }
40
41 TEST(TextWordGet, TabTerminator) {
42 std::string word;
43 spv_position_t endPosition = {};
44 ASSERT_EQ(SPV_SUCCESS, AssemblyContext(AutoText("Word\t"), nullptr)
45 .getWord(&word, &endPosition));
46 ASSERT_EQ(4u, endPosition.column);
47 ASSERT_EQ(0u, endPosition.line);
48 ASSERT_EQ(4u, endPosition.index);
49 ASSERT_STREQ("Word", word.c_str());
50 }
51
52 TEST(TextWordGet, SpaceTerminator) {
53 std::string word;
54 spv_position_t endPosition = {};
55 ASSERT_EQ(
56 SPV_SUCCESS,
57 AssemblyContext(AutoText("Word "), nullptr).getWord(&word, &endPosition));
58 ASSERT_EQ(4u, endPosition.column);
59 ASSERT_EQ(0u, endPosition.line);
60 ASSERT_EQ(4u, endPosition.index);
61 ASSERT_STREQ("Word", word.c_str());
62 }
63
64 TEST(TextWordGet, SemicolonTerminator) {
65 std::string word;
66 spv_position_t endPosition = {};
67 ASSERT_EQ(
68 SPV_SUCCESS,
69 AssemblyContext(AutoText("Wo;rd"), nullptr).getWord(&word, &endPosition));
70 ASSERT_EQ(2u, endPosition.column);
71 ASSERT_EQ(0u, endPosition.line);
72 ASSERT_EQ(2u, endPosition.index);
73 ASSERT_STREQ("Wo", word.c_str());
74 }
75
TEST(TextWordGet,NoTerminator)76 TEST(TextWordGet, NoTerminator) {
77 const std::string full_text = "abcdefghijklmn";
78 for (size_t len = 1; len <= full_text.size(); ++len) {
79 std::string word;
80 spv_text_t text = {full_text.data(), len};
81 spv_position_t endPosition = {};
82 ASSERT_EQ(SPV_SUCCESS,
83 AssemblyContext(&text, nullptr).getWord(&word, &endPosition));
84 ASSERT_EQ(0u, endPosition.line);
85 ASSERT_EQ(len, endPosition.column);
86 ASSERT_EQ(len, endPosition.index);
87 ASSERT_EQ(full_text.substr(0, len), word);
88 }
89 }
90
91 TEST(TextWordGet, MultipleWords) {
92 AutoText input("Words in a sentence");
93 AssemblyContext data(input, nullptr);
94
95 spv_position_t endPosition = {};
96 const char* words[] = {"Words", "in", "a", "sentence"};
97
98 std::string word;
99 for (uint32_t wordIndex = 0; wordIndex < 4; ++wordIndex) {
100 ASSERT_EQ(SPV_SUCCESS, data.getWord(&word, &endPosition));
101 ASSERT_EQ(strlen(words[wordIndex]),
102 endPosition.column - data.position().column);
103 ASSERT_EQ(0u, endPosition.line);
104 ASSERT_EQ(strlen(words[wordIndex]),
105 endPosition.index - data.position().index);
106 ASSERT_STREQ(words[wordIndex], word.c_str());
107
108 data.setPosition(endPosition);
109 if (3 != wordIndex) {
110 ASSERT_EQ(SPV_SUCCESS, data.advance());
111 } else {
112 ASSERT_EQ(SPV_END_OF_STREAM, data.advance());
113 }
114 }
115 }
116
117 TEST(TextWordGet, QuotesAreKept) {
118 AutoText input(R"("quotes" "around words")");
119 const char* expected[] = {R"("quotes")", R"("around words")"};
120 AssemblyContext data(input, nullptr);
121
122 std::string word;
123 spv_position_t endPosition = {};
124 ASSERT_EQ(SPV_SUCCESS, data.getWord(&word, &endPosition));
125 EXPECT_EQ(8u, endPosition.column);
126 EXPECT_EQ(0u, endPosition.line);
127 EXPECT_EQ(8u, endPosition.index);
128 EXPECT_STREQ(expected[0], word.c_str());
129
130 // Move to the next word.
131 data.setPosition(endPosition);
132 data.seekForward(1);
133
134 ASSERT_EQ(SPV_SUCCESS, data.getWord(&word, &endPosition));
135 EXPECT_EQ(23u, endPosition.column);
136 EXPECT_EQ(0u, endPosition.line);
137 EXPECT_EQ(23u, endPosition.index);
138 EXPECT_STREQ(expected[1], word.c_str());
139 }
140
141 TEST(TextWordGet, QuotesBetweenWordsActLikeGlue) {
142 AutoText input(R"(quotes" "between words)");
143 const char* expected[] = {R"(quotes" "between)", "words"};
144 AssemblyContext data(input, nullptr);
145
146 std::string word;
147 spv_position_t endPosition = {};
148 ASSERT_EQ(SPV_SUCCESS, data.getWord(&word, &endPosition));
149 EXPECT_EQ(16u, endPosition.column);
150 EXPECT_EQ(0u, endPosition.line);
151 EXPECT_EQ(16u, endPosition.index);
152 EXPECT_STREQ(expected[0], word.c_str());
153
154 // Move to the next word.
155 data.setPosition(endPosition);
156 data.seekForward(1);
157
158 ASSERT_EQ(SPV_SUCCESS, data.getWord(&word, &endPosition));
159 EXPECT_EQ(22u, endPosition.column);
160 EXPECT_EQ(0u, endPosition.line);
161 EXPECT_EQ(22u, endPosition.index);
162 EXPECT_STREQ(expected[1], word.c_str());
163 }
164
165 TEST(TextWordGet, QuotingWhitespace) {
166 AutoText input(QUOTE "white " NEWLINE TAB " space" QUOTE);
167 // Whitespace surrounded by quotes acts like glue.
168 std::string word;
169 spv_position_t endPosition = {};
170 ASSERT_EQ(SPV_SUCCESS,
171 AssemblyContext(input, nullptr).getWord(&word, &endPosition));
172 EXPECT_EQ(input.str.length(), endPosition.column);
173 EXPECT_EQ(0u, endPosition.line);
174 EXPECT_EQ(input.str.length(), endPosition.index);
175 EXPECT_EQ(input.str, word);
176 }
177
178 TEST(TextWordGet, QuoteAlone) {
179 AutoText input(QUOTE);
180 std::string word;
181 spv_position_t endPosition = {};
182 ASSERT_EQ(SPV_SUCCESS,
183 AssemblyContext(input, nullptr).getWord(&word, &endPosition));
184 ASSERT_EQ(1u, endPosition.column);
185 ASSERT_EQ(0u, endPosition.line);
186 ASSERT_EQ(1u, endPosition.index);
187 ASSERT_STREQ(QUOTE, word.c_str());
188 }
189
190 TEST(TextWordGet, EscapeAlone) {
191 AutoText input(BACKSLASH);
192 std::string word;
193 spv_position_t endPosition = {};
194 ASSERT_EQ(SPV_SUCCESS,
195 AssemblyContext(input, nullptr).getWord(&word, &endPosition));
196 ASSERT_EQ(1u, endPosition.column);
197 ASSERT_EQ(0u, endPosition.line);
198 ASSERT_EQ(1u, endPosition.index);
199 ASSERT_STREQ(BACKSLASH, word.c_str());
200 }
201
202 TEST(TextWordGet, EscapeAtEndOfInput) {
203 AutoText input("word" BACKSLASH);
204 std::string word;
205 spv_position_t endPosition = {};
206 ASSERT_EQ(SPV_SUCCESS,
207 AssemblyContext(input, nullptr).getWord(&word, &endPosition));
208 ASSERT_EQ(5u, endPosition.column);
209 ASSERT_EQ(0u, endPosition.line);
210 ASSERT_EQ(5u, endPosition.index);
211 ASSERT_STREQ("word" BACKSLASH, word.c_str());
212 }
213
214 TEST(TextWordGet, Escaping) {
215 AutoText input("w" BACKSLASH QUOTE "o" BACKSLASH NEWLINE "r" BACKSLASH ";d");
216 std::string word;
217 spv_position_t endPosition = {};
218 ASSERT_EQ(SPV_SUCCESS,
219 AssemblyContext(input, nullptr).getWord(&word, &endPosition));
220 ASSERT_EQ(10u, endPosition.column);
221 ASSERT_EQ(0u, endPosition.line);
222 ASSERT_EQ(10u, endPosition.index);
223 ASSERT_EQ(input.str, word);
224 }
225
TEST(TextWordGet,EscapingEscape)226 TEST(TextWordGet, EscapingEscape) {
227 AutoText input("word" BACKSLASH BACKSLASH " abc");
228 std::string word;
229 spv_position_t endPosition = {};
230 ASSERT_EQ(SPV_SUCCESS,
231 AssemblyContext(input, nullptr).getWord(&word, &endPosition));
232 ASSERT_EQ(6u, endPosition.column);
233 ASSERT_EQ(0u, endPosition.line);
234 ASSERT_EQ(6u, endPosition.index);
235 ASSERT_STREQ("word" BACKSLASH BACKSLASH, word.c_str());
236 }
237
238 TEST(TextWordGet, CRLF) {
239 AutoText input("abc\r\nd");
240 AssemblyContext data(input, nullptr);
241 std::string word;
242 spv_position_t pos = {};
243 ASSERT_EQ(SPV_SUCCESS, data.getWord(&word, &pos));
244 EXPECT_EQ(3u, pos.column);
245 EXPECT_STREQ("abc", word.c_str());
246 data.setPosition(pos);
247 data.advance();
248 ASSERT_EQ(SPV_SUCCESS, data.getWord(&word, &pos));
249 EXPECT_EQ(1u, pos.column);
250 EXPECT_STREQ("d", word.c_str());
251 }
252
253 } // namespace
254 } // namespace spvtools
255