00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "config.h"
00021 #include "vypIO.h"
00022
00023 #ifndef BUILDING_DOX
00024 # include <string>
00025 # include <iomanip>
00026 #endif
00027
00028 using std::string;
00029
00030 namespace StreamDecorator {
00031
00032
00033 bool Color::useColors = false;
00034 struct Color::Private {
00035 EColor color;
00036 };
00037 Color::Color(EColor color):
00038 d(new Private)
00039 {
00040 d->color = color;
00041 }
00042 Color::Color(const Color &cObj):
00043 d(new Private)
00044 {
00045 d->color = cObj.d->color;
00046 }
00047 Color::~Color() {
00048 delete d;
00049 }
00050 void Color::enable(bool b) {
00051 Color::useColors = b;
00052 }
00053 bool Color::isEnabled() {
00054 return Color::useColors;
00055 }
00056 std::ostream& operator<< (std::ostream &stream, const Color &cObj) {
00057 if (Color::useColors) {
00058 static const char ESC = '\033';
00059 stream << ESC;
00060 switch (cObj.d->color) {
00061 case C_NO_COLOR: stream << "[0m"; break;
00062 case C_BLUE: stream << "[0;34m"; break;
00063 case C_GREEN: stream << "[0;32m"; break;
00064 case C_CYAN: stream << "[0;36m"; break;
00065 case C_RED: stream << "[0;31m"; break;
00066 case C_PURPLE: stream << "[0;35m"; break;
00067 case C_BROWN: stream << "[0;33m"; break;
00068 case C_LIGHT_GRAY: stream << "[0;37m"; break;
00069 case C_DARK_GRAY: stream << "[1;30m"; break;
00070 case C_LIGHT_BLUE: stream << "[1;34m"; break;
00071 case C_LIGHT_GREEN: stream << "[1;32m"; break;
00072 case C_LIGHT_CYAN: stream << "[1;36m"; break;
00073 case C_LIGHT_RED: stream << "[1;31m"; break;
00074 case C_LIGHT_PURPLE: stream << "[1;35m"; break;
00075 case C_YELLOW: stream << "[1;33m"; break;
00076 case C_WHITE: stream << "[1;37m"; break;
00077 }
00078 }
00079 return stream;
00080 }
00081
00082
00083
00084 struct Error::Private {
00085 EError type;
00086 string file;
00087 string msg;
00088 int lineno;
00089 string category;
00090 Token token;
00091 };
00092 Error::Error(EError type, std::string file, std::string msg, int lineno, std::string category, Token token):
00093 d(new Private)
00094 {
00095 d->type = type;
00096 d->file = file;
00097 d->msg = msg;
00098 d->lineno = lineno;
00099 d->category = category;
00100 d->token = token;
00101 }
00102 Error::Error(EError type, std::string file, std::string msg, Token token, bool internal):
00103 d(new Private)
00104 {
00105 d->type = type;
00106 d->file = file;
00107 d->msg = msg;
00108 d->lineno = token.lineno;
00109 if (internal) {
00110 d->category = "internal";
00111 d->token = token;
00112 } else if (!token.text.empty())
00113 d->category += string("'") + token.text + "'";
00114 }
00115 Error::~Error() {
00116 delete d;
00117 }
00118 std::ostream& operator<< (std::ostream &str, const Error &err) {
00119 str << err.d->file << ": ";
00120 if (err.d->lineno)
00121
00122 str << Color(C_LIGHT_GREEN) << err.d->lineno
00123 << Color(C_NO_COLOR) << ": ";
00124
00125 switch (err.d->type) {
00126 case E_ERROR:
00127 str << Color(C_LIGHT_RED) << "error"
00128 << Color(C_NO_COLOR) << ": ";
00129 break;
00130 case E_WARNING:
00131 str << Color(C_YELLOW) << "warrning"
00132 << Color(C_NO_COLOR) << ": ";
00133 break;
00134 case E_NOTE:
00135 str << Color(C_LIGHT_BLUE) << "note"
00136 << Color(C_NO_COLOR) << ": ";
00137 break;
00138 default:
00139 str << err.d->msg;
00140 return str;
00141 }
00142
00143 if (!err.d->category.empty())
00144
00145 str << Color(C_LIGHT_CYAN) << err.d->category
00146 << Color(C_NO_COLOR) << ": ";
00147
00148
00149 str << err.d->msg;
00150
00151 if (err.d->token.type != ETOKEN_NULL)
00152
00153 str << " "
00154 << Color(C_LIGHT_BLUE) << "[" << Color(C_NO_COLOR)
00155 << "caused by token " << err.d->token
00156 << Color(C_LIGHT_BLUE) << "]" << Color(C_NO_COLOR);
00157
00158 return str;
00159 }
00160 }
00161