robIO.cc

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2008 Kamil Dudka <xdudka00@stud.fit.vutbr.cz>
00003  *
00004  * This file is part of rob08
00005  *
00006  * rob08 is free software: you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation, either version 3 of the License, or
00009  * any later version.
00010  *
00011  * rob08 is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with rob08.  If not, see <http://www.gnu.org/licenses/>.
00018  */
00019 
00020 #include "config.h"
00021 #include "robIO.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     // PrintHex implementation
00033     struct PrintHex::Private {
00034         unsigned number;
00035         unsigned width;
00036     };
00037     PrintHex::PrintHex(unsigned number, unsigned width):
00038         d(new Private)
00039     {
00040         d->number = number;
00041         d->width = width;
00042     }
00043     PrintHex::PrintHex(const PrintHex &other):
00044         d(new Private)
00045     {
00046         d->number = other.d->number;
00047         d->width = other.d->width;
00048     }
00049     PrintHex::~PrintHex() {
00050         delete d;
00051     }
00052     std::ostream& operator<< (std::ostream &stream, const PrintHex &obj) {
00053         stream
00054             << std::uppercase << std::setfill('0') << std::setw(obj.d->width) << std::hex << obj.d->number
00055             << std::resetiosflags(std::ios_base::hex) << std::resetiosflags(std::ios_base::uppercase);
00056         return stream;
00057     }
00058 
00059     // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00060     // Color implementation
00061     bool Color::useColors = false;
00062     struct Color::Private {
00063         EColor            color;
00064     };
00065     Color::Color(EColor color):
00066         d(new Private)
00067     {
00068         d->color = color;
00069     }
00070     Color::Color(const Color &cObj):
00071         d(new Private)
00072     {
00073         d->color = cObj.d->color;
00074     }
00075     Color::~Color() {
00076         delete d;
00077     }
00078     void Color::enable(bool b) {
00079         Color::useColors = b;
00080     }
00081     bool Color::isEnabled() {
00082         return Color::useColors;
00083     }
00084     std::ostream& operator<< (std::ostream &stream, const Color &cObj) {
00085         if (Color::useColors) {
00086             static const char ESC = '\033';
00087             stream << ESC;
00088             switch (cObj.d->color) {
00089                 case C_NO_COLOR:     stream << "[0m";    break;
00090                 case C_BLUE:         stream << "[0;34m"; break;
00091                 case C_GREEN:        stream << "[0;32m"; break;
00092                 case C_CYAN:         stream << "[0;36m"; break;
00093                 case C_RED:          stream << "[0;31m"; break;
00094                 case C_PURPLE:       stream << "[0;35m"; break;
00095                 case C_BROWN:        stream << "[0;33m"; break;
00096                 case C_LIGHT_GRAY:   stream << "[0;37m"; break;
00097                 case C_DARK_GRAY:    stream << "[1;30m"; break;
00098                 case C_LIGHT_BLUE:   stream << "[1;34m"; break;
00099                 case C_LIGHT_GREEN:  stream << "[1;32m"; break;
00100                 case C_LIGHT_CYAN:   stream << "[1;36m"; break;
00101                 case C_LIGHT_RED:    stream << "[1;31m"; break;
00102                 case C_LIGHT_PURPLE: stream << "[1;35m"; break;
00103                 case C_YELLOW:       stream << "[1;33m"; break;
00104                 case C_WHITE:        stream << "[1;37m"; break;
00105             }
00106         }
00107         return stream;
00108     }
00109 
00110     // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
00111     // Error implementation
00112     struct Error::Private {
00113         EError      type;
00114         string      file;
00115         string      msg;
00116         int         lineno;
00117         string      category;
00118         Token       token;
00119     };
00120     Error::Error(EError type, std::string file, std::string msg, int lineno, std::string category, Token token):
00121         d(new Private)
00122     {
00123         d->type     = type;
00124         d->file     = file;
00125         d->msg      = msg;
00126         d->lineno   = lineno;
00127         d->category = category;
00128         d->token    = token;
00129     }
00130     Error::Error(EError type, std::string file, std::string msg, Token token, bool internal):
00131         d(new Private)
00132     {
00133         d->type     = type;
00134         d->file     = file;
00135         d->msg      = msg;
00136         d->lineno   = token.lineno;
00137         if (internal) {
00138             d->category = "internal";
00139             d->token    = token;
00140         } else if (!token.text.empty())
00141             d->category += string("'") + token.text + "'";
00142     }
00143     Error::~Error() {
00144         delete d;
00145     }
00146     std::ostream& operator<< (std::ostream &str, const Error &err) {
00147         str << err.d->file << ": ";
00148         if (err.d->lineno)
00149             // print line number
00150             str << Color(C_LIGHT_GREEN) << err.d->lineno
00151                 << Color(C_NO_COLOR) << ": ";
00152 
00153         switch (err.d->type) {
00154             case E_ERROR:
00155                 str << Color(C_LIGHT_RED) << "error"
00156                     << Color(C_NO_COLOR) << ": ";
00157                 break;
00158             case E_WARNING:
00159                 str << Color(C_YELLOW) << "warrning"
00160                     << Color(C_NO_COLOR) << ": ";
00161                 break;
00162             case E_NOTE:
00163                 str << Color(C_LIGHT_BLUE) << "note"
00164                     << Color(C_NO_COLOR) << ": ";
00165                 break;
00166             default:
00167                 str << err.d->msg;
00168                 return str;
00169         }
00170 
00171         if (!err.d->category.empty())
00172             // print category
00173             str << Color(C_LIGHT_CYAN) << err.d->category
00174                 << Color(C_NO_COLOR) << ": ";
00175 
00176         // print message
00177         str << err.d->msg;
00178 
00179         if (err.d->token.type != ET_NULL)
00180             // print related token
00181             str << " "
00182                 << Color(C_LIGHT_BLUE) << "[" << Color(C_NO_COLOR)
00183                 << "caused by token " << err.d->token
00184                 << Color(C_LIGHT_BLUE) << "]" << Color(C_NO_COLOR);
00185 
00186         return str;
00187     }
00188 } // namespace StreamDecorator
00189 

Generated on Fri Jul 10 22:42:01 2009 for rob08 by  doxygen 1.5.4