From nobody Sat Sep 26 01:49:24 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hs9VK5pBXz6t2ns for ; Sat, 26 Sep 2026 01:49:29 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hs9VK4w6qz4gQB for ; Sat, 26 Sep 2026 01:49:29 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1790387369; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=BVaAref54/sLafz132vmx8J6dO84AW74ynsFkjResXQ=; b=NgyDfBenciRKsCFBRkbMc3WDU6RZLHo9aunF3alLrY+N0oX+5Jd/IHc+hmk3+coairRyWN q5qc9KWAW+1hS2ZPyOW2Q3A5BpnoWZWBK47auukBZBdv8srGmXoNNpzXdGqeRY0SHHQbJk sjQ27ewm6rDPbexUm7HBXb80iqz9HRC860byD1Q8QGmGq2Wo/OeV+BFFqtnCeK4gqQg3bV HJi/NBnzXFP3Jt0zSfzc/yeULXaYy5j3+lLd6uf4QrvhZ8E61rRKp4izCGw/RkWtqrNNZn QSZvruvsRwAGKDedeoHflYo+X8A9t7TIFrsA8IHu95zu87HhkBPBpZK63pvAfQ== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1790387369; b=nFevWbIOYDE/UcZoBY4K9rPbp5GgRGAX1Bu7r3jngHraUlJ+N5J7jEzb1TwdhvZagCzUeM fnXa7PUXaq1ymGCBqz0I1agztmo1/BH1KAGzxIZc/jxZlYoNz6RRsfytdBd9H32bylqU13 LVQ6bf1bzeGfwXxrtRr25c6nCT+YJnYV+0X+75ImxtGevN4zxr02NX+yZmMhoSKwSkVXRv sCESiIGqzaIBUnZrOB/ge5WRtfZfKyQcHcOsIdrtkYM6Dv1dRaqqcCwBpWwa1TFG+z8Uvn 7l84UkPYgjpni53DwS+JcjXns3l6FCTfmAp075l8cRT6ZSdbTVfbTLfElr/6PQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1790387369; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=BVaAref54/sLafz132vmx8J6dO84AW74ynsFkjResXQ=; b=x1GkDClBFWmduet5o1vig21NQlbFmoK0r2pZv6leRLBgw9AGzqR1v1GyN67JnyUEvCd+r2 QGdsFuvMFLZGCtjvJgnxy9UUU4jDmG7PrTdAL3hOuUM9A7BYpetxtlh0pvZd9B4h/Y+Pu8 fbfgOibcO796FPPnbdiw+hk8iNQ0tWZxtn/at8hmqIWxB15G5On8CACYfifQU4tJMR8kO7 0ReThZhMrUrhAbOYIJB12fw73psRhbr8hcge7djfA2TecXp2UybARxdKg4qEt0TYZcL4VS 9llHI+soFZsWw6Y06evIKZ8A/svxlmOGTNEWft2OK739qGuAL/OU1V5B1RfBKQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hs9VK40J5zcFT for ; Sat, 26 Sep 2026 01:49:29 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 35d0e by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sat, 26 Sep 2026 01:49:24 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Xin LI Subject: git: c7bcccbb669e - stable/14 - MFC: MFV: less v710. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: delphij X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: c7bcccbb669ee9900bf13c6ecbf42daa9d5d1f82 Auto-Submitted: auto-generated Date: Sat, 26 Sep 2026 01:49:24 +0000 Message-Id: <6ab724a4.35d0e.c43c468@gitrepo.freebsd.org> The branch stable/14 has been updated by delphij: URL: https://cgit.FreeBSD.org/src/commit/?id=c7bcccbb669ee9900bf13c6ecbf42daa9d5d1f82 commit c7bcccbb669ee9900bf13c6ecbf42daa9d5d1f82 Author: Xin LI AuthorDate: 2026-09-19 18:20:29 +0000 Commit: Xin LI CommitDate: 2026-09-26 01:48:17 +0000 MFC: MFV: less v710. (cherry picked from commit 4523eebc6c1828d4fd41d7f1ab943cf079043bc8) --- ObsoleteFiles.inc | 4 + UPDATING | 21 ++ contrib/less/NEWS | 81 +++++ contrib/less/brac.c | 17 +- contrib/less/ch.c | 46 ++- contrib/less/charset.c | 47 +-- contrib/less/cmd.h | 13 +- contrib/less/cmdbuf.c | 33 +- contrib/less/command.c | 228 ++++++++---- contrib/less/decode.c | 371 ++++++++++++------- contrib/less/edit.c | 48 +-- contrib/less/filename.c | 133 +++++-- contrib/less/forwback.c | 11 +- contrib/less/funcs.h | 43 +-- contrib/less/help.c | 6 +- contrib/less/ifile.c | 9 +- contrib/less/input.c | 14 +- contrib/less/jump.c | 23 +- contrib/less/less.h | 16 +- contrib/less/less.hlp | 4 + contrib/less/less.nro | 238 ++++++++---- contrib/less/lessecho.nro | 67 +++- contrib/less/lesskey.c | 364 ------------------- contrib/less/lesskey.h | 22 -- contrib/less/lesskey.nro | 120 +++--- contrib/less/lesskey_parse.c | 83 +++-- contrib/less/lessmsg | 372 +++++++++++++++++++ contrib/less/lessmsg.inc | 331 +++++++++++++++++ contrib/less/lessmsg_int | 5 + contrib/less/line.c | 106 ++++-- contrib/less/linenum.c | 6 +- contrib/less/lmsg.c | 218 +++++++++++ contrib/less/lmsg.h | 24 ++ contrib/less/lsystem.c | 124 ++++--- contrib/less/main.c | 66 ++-- contrib/less/mark.c | 40 +- contrib/less/optfunc.c | 157 ++++---- contrib/less/option.c | 59 +-- contrib/less/option.h | 1 + contrib/less/opttbl.c | 622 ++++++++++++++++++-------------- contrib/less/os.c | 2 +- contrib/less/output.c | 67 ++-- contrib/less/pattern.c | 41 ++- contrib/less/pattern.h | 15 +- contrib/less/pckeys.h | 11 +- contrib/less/prompt.c | 39 +- contrib/less/screen.c | 510 ++++++++++++++------------ contrib/less/search.c | 104 +++--- contrib/less/signal.c | 10 +- contrib/less/tags.c | 20 +- contrib/less/ttyin.c | 8 + contrib/less/version.c | 20 +- targets/pseudo/userland/Makefile.depend | 1 - usr.bin/Makefile | 1 - usr.bin/less/Makefile | 5 +- usr.bin/less/Makefile.common | 5 +- usr.bin/lesskey/Makefile | 7 - usr.bin/lesskey/Makefile.depend | 15 - 58 files changed, 3274 insertions(+), 1800 deletions(-) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index d4c05005f5a2..5b7648b78e6d 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -51,6 +51,10 @@ # xargs -n1 | sort | uniq -d; # done +# 20260925: lesskey(1) removed, lesskey(5) man page added +OLD_FILES+=usr/bin/lesskey +OLD_FILES+=usr/share/man/man1/lesskey.1.gz + # 20260602: Removed by 0a36787e4c1f on 20210723 OLD_FILES+=usr/share/locale/hr_HR.ISO8859-2/LC_MESSAGES OLD_FILES+=usr/share/locale/nl_BE.ISO8859-1/LC_MESSAGES diff --git a/UPDATING b/UPDATING index 0e3fd5317bb0..443af136201c 100644 --- a/UPDATING +++ b/UPDATING @@ -12,6 +12,27 @@ Items affecting the ports and packages system can be found in /usr/ports/UPDATING. Please read that file before updating system packages and/or ports. +20260925: + less(1) has been updated to version 710, which removes the obsolete + lesskey(1) utility. It is no longer built or installed, and the + manual page describing the lesskey file format has moved from + lesskey(1) to lesskey(5). + + No separate compilation step is needed any more: less(1) has been + able to read plain-text lesskey files directly since version 590, + imported into FreeBSD in 2021. Keep your key bindings in the + plain-text ~/.lesskey (or the file named by $LESSKEYIN) rather than + compiling them into the binary ~/.less; system-wide bindings belong + in /etc/syslesskey (or $LESSKEYIN_SYSTEM) rather than /etc/sysless. + If both forms are present, the plain-text one is used and the binary + one is ignored. + + Existing binary lesskey files are still read, so nothing stops + working immediately, but they can no longer be generated or + regenerated. Binary files produced by lesskey from less 240 or + older are no longer supported at all and must be rewritten in the + plain-text format. + 20260727: The wait_for_pids() function in rc.subr, used by rc scripts when stopping or restarting a service, has been modified to diff --git a/contrib/less/NEWS b/contrib/less/NEWS index a031353acf46..49c4a5c0f317 100644 --- a/contrib/less/NEWS +++ b/contrib/less/NEWS @@ -9,6 +9,87 @@ Report bugs, suggestions or comments at https://github.com/gwsw/less/issues. +====================================================================== + + Major changes between "less" versions 704 and 710 + +* Add || command. + +* In | and || commands, ^N allows entering line number instead of mark letter. + +* Add "ESC-]" / "ESC-RIGHTARROW" (right-limit-scroll) command (github #783). + +* In lesskey files, add \k^x syntax for control chars and \k+x syntax + for shifted chars. + +* Underline OSC 8 links in text. + +* Add -DO for custom coloring of OSC 8 links. + +* Add LESSMSG, which allows translation of messages into other languages. + +* Add LESSSECURE_DISALLOW. + +* Add LESS_SHELL_COPTION. + +* Add %G, %y, and %% in prompt strings. + +* Add lesskey support for shift-uparrow, shift-downarrow, shift-pageup, + shift-pagedown, ctl-uparrow, ctl-downarrow, ctl-pageup, ctl-pagedown, + shift-delete. + +* Change "make check" to use nonstandard object and binary file names, + to avoid accidentally installing test binaries (github #791). + +* Fix issues on systems with volatile getenv return values. + +* Improve error handling for malformed binary lesskey file. + +* Improve messaging when using __mouse after --emouse (github #808). + +* Remove support for obsolete pre-241 lesskey binary format. + +* Remove obsolete lesskey program. + +* Move lesskey man page to section 5. + +* Update display when resize window while in F mode on Windows. + +* Fix missing "END" message at end of &-filtered output (github #774). + +* Fix missing bell with G command at end of &-filtered output (github #774). + +* Don't reset signal handlers in a subprocess on Windows. + +* Fix ' command to not modify the mark when given a numeric argument + (github #799). + +* Fix erroneous message from --rscroll command when rscroll char is non-ASCII. + +* Fix unexpected exit when TERM is invalid (github #809). + +* Fix possible crash when use ":e #" after ":d" (github #810). + +* Fix infinite loop if invalid option letter in LESS_UNSUPPORT. + +* Fix crash if run !! command with no previous ! command (github #812). + +* Fix inability to run a shell command starting with "!" character. + +* Fix bugs using ^S search modifier (github #814). + +* Fix display bugs when a status message contains non-ASCII chars + or is displayed on a very narrow screen (github #816). + +* Fix bug defining command which has a built-in command as a prefix + (github #795). + +* Fix string overrrun if input contains "\e\0". + +* Fix memory leak when using ${...} in lesskey file. + +* Fix status column display when long line is marked (github #820). + ====================================================================== Major changes between "less" versions 702 and 704 diff --git a/contrib/less/brac.c b/contrib/less/brac.c index b3b74e07d18a..deaedb187b3c 100644 --- a/contrib/less/brac.c +++ b/contrib/less/brac.c @@ -23,12 +23,12 @@ * The characters which serve as "open bracket" and * "close bracket" are given. */ -public void match_brac(char obrac, char cbrac, int forwdir, int n) +public void match_brac(char obrac, char cbrac, lbool forwdir, int n) { int c; int nest; POSITION pos; - int (*chget)(); + int (*chget)(void); extern int ch_forw_get(), ch_back_get(); @@ -41,9 +41,9 @@ public void match_brac(char obrac, char cbrac, int forwdir, int n) if (pos == NULL_POSITION || ch_seek(pos)) { if (forwdir) - error("Nothing in top line", NULL_PARG); + error(LM(Nothing_in_top_line), NULL_PARG); else - error("Nothing in bottom line", NULL_PARG); + error(LM(Nothing_in_bottom_line), NULL_PARG); return; } @@ -55,9 +55,9 @@ public void match_brac(char obrac, char cbrac, int forwdir, int n) if ((c = ch_forw_get()) == '\n' || c == EOI) { if (forwdir) - error("No bracket in top line", NULL_PARG); + error(LM(No_bracket_in_top_line), NULL_PARG); else - error("No bracket in bottom line", NULL_PARG); + error(LM(No_bracket_in_bottom_line), NULL_PARG); return; } } while (c != obrac || --n > 0); @@ -83,8 +83,7 @@ public void match_brac(char obrac, char cbrac, int forwdir, int n) if (nest == INT_MAX) break; nest++; - } - else if (c == cbrac && --nest < 0) + } else if (c == cbrac && --nest < 0) { /* * Found the matching bracket. @@ -95,5 +94,5 @@ public void match_brac(char obrac, char cbrac, int forwdir, int n) return; } } - error("No matching bracket", NULL_PARG); + error(LM(No_matching_bracket), NULL_PARG); } diff --git a/contrib/less/ch.c b/contrib/less/ch.c index dfe1e7169f72..beda45895c52 100644 --- a/contrib/less/ch.c +++ b/contrib/less/ch.c @@ -124,8 +124,8 @@ extern int autobuf; extern int sigs; extern int follow_mode; extern lbool waiting_for_data; -extern constant char helpdata[]; -extern constant int size_helpdata; +extern constant char *help_data; +extern constant int size_help_data; extern IFILE curr_ifile; #if LOGFILE extern int logfile; @@ -256,7 +256,7 @@ static int ch_get(void) return ('?'); if (less_lseek(ch_file, (less_off_t)pos, SEEK_SET) == BAD_LSEEK) { - error("seek error", NULL_PARG); + error(LM(seek_error), NULL_PARG); clear_eol(); return (EOI); } @@ -275,10 +275,12 @@ static int ch_get(void) ch_have_ungotchar = FALSE; } else if (ch_flags & CH_HELPFILE) { - bp->data[bp->datasize] = (unsigned char) helpdata[ch_fpos]; + bp->data[bp->datasize] = (unsigned char) help_data[ch_fpos]; n = 1; } else { + if (ch_file < 0) + return (EOI); n = iread(ch_file, &bp->data[bp->datasize], LBUFSIZE - bp->datasize); } @@ -324,7 +326,22 @@ static int ch_get(void) /* Either end of file or no data available. * read_again indicates the latter. */ if (!read_again) + { ch_fsize = pos; + if (ch_flags & CH_POPENED) + { + /* + * ch_file is a pipe from a LESSOPEN child program. + * Since we've read to EOF, the child should have exited. + * Close the pipe now so the child does not remain a + * zombie. This also reports any error status from the + * child if -show-preproc-errors is enabled. + */ + close_pipe(get_altpipe(curr_ifile)); + set_altpipe(curr_ifile, NULL); + ch_file = -1; + } + } if (ignore_eoi || read_again) { /* Wait a while, then try again. */ @@ -388,7 +405,7 @@ public void ch_ungetchar(int c) else { if (ch_have_ungotchar) - error("ch_ungetchar overrun", NULL_PARG); + error(LM(ch_ungetchar_overrun), NULL_PARG); ch_ungotchar = (unsigned char) c; ch_have_ungotchar = TRUE; } @@ -408,7 +425,7 @@ public void end_logfile(void) if (!tried && ch_fsize == NULL_POSITION) { tried = TRUE; - ierror("Finishing logfile", NULL_PARG); + ierror(LM(Finishing_logfile), NULL_PARG); while (ch_forw_get() != EOI) if (ABORT_SIGS()) break; @@ -454,8 +471,7 @@ public void sync_logfile(void) } if (!wrote && !warned) { - error("Warning: log file is incomplete", - NULL_PARG); + error(LM(log_file_is_incomplete), NULL_PARG); warned = TRUE; } } @@ -614,7 +630,7 @@ public POSITION ch_length(void) if (ignore_eoi) return (NULL_POSITION); if (ch_flags & CH_HELPFILE) - return (size_helpdata); + return (size_help_data); if (ch_flags & CH_NODATA) return (0); return (ch_fsize); @@ -745,7 +761,7 @@ public void ch_flush(void) ch_flags &= ~CH_CANSEEK; } else { - ch_fsize = (ch_flags & CH_HELPFILE) ? size_helpdata : filesize(ch_file); + ch_fsize = (ch_flags & CH_HELPFILE) ? size_help_data : filesize(ch_file); } if (less_lseek(ch_file, (less_off_t)0, SEEK_SET) == BAD_LSEEK) @@ -755,7 +771,7 @@ public void ch_flush(void) * there's a good chance we're at the beginning anyway. * {{ I think this is bogus reasoning. }} */ - error("seek error to 0", NULL_PARG); + error(LM(seek_error_to_0), NULL_PARG); } } @@ -818,7 +834,7 @@ static void ch_delbufs(void) /* * Is it possible to seek on a file descriptor? */ -public int seekable(int f) +public lbool seekable(int f) { #if MSDOS_COMPILER extern int fd0; @@ -828,7 +844,7 @@ public int seekable(int f) * In MS-DOS, pipes are seekable. Check for * standard input, and pretend it is not seekable. */ - return (0); + return (FALSE); } #endif return (less_lseek(f, (less_off_t)1, SEEK_SET) != BAD_LSEEK); @@ -883,7 +899,7 @@ public void ch_init(int f, int flags, ssize_t nread) /* * Figure out the size of the file, if we can. */ - ch_fsize = (flags & CH_HELPFILE) ? size_helpdata : filesize(ch_file); + ch_fsize = (flags & CH_HELPFILE) ? size_help_data : filesize(ch_file); if (ch_fsize == 0 && nread > 0) { @@ -924,7 +940,7 @@ public void ch_close(void) * But don't really close it if it was opened via popen(), * because pclose() wants to close it. */ - if (!(ch_flags & (CH_POPENED|CH_HELPFILE))) + if (ch_file >= 0 && !(ch_flags & (CH_POPENED|CH_HELPFILE))) close(ch_file); ch_file = -1; } else diff --git a/contrib/less/charset.c b/contrib/less/charset.c index f2020e4ef5c5..9447a8dcff24 100644 --- a/contrib/less/charset.c +++ b/contrib/less/charset.c @@ -191,12 +191,12 @@ static void ichardef_utf(constant char *s) wchar_range_get(&s, &range); if (range.last == 0) { - error("invalid hex number(s) in LESSUTFCHARDEF", NULL_PARG); + error(LM(invalid_hex_number_in_LESSUTFCHARDEF), NULL_PARG); quit(QUIT_ERROR); } if (*s++ != ':') { - error("missing colon in LESSUTFCHARDEF", NULL_PARG); + error(LM(missing_colon_in_LESSUTFCHARDEF), NULL_PARG); quit(QUIT_ERROR); } switch (*s++) @@ -279,7 +279,7 @@ static void ichardef(constant char *s) default: invalid_chardef: - error("invalid chardef", NULL_PARG); + error(LM(invalid_chardef), NULL_PARG); quit(QUIT_ERROR); /*NOTREACHED*/ } @@ -288,7 +288,7 @@ static void ichardef(constant char *s) { if (cp >= chardef + sizeof(chardef)) { - error("chardef longer than 256", NULL_PARG); + error(LM(chardef_longer_than_256), NULL_PARG); quit(QUIT_ERROR); /*NOTREACHED*/ } @@ -305,7 +305,7 @@ static void ichardef(constant char *s) * Define a charset, given a charset name. * The valid charset names are listed in the "charsets" array. */ -static int icharset(constant char *name, int no_error) +static int icharset(constant char *name, lbool no_error) { struct charset *p; struct cs_alias *a; @@ -341,7 +341,7 @@ static int icharset(constant char *name, int no_error) } if (!no_error) { - error("invalid charset name", NULL_PARG); + error(LM(invalid_charset_name), NULL_PARG); quit(QUIT_ERROR); } return (0); @@ -353,9 +353,9 @@ static int icharset(constant char *name, int no_error) */ static void ilocale(void) { - int c; + size_t c; - for (c = 0; c < (int) sizeof(chardef); c++) + for (c = 0; c < sizeof(chardef); c++) { if (isprint(c)) chardef[c] = 0; @@ -411,7 +411,7 @@ static void set_charset(void) * See if environment variable LESSCHARSET is defined. */ s = lgetenv("LESSCHARSET"); - if (icharset(s, 0)) + if (icharset(s, FALSE)) return; /* @@ -438,7 +438,7 @@ static void set_charset(void) #endif { s = nl_langinfo(CODESET); - if (icharset(s, 1)) + if (icharset(s, TRUE)) return; } #endif @@ -453,7 +453,7 @@ static void set_charset(void) { if ( strstr(s, "UTF-8") != NULL || strstr(s, "utf-8") != NULL || strstr(s, "UTF8") != NULL || strstr(s, "utf8") != NULL) - if (icharset("utf-8", 1)) + if (icharset("utf-8", TRUE)) return; } @@ -466,12 +466,12 @@ static void set_charset(void) #else #if MSDOS_COMPILER #if MSDOS_COMPILER==WIN32C - (void) icharset("utf-8", 1); + (void) icharset("utf-8", TRUE); #else - (void) icharset("dos", 1); + (void) icharset("dos", TRUE); #endif #else - (void) icharset("utf-8", 1); + (void) icharset("utf-8", TRUE); #endif #endif } @@ -527,7 +527,7 @@ public constant char * prchar(LWCHAR c) /* {{ Fixed buffer size means LESSBINFMT etc can be truncated. }} */ static char buf[MAX_PRCHAR_LEN+1]; - c &= 0377; /*{{type-issue}}*/ + c = (unsigned char) c; /* {{ parameter is interpreted as a byte }} */ if ((c < 128 || !utf_mode) && !control_char(c)) SNPRINTF1(buf, sizeof(buf), "%c", (int) c); else if (c == ESC) @@ -617,27 +617,28 @@ public lbool is_utf8_well_formed(constant char *ssa, int slen) unsigned char s0 = ss[0]; if (IS_UTF8_LEAD5(s0) || IS_UTF8_LEAD6(s0) || IS_UTF8_INVALID(s0)) - return (FALSE); + return (FALSE); /* invalid lead byte */ len = utf_len(s0); if (len > slen) - return (FALSE); + return (FALSE); /* UTF-8 sequence doesn't fit in buffer */ if (len == 1) return (TRUE); if (len == 2) { if (s0 < 0xC2) - return (FALSE); + return (FALSE); /* overlong (fits in 1 byte) */ } else { + /* mask = byte with len high-order bits set to 1, others 0 */ unsigned char mask = (unsigned char) (~((1 << (8-len)) - 1)); if (s0 == mask && (ss[1] & mask) == 0x80) - return (FALSE); + return (FALSE); /* overlong (fits in fewer bytes) */ } for (i = 1; i < len; i++) if (!IS_UTF8_TRAIL(ss[i])) - return (FALSE); + return (FALSE); /* not a continuation byte */ return (TRUE); } @@ -651,7 +652,6 @@ public void utf_skip_to_lead(constant char **pp, constant char *limit) } while (*pp < limit && !IS_UTF8_LEAD((*pp)[0] & 0377) && !IS_ASCII_OCTET((*pp)[0])); } - /* * Get the value of a UTF-8 character. */ @@ -755,7 +755,8 @@ public void put_wchar(mutable char **pp, LWCHAR ch) } /* - * Step forward or backward one character in a string. + * Step forward (dir > 0) or backward (dir < 0) one character in a string. + * If dir > 0, limit is end of string; if dir < 0, limit is start of string. */ public LWCHAR step_charc(constant char **pp, signed int dir, constant char *limit) { @@ -779,6 +780,7 @@ public LWCHAR step_charc(constant char **pp, signed int dir, constant char *limi len = utf_len(*p); if (p + len > limit || !is_utf8_well_formed(p, len)) { + /* Invalid UTF-8 sequence; just take the next byte as a character. */ ch = (LWCHAR) (unsigned char) *p++; } else { @@ -797,6 +799,7 @@ public LWCHAR step_charc(constant char **pp, signed int dir, constant char *limi len = utf_len(*--p); if (p + len != *pp || !is_utf8_well_formed(p, len)) { + /* Invalid UTF-8 sequence; just take the next byte as a character. */ p = *pp - 1; ch = (LWCHAR) (unsigned char) *p; } else diff --git a/contrib/less/cmd.h b/contrib/less/cmd.h index fb66a6adb99d..97d51ab9b7f9 100644 --- a/contrib/less/cmd.h +++ b/contrib/less/cmd.h @@ -89,6 +89,7 @@ #define A_F_FOREVER_BELL 77 #define A_L_MOUSE 78 #define A_R_MOUSE 79 +#define A_RSHIFT_LIMIT 80 /* These values must not conflict with any A_* or EC_* value. */ #define A_INVALID 100 @@ -180,6 +181,14 @@ #define SK_CTL_END 37 #define SK_SHIFT_LEFT_ARROW 38 #define SK_SHIFT_RIGHT_ARROW 39 -#define SK_PAD_ENTER 41 - #define SK_CONTROL_K 40 +#define SK_PAD_ENTER 41 +#define SK_SHIFT_UP_ARROW 42 +#define SK_SHIFT_DOWN_ARROW 43 +#define SK_CTL_UP_ARROW 44 +#define SK_CTL_DOWN_ARROW 45 +#define SK_SHIFT_DELETE 46 +#define SK_SHIFT_PAGE_UP 47 +#define SK_SHIFT_PAGE_DOWN 48 +#define SK_CTL_PAGE_UP 49 +#define SK_CTL_PAGE_DOWN 50 diff --git a/contrib/less/cmdbuf.c b/contrib/less/cmdbuf.c index 9f13473eba03..5c6600f9c49c 100644 --- a/contrib/less/cmdbuf.c +++ b/contrib/less/cmdbuf.c @@ -358,7 +358,7 @@ static void cmd_lshift(void) s = ns; } - cmd_offset = (int) (s - cmdbuf); + cmd_offset = (int) ptr_diff(s, cmdbuf); save_cp = cp; cmd_home(); cmd_repaint(save_cp); @@ -387,7 +387,7 @@ static void cmd_rshift(void) cols += width; } - cmd_offset = (int) (s - cmdbuf); + cmd_offset = (int) ptr_diff(s, cmdbuf); save_cp = cp; cmd_home(); cmd_repaint(save_cp); @@ -479,7 +479,7 @@ static int cmd_erase(void) */ s = cp; cmd_left(); - clen = (int) (s - cp); + clen = (int) ptr_diff(s, cp); /* * Remove the char from the buffer (shift the buffer left). @@ -993,10 +993,12 @@ static int cmd_istr(constant char *str) */ static void set_tk_original(constant char *word) { + size_t len = ptr_diff(cp, word); if (tk_original != NULL) free(tk_original); - tk_original = (char *) ecalloc(ptr_diff(cp,word)+1, sizeof(char)); - strncpy(tk_original, word, ptr_diff(cp,word)); + tk_original = (char *) ecalloc(len+1, sizeof(char)); + strncpy(tk_original, word, len); + tk_original[len] = '\0'; } #if TAB_COMPLETE_FILENAME @@ -1418,15 +1420,18 @@ public LINENUM cmd_int(mutable long *frac) { if (ckd_mul(&n, n, 10) || ckd_add(&n, n, *p - '0')) { - error("Integer is too big", NULL_PARG); + error(LM(Integer_is_too_big), NULL_PARG); return (0); } } - *frac = 0; - if (*p++ == '.') + if (frac != NULL) { - /* {{ Just ignore error in fractional part. }} */ - (void) getfraction(&p, frac); + *frac = 0; + if (*p++ == '.') + { + /* {{ Just ignore error in fractional part. }} */ + (void) getfraction(&p, frac); + } } return (n); } @@ -1481,7 +1486,7 @@ static char * histfile_find(lbool must_exist) name = dirfile(lgetenv("XDG_STATE_HOME"), &LESSHISTFILE[1], must_exist); if (name == NULL) { - char *dir = dirfile(home, ".local/state", 1); + char *dir = dirfile(home, ".local/state", TRUE); if (dir != NULL) { name = dirfile(dir, &LESSHISTFILE[1], must_exist); @@ -1606,7 +1611,7 @@ static void addhist_init(void *uparam, struct mlist *ml, constant char *string) { (void) uparam; if (ml != NULL) - cmd_addhist(ml, string, 0); + cmd_addhist(ml, string, FALSE); else if (string != NULL) restore_mark(string); } @@ -1721,8 +1726,8 @@ static void make_file_private(FILE *f) #if HAVE_FCHMOD lbool do_chmod = TRUE; #if HAVE_STAT - struct stat statbuf; - int r = fstat(fileno(f), &statbuf); + less_stat_t statbuf; + int r = less_fstat(fileno(f), &statbuf); if (r < 0 || !S_ISREG(statbuf.st_mode)) /* Don't chmod if not a regular file. */ do_chmod = FALSE; diff --git a/contrib/less/command.c b/contrib/less/command.c index 09eb1614c76d..cba6117c4f6f 100644 --- a/contrib/less/command.c +++ b/contrib/less/command.c @@ -38,7 +38,7 @@ extern int hshift; extern int bs_mode; extern int proc_backspace; extern int show_attn; -extern int less_is_more; +extern lbool less_is_more; extern int chopline; extern POSITION highest_hilite; extern char *every_first_cmd; @@ -103,7 +103,8 @@ static int search_incr_hshift; static time_type ignoring_input_time; #endif #if PIPEC -static char pipec; +static POSITION pipe_pos1; +static POSITION pipe_pos2; #endif /* Stack of ungotten chars (via ungetcc) */ @@ -181,28 +182,34 @@ static void mca_search1(void) set_mca(A_B_SEARCH); if (search_type & SRCH_NO_MATCH) - cmd_putstr("Non-match "); + cmd_putstr(LM(Non_match)); if (search_type & SRCH_FIRST_FILE) - cmd_putstr("First-file "); + cmd_putstr(LM(First_file)); if (search_type & SRCH_PAST_EOF) - cmd_putstr("EOF-ignore "); + cmd_putstr(LM(EOF_ignore)); if (search_type & SRCH_NO_MOVE) - cmd_putstr("Keep-pos "); + cmd_putstr(LM(Keep_pos)); if (search_type & SRCH_NO_REGEX) - cmd_putstr("Regex-off "); + cmd_putstr(LM(Regex_off)); if (search_type & SRCH_WRAP) - cmd_putstr("Wrap "); + cmd_putstr(LM(Wrap)); for (i = 1; i <= NUM_SEARCH_COLORS; i++) { if (search_type & SRCH_SUBSEARCH(i)) { - char buf[INT_STRLEN_BOUND(int)+8]; - SNPRINTF1(buf, sizeof(buf), "Sub-%d ", i); + static char *buf = NULL; + static size_t buflen; + if (buf == NULL) + { + buflen = INT_STRLEN_BOUND(int)+strlen(LM(Sub_X)+1); + buf = ecalloc(buflen, sizeof(char)); + } + SNPRINTF1(buf, buflen, LM(Sub_X), i); cmd_putstr(buf); } } if (literal_char) - cmd_putstr("Lit "); + cmd_putstr(LM(Lit)); #if HILITE_SEARCH if (search_type & SRCH_FILTER) @@ -300,10 +307,10 @@ static void exec_mca(void) curropt = NULL; break; case A_F_BRACKET: - match_brac(cbuf[0], cbuf[1], 1, (int) number); + match_brac(cbuf[0], cbuf[1], TRUE, (int) number); break; case A_B_BRACKET: - match_brac(cbuf[1], cbuf[0], 0, (int) number); + match_brac(cbuf[1], cbuf[0], FALSE, (int) number); break; #if EXAMINE case A_EXAMINE: { @@ -329,7 +336,7 @@ static void exec_mca(void) constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "!done"; if (done_msg == NULL) ++cbuf; - if (*cbuf != '!') + if (strcmp(cbuf, "!") != 0) { if (shellcmd != NULL) free(shellcmd); @@ -337,9 +344,7 @@ static void exec_mca(void) } if (!secure_allow(SF_SHELL)) break; - if (shellcmd == NULL) - shellcmd = ""; - lsystem(shellcmd, done_msg); + lsystem(shellcmd == NULL ? "" : shellcmd, done_msg); break; } case A_PSHELL: { constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "#done"; @@ -357,7 +362,7 @@ static void exec_mca(void) ++cbuf; if (!secure_allow(SF_PIPE)) break; - (void) pipe_mark(pipec, cbuf); + (void) pipe_pos(cbuf, pipe_pos1, pipe_pos2); if (done_msg != NULL) error(done_msg, NULL_PARG); break; } @@ -513,7 +518,7 @@ static int mca_opt_char(char c) parg.p_string = get_cmdbuf(); if (parg.p_string == NULL) return (MCA_MORE); - error("There is no --%s option", &parg); + error(LM(There_is_no__X_option), &parg); return (MCA_DONE); } optgetname = FALSE; @@ -529,7 +534,7 @@ static int mca_opt_char(char c) if (curropt == NULL) { parg.p_string = propt(c); - error("There is no %s option", &parg); + error(LM(There_is_no_X_option), &parg); return (MCA_DONE); } opt_lower = ASCII_IS_LOWER(c); @@ -608,8 +613,14 @@ static int mca_search_char(char c) flag = SRCH_NO_MOVE; break; case CONTROL('S'): { /* SUBSEARCH */ - char buf[INT_STRLEN_BOUND(int)+24]; - SNPRINTF1(buf, sizeof(buf), "Sub-pattern (1-%d):", NUM_SEARCH_COLORS); + static char *buf = NULL; + static size_t buflen; + if (buf == NULL) + { + buflen = INT_STRLEN_BOUND(int)+strlen(LM(Sub_pattern_1_X))+1; + buf = ecalloc(buflen, sizeof(char)); + } + SNPRINTF1(buf, buflen, LM(Sub_pattern_1_X), NUM_SEARCH_COLORS); clear_bot(); cmd_putstr(buf); flush(); @@ -890,15 +901,15 @@ static void prompt_message(void) { if (read_error) { - error("read error", NULL_PARG); + error(LM(read_error), NULL_PARG); read_error = FALSE; } if (search_wrapped) { if (search_type & SRCH_BACK) - error("Search hit top; continuing at bottom", NULL_PARG); + error(LM(Search_hit_top), NULL_PARG); else - error("Search hit bottom; continuing at top", NULL_PARG); + error(LM(Search_hit_bottom), NULL_PARG); search_wrapped = FALSE; } #if OSC8_LINK @@ -906,7 +917,7 @@ static void prompt_message(void) { PARG parg; parg.p_string = osc8_uri; - error("Link: %s", &parg); + error(LM(Link_X), &parg); free(osc8_uri); osc8_uri = NULL; } @@ -1328,9 +1339,9 @@ static void multi_search(constant char *pattern, int n, int silent) PARG parg; parg.p_string = prev_pattern_text(); if (parg.p_string == NULL) /* {{ can this happen? }} */ - error("Pattern not found", NULL_PARG); + error(LM(Pattern_not_found), NULL_PARG); else - error("Pattern not found: %s", &parg); + error(LM(Pattern_not_found_X), &parg); } if (changed_file) @@ -1425,6 +1436,72 @@ public lbool is_ignoring_input(int action) return (action != A_PREFIX); } +#if PIPEC +/* + * Read a mark char or line number from the user for use by the pipe command. + * If mark_char != NULL, accept *mark_char as well as the normal mark chars. + * Also return the entered mark char in *mark_char. + */ +static POSITION get_pipe_pos(constant char *mark_msg, constant char *line_msg, mutable char *mark_char) +{ + lbool get_line = FALSE; + char spec_char = '\0'; + char c; + + start_mca(A_PIPE, mark_msg, NULL, 0); + if (mark_char != NULL) + { + spec_char = *mark_char; + *mark_char = '\0'; + } + for (;;) + { + c = getcc(); + if (spec_char != '\0' && c == spec_char) + { + *mark_char = c; + return NULL_POSITION; + } + if (c == CONTROL('N')) /* toggle between reading mark and line number */ + { + get_line = !get_line; + cmd_reset(); + start_mca(A_PIPE, get_line ? line_msg : mark_msg, NULL, 0); + } else if (get_line) /* reading line number */ + { + if ((c >= '0' && c <= '9') || is_erase_char(c)) + { + if (cmd_char(c) == CC_QUIT) + return NULL_POSITION; + } else if (is_newline_char(c)) + { + POSITION pos; + LINENUM lnum = cmd_int(NULL); + cmd_reset(); + if (lnum == 0 || (pos = find_pos(lnum)) == NULL_POSITION) + { + error(LM(Invalid_line_number), NULL_PARG); + return NULL_POSITION; + } + return pos; + } else + lbell(); + } else /* reading mark char */ + { + if (is_erase_char(c)) + return NULL_POSITION; + if (is_newline_char(c)) + c = '.'; + if (badmark(c)) + return NULL_POSITION; + if (mark_char != NULL) *** 8772 LINES SKIPPED ***