MFV: less v632.

MFC after:	2 weeks
This commit is contained in:
Xin LI 2023-05-01 20:43:57 -07:00
commit d713e0891f
61 changed files with 3729 additions and 3631 deletions

View File

@ -2,7 +2,7 @@
------------ ------------
Less Less
Copyright (C) 1984-2022 Mark Nudelman Copyright (C) 1984-2023 Mark Nudelman
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions

View File

@ -9,6 +9,77 @@
Report bugs, suggestions or comments at Report bugs, suggestions or comments at
https://github.com/gwsw/less/issues. https://github.com/gwsw/less/issues.
======================================================================
Major changes between "less" versions 608 and 632
* Add LESSUTFCHARDEF environment variable (github #275).
* Add # command (github #330).
* Add ^S search modifier (github #196).
* Add --wordwrap option (github #113).
* Add --no-vbell option (github #304).
* Add --no-search-headers option (github #44).
* Add --modelines option (github #89).
* Add --intr option (github #224).
* Add --proc-backspace, --proc-tab and --proc-return options (github #335).
* Add --show-preproc-errors option (github #258).
* Add LESS_LINES and LESS_COLUMNS environment variables (github #84).
* Add LESS_DATA_DELAY environment variable (github #337).
* Allow empty "lines" field in --header option.
* Update Unicode tables.
* Improve ability of ^X to interrupt F command (github #49).
* Status column (-J) shows off-screen matches.
* Parenthesized sub-patterns in searches are colored with unique colors,
if supported by the regular expression library (github #196).
* Don't allow opening a tty as file input unless -f is set (github #309).
* Don't require newline input after +&... option (github #339).
* Fix incorrect handling of some Private Use Unicode characters.
* Fix ANSI color bug when overstriking with colored chars (github #276).
* Fix compiler const warning (github #279).
* Fix signal race in iread (github #280).
* Fix reading procfs files on Linux (github #282).
* Fix --ignore-case with ctrl-R (no regex) search (github #300).
* Fix bug doing repeat search after setting & filter (github #299).
* Fix bug doing repeat search before non-repeat search.
* Fix crash with -R and certain line lengths (github #338).
* Fix input of Windows dead keys (github #352).
* Don't retain search options from a cancelled search (github #302).
* Don't call realpath on fake filenames like "-" (github #289).
* Implement lesstest test suite.
* Convert function parameter definitions from K&R to C89 (github #316).
====================================================================== ======================================================================
Major changes between "less" versions 590 and 608 Major changes between "less" versions 590 and 608
@ -241,7 +312,7 @@
* Update Unicode tables to 2017-03-08. * Update Unicode tables to 2017-03-08.
* Pass-thru Unicode formating chars (Cf type) instead of treating them * Pass-thru Unicode formatting chars (Cf type) instead of treating them
as binary chars. But treat them as binary if -U is set. as binary chars. But treat them as binary if -U is set.
* Fix erroneous binary file warning when UTF-8 file contains ANSI SGR sequences. * Fix erroneous binary file warning when UTF-8 file contains ANSI SGR sequences.
@ -433,7 +504,7 @@
* Fix problem interrupting the line number calculation for initial prompt. * Fix problem interrupting the line number calculation for initial prompt.
* Fix SGR emulation when dealing with multiple attributes (eg. bold+underline). * Fix SGR emulation when dealing with multiple attributes (e.g. bold+underline).
* Fix highlight bug when searching for underlined/overstruck text. * Fix highlight bug when searching for underlined/overstruck text.
@ -515,7 +586,7 @@
* The -c option has been made identical with the -C option. * The -c option has been made identical with the -C option.
* Allow "/dev/null" as synomym for "-" in LESSHISTFILE to indicate * Allow "/dev/null" as synonym for "-" in LESSHISTFILE to indicate
that no history file should be used. that no history file should be used.
* Search can now find text which follows a null byte, if the PCRE * Search can now find text which follows a null byte, if the PCRE
@ -665,7 +736,7 @@
* Improved performance in reading very large pipes. * Improved performance in reading very large pipes.
* Eliminated some dependencies on file offets being 32 bits. * Eliminated some dependencies on file offsets being 32 bits.
* Fixed problems when viewing files with very long lines. * Fixed problems when viewing files with very long lines.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -23,12 +23,7 @@
* The characters which serve as "open bracket" and * The characters which serve as "open bracket" and
* "close bracket" are given. * "close bracket" are given.
*/ */
public void public void match_brac(char obrac, char cbrac, int forwdir, int n)
match_brac(obrac, cbrac, forwdir, n)
int obrac;
int cbrac;
int forwdir;
int n;
{ {
int c; int c;
int nest; int nest;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -20,14 +20,11 @@
#include <windows.h> #include <windows.h>
#endif #endif
#if HAVE_STAT_INO
#include <sys/stat.h>
extern dev_t curr_dev;
extern ino_t curr_ino;
#endif
#if HAVE_PROCFS #if HAVE_PROCFS
#include <sys/statfs.h> #include <sys/statfs.h>
#if HAVE_LINUX_MAGIC_H
#include <linux/magic.h>
#endif
#endif #endif
typedef POSITION BLOCKNUM; typedef POSITION BLOCKNUM;
@ -133,6 +130,7 @@ extern int sigs;
extern int secure; extern int secure;
extern int screen_trashed; extern int screen_trashed;
extern int follow_mode; extern int follow_mode;
extern int waiting_for_data;
extern constant char helpdata[]; extern constant char helpdata[];
extern constant int size_helpdata; extern constant int size_helpdata;
extern IFILE curr_ifile; extern IFILE curr_ifile;
@ -147,13 +145,12 @@ static int ch_addbuf();
/* /*
* Get the character pointed to by the read pointer. * Get the character pointed to by the read pointer.
*/ */
int static int ch_get(void)
ch_get(VOID_PARAM)
{ {
struct buf *bp; struct buf *bp;
struct bufnode *bn; struct bufnode *bn;
int n; int n;
int slept; int read_again;
int h; int h;
POSITION pos; POSITION pos;
POSITION len; POSITION len;
@ -172,11 +169,10 @@ ch_get(VOID_PARAM)
return bp->data[ch_offset]; return bp->data[ch_offset];
} }
slept = FALSE;
/* /*
* Look for a buffer holding the desired block. * Look for a buffer holding the desired block.
*/ */
waiting_for_data = FALSE;
h = BUFHASH(ch_block); h = BUFHASH(ch_block);
FOR_BUFS_IN_CHAIN(h, bn) FOR_BUFS_IN_CHAIN(h, bn)
{ {
@ -225,149 +221,139 @@ ch_get(VOID_PARAM)
BUF_HASH_INS(bn, h); /* Insert into new hash chain. */ BUF_HASH_INS(bn, h); /* Insert into new hash chain. */
} }
read_more: for (;;)
pos = (ch_block * LBUFSIZE) + bp->datasize;
if ((len = ch_length()) != NULL_POSITION && pos >= len)
/*
* At end of file.
*/
return (EOI);
if (pos != ch_fpos)
{ {
/* pos = (ch_block * LBUFSIZE) + bp->datasize;
* Not at the correct position: must seek. if ((len = ch_length()) != NULL_POSITION && pos >= len)
* If input is a pipe, we're in trouble (can't seek on a pipe). /*
* Some data has been lost: just return "?". * At end of file.
*/ */
if (!(ch_flags & CH_CANSEEK))
return ('?');
if (lseek(ch_file, (off_t)pos, SEEK_SET) == BAD_LSEEK)
{
error("seek error", NULL_PARG);
clear_eol();
return (EOI); return (EOI);
}
ch_fpos = pos;
}
/* if (pos != ch_fpos)
* Read the block.
* If we read less than a full block, that's ok.
* We use partial block and pick up the rest next time.
*/
if (ch_ungotchar != -1)
{
bp->data[bp->datasize] = ch_ungotchar;
n = 1;
ch_ungotchar = -1;
} else if (ch_flags & CH_HELPFILE)
{
bp->data[bp->datasize] = helpdata[ch_fpos];
n = 1;
} else
{
n = iread(ch_file, &bp->data[bp->datasize],
(unsigned int)(LBUFSIZE - bp->datasize));
}
if (n == READ_INTR)
return (EOI);
if (n < 0)
{
#if MSDOS_COMPILER==WIN32C
if (errno != EPIPE)
#endif
{
error("read error", NULL_PARG);
clear_eol();
}
n = 0;
}
#if LOGFILE
/*
* If we have a log file, write the new data to it.
*/
if (!secure && logfile >= 0 && n > 0)
write(logfile, (char *) &bp->data[bp->datasize], n);
#endif
ch_fpos += n;
bp->datasize += n;
/*
* If we have read to end of file, set ch_fsize to indicate
* the position of the end of file.
*/
if (n == 0)
{
ch_fsize = pos;
if (ignore_eoi)
{ {
/* /*
* We are ignoring EOF. * Not at the correct position: must seek.
* Wait a while, then try again. * If input is a pipe, we're in trouble (can't seek on a pipe).
* Some data has been lost: just return "?".
*/ */
if (!slept) if (!(ch_flags & CH_CANSEEK))
return ('?');
if (lseek(ch_file, (off_t)pos, SEEK_SET) == BAD_LSEEK)
{ {
PARG parg; error("seek error", NULL_PARG);
parg.p_string = wait_message(); clear_eol();
ierror("%s", &parg); return (EOI);
} }
sleep_ms(2); /* Reduce system load */ ch_fpos = pos;
slept = TRUE;
#if HAVE_STAT_INO
if (follow_mode == FOLLOW_NAME)
{
/* See whether the file's i-number has changed,
* or the file has shrunk.
* If so, force the file to be closed and
* reopened. */
struct stat st;
POSITION curr_pos = ch_tell();
int r = stat(get_filename(curr_ifile), &st);
if (r == 0 && (st.st_ino != curr_ino ||
st.st_dev != curr_dev ||
(curr_pos != NULL_POSITION && st.st_size < curr_pos)))
{
/* screen_trashed=2 causes
* make_display to reopen the file. */
screen_trashed = 2;
return (EOI);
}
}
#endif
} }
if (sigs)
/*
* Read the block.
* If we read less than a full block, that's ok.
* We use partial block and pick up the rest next time.
*/
if (ch_ungotchar != -1)
{
bp->data[bp->datasize] = ch_ungotchar;
n = 1;
ch_ungotchar = -1;
} else if (ch_flags & CH_HELPFILE)
{
bp->data[bp->datasize] = helpdata[ch_fpos];
n = 1;
} else
{
n = iread(ch_file, &bp->data[bp->datasize],
(unsigned int)(LBUFSIZE - bp->datasize));
}
read_again = FALSE;
if (n == READ_INTR)
{
ch_fsize = pos;
return (EOI); return (EOI);
} }
if (n == READ_AGAIN)
{
read_again = TRUE;
n = 0;
}
if (n < 0)
{
#if MSDOS_COMPILER==WIN32C
if (errno != EPIPE)
#endif
{
error("read error", NULL_PARG);
clear_eol();
}
n = 0;
}
found: #if LOGFILE
if (ch_bufhead != bn)
{
/* /*
* Move the buffer to the head of the buffer chain. * If we have a log file, write the new data to it.
* This orders the buffer chain, most- to least-recently used.
*/ */
BUF_RM(bn); if (!secure && logfile >= 0 && n > 0)
BUF_INS_HEAD(bn); write(logfile, (char *) &bp->data[bp->datasize], n);
#endif
/* ch_fpos += n;
* Move to head of hash chain too. bp->datasize += n;
*/
BUF_HASH_RM(bn);
BUF_HASH_INS(bn, h);
}
if (ch_offset >= bp->datasize) if (n == 0)
{
/* Either end of file or no data available.
* read_again indicates the latter. */
if (!read_again)
ch_fsize = pos;
if (ignore_eoi || read_again)
{
/* Wait a while, then try again. */
if (!waiting_for_data)
{
PARG parg;
parg.p_string = wait_message();
ixerror("%s", &parg);
waiting_for_data = TRUE;
}
sleep_ms(50); /* Reduce system load */
}
if (ignore_eoi && follow_mode == FOLLOW_NAME && curr_ifile_changed())
{
/* screen_trashed=2 causes make_display to reopen the file. */
screen_trashed = 2;
return (EOI);
}
if (sigs)
return (EOI);
}
found:
if (ch_bufhead != bn)
{
/*
* Move the buffer to the head of the buffer chain.
* This orders the buffer chain, most- to least-recently used.
*/
BUF_RM(bn);
BUF_INS_HEAD(bn);
/*
* Move to head of hash chain too.
*/
BUF_HASH_RM(bn);
BUF_HASH_INS(bn, h);
}
if (ch_offset < bp->datasize)
break;
/* /*
* After all that, we still don't have enough data. * After all that, we still don't have enough data.
* Go back and try again. * Go back and try again.
*/ */
goto read_more; }
return (bp->data[ch_offset]); return (bp->data[ch_offset]);
} }
@ -375,9 +361,7 @@ ch_get(VOID_PARAM)
* ch_ungetchar is a rather kludgy and limited way to push * ch_ungetchar is a rather kludgy and limited way to push
* a single char onto an input file descriptor. * a single char onto an input file descriptor.
*/ */
public void public void ch_ungetchar(int c)
ch_ungetchar(c)
int c;
{ {
if (c != -1 && ch_ungotchar != -1) if (c != -1 && ch_ungotchar != -1)
error("ch_ungetchar overrun", NULL_PARG); error("ch_ungetchar overrun", NULL_PARG);
@ -389,8 +373,7 @@ ch_ungetchar(c)
* Close the logfile. * Close the logfile.
* If we haven't read all of standard input into it, do that now. * If we haven't read all of standard input into it, do that now.
*/ */
public void public void end_logfile(void)
end_logfile(VOID_PARAM)
{ {
static int tried = FALSE; static int tried = FALSE;
@ -415,8 +398,7 @@ end_logfile(VOID_PARAM)
* Invoked from the - command; see toggle_option(). * Invoked from the - command; see toggle_option().
* Write all the existing buffered data to the log file. * Write all the existing buffered data to the log file.
*/ */
public void public void sync_logfile(void)
sync_logfile(VOID_PARAM)
{ {
struct buf *bp; struct buf *bp;
struct bufnode *bn; struct bufnode *bn;
@ -452,9 +434,7 @@ sync_logfile(VOID_PARAM)
/* /*
* Determine if a specific block is currently in one of the buffers. * Determine if a specific block is currently in one of the buffers.
*/ */
static int static int buffered(BLOCKNUM block)
buffered(block)
BLOCKNUM block;
{ {
struct buf *bp; struct buf *bp;
struct bufnode *bn; struct bufnode *bn;
@ -474,9 +454,7 @@ buffered(block)
* Seek to a specified position in the file. * Seek to a specified position in the file.
* Return 0 if successful, non-zero if can't seek there. * Return 0 if successful, non-zero if can't seek there.
*/ */
public int public int ch_seek(POSITION pos)
ch_seek(pos)
POSITION pos;
{ {
BLOCKNUM new_block; BLOCKNUM new_block;
POSITION len; POSITION len;
@ -513,8 +491,7 @@ ch_seek(pos)
/* /*
* Seek to the end of the file. * Seek to the end of the file.
*/ */
public int public int ch_end_seek(void)
ch_end_seek(VOID_PARAM)
{ {
POSITION len; POSITION len;
@ -540,8 +517,7 @@ ch_end_seek(VOID_PARAM)
/* /*
* Seek to the last position in the file that is currently buffered. * Seek to the last position in the file that is currently buffered.
*/ */
public int public int ch_end_buffer_seek(void)
ch_end_buffer_seek(VOID_PARAM)
{ {
struct buf *bp; struct buf *bp;
struct bufnode *bn; struct bufnode *bn;
@ -568,8 +544,7 @@ ch_end_buffer_seek(VOID_PARAM)
* We may not be able to seek there if input is a pipe and the * We may not be able to seek there if input is a pipe and the
* beginning of the pipe is no longer buffered. * beginning of the pipe is no longer buffered.
*/ */
public int public int ch_beg_seek(void)
ch_beg_seek(VOID_PARAM)
{ {
struct bufnode *bn; struct bufnode *bn;
struct bufnode *firstbn; struct bufnode *firstbn;
@ -600,8 +575,7 @@ ch_beg_seek(VOID_PARAM)
/* /*
* Return the length of the file, if known. * Return the length of the file, if known.
*/ */
public POSITION public POSITION ch_length(void)
ch_length(VOID_PARAM)
{ {
if (thisfile == NULL) if (thisfile == NULL)
return (NULL_POSITION); return (NULL_POSITION);
@ -617,8 +591,7 @@ ch_length(VOID_PARAM)
/* /*
* Return the current position in the file. * Return the current position in the file.
*/ */
public POSITION public POSITION ch_tell(void)
ch_tell(VOID_PARAM)
{ {
if (thisfile == NULL) if (thisfile == NULL)
return (NULL_POSITION); return (NULL_POSITION);
@ -628,8 +601,7 @@ ch_tell(VOID_PARAM)
/* /*
* Get the current char and post-increment the read pointer. * Get the current char and post-increment the read pointer.
*/ */
public int public int ch_forw_get(void)
ch_forw_get(VOID_PARAM)
{ {
int c; int c;
@ -651,8 +623,7 @@ ch_forw_get(VOID_PARAM)
/* /*
* Pre-decrement the read pointer and get the new current char. * Pre-decrement the read pointer and get the new current char.
*/ */
public int public int ch_back_get(void)
ch_back_get(VOID_PARAM)
{ {
if (thisfile == NULL) if (thisfile == NULL)
return (EOI); return (EOI);
@ -674,15 +645,14 @@ ch_back_get(VOID_PARAM)
* Set max amount of buffer space. * Set max amount of buffer space.
* bufspace is in units of 1024 bytes. -1 mean no limit. * bufspace is in units of 1024 bytes. -1 mean no limit.
*/ */
public void public void ch_setbufspace(int bufspace)
ch_setbufspace(bufspace)
int bufspace;
{ {
if (bufspace < 0) if (bufspace < 0)
maxbufs = -1; maxbufs = -1;
else else
{ {
maxbufs = ((bufspace * 1024) + LBUFSIZE-1) / LBUFSIZE; int lbufk = LBUFSIZE / 1024;
maxbufs = bufspace / lbufk + (bufspace % lbufk != 0);
if (maxbufs < 1) if (maxbufs < 1)
maxbufs = 1; maxbufs = 1;
} }
@ -691,8 +661,7 @@ ch_setbufspace(bufspace)
/* /*
* Flush (discard) any saved file state, including buffer contents. * Flush (discard) any saved file state, including buffer contents.
*/ */
public void public void ch_flush(void)
ch_flush(VOID_PARAM)
{ {
struct bufnode *bn; struct bufnode *bn;
@ -765,8 +734,7 @@ ch_flush(VOID_PARAM)
* Allocate a new buffer. * Allocate a new buffer.
* The buffer is added to the tail of the buffer chain. * The buffer is added to the tail of the buffer chain.
*/ */
static int static int ch_addbuf(void)
ch_addbuf(VOID_PARAM)
{ {
struct buf *bp; struct buf *bp;
struct bufnode *bn; struct bufnode *bn;
@ -790,8 +758,7 @@ ch_addbuf(VOID_PARAM)
/* /*
* *
*/ */
static void static void init_hashtbl(void)
init_hashtbl(VOID_PARAM)
{ {
int h; int h;
@ -805,8 +772,7 @@ init_hashtbl(VOID_PARAM)
/* /*
* Delete all buffers for this file. * Delete all buffers for this file.
*/ */
static void static void ch_delbufs(void)
ch_delbufs(VOID_PARAM)
{ {
struct bufnode *bn; struct bufnode *bn;
@ -823,9 +789,7 @@ ch_delbufs(VOID_PARAM)
/* /*
* Is it possible to seek on a file descriptor? * Is it possible to seek on a file descriptor?
*/ */
public int public int seekable(int f)
seekable(f)
int f;
{ {
#if MSDOS_COMPILER #if MSDOS_COMPILER
extern int fd0; extern int fd0;
@ -845,8 +809,7 @@ seekable(f)
* Force EOF to be at the current read position. * Force EOF to be at the current read position.
* This is used after an ignore_eof read, during which the EOF may change. * This is used after an ignore_eof read, during which the EOF may change.
*/ */
public void public void ch_set_eof(void)
ch_set_eof(VOID_PARAM)
{ {
if (ch_fsize != NULL_POSITION && ch_fsize < ch_fpos) if (ch_fsize != NULL_POSITION && ch_fsize < ch_fpos)
ch_fsize = ch_fpos; ch_fsize = ch_fpos;
@ -856,10 +819,7 @@ ch_set_eof(VOID_PARAM)
/* /*
* Initialize file state for a new file. * Initialize file state for a new file.
*/ */
public void public void ch_init(int f, int flags)
ch_init(f, flags)
int f;
int flags;
{ {
/* /*
* See if we already have a filestate for this file. * See if we already have a filestate for this file.
@ -896,8 +856,7 @@ ch_init(f, flags)
/* /*
* Close a filestate. * Close a filestate.
*/ */
public void public void ch_close(void)
ch_close(VOID_PARAM)
{ {
int keepstate = FALSE; int keepstate = FALSE;
@ -939,8 +898,7 @@ ch_close(VOID_PARAM)
/* /*
* Return ch_flags for the current file. * Return ch_flags for the current file.
*/ */
public int public int ch_getflags(void)
ch_getflags(VOID_PARAM)
{ {
if (thisfile == NULL) if (thisfile == NULL)
return (0); return (0);
@ -948,8 +906,7 @@ ch_getflags(VOID_PARAM)
} }
#if 0 #if 0
public void static void ch_dump(struct filestate *fs)
ch_dump(struct filestate *fs)
{ {
struct buf *bp; struct buf *bp;
struct bufnode *bn; struct bufnode *bn;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -21,6 +21,7 @@
#endif #endif
#include "charset.h" #include "charset.h"
#include "xbuf.h"
#if MSDOS_COMPILER==WIN32C #if MSDOS_COMPILER==WIN32C
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
@ -123,6 +124,108 @@ static char *binfmt = NULL;
static char *utfbinfmt = NULL; static char *utfbinfmt = NULL;
public int binattr = AT_STANDOUT|AT_COLOR_BIN; public int binattr = AT_STANDOUT|AT_COLOR_BIN;
static struct xbuffer user_wide_array;
static struct xbuffer user_ubin_array;
static struct xbuffer user_compose_array;
static struct xbuffer user_prt_array;
static struct wchar_range_table user_wide_table;
static struct wchar_range_table user_ubin_table;
static struct wchar_range_table user_compose_table;
static struct wchar_range_table user_prt_table;
/*
* Set a wchar_range_table to the table in an xbuffer.
*/
static void wchar_range_table_set(struct wchar_range_table *tbl, struct xbuffer *arr)
{
tbl->table = (struct wchar_range *) arr->data;
tbl->count = arr->end / sizeof(struct wchar_range);
}
/*
* Skip over a "U" or "U+" prefix before a hex codepoint.
*/
static char * skip_uprefix(char *s)
{
if (*s == 'U' || *s == 'u')
if (*++s == '+') ++s;
return s;
}
/*
* Parse a dash-separated range of hex values.
*/
static void wchar_range_get(char **ss, struct wchar_range *range)
{
char *s = skip_uprefix(*ss);
range->first = lstrtoul(s, &s, 16);
if (s[0] == '-')
{
s = skip_uprefix(&s[1]);
range->last = lstrtoul(s, &s, 16);
} else
{
range->last = range->first;
}
*ss = s;
}
/*
* Parse the LESSUTFCHARDEF variable.
*/
static void ichardef_utf(char *s)
{
xbuf_init(&user_wide_array);
xbuf_init(&user_ubin_array);
xbuf_init(&user_compose_array);
xbuf_init(&user_prt_array);
if (s != NULL)
{
while (s[0] != '\0')
{
struct wchar_range range;
wchar_range_get(&s, &range);
if (range.last == 0)
{
error("invalid hex number(s) in LESSUTFCHARDEF", NULL_PARG);
quit(QUIT_ERROR);
}
if (*s++ != ':')
{
error("missing colon in LESSUTFCHARDEF", NULL_PARG);
quit(QUIT_ERROR);
}
switch (*s++)
{
case 'b':
xbuf_add_data(&user_ubin_array, (unsigned char *) &range, sizeof(range));
break;
case 'c':
xbuf_add_data(&user_compose_array, (unsigned char *) &range, sizeof(range));
break;
case 'w':
xbuf_add_data(&user_wide_array, (unsigned char *) &range, sizeof(range));
xbuf_add_data(&user_prt_array, (unsigned char *) &range, sizeof(range));
break;
case 'p': case '.':
xbuf_add_data(&user_prt_array, (unsigned char *) &range, sizeof(range));
break;
case '\0':
s--;
break;
default:
/* Ignore unknown character attribute. */
break;
}
if (s[0] == ',') ++s;
}
}
wchar_range_table_set(&user_wide_table, &user_wide_array);
wchar_range_table_set(&user_ubin_table, &user_ubin_array);
wchar_range_table_set(&user_compose_table, &user_compose_array);
wchar_range_table_set(&user_prt_table, &user_prt_array);
}
/* /*
* Define a charset, given a description string. * Define a charset, given a description string.
@ -138,9 +241,7 @@ public int binattr = AT_STANDOUT|AT_COLOR_BIN;
* b binary character * b binary character
* c control character * c control character
*/ */
static void static void ichardef(char *s)
ichardef(s)
char *s;
{ {
char *cp; char *cp;
int n; int n;
@ -165,10 +266,12 @@ ichardef(s)
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
n = (10 * n) + (s[-1] - '0'); if (ckd_mul(&n, n, 10) || ckd_add(&n, n, s[-1] - '0'))
goto invalid_chardef;
continue; continue;
default: default:
invalid_chardef:
error("invalid chardef", NULL_PARG); error("invalid chardef", NULL_PARG);
quit(QUIT_ERROR); quit(QUIT_ERROR);
/*NOTREACHED*/ /*NOTREACHED*/
@ -195,10 +298,7 @@ ichardef(s)
* Define a charset, given a charset name. * Define a charset, given a charset name.
* The valid charset names are listed in the "charsets" array. * The valid charset names are listed in the "charsets" array.
*/ */
static int static int icharset(char *name, int no_error)
icharset(name, no_error)
char *name;
int no_error;
{ {
struct charset *p; struct charset *p;
struct cs_alias *a; struct cs_alias *a;
@ -244,8 +344,7 @@ icharset(name, no_error)
/* /*
* Define a charset, given a locale name. * Define a charset, given a locale name.
*/ */
static void static void ilocale(void)
ilocale(VOID_PARAM)
{ {
int c; int c;
@ -264,12 +363,7 @@ ilocale(VOID_PARAM)
/* /*
* Define the printing format for control (or binary utf) chars. * Define the printing format for control (or binary utf) chars.
*/ */
public void public void setfmt(char *s, char **fmtvarptr, int *attrptr, char *default_fmt, int for_printf)
setfmt(s, fmtvarptr, attrptr, default_fmt)
char *s;
char **fmtvarptr;
int *attrptr;
char *default_fmt;
{ {
if (s && utf_mode) if (s && utf_mode)
{ {
@ -286,10 +380,12 @@ setfmt(s, fmtvarptr, attrptr, default_fmt)
} }
} }
/* %n is evil */ if (s == NULL || *s == '\0')
if (s == NULL || *s == '\0' || s = default_fmt;
(*s == '*' && (s[1] == '\0' || s[2] == '\0' || strchr(s + 2, 'n'))) || else if (for_printf &&
(*s != '*' && strchr(s, 'n'))) ((*s == '*' && (s[1] == '\0' || s[2] == '\0' || strchr(s + 2, 'n'))) ||
(*s != '*' && strchr(s, 'n'))))
/* %n is evil */
s = default_fmt; s = default_fmt;
/* /*
@ -314,8 +410,7 @@ setfmt(s, fmtvarptr, attrptr, default_fmt)
/* /*
* *
*/ */
static void static void set_charset(void)
set_charset(VOID_PARAM)
{ {
char *s; char *s;
@ -327,6 +422,9 @@ set_charset(VOID_PARAM)
if (icharset("utf-8", 1)) if (icharset("utf-8", 1))
return; return;
#endif #endif
ichardef_utf(lgetenv("LESSUTFCHARDEF"));
/* /*
* See if environment variable LESSCHARSET is defined. * See if environment variable LESSCHARSET is defined.
*/ */
@ -394,8 +492,7 @@ set_charset(VOID_PARAM)
/* /*
* Initialize charset data structures. * Initialize charset data structures.
*/ */
public void public void init_charset(void)
init_charset(VOID_PARAM)
{ {
char *s; char *s;
@ -406,18 +503,16 @@ init_charset(VOID_PARAM)
set_charset(); set_charset();
s = lgetenv("LESSBINFMT"); s = lgetenv("LESSBINFMT");
setfmt(s, &binfmt, &binattr, "*s<%02X>"); setfmt(s, &binfmt, &binattr, "*s<%02X>", TRUE);
s = lgetenv("LESSUTFBINFMT"); s = lgetenv("LESSUTFBINFMT");
setfmt(s, &utfbinfmt, &binattr, "<U+%04lX>"); setfmt(s, &utfbinfmt, &binattr, "<U+%04lX>", TRUE);
} }
/* /*
* Is a given character a "binary" character? * Is a given character a "binary" character?
*/ */
public int public int binary_char(LWCHAR c)
binary_char(c)
LWCHAR c;
{ {
if (utf_mode) if (utf_mode)
return (is_ubin_char(c)); return (is_ubin_char(c));
@ -428,9 +523,7 @@ binary_char(c)
/* /*
* Is a given character a "control" character? * Is a given character a "control" character?
*/ */
public int public int control_char(LWCHAR c)
control_char(c)
LWCHAR c;
{ {
c &= 0377; c &= 0377;
return (chardef[c] & IS_CONTROL_CHAR); return (chardef[c] & IS_CONTROL_CHAR);
@ -440,9 +533,7 @@ control_char(c)
* Return the printable form of a character. * Return the printable form of a character.
* For example, in the "ascii" charset '\3' is printed as "^C". * For example, in the "ascii" charset '\3' is printed as "^C".
*/ */
public char * public char * prchar(LWCHAR c)
prchar(c)
LWCHAR c;
{ {
/* {{ This buffer can be overrun if LESSBINFMT is a long string. }} */ /* {{ This buffer can be overrun if LESSBINFMT is a long string. }} */
static char buf[MAX_PRCHAR_LEN+1]; static char buf[MAX_PRCHAR_LEN+1];
@ -476,9 +567,7 @@ prchar(c)
/* /*
* Return the printable form of a UTF-8 character. * Return the printable form of a UTF-8 character.
*/ */
public char * public char * prutfchar(LWCHAR ch)
prutfchar(ch)
LWCHAR ch;
{ {
static char buf[MAX_PRCHAR_LEN+1]; static char buf[MAX_PRCHAR_LEN+1];
@ -507,9 +596,7 @@ prutfchar(ch)
/* /*
* Get the length of a UTF-8 character in bytes. * Get the length of a UTF-8 character in bytes.
*/ */
public int public int utf_len(int ch)
utf_len(ch)
int ch;
{ {
if ((ch & 0x80) == 0) if ((ch & 0x80) == 0)
return 1; return 1;
@ -530,10 +617,7 @@ utf_len(ch)
/* /*
* Does the parameter point to the lead byte of a well-formed UTF-8 character? * Does the parameter point to the lead byte of a well-formed UTF-8 character?
*/ */
public int public int is_utf8_well_formed(char *ss, int slen)
is_utf8_well_formed(ss, slen)
char *ss;
int slen;
{ {
int i; int i;
int len; int len;
@ -568,10 +652,7 @@ is_utf8_well_formed(ss, slen)
/* /*
* Skip bytes until a UTF-8 lead byte (11xxxxxx) or ASCII byte (0xxxxxxx) is found. * Skip bytes until a UTF-8 lead byte (11xxxxxx) or ASCII byte (0xxxxxxx) is found.
*/ */
public void public void utf_skip_to_lead(char **pp, char *limit)
utf_skip_to_lead(pp, limit)
char **pp;
char *limit;
{ {
do { do {
++(*pp); ++(*pp);
@ -582,9 +663,7 @@ utf_skip_to_lead(pp, limit)
/* /*
* Get the value of a UTF-8 character. * Get the value of a UTF-8 character.
*/ */
public LWCHAR public LWCHAR get_wchar(constant char *p)
get_wchar(p)
constant char *p;
{ {
switch (utf_len(p[0])) switch (utf_len(p[0]))
{ {
@ -634,10 +713,7 @@ get_wchar(p)
/* /*
* Store a character into a UTF-8 string. * Store a character into a UTF-8 string.
*/ */
public void public void put_wchar(char **pp, LWCHAR ch)
put_wchar(pp, ch)
char **pp;
LWCHAR ch;
{ {
if (!utf_mode || ch < 0x80) if (!utf_mode || ch < 0x80)
{ {
@ -684,11 +760,7 @@ put_wchar(pp, ch)
/* /*
* Step forward or backward one character in a string. * Step forward or backward one character in a string.
*/ */
public LWCHAR public LWCHAR step_char(char **pp, signed int dir, constant char *limit)
step_char(pp, dir, limit)
char **pp;
signed int dir;
constant char *limit;
{ {
LWCHAR ch; LWCHAR ch;
int len; int len;
@ -758,16 +830,13 @@ static struct wchar_range comb_table[] = {
}; };
static int static int is_in_table(LWCHAR ch, struct wchar_range_table *table)
is_in_table(ch, table)
LWCHAR ch;
struct wchar_range_table *table;
{ {
int hi; int hi;
int lo; int lo;
/* Binary search in the table. */ /* Binary search in the table. */
if (ch < table->table[0].first) if (table->table == NULL || table->count == 0 || ch < table->table[0].first)
return 0; return 0;
lo = 0; lo = 0;
hi = table->count - 1; hi = table->count - 1;
@ -788,34 +857,32 @@ is_in_table(ch, table)
* Is a character a UTF-8 composing character? * Is a character a UTF-8 composing character?
* If a composing character follows any char, the two combine into one glyph. * If a composing character follows any char, the two combine into one glyph.
*/ */
public int public int is_composing_char(LWCHAR ch)
is_composing_char(ch)
LWCHAR ch;
{ {
return is_in_table(ch, &compose_table) || if (is_in_table(ch, &user_prt_table)) return 0;
return is_in_table(ch, &user_compose_table) ||
is_in_table(ch, &compose_table) ||
(bs_mode != BS_CONTROL && is_in_table(ch, &fmt_table)); (bs_mode != BS_CONTROL && is_in_table(ch, &fmt_table));
} }
/* /*
* Should this UTF-8 character be treated as binary? * Should this UTF-8 character be treated as binary?
*/ */
public int public int is_ubin_char(LWCHAR ch)
is_ubin_char(ch)
LWCHAR ch;
{ {
int ubin = is_in_table(ch, &ubin_table) || if (is_in_table(ch, &user_prt_table)) return 0;
(bs_mode == BS_CONTROL && is_in_table(ch, &fmt_table)); return is_in_table(ch, &user_ubin_table) ||
return ubin; is_in_table(ch, &ubin_table) ||
(bs_mode == BS_CONTROL && is_in_table(ch, &fmt_table));
} }
/* /*
* Is this a double width UTF-8 character? * Is this a double width UTF-8 character?
*/ */
public int public int is_wide_char(LWCHAR ch)
is_wide_char(ch)
LWCHAR ch;
{ {
return is_in_table(ch, &wide_table); return is_in_table(ch, &user_wide_table) ||
is_in_table(ch, &wide_table);
} }
/* /*
@ -823,10 +890,7 @@ is_wide_char(ch)
* A combining char acts like an ordinary char, but if it follows * A combining char acts like an ordinary char, but if it follows
* a specific char (not any char), the two combine into one glyph. * a specific char (not any char), the two combine into one glyph.
*/ */
public int public int is_combining_char(LWCHAR ch1, LWCHAR ch2)
is_combining_char(ch1, ch2)
LWCHAR ch1;
LWCHAR ch2;
{ {
/* The table is small; use linear search. */ /* The table is small; use linear search. */
int i; int i;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -75,6 +75,7 @@
#define A_B_MOUSE 67 #define A_B_MOUSE 67
/* Note "X116" refers to extended (1006) X11 mouse reporting. */ /* Note "X116" refers to extended (1006) X11 mouse reporting. */
#define A_X116MOUSE_IN 68 #define A_X116MOUSE_IN 68
#define A_PSHELL 69
#define A_CLR_SEARCH 70 #define A_CLR_SEARCH 70
/* These values must not conflict with any A_* or EC_* value. */ /* These values must not conflict with any A_* or EC_* value. */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -35,7 +35,7 @@ static int literal; /* Next input char should not be interpreted */
public 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 #if TAB_COMPLETE_FILENAME
static int cmd_complete LESSPARAMS((int action)); static int cmd_complete(int action);
/* /*
* These variables are statics used by cmd_complete. * These variables are statics used by cmd_complete.
*/ */
@ -117,8 +117,7 @@ static int cmd_mbc_buf_index;
/* /*
* Reset command buffer (to empty). * Reset command buffer (to empty).
*/ */
public void public void cmd_reset(void)
cmd_reset(VOID_PARAM)
{ {
cp = cmdbuf; cp = cmdbuf;
*cp = '\0'; *cp = '\0';
@ -132,8 +131,7 @@ cmd_reset(VOID_PARAM)
/* /*
* Clear command line. * Clear command line.
*/ */
public void public void clear_cmd(void)
clear_cmd(VOID_PARAM)
{ {
cmd_col = prompt_col = 0; cmd_col = prompt_col = 0;
cmd_mbc_buf_len = 0; cmd_mbc_buf_len = 0;
@ -143,9 +141,7 @@ clear_cmd(VOID_PARAM)
/* /*
* Display a string, usually as a prompt for input into the command buffer. * Display a string, usually as a prompt for input into the command buffer.
*/ */
public void public void cmd_putstr(constant char *s)
cmd_putstr(s)
constant char *s;
{ {
LWCHAR prev_ch = 0; LWCHAR prev_ch = 0;
LWCHAR ch; LWCHAR ch;
@ -172,8 +168,7 @@ cmd_putstr(s)
/* /*
* How many characters are in the command buffer? * How many characters are in the command buffer?
*/ */
public int public int len_cmdbuf(void)
len_cmdbuf(VOID_PARAM)
{ {
char *s = cmdbuf; char *s = cmdbuf;
char *endline = s + strlen(s); char *endline = s + strlen(s);
@ -192,13 +187,7 @@ len_cmdbuf(VOID_PARAM)
* {{ Returning pwidth and bswidth separately is a historical artifact * {{ Returning pwidth and bswidth separately is a historical artifact
* since they're always the same. Maybe clean this up someday. }} * since they're always the same. Maybe clean this up someday. }}
*/ */
static char * static char * cmd_step_common(char *p, LWCHAR ch, int len, int *pwidth, int *bswidth)
cmd_step_common(p, ch, len, pwidth, bswidth)
char *p;
LWCHAR ch;
int len;
int *pwidth;
int *bswidth;
{ {
char *pr; char *pr;
int width; int width;
@ -233,11 +222,7 @@ cmd_step_common(p, ch, len, pwidth, bswidth)
/* /*
* Step a pointer one character right in the command buffer. * Step a pointer one character right in the command buffer.
*/ */
static char * static char * cmd_step_right(char **pp, int *pwidth, int *bswidth)
cmd_step_right(pp, pwidth, bswidth)
char **pp;
int *pwidth;
int *bswidth;
{ {
char *p = *pp; char *p = *pp;
LWCHAR ch = step_char(pp, +1, p + strlen(p)); LWCHAR ch = step_char(pp, +1, p + strlen(p));
@ -248,11 +233,7 @@ cmd_step_right(pp, pwidth, bswidth)
/* /*
* Step a pointer one character left in the command buffer. * Step a pointer one character left in the command buffer.
*/ */
static char * static char * cmd_step_left(char **pp, int *pwidth, int *bswidth)
cmd_step_left(pp, pwidth, bswidth)
char **pp;
int *pwidth;
int *bswidth;
{ {
char *p = *pp; char *p = *pp;
LWCHAR ch = step_char(pp, -1, cmdbuf); LWCHAR ch = step_char(pp, -1, cmdbuf);
@ -264,8 +245,7 @@ cmd_step_left(pp, pwidth, bswidth)
* Put the cursor at "home" (just after the prompt), * Put the cursor at "home" (just after the prompt),
* and set cp to the corresponding char in cmdbuf. * and set cp to the corresponding char in cmdbuf.
*/ */
static void static void cmd_home(void)
cmd_home(VOID_PARAM)
{ {
while (cmd_col > prompt_col) while (cmd_col > prompt_col)
{ {
@ -284,9 +264,7 @@ cmd_home(VOID_PARAM)
* Repaint the line from cp onwards. * Repaint the line from cp onwards.
* Then position the cursor just after the char old_cp (a pointer into cmdbuf). * Then position the cursor just after the char old_cp (a pointer into cmdbuf).
*/ */
public void public void cmd_repaint(constant char *old_cp)
cmd_repaint(old_cp)
constant char *old_cp;
{ {
/* /*
* Repaint the line from the current position. * Repaint the line from the current position.
@ -329,8 +307,7 @@ cmd_repaint(old_cp)
/* /*
* Shift the cmdbuf display left a half-screen. * Shift the cmdbuf display left a half-screen.
*/ */
static void static void cmd_lshift(void)
cmd_lshift(VOID_PARAM)
{ {
char *s; char *s;
char *save_cp; char *save_cp;
@ -367,8 +344,7 @@ cmd_lshift(VOID_PARAM)
/* /*
* Shift the cmdbuf display right a half-screen. * Shift the cmdbuf display right a half-screen.
*/ */
static void static void cmd_rshift(void)
cmd_rshift(VOID_PARAM)
{ {
char *s; char *s;
char *save_cp; char *save_cp;
@ -397,8 +373,7 @@ cmd_rshift(VOID_PARAM)
/* /*
* Move cursor right one character. * Move cursor right one character.
*/ */
static int static int cmd_right(void)
cmd_right(VOID_PARAM)
{ {
char *pr; char *pr;
char *ncp; char *ncp;
@ -432,8 +407,7 @@ cmd_right(VOID_PARAM)
/* /*
* Move cursor left one character. * Move cursor left one character.
*/ */
static int static int cmd_left(void)
cmd_left(VOID_PARAM)
{ {
char *ncp; char *ncp;
int width = 0; int width = 0;
@ -463,10 +437,7 @@ cmd_left(VOID_PARAM)
/* /*
* Insert a char into the command buffer, at the current position. * Insert a char into the command buffer, at the current position.
*/ */
static int static int cmd_ichar(char *cs, int clen)
cmd_ichar(cs, clen)
char *cs;
int clen;
{ {
char *s; char *s;
@ -500,8 +471,7 @@ cmd_ichar(cs, clen)
* Backspace in the command buffer. * Backspace in the command buffer.
* Delete the char to the left of the cursor. * Delete the char to the left of the cursor.
*/ */
static int static int cmd_erase(void)
cmd_erase(VOID_PARAM)
{ {
char *s; char *s;
int clen; int clen;
@ -549,8 +519,7 @@ cmd_erase(VOID_PARAM)
/* /*
* Delete the char under the cursor. * Delete the char under the cursor.
*/ */
static int static int cmd_delete(void)
cmd_delete(VOID_PARAM)
{ {
if (*cp == '\0') if (*cp == '\0')
{ {
@ -568,8 +537,7 @@ cmd_delete(VOID_PARAM)
/* /*
* Delete the "word" to the left of the cursor. * Delete the "word" to the left of the cursor.
*/ */
static int static int cmd_werase(void)
cmd_werase(VOID_PARAM)
{ {
if (cp > cmdbuf && cp[-1] == ' ') if (cp > cmdbuf && cp[-1] == ' ')
{ {
@ -594,8 +562,7 @@ cmd_werase(VOID_PARAM)
/* /*
* Delete the "word" under the cursor. * Delete the "word" under the cursor.
*/ */
static int static int cmd_wdelete(void)
cmd_wdelete(VOID_PARAM)
{ {
if (*cp == ' ') if (*cp == ' ')
{ {
@ -620,8 +587,7 @@ cmd_wdelete(VOID_PARAM)
/* /*
* Delete all chars in the command buffer. * Delete all chars in the command buffer.
*/ */
static int static int cmd_kill(void)
cmd_kill(VOID_PARAM)
{ {
if (cmdbuf[0] == '\0') if (cmdbuf[0] == '\0')
{ {
@ -646,10 +612,7 @@ cmd_kill(VOID_PARAM)
/* /*
* Select an mlist structure to be the current command history. * Select an mlist structure to be the current command history.
*/ */
public void public void set_mlist(void *mlist, int cmdflags)
set_mlist(mlist, cmdflags)
void *mlist;
int cmdflags;
{ {
#if CMD_HISTORY #if CMD_HISTORY
curr_mlist = (struct mlist *) mlist; curr_mlist = (struct mlist *) mlist;
@ -667,9 +630,7 @@ set_mlist(mlist, cmdflags)
* Only consider entries whose first updown_match chars are equal to * Only consider entries whose first updown_match chars are equal to
* cmdbuf's corresponding chars. * cmdbuf's corresponding chars.
*/ */
static int static int cmd_updown(int action)
cmd_updown(action)
int action;
{ {
constant char *s; constant char *s;
struct mlist *ml; struct mlist *ml;
@ -731,10 +692,7 @@ cmd_updown(action)
/* /*
* *
*/ */
static void static void ml_link(struct mlist *mlist, struct mlist *ml)
ml_link(mlist, ml)
struct mlist *mlist;
struct mlist *ml;
{ {
ml->next = mlist; ml->next = mlist;
ml->prev = mlist->prev; ml->prev = mlist->prev;
@ -745,9 +703,7 @@ ml_link(mlist, ml)
/* /*
* *
*/ */
static void static void ml_unlink(struct mlist *ml)
ml_unlink(ml)
struct mlist *ml;
{ {
ml->prev->next = ml->next; ml->prev->next = ml->next;
ml->next->prev = ml->prev; ml->next->prev = ml->prev;
@ -756,11 +712,7 @@ ml_unlink(ml)
/* /*
* Add a string to an mlist. * Add a string to an mlist.
*/ */
public void public void cmd_addhist(struct mlist *mlist, constant char *cmd, int modified)
cmd_addhist(mlist, cmd, modified)
struct mlist *mlist;
constant char *cmd;
int modified;
{ {
#if CMD_HISTORY #if CMD_HISTORY
struct mlist *ml; struct mlist *ml;
@ -814,8 +766,7 @@ cmd_addhist(mlist, cmd, modified)
* Accept the command in the command buffer. * Accept the command in the command buffer.
* Add it to the currently selected history list. * Add it to the currently selected history list.
*/ */
public void public void cmd_accept(void)
cmd_accept(VOID_PARAM)
{ {
#if CMD_HISTORY #if CMD_HISTORY
/* /*
@ -836,9 +787,7 @@ cmd_accept(VOID_PARAM)
* CC_OK Line edit function done. * CC_OK Line edit function done.
* CC_QUIT The char requests the current command to be aborted. * CC_QUIT The char requests the current command to be aborted.
*/ */
static int static int cmd_edit(int c)
cmd_edit(c)
int c;
{ {
int action; int action;
int flags; int flags;
@ -846,7 +795,7 @@ cmd_edit(c)
#if TAB_COMPLETE_FILENAME #if TAB_COMPLETE_FILENAME
#define not_in_completion() in_completion = 0 #define not_in_completion() in_completion = 0
#else #else
#define not_in_completion(VOID_PARAM) #define not_in_completion(void)
#endif #endif
/* /*
@ -953,9 +902,7 @@ cmd_edit(c)
/* /*
* Insert a string into the command buffer, at the current position. * Insert a string into the command buffer, at the current position.
*/ */
static int static int cmd_istr(char *str)
cmd_istr(str)
char *str;
{ {
char *s; char *s;
int action; int action;
@ -978,8 +925,7 @@ cmd_istr(str)
* Return pointer to the beginning of the word and put the * Return pointer to the beginning of the word and put the
* cursor at the end of the word. * cursor at the end of the word.
*/ */
static char * static char * delimit_word(void)
delimit_word(VOID_PARAM)
{ {
char *word; char *word;
#if SPACES_IN_FILENAMES #if SPACES_IN_FILENAMES
@ -1065,8 +1011,7 @@ delimit_word(VOID_PARAM)
* Expand the word under the cursor into a list of filenames * Expand the word under the cursor into a list of filenames
* which start with that word, and set tk_text to that list. * which start with that word, and set tk_text to that list.
*/ */
static void static void init_compl(void)
init_compl(VOID_PARAM)
{ {
char *word; char *word;
char c; char c;
@ -1128,10 +1073,7 @@ init_compl(VOID_PARAM)
/* /*
* Return the next word in the current completion list. * Return the next word in the current completion list.
*/ */
static char * static char * next_compl(int action, char *prev)
next_compl(action, prev)
int action;
char *prev;
{ {
switch (action) switch (action)
{ {
@ -1150,9 +1092,7 @@ next_compl(action, prev)
* remembers whether this call is the first time (create the list), * remembers whether this call is the first time (create the list),
* or a subsequent time (step thru the list). * or a subsequent time (step thru the list).
*/ */
static int static int cmd_complete(int action)
cmd_complete(action)
int action;
{ {
char *s; char *s;
@ -1248,9 +1188,7 @@ cmd_complete(action)
* CC_QUIT The char requests the command to be aborted. * CC_QUIT The char requests the command to be aborted.
* CC_ERROR The char could not be accepted due to an error. * CC_ERROR The char could not be accepted due to an error.
*/ */
public int public int cmd_char(int c)
cmd_char(c)
int c;
{ {
int action; int action;
int len; int len;
@ -1345,9 +1283,7 @@ cmd_char(c)
/* /*
* Return the number currently in the command buffer. * Return the number currently in the command buffer.
*/ */
public LINENUM public LINENUM cmd_int(long *frac)
cmd_int(frac)
long *frac;
{ {
char *p; char *p;
LINENUM n = 0; LINENUM n = 0;
@ -1355,13 +1291,11 @@ cmd_int(frac)
for (p = cmdbuf; *p >= '0' && *p <= '9'; p++) for (p = cmdbuf; *p >= '0' && *p <= '9'; p++)
{ {
LINENUM nn = (n * 10) + (*p - '0'); if (ckd_mul(&n, n, 10) || ckd_add(&n, n, *p - '0'))
if (nn < n)
{ {
error("Integer is too big", NULL_PARG); error("Integer is too big", NULL_PARG);
return (0); return (0);
} }
n = nn;
} }
*frac = 0; *frac = 0;
if (*p++ == '.') if (*p++ == '.')
@ -1375,8 +1309,7 @@ cmd_int(frac)
/* /*
* Return a pointer to the command buffer. * Return a pointer to the command buffer.
*/ */
public char * public char * get_cmdbuf(void)
get_cmdbuf(VOID_PARAM)
{ {
if (cmd_mbc_buf_index < cmd_mbc_buf_len) if (cmd_mbc_buf_index < cmd_mbc_buf_len)
/* Don't return buffer containing an incomplete multibyte char. */ /* Don't return buffer containing an incomplete multibyte char. */
@ -1388,8 +1321,7 @@ get_cmdbuf(VOID_PARAM)
/* /*
* Return the last (most recent) string in the current command history. * Return the last (most recent) string in the current command history.
*/ */
public char * public char * cmd_lastpattern(void)
cmd_lastpattern(VOID_PARAM)
{ {
if (curr_mlist == NULL) if (curr_mlist == NULL)
return (NULL); return (NULL);
@ -1400,9 +1332,7 @@ cmd_lastpattern(VOID_PARAM)
#if CMD_HISTORY #if CMD_HISTORY
/* /*
*/ */
static int static int mlist_size(struct mlist *ml)
mlist_size(ml)
struct mlist *ml;
{ {
int size = 0; int size = 0;
for (ml = ml->next; ml->string != NULL; ml = ml->next) for (ml = ml->next; ml->string != NULL; ml = ml->next)
@ -1413,9 +1343,7 @@ mlist_size(ml)
/* /*
* Get the name of the history file. * Get the name of the history file.
*/ */
static char * static char * histfile_find(int must_exist)
histfile_find(must_exist)
int must_exist;
{ {
char *home = lgetenv("HOME"); char *home = lgetenv("HOME");
char *name = NULL; char *name = NULL;
@ -1442,9 +1370,7 @@ histfile_find(must_exist)
return (name); return (name);
} }
static char * static char * histfile_name(int must_exist)
histfile_name(must_exist)
int must_exist;
{ {
char *name; char *name;
@ -1476,12 +1402,7 @@ histfile_name(must_exist)
/* /*
* Read a .lesshst file and call a callback for each line in the file. * Read a .lesshst file and call a callback for each line in the file.
*/ */
static void static void read_cmdhist2(void (*action)(void*,struct mlist*,char*), void *uparam, int skip_search, int skip_shell)
read_cmdhist2(action, uparam, skip_search, skip_shell)
void (*action)(void*,struct mlist*,char*);
void *uparam;
int skip_search;
int skip_shell;
{ {
struct mlist *ml = NULL; struct mlist *ml = NULL;
char line[CMDBUF_SIZE]; char line[CMDBUF_SIZE];
@ -1546,12 +1467,7 @@ read_cmdhist2(action, uparam, skip_search, skip_shell)
fclose(f); fclose(f);
} }
static void static void read_cmdhist(void (*action)(void*,struct mlist*,char*), void *uparam, int skip_search, int skip_shell)
read_cmdhist(action, uparam, skip_search, skip_shell)
void (*action)(void*,struct mlist*,char*);
void *uparam;
int skip_search;
int skip_shell;
{ {
if (secure) if (secure)
return; return;
@ -1559,11 +1475,7 @@ read_cmdhist(action, uparam, skip_search, skip_shell)
(*action)(uparam, NULL, NULL); /* signal end of file */ (*action)(uparam, NULL, NULL); /* signal end of file */
} }
static void 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) if (ml != NULL)
cmd_addhist(ml, string, 0); cmd_addhist(ml, string, 0);
@ -1575,8 +1487,7 @@ addhist_init(uparam, ml, string)
/* /*
* Initialize history from a .lesshist file. * Initialize history from a .lesshist file.
*/ */
public void public void init_cmdhist(void)
init_cmdhist(VOID_PARAM)
{ {
#if CMD_HISTORY #if CMD_HISTORY
read_cmdhist(&addhist_init, NULL, 0, 0); read_cmdhist(&addhist_init, NULL, 0, 0);
@ -1587,10 +1498,7 @@ init_cmdhist(VOID_PARAM)
* Write the header for a section of the history file. * Write the header for a section of the history file.
*/ */
#if CMD_HISTORY #if CMD_HISTORY
static void static void write_mlist_header(struct mlist *ml, FILE *f)
write_mlist_header(ml, f)
struct mlist *ml;
FILE *f;
{ {
if (ml == &mlist_search) if (ml == &mlist_search)
fprintf(f, "%s\n", HISTFILE_SEARCH_SECTION); fprintf(f, "%s\n", HISTFILE_SEARCH_SECTION);
@ -1603,10 +1511,7 @@ write_mlist_header(ml, f)
/* /*
* Write all modified entries in an mlist to the history file. * Write all modified entries in an mlist to the history file.
*/ */
static void static void write_mlist(struct mlist *ml, FILE *f)
write_mlist(ml, f)
struct mlist *ml;
FILE *f;
{ {
for (ml = ml->next; ml->string != NULL; ml = ml->next) for (ml = ml->next; ml->string != NULL; ml = ml->next)
{ {
@ -1621,9 +1526,7 @@ write_mlist(ml, f)
/* /*
* Make a temp name in the same directory as filename. * Make a temp name in the same directory as filename.
*/ */
static char * static char * make_tempname(char *filename)
make_tempname(filename)
char *filename;
{ {
char lastch; char lastch;
char *tempname = ecalloc(1, strlen(filename)+1); char *tempname = ecalloc(1, strlen(filename)+1);
@ -1644,11 +1547,7 @@ struct save_ctx
* At the end of each mlist, append any new entries * At the end of each mlist, append any new entries
* created during this session. * created during this session.
*/ */
static void 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; struct save_ctx *ctx = (struct save_ctx *) uparam;
@ -1689,9 +1588,7 @@ copy_hist(uparam, ml, string)
/* /*
* Make a file readable only by its owner. * Make a file readable only by its owner.
*/ */
static void static void make_file_private(FILE *f)
make_file_private(f)
FILE *f;
{ {
#if HAVE_FCHMOD #if HAVE_FCHMOD
int do_chmod = 1; int do_chmod = 1;
@ -1711,8 +1608,7 @@ make_file_private(f)
* Does the history file need to be updated? * Does the history file need to be updated?
*/ */
#if CMD_HISTORY #if CMD_HISTORY
static int static int histfile_modified(void)
histfile_modified(VOID_PARAM)
{ {
if (mlist_search.modified) if (mlist_search.modified)
return 1; return 1;
@ -1729,8 +1625,7 @@ histfile_modified(VOID_PARAM)
/* /*
* Update the .lesshst file. * Update the .lesshst file.
*/ */
public void public void save_cmdhist(void)
save_cmdhist(VOID_PARAM)
{ {
#if CMD_HISTORY #if CMD_HISTORY
char *histname; char *histname;

View File

@ -1,6 +1,6 @@
/* $FreeBSD$ */ /* $FreeBSD$ */
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -24,6 +24,7 @@
extern int erase_char, erase2_char, kill_char; extern int erase_char, erase2_char, kill_char;
extern int sigs; extern int sigs;
extern int quit_if_one_screen; extern int quit_if_one_screen;
extern int one_screen;
extern int squished; extern int squished;
extern int sc_width; extern int sc_width;
extern int sc_height; extern int sc_height;
@ -37,6 +38,7 @@ extern int ignore_eoi;
extern int secure; extern int secure;
extern int hshift; extern int hshift;
extern int bs_mode; extern int bs_mode;
extern int proc_backspace;
extern int show_attn; extern int show_attn;
extern int less_is_more; extern int less_is_more;
extern int status_col; extern int status_col;
@ -65,6 +67,7 @@ extern int shift_count;
extern int oldbot; extern int oldbot;
extern int forw_prompt; extern int forw_prompt;
extern int incr_search; extern int incr_search;
extern int full_screen;
#if MSDOS_COMPILER==WIN32C #if MSDOS_COMPILER==WIN32C
extern int utf_mode; extern int utf_mode;
#endif #endif
@ -74,6 +77,7 @@ static char *shellcmd = NULL; /* For holding last shell command for "!!" */
#endif #endif
static int mca; /* The multicharacter command (action) */ static int mca; /* The multicharacter command (action) */
static int search_type; /* The previous type of search */ static int search_type; /* The previous type of search */
static int last_search_type; /* Type of last executed search */
static LINENUM number; /* The number typed by the user */ static LINENUM number; /* The number typed by the user */
static long fraction; /* The fractional part of the number */ static long fraction; /* The fractional part of the number */
static struct loption *curropt; static struct loption *curropt;
@ -83,6 +87,7 @@ static int optgetname;
static POSITION bottompos; static POSITION bottompos;
static int save_hshift; static int save_hshift;
static int save_bs_mode; static int save_bs_mode;
static int save_proc_backspace;
#if PIPEC #if PIPEC
static char pipec; static char pipec;
#endif #endif
@ -94,15 +99,14 @@ struct ungot {
}; };
static struct ungot* ungot = NULL; static struct ungot* ungot = NULL;
static void multi_search LESSPARAMS((char *pattern, int n, int silent)); static void multi_search (char *pattern, int n, int silent);
/* /*
* Move the cursor to start of prompt line before executing a command. * Move the cursor to start of prompt line before executing a command.
* This looks nicer if the command takes a long time before * This looks nicer if the command takes a long time before
* updating the screen. * updating the screen.
*/ */
static void static void cmd_exec(void)
cmd_exec(VOID_PARAM)
{ {
clear_attn(); clear_attn();
clear_bot(); clear_bot();
@ -112,9 +116,7 @@ cmd_exec(VOID_PARAM)
/* /*
* Indicate we are reading a multi-character command. * Indicate we are reading a multi-character command.
*/ */
static void static void set_mca(int action)
set_mca(action)
int action;
{ {
mca = action; mca = action;
clear_bot(); clear_bot();
@ -124,8 +126,7 @@ set_mca(action)
/* /*
* Indicate we are not reading a multi-character command. * Indicate we are not reading a multi-character command.
*/ */
static void static void clear_mca(void)
clear_mca(VOID_PARAM)
{ {
if (mca == 0) if (mca == 0)
return; return;
@ -135,20 +136,14 @@ clear_mca(VOID_PARAM)
/* /*
* Set up the display to start a new multi-character command. * Set up the display to start a new multi-character command.
*/ */
static void static void start_mca(int action, constant char *prompt, void *mlist, int cmdflags)
start_mca(action, prompt, mlist, cmdflags)
int action;
constant char *prompt;
void *mlist;
int cmdflags;
{ {
set_mca(action); set_mca(action);
cmd_putstr(prompt); cmd_putstr(prompt);
set_mlist(mlist, cmdflags); set_mlist(mlist, cmdflags);
} }
public int public int in_mca(void)
in_mca(VOID_PARAM)
{ {
return (mca != 0 && mca != A_PREFIX); return (mca != 0 && mca != A_PREFIX);
} }
@ -156,9 +151,10 @@ in_mca(VOID_PARAM)
/* /*
* Set up the display to start a new search command. * Set up the display to start a new search command.
*/ */
static void static void mca_search1(void)
mca_search1(VOID_PARAM)
{ {
int i;
#if HILITE_SEARCH #if HILITE_SEARCH
if (search_type & SRCH_FILTER) if (search_type & SRCH_FILTER)
set_mca(A_FILTER); set_mca(A_FILTER);
@ -181,6 +177,15 @@ mca_search1(VOID_PARAM)
cmd_putstr("Regex-off "); cmd_putstr("Regex-off ");
if (search_type & SRCH_WRAP) if (search_type & SRCH_WRAP)
cmd_putstr("Wrap "); cmd_putstr("Wrap ");
for (i = 1; i <= NUM_SEARCH_COLORS; i++)
{
if (search_type & SRCH_SUBSEARCH(i))
{
char buf[8];
SNPRINTF1(buf, sizeof(buf), "Sub-%d ", i);
cmd_putstr(buf);
}
}
#if HILITE_SEARCH #if HILITE_SEARCH
if (search_type & SRCH_FILTER) if (search_type & SRCH_FILTER)
@ -194,8 +199,7 @@ mca_search1(VOID_PARAM)
forw_prompt = 0; forw_prompt = 0;
} }
static void static void mca_search(void)
mca_search(VOID_PARAM)
{ {
mca_search1(); mca_search1();
set_mlist(ml_search, 0); set_mlist(ml_search, 0);
@ -204,8 +208,7 @@ mca_search(VOID_PARAM)
/* /*
* Set up the display to start a new toggle-option command. * Set up the display to start a new toggle-option command.
*/ */
static void static void mca_opt_toggle(void)
mca_opt_toggle(VOID_PARAM)
{ {
int no_prompt; int no_prompt;
int flag; int flag;
@ -237,8 +240,7 @@ mca_opt_toggle(VOID_PARAM)
/* /*
* Execute a multicharacter command. * Execute a multicharacter command.
*/ */
static void static void exec_mca(void)
exec_mca(VOID_PARAM)
{ {
char *cbuf; char *cbuf;
@ -314,6 +316,11 @@ exec_mca(VOID_PARAM)
else else
lsystem(shellcmd, "!done"); lsystem(shellcmd, "!done");
break; break;
case A_PSHELL:
if (secure)
break;
lsystem(pr_expand(cbuf), "#done");
break;
#endif #endif
#if PIPEC #if PIPEC
case A_PIPE: case A_PIPE:
@ -329,9 +336,7 @@ exec_mca(VOID_PARAM)
/* /*
* Is a character an erase or kill char? * Is a character an erase or kill char?
*/ */
static int static int is_erase_char(int c)
is_erase_char(c)
int c;
{ {
return (c == erase_char || c == erase2_char || c == kill_char); return (c == erase_char || c == erase2_char || c == kill_char);
} }
@ -339,9 +344,7 @@ is_erase_char(c)
/* /*
* Is a character a carriage return or newline? * Is a character a carriage return or newline?
*/ */
static int static int is_newline_char(int c)
is_newline_char(c)
int c;
{ {
return (c == '\n' || c == '\r'); return (c == '\n' || c == '\r');
} }
@ -349,9 +352,7 @@ is_newline_char(c)
/* /*
* Handle the first char of an option (after the initial dash). * Handle the first char of an option (after the initial dash).
*/ */
static int static int mca_opt_first_char(int c)
mca_opt_first_char(c)
int c;
{ {
int no_prompt = (optflag & OPT_NO_PROMPT); int no_prompt = (optflag & OPT_NO_PROMPT);
int flag = (optflag & ~OPT_NO_PROMPT); int flag = (optflag & ~OPT_NO_PROMPT);
@ -402,9 +403,7 @@ mca_opt_first_char(c)
* If so, display the complete name and stop * If so, display the complete name and stop
* accepting chars until user hits RETURN. * accepting chars until user hits RETURN.
*/ */
static int static int mca_opt_nonfirst_char(int c)
mca_opt_nonfirst_char(c)
int c;
{ {
char *p; char *p;
char *oname; char *oname;
@ -459,9 +458,7 @@ mca_opt_nonfirst_char(c)
/* /*
* Handle a char of an option toggle command. * Handle a char of an option toggle command.
*/ */
static int static int mca_opt_char(int c)
mca_opt_char(c)
int c;
{ {
PARG parg; PARG parg;
@ -528,9 +525,7 @@ mca_opt_char(c)
/* /*
* Normalize search type. * Normalize search type.
*/ */
public int public int norm_search_type(int st)
norm_search_type(st)
int st;
{ {
/* WRAP and PAST_EOF are mutually exclusive. */ /* WRAP and PAST_EOF are mutually exclusive. */
if ((st & (SRCH_PAST_EOF|SRCH_WRAP)) == (SRCH_PAST_EOF|SRCH_WRAP)) if ((st & (SRCH_PAST_EOF|SRCH_WRAP)) == (SRCH_PAST_EOF|SRCH_WRAP))
@ -541,9 +536,7 @@ norm_search_type(st)
/* /*
* Handle a char of a search command. * Handle a char of a search command.
*/ */
static int static int mca_search_char(int c)
mca_search_char(c)
int c;
{ {
int flag = 0; int flag = 0;
@ -577,6 +570,18 @@ mca_search_char(c)
if (mca != A_FILTER) if (mca != A_FILTER)
flag = SRCH_NO_MOVE; flag = SRCH_NO_MOVE;
break; break;
case CONTROL('S'): { /* SUBSEARCH */
char buf[32];
SNPRINTF1(buf, sizeof(buf), "Sub-pattern (1-%d):", NUM_SEARCH_COLORS);
clear_bot();
cmd_putstr(buf);
flush();
c = getcc();
if (c >= '1' && c <= '0'+NUM_SEARCH_COLORS)
flag = SRCH_SUBSEARCH(c-'0');
else
flag = -1; /* calls mca_search() below to repaint */
break; }
case CONTROL('W'): /* WRAP around */ case CONTROL('W'): /* WRAP around */
if (mca != A_FILTER) if (mca != A_FILTER)
flag = SRCH_WRAP; flag = SRCH_WRAP;
@ -592,7 +597,8 @@ mca_search_char(c)
if (flag != 0) if (flag != 0)
{ {
search_type = norm_search_type(search_type ^ flag); if (flag != -1)
search_type = norm_search_type(search_type ^ flag);
mca_search(); mca_search();
return (MCA_MORE); return (MCA_MORE);
} }
@ -602,9 +608,7 @@ mca_search_char(c)
/* /*
* Handle a character of a multi-character command. * Handle a character of a multi-character command.
*/ */
static int static int mca_char(int c)
mca_char(c)
int c;
{ {
int ret; int ret;
@ -712,7 +716,7 @@ mca_char(c)
if (incr_search) if (incr_search)
{ {
/* Incremental search: do a search after every input char. */ /* 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)); int st = (search_type & (SRCH_FORW|SRCH_BACK|SRCH_NO_MATCH|SRCH_NO_REGEX|SRCH_NO_MOVE|SRCH_WRAP|SRCH_SUBSEARCH_ALL));
char *pattern = get_cmdbuf(); char *pattern = get_cmdbuf();
if (pattern == NULL) if (pattern == NULL)
return (MCA_MORE); return (MCA_MORE);
@ -734,6 +738,11 @@ mca_char(c)
undo_search(1); undo_search(1);
} }
/* Redraw the search prompt and search string. */ /* Redraw the search prompt and search string. */
if (!full_screen)
{
clear();
repaint();
}
mca_search1(); mca_search1();
updown_match = save_updown_match; updown_match = save_updown_match;
cmd_repaint(NULL); cmd_repaint(NULL);
@ -750,8 +759,7 @@ mca_char(c)
/* /*
* Discard any buffered file data. * Discard any buffered file data.
*/ */
static void static void clear_buffers(void)
clear_buffers(VOID_PARAM)
{ {
if (!(ch_getflags() & CH_CANSEEK)) if (!(ch_getflags() & CH_CANSEEK))
return; return;
@ -765,9 +773,14 @@ clear_buffers(VOID_PARAM)
/* /*
* Make sure the screen is displayed. * Make sure the screen is displayed.
*/ */
static void static void make_display(void)
make_display(VOID_PARAM)
{ {
/*
* If not full_screen, we can't rely on scrolling to fill the screen.
* We need to clear and repaint screen before any change.
*/
if (!full_screen && !(quit_if_one_screen && one_screen))
clear();
/* /*
* If nothing is displayed yet, display starting from initial_scrpos. * If nothing is displayed yet, display starting from initial_scrpos.
*/ */
@ -777,7 +790,7 @@ make_display(VOID_PARAM)
jump_loc(ch_zero(), 1); jump_loc(ch_zero(), 1);
else else
jump_loc(initial_scrpos.pos, initial_scrpos.ln); jump_loc(initial_scrpos.pos, initial_scrpos.ln);
} else if (screen_trashed) } else if (screen_trashed || !full_screen)
{ {
int save_top_scroll = top_scroll; int save_top_scroll = top_scroll;
int save_ignore_eoi = ignore_eoi; int save_ignore_eoi = ignore_eoi;
@ -799,8 +812,7 @@ make_display(VOID_PARAM)
/* /*
* Display the appropriate prompt. * Display the appropriate prompt.
*/ */
static void static void prompt(void)
prompt(VOID_PARAM)
{ {
constant char *p; constant char *p;
@ -895,8 +907,7 @@ prompt(VOID_PARAM)
/* /*
* Display the less version message. * Display the less version message.
*/ */
public void public void dispversion(void)
dispversion(VOID_PARAM)
{ {
PARG parg; PARG parg;
@ -907,8 +918,7 @@ dispversion(VOID_PARAM)
/* /*
* Return a character to complete a partial command, if possible. * Return a character to complete a partial command, if possible.
*/ */
static LWCHAR static LWCHAR getcc_end_command(void)
getcc_end_command(VOID_PARAM)
{ {
switch (mca) switch (mca)
{ {
@ -917,6 +927,7 @@ getcc_end_command(VOID_PARAM)
return ('g'); return ('g');
case A_F_SEARCH: case A_F_SEARCH:
case A_B_SEARCH: case A_B_SEARCH:
case A_FILTER:
/* We have "/string" but no newline. Add the \n. */ /* We have "/string" but no newline. Add the \n. */
return ('\n'); return ('\n');
default: default:
@ -931,8 +942,7 @@ getcc_end_command(VOID_PARAM)
* but may come from ungotten characters * but may come from ungotten characters
* (characters previously given to ungetcc or ungetsc). * (characters previously given to ungetcc or ungetsc).
*/ */
static LWCHAR static LWCHAR getccu(void)
getccu(VOID_PARAM)
{ {
LWCHAR c = 0; LWCHAR c = 0;
while (c == 0) while (c == 0)
@ -962,12 +972,7 @@ getccu(VOID_PARAM)
* Get a command character, but if we receive the orig sequence, * Get a command character, but if we receive the orig sequence,
* convert it to the repl sequence. * convert it to the repl sequence.
*/ */
static LWCHAR static LWCHAR getcc_repl(char constant *orig, char constant *repl, LWCHAR (*gr_getc)(void), void (*gr_ungetc)(LWCHAR))
getcc_repl(orig, repl, gr_getc, gr_ungetc)
char constant* orig;
char constant* repl;
LWCHAR (*gr_getc)(VOID_PARAM);
void (*gr_ungetc)(LWCHAR);
{ {
LWCHAR c; LWCHAR c;
LWCHAR keys[16]; LWCHAR keys[16];
@ -1006,8 +1011,7 @@ getcc_repl(orig, repl, gr_getc, gr_ungetc)
/* /*
* Get command character. * Get command character.
*/ */
public int public int getcc(void)
getcc(VOID_PARAM)
{ {
/* Replace kent (keypad Enter) with a newline. */ /* Replace kent (keypad Enter) with a newline. */
return getcc_repl(kent, "\n", getccu, ungetcc); return getcc_repl(kent, "\n", getccu, ungetcc);
@ -1017,9 +1021,7 @@ getcc(VOID_PARAM)
* "Unget" a command character. * "Unget" a command character.
* The next getcc() will return this character. * The next getcc() will return this character.
*/ */
public void public void ungetcc(LWCHAR c)
ungetcc(c)
LWCHAR c;
{ {
struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot)); struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot));
@ -1032,9 +1034,7 @@ ungetcc(c)
* "Unget" a command character. * "Unget" a command character.
* If any other chars are already ungotten, put this one after those. * If any other chars are already ungotten, put this one after those.
*/ */
public void public void ungetcc_back(LWCHAR c)
ungetcc_back(c)
LWCHAR c;
{ {
struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot)); struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot));
ug->ug_char = c; ug->ug_char = c;
@ -1054,9 +1054,7 @@ ungetcc_back(c)
* Unget a whole string of command characters. * Unget a whole string of command characters.
* The next sequence of getcc()'s will return this string. * The next sequence of getcc()'s will return this string.
*/ */
public void public void ungetsc(char *s)
ungetsc(s)
char *s;
{ {
while (*s != '\0') while (*s != '\0')
ungetcc_back(*s++); ungetcc_back(*s++);
@ -1065,8 +1063,7 @@ ungetsc(s)
/* /*
* Peek the next command character, without consuming it. * Peek the next command character, without consuming it.
*/ */
public LWCHAR public LWCHAR peekcc(void)
peekcc(VOID_PARAM)
{ {
LWCHAR c = getcc(); LWCHAR c = getcc();
ungetcc(c); ungetcc(c);
@ -1078,11 +1075,7 @@ peekcc(VOID_PARAM)
* If SRCH_FIRST_FILE is set, begin searching at the first file. * If SRCH_FIRST_FILE is set, begin searching at the first file.
* If SRCH_PAST_EOF is set, continue the search thru multiple files. * If SRCH_PAST_EOF is set, continue the search thru multiple files.
*/ */
static void static void multi_search(char *pattern, int n, int silent)
multi_search(pattern, n, silent)
char *pattern;
int n;
int silent;
{ {
int nomore; int nomore;
IFILE save_ifile; IFILE save_ifile;
@ -1091,6 +1084,8 @@ multi_search(pattern, n, silent)
changed_file = 0; changed_file = 0;
save_ifile = save_curr_ifile(); save_ifile = save_curr_ifile();
if ((search_type & (SRCH_FORW|SRCH_BACK)) == 0)
search_type |= SRCH_FORW;
if (search_type & SRCH_FIRST_FILE) if (search_type & SRCH_FIRST_FILE)
{ {
/* /*
@ -1119,6 +1114,7 @@ multi_search(pattern, n, silent)
* using a /@@ search. * using a /@@ search.
*/ */
search_type &= ~SRCH_NO_MOVE; search_type &= ~SRCH_NO_MOVE;
last_search_type = search_type;
if (n == 0) if (n == 0)
{ {
/* /*
@ -1175,9 +1171,7 @@ multi_search(pattern, n, silent)
/* /*
* Forward forever, or until a highlighted line appears. * Forward forever, or until a highlighted line appears.
*/ */
static int static int forw_loop(int until_hilite)
forw_loop(until_hilite)
int until_hilite;
{ {
POSITION curr_len; POSITION curr_len;
@ -1216,8 +1210,7 @@ forw_loop(until_hilite)
* Main command processor. * Main command processor.
* Accept and execute commands until a quit command. * Accept and execute commands until a quit command.
*/ */
public void public void commands(void)
commands(VOID_PARAM)
{ {
int c; int c;
int action; int action;
@ -1624,6 +1617,7 @@ commands(VOID_PARAM)
*/ */
hshift = save_hshift; hshift = save_hshift;
bs_mode = save_bs_mode; bs_mode = save_bs_mode;
proc_backspace = save_proc_backspace;
if (edit_prev(1) == 0) if (edit_prev(1) == 0)
break; break;
} }
@ -1641,7 +1635,6 @@ commands(VOID_PARAM)
cmd_exec(); \ cmd_exec(); \
multi_search((char *)NULL, (int) number, 0); multi_search((char *)NULL, (int) number, 0);
case A_F_SEARCH: case A_F_SEARCH:
/* /*
* Search forward for a pattern. * Search forward for a pattern.
@ -1681,6 +1674,7 @@ commands(VOID_PARAM)
/* /*
* Repeat previous search. * Repeat previous search.
*/ */
search_type = last_search_type;
DO_SEARCH(); DO_SEARCH();
break; break;
@ -1688,7 +1682,7 @@ commands(VOID_PARAM)
/* /*
* Repeat previous search, multiple files. * Repeat previous search, multiple files.
*/ */
search_type |= SRCH_PAST_EOF; search_type = last_search_type | SRCH_PAST_EOF;
DO_SEARCH(); DO_SEARCH();
break; break;
@ -1696,10 +1690,10 @@ commands(VOID_PARAM)
/* /*
* Repeat previous search, in reverse direction. * Repeat previous search, in reverse direction.
*/ */
save_search_type = search_type; save_search_type = search_type = last_search_type;
search_type = SRCH_REVERSE(search_type); search_type = SRCH_REVERSE(search_type);
DO_SEARCH(); DO_SEARCH();
search_type = save_search_type; last_search_type = save_search_type;
break; break;
case A_T_REVERSE_SEARCH: case A_T_REVERSE_SEARCH:
@ -1707,11 +1701,10 @@ commands(VOID_PARAM)
* Repeat previous search, * Repeat previous search,
* multiple files in reverse direction. * multiple files in reverse direction.
*/ */
save_search_type = search_type; save_search_type = search_type = last_search_type;
search_type = SRCH_REVERSE(search_type); search_type = SRCH_REVERSE(search_type) | SRCH_PAST_EOF;
search_type |= SRCH_PAST_EOF;
DO_SEARCH(); DO_SEARCH();
search_type = save_search_type; last_search_type = save_search_type;
break; break;
case A_UNDO_SEARCH: case A_UNDO_SEARCH:
@ -1733,6 +1726,8 @@ commands(VOID_PARAM)
hshift = 0; hshift = 0;
save_bs_mode = bs_mode; save_bs_mode = bs_mode;
bs_mode = BS_SPECIAL; bs_mode = BS_SPECIAL;
save_proc_backspace = proc_backspace;
proc_backspace = OPT_OFF;
(void) edit(FAKE_HELPFILE); (void) edit(FAKE_HELPFILE);
break; break;
@ -1945,13 +1940,14 @@ commands(VOID_PARAM)
goto again; goto again;
case A_SHELL: case A_SHELL:
case A_PSHELL:
/* /*
* Shell escape. * Shell escape.
*/ */
#if SHELL_ESCAPE #if SHELL_ESCAPE
if (!secure) if (!secure)
{ {
start_mca(A_SHELL, "!", ml_shell, 0); start_mca(action, (action == A_SHELL) ? "!" : "#", ml_shell, 0);
c = getcc(); c = getcc();
goto again; goto again;
} }

View File

@ -1,4 +1,4 @@
/* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Tue Jul 19 12:45:16 PDT 2022 */ /* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Mon Nov 14 18:19:23 PST 2022 */
{ 0x0300, 0x036f }, /* Mn */ { 0x0300, 0x036f }, /* Mn */
{ 0x0483, 0x0487 }, /* Mn */ { 0x0483, 0x0487 }, /* Mn */
{ 0x0488, 0x0489 }, /* Me */ { 0x0488, 0x0489 }, /* Me */
@ -92,7 +92,7 @@
{ 0x0e47, 0x0e4e }, /* Mn */ { 0x0e47, 0x0e4e }, /* Mn */
{ 0x0eb1, 0x0eb1 }, /* Mn */ { 0x0eb1, 0x0eb1 }, /* Mn */
{ 0x0eb4, 0x0ebc }, /* Mn */ { 0x0eb4, 0x0ebc }, /* Mn */
{ 0x0ec8, 0x0ecd }, /* Mn */ { 0x0ec8, 0x0ece }, /* Mn */
{ 0x0f18, 0x0f19 }, /* Mn */ { 0x0f18, 0x0f19 }, /* Mn */
{ 0x0f35, 0x0f35 }, /* Mn */ { 0x0f35, 0x0f35 }, /* Mn */
{ 0x0f37, 0x0f37 }, /* Mn */ { 0x0f37, 0x0f37 }, /* Mn */
@ -230,6 +230,7 @@
{ 0x10ae5, 0x10ae6 }, /* Mn */ { 0x10ae5, 0x10ae6 }, /* Mn */
{ 0x10d24, 0x10d27 }, /* Mn */ { 0x10d24, 0x10d27 }, /* Mn */
{ 0x10eab, 0x10eac }, /* Mn */ { 0x10eab, 0x10eac }, /* Mn */
{ 0x10efd, 0x10eff }, /* Mn */
{ 0x10f46, 0x10f50 }, /* Mn */ { 0x10f46, 0x10f50 }, /* Mn */
{ 0x10f82, 0x10f85 }, /* Mn */ { 0x10f82, 0x10f85 }, /* Mn */
{ 0x11001, 0x11001 }, /* Mn */ { 0x11001, 0x11001 }, /* Mn */
@ -252,6 +253,7 @@
{ 0x11234, 0x11234 }, /* Mn */ { 0x11234, 0x11234 }, /* Mn */
{ 0x11236, 0x11237 }, /* Mn */ { 0x11236, 0x11237 }, /* Mn */
{ 0x1123e, 0x1123e }, /* Mn */ { 0x1123e, 0x1123e }, /* Mn */
{ 0x11241, 0x11241 }, /* Mn */
{ 0x112df, 0x112df }, /* Mn */ { 0x112df, 0x112df }, /* Mn */
{ 0x112e3, 0x112ea }, /* Mn */ { 0x112e3, 0x112ea }, /* Mn */
{ 0x11300, 0x11301 }, /* Mn */ { 0x11300, 0x11301 }, /* Mn */
@ -313,6 +315,12 @@
{ 0x11d95, 0x11d95 }, /* Mn */ { 0x11d95, 0x11d95 }, /* Mn */
{ 0x11d97, 0x11d97 }, /* Mn */ { 0x11d97, 0x11d97 }, /* Mn */
{ 0x11ef3, 0x11ef4 }, /* Mn */ { 0x11ef3, 0x11ef4 }, /* Mn */
{ 0x11f00, 0x11f01 }, /* Mn */
{ 0x11f36, 0x11f3a }, /* Mn */
{ 0x11f40, 0x11f40 }, /* Mn */
{ 0x11f42, 0x11f42 }, /* Mn */
{ 0x13440, 0x13440 }, /* Mn */
{ 0x13447, 0x13455 }, /* Mn */
{ 0x16af0, 0x16af4 }, /* Mn */ { 0x16af0, 0x16af4 }, /* Mn */
{ 0x16b30, 0x16b36 }, /* Mn */ { 0x16b30, 0x16b36 }, /* Mn */
{ 0x16f4f, 0x16f4f }, /* Mn */ { 0x16f4f, 0x16f4f }, /* Mn */
@ -337,9 +345,11 @@
{ 0x1e01b, 0x1e021 }, /* Mn */ { 0x1e01b, 0x1e021 }, /* Mn */
{ 0x1e023, 0x1e024 }, /* Mn */ { 0x1e023, 0x1e024 }, /* Mn */
{ 0x1e026, 0x1e02a }, /* Mn */ { 0x1e026, 0x1e02a }, /* Mn */
{ 0x1e08f, 0x1e08f }, /* Mn */
{ 0x1e130, 0x1e136 }, /* Mn */ { 0x1e130, 0x1e136 }, /* Mn */
{ 0x1e2ae, 0x1e2ae }, /* Mn */ { 0x1e2ae, 0x1e2ae }, /* Mn */
{ 0x1e2ec, 0x1e2ef }, /* Mn */ { 0x1e2ec, 0x1e2ef }, /* Mn */
{ 0x1e4ec, 0x1e4ef }, /* Mn */
{ 0x1e8d0, 0x1e8d6 }, /* Mn */ { 0x1e8d0, 0x1e8d6 }, /* Mn */
{ 0x1e944, 0x1e94a }, /* Mn */ { 0x1e944, 0x1e94a }, /* Mn */
{ 0xe0100, 0xe01ef }, /* Mn */ { 0xe0100, 0xe01ef }, /* Mn */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -19,10 +19,7 @@ extern int utf_mode;
/* /*
* Get the length of a buffer needed to convert a string. * Get the length of a buffer needed to convert a string.
*/ */
public int public int cvt_length(int len, int ops)
cvt_length(len, ops)
int len;
int ops;
{ {
if (utf_mode) if (utf_mode)
/* /*
@ -37,9 +34,7 @@ cvt_length(len, ops)
/* /*
* Allocate a chpos array for use by cvt_text. * Allocate a chpos array for use by cvt_text.
*/ */
public int * public int * cvt_alloc_chpos(int len)
cvt_alloc_chpos(len)
int len;
{ {
int i; int i;
int *chpos = (int *) ecalloc(sizeof(int), len); int *chpos = (int *) ecalloc(sizeof(int), len);
@ -54,13 +49,7 @@ cvt_alloc_chpos(len)
* Returns converted text in odst. The original offset of each * Returns converted text in odst. The original offset of each
* odst character (when it was in osrc) is returned in the chpos array. * odst character (when it was in osrc) is returned in the chpos array.
*/ */
public void public void cvt_text(char *odst, char *osrc, int *chpos, int *lenp, int ops)
cvt_text(odst, osrc, chpos, lenp, ops)
char *odst;
char *osrc;
int *chpos;
int *lenp;
int ops;
{ {
char *dst; char *dst;
char *edst = odst; char *edst = odst;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -166,6 +166,7 @@ static unsigned char cmdtable[] =
'|',0, A_PIPE, '|',0, A_PIPE,
'v',0, A_VISUAL, 'v',0, A_VISUAL,
'!',0, A_SHELL, '!',0, A_SHELL,
'#',0, A_PSHELL,
'+',0, A_FIRSTCMD, '+',0, A_FIRSTCMD,
'H',0, A_HELP, 'H',0, A_HELP,
@ -242,10 +243,7 @@ static struct tablelist *list_sysvar_tables = NULL;
/* /*
* Expand special key abbreviations in a command table. * Expand special key abbreviations in a command table.
*/ */
static void static void expand_special_keys(char *table, int len)
expand_special_keys(table, len)
char *table;
int len;
{ {
char *fm; char *fm;
char *to; char *to;
@ -303,9 +301,7 @@ expand_special_keys(table, len)
/* /*
* Expand special key abbreviations in a list of command tables. * Expand special key abbreviations in a list of command tables.
*/ */
static void static void expand_cmd_table(struct tablelist *tlist)
expand_cmd_table(tlist)
struct tablelist *tlist;
{ {
struct tablelist *t; struct tablelist *t;
for (t = tlist; t != NULL; t = t->t_next) for (t = tlist; t != NULL; t = t->t_next)
@ -317,8 +313,7 @@ expand_cmd_table(tlist)
/* /*
* Expand special key abbreviations in all command tables. * Expand special key abbreviations in all command tables.
*/ */
public void public void expand_cmd_tables(void)
expand_cmd_tables(VOID_PARAM)
{ {
expand_cmd_table(list_fcmd_tables); expand_cmd_table(list_fcmd_tables);
expand_cmd_table(list_ecmd_tables); expand_cmd_table(list_ecmd_tables);
@ -330,8 +325,7 @@ expand_cmd_tables(VOID_PARAM)
/* /*
* Initialize the command lists. * Initialize the command lists.
*/ */
public void public void init_cmds(void)
init_cmds(VOID_PARAM)
{ {
/* /*
* Add the default command tables. * Add the default command tables.
@ -380,11 +374,7 @@ init_cmds(VOID_PARAM)
/* /*
* Add a command table. * Add a command table.
*/ */
static int static int add_cmd_table(struct tablelist **tlist, char *buf, int len)
add_cmd_table(tlist, buf, len)
struct tablelist **tlist;
char *buf;
int len;
{ {
struct tablelist *t; struct tablelist *t;
@ -409,10 +399,7 @@ add_cmd_table(tlist, buf, len)
/* /*
* Add a command table. * Add a command table.
*/ */
public void public void add_fcmd_table(char *buf, int len)
add_fcmd_table(buf, len)
char *buf;
int len;
{ {
if (add_cmd_table(&list_fcmd_tables, buf, len) < 0) if (add_cmd_table(&list_fcmd_tables, buf, len) < 0)
error("Warning: some commands disabled", NULL_PARG); error("Warning: some commands disabled", NULL_PARG);
@ -421,10 +408,7 @@ add_fcmd_table(buf, len)
/* /*
* Add an editing command table. * Add an editing command table.
*/ */
public void public void add_ecmd_table(char *buf, int len)
add_ecmd_table(buf, len)
char *buf;
int len;
{ {
if (add_cmd_table(&list_ecmd_tables, buf, len) < 0) if (add_cmd_table(&list_ecmd_tables, buf, len) < 0)
error("Warning: some edit commands disabled", NULL_PARG); error("Warning: some edit commands disabled", NULL_PARG);
@ -433,11 +417,7 @@ add_ecmd_table(buf, len)
/* /*
* Add an environment variable table. * Add an environment variable table.
*/ */
static void static void add_var_table(struct tablelist **tlist, char *buf, int len)
add_var_table(tlist, buf, len)
struct tablelist **tlist;
char *buf;
int len;
{ {
if (add_cmd_table(tlist, buf, len) < 0) if (add_cmd_table(tlist, buf, len) < 0)
error("Warning: environment variables from lesskey file unavailable", NULL_PARG); error("Warning: environment variables from lesskey file unavailable", NULL_PARG);
@ -446,8 +426,7 @@ add_var_table(tlist, buf, len)
/* /*
* Return action for a mouse wheel down event. * Return action for a mouse wheel down event.
*/ */
static int static int mouse_wheel_down(void)
mouse_wheel_down(VOID_PARAM)
{ {
return ((mousecap == OPT_ONPLUS) ? A_B_MOUSE : A_F_MOUSE); return ((mousecap == OPT_ONPLUS) ? A_B_MOUSE : A_F_MOUSE);
} }
@ -455,8 +434,7 @@ mouse_wheel_down(VOID_PARAM)
/* /*
* Return action for a mouse wheel up event. * Return action for a mouse wheel up event.
*/ */
static int static int mouse_wheel_up(void)
mouse_wheel_up(VOID_PARAM)
{ {
return ((mousecap == OPT_ONPLUS) ? A_F_MOUSE : A_B_MOUSE); return ((mousecap == OPT_ONPLUS) ? A_F_MOUSE : A_B_MOUSE);
} }
@ -464,10 +442,7 @@ mouse_wheel_up(VOID_PARAM)
/* /*
* Return action for a mouse button release event. * Return action for a mouse button release event.
*/ */
static int static int mouse_button_rel(int x, int y)
mouse_button_rel(x, y)
int x;
int y;
{ {
/* /*
* {{ It would be better to return an action and then do this * {{ It would be better to return an action and then do this
@ -484,9 +459,7 @@ mouse_button_rel(x, y)
/* /*
* Read a decimal integer. Return the integer and set *pterm to the terminating char. * Read a decimal integer. Return the integer and set *pterm to the terminating char.
*/ */
static int static int getcc_int(char *pterm)
getcc_int(pterm)
char* pterm;
{ {
int num = 0; int num = 0;
int digits = 0; int digits = 0;
@ -500,7 +473,8 @@ getcc_int(pterm)
return (-1); return (-1);
return (num); return (num);
} }
num = (10 * num) + (ch - '0'); if (ckd_mul(&num, num, 10) || ckd_add(&num, num, ch - '0'))
return -1;
++digits; ++digits;
} }
} }
@ -509,9 +483,7 @@ getcc_int(pterm)
* Read suffix of mouse input and return the action to take. * Read suffix of mouse input and return the action to take.
* The prefix ("\e[M") has already been read. * The prefix ("\e[M") has already been read.
*/ */
static int static int x11mouse_action(int skip)
x11mouse_action(skip)
int skip;
{ {
int b = getcc() - X11MOUSE_OFFSET; int b = getcc() - X11MOUSE_OFFSET;
int x = getcc() - X11MOUSE_OFFSET-1; int x = getcc() - X11MOUSE_OFFSET-1;
@ -534,9 +506,7 @@ x11mouse_action(skip)
* Read suffix of mouse input and return the action to take. * Read suffix of mouse input and return the action to take.
* The prefix ("\e[<") has already been read. * The prefix ("\e[<") has already been read.
*/ */
static int static int x116mouse_action(int skip)
x116mouse_action(skip)
int skip;
{ {
char ch; char ch;
int x, y; int x, y;
@ -562,12 +532,7 @@ x116mouse_action(skip)
/* /*
* Search a single command table for the command string in cmd. * Search a single command table for the command string in cmd.
*/ */
static int static int cmd_search(char *cmd, char *table, char *endtable, char **sp)
cmd_search(cmd, table, endtable, sp)
char *cmd;
char *table;
char *endtable;
char **sp;
{ {
char *p; char *p;
char *q; char *q;
@ -658,11 +623,7 @@ cmd_search(cmd, table, endtable, sp)
* Decode a command character and return the associated action. * Decode a command character and return the associated action.
* The "extra" string, if any, is returned in sp. * The "extra" string, if any, is returned in sp.
*/ */
static int static int cmd_decode(struct tablelist *tlist, char *cmd, char **sp)
cmd_decode(tlist, cmd, sp)
struct tablelist *tlist;
char *cmd;
char **sp;
{ {
struct tablelist *t; struct tablelist *t;
int action = A_INVALID; int action = A_INVALID;
@ -685,10 +646,7 @@ cmd_decode(tlist, cmd, sp)
/* /*
* Decode a command from the cmdtables list. * Decode a command from the cmdtables list.
*/ */
public int public int fcmd_decode(char *cmd, char **sp)
fcmd_decode(cmd, sp)
char *cmd;
char **sp;
{ {
return (cmd_decode(list_fcmd_tables, cmd, sp)); return (cmd_decode(list_fcmd_tables, cmd, sp));
} }
@ -696,10 +654,7 @@ fcmd_decode(cmd, sp)
/* /*
* Decode a command from the edittables list. * Decode a command from the edittables list.
*/ */
public int public int ecmd_decode(char *cmd, char **sp)
ecmd_decode(cmd, sp)
char *cmd;
char **sp;
{ {
return (cmd_decode(list_ecmd_tables, cmd, sp)); return (cmd_decode(list_ecmd_tables, cmd, sp));
} }
@ -708,9 +663,7 @@ ecmd_decode(cmd, sp)
* Get the value of an environment variable. * Get the value of an environment variable.
* Looks first in the lesskey file, then in the real environment. * Looks first in the lesskey file, then in the real environment.
*/ */
public char * public char * lgetenv(char *var)
lgetenv(var)
char *var;
{ {
int a; int a;
char *s; char *s;
@ -730,9 +683,7 @@ lgetenv(var)
/* /*
* Is a string null or empty? * Is a string null or empty?
*/ */
public int public int isnullenv(char *s)
isnullenv(s)
char* s;
{ {
return (s == NULL || *s == '\0'); return (s == NULL || *s == '\0');
} }
@ -743,9 +694,7 @@ isnullenv(s)
* Integers are stored in a funny format: * Integers are stored in a funny format:
* two bytes, low order first, in radix KRADIX. * two bytes, low order first, in radix KRADIX.
*/ */
static int static int gint(char **sp)
gint(sp)
char **sp;
{ {
int n; int n;
@ -757,10 +706,7 @@ gint(sp)
/* /*
* Process an old (pre-v241) lesskey file. * Process an old (pre-v241) lesskey file.
*/ */
static int static int old_lesskey(char *buf, int len)
old_lesskey(buf, len)
char *buf;
int len;
{ {
/* /*
* Old-style lesskey file. * Old-style lesskey file.
@ -778,11 +724,7 @@ old_lesskey(buf, len)
/* /*
* Process a new (post-v241) lesskey file. * Process a new (post-v241) lesskey file.
*/ */
static int static int new_lesskey(char *buf, int len, int sysvar)
new_lesskey(buf, len, sysvar)
char *buf;
int len;
int sysvar;
{ {
char *p; char *p;
char *end; char *end;
@ -840,10 +782,7 @@ new_lesskey(buf, len, sysvar)
/* /*
* Set up a user command table, based on a "lesskey" file. * Set up a user command table, based on a "lesskey" file.
*/ */
public int public int lesskey(char *filename, int sysvar)
lesskey(filename, sysvar)
char *filename;
int sysvar;
{ {
char *buf; char *buf;
POSITION len; POSITION len;
@ -907,25 +846,20 @@ lesskey(filename, sysvar)
} }
#if HAVE_LESSKEYSRC #if HAVE_LESSKEYSRC
public int public int lesskey_src(char *filename, int sysvar)
lesskey_src(filename, sysvar)
char *filename;
int sysvar;
{ {
static struct lesskey_tables tables; static struct lesskey_tables tables;
int r = parse_lesskey(filename, &tables); int r = parse_lesskey(filename, &tables);
if (r != 0) if (r != 0)
return (r); return (r);
add_fcmd_table(tables.cmdtable.buf.data, tables.cmdtable.buf.end); add_fcmd_table(xbuf_char_data(&tables.cmdtable.buf), tables.cmdtable.buf.end);
add_ecmd_table(tables.edittable.buf.data, tables.edittable.buf.end); add_ecmd_table(xbuf_char_data(&tables.edittable.buf), tables.edittable.buf.end);
add_var_table(sysvar ? &list_sysvar_tables : &list_var_tables, add_var_table(sysvar ? &list_sysvar_tables : &list_var_tables,
tables.vartable.buf.data, tables.vartable.buf.end); xbuf_char_data(&tables.vartable.buf), tables.vartable.buf.end);
return (0); return (0);
} }
void void lesskey_parse_error(char *s)
lesskey_parse_error(s)
char *s;
{ {
PARG parg; PARG parg;
parg.p_string = s; parg.p_string = s;
@ -936,12 +870,7 @@ lesskey_parse_error(s)
/* /*
* Add a lesskey file. * Add a lesskey file.
*/ */
public int public int add_hometable(int (*call_lesskey)(char *, int), char *envname, char *def_filename, int sysvar)
add_hometable(call_lesskey, envname, def_filename, sysvar)
int (*call_lesskey)(char *, int);
char *envname;
char *def_filename;
int sysvar;
{ {
char *filename; char *filename;
int r; int r;
@ -980,10 +909,7 @@ add_hometable(call_lesskey, envname, def_filename, sysvar)
/* /*
* See if a char is a special line-editing command. * See if a char is a special line-editing command.
*/ */
public int public int editchar(int c, int flags)
editchar(c, flags)
int c;
int flags;
{ {
int action; int action;
int nch; int nch;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -13,9 +13,10 @@
#if HAVE_STAT #if HAVE_STAT
#include <sys/stat.h> #include <sys/stat.h>
#endif #endif
#if OS2 #if HAVE_SYS_WAIT_H
#include <signal.h> #include <sys/wait.h>
#endif #endif
#include <signal.h>
public int fd0 = 0; public int fd0 = 0;
@ -28,6 +29,8 @@ extern int sigs;
extern int hshift; extern int hshift;
extern int want_filesize; extern int want_filesize;
extern int consecutive_nulls; extern int consecutive_nulls;
extern int modelines;
extern int show_preproc_error;
extern IFILE curr_ifile; extern IFILE curr_ifile;
extern IFILE old_ifile; extern IFILE old_ifile;
extern struct scrpos initial_scrpos; extern struct scrpos initial_scrpos;
@ -55,10 +58,7 @@ public ino_t curr_ino;
* words, returning each one as a standard null-terminated string. * words, returning each one as a standard null-terminated string.
* back_textlist does the same, but runs thru the list backwards. * back_textlist does the same, but runs thru the list backwards.
*/ */
public void public void init_textlist(struct textlist *tlist, char *str)
init_textlist(tlist, str)
struct textlist *tlist;
char *str;
{ {
char *s; char *s;
#if SPACES_IN_FILENAMES #if SPACES_IN_FILENAMES
@ -99,10 +99,7 @@ init_textlist(tlist, str)
} }
} }
public char * public char * forw_textlist(struct textlist *tlist, char *prev)
forw_textlist(tlist, prev)
struct textlist *tlist;
char *prev;
{ {
char *s; char *s;
@ -123,10 +120,7 @@ forw_textlist(tlist, prev)
return (s); return (s);
} }
public char * public char * back_textlist(struct textlist *tlist, char *prev)
back_textlist(tlist, prev)
struct textlist *tlist;
char *prev;
{ {
char *s; char *s;
@ -149,12 +143,129 @@ back_textlist(tlist, prev)
return (s); return (s);
} }
/*
* Parse a single option setting in a modeline.
*/
static void modeline_option(char *str, int opt_len)
{
struct mloption { char *opt_name; void (*opt_func)(char*,int); };
struct mloption options[] = {
{ "ts=", set_tabs },
{ "tabstop=", set_tabs },
{ NULL, NULL }
};
struct mloption *opt;
for (opt = options; opt->opt_name != NULL; opt++)
{
int name_len = strlen(opt->opt_name);
if (opt_len > name_len && strncmp(str, opt->opt_name, name_len) == 0)
{
(*opt->opt_func)(str + name_len, opt_len - name_len);
break;
}
}
}
/*
* String length, terminated by option separator (space or colon).
* Space/colon can be escaped with backspace.
*/
static int modeline_option_len(char *str)
{
int esc = FALSE;
char *s;
for (s = str; *s != '\0'; s++)
{
if (esc)
esc = FALSE;
else if (*s == '\\')
esc = TRUE;
else if (*s == ' ' || *s == ':') /* separator */
break;
}
return (s - str);
}
/*
* Parse colon- or space-separated option settings in a modeline.
*/
static void modeline_options(char *str, char end_char)
{
for (;;)
{
int opt_len;
str = skipsp(str);
if (*str == '\0' || *str == end_char)
break;
opt_len = modeline_option_len(str);
modeline_option(str, opt_len);
str += opt_len;
if (*str != '\0')
str += 1; /* skip past the separator */
}
}
/*
* See if there is a modeline string in a line.
*/
static void check_modeline(char *line)
{
#if HAVE_STRSTR
static char *pgms[] = { "less:", "vim:", "vi:", "ex:", NULL };
char **pgm;
for (pgm = pgms; *pgm != NULL; ++pgm)
{
char *pline = line;
for (;;)
{
char *str;
pline = strstr(pline, *pgm);
if (pline == NULL) /* pgm is not in this line */
break;
str = skipsp(pline + strlen(*pgm));
if (pline == line || pline[-1] == ' ')
{
if (strncmp(str, "set ", 4) == 0)
modeline_options(str+4, ':');
else if (pgm != &pgms[0]) /* "less:" requires "set" */
modeline_options(str, '\0');
break;
}
/* Continue searching the rest of the line. */
pline = str;
}
}
#endif /* HAVE_STRSTR */
}
/*
* Read lines from start of file and check if any are modelines.
*/
static void check_modelines(void)
{
POSITION pos = ch_zero();
int i;
for (i = 0; i < modelines; i++)
{
char *line;
int line_len;
if (ABORT_SIGS())
return;
pos = forw_raw_line(pos, &line, &line_len);
if (pos == NULL_POSITION)
break;
check_modeline(line);
}
}
/* /*
* Close a pipe opened via popen. * Close a pipe opened via popen.
*/ */
static void static void close_pipe(FILE *pipefd)
close_pipe(FILE *pipefd)
{ {
int status;
PARG parg;
if (pipefd == NULL) if (pipefd == NULL)
return; return;
#if OS2 #if OS2
@ -164,18 +275,79 @@ close_pipe(FILE *pipefd)
*/ */
kill(pipefd->_pid, SIGINT); kill(pipefd->_pid, SIGINT);
#endif #endif
pclose(pipefd); status = pclose(pipefd);
if (status == -1)
{
/* An internal error in 'less', not a preprocessor error. */
parg.p_string = errno_message("pclose");
error("%s", &parg);
free(parg.p_string);
return;
}
if (!show_preproc_error)
return;
#if defined WIFEXITED && defined WEXITSTATUS
if (WIFEXITED(status))
{
int s = WEXITSTATUS(status);
if (s != 0)
{
parg.p_int = s;
error("Input preprocessor failed (status %d)", &parg);
}
return;
}
#endif
#if defined WIFSIGNALED && defined WTERMSIG && HAVE_STRSIGNAL
if (WIFSIGNALED(status))
{
int sig = WTERMSIG(status);
if (sig != SIGPIPE || ch_length() != NULL_POSITION)
{
parg.p_string = signal_message(sig);
error("Input preprocessor terminated: %s", &parg);
}
return;
}
#endif
if (status != 0)
{
parg.p_int = status;
error("Input preprocessor exited with status %x", &parg);
}
}
/*
* Drain and close an input pipe if needed.
*/
public void close_altpipe(IFILE ifile)
{
FILE *altpipe = get_altpipe(ifile);
if (altpipe != NULL && !(ch_getflags() & CH_KEEPOPEN))
{
close_pipe(altpipe);
set_altpipe(ifile, NULL);
}
}
/*
* Check for error status from the current altpipe.
* May or may not close the pipe.
*/
public void check_altpipe_error(void)
{
if (!show_preproc_error)
return;
if (curr_ifile != NULL_IFILE && get_altfilename(curr_ifile) != NULL)
close_altpipe(curr_ifile);
} }
/* /*
* Close the current input file. * Close the current input file.
*/ */
static void static void close_file(void)
close_file(VOID_PARAM)
{ {
struct scrpos scrpos; struct scrpos scrpos;
int chflags;
FILE *altpipe;
char *altfilename; char *altfilename;
if (curr_ifile == NULL_IFILE) if (curr_ifile == NULL_IFILE)
@ -194,7 +366,6 @@ close_file(VOID_PARAM)
/* /*
* Close the file descriptor, unless it is a pipe. * Close the file descriptor, unless it is a pipe.
*/ */
chflags = ch_getflags();
ch_close(); ch_close();
/* /*
* If we opened a file using an alternate name, * If we opened a file using an alternate name,
@ -203,12 +374,7 @@ close_file(VOID_PARAM)
altfilename = get_altfilename(curr_ifile); altfilename = get_altfilename(curr_ifile);
if (altfilename != NULL) if (altfilename != NULL)
{ {
altpipe = get_altpipe(curr_ifile); close_altpipe(curr_ifile);
if (altpipe != NULL && !(chflags & CH_KEEPOPEN))
{
close_pipe(altpipe);
set_altpipe(curr_ifile, NULL);
}
close_altfile(altfilename, get_filename(curr_ifile)); close_altfile(altfilename, get_filename(curr_ifile));
set_altfilename(curr_ifile, NULL); set_altfilename(curr_ifile, NULL);
} }
@ -223,22 +389,46 @@ close_file(VOID_PARAM)
* Filename == "-" means standard input. * Filename == "-" means standard input.
* Filename == NULL means just close the current file. * Filename == NULL means just close the current file.
*/ */
public int public int edit(char *filename)
edit(filename)
char *filename;
{ {
if (filename == NULL) if (filename == NULL)
return (edit_ifile(NULL_IFILE)); return (edit_ifile(NULL_IFILE));
return (edit_ifile(get_ifile(filename, curr_ifile))); return (edit_ifile(get_ifile(filename, curr_ifile)));
} }
/*
* Clean up what edit_ifile did before error return.
*/
static int edit_error(char *filename, char *alt_filename, void *altpipe, IFILE ifile, IFILE was_curr_ifile)
{
if (alt_filename != NULL)
{
close_pipe(altpipe);
close_altfile(alt_filename, filename);
free(alt_filename);
}
del_ifile(ifile);
free(filename);
/*
* Re-open the current file.
*/
if (was_curr_ifile == ifile)
{
/*
* Whoops. The "current" ifile is the one we just deleted.
* Just give up.
*/
quit(QUIT_ERROR);
}
reedit_ifile(was_curr_ifile);
return (1);
}
/* /*
* Edit a new file (given its IFILE). * Edit a new file (given its IFILE).
* ifile == NULL means just close the current file. * ifile == NULL means just close the current file.
*/ */
public int public int edit_ifile(IFILE ifile)
edit_ifile(ifile)
IFILE ifile;
{ {
int f; int f;
int answer; int answer;
@ -371,28 +561,7 @@ edit_ifile(ifile)
*/ */
error("%s", &parg); error("%s", &parg);
free(parg.p_string); free(parg.p_string);
err1: return edit_error(filename, alt_filename, altpipe, ifile, was_curr_ifile);
if (alt_filename != NULL)
{
close_pipe(altpipe);
close_altfile(alt_filename, filename);
free(alt_filename);
}
del_ifile(ifile);
free(filename);
/*
* Re-open the current file.
*/
if (was_curr_ifile == ifile)
{
/*
* Whoops. The "current" ifile is the one we just deleted.
* Just give up.
*/
quit(QUIT_ERROR);
}
reedit_ifile(was_curr_ifile);
return (1);
} else if ((f = open(open_filename, OPEN_READ)) < 0) } else if ((f = open(open_filename, OPEN_READ)) < 0)
{ {
/* /*
@ -401,7 +570,7 @@ edit_ifile(ifile)
parg.p_string = errno_message(filename); parg.p_string = errno_message(filename);
error("%s", &parg); error("%s", &parg);
free(parg.p_string); free(parg.p_string);
goto err1; return edit_error(filename, alt_filename, altpipe, ifile, was_curr_ifile);
} else } else
{ {
chflags |= CH_CANSEEK; chflags |= CH_CANSEEK;
@ -417,11 +586,18 @@ edit_ifile(ifile)
if (answer != 'y' && answer != 'Y') if (answer != 'y' && answer != 'Y')
{ {
close(f); close(f);
goto err1; return edit_error(filename, alt_filename, altpipe, ifile, was_curr_ifile);
} }
} }
} }
} }
if (!force_open && f >= 0 && isatty(f))
{
PARG parg;
parg.p_string = filename;
error("%s is a terminal (use -f to open it)", &parg);
return edit_error(filename, alt_filename, altpipe, ifile, was_curr_ifile);
}
/* /*
* Get the new ifile. * Get the new ifile.
@ -440,6 +616,7 @@ edit_ifile(ifile)
new_file = TRUE; new_file = TRUE;
ch_init(f, chflags); ch_init(f, chflags);
consecutive_nulls = 0; consecutive_nulls = 0;
check_modelines();
if (!(chflags & CH_HELPFILE)) if (!(chflags & CH_HELPFILE))
{ {
@ -502,9 +679,7 @@ edit_ifile(ifile)
* For each filename in the list, enter it into the ifile list. * For each filename in the list, enter it into the ifile list.
* Then edit the first one. * Then edit the first one.
*/ */
public int public int edit_list(char *filelist)
edit_list(filelist)
char *filelist;
{ {
IFILE save_ifile; IFILE save_ifile;
char *good_filename; char *good_filename;
@ -563,8 +738,7 @@ edit_list(filelist)
/* /*
* Edit the first file in the command line (ifile) list. * Edit the first file in the command line (ifile) list.
*/ */
public int public int edit_first(void)
edit_first(VOID_PARAM)
{ {
if (nifile() == 0) if (nifile() == 0)
return (edit_stdin()); return (edit_stdin());
@ -575,8 +749,7 @@ edit_first(VOID_PARAM)
/* /*
* Edit the last file in the command line (ifile) list. * Edit the last file in the command line (ifile) list.
*/ */
public int public int edit_last(void)
edit_last(VOID_PARAM)
{ {
curr_ifile = NULL_IFILE; curr_ifile = NULL_IFILE;
return (edit_prev(1)); return (edit_prev(1));
@ -586,11 +759,7 @@ edit_last(VOID_PARAM)
/* /*
* Edit the n-th next or previous file in the command line (ifile) list. * Edit the n-th next or previous file in the command line (ifile) list.
*/ */
static int static int edit_istep(IFILE h, int n, int dir)
edit_istep(h, n, dir)
IFILE h;
int n;
int dir;
{ {
IFILE next; IFILE next;
@ -628,32 +797,22 @@ edit_istep(h, n, dir)
return (0); return (0);
} }
static int static int edit_inext(IFILE h, int n)
edit_inext(h, n)
IFILE h;
int n;
{ {
return (edit_istep(h, n, +1)); return (edit_istep(h, n, +1));
} }
public int public int edit_next(int n)
edit_next(n)
int n;
{ {
return edit_istep(curr_ifile, n, +1); return edit_istep(curr_ifile, n, +1);
} }
static int static int edit_iprev(IFILE h, int n)
edit_iprev(h, n)
IFILE h;
int n;
{ {
return (edit_istep(h, n, -1)); return (edit_istep(h, n, -1));
} }
public int public int edit_prev(int n)
edit_prev(n)
int n;
{ {
return edit_istep(curr_ifile, n, -1); return edit_istep(curr_ifile, n, -1);
} }
@ -661,9 +820,7 @@ edit_prev(n)
/* /*
* Edit a specific file in the command line (ifile) list. * Edit a specific file in the command line (ifile) list.
*/ */
public int public int edit_index(int n)
edit_index(n)
int n;
{ {
IFILE h; IFILE h;
@ -682,17 +839,14 @@ edit_index(n)
return (edit_ifile(h)); return (edit_ifile(h));
} }
public IFILE public IFILE save_curr_ifile(void)
save_curr_ifile(VOID_PARAM)
{ {
if (curr_ifile != NULL_IFILE) if (curr_ifile != NULL_IFILE)
hold_ifile(curr_ifile, 1); hold_ifile(curr_ifile, 1);
return (curr_ifile); return (curr_ifile);
} }
public void public void unsave_ifile(IFILE save_ifile)
unsave_ifile(save_ifile)
IFILE save_ifile;
{ {
if (save_ifile != NULL_IFILE) if (save_ifile != NULL_IFILE)
hold_ifile(save_ifile, -1); hold_ifile(save_ifile, -1);
@ -701,9 +855,7 @@ unsave_ifile(save_ifile)
/* /*
* Reedit the ifile which was previously open. * Reedit the ifile which was previously open.
*/ */
public void public void reedit_ifile(IFILE save_ifile)
reedit_ifile(save_ifile)
IFILE save_ifile;
{ {
IFILE next; IFILE next;
IFILE prev; IFILE prev;
@ -735,8 +887,7 @@ reedit_ifile(save_ifile)
quit(QUIT_ERROR); quit(QUIT_ERROR);
} }
public void public void reopen_curr_ifile(void)
reopen_curr_ifile(VOID_PARAM)
{ {
IFILE save_ifile = save_curr_ifile(); IFILE save_ifile = save_curr_ifile();
close_file(); close_file();
@ -746,8 +897,7 @@ reopen_curr_ifile(VOID_PARAM)
/* /*
* Edit standard input. * Edit standard input.
*/ */
public int public int edit_stdin(void)
edit_stdin(VOID_PARAM)
{ {
if (isatty(fd0)) if (isatty(fd0))
{ {
@ -761,8 +911,7 @@ edit_stdin(VOID_PARAM)
* Copy a file directly to standard output. * Copy a file directly to standard output.
* Used if standard output is not a tty. * Used if standard output is not a tty.
*/ */
public void public void cat_file(void)
cat_file(VOID_PARAM)
{ {
int c; int c;
@ -780,9 +929,7 @@ cat_file(VOID_PARAM)
* is standard input, create the log file. * is standard input, create the log file.
* We take care not to blindly overwrite an existing file. * We take care not to blindly overwrite an existing file.
*/ */
public void public void use_logfile(char *filename)
use_logfile(filename)
char *filename;
{ {
int exists; int exists;
int answer; int answer;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -54,13 +54,15 @@ extern IFILE old_ifile;
extern char openquote; extern char openquote;
extern char closequote; extern char closequote;
#endif #endif
#if HAVE_STAT_INO
extern ino_t curr_ino;
extern dev_t curr_dev;
#endif
/* /*
* Remove quotes around a filename. * Remove quotes around a filename.
*/ */
public char * public char * shell_unquote(char *str)
shell_unquote(str)
char *str;
{ {
char *name; char *name;
char *p; char *p;
@ -97,8 +99,7 @@ shell_unquote(str)
/* /*
* Get the shell's escape character. * Get the shell's escape character.
*/ */
public char * public char * get_meta_escape(void)
get_meta_escape(VOID_PARAM)
{ {
char *s; char *s;
@ -111,8 +112,7 @@ get_meta_escape(VOID_PARAM)
/* /*
* Get the characters which the shell considers to be "metacharacters". * Get the characters which the shell considers to be "metacharacters".
*/ */
static char * static char * metachars(void)
metachars(VOID_PARAM)
{ {
static char *mchars = NULL; static char *mchars = NULL;
@ -128,9 +128,7 @@ metachars(VOID_PARAM)
/* /*
* Is this a shell metacharacter? * Is this a shell metacharacter?
*/ */
static int static int metachar(char c)
metachar(c)
char c;
{ {
return (strchr(metachars(), c) != NULL); return (strchr(metachars(), c) != NULL);
} }
@ -138,9 +136,7 @@ metachar(c)
/* /*
* Insert a backslash before each metacharacter in a string. * Insert a backslash before each metacharacter in a string.
*/ */
public char * public char * shell_quote(char *s)
shell_quote(s)
char *s;
{ {
char *p; char *p;
char *newstr; char *newstr;
@ -216,11 +212,7 @@ shell_quote(s)
* Return a pathname that points to a specified file in a specified directory. * Return a pathname that points to a specified file in a specified directory.
* Return NULL if the file does not exist in the directory. * Return NULL if the file does not exist in the directory.
*/ */
public char * public char * dirfile(char *dirname, char *filename, int must_exist)
dirfile(dirname, filename, must_exist)
char *dirname;
char *filename;
int must_exist;
{ {
char *pathname; char *pathname;
int len; int len;
@ -257,9 +249,7 @@ dirfile(dirname, filename, must_exist)
/* /*
* Return the full pathname of the given file in the "home directory". * Return the full pathname of the given file in the "home directory".
*/ */
public char * public char * homefile(char *filename)
homefile(filename)
char *filename;
{ {
char *pathname; char *pathname;
@ -301,9 +291,7 @@ homefile(filename)
* Likewise for a string of N "#"s. * Likewise for a string of N "#"s.
* {{ This is a lot of work just to support % and #. }} * {{ This is a lot of work just to support % and #. }}
*/ */
public char * public char * fexpand(char *s)
fexpand(s)
char *s;
{ {
char *fr, *to; char *fr, *to;
int n; int n;
@ -397,9 +385,7 @@ fexpand(s)
* Return a blank-separated list of filenames which "complete" * Return a blank-separated list of filenames which "complete"
* the given string. * the given string.
*/ */
public char * public char * fcomplete(char *s)
fcomplete(s)
char *s;
{ {
char *fpat; char *fpat;
char *qs; char *qs;
@ -457,9 +443,7 @@ fcomplete(s)
* Try to determine if a file is "binary". * Try to determine if a file is "binary".
* This is just a guess, and we need not try too hard to make it accurate. * This is just a guess, and we need not try too hard to make it accurate.
*/ */
public int public int bin_file(int f)
bin_file(f)
int f;
{ {
int n; int n;
int bin_count = 0; int bin_count = 0;
@ -503,9 +487,7 @@ bin_file(f)
/* /*
* Try to determine the size of a file by seeking to the end. * Try to determine the size of a file by seeking to the end.
*/ */
static POSITION static POSITION seek_filesize(int f)
seek_filesize(f)
int f;
{ {
off_t spos; off_t spos;
@ -520,9 +502,7 @@ seek_filesize(f)
* Read a string from a file. * Read a string from a file.
* Return a pointer to the string in memory. * Return a pointer to the string in memory.
*/ */
static char * static char * readfd(FILE *fd)
readfd(fd)
FILE *fd;
{ {
int len; int len;
int ch; int ch;
@ -563,9 +543,7 @@ readfd(fd)
* Execute a shell command. * Execute a shell command.
* Return a pointer to a pipe connected to the shell command's standard output. * Return a pointer to a pipe connected to the shell command's standard output.
*/ */
static FILE * static FILE * shellcmd(char *cmd)
shellcmd(cmd)
char *cmd;
{ {
FILE *fd; FILE *fd;
@ -614,9 +592,7 @@ shellcmd(cmd)
/* /*
* Expand a filename, doing any system-specific metacharacter substitutions. * Expand a filename, doing any system-specific metacharacter substitutions.
*/ */
public char * public char * lglob(char *filename)
lglob(filename)
char *filename;
{ {
char *gfilename; char *gfilename;
@ -793,18 +769,28 @@ lglob(filename)
return (gfilename); return (gfilename);
} }
/*
* Does path not represent something in the file system?
*/
public int is_fake_pathname(char *path)
{
return (strcmp(path, "-") == 0 ||
strcmp(path, FAKE_HELPFILE) == 0 || strcmp(path, FAKE_EMPTYFILE) == 0);
}
/* /*
* Return canonical pathname. * Return canonical pathname.
*/ */
public char * public char * lrealpath(char *path)
lrealpath(path)
char *path;
{ {
if (!is_fake_pathname(path))
{
#if HAVE_REALPATH #if HAVE_REALPATH
char rpath[PATH_MAX]; char rpath[PATH_MAX];
if (realpath(path, rpath) != NULL) if (realpath(path, rpath) != NULL)
return (save(rpath)); return (save(rpath));
#endif #endif
}
return (save(path)); return (save(path));
} }
@ -813,9 +799,7 @@ lrealpath(path)
* Return number of %s escapes in a string. * Return number of %s escapes in a string.
* Return a large number if there are any other % escapes besides %s. * Return a large number if there are any other % escapes besides %s.
*/ */
static int static int num_pct_s(char *lessopen)
num_pct_s(lessopen)
char *lessopen;
{ {
int num = 0; int num = 0;
@ -840,11 +824,7 @@ num_pct_s(lessopen)
* See if we should open a "replacement file" * See if we should open a "replacement file"
* instead of the file we're about to open. * instead of the file we're about to open.
*/ */
public char * public char * open_altfile(char *filename, int *pf, void **pfd)
open_altfile(filename, pf, pfd)
char *filename;
int *pf;
void **pfd;
{ {
#if !HAVE_POPEN #if !HAVE_POPEN
return (NULL); return (NULL);
@ -965,10 +945,7 @@ open_altfile(filename, pf, pfd)
/* /*
* Close a replacement file. * Close a replacement file.
*/ */
public void public void close_altfile(char *altfilename, char *filename)
close_altfile(altfilename, filename)
char *altfilename;
char *filename;
{ {
#if HAVE_POPEN #if HAVE_POPEN
char *lessclose; char *lessclose;
@ -1005,9 +982,7 @@ close_altfile(altfilename, filename)
/* /*
* Is the specified file a directory? * Is the specified file a directory?
*/ */
public int public int is_dir(char *filename)
is_dir(filename)
char *filename;
{ {
int isdir = 0; int isdir = 0;
@ -1039,9 +1014,7 @@ is_dir(filename)
* is an ordinary file, otherwise an error message * is an ordinary file, otherwise an error message
* (if it cannot be opened or is a directory, etc.) * (if it cannot be opened or is a directory, etc.)
*/ */
public char * public char * bad_file(char *filename)
bad_file(filename)
char *filename;
{ {
char *m = NULL; char *m = NULL;
@ -1083,9 +1056,7 @@ bad_file(filename)
* Return the size of a file, as cheaply as possible. * Return the size of a file, as cheaply as possible.
* In Unix, we can stat the file. * In Unix, we can stat the file.
*/ */
public POSITION public POSITION filesize(int f)
filesize(f)
int f;
{ {
#if HAVE_STAT #if HAVE_STAT
struct stat statbuf; struct stat statbuf;
@ -1103,11 +1074,29 @@ filesize(f)
return (seek_filesize(f)); return (seek_filesize(f));
} }
public int curr_ifile_changed(void)
{
#if HAVE_STAT_INO
/*
* If the file's i-number or device has changed,
* or if the file is smaller than it previously was,
* the file must be different.
*/
struct stat st;
POSITION curr_pos = ch_tell();
int r = stat(get_filename(curr_ifile), &st);
if (r == 0 && (st.st_ino != curr_ino ||
st.st_dev != curr_dev ||
(curr_pos != NULL_POSITION && st.st_size < curr_pos)))
return (TRUE);
#endif
return (FALSE);
}
/* /*
* *
*/ */
public char * public char * shell_coption(void)
shell_coption(VOID_PARAM)
{ {
return ("-c"); return ("-c");
} }
@ -1115,9 +1104,7 @@ shell_coption(VOID_PARAM)
/* /*
* Return last component of a pathname. * Return last component of a pathname.
*/ */
public char * public char * last_component(char *name)
last_component(name)
char *name;
{ {
char *slash; char *slash;

View File

@ -1,4 +1,4 @@
/* Generated by "./mkutable -f2 Cf -- unicode/UnicodeData.txt" on Tue Jul 19 12:45:17 PDT 2022 */ /* Generated by "./mkutable -f2 Cf -- unicode/UnicodeData.txt" on Mon Nov 14 18:19:23 PST 2022 */
{ 0x00ad, 0x00ad }, /* Cf */ { 0x00ad, 0x00ad }, /* Cf */
{ 0x0600, 0x0605 }, /* Cf */ { 0x0600, 0x0605 }, /* Cf */
{ 0x061c, 0x061c }, /* Cf */ { 0x061c, 0x061c }, /* Cf */
@ -15,7 +15,7 @@
{ 0xfff9, 0xfffb }, /* Cf */ { 0xfff9, 0xfffb }, /* Cf */
{ 0x110bd, 0x110bd }, /* Cf */ { 0x110bd, 0x110bd }, /* Cf */
{ 0x110cd, 0x110cd }, /* Cf */ { 0x110cd, 0x110cd }, /* Cf */
{ 0x13430, 0x13438 }, /* Cf */ { 0x13430, 0x1343f }, /* Cf */
{ 0x1bca0, 0x1bca3 }, /* Cf */ { 0x1bca0, 0x1bca3 }, /* Cf */
{ 0x1d173, 0x1d17a }, /* Cf */ { 0x1d173, 0x1d17a }, /* Cf */
{ 0xe0001, 0xe0001 }, /* Cf */ { 0xe0001, 0xe0001 }, /* Cf */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -38,6 +38,7 @@ extern int clear_bg;
extern int final_attr; extern int final_attr;
extern int header_lines; extern int header_lines;
extern int header_cols; extern int header_cols;
extern int full_screen;
#if HILITE_SEARCH #if HILITE_SEARCH
extern int size_linebuf; extern int size_linebuf;
extern int hilite_search; extern int hilite_search;
@ -50,8 +51,7 @@ extern char *tagoption;
/* /*
* Sound the bell to indicate user is trying to move past end of file. * Sound the bell to indicate user is trying to move past end of file.
*/ */
static void public void eof_bell(void)
eof_bell(VOID_PARAM)
{ {
#if HAVE_TIME #if HAVE_TIME
static time_type last_eof_bell = 0; static time_type last_eof_bell = 0;
@ -69,8 +69,7 @@ eof_bell(VOID_PARAM)
/* /*
* Check to see if the end of file is currently displayed. * Check to see if the end of file is currently displayed.
*/ */
public int public int eof_displayed(void)
eof_displayed(VOID_PARAM)
{ {
POSITION pos; POSITION pos;
@ -96,8 +95,7 @@ eof_displayed(VOID_PARAM)
/* /*
* Check to see if the entire file is currently displayed. * Check to see if the entire file is currently displayed.
*/ */
public int public int entire_file_displayed(void)
entire_file_displayed(VOID_PARAM)
{ {
POSITION pos; POSITION pos;
@ -116,8 +114,7 @@ entire_file_displayed(VOID_PARAM)
* of the screen; this can happen when we display a short file * of the screen; this can happen when we display a short file
* for the first time. * for the first time.
*/ */
public void public void squish_check(void)
squish_check(VOID_PARAM)
{ {
if (!squished) if (!squished)
return; return;
@ -129,11 +126,7 @@ squish_check(VOID_PARAM)
* Read the first pfx columns of the next line. * Read the first pfx columns of the next line.
* If skipeol==0 stop there, otherwise read and discard chars to end of line. * If skipeol==0 stop there, otherwise read and discard chars to end of line.
*/ */
static POSITION static POSITION forw_line_pfx(POSITION pos, int pfx, int skipeol)
forw_line_pfx(pos, pfx, skipeol)
POSITION pos;
int pfx;
int skipeol;
{ {
int save_sc_width = sc_width; int save_sc_width = sc_width;
int save_auto_wrap = auto_wrap; int save_auto_wrap = auto_wrap;
@ -154,9 +147,7 @@ forw_line_pfx(pos, pfx, skipeol)
* Underline last line of headers, but not at beginning of file * 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). * (where there is no gap between the last header line and the next line).
*/ */
static void static void set_attr_header(int ln)
set_attr_header(ln)
int ln;
{ {
set_attr_line(AT_COLOR_HEADER); set_attr_line(AT_COLOR_HEADER);
if (ln+1 == header_lines && position(0) != ch_zero()) if (ln+1 == header_lines && position(0) != ch_zero())
@ -167,8 +158,7 @@ set_attr_header(ln)
* Display file headers, overlaying text already drawn * Display file headers, overlaying text already drawn
* at top and left of screen. * at top and left of screen.
*/ */
public int public int overlay_header(void)
overlay_header(VOID_PARAM)
{ {
POSITION pos = ch_zero(); /* header lines are at beginning of file */ POSITION pos = ch_zero(); /* header lines are at beginning of file */
int ln; int ln;
@ -222,13 +212,7 @@ overlay_header(VOID_PARAM)
* real line. If nblank > 0, the pos must be NULL_POSITION. * real line. If nblank > 0, the pos must be NULL_POSITION.
* The first real line after the blanks will start at ch_zero(). * The first real line after the blanks will start at ch_zero().
*/ */
public void public void forw(int n, POSITION pos, int force, int only_last, int nblank)
forw(n, pos, force, only_last, nblank)
int n;
POSITION pos;
int force;
int only_last;
int nblank;
{ {
int nlines = 0; int nlines = 0;
int do_repaint; int do_repaint;
@ -287,7 +271,7 @@ forw(n, pos, force, only_last, nblank)
{ {
clear(); clear();
home(); home();
} else if (!first_time && !is_filtering()) } else if (!first_time && !is_filtering() && full_screen)
{ {
putstr("...skipping...\n"); putstr("...skipping...\n");
} }
@ -354,6 +338,7 @@ forw(n, pos, force, only_last, nblank)
*/ */
if ((first_time || less_is_more) && if ((first_time || less_is_more) &&
pos == NULL_POSITION && !top_scroll && pos == NULL_POSITION && !top_scroll &&
header_lines == 0 && header_cols == 0 &&
#if TAGS #if TAGS
tagoption == NULL && tagoption == NULL &&
#endif #endif
@ -415,12 +400,7 @@ forw(n, pos, force, only_last, nblank)
/* /*
* Display n lines, scrolling backward. * Display n lines, scrolling backward.
*/ */
public void public void back(int n, POSITION pos, int force, int only_last)
back(n, pos, force, only_last)
int n;
POSITION pos;
int force;
int only_last;
{ {
int nlines = 0; int nlines = 0;
int do_repaint; int do_repaint;
@ -479,11 +459,7 @@ back(n, pos, force, only_last)
* Display n more lines, forward. * Display n more lines, forward.
* Start just after the line currently displayed at the bottom of the screen. * Start just after the line currently displayed at the bottom of the screen.
*/ */
public void public void forward(int n, int force, int only_last)
forward(n, force, only_last)
int n;
int force;
int only_last;
{ {
POSITION pos; POSITION pos;
@ -531,11 +507,7 @@ forward(n, force, only_last)
* Display n more lines, backward. * Display n more lines, backward.
* Start just before the line currently displayed at the top of the screen. * Start just before the line currently displayed at the top of the screen.
*/ */
public void public void backward(int n, int force, int only_last)
backward(n, force, only_last)
int n;
int force;
int only_last;
{ {
POSITION pos; POSITION pos;
@ -554,8 +526,7 @@ backward(n, force, only_last)
* back_scroll, because the default case depends on sc_height and * back_scroll, because the default case depends on sc_height and
* top_scroll, as well as back_scroll. * top_scroll, as well as back_scroll.
*/ */
public int public int get_back_scroll(void)
get_back_scroll(VOID_PARAM)
{ {
if (no_back_scroll) if (no_back_scroll)
return (0); return (0);
@ -569,8 +540,7 @@ get_back_scroll(VOID_PARAM)
/* /*
* Will the entire file fit on one screen? * Will the entire file fit on one screen?
*/ */
public int public int get_one_screen(void)
get_one_screen(VOID_PARAM)
{ {
int nlines; int nlines;
POSITION pos = ch_zero(); POSITION pos = ch_zero();

View File

@ -1,364 +1,384 @@
public char * save LESSPARAMS ((constant char *s)); public char * save(constant char *s);
public VOID_POINTER ecalloc LESSPARAMS ((int count, unsigned int size)); public void out_of_memory(void);
public char * skipsp LESSPARAMS ((char *s)); public void * ecalloc(int count, unsigned int size);
public int sprefix LESSPARAMS ((char *ps, char *s, int uppercase)); public char * skipsp(char *s);
public void quit LESSPARAMS ((int status)); public int sprefix(char *ps, char *s, int uppercase);
public void raw_mode LESSPARAMS ((int on)); public void quit(int status);
public void scrsize LESSPARAMS ((VOID_PARAM)); public void raw_mode(int on);
public char * special_key_str LESSPARAMS ((int key)); public void scrsize(void);
public void get_term LESSPARAMS ((VOID_PARAM)); public char * special_key_str(int key);
public void init_mouse LESSPARAMS ((VOID_PARAM)); public void get_term(void);
public void deinit_mouse LESSPARAMS ((VOID_PARAM)); public void init_mouse(void);
public void init LESSPARAMS ((VOID_PARAM)); public void deinit_mouse(void);
public void deinit LESSPARAMS ((VOID_PARAM)); public void init(void);
public int interactive LESSPARAMS ((VOID_PARAM)); public void deinit(void);
public void home LESSPARAMS ((VOID_PARAM)); public int interactive(void);
public void add_line LESSPARAMS ((VOID_PARAM)); public void home(void);
public void remove_top LESSPARAMS ((int n)); public void dump_screen(void);
public void win32_scroll_up LESSPARAMS ((int n)); public void add_line(void);
public void lower_left LESSPARAMS ((VOID_PARAM)); public void remove_top(int n);
public void line_left LESSPARAMS ((VOID_PARAM)); public void win32_scroll_up(int n);
public void check_winch LESSPARAMS ((VOID_PARAM)); public void lower_left(void);
public void goto_line LESSPARAMS ((int sindex)); public void line_left(void);
public void vbell LESSPARAMS ((VOID_PARAM)); public void check_winch(void);
public void bell LESSPARAMS ((VOID_PARAM)); public void goto_line(int sindex);
public void clear LESSPARAMS ((VOID_PARAM)); public void vbell(void);
public void clear_eol LESSPARAMS ((VOID_PARAM)); public void bell(void);
public void clear_bot LESSPARAMS ((VOID_PARAM)); public void clear(void);
public COLOR_TYPE parse_color LESSPARAMS ((char *str, int *p_fg, int *p_bg)); public void clear_eol(void);
public void at_enter LESSPARAMS ((int attr)); public void clear_bot(void);
public void at_exit LESSPARAMS ((VOID_PARAM)); public COLOR_TYPE parse_color(char *str, int *p_fg, int *p_bg);
public void at_switch LESSPARAMS ((int attr)); public void at_enter(int attr);
public int is_at_equiv LESSPARAMS ((int attr1, int attr2)); public void at_exit(void);
public int apply_at_specials LESSPARAMS ((int attr)); public void at_switch(int attr);
public void putbs LESSPARAMS ((VOID_PARAM)); public int is_at_equiv(int attr1, int attr2);
public int win32_kbhit LESSPARAMS ((VOID_PARAM)); public int apply_at_specials(int attr);
public char WIN32getch LESSPARAMS ((VOID_PARAM)); public void putbs(void);
public void WIN32setcolors LESSPARAMS ((int fg, int bg)); public int win32_kbhit(void);
public void WIN32textout LESSPARAMS ((char *text, int len)); public char WIN32getch(void);
public void match_brac LESSPARAMS ((int obrac, int cbrac, int forwdir, int n)); public void WIN32setcolors(int fg, int bg);
public void ch_ungetchar LESSPARAMS ((int c)); public void WIN32textout(char *text, int len);
public void end_logfile LESSPARAMS ((VOID_PARAM)); public void match_brac(char obrac, char cbrac, int forwdir, int n);
public void sync_logfile LESSPARAMS ((VOID_PARAM)); public void ch_ungetchar(int c);
public int ch_seek LESSPARAMS ((POSITION pos)); public void end_logfile(void);
public int ch_end_seek LESSPARAMS ((VOID_PARAM)); public void sync_logfile(void);
public int ch_end_buffer_seek LESSPARAMS ((VOID_PARAM)); public int ch_seek(POSITION pos);
public int ch_beg_seek LESSPARAMS ((VOID_PARAM)); public int ch_end_seek(void);
public POSITION ch_length LESSPARAMS ((VOID_PARAM)); public int ch_end_buffer_seek(void);
public POSITION ch_tell LESSPARAMS ((VOID_PARAM)); public int ch_beg_seek(void);
public int ch_forw_get LESSPARAMS ((VOID_PARAM)); public POSITION ch_length(void);
public int ch_back_get LESSPARAMS ((VOID_PARAM)); public POSITION ch_tell(void);
public void ch_setbufspace LESSPARAMS ((int bufspace)); public int ch_forw_get(void);
public void ch_flush LESSPARAMS ((VOID_PARAM)); public int ch_back_get(void);
public int seekable LESSPARAMS ((int f)); public void ch_setbufspace(int bufspace);
public void ch_set_eof LESSPARAMS ((VOID_PARAM)); public void ch_flush(void);
public void ch_init LESSPARAMS ((int f, int flags)); public int seekable(int f);
public void ch_close LESSPARAMS ((VOID_PARAM)); public void ch_set_eof(void);
public int ch_getflags LESSPARAMS ((VOID_PARAM)); public void ch_init(int f, int flags);
public void ch_dump LESSPARAMS ((VOID_PARAM)); public void ch_close(void);
public void setfmt LESSPARAMS ((char *s, char **fmtvarptr, int *attrptr, char *default_fmt)); public int ch_getflags(void);
public void init_charset LESSPARAMS ((VOID_PARAM)); public void setfmt(char *s, char **fmtvarptr, int *attrptr, char *default_fmt, int for_printf);
public int binary_char LESSPARAMS ((LWCHAR c)); public void init_charset(void);
public int control_char LESSPARAMS ((LWCHAR c)); public int binary_char(LWCHAR c);
public char * prchar LESSPARAMS ((LWCHAR c)); public int control_char(LWCHAR c);
public char * prutfchar LESSPARAMS ((LWCHAR ch)); public char * prchar(LWCHAR c);
public int utf_len LESSPARAMS ((int ch)); public char * prutfchar(LWCHAR ch);
public int is_utf8_well_formed LESSPARAMS ((char *ss, int slen)); public int utf_len(int ch);
public void utf_skip_to_lead LESSPARAMS ((char **pp, char *limit)); public int is_utf8_well_formed(char *ss, int slen);
public LWCHAR get_wchar LESSPARAMS ((constant char *p)); public void utf_skip_to_lead(char **pp, char *limit);
public void put_wchar LESSPARAMS ((char **pp, LWCHAR ch)); public LWCHAR get_wchar(constant char *p);
public LWCHAR step_char LESSPARAMS ((char **pp, signed int dir, constant char *limit)); public void put_wchar(char **pp, LWCHAR ch);
public int is_composing_char LESSPARAMS ((LWCHAR ch)); public LWCHAR step_char(char **pp, signed int dir, constant char *limit);
public int is_ubin_char LESSPARAMS ((LWCHAR ch)); public int is_composing_char(LWCHAR ch);
public int is_wide_char LESSPARAMS ((LWCHAR ch)); public int is_ubin_char(LWCHAR ch);
public int is_combining_char LESSPARAMS ((LWCHAR ch1, LWCHAR ch2)); public int is_wide_char(LWCHAR ch);
public void cmd_reset LESSPARAMS ((VOID_PARAM)); public int is_combining_char(LWCHAR ch1, LWCHAR ch2);
public void clear_cmd LESSPARAMS ((VOID_PARAM)); public void cmd_reset(void);
public void cmd_putstr LESSPARAMS ((constant char *s)); public void clear_cmd(void);
public int len_cmdbuf LESSPARAMS ((VOID_PARAM)); public void cmd_putstr(constant char *s);
public void cmd_repaint LESSPARAMS ((constant char *old_cp)); public int len_cmdbuf(void);
public void set_mlist LESSPARAMS ((void *mlist, int cmdflags)); public void cmd_repaint(constant char *old_cp);
public void cmd_addhist LESSPARAMS ((struct mlist *mlist, constant char *cmd, int modified)); public void set_mlist(void *mlist, int cmdflags);
public void cmd_accept LESSPARAMS ((VOID_PARAM)); public void cmd_addhist(struct mlist *mlist, constant char *cmd, int modified);
public int cmd_char LESSPARAMS ((int c)); public void cmd_accept(void);
public LINENUM cmd_int LESSPARAMS ((long *frac)); public int cmd_char(int c);
public char * get_cmdbuf LESSPARAMS ((VOID_PARAM)); public LINENUM cmd_int(long *frac);
public char * cmd_lastpattern LESSPARAMS ((VOID_PARAM)); public char * get_cmdbuf(void);
public void init_cmdhist LESSPARAMS ((VOID_PARAM)); public char * cmd_lastpattern(void);
public void save_cmdhist LESSPARAMS ((VOID_PARAM)); public void init_cmdhist(void);
public int in_mca LESSPARAMS ((VOID_PARAM)); public void save_cmdhist(void);
public int norm_search_type LESSPARAMS ((int st)); public int in_mca(void);
public void dispversion LESSPARAMS ((VOID_PARAM)); public int norm_search_type(int st);
public int getcc LESSPARAMS ((VOID_PARAM)); public void dispversion(void);
public void ungetcc LESSPARAMS ((LWCHAR c)); public int getcc(void);
public void ungetcc_back LESSPARAMS ((LWCHAR c)); public void ungetcc(LWCHAR c);
public void ungetsc LESSPARAMS ((char *s)); public void ungetcc_back(LWCHAR c);
public LWCHAR peekcc LESSPARAMS ((VOID_PARAM)); public void ungetsc(char *s);
public void commands LESSPARAMS ((VOID_PARAM)); public LWCHAR peekcc(void);
public int cvt_length LESSPARAMS ((int len, int ops)); public void commands(void);
public int * cvt_alloc_chpos LESSPARAMS ((int len)); public int cvt_length(int len, int ops);
public void cvt_text LESSPARAMS ((char *odst, char *osrc, int *chpos, int *lenp, int ops)); public int * cvt_alloc_chpos(int len);
public void expand_cmd_tables LESSPARAMS ((VOID_PARAM)); public void cvt_text(char *odst, char *osrc, int *chpos, int *lenp, int ops);
public void init_cmds LESSPARAMS ((VOID_PARAM)); public void expand_cmd_tables(void);
public void add_fcmd_table LESSPARAMS ((char *buf, int len)); public void init_cmds(void);
public void add_ecmd_table LESSPARAMS ((char *buf, int len)); public void add_fcmd_table(char *buf, int len);
public int fcmd_decode LESSPARAMS ((char *cmd, char **sp)); public void add_ecmd_table(char *buf, int len);
public int ecmd_decode LESSPARAMS ((char *cmd, char **sp)); public int fcmd_decode(char *cmd, char **sp);
public char * lgetenv LESSPARAMS ((char *var)); public int ecmd_decode(char *cmd, char **sp);
public int isnullenv LESSPARAMS ((char* s)); public char * lgetenv(char *var);
public int lesskey LESSPARAMS ((char *filename, int sysvar)); public int isnullenv(char *s);
public int lesskey_src LESSPARAMS ((char *filename, int sysvar)); public int lesskey(char *filename, int sysvar);
public int add_hometable LESSPARAMS ((int (*call_lesskey)(char *, int), char *envname, char *def_filename, int sysvar)); public int lesskey_src(char *filename, int sysvar);
public int editchar LESSPARAMS ((int c, int flags)); public int add_hometable(int (*call_lesskey)(char *, int), char *envname, char *def_filename, int sysvar);
public void init_textlist LESSPARAMS ((struct textlist *tlist, char *str)); public int editchar(int c, int flags);
public char * forw_textlist LESSPARAMS ((struct textlist *tlist, char *prev)); public void init_textlist(struct textlist *tlist, char *str);
public char * back_textlist LESSPARAMS ((struct textlist *tlist, char *prev)); public char * forw_textlist(struct textlist *tlist, char *prev);
public int edit LESSPARAMS ((char *filename)); public char * back_textlist(struct textlist *tlist, char *prev);
public int edit_ifile LESSPARAMS ((IFILE ifile)); public void close_altpipe(IFILE ifile);
public int edit_list LESSPARAMS ((char *filelist)); public void check_altpipe_error(void);
public int edit_first LESSPARAMS ((VOID_PARAM)); public int edit(char *filename);
public int edit_last LESSPARAMS ((VOID_PARAM)); public int edit_ifile(IFILE ifile);
public int edit_next LESSPARAMS ((int n)); public int edit_list(char *filelist);
public int edit_prev LESSPARAMS ((int n)); public int edit_first(void);
public int edit_index LESSPARAMS ((int n)); public int edit_last(void);
public IFILE save_curr_ifile LESSPARAMS ((VOID_PARAM)); public int edit_next(int n);
public void unsave_ifile LESSPARAMS ((IFILE save_ifile)); public int edit_prev(int n);
public void reedit_ifile LESSPARAMS ((IFILE save_ifile)); public int edit_index(int n);
public void reopen_curr_ifile LESSPARAMS ((VOID_PARAM)); public IFILE save_curr_ifile(void);
public int edit_stdin LESSPARAMS ((VOID_PARAM)); public void unsave_ifile(IFILE save_ifile);
public void cat_file LESSPARAMS ((VOID_PARAM)); public void reedit_ifile(IFILE save_ifile);
public void use_logfile LESSPARAMS ((char *filename)); public void reopen_curr_ifile(void);
public char * shell_unquote LESSPARAMS ((char *str)); public int edit_stdin(void);
public char * get_meta_escape LESSPARAMS ((VOID_PARAM)); public void cat_file(void);
public char * shell_quote LESSPARAMS ((char *s)); public void use_logfile(char *filename);
public char * dirfile LESSPARAMS ((char *dirname, char *filename, int must_exist)); public char * shell_unquote(char *str);
public char * homefile LESSPARAMS ((char *filename)); public char * get_meta_escape(void);
public char * fexpand LESSPARAMS ((char *s)); public char * shell_quote(char *s);
public char * fcomplete LESSPARAMS ((char *s)); public char * dirfile(char *dirname, char *filename, int must_exist);
public int bin_file LESSPARAMS ((int f)); public char * homefile(char *filename);
public char * lglob LESSPARAMS ((char *filename)); public char * fexpand(char *s);
public char * lrealpath LESSPARAMS ((char *path)); public char * fcomplete(char *s);
public char * open_altfile LESSPARAMS ((char *filename, int *pf, void **pfd)); public int bin_file(int f);
public void close_altfile LESSPARAMS ((char *altfilename, char *filename)); public char * lglob(char *filename);
public int is_dir LESSPARAMS ((char *filename)); public int is_fake_pathname(char *path);
public char * bad_file LESSPARAMS ((char *filename)); public char * lrealpath(char *path);
public POSITION filesize LESSPARAMS ((int f)); public char * open_altfile(char *filename, int *pf, void **pfd);
public char * shell_coption LESSPARAMS ((VOID_PARAM)); public void close_altfile(char *altfilename, char *filename);
public char * last_component LESSPARAMS ((char *name)); public int is_dir(char *filename);
public int eof_displayed LESSPARAMS ((VOID_PARAM)); public char * bad_file(char *filename);
public int entire_file_displayed LESSPARAMS ((VOID_PARAM)); public POSITION filesize(int f);
public void squish_check LESSPARAMS ((VOID_PARAM)); public int curr_ifile_changed(void);
public int overlay_header LESSPARAMS ((VOID_PARAM)); public char * shell_coption(void);
public void forw LESSPARAMS ((int n, POSITION pos, int force, int only_last, int nblank)); public char * last_component(char *name);
public void back LESSPARAMS ((int n, POSITION pos, int force, int only_last)); public void eof_bell(void);
public void forward LESSPARAMS ((int n, int force, int only_last)); public int eof_displayed(void);
public void backward LESSPARAMS ((int n, int force, int only_last)); public int entire_file_displayed(void);
public int get_back_scroll LESSPARAMS ((VOID_PARAM)); public void squish_check(void);
public int get_one_screen LESSPARAMS ((VOID_PARAM)); public int overlay_header(void);
public void del_ifile LESSPARAMS ((IFILE h)); public void forw(int n, POSITION pos, int force, int only_last, int nblank);
public IFILE next_ifile LESSPARAMS ((IFILE h)); public void back(int n, POSITION pos, int force, int only_last);
public IFILE prev_ifile LESSPARAMS ((IFILE h)); public void forward(int n, int force, int only_last);
public IFILE getoff_ifile LESSPARAMS ((IFILE ifile)); public void backward(int n, int force, int only_last);
public int nifile LESSPARAMS ((VOID_PARAM)); public int get_back_scroll(void);
public IFILE get_ifile LESSPARAMS ((char *filename, IFILE prev)); public int get_one_screen(void);
public char * get_filename LESSPARAMS ((IFILE ifile)); public void del_ifile(IFILE h);
public char * get_real_filename LESSPARAMS ((IFILE ifile)); public IFILE next_ifile(IFILE h);
public int get_index LESSPARAMS ((IFILE ifile)); public IFILE prev_ifile(IFILE h);
public void store_pos LESSPARAMS ((IFILE ifile, struct scrpos *scrpos)); public IFILE getoff_ifile(IFILE ifile);
public void get_pos LESSPARAMS ((IFILE ifile, struct scrpos *scrpos)); public int nifile(void);
public void set_open LESSPARAMS ((IFILE ifile)); public IFILE get_ifile(char *filename, IFILE prev);
public int opened LESSPARAMS ((IFILE ifile)); public char * get_filename(IFILE ifile);
public void hold_ifile LESSPARAMS ((IFILE ifile, int incr)); public char * get_real_filename(IFILE ifile);
public int held_ifile LESSPARAMS ((IFILE ifile)); public int get_index(IFILE ifile);
public void * get_filestate LESSPARAMS ((IFILE ifile)); public void store_pos(IFILE ifile, struct scrpos *scrpos);
public void set_filestate LESSPARAMS ((IFILE ifile, void *filestate)); public void get_pos(IFILE ifile, struct scrpos *scrpos);
public void set_altpipe LESSPARAMS ((IFILE ifile, void *p)); public void set_open(IFILE ifile);
public void * get_altpipe LESSPARAMS ((IFILE ifile)); public int opened(IFILE ifile);
public void set_altfilename LESSPARAMS ((IFILE ifile, char *altfilename)); public void hold_ifile(IFILE ifile, int incr);
public char * get_altfilename LESSPARAMS ((IFILE ifile)); public int held_ifile(IFILE ifile);
public void if_dump LESSPARAMS ((VOID_PARAM)); public void * get_filestate(IFILE ifile);
public POSITION forw_line_seg LESSPARAMS ((POSITION curr_pos, int skipeol, int rscroll, int nochop)); public void set_filestate(IFILE ifile, void *filestate);
public POSITION forw_line LESSPARAMS ((POSITION curr_pos)); public void set_altpipe(IFILE ifile, void *p);
public POSITION back_line LESSPARAMS ((POSITION curr_pos)); public void *get_altpipe(IFILE ifile);
public void set_attnpos LESSPARAMS ((POSITION pos)); public void set_altfilename(IFILE ifile, char *altfilename);
public void jump_forw LESSPARAMS ((VOID_PARAM)); public char * get_altfilename(IFILE ifile);
public void jump_forw_buffered LESSPARAMS ((VOID_PARAM)); public void if_dump(void);
public void jump_back LESSPARAMS ((LINENUM linenum)); public POSITION forw_line_seg(POSITION curr_pos, int skipeol, int rscroll, int nochop);
public void repaint LESSPARAMS ((VOID_PARAM)); public POSITION forw_line(POSITION curr_pos);
public void jump_percent LESSPARAMS ((int percent, long fraction)); public POSITION back_line(POSITION curr_pos);
public void jump_line_loc LESSPARAMS ((POSITION pos, int sline)); public void set_attnpos(POSITION pos);
public void jump_loc LESSPARAMS ((POSITION pos, int sline)); public void jump_forw(void);
public void init_line LESSPARAMS ((VOID_PARAM)); public void jump_forw_buffered(void);
public int is_ascii_char LESSPARAMS ((LWCHAR ch)); public void jump_back(LINENUM linenum);
public void prewind LESSPARAMS ((VOID_PARAM)); public void repaint(void);
public void plinestart LESSPARAMS ((POSITION pos)); public void jump_percent(int percent, long fraction);
public int line_pfx_width LESSPARAMS ((VOID_PARAM)); public void jump_line_loc(POSITION pos, int sline);
public void pshift_all LESSPARAMS ((VOID_PARAM)); public void jump_loc(POSITION pos, int sline);
public int pwidth LESSPARAMS ((LWCHAR ch, int a, LWCHAR prev_ch, int prev_a)); public void init_line(void);
public int is_ansi_end LESSPARAMS ((LWCHAR ch)); public int is_ascii_char(LWCHAR ch);
public int is_ansi_middle LESSPARAMS ((LWCHAR ch)); public POSITION line_position(void);
public void skip_ansi LESSPARAMS ((struct ansi_state *pansi, char **pp, constant char *limit)); public void prewind(void);
public struct ansi_state * ansi_start LESSPARAMS ((LWCHAR ch)); public void plinestart(POSITION pos);
public int ansi_step LESSPARAMS ((struct ansi_state *pansi, LWCHAR ch)); public int line_pfx_width(void);
public void ansi_done LESSPARAMS ((struct ansi_state *pansi)); public void pshift_all(void);
public int pappend LESSPARAMS ((int c, POSITION pos)); public int pwidth(LWCHAR ch, int a, LWCHAR prev_ch, int prev_a);
public int pflushmbc LESSPARAMS ((VOID_PARAM)); public void savec(void);
public void pdone LESSPARAMS ((int endline, int chopped, int forw)); public void loadc(void);
public void set_attr_line LESSPARAMS ((int a)); public int is_ansi_end(LWCHAR ch);
public void set_status_col LESSPARAMS ((int c, int attr)); public int is_ansi_middle(LWCHAR ch);
public int gline LESSPARAMS ((int i, int *ap)); public void skip_ansi(struct ansi_state *pansi, char **pp, constant char *limit);
public void null_line LESSPARAMS ((VOID_PARAM)); public struct ansi_state * ansi_start(LWCHAR ch);
public POSITION forw_raw_line LESSPARAMS ((POSITION curr_pos, char **linep, int *line_lenp)); public int ansi_step(struct ansi_state *pansi, LWCHAR ch);
public POSITION back_raw_line LESSPARAMS ((POSITION curr_pos, char **linep, int *line_lenp)); public void ansi_done(struct ansi_state *pansi);
public void load_line LESSPARAMS ((constant char *str)); public int pappend(int c, POSITION pos);
public int rrshift LESSPARAMS ((VOID_PARAM)); public int pflushmbc(void);
public int set_color_map LESSPARAMS ((int attr, char *colorstr)); public void pdone(int endline, int chopped, int forw);
public char * get_color_map LESSPARAMS ((int attr)); public void set_attr_line(int a);
public void clr_linenum LESSPARAMS ((VOID_PARAM)); public void set_status_col(char c, int attr);
public void add_lnum LESSPARAMS ((LINENUM linenum, POSITION pos)); public int gline(int i, int *ap);
public LINENUM find_linenum LESSPARAMS ((POSITION pos)); public void null_line(void);
public POSITION find_pos LESSPARAMS ((LINENUM linenum)); public POSITION forw_raw_line(POSITION curr_pos, char **linep, int *line_lenp);
public LINENUM currline LESSPARAMS ((int where)); public POSITION back_raw_line(POSITION curr_pos, char **linep, int *line_lenp);
public void scan_eof LESSPARAMS ((VOID_PARAM)); public int skip_columns(int cols, char **linep, int *line_lenp);
public LINENUM vlinenum LESSPARAMS ((LINENUM linenum)); public void load_line(constant char *str);
public void lsystem LESSPARAMS ((char *cmd, char *donemsg)); public int rrshift(void);
public int pipe_mark LESSPARAMS ((int c, char *cmd)); public int set_color_map(int attr, char *colorstr);
public int pipe_data LESSPARAMS ((char *cmd, POSITION spos, POSITION epos)); public char * get_color_map(int attr);
public void init_mark LESSPARAMS ((VOID_PARAM)); public void clr_linenum(void);
public int badmark LESSPARAMS ((int c)); public void add_lnum(LINENUM linenum, POSITION pos);
public void setmark LESSPARAMS ((int c, int where)); public LINENUM find_linenum(POSITION pos);
public void clrmark LESSPARAMS ((int c)); public POSITION find_pos(LINENUM linenum);
public void lastmark LESSPARAMS ((VOID_PARAM)); public LINENUM currline(int where);
public void gomark LESSPARAMS ((int c)); public void scan_eof(void);
public POSITION markpos LESSPARAMS ((int c)); public LINENUM vlinenum(LINENUM linenum);
public char posmark LESSPARAMS ((POSITION pos)); public void lsystem(char *cmd, char *donemsg);
public void unmark LESSPARAMS ((IFILE ifile)); public int pipe_mark(int c, char *cmd);
public void mark_check_ifile LESSPARAMS ((IFILE ifile)); public int pipe_data(char *cmd, POSITION spos, POSITION epos);
public void save_marks LESSPARAMS ((FILE *fout, char *hdr)); public void init_mark(void);
public void restore_mark LESSPARAMS ((char *line)); public int badmark(LWCHAR c);
public void opt_o LESSPARAMS ((int type, char *s)); public void setmark(LWCHAR c, int where);
public void opt__O LESSPARAMS ((int type, char *s)); public void clrmark(LWCHAR c);
public void opt_j LESSPARAMS ((int type, char *s)); public void lastmark(void);
public void calc_jump_sline LESSPARAMS ((VOID_PARAM)); public void gomark(LWCHAR c);
public void opt_shift LESSPARAMS ((int type, char *s)); public POSITION markpos(LWCHAR c);
public void calc_shift_count LESSPARAMS ((VOID_PARAM)); public char posmark(POSITION pos);
public void opt_k LESSPARAMS ((int type, char *s)); public void unmark(IFILE ifile);
public void opt_ks LESSPARAMS ((int type, char *s)); public void mark_check_ifile(IFILE ifile);
public void opt_t LESSPARAMS ((int type, char *s)); public void save_marks(FILE *fout, char *hdr);
public void opt__T LESSPARAMS ((int type, char *s)); public void restore_mark(char *line);
public void opt_p LESSPARAMS ((int type, char *s)); public void opt_o(int type, char *s);
public void opt__P LESSPARAMS ((int type, char *s)); public void opt__O(int type, char *s);
public void opt_b LESSPARAMS ((int type, char *s)); public void opt_j(int type, char *s);
public void opt_i LESSPARAMS ((int type, char *s)); public void calc_jump_sline(void);
public void opt__V LESSPARAMS ((int type, char *s)); public void opt_shift(int type, char *s);
public void opt_D LESSPARAMS ((int type, char *s)); public void calc_shift_count(void);
public void opt_x LESSPARAMS ((int type, char *s)); public void opt_k(int type, char *s);
public void opt_quote LESSPARAMS ((int type, char *s)); public void opt_ks(int type, char *s);
public void opt_rscroll LESSPARAMS ((int type, char *s)); public void opt_t(int type, char *s);
public void opt_query LESSPARAMS ((int type, char *s)); public void opt__T(int type, char *s);
public void opt_mousecap LESSPARAMS ((int type, char *s)); public void opt_p(int type, char *s);
public void opt_wheel_lines LESSPARAMS ((int type, char *s)); public void opt__P(int type, char *s);
public void opt_linenum_width LESSPARAMS ((int type, char *s)); public void opt_b(int type, char *s);
public void opt_status_col_width LESSPARAMS ((int type, char *s)); public void opt_i(int type, char *s);
public void opt_filesize LESSPARAMS ((int type, char *s)); public void opt__V(int type, char *s);
public void opt_header LESSPARAMS ((int type, char *s)); public void opt_D(int type, char *s);
public void opt_search_type LESSPARAMS ((int type, char *s)); public void set_tabs(char *s, int len);
public void opt_ttyin_name LESSPARAMS ((int type, char *s)); public void opt_x(int type, char *s);
public void opt_rstat LESSPARAMS ((int type, char *s)); public void opt_quote(int type, char *s);
public int chop_line LESSPARAMS ((VOID_PARAM)); public void opt_rscroll(int type, char *s);
public int get_swindow LESSPARAMS ((VOID_PARAM)); public void opt_query(int type, char *s);
public char * propt LESSPARAMS ((int c)); public void opt_mousecap(int type, char *s);
public void scan_option LESSPARAMS ((char *s)); public void opt_wheel_lines(int type, char *s);
public void toggle_option LESSPARAMS ((struct loption *o, int lower, char *s, int how_toggle)); public void opt_linenum_width(int type, char *s);
public int opt_has_param LESSPARAMS ((struct loption *o)); public void opt_status_col_width(int type, char *s);
public char * opt_prompt LESSPARAMS ((struct loption *o)); public void opt_filesize(int type, char *s);
public char * opt_toggle_disallowed LESSPARAMS ((int c)); public void opt_intr(int type, char *s);
public int isoptpending LESSPARAMS ((VOID_PARAM)); public void opt_header(int type, char *s);
public void nopendopt LESSPARAMS ((VOID_PARAM)); public void opt_search_type(int type, char *s);
public int getnum LESSPARAMS ((char **sp, char *printopt, int *errp)); public void opt_ttyin_name(int type, char *s);
public long getfraction LESSPARAMS ((char **sp, char *printopt, int *errp)); public int chop_line(void);
public int get_quit_at_eof LESSPARAMS ((VOID_PARAM)); public int get_swindow(void);
public void init_option LESSPARAMS ((VOID_PARAM)); public char * propt(int c);
public struct loption * findopt LESSPARAMS ((int c)); public void scan_option(char *s);
public struct loption * findopt_name LESSPARAMS ((char **p_optname, char **p_oname, int *p_err)); public void toggle_option(struct loption *o, int lower, char *s, int how_toggle);
public int iread LESSPARAMS ((int fd, unsigned char *buf, unsigned int len)); public int opt_has_param(struct loption *o);
public void intread LESSPARAMS ((VOID_PARAM)); public char * opt_prompt(struct loption *o);
public time_type get_time LESSPARAMS ((VOID_PARAM)); public char * opt_toggle_disallowed(int c);
public char * errno_message LESSPARAMS ((char *filename)); public int isoptpending(void);
public int percentage LESSPARAMS ((POSITION num, POSITION den)); public void nopendopt(void);
public POSITION percent_pos LESSPARAMS ((POSITION pos, int percent, long fraction)); public int getnum(char **sp, char *printopt, int *errp);
public int os9_signal LESSPARAMS ((int type, RETSIGTYPE (*handler)())); public long getfraction(char **sp, char *printopt, int *errp);
public void sleep_ms LESSPARAMS ((int ms)); public int get_quit_at_eof(void);
public void put_line LESSPARAMS ((VOID_PARAM)); public void init_option(void);
public void flush LESSPARAMS ((VOID_PARAM)); public struct loption * findopt(int c);
public void set_output LESSPARAMS ((int fd)); public struct loption * findopt_name(char **p_optname, char **p_oname, int *p_err);
public int putchr LESSPARAMS ((int c)); public void init_poll(void);
public void clear_bot_if_needed LESSPARAMS ((VOID_PARAM)); public int supports_ctrl_x(void);
public void putstr LESSPARAMS ((constant char *s)); public int iread(int fd, unsigned char *buf, unsigned int len);
public int less_printf LESSPARAMS ((char *fmt, PARG *parg)); public void intread(void);
public void get_return LESSPARAMS ((VOID_PARAM)); public time_type get_time(void);
public void error LESSPARAMS ((char *fmt, PARG *parg)); public char * errno_message(char *filename);
public void ierror LESSPARAMS ((char *fmt, PARG *parg)); public char * signal_message(int sig);
public int query LESSPARAMS ((char *fmt, PARG *parg)); public uintmax muldiv(uintmax val, uintmax num, uintmax den);
public int compile_pattern LESSPARAMS ((char *pattern, int search_type, int show_error, PATTERN_TYPE *comp_pattern)); public int percentage(POSITION num, POSITION den);
public void uncompile_pattern LESSPARAMS ((PATTERN_TYPE *pattern)); public POSITION percent_pos(POSITION pos, int percent, long fraction);
public int valid_pattern LESSPARAMS ((char *pattern)); public int os9_signal(int type, RETSIGTYPE (*handler)());
public int is_null_pattern LESSPARAMS ((PATTERN_TYPE pattern)); public void sleep_ms(int ms);
public int match_pattern LESSPARAMS ((PATTERN_TYPE pattern, char *tpattern, char *line, int line_len, char **sp, char **ep, int notbol, int search_type)); public void put_line(void);
public char * pattern_lib_name LESSPARAMS ((VOID_PARAM)); public void flush(void);
public POSITION position LESSPARAMS ((int sindex)); public void set_output(int fd);
public void add_forw_pos LESSPARAMS ((POSITION pos)); public int putchr(int c);
public void add_back_pos LESSPARAMS ((POSITION pos)); public void clear_bot_if_needed(void);
public void pos_clear LESSPARAMS ((VOID_PARAM)); public void putstr(constant char *s);
public void pos_init LESSPARAMS ((VOID_PARAM)); public int less_printf(char *fmt, PARG *parg);
public int onscreen LESSPARAMS ((POSITION pos)); public void get_return(void);
public int empty_screen LESSPARAMS ((VOID_PARAM)); public void error(char *fmt, PARG *parg);
public int empty_lines LESSPARAMS ((int s, int e)); public void ierror(char *fmt, PARG *parg);
public void get_scrpos LESSPARAMS ((struct scrpos *scrpos, int where)); public void ixerror(char *fmt, PARG *parg);
public int sindex_from_sline LESSPARAMS ((int sline)); public int query(char *fmt, PARG *parg);
public void init_prompt LESSPARAMS ((VOID_PARAM)); public int compile_pattern(char *pattern, int search_type, int show_error, PATTERN_TYPE *comp_pattern);
public char * pr_expand LESSPARAMS ((constant char *proto)); public void uncompile_pattern(PATTERN_TYPE *pattern);
public char * eq_message LESSPARAMS ((VOID_PARAM)); public int valid_pattern(char *pattern);
public char * pr_string LESSPARAMS ((VOID_PARAM)); public int is_null_pattern(PATTERN_TYPE pattern);
public char * wait_message LESSPARAMS ((VOID_PARAM)); public int match_pattern(PATTERN_TYPE pattern, char *tpattern, char *line, int line_len, char **sp, char **ep, int nsp, int notbol, int search_type);
public void init_search LESSPARAMS ((VOID_PARAM)); public char * pattern_lib_name(void);
public void repaint_hilite LESSPARAMS ((int on)); public POSITION position(int sindex);
public void clear_attn LESSPARAMS ((VOID_PARAM)); public void add_forw_pos(POSITION pos);
public void undo_search LESSPARAMS ((int clear)); public void add_back_pos(POSITION pos);
public void clr_hlist LESSPARAMS ((struct hilite_tree *anchor)); public void pos_clear(void);
public void clr_hilite LESSPARAMS ((VOID_PARAM)); public void pos_init(void);
public void clr_filter LESSPARAMS ((VOID_PARAM)); public int onscreen(POSITION pos);
public int is_filtered LESSPARAMS ((POSITION pos)); public int empty_screen(void);
public POSITION next_unfiltered LESSPARAMS ((POSITION pos)); public int empty_lines(int s, int e);
public POSITION prev_unfiltered LESSPARAMS ((POSITION pos)); public void get_scrpos(struct scrpos *scrpos, int where);
public int is_hilited_attr LESSPARAMS ((POSITION pos, POSITION epos, int nohide, int *p_matches)); public int sindex_from_sline(int sline);
public void chg_hilite LESSPARAMS ((VOID_PARAM)); public void init_prompt(void);
public void chg_caseless LESSPARAMS ((VOID_PARAM)); public char * pr_expand(constant char *proto);
public int search LESSPARAMS ((int search_type, char *pattern, int n)); public char * eq_message(void);
public void prep_hilite LESSPARAMS ((POSITION spos, POSITION epos, int maxlines)); public char * pr_string(void);
public void set_filter_pattern LESSPARAMS ((char *pattern, int search_type)); public char * wait_message(void);
public int is_filtering LESSPARAMS ((VOID_PARAM)); public void init_search(void);
public RETSIGTYPE winch LESSPARAMS ((int type)); public void repaint_hilite(int on);
public void init_signals LESSPARAMS ((int on)); public void clear_attn(void);
public void psignals LESSPARAMS ((VOID_PARAM)); public void undo_search(int clear);
public void cleantags LESSPARAMS ((VOID_PARAM)); public void clr_hlist(struct hilite_tree *anchor);
public int gettagtype LESSPARAMS ((VOID_PARAM)); public void clr_hilite(void);
public void findtag LESSPARAMS ((char *tag)); public void clr_filter(void);
public POSITION tagsearch LESSPARAMS ((VOID_PARAM)); public int is_filtered(POSITION pos);
public char * nexttag LESSPARAMS ((int n)); public POSITION next_unfiltered(POSITION pos);
public char * prevtag LESSPARAMS ((int n)); public POSITION prev_unfiltered(POSITION pos);
public int ntags LESSPARAMS ((VOID_PARAM)); public int is_hilited_attr(POSITION pos, POSITION epos, int nohide, int *p_matches);
public int curr_tag LESSPARAMS ((VOID_PARAM)); public void chg_hilite(void);
public int edit_tagfile LESSPARAMS ((VOID_PARAM)); public void chg_caseless(void);
public int open_tty LESSPARAMS ((VOID_PARAM)); public int search(int search_type, char *pattern, int n);
public void open_getchr LESSPARAMS ((VOID_PARAM)); public void prep_hilite(POSITION spos, POSITION epos, int maxlines);
public void close_getchr LESSPARAMS ((VOID_PARAM)); public void set_filter_pattern(char *pattern, int search_type);
public int default_wheel_lines LESSPARAMS ((VOID_PARAM)); public int is_filtering(void);
public void rstat LESSPARAMS ((char st)); public RETSIGTYPE winch(int type);
public int getchr LESSPARAMS ((VOID_PARAM)); public void init_signals(int on);
public void xbuf_init LESSPARAMS ((struct xbuffer *xbuf)); public void psignals(void);
public void xbuf_deinit LESSPARAMS ((struct xbuffer *xbuf)); public void cleantags(void);
public void xbuf_reset LESSPARAMS ((struct xbuffer *xbuf)); public int gettagtype(void);
public void xbuf_add LESSPARAMS ((struct xbuffer *xbuf, int ch)); public void findtag(char *tag);
public int xbuf_pop LESSPARAMS ((struct xbuffer *buf)); public POSITION tagsearch(void);
public void xbuf_set LESSPARAMS ((struct xbuffer *dst, struct xbuffer *src)); public char * nexttag(int n);
public char * prevtag(int n);
public int ntags(void);
public int curr_tag(void);
public int edit_tagfile(void);
public int open_tty(void);
public void open_getchr(void);
public void close_getchr(void);
public int pclose(FILE *f);
public int default_wheel_lines(void);
public int getchr(void);
public void xbuf_init(struct xbuffer *xbuf);
public void xbuf_deinit(struct xbuffer *xbuf);
public void xbuf_reset(struct xbuffer *xbuf);
public void xbuf_add_byte(struct xbuffer *xbuf, unsigned char b);
public void xbuf_add_data(struct xbuffer *xbuf, unsigned char *data, int len);
public int xbuf_pop(struct xbuffer *buf);
public void xbuf_set(struct xbuffer *dst, struct xbuffer *src);
public char * xbuf_char_data(struct xbuffer *xbuf);
public int help_ckd_add(void *r, uintmax a, uintmax b, int rsize, int rsigned);
public int help_ckd_mul(void *r, uintmax a, uintmax b, int rsize, int rsigned);

View File

@ -1,4 +1,4 @@
/* This file was generated by mkhelp.pl from less.hlp at 19:26 on 2022/7/22 */ /* This file was generated by mkhelp.pl from less.hlp at 17:26 on 2023/4/6 */
#include "less.h" #include "less.h"
constant char helpdata[] = { constant char helpdata[] = {
'\n', '\n',
@ -54,6 +54,7 @@ constant char helpdata[] = {
' ',' ',' ',' ',' ',' ',' ',' ','^','F',' ','o','r',' ','@',' ',' ','S','t','a','r','t',' ','s','e','a','r','c','h',' ','a','t',' ','F','I','R','S','T',' ','f','i','l','e',' ','(','f','o','r',' ','/',')',' ','o','r',' ','l','a','s','t',' ','f','i','l','e',' ','(','f','o','r',' ','?',')','.','\n', ' ',' ',' ',' ',' ',' ',' ',' ','^','F',' ','o','r',' ','@',' ',' ','S','t','a','r','t',' ','s','e','a','r','c','h',' ','a','t',' ','F','I','R','S','T',' ','f','i','l','e',' ','(','f','o','r',' ','/',')',' ','o','r',' ','l','a','s','t',' ','f','i','l','e',' ','(','f','o','r',' ','?',')','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','K',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','m','a','t','c','h','e','s',',',' ','b','u','t',' ','d','o','n','\'','t',' ','m','o','v','e',' ','(','K','E','E','P',' ','p','o','s','i','t','i','o','n',')','.','\n', ' ',' ',' ',' ',' ',' ',' ',' ','^','K',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','m','a','t','c','h','e','s',',',' ','b','u','t',' ','d','o','n','\'','t',' ','m','o','v','e',' ','(','K','E','E','P',' ','p','o','s','i','t','i','o','n',')','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','R',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','u','s','e',' ','R','E','G','U','L','A','R',' ','E','X','P','R','E','S','S','I','O','N','S','.','\n', ' ',' ',' ',' ',' ',' ',' ',' ','^','R',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','u','s','e',' ','R','E','G','U','L','A','R',' ','E','X','P','R','E','S','S','I','O','N','S','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','S',' ','_','\b','n',' ',' ',' ',' ',' ','S','e','a','r','c','h',' ','f','o','r',' ','m','a','t','c','h',' ','i','n',' ','_','\b','n','-','t','h',' ','p','a','r','e','n','t','h','e','s','i','z','e','d',' ','s','u','b','p','a','t','t','e','r','n','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','W',' ',' ',' ',' ',' ',' ',' ','W','R','A','P',' ','s','e','a','r','c','h',' ','i','f',' ','n','o',' ','m','a','t','c','h',' ','f','o','u','n','d','.','\n', ' ',' ',' ',' ',' ',' ',' ',' ','^','W',' ',' ',' ',' ',' ',' ',' ','W','R','A','P',' ','s','e','a','r','c','h',' ','i','f',' ','n','o',' ','m','a','t','c','h',' ','f','o','u','n','d','.','\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n', ' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n', '\n',
@ -107,6 +108,7 @@ constant char helpdata[] = {
' ',' ','+','_','\b','c','_','\b','m','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','e','c','u','t','e',' ','t','h','e',' ','l','e','s','s',' ','c','m','d',' ','e','a','c','h',' ','t','i','m','e',' ','a',' ','n','e','w',' ','f','i','l','e',' ','i','s',' ','e','x','a','m','i','n','e','d','.','\n', ' ',' ','+','_','\b','c','_','\b','m','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','e','c','u','t','e',' ','t','h','e',' ','l','e','s','s',' ','c','m','d',' ','e','a','c','h',' ','t','i','m','e',' ','a',' ','n','e','w',' ','f','i','l','e',' ','i','s',' ','e','x','a','m','i','n','e','d','.','\n',
'\n', '\n',
' ',' ','!','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','e','c','u','t','e',' ','t','h','e',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d',' ','w','i','t','h',' ','$','S','H','E','L','L','.','\n', ' ',' ','!','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','e','c','u','t','e',' ','t','h','e',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d',' ','w','i','t','h',' ','$','S','H','E','L','L','.','\n',
' ',' ','#','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','e','c','u','t','e',' ','t','h','e',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d',',',' ','e','x','p','a','n','d','e','d',' ','l','i','k','e',' ','a',' ','p','r','o','m','p','t','.','\n',
' ',' ','|','X','\b','X','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','i','p','e',' ','f','i','l','e',' ','b','e','t','w','e','e','n',' ','c','u','r','r','e','n','t',' ','p','o','s',' ','&',' ','m','a','r','k',' ','X','\b','X',' ','t','o',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d','.','\n', ' ',' ','|','X','\b','X','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','i','p','e',' ','f','i','l','e',' ','b','e','t','w','e','e','n',' ','c','u','r','r','e','n','t',' ','p','o','s',' ','&',' ','m','a','r','k',' ','X','\b','X',' ','t','o',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d','.','\n',
' ',' ','s',' ','_','\b','f','_','\b','i','_','\b','l','_','\b','e',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','a','v','e',' ','i','n','p','u','t',' ','t','o',' ','a',' ','f','i','l','e','.','\n', ' ',' ','s',' ','_','\b','f','_','\b','i','_','\b','l','_','\b','e',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','a','v','e',' ','i','n','p','u','t',' ','t','o',' ','a',' ','f','i','l','e','.','\n',
' ',' ','v',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','d','i','t',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','f','i','l','e',' ','w','i','t','h',' ','$','V','I','S','U','A','L',' ','o','r',' ','$','E','D','I','T','O','R','.','\n', ' ',' ','v',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','d','i','t',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','f','i','l','e',' ','w','i','t','h',' ','$','V','I','S','U','A','L',' ','o','r',' ','$','E','D','I','T','O','R','.','\n',
@ -189,7 +191,7 @@ constant char helpdata[] = {
' ',' ','-','T',' ','[','_','\b','t','_','\b','a','_','\b','g','_','\b','s','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ','-','-','t','a','g','-','f','i','l','e','=','[','_','\b','t','_','\b','a','_','\b','g','_','\b','s','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n', ' ',' ','-','T',' ','[','_','\b','t','_','\b','a','_','\b','g','_','\b','s','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ','-','-','t','a','g','-','f','i','l','e','=','[','_','\b','t','_','\b','a','_','\b','g','_','\b','s','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','a','n',' ','a','l','t','e','r','n','a','t','e',' ','t','a','g','s',' ','f','i','l','e','.','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','a','n',' ','a','l','t','e','r','n','a','t','e',' ','t','a','g','s',' ','f','i','l','e','.','\n',
' ',' ','-','u',' ',' ','-','U',' ',' ','.','.','.','.',' ',' ','-','-','u','n','d','e','r','l','i','n','e','-','s','p','e','c','i','a','l',' ',' ','-','-','U','N','D','E','R','L','I','N','E','-','S','P','E','C','I','A','L','\n', ' ',' ','-','u',' ',' ','-','U',' ',' ','.','.','.','.',' ',' ','-','-','u','n','d','e','r','l','i','n','e','-','s','p','e','c','i','a','l',' ',' ','-','-','U','N','D','E','R','L','I','N','E','-','S','P','E','C','I','A','L','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','h','a','n','g','e',' ','h','a','n','d','l','i','n','g',' ','o','f',' ','b','a','c','k','s','p','a','c','e','s','.','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','h','a','n','g','e',' ','h','a','n','d','l','i','n','g',' ','o','f',' ','b','a','c','k','s','p','a','c','e','s',',',' ','t','a','b','s',' ','a','n','d',' ','c','a','r','r','i','a','g','e',' ','r','e','t','u','r','n','s','.','\n',
' ',' ','-','V',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','v','e','r','s','i','o','n','\n', ' ',' ','-','V',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','v','e','r','s','i','o','n','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','t','h','e',' ','v','e','r','s','i','o','n',' ','n','u','m','b','e','r',' ','o','f',' ','"','l','e','s','s','"','.','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','t','h','e',' ','v','e','r','s','i','o','n',' ','n','u','m','b','e','r',' ','o','f',' ','"','l','e','s','s','"','.','\n',
' ',' ','-','w',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','h','i','l','i','t','e','-','u','n','r','e','a','d','\n', ' ',' ','-','w',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','h','i','l','i','t','e','-','u','n','r','e','a','d','\n',
@ -210,6 +212,8 @@ constant char helpdata[] = {
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','d','i','s','p','l','a','y',' ','t','i','l','d','e','s',' ','a','f','t','e','r',' ','e','n','d',' ','o','f',' ','f','i','l','e','.','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','d','i','s','p','l','a','y',' ','t','i','l','d','e','s',' ','a','f','t','e','r',' ','e','n','d',' ','o','f',' ','f','i','l','e','.','\n',
' ',' ','-','#',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','s','h','i','f','t','=','[','_','\b','N',']','\n', ' ',' ','-','#',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','s','h','i','f','t','=','[','_','\b','N',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','h','o','r','i','z','o','n','t','a','l',' ','s','c','r','o','l','l',' ','a','m','o','u','n','t',' ','(','0',' ','=',' ','o','n','e',' ','h','a','l','f',' ','s','c','r','e','e','n',' ','w','i','d','t','h',')','.','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','h','o','r','i','z','o','n','t','a','l',' ','s','c','r','o','l','l',' ','a','m','o','u','n','t',' ','(','0',' ','=',' ','o','n','e',' ','h','a','l','f',' ','s','c','r','e','e','n',' ','w','i','d','t','h',')','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','e','x','i','t','-','f','o','l','l','o','w','-','o','n','-','c','l','o','s','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','i','t',' ','F',' ','c','o','m','m','a','n','d',' ','o','n',' ','a',' ','p','i','p','e',' ','w','h','e','n',' ','w','r','i','t','e','r',' ','c','l','o','s','e','s',' ','p','i','p','e','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','f','i','l','e','-','s','i','z','e','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','f','i','l','e','-','s','i','z','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','f','o','l','l','o','w','-','n','a','m','e','\n',
@ -218,8 +222,12 @@ constant char helpdata[] = {
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','i','n','t','r','=','_','\b','C','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','h','e',' ','w','i','d','t','h',' ','o','f',' ','t','h','e',' ','-','N',' ','l','i','n','e',' ','n','u','m','b','e','r',' ','f','i','e','l','d',' ','t','o',' ','N',' ','c','h','a','r','a','c','t','e','r','s','.','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','_','\b','C',' ','i','n','s','t','e','a','d',' ','o','f',' ','^','X',' ','t','o',' ','i','n','t','e','r','r','u','p','t',' ','a',' ','r','e','a','d','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','l','i','n','e','-','n','u','m','-','w','i','d','t','h','=','_','\b','N','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','h','e',' ','w','i','d','t','h',' ','o','f',' ','t','h','e',' ','-','N',' ','l','i','n','e',' ','n','u','m','b','e','r',' ','f','i','e','l','d',' ','t','o',' ','_','\b','N',' ','c','h','a','r','a','c','t','e','r','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','m','o','d','e','l','i','n','e','s','=','_','\b','N','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','a','d',' ','_','\b','N',' ','l','i','n','e','s',' ','f','r','o','m',' ','t','h','e',' ','i','n','p','u','t',' ','f','i','l','e',' ','a','n','d',' ','l','o','o','k',' ','f','o','r',' ','v','i','m',' ','m','o','d','e','l','i','n','e','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','m','o','u','s','e','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','m','o','u','s','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','n','a','b','l','e',' ','m','o','u','s','e',' ','i','n','p','u','t','.','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','n','a','b','l','e',' ','m','o','u','s','e',' ','i','n','p','u','t','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','k','e','y','p','a','d','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','k','e','y','p','a','d','\n',
@ -228,24 +236,44 @@ constant char helpdata[] = {
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','s','e','a','r','c','h','-','h','e','a','d','e','r','s','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','s','e','a','r','c','h',' ','i','n',' ','h','e','a','d','e','r',' ','l','i','n','e','s',' ','o','r',' ','c','o','l','u','m','n','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','v','b','e','l','l','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','a','b','l','e',' ','t','h','e',' ','t','e','r','m','i','n','a','l','\'','s',' ','v','i','s','u','a','l',' ','b','e','l','l','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','r','e','d','r','a','w','-','o','n','-','q','u','i','t','\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','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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','r','s','c','r','o','l','l','=','_','\b','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','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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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','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','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','h','o','w','-','p','r','e','p','r','o','c','-','e','r','r','o','r','s','\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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','a',' ','m','e','s','s','a','g','e',' ','i','f',' ','p','r','e','p','r','o','c','e','s','s','o','r',' ','e','x','i','t','s',' ','w','i','t','h',' ','a','n',' ','e','r','r','o','r',' ','s','t','a','t','u','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','p','r','o','c','-','b','a','c','k','s','p','a','c','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','r','o','c','e','s','s',' ','b','a','c','k','s','p','a','c','e','s',' ','f','o','r',' ','b','o','l','d','/','u','n','d','e','r','l','i','n','e','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','S','P','E','C','I','A','L','-','B','A','C','K','S','P','A','C','E','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','r','e','a','t',' ','b','a','c','k','s','p','a','c','e','s',' ','a','s',' ','c','o','n','t','r','o','l',' ','c','h','a','r','a','c','t','e','r','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','p','r','o','c','-','r','e','t','u','r','n','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','c','a','r','r','i','a','g','e',' ','r','e','t','u','r','n','s',' ','b','e','f','o','r','e',' ','n','e','w','l','i','n','e','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','S','P','E','C','I','A','L','-','R','E','T','U','R','N','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','r','e','a','t',' ','c','a','r','r','i','a','g','e',' ','r','e','t','u','r','n','s',' ','a','s',' ','c','o','n','t','r','o','l',' ','c','h','a','r','a','c','t','e','r','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','p','r','o','c','-','t','a','b','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','p','a','n','d',' ','t','a','b','s',' ','t','o',' ','s','p','a','c','e','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','S','P','E','C','I','A','L','-','T','A','B','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','r','e','a','t',' ','t','a','b','s',' ','a','s',' ','c','o','n','t','r','o','l',' ','c','h','a','r','a','c','t','e','r','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','t','a','t','u','s','-','c','o','l','-','w','i','d','t','h','=','_','\b','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',' ','_','\b','N',' ','c','h','a','r','a','c','t','e','r','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','s','t','a','t','u','s','-','l','i','n','e','\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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','u','s','e','-','c','o','l','o','r','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','n','a','b','l','e','s',' ','c','o','l','o','r','e','d',' ','t','e','x','t','.','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','n','a','b','l','e','s',' ','c','o','l','o','r','e','d',' ','t','e','x','t','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','w','h','e','e','l','-','l','i','n','e','s','=','N','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','w','h','e','e','l','-','l','i','n','e','s','=','_','\b','N','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','a','c','h',' ','c','l','i','c','k',' ','o','f',' ','t','h','e',' ','m','o','u','s','e',' ','w','h','e','e','l',' ','m','o','v','e','s',' ','N',' ','l','i','n','e','s','.','\n', ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','a','c','h',' ','c','l','i','c','k',' ','o','f',' ','t','h','e',' ','m','o','u','s','e',' ','w','h','e','e','l',' ','m','o','v','e','s',' ','_','\b','N',' ','l','i','n','e','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','w','o','r','d','w','r','a','p','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','W','r','a','p',' ','l','i','n','e','s',' ','a','t',' ','s','p','a','c','e','s','.','\n',
'\n', '\n',
'\n', '\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n', ' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -51,10 +51,7 @@ static struct ifile anchor = { &anchor, &anchor, NULL, NULL, NULL, 0, 0, '\0',
{ NULL_POSITION, 0 } }; { NULL_POSITION, 0 } };
static int ifiles = 0; static int ifiles = 0;
static void static void incr_index(struct ifile *p, int incr)
incr_index(p, incr)
struct ifile *p;
int incr;
{ {
for (; p != &anchor; p = p->h_next) for (; p != &anchor; p = p->h_next)
p->h_index += incr; p->h_index += incr;
@ -63,10 +60,7 @@ incr_index(p, incr)
/* /*
* Link an ifile into the ifile list. * Link an ifile into the ifile list.
*/ */
static void static void link_ifile(struct ifile *p, struct ifile *prev)
link_ifile(p, prev)
struct ifile *p;
struct ifile *prev;
{ {
/* /*
* Link into list. * Link into list.
@ -89,9 +83,7 @@ link_ifile(p, prev)
/* /*
* Unlink an ifile from the ifile list. * Unlink an ifile from the ifile list.
*/ */
static void static void unlink_ifile(struct ifile *p)
unlink_ifile(p)
struct ifile *p;
{ {
p->h_next->h_prev = p->h_prev; p->h_next->h_prev = p->h_prev;
p->h_prev->h_next = p->h_next; p->h_prev->h_next = p->h_next;
@ -105,10 +97,7 @@ unlink_ifile(p)
* (or at the beginning of the list if "prev" is NULL). * (or at the beginning of the list if "prev" is NULL).
* Return a pointer to the new ifile structure. * Return a pointer to the new ifile structure.
*/ */
static struct ifile * static struct ifile * new_ifile(char *filename, struct ifile *prev)
new_ifile(filename, prev)
char *filename;
struct ifile *prev;
{ {
struct ifile *p; struct ifile *p;
@ -137,9 +126,7 @@ new_ifile(filename, prev)
/* /*
* Delete an existing ifile structure. * Delete an existing ifile structure.
*/ */
public void public void del_ifile(IFILE h)
del_ifile(h)
IFILE h;
{ {
struct ifile *p; struct ifile *p;
@ -162,9 +149,7 @@ del_ifile(h)
/* /*
* Get the ifile after a given one in the list. * Get the ifile after a given one in the list.
*/ */
public IFILE public IFILE next_ifile(IFILE h)
next_ifile(h)
IFILE h;
{ {
struct ifile *p; struct ifile *p;
@ -177,9 +162,7 @@ next_ifile(h)
/* /*
* Get the ifile before a given one in the list. * Get the ifile before a given one in the list.
*/ */
public IFILE public IFILE prev_ifile(IFILE h)
prev_ifile(h)
IFILE h;
{ {
struct ifile *p; struct ifile *p;
@ -192,9 +175,7 @@ prev_ifile(h)
/* /*
* Return a different ifile from the given one. * Return a different ifile from the given one.
*/ */
public IFILE public IFILE getoff_ifile(IFILE ifile)
getoff_ifile(ifile)
IFILE ifile;
{ {
IFILE newifile; IFILE newifile;
@ -208,8 +189,7 @@ getoff_ifile(ifile)
/* /*
* Return the number of ifiles. * Return the number of ifiles.
*/ */
public int public int nifile(void)
nifile(VOID_PARAM)
{ {
return (ifiles); return (ifiles);
} }
@ -217,9 +197,7 @@ nifile(VOID_PARAM)
/* /*
* Find an ifile structure, given a filename. * Find an ifile structure, given a filename.
*/ */
static struct ifile * static struct ifile * find_ifile(char *filename)
find_ifile(filename)
char *filename;
{ {
struct ifile *p; struct ifile *p;
char *rfilename = lrealpath(filename); char *rfilename = lrealpath(filename);
@ -251,10 +229,7 @@ find_ifile(filename)
* If the filename has not been seen before, * If the filename has not been seen before,
* insert the new ifile after "prev" in the list. * insert the new ifile after "prev" in the list.
*/ */
public IFILE public IFILE get_ifile(char *filename, IFILE prev)
get_ifile(filename, prev)
char *filename;
IFILE prev;
{ {
struct ifile *p; struct ifile *p;
@ -266,9 +241,7 @@ get_ifile(filename, prev)
/* /*
* Get the display filename associated with a ifile. * Get the display filename associated with a ifile.
*/ */
public char * public char * get_filename(IFILE ifile)
get_filename(ifile)
IFILE ifile;
{ {
if (ifile == NULL) if (ifile == NULL)
return (NULL); return (NULL);
@ -278,9 +251,7 @@ get_filename(ifile)
/* /*
* Get the canonical filename associated with a ifile. * Get the canonical filename associated with a ifile.
*/ */
public char * public char * get_real_filename(IFILE ifile)
get_real_filename(ifile)
IFILE ifile;
{ {
if (ifile == NULL) if (ifile == NULL)
return (NULL); return (NULL);
@ -290,9 +261,7 @@ get_real_filename(ifile)
/* /*
* Get the index of the file associated with a ifile. * Get the index of the file associated with a ifile.
*/ */
public int public int get_index(IFILE ifile)
get_index(ifile)
IFILE ifile;
{ {
return (int_ifile(ifile)->h_index); return (int_ifile(ifile)->h_index);
} }
@ -300,10 +269,7 @@ get_index(ifile)
/* /*
* Save the file position to be associated with a given file. * Save the file position to be associated with a given file.
*/ */
public void public void store_pos(IFILE ifile, struct scrpos *scrpos)
store_pos(ifile, scrpos)
IFILE ifile;
struct scrpos *scrpos;
{ {
int_ifile(ifile)->h_scrpos = *scrpos; int_ifile(ifile)->h_scrpos = *scrpos;
} }
@ -312,10 +278,7 @@ store_pos(ifile, scrpos)
* Recall the file position associated with a file. * Recall the file position associated with a file.
* If no position has been associated with the file, return NULL_POSITION. * If no position has been associated with the file, return NULL_POSITION.
*/ */
public void public void get_pos(IFILE ifile, struct scrpos *scrpos)
get_pos(ifile, scrpos)
IFILE ifile;
struct scrpos *scrpos;
{ {
*scrpos = int_ifile(ifile)->h_scrpos; *scrpos = int_ifile(ifile)->h_scrpos;
} }
@ -323,9 +286,7 @@ get_pos(ifile, scrpos)
/* /*
* Mark the ifile as "opened". * Mark the ifile as "opened".
*/ */
public void public void set_open(IFILE ifile)
set_open(ifile)
IFILE ifile;
{ {
int_ifile(ifile)->h_opened = 1; int_ifile(ifile)->h_opened = 1;
} }
@ -333,62 +294,42 @@ set_open(ifile)
/* /*
* Return whether the ifile has been opened previously. * Return whether the ifile has been opened previously.
*/ */
public int public int opened(IFILE ifile)
opened(ifile)
IFILE ifile;
{ {
return (int_ifile(ifile)->h_opened); return (int_ifile(ifile)->h_opened);
} }
public void public void hold_ifile(IFILE ifile, int incr)
hold_ifile(ifile, incr)
IFILE ifile;
int incr;
{ {
int_ifile(ifile)->h_hold += incr; int_ifile(ifile)->h_hold += incr;
} }
public int public int held_ifile(IFILE ifile)
held_ifile(ifile)
IFILE ifile;
{ {
return (int_ifile(ifile)->h_hold); return (int_ifile(ifile)->h_hold);
} }
public void * public void * get_filestate(IFILE ifile)
get_filestate(ifile)
IFILE ifile;
{ {
return (int_ifile(ifile)->h_filestate); return (int_ifile(ifile)->h_filestate);
} }
public void public void set_filestate(IFILE ifile, void *filestate)
set_filestate(ifile, filestate)
IFILE ifile;
void *filestate;
{ {
int_ifile(ifile)->h_filestate = filestate; int_ifile(ifile)->h_filestate = filestate;
} }
public void public void set_altpipe(IFILE ifile, void *p)
set_altpipe(ifile, p)
IFILE ifile;
void *p;
{ {
int_ifile(ifile)->h_altpipe = p; int_ifile(ifile)->h_altpipe = p;
} }
public void * public void *get_altpipe(IFILE ifile)
get_altpipe(ifile)
IFILE ifile;
{ {
return (int_ifile(ifile)->h_altpipe); return (int_ifile(ifile)->h_altpipe);
} }
public void public void set_altfilename(IFILE ifile, char *altfilename)
set_altfilename(ifile, altfilename)
IFILE ifile;
char *altfilename;
{ {
struct ifile *p = int_ifile(ifile); struct ifile *p = int_ifile(ifile);
if (p->h_altfilename != NULL && p->h_altfilename != altfilename) if (p->h_altfilename != NULL && p->h_altfilename != altfilename)
@ -396,16 +337,13 @@ set_altfilename(ifile, altfilename)
p->h_altfilename = altfilename; p->h_altfilename = altfilename;
} }
public char * public char * get_altfilename(IFILE ifile)
get_altfilename(ifile)
IFILE ifile;
{ {
return (int_ifile(ifile)->h_altfilename); return (int_ifile(ifile)->h_altfilename);
} }
#if 0 #if 0
public void public void if_dump(void)
if_dump(VOID_PARAM)
{ {
struct ifile *p; struct ifile *p;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -25,6 +25,7 @@ extern int quit_if_one_screen;
extern int sigs; extern int sigs;
extern int ignore_eoi; extern int ignore_eoi;
extern int status_col; extern int status_col;
extern int wordwrap;
extern POSITION start_attnpos; extern POSITION start_attnpos;
extern POSITION end_attnpos; extern POSITION end_attnpos;
#if HILITE_SEARCH #if HILITE_SEARCH
@ -33,6 +34,45 @@ extern int size_linebuf;
extern int show_attn; extern int show_attn;
#endif #endif
/*
* Set the status column.
* base Position of first char in line.
* disp First visible char.
* Different than base_pos if line is shifted.
* edisp Last visible char.
* eol End of line. Normally the newline.
* Different than edisp if line is chopped.
*/
static void init_status_col(POSITION base_pos, POSITION disp_pos, POSITION edisp_pos, POSITION eol_pos)
{
int hl_before = (chop_line() && disp_pos != NULL_POSITION) ?
is_hilited_attr(base_pos, disp_pos, TRUE, NULL) : 0;
int hl_after = (chop_line()) ?
is_hilited_attr(edisp_pos, eol_pos, TRUE, NULL) : 0;
int attr;
char ch;
if (hl_before && hl_after)
{
attr = hl_after;
ch = '=';
} else if (hl_before)
{
attr = hl_before;
ch = '<';
} else if (hl_after)
{
attr = hl_after;
ch = '>';
} else
{
attr = is_hilited_attr(base_pos, eol_pos, TRUE, NULL);
ch = '*';
}
if (attr)
set_status_col(ch, attr);
}
/* /*
* Get the next line. * Get the next line.
* A "current" position is passed and a "new" position is returned. * A "current" position is passed and a "new" position is returned.
@ -40,20 +80,18 @@ extern int show_attn;
* a line. The new position is the position of the first character * a line. The new position is the position of the first character
* of the NEXT line. The line obtained is the line starting at curr_pos. * of the NEXT line. The line obtained is the line starting at curr_pos.
*/ */
public POSITION public POSITION forw_line_seg(POSITION curr_pos, int skipeol, int rscroll, int nochop)
forw_line_seg(curr_pos, skipeol, rscroll, nochop)
POSITION curr_pos;
int skipeol;
int rscroll;
int nochop;
{ {
POSITION base_pos; POSITION base_pos;
POSITION new_pos; POSITION new_pos;
POSITION edisp_pos;
int c; int c;
int blankline; int blankline;
int endline; int endline;
int chopped; int chopped;
int backchars; int backchars;
POSITION wrap_pos;
int skipped_leading;
get_forw_line: get_forw_line:
if (curr_pos == NULL_POSITION) if (curr_pos == NULL_POSITION)
@ -124,6 +162,15 @@ forw_line_seg(curr_pos, skipeol, rscroll, nochop)
if (backchars > 0) if (backchars > 0)
{ {
pshift_all(); pshift_all();
if (wordwrap && (c == ' ' || c == '\t'))
{
do
{
new_pos++;
c = ch_forw_get();
} while (c == ' ' || c == '\t');
backchars = 1;
}
new_pos -= backchars; new_pos -= backchars;
while (--backchars >= 0) while (--backchars >= 0)
(void) ch_back_get(); (void) ch_back_get();
@ -142,6 +189,8 @@ forw_line_seg(curr_pos, skipeol, rscroll, nochop)
return (NULL_POSITION); return (NULL_POSITION);
} }
blankline = (c == '\n' || c == '\r'); blankline = (c == '\n' || c == '\r');
wrap_pos = NULL_POSITION;
skipped_leading = FALSE;
/* /*
* Read each character in the line and append to the line buffer. * Read each character in the line and append to the line buffer.
@ -167,6 +216,7 @@ forw_line_seg(curr_pos, skipeol, rscroll, nochop)
endline = FALSE; endline = FALSE;
} else } else
endline = TRUE; endline = TRUE;
edisp_pos = new_pos;
break; break;
} }
if (c != '\r') if (c != '\r')
@ -186,6 +236,7 @@ forw_line_seg(curr_pos, skipeol, rscroll, nochop)
if (skipeol) if (skipeol)
{ {
/* Read to end of line. */ /* Read to end of line. */
edisp_pos = ch_tell();
do do
{ {
if (ABORT_SIGS()) if (ABORT_SIGS())
@ -201,11 +252,50 @@ forw_line_seg(curr_pos, skipeol, rscroll, nochop)
chopped = TRUE; chopped = TRUE;
} else } else
{ {
new_pos = ch_tell() - backchars; if (!wordwrap)
new_pos = ch_tell() - backchars;
else
{
/*
* We're word-wrapping, so go back to the last space.
* However, if it's the space itself that couldn't fit,
* simply ignore it and any subsequent spaces.
*/
if (c == ' ' || c == '\t')
{
do
{
new_pos = ch_tell();
c = ch_forw_get();
} while (c == ' ' || c == '\t');
if (c == '\r')
c = ch_forw_get();
if (c == '\n')
new_pos = ch_tell();
} else if (wrap_pos == NULL_POSITION)
new_pos = ch_tell() - backchars;
else
{
new_pos = wrap_pos;
loadc();
}
}
endline = FALSE; endline = FALSE;
} }
break; break;
} }
if (wordwrap)
{
if (c == ' ' || c == '\t')
{
if (skipped_leading)
{
wrap_pos = ch_tell();
savec();
}
} else
skipped_leading = TRUE;
}
c = ch_forw_get(); c = ch_forw_get();
} }
@ -228,13 +318,8 @@ forw_line_seg(curr_pos, skipeol, rscroll, nochop)
curr_pos = new_pos; curr_pos = new_pos;
goto get_forw_line; goto get_forw_line;
} }
if (status_col) if (status_col)
{ init_status_col(base_pos, line_position(), edisp_pos, new_pos);
int attr = is_hilited_attr(base_pos, ch_tell()-1, 1, NULL);
if (attr)
set_status_col('*', attr);
}
#endif #endif
if (squeeze && blankline) if (squeeze && blankline)
@ -258,9 +343,7 @@ forw_line_seg(curr_pos, skipeol, rscroll, nochop)
return (new_pos); return (new_pos);
} }
public POSITION public POSITION forw_line(POSITION curr_pos)
forw_line(curr_pos)
POSITION curr_pos;
{ {
return forw_line_seg(curr_pos, (chop_line() || hshift > 0), TRUE, FALSE); return forw_line_seg(curr_pos, (chop_line() || hshift > 0), TRUE, FALSE);
@ -273,15 +356,18 @@ forw_line(curr_pos)
* a line. The new position is the position of the first character * a line. The new position is the position of the first character
* of the PREVIOUS line. The line obtained is the one starting at new_pos. * of the PREVIOUS line. The line obtained is the one starting at new_pos.
*/ */
public POSITION public POSITION back_line(POSITION curr_pos)
back_line(curr_pos)
POSITION curr_pos;
{ {
POSITION new_pos, begin_new_pos, base_pos; POSITION base_pos;
POSITION new_pos;
POSITION edisp_pos;
POSITION begin_new_pos;
int c; int c;
int endline; int endline;
int chopped; int chopped;
int backchars; int backchars;
POSITION wrap_pos;
int skipped_leading;
get_back_line: get_back_line:
if (curr_pos == NULL_POSITION || curr_pos <= ch_zero()) if (curr_pos == NULL_POSITION || curr_pos <= ch_zero())
@ -383,11 +469,13 @@ back_line(curr_pos)
prewind(); prewind();
plinestart(new_pos); plinestart(new_pos);
loop: loop:
wrap_pos = NULL_POSITION;
skipped_leading = FALSE;
begin_new_pos = new_pos; begin_new_pos = new_pos;
(void) ch_seek(new_pos); (void) ch_seek(new_pos);
chopped = FALSE; chopped = FALSE;
do for (;;)
{ {
c = ch_forw_get(); c = ch_forw_get();
if (c == EOI || ABORT_SIGS()) if (c == EOI || ABORT_SIGS())
@ -405,6 +493,7 @@ back_line(curr_pos)
goto shift; goto shift;
} }
endline = TRUE; endline = TRUE;
edisp_pos = new_pos;
break; break;
} }
backchars = pappend(c, ch_tell()-1); backchars = pappend(c, ch_tell()-1);
@ -420,18 +509,65 @@ back_line(curr_pos)
endline = TRUE; endline = TRUE;
chopped = TRUE; chopped = TRUE;
quit_if_one_screen = FALSE; quit_if_one_screen = FALSE;
edisp_pos = new_pos;
break; break;
} }
shift: shift:
pshift_all(); if (!wordwrap)
while (backchars-- > 0)
{ {
(void) ch_back_get(); pshift_all();
new_pos--; new_pos -= backchars;
} else
{
if (c == ' ' || c == '\t')
{
for (;;)
{
c = ch_forw_get();
if (c == ' ' || c == '\t')
new_pos++;
else
{
if (c == '\r')
{
c = ch_forw_get();
if (c == '\n')
new_pos++;
}
if (c == '\n')
new_pos++;
break;
}
}
if (new_pos >= curr_pos)
break;
pshift_all();
} else
{
pshift_all();
if (wrap_pos == NULL_POSITION)
new_pos -= backchars;
else
new_pos = wrap_pos;
}
} }
goto loop; goto loop;
} }
} while (new_pos < curr_pos); if (wordwrap)
{
if (c == ' ' || c == '\t')
{
if (skipped_leading)
wrap_pos = new_pos;
} else
skipped_leading = TRUE;
}
if (new_pos >= curr_pos)
{
edisp_pos = new_pos;
break;
}
}
pdone(endline, chopped, 0); pdone(endline, chopped, 0);
@ -445,13 +581,8 @@ back_line(curr_pos)
curr_pos = begin_new_pos; curr_pos = begin_new_pos;
goto get_back_line; goto get_back_line;
} }
if (status_col)
if (status_col && curr_pos > 0) init_status_col(base_pos, line_position(), edisp_pos, new_pos);
{
int attr = is_hilited_attr(base_pos, curr_pos-1, 1, NULL);
if (attr)
set_status_col('*', attr);
}
#endif #endif
return (begin_new_pos); return (begin_new_pos);
@ -460,9 +591,7 @@ back_line(curr_pos)
/* /*
* Set attnpos. * Set attnpos.
*/ */
public void public void set_attnpos(POSITION pos)
set_attnpos(pos)
POSITION pos;
{ {
int c; int c;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -25,8 +25,7 @@ extern int top_scroll;
/* /*
* Jump to the end of the file. * Jump to the end of the file.
*/ */
public void public void jump_forw(void)
jump_forw(VOID_PARAM)
{ {
POSITION pos; POSITION pos;
POSITION end_pos; POSITION end_pos;
@ -36,6 +35,12 @@ jump_forw(VOID_PARAM)
error("Cannot seek to end of file", NULL_PARG); error("Cannot seek to end of file", NULL_PARG);
return; return;
} }
end_pos = ch_tell();
if (position(sc_height-1) == end_pos)
{
eof_bell();
return;
}
/* /*
* Note; lastmark will be called later by jump_loc, but it fails * Note; lastmark will be called later by jump_loc, but it fails
* because the position table has been cleared by pos_clear below. * because the position table has been cleared by pos_clear below.
@ -48,7 +53,6 @@ jump_forw(VOID_PARAM)
* to get to the beginning of the last line. * to get to the beginning of the last line.
*/ */
pos_clear(); pos_clear();
end_pos = ch_tell();
pos = back_line(end_pos); pos = back_line(end_pos);
if (pos == NULL_POSITION) if (pos == NULL_POSITION)
jump_loc(ch_zero(), sc_height-1); jump_loc(ch_zero(), sc_height-1);
@ -63,8 +67,7 @@ jump_forw(VOID_PARAM)
/* /*
* Jump to the last buffered line in the file. * Jump to the last buffered line in the file.
*/ */
public void public void jump_forw_buffered(void)
jump_forw_buffered(VOID_PARAM)
{ {
POSITION end; POSITION end;
@ -81,9 +84,7 @@ jump_forw_buffered(VOID_PARAM)
/* /*
* Jump to line n in the file. * Jump to line n in the file.
*/ */
public void public void jump_back(LINENUM linenum)
jump_back(linenum)
LINENUM linenum;
{ {
POSITION pos; POSITION pos;
PARG parg; PARG parg;
@ -114,8 +115,7 @@ jump_back(linenum)
/* /*
* Repaint the screen. * Repaint the screen.
*/ */
public void public void repaint(void)
repaint(VOID_PARAM)
{ {
struct scrpos scrpos; struct scrpos scrpos;
/* /*
@ -134,10 +134,7 @@ repaint(VOID_PARAM)
/* /*
* Jump to a specified percentage into the file. * Jump to a specified percentage into the file.
*/ */
public void public void jump_percent(int percent, long fraction)
jump_percent(percent, fraction)
int percent;
long fraction;
{ {
POSITION pos, len; POSITION pos, len;
@ -167,10 +164,7 @@ jump_percent(percent, fraction)
* Like jump_loc, but the position need not be * Like jump_loc, but the position need not be
* the first character in a line. * the first character in a line.
*/ */
public void public void jump_line_loc(POSITION pos, int sline)
jump_line_loc(pos, sline)
POSITION pos;
int sline;
{ {
int c; int c;
@ -195,10 +189,7 @@ jump_line_loc(pos, sline)
* The position must be the first character in a line. * The position must be the first character in a line.
* Place the target line on a specified line on the screen. * Place the target line on a specified line on the screen.
*/ */
public void public void jump_loc(POSITION pos, int sline)
jump_loc(pos, sline)
POSITION pos;
int sline;
{ {
int nline; int nline;
int sindex; int sindex;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -39,19 +39,6 @@
/* /*
* Language details. * Language details.
*/ */
#if HAVE_ANSI_PROTOS
#define LESSPARAMS(a) a
#else
#define LESSPARAMS(a) ()
#endif
#if HAVE_VOID
#define VOID_POINTER void *
#define VOID_PARAM void
#else
#define VOID_POINTER char *
#define VOID_PARAM
#define void int
#endif
#if HAVE_CONST #if HAVE_CONST
#define constant const #define constant const
#else #else
@ -83,6 +70,9 @@
#if HAVE_LIMITS_H #if HAVE_LIMITS_H
#include <limits.h> #include <limits.h>
#endif #endif
#if HAVE_STDINT_H
#include <stdint.h>
#endif
#if HAVE_STDLIB_H #if HAVE_STDLIB_H
#include <stdlib.h> #include <stdlib.h>
#endif #endif
@ -90,6 +80,27 @@
#include <string.h> #include <string.h>
#endif #endif
#if HAVE_STDCKDINT_H
#include <stdckdint.h>
#else
/*
* These substitutes for C23 stdckdint macros do not set *R on overflow,
* and they assume A and B are nonnegative. That is good enough for us.
*/
#define ckd_add(r, a, b) help_ckd_add(r, a, b, sizeof *(r), signed_expr(*(r)))
#define ckd_mul(r, a, b) help_ckd_mul(r, a, b, sizeof *(r), signed_expr(*(r)))
/* True if the integer expression E, after promotion, is signed. */
#define signed_expr(e) ((TRUE ? 0 : e) - 1 < 0)
#endif
#if defined UINTMAX_MAX
typedef uintmax_t uintmax;
#elif defined ULLONG_MAX
typedef unsigned long long uintmax;
#else
typedef unsigned long uintmax;
#endif
/* OS-specific includes */ /* OS-specific includes */
#ifdef _OSK #ifdef _OSK
#include <modes.h> #include <modes.h>
@ -114,7 +125,7 @@
#if !HAVE_STDLIB_H #if !HAVE_STDLIB_H
char *getenv(); char *getenv();
off_t lseek(); off_t lseek();
VOID_POINTER calloc(); void *calloc();
void free(); void free();
#endif #endif
@ -289,7 +300,7 @@ typedef off_t LINENUM;
/* /*
* An IFILE represents an input file. * An IFILE represents an input file.
*/ */
#define IFILE VOID_POINTER #define IFILE void*
#define NULL_IFILE ((IFILE)NULL) #define NULL_IFILE ((IFILE)NULL)
/* /*
@ -332,11 +343,20 @@ struct wchar_range_table
int count; int count;
}; };
#if HAVE_POLL
typedef short POLL_EVENTS;
#endif
#define EOI (-1) #define EOI (-1)
#define READ_ERR (-1)
#define READ_INTR (-2) #define READ_INTR (-2)
#define READ_AGAIN (-3)
/* A fraction is represented by an int n; the fraction is n/NUM_FRAC_DENOM */ /*
* A fraction is represented by a long n; the fraction is n/NUM_FRAC_DENOM.
* To avoid overflow problems, 0 <= n < NUM_FRAC_DENUM <= LONG_MAX/100.
*/
#define NUM_FRAC_DENOM 1000000 #define NUM_FRAC_DENOM 1000000
#define NUM_LOG_FRAC_DENOM 6 #define NUM_LOG_FRAC_DENOM 6
@ -368,6 +388,9 @@ struct wchar_range_table
#define SRCH_FILTER (1 << 13) /* Search is for '&' (filter) command */ #define SRCH_FILTER (1 << 13) /* Search is for '&' (filter) command */
#define SRCH_AFTER_TARGET (1 << 14) /* Start search after the target line */ #define SRCH_AFTER_TARGET (1 << 14) /* Start search after the target line */
#define SRCH_WRAP (1 << 15) /* Wrap-around search (continue at BOF/EOF) */ #define SRCH_WRAP (1 << 15) /* Wrap-around search (continue at BOF/EOF) */
#define SRCH_SUBSEARCH(i) (1 << (16+(i))) /* Search for subpattern */
/* {{ Depends on NUM_SEARCH_COLORS==5 }} */
#define SRCH_SUBSEARCH_ALL (SRCH_SUBSEARCH(1)|SRCH_SUBSEARCH(2)|SRCH_SUBSEARCH(3)|SRCH_SUBSEARCH(4)|SRCH_SUBSEARCH(5))
#define SRCH_REVERSE(t) (((t) & SRCH_FORW) ? \ #define SRCH_REVERSE(t) (((t) & SRCH_FORW) ? \
(((t) & ~SRCH_FORW) | SRCH_BACK) : \ (((t) & ~SRCH_FORW) | SRCH_BACK) : \
@ -406,8 +429,10 @@ struct wchar_range_table
#define AT_COLOR_MARK (6 << AT_COLOR_SHIFT) #define AT_COLOR_MARK (6 << AT_COLOR_SHIFT)
#define AT_COLOR_PROMPT (7 << AT_COLOR_SHIFT) #define AT_COLOR_PROMPT (7 << AT_COLOR_SHIFT)
#define AT_COLOR_RSCROLL (8 << AT_COLOR_SHIFT) #define AT_COLOR_RSCROLL (8 << AT_COLOR_SHIFT)
#define AT_COLOR_SEARCH (9 << AT_COLOR_SHIFT) #define AT_COLOR_HEADER (9 << AT_COLOR_SHIFT)
#define AT_COLOR_HEADER (11 << AT_COLOR_SHIFT) #define AT_COLOR_SEARCH (10 << AT_COLOR_SHIFT)
#define AT_COLOR_SUBSEARCH(i) ((10+(i)) << AT_COLOR_SHIFT)
#define NUM_SEARCH_COLORS (AT_NUM_COLORS-10-1)
typedef enum { CT_NULL, CT_4BIT, CT_6BIT } COLOR_TYPE; typedef enum { CT_NULL, CT_4BIT, CT_6BIT } COLOR_TYPE;
@ -527,9 +552,18 @@ typedef enum {
#define S_WINCH 04 #define S_WINCH 04
#define ABORT_SIGS() (sigs & (S_INTERRUPT|S_STOP)) #define ABORT_SIGS() (sigs & (S_INTERRUPT|S_STOP))
#ifdef EXIT_SUCCESS
#define QUIT_OK EXIT_SUCCESS
#else
#define QUIT_OK 0 #define QUIT_OK 0
#endif
#ifdef EXIT_FAILURE
#define QUIT_ERROR EXIT_FAILURE
#define QUIT_INTERRUPT (EXIT_FAILURE+1)
#else
#define QUIT_ERROR 1 #define QUIT_ERROR 1
#define QUIT_INTERRUPT 2 #define QUIT_INTERRUPT 2
#endif
#define QUIT_SAVED_STATUS (-1) #define QUIT_SAVED_STATUS (-1)
#define FOLLOW_DESC 0 #define FOLLOW_DESC 0
@ -568,6 +602,10 @@ typedef enum {
#define X11MOUSE_WHEEL_DOWN 0x41 /* Wheel scroll down */ #define X11MOUSE_WHEEL_DOWN 0x41 /* Wheel scroll down */
#define X11MOUSE_OFFSET 0x20 /* Added to button & pos bytes to create a char */ #define X11MOUSE_OFFSET 0x20 /* Added to button & pos bytes to create a char */
#if LESSTEST
#define LESS_DUMP_CHAR CONTROL(']')
#endif
struct mlist; struct mlist;
struct loption; struct loption;
struct hilite_tree; struct hilite_tree;
@ -577,11 +615,12 @@ struct ansi_state;
#include "funcs.h" #include "funcs.h"
/* Functions not included in funcs.h */ /* Functions not included in funcs.h */
void postoa LESSPARAMS ((POSITION, char*)); void postoa(POSITION, char*, int);
void linenumtoa LESSPARAMS ((LINENUM, char*)); void linenumtoa(LINENUM, char*, int);
void inttoa LESSPARAMS ((int, char*)); void inttoa(int, char*, int);
int lstrtoi LESSPARAMS ((char*, char**)); int lstrtoi(char*, char**, int);
POSITION lstrtopos LESSPARAMS ((char*, char**)); POSITION lstrtopos(char*, char**, int);
unsigned long lstrtoul(char*, char**, int);
#if MSDOS_COMPILER==WIN32C #if MSDOS_COMPILER==WIN32C
int pclose LESSPARAMS ((FILE*)); int pclose(FILE*);
#endif #endif

View File

@ -51,6 +51,7 @@
^F or @ Start search at FIRST file (for /) or last file (for ?). ^F or @ Start search at FIRST file (for /) or last file (for ?).
^K Highlight matches, but don't move (KEEP position). ^K Highlight matches, but don't move (KEEP position).
^R Don't use REGULAR EXPRESSIONS. ^R Don't use REGULAR EXPRESSIONS.
^S _n Search for match in _n-th parenthesized subpattern.
^W WRAP search if no match found. ^W WRAP search if no match found.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
@ -104,6 +105,7 @@
+_c_m_d Execute the less cmd each time a new file is examined. +_c_m_d Execute the less cmd each time a new file is examined.
!_c_o_m_m_a_n_d Execute the shell command with $SHELL. !_c_o_m_m_a_n_d Execute the shell command with $SHELL.
#_c_o_m_m_a_n_d Execute the shell command, expanded like a prompt.
|XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command. |XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command.
s _f_i_l_e Save input to a file. s _f_i_l_e Save input to a file.
v Edit the current file with $VISUAL or $EDITOR. v Edit the current file with $VISUAL or $EDITOR.
@ -186,7 +188,7 @@
-T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e] -T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e]
Use an alternate tags file. Use an alternate tags file.
-u -U .... --underline-special --UNDERLINE-SPECIAL -u -U .... --underline-special --UNDERLINE-SPECIAL
Change handling of backspaces. Change handling of backspaces, tabs and carriage returns.
-V ........ --version -V ........ --version
Display the version number of "less". Display the version number of "less".
-w ........ --hilite-unread -w ........ --hilite-unread
@ -207,6 +209,8 @@
Don't display tildes after end of file. Don't display tildes after end of file.
-# [_N] .... --shift=[_N] -# [_N] .... --shift=[_N]
Set horizontal scroll amount (0 = one half screen width). Set horizontal scroll amount (0 = one half screen width).
--exit-follow-on-close
Exit F command on a pipe when writer closes pipe.
--file-size --file-size
Automatically determine the size of the input file. Automatically determine the size of the input file.
--follow-name --follow-name
@ -215,8 +219,12 @@
Use N lines and M columns to display file headers. Use N lines and M columns to display file headers.
--incsearch --incsearch
Search file as each pattern character is typed in. Search file as each pattern character is typed in.
--line-num-width=N --intr=_C
Set the width of the -N line number field to N characters. Use _C instead of ^X to interrupt a read.
--line-num-width=_N
Set the width of the -N line number field to _N characters.
--modelines=_N
Read _N lines from the input file and look for vim modelines.
--mouse --mouse
Enable mouse input. Enable mouse input.
--no-keypad --no-keypad
@ -225,24 +233,44 @@
Remove duplicates from command history. Remove duplicates from command history.
--no-number-headers --no-number-headers
Don't give line numbers to header lines. Don't give line numbers to header lines.
--no-search-headers
Don't search in header lines or columns.
--no-vbell
Disable the terminal's visual bell.
--redraw-on-quit --redraw-on-quit
Redraw final screen when quitting. Redraw final screen when quitting.
--rscroll=C --rscroll=_C
Set the character used to mark truncated lines. Set the character used to mark truncated lines.
--save-marks --save-marks
Retain marks across invocations of less. Retain marks across invocations of less.
--search-options=[EFKNRW-] --search-options=[EFKNRW-]
Set default options for every search. Set default options for every search.
--status-col-width=N --show-preproc-errors
Set the width of the -J status column to N characters. Display a message if preprocessor exits with an error status.
--proc-backspace
Process backspaces for bold/underline.
--SPECIAL-BACKSPACE
Treat backspaces as control characters.
--proc-return
Delete carriage returns before newline.
--SPECIAL-RETURN
Treat carriage returns as control characters.
--proc-tab
Expand tabs to spaces.
--SPECIAL-TAB
Treat tabs as control characters.
--status-col-width=_N
Set the width of the -J status column to _N characters.
--status-line --status-line
Highlight or color the entire line containing a mark. Highlight or color the entire line containing a mark.
--use-backslash --use-backslash
Subsequent options use backslash as escape char. Subsequent options use backslash as escape char.
--use-color --use-color
Enables colored text. Enables colored text.
--wheel-lines=N --wheel-lines=_N
Each click of the mouse wheel moves N lines. Each click of the mouse wheel moves _N lines.
--wordwrap
Wrap lines at spaces.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -38,15 +38,13 @@ static char* metachars = NULL;
static int num_metachars = 0; static int num_metachars = 0;
static int size_metachars = 0; static int size_metachars = 0;
static void static void pr_usage(void)
pr_usage(VOID_PARAM)
{ {
fprintf(stderr, fprintf(stderr,
"usage: lessecho [-ox] [-cx] [-pn] [-dn] [-mx] [-nn] [-ex] [-fn] [-a] file ...\n"); "usage: lessecho [-ox] [-cx] [-pn] [-dn] [-mx] [-nn] [-ex] [-fn] [-a] file ...\n");
} }
static void static void pr_version(void)
pr_version(VOID_PARAM)
{ {
char *p; char *p;
char buf[10]; char buf[10];
@ -61,19 +59,13 @@ pr_version(VOID_PARAM)
printf("%s\n", buf); printf("%s\n", buf);
} }
static void static void pr_error(char *s)
pr_error(s)
char *s;
{ {
fprintf(stderr, "%s\n", s); fprintf(stderr, "%s\n", s);
exit(1); exit(1);
} }
static long static long lstrtol(char *s, char **pend, int radix)
lstrtol(s, radix, pend)
char *s;
int radix;
char **pend;
{ {
int v; int v;
int neg = 0; int neg = 0;
@ -141,9 +133,7 @@ lstrtol(s, radix, pend)
return (n); return (n);
} }
static void static void add_metachar(int ch)
add_metachar(ch)
int ch;
{ {
if (num_metachars+1 >= size_metachars) if (num_metachars+1 >= size_metachars)
{ {
@ -164,18 +154,13 @@ add_metachar(ch)
metachars[num_metachars] = '\0'; metachars[num_metachars] = '\0';
} }
static int static int is_metachar(int ch)
is_metachar(ch)
int ch;
{ {
return (metachars != NULL && strchr(metachars, ch) != NULL); return (metachars != NULL && strchr(metachars, ch) != NULL);
} }
#if !HAVE_STRCHR #if !HAVE_STRCHR
char * char * strchr(char *s, char c)
strchr(s, c)
char *s;
int c;
{ {
for ( ; *s != '\0'; s++) for ( ; *s != '\0'; s++)
if (*s == c) if (*s == c)
@ -186,10 +171,7 @@ strchr(s, c)
} }
#endif #endif
int int main(int argc, char *argv[])
main(argc, argv)
int argc;
char *argv[];
{ {
char *arg; char *arg;
char *s; char *s;
@ -210,7 +192,7 @@ main(argc, argv)
closequote = *++arg; closequote = *++arg;
break; break;
case 'd': case 'd':
closequote = lstrtol(++arg, 0, &s); closequote = lstrtol(++arg, &s, 0);
if (s == arg) if (s == arg)
pr_error("Missing number after -d"); pr_error("Missing number after -d");
break; break;
@ -221,7 +203,7 @@ main(argc, argv)
meta_escape = arg; meta_escape = arg;
break; break;
case 'f': case 'f':
meta_escape_buf[0] = lstrtol(++arg, 0, &s); meta_escape_buf[0] = lstrtol(++arg, &s, 0);
meta_escape_buf[1] = '\0'; meta_escape_buf[1] = '\0';
meta_escape = meta_escape_buf; meta_escape = meta_escape_buf;
if (s == arg) if (s == arg)
@ -231,7 +213,7 @@ main(argc, argv)
openquote = *++arg; openquote = *++arg;
break; break;
case 'p': case 'p':
openquote = lstrtol(++arg, 0, &s); openquote = lstrtol(++arg, &s, 0);
if (s == arg) if (s == arg)
pr_error("Missing number after -p"); pr_error("Missing number after -p");
break; break;
@ -239,7 +221,7 @@ main(argc, argv)
add_metachar(*++arg); add_metachar(*++arg);
break; break;
case 'n': case 'n':
add_metachar(lstrtol(++arg, 0, &s)); add_metachar(lstrtol(++arg, &s, 0));
if (s == arg) if (s == arg)
pr_error("Missing number after -n"); pr_error("Missing number after -n");
break; break;

View File

@ -1,44 +1,44 @@
.TH LESSECHO 1 "Version 608: 22 Jul 2022" .TH LESSECHO 1 "Version 632: 06 Apr 2023"
.SH NAME .SH NAME
lessecho \- expand metacharacters lessecho \- expand metacharacters
.SH SYNOPSIS .SH SYNOPSIS
.B lessecho .B lessecho
.I "[-ox] [-cx] [-pn] [-dn] [-mx] [-nn] [-ex] [-a] file ..." .I "[-ox] [-cx] [-pn] [-dn] [-mx] [-nn] [-ex] [-a] file ..."
.SH "DESCRIPTION" .SH "DESCRIPTION"
.I lessecho .B lessecho
is a program that simply echos its arguments on standard output. is a program that simply echos its arguments on standard output.
But any metacharacter in the output is preceded by an "escape" But any metacharacter in the output is preceded by an "escape"
character, which by default is a backslash. character, which by default is a backslash.
.SH OPTIONS .SH OPTIONS
A summary of options is included below. A summary of options is included below.
.TP .TP
.B \-ex .B \-e\fIx\fP
Specifies "x", rather than backslash, to be the escape char for metachars. Specifies "\fIx\fP", rather than backslash, to be the escape char for metachars.
If x is "-", no escape char is used and arguments containing metachars If \fIx\fP is "-", no escape char is used and arguments containing metachars
are surrounded by quotes instead. are surrounded by quotes instead.
.TP .TP
.B \-ox .B \-o\fIx\fP
Specifies "x", rather than double-quote, to be the open quote character, Specifies "\fIx\fP", rather than double-quote, to be the open quote character,
which is used if the \-e- option is specified. which is used if the \-e- option is specified.
.TP .TP
.B \-cx .B \-c\fIx\fP
Specifies "x" to be the close quote character. Specifies "\fIx\fP" to be the close quote character.
.TP .TP
.B \-pn .B \-p\fIn\fP
Specifies "n" to be the open quote character, as an integer. Specifies "\fIn\fP" to be the open quote character, as an integer.
.TP .TP
.B \-dn .B \-d\fIn\fP
Specifies "n" to be the close quote character, as an integer. Specifies "\fIn\fP" to be the close quote character, as an integer.
.TP .TP
.B \-mx .B \-m\fIx\fP
Specifies "x" to be a metachar. Specifies "\fIx\fP" to be a metachar.
By default, no characters are considered metachars. By default, no characters are considered metachars.
.TP .TP
.B \-nn .B \-n\fIn\fP
Specifies "n" to be a metachar, as an integer. Specifies "\fIn\fP" to be a metachar, as an integer.
.TP .TP
.B \-fn .B \-f\fIn\fP
Specifies "n" to be the escape char for metachars, as an integer. Specifies "\fIn\fP" to be the escape char for metachars, as an integer.
.TP .TP
.B \-a .B \-a
Specifies that all arguments are to be quoted. Specifies that all arguments are to be quoted.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -80,12 +80,12 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/ */
#include "defines.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "lesskey.h" #include "lesskey.h"
#include "cmd.h" #include "cmd.h"
#include "defines.h"
char fileheader[] = { char fileheader[] = {
C0_LESSKEY_MAGIC, C0_LESSKEY_MAGIC,
@ -108,46 +108,39 @@ char *outfile = NULL ;
extern char version[]; extern char version[];
static void static void usage(void)
usage(void)
{ {
fprintf(stderr, "usage: lesskey [-o output] [input]\n"); fprintf(stderr, "usage: lesskey [-o output] [input]\n");
exit(1); exit(1);
} }
void void lesskey_parse_error(char *s)
lesskey_parse_error(s)
char *s;
{ {
fprintf(stderr, "%s\n", s); fprintf(stderr, "%s\n", s);
} }
int int lstrtoi(char *buf, char **ebuf, int radix)
lstrtoi(buf, ebuf)
char *buf;
char **ebuf;
{ {
return (int) strtol(buf, ebuf, 10); return (int) strtol(buf, ebuf, radix);
} }
void * void out_of_memory(void)
ecalloc(count, size) {
int count; fprintf(stderr, "lesskey: cannot allocate memory\n");
unsigned int size; exit(1);
}
void * ecalloc(int count, unsigned int size)
{ {
void *p; void *p;
p = calloc(count, size); p = calloc(count, size);
if (p != NULL) if (p == NULL)
return (p); out_of_memory();
fprintf(stderr, "lesskey: cannot allocate %d bytes of memory\n", count*size); return (p);
exit(1);
} }
static char * static char * mkpathname(char *dirname, char *filename)
mkpathname(dirname, filename)
char *dirname;
char *filename;
{ {
char *pathname; char *pathname;
@ -161,9 +154,7 @@ mkpathname(dirname, filename)
/* /*
* Figure out the name of a default file (in the user's HOME directory). * Figure out the name of a default file (in the user's HOME directory).
*/ */
char * char * homefile(char *filename)
homefile(filename)
char *filename;
{ {
char *p; char *p;
char *pathname; char *pathname;
@ -185,10 +176,7 @@ homefile(filename)
/* /*
* Parse command line arguments. * Parse command line arguments.
*/ */
static void static void parse_args(int argc, char **argv)
parse_args(argc, argv)
int argc;
char **argv;
{ {
char *arg; char *arg;
@ -258,11 +246,7 @@ parse_args(argc, argv)
/* /*
* Output some bytes. * Output some bytes.
*/ */
static void static void fputbytes(FILE *fd, char *buf, int len)
fputbytes(fd, buf, len)
FILE *fd;
char *buf;
int len;
{ {
while (len-- > 0) while (len-- > 0)
{ {
@ -274,10 +258,7 @@ fputbytes(fd, buf, len)
/* /*
* Output an integer, in special KRADIX form. * Output an integer, in special KRADIX form.
*/ */
static void static void fputint(FILE *fd, unsigned int val)
fputint(fd, val)
FILE *fd;
unsigned int val;
{ {
char c; char c;
@ -293,10 +274,7 @@ fputint(fd, val)
fwrite(&c, sizeof(char), 1, fd); fwrite(&c, sizeof(char), 1, fd);
} }
int int main(int argc, char *argv[])
main(argc, argv)
int argc;
char *argv[];
{ {
struct lesskey_tables tables; struct lesskey_tables tables;
FILE *out; FILE *out;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.

View File

@ -1,5 +1,5 @@
'\" t '\" t
.TH LESSKEY 1 "Version 608: 22 Jul 2022" .TH LESSKEY 1 "Version 632: 06 Apr 2023"
.SH NAME .SH NAME
lesskey \- customize key bindings for less lesskey \- customize key bindings for less
.SH "SYNOPSIS (deprecated)" .SH "SYNOPSIS (deprecated)"
@ -12,33 +12,33 @@ lesskey \- customize key bindings for less
.B "lesskey \-\-version" .B "lesskey \-\-version"
.SH SCOPE .SH SCOPE
This document describes the format of the This document describes the format of the
.I lesskey .B lesskey
source file, which is used by source file, which is used by
.I less .B less
version 582 and later. version 582 and later.
In previous versions of In previous versions of
.IR less , .BR less ,
a separate program called a separate program called
.I lesskey .B lesskey
was used to compile the was used to compile the
.I lesskey .B lesskey
source file into a format understood by source file into a format understood by
.IR less . .BR less .
This compilation step is no longer required and the This compilation step is no longer required and the
.I lesskey .B 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 .B less
itself. itself.
.PP .PP
.SH DESCRIPTION .SH DESCRIPTION
A A
.I lesskey .B lesskey
file specifies a set of key bindings and environment variables file specifies a set of key bindings and environment variables
to be used by subsequent invocations of to be used by subsequent invocations of
.I less. .BR less .
.SH FILE FORMAT .SH FILE FORMAT
The input file consists of one or more The input file consists of one or more
.I sections. .IR sections .
Each section starts with a line that identifies the type of section. Each section starts with a line that identifies the type of section.
Possible sections are: Possible sections are:
.IP #command .IP #command
@ -112,22 +112,22 @@ caret, space, tab and the backslash itself.
.PP .PP
An action may be followed by an "extra" string. An action may be followed by an "extra" string.
When such a command is entered while running When such a command is entered while running
.IR less , .BR less ,
the action is performed, and then the extra the action is performed, and then the extra
string is parsed, just as if it were typed in to string is parsed, just as if it were typed in to
.IR less . .BR less .
This feature can be used in certain cases to extend This feature can be used in certain cases to extend
the functionality of a command. the functionality of a command.
For example, see the "{" and ":t" commands in the example below. For example, see the "{" and ":t" commands in the example below.
The extra string has a special meaning for the "quit" action: The extra string has a special meaning for the "quit" action:
when when
.I less .B less
quits, the first character of the extra string is used as its exit status. quits, the first character of the extra string is used as its exit status.
. .
.SH EXAMPLE .SH EXAMPLE
The following input file describes the set of The following input file describes the set of
default command keys used by default command keys used by
.IR less . .BR less .
Documentation on each command can be found in the Documentation on each command can be found in the
.less .less
man page, under the key sequence which invokes the command. man page, under the key sequence which invokes the command.
@ -231,12 +231,14 @@ T prev-tag
- toggle-option - toggle-option
:t toggle-option t :t toggle-option t
s toggle-option o s toggle-option o
## Use a long option name by starting the extra string with ONE dash; eg: ## Use a long option name by starting the
## s toggle-option -log-file\n ## extra string with ONE dash; eg:
## s toggle-option -log-file\en
\&_ display-option \&_ display-option
| pipe | pipe
v visual v visual
! shell ! shell
# pshell
+ firstcmd + firstcmd
H help H help
h help h help
@ -261,14 +263,14 @@ ZZ quit
.sp .sp
.SH PRECEDENCE .SH PRECEDENCE
Commands specified by Commands specified by
.I lesskey .B lesskey
take precedence over the default commands. take precedence over the default commands.
A default command key may be disabled by including it in the A default command key may be disabled by including it in the
input file with the action "invalid". input file with the action "invalid".
Alternatively, a key may be defined Alternatively, a key may be defined
to do nothing by using the action "noaction". to do nothing by using the action "noaction".
"noaction" is similar to "invalid", but "noaction" is similar to "invalid", but
.I less .B less
will give an error beep for an "invalid" command, will give an error beep for an "invalid" command,
but not for a "noaction" command. but not for a "noaction" command.
In addition, ALL default commands may be disabled by In addition, ALL default commands may be disabled by
@ -299,7 +301,7 @@ one per line as in the example below.
.SH EXAMPLE .SH EXAMPLE
The following input file describes the set of The following input file describes the set of
default line-editing keys used by default line-editing keys used by
.IR less : .BR less :
.sp .sp
.RS 5m .RS 5m
.TS .TS
@ -347,7 +349,7 @@ Each line consists of an environment variable name, an equals sign (=)
and the value to be assigned to the environment variable. and the value to be assigned to the environment variable.
White space before and after the equals sign is ignored. White space before and after the equals sign is ignored.
Variables assigned in this way are visible only to Variables assigned in this way are visible only to
.IR less . .BR less .
If a variable is specified in the system environment and also in a If a variable is specified in the system environment and also in a
lesskey file, the value in the lesskey file takes precedence. lesskey file, the value in the lesskey file takes precedence.
. .
@ -363,18 +365,18 @@ it cannot append to a variable in the system environment.
.SH CONDITIONAL CONFIGURATION .SH CONDITIONAL CONFIGURATION
If a line begins with #version followed by a relational operator and a version number, 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 the remainder of the line is parsed if and only if the running version of
.I less .B less
(or (or
.IR lesskey ) .BR lesskey )
matches the operator. matches the operator.
This can be helpful if a lesskey file is used by different versions of This can be helpful if a lesskey file is used by different versions of
.IR less . .BR less .
.sp .sp
For example, suppose that a new command named 'sideways-search' is added in For example, suppose that a new command named 'sideways-search' is added in
.I less .B less
version 777. version 777.
Then the following line would assign the command to the Q key, but only in versions of Then the following line would assign the command to the Q key, but only in versions of
.I less .B less
which support it. The line would be ignored by versions earlier than 777. which support it. The line would be ignored by versions earlier than 777.
.sp .sp
.nf .nf
@ -395,9 +397,9 @@ l l.
.RE .RE
.sp .sp
The #version feature is not supported in The #version feature is not supported in
.I less .B less
and and
.I lesskey .B lesskey
before version 594. before version 594.
In those older versions, all #version lines are ignored. In those older versions, all #version lines are ignored.
. .
@ -421,7 +423,7 @@ which start with a NUL character (0).
This NUL character should be represented as \e340 in a lesskey file. This NUL character should be represented as \e340 in a lesskey file.
. .
.SH COPYRIGHT .SH COPYRIGHT
Copyright (C) 1984-2022 Mark Nudelman Copyright (C) 1984-2023 Mark Nudelman
.PP .PP
less is part of the GNU project and is free software. less is part of the GNU project and is free software.
You can redistribute it and/or modify it You can redistribute it and/or modify it

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -7,13 +7,13 @@
* For more information, see the README file. * For more information, see the README file.
*/ */
#include "defines.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "lesskey.h" #include "lesskey.h"
#include "cmd.h" #include "cmd.h"
#include "xbuf.h" #include "xbuf.h"
#include "defines.h"
#define CONTROL(c) ((c)&037) #define CONTROL(c) ((c)&037)
#define ESC CONTROL('[') #define ESC CONTROL('[')
@ -21,7 +21,7 @@
extern void lesskey_parse_error(char *msg); extern void lesskey_parse_error(char *msg);
extern char *homefile(char *filename); extern char *homefile(char *filename);
extern void *ecalloc(int count, unsigned int size); extern void *ecalloc(int count, unsigned int size);
extern int lstrtoi(char *str, char **end); extern int lstrtoi(char *str, char **end, int radix);
extern char version[]; extern char version[];
static int linenum; static int linenum;
@ -88,6 +88,7 @@ static struct lesskey_cmdname cmdnames[] =
{ "set-mark", A_SETMARK }, { "set-mark", A_SETMARK },
{ "set-mark-bottom", A_SETMARKBOT }, { "set-mark-bottom", A_SETMARKBOT },
{ "shell", A_SHELL }, { "shell", A_SHELL },
{ "pshell", A_PSHELL },
{ "status", A_STAT }, { "status", A_STAT },
{ "toggle-flag", A_OPT_TOGGLE }, { "toggle-flag", A_OPT_TOGGLE },
{ "toggle-option", A_OPT_TOGGLE }, { "toggle-option", A_OPT_TOGGLE },
@ -126,10 +127,7 @@ static struct lesskey_cmdname editnames[] =
/* /*
* Print a parse error message. * Print a parse error message.
*/ */
static void static void parse_error(char *fmt, char *arg1)
parse_error(fmt, arg1)
char *fmt;
char *arg1;
{ {
char buf[1024]; char buf[1024];
int n = snprintf(buf, sizeof(buf), "%s: line %d: ", lesskey_file, linenum); int n = snprintf(buf, sizeof(buf), "%s: line %d: ", lesskey_file, linenum);
@ -142,9 +140,7 @@ parse_error(fmt, arg1)
/* /*
* Initialize lesskey_tables. * Initialize lesskey_tables.
*/ */
static void static void init_tables(struct lesskey_tables *tables)
init_tables(tables)
struct lesskey_tables *tables;
{ {
tables->currtable = &tables->cmdtable; tables->currtable = &tables->cmdtable;
@ -163,11 +159,7 @@ init_tables(tables)
#define CHAR_STRING_LEN 8 #define CHAR_STRING_LEN 8
static char * static char * char_string(char *buf, int ch, int lit)
char_string(buf, ch, lit)
char *buf;
int ch;
int lit;
{ {
if (lit || (ch >= 0x20 && ch < 0x7f)) if (lit || (ch >= 0x20 && ch < 0x7f))
{ {
@ -183,9 +175,7 @@ char_string(buf, ch, lit)
/* /*
* Increment char pointer by one up to terminating nul byte. * Increment char pointer by one up to terminating nul byte.
*/ */
static char * static char * increment_pointer(char *p)
increment_pointer(p)
char *p;
{ {
if (*p == '\0') if (*p == '\0')
return p; return p;
@ -195,10 +185,7 @@ increment_pointer(p)
/* /*
* Parse one character of a string. * Parse one character of a string.
*/ */
static char * static char * tstr(char **pp, int xlate)
tstr(pp, xlate)
char **pp;
int xlate;
{ {
char *p; char *p;
char ch; char ch;
@ -309,9 +296,7 @@ tstr(pp, xlate)
return (buf); return (buf);
} }
static int static int issp(char ch)
issp(ch)
char ch;
{ {
return (ch == ' ' || ch == '\t'); return (ch == ' ' || ch == '\t');
} }
@ -319,9 +304,7 @@ issp(ch)
/* /*
* Skip leading spaces in a string. * Skip leading spaces in a string.
*/ */
static char * static char * skipsp(char *s)
skipsp(s)
char *s;
{ {
while (issp(*s)) while (issp(*s))
s++; s++;
@ -331,9 +314,7 @@ skipsp(s)
/* /*
* Skip non-space characters in a string. * Skip non-space characters in a string.
*/ */
static char * static char * skipnsp(char *s)
skipnsp(s)
char *s;
{ {
while (*s != '\0' && !issp(*s)) while (*s != '\0' && !issp(*s))
s++; s++;
@ -344,9 +325,7 @@ skipnsp(s)
* Clean up an input line: * Clean up an input line:
* strip off the trailing newline & any trailing # comment. * strip off the trailing newline & any trailing # comment.
*/ */
static char * static char * clean_line(char *s)
clean_line(s)
char *s;
{ {
int i; int i;
@ -361,17 +340,12 @@ clean_line(s)
/* /*
* Add a byte to the output command table. * Add a byte to the output command table.
*/ */
static void static void add_cmd_char(unsigned char c, struct lesskey_tables *tables)
add_cmd_char(c, tables)
int c;
struct lesskey_tables *tables;
{ {
xbuf_add(&tables->currtable->buf, c); xbuf_add_byte(&tables->currtable->buf, c);
} }
static void static void erase_cmd_char(struct lesskey_tables *tables)
erase_cmd_char(tables)
struct lesskey_tables *tables;
{ {
xbuf_pop(&tables->currtable->buf); xbuf_pop(&tables->currtable->buf);
} }
@ -379,10 +353,7 @@ erase_cmd_char(tables)
/* /*
* Add a string to the output command table. * Add a string to the output command table.
*/ */
static void static void add_cmd_str(char *s, struct lesskey_tables *tables)
add_cmd_str(s, tables)
char *s;
struct lesskey_tables *tables;
{ {
for ( ; *s != '\0'; s++) for ( ; *s != '\0'; s++)
add_cmd_char(*s, tables); add_cmd_char(*s, tables);
@ -392,10 +363,7 @@ add_cmd_str(s, tables)
* Does a given version number match the running version? * Does a given version number match the running version?
* Operator compares the running version to the given version. * Operator compares the running version to the given version.
*/ */
static int static int match_version(char op, int ver)
match_version(op, ver)
char op;
int ver;
{ {
switch (op) switch (op)
{ {
@ -414,10 +382,7 @@ match_version(op, ver)
* If the version matches, return the part of the line that should be executed. * If the version matches, return the part of the line that should be executed.
* Otherwise, return NULL. * Otherwise, return NULL.
*/ */
static char * static char * version_line(char *s, struct lesskey_tables *tables)
version_line(s, tables)
char *s;
struct lesskey_tables *tables;
{ {
char op; char op;
int ver; int ver;
@ -439,7 +404,7 @@ version_line(s, tables)
return (NULL); return (NULL);
} }
s = skipsp(s); s = skipsp(s);
ver = lstrtoi(s, &e); ver = lstrtoi(s, &e, 10);
if (e == s) if (e == s)
{ {
parse_error("non-numeric version number in #version line", ""); parse_error("non-numeric version number in #version line", "");
@ -453,10 +418,7 @@ version_line(s, tables)
/* /*
* See if we have a special "control" line. * See if we have a special "control" line.
*/ */
static char * static char * control_line(char *s, struct lesskey_tables *tables)
control_line(s, tables)
char *s;
struct lesskey_tables *tables;
{ {
#define PREFIX(str,pat) (strncmp(str,pat,strlen(pat)) == 0) #define PREFIX(str,pat) (strncmp(str,pat,strlen(pat)) == 0)
@ -491,10 +453,7 @@ control_line(s, tables)
/* /*
* Find an action, given the name of the action. * Find an action, given the name of the action.
*/ */
static int static int findaction(char *actname, struct lesskey_tables *tables)
findaction(actname, tables)
char *actname;
struct lesskey_tables *tables;
{ {
int i; int i;
@ -512,10 +471,7 @@ findaction(actname, tables)
* resulting less action, and EXTRA is an "extra" user * resulting less action, and EXTRA is an "extra" user
* key sequence injected after the action. * key sequence injected after the action.
*/ */
static void static void parse_cmdline(char *p, struct lesskey_tables *tables)
parse_cmdline(p, tables)
char *p;
struct lesskey_tables *tables;
{ {
char *actname; char *actname;
int action; int action;
@ -563,14 +519,14 @@ parse_cmdline(p, tables)
p = skipsp(p); p = skipsp(p);
if (*p == '\0') if (*p == '\0')
{ {
add_cmd_char(action, tables); add_cmd_char((unsigned char) action, tables);
} else } else
{ {
/* /*
* OR the special value A_EXTRA into the action byte. * OR the special value A_EXTRA into the action byte.
* Put the extra string after the action byte. * Put the extra string after the action byte.
*/ */
add_cmd_char(action | A_EXTRA, tables); add_cmd_char((unsigned char) (action | A_EXTRA), tables);
while (*p != '\0') while (*p != '\0')
add_cmd_str(tstr(&p, 0), tables); add_cmd_str(tstr(&p, 0), tables);
add_cmd_char('\0', tables); add_cmd_char('\0', tables);
@ -581,10 +537,7 @@ parse_cmdline(p, tables)
* Parse a variable definition line, of the form * Parse a variable definition line, of the form
* NAME = VALUE * NAME = VALUE
*/ */
static void static void parse_varline(char *line, struct lesskey_tables *tables)
parse_varline(line, tables)
char *line;
struct lesskey_tables *tables;
{ {
char *s; char *s;
char *p = line; char *p = line;
@ -631,10 +584,7 @@ parse_varline(line, tables)
/* /*
* Parse a line from the lesskey file. * Parse a line from the lesskey file.
*/ */
static void static void parse_line(char *line, struct lesskey_tables *tables)
parse_line(line, tables)
char *line;
struct lesskey_tables *tables;
{ {
char *p; char *p;
@ -662,10 +612,7 @@ parse_line(line, tables)
/* /*
* Parse a lesskey source file and store result in tables. * Parse a lesskey source file and store result in tables.
*/ */
int int parse_lesskey(char *infile, struct lesskey_tables *tables)
parse_lesskey(infile, tables)
char *infile;
struct lesskey_tables *tables;
{ {
FILE *desc; FILE *desc;
char line[1024]; char line[1024];
@ -678,7 +625,7 @@ parse_lesskey(infile, tables)
errors = 0; errors = 0;
linenum = 0; linenum = 0;
if (less_version == 0) if (less_version == 0)
less_version = lstrtoi(version, NULL); less_version = lstrtoi(version, NULL, 10);
/* /*
* Open the input file. * Open the input file.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -37,7 +37,7 @@ static struct {
* Buffer of ansi sequences which have been shifted off the left edge * Buffer of ansi sequences which have been shifted off the left edge
* of the screen. * of the screen.
*/ */
struct xbuffer shifted_ansi; static struct xbuffer shifted_ansi;
/* /*
* Ring buffer of last ansi sequences sent. * Ring buffer of last ansi sequences sent.
@ -61,6 +61,7 @@ public int tabstops[TABSTOP_MAX] = { 0 }; /* Custom tabstops */
public int ntabstops = 1; /* Number of tabstops */ public int ntabstops = 1; /* Number of tabstops */
public int tabdefault = 8; /* Default repeated tabstops */ public int tabdefault = 8; /* Default repeated tabstops */
public POSITION highest_hilite; /* Pos of last hilite in file found so far */ public POSITION highest_hilite; /* Pos of last hilite in file found so far */
static POSITION line_pos;
static int end_column; /* Printable length, accounting for backspaces, etc. */ static int end_column; /* Printable length, accounting for backspaces, etc. */
static int right_curr; static int right_curr;
@ -74,12 +75,15 @@ static char *end_ansi_chars;
static char *mid_ansi_chars; static char *mid_ansi_chars;
static int in_hilite; static int in_hilite;
static int attr_swidth LESSPARAMS ((int a)); static int attr_swidth(int a);
static int attr_ewidth LESSPARAMS ((int a)); static int attr_ewidth(int a);
static int do_append LESSPARAMS ((LWCHAR ch, char *rep, POSITION pos)); static int do_append(LWCHAR ch, char *rep, POSITION pos);
extern int sigs; extern int sigs;
extern int bs_mode; extern int bs_mode;
extern int proc_backspace;
extern int proc_tab;
extern int proc_return;
extern int linenums; extern int linenums;
extern int ctldisp; extern int ctldisp;
extern int twiddle; extern int twiddle;
@ -105,23 +109,31 @@ static char mbc_buf[MAX_UTF_CHAR_LEN];
static int mbc_buf_len = 0; static int mbc_buf_len = 0;
static int mbc_buf_index = 0; static int mbc_buf_index = 0;
static POSITION mbc_pos; static POSITION mbc_pos;
static int saved_line_end;
static int saved_end_column;
/* Configurable color map */ /* Configurable color map */
static char color_map[AT_NUM_COLORS][12] = { struct color_map { int attr; char color[12]; };
"Wm", /* AT_COLOR_ATTN */ static struct color_map color_map[] = {
"kR", /* AT_COLOR_BIN */ { AT_UNDERLINE, "" },
"kR", /* AT_COLOR_CTRL */ { AT_BOLD, "" },
"kY", /* AT_COLOR_ERROR */ { AT_BLINK, "" },
"c", /* AT_COLOR_LINENUM */ { AT_STANDOUT, "" },
"Wb", /* AT_COLOR_MARK */ { AT_COLOR_ATTN, "Wm" },
"kC", /* AT_COLOR_PROMPT */ { AT_COLOR_BIN, "kR" },
"kc", /* AT_COLOR_RSCROLL */ { AT_COLOR_CTRL, "kR" },
"kG", /* AT_COLOR_SEARCH */ { AT_COLOR_ERROR, "kY" },
"", /* AT_COLOR_HEADER */ { AT_COLOR_LINENUM, "c" },
"", /* AT_UNDERLINE */ { AT_COLOR_MARK, "Wb" },
"", /* AT_BOLD */ { AT_COLOR_PROMPT, "kC" },
"", /* AT_BLINK */ { AT_COLOR_RSCROLL, "kc" },
"", /* AT_STANDOUT */ { AT_COLOR_HEADER, "" },
{ AT_COLOR_SEARCH, "kG" },
{ AT_COLOR_SUBSEARCH(1), "ky" },
{ AT_COLOR_SUBSEARCH(2), "wb" },
{ AT_COLOR_SUBSEARCH(3), "YM" },
{ AT_COLOR_SUBSEARCH(4), "Yr" },
{ AT_COLOR_SUBSEARCH(5), "Wc" },
}; };
/* State while processing an ANSI escape sequence */ /* State while processing an ANSI escape sequence */
@ -134,8 +146,7 @@ struct ansi_state {
/* /*
* Initialize from environment variables. * Initialize from environment variables.
*/ */
public void public void init_line(void)
init_line(VOID_PARAM)
{ {
int ax; int ax;
@ -160,8 +171,7 @@ init_line(VOID_PARAM)
/* /*
* Expand the line buffer. * Expand the line buffer.
*/ */
static int static int expand_linebuf(void)
expand_linebuf(VOID_PARAM)
{ {
/* Double the size of the line buffer. */ /* Double the size of the line buffer. */
int new_size = size_linebuf * 2; int new_size = size_linebuf * 2;
@ -191,18 +201,14 @@ expand_linebuf(VOID_PARAM)
/* /*
* Is a character ASCII? * Is a character ASCII?
*/ */
public int public int is_ascii_char(LWCHAR ch)
is_ascii_char(ch)
LWCHAR ch;
{ {
return (ch <= 0x7F); return (ch <= 0x7F);
} }
/* /*
*/ */
static void static void inc_end_column(int w)
inc_end_column(w)
int w;
{ {
if (end_column > right_column && w > 0) if (end_column > right_column && w > 0)
{ {
@ -212,11 +218,15 @@ inc_end_column(w)
end_column += w; end_column += w;
} }
public POSITION line_position(void)
{
return line_pos;
}
/* /*
* Rewind the line buffer. * Rewind the line buffer.
*/ */
public void public void prewind(void)
prewind(VOID_PARAM)
{ {
int ax; int ax;
@ -241,6 +251,7 @@ prewind(VOID_PARAM)
ansi_in_line = 0; ansi_in_line = 0;
hlink_in_line = 0; hlink_in_line = 0;
line_mark_attr = 0; line_mark_attr = 0;
line_pos = NULL_POSITION;
xbuf_reset(&shifted_ansi); xbuf_reset(&shifted_ansi);
xbuf_reset(&last_ansi); xbuf_reset(&last_ansi);
for (ax = 0; ax < NUM_LAST_ANSIS; ax++) for (ax = 0; ax < NUM_LAST_ANSIS; ax++)
@ -251,12 +262,17 @@ prewind(VOID_PARAM)
/* /*
* Set a character in the line buffer. * Set a character in the line buffer.
*/ */
static void static void set_linebuf(int n, char ch, int attr)
set_linebuf(n, ch, attr)
int n;
char ch;
int attr;
{ {
if (n >= size_linebuf)
{
/*
* Won't fit in line buffer.
* Try to expand it.
*/
if (expand_linebuf())
return;
}
linebuf.buf[n] = ch; linebuf.buf[n] = ch;
linebuf.attr[n] = attr; linebuf.attr[n] = attr;
} }
@ -264,11 +280,7 @@ set_linebuf(n, ch, attr)
/* /*
* Append a character to the line buffer. * Append a character to the line buffer.
*/ */
static void static void add_linebuf(char ch, int attr, int w)
add_linebuf(ch, attr, w)
char ch;
int attr;
int w;
{ {
set_linebuf(linebuf.end++, ch, attr); set_linebuf(linebuf.end++, ch, attr);
inc_end_column(w); inc_end_column(w);
@ -277,11 +289,7 @@ add_linebuf(ch, attr, w)
/* /*
* Append a string to the line buffer. * Append a string to the line buffer.
*/ */
static void static void addstr_linebuf(char *s, int attr, int cw)
addstr_linebuf(s, attr, cw)
char *s;
int attr;
int cw;
{ {
for ( ; *s != '\0'; s++) for ( ; *s != '\0'; s++)
add_linebuf(*s, attr, cw); add_linebuf(*s, attr, cw);
@ -290,11 +298,7 @@ addstr_linebuf(s, attr, cw)
/* /*
* Set a character in the line prefix buffer. * Set a character in the line prefix buffer.
*/ */
static void static void set_pfx(int n, char ch, int attr)
set_pfx(n, ch, attr)
int n;
char ch;
int attr;
{ {
linebuf.pfx[n] = ch; linebuf.pfx[n] = ch;
linebuf.pfx_attr[n] = attr; linebuf.pfx_attr[n] = attr;
@ -303,10 +307,7 @@ set_pfx(n, ch, attr)
/* /*
* Append a character to the line prefix buffer. * Append a character to the line prefix buffer.
*/ */
static void static void add_pfx(char ch, int attr)
add_pfx(ch, attr)
char ch;
int attr;
{ {
set_pfx(linebuf.pfx_end++, ch, attr); set_pfx(linebuf.pfx_end++, ch, attr);
} }
@ -314,9 +315,7 @@ add_pfx(ch, attr)
/* /*
* Insert the status column and line number into the line buffer. * Insert the status column and line number into the line buffer.
*/ */
public void public void plinestart(POSITION pos)
plinestart(pos)
POSITION pos;
{ {
LINENUM linenum = 0; LINENUM linenum = 0;
int i; int i;
@ -367,7 +366,7 @@ plinestart(pos)
len = 0; len = 0;
else else
{ {
linenumtoa(linenum, buf); linenumtoa(linenum, buf, 10);
len = (int) strlen(buf); len = (int) strlen(buf);
} }
for (i = 0; i < linenum_width - len; i++) for (i = 0; i < linenum_width - len; i++)
@ -383,8 +382,7 @@ plinestart(pos)
* Return the width of the line prefix (status column and line number). * Return the width of the line prefix (status column and line number).
* {{ Actual line number can be wider than linenum_width. }} * {{ Actual line number can be wider than linenum_width. }}
*/ */
public int public int line_pfx_width(void)
line_pfx_width(VOID_PARAM)
{ {
int width = 0; int width = 0;
if (status_col) if (status_col)
@ -398,13 +396,12 @@ line_pfx_width(VOID_PARAM)
* Shift line left so that the last char is just to the left * Shift line left so that the last char is just to the left
* of the first visible column. * of the first visible column.
*/ */
public void public void pshift_all(void)
pshift_all(VOID_PARAM)
{ {
int i; int i;
for (i = linebuf.print; i < linebuf.end; i++) for (i = linebuf.print; i < linebuf.end; i++)
if (linebuf.attr[i] == AT_ANSI) if (linebuf.attr[i] == AT_ANSI)
xbuf_add(&shifted_ansi, linebuf.buf[i]); xbuf_add_byte(&shifted_ansi, (unsigned char) linebuf.buf[i]);
linebuf.end = linebuf.print; linebuf.end = linebuf.print;
end_column = linebuf.pfx_end; end_column = linebuf.pfx_end;
} }
@ -413,9 +410,7 @@ pshift_all(VOID_PARAM)
* Return the printing width of the start (enter) sequence * Return the printing width of the start (enter) sequence
* for a given character attribute. * for a given character attribute.
*/ */
static int static int attr_swidth(int a)
attr_swidth(a)
int a;
{ {
int w = 0; int w = 0;
@ -437,9 +432,7 @@ attr_swidth(a)
* Return the printing width of the end (exit) sequence * Return the printing width of the end (exit) sequence
* for a given character attribute. * for a given character attribute.
*/ */
static int static int attr_ewidth(int a)
attr_ewidth(a)
int a;
{ {
int w = 0; int w = 0;
@ -463,12 +456,7 @@ attr_ewidth(a)
* Adding a character with a given attribute may cause an enter or exit * Adding a character with a given attribute may cause an enter or exit
* attribute sequence to be inserted, so this must be taken into account. * attribute sequence to be inserted, so this must be taken into account.
*/ */
public int public int pwidth(LWCHAR ch, int a, LWCHAR prev_ch, int prev_a)
pwidth(ch, a, prev_ch, prev_a)
LWCHAR ch;
int a;
LWCHAR prev_ch;
int prev_a;
{ {
int w; int w;
@ -530,8 +518,7 @@ pwidth(ch, a, prev_ch, prev_a)
/* /*
* Delete to the previous base character in the line buffer. * Delete to the previous base character in the line buffer.
*/ */
static int static int backc(void)
backc(VOID_PARAM)
{ {
LWCHAR ch; LWCHAR ch;
char *p; char *p;
@ -557,12 +544,28 @@ backc(VOID_PARAM)
return (1); return (1);
} }
/*
* Preserve the current position in the line buffer (for word wrapping).
*/
public void savec(void)
{
saved_line_end = linebuf.end;
saved_end_column = end_column;
}
/*
* Restore the position in the line buffer (start of line for word wrapping).
*/
public void loadc(void)
{
linebuf.end = saved_line_end;
end_column = saved_end_column;
}
/* /*
* Is a character the end of an ANSI escape sequence? * Is a character the end of an ANSI escape sequence?
*/ */
public int public int is_ansi_end(LWCHAR ch)
is_ansi_end(ch)
LWCHAR ch;
{ {
if (!is_ascii_char(ch)) if (!is_ascii_char(ch))
return (0); return (0);
@ -572,9 +575,7 @@ is_ansi_end(ch)
/* /*
* Can a char appear in an ANSI escape sequence, before the end char? * Can a char appear in an ANSI escape sequence, before the end char?
*/ */
public int public int is_ansi_middle(LWCHAR ch)
is_ansi_middle(ch)
LWCHAR ch;
{ {
if (!is_ascii_char(ch)) if (!is_ascii_char(ch))
return (0); return (0);
@ -587,11 +588,7 @@ is_ansi_middle(ch)
* Skip past an ANSI escape sequence. * Skip past an ANSI escape sequence.
* pp is initially positioned just after the CSI_START char. * pp is initially positioned just after the CSI_START char.
*/ */
public void public void skip_ansi(struct ansi_state *pansi, char **pp, constant char *limit)
skip_ansi(pansi, pp, limit)
struct ansi_state *pansi;
char **pp;
constant char *limit;
{ {
LWCHAR c; LWCHAR c;
do { do {
@ -604,9 +601,7 @@ skip_ansi(pansi, pp, limit)
* Determine if a character starts an ANSI escape sequence. * Determine if a character starts an ANSI escape sequence.
* If so, return an ansi_state struct; otherwise return NULL. * If so, return an ansi_state struct; otherwise return NULL.
*/ */
public struct ansi_state * public struct ansi_state * ansi_start(LWCHAR ch)
ansi_start(ch)
LWCHAR ch;
{ {
struct ansi_state *pansi; struct ansi_state *pansi;
@ -623,18 +618,15 @@ ansi_start(ch)
* Determine whether the next char in an ANSI escape sequence * Determine whether the next char in an ANSI escape sequence
* ends the sequence. * ends the sequence.
*/ */
public int public int ansi_step(struct ansi_state *pansi, LWCHAR ch)
ansi_step(pansi, ch)
struct ansi_state *pansi;
LWCHAR ch;
{ {
if (pansi->hlink) if (pansi->hlink)
{ {
/* Hyperlink ends with \7 or ESC-backslash. */ /* Hyperlink ends with \7 or ESC-backslash. */
if (ch == '\7') if (ch == '\7')
return ANSI_END; return ANSI_END;
if (pansi->prev_esc && ch == '\\') if (pansi->prev_esc)
return ANSI_END; return (ch == '\\') ? ANSI_END : ANSI_ERR;
pansi->prev_esc = (ch == ESC); pansi->prev_esc = (ch == ESC);
return ANSI_MID; return ANSI_MID;
} }
@ -662,9 +654,7 @@ ansi_step(pansi, ch)
/* /*
* Free an ansi_state structure. * Free an ansi_state structure.
*/ */
public void public void ansi_done(struct ansi_state *pansi)
ansi_done(pansi)
struct ansi_state *pansi;
{ {
free(pansi); free(pansi);
} }
@ -672,10 +662,7 @@ ansi_done(pansi)
/* /*
* Will w characters in attribute a fit on the screen? * Will w characters in attribute a fit on the screen?
*/ */
static int static int fits_on_screen(int w, int a)
fits_on_screen(w, a)
int w;
int a;
{ {
if (ctldisp == OPT_ON) if (ctldisp == OPT_ON)
/* We're not counting, so say that everything fits. */ /* We're not counting, so say that everything fits. */
@ -691,12 +678,7 @@ fits_on_screen(w, a)
if (store_char((ch),(a),(rep),(pos))) return (1); \ if (store_char((ch),(a),(rep),(pos))) return (1); \
} while (0) } while (0)
static int static int store_char(LWCHAR ch, int a, char *rep, POSITION pos)
store_char(ch, a, rep, pos)
LWCHAR ch;
int a;
char *rep;
POSITION pos;
{ {
int w; int w;
int i; int i;
@ -711,13 +693,13 @@ store_char(ch, a, rep, pos)
{ {
int matches; int matches;
int resend_last = 0; int resend_last = 0;
int hl_attr; int hl_attr = 0;
if (pos == NULL_POSITION) if (pos == NULL_POSITION)
{ {
/* Color the prompt unless it has ansi sequences in it. */ /* Color the prompt unless it has ansi sequences in it. */
hl_attr = ansi_in_line ? 0 : AT_STANDOUT|AT_COLOR_PROMPT; hl_attr = ansi_in_line ? 0 : AT_STANDOUT|AT_COLOR_PROMPT;
} else } else if (a != AT_ANSI)
{ {
hl_attr = is_hilited_attr(pos, pos+1, 0, &matches); hl_attr = is_hilited_attr(pos, pos+1, 0, &matches);
if (hl_attr == 0 && status_line) if (hl_attr == 0 && status_line)
@ -729,12 +711,9 @@ store_char(ch, a, rep, pos)
* This character should be highlighted. * This character should be highlighted.
* Override the attribute passed in. * Override the attribute passed in.
*/ */
if (a != AT_ANSI) a |= hl_attr;
{ if (highest_hilite != NULL_POSITION && pos != NULL_POSITION && pos > highest_hilite)
if (highest_hilite != NULL_POSITION && pos != NULL_POSITION && pos > highest_hilite) highest_hilite = pos;
highest_hilite = pos;
a |= hl_attr;
}
in_hilite = 1; in_hilite = 1;
} else } else
{ {
@ -782,23 +761,20 @@ store_char(ch, a, rep, pos)
{ {
replen = utf_len(rep[0]); replen = utf_len(rep[0]);
} }
if (linebuf.end + replen >= size_linebuf-6)
if (cshift == hshift)
{ {
/* if (line_pos == NULL_POSITION)
* Won't fit in line buffer. line_pos = pos;
* Try to expand it. if (shifted_ansi.end > 0)
*/ {
if (expand_linebuf()) /* Copy shifted ANSI sequences to beginning of line. */
return (1); for (i = 0; i < shifted_ansi.end; i++)
add_linebuf(shifted_ansi.data[i], AT_ANSI, 0);
xbuf_reset(&shifted_ansi);
}
} }
if (cshift == hshift && shifted_ansi.end > 0)
{
/* Copy shifted ANSI sequences to beginning of line. */
for (i = 0; i < shifted_ansi.end; i++)
add_linebuf(shifted_ansi.data[i], AT_ANSI, 0);
xbuf_reset(&shifted_ansi);
}
/* Add the char to the buf, even if we will left-shift it next. */ /* Add the char to the buf, even if we will left-shift it next. */
inc_end_column(w); inc_end_column(w);
for (i = 0; i < replen; i++) for (i = 0; i < replen; i++)
@ -808,7 +784,7 @@ store_char(ch, a, rep, pos)
{ {
/* We haven't left-shifted enough yet. */ /* We haven't left-shifted enough yet. */
if (a == AT_ANSI) if (a == AT_ANSI)
xbuf_add(&shifted_ansi, ch); /* Save ANSI attributes */ xbuf_add_byte(&shifted_ansi, (unsigned char) ch); /* Save ANSI attributes */
if (linebuf.end > linebuf.print) if (linebuf.end > linebuf.print)
{ {
/* Shift left enough to put last byte of this char at print-1. */ /* Shift left enough to put last byte of this char at print-1. */
@ -838,11 +814,7 @@ store_char(ch, a, rep, pos)
#define STORE_STRING(s,a,pos) \ #define STORE_STRING(s,a,pos) \
do { if (store_string((s),(a),(pos))) return (1); } while (0) do { if (store_string((s),(a),(pos))) return (1); } while (0)
static int static int store_string(char *s, int a, POSITION pos)
store_string(s, a, pos)
char *s;
int a;
POSITION pos;
{ {
if (!fits_on_screen(strlen(s), a)) if (!fits_on_screen(strlen(s), a))
return 1; return 1;
@ -858,10 +830,7 @@ store_string(s, a, pos)
#define STORE_TAB(a,pos) \ #define STORE_TAB(a,pos) \
do { if (store_tab((a),(pos))) return (1); } while (0) do { if (store_tab((a),(pos))) return (1); } while (0)
static int static int store_tab(int attr, POSITION pos)
store_tab(attr, pos)
int attr;
POSITION pos;
{ {
int to_tab = end_column - linebuf.pfx_end; int to_tab = end_column - linebuf.pfx_end;
@ -886,10 +855,7 @@ store_tab(attr, pos)
#define STORE_PRCHAR(c, pos) \ #define STORE_PRCHAR(c, pos) \
do { if (store_prchar((c), (pos))) return 1; } while (0) do { if (store_prchar((c), (pos))) return 1; } while (0)
static int static int store_prchar(LWCHAR c, POSITION pos)
store_prchar(c, pos)
LWCHAR c;
POSITION pos;
{ {
/* /*
* Convert to printable representation. * Convert to printable representation.
@ -898,9 +864,7 @@ store_prchar(c, pos)
return 0; return 0;
} }
static int static int flush_mbc_buf(POSITION pos)
flush_mbc_buf(pos)
POSITION pos;
{ {
int i; int i;
@ -915,10 +879,7 @@ flush_mbc_buf(pos)
* Expand tabs into spaces, handle underlining, boldfacing, etc. * Expand tabs into spaces, handle underlining, boldfacing, etc.
* Returns 0 if ok, 1 if couldn't fit in buffer. * Returns 0 if ok, 1 if couldn't fit in buffer.
*/ */
public int public int pappend(int c, POSITION pos)
pappend(c, pos)
int c;
POSITION pos;
{ {
int r; int r;
@ -935,7 +896,7 @@ pappend(c, pos)
pendc = '\0'; pendc = '\0';
} }
if (c == '\r' && bs_mode == BS_SPECIAL) if (c == '\r' && (proc_return == OPT_ON || (bs_mode == BS_SPECIAL && proc_return == OPT_OFF)))
{ {
if (mbc_buf_len > 0) /* utf_mode must be on. */ if (mbc_buf_len > 0) /* utf_mode must be on. */
{ {
@ -1008,11 +969,7 @@ pappend(c, pos)
return (r); return (r);
} }
static int static int store_control_char(LWCHAR ch, char *rep, POSITION pos)
store_control_char(ch, rep, pos)
LWCHAR ch;
char *rep;
POSITION pos;
{ {
if (ctldisp == OPT_ON) if (ctldisp == OPT_ON)
{ {
@ -1026,11 +983,7 @@ store_control_char(ch, rep, pos)
return (0); return (0);
} }
static int static int store_ansi(LWCHAR ch, char *rep, POSITION pos)
store_ansi(ch, rep, pos)
LWCHAR ch;
char *rep;
POSITION pos;
{ {
switch (ansi_step(line_ansi, ch)) switch (ansi_step(line_ansi, ch))
{ {
@ -1038,13 +991,13 @@ store_ansi(ch, rep, pos)
STORE_CHAR(ch, AT_ANSI, rep, pos); STORE_CHAR(ch, AT_ANSI, rep, pos);
if (line_ansi->hlink) if (line_ansi->hlink)
hlink_in_line = 1; hlink_in_line = 1;
xbuf_add(&last_ansi, ch); xbuf_add_byte(&last_ansi, (unsigned char) ch);
break; break;
case ANSI_END: case ANSI_END:
STORE_CHAR(ch, AT_ANSI, rep, pos); STORE_CHAR(ch, AT_ANSI, rep, pos);
ansi_done(line_ansi); ansi_done(line_ansi);
line_ansi = NULL; line_ansi = NULL;
xbuf_add(&last_ansi, ch); xbuf_add_byte(&last_ansi, (unsigned char) ch);
xbuf_set(&last_ansis[curr_last_ansi], &last_ansi); xbuf_set(&last_ansis[curr_last_ansi], &last_ansi);
xbuf_reset(&last_ansi); xbuf_reset(&last_ansi);
curr_last_ansi = (curr_last_ansi + 1) % NUM_LAST_ANSIS; curr_last_ansi = (curr_last_ansi + 1) % NUM_LAST_ANSIS;
@ -1052,7 +1005,7 @@ store_ansi(ch, rep, pos)
case ANSI_ERR: case ANSI_ERR:
{ {
/* Remove whole unrecognized sequence. */ /* Remove whole unrecognized sequence. */
char *start = (cshift < hshift) ? shifted_ansi.data : linebuf.buf; char *start = (cshift < hshift) ? xbuf_char_data(&shifted_ansi): linebuf.buf;
int *end = (cshift < hshift) ? &shifted_ansi.end : &linebuf.end; int *end = (cshift < hshift) ? &shifted_ansi.end : &linebuf.end;
char *p = start + *end; char *p = start + *end;
LWCHAR bch; LWCHAR bch;
@ -1069,32 +1022,25 @@ store_ansi(ch, rep, pos)
return (0); return (0);
} }
static int static int store_bs(LWCHAR ch, char *rep, POSITION pos)
store_bs(ch, rep, pos)
LWCHAR ch;
char *rep;
POSITION pos;
{ {
if (bs_mode == BS_CONTROL) if (proc_backspace == OPT_ONPLUS || (bs_mode == BS_CONTROL && proc_backspace == OPT_OFF))
return store_control_char(ch, rep, pos); return store_control_char(ch, rep, pos);
if (linebuf.end > 0 && if (linebuf.end > 0 &&
((linebuf.end <= linebuf.print && linebuf.buf[linebuf.end-1] == '\0') || ((linebuf.end <= linebuf.print && linebuf.buf[linebuf.end-1] == '\0') ||
(linebuf.end > 0 && linebuf.attr[linebuf.end - 1] & (AT_ANSI|AT_BINARY)))) (linebuf.end > 0 && linebuf.attr[linebuf.end - 1] & (AT_ANSI|AT_BINARY))))
STORE_PRCHAR('\b', pos); STORE_PRCHAR('\b', pos);
else if (bs_mode == BS_NORMAL) else if (proc_backspace == OPT_OFF && bs_mode == BS_NORMAL)
STORE_CHAR(ch, AT_NORMAL, NULL, pos); STORE_CHAR(ch, AT_NORMAL, NULL, pos);
else if (bs_mode == BS_SPECIAL) else if (proc_backspace == OPT_ON || (bs_mode == BS_SPECIAL && proc_backspace == OPT_OFF))
overstrike = backc(); overstrike = backc();
return 0; return 0;
} }
static int static int do_append(LWCHAR ch, char *rep, POSITION pos)
do_append(ch, rep, pos)
LWCHAR ch;
char *rep;
POSITION pos;
{ {
int a = AT_NORMAL; int a = AT_NORMAL;
int in_overstrike = overstrike;
if (ctldisp == OPT_ONPLUS && line_ansi == NULL) if (ctldisp == OPT_ONPLUS && line_ansi == NULL)
{ {
@ -1103,13 +1049,14 @@ do_append(ch, rep, pos)
ansi_in_line = 1; ansi_in_line = 1;
} }
overstrike = 0;
if (line_ansi != NULL) if (line_ansi != NULL)
return store_ansi(ch, rep, pos); return store_ansi(ch, rep, pos);
if (ch == '\b') if (ch == '\b')
return store_bs(ch, rep, pos); return store_bs(ch, rep, pos);
if (overstrike > 0) if (in_overstrike > 0)
{ {
/* /*
* Overstrike the character at the current position * Overstrike the character at the current position
@ -1158,7 +1105,7 @@ do_append(ch, rep, pos)
a |= AT_UNDERLINE; a |= AT_UNDERLINE;
} }
/* Else we replace prev_ch, but we keep its attributes. */ /* Else we replace prev_ch, but we keep its attributes. */
} else if (overstrike < 0) } else if (in_overstrike < 0)
{ {
if ( is_composing_char(ch) if ( is_composing_char(ch)
|| is_combining_char(get_wchar(&linebuf.buf[linebuf.end]), ch)) || is_combining_char(get_wchar(&linebuf.buf[linebuf.end]), ch))
@ -1173,15 +1120,9 @@ do_append(ch, rep, pos)
/* /*
* Expand a tab into spaces. * Expand a tab into spaces.
*/ */
switch (bs_mode) if (proc_tab == OPT_ONPLUS || (bs_mode == BS_CONTROL && proc_tab == OPT_OFF))
{
case BS_CONTROL:
return store_control_char(ch, rep, pos); return store_control_char(ch, rep, pos);
case BS_NORMAL: STORE_TAB(a, pos);
case BS_SPECIAL:
STORE_TAB(a, pos);
break;
}
return (0); return (0);
} }
if ((!utf_mode || is_ascii_char(ch)) && control_char((char)ch)) if ((!utf_mode || is_ascii_char(ch)) && control_char((char)ch))
@ -1200,8 +1141,7 @@ do_append(ch, rep, pos)
/* /*
* *
*/ */
public int public int pflushmbc(void)
pflushmbc(VOID_PARAM)
{ {
int r = 0; int r = 0;
@ -1217,8 +1157,7 @@ pflushmbc(VOID_PARAM)
/* /*
* Switch to normal attribute at end of line. * Switch to normal attribute at end of line.
*/ */
static void static void add_attr_normal(void)
add_attr_normal(VOID_PARAM)
{ {
if (ctldisp != OPT_ONPLUS || !is_ansi_end('m')) if (ctldisp != OPT_ONPLUS || !is_ansi_end('m'))
return; return;
@ -1230,11 +1169,7 @@ add_attr_normal(VOID_PARAM)
/* /*
* Terminate the line in the line buffer. * Terminate the line in the line buffer.
*/ */
public void public void pdone(int endline, int chopped, int forw)
pdone(endline, chopped, forw)
int endline;
int chopped;
int forw;
{ {
(void) pflushmbc(); (void) pflushmbc();
@ -1326,23 +1261,19 @@ pdone(endline, chopped, forw)
/* /*
* Set an attribute on each char of the line in the line buffer. * Set an attribute on each char of the line in the line buffer.
*/ */
public void public void set_attr_line(int a)
set_attr_line(a)
int a;
{ {
int i; int i;
for (i = linebuf.print; i < linebuf.end; i++) for (i = linebuf.print; i < linebuf.end; i++)
linebuf.attr[i] |= a; if ((linebuf.attr[i] & AT_COLOR) == 0 || (a & AT_COLOR) == 0)
linebuf.attr[i] |= a;
} }
/* /*
* Set the char to be displayed in the status column. * Set the char to be displayed in the status column.
*/ */
public void public void set_status_col(char c, int attr)
set_status_col(c, attr)
int c;
int attr;
{ {
set_pfx(0, c, attr); set_pfx(0, c, attr);
} }
@ -1352,10 +1283,7 @@ set_status_col(c, attr)
* Return the character as the function return value, * Return the character as the function return value,
* and the character attribute in *ap. * and the character attribute in *ap.
*/ */
public int public int gline(int i, int *ap)
gline(i, ap)
int i;
int *ap;
{ {
if (is_null_line) if (is_null_line)
{ {
@ -1390,8 +1318,7 @@ gline(i, ap)
/* /*
* Indicate that there is no current line. * Indicate that there is no current line.
*/ */
public void public void null_line(void)
null_line(VOID_PARAM)
{ {
is_null_line = 1; is_null_line = 1;
cshift = 0; cshift = 0;
@ -1402,11 +1329,7 @@ null_line(VOID_PARAM)
* lines which are not split for screen width. * lines which are not split for screen width.
* {{ This is supposed to be more efficient than forw_line(). }} * {{ This is supposed to be more efficient than forw_line(). }}
*/ */
public POSITION public POSITION forw_raw_line(POSITION curr_pos, char **linep, int *line_lenp)
forw_raw_line(curr_pos, linep, line_lenp)
POSITION curr_pos;
char **linep;
int *line_lenp;
{ {
int n; int n;
int c; int c;
@ -1451,11 +1374,7 @@ forw_raw_line(curr_pos, linep, line_lenp)
* Analogous to back_line(), but deals with "raw lines". * Analogous to back_line(), but deals with "raw lines".
* {{ This is supposed to be more efficient than back_line(). }} * {{ This is supposed to be more efficient than back_line(). }}
*/ */
public POSITION public POSITION back_raw_line(POSITION curr_pos, char **linep, int *line_lenp)
back_raw_line(curr_pos, linep, line_lenp)
POSITION curr_pos;
char **linep;
int *line_lenp;
{ {
int n; int n;
int c; int c;
@ -1521,12 +1440,43 @@ back_raw_line(curr_pos, linep, line_lenp)
return (new_pos); return (new_pos);
} }
/*
* Skip cols printable columns at the start of line.
* Return number of bytes skipped.
*/
public int skip_columns(int cols, char **linep, int *line_lenp)
{
char *line = *linep;
char *eline = line + *line_lenp;
LWCHAR pch = 0;
int bytes;
while (cols > 0 && line < eline)
{
LWCHAR ch = step_char(&line, +1, eline);
struct ansi_state *pansi = ansi_start(ch);
if (pansi != NULL)
{
skip_ansi(pansi, &line, eline);
ansi_done(pansi);
pch = 0;
} else
{
int w = pwidth(ch, 0, pch, 0);
cols -= w;
pch = ch;
}
}
bytes = line - *linep;
*linep = line;
*line_lenp -= bytes;
return (bytes);
}
/* /*
* Append a string to the line buffer. * Append a string to the line buffer.
*/ */
static int static int pappstr(constant char *str)
pappstr(str)
constant char *str;
{ {
while (*str != '\0') while (*str != '\0')
{ {
@ -1542,9 +1492,7 @@ pappstr(str)
* If the string is too long to fit on the screen, * If the string is too long to fit on the screen,
* truncate the beginning of the string to fit. * truncate the beginning of the string to fit.
*/ */
public void public void load_line(constant char *str)
load_line(str)
constant char *str;
{ {
int save_hshift = hshift; int save_hshift = hshift;
@ -1568,8 +1516,7 @@ load_line(str)
/* /*
* Find the shift necessary to show the end of the longest displayed line. * Find the shift necessary to show the end of the longest displayed line.
*/ */
public int public int rrshift(void)
rrshift(VOID_PARAM)
{ {
POSITION pos; POSITION pos;
int save_width; int save_width;
@ -1594,65 +1541,53 @@ rrshift(VOID_PARAM)
/* /*
* Get the color_map index associated with a given attribute. * Get the color_map index associated with a given attribute.
*/ */
static int static int lookup_color_index(int attr)
color_index(attr)
int attr;
{ {
if (use_color) int cx;
{ for (cx = 0; cx < sizeof(color_map)/sizeof(*color_map); cx++)
switch (attr & AT_COLOR) if (color_map[cx].attr == attr)
{ return cx;
case AT_COLOR_ATTN: return 0; return -1;
case AT_COLOR_BIN: return 1; }
case AT_COLOR_CTRL: return 2;
case AT_COLOR_ERROR: return 3; static int color_index(int attr)
case AT_COLOR_LINENUM: return 4; {
case AT_COLOR_MARK: return 5; if (use_color && (attr & AT_COLOR))
case AT_COLOR_PROMPT: return 6; return lookup_color_index(attr & AT_COLOR);
case AT_COLOR_RSCROLL: return 7;
case AT_COLOR_SEARCH: return 8;
case AT_COLOR_HEADER: return 9;
}
}
if (attr & AT_UNDERLINE) if (attr & AT_UNDERLINE)
return 10; return lookup_color_index(AT_UNDERLINE);
if (attr & AT_BOLD) if (attr & AT_BOLD)
return 11; return lookup_color_index(AT_BOLD);
if (attr & AT_BLINK) if (attr & AT_BLINK)
return 12; return lookup_color_index(AT_BLINK);
if (attr & AT_STANDOUT) if (attr & AT_STANDOUT)
return 13; return lookup_color_index(AT_STANDOUT);
return -1; return -1;
} }
/* /*
* Set the color string to use for a given attribute. * Set the color string to use for a given attribute.
*/ */
public int public int set_color_map(int attr, char *colorstr)
set_color_map(attr, colorstr)
int attr;
char *colorstr;
{ {
int cx = color_index(attr); int cx = color_index(attr);
if (cx < 0) if (cx < 0)
return -1; return -1;
if (strlen(colorstr)+1 > sizeof(color_map[cx])) if (strlen(colorstr)+1 > sizeof(color_map[cx].color))
return -1; return -1;
if (*colorstr != '\0' && parse_color(colorstr, NULL, NULL) == CT_NULL) if (*colorstr != '\0' && parse_color(colorstr, NULL, NULL) == CT_NULL)
return -1; return -1;
strcpy(color_map[cx], colorstr); strcpy(color_map[cx].color, colorstr);
return 0; return 0;
} }
/* /*
* Get the color string to use for a given attribute. * Get the color string to use for a given attribute.
*/ */
public char * public char * get_color_map(int attr)
get_color_map(attr)
int attr;
{ {
int cx = color_index(attr); int cx = color_index(attr);
if (cx < 0) if (cx < 0)
return NULL; return NULL;
return color_map[cx]; return color_map[cx].color;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -62,7 +62,8 @@ struct linenum_info
static struct linenum_info anchor; /* Anchor of the list */ static struct linenum_info anchor; /* Anchor of the list */
static struct linenum_info *freelist; /* Anchor of the unused entries */ static struct linenum_info *freelist; /* Anchor of the unused entries */
static struct linenum_info pool[NPOOL]; /* The pool itself */ static struct linenum_info pool[NPOOL]; /* The pool itself */
static struct linenum_info *spare; /* We always keep one spare entry */ static struct linenum_info *spare; /* We always keep one spare entry */
public int scanning_eof = FALSE;
extern int linenums; extern int linenums;
extern int sigs; extern int sigs;
@ -74,8 +75,7 @@ extern int nonum_headers;
/* /*
* Initialize the line number structures. * Initialize the line number structures.
*/ */
public void public void clr_linenum(void)
clr_linenum(VOID_PARAM)
{ {
struct linenum_info *p; struct linenum_info *p;
@ -102,9 +102,7 @@ clr_linenum(VOID_PARAM)
/* /*
* Calculate the gap for an entry. * Calculate the gap for an entry.
*/ */
static void static void calcgap(struct linenum_info *p)
calcgap(p)
struct linenum_info *p;
{ {
/* /*
* Don't bother to compute a gap for the anchor. * Don't bother to compute a gap for the anchor.
@ -122,10 +120,7 @@ calcgap(p)
* The specified position (pos) should be the file position of the * The specified position (pos) should be the file position of the
* FIRST character in the specified line. * FIRST character in the specified line.
*/ */
public void public void add_lnum(LINENUM linenum, POSITION pos)
add_lnum(linenum, pos)
LINENUM linenum;
POSITION pos;
{ {
struct linenum_info *p; struct linenum_info *p;
struct linenum_info *new; struct linenum_info *new;
@ -210,8 +205,7 @@ add_lnum(linenum, pos)
* If we get stuck in a long loop trying to figure out the * If we get stuck in a long loop trying to figure out the
* line number, print a message to tell the user what we're doing. * line number, print a message to tell the user what we're doing.
*/ */
static void static void longloopmessage(void)
longloopmessage(VOID_PARAM)
{ {
ierror("Calculating line numbers", NULL_PARG); ierror("Calculating line numbers", NULL_PARG);
} }
@ -221,8 +215,7 @@ static int loopcount;
static time_type startime; static time_type startime;
#endif #endif
static void static void longish(void)
longish(VOID_PARAM)
{ {
#if HAVE_TIME #if HAVE_TIME
if (loopcount >= 0 && ++loopcount > 100) if (loopcount >= 0 && ++loopcount > 100)
@ -247,8 +240,7 @@ longish(VOID_PARAM)
* Turn off line numbers because the user has interrupted * Turn off line numbers because the user has interrupted
* a lengthy line number calculation. * a lengthy line number calculation.
*/ */
static void static void abort_long(void)
abort_long(VOID_PARAM)
{ {
if (loopcount >= 0) if (loopcount >= 0)
return; return;
@ -265,9 +257,7 @@ abort_long(VOID_PARAM)
* Find the line number associated with a given position. * Find the line number associated with a given position.
* Return 0 if we can't figure it out. * Return 0 if we can't figure it out.
*/ */
public LINENUM public LINENUM find_linenum(POSITION pos)
find_linenum(pos)
POSITION pos;
{ {
struct linenum_info *p; struct linenum_info *p;
LINENUM linenum; LINENUM linenum;
@ -379,9 +369,7 @@ find_linenum(pos)
* Find the position of a given line number. * Find the position of a given line number.
* Return NULL_POSITION if we can't figure it out. * Return NULL_POSITION if we can't figure it out.
*/ */
public POSITION public POSITION find_pos(LINENUM linenum)
find_pos(linenum)
LINENUM linenum;
{ {
struct linenum_info *p; struct linenum_info *p;
POSITION cpos; POSITION cpos;
@ -452,9 +440,7 @@ find_pos(linenum)
* The argument "where" tells which line is to be considered * The argument "where" tells which line is to be considered
* the "current" line (e.g. TOP, BOTTOM, MIDDLE, etc). * the "current" line (e.g. TOP, BOTTOM, MIDDLE, etc).
*/ */
public LINENUM public LINENUM currline(int where)
currline(where)
int where;
{ {
POSITION pos; POSITION pos;
POSITION len; POSITION len;
@ -475,15 +461,19 @@ currline(where)
/* /*
* Scan entire file, counting line numbers. * Scan entire file, counting line numbers.
*/ */
public void public void scan_eof(void)
scan_eof(VOID_PARAM)
{ {
POSITION pos = 0; POSITION pos = ch_zero();
LINENUM linenum = 0; LINENUM linenum = 0;
if (ch_seek(0)) if (ch_seek(0))
return; return;
ierror("Determining length of file", NULL_PARG); ierror("Determining length of file", NULL_PARG);
/*
* scanning_eof prevents the "Waiting for data" message from
* overwriting "Determining length of file".
*/
scanning_eof = TRUE;
while (pos != NULL_POSITION) while (pos != NULL_POSITION)
{ {
/* For efficiency, only add one every 256 line numbers. */ /* For efficiency, only add one every 256 line numbers. */
@ -493,15 +483,14 @@ scan_eof(VOID_PARAM)
if (ABORT_SIGS()) if (ABORT_SIGS())
break; break;
} }
scanning_eof = FALSE;
} }
/* /*
* Return a line number adjusted for display * Return a line number adjusted for display
* (handles the --no-number-headers option). * (handles the --no-number-headers option).
*/ */
public LINENUM public LINENUM vlinenum(LINENUM linenum)
vlinenum(linenum)
LINENUM linenum;
{ {
if (nonum_headers) if (nonum_headers)
linenum = (linenum < header_lines) ? 0 : linenum - header_lines; linenum = (linenum < header_lines) ? 0 : linenum - header_lines;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -42,10 +42,7 @@ extern IFILE curr_ifile;
* Pass the specified command to a shell to be executed. * Pass the specified command to a shell to be executed.
* Like plain "system()", but handles resetting terminal modes, etc. * Like plain "system()", but handles resetting terminal modes, etc.
*/ */
public void public void lsystem(char *cmd, char *donemsg)
lsystem(cmd, donemsg)
char *cmd;
char *donemsg;
{ {
int inp; int inp;
#if HAVE_SHELL #if HAVE_SHELL
@ -251,10 +248,7 @@ lsystem(cmd, donemsg)
* If the mark is on the current screen, or if the mark is ".", * If the mark is on the current screen, or if the mark is ".",
* the whole current screen is piped. * the whole current screen is piped.
*/ */
public int public int pipe_mark(int c, char *cmd)
pipe_mark(c, cmd)
int c;
char *cmd;
{ {
POSITION mpos, tpos, bpos; POSITION mpos, tpos, bpos;
@ -285,11 +279,7 @@ pipe_mark(c, cmd)
* Create a pipe to the given shell command. * Create a pipe to the given shell command.
* Feed it the file contents between the positions spos and epos. * Feed it the file contents between the positions spos and epos.
*/ */
public int public int pipe_data(char *cmd, POSITION spos, POSITION epos)
pipe_data(cmd, spos, epos)
char *cmd;
POSITION spos;
POSITION epos;
{ {
FILE *f; FILE *f;
int c; int c;

View File

@ -1,6 +1,6 @@
/* $FreeBSD$ */ /* $FreeBSD$ */
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -69,10 +69,7 @@ extern int first_time;
/* /*
* Entry point. * Entry point.
*/ */
int int main(int argc, char *argv[])
main(argc, argv)
int argc;
char *argv[];
{ {
IFILE ifile; IFILE ifile;
char *s; char *s;
@ -123,6 +120,7 @@ main(argc, argv)
is_tty = isatty(1); is_tty = isatty(1);
init_mark(); init_mark();
init_cmds(); init_cmds();
init_poll();
get_term(); get_term();
init_charset(); init_charset();
init_line(); init_line();
@ -320,9 +318,7 @@ main(argc, argv)
* Copy a string to a "safe" place * Copy a string to a "safe" place
* (that is, to a buffer allocated by calloc). * (that is, to a buffer allocated by calloc).
*/ */
public char * public char * save(constant char *s)
save(s)
constant char *s;
{ {
char *p; char *p;
@ -331,32 +327,30 @@ save(s)
return (p); return (p);
} }
public void out_of_memory(void)
{
error("Cannot allocate memory", NULL_PARG);
quit(QUIT_ERROR);
}
/* /*
* Allocate memory. * Allocate memory.
* Like calloc(), but never returns an error (NULL). * Like calloc(), but never returns an error (NULL).
*/ */
public VOID_POINTER public void * ecalloc(int count, unsigned int size)
ecalloc(count, size)
int count;
unsigned int size;
{ {
VOID_POINTER p; void * p;
p = (VOID_POINTER) calloc(count, size); p = (void *) calloc(count, size);
if (p != NULL) if (p == NULL)
return (p); out_of_memory();
error("Cannot allocate memory", NULL_PARG); return p;
quit(QUIT_ERROR);
/*NOTREACHED*/
return (NULL);
} }
/* /*
* Skip leading spaces in a string. * Skip leading spaces in a string.
*/ */
public char * public char * skipsp(char *s)
skipsp(s)
char *s;
{ {
while (*s == ' ' || *s == '\t') while (*s == ' ' || *s == '\t')
s++; s++;
@ -368,11 +362,7 @@ skipsp(s)
* If uppercase is true, the first string must begin with an uppercase * If uppercase is true, the first string must begin with an uppercase
* character; the remainder of the first string may be either case. * character; the remainder of the first string may be either case.
*/ */
public int public int sprefix(char *ps, char *s, int uppercase)
sprefix(ps, s, uppercase)
char *ps;
char *s;
int uppercase;
{ {
int c; int c;
int sc; int sc;
@ -401,9 +391,7 @@ sprefix(ps, s, uppercase)
/* /*
* Exit the program. * Exit the program.
*/ */
public void public void quit(int status)
quit(status)
int status;
{ {
static int save_status; static int save_status;
@ -415,10 +403,8 @@ quit(status)
status = save_status; status = save_status;
else else
save_status = status; save_status = status;
#if LESSTEST
rstat('Q');
#endif /*LESSTEST*/
quitting = 1; quitting = 1;
check_altpipe_error();
if (interactive()) if (interactive())
clear_bot(); clear_bot();
deinit(); deinit();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -49,12 +49,7 @@ public int marks_modified = 0;
/* /*
* Initialize a mark struct. * Initialize a mark struct.
*/ */
static void static void cmark(struct mark *m, IFILE ifile, POSITION pos, int ln)
cmark(m, ifile, pos, ln)
struct mark *m;
IFILE ifile;
POSITION pos;
int ln;
{ {
m->m_ifile = ifile; m->m_ifile = ifile;
m->m_scrpos.pos = pos; m->m_scrpos.pos = pos;
@ -68,8 +63,7 @@ cmark(m, ifile, pos, ln)
/* /*
* Initialize the mark table to show no marks are set. * Initialize the mark table to show no marks are set.
*/ */
public void public void init_mark(void)
init_mark(VOID_PARAM)
{ {
int i; int i;
@ -89,10 +83,7 @@ init_mark(VOID_PARAM)
/* /*
* Set m_ifile and clear m_filename. * Set m_ifile and clear m_filename.
*/ */
static void static void mark_set_ifile(struct mark *m, IFILE ifile)
mark_set_ifile(m, ifile)
struct mark *m;
IFILE ifile;
{ {
m->m_ifile = ifile; m->m_ifile = ifile;
/* With m_ifile set, m_filename is no longer needed. */ /* With m_ifile set, m_filename is no longer needed. */
@ -103,9 +94,7 @@ mark_set_ifile(m, ifile)
/* /*
* Populate the m_ifile member of a mark struct from m_filename. * Populate the m_ifile member of a mark struct from m_filename.
*/ */
static void static void mark_get_ifile(struct mark *m)
mark_get_ifile(m)
struct mark *m;
{ {
if (m->m_ifile != NULL_IFILE) if (m->m_ifile != NULL_IFILE)
return; /* m_ifile is already set */ return; /* m_ifile is already set */
@ -115,9 +104,7 @@ mark_get_ifile(m)
/* /*
* Return the user mark struct identified by a character. * Return the user mark struct identified by a character.
*/ */
static struct mark * static struct mark * getumark(LWCHAR c)
getumark(c)
int c;
{ {
PARG parg; PARG parg;
if (c >= 'a' && c <= 'z') if (c >= 'a' && c <= 'z')
@ -138,9 +125,7 @@ getumark(c)
* The mark struct may either be in the mark table (user mark) * The mark struct may either be in the mark table (user mark)
* or may be constructed on the fly for certain characters like ^, $. * or may be constructed on the fly for certain characters like ^, $.
*/ */
static struct mark * static struct mark * getmark(LWCHAR c)
getmark(c)
int c;
{ {
struct mark *m; struct mark *m;
static struct mark sm; static struct mark sm;
@ -200,9 +185,7 @@ getmark(c)
/* /*
* Is a mark letter invalid? * Is a mark letter invalid?
*/ */
public int public int badmark(LWCHAR c)
badmark(c)
int c;
{ {
return (getmark(c) == NULL); return (getmark(c) == NULL);
} }
@ -210,10 +193,7 @@ badmark(c)
/* /*
* Set a user-defined mark. * Set a user-defined mark.
*/ */
public void public void setmark(LWCHAR c, int where)
setmark(c, where)
int c;
int where;
{ {
struct mark *m; struct mark *m;
struct scrpos scrpos; struct scrpos scrpos;
@ -234,9 +214,7 @@ setmark(c, where)
/* /*
* Clear a user-defined mark. * Clear a user-defined mark.
*/ */
public void public void clrmark(LWCHAR c)
clrmark(c)
int c;
{ {
struct mark *m; struct mark *m;
@ -255,8 +233,7 @@ clrmark(c)
/* /*
* Set lmark (the mark named by the apostrophe). * Set lmark (the mark named by the apostrophe).
*/ */
public void public void lastmark(void)
lastmark(VOID_PARAM)
{ {
struct scrpos scrpos; struct scrpos scrpos;
@ -272,9 +249,7 @@ lastmark(VOID_PARAM)
/* /*
* Go to a mark. * Go to a mark.
*/ */
public void public void gomark(LWCHAR c)
gomark(c)
int c;
{ {
struct mark *m; struct mark *m;
struct scrpos scrpos; struct scrpos scrpos;
@ -315,9 +290,7 @@ gomark(c)
* is associated with, but this doesn't matter much, * is associated with, but this doesn't matter much,
* because it's always the first non-blank line on the screen. * because it's always the first non-blank line on the screen.
*/ */
public POSITION public POSITION markpos(LWCHAR c)
markpos(c)
int c;
{ {
struct mark *m; struct mark *m;
@ -336,9 +309,7 @@ markpos(c)
/* /*
* Return the mark associated with a given position, if any. * Return the mark associated with a given position, if any.
*/ */
public char public char posmark(POSITION pos)
posmark(pos)
POSITION pos;
{ {
int i; int i;
@ -358,9 +329,7 @@ posmark(pos)
/* /*
* Clear the marks associated with a specified ifile. * Clear the marks associated with a specified ifile.
*/ */
public void public void unmark(IFILE ifile)
unmark(ifile)
IFILE ifile;
{ {
int i; int i;
@ -373,9 +342,7 @@ unmark(ifile)
* Check if any marks refer to a specified ifile vi m_filename * Check if any marks refer to a specified ifile vi m_filename
* rather than m_ifile. * rather than m_ifile.
*/ */
public void public void mark_check_ifile(IFILE ifile)
mark_check_ifile(ifile)
IFILE ifile;
{ {
int i; int i;
char *filename = get_real_filename(ifile); char *filename = get_real_filename(ifile);
@ -399,10 +366,7 @@ mark_check_ifile(ifile)
/* /*
* Save marks to history file. * Save marks to history file.
*/ */
public void public void save_marks(FILE *fout, char *hdr)
save_marks(fout, hdr)
FILE *fout;
char *hdr;
{ {
int i; int i;
@ -417,7 +381,7 @@ save_marks(fout, hdr)
char pos_str[INT_STRLEN_BOUND(m->m_scrpos.pos) + 2]; char pos_str[INT_STRLEN_BOUND(m->m_scrpos.pos) + 2];
if (m->m_scrpos.pos == NULL_POSITION) if (m->m_scrpos.pos == NULL_POSITION)
continue; continue;
postoa(m->m_scrpos.pos, pos_str); postoa(m->m_scrpos.pos, pos_str, 10);
filename = m->m_filename; filename = m->m_filename;
if (filename == NULL) if (filename == NULL)
filename = get_real_filename(m->m_ifile); filename = get_real_filename(m->m_ifile);
@ -430,9 +394,7 @@ save_marks(fout, hdr)
/* /*
* Restore one mark from the history file. * Restore one mark from the history file.
*/ */
public void public void restore_mark(char *line)
restore_mark(line)
char *line;
{ {
struct mark *m; struct mark *m;
int ln; int ln;
@ -446,13 +408,17 @@ restore_mark(line)
if (m == NULL) if (m == NULL)
return; return;
skip_whitespace; skip_whitespace;
ln = lstrtoi(line, &line); ln = lstrtoi(line, &line, 10);
if (ln < 0)
return;
if (ln < 1) if (ln < 1)
ln = 1; ln = 1;
if (ln > sc_height) if (ln > sc_height)
ln = sc_height; ln = sc_height;
skip_whitespace; skip_whitespace;
pos = lstrtopos(line, &line); pos = lstrtopos(line, &line, 10);
if (pos < 0)
return;
skip_whitespace; skip_whitespace;
cmark(m, NULL_IFILE, pos, ln); cmark(m, NULL_IFILE, pos, ln);
m->m_filename = save(line); m->m_filename = save(line);

View File

@ -1,4 +1,4 @@
#! /usr/bin/perl #!/usr/bin/env perl
use strict; use strict;
my $USAGE = <<__EOF__; my $USAGE = <<__EOF__;
@ -57,6 +57,7 @@ sub main {
print "/* Generated by \"$0 $args\" on $date */\n"; print "/* Generated by \"$0 $args\" on $date */\n";
my $last_code = 0; my $last_code = 0;
my $start_range = 0;
while (<>) { while (<>) {
chomp; chomp;
s/#.*//; s/#.*//;
@ -70,6 +71,18 @@ sub main {
} else { } else {
$lo_code = $hi_code = hex $codes; $lo_code = $hi_code = hex $codes;
} }
if ($fields[1] =~ /, First>$/) {
die "invalid Unicode data: First with range" if $hi_code != $lo_code;
$start_range = $lo_code;
next;
}
if ($fields[1] =~ /, Last>$/) {
die "invalid Unicode data: Last without First" if not $start_range;
$lo_code = $start_range;
$start_range = 0;
} elsif ($start_range) {
die "invalid Unicode data: First without Last";
}
my $type = $fields[$type_field]; my $type = $fields[$type_field];
$type =~ s/\s//g; $type =~ s/\s//g;
for ($last_code = $lo_code; $last_code <= $hi_code; ++$last_code) { for ($last_code = $lo_code; $last_code <= $hi_code; ++$last_code) {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -63,6 +63,10 @@ extern int header_lines;
extern int header_cols; extern int header_cols;
extern int def_search_type; extern int def_search_type;
extern int chopline; extern int chopline;
extern int tabstops[];
extern int ntabstops;
extern int tabdefault;
extern char intr_char;
#if LOGFILE #if LOGFILE
extern char *namelogfile; extern char *namelogfile;
extern int force_logfile; extern int force_logfile;
@ -75,7 +79,6 @@ extern char ztags[];
#endif #endif
#if LESSTEST #if LESSTEST
extern char *ttyin_name; extern char *ttyin_name;
extern int rstat_file;
#endif /*LESSTEST*/ #endif /*LESSTEST*/
#if MSDOS_COMPILER #if MSDOS_COMPILER
extern int nm_fg_color, nm_bg_color; extern int nm_fg_color, nm_bg_color;
@ -96,10 +99,7 @@ extern int sgr_mode;
/* /*
* Handler for -o option. * Handler for -o option.
*/ */
public void public void opt_o(int type, char *s)
opt_o(type, s)
int type;
char *s;
{ {
PARG parg; PARG parg;
char *filename; char *filename;
@ -149,10 +149,7 @@ opt_o(type, s)
/* /*
* Handler for -O option. * Handler for -O option.
*/ */
public void public void opt__O(int type, char *s)
opt__O(type, s)
int type;
char *s;
{ {
force_logfile = TRUE; force_logfile = TRUE;
opt_o(type, s); opt_o(type, s);
@ -162,10 +159,7 @@ opt__O(type, s)
/* /*
* Handlers for -j option. * Handlers for -j option.
*/ */
public void public void opt_j(int type, char *s)
opt_j(type, s)
int type;
char *s;
{ {
PARG parg; PARG parg;
int len; int len;
@ -215,21 +209,17 @@ opt_j(type, s)
} }
} }
public void public void calc_jump_sline(void)
calc_jump_sline(VOID_PARAM)
{ {
if (jump_sline_fraction < 0) if (jump_sline_fraction < 0)
return; return;
jump_sline = sc_height * jump_sline_fraction / NUM_FRAC_DENOM; jump_sline = muldiv(sc_height, jump_sline_fraction, NUM_FRAC_DENOM);
} }
/* /*
* Handlers for -# option. * Handlers for -# option.
*/ */
public void public void opt_shift(int type, char *s)
opt_shift(type, s)
int type;
char *s;
{ {
PARG parg; PARG parg;
int len; int len;
@ -279,19 +269,15 @@ opt_shift(type, s)
} }
} }
public void public void calc_shift_count(void)
calc_shift_count(VOID_PARAM)
{ {
if (shift_count_fraction < 0) if (shift_count_fraction < 0)
return; return;
shift_count = sc_width * shift_count_fraction / NUM_FRAC_DENOM; shift_count = muldiv(sc_width, shift_count_fraction, NUM_FRAC_DENOM);
} }
#if USERFILE #if USERFILE
public void public void opt_k(int type, char *s)
opt_k(type, s)
int type;
char *s;
{ {
PARG parg; PARG parg;
@ -308,10 +294,7 @@ opt_k(type, s)
} }
#if HAVE_LESSKEYSRC #if HAVE_LESSKEYSRC
public void public void opt_ks(int type, char *s)
opt_ks(type, s)
int type;
char *s;
{ {
PARG parg; PARG parg;
@ -333,10 +316,7 @@ opt_ks(type, s)
/* /*
* Handler for -t option. * Handler for -t option.
*/ */
public void public void opt_t(int type, char *s)
opt_t(type, s)
int type;
char *s;
{ {
IFILE save_ifile; IFILE save_ifile;
POSITION pos; POSITION pos;
@ -374,10 +354,7 @@ opt_t(type, s)
/* /*
* Handler for -T option. * Handler for -T option.
*/ */
public void public void opt__T(int type, char *s)
opt__T(type, s)
int type;
char *s;
{ {
PARG parg; PARG parg;
char *filename; char *filename;
@ -406,10 +383,7 @@ opt__T(type, s)
/* /*
* Handler for -p option. * Handler for -p option.
*/ */
public void public void opt_p(int type, char *s)
opt_p(type, s)
int type;
char *s;
{ {
switch (type) switch (type)
{ {
@ -442,10 +416,7 @@ opt_p(type, s)
/* /*
* Handler for -P option. * Handler for -P option.
*/ */
public void public void opt__P(int type, char *s)
opt__P(type, s)
int type;
char *s;
{ {
char **proto; char **proto;
PARG parg; PARG parg;
@ -481,10 +452,7 @@ opt__P(type, s)
* Handler for the -b option. * Handler for the -b option.
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
public void public void opt_b(int type, char *s)
opt_b(type, s)
int type;
char *s;
{ {
switch (type) switch (type)
{ {
@ -504,10 +472,7 @@ opt_b(type, s)
* Handler for the -i option. * Handler for the -i option.
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
public void public void opt_i(int type, char *s)
opt_i(type, s)
int type;
char *s;
{ {
switch (type) switch (type)
{ {
@ -524,10 +489,7 @@ opt_i(type, s)
* Handler for the -V option. * Handler for the -V option.
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
public void public void opt__V(int type, char *s)
opt__V(type, s)
int type;
char *s;
{ {
switch (type) switch (type)
{ {
@ -544,7 +506,7 @@ opt__V(type, s)
putstr(" regular expressions)\n"); putstr(" regular expressions)\n");
{ {
char constant *copyright = char constant *copyright =
"Copyright (C) 1984-2022 Mark Nudelman\n\n"; "Copyright (C) 1984-2023 Mark Nudelman\n\n";
putstr(copyright); putstr(copyright);
} }
if (version[strlen(version)-1] == 'x') if (version[strlen(version)-1] == 'x')
@ -553,6 +515,9 @@ opt__V(type, s)
putstr("** and may not function correctly.\n"); putstr("** and may not function correctly.\n");
putstr("** Obtain release builds from the web page below.\n\n"); putstr("** Obtain release builds from the web page below.\n\n");
} }
#if LESSTEST
putstr("This build supports LESSTEST.\n");
#endif /*LESSTEST*/
putstr("less comes with NO WARRANTY, to the extent permitted by law.\n"); putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
putstr("For information about the terms of redistribution,\n"); putstr("For information about the terms of redistribution,\n");
putstr("see the file named README in the less distribution.\n"); putstr("see the file named README in the less distribution.\n");
@ -566,11 +531,7 @@ opt__V(type, s)
/* /*
* Parse an MSDOS color descriptor. * Parse an MSDOS color descriptor.
*/ */
static void static void colordesc(char *s, int *fg_color, int *bg_color)
colordesc(s, fg_color, bg_color)
char *s;
int *fg_color;
int *bg_color;
{ {
int fg, bg; int fg, bg;
#if MSDOS_COMPILER==WIN32C #if MSDOS_COMPILER==WIN32C
@ -608,9 +569,7 @@ colordesc(s, fg_color, bg_color)
} }
#endif #endif
static int static int color_from_namechar(char namechar)
color_from_namechar(namechar)
char namechar;
{ {
switch (namechar) switch (namechar)
{ {
@ -629,7 +588,10 @@ color_from_namechar(namechar)
case 'd': return AT_BOLD; case 'd': return AT_BOLD;
case 'u': return AT_UNDERLINE; case 'u': return AT_UNDERLINE;
case 'k': return AT_BLINK; case 'k': return AT_BLINK;
default: return -1; default:
if (namechar >= '1' && namechar <= '0'+NUM_SEARCH_COLORS)
return AT_COLOR_SUBSEARCH(namechar-'0');
return -1;
} }
} }
@ -637,10 +599,7 @@ color_from_namechar(namechar)
* Handler for the -D option. * Handler for the -D option.
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
public void public void opt_D(int type, char *s)
opt_D(type, s)
int type;
char *s;
{ {
PARG p; PARG p;
int attr; int attr;
@ -713,17 +672,42 @@ opt_D(type, s)
} }
} }
/*
*/
public void set_tabs(char *s, int len)
{
int i;
char *es = s + len;
/* Start at 1 because tabstops[0] is always zero. */
for (i = 1; i < TABSTOP_MAX; )
{
int n = 0;
int v = FALSE;
while (s < es && *s == ' ')
s++;
for (; s < es && *s >= '0' && *s <= '9'; s++)
{
v |= ckd_mul(&n, n, 10);
v |= ckd_add(&n, n, *s - '0');
}
if (!v && n > tabstops[i-1])
tabstops[i++] = n;
while (s < es && *s == ' ')
s++;
if (s == es || *s++ != ',')
break;
}
if (i < 2)
return;
ntabstops = i;
tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
}
/* /*
* Handler for the -x option. * Handler for the -x option.
*/ */
public void public void opt_x(int type, char *s)
opt_x(type, s)
int type;
char *s;
{ {
extern int tabstops[];
extern int ntabstops;
extern int tabdefault;
char msg[60+((INT_STRLEN_BOUND(int)+1)*TABSTOP_MAX)]; char msg[60+((INT_STRLEN_BOUND(int)+1)*TABSTOP_MAX)];
int i; int i;
PARG p; PARG p;
@ -732,23 +716,7 @@ opt_x(type, s)
{ {
case INIT: case INIT:
case TOGGLE: case TOGGLE:
/* Start at 1 because tabstops[0] is always zero. */ set_tabs(s, strlen(s));
for (i = 1; i < TABSTOP_MAX; )
{
int n = 0;
s = skipsp(s);
while (*s >= '0' && *s <= '9')
n = (10 * n) + (*s++ - '0');
if (n > tabstops[i-1])
tabstops[i++] = n;
s = skipsp(s);
if (*s++ != ',')
break;
}
if (i < 2)
return;
ntabstops = i;
tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
break; break;
case QUERY: case QUERY:
strcpy(msg, "Tab stops "); strcpy(msg, "Tab stops ");
@ -774,10 +742,7 @@ opt_x(type, s)
/* /*
* Handler for the -" option. * Handler for the -" option.
*/ */
public void public void opt_quote(int type, char *s)
opt_quote(type, s)
int type;
char *s;
{ {
char buf[3]; char buf[3];
PARG parg; PARG parg;
@ -816,10 +781,7 @@ opt_quote(type, s)
* Handler for the --rscroll option. * Handler for the --rscroll option.
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
public void public void opt_rscroll(int type, char *s)
opt_rscroll(type, s)
int type;
char *s;
{ {
PARG p; PARG p;
@ -829,7 +791,7 @@ opt_rscroll(type, s)
case TOGGLE: { case TOGGLE: {
char *fmt; char *fmt;
int attr = AT_STANDOUT; int attr = AT_STANDOUT;
setfmt(s, &fmt, &attr, "*s>"); setfmt(s, &fmt, &attr, "*s>", FALSE);
if (strcmp(fmt, "-") == 0) if (strcmp(fmt, "-") == 0)
{ {
rscroll_char = 0; rscroll_char = 0;
@ -841,7 +803,7 @@ opt_rscroll(type, s)
break; } break; }
case QUERY: { case QUERY: {
p.p_string = rscroll_char ? prchar(rscroll_char) : "-"; p.p_string = rscroll_char ? prchar(rscroll_char) : "-";
error("rscroll char is %s", &p); error("rscroll character is %s", &p);
break; } break; }
} }
} }
@ -851,10 +813,7 @@ opt_rscroll(type, s)
* If from the command line, exit immediately. * If from the command line, exit immediately.
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
public void public void opt_query(int type, char *s)
opt_query(type, s)
int type;
char *s;
{ {
switch (type) switch (type)
{ {
@ -871,10 +830,7 @@ opt_query(type, s)
* Handler for the --mouse option. * Handler for the --mouse option.
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
public void public void opt_mousecap(int type, char *s)
opt_mousecap(type, s)
int type;
char *s;
{ {
switch (type) switch (type)
{ {
@ -894,10 +850,7 @@ opt_mousecap(type, s)
* Handler for the --wheel-lines option. * Handler for the --wheel-lines option.
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
public void public void opt_wheel_lines(int type, char *s)
opt_wheel_lines(type, s)
int type;
char *s;
{ {
switch (type) switch (type)
{ {
@ -915,10 +868,7 @@ opt_wheel_lines(type, s)
* Handler for the --line-number-width option. * Handler for the --line-number-width option.
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
public void public void opt_linenum_width(int type, char *s)
opt_linenum_width(type, s)
int type;
char *s;
{ {
PARG parg; PARG parg;
@ -942,10 +892,7 @@ opt_linenum_width(type, s)
* Handler for the --status-column-width option. * Handler for the --status-column-width option.
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
public void public void opt_status_col_width(int type, char *s)
opt_status_col_width(type, s)
int type;
char *s;
{ {
PARG parg; PARG parg;
@ -969,10 +916,7 @@ opt_status_col_width(type, s)
* Handler for the --file-size option. * Handler for the --file-size option.
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
public void public void opt_filesize(int type, char *s)
opt_filesize(type, s)
int type;
char *s;
{ {
switch (type) switch (type)
{ {
@ -986,14 +930,34 @@ opt_filesize(type, s)
} }
} }
/*
* Handler for the --intr option.
*/
/*ARGSUSED*/
public void opt_intr(int type, char *s)
{
PARG p;
switch (type)
{
case INIT:
case TOGGLE:
intr_char = *s;
if (intr_char == '^' && s[1] != '\0')
intr_char = CONTROL(s[1]);
break;
case QUERY: {
p.p_string = prchar(intr_char);
error("interrupt character is %s", &p);
break; }
}
}
/* /*
* Handler for the --header option. * Handler for the --header option.
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
public void public void opt_header(int type, char *s)
opt_header(type, s)
int type;
char *s;
{ {
int err; int err;
int n; int n;
@ -1002,22 +966,26 @@ opt_header(type, s)
{ {
case INIT: case INIT:
case TOGGLE: case TOGGLE:
n = getnum(&s, "header", &err); header_lines = 0;
if (err) header_cols = 0;
error("invalid number of lines", NULL_PARG); if (*s != ',')
else
{ {
header_lines = n; n = getnum(&s, "header", &err);
header_cols = 0; if (err)
if (*s == ',')
{ {
++s; error("invalid number of lines", NULL_PARG);
n = getnum(&s, "header", &err); return;
if (err)
error("invalid number of columns", NULL_PARG);
else
header_cols = n;
} }
header_lines = n;
}
if (*s == ',')
{
++s;
n = getnum(&s, "header", &err);
if (err)
error("invalid number of columns", NULL_PARG);
else
header_cols = n;
} }
break; break;
case QUERY: case QUERY:
@ -1036,15 +1004,13 @@ opt_header(type, s)
* Handler for the --search-options option. * Handler for the --search-options option.
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
public void public void opt_search_type(int type, char *s)
opt_search_type(type, s)
int type;
char *s;
{ {
int st; int st;
PARG parg; PARG parg;
char buf[16]; char buf[16];
char *bp; char *bp;
int i;
switch (type) switch (type)
{ {
@ -1064,6 +1030,11 @@ opt_search_type(type, s)
case '-': st = 0; break; case '-': st = 0; break;
case '^': break; case '^': break;
default: default:
if (*s >= '1' && *s <= '0'+NUM_SEARCH_COLORS)
{
st |= SRCH_SUBSEARCH(*s-'0');
break;
}
parg.p_char = *s; parg.p_char = *s;
error("invalid search option '%c'", &parg); error("invalid search option '%c'", &parg);
return; return;
@ -1079,6 +1050,9 @@ opt_search_type(type, s)
if (def_search_type & SRCH_NO_MATCH) *bp++ = 'N'; if (def_search_type & SRCH_NO_MATCH) *bp++ = 'N';
if (def_search_type & SRCH_NO_REGEX) *bp++ = 'R'; if (def_search_type & SRCH_NO_REGEX) *bp++ = 'R';
if (def_search_type & SRCH_WRAP) *bp++ = 'W'; if (def_search_type & SRCH_WRAP) *bp++ = 'W';
for (i = 1; i <= NUM_SEARCH_COLORS; i++)
if (def_search_type & SRCH_SUBSEARCH(i))
*bp++ = '0'+i;
if (bp == buf) if (bp == buf)
*bp++ = '-'; *bp++ = '-';
*bp = '\0'; *bp = '\0';
@ -1093,10 +1067,7 @@ opt_search_type(type, s)
* Handler for the --tty option. * Handler for the --tty option.
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
public void public void opt_ttyin_name(int type, char *s)
opt_ttyin_name(type, s)
int type;
char *s;
{ {
switch (type) switch (type)
{ {
@ -1106,33 +1077,9 @@ opt_ttyin_name(type, s)
break; break;
} }
} }
/*
* Handler for the --rstat option.
*/
/*ARGSUSED*/
public void
opt_rstat(type, s)
int type;
char *s;
{
switch (type)
{
case INIT:
rstat_file = open(s, O_WRONLY|O_CREAT, 0664);
if (rstat_file < 0)
{
PARG parg;
parg.p_string = s;
error("Cannot create rstat file \"%s\"", &parg);
}
break;
}
}
#endif /*LESSTEST*/ #endif /*LESSTEST*/
public int public int chop_line(void)
chop_line(VOID_PARAM)
{ {
return (chopline || header_cols > 0 || header_lines > 0); return (chopline || header_cols > 0 || header_lines > 0);
} }
@ -1140,8 +1087,7 @@ chop_line(VOID_PARAM)
/* /*
* Get the "screen window" size. * Get the "screen window" size.
*/ */
public int public int get_swindow(void)
get_swindow(VOID_PARAM)
{ {
if (swindow > 0) if (swindow > 0)
return (swindow); return (swindow);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -23,8 +23,8 @@
static struct loption *pendopt; static struct loption *pendopt;
public int plusoption = FALSE; public int plusoption = FALSE;
static char *optstring LESSPARAMS((char *s, char **p_str, char *printopt, char *validchars)); static char *optstring(char *s, char **p_str, char *printopt, char *validchars);
static int flip_triple LESSPARAMS((int val, int lc)); static int flip_triple(int val, int lc);
extern int screen_trashed; extern int screen_trashed;
extern int less_is_more; extern int less_is_more;
@ -35,9 +35,7 @@ extern int opt_use_backslash;
/* /*
* Return a printable description of an option. * Return a printable description of an option.
*/ */
static char * static char * opt_desc(struct loption *o)
opt_desc(o)
struct loption *o;
{ {
static char buf[OPTNAME_MAX + 10]; static char buf[OPTNAME_MAX + 10];
if (o->oletter == OLETTER_NONE) if (o->oletter == OLETTER_NONE)
@ -51,9 +49,7 @@ opt_desc(o)
* Return a string suitable for printing as the "name" of an option. * Return a string suitable for printing as the "name" of an option.
* For example, if the option letter is 'x', just return "-x". * For example, if the option letter is 'x', just return "-x".
*/ */
public char * public char * propt(int c)
propt(c)
int c;
{ {
static char buf[MAX_PRCHAR_LEN+2]; static char buf[MAX_PRCHAR_LEN+2];
@ -65,9 +61,7 @@ propt(c)
* Scan an argument (either from the command line or from the * Scan an argument (either from the command line or from the
* LESS environment variable) and process it. * LESS environment variable) and process it.
*/ */
public void public void scan_option(char *s)
scan_option(s)
char *s;
{ {
struct loption *o; struct loption *o;
int optc; int optc;
@ -301,12 +295,7 @@ scan_option(s)
* OPT_UNSET set to the default value * OPT_UNSET set to the default value
* OPT_SET set to the inverse of the default value * OPT_SET set to the inverse of the default value
*/ */
public void public void toggle_option(struct loption *o, int lower, char *s, int how_toggle)
toggle_option(o, lower, s, how_toggle)
struct loption *o;
int lower;
char *s;
int how_toggle;
{ {
int num; int num;
int no_prompt; int no_prompt;
@ -487,10 +476,7 @@ toggle_option(o, lower, s, how_toggle)
/* /*
* "Toggle" a triple-valued option. * "Toggle" a triple-valued option.
*/ */
static int static int flip_triple(int val, int lc)
flip_triple(val, lc)
int val;
int lc;
{ {
if (lc) if (lc)
return ((val == OPT_ON) ? OPT_OFF : OPT_ON); return ((val == OPT_ON) ? OPT_OFF : OPT_ON);
@ -501,9 +487,7 @@ flip_triple(val, lc)
/* /*
* Determine if an option takes a parameter. * Determine if an option takes a parameter.
*/ */
public int public int opt_has_param(struct loption *o)
opt_has_param(o)
struct loption *o;
{ {
if (o == NULL) if (o == NULL)
return (0); return (0);
@ -516,9 +500,7 @@ opt_has_param(o)
* Return the prompt to be used for a given option letter. * Return the prompt to be used for a given option letter.
* Only string and number valued options have prompts. * Only string and number valued options have prompts.
*/ */
public char * public char * opt_prompt(struct loption *o)
opt_prompt(o)
struct loption *o;
{ {
if (o == NULL || (o->otype & (STRING|NUMBER)) == 0) if (o == NULL || (o->otype & (STRING|NUMBER)) == 0)
return ("?"); return ("?");
@ -529,9 +511,7 @@ opt_prompt(o)
* If the specified option can be toggled, return NULL. * If the specified option can be toggled, return NULL.
* Otherwise return an appropriate error message. * Otherwise return an appropriate error message.
*/ */
public char * public char * opt_toggle_disallowed(int c)
opt_toggle_disallowed(c)
int c;
{ {
switch (c) switch (c)
{ {
@ -550,8 +530,7 @@ opt_toggle_disallowed(c)
* In that case, the current option is taken to be the string for * In that case, the current option is taken to be the string for
* the previous option. * the previous option.
*/ */
public int public int isoptpending(void)
isoptpending(VOID_PARAM)
{ {
return (pendopt != NULL); return (pendopt != NULL);
} }
@ -559,9 +538,7 @@ isoptpending(VOID_PARAM)
/* /*
* Print error message about missing string. * Print error message about missing string.
*/ */
static void static void nostring(char *printopt)
nostring(printopt)
char *printopt;
{ {
PARG parg; PARG parg;
parg.p_string = printopt; parg.p_string = printopt;
@ -571,8 +548,7 @@ nostring(printopt)
/* /*
* Print error message if a STRING type option is not followed by a string. * Print error message if a STRING type option is not followed by a string.
*/ */
public void public void nopendopt(void)
nopendopt(VOID_PARAM)
{ {
nostring(opt_desc(pendopt)); nostring(opt_desc(pendopt));
} }
@ -582,12 +558,7 @@ nopendopt(VOID_PARAM)
* In the latter case, replace the char with a null char. * In the latter case, replace the char with a null char.
* Return a pointer to the remainder of the string, if any. * Return a pointer to the remainder of the string, if any.
*/ */
static char * static char * optstring(char *s, char **p_str, char *printopt, char *validchars)
optstring(s, p_str, printopt, validchars)
char *s;
char **p_str;
char *printopt;
char *validchars;
{ {
char *p; char *p;
char *out; char *out;
@ -622,10 +593,7 @@ optstring(s, p_str, printopt, validchars)
/* /*
*/ */
static int static int num_error(char *printopt, int *errp, int overflow)
num_error(printopt, errp)
char *printopt;
int *errp;
{ {
PARG parg; PARG parg;
@ -637,7 +605,10 @@ num_error(printopt, errp)
if (printopt != NULL) if (printopt != NULL)
{ {
parg.p_string = printopt; parg.p_string = printopt;
error("Number is required after %s", &parg); error((overflow
? "Number too large in '%s'"
: "Number is required after %s"),
&parg);
} }
return (-1); return (-1);
} }
@ -647,11 +618,7 @@ num_error(printopt, errp)
* Like atoi(), but takes a pointer to a char *, and updates * Like atoi(), but takes a pointer to a char *, and updates
* the char * to point after the translated number. * the char * to point after the translated number.
*/ */
public int public int getnum(char **sp, char *printopt, int *errp)
getnum(sp, printopt, errp)
char **sp;
char *printopt;
int *errp;
{ {
char *s; char *s;
int n; int n;
@ -665,12 +632,11 @@ getnum(sp, printopt, errp)
s++; s++;
} }
if (*s < '0' || *s > '9') if (*s < '0' || *s > '9')
return (num_error(printopt, errp)); return (num_error(printopt, errp, FALSE));
n = 0; n = lstrtoi(s, sp, 10);
while (*s >= '0' && *s <= '9') if (n < 0)
n = 10 * n + *s++ - '0'; return (num_error(printopt, errp, TRUE));
*sp = s;
if (errp != NULL) if (errp != NULL)
*errp = FALSE; *errp = FALSE;
if (neg) if (neg)
@ -684,11 +650,7 @@ getnum(sp, printopt, errp)
* The value of the fraction is returned as parts per NUM_FRAC_DENOM. * The value of the fraction is returned as parts per NUM_FRAC_DENOM.
* That is, if "n" is returned, the fraction intended is n/NUM_FRAC_DENOM. * That is, if "n" is returned, the fraction intended is n/NUM_FRAC_DENOM.
*/ */
public long public long getfraction(char **sp, char *printopt, int *errp)
getfraction(sp, printopt, errp)
char **sp;
char *printopt;
int *errp;
{ {
char *s; char *s;
long frac = 0; long frac = 0;
@ -696,19 +658,17 @@ getfraction(sp, printopt, errp)
s = skipsp(*sp); s = skipsp(*sp);
if (*s < '0' || *s > '9') if (*s < '0' || *s > '9')
return (num_error(printopt, errp)); return (num_error(printopt, errp, FALSE));
for ( ; *s >= '0' && *s <= '9'; s++) for ( ; *s >= '0' && *s <= '9'; s++)
{ {
if (NUM_LOG_FRAC_DENOM <= fraclen)
continue;
frac = (frac * 10) + (*s - '0'); frac = (frac * 10) + (*s - '0');
fraclen++; fraclen++;
} }
if (fraclen > NUM_LOG_FRAC_DENOM) while (fraclen++ < NUM_LOG_FRAC_DENOM)
while (fraclen-- > NUM_LOG_FRAC_DENOM) frac *= 10;
frac /= 10;
else
while (fraclen++ < NUM_LOG_FRAC_DENOM)
frac *= 10;
*sp = s; *sp = s;
if (errp != NULL) if (errp != NULL)
*errp = FALSE; *errp = FALSE;
@ -719,8 +679,7 @@ getfraction(sp, printopt, errp)
/* /*
* Get the value of the -e flag. * Get the value of the -e flag.
*/ */
public int public int get_quit_at_eof(void)
get_quit_at_eof(VOID_PARAM)
{ {
if (!less_is_more) if (!less_is_more)
return quit_at_eof; return quit_at_eof;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -60,7 +60,7 @@ struct loption
int otype; /* Type of the option */ int otype; /* Type of the option */
int odefault; /* Default value */ int odefault; /* Default value */
int *ovar; /* Pointer to the associated variable */ int *ovar; /* Pointer to the associated variable */
void (*ofunc) LESSPARAMS ((int, char*)); /* Pointer to special handling function */ void (*ofunc)(int, char*); /* Pointer to special handling function */
char *odesc[3]; /* Description of each value */ char *odesc[3]; /* Description of each value */
}; };

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -19,6 +19,7 @@
* Variables controlled by command line options. * Variables controlled by command line options.
*/ */
public int quiet; /* Should we suppress the audible bell? */ public int quiet; /* Should we suppress the audible bell? */
public int no_vbell; /* Should we suppress the visual bell? */
public int how_search; /* Where should forward searches start? */ public int how_search; /* Where should forward searches start? */
public int top_scroll; /* Repaint screen from top? public int top_scroll; /* Repaint screen from top?
(alternative is scroll from bottom) */ (alternative is scroll from bottom) */
@ -42,6 +43,7 @@ public int jump_sline; /* Screen line of "jump target" */
public long jump_sline_fraction = -1; public long jump_sline_fraction = -1;
public long shift_count_fraction = -1; public long shift_count_fraction = -1;
public int chopline; /* Truncate displayed lines at screen width */ public int chopline; /* Truncate displayed lines at screen width */
public int wordwrap; /* Wrap lines at space */
public int no_init; /* Disable sending ti/te termcap strings */ public int no_init; /* Disable sending ti/te termcap strings */
public int no_keypad; /* Disable sending ks/ke termcap strings */ public int no_keypad; /* Disable sending ks/ke termcap strings */
public int twiddle; /* Show tildes after EOF */ public int twiddle; /* Show tildes after EOF */
@ -68,9 +70,16 @@ public int status_line; /* Highlight entire marked lines */
public int header_lines; /* Freeze header lines at top of screen */ public int header_lines; /* Freeze header lines at top of screen */
public int header_cols; /* Freeze header columns at left 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 nonum_headers; /* Don't give headers line numbers */
public int nosearch_headers; /* Don't search in header lines or columns */
public int redraw_on_quit; /* Redraw last screen after term deinit */ public int redraw_on_quit; /* Redraw last screen after term deinit */
public int def_search_type; /* */ public int def_search_type; /* */
public int exit_F_on_close; /* Exit F command when input closes */ public int exit_F_on_close; /* Exit F command when input closes */
public int modelines; /* Lines to read looking for modelines */
public int show_preproc_error; /* Display msg when preproc exits with error */
public int proc_backspace; /* Special handling of backspace */
public int proc_tab; /* Special handling of tab */
public int proc_return; /* Special handling of carriage return */
public char intr_char = CONTROL('X'); /* Char to interrupt reads */
#if HILITE_SEARCH #if HILITE_SEARCH
public int hilite_search; /* Highlight matched search patterns? */ public int hilite_search; /* Highlight matched search patterns? */
#endif #endif
@ -149,12 +158,20 @@ static struct optname want_filesize_optname = { "file-size", NULL };
static struct optname status_line_optname = { "status-line", NULL }; static struct optname status_line_optname = { "status-line", NULL };
static struct optname header_optname = { "header", NULL }; static struct optname header_optname = { "header", NULL };
static struct optname nonum_headers_optname = { "no-number-headers", NULL }; static struct optname nonum_headers_optname = { "no-number-headers", NULL };
static struct optname nosearch_headers_optname = { "no-search-headers", NULL };
static struct optname redraw_on_quit_optname = { "redraw-on-quit", NULL }; static struct optname redraw_on_quit_optname = { "redraw-on-quit", NULL };
static struct optname search_type_optname = { "search-options", NULL }; static struct optname search_type_optname = { "search-options", NULL };
static struct optname exit_F_on_close_optname = { "exit-follow-on-close", NULL }; static struct optname exit_F_on_close_optname = { "exit-follow-on-close", NULL };
static struct optname modelines_optname = { "modelines", NULL };
static struct optname no_vbell_optname = { "no-vbell", NULL };
static struct optname intr_optname = { "intr", NULL };
static struct optname wordwrap_optname = { "wordwrap", NULL };
static struct optname show_preproc_error_optname = { "show-preproc-errors", NULL };
static struct optname proc_backspace_optname = { "proc-backspace", NULL };
static struct optname proc_tab_optname = { "proc-tab", NULL };
static struct optname proc_return_optname = { "proc-return", NULL };
#if LESSTEST #if LESSTEST
static struct optname ttyin_name_optname = { "tty", NULL }; static struct optname ttyin_name_optname = { "tty", NULL };
static struct optname rstat_optname = { "rstat", NULL };
#endif /*LESSTEST*/ #endif /*LESSTEST*/
@ -392,7 +409,7 @@ static struct loption option[] =
}, },
#endif #endif
{ 'u', &u_optname, { 'u', &u_optname,
TRIPLE|REPAINT, OPT_OFF, &bs_mode, NULL, TRIPLE|REPAINT|HL_REPAINT, OPT_OFF, &bs_mode, NULL,
{ {
"Display underlined text in underline mode", "Display underlined text in underline mode",
"Backspaces cause overstrike", "Backspaces cause overstrike",
@ -501,7 +518,7 @@ static struct loption option[] =
}, },
{ OLETTER_NONE, &rscroll_optname, { OLETTER_NONE, &rscroll_optname,
STRING|REPAINT|INIT_HANDLER, 0, NULL, opt_rscroll, STRING|REPAINT|INIT_HANDLER, 0, NULL, opt_rscroll,
{ "right scroll character: ", NULL, NULL } { "rscroll character: ", NULL, NULL }
}, },
{ OLETTER_NONE, &nohistdups_optname, { OLETTER_NONE, &nohistdups_optname,
BOOL, OPT_OFF, &no_hist_dups, NULL, BOOL, OPT_OFF, &no_hist_dups, NULL,
@ -599,6 +616,14 @@ static struct loption option[] =
NULL NULL
} }
}, },
{ OLETTER_NONE, &nosearch_headers_optname,
BOOL|HL_REPAINT, 0, &nosearch_headers, NULL,
{
"Search includes header lines",
"Search does not include header lines",
NULL
}
},
{ OLETTER_NONE, &redraw_on_quit_optname, { OLETTER_NONE, &redraw_on_quit_optname,
BOOL, OPT_OFF, &redraw_on_quit, NULL, BOOL, OPT_OFF, &redraw_on_quit, NULL,
{ {
@ -623,17 +648,69 @@ static struct loption option[] =
NULL NULL
} }
}, },
#if LESSTEST { OLETTER_NONE, &no_vbell_optname,
{ OLETTER_NONE, &ttyin_name_optname, BOOL, OPT_OFF, &no_vbell, NULL,
STRING|NO_TOGGLE, 0, NULL, opt_ttyin_name,
{ {
NULL, "Display visual bell",
NULL, "Don't display visual bell",
NULL NULL
} }
}, },
{ OLETTER_NONE, &rstat_optname, { OLETTER_NONE, &modelines_optname,
STRING|NO_TOGGLE, 0, NULL, opt_rstat, NUMBER, 0, &modelines, NULL,
{
"Lines to read looking for modelines: ",
"Read %d lines looking for modelines",
NULL
}
},
{ OLETTER_NONE, &intr_optname,
STRING, 0, NULL, opt_intr,
{ "interrupt character: ", NULL, NULL }
},
{ OLETTER_NONE, &wordwrap_optname,
BOOL|REPAINT, OPT_OFF, &wordwrap, NULL,
{
"Wrap lines at any character",
"Wrap lines at spaces",
NULL
}
},
{ OLETTER_NONE, &show_preproc_error_optname,
BOOL, OPT_OFF, &show_preproc_error, NULL,
{
"Don't show error message if preprocessor fails",
"Show error message if preprocessor fails",
NULL
}
},
{ OLETTER_NONE, &proc_backspace_optname,
TRIPLE|REPAINT|HL_REPAINT, OPT_OFF, &proc_backspace, NULL,
{
"Backspace handling is specified by the -U option",
"Display underline text in underline mode",
"Print backspaces as ^H"
}
},
{ OLETTER_NONE, &proc_tab_optname,
TRIPLE|REPAINT|HL_REPAINT, OPT_OFF, &proc_tab, NULL,
{
"Tab handling is specified by the -U option",
"Expand tabs to spaces",
"Print tabs as ^I"
}
},
{ OLETTER_NONE, &proc_return_optname,
TRIPLE|REPAINT|HL_REPAINT, OPT_OFF, &proc_return, NULL,
{
"Carriage return handling is specified by the -U option",
"Delete carriage return before newline",
"Print carriage return as ^M"
}
},
#if LESSTEST
{ OLETTER_NONE, &ttyin_name_optname,
STRING|NO_TOGGLE, 0, NULL, opt_ttyin_name,
{ {
NULL, NULL,
NULL, NULL,
@ -648,8 +725,7 @@ static struct loption option[] =
/* /*
* Initialize each option to its default value. * Initialize each option to its default value.
*/ */
public void public void init_option(void)
init_option(VOID_PARAM)
{ {
struct loption *o; struct loption *o;
char *p; char *p;
@ -673,9 +749,7 @@ init_option(VOID_PARAM)
/* /*
* Find an option in the option table, given its option letter. * Find an option in the option table, given its option letter.
*/ */
public struct loption * public struct loption * findopt(int c)
findopt(c)
int c;
{ {
struct loption *o; struct loption *o;
@ -692,9 +766,7 @@ findopt(c)
/* /*
* *
*/ */
static int static int is_optchar(char c)
is_optchar(c)
char c;
{ {
if (ASCII_IS_UPPER(c)) if (ASCII_IS_UPPER(c))
return 1; return 1;
@ -711,11 +783,7 @@ is_optchar(c)
* is updated to point after the matched name. * is updated to point after the matched name.
* p_oname if non-NULL is set to point to the full option name. * p_oname if non-NULL is set to point to the full option name.
*/ */
public struct loption * public struct loption * findopt_name(char **p_optname, char **p_oname, int *p_err)
findopt_name(p_optname, p_oname, p_err)
char **p_optname;
char **p_oname;
int *p_err;
{ {
char *optname = *p_optname; char *optname = *p_optname;
struct loption *o; struct loption *o;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -36,8 +36,13 @@
#include <values.h> #include <values.h>
#endif #endif
#if HAVE_POLL && !MSDOS_COMPILER && !defined(__APPLE__) #if defined(__APPLE__)
#include <sys/utsname.h>
#endif
#if HAVE_POLL && !MSDOS_COMPILER
#define USE_POLL 1 #define USE_POLL 1
static int use_poll = TRUE;
#else #else
#define USE_POLL 0 #define USE_POLL 0
#endif #endif
@ -61,44 +66,93 @@
#endif #endif
public int reading; public int reading;
public int waiting_for_data;
public int consecutive_nulls = 0; public int consecutive_nulls = 0;
/* Milliseconds to wait for data before displaying "waiting for data" message. */
static int waiting_for_data_delay = 4000;
static jmp_buf read_label; static jmp_buf read_label;
extern int sigs; extern int sigs;
extern int ignore_eoi; extern int ignore_eoi;
extern int exit_F_on_close; extern int exit_F_on_close;
extern int follow_mode;
extern int scanning_eof;
extern char intr_char;
#if !MSDOS_COMPILER #if !MSDOS_COMPILER
extern int tty; extern int tty;
#endif #endif
#if LESSTEST
extern char *ttyin_name;
#endif /*LESSTEST*/
public void init_poll(void)
{
char *delay = lgetenv("LESS_DATA_DELAY");
int idelay = (delay == NULL) ? 0 : atoi(delay);
if (idelay > 0)
waiting_for_data_delay = idelay;
#if USE_POLL
#if defined(__APPLE__)
/* In old versions of MacOS, poll() does not work with /dev/tty. */
struct utsname uts;
if (uname(&uts) < 0 || lstrtoi(uts.release, NULL, 10) < 20)
use_poll = FALSE;
#endif
#endif
}
#if USE_POLL #if USE_POLL
/* /*
* Return true if one of the events has occurred on the specified file. * Check whether data is available, either from a file/pipe or from the tty.
* Return READ_AGAIN if no data currently available, but caller should retry later.
* Return READ_INTR to abort F command (forw_loop).
* Return 0 if safe to read from fd.
*/ */
static int static int check_poll(int fd, int tty)
poll_events(fd, events)
int fd;
int events;
{ {
struct pollfd poller = { fd, events, 0 }; struct pollfd poller[2] = { { fd, POLLIN, 0 }, { tty, POLLIN, 0 } };
int n = poll(&poller, 1, 0); int timeout = (waiting_for_data && !(scanning_eof && follow_mode == FOLLOW_NAME)) ? -1 : waiting_for_data_delay;
if (n <= 0) poll(poller, 2, timeout);
return 0; #if LESSTEST
return (poller.revents & events); if (ttyin_name == NULL) /* Check for ^X only on a real tty. */
#endif /*LESSTEST*/
{
if (poller[1].revents & POLLIN)
{
LWCHAR ch = getchr();
if (ch == intr_char)
/* Break out of "waiting for data". */
return (READ_INTR);
ungetcc_back(ch);
}
}
if (ignore_eoi && exit_F_on_close && (poller[0].revents & (POLLHUP|POLLIN)) == POLLHUP)
/* Break out of F loop on HUP due to --exit-follow-on-close. */
return (READ_INTR);
if ((poller[0].revents & (POLLIN|POLLHUP|POLLERR)) == 0)
/* No data available; let caller take action, then try again. */
return (READ_AGAIN);
/* There is data (or HUP/ERR) available. Safe to call read() without blocking. */
return (0);
}
#endif /* USE_POLL */
public int supports_ctrl_x(void)
{
#if USE_POLL
return (use_poll);
#else
return (FALSE);
#endif /* USE_POLL */
} }
#endif
/* /*
* Like read() system call, but is deliberately interruptible. * Like read() system call, but is deliberately interruptible.
* A call to intread() from a signal handler will interrupt * A call to intread() from a signal handler will interrupt
* any pending iread(). * any pending iread().
*/ */
public int public int iread(int fd, unsigned char *buf, unsigned int len)
iread(fd, buf, len)
int fd;
unsigned char *buf;
unsigned int len;
{ {
int n; int n;
@ -119,7 +173,7 @@ iread(fd, buf, len)
} }
#endif #endif
#endif #endif
if (SET_JUMP(read_label)) if (!reading && SET_JUMP(read_label))
{ {
/* /*
* We jumped here from intread. * We jumped here from intread.
@ -153,6 +207,7 @@ iread(fd, buf, len)
* available, because that makes some background programs * available, because that makes some background programs
* believe DOS is busy in a way that prevents those * believe DOS is busy in a way that prevents those
* programs from working while "less" waits. * programs from working while "less" waits.
* {{ This code was added 12 Jan 2007; still needed? }}
*/ */
fd_set readfds; fd_set readfds;
@ -161,30 +216,25 @@ iread(fd, buf, len)
if (select(fd+1, &readfds, 0, 0, 0) == -1) if (select(fd+1, &readfds, 0, 0, 0) == -1)
{ {
reading = 0; reading = 0;
return (-1); return (READ_ERR);
} }
} }
#endif #endif
#if USE_POLL #if USE_POLL
if (ignore_eoi && fd != tty) if (fd != tty && use_poll)
{ {
int close_events = exit_F_on_close ? POLLERR|POLLHUP : POLLERR; int ret = check_poll(fd, tty);
if (poll_events(tty, POLLIN) && getchr() == CONTROL('X')) if (ret != 0)
{ {
sigs |= S_INTERRUPT; if (ret == READ_INTR)
sigs |= S_INTERRUPT;
reading = 0; reading = 0;
return (READ_INTR); return (ret);
}
if (poll_events(fd, close_events))
{
sigs |= S_INTERRUPT;
reading = 0;
return (READ_INTR);
} }
} }
#else #else
#if MSDOS_COMPILER==WIN32C #if MSDOS_COMPILER==WIN32C
if (win32_kbhit() && WIN32getch() == CONTROL('X')) if (win32_kbhit() && WIN32getch() == intr_char)
{ {
sigs |= S_INTERRUPT; sigs |= S_INTERRUPT;
reading = 0; reading = 0;
@ -230,7 +280,7 @@ iread(fd, buf, len)
goto start; goto start;
#endif #endif
#endif #endif
return (-1); return (READ_ERR);
} }
return (n); return (n);
} }
@ -238,8 +288,7 @@ iread(fd, buf, len)
/* /*
* Interrupt a pending iread(). * Interrupt a pending iread().
*/ */
public void public void intread(void)
intread(VOID_PARAM)
{ {
LONG_JUMP(read_label, 1); LONG_JUMP(read_label, 1);
} }
@ -248,8 +297,7 @@ intread(VOID_PARAM)
* Return the current time. * Return the current time.
*/ */
#if HAVE_TIME #if HAVE_TIME
public time_type public time_type get_time(void)
get_time(VOID_PARAM)
{ {
time_type t; time_type t;
@ -263,9 +311,7 @@ get_time(VOID_PARAM)
/* /*
* Local version of strerror, if not available from the system. * Local version of strerror, if not available from the system.
*/ */
static char * static char * strerror(int err)
strerror(err)
int err;
{ {
static char buf[INT_STRLEN_BOUND(int)+12]; static char buf[INT_STRLEN_BOUND(int)+12];
#if HAVE_SYS_ERRLIST #if HAVE_SYS_ERRLIST
@ -283,9 +329,7 @@ strerror(err)
/* /*
* errno_message: Return an error message based on the value of "errno". * errno_message: Return an error message based on the value of "errno".
*/ */
public char * public char * errno_message(char *filename)
errno_message(filename)
char *filename;
{ {
char *p; char *p;
char *m; char *m;
@ -304,65 +348,73 @@ errno_message(filename)
return (m); return (m);
} }
/* #define HAVE_FLOAT 0 */ /*
* Return a description of a signal.
static POSITION * The return value is good until the next call to this function.
muldiv(val, num, den) */
POSITION val, num, den; public char * signal_message(int sig)
{ {
#if HAVE_FLOAT static char sigbuf[sizeof("Signal ") + INT_STRLEN_BOUND(sig) + 1];
double v = (((double) val) * num) / den; #if HAVE_STRSIGNAL
return ((POSITION) (v + 0.5)); char *description = strsignal(sig);
#else if (description)
POSITION v = ((POSITION) val) * num; return description;
if (v / num == val)
/* No overflow */
return (POSITION) (v / den);
else
/* Above calculation overflows;
* use a method that is less precise but won't overflow. */
return (POSITION) (val / (den / num));
#endif #endif
sprintf(sigbuf, "Signal %d", sig);
return sigbuf;
}
/*
* Return (VAL * NUM) / DEN, where DEN is positive
* and min(VAL, NUM) <= DEN so the result cannot overflow.
* Round to the nearest integer, breaking ties by rounding to even.
*/
public uintmax muldiv(uintmax val, uintmax num, uintmax den)
{
/*
* Like round(val * (double) num / den), but without rounding error.
* Overflow cannot occur, so there is no need for floating point.
*/
uintmax q = val / den;
uintmax r = val % den;
uintmax qnum = q * num;
uintmax rnum = r * num;
uintmax quot = qnum + rnum / den;
uintmax rem = rnum % den;
return quot + (den / 2 < rem + (quot & ~den & 1));
} }
/* /*
* Return the ratio of two POSITIONS, as a percentage. * Return the ratio of two POSITIONS, as a percentage.
* {{ Assumes a POSITION is a long int. }} * {{ Assumes a POSITION is a long int. }}
*/ */
public int public int percentage(POSITION num, POSITION den)
percentage(num, den)
POSITION num;
POSITION den;
{ {
return (int) muldiv(num, (POSITION) 100, den); return (int) muldiv(num, (POSITION) 100, den);
} }
/* /*
* Return the specified percentage of a POSITION. * Return the specified percentage of a POSITION.
* Assume (0 <= POS && 0 <= PERCENT <= 100
* && 0 <= FRACTION < (PERCENT == 100 ? 1 : NUM_FRAC_DENOM)),
* so the result cannot overflow. Round to even.
*/ */
public POSITION public POSITION percent_pos(POSITION pos, int percent, long fraction)
percent_pos(pos, percent, fraction)
POSITION pos;
int percent;
long fraction;
{ {
/* Change percent (parts per 100) to perden (parts per NUM_FRAC_DENOM). */ /*
POSITION perden = (percent * (NUM_FRAC_DENOM / 100)) + (fraction / 100); * Change from percent (parts per 100)
* to pctden (parts per 100 * NUM_FRAC_DENOM).
*/
POSITION pctden = (percent * NUM_FRAC_DENOM) + fraction;
if (perden == 0) return (POSITION) muldiv(pos, pctden, 100 * (POSITION) NUM_FRAC_DENOM);
return (0);
return (POSITION) muldiv(pos, perden, (POSITION) NUM_FRAC_DENOM);
} }
#if !HAVE_STRCHR #if !HAVE_STRCHR
/* /*
* strchr is used by regexp.c. * strchr is used by regexp.c.
*/ */
char * char * strchr(char *s, char c)
strchr(s, c)
char *s;
int c;
{ {
for ( ; *s != '\0'; s++) for ( ; *s != '\0'; s++)
if (*s == c) if (*s == c)
@ -374,11 +426,7 @@ strchr(s, c)
#endif #endif
#if !HAVE_MEMCPY #if !HAVE_MEMCPY
VOID_POINTER void * memcpy(void *dst, void *src, int len)
memcpy(dst, src, len)
VOID_POINTER dst;
VOID_POINTER src;
int len;
{ {
char *dstp = (char *) dst; char *dstp = (char *) dst;
char *srcp = (char *) src; char *srcp = (char *) src;
@ -395,19 +443,14 @@ memcpy(dst, src, len)
/* /*
* This implements an ANSI-style intercept setup for Microware C 3.2 * This implements an ANSI-style intercept setup for Microware C 3.2
*/ */
public int public int os9_signal(int type, RETSIGTYPE (*handler)())
os9_signal(type, handler)
int type;
RETSIGTYPE (*handler)();
{ {
intercept(handler); intercept(handler);
} }
#include <sgstat.h> #include <sgstat.h>
int int isatty(int f)
isatty(f)
int f;
{ {
struct sgbuf sgbuf; struct sgbuf sgbuf;
@ -418,9 +461,7 @@ isatty(f)
#endif #endif
public void public void sleep_ms(int ms)
sleep_ms(ms)
int ms;
{ {
#if MSDOS_COMPILER==WIN32C #if MSDOS_COMPILER==WIN32C
Sleep(ms); Sleep(ms);
@ -433,7 +474,7 @@ sleep_ms(ms)
#if HAVE_USLEEP #if HAVE_USLEEP
usleep(ms); usleep(ms);
#else #else
sleep((ms+999) / 1000); sleep(ms / 1000 + (ms % 1000 != 0));
#endif #endif
#endif #endif
#endif #endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -31,6 +31,7 @@ extern int so_s_width, so_e_width;
extern int screen_trashed; extern int screen_trashed;
extern int is_tty; extern int is_tty;
extern int oldbot; extern int oldbot;
extern char intr_char;
#if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC #if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
extern int ctldisp; extern int ctldisp;
@ -48,8 +49,7 @@ extern int vt_enabled;
/* /*
* Display the line which is in the line buffer. * Display the line which is in the line buffer.
*/ */
public void public void put_line(void)
put_line(VOID_PARAM)
{ {
int c; int c;
int i; int i;
@ -84,8 +84,7 @@ static char *ob = obuf;
static int outfd = 2; /* stderr */ static int outfd = 2; /* stderr */
#if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC #if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
static void static void win_flush(void)
win_flush(VOID_PARAM)
{ {
if (ctldisp != OPT_ONPLUS || (vt_enabled && sgr_mode)) if (ctldisp != OPT_ONPLUS || (vt_enabled && sgr_mode))
WIN32textout(obuf, ob - obuf); WIN32textout(obuf, ob - obuf);
@ -361,8 +360,7 @@ win_flush(VOID_PARAM)
* sure these messages can be seen before they are * sure these messages can be seen before they are
* overwritten or scrolled away. * overwritten or scrolled away.
*/ */
public void public void flush(void)
flush(VOID_PARAM)
{ {
int n; int n;
@ -397,9 +395,7 @@ flush(VOID_PARAM)
/* /*
* Set the output file descriptor (1=stdout or 2=stderr). * Set the output file descriptor (1=stdout or 2=stderr).
*/ */
public void public void set_output(int fd)
set_output(fd)
int fd;
{ {
flush(); flush();
outfd = fd; outfd = fd;
@ -408,9 +404,7 @@ set_output(fd)
/* /*
* Output a character. * Output a character.
*/ */
public int public int putchr(int c)
putchr(c)
int c;
{ {
#if 0 /* fake UTF-8 output for testing */ #if 0 /* fake UTF-8 output for testing */
extern int utf_mode; extern int utf_mode;
@ -455,8 +449,7 @@ putchr(c)
return (c); return (c);
} }
public void public void clear_bot_if_needed(void)
clear_bot_if_needed(VOID_PARAM)
{ {
if (!need_clr) if (!need_clr)
return; return;
@ -467,9 +460,7 @@ clear_bot_if_needed(VOID_PARAM)
/* /*
* Output a string. * Output a string.
*/ */
public void public void putstr(constant char *s)
putstr(s)
constant char *s;
{ {
while (*s != '\0') while (*s != '\0')
putchr(*s++); putchr(*s++);
@ -480,9 +471,7 @@ putstr(s)
* Convert an integral type to a string. * Convert an integral type to a string.
*/ */
#define TYPE_TO_A_FUNC(funcname, type) \ #define TYPE_TO_A_FUNC(funcname, type) \
void funcname(num, buf) \ void funcname(type num, char *buf, int radix) \
type num; \
char *buf; \
{ \ { \
int neg = (num < 0); \ int neg = (num < 0); \
char tbuf[INT_STRLEN_BOUND(num)+2]; \ char tbuf[INT_STRLEN_BOUND(num)+2]; \
@ -490,8 +479,8 @@ void funcname(num, buf) \
if (neg) num = -num; \ if (neg) num = -num; \
*--s = '\0'; \ *--s = '\0'; \
do { \ do { \
*--s = (num % 10) + '0'; \ *--s = "0123456789ABCDEF"[num % radix]; \
} while ((num /= 10) != 0); \ } while ((num /= radix) != 0); \
if (neg) *--s = '-'; \ if (neg) *--s = '-'; \
strcpy(buf, s); \ strcpy(buf, s); \
} }
@ -501,53 +490,42 @@ TYPE_TO_A_FUNC(linenumtoa, LINENUM)
TYPE_TO_A_FUNC(inttoa, int) TYPE_TO_A_FUNC(inttoa, int)
/* /*
* Convert an string to an integral type. * Convert a string to an integral type. Return ((type) -1) on overflow.
*/ */
#define STR_TO_TYPE_FUNC(funcname, type) \ #define STR_TO_TYPE_FUNC(funcname, type) \
type funcname(buf, ebuf) \ type funcname(char *buf, char **ebuf, int radix) \
char *buf; \
char **ebuf; \
{ \ { \
type val = 0; \ type val = 0; \
int v = 0; \
for (;; buf++) { \ for (;; buf++) { \
char c = *buf; \ char c = *buf; \
if (c < '0' || c > '9') break; \ int digit = (c >= '0' && c <= '9') ? c - '0' : (c >= 'a' && c <= 'f') ? c - 'a' + 10 : (c >= 'A' && c <= 'F') ? c - 'A' + 10 : -1; \
val = 10 * val + c - '0'; \ if (digit < 0 || digit >= radix) break; \
v |= ckd_mul(&val, val, radix); \
v |= ckd_add(&val, val, digit); \
} \ } \
if (ebuf != NULL) *ebuf = buf; \ if (ebuf != NULL) *ebuf = buf; \
return val; \ return v ? -1 : val; \
} }
STR_TO_TYPE_FUNC(lstrtopos, POSITION) STR_TO_TYPE_FUNC(lstrtopos, POSITION)
STR_TO_TYPE_FUNC(lstrtoi, int) STR_TO_TYPE_FUNC(lstrtoi, int)
STR_TO_TYPE_FUNC(lstrtoul, unsigned long)
/* /*
* Output an integer in a given radix. * Print an integral type.
*/ */
static int #define IPRINT_FUNC(funcname, type, typetoa) \
iprint_int(num) static int funcname(type num, int radix) \
int num; { \
{ char buf[INT_STRLEN_BOUND(num)]; \
char buf[INT_STRLEN_BOUND(num)]; typetoa(num, buf, radix); \
putstr(buf); \
inttoa(num, buf); return (int) strlen(buf); \
putstr(buf);
return ((int) strlen(buf));
} }
/* IPRINT_FUNC(iprint_int, int, inttoa)
* Output a line number in a given radix. IPRINT_FUNC(iprint_linenum, LINENUM, linenumtoa)
*/
static int
iprint_linenum(num)
LINENUM num;
{
char buf[INT_STRLEN_BOUND(num)];
linenumtoa(num, buf);
putstr(buf);
return ((int) strlen(buf));
}
/* /*
* This function implements printf-like functionality * This function implements printf-like functionality
@ -556,10 +534,7 @@ iprint_linenum(num)
* {{ This paranoia about the portability of printf dates from experiences * {{ This paranoia about the portability of printf dates from experiences
* with systems in the 1980s and is of course no longer necessary. }} * with systems in the 1980s and is of course no longer necessary. }}
*/ */
public int public int less_printf(char *fmt, PARG *parg)
less_printf(fmt, parg)
char *fmt;
PARG *parg;
{ {
char *s; char *s;
int col; int col;
@ -586,11 +561,15 @@ less_printf(fmt, parg)
} }
break; break;
case 'd': case 'd':
col += iprint_int(parg->p_int); col += iprint_int(parg->p_int, 10);
parg++;
break;
case 'x':
col += iprint_int(parg->p_int, 16);
parg++; parg++;
break; break;
case 'n': case 'n':
col += iprint_linenum(parg->p_linenum); col += iprint_linenum(parg->p_linenum, 10);
parg++; parg++;
break; break;
case 'c': case 'c':
@ -616,8 +595,7 @@ less_printf(fmt, parg)
* If some other non-trivial char is pressed, unget it, so it will * If some other non-trivial char is pressed, unget it, so it will
* become the next command. * become the next command.
*/ */
public void public void get_return(void)
get_return(VOID_PARAM)
{ {
int c; int c;
@ -635,10 +613,7 @@ get_return(VOID_PARAM)
* Output a message in the lower left corner of the screen * Output a message in the lower left corner of the screen
* and wait for carriage return. * and wait for carriage return.
*/ */
public void public void error(char *fmt, PARG *parg)
error(fmt, parg)
char *fmt;
PARG *parg;
{ {
int col = 0; int col = 0;
static char return_to_continue[] = " (press RETURN)"; static char return_to_continue[] = " (press RETURN)";
@ -678,37 +653,45 @@ error(fmt, parg)
flush(); flush();
} }
static char intr_to_abort[] = "... (interrupt to abort)";
/* /*
* Output a message in the lower left corner of the screen * Output a message in the lower left corner of the screen
* and don't wait for carriage return. * and don't wait for carriage return.
* Usually used to warn that we are beginning a potentially * Usually used to warn that we are beginning a potentially
* time-consuming operation. * time-consuming operation.
*/ */
public void static void ierror_suffix(char *fmt, PARG *parg, char *suffix1, char *suffix2, char *suffix3)
ierror(fmt, parg)
char *fmt;
PARG *parg;
{ {
at_exit(); at_exit();
clear_bot(); clear_bot();
at_enter(AT_STANDOUT|AT_COLOR_ERROR); at_enter(AT_STANDOUT|AT_COLOR_ERROR);
(void) less_printf(fmt, parg); (void) less_printf(fmt, parg);
putstr(intr_to_abort); putstr(suffix1);
putstr(suffix2);
putstr(suffix3);
at_exit(); at_exit();
flush(); flush();
need_clr = 1; need_clr = 1;
} }
public void ierror(char *fmt, PARG *parg)
{
ierror_suffix(fmt, parg, "... (interrupt to abort)", "", "");
}
public void ixerror(char *fmt, PARG *parg)
{
if (!supports_ctrl_x())
ierror(fmt, parg);
else
ierror_suffix(fmt, parg,
"... (", prchar(intr_char), " or interrupt to abort)");
}
/* /*
* Output a message in the lower left corner of the screen * Output a message in the lower left corner of the screen
* and return a single-character response. * and return a single-character response.
*/ */
public int public int query(char *fmt, PARG *parg)
query(fmt, parg)
char *fmt;
PARG *parg;
{ {
int c; int c;
int col = 0; int col = 0;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -20,12 +20,7 @@ extern int utf_mode;
/* /*
* Compile a search pattern, for future use by match_pattern. * Compile a search pattern, for future use by match_pattern.
*/ */
static int static int compile_pattern2(char *pattern, int search_type, PATTERN_TYPE *comp_pattern, int show_error)
compile_pattern2(pattern, search_type, comp_pattern, show_error)
char *pattern;
int search_type;
PATTERN_TYPE *comp_pattern;
int show_error;
{ {
if (search_type & SRCH_NO_REGEX) if (search_type & SRCH_NO_REGEX)
return (0); return (0);
@ -147,17 +142,12 @@ compile_pattern2(pattern, search_type, comp_pattern, show_error)
/* /*
* Like compile_pattern2, but convert the pattern to lowercase if necessary. * Like compile_pattern2, but convert the pattern to lowercase if necessary.
*/ */
public int public int compile_pattern(char *pattern, int search_type, int show_error, PATTERN_TYPE *comp_pattern)
compile_pattern(pattern, search_type, show_error, comp_pattern)
char *pattern;
int search_type;
int show_error;
PATTERN_TYPE *comp_pattern;
{ {
char *cvt_pattern; char *cvt_pattern;
int result; int result;
if (caseless != OPT_ONPLUS || re_handles_caseless) if (caseless != OPT_ONPLUS || (re_handles_caseless && !(search_type & SRCH_NO_REGEX)))
cvt_pattern = pattern; cvt_pattern = pattern;
else else
{ {
@ -173,9 +163,7 @@ compile_pattern(pattern, search_type, show_error, comp_pattern)
/* /*
* Forget that we have a compiled pattern. * Forget that we have a compiled pattern.
*/ */
public void public void uncompile_pattern(PATTERN_TYPE *pattern)
uncompile_pattern(pattern)
PATTERN_TYPE *pattern;
{ {
#if HAVE_GNU_REGEX #if HAVE_GNU_REGEX
if (*pattern != NULL) if (*pattern != NULL)
@ -222,9 +210,7 @@ uncompile_pattern(pattern)
/* /*
* Can a pattern be successfully compiled? * Can a pattern be successfully compiled?
*/ */
public int public int valid_pattern(char *pattern)
valid_pattern(pattern)
char *pattern;
{ {
PATTERN_TYPE comp_pattern; PATTERN_TYPE comp_pattern;
int result; int result;
@ -241,9 +227,7 @@ valid_pattern(pattern)
/* /*
* Is a compiled pattern null? * Is a compiled pattern null?
*/ */
public int public int is_null_pattern(PATTERN_TYPE pattern)
is_null_pattern(pattern)
PATTERN_TYPE pattern;
{ {
#if HAVE_GNU_REGEX #if HAVE_GNU_REGEX
return (pattern == NULL); return (pattern == NULL);
@ -270,18 +254,11 @@ is_null_pattern(pattern)
return (pattern == NULL); return (pattern == NULL);
#endif #endif
} }
/* /*
* Simple pattern matching function. * Simple pattern matching function.
* It supports no metacharacters like *, etc. * It supports no metacharacters like *, etc.
*/ */
static int static int match(char *pattern, int pattern_len, char *buf, int buf_len, char ***sp, char ***ep, int nsubs)
match(pattern, pattern_len, buf, buf_len, pfound, pend)
char *pattern;
int pattern_len;
char *buf;
int buf_len;
char **pfound, **pend;
{ {
char *pp, *lp; char *pp, *lp;
char *pattern_end = pattern + pattern_len; char *pattern_end = pattern + pattern_len;
@ -302,39 +279,30 @@ match(pattern, pattern_len, buf, buf_len, pfound, pend)
} }
if (pp == pattern_end) if (pp == pattern_end)
{ {
if (pfound != NULL) *(*sp)++ = buf;
*pfound = buf; *(*ep)++ = lp;
if (pend != NULL)
*pend = lp;
return (1); return (1);
} }
} }
**sp = **ep = NULL;
return (0); return (0);
} }
/* /*
* Perform a pattern match with the previously compiled pattern. * Perform a pattern match with the previously compiled pattern.
* Set sp and ep to the start and end of the matched string. * Set sp[0] and ep[0] to the start and end of the matched string.
* Set sp[i] and ep[i] to the start and end of the i-th matched subpattern.
* Subpatterns are defined by parentheses in the regex language.
*/ */
public int static int match_pattern1(PATTERN_TYPE pattern, char *tpattern, char *line, int line_len, char **sp, char **ep, int nsp, int notbol, int search_type)
match_pattern(pattern, tpattern, line, line_len, sp, ep, notbol, search_type)
PATTERN_TYPE pattern;
char *tpattern;
char *line;
int line_len;
char **sp;
char **ep;
int notbol;
int search_type;
{ {
int matched; int matched;
*sp = *ep = NULL;
#if NO_REGEX #if NO_REGEX
search_type |= SRCH_NO_REGEX; search_type |= SRCH_NO_REGEX;
#endif #endif
if (search_type & SRCH_NO_REGEX) if (search_type & SRCH_NO_REGEX)
matched = match(tpattern, strlen(tpattern), line, line_len, sp, ep); matched = match(tpattern, strlen(tpattern), line, line_len, &sp, &ep, nsp);
else else
{ {
#if HAVE_GNU_REGEX #if HAVE_GNU_REGEX
@ -345,57 +313,101 @@ match_pattern(pattern, tpattern, line, line_len, sp, ep, notbol, search_type)
matched = re_search(pattern, line, line_len, 0, line_len, &search_regs) >= 0; matched = re_search(pattern, line, line_len, 0, line_len, &search_regs) >= 0;
if (matched) if (matched)
{ {
*sp = line + search_regs.start[0]; *sp++ = line + search_regs.start[0];
*ep = line + search_regs.end[0]; *ep++ = line + search_regs.end[0];
} }
} }
#endif #endif
#if HAVE_POSIX_REGCOMP #if HAVE_POSIX_REGCOMP
{ {
regmatch_t rm; #define RM_COUNT (NUM_SEARCH_COLORS+2)
regmatch_t rm[RM_COUNT];
int flags = (notbol) ? REG_NOTBOL : 0; int flags = (notbol) ? REG_NOTBOL : 0;
#ifdef REG_STARTEND #ifdef REG_STARTEND
flags |= REG_STARTEND; flags |= REG_STARTEND;
rm.rm_so = 0; rm[0].rm_so = 0;
rm.rm_eo = line_len; rm[0].rm_eo = line_len;
#endif #endif
matched = !regexec(pattern, line, 1, &rm, flags); matched = !regexec(pattern, line, RM_COUNT, rm, flags);
if (matched) if (matched)
{ {
int i;
int ecount;
for (ecount = RM_COUNT; ecount > 0; ecount--)
if (rm[ecount-1].rm_so >= 0)
break;
if (ecount >= nsp)
ecount = nsp-1;
for (i = 0; i < ecount; i++)
{
if (rm[i].rm_so < 0)
{
*sp++ = *ep++ = line;
} else
{
#ifndef __WATCOMC__ #ifndef __WATCOMC__
*sp = line + rm.rm_so; *sp++ = line + rm[i].rm_so;
*ep = line + rm.rm_eo; *ep++ = line + rm[i].rm_eo;
#else #else
*sp = rm.rm_sp; *sp++ = rm[i].rm_sp;
*ep = rm.rm_ep; *ep++ = rm[i].rm_ep;
#endif #endif
}
}
} }
} }
#endif #endif
#if HAVE_PCRE #if HAVE_PCRE
{ {
#define OVECTOR_COUNT ((3*NUM_SEARCH_COLORS)+3)
int ovector[OVECTOR_COUNT];
int flags = (notbol) ? PCRE_NOTBOL : 0; int flags = (notbol) ? PCRE_NOTBOL : 0;
int ovector[3]; int i;
matched = pcre_exec(pattern, NULL, line, line_len, int ecount;
0, flags, ovector, 3) >= 0; int mcount = pcre_exec(pattern, NULL, line, line_len,
if (matched) 0, flags, ovector, OVECTOR_COUNT);
matched = (mcount > 0);
ecount = nsp-1;
if (ecount > mcount) ecount = mcount;
for (i = 0; i < ecount*2; )
{ {
*sp = line + ovector[0]; if (ovector[i] < 0 || ovector[i+1] < 0)
*ep = line + ovector[1]; {
*sp++ = *ep++ = line;
i += 2;
} else
{
*sp++ = line + ovector[i++];
*ep++ = line + ovector[i++];
}
} }
} }
#endif #endif
#if HAVE_PCRE2 #if HAVE_PCRE2
{ {
int flags = (notbol) ? PCRE2_NOTBOL : 0; int flags = (notbol) ? PCRE2_NOTBOL : 0;
pcre2_match_data *md = pcre2_match_data_create(3, NULL); pcre2_match_data *md = pcre2_match_data_create(nsp-1, NULL);
matched = pcre2_match(pattern, (PCRE2_SPTR)line, line_len, int mcount = pcre2_match(pattern, (PCRE2_SPTR)line, line_len,
0, flags, md, NULL) >= 0; 0, flags, md, NULL);
matched = (mcount > 0);
if (matched) if (matched)
{ {
PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(md); PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(md);
*sp = line + ovector[0]; int i;
*ep = line + ovector[1]; int ecount = nsp-1;
if (ecount > mcount) ecount = mcount;
for (i = 0; i < ecount*2; )
{
if (ovector[i] < 0 || ovector[i+1] < 0)
{
*sp++ = *ep++ = line;
i += 2;
} else
{
*sp++ = line + ovector[i++];
*ep++ = line + ovector[i++];
}
}
} }
pcre2_match_data_free(md); pcre2_match_data_free(md);
} }
@ -405,13 +417,11 @@ match_pattern(pattern, tpattern, line, line_len, sp, ep, notbol, search_type)
/* /*
* re_exec doesn't seem to provide a way to get the matched string. * re_exec doesn't seem to provide a way to get the matched string.
*/ */
*sp = *ep = NULL;
#endif #endif
#if HAVE_REGCMP #if HAVE_REGCMP
*ep = regex(pattern, line); matched = ((*ep++ = regex(pattern, line)) != NULL);
matched = (*ep != NULL);
if (matched) if (matched)
*sp = __loc1; *sp++ = __loc1;
#endif #endif
#if HAVE_V8_REGCOMP #if HAVE_V8_REGCOMP
#if HAVE_REGEXEC2 #if HAVE_REGEXEC2
@ -421,21 +431,33 @@ match_pattern(pattern, tpattern, line, line_len, sp, ep, notbol, search_type)
#endif #endif
if (matched) if (matched)
{ {
*sp = pattern->startp[0]; *sp++ = pattern->startp[0];
*ep = pattern->endp[0]; *ep++ = pattern->endp[0];
} }
#endif #endif
} }
*sp = *ep = NULL;
matched = (!(search_type & SRCH_NO_MATCH) && matched) || matched = (!(search_type & SRCH_NO_MATCH) && matched) ||
((search_type & SRCH_NO_MATCH) && !matched); ((search_type & SRCH_NO_MATCH) && !matched);
return (matched); return (matched);
} }
public int match_pattern(PATTERN_TYPE pattern, char *tpattern, char *line, int line_len, char **sp, char **ep, int nsp, int notbol, int search_type)
{
int matched = match_pattern1(pattern, tpattern, line, line_len, sp, ep, nsp, notbol, search_type);
int i;
for (i = 1; i <= NUM_SEARCH_COLORS; i++)
{
if ((search_type & SRCH_SUBSEARCH(i)) && ep[i] == sp[i])
matched = 0;
}
return matched;
}
/* /*
* Return the name of the pattern matching library. * Return the name of the pattern matching library.
*/ */
public char * public char * pattern_lib_name(void)
pattern_lib_name(VOID_PARAM)
{ {
#if HAVE_GNU_REGEX #if HAVE_GNU_REGEX
return ("GNU"); return ("GNU");

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -47,16 +47,16 @@ extern int less_is_more;
/* ---- RE_COMP ---- */ /* ---- RE_COMP ---- */
#if HAVE_RE_COMP #if HAVE_RE_COMP
char *re_comp LESSPARAMS ((char*)); char *re_comp(char*);
int re_exec LESSPARAMS ((char*)); int re_exec(char*);
#define PATTERN_TYPE int #define PATTERN_TYPE int
#define SET_NULL_PATTERN(name) name = 0 #define SET_NULL_PATTERN(name) name = 0
#endif #endif
/* ---- REGCMP ---- */ /* ---- REGCMP ---- */
#if HAVE_REGCMP #if HAVE_REGCMP
char *regcmp LESSPARAMS ((char*)); char *regcmp(char*);
char *regex LESSPARAMS ((char**, char*)); char *regex(char**, char*);
extern char *__loc1; extern char *__loc1;
#define PATTERN_TYPE char ** #define PATTERN_TYPE char **
#define SET_NULL_PATTERN(name) name = NULL #define SET_NULL_PATTERN(name) name = NULL

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -36,9 +36,7 @@ extern int header_lines;
* the bottom line on the screen * the bottom line on the screen
* the line after the bottom line on the screen * the line after the bottom line on the screen
*/ */
public POSITION public POSITION position(int sindex)
position(sindex)
int sindex;
{ {
switch (sindex) switch (sindex)
{ {
@ -58,9 +56,7 @@ position(sindex)
/* /*
* Add a new file position to the bottom of the position table. * Add a new file position to the bottom of the position table.
*/ */
public void public void add_forw_pos(POSITION pos)
add_forw_pos(pos)
POSITION pos;
{ {
int i; int i;
@ -75,9 +71,7 @@ add_forw_pos(pos)
/* /*
* Add a new file position to the top of the position table. * Add a new file position to the top of the position table.
*/ */
public void public void add_back_pos(POSITION pos)
add_back_pos(pos)
POSITION pos;
{ {
int i; int i;
@ -92,8 +86,7 @@ add_back_pos(pos)
/* /*
* Initialize the position table, done whenever we clear the screen. * Initialize the position table, done whenever we clear the screen.
*/ */
public void public void pos_clear(void)
pos_clear(VOID_PARAM)
{ {
int i; int i;
@ -104,8 +97,7 @@ pos_clear(VOID_PARAM)
/* /*
* Allocate or reallocate the position table. * Allocate or reallocate the position table.
*/ */
public void public void pos_init(void)
pos_init(VOID_PARAM)
{ {
struct scrpos scrpos; struct scrpos scrpos;
@ -133,9 +125,7 @@ pos_init(VOID_PARAM)
* Check the position table to see if the position falls within its range. * Check the position table to see if the position falls within its range.
* Return the position table entry if found, -1 if not. * Return the position table entry if found, -1 if not.
*/ */
public int public int onscreen(POSITION pos)
onscreen(pos)
POSITION pos;
{ {
int i; int i;
@ -150,16 +140,12 @@ onscreen(pos)
/* /*
* See if the entire screen is empty. * See if the entire screen is empty.
*/ */
public int public int empty_screen(void)
empty_screen(VOID_PARAM)
{ {
return (empty_lines(0, sc_height-1)); return (empty_lines(0, sc_height-1));
} }
public int public int empty_lines(int s, int e)
empty_lines(s, e)
int s;
int e;
{ {
int i; int i;
@ -177,10 +163,7 @@ empty_lines(s, e)
* such that the top few lines are empty, we may have to set * such that the top few lines are empty, we may have to set
* the screen line to a number > 0. * the screen line to a number > 0.
*/ */
public void public void get_scrpos(struct scrpos *scrpos, int where)
get_scrpos(scrpos, where)
struct scrpos *scrpos;
int where;
{ {
int i; int i;
int dir; int dir;
@ -233,9 +216,7 @@ get_scrpos(scrpos, where)
* or it may be in { -1 .. -(sc_height-1) } to refer to lines * or it may be in { -1 .. -(sc_height-1) } to refer to lines
* relative to the bottom of the screen. * relative to the bottom of the screen.
*/ */
public int public int sindex_from_sline(int sline)
sindex_from_sline(sline)
int sline;
{ {
/* /*
* Negative screen line number means * Negative screen line number means

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -66,8 +66,7 @@ static char *mp;
/* /*
* Initialize the prompt prototype strings. * Initialize the prompt prototype strings.
*/ */
public void public void init_prompt(void)
init_prompt(VOID_PARAM)
{ {
prproto[0] = save(s_proto); prproto[0] = save(s_proto);
prproto[1] = save(less_is_more ? more_proto : m_proto); prproto[1] = save(less_is_more ? more_proto : m_proto);
@ -80,9 +79,7 @@ init_prompt(VOID_PARAM)
/* /*
* Append a string to the end of the message. * Append a string to the end of the message.
*/ */
static void static void ap_str(char *s)
ap_str(s)
char *s;
{ {
int len; int len;
@ -97,9 +94,7 @@ ap_str(s)
/* /*
* Append a character to the end of the message. * Append a character to the end of the message.
*/ */
static void static void ap_char(char c)
ap_char(c)
char c;
{ {
char buf[2]; char buf[2];
@ -111,47 +106,40 @@ ap_char(c)
/* /*
* Append a POSITION (as a decimal integer) to the end of the message. * Append a POSITION (as a decimal integer) to the end of the message.
*/ */
static void static void ap_pos(POSITION pos)
ap_pos(pos)
POSITION pos;
{ {
char buf[INT_STRLEN_BOUND(pos) + 2]; char buf[INT_STRLEN_BOUND(pos) + 2];
postoa(pos, buf); postoa(pos, buf, 10);
ap_str(buf); ap_str(buf);
} }
/* /*
* Append a line number to the end of the message. * Append a line number to the end of the message.
*/ */
static void static void ap_linenum(LINENUM linenum)
ap_linenum(linenum)
LINENUM linenum;
{ {
char buf[INT_STRLEN_BOUND(linenum) + 2]; char buf[INT_STRLEN_BOUND(linenum) + 2];
linenumtoa(linenum, buf); linenumtoa(linenum, buf, 10);
ap_str(buf); ap_str(buf);
} }
/* /*
* Append an integer to the end of the message. * Append an integer to the end of the message.
*/ */
static void static void ap_int(int num)
ap_int(num)
int num;
{ {
char buf[INT_STRLEN_BOUND(num) + 2]; char buf[INT_STRLEN_BOUND(num) + 2];
inttoa(num, buf); inttoa(num, buf, 10);
ap_str(buf); ap_str(buf);
} }
/* /*
* Append a question mark to the end of the message. * Append a question mark to the end of the message.
*/ */
static void static void ap_quest(void)
ap_quest(VOID_PARAM)
{ {
ap_str("?"); ap_str("?");
} }
@ -159,9 +147,7 @@ ap_quest(VOID_PARAM)
/* /*
* Return the "current" byte offset in the file. * Return the "current" byte offset in the file.
*/ */
static POSITION static POSITION curr_byte(int where)
curr_byte(where)
int where;
{ {
POSITION pos; POSITION pos;
@ -179,10 +165,7 @@ curr_byte(where)
* question mark followed by a single letter. * question mark followed by a single letter.
* Here we decode that letter and return the appropriate boolean value. * Here we decode that letter and return the appropriate boolean value.
*/ */
static int static int cond(char c, int where)
cond(c, where)
char c;
int where;
{ {
POSITION len; POSITION len;
@ -246,11 +229,7 @@ cond(c, where)
* Here we decode that letter and take the appropriate action, * Here we decode that letter and take the appropriate action,
* usually by appending something to the message being built. * usually by appending something to the message being built.
*/ */
static void static void protochar(int c, int where, int iseditproto)
protochar(c, where, iseditproto)
int c;
int where;
int iseditproto;
{ {
POSITION pos; POSITION pos;
POSITION len; POSITION len;
@ -402,9 +381,7 @@ protochar(c, where, iseditproto)
* where to resume parsing the string. * where to resume parsing the string.
* We must keep track of nested IFs and skip them properly. * We must keep track of nested IFs and skip them properly.
*/ */
static constant char * static constant char * skipcond(constant char *p)
skipcond(p)
constant char *p;
{ {
int iflevel; int iflevel;
@ -444,7 +421,8 @@ skipcond(p)
/* /*
* Backslash escapes the next character. * Backslash escapes the next character.
*/ */
++p; if (p[1] != '\0')
++p;
break; break;
case '\0': case '\0':
/* /*
@ -460,10 +438,7 @@ skipcond(p)
/* /*
* Decode a char that represents a position on the screen. * Decode a char that represents a position on the screen.
*/ */
static constant char * static constant char * wherechar(char constant *p, int *wp)
wherechar(p, wp)
char constant *p;
int *wp;
{ {
switch (*p) switch (*p)
{ {
@ -484,9 +459,7 @@ wherechar(p, wp)
/* /*
* Construct a message based on a prototype string. * Construct a message based on a prototype string.
*/ */
public char * public char * pr_expand(constant char *proto)
pr_expand(proto)
constant char *proto;
{ {
constant char *p; constant char *p;
int c; int c;
@ -505,8 +478,8 @@ pr_expand(proto)
ap_char(*p); ap_char(*p);
break; break;
case '\\': /* Backslash escapes the next character */ case '\\': /* Backslash escapes the next character */
p++; if (p[1] != '\0')
ap_char(*p); ap_char(*++p);
break; break;
case '?': /* Conditional (IF) */ case '?': /* Conditional (IF) */
if ((c = *++p) == '\0') if ((c = *++p) == '\0')
@ -551,8 +524,7 @@ pr_expand(proto)
/* /*
* Return a message suitable for printing by the "=" command. * Return a message suitable for printing by the "=" command.
*/ */
public char * public char * eq_message(void)
eq_message(VOID_PARAM)
{ {
return (pr_expand(eqproto)); return (pr_expand(eqproto));
} }
@ -563,8 +535,7 @@ eq_message(VOID_PARAM)
* If we can't come up with an appropriate prompt, return NULL * If we can't come up with an appropriate prompt, return NULL
* and the caller will prompt with a colon. * and the caller will prompt with a colon.
*/ */
public char * public char * pr_string(void)
pr_string(VOID_PARAM)
{ {
char *prompt; char *prompt;
int type; int type;
@ -579,8 +550,7 @@ pr_string(VOID_PARAM)
/* /*
* Return a message suitable for printing while waiting in the F command. * Return a message suitable for printing while waiting in the F command.
*/ */
public char * public char * wait_message(void)
wait_message(VOID_PARAM)
{ {
return (pr_expand(wproto)); return (pr_expand(wproto));
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -26,6 +26,8 @@ extern int linenums;
extern int sc_height; extern int sc_height;
extern int jump_sline; extern int jump_sline;
extern int bs_mode; extern int bs_mode;
extern int proc_backspace;
extern int proc_return;
extern int ctldisp; extern int ctldisp;
extern int status_col; extern int status_col;
extern void *ml_search; extern void *ml_search;
@ -36,6 +38,9 @@ extern int screen_trashed;
extern int sc_width; extern int sc_width;
extern int sc_height; extern int sc_height;
extern int hshift; extern int hshift;
extern int nosearch_headers;
extern int header_lines;
extern int header_cols;
#if HILITE_SEARCH #if HILITE_SEARCH
extern int hilite_search; extern int hilite_search;
extern int size_linebuf; extern int size_linebuf;
@ -66,6 +71,7 @@ struct hilite
{ {
POSITION hl_startpos; POSITION hl_startpos;
POSITION hl_endpos; POSITION hl_endpos;
int hl_attr;
}; };
struct hilite_node struct hilite_node
{ {
@ -108,6 +114,7 @@ struct pattern_info {
PATTERN_TYPE compiled; PATTERN_TYPE compiled;
char* text; char* text;
int search_type; int search_type;
int is_ucase_pattern;
struct pattern_info *next; struct pattern_info *next;
}; };
@ -118,15 +125,12 @@ struct pattern_info {
#endif #endif
static struct pattern_info search_info; static struct pattern_info search_info;
static int is_ucase_pattern;
public int is_caseless; public int is_caseless;
/* /*
* Are there any uppercase letters in this string? * Are there any uppercase letters in this string?
*/ */
static int static int is_ucase(char *str)
is_ucase(str)
char *str;
{ {
char *str_end = str + strlen(str); char *str_end = str + strlen(str);
LWCHAR ch; LWCHAR ch;
@ -143,9 +147,7 @@ is_ucase(str)
/* /*
* Discard a saved pattern. * Discard a saved pattern.
*/ */
static void static void clear_pattern(struct pattern_info *info)
clear_pattern(info)
struct pattern_info *info;
{ {
if (info->text != NULL) if (info->text != NULL)
free(info->text); free(info->text);
@ -158,19 +160,14 @@ clear_pattern(info)
/* /*
* Compile and save a search pattern. * Compile and save a search pattern.
*/ */
static int static int set_pattern(struct pattern_info *info, char *pattern, int search_type, int show_error)
set_pattern(info, pattern, search_type, show_error)
struct pattern_info *info;
char *pattern;
int search_type;
int show_error;
{ {
/* /*
* Ignore case if -I is set OR * Ignore case if -I is set OR
* -i is set AND the pattern is all lowercase. * -i is set AND the pattern is all lowercase.
*/ */
is_ucase_pattern = (pattern == NULL) ? FALSE : is_ucase(pattern); info->is_ucase_pattern = (pattern == NULL) ? FALSE : is_ucase(pattern);
is_caseless = (is_ucase_pattern && caseless != OPT_ONPLUS) ? 0 : caseless; is_caseless = (info->is_ucase_pattern && caseless != OPT_ONPLUS) ? 0 : caseless;
#if !NO_REGEX #if !NO_REGEX
if (pattern == NULL) if (pattern == NULL)
SET_NULL_PATTERN(info->compiled); SET_NULL_PATTERN(info->compiled);
@ -193,9 +190,7 @@ set_pattern(info, pattern, search_type, show_error)
/* /*
* Initialize saved pattern to nothing. * Initialize saved pattern to nothing.
*/ */
static void static void init_pattern(struct pattern_info *info)
init_pattern(info)
struct pattern_info *info;
{ {
SET_NULL_PATTERN(info->compiled); SET_NULL_PATTERN(info->compiled);
info->text = NULL; info->text = NULL;
@ -206,8 +201,7 @@ init_pattern(info)
/* /*
* Initialize search variables. * Initialize search variables.
*/ */
public void public void init_search(void)
init_search(VOID_PARAM)
{ {
init_pattern(&search_info); init_pattern(&search_info);
} }
@ -215,16 +209,15 @@ init_search(VOID_PARAM)
/* /*
* Determine which text conversions to perform before pattern matching. * Determine which text conversions to perform before pattern matching.
*/ */
static int static int get_cvt_ops(int search_type)
get_cvt_ops(VOID_PARAM)
{ {
int ops = 0; int ops = 0;
if (is_caseless && !re_handles_caseless) if (is_caseless && (!re_handles_caseless || (search_type & SRCH_NO_REGEX)))
ops |= CVT_TO_LC; ops |= CVT_TO_LC;
if (bs_mode == BS_SPECIAL) if (proc_backspace == OPT_ON || (bs_mode == BS_SPECIAL && proc_backspace == OPT_OFF))
ops |= CVT_BS; ops |= CVT_BS;
if (bs_mode != BS_CONTROL) if (proc_return == OPT_ON || (bs_mode != BS_CONTROL && proc_backspace == OPT_OFF))
ops |= CVT_CRLF; ops |= CVT_CRLF;
if (ctldisp == OPT_ONPLUS) if (ctldisp == OPT_ONPLUS)
ops |= CVT_ANSI; ops |= CVT_ANSI;
@ -234,9 +227,7 @@ get_cvt_ops(VOID_PARAM)
/* /*
* Is there a previous (remembered) search pattern? * Is there a previous (remembered) search pattern?
*/ */
static int static int prev_pattern(struct pattern_info *info)
prev_pattern(info)
struct pattern_info *info;
{ {
#if !NO_REGEX #if !NO_REGEX
if ((info->search_type & SRCH_NO_REGEX) == 0) if ((info->search_type & SRCH_NO_REGEX) == 0)
@ -251,9 +242,7 @@ prev_pattern(info)
* Repaint each line which contains highlighted text. * Repaint each line which contains highlighted text.
* If on==0, force all hilites off. * If on==0, force all hilites off.
*/ */
public void public void repaint_hilite(int on)
repaint_hilite(on)
int on;
{ {
int sindex; int sindex;
POSITION pos; POSITION pos;
@ -284,6 +273,7 @@ repaint_hilite(on)
continue; continue;
(void) forw_line(pos); (void) forw_line(pos);
goto_line(sindex); goto_line(sindex);
clear_eol();
put_line(); put_line();
} }
overlay_header(); overlay_header();
@ -295,8 +285,7 @@ repaint_hilite(on)
/* /*
* Clear the attn hilite. * Clear the attn hilite.
*/ */
public void public void clear_attn(void)
clear_attn(VOID_PARAM)
{ {
#if HILITE_SEARCH #if HILITE_SEARCH
int sindex; int sindex;
@ -331,6 +320,7 @@ clear_attn(VOID_PARAM)
{ {
(void) forw_line(pos); (void) forw_line(pos);
goto_line(sindex); goto_line(sindex);
clear_eol();
put_line(); put_line();
moved = 1; moved = 1;
} }
@ -345,9 +335,7 @@ clear_attn(VOID_PARAM)
/* /*
* Toggle or clear search string highlighting. * Toggle or clear search string highlighting.
*/ */
public void public void undo_search(int clear)
undo_search(clear)
int clear;
{ {
clear_pattern(&search_info); clear_pattern(&search_info);
#if HILITE_SEARCH #if HILITE_SEARCH
@ -371,9 +359,7 @@ undo_search(clear)
/* /*
* Clear the hilite list. * Clear the hilite list.
*/ */
public void public void clr_hlist(struct hilite_tree *anchor)
clr_hlist(anchor)
struct hilite_tree *anchor;
{ {
struct hilite_storage *hls; struct hilite_storage *hls;
struct hilite_storage *nexthls; struct hilite_storage *nexthls;
@ -393,52 +379,23 @@ clr_hlist(anchor)
prep_startpos = prep_endpos = NULL_POSITION; prep_startpos = prep_endpos = NULL_POSITION;
} }
public void public void clr_hilite(void)
clr_hilite(VOID_PARAM)
{ {
clr_hlist(&hilite_anchor); clr_hlist(&hilite_anchor);
} }
public void public void clr_filter(void)
clr_filter(VOID_PARAM)
{ {
clr_hlist(&filter_anchor); clr_hlist(&filter_anchor);
} }
struct hilite_node*
hlist_last(anchor)
struct hilite_tree *anchor;
{
struct hilite_node *n = anchor->root;
while (n != NULL && n->right != NULL)
n = n->right;
return n;
}
struct hilite_node*
hlist_next(n)
struct hilite_node *n;
{
return n->next;
}
struct hilite_node*
hlist_prev(n)
struct hilite_node *n;
{
return n->prev;
}
/* /*
* Find the node covering pos, or the node after it if no node covers it, * Find the node covering pos, or the node after it if no node covers it,
* or return NULL if pos is after the last range. Remember the found node, * or return NULL if pos is after the last range. Remember the found node,
* to speed up subsequent searches for the same or similar positions (if * to speed up subsequent searches for the same or similar positions (if
* we return NULL, remember the last node.) * we return NULL, remember the last node.)
*/ */
struct hilite_node* static struct hilite_node* hlist_find(struct hilite_tree *anchor, POSITION pos)
hlist_find(anchor, pos)
struct hilite_tree *anchor;
POSITION pos;
{ {
struct hilite_node *n, *m; struct hilite_node *n, *m;
@ -528,21 +485,20 @@ hlist_find(anchor, pos)
/* /*
* Should any characters in a specified range be highlighted? * Should any characters in a specified range be highlighted?
*/ */
static int static int hilited_range_attr(POSITION pos, POSITION epos)
is_hilited_range(pos, epos)
POSITION pos;
POSITION epos;
{ {
struct hilite_node *n = hlist_find(&hilite_anchor, pos); struct hilite_node *n = hlist_find(&hilite_anchor, pos);
return (n != NULL && (epos == NULL_POSITION || epos > n->r.hl_startpos)); if (n == NULL)
return 0;
if (epos != NULL_POSITION && epos <= n->r.hl_startpos)
return 0;
return n->r.hl_attr;
} }
/* /*
* Is a line "filtered" -- that is, should it be hidden? * Is a line "filtered" -- that is, should it be hidden?
*/ */
public int public int is_filtered(POSITION pos)
is_filtered(pos)
POSITION pos;
{ {
struct hilite_node *n; struct hilite_node *n;
@ -557,9 +513,7 @@ is_filtered(pos)
* If pos is hidden, return the next position which isn't, otherwise * If pos is hidden, return the next position which isn't, otherwise
* just return pos. * just return pos.
*/ */
public POSITION public POSITION next_unfiltered(POSITION pos)
next_unfiltered(pos)
POSITION pos;
{ {
struct hilite_node *n; struct hilite_node *n;
@ -579,9 +533,7 @@ next_unfiltered(pos)
* If pos is hidden, return the previous position which isn't or 0 if * If pos is hidden, return the previous position which isn't or 0 if
* we're filtered right to the beginning, otherwise just return pos. * we're filtered right to the beginning, otherwise just return pos.
*/ */
public POSITION public POSITION prev_unfiltered(POSITION pos)
prev_unfiltered(pos)
POSITION pos;
{ {
struct hilite_node *n; struct hilite_node *n;
@ -605,14 +557,9 @@ prev_unfiltered(pos)
* Should any characters in a specified range be highlighted? * Should any characters in a specified range be highlighted?
* If nohide is nonzero, don't consider hide_hilite. * If nohide is nonzero, don't consider hide_hilite.
*/ */
public int public int is_hilited_attr(POSITION pos, POSITION epos, int nohide, int *p_matches)
is_hilited_attr(pos, epos, nohide, p_matches)
POSITION pos;
POSITION epos;
int nohide;
int *p_matches;
{ {
int match; int attr;
if (p_matches != NULL) if (p_matches != NULL)
*p_matches = 0; *p_matches = 0;
@ -626,8 +573,8 @@ is_hilited_attr(pos, epos, nohide, p_matches)
*/ */
return (AT_HILITE|AT_COLOR_ATTN); return (AT_HILITE|AT_COLOR_ATTN);
match = is_hilited_range(pos, epos); attr = hilited_range_attr(pos, epos);
if (!match) if (attr == 0)
return (0); return (0);
if (p_matches == NULL) if (p_matches == NULL)
@ -636,7 +583,7 @@ is_hilited_attr(pos, epos, nohide, p_matches)
* hilite in status column. In this case we want to return * hilite in status column. In this case we want to return
* hilite status even if hiliting is disabled or hidden. * hilite status even if hiliting is disabled or hidden.
*/ */
return (AT_HILITE|AT_COLOR_SEARCH); return (attr);
/* /*
* Report matches, even if we're hiding highlights. * Report matches, even if we're hiding highlights.
@ -655,16 +602,14 @@ is_hilited_attr(pos, epos, nohide, p_matches)
*/ */
return (0); return (0);
return (AT_HILITE|AT_COLOR_SEARCH); return (attr);
} }
/* /*
* Tree node storage: get the current block of nodes if it has spare * Tree node storage: get the current block of nodes if it has spare
* capacity, or create a new one if not. * capacity, or create a new one if not.
*/ */
static struct hilite_storage* static struct hilite_storage * hlist_getstorage(struct hilite_tree *anchor)
hlist_getstorage(anchor)
struct hilite_tree *anchor;
{ {
int capacity = 1; int capacity = 1;
struct hilite_storage *s; struct hilite_storage *s;
@ -693,9 +638,7 @@ hlist_getstorage(anchor)
* Tree node storage: retrieve a new empty node to be inserted into the * Tree node storage: retrieve a new empty node to be inserted into the
* tree. * tree.
*/ */
static struct hilite_node* static struct hilite_node * hlist_getnode(struct hilite_tree *anchor)
hlist_getnode(anchor)
struct hilite_tree *anchor;
{ {
struct hilite_storage *s = hlist_getstorage(anchor); struct hilite_storage *s = hlist_getstorage(anchor);
return &s->nodes[s->used++]; return &s->nodes[s->used++];
@ -704,10 +647,7 @@ hlist_getnode(anchor)
/* /*
* Rotate the tree left around a pivot node. * Rotate the tree left around a pivot node.
*/ */
static void static void hlist_rotate_left(struct hilite_tree *anchor, struct hilite_node *n)
hlist_rotate_left(anchor, n)
struct hilite_tree *anchor;
struct hilite_node *n;
{ {
struct hilite_node *np = n->parent; struct hilite_node *np = n->parent;
struct hilite_node *nr = n->right; struct hilite_node *nr = n->right;
@ -735,10 +675,7 @@ hlist_rotate_left(anchor, n)
/* /*
* Rotate the tree right around a pivot node. * Rotate the tree right around a pivot node.
*/ */
static void static void hlist_rotate_right(struct hilite_tree *anchor, struct hilite_node *n)
hlist_rotate_right(anchor, n)
struct hilite_tree *anchor;
struct hilite_node *n;
{ {
struct hilite_node *np = n->parent; struct hilite_node *np = n->parent;
struct hilite_node *nl = n->left; struct hilite_node *nl = n->left;
@ -767,10 +704,7 @@ hlist_rotate_right(anchor, n)
/* /*
* Add a new hilite to a hilite list. * Add a new hilite to a hilite list.
*/ */
static void static void add_hilite(struct hilite_tree *anchor, struct hilite *hl)
add_hilite(anchor, hl)
struct hilite_tree *anchor;
struct hilite *hl;
{ {
struct hilite_node *p, *n, *u; struct hilite_node *p, *n, *u;
@ -799,7 +733,7 @@ add_hilite(anchor, hl)
{ {
if (hl->hl_startpos < p->r.hl_startpos) if (hl->hl_startpos < p->r.hl_startpos)
{ {
if (hl->hl_endpos > p->r.hl_startpos) if (hl->hl_endpos > p->r.hl_startpos && hl->hl_attr == p->r.hl_attr)
hl->hl_endpos = p->r.hl_startpos; hl->hl_endpos = p->r.hl_startpos;
if (p->left != NULL) if (p->left != NULL)
{ {
@ -808,7 +742,7 @@ add_hilite(anchor, hl)
} }
break; break;
} }
if (hl->hl_startpos < p->r.hl_endpos) { if (hl->hl_startpos < p->r.hl_endpos && hl->hl_attr == p->r.hl_attr) {
hl->hl_startpos = p->r.hl_endpos; hl->hl_startpos = p->r.hl_endpos;
if (hl->hl_startpos >= hl->hl_endpos) if (hl->hl_startpos >= hl->hl_endpos)
return; return;
@ -827,17 +761,19 @@ add_hilite(anchor, hl)
* insertion. Otherwise insert a new node at the leaf. * insertion. Otherwise insert a new node at the leaf.
*/ */
if (hl->hl_startpos < p->r.hl_startpos) { if (hl->hl_startpos < p->r.hl_startpos) {
if (hl->hl_endpos == p->r.hl_startpos) if (hl->hl_attr == p->r.hl_attr)
{ {
p->r.hl_startpos = hl->hl_startpos; if (hl->hl_endpos == p->r.hl_startpos)
return; {
p->r.hl_startpos = hl->hl_startpos;
return;
}
if (p->prev != NULL && p->prev->r.hl_endpos == hl->hl_startpos)
{
p->prev->r.hl_endpos = hl->hl_endpos;
return;
}
} }
if (p->prev != NULL && p->prev->r.hl_endpos == hl->hl_startpos)
{
p->prev->r.hl_endpos = hl->hl_endpos;
return;
}
p->left = n = hlist_getnode(anchor); p->left = n = hlist_getnode(anchor);
n->next = p; n->next = p;
if (p->prev != NULL) if (p->prev != NULL)
@ -847,16 +783,18 @@ add_hilite(anchor, hl)
} }
p->prev = n; p->prev = n;
} else { } else {
if (p->r.hl_endpos == hl->hl_startpos) if (hl->hl_attr == p->r.hl_attr)
{ {
p->r.hl_endpos = hl->hl_endpos; if (p->r.hl_endpos == hl->hl_startpos)
return; {
p->r.hl_endpos = hl->hl_endpos;
return;
}
if (p->next != NULL && hl->hl_endpos == p->next->r.hl_startpos) {
p->next->r.hl_startpos = hl->hl_startpos;
return;
}
} }
if (p->next != NULL && hl->hl_endpos == p->next->r.hl_startpos) {
p->next->r.hl_startpos = hl->hl_startpos;
return;
}
p->right = n = hlist_getnode(anchor); p->right = n = hlist_getnode(anchor);
n->prev = p; n->prev = p;
if (p->next != NULL) if (p->next != NULL)
@ -946,18 +884,16 @@ add_hilite(anchor, hl)
/* /*
* Highlight every character in a range of displayed characters. * Highlight every character in a range of displayed characters.
*/ */
static void static void create_hilites(POSITION linepos, char *line, char *sp, char *ep, int attr, int *chpos)
create_hilites(linepos, start_index, end_index, chpos)
POSITION linepos;
int start_index;
int end_index;
int *chpos;
{ {
int start_index = sp - line;
int end_index = ep - line;
struct hilite hl; struct hilite hl;
int i; int i;
/* Start the first hilite. */ /* Start the first hilite. */
hl.hl_startpos = linepos + chpos[start_index]; hl.hl_startpos = linepos + chpos[start_index];
hl.hl_attr = attr;
/* /*
* Step through the displayed chars. * Step through the displayed chars.
@ -987,21 +923,13 @@ create_hilites(linepos, start_index, end_index, chpos)
* the current pattern. * the current pattern.
* sp,ep delimit the first match already found. * sp,ep delimit the first match already found.
*/ */
static void static void hilite_line(POSITION linepos, char *line, int line_len, int *chpos, char **sp, char **ep, int nsp, int cvt_ops)
hilite_line(linepos, line, line_len, chpos, sp, ep, cvt_ops)
POSITION linepos;
char *line;
int line_len;
int *chpos;
char *sp;
char *ep;
int cvt_ops;
{ {
char *searchp; char *searchp;
char *line_end = line + line_len; char *line_end = line + line_len;
/* /*
* sp and ep delimit the first match in the line. * sp[0] and ep[0] delimit the first match in the line.
* Mark the corresponding file positions, then * Mark the corresponding file positions, then
* look for further matches and mark them. * look for further matches and mark them.
* {{ This technique, of calling match_pattern on subsequent * {{ This technique, of calling match_pattern on subsequent
@ -1009,25 +937,42 @@ hilite_line(linepos, line, line_len, chpos, sp, ep, cvt_ops)
* if the pattern starts with "^". This bug is fixed * if the pattern starts with "^". This bug is fixed
* for those regex functions that accept a notbol parameter * for those regex functions that accept a notbol parameter
* (currently POSIX, PCRE and V8-with-regexec2). }} * (currently POSIX, PCRE and V8-with-regexec2). }}
* sp[i] and ep[i] for i>0 delimit subpattern matches.
* Color each of them with its unique color.
*/ */
searchp = line; searchp = line;
do { do {
if (sp == NULL || ep == NULL) char *lep = sp[0];
return; int i;
create_hilites(linepos, sp-line, ep-line, chpos); for (i = 1; i < nsp; i++)
{
if (sp[i] == NULL || ep[i] == NULL)
break;
if (ep[i] > sp[i])
{
create_hilites(linepos, line, lep, sp[i],
AT_HILITE | AT_COLOR_SEARCH, chpos);
create_hilites(linepos, line, sp[i], ep[i],
AT_HILITE | AT_COLOR_SUBSEARCH(i), chpos);
lep = ep[i];
}
}
create_hilites(linepos, line, lep, ep[0],
AT_HILITE | AT_COLOR_SEARCH, chpos);
/* /*
* If we matched more than zero characters, * If we matched more than zero characters,
* move to the first char after the string we matched. * move to the first char after the string we matched.
* If we matched zero, just move to the next char. * If we matched zero, just move to the next char.
*/ */
if (ep > searchp) if (ep[0] > searchp)
searchp = ep; searchp = ep[0];
else if (searchp != line_end) else if (searchp != line_end)
searchp++; searchp++;
else /* end of line */ else /* end of line */
break; break;
} while (match_pattern(info_compiled(&search_info), search_info.text, } while (match_pattern(info_compiled(&search_info), search_info.text,
searchp, line_end - searchp, &sp, &ep, 1, search_info.search_type)); searchp, line_end - searchp, sp, ep, nsp, 1, search_info.search_type));
} }
#endif #endif
@ -1035,8 +980,7 @@ hilite_line(linepos, line, line_len, chpos, sp, ep, cvt_ops)
/* /*
* Find matching text which is currently on screen and highlight it. * Find matching text which is currently on screen and highlight it.
*/ */
static void static void hilite_screen(void)
hilite_screen(VOID_PARAM)
{ {
struct scrpos scrpos; struct scrpos scrpos;
@ -1050,8 +994,7 @@ hilite_screen(VOID_PARAM)
/* /*
* Change highlighting parameters. * Change highlighting parameters.
*/ */
public void public void chg_hilite(void)
chg_hilite(VOID_PARAM)
{ {
/* /*
* Erase any highlights currently on screen. * Erase any highlights currently on screen.
@ -1070,9 +1013,7 @@ chg_hilite(VOID_PARAM)
/* /*
* Figure out where to start a search. * Figure out where to start a search.
*/ */
static POSITION static POSITION search_pos(int search_type)
search_pos(search_type)
int search_type;
{ {
POSITION pos; POSITION pos;
int sindex; int sindex;
@ -1165,22 +1106,14 @@ search_pos(search_type)
* If so, add an entry to the filter list. * If so, add an entry to the filter list.
*/ */
#if HILITE_SEARCH #if HILITE_SEARCH
static int static int matches_filters(POSITION pos, char *cline, int line_len, int *chpos, POSITION linepos, char **sp, char **ep, int nsp)
matches_filters(pos, cline, line_len, chpos, linepos, sp, ep)
POSITION pos;
char *cline;
int line_len;
int *chpos;
POSITION linepos;
char **sp;
char **ep;
{ {
struct pattern_info *filter; struct pattern_info *filter;
for (filter = filter_infos; filter != NULL; filter = filter->next) for (filter = filter_infos; filter != NULL; filter = filter->next)
{ {
int line_filter = match_pattern(info_compiled(filter), filter->text, int line_filter = match_pattern(info_compiled(filter), filter->text,
cline, line_len, sp, ep, 0, filter->search_type); cline, line_len, sp, ep, nsp, 0, filter->search_type);
if (line_filter) if (line_filter)
{ {
struct hilite hl; struct hilite hl;
@ -1200,11 +1133,7 @@ matches_filters(pos, cline, line_len, chpos, linepos, sp, ep)
* Get the position of the first char in the screen line which * Get the position of the first char in the screen line which
* puts tpos on screen. * puts tpos on screen.
*/ */
static POSITION static POSITION get_lastlinepos(POSITION pos, POSITION tpos, int sheight)
get_lastlinepos(pos, tpos, sheight)
POSITION pos;
POSITION tpos;
int sheight;
{ {
int nlines; int nlines;
@ -1225,10 +1154,7 @@ get_lastlinepos(pos, tpos, sheight)
* Get the segment index of tpos in the line starting at pos. * Get the segment index of tpos in the line starting at pos.
* A segment is a string of printable chars that fills the screen width. * A segment is a string of printable chars that fills the screen width.
*/ */
static int static int get_seg(POSITION pos, POSITION tpos)
get_seg(pos, tpos)
POSITION pos;
POSITION tpos;
{ {
int seg; int seg;
@ -1244,31 +1170,32 @@ get_seg(pos, tpos)
/* /*
* Search a subset of the file, specified by start/end position. * Search a subset of the file, specified by start/end position.
*/ */
static int static int search_range(POSITION pos, POSITION endpos, int search_type, int matches, int maxlines, POSITION *plinepos, POSITION *pendpos, POSITION *plastlinepos)
search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos, plastlinepos)
POSITION pos;
POSITION endpos;
int search_type;
int matches;
int maxlines;
POSITION *plinepos;
POSITION *pendpos;
POSITION *plastlinepos;
{ {
char *line; char *line;
char *cline; char *cline;
int line_len; int line_len;
LINENUM linenum; LINENUM linenum;
char *sp, *ep; #define NSP (NUM_SEARCH_COLORS+2)
char *sp[NSP];
char *ep[NSP];
int line_match; int line_match;
int cvt_ops; int cvt_ops;
int cvt_len; int cvt_len;
int *chpos; int *chpos;
POSITION linepos, oldpos; POSITION linepos, oldpos;
int skip_bytes = 0;
int swidth = sc_width - line_pfx_width(); int swidth = sc_width - line_pfx_width();
int sheight = sc_height - sindex_from_sline(jump_sline); int sheight = sc_height - sindex_from_sline(jump_sline);
linenum = find_linenum(pos); linenum = find_linenum(pos);
if (nosearch_headers && linenum <= header_lines)
{
linenum = header_lines + 1;
pos = find_pos(linenum);
}
if (pos == NULL_POSITION)
return (-1);
oldpos = pos; oldpos = pos;
/* When the search wraps around, end at starting position. */ /* When the search wraps around, end at starting position. */
if ((search_type & SRCH_WRAP) && endpos == NULL_POSITION) if ((search_type & SRCH_WRAP) && endpos == NULL_POSITION)
@ -1379,12 +1306,14 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos, pla
if (is_filtered(linepos)) if (is_filtered(linepos))
continue; continue;
#endif #endif
if (nosearch_headers)
skip_bytes = skip_columns(header_cols, &line, &line_len);
/* /*
* If it's a caseless search, convert the line to lowercase. * If it's a caseless search, convert the line to lowercase.
* If we're doing backspace processing, delete backspaces. * If we're doing backspace processing, delete backspaces.
*/ */
cvt_ops = get_cvt_ops(); cvt_ops = get_cvt_ops(search_type);
cvt_len = cvt_length(line_len, cvt_ops); cvt_len = cvt_length(line_len, cvt_ops);
cline = (char *) ecalloc(1, cvt_len); cline = (char *) ecalloc(1, cvt_len);
chpos = cvt_alloc_chpos(cvt_len); chpos = cvt_alloc_chpos(cvt_len);
@ -1398,7 +1327,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos, pla
((search_type & SRCH_FIND_ALL) || ((search_type & SRCH_FIND_ALL) ||
prep_startpos == NULL_POSITION || prep_startpos == NULL_POSITION ||
linepos < prep_startpos || linepos >= prep_endpos)) { linepos < prep_startpos || linepos >= prep_endpos)) {
if (matches_filters(pos, cline, line_len, chpos, linepos, &sp, &ep)) if (matches_filters(pos, cline, line_len, chpos, linepos, sp, ep, NSP))
continue; continue;
} }
#endif #endif
@ -1411,7 +1340,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos, pla
if (prev_pattern(&search_info)) if (prev_pattern(&search_info))
{ {
line_match = match_pattern(info_compiled(&search_info), search_info.text, line_match = match_pattern(info_compiled(&search_info), search_info.text,
cline, line_len, &sp, &ep, 0, search_type); cline, line_len, sp, ep, NSP, 0, search_type);
if (line_match) if (line_match)
{ {
/* /*
@ -1425,7 +1354,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos, pla
* Just add the matches in this line to the * Just add the matches in this line to the
* hilite list and keep searching. * hilite list and keep searching.
*/ */
hilite_line(linepos, cline, line_len, chpos, sp, ep, cvt_ops); hilite_line(linepos + skip_bytes, cline, line_len, chpos, sp, ep, NSP, cvt_ops);
#endif #endif
} else if (--matches <= 0) } else if (--matches <= 0)
{ {
@ -1441,7 +1370,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos, pla
* the matches in this one line. * the matches in this one line.
*/ */
clr_hilite(); clr_hilite();
hilite_line(linepos, cline, line_len, chpos, sp, ep, cvt_ops); hilite_line(linepos + skip_bytes, cline, line_len, chpos, sp, ep, NSP, cvt_ops);
} }
#endif #endif
if (chop_line()) if (chop_line())
@ -1450,10 +1379,10 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos, pla
* If necessary, shift horizontally to make sure * If necessary, shift horizontally to make sure
* search match is fully visible. * search match is fully visible.
*/ */
if (sp != NULL && ep != NULL) if (sp[0] != NULL && ep[0] != NULL)
{ {
int start_off = sp - cline; int start_off = sp[0] - cline;
int end_off = ep - cline; int end_off = ep[0] - cline;
int save_hshift = hshift; int save_hshift = hshift;
int sshift; int sshift;
int eshift; int eshift;
@ -1479,9 +1408,9 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos, pla
* of the match appears in the last line on the screen. * of the match appears in the last line on the screen.
* lastlinepos is the position of the first char of that last line. * lastlinepos is the position of the first char of that last line.
*/ */
if (ep != NULL) if (ep[0] != NULL)
{ {
int end_off = ep - cline; int end_off = ep[0] - cline;
if (end_off >= swidth * sheight / 4) /* heuristic */ if (end_off >= swidth * sheight / 4) /* heuristic */
*plastlinepos = get_lastlinepos(linepos, linepos + chpos[end_off], sheight); *plastlinepos = get_lastlinepos(linepos, linepos + chpos[end_off], sheight);
} }
@ -1502,9 +1431,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos, pla
/* /*
* search for a pattern in history. If found, compile that pattern. * search for a pattern in history. If found, compile that pattern.
*/ */
static int static int hist_pattern(int search_type)
hist_pattern(search_type)
int search_type;
{ {
#if CMD_HISTORY #if CMD_HISTORY
char *pattern; char *pattern;
@ -1532,10 +1459,9 @@ hist_pattern(search_type)
* Change the caseless-ness of searches. * Change the caseless-ness of searches.
* Updates the internal search state to reflect a change in the -i flag. * Updates the internal search state to reflect a change in the -i flag.
*/ */
public void public void chg_caseless(void)
chg_caseless(VOID_PARAM)
{ {
if (!is_ucase_pattern) if (!search_info.is_ucase_pattern)
{ {
/* /*
* Pattern did not have uppercase. * Pattern did not have uppercase.
@ -1566,11 +1492,7 @@ chg_caseless(VOID_PARAM)
* Caller may continue the search in another file * Caller may continue the search in another file
* if less than n matches are found in this file. * if less than n matches are found in this file.
*/ */
public int public int search(int search_type, char *pattern, int n)
search(search_type, pattern, n)
int search_type;
char *pattern;
int n;
{ {
POSITION pos; POSITION pos;
POSITION opos; POSITION opos;
@ -1715,11 +1637,7 @@ search(search_type, pattern, n)
* If prep_endpos == NULL_POSITION, the prep region extends to EOF. * If prep_endpos == NULL_POSITION, the prep region extends to EOF.
* prep_hilite asks that the range (spos,epos) be covered by the prep region. * prep_hilite asks that the range (spos,epos) be covered by the prep region.
*/ */
public void public void prep_hilite(POSITION spos, POSITION epos, int maxlines)
prep_hilite(spos, epos, maxlines)
POSITION spos;
POSITION epos;
int maxlines;
{ {
POSITION nprep_startpos = prep_startpos; POSITION nprep_startpos = prep_startpos;
POSITION nprep_endpos = prep_endpos; POSITION nprep_endpos = prep_endpos;
@ -1834,7 +1752,7 @@ prep_hilite(spos, epos, maxlines)
if (epos == NULL_POSITION || epos > spos) if (epos == NULL_POSITION || epos > spos)
{ {
int search_type = SRCH_FORW | SRCH_FIND_ALL; int search_type = SRCH_FORW | SRCH_FIND_ALL;
search_type |= (search_info.search_type & SRCH_NO_REGEX); search_type |= (search_info.search_type & (SRCH_NO_REGEX|SRCH_SUBSEARCH_ALL));
for (;;) for (;;)
{ {
result = search_range(spos, epos, search_type, 0, maxlines, (POSITION*)NULL, &new_epos, (POSITION*)NULL); result = search_range(spos, epos, search_type, 0, maxlines, (POSITION*)NULL, &new_epos, (POSITION*)NULL);
@ -1885,10 +1803,7 @@ prep_hilite(spos, epos, maxlines)
/* /*
* Set the pattern to be used for line filtering. * Set the pattern to be used for line filtering.
*/ */
public void public void set_filter_pattern(char *pattern, int search_type)
set_filter_pattern(pattern, search_type)
char *pattern;
int search_type;
{ {
struct pattern_info *filter; struct pattern_info *filter;
@ -1923,8 +1838,7 @@ set_filter_pattern(pattern, search_type)
/* /*
* Is there a line filter in effect? * Is there a line filter in effect?
*/ */
public int public int is_filtering(void)
is_filtering(VOID_PARAM)
{ {
if (ch_getflags() & CH_HELPFILE) if (ch_getflags() & CH_HELPFILE)
return (0); return (0);
@ -1939,9 +1853,7 @@ is_filtering(VOID_PARAM)
*/ */
public int reg_show_error = 1; public int reg_show_error = 1;
void void regerror(char *s)
regerror(s)
char *s;
{ {
PARG parg; PARG parg;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -44,9 +44,7 @@ extern int less_is_more;
*/ */
#if MSDOS_COMPILER!=WIN32C #if MSDOS_COMPILER!=WIN32C
/* ARGSUSED*/ /* ARGSUSED*/
static RETSIGTYPE static RETSIGTYPE u_interrupt(int type)
u_interrupt(type)
int type;
{ {
bell(); bell();
#if OS2 #if OS2
@ -78,9 +76,7 @@ u_interrupt(type)
* "Stop" (^Z) signal handler. * "Stop" (^Z) signal handler.
*/ */
/* ARGSUSED*/ /* ARGSUSED*/
static RETSIGTYPE static RETSIGTYPE stop(int type)
stop(type)
int type;
{ {
LSIGNAL(SIGTSTP, stop); LSIGNAL(SIGTSTP, stop);
sigs |= S_STOP; sigs |= S_STOP;
@ -103,9 +99,7 @@ stop(type)
* "Window" change handler * "Window" change handler
*/ */
/* ARGSUSED*/ /* ARGSUSED*/
public RETSIGTYPE public RETSIGTYPE winch(int type)
winch(type)
int type;
{ {
LSIGNAL(SIG_LESSWINDOW, winch); LSIGNAL(SIG_LESSWINDOW, winch);
sigs |= S_WINCH; sigs |= S_WINCH;
@ -121,9 +115,7 @@ winch(type)
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
static BOOL WINAPI static BOOL WINAPI wbreak_handler(DWORD dwCtrlType)
wbreak_handler(dwCtrlType)
DWORD dwCtrlType;
{ {
switch (dwCtrlType) switch (dwCtrlType)
{ {
@ -141,9 +133,7 @@ wbreak_handler(dwCtrlType)
} }
#endif #endif
static RETSIGTYPE static RETSIGTYPE terminate(int type)
terminate(type)
int type;
{ {
quit(15); quit(15);
} }
@ -151,9 +141,7 @@ terminate(type)
/* /*
* Set up the signal handlers. * Set up the signal handlers.
*/ */
public void public void init_signals(int on)
init_signals(on)
int on;
{ {
if (on) if (on)
{ {
@ -212,8 +200,7 @@ init_signals(on)
* Process any signals we have received. * Process any signals we have received.
* A received signal cause a bit to be set in "sigs". * A received signal cause a bit to be set in "sigs".
*/ */
public void public void psignals(void)
psignals(VOID_PARAM)
{ {
int tsignals; int tsignals;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -44,13 +44,13 @@ enum {
T_GPATH /* 'GPATH': path name (global) */ T_GPATH /* 'GPATH': path name (global) */
}; };
static enum tag_result findctag LESSPARAMS((char *tag)); static enum tag_result findctag(char *tag);
static enum tag_result findgtag LESSPARAMS((char *tag, int type)); static enum tag_result findgtag(char *tag, int type);
static char *nextgtag(VOID_PARAM); static char *nextgtag(void);
static char *prevgtag(VOID_PARAM); static char *prevgtag(void);
static POSITION ctagsearch(VOID_PARAM); static POSITION ctagsearch(void);
static POSITION gtagsearch(VOID_PARAM); static POSITION gtagsearch(void);
static int getentry LESSPARAMS((char *buf, char **tag, char **file, char **line)); static int getentry(char *buf, char **tag, char **file, char **line);
/* /*
* The list of tags generated by the last findgtag() call. * The list of tags generated by the last findgtag() call.
@ -88,8 +88,7 @@ static struct tag *curtag;
/* /*
* Delete tag structures. * Delete tag structures.
*/ */
public void public void cleantags(void)
cleantags(VOID_PARAM)
{ {
struct tag *tp; struct tag *tp;
@ -112,13 +111,7 @@ cleantags(VOID_PARAM)
/* /*
* Create a new tag entry. * Create a new tag entry.
*/ */
static struct tag * static struct tag * maketagent(char *name, char *file, LINENUM linenum, char *pattern, int endline)
maketagent(name, file, linenum, pattern, endline)
char *name;
char *file;
LINENUM linenum;
char *pattern;
int endline;
{ {
struct tag *tp; struct tag *tp;
@ -140,8 +133,7 @@ maketagent(name, file, linenum, pattern, endline)
/* /*
* Get tag mode. * Get tag mode.
*/ */
public int public int gettagtype(void)
gettagtype(VOID_PARAM)
{ {
int f; int f;
@ -171,9 +163,7 @@ gettagtype(VOID_PARAM)
* and "tagpattern" to the search pattern which should be used * and "tagpattern" to the search pattern which should be used
* to find the tag. * to find the tag.
*/ */
public void public void findtag(char *tag)
findtag(tag)
char *tag;
{ {
int type = gettagtype(); int type = gettagtype();
enum tag_result result; enum tag_result result;
@ -202,8 +192,7 @@ findtag(tag)
/* /*
* Search for a tag. * Search for a tag.
*/ */
public POSITION public POSITION tagsearch(void)
tagsearch(VOID_PARAM)
{ {
if (curtag == NULL) if (curtag == NULL)
return (NULL_POSITION); /* No gtags loaded! */ return (NULL_POSITION); /* No gtags loaded! */
@ -216,9 +205,7 @@ tagsearch(VOID_PARAM)
/* /*
* Go to the next tag. * Go to the next tag.
*/ */
public char * public char * nexttag(int n)
nexttag(n)
int n;
{ {
char *tagfile = (char *) NULL; char *tagfile = (char *) NULL;
@ -230,9 +217,7 @@ nexttag(n)
/* /*
* Go to the previous tag. * Go to the previous tag.
*/ */
public char * public char * prevtag(int n)
prevtag(n)
int n;
{ {
char *tagfile = (char *) NULL; char *tagfile = (char *) NULL;
@ -244,8 +229,7 @@ prevtag(n)
/* /*
* Return the total number of tags. * Return the total number of tags.
*/ */
public int public int ntags(void)
ntags(VOID_PARAM)
{ {
return total; return total;
} }
@ -253,8 +237,7 @@ ntags(VOID_PARAM)
/* /*
* Return the sequence number of current tag. * Return the sequence number of current tag.
*/ */
public int public int curr_tag(void)
curr_tag(VOID_PARAM)
{ {
return curseq; return curseq;
} }
@ -267,9 +250,7 @@ curr_tag(VOID_PARAM)
* Find tags in the "tags" file. * Find tags in the "tags" file.
* Sets curtag to the first tag entry. * Sets curtag to the first tag entry.
*/ */
static enum tag_result static enum tag_result findctag(char *tag)
findctag(tag)
char *tag;
{ {
char *p; char *p;
char *q; char *q;
@ -387,18 +368,14 @@ findctag(tag)
/* /*
* Edit current tagged file. * Edit current tagged file.
*/ */
public int public int edit_tagfile(void)
edit_tagfile(VOID_PARAM)
{ {
if (curtag == NULL) if (curtag == NULL)
return (1); return (1);
return (edit(curtag->tag_file)); return (edit(curtag->tag_file));
} }
static int static int curtag_match(char constant *line, POSITION linepos)
curtag_match(line, linepos)
char constant *line;
POSITION linepos;
{ {
/* /*
* Test the line to see if we have a match. * Test the line to see if we have a match.
@ -426,8 +403,7 @@ curtag_match(line, linepos)
* regcmp vs. re_comp) behave differently in the presence of * regcmp vs. re_comp) behave differently in the presence of
* parentheses (which are almost always found in a tag). * parentheses (which are almost always found in a tag).
*/ */
static POSITION static POSITION ctagsearch(void)
ctagsearch(VOID_PARAM)
{ {
POSITION pos, linepos; POSITION pos, linepos;
LINENUM linenum; LINENUM linenum;
@ -505,10 +481,7 @@ ctagsearch(VOID_PARAM)
* for future use by gtagsearch(). * for future use by gtagsearch().
* Sets curtag to the first tag entry. * Sets curtag to the first tag entry.
*/ */
static enum tag_result static enum tag_result findgtag(char *tag, int type)
findgtag(tag, type)
char *tag; /* tag to load */
int type; /* tags type */
{ {
char buf[1024]; char buf[1024];
FILE *fp; FILE *fp;
@ -640,8 +613,7 @@ static int circular = 0; /* 1: circular tag structure */
* by findgtag(). The next call to gtagsearch() will try to position at the * by findgtag(). The next call to gtagsearch() will try to position at the
* appropriate tag. * appropriate tag.
*/ */
static char * static char * nextgtag(void)
nextgtag(VOID_PARAM)
{ {
struct tag *tp; struct tag *tp;
@ -670,8 +642,7 @@ nextgtag(VOID_PARAM)
* setup by findgtat(). The next call to gtagsearch() will try to position * setup by findgtat(). The next call to gtagsearch() will try to position
* at the appropriate tag. * at the appropriate tag.
*/ */
static char * static char * prevgtag(void)
prevgtag(VOID_PARAM)
{ {
struct tag *tp; struct tag *tp;
@ -700,8 +671,7 @@ prevgtag(VOID_PARAM)
* using either findtag() or one of nextgtag() and prevgtag(). Returns -1 * using either findtag() or one of nextgtag() and prevgtag(). Returns -1
* if it was unable to position at the tag, 0 if successful. * if it was unable to position at the tag, 0 if successful.
*/ */
static POSITION static POSITION gtagsearch(void)
gtagsearch(VOID_PARAM)
{ {
if (curtag == NULL) if (curtag == NULL)
return (NULL_POSITION); /* No gtags loaded! */ return (NULL_POSITION); /* No gtags loaded! */
@ -736,12 +706,7 @@ gtagsearch(VOID_PARAM)
* The tag, file, and line will each be NUL-terminated pointers * The tag, file, and line will each be NUL-terminated pointers
* into buf. * into buf.
*/ */
static int static int getentry(char *buf, char **tag, char **file, char **line)
getentry(buf, tag, file, line)
char *buf; /* standard or extended ctags -x format data */
char **tag; /* name of the tag we actually found */
char **file; /* file in which to find this tag */
char **line; /* line number of file where this tag is found */
{ {
char *p = buf; char *p = buf;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -30,16 +30,13 @@ public int tty;
#endif #endif
#if LESSTEST #if LESSTEST
public char *ttyin_name = NULL; public char *ttyin_name = NULL;
public int rstat_file = -1;
#endif /*LESSTEST*/ #endif /*LESSTEST*/
extern int sigs; extern int sigs;
extern int utf_mode; extern int utf_mode;
extern int wheel_lines; extern int wheel_lines;
#if !MSDOS_COMPILER #if !MSDOS_COMPILER
static int static int open_tty_device(constant char* dev)
open_tty_device(dev)
constant char* dev;
{ {
#if OS2 #if OS2
/* The __open() system call translates "/dev/tty" to "con". */ /* The __open() system call translates "/dev/tty" to "con". */
@ -55,8 +52,7 @@ open_tty_device(dev)
* In Unix, file descriptor 2 is usually attached to the screen, * In Unix, file descriptor 2 is usually attached to the screen,
* but also usually lets you read from the keyboard. * but also usually lets you read from the keyboard.
*/ */
public int public int open_tty(void)
open_tty(VOID_PARAM)
{ {
int fd = -1; int fd = -1;
#if LESSTEST #if LESSTEST
@ -82,8 +78,7 @@ open_tty(VOID_PARAM)
/* /*
* Open keyboard for input. * Open keyboard for input.
*/ */
public void public void open_getchr(void)
open_getchr(VOID_PARAM)
{ {
#if MSDOS_COMPILER==WIN32C #if MSDOS_COMPILER==WIN32C
/* Need this to let child processes inherit our console handle */ /* Need this to let child processes inherit our console handle */
@ -123,8 +118,7 @@ open_getchr(VOID_PARAM)
/* /*
* Close the keyboard. * Close the keyboard.
*/ */
public void public void close_getchr(void)
close_getchr(VOID_PARAM)
{ {
#if MSDOS_COMPILER==WIN32C #if MSDOS_COMPILER==WIN32C
SetConsoleMode(tty, console_mode); SetConsoleMode(tty, console_mode);
@ -136,9 +130,7 @@ close_getchr(VOID_PARAM)
/* /*
* Close the pipe, restoring the keyboard (CMD resets it, losing the mouse). * Close the pipe, restoring the keyboard (CMD resets it, losing the mouse).
*/ */
int public int pclose(FILE *f)
pclose(f)
FILE *f;
{ {
int result; int result;
@ -151,8 +143,7 @@ pclose(f)
/* /*
* Get the number of lines to scroll when mouse wheel is moved. * Get the number of lines to scroll when mouse wheel is moved.
*/ */
public int public int default_wheel_lines(void)
default_wheel_lines(VOID_PARAM)
{ {
int lines = 1; int lines = 1;
#if MSDOS_COMPILER==WIN32C #if MSDOS_COMPILER==WIN32C
@ -165,23 +156,10 @@ default_wheel_lines(VOID_PARAM)
return lines; return lines;
} }
#if LESSTEST
public void
rstat(st)
char st;
{
if (rstat_file < 0)
return;
lseek(rstat_file, SEEK_SET, 0);
write(rstat_file, &st, 1);
}
#endif /*LESSTEST*/
/* /*
* Get a character from the keyboard. * Get a character from the keyboard.
*/ */
public int public int getchr(void)
getchr(VOID_PARAM)
{ {
char c; char c;
int result; int result;
@ -204,17 +182,11 @@ getchr(VOID_PARAM)
if (c == '\003') if (c == '\003')
return (READ_INTR); return (READ_INTR);
#else #else
#if LESSTEST
rstat('R');
#endif /*LESSTEST*/
{ {
unsigned char uc; unsigned char uc;
result = iread(tty, &uc, sizeof(char)); result = iread(tty, &uc, sizeof(char));
c = (char) uc; c = (char) uc;
} }
#if LESSTEST
rstat('B');
#endif /*LESSTEST*/
if (result == READ_INTR) if (result == READ_INTR)
return (READ_INTR); return (READ_INTR);
if (result < 0) if (result < 0)
@ -226,6 +198,14 @@ getchr(VOID_PARAM)
quit(QUIT_ERROR); quit(QUIT_ERROR);
} }
#endif #endif
#if LESSTEST
if (c == LESS_DUMP_CHAR)
{
dump_screen();
result = 0;
continue;
}
#endif
#if 0 /* allow entering arbitrary hex chars for testing */ #if 0 /* allow entering arbitrary hex chars for testing */
/* ctrl-A followed by two hex chars makes a byte */ /* ctrl-A followed by two hex chars makes a byte */
{ {

View File

@ -1,17 +1,11 @@
/* Generated by "./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt" on Tue Jul 19 12:45:17 PDT 2022 */ /* Generated by "./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt" on Mon Nov 14 18:19:24 PST 2022 */
{ 0x0000, 0x0007 }, /* Cc */ { 0x0000, 0x0007 }, /* Cc */
{ 0x000b, 0x000b }, /* Cc */ { 0x000b, 0x000b }, /* Cc */
{ 0x000e, 0x001f }, /* Cc */ { 0x000e, 0x001f }, /* Cc */
{ 0x007f, 0x009f }, /* Cc */ { 0x007f, 0x009f }, /* Cc */
{ 0x2028, 0x2028 }, /* Zl */ { 0x2028, 0x2028 }, /* Zl */
{ 0x2029, 0x2029 }, /* Zp */ { 0x2029, 0x2029 }, /* Zp */
{ 0xd800, 0xd800 }, /* Cs */ { 0xd800, 0xdfff }, /* Cs */
{ 0xdb7f, 0xdb80 }, /* Cs */ { 0xe000, 0xf8ff }, /* Co */
{ 0xdbff, 0xdc00 }, /* Cs */ { 0xf0000, 0xffffd }, /* Co */
{ 0xdfff, 0xdfff }, /* Cs */ { 0x100000, 0x10fffd }, /* Co */
{ 0xe000, 0xe000 }, /* Co */
{ 0xf8ff, 0xf8ff }, /* Co */
{ 0xf0000, 0xf0000 }, /* Co */
{ 0xffffd, 0xffffd }, /* Co */
{ 0x100000, 0x100000 }, /* Co */
{ 0x10fffd, 0x10fffd }, /* Co */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2022 Mark Nudelman * Copyright (C) 1984-2023 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -954,6 +954,33 @@ v606 7/17/22 Fix bug with multibyte chars and --incsearch;
escape filenames in LESSCLOSE; fix bin_file overrun. escape filenames in LESSCLOSE; fix bin_file overrun.
v607 7/19/22 Update Unicode tables. v607 7/19/22 Update Unicode tables.
v608 7/22/22 Fix highlighting on colored text boundaries. v608 7/22/22 Fix highlighting on colored text boundaries.
v609 11/10/22 Add LESSUTFCHARDEF; fix overstrike color bug;
fix procfs bug; fix signal race.
v610 11/14/22 Update Unicode tables; fix again-search after filter;
improve ^X to interrupt F command.
v611 11/16/22 Fix EOF bug related to ^X change.
v612 11/18/22 Fix more bugs related to ^X change.
v613 11/28/22 Even more ^X issues.
v614 11/28/22 Add ^X to wait message.
v615 11/30/22 Add --no-vbell option.
v616 12/9/22 Don't open tty as input file without -f.
v617 12/10/22 Support poll on newer versions of MacOS.
v618 12/29/22 Add --no-search-headers option; use C89 function definitions.
v619 12/30/22 Fix bug using 'n' before '/'.
v620 1/12/23 Add --modelines option; add --intr option;
add subpattern coloring.
v621 1/15/23 Add --wordwrap option; add LESS_LINES & LESS_COLUMNS.
v622 1/27/23 Add --show-preproc-errors option.
v623 2/2/23 Add # command; add ^S search modifier.
v624 2/11/23 Add --proc-backspace, --proc-tab and --proc-return options.
v625 2/16/23 Minor fixes.
v626 2/19/23 Fix rare crash in add_attr_normal.
v627 2/19/23 Doc.
v628 2/20/23 Don't require newline after +&...
v629 2/26/23 Delay "waiting for data" message for 500 ms.
v630 3/18/23 Add LESS_DATA_DELAY.
v631 3/26/23 Fix input of dead keys on Windows.
v632 4/6/23 Make lesstest work on MacOS; minor fixes.
*/ */
char version[] = "608"; char version[] = "632";

View File

@ -1,4 +1,4 @@
/* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Tue Jul 19 12:45:19 PDT 2022 */ /* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Mon Nov 14 18:19:24 PST 2022 */
{ 0x1100, 0x115f }, /* W */ { 0x1100, 0x115f }, /* W */
{ 0x231a, 0x231b }, /* W */ { 0x231a, 0x231b }, /* W */
{ 0x2329, 0x232a }, /* W */ { 0x2329, 0x232a }, /* W */
@ -68,7 +68,9 @@
{ 0x1aff5, 0x1affb }, /* W */ { 0x1aff5, 0x1affb }, /* W */
{ 0x1affd, 0x1affe }, /* W */ { 0x1affd, 0x1affe }, /* W */
{ 0x1b000, 0x1b122 }, /* W */ { 0x1b000, 0x1b122 }, /* W */
{ 0x1b132, 0x1b132 }, /* W */
{ 0x1b150, 0x1b152 }, /* W */ { 0x1b150, 0x1b152 }, /* W */
{ 0x1b155, 0x1b155 }, /* W */
{ 0x1b164, 0x1b167 }, /* W */ { 0x1b164, 0x1b167 }, /* W */
{ 0x1b170, 0x1b2fb }, /* W */ { 0x1b170, 0x1b2fb }, /* W */
{ 0x1f004, 0x1f004 }, /* W */ { 0x1f004, 0x1f004 }, /* W */
@ -102,7 +104,7 @@
{ 0x1f6cc, 0x1f6cc }, /* W */ { 0x1f6cc, 0x1f6cc }, /* W */
{ 0x1f6d0, 0x1f6d2 }, /* W */ { 0x1f6d0, 0x1f6d2 }, /* W */
{ 0x1f6d5, 0x1f6d7 }, /* W */ { 0x1f6d5, 0x1f6d7 }, /* W */
{ 0x1f6dd, 0x1f6df }, /* W */ { 0x1f6dc, 0x1f6df }, /* W */
{ 0x1f6eb, 0x1f6ec }, /* W */ { 0x1f6eb, 0x1f6ec }, /* W */
{ 0x1f6f4, 0x1f6fc }, /* W */ { 0x1f6f4, 0x1f6fc }, /* W */
{ 0x1f7e0, 0x1f7eb }, /* W */ { 0x1f7e0, 0x1f7eb }, /* W */
@ -110,14 +112,12 @@
{ 0x1f90c, 0x1f93a }, /* W */ { 0x1f90c, 0x1f93a }, /* W */
{ 0x1f93c, 0x1f945 }, /* W */ { 0x1f93c, 0x1f945 }, /* W */
{ 0x1f947, 0x1f9ff }, /* W */ { 0x1f947, 0x1f9ff }, /* W */
{ 0x1fa70, 0x1fa74 }, /* W */ { 0x1fa70, 0x1fa7c }, /* W */
{ 0x1fa78, 0x1fa7c }, /* W */ { 0x1fa80, 0x1fa88 }, /* W */
{ 0x1fa80, 0x1fa86 }, /* W */ { 0x1fa90, 0x1fabd }, /* W */
{ 0x1fa90, 0x1faac }, /* W */ { 0x1fabf, 0x1fac5 }, /* W */
{ 0x1fab0, 0x1faba }, /* W */ { 0x1face, 0x1fadb }, /* W */
{ 0x1fac0, 0x1fac5 }, /* W */ { 0x1fae0, 0x1fae8 }, /* W */
{ 0x1fad0, 0x1fad9 }, /* W */ { 0x1faf0, 0x1faf8 }, /* W */
{ 0x1fae0, 0x1fae7 }, /* W */
{ 0x1faf0, 0x1faf6 }, /* W */
{ 0x20000, 0x2fffd }, /* W */ { 0x20000, 0x2fffd }, /* W */
{ 0x30000, 0x3fffd }, /* W */ { 0x30000, 0x3fffd }, /* W */

View File

@ -4,43 +4,35 @@
/* /*
* Initialize an expandable text buffer. * Initialize an expandable text buffer.
*/ */
public void public void xbuf_init(struct xbuffer *xbuf)
xbuf_init(xbuf)
struct xbuffer *xbuf;
{ {
xbuf->data = NULL; xbuf->data = NULL;
xbuf->size = xbuf->end = 0; xbuf->size = xbuf->end = 0;
} }
public void public void xbuf_deinit(struct xbuffer *xbuf)
xbuf_deinit(xbuf)
struct xbuffer *xbuf;
{ {
if (xbuf->data != NULL) if (xbuf->data != NULL)
free(xbuf->data); free(xbuf->data);
xbuf_init(xbuf); xbuf_init(xbuf);
} }
public void public void xbuf_reset(struct xbuffer *xbuf)
xbuf_reset(xbuf)
struct xbuffer *xbuf;
{ {
xbuf->end = 0; xbuf->end = 0;
} }
/* /*
* Add a char to an expandable text buffer. * Add a byte to an expandable text buffer.
*/ */
public void public void xbuf_add_byte(struct xbuffer *xbuf, unsigned char b)
xbuf_add(xbuf, ch)
struct xbuffer *xbuf;
int ch;
{ {
if (xbuf->end >= xbuf->size) if (xbuf->end >= xbuf->size)
{ {
char *data; unsigned char *data;
xbuf->size = (xbuf->size == 0) ? 16 : xbuf->size * 2; if (ckd_add(&xbuf->size, xbuf->size, xbuf->size ? xbuf->size : 16))
data = (char *) ecalloc(xbuf->size, sizeof(char)); out_of_memory();
data = (unsigned char *) ecalloc(xbuf->size, sizeof(unsigned char));
if (xbuf->data != NULL) if (xbuf->data != NULL)
{ {
memcpy(data, xbuf->data, xbuf->end); memcpy(data, xbuf->data, xbuf->end);
@ -48,26 +40,124 @@ xbuf_add(xbuf, ch)
} }
xbuf->data = data; xbuf->data = data;
} }
xbuf->data[xbuf->end++] = ch; xbuf->data[xbuf->end++] = (unsigned char) b;
} }
public int public void xbuf_add_data(struct xbuffer *xbuf, unsigned char *data, int len)
xbuf_pop(buf) {
struct xbuffer *buf; int i;
for (i = 0; i < len; i++)
xbuf_add_byte(xbuf, data[i]);
}
public int xbuf_pop(struct xbuffer *buf)
{ {
if (buf->end == 0) if (buf->end == 0)
return -1; return -1;
return buf->data[--(buf->end)]; return (int) buf->data[--(buf->end)];
} }
public void public void xbuf_set(struct xbuffer *dst, struct xbuffer *src)
xbuf_set(dst, src)
struct xbuffer *dst;
struct xbuffer *src;
{ {
int i;
xbuf_reset(dst); xbuf_reset(dst);
for (i = 0; i < src->end; i++) xbuf_add_data(dst, src->data, src->end);
xbuf_add(dst, src->data[i]);
} }
public char * xbuf_char_data(struct xbuffer *xbuf)
{
return (char *)(xbuf->data);
}
/*
* Helper functions for the ckd_add and ckd_mul macro substitutes.
* These helper functions do not set *R on overflow, and assume that
* arguments are nonnegative, that INTMAX_MAX <= UINTMAX_MAX, and that
* sizeof is a reliable way to distinguish integer representations.
* Despite these limitations they are good enough for 'less' on all
* known practical platforms. For more-complicated substitutes
* without most of these limitations, see Gnulib's stdckdint module.
*/
#if !HAVE_STDCKDINT_H
/*
* If the integer *R can represent VAL, store the value and return FALSE.
* Otherwise, possibly set *R to an indeterminate value and return TRUE.
* R has size RSIZE, and is signed if and only if RSIGNED is nonzero.
*/
static int help_fixup(void *r, uintmax val, int rsize, int rsigned)
{
if (rsigned)
{
if (rsize == sizeof (int))
{
int *pr = r;
if (INT_MAX < val)
return TRUE;
*pr = val;
#ifdef LLONG_MAX
} else if (rsize == sizeof (long long))
{
long long *pr = r;
if (LLONG_MAX < val)
return TRUE;
*pr = val;
#endif
#ifdef INTMAX_MAX
} else if (rsize == sizeof (intmax_t)) {
intmax_t *pr = r;
if (INTMAX_MAX < val)
return TRUE;
*pr = val;
#endif
} else /* rsize == sizeof (long) */
{
long *pr = r;
if (LONG_MAX < val)
return TRUE;
*pr = val;
}
} else {
if (rsize == sizeof (unsigned)) {
unsigned *pr = r;
if (UINT_MAX < val)
return TRUE;
*pr = val;
} else if (rsize == sizeof (unsigned long)) {
unsigned long *pr = r;
if (ULONG_MAX < val)
return TRUE;
*pr = val;
#ifdef ULLONG_MAX
} else if (rsize == sizeof (unsigned long long)) {
long long *pr = r;
if (ULLONG_MAX < val)
return TRUE;
*pr = val;
#endif
} else /* rsize == sizeof (uintmax) */
{
uintmax *pr = r;
*pr = val;
}
}
return FALSE;
}
/*
* If *R can represent the mathematical sum of A and B, store the sum
* and return FALSE. Otherwise, possibly set *R to an indeterminate
* value and return TRUE. R has size RSIZE, and is signed if and only
* if RSIGNED is nonzero.
*/
public int help_ckd_add(void *r, uintmax a, uintmax b, int rsize, int rsigned)
{
uintmax sum = a + b;
return sum < a || help_fixup(r, sum, rsize, rsigned);
}
/* Likewise, but for the product of A and B. */
public int help_ckd_mul(void *r, uintmax a, uintmax b, int rsize, int rsigned)
{
uintmax product = a * b;
return ((b != 0 && a != product / b)
|| help_fixup(r, product, rsize, rsigned));
}
#endif

View File

@ -3,14 +3,17 @@
struct xbuffer struct xbuffer
{ {
char *data; unsigned char *data;
int end; int end;
int size; int size;
}; };
void xbuf_init(struct xbuffer *xbuf); void xbuf_init(struct xbuffer *xbuf);
void xbuf_deinit(struct xbuffer *xbuf);
void xbuf_reset(struct xbuffer *xbuf); void xbuf_reset(struct xbuffer *xbuf);
void xbuf_add(struct xbuffer *xbuf, int ch); void xbuf_add_byte(struct xbuffer *xbuf, unsigned char b);
void xbuf_add_data(struct xbuffer *xbuf, unsigned char *data, int len);
int xbuf_pop(struct xbuffer *xbuf); int xbuf_pop(struct xbuffer *xbuf);
char *xbuf_char_data(struct xbuffer *xbuf);
#endif #endif

View File

@ -214,6 +214,9 @@
#define TABSTOP_MAX 128 /* Max number of custom tab stops */ #define TABSTOP_MAX 128 /* Max number of custom tab stops */
#endif #endif
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
/* Settings automatically determined by configure. */ /* Settings automatically determined by configure. */
@ -241,9 +244,6 @@
/* Define HAVE_FILENO if you have the fileno() macro. */ /* Define HAVE_FILENO if you have the fileno() macro. */
#define HAVE_FILENO 1 #define HAVE_FILENO 1
/* Define HAVE_FLOAT if your compiler supports the "double" type. */
#define HAVE_FLOAT 1
/* Define to 1 if you have the `fsync' function. */ /* Define to 1 if you have the `fsync' function. */
#define HAVE_FSYNC 1 #define HAVE_FSYNC 1
@ -256,6 +256,9 @@
/* Define to 1 if you have the <limits.h> header file. */ /* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1 #define HAVE_LIMITS_H 1
/* Define to 1 if you have the <linux/magic.h> header file. */
/* #undef HAVE_LINUX_MAGIC_H */
/* Define HAVE_LOCALE if you have locale.h and setlocale. */ /* Define HAVE_LOCALE if you have locale.h and setlocale. */
#define HAVE_LOCALE 1 #define HAVE_LOCALE 1
@ -320,6 +323,9 @@
/* Define HAVE_STAT_INO if your struct stat has st_ino and st_dev. */ /* Define HAVE_STAT_INO if your struct stat has st_ino and st_dev. */
#define HAVE_STAT_INO 1 #define HAVE_STAT_INO 1
/* Define to 1 if you have the <stdckdint.h> header file. */
/* #undef HAVE_STDCKDINT_H */
/* Define to 1 if you have the <stdint.h> header file. */ /* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1 #define HAVE_STDINT_H 1
@ -338,6 +344,9 @@
/* Define to 1 if you have the <string.h> header file. */ /* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1 #define HAVE_STRING_H 1
/* Define to 1 if you have the `strsignal' function. */
#define HAVE_STRSIGNAL 1
/* Define to 1 if you have the `system' function. */ /* Define to 1 if you have the `system' function. */
#define HAVE_SYSTEM 1 #define HAVE_SYSTEM 1
@ -356,6 +365,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */ /* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1 #define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/wait.h> header file. */
#define HAVE_SYS_WAIT_H 1
/* Define to 1 if you have the <termcap.h> header file. */ /* Define to 1 if you have the <termcap.h> header file. */
#define HAVE_TERMCAP_H 1 #define HAVE_TERMCAP_H 1
@ -433,9 +445,6 @@
/* Define to the version of this package. */ /* Define to the version of this package. */
#define PACKAGE_VERSION "1" #define PACKAGE_VERSION "1"
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
/* Define SECURE_COMPILE=1 to build a secure version of less. */ /* Define SECURE_COMPILE=1 to build a secure version of less. */
#define SECURE_COMPILE 0 #define SECURE_COMPILE 0
@ -445,9 +454,6 @@
/* Define to 1 if you have the ANSI C header files. */ /* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1 #define STDC_HEADERS 1
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#define TIME_WITH_SYS_TIME 1
/* Enable large inode numbers on Mac OS X 10.5. */ /* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE #ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1 # define _DARWIN_USE_64_BIT_INODE 1