Fix pcre2grep Windows problem for new output-colouring code when not under

mingw (Bugzilla 2067).
This commit is contained in:
Philip.Hazel 2017-03-21 16:09:57 +00:00
parent 31455a7665
commit ca75518017
2 changed files with 70 additions and 61 deletions

View File

@ -64,6 +64,10 @@ for global matching, unpredictable things could happen. For example, in UTF-8
mode, the pattern //g,zero_terminate read random memory when matched against an
empty string with zero_terminate. This was a bug in pcre2test, not the library.
9. Moved some Windows-specific code in pcre2grep (introduced in 10.23/13) out
of the section that is compiled when Unix-style directory scanning is
available, and into a new section that is always compiled for Windows.
Version 10.23 14-February-2017
------------------------------

View File

@ -622,9 +622,70 @@ while (fn != NULL)
* OS-specific functions *
*************************************************/
/* These functions are defined so that they can be made system specific.
At present there are versions for Unix-style environments, Windows, native
z/OS, and "no support". */
/* These definitions are needed in all Windows environments, even those where
Unix-style directory scanning can be used (see below). */
#ifdef WIN32
#define iswild(name) (strpbrk(name, "*?") != NULL)
/* Convert ANSI BGR format to RGB used by Windows */
#define BGR_RGB(x) ((x & 1 ? 4 : 0) | (x & 2) | (x & 4 ? 1 : 0))
static WORD
decode_ANSI_colour(const char *cs)
{
WORD result = csbi.wAttributes;
while (*cs)
{
if (isdigit(*cs))
{
int code = atoi(cs);
if (code == 1) result |= 0x08;
else if (code == 4) result |= 0x8000;
else if (code == 5) result |= 0x80;
else if (code >= 30 && code <= 37) result = (result & 0xF8) | BGR_RGB(code - 30);
else if (code == 39) result = (result & 0xF0) | (csbi.wAttributes & 0x0F);
else if (code >= 40 && code <= 47) result = (result & 0x8F) | (BGR_RGB(code - 40) << 4);
else if (code == 49) result = (result & 0x0F) | (csbi.wAttributes & 0xF0);
/* aixterm high intensity colour codes */
else if (code >= 90 && code <= 97) result = (result & 0xF0) | BGR_RGB(code - 90) | 0x08;
else if (code >= 100 && code <= 107) result = (result & 0x0F) | (BGR_RGB(code - 100) << 4) | 0x80;
while (isdigit(*cs)) cs++;
}
if (*cs) cs++;
}
return result;
}
static void
init_colour_output()
{
if (do_colour)
{
hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
/* This fails when redirected to con; try again if so. */
if (!GetConsoleScreenBufferInfo(hstdout, &csbi) && !do_ansi)
{
HANDLE hcon = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
GetConsoleScreenBufferInfo(hcon, &csbi);
CloseHandle(hcon);
}
match_colour = decode_ANSI_colour(colour_string);
/* No valid colour found - turn off colouring */
if (!match_colour) do_colour = FALSE;
}
}
#endif /* WIN32 */
/* The following sets of functions are defined so that they can be made system
specific. At present there are versions for Unix-style environments, Windows,
native z/OS, and "no support". */
/************* Directory scanning Unix-style and z/OS ***********/
@ -748,7 +809,8 @@ if (do_colour) fprintf(stdout, "%c[0m", 0x1b);
/* I (Philip Hazel) have no means of testing this code. It was contributed by
Lionel Fourquaux. David Burgess added a patch to define INVALID_FILE_ATTRIBUTES
when it did not exist. David Byron added a patch that moved the #include of
<windows.h> to before the INVALID_FILE_ATTRIBUTES definition rather than after. */
<windows.h> to before the INVALID_FILE_ATTRIBUTES definition rather than after.
*/
#elif defined WIN32
@ -765,11 +827,6 @@ when it did not exist. David Byron added a patch that moved the #include of
#define INVALID_FILE_ATTRIBUTES 0xFFFFFFFF
#endif
/* Allow opendirectory to provide globbing, since Microsoft started doing it
wrong (expanding quoted arguments). */
#define iswild(name) (strpbrk(name, "*?") != NULL)
typedef struct directory_type
{
HANDLE handle;
@ -901,58 +958,6 @@ if (do_colour)
}
}
/* Convert ANSI BGR format to RGB used by Windows */
#define BGR_RGB(x) ((x & 1 ? 4 : 0) | (x & 2) | (x & 4 ? 1 : 0))
static WORD
decode_ANSI_colour(const char *cs)
{
WORD result = csbi.wAttributes;
while (*cs)
{
if (isdigit(*cs))
{
int code = atoi(cs);
if (code == 1) result |= 0x08;
else if (code == 4) result |= 0x8000;
else if (code == 5) result |= 0x80;
else if (code >= 30 && code <= 37) result = (result & 0xF8) | BGR_RGB(code - 30);
else if (code == 39) result = (result & 0xF0) | (csbi.wAttributes & 0x0F);
else if (code >= 40 && code <= 47) result = (result & 0x8F) | (BGR_RGB(code - 40) << 4);
else if (code == 49) result = (result & 0x0F) | (csbi.wAttributes & 0xF0);
/* aixterm high intensity colour codes */
else if (code >= 90 && code <= 97) result = (result & 0xF0) | BGR_RGB(code - 90) | 0x08;
else if (code >= 100 && code <= 107) result = (result & 0x0F) | (BGR_RGB(code - 100) << 4) | 0x80;
while (isdigit(*cs)) cs++;
}
if (*cs) cs++;
}
return result;
}
static void
init_colour_output()
{
if (do_colour)
{
hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
/* This fails when redirected to con; try again if so. */
if (!GetConsoleScreenBufferInfo(hstdout, &csbi) && !do_ansi)
{
HANDLE hcon = CreateFile("CONOUT$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
GetConsoleScreenBufferInfo(hcon, &csbi);
CloseHandle(hcon);
}
match_colour = decode_ANSI_colour(colour_string);
/* No valid colour found - turn off colouring */
if (!match_colour) do_colour = FALSE;
}
}
/* End of Windows functions */