Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 02 Feb 2026 20:51:59 +0000
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: dafba19e42e7 - main - MFV less v691
Message-ID:  <69810e6f.3e40d.3f762f14@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by delphij:

URL: https://cgit.FreeBSD.org/src/commit/?id=dafba19e42e78cd3d7c9264ece49ddd3d7d70da5

commit dafba19e42e78cd3d7c9264ece49ddd3d7d70da5
Merge: 69f535564125 c408e7413bcf
Author:     Xin LI <delphij@FreeBSD.org>
AuthorDate: 2026-02-02 20:50:35 +0000
Commit:     Xin LI <delphij@FreeBSD.org>
CommitDate: 2026-02-02 20:50:35 +0000

    MFV less v691
    
    Relnotes:       yes
    MFC after:      2 weeks

 contrib/less/NEWS            |   62 ++
 contrib/less/README          |   60 +-
 contrib/less/ch.c            |   12 +-
 contrib/less/charset.c       |   14 +-
 contrib/less/cmd.h           |   22 +
 contrib/less/cmdbuf.c        |  136 ++--
 contrib/less/command.c       |   85 +--
 contrib/less/compose.uni     |   14 +-
 contrib/less/decode.c        |  101 ++-
 contrib/less/edit.c          |   14 +-
 contrib/less/filename.c      |   13 +-
 contrib/less/fmt.uni         |    2 +-
 contrib/less/forwback.c      |   35 +-
 contrib/less/funcs.h         |   75 ++-
 contrib/less/help.c          |    5 +-
 contrib/less/ifile.c         |   10 +-
 contrib/less/input.c         |    1 -
 contrib/less/jump.c          |   16 +-
 contrib/less/lang.h          |    3 +
 contrib/less/less.h          |   17 +-
 contrib/less/less.hlp        |    3 +
 contrib/less/less.nro        | 1487 ++++++++++++++++++++++++++++--------------
 contrib/less/lessecho.nro    |   37 +-
 contrib/less/lesskey.nro     |  357 ++++++----
 contrib/less/lesskey_parse.c |   26 +-
 contrib/less/line.c          |   37 +-
 contrib/less/lsystem.c       |   20 +-
 contrib/less/main.c          |   53 +-
 contrib/less/mark.c          |  152 +++--
 contrib/less/omit.uni        |    2 +-
 contrib/less/optfunc.c       |  128 ++--
 contrib/less/option.c        |  132 ++--
 contrib/less/opttbl.c        |    7 +
 contrib/less/os.c            |   63 +-
 contrib/less/output.c        |   36 +-
 contrib/less/pckeys.h        |   41 +-
 contrib/less/position.c      |   14 +-
 contrib/less/prompt.c        |   36 +-
 contrib/less/screen.c        |  486 +++++++++-----
 contrib/less/search.c        |   21 +-
 contrib/less/signal.c        |   28 +-
 contrib/less/tags.c          |    7 +-
 contrib/less/ttyin.c         |    4 +-
 contrib/less/ubin.uni        |    2 +-
 contrib/less/version.c       |   15 +-
 contrib/less/wide.uni        |   23 +-
 contrib/less/xbuf.c          |    3 +-
 contrib/less/xbuf.h          |    2 +-
 usr.bin/less/defines.h       |  116 ++--
 49 files changed, 2651 insertions(+), 1384 deletions(-)

diff --cc contrib/less/README
index 4bfdc5e5a67f,000000000000..a6954eb67c1e
mode 100644,000000..100644
--- a/contrib/less/README
+++ b/contrib/less/README
@@@ -1,254 -1,0 +1,242 @@@
 +**************************************************************************
 +**************************************************************************
 +**                                                                      **
 +** The FreeBSD Project has chosen to redistribute and modify Less under **
 +** the 'Less License' (as described in the 'LICENSE' file).             **
 +**                                                                      **
 +**************************************************************************
 +**************************************************************************
 +
 +    This is the source code distribution of "less".
 +    This program is part of the GNU project (https://www.gnu.org).
 +
 +    This program is free software.  You may redistribute it and/or
 +    modify it under the terms of either:
 +
 +    1. The GNU General Public License, as published by the Free
 +       Software Foundation; either version 3, or (at your option) any
 +       later version.  A copy of this license is in the file COPYING.
 +    or
 +    2. The Less License, in the file LICENSE.
 +
 +    Please report any problems at https://github.com/gwsw/less/issues.
 +    See https://greenwoodsoftware.com/less for the latest info.
 +    Source repository is at https://github.com/gwsw/less.git.
 +
 +=========================================================================
 +
 +You should build from a clone of a git repository 
 +ONLY IF you are doing development on the less source itself.
 +If you are merely using less as a tool, you should download a release
 +from https://greenwoodsoftware.com and NOT from github.
 +
 +The formatted manual page is in less.man.
 +The manual page nroff source is in less.nro.
 +Major changes made since the last posted version are in NEWS.
 +
 +=======================================================================
 +INSTALLATION (Unix & Linux systems only):
 +
 +1. Move the distributed source to its own directory and unpack it,
 +   if you have not already done so.  
 +
 +2. If you are building from a clone of a git repository,
 +   type "make -f Makefile.aut distfiles".
 +   If you are building from a numbered release package (a tar or 
 +   zip file with a name like less-999.tar.gz or less-999.zip downloaded 
 +   from greenwoodsoftware.com, not from github), you should skip this step. 
 +
 +3. Type "sh configure".
 +   This will generate a Makefile and a defines.h.
 +   Warning: if you have a GNU sed, make sure it is version 2.05 or later.
 +
 +   The file INSTALL describes the usage of the configure program in
 +   general.  In addition, these options to configure are supported:
 +
 +   --with-editor=program
 +     Specifies the default editor program used by the "v" command.
 +     The default is "vi".
 +
 +   --with-regex=lib
 +     Specifies the regular expression library used by less for pattern
 +     matching.  The default is "auto", which means the configure program 
 +     finds a regular expression library automatically.  Other values are:
 +        gnu            Use the GNU regex library.
 +        pcre           Use the PCRE library.
 +        pcre2          Use the PCRE2 library.
 +        posix          Use the POSIX-compatible regcomp.
 +        regcmp         Use the regcmp library.
 +        re_comp        Use the re_comp library.
 +        regcomp        Use the V8-compatible regcomp.
 +        regcomp-local  Use Henry Spencer's V8-compatible regcomp
 +                       (source is supplied with less).
 +        none           No regular expressions, only simple string matching.
 +
 +   --with-secure
 +     Builds a "secure" version of less, with some features disabled
 +     to prevent users from viewing other files, accessing shell
 +     commands, etc.
 +
 +
 +4. It is a good idea to look over the generated Makefile and defines.h
 +   and make sure they look ok.  If you know of any peculiarities of
 +   your system that configure might not have detected, you may fix the
 +   Makefile now.  Take particular notice of the list of "terminal" 
 +   libraries in the LIBS definition in the Makefile; these may need 
 +   to be edited.  The terminal libraries will be some subset of
-        -lncurses  -lcurses  -ltermcap  -ltermlib
++    -ltinfo -ltinfow -lxcurses -lncursesw -lncurses -lcurses -ltermcap -ltermlib
 +
 +   If you wish, you may edit defines.h to remove some optional features.
 +   If you choose not to include some features in your version, you may
 +   wish to edit the manual page "less.nro" and the help page "less.hlp" 
 +   to remove the descriptions of the features which you are removing.
 +   If you edit less.hlp, you should run "make -f Makefile.aut help.c".
 +
 +5. Type "make" and watch the fun.
 +
 +6. If the make succeeds, it will generate the programs "less",
 +   "lesskey" and "lessecho" in your current directory.  Test the 
 +   generated programs.
 +
 +7. When satisfied that it works, if you wish to install it
 +   in a public place, type "make install".
 +
 +   The default install destinations are:
 +        Executables (less, lesskey, lessecho) in /usr/local/bin
 +        Documentation (less.nro, lesskey.nro) in /usr/local/man/man1
 +   If you want to install any of these files elsewhere, define
 +   bindir and/or mandir to the appropriate directories.
 +
 +
 +Note to hackers: comments noting possible improvements are enclosed
 +in double curly brackets {{ like this }}.
 +
 +(Note that the above note was originally written at a time when 
 +"hackers" most commonly meant "enthusiastic and dedicated computer 
 +programmers", not "persons who attempt to circumvent computer security".)
 +
 +
 +
++=======================================================================
++INSTALLATION (Windows-95, Windows-98 and Windows-NT systems only,
++              with Microsoft Visual C++, mingw, or Borland C)
++
++1. Move the distributed source to its own directory.
++
++2. If you wish, you may edit defines.wn to remove some optional features.
++   If you choose not to include some features in your version, you may
++   wish to edit the manual page less.man and the help page help.c
++   to remove the descriptions of the features which you are removing.
++
++3. If you are using Microsoft Visual C++, run "nmake -f Makefile.wnm".
++   If you are using mingw, run "make -f Makefile.wng".
++   If you are using Borland C, run "make -f Makefile.wnb".
++
++   If the environment variable SECURE_COMPILE is to 1 during the make,
++   a "secure" version of less is built, with some features disabled.
++
++4. If the make succeeds, it will generate the programs "less.exe" and
++   "lesskey.exe" in your current directory.  Test the generated programs.
++
++
++
 +=======================================================================
 +INSTALLATION (MS-DOS systems only,
 +              with Microsoft C, Borland C, or DJGPP)
 +
 +1. Move the distributed source to its own directory.
 +   Depending on your compiler, you may need to convert the source 
 +   to have CR-LF rather than LF as line terminators.
 +
 +2. If you are using Microsoft C, rename MAKEFILE.DSU to MAKEFILE.
 +   If you are using Borland C, rename MAKEFILE.DSB to MAKEFILE.
 +   If you are using DJGPP, rename MAKEFILE.DSG to MAKEFILE.
 +
 +3. Look at MAKEFILE to make sure that the definitions for CC and LIBDIR
 +   are correct.  CC should be the name of your C compiler and
 +   LIBDIR should be the directory where the C libraries reside (for
 +   Microsoft C only).  If these definitions need to be changed, you can
 +   either modify the definitions directly in MAKEFILE, or set your
 +   environment variables CC and/or LIBDIR to override the definitions
 +   in MAKEFILE.
 +
 +4. If you wish, you may edit DEFINES.DS to remove some optional features.
 +   If you choose not to include some features in your version, you may
 +   wish to edit the manual page LESS.MAN and the help page HELP.C
 +   to remove the descriptions of the features which you are removing.
 +
 +5. Run your "make" program and watch the fun.
 +   If your "make" requires a flag to import environment variables,
 +   you should use that flag.
 +   If your compiler runs out of memory, try running "make -n >cmds.bat" 
 +   and then run cmds.bat.
 +
 +6. If the make succeeds, it will generate the programs "LESS.EXE" and
 +   "LESSKEY.EXE" in your current directory.  Test the generated programs.
 +
 +7. When satisfied that it works, you may wish to install LESS.EXE and
 +   LESSKEY.EXE in a directory which is included in your PATH.
 +
 +
 +
- =======================================================================
- INSTALLATION (Windows-95, Windows-98 and Windows-NT systems only,
-               with Borland C or Microsoft Visual C++)
- 
- 1. Move the distributed source to its own directory.
- 
- 2. If you are using Borland C, rename Makefile.wnb to Makefile.
-    If you are using Microsoft Visual C++, rename Makefile.wnm to Makefile.
- 
- 3. Check the Makefile to make sure the definitions look ok.
- 
- 4. If you wish, you may edit defines.wn to remove some optional features.
-    If you choose not to include some features in your version, you may
-    wish to edit the manual page less.man and the help page help.c
-    to remove the descriptions of the features which you are removing.
- 
- 5. Type "make" and watch the fun.
- 
- 6. If the make succeeds, it will generate the programs "less.exe" and
-    "lesskey.exe" in your current directory.  Test the generated programs.
- 
- 7. When satisfied that it works, if you wish to install it
-    in a public place, type "make install".
-    See step 6 of the Unix installation instructions for details
-    on how to change the default installation directories.
- 
- 
- 
 +=======================================================================
 +INSTALLATION (OS/2 systems only,
 +              with EMX C)
 +
 +1. Move the distributed source to its own directory.
 +
 +2. Rename Makefile.o2e to Makefile.
 +
 +3. Check the Makefile to make sure the definitions look ok.
 +
 +4. If you wish, you may edit defines.o2 to remove some optional features.
 +   If you choose not to include some features in your version, you may
 +   wish to edit the manual page less.man and the help page help.c
 +   to remove the descriptions of the features which you are removing.
 +
 +5. Type "make" and watch the fun.
 +
 +6. If the make succeeds, it will generate the programs "less.exe" and
 +   "lesskey.exe" in your current directory.  Test the generated programs.
 +
 +7. Make sure you have the emx runtime installed. You need the emx DLLs
 +   emx.dll and emxlibcs.dll and also the termcap database, termcap.dat.
 +   Make sure you have termcap.dat either in the default location or
 +   somewhere in a directory listed in the PATH or INIT environment 
 +   variables.
 +
 +8. When satisfied that it works, you may wish to install less.exe,
 +   lesskey.exe and scrsize.exe in a directory which is included in 
 +   your PATH.  scrsize.exe is required only if you use a terminal
 +   emulator such as xterm or rxvt.
 +
 +
 +
 +=======================================================================
 +INSTALLATION (OS-9 systems only,
 +              with Microware C or Ultra C)
 +
 +1. Move the distributed source to its own directory.
 +
 +2. If you are using Microware C, rename Makefile.o9c to Makefile.
 +   If you are using Ultra C, rename Makefile.o9u to Makefile.
 +
 +3. Check the Makefile to make sure the definitions look ok.
 +
 +4. If you wish, you may edit defines.o9 to remove some optional features.
 +   If you choose not to include some features in your version, you may
 +   wish to edit the manual page less.man and the help page help.c
 +   to remove the descriptions of the features which you are removing.
 +
 +5. Type "dmake" and watch the fun.
 +   The standard OS-9 "make" will probably not work.  If you don't
 +   have dmake, you can get a copy from os9archive.rtsi.com.
 +
 +6. If the make succeeds, it will generate the programs "less" and
 +   "lesskey" in your current directory.  Test the generated programs.
 +
 +7. When satisfied that it works, if you wish to install it
 +   in a public place, type "dmake install".
 +   See step 6 of the Unix installation instructions for details
 +   on how to change the default installation directories.
 +
- =======================================================================
- ACKNOWLEDGMENTS:
-   Some versions of the less distribution are packaged using 
-   Info-ZIP's compression utility.
-   Info-ZIP's software is free and can be obtained as source 
-   code or executables from various anonymous-ftp sites,
-   including ftp.uu.net:/pub/archiving/zip.
diff --cc contrib/less/command.c
index 390385547385,000000000000..4784cf45daa6
mode 100644,000000..100644
--- a/contrib/less/command.c
+++ b/contrib/less/command.c
@@@ -1,2360 -1,0 +1,2365 @@@
 +/*
 + * Copyright (C) 1984-2025  Mark Nudelman
 + *
 + * You may distribute under the terms of either the GNU General Public
 + * License or the Less License, as specified in the README file.
 + *
 + * For more information, see the README file.
 + */
 +
 +
 +/*
 + * User-level command processor.
 + */
 +
 +#include "less.h"
 +#if MSDOS_COMPILER==WIN32C
 +#include <windows.h>
 +#endif
 +#include "position.h"
 +#include "option.h"
 +#include "cmd.h"
 +
 +extern int erase_char, erase2_char, kill_char;
 +extern int sigs;
 +extern int quit_if_one_screen;
 +extern int one_screen;
 +extern int sc_width;
 +extern int sc_height;
 +extern char *kent;
 +extern int swindow;
 +extern int jump_sline;
 +extern lbool quitting;
 +extern int wscroll;
 +extern int top_scroll;
- extern int ignore_eoi;
++extern lbool ignore_eoi;
 +extern int hshift;
 +extern int bs_mode;
 +extern int proc_backspace;
 +extern int show_attn;
 +extern int less_is_more;
 +extern int chopline;
 +extern POSITION highest_hilite;
 +extern char *every_first_cmd;
 +extern char version[];
 +extern struct scrpos initial_scrpos;
 +extern IFILE curr_ifile;
 +extern void *ml_search;
 +extern void *ml_examine;
 +extern int wheel_lines;
 +extern int def_search_type;
 +extern lbool search_wrapped;
- extern lbool no_poll;
 +extern int no_paste;
 +extern lbool pasting;
 +extern int no_edit_warn;
 +extern POSITION soft_eof;
 +extern POSITION search_incr_start;
 +extern char *first_cmd_at_prompt;
 +#if SHELL_ESCAPE || PIPEC
 +extern void *ml_shell;
 +#endif
 +#if EDITOR
 +extern constant char *editproto;
 +#endif
 +#if OSC8_LINK
 +extern char *osc8_uri;
 +#endif
 +extern int shift_count;
 +extern int forw_prompt;
 +extern int incr_search;
 +extern int full_screen;
 +#if MSDOS_COMPILER==WIN32C
 +extern int utf_mode;
 +extern unsigned less_acp;
 +#endif
 +
 +#if SHELL_ESCAPE
 +static char *shellcmd = NULL;   /* For holding last shell command for "!!" */
 +#endif
 +static int mca;                 /* The multicharacter command (action) */
 +static int search_type;         /* The previous type of search */
 +static int last_search_type;    /* Type of last executed search */
 +static LINENUM number;          /* The number typed by the user */
 +static long fraction;           /* The fractional part of the number */
 +static struct loption *curropt;
 +static lbool opt_lower;
 +static int optflag;
 +static lbool optgetname;
 +static POSITION bottompos;
 +static int save_hshift;
 +static int save_bs_mode;
 +static int save_proc_backspace;
 +static int screen_trashed_value = 0;
 +static lbool literal_char = FALSE;
 +static lbool ignoring_input = FALSE;
 +static struct scrpos search_incr_pos = { NULL_POSITION, 0 };
 +static int search_incr_hshift;
 +#if HAVE_TIME
 +static time_type ignoring_input_time;
 +#endif
 +#if PIPEC
 +static char pipec;
 +#endif
 +
 +/* Stack of ungotten chars (via ungetcc) */
 +struct ungot {
 +	struct ungot *ug_next;
 +	char ug_char;
 +	lbool ug_end_command;
 +};
 +static struct ungot* ungot = NULL;
 +
 +static void multi_search(constant char *pattern, int n, int silent);
 +
 +/*
 + * Move the cursor to start of prompt line before executing a command.
 + * This looks nicer if the command takes a long time before
 + * updating the screen.
 + */
 +public void cmd_exec(void)
 +{
 +	clear_attn();
 +	clear_bot();
 +	flush();
 +}
 +
 +/*
 + * Indicate we are reading a multi-character command.
 + */
 +static void set_mca(int action)
 +{
 +	mca = action;
 +	clear_bot();
 +	clear_cmd();
 +}
 +
 +/*
 + * Indicate we are not reading a multi-character command.
 + */
 +static void clear_mca(void)
 +{
 +	if (mca == 0)
 +		return;
 +	mca = 0;
 +}
 +
 +/*
 + * Set up the display to start a new multi-character command.
 + */
 +static void start_mca(int action, constant char *prompt, void *mlist, int cmdflags)
 +{
 +	set_mca(action);
 +	cmd_putstr(prompt);
 +	set_mlist(mlist, cmdflags);
 +}
 +
- public int in_mca(void)
++public lbool in_mca(void)
 +{
 +	return (mca != 0 && mca != A_PREFIX);
 +}
 +
 +/*
 + * Set up the display to start a new search command.
 + */
 +static void mca_search1(void)
 +{
 +	int i;
 +
 +#if HILITE_SEARCH
 +	if (search_type & SRCH_FILTER)
 +		set_mca(A_FILTER);
 +	else 
 +#endif
 +	if (search_type & SRCH_FORW)
 +		set_mca(A_F_SEARCH);
 +	else
 +		set_mca(A_B_SEARCH);
 +
 +	if (search_type & SRCH_NO_MATCH)
 +		cmd_putstr("Non-match ");
 +	if (search_type & SRCH_FIRST_FILE)
 +		cmd_putstr("First-file ");
 +	if (search_type & SRCH_PAST_EOF)
 +		cmd_putstr("EOF-ignore ");
 +	if (search_type & SRCH_NO_MOVE)
 +		cmd_putstr("Keep-pos ");
 +	if (search_type & SRCH_NO_REGEX)
 +		cmd_putstr("Regex-off ");
 +	if (search_type & SRCH_WRAP)
 +		cmd_putstr("Wrap ");
 +	for (i = 1; i <= NUM_SEARCH_COLORS; i++)
 +	{
 +		if (search_type & SRCH_SUBSEARCH(i))
 +		{
 +			char buf[INT_STRLEN_BOUND(int)+8];
 +			SNPRINTF1(buf, sizeof(buf), "Sub-%d ", i);
 +			cmd_putstr(buf);
 +		}
 +	}
 +	if (literal_char)
 +		cmd_putstr("Lit ");
 +
 +#if HILITE_SEARCH
 +	if (search_type & SRCH_FILTER)
 +		cmd_putstr("&/");
 +	else 
 +#endif
 +	if (search_type & SRCH_FORW)
 +		cmd_putstr("/");
 +	else
 +		cmd_putstr("?");
 +	forw_prompt = 0;
 +}
 +
 +static void mca_search(void)
 +{
 +	if (incr_search)
 +	{
 +		/* Remember where the incremental search started. */
 +		get_scrpos(&search_incr_pos, TOP);
 +		search_incr_start = search_pos(search_type);
 +		search_incr_hshift = hshift;
 +	}
 +	mca_search1();
 +	set_mlist(ml_search, 0);
 +}
 +
 +/*
 + * Set up the display to start a new toggle-option command.
 + */
 +static void mca_opt_toggle(void)
 +{
 +	int no_prompt = (optflag & OPT_NO_PROMPT);
 +	int flag = (optflag & ~OPT_NO_PROMPT);
 +	constant char *dash = (flag == OPT_NO_TOGGLE) ? "_" : "-";
 +	
 +	set_mca(A_OPT_TOGGLE);
 +	cmd_putstr(dash);
 +	if (optgetname)
 +		cmd_putstr(dash);
 +	if (no_prompt)
 +		cmd_putstr("(P)");
 +	switch (flag)
 +	{
 +	case OPT_UNSET:
 +		cmd_putstr("+");
 +		break;
 +	case OPT_SET:
 +		cmd_putstr("!");
 +		break;
 +	}
 +	forw_prompt = 0;
 +	set_mlist(NULL, CF_OPTION);
 +}
 +
 +/*
 + * Execute a multicharacter command.
 + */
 +static void exec_mca(void)
 +{
 +	constant char *cbuf;
 +
 +	cmd_exec();
 +	cbuf = get_cmdbuf();
 +	if (cbuf == NULL)
 +		return;
 +
 +	switch (mca)
 +	{
 +	case A_F_SEARCH:
 +	case A_B_SEARCH:
 +		multi_search(cbuf, (int) number, 0);
 +		break;
 +#if HILITE_SEARCH
 +	case A_FILTER:
 +		search_type ^= SRCH_NO_MATCH;
 +		set_filter_pattern(cbuf, search_type);
 +		soft_eof = NULL_POSITION;
 +		break;
 +#endif
 +	case A_FIRSTCMD:
 +		/*
 +		 * Skip leading spaces or + signs in the string.
 +		 */
 +		while (*cbuf == '+' || *cbuf == ' ')
 +			cbuf++;
 +		if (every_first_cmd != NULL)
 +			free(every_first_cmd);
 +		if (*cbuf == '\0')
 +			every_first_cmd = NULL;
 +		else
 +			every_first_cmd = save(cbuf);
 +		break;
 +	case A_OPT_TOGGLE:
 +		toggle_option(curropt, opt_lower, cbuf, optflag);
 +		curropt = NULL;
 +		break;
 +	case A_F_BRACKET:
 +		match_brac(cbuf[0], cbuf[1], 1, (int) number);
 +		break;
 +	case A_B_BRACKET:
 +		match_brac(cbuf[1], cbuf[0], 0, (int) number);
 +		break;
 +#if EXAMINE
 +	case A_EXAMINE: {
 +		char *p;
 +		if (!secure_allow(SF_EXAMINE))
 +			break;
 +		p = save(cbuf);
 +		edit_list(p);
 +		free(p);
 +#if TAGS
 +		/* If tag structure is loaded then clean it up. */
 +		cleantags();
 +#endif
 +		break; }
 +#endif
 +#if SHELL_ESCAPE
 +	case A_SHELL: {
 +		/*
 +		 * !! just uses whatever is in shellcmd.
 +		 * Otherwise, copy cmdbuf to shellcmd,
 +		 * expanding any special characters ("%" or "#").
 +		 */
 +		constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "!done";
 +		if (done_msg == NULL)
 +			++cbuf;
 +		if (*cbuf != '!')
 +		{
 +			if (shellcmd != NULL)
 +				free(shellcmd);
 +			shellcmd = fexpand(cbuf);
 +		}
 +		if (!secure_allow(SF_SHELL))
 +			break;
 +		if (shellcmd == NULL)
 +			shellcmd = "";
 +		lsystem(shellcmd, done_msg);
 +		break; }
 +	case A_PSHELL: {
 +		constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "#done";
 +		if (done_msg == NULL)
 +			++cbuf;
 +		if (!secure_allow(SF_SHELL))
 +			break;
 +		lsystem(pr_expand(cbuf), done_msg);
 +		break; }
 +#endif
 +#if PIPEC
 +	case A_PIPE: {
 +		constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "|done";
 +		if (done_msg == NULL)
 +			++cbuf;
 +		if (!secure_allow(SF_PIPE))
 +			break;
 +		(void) pipe_mark(pipec, cbuf);
 +		if (done_msg != NULL)
 +			error(done_msg, NULL_PARG);
 +		break; }
 +#endif
 +	}
 +}
 +
 +/*
 + * Is a character an erase or kill char?
 + */
 +static lbool is_erase_char(char c)
 +{
 +	return (c == erase_char || c == erase2_char || c == kill_char);
 +}
 +
 +/*
 + * Is a character a carriage return or newline?
 + */
 +static lbool is_newline_char(char c)
 +{
 +	return (c == '\n' || c == '\r');
 +}
 +
 +/*
 + * Handle the first char of an option (after the initial dash).
 + */
 +static int mca_opt_first_char(char c)
 +{
 +	int no_prompt = (optflag & OPT_NO_PROMPT);
 +	int flag = (optflag & ~OPT_NO_PROMPT);
 +	if (flag == OPT_NO_TOGGLE)
 +	{
 +		switch (c)
 +		{
 +		case '_':
 +			/* "__" = long option name. */
 +			optgetname = TRUE;
 +			mca_opt_toggle();
 +			return (MCA_MORE);
 +		}
 +	} else
 +	{
 +		switch (c)
 +		{
 +		case '+':
 +			/* "-+" = UNSET. */
 +			optflag = no_prompt | ((flag == OPT_UNSET) ?
 +				OPT_TOGGLE : OPT_UNSET);
 +			mca_opt_toggle();
 +			return (MCA_MORE);
 +		case '!':
 +			/* "-!" = SET */
 +			optflag = no_prompt | ((flag == OPT_SET) ?
 +				OPT_TOGGLE : OPT_SET);
 +			mca_opt_toggle();
 +			return (MCA_MORE);
 +		case CONTROL('P'):
 +			optflag ^= OPT_NO_PROMPT;
 +			mca_opt_toggle();
 +			return (MCA_MORE);
 +		case '-':
 +			/* "--" = long option name. */
 +			optgetname = TRUE;
 +			mca_opt_toggle();
 +			return (MCA_MORE);
 +		}
 +	}
 +	/* Char was not handled here. */
 +	return (NO_MCA);
 +}
 +
 +/*
 + * Add a char to a long option name.
 + * See if we've got a match for an option name yet.
 + * If so, display the complete name and stop 
 + * accepting chars until user hits RETURN.
 + */
 +static int mca_opt_nonfirst_char(char c)
 +{
 +	constant char *p;
 +	constant char *oname;
 +	lbool ambig;
 +	struct loption *was_curropt;
 +
 +	if (curropt != NULL)
 +	{
 +		/* Already have a match for the name. */
 +		if (is_erase_char(c))
 +			return (MCA_DONE);
 +		/* {{ Checking for TAB here is ugly.
 +		 *    Also doesn't extend well -- can't do BACKTAB this way
 +		 *    because it's a multichar sequence. }} */
 +		if (c != '\t') 
 +			return (MCA_MORE);
 +	}
 +	/*
 +	 * Add char to cmd buffer and try to match
 +	 * the option name.
 +	 */
 +	if (cmd_char(c) == CC_QUIT)
 +		return (MCA_DONE);
 +	p = get_cmdbuf();
 +	if (p == NULL || p[0] == '\0')
 +		return (MCA_MORE);
 +	opt_lower = ASCII_IS_LOWER(p[0]);
 +	was_curropt = curropt;
 +	curropt = findopt_name(&p, &oname, &ambig);
 +	if (curropt != NULL)
 +	{
 +		if (was_curropt == NULL)
 +		{
 +			/*
 +			 * Got a match.
 +			 * Remember the option and
 +			 * display the full option name.
 +			 */
 +			cmd_reset();
 +			mca_opt_toggle();
 +			cmd_setstring(oname, !opt_lower);
 +		}
 +	} else if (!ambig)
 +	{
- 		bell();
++		lbell();
 +	}
 +	return (MCA_MORE);
 +}
 +
 +/*
 + * Handle a char of an option toggle command.
 + */
 +static int mca_opt_char(char c)
 +{
 +	PARG parg;
 +
 +	/*
 +	 * This may be a short option (single char),
 +	 * or one char of a long option name,
 +	 * or one char of the option parameter.
 +	 */
 +	if (curropt == NULL && cmdbuf_empty())
 +	{
 +		int ret = mca_opt_first_char(c);
 +		if (ret != NO_MCA)
 +			return (ret);
 +	}
 +	if (optgetname)
 +	{
 +		/* We're getting a long option name.  */
 +		if (!is_newline_char(c) && c != '=')
 +			return (mca_opt_nonfirst_char(c));
 +		if (curropt == NULL)
 +		{
 +			parg.p_string = get_cmdbuf();
 +			if (parg.p_string == NULL)
 +				return (MCA_MORE);
 +			error("There is no --%s option", &parg);
 +			return (MCA_DONE);
 +		}
 +		optgetname = FALSE;
 +		cmd_reset();
 +	} else
 +	{
 +		if (is_erase_char(c))
 +			return (NO_MCA);
 +		if (curropt != NULL)
 +			/* We're getting the option parameter. */
 +			return (NO_MCA);
 +		curropt = findopt(c);
 +		if (curropt == NULL)
 +		{
 +			parg.p_string = propt(c);
 +			error("There is no %s option", &parg);
 +			return (MCA_DONE);
 +		}
 +		opt_lower = ASCII_IS_LOWER(c);
 +	}
 +	/*
 +	 * If the option which was entered does not take a 
 +	 * parameter, toggle the option immediately,
 +	 * so user doesn't have to hit RETURN.
 +	 */
 +	if ((optflag & ~OPT_NO_PROMPT) != OPT_TOGGLE ||
 +	    !opt_has_param(curropt))
 +	{
 +		toggle_option(curropt, opt_lower, "", optflag);
 +		return (MCA_DONE);
 +	}
 +	/*
 +	 * Display a prompt appropriate for the option parameter.
 +	 */
 +	start_mca(A_OPT_TOGGLE, opt_prompt(curropt), NULL, CF_OPTION);
 +	return (MCA_MORE);
 +}
 +
 +/*
 + * Normalize search type.
 + */
 +public int norm_search_type(int st)
 +{
 +	/* WRAP and PAST_EOF are mutually exclusive. */
 +	if ((st & (SRCH_PAST_EOF|SRCH_WRAP)) == (SRCH_PAST_EOF|SRCH_WRAP))
 +		st ^= SRCH_PAST_EOF;
 +	return st;
 +}
 +
 +/*
 + * Handle a char of a search command.
 + */
 +static int mca_search_char(char c)
 +{
 +	int flag = 0;
 +
 +	/*
 +	 * Certain characters as the first char of 
 +	 * the pattern have special meaning:
 +	 *      !  Toggle the NO_MATCH flag
 +	 *      *  Toggle the PAST_EOF flag
 +	 *      @  Toggle the FIRST_FILE flag
 +	 */
 +	if (!cmdbuf_empty() || literal_char)
 +	{
++		lbool was_literal_char = literal_char;
 +		literal_char = FALSE;
++		if (was_literal_char)
++			mca_search1();
 +		return (NO_MCA);
 +	}
 +
 +	switch (c)
 +	{
 +	case '*':
 +		if (less_is_more)
 +			break;
 +	case CONTROL('E'): /* ignore END of file */
 +		if (mca != A_FILTER)
 +			flag = SRCH_PAST_EOF;
 +		search_type &= ~SRCH_WRAP;
 +		break;
 +	case '@':
 +		if (less_is_more)
 +			break;
 +	case CONTROL('F'): /* FIRST file */
 +		if (mca != A_FILTER)
 +			flag = SRCH_FIRST_FILE;
 +		break;
 +	case CONTROL('K'): /* KEEP position */
 +		if (mca != A_FILTER)
 +			flag = SRCH_NO_MOVE;
 +		break;
 +	case CONTROL('S'): { /* SUBSEARCH */
 +		char buf[INT_STRLEN_BOUND(int)+24];
 +		SNPRINTF1(buf, sizeof(buf), "Sub-pattern (1-%d):", NUM_SEARCH_COLORS);
 +		clear_bot();
 +		cmd_putstr(buf);
 +		flush();
 +		c = getcc();
 +		if (c >= '1' && c <= '0'+NUM_SEARCH_COLORS)
 +			flag = SRCH_SUBSEARCH(c-'0');
 +		else
 +			flag = -1; /* calls mca_search() below to repaint */
 +		break; }
 +	case CONTROL('W'): /* WRAP around */
 +		if (mca != A_FILTER)
 +			flag = SRCH_WRAP;
 +		break;
 +	case CONTROL('R'): /* Don't use REGULAR EXPRESSIONS */
 +		flag = SRCH_NO_REGEX;
 +		break;
 +	case CONTROL('N'): /* NOT match */
 +	case '!':
 +		flag = SRCH_NO_MATCH;
*** 3370 LINES SKIPPED ***


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69810e6f.3e40d.3f762f14>