From ca75518017c48784be007942d6e8fd918fc04662 Mon Sep 17 00:00:00 2001 From: "Philip.Hazel" Date: Tue, 21 Mar 2017 16:09:57 +0000 Subject: [PATCH] Fix pcre2grep Windows problem for new output-colouring code when not under mingw (Bugzilla 2067). --- ChangeLog | 4 ++ src/pcre2grep.c | 127 +++++++++++++++++++++++++----------------------- 2 files changed, 70 insertions(+), 61 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8e21a3d..c07e631 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 ------------------------------ diff --git a/src/pcre2grep.c b/src/pcre2grep.c index 4e42278..d95e7d7 100644 --- a/src/pcre2grep.c +++ b/src/pcre2grep.c @@ -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 - to before the INVALID_FILE_ATTRIBUTES definition rather than after. */ + 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 */