Print diagnostics at the beginning of input.

A spv_diagnostic_t value knows if the source is textual rather
than binary.
This commit is contained in:
David Neto 2015-09-01 18:05:14 -04:00
parent e75b3e769d
commit c978643748
4 changed files with 38 additions and 13 deletions

View File

@ -362,6 +362,7 @@ typedef struct spv_position_t {
typedef struct spv_diagnostic_t {
spv_position_t position;
char *error;
bool isTextSource;
} spv_diagnostic_t;
// Type Definitions

View File

@ -42,6 +42,7 @@ spv_diagnostic spvDiagnosticCreate(const spv_position position,
diagnostic->error = new char[length];
spvCheck(!diagnostic->error, delete diagnostic; return nullptr);
diagnostic->position = *position;
diagnostic->isTextSource = false;
memset(diagnostic->error, 0, length);
strncpy(diagnostic->error, message, length);
return diagnostic;
@ -58,10 +59,7 @@ void spvDiagnosticDestroy(spv_diagnostic diagnostic) {
spv_result_t spvDiagnosticPrint(const spv_diagnostic diagnostic) {
spvCheck(!diagnostic, return SPV_ERROR_INVALID_DIAGNOSTIC);
// TODO: Check that the logic choosing between a text or binary diagnostic is
// corrent.
if ((diagnostic->position.line || diagnostic->position.column) &&
diagnostic->position.index) {
if (diagnostic->isTextSource) {
// NOTE: This is a text position
// NOTE: add 1 to the line as editors start at line 1, we are counting new
// line characters to start at line 0
@ -69,9 +67,8 @@ spv_result_t spvDiagnosticPrint(const spv_diagnostic diagnostic) {
<< diagnostic->position.column + 1 << ": " << diagnostic->error
<< "\n";
return SPV_SUCCESS;
} else if (!diagnostic->position.line && !diagnostic->position.column &&
diagnostic->position.index) {
// NOTE: This is a binary position
} else {
// NOTE: Assume this is a binary position
std::cerr << "error: " << diagnostic->position.index << ": "
<< diagnostic->error << "\n";
return SPV_SUCCESS;

View File

@ -186,8 +186,10 @@ spv_result_t spvTextWordGet(const spv_text text,
}
}
namespace {
// Returns true if the string at the given position in text starts with "Op".
static bool spvStartsWithOp(const spv_text text, const spv_position position) {
bool spvStartsWithOp(const spv_text text, const spv_position position) {
if (text->length < position->index + 3) return false;
char ch0 = text->str[position->index];
char ch1 = text->str[position->index + 1];
@ -195,6 +197,8 @@ static bool spvStartsWithOp(const spv_text text, const spv_position position) {
return ('O' == ch0 && 'p' == ch1 && ('A' <= ch2 && ch2 <= 'Z'));
}
} // anonymous namespace
// Returns true if a new instruction begins at the given position in text.
bool spvTextIsStartOfNewInst(const spv_text text,
const spv_position position) {
@ -670,11 +674,17 @@ spv_result_t spvTextEncodeOpcode(
return SPV_SUCCESS;
}
spv_result_t spvTextToBinary(const spv_text text,
const spv_opcode_table opcodeTable,
const spv_operand_table operandTable,
const spv_ext_inst_table extInstTable,
spv_binary *pBinary, spv_diagnostic *pDiagnostic) {
namespace {
// Translates a given assembly language module into binary form.
// If a diagnostic is generated, it is not yet marked as being
// for a text-based input.
spv_result_t spvTextToBinaryInternal(const spv_text text,
const spv_opcode_table opcodeTable,
const spv_operand_table operandTable,
const spv_ext_inst_table extInstTable,
spv_binary *pBinary,
spv_diagnostic *pDiagnostic) {
spv_position_t position = {};
spvCheck(!text->str || !text->length, DIAGNOSTIC << "Text stream is empty.";
return SPV_ERROR_INVALID_TEXT);
@ -742,6 +752,20 @@ spv_result_t spvTextToBinary(const spv_text text,
return SPV_SUCCESS;
}
} // anonymous namespace
spv_result_t spvTextToBinary(const spv_text text,
const spv_opcode_table opcodeTable,
const spv_operand_table operandTable,
const spv_ext_inst_table extInstTable,
spv_binary *pBinary, spv_diagnostic *pDiagnostic) {
spv_result_t result = spvTextToBinaryInternal(
text, opcodeTable, operandTable, extInstTable, pBinary, pDiagnostic);
if (pDiagnostic && *pDiagnostic) (*pDiagnostic)->isTextSource = true;
return result;
}
void spvTextDestroy(spv_text text) {
spvCheck(!text, return );
if (text->str) {

View File

@ -41,4 +41,7 @@ TEST(DiagnosticPrint, InvalidDiagnostic) {
ASSERT_EQ(SPV_ERROR_INVALID_DIAGNOSTIC, spvDiagnosticPrint(nullptr));
}
// TODO(dneto): We should be able to redirect the diagnostic printing.
// Once we do that, we can test diagnostic corner cases.
} // anonymous namespace