git: 95270f73baf6 - main - MFV: less v608
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 06 Sep 2022 05:55:34 UTC
The branch main has been updated by delphij: URL: https://cgit.FreeBSD.org/src/commit/?id=95270f73baf6fa95ae529bc2eb6a61f5c79f32c0 commit 95270f73baf6fa95ae529bc2eb6a61f5c79f32c0 Merge: dda082e00939 2b6624fffa5f Author: Xin LI <delphij@FreeBSD.org> AuthorDate: 2022-09-06 05:52:39 +0000 Commit: Xin LI <delphij@FreeBSD.org> CommitDate: 2022-09-06 05:52:39 +0000 MFV: less v608 Relnotes: yes MFC after: 2 weeks contrib/less/LICENSE | 2 +- contrib/less/NEWS | 67 ++++++++++ contrib/less/README | 6 +- contrib/less/brac.c | 6 +- contrib/less/ch.c | 19 ++- contrib/less/charset.c | 18 +-- contrib/less/charset.h | 2 +- contrib/less/cmd.h | 3 +- contrib/less/cmdbuf.c | 91 ++++++++++---- contrib/less/command.c | 76 +++++++++--- contrib/less/compose.uni | 20 ++- contrib/less/cvt.c | 2 +- contrib/less/decode.c | 30 ++++- contrib/less/edit.c | 4 +- contrib/less/filename.c | 19 ++- contrib/less/fmt.uni | 3 +- contrib/less/forwback.c | 126 +++++++++++++++++-- contrib/less/funcs.h | 18 ++- contrib/less/help.c | 20 ++- contrib/less/ifile.c | 2 +- contrib/less/input.c | 22 ++-- contrib/less/jump.c | 2 +- contrib/less/less.h | 4 +- contrib/less/less.hlp | 18 ++- contrib/less/less.nro | 99 ++++++++++++--- contrib/less/lessecho.c | 45 +++++-- contrib/less/lessecho.nro | 2 +- contrib/less/lesskey.c | 11 +- contrib/less/lesskey.h | 2 +- contrib/less/lesskey.nro | 155 ++++++++++++++++------- contrib/less/lesskey_parse.c | 238 +++++++++++++++++++++++++++--------- contrib/less/lglob.h | 2 +- contrib/less/line.c | 285 ++++++++++++++++++++++++++++++++----------- contrib/less/linenum.c | 23 +++- contrib/less/lsystem.c | 9 +- contrib/less/main.c | 25 +++- contrib/less/mark.c | 5 +- contrib/less/optfunc.c | 131 ++++++++++++++++++-- contrib/less/option.c | 4 +- contrib/less/option.h | 2 +- contrib/less/opttbl.c | 65 +++++++++- contrib/less/os.c | 18 ++- contrib/less/output.c | 11 +- contrib/less/pattern.c | 13 +- contrib/less/pattern.h | 34 ++++-- contrib/less/pckeys.h | 2 +- contrib/less/position.c | 3 +- contrib/less/position.h | 2 +- contrib/less/prompt.c | 29 ++--- contrib/less/screen.c | 62 ++++++++-- contrib/less/scrsize.c | 2 +- contrib/less/search.c | 59 +++++---- contrib/less/signal.c | 2 +- contrib/less/tags.c | 8 +- contrib/less/ttyin.c | 63 ++++++---- contrib/less/ubin.uni | 2 +- contrib/less/version.c | 27 +++- contrib/less/wide.uni | 25 ++-- contrib/less/xbuf.c | 23 +++- contrib/less/xbuf.h | 3 +- usr.bin/less/defines.h | 4 + 61 files changed, 1586 insertions(+), 489 deletions(-) diff --cc contrib/less/README index 4a5aa62a44ee,000000000000..4bfdc5e5a67f mode 100644,000000..100644 --- a/contrib/less/README +++ b/contrib/less/README @@@ -1,254 -1,0 +1,254 @@@ +************************************************************************** +************************************************************************** +** ** +** 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 (http://www.gnu.org). ++ 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 http://greenwoodsoftware.com and NOT from github. ++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". ++ 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 + + 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 (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 171788f2e750,000000000000..8bd999e9f7a3 mode 100644,000000..100644 --- a/contrib/less/command.c +++ b/contrib/less/command.c @@@ -1,2061 -1,0 +1,2099 @@@ +/* $FreeBSD$ */ +/* - * Copyright (C) 1984-2021 Mark Nudelman ++ * Copyright (C) 1984-2022 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 squished; +extern int sc_width; +extern int sc_height; +extern char *kent; +extern int swindow; +extern int jump_sline; +extern int quitting; +extern int wscroll; +extern int top_scroll; +extern int ignore_eoi; +extern int secure; +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 version[]; +extern struct scrpos initial_scrpos; +extern IFILE curr_ifile; +extern void *ml_search; +extern void *ml_examine; +extern int wheel_lines; ++extern int header_lines; ++extern int def_search_type; ++extern int updown_match; +#if SHELL_ESCAPE || PIPEC +extern void *ml_shell; +#endif +#if EDITOR +extern char *editor; +extern char *editproto; +#endif +extern int screen_trashed; /* The screen has been overwritten */ +extern int shift_count; +extern int oldbot; +extern int forw_prompt; +extern int incr_search; +#if MSDOS_COMPILER==WIN32C +extern int utf_mode; +#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 LINENUM number; /* The number typed by the user */ +static long fraction; /* The fractional part of the number */ +static struct loption *curropt; +static int opt_lower; +static int optflag; +static int optgetname; +static POSITION bottompos; +static int save_hshift; +static int save_bs_mode; +#if PIPEC +static char pipec; +#endif + +/* Stack of ungotten chars (via ungetcc) */ +struct ungot { + struct ungot *ug_next; + LWCHAR ug_char; +}; +static struct ungot* ungot = NULL; + +static void multi_search LESSPARAMS((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. + */ + static void +cmd_exec(VOID_PARAM) +{ + clear_attn(); + clear_bot(); + flush(); +} + +/* + * Indicate we are reading a multi-character command. + */ + static void +set_mca(action) + int action; +{ + mca = action; + clear_bot(); + clear_cmd(); +} + +/* + * Indicate we are not reading a multi-character command. + */ + static void +clear_mca(VOID_PARAM) +{ + if (mca == 0) + return; + mca = 0; +} + +/* + * Set up the display to start a new multi-character command. + */ + static void +start_mca(action, prompt, mlist, cmdflags) + int action; + constant char *prompt; + void *mlist; + int cmdflags; +{ + set_mca(action); + cmd_putstr(prompt); + set_mlist(mlist, cmdflags); +} + + public int +in_mca(VOID_PARAM) +{ + return (mca != 0 && mca != A_PREFIX); +} + +/* + * Set up the display to start a new search command. + */ + static void - mca_search(VOID_PARAM) ++mca_search1(VOID_PARAM) +{ +#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 "); + +#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_PARAM) ++{ ++ mca_search1(); + set_mlist(ml_search, 0); +} + +/* + * Set up the display to start a new toggle-option command. + */ + static void +mca_opt_toggle(VOID_PARAM) +{ + int no_prompt; + int flag; + char *dash; + + no_prompt = (optflag & OPT_NO_PROMPT); + flag = (optflag & ~OPT_NO_PROMPT); + 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, 0); +} + +/* + * Execute a multicharacter command. + */ + static void +exec_mca(VOID_PARAM) +{ + 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); + 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: + if (secure) + break; + edit_list(cbuf); +#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 "#"). + */ + if (*cbuf != '!') + { + if (shellcmd != NULL) + free(shellcmd); + shellcmd = fexpand(cbuf); + } + + if (secure) + break; + if (shellcmd == NULL) + lsystem("", "!done"); + else + lsystem(shellcmd, "!done"); + break; +#endif +#if PIPEC + case A_PIPE: + if (secure) + break; + (void) pipe_mark(pipec, cbuf); + error("|done", NULL_PARG); + break; +#endif + } +} + +/* + * Is a character an erase or kill char? + */ + static int +is_erase_char(c) + int c; +{ + return (c == erase_char || c == erase2_char || c == kill_char); +} + +/* + * 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 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 = (flag == OPT_UNSET) ? - OPT_TOGGLE : OPT_UNSET; ++ optflag = no_prompt | ((flag == OPT_UNSET) ? ++ OPT_TOGGLE : OPT_UNSET); + mca_opt_toggle(); + return (MCA_MORE); + case '!': + /* "-!" = SET */ - optflag = (flag == OPT_SET) ? - OPT_TOGGLE : OPT_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(c) + int c; +{ + char *p; + char *oname; + int err; + + if (curropt != NULL) + { + /* + * Already have a match for the name. + * Don't accept anything but erase/kill. + */ + if (is_erase_char(c)) + return (MCA_DONE); + 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) ++ return (MCA_MORE); + opt_lower = ASCII_IS_LOWER(p[0]); + err = 0; + curropt = findopt_name(&p, &oname, &err); + if (curropt != NULL) + { + /* + * Got a match. + * Remember the option and + * display the full option name. + */ + cmd_reset(); + mca_opt_toggle(); + for (p = oname; *p != '\0'; p++) + { + c = *p; + if (!opt_lower && ASCII_IS_LOWER(c)) + c = ASCII_TO_UPPER(c); + if (cmd_char(c) != CC_OK) + return (MCA_DONE); + } + } else if (err != OPT_AMBIG) + { + bell(); + } + return (MCA_MORE); +} + +/* + * Handle a char of an option toggle command. + */ + static int +mca_opt_char(c) + int 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 && len_cmdbuf() == 0) + { + 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)) ++ 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), (void*)NULL, 0); + return (MCA_MORE); +} + ++/* ++ * Normalize search type. ++ */ ++ public int ++norm_search_type(st) ++ 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(c) + int 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 (len_cmdbuf() > 0) + 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; + 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('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; + break; + } + + if (flag != 0) + { - /* Toggle flag, but keep PAST_EOF and WRAP mutually exclusive. */ - search_type ^= flag | (search_type & (SRCH_PAST_EOF|SRCH_WRAP)); ++ search_type = norm_search_type(search_type ^ flag); + mca_search(); + return (MCA_MORE); + } + return (NO_MCA); +} + +/* + * Handle a character of a multi-character command. + */ + static int +mca_char(c) + int c; +{ + int ret; + + switch (mca) + { + case 0: + /* + * We're not in a multicharacter command. + */ + return (NO_MCA); + + case A_PREFIX: + /* + * In the prefix of a command. + * This not considered a multichar command + * (even tho it uses cmdbuf, etc.). + * It is handled in the commands() switch. + */ + return (NO_MCA); + + case A_DIGIT: + /* + * Entering digits of a number. *** 2753 LINES SKIPPED ***