[Pcre-svn] [568] code/trunk: Dmitry Cherniachenko' s patch f…

Top Page
Delete this message
Author: Subversion repository
Date:  
To: pcre-svn
Subject: [Pcre-svn] [568] code/trunk: Dmitry Cherniachenko' s patch for colouring pcre2grep output in Windows.
Revision: 568
          http://www.exim.org/viewvc/pcre2?view=rev&revision=568
Author:   ph10
Date:     2016-10-14 17:17:48 +0100 (Fri, 14 Oct 2016)
Log Message:
-----------
Dmitry Cherniachenko's patch for colouring pcre2grep output in Windows.


Modified Paths:
--------------
    code/trunk/ChangeLog
    code/trunk/doc/pcre2grep.1
    code/trunk/src/pcre2grep.c


Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog    2016-10-14 15:47:27 UTC (rev 567)
+++ code/trunk/ChangeLog    2016-10-14 16:17:48 UTC (rev 568)
@@ -74,7 +74,11 @@


12. Added some "const" qualifiers to variables in pcre2grep.

+13. Added Dmitry Cherniachenko's patch for colouring output in Windows
+(untested by me). Also, look for GREP_COLOUR or GREP_COLOR if the environment
+variables PCRE2GREP_COLOUR and PCRE2GREP_COLOR are not found.

+
Version 10.22 29-July-2016
--------------------------


Modified: code/trunk/doc/pcre2grep.1
===================================================================
--- code/trunk/doc/pcre2grep.1    2016-10-14 15:47:27 UTC (rev 567)
+++ code/trunk/doc/pcre2grep.1    2016-10-14 16:17:48 UTC (rev 568)
@@ -1,4 +1,4 @@
-.TH PCRE2GREP 1 "11 October 2016" "PCRE2 10.23"
+.TH PCRE2GREP 1 "14 October 2016" "PCRE2 10.23"
 .SH NAME
 pcre2grep - a grep with Perl-compatible regular expressions.
 .SH SYNOPSIS
@@ -206,11 +206,12 @@
 just one, in order to colour them all.
 .sp
 The colour that is used can be specified by setting the environment variable
-PCRE2GREP_COLOUR or PCRE2GREP_COLOR. The value of this variable should be a
-string of two numbers, separated by a semicolon. They are copied directly into
-the control string for setting colour on a terminal, so it is your
-responsibility to ensure that they make sense. If neither of the environment
-variables is set, the default is "1;31", which gives red.
+PCRE2GREP_COLOUR or PCRE2GREP_COLOR. If neither of these are set,
+\fBpcre2grep\fP looks for GREP_COLOUR or GREP_COLOR. The value of the variable
+should be a string of two numbers, separated by a semicolon. They are copied
+directly into the control string for setting colour on a terminal, so it is
+your responsibility to ensure that they make sense. If neither of the
+environment variables is set, the default is "1;31", which gives red.
 .TP
 \fB-D\fP \fIaction\fP, \fB--devices=\fP\fIaction\fP
 If an input path is not a regular file or a directory, "action" specifies how
@@ -525,12 +526,13 @@
 Show only the part of the line that matched a pattern instead of the whole
 line. In this mode, no context is shown. That is, the \fB-A\fP, \fB-B\fP, and
 \fB-C\fP options are ignored. If there is more than one match in a line, each
-of them is shown separately. If \fB-o\fP is combined with \fB-v\fP (invert the
-sense of the match to find non-matching lines), no output is generated, but the
-return code is set appropriately. If the matched portion of the line is empty,
-nothing is output unless the file name or line number are being printed, in
-which case they are shown on an otherwise empty line. This option is mutually
-exclusive with \fB--file-offsets\fP and \fB--line-offsets\fP.
+of them is shown separately, on a separate line of output. If \fB-o\fP is
+combined with \fB-v\fP (invert the sense of the match to find non-matching
+lines), no output is generated, but the return code is set appropriately. If
+the matched portion of the line is empty, nothing is output unless the file
+name or line number are being printed, in which case they are shown on an
+otherwise empty line. This option is mutually exclusive with
+\fB--file-offsets\fP and \fB--line-offsets\fP.
 .TP
 \fB-o\fP\fInumber\fP, \fB--only-matching\fP=\fInumber\fP
 Show only the part of the line that matched the capturing parentheses of the
@@ -542,10 +544,11 @@
 capturing parentheses do not exist in the pattern, or were not set in the
 match, nothing is output unless the file name or line number are being output.
 .sp
-If this option is given multiple times, multiple substrings are output, in the
-order the options are given. For example, -o3 -o1 -o3 causes the substrings
-matched by capturing parentheses 3 and 1 and then 3 again to be output. By
-default, there is no separator (but see the next option).
+If this option is given multiple times, multiple substrings are output for each 
+match, in the order the options are given, and all on one line. For example,
+-o3 -o1 -o3 causes the substrings matched by capturing parentheses 3 and 1 and
+then 3 again to be output. By default, there is no separator (but see the next
+option).
 .TP
 \fB--om-separator\fP=\fItext\fP
 Specify a separating string for multiple occurrences of \fB-o\fP. The default
@@ -775,6 +778,6 @@
 .rs
 .sp
 .nf
-Last updated: 11 October 2016
+Last updated: 14 October 2016
 Copyright (c) 1997-2016 University of Cambridge.
 .fi


Modified: code/trunk/src/pcre2grep.c
===================================================================
--- code/trunk/src/pcre2grep.c    2016-10-14 15:47:27 UTC (rev 567)
+++ code/trunk/src/pcre2grep.c    2016-10-14 16:17:48 UTC (rev 568)
@@ -681,6 +681,17 @@
 }
 #endif


+
+/************* Print optionally coloured match Unix-style and z/OS **********/
+
+static void
+print_match(const char* buf, int length)
+{
+if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string);
+FWRITE(buf, 1, length, stdout);
+if (do_colour) fprintf(stdout, "%c[00m", 0x1b);
+}
+
/* End of Unix-style or native z/OS environment functions. */


@@ -814,6 +825,65 @@
return FALSE;
}

+
+/************* Print optionally coloured match in Windows **********/
+
+static HANDLE hstdout;
+static CONSOLE_SCREEN_BUFFER_INFO csbi;
+static WORD match_colour;
+
+static void
+print_match(const char* buf, int length)
+{
+if (do_colour) SetConsoleTextAttribute(hstdout, match_colour);
+FWRITE(buf, 1, length, stdout);
+if (do_colour) SetConsoleTextAttribute(hstdout, csbi.wAttributes);
+}
+
+/* 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(char *cs)
+{
+WORD result = 0;
+while (*cs)
+  {
+  if (isdigit(*cs))
+    {
+    int code = atoi(cs);
+    if (code == 1) result |= 0x08;
+    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);
+  GetConsoleScreenBufferInfo(hstdout, &csbi);
+
+  match_colour = decode_ANSI_colour(colour_string);
+  /* No valid colour found - turn off colouring */
+  if (!match_colour) do_colour = FALSE;
+  }
+}
+
 /* End of Windows functions */



@@ -2113,9 +2183,7 @@
               if (plen > 0)
                 {
                 if (printed) fprintf(stdout, "%s", om_separator);
-                if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string);
-                FWRITE(matchptr + offsets[n*2], 1, plen, stdout);
-                if (do_colour) fprintf(stdout, "%c[00m", 0x1b);
+                print_match(matchptr + offsets[n*2], plen);
                 printed = TRUE;
                 }
               }
@@ -2283,9 +2351,7 @@
         {
         int plength;
         FWRITE(ptr, 1, offsets[0], stdout);
-        fprintf(stdout, "%c[%sm", 0x1b, colour_string);
-        FWRITE(ptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
-        fprintf(stdout, "%c[00m", 0x1b);
+        print_match(ptr + offsets[0], offsets[1] - offsets[0]);
         for (;;)
           {
           startoffset = offsets[1];
@@ -2293,9 +2359,7 @@
               !match_patterns(matchptr, length, options, startoffset, &mrc))
             break;
           FWRITE(matchptr + startoffset, 1, offsets[0] - startoffset, stdout);
-          fprintf(stdout, "%c[%sm", 0x1b, colour_string);
-          FWRITE(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout);
-          fprintf(stdout, "%c[00m", 0x1b);
+          print_match(matchptr + offsets[0], offsets[1] - offsets[0]);
           }


         /* In multiline mode, we may have already printed the complete line
@@ -3391,7 +3455,12 @@
     {
     char *cs = getenv("PCRE2GREP_COLOUR");
     if (cs == NULL) cs = getenv("PCRE2GREP_COLOR");
+    if (cs == NULL) cs = getenv("GREP_COLOUR"); 
+    if (cs == NULL) cs = getenv("GREP_COLOR"); 
     if (cs != NULL) colour_string = cs;
+#if defined HAVE_WINDOWS_H && HAVE_WINDOWS_H
+    init_colour_output();
+#endif 
     }
   }