summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2011-12-31 19:35:58 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2011-12-31 19:40:20 -0800
commit4f61a0530c565bed2e8d0cf74ac9fd4322313093 (patch)
tree5edda0ed22e0a47b8d27da3bc92187de540fa0f1 /lib
parentca0d4f3bae56c486ec1d49d72c9ed6924236babc (diff)
downloadgrep-4f61a0530c565bed2e8d0cf74ac9fd4322313093.tar.gz
ms: move Microsoft-specific stuff to lib/ms
* cfg.mk (exclude_file_name_regexp--sc_prohibit_strcmp) (exclude_file_name_regexp--sc_require_config_h) (exclude_file_name_regexp--sc_require_config_h_first): New rules. * lib/colorize.c, lib/colorize.h, lib/colorize-impl.c: * lib/ms/colorize.h, lib/ms/colorize-impl.c: New files. * configure.ac (GREP_SRC_INCLUDES): New macro. * lib/Makefile.am (libgreputils_a_SOURCES): Add colorize.[ch]. (EXTRA_DIST): New macro. * src/Makefile.am (DEFAULT_INCLUDES): New macro. * src/main.c: Include colorize.h. (PR_SGR_START, PR_SGR_END, PR_SGR_START_IF, PR_SGR_END_IF): Now static functions, not macros. (hstdout, norm_attr, w32_console_init, w32_sgr2attr) (w32_clreol) [__MINGW32__]: Move to lib/ms/colorize-impl.c. (pr_sgr_start, pr_sgr_end): Remove; callers changed to use new print_start_colorize, print_end_colorize from colorize.h. (init_colorize): Rename from w32_console_init and move to colorize module; caller changed. (should_colorize): Move to colorize module.
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am4
-rw-r--r--lib/colorize-impl.c39
-rw-r--r--lib/colorize.c1
-rw-r--r--lib/colorize.h37
-rw-r--r--lib/ms/colorize-impl.c216
-rw-r--r--lib/ms/colorize.h4
6 files changed, 300 insertions, 1 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 3d0c1ba3..239a53fe 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -21,7 +21,9 @@ INCLUDES = -I.. -I$(srcdir)
AM_CFLAGS += $(GNULIB_WARN_CFLAGS) $(WERROR_CFLAGS)
libgreputils_a_SOURCES += \
- savedir.c savedir.h
+ colorize.c colorize.h savedir.c savedir.h
+
+EXTRA_DIST += colorize-impl.c ms/colorize.h ms/colorize-impl.c
libgreputils_a_LIBADD += $(LIBOBJS) $(ALLOCA)
libgreputils_a_DEPENDENCIES += $(LIBOBJS) $(ALLOCA)
diff --git a/lib/colorize-impl.c b/lib/colorize-impl.c
new file mode 100644
index 00000000..48af4d4a
--- /dev/null
+++ b/lib/colorize-impl.c
@@ -0,0 +1,39 @@
+/* Output colorization.
+ Copyright 2011 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include <config.h>
+
+#include "colorize.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+/* Return non-zero if we should highlight matches in output to file
+ descriptor FD. */
+int
+should_colorize (int fd)
+{
+ if (! isatty (fd))
+ return 0;
+ else
+ {
+ char const *t = getenv ("TERM");
+ return t && strcmp (t, "dumb") != 0;
+ }
+}
diff --git a/lib/colorize.c b/lib/colorize.c
new file mode 100644
index 00000000..51b1847d
--- /dev/null
+++ b/lib/colorize.c
@@ -0,0 +1 @@
+#include <colorize-impl.c>
diff --git a/lib/colorize.h b/lib/colorize.h
new file mode 100644
index 00000000..9fdfaa30
--- /dev/null
+++ b/lib/colorize.h
@@ -0,0 +1,37 @@
+/* Output colorization.
+
+ Copyright 2011 Free Software Foundation, Inc.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+#include <stdio.h>
+
+static inline void init_colorize (void) { }
+extern int should_colorize (int);
+
+/* Start a colorized text attribute on stdout using the SGR_START
+ format; the attribute is specified by SGR_SEQ. */
+static inline void
+print_start_colorize (char const *sgr_start, char const *sgr_seq)
+{
+ printf (sgr_start, sgr_seq);
+}
+
+/* Restore the normal text attribute using the SGR_END string. */
+static inline void
+print_end_colorize (char const *sgr_end)
+{
+ printf ("%s", sgr_end);
+}
diff --git a/lib/ms/colorize-impl.c b/lib/ms/colorize-impl.c
new file mode 100644
index 00000000..d5634107
--- /dev/null
+++ b/lib/ms/colorize-impl.c
@@ -0,0 +1,216 @@
+/* Output colorization on MS-Windows.
+ Copyright 2011 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+/* Written by Eli Zaretskii. */
+
+#include <config.h>
+
+#include "colorize.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#undef DATADIR /* conflicts with objidl.h, which is included by windows.h */
+#include <windows.h>
+
+static HANDLE hstdout = INVALID_HANDLE_VALUE;
+static SHORT norm_attr;
+
+/* Initialize the normal text attribute used by the console. */
+void
+init_colorize (void)
+{
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+ hstdout = GetStdHandle (STD_OUTPUT_HANDLE);
+ if (hstdout != INVALID_HANDLE_VALUE
+ && GetConsoleScreenBufferInfo (hstdout, &csbi))
+ norm_attr = csbi.wAttributes;
+ else
+ hstdout = INVALID_HANDLE_VALUE;
+}
+
+/* Return non-zero if we should highlight matches in output. */
+int
+should_colorize (int fd)
+{
+ if (! isatty (fd))
+ return 0;
+ /* Windows isatty returns non-zero for the null device too. */
+ else if (lseek (fd, SEEK_CUR, 0) != -1)
+ return 0;
+ else
+ {
+ /* $TERM is not normally defined on DOS/Windows, so don't require
+ it for highlighting. But some programs, like Emacs, do define
+ it when running Grep as a subprocess, so make sure they don't
+ set TERM=dumb. */
+ char const *t = getenv ("TERM");
+ return ! (t && strcmp (t, "dumb") == 0);
+ }
+}
+
+/* Convert a color spec, a semi-colon separated list of the form
+ "NN;MM;KK;...", where each number is a value of the SGR parameter,
+ into the corresponding Windows console text attribute.
+
+ This function supports a subset of the SGR rendition aspects that
+ the Windows console can display. */
+static int
+w32_sgr2attr (const char *sgr_seq)
+{
+ const char *s, *p;
+ int code, fg = norm_attr & 15, bg = norm_attr & (15 << 4);
+ int bright = 0, inverse = 0;
+ static const int fg_color[] = {
+ 0, /* black */
+ FOREGROUND_RED, /* red */
+ FOREGROUND_GREEN, /* green */
+ FOREGROUND_GREEN | FOREGROUND_RED, /* yellow */
+ FOREGROUND_BLUE, /* blue */
+ FOREGROUND_BLUE | FOREGROUND_RED, /* magenta */
+ FOREGROUND_BLUE | FOREGROUND_GREEN, /* cyan */
+ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE /* gray */
+ };
+ static const int bg_color[] = {
+ 0, /* black */
+ BACKGROUND_RED, /* red */
+ BACKGROUND_GREEN, /* green */
+ BACKGROUND_GREEN | BACKGROUND_RED, /* yellow */
+ BACKGROUND_BLUE, /* blue */
+ BACKGROUND_BLUE | BACKGROUND_RED, /* magenta */
+ BACKGROUND_BLUE | BACKGROUND_GREEN, /* cyan */
+ BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE /* gray */
+ };
+
+ for (s = p = sgr_seq; *s; p++)
+ {
+ if (*p == ';' || *p == '\0')
+ {
+ code = strtol (s, NULL, 10);
+ s = p + (*p != '\0');
+
+ switch (code)
+ {
+ case 0: /* all attributes off */
+ fg = norm_attr & 15;
+ bg = norm_attr & (15 << 4);
+ bright = 0;
+ inverse = 0;
+ break;
+ case 1: /* intensity on */
+ bright = 1;
+ break;
+ case 7: /* inverse video */
+ inverse = 1;
+ break;
+ case 22: /* intensity off */
+ bright = 0;
+ break;
+ case 27: /* inverse off */
+ inverse = 0;
+ break;
+ case 30: case 31: case 32: case 33: /* foreground color */
+ case 34: case 35: case 36: case 37:
+ fg = fg_color[code - 30];
+ break;
+ case 39: /* default foreground */
+ fg = norm_attr & 15;
+ break;
+ case 40: case 41: case 42: case 43: /* background color */
+ case 44: case 45: case 46: case 47:
+ bg = bg_color[code - 40];
+ break;
+ case 49: /* default background */
+ bg = norm_attr & (15 << 4);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if (inverse)
+ {
+ int t = fg;
+ fg = (bg >> 4);
+ bg = (t << 4);
+ }
+ if (bright)
+ fg |= FOREGROUND_INTENSITY;
+
+ return (bg & (15 << 4)) | (fg & 15);
+}
+
+/* Start a colorized text attribute on stdout using the SGR_START
+ format; the attribute is specified by SGR_SEQ. */
+void
+print_start_colorize (char const *sgr_start, char const *sgr_seq)
+{
+ /* If stdout is connected to a console, set the console text
+ attribute directly instead of using SGR_START. Otherwise, use
+ SGR_START to emit the SGR escape sequence as on Posix platforms;
+ this is needed when Grep is invoked as a subprocess of another
+ program, such as Emacs, which will handle the display of the
+ matches. */
+ if (hstdout != INVALID_HANDLE_VALUE)
+ {
+ SHORT attr = w32_sgr2attr (sgr_seq);
+ SetConsoleTextAttribute (hstdout, attr);
+ }
+ else
+ printf (sgr_start, sgr_seq);
+}
+
+/* Clear to the end of the current line with the default attribute.
+ This is needed for reasons similar to those that require the "EL to
+ Right after SGR" operation on Posix platforms: if we don't do this,
+ setting the `mt', `ms', or `mc' capabilities to use a non-default
+ background color spills that color to the empty space at the end of
+ the last screen line in a match whose line spans multiple screen
+ lines. */
+static void
+w32_clreol (void)
+{
+ DWORD nchars;
+ COORD start_pos;
+ DWORD written;
+ CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+ GetConsoleScreenBufferInfo (hstdout, &csbi);
+ start_pos = csbi.dwCursorPosition;
+ nchars = csbi.dwSize.X - start_pos.X;
+
+ FillConsoleOutputAttribute (hstdout, norm_attr, nchars, start_pos,
+ &written);
+ FillConsoleOutputCharacter (hstdout, ' ', nchars, start_pos, &written);
+}
+
+/* Restore the normal text attribute using the SGR_END string. */
+void
+print_end_colorize (char const *sgr_end)
+{
+ if (hstdout != INVALID_HANDLE_VALUE)
+ {
+ SetConsoleTextAttribute (hstdout, norm_attr);
+ w32_clreol ();
+ }
+ else
+ printf ("%s", sgr_end);
+}
diff --git a/lib/ms/colorize.h b/lib/ms/colorize.h
new file mode 100644
index 00000000..c49657d6
--- /dev/null
+++ b/lib/ms/colorize.h
@@ -0,0 +1,4 @@
+extern void colorize_init (void);
+extern int should_colorize (int);
+extern void print_start_colorize (char const *, char const *);
+extern void print_end_colorize (char const *);