libspirv::AssemblyContext* context, spv_instruction_t* pInst) {
std::string firstWord;
spv_position_t nextPosition = {};
- auto error = context->getWord(firstWord, &nextPosition);
+ auto error = context->getWord(&firstWord, &nextPosition);
if (error) return context->diagnostic(error) << "Internal Error";
if ((error = encodeImmediate(context, firstWord.c_str(), pInst))) {
// Otherwise, there must be an operand that's either a literal, an ID, or
// an immediate.
std::string operandValue;
- if ((error = context->getWord(operandValue, &nextPosition)))
+ if ((error = context->getWord(&operandValue, &nextPosition)))
return context->diagnostic(error) << "Internal Error";
if (operandValue == "=")
std::string firstWord;
spv_position_t nextPosition = {};
- spv_result_t error = context->getWord(firstWord, &nextPosition);
+ spv_result_t error = context->getWord(&firstWord, &nextPosition);
if (error) return context->diagnostic() << "Internal Error";
std::string opcodeName;
if (context->advance())
return context->diagnostic() << "Expected '=', found end of stream.";
std::string equal_sign;
- error = context->getWord(equal_sign, &nextPosition);
+ error = context->getWord(&equal_sign, &nextPosition);
if ("=" != equal_sign)
return context->diagnostic() << "'=' expected after result id.";
context->setPosition(nextPosition);
if (context->advance())
return context->diagnostic() << "Expected opcode, found end of stream.";
- error = context->getWord(opcodeName, &nextPosition);
+ error = context->getWord(&opcodeName, &nextPosition);
if (error) return context->diagnostic(error) << "Internal Error";
if (!context->startsWithOp()) {
return context->diagnostic() << "Invalid Opcode prefix '" << opcodeName
spv_opcode_desc opcodeEntry;
error = grammar.lookupOpcode(pInstName, &opcodeEntry);
if (error) {
- return context->diagnostic(error) << "Invalid Opcode name '"
- << opcodeName << "'";
+ return context->diagnostic(error) << "Invalid Opcode name '" << opcodeName
+ << "'";
}
if (opcodeEntry->hasResult && result_id.empty()) {
return context->diagnostic()
}
std::string operandValue;
- error = context->getWord(operandValue, &nextPosition);
+ error = context->getWord(&operandValue, &nextPosition);
if (error) return context->diagnostic(error) << "Internal Error";
error = spvTextEncodeOperand(grammar, context, type, operandValue.c_str(),
return SPV_SUCCESS;
}
-/// @brief Fetch the next word from the text stream.
-///
-/// A word ends at the next comment or whitespace. However, double-quoted
-/// strings remain intact, and a backslash always escapes the next character.
-///
-/// @param[in] text stream to read from
-/// @param[in] position current position in text stream
-/// @param[out] word returned word
-/// @param[out] endPosition one past the end of the returned word
-///
-/// @return result code
-spv_result_t getWord(spv_text text, spv_position position, std::string& word,
- spv_position endPosition) {
+// Fetches the next word from the given text stream starting from the given
+// *position. On success, writes the decoded word into *word and updates
+// *position to the location past the returned word.
+//
+// A word ends at the next comment or whitespace. However, double-quoted
+// strings remain intact, and a backslash always escapes the next character.
+spv_result_t getWord(spv_text text, spv_position position, std::string* word) {
if (!text->str || !text->length) return SPV_ERROR_INVALID_TEXT;
- if (!position || !endPosition) return SPV_ERROR_INVALID_POINTER;
+ if (!position) return SPV_ERROR_INVALID_POINTER;
- *endPosition = *position;
+ const size_t start_index = position->index;
bool quoting = false;
bool escaping = false;
// NOTE: Assumes first character is not white space!
while (true) {
- if (endPosition->index >= text->length) {
- word.assign(text->str + position->index,
- static_cast<size_t>(endPosition->index - position->index));
+ if (position->index >= text->length) {
+ word->assign(text->str + start_index, text->str + position->index);
return SPV_SUCCESS;
}
- const char ch = text->str[endPosition->index];
+ const char ch = text->str[position->index];
if (ch == '\\')
escaping = !escaping;
else {
if (escaping || quoting) break;
// Fall through.
case '\0': { // NOTE: End of word found!
- word.assign(
- text->str + position->index,
- static_cast<size_t>(endPosition->index - position->index));
+ word->assign(text->str + start_index, text->str + position->index);
return SPV_SUCCESS;
}
default:
escaping = false;
}
- endPosition->column++;
- endPosition->index++;
+ position->column++;
+ position->index++;
}
}
return ::advance(text_, ¤t_position_);
}
-spv_result_t AssemblyContext::getWord(std::string& word,
- spv_position endPosition) {
- return ::getWord(text_, ¤t_position_, word, endPosition);
+spv_result_t AssemblyContext::getWord(std::string* word,
+ spv_position next_position) {
+ *next_position = current_position_;
+ return ::getWord(text_, next_position, word);
}
bool AssemblyContext::startsWithOp() {
}
bool AssemblyContext::isStartOfNewInst() {
- spv_position_t nextPosition = current_position_;
- if (::advance(text_, &nextPosition)) return false;
- if (::startsWithOp(text_, &nextPosition)) return true;
+ spv_position_t pos = current_position_;
+ if (::advance(text_, &pos)) return false;
+ if (::startsWithOp(text_, &pos)) return true;
std::string word;
- spv_position_t startPosition = current_position_;
- if (::getWord(text_, &startPosition, word, &nextPosition)) return false;
+ pos = current_position_;
+ if (::getWord(text_, &pos, &word)) return false;
if ('%' != word.front()) return false;
- if (::advance(text_, &nextPosition)) return false;
- startPosition = nextPosition;
- if (::getWord(text_, &startPosition, word, &nextPosition)) return false;
+ if (::advance(text_, &pos)) return false;
+ if (::getWord(text_, &pos, &word)) return false;
if ("=" != word) return false;
- if (::advance(text_, &nextPosition)) return false;
- startPosition = nextPosition;
- if (::startsWithOp(text_, &startPosition)) return true;
+ if (::advance(text_, &pos)) return false;
+ if (::startsWithOp(text_, &pos)) return true;
return false;
}
TEST(TextWordGet, NullTerminator) {
std::string word;
spv_position_t endPosition = {};
- ASSERT_EQ(SPV_SUCCESS, AssemblyContext(AutoText("Word"), nullptr)
- .getWord(word, &endPosition));
+ ASSERT_EQ(
+ SPV_SUCCESS,
+ AssemblyContext(AutoText("Word"), nullptr).getWord(&word, &endPosition));
ASSERT_EQ(4u, endPosition.column);
ASSERT_EQ(0u, endPosition.line);
ASSERT_EQ(4u, endPosition.index);
std::string word;
spv_position_t endPosition = {};
ASSERT_EQ(SPV_SUCCESS, AssemblyContext(AutoText("Word\t"), nullptr)
- .getWord(word, &endPosition));
+ .getWord(&word, &endPosition));
ASSERT_EQ(4u, endPosition.column);
ASSERT_EQ(0u, endPosition.line);
ASSERT_EQ(4u, endPosition.index);
TEST(TextWordGet, SpaceTerminator) {
std::string word;
spv_position_t endPosition = {};
- ASSERT_EQ(SPV_SUCCESS, AssemblyContext(AutoText("Word "), nullptr)
- .getWord(word, &endPosition));
+ ASSERT_EQ(
+ SPV_SUCCESS,
+ AssemblyContext(AutoText("Word "), nullptr).getWord(&word, &endPosition));
ASSERT_EQ(4u, endPosition.column);
ASSERT_EQ(0u, endPosition.line);
ASSERT_EQ(4u, endPosition.index);
TEST(TextWordGet, SemicolonTerminator) {
std::string word;
spv_position_t endPosition = {};
- ASSERT_EQ(SPV_SUCCESS, AssemblyContext(AutoText("Wo;rd"), nullptr)
- .getWord(word, &endPosition));
+ ASSERT_EQ(
+ SPV_SUCCESS,
+ AssemblyContext(AutoText("Wo;rd"), nullptr).getWord(&word, &endPosition));
ASSERT_EQ(2u, endPosition.column);
ASSERT_EQ(0u, endPosition.line);
ASSERT_EQ(2u, endPosition.index);
spv_text_t text = {full_text.data(), len};
spv_position_t endPosition = {};
ASSERT_EQ(SPV_SUCCESS,
- AssemblyContext(&text, nullptr).getWord(word, &endPosition));
+ AssemblyContext(&text, nullptr).getWord(&word, &endPosition));
ASSERT_EQ(0u, endPosition.line);
ASSERT_EQ(len, endPosition.column);
ASSERT_EQ(len, endPosition.index);
std::string word;
for (uint32_t wordIndex = 0; wordIndex < 4; ++wordIndex) {
- ASSERT_EQ(SPV_SUCCESS, data.getWord(word, &endPosition));
+ ASSERT_EQ(SPV_SUCCESS, data.getWord(&word, &endPosition));
ASSERT_EQ(strlen(words[wordIndex]),
endPosition.column - data.position().column);
ASSERT_EQ(0u, endPosition.line);
std::string word;
spv_position_t endPosition = {};
- ASSERT_EQ(SPV_SUCCESS, data.getWord(word, &endPosition));
+ ASSERT_EQ(SPV_SUCCESS, data.getWord(&word, &endPosition));
EXPECT_EQ(8u, endPosition.column);
EXPECT_EQ(0u, endPosition.line);
EXPECT_EQ(8u, endPosition.index);
data.setPosition(endPosition);
data.seekForward(1);
- ASSERT_EQ(SPV_SUCCESS, data.getWord(word, &endPosition));
+ ASSERT_EQ(SPV_SUCCESS, data.getWord(&word, &endPosition));
EXPECT_EQ(23u, endPosition.column);
EXPECT_EQ(0u, endPosition.line);
EXPECT_EQ(23u, endPosition.index);
std::string word;
spv_position_t endPosition = {};
- ASSERT_EQ(SPV_SUCCESS, data.getWord(word, &endPosition));
+ ASSERT_EQ(SPV_SUCCESS, data.getWord(&word, &endPosition));
EXPECT_EQ(16u, endPosition.column);
EXPECT_EQ(0u, endPosition.line);
EXPECT_EQ(16u, endPosition.index);
data.setPosition(endPosition);
data.seekForward(1);
- ASSERT_EQ(SPV_SUCCESS, data.getWord(word, &endPosition));
+ ASSERT_EQ(SPV_SUCCESS, data.getWord(&word, &endPosition));
EXPECT_EQ(22u, endPosition.column);
EXPECT_EQ(0u, endPosition.line);
EXPECT_EQ(22u, endPosition.index);
std::string word;
spv_position_t endPosition = {};
ASSERT_EQ(SPV_SUCCESS,
- AssemblyContext(input, nullptr).getWord(word, &endPosition));
+ AssemblyContext(input, nullptr).getWord(&word, &endPosition));
EXPECT_EQ(input.str.length(), endPosition.column);
EXPECT_EQ(0u, endPosition.line);
EXPECT_EQ(input.str.length(), endPosition.index);
std::string word;
spv_position_t endPosition = {};
ASSERT_EQ(SPV_SUCCESS,
- AssemblyContext(input, nullptr).getWord(word, &endPosition));
+ AssemblyContext(input, nullptr).getWord(&word, &endPosition));
ASSERT_EQ(1u, endPosition.column);
ASSERT_EQ(0u, endPosition.line);
ASSERT_EQ(1u, endPosition.index);
std::string word;
spv_position_t endPosition = {};
ASSERT_EQ(SPV_SUCCESS,
- AssemblyContext(input, nullptr).getWord(word, &endPosition));
+ AssemblyContext(input, nullptr).getWord(&word, &endPosition));
ASSERT_EQ(1u, endPosition.column);
ASSERT_EQ(0u, endPosition.line);
ASSERT_EQ(1u, endPosition.index);
std::string word;
spv_position_t endPosition = {};
ASSERT_EQ(SPV_SUCCESS,
- AssemblyContext(input, nullptr).getWord(word, &endPosition));
+ AssemblyContext(input, nullptr).getWord(&word, &endPosition));
ASSERT_EQ(5u, endPosition.column);
ASSERT_EQ(0u, endPosition.line);
ASSERT_EQ(5u, endPosition.index);
std::string word;
spv_position_t endPosition = {};
ASSERT_EQ(SPV_SUCCESS,
- AssemblyContext(input, nullptr).getWord(word, &endPosition));
+ AssemblyContext(input, nullptr).getWord(&word, &endPosition));
ASSERT_EQ(10u, endPosition.column);
ASSERT_EQ(0u, endPosition.line);
ASSERT_EQ(10u, endPosition.index);
std::string word;
spv_position_t endPosition = {};
ASSERT_EQ(SPV_SUCCESS,
- AssemblyContext(input, nullptr).getWord(word, &endPosition));
+ AssemblyContext(input, nullptr).getWord(&word, &endPosition));
ASSERT_EQ(6u, endPosition.column);
ASSERT_EQ(0u, endPosition.line);
ASSERT_EQ(6u, endPosition.index);