Colorize diagnostics.
This commit is contained in:
@@ -106,6 +106,7 @@ Short options:
|
|||||||
Long options:
|
Long options:
|
||||||
--auto-import Mark unresolved symbols as import
|
--auto-import Mark unresolved symbols as import
|
||||||
--bin-include-dir dir Set a search path for binary includes
|
--bin-include-dir dir Set a search path for binary includes
|
||||||
|
--color [on|auto|off] Color diagnostics (default: auto)
|
||||||
--cpu type Set cpu type
|
--cpu type Set cpu type
|
||||||
--create-dep name Create a make dependency file
|
--create-dep name Create a make dependency file
|
||||||
--create-full-dep name Create a full make dependency file
|
--create-full-dep name Create a full make dependency file
|
||||||
@@ -120,7 +121,7 @@ Long options:
|
|||||||
--list-bytes n Maximum number of bytes per listing line
|
--list-bytes n Maximum number of bytes per listing line
|
||||||
--memory-model model Set the memory model
|
--memory-model model Set the memory model
|
||||||
--pagelength n Set the page length for the listing
|
--pagelength n Set the page length for the listing
|
||||||
--relax-checks Disables some error checks
|
--relax-checks Relax some checks (see docs)
|
||||||
--smart Enable smart mode
|
--smart Enable smart mode
|
||||||
--target sys Set the target system
|
--target sys Set the target system
|
||||||
--verbose Increase verbosity
|
--verbose Increase verbosity
|
||||||
@@ -146,6 +147,14 @@ Here is a description of all the command line options:
|
|||||||
name="search paths">.
|
name="search paths">.
|
||||||
|
|
||||||
|
|
||||||
|
<label id="option-color">
|
||||||
|
<tag><tt>--color</tt></tag>
|
||||||
|
|
||||||
|
This option controls if the assembler will use colors when printing
|
||||||
|
diagnostics. The default is "auto" which will enable colors if the output
|
||||||
|
goes to a terminal (not to a file).
|
||||||
|
|
||||||
|
|
||||||
<label id="option--cpu">
|
<label id="option--cpu">
|
||||||
<tag><tt>--cpu type</tt></tag>
|
<tag><tt>--cpu type</tt></tag>
|
||||||
|
|
||||||
@@ -186,12 +195,6 @@ Here is a description of all the command line options:
|
|||||||
information to the assembler.
|
information to the assembler.
|
||||||
|
|
||||||
|
|
||||||
<tag><tt>-d, --debug</tt></tag>
|
|
||||||
|
|
||||||
Enables debug mode, something that should not be needed for mere
|
|
||||||
mortals:-)
|
|
||||||
|
|
||||||
|
|
||||||
<label id="option--feature">
|
<label id="option--feature">
|
||||||
<tag><tt>--feature name</tt></tag>
|
<tag><tt>--feature name</tt></tag>
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,8 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
|
#include "cmdline.h"
|
||||||
|
#include "consprop.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
|
|
||||||
/* ca65 */
|
/* ca65 */
|
||||||
@@ -45,6 +47,7 @@
|
|||||||
#include "filetab.h"
|
#include "filetab.h"
|
||||||
#include "lineinfo.h"
|
#include "lineinfo.h"
|
||||||
#include "nexttok.h"
|
#include "nexttok.h"
|
||||||
|
#include "spool.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -64,6 +67,14 @@ unsigned WarningCount = 0;
|
|||||||
/* Maximum number of additional notifications */
|
/* Maximum number of additional notifications */
|
||||||
#define MAX_NOTES 8
|
#define MAX_NOTES 8
|
||||||
|
|
||||||
|
/* Diagnostic category */
|
||||||
|
typedef enum { DC_NOTE, DC_WARN, DC_ERR, DC_FATAL, DC_COUNT } DiagCat;
|
||||||
|
|
||||||
|
/* Descriptions for diagnostic categories */
|
||||||
|
const char* DiagCatDesc[DC_COUNT] = {
|
||||||
|
"Note", "Warning", "Error", "Fatal error"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -72,27 +83,53 @@ unsigned WarningCount = 0;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void VPrintMsg (const FilePos* Pos, const char* Desc,
|
static void VPrintMsg (const FilePos* Pos, DiagCat Cat, const char* Format,
|
||||||
const char* Format, va_list ap)
|
va_list ap)
|
||||||
/* Format and output an error/warning message. */
|
/* Format and output an error/warning message. */
|
||||||
{
|
{
|
||||||
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
StrBuf S = AUTO_STRBUF_INITIALIZER;
|
||||||
|
StrBuf Msg = AUTO_STRBUF_INITIALIZER;
|
||||||
|
StrBuf Loc = AUTO_STRBUF_INITIALIZER;
|
||||||
|
|
||||||
|
/* Determine the description for the category and its color */
|
||||||
|
const char* Desc = DiagCatDesc[Cat];
|
||||||
|
const char* Color;
|
||||||
|
switch (Cat) {
|
||||||
|
case DC_NOTE: Color = CP_Cyan (); break;
|
||||||
|
case DC_WARN: Color = CP_Yellow (); break;
|
||||||
|
case DC_ERR: Color = CP_BrightRed (); break;
|
||||||
|
case DC_FATAL: Color = CP_BrightRed (); break;
|
||||||
|
default: FAIL ("Unexpected Cat value"); break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Format the actual message */
|
/* Format the actual message */
|
||||||
StrBuf Msg = STATIC_STRBUF_INITIALIZER;
|
|
||||||
SB_VPrintf (&Msg, Format, ap);
|
SB_VPrintf (&Msg, Format, ap);
|
||||||
SB_Terminate (&Msg);
|
SB_Terminate (&Msg);
|
||||||
|
|
||||||
/* Format the message header */
|
/* Format the location. If the file position is valid, we use the file
|
||||||
SB_Printf (&S, "%s:%u: %s: ",
|
** position, otherwise the program name. This allows to print fatal
|
||||||
SB_GetConstBuf (GetFileName (Pos->Name)),
|
** errors in the startup phase.
|
||||||
Pos->Line,
|
*/
|
||||||
Desc);
|
if (Pos->Name == EMPTY_STRING_ID) {
|
||||||
|
SB_CopyStr (&Loc, ProgName);
|
||||||
|
} else {
|
||||||
|
SB_Printf (&Loc, "%s:%u", SB_GetConstBuf (GetFileName (Pos->Name)),
|
||||||
|
Pos->Line);
|
||||||
|
}
|
||||||
|
SB_Terminate (&Loc);
|
||||||
|
|
||||||
/* Append the message to the message header */
|
/* Format the full message */
|
||||||
SB_Append (&S, &Msg);
|
SB_Printf (&S, "%s%s: %s%s:%s %s%s",
|
||||||
|
CP_White (),
|
||||||
|
SB_GetConstBuf (&Loc),
|
||||||
|
Color,
|
||||||
|
Desc,
|
||||||
|
CP_White (),
|
||||||
|
SB_GetConstBuf (&Msg),
|
||||||
|
CP_Reset ());
|
||||||
|
|
||||||
/* Delete the formatted message */
|
/* Delete the formatted message and the location string */
|
||||||
|
SB_Done (&Loc);
|
||||||
SB_Done (&Msg);
|
SB_Done (&Msg);
|
||||||
|
|
||||||
/* Add a new line and terminate the generated full message */
|
/* Add a new line and terminate the generated full message */
|
||||||
@@ -183,7 +220,7 @@ void PNotification (const FilePos* Pos, const char* Format, ...)
|
|||||||
/* Output the message */
|
/* Output the message */
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
VPrintMsg (Pos, "Note", Format, ap);
|
VPrintMsg (Pos, DC_NOTE, Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +239,7 @@ static void WarningMsg (const Collection* LineInfos, const char* Format, va_list
|
|||||||
const LineInfo* LI = CollConstAt (LineInfos, 0);
|
const LineInfo* LI = CollConstAt (LineInfos, 0);
|
||||||
|
|
||||||
/* Output a warning for this position */
|
/* Output a warning for this position */
|
||||||
VPrintMsg (GetSourcePos (LI), "Warning", Format, ap);
|
VPrintMsg (GetSourcePos (LI), DC_WARN, Format, ap);
|
||||||
|
|
||||||
/* Add additional notifications if necessary */
|
/* Add additional notifications if necessary */
|
||||||
AddNotifications (LineInfos);
|
AddNotifications (LineInfos);
|
||||||
@@ -243,7 +280,7 @@ void PWarning (const FilePos* Pos, unsigned Level, const char* Format, ...)
|
|||||||
if (Level <= WarnLevel) {
|
if (Level <= WarnLevel) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
VPrintMsg (Pos, "Warning", Format, ap);
|
VPrintMsg (Pos, DC_WARN, Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
/* Count warnings */
|
/* Count warnings */
|
||||||
@@ -280,7 +317,7 @@ void ErrorMsg (const Collection* LineInfos, const char* Format, va_list ap)
|
|||||||
const LineInfo* LI = CollConstAt (LineInfos, 0);
|
const LineInfo* LI = CollConstAt (LineInfos, 0);
|
||||||
|
|
||||||
/* Output an error for this position */
|
/* Output an error for this position */
|
||||||
VPrintMsg (GetSourcePos (LI), "Error", Format, ap);
|
VPrintMsg (GetSourcePos (LI), DC_ERR, Format, ap);
|
||||||
|
|
||||||
/* Add additional notifications if necessary */
|
/* Add additional notifications if necessary */
|
||||||
AddNotifications (LineInfos);
|
AddNotifications (LineInfos);
|
||||||
@@ -317,7 +354,7 @@ void PError (const FilePos* Pos, const char* Format, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
VPrintMsg (Pos, "Error", Format, ap);
|
VPrintMsg (Pos, DC_ERR, Format, ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
/* Count errors */
|
/* Count errors */
|
||||||
@@ -371,18 +408,12 @@ void ErrorSkip (const char* Format, ...)
|
|||||||
void Fatal (const char* Format, ...)
|
void Fatal (const char* Format, ...)
|
||||||
/* Print a message about a fatal error and die */
|
/* Print a message about a fatal error and die */
|
||||||
{
|
{
|
||||||
|
/* Output the message ... */
|
||||||
va_list ap;
|
va_list ap;
|
||||||
StrBuf S = STATIC_STRBUF_INITIALIZER;
|
|
||||||
|
|
||||||
va_start (ap, Format);
|
va_start (ap, Format);
|
||||||
SB_VPrintf (&S, Format, ap);
|
VPrintMsg (&CurTok.Pos, DC_FATAL, Format, ap);
|
||||||
SB_Terminate (&S);
|
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
fprintf (stderr, "Fatal error: %s\n", SB_GetConstBuf (&S));
|
|
||||||
|
|
||||||
SB_Done (&S);
|
|
||||||
|
|
||||||
/* And die... */
|
/* And die... */
|
||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include "addrsize.h"
|
#include "addrsize.h"
|
||||||
#include "chartype.h"
|
#include "chartype.h"
|
||||||
#include "cmdline.h"
|
#include "cmdline.h"
|
||||||
|
#include "consprop.h"
|
||||||
#include "debugflag.h"
|
#include "debugflag.h"
|
||||||
#include "mmodel.h"
|
#include "mmodel.h"
|
||||||
#include "print.h"
|
#include "print.h"
|
||||||
@@ -111,6 +112,7 @@ static void Usage (void)
|
|||||||
"Long options:\n"
|
"Long options:\n"
|
||||||
" --auto-import\t\t\tMark unresolved symbols as import\n"
|
" --auto-import\t\t\tMark unresolved symbols as import\n"
|
||||||
" --bin-include-dir dir\t\tSet a search path for binary includes\n"
|
" --bin-include-dir dir\t\tSet a search path for binary includes\n"
|
||||||
|
" --color [on|auto|off]\t\tColor diagnostics (default: auto)\n"
|
||||||
" --cpu type\t\t\tSet cpu type\n"
|
" --cpu type\t\t\tSet cpu type\n"
|
||||||
" --create-dep name\t\tCreate a make dependency file\n"
|
" --create-dep name\t\tCreate a make dependency file\n"
|
||||||
" --create-full-dep name\tCreate a full make dependency file\n"
|
" --create-full-dep name\tCreate a full make dependency file\n"
|
||||||
@@ -129,7 +131,8 @@ static void Usage (void)
|
|||||||
" --smart\t\t\tEnable smart mode\n"
|
" --smart\t\t\tEnable smart mode\n"
|
||||||
" --target sys\t\t\tSet the target system\n"
|
" --target sys\t\t\tSet the target system\n"
|
||||||
" --verbose\t\t\tIncrease verbosity\n"
|
" --verbose\t\t\tIncrease verbosity\n"
|
||||||
" --version\t\t\tPrint the assembler version\n",
|
" --version\t\t\tPrint the assembler version\n"
|
||||||
|
" --warnings-as-errors\t\tTreat warnings as errors\n",
|
||||||
ProgName);
|
ProgName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,6 +495,22 @@ static void OptBinIncludeDir (const char* Opt attribute ((unused)), const char*
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void OptColor(const char* Opt, const char* Arg)
|
||||||
|
/* Handle the --color option */
|
||||||
|
{
|
||||||
|
if (strcmp (Arg, "off") == 0 || strcmp (Arg, "false") == 0) {
|
||||||
|
CP_SetColorMode (CM_OFF);
|
||||||
|
} else if (strcmp (Arg, "auto") == 0) {
|
||||||
|
CP_SetColorMode (CM_AUTO);
|
||||||
|
} else if (strcmp (Arg, "on") == 0 || strcmp (Arg, "true") == 0) {
|
||||||
|
CP_SetColorMode (CM_ON);
|
||||||
|
} else {
|
||||||
|
AbEnd ("Invalid argument to %s: %s", Opt, Arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void OptCPU (const char* Opt attribute ((unused)), const char* Arg)
|
static void OptCPU (const char* Opt attribute ((unused)), const char* Arg)
|
||||||
/* Handle the --cpu option */
|
/* Handle the --cpu option */
|
||||||
{
|
{
|
||||||
@@ -1013,6 +1032,7 @@ int main (int argc, char* argv [])
|
|||||||
static const LongOpt OptTab[] = {
|
static const LongOpt OptTab[] = {
|
||||||
{ "--auto-import", 0, OptAutoImport },
|
{ "--auto-import", 0, OptAutoImport },
|
||||||
{ "--bin-include-dir", 1, OptBinIncludeDir },
|
{ "--bin-include-dir", 1, OptBinIncludeDir },
|
||||||
|
{ "--color", 1, OptColor },
|
||||||
{ "--cpu", 1, OptCPU },
|
{ "--cpu", 1, OptCPU },
|
||||||
{ "--create-dep", 1, OptCreateDep },
|
{ "--create-dep", 1, OptCreateDep },
|
||||||
{ "--create-full-dep", 1, OptCreateFullDep },
|
{ "--create-full-dep", 1, OptCreateFullDep },
|
||||||
@@ -1040,6 +1060,9 @@ int main (int argc, char* argv [])
|
|||||||
|
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
|
/* Initialize console output */
|
||||||
|
CP_Init ();
|
||||||
|
|
||||||
/* Initialize the cmdline module */
|
/* Initialize the cmdline module */
|
||||||
InitCmdLine (&argc, &argv, "ca65");
|
InitCmdLine (&argc, &argv, "ca65");
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2026, Kugelfuhr */
|
/* (C) 2025, Kugelfuhr */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
|
|||||||
208
src/common/consprop.c
Normal file
208
src/common/consprop.c
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* consprop.c */
|
||||||
|
/* */
|
||||||
|
/* Console properties */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* (C) 2025, Kugelfuhr */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
|
/* warranty. In no event will the authors be held liable for any damages */
|
||||||
|
/* arising from the use of this software. */
|
||||||
|
/* */
|
||||||
|
/* Permission is granted to anyone to use this software for any purpose, */
|
||||||
|
/* including commercial applications, and to alter it and redistribute it */
|
||||||
|
/* freely, subject to the following restrictions: */
|
||||||
|
/* */
|
||||||
|
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||||
|
/* claim that you wrote the original software. If you use this software */
|
||||||
|
/* in a product, an acknowledgment in the product documentation would be */
|
||||||
|
/* appreciated but is not required. */
|
||||||
|
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||||
|
/* be misrepresented as being the original software. */
|
||||||
|
/* 3. This notice may not be removed or altered from any source */
|
||||||
|
/* distribution. */
|
||||||
|
/* */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#define isatty _isatty
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "consprop.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Data */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
static unsigned CodePage; /* Windows code page on startup */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* State variables */
|
||||||
|
static int IsTTY = 1; /* True if console is a tty */
|
||||||
|
static int IsUTF8 = 1; /* True if console is in UTF-8 mode */
|
||||||
|
static int Color = 0; /* True if we should use color */
|
||||||
|
static ColorMode CMode = CM_AUTO; /* Current color mode */
|
||||||
|
|
||||||
|
/* ANSI escape sequences for color */
|
||||||
|
const char CP_ColorSeq[CC_COUNT][2][8] = {
|
||||||
|
{ "", "\x1b[30m", }, /* Black */
|
||||||
|
{ "", "\x1b[31m", }, /* Red */
|
||||||
|
{ "", "\x1b[32m", }, /* Green */
|
||||||
|
{ "", "\x1b[33m", }, /* Brown */
|
||||||
|
{ "", "\x1b[34m", }, /* Blue */
|
||||||
|
{ "", "\x1b[35m", }, /* Magenta */
|
||||||
|
{ "", "\x1b[36m", }, /* Cyan */
|
||||||
|
{ "", "\x1b[37m", }, /* LightGray */
|
||||||
|
{ "", "\x1b[90m", }, /* Gray */
|
||||||
|
{ "", "\x1b[91m", }, /* BrightRed */
|
||||||
|
{ "", "\x1b[92m", }, /* BrightGreen */
|
||||||
|
{ "", "\x1b[93m", }, /* Yellow */
|
||||||
|
{ "", "\x1b[94m", }, /* BrightBlue */
|
||||||
|
{ "", "\x1b[95m", }, /* BrightMagenta */
|
||||||
|
{ "", "\x1b[96m", }, /* BrightCyan */
|
||||||
|
{ "", "\x1b[97m", }, /* White */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Box drawing sequences */
|
||||||
|
const char CP_BoxDrawingSeq[BD_COUNT][2][4] = {
|
||||||
|
{ "-", "\xE2\x94\x80", }, /* "─" - Horizontal */
|
||||||
|
{ "|", "\xE2\x94\x82", }, /* "│" - Vertical */
|
||||||
|
{ "+", "\xE2\x94\x8C", }, /* "┌" - ULCorner */
|
||||||
|
{ "+", "\xE2\x94\x94", }, /* "└" - LLCorner */
|
||||||
|
{ "+", "\xE2\x94\x90", }, /* "┐" - URCorner */
|
||||||
|
{ "+", "\xE2\x94\x98", }, /* "┘" - LRCorner */
|
||||||
|
{ "+", "\xE2\x94\x9C", }, /* "├" - VerticalRight */
|
||||||
|
{ "+", "\xE2\x94\xA4", }, /* "┤" - VerticalLeft */
|
||||||
|
{ "+", "\xE2\x94\xAC", }, /* "┬" - HorizontalDown */
|
||||||
|
{ "+", "\xE2\x94\xB4", }, /* "┴" - HorizontalUp */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Helpers */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
static void Cleanup()
|
||||||
|
/* Cleanup on program exit */
|
||||||
|
{
|
||||||
|
SetConsoleOutputCP (CodePage);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Code */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void CP_Init (void)
|
||||||
|
/* Init console properties. Must be called before using any other function or
|
||||||
|
** data from this module.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
IsTTY = (isatty (STDOUT_FILENO) && isatty (STDERR_FILENO));
|
||||||
|
CP_SetColorMode (CMode);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (IsTTY) {
|
||||||
|
CodePage = GetConsoleOutputCP ();
|
||||||
|
if (SetConsoleOutputCP (CP_UTF8)) {
|
||||||
|
IsUTF8 = 1;
|
||||||
|
atexit (Cleanup);
|
||||||
|
}
|
||||||
|
if (Color) {
|
||||||
|
HANDLE StdOut = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||||
|
if (StdOut != INVALID_HANDLE_VALUE) {
|
||||||
|
DWORD Mode;
|
||||||
|
if (GetConsoleMode (StdOut, &Mode)) {
|
||||||
|
Mode |= ENABLE_PROCESSED_OUTPUT |
|
||||||
|
ENABLE_VIRTUAL_TERMINAL_PROCESSING;
|
||||||
|
SetConsoleMode (StdOut, Mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int CP_IsTTY (void)
|
||||||
|
/* Return true if console output goes to a tty */
|
||||||
|
{
|
||||||
|
return IsTTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int CP_IsUTF8 (void)
|
||||||
|
/* Return true if the console supports UTF-8 */
|
||||||
|
{
|
||||||
|
return IsUTF8;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int CP_HasColor (void)
|
||||||
|
/* Return true if the console supports color and it should be used */
|
||||||
|
{
|
||||||
|
return Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ColorMode CP_GetColorMode (void)
|
||||||
|
/* Return the current color mode */
|
||||||
|
{
|
||||||
|
return CMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void CP_SetColorMode (ColorMode M)
|
||||||
|
/* Set the color mode */
|
||||||
|
{
|
||||||
|
CMode = M;
|
||||||
|
switch (CMode) {
|
||||||
|
case CM_AUTO: Color = IsTTY; break;
|
||||||
|
case CM_ON: Color = 1; break;
|
||||||
|
default: Color = 0; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void CP_DisableUTF8 (void)
|
||||||
|
/* Disable UTF-8 support */
|
||||||
|
{
|
||||||
|
IsUTF8 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void CP_EnableUTF8 (void)
|
||||||
|
/* Enable UTF-8 support */
|
||||||
|
{
|
||||||
|
IsUTF8 = 1;
|
||||||
|
}
|
||||||
174
src/common/consprop.h
Normal file
174
src/common/consprop.h
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* consprop.h */
|
||||||
|
/* */
|
||||||
|
/* Console properties */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* (C) 2025, Kugelfuhr */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
|
/* warranty. In no event will the authors be held liable for any damages */
|
||||||
|
/* arising from the use of this software. */
|
||||||
|
/* */
|
||||||
|
/* Permission is granted to anyone to use this software for any purpose, */
|
||||||
|
/* including commercial applications, and to alter it and redistribute it */
|
||||||
|
/* freely, subject to the following restrictions: */
|
||||||
|
/* */
|
||||||
|
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||||
|
/* claim that you wrote the original software. If you use this software */
|
||||||
|
/* in a product, an acknowledgment in the product documentation would be */
|
||||||
|
/* appreciated but is not required. */
|
||||||
|
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||||
|
/* be misrepresented as being the original software. */
|
||||||
|
/* 3. This notice may not be removed or altered from any source */
|
||||||
|
/* distribution. */
|
||||||
|
/* */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CONSPROP_H
|
||||||
|
#define CONSPROP_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "check.h"
|
||||||
|
#include "consprop.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Data */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Color mode for the program */
|
||||||
|
enum ColorMode { CM_OFF, CM_AUTO, CM_ON };
|
||||||
|
typedef enum ColorMode ColorMode;
|
||||||
|
|
||||||
|
/* Colors */
|
||||||
|
enum ConsoleColor {
|
||||||
|
CC_BLACK, CC_RED, CC_GREEN, CC_BROWN,
|
||||||
|
CC_BLUE, CC_MAGENTA, CC_CYAN, CC_LIGHTGRAY,
|
||||||
|
CC_GRAY, CC_BRIGHTRED, CC_BRIGHTGREEN, CC_YELLOW,
|
||||||
|
CC_BRIGHTBLUE, CC_BRIGHTMAGENTA, CC_BRIGHTCYAN, CC_WHITE,
|
||||||
|
CC_COUNT, /* Number of colors */
|
||||||
|
};
|
||||||
|
typedef enum ConsoleColor ConsoleColor;
|
||||||
|
|
||||||
|
/* Box drawing characters */
|
||||||
|
enum BoxDrawing {
|
||||||
|
BD_HORIZONTAL,
|
||||||
|
BD_VERTICAL,
|
||||||
|
BD_ULCORNER,
|
||||||
|
BD_LLCORNER,
|
||||||
|
BD_URCORNER,
|
||||||
|
BD_LRCORNER,
|
||||||
|
BD_RVERTICAL,
|
||||||
|
BD_LVERTICAL,
|
||||||
|
BD_DHORIZONTAL,
|
||||||
|
BD_UHORIZONTAL,
|
||||||
|
BD_COUNT, /* Number of available box drawing chars */
|
||||||
|
};
|
||||||
|
typedef enum BoxDrawing BoxDrawing;
|
||||||
|
|
||||||
|
/* ANSI escape sequences for color - don't use directly */
|
||||||
|
extern const char CP_ColorSeq[CC_COUNT][2][8];
|
||||||
|
|
||||||
|
/* Box drawing characters - don't use directly */
|
||||||
|
extern const char CP_BoxDrawingSeq[BD_COUNT][2][4];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Code */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void CP_Init (void);
|
||||||
|
/* Init console properties. Must be called before using any other function or
|
||||||
|
** data from this module.
|
||||||
|
**/
|
||||||
|
|
||||||
|
int CP_IsTTY (void);
|
||||||
|
/* Return true if console output goes to a tty */
|
||||||
|
|
||||||
|
int CP_IsUTF8 (void);
|
||||||
|
/* Return true if the console supports UTF-8 */
|
||||||
|
|
||||||
|
int CP_HasColor (void);
|
||||||
|
/* Return true if the console supports color and it should be used */
|
||||||
|
|
||||||
|
ColorMode CP_GetColorMode (void);
|
||||||
|
/* Return the current color mode */
|
||||||
|
|
||||||
|
void CP_SetColorMode (ColorMode M);
|
||||||
|
/* Set the color mode */
|
||||||
|
|
||||||
|
void CP_DisableUTF8 (void);
|
||||||
|
/* Disable UTF-8 support */
|
||||||
|
|
||||||
|
void CP_EnableUTF8 (void);
|
||||||
|
/* Enable UTF-8 support */
|
||||||
|
|
||||||
|
static inline const char* CP_Color (ConsoleColor C)
|
||||||
|
/* Return the ANSI escape sequence for a specific color or an empty string */
|
||||||
|
{
|
||||||
|
PRECONDITION (C >= 0 && C < CC_COUNT);
|
||||||
|
return CP_ColorSeq[C][CP_HasColor ()];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const char* CP_Reset (void)
|
||||||
|
/* Return the ANSI escape sequence to reset the colors or an empty string */
|
||||||
|
{
|
||||||
|
return CP_HasColor () ? "\x1b[0m" : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return specific colors */
|
||||||
|
static inline const char* CP_Black (void) { return CP_Color (CC_BLACK); }
|
||||||
|
static inline const char* CP_Red (void) { return CP_Color (CC_RED); }
|
||||||
|
static inline const char* CP_Green (void) { return CP_Color (CC_GREEN); }
|
||||||
|
static inline const char* CP_Brown (void) { return CP_Color (CC_BROWN); }
|
||||||
|
static inline const char* CP_Blue (void) { return CP_Color (CC_BLUE); }
|
||||||
|
static inline const char* CP_Magenta (void) { return CP_Color (CC_MAGENTA); }
|
||||||
|
static inline const char* CP_Cyan (void) { return CP_Color (CC_CYAN); }
|
||||||
|
static inline const char* CP_LightGray (void) { return CP_Color (CC_LIGHTGRAY); }
|
||||||
|
static inline const char* CP_Gray (void) { return CP_Color (CC_GRAY); }
|
||||||
|
static inline const char* CP_BrightRed (void) { return CP_Color (CC_BRIGHTRED); }
|
||||||
|
static inline const char* CP_BrightGreen (void) { return CP_Color (CC_BRIGHTGREEN); }
|
||||||
|
static inline const char* CP_Yellow (void) { return CP_Color (CC_YELLOW); }
|
||||||
|
static inline const char* CP_BrightBlue (void) { return CP_Color (CC_BRIGHTBLUE); }
|
||||||
|
static inline const char* CP_BrightMagenta (void) { return CP_Color (CC_BRIGHTMAGENTA); }
|
||||||
|
static inline const char* CP_BrightCyan (void) { return CP_Color (CC_BRIGHTCYAN); }
|
||||||
|
static inline const char* CP_White (void) { return CP_Color (CC_WHITE); }
|
||||||
|
|
||||||
|
static inline const char* CP_BoxDrawing (BoxDrawing B)
|
||||||
|
/* Return the UTF-8 sequence for the box drawing characters */
|
||||||
|
{
|
||||||
|
PRECONDITION (B >= 0 && B < BD_COUNT);
|
||||||
|
return CP_BoxDrawingSeq[B][CP_IsUTF8 ()];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return specific box drawing character sequences */
|
||||||
|
static inline const char* CP_Horizontal (void) { return CP_BoxDrawing (BD_HORIZONTAL); }
|
||||||
|
static inline const char* CP_Vertical (void) { return CP_BoxDrawing (BD_VERTICAL); }
|
||||||
|
static inline const char* CP_ULCorner (void) { return CP_BoxDrawing (BD_ULCORNER); }
|
||||||
|
static inline const char* CP_LLCorner (void) { return CP_BoxDrawing (BD_LLCORNER); }
|
||||||
|
static inline const char* CP_URCorner (void) { return CP_BoxDrawing (BD_URCORNER); }
|
||||||
|
static inline const char* CP_LRCorner (void) { return CP_BoxDrawing (BD_LRCORNER); }
|
||||||
|
static inline const char* CP_VerticalRight (void) { return CP_BoxDrawing (BD_RVERTICAL); }
|
||||||
|
static inline const char* CP_VerticalLeft (void) { return CP_BoxDrawing (BD_LVERTICAL); }
|
||||||
|
static inline const char* CP_HorizontalDown (void) { return CP_BoxDrawing (BD_DHORIZONTAL); }
|
||||||
|
static inline const char* CP_HorizontalUp (void) { return CP_BoxDrawing (BD_UHORIZONTAL); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* End of consprop.h */
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user