Color print on Visual Studio older than 2019
nikishyn opened this issue · comments
- Hi, when running tests I have printed:
�[32m[==========]�[0m Running 1 test cases.
�[32m[ RUN ]�[0m Test0.uint8Test_default
�[32m[ OK ]�[0m Test0.uint8Test_default (7700ns)
�[32m[==========]�[0m 1 test cases ran.
�[32m[ PASSED ]�[0m 1 tests.
Windows 10 Pro, Vers 1909, Build: 18363.1139
MSVC 2015.
- it seems on line 923 there is an attempt to read an uninitialized variable.
utest_state.tests[index].func(&result, utest_state.tests[index].index);
This looks similar to what #40 tried to fix.
I'm also have the same issue on windows 10 with visual studio 2017, it seems that on visual studio 2019 is ok.
If someone wants to try land a PR I'll gladly accept it!
There is nothing wrong with Neals code. Do not try to change it. Using utest.h
or ubench.h
from the windows console app does require the following:
- in your main() please do
system(" ");
Notice that is one space in there. That will "kick start" cmd.exe into properly interpreting VT100 escape codes
- after that use your favorite solution to check the Windows version at runtime. And it has to be equal or higher than
10.0.14393
- Then please do
/* for building also require WIN10 as minimum */
#include <winsdkver.h>
#ifndef WINVER
#define WINVER 0x0A00
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0A00
#endif
To give full and proper advice here is the code to check the Windows version at runtime:
#include <winsdkver.h>
#ifndef WINVER
#define WINVER 0x0A00
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0A00
#endif
#ifdef __STDC_ALLOC_LIB__
#define __STDC_WANT_LIB_EXT2__ 1
#else
#define _POSIX_C_SOURCE 200809L
#endif
#define NOMINMAX
#define STRICT 1
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <processenv.h>
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#error ENABLE_VIRTUAL_TERMINAL_PROCESSING not found? Try Visual Studio solution re-targeting to the latest SDK.
#endif
#ifdef NOMINMAX
#undef min
#define min(x, y) ((x) < (y) ? (x) : (y))
#undef max
#define max(x, y) ((x) > (y) ? (x) : (y))
#endif // NOMINIMAX
. . .
// we emulate _OSVERSIONINFOA and return osinfo_struct to the callers
typedef struct osinfo_struct {
long size_info_;
long major;
long minor;
long build_num;
long platform_id;
char csd_version[128]; // Maintenance string for PSS usage
} osinfo, * osinfo_ptr;
// probably the only sure-fire way to obtain windows version
inline osinfo get_win_version(void)
{
typedef LONG NTSTATUS; // , * PNTSTATUS{};
typedef NTSTATUS(WINAPI* get_version_fp)(osinfo_ptr);
static HMODULE hMod = ::GetModuleHandleA("ntdll.dll");
if (hMod) {
static get_version_fp fxPtr =
(get_version_fp)::GetProcAddress(hMod, "RtlGetVersion");
_ASSERTE(fxPtr != nullptr);
if (fxPtr != nullptr) {
osinfo osinfo_var_ = { 0 };
osinfo_var_.size_info_ = sizeof(osinfo_var_);
if ((0x00000000) == fxPtr(&osinfo_var_)) {
return osinfo_var_;
}
}
}
static osinfo osinfo_empty_ = { 0, 0, 0, 0, 0, {0} };
return osinfo_empty_;
} // get_win_version
#define IS_OS_INFO_EMPTY(info_) (0 == info_.major)
Now another helper function to return true if Windows version is greater than or equal to the specified number
inline bool is_win_ver_or_greater(WORD major_ver, WORD minor_ver,
WORD build_ver) {
osinfo ver_info_ = get_win_version();
if (IS_OS_INFO_EMPTY(ver_info_))
return false;
if (ver_info_.major > major_ver)
return true;
else if (ver_info_.major < major_ver)
return false;
if (ver_info_.minor > minor_ver)
return true;
else if (ver_info_.minor < minor_ver)
return false;
// we are here because both major and minor are equal
if (ver_info_.build_num >= build_ver)
return true;
return false;
}
#undef IS_OS_INFO_EMPTY
In my code I call this first upon entering main()
.
extern "C"
inline void os_check(void) {
if (false == is_win_ver_or_greater(10, 0, 14393))
{
puts("");
puts("FATAL -- ERROR ");
puts("");
puts("Minimum Windows version required is 10.0.14393");
perror(" Exiting ...");
__fastfail(FAST_FAIL_FATAL_APP_EXIT);
}
}
If the Windows version is equal to or greater than 10.0.14393 then ENABLE_VIRTUAL_TERMINAL_PROCESSING
is
supported. That is: cmd.exe is capable of handling VT100 color codes after doing system(" ")
Many thanks for reading.
@DBJDBJ thanks for the brain dump, but I've got to say whether you intended it or not it did indeed come across as patronizing. Information == good, drama == bad.
Rectified
I can confirm as of today (2021-07-13) that is still needed ... My Windows (as of today) is:
Microsoft Windows [Version 10.0.19042.1052]
If one is using Visual Code terminal to run her console exe's using UTEST.h or (whatever else using VT100 ESC) console output colouring will work just if one places system(" ")
in her main, no other shenanigans necessary.
UTEST_STATE();
int main(int argc, const char* const argv[]) {
#ifdef WIN32
// VT100 ESC codes kick-start hack
// 2021-07-10
// Microsoft Windows [Version 10.0.19042.1052]
// Advice: Your console exe from the V.Code terminal window
// will show proper colouring after this
// standard cmd.exe is still hit-and-miss
system(" ");
#endif
return utest_main(argc, argv);
}
I'm also have the same issue on windows 10 with visual studio 2017, it seems that on visual studio 2019 is ok.
The issue is attached to the Windows version, not the Visual Studio version.