1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | /* colorout.hpp * (c) 2012 Daniel S. Roche, USNA * * The class colorout below provides the functionality of * cout or cerr (depending on the first constructor argument being * 1 or 2, respectively). The only difference is that the output * is printed in the color corresponding to the second argument. * You use it by first calling the constructor to make a new object: colorout out(1, 'r'); // r is for red * and then you can use that just like cout: out << "This is " << "all red!\n"; * Note that cout still prints in the default color. */ #include <unistd.h> // for isatty #include <cstdlib> // for exit #include <iostream> class colorbuf : public std::streambuf { private: int filedes; std::streambuf *dest; bool tty; char magic[7]; public: colorbuf (int fd, char color) { filedes = fd; if (filedes == 1) dest = std::cout.rdbuf(); else if (filedes == 2) dest = std::cerr.rdbuf(); else { std::cerr << "Illegal file descriptor in colorbuf constructor" << std::endl; exit(11); } tty = isatty(filedes); int colorcode; switch(color) { case 'b': colorcode = 30; break; // black case 'r': colorcode = 31; break; // red case 'g': colorcode = 32; break; // green case 'y': colorcode = 33; break; // yellow case 'u': colorcode = 34; break; // blue case 'w': colorcode = 37; break; // white default: std::cerr << "Illegal color for colorbuf" << std::endl; exit(12); } magic[0] = '\033'; magic[1] = '['; magic[2] = colorcode / 10 + '0'; magic[3] = colorcode % 10 + '0'; magic[4] = ';'; magic[5] = '1'; magic[6] = 'm'; } protected: virtual int overflow(int ch) { if (tty) dest->sputn(magic, 7); dest->sputc(ch); if (tty) dest->sputn("\033[0m", 4); } }; class colorout : public std::ostream { private: colorbuf buf; public: colorout(int fd, int cc) :buf(fd,cc), std::ostream(&buf) { } }; |