svn commit: r326010 - in head: contrib/less usr.bin/less

Xin LI delphij at FreeBSD.org
Mon Nov 20 08:52:36 UTC 2017


Author: delphij
Date: Mon Nov 20 08:52:33 2017
New Revision: 326010
URL: https://svnweb.freebsd.org/changeset/base/326010

Log:
  MFV r326007: less v529.
  
  MFC after:	2 weeks

Added:
  head/contrib/less/fmt.uni
     - copied unchanged from r326007, vendor/less/dist/fmt.uni
Deleted:
  head/contrib/less/mkhelp.c
Modified:
  head/contrib/less/NEWS
  head/contrib/less/README
  head/contrib/less/ch.c
  head/contrib/less/charset.c
  head/contrib/less/cmd.h
  head/contrib/less/cmdbuf.c
  head/contrib/less/command.c
  head/contrib/less/compose.uni
  head/contrib/less/cvt.c
  head/contrib/less/decode.c
  head/contrib/less/edit.c
  head/contrib/less/filename.c
  head/contrib/less/forwback.c
  head/contrib/less/funcs.h
  head/contrib/less/help.c
  head/contrib/less/ifile.c
  head/contrib/less/input.c
  head/contrib/less/jump.c
  head/contrib/less/less.h
  head/contrib/less/less.hlp
  head/contrib/less/less.nro
  head/contrib/less/lessecho.nro
  head/contrib/less/lesskey.c
  head/contrib/less/lesskey.nro
  head/contrib/less/line.c
  head/contrib/less/main.c
  head/contrib/less/mark.c
  head/contrib/less/mkutable
  head/contrib/less/optfunc.c
  head/contrib/less/option.h
  head/contrib/less/opttbl.c
  head/contrib/less/output.c
  head/contrib/less/pattern.h
  head/contrib/less/position.c
  head/contrib/less/prompt.c
  head/contrib/less/screen.c
  head/contrib/less/search.c
  head/contrib/less/signal.c
  head/contrib/less/tags.c
  head/contrib/less/ubin.uni
  head/contrib/less/version.c
  head/contrib/less/wide.uni
  head/usr.bin/less/defines.h
Directory Properties:
  head/contrib/less/   (props changed)

Modified: head/contrib/less/NEWS
==============================================================================
--- head/contrib/less/NEWS	Mon Nov 20 08:12:40 2017	(r326009)
+++ head/contrib/less/NEWS	Mon Nov 20 08:52:33 2017	(r326010)
@@ -11,17 +11,59 @@
 
 ======================================================================
 
-	Major changes between "less" versions 487 and 491
+	Major changes between "less" versions 487 and 529
 
 * Don't output terminal init sequence if using -F and file fits on one screen.
 
-* Use ANSI prototypes in funcs.h declarations.
+* When using -S, mark truncated lines with a special character.
+  The character can be changed or disabled via the new --rscroll option.
 
-* Fix some const mismatches.
+* New command M marks the last line displayed on the screen.
 
-* Remove "register" in variable declarations.
+* New command ESC-m removes a line mark.
 
+* Status column (enabled via -J) now shows mark letters.
+
+* Status column shows search matches even if highlighting is disabled via -G.
+
+* A second ESC-u command will clear search match markers in the status column.
+
+* Do same ANSI escape code filtering for tag matching that we do for 
+  searching, to help when viewing syntax-highlighted code.
+  
+* Catch SIGTERM and clean up before exiting.
+
+* Fix bug initializing default charset on Windows.
+
+* Handle keypad ENTER key correctly if it sends something other than newline.
+
+* Fix buffering bug when using stdin with a LESSOPEN pipe.
+
+* On Windows, allow 'u' in -D option to enable underlining.
+
+* On Windows, use underline in sgr mode.
+
+* On Windows, convert UTF-8 to multibyte if console is not UTF-8.
+
+* Update Unicode tables to 2017-03-08.
+
+* Pass-thru Unicode formating chars (Cf type) instead of treating them
+  as binary chars. But treat them as binary if -U is set.
+
+* Fix erroneous binary file warning when UTF-8 file contains ANSI SGR sequences.
+
+* Fix bugs when using LESSOPEN and switching between stdin and other files.
+
+* Fix some bugs handling filenames containing shell metacharacters.
+
 * Fix some memory leaks.
+
+* Allow some debugging environment variables to be set in lesskey file.
+
+* Code improvements:
+  . Use ANSI prototypes in funcs.h declarations.
+  . Fix some const mismatches.
+  . Remove archaic "register" in variable declarations.
 
 ======================================================================
 

Modified: head/contrib/less/README
==============================================================================
--- head/contrib/less/README	Mon Nov 20 08:12:40 2017	(r326009)
+++ head/contrib/less/README	Mon Nov 20 08:52:33 2017	(r326010)
@@ -7,9 +7,9 @@
 **************************************************************************
 **************************************************************************
 
-                            Less, version 491
+                            Less, version 529
 
-    This is the distribution of less, version 491, released 07 Apr 2017.
+    This is the distribution of less, version 529, released 13 Nov 2017.
     This program is part of the GNU project (http://www.gnu.org).
 
     This program is free software.  You may redistribute it and/or
@@ -23,6 +23,7 @@
 
     Please report any problems to bug-less at gnu.org.
     See http://www.greenwoodsoftware.com/less for the latest info.
+    Source repository is at https://github.com/gwsw/less.git.
 
 =========================================================================
 

Modified: head/contrib/less/ch.c
==============================================================================
--- head/contrib/less/ch.c	Mon Nov 20 08:12:40 2017	(r326009)
+++ head/contrib/less/ch.c	Mon Nov 20 08:52:33 2017	(r326010)
@@ -867,13 +867,12 @@ ch_init(f, flags)
 				calloc(1, sizeof(struct filestate));
 		thisfile->buflist.next = thisfile->buflist.prev = END_OF_CHAIN;
 		thisfile->nbufs = 0;
-		thisfile->flags = 0;
+		thisfile->flags = flags;
 		thisfile->fpos = 0;
 		thisfile->block = 0;
 		thisfile->offset = 0;
 		thisfile->file = -1;
 		thisfile->fsize = NULL_POSITION;
-		ch_flags = flags;
 		init_hashtbl();
 		/*
 		 * Try to seek; set CH_CANSEEK if it works.
@@ -898,7 +897,7 @@ ch_close()
 	if (thisfile == NULL)
 		return;
 
-	if (ch_flags & (CH_CANSEEK|CH_POPENED|CH_HELPFILE))
+	if ((ch_flags & (CH_CANSEEK|CH_POPENED|CH_HELPFILE)) && !(ch_flags & CH_KEEPOPEN))
 	{
 		/*
 		 * We can seek or re-open, so we don't need to keep buffers.

Modified: head/contrib/less/charset.c
==============================================================================
--- head/contrib/less/charset.c	Mon Nov 20 08:12:40 2017	(r326009)
+++ head/contrib/less/charset.c	Mon Nov 20 08:52:33 2017	(r326010)
@@ -22,6 +22,13 @@
 
 #include "charset.h"
 
+#if MSDOS_COMPILER==WIN32C
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
+extern int bs_mode;
+
 public int utf_mode = 0;
 
 /*
@@ -215,7 +222,13 @@ icharset(name, no_error)
 		{
 			ichardef(p->desc);
 			if (p->p_flag != NULL)
+			{
+#if MSDOS_COMPILER==WIN32C
+				*(p->p_flag) = 1 + (GetConsoleOutputCP() != CP_UTF8);
+#else
 				*(p->p_flag) = 1;
+#endif
+			}
 			return (1);
 		}
 	}
@@ -251,16 +264,17 @@ ilocale()
 /*
  * Define the printing format for control (or binary utf) chars.
  */
-   	static void
-setbinfmt(s, fmtvarptr, default_fmt)
+	public void
+setfmt(s, fmtvarptr, attrptr, default_fmt)
 	char *s;
 	char **fmtvarptr;
+	int *attrptr;
 	char *default_fmt;
 {
 	if (s && utf_mode)
 	{
 		/* It would be too hard to account for width otherwise.  */
-		char *t = s;
+		char constant *t = s;
 		while (*t)
 		{
 			if (*t < ' ' || *t > '~')
@@ -282,15 +296,15 @@ setbinfmt(s, fmtvarptr, default_fmt)
 	 * Select the attributes if it starts with "*".
 	 */
  attr:
-	if (*s == '*')
+	if (*s == '*' && s[1] != '\0')
 	{
 		switch (s[1])
 		{
-		case 'd':  binattr = AT_BOLD;      break;
-		case 'k':  binattr = AT_BLINK;     break;
-		case 's':  binattr = AT_STANDOUT;  break;
-		case 'u':  binattr = AT_UNDERLINE; break;
-		default:   binattr = AT_NORMAL;    break;
+		case 'd':  *attrptr = AT_BOLD;      break;
+		case 'k':  *attrptr = AT_BLINK;     break;
+		case 's':  *attrptr = AT_STANDOUT;  break;
+		case 'u':  *attrptr = AT_UNDERLINE; break;
+		default:   *attrptr = AT_NORMAL;    break;
 		}
 		s += 2;
 	}
@@ -305,7 +319,15 @@ set_charset()
 {
 	char *s;
 
+#if MSDOS_COMPILER==WIN32C
 	/*
+	 * If the Windows console is using UTF-8, we'll use it too.
+	 */
+	if (GetConsoleOutputCP() == CP_UTF8)
+		if (icharset("utf-8", 1))
+			return;
+#endif
+	/*
 	 * See if environment variable LESSCHARSET is defined.
 	 */
 	s = lgetenv("LESSCHARSET");
@@ -354,6 +376,7 @@ set_charset()
 	 * rather than from predefined charset entry.
 	 */
 	ilocale();
+#else
 #if MSDOS_COMPILER
 	/*
 	 * Default to "dos".
@@ -383,10 +406,10 @@ init_charset()
 	set_charset();
 
 	s = lgetenv("LESSBINFMT");
-	setbinfmt(s, &binfmt, "*s<%02X>");
+	setfmt(s, &binfmt, &binattr, "*s<%02X>");
 	
 	s = lgetenv("LESSUTFBINFMT");
-	setbinfmt(s, &utfbinfmt, "<U+%04lX>");
+	setfmt(s, &utfbinfmt, &binattr, "<U+%04lX>");
 }
 
 /*
@@ -543,34 +566,19 @@ is_utf8_well_formed(ss, slen)
 }
 
 /*
- * Return number of invalid UTF-8 sequences found in a buffer.
+ * Skip bytes until a UTF-8 lead byte (11xxxxxx) or ASCII byte (0xxxxxxx) is found.
  */
-	public int
-utf_bin_count(data, len)
-	char *data;
-	int len;
+	public void
+utf_skip_to_lead(pp, limit)
+	char **pp;
+	char *limit;
 {
-	int bin_count = 0;
-	while (len > 0)
-	{
-		if (is_utf8_well_formed(data, len))
-		{
-			int clen = utf_len(*data & 0377);
-			data += clen;
-			len -= clen;
-		} else
-		{
-			/* Skip to next lead byte. */
-			bin_count++;
-			do {
-				++data;
-				--len;
-			} while (len > 0 && !IS_UTF8_LEAD(*data & 0377));
-		}
-	}
-	return (bin_count);
+	do {
+		++(*pp);
+	} while (*pp < limit && !IS_UTF8_LEAD((*pp)[0] & 0377) && !IS_ASCII_OCTET((*pp)[0]));
 }
 
+
 /*
  * Get the value of a UTF-8 character.
  */
@@ -690,9 +698,9 @@ step_char(pp, dir, limit)
 	{
 		/* It's easy if chars are one byte. */
 		if (dir > 0)
-			ch = (LWCHAR) ((p < limit) ? *p++ : 0);
+			ch = (LWCHAR) (unsigned char) ((p < limit) ? *p++ : 0);
 		else
-			ch = (LWCHAR) ((p > limit) ? *--p : 0);
+			ch = (LWCHAR) (unsigned char) ((p > limit) ? *--p : 0);
 	} else if (dir > 0)
 	{
 		len = utf_len(*p);
@@ -740,6 +748,10 @@ DECLARE_RANGE_TABLE_START(wide)
 #include "wide.uni"
 DECLARE_RANGE_TABLE_END(wide)
 
+DECLARE_RANGE_TABLE_START(fmt)
+#include "fmt.uni"
+DECLARE_RANGE_TABLE_END(fmt)
+
 /* comb_table is special pairs, not ranges. */
 static struct wchar_range comb_table[] = {
 	{0x0644,0x0622}, {0x0644,0x0623}, {0x0644,0x0625}, {0x0644,0x0627},
@@ -780,7 +792,8 @@ is_in_table(ch, table)
 is_composing_char(ch)
 	LWCHAR ch;
 {
-	return is_in_table(ch, &compose_table);
+	return is_in_table(ch, &compose_table) ||
+	       (bs_mode != BS_CONTROL && is_in_table(ch, &fmt_table));
 }
 
 /*
@@ -790,7 +803,21 @@ is_composing_char(ch)
 is_ubin_char(ch)
 	LWCHAR ch;
 {
-	return is_in_table(ch, &ubin_table);
+	int ubin = is_in_table(ch, &ubin_table) ||
+	           (bs_mode == BS_CONTROL && is_in_table(ch, &fmt_table));
+#if MSDOS_COMPILER==WIN32C
+	if (!ubin && utf_mode == 2 && ch < 0x10000)
+	{
+		/*
+		 * Consider it binary if it can't be converted.
+		 */
+		BOOL used_default = TRUE;
+		WideCharToMultiByte(GetConsoleOutputCP(), WC_NO_BEST_FIT_CHARS, (LPCWSTR) &ch, 1, NULL, 0, NULL, &used_default);
+		if (used_default)
+			ubin = 1;
+	}
+#endif
+	return ubin;
 }
 
 /*

Modified: head/contrib/less/cmd.h
==============================================================================
--- head/contrib/less/cmd.h	Mon Nov 20 08:12:40 2017	(r326009)
+++ head/contrib/less/cmd.h	Mon Nov 20 08:52:33 2017	(r326010)
@@ -8,129 +8,131 @@
  */
 
 
-#define	MAX_USERCMD		1000
-#define	MAX_CMDLEN		16
+#define MAX_USERCMD            1000
+#define MAX_CMDLEN             16
 
-#define	A_B_LINE		2
-#define	A_B_SCREEN		3
-#define	A_B_SCROLL		4
-#define	A_B_SEARCH		5
-#define	A_DIGIT			6
-#define	A_DISP_OPTION		7
-#define	A_DEBUG			8
-#define	A_EXAMINE		9
-#define	A_FIRSTCMD		10
-#define	A_FREPAINT		11
-#define	A_F_LINE		12
-#define	A_F_SCREEN		13
-#define	A_F_SCROLL		14
-#define	A_F_SEARCH		15
-#define	A_GOEND			16
-#define	A_GOLINE		17
-#define	A_GOMARK		18
-#define	A_HELP			19
-#define	A_NEXT_FILE		20
-#define	A_PERCENT		21
-#define	A_PREFIX		22
-#define	A_PREV_FILE		23
-#define	A_QUIT			24
-#define	A_REPAINT		25
-#define	A_SETMARK		26
-#define	A_SHELL			27
-#define	A_STAT			28
-#define	A_FF_LINE		29
-#define	A_BF_LINE		30
-#define	A_VERSION		31
-#define	A_VISUAL		32
-#define	A_F_WINDOW		33
-#define	A_B_WINDOW		34
-#define	A_F_BRACKET		35
-#define	A_B_BRACKET		36
-#define	A_PIPE			37
-#define	A_INDEX_FILE		38
-#define	A_UNDO_SEARCH		39
-#define	A_FF_SCREEN		40
-#define	A_LSHIFT		41
-#define	A_RSHIFT		42
-#define	A_AGAIN_SEARCH		43
-#define	A_T_AGAIN_SEARCH	44
-#define	A_REVERSE_SEARCH	45
-#define	A_T_REVERSE_SEARCH	46
-#define	A_OPT_TOGGLE		47
-#define	A_OPT_SET		48
-#define	A_OPT_UNSET		49
-#define	A_F_FOREVER		50
-#define	A_GOPOS			51
-#define	A_REMOVE_FILE		52
-#define	A_NEXT_TAG		53
-#define	A_PREV_TAG		54
-#define	A_FILTER		55
-#define	A_F_UNTIL_HILITE	56
-#define	A_GOEND_BUF		57
-#define	A_LLSHIFT		58
-#define	A_RRSHIFT		59
+#define A_B_LINE               2
+#define A_B_SCREEN             3
+#define A_B_SCROLL             4
+#define A_B_SEARCH             5
+#define A_DIGIT                6
+#define A_DISP_OPTION          7
+#define A_DEBUG                8
+#define A_EXAMINE              9
+#define A_FIRSTCMD             10
+#define A_FREPAINT             11
+#define A_F_LINE               12
+#define A_F_SCREEN             13
+#define A_F_SCROLL             14
+#define A_F_SEARCH             15
+#define A_GOEND                16
+#define A_GOLINE               17
+#define A_GOMARK               18
+#define A_HELP                 19
+#define A_NEXT_FILE            20
+#define A_PERCENT              21
+#define A_PREFIX               22
+#define A_PREV_FILE            23
+#define A_QUIT                 24
+#define A_REPAINT              25
+#define A_SETMARK              26
+#define A_SHELL                27
+#define A_STAT                 28
+#define A_FF_LINE              29
+#define A_BF_LINE              30
+#define A_VERSION              31
+#define A_VISUAL               32
+#define A_F_WINDOW             33
+#define A_B_WINDOW             34
+#define A_F_BRACKET            35
+#define A_B_BRACKET            36
+#define A_PIPE                 37
+#define A_INDEX_FILE           38
+#define A_UNDO_SEARCH          39
+#define A_FF_SCREEN            40
+#define A_LSHIFT               41
+#define A_RSHIFT               42
+#define A_AGAIN_SEARCH         43
+#define A_T_AGAIN_SEARCH       44
+#define A_REVERSE_SEARCH       45
+#define A_T_REVERSE_SEARCH     46
+#define A_OPT_TOGGLE           47
+#define A_OPT_SET              48
+#define A_OPT_UNSET            49
+#define A_F_FOREVER            50
+#define A_GOPOS                51
+#define A_REMOVE_FILE          52
+#define A_NEXT_TAG             53
+#define A_PREV_TAG             54
+#define A_FILTER               55
+#define A_F_UNTIL_HILITE       56
+#define A_GOEND_BUF            57
+#define A_LLSHIFT              58
+#define A_RRSHIFT              59
+#define A_CLRMARK              62
+#define A_SETMARKBOT           63
 
-#define	A_INVALID		100
-#define	A_NOACTION		101
-#define	A_UINVALID		102
-#define	A_END_LIST		103
-#define	A_SPECIAL_KEY		104
+#define A_INVALID              100
+#define A_NOACTION             101
+#define A_UINVALID             102
+#define A_END_LIST             103
+#define A_SPECIAL_KEY          104
 
-#define A_SKIP			127
+#define A_SKIP                 127
 
-#define	A_EXTRA			0200
+#define A_EXTRA                0200
 
 
 /* Line editing characters */
 
-#define	EC_BACKSPACE	1
-#define	EC_LINEKILL	2
-#define	EC_RIGHT	3
-#define	EC_LEFT		4
-#define	EC_W_LEFT	5
-#define	EC_W_RIGHT	6
-#define	EC_INSERT 	7
-#define	EC_DELETE	8
-#define	EC_HOME		9
-#define	EC_END		10
-#define	EC_W_BACKSPACE	11
-#define	EC_W_DELETE	12
-#define	EC_UP		13
-#define	EC_DOWN		14
-#define	EC_EXPAND	15
-#define	EC_F_COMPLETE	17
-#define	EC_B_COMPLETE	18
-#define	EC_LITERAL	19
-#define	EC_ABORT	20
+#define EC_BACKSPACE           1
+#define EC_LINEKILL            2
+#define EC_RIGHT               3
+#define EC_LEFT                4
+#define EC_W_LEFT              5
+#define EC_W_RIGHT             6
+#define EC_INSERT              7
+#define EC_DELETE              8
+#define EC_HOME                9
+#define EC_END                 10
+#define EC_W_BACKSPACE         11
+#define EC_W_DELETE            12
+#define EC_UP                  13
+#define EC_DOWN                14
+#define EC_EXPAND              15
+#define EC_F_COMPLETE          17
+#define EC_B_COMPLETE          18
+#define EC_LITERAL             19
+#define EC_ABORT               20
 
-#define	EC_NOACTION	101
-#define	EC_UINVALID	102
+#define EC_NOACTION            101
+#define EC_UINVALID            102
 
 /* Flags for editchar() */
-#define	EC_PEEK		01
-#define	EC_NOHISTORY	02
-#define	EC_NOCOMPLETE	04
-#define	EC_NORIGHTLEFT	010
+#define EC_PEEK                01
+#define EC_NOHISTORY           02
+#define EC_NOCOMPLETE          04
+#define EC_NORIGHTLEFT         010
 
 /* Environment variable stuff */
-#define	EV_OK		01
+#define EV_OK                  01
 
 /* Special keys (keys which output different strings on different terminals) */
-#define SK_SPECIAL_KEY		CONTROL('K')
-#define SK_RIGHT_ARROW		1
-#define SK_LEFT_ARROW		2
-#define SK_UP_ARROW		3
-#define SK_DOWN_ARROW		4
-#define SK_PAGE_UP		5
-#define SK_PAGE_DOWN		6
-#define SK_HOME			7
-#define SK_END			8
-#define SK_DELETE		9
-#define SK_INSERT		10
-#define SK_CTL_LEFT_ARROW	11
-#define SK_CTL_RIGHT_ARROW	12
-#define SK_CTL_DELETE		13
-#define SK_F1			14
-#define SK_BACKTAB		15
-#define SK_CTL_BACKSPACE	16
-#define SK_CONTROL_K		40
+#define SK_SPECIAL_KEY         CONTROL('K')
+#define SK_RIGHT_ARROW         1
+#define SK_LEFT_ARROW          2
+#define SK_UP_ARROW            3
+#define SK_DOWN_ARROW          4
+#define SK_PAGE_UP             5
+#define SK_PAGE_DOWN           6
+#define SK_HOME                7
+#define SK_END                 8
+#define SK_DELETE              9
+#define SK_INSERT              10
+#define SK_CTL_LEFT_ARROW      11
+#define SK_CTL_RIGHT_ARROW     12
+#define SK_CTL_DELETE          13
+#define SK_F1                  14
+#define SK_BACKTAB             15
+#define SK_CTL_BACKSPACE       16
+#define SK_CONTROL_K           40

Modified: head/contrib/less/cmdbuf.c
==============================================================================
--- head/contrib/less/cmdbuf.c	Mon Nov 20 08:12:40 2017	(r326009)
+++ head/contrib/less/cmdbuf.c	Mon Nov 20 08:52:33 2017	(r326010)
@@ -40,7 +40,7 @@ static int in_completion = 0;
 static char *tk_text;
 static char *tk_original;
 static char *tk_ipoint;
-static char *tk_trial;
+static char *tk_trial = NULL;
 static struct textlist tk_tlist;
 #endif
 
@@ -427,8 +427,9 @@ cmd_right()
 cmd_left()
 {
 	char *ncp;
-	int width, bswidth;
-	
+	int width = 0;
+	int bswidth = 0;
+
 	if (cp <= cmdbuf)
 	{
 		/* Already at the beginning of the line */
@@ -1223,6 +1224,13 @@ cmd_char(c)
 			*cmd_mbc_buf = c;
 			if (IS_ASCII_OCTET(c))
 				cmd_mbc_buf_len = 1;
+#if MSDOS_COMPILER || OS2
+			else if (c == (unsigned char) '\340' && IS_ASCII_OCTET(peekcc()))
+			{
+				/* Assume a special key. */
+				cmd_mbc_buf_len = 1;
+			}
+#endif
 			else if (IS_UTF8_LEAD(c))
 			{
 				cmd_mbc_buf_len = utf_len(c);

Modified: head/contrib/less/command.c
==============================================================================
--- head/contrib/less/command.c	Mon Nov 20 08:12:40 2017	(r326009)
+++ head/contrib/less/command.c	Mon Nov 20 08:52:33 2017	(r326010)
@@ -27,6 +27,7 @@ extern int quit_if_one_screen;
 extern int squished;
 extern int sc_width;
 extern int sc_height;
+extern char *kent;
 extern int swindow;
 extern int jump_sline;
 extern int quitting;
@@ -38,9 +39,11 @@ extern int hshift;
 extern int bs_mode;
 extern int show_attn;
 extern int less_is_more;
+extern int status_col;
 extern POSITION highest_hilite;
+extern POSITION start_attnpos;
+extern POSITION end_attnpos;
 extern char *every_first_cmd;
-extern char *curr_altfilename;
 extern char version[];
 extern struct scrpos initial_scrpos;
 extern IFILE curr_ifile;
@@ -57,7 +60,6 @@ extern int screen_trashed;	/* The screen has been over
 extern int shift_count;
 extern int oldbot;
 extern int forw_prompt;
-extern int same_pos_bell;
 
 #if SHELL_ESCAPE
 static char *shellcmd = NULL;	/* For holding last shell command for "!!" */
@@ -77,10 +79,10 @@ static int save_bs_mode;
 static char pipec;
 #endif
 
+/* Stack of ungotten chars (via ungetcc) */
 struct ungot {
 	struct ungot *ug_next;
-	char ug_char;
-	char ug_end_command;
+	LWCHAR ug_char;
 };
 static struct ungot* ungot = NULL;
 
@@ -94,9 +96,7 @@ static void multi_search();
 	static void
 cmd_exec()
 {
-#if HILITE_SEARCH
-	clear_attn();
-#endif
+    clear_attn();
 	clear_bot();
 	flush();
 }
@@ -303,11 +303,21 @@ is_erase_char(c)
 }
 
 /*
+ * Is a character a carriage return or newline?
+ */
+	static int
+is_newline_char(c)
+	int c;
+{
+	return (c == '\n' || c == '\r');
+}
+
+/*
  * Handle the first char of an option (after the initial dash).
  */
 	static int
 mca_opt_first_char(c)
-    int c;
+	int c;
 {
 	int flag = (optflag & ~OPT_NO_PROMPT);
 	if (flag == OPT_NO_TOGGLE)
@@ -427,7 +437,7 @@ mca_opt_char(c)
 	if (optgetname)
 	{
 		/* We're getting a long option name.  */
-		if (c != '\n' && c != '\r')
+		if (!is_newline_char(c))
 			return (mca_opt_nonfirst_char(c));
 		if (curropt == NULL)
 		{
@@ -595,7 +605,7 @@ mca_char(c)
 	/*
 	 * The multichar command is terminated by a newline.
 	 */
-	if (c == '\n' || c == '\r')
+	if (is_newline_char(c))
 	{
 		/*
 		 * Execute the command.
@@ -693,7 +703,7 @@ prompt()
 {
 	constant char *p;
 
-	if (ungot != NULL && !ungot->ug_end_command)
+	if (ungot != NULL && ungot->ug_char != CHAR_END_COMMAND)
 	{
 		/*
 		 * No prompt necessary if commands are from 
@@ -775,74 +785,122 @@ dispversion()
 }
 
 /*
+ * Return a character to complete a partial command, if possible.
+ */
+	static LWCHAR
+getcc_end_command()
+{
+	switch (mca)
+	{
+	case A_DIGIT:
+		/* We have a number but no command.  Treat as #g. */
+		return ('g');
+	case A_F_SEARCH:
+	case A_B_SEARCH:
+		/* We have "/string" but no newline.  Add the \n. */
+		return ('\n'); 
+	default:
+		/* Some other incomplete command.  Let user complete it. */
+		return (getchr());
+	}
+}
+
+/*
  * Get command character.
  * The character normally comes from the keyboard,
  * but may come from ungotten characters
  * (characters previously given to ungetcc or ungetsc).
  */
-	public int
-getcc()
+	static LWCHAR
+getccu()
 {
+	LWCHAR c;
 	if (ungot == NULL)
 	{
-		/*
-		 * Normal case: no ungotten chars, so get one from the user.
-		 */
-		return (getchr());
-	}
-
-	/*
-	 * Return the next ungotten char.
-	 */
+		/* Normal case: no ungotten chars.
+		 * Get char from the user. */
+		c = getchr();
+	} else
 	{
+		/* Ungotten chars available:
+		 * Take the top of stack (most recent). */
 		struct ungot *ug = ungot;
-		char c = ug->ug_char;
-		int end_command = ug->ug_end_command;
+		c = ug->ug_char;
 		ungot = ug->ug_next;
 		free(ug);
-		if (end_command)
-		{
-			/*
-			 * Command is incomplete, so try to complete it.
-			 */
-			switch (mca)
-			{
-			case A_DIGIT:
-				/*
-				 * We have a number but no command.  Treat as #g.
-				 */
-				return ('g');
 
-			case A_F_SEARCH:
-			case A_B_SEARCH:
-				/*
-				 * We have "/string" but no newline.  Add the \n.
-				 */
-				return ('\n'); 
+		if (c == CHAR_END_COMMAND)
+			c = getcc_end_command();
+	}
+	return (c);
+}
 
-			default:
-				/*
-				 * Some other incomplete command.  Let user complete it.
-				 */
-				return (getchr());
-			}
+/*
+ * Get a command character, but if we receive the orig sequence,
+ * convert it to the repl sequence.
+ */
+	static LWCHAR
+getcc_repl(orig, repl, gr_getc, gr_ungetc)
+	char const* orig;
+	char const* repl;
+	LWCHAR (*gr_getc)(VOID_PARAM);
+	void (*gr_ungetc)(LWCHAR);
+{
+	LWCHAR c;
+	LWCHAR keys[16];
+	int ki = 0;
+
+	c = (*gr_getc)();
+	if (orig == NULL || orig[0] == '\0')
+		return c;
+	for (;;)
+	{
+		keys[ki] = c;
+		if (c != orig[ki] || ki >= sizeof(keys)-1)
+		{
+			/* This is not orig we have been receiving.
+			 * If we have stashed chars in keys[],
+			 * unget them and return the first one. */
+			while (ki > 0)
+				(*gr_ungetc)(keys[ki--]);
+			return keys[0];
 		}
-		return (c);
+		if (orig[++ki] == '\0')
+		{
+			/* We've received the full orig sequence.
+			 * Return the repl sequence. */
+			ki = strlen(repl)-1;
+			while (ki > 0)
+				(*gr_ungetc)(repl[ki--]);
+			return repl[0];
+		}
+		/* We've received a partial orig sequence (ki chars of it).
+		 * Get next char and see if it continues to match orig. */
+		c = (*gr_getc)();
 	}
 }
 
 /*
+ * Get command character.
+ */
+	public int
+getcc()
+{
+    /* Replace kent (keypad Enter) with a newline. */
+    return getcc_repl(kent, "\n", getccu, ungetcc);
+}
+
+/*
  * "Unget" a command character.
  * The next getcc() will return this character.
  */
 	public void
 ungetcc(c)
-	int c;
+	LWCHAR c;
 {
 	struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot));
 
-	ug->ug_char = (char) c;
-	ug->ug_end_command = (c == CHAR_END_COMMAND);
+	ug->ug_char = c;
 	ug->ug_next = ungot;
 	ungot = ug;
 }
@@ -862,6 +920,17 @@ ungetsc(s)
 }
 
 /*
+ * Peek the next command character, without consuming it.
+ */
+	public LWCHAR
+peekcc()
+{
+	LWCHAR c = getcc();
+	ungetcc(c);
+	return c;
+}
+
+/*
  * Search for a pattern, possibly in multiple files.
  * If SRCH_FIRST_FILE is set, begin searching at the first file.
  * If SRCH_PAST_EOF is set, continue the search thru multiple files.
@@ -1477,6 +1546,9 @@ commands()
 			break;
 
 		case A_UNDO_SEARCH:
+			/*
+			 * Clear search string highlighting.
+			 */
 			undo_search();
 			break;
 
@@ -1495,60 +1567,54 @@ commands()
 			break;
 
 		case A_EXAMINE:
-#if EXAMINE
 			/*
 			 * Edit a new file.  Get the filename.
 			 */
-			if (secure)
+#if EXAMINE
+			if (!secure)
 			{
-				error("Command not available", NULL_PARG);
-				break;
+				start_mca(A_EXAMINE, "Examine: ", ml_examine, 0);
+				c = getcc();
+				goto again;
 			}
-			start_mca(A_EXAMINE, "Examine: ", ml_examine, 0);
-			c = getcc();
-			goto again;
-#else
+#endif
 			error("Command not available", NULL_PARG);
 			break;
-#endif
 			
 		case A_VISUAL:
 			/*
 			 * Invoke an editor on the input file.
 			 */
 #if EDITOR
-			if (secure)
+			if (!secure)
 			{
-				error("Command not available", NULL_PARG);
+				if (ch_getflags() & CH_HELPFILE)
+					break;
+				if (strcmp(get_filename(curr_ifile), "-") == 0)
+				{
+					error("Cannot edit standard input", NULL_PARG);
+					break;
+				}
+				if (get_altfilename(curr_ifile) != NULL)
+				{
+					error("WARNING: This file was viewed via LESSOPEN",
+						NULL_PARG);
+				}
+				start_mca(A_SHELL, "!", ml_shell, 0);
+				/*
+				 * Expand the editor prototype string
+				 * and pass it to the system to execute.
+				 * (Make sure the screen is displayed so the
+				 * expansion of "+%lm" works.)
+				 */
+				make_display();
+				cmd_exec();
+				lsystem(pr_expand(editproto, 0), (char*)NULL);
 				break;
 			}
-			if (ch_getflags() & CH_HELPFILE)
-				break;
-			if (strcmp(get_filename(curr_ifile), "-") == 0)
-			{
-				error("Cannot edit standard input", NULL_PARG);
-				break;
-			}
-			if (curr_altfilename != NULL)
-			{
-				error("WARNING: This file was viewed via LESSOPEN",
-					NULL_PARG);
-			}
-			start_mca(A_SHELL, "!", ml_shell, 0);
-			/*
-			 * Expand the editor prototype string
-			 * and pass it to the system to execute.
-			 * (Make sure the screen is displayed so the
-			 * expansion of "+%lm" works.)
-			 */
-			make_display();
-			cmd_exec();
-			lsystem(pr_expand(editproto, 0), (char*)NULL);
-			break;
-#else
+#endif
 			error("Command not available", NULL_PARG);
 			break;
-#endif
 
 		case A_NEXT_FILE:
 			/*
@@ -1594,6 +1660,9 @@ commands()
 			break;
 
 		case A_NEXT_TAG:
+			/*
+			 * Jump to the next tag in the current tag list.

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list