diff --git a/contrib/less/NEWS b/contrib/less/NEWS index ccb14ba432bd..f251a1e71ef6 100644 --- a/contrib/less/NEWS +++ b/contrib/less/NEWS @@ -13,6 +13,18 @@ ====================================================================== + Major changes between "less" versions 406 and 408 + +* Support CSI escape sequences, like SGR escape sequences. + +* Fix bug which caused screen to fail to repaint when window is resized. + +* Fix bug in using -i and -I flags with non-ASCII text. + +* Fix configure bug on systems which don't support langinfo.h. + +====================================================================== + Major changes between "less" versions 394 and 406 * Allow decimal point in number for % (percent) command. diff --git a/contrib/less/README b/contrib/less/README index 848fe4de7731..ace7bf090ed1 100644 --- a/contrib/less/README +++ b/contrib/less/README @@ -1,7 +1,7 @@ - Less, version 406 + Less, version 408 - This is the distribution of less, version 406, released 19 Jun 2007. + This is the distribution of less, version 408, released 01 Oct 2007. This program is part of the GNU project (http://www.gnu.org). This program is free software. You may redistribute it and/or diff --git a/contrib/less/ch.c b/contrib/less/ch.c index 61bc83a48aac..2ac14d7a1a8e 100644 --- a/contrib/less/ch.c +++ b/contrib/less/ch.c @@ -128,6 +128,9 @@ fch_get() POSITION pos; POSITION len; + if (thisfile == NULL) + return (EOI); + slept = FALSE; /* @@ -416,6 +419,9 @@ ch_seek(pos) BLOCKNUM new_block; POSITION len; + if (thisfile == NULL) + return (0); + len = ch_length(); if (pos < ch_zero() || (len != NULL_POSITION && pos > len)) return (1); @@ -450,6 +456,9 @@ ch_end_seek() { POSITION len; + if (thisfile == NULL) + return (0); + if (ch_flags & CH_CANSEEK) ch_fsize = filesize(ch_file); @@ -503,6 +512,8 @@ ch_beg_seek() public POSITION ch_length() { + if (thisfile == NULL) + return (NULL_POSITION); if (ignore_eoi) return (NULL_POSITION); if (ch_flags & CH_HELPFILE) @@ -516,6 +527,8 @@ ch_length() public POSITION ch_tell() { + if (thisfile == NULL) + return (NULL_POSITION); return (ch_block * LBUFSIZE) + ch_offset; } @@ -527,6 +540,8 @@ ch_forw_get() { register int c; + if (thisfile == NULL) + return (EOI); c = ch_get(); if (c == EOI) return (EOI); @@ -546,6 +561,8 @@ ch_forw_get() public int ch_back_get() { + if (thisfile == NULL) + return (EOI); if (ch_offset > 0) ch_offset --; else @@ -586,6 +603,9 @@ ch_flush() { register struct buf *bp; + if (thisfile == NULL) + return; + if (!(ch_flags & CH_CANSEEK)) { /* @@ -769,6 +789,9 @@ ch_close() { int keepstate = FALSE; + if (thisfile == NULL) + return; + if (ch_flags & (CH_CANSEEK|CH_POPENED|CH_HELPFILE)) { /* @@ -807,6 +830,8 @@ ch_close() public int ch_getflags() { + if (thisfile == NULL) + return (0); return (ch_flags); } diff --git a/contrib/less/charset.c b/contrib/less/charset.c index 3ee76bc6bcfb..628218d50f24 100644 --- a/contrib/less/charset.c +++ b/contrib/less/charset.c @@ -567,24 +567,29 @@ get_wchar(p) { case 1: default: + /* 0xxxxxxx */ return (LWCHAR) (p[0] & 0xFF); case 2: + /* 110xxxxx 10xxxxxx */ return (LWCHAR) ( ((p[0] & 0x1F) << 6) | (p[1] & 0x3F)); case 3: + /* 1110xxxx 10xxxxxx 10xxxxxx */ return (LWCHAR) ( ((p[0] & 0x0F) << 12) | ((p[1] & 0x3F) << 6) | (p[2] & 0x3F)); case 4: + /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ return (LWCHAR) ( ((p[0] & 0x07) << 18) | ((p[1] & 0x3F) << 12) | ((p[2] & 0x3F) << 6) | (p[3] & 0x3F)); case 5: + /* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ return (LWCHAR) ( ((p[0] & 0x03) << 24) | ((p[1] & 0x3F) << 18) | @@ -592,6 +597,7 @@ get_wchar(p) ((p[3] & 0x3F) << 6) | (p[4] & 0x3F)); case 6: + /* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ return (LWCHAR) ( ((p[0] & 0x01) << 30) | ((p[1] & 0x3F) << 24) | @@ -602,6 +608,56 @@ get_wchar(p) } } +/* + * Store a character into a UTF-8 string. + */ + public void +put_wchar(pp, ch) + char **pp; + LWCHAR ch; +{ + if (!utf_mode || ch < 0x80) + { + /* 0xxxxxxx */ + *(*pp)++ = (char) ch; + } else if (ch < 0x800) + { + /* 110xxxxx 10xxxxxx */ + *(*pp)++ = (char) (0xC0 | ((ch >> 6) & 0x1F)); + *(*pp)++ = (char) (0x80 | (ch & 0x3F)); + } else if (ch < 0x10000) + { + /* 1110xxxx 10xxxxxx 10xxxxxx */ + *(*pp)++ = (char) (0xE0 | ((ch >> 12) & 0x0F)); + *(*pp)++ = (char) (0x80 | ((ch >> 6) & 0x3F)); + *(*pp)++ = (char) (0x80 | (ch & 0x3F)); + } else if (ch < 0x200000) + { + /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + *(*pp)++ = (char) (0xF0 | ((ch >> 18) & 0x07)); + *(*pp)++ = (char) (0x80 | ((ch >> 12) & 0x3F)); + *(*pp)++ = (char) (0x80 | ((ch >> 6) & 0x3F)); + *(*pp)++ = (char) (0x80 | (ch & 0x3F)); + } else if (ch < 0x4000000) + { + /* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + *(*pp)++ = (char) (0xF0 | ((ch >> 24) & 0x03)); + *(*pp)++ = (char) (0x80 | ((ch >> 18) & 0x3F)); + *(*pp)++ = (char) (0x80 | ((ch >> 12) & 0x3F)); + *(*pp)++ = (char) (0x80 | ((ch >> 6) & 0x3F)); + *(*pp)++ = (char) (0x80 | (ch & 0x3F)); + } else + { + /* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + *(*pp)++ = (char) (0xF0 | ((ch >> 30) & 0x01)); + *(*pp)++ = (char) (0x80 | ((ch >> 24) & 0x3F)); + *(*pp)++ = (char) (0x80 | ((ch >> 18) & 0x3F)); + *(*pp)++ = (char) (0x80 | ((ch >> 12) & 0x3F)); + *(*pp)++ = (char) (0x80 | ((ch >> 6) & 0x3F)); + *(*pp)++ = (char) (0x80 | (ch & 0x3F)); + } +} + /* * Step forward or backward one character in a string. */ diff --git a/contrib/less/configure b/contrib/less/configure index 8501917f1928..3dbc604ebfef 100755 --- a/contrib/less/configure +++ b/contrib/less/configure @@ -6473,6 +6473,7 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include +#include int main () { diff --git a/contrib/less/configure.ac b/contrib/less/configure.ac index 80ec43a8cc1c..d738607ee30c 100644 --- a/contrib/less/configure.ac +++ b/contrib/less/configure.ac @@ -304,7 +304,8 @@ fi AC_MSG_CHECKING(for locale) AC_TRY_LINK([#include -#include ], [setlocale(LC_CTYPE,""); isprint(0); iscntrl(0);], +#include +#include ], [setlocale(LC_CTYPE,""); isprint(0); iscntrl(0);], [AC_MSG_RESULT(yes); AC_DEFINE(HAVE_LOCALE)], [AC_MSG_RESULT(no)]) AC_MSG_CHECKING(for ctype functions) AC_TRY_LINK([ diff --git a/contrib/less/filename.c b/contrib/less/filename.c index 8e0823e85744..ea3120fbbd89 100644 --- a/contrib/less/filename.c +++ b/contrib/less/filename.c @@ -482,7 +482,7 @@ bin_file(f) for (i = 0; i < n; i++) { char c = data[i]; - if (ctldisp == OPT_ONPLUS && c == ESC) + if (ctldisp == OPT_ONPLUS && IS_CSI_START(c)) { while (++i < n && is_ansi_middle(data[i])) continue; diff --git a/contrib/less/funcs.h b/contrib/less/funcs.h index 201052453d38..a4a0c7c2d9f0 100644 --- a/contrib/less/funcs.h +++ b/contrib/less/funcs.h @@ -56,6 +56,7 @@ public int utf_len (); public int is_utf8_well_formed (); public LWCHAR get_wchar (); + public void put_wchar (); public LWCHAR step_char (); public int is_composing_char (); public int is_ubin_char (); diff --git a/contrib/less/jump.c b/contrib/less/jump.c index 6e0c90dbcc10..585d9b209e6d 100644 --- a/contrib/less/jump.c +++ b/contrib/less/jump.c @@ -31,6 +31,7 @@ extern int top_scroll; jump_forw() { POSITION pos; + POSITION end_pos; if (ch_end_seek()) { @@ -42,11 +43,17 @@ jump_forw() * Go back one line from the end of the file * to get to the beginning of the last line. */ - pos = back_line(ch_tell()); + pos_clear(); + end_pos = ch_tell(); + pos = back_line(end_pos); if (pos == NULL_POSITION) jump_loc((POSITION)0, sc_height-1); else + { jump_loc(pos, sc_height-1); + if (position(sc_height-1) != end_pos) + repaint(); + } } /* diff --git a/contrib/less/less.h b/contrib/less/less.h index ada9e270ac91..eb40a0f4b47c 100644 --- a/contrib/less/less.h +++ b/contrib/less/less.h @@ -150,6 +150,8 @@ void free(); #define IS_DIGIT(c) ((c) >= '0' && (c) <= '9') #endif +#define IS_CSI_START(c) ((c) == ESC || ((unsigned char)(c)) == CSI) + #ifndef NULL #define NULL 0 #endif @@ -425,6 +427,7 @@ struct textlist #endif /* IS_EBCDIC_HOST */ #define ESC CONTROL('[') +#define CSI ((unsigned char)'\233') #if _OSK_MWC32 #define LSIGNAL(sig,func) os9_signal(sig,func) diff --git a/contrib/less/less.man b/contrib/less/less.man index 2efc49dfce82..217a321ccccc 100644 --- a/contrib/less/less.man +++ b/contrib/less/less.man @@ -1544,4 +1544,4 @@ LESS(1) LESS(1) - Version 406: 19 Jun 2007 LESS(1) + Version 408: 01 Oct 2007 LESS(1) diff --git a/contrib/less/less.nro b/contrib/less/less.nro index ddba6d85672a..5399e83a713c 100644 --- a/contrib/less/less.nro +++ b/contrib/less/less.nro @@ -1,4 +1,4 @@ -.TH LESS 1 "Version 406: 19 Jun 2007" +.TH LESS 1 "Version 408: 01 Oct 2007" .SH NAME less \- opposite of more .SH SYNOPSIS diff --git a/contrib/less/lessecho.man b/contrib/less/lessecho.man index 49c863a17e3c..2bf8c9ec0af9 100644 --- a/contrib/less/lessecho.man +++ b/contrib/less/lessecho.man @@ -46,4 +46,4 @@ LESSECHO(1) LESSECHO(1) - Version 406: 19 Jun 2007 LESSECHO(1) + Version 408: 01 Oct 2007 LESSECHO(1) diff --git a/contrib/less/lessecho.nro b/contrib/less/lessecho.nro index 297a7323b500..06c39361791f 100644 --- a/contrib/less/lessecho.nro +++ b/contrib/less/lessecho.nro @@ -1,4 +1,4 @@ -.TH LESSECHO 1 "Version 406: 19 Jun 2007" +.TH LESSECHO 1 "Version 408: 01 Oct 2007" .SH NAME lessecho \- expand metacharacters .SH SYNOPSIS diff --git a/contrib/less/lesskey.man b/contrib/less/lesskey.man index ffad2c346f4c..b4d4e2fc9cf4 100644 --- a/contrib/less/lesskey.man +++ b/contrib/less/lesskey.man @@ -357,4 +357,4 @@ LESSKEY(1) LESSKEY(1) - Version 406: 19 Jun 2007 LESSKEY(1) + Version 408: 01 Oct 2007 LESSKEY(1) diff --git a/contrib/less/lesskey.nro b/contrib/less/lesskey.nro index 63cb39a1dc63..a49a1c07a8cb 100644 --- a/contrib/less/lesskey.nro +++ b/contrib/less/lesskey.nro @@ -1,4 +1,4 @@ -.TH LESSKEY 1 "Version 406: 19 Jun 2007" +.TH LESSKEY 1 "Version 408: 01 Oct 2007" .SH NAME lesskey \- specify key bindings for less .SH SYNOPSIS diff --git a/contrib/less/line.c b/contrib/less/line.c index c1a31fb714da..217c24c5c267 100644 --- a/contrib/less/line.c +++ b/contrib/less/line.c @@ -269,7 +269,7 @@ pshift(shift) while (shifted <= shift && from < curr) { c = linebuf[from]; - if (c == ESC && ctldisp == OPT_ONPLUS) + if (ctldisp == OPT_ONPLUS && IS_CSI_START(c)) { /* Keep cumulative effect. */ linebuf[to] = c; @@ -524,7 +524,7 @@ in_ansi_esc_seq() for (p = &linebuf[curr]; p > linebuf; ) { LWCHAR ch = step_char(&p, -1, linebuf); - if (ch == ESC) + if (IS_CSI_START(ch)) return (1); if (!is_ansi_middle(ch)) return (0); @@ -603,13 +603,13 @@ store_char(ch, a, rep, pos) /* Remove whole unrecognized sequence. */ do { --curr; - } while (linebuf[curr] != ESC); + } while (!IS_CSI_START(linebuf[curr])); return 0; } a = AT_ANSI; /* Will force re-AT_'ing around it. */ w = 0; } - else if (ctldisp == OPT_ONPLUS && ch == ESC) + else if (ctldisp == OPT_ONPLUS && IS_CSI_START(ch)) { a = AT_ANSI; /* Will force re-AT_'ing around it. */ w = 0; @@ -943,7 +943,7 @@ do_append(ch, rep, pos) } else if ((!utf_mode || is_ascii_char(ch)) && control_char((char)ch)) { do_control_char: - if (ctldisp == OPT_ON || (ctldisp == OPT_ONPLUS && ch == ESC)) + if (ctldisp == OPT_ON || (ctldisp == OPT_ONPLUS && IS_CSI_START(ch))) { /* * Output as a normal character. diff --git a/contrib/less/search.c b/contrib/less/search.c index e81bce5c81d2..c3a3e768d5b4 100644 --- a/contrib/less/search.c +++ b/contrib/less/search.c @@ -16,6 +16,7 @@ #include "less.h" #include "position.h" +#include "charset.h" #define MINPOS(a,b) (((a) < (b)) ? (a) : (b)) #define MAXPOS(a,b) (((a) > (b)) ? (a) : (b)) @@ -120,24 +121,31 @@ cvt_text(odst, osrc, lenp, ops) int *lenp; int ops; { - register char *dst; - register char *src; + char *dst; + char *src; register char *src_end; + LWCHAR ch; if (lenp != NULL) src_end = osrc + *lenp; else src_end = osrc + strlen(osrc); - for (src = osrc, dst = odst; src < src_end; src++) + for (src = osrc, dst = odst; src < src_end; ) { - if ((ops & CVT_TO_LC) && IS_UPPER(*src)) + ch = step_char(&src, +1, src_end); + if ((ops & CVT_TO_LC) && IS_UPPER(ch)) + { /* Convert uppercase to lowercase. */ - *dst++ = TO_LOWER(*src); - else if ((ops & CVT_BS) && *src == '\b' && dst > odst) + put_wchar(&dst, TO_LOWER(ch)); + } else if ((ops & CVT_BS) && ch == '\b' && dst > odst) + { /* Delete BS and preceding char. */ - dst--; - else if ((ops & CVT_ANSI) && *src == ESC) + do { + dst--; + } while (dst > odst && + !IS_ASCII_OCTET(*dst) && !IS_UTF8_LEAD(*dst)); + } else if ((ops & CVT_ANSI) && IS_CSI_START(ch)) { /* Skip to end of ANSI escape sequence. */ while (src + 1 != src_end) @@ -145,7 +153,7 @@ cvt_text(odst, osrc, lenp, ops) break; } else /* Just copy. */ - *dst++ = *src; + put_wchar(&dst, ch); } if ((ops & CVT_CRLF) && dst > odst && dst[-1] == '\r') dst--; @@ -182,14 +190,18 @@ get_cvt_ops() * Are there any uppercase letters in this string? */ static int -is_ucase(s) - char *s; +is_ucase(str) + char *str; { - register char *p; + char *str_end = str + strlen(str); + LWCHAR ch; - for (p = s; *p != '\0'; p++) - if (IS_UPPER(*p)) + while (str < str_end) + { + ch = step_char(&str, +1, str_end); + if (IS_UPPER(ch)) return (1); + } return (0); } @@ -679,7 +691,7 @@ adj_hilite_ansi(cvt_ops, line, line_len, npos) char *line_end = *line + line_len; if (cvt_ops & CVT_ANSI) - while (**line == ESC) + while (IS_CSI_START(**line)) { /* * Found an ESC. The file position moves diff --git a/contrib/less/signal.c b/contrib/less/signal.c index 26dcadddc568..def985dba7e5 100644 --- a/contrib/less/signal.c +++ b/contrib/less/signal.c @@ -93,6 +93,8 @@ winch(type) { LSIGNAL(SIGWINCH, winch); sigs |= S_WINCH; + if (reading) + intread(); } #else #ifdef SIGWIND diff --git a/contrib/less/version.c b/contrib/less/version.c index df74e04f2aa0..a4d7ea757cb6 100644 --- a/contrib/less/version.c +++ b/contrib/less/version.c @@ -693,6 +693,8 @@ v403 5/25/07 Fix Windows build. v404 6/5/07 Fix display bug with F command and long lines. v405 6/17/07 Fix display bug when using -w option. v406 6/17/07 Fix secure build. +v407 8/16/07 Fix bugs; support CSI chars. +v408 10/1/07 Fix bug in -i with non-ASCII chars. */ -char version[] = "406"; +char version[] = "408";