diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2011-12-31 19:35:58 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2011-12-31 19:40:20 -0800 |
commit | 4f61a0530c565bed2e8d0cf74ac9fd4322313093 (patch) | |
tree | 5edda0ed22e0a47b8d27da3bc92187de540fa0f1 /lib | |
parent | ca0d4f3bae56c486ec1d49d72c9ed6924236babc (diff) | |
download | grep-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.am | 4 | ||||
-rw-r--r-- | lib/colorize-impl.c | 39 | ||||
-rw-r--r-- | lib/colorize.c | 1 | ||||
-rw-r--r-- | lib/colorize.h | 37 | ||||
-rw-r--r-- | lib/ms/colorize-impl.c | 216 | ||||
-rw-r--r-- | lib/ms/colorize.h | 4 |
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 *); |