00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "comma/basic/Diagnostic.h"
00010 #include <cassert>
00011
00012 using namespace comma;
00013
00014 DiagnosticStream::DiagnosticStream(std::ostream &stream)
00015 : stream(stream), position(0) { }
00016
00017 DiagnosticStream &DiagnosticStream::initialize(const SourceLocation &loc,
00018 const char *format)
00019 {
00020 assert(position == 0 && "Diagnostic reinitialized before completion!");
00021
00022 message.str("");
00023 this->format = format;
00024 if (!loc.getIdentity().empty())
00025 message << loc.getIdentity() << ":";
00026 message << loc.getLine() << ":" << loc.getColumn() << ": ";
00027
00028 emitFormatComponent();
00029 return *this;
00030 }
00031
00032 void DiagnosticStream::emitFormatComponent()
00033 {
00034 for (char c = format[position]; c; c = format[++position]) {
00035 if (c == '%') {
00036 c = format[++position];
00037 assert(c != 0 && "Malformed diagnostic format string!");
00038 if (c == '%') {
00039 message << c;
00040 continue;
00041 }
00042 ++position;
00043 return;
00044 }
00045 message << c;
00046 }
00047
00048
00049 stream << message.str() << std::endl;
00050 position = 0;
00051 message.str("");
00052 }
00053
00054 DiagnosticStream &DiagnosticStream::operator<<(const std::string &string)
00055 {
00056 message << string;
00057 emitFormatComponent();
00058 return *this;
00059 }
00060
00061 DiagnosticStream &DiagnosticStream::operator<<(const char *string)
00062 {
00063 message << string;
00064 emitFormatComponent();
00065 return *this;
00066 }
00067
00068 DiagnosticStream &DiagnosticStream::operator<<(int n)
00069 {
00070 message << n;
00071 emitFormatComponent();
00072 return *this;
00073 }
00074
00075 DiagnosticStream &DiagnosticStream::operator<<(char c)
00076 {
00077 message << c;
00078 emitFormatComponent();
00079 return *this;
00080 }
00081
00082 DiagnosticStream &Diagnostic::report(const SourceLocation &loc, diag::Kind kind)
00083 {
00084 return diagstream.initialize(loc, messages[kind]);
00085 }
00086
00087 const char *Diagnostic::messages[diag::LAST_UNUSED_DIAGNOSTIC_KIND] = {
00088 #define DIAGNOSTIC(ENUM, KIND, FORMAT) FORMAT,
00089 #include "comma/basic/Diagnostic.def"
00090 #undef DIAGNOSTIC
00091 };