aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2022-09-06 05:52:39 +0000
committerXin LI <delphij@FreeBSD.org>2022-09-20 01:51:53 +0000
commitf447ddc7b861ccdf4f433988776ad537588a2919 (patch)
tree20a6f5b27d35d7d5b033356e115ffb3c93327e3d
parent04c146afea26ea71c6f628ed94435740f87eda7e (diff)
downloadsrc-f447ddc7b861ccdf4f433988776ad537588a2919.tar.gz
src-f447ddc7b861ccdf4f433988776ad537588a2919.zip
MFV: less v608
Relnotes: yes (cherry picked from commit 95270f73baf6fa95ae529bc2eb6a61f5c79f32c0)
-rw-r--r--contrib/less/LICENSE2
-rw-r--r--contrib/less/NEWS67
-rw-r--r--contrib/less/README6
-rw-r--r--contrib/less/brac.c6
-rw-r--r--contrib/less/ch.c19
-rw-r--r--contrib/less/charset.c18
-rw-r--r--contrib/less/charset.h2
-rw-r--r--contrib/less/cmd.h3
-rw-r--r--contrib/less/cmdbuf.c91
-rw-r--r--contrib/less/command.c76
-rw-r--r--contrib/less/compose.uni20
-rw-r--r--contrib/less/cvt.c2
-rw-r--r--contrib/less/decode.c30
-rw-r--r--contrib/less/edit.c4
-rw-r--r--contrib/less/filename.c19
-rw-r--r--contrib/less/fmt.uni3
-rw-r--r--contrib/less/forwback.c126
-rw-r--r--contrib/less/funcs.h18
-rw-r--r--contrib/less/help.c20
-rw-r--r--contrib/less/ifile.c2
-rw-r--r--contrib/less/input.c22
-rw-r--r--contrib/less/jump.c2
-rw-r--r--contrib/less/less.h4
-rw-r--r--contrib/less/less.hlp18
-rw-r--r--contrib/less/less.nro99
-rw-r--r--contrib/less/lessecho.c45
-rw-r--r--contrib/less/lessecho.nro2
-rw-r--r--contrib/less/lesskey.c11
-rw-r--r--contrib/less/lesskey.h2
-rw-r--r--contrib/less/lesskey.nro155
-rw-r--r--contrib/less/lesskey_parse.c238
-rw-r--r--contrib/less/lglob.h2
-rw-r--r--contrib/less/line.c285
-rw-r--r--contrib/less/linenum.c23
-rw-r--r--contrib/less/lsystem.c9
-rw-r--r--contrib/less/main.c25
-rw-r--r--contrib/less/mark.c5
-rw-r--r--contrib/less/optfunc.c131
-rw-r--r--contrib/less/option.c4
-rw-r--r--contrib/less/option.h2
-rw-r--r--contrib/less/opttbl.c65
-rw-r--r--contrib/less/os.c18
-rw-r--r--contrib/less/output.c11
-rw-r--r--contrib/less/pattern.c13
-rw-r--r--contrib/less/pattern.h34
-rw-r--r--contrib/less/pckeys.h2
-rw-r--r--contrib/less/position.c3
-rw-r--r--contrib/less/position.h2
-rw-r--r--contrib/less/prompt.c29
-rw-r--r--contrib/less/screen.c62
-rw-r--r--contrib/less/scrsize.c2
-rw-r--r--contrib/less/search.c59
-rw-r--r--contrib/less/signal.c2
-rw-r--r--contrib/less/tags.c8
-rw-r--r--contrib/less/ttyin.c63
-rw-r--r--contrib/less/ubin.uni2
-rw-r--r--contrib/less/version.c27
-rw-r--r--contrib/less/wide.uni25
-rw-r--r--contrib/less/xbuf.c23
-rw-r--r--contrib/less/xbuf.h3
-rw-r--r--usr.bin/less/defines.h4
61 files changed, 1586 insertions, 489 deletions
diff --git a/contrib/less/LICENSE b/contrib/less/LICENSE
index 315d1d86815c..65bce4288972 100644
--- a/contrib/less/LICENSE
+++ b/contrib/less/LICENSE
@@ -2,7 +2,7 @@
------------
Less
-Copyright (C) 1984-2018 Mark Nudelman
+Copyright (C) 1984-2022 Mark Nudelman
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
diff --git a/contrib/less/NEWS b/contrib/less/NEWS
index a403c5d8a875..bcfe4c6c9e38 100644
--- a/contrib/less/NEWS
+++ b/contrib/less/NEWS
@@ -11,6 +11,73 @@
======================================================================
+ Major changes between "less" versions 590 and 608
+
+* Add the --header option (github #43).
+
+* Add the --no-number-headers option (github #178).
+
+* Add the --status-line option.
+
+* Add the --redraw-on-quit option (github #36).
+
+* Add the --search-options option (github #213).
+
+* Add the --exit-follow-on-close option (github #244).
+
+* Add 'H' color type to set color of header lines.
+
+* Add #version conditional to lesskey.
+
+* Add += syntax to variable section in lesskey files.
+
+* Allow option name in -- command to end with '=' in addition to '\n'.
+
+* Add $HOME/.config to possible locations of lesskey file (github #153).
+
+* Add $XDG_STATE_HOME and $HOME/.local/state to possible locations
+ of history file (github #223).
+
+* Don't read or write history file in secure mode (github #201).
+
+* Fix display of multibyte and double-width chars in prompt.
+
+* Fix ESC-BACKSPACE command when BACKSPACE key does not send 0x08
+ (github #188).
+
+* Add more \k codes to lesskey format.
+
+* Fix bug when empty file is modified while viewing it.
+
+* Fix bug when parsing a malformed lesskey file (githb #234).
+
+* Fix bug scrolling history when --incsearch is set (github #214).
+
+* Fix buffer overflow when invoking lessecho with more than 63 -m/-n
+ options (github #198).
+
+* Fix buffer overflow in bin_file (github #271).
+
+* Fix bug restoring color at end of highlighted text.
+
+* Fix bug in parsing lesskey file.
+
+* Defer moving cursor to lower left in some more cases.
+
+* Suppress TAB filename expansion in some cases where it doesn't make sense.
+
+* Fix termlib detection when compiler doesn't accept
+ calls to undeclared functions.
+
+* Fix bug in input of non-ASCII characters on Windows (github #247)
+
+* Escape filenames when invoking LESSCLOSE.
+
+* Fix bug using multibyte UTF-8 char in search string
+ with --incsearch (github #273).
+
+======================================================================
+
Major changes between "less" versions 581 and 590
* Make less able to read lesskey source files (deprecating lesskey).
diff --git a/contrib/less/README b/contrib/less/README
index 4a5aa62a44ee..4bfdc5e5a67f 100644
--- a/contrib/less/README
+++ b/contrib/less/README
@@ -8,7 +8,7 @@
**************************************************************************
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:
@@ -28,7 +28,7 @@
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.
@@ -41,7 +41,7 @@ INSTALLATION (Unix & Linux systems only):
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.
diff --git a/contrib/less/brac.c b/contrib/less/brac.c
index 53ada50aab56..58ecf172ae4e 100644
--- a/contrib/less/brac.c
+++ b/contrib/less/brac.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -84,7 +84,11 @@ match_brac(obrac, cbrac, forwdir, n)
while ((c = (*chget)()) != EOI)
{
if (c == obrac)
+ {
+ if (nest == INT_MAX)
+ break;
nest++;
+ }
else if (c == cbrac && --nest < 0)
{
/*
diff --git a/contrib/less/ch.c b/contrib/less/ch.c
index 379dd84c41b8..bfad09c719f6 100644
--- a/contrib/less/ch.c
+++ b/contrib/less/ch.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -26,6 +26,10 @@ extern dev_t curr_dev;
extern ino_t curr_ino;
#endif
+#if HAVE_PROCFS
+#include <sys/statfs.h>
+#endif
+
typedef POSITION BLOCKNUM;
public int ignore_eoi;
@@ -725,7 +729,7 @@ ch_flush(VOID_PARAM)
ch_block = 0; /* ch_fpos / LBUFSIZE; */
ch_offset = 0; /* ch_fpos % LBUFSIZE; */
-#if 1
+#if HAVE_PROCFS
/*
* This is a kludge to workaround a Linux kernel bug: files in
* /proc have a size of 0 according to fstat() but have readable
@@ -734,8 +738,15 @@ ch_flush(VOID_PARAM)
*/
if (ch_fsize == 0)
{
- ch_fsize = NULL_POSITION;
- ch_flags &= ~CH_CANSEEK;
+ struct statfs st;
+ if (fstatfs(ch_file, &st) == 0)
+ {
+ if (st.f_type == PROC_SUPER_MAGIC)
+ {
+ ch_fsize = NULL_POSITION;
+ ch_flags &= ~CH_CANSEEK;
+ }
+ }
}
#endif
diff --git a/contrib/less/charset.c b/contrib/less/charset.c
index b37c8a29cbd9..5e9a2d6427b8 100644
--- a/contrib/less/charset.c
+++ b/contrib/less/charset.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -445,7 +445,7 @@ prchar(c)
LWCHAR c;
{
/* {{ This buffer can be overrun if LESSBINFMT is a long string. }} */
- static char buf[32];
+ static char buf[MAX_PRCHAR_LEN+1];
c &= 0377;
if ((c < 128 || !utf_mode) && !control_char(c))
@@ -480,7 +480,7 @@ prchar(c)
prutfchar(ch)
LWCHAR ch;
{
- static char buf[32];
+ static char buf[MAX_PRCHAR_LEN+1];
if (ch == ESC)
strcpy(buf, "ESC");
@@ -805,18 +805,6 @@ is_ubin_char(ch)
{
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;
}
diff --git a/contrib/less/charset.h b/contrib/less/charset.h
index 3e7ecf73db94..aa6273dfda6c 100644
--- a/contrib/less/charset.h
+++ b/contrib/less/charset.h
@@ -1,5 +1,5 @@
/*
- * 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.
diff --git a/contrib/less/cmd.h b/contrib/less/cmd.h
index c51f0bc5c4f3..b0f3fdb14b1e 100644
--- a/contrib/less/cmd.h
+++ b/contrib/less/cmd.h
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -142,4 +142,5 @@
#define SK_F1 14
#define SK_BACKTAB 15
#define SK_CTL_BACKSPACE 16
+#define SK_BACKSPACE 17
#define SK_CONTROL_K 40
diff --git a/contrib/less/cmdbuf.c b/contrib/less/cmdbuf.c
index dd135382aa11..5b5704602d8d 100644
--- a/contrib/less/cmdbuf.c
+++ b/contrib/less/cmdbuf.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -24,6 +24,7 @@ extern int sc_width;
extern int utf_mode;
extern int no_hist_dups;
extern int marks_modified;
+extern int secure;
static char cmdbuf[CMDBUF_SIZE]; /* Buffer for holding a multi-char command */
static int cmd_col; /* Current column of the cursor */
@@ -31,7 +32,7 @@ static int prompt_col; /* Column of cursor just after prompt */
static char *cp; /* Pointer into cmdbuf */
static int cmd_offset; /* Index into cmdbuf of first displayed char */
static int literal; /* Next input char should not be interpreted */
-static int updown_match = -1; /* Prefix length in up/down movement */
+public int updown_match = -1; /* Prefix length in up/down movement */
#if TAB_COMPLETE_FILENAME
static int cmd_complete LESSPARAMS((int action));
@@ -860,9 +861,10 @@ cmd_edit(c)
flags |= ECF_NOHISTORY;
#endif
#if TAB_COMPLETE_FILENAME
- if (curr_mlist == ml_search)
+ if (curr_mlist == ml_search || curr_mlist == NULL)
/*
- * In a search command; don't accept file-completion cmds.
+ * Don't accept file-completion cmds in contexts
+ * such as search pattern, digits, long option name, etc.
*/
flags |= ECF_NOCOMPLETE;
#endif
@@ -1352,7 +1354,15 @@ cmd_int(frac)
int err;
for (p = cmdbuf; *p >= '0' && *p <= '9'; p++)
- n = (n * 10) + (*p - '0');
+ {
+ LINENUM nn = (n * 10) + (*p - '0');
+ if (nn < n)
+ {
+ error("Integer is too big", NULL_PARG);
+ return (0);
+ }
+ n = nn;
+ }
*frac = 0;
if (*p++ == '.')
{
@@ -1368,6 +1378,9 @@ cmd_int(frac)
public char *
get_cmdbuf(VOID_PARAM)
{
+ if (cmd_mbc_buf_index < cmd_mbc_buf_len)
+ /* Don't return buffer containing an incomplete multibyte char. */
+ return (NULL);
return (cmdbuf);
}
@@ -1401,13 +1414,40 @@ mlist_size(ml)
* Get the name of the history file.
*/
static char *
+histfile_find(must_exist)
+ int must_exist;
+{
+ char *home = lgetenv("HOME");
+ char *name = NULL;
+
+ /* Try in $XDG_STATE_HOME, then in $HOME/.local/state, then in $XDG_DATA_HOME, then in $HOME. */
+#if OS2
+ if (isnullenv(home))
+ home = lgetenv("INIT");
+#endif
+ name = dirfile(lgetenv("XDG_STATE_HOME"), &LESSHISTFILE[1], must_exist);
+ if (name == NULL)
+ {
+ char *dir = dirfile(home, ".local/state", 1);
+ if (dir != NULL)
+ {
+ name = dirfile(dir, &LESSHISTFILE[1], must_exist);
+ free(dir);
+ }
+ }
+ if (name == NULL)
+ name = dirfile(lgetenv("XDG_DATA_HOME"), &LESSHISTFILE[1], must_exist);
+ if (name == NULL)
+ name = dirfile(home, LESSHISTFILE, must_exist);
+ return (name);
+}
+
+ static char *
histfile_name(must_exist)
int must_exist;
{
- char *home;
- char *xdg;
char *name;
-
+
/* See if filename is explicitly specified by $LESSHISTFILE. */
name = lgetenv("LESSHISTFILE");
if (!isnullenv(name))
@@ -1422,25 +1462,14 @@ histfile_name(must_exist)
if (strcmp(LESSHISTFILE, "") == 0 || strcmp(LESSHISTFILE, "-") == 0)
return (NULL);
- /* Try in $XDG_DATA_HOME first, then in $HOME. */
- xdg = lgetenv("XDG_DATA_HOME");
- home = lgetenv("HOME");
-#if OS2
- if (isnullenv(home))
- home = lgetenv("INIT");
-#endif
name = NULL;
if (!must_exist)
{
/* If we're writing the file and the file already exists, use it. */
- name = dirfile(xdg, &LESSHISTFILE[1], 1);
- if (name == NULL)
- name = dirfile(home, LESSHISTFILE, 1);
+ name = histfile_find(1);
}
if (name == NULL)
- name = dirfile(xdg, &LESSHISTFILE[1], must_exist);
- if (name == NULL)
- name = dirfile(home, LESSHISTFILE, must_exist);
+ name = histfile_find(must_exist);
return (name);
}
@@ -1524,17 +1553,22 @@ read_cmdhist(action, uparam, skip_search, skip_shell)
int skip_search;
int skip_shell;
{
+ if (secure)
+ return;
read_cmdhist2(action, uparam, skip_search, skip_shell);
(*action)(uparam, NULL, NULL); /* signal end of file */
}
static void
-addhist_init(void *uparam, struct mlist *ml, char *string)
+addhist_init(uparam, ml, string)
+ void *uparam;
+ struct mlist *ml;
+ char constant *string;
{
if (ml != NULL)
cmd_addhist(ml, string, 0);
else if (string != NULL)
- restore_mark(string);
+ restore_mark((char*)string); /* stupid const cast */
}
#endif /* CMD_HISTORY */
@@ -1611,7 +1645,10 @@ struct save_ctx
* created during this session.
*/
static void
-copy_hist(void *uparam, struct mlist *ml, char *string)
+copy_hist(uparam, ml, string)
+ void *uparam;
+ struct mlist *ml;
+ char constant *string;
{
struct save_ctx *ctx = (struct save_ctx *) uparam;
@@ -1673,6 +1710,7 @@ make_file_private(f)
/*
* Does the history file need to be updated?
*/
+#if CMD_HISTORY
static int
histfile_modified(VOID_PARAM)
{
@@ -1682,12 +1720,11 @@ histfile_modified(VOID_PARAM)
if (mlist_shell.modified)
return 1;
#endif
-#if CMD_HISTORY
if (marks_modified)
return 1;
-#endif
return 0;
}
+#endif
/*
* Update the .lesshst file.
@@ -1705,7 +1742,7 @@ save_cmdhist(VOID_PARAM)
FILE *fout = NULL;
int histsize = 0;
- if (!histfile_modified())
+ if (secure || !histfile_modified())
return;
histname = histfile_name(0);
if (histname == NULL)
diff --git a/contrib/less/command.c b/contrib/less/command.c
index 171788f2e750..8bd999e9f7a3 100644
--- a/contrib/less/command.c
+++ b/contrib/less/command.c
@@ -1,6 +1,6 @@
/* $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.
@@ -50,6 +50,9 @@ 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
@@ -154,7 +157,7 @@ in_mca(VOID_PARAM)
* 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)
@@ -189,6 +192,12 @@ mca_search(VOID_PARAM)
else
cmd_putstr("?");
forw_prompt = 0;
+}
+
+ static void
+mca_search(VOID_PARAM)
+{
+ mca_search1();
set_mlist(ml_search, 0);
}
@@ -235,6 +244,8 @@ exec_mca(VOID_PARAM)
cmd_exec();
cbuf = get_cmdbuf();
+ if (cbuf == NULL)
+ return;
switch (mca)
{
@@ -342,6 +353,7 @@ is_newline_char(c)
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)
{
@@ -359,14 +371,14 @@ mca_opt_first_char(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'):
@@ -415,6 +427,8 @@ mca_opt_nonfirst_char(c)
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);
@@ -465,11 +479,13 @@ mca_opt_char(c)
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);
}
@@ -510,6 +526,19 @@ mca_opt_char(c)
}
/*
+ * 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
@@ -563,8 +592,7 @@ mca_search_char(c)
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);
}
@@ -686,6 +714,14 @@ mca_char(c)
/* Incremental search: do a search after every input char. */
int st = (search_type & (SRCH_FORW|SRCH_BACK|SRCH_NO_MATCH|SRCH_NO_REGEX|SRCH_NO_MOVE|SRCH_WRAP));
char *pattern = get_cmdbuf();
+ if (pattern == NULL)
+ return (MCA_MORE);
+ /*
+ * Must save updown_match because mca_search
+ * reinits it. That breaks history scrolling.
+ * {{ This is ugly. mca_search probably shouldn't call set_mlist. }}
+ */
+ int save_updown_match = updown_match;
cmd_exec();
if (*pattern == '\0')
{
@@ -698,7 +734,8 @@ mca_char(c)
undo_search(1);
}
/* Redraw the search prompt and search string. */
- mca_search();
+ mca_search1();
+ updown_match = save_updown_match;
cmd_repaint(NULL);
}
break;
@@ -806,7 +843,7 @@ prompt(VOID_PARAM)
if (!(ch_getflags() & CH_HELPFILE))
{
WCHAR w[MAX_PATH+16];
- p = pr_expand("Less?f - %f.", 0);
+ p = pr_expand("Less?f - %f.");
MultiByteToWideChar(CP_ACP, 0, p, -1, w, sizeof(w)/sizeof(*w));
SetConsoleTitleW(w);
}
@@ -849,9 +886,8 @@ prompt(VOID_PARAM)
0, w, -1, a, sizeof(a), NULL, NULL);
p = a;
#endif
- at_enter(AT_STANDOUT|AT_COLOR_PROMPT);
- putstr(p);
- at_exit();
+ load_line(p);
+ put_line();
}
clear_eol();
}
@@ -928,8 +964,8 @@ getccu(VOID_PARAM)
*/
static LWCHAR
getcc_repl(orig, repl, gr_getc, gr_ungetc)
- char const* orig;
- char const* repl;
+ char constant* orig;
+ char constant* repl;
LWCHAR (*gr_getc)(VOID_PARAM);
void (*gr_ungetc)(LWCHAR);
{
@@ -1286,6 +1322,8 @@ commands(VOID_PARAM)
if (cmd_char(c) == CC_QUIT || len_cmdbuf() == 0)
continue;
cbuf = get_cmdbuf();
+ if (cbuf == NULL)
+ continue;
} else
{
/*
@@ -1609,7 +1647,7 @@ commands(VOID_PARAM)
* Search forward for a pattern.
* Get the first char of the pattern.
*/
- search_type = SRCH_FORW;
+ search_type = SRCH_FORW | def_search_type;
if (number <= 0)
number = 1;
mca_search();
@@ -1621,7 +1659,7 @@ commands(VOID_PARAM)
* Search backward for a pattern.
* Get the first char of the pattern.
*/
- search_type = SRCH_BACK;
+ search_type = SRCH_BACK | def_search_type;
if (number <= 0)
number = 1;
mca_search();
@@ -1741,7 +1779,7 @@ commands(VOID_PARAM)
*/
make_display();
cmd_exec();
- lsystem(pr_expand(editproto, 0), (char*)NULL);
+ lsystem(pr_expand(editproto), (char*)NULL);
break;
}
#endif
diff --git a/contrib/less/compose.uni b/contrib/less/compose.uni
index bbf4b20387fc..cc7ddcf02bb9 100644
--- a/contrib/less/compose.uni
+++ b/contrib/less/compose.uni
@@ -1,4 +1,4 @@
-/* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Tue May 19 14:47:34 PDT 2020 */
+/* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Tue Jul 19 12:45:16 PDT 2022 */
{ 0x0300, 0x036f }, /* Mn */
{ 0x0483, 0x0487 }, /* Mn */
{ 0x0488, 0x0489 }, /* Me */
@@ -24,7 +24,8 @@
{ 0x0825, 0x0827 }, /* Mn */
{ 0x0829, 0x082d }, /* Mn */
{ 0x0859, 0x085b }, /* Mn */
- { 0x08d3, 0x08e1 }, /* Mn */
+ { 0x0898, 0x089f }, /* Mn */
+ { 0x08ca, 0x08e1 }, /* Mn */
{ 0x08e3, 0x0902 }, /* Mn */
{ 0x093a, 0x093a }, /* Mn */
{ 0x093c, 0x093c }, /* Mn */
@@ -65,6 +66,7 @@
{ 0x0bcd, 0x0bcd }, /* Mn */
{ 0x0c00, 0x0c00 }, /* Mn */
{ 0x0c04, 0x0c04 }, /* Mn */
+ { 0x0c3c, 0x0c3c }, /* Mn */
{ 0x0c3e, 0x0c40 }, /* Mn */
{ 0x0c46, 0x0c48 }, /* Mn */
{ 0x0c4a, 0x0c4d }, /* Mn */
@@ -115,7 +117,7 @@
{ 0x1160, 0x11ff }, /* Mn */
{ 0x135d, 0x135f }, /* Mn */
{ 0x1712, 0x1714 }, /* Mn */
- { 0x1732, 0x1734 }, /* Mn */
+ { 0x1732, 0x1733 }, /* Mn */
{ 0x1752, 0x1753 }, /* Mn */
{ 0x1772, 0x1773 }, /* Mn */
{ 0x17b4, 0x17b5 }, /* Mn */
@@ -124,6 +126,7 @@
{ 0x17c9, 0x17d3 }, /* Mn */
{ 0x17dd, 0x17dd }, /* Mn */
{ 0x180b, 0x180d }, /* Mn */
+ { 0x180f, 0x180f }, /* Mn */
{ 0x1885, 0x1886 }, /* Mn */
{ 0x18a9, 0x18a9 }, /* Mn */
{ 0x1920, 0x1922 }, /* Mn */
@@ -141,7 +144,7 @@
{ 0x1a7f, 0x1a7f }, /* Mn */
{ 0x1ab0, 0x1abd }, /* Mn */
{ 0x1abe, 0x1abe }, /* Me */
- { 0x1abf, 0x1ac0 }, /* Mn */
+ { 0x1abf, 0x1ace }, /* Mn */
{ 0x1b00, 0x1b03 }, /* Mn */
{ 0x1b34, 0x1b34 }, /* Mn */
{ 0x1b36, 0x1b3a }, /* Mn */
@@ -164,8 +167,7 @@
{ 0x1ced, 0x1ced }, /* Mn */
{ 0x1cf4, 0x1cf4 }, /* Mn */
{ 0x1cf8, 0x1cf9 }, /* Mn */
- { 0x1dc0, 0x1df9 }, /* Mn */
- { 0x1dfb, 0x1dff }, /* Mn */
+ { 0x1dc0, 0x1dff }, /* Mn */
{ 0x20d0, 0x20dc }, /* Mn */
{ 0x20dd, 0x20e0 }, /* Me */
{ 0x20e1, 0x20e1 }, /* Mn */
@@ -229,11 +231,15 @@
{ 0x10d24, 0x10d27 }, /* Mn */
{ 0x10eab, 0x10eac }, /* Mn */
{ 0x10f46, 0x10f50 }, /* Mn */
+ { 0x10f82, 0x10f85 }, /* Mn */
{ 0x11001, 0x11001 }, /* Mn */
{ 0x11038, 0x11046 }, /* Mn */
+ { 0x11070, 0x11070 }, /* Mn */
+ { 0x11073, 0x11074 }, /* Mn */
{ 0x1107f, 0x11081 }, /* Mn */
{ 0x110b3, 0x110b6 }, /* Mn */
{ 0x110b9, 0x110ba }, /* Mn */
+ { 0x110c2, 0x110c2 }, /* Mn */
{ 0x11100, 0x11102 }, /* Mn */
{ 0x11127, 0x1112b }, /* Mn */
{ 0x1112d, 0x11134 }, /* Mn */
@@ -313,6 +319,8 @@
{ 0x16f8f, 0x16f92 }, /* Mn */
{ 0x16fe4, 0x16fe4 }, /* Mn */
{ 0x1bc9d, 0x1bc9e }, /* Mn */
+ { 0x1cf00, 0x1cf2d }, /* Mn */
+ { 0x1cf30, 0x1cf46 }, /* Mn */
{ 0x1d167, 0x1d169 }, /* Mn */
{ 0x1d17b, 0x1d182 }, /* Mn */
{ 0x1d185, 0x1d18b }, /* Mn */
diff --git a/contrib/less/cvt.c b/contrib/less/cvt.c
index 9cf44b894e7d..bb4649264f12 100644
--- a/contrib/less/cvt.c
+++ b/contrib/less/cvt.c
@@ -1,5 +1,5 @@
/*
- * 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.
diff --git a/contrib/less/decode.c b/contrib/less/decode.c
index 7e9b167bc786..0444cab399c9 100644
--- a/contrib/less/decode.c
+++ b/contrib/less/decode.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -206,7 +206,7 @@ static unsigned char edittable[] =
ESC,SK(SK_DELETE),0, EC_W_DELETE, /* ESC DELETE */
SK(SK_CTL_DELETE),0, EC_W_DELETE, /* CTRL-DELETE */
SK(SK_CTL_BACKSPACE),0, EC_W_BACKSPACE, /* CTRL-BACKSPACE */
- ESC,'\b',0, EC_W_BACKSPACE, /* ESC BACKSPACE */
+ ESC,SK(SK_BACKSPACE),0, EC_W_BACKSPACE, /* ESC BACKSPACE */
ESC,'0',0, EC_HOME, /* ESC 0 */
SK(SK_HOME),0, EC_HOME, /* HOME */
ESC,'$',0, EC_END, /* ESC $ */
@@ -268,7 +268,7 @@ expand_special_keys(table, len)
}
/*
* After SK_SPECIAL_KEY, next byte is the type
- * of special key (one of the SK_* contants),
+ * of special key (one of the SK_* constants),
* and the byte after that is the number of bytes,
* N, reserved by the abbreviation (including the
* SK_SPECIAL_KEY and key type bytes).
@@ -785,6 +785,7 @@ new_lesskey(buf, len, sysvar)
int sysvar;
{
char *p;
+ char *end;
int c;
int n;
@@ -797,6 +798,7 @@ new_lesskey(buf, len, sysvar)
buf[len-1] != C2_END_LESSKEY_MAGIC)
return (-1);
p = buf + 4;
+ end = buf + len;
for (;;)
{
c = *p++;
@@ -804,16 +806,22 @@ new_lesskey(buf, len, sysvar)
{
case CMD_SECTION:
n = gint(&p);
+ if (n < 0 || p+n >= end)
+ return (-1);
add_fcmd_table(p, n);
p += n;
break;
case EDIT_SECTION:
n = gint(&p);
+ if (n < 0 || p+n >= end)
+ return (-1);
add_ecmd_table(p, n);
p += n;
break;
case VAR_SECTION:
n = gint(&p);
+ if (n < 0 || p+n >= end)
+ return (-1);
add_var_table((sysvar) ?
&list_sysvar_tables : &list_var_tables, p, n);
p += n;
@@ -891,7 +899,8 @@ lesskey(filename, sysvar)
* Figure out if this is an old-style (before version 241)
* or new-style lesskey file format.
*/
- if (buf[0] != C0_LESSKEY_MAGIC || buf[1] != C1_LESSKEY_MAGIC ||
+ if (len < 4 ||
+ buf[0] != C0_LESSKEY_MAGIC || buf[1] != C1_LESSKEY_MAGIC ||
buf[2] != C2_LESSKEY_MAGIC || buf[3] != C3_LESSKEY_MAGIC)
return (old_lesskey(buf, (int)len));
return (new_lesskey(buf, (int)len, sysvar));
@@ -943,9 +952,20 @@ add_hometable(call_lesskey, envname, def_filename, sysvar)
filename = save(def_filename);
else /* def_filename is just basename */
{
+ /* Remove first char (normally a dot) unless stored in $HOME. */
char *xdg = lgetenv("XDG_CONFIG_HOME");
if (!isnullenv(xdg))
- filename = dirfile(xdg, def_filename+1, 1);
+ filename = dirfile(xdg, &def_filename[1], 1);
+ if (filename == NULL)
+ {
+ char *home = lgetenv("HOME");
+ if (!isnullenv(home))
+ {
+ char *cfg_dir = dirfile(home, ".config", 0);
+ filename = dirfile(cfg_dir, &def_filename[1], 1);
+ free(cfg_dir);
+ }
+ }
if (filename == NULL)
filename = homefile(def_filename);
}
diff --git a/contrib/less/edit.c b/contrib/less/edit.c
index 529ed75b0afe..151ac744f7b5 100644
--- a/contrib/less/edit.c
+++ b/contrib/less/edit.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -27,6 +27,7 @@ extern int is_tty;
extern int sigs;
extern int hshift;
extern int want_filesize;
+extern int consecutive_nulls;
extern IFILE curr_ifile;
extern IFILE old_ifile;
extern struct scrpos initial_scrpos;
@@ -438,6 +439,7 @@ edit_ifile(ifile)
get_pos(curr_ifile, &initial_scrpos);
new_file = TRUE;
ch_init(f, chflags);
+ consecutive_nulls = 0;
if (!(chflags & CH_HELPFILE))
{
diff --git a/contrib/less/filename.c b/contrib/less/filename.c
index aba8d3a362e3..6d29753c3d2b 100644
--- a/contrib/less/filename.c
+++ b/contrib/less/filename.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -477,7 +477,7 @@ bin_file(f)
edata = &data[n];
for (p = data; p < edata; )
{
- if (utf_mode && !is_utf8_well_formed(p, edata-data))
+ if (utf_mode && !is_utf8_well_formed(p, edata-p))
{
bin_count++;
utf_skip_to_lead(&p, edata);
@@ -757,10 +757,11 @@ lglob(filename)
*/
len = (int) (strlen(lessecho) + strlen(filename) + (7*strlen(metachars())) + 24);
cmd = (char *) ecalloc(len, sizeof(char));
- SNPRINTF4(cmd, len, "%s -p0x%x -d0x%x -e%s ", lessecho, openquote, closequote, esc);
+ SNPRINTF4(cmd, len, "%s -p0x%x -d0x%x -e%s ", lessecho,
+ (unsigned char) openquote, (unsigned char) closequote, esc);
free(esc);
for (s = metachars(); *s != '\0'; s++)
- sprintf(cmd + strlen(cmd), "-n0x%x ", *s);
+ sprintf(cmd + strlen(cmd), "-n0x%x ", (unsigned char) *s);
sprintf(cmd + strlen(cmd), "-- %s", filename);
fd = shellcmd(cmd);
free(cmd);
@@ -971,6 +972,8 @@ close_altfile(altfilename, filename)
{
#if HAVE_POPEN
char *lessclose;
+ char *qfilename;
+ char *qaltfilename;
FILE *fd;
char *cmd;
int len;
@@ -985,9 +988,13 @@ close_altfile(altfilename, filename)
error("LESSCLOSE ignored; must contain no more than 2 %%s", NULL_PARG);
return;
}
- len = (int) (strlen(lessclose) + strlen(filename) + strlen(altfilename) + 2);
+ qfilename = shell_quote(filename);
+ qaltfilename = shell_quote(altfilename);
+ len = (int) (strlen(lessclose) + strlen(qfilename) + strlen(qaltfilename) + 2);
cmd = (char *) ecalloc(len, sizeof(char));
- SNPRINTF2(cmd, len, lessclose, filename, altfilename);
+ SNPRINTF2(cmd, len, lessclose, qfilename, qaltfilename);
+ free(qaltfilename);
+ free(qfilename);
fd = shellcmd(cmd);
free(cmd);
if (fd != NULL)
diff --git a/contrib/less/fmt.uni b/contrib/less/fmt.uni
index bef4227fea9e..c4822942a166 100644
--- a/contrib/less/fmt.uni
+++ b/contrib/less/fmt.uni
@@ -1,9 +1,10 @@
-/* Generated by "./mkutable -f2 Cf -- unicode/UnicodeData.txt" on Tue May 19 14:47:34 PDT 2020 */
+/* Generated by "./mkutable -f2 Cf -- unicode/UnicodeData.txt" on Tue Jul 19 12:45:17 PDT 2022 */
{ 0x00ad, 0x00ad }, /* Cf */
{ 0x0600, 0x0605 }, /* Cf */
{ 0x061c, 0x061c }, /* Cf */
{ 0x06dd, 0x06dd }, /* Cf */
{ 0x070f, 0x070f }, /* Cf */
+ { 0x0890, 0x0891 }, /* Cf */
{ 0x08e2, 0x08e2 }, /* Cf */
{ 0x180e, 0x180e }, /* Cf */
{ 0x200b, 0x200f }, /* Cf */
diff --git a/contrib/less/forwback.c b/contrib/less/forwback.c
index db16da4a4aff..8dfd01cea98e 100644
--- a/contrib/less/forwback.c
+++ b/contrib/less/forwback.c
@@ -1,6 +1,5 @@
-/* $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.
@@ -17,23 +16,28 @@
#include "less.h"
#include "position.h"
+extern int less_is_more;
+
public int screen_trashed;
public int squished;
public int no_back_scroll = 0;
public int forw_prompt;
+public int first_time = 1;
extern int sigs;
extern int top_scroll;
extern int quiet;
extern int sc_width, sc_height;
-extern int less_is_more;
+extern int hshift;
+extern int auto_wrap;
extern int plusoption;
extern int forw_scroll;
extern int back_scroll;
extern int ignore_eoi;
extern int clear_bg;
extern int final_attr;
-extern int oldbot;
+extern int header_lines;
+extern int header_cols;
#if HILITE_SEARCH
extern int size_linebuf;
extern int hilite_search;
@@ -122,6 +126,94 @@ squish_check(VOID_PARAM)
}
/*
+ * Read the first pfx columns of the next line.
+ * If skipeol==0 stop there, otherwise read and discard chars to end of line.
+ */
+ static POSITION
+forw_line_pfx(pos, pfx, skipeol)
+ POSITION pos;
+ int pfx;
+ int skipeol;
+{
+ int save_sc_width = sc_width;
+ int save_auto_wrap = auto_wrap;
+ int save_hshift = hshift;
+ /* Set fake sc_width to force only pfx chars to be read. */
+ sc_width = pfx + line_pfx_width();
+ auto_wrap = 0;
+ hshift = 0;
+ pos = forw_line_seg(pos, skipeol, FALSE, FALSE);
+ sc_width = save_sc_width;
+ auto_wrap = save_auto_wrap;
+ hshift = save_hshift;
+ return pos;
+}
+
+/*
+ * Set header text color.
+ * Underline last line of headers, but not at beginning of file
+ * (where there is no gap between the last header line and the next line).
+ */
+ static void
+set_attr_header(ln)
+ int ln;
+{
+ set_attr_line(AT_COLOR_HEADER);
+ if (ln+1 == header_lines && position(0) != ch_zero())
+ set_attr_line(AT_UNDERLINE);
+}
+
+/*
+ * Display file headers, overlaying text already drawn
+ * at top and left of screen.
+ */
+ public int
+overlay_header(VOID_PARAM)
+{
+ POSITION pos = ch_zero(); /* header lines are at beginning of file */
+ int ln;
+ int moved = FALSE;
+
+ if (header_lines > 0)
+ {
+ /* Draw header_lines lines from start of file at top of screen. */
+ home();
+ for (ln = 0; ln < header_lines; ++ln)
+ {
+ pos = forw_line(pos);
+ set_attr_header(ln);
+ clear_eol();
+ put_line();
+ }
+ moved = TRUE;
+ }
+ if (header_cols > 0)
+ {
+ /* Draw header_cols columns at left of each line. */
+ home();
+ pos = ch_zero();
+ for (ln = 0; ln < sc_height-1; ++ln)
+ {
+ if (ln >= header_lines) /* switch from header lines to normal lines */
+ pos = position(ln);
+ if (pos == NULL_POSITION)
+ putchr('\n');
+ else
+ {
+ /* Need skipeol for all header lines except the last one. */
+ pos = forw_line_pfx(pos, header_cols, ln+1 < header_lines);
+ set_attr_header(ln);
+ put_line();
+ }
+ }
+ moved = TRUE;
+ }
+ if (moved)
+ lower_left();
+ return moved;
+}
+
+/*
* Display n lines, scrolling forward,
* starting at position pos in the input file.
* "force" means display the n lines even if we hit end of file.
@@ -140,7 +232,6 @@ forw(n, pos, force, only_last, nblank)
{
int nlines = 0;
int do_repaint;
- static int first_time = 1;
squish_check();
@@ -296,10 +387,27 @@ forw(n, pos, force, only_last, nblank)
forw_prompt = 1;
}
+ if (header_lines > 0)
+ {
+ /*
+ * Don't allow ch_zero to appear on screen except at top of screen.
+ * Otherwise duplicate header lines may be displayed.
+ */
+ if (onscreen(ch_zero()) > 0)
+ {
+ jump_loc(ch_zero(), 0); /* {{ yuck }} */
+ return;
+ }
+ }
if (nlines == 0 && !ignore_eoi)
eof_bell();
else if (do_repaint)
repaint();
+ else
+ {
+ overlay_header();
+ /* lower_left(); {{ considered harmful? }} */
+ }
first_time = 0;
(void) currline(BOTTOM);
}
@@ -318,7 +426,7 @@ back(n, pos, force, only_last)
int do_repaint;
squish_check();
- do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1));
+ do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1) || header_lines > 0);
#if HILITE_SEARCH
if (hilite_search == OPT_ONPLUS || is_filtering() || status_col) {
prep_hilite((pos < 3*size_linebuf) ? 0 : pos - 3*size_linebuf, pos, -1);
@@ -355,13 +463,15 @@ back(n, pos, force, only_last)
put_line();
}
}
-
if (nlines == 0)
eof_bell();
else if (do_repaint)
repaint();
- else if (!oldbot)
+ else
+ {
+ overlay_header();
lower_left();
+ }
(void) currline(BOTTOM);
}
diff --git a/contrib/less/funcs.h b/contrib/less/funcs.h
index 330540ac2156..146dffdc0cae 100644
--- a/contrib/less/funcs.h
+++ b/contrib/less/funcs.h
@@ -87,6 +87,7 @@ public char * cmd_lastpattern LESSPARAMS ((VOID_PARAM));
public void init_cmdhist LESSPARAMS ((VOID_PARAM));
public void save_cmdhist LESSPARAMS ((VOID_PARAM));
public int in_mca LESSPARAMS ((VOID_PARAM));
+public int norm_search_type LESSPARAMS ((int st));
public void dispversion LESSPARAMS ((VOID_PARAM));
public int getcc LESSPARAMS ((VOID_PARAM));
public void ungetcc LESSPARAMS ((LWCHAR c));
@@ -147,6 +148,7 @@ public char * last_component LESSPARAMS ((char *name));
public int eof_displayed LESSPARAMS ((VOID_PARAM));
public int entire_file_displayed LESSPARAMS ((VOID_PARAM));
public void squish_check LESSPARAMS ((VOID_PARAM));
+public int overlay_header LESSPARAMS ((VOID_PARAM));
public void forw LESSPARAMS ((int n, POSITION pos, int force, int only_last, int nblank));
public void back LESSPARAMS ((int n, POSITION pos, int force, int only_last));
public void forward LESSPARAMS ((int n, int force, int only_last));
@@ -175,7 +177,7 @@ public void * get_altpipe LESSPARAMS ((IFILE ifile));
public void set_altfilename LESSPARAMS ((IFILE ifile, char *altfilename));
public char * get_altfilename LESSPARAMS ((IFILE ifile));
public void if_dump LESSPARAMS ((VOID_PARAM));
-public POSITION forw_line_seg LESSPARAMS ((POSITION curr_pos, int get_segpos));
+public POSITION forw_line_seg LESSPARAMS ((POSITION curr_pos, int skipeol, int rscroll, int nochop));
public POSITION forw_line LESSPARAMS ((POSITION curr_pos));
public POSITION back_line LESSPARAMS ((POSITION curr_pos));
public void set_attnpos LESSPARAMS ((POSITION pos));
@@ -202,11 +204,13 @@ public void ansi_done LESSPARAMS ((struct ansi_state *pansi));
public int pappend LESSPARAMS ((int c, POSITION pos));
public int pflushmbc LESSPARAMS ((VOID_PARAM));
public void pdone LESSPARAMS ((int endline, int chopped, int forw));
+public void set_attr_line LESSPARAMS ((int a));
public void set_status_col LESSPARAMS ((int c, int attr));
public int gline LESSPARAMS ((int i, int *ap));
public void null_line LESSPARAMS ((VOID_PARAM));
public POSITION forw_raw_line LESSPARAMS ((POSITION curr_pos, char **linep, int *line_lenp));
public POSITION back_raw_line LESSPARAMS ((POSITION curr_pos, char **linep, int *line_lenp));
+public void load_line LESSPARAMS ((constant char *str));
public int rrshift LESSPARAMS ((VOID_PARAM));
public int set_color_map LESSPARAMS ((int attr, char *colorstr));
public char * get_color_map LESSPARAMS ((int attr));
@@ -216,6 +220,7 @@ public LINENUM find_linenum LESSPARAMS ((POSITION pos));
public POSITION find_pos LESSPARAMS ((LINENUM linenum));
public LINENUM currline LESSPARAMS ((int where));
public void scan_eof LESSPARAMS ((VOID_PARAM));
+public LINENUM vlinenum LESSPARAMS ((LINENUM linenum));
public void lsystem LESSPARAMS ((char *cmd, char *donemsg));
public int pipe_mark LESSPARAMS ((int c, char *cmd));
public int pipe_data LESSPARAMS ((char *cmd, POSITION spos, POSITION epos));
@@ -256,8 +261,11 @@ public void opt_wheel_lines LESSPARAMS ((int type, char *s));
public void opt_linenum_width LESSPARAMS ((int type, char *s));
public void opt_status_col_width LESSPARAMS ((int type, char *s));
public void opt_filesize LESSPARAMS ((int type, char *s));
+public void opt_header LESSPARAMS ((int type, char *s));
+public void opt_search_type LESSPARAMS ((int type, char *s));
public void opt_ttyin_name LESSPARAMS ((int type, char *s));
public void opt_rstat LESSPARAMS ((int type, char *s));
+public int chop_line LESSPARAMS ((VOID_PARAM));
public int get_swindow LESSPARAMS ((VOID_PARAM));
public char * propt LESSPARAMS ((int c));
public void scan_option LESSPARAMS ((char *s));
@@ -309,7 +317,7 @@ public int empty_lines LESSPARAMS ((int s, int e));
public void get_scrpos LESSPARAMS ((struct scrpos *scrpos, int where));
public int sindex_from_sline LESSPARAMS ((int sline));
public void init_prompt LESSPARAMS ((VOID_PARAM));
-public char * pr_expand LESSPARAMS ((constant char *proto, int maxwidth));
+public char * pr_expand LESSPARAMS ((constant char *proto));
public char * eq_message LESSPARAMS ((VOID_PARAM));
public char * pr_string LESSPARAMS ((VOID_PARAM));
public char * wait_message LESSPARAMS ((VOID_PARAM));
@@ -342,7 +350,7 @@ public char * prevtag LESSPARAMS ((int n));
public int ntags LESSPARAMS ((VOID_PARAM));
public int curr_tag LESSPARAMS ((VOID_PARAM));
public int edit_tagfile LESSPARAMS ((VOID_PARAM));
-public char * tty_device LESSPARAMS ((VOID_PARAM));
+public int open_tty LESSPARAMS ((VOID_PARAM));
public void open_getchr LESSPARAMS ((VOID_PARAM));
public void close_getchr LESSPARAMS ((VOID_PARAM));
public int default_wheel_lines LESSPARAMS ((VOID_PARAM));
@@ -351,4 +359,6 @@ public int getchr LESSPARAMS ((VOID_PARAM));
public void xbuf_init LESSPARAMS ((struct xbuffer *xbuf));
public void xbuf_deinit LESSPARAMS ((struct xbuffer *xbuf));
public void xbuf_reset LESSPARAMS ((struct xbuffer *xbuf));
-public void xbuf_add LESSPARAMS ((struct xbuffer *xbuf, char ch));
+public void xbuf_add LESSPARAMS ((struct xbuffer *xbuf, int ch));
+public int xbuf_pop LESSPARAMS ((struct xbuffer *buf));
+public void xbuf_set LESSPARAMS ((struct xbuffer *dst, struct xbuffer *src));
diff --git a/contrib/less/help.c b/contrib/less/help.c
index 9dabd43ca221..75a91d1e1948 100644
--- a/contrib/less/help.c
+++ b/contrib/less/help.c
@@ -1,4 +1,4 @@
-/* This file was generated by mkhelp.pl from less.hlp at 17:45 on 2021/6/3 */
+/* This file was generated by mkhelp.pl from less.hlp at 19:26 on 2022/7/22 */
#include "less.h"
constant char helpdata[] = {
'\n',
@@ -79,7 +79,7 @@ constant char helpdata[] = {
' ',' ','\'','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','G','o',' ','t','o',' ','a',' ','p','r','e','v','i','o','u','s','l','y',' ','m','a','r','k','e','d',' ','p','o','s','i','t','i','o','n','.','\n',
' ',' ','\'','\'',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','G','o',' ','t','o',' ','t','h','e',' ','p','r','e','v','i','o','u','s',' ','p','o','s','i','t','i','o','n','.','\n',
' ',' ','^','X','^','X',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','a','m','e',' ','a','s',' ','\'','.','\n',
-' ',' ','E','S','C','-','M','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ','C','l','e','a','r',' ','a',' ','m','a','r','k','.','\n',
+' ',' ','E','S','C','-','m','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ','C','l','e','a','r',' ','a',' ','m','a','r','k','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
' ',' ',' ',' ',' ',' ',' ',' ','A',' ','m','a','r','k',' ','i','s',' ','a','n','y',' ','u','p','p','e','r','-','c','a','s','e',' ','o','r',' ','l','o','w','e','r','-','c','a','s','e',' ','l','e','t','t','e','r','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','C','e','r','t','a','i','n',' ','m','a','r','k','s',' ','a','r','e',' ','p','r','e','d','e','f','i','n','e','d',':','\n',
@@ -164,8 +164,10 @@ constant char helpdata[] = {
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','I','g','n','o','r','e',' ','t','h','e',' ','L','E','S','S','O','P','E','N',' ','e','n','v','i','r','o','n','m','e','n','t',' ','v','a','r','i','a','b','l','e','.','\n',
' ',' ','-','m',' ',' ','-','M',' ',' ','.','.','.','.',' ',' ','-','-','l','o','n','g','-','p','r','o','m','p','t',' ',' ','-','-','L','O','N','G','-','P','R','O','M','P','T','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','p','r','o','m','p','t',' ','s','t','y','l','e','.','\n',
-' ',' ','-','n',' ',' ','-','N',' ',' ','.','.','.','.',' ',' ','-','-','l','i','n','e','-','n','u','m','b','e','r','s',' ',' ','-','-','L','I','N','E','-','N','U','M','B','E','R','S','\n',
-' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','u','s','e',' ','l','i','n','e',' ','n','u','m','b','e','r','s','.','\n',
+' ',' ','-','n',' ','.','.','.','.','.','.','.','.','.',' ',' ','-','-','l','i','n','e','-','n','u','m','b','e','r','s','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','u','p','p','r','e','s','s',' ','l','i','n','e',' ','n','u','m','b','e','r','s',' ','i','n',' ','p','r','o','m','p','t','s',' ','a','n','d',' ','m','e','s','s','a','g','e','s','.','\n',
+' ',' ','-','N',' ','.','.','.','.','.','.','.','.','.',' ',' ','-','-','L','I','N','E','-','N','U','M','B','E','R','S','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','l','i','n','e',' ','n','u','m','b','e','r',' ','a','t',' ','s','t','a','r','t',' ','o','f',' ','e','a','c','h',' ','l','i','n','e','.','\n',
' ',' ','-','o',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','l','o','g','-','f','i','l','e','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','o','p','y',' ','t','o',' ','l','o','g',' ','f','i','l','e',' ','(','s','t','a','n','d','a','r','d',' ','i','n','p','u','t',' ','o','n','l','y',')','.','\n',
' ',' ','-','O',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','L','O','G','-','F','I','L','E','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
@@ -212,6 +214,8 @@ constant char helpdata[] = {
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','A','u','t','o','m','a','t','i','c','a','l','l','y',' ','d','e','t','e','r','m','i','n','e',' ','t','h','e',' ','s','i','z','e',' ','o','f',' ','t','h','e',' ','i','n','p','u','t',' ','f','i','l','e','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','f','o','l','l','o','w','-','n','a','m','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','h','e',' ','F',' ','c','o','m','m','a','n','d',' ','c','h','a','n','g','e','s',' ','f','i','l','e','s',' ','i','f',' ','t','h','e',' ','i','n','p','u','t',' ','f','i','l','e',' ','i','s',' ','r','e','n','a','m','e','d','.','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','h','e','a','d','e','r','=','[','_','\b','N','[',',','_','\b','M',']',']','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','N',' ','l','i','n','e','s',' ','a','n','d',' ','M',' ','c','o','l','u','m','n','s',' ','t','o',' ','d','i','s','p','l','a','y',' ','f','i','l','e',' ','h','e','a','d','e','r','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','i','n','c','s','e','a','r','c','h','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','a','r','c','h',' ','f','i','l','e',' ','a','s',' ','e','a','c','h',' ','p','a','t','t','e','r','n',' ','c','h','a','r','a','c','t','e','r',' ','i','s',' ','t','y','p','e','d',' ','i','n','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','l','i','n','e','-','n','u','m','-','w','i','d','t','h','=','N','\n',
@@ -222,12 +226,20 @@ constant char helpdata[] = {
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','s','e','n','d',' ','t','e','r','m','c','a','p',' ','k','e','y','p','a','d',' ','i','n','i','t','/','d','e','i','n','i','t',' ','s','t','r','i','n','g','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','h','i','s','t','d','u','p','s','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','m','o','v','e',' ','d','u','p','l','i','c','a','t','e','s',' ','f','r','o','m',' ','c','o','m','m','a','n','d',' ','h','i','s','t','o','r','y','.','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','n','u','m','b','e','r','-','h','e','a','d','e','r','s','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','g','i','v','e',' ','l','i','n','e',' ','n','u','m','b','e','r','s',' ','t','o',' ','h','e','a','d','e','r',' ','l','i','n','e','s','.','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','r','e','d','r','a','w','-','o','n','-','q','u','i','t','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','d','r','a','w',' ','f','i','n','a','l',' ','s','c','r','e','e','n',' ','w','h','e','n',' ','q','u','i','t','t','i','n','g','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','r','s','c','r','o','l','l','=','C','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','h','e',' ','c','h','a','r','a','c','t','e','r',' ','u','s','e','d',' ','t','o',' ','m','a','r','k',' ','t','r','u','n','c','a','t','e','d',' ','l','i','n','e','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','a','v','e','-','m','a','r','k','s','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','t','a','i','n',' ','m','a','r','k','s',' ','a','c','r','o','s','s',' ','i','n','v','o','c','a','t','i','o','n','s',' ','o','f',' ','l','e','s','s','.','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','e','a','r','c','h','-','o','p','t','i','o','n','s','=','[','E','F','K','N','R','W','-',']','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','d','e','f','a','u','l','t',' ','o','p','t','i','o','n','s',' ','f','o','r',' ','e','v','e','r','y',' ','s','e','a','r','c','h','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','t','a','t','u','s','-','c','o','l','-','w','i','d','t','h','=','N','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','h','e',' ','w','i','d','t','h',' ','o','f',' ','t','h','e',' ','-','J',' ','s','t','a','t','u','s',' ','c','o','l','u','m','n',' ','t','o',' ','N',' ','c','h','a','r','a','c','t','e','r','s','.','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','t','a','t','u','s','-','l','i','n','e','\n',
+' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','o','r',' ','c','o','l','o','r',' ','t','h','e',' ','e','n','t','i','r','e',' ','l','i','n','e',' ','c','o','n','t','a','i','n','i','n','g',' ','a',' ','m','a','r','k','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','u','s','e','-','b','a','c','k','s','l','a','s','h','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','u','b','s','e','q','u','e','n','t',' ','o','p','t','i','o','n','s',' ','u','s','e',' ','b','a','c','k','s','l','a','s','h',' ','a','s',' ','e','s','c','a','p','e',' ','c','h','a','r','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','u','s','e','-','c','o','l','o','r','\n',
diff --git a/contrib/less/ifile.c b/contrib/less/ifile.c
index bc47a666754f..6b3d1ce9a5e3 100644
--- a/contrib/less/ifile.c
+++ b/contrib/less/ifile.c
@@ -1,5 +1,5 @@
/*
- * 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.
diff --git a/contrib/less/input.c b/contrib/less/input.c
index f57c9e3403f2..ffd2f13e3f3f 100644
--- a/contrib/less/input.c
+++ b/contrib/less/input.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -20,7 +20,6 @@
#include "less.h"
extern int squeeze;
-extern int chopline;
extern int hshift;
extern int quit_if_one_screen;
extern int sigs;
@@ -42,9 +41,11 @@ extern int show_attn;
* of the NEXT line. The line obtained is the line starting at curr_pos.
*/
public POSITION
-forw_line_seg(curr_pos, get_segpos)
+forw_line_seg(curr_pos, skipeol, rscroll, nochop)
POSITION curr_pos;
- int get_segpos;
+ int skipeol;
+ int rscroll;
+ int nochop;
{
POSITION base_pos;
POSITION new_pos;
@@ -160,7 +161,7 @@ get_forw_line:
*/
backchars = pflushmbc();
new_pos = ch_tell();
- if (backchars > 0 && !chopline && hshift == 0)
+ if (backchars > 0 && (nochop || !chop_line()) && hshift == 0)
{
new_pos -= backchars + 1;
endline = FALSE;
@@ -182,7 +183,7 @@ get_forw_line:
* is too long to print in the screen width.
* End the line here.
*/
- if ((chopline || hshift > 0) && !get_segpos)
+ if (skipeol)
{
/* Read to end of line. */
do
@@ -215,7 +216,7 @@ get_forw_line:
pappend(' ', ch_tell()-1);
}
#endif
- pdone(endline, chopped, 1);
+ pdone(endline, rscroll && chopped, 1);
#if HILITE_SEARCH
if (is_filtered(base_pos))
@@ -261,7 +262,8 @@ get_forw_line:
forw_line(curr_pos)
POSITION curr_pos;
{
- return forw_line_seg(curr_pos, FALSE);
+
+ return forw_line_seg(curr_pos, (chop_line() || hshift > 0), TRUE, FALSE);
}
/*
@@ -397,7 +399,7 @@ get_back_line:
if (c == '\n')
{
backchars = pflushmbc();
- if (backchars > 0 && !chopline && hshift == 0)
+ if (backchars > 0 && !chop_line() && hshift == 0)
{
backchars++;
goto shift;
@@ -413,7 +415,7 @@ get_back_line:
* reached our curr_pos yet. Discard the line
* and start a new one.
*/
- if (chopline || hshift > 0)
+ if (chop_line() || hshift > 0)
{
endline = TRUE;
chopped = TRUE;
diff --git a/contrib/less/jump.c b/contrib/less/jump.c
index a376486c5e23..ee1b0c632028 100644
--- a/contrib/less/jump.c
+++ b/contrib/less/jump.c
@@ -1,5 +1,5 @@
/*
- * 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.
diff --git a/contrib/less/less.h b/contrib/less/less.h
index 83e31514be3e..43e2cc476a7d 100644
--- a/contrib/less/less.h
+++ b/contrib/less/less.h
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -231,6 +231,7 @@ typedef off_t LINENUM;
#define MAX_LINENUM_WIDTH 16 /* Max width of a line number */
#define MAX_STATUSCOL_WIDTH 4 /* Max width of the status column */
#define MAX_UTF_CHAR_LEN 6 /* Max bytes in one UTF-8 char */
+#define MAX_PRCHAR_LEN 31 /* Max chars in prchar() result */
#define NULL_POSITION ((POSITION)(-1))
@@ -406,6 +407,7 @@ struct wchar_range_table
#define AT_COLOR_PROMPT (7 << AT_COLOR_SHIFT)
#define AT_COLOR_RSCROLL (8 << AT_COLOR_SHIFT)
#define AT_COLOR_SEARCH (9 << AT_COLOR_SHIFT)
+#define AT_COLOR_HEADER (11 << AT_COLOR_SHIFT)
typedef enum { CT_NULL, CT_4BIT, CT_6BIT } COLOR_TYPE;
diff --git a/contrib/less/less.hlp b/contrib/less/less.hlp
index 333a0b576c5e..59725788f609 100644
--- a/contrib/less/less.hlp
+++ b/contrib/less/less.hlp
@@ -76,7 +76,7 @@
'_<_l_e_t_t_e_r_> Go to a previously marked position.
'' Go to the previous position.
^X^X Same as '.
- ESC-M_<_l_e_t_t_e_r_> Clear a mark.
+ ESC-m_<_l_e_t_t_e_r_> Clear a mark.
---------------------------------------------------
A mark is any upper-case or lower-case letter.
Certain marks are predefined:
@@ -161,8 +161,10 @@
Ignore the LESSOPEN environment variable.
-m -M .... --long-prompt --LONG-PROMPT
Set prompt style.
- -n -N .... --line-numbers --LINE-NUMBERS
- Don't use line numbers.
+ -n ......... --line-numbers
+ Suppress line numbers in prompts and messages.
+ -N ......... --LINE-NUMBERS
+ Display line number at start of each line.
-o [_f_i_l_e] . --log-file=[_f_i_l_e]
Copy to log file (standard input only).
-O [_f_i_l_e] . --LOG-FILE=[_f_i_l_e]
@@ -209,6 +211,8 @@
Automatically determine the size of the input file.
--follow-name
The F command changes files if the input file is renamed.
+ --header=[_N[,_M]]
+ Use N lines and M columns to display file headers.
--incsearch
Search file as each pattern character is typed in.
--line-num-width=N
@@ -219,12 +223,20 @@
Don't send termcap keypad init/deinit strings.
--no-histdups
Remove duplicates from command history.
+ --no-number-headers
+ Don't give line numbers to header lines.
+ --redraw-on-quit
+ Redraw final screen when quitting.
--rscroll=C
Set the character used to mark truncated lines.
--save-marks
Retain marks across invocations of less.
+ --search-options=[EFKNRW-]
+ Set default options for every search.
--status-col-width=N
Set the width of the -J status column to N characters.
+ --status-line
+ Highlight or color the entire line containing a mark.
--use-backslash
Subsequent options use backslash as escape char.
--use-color
diff --git a/contrib/less/less.nro b/contrib/less/less.nro
index 7c8372b500c6..b6dfa431ec84 100644
--- a/contrib/less/less.nro
+++ b/contrib/less/less.nro
@@ -1,5 +1,5 @@
'\" t
-.TH LESS 1 "Version 590: 03 Jun 2021"
+.TH LESS 1 "Version 608: 22 Jul 2022"
.SH NAME
less \- opposite of more
.SH SYNOPSIS
@@ -120,6 +120,10 @@ while it is being viewed.
(The behavior is similar to the "tail \-f" command.)
To stop waiting for more data, enter the interrupt character (usually ^C).
On some systems you can also use ^X.
+If the input is a pipe and the \-\-exit-follow-on-close option is in effect,
+.I less
+will automatically stop waiting for data when the input side
+of the pipe is closed.
.IP "ESC-F"
Like F, but as soon as a line is found which matches
the last search pattern, the terminal bell is rung
@@ -154,7 +158,7 @@ on the screen,
the } command will go to the matching left curly bracket.
The matching left curly bracket is positioned on the top
line of the screen.
-If there is more than one right curly bracket on the top line,
+If there is more than one right curly bracket on the bottom line,
a number N may be used to specify the N-th bracket on the line.
.IP "("
Like {, but applies to parentheses rather than curly brackets.
@@ -234,6 +238,7 @@ WRAP around the current file.
That is, if the search reaches the end of the current file
without finding a match, the search continues from the first line of the
current file up to the line where it started.
+If the ^W modifier is set, the ^E modifier is ignored.
.RE
.IP ?pattern
Search backward in the file for the N-th line containing the pattern.
@@ -581,6 +586,8 @@ Binary characters.
Control characters.
.IP "E"
Errors and informational messages.
+.IP "H"
+Header lines and columns, set via the \-\-header option.
.IP "M"
Mark letters in the status column.
.IP "N"
@@ -615,7 +622,7 @@ overstriking with backspaces (see the \-u option),
not to text using ANSI escape sequences with the \-R option.
.PP
A lowercase letter may be followed by a + to indicate that
-both the normal format change and the specified color should both be used.
+the normal format change and the specified color should both be used.
For example, \-Dug displays underlined text as green without underlining;
the green color has replaced the usual underline formatting.
But \-Du+g displays underlined text as both green and in underlined format.
@@ -656,7 +663,7 @@ Each integer is a value between 0 and 255 inclusive which selects
a "CSI 38;5" color value (see
.br
.nh
-https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters)
+https://en.wikipedia.org/wiki/ANSI_escape_code#SGR)
.hy
If either integer is a "-" or is omitted,
the corresponding color is set to that of normal text.
@@ -875,7 +882,7 @@ to that string.
\-PM changes the long (\-M) prompt.
\-Ph changes the prompt for the help screen.
\-P= changes the message printed by the = command.
- \-Pw changes the message printed while waiting for data (in the F command).
+ \-Pw changes the message printed while waiting for data (in the "F" command).
.sp 1
All prompt strings consist of a sequence of
letters and special escape sequences.
@@ -1011,7 +1018,10 @@ The first "new" line is the line immediately following the line previously
at the bottom of the screen.
Also highlights the target line after a g or p command.
The highlight is removed at the next command which causes movement.
-The entire line is highlighted, unless the \-J option is in effect,
+If the \-\-status-line option is in effect, the entire line
+(the width of the screen) is highlighted.
+Otherwise, only the text in the line is highlighted,
+unless the \-J option is in effect,
in which case only the status column is highlighted.
.IP "\-W or \-\-HILITE-UNREAD"
Like \-w, but temporarily highlights the first new line after any
@@ -1079,12 +1089,18 @@ If the number is specified as a fraction, the actual number of
scroll positions is recalculated if the terminal window is resized,
so that the actual scroll remains at the specified fraction
of the screen width.
+.IP "\-\-exit-follow-on-close"
+When using the "F" command on a pipe,
+.I less
+will automatically stop waiting for more data when the input side of the
+pipe is closed.
.IP "\-\-file-size"
If \-\-file-size is specified,
.I less
will determine the size of the file
immediately after opening the file.
-Normally this is not done, because it can be slow if the input file is large.
+Normally this is not done, because it can be slow if the input file
+is non-seekable (such as a pipe) and is large.
.IP "\-\-follow-name"
Normally, if the input file is renamed while an F command is executing,
.I less
@@ -1098,6 +1114,23 @@ If the reopen succeeds and the file is a different file from the original
with the same name as the original (now renamed) file),
.I less
will display the contents of that new file.
+.IP "\-\-header"
+Sets the number of header lines and columns displayed on the screen.
+The value may be of the form "N,M" where N and M are integers,
+to set the header lines to N and the header columns to M,
+or it may be a single integer "N" which sets the header lines to N
+and the header columns to zero.
+When N is nonzero, the first N lines at the top
+of the screen are replaced with the first N lines of the file,
+regardless of what part of the file are being viewed.
+When M is nonzero, the characters displayed at the
+beginning of each line are replaced with the first M characters of the line,
+even if the rest of the line is scrolled horizontally.
+If either N or M is zero,
+.I less
+stops displaying header lines or columns, respectively.
+(Note that it may be necessary to change the setting of the \-j option
+to ensure that the target line is not obscured by the header line(s).)
.IP "\-\-incsearch"
Subsequent search commands will be "incremental"; that is,
.I less
@@ -1131,26 +1164,52 @@ file name is typed in, and the same string is already in the history list,
the existing copy is removed from the history list before the new one is added.
Thus, a given string will appear only once in the history list.
Normally, a string may appear multiple times.
+.IP "\-\-no-number-headers"
+Header lines (defined via the \-\-header option) are not assigned line numbers.
+Line number 1 is assigned to the first line after any header lines.
.IP "\-\-rscroll"
This option changes the character used to mark truncated lines.
It may begin with a two-character attribute indicator like LESSBINFMT does.
If there is no attribute indicator, standout is used.
If set to "\-", truncated lines are not marked.
+.IP "\-\-redraw-on-quit"
+When quitting, after sending the terminal deinitialization string,
+redraws the entire last screen.
+On terminals whose terminal deinitialization string causes the
+terminal to switch from an alternate screen,
+this makes the last screenful of the current file remain visible after
+.I less
+has quit.
.IP "\-\-save-marks"
Save marks in the history file, so marks are retained
across different invocations of
.IR less .
+.IP "\-\-search-options"
+Sets default search modifiers.
+The value is a string of one or more of the characters
+E, F, K, N, R or W.
+Setting any of these has the same effect as typing that
+control character at the beginning of every search pattern.
+For example, setting \-\-search-options=W is the same as
+typing ^W at the beginning of every pattern.
+The value "-" disables all default search modifiers.
.IP "\-\-status-col-width"
Sets the width of the status column when the \-J option is in effect.
The default is 2 characters.
+.IP "\-\-status-line"
+If a line is marked, the entire line (rather than just the status column)
+is highlighted.
+Also lines highlighted due to the \-w option will have
+the entire line highlighted.
+If \-\-use-color is set, the line is colored rather than highlighted.
.IP "\-\-use-backslash"
This option changes the interpretations of options which follow this one.
After the \-\-use-backslash option, any backslash in an option string is
removed and the following character is taken literally.
This allows a dollar sign to be included in option strings.
.IP "\-\-use-color"
-Enables the colored text in various places.
-The -D option can be used to change the colors.
+Enables colored text in various places.
+The \-D option can be used to change the colors.
Colored text works only if the terminal supports
ANSI color escape sequences (as defined in ECMA-48 SGR;
see
@@ -1266,7 +1325,7 @@ Otherwise,
looks in a standard place for the lesskey source file:
On Unix systems,
.I less
-looks for a lesskey file called "$XDG_CONFIG_HOME/lesskey" or "$HOME/.lesskey".
+looks for a lesskey file called "$XDG_CONFIG_HOME/lesskey" or "$HOME/.config/lesskey" or "$HOME/.lesskey".
On MS-DOS and Windows systems,
.I less
looks for a lesskey file called "$HOME/_lesskey", and if it is not found there,
@@ -1445,11 +1504,11 @@ Note that a preprocessor cannot output an empty file, since that
is interpreted as meaning there is no replacement, and
the original file is used.
To avoid this, if LESSOPEN starts with two vertical bars,
-the exit status of the script becomes meaningful.
-If the exit status is zero, the output is considered to be
-replacement text, even if it is empty.
-If the exit status is nonzero, any output is ignored and the
-original file is used.
+the exit status of the script determines the behavior when the output is empty.
+If the output is empty and the exit status is zero,
+the empty output is considered to be replacement text.
+If the output is empty and the exit status is nonzero,
+the original file is used.
For compatibility with previous versions of
.IR less ,
if LESSOPEN starts with only one vertical bar, the exit status
@@ -1825,6 +1884,8 @@ use of tags files
metacharacters in filenames, such as *
.IP
filename completion (TAB, ^L)
+.IP
+history file
.RE
.PP
Less can also be compiled to be permanently in "secure" mode.
@@ -1925,10 +1986,10 @@ Name of the history file used to remember search commands and
shell commands between invocations of
.IR less .
If set to "\-" or "/dev/null", a history file is not used.
-The default is "$XDG_DATA_HOME/lesshst" or "$HOME/.lesshst" on Unix systems,
+The default is "$XDG_STATE_HOME/lesshst" or "$HOME/.local/state/lesshst" or
+"$XDG_DATA_HOME/lesshst" or "$HOME/.lesshst" on Unix systems,
"$HOME/_lesshst" on DOS and Windows systems,
-or "$HOME/lesshst.ini" or "$INIT/lesshst.ini"
-on OS/2 systems.
+or "$HOME/lesshst.ini" or "$INIT/lesshst.ini" on OS/2 systems.
.IP LESSHISTSIZE
The maximum number of commands to save in the history file.
The default is 100.
@@ -1996,7 +2057,7 @@ The name of the editor (used for the v command).
.BR lesskey (1)
.
.SH COPYRIGHT
-Copyright (C) 1984-2021 Mark Nudelman
+Copyright (C) 1984-2022 Mark Nudelman
.PP
less is part of the GNU project and is free software.
You can redistribute it and/or modify it
diff --git a/contrib/less/lessecho.c b/contrib/less/lessecho.c
index bfb0f729a8b8..5cd660db50ba 100644
--- a/contrib/less/lessecho.c
+++ b/contrib/less/lessecho.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -34,8 +34,9 @@ static char openquote = '"';
static char closequote = '"';
static char *meta_escape = "\\";
static char meta_escape_buf[2];
-static char metachars[64] = "";
+static char* metachars = NULL;
static int num_metachars = 0;
+static int size_metachars = 0;
static void
pr_usage(VOID_PARAM)
@@ -140,6 +141,35 @@ lstrtol(s, radix, pend)
return (n);
}
+ static void
+add_metachar(ch)
+ int ch;
+{
+ if (num_metachars+1 >= size_metachars)
+ {
+ char *p;
+ size_metachars = (size_metachars > 0) ? size_metachars*2 : 16;
+ p = (char *) malloc(size_metachars);
+ if (p == NULL)
+ pr_error("Cannot allocate memory");
+
+ if (metachars != NULL)
+ {
+ strcpy(p, metachars);
+ free(metachars);
+ }
+ metachars = p;
+ }
+ metachars[num_metachars++] = ch;
+ metachars[num_metachars] = '\0';
+}
+
+ static int
+is_metachar(ch)
+ int ch;
+{
+ return (metachars != NULL && strchr(metachars, ch) != NULL);
+}
#if !HAVE_STRCHR
char *
@@ -192,6 +222,7 @@ main(argc, argv)
break;
case 'f':
meta_escape_buf[0] = lstrtol(++arg, 0, &s);
+ meta_escape_buf[1] = '\0';
meta_escape = meta_escape_buf;
if (s == arg)
pr_error("Missing number after -f");
@@ -205,14 +236,12 @@ main(argc, argv)
pr_error("Missing number after -p");
break;
case 'm':
- metachars[num_metachars++] = *++arg;
- metachars[num_metachars] = '\0';
+ add_metachar(*++arg);
break;
case 'n':
- metachars[num_metachars++] = lstrtol(++arg, 0, &s);
+ add_metachar(lstrtol(++arg, 0, &s));
if (s == arg)
pr_error("Missing number after -n");
- metachars[num_metachars] = '\0';
break;
case '?':
pr_usage();
@@ -245,7 +274,7 @@ main(argc, argv)
arg = *argv++;
for (s = arg; *s != '\0'; s++)
{
- if (strchr(metachars, *s) != NULL)
+ if (is_metachar(*s))
{
has_meta = 1;
break;
@@ -257,7 +286,7 @@ main(argc, argv)
{
for (s = arg; *s != '\0'; s++)
{
- if (strchr(metachars, *s) != NULL)
+ if (is_metachar(*s))
printf("%s", meta_escape);
printf("%c", *s);
}
diff --git a/contrib/less/lessecho.nro b/contrib/less/lessecho.nro
index 4733a93edd68..5b16d4aa8530 100644
--- a/contrib/less/lessecho.nro
+++ b/contrib/less/lessecho.nro
@@ -1,4 +1,4 @@
-.TH LESSECHO 1 "Version 590: 03 Jun 2021"
+.TH LESSECHO 1 "Version 608: 22 Jul 2022"
.SH NAME
lessecho \- expand metacharacters
.SH SYNOPSIS
diff --git a/contrib/less/lesskey.c b/contrib/less/lesskey.c
index b5130cccb8f7..39ebe8b980a9 100644
--- a/contrib/less/lesskey.c
+++ b/contrib/less/lesskey.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -122,6 +122,14 @@ lesskey_parse_error(s)
fprintf(stderr, "%s\n", s);
}
+ int
+lstrtoi(buf, ebuf)
+ char *buf;
+ char **ebuf;
+{
+ return (int) strtol(buf, ebuf, 10);
+}
+
void *
ecalloc(count, size)
int count;
@@ -366,5 +374,6 @@ main(argc, argv)
/* File trailer */
fputbytes(out, endsection, sizeof(endsection));
fputbytes(out, filetrailer, sizeof(filetrailer));
+ fclose(out);
return (0);
}
diff --git a/contrib/less/lesskey.h b/contrib/less/lesskey.h
index 1e70a7fe09a5..988c6aa50e17 100644
--- a/contrib/less/lesskey.h
+++ b/contrib/less/lesskey.h
@@ -1,5 +1,5 @@
/*
- * 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.
diff --git a/contrib/less/lesskey.nro b/contrib/less/lesskey.nro
index 9b3ec1672f9c..0e8cb1bb96c3 100644
--- a/contrib/less/lesskey.nro
+++ b/contrib/less/lesskey.nro
@@ -1,7 +1,7 @@
'\" t
-.TH LESSKEY 1 "Version 590: 03 Jun 2021"
+.TH LESSKEY 1 "Version 608: 22 Jul 2022"
.SH NAME
-lesskey \- specify key bindings for less
+lesskey \- customize key bindings for less
.SH "SYNOPSIS (deprecated)"
.B "lesskey [\-o output] [\-\-] [input]"
.br
@@ -26,24 +26,30 @@ source file into a format understood by
.IR less .
This compilation step is no longer required and the
.I lesskey
-program is therefore deprecated although the file format remains supported by
+program is therefore deprecated, although the file format remains supported by
.I less
itself.
.PP
+.SH DESCRIPTION
+A
+.I lesskey
+file specifies a set of key bindings and environment variables
+to be used by subsequent invocations of
+.I less.
.SH FILE FORMAT
The input file consists of one or more
.I sections.
Each section starts with a line that identifies the type of section.
Possible sections are:
.IP #command
-Defines new command keys.
+Customizes command key bindings.
.IP #line-edit
-Defines new line-editing keys.
+Customizes line-editing key bindings.
.IP #env
Defines environment variables.
.PP
Blank lines and lines which start with a pound sign (#) are ignored,
-except for the special section header lines.
+except as noted below.
.
.SH "COMMAND SECTION"
The command section begins with the line
@@ -66,34 +72,38 @@ A backslash followed by one to three octal digits may be used to
specify a character by its octal value.
A backslash followed by certain characters specifies input
characters as follows:
-.IP \eb
-BACKSPACE
-.IP \ee
-ESCAPE
-.IP \en
-NEWLINE
-.IP \er
-RETURN
-.IP \et
-TAB
-.IP \eku
-UP ARROW
-.IP \ekd
-DOWN ARROW
-.IP \ekr
-RIGHT ARROW
-.IP \ekl
-LEFT ARROW
-.IP \ekU
-PAGE UP
-.IP \ekD
-PAGE DOWN
-.IP \ekh
-HOME
-.IP \eke
-END
-.IP \ekx
-DELETE
+.RS 5m
+.TS
+l l l.
+\eb BACKSPACE (0x08)
+\ee ESCAPE (0x1B)
+\en NEWLINE (0x0A)
+\er RETURN (0x0D)
+\et TAB (0x09)
+.TE
+.sp
+\ek followed by a single character represents the char(s) produced when one of these keys is pressed:
+.TS
+l l.
+\ekb BACKSPACE (the BACKSPACE key)
+\ekB ctrl-BACKSPACE
+\ekd DOWN ARROW
+\ekD PAGE DOWN
+\eke END
+\ekh HOME
+\eki INSERT
+\ekl LEFT ARROW
+\ekL ctrl-LEFT ARROW
+\ekr RIGHT ARROW
+\ekR ctrl-RIGHT ARROW
+\ekt BACKTAB
+\eku UP ARROW
+\ekU PAGE UP
+\ekx DELETE
+\ekX ctrl-DELETE
+\ek1 F1
+.TE
+
.PP
A backslash followed by any other character indicates that character is
to be taken literally.
@@ -116,7 +126,11 @@ quits, the first character of the extra string is used as its exit status.
.
.SH EXAMPLE
The following input file describes the set of
-default command keys used by less:
+default command keys used by
+.IR less .
+Documentation on each command can be found in the
+.less
+man page, under the key sequence which invokes the command.
.sp
.RS 5m
.TS
@@ -217,6 +231,8 @@ T prev-tag
- toggle-option
:t toggle-option t
s toggle-option o
+ ## Use a long option name by starting the extra string with ONE dash; eg:
+ ## s toggle-option -log-file\n
\&_ display-option
| pipe
v visual
@@ -282,7 +298,8 @@ one per line as in the example below.
.
.SH EXAMPLE
The following input file describes the set of
-default line-editing keys used by less:
+default line-editing keys used by
+.IR less :
.sp
.RS 5m
.TS
@@ -333,23 +350,67 @@ Variables assigned in this way are visible only to
.IR less .
If a variable is specified in the system environment and also in a
lesskey file, the value in the lesskey file takes precedence.
-Although the lesskey file can be used to override variables set in the
-environment, the main purpose of assigning variables in the lesskey file
-is simply to have all
+.
+.sp
+If the variable name is followed by += rather than =,
+the string is appended to the variable's existing value.
+This currently works only if any += lines immediately follow
+the same variable's original definition (with an = line),
+without any intervening definitions of other variables.
+It can append only to a variable defined earlier in the file;
+it cannot append to a variable in the system environment.
+.
+.SH CONDITIONAL CONFIGURATION
+If a line begins with #version followed by a relational operator and a version number,
+the remainder of the line is parsed if and only if the running version of
+.I less
+(or
+.IR lesskey )
+matches the operator.
+This can be helpful if a lesskey file is used by different versions of
+.IR less .
+.sp
+For example, suppose that a new command named 'sideways-search' is added in
.I less
-configuration information stored in one file.
+version 777.
+Then the following line would assign the command to the Q key, but only in versions of
+.I less
+which support it. The line would be ignored by versions earlier than 777.
+.sp
+.nf
+ #version >= 777 Q sideways-search
+.fi
+.sp
+These six operators are supported:
+.RS 5m
+.TS
+l l.
+ > Greater than
+ < Less than
+ >= Greater than or equal to
+ <= Less than or equal to
+ = Equal to
+ != Not equal to
+.TE
+.RE
+.sp
+The #version feature is not supported in
+.I less
+and
+.I lesskey
+before version 594.
+In those older versions, all #version lines are ignored.
.
.SH EXAMPLE
-The following input file sets the \-i option whenever
-.I less
-is run, and specifies the character set to be "latin1":
+The following input file sets the \-i and \-S options when
+.less
+is run and, on version 595 and higher, adds a \-\-color option.
.sp
.nf
#env
- LESS = \-i
- LESSCHARSET = latin1
+ LESS = \-i\ \-S
+ #version\ >=\ 595\ \ LESS\ +=\ \-\-color=Hkc
.fi
-.sp
.
.SH "SEE ALSO"
.BR less (1)
@@ -360,7 +421,7 @@ which start with a NUL character (0).
This NUL character should be represented as \e340 in a lesskey file.
.
.SH COPYRIGHT
-Copyright (C) 1984-2021 Mark Nudelman
+Copyright (C) 1984-2022 Mark Nudelman
.PP
less is part of the GNU project and is free software.
You can redistribute it and/or modify it
diff --git a/contrib/less/lesskey_parse.c b/contrib/less/lesskey_parse.c
index 18cdf3753d53..7042b6e12708 100644
--- a/contrib/less/lesskey_parse.c
+++ b/contrib/less/lesskey_parse.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -21,9 +21,12 @@
extern void lesskey_parse_error(char *msg);
extern char *homefile(char *filename);
extern void *ecalloc(int count, unsigned int size);
+extern int lstrtoi(char *str, char **end);
+extern char version[];
static int linenum;
static int errors;
+static int less_version = 0;
static char *lesskey_file;
static struct lesskey_cmdname cmdnames[] =
@@ -124,13 +127,15 @@ static struct lesskey_cmdname editnames[] =
* Print a parse error message.
*/
static void
-parse_error(s1, s2)
- char *s1;
- char *s2;
+parse_error(fmt, arg1)
+ char *fmt;
+ char *arg1;
{
char buf[1024];
+ int n = snprintf(buf, sizeof(buf), "%s: line %d: ", lesskey_file, linenum);
+ if (n >= 0 && n < sizeof(buf))
+ snprintf(buf+n, sizeof(buf)-n, fmt, arg1);
++errors;
- snprintf(buf, sizeof(buf), "%s: line %d: %s%s", lesskey_file, linenum, s1, s2);
lesskey_parse_error(buf);
}
@@ -156,6 +161,37 @@ init_tables(tables)
xbuf_init(&tables->vartable.buf);
}
+#define CHAR_STRING_LEN 8
+
+ static char *
+char_string(buf, ch, lit)
+ char *buf;
+ int ch;
+ int lit;
+{
+ if (lit || (ch >= 0x20 && ch < 0x7f))
+ {
+ buf[0] = ch;
+ buf[1] = '\0';
+ } else
+ {
+ snprintf(buf, CHAR_STRING_LEN, "\\x%02x", ch);
+ }
+ return buf;
+}
+
+/*
+ * Increment char pointer by one up to terminating nul byte.
+ */
+ static char *
+increment_pointer(p)
+ char *p;
+{
+ if (*p == '\0')
+ return p;
+ return p+1;
+}
+
/*
* Parse one character of a string.
*/
@@ -167,7 +203,7 @@ tstr(pp, xlate)
char *p;
char ch;
int i;
- static char buf[10];
+ static char buf[CHAR_STRING_LEN];
static char tstr_control_k[] =
{ SK_SPECIAL_KEY, SK_CONTROL_K, 6, 1, 1, 1, '\0' };
@@ -191,17 +227,13 @@ tstr(pp, xlate)
*pp = p;
if (xlate && ch == CONTROL('K'))
return tstr_control_k;
- buf[0] = ch;
- buf[1] = '\0';
- return (buf);
+ return char_string(buf, ch, 1);
case 'b':
*pp = p+1;
return ("\b");
case 'e':
*pp = p+1;
- buf[0] = ESC;
- buf[1] = '\0';
- return (buf);
+ return char_string(buf, ESC, 1);
case 'n':
*pp = p+1;
return ("\n");
@@ -216,19 +248,27 @@ tstr(pp, xlate)
{
switch (*++p)
{
- case 'u': ch = SK_UP_ARROW; break;
+ case 'b': ch = SK_BACKSPACE; break;
+ case 'B': ch = SK_CTL_BACKSPACE; break;
case 'd': ch = SK_DOWN_ARROW; break;
- case 'r': ch = SK_RIGHT_ARROW; break;
- case 'l': ch = SK_LEFT_ARROW; break;
- case 'U': ch = SK_PAGE_UP; break;
case 'D': ch = SK_PAGE_DOWN; break;
- case 'h': ch = SK_HOME; break;
case 'e': ch = SK_END; break;
+ case 'h': ch = SK_HOME; break;
+ case 'i': ch = SK_INSERT; break;
+ case 'l': ch = SK_LEFT_ARROW; break;
+ case 'L': ch = SK_CTL_LEFT_ARROW; break;
+ case 'r': ch = SK_RIGHT_ARROW; break;
+ case 'R': ch = SK_CTL_RIGHT_ARROW; break;
+ case 't': ch = SK_BACKTAB; break;
+ case 'u': ch = SK_UP_ARROW; break;
+ case 'U': ch = SK_PAGE_UP; break;
case 'x': ch = SK_DELETE; break;
- default: { char buf[2]; buf[0] = *p; buf[1] = '\0';
- parse_error("illegal escape sequence \\k", buf);
- *pp = p+1;
- return (""); }
+ case 'X': ch = SK_CTL_DELETE; break;
+ case '1': ch = SK_F1; break;
+ default:
+ parse_error("invalid escape sequence \"\\k%s\"", char_string(buf, *p, 0));
+ *pp = increment_pointer(p);
+ return ("");
}
*pp = p+1;
buf[0] = SK_SPECIAL_KEY;
@@ -246,9 +286,8 @@ tstr(pp, xlate)
* Backslash followed by any other char
* just means that char.
*/
- *pp = p+1;
- buf[0] = *p;
- buf[1] = '\0';
+ *pp = increment_pointer(p);
+ char_string(buf, *p, 1);
if (xlate && buf[0] == CONTROL('K'))
return tstr_control_k;
return (buf);
@@ -257,16 +296,14 @@ tstr(pp, xlate)
/*
* Caret means CONTROL.
*/
- *pp = p+2;
- buf[0] = CONTROL(p[1]);
- buf[1] = '\0';
+ *pp = increment_pointer(p+1);
+ char_string(buf, CONTROL(p[1]), 1);
if (xlate && buf[0] == CONTROL('K'))
return tstr_control_k;
return (buf);
}
- *pp = p+1;
- buf[0] = *p;
- buf[1] = '\0';
+ *pp = increment_pointer(p);
+ char_string(buf, *p, 1);
if (xlate && buf[0] == CONTROL('K'))
return tstr_control_k;
return (buf);
@@ -332,6 +369,13 @@ add_cmd_char(c, tables)
xbuf_add(&tables->currtable->buf, c);
}
+ static void
+erase_cmd_char(tables)
+ struct lesskey_tables *tables;
+{
+ xbuf_pop(&tables->currtable->buf);
+}
+
/*
* Add a string to the output command table.
*/
@@ -345,9 +389,71 @@ add_cmd_str(s, tables)
}
/*
- * See if we have a special "control" line.
+ * Does a given version number match the running version?
+ * Operator compares the running version to the given version.
*/
static int
+match_version(op, ver)
+ char op;
+ int ver;
+{
+ switch (op)
+ {
+ case '>': return less_version > ver;
+ case '<': return less_version < ver;
+ case '+': return less_version >= ver;
+ case '-': return less_version <= ver;
+ case '=': return less_version == ver;
+ case '!': return less_version != ver;
+ default: return 0; /* cannot happen */
+ }
+}
+
+/*
+ * Handle a #version line.
+ * If the version matches, return the part of the line that should be executed.
+ * Otherwise, return NULL.
+ */
+ static char *
+version_line(s, tables)
+ char *s;
+ struct lesskey_tables *tables;
+{
+ char op;
+ int ver;
+ char *e;
+ char buf[CHAR_STRING_LEN];
+
+ s += strlen("#version");
+ s = skipsp(s);
+ op = *s++;
+ /* Simplify 2-char op to one char. */
+ switch (op)
+ {
+ case '<': if (*s == '=') { s++; op = '-'; } break;
+ case '>': if (*s == '=') { s++; op = '+'; } break;
+ case '=': if (*s == '=') { s++; } break;
+ case '!': if (*s == '=') { s++; } break;
+ default:
+ parse_error("invalid operator '%s' in #version line", char_string(buf, op, 0));
+ return (NULL);
+ }
+ s = skipsp(s);
+ ver = lstrtoi(s, &e);
+ if (e == s)
+ {
+ parse_error("non-numeric version number in #version line", "");
+ return (NULL);
+ }
+ if (!match_version(op, ver))
+ return (NULL);
+ return (e);
+}
+
+/*
+ * See if we have a special "control" line.
+ */
+ static char *
control_line(s, tables)
char *s;
struct lesskey_tables *tables;
@@ -357,25 +463,29 @@ control_line(s, tables)
if (PREFIX(s, "#line-edit"))
{
tables->currtable = &tables->edittable;
- return (1);
+ return (NULL);
}
if (PREFIX(s, "#command"))
{
tables->currtable = &tables->cmdtable;
- return (1);
+ return (NULL);
}
if (PREFIX(s, "#env"))
{
tables->currtable = &tables->vartable;
- return (1);
+ return (NULL);
}
if (PREFIX(s, "#stop"))
{
add_cmd_char('\0', tables);
add_cmd_char(A_END_LIST, tables);
- return (1);
+ return (NULL);
}
- return (0);
+ if (PREFIX(s, "#version"))
+ {
+ return (version_line(s, tables));
+ }
+ return (s);
}
/*
@@ -391,7 +501,7 @@ findaction(actname, tables)
for (i = 0; tables->currtable->names[i].cn_name != NULL; i++)
if (strcmp(tables->currtable->names[i].cn_name, actname) == 0)
return (tables->currtable->names[i].cn_action);
- parse_error("unknown action: ", actname);
+ parse_error("unknown action: \"%s\"", actname);
return (A_INVALID);
}
@@ -478,26 +588,37 @@ parse_varline(line, tables)
{
char *s;
char *p = line;
+ char *eq;
- do
+ eq = strchr(line, '=');
+ if (eq != NULL && eq > line && eq[-1] == '+')
{
- s = tstr(&p, 0);
- add_cmd_str(s, tables);
- } while (*p != '\0' && !issp(*p) && *p != '=');
- /*
- * Terminate the variable name with a null byte.
- */
- add_cmd_char('\0', tables);
-
- p = skipsp(p);
- if (*p++ != '=')
+ /*
+ * Rather ugly way of handling a += line.
+ * {{ Note that we ignore the variable name and
+ * just append to the previously defined variable. }}
+ */
+ erase_cmd_char(tables); /* backspace over the final null */
+ p = eq+1;
+ } else
{
- parse_error("missing = in: ", line);
- return;
+ do
+ {
+ s = tstr(&p, 0);
+ add_cmd_str(s, tables);
+ } while (*p != '\0' && !issp(*p) && *p != '=');
+ /*
+ * Terminate the variable name with a null byte.
+ */
+ add_cmd_char('\0', tables);
+ p = skipsp(p);
+ if (*p++ != '=')
+ {
+ parse_error("missing = in variable definition", "");
+ return;
+ }
+ add_cmd_char(EV_OK|A_EXTRA, tables);
}
-
- add_cmd_char(EV_OK|A_EXTRA, tables);
-
p = skipsp(p);
while (*p != '\0')
{
@@ -520,14 +641,15 @@ parse_line(line, tables)
/*
* See if it is a control line.
*/
- if (control_line(line, tables))
+ p = control_line(line, tables);
+ if (p == NULL)
return;
/*
* Skip leading white space.
* Replace the final newline with a null byte.
* Ignore blank lines and comments.
*/
- p = clean_line(line);
+ p = clean_line(p);
if (*p == '\0')
return;
@@ -555,6 +677,8 @@ parse_lesskey(infile, tables)
init_tables(tables);
errors = 0;
linenum = 0;
+ if (less_version == 0)
+ less_version = lstrtoi(version, NULL);
/*
* Open the input file.
@@ -563,7 +687,7 @@ parse_lesskey(infile, tables)
desc = stdin;
else if ((desc = fopen(infile, "r")) == NULL)
{
- /* parse_error("cannot open lesskey file ", infile); */
+ /* parse_error("cannot open lesskey file %s", infile); */
return (-1);
}
@@ -575,6 +699,6 @@ parse_lesskey(infile, tables)
++linenum;
parse_line(line, tables);
}
-
+ fclose(desc);
return (errors);
}
diff --git a/contrib/less/lglob.h b/contrib/less/lglob.h
index 2e5e74ec1900..794488a047e1 100644
--- a/contrib/less/lglob.h
+++ b/contrib/less/lglob.h
@@ -1,5 +1,5 @@
/*
- * 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.
diff --git a/contrib/less/line.c b/contrib/less/line.c
index b8f609e9d4df..2f1b3fb9d2b2 100644
--- a/contrib/less/line.c
+++ b/contrib/less/line.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -33,11 +33,28 @@ static struct {
int pfx_end; /* Number of chars in pfx */
} linebuf;
+/*
+ * Buffer of ansi sequences which have been shifted off the left edge
+ * of the screen.
+ */
struct xbuffer shifted_ansi;
-struct xbuffer last_ansi;
+
+/*
+ * Ring buffer of last ansi sequences sent.
+ * While sending a line, these will be resent at the end
+ * of any highlighted string, to restore text modes.
+ * {{ Not ideal, since we don't really know how many to resend. }}
+ */
+#define NUM_LAST_ANSIS 3
+static struct xbuffer last_ansi;
+static struct xbuffer last_ansis[NUM_LAST_ANSIS];
+static int curr_last_ansi;
public int size_linebuf = 0; /* Size of line buffer (and attr buffer) */
static struct ansi_state *line_ansi = NULL;
+static int ansi_in_line;
+static int hlink_in_line;
+static int line_mark_attr;
static int cshift; /* Current left-shift of output line buffer */
public int hshift; /* Desired left-shift of output line buffer */
public int tabstops[TABSTOP_MAX] = { 0 }; /* Custom tabstops */
@@ -82,6 +99,7 @@ extern POSITION end_attnpos;
extern char rscroll_char;
extern int rscroll_attr;
extern int use_color;
+extern int status_line;
static char mbc_buf[MAX_UTF_CHAR_LEN];
static int mbc_buf_len = 0;
@@ -99,6 +117,7 @@ static char color_map[AT_NUM_COLORS][12] = {
"kC", /* AT_COLOR_PROMPT */
"kc", /* AT_COLOR_RSCROLL */
"kG", /* AT_COLOR_SEARCH */
+ "", /* AT_COLOR_HEADER */
"", /* AT_UNDERLINE */
"", /* AT_BOLD */
"", /* AT_BLINK */
@@ -118,6 +137,8 @@ struct ansi_state {
public void
init_line(VOID_PARAM)
{
+ int ax;
+
end_ansi_chars = lgetenv("LESSANSIENDCHARS");
if (isnullenv(end_ansi_chars))
end_ansi_chars = "m";
@@ -131,6 +152,9 @@ init_line(VOID_PARAM)
size_linebuf = LINEBUF_SIZE;
xbuf_init(&shifted_ansi);
xbuf_init(&last_ansi);
+ for (ax = 0; ax < NUM_LAST_ANSIS; ax++)
+ xbuf_init(&last_ansis[ax]);
+ curr_last_ansi = 0;
}
/*
@@ -141,15 +165,8 @@ expand_linebuf(VOID_PARAM)
{
/* Double the size of the line buffer. */
int new_size = size_linebuf * 2;
-
- /* Just realloc to expand the buffer, if we can. */
-#if HAVE_REALLOC
- char *new_buf = (char *) realloc(linebuf.buf, new_size);
- int *new_attr = (int *) realloc(linebuf.attr, new_size*sizeof(int));
-#else
char *new_buf = (char *) calloc(new_size, sizeof(char));
int *new_attr = (int *) calloc(new_size, sizeof(int));
-#endif
if (new_buf == NULL || new_attr == NULL)
{
if (new_attr != NULL)
@@ -158,7 +175,6 @@ expand_linebuf(VOID_PARAM)
free(new_buf);
return 1;
}
-#if !HAVE_REALLOC
/*
* We just calloc'd the buffers; copy the old contents.
*/
@@ -166,7 +182,6 @@ expand_linebuf(VOID_PARAM)
memcpy(new_attr, linebuf.attr, size_linebuf * sizeof(int));
free(linebuf.attr);
free(linebuf.buf);
-#endif
linebuf.buf = new_buf;
linebuf.attr = new_attr;
size_linebuf = new_size;
@@ -203,6 +218,8 @@ inc_end_column(w)
public void
prewind(VOID_PARAM)
{
+ int ax;
+
linebuf.print = 6; /* big enough for longest UTF-8 sequence */
linebuf.pfx_end = 0;
for (linebuf.end = 0; linebuf.end < linebuf.print; linebuf.end++)
@@ -221,8 +238,14 @@ prewind(VOID_PARAM)
is_null_line = 0;
pendc = '\0';
in_hilite = 0;
+ ansi_in_line = 0;
+ hlink_in_line = 0;
+ line_mark_attr = 0;
xbuf_reset(&shifted_ansi);
xbuf_reset(&last_ansi);
+ for (ax = 0; ax < NUM_LAST_ANSIS; ax++)
+ xbuf_reset(&last_ansis[ax]);
+ curr_last_ansi = 0;
}
/*
@@ -252,6 +275,19 @@ add_linebuf(ch, attr, w)
}
/*
+ * Append a string to the line buffer.
+ */
+ static void
+addstr_linebuf(s, attr, cw)
+ char *s;
+ int attr;
+ int cw;
+{
+ for ( ; *s != '\0'; s++)
+ add_linebuf(*s, attr, cw);
+}
+
+/*
* Set a character in the line prefix buffer.
*/
static void
@@ -301,22 +337,20 @@ plinestart(pos)
/*
* Display a status column if the -J option is set.
*/
- if (status_col)
+ if (status_col || status_line)
{
- int a = AT_NORMAL;
char c = posmark(pos);
if (c != 0)
- a |= AT_HILITE|AT_COLOR_MARK;
- else
+ line_mark_attr = AT_HILITE|AT_COLOR_MARK;
+ else if (start_attnpos != NULL_POSITION &&
+ pos >= start_attnpos && pos <= end_attnpos)
+ line_mark_attr = AT_HILITE|AT_COLOR_ATTN;
+ if (status_col)
{
- c = ' ';
- if (start_attnpos != NULL_POSITION &&
- pos >= start_attnpos && pos <= end_attnpos)
- a |= AT_HILITE|AT_COLOR_ATTN;
+ add_pfx(c ? c : ' ', line_mark_attr); /* column 0: status */
+ while (linebuf.pfx_end < status_col_width)
+ add_pfx(' ', AT_NORMAL);
}
- add_pfx(c, a); /* column 0: status */
- while (linebuf.pfx_end < status_col_width)
- add_pfx(' ', AT_NORMAL);
}
/*
@@ -328,12 +362,18 @@ plinestart(pos)
char buf[INT_STRLEN_BOUND(linenum) + 2];
int len;
- linenumtoa(linenum, buf);
- len = (int) strlen(buf);
+ linenum = vlinenum(linenum);
+ if (linenum == 0)
+ len = 0;
+ else
+ {
+ linenumtoa(linenum, buf);
+ len = (int) strlen(buf);
+ }
for (i = 0; i < linenum_width - len; i++)
add_pfx(' ', AT_NORMAL);
for (i = 0; i < len; i++)
- add_pfx(buf[i], AT_NORMAL|AT_COLOR_LINENUM);
+ add_pfx(buf[i], AT_BOLD|AT_COLOR_LINENUM);
add_pfx(' ', AT_NORMAL);
}
end_column = linebuf.pfx_end;
@@ -630,6 +670,20 @@ ansi_done(pansi)
}
/*
+ * Will w characters in attribute a fit on the screen?
+ */
+ static int
+fits_on_screen(w, a)
+ int w;
+ int a;
+{
+ if (ctldisp == OPT_ON)
+ /* We're not counting, so say that everything fits. */
+ return 1;
+ return (end_column - cshift + w + attr_ewidth(a) <= sc_width);
+}
+
+/*
* Append a character and attribute to the line buffer.
*/
#define STORE_CHAR(ch,a,rep,pos) \
@@ -657,7 +711,18 @@ store_char(ch, a, rep, pos)
{
int matches;
int resend_last = 0;
- int hl_attr = is_hilited_attr(pos, pos+1, 0, &matches);
+ int hl_attr;
+
+ if (pos == NULL_POSITION)
+ {
+ /* Color the prompt unless it has ansi sequences in it. */
+ hl_attr = ansi_in_line ? 0 : AT_STANDOUT|AT_COLOR_PROMPT;
+ } else
+ {
+ hl_attr = is_hilited_attr(pos, pos+1, 0, &matches);
+ if (hl_attr == 0 && status_line)
+ hl_attr = line_mark_attr;
+ }
if (hl_attr)
{
/*
@@ -666,7 +731,7 @@ store_char(ch, a, rep, pos)
*/
if (a != AT_ANSI)
{
- if (highest_hilite != NULL_POSITION && pos > highest_hilite)
+ if (highest_hilite != NULL_POSITION && pos != NULL_POSITION && pos > highest_hilite)
highest_hilite = pos;
a |= hl_attr;
}
@@ -685,8 +750,13 @@ store_char(ch, a, rep, pos)
}
if (resend_last)
{
- for (i = 0; i < last_ansi.end; i++)
- STORE_CHAR(last_ansi.data[i], AT_ANSI, NULL, pos);
+ int ai;
+ for (ai = 0; ai < NUM_LAST_ANSIS; ai++)
+ {
+ int ax = (curr_last_ansi + ai) % NUM_LAST_ANSIS;
+ for (i = 0; i < last_ansis[ax].end; i++)
+ STORE_CHAR(last_ansis[ax].data[i], AT_ANSI, NULL, pos);
+ }
}
}
#endif
@@ -700,10 +770,7 @@ store_char(ch, a, rep, pos)
w = pwidth(ch, a, prev_ch, prev_a);
}
- if (ctldisp != OPT_ON && end_column - cshift + w + attr_ewidth(a) > sc_width)
- /*
- * Won't fit on screen.
- */
+ if (!fits_on_screen(w, a))
return (1);
if (rep == NULL)
@@ -768,6 +835,22 @@ store_char(ch, a, rep, pos)
return (0);
}
+#define STORE_STRING(s,a,pos) \
+ do { if (store_string((s),(a),(pos))) return (1); } while (0)
+
+ static int
+store_string(s, a, pos)
+ char *s;
+ int a;
+ POSITION pos;
+{
+ if (!fits_on_screen(strlen(s), a))
+ return 1;
+ for ( ; *s != 0; s++)
+ STORE_CHAR(*s, a, NULL, pos);
+ return 0;
+}
+
/*
* Append a tab to the line buffer.
* Store spaces to represent the tab.
@@ -808,14 +891,10 @@ store_prchar(c, pos)
LWCHAR c;
POSITION pos;
{
- char *s;
-
/*
* Convert to printable representation.
*/
- s = prchar(c);
- for ( ; *s != 0; s++)
- STORE_CHAR(*s, AT_BINARY|AT_COLOR_CTRL, NULL, pos);
+ STORE_STRING(prchar(c), AT_BINARY|AT_COLOR_CTRL, pos);
return 0;
}
@@ -956,28 +1035,36 @@ store_ansi(ch, rep, pos)
switch (ansi_step(line_ansi, ch))
{
case ANSI_MID:
- if (!in_hilite)
- STORE_CHAR(ch, AT_ANSI, rep, pos);
+ STORE_CHAR(ch, AT_ANSI, rep, pos);
+ if (line_ansi->hlink)
+ hlink_in_line = 1;
+ xbuf_add(&last_ansi, ch);
break;
case ANSI_END:
- if (!in_hilite)
- STORE_CHAR(ch, AT_ANSI, rep, pos);
+ STORE_CHAR(ch, AT_ANSI, rep, pos);
ansi_done(line_ansi);
line_ansi = NULL;
+ xbuf_add(&last_ansi, ch);
+ xbuf_set(&last_ansis[curr_last_ansi], &last_ansi);
+ xbuf_reset(&last_ansi);
+ curr_last_ansi = (curr_last_ansi + 1) % NUM_LAST_ANSIS;
break;
- case ANSI_ERR: {
- /* Remove whole unrecognized sequence. */
- char *start = (cshift < hshift) ? shifted_ansi.data : linebuf.buf;
- int *end = (cshift < hshift) ? &shifted_ansi.end : &linebuf.end;
- char *p = start + *end;
- LWCHAR bch;
- do {
- bch = step_char(&p, -1, start);
- } while (p > start && !IS_CSI_START(bch));
- *end = (int) (p - start);
+ case ANSI_ERR:
+ {
+ /* Remove whole unrecognized sequence. */
+ char *start = (cshift < hshift) ? shifted_ansi.data : linebuf.buf;
+ int *end = (cshift < hshift) ? &shifted_ansi.end : &linebuf.end;
+ char *p = start + *end;
+ LWCHAR bch;
+ do {
+ bch = step_char(&p, -1, start);
+ } while (p > start && !IS_CSI_START(bch));
+ *end = (int) (p - start);
+ }
+ xbuf_reset(&last_ansi);
ansi_done(line_ansi);
line_ansi = NULL;
- break; }
+ break;
}
return (0);
}
@@ -1013,14 +1100,11 @@ do_append(ch, rep, pos)
{
line_ansi = ansi_start(ch);
if (line_ansi != NULL)
- xbuf_reset(&last_ansi);
+ ansi_in_line = 1;
}
if (line_ansi != NULL)
- {
- xbuf_add(&last_ansi, ch);
return store_ansi(ch, rep, pos);
- }
if (ch == '\b')
return store_bs(ch, rep, pos);
@@ -1105,9 +1189,7 @@ do_append(ch, rep, pos)
return store_control_char(ch, rep, pos);
} else if (utf_mode && ctldisp != OPT_ON && is_ubin_char(ch))
{
- char *s = prutfchar(ch);
- for ( ; *s != 0; s++)
- STORE_CHAR(*s, AT_BINARY, NULL, pos);
+ STORE_STRING(prutfchar(ch), AT_BINARY, pos);
} else
{
STORE_CHAR(ch, a, rep, pos);
@@ -1138,12 +1220,11 @@ pflushmbc(VOID_PARAM)
static void
add_attr_normal(VOID_PARAM)
{
- char *p = "\033[m";
-
if (ctldisp != OPT_ONPLUS || !is_ansi_end('m'))
return;
- for ( ; *p != '\0'; p++)
- add_linebuf(*p, AT_ANSI, 0);
+ addstr_linebuf("\033[m", AT_ANSI, 0);
+ if (hlink_in_line) /* Don't send hyperlink clear if we know we don't need to. */
+ addstr_linebuf("\033]8;;\033\\", AT_ANSI, 0);
}
/*
@@ -1196,6 +1277,14 @@ pdone(endline, chopped, forw)
}
/*
+ * If we're coloring a status line, fill out the line with spaces.
+ */
+ if (status_line && line_mark_attr != 0) {
+ while (end_column +1 < sc_width + cshift)
+ add_linebuf(' ', line_mark_attr, 1);
+ }
+
+ /*
* Add a newline if necessary,
* and append a '\0' to the end of the line.
* We output a newline if we're not at the right edge of the screen,
@@ -1235,7 +1324,20 @@ pdone(endline, chopped, forw)
}
/*
- *
+ * Set an attribute on each char of the line in the line buffer.
+ */
+ public void
+set_attr_line(a)
+ int a;
+{
+ int i;
+
+ for (i = linebuf.print; i < linebuf.end; i++)
+ linebuf.attr[i] |= a;
+}
+
+/*
+ * Set the char to be displayed in the status column.
*/
public void
set_status_col(c, attr)
@@ -1420,6 +1522,50 @@ back_raw_line(curr_pos, linep, line_lenp)
}
/*
+ * Append a string to the line buffer.
+ */
+ static int
+pappstr(str)
+ constant char *str;
+{
+ while (*str != '\0')
+ {
+ if (pappend(*str++, NULL_POSITION))
+ /* Doesn't fit on screen. */
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Load a string into the line buffer.
+ * If the string is too long to fit on the screen,
+ * truncate the beginning of the string to fit.
+ */
+ public void
+load_line(str)
+ constant char *str;
+{
+ int save_hshift = hshift;
+
+ hshift = 0;
+ for (;;)
+ {
+ prewind();
+ if (pappstr(str) == 0)
+ break;
+ /*
+ * Didn't fit on screen; increase left shift by one.
+ * {{ This gets very inefficient if the string
+ * is much longer than the screen width. }}
+ */
+ hshift += 1;
+ }
+ set_linebuf(linebuf.end, '\0', AT_NORMAL);
+ hshift = save_hshift;
+}
+
+/*
* Find the shift necessary to show the end of the longest displayed line.
*/
public int
@@ -1465,16 +1611,17 @@ color_index(attr)
case AT_COLOR_PROMPT: return 6;
case AT_COLOR_RSCROLL: return 7;
case AT_COLOR_SEARCH: return 8;
+ case AT_COLOR_HEADER: return 9;
}
}
if (attr & AT_UNDERLINE)
- return 9;
- if (attr & AT_BOLD)
return 10;
- if (attr & AT_BLINK)
+ if (attr & AT_BOLD)
return 11;
- if (attr & AT_STANDOUT)
+ if (attr & AT_BLINK)
return 12;
+ if (attr & AT_STANDOUT)
+ return 13;
return -1;
}
diff --git a/contrib/less/linenum.c b/contrib/less/linenum.c
index a3e1b2fcb52d..1808ea97851e 100644
--- a/contrib/less/linenum.c
+++ b/contrib/less/linenum.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -68,6 +68,8 @@ extern int linenums;
extern int sigs;
extern int sc_height;
extern int screen_trashed;
+extern int header_lines;
+extern int nonum_headers;
/*
* Initialize the line number structures.
@@ -484,11 +486,24 @@ scan_eof(VOID_PARAM)
ierror("Determining length of file", NULL_PARG);
while (pos != NULL_POSITION)
{
- /* For efficiency, only add one every 256 line numbers. */
- if ((linenum++ % 256) == 0)
- add_lnum(linenum, pos);
+ /* For efficiency, only add one every 256 line numbers. */
+ if ((linenum++ % 256) == 0)
+ add_lnum(linenum, pos);
pos = forw_raw_line(pos, (char **)NULL, (int *)NULL);
if (ABORT_SIGS())
break;
}
}
+
+/*
+ * Return a line number adjusted for display
+ * (handles the --no-number-headers option).
+ */
+ public LINENUM
+vlinenum(linenum)
+ LINENUM linenum;
+{
+ if (nonum_headers)
+ linenum = (linenum < header_lines) ? 0 : linenum - header_lines;
+ return linenum;
+}
diff --git a/contrib/less/lsystem.c b/contrib/less/lsystem.c
index 5c67526e1030..d817369e42d0 100644
--- a/contrib/less/lsystem.c
+++ b/contrib/less/lsystem.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -117,12 +117,7 @@ lsystem(cmd, donemsg)
inp = dup(0);
close(0);
#if !MSDOS_COMPILER
-#if OS2
- /* The __open() system call translates "/dev/tty" to "con". */
- if (__open(tty_device(), OPEN_READ) < 0)
-#else
- if (open(tty_device(), OPEN_READ) < 0)
-#endif
+ if (open_tty() < 0)
#endif
dup(inp);
#endif
diff --git a/contrib/less/main.c b/contrib/less/main.c
index 4f8526b69225..d52172a1ada6 100644
--- a/contrib/less/main.c
+++ b/contrib/less/main.c
@@ -1,6 +1,6 @@
/* $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.
@@ -61,8 +61,10 @@ extern int know_dumb;
extern int pr_type;
extern int quit_if_one_screen;
extern int no_init;
-extern int errmsgs;
-
+extern int errmsgs;
+extern int redraw_on_quit;
+extern int term_init_done;
+extern int first_time;
/*
* Entry point.
@@ -143,7 +145,7 @@ main(argc, argv)
s = lgetenv(less_is_more ? "MORE" : "LESS");
if (s != NULL)
- scan_option(save(s));
+ scan_option(s);
#define isoptstring(s) less_is_more ? (((s)[0] == '-') && (s)[1] != '\0') : \
(((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0')
@@ -417,12 +419,23 @@ quit(status)
rstat('Q');
#endif /*LESSTEST*/
quitting = 1;
- edit((char*)NULL);
- save_cmdhist();
if (interactive())
clear_bot();
deinit();
flush();
+ if (redraw_on_quit && term_init_done)
+ {
+ /*
+ * The last file text displayed might have been on an
+ * alternate screen, which now (since deinit) cannot be seen.
+ * redraw_on_quit tells us to redraw it on the main screen.
+ */
+ first_time = 1; /* Don't print "skipping" or tildes */
+ repaint();
+ flush();
+ }
+ edit((char*)NULL);
+ save_cmdhist();
raw_mode(0);
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
/*
diff --git a/contrib/less/mark.c b/contrib/less/mark.c
index cbb316f276e6..f3bf0c4f6b55 100644
--- a/contrib/less/mark.c
+++ b/contrib/less/mark.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -59,6 +59,9 @@ cmark(m, ifile, pos, ln)
m->m_ifile = ifile;
m->m_scrpos.pos = pos;
m->m_scrpos.ln = ln;
+ if (m->m_filename != NULL)
+ /* Normally should not happen but a corrupt lesshst file can do it. */
+ free(m->m_filename);
m->m_filename = NULL;
}
diff --git a/contrib/less/optfunc.c b/contrib/less/optfunc.c
index 9e7c86925b3a..84333b716ac9 100644
--- a/contrib/less/optfunc.c
+++ b/contrib/less/optfunc.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -59,6 +59,10 @@ extern int linenum_width;
extern int status_col_width;
extern int use_color;
extern int want_filesize;
+extern int header_lines;
+extern int header_cols;
+extern int def_search_type;
+extern int chopline;
#if LOGFILE
extern char *namelogfile;
extern int force_logfile;
@@ -164,7 +168,6 @@ opt_j(type, s)
char *s;
{
PARG parg;
- char buf[24];
int len;
int err;
@@ -199,7 +202,7 @@ opt_j(type, s)
error("Position target at screen line %d", &parg);
} else
{
-
+ char buf[24];
SNPRINTF1(buf, sizeof(buf), ".%06ld", jump_sline_fraction);
len = (int) strlen(buf);
while (len > 2 && buf[len-1] == '0')
@@ -229,7 +232,6 @@ opt_shift(type, s)
char *s;
{
PARG parg;
- char buf[24];
int len;
int err;
@@ -264,7 +266,7 @@ opt_shift(type, s)
error("Horizontal shift %d columns", &parg);
} else
{
-
+ char buf[24];
SNPRINTF1(buf, sizeof(buf), ".%06ld", shift_count_fraction);
len = (int) strlen(buf);
while (len > 2 && buf[len-1] == '0')
@@ -542,7 +544,7 @@ opt__V(type, s)
putstr(" regular expressions)\n");
{
char constant *copyright =
- "Copyright (C) 1984-2021 Mark Nudelman\n\n";
+ "Copyright (C) 1984-2022 Mark Nudelman\n\n";
putstr(copyright);
}
if (version[strlen(version)-1] == 'x')
@@ -612,15 +614,16 @@ color_from_namechar(namechar)
{
switch (namechar)
{
- case 'W': case 'A': return AT_COLOR_ATTN;
case 'B': return AT_COLOR_BIN;
case 'C': return AT_COLOR_CTRL;
case 'E': return AT_COLOR_ERROR;
+ case 'H': return AT_COLOR_HEADER;
case 'M': return AT_COLOR_MARK;
case 'N': return AT_COLOR_LINENUM;
case 'P': return AT_COLOR_PROMPT;
case 'R': return AT_COLOR_RSCROLL;
case 'S': return AT_COLOR_SEARCH;
+ case 'W': case 'A': return AT_COLOR_ATTN;
case 'n': return AT_NORMAL;
case 's': return AT_STANDOUT;
case 'd': return AT_BOLD;
@@ -721,7 +724,7 @@ opt_x(type, s)
extern int tabstops[];
extern int ntabstops;
extern int tabdefault;
- char msg[60+(4*TABSTOP_MAX)];
+ char msg[60+((INT_STRLEN_BOUND(int)+1)*TABSTOP_MAX)];
int i;
PARG p;
@@ -976,9 +979,111 @@ opt_filesize(type, s)
case INIT:
case TOGGLE:
if (want_filesize && curr_ifile != NULL && ch_length() == NULL_POSITION)
- scan_eof();
+ scan_eof();
+ break;
+ case QUERY:
+ break;
+ }
+}
+
+/*
+ * Handler for the --header option.
+ */
+ /*ARGSUSED*/
+ public void
+opt_header(type, s)
+ int type;
+ char *s;
+{
+ int err;
+ int n;
+
+ switch (type)
+ {
+ case INIT:
+ case TOGGLE:
+ n = getnum(&s, "header", &err);
+ if (err)
+ error("invalid number of lines", NULL_PARG);
+ else
+ {
+ header_lines = n;
+ header_cols = 0;
+ if (*s == ',')
+ {
+ ++s;
+ n = getnum(&s, "header", &err);
+ if (err)
+ error("invalid number of columns", NULL_PARG);
+ else
+ header_cols = n;
+ }
+ }
+ break;
+ case QUERY:
+ {
+ char buf[2*INT_STRLEN_BOUND(int)+2];
+ PARG parg;
+ SNPRINTF2(buf, sizeof(buf), "%d,%d", header_lines, header_cols);
+ parg.p_string = buf;
+ error("header (lines,columns) is %s", &parg);
+ }
+ break;
+ }
+}
+
+/*
+ * Handler for the --search-options option.
+ */
+ /*ARGSUSED*/
+ public void
+opt_search_type(type, s)
+ int type;
+ char *s;
+{
+ int st;
+ PARG parg;
+ char buf[16];
+ char *bp;
+
+ switch (type)
+ {
+ case INIT:
+ case TOGGLE:
+ st = 0;
+ for (; *s != '\0'; s++)
+ {
+ switch (*s)
+ {
+ case 'E': case 'e': case CONTROL('E'): st |= SRCH_PAST_EOF; break;
+ case 'F': case 'f': case CONTROL('F'): st |= SRCH_FIRST_FILE; break;
+ case 'K': case 'k': case CONTROL('K'): st |= SRCH_NO_MOVE; break;
+ case 'N': case 'n': case CONTROL('N'): st |= SRCH_NO_MATCH; break;
+ case 'R': case 'r': case CONTROL('R'): st |= SRCH_NO_REGEX; break;
+ case 'W': case 'w': case CONTROL('W'): st |= SRCH_WRAP; break;
+ case '-': st = 0; break;
+ case '^': break;
+ default:
+ parg.p_char = *s;
+ error("invalid search option '%c'", &parg);
+ return;
+ }
+ }
+ def_search_type = norm_search_type(st);
break;
case QUERY:
+ bp = buf;
+ if (def_search_type & SRCH_PAST_EOF) *bp++ = 'E';
+ if (def_search_type & SRCH_FIRST_FILE) *bp++ = 'F';
+ if (def_search_type & SRCH_NO_MOVE) *bp++ = 'K';
+ if (def_search_type & SRCH_NO_MATCH) *bp++ = 'N';
+ if (def_search_type & SRCH_NO_REGEX) *bp++ = 'R';
+ if (def_search_type & SRCH_WRAP) *bp++ = 'W';
+ if (bp == buf)
+ *bp++ = '-';
+ *bp = '\0';
+ parg.p_string = buf;
+ error("search options: %s", &parg);
break;
}
}
@@ -1026,6 +1131,12 @@ opt_rstat(type, s)
}
#endif /*LESSTEST*/
+ public int
+chop_line(VOID_PARAM)
+{
+ return (chopline || header_cols > 0 || header_lines > 0);
+}
+
/*
* Get the "screen window" size.
*/
@@ -1034,6 +1145,6 @@ get_swindow(VOID_PARAM)
{
if (swindow > 0)
return (swindow);
- return (sc_height + swindow);
+ return (sc_height - header_lines + swindow);
}
diff --git a/contrib/less/option.c b/contrib/less/option.c
index 61247d81ee9b..c4a496eddb4d 100644
--- a/contrib/less/option.c
+++ b/contrib/less/option.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -55,7 +55,7 @@ opt_desc(o)
propt(c)
int c;
{
- static char buf[8];
+ static char buf[MAX_PRCHAR_LEN+2];
sprintf(buf, "-%s", prchar(c));
return (buf);
diff --git a/contrib/less/option.h b/contrib/less/option.h
index 4a10d6b8b228..2ed238323874 100644
--- a/contrib/less/option.h
+++ b/contrib/less/option.h
@@ -1,5 +1,5 @@
/*
- * 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.
diff --git a/contrib/less/opttbl.c b/contrib/less/opttbl.c
index 73f8435043e6..6da2b305b820 100644
--- a/contrib/less/opttbl.c
+++ b/contrib/less/opttbl.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -63,7 +63,14 @@ public int linenum_width; /* Width of line numbers */
public int status_col_width; /* Width of status column */
public int incr_search; /* Incremental search */
public int use_color; /* Use UI color */
-public int want_filesize; /* */
+public int want_filesize; /* Scan to EOF if necessary to get file size */
+public int status_line; /* Highlight entire marked lines */
+public int header_lines; /* Freeze header lines at top of screen */
+public int header_cols; /* Freeze header columns at left of screen */
+public int nonum_headers; /* Don't give headers line numbers */
+public int redraw_on_quit; /* Redraw last screen after term deinit */
+public int def_search_type; /* */
+public int exit_F_on_close; /* Exit F command when input closes */
#if HILITE_SEARCH
public int hilite_search; /* Highlight matched search patterns? */
#endif
@@ -139,6 +146,12 @@ static struct optname status_col_width_optname = { "status-col-width", NULL };
static struct optname incr_search_optname = { "incsearch", NULL };
static struct optname use_color_optname = { "use-color", NULL };
static struct optname want_filesize_optname = { "file-size", NULL };
+static struct optname status_line_optname = { "status-line", NULL };
+static struct optname header_optname = { "header", NULL };
+static struct optname nonum_headers_optname = { "no-number-headers", NULL };
+static struct optname redraw_on_quit_optname = { "redraw-on-quit", NULL };
+static struct optname search_type_optname = { "search-options", NULL };
+static struct optname exit_F_on_close_optname = { "exit-follow-on-close", NULL };
#if LESSTEST
static struct optname ttyin_name_optname = { "tty", NULL };
static struct optname rstat_optname = { "rstat", NULL };
@@ -562,6 +575,54 @@ static struct loption option[] =
NULL
}
},
+ { OLETTER_NONE, &status_line_optname,
+ BOOL|REPAINT, OPT_OFF, &status_line, NULL,
+ {
+ "Don't color each line with its status column color",
+ "Color each line with its status column color",
+ NULL
+ }
+ },
+ { OLETTER_NONE, &header_optname,
+ STRING|REPAINT, 0, NULL, opt_header,
+ {
+ "Header lines: ",
+ NULL,
+ NULL
+ }
+ },
+ { OLETTER_NONE, &nonum_headers_optname,
+ BOOL|REPAINT, 0, &nonum_headers, NULL,
+ {
+ "Number header lines",
+ "Don't number header lines",
+ NULL
+ }
+ },
+ { OLETTER_NONE, &redraw_on_quit_optname,
+ BOOL, OPT_OFF, &redraw_on_quit, NULL,
+ {
+ "Don't redraw screen when quitting",
+ "Redraw last screen when quitting",
+ NULL
+ }
+ },
+ { OLETTER_NONE, &search_type_optname,
+ STRING, 0, NULL, opt_search_type,
+ {
+ "Search options: ",
+ NULL,
+ NULL
+ }
+ },
+ { OLETTER_NONE, &exit_F_on_close_optname,
+ BOOL, OPT_OFF, &exit_F_on_close, NULL,
+ {
+ "Don't exit F command when input closes",
+ "Exit F command when input closes",
+ NULL
+ }
+ },
#if LESSTEST
{ OLETTER_NONE, &ttyin_name_optname,
STRING|NO_TOGGLE, 0, NULL, opt_ttyin_name,
diff --git a/contrib/less/os.c b/contrib/less/os.c
index 1723787b1c50..22b97de34b1c 100644
--- a/contrib/less/os.c
+++ b/contrib/less/os.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -61,11 +61,13 @@
#endif
public int reading;
+public int consecutive_nulls = 0;
static jmp_buf read_label;
extern int sigs;
extern int ignore_eoi;
+extern int exit_F_on_close;
#if !MSDOS_COMPILER
extern int tty;
#endif
@@ -157,20 +159,26 @@ start:
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
if (select(fd+1, &readfds, 0, 0, 0) == -1)
+ {
+ reading = 0;
return (-1);
+ }
}
#endif
#if USE_POLL
if (ignore_eoi && fd != tty)
{
+ int close_events = exit_F_on_close ? POLLERR|POLLHUP : POLLERR;
if (poll_events(tty, POLLIN) && getchr() == CONTROL('X'))
{
sigs |= S_INTERRUPT;
+ reading = 0;
return (READ_INTR);
}
- if (poll_events(fd, POLLERR|POLLHUP))
+ if (poll_events(fd, close_events))
{
sigs |= S_INTERRUPT;
+ reading = 0;
return (READ_INTR);
}
}
@@ -179,11 +187,13 @@ start:
if (win32_kbhit() && WIN32getch() == CONTROL('X'))
{
sigs |= S_INTERRUPT;
+ reading = 0;
return (READ_INTR);
}
#endif
#endif
n = read(fd, buf, len);
+ reading = 0;
#if 1
/*
* This is a kludge to workaround a problem on some systems
@@ -193,7 +203,6 @@ start:
{
if (!ignore_eoi)
{
- static int consecutive_nulls = 0;
if (n == 0)
consecutive_nulls++;
else
@@ -203,7 +212,6 @@ start:
}
}
#endif
- reading = 0;
if (n < 0)
{
#if HAVE_ERRNO
@@ -259,7 +267,7 @@ get_time(VOID_PARAM)
strerror(err)
int err;
{
- static char buf[16];
+ static char buf[INT_STRLEN_BOUND(int)+12];
#if HAVE_SYS_ERRLIST
extern char *sys_errlist[];
extern int sys_nerr;
diff --git a/contrib/less/output.c b/contrib/less/output.c
index a865f4f0ce0b..3fed3df3ad33 100644
--- a/contrib/less/output.c
+++ b/contrib/less/output.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -594,8 +594,13 @@ less_printf(fmt, parg)
parg++;
break;
case 'c':
- putchr(parg->p_char);
- col++;
+ s = prchar(parg->p_char);
+ parg++;
+ while (*s != '\0')
+ {
+ putchr(*s++);
+ col++;
+ }
break;
case '%':
putchr('%');
diff --git a/contrib/less/pattern.c b/contrib/less/pattern.c
index c2266fcf68c8..bed36dfd57d1 100644
--- a/contrib/less/pattern.c
+++ b/contrib/less/pattern.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -14,6 +14,7 @@
#include "less.h"
extern int caseless;
+extern int is_caseless;
extern int utf_mode;
/*
@@ -49,7 +50,7 @@ compile_pattern2(pattern, search_type, comp_pattern, show_error)
#endif
#if HAVE_POSIX_REGCOMP
regex_t *comp = (regex_t *) ecalloc(1, sizeof(regex_t));
- if (regcomp(comp, pattern, REGCOMP_FLAG))
+ if (regcomp(comp, pattern, REGCOMP_FLAG | (is_caseless ? REG_ICASE : 0)))
{
free(comp);
if (show_error)
@@ -68,7 +69,8 @@ compile_pattern2(pattern, search_type, comp_pattern, show_error)
int erroffset;
PARG parg;
pcre *comp = pcre_compile(pattern,
- (utf_mode) ? PCRE_UTF8 | PCRE_NO_UTF8_CHECK : 0,
+ ((utf_mode) ? PCRE_UTF8 | PCRE_NO_UTF8_CHECK : 0) |
+ (is_caseless ? PCRE_CASELESS : 0),
&errstring, &erroffset, NULL);
if (comp == NULL)
{
@@ -84,7 +86,8 @@ compile_pattern2(pattern, search_type, comp_pattern, show_error)
PCRE2_SIZE erroffset;
PARG parg;
pcre2_code *comp = pcre2_compile((PCRE2_SPTR)pattern, strlen(pattern),
- 0, &errcode, &erroffset, NULL);
+ (is_caseless ? PCRE2_CASELESS : 0),
+ &errcode, &erroffset, NULL);
if (comp == NULL)
{
if (show_error)
@@ -154,7 +157,7 @@ compile_pattern(pattern, search_type, show_error, comp_pattern)
char *cvt_pattern;
int result;
- if (caseless != OPT_ONPLUS)
+ if (caseless != OPT_ONPLUS || re_handles_caseless)
cvt_pattern = pattern;
else
{
diff --git a/contrib/less/pattern.h b/contrib/less/pattern.h
index 96d4494d783f..5c0de46dbdcb 100644
--- a/contrib/less/pattern.h
+++ b/contrib/less/pattern.h
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -10,58 +10,72 @@
#if HAVE_GNU_REGEX
#define __USE_GNU 1
#include <regex.h>
-#define PATTERN_TYPE struct re_pattern_buffer *
+#define PATTERN_TYPE struct re_pattern_buffer *
#define SET_NULL_PATTERN(name) name = NULL
#endif
+/* ---- POSIX ---- */
#if HAVE_POSIX_REGCOMP
#include <regex.h>
#ifdef REG_EXTENDED
extern int less_is_more;
#define REGCOMP_FLAG (less_is_more ? 0 : REG_EXTENDED)
#else
-#define REGCOMP_FLAG 0
+#define REGCOMP_FLAG 0
#endif
-#define PATTERN_TYPE regex_t *
+#define PATTERN_TYPE regex_t *
#define SET_NULL_PATTERN(name) name = NULL
+#define re_handles_caseless TRUE
#endif
+/* ---- PCRE ---- */
#if HAVE_PCRE
#include <pcre.h>
-#define PATTERN_TYPE pcre *
+#define PATTERN_TYPE pcre *
#define SET_NULL_PATTERN(name) name = NULL
+#define re_handles_caseless TRUE
#endif
+/* ---- PCRE2 ---- */
#if HAVE_PCRE2
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
-#define PATTERN_TYPE pcre2_code *
+#define PATTERN_TYPE pcre2_code *
#define SET_NULL_PATTERN(name) name = NULL
+#define re_handles_caseless TRUE
#endif
+/* ---- RE_COMP ---- */
#if HAVE_RE_COMP
char *re_comp LESSPARAMS ((char*));
int re_exec LESSPARAMS ((char*));
-#define PATTERN_TYPE int
+#define PATTERN_TYPE int
#define SET_NULL_PATTERN(name) name = 0
#endif
+/* ---- REGCMP ---- */
#if HAVE_REGCMP
char *regcmp LESSPARAMS ((char*));
char *regex LESSPARAMS ((char**, char*));
extern char *__loc1;
-#define PATTERN_TYPE char **
+#define PATTERN_TYPE char **
#define SET_NULL_PATTERN(name) name = NULL
#endif
+/* ---- REGCOMP ---- */
#if HAVE_V8_REGCOMP
#include "regexp.h"
extern int reg_show_error;
-#define PATTERN_TYPE struct regexp *
+#define PATTERN_TYPE struct regexp *
#define SET_NULL_PATTERN(name) name = NULL
#endif
+/* ---- NONE ---- */
#if NO_REGEX
-#define PATTERN_TYPE void *
+#define PATTERN_TYPE void *
#define SET_NULL_PATTERN(name)
#endif
+
+#ifndef re_handles_caseless
+#define re_handles_caseless FALSE
+#endif
diff --git a/contrib/less/pckeys.h b/contrib/less/pckeys.h
index 8b21d729935a..a4f9c25ca88d 100644
--- a/contrib/less/pckeys.h
+++ b/contrib/less/pckeys.h
@@ -1,5 +1,5 @@
/*
- * 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.
diff --git a/contrib/less/position.c b/contrib/less/position.c
index 8f6edc939377..eabaf7e66dc2 100644
--- a/contrib/less/position.c
+++ b/contrib/less/position.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -25,6 +25,7 @@ static POSITION *table = NULL; /* The position table */
static int table_size = 0;
extern int sc_width, sc_height;
+extern int header_lines;
/*
* Return the starting file position of a line displayed on the screen.
diff --git a/contrib/less/position.h b/contrib/less/position.h
index 4e0efc7f4c0f..85a110fca0f0 100644
--- a/contrib/less/position.h
+++ b/contrib/less/position.h
@@ -1,5 +1,5 @@
/*
- * 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.
diff --git a/contrib/less/prompt.c b/contrib/less/prompt.c
index 0e38c0f6e438..5319c40293bf 100644
--- a/contrib/less/prompt.c
+++ b/contrib/less/prompt.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -29,6 +29,7 @@ extern int hshift;
extern int sc_height;
extern int jump_sline;
extern int less_is_more;
+extern int header_lines;
extern IFILE curr_ifile;
#if EDITOR
extern char *editor;
@@ -260,7 +261,7 @@ protochar(c, where, iseditproto)
char *s;
#undef PAGE_NUM
-#define PAGE_NUM(linenum) ((((linenum) - 1) / (sc_height - 1)) + 1)
+#define PAGE_NUM(linenum) ((((linenum) - 1) / (sc_height - header_lines - 1)) + 1)
switch (c)
{
@@ -276,7 +277,7 @@ protochar(c, where, iseditproto)
break;
case 'd': /* Current page number */
linenum = currline(where);
- if (linenum > 0 && sc_height > 1)
+ if (linenum > 0 && sc_height > header_lines + 1)
ap_linenum(PAGE_NUM(linenum));
else
ap_quest();
@@ -325,7 +326,7 @@ protochar(c, where, iseditproto)
case 'l': /* Current line number */
linenum = currline(where);
if (linenum != 0)
- ap_linenum(linenum);
+ ap_linenum(vlinenum(linenum));
else
ap_quest();
break;
@@ -335,7 +336,7 @@ protochar(c, where, iseditproto)
(linenum = find_linenum(len)) <= 0)
ap_quest();
else
- ap_linenum(linenum-1);
+ ap_linenum(vlinenum(linenum-1));
break;
case 'm': /* Number of files */
#if TAGS
@@ -484,9 +485,8 @@ wherechar(p, wp)
* Construct a message based on a prototype string.
*/
public char *
-pr_expand(proto, maxwidth)
+pr_expand(proto)
constant char *proto;
- int maxwidth;
{
constant char *p;
int c;
@@ -545,14 +545,6 @@ pr_expand(proto, maxwidth)
if (mp == message)
return ("");
- if (maxwidth > 0 && mp >= message + maxwidth)
- {
- /*
- * Message is too long.
- * Return just the final portion of it.
- */
- return (mp - maxwidth);
- }
return (message);
}
@@ -562,7 +554,7 @@ pr_expand(proto, maxwidth)
public char *
eq_message(VOID_PARAM)
{
- return (pr_expand(eqproto, 0));
+ return (pr_expand(eqproto));
}
/*
@@ -579,8 +571,7 @@ pr_string(VOID_PARAM)
type = (!less_is_more) ? pr_type : pr_type ? 0 : 1;
prompt = pr_expand((ch_getflags() & CH_HELPFILE) ?
- hproto : prproto[type],
- sc_width-so_s_width-so_e_width-2);
+ hproto : prproto[type]);
new_file = 0;
return (prompt);
}
@@ -591,5 +582,5 @@ pr_string(VOID_PARAM)
public char *
wait_message(VOID_PARAM)
{
- return (pr_expand(wproto, sc_width-so_s_width-so_e_width-2));
+ return (pr_expand(wproto));
}
diff --git a/contrib/less/screen.c b/contrib/less/screen.c
index 033a5b9cf23f..7c903ab61eb1 100644
--- a/contrib/less/screen.c
+++ b/contrib/less/screen.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -128,8 +128,10 @@ extern int sc_height;
#endif
#if MSDOS_COMPILER==WIN32C
+#define UTF8_MAX_LENGTH 4
struct keyRecord
{
+ WCHAR unicode;
int ascii;
int scan;
} currentKey;
@@ -234,6 +236,7 @@ public int can_goto_line; /* Can move cursor to any line */
public int clear_bg; /* Clear fills with background color */
public int missing_cap = 0; /* Some capability is missing */
public char *kent = NULL; /* Keypad ENTER sequence */
+public int term_init_done = FALSE;
static int attrmode = AT_NORMAL;
static int termcap_debug = -1;
@@ -930,6 +933,7 @@ special_key_str(key)
static char k_delete[] = { '\340', PCK_DELETE, 0 };
static char k_ctl_delete[] = { '\340', PCK_CTL_DELETE, 0 };
static char k_ctl_backspace[] = { '\177', 0 };
+ static char k_backspace[] = { '\b', 0 };
static char k_home[] = { '\340', PCK_HOME, 0 };
static char k_end[] = { '\340', PCK_END, 0 };
static char k_up[] = { '\340', PCK_UP, 0 };
@@ -1029,6 +1033,9 @@ special_key_str(key)
case SK_CTL_DELETE:
s = k_ctl_delete;
break;
+ case SK_BACKSPACE:
+ s = k_backspace;
+ break;
case SK_F1:
s = k_f1;
break;
@@ -1069,6 +1076,15 @@ special_key_str(key)
s = tbuf;
}
break;
+ case SK_BACKSPACE:
+ s = ltgetstr("kb", &sp);
+ if (s == NULL)
+ {
+ tbuf[0] = '\b';
+ tbuf[1] = '\0';
+ s = tbuf;
+ }
+ break;
#endif
case SK_CONTROL_K:
tbuf[0] = CONTROL('K');
@@ -1712,7 +1728,10 @@ init(VOID_PARAM)
if (!(quit_if_one_screen && one_screen))
{
if (!no_init)
+ {
ltputs(sc_init, sc_height, putchr);
+ term_init_done = 1;
+ }
if (!no_keypad)
ltputs(sc_s_keypad, sc_height, putchr);
if (mousecap)
@@ -1738,7 +1757,10 @@ init(VOID_PARAM)
if (!(quit_if_one_screen && one_screen))
{
if (!no_init)
+ {
win32_init_term();
+ term_init_done = 1;
+ }
if (mousecap)
init_mouse();
@@ -2527,7 +2549,7 @@ tput_fmt(fmt, color, f_putc)
int color;
int (*f_putc)(int);
{
- char buf[32];
+ char buf[INT_STRLEN_BOUND(int)+16];
if (color == attrcolor)
return;
SNPRINTF1(buf, sizeof(buf), fmt, color);
@@ -2608,7 +2630,7 @@ WIN32put_fmt(fmt, color)
char *fmt;
int color;
{
- char buf[16];
+ char buf[INT_STRLEN_BOUND(int)+16];
int len = SNPRINTF1(buf, sizeof(buf), fmt, color);
WIN32textout(buf, len);
return TRUE;
@@ -2827,10 +2849,10 @@ win32_kbhit(VOID_PARAM)
*/
do
{
- PeekConsoleInput(tty, &ip, 1, &read);
+ PeekConsoleInputW(tty, &ip, 1, &read);
if (read == 0)
return (FALSE);
- ReadConsoleInput(tty, &ip, 1, &read);
+ ReadConsoleInputW(tty, &ip, 1, &read);
/* generate an X11 mouse sequence from the mouse event */
if (mousecap && ip.EventType == MOUSE_EVENT &&
ip.Event.MouseEvent.dwEventFlags != MOUSE_MOVED)
@@ -2861,11 +2883,13 @@ win32_kbhit(VOID_PARAM)
}
} while (ip.EventType != KEY_EVENT ||
ip.Event.KeyEvent.bKeyDown != TRUE ||
- ip.Event.KeyEvent.wVirtualScanCode == 0 ||
+ (ip.Event.KeyEvent.wVirtualScanCode == 0 && ip.Event.KeyEvent.uChar.UnicodeChar == 0) ||
+ ip.Event.KeyEvent.wVirtualKeyCode == VK_KANJI ||
ip.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT ||
ip.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL ||
ip.Event.KeyEvent.wVirtualKeyCode == VK_MENU);
+ currentKey.unicode = ip.Event.KeyEvent.uChar.UnicodeChar;
currentKey.ascii = ip.Event.KeyEvent.uChar.AsciiChar;
currentKey.scan = ip.Event.KeyEvent.wVirtualScanCode;
keyCount = ip.Event.KeyEvent.wRepeatCount;
@@ -2913,7 +2937,18 @@ win32_kbhit(VOID_PARAM)
public char
WIN32getch(VOID_PARAM)
{
- int ascii;
+ char ascii;
+ static unsigned char utf8[UTF8_MAX_LENGTH];
+ static int utf8_size = 0;
+ static int utf8_next_byte = 0;
+
+ // Return the rest of multibyte character from the prior call
+ if (utf8_next_byte < utf8_size)
+ {
+ ascii = utf8[utf8_next_byte++];
+ return ascii;
+ }
+ utf8_size = 0;
if (pending_scancode)
{
@@ -2930,7 +2965,16 @@ WIN32getch(VOID_PARAM)
continue;
}
keyCount --;
- ascii = currentKey.ascii;
+ // If multibyte character, return its first byte
+ if (currentKey.ascii != currentKey.unicode)
+ {
+ utf8_size = WideCharToMultiByte(CP_UTF8, 0, &currentKey.unicode, 1, &utf8, sizeof(utf8), NULL, NULL);
+ if (utf8_size == 0 )
+ return '\0';
+ ascii = utf8[0];
+ utf8_next_byte = 1;
+ } else
+ ascii = currentKey.ascii;
/*
* On PC's, the extended keys return a 2 byte sequence beginning
* with '00', so if the ascii code is 00, the next byte will be
@@ -2940,7 +2984,7 @@ WIN32getch(VOID_PARAM)
} while (pending_scancode &&
(currentKey.scan == PCK_CAPS_LOCK || currentKey.scan == PCK_NUM_LOCK));
- return ((char)ascii);
+ return ascii;
}
#endif
diff --git a/contrib/less/scrsize.c b/contrib/less/scrsize.c
index ee07cb8af1e6..7ceed58bd755 100644
--- a/contrib/less/scrsize.c
+++ b/contrib/less/scrsize.c
@@ -1,5 +1,5 @@
/*
- * 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.
diff --git a/contrib/less/search.c b/contrib/less/search.c
index f619fbebeae8..224bc493df4c 100644
--- a/contrib/less/search.c
+++ b/contrib/less/search.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -35,7 +35,6 @@ extern int utf_mode;
extern int screen_trashed;
extern int sc_width;
extern int sc_height;
-extern int chopline;
extern int hshift;
#if HILITE_SEARCH
extern int hilite_search;
@@ -120,7 +119,7 @@ struct pattern_info {
static struct pattern_info search_info;
static int is_ucase_pattern;
-static int is_caseless;
+public int is_caseless;
/*
* Are there any uppercase letters in this string?
@@ -166,6 +165,12 @@ set_pattern(info, pattern, search_type, show_error)
int search_type;
int show_error;
{
+ /*
+ * Ignore case if -I is set OR
+ * -i is set AND the pattern is all lowercase.
+ */
+ is_ucase_pattern = (pattern == NULL) ? FALSE : is_ucase(pattern);
+ is_caseless = (is_ucase_pattern && caseless != OPT_ONPLUS) ? 0 : caseless;
#if !NO_REGEX
if (pattern == NULL)
SET_NULL_PATTERN(info->compiled);
@@ -182,16 +187,6 @@ set_pattern(info, pattern, search_type, show_error)
strcpy(info->text, pattern);
}
info->search_type = search_type;
-
- /*
- * Ignore case if -I is set OR
- * -i is set AND the pattern is all lowercase.
- */
- is_ucase_pattern = is_ucase(pattern);
- if (is_ucase_pattern && caseless != OPT_ONPLUS)
- is_caseless = 0;
- else
- is_caseless = caseless;
return 0;
}
@@ -225,7 +220,7 @@ get_cvt_ops(VOID_PARAM)
{
int ops = 0;
- if (is_caseless)
+ if (is_caseless && !re_handles_caseless)
ops |= CVT_TO_LC;
if (bs_mode == BS_SPECIAL)
ops |= CVT_BS;
@@ -291,6 +286,7 @@ repaint_hilite(on)
goto_line(sindex);
put_line();
}
+ overlay_header();
lower_left();
hide_hilite = save_hide_hilite;
}
@@ -339,6 +335,8 @@ clear_attn(VOID_PARAM)
moved = 1;
}
}
+ if (overlay_header())
+ moved = 1;
if (moved)
lower_left();
#endif
@@ -946,7 +944,7 @@ add_hilite(anchor, hl)
}
/*
- * Hilight every character in a range of displayed characters.
+ * Highlight every character in a range of displayed characters.
*/
static void
create_hilites(linepos, start_index, end_index, chpos)
@@ -1236,7 +1234,7 @@ get_seg(pos, tpos)
for (seg = 0;; seg++)
{
- POSITION npos = forw_line_seg(pos, TRUE);
+ POSITION npos = forw_line_seg(pos, FALSE, FALSE, TRUE);
if (npos > tpos)
return seg;
pos = npos;
@@ -1446,7 +1444,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos, pla
hilite_line(linepos, cline, line_len, chpos, sp, ep, cvt_ops);
}
#endif
- if (chopline)
+ if (chop_line())
{
/*
* If necessary, shift horizontally to make sure
@@ -1460,10 +1458,8 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos, pla
int sshift;
int eshift;
hshift = 0; /* make get_seg count screen lines */
- chopline = FALSE;
sshift = swidth * get_seg(linepos, linepos + chpos[start_off]);
eshift = swidth * get_seg(linepos, linepos + chpos[end_off]);
- chopline = TRUE;
if (sshift >= save_hshift && eshift <= save_hshift)
{
hshift = save_hshift;
@@ -1540,20 +1536,25 @@ hist_pattern(search_type)
chg_caseless(VOID_PARAM)
{
if (!is_ucase_pattern)
+ {
/*
* Pattern did not have uppercase.
- * Just set the search caselessness to the global caselessness.
+ * Set the search caselessness to the global caselessness.
*/
is_caseless = caseless;
- else
- {
/*
- * Pattern did have uppercase.
- * Regenerate the pattern using the new state.
+ * If regex handles caseless, we need to discard
+ * the pattern which was compiled with the old caseless.
*/
- clear_pattern(&search_info);
- (void) hist_pattern(search_info.search_type);
+ if (!re_handles_caseless)
+ /* We handle caseless, so the pattern doesn't change. */
+ return;
}
+ /*
+ * Regenerate the pattern using the new state.
+ */
+ clear_pattern(&search_info);
+ (void) hist_pattern(search_info.search_type);
}
/*
@@ -1908,7 +1909,11 @@ set_filter_pattern(pattern, search_type)
/* Create a new filter and add it to the filter_infos list. */
filter = ecalloc(1, sizeof(struct pattern_info));
init_pattern(filter);
- set_pattern(filter, pattern, search_type, 1);
+ if (set_pattern(filter, pattern, search_type, 1) < 0)
+ {
+ free(filter);
+ return;
+ }
filter->next = filter_infos;
filter_infos = filter;
}
diff --git a/contrib/less/signal.c b/contrib/less/signal.c
index 9e580e00fe36..290275696582 100644
--- a/contrib/less/signal.c
+++ b/contrib/less/signal.c
@@ -1,5 +1,5 @@
/*
- * 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.
diff --git a/contrib/less/tags.c b/contrib/less/tags.c
index 23a9b92f018b..03e29736488a 100644
--- a/contrib/less/tags.c
+++ b/contrib/less/tags.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -396,7 +396,9 @@ edit_tagfile(VOID_PARAM)
}
static int
-curtag_match(char const *line, POSITION linepos)
+curtag_match(line, linepos)
+ char constant *line;
+ POSITION linepos;
{
/*
* Test the line to see if we have a match.
@@ -508,7 +510,7 @@ findgtag(tag, type)
char *tag; /* tag to load */
int type; /* tags type */
{
- char buf[256];
+ char buf[1024];
FILE *fp;
struct tag *tp;
diff --git a/contrib/less/ttyin.c b/contrib/less/ttyin.c
index 5bd3385ceadb..4be4527530d9 100644
--- a/contrib/less/ttyin.c
+++ b/contrib/less/ttyin.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -36,24 +36,46 @@ extern int sigs;
extern int utf_mode;
extern int wheel_lines;
-/*
- * Get name of tty device.
- */
#if !MSDOS_COMPILER
- public char *
-tty_device(VOID_PARAM)
+ static int
+open_tty_device(dev)
+ constant char* dev;
{
- char *dev = NULL;
-#if HAVE_TTYNAME
- dev = ttyname(2);
+#if OS2
+ /* The __open() system call translates "/dev/tty" to "con". */
+ return __open(dev, OPEN_READ);
+#else
+ return open(dev, OPEN_READ);
#endif
- if (dev == NULL)
- dev = "/dev/tty";
+}
+
+/*
+ * Open the tty device.
+ * Try ttyname(), then try /dev/tty, then use file descriptor 2.
+ * In Unix, file descriptor 2 is usually attached to the screen,
+ * but also usually lets you read from the keyboard.
+ */
+ public int
+open_tty(VOID_PARAM)
+{
+ int fd = -1;
#if LESSTEST
if (ttyin_name != NULL)
- dev = ttyin_name;
+ fd = open_tty_device(ttyin_name);
#endif /*LESSTEST*/
- return dev;
+#if HAVE_TTYNAME
+ if (fd < 0)
+ {
+ constant char *dev = ttyname(2);
+ if (dev != NULL)
+ fd = open_tty_device(dev);
+ }
+#endif
+ if (fd < 0)
+ fd = open_tty_device("/dev/tty");
+ if (fd < 0)
+ fd = 2;
+ return fd;
}
#endif /* MSDOS_COMPILER */
@@ -93,20 +115,7 @@ open_getchr(VOID_PARAM)
(void) __djgpp_set_ctrl_c(1);
#endif
#else
- /*
- * Try /dev/tty.
- * If that doesn't work, use file descriptor 2,
- * which in Unix is usually attached to the screen,
- * but also usually lets you read from the keyboard.
- */
-#if OS2
- /* The __open() system call translates "/dev/tty" to "con". */
- tty = __open(tty_device(), OPEN_READ);
-#else
- tty = open(tty_device(), OPEN_READ);
-#endif
- if (tty < 0)
- tty = 2;
+ tty = open_tty();
#endif
#endif
}
diff --git a/contrib/less/ubin.uni b/contrib/less/ubin.uni
index 10a48d5be50e..661cccb03542 100644
--- a/contrib/less/ubin.uni
+++ b/contrib/less/ubin.uni
@@ -1,4 +1,4 @@
-/* Generated by "./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt" on Tue May 19 14:47:34 PDT 2020 */
+/* Generated by "./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt" on Tue Jul 19 12:45:17 PDT 2022 */
{ 0x0000, 0x0007 }, /* Cc */
{ 0x000b, 0x000b }, /* Cc */
{ 0x000e, 0x001f }, /* Cc */
diff --git a/contrib/less/version.c b/contrib/less/version.c
index cab2690176fe..44e811604ca6 100644
--- a/contrib/less/version.c
+++ b/contrib/less/version.c
@@ -1,5 +1,5 @@
/*
- * 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.
@@ -931,6 +931,29 @@ v587 5/27/21 Fix --with-secure; fix --file-size message on Windows;
v588 5/27/21 Fix release.
v589 5/29/21 Copyright & build changes.
v590 6/3/21 Fix non-autoconf Makefiles.
+v591 8/8/21 Use \kB for backspace key in lesskey; add more \k codes;
+ handle multibyte chars in prompt.
+v592 8/24/21 Add --status-line option; limit use of /proc kludge; add --header.
+v593 8/30/21 Add header columns, --no-number-headers.
+v594 10/1/21 Let regex library handle caseless; add --redraw-on-quit option;
+ add #version to lesskey.
+v595 10/12/21 Add H color type; add += to lesskey var section;
+ add --search-options.
+v596 11/8/21 Look for lesskey in $HOME/.config.
+v597 11/16/21 Fix bugs in --header.
+v598 12/6/21 Look for lesshst in $XDG_STATE_HOME and $HOME/.local/state.
+v599 12/28/21 Defer moving to lower left in some cases;
+ suppress TAB expansion in some cases.
+v600 1/7/22 Use /dev/tty if cannot open ttyname().
+v601 1/31/22 Add --exit-follow-on-close option.
+v602 3/1/22 Doc changes.
+v603 3/14/22 Fix --header.
+v604 5/14/22 Fix termlib detection; fix non-ASCII input on Windows.
+v605 6/14/22 Update version number.
+v606 7/17/22 Fix bug with multibyte chars and --incsearch;
+ escape filenames in LESSCLOSE; fix bin_file overrun.
+v607 7/19/22 Update Unicode tables.
+v608 7/22/22 Fix highlighting on colored text boundaries.
*/
-char version[] = "590";
+char version[] = "608";
diff --git a/contrib/less/wide.uni b/contrib/less/wide.uni
index f1ec98d21b79..0e9922373409 100644
--- a/contrib/less/wide.uni
+++ b/contrib/less/wide.uni
@@ -1,4 +1,4 @@
-/* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Tue May 19 14:47:35 PDT 2020 */
+/* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Tue Jul 19 12:45:19 PDT 2022 */
{ 0x1100, 0x115f }, /* W */
{ 0x231a, 0x231b }, /* W */
{ 0x2329, 0x232a }, /* W */
@@ -64,7 +64,10 @@
{ 0x17000, 0x187f7 }, /* W */
{ 0x18800, 0x18cd5 }, /* W */
{ 0x18d00, 0x18d08 }, /* W */
- { 0x1b000, 0x1b11e }, /* W */
+ { 0x1aff0, 0x1aff3 }, /* W */
+ { 0x1aff5, 0x1affb }, /* W */
+ { 0x1affd, 0x1affe }, /* W */
+ { 0x1b000, 0x1b122 }, /* W */
{ 0x1b150, 0x1b152 }, /* W */
{ 0x1b164, 0x1b167 }, /* W */
{ 0x1b170, 0x1b2fb }, /* W */
@@ -99,20 +102,22 @@
{ 0x1f6cc, 0x1f6cc }, /* W */
{ 0x1f6d0, 0x1f6d2 }, /* W */
{ 0x1f6d5, 0x1f6d7 }, /* W */
+ { 0x1f6dd, 0x1f6df }, /* W */
{ 0x1f6eb, 0x1f6ec }, /* W */
{ 0x1f6f4, 0x1f6fc }, /* W */
{ 0x1f7e0, 0x1f7eb }, /* W */
+ { 0x1f7f0, 0x1f7f0 }, /* W */
{ 0x1f90c, 0x1f93a }, /* W */
{ 0x1f93c, 0x1f945 }, /* W */
- { 0x1f947, 0x1f978 }, /* W */
- { 0x1f97a, 0x1f9cb }, /* W */
- { 0x1f9cd, 0x1f9ff }, /* W */
+ { 0x1f947, 0x1f9ff }, /* W */
{ 0x1fa70, 0x1fa74 }, /* W */
- { 0x1fa78, 0x1fa7a }, /* W */
+ { 0x1fa78, 0x1fa7c }, /* W */
{ 0x1fa80, 0x1fa86 }, /* W */
- { 0x1fa90, 0x1faa8 }, /* W */
- { 0x1fab0, 0x1fab6 }, /* W */
- { 0x1fac0, 0x1fac2 }, /* W */
- { 0x1fad0, 0x1fad6 }, /* W */
+ { 0x1fa90, 0x1faac }, /* W */
+ { 0x1fab0, 0x1faba }, /* W */
+ { 0x1fac0, 0x1fac5 }, /* W */
+ { 0x1fad0, 0x1fad9 }, /* W */
+ { 0x1fae0, 0x1fae7 }, /* W */
+ { 0x1faf0, 0x1faf6 }, /* W */
{ 0x20000, 0x2fffd }, /* W */
{ 0x30000, 0x3fffd }, /* W */
diff --git a/contrib/less/xbuf.c b/contrib/less/xbuf.c
index f20dfae1e7df..4e767e34d193 100644
--- a/contrib/less/xbuf.c
+++ b/contrib/less/xbuf.c
@@ -34,7 +34,7 @@ xbuf_reset(xbuf)
public void
xbuf_add(xbuf, ch)
struct xbuffer *xbuf;
- char ch;
+ int ch;
{
if (xbuf->end >= xbuf->size)
{
@@ -50,3 +50,24 @@ xbuf_add(xbuf, ch)
}
xbuf->data[xbuf->end++] = ch;
}
+
+ public int
+xbuf_pop(buf)
+ struct xbuffer *buf;
+{
+ if (buf->end == 0)
+ return -1;
+ return buf->data[--(buf->end)];
+}
+
+ public void
+xbuf_set(dst, src)
+ struct xbuffer *dst;
+ struct xbuffer *src;
+{
+ int i;
+
+ xbuf_reset(dst);
+ for (i = 0; i < src->end; i++)
+ xbuf_add(dst, src->data[i]);
+}
diff --git a/contrib/less/xbuf.h b/contrib/less/xbuf.h
index ba62ef1722b1..d317e17868d5 100644
--- a/contrib/less/xbuf.h
+++ b/contrib/less/xbuf.h
@@ -10,6 +10,7 @@ struct xbuffer
void xbuf_init(struct xbuffer *xbuf);
void xbuf_reset(struct xbuffer *xbuf);
-void xbuf_add(struct xbuffer *xbuf, char ch);
+void xbuf_add(struct xbuffer *xbuf, int ch);
+int xbuf_pop(struct xbuffer *xbuf);
#endif
diff --git a/usr.bin/less/defines.h b/usr.bin/less/defines.h
index 497644f23a48..9b87a45e6be7 100644
--- a/usr.bin/less/defines.h
+++ b/usr.bin/less/defines.h
@@ -283,6 +283,10 @@
/* POSIX regcomp() and regex.h */
#define HAVE_POSIX_REGCOMP 1
+/* Define HAVE_PROCFS if have have fstatfs with f_type and PROC_SUPER_MAGIC.
+ */
+/* #undef HAVE_PROCFS */
+
/* Define to 1 if you have the `realpath' function. */
#define HAVE_REALPATH 1