Escape control characters; fix CRM issues

Since ESC is now preserved for unrecognised sequences, I feel able to
use it to escape control characters in order to display them (e.g.
"\e\e" will display a single escape).

Control mode would not display the recognised controls (i.e. BEL, SO and
SI) and would not work if it was turned off in the same string.
This commit is contained in:
Jason Hood 2017-11-24 11:10:42 +10:00
parent e44cbb848f
commit 9fbe42a583
3 changed files with 40 additions and 15 deletions

43
ANSI.c
View File

@ -162,7 +162,8 @@
fix escape followed by CRM in control mode; fix escape followed by CRM in control mode;
use the system default sound for the bell; use the system default sound for the bell;
add DECPS Play Sound; add DECPS Play Sound;
use intermediate byte '+' to use buffer, not window. use intermediate byte '+' to use buffer, not window;
ESC followed by a control character will display that character.
*/ */
#include "ansicon.h" #include "ansicon.h"
@ -185,7 +186,7 @@ HANDLE hHeap; // local memory heap
HANDLE hBell; HANDLE hBell;
#define CACHE 5 #define CACHE 5
struct struct Cache
{ {
HANDLE h; HANDLE h;
DWORD mode; DWORD mode;
@ -478,11 +479,9 @@ void FlushBuffer( void )
if (pState->crm) if (pState->crm)
{ {
DWORD mode; SetConsoleMode( hConOut, cache[0].mode & ~ENABLE_PROCESSED_OUTPUT );
GetConsoleMode( hConOut, &mode );
SetConsoleMode( hConOut, mode & ~ENABLE_PROCESSED_OUTPUT );
WriteConsole( hConOut, ChBuffer, nCharInBuffer, &nWritten, NULL ); WriteConsole( hConOut, ChBuffer, nCharInBuffer, &nWritten, NULL );
SetConsoleMode( hConOut, mode ); SetConsoleMode( hConOut, cache[0].mode );
} }
else else
{ {
@ -699,9 +698,11 @@ void InterpretEscSeq( void )
return; return;
case 7: case 7:
mode = ENABLE_PROCESSED_OUTPUT; mode = cache[0].mode;
if (suffix == 'h') if (suffix == 'h')
mode |= ENABLE_WRAP_AT_EOL_OUTPUT; mode |= ENABLE_WRAP_AT_EOL_OUTPUT;
else
mode &= ~ENABLE_WRAP_AT_EOL_OUTPUT;
SetConsoleMode( hConOut, mode ); SetConsoleMode( hConOut, mode );
return; return;
} }
@ -1269,6 +1270,7 @@ ParseAndPrintString( HANDLE hDev,
get_state(); get_state();
state = (pState->crm) ? 7 : 2; state = (pState->crm) ? 7 : 2;
} }
else if (pState->crm) PushBuffer( (WCHAR)c );
else if (c == BEL) else if (c == BEL)
{ {
if (hBell == NULL) if (hBell == NULL)
@ -1280,8 +1282,15 @@ ParseAndPrintString( HANDLE hDev,
} }
else if (state == 2) else if (state == 2)
{ {
if (c == ESC) if (c < '\x20')
PushBuffer( ESC ); {
FlushBuffer();
pState->crm = TRUE;
PushBuffer( (WCHAR)c );
FlushBuffer();
pState->crm = FALSE;
state = 1;
}
else if (c >= '\x20' && c <= '\x2f') else if (c >= '\x20' && c <= '\x2f')
suffix2 = c; suffix2 = c;
else if (suffix2 != 0) else if (suffix2 != 0)
@ -1433,7 +1442,11 @@ ParseAndPrintString( HANDLE hDev,
} }
else if (state == 9) else if (state == 9)
{ {
if (c == 'l') pState->crm = FALSE; if (c == 'l')
{
FlushBuffer();
pState->crm = FALSE;
}
else else
{ {
PushBuffer( ESC ); PushBuffer( ESC );
@ -2098,7 +2111,15 @@ BOOL IsConsoleHandle( HANDLE h )
for (c = 0; c < CACHE; ++c) for (c = 0; c < CACHE; ++c)
if (cache[c].h == h) if (cache[c].h == h)
return (cache[c].mode & ENABLE_PROCESSED_OUTPUT); {
if (c != 0)
{
struct Cache tc = cache[c];
do cache[c] = cache[c-1]; while (--c > 0);
cache[0] = tc;
}
return (cache[0].mode & ENABLE_PROCESSED_OUTPUT);
}
while (--c > 0) while (--c > 0)
cache[c] = cache[c-1]; cache[c] = cache[c-1];

View File

@ -90,7 +90,7 @@
write newline with _putws, not putwchar (fixes redirecting to CON). write newline with _putws, not putwchar (fixes redirecting to CON).
*/ */
#define PDATE L"23 November, 2017" #define PDATE L"24 November, 2017"
#include "ansicon.h" #include "ansicon.h"
#include "version.h" #include "version.h"

View File

@ -198,6 +198,9 @@ Sequences Recognised
and underline will set the background intensity; conceal uses background as and underline will set the background intensity; conceal uses background as
foreground. See "sequences.txt" for a more complete description. foreground. See "sequences.txt" for a more complete description.
Escape followed by a control character will display that character, not
perform its function. An unrecognised sequence will preserve the escape.
I make a distinction between '\e[m' and '\e[0;...m'. Both will restore the I make a distinction between '\e[m' and '\e[0;...m'. Both will restore the
original foreground/background colors (and so '0' should be the first para- original foreground/background colors (and so '0' should be the first para-
meter); the former will also restore the original bold and underline attri- meter); the former will also restore the original bold and underline attri-
@ -295,15 +298,16 @@ Version History
Legend: + added, - bug-fixed, * changed. Legend: + added, - bug-fixed, * changed.
1.80 - 23 November, 2017: 1.80 - 24 November, 2017:
- fix unloading; - fix unloading;
- fix -e et al when redirecting to CON; - fix -e et al when redirecting to CON;
- hook CreateFile and CreateConsoleScreenBuffer to force read/write access - hook CreateFile and CreateConsoleScreenBuffer to force read/write access
(fixes redirecting to CON and Microsoft's conio); (fixes redirecting to CON and Microsoft's conio);
- fix cursor report with duplicated digits (e.g. "11" was only writing "1"); - fix cursor report with duplicated digits (e.g. "11" was only writing "1");
- fix escape followed by CRM in control mode; - fix issues with CRM;
* go back to saving the buffer cursor position; * go back to saving the buffer cursor position;
* preserve escape that isn't part of a sequence; * preserve escape that isn't part of a sequence;
* escape control characters;
+ use the system default sound for the bell; + use the system default sound for the bell;
+ added Play Sound DECPS; + added Play Sound DECPS;
+ added '+' intermediate byte to use the buffer, rather than the window. + added '+' intermediate byte to use the buffer, rather than the window.
@ -535,4 +539,4 @@ Distribution
============================= =============================
Jason Hood, 23 November, 2017. Jason Hood, 24 November, 2017.