From e918dd8a279b4d4db2f2e6428b87c0ef6c06f174 Mon Sep 17 00:00:00 2001 From: anders_k Date: Wed, 9 Nov 2011 10:30:11 +0000 Subject: [PATCH] MakeNSIS console warn/err colors on Win32 git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6167 212acab6-be3b-0410-9dea-997c60f758d6 --- Source/build.cpp | 12 +++++----- Source/growbuf.cpp | 7 +++--- Source/icon.cpp | 2 +- Source/makenssi.cpp | 33 +++++++++++---------------- Source/mmap.cpp | 12 +++++----- Source/strlist.cpp | 3 +-- Source/strlist.h | 4 ++-- Source/tstring.cpp | 4 ++-- Source/util.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++- Source/util.h | 26 +++++++++++++++++++++ 10 files changed, 112 insertions(+), 46 deletions(-) diff --git a/Source/build.cpp b/Source/build.cpp index 498d1483..460760fe 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -3310,8 +3310,7 @@ void CEXEBuild::warning(const TCHAR *s, ...) notify(MAKENSIS_NOTIFY_WARNING,buf); if (display_warnings) { - _ftprintf(g_output,_T("warning: %s\n"),buf); - fflush(g_output); + PrintColorFmtMsg_WARN(_T("warning: %s\n"),buf); } } @@ -3332,8 +3331,7 @@ void CEXEBuild::warning_fl(const TCHAR *s, ...) notify(MAKENSIS_NOTIFY_WARNING,buf); if (display_warnings) { - _ftprintf(g_output,_T("warning: %s\n"),buf); - fflush(g_output); + PrintColorFmtMsg_WARN(_T("warning: %s\n"),buf); } } @@ -3353,8 +3351,7 @@ void CEXEBuild::ERROR_MSG(const TCHAR *s, ...) const notify(MAKENSIS_NOTIFY_ERROR,buf); if (display_errors) { - _ftprintf(g_output,_T("%s"),buf); - fflush(g_output); + PrintColorFmtMsg_ERR(_T("%s"),buf); } } } @@ -3389,13 +3386,14 @@ void CEXEBuild::print_warnings() if (!x || !display_warnings) return; TCHAR *p=m_warnings.get(); while (x>0) if (!p[--x]) nw++; + SetPrintColorWARN(); _ftprintf(g_output,_T("\n%d warning%s:\n"),nw,nw==1?_T(""):_T("s")); for (x = 0; x < nw; x ++) { _ftprintf(g_output,_T(" %s\n"),p); p+=_tcslen(p)+1; } - fflush(g_output); + FlushOutputAndResetPrintColor(); } void CEXEBuild::notify(notify_e code, const TCHAR *data) const diff --git a/Source/growbuf.cpp b/Source/growbuf.cpp index f0a7169a..17c651ad 100644 --- a/Source/growbuf.cpp +++ b/Source/growbuf.cpp @@ -23,6 +23,7 @@ #include // for f* #include // for std::min #include "tchar.h" +#include "util.h" #include "Platform.h" @@ -64,8 +65,7 @@ void GrowBuf::resize(int newlen) extern int g_display_errors; if (g_display_errors) { - _ftprintf(g_output,_T("\nack! realloc(%d) failed, trying malloc(%d)!\n"),m_alloc,newlen); - fflush(g_output); + PrintColorFmtMsg_ERR(_T("\nack! realloc(%d) failed, trying malloc(%d)!\n"),m_alloc,newlen); } m_alloc=newlen; // try to malloc the minimum needed n=malloc(m_alloc); @@ -74,8 +74,7 @@ void GrowBuf::resize(int newlen) extern void quit(); if (g_display_errors) { - _ftprintf(g_output,_T("\nInternal compiler error #12345: GrowBuf realloc/malloc(%d) failed.\n"),m_alloc); - fflush(g_output); + PrintColorFmtMsg_ERR(_T("\nInternal compiler error #12345: GrowBuf realloc/malloc(%d) failed.\n"),m_alloc); } quit(); } diff --git a/Source/icon.cpp b/Source/icon.cpp index 1564f9b2..67983b96 100644 --- a/Source/icon.cpp +++ b/Source/icon.cpp @@ -416,7 +416,7 @@ int generate_unicons_offsets(LPBYTE exeHeader, size_t exeHeaderSize, LPBYTE unin catch (const exception& e) { if (g_display_errors) - _ftprintf(g_output, _T("\nError generating uninstaller icon: %s -- failing!\n"), CtoTString(e.what())); + PrintColorFmtMsg_ERR(_T("\nError generating uninstaller icon: %s -- failing!\n"), CtoTString(e.what())); return 0; } diff --git a/Source/makenssi.cpp b/Source/makenssi.cpp index 3f5a6729..c4d0fc11 100644 --- a/Source/makenssi.cpp +++ b/Source/makenssi.cpp @@ -46,9 +46,8 @@ void quit() { if (g_display_errors) { - _ftprintf(g_output,_T("\nNote: you may have one or two (large) stale temporary file(s)\n") + PrintColorFmtMsg_WARN(_T("\nNote: you may have one or two (large) stale temporary file(s)\n") _T("left in your temporary directory (Generally this only happens on Windows 9x).\n")); - fflush(g_output); } exit(1); } @@ -56,6 +55,7 @@ void quit() static void myatexit() { dopause(); + ResetPrintColor(); if (g_output != stdout && g_output) fclose(g_output); #ifdef _WIN32 #ifdef _UNICODE @@ -68,8 +68,7 @@ static void sigint(int sig) { if (g_display_errors) { - _ftprintf(g_output,_T("\n\nAborting on Ctrl+C...\n")); - fflush(g_output); + PrintColorFmtMsg_WARN(_T("\n\nAborting on Ctrl+C...\n")); } quit(); } @@ -214,8 +213,7 @@ static int process_config(CEXEBuild& build, tstring& conf) { if (build.display_errors) { - _ftprintf(g_output,_T("Error in config on line %d -- aborting creation process\n"),build.linecnt); - fflush(g_output); + PrintColorFmtMsg_ERR(_T("Error in config on line %d -- aborting creation process\n"),build.linecnt); } return 1; } @@ -242,8 +240,7 @@ static int change_to_script_dir(CEXEBuild& build, tstring& script) { if (build.display_errors) { - _ftprintf(g_output,_T("Error changing directory to \"%s\"\n"),dir.c_str()); - fflush(g_output); + PrintColorFmtMsg_ERR(_T("Error changing directory to \"%s\"\n"),dir.c_str()); } return 1; } @@ -292,8 +289,7 @@ int _tmain(int argc, TCHAR **argv) } catch (exception& err) { - _ftprintf(g_output, _T("Error initalizing CEXEBuild: %s\n"), CtoTString(err.what())); - fflush(g_output); + PrintColorFmtMsg_ERR(_T("Error initalizing CEXEBuild: %s\n"), CtoTString(err.what())); return 1; } @@ -319,8 +315,8 @@ int _tmain(int argc, TCHAR **argv) g_output=FOPENTEXT(argv[tmpargpos]+2,"w"); if (!g_output) { - _tprintf(_T("Error opening output log for writing. Using stdout.\n")); - g_output=stdout; + g_output=stdout; // Needs to be set before calling PrintColorFmtMsg* + PrintColorFmtMsg_WARN(_T("Error opening output log for writing. Using stdout.\n")); } outputtried=1; } @@ -365,8 +361,8 @@ int _tmain(int argc, TCHAR **argv) g_output=FOPENTEXT(argv[argpos]+2,"w"); if (!g_output) { - if (build.display_errors) _tprintf(_T("Error opening output log for writing. Using stdout.\n")); - g_output=stdout; + g_output=stdout; // Needs to be set before calling PrintColorFmtMsg* + if (build.display_errors) PrintColorFmtMsg_WARN(_T("Error opening output log for writing. Using stdout.\n")); } outputtried=1; } @@ -508,8 +504,7 @@ int _tmain(int argc, TCHAR **argv) if (build.display_errors) { sfile[_tcslen(sfile)-4]=0; - _ftprintf(g_output,_T("Can't open script \"%s\"\n"),sfile); - fflush(g_output); + PrintColorFmtMsg_ERR(_T("Can't open script \"%s\"\n"),sfile); } return 1; } @@ -536,8 +531,7 @@ int _tmain(int argc, TCHAR **argv) { if (build.display_errors) { - _ftprintf(g_output,_T("Error in script \"%s\" on line %d -- aborting creation process\n"),sfile,build.linecnt); - fflush(g_output); + PrintColorFmtMsg_ERR(_T("Error in script \"%s\" on line %d -- aborting creation process\n"),sfile,build.linecnt); } return 1; } @@ -568,8 +562,7 @@ int _tmain(int argc, TCHAR **argv) { if (build.display_errors) { - _ftprintf(g_output,_T("Error - aborting creation process\n")); - fflush(g_output); + PrintColorFmtMsg_ERR(_T("Error - aborting creation process\n")); } return 1; } diff --git a/Source/mmap.cpp b/Source/mmap.cpp index 0684ba28..ba01ab85 100644 --- a/Source/mmap.cpp +++ b/Source/mmap.cpp @@ -17,7 +17,7 @@ #include "mmap.h" #include // for f* #include // for assert -#include "tchar.h" +#include "tchar.h" #include #ifndef _WIN32 # include // for freebsd @@ -26,6 +26,7 @@ # include # include #endif +#include "util.h" // ======== // MMapFile @@ -220,8 +221,7 @@ void MMapFile::resize(int newsize) extern void quit(); extern int g_display_errors; if (g_display_errors) { - _ftprintf(g_output,_T("\nInternal compiler error #12345: error creating mmap the size of %d.\n"), m_iSize); - fflush(g_output); + PrintColorFmtMsg_ERR(_T("\nInternal compiler error #12345: error creating mmap the size of %d.\n"), m_iSize); } quit(); } @@ -253,8 +253,7 @@ void *MMapFile::get(int offset, int *sizep) const extern void quit(); extern int g_display_errors; if (g_display_errors) { - _ftprintf(g_output,_T("\nInternal compiler error #12345: error mmapping file (%d, %d) is out of range.\n"), offset, size); - fflush(g_output); + PrintColorFmtMsg_ERR(_T("\nInternal compiler error #12345: error mmapping file (%d, %d) is out of range.\n"), offset, size); } quit(); } @@ -280,8 +279,7 @@ void *MMapFile::get(int offset, int *sizep) const extern void quit(); extern int g_display_errors; if (g_display_errors) { - _ftprintf(g_output,_T("\nInternal compiler error #12345: error mmapping datablock to %d.\n"), size); - fflush(g_output); + PrintColorFmtMsg_ERR(_T("\nInternal compiler error #12345: error mmapping datablock to %d.\n"), size); } quit(); } diff --git a/Source/strlist.cpp b/Source/strlist.cpp index 48214ad5..5d19d29b 100644 --- a/Source/strlist.cpp +++ b/Source/strlist.cpp @@ -233,8 +233,7 @@ int DefineList::add(const TCHAR *name, const TCHAR *value/*=_T("")*/) extern void quit(); if (g_display_errors) { - _ftprintf(g_output,_T("\nInternal compiler error #12345: GrowBuf realloc/malloc(%lu) failed.\n"), (unsigned long) size_in_bytes); - fflush(g_output); + PrintColorFmtMsg_ERR(_T("\nInternal compiler error #12345: GrowBuf realloc/malloc(%lu) failed.\n"), (unsigned long) size_in_bytes); } quit(); } diff --git a/Source/strlist.h b/Source/strlist.h index 4a974a4e..b25b66d6 100644 --- a/Source/strlist.h +++ b/Source/strlist.h @@ -24,6 +24,7 @@ #include #include "tchar.h" #include "growbuf.h" +#include "util.h" /** * Implements a list of strings mapped into a straight buffer. It is @@ -188,8 +189,7 @@ class SortedStringList extern void quit(); if (g_display_errors) { - _ftprintf(g_output,_T("\nInternal compiler error #12345: GrowBuf realloc/malloc(%lu) failed.\n"),(unsigned long)((_tcslen(name)+1)*sizeof(TCHAR))); - fflush(g_output); + PrintColorFmtMsg_ERR(_T("\nInternal compiler error #12345: GrowBuf realloc/malloc(%lu) failed.\n"),(unsigned long)((_tcslen(name)+1)*sizeof(TCHAR))); } quit(); } diff --git a/Source/tstring.cpp b/Source/tstring.cpp index f1b93cf5..7477a867 100644 --- a/Source/tstring.cpp +++ b/Source/tstring.cpp @@ -58,7 +58,7 @@ FILE* FileOpenUnicodeText(const TCHAR* file, const TCHAR* mode, BOOL* unicode) break; case CValidateUnicode::UTF_32LE: case CValidateUnicode::UTF_32BE: - _ftprintf(g_output, _T("File '%s' has a BOM marked as %s which is not supported at this time.\n"), + PrintColorFmtMsg_ERR(_T("File '%s' has a BOM marked as %s which is not supported at this time.\n"), file, CValidateUnicode::TypeToName(ftype)); exit(-1); break; @@ -72,7 +72,7 @@ FILE* FileOpenUnicodeText(const TCHAR* file, const TCHAR* mode, BOOL* unicode) } break; default: - _ftprintf(g_output, _T("CValidateUnicode::CheckBOM() for file '%s' returned an unknown return value: %d\n"), + PrintColorFmtMsg_ERR(_T("CValidateUnicode::CheckBOM() for file '%s' returned an unknown return value: %d\n"), file, ftype); exit(-1); break; diff --git a/Source/util.cpp b/Source/util.cpp index afce0508..dc3d488d 100644 --- a/Source/util.cpp +++ b/Source/util.cpp @@ -293,7 +293,7 @@ BOOL IsValidCodePage(UINT CodePage) return TRUE; } -#define MY_ERROR_MSG(x) {if (g_display_errors) {_ftprintf(g_output,_T("%s"), x);}} +#define MY_ERROR_MSG(x) {if (g_display_errors) {PrintColorFmtMsg_ERR(_T("%s"), x);}} TCHAR *my_convert(const TCHAR *path) { @@ -515,6 +515,59 @@ int sane_system(const TCHAR *command) { } +void PrintColorFmtMsg(unsigned int type, const TCHAR *fmtstr, va_list args) +{ +#ifdef _WIN32 + const HANDLE hWin32Con = GetStdHandle(STD_OUTPUT_HANDLE); + static INT32 contxtattrbak = -1; + WORD txtattr = 0; + if (contxtattrbak < 0) + { + if (-1 == contxtattrbak) + { + CONSOLE_SCREEN_BUFFER_INFO csbi; + contxtattrbak = -2; + if ( GetConsoleScreenBufferInfo(hWin32Con, &csbi) ) + { + contxtattrbak = csbi.wAttributes; + goto gottxtattrbak; + } + } + } + else + { +gottxtattrbak: + switch(type & 0xF) + { + case 0: goto resettxtattr; + case 1: txtattr = FOREGROUND_INTENSITY|FOREGROUND_GREEN|FOREGROUND_RED; break; + case 2: txtattr = FOREGROUND_INTENSITY|FOREGROUND_RED; break; + } + SetConsoleTextAttribute(hWin32Con, txtattr); + } +#endif + + if (fmtstr) _vftprintf(g_output, fmtstr, args); + fflush(g_output); + +#ifdef _WIN32 + if (contxtattrbak >= 0 && !(0x10 & type)) + { +resettxtattr: + SetConsoleTextAttribute(hWin32Con, contxtattrbak); + } +#endif +} + +void FlushOutputAndResetPrintColor() +{ + fflush(g_output); +#ifdef _WIN32 + PrintColorFmtMsg(0, NULL, (va_list)NULL); //va_list is just a pointer on windows so this is ok +#endif +} + + static bool GetDLLVersionUsingRE(const tstring& filepath, DWORD& high, DWORD & low) { bool found = false; diff --git a/Source/util.h b/Source/util.h index 5bed0f74..022d563b 100644 --- a/Source/util.h +++ b/Source/util.h @@ -56,6 +56,32 @@ tstring get_string_suffix(const tstring& str, const tstring& separator); int sane_system(const TCHAR *command); +void PrintColorFmtMsg(unsigned int type, const TCHAR *fmtstr, va_list args); +void FlushOutputAndResetPrintColor(); +#ifdef _WIN32 +#define ResetPrintColor() FlushOutputAndResetPrintColor() // For reset ONLY use PrintColorFmtMsg(0,NULL ... +#define SetPrintColorWARN() PrintColorFmtMsg(1|0x10, NULL, (va_list)NULL) +#define SetPrintColorERR() PrintColorFmtMsg(2|0x10, NULL, (va_list)NULL) +#else +#define ResetPrintColor() +#define SetPrintColorWARN() +#define SetPrintColorERR() +#endif +inline void PrintColorFmtMsg_WARN(const TCHAR *fmtstr, ...) +{ + va_list val; + va_start(val,fmtstr); + PrintColorFmtMsg(1, fmtstr, val); + va_end(val); +} +inline void PrintColorFmtMsg_ERR(const TCHAR *fmtstr, ...) +{ + va_list val; + va_start(val,fmtstr); + PrintColorFmtMsg(2, fmtstr, val); + va_end(val); +} + #ifndef _WIN32 TCHAR *CharPrev(const TCHAR *s, const TCHAR *p); TCHAR *CharNext(const TCHAR *s);