diff --git a/vhdlpp/debug.cc b/vhdlpp/debug.cc index 71ca0abd4..22fb312a6 100644 --- a/vhdlpp/debug.cc +++ b/vhdlpp/debug.cc @@ -415,12 +415,8 @@ void ExpRelation::dump(ostream&out, int indent) const void ExpString::dump(ostream&out, int indent) const { - out << setw(indent) << "" << "String \""; - for(vector::const_iterator it = value_.begin(); - it != value_.end(); ++it) - out << *it; - out << "\"" - << " at " << get_fileline() << endl; + out << setw(indent) << "" << "String \"" << value_; + out << "\"" << " at " << get_fileline() << endl; } void ExpUAbs::dump(ostream&out, int indent) const diff --git a/vhdlpp/expression.cc b/vhdlpp/expression.cc index 4361656a0..b9573d1ef 100644 --- a/vhdlpp/expression.cc +++ b/vhdlpp/expression.cc @@ -632,10 +632,8 @@ ExpShift::ExpShift(ExpShift::shift_t op, Expression*op1, Expression*op2) } ExpString::ExpString(const char* value) -: value_(strlen(value)) +: value_(value) { - for(size_t idx = 0; idx < value_.size(); idx += 1) - value_[idx] = value[idx]; } ExpString::~ExpString() diff --git a/vhdlpp/expression.h b/vhdlpp/expression.h index ba1a48120..ee609ae60 100644 --- a/vhdlpp/expression.h +++ b/vhdlpp/expression.h @@ -796,13 +796,17 @@ class ExpString : public Expression { int emit(ostream&out, Entity*ent, ScopeBase*scope); bool is_primary(void) const; void dump(ostream&out, int indent = 0) const; - const std::vector& get_value() const { return value_; } + const std::string& get_value() const { return value_; } + + // Converts quotation marks (") to its escaped + // counterpart in SystemVerilog (\") + static std::string escape_quot(const std::string& str); private: int emit_as_array_(ostream&out, Entity*ent, ScopeBase*scope, const VTypeArray*arr); private: - std::vector value_; + std::string value_; }; class ExpUAbs : public ExpUnary { diff --git a/vhdlpp/expression_emit.cc b/vhdlpp/expression_emit.cc index 9ab2c66fa..09ac0654d 100644 --- a/vhdlpp/expression_emit.cc +++ b/vhdlpp/expression_emit.cc @@ -916,11 +916,8 @@ int ExpString::emit(ostream& out, Entity*ent, ScopeBase*scope) return emit_as_array_(out, ent, scope, arr); } - out << "\""; - for(vector::const_iterator it = value_.begin() - ; it != value_.end(); ++it) - out << *it; - out << "\""; + out << "\"" << escape_quot(value_) << "\""; + return 0; } @@ -959,6 +956,19 @@ int ExpString::emit_as_array_(ostream& out, Entity*, ScopeBase*, const VTypeArra return errors; } +std::string ExpString::escape_quot(const std::string& str) +{ + size_t idx = 0; + string result(str); + + while((idx = result.find('"', idx)) != string::npos) { + result.replace(idx, 1, "\\\""); + idx += 2; + } + + return result; +} + int ExpUAbs::emit(ostream&out, Entity*ent, ScopeBase*scope) { int errors = 0; diff --git a/vhdlpp/expression_stream.cc b/vhdlpp/expression_stream.cc index 1321a3740..d707fdcff 100644 --- a/vhdlpp/expression_stream.cc +++ b/vhdlpp/expression_stream.cc @@ -272,10 +272,15 @@ void ExpShift::write_to_stream(ostream&out) const void ExpString::write_to_stream(ostream&fd) const { fd << "\""; - for(vector::const_iterator it = value_.begin(); - it != value_.end(); ++it) { - fd << *it; + + // Restore double quotation marks + for(string::const_iterator it = value_.begin(); it != value_.end(); ++it) { + if(*it == '"') + fd << "\"\""; + else + fd << *it; } + fd << "\""; } diff --git a/vhdlpp/sequential_emit.cc b/vhdlpp/sequential_emit.cc index 7148e2b52..ec60fa394 100644 --- a/vhdlpp/sequential_emit.cc +++ b/vhdlpp/sequential_emit.cc @@ -484,7 +484,7 @@ int ReportStmt::emit(ostream&out, Entity*, ScopeBase*) case UNSPECIFIED: ivl_assert(*this, false); break; } - out << msg_; + out << ExpString::escape_quot(msg_); out << " (" << get_fileline() << ")\");"; if(severity_ == FAILURE) @@ -497,7 +497,7 @@ int ReportStmt::emit(ostream&out, Entity*, ScopeBase*) void ReportStmt::write_to_stream(std::ostream&fd) { - fd << "report \"" << msg_ << "\"" << std::endl; + fd << "report \"" << ExpString::escape_quot(msg_) << "\"" << std::endl; fd << "severity "; switch(severity_)