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 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 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 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