Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

226 lines (181 sloc) 6.369 kB
/**************************************************************************
*
* Copyright 2010 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
**************************************************************************/
/*
* Helpers for coloring output.
*/
#ifndef _FORMATTER_HPP_
#define _FORMATTER_HPP_
#include <iostream>
#ifdef _WIN32
#include <windows.h>
#ifndef COMMON_LVB_LEADING_BYTE
#define COMMON_LVB_LEADING_BYTE 0x0100
#endif
#ifndef COMMON_LVB_TRAILING_BYTE
#define COMMON_LVB_TRAILING_BYTE 0x0200
#endif
#ifndef COMMON_LVB_GRID_HORIZONTAL
#define COMMON_LVB_GRID_HORIZONTAL 0x0400
#endif
#ifndef COMMON_LVB_GRID_LVERTICAL
#define COMMON_LVB_GRID_LVERTICAL 0x0800
#endif
#ifndef COMMON_LVB_GRID_RVERTICAL
#define COMMON_LVB_GRID_RVERTICAL 0x1000
#endif
#ifndef COMMON_LVB_REVERSE_VIDEO
#define COMMON_LVB_REVERSE_VIDEO 0x4000
#endif
#ifndef COMMON_LVB_UNDERSCORE
#define COMMON_LVB_UNDERSCORE 0x8000
#endif
#endif /* _WIN32 */
namespace formatter {
/*
* See also http://bytes.com/topic/c/answers/63822-design-question-little-c-header-colorizing-text-linux-comments-ideas
*/
class Attribute {
public:
virtual ~Attribute() {}
virtual void apply(std::ostream &) const {}
};
enum Color {
RED,
GREEN,
BLUE,
};
class Formatter {
public:
virtual ~Formatter() {}
virtual Attribute *normal(void) const { return new Attribute; }
virtual Attribute *bold(void) const { return new Attribute; }
virtual Attribute *italic(void) const { return new Attribute; }
virtual Attribute *strike(void) const { return new Attribute; }
virtual Attribute *color(Color) const { return new Attribute; }
};
class AnsiAttribute : public Attribute {
protected:
const char *escape;
public:
AnsiAttribute(const char *_escape) : escape(_escape) {}
void apply(std::ostream& os) const {
os << "\33[" << escape;
}
};
/**
* Formatter for plain-text files which outputs ANSI escape codes. See
* http://en.wikipedia.org/wiki/ANSI_escape_code for more information
* concerning ANSI escape codes.
*/
class AnsiFormatter : public Formatter {
protected:
public:
virtual Attribute *normal(void) const { return new AnsiAttribute("0m"); }
virtual Attribute *bold(void) const { return new AnsiAttribute("1m"); }
/* Italic is not widely supported, or worse, implemented with a reverse */
#if 0
virtual Attribute *italic(void) const { return new AnsiAttribute("3m"); }
#endif
virtual Attribute *strike(void) const { return new AnsiAttribute("9m"); }
virtual Attribute *color(Color c) const {
static const char *color_escapes[] = {
"31m", /* red */
"32m", /* green */
"34m", /* blue */
};
return new AnsiAttribute(color_escapes[c]);
}
};
inline std::ostream& operator<<(std::ostream& os, const Attribute *attr) {
attr->apply(os);
return os;
}
#ifdef _WIN32
class WindowsAttribute : public Attribute {
protected:
WORD wAttributes;
public:
WindowsAttribute(WORD _wAttributes) : wAttributes(_wAttributes) {}
void apply(std::ostream& os) const {
DWORD nStdHandleOutput;
if (os == std::cout) {
nStdHandleOutput = STD_OUTPUT_HANDLE;
} else if (os == std::cerr) {
nStdHandleOutput = STD_ERROR_HANDLE;
} else {
return;
}
HANDLE hConsoleOutput = GetStdHandle(nStdHandleOutput);
if (hConsoleOutput == INVALID_HANDLE_VALUE) {
return;
}
SetConsoleTextAttribute(hConsoleOutput, wAttributes);
}
};
/**
* Formatter for the Windows Console.
*/
class WindowsFormatter : public Formatter {
protected:
public:
virtual Attribute *normal(void) const { return new WindowsAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); }
virtual Attribute *bold(void) const { return new WindowsAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY); }
virtual Attribute *italic(void) const { return new WindowsAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); }
virtual Attribute *strike(void) const { return new WindowsAttribute(COMMON_LVB_REVERSE_VIDEO | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED); }
virtual Attribute *color(Color c) const {
static const WORD color_escapes[] = {
FOREGROUND_RED | FOREGROUND_INTENSITY,
FOREGROUND_GREEN | FOREGROUND_INTENSITY,
FOREGROUND_BLUE | FOREGROUND_INTENSITY,
};
return new WindowsAttribute(color_escapes[c]);
}
};
#endif /* _WIN32 */
inline Formatter *defaultFormatter(bool color = true) {
if (color) {
#ifdef _WIN32
// http://wiki.winehq.org/DeveloperFaq#detect-wine
static HMODULE hNtDll = NULL;
static bool bWine = false;
if (!hNtDll) {
hNtDll = LoadLibraryA("ntdll");
if (hNtDll) {
bWine = GetProcAddress(hNtDll, "wine_get_version") != NULL;
}
}
if (bWine) {
return new AnsiFormatter;
}
return new WindowsFormatter;
#else
return new AnsiFormatter;
#endif
} else {
return new Formatter;
}
}
} /* namespace formatter */
#endif /* _FORMATTER_HPP_ */
Jump to Line
Something went wrong with that request. Please try again.