mirror of
https://github.com/slorelee/wimbuilder2.git
synced 2025-05-06 18:25:51 +08:00
186 lines
3.8 KiB
C++
186 lines
3.8 KiB
C++
/*
|
|
* Colorizes standard output on Windows
|
|
* https://github.com/jeremejevs/cmdcolor
|
|
*/
|
|
|
|
#include <signal.h>
|
|
#include <cstring>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <windows.h>
|
|
|
|
using std::cin;
|
|
using std::cout;
|
|
using std::string;
|
|
using std::ostringstream;
|
|
|
|
HANDLE con;
|
|
CONSOLE_SCREEN_BUFFER_INFO definfo;
|
|
ostringstream tmpins;
|
|
const int ntow[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
|
|
|
|
void rawget(char &c) {
|
|
if (!cin.get(c).good()) {
|
|
throw -1;
|
|
}
|
|
}
|
|
|
|
void append(char c) {
|
|
tmpins << c;
|
|
}
|
|
|
|
void get(char &c) {
|
|
rawget(c);
|
|
append(c);
|
|
}
|
|
|
|
void reset() {
|
|
tmpins.str(string());
|
|
tmpins.clear();
|
|
}
|
|
|
|
void dump() {
|
|
cout << tmpins.str();
|
|
reset();
|
|
}
|
|
|
|
int parse(bool *fore) {
|
|
char c, d;
|
|
get(c);
|
|
c -= '0';
|
|
if (c == 0) {
|
|
throw -3;
|
|
}
|
|
|
|
get(d);
|
|
d -= '0';
|
|
if (c == 1) {
|
|
if (d != 0) {
|
|
throw -2;
|
|
}
|
|
get(d);
|
|
d -= '0';
|
|
}
|
|
|
|
if (d < 0 || d > 7) {
|
|
throw -2;
|
|
}
|
|
|
|
int res = ntow[d];
|
|
switch (c) {
|
|
case 3: {
|
|
*fore = true;
|
|
return res;
|
|
}
|
|
case 4: {
|
|
*fore = false;
|
|
return res << 4;
|
|
}
|
|
case 9: {
|
|
*fore = true;
|
|
return res + 8;
|
|
}
|
|
case 1: {
|
|
*fore = false;
|
|
return (res + 8) << 4;
|
|
}
|
|
default: {
|
|
throw -2;
|
|
}
|
|
}
|
|
}
|
|
|
|
void bye(int sig=0) {
|
|
if (con != NULL) {
|
|
SetConsoleTextAttribute(con, definfo.wAttributes);
|
|
}
|
|
|
|
exit(0);
|
|
}
|
|
|
|
int main() {
|
|
signal(SIGABRT, &bye);
|
|
signal(SIGINT, &bye);
|
|
signal(SIGTERM, &bye);
|
|
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
|
|
con = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
GetConsoleScreenBufferInfo(con, &definfo);
|
|
try {
|
|
char c;
|
|
while (true) {
|
|
try {
|
|
rawget(c);
|
|
if (c != '\\' && c != 27) {
|
|
cout << c;
|
|
continue;
|
|
}
|
|
|
|
append(c);
|
|
if (c == '\\') {
|
|
get(c);
|
|
if (c != '0') {
|
|
throw -2;
|
|
}
|
|
get(c);
|
|
if (c != '3') {
|
|
throw -2;
|
|
}
|
|
get(c);
|
|
if (c != '3') {
|
|
throw -2;
|
|
}
|
|
c = 27;
|
|
}
|
|
else if (c != 27) {
|
|
throw -2;
|
|
}
|
|
|
|
get(c);
|
|
if (c != '[') {
|
|
throw -2;
|
|
}
|
|
|
|
int res = 0;
|
|
bool fore;
|
|
do {
|
|
try {
|
|
res = parse(&fore) + (res & (fore ? 0xF0 : 0x0F));
|
|
}
|
|
catch (int e) {
|
|
if (-3 == e) {
|
|
res = definfo.wAttributes;
|
|
}
|
|
else {
|
|
throw;
|
|
}
|
|
}
|
|
|
|
get(c);
|
|
} while (c == ';');
|
|
|
|
if (c != 'm') {
|
|
throw -2;
|
|
}
|
|
|
|
SetConsoleTextAttribute(con, res);
|
|
reset();
|
|
}
|
|
catch (int e) {
|
|
if (-2 == e) {
|
|
dump();
|
|
continue;
|
|
}
|
|
else {
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (int e) {
|
|
}
|
|
|
|
bye();
|
|
return 0;
|
|
}
|