Handle CRLF in assembly text.
authorDejan Mircevski <deki@google.com>
Fri, 1 Apr 2016 04:47:02 +0000 (00:47 -0400)
committerDejan Mircevski <deki@google.com>
Fri, 1 Apr 2016 04:47:02 +0000 (00:47 -0400)
source/text_handler.cpp
test/TextAdvance.cpp
test/TextToBinary.cpp
test/TextWordGet.cpp

index cc4a42b..3803465 100644 (file)
@@ -90,6 +90,7 @@ spv_result_t advance(spv_text text, spv_position position) {
       return advance(text, position);
     case ' ':
     case '\t':
+    case '\r':
       position->column++;
       position->index++;
       return advance(text, position);
@@ -137,6 +138,7 @@ spv_result_t getWord(spv_text text, spv_position position, std::string* word) {
         case ';':
         case '\t':
         case '\n':
+        case '\r':
           if (escaping || quoting) break;
         // Fall through.
         case '\0': {  // NOTE: End of word found!
index 627d0d6..0f18530 100644 (file)
@@ -96,4 +96,40 @@ TEST(TextAdvance, NoNullTerminator) {
   ASSERT_EQ(SPV_END_OF_STREAM, data.advance());
 }
 
+// Invokes AssemblyContext::advance() on text, asserts success, and returns
+// AssemblyContext::position().
+spv_position_t PositionAfterAdvance(const char* text) {
+  AutoText input(text);
+  AssemblyContext data(input, nullptr);
+  EXPECT_EQ(SPV_SUCCESS, data.advance());
+  return data.position();
+}
+
+TEST(TextAdvance, SkipOverCR) {
+  const auto pos = PositionAfterAdvance("\rWord");
+  EXPECT_EQ(1u, pos.column);
+  EXPECT_EQ(0u, pos.line);
+  EXPECT_EQ(1u, pos.index);
+}
+
+TEST(TextAdvance, SkipOverCRs) {
+  const auto pos = PositionAfterAdvance("\r\r\rWord");
+  EXPECT_EQ(3u, pos.column);
+  EXPECT_EQ(0u, pos.line);
+  EXPECT_EQ(3u, pos.index);
+}
+
+TEST(TextAdvance, SkipOverCRLF) {
+  const auto pos = PositionAfterAdvance("\r\nWord");
+  EXPECT_EQ(0u, pos.column);
+  EXPECT_EQ(1u, pos.line);
+  EXPECT_EQ(2u, pos.index);
+}
+
+TEST(TextAdvance, SkipOverCRLFs) {
+  const auto pos = PositionAfterAdvance("\r\n\r\nWord");
+  EXPECT_EQ(0u, pos.column);
+  EXPECT_EQ(2u, pos.line);
+  EXPECT_EQ(4u, pos.index);
+}
 }  // anonymous namespace
index 2ea1be6..812da40 100644 (file)
@@ -195,6 +195,14 @@ TEST_F(TextToBinaryTest, WrongOpCode) {
   EXPECT_EQ(6u, diagnostic->position.column + 1);
 }
 
+TEST_F(TextToBinaryTest, CRLF) {
+  const std::string input =
+      "%i32 = OpTypeInt 32 1\r\n%c = OpConstant %i32 123\r\n";
+  EXPECT_THAT(CompiledInstructions(input),
+              Eq(Concatenate({MakeInstruction(SpvOpTypeInt, {1, 32, 1}),
+                              MakeInstruction(SpvOpConstant, {1, 2, 123})})));
+}
+
 using TextToBinaryFloatValueTest = spvtest::TextToBinaryTestBase<
     ::testing::TestWithParam<std::pair<std::string, uint32_t>>>;
 
index 7abfee5..651f850 100644 (file)
@@ -245,4 +245,19 @@ TEST(TextWordGet, EscapingEscape) {
   ASSERT_STREQ("word" BACKSLASH BACKSLASH, word.c_str());
 }
 
+TEST(TextWordGet, CRLF) {
+  AutoText input("abc\r\nd");
+  AssemblyContext data(input, nullptr);
+  std::string word;
+  spv_position_t pos = {};
+  ASSERT_EQ(SPV_SUCCESS, data.getWord(&word, &pos));
+  EXPECT_EQ(3u, pos.column);
+  EXPECT_STREQ("abc", word.c_str());
+  data.setPosition(pos);
+  data.advance();
+  ASSERT_EQ(SPV_SUCCESS, data.getWord(&word, &pos));
+  EXPECT_EQ(1u, pos.column);
+  EXPECT_STREQ("d", word.c_str());
+}
+
 }  // anonymous namespace