You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
7.3 KiB
C

/*
* stderr - Message output system
*
* (C) Frank Klemm, Janne Hyv<79>inen 2002. All rights reserved.
*
* Principles:
*
* History:
* 2001 created
* 2002 Spring added functionality to switch on and off printing to easily allow silent modes
* 2002-10-10 Escape sequence handling for Windows added.
*
* Global functions:
* - SetStderrSilent()
* - GetStderrSilent()
* - stderr_printf()
*
* TODO:
* -
*/
#include <mpc/mpc_types.h>
#ifdef _WIN32
# include <windows.h>
#endif
#include <stdio.h>
#include <stdarg.h>
// #include "mpcenc.h"
#define WRITE(fp,ptr,len) fwrite (ptr, 1, len, fp) // WRITE returns -1 or 0 on error/EOF, otherwise > 0
static mpc_bool_t stderr_silent = 0;
void
SetStderrSilent ( mpc_bool_t state )
{
stderr_silent = state;
}
mpc_bool_t
GetStderrSilent ( void )
{
return stderr_silent;
}
int mpc_cdecl
stderr_printf ( const char* format, ... )
{
char buff [2 * 1024 + 3072];
char* p = buff;
int ret;
va_list v;
/* print to a buffer */
va_start ( v, format );
ret = vsprintf ( p, format, v );
va_end ( v );
if ( !stderr_silent ) {
#if defined __unix__ || defined __UNIX__
WRITE ( stderr, buff, ret );
#elif defined _WIN32
# define FOREGROUND_ALL ( FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED )
# define BACKGROUND_ALL ( BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED )
// for Windows systems we must merge carriage returns into the stream to avoid staircases
// Also escape sequences must be detected and replaced (incomplete now)
char buff [128], *q;
static int init = 0;
CONSOLE_SCREEN_BUFFER_INFO con_info;
static HANDLE hSTDERR;
static WORD attr;
static WORD attr_initial;
DWORD written;
if ( init == 0 ) {
hSTDERR = GetStdHandle ( STD_ERROR_HANDLE );
attr = hSTDERR == INVALID_HANDLE_VALUE || GetConsoleScreenBufferInfo ( hSTDERR, &con_info ) == 0
? FOREGROUND_ALL : con_info.wAttributes;
attr_initial = attr;
init = 1;
}
if ( hSTDERR == INVALID_HANDLE_VALUE ) {
while ( ( q = strchr (p, '\n')) != NULL ) {
WRITE ( stderr, p, q-p );
WRITE ( stderr, "\r\n", 2 );
p = q+1;
}
WRITE ( stderr, p, strlen (p) );
}
else {
for ( ; *p; p++ ) {
switch ( *p ) {
case '\n':
SetConsoleTextAttribute ( hSTDERR, attr_initial );
fprintf ( stderr, "\r\n" );
SetConsoleTextAttribute ( hSTDERR, attr );
break;
case '\x1B':
if ( p[1] == '[' ) {
unsigned int tmp;
p++;
cont: p++;
for ( tmp = 0; (unsigned int)( *p - '0' ) < 10u; p++ )
tmp = 10 * tmp + ( *p - '0' );
switch ( *p ) {
case ';':
case 'm':
switch ( tmp ) {
case 0: attr = FOREGROUND_ALL; break; // reset defaults
case 1: attr |= FOREGROUND_INTENSITY; break; // high intensity on
case 2: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_INTENSITY; break; // (very) low intensity
case 3: break; // italic on
case 4: break; // underline on
case 5: break; // blinking on
case 7: break; // reverse
case 8: attr = 0; break; // invisible
case 30: attr &= ~FOREGROUND_ALL; break;
case 31: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_RED; break;
case 32: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_GREEN; break;
case 33: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_RED | FOREGROUND_GREEN; break;
case 34: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_BLUE; break;
case 35: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_RED | FOREGROUND_BLUE; break;
case 36: attr &= ~FOREGROUND_ALL; attr |= FOREGROUND_GREEN | FOREGROUND_BLUE; break;
case 37: case 39: attr |= FOREGROUND_ALL; break;
case 40: case 49:
attr &= ~BACKGROUND_ALL; break;
case 41: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_RED; break;
case 42: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_GREEN; break;
case 43: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_RED | BACKGROUND_GREEN; break;
case 44: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_BLUE; break;
case 45: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_RED | BACKGROUND_BLUE; break;
case 46: attr &= ~BACKGROUND_ALL; attr |= BACKGROUND_GREEN | BACKGROUND_BLUE; break;
case 47: attr |= BACKGROUND_ALL; break;
}
SetConsoleTextAttribute ( hSTDERR, attr );
if ( *p == ';' )
goto cont;
break;
default:
WriteFile ( hSTDERR, buff, sprintf ( buff, "Unknown escape sequence ending with '%c'\n", *p ), &written, NULL );
break;
}
break;
}
default:
fputc ( *p, stderr );
break;
}
} /* end for */
}
#else
char * q;
// for non-Unix systems we must merge carriage returns into the stream to avoid staircases
while ( ( q = strchr (p, '\n')) != NULL ) {
WRITE ( stderr, p, q-p );
WRITE ( stderr, "\r\n", 2 );
p = q+1;
}
WRITE ( stderr, p, strlen (p) );
#endif
}
return ret;
}
/* end of stderr.c */