mirror of
https://github.com/opnsense/src.git
synced 2026-06-08 16:22:46 -04:00
MFV: less v668.
MFC after: 2 weeks
This commit is contained in:
commit
c77c488926
65 changed files with 5751 additions and 2937 deletions
|
|
@ -2,7 +2,7 @@
|
|||
------------
|
||||
|
||||
Less
|
||||
Copyright (C) 1984-2023 Mark Nudelman
|
||||
Copyright (C) 1984-2024 Mark Nudelman
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
|
|
|
|||
|
|
@ -9,6 +9,140 @@
|
|||
Report bugs, suggestions or comments at
|
||||
https://github.com/gwsw/less/issues.
|
||||
|
||||
======================================================================
|
||||
|
||||
Major changes between "less" versions 661 and 668
|
||||
|
||||
* Make 256/true colors work better on Windows without -Da
|
||||
(github #539, github #546, github #562).
|
||||
|
||||
* Fix build using --with-secure (github #544).
|
||||
|
||||
* Fix crash when using --header on command line (github #545).
|
||||
|
||||
* Fix possible crash when scrolling left/right or toggling -S (github #547).
|
||||
|
||||
* Fix bug when using #stop in a lesskey file (github #551).
|
||||
|
||||
* Fix bug when using --shift or --match-shift on command line with
|
||||
a parameter starting with '.' (github #554).
|
||||
|
||||
* Fix bug in R command when file size changes (github #553).
|
||||
|
||||
* Fix bug using --header when file does not fill screen (github #556).
|
||||
|
||||
* Fix ^X bug when output is not a terminal (github #558).
|
||||
|
||||
* Fix bug where ^Z is not handled immediately (github #563).
|
||||
|
||||
* Fix bug where first byte from a LESSOPEN filter is deleted if it is
|
||||
greater than 0x7F (github #568).
|
||||
|
||||
* Fix uninitialized variable in edit_ifile (github #573).
|
||||
|
||||
* Fix incorrect handling of UTF-8 chars in prompts (github #576).
|
||||
|
||||
======================================================================
|
||||
|
||||
Major changes between "less" versions 643 and 661
|
||||
|
||||
* Add ^O^N, ^O^P, ^O^L and ^O^O commands and mouse clicks (with --mouse)
|
||||
to find and open OSC8 hyperlinks (github #251).
|
||||
|
||||
* Add --match-shift option.
|
||||
|
||||
* Add --lesskey-content option (github #447).
|
||||
|
||||
* Add LESSKEY_CONTENT environment variable (github #447).
|
||||
|
||||
* Add --no-search-header-lines and --no-search-header-columns options
|
||||
(github #397).
|
||||
|
||||
* Add ctrl-L search modifier (github #367).
|
||||
|
||||
* A ctrl-P at the start of a shell command suppresses the "done"
|
||||
message (github #462).
|
||||
|
||||
* Add attribute characters ('*', '~', '_', '&') to --color
|
||||
parameter (github #471).
|
||||
|
||||
* Allow expansion of environment variables in lesskey files.
|
||||
|
||||
* Add LESSSECURE_ALLOW environment variable (github #449).
|
||||
|
||||
* Add LESS_UNSUPPORT environment variable.
|
||||
|
||||
* Add line number parameter to --header option (github #436).
|
||||
|
||||
* Mouse right-click jumps to position marked by left-click (github #390).
|
||||
|
||||
* Ensure that the target line is not obscured by a header line
|
||||
set by --header (github #444).
|
||||
|
||||
* Change default character set to "utf-8", except remains "dos" on MS-DOS.
|
||||
|
||||
* Add message when search with ^W wraps (github #459).
|
||||
|
||||
* UCRT builds on Windows 10 and later now support Unicode file names
|
||||
(github #438).
|
||||
|
||||
* Improve behavior of interrupt while reading non-terminated pipe
|
||||
(github #414).
|
||||
|
||||
* Improve parsing of -j, -x and -# options (github #393).
|
||||
|
||||
* Support files larger than 4GB on Windows (github #417).
|
||||
|
||||
* Support entry of Unicode chars larger than U+FFFF on Windows (github #391).
|
||||
|
||||
* Improve colors of bold, underline and standout text on Windows.
|
||||
|
||||
* Allow --rscroll to accept non-ASCII characters (github #483).
|
||||
|
||||
* Allow the parameter to certain options to be terminated with a
|
||||
space (--color, --quotes, --rscroll, --search-options
|
||||
and --intr) (github #495).
|
||||
|
||||
* Fix bug where # substitution failed after viewing help (github #420).
|
||||
|
||||
* Fix crash if files are deleted while less is viewing them (github #404).
|
||||
|
||||
* Workaround unreliable ReadConsoleInputW behavior on Windows
|
||||
with non-ASCII input.
|
||||
|
||||
* Fix -J display when searching for non-ASCII characters (github #422).
|
||||
|
||||
* Don't filter header lines via the & command (github #423).
|
||||
|
||||
* Fix bug when horizontally shifting long lines (github #425).
|
||||
|
||||
* Add -x and -D options to lesstest, to make it easier to diagnose
|
||||
a failed lesstest run.
|
||||
|
||||
* Fix bug searching long lines with --incsearch and -S (github #428).
|
||||
|
||||
* Fix bug that made ESC-} fail if top line on screen was empty (github #429).
|
||||
|
||||
* Fix bug with --mouse on Windows when used with pipes (github #440).
|
||||
|
||||
* Fix bug in --+OPTION command line syntax.
|
||||
|
||||
* Fix display bug when using -w with an empty line with a CR/LF
|
||||
line ending (github #474).
|
||||
|
||||
* When substituting '#' or '%' with a filename, quote the filename
|
||||
if it contains a space (github #480).
|
||||
|
||||
* Fix wrong sleep time when system has usleep but not nanosleep (github #489).
|
||||
|
||||
* Fix bug when file name contains a newline.
|
||||
|
||||
* Fix bug when file name contains nonprintable characters (github #503).
|
||||
|
||||
* Fix DJGPP build (github #497).
|
||||
|
||||
* Update Unicode tables.
|
||||
|
||||
======================================================================
|
||||
|
||||
Major changes between "less" versions 633 and 643
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -20,13 +20,6 @@
|
|||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_PROCFS
|
||||
#include <sys/statfs.h>
|
||||
#if HAVE_LINUX_MAGIC_H
|
||||
#include <linux/magic.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef POSITION BLOCKNUM;
|
||||
|
||||
public int ignore_eoi;
|
||||
|
|
@ -46,7 +39,7 @@ struct bufnode {
|
|||
struct buf {
|
||||
struct bufnode node;
|
||||
BLOCKNUM block;
|
||||
unsigned int datasize;
|
||||
size_t datasize;
|
||||
unsigned char data[LBUFSIZE];
|
||||
};
|
||||
#define bufnode_buf(bn) ((struct buf *) bn)
|
||||
|
|
@ -64,7 +57,7 @@ struct filestate {
|
|||
POSITION fpos;
|
||||
int nbufs;
|
||||
BLOCKNUM block;
|
||||
unsigned int offset;
|
||||
size_t offset;
|
||||
POSITION fsize;
|
||||
};
|
||||
|
||||
|
|
@ -122,15 +115,14 @@ struct filestate {
|
|||
thisfile->hashtbl[h].hnext = (bn);
|
||||
|
||||
static struct filestate *thisfile;
|
||||
static int ch_ungotchar = -1;
|
||||
static unsigned char ch_ungotchar;
|
||||
static lbool ch_have_ungotchar = FALSE;
|
||||
static int maxbufs = -1;
|
||||
|
||||
extern int autobuf;
|
||||
extern int sigs;
|
||||
extern int secure;
|
||||
extern int screen_trashed;
|
||||
extern int follow_mode;
|
||||
extern int waiting_for_data;
|
||||
extern lbool waiting_for_data;
|
||||
extern constant char helpdata[];
|
||||
extern constant int size_helpdata;
|
||||
extern IFILE curr_ifile;
|
||||
|
|
@ -141,6 +133,13 @@ extern char *namelogfile;
|
|||
|
||||
static int ch_addbuf();
|
||||
|
||||
/*
|
||||
* Return the file position corresponding to an offset within a block.
|
||||
*/
|
||||
static POSITION ch_position(BLOCKNUM block, size_t offset)
|
||||
{
|
||||
return (block * LBUFSIZE) + (POSITION) offset;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the character pointed to by the read pointer.
|
||||
|
|
@ -149,8 +148,8 @@ static int ch_get(void)
|
|||
{
|
||||
struct buf *bp;
|
||||
struct bufnode *bn;
|
||||
int n;
|
||||
int read_again;
|
||||
ssize_t n;
|
||||
lbool read_again;
|
||||
int h;
|
||||
POSITION pos;
|
||||
POSITION len;
|
||||
|
|
@ -187,6 +186,8 @@ static int ch_get(void)
|
|||
goto found;
|
||||
}
|
||||
}
|
||||
if (ABORT_SIGS())
|
||||
return (EOI);
|
||||
if (bn == END_OF_HCHAIN(h))
|
||||
{
|
||||
/*
|
||||
|
|
@ -223,7 +224,7 @@ static int ch_get(void)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
pos = (ch_block * LBUFSIZE) + bp->datasize;
|
||||
pos = ch_position(ch_block, bp->datasize);
|
||||
if ((len = ch_length()) != NULL_POSITION && pos >= len)
|
||||
/*
|
||||
* At end of file.
|
||||
|
|
@ -239,7 +240,7 @@ static int ch_get(void)
|
|||
*/
|
||||
if (!(ch_flags & CH_CANSEEK))
|
||||
return ('?');
|
||||
if (lseek(ch_file, (off_t)pos, SEEK_SET) == BAD_LSEEK)
|
||||
if (less_lseek(ch_file, (less_off_t)pos, SEEK_SET) == BAD_LSEEK)
|
||||
{
|
||||
error("seek error", NULL_PARG);
|
||||
clear_eol();
|
||||
|
|
@ -253,19 +254,18 @@ static int ch_get(void)
|
|||
* 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)
|
||||
if (ch_have_ungotchar)
|
||||
{
|
||||
bp->data[bp->datasize] = ch_ungotchar;
|
||||
n = 1;
|
||||
ch_ungotchar = -1;
|
||||
ch_have_ungotchar = FALSE;
|
||||
} else if (ch_flags & CH_HELPFILE)
|
||||
{
|
||||
bp->data[bp->datasize] = helpdata[ch_fpos];
|
||||
bp->data[bp->datasize] = (unsigned char) helpdata[ch_fpos];
|
||||
n = 1;
|
||||
} else
|
||||
{
|
||||
n = iread(ch_file, &bp->data[bp->datasize],
|
||||
(unsigned int)(LBUFSIZE - bp->datasize));
|
||||
n = iread(ch_file, &bp->data[bp->datasize], LBUFSIZE - bp->datasize);
|
||||
}
|
||||
|
||||
read_again = FALSE;
|
||||
|
|
@ -295,12 +295,15 @@ static int ch_get(void)
|
|||
/*
|
||||
* 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);
|
||||
if (secure_allow(SF_LOGFILE))
|
||||
{
|
||||
if (logfile >= 0 && n > 0)
|
||||
write(logfile, &bp->data[bp->datasize], (size_t) n);
|
||||
}
|
||||
#endif
|
||||
|
||||
ch_fpos += n;
|
||||
bp->datasize += n;
|
||||
bp->datasize += (size_t) n;
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
|
|
@ -323,7 +326,7 @@ static int ch_get(void)
|
|||
if (ignore_eoi && follow_mode == FOLLOW_NAME && curr_ifile_changed())
|
||||
{
|
||||
/* screen_trashed=2 causes make_display to reopen the file. */
|
||||
screen_trashed = 2;
|
||||
screen_trashed_num(2);
|
||||
return (EOI);
|
||||
}
|
||||
if (sigs)
|
||||
|
|
@ -363,9 +366,15 @@ static int ch_get(void)
|
|||
*/
|
||||
public void ch_ungetchar(int c)
|
||||
{
|
||||
if (c != -1 && ch_ungotchar != -1)
|
||||
error("ch_ungetchar overrun", NULL_PARG);
|
||||
ch_ungotchar = c;
|
||||
if (c < 0)
|
||||
ch_have_ungotchar = FALSE;
|
||||
else
|
||||
{
|
||||
if (ch_have_ungotchar)
|
||||
error("ch_ungetchar overrun", NULL_PARG);
|
||||
ch_ungotchar = (unsigned char) c;
|
||||
ch_have_ungotchar = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
#if LOGFILE
|
||||
|
|
@ -375,7 +384,7 @@ public void ch_ungetchar(int c)
|
|||
*/
|
||||
public void end_logfile(void)
|
||||
{
|
||||
static int tried = FALSE;
|
||||
static lbool tried = FALSE;
|
||||
|
||||
if (logfile < 0)
|
||||
return;
|
||||
|
|
@ -402,7 +411,7 @@ public void sync_logfile(void)
|
|||
{
|
||||
struct buf *bp;
|
||||
struct bufnode *bn;
|
||||
int warned = FALSE;
|
||||
lbool warned = FALSE;
|
||||
BLOCKNUM block;
|
||||
BLOCKNUM nblocks;
|
||||
|
||||
|
|
@ -411,13 +420,13 @@ public void sync_logfile(void)
|
|||
nblocks = (ch_fpos + LBUFSIZE - 1) / LBUFSIZE;
|
||||
for (block = 0; block < nblocks; block++)
|
||||
{
|
||||
int wrote = FALSE;
|
||||
lbool wrote = FALSE;
|
||||
FOR_BUFS(bn)
|
||||
{
|
||||
bp = bufnode_buf(bn);
|
||||
if (bp->block == block)
|
||||
{
|
||||
write(logfile, (char *) bp->data, bp->datasize);
|
||||
write(logfile, bp->data, bp->datasize);
|
||||
wrote = TRUE;
|
||||
break;
|
||||
}
|
||||
|
|
@ -436,7 +445,7 @@ public void sync_logfile(void)
|
|||
/*
|
||||
* Determine if a specific block is currently in one of the buffers.
|
||||
*/
|
||||
static int buffered(BLOCKNUM block)
|
||||
static lbool buffered(BLOCKNUM block)
|
||||
{
|
||||
struct buf *bp;
|
||||
struct bufnode *bn;
|
||||
|
|
@ -486,7 +495,7 @@ public int ch_seek(POSITION pos)
|
|||
* Set read pointer.
|
||||
*/
|
||||
ch_block = new_block;
|
||||
ch_offset = pos % LBUFSIZE;
|
||||
ch_offset = (size_t) (pos % LBUFSIZE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
@ -533,7 +542,7 @@ public int ch_end_buffer_seek(void)
|
|||
FOR_BUFS(bn)
|
||||
{
|
||||
bp = bufnode_buf(bn);
|
||||
buf_pos = (bp->block * LBUFSIZE) + bp->datasize;
|
||||
buf_pos = ch_position(bp->block, bp->datasize);
|
||||
if (buf_pos > end_pos)
|
||||
end_pos = buf_pos;
|
||||
}
|
||||
|
|
@ -597,7 +606,7 @@ public POSITION ch_tell(void)
|
|||
{
|
||||
if (thisfile == NULL)
|
||||
return (NULL_POSITION);
|
||||
return (ch_block * LBUFSIZE) + ch_offset;
|
||||
return ch_position(ch_block, ch_offset);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -647,14 +656,14 @@ public int ch_back_get(void)
|
|||
* Set max amount of buffer space.
|
||||
* bufspace is in units of 1024 bytes. -1 mean no limit.
|
||||
*/
|
||||
public void ch_setbufspace(int bufspace)
|
||||
public void ch_setbufspace(ssize_t bufspace)
|
||||
{
|
||||
if (bufspace < 0)
|
||||
maxbufs = -1;
|
||||
else
|
||||
{
|
||||
int lbufk = LBUFSIZE / 1024;
|
||||
maxbufs = bufspace / lbufk + (bufspace % lbufk != 0);
|
||||
size_t lbufk = LBUFSIZE / 1024;
|
||||
maxbufs = (int) (bufspace / lbufk + (bufspace % lbufk != 0));
|
||||
if (maxbufs < 1)
|
||||
maxbufs = 1;
|
||||
}
|
||||
|
|
@ -688,11 +697,6 @@ public void ch_flush(void)
|
|||
bufnode_buf(bn)->block = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Figure out the size of the file, if we can.
|
||||
*/
|
||||
ch_fsize = filesize(ch_file);
|
||||
|
||||
/*
|
||||
* Seek to a known position: the beginning of the file.
|
||||
*/
|
||||
|
|
@ -700,19 +704,16 @@ public void ch_flush(void)
|
|||
ch_block = 0; /* ch_fpos / LBUFSIZE; */
|
||||
ch_offset = 0; /* ch_fpos % LBUFSIZE; */
|
||||
|
||||
/*
|
||||
* This is a kludge to workaround a Linux kernel bug: files in
|
||||
* /proc have a size of 0 according to fstat() but have readable
|
||||
* data. They are sometimes, but not always, seekable.
|
||||
* Force them to be non-seekable here.
|
||||
*/
|
||||
if (ch_fsize == 0)
|
||||
if (ch_flags & CH_NOTRUSTSIZE)
|
||||
{
|
||||
ch_fsize = NULL_POSITION;
|
||||
ch_flags &= ~CH_CANSEEK;
|
||||
} else
|
||||
{
|
||||
ch_fsize = (ch_flags & CH_HELPFILE) ? size_helpdata : filesize(ch_file);
|
||||
}
|
||||
|
||||
if (lseek(ch_file, (off_t)0, SEEK_SET) == BAD_LSEEK)
|
||||
if (less_lseek(ch_file, (less_off_t)0, SEEK_SET) == BAD_LSEEK)
|
||||
{
|
||||
/*
|
||||
* Warning only; even if the seek fails for some reason,
|
||||
|
|
@ -795,7 +796,7 @@ public int seekable(int f)
|
|||
return (0);
|
||||
}
|
||||
#endif
|
||||
return (lseek(f, (off_t)1, SEEK_SET) != BAD_LSEEK);
|
||||
return (less_lseek(f, (less_off_t)1, SEEK_SET) != BAD_LSEEK);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -812,7 +813,7 @@ public void ch_set_eof(void)
|
|||
/*
|
||||
* Initialize file state for a new file.
|
||||
*/
|
||||
public void ch_init(int f, int flags)
|
||||
public void ch_init(int f, int flags, ssize_t nread)
|
||||
{
|
||||
/*
|
||||
* See if we already have a filestate for this file.
|
||||
|
|
@ -843,6 +844,22 @@ public void ch_init(int f, int flags)
|
|||
}
|
||||
if (thisfile->file == -1)
|
||||
thisfile->file = f;
|
||||
|
||||
/*
|
||||
* Figure out the size of the file, if we can.
|
||||
*/
|
||||
ch_fsize = (flags & CH_HELPFILE) ? size_helpdata : filesize(ch_file);
|
||||
|
||||
/*
|
||||
* This is a kludge to workaround a Linux kernel bug: files in some
|
||||
* pseudo filesystems like /proc and tracefs have a size of 0 according
|
||||
* to fstat() but have readable data.
|
||||
*/
|
||||
if (ch_fsize == 0 && nread > 0)
|
||||
{
|
||||
ch_flags |= CH_NOTRUSTSIZE;
|
||||
}
|
||||
|
||||
ch_flush();
|
||||
}
|
||||
|
||||
|
|
@ -851,7 +868,7 @@ public void ch_init(int f, int flags)
|
|||
*/
|
||||
public void ch_close(void)
|
||||
{
|
||||
int keepstate = FALSE;
|
||||
lbool keepstate = FALSE;
|
||||
|
||||
if (thisfile == NULL)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -120,8 +120,8 @@ struct cs_alias {
|
|||
#define IS_CONTROL_CHAR 02
|
||||
|
||||
static char chardef[256];
|
||||
static char *binfmt = NULL;
|
||||
static char *utfbinfmt = NULL;
|
||||
static constant char *binfmt = NULL;
|
||||
static constant char *utfbinfmt = NULL;
|
||||
public int binattr = AT_STANDOUT|AT_COLOR_BIN;
|
||||
|
||||
static struct xbuffer user_wide_array;
|
||||
|
|
@ -139,13 +139,13 @@ static struct wchar_range_table user_prt_table;
|
|||
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);
|
||||
tbl->count = (unsigned int) (arr->end / sizeof(struct wchar_range));
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip over a "U" or "U+" prefix before a hex codepoint.
|
||||
*/
|
||||
static char * skip_uprefix(char *s)
|
||||
static constant char * skip_uprefix(constant char *s)
|
||||
{
|
||||
if (*s == 'U' || *s == 'u')
|
||||
if (*++s == '+') ++s;
|
||||
|
|
@ -155,14 +155,14 @@ static char * skip_uprefix(char *s)
|
|||
/*
|
||||
* Parse a dash-separated range of hex values.
|
||||
*/
|
||||
static void wchar_range_get(char **ss, struct wchar_range *range)
|
||||
static void wchar_range_get(constant char **ss, struct wchar_range *range)
|
||||
{
|
||||
char *s = skip_uprefix(*ss);
|
||||
range->first = lstrtoul(s, &s, 16);
|
||||
constant char *s = skip_uprefix(*ss);
|
||||
range->first = lstrtoulc(s, &s, 16);
|
||||
if (s[0] == '-')
|
||||
{
|
||||
s = skip_uprefix(&s[1]);
|
||||
range->last = lstrtoul(s, &s, 16);
|
||||
range->last = lstrtoulc(s, &s, 16);
|
||||
} else
|
||||
{
|
||||
range->last = range->first;
|
||||
|
|
@ -173,7 +173,7 @@ static void wchar_range_get(char **ss, struct wchar_range *range)
|
|||
/*
|
||||
* Parse the LESSUTFCHARDEF variable.
|
||||
*/
|
||||
static void ichardef_utf(char *s)
|
||||
static void ichardef_utf(constant char *s)
|
||||
{
|
||||
xbuf_init(&user_wide_array);
|
||||
xbuf_init(&user_ubin_array);
|
||||
|
|
@ -241,7 +241,7 @@ static void ichardef_utf(char *s)
|
|||
* b binary character
|
||||
* c control character
|
||||
*/
|
||||
static void ichardef(char *s)
|
||||
static void ichardef(constant char *s)
|
||||
{
|
||||
char *cp;
|
||||
int n;
|
||||
|
|
@ -298,7 +298,7 @@ static void ichardef(char *s)
|
|||
* Define a charset, given a charset name.
|
||||
* The valid charset names are listed in the "charsets" array.
|
||||
*/
|
||||
static int icharset(char *name, int no_error)
|
||||
static int icharset(constant char *name, int no_error)
|
||||
{
|
||||
struct charset *p;
|
||||
struct cs_alias *a;
|
||||
|
|
@ -363,23 +363,8 @@ static void ilocale(void)
|
|||
/*
|
||||
* Define the printing format for control (or binary utf) chars.
|
||||
*/
|
||||
public void setfmt(char *s, char **fmtvarptr, int *attrptr, char *default_fmt, int for_printf)
|
||||
public void setfmt(constant char *s, constant char **fmtvarptr, int *attrptr, constant char *default_fmt, lbool for_printf)
|
||||
{
|
||||
if (s && utf_mode)
|
||||
{
|
||||
/* It would be too hard to account for width otherwise. */
|
||||
char constant *t = s;
|
||||
while (*t)
|
||||
{
|
||||
if (*t < ' ' || *t > '~')
|
||||
{
|
||||
s = default_fmt;
|
||||
goto attr;
|
||||
}
|
||||
t++;
|
||||
}
|
||||
}
|
||||
|
||||
if (s == NULL || *s == '\0')
|
||||
s = default_fmt;
|
||||
else if (for_printf &&
|
||||
|
|
@ -391,7 +376,6 @@ public void setfmt(char *s, char **fmtvarptr, int *attrptr, char *default_fmt, i
|
|||
/*
|
||||
* Select the attributes if it starts with "*".
|
||||
*/
|
||||
attr:
|
||||
if (*s == '*' && s[1] != '\0')
|
||||
{
|
||||
switch (s[1])
|
||||
|
|
@ -412,16 +396,7 @@ public void setfmt(char *s, char **fmtvarptr, int *attrptr, char *default_fmt, i
|
|||
*/
|
||||
static void set_charset(void)
|
||||
{
|
||||
char *s;
|
||||
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
/*
|
||||
* If the Windows console is using UTF-8, we'll use it too.
|
||||
*/
|
||||
if (GetConsoleOutputCP() == CP_UTF8)
|
||||
if (icharset("utf-8", 1))
|
||||
return;
|
||||
#endif
|
||||
constant char *s;
|
||||
|
||||
ichardef_utf(lgetenv("LESSUTFCHARDEF"));
|
||||
|
||||
|
|
@ -476,15 +451,13 @@ static void set_charset(void)
|
|||
ilocale();
|
||||
#else
|
||||
#if MSDOS_COMPILER
|
||||
/*
|
||||
* Default to "dos".
|
||||
*/
|
||||
(void) icharset("dos", 1);
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
(void) icharset("utf-8", 1);
|
||||
#else
|
||||
/*
|
||||
* Default to "latin1".
|
||||
*/
|
||||
(void) icharset("latin1", 1);
|
||||
(void) icharset("dos", 1);
|
||||
#endif
|
||||
#else
|
||||
(void) icharset("utf-8", 1);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
|
@ -494,7 +467,7 @@ static void set_charset(void)
|
|||
*/
|
||||
public void init_charset(void)
|
||||
{
|
||||
char *s;
|
||||
constant char *s;
|
||||
|
||||
#if HAVE_LOCALE
|
||||
setlocale(LC_ALL, "");
|
||||
|
|
@ -512,20 +485,22 @@ public void init_charset(void)
|
|||
/*
|
||||
* Is a given character a "binary" character?
|
||||
*/
|
||||
public int binary_char(LWCHAR c)
|
||||
public lbool binary_char(LWCHAR c)
|
||||
{
|
||||
if (utf_mode)
|
||||
return (is_ubin_char(c));
|
||||
c &= 0377;
|
||||
return (chardef[c] & IS_BINARY_CHAR);
|
||||
if (c >= sizeof(chardef))
|
||||
return TRUE;
|
||||
return ((chardef[c] & IS_BINARY_CHAR) != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Is a given character a "control" character?
|
||||
*/
|
||||
public int control_char(LWCHAR c)
|
||||
public lbool control_char(LWCHAR c)
|
||||
{
|
||||
c &= 0377;
|
||||
if (c >= sizeof(chardef))
|
||||
return TRUE;
|
||||
return (chardef[c] & IS_CONTROL_CHAR);
|
||||
}
|
||||
|
||||
|
|
@ -533,12 +508,12 @@ public int control_char(LWCHAR c)
|
|||
* Return the printable form of a character.
|
||||
* For example, in the "ascii" charset '\3' is printed as "^C".
|
||||
*/
|
||||
public char * prchar(LWCHAR c)
|
||||
public constant char * prchar(LWCHAR c)
|
||||
{
|
||||
/* {{ This buffer can be overrun if LESSBINFMT is a long string. }} */
|
||||
/* {{ Fixed buffer size means LESSBINFMT etc can be truncated. }} */
|
||||
static char buf[MAX_PRCHAR_LEN+1];
|
||||
|
||||
c &= 0377;
|
||||
c &= 0377; /*{{type-issue}}*/
|
||||
if ((c < 128 || !utf_mode) && !control_char(c))
|
||||
SNPRINTF1(buf, sizeof(buf), "%c", (int) c);
|
||||
else if (c == ESC)
|
||||
|
|
@ -567,7 +542,7 @@ public char * prchar(LWCHAR c)
|
|||
/*
|
||||
* Return the printable form of a UTF-8 character.
|
||||
*/
|
||||
public char * prutfchar(LWCHAR ch)
|
||||
public constant char * prutfchar(LWCHAR ch)
|
||||
{
|
||||
static char buf[MAX_PRCHAR_LEN+1];
|
||||
|
||||
|
|
@ -596,7 +571,7 @@ public char * prutfchar(LWCHAR ch)
|
|||
/*
|
||||
* Get the length of a UTF-8 character in bytes.
|
||||
*/
|
||||
public int utf_len(int ch)
|
||||
public int utf_len(char ch)
|
||||
{
|
||||
if ((ch & 0x80) == 0)
|
||||
return 1;
|
||||
|
|
@ -606,10 +581,12 @@ public int utf_len(int ch)
|
|||
return 3;
|
||||
if ((ch & 0xF8) == 0xF0)
|
||||
return 4;
|
||||
#if 0
|
||||
if ((ch & 0xFC) == 0xF8)
|
||||
return 5;
|
||||
if ((ch & 0xFE) == 0xFC)
|
||||
return 6;
|
||||
#endif
|
||||
/* Invalid UTF-8 encoding. */
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -617,42 +594,41 @@ public int utf_len(int ch)
|
|||
/*
|
||||
* Does the parameter point to the lead byte of a well-formed UTF-8 character?
|
||||
*/
|
||||
public int is_utf8_well_formed(char *ss, int slen)
|
||||
public lbool is_utf8_well_formed(constant char *ss, int slen)
|
||||
{
|
||||
int i;
|
||||
int len;
|
||||
unsigned char *s = (unsigned char *) ss;
|
||||
unsigned char s0 = (unsigned char) ss[0];
|
||||
|
||||
if (IS_UTF8_INVALID(s[0]))
|
||||
return (0);
|
||||
if (IS_UTF8_INVALID(s0))
|
||||
return (FALSE);
|
||||
|
||||
len = utf_len(s[0]);
|
||||
len = utf_len(ss[0]);
|
||||
if (len > slen)
|
||||
return (0);
|
||||
return (FALSE);
|
||||
if (len == 1)
|
||||
return (1);
|
||||
return (TRUE);
|
||||
if (len == 2)
|
||||
{
|
||||
if (s[0] < 0xC2)
|
||||
return (0);
|
||||
if (s0 < 0xC2)
|
||||
return (FALSE);
|
||||
} else
|
||||
{
|
||||
unsigned char mask;
|
||||
mask = (~((1 << (8-len)) - 1)) & 0xFF;
|
||||
if (s[0] == mask && (s[1] & mask) == 0x80)
|
||||
return (0);
|
||||
unsigned char mask = (unsigned char) (~((1 << (8-len)) - 1));
|
||||
if (s0 == mask && (ss[1] & mask) == 0x80)
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
for (i = 1; i < len; i++)
|
||||
if (!IS_UTF8_TRAIL(s[i]))
|
||||
return (0);
|
||||
return (1);
|
||||
if (!IS_UTF8_TRAIL(ss[i]))
|
||||
return (FALSE);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip bytes until a UTF-8 lead byte (11xxxxxx) or ASCII byte (0xxxxxxx) is found.
|
||||
*/
|
||||
public void utf_skip_to_lead(char **pp, char *limit)
|
||||
public void utf_skip_to_lead(constant char **pp, constant char *limit)
|
||||
{
|
||||
do {
|
||||
++(*pp);
|
||||
|
|
@ -663,9 +639,10 @@ public void utf_skip_to_lead(char **pp, char *limit)
|
|||
/*
|
||||
* Get the value of a UTF-8 character.
|
||||
*/
|
||||
public LWCHAR get_wchar(constant char *p)
|
||||
public LWCHAR get_wchar(constant char *sp)
|
||||
{
|
||||
switch (utf_len(p[0]))
|
||||
constant unsigned char *p = (constant unsigned char *) sp;
|
||||
switch (utf_len(sp[0]))
|
||||
{
|
||||
case 1:
|
||||
default:
|
||||
|
|
@ -690,6 +667,7 @@ public LWCHAR get_wchar(constant char *p)
|
|||
((p[1] & 0x3F) << 12) |
|
||||
((p[2] & 0x3F) << 6) |
|
||||
(p[3] & 0x3F));
|
||||
#if 0
|
||||
case 5:
|
||||
/* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */
|
||||
return (LWCHAR) (
|
||||
|
|
@ -707,13 +685,14 @@ public LWCHAR get_wchar(constant char *p)
|
|||
((p[3] & 0x3F) << 12) |
|
||||
((p[4] & 0x3F) << 6) |
|
||||
(p[5] & 0x3F));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Store a character into a UTF-8 string.
|
||||
*/
|
||||
public void put_wchar(char **pp, LWCHAR ch)
|
||||
public void put_wchar(mutable char **pp, LWCHAR ch)
|
||||
{
|
||||
if (!utf_mode || ch < 0x80)
|
||||
{
|
||||
|
|
@ -737,6 +716,7 @@ public void put_wchar(char **pp, LWCHAR ch)
|
|||
*(*pp)++ = (char) (0x80 | ((ch >> 12) & 0x3F));
|
||||
*(*pp)++ = (char) (0x80 | ((ch >> 6) & 0x3F));
|
||||
*(*pp)++ = (char) (0x80 | (ch & 0x3F));
|
||||
#if 0
|
||||
} else if (ch < 0x4000000)
|
||||
{
|
||||
/* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */
|
||||
|
|
@ -754,17 +734,18 @@ public void put_wchar(char **pp, LWCHAR ch)
|
|||
*(*pp)++ = (char) (0x80 | ((ch >> 12) & 0x3F));
|
||||
*(*pp)++ = (char) (0x80 | ((ch >> 6) & 0x3F));
|
||||
*(*pp)++ = (char) (0x80 | (ch & 0x3F));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Step forward or backward one character in a string.
|
||||
*/
|
||||
public LWCHAR step_char(char **pp, signed int dir, constant char *limit)
|
||||
public LWCHAR step_charc(constant char **pp, signed int dir, constant char *limit)
|
||||
{
|
||||
LWCHAR ch;
|
||||
int len;
|
||||
char *p = *pp;
|
||||
constant char *p = *pp;
|
||||
|
||||
if (!utf_mode)
|
||||
{
|
||||
|
|
@ -798,6 +779,14 @@ public LWCHAR step_char(char **pp, signed int dir, constant char *limit)
|
|||
return ch;
|
||||
}
|
||||
|
||||
public LWCHAR step_char(char **pp, signed int dir, constant char *limit)
|
||||
{
|
||||
constant char *p = (constant char *) *pp;
|
||||
LWCHAR ch = step_charc(&p, dir, limit);
|
||||
*pp = (char *) p;
|
||||
return ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unicode characters data
|
||||
* Actual data is in the generated *.uni files.
|
||||
|
|
@ -806,7 +795,7 @@ public LWCHAR step_char(char **pp, signed int dir, constant char *limit)
|
|||
#define DECLARE_RANGE_TABLE_START(name) \
|
||||
static struct wchar_range name##_array[] = {
|
||||
#define DECLARE_RANGE_TABLE_END(name) \
|
||||
}; struct wchar_range_table name##_table = { name##_array, sizeof(name##_array)/sizeof(*name##_array) };
|
||||
}; struct wchar_range_table name##_table = { name##_array, countof(name##_array) };
|
||||
|
||||
DECLARE_RANGE_TABLE_START(compose)
|
||||
#include "compose.uni"
|
||||
|
|
@ -830,36 +819,36 @@ static struct wchar_range comb_table[] = {
|
|||
};
|
||||
|
||||
|
||||
static int is_in_table(LWCHAR ch, struct wchar_range_table *table)
|
||||
static lbool is_in_table(LWCHAR ch, struct wchar_range_table *table)
|
||||
{
|
||||
int hi;
|
||||
int lo;
|
||||
unsigned int hi;
|
||||
unsigned int lo;
|
||||
|
||||
/* Binary search in the table. */
|
||||
if (table->table == NULL || table->count == 0 || ch < table->table[0].first)
|
||||
return 0;
|
||||
return FALSE;
|
||||
lo = 0;
|
||||
hi = table->count - 1;
|
||||
while (lo <= hi)
|
||||
{
|
||||
int mid = (lo + hi) / 2;
|
||||
unsigned int mid = (lo + hi) / 2;
|
||||
if (ch > table->table[mid].last)
|
||||
lo = mid + 1;
|
||||
else if (ch < table->table[mid].first)
|
||||
hi = mid - 1;
|
||||
else
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is a character a UTF-8 composing character?
|
||||
* If a composing character follows any char, the two combine into one glyph.
|
||||
*/
|
||||
public int is_composing_char(LWCHAR ch)
|
||||
public lbool is_composing_char(LWCHAR ch)
|
||||
{
|
||||
if (is_in_table(ch, &user_prt_table)) return 0;
|
||||
if (is_in_table(ch, &user_prt_table)) return FALSE;
|
||||
return is_in_table(ch, &user_compose_table) ||
|
||||
is_in_table(ch, &compose_table) ||
|
||||
(bs_mode != BS_CONTROL && is_in_table(ch, &fmt_table));
|
||||
|
|
@ -868,9 +857,9 @@ public int is_composing_char(LWCHAR ch)
|
|||
/*
|
||||
* Should this UTF-8 character be treated as binary?
|
||||
*/
|
||||
public int is_ubin_char(LWCHAR ch)
|
||||
public lbool is_ubin_char(LWCHAR ch)
|
||||
{
|
||||
if (is_in_table(ch, &user_prt_table)) return 0;
|
||||
if (is_in_table(ch, &user_prt_table)) return FALSE;
|
||||
return is_in_table(ch, &user_ubin_table) ||
|
||||
is_in_table(ch, &ubin_table) ||
|
||||
(bs_mode == BS_CONTROL && is_in_table(ch, &fmt_table));
|
||||
|
|
@ -879,7 +868,7 @@ public int is_ubin_char(LWCHAR ch)
|
|||
/*
|
||||
* Is this a double width UTF-8 character?
|
||||
*/
|
||||
public int is_wide_char(LWCHAR ch)
|
||||
public lbool is_wide_char(LWCHAR ch)
|
||||
{
|
||||
return is_in_table(ch, &user_wide_table) ||
|
||||
is_in_table(ch, &wide_table);
|
||||
|
|
@ -890,16 +879,16 @@ public int is_wide_char(LWCHAR ch)
|
|||
* A combining char acts like an ordinary char, but if it follows
|
||||
* a specific char (not any char), the two combine into one glyph.
|
||||
*/
|
||||
public int is_combining_char(LWCHAR ch1, LWCHAR ch2)
|
||||
public lbool is_combining_char(LWCHAR ch1, LWCHAR ch2)
|
||||
{
|
||||
/* The table is small; use linear search. */
|
||||
int i;
|
||||
for (i = 0; i < sizeof(comb_table)/sizeof(*comb_table); i++)
|
||||
for (i = 0; i < countof(comb_table); i++)
|
||||
{
|
||||
if (ch1 == comb_table[i].first &&
|
||||
ch2 == comb_table[i].last)
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
return 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -77,6 +77,10 @@
|
|||
#define A_X116MOUSE_IN 68
|
||||
#define A_PSHELL 69
|
||||
#define A_CLR_SEARCH 70
|
||||
#define A_OSC8_F_SEARCH 71
|
||||
#define A_OSC8_B_SEARCH 72
|
||||
#define A_OSC8_OPEN 73
|
||||
#define A_OSC8_JUMP 74
|
||||
|
||||
/* These values must not conflict with any A_* or EC_* value. */
|
||||
#define A_INVALID 100
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -24,26 +24,26 @@ extern int sc_width;
|
|||
extern int utf_mode;
|
||||
extern int no_hist_dups;
|
||||
extern int marks_modified;
|
||||
extern int secure;
|
||||
|
||||
static char cmdbuf[CMDBUF_SIZE]; /* Buffer for holding a multi-char command */
|
||||
static int cmd_col; /* Current column of the cursor */
|
||||
static int prompt_col; /* Column of cursor just after prompt */
|
||||
static char *cp; /* Pointer into cmdbuf */
|
||||
static int cmd_offset; /* Index into cmdbuf of first displayed char */
|
||||
static int literal; /* Next input char should not be interpreted */
|
||||
public int updown_match = -1; /* Prefix length in up/down movement */
|
||||
static lbool literal; /* Next input char should not be interpreted */
|
||||
static size_t updown_match; /* Prefix length in up/down movement */
|
||||
static lbool have_updown_match = FALSE;
|
||||
|
||||
#if TAB_COMPLETE_FILENAME
|
||||
static int cmd_complete(int action);
|
||||
/*
|
||||
* These variables are statics used by cmd_complete.
|
||||
*/
|
||||
static int in_completion = 0;
|
||||
static lbool in_completion = FALSE;
|
||||
static char *tk_text;
|
||||
static char *tk_original;
|
||||
static char *tk_ipoint;
|
||||
static char *tk_trial = NULL;
|
||||
static constant char *tk_ipoint;
|
||||
static constant char *tk_trial = NULL;
|
||||
static struct textlist tk_tlist;
|
||||
#endif
|
||||
|
||||
|
|
@ -72,7 +72,7 @@ struct mlist
|
|||
struct mlist *prev;
|
||||
struct mlist *curr_mp;
|
||||
char *string;
|
||||
int modified;
|
||||
lbool modified;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -123,9 +123,9 @@ public void cmd_reset(void)
|
|||
*cp = '\0';
|
||||
cmd_col = 0;
|
||||
cmd_offset = 0;
|
||||
literal = 0;
|
||||
literal = FALSE;
|
||||
cmd_mbc_buf_len = 0;
|
||||
updown_match = -1;
|
||||
have_updown_match = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -135,7 +135,7 @@ public void clear_cmd(void)
|
|||
{
|
||||
cmd_col = prompt_col = 0;
|
||||
cmd_mbc_buf_len = 0;
|
||||
updown_match = -1;
|
||||
have_updown_match = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -148,11 +148,11 @@ public void cmd_putstr(constant char *s)
|
|||
constant char *endline = s + strlen(s);
|
||||
while (*s != '\0')
|
||||
{
|
||||
char *ns = (char *) s;
|
||||
constant char *os = s;
|
||||
int width;
|
||||
ch = step_char(&ns, +1, endline);
|
||||
while (s < ns)
|
||||
putchr(*s++);
|
||||
ch = step_charc(&s, +1, endline);
|
||||
while (os < s)
|
||||
putchr(*os++);
|
||||
if (!utf_mode)
|
||||
width = 1;
|
||||
else if (is_composing_char(ch) || is_combining_char(prev_ch, ch))
|
||||
|
|
@ -170,13 +170,13 @@ public void cmd_putstr(constant char *s)
|
|||
*/
|
||||
public int len_cmdbuf(void)
|
||||
{
|
||||
char *s = cmdbuf;
|
||||
char *endline = s + strlen(s);
|
||||
constant char *s = cmdbuf;
|
||||
constant char *endline = s + strlen(s);
|
||||
int len = 0;
|
||||
|
||||
while (*s != '\0')
|
||||
{
|
||||
step_char(&s, +1, endline);
|
||||
step_charc(&s, +1, endline);
|
||||
len++;
|
||||
}
|
||||
return (len);
|
||||
|
|
@ -187,14 +187,14 @@ public int len_cmdbuf(void)
|
|||
* {{ Returning pwidth and bswidth separately is a historical artifact
|
||||
* since they're always the same. Maybe clean this up someday. }}
|
||||
*/
|
||||
static char * cmd_step_common(char *p, LWCHAR ch, int len, int *pwidth, int *bswidth)
|
||||
static constant char * cmd_step_common(char *p, LWCHAR ch, size_t len, int *pwidth, int *bswidth)
|
||||
{
|
||||
char *pr;
|
||||
constant char *pr;
|
||||
int width;
|
||||
|
||||
if (len == 1)
|
||||
{
|
||||
pr = prchar((int) ch);
|
||||
pr = prchar(ch);
|
||||
width = (int) strlen(pr);
|
||||
} else
|
||||
{
|
||||
|
|
@ -222,23 +222,23 @@ static char * cmd_step_common(char *p, LWCHAR ch, int len, int *pwidth, int *bsw
|
|||
/*
|
||||
* Step a pointer one character right in the command buffer.
|
||||
*/
|
||||
static char * cmd_step_right(char **pp, int *pwidth, int *bswidth)
|
||||
static constant char * cmd_step_right(char **pp, int *pwidth, int *bswidth)
|
||||
{
|
||||
char *p = *pp;
|
||||
LWCHAR ch = step_char(pp, +1, p + strlen(p));
|
||||
|
||||
return cmd_step_common(p, ch, *pp - p, pwidth, bswidth);
|
||||
return cmd_step_common(p, ch, ptr_diff(*pp, p), pwidth, bswidth);
|
||||
}
|
||||
|
||||
/*
|
||||
* Step a pointer one character left in the command buffer.
|
||||
*/
|
||||
static char * cmd_step_left(char **pp, int *pwidth, int *bswidth)
|
||||
static constant char * cmd_step_left(char **pp, int *pwidth, int *bswidth)
|
||||
{
|
||||
char *p = *pp;
|
||||
LWCHAR ch = step_char(pp, -1, cmdbuf);
|
||||
|
||||
return cmd_step_common(*pp, ch, p - *pp, pwidth, bswidth);
|
||||
return cmd_step_common(*pp, ch, ptr_diff(p, *pp), pwidth, bswidth);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -279,7 +279,7 @@ public void cmd_repaint(constant char *old_cp)
|
|||
{
|
||||
char *np = cp;
|
||||
int width;
|
||||
char *pr = cmd_step_right(&np, &width, NULL);
|
||||
constant char *pr = cmd_step_right(&np, &width, NULL);
|
||||
if (cmd_col + width >= sc_width)
|
||||
break;
|
||||
cp = np;
|
||||
|
|
@ -290,7 +290,7 @@ public void cmd_repaint(constant char *old_cp)
|
|||
{
|
||||
char *np = cp;
|
||||
int width;
|
||||
char *pr = cmd_step_right(&np, &width, NULL);
|
||||
constant char *pr = cmd_step_right(&np, &width, NULL);
|
||||
if (width > 0)
|
||||
break;
|
||||
cp = np;
|
||||
|
|
@ -375,7 +375,7 @@ static void cmd_rshift(void)
|
|||
*/
|
||||
static int cmd_right(void)
|
||||
{
|
||||
char *pr;
|
||||
constant char *pr;
|
||||
char *ncp;
|
||||
int width;
|
||||
|
||||
|
|
@ -437,7 +437,7 @@ static int cmd_left(void)
|
|||
/*
|
||||
* Insert a char into the command buffer, at the current position.
|
||||
*/
|
||||
static int cmd_ichar(char *cs, int clen)
|
||||
static int cmd_ichar(constant char *cs, size_t clen)
|
||||
{
|
||||
char *s;
|
||||
|
||||
|
|
@ -461,7 +461,7 @@ static int cmd_ichar(char *cs, int clen)
|
|||
/*
|
||||
* Reprint the tail of the line from the inserted char.
|
||||
*/
|
||||
updown_match = -1;
|
||||
have_updown_match = FALSE;
|
||||
cmd_repaint(cp);
|
||||
cmd_right();
|
||||
return (CC_OK);
|
||||
|
|
@ -504,7 +504,7 @@ static int cmd_erase(void)
|
|||
/*
|
||||
* Repaint the buffer after the erased char.
|
||||
*/
|
||||
updown_match = -1;
|
||||
have_updown_match = FALSE;
|
||||
cmd_repaint(cp);
|
||||
|
||||
/*
|
||||
|
|
@ -597,7 +597,7 @@ static int cmd_kill(void)
|
|||
cmd_offset = 0;
|
||||
cmd_home();
|
||||
*cp = '\0';
|
||||
updown_match = -1;
|
||||
have_updown_match = FALSE;
|
||||
cmd_repaint(cp);
|
||||
|
||||
/*
|
||||
|
|
@ -644,9 +644,10 @@ static int cmd_updown(int action)
|
|||
return (CC_OK);
|
||||
}
|
||||
|
||||
if (updown_match < 0)
|
||||
if (!have_updown_match)
|
||||
{
|
||||
updown_match = (int) (cp - cmdbuf);
|
||||
updown_match = ptr_diff(cp, cmdbuf);
|
||||
have_updown_match = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -687,7 +688,23 @@ static int cmd_updown(int action)
|
|||
bell();
|
||||
return (CC_OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Yet another lesson in the evils of global variables.
|
||||
*/
|
||||
public ssize_t save_updown_match(void)
|
||||
{
|
||||
if (!have_updown_match)
|
||||
return (ssize_t)(-1);
|
||||
return (ssize_t) updown_match;
|
||||
}
|
||||
|
||||
public void restore_updown_match(ssize_t udm)
|
||||
{
|
||||
updown_match = udm;
|
||||
have_updown_match = (udm != (ssize_t)(-1));
|
||||
}
|
||||
#endif /* CMD_HISTORY */
|
||||
|
||||
/*
|
||||
*
|
||||
|
|
@ -712,7 +729,7 @@ static void ml_unlink(struct mlist *ml)
|
|||
/*
|
||||
* Add a string to an mlist.
|
||||
*/
|
||||
public void cmd_addhist(struct mlist *mlist, constant char *cmd, int modified)
|
||||
public void cmd_addhist(struct mlist *mlist, constant char *cmd, lbool modified)
|
||||
{
|
||||
#if CMD_HISTORY
|
||||
struct mlist *ml;
|
||||
|
|
@ -774,8 +791,8 @@ public void cmd_accept(void)
|
|||
*/
|
||||
if (curr_mlist == NULL || curr_mlist == ml_examine)
|
||||
return;
|
||||
cmd_addhist(curr_mlist, cmdbuf, 1);
|
||||
curr_mlist->modified = 1;
|
||||
cmd_addhist(curr_mlist, cmdbuf, TRUE);
|
||||
curr_mlist->modified = TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -787,7 +804,7 @@ public void cmd_accept(void)
|
|||
* CC_OK Line edit function done.
|
||||
* CC_QUIT The char requests the current command to be aborted.
|
||||
*/
|
||||
static int cmd_edit(int c)
|
||||
static int cmd_edit(char c)
|
||||
{
|
||||
int action;
|
||||
int flags;
|
||||
|
|
@ -878,7 +895,7 @@ static int cmd_edit(int c)
|
|||
not_in_completion();
|
||||
return (cmd_wdelete());
|
||||
case EC_LITERAL:
|
||||
literal = 1;
|
||||
literal = TRUE;
|
||||
return (CC_OK);
|
||||
#if CMD_HISTORY
|
||||
case EC_UP:
|
||||
|
|
@ -902,17 +919,17 @@ static int cmd_edit(int c)
|
|||
/*
|
||||
* Insert a string into the command buffer, at the current position.
|
||||
*/
|
||||
static int cmd_istr(char *str)
|
||||
static int cmd_istr(constant char *str)
|
||||
{
|
||||
char *s;
|
||||
constant char *endline = str + strlen(str);
|
||||
constant char *s;
|
||||
int action;
|
||||
char *endline = str + strlen(str);
|
||||
|
||||
for (s = str; *s != '\0'; )
|
||||
{
|
||||
char *os = s;
|
||||
step_char(&s, +1, endline);
|
||||
action = cmd_ichar(os, s - os);
|
||||
constant char *os = s;
|
||||
step_charc(&s, +1, endline);
|
||||
action = cmd_ichar(os, ptr_diff(s, os));
|
||||
if (action != CC_OK)
|
||||
return (action);
|
||||
}
|
||||
|
|
@ -930,10 +947,10 @@ static char * delimit_word(void)
|
|||
char *word;
|
||||
#if SPACES_IN_FILENAMES
|
||||
char *p;
|
||||
int delim_quoted = 0;
|
||||
int meta_quoted = 0;
|
||||
int delim_quoted = FALSE;
|
||||
int meta_quoted = FALSE;
|
||||
constant char *esc = get_meta_escape();
|
||||
int esclen = (int) strlen(esc);
|
||||
size_t esclen = strlen(esc);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -984,20 +1001,20 @@ static char * delimit_word(void)
|
|||
{
|
||||
if (meta_quoted)
|
||||
{
|
||||
meta_quoted = 0;
|
||||
meta_quoted = FALSE;
|
||||
} else if (esclen > 0 && p + esclen < cp &&
|
||||
strncmp(p, esc, esclen) == 0)
|
||||
{
|
||||
meta_quoted = 1;
|
||||
meta_quoted = TRUE;
|
||||
p += esclen - 1;
|
||||
} else if (delim_quoted)
|
||||
{
|
||||
if (*p == closequote)
|
||||
delim_quoted = 0;
|
||||
delim_quoted = FALSE;
|
||||
} else /* (!delim_quoted) */
|
||||
{
|
||||
if (*p == openquote)
|
||||
delim_quoted = 1;
|
||||
delim_quoted = TRUE;
|
||||
else if (*p == ' ')
|
||||
word = p+1;
|
||||
}
|
||||
|
|
@ -1040,8 +1057,8 @@ static void init_compl(void)
|
|||
*/
|
||||
if (tk_original != NULL)
|
||||
free(tk_original);
|
||||
tk_original = (char *) ecalloc(cp-word+1, sizeof(char));
|
||||
strncpy(tk_original, word, cp-word);
|
||||
tk_original = (char *) ecalloc(ptr_diff(cp,word)+1, sizeof(char));
|
||||
strncpy(tk_original, word, ptr_diff(cp,word));
|
||||
/*
|
||||
* Get the expanded filename.
|
||||
* This may result in a single filename, or
|
||||
|
|
@ -1073,7 +1090,7 @@ static void init_compl(void)
|
|||
/*
|
||||
* Return the next word in the current completion list.
|
||||
*/
|
||||
static char * next_compl(int action, char *prev)
|
||||
static constant char * next_compl(int action, constant char *prev)
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
|
|
@ -1094,7 +1111,7 @@ static char * next_compl(int action, char *prev)
|
|||
*/
|
||||
static int cmd_complete(int action)
|
||||
{
|
||||
char *s;
|
||||
constant char *s;
|
||||
|
||||
if (!in_completion || action == EC_EXPAND)
|
||||
{
|
||||
|
|
@ -1120,7 +1137,7 @@ static int cmd_complete(int action)
|
|||
/*
|
||||
* Use the first filename in the list.
|
||||
*/
|
||||
in_completion = 1;
|
||||
in_completion = TRUE;
|
||||
init_textlist(&tk_tlist, tk_text);
|
||||
tk_trial = next_compl(action, (char*)NULL);
|
||||
}
|
||||
|
|
@ -1145,7 +1162,7 @@ static int cmd_complete(int action)
|
|||
* There are no more trial completions.
|
||||
* Insert the original (uncompleted) filename.
|
||||
*/
|
||||
in_completion = 0;
|
||||
in_completion = FALSE;
|
||||
if (cmd_istr(tk_original) != CC_OK)
|
||||
goto fail;
|
||||
} else
|
||||
|
|
@ -1173,7 +1190,7 @@ static int cmd_complete(int action)
|
|||
return (CC_OK);
|
||||
|
||||
fail:
|
||||
in_completion = 0;
|
||||
in_completion = FALSE;
|
||||
bell();
|
||||
return (CC_OK);
|
||||
}
|
||||
|
|
@ -1188,10 +1205,10 @@ fail:
|
|||
* CC_QUIT The char requests the command to be aborted.
|
||||
* CC_ERROR The char could not be accepted due to an error.
|
||||
*/
|
||||
public int cmd_char(int c)
|
||||
public int cmd_char(char c)
|
||||
{
|
||||
int action;
|
||||
int len;
|
||||
size_t len;
|
||||
|
||||
if (!utf_mode)
|
||||
{
|
||||
|
|
@ -1208,7 +1225,7 @@ public int cmd_char(int c)
|
|||
if (IS_ASCII_OCTET(c))
|
||||
cmd_mbc_buf_len = 1;
|
||||
#if MSDOS_COMPILER || OS2
|
||||
else if (c == (unsigned char) '\340' && IS_ASCII_OCTET(peekcc()))
|
||||
else if (c == '\340' && IS_ASCII_OCTET(peekcc()))
|
||||
{
|
||||
/* Assume a special key. */
|
||||
cmd_mbc_buf_len = 1;
|
||||
|
|
@ -1245,7 +1262,7 @@ public int cmd_char(int c)
|
|||
goto retry;
|
||||
}
|
||||
|
||||
len = cmd_mbc_buf_len;
|
||||
len = (size_t) cmd_mbc_buf_len; /*{{type-issue}}*/
|
||||
cmd_mbc_buf_len = 0;
|
||||
}
|
||||
|
||||
|
|
@ -1254,7 +1271,7 @@ public int cmd_char(int c)
|
|||
/*
|
||||
* Insert the char, even if it is a line-editing char.
|
||||
*/
|
||||
literal = 0;
|
||||
literal = FALSE;
|
||||
return (cmd_ichar(cmd_mbc_buf, len));
|
||||
}
|
||||
|
||||
|
|
@ -1283,11 +1300,11 @@ public int cmd_char(int c)
|
|||
/*
|
||||
* Return the number currently in the command buffer.
|
||||
*/
|
||||
public LINENUM cmd_int(long *frac)
|
||||
public LINENUM cmd_int(mutable long *frac)
|
||||
{
|
||||
char *p;
|
||||
constant char *p;
|
||||
LINENUM n = 0;
|
||||
int err;
|
||||
lbool err;
|
||||
|
||||
for (p = cmdbuf; *p >= '0' && *p <= '9'; p++)
|
||||
{
|
||||
|
|
@ -1309,7 +1326,7 @@ public LINENUM cmd_int(long *frac)
|
|||
/*
|
||||
* Return a pointer to the command buffer.
|
||||
*/
|
||||
public char * get_cmdbuf(void)
|
||||
public constant char * get_cmdbuf(void)
|
||||
{
|
||||
if (cmd_mbc_buf_index < cmd_mbc_buf_len)
|
||||
/* Don't return buffer containing an incomplete multibyte char. */
|
||||
|
|
@ -1321,7 +1338,7 @@ public char * get_cmdbuf(void)
|
|||
/*
|
||||
* Return the last (most recent) string in the current command history.
|
||||
*/
|
||||
public char * cmd_lastpattern(void)
|
||||
public constant char * cmd_lastpattern(void)
|
||||
{
|
||||
if (curr_mlist == NULL)
|
||||
return (NULL);
|
||||
|
|
@ -1343,9 +1360,9 @@ static int mlist_size(struct mlist *ml)
|
|||
/*
|
||||
* Get the name of the history file.
|
||||
*/
|
||||
static char * histfile_find(int must_exist)
|
||||
static char * histfile_find(lbool must_exist)
|
||||
{
|
||||
char *home = lgetenv("HOME");
|
||||
constant char *home = lgetenv("HOME");
|
||||
char *name = NULL;
|
||||
|
||||
/* Try in $XDG_STATE_HOME, then in $HOME/.local/state, then in $XDG_DATA_HOME, then in $HOME. */
|
||||
|
|
@ -1370,9 +1387,10 @@ static char * histfile_find(int must_exist)
|
|||
return (name);
|
||||
}
|
||||
|
||||
static char * histfile_name(int must_exist)
|
||||
static char * histfile_name(lbool must_exist)
|
||||
{
|
||||
char *name;
|
||||
constant char *name;
|
||||
char *wname;
|
||||
|
||||
/* See if filename is explicitly specified by $LESSHISTFILE. */
|
||||
name = lgetenv("LESSHISTFILE");
|
||||
|
|
@ -1388,30 +1406,29 @@ static char * histfile_name(int must_exist)
|
|||
if (strcmp(LESSHISTFILE, "") == 0 || strcmp(LESSHISTFILE, "-") == 0)
|
||||
return (NULL);
|
||||
|
||||
name = NULL;
|
||||
wname = NULL;
|
||||
if (!must_exist)
|
||||
{
|
||||
/* If we're writing the file and the file already exists, use it. */
|
||||
name = histfile_find(1);
|
||||
wname = histfile_find(TRUE);
|
||||
}
|
||||
if (name == NULL)
|
||||
name = histfile_find(must_exist);
|
||||
return (name);
|
||||
if (wname == NULL)
|
||||
wname = histfile_find(must_exist);
|
||||
return (wname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read a .lesshst file and call a callback for each line in the file.
|
||||
*/
|
||||
static void read_cmdhist2(void (*action)(void*,struct mlist*,char*), void *uparam, int skip_search, int skip_shell)
|
||||
static void read_cmdhist2(void (*action)(void*,struct mlist*,constant char*), void *uparam, int skip_search, int skip_shell)
|
||||
{
|
||||
struct mlist *ml = NULL;
|
||||
char line[CMDBUF_SIZE];
|
||||
char *filename;
|
||||
FILE *f;
|
||||
char *p;
|
||||
int *skip = NULL;
|
||||
|
||||
filename = histfile_name(1);
|
||||
filename = histfile_name(TRUE);
|
||||
if (filename == NULL)
|
||||
return;
|
||||
f = fopen(filename, "r");
|
||||
|
|
@ -1426,6 +1443,7 @@ static void read_cmdhist2(void (*action)(void*,struct mlist*,char*), void *upara
|
|||
}
|
||||
while (fgets(line, sizeof(line), f) != NULL)
|
||||
{
|
||||
char *p;
|
||||
for (p = line; *p != '\0'; p++)
|
||||
{
|
||||
if (*p == '\n' || *p == '\r')
|
||||
|
|
@ -1467,20 +1485,21 @@ static void read_cmdhist2(void (*action)(void*,struct mlist*,char*), void *upara
|
|||
fclose(f);
|
||||
}
|
||||
|
||||
static void read_cmdhist(void (*action)(void*,struct mlist*,char*), void *uparam, int skip_search, int skip_shell)
|
||||
static void read_cmdhist(void (*action)(void*,struct mlist*,constant char*), void *uparam, lbool skip_search, lbool skip_shell)
|
||||
{
|
||||
if (secure)
|
||||
if (!secure_allow(SF_HISTORY))
|
||||
return;
|
||||
read_cmdhist2(action, uparam, skip_search, skip_shell);
|
||||
(*action)(uparam, NULL, NULL); /* signal end of file */
|
||||
}
|
||||
|
||||
static void addhist_init(void *uparam, struct mlist *ml, char *string)
|
||||
static void addhist_init(void *uparam, struct mlist *ml, constant char *string)
|
||||
{
|
||||
(void) uparam;
|
||||
if (ml != NULL)
|
||||
cmd_addhist(ml, string, 0);
|
||||
else if (string != NULL)
|
||||
restore_mark((char*)string); /* stupid const cast */
|
||||
restore_mark(string);
|
||||
}
|
||||
#endif /* CMD_HISTORY */
|
||||
|
||||
|
|
@ -1518,15 +1537,15 @@ static void write_mlist(struct mlist *ml, FILE *f)
|
|||
if (!ml->modified)
|
||||
continue;
|
||||
fprintf(f, "\"%s\n", ml->string);
|
||||
ml->modified = 0;
|
||||
ml->modified = FALSE;
|
||||
}
|
||||
ml->modified = 0; /* entire mlist is now unmodified */
|
||||
ml->modified = FALSE; /* entire mlist is now unmodified */
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a temp name in the same directory as filename.
|
||||
*/
|
||||
static char * make_tempname(char *filename)
|
||||
static char * make_tempname(constant char *filename)
|
||||
{
|
||||
char lastch;
|
||||
char *tempname = ecalloc(1, strlen(filename)+1);
|
||||
|
|
@ -1547,7 +1566,7 @@ struct save_ctx
|
|||
* At the end of each mlist, append any new entries
|
||||
* created during this session.
|
||||
*/
|
||||
static void copy_hist(void *uparam, struct mlist *ml, char *string)
|
||||
static void copy_hist(void *uparam, struct mlist *ml, constant char *string)
|
||||
{
|
||||
struct save_ctx *ctx = (struct save_ctx *) uparam;
|
||||
|
||||
|
|
@ -1591,13 +1610,13 @@ static void copy_hist(void *uparam, struct mlist *ml, char *string)
|
|||
static void make_file_private(FILE *f)
|
||||
{
|
||||
#if HAVE_FCHMOD
|
||||
int do_chmod = 1;
|
||||
lbool do_chmod = TRUE;
|
||||
#if HAVE_STAT
|
||||
struct stat statbuf;
|
||||
int r = fstat(fileno(f), &statbuf);
|
||||
if (r < 0 || !S_ISREG(statbuf.st_mode))
|
||||
/* Don't chmod if not a regular file. */
|
||||
do_chmod = 0;
|
||||
do_chmod = FALSE;
|
||||
#endif
|
||||
if (do_chmod)
|
||||
fchmod(fileno(f), 0600);
|
||||
|
|
@ -1608,17 +1627,17 @@ static void make_file_private(FILE *f)
|
|||
* Does the history file need to be updated?
|
||||
*/
|
||||
#if CMD_HISTORY
|
||||
static int histfile_modified(void)
|
||||
static lbool histfile_modified(void)
|
||||
{
|
||||
if (mlist_search.modified)
|
||||
return 1;
|
||||
return TRUE;
|
||||
#if SHELL_ESCAPE || PIPEC
|
||||
if (mlist_shell.modified)
|
||||
return 1;
|
||||
return TRUE;
|
||||
#endif
|
||||
if (marks_modified)
|
||||
return 1;
|
||||
return 0;
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1633,11 +1652,11 @@ public void save_cmdhist(void)
|
|||
int skip_search;
|
||||
int skip_shell;
|
||||
struct save_ctx ctx;
|
||||
char *s;
|
||||
constant char *s;
|
||||
FILE *fout = NULL;
|
||||
int histsize = 0;
|
||||
|
||||
if (secure || !histfile_modified())
|
||||
if (!secure_allow(SF_HISTORY) || !histfile_modified())
|
||||
return;
|
||||
histname = histfile_name(0);
|
||||
if (histname == NULL)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* $FreeBSD$ */
|
||||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -25,7 +25,6 @@ extern int erase_char, erase2_char, kill_char;
|
|||
extern int sigs;
|
||||
extern int quit_if_one_screen;
|
||||
extern int one_screen;
|
||||
extern int squished;
|
||||
extern int sc_width;
|
||||
extern int sc_height;
|
||||
extern char *kent;
|
||||
|
|
@ -35,16 +34,12 @@ extern int quitting;
|
|||
extern int wscroll;
|
||||
extern int top_scroll;
|
||||
extern int ignore_eoi;
|
||||
extern int secure;
|
||||
extern int hshift;
|
||||
extern int bs_mode;
|
||||
extern int proc_backspace;
|
||||
extern int show_attn;
|
||||
extern int less_is_more;
|
||||
extern int status_col;
|
||||
extern POSITION highest_hilite;
|
||||
extern POSITION start_attnpos;
|
||||
extern POSITION end_attnpos;
|
||||
extern char *every_first_cmd;
|
||||
extern char version[];
|
||||
extern struct scrpos initial_scrpos;
|
||||
|
|
@ -52,24 +47,24 @@ extern IFILE curr_ifile;
|
|||
extern void *ml_search;
|
||||
extern void *ml_examine;
|
||||
extern int wheel_lines;
|
||||
extern int header_lines;
|
||||
extern int def_search_type;
|
||||
extern int updown_match;
|
||||
extern lbool search_wrapped;
|
||||
#if SHELL_ESCAPE || PIPEC
|
||||
extern void *ml_shell;
|
||||
#endif
|
||||
#if EDITOR
|
||||
extern char *editor;
|
||||
extern char *editproto;
|
||||
extern constant char *editproto;
|
||||
#endif
|
||||
#if OSC8_LINK
|
||||
extern char *osc8_uri;
|
||||
#endif
|
||||
extern int screen_trashed; /* The screen has been overwritten */
|
||||
extern int shift_count;
|
||||
extern int oldbot;
|
||||
extern int forw_prompt;
|
||||
extern int incr_search;
|
||||
extern int full_screen;
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
extern int utf_mode;
|
||||
extern unsigned less_acp;
|
||||
#endif
|
||||
|
||||
#if SHELL_ESCAPE
|
||||
|
|
@ -83,11 +78,13 @@ static long fraction; /* The fractional part of the number */
|
|||
static struct loption *curropt;
|
||||
static int opt_lower;
|
||||
static int optflag;
|
||||
static int optgetname;
|
||||
static lbool optgetname;
|
||||
static POSITION bottompos;
|
||||
static int save_hshift;
|
||||
static int save_bs_mode;
|
||||
static int save_proc_backspace;
|
||||
static int screen_trashed_value = 0;
|
||||
static lbool literal_char = FALSE;
|
||||
#if PIPEC
|
||||
static char pipec;
|
||||
#endif
|
||||
|
|
@ -95,11 +92,12 @@ static char pipec;
|
|||
/* Stack of ungotten chars (via ungetcc) */
|
||||
struct ungot {
|
||||
struct ungot *ug_next;
|
||||
LWCHAR ug_char;
|
||||
char ug_char;
|
||||
lbool ug_end_command;
|
||||
};
|
||||
static struct ungot* ungot = NULL;
|
||||
|
||||
static void multi_search (char *pattern, int n, int silent);
|
||||
static void multi_search(constant char *pattern, int n, int silent);
|
||||
|
||||
/*
|
||||
* Move the cursor to start of prompt line before executing a command.
|
||||
|
|
@ -186,6 +184,8 @@ static void mca_search1(void)
|
|||
cmd_putstr(buf);
|
||||
}
|
||||
}
|
||||
if (literal_char)
|
||||
cmd_putstr("Lit ");
|
||||
|
||||
#if HILITE_SEARCH
|
||||
if (search_type & SRCH_FILTER)
|
||||
|
|
@ -210,14 +210,10 @@ static void mca_search(void)
|
|||
*/
|
||||
static void mca_opt_toggle(void)
|
||||
{
|
||||
int no_prompt;
|
||||
int flag;
|
||||
char *dash;
|
||||
int no_prompt = (optflag & OPT_NO_PROMPT);
|
||||
int flag = (optflag & ~OPT_NO_PROMPT);
|
||||
constant char *dash = (flag == OPT_NO_TOGGLE) ? "_" : "-";
|
||||
|
||||
no_prompt = (optflag & OPT_NO_PROMPT);
|
||||
flag = (optflag & ~OPT_NO_PROMPT);
|
||||
dash = (flag == OPT_NO_TOGGLE) ? "_" : "-";
|
||||
|
||||
set_mca(A_OPT_TOGGLE);
|
||||
cmd_putstr(dash);
|
||||
if (optgetname)
|
||||
|
|
@ -242,7 +238,8 @@ static void mca_opt_toggle(void)
|
|||
*/
|
||||
static void exec_mca(void)
|
||||
{
|
||||
char *cbuf;
|
||||
constant char *cbuf;
|
||||
char *p;
|
||||
|
||||
cmd_exec();
|
||||
cbuf = get_cmdbuf();
|
||||
|
|
@ -286,9 +283,11 @@ static void exec_mca(void)
|
|||
break;
|
||||
#if EXAMINE
|
||||
case A_EXAMINE:
|
||||
if (secure)
|
||||
if (!secure_allow(SF_EXAMINE))
|
||||
break;
|
||||
edit_list(cbuf);
|
||||
p = save(cbuf);
|
||||
edit_list(p);
|
||||
free(p);
|
||||
#if TAGS
|
||||
/* If tag structure is loaded then clean it up. */
|
||||
cleantags();
|
||||
|
|
@ -296,39 +295,47 @@ static void exec_mca(void)
|
|||
break;
|
||||
#endif
|
||||
#if SHELL_ESCAPE
|
||||
case A_SHELL:
|
||||
case A_SHELL: {
|
||||
/*
|
||||
* !! just uses whatever is in shellcmd.
|
||||
* Otherwise, copy cmdbuf to shellcmd,
|
||||
* expanding any special characters ("%" or "#").
|
||||
*/
|
||||
constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "!done";
|
||||
if (done_msg == NULL)
|
||||
++cbuf;
|
||||
if (*cbuf != '!')
|
||||
{
|
||||
if (shellcmd != NULL)
|
||||
free(shellcmd);
|
||||
shellcmd = fexpand(cbuf);
|
||||
}
|
||||
|
||||
if (secure)
|
||||
if (!secure_allow(SF_SHELL))
|
||||
break;
|
||||
if (shellcmd == NULL)
|
||||
lsystem("", "!done");
|
||||
else
|
||||
lsystem(shellcmd, "!done");
|
||||
break;
|
||||
case A_PSHELL:
|
||||
if (secure)
|
||||
shellcmd = "";
|
||||
lsystem(shellcmd, done_msg);
|
||||
break; }
|
||||
case A_PSHELL: {
|
||||
constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "#done";
|
||||
if (done_msg == NULL)
|
||||
++cbuf;
|
||||
if (!secure_allow(SF_SHELL))
|
||||
break;
|
||||
lsystem(pr_expand(cbuf), "#done");
|
||||
break;
|
||||
lsystem(pr_expand(cbuf), done_msg);
|
||||
break; }
|
||||
#endif
|
||||
#if PIPEC
|
||||
case A_PIPE:
|
||||
if (secure)
|
||||
case A_PIPE: {
|
||||
constant char *done_msg = (*cbuf == CONTROL('P')) ? NULL : "|done";
|
||||
if (done_msg == NULL)
|
||||
++cbuf;
|
||||
if (!secure_allow(SF_PIPE))
|
||||
break;
|
||||
(void) pipe_mark(pipec, cbuf);
|
||||
error("|done", NULL_PARG);
|
||||
break;
|
||||
if (done_msg != NULL)
|
||||
error(done_msg, NULL_PARG);
|
||||
break; }
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -336,7 +343,7 @@ static void exec_mca(void)
|
|||
/*
|
||||
* Is a character an erase or kill char?
|
||||
*/
|
||||
static int is_erase_char(int c)
|
||||
static lbool is_erase_char(char c)
|
||||
{
|
||||
return (c == erase_char || c == erase2_char || c == kill_char);
|
||||
}
|
||||
|
|
@ -344,7 +351,7 @@ static int is_erase_char(int c)
|
|||
/*
|
||||
* Is a character a carriage return or newline?
|
||||
*/
|
||||
static int is_newline_char(int c)
|
||||
static lbool is_newline_char(char c)
|
||||
{
|
||||
return (c == '\n' || c == '\r');
|
||||
}
|
||||
|
|
@ -352,7 +359,7 @@ static int is_newline_char(int c)
|
|||
/*
|
||||
* Handle the first char of an option (after the initial dash).
|
||||
*/
|
||||
static int mca_opt_first_char(int c)
|
||||
static int mca_opt_first_char(char c)
|
||||
{
|
||||
int no_prompt = (optflag & OPT_NO_PROMPT);
|
||||
int flag = (optflag & ~OPT_NO_PROMPT);
|
||||
|
|
@ -403,11 +410,11 @@ static int mca_opt_first_char(int c)
|
|||
* If so, display the complete name and stop
|
||||
* accepting chars until user hits RETURN.
|
||||
*/
|
||||
static int mca_opt_nonfirst_char(int c)
|
||||
static int mca_opt_nonfirst_char(char c)
|
||||
{
|
||||
char *p;
|
||||
char *oname;
|
||||
int err;
|
||||
constant char *p;
|
||||
constant char *oname;
|
||||
lbool ambig;
|
||||
|
||||
if (curropt != NULL)
|
||||
{
|
||||
|
|
@ -429,8 +436,7 @@ static int mca_opt_nonfirst_char(int c)
|
|||
if (p == NULL)
|
||||
return (MCA_MORE);
|
||||
opt_lower = ASCII_IS_LOWER(p[0]);
|
||||
err = 0;
|
||||
curropt = findopt_name(&p, &oname, &err);
|
||||
curropt = findopt_name(&p, &oname, &ambig);
|
||||
if (curropt != NULL)
|
||||
{
|
||||
/*
|
||||
|
|
@ -448,7 +454,7 @@ static int mca_opt_nonfirst_char(int c)
|
|||
if (cmd_char(c) != CC_OK)
|
||||
return (MCA_DONE);
|
||||
}
|
||||
} else if (err != OPT_AMBIG)
|
||||
} else if (!ambig)
|
||||
{
|
||||
bell();
|
||||
}
|
||||
|
|
@ -458,7 +464,7 @@ static int mca_opt_nonfirst_char(int c)
|
|||
/*
|
||||
* Handle a char of an option toggle command.
|
||||
*/
|
||||
static int mca_opt_char(int c)
|
||||
static int mca_opt_char(char c)
|
||||
{
|
||||
PARG parg;
|
||||
|
||||
|
|
@ -518,7 +524,7 @@ static int mca_opt_char(int c)
|
|||
/*
|
||||
* Display a prompt appropriate for the option parameter.
|
||||
*/
|
||||
start_mca(A_OPT_TOGGLE, opt_prompt(curropt), (void*)NULL, 0);
|
||||
start_mca(A_OPT_TOGGLE, opt_prompt(curropt), NULL, 0);
|
||||
return (MCA_MORE);
|
||||
}
|
||||
|
||||
|
|
@ -536,7 +542,7 @@ public int norm_search_type(int st)
|
|||
/*
|
||||
* Handle a char of a search command.
|
||||
*/
|
||||
static int mca_search_char(int c)
|
||||
static int mca_search_char(char c)
|
||||
{
|
||||
int flag = 0;
|
||||
|
||||
|
|
@ -547,8 +553,11 @@ static int mca_search_char(int c)
|
|||
* * Toggle the PAST_EOF flag
|
||||
* @ Toggle the FIRST_FILE flag
|
||||
*/
|
||||
if (len_cmdbuf() > 0)
|
||||
if (len_cmdbuf() > 0 || literal_char)
|
||||
{
|
||||
literal_char = FALSE;
|
||||
return (NO_MCA);
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
|
|
@ -594,6 +603,10 @@ static int mca_search_char(int c)
|
|||
case '!':
|
||||
flag = SRCH_NO_MATCH;
|
||||
break;
|
||||
case CONTROL('L'):
|
||||
literal_char = TRUE;
|
||||
flag = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (flag != 0)
|
||||
|
|
@ -609,7 +622,7 @@ static int mca_search_char(int c)
|
|||
/*
|
||||
* Handle a character of a multi-character command.
|
||||
*/
|
||||
static int mca_char(int c)
|
||||
static int mca_char(char c)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
|
@ -718,7 +731,8 @@ static int mca_char(int c)
|
|||
{
|
||||
/* Incremental search: do a search after every input char. */
|
||||
int st = (search_type & (SRCH_FORW|SRCH_BACK|SRCH_NO_MATCH|SRCH_NO_REGEX|SRCH_NO_MOVE|SRCH_WRAP|SRCH_SUBSEARCH_ALL));
|
||||
char *pattern = get_cmdbuf();
|
||||
ssize_t save_updown;
|
||||
constant char *pattern = get_cmdbuf();
|
||||
if (pattern == NULL)
|
||||
return (MCA_MORE);
|
||||
/*
|
||||
|
|
@ -726,7 +740,7 @@ static int mca_char(int c)
|
|||
* reinits it. That breaks history scrolling.
|
||||
* {{ This is ugly. mca_search probably shouldn't call set_mlist. }}
|
||||
*/
|
||||
int save_updown_match = updown_match;
|
||||
save_updown = save_updown_match();
|
||||
cmd_exec();
|
||||
if (*pattern == '\0')
|
||||
{
|
||||
|
|
@ -739,13 +753,13 @@ static int mca_char(int c)
|
|||
undo_search(1);
|
||||
}
|
||||
/* Redraw the search prompt and search string. */
|
||||
if (!full_screen)
|
||||
if (is_screen_trashed() || !full_screen)
|
||||
{
|
||||
clear();
|
||||
repaint();
|
||||
}
|
||||
mca_search1();
|
||||
updown_match = save_updown_match;
|
||||
restore_updown_match(save_updown);
|
||||
cmd_repaint(NULL);
|
||||
}
|
||||
break;
|
||||
|
|
@ -771,6 +785,21 @@ static void clear_buffers(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
public void screen_trashed_num(int trashed)
|
||||
{
|
||||
screen_trashed_value = trashed;
|
||||
}
|
||||
|
||||
public void screen_trashed(void)
|
||||
{
|
||||
screen_trashed_num(1);
|
||||
}
|
||||
|
||||
public int is_screen_trashed(void)
|
||||
{
|
||||
return screen_trashed_value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure the screen is displayed.
|
||||
*/
|
||||
|
|
@ -791,13 +820,13 @@ static void make_display(void)
|
|||
jump_loc(ch_zero(), 1);
|
||||
else
|
||||
jump_loc(initial_scrpos.pos, initial_scrpos.ln);
|
||||
} else if (screen_trashed || !full_screen)
|
||||
} else if (is_screen_trashed() || !full_screen)
|
||||
{
|
||||
int save_top_scroll = top_scroll;
|
||||
int save_ignore_eoi = ignore_eoi;
|
||||
top_scroll = 1;
|
||||
ignore_eoi = 0;
|
||||
if (screen_trashed == 2)
|
||||
if (is_screen_trashed() == 2)
|
||||
{
|
||||
/* Special case used by ignore_eoi: re-open the input file
|
||||
* and jump to the end of the file. */
|
||||
|
|
@ -817,7 +846,7 @@ static void prompt(void)
|
|||
{
|
||||
constant char *p;
|
||||
|
||||
if (ungot != NULL && ungot->ug_char != CHAR_END_COMMAND)
|
||||
if (ungot != NULL && !ungot->ug_end_command)
|
||||
{
|
||||
/*
|
||||
* No prompt necessary if commands are from
|
||||
|
|
@ -857,7 +886,7 @@ static void prompt(void)
|
|||
{
|
||||
WCHAR w[MAX_PATH+16];
|
||||
p = pr_expand("Less?f - %f.");
|
||||
MultiByteToWideChar(CP_ACP, 0, p, -1, w, sizeof(w)/sizeof(*w));
|
||||
MultiByteToWideChar(less_acp, 0, p, -1, w, countof(w));
|
||||
SetConsoleTitleW(w);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -883,6 +912,24 @@ static void prompt(void)
|
|||
#if HILITE_SEARCH
|
||||
if (is_filtering())
|
||||
putstr("& ");
|
||||
#endif
|
||||
if (search_wrapped)
|
||||
{
|
||||
if (search_type & SRCH_BACK)
|
||||
error("Search hit top; continuing at bottom", NULL_PARG);
|
||||
else
|
||||
error("Search hit bottom; continuing at top", NULL_PARG);
|
||||
search_wrapped = FALSE;
|
||||
}
|
||||
#if OSC8_LINK
|
||||
if (osc8_uri != NULL)
|
||||
{
|
||||
PARG parg;
|
||||
parg.p_string = osc8_uri;
|
||||
error("Link: %s", &parg);
|
||||
free(osc8_uri);
|
||||
osc8_uri = NULL;
|
||||
}
|
||||
#endif
|
||||
if (p == NULL || *p == '\0')
|
||||
{
|
||||
|
|
@ -894,7 +941,7 @@ static void prompt(void)
|
|||
#if MSDOS_COMPILER==WIN32C
|
||||
WCHAR w[MAX_PATH*2];
|
||||
char a[MAX_PATH*2];
|
||||
MultiByteToWideChar(CP_ACP, 0, p, -1, w, sizeof(w)/sizeof(*w));
|
||||
MultiByteToWideChar(less_acp, 0, p, -1, w, countof(w));
|
||||
WideCharToMultiByte(utf_mode ? CP_UTF8 : GetConsoleOutputCP(),
|
||||
0, w, -1, a, sizeof(a), NULL, NULL);
|
||||
p = a;
|
||||
|
|
@ -919,8 +966,9 @@ public void dispversion(void)
|
|||
/*
|
||||
* Return a character to complete a partial command, if possible.
|
||||
*/
|
||||
static LWCHAR getcc_end_command(void)
|
||||
static char getcc_end_command(void)
|
||||
{
|
||||
int ch;
|
||||
switch (mca)
|
||||
{
|
||||
case A_DIGIT:
|
||||
|
|
@ -933,51 +981,76 @@ static LWCHAR getcc_end_command(void)
|
|||
return ('\n');
|
||||
default:
|
||||
/* Some other incomplete command. Let user complete it. */
|
||||
return ((ungot == NULL) ? getchr() : 0);
|
||||
if (ungot != NULL)
|
||||
return ('\0');
|
||||
ch = getchr();
|
||||
if (ch < 0) ch = '\0';
|
||||
return (char) ch;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a command character from the ungotten stack.
|
||||
*/
|
||||
static char get_ungot(lbool *p_end_command)
|
||||
{
|
||||
struct ungot *ug = ungot;
|
||||
char c = ug->ug_char;
|
||||
if (p_end_command != NULL)
|
||||
*p_end_command = ug->ug_end_command;
|
||||
ungot = ug->ug_next;
|
||||
free(ug);
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete all ungotten characters.
|
||||
*/
|
||||
public void getcc_clear(void)
|
||||
{
|
||||
while (ungot != NULL)
|
||||
(void) get_ungot(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get command character.
|
||||
* The character normally comes from the keyboard,
|
||||
* but may come from ungotten characters
|
||||
* (characters previously given to ungetcc or ungetsc).
|
||||
*/
|
||||
static LWCHAR getccu(void)
|
||||
static char getccu(void)
|
||||
{
|
||||
LWCHAR c = 0;
|
||||
while (c == 0)
|
||||
int c = 0;
|
||||
while (c == 0 && !ABORT_SIGS())
|
||||
{
|
||||
if (ungot == NULL)
|
||||
{
|
||||
/* Normal case: no ungotten chars.
|
||||
* Get char from the user. */
|
||||
c = getchr();
|
||||
if (c < 0) return ('\0');
|
||||
} else
|
||||
{
|
||||
/* Ungotten chars available:
|
||||
* Take the top of stack (most recent). */
|
||||
struct ungot *ug = ungot;
|
||||
c = ug->ug_char;
|
||||
ungot = ug->ug_next;
|
||||
free(ug);
|
||||
|
||||
if (c == CHAR_END_COMMAND)
|
||||
lbool end_command;
|
||||
c = get_ungot(&end_command);
|
||||
if (end_command)
|
||||
c = getcc_end_command();
|
||||
}
|
||||
}
|
||||
return (c);
|
||||
return ((char) c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a command character, but if we receive the orig sequence,
|
||||
* convert it to the repl sequence.
|
||||
*/
|
||||
static LWCHAR getcc_repl(char constant *orig, char constant *repl, LWCHAR (*gr_getc)(void), void (*gr_ungetc)(LWCHAR))
|
||||
static char getcc_repl(char constant *orig, char constant *repl, char (*gr_getc)(void), void (*gr_ungetc)(char))
|
||||
{
|
||||
LWCHAR c;
|
||||
LWCHAR keys[16];
|
||||
int ki = 0;
|
||||
char c;
|
||||
char keys[16];
|
||||
size_t ki = 0;
|
||||
|
||||
c = (*gr_getc)();
|
||||
if (orig == NULL || orig[0] == '\0')
|
||||
|
|
@ -1012,7 +1085,7 @@ static LWCHAR getcc_repl(char constant *orig, char constant *repl, LWCHAR (*gr_g
|
|||
/*
|
||||
* Get command character.
|
||||
*/
|
||||
public int getcc(void)
|
||||
public char getcc(void)
|
||||
{
|
||||
/* Replace kent (keypad Enter) with a newline. */
|
||||
return getcc_repl(kent, "\n", getccu, ungetcc);
|
||||
|
|
@ -1022,7 +1095,7 @@ public int getcc(void)
|
|||
* "Unget" a command character.
|
||||
* The next getcc() will return this character.
|
||||
*/
|
||||
public void ungetcc(LWCHAR c)
|
||||
public void ungetcc(char c)
|
||||
{
|
||||
struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot));
|
||||
|
||||
|
|
@ -1035,10 +1108,11 @@ public void ungetcc(LWCHAR c)
|
|||
* "Unget" a command character.
|
||||
* If any other chars are already ungotten, put this one after those.
|
||||
*/
|
||||
public void ungetcc_back(LWCHAR c)
|
||||
static void ungetcc_back1(char c, lbool end_command)
|
||||
{
|
||||
struct ungot *ug = (struct ungot *) ecalloc(1, sizeof(struct ungot));
|
||||
ug->ug_char = c;
|
||||
ug->ug_end_command = end_command;
|
||||
ug->ug_next = NULL;
|
||||
if (ungot == NULL)
|
||||
ungot = ug;
|
||||
|
|
@ -1051,11 +1125,21 @@ public void ungetcc_back(LWCHAR c)
|
|||
}
|
||||
}
|
||||
|
||||
public void ungetcc_back(char c)
|
||||
{
|
||||
ungetcc_back1(c, FALSE);
|
||||
}
|
||||
|
||||
public void ungetcc_end_command(void)
|
||||
{
|
||||
ungetcc_back1('\0', TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Unget a whole string of command characters.
|
||||
* The next sequence of getcc()'s will return this string.
|
||||
*/
|
||||
public void ungetsc(char *s)
|
||||
public void ungetsc(constant char *s)
|
||||
{
|
||||
while (*s != '\0')
|
||||
ungetcc_back(*s++);
|
||||
|
|
@ -1064,9 +1148,9 @@ public void ungetsc(char *s)
|
|||
/*
|
||||
* Peek the next command character, without consuming it.
|
||||
*/
|
||||
public LWCHAR peekcc(void)
|
||||
public char peekcc(void)
|
||||
{
|
||||
LWCHAR c = getcc();
|
||||
char c = getcc();
|
||||
ungetcc(c);
|
||||
return c;
|
||||
}
|
||||
|
|
@ -1076,13 +1160,13 @@ public LWCHAR peekcc(void)
|
|||
* If SRCH_FIRST_FILE is set, begin searching at the first file.
|
||||
* If SRCH_PAST_EOF is set, continue the search thru multiple files.
|
||||
*/
|
||||
static void multi_search(char *pattern, int n, int silent)
|
||||
static void multi_search(constant char *pattern, int n, int silent)
|
||||
{
|
||||
int nomore;
|
||||
IFILE save_ifile;
|
||||
int changed_file;
|
||||
lbool changed_file;
|
||||
|
||||
changed_file = 0;
|
||||
changed_file = FALSE;
|
||||
save_ifile = save_curr_ifile();
|
||||
|
||||
if ((search_type & (SRCH_FORW|SRCH_BACK)) == 0)
|
||||
|
|
@ -1102,7 +1186,7 @@ static void multi_search(char *pattern, int n, int silent)
|
|||
unsave_ifile(save_ifile);
|
||||
return;
|
||||
}
|
||||
changed_file = 1;
|
||||
changed_file = TRUE;
|
||||
search_type &= ~SRCH_FIRST_FILE;
|
||||
}
|
||||
|
||||
|
|
@ -1147,7 +1231,7 @@ static void multi_search(char *pattern, int n, int silent)
|
|||
nomore = edit_prev(1);
|
||||
if (nomore)
|
||||
break;
|
||||
changed_file = 1;
|
||||
changed_file = TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1213,18 +1297,18 @@ static int forw_loop(int until_hilite)
|
|||
*/
|
||||
public void commands(void)
|
||||
{
|
||||
int c;
|
||||
char c;
|
||||
int action;
|
||||
char *cbuf;
|
||||
constant char *cbuf;
|
||||
constant char *msg;
|
||||
int newaction;
|
||||
int save_jump_sline;
|
||||
int save_search_type;
|
||||
char *extra;
|
||||
char tbuf[2];
|
||||
constant char *extra;
|
||||
PARG parg;
|
||||
IFILE old_ifile;
|
||||
IFILE new_ifile;
|
||||
char *tagfile;
|
||||
constant char *tagfile;
|
||||
|
||||
search_type = SRCH_FORW;
|
||||
wscroll = (sc_height + 1) / 2;
|
||||
|
|
@ -1304,6 +1388,7 @@ public void commands(void)
|
|||
/*
|
||||
* Decode the command character and decide what to do.
|
||||
*/
|
||||
extra = NULL;
|
||||
if (mca)
|
||||
{
|
||||
/*
|
||||
|
|
@ -1318,6 +1403,7 @@ public void commands(void)
|
|||
cbuf = get_cmdbuf();
|
||||
if (cbuf == NULL)
|
||||
continue;
|
||||
action = fcmd_decode(cbuf, &extra);
|
||||
} else
|
||||
{
|
||||
/*
|
||||
|
|
@ -1328,12 +1414,9 @@ public void commands(void)
|
|||
* want erase_char/kill_char to be treated
|
||||
* as line editing characters.
|
||||
*/
|
||||
tbuf[0] = c;
|
||||
tbuf[1] = '\0';
|
||||
cbuf = tbuf;
|
||||
constant char tbuf[2] = { c, '\0' };
|
||||
action = fcmd_decode(tbuf, &extra);
|
||||
}
|
||||
extra = NULL;
|
||||
action = fcmd_decode(cbuf, &extra);
|
||||
/*
|
||||
* If an "extra" string was returned,
|
||||
* process it as a string of command characters.
|
||||
|
|
@ -1355,7 +1438,7 @@ public void commands(void)
|
|||
/*
|
||||
* First digit of a number.
|
||||
*/
|
||||
start_mca(A_DIGIT, ":", (void*)NULL, CF_QUIT_ON_ERASE);
|
||||
start_mca(A_DIGIT, ":", NULL, CF_QUIT_ON_ERASE);
|
||||
goto again;
|
||||
|
||||
case A_F_WINDOW:
|
||||
|
|
@ -1634,7 +1717,7 @@ public void commands(void)
|
|||
if (number <= 0) number = 1; \
|
||||
mca_search(); \
|
||||
cmd_exec(); \
|
||||
multi_search((char *)NULL, (int) number, 0);
|
||||
multi_search(NULL, (int) number, 0);
|
||||
|
||||
case A_F_SEARCH:
|
||||
/*
|
||||
|
|
@ -1644,6 +1727,7 @@ public void commands(void)
|
|||
search_type = SRCH_FORW | def_search_type;
|
||||
if (number <= 0)
|
||||
number = 1;
|
||||
literal_char = FALSE;
|
||||
mca_search();
|
||||
c = getcc();
|
||||
goto again;
|
||||
|
|
@ -1656,13 +1740,58 @@ public void commands(void)
|
|||
search_type = SRCH_BACK | def_search_type;
|
||||
if (number <= 0)
|
||||
number = 1;
|
||||
literal_char = FALSE;
|
||||
mca_search();
|
||||
c = getcc();
|
||||
goto again;
|
||||
|
||||
case A_OSC8_F_SEARCH:
|
||||
#if OSC8_LINK
|
||||
cmd_exec();
|
||||
if (number <= 0)
|
||||
number = 1;
|
||||
osc8_search(SRCH_FORW, NULL, number);
|
||||
#else
|
||||
error("Command not available", NULL_PARG);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case A_OSC8_B_SEARCH:
|
||||
#if OSC8_LINK
|
||||
cmd_exec();
|
||||
if (number <= 0)
|
||||
number = 1;
|
||||
osc8_search(SRCH_BACK, NULL, number);
|
||||
#else
|
||||
error("Command not available", NULL_PARG);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case A_OSC8_OPEN:
|
||||
#if OSC8_LINK
|
||||
if (secure_allow(SF_OSC8_OPEN))
|
||||
{
|
||||
cmd_exec();
|
||||
osc8_open();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
error("Command not available", NULL_PARG);
|
||||
break;
|
||||
|
||||
case A_OSC8_JUMP:
|
||||
#if OSC8_LINK
|
||||
cmd_exec();
|
||||
osc8_jump();
|
||||
#else
|
||||
error("Command not available", NULL_PARG);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case A_FILTER:
|
||||
#if HILITE_SEARCH
|
||||
search_type = SRCH_FORW | SRCH_FILTER;
|
||||
literal_char = FALSE;
|
||||
mca_search();
|
||||
c = getcc();
|
||||
goto again;
|
||||
|
|
@ -1737,7 +1866,7 @@ public void commands(void)
|
|||
* Edit a new file. Get the filename.
|
||||
*/
|
||||
#if EXAMINE
|
||||
if (!secure)
|
||||
if (secure_allow(SF_EXAMINE))
|
||||
{
|
||||
start_mca(A_EXAMINE, "Examine: ", ml_examine, 0);
|
||||
c = getcc();
|
||||
|
|
@ -1752,7 +1881,7 @@ public void commands(void)
|
|||
* Invoke an editor on the input file.
|
||||
*/
|
||||
#if EDITOR
|
||||
if (!secure)
|
||||
if (secure_allow(SF_EDIT))
|
||||
{
|
||||
if (ch_getflags() & CH_HELPFILE)
|
||||
break;
|
||||
|
|
@ -1775,7 +1904,7 @@ public void commands(void)
|
|||
*/
|
||||
make_display();
|
||||
cmd_exec();
|
||||
lsystem(pr_expand(editproto), (char*)NULL);
|
||||
lsystem(pr_expand(editproto), NULL);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1914,10 +2043,10 @@ public void commands(void)
|
|||
optgetname = FALSE;
|
||||
mca_opt_toggle();
|
||||
c = getcc();
|
||||
cbuf = opt_toggle_disallowed(c);
|
||||
if (cbuf != NULL)
|
||||
msg = opt_toggle_disallowed(c);
|
||||
if (msg != NULL)
|
||||
{
|
||||
error(cbuf, NULL_PARG);
|
||||
error(msg, NULL_PARG);
|
||||
break;
|
||||
}
|
||||
goto again;
|
||||
|
|
@ -1936,7 +2065,7 @@ public void commands(void)
|
|||
/*
|
||||
* Set an initial command for new files.
|
||||
*/
|
||||
start_mca(A_FIRSTCMD, "+", (void*)NULL, 0);
|
||||
start_mca(A_FIRSTCMD, "+", NULL, 0);
|
||||
c = getcc();
|
||||
goto again;
|
||||
|
||||
|
|
@ -1946,7 +2075,7 @@ public void commands(void)
|
|||
* Shell escape.
|
||||
*/
|
||||
#if SHELL_ESCAPE
|
||||
if (!secure)
|
||||
if (secure_allow(SF_SHELL))
|
||||
{
|
||||
start_mca(action, (action == A_SHELL) ? "!" : "#", ml_shell, 0);
|
||||
c = getcc();
|
||||
|
|
@ -1963,7 +2092,7 @@ public void commands(void)
|
|||
*/
|
||||
if (ch_getflags() & CH_HELPFILE)
|
||||
break;
|
||||
start_mca(A_SETMARK, "set mark: ", (void*)NULL, 0);
|
||||
start_mca(A_SETMARK, "set mark: ", NULL, 0);
|
||||
c = getcc();
|
||||
if (is_erase_char(c) || is_newline_char(c))
|
||||
break;
|
||||
|
|
@ -1975,7 +2104,7 @@ public void commands(void)
|
|||
/*
|
||||
* Clear a mark.
|
||||
*/
|
||||
start_mca(A_CLRMARK, "clear mark: ", (void*)NULL, 0);
|
||||
start_mca(A_CLRMARK, "clear mark: ", NULL, 0);
|
||||
c = getcc();
|
||||
if (is_erase_char(c) || is_newline_char(c))
|
||||
break;
|
||||
|
|
@ -1987,7 +2116,7 @@ public void commands(void)
|
|||
/*
|
||||
* Jump to a marked position.
|
||||
*/
|
||||
start_mca(A_GOMARK, "goto mark: ", (void*)NULL, 0);
|
||||
start_mca(A_GOMARK, "goto mark: ", NULL, 0);
|
||||
c = getcc();
|
||||
if (is_erase_char(c) || is_newline_char(c))
|
||||
break;
|
||||
|
|
@ -2000,9 +2129,9 @@ public void commands(void)
|
|||
* Write part of the input to a pipe to a shell command.
|
||||
*/
|
||||
#if PIPEC
|
||||
if (!secure)
|
||||
if (secure_allow(SF_PIPE))
|
||||
{
|
||||
start_mca(A_PIPE, "|mark: ", (void*)NULL, 0);
|
||||
start_mca(A_PIPE, "|mark: ", NULL, 0);
|
||||
c = getcc();
|
||||
if (is_erase_char(c))
|
||||
break;
|
||||
|
|
@ -2021,7 +2150,7 @@ public void commands(void)
|
|||
|
||||
case A_B_BRACKET:
|
||||
case A_F_BRACKET:
|
||||
start_mca(action, "Brackets: ", (void*)NULL, 0);
|
||||
start_mca(action, "Brackets: ", NULL, 0);
|
||||
c = getcc();
|
||||
goto again;
|
||||
|
||||
|
|
@ -2030,14 +2159,14 @@ public void commands(void)
|
|||
* Shift view left.
|
||||
*/
|
||||
if (number > 0)
|
||||
shift_count = number;
|
||||
shift_count = (int) number;
|
||||
else
|
||||
number = (shift_count > 0) ?
|
||||
shift_count : sc_width / 2;
|
||||
number = (shift_count > 0) ? shift_count : sc_width / 2;
|
||||
if (number > hshift)
|
||||
number = hshift;
|
||||
hshift -= number;
|
||||
screen_trashed = 1;
|
||||
pos_rehead();
|
||||
hshift -= (int) number;
|
||||
screen_trashed();
|
||||
break;
|
||||
|
||||
case A_RSHIFT:
|
||||
|
|
@ -2045,28 +2174,30 @@ public void commands(void)
|
|||
* Shift view right.
|
||||
*/
|
||||
if (number > 0)
|
||||
shift_count = number;
|
||||
shift_count = (int) number;
|
||||
else
|
||||
number = (shift_count > 0) ?
|
||||
shift_count : sc_width / 2;
|
||||
hshift += number;
|
||||
screen_trashed = 1;
|
||||
number = (shift_count > 0) ? shift_count : sc_width / 2;
|
||||
pos_rehead();
|
||||
hshift += (int) number;
|
||||
screen_trashed();
|
||||
break;
|
||||
|
||||
case A_LLSHIFT:
|
||||
/*
|
||||
* Shift view left to margin.
|
||||
*/
|
||||
pos_rehead();
|
||||
hshift = 0;
|
||||
screen_trashed = 1;
|
||||
screen_trashed();
|
||||
break;
|
||||
|
||||
case A_RRSHIFT:
|
||||
/*
|
||||
* Shift view right to view rightmost char on screen.
|
||||
*/
|
||||
pos_rehead();
|
||||
hshift = rrshift();
|
||||
screen_trashed = 1;
|
||||
screen_trashed();
|
||||
break;
|
||||
|
||||
case A_PREFIX:
|
||||
|
|
@ -2078,8 +2209,7 @@ public void commands(void)
|
|||
if (mca != A_PREFIX)
|
||||
{
|
||||
cmd_reset();
|
||||
start_mca(A_PREFIX, " ", (void*)NULL,
|
||||
CF_QUIT_ON_ERASE);
|
||||
start_mca(A_PREFIX, " ", NULL, CF_QUIT_ON_ERASE);
|
||||
(void) cmd_char(c);
|
||||
}
|
||||
c = getcc();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Mon Nov 14 18:19:23 PST 2022 */
|
||||
/* Generated by "./mkutable -f2 Mn Me -- unicode/UnicodeData.txt" on Sun Sep 17 17:56:27 PDT 2023 */
|
||||
{ 0x0300, 0x036f }, /* Mn */
|
||||
{ 0x0483, 0x0487 }, /* Mn */
|
||||
{ 0x0488, 0x0489 }, /* Me */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -19,8 +19,9 @@ extern int utf_mode;
|
|||
/*
|
||||
* Get the length of a buffer needed to convert a string.
|
||||
*/
|
||||
public int cvt_length(int len, int ops)
|
||||
public size_t cvt_length(size_t len, int ops)
|
||||
{
|
||||
(void) ops;
|
||||
if (utf_mode)
|
||||
/*
|
||||
* Just copying a string in UTF-8 mode can cause it to grow
|
||||
|
|
@ -34,10 +35,10 @@ public int cvt_length(int len, int ops)
|
|||
/*
|
||||
* Allocate a chpos array for use by cvt_text.
|
||||
*/
|
||||
public int * cvt_alloc_chpos(int len)
|
||||
public int * cvt_alloc_chpos(size_t len)
|
||||
{
|
||||
int i;
|
||||
int *chpos = (int *) ecalloc(sizeof(int), len);
|
||||
size_t i;
|
||||
int *chpos = (int *) ecalloc(len, sizeof(int));
|
||||
/* Initialize all entries to an invalid position. */
|
||||
for (i = 0; i < len; i++)
|
||||
chpos[i] = -1;
|
||||
|
|
@ -49,12 +50,12 @@ public int * cvt_alloc_chpos(int len)
|
|||
* Returns converted text in odst. The original offset of each
|
||||
* odst character (when it was in osrc) is returned in the chpos array.
|
||||
*/
|
||||
public void cvt_text(char *odst, char *osrc, int *chpos, int *lenp, int ops)
|
||||
public void cvt_text(mutable char *odst, constant char *osrc, mutable int *chpos, mutable size_t *lenp, int ops)
|
||||
{
|
||||
char *dst;
|
||||
char *edst = odst;
|
||||
char *src;
|
||||
char *src_end;
|
||||
constant char *src;
|
||||
constant char *src_end;
|
||||
LWCHAR ch;
|
||||
|
||||
if (lenp != NULL)
|
||||
|
|
@ -64,10 +65,10 @@ public void cvt_text(char *odst, char *osrc, int *chpos, int *lenp, int ops)
|
|||
|
||||
for (src = osrc, dst = odst; src < src_end; )
|
||||
{
|
||||
int src_pos = (int) (src - osrc);
|
||||
int dst_pos = (int) (dst - odst);
|
||||
size_t src_pos = ptr_diff(src, osrc);
|
||||
size_t dst_pos = ptr_diff(dst, odst);
|
||||
struct ansi_state *pansi;
|
||||
ch = step_char(&src, +1, src_end);
|
||||
ch = step_charc(&src, +1, src_end);
|
||||
if ((ops & CVT_BS) && ch == '\b' && dst > odst)
|
||||
{
|
||||
/* Delete backspace and preceding char. */
|
||||
|
|
@ -82,18 +83,22 @@ public void cvt_text(char *odst, char *osrc, int *chpos, int *lenp, int ops)
|
|||
{
|
||||
if (ansi_step(pansi, ch) != ANSI_MID)
|
||||
break;
|
||||
ch = *src++;
|
||||
ch = (LWCHAR) *src++; /* {{ would step_char work? }} */
|
||||
}
|
||||
ansi_done(pansi);
|
||||
} else
|
||||
{
|
||||
/* Just copy the char to the destination buffer. */
|
||||
char *cdst = dst;
|
||||
if ((ops & CVT_TO_LC) && IS_UPPER(ch))
|
||||
ch = TO_LOWER(ch);
|
||||
put_wchar(&dst, ch);
|
||||
/* Record the original position of the char. */
|
||||
if (chpos != NULL)
|
||||
chpos[dst_pos] = src_pos;
|
||||
{
|
||||
while (cdst++ < dst)
|
||||
chpos[dst_pos++] = (int) src_pos; /*{{type-issue}}*/
|
||||
}
|
||||
}
|
||||
if (dst > edst)
|
||||
edst = dst;
|
||||
|
|
@ -102,6 +107,6 @@ public void cvt_text(char *odst, char *osrc, int *chpos, int *lenp, int ops)
|
|||
edst--;
|
||||
*edst = '\0';
|
||||
if (lenp != NULL)
|
||||
*lenp = (int) (edst - odst);
|
||||
*lenp = ptr_diff(edst, odst);
|
||||
/* FIXME: why was this here? if (chpos != NULL) chpos[dst - odst] = src - osrc; */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -34,11 +34,15 @@
|
|||
#include "lesskey.h"
|
||||
|
||||
extern int erase_char, erase2_char, kill_char;
|
||||
extern int secure;
|
||||
extern int mousecap;
|
||||
extern int screen_trashed;
|
||||
extern int sc_height;
|
||||
|
||||
#if USERFILE
|
||||
/* "content" is lesskey source, never binary. */
|
||||
static void add_content_table(int (*call_lesskey)(constant char *, lbool), constant char *envname, lbool sysvar);
|
||||
static int add_hometable(int (*call_lesskey)(constant char *, lbool), constant char *envname, constant char *def_filename, lbool sysvar);
|
||||
#endif /* USERFILE */
|
||||
|
||||
#define SK(k) \
|
||||
SK_SPECIAL_KEY, (k), 6, 1, 1, 1
|
||||
/*
|
||||
|
|
@ -96,8 +100,6 @@ static unsigned char cmdtable[] =
|
|||
ESC,'<',0, A_GOLINE,
|
||||
'p',0, A_PERCENT,
|
||||
'%',0, A_PERCENT,
|
||||
ESC,'[',0, A_LSHIFT,
|
||||
ESC,']',0, A_RSHIFT,
|
||||
ESC,'(',0, A_LSHIFT,
|
||||
ESC,')',0, A_RSHIFT,
|
||||
ESC,'{',0, A_LLSHIFT,
|
||||
|
|
@ -155,6 +157,14 @@ static unsigned char cmdtable[] =
|
|||
CONTROL('X'),CONTROL('V'),0, A_EXAMINE,
|
||||
':','n',0, A_NEXT_FILE,
|
||||
':','p',0, A_PREV_FILE,
|
||||
CONTROL('O'),CONTROL('N'),0, A_OSC8_F_SEARCH,
|
||||
CONTROL('O'),'n',0, A_OSC8_F_SEARCH,
|
||||
CONTROL('O'),CONTROL('P'),0, A_OSC8_B_SEARCH,
|
||||
CONTROL('O'),'p',0, A_OSC8_B_SEARCH,
|
||||
CONTROL('O'),CONTROL('O'),0, A_OSC8_OPEN,
|
||||
CONTROL('O'),'o',0, A_OSC8_OPEN,
|
||||
CONTROL('O'),CONTROL('L'),0, A_OSC8_JUMP,
|
||||
CONTROL('O'),'l',0, A_OSC8_JUMP,
|
||||
't',0, A_NEXT_TAG,
|
||||
'T',0, A_PREV_TAG,
|
||||
':','x',0, A_INDEX_FILE,
|
||||
|
|
@ -221,14 +231,27 @@ static unsigned char edittable[] =
|
|||
ESC,'[','<',0, EC_X116MOUSE, /* X11 1006 mouse report */
|
||||
};
|
||||
|
||||
static unsigned char dflt_vartable[] =
|
||||
{
|
||||
'L','E','S','S','_','O','S','C','8','_','m','a','n', 0, EV_OK|A_EXTRA,
|
||||
/* echo '%o' | sed -e "s,^man\:\\([^(]*\\)( *\\([^)]*\\)\.*,-man '\\2' '\\1'," -e"t X" -e"s,\.*,-echo Invalid man link," -e"\: X" */
|
||||
'e','c','h','o',' ','\'','%','o','\'',' ','|',' ','s','e','d',' ','-','e',' ','"','s',',','^','m','a','n','\\',':','\\','\\','(','[','^','(',']','*','\\','\\',')','(',' ','*','\\','\\','(','[','^',')',']','*','\\','\\',')','\\','.','*',',','-','m','a','n',' ','\'','\\','\\','2','\'',' ','\'','\\','\\','1','\'',',','"',' ','-','e','"','t',' ','X','"',' ','-','e','"','s',',','\\','.','*',',','-','e','c','h','o',' ','I','n','v','a','l','i','d',' ','m','a','n',' ','l','i','n','k',',','"',' ','-','e','"','\\',':',' ','X','"',
|
||||
0,
|
||||
|
||||
'L','E','S','S','_','O','S','C','8','_','f','i','l','e', 0, EV_OK|A_EXTRA,
|
||||
/* eval `echo '%o' | sed -e "s,^file://\\([^/]*\\)\\(.*\\),_H=\\1;_P=\\2;_E=0," -e"t X" -e"s,.*,_E=1," -e": X"`; if [ "$_E" = 1 ]; then echo -echo Invalid file link; elif [ -z "$_H" -o "$_H" = localhost -o "$_H" = $HOSTNAME ]; then echo ":e $_P"; else echo -echo Cannot open remote file on "$_H"; fi */
|
||||
'e','v','a','l',' ','`','e','c','h','o',' ','\'','%','o','\'',' ','|',' ','s','e','d',' ','-','e',' ','"','s',',','^','f','i','l','e','\\',':','/','/','\\','\\','(','[','^','/',']','*','\\','\\',')','\\','\\','(','\\','.','*','\\','\\',')',',','_','H','=','\\','\\','1',';','_','P','=','\\','\\','2',';','_','E','=','0',',','"',' ','-','e','"','t',' ','X','"',' ','-','e','"','s',',','\\','.','*',',','_','E','=','1',',','"',' ','-','e','"','\\',':',' ','X','"','`',';',' ','i','f',' ','[',' ','"','$','_','E','"',' ','=',' ','1',' ',']',';',' ','t','h','e','n',' ','e','c','h','o',' ','-','e','c','h','o',' ','I','n','v','a','l','i','d',' ','f','i','l','e',' ','l','i','n','k',';',' ','e','l','i','f',' ','[',' ','-','z',' ','"','$','_','H','"',' ','-','o',' ','"','$','_','H','"',' ','=',' ','l','o','c','a','l','h','o','s','t',' ','-','o',' ','"','$','_','H','"',' ','=',' ','$','H','O','S','T','N','A','M','E',' ',']',';',' ','t','h','e','n',' ','e','c','h','o',' ','"','\\',':','e',' ','$','_','P','"',';',' ','e','l','s','e',' ','e','c','h','o',' ','-','e','c','h','o',' ','C','a','n','n','o','t',' ','o','p','e','n',' ','r','e','m','o','t','e',' ','f','i','l','e',' ','o','n',' ','"','$','_','H','"',';',' ','f','i',
|
||||
0,
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure to support a list of command tables.
|
||||
*/
|
||||
struct tablelist
|
||||
{
|
||||
struct tablelist *t_next;
|
||||
char *t_start;
|
||||
char *t_end;
|
||||
unsigned char *t_start;
|
||||
unsigned char *t_end;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -243,13 +266,13 @@ static struct tablelist *list_sysvar_tables = NULL;
|
|||
/*
|
||||
* Expand special key abbreviations in a command table.
|
||||
*/
|
||||
static void expand_special_keys(char *table, int len)
|
||||
static void expand_special_keys(unsigned char *table, size_t len)
|
||||
{
|
||||
char *fm;
|
||||
char *to;
|
||||
unsigned char *fm;
|
||||
unsigned char *to;
|
||||
int a;
|
||||
char *repl;
|
||||
int klen;
|
||||
constant char *repl;
|
||||
size_t klen;
|
||||
|
||||
for (fm = table; fm < table + len; )
|
||||
{
|
||||
|
|
@ -276,10 +299,10 @@ static void expand_special_keys(char *table, int len)
|
|||
repl = special_key_str(fm[1]);
|
||||
klen = fm[2] & 0377;
|
||||
fm += klen;
|
||||
if (repl == NULL || (int) strlen(repl) > klen)
|
||||
if (repl == NULL || strlen(repl) > klen)
|
||||
repl = "\377";
|
||||
while (*repl != '\0')
|
||||
*to++ = *repl++;
|
||||
*to++ = (unsigned char) *repl++; /*{{type-issue}}*/
|
||||
}
|
||||
*to++ = '\0';
|
||||
/*
|
||||
|
|
@ -306,7 +329,7 @@ static void expand_cmd_table(struct tablelist *tlist)
|
|||
struct tablelist *t;
|
||||
for (t = tlist; t != NULL; t = t->t_next)
|
||||
{
|
||||
expand_special_keys(t->t_start, t->t_end - t->t_start);
|
||||
expand_special_keys(t->t_start, ptr_diff(t->t_end, t->t_start));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -321,7 +344,6 @@ public void expand_cmd_tables(void)
|
|||
expand_cmd_table(list_sysvar_tables);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the command lists.
|
||||
*/
|
||||
|
|
@ -330,12 +352,13 @@ public void init_cmds(void)
|
|||
/*
|
||||
* Add the default command tables.
|
||||
*/
|
||||
add_fcmd_table((char*)cmdtable, sizeof(cmdtable));
|
||||
add_ecmd_table((char*)edittable, sizeof(edittable));
|
||||
add_fcmd_table(cmdtable, sizeof(cmdtable));
|
||||
add_ecmd_table(edittable, sizeof(edittable));
|
||||
add_sysvar_table(dflt_vartable, sizeof(dflt_vartable));
|
||||
#if USERFILE
|
||||
#ifdef BINDIR /* For backwards compatibility */
|
||||
/* Try to add tables in the OLD system lesskey file. */
|
||||
add_hometable(lesskey, NULL, BINDIR "/.sysless", 1);
|
||||
add_hometable(lesskey, NULL, BINDIR "/.sysless", TRUE);
|
||||
#endif
|
||||
/*
|
||||
* Try to load lesskey source file or binary file.
|
||||
|
|
@ -348,33 +371,36 @@ public void init_cmds(void)
|
|||
* Try to add tables in system lesskey src file.
|
||||
*/
|
||||
#if HAVE_LESSKEYSRC
|
||||
if (add_hometable(lesskey_src, "LESSKEYIN_SYSTEM", LESSKEYINFILE_SYS, 1) != 0)
|
||||
if (add_hometable(lesskey_src, "LESSKEYIN_SYSTEM", LESSKEYINFILE_SYS, TRUE) != 0)
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* Try to add the tables in the system lesskey binary file.
|
||||
*/
|
||||
add_hometable(lesskey, "LESSKEY_SYSTEM", LESSKEYFILE_SYS, 1);
|
||||
add_hometable(lesskey, "LESSKEY_SYSTEM", LESSKEYFILE_SYS, TRUE);
|
||||
}
|
||||
/*
|
||||
* Try to add tables in the lesskey src file "$HOME/.lesskey".
|
||||
*/
|
||||
#if HAVE_LESSKEYSRC
|
||||
if (add_hometable(lesskey_src, "LESSKEYIN", DEF_LESSKEYINFILE, 0) != 0)
|
||||
if (add_hometable(lesskey_src, "LESSKEYIN", DEF_LESSKEYINFILE, FALSE) != 0)
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* Try to add the tables in the standard lesskey binary file "$HOME/.less".
|
||||
*/
|
||||
add_hometable(lesskey, "LESSKEY", LESSKEYFILE, 0);
|
||||
add_hometable(lesskey, "LESSKEY", LESSKEYFILE, FALSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
add_content_table(lesskey_content, "LESSKEY_CONTENT_SYSTEM", TRUE);
|
||||
add_content_table(lesskey_content, "LESSKEY_CONTENT", FALSE);
|
||||
#endif /* USERFILE */
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a command table.
|
||||
*/
|
||||
static int add_cmd_table(struct tablelist **tlist, char *buf, int len)
|
||||
static int add_cmd_table(struct tablelist **tlist, unsigned char *buf, size_t len)
|
||||
{
|
||||
struct tablelist *t;
|
||||
|
||||
|
|
@ -391,15 +417,46 @@ static int add_cmd_table(struct tablelist **tlist, char *buf, int len)
|
|||
}
|
||||
t->t_start = buf;
|
||||
t->t_end = buf + len;
|
||||
t->t_next = *tlist;
|
||||
*tlist = t;
|
||||
t->t_next = NULL;
|
||||
if (*tlist == NULL)
|
||||
*tlist = t;
|
||||
else
|
||||
{
|
||||
struct tablelist *e;
|
||||
for (e = *tlist; e->t_next != NULL; e = e->t_next)
|
||||
continue;
|
||||
e->t_next = t;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the last command table in a list.
|
||||
*/
|
||||
static void pop_cmd_table(struct tablelist **tlist)
|
||||
{
|
||||
struct tablelist *t;
|
||||
if (*tlist == NULL)
|
||||
return;
|
||||
if ((*tlist)->t_next == NULL)
|
||||
{
|
||||
t = *tlist;
|
||||
*tlist = NULL;
|
||||
} else
|
||||
{
|
||||
struct tablelist *e;
|
||||
for (e = *tlist; e->t_next->t_next != NULL; e = e->t_next)
|
||||
continue;
|
||||
t = e->t_next;
|
||||
e->t_next = NULL;
|
||||
}
|
||||
free(t);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a command table.
|
||||
*/
|
||||
public void add_fcmd_table(char *buf, int len)
|
||||
public void add_fcmd_table(unsigned char *buf, size_t len)
|
||||
{
|
||||
if (add_cmd_table(&list_fcmd_tables, buf, len) < 0)
|
||||
error("Warning: some commands disabled", NULL_PARG);
|
||||
|
|
@ -408,7 +465,7 @@ public void add_fcmd_table(char *buf, int len)
|
|||
/*
|
||||
* Add an editing command table.
|
||||
*/
|
||||
public void add_ecmd_table(char *buf, int len)
|
||||
public void add_ecmd_table(unsigned char *buf, size_t len)
|
||||
{
|
||||
if (add_cmd_table(&list_ecmd_tables, buf, len) < 0)
|
||||
error("Warning: some edit commands disabled", NULL_PARG);
|
||||
|
|
@ -417,12 +474,27 @@ public void add_ecmd_table(char *buf, int len)
|
|||
/*
|
||||
* Add an environment variable table.
|
||||
*/
|
||||
static void add_var_table(struct tablelist **tlist, char *buf, int len)
|
||||
static void add_var_table(struct tablelist **tlist, unsigned char *buf, size_t len)
|
||||
{
|
||||
if (add_cmd_table(tlist, buf, len) < 0)
|
||||
struct xbuffer xbuf;
|
||||
|
||||
xbuf_init(&xbuf);
|
||||
expand_evars((char*)buf, len, &xbuf); /*{{unsigned-issue}}*/
|
||||
/* {{ We leak the table in buf. expand_evars scribbled in it so it's useless anyway. }} */
|
||||
if (add_cmd_table(tlist, xbuf.data, xbuf.end) < 0)
|
||||
error("Warning: environment variables from lesskey file unavailable", NULL_PARG);
|
||||
}
|
||||
|
||||
public void add_uvar_table(unsigned char *buf, size_t len)
|
||||
{
|
||||
add_var_table(&list_var_tables, buf, len);
|
||||
}
|
||||
|
||||
public void add_sysvar_table(unsigned char *buf, size_t len)
|
||||
{
|
||||
add_var_table(&list_sysvar_tables, buf, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return action for a mouse wheel down event.
|
||||
*/
|
||||
|
|
@ -440,18 +512,42 @@ static int mouse_wheel_up(void)
|
|||
}
|
||||
|
||||
/*
|
||||
* Return action for a mouse button release event.
|
||||
* Return action for the left mouse button trigger.
|
||||
*/
|
||||
static int mouse_button_rel(int x, int y)
|
||||
static int mouse_button_left(int x, int y)
|
||||
{
|
||||
/*
|
||||
* {{ It would be better to return an action and then do this
|
||||
* in commands() but it's nontrivial to pass y to it. }}
|
||||
*/
|
||||
#if OSC8_LINK
|
||||
if (osc8_click(y, x))
|
||||
return (A_NOACTION);
|
||||
#else
|
||||
(void) x;
|
||||
#endif /* OSC8_LINK */
|
||||
if (y < sc_height-1)
|
||||
{
|
||||
setmark('#', y);
|
||||
screen_trashed = 1;
|
||||
screen_trashed();
|
||||
}
|
||||
return (A_NOACTION);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return action for the right mouse button trigger.
|
||||
*/
|
||||
static int mouse_button_right(int x, int y)
|
||||
{
|
||||
(void) x;
|
||||
/*
|
||||
* {{ unlike mouse_button_left, we could return an action,
|
||||
* but keep it near mouse_button_left for readability. }}
|
||||
*/
|
||||
if (y < sc_height-1)
|
||||
{
|
||||
gomark('#');
|
||||
screen_trashed();
|
||||
}
|
||||
return (A_NOACTION);
|
||||
}
|
||||
|
|
@ -485,6 +581,7 @@ static int getcc_int(char *pterm)
|
|||
*/
|
||||
static int x11mouse_action(int skip)
|
||||
{
|
||||
static int prev_b = X11MOUSE_BUTTON_REL;
|
||||
int b = getcc() - X11MOUSE_OFFSET;
|
||||
int x = getcc() - X11MOUSE_OFFSET-1;
|
||||
int y = getcc() - X11MOUSE_OFFSET-1;
|
||||
|
|
@ -492,13 +589,23 @@ static int x11mouse_action(int skip)
|
|||
return (A_NOACTION);
|
||||
switch (b) {
|
||||
default:
|
||||
prev_b = b;
|
||||
return (A_NOACTION);
|
||||
case X11MOUSE_WHEEL_DOWN:
|
||||
return mouse_wheel_down();
|
||||
case X11MOUSE_WHEEL_UP:
|
||||
return mouse_wheel_up();
|
||||
case X11MOUSE_BUTTON_REL:
|
||||
return mouse_button_rel(x, y);
|
||||
/* to trigger on button-up, we check the last button-down */
|
||||
switch (prev_b) {
|
||||
case X11MOUSE_BUTTON1:
|
||||
return mouse_button_left(x, y);
|
||||
/* is BUTTON2 the rightmost with 2-buttons mouse? */
|
||||
case X11MOUSE_BUTTON2:
|
||||
case X11MOUSE_BUTTON3:
|
||||
return mouse_button_right(x, y);
|
||||
}
|
||||
return (A_NOACTION);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -523,20 +630,24 @@ static int x116mouse_action(int skip)
|
|||
return mouse_wheel_down();
|
||||
case X11MOUSE_WHEEL_UP:
|
||||
return mouse_wheel_up();
|
||||
case X11MOUSE_BUTTON1:
|
||||
if (ch != 'm') return (A_NOACTION);
|
||||
return mouse_button_left(x, y);
|
||||
default:
|
||||
if (ch != 'm') return (A_NOACTION);
|
||||
return mouse_button_rel(x, y);
|
||||
/* any other button release */
|
||||
return mouse_button_right(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Search a single command table for the command string in cmd.
|
||||
*/
|
||||
static int cmd_search(char *cmd, char *table, char *endtable, char **sp)
|
||||
static int cmd_search(constant char *cmd, constant char *table, constant char *endtable, constant char **sp)
|
||||
{
|
||||
char *p;
|
||||
char *q;
|
||||
int a;
|
||||
constant char *p;
|
||||
constant char *q;
|
||||
int a = A_INVALID;
|
||||
|
||||
*sp = NULL;
|
||||
for (p = table, q = cmd; p < endtable; p++, q++)
|
||||
|
|
@ -571,13 +682,15 @@ static int cmd_search(char *cmd, char *table, char *endtable, char **sp)
|
|||
if (a & A_EXTRA)
|
||||
{
|
||||
*sp = ++p;
|
||||
while (*p != '\0')
|
||||
++p;
|
||||
a &= ~A_EXTRA;
|
||||
}
|
||||
if (a == A_X11MOUSE_IN)
|
||||
a = x11mouse_action(0);
|
||||
else if (a == A_X116MOUSE_IN)
|
||||
a = x116mouse_action(0);
|
||||
return (a);
|
||||
q = cmd-1;
|
||||
}
|
||||
} else if (*q == '\0')
|
||||
{
|
||||
|
|
@ -586,7 +699,9 @@ static int cmd_search(char *cmd, char *table, char *endtable, char **sp)
|
|||
* but not the end of the string in the command table.
|
||||
* The user's command is incomplete.
|
||||
*/
|
||||
return (A_PREFIX);
|
||||
if (a == A_INVALID)
|
||||
a = A_PREFIX;
|
||||
q = cmd-1;
|
||||
} else
|
||||
{
|
||||
/*
|
||||
|
|
@ -600,8 +715,10 @@ static int cmd_search(char *cmd, char *table, char *endtable, char **sp)
|
|||
/*
|
||||
* A_END_LIST is a special marker that tells
|
||||
* us to abort the cmd search.
|
||||
* Negative action means accept this action
|
||||
* without searching any more cmd tables.
|
||||
*/
|
||||
return (A_UINVALID);
|
||||
return -a;
|
||||
}
|
||||
while (*p++ != '\0')
|
||||
continue;
|
||||
|
|
@ -613,40 +730,44 @@ static int cmd_search(char *cmd, char *table, char *endtable, char **sp)
|
|||
q = cmd-1;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* No match found in the entire command table.
|
||||
*/
|
||||
return (A_INVALID);
|
||||
return (a);
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a command character and return the associated action.
|
||||
* The "extra" string, if any, is returned in sp.
|
||||
*/
|
||||
static int cmd_decode(struct tablelist *tlist, char *cmd, char **sp)
|
||||
static int cmd_decode(struct tablelist *tlist, constant char *cmd, constant char **sp)
|
||||
{
|
||||
struct tablelist *t;
|
||||
int action = A_INVALID;
|
||||
|
||||
/*
|
||||
* Search thru all the command tables.
|
||||
* Stop when we find an action which is not A_INVALID.
|
||||
* Search for the cmd thru all the command tables.
|
||||
* If we find it more than once, take the last one.
|
||||
*/
|
||||
*sp = NULL;
|
||||
for (t = tlist; t != NULL; t = t->t_next)
|
||||
{
|
||||
action = cmd_search(cmd, t->t_start, t->t_end, sp);
|
||||
if (action != A_INVALID)
|
||||
break;
|
||||
constant char *tsp;
|
||||
int taction = cmd_search(cmd, (char *) t->t_start, (char *) t->t_end, &tsp);
|
||||
if (taction == A_UINVALID)
|
||||
taction = A_INVALID;
|
||||
if (taction != A_INVALID)
|
||||
{
|
||||
*sp = tsp;
|
||||
if (taction < 0)
|
||||
return (-taction);
|
||||
action = taction;
|
||||
}
|
||||
}
|
||||
if (action == A_UINVALID)
|
||||
action = A_INVALID;
|
||||
return (action);
|
||||
}
|
||||
|
||||
/*
|
||||
* Decode a command from the cmdtables list.
|
||||
*/
|
||||
public int fcmd_decode(char *cmd, char **sp)
|
||||
public int fcmd_decode(constant char *cmd, constant char **sp)
|
||||
{
|
||||
return (cmd_decode(list_fcmd_tables, cmd, sp));
|
||||
}
|
||||
|
|
@ -654,7 +775,7 @@ public int fcmd_decode(char *cmd, char **sp)
|
|||
/*
|
||||
* Decode a command from the edittables list.
|
||||
*/
|
||||
public int ecmd_decode(char *cmd, char **sp)
|
||||
public int ecmd_decode(constant char *cmd, constant char **sp)
|
||||
{
|
||||
return (cmd_decode(list_ecmd_tables, cmd, sp));
|
||||
}
|
||||
|
|
@ -663,10 +784,10 @@ public int ecmd_decode(char *cmd, char **sp)
|
|||
* Get the value of an environment variable.
|
||||
* Looks first in the lesskey file, then in the real environment.
|
||||
*/
|
||||
public char * lgetenv(char *var)
|
||||
public constant char * lgetenv(constant char *var)
|
||||
{
|
||||
int a;
|
||||
char *s;
|
||||
constant char *s;
|
||||
|
||||
a = cmd_decode(list_var_tables, var, &s);
|
||||
if (a == EV_OK)
|
||||
|
|
@ -680,10 +801,42 @@ public char * lgetenv(char *var)
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Like lgetenv, but also uses a buffer partially filled with an env table.
|
||||
*/
|
||||
public constant char * lgetenv_ext(constant char *var, unsigned char *env_buf, size_t env_buf_len)
|
||||
{
|
||||
constant char *r;
|
||||
size_t e;
|
||||
size_t env_end = 0;
|
||||
|
||||
for (e = 0;;)
|
||||
{
|
||||
for (; e < env_buf_len; e++)
|
||||
if (env_buf[e] == '\0')
|
||||
break;
|
||||
if (e >= env_buf_len) break;
|
||||
if (env_buf[++e] & A_EXTRA)
|
||||
{
|
||||
for (e = e+1; e < env_buf_len; e++)
|
||||
if (env_buf[e] == '\0')
|
||||
break;
|
||||
}
|
||||
e++;
|
||||
if (e >= env_buf_len) break;
|
||||
env_end = e;
|
||||
}
|
||||
/* Temporarily add env_buf to var_tables, do the lookup, then remove it. */
|
||||
add_uvar_table(env_buf, env_end);
|
||||
r = lgetenv(var);
|
||||
pop_cmd_table(&list_var_tables);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Is a string null or empty?
|
||||
*/
|
||||
public int isnullenv(char *s)
|
||||
public lbool isnullenv(constant char *s)
|
||||
{
|
||||
return (s == NULL || *s == '\0');
|
||||
}
|
||||
|
|
@ -694,9 +847,9 @@ public int isnullenv(char *s)
|
|||
* Integers are stored in a funny format:
|
||||
* two bytes, low order first, in radix KRADIX.
|
||||
*/
|
||||
static int gint(char **sp)
|
||||
static size_t gint(unsigned char **sp)
|
||||
{
|
||||
int n;
|
||||
size_t n;
|
||||
|
||||
n = *(*sp)++;
|
||||
n += *(*sp)++ * KRADIX;
|
||||
|
|
@ -706,7 +859,7 @@ static int gint(char **sp)
|
|||
/*
|
||||
* Process an old (pre-v241) lesskey file.
|
||||
*/
|
||||
static int old_lesskey(char *buf, int len)
|
||||
static int old_lesskey(unsigned char *buf, size_t len)
|
||||
{
|
||||
/*
|
||||
* Old-style lesskey file.
|
||||
|
|
@ -724,12 +877,12 @@ static int old_lesskey(char *buf, int len)
|
|||
/*
|
||||
* Process a new (post-v241) lesskey file.
|
||||
*/
|
||||
static int new_lesskey(char *buf, int len, int sysvar)
|
||||
static int new_lesskey(unsigned char *buf, size_t len, lbool sysvar)
|
||||
{
|
||||
char *p;
|
||||
char *end;
|
||||
unsigned char *p;
|
||||
unsigned char *end;
|
||||
int c;
|
||||
int n;
|
||||
size_t n;
|
||||
|
||||
/*
|
||||
* New-style lesskey file.
|
||||
|
|
@ -748,24 +901,26 @@ static int new_lesskey(char *buf, int len, int sysvar)
|
|||
{
|
||||
case CMD_SECTION:
|
||||
n = gint(&p);
|
||||
if (n < 0 || p+n >= end)
|
||||
if (p+n >= end)
|
||||
return (-1);
|
||||
add_fcmd_table(p, n);
|
||||
p += n;
|
||||
break;
|
||||
case EDIT_SECTION:
|
||||
n = gint(&p);
|
||||
if (n < 0 || p+n >= end)
|
||||
if (p+n >= end)
|
||||
return (-1);
|
||||
add_ecmd_table(p, n);
|
||||
p += n;
|
||||
break;
|
||||
case VAR_SECTION:
|
||||
n = gint(&p);
|
||||
if (n < 0 || p+n >= end)
|
||||
if (p+n >= end)
|
||||
return (-1);
|
||||
add_var_table((sysvar) ?
|
||||
&list_sysvar_tables : &list_var_tables, p, n);
|
||||
if (sysvar)
|
||||
add_sysvar_table(p, n);
|
||||
else
|
||||
add_uvar_table(p, n);
|
||||
p += n;
|
||||
break;
|
||||
case END_SECTION:
|
||||
|
|
@ -782,14 +937,14 @@ static int new_lesskey(char *buf, int len, int sysvar)
|
|||
/*
|
||||
* Set up a user command table, based on a "lesskey" file.
|
||||
*/
|
||||
public int lesskey(char *filename, int sysvar)
|
||||
public int lesskey(constant char *filename, lbool sysvar)
|
||||
{
|
||||
char *buf;
|
||||
unsigned char *buf;
|
||||
POSITION len;
|
||||
long n;
|
||||
ssize_t n;
|
||||
int f;
|
||||
|
||||
if (secure)
|
||||
if (!secure_allow(SF_LESSKEY))
|
||||
return (1);
|
||||
/*
|
||||
* Try to open the lesskey file.
|
||||
|
|
@ -815,18 +970,18 @@ public int lesskey(char *filename, int sysvar)
|
|||
close(f);
|
||||
return (-1);
|
||||
}
|
||||
if ((buf = (char *) calloc((int)len, sizeof(char))) == NULL)
|
||||
if ((buf = (unsigned char *) calloc((size_t)len, sizeof(char))) == NULL)
|
||||
{
|
||||
close(f);
|
||||
return (-1);
|
||||
}
|
||||
if (lseek(f, (off_t)0, SEEK_SET) == BAD_LSEEK)
|
||||
if (less_lseek(f, (less_off_t)0, SEEK_SET) == BAD_LSEEK)
|
||||
{
|
||||
free(buf);
|
||||
close(f);
|
||||
return (-1);
|
||||
}
|
||||
n = read(f, buf, (unsigned int) len);
|
||||
n = read(f, buf, (size_t) len);
|
||||
close(f);
|
||||
if (n != len)
|
||||
{
|
||||
|
|
@ -841,24 +996,38 @@ public int lesskey(char *filename, int sysvar)
|
|||
if (len < 4 ||
|
||||
buf[0] != C0_LESSKEY_MAGIC || buf[1] != C1_LESSKEY_MAGIC ||
|
||||
buf[2] != C2_LESSKEY_MAGIC || buf[3] != C3_LESSKEY_MAGIC)
|
||||
return (old_lesskey(buf, (int)len));
|
||||
return (new_lesskey(buf, (int)len, sysvar));
|
||||
return (old_lesskey(buf, (size_t) len));
|
||||
return (new_lesskey(buf, (size_t) len, sysvar));
|
||||
}
|
||||
|
||||
#if HAVE_LESSKEYSRC
|
||||
public int lesskey_src(char *filename, int sysvar)
|
||||
static int lesskey_text(constant char *filename, lbool sysvar, lbool content)
|
||||
{
|
||||
static struct lesskey_tables tables;
|
||||
int r = parse_lesskey(filename, &tables);
|
||||
if (!secure_allow(SF_LESSKEY))
|
||||
return (1);
|
||||
int r = content ? parse_lesskey_content(filename, &tables) : parse_lesskey(filename, &tables);
|
||||
if (r != 0)
|
||||
return (r);
|
||||
add_fcmd_table(xbuf_char_data(&tables.cmdtable.buf), tables.cmdtable.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,
|
||||
xbuf_char_data(&tables.vartable.buf), tables.vartable.buf.end);
|
||||
add_fcmd_table(tables.cmdtable.buf.data, tables.cmdtable.buf.end);
|
||||
add_ecmd_table(tables.edittable.buf.data, tables.edittable.buf.end);
|
||||
if (sysvar)
|
||||
add_sysvar_table(tables.vartable.buf.data, tables.vartable.buf.end);
|
||||
else
|
||||
add_uvar_table(tables.vartable.buf.data, tables.vartable.buf.end);
|
||||
return (0);
|
||||
}
|
||||
|
||||
public int lesskey_src(constant char *filename, lbool sysvar)
|
||||
{
|
||||
return lesskey_text(filename, sysvar, FALSE);
|
||||
}
|
||||
|
||||
public int lesskey_content(constant char *content, lbool sysvar)
|
||||
{
|
||||
return lesskey_text(content, sysvar, TRUE);
|
||||
}
|
||||
|
||||
void lesskey_parse_error(char *s)
|
||||
{
|
||||
PARG parg;
|
||||
|
|
@ -870,24 +1039,25 @@ void lesskey_parse_error(char *s)
|
|||
/*
|
||||
* Add a lesskey file.
|
||||
*/
|
||||
public int add_hometable(int (*call_lesskey)(char *, int), char *envname, char *def_filename, int sysvar)
|
||||
static int add_hometable(int (*call_lesskey)(constant char *, lbool), constant char *envname, constant char *def_filename, lbool sysvar)
|
||||
{
|
||||
char *filename;
|
||||
char *filename = NULL;
|
||||
constant char *efilename;
|
||||
int r;
|
||||
|
||||
if (envname != NULL && (filename = lgetenv(envname)) != NULL)
|
||||
filename = save(filename);
|
||||
if (envname != NULL && (efilename = lgetenv(envname)) != NULL)
|
||||
filename = save(efilename);
|
||||
else if (sysvar) /* def_filename is full path */
|
||||
filename = save(def_filename);
|
||||
else /* def_filename is just basename */
|
||||
{
|
||||
/* Remove first char (normally a dot) unless stored in $HOME. */
|
||||
char *xdg = lgetenv("XDG_CONFIG_HOME");
|
||||
constant char *xdg = lgetenv("XDG_CONFIG_HOME");
|
||||
if (!isnullenv(xdg))
|
||||
filename = dirfile(xdg, &def_filename[1], 1);
|
||||
if (filename == NULL)
|
||||
{
|
||||
char *home = lgetenv("HOME");
|
||||
constant char *home = lgetenv("HOME");
|
||||
if (!isnullenv(home))
|
||||
{
|
||||
char *cfg_dir = dirfile(home, ".config", 0);
|
||||
|
|
@ -904,16 +1074,28 @@ public int add_hometable(int (*call_lesskey)(char *, int), char *envname, char *
|
|||
free(filename);
|
||||
return (r);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Add the content of a lesskey source file.
|
||||
*/
|
||||
static void add_content_table(int (*call_lesskey)(constant char *, lbool), constant char *envname, lbool sysvar)
|
||||
{
|
||||
(void) call_lesskey; /* not used */
|
||||
constant char *content = lgetenv(envname);
|
||||
if (isnullenv(content))
|
||||
return;
|
||||
lesskey_content(content, sysvar);
|
||||
}
|
||||
#endif /* USERFILE */
|
||||
|
||||
/*
|
||||
* See if a char is a special line-editing command.
|
||||
*/
|
||||
public int editchar(int c, int flags)
|
||||
public int editchar(char c, int flags)
|
||||
{
|
||||
int action;
|
||||
int nch;
|
||||
char *s;
|
||||
constant char *s;
|
||||
char usercmd[MAX_CMDLEN+1];
|
||||
|
||||
/*
|
||||
|
|
@ -939,7 +1121,7 @@ public int editchar(int c, int flags)
|
|||
*/
|
||||
nch = 0;
|
||||
do {
|
||||
if (nch > 0)
|
||||
if (nch > 0)
|
||||
c = getcc();
|
||||
usercmd[nch] = c;
|
||||
usercmd[nch+1] = '\0';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -16,12 +16,13 @@
|
|||
#if HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#if OS2 || __MVS__ || (defined WIFSIGNALED && defined WTERMSIG)
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
public int fd0 = 0;
|
||||
|
||||
extern int new_file;
|
||||
extern int cbufs;
|
||||
extern lbool new_file;
|
||||
extern char *every_first_cmd;
|
||||
extern int force_open;
|
||||
extern int is_tty;
|
||||
|
|
@ -58,14 +59,14 @@ public ino_t curr_ino;
|
|||
* words, returning each one as a standard null-terminated string.
|
||||
* back_textlist does the same, but runs thru the list backwards.
|
||||
*/
|
||||
public void init_textlist(struct textlist *tlist, char *str)
|
||||
public void init_textlist(struct textlist *tlist, mutable char *str)
|
||||
{
|
||||
char *s;
|
||||
#if SPACES_IN_FILENAMES
|
||||
int meta_quoted = 0;
|
||||
int delim_quoted = 0;
|
||||
char *esc = get_meta_escape();
|
||||
int esclen = (int) strlen(esc);
|
||||
lbool meta_quoted = FALSE;
|
||||
lbool delim_quoted = FALSE;
|
||||
constant char *esc = get_meta_escape();
|
||||
size_t esclen = strlen(esc);
|
||||
#endif
|
||||
|
||||
tlist->string = skipsp(str);
|
||||
|
|
@ -99,9 +100,9 @@ public void init_textlist(struct textlist *tlist, char *str)
|
|||
}
|
||||
}
|
||||
|
||||
public char * forw_textlist(struct textlist *tlist, char *prev)
|
||||
public constant char * forw_textlist(struct textlist *tlist, constant char *prev)
|
||||
{
|
||||
char *s;
|
||||
constant char *s;
|
||||
|
||||
/*
|
||||
* prev == NULL means return the first word in the list.
|
||||
|
|
@ -120,9 +121,9 @@ public char * forw_textlist(struct textlist *tlist, char *prev)
|
|||
return (s);
|
||||
}
|
||||
|
||||
public char * back_textlist(struct textlist *tlist, char *prev)
|
||||
public constant char * back_textlist(struct textlist *tlist, constant char *prev)
|
||||
{
|
||||
char *s;
|
||||
constant char *s;
|
||||
|
||||
/*
|
||||
* prev == NULL means return the last word in the list.
|
||||
|
|
@ -146,9 +147,9 @@ public char * back_textlist(struct textlist *tlist, char *prev)
|
|||
/*
|
||||
* Parse a single option setting in a modeline.
|
||||
*/
|
||||
static void modeline_option(char *str, int opt_len)
|
||||
static void modeline_option(constant char *str, size_t opt_len)
|
||||
{
|
||||
struct mloption { char *opt_name; void (*opt_func)(char*,int); };
|
||||
struct mloption { constant char *opt_name; void (*opt_func)(constant char*,size_t); };
|
||||
struct mloption options[] = {
|
||||
{ "ts=", set_tabs },
|
||||
{ "tabstop=", set_tabs },
|
||||
|
|
@ -157,7 +158,7 @@ static void modeline_option(char *str, int opt_len)
|
|||
struct mloption *opt;
|
||||
for (opt = options; opt->opt_name != NULL; opt++)
|
||||
{
|
||||
int name_len = strlen(opt->opt_name);
|
||||
size_t 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);
|
||||
|
|
@ -170,10 +171,10 @@ static void modeline_option(char *str, int opt_len)
|
|||
* String length, terminated by option separator (space or colon).
|
||||
* Space/colon can be escaped with backspace.
|
||||
*/
|
||||
static int modeline_option_len(char *str)
|
||||
static size_t modeline_option_len(constant char *str)
|
||||
{
|
||||
int esc = FALSE;
|
||||
char *s;
|
||||
lbool esc = FALSE;
|
||||
constant char *s;
|
||||
for (s = str; *s != '\0'; s++)
|
||||
{
|
||||
if (esc)
|
||||
|
|
@ -183,18 +184,18 @@ static int modeline_option_len(char *str)
|
|||
else if (*s == ' ' || *s == ':') /* separator */
|
||||
break;
|
||||
}
|
||||
return (s - str);
|
||||
return ptr_diff(s, str);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse colon- or space-separated option settings in a modeline.
|
||||
*/
|
||||
static void modeline_options(char *str, char end_char)
|
||||
static void modeline_options(constant char *str, char end_char)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
int opt_len;
|
||||
str = skipsp(str);
|
||||
size_t opt_len;
|
||||
str = skipspc(str);
|
||||
if (*str == '\0' || *str == end_char)
|
||||
break;
|
||||
opt_len = modeline_option_len(str);
|
||||
|
|
@ -208,21 +209,21 @@ static void modeline_options(char *str, char end_char)
|
|||
/*
|
||||
* See if there is a modeline string in a line.
|
||||
*/
|
||||
static void check_modeline(char *line)
|
||||
static void check_modeline(constant char *line)
|
||||
{
|
||||
#if HAVE_STRSTR
|
||||
static char *pgms[] = { "less:", "vim:", "vi:", "ex:", NULL };
|
||||
char **pgm;
|
||||
static constant char *pgms[] = { "less:", "vim:", "vi:", "ex:", NULL };
|
||||
constant char **pgm;
|
||||
for (pgm = pgms; *pgm != NULL; ++pgm)
|
||||
{
|
||||
char *pline = line;
|
||||
constant char *pline = line;
|
||||
for (;;)
|
||||
{
|
||||
char *str;
|
||||
constant char *str;
|
||||
pline = strstr(pline, *pgm);
|
||||
if (pline == NULL) /* pgm is not in this line */
|
||||
break;
|
||||
str = skipsp(pline + strlen(*pgm));
|
||||
str = skipspc(pline + strlen(*pgm));
|
||||
if (pline == line || pline[-1] == ' ')
|
||||
{
|
||||
if (strncmp(str, "set ", 4) == 0)
|
||||
|
|
@ -247,8 +248,8 @@ static void check_modelines(void)
|
|||
int i;
|
||||
for (i = 0; i < modelines; i++)
|
||||
{
|
||||
char *line;
|
||||
int line_len;
|
||||
constant char *line;
|
||||
size_t line_len;
|
||||
if (ABORT_SIGS())
|
||||
return;
|
||||
pos = forw_raw_line(pos, &line, &line_len);
|
||||
|
|
@ -264,6 +265,7 @@ static void check_modelines(void)
|
|||
static void close_pipe(FILE *pipefd)
|
||||
{
|
||||
int status;
|
||||
char *p;
|
||||
PARG parg;
|
||||
|
||||
if (pipefd == NULL)
|
||||
|
|
@ -279,9 +281,10 @@ static void close_pipe(FILE *pipefd)
|
|||
if (status == -1)
|
||||
{
|
||||
/* An internal error in 'less', not a preprocessor error. */
|
||||
parg.p_string = errno_message("pclose");
|
||||
p = errno_message("pclose");
|
||||
parg.p_string = p;
|
||||
error("%s", &parg);
|
||||
free(parg.p_string);
|
||||
free(p);
|
||||
return;
|
||||
}
|
||||
if (!show_preproc_error)
|
||||
|
|
@ -298,7 +301,7 @@ static void close_pipe(FILE *pipefd)
|
|||
return;
|
||||
}
|
||||
#endif
|
||||
#if defined WIFSIGNALED && defined WTERMSIG && HAVE_STRSIGNAL
|
||||
#if defined WIFSIGNALED && defined WTERMSIG
|
||||
if (WIFSIGNALED(status))
|
||||
{
|
||||
int sig = WTERMSIG(status);
|
||||
|
|
@ -348,7 +351,7 @@ public void check_altpipe_error(void)
|
|||
static void close_file(void)
|
||||
{
|
||||
struct scrpos scrpos;
|
||||
char *altfilename;
|
||||
constant char *altfilename;
|
||||
|
||||
if (curr_ifile == NULL_IFILE)
|
||||
return;
|
||||
|
|
@ -389,7 +392,7 @@ static void close_file(void)
|
|||
* Filename == "-" means standard input.
|
||||
* Filename == NULL means just close the current file.
|
||||
*/
|
||||
public int edit(char *filename)
|
||||
public int edit(constant char *filename)
|
||||
{
|
||||
if (filename == NULL)
|
||||
return (edit_ifile(NULL_IFILE));
|
||||
|
|
@ -399,20 +402,19 @@ public int edit(char *filename)
|
|||
/*
|
||||
* 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)
|
||||
static int edit_error(constant char *filename, constant char *alt_filename, void *altpipe, IFILE ifile)
|
||||
{
|
||||
if (alt_filename != NULL)
|
||||
{
|
||||
close_pipe(altpipe);
|
||||
close_altfile(alt_filename, filename);
|
||||
free(alt_filename);
|
||||
free((char*)alt_filename); /* FIXME: WTF? */
|
||||
}
|
||||
del_ifile(ifile);
|
||||
free(filename);
|
||||
/*
|
||||
* Re-open the current file.
|
||||
*/
|
||||
if (was_curr_ifile == ifile)
|
||||
if (curr_ifile == ifile)
|
||||
{
|
||||
/*
|
||||
* Whoops. The "current" ifile is the one we just deleted.
|
||||
|
|
@ -420,7 +422,6 @@ static int edit_error(char *filename, char *alt_filename, void *altpipe, IFILE i
|
|||
*/
|
||||
quit(QUIT_ERROR);
|
||||
}
|
||||
reedit_ifile(was_curr_ifile);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
|
@ -433,13 +434,15 @@ public int edit_ifile(IFILE ifile)
|
|||
int f;
|
||||
int answer;
|
||||
int chflags;
|
||||
char *filename;
|
||||
char *open_filename;
|
||||
constant char *filename;
|
||||
constant char *open_filename;
|
||||
char *alt_filename;
|
||||
void *altpipe;
|
||||
IFILE was_curr_ifile;
|
||||
char *p;
|
||||
PARG parg;
|
||||
|
||||
ssize_t nread = 0;
|
||||
|
||||
if (ifile == curr_ifile)
|
||||
{
|
||||
/*
|
||||
|
|
@ -447,31 +450,143 @@ public int edit_ifile(IFILE ifile)
|
|||
*/
|
||||
return (0);
|
||||
}
|
||||
new_file = TRUE;
|
||||
|
||||
if (ifile != NULL_IFILE)
|
||||
{
|
||||
/*
|
||||
* See if LESSOPEN specifies an "alternate" file to open.
|
||||
*/
|
||||
filename = get_filename(ifile);
|
||||
altpipe = get_altpipe(ifile);
|
||||
if (altpipe != NULL)
|
||||
{
|
||||
/*
|
||||
* File is already open.
|
||||
* chflags and f are not used by ch_init if ifile has
|
||||
* filestate which should be the case if we're here.
|
||||
* Set them here to avoid uninitialized variable warnings.
|
||||
*/
|
||||
chflags = 0;
|
||||
f = -1;
|
||||
alt_filename = get_altfilename(ifile);
|
||||
open_filename = (alt_filename != NULL) ? alt_filename : filename;
|
||||
} else
|
||||
{
|
||||
if (strcmp(filename, FAKE_HELPFILE) == 0 ||
|
||||
strcmp(filename, FAKE_EMPTYFILE) == 0)
|
||||
alt_filename = NULL;
|
||||
else
|
||||
alt_filename = open_altfile(filename, &f, &altpipe);
|
||||
|
||||
open_filename = (alt_filename != NULL) ? alt_filename : filename;
|
||||
|
||||
chflags = 0;
|
||||
if (altpipe != NULL)
|
||||
{
|
||||
/*
|
||||
* The alternate "file" is actually a pipe.
|
||||
* f has already been set to the file descriptor of the pipe
|
||||
* in the call to open_altfile above.
|
||||
* Keep the file descriptor open because it was opened
|
||||
* via popen(), and pclose() wants to close it.
|
||||
*/
|
||||
chflags |= CH_POPENED;
|
||||
if (strcmp(filename, "-") == 0)
|
||||
chflags |= CH_KEEPOPEN;
|
||||
} else if (strcmp(filename, "-") == 0)
|
||||
{
|
||||
/*
|
||||
* Use standard input.
|
||||
* Keep the file descriptor open because we can't reopen it.
|
||||
*/
|
||||
f = fd0;
|
||||
chflags |= CH_KEEPOPEN;
|
||||
/*
|
||||
* Must switch stdin to BINARY mode.
|
||||
*/
|
||||
SET_BINARY(f);
|
||||
#if MSDOS_COMPILER==DJGPPC
|
||||
/*
|
||||
* Setting stdin to binary by default causes
|
||||
* Ctrl-C to not raise SIGINT. We must undo
|
||||
* that side-effect.
|
||||
*/
|
||||
__djgpp_set_ctrl_c(1);
|
||||
#endif
|
||||
} else if (strcmp(open_filename, FAKE_EMPTYFILE) == 0)
|
||||
{
|
||||
f = -1;
|
||||
chflags |= CH_NODATA;
|
||||
} else if (strcmp(open_filename, FAKE_HELPFILE) == 0)
|
||||
{
|
||||
f = -1;
|
||||
chflags |= CH_HELPFILE;
|
||||
} else if ((p = bad_file(open_filename)) != NULL)
|
||||
{
|
||||
/*
|
||||
* It looks like a bad file. Don't try to open it.
|
||||
*/
|
||||
parg.p_string = p;
|
||||
error("%s", &parg);
|
||||
free(p);
|
||||
return edit_error(filename, alt_filename, altpipe, ifile);
|
||||
} else if ((f = open(open_filename, OPEN_READ)) < 0)
|
||||
{
|
||||
/*
|
||||
* Got an error trying to open it.
|
||||
*/
|
||||
char *p = errno_message(filename);
|
||||
parg.p_string = p;
|
||||
error("%s", &parg);
|
||||
free(p);
|
||||
return edit_error(filename, alt_filename, altpipe, ifile);
|
||||
} else
|
||||
{
|
||||
chflags |= CH_CANSEEK;
|
||||
if (bin_file(f, &nread) && !force_open && !opened(ifile))
|
||||
{
|
||||
/*
|
||||
* Looks like a binary file.
|
||||
* Ask user if we should proceed.
|
||||
*/
|
||||
parg.p_string = filename;
|
||||
answer = query("\"%s\" may be a binary file. See it anyway? ", &parg);
|
||||
if (answer != 'y' && answer != 'Y')
|
||||
{
|
||||
close(f);
|
||||
return edit_error(filename, alt_filename, altpipe, 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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We must close the currently open file now.
|
||||
* This is necessary to make the open_altfile/close_altfile pairs
|
||||
* nest properly (or rather to avoid nesting at all).
|
||||
* {{ Some stupid implementations of popen() mess up if you do:
|
||||
* fA = popen("A"); fB = popen("B"); pclose(fA); pclose(fB); }}
|
||||
*/
|
||||
#if LOGFILE
|
||||
end_logfile();
|
||||
#endif
|
||||
was_curr_ifile = save_curr_ifile();
|
||||
if (curr_ifile != NULL_IFILE)
|
||||
{
|
||||
chflags = ch_getflags();
|
||||
int was_helpfile = (ch_getflags() & CH_HELPFILE);
|
||||
close_file();
|
||||
if ((chflags & CH_HELPFILE) && held_ifile(was_curr_ifile) <= 1)
|
||||
if (was_helpfile && held_ifile(was_curr_ifile) <= 1)
|
||||
{
|
||||
/*
|
||||
* Don't keep the help file in the ifile list.
|
||||
*/
|
||||
del_ifile(was_curr_ifile);
|
||||
was_curr_ifile = old_ifile;
|
||||
was_curr_ifile = NULL_IFILE;
|
||||
}
|
||||
}
|
||||
unsave_ifile(was_curr_ifile);
|
||||
|
||||
if (ifile == NULL_IFILE)
|
||||
{
|
||||
|
|
@ -481,145 +596,26 @@ public int edit_ifile(IFILE ifile)
|
|||
* you're supposed to have saved curr_ifile yourself,
|
||||
* and you'll restore it if necessary.)
|
||||
*/
|
||||
unsave_ifile(was_curr_ifile);
|
||||
return (0);
|
||||
}
|
||||
|
||||
filename = save(get_filename(ifile));
|
||||
|
||||
/*
|
||||
* See if LESSOPEN specifies an "alternate" file to open.
|
||||
*/
|
||||
altpipe = get_altpipe(ifile);
|
||||
if (altpipe != NULL)
|
||||
{
|
||||
/*
|
||||
* File is already open.
|
||||
* chflags and f are not used by ch_init if ifile has
|
||||
* filestate which should be the case if we're here.
|
||||
* Set them here to avoid uninitialized variable warnings.
|
||||
*/
|
||||
chflags = 0;
|
||||
f = -1;
|
||||
alt_filename = get_altfilename(ifile);
|
||||
open_filename = (alt_filename != NULL) ? alt_filename : filename;
|
||||
} else
|
||||
{
|
||||
if (strcmp(filename, FAKE_HELPFILE) == 0 ||
|
||||
strcmp(filename, FAKE_EMPTYFILE) == 0)
|
||||
alt_filename = NULL;
|
||||
else
|
||||
alt_filename = open_altfile(filename, &f, &altpipe);
|
||||
|
||||
open_filename = (alt_filename != NULL) ? alt_filename : filename;
|
||||
|
||||
chflags = 0;
|
||||
if (altpipe != NULL)
|
||||
{
|
||||
/*
|
||||
* The alternate "file" is actually a pipe.
|
||||
* f has already been set to the file descriptor of the pipe
|
||||
* in the call to open_altfile above.
|
||||
* Keep the file descriptor open because it was opened
|
||||
* via popen(), and pclose() wants to close it.
|
||||
*/
|
||||
chflags |= CH_POPENED;
|
||||
if (strcmp(filename, "-") == 0)
|
||||
chflags |= CH_KEEPOPEN;
|
||||
} else if (strcmp(filename, "-") == 0)
|
||||
{
|
||||
/*
|
||||
* Use standard input.
|
||||
* Keep the file descriptor open because we can't reopen it.
|
||||
*/
|
||||
f = fd0;
|
||||
chflags |= CH_KEEPOPEN;
|
||||
/*
|
||||
* Must switch stdin to BINARY mode.
|
||||
*/
|
||||
SET_BINARY(f);
|
||||
#if MSDOS_COMPILER==DJGPPC
|
||||
/*
|
||||
* Setting stdin to binary by default causes
|
||||
* Ctrl-C to not raise SIGINT. We must undo
|
||||
* that side-effect.
|
||||
*/
|
||||
__djgpp_set_ctrl_c(1);
|
||||
#endif
|
||||
} else if (strcmp(open_filename, FAKE_EMPTYFILE) == 0)
|
||||
{
|
||||
f = -1;
|
||||
chflags |= CH_NODATA;
|
||||
} else if (strcmp(open_filename, FAKE_HELPFILE) == 0)
|
||||
{
|
||||
f = -1;
|
||||
chflags |= CH_HELPFILE;
|
||||
} else if ((parg.p_string = bad_file(open_filename)) != NULL)
|
||||
{
|
||||
/*
|
||||
* It looks like a bad file. Don't try to open it.
|
||||
*/
|
||||
error("%s", &parg);
|
||||
free(parg.p_string);
|
||||
return edit_error(filename, alt_filename, altpipe, ifile, was_curr_ifile);
|
||||
} else if ((f = open(open_filename, OPEN_READ)) < 0)
|
||||
{
|
||||
/*
|
||||
* Got an error trying to open it.
|
||||
*/
|
||||
parg.p_string = errno_message(filename);
|
||||
error("%s", &parg);
|
||||
free(parg.p_string);
|
||||
return edit_error(filename, alt_filename, altpipe, ifile, was_curr_ifile);
|
||||
} else
|
||||
{
|
||||
chflags |= CH_CANSEEK;
|
||||
if (!force_open && !opened(ifile) && bin_file(f))
|
||||
{
|
||||
/*
|
||||
* Looks like a binary file.
|
||||
* Ask user if we should proceed.
|
||||
*/
|
||||
parg.p_string = filename;
|
||||
answer = query("\"%s\" may be a binary file. See it anyway? ",
|
||||
&parg);
|
||||
if (answer != 'y' && answer != 'Y')
|
||||
{
|
||||
close(f);
|
||||
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.
|
||||
* Set up the new ifile.
|
||||
* Get the saved position for the file.
|
||||
*/
|
||||
if (was_curr_ifile != NULL_IFILE)
|
||||
{
|
||||
old_ifile = was_curr_ifile;
|
||||
unsave_ifile(was_curr_ifile);
|
||||
}
|
||||
curr_ifile = ifile;
|
||||
set_altfilename(curr_ifile, alt_filename);
|
||||
set_altpipe(curr_ifile, altpipe);
|
||||
set_open(curr_ifile); /* File has been opened */
|
||||
get_pos(curr_ifile, &initial_scrpos);
|
||||
new_file = TRUE;
|
||||
ch_init(f, chflags);
|
||||
ch_init(f, chflags, nread);
|
||||
consecutive_nulls = 0;
|
||||
check_modelines();
|
||||
|
||||
if (!(chflags & CH_HELPFILE))
|
||||
{
|
||||
if (was_curr_ifile != NULL_IFILE)
|
||||
old_ifile = was_curr_ifile;
|
||||
#if LOGFILE
|
||||
if (namelogfile != NULL && is_tty)
|
||||
use_logfile(namelogfile);
|
||||
|
|
@ -640,7 +636,7 @@ public int edit_ifile(IFILE ifile)
|
|||
if (every_first_cmd != NULL)
|
||||
{
|
||||
ungetsc(every_first_cmd);
|
||||
ungetcc_back(CHAR_END_COMMAND);
|
||||
ungetcc_end_command();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -669,8 +665,8 @@ public int edit_ifile(IFILE ifile)
|
|||
}
|
||||
if (want_filesize)
|
||||
scan_eof();
|
||||
set_header(ch_zero());
|
||||
}
|
||||
free(filename);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
@ -682,10 +678,10 @@ public int edit_ifile(IFILE ifile)
|
|||
public int edit_list(char *filelist)
|
||||
{
|
||||
IFILE save_ifile;
|
||||
char *good_filename;
|
||||
char *filename;
|
||||
constant char *good_filename;
|
||||
constant char *filename;
|
||||
char *gfilelist;
|
||||
char *gfilename;
|
||||
constant char *gfilename;
|
||||
char *qfilename;
|
||||
struct textlist tl_files;
|
||||
struct textlist tl_gfiles;
|
||||
|
|
@ -929,7 +925,7 @@ public void cat_file(void)
|
|||
* is standard input, create the log file.
|
||||
* We take care not to blindly overwrite an existing file.
|
||||
*/
|
||||
public void use_logfile(char *filename)
|
||||
public void use_logfile(constant char *filename)
|
||||
{
|
||||
int exists;
|
||||
int answer;
|
||||
|
|
@ -982,7 +978,7 @@ loop:
|
|||
* Append: open the file and seek to the end.
|
||||
*/
|
||||
logfile = open(filename, OPEN_APPEND);
|
||||
if (lseek(logfile, (off_t)0, SEEK_END) == BAD_LSEEK)
|
||||
if (less_lseek(logfile, (less_off_t)0, SEEK_END) == BAD_LSEEK)
|
||||
{
|
||||
close(logfile);
|
||||
logfile = -1;
|
||||
|
|
|
|||
192
contrib/less/evar.c
Normal file
192
contrib/less/evar.c
Normal file
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
*
|
||||
* For more information, see the README file.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Code to support expanding environment variables in text.
|
||||
*/
|
||||
|
||||
#include "less.h"
|
||||
#include "xbuf.h"
|
||||
|
||||
struct replace {
|
||||
struct replace *r_next;
|
||||
char *r_fm;
|
||||
char *r_to;
|
||||
};
|
||||
|
||||
/*
|
||||
* Skip to the next unescaped slash or right curly bracket in a string.
|
||||
*/
|
||||
static size_t skipsl(constant char *buf, size_t len, size_t e)
|
||||
{
|
||||
lbool esc = FALSE;
|
||||
while (e < len && buf[e] != '\0' && (esc || (buf[e] != '/' && buf[e] != '}')))
|
||||
{
|
||||
esc = (!esc && buf[e] == '\\');
|
||||
++e;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a replacement string: one or more instances of
|
||||
* (slash, pattern, slash, replacement), followed by right curly bracket.
|
||||
* Replacement may be empty in which case the second slash is optional.
|
||||
*/
|
||||
static struct replace * make_replaces(mutable char *buf, size_t len, size_t *pe, char term)
|
||||
{
|
||||
size_t e = *pe;
|
||||
struct replace *replaces = NULL;
|
||||
|
||||
while (term == '/')
|
||||
{
|
||||
struct replace *repl;
|
||||
size_t to;
|
||||
size_t fm = e;
|
||||
e = skipsl(buf, len, e);
|
||||
if (e >= len) break;
|
||||
if (e == fm) /* missing fm string; we're done */
|
||||
{
|
||||
while (e < len)
|
||||
if (buf[e++] == '}') break;
|
||||
break;
|
||||
}
|
||||
term = buf[e];
|
||||
buf[e++] = '\0'; /* terminate the fm string */
|
||||
if (term != '/') /* missing to string */
|
||||
{
|
||||
to = e-1;
|
||||
} else
|
||||
{
|
||||
to = e;
|
||||
e = skipsl(buf, len, e);
|
||||
if (e >= len) break;
|
||||
term = buf[e];
|
||||
buf[e++] = '\0'; /* terminate the to string */
|
||||
}
|
||||
repl = ecalloc(1, sizeof(struct replace));
|
||||
repl->r_fm = &buf[fm];
|
||||
repl->r_to = &buf[to];
|
||||
repl->r_next = replaces;
|
||||
replaces = repl;
|
||||
}
|
||||
*pe = e;
|
||||
return replaces;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free a list of replace structs.
|
||||
*/
|
||||
static void free_replaces(struct replace *replaces)
|
||||
{
|
||||
while (replaces != NULL)
|
||||
{
|
||||
struct replace *r = replaces;
|
||||
replaces = r->r_next;
|
||||
free(r);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* See if the initial substring of a string matches a pattern.
|
||||
* Backslash escapes in the pattern are ignored.
|
||||
* Return the length of the matched substring, or 0 if no match.
|
||||
*/
|
||||
static size_t evar_match(constant char *str, constant char *pat)
|
||||
{
|
||||
size_t len = 0;
|
||||
while (*pat != '\0')
|
||||
{
|
||||
if (*pat == '\\') ++pat;
|
||||
if (*str++ != *pat++) return 0;
|
||||
++len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the replacement for a string (&evar[*pv]),
|
||||
* given a list of replace structs.
|
||||
*/
|
||||
static constant char * find_replace(constant struct replace *repl, constant char *evar, size_t *pv)
|
||||
{
|
||||
for (; repl != NULL; repl = repl->r_next)
|
||||
{
|
||||
size_t len = evar_match(&evar[*pv], repl->r_fm);
|
||||
if (len > 0)
|
||||
{
|
||||
*pv += len;
|
||||
return repl->r_to;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* With buf[e] positioned just after NAME in "${NAME" and
|
||||
* term containing the character at that point, parse the rest
|
||||
* of the environment var string (including the final right curly bracket).
|
||||
* Write evar to xbuf, performing any specified text replacements.
|
||||
* Return the new value of e to point just after the final right curly bracket.
|
||||
*/
|
||||
static size_t add_evar(struct xbuffer *xbuf, mutable char *buf, size_t len, size_t e, constant char *evar, char term)
|
||||
{
|
||||
struct replace *replaces = make_replaces(buf, len, &e, term);
|
||||
size_t v;
|
||||
|
||||
for (v = 0; evar[v] != '\0'; )
|
||||
{
|
||||
constant char *repl = find_replace(replaces, evar, &v);
|
||||
if (repl == NULL)
|
||||
xbuf_add_char(xbuf, evar[v++]);
|
||||
else
|
||||
{
|
||||
size_t r;
|
||||
for (r = 0; repl[r] != '\0'; r++)
|
||||
{
|
||||
if (repl[r] == '\\') ++r;
|
||||
xbuf_add_char(xbuf, repl[r]);
|
||||
}
|
||||
}
|
||||
}
|
||||
free_replaces(replaces);
|
||||
return e;
|
||||
}
|
||||
|
||||
/*
|
||||
* Expand env variables in a string.
|
||||
* Writes expanded output to xbuf. Corrupts buf.
|
||||
*/
|
||||
public void expand_evars(mutable char *buf, size_t len, struct xbuffer *xbuf)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < len; )
|
||||
{
|
||||
if (i+1 < len && buf[i] == '$' && buf[i+1] == '{')
|
||||
{
|
||||
constant char *evar;
|
||||
char term;
|
||||
size_t e;
|
||||
i += 2; /* skip "${" */
|
||||
for (e = i; e < len; e++)
|
||||
if (buf[e] == '\0' || buf[e] == '}' || buf[e] == '/')
|
||||
break;
|
||||
if (e >= len || buf[e] == '\0')
|
||||
break; /* missing right curly bracket; ignore var */
|
||||
term = buf[e];
|
||||
buf[e++] = '\0';
|
||||
evar = lgetenv_ext(&buf[i], xbuf->data, xbuf->end);
|
||||
if (evar == NULL) evar = "";
|
||||
i = add_evar(xbuf, buf, len, e, evar, term);
|
||||
} else
|
||||
{
|
||||
xbuf_add_char(xbuf, buf[i++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -44,7 +44,6 @@
|
|||
#endif
|
||||
|
||||
extern int force_open;
|
||||
extern int secure;
|
||||
extern int use_lessopen;
|
||||
extern int ctldisp;
|
||||
extern int utf_mode;
|
||||
|
|
@ -62,7 +61,7 @@ extern dev_t curr_dev;
|
|||
/*
|
||||
* Remove quotes around a filename.
|
||||
*/
|
||||
public char * shell_unquote(char *str)
|
||||
public char * shell_unquote(constant char *str)
|
||||
{
|
||||
char *name;
|
||||
char *p;
|
||||
|
|
@ -83,8 +82,8 @@ public char * shell_unquote(char *str)
|
|||
}
|
||||
} else
|
||||
{
|
||||
char *esc = get_meta_escape();
|
||||
int esclen = (int) strlen(esc);
|
||||
constant char *esc = get_meta_escape();
|
||||
size_t esclen = strlen(esc);
|
||||
while (*str != '\0')
|
||||
{
|
||||
if (esclen > 0 && strncmp(str, esc, esclen) == 0)
|
||||
|
|
@ -99,9 +98,9 @@ public char * shell_unquote(char *str)
|
|||
/*
|
||||
* Get the shell's escape character.
|
||||
*/
|
||||
public char * get_meta_escape(void)
|
||||
public constant char * get_meta_escape(void)
|
||||
{
|
||||
char *s;
|
||||
constant char *s;
|
||||
|
||||
s = lgetenv("LESSMETAESCAPE");
|
||||
if (s == NULL)
|
||||
|
|
@ -112,9 +111,9 @@ public char * get_meta_escape(void)
|
|||
/*
|
||||
* Get the characters which the shell considers to be "metacharacters".
|
||||
*/
|
||||
static char * metachars(void)
|
||||
static constant char * metachars(void)
|
||||
{
|
||||
static char *mchars = NULL;
|
||||
static constant char *mchars = NULL;
|
||||
|
||||
if (mchars == NULL)
|
||||
{
|
||||
|
|
@ -128,33 +127,43 @@ static char * metachars(void)
|
|||
/*
|
||||
* Is this a shell metacharacter?
|
||||
*/
|
||||
static int metachar(char c)
|
||||
static lbool metachar(char c)
|
||||
{
|
||||
return (strchr(metachars(), c) != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Must use quotes rather than escape char for this metachar?
|
||||
*/
|
||||
static lbool must_quote(char c)
|
||||
{
|
||||
/* {{ Maybe the set of must_quote chars should be configurable? }} */
|
||||
return (c == '\n');
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert a backslash before each metacharacter in a string.
|
||||
*/
|
||||
public char * shell_quote(char *s)
|
||||
public char * shell_quoten(constant char *s, size_t slen)
|
||||
{
|
||||
char *p;
|
||||
constant char *p;
|
||||
char *np;
|
||||
char *newstr;
|
||||
int len;
|
||||
char *esc = get_meta_escape();
|
||||
int esclen = (int) strlen(esc);
|
||||
int use_quotes = 0;
|
||||
int have_quotes = 0;
|
||||
size_t len;
|
||||
constant char *esc = get_meta_escape();
|
||||
size_t esclen = strlen(esc);
|
||||
lbool use_quotes = FALSE;
|
||||
lbool have_quotes = FALSE;
|
||||
|
||||
/*
|
||||
* Determine how big a string we need to allocate.
|
||||
*/
|
||||
len = 1; /* Trailing null byte */
|
||||
for (p = s; *p != '\0'; p++)
|
||||
for (p = s; p < s + slen; p++)
|
||||
{
|
||||
len++;
|
||||
if (*p == openquote || *p == closequote)
|
||||
have_quotes = 1;
|
||||
have_quotes = TRUE;
|
||||
if (metachar(*p))
|
||||
{
|
||||
if (esclen == 0)
|
||||
|
|
@ -163,7 +172,10 @@ public char * shell_quote(char *s)
|
|||
* We've got a metachar, but this shell
|
||||
* doesn't support escape chars. Use quotes.
|
||||
*/
|
||||
use_quotes = 1;
|
||||
use_quotes = TRUE;
|
||||
} else if (must_quote(*p))
|
||||
{
|
||||
len += 3; /* open quote + char + close quote */
|
||||
} else
|
||||
{
|
||||
/*
|
||||
|
|
@ -180,42 +192,55 @@ public char * shell_quote(char *s)
|
|||
* We can't quote a string that contains quotes.
|
||||
*/
|
||||
return (NULL);
|
||||
len = (int) strlen(s) + 3;
|
||||
len = slen + 3;
|
||||
}
|
||||
/*
|
||||
* Allocate and construct the new string.
|
||||
*/
|
||||
newstr = p = (char *) ecalloc(len, sizeof(char));
|
||||
newstr = np = (char *) ecalloc(len, sizeof(char));
|
||||
if (use_quotes)
|
||||
{
|
||||
SNPRINTF3(newstr, len, "%c%s%c", openquote, s, closequote);
|
||||
SNPRINTF4(newstr, len, "%c%.*s%c", openquote, (int) slen, s, closequote);
|
||||
} else
|
||||
{
|
||||
while (*s != '\0')
|
||||
constant char *es = s + slen;
|
||||
while (s < es)
|
||||
{
|
||||
if (metachar(*s))
|
||||
if (!metachar(*s))
|
||||
{
|
||||
/*
|
||||
* Add the escape char.
|
||||
*/
|
||||
strcpy(p, esc);
|
||||
p += esclen;
|
||||
*np++ = *s++;
|
||||
} else if (must_quote(*s))
|
||||
{
|
||||
/* Surround the char with quotes. */
|
||||
*np++ = openquote;
|
||||
*np++ = *s++;
|
||||
*np++ = closequote;
|
||||
} else
|
||||
{
|
||||
/* Insert an escape char before the char. */
|
||||
strcpy(np, esc);
|
||||
np += esclen;
|
||||
*np++ = *s++;
|
||||
}
|
||||
*p++ = *s++;
|
||||
}
|
||||
*p = '\0';
|
||||
*np = '\0';
|
||||
}
|
||||
return (newstr);
|
||||
}
|
||||
|
||||
public char * shell_quote(constant char *s)
|
||||
{
|
||||
return shell_quoten(s, strlen(s));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a pathname that points to a specified file in a specified directory.
|
||||
* Return NULL if the file does not exist in the directory.
|
||||
*/
|
||||
public char * dirfile(char *dirname, char *filename, int must_exist)
|
||||
public char * dirfile(constant char *dirname, constant char *filename, int must_exist)
|
||||
{
|
||||
char *pathname;
|
||||
int len;
|
||||
size_t len;
|
||||
int f;
|
||||
|
||||
if (dirname == NULL || *dirname == '\0')
|
||||
|
|
@ -223,7 +248,7 @@ public char * dirfile(char *dirname, char *filename, int must_exist)
|
|||
/*
|
||||
* Construct the full pathname.
|
||||
*/
|
||||
len = (int) (strlen(dirname) + strlen(filename) + 2);
|
||||
len = strlen(dirname) + strlen(filename) + 2;
|
||||
pathname = (char *) calloc(len, sizeof(char));
|
||||
if (pathname == NULL)
|
||||
return (NULL);
|
||||
|
|
@ -249,7 +274,7 @@ public char * dirfile(char *dirname, char *filename, int must_exist)
|
|||
/*
|
||||
* Return the full pathname of the given file in the "home directory".
|
||||
*/
|
||||
public char * homefile(char *filename)
|
||||
public char * homefile(constant char *filename)
|
||||
{
|
||||
char *pathname;
|
||||
|
||||
|
|
@ -284,6 +309,69 @@ public char * homefile(char *filename)
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
typedef struct xcpy { char *dest; size_t copied; } xcpy;
|
||||
|
||||
static void xcpy_char(xcpy *xp, char ch)
|
||||
{
|
||||
if (xp->dest != NULL) *(xp->dest)++ = ch;
|
||||
xp->copied++;
|
||||
}
|
||||
|
||||
static void xcpy_filename(xcpy *xp, constant char *str)
|
||||
{
|
||||
/* If filename contains spaces, quote it
|
||||
* to prevent edit_list from splitting it. */
|
||||
lbool quote = (strchr(str, ' ') != NULL);
|
||||
if (quote)
|
||||
xcpy_char(xp, openquote);
|
||||
for (; *str != '\0'; str++)
|
||||
xcpy_char(xp, *str);
|
||||
if (quote)
|
||||
xcpy_char(xp, closequote);
|
||||
}
|
||||
|
||||
static size_t fexpand_copy(constant char *fr, char *to)
|
||||
{
|
||||
xcpy xp;
|
||||
xp.copied = 0;
|
||||
xp.dest = to;
|
||||
|
||||
for (; *fr != '\0'; fr++)
|
||||
{
|
||||
lbool expand = FALSE;
|
||||
switch (*fr)
|
||||
{
|
||||
case '%':
|
||||
case '#':
|
||||
if (fr[1] == *fr)
|
||||
{
|
||||
/* Two identical chars. Output just one. */
|
||||
fr += 1;
|
||||
} else
|
||||
{
|
||||
/* Single char. Expand to a (quoted) file name. */
|
||||
expand = TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (expand)
|
||||
{
|
||||
IFILE ifile = (*fr == '%') ? curr_ifile : (*fr == '#') ? old_ifile : NULL_IFILE;
|
||||
if (ifile == NULL_IFILE)
|
||||
xcpy_char(&xp, *fr);
|
||||
else
|
||||
xcpy_filename(&xp, get_filename(ifile));
|
||||
} else
|
||||
{
|
||||
xcpy_char(&xp, *fr);
|
||||
}
|
||||
}
|
||||
xcpy_char(&xp, '\0');
|
||||
return xp.copied;
|
||||
}
|
||||
|
||||
/*
|
||||
* Expand a string, substituting any "%" with the current filename,
|
||||
* and any "#" with the previous filename.
|
||||
|
|
@ -291,90 +379,22 @@ public char * homefile(char *filename)
|
|||
* Likewise for a string of N "#"s.
|
||||
* {{ This is a lot of work just to support % and #. }}
|
||||
*/
|
||||
public char * fexpand(char *s)
|
||||
public char * fexpand(constant char *s)
|
||||
{
|
||||
char *fr, *to;
|
||||
int n;
|
||||
size_t n;
|
||||
char *e;
|
||||
IFILE ifile;
|
||||
|
||||
#define fchar_ifile(c) \
|
||||
((c) == '%' ? curr_ifile : \
|
||||
(c) == '#' ? old_ifile : NULL_IFILE)
|
||||
|
||||
/*
|
||||
* Make one pass to see how big a buffer we
|
||||
* need to allocate for the expanded string.
|
||||
*/
|
||||
n = 0;
|
||||
for (fr = s; *fr != '\0'; fr++)
|
||||
{
|
||||
switch (*fr)
|
||||
{
|
||||
case '%':
|
||||
case '#':
|
||||
if (fr > s && fr[-1] == *fr)
|
||||
{
|
||||
/*
|
||||
* Second (or later) char in a string
|
||||
* of identical chars. Treat as normal.
|
||||
*/
|
||||
n++;
|
||||
} else if (fr[1] != *fr)
|
||||
{
|
||||
/*
|
||||
* Single char (not repeated). Treat specially.
|
||||
*/
|
||||
ifile = fchar_ifile(*fr);
|
||||
if (ifile == NULL_IFILE)
|
||||
n++;
|
||||
else
|
||||
n += (int) strlen(get_filename(ifile));
|
||||
}
|
||||
/*
|
||||
* Else it is the first char in a string of
|
||||
* identical chars. Just discard it.
|
||||
*/
|
||||
break;
|
||||
default:
|
||||
n++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
e = (char *) ecalloc(n+1, sizeof(char));
|
||||
n = fexpand_copy(s, NULL);
|
||||
e = (char *) ecalloc(n, sizeof(char));
|
||||
|
||||
/*
|
||||
* Now copy the string, expanding any "%" or "#".
|
||||
*/
|
||||
to = e;
|
||||
for (fr = s; *fr != '\0'; fr++)
|
||||
{
|
||||
switch (*fr)
|
||||
{
|
||||
case '%':
|
||||
case '#':
|
||||
if (fr > s && fr[-1] == *fr)
|
||||
{
|
||||
*to++ = *fr;
|
||||
} else if (fr[1] != *fr)
|
||||
{
|
||||
ifile = fchar_ifile(*fr);
|
||||
if (ifile == NULL_IFILE)
|
||||
*to++ = *fr;
|
||||
else
|
||||
{
|
||||
strcpy(to, get_filename(ifile));
|
||||
to += strlen(to);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
*to++ = *fr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*to = '\0';
|
||||
fexpand_copy(s, e);
|
||||
return (e);
|
||||
}
|
||||
|
||||
|
|
@ -385,12 +405,14 @@ public char * fexpand(char *s)
|
|||
* Return a blank-separated list of filenames which "complete"
|
||||
* the given string.
|
||||
*/
|
||||
public char * fcomplete(char *s)
|
||||
public char * fcomplete(constant char *s)
|
||||
{
|
||||
char *fpat;
|
||||
char *qs;
|
||||
char *uqs;
|
||||
|
||||
if (secure)
|
||||
/* {{ Is this needed? lglob calls secure_allow. }} */
|
||||
if (!secure_allow(SF_GLOB))
|
||||
return (NULL);
|
||||
/*
|
||||
* Complete the filename "s" by globbing "s*".
|
||||
|
|
@ -404,12 +426,12 @@ public char * fcomplete(char *s)
|
|||
* but "FILE.A" is globbed as "FILE.A*").
|
||||
*/
|
||||
{
|
||||
char *slash;
|
||||
int len;
|
||||
constant char *slash;
|
||||
size_t len;
|
||||
for (slash = s+strlen(s)-1; slash > s; slash--)
|
||||
if (*slash == *PATHNAME_SEP || *slash == '/')
|
||||
break;
|
||||
len = (int) strlen(s) + 4;
|
||||
len = strlen(s) + 4;
|
||||
fpat = (char *) ecalloc(len, sizeof(char));
|
||||
if (strchr(slash, '.') == NULL)
|
||||
SNPRINTF1(fpat, len, "%s*.*", s);
|
||||
|
|
@ -418,14 +440,14 @@ public char * fcomplete(char *s)
|
|||
}
|
||||
#else
|
||||
{
|
||||
int len = (int) strlen(s) + 2;
|
||||
size_t len = strlen(s) + 2;
|
||||
fpat = (char *) ecalloc(len, sizeof(char));
|
||||
SNPRINTF1(fpat, len, "%s*", s);
|
||||
}
|
||||
#endif
|
||||
qs = lglob(fpat);
|
||||
s = shell_unquote(qs);
|
||||
if (strcmp(s,fpat) == 0)
|
||||
uqs = shell_unquote(qs);
|
||||
if (strcmp(uqs, fpat) == 0)
|
||||
{
|
||||
/*
|
||||
* The filename didn't expand.
|
||||
|
|
@ -433,7 +455,7 @@ public char * fcomplete(char *s)
|
|||
free(qs);
|
||||
qs = NULL;
|
||||
}
|
||||
free(s);
|
||||
free(uqs);
|
||||
free(fpat);
|
||||
return (qs);
|
||||
}
|
||||
|
|
@ -442,32 +464,35 @@ public char * fcomplete(char *s)
|
|||
/*
|
||||
* Try to determine if a file is "binary".
|
||||
* This is just a guess, and we need not try too hard to make it accurate.
|
||||
*
|
||||
* The number of bytes read is returned to the caller, because it will
|
||||
* be used later to compare to st_size from stat(2) to see if the file
|
||||
* is lying about its size.
|
||||
*/
|
||||
public int bin_file(int f)
|
||||
public int bin_file(int f, ssize_t *n)
|
||||
{
|
||||
int n;
|
||||
int bin_count = 0;
|
||||
char data[256];
|
||||
char* p;
|
||||
char* edata;
|
||||
constant char* p;
|
||||
constant char* edata;
|
||||
|
||||
if (!seekable(f))
|
||||
return (0);
|
||||
if (lseek(f, (off_t)0, SEEK_SET) == BAD_LSEEK)
|
||||
if (less_lseek(f, (less_off_t)0, SEEK_SET) == BAD_LSEEK)
|
||||
return (0);
|
||||
n = read(f, data, sizeof(data));
|
||||
if (n <= 0)
|
||||
*n = read(f, data, sizeof(data));
|
||||
if (*n <= 0)
|
||||
return (0);
|
||||
edata = &data[n];
|
||||
edata = &data[*n];
|
||||
for (p = data; p < edata; )
|
||||
{
|
||||
if (utf_mode && !is_utf8_well_formed(p, edata-p))
|
||||
if (utf_mode && !is_utf8_well_formed(p, (int) ptr_diff(edata,p)))
|
||||
{
|
||||
bin_count++;
|
||||
utf_skip_to_lead(&p, edata);
|
||||
} else
|
||||
{
|
||||
LWCHAR c = step_char(&p, +1, edata);
|
||||
LWCHAR c = step_charc(&p, +1, edata);
|
||||
struct ansi_state *pansi;
|
||||
if (ctldisp == OPT_ONPLUS && (pansi = ansi_start(c)) != NULL)
|
||||
{
|
||||
|
|
@ -489,9 +514,9 @@ public int bin_file(int f)
|
|||
*/
|
||||
static POSITION seek_filesize(int f)
|
||||
{
|
||||
off_t spos;
|
||||
less_off_t spos;
|
||||
|
||||
spos = lseek(f, (off_t)0, SEEK_END);
|
||||
spos = less_lseek(f, (less_off_t)0, SEEK_END);
|
||||
if (spos == BAD_LSEEK)
|
||||
return (NULL_POSITION);
|
||||
return ((POSITION) spos);
|
||||
|
|
@ -502,53 +527,31 @@ static POSITION seek_filesize(int f)
|
|||
* Read a string from a file.
|
||||
* Return a pointer to the string in memory.
|
||||
*/
|
||||
static char * readfd(FILE *fd)
|
||||
public char * readfd(FILE *fd)
|
||||
{
|
||||
int len;
|
||||
int ch;
|
||||
char *buf;
|
||||
char *p;
|
||||
|
||||
/*
|
||||
* Make a guess about how many chars in the string
|
||||
* and allocate a buffer to hold it.
|
||||
*/
|
||||
len = 100;
|
||||
buf = (char *) ecalloc(len, sizeof(char));
|
||||
for (p = buf; ; p++)
|
||||
struct xbuffer xbuf;
|
||||
xbuf_init(&xbuf);
|
||||
for (;;)
|
||||
{
|
||||
int ch;
|
||||
if ((ch = getc(fd)) == '\n' || ch == EOF)
|
||||
break;
|
||||
if (p - buf >= len-1)
|
||||
{
|
||||
/*
|
||||
* The string is too big to fit in the buffer we have.
|
||||
* Allocate a new buffer, twice as big.
|
||||
*/
|
||||
len *= 2;
|
||||
*p = '\0';
|
||||
p = (char *) ecalloc(len, sizeof(char));
|
||||
strcpy(p, buf);
|
||||
free(buf);
|
||||
buf = p;
|
||||
p = buf + strlen(buf);
|
||||
}
|
||||
*p = ch;
|
||||
xbuf_add_char(&xbuf, (char) ch);
|
||||
}
|
||||
*p = '\0';
|
||||
return (buf);
|
||||
xbuf_add_char(&xbuf, '\0');
|
||||
return (char *) xbuf.data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute a shell command.
|
||||
* Return a pointer to a pipe connected to the shell command's standard output.
|
||||
*/
|
||||
static FILE * shellcmd(char *cmd)
|
||||
static FILE * shellcmd(constant char *cmd)
|
||||
{
|
||||
FILE *fd;
|
||||
|
||||
#if HAVE_SHELL
|
||||
char *shell;
|
||||
constant char *shell;
|
||||
|
||||
shell = lgetenv("SHELL");
|
||||
if (!isnullenv(shell))
|
||||
|
|
@ -566,7 +569,7 @@ static FILE * shellcmd(char *cmd)
|
|||
fd = popen(cmd, "r");
|
||||
} else
|
||||
{
|
||||
int len = (int) (strlen(shell) + strlen(esccmd) + 5);
|
||||
size_t len = strlen(shell) + strlen(esccmd) + 5;
|
||||
scmd = (char *) ecalloc(len, sizeof(char));
|
||||
SNPRINTF3(scmd, len, "%s %s %s", shell, shell_coption(), esccmd);
|
||||
free(esccmd);
|
||||
|
|
@ -592,12 +595,12 @@ static FILE * shellcmd(char *cmd)
|
|||
/*
|
||||
* Expand a filename, doing any system-specific metacharacter substitutions.
|
||||
*/
|
||||
public char * lglob(char *filename)
|
||||
public char * lglob(constant char *afilename)
|
||||
{
|
||||
char *gfilename;
|
||||
char *filename = fexpand(afilename);
|
||||
|
||||
filename = fexpand(filename);
|
||||
if (secure)
|
||||
if (!secure_allow(SF_GLOB))
|
||||
return (filename);
|
||||
|
||||
#ifdef DECL_GLOB_LIST
|
||||
|
|
@ -605,7 +608,7 @@ public char * lglob(char *filename)
|
|||
/*
|
||||
* The globbing function returns a list of names.
|
||||
*/
|
||||
int length;
|
||||
size_t length;
|
||||
char *p;
|
||||
char *qfilename;
|
||||
DECL_GLOB_LIST(list)
|
||||
|
|
@ -651,8 +654,8 @@ public char * lglob(char *filename)
|
|||
* is called multiple times to walk thru all names.
|
||||
*/
|
||||
char *p;
|
||||
int len;
|
||||
int n;
|
||||
size_t len;
|
||||
size_t n;
|
||||
char *pfilename;
|
||||
char *qfilename;
|
||||
DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle)
|
||||
|
|
@ -668,14 +671,14 @@ public char * lglob(char *filename)
|
|||
gfilename = (char *) ecalloc(len, sizeof(char));
|
||||
p = gfilename;
|
||||
do {
|
||||
n = (int) (strlen(drive) + strlen(dir) + strlen(fnd.GLOB_NAME) + 1);
|
||||
n = strlen(drive) + strlen(dir) + strlen(fnd.GLOB_NAME) + 1;
|
||||
pfilename = (char *) ecalloc(n, sizeof(char));
|
||||
SNPRINTF3(pfilename, n, "%s%s%s", drive, dir, fnd.GLOB_NAME);
|
||||
qfilename = shell_quote(pfilename);
|
||||
free(pfilename);
|
||||
if (qfilename != NULL)
|
||||
{
|
||||
n = (int) strlen(qfilename);
|
||||
n = strlen(qfilename);
|
||||
while (p - gfilename + n + 2 >= len)
|
||||
{
|
||||
/*
|
||||
|
|
@ -711,17 +714,18 @@ public char * lglob(char *filename)
|
|||
* an "echo" command to the shell and reading its output.
|
||||
*/
|
||||
FILE *fd;
|
||||
char *s;
|
||||
char *lessecho;
|
||||
constant char *s;
|
||||
constant char *lessecho;
|
||||
char *cmd;
|
||||
char *esc;
|
||||
int len;
|
||||
constant char *esc;
|
||||
char *qesc;
|
||||
size_t len;
|
||||
|
||||
esc = get_meta_escape();
|
||||
if (strlen(esc) == 0)
|
||||
esc = "-";
|
||||
esc = shell_quote(esc);
|
||||
if (esc == NULL)
|
||||
qesc = shell_quote(esc);
|
||||
if (qesc == NULL)
|
||||
{
|
||||
return (filename);
|
||||
}
|
||||
|
|
@ -731,11 +735,11 @@ public char * lglob(char *filename)
|
|||
/*
|
||||
* Invoke lessecho, and read its output (a globbed list of filenames).
|
||||
*/
|
||||
len = (int) (strlen(lessecho) + strlen(filename) + (7*strlen(metachars())) + 24);
|
||||
len = strlen(lessecho) + strlen(filename) + (7*strlen(metachars())) + 24;
|
||||
cmd = (char *) ecalloc(len, sizeof(char));
|
||||
SNPRINTF4(cmd, len, "%s -p0x%x -d0x%x -e%s ", lessecho,
|
||||
(unsigned char) openquote, (unsigned char) closequote, esc);
|
||||
free(esc);
|
||||
(unsigned char) openquote, (unsigned char) closequote, qesc);
|
||||
free(qesc);
|
||||
for (s = metachars(); *s != '\0'; s++)
|
||||
sprintf(cmd + strlen(cmd), "-n0x%x ", (unsigned char) *s);
|
||||
sprintf(cmd + strlen(cmd), "-- %s", filename);
|
||||
|
|
@ -772,7 +776,7 @@ public char * lglob(char *filename)
|
|||
/*
|
||||
* Does path not represent something in the file system?
|
||||
*/
|
||||
public int is_fake_pathname(char *path)
|
||||
public lbool is_fake_pathname(constant char *path)
|
||||
{
|
||||
return (strcmp(path, "-") == 0 ||
|
||||
strcmp(path, FAKE_HELPFILE) == 0 || strcmp(path, FAKE_EMPTYFILE) == 0);
|
||||
|
|
@ -781,14 +785,29 @@ public int is_fake_pathname(char *path)
|
|||
/*
|
||||
* Return canonical pathname.
|
||||
*/
|
||||
public char * lrealpath(char *path)
|
||||
public char * lrealpath(constant char *path)
|
||||
{
|
||||
if (!is_fake_pathname(path))
|
||||
{
|
||||
#if HAVE_REALPATH
|
||||
/*
|
||||
* Not all systems support the POSIX.1-2008 realpath() behavior
|
||||
* of allocating when passing a NULL argument. And PATH_MAX is
|
||||
* not required to be defined, or might contain an exceedingly
|
||||
* big value. We assume that if it is not defined (such as on
|
||||
* GNU/Hurd), then realpath() accepts NULL.
|
||||
*/
|
||||
#ifndef PATH_MAX
|
||||
char *rpath;
|
||||
|
||||
rpath = realpath(path, NULL);
|
||||
if (rpath != NULL)
|
||||
return (rpath);
|
||||
#else
|
||||
char rpath[PATH_MAX];
|
||||
if (realpath(path, rpath) != NULL)
|
||||
return (save(rpath));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
return (save(path));
|
||||
|
|
@ -799,7 +818,7 @@ public char * lrealpath(char *path)
|
|||
* Return number of %s escapes in a string.
|
||||
* Return a large number if there are any other % escapes besides %s.
|
||||
*/
|
||||
static int num_pct_s(char *lessopen)
|
||||
static int num_pct_s(constant char *lessopen)
|
||||
{
|
||||
int num = 0;
|
||||
|
||||
|
|
@ -824,21 +843,23 @@ static int num_pct_s(char *lessopen)
|
|||
* See if we should open a "replacement file"
|
||||
* instead of the file we're about to open.
|
||||
*/
|
||||
public char * open_altfile(char *filename, int *pf, void **pfd)
|
||||
public char * open_altfile(constant char *filename, int *pf, void **pfd)
|
||||
{
|
||||
#if !HAVE_POPEN
|
||||
return (NULL);
|
||||
#else
|
||||
char *lessopen;
|
||||
constant char *lessopen;
|
||||
char *qfilename;
|
||||
char *cmd;
|
||||
int len;
|
||||
size_t len;
|
||||
FILE *fd;
|
||||
#if HAVE_FILENO
|
||||
int returnfd = 0;
|
||||
#endif
|
||||
|
||||
if (!use_lessopen || secure)
|
||||
if (!secure_allow(SF_LESSOPEN))
|
||||
return (NULL);
|
||||
if (!use_lessopen)
|
||||
return (NULL);
|
||||
ch_ungetchar(-1);
|
||||
if ((lessopen = lgetenv("LESSOPEN")) == NULL)
|
||||
|
|
@ -875,7 +896,7 @@ public char * open_altfile(char *filename, int *pf, void **pfd)
|
|||
}
|
||||
|
||||
qfilename = shell_quote(filename);
|
||||
len = (int) (strlen(lessopen) + strlen(qfilename) + 2);
|
||||
len = strlen(lessopen) + strlen(qfilename) + 2;
|
||||
cmd = (char *) ecalloc(len, sizeof(char));
|
||||
SNPRINTF1(cmd, len, lessopen, qfilename);
|
||||
free(qfilename);
|
||||
|
|
@ -891,7 +912,7 @@ public char * open_altfile(char *filename, int *pf, void **pfd)
|
|||
#if HAVE_FILENO
|
||||
if (returnfd)
|
||||
{
|
||||
char c;
|
||||
unsigned char c;
|
||||
int f;
|
||||
|
||||
/*
|
||||
|
|
@ -945,19 +966,18 @@ public char * open_altfile(char *filename, int *pf, void **pfd)
|
|||
/*
|
||||
* Close a replacement file.
|
||||
*/
|
||||
public void close_altfile(char *altfilename, char *filename)
|
||||
public void close_altfile(constant char *altfilename, constant char *filename)
|
||||
{
|
||||
#if HAVE_POPEN
|
||||
char *lessclose;
|
||||
constant char *lessclose;
|
||||
char *qfilename;
|
||||
char *qaltfilename;
|
||||
FILE *fd;
|
||||
char *cmd;
|
||||
int len;
|
||||
size_t len;
|
||||
|
||||
if (secure)
|
||||
if (!secure_allow(SF_LESSOPEN))
|
||||
return;
|
||||
ch_ungetchar(-1);
|
||||
if ((lessclose = lgetenv("LESSCLOSE")) == NULL)
|
||||
return;
|
||||
if (num_pct_s(lessclose) > 2)
|
||||
|
|
@ -967,7 +987,7 @@ public void close_altfile(char *altfilename, char *filename)
|
|||
}
|
||||
qfilename = shell_quote(filename);
|
||||
qaltfilename = shell_quote(altfilename);
|
||||
len = (int) (strlen(lessclose) + strlen(qfilename) + strlen(qaltfilename) + 2);
|
||||
len = strlen(lessclose) + strlen(qfilename) + strlen(qaltfilename) + 2;
|
||||
cmd = (char *) ecalloc(len, sizeof(char));
|
||||
SNPRINTF2(cmd, len, lessclose, qfilename, qaltfilename);
|
||||
free(qaltfilename);
|
||||
|
|
@ -982,16 +1002,16 @@ public void close_altfile(char *altfilename, char *filename)
|
|||
/*
|
||||
* Is the specified file a directory?
|
||||
*/
|
||||
public int is_dir(char *filename)
|
||||
public lbool is_dir(constant char *filename)
|
||||
{
|
||||
int isdir = 0;
|
||||
lbool isdir = FALSE;
|
||||
|
||||
#if HAVE_STAT
|
||||
{
|
||||
int r;
|
||||
struct stat statbuf;
|
||||
less_stat_t statbuf;
|
||||
|
||||
r = stat(filename, &statbuf);
|
||||
r = less_stat(filename, &statbuf);
|
||||
isdir = (r >= 0 && S_ISDIR(statbuf.st_mode));
|
||||
}
|
||||
#else
|
||||
|
|
@ -1014,7 +1034,7 @@ public int is_dir(char *filename)
|
|||
* is an ordinary file, otherwise an error message
|
||||
* (if it cannot be opened or is a directory, etc.)
|
||||
*/
|
||||
public char * bad_file(char *filename)
|
||||
public char * bad_file(constant char *filename)
|
||||
{
|
||||
char *m = NULL;
|
||||
|
||||
|
|
@ -1030,9 +1050,9 @@ public char * bad_file(char *filename)
|
|||
{
|
||||
#if HAVE_STAT
|
||||
int r;
|
||||
struct stat statbuf;
|
||||
less_stat_t statbuf;
|
||||
|
||||
r = stat(filename, &statbuf);
|
||||
r = less_stat(filename, &statbuf);
|
||||
if (r < 0)
|
||||
{
|
||||
m = errno_message(filename);
|
||||
|
|
@ -1059,9 +1079,9 @@ public char * bad_file(char *filename)
|
|||
public POSITION filesize(int f)
|
||||
{
|
||||
#if HAVE_STAT
|
||||
struct stat statbuf;
|
||||
less_stat_t statbuf;
|
||||
|
||||
if (fstat(f, &statbuf) >= 0)
|
||||
if (less_fstat(f, &statbuf) >= 0)
|
||||
return ((POSITION) statbuf.st_size);
|
||||
#else
|
||||
#ifdef _OSK
|
||||
|
|
@ -1074,7 +1094,7 @@ public POSITION filesize(int f)
|
|||
return (seek_filesize(f));
|
||||
}
|
||||
|
||||
public int curr_ifile_changed(void)
|
||||
public lbool curr_ifile_changed(void)
|
||||
{
|
||||
#if HAVE_STAT_INO
|
||||
/*
|
||||
|
|
@ -1096,7 +1116,7 @@ public int curr_ifile_changed(void)
|
|||
/*
|
||||
*
|
||||
*/
|
||||
public char * shell_coption(void)
|
||||
public constant char * shell_coption(void)
|
||||
{
|
||||
return ("-c");
|
||||
}
|
||||
|
|
@ -1104,9 +1124,9 @@ public char * shell_coption(void)
|
|||
/*
|
||||
* Return last component of a pathname.
|
||||
*/
|
||||
public char * last_component(char *name)
|
||||
public constant char * last_component(constant char *name)
|
||||
{
|
||||
char *slash;
|
||||
constant char *slash;
|
||||
|
||||
for (slash = name + strlen(name); slash > name; )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Generated by "./mkutable -f2 Cf -- unicode/UnicodeData.txt" on Mon Nov 14 18:19:23 PST 2022 */
|
||||
/* Generated by "./mkutable -f2 Cf -- unicode/UnicodeData.txt" on Sun Sep 17 17:56:27 PDT 2023 */
|
||||
{ 0x00ad, 0x00ad }, /* Cf */
|
||||
{ 0x0600, 0x0605 }, /* Cf */
|
||||
{ 0x061c, 0x061c }, /* Cf */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -18,11 +18,11 @@
|
|||
|
||||
extern int less_is_more;
|
||||
|
||||
public int screen_trashed;
|
||||
public int squished;
|
||||
public lbool squished;
|
||||
public int no_back_scroll = 0;
|
||||
public int forw_prompt;
|
||||
public int first_time = 1;
|
||||
public lbool no_eof_bell = FALSE;
|
||||
|
||||
extern int sigs;
|
||||
extern int top_scroll;
|
||||
|
|
@ -30,17 +30,16 @@ extern int quiet;
|
|||
extern int sc_width, sc_height;
|
||||
extern int hshift;
|
||||
extern int auto_wrap;
|
||||
extern int plusoption;
|
||||
extern lbool plusoption;
|
||||
extern int forw_scroll;
|
||||
extern int back_scroll;
|
||||
extern int ignore_eoi;
|
||||
extern int clear_bg;
|
||||
extern int final_attr;
|
||||
extern int header_lines;
|
||||
extern int header_cols;
|
||||
extern int full_screen;
|
||||
extern POSITION header_start_pos;
|
||||
#if HILITE_SEARCH
|
||||
extern int size_linebuf;
|
||||
extern size_t size_linebuf;
|
||||
extern int hilite_search;
|
||||
extern int status_col;
|
||||
#endif
|
||||
|
|
@ -53,6 +52,8 @@ extern char *tagoption;
|
|||
*/
|
||||
public void eof_bell(void)
|
||||
{
|
||||
if (no_eof_bell)
|
||||
return;
|
||||
#if HAVE_TIME
|
||||
static time_type last_eof_bell = 0;
|
||||
time_type now = get_time();
|
||||
|
|
@ -69,19 +70,19 @@ public void eof_bell(void)
|
|||
/*
|
||||
* Check to see if the end of file is currently displayed.
|
||||
*/
|
||||
public int eof_displayed(void)
|
||||
public lbool eof_displayed(void)
|
||||
{
|
||||
POSITION pos;
|
||||
|
||||
if (ignore_eoi)
|
||||
return (0);
|
||||
return (FALSE);
|
||||
|
||||
if (ch_length() == NULL_POSITION)
|
||||
/*
|
||||
* If the file length is not known,
|
||||
* we can't possibly be displaying EOF.
|
||||
*/
|
||||
return (0);
|
||||
return (FALSE);
|
||||
|
||||
/*
|
||||
* If the bottom line is empty, we are at EOF.
|
||||
|
|
@ -95,13 +96,13 @@ public int eof_displayed(void)
|
|||
/*
|
||||
* Check to see if the entire file is currently displayed.
|
||||
*/
|
||||
public int entire_file_displayed(void)
|
||||
public lbool entire_file_displayed(void)
|
||||
{
|
||||
POSITION pos;
|
||||
|
||||
/* Make sure last line of file is displayed. */
|
||||
if (!eof_displayed())
|
||||
return (0);
|
||||
return (FALSE);
|
||||
|
||||
/* Make sure first line of file is displayed. */
|
||||
pos = position(0);
|
||||
|
|
@ -118,7 +119,7 @@ public void squish_check(void)
|
|||
{
|
||||
if (!squished)
|
||||
return;
|
||||
squished = 0;
|
||||
squished = FALSE;
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
|
@ -144,13 +145,13 @@ static POSITION forw_line_pfx(POSITION pos, int pfx, int skipeol)
|
|||
|
||||
/*
|
||||
* Set header text color.
|
||||
* Underline last line of headers, but not at beginning of file
|
||||
* Underline last line of headers, but not at header_start_pos
|
||||
* (where there is no gap between the last header line and the next line).
|
||||
*/
|
||||
static void set_attr_header(int ln)
|
||||
{
|
||||
set_attr_line(AT_COLOR_HEADER);
|
||||
if (ln+1 == header_lines && position(0) != ch_zero())
|
||||
if (ln+1 == header_lines && position(0) != header_start_pos)
|
||||
set_attr_line(AT_UNDERLINE);
|
||||
}
|
||||
|
||||
|
|
@ -160,13 +161,13 @@ static void set_attr_header(int ln)
|
|||
*/
|
||||
public int overlay_header(void)
|
||||
{
|
||||
POSITION pos = ch_zero(); /* header lines are at beginning of file */
|
||||
int ln;
|
||||
int moved = FALSE;
|
||||
lbool moved = FALSE;
|
||||
|
||||
if (header_lines > 0)
|
||||
{
|
||||
/* Draw header_lines lines from start of file at top of screen. */
|
||||
POSITION pos = header_start_pos;
|
||||
home();
|
||||
for (ln = 0; ln < header_lines; ++ln)
|
||||
{
|
||||
|
|
@ -180,8 +181,8 @@ public int overlay_header(void)
|
|||
if (header_cols > 0)
|
||||
{
|
||||
/* Draw header_cols columns at left of each line. */
|
||||
POSITION pos = header_start_pos;
|
||||
home();
|
||||
pos = ch_zero();
|
||||
for (ln = 0; ln < sc_height-1; ++ln)
|
||||
{
|
||||
if (ln >= header_lines) /* switch from header lines to normal lines */
|
||||
|
|
@ -212,11 +213,13 @@ public int overlay_header(void)
|
|||
* real line. If nblank > 0, the pos must be NULL_POSITION.
|
||||
* The first real line after the blanks will start at ch_zero().
|
||||
*/
|
||||
public void forw(int n, POSITION pos, int force, int only_last, int nblank)
|
||||
public void forw(int n, POSITION pos, lbool force, lbool only_last, int nblank)
|
||||
{
|
||||
int nlines = 0;
|
||||
int do_repaint;
|
||||
lbool do_repaint;
|
||||
|
||||
if (pos != NULL_POSITION)
|
||||
pos = after_header_pos(pos);
|
||||
squish_check();
|
||||
|
||||
/*
|
||||
|
|
@ -233,7 +236,7 @@ public void forw(int n, POSITION pos, int force, int only_last, int nblank)
|
|||
|
||||
#if HILITE_SEARCH
|
||||
if (pos != NULL_POSITION && (hilite_search == OPT_ONPLUS || is_filtering() || status_col)) {
|
||||
prep_hilite(pos, pos + 4*size_linebuf, ignore_eoi ? 1 : -1);
|
||||
prep_hilite(pos, pos + (POSITION) (4*size_linebuf), ignore_eoi ? 1 : -1);
|
||||
pos = next_unfiltered(pos);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -250,7 +253,7 @@ public void forw(int n, POSITION pos, int force, int only_last, int nblank)
|
|||
*/
|
||||
pos_clear();
|
||||
add_forw_pos(pos);
|
||||
force = 1;
|
||||
force = TRUE;
|
||||
if (less_is_more == 0) {
|
||||
clear();
|
||||
home();
|
||||
|
|
@ -266,7 +269,7 @@ public void forw(int n, POSITION pos, int force, int only_last, int nblank)
|
|||
*/
|
||||
pos_clear();
|
||||
add_forw_pos(pos);
|
||||
force = 1;
|
||||
force = TRUE;
|
||||
if (top_scroll)
|
||||
{
|
||||
clear();
|
||||
|
|
@ -344,7 +347,7 @@ public void forw(int n, POSITION pos, int force, int only_last, int nblank)
|
|||
#endif
|
||||
!plusoption)
|
||||
{
|
||||
squished = 1;
|
||||
squished = TRUE;
|
||||
continue;
|
||||
}
|
||||
put_line();
|
||||
|
|
@ -371,19 +374,6 @@ public void forw(int n, POSITION pos, int force, int only_last, int nblank)
|
|||
#endif
|
||||
forw_prompt = 1;
|
||||
}
|
||||
|
||||
if (header_lines > 0)
|
||||
{
|
||||
/*
|
||||
* Don't allow ch_zero to appear on screen except at top of screen.
|
||||
* Otherwise duplicate header lines may be displayed.
|
||||
*/
|
||||
if (onscreen(ch_zero()) > 0)
|
||||
{
|
||||
jump_loc(ch_zero(), 0); /* {{ yuck }} */
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (nlines == 0 && !ignore_eoi)
|
||||
eof_bell();
|
||||
else if (do_repaint)
|
||||
|
|
@ -400,16 +390,16 @@ public void forw(int n, POSITION pos, int force, int only_last, int nblank)
|
|||
/*
|
||||
* Display n lines, scrolling backward.
|
||||
*/
|
||||
public void back(int n, POSITION pos, int force, int only_last)
|
||||
public void back(int n, POSITION pos, lbool force, lbool only_last)
|
||||
{
|
||||
int nlines = 0;
|
||||
int do_repaint;
|
||||
lbool do_repaint;
|
||||
|
||||
squish_check();
|
||||
do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1) || header_lines > 0);
|
||||
#if HILITE_SEARCH
|
||||
if (pos != NULL_POSITION && (hilite_search == OPT_ONPLUS || is_filtering() || status_col)) {
|
||||
prep_hilite((pos < 3*size_linebuf) ? 0 : pos - 3*size_linebuf, pos, -1);
|
||||
prep_hilite((pos < (POSITION) (3*size_linebuf)) ? 0 : pos - (POSITION) (3*size_linebuf), pos, -1);
|
||||
}
|
||||
#endif
|
||||
while (--n >= 0)
|
||||
|
|
@ -420,7 +410,6 @@ public void back(int n, POSITION pos, int force, int only_last)
|
|||
#if HILITE_SEARCH
|
||||
pos = prev_unfiltered(pos);
|
||||
#endif
|
||||
|
||||
pos = back_line(pos);
|
||||
if (pos == NULL_POSITION)
|
||||
{
|
||||
|
|
@ -430,6 +419,13 @@ public void back(int n, POSITION pos, int force, int only_last)
|
|||
if (!force)
|
||||
break;
|
||||
}
|
||||
if (pos != after_header_pos(pos))
|
||||
{
|
||||
/*
|
||||
* Don't allow scrolling back to before the current header line.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Add the position of the previous line to the position table.
|
||||
* Display the line on the screen.
|
||||
|
|
@ -459,7 +455,7 @@ public void back(int n, POSITION pos, int force, int only_last)
|
|||
* Display n more lines, forward.
|
||||
* Start just after the line currently displayed at the bottom of the screen.
|
||||
*/
|
||||
public void forward(int n, int force, int only_last)
|
||||
public void forward(int n, lbool force, lbool only_last)
|
||||
{
|
||||
POSITION pos;
|
||||
|
||||
|
|
@ -507,7 +503,7 @@ public void forward(int n, int force, int only_last)
|
|||
* Display n more lines, backward.
|
||||
* Start just before the line currently displayed at the top of the screen.
|
||||
*/
|
||||
public void backward(int n, int force, int only_last)
|
||||
public void backward(int n, lbool force, lbool only_last)
|
||||
{
|
||||
POSITION pos;
|
||||
|
||||
|
|
@ -515,7 +511,7 @@ public void backward(int n, int force, int only_last)
|
|||
if (pos == NULL_POSITION && (!force || position(BOTTOM) == 0))
|
||||
{
|
||||
eof_bell();
|
||||
return;
|
||||
return;
|
||||
}
|
||||
back(n, pos, force, only_last);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
public char * saven(constant char *s, size_t n);
|
||||
public char * save(constant char *s);
|
||||
public void out_of_memory(void);
|
||||
public void * ecalloc(int count, unsigned int size);
|
||||
public void * ecalloc(size_t count, size_t size);
|
||||
public char * skipsp(char *s);
|
||||
public int sprefix(char *ps, char *s, int uppercase);
|
||||
public constant char * skipspc(constant char *s);
|
||||
public size_t sprefix(constant char *ps, constant char *s, int uppercase);
|
||||
public void quit(int status);
|
||||
public int secure_allow(int features);
|
||||
public void raw_mode(int on);
|
||||
public void scrsize(void);
|
||||
public char * special_key_str(int key);
|
||||
public void screen_size_changed(void);
|
||||
public constant char * special_key_str(int key);
|
||||
public void init_win_colors(void);
|
||||
public void get_term(void);
|
||||
public void init_mouse(void);
|
||||
public void deinit_mouse(void);
|
||||
|
|
@ -27,18 +31,19 @@ public void bell(void);
|
|||
public void clear(void);
|
||||
public void clear_eol(void);
|
||||
public void clear_bot(void);
|
||||
public COLOR_TYPE parse_color(char *str, int *p_fg, int *p_bg);
|
||||
public COLOR_TYPE parse_color(constant char *str, mutable int *p_fg, mutable int *p_bg, mutable CHAR_ATTR *p_cattr);
|
||||
public void at_enter(int attr);
|
||||
public void at_exit(void);
|
||||
public void at_switch(int attr);
|
||||
public int is_at_equiv(int attr1, int attr2);
|
||||
public lbool is_at_equiv(int attr1, int attr2);
|
||||
public int apply_at_specials(int attr);
|
||||
public void putbs(void);
|
||||
public int win32_kbhit(void);
|
||||
public char WIN32getch(void);
|
||||
public void WIN32ungetch(int ch);
|
||||
public lbool win32_kbhit(void);
|
||||
public char WIN32getch(void);
|
||||
public void win32_getch_clear(void);
|
||||
public void WIN32setcolors(int fg, int bg);
|
||||
public void WIN32textout(char *text, int len);
|
||||
public void WIN32textout(constant char *text, size_t len);
|
||||
public void match_brac(char obrac, char cbrac, int forwdir, int n);
|
||||
public void ch_ungetchar(int c);
|
||||
public void end_logfile(void);
|
||||
|
|
@ -51,73 +56,84 @@ public POSITION ch_length(void);
|
|||
public POSITION ch_tell(void);
|
||||
public int ch_forw_get(void);
|
||||
public int ch_back_get(void);
|
||||
public void ch_setbufspace(int bufspace);
|
||||
public void ch_setbufspace(ssize_t bufspace);
|
||||
public void ch_flush(void);
|
||||
public int seekable(int f);
|
||||
public void ch_set_eof(void);
|
||||
public void ch_init(int f, int flags);
|
||||
public void ch_init(int f, int flags, ssize_t nread);
|
||||
public void ch_close(void);
|
||||
public int ch_getflags(void);
|
||||
public void setfmt(char *s, char **fmtvarptr, int *attrptr, char *default_fmt, int for_printf);
|
||||
public void setfmt(constant char *s, constant char **fmtvarptr, int *attrptr, constant char *default_fmt, lbool for_printf);
|
||||
public void init_charset(void);
|
||||
public int binary_char(LWCHAR c);
|
||||
public int control_char(LWCHAR c);
|
||||
public char * prchar(LWCHAR c);
|
||||
public char * prutfchar(LWCHAR ch);
|
||||
public int utf_len(int ch);
|
||||
public int is_utf8_well_formed(char *ss, int slen);
|
||||
public void utf_skip_to_lead(char **pp, char *limit);
|
||||
public LWCHAR get_wchar(constant char *p);
|
||||
public void put_wchar(char **pp, LWCHAR ch);
|
||||
public lbool binary_char(LWCHAR c);
|
||||
public lbool control_char(LWCHAR c);
|
||||
public constant char * prchar(LWCHAR c);
|
||||
public constant char * prutfchar(LWCHAR ch);
|
||||
public int utf_len(char ch);
|
||||
public lbool is_utf8_well_formed(constant char *ss, int slen);
|
||||
public void utf_skip_to_lead(constant char **pp, constant char *limit);
|
||||
public LWCHAR get_wchar(constant char *sp);
|
||||
public void put_wchar(mutable char **pp, LWCHAR ch);
|
||||
public LWCHAR step_charc(constant char **pp, signed int dir, constant char *limit);
|
||||
public LWCHAR step_char(char **pp, signed int dir, constant char *limit);
|
||||
public int is_composing_char(LWCHAR ch);
|
||||
public int is_ubin_char(LWCHAR ch);
|
||||
public int is_wide_char(LWCHAR ch);
|
||||
public int is_combining_char(LWCHAR ch1, LWCHAR ch2);
|
||||
public lbool is_composing_char(LWCHAR ch);
|
||||
public lbool is_ubin_char(LWCHAR ch);
|
||||
public lbool is_wide_char(LWCHAR ch);
|
||||
public lbool is_combining_char(LWCHAR ch1, LWCHAR ch2);
|
||||
public void cmd_reset(void);
|
||||
public void clear_cmd(void);
|
||||
public void cmd_putstr(constant char *s);
|
||||
public int len_cmdbuf(void);
|
||||
public void cmd_repaint(constant char *old_cp);
|
||||
public void set_mlist(void *mlist, int cmdflags);
|
||||
public void cmd_addhist(struct mlist *mlist, constant char *cmd, int modified);
|
||||
public ssize_t save_updown_match(void);
|
||||
public void restore_updown_match(ssize_t udm);
|
||||
public void cmd_addhist(struct mlist *mlist, constant char *cmd, lbool modified);
|
||||
public void cmd_accept(void);
|
||||
public int cmd_char(int c);
|
||||
public LINENUM cmd_int(long *frac);
|
||||
public char * get_cmdbuf(void);
|
||||
public char * cmd_lastpattern(void);
|
||||
public int cmd_char(char c);
|
||||
public LINENUM cmd_int(mutable long *frac);
|
||||
public constant char * get_cmdbuf(void);
|
||||
public constant char * cmd_lastpattern(void);
|
||||
public void init_cmdhist(void);
|
||||
public void save_cmdhist(void);
|
||||
public int in_mca(void);
|
||||
public int norm_search_type(int st);
|
||||
public void screen_trashed_num(int trashed);
|
||||
public void screen_trashed(void);
|
||||
public int is_screen_trashed(void);
|
||||
public void dispversion(void);
|
||||
public int getcc(void);
|
||||
public void ungetcc(LWCHAR c);
|
||||
public void ungetcc_back(LWCHAR c);
|
||||
public void ungetsc(char *s);
|
||||
public LWCHAR peekcc(void);
|
||||
public void getcc_clear(void);
|
||||
public char getcc(void);
|
||||
public void ungetcc(char c);
|
||||
public void ungetcc_back(char c);
|
||||
public void ungetcc_end_command(void);
|
||||
public void ungetsc(constant char *s);
|
||||
public char peekcc(void);
|
||||
public void commands(void);
|
||||
public int cvt_length(int len, int ops);
|
||||
public int * cvt_alloc_chpos(int len);
|
||||
public void cvt_text(char *odst, char *osrc, int *chpos, int *lenp, int ops);
|
||||
public size_t cvt_length(size_t len, int ops);
|
||||
public int * cvt_alloc_chpos(size_t len);
|
||||
public void cvt_text(mutable char *odst, constant char *osrc, mutable int *chpos, mutable size_t *lenp, int ops);
|
||||
public void expand_cmd_tables(void);
|
||||
public void init_cmds(void);
|
||||
public void add_fcmd_table(char *buf, int len);
|
||||
public void add_ecmd_table(char *buf, int len);
|
||||
public int fcmd_decode(char *cmd, char **sp);
|
||||
public int ecmd_decode(char *cmd, char **sp);
|
||||
public char * lgetenv(char *var);
|
||||
public int isnullenv(char *s);
|
||||
public int lesskey(char *filename, int sysvar);
|
||||
public int lesskey_src(char *filename, int sysvar);
|
||||
public int add_hometable(int (*call_lesskey)(char *, int), char *envname, char *def_filename, int sysvar);
|
||||
public int editchar(int c, int flags);
|
||||
public void init_textlist(struct textlist *tlist, char *str);
|
||||
public char * forw_textlist(struct textlist *tlist, char *prev);
|
||||
public char * back_textlist(struct textlist *tlist, char *prev);
|
||||
public void add_fcmd_table(unsigned char *buf, size_t len);
|
||||
public void add_ecmd_table(unsigned char *buf, size_t len);
|
||||
public void add_uvar_table(unsigned char *buf, size_t len);
|
||||
public void add_sysvar_table(unsigned char *buf, size_t len);
|
||||
public int fcmd_decode(constant char *cmd, constant char **sp);
|
||||
public int ecmd_decode(constant char *cmd, constant char **sp);
|
||||
public constant char * lgetenv(constant char *var);
|
||||
public constant char * lgetenv_ext(constant char *var, unsigned char *env_buf, size_t env_buf_len);
|
||||
public lbool isnullenv(constant char *s);
|
||||
public int lesskey(constant char *filename, lbool sysvar);
|
||||
public int lesskey_src(constant char *filename, lbool sysvar);
|
||||
public int lesskey_content(constant char *content, lbool sysvar);
|
||||
public int editchar(char c, int flags);
|
||||
public void init_textlist(struct textlist *tlist, mutable char *str);
|
||||
public constant char * forw_textlist(struct textlist *tlist, constant char *prev);
|
||||
public constant char * back_textlist(struct textlist *tlist, constant char *prev);
|
||||
public void close_altpipe(IFILE ifile);
|
||||
public void check_altpipe_error(void);
|
||||
public int edit(char *filename);
|
||||
public int edit(constant char *filename);
|
||||
public int edit_ifile(IFILE ifile);
|
||||
public int edit_list(char *filelist);
|
||||
public int edit_first(void);
|
||||
|
|
@ -131,35 +147,38 @@ public void reedit_ifile(IFILE save_ifile);
|
|||
public void reopen_curr_ifile(void);
|
||||
public int edit_stdin(void);
|
||||
public void cat_file(void);
|
||||
public void use_logfile(char *filename);
|
||||
public char * shell_unquote(char *str);
|
||||
public char * get_meta_escape(void);
|
||||
public char * shell_quote(char *s);
|
||||
public char * dirfile(char *dirname, char *filename, int must_exist);
|
||||
public char * homefile(char *filename);
|
||||
public char * fexpand(char *s);
|
||||
public char * fcomplete(char *s);
|
||||
public int bin_file(int f);
|
||||
public char * lglob(char *filename);
|
||||
public int is_fake_pathname(char *path);
|
||||
public char * lrealpath(char *path);
|
||||
public char * open_altfile(char *filename, int *pf, void **pfd);
|
||||
public void close_altfile(char *altfilename, char *filename);
|
||||
public int is_dir(char *filename);
|
||||
public char * bad_file(char *filename);
|
||||
public void use_logfile(constant char *filename);
|
||||
public void expand_evars(mutable char *buf, size_t len, struct xbuffer *xbuf);
|
||||
public char * shell_unquote(constant char *str);
|
||||
public constant char * get_meta_escape(void);
|
||||
public char * shell_quoten(constant char *s, size_t slen);
|
||||
public char * shell_quote(constant char *s);
|
||||
public char * dirfile(constant char *dirname, constant char *filename, int must_exist);
|
||||
public char * homefile(constant char *filename);
|
||||
public char * fexpand(constant char *s);
|
||||
public char * fcomplete(constant char *s);
|
||||
public int bin_file(int f, ssize_t *n);
|
||||
public char * readfd(FILE *fd);
|
||||
public char * lglob(constant char *afilename);
|
||||
public lbool is_fake_pathname(constant char *path);
|
||||
public char * lrealpath(constant char *path);
|
||||
public char * open_altfile(constant char *filename, int *pf, void **pfd);
|
||||
public void close_altfile(constant char *altfilename, constant char *filename);
|
||||
public lbool is_dir(constant char *filename);
|
||||
public char * bad_file(constant char *filename);
|
||||
public POSITION filesize(int f);
|
||||
public int curr_ifile_changed(void);
|
||||
public char * shell_coption(void);
|
||||
public char * last_component(char *name);
|
||||
public lbool curr_ifile_changed(void);
|
||||
public constant char * shell_coption(void);
|
||||
public constant char * last_component(constant char *name);
|
||||
public void eof_bell(void);
|
||||
public int eof_displayed(void);
|
||||
public int entire_file_displayed(void);
|
||||
public lbool eof_displayed(void);
|
||||
public lbool entire_file_displayed(void);
|
||||
public void squish_check(void);
|
||||
public int overlay_header(void);
|
||||
public void forw(int n, POSITION pos, int force, int only_last, int nblank);
|
||||
public void back(int n, POSITION pos, int force, int only_last);
|
||||
public void forward(int n, int force, int only_last);
|
||||
public void backward(int n, int force, int only_last);
|
||||
public void forw(int n, POSITION pos, lbool force, lbool only_last, int nblank);
|
||||
public void back(int n, POSITION pos, lbool force, lbool only_last);
|
||||
public void forward(int n, lbool force, lbool only_last);
|
||||
public void backward(int n, lbool force, lbool only_last);
|
||||
public int get_back_scroll(void);
|
||||
public int get_one_screen(void);
|
||||
public void del_ifile(IFILE h);
|
||||
|
|
@ -167,9 +186,9 @@ public IFILE next_ifile(IFILE h);
|
|||
public IFILE prev_ifile(IFILE h);
|
||||
public IFILE getoff_ifile(IFILE ifile);
|
||||
public int nifile(void);
|
||||
public IFILE get_ifile(char *filename, IFILE prev);
|
||||
public char * get_filename(IFILE ifile);
|
||||
public char * get_real_filename(IFILE ifile);
|
||||
public IFILE get_ifile(constant char *filename, IFILE prev);
|
||||
public constant char * get_filename(IFILE ifile);
|
||||
public constant char * get_real_filename(IFILE ifile);
|
||||
public int get_index(IFILE ifile);
|
||||
public void store_pos(IFILE ifile, struct scrpos *scrpos);
|
||||
public void get_pos(IFILE ifile, struct scrpos *scrpos);
|
||||
|
|
@ -184,7 +203,7 @@ public void *get_altpipe(IFILE ifile);
|
|||
public void set_altfilename(IFILE ifile, char *altfilename);
|
||||
public char * get_altfilename(IFILE ifile);
|
||||
public void if_dump(void);
|
||||
public POSITION forw_line_seg(POSITION curr_pos, int skipeol, int rscroll, int nochop);
|
||||
public POSITION forw_line_seg(POSITION curr_pos, lbool skipeol, lbool rscroll, lbool nochop);
|
||||
public POSITION forw_line(POSITION curr_pos);
|
||||
public POSITION back_line(POSITION curr_pos);
|
||||
public void set_attnpos(POSITION pos);
|
||||
|
|
@ -194,9 +213,10 @@ public void jump_back(LINENUM linenum);
|
|||
public void repaint(void);
|
||||
public void jump_percent(int percent, long fraction);
|
||||
public void jump_line_loc(POSITION pos, int sline);
|
||||
public POSITION after_header_pos(POSITION pos);
|
||||
public void jump_loc(POSITION pos, int sline);
|
||||
public void init_line(void);
|
||||
public int is_ascii_char(LWCHAR ch);
|
||||
public lbool is_ascii_char(LWCHAR ch);
|
||||
public POSITION line_position(void);
|
||||
public void prewind(void);
|
||||
public void plinestart(POSITION pos);
|
||||
|
|
@ -205,26 +225,31 @@ public void pshift_all(void);
|
|||
public int pwidth(LWCHAR ch, int a, LWCHAR prev_ch, int prev_a);
|
||||
public void savec(void);
|
||||
public void loadc(void);
|
||||
public int is_ansi_end(LWCHAR ch);
|
||||
public int is_ansi_middle(LWCHAR ch);
|
||||
public void skip_ansi(struct ansi_state *pansi, char **pp, constant char *limit);
|
||||
public lbool is_ansi_end(LWCHAR ch);
|
||||
public lbool is_ansi_middle(LWCHAR ch);
|
||||
public void skip_ansi(struct ansi_state *pansi, constant char **pp, constant char *limit);
|
||||
public struct ansi_state * ansi_start(LWCHAR ch);
|
||||
public int ansi_step(struct ansi_state *pansi, LWCHAR ch);
|
||||
public ansi_state ansi_step(struct ansi_state *pansi, LWCHAR ch);
|
||||
public osc8_state ansi_osc8_state(struct ansi_state *pansi);
|
||||
public void ansi_done(struct ansi_state *pansi);
|
||||
public int pappend(int c, POSITION pos);
|
||||
public int pappend_b(char c, POSITION pos, lbool before_pendc);
|
||||
public int pappend(char c, POSITION pos);
|
||||
public int pflushmbc(void);
|
||||
public void pdone(int endline, int chopped, int forw);
|
||||
public int col_from_pos(POSITION linepos, POSITION spos, POSITION saved_pos, int saved_col);
|
||||
public POSITION pos_from_col(POSITION linepos, int col, POSITION saved_pos, int saved_col);
|
||||
public void set_attr_line(int a);
|
||||
public void set_status_col(char c, int attr);
|
||||
public int gline(int i, int *ap);
|
||||
public int gline(size_t i, int *ap);
|
||||
public void null_line(void);
|
||||
public POSITION forw_raw_line(POSITION curr_pos, char **linep, int *line_lenp);
|
||||
public POSITION back_raw_line(POSITION curr_pos, char **linep, int *line_lenp);
|
||||
public int skip_columns(int cols, char **linep, int *line_lenp);
|
||||
public POSITION forw_raw_line_len(POSITION curr_pos, size_t read_len, constant char **linep, size_t *line_lenp);
|
||||
public POSITION forw_raw_line(POSITION curr_pos, constant char **linep, size_t *line_lenp);
|
||||
public POSITION back_raw_line(POSITION curr_pos, constant char **linep, size_t *line_lenp);
|
||||
public int skip_columns(int cols, constant char **linep, size_t *line_lenp);
|
||||
public void load_line(constant char *str);
|
||||
public int rrshift(void);
|
||||
public int set_color_map(int attr, char *colorstr);
|
||||
public char * get_color_map(int attr);
|
||||
public int set_color_map(int attr, constant char *colorstr);
|
||||
public constant char * get_color_map(int attr);
|
||||
public void clr_linenum(void);
|
||||
public void add_lnum(LINENUM linenum, POSITION pos);
|
||||
public LINENUM find_linenum(POSITION pos);
|
||||
|
|
@ -232,75 +257,85 @@ public POSITION find_pos(LINENUM linenum);
|
|||
public LINENUM currline(int where);
|
||||
public void scan_eof(void);
|
||||
public LINENUM vlinenum(LINENUM linenum);
|
||||
public void lsystem(char *cmd, char *donemsg);
|
||||
public int pipe_mark(int c, char *cmd);
|
||||
public int pipe_data(char *cmd, POSITION spos, POSITION epos);
|
||||
public void lsystem(constant char *cmd, constant char *donemsg);
|
||||
public int pipe_mark(char c, constant char *cmd);
|
||||
public int pipe_data(constant char *cmd, POSITION spos, POSITION epos);
|
||||
public void init_mark(void);
|
||||
public int badmark(LWCHAR c);
|
||||
public void setmark(LWCHAR c, int where);
|
||||
public void clrmark(LWCHAR c);
|
||||
public int badmark(char c);
|
||||
public void setmark(char c, int where);
|
||||
public void clrmark(char c);
|
||||
public void lastmark(void);
|
||||
public void gomark(LWCHAR c);
|
||||
public POSITION markpos(LWCHAR c);
|
||||
public void gomark(char c);
|
||||
public POSITION markpos(char c);
|
||||
public char posmark(POSITION pos);
|
||||
public void unmark(IFILE ifile);
|
||||
public void mark_check_ifile(IFILE ifile);
|
||||
public void save_marks(FILE *fout, char *hdr);
|
||||
public void restore_mark(char *line);
|
||||
public void opt_o(int type, char *s);
|
||||
public void opt__O(int type, char *s);
|
||||
public void opt_j(int type, char *s);
|
||||
public void save_marks(FILE *fout, constant char *hdr);
|
||||
public void restore_mark(constant char *line);
|
||||
public void opt_o(int type, constant char *s);
|
||||
public void opt__O(int type, constant char *s);
|
||||
public void opt_j(int type, constant char *s);
|
||||
public void calc_jump_sline(void);
|
||||
public void opt_shift(int type, char *s);
|
||||
public void opt_shift(int type, constant char *s);
|
||||
public void calc_shift_count(void);
|
||||
public void opt_k(int type, char *s);
|
||||
public void opt_ks(int type, char *s);
|
||||
public void opt_t(int type, char *s);
|
||||
public void opt__T(int type, char *s);
|
||||
public void opt_p(int type, char *s);
|
||||
public void opt__P(int type, char *s);
|
||||
public void opt_b(int type, char *s);
|
||||
public void opt_i(int type, char *s);
|
||||
public void opt__V(int type, char *s);
|
||||
public void opt_D(int type, char *s);
|
||||
public void set_tabs(char *s, int len);
|
||||
public void opt_x(int type, char *s);
|
||||
public void opt_quote(int type, char *s);
|
||||
public void opt_rscroll(int type, char *s);
|
||||
public void opt_query(int type, char *s);
|
||||
public void opt_mousecap(int type, char *s);
|
||||
public void opt_wheel_lines(int type, char *s);
|
||||
public void opt_linenum_width(int type, char *s);
|
||||
public void opt_status_col_width(int type, char *s);
|
||||
public void opt_filesize(int type, char *s);
|
||||
public void opt_intr(int type, char *s);
|
||||
public void opt_header(int type, char *s);
|
||||
public void opt_search_type(int type, char *s);
|
||||
public void opt_ttyin_name(int type, char *s);
|
||||
public void opt_k(int type, constant char *s);
|
||||
public void opt_ks(int type, constant char *s);
|
||||
public void opt_kc(int type, constant char *s);
|
||||
public void opt__S(int type, constant char *s);
|
||||
public void opt_t(int type, constant char *s);
|
||||
public void opt__T(int type, constant char *s);
|
||||
public void opt_p(int type, constant char *s);
|
||||
public void opt__P(int type, constant char *s);
|
||||
public void opt_b(int type, constant char *s);
|
||||
public void opt_i(int type, constant char *s);
|
||||
public void opt__V(int type, constant char *s);
|
||||
public void opt_D(int type, constant char *s);
|
||||
public void set_tabs(constant char *s, size_t len);
|
||||
public void opt_x(int type, constant char *s);
|
||||
public void opt_quote(int type, constant char *s);
|
||||
public void opt_rscroll(int type, constant char *s);
|
||||
public void opt_query(int type, constant char *s);
|
||||
public void opt_match_shift(int type, constant char *s);
|
||||
public void calc_match_shift(void);
|
||||
public void opt_mousecap(int type, constant char *s);
|
||||
public void opt_wheel_lines(int type, constant char *s);
|
||||
public void opt_linenum_width(int type, constant char *s);
|
||||
public void opt_status_col_width(int type, constant char *s);
|
||||
public void opt_filesize(int type, constant char *s);
|
||||
public void opt_intr(int type, constant char *s);
|
||||
public int next_cnum(constant char **sp, constant char *printopt, constant char *errmsg, lbool *errp);
|
||||
public void opt_header(int type, constant char *s);
|
||||
public void opt_search_type(int type, constant char *s);
|
||||
public void opt_nosearch_headers(int type, constant char *s);
|
||||
public void opt_nosearch_header_lines(int type, constant char *s);
|
||||
public void opt_nosearch_header_cols(int type, constant char *s);
|
||||
public void opt_ttyin_name(int type, constant char *s);
|
||||
public int chop_line(void);
|
||||
public int get_swindow(void);
|
||||
public char * propt(int c);
|
||||
public void scan_option(char *s);
|
||||
public void toggle_option(struct loption *o, int lower, char *s, int how_toggle);
|
||||
public constant char * propt(char c);
|
||||
public void scan_option(constant char *s);
|
||||
public void toggle_option(struct loption *o, int lower, constant char *s, int how_toggle);
|
||||
public int opt_has_param(struct loption *o);
|
||||
public char * opt_prompt(struct loption *o);
|
||||
public char * opt_toggle_disallowed(int c);
|
||||
public int isoptpending(void);
|
||||
public constant char * opt_prompt(struct loption *o);
|
||||
public constant char * opt_toggle_disallowed(int c);
|
||||
public lbool isoptpending(void);
|
||||
public void nopendopt(void);
|
||||
public int getnum(char **sp, char *printopt, int *errp);
|
||||
public long getfraction(char **sp, char *printopt, int *errp);
|
||||
public int getnumc(constant char **sp, constant char *printopt, lbool *errp);
|
||||
public int getnum(char **sp, constant char *printopt, lbool *errp);
|
||||
public long getfraction(constant char **sp, constant char *printopt, lbool *errp);
|
||||
public void init_unsupport(void);
|
||||
public int get_quit_at_eof(void);
|
||||
public void init_option(void);
|
||||
public struct loption * findopt(int c);
|
||||
public struct loption * findopt_name(char **p_optname, char **p_oname, int *p_err);
|
||||
public struct loption * findopt_name(constant char **p_optname, constant char **p_oname, lbool *p_ambig);
|
||||
public void init_poll(void);
|
||||
public int supports_ctrl_x(void);
|
||||
public int iread(int fd, unsigned char *buf, unsigned int len);
|
||||
public ssize_t iread(int fd, unsigned char *buf, size_t len);
|
||||
public void intread(void);
|
||||
public time_type get_time(void);
|
||||
public char * errno_message(char *filename);
|
||||
public char * signal_message(int sig);
|
||||
public uintmax muldiv(uintmax val, uintmax num, uintmax den);
|
||||
public char * errno_message(constant char *filename);
|
||||
public constant char * signal_message(int sig);
|
||||
public uintmax umuldiv(uintmax val, uintmax num, uintmax den);
|
||||
public int percentage(POSITION num, POSITION den);
|
||||
public POSITION percent_pos(POSITION pos, int percent, long fraction);
|
||||
public int os9_signal(int type, RETSIGTYPE (*handler)());
|
||||
|
|
@ -308,21 +343,21 @@ public void sleep_ms(int ms);
|
|||
public void put_line(void);
|
||||
public void flush(void);
|
||||
public void set_output(int fd);
|
||||
public int putchr(int c);
|
||||
public int putchr(int ch);
|
||||
public void clear_bot_if_needed(void);
|
||||
public void putstr(constant char *s);
|
||||
public int less_printf(char *fmt, PARG *parg);
|
||||
public int less_printf(constant char *fmt, PARG *parg);
|
||||
public void get_return(void);
|
||||
public void error(char *fmt, PARG *parg);
|
||||
public void ierror(char *fmt, PARG *parg);
|
||||
public void ixerror(char *fmt, PARG *parg);
|
||||
public int query(char *fmt, PARG *parg);
|
||||
public int compile_pattern(char *pattern, int search_type, int show_error, PATTERN_TYPE *comp_pattern);
|
||||
public void error(constant char *fmt, PARG *parg);
|
||||
public void ierror(constant char *fmt, PARG *parg);
|
||||
public void ixerror(constant char *fmt, PARG *parg);
|
||||
public int query(constant char *fmt, PARG *parg);
|
||||
public int compile_pattern(constant char *pattern, int search_type, int show_error, PATTERN_TYPE *comp_pattern);
|
||||
public void uncompile_pattern(PATTERN_TYPE *pattern);
|
||||
public int valid_pattern(char *pattern);
|
||||
public int is_null_pattern(PATTERN_TYPE pattern);
|
||||
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 char * pattern_lib_name(void);
|
||||
public lbool is_null_pattern(PATTERN_TYPE pattern);
|
||||
public int match_pattern(PATTERN_TYPE pattern, constant char *tpattern, constant char *line, size_t line_len, constant char **sp, constant char **ep, int nsp, int notbol, int search_type);
|
||||
public constant char * pattern_lib_name(void);
|
||||
public POSITION position(int sindex);
|
||||
public void add_forw_pos(POSITION pos);
|
||||
public void add_back_pos(POSITION pos);
|
||||
|
|
@ -333,40 +368,48 @@ public int empty_screen(void);
|
|||
public int empty_lines(int s, int e);
|
||||
public void get_scrpos(struct scrpos *scrpos, int where);
|
||||
public int sindex_from_sline(int sline);
|
||||
public void pos_rehead(void);
|
||||
public void init_prompt(void);
|
||||
public char * pr_expand(constant char *proto);
|
||||
public char * eq_message(void);
|
||||
public char * pr_string(void);
|
||||
public char * wait_message(void);
|
||||
public constant char * pr_expand(constant char *proto);
|
||||
public constant char * eq_message(void);
|
||||
public constant char * pr_string(void);
|
||||
public constant char * wait_message(void);
|
||||
public void init_search(void);
|
||||
public void repaint_hilite(int on);
|
||||
public int get_cvt_ops(int search_type);
|
||||
public void repaint_hilite(lbool on);
|
||||
public void clear_attn(void);
|
||||
public void undo_search(int clear);
|
||||
public void undo_search(lbool clear);
|
||||
public void clr_hlist(struct hilite_tree *anchor);
|
||||
public void clr_hilite(void);
|
||||
public void clr_filter(void);
|
||||
public int is_filtered(POSITION pos);
|
||||
public void set_header(POSITION pos);
|
||||
public lbool is_filtered(POSITION pos);
|
||||
public POSITION next_unfiltered(POSITION pos);
|
||||
public POSITION prev_unfiltered(POSITION pos);
|
||||
public int is_hilited_attr(POSITION pos, POSITION epos, int nohide, int *p_matches);
|
||||
public void chg_hilite(void);
|
||||
public void osc8_search(int search_type, constant char *param, int matches);
|
||||
public lbool osc8_click(int sindex, int col);
|
||||
public void osc8_open(void);
|
||||
public void osc8_jump(void);
|
||||
public void chg_caseless(void);
|
||||
public int search(int search_type, char *pattern, int n);
|
||||
public int search(int search_type, constant char *pattern, int n);
|
||||
public void prep_hilite(POSITION spos, POSITION epos, int maxlines);
|
||||
public void set_filter_pattern(char *pattern, int search_type);
|
||||
public int is_filtering(void);
|
||||
public void set_filter_pattern(constant char *pattern, int search_type);
|
||||
public lbool is_filtering(void);
|
||||
public RETSIGTYPE winch(int type);
|
||||
public void init_signals(int on);
|
||||
public void psignals(void);
|
||||
public void cleantags(void);
|
||||
public int gettagtype(void);
|
||||
public void findtag(char *tag);
|
||||
public void findtag(constant char *tag);
|
||||
public POSITION tagsearch(void);
|
||||
public char * nexttag(int n);
|
||||
public char * prevtag(int n);
|
||||
public constant char * nexttag(int n);
|
||||
public constant char * prevtag(int n);
|
||||
public int ntags(void);
|
||||
public int curr_tag(void);
|
||||
public int edit_tagfile(void);
|
||||
public lbool is_lesstest(void);
|
||||
public int open_tty(void);
|
||||
public void open_getchr(void);
|
||||
public void close_getchr(void);
|
||||
|
|
@ -374,12 +417,14 @@ 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_init_size(struct xbuffer *xbuf, size_t init_size);
|
||||
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 void xbuf_add_char(struct xbuffer *xbuf, char c);
|
||||
public void xbuf_add_data(struct xbuffer *xbuf, constant unsigned char *data, size_t 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);
|
||||
public constant char * xbuf_char_data(constant struct xbuffer *xbuf);
|
||||
public lbool help_ckd_add(void *r, uintmax a, uintmax b, int rsize, int rsigned);
|
||||
public lbool help_ckd_mul(void *r, uintmax a, uintmax b, int rsize, int rsigned);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* This file was generated by mkhelp.pl from less.hlp at 22:43 on 2023/7/20 */
|
||||
/* This file was generated by mkhelp.pl from less.hlp at 22:29 on 2024/10/6 */
|
||||
#include "less.h"
|
||||
constant char helpdata[] = {
|
||||
'\n',
|
||||
|
|
@ -44,6 +44,9 @@ constant char helpdata[] = {
|
|||
' ',' ','N',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',' ','i','n',' ','r','e','v','e','r','s','e',' ','d','i','r','e','c','t','i','o','n','.','\n',
|
||||
' ',' ','E','S','C','-','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',',',' ','s','p','a','n','n','i','n','g',' ','f','i','l','e','s','.','\n',
|
||||
' ',' ','E','S','C','-','N',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',',',' ','r','e','v','e','r','s','e',' ','d','i','r','.',' ','&',' ','s','p','a','n','n','i','n','g',' ','f','i','l','e','s','.','\n',
|
||||
' ',' ','^','O','^','N',' ',' ','^','O','n',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','S','e','a','r','c','h',' ','f','o','r','w','a','r','d',' ','f','o','r',' ','(','_','\b','N','-','t','h',')',' ','O','S','C','8',' ','h','y','p','e','r','l','i','n','k','.','\n',
|
||||
' ',' ','^','O','^','P',' ',' ','^','O','p',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','S','e','a','r','c','h',' ','b','a','c','k','w','a','r','d',' ','f','o','r',' ','(','_','\b','N','-','t','h',')',' ','O','S','C','8',' ','h','y','p','e','r','l','i','n','k','.','\n',
|
||||
' ',' ','^','O','^','L',' ',' ','^','O','l',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','J','u','m','p',' ','t','o',' ','t','h','e',' ','c','u','r','r','e','n','t','l','y',' ','s','e','l','e','c','t','e','d',' ','O','S','C','8',' ','h','y','p','e','r','l','i','n','k','.','\n',
|
||||
' ',' ','E','S','C','-','u',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','n','d','o',' ','(','t','o','g','g','l','e',')',' ','s','e','a','r','c','h',' ','h','i','g','h','l','i','g','h','t','i','n','g','.','\n',
|
||||
' ',' ','E','S','C','-','U',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','l','e','a','r',' ','s','e','a','r','c','h',' ','h','i','g','h','l','i','g','h','t','i','n','g','.','\n',
|
||||
' ',' ','&','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','D','i','s','p','l','a','y',' ','o','n','l','y',' ','m','a','t','c','h','i','n','g',' ','l','i','n','e','s','.','\n',
|
||||
|
|
@ -56,6 +59,7 @@ constant char helpdata[] = {
|
|||
' ',' ',' ',' ',' ',' ',' ',' ','^','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',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ','^','L',' ',' ',' ',' ',' ',' ',' ','E','n','t','e','r',' ','n','e','x','t',' ','c','h','a','r','a','c','t','e','r',' ','l','i','t','e','r','a','l','l','y',' ','i','n','t','o',' ','p','a','t','t','e','r','n','.','\n',
|
||||
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
|
||||
'\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','J','\b','J','U','\b','U','M','\b','M','P','\b','P','I','\b','I','N','\b','N','G','\b','G','\n',
|
||||
|
|
@ -95,6 +99,7 @@ constant char helpdata[] = {
|
|||
' ',' ',':','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','E','x','a','m','i','n','e',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','n','e','x','t',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n',
|
||||
' ',' ',':','p',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','E','x','a','m','i','n','e',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','p','r','e','v','i','o','u','s',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n',
|
||||
' ',' ',':','x',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','E','x','a','m','i','n','e',' ','t','h','e',' ','f','i','r','s','t',' ','(','o','r',' ','_','\b','N','-','t','h',')',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n',
|
||||
' ',' ','^','O','^','O',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','O','p','e','n',' ','t','h','e',' ','c','u','r','r','e','n','t','l','y',' ','s','e','l','e','c','t','e','d',' ','O','S','C','8',' ','h','y','p','e','r','l','i','n','k','.','\n',
|
||||
' ',' ',':','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e',' ','l','i','s','t','.','\n',
|
||||
' ',' ','=',' ',' ','^','G',' ',' ',':','f',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','r','i','n','t',' ','c','u','r','r','e','n','t',' ','f','i','l','e',' ','n','a','m','e','.','\n',
|
||||
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
|
||||
|
|
@ -158,8 +163,8 @@ constant char helpdata[] = {
|
|||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','c','r','e','e','n',' ','p','o','s','i','t','i','o','n',' ','o','f',' ','t','a','r','g','e','t',' ','l','i','n','e','s','.','\n',
|
||||
' ',' ','-','J',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','s','t','a','t','u','s','-','c','o','l','u','m','n','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','a',' ','s','t','a','t','u','s',' ','c','o','l','u','m','n',' ','a','t',' ','l','e','f','t',' ','e','d','g','e',' ','o','f',' ','s','c','r','e','e','n','.','\n',
|
||||
' ',' ','-','k',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','l','e','s','s','k','e','y','-','f','i','l','e','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','a',' ','l','e','s','s','k','e','y',' ','f','i','l','e','.','\n',
|
||||
' ',' ','-','k',' ','_','\b','f','_','\b','i','_','\b','l','_','\b','e',' ',' ','.','.','.',' ',' ','-','-','l','e','s','s','k','e','y','-','f','i','l','e','=','_','\b','f','_','\b','i','_','\b','l','_','\b','e','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','a',' ','c','o','m','p','i','l','e','d',' ','l','e','s','s','k','e','y',' ','f','i','l','e','.','\n',
|
||||
' ',' ','-','K',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','q','u','i','t','-','o','n','-','i','n','t','r','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','i','t',' ','l','e','s','s',' ','i','n',' ','r','e','s','p','o','n','s','e',' ','t','o',' ','c','t','r','l','-','C','.','\n',
|
||||
' ',' ','-','L',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','n','o','-','l','e','s','s','o','p','e','n','\n',
|
||||
|
|
@ -170,11 +175,11 @@ constant char helpdata[] = {
|
|||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','u','p','p','r','e','s','s',' ','l','i','n','e',' ','n','u','m','b','e','r','s',' ','i','n',' ','p','r','o','m','p','t','s',' ','a','n','d',' ','m','e','s','s','a','g','e','s','.','\n',
|
||||
' ',' ','-','N',' ','.','.','.','.','.','.','.','.','.',' ',' ','-','-','L','I','N','E','-','N','U','M','B','E','R','S','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','l','i','n','e',' ','n','u','m','b','e','r',' ','a','t',' ','s','t','a','r','t',' ','o','f',' ','e','a','c','h',' ','l','i','n','e','.','\n',
|
||||
' ',' ','-','o',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','l','o','g','-','f','i','l','e','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
|
||||
' ',' ','-','o',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ','.','.',' ',' ','-','-','l','o','g','-','f','i','l','e','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','o','p','y',' ','t','o',' ','l','o','g',' ','f','i','l','e',' ','(','s','t','a','n','d','a','r','d',' ','i','n','p','u','t',' ','o','n','l','y',')','.','\n',
|
||||
' ',' ','-','O',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','L','O','G','-','F','I','L','E','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
|
||||
' ',' ','-','O',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ','.','.',' ',' ','-','-','L','O','G','-','F','I','L','E','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','o','p','y',' ','t','o',' ','l','o','g',' ','f','i','l','e',' ','(','u','n','c','o','n','d','i','t','i','o','n','a','l','l','y',' ','o','v','e','r','w','r','i','t','e',')','.','\n',
|
||||
' ',' ','-','p',' ','[','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',']',' ',' ','-','-','p','a','t','t','e','r','n','=','[','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',']','\n',
|
||||
' ',' ','-','p',' ','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',' ','.',' ',' ','-','-','p','a','t','t','e','r','n','=','[','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','t','a','r','t',' ','a','t',' ','p','a','t','t','e','r','n',' ','(','f','r','o','m',' ','c','o','m','m','a','n','d',' ','l','i','n','e',')','.','\n',
|
||||
' ',' ','-','P',' ','[','_','\b','p','_','\b','r','_','\b','o','_','\b','m','_','\b','p','_','\b','t',']',' ',' ',' ','-','-','p','r','o','m','p','t','=','[','_','\b','p','_','\b','r','_','\b','o','_','\b','m','_','\b','p','_','\b','t',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','f','i','n','e',' ','n','e','w',' ','p','r','o','m','p','t','.','\n',
|
||||
|
|
@ -186,7 +191,7 @@ constant char helpdata[] = {
|
|||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','q','u','e','e','z','e',' ','m','u','l','t','i','p','l','e',' ','b','l','a','n','k',' ','l','i','n','e','s','.','\n',
|
||||
' ',' ','-','S',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','c','h','o','p','-','l','o','n','g','-','l','i','n','e','s','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','h','o','p',' ','(','t','r','u','n','c','a','t','e',')',' ','l','o','n','g',' ','l','i','n','e','s',' ','r','a','t','h','e','r',' ','t','h','a','n',' ','w','r','a','p','p','i','n','g','.','\n',
|
||||
' ',' ','-','t',' ','[','_','\b','t','_','\b','a','_','\b','g',']',' ',' ','.','.',' ',' ','-','-','t','a','g','=','[','_','\b','t','_','\b','a','_','\b','g',']','\n',
|
||||
' ',' ','-','t',' ','_','\b','t','_','\b','a','_','\b','g',' ',' ','.','.','.','.',' ',' ','-','-','t','a','g','=','[','_','\b','t','_','\b','a','_','\b','g',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','i','n','d',' ','a',' ','t','a','g','.','\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',
|
||||
|
|
@ -212,21 +217,28 @@ 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',
|
||||
' ',' ','-','#',' ','[','_','\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',
|
||||
'\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',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','A','u','t','o','m','a','t','i','c','a','l','l','y',' ','d','e','t','e','r','m','i','n','e',' ','t','h','e',' ','s','i','z','e',' ','o','f',' ','t','h','e',' ','i','n','p','u','t',' ','f','i','l','e','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','f','o','l','l','o','w','-','n','a','m','e','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','h','e',' ','F',' ','c','o','m','m','a','n','d',' ','c','h','a','n','g','e','s',' ','f','i','l','e','s',' ','i','f',' ','t','h','e',' ','i','n','p','u','t',' ','f','i','l','e',' ','i','s',' ','r','e','n','a','m','e','d','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','h','e','a','d','e','r','=','[','_','\b','N','[',',','_','\b','M',']',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','N',' ','l','i','n','e','s',' ','a','n','d',' ','M',' ','c','o','l','u','m','n','s',' ','t','o',' ','d','i','s','p','l','a','y',' ','f','i','l','e',' ','h','e','a','d','e','r','s','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','h','e','a','d','e','r','=','[','_','\b','L','[',',','_','\b','C','[',',','_','\b','N',']',']',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','_','\b','L',' ','l','i','n','e','s',' ','(','s','t','a','r','t','i','n','g',' ','a','t',' ','l','i','n','e',' ','_','\b','N',')',' ','a','n','d',' ','_','\b','C',' ','c','o','l','u','m','n','s',' ','a','s',' ','h','e','a','d','e','r','s','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','i','n','c','s','e','a','r','c','h','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','a','r','c','h',' ','f','i','l','e',' ','a','s',' ','e','a','c','h',' ','p','a','t','t','e','r','n',' ','c','h','a','r','a','c','t','e','r',' ','i','s',' ','t','y','p','e','d',' ','i','n','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','i','n','t','r','=','_','\b','C','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','i','n','t','r','=','[','_','\b','C',']','\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',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','l','e','s','s','k','e','y','-','c','o','n','t','e','x','t','=','_','\b','t','_','\b','e','_','\b','x','_','\b','t','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','l','e','s','s','k','e','y',' ','s','o','u','r','c','e',' ','f','i','l','e',' ','c','o','n','t','e','n','t','s','.','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','l','e','s','s','k','e','y','-','s','r','c','=','_','\b','f','_','\b','i','_','\b','l','_','\b','e','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','a',' ','l','e','s','s','k','e','y',' ','s','o','u','r','c','e',' ','f','i','l','e','.','\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',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','m','a','t','c','h','-','s','h','i','f','t','=','[','_','\b','N',']','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','h','o','w',' ','a','t',' ','l','e','a','s','t',' ','_','\b','N',' ','c','h','a','r','a','c','t','e','r','s',' ','t','o',' ','t','h','e',' ','l','e','f','t',' ','o','f',' ','a',' ','s','e','a','r','c','h',' ','m','a','t','c','h','.','\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',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','n','a','b','l','e',' ','m','o','u','s','e',' ','i','n','p','u','t','.','\n',
|
||||
|
|
@ -236,13 +248,17 @@ 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',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','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',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','s','e','a','r','c','h','-','h','e','a','d','e','r','-','l','i','n','e','s','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','a','r','c','h','e','s',' ','d','o',' ','n','o','t',' ','i','n','c','l','u','d','e',' ','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','-','c','o','l','u','m','n','s','\n',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','a','r','c','h','e','s',' ','d','o',' ','n','o','t',' ','i','n','c','l','u','d','e',' ','h','e','a','d','e','r',' ','c','o','l','u','m','n','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',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','a','r','c','h','e','s',' ','d','o',' ','n','o','t',' ','i','n','c','l','u','d','e',' ','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',' ','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','=','_','\b','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','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',
|
||||
|
|
@ -252,17 +268,17 @@ constant char helpdata[] = {
|
|||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','P','R','O','C','-','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',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','P','R','O','C','-','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',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','P','R','O','C','-','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','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',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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',
|
||||
|
|
@ -270,7 +286,7 @@ constant char helpdata[] = {
|
|||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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','=','_','\b','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',' ','_','\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',
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -48,7 +48,7 @@ struct ifile {
|
|||
* Anchor for linked list.
|
||||
*/
|
||||
static struct ifile anchor = { &anchor, &anchor, NULL, NULL, NULL, 0, 0, '\0',
|
||||
{ NULL_POSITION, 0 } };
|
||||
{ NULL_POSITION, 0 }, NULL, NULL };
|
||||
static int ifiles = 0;
|
||||
|
||||
static void incr_index(struct ifile *p, int incr)
|
||||
|
|
@ -97,7 +97,7 @@ static void unlink_ifile(struct ifile *p)
|
|||
* (or at the beginning of the list if "prev" is NULL).
|
||||
* Return a pointer to the new ifile structure.
|
||||
*/
|
||||
static struct ifile * new_ifile(char *filename, struct ifile *prev)
|
||||
static struct ifile * new_ifile(constant char *filename, struct ifile *prev)
|
||||
{
|
||||
struct ifile *p;
|
||||
|
||||
|
|
@ -197,7 +197,7 @@ public int nifile(void)
|
|||
/*
|
||||
* Find an ifile structure, given a filename.
|
||||
*/
|
||||
static struct ifile * find_ifile(char *filename)
|
||||
static struct ifile * find_ifile(constant char *filename)
|
||||
{
|
||||
struct ifile *p;
|
||||
char *rfilename = lrealpath(filename);
|
||||
|
|
@ -229,7 +229,7 @@ static struct ifile * find_ifile(char *filename)
|
|||
* If the filename has not been seen before,
|
||||
* insert the new ifile after "prev" in the list.
|
||||
*/
|
||||
public IFILE get_ifile(char *filename, IFILE prev)
|
||||
public IFILE get_ifile(constant char *filename, IFILE prev)
|
||||
{
|
||||
struct ifile *p;
|
||||
|
||||
|
|
@ -241,7 +241,7 @@ public IFILE get_ifile(char *filename, IFILE prev)
|
|||
/*
|
||||
* Get the display filename associated with a ifile.
|
||||
*/
|
||||
public char * get_filename(IFILE ifile)
|
||||
public constant char * get_filename(IFILE ifile)
|
||||
{
|
||||
if (ifile == NULL)
|
||||
return (NULL);
|
||||
|
|
@ -251,7 +251,7 @@ public char * get_filename(IFILE ifile)
|
|||
/*
|
||||
* Get the canonical filename associated with a ifile.
|
||||
*/
|
||||
public char * get_real_filename(IFILE ifile)
|
||||
public constant char * get_real_filename(IFILE ifile)
|
||||
{
|
||||
if (ifile == NULL)
|
||||
return (NULL);
|
||||
|
|
@ -337,6 +337,10 @@ public void set_altfilename(IFILE ifile, char *altfilename)
|
|||
p->h_altfilename = altfilename;
|
||||
}
|
||||
|
||||
/*
|
||||
* Not constant; caller can free altfilename.
|
||||
* {{ This is poor design and should be changed. }}
|
||||
*/
|
||||
public char * get_altfilename(IFILE ifile)
|
||||
{
|
||||
return (int_ifile(ifile)->h_altfilename);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -22,7 +22,6 @@
|
|||
extern int squeeze;
|
||||
extern int hshift;
|
||||
extern int quit_if_one_screen;
|
||||
extern int sigs;
|
||||
extern int ignore_eoi;
|
||||
extern int status_col;
|
||||
extern int wordwrap;
|
||||
|
|
@ -30,7 +29,7 @@ extern POSITION start_attnpos;
|
|||
extern POSITION end_attnpos;
|
||||
#if HILITE_SEARCH
|
||||
extern int hilite_search;
|
||||
extern int size_linebuf;
|
||||
extern size_t size_linebuf;
|
||||
extern int show_attn;
|
||||
#endif
|
||||
|
||||
|
|
@ -47,7 +46,7 @@ static void init_status_col(POSITION base_pos, POSITION disp_pos, POSITION edisp
|
|||
{
|
||||
int hl_before = (chop_line() && disp_pos != NULL_POSITION) ?
|
||||
is_hilited_attr(base_pos, disp_pos, TRUE, NULL) : 0;
|
||||
int hl_after = (chop_line()) ?
|
||||
int hl_after = (chop_line() && edisp_pos != NULL_POSITION) ?
|
||||
is_hilited_attr(edisp_pos, eol_pos, TRUE, NULL) : 0;
|
||||
int attr;
|
||||
char ch;
|
||||
|
|
@ -64,11 +63,14 @@ static void init_status_col(POSITION base_pos, POSITION disp_pos, POSITION edisp
|
|||
{
|
||||
attr = hl_after;
|
||||
ch = '>';
|
||||
} else
|
||||
} else if (disp_pos != NULL_POSITION)
|
||||
{
|
||||
attr = is_hilited_attr(base_pos, eol_pos, TRUE, NULL);
|
||||
attr = is_hilited_attr(disp_pos, edisp_pos, TRUE, NULL);
|
||||
ch = '*';
|
||||
}
|
||||
} else
|
||||
{
|
||||
attr = 0;
|
||||
}
|
||||
if (attr)
|
||||
set_status_col(ch, attr);
|
||||
}
|
||||
|
|
@ -80,18 +82,18 @@ static void init_status_col(POSITION base_pos, POSITION disp_pos, POSITION edisp
|
|||
* 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.
|
||||
*/
|
||||
public POSITION forw_line_seg(POSITION curr_pos, int skipeol, int rscroll, int nochop)
|
||||
public POSITION forw_line_seg(POSITION curr_pos, lbool skipeol, lbool rscroll, lbool nochop)
|
||||
{
|
||||
POSITION base_pos;
|
||||
POSITION new_pos;
|
||||
POSITION edisp_pos;
|
||||
int c;
|
||||
int blankline;
|
||||
int endline;
|
||||
int chopped;
|
||||
lbool blankline;
|
||||
lbool endline;
|
||||
lbool chopped;
|
||||
int backchars;
|
||||
POSITION wrap_pos;
|
||||
int skipped_leading;
|
||||
lbool skipped_leading;
|
||||
|
||||
get_forw_line:
|
||||
if (curr_pos == NULL_POSITION)
|
||||
|
|
@ -109,8 +111,7 @@ get_forw_line:
|
|||
* If we're not ignoring EOI, we *could* do the same, but
|
||||
* for efficiency we prepare several lines ahead at once.
|
||||
*/
|
||||
prep_hilite(curr_pos, curr_pos + 3*size_linebuf,
|
||||
ignore_eoi ? 1 : -1);
|
||||
prep_hilite(curr_pos, curr_pos + (POSITION) (3*size_linebuf), ignore_eoi ? 1 : -1);
|
||||
curr_pos = next_unfiltered(curr_pos);
|
||||
}
|
||||
#endif
|
||||
|
|
@ -126,11 +127,6 @@ get_forw_line:
|
|||
base_pos = curr_pos;
|
||||
for (;;)
|
||||
{
|
||||
if (ABORT_SIGS())
|
||||
{
|
||||
null_line();
|
||||
return (NULL_POSITION);
|
||||
}
|
||||
c = ch_back_get();
|
||||
if (c == EOI)
|
||||
break;
|
||||
|
|
@ -151,13 +147,13 @@ get_forw_line:
|
|||
new_pos = base_pos;
|
||||
while (new_pos < curr_pos)
|
||||
{
|
||||
if (ABORT_SIGS())
|
||||
c = ch_forw_get();
|
||||
if (c == EOI)
|
||||
{
|
||||
null_line();
|
||||
return (NULL_POSITION);
|
||||
}
|
||||
c = ch_forw_get();
|
||||
backchars = pappend(c, new_pos);
|
||||
backchars = pappend((char) c, new_pos);
|
||||
new_pos++;
|
||||
if (backchars > 0)
|
||||
{
|
||||
|
|
@ -167,7 +163,7 @@ get_forw_line:
|
|||
do
|
||||
{
|
||||
new_pos++;
|
||||
c = ch_forw_get();
|
||||
c = ch_forw_get(); /* {{ what if c == EOI? }} */
|
||||
} while (c == ' ' || c == '\t');
|
||||
backchars = 1;
|
||||
}
|
||||
|
|
@ -198,11 +194,6 @@ get_forw_line:
|
|||
chopped = FALSE;
|
||||
for (;;)
|
||||
{
|
||||
if (ABORT_SIGS())
|
||||
{
|
||||
null_line();
|
||||
return (NULL_POSITION);
|
||||
}
|
||||
if (c == '\n' || c == EOI)
|
||||
{
|
||||
/*
|
||||
|
|
@ -220,12 +211,12 @@ get_forw_line:
|
|||
break;
|
||||
}
|
||||
if (c != '\r')
|
||||
blankline = 0;
|
||||
blankline = FALSE;
|
||||
|
||||
/*
|
||||
* Append the char to the line and get the next char.
|
||||
*/
|
||||
backchars = pappend(c, ch_tell()-1);
|
||||
backchars = pappend((char) c, ch_tell()-1);
|
||||
if (backchars > 0)
|
||||
{
|
||||
/*
|
||||
|
|
@ -236,14 +227,9 @@ get_forw_line:
|
|||
if (skipeol)
|
||||
{
|
||||
/* Read to end of line. */
|
||||
edisp_pos = ch_tell();
|
||||
edisp_pos = ch_tell() - backchars;
|
||||
do
|
||||
{
|
||||
if (ABORT_SIGS())
|
||||
{
|
||||
null_line();
|
||||
return (NULL_POSITION);
|
||||
}
|
||||
c = ch_forw_get();
|
||||
} while (c != '\n' && c != EOI);
|
||||
new_pos = ch_tell();
|
||||
|
|
@ -266,10 +252,10 @@ get_forw_line:
|
|||
do
|
||||
{
|
||||
new_pos = ch_tell();
|
||||
c = ch_forw_get();
|
||||
c = ch_forw_get(); /* {{ what if c == EOI? }} */
|
||||
} while (c == ' ' || c == '\t');
|
||||
if (c == '\r')
|
||||
c = ch_forw_get();
|
||||
c = ch_forw_get(); /* {{ what if c == EOI? }} */
|
||||
if (c == '\n')
|
||||
new_pos = ch_tell();
|
||||
} else if (wrap_pos == NULL_POSITION)
|
||||
|
|
@ -281,6 +267,7 @@ get_forw_line:
|
|||
}
|
||||
}
|
||||
endline = FALSE;
|
||||
edisp_pos = new_pos;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -302,8 +289,10 @@ get_forw_line:
|
|||
#if HILITE_SEARCH
|
||||
if (blankline && show_attn)
|
||||
{
|
||||
/* Add spurious space to carry possible attn hilite. */
|
||||
pappend(' ', ch_tell()-1);
|
||||
/* Add spurious space to carry possible attn hilite.
|
||||
* Use pappend_b so that if line ended with \r\n,
|
||||
* we insert the space before the \r. */
|
||||
pappend_b(' ', ch_tell()-1, TRUE);
|
||||
}
|
||||
#endif
|
||||
pdone(endline, rscroll && chopped, 1);
|
||||
|
|
@ -330,11 +319,7 @@ get_forw_line:
|
|||
* and pretend it is the one which we are returning.
|
||||
*/
|
||||
while ((c = ch_forw_get()) == '\n' || c == '\r')
|
||||
if (ABORT_SIGS())
|
||||
{
|
||||
null_line();
|
||||
return (NULL_POSITION);
|
||||
}
|
||||
continue;
|
||||
if (c != EOI)
|
||||
(void) ch_back_get();
|
||||
new_pos = ch_tell();
|
||||
|
|
@ -363,11 +348,11 @@ public POSITION back_line(POSITION curr_pos)
|
|||
POSITION edisp_pos;
|
||||
POSITION begin_new_pos;
|
||||
int c;
|
||||
int endline;
|
||||
int chopped;
|
||||
lbool endline;
|
||||
lbool chopped;
|
||||
int backchars;
|
||||
POSITION wrap_pos;
|
||||
int skipped_leading;
|
||||
lbool skipped_leading;
|
||||
|
||||
get_back_line:
|
||||
if (curr_pos == NULL_POSITION || curr_pos <= ch_zero())
|
||||
|
|
@ -377,8 +362,8 @@ get_back_line:
|
|||
}
|
||||
#if HILITE_SEARCH
|
||||
if (hilite_search == OPT_ONPLUS || is_filtering() || status_col)
|
||||
prep_hilite((curr_pos < 3*size_linebuf) ?
|
||||
0 : curr_pos - 3*size_linebuf, curr_pos, -1);
|
||||
prep_hilite((curr_pos < (POSITION) (3*size_linebuf)) ? 0 :
|
||||
curr_pos - (POSITION) (3*size_linebuf), curr_pos, -1);
|
||||
#endif
|
||||
if (ch_seek(curr_pos-1))
|
||||
{
|
||||
|
|
@ -393,6 +378,7 @@ get_back_line:
|
|||
*/
|
||||
(void) ch_forw_get(); /* Skip the newline */
|
||||
c = ch_forw_get(); /* First char of "current" line */
|
||||
/* {{ what if c == EOI? }} */
|
||||
(void) ch_back_get(); /* Restore our position */
|
||||
(void) ch_back_get();
|
||||
|
||||
|
|
@ -404,11 +390,7 @@ get_back_line:
|
|||
* since we skipped them in forw_line().
|
||||
*/
|
||||
while ((c = ch_back_get()) == '\n' || c == '\r')
|
||||
if (ABORT_SIGS())
|
||||
{
|
||||
null_line();
|
||||
return (NULL_POSITION);
|
||||
}
|
||||
continue;
|
||||
if (c == EOI)
|
||||
{
|
||||
null_line();
|
||||
|
|
@ -423,11 +405,6 @@ get_back_line:
|
|||
*/
|
||||
for (;;)
|
||||
{
|
||||
if (ABORT_SIGS())
|
||||
{
|
||||
null_line();
|
||||
return (NULL_POSITION);
|
||||
}
|
||||
c = ch_back_get();
|
||||
if (c == '\n')
|
||||
{
|
||||
|
|
@ -478,7 +455,7 @@ get_back_line:
|
|||
for (;;)
|
||||
{
|
||||
c = ch_forw_get();
|
||||
if (c == EOI || ABORT_SIGS())
|
||||
if (c == EOI)
|
||||
{
|
||||
null_line();
|
||||
return (NULL_POSITION);
|
||||
|
|
@ -496,7 +473,7 @@ get_back_line:
|
|||
edisp_pos = new_pos;
|
||||
break;
|
||||
}
|
||||
backchars = pappend(c, ch_tell()-1);
|
||||
backchars = pappend((char) c, ch_tell()-1);
|
||||
if (backchars > 0)
|
||||
{
|
||||
/*
|
||||
|
|
@ -523,24 +500,28 @@ get_back_line:
|
|||
{
|
||||
for (;;)
|
||||
{
|
||||
c = ch_forw_get();
|
||||
c = ch_forw_get(); /* {{ what if c == EOI? }} */
|
||||
if (c == ' ' || c == '\t')
|
||||
new_pos++;
|
||||
else
|
||||
{
|
||||
if (c == '\r')
|
||||
{
|
||||
c = ch_forw_get();
|
||||
c = ch_forw_get(); /* {{ what if c == EOI? }} */
|
||||
if (c == '\n')
|
||||
new_pos++;
|
||||
}
|
||||
if (c == '\n')
|
||||
new_pos++;
|
||||
edisp_pos = new_pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (new_pos >= curr_pos)
|
||||
{
|
||||
edisp_pos = new_pos;
|
||||
break;
|
||||
}
|
||||
pshift_all();
|
||||
} else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -16,11 +16,11 @@
|
|||
#include "position.h"
|
||||
|
||||
extern int jump_sline;
|
||||
extern int squished;
|
||||
extern int screen_trashed;
|
||||
extern lbool squished;
|
||||
extern int sc_width, sc_height;
|
||||
extern int show_attn;
|
||||
extern int top_scroll;
|
||||
extern POSITION header_start_pos;
|
||||
|
||||
/*
|
||||
* Jump to the end of the file.
|
||||
|
|
@ -184,6 +184,38 @@ public void jump_line_loc(POSITION pos, int sline)
|
|||
jump_loc(pos, sline);
|
||||
}
|
||||
|
||||
static void after_header_message(void)
|
||||
{
|
||||
#if HAVE_TIME
|
||||
#define MSG_FREQ 1 /* seconds */
|
||||
static time_type last_msg = (time_type) 0;
|
||||
time_type now = get_time();
|
||||
if (now < last_msg + MSG_FREQ)
|
||||
return;
|
||||
last_msg = now;
|
||||
#endif
|
||||
bell();
|
||||
/* {{ This message displays before the file text is updated, which is not a good UX. }} */
|
||||
/** error("Cannot display text before header; use --header=- to disable header", NULL_PARG); */
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that a position is not before the header.
|
||||
* If it is, print a message and return the position of the start of the header.
|
||||
* {{ This is probably not being used correctly in all cases.
|
||||
* It does not account for the location of pos on the screen,
|
||||
* so lines before pos could be displayed. }}
|
||||
*/
|
||||
public POSITION after_header_pos(POSITION pos)
|
||||
{
|
||||
if (header_start_pos != NULL_POSITION && pos < header_start_pos)
|
||||
{
|
||||
after_header_message();
|
||||
pos = header_start_pos;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
/*
|
||||
* Jump to a specified position in the file.
|
||||
* The position must be the first character in a line.
|
||||
|
|
@ -199,6 +231,7 @@ public void jump_loc(POSITION pos, int sline)
|
|||
/*
|
||||
* Normalize sline.
|
||||
*/
|
||||
pos = after_header_pos(pos);
|
||||
sindex = sindex_from_sline(sline);
|
||||
|
||||
if ((nline = onscreen(pos)) >= 0)
|
||||
|
|
@ -214,7 +247,7 @@ public void jump_loc(POSITION pos, int sline)
|
|||
back(-nline, position(TOP), 1, 0);
|
||||
#if HILITE_SEARCH
|
||||
if (show_attn)
|
||||
repaint_hilite(1);
|
||||
repaint_hilite(TRUE);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -255,7 +288,7 @@ public void jump_loc(POSITION pos, int sline)
|
|||
forw(sc_height-sindex+nline-1, bpos, 1, 0, 0);
|
||||
#if HILITE_SEARCH
|
||||
if (show_attn)
|
||||
repaint_hilite(1);
|
||||
repaint_hilite(TRUE);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -272,8 +305,8 @@ public void jump_loc(POSITION pos, int sline)
|
|||
}
|
||||
}
|
||||
lastmark();
|
||||
squished = 0;
|
||||
screen_trashed = 0;
|
||||
squished = FALSE;
|
||||
screen_trashed_num(0);
|
||||
forw(sc_height-1, pos, 1, 0, sindex-nline);
|
||||
} else
|
||||
{
|
||||
|
|
@ -308,7 +341,7 @@ public void jump_loc(POSITION pos, int sline)
|
|||
back(nline+1, tpos, 1, 0);
|
||||
#if HILITE_SEARCH
|
||||
if (show_attn)
|
||||
repaint_hilite(1);
|
||||
repaint_hilite(TRUE);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -318,7 +351,7 @@ public void jump_loc(POSITION pos, int sline)
|
|||
clear();
|
||||
else
|
||||
home();
|
||||
screen_trashed = 0;
|
||||
screen_trashed_num(0);
|
||||
add_back_pos(pos);
|
||||
back(sc_height-1, pos, 1, 0);
|
||||
}
|
||||
|
|
|
|||
57
contrib/less/lang.h
Normal file
57
contrib/less/lang.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
*
|
||||
* For more information, see the README file.
|
||||
*/
|
||||
|
||||
#ifndef LESS_LANG_H_
|
||||
#define LESS_LANG_H_ 1
|
||||
|
||||
/*
|
||||
* C language details.
|
||||
*/
|
||||
#if HAVE_CONST
|
||||
#define constant const
|
||||
#else
|
||||
#define constant
|
||||
#endif
|
||||
|
||||
/*
|
||||
* mutable is the opposite of constant.
|
||||
* It documents that a pointer parameter will be written through by the
|
||||
* called function, more directly than by the mere absence of "constant".
|
||||
*/
|
||||
#define mutable
|
||||
|
||||
#define public /* PUBLIC FUNCTION */
|
||||
|
||||
#undef ptr_diff
|
||||
#define ptr_diff(p1,p2) ((size_t) ((p1)-(p2)))
|
||||
#undef countof
|
||||
#define countof(a) ((int)(sizeof(a)/sizeof(*a)))
|
||||
|
||||
#define size_t_null ((size_t)-1)
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
typedef enum lbool { LFALSE, LTRUE } lbool;
|
||||
|
||||
#undef TRUE
|
||||
#define TRUE LTRUE
|
||||
#undef FALSE
|
||||
#define FALSE LFALSE
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _WIN64
|
||||
typedef __int64 ssize_t;
|
||||
#else
|
||||
typedef __int32 ssize_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // LESS_LANG_H_
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -36,16 +36,6 @@
|
|||
#undef HAVE_SIGSETMASK
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Language details.
|
||||
*/
|
||||
#if HAVE_CONST
|
||||
#define constant const
|
||||
#else
|
||||
#define constant
|
||||
#endif
|
||||
|
||||
#define public /* PUBLIC FUNCTION */
|
||||
|
||||
/* Library function declarations */
|
||||
|
||||
|
|
@ -87,11 +77,14 @@
|
|||
* 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)))
|
||||
#define ckd_add(r, a, b) help_ckd_add(r, (uintmax)(a), (uintmax)(b), sizeof *(r), signed_expr(*(r)))
|
||||
#define ckd_mul(r, a, b) help_ckd_mul(r, (uintmax)(a), (uintmax)(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
|
||||
#define muldiv(val,num,den) umuldiv((uintmax)(val), (uintmax)(num), (uintmax)(den))
|
||||
|
||||
#include "lang.h"
|
||||
|
||||
#if defined UINTMAX_MAX
|
||||
typedef uintmax_t uintmax;
|
||||
|
|
@ -146,21 +139,21 @@ void free();
|
|||
#undef IS_DIGIT
|
||||
|
||||
#if HAVE_WCTYPE
|
||||
#define IS_UPPER(c) iswupper(c)
|
||||
#define IS_LOWER(c) iswlower(c)
|
||||
#define TO_UPPER(c) towupper(c)
|
||||
#define TO_LOWER(c) towlower(c)
|
||||
#define IS_UPPER(c) iswupper((wint_t) (c))
|
||||
#define IS_LOWER(c) iswlower((wint_t) (c))
|
||||
#define TO_UPPER(c) towupper((wint_t) (c))
|
||||
#define TO_LOWER(c) towlower((wint_t) (c))
|
||||
#else
|
||||
#if HAVE_UPPER_LOWER
|
||||
#define IS_UPPER(c) isupper((unsigned char) (c))
|
||||
#define IS_LOWER(c) islower((unsigned char) (c))
|
||||
#define TO_UPPER(c) toupper((unsigned char) (c))
|
||||
#define TO_LOWER(c) tolower((unsigned char) (c))
|
||||
#define IS_UPPER(c) (is_ascii_char(c) && isupper((unsigned char) (c)))
|
||||
#define IS_LOWER(c) (is_ascii_char(c) && islower((unsigned char) (c)))
|
||||
#define TO_UPPER(c) (is_ascii_char(c) ? toupper((unsigned char) (c)) : (c))
|
||||
#define TO_LOWER(c) (is_ascii_char(c) ? tolower((unsigned char) (c)) : (c))
|
||||
#else
|
||||
#define IS_UPPER(c) ASCII_IS_UPPER(c)
|
||||
#define IS_LOWER(c) ASCII_IS_LOWER(c)
|
||||
#define TO_UPPER(c) ASCII_TO_UPPER(c)
|
||||
#define TO_LOWER(c) ASCII_TO_LOWER(c)
|
||||
#define IS_UPPER(c) (is_ascii_char(c) && ASCII_IS_UPPER(c))
|
||||
#define IS_LOWER(c) (is_ascii_char(c) && ASCII_IS_LOWER(c))
|
||||
#define TO_UPPER(c) (is_ascii_char(c) ? ASCII_TO_UPPER(c) : (c))
|
||||
#define TO_LOWER(c) (is_ascii_char(c) ? ASCII_TO_LOWER(c) : (c))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
@ -178,17 +171,6 @@ void free();
|
|||
|
||||
#define IS_CSI_START(c) (((LWCHAR)(c)) == ESC || (((LWCHAR)(c)) == CSI))
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define OPT_OFF 0
|
||||
#define OPT_ON 1
|
||||
#define OPT_ONPLUS 2
|
||||
|
|
@ -236,7 +218,20 @@ void free();
|
|||
* Special types and constants.
|
||||
*/
|
||||
typedef unsigned long LWCHAR;
|
||||
typedef off_t POSITION;
|
||||
#if defined(MINGW) || (defined(_MSC_VER) && _MSC_VER >= 1500)
|
||||
typedef long long less_off_t; /* __int64 */
|
||||
typedef struct _stat64 less_stat_t;
|
||||
#define less_fstat _fstat64
|
||||
#define less_stat _stat64
|
||||
#define less_lseek _lseeki64
|
||||
#else
|
||||
typedef off_t less_off_t;
|
||||
typedef struct stat less_stat_t;
|
||||
#define less_fstat fstat
|
||||
#define less_stat stat
|
||||
#define less_lseek lseek
|
||||
#endif
|
||||
typedef less_off_t POSITION;
|
||||
typedef off_t LINENUM;
|
||||
#define MIN_LINENUM_WIDTH 7 /* Default min printing width of a line number */
|
||||
#define MAX_LINENUM_WIDTH 16 /* Max width of a line number */
|
||||
|
|
@ -327,7 +322,7 @@ struct scrpos
|
|||
|
||||
typedef union parg
|
||||
{
|
||||
char *p_string;
|
||||
constant char *p_string;
|
||||
int p_int;
|
||||
LINENUM p_linenum;
|
||||
char p_char;
|
||||
|
|
@ -348,8 +343,8 @@ struct wchar_range
|
|||
|
||||
struct wchar_range_table
|
||||
{
|
||||
struct wchar_range *table;
|
||||
int count;
|
||||
struct wchar_range *table;
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
#if HAVE_POLL
|
||||
|
|
@ -397,13 +392,25 @@ typedef short POLL_EVENTS;
|
|||
#define SRCH_FILTER (1 << 13) /* Search is for '&' (filter) command */
|
||||
#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_SUBSEARCH(i) (1 << (16+(i))) /* Search for subpattern */
|
||||
#if OSC8_LINK
|
||||
#define SRCH_OSC8 (1 << 16) /* */
|
||||
#endif
|
||||
#define SRCH_SUBSEARCH(i) (1 << (17+(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) ? \
|
||||
(((t) & ~SRCH_FORW) | SRCH_BACK) : \
|
||||
(((t) & ~SRCH_BACK) | SRCH_FORW))
|
||||
/* Parsing position in an OSC8 link: "\e]8;PARAMS;URI\e\\" (final "\e\\" may be "\7") */
|
||||
typedef enum osc8_state {
|
||||
OSC8_NOT, /* This is not an OSC8 link */
|
||||
OSC8_PREFIX, /* In the "\e]8;" */
|
||||
OSC8_PARAMS, /* In the parameters */
|
||||
OSC8_URI, /* In the URI */
|
||||
OSC8_ST_ESC, /* After the final \e */
|
||||
OSC8_END, /* At end */
|
||||
} osc8_state;
|
||||
|
||||
/* */
|
||||
#define NO_MCA 0
|
||||
|
|
@ -454,10 +461,21 @@ typedef enum {
|
|||
CV_ERROR = -1
|
||||
} COLOR_VALUE;
|
||||
|
||||
typedef enum {
|
||||
CATTR_NULL = 0,
|
||||
CATTR_STANDOUT = (1 << 0),
|
||||
CATTR_BOLD = (1 << 1),
|
||||
CATTR_UNDERLINE = (1 << 2),
|
||||
CATTR_BLINK = (1 << 3),
|
||||
} CHAR_ATTR;
|
||||
|
||||
/* ANSI states */
|
||||
#define ANSI_MID 1
|
||||
#define ANSI_ERR 2
|
||||
#define ANSI_END 3
|
||||
typedef enum {
|
||||
ANSI_NULL,
|
||||
ANSI_MID,
|
||||
ANSI_ERR,
|
||||
ANSI_END,
|
||||
} ansi_state;
|
||||
|
||||
#if '0' == 240
|
||||
#define IS_EBCDIC_HOST 1
|
||||
|
|
@ -534,7 +552,6 @@ typedef enum {
|
|||
#define ESC CONTROL('[')
|
||||
#define ESCS "\33"
|
||||
#define CSI ((unsigned char)'\233')
|
||||
#define CHAR_END_COMMAND 0x40000000
|
||||
|
||||
#if _OSK_MWC32
|
||||
#define LSIGNAL(sig,func) os9_signal(sig,func)
|
||||
|
|
@ -584,6 +601,7 @@ typedef enum {
|
|||
#define CH_POPENED 004
|
||||
#define CH_HELPFILE 010
|
||||
#define CH_NODATA 020 /* Special case for zero length files */
|
||||
#define CH_NOTRUSTSIZE 040 /* For files that claim 0 length size falsely */
|
||||
|
||||
#define ch_zero() ((POSITION)0)
|
||||
|
||||
|
|
@ -611,6 +629,20 @@ typedef enum {
|
|||
#define X11MOUSE_WHEEL_DOWN 0x41 /* Wheel scroll down */
|
||||
#define X11MOUSE_OFFSET 0x20 /* Added to button & pos bytes to create a char */
|
||||
|
||||
/* Security features. */
|
||||
#define SF_EDIT (1<<1) /* Edit file (v) */
|
||||
#define SF_EXAMINE (1<<2) /* Examine file (:e) */
|
||||
#define SF_GLOB (1<<3) /* Expand file pattern */
|
||||
#define SF_HISTORY (1<<4) /* History file */
|
||||
#define SF_LESSKEY (1<<5) /* Lesskey files */
|
||||
#define SF_LESSOPEN (1<<6) /* LESSOPEN */
|
||||
#define SF_LOGFILE (1<<7) /* Log file (s, -o) */
|
||||
#define SF_PIPE (1<<8) /* Pipe (|) */
|
||||
#define SF_SHELL (1<<9) /* Shell command (!) */
|
||||
#define SF_STOP (1<<10) /* Stop signal */
|
||||
#define SF_TAGS (1<<11) /* Tags */
|
||||
#define SF_OSC8_OPEN (1<<12) /* OSC8 open */
|
||||
|
||||
#if LESSTEST
|
||||
#define LESS_DUMP_CHAR CONTROL(']')
|
||||
#endif
|
||||
|
|
@ -630,6 +662,9 @@ void inttoa(int, char*, int);
|
|||
int lstrtoi(char*, char**, int);
|
||||
POSITION lstrtopos(char*, char**, int);
|
||||
unsigned long lstrtoul(char*, char**, int);
|
||||
int lstrtoic(constant char*, constant char**, int);
|
||||
POSITION lstrtoposc(constant char*, constant char**, int);
|
||||
unsigned long lstrtoulc(constant char*, constant char**, int);
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
int pclose(FILE*);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@
|
|||
N * Repeat previous search in reverse direction.
|
||||
ESC-n * Repeat previous search, spanning files.
|
||||
ESC-N * Repeat previous search, reverse dir. & spanning files.
|
||||
^O^N ^On * Search forward for (_N-th) OSC8 hyperlink.
|
||||
^O^P ^Op * Search backward for (_N-th) OSC8 hyperlink.
|
||||
^O^L ^Ol Jump to the currently selected OSC8 hyperlink.
|
||||
ESC-u Undo (toggle) search highlighting.
|
||||
ESC-U Clear search highlighting.
|
||||
&_p_a_t_t_e_r_n * Display only matching lines.
|
||||
|
|
@ -53,6 +56,7 @@
|
|||
^R Don't use REGULAR EXPRESSIONS.
|
||||
^S _n Search for match in _n-th parenthesized subpattern.
|
||||
^W WRAP search if no match found.
|
||||
^L Enter next character literally into pattern.
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
JJUUMMPPIINNGG
|
||||
|
|
@ -92,6 +96,7 @@
|
|||
:n * Examine the (_N-th) next file from the command line.
|
||||
:p * Examine the (_N-th) previous file from the command line.
|
||||
:x * Examine the first (or _N-th) file from the command line.
|
||||
^O^O Open the currently selected OSC8 hyperlink.
|
||||
:d Delete the current file from the command line list.
|
||||
= ^G :f Print current file name.
|
||||
---------------------------------------------------------------------------
|
||||
|
|
@ -155,8 +160,8 @@
|
|||
Screen position of target lines.
|
||||
-J ........ --status-column
|
||||
Display a status column at left edge of screen.
|
||||
-k [_f_i_l_e] . --lesskey-file=[_f_i_l_e]
|
||||
Use a lesskey file.
|
||||
-k _f_i_l_e ... --lesskey-file=_f_i_l_e
|
||||
Use a compiled lesskey file.
|
||||
-K ........ --quit-on-intr
|
||||
Exit less in response to ctrl-C.
|
||||
-L ........ --no-lessopen
|
||||
|
|
@ -167,11 +172,11 @@
|
|||
Suppress line numbers in prompts and messages.
|
||||
-N ......... --LINE-NUMBERS
|
||||
Display line number at start of each line.
|
||||
-o [_f_i_l_e] . --log-file=[_f_i_l_e]
|
||||
-o [_f_i_l_e] .. --log-file=[_f_i_l_e]
|
||||
Copy to log file (standard input only).
|
||||
-O [_f_i_l_e] . --LOG-FILE=[_f_i_l_e]
|
||||
-O [_f_i_l_e] .. --LOG-FILE=[_f_i_l_e]
|
||||
Copy to log file (unconditionally overwrite).
|
||||
-p [_p_a_t_t_e_r_n] --pattern=[_p_a_t_t_e_r_n]
|
||||
-p _p_a_t_t_e_r_n . --pattern=[_p_a_t_t_e_r_n]
|
||||
Start at pattern (from command line).
|
||||
-P [_p_r_o_m_p_t] --prompt=[_p_r_o_m_p_t]
|
||||
Define new prompt.
|
||||
|
|
@ -183,7 +188,7 @@
|
|||
Squeeze multiple blank lines.
|
||||
-S ........ --chop-long-lines
|
||||
Chop (truncate) long lines rather than wrapping.
|
||||
-t [_t_a_g] .. --tag=[_t_a_g]
|
||||
-t _t_a_g .... --tag=[_t_a_g]
|
||||
Find a tag.
|
||||
-T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e]
|
||||
Use an alternate tags file.
|
||||
|
|
@ -209,21 +214,28 @@
|
|||
Don't display tildes after end of file.
|
||||
-# [_N] .... --shift=[_N]
|
||||
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
|
||||
Automatically determine the size of the input file.
|
||||
--follow-name
|
||||
The F command changes files if the input file is renamed.
|
||||
--header=[_N[,_M]]
|
||||
Use N lines and M columns to display file headers.
|
||||
--header=[_L[,_C[,_N]]]
|
||||
Use _L lines (starting at line _N) and _C columns as headers.
|
||||
--incsearch
|
||||
Search file as each pattern character is typed in.
|
||||
--intr=_C
|
||||
--intr=[_C]
|
||||
Use _C instead of ^X to interrupt a read.
|
||||
--line-num-width=_N
|
||||
--lesskey-context=_t_e_x_t
|
||||
Use lesskey source file contents.
|
||||
--lesskey-src=_f_i_l_e
|
||||
Use a lesskey source file.
|
||||
--line-num-width=[_N]
|
||||
Set the width of the -N line number field to _N characters.
|
||||
--modelines=_N
|
||||
--match-shift=[_N]
|
||||
Show at least _N characters to the left of a search match.
|
||||
--modelines=[_N]
|
||||
Read _N lines from the input file and look for vim modelines.
|
||||
--mouse
|
||||
Enable mouse input.
|
||||
|
|
@ -233,13 +245,17 @@
|
|||
Remove duplicates from command history.
|
||||
--no-number-headers
|
||||
Don't give line numbers to header lines.
|
||||
--no-search-header-lines
|
||||
Searches do not include header lines.
|
||||
--no-search-header-columns
|
||||
Searches do not include header columns.
|
||||
--no-search-headers
|
||||
Don't search in header lines or columns.
|
||||
Searches do not include header lines or columns.
|
||||
--no-vbell
|
||||
Disable the terminal's visual bell.
|
||||
--redraw-on-quit
|
||||
Redraw final screen when quitting.
|
||||
--rscroll=_C
|
||||
--rscroll=[_C]
|
||||
Set the character used to mark truncated lines.
|
||||
--save-marks
|
||||
Retain marks across invocations of less.
|
||||
|
|
@ -249,17 +265,17 @@
|
|||
Display a message if preprocessor exits with an error status.
|
||||
--proc-backspace
|
||||
Process backspaces for bold/underline.
|
||||
--SPECIAL-BACKSPACE
|
||||
--PROC-BACKSPACE
|
||||
Treat backspaces as control characters.
|
||||
--proc-return
|
||||
Delete carriage returns before newline.
|
||||
--SPECIAL-RETURN
|
||||
--PROC-RETURN
|
||||
Treat carriage returns as control characters.
|
||||
--proc-tab
|
||||
Expand tabs to spaces.
|
||||
--SPECIAL-TAB
|
||||
--PROC-TAB
|
||||
Treat tabs as control characters.
|
||||
--status-col-width=_N
|
||||
--status-col-width=[_N]
|
||||
Set the width of the -J status column to _N characters.
|
||||
--status-line
|
||||
Highlight or color the entire line containing a mark.
|
||||
|
|
@ -267,7 +283,7 @@
|
|||
Subsequent options use backslash as escape char.
|
||||
--use-color
|
||||
Enables colored text.
|
||||
--wheel-lines=_N
|
||||
--wheel-lines=[_N]
|
||||
Each click of the mouse wheel moves _N lines.
|
||||
--wordwrap
|
||||
Wrap lines at spaces.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
'\" t
|
||||
.TH LESS 1 "Version 643: 20 Jul 2023"
|
||||
.TH LESS 1 "Version 668: 06 Oct 2024"
|
||||
.SH NAME
|
||||
less \- opposite of more
|
||||
less \- display the contents of a file in a terminal
|
||||
.SH SYNOPSIS
|
||||
.B "less \-?"
|
||||
.br
|
||||
|
|
@ -27,10 +27,8 @@ less \- opposite of more
|
|||
.B Less
|
||||
is a program similar to
|
||||
.BR more (1),
|
||||
but which allows backward movement
|
||||
in the file as well as forward movement.
|
||||
Also,
|
||||
.B less
|
||||
but it has many more features.
|
||||
.B Less
|
||||
does not have to read the entire input file before starting,
|
||||
so with large input files it starts up faster than text editors like
|
||||
.BR vi (1).
|
||||
|
|
@ -253,6 +251,9 @@ That is, if the search reaches the end of the current file
|
|||
without finding a match, the search continues from the first line of the
|
||||
current file up to the line where it started.
|
||||
If the \(haW modifier is set, the \(haE modifier is ignored.
|
||||
.IP "\(haL"
|
||||
The next character is taken literally; that is, it becomes part of the pattern
|
||||
even if it is one of the above search modifier characters.
|
||||
.RE
|
||||
.IP ?pattern
|
||||
Search backward in the file for the N-th line containing the pattern.
|
||||
|
|
@ -376,6 +377,12 @@ Go to the next tag, if there were more than one matches for the current tag.
|
|||
See the \-t option for more details about tags.
|
||||
.IP "T"
|
||||
Go to the previous tag, if there were more than one matches for the current tag.
|
||||
.IP "\(haO\(haN or \(haOn"
|
||||
Search forward in the file for the N-th next OSC 8 hyperlink.
|
||||
.IP "\(haO\(haP or \(haOp"
|
||||
Search backward in the file for the N-th previous OSC 8 hyperlink.
|
||||
.IP "\(haO\(haL or \(haOl"
|
||||
Jump to the currently selected OSC 8 hyperlink.
|
||||
.IP "= or \(haG or :f"
|
||||
Prints some information about the file being viewed,
|
||||
including its name
|
||||
|
|
@ -443,7 +450,7 @@ Exits
|
|||
.BR less .
|
||||
.PP
|
||||
The following
|
||||
six
|
||||
seven
|
||||
commands may or may not be valid, depending on your particular installation.
|
||||
.
|
||||
.IP v
|
||||
|
|
@ -459,9 +466,11 @@ current file.
|
|||
A pound sign (#) is replaced by the name of the previously examined file.
|
||||
"!!" repeats the last shell command.
|
||||
"!" with no shell command simply invokes a shell.
|
||||
If a \(haP (CONTROL-P) is entered immediately after the !,
|
||||
no "done" message is printed after the shell command is executed.
|
||||
On Unix systems, the shell is taken from the environment variable SHELL,
|
||||
or defaults to "sh".
|
||||
On MS-DOS and OS/2 systems, the shell is the normal command processor.
|
||||
On MS-DOS, Windows, and OS/2 systems, the shell is the normal command processor.
|
||||
.IP "# shell-command"
|
||||
Similar to the "!" command,
|
||||
except that the command is expanded in the same way as prompt strings.
|
||||
|
|
@ -475,9 +484,74 @@ The entire current screen is included, regardless of whether the
|
|||
marked position is before or after the current screen.
|
||||
<m> may also be \(ha or $ to indicate beginning or end of file respectively.
|
||||
If <m> is \&.\& or newline, the current screen is piped.
|
||||
If a \(haP (CONTROL-P) is entered immediately after the mark letter,
|
||||
no "done" message is printed after the shell command is executed.
|
||||
.IP "s filename"
|
||||
Save the input to a file.
|
||||
This works only if the input is a pipe, not an ordinary file.
|
||||
.IP "\(haO\(haO"
|
||||
.RS
|
||||
Run a shell command to open the URI in the current OSC 8 hyperlink,
|
||||
selected by a previous \(haO\(haN or \(haO\(haP command.
|
||||
To find the shell command,
|
||||
the environment variable named "LESS_OSC8_xxx" is read,
|
||||
where "xxx" is the scheme from the URI (the part before the first colon),
|
||||
or is empty if there is no colon in the URI.
|
||||
The value of the environment variable is then expanded in the same way as
|
||||
prompt strings (in particular, any instance of "%o" is replaced with the URI)
|
||||
to produce an OSC 8 "handler" shell command.
|
||||
The standard output from the handler is an "opener" shell command
|
||||
which is then executed to open the URI.
|
||||
.PP
|
||||
There are two special cases:
|
||||
.RS
|
||||
.IP 1.
|
||||
If the URI begins with "#", the remainder of the URI is taken to be
|
||||
the value of the id parameter in another OSC 8 link in the same file,
|
||||
and \(haO\(haO will simply jump to that link.
|
||||
.IP 2.
|
||||
If the opener begins with the characters ":e" followed by
|
||||
whitespace and a filename,
|
||||
then instead of running the opener as a shell command,
|
||||
the specified filename is opened in the current instance of
|
||||
.BR less .
|
||||
.RE
|
||||
.PP
|
||||
In a simple case where the opener accepts the complete URI
|
||||
as a command line parameter, the handler may be as simple as
|
||||
.nf
|
||||
.sp
|
||||
echo mybrowser '%o'
|
||||
.sp
|
||||
.fi
|
||||
In other cases, the URI may need to be modified, so the handler
|
||||
may have to do some manipulation of the %o value.
|
||||
.PP
|
||||
If the LESS_OSC8_xxx variable is not set, the variable LESS_OSC8_ANY is tried.
|
||||
If neither LESS_OSC8_xxx nor LESS_OSC8_ANY is set,
|
||||
links using the "xxx" scheme cannot be opened.
|
||||
However, there are default handlers for the
|
||||
schemes "man" (used when LESS_OSC8_man is not set)
|
||||
and "file" (used when LESS_OSC8_file is not set),
|
||||
which should work on systems which provide the
|
||||
.BR sed (1)
|
||||
command and a shell with syntax compatible with the Bourne shell
|
||||
.BR sh (1).
|
||||
If you use LESS_OSC8_ANY to override LESS_OSC8_file, you must
|
||||
set LESS_OSC8_file to "-" to indicate that the default value
|
||||
should not be used, and likewise for LESS_OSC8_man.
|
||||
.PP
|
||||
The URI passed to an OSC8 handler via %o is guaranteed not to contain any single quote
|
||||
or double quote characters, but it may contain any other shell metacharacters
|
||||
such as semicolons, dollar signs, ampersands, etc.
|
||||
The handler should take care to appropriately quote parameters in the opener command,
|
||||
to prevent execution of unintended shell commands in the case of opening
|
||||
a URI which contains shell metacharacters.
|
||||
Also, since the handler command is expanded like a command prompt,
|
||||
any metacharacters interpreted by prompt expansion
|
||||
(such as percent, dot, colon, backslash, etc.) must be escaped with a backslash
|
||||
(see the PROMPTS section for details).
|
||||
.RE
|
||||
.IP "\(haX"
|
||||
When the "Waiting for data" message is displayed,
|
||||
such as while in the F command, pressing \(haX
|
||||
|
|
@ -530,8 +604,9 @@ or if you use
|
|||
.sp
|
||||
LESS="\-options"; export LESS
|
||||
.sp
|
||||
On MS-DOS, you don't need the quotes, but you should replace any
|
||||
percent signs in the options string by double percent signs.
|
||||
On MS-DOS and Windows, you don't need the quotes, but you should
|
||||
be careful that any percent signs in the options string are not
|
||||
interpreted as an environment variable expansion.
|
||||
.sp
|
||||
The environment variable is parsed before the command line,
|
||||
so command line options override the LESS environment variable.
|
||||
|
|
@ -543,7 +618,7 @@ Some options like \-k or \-D require a string to follow the option letter.
|
|||
The string for that option is considered to end when a dollar sign ($) is found.
|
||||
For example, you can set two \-D options like this:
|
||||
.sp
|
||||
LESS="Dn9.1$Ds4.1"
|
||||
LESS="Dnwb$Dsbw"
|
||||
.sp
|
||||
If the \-\-use-backslash option appears earlier in the options, then
|
||||
a dollar sign or backslash may be included literally in an option string
|
||||
|
|
@ -637,6 +712,8 @@ Prompts.
|
|||
The rscroll character.
|
||||
.IP "S"
|
||||
Search results.
|
||||
.IP "W"
|
||||
The highlight enabled via the \-w option.
|
||||
.IP "1-5"
|
||||
The text in a search result which matches
|
||||
the first through fifth parenthesized sub-pattern.
|
||||
|
|
@ -644,8 +721,6 @@ Sub-pattern coloring works only if
|
|||
.B less
|
||||
is built with one of the regular expression libraries
|
||||
.BR posix ", " pcre ", or " pcre2 .
|
||||
.IP "W"
|
||||
The highlight enabled via the \-w option.
|
||||
.IP "d"
|
||||
Bold text.
|
||||
.IP "k"
|
||||
|
|
@ -655,7 +730,7 @@ Standout text.
|
|||
.IP "u"
|
||||
Underlined text.
|
||||
.RE
|
||||
|
||||
|
||||
.RS
|
||||
The uppercase letters and digits can be used only when the \-\-use-color option is enabled.
|
||||
When text color is specified by both an uppercase letter and a lowercase letter,
|
||||
|
|
@ -663,9 +738,11 @@ the uppercase letter takes precedence.
|
|||
For example, error messages are normally displayed as standout text.
|
||||
So if both "s" and "E" are given a color, the "E" color applies
|
||||
to error messages, and the "s" color applies to other standout text.
|
||||
The "d" and "u" letters refer to bold and underline text formed by
|
||||
overstriking with backspaces (see the \-U option),
|
||||
not to text using ANSI escape sequences with the \-R option.
|
||||
The lowercase letters refer to bold and underline text formed by
|
||||
overstriking with backspaces (see the \-U option) and to non-content
|
||||
text (such as line numbers and prompts),
|
||||
but not to text formatted using ANSI escape sequences with the \-R option
|
||||
(but see the note below for different behavior on Windows and MS-DOS).
|
||||
.PP
|
||||
A lowercase letter may be followed by a + to indicate that
|
||||
the normal format change and the specified color should both be used.
|
||||
|
|
@ -675,7 +752,7 @@ But \-Du+g displays underlined text as both green and in underlined format.
|
|||
.PP
|
||||
\fIcolor\fP is either a 4-bit color string or an 8-bit color string:
|
||||
.PP
|
||||
A 4-bit color string is zero, one or two characters, where
|
||||
A 4-bit color string is one or two characters, where
|
||||
the first character specifies the foreground color and
|
||||
the second specifies the background color as follows:
|
||||
.IP "b"
|
||||
|
|
@ -707,26 +784,62 @@ where the first integer specifies the foreground color and
|
|||
the second specifies the background color.
|
||||
Each integer is a value between 0 and 255 inclusive which selects
|
||||
a "CSI 38;5" color value (see
|
||||
.br
|
||||
.nh
|
||||
https://en.wikipedia.org/wiki/ANSI_escape_code#SGR)
|
||||
https://en.wikipedia.org/wiki/ANSI_escape_code#SGR).
|
||||
.hy
|
||||
If either integer is a "-" or is omitted,
|
||||
the corresponding color is set to that of normal text.
|
||||
On MS-DOS versions of
|
||||
.BR less ,
|
||||
8-bit color is not supported; instead, decimal values are interpreted as 4-bit
|
||||
CHAR_INFO.Attributes values
|
||||
(see
|
||||
.br
|
||||
.nh
|
||||
https://docs.microsoft.com/en-us/windows/console/char-info-str).
|
||||
.hy
|
||||
.PP
|
||||
On MS-DOS only, the \-Da option may be used to specify strict parsing of
|
||||
ANSI color (SGR) sequences when the \-R option is used.
|
||||
Without this option, sequences that change text attributes
|
||||
(bold, underline, etc.) may clear the text color.
|
||||
A 4-bit or 8-bit color string may be followed by one or more of the
|
||||
following characters to set text attributes in addition to the color.
|
||||
.IP "s or ~"
|
||||
Standout (reverse video)
|
||||
.IP "u or _"
|
||||
Underline
|
||||
.IP "d or *"
|
||||
Bold
|
||||
.IP "l or &"
|
||||
Blinking
|
||||
.PP
|
||||
On MS-DOS and Windows, the \-\-color option behaves
|
||||
differently from what is described above in these ways:
|
||||
.IP \(bu
|
||||
The bold (d and *) and blinking (l and &) text attributes
|
||||
at the end of a color string are not supported.
|
||||
.IP \(bu
|
||||
Lowercase color selector letters refer to text formatted by ANSI
|
||||
escape sequences with \-R,
|
||||
in addition to overstruck and non-content text (but see \-Da).
|
||||
.IP \(bu
|
||||
For historical reasons, when a lowercase color selector letter
|
||||
is followed by a numeric color value,
|
||||
the number is not interpreted as an "CSI 38;5" color value as described above,
|
||||
but instead as a 4-bit
|
||||
.nh
|
||||
CHAR_INFO.Attributes
|
||||
.hy
|
||||
value, between 0 and 15 inclusive
|
||||
(see
|
||||
.nh
|
||||
https://learn.microsoft.com/en-us/windows/console/char-info-str).
|
||||
.hy
|
||||
|
||||
To avoid confusion, it is recommended that the equivalent letters rather than numbers
|
||||
be used after a lowercase color selector on MS-DOS/Windows.
|
||||
.IP \(bu
|
||||
Numeric color values ("CSI 38;5" color) following an uppercase color selector letter
|
||||
are not supported on systems earlier than Windows 10.
|
||||
.IP \(bu
|
||||
Only a limited set of ANSI escape sequences to set color in the content work correctly.
|
||||
4-bit color sequences work, but "CSI 38;5" color sequences do not.
|
||||
.IP \(bu
|
||||
The \-Da option makes the behavior of \-\-color
|
||||
more similar to its behavior on non-MS-DOS/Windows systems by (1)
|
||||
making lowercase color selector letters not affect text formatted
|
||||
with ANSI escape sequences, and (2)
|
||||
allowing "CSI 38;5" color sequences in the content
|
||||
work by passing them to the terminal (only on Windows 10 and later; on
|
||||
earlier Windows systems, such sequences do not work regardless of the setting of \-Da).
|
||||
.RE
|
||||
.IP "\-e or \-\-quit-at-eof"
|
||||
Causes
|
||||
|
|
@ -797,6 +910,13 @@ of the screen, starting with a decimal point: \&.5 is in the middle of the
|
|||
screen, \&.3 is three tenths down from the first line, and so on.
|
||||
If the line is specified as a fraction, the actual line number
|
||||
is recalculated if the terminal window is resized.
|
||||
If the \-\-header option is used and the target line specified by \-j
|
||||
would be obscured by the header, the target line is moved to the first
|
||||
line after the header.
|
||||
While the \-\-header option is active, the \-S option is ignored,
|
||||
and lines longer than the screen width are truncated.
|
||||
.RS
|
||||
.PP
|
||||
If any form of the \-j option is used,
|
||||
repeated forward searches (invoked with "n" or "N")
|
||||
begin at the line immediately after the target line,
|
||||
|
|
@ -807,6 +927,7 @@ fourth line on the screen, so forward searches begin at the fifth line
|
|||
on the screen.
|
||||
However nonrepeated searches (invoked with "/" or "?")
|
||||
always begin at the start or end of the current screen respectively.
|
||||
.RE
|
||||
.IP "\-J or \-\-status-column"
|
||||
Displays a status column at the left edge of the screen.
|
||||
The character displayed in the status column may be one of:
|
||||
|
|
@ -840,6 +961,7 @@ if a lesskey file is found in a standard place (see KEY BINDINGS),
|
|||
it is also used as a
|
||||
.B lesskey
|
||||
file.
|
||||
Note the warning under "\-\-lesskey-content" below.
|
||||
.IP "\-\-lesskey-src=\fIfilename\fP"
|
||||
Causes
|
||||
.B less
|
||||
|
|
@ -865,6 +987,26 @@ Newer versions of
|
|||
read the
|
||||
.I "lesskey source"
|
||||
file directly and ignore the binary file if the source file exists.
|
||||
Note the warning under "\-\-lesskey-content" below.
|
||||
.IP "\-\-lesskey-content=\fItext\fP"
|
||||
Causes less to interpret the specified text as the contents of a
|
||||
.BR lesskey (1)
|
||||
source file.
|
||||
In the text,
|
||||
.B lesskey
|
||||
lines may be separated by either newlines as usual, or by semicolons.
|
||||
A literal semicolon may be represented by a backslash followed by a semicolon.
|
||||
.sp
|
||||
Warning: certain environment variables such as
|
||||
LESS, LESSSECURE, LESSCHARSET and others,
|
||||
which are used early in startup,
|
||||
cannot be set in a file specified by a command line option
|
||||
(\-\-lesskey, \-\-lesskey-src or \-\-lesskey-content). When using a
|
||||
.B lesskey
|
||||
file to set environment variables, it is safer to use the
|
||||
default lesskey file, or to specify the file using the
|
||||
LESSKEYIN or LESSKEY_CONTENT environment variables rather than using
|
||||
a command line option.
|
||||
.IP "\-K or \-\-quit-on-intr"
|
||||
Causes
|
||||
.B less
|
||||
|
|
@ -1186,25 +1328,32 @@ If the reopen succeeds and the file is a different file from the original
|
|||
with the same name as the original (now renamed) file),
|
||||
.B less
|
||||
will display the contents of that new file.
|
||||
.IP "\-\-header=\fIN[,M]\fP"
|
||||
.IP "\-\-header=\fIL\fP,\fIC\fP,\fIN\fP"
|
||||
.RS
|
||||
Sets the number of header lines and columns displayed on the screen.
|
||||
The value may be of the form "N,M" where N and M are integers,
|
||||
to set the header lines to N and the header columns to M,
|
||||
or it may be a single integer "N" which sets the header lines to N
|
||||
and the header columns to zero,
|
||||
or it may be ",M" which sets the header columns to M and the
|
||||
header lines to zero.
|
||||
When N is nonzero, the first N lines at the top
|
||||
of the screen are replaced with the first N lines of the file,
|
||||
regardless of what part of the file are being viewed.
|
||||
When M is nonzero, the characters displayed at the
|
||||
beginning of each line are replaced with the first M characters of the line,
|
||||
The number of header lines is set to \fIL\fP.
|
||||
If \fIL\fP is 0, header lines are disabled.
|
||||
If \fIL\fP is empty or missing, the number of header lines is unchanged.
|
||||
The number of header columns is set to \fIC\fP.
|
||||
If \fIC\fP is 0, header columns are disabled.
|
||||
If \fIC\fP is empty or missing, the number of header columns is unchanged.
|
||||
The first header line is set to line number \fIN\fP in the file.
|
||||
If \fIN\fP is empty or missing, it is taken to be
|
||||
the number of the line currently displayed in the first line of the screen
|
||||
(if the \-\-header command has been issued from within
|
||||
.BR less "),"
|
||||
or 1 (if the \-\-header option has been given on the command line).
|
||||
The special form "\-\-header=\-" disables header lines and header columns,
|
||||
and is equivalent to "\-\-header=0,0".
|
||||
.PP
|
||||
When \fIL\fP is nonzero, the first \fIL\fP lines at the top
|
||||
of the screen are replaced with the \fIL\fP lines of the file beginning at line \fIN\fP,
|
||||
regardless of what part of the file is being viewed.
|
||||
When header lines are displayed, any file contents before the header line cannot be viewed.
|
||||
When \fIC\fP is nonzero, the first \fIC\fP characters displayed at the
|
||||
beginning of each line are replaced with the first \fIC\fP characters of the line,
|
||||
even if the rest of the line is scrolled horizontally.
|
||||
If either N or M is zero,
|
||||
.B less
|
||||
stops displaying header lines or columns, respectively.
|
||||
(Note that it may be necessary to change the setting of the \-j option
|
||||
to ensure that the target line is not obscured by the header line(s).)
|
||||
.RE
|
||||
.IP "\-\-incsearch"
|
||||
Subsequent search commands will be "incremental"; that is,
|
||||
.B less
|
||||
|
|
@ -1221,6 +1370,21 @@ to specify a control character.
|
|||
Sets the minimum width of the line number field when the \-N option is in effect
|
||||
to \fIn\fP characters.
|
||||
The default is 7.
|
||||
.IP "\-\-match-shift=\fIn\fP"
|
||||
When \-S is in effect, if a search match is not visible
|
||||
because it is shifted to the left or right of the currently
|
||||
visible screen, the text will horizontally shift
|
||||
to ensure that the search match is visible.
|
||||
This option selects the column in which the first character
|
||||
of the search match will be placed after the shift.
|
||||
In other words, there will be \fIn\fP characters visible
|
||||
to the left of the search match.
|
||||
|
||||
Alternately, the number may be specified as a fraction of the width
|
||||
of the screen, starting with a decimal point: \&.5 is half of the
|
||||
screen width, \&.3 is three tenths of the screen width, and so on.
|
||||
If the number is specified as a fraction, the actual number of
|
||||
scroll positions is recalculated if the terminal window is resized.
|
||||
.IP "\-\-modelines=\fIn\fP"
|
||||
.RS
|
||||
Before displaying a file,
|
||||
|
|
@ -1252,8 +1416,12 @@ See the \-\-tabs description for acceptable values of \fIn\fP.
|
|||
Enables mouse input:
|
||||
scrolling the mouse wheel down moves forward in the file,
|
||||
scrolling the mouse wheel up moves backwards in the file,
|
||||
and clicking the mouse sets the "#" mark to the line
|
||||
where the mouse is clicked.
|
||||
left-click sets the "#" mark to the line where the mouse is clicked,
|
||||
and right-click (or any other) returns to the "#" mark position.
|
||||
If a left-click is performed with the mouse cursor on an OSC 8 hyperlink,
|
||||
the hyperlink is selected as if by the \(haO\(haN command.
|
||||
If a left-click is performed with the mouse cursor on an OSC 8 hyperlink
|
||||
which is already selected, the hyperlink is opened as if by the \(haO\(haO command.
|
||||
The number of lines to scroll when the wheel is moved
|
||||
can be set by the \-\-wheel-lines option.
|
||||
Mouse input works only on terminals which support X11 mouse reporting,
|
||||
|
|
@ -1276,6 +1444,10 @@ Normally, a string may appear multiple times.
|
|||
.IP "\-\-no-number-headers"
|
||||
Header lines (defined via the \-\-header option) are not assigned line numbers.
|
||||
Line number 1 is assigned to the first line after any header lines.
|
||||
.IP "\-\-no-search-header-lines"
|
||||
Searches do not include header lines, but still include header columns.
|
||||
.IP "\-\-no-search-header-columns"
|
||||
Searches do not include header columns, but still include header lines.
|
||||
.IP "\-\-no-search-headers"
|
||||
Searches do not include header lines or header columns.
|
||||
.IP "\-\-no-vbell"
|
||||
|
|
@ -1363,9 +1535,7 @@ This allows a dollar sign to be included in option strings.
|
|||
Enables colored text in various places.
|
||||
The \-D option can be used to change the colors.
|
||||
Colored text works only if the terminal supports
|
||||
ANSI color escape sequences (as defined in ECMA-48 SGR;
|
||||
see
|
||||
.br
|
||||
ANSI color escape sequences (as defined in
|
||||
.nh
|
||||
https://www.ecma-international.org/publications-and-standards/standards/ecma-48).
|
||||
.hy
|
||||
|
|
@ -1449,7 +1619,7 @@ If it matches more than one filename, the first match
|
|||
is entered into the command line.
|
||||
Repeated TABs will cycle thru the other matching filenames.
|
||||
If the completed filename is a directory, a "/" is appended to the filename.
|
||||
(On MS-DOS systems, a "\e" is appended.)
|
||||
(On MS-DOS and Windows systems, a "\e" is appended.)
|
||||
The environment variable LESSSEPARATOR can be used to specify a
|
||||
different character to append to a directory name.
|
||||
.IP "BACKTAB [ ESC-TAB ]"
|
||||
|
|
@ -1458,7 +1628,7 @@ Like, TAB, but cycles in the reverse direction thru the matching filenames.
|
|||
Complete the partial filename to the left of the cursor.
|
||||
If it matches more than one filename, all matches are entered into
|
||||
the command line (if they fit).
|
||||
.IP "\(haU (Unix and OS/2) or ESC (MS-DOS)"
|
||||
.IP "\(haU (Unix and OS/2) or ESC (MS-DOS and Windows)"
|
||||
Delete the entire command line,
|
||||
or cancel the command if the command line is empty.
|
||||
If you have changed your line-kill character in Unix to something
|
||||
|
|
@ -1741,7 +1911,7 @@ Selects the UTF-8 encoding of the ISO 10646 character set.
|
|||
UTF-8 is special in that it supports multi-byte characters in the input file.
|
||||
It is the only character set that supports multi-byte characters.
|
||||
.IP windows
|
||||
Selects a character set appropriate for Microsoft Windows (cp 1251).
|
||||
Selects a character set appropriate for Microsoft Windows (cp 1252).
|
||||
.PP
|
||||
In rare cases, it may be desired to tailor
|
||||
.B less
|
||||
|
|
@ -1794,7 +1964,7 @@ variables.
|
|||
.PP
|
||||
Finally, if the
|
||||
.I setlocale
|
||||
interface is also not available, the default character set is latin1.
|
||||
interface is also not available, the default character set is utf-8.
|
||||
.PP
|
||||
Control and binary characters are displayed in standout (reverse video).
|
||||
Each such character is displayed in caret notation if possible
|
||||
|
|
@ -1924,6 +2094,10 @@ The line to be used is determined by the \fIX\fP, as with the %b option.
|
|||
Replaced by the line number of the last line in the input file.
|
||||
.IP "%m"
|
||||
Replaced by the total number of input files.
|
||||
.IP "%o"
|
||||
Replaced by the URI of the currently selected OSC 8 hyperlink,
|
||||
or a question mark if no hyperlink is selected.
|
||||
This is used by OSC 8 handlers as explained in the \(haO\(haO command description.
|
||||
.IP "%p\fIX\fP"
|
||||
Replaced by the percent into the current input file, based on byte offsets.
|
||||
The line used is determined by the \fIX\fP as with the %b option.
|
||||
|
|
@ -2015,7 +2189,7 @@ Notice how each question mark has a matching period,
|
|||
and how the % after the %pt
|
||||
is included literally by escaping it with a backslash.
|
||||
.sp
|
||||
?n?f%f\ .?m(%T %i of %m)\ ..?e(END)\ ?x-\ Next\e:\ %x..%t";
|
||||
?n?f%f\ .?m(%T %i of %m)\ ..?e(END)\ ?x-\ Next\e:\ %x..%t
|
||||
.sp
|
||||
This prints the filename if this is the first prompt in a file,
|
||||
followed by the "file N of N" message if there is more
|
||||
|
|
@ -2063,33 +2237,53 @@ changed to modify this default.
|
|||
When the environment variable LESSSECURE is set to 1,
|
||||
.B less
|
||||
runs in a "secure" mode.
|
||||
This means these features are disabled:
|
||||
.RS
|
||||
.IP "!"
|
||||
the shell command
|
||||
.IP "#"
|
||||
the pshell command
|
||||
.IP "|"
|
||||
the pipe command
|
||||
.IP ":e"
|
||||
the examine command.
|
||||
.IP "v"
|
||||
the editing command
|
||||
.IP "s \-o"
|
||||
log files
|
||||
.IP "\-k"
|
||||
use of lesskey files
|
||||
.IP "\-t"
|
||||
use of tags files
|
||||
.IP
|
||||
metacharacters in filenames, such as *
|
||||
.IP
|
||||
filename completion (TAB, \(haL)
|
||||
.IP
|
||||
In this mode, these features are disabled:
|
||||
.IP "edit" 10
|
||||
the edit command (v)
|
||||
.IP "examine"
|
||||
the examine command (:e)
|
||||
.IP "glob"
|
||||
metacharacters such as * in filenames,
|
||||
.br
|
||||
and filename completion (TAB, \(haL)
|
||||
.IP "history"
|
||||
history file
|
||||
.RE
|
||||
.IP "lesskey"
|
||||
use of lesskey files (-k and \-\-lesskey-src)
|
||||
.IP "lessopen"
|
||||
input preprocessor (LESSOPEN environment variable)
|
||||
.IP "logfile"
|
||||
log files (s and \-o)
|
||||
.IP "osc8"
|
||||
opening OSC 8 links (\(haO\(haO)
|
||||
.IP "pipe"
|
||||
the pipe command (|)
|
||||
.IP "shell"
|
||||
the shell and pshell commands (! and #)
|
||||
.IP "stop"
|
||||
stopping
|
||||
.B less
|
||||
via a SIGSTOP signal
|
||||
.IP "tags"
|
||||
use of tags files (-t)
|
||||
.PP
|
||||
The LESSSECURE_ALLOW environment variable can be set to a comma-separated list
|
||||
of names of features which are selectively enabled when LESSSECURE is set.
|
||||
Each feature name is the first word in each line in the above list.
|
||||
A feature name may be abbreviated as long as the abbreviation is unambiguous.
|
||||
For example, if
|
||||
.nh
|
||||
LESSSECURE=1
|
||||
.hy
|
||||
and
|
||||
.nh
|
||||
LESSSECURE_ALLOW=hist,edit
|
||||
.hy
|
||||
were set, all of the above features would be disabled
|
||||
except for history files and the edit command.
|
||||
.PP
|
||||
Less can also be compiled to be permanently in "secure" mode.
|
||||
In that case, the LESSSECURE and LESSSECURE_ALLOW variables are ignored.
|
||||
.
|
||||
.SH "COMPATIBILITY WITH MORE"
|
||||
If the environment variable LESS_IS_MORE is set to 1,
|
||||
|
|
@ -2210,6 +2404,8 @@ file.
|
|||
Name of the default
|
||||
.I "lesskey binary"
|
||||
file. (Not used if "$LESSKEYIN" exists.)
|
||||
.IP LESSKEY_CONTENT
|
||||
The value is parsed as if it were the parameter of a \-\-lesskey-content option.
|
||||
.IP LESSKEYIN_SYSTEM
|
||||
Name of the default system-wide
|
||||
.I "lesskey source"
|
||||
|
|
@ -2230,6 +2426,9 @@ Command line to invoke the (optional) input-preprocessor.
|
|||
.IP LESSSECURE
|
||||
Runs less in "secure" mode.
|
||||
See discussion under SECURITY.
|
||||
.IP LESSSECURE_ALLOW
|
||||
Enables individual features which are normally disabled by LESSSECURE.
|
||||
See discussion under SECURITY.
|
||||
.IP LESSSEPARATOR
|
||||
String to be appended to a directory name in filename completion.
|
||||
.IP LESSUTFBINFMT
|
||||
|
|
@ -2264,9 +2463,22 @@ The default is 4000 (4 seconds).
|
|||
Emulate the
|
||||
.BR more (1)
|
||||
command.
|
||||
.IP LESS_OSC8_xxx
|
||||
Where "xxx" is a URI scheme such as "http" or "file",
|
||||
sets an OSC 8 handler for opening OSC 8 links containing a URI with that scheme.
|
||||
.IP LESS_OSC8_ANY
|
||||
Sets an OSC 8 handler for opening OSC 8 links for which there is
|
||||
no specific LESS_OSC8_xxx handler set for the "xxx" scheme.
|
||||
.IP LESS_TERMCAP_xx
|
||||
Where "xx" is any two characters, overrides the definition
|
||||
of the termcap "xx" capability for the terminal.
|
||||
.IP LESS_UNSUPPORT
|
||||
A space-separated list of command line options.
|
||||
These options will be ignored (with no error message) if they appear
|
||||
on the command line or in the LESS environment variable.
|
||||
Options listed in LESS_UNSUPPORT can still be changed by the \- and \-\- commands.
|
||||
Each option in LESS_UNSUPPORT is a dash followed by a single character
|
||||
option letter, or two dashes followed by a long option name.
|
||||
.IP LINES
|
||||
Sets the number of lines on the screen.
|
||||
Takes precedence over the number of lines specified by the TERM variable.
|
||||
|
|
@ -2280,7 +2492,7 @@ automatically when running in
|
|||
.BR more "-compatible mode."
|
||||
.IP PATH
|
||||
User's search path (used to find a lesskey file
|
||||
on MS-DOS and OS/2 systems).
|
||||
on MS-DOS, Windows, and OS/2 systems).
|
||||
.IP SHELL
|
||||
The shell used to execute the !\& command, as well as to expand filenames.
|
||||
.IP TERM
|
||||
|
|
@ -2303,7 +2515,7 @@ Possible location of the history file; see the description of the LESSHISTFILE e
|
|||
.BR lessecho (1)
|
||||
.
|
||||
.SH COPYRIGHT
|
||||
Copyright (C) 1984-2023 Mark Nudelman
|
||||
Copyright (C) 1984-2024 Mark Nudelman
|
||||
.PP
|
||||
less is part of the GNU project and is free software.
|
||||
You can redistribute it and/or modify it
|
||||
|
|
@ -2328,8 +2540,13 @@ See the GNU General Public License for more details.
|
|||
.
|
||||
Mark Nudelman
|
||||
.br
|
||||
Report bugs at https://github.com/gwsw/less/issues.
|
||||
Report bugs at
|
||||
.nh
|
||||
https://github.com/gwsw/less/issues.
|
||||
.hy
|
||||
.br
|
||||
For more information, see the less homepage at
|
||||
.br
|
||||
https://greenwoodsoftware.com/less
|
||||
.nh
|
||||
https://greenwoodsoftware.com/less.
|
||||
.hy
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -133,13 +133,13 @@ static long lstrtol(char *s, char **pend, int radix)
|
|||
return (n);
|
||||
}
|
||||
|
||||
static void add_metachar(int ch)
|
||||
static void add_metachar(char ch)
|
||||
{
|
||||
if (num_metachars+1 >= size_metachars)
|
||||
{
|
||||
char *p;
|
||||
size_metachars = (size_metachars > 0) ? size_metachars*2 : 16;
|
||||
p = (char *) malloc(size_metachars);
|
||||
p = (char *) malloc((size_t) size_metachars);
|
||||
if (p == NULL)
|
||||
pr_error("Cannot allocate memory");
|
||||
|
||||
|
|
@ -192,7 +192,7 @@ int main(int argc, char *argv[])
|
|||
closequote = *++arg;
|
||||
break;
|
||||
case 'd':
|
||||
closequote = lstrtol(++arg, &s, 0);
|
||||
closequote = (char) lstrtol(++arg, &s, 0);
|
||||
if (s == arg)
|
||||
pr_error("Missing number after -d");
|
||||
break;
|
||||
|
|
@ -203,7 +203,7 @@ int main(int argc, char *argv[])
|
|||
meta_escape = arg;
|
||||
break;
|
||||
case 'f':
|
||||
meta_escape_buf[0] = lstrtol(++arg, &s, 0);
|
||||
meta_escape_buf[0] = (char) lstrtol(++arg, &s, 0);
|
||||
meta_escape_buf[1] = '\0';
|
||||
meta_escape = meta_escape_buf;
|
||||
if (s == arg)
|
||||
|
|
@ -213,7 +213,7 @@ int main(int argc, char *argv[])
|
|||
openquote = *++arg;
|
||||
break;
|
||||
case 'p':
|
||||
openquote = lstrtol(++arg, &s, 0);
|
||||
openquote = (char) lstrtol(++arg, &s, 0);
|
||||
if (s == arg)
|
||||
pr_error("Missing number after -p");
|
||||
break;
|
||||
|
|
@ -221,7 +221,7 @@ int main(int argc, char *argv[])
|
|||
add_metachar(*++arg);
|
||||
break;
|
||||
case 'n':
|
||||
add_metachar(lstrtol(++arg, &s, 0));
|
||||
add_metachar((char) lstrtol(++arg, &s, 0));
|
||||
if (s == arg)
|
||||
pr_error("Missing number after -n");
|
||||
break;
|
||||
|
|
@ -245,6 +245,7 @@ int main(int argc, char *argv[])
|
|||
return (0);
|
||||
}
|
||||
pr_error("Invalid option after --");
|
||||
return (0);
|
||||
default:
|
||||
pr_error("Invalid option letter");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.TH LESSECHO 1 "Version 643: 20 Jul 2023"
|
||||
.TH LESSECHO 1 "Version 668: 06 Oct 2024"
|
||||
.SH NAME
|
||||
lessecho \- expand metacharacters
|
||||
.SH SYNOPSIS
|
||||
|
|
@ -9,6 +9,10 @@ lessecho \- expand metacharacters
|
|||
is a program that simply echos its arguments on standard output.
|
||||
But any metacharacter in the output is preceded by an "escape"
|
||||
character, which by default is a backslash.
|
||||
.B lessecho
|
||||
is invoked internally by
|
||||
.BR less ,
|
||||
and is not intended to be used directly by humans.
|
||||
.SH OPTIONS
|
||||
A summary of options is included below.
|
||||
.TP
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -87,24 +87,24 @@
|
|||
#include "lesskey.h"
|
||||
#include "cmd.h"
|
||||
|
||||
char fileheader[] = {
|
||||
constant char fileheader[] = {
|
||||
C0_LESSKEY_MAGIC,
|
||||
C1_LESSKEY_MAGIC,
|
||||
C2_LESSKEY_MAGIC,
|
||||
C3_LESSKEY_MAGIC
|
||||
};
|
||||
char filetrailer[] = {
|
||||
constant char filetrailer[] = {
|
||||
C0_END_LESSKEY_MAGIC,
|
||||
C1_END_LESSKEY_MAGIC,
|
||||
C2_END_LESSKEY_MAGIC
|
||||
};
|
||||
char cmdsection[1] = { CMD_SECTION };
|
||||
char editsection[1] = { EDIT_SECTION };
|
||||
char varsection[1] = { VAR_SECTION };
|
||||
char endsection[1] = { END_SECTION };
|
||||
constant char cmdsection[1] = { CMD_SECTION };
|
||||
constant char editsection[1] = { EDIT_SECTION };
|
||||
constant char varsection[1] = { VAR_SECTION };
|
||||
constant char endsection[1] = { END_SECTION };
|
||||
|
||||
char *infile = NULL;
|
||||
char *outfile = NULL ;
|
||||
constant char *infile = NULL;
|
||||
constant char *outfile = NULL;
|
||||
|
||||
extern char version[];
|
||||
|
||||
|
|
@ -114,14 +114,14 @@ static void usage(void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
void lesskey_parse_error(char *s)
|
||||
void lesskey_parse_error(constant char *s)
|
||||
{
|
||||
fprintf(stderr, "%s\n", s);
|
||||
}
|
||||
|
||||
int lstrtoi(char *buf, char **ebuf, int radix)
|
||||
int lstrtoi(constant char *buf, constant char **ebuf, int radix)
|
||||
{
|
||||
return (int) strtol(buf, ebuf, radix);
|
||||
return (int) strtol(buf, (char**)ebuf, radix);
|
||||
}
|
||||
|
||||
void out_of_memory(void)
|
||||
|
|
@ -130,7 +130,7 @@ void out_of_memory(void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
void * ecalloc(int count, unsigned int size)
|
||||
void * ecalloc(size_t count, size_t size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ void * ecalloc(int count, unsigned int size)
|
|||
return (p);
|
||||
}
|
||||
|
||||
static char * mkpathname(char *dirname, char *filename)
|
||||
static char * mkpathname(constant char *dirname, constant char *filename)
|
||||
{
|
||||
char *pathname;
|
||||
|
||||
|
|
@ -154,9 +154,9 @@ static char * mkpathname(char *dirname, char *filename)
|
|||
/*
|
||||
* Figure out the name of a default file (in the user's HOME directory).
|
||||
*/
|
||||
char * homefile(char *filename)
|
||||
char * homefile(constant char *filename)
|
||||
{
|
||||
char *p;
|
||||
constant char *p;
|
||||
char *pathname;
|
||||
|
||||
if ((p = getenv("HOME")) != NULL && *p != '\0')
|
||||
|
|
@ -176,9 +176,9 @@ char * homefile(char *filename)
|
|||
/*
|
||||
* Parse command line arguments.
|
||||
*/
|
||||
static void parse_args(int argc, char **argv)
|
||||
static void parse_args(int argc, constant char **argv)
|
||||
{
|
||||
char *arg;
|
||||
constant char *arg;
|
||||
|
||||
outfile = NULL;
|
||||
while (--argc > 0)
|
||||
|
|
@ -246,7 +246,7 @@ static void parse_args(int argc, char **argv)
|
|||
/*
|
||||
* Output some bytes.
|
||||
*/
|
||||
static void fputbytes(FILE *fd, char *buf, int len)
|
||||
static void fputbytes(FILE *fd, constant char *buf, size_t len)
|
||||
{
|
||||
while (len-- > 0)
|
||||
{
|
||||
|
|
@ -258,23 +258,30 @@ static void fputbytes(FILE *fd, char *buf, int len)
|
|||
/*
|
||||
* Output an integer, in special KRADIX form.
|
||||
*/
|
||||
static void fputint(FILE *fd, unsigned int val)
|
||||
static void fputint(FILE *fd, size_t val)
|
||||
{
|
||||
char c;
|
||||
char c1, c2;
|
||||
|
||||
if (val >= KRADIX*KRADIX)
|
||||
{
|
||||
fprintf(stderr, "error: cannot write %d, max %d\n",
|
||||
val, KRADIX*KRADIX);
|
||||
fprintf(stderr, "error: cannot write %ld, max %ld\n",
|
||||
(long) val, (long) (KRADIX*KRADIX));
|
||||
exit(1);
|
||||
}
|
||||
c = val % KRADIX;
|
||||
fwrite(&c, sizeof(char), 1, fd);
|
||||
c = val / KRADIX;
|
||||
fwrite(&c, sizeof(char), 1, fd);
|
||||
c1 = (char) (val % KRADIX);
|
||||
val /= KRADIX;
|
||||
c2 = (char) (val % KRADIX);
|
||||
val /= KRADIX;
|
||||
if (val != 0) {
|
||||
fprintf(stderr, "error: %ld exceeds max integer size (%ld)\n",
|
||||
(long) val, (long) (KRADIX*KRADIX));
|
||||
exit(1);
|
||||
}
|
||||
fwrite(&c1, sizeof(char), 1, fd);
|
||||
fwrite(&c2, sizeof(char), 1, fd);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int main(int argc, constant char *argv[])
|
||||
{
|
||||
struct lesskey_tables tables;
|
||||
FILE *out;
|
||||
|
|
@ -287,8 +294,8 @@ int main(int argc, char *argv[])
|
|||
* If there is no HOME environment variable,
|
||||
* try the concatenation of HOMEDRIVE + HOMEPATH.
|
||||
*/
|
||||
char *drive = getenv("HOMEDRIVE");
|
||||
char *path = getenv("HOMEPATH");
|
||||
constant char *drive = getenv("HOMEDRIVE");
|
||||
constant char *path = getenv("HOMEPATH");
|
||||
if (drive != NULL && path != NULL)
|
||||
{
|
||||
char *env = (char *) ecalloc(strlen(drive) +
|
||||
|
|
@ -338,16 +345,16 @@ int main(int argc, char *argv[])
|
|||
/* Command key section */
|
||||
fputbytes(out, cmdsection, sizeof(cmdsection));
|
||||
fputint(out, tables.cmdtable.buf.end);
|
||||
fputbytes(out, (char *)tables.cmdtable.buf.data, tables.cmdtable.buf.end);
|
||||
fputbytes(out, xbuf_char_data(&tables.cmdtable.buf), tables.cmdtable.buf.end);
|
||||
/* Edit key section */
|
||||
fputbytes(out, editsection, sizeof(editsection));
|
||||
fputint(out, tables.edittable.buf.end);
|
||||
fputbytes(out, (char *)tables.edittable.buf.data, tables.edittable.buf.end);
|
||||
fputbytes(out, xbuf_char_data(&tables.edittable.buf), tables.edittable.buf.end);
|
||||
|
||||
/* Environment variable section */
|
||||
fputbytes(out, varsection, sizeof(varsection));
|
||||
fputint(out, tables.vartable.buf.end);
|
||||
fputbytes(out, (char *)tables.vartable.buf.data, tables.vartable.buf.end);
|
||||
fputbytes(out, xbuf_char_data(&tables.vartable.buf), tables.vartable.buf.end);
|
||||
|
||||
/* File trailer */
|
||||
fputbytes(out, endsection, sizeof(endsection));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
* For more information, see the README file.
|
||||
*/
|
||||
|
||||
#include "lang.h"
|
||||
#include "xbuf.h"
|
||||
|
||||
/*
|
||||
|
|
@ -41,13 +42,13 @@
|
|||
|
||||
struct lesskey_cmdname
|
||||
{
|
||||
char *cn_name;
|
||||
constant char *cn_name;
|
||||
int cn_action;
|
||||
};
|
||||
|
||||
struct lesskey_table
|
||||
{
|
||||
struct lesskey_cmdname *names;
|
||||
constant struct lesskey_cmdname *names;
|
||||
struct xbuffer buf;
|
||||
int is_var;
|
||||
};
|
||||
|
|
@ -60,4 +61,19 @@ struct lesskey_tables
|
|||
struct lesskey_table vartable;
|
||||
};
|
||||
|
||||
extern int parse_lesskey(char *infile, struct lesskey_tables *tables);
|
||||
extern int parse_lesskey(constant char *infile, struct lesskey_tables *tables);
|
||||
extern int parse_lesskey_content(constant char *content, struct lesskey_tables *tables);
|
||||
|
||||
/* keep in sync with less.h */
|
||||
#if HAVE_SNPRINTF
|
||||
#define SNPRINTF1(str, size, fmt, v1) snprintf((str), (size), (fmt), (v1))
|
||||
#define SNPRINTF2(str, size, fmt, v1, v2) snprintf((str), (size), (fmt), (v1), (v2))
|
||||
#define SNPRINTF3(str, size, fmt, v1, v2, v3) snprintf((str), (size), (fmt), (v1), (v2), (v3))
|
||||
#define SNPRINTF4(str, size, fmt, v1, v2, v3, v4) snprintf((str), (size), (fmt), (v1), (v2), (v3), (v4))
|
||||
#else
|
||||
/* Use unsafe sprintf if we don't have snprintf. */
|
||||
#define SNPRINTF1(str, size, fmt, v1) sprintf((str), (fmt), (v1))
|
||||
#define SNPRINTF2(str, size, fmt, v1, v2) sprintf((str), (fmt), (v1), (v2))
|
||||
#define SNPRINTF3(str, size, fmt, v1, v2, v3) sprintf((str), (fmt), (v1), (v2), (v3))
|
||||
#define SNPRINTF4(str, size, fmt, v1, v2, v3, v4) sprintf((str), (fmt), (v1), (v2), (v3), (v4))
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
'\" t
|
||||
.TH LESSKEY 1 "Version 643: 20 Jul 2023"
|
||||
.TH LESSKEY 1 "Version 668: 06 Oct 2024"
|
||||
.SH NAME
|
||||
lesskey \- customize key bindings for less
|
||||
.SH "SYNOPSIS (deprecated)"
|
||||
|
|
@ -122,14 +122,15 @@ For example, see the "{" and ":t" commands in the example below.
|
|||
The extra string has a special meaning for the "quit" action:
|
||||
when
|
||||
.B less
|
||||
quits, the first character of the extra string is used as its exit status.
|
||||
quits, the ASCII value of the first character of the extra string
|
||||
is used as its exit status.
|
||||
.
|
||||
.SH EXAMPLE
|
||||
The following input file describes the set of
|
||||
default command keys used by
|
||||
.BR less .
|
||||
Documentation on each command can be found in the
|
||||
.less
|
||||
.B less
|
||||
man page, under the key sequence which invokes the command.
|
||||
.sp
|
||||
.RS 5m
|
||||
|
|
@ -181,8 +182,6 @@ g goto-line
|
|||
\ee< goto-line
|
||||
p percent
|
||||
% percent
|
||||
\ee[ left-scroll
|
||||
\ee] right-scroll
|
||||
\ee( left-scroll
|
||||
\ee) right-scroll
|
||||
\ekl left-scroll
|
||||
|
|
@ -213,11 +212,16 @@ n repeat-search
|
|||
\een repeat-search-all
|
||||
N reverse-search
|
||||
\eeN reverse-search-all
|
||||
^O^N osc8-forw-search
|
||||
^On osc8-forw-search
|
||||
^O^P osc8-back-search
|
||||
^Op osc8-back-search
|
||||
^O^O osc8-open
|
||||
& filter
|
||||
m set-mark
|
||||
M set-mark-bottom
|
||||
\eem clear-mark
|
||||
' goto-mark
|
||||
\&' goto-mark
|
||||
^X^X goto-mark
|
||||
E examine
|
||||
:e examine
|
||||
|
|
@ -367,6 +371,24 @@ it should be appended to the end of the preceding line.
|
|||
(It cannot be added to the beginning of the += string because space after
|
||||
the equals sign is ignored, as noted above.)
|
||||
.
|
||||
.sp
|
||||
In the string after the = sign, a substring of the form ${NAME}
|
||||
is replaced with the value of the environment variable "NAME".
|
||||
The value of the variable may come from either the system environment,
|
||||
an earlier lesskey file, or an earlier definition in the current lesskey file.
|
||||
Simple text replacements can be performed by using
|
||||
the syntax ${NAME/STRING/REPL}.
|
||||
This replaces all instances of "STRING" in the named
|
||||
environment variable with the text "REPL".
|
||||
STRING is matched using a simple text comparison;
|
||||
no metacharacters are supported.
|
||||
An instance of slash or right curly bracket in STRING or REPL
|
||||
must be escaped by preceding it with \fItwo\fP backslashes.
|
||||
If REPL is an empty string, all instances of STRING are removed.
|
||||
A slash immediately before the right curly bracket may be omitted.
|
||||
Multiple replacements may be performed by using
|
||||
the syntax ${NAME/STRING1/REPL1/STRING2/REPL2} and so on.
|
||||
.
|
||||
.SH CONDITIONAL CONFIGURATION
|
||||
If a line begins with #version followed by a relational operator and a version number,
|
||||
the remainder of the line is parsed if and only if the running version of
|
||||
|
|
@ -410,7 +432,7 @@ In those older versions, all #version lines are ignored.
|
|||
.
|
||||
.SH EXAMPLE
|
||||
The following input file sets the \-i and \-S options when
|
||||
.less
|
||||
.B less
|
||||
is run and, on version 595 and higher, adds a \-\-color option.
|
||||
.sp
|
||||
.nf
|
||||
|
|
@ -430,7 +452,7 @@ which start with a NUL character (0).
|
|||
This NUL character should be represented as \e340 in a lesskey file.
|
||||
.
|
||||
.SH COPYRIGHT
|
||||
Copyright (C) 1984-2023 Mark Nudelman
|
||||
Copyright (C) 1984-2024 Mark Nudelman
|
||||
.PP
|
||||
less is part of the GNU project and is free software.
|
||||
You can redistribute it and/or modify it
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -20,16 +20,16 @@
|
|||
|
||||
extern void lesskey_parse_error(char *msg);
|
||||
extern char *homefile(char *filename);
|
||||
extern void *ecalloc(int count, unsigned int size);
|
||||
extern void *ecalloc(size_t count, size_t size);
|
||||
extern int lstrtoi(char *str, char **end, int radix);
|
||||
extern char version[];
|
||||
|
||||
static int linenum;
|
||||
static int errors;
|
||||
static int less_version = 0;
|
||||
static char *lesskey_file;
|
||||
static char *lesskey_file = NULL;
|
||||
|
||||
static struct lesskey_cmdname cmdnames[] =
|
||||
static constant struct lesskey_cmdname cmdnames[] =
|
||||
{
|
||||
{ "back-bracket", A_B_BRACKET },
|
||||
{ "back-line", A_B_LINE },
|
||||
|
|
@ -39,6 +39,7 @@ static struct lesskey_cmdname cmdnames[] =
|
|||
{ "back-search", A_B_SEARCH },
|
||||
{ "back-window", A_B_WINDOW },
|
||||
{ "clear-mark", A_CLRMARK },
|
||||
{ "clear-search", A_CLR_SEARCH },
|
||||
{ "debug", A_DEBUG },
|
||||
{ "digit", A_DIGIT },
|
||||
{ "display-flag", A_DISP_OPTION },
|
||||
|
|
@ -52,13 +53,13 @@ static struct lesskey_cmdname cmdnames[] =
|
|||
{ "flush-repaint", A_FREPAINT },
|
||||
{ "forw-bracket", A_F_BRACKET },
|
||||
{ "forw-forever", A_F_FOREVER },
|
||||
{ "forw-until-hilite", A_F_UNTIL_HILITE },
|
||||
{ "forw-line", A_F_LINE },
|
||||
{ "forw-line-force", A_FF_LINE },
|
||||
{ "forw-screen", A_F_SCREEN },
|
||||
{ "forw-screen-force", A_FF_SCREEN },
|
||||
{ "forw-scroll", A_F_SCROLL },
|
||||
{ "forw-search", A_F_SEARCH },
|
||||
{ "forw-until-hilite", A_F_UNTIL_HILITE },
|
||||
{ "forw-window", A_F_WINDOW },
|
||||
{ "goto-end", A_GOEND },
|
||||
{ "goto-end-buffered", A_GOEND_BUF },
|
||||
|
|
@ -70,12 +71,16 @@ static struct lesskey_cmdname cmdnames[] =
|
|||
{ "left-scroll", A_LSHIFT },
|
||||
{ "next-file", A_NEXT_FILE },
|
||||
{ "next-tag", A_NEXT_TAG },
|
||||
{ "noaction", A_NOACTION },
|
||||
{ "no-scroll", A_LLSHIFT },
|
||||
{ "noaction", A_NOACTION },
|
||||
{ "osc8-forw-search", A_OSC8_F_SEARCH },
|
||||
{ "osc8-back-search", A_OSC8_B_SEARCH },
|
||||
{ "osc8-open", A_OSC8_OPEN },
|
||||
{ "percent", A_PERCENT },
|
||||
{ "pipe", A_PIPE },
|
||||
{ "prev-file", A_PREV_FILE },
|
||||
{ "prev-tag", A_PREV_TAG },
|
||||
{ "pshell", A_PSHELL },
|
||||
{ "quit", A_QUIT },
|
||||
{ "remove-file", A_REMOVE_FILE },
|
||||
{ "repaint", A_REPAINT },
|
||||
|
|
@ -88,18 +93,16 @@ static struct lesskey_cmdname cmdnames[] =
|
|||
{ "set-mark", A_SETMARK },
|
||||
{ "set-mark-bottom", A_SETMARKBOT },
|
||||
{ "shell", A_SHELL },
|
||||
{ "pshell", A_PSHELL },
|
||||
{ "status", A_STAT },
|
||||
{ "toggle-flag", A_OPT_TOGGLE },
|
||||
{ "toggle-option", A_OPT_TOGGLE },
|
||||
{ "undo-hilite", A_UNDO_SEARCH },
|
||||
{ "clear-search", A_CLR_SEARCH },
|
||||
{ "version", A_VERSION },
|
||||
{ "visual", A_VISUAL },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static struct lesskey_cmdname editnames[] =
|
||||
static constant struct lesskey_cmdname editnames[] =
|
||||
{
|
||||
{ "back-complete", EC_B_COMPLETE },
|
||||
{ "backspace", EC_BACKSPACE },
|
||||
|
|
@ -127,12 +130,16 @@ static struct lesskey_cmdname editnames[] =
|
|||
/*
|
||||
* Print a parse error message.
|
||||
*/
|
||||
static void parse_error(char *fmt, char *arg1)
|
||||
static void parse_error(constant char *fmt, constant char *arg1)
|
||||
{
|
||||
char buf[1024];
|
||||
int n = snprintf(buf, sizeof(buf), "%s: line %d: ", lesskey_file, linenum);
|
||||
if (n >= 0 && n < sizeof(buf))
|
||||
snprintf(buf+n, sizeof(buf)-n, fmt, arg1);
|
||||
int n = SNPRINTF2(buf, sizeof(buf), "%s: line %d: ", lesskey_file, linenum);
|
||||
if (n >= 0)
|
||||
{
|
||||
size_t len = (size_t) n;
|
||||
if (len < sizeof(buf))
|
||||
SNPRINTF1(buf+len, sizeof(buf)-len, fmt, arg1);
|
||||
}
|
||||
++errors;
|
||||
lesskey_parse_error(buf);
|
||||
}
|
||||
|
|
@ -159,7 +166,7 @@ static void init_tables(struct lesskey_tables *tables)
|
|||
|
||||
#define CHAR_STRING_LEN 8
|
||||
|
||||
static char * char_string(char *buf, int ch, int lit)
|
||||
static constant char * char_string(char *buf, char ch, int lit)
|
||||
{
|
||||
if (lit || (ch >= 0x20 && ch < 0x7f))
|
||||
{
|
||||
|
|
@ -167,7 +174,7 @@ static char * char_string(char *buf, int ch, int lit)
|
|||
buf[1] = '\0';
|
||||
} else
|
||||
{
|
||||
snprintf(buf, CHAR_STRING_LEN, "\\x%02x", ch);
|
||||
SNPRINTF1(buf, CHAR_STRING_LEN, "\\x%02x", ch);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
|
@ -185,7 +192,7 @@ static char * increment_pointer(char *p)
|
|||
/*
|
||||
* Parse one character of a string.
|
||||
*/
|
||||
static char * tstr(char **pp, int xlate)
|
||||
static constant char * tstr(char **pp, int xlate)
|
||||
{
|
||||
char *p;
|
||||
char ch;
|
||||
|
|
@ -209,7 +216,7 @@ static char * tstr(char **pp, int xlate)
|
|||
ch = 0;
|
||||
i = 0;
|
||||
do
|
||||
ch = 8*ch + (*p - '0');
|
||||
ch = (char) (8*ch + (*p - '0'));
|
||||
while (*++p >= '0' && *p <= '7' && ++i < 3);
|
||||
*pp = p;
|
||||
if (xlate && ch == CONTROL('K'))
|
||||
|
|
@ -353,10 +360,10 @@ static void erase_cmd_char(struct lesskey_tables *tables)
|
|||
/*
|
||||
* Add a string to the output command table.
|
||||
*/
|
||||
static void add_cmd_str(char *s, struct lesskey_tables *tables)
|
||||
static void add_cmd_str(constant char *s, struct lesskey_tables *tables)
|
||||
{
|
||||
for ( ; *s != '\0'; s++)
|
||||
add_cmd_char(*s, tables);
|
||||
add_cmd_char((unsigned char) *s, tables);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -382,7 +389,7 @@ static int match_version(char op, int ver)
|
|||
* If the version matches, return the part of the line that should be executed.
|
||||
* Otherwise, return NULL.
|
||||
*/
|
||||
static char * version_line(char *s, struct lesskey_tables *tables)
|
||||
static char * version_line(char *s)
|
||||
{
|
||||
char op;
|
||||
int ver;
|
||||
|
|
@ -445,7 +452,7 @@ static char * control_line(char *s, struct lesskey_tables *tables)
|
|||
}
|
||||
if (PREFIX(s, "#version"))
|
||||
{
|
||||
return (version_line(s, tables));
|
||||
return (version_line(s));
|
||||
}
|
||||
return (s);
|
||||
}
|
||||
|
|
@ -475,7 +482,7 @@ static void parse_cmdline(char *p, struct lesskey_tables *tables)
|
|||
{
|
||||
char *actname;
|
||||
int action;
|
||||
char *s;
|
||||
constant char *s;
|
||||
char c;
|
||||
|
||||
/*
|
||||
|
|
@ -539,7 +546,7 @@ static void parse_cmdline(char *p, struct lesskey_tables *tables)
|
|||
*/
|
||||
static void parse_varline(char *line, struct lesskey_tables *tables)
|
||||
{
|
||||
char *s;
|
||||
constant char *s;
|
||||
char *p = line;
|
||||
char *eq;
|
||||
|
||||
|
|
@ -612,14 +619,14 @@ static void parse_line(char *line, struct lesskey_tables *tables)
|
|||
/*
|
||||
* Parse a lesskey source file and store result in tables.
|
||||
*/
|
||||
int parse_lesskey(char *infile, struct lesskey_tables *tables)
|
||||
int parse_lesskey(constant char *infile, struct lesskey_tables *tables)
|
||||
{
|
||||
FILE *desc;
|
||||
char line[1024];
|
||||
|
||||
if (infile == NULL)
|
||||
infile = homefile(DEF_LESSKEYINFILE);
|
||||
lesskey_file = infile;
|
||||
lesskey_file = (infile != NULL) ? strdup(infile) : homefile(DEF_LESSKEYINFILE);
|
||||
if (lesskey_file == NULL)
|
||||
return (-1);
|
||||
|
||||
init_tables(tables);
|
||||
errors = 0;
|
||||
|
|
@ -630,22 +637,63 @@ int parse_lesskey(char *infile, struct lesskey_tables *tables)
|
|||
/*
|
||||
* Open the input file.
|
||||
*/
|
||||
if (strcmp(infile, "-") == 0)
|
||||
if (strcmp(lesskey_file, "-") == 0)
|
||||
desc = stdin;
|
||||
else if ((desc = fopen(infile, "r")) == NULL)
|
||||
else if ((desc = fopen(lesskey_file, "r")) == NULL)
|
||||
{
|
||||
/* parse_error("cannot open lesskey file %s", infile); */
|
||||
return (-1);
|
||||
/* parse_error("cannot open lesskey file %s", lesskey_file); */
|
||||
errors = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read and parse the input file, one line at a time.
|
||||
*/
|
||||
while (fgets(line, sizeof(line), desc) != NULL)
|
||||
if (desc != NULL)
|
||||
{
|
||||
++linenum;
|
||||
parse_line(line, tables);
|
||||
while (fgets(line, sizeof(line), desc) != NULL)
|
||||
{
|
||||
++linenum;
|
||||
parse_line(line, tables);
|
||||
}
|
||||
if (desc != stdin)
|
||||
fclose(desc);
|
||||
}
|
||||
fclose(desc);
|
||||
free(lesskey_file);
|
||||
lesskey_file = NULL;
|
||||
return (errors);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a lesskey source content and store result in tables.
|
||||
*/
|
||||
int parse_lesskey_content(constant char *content, struct lesskey_tables *tables)
|
||||
{
|
||||
size_t cx = 0;
|
||||
|
||||
lesskey_file = "lesskey-content";
|
||||
init_tables(tables);
|
||||
errors = 0;
|
||||
linenum = 0;
|
||||
if (less_version == 0)
|
||||
less_version = lstrtoi(version, NULL, 10);
|
||||
|
||||
while (content[cx] != '\0')
|
||||
{
|
||||
/* Extract a line from the content buffer and parse it. */
|
||||
char line[1024];
|
||||
size_t lx = 0;
|
||||
while (content[cx] != '\0' && content[cx] != '\n' && content[cx] != ';')
|
||||
{
|
||||
if (lx >= sizeof(line)-1) break;
|
||||
if (content[cx] == '\\' && content[cx+1] == ';')
|
||||
++cx; /* escaped semicolon: skip the backslash */
|
||||
line[lx++] = content[cx++];
|
||||
}
|
||||
line[lx] = '\0';
|
||||
++linenum;
|
||||
parse_line(line, tables);
|
||||
if (content[cx] != '\0') ++cx; /* skip newline or semicolon */
|
||||
}
|
||||
lesskey_file = NULL;
|
||||
return (errors);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -25,12 +25,12 @@
|
|||
#define MAX_PFX_WIDTH (MAX_LINENUM_WIDTH + MAX_STATUSCOL_WIDTH + 1)
|
||||
static struct {
|
||||
char *buf; /* Buffer which holds the current output line */
|
||||
int *attr; /* Parallel to buf, to hold attributes */
|
||||
int print; /* Index in buf of first printable char */
|
||||
int end; /* Number of chars in buf */
|
||||
int *attr; /* Parallel to buf, to hold attributes */
|
||||
size_t print; /* Index in buf of first printable char */
|
||||
size_t end; /* Number of chars in buf */
|
||||
char pfx[MAX_PFX_WIDTH]; /* Holds status column and line number */
|
||||
int pfx_attr[MAX_PFX_WIDTH];
|
||||
int pfx_end; /* Number of chars in pfx */
|
||||
size_t pfx_end; /* Number of chars in pfx */
|
||||
} linebuf;
|
||||
|
||||
/*
|
||||
|
|
@ -50,9 +50,9 @@ static struct xbuffer last_ansi;
|
|||
static struct xbuffer last_ansis[NUM_LAST_ANSIS];
|
||||
static int curr_last_ansi;
|
||||
|
||||
public int size_linebuf = 0; /* Size of line buffer (and attr buffer) */
|
||||
public size_t size_linebuf = 0; /* Size of line buffer (and attr buffer) */
|
||||
static struct ansi_state *line_ansi = NULL;
|
||||
static int ansi_in_line;
|
||||
static lbool ansi_in_line;
|
||||
static int hlink_in_line;
|
||||
static int line_mark_attr;
|
||||
static int cshift; /* Current left-shift of output line buffer */
|
||||
|
|
@ -68,16 +68,16 @@ static int right_curr;
|
|||
static int right_column;
|
||||
static int overstrike; /* Next char should overstrike previous char */
|
||||
static int last_overstrike = AT_NORMAL;
|
||||
static int is_null_line; /* There is no current line */
|
||||
static lbool is_null_line; /* There is no current line */
|
||||
static LWCHAR pendc;
|
||||
static POSITION pendpos;
|
||||
static char *end_ansi_chars;
|
||||
static char *mid_ansi_chars;
|
||||
static constant char *end_ansi_chars;
|
||||
static constant char *mid_ansi_chars;
|
||||
static int in_hilite;
|
||||
|
||||
static int attr_swidth(int a);
|
||||
static int attr_ewidth(int a);
|
||||
static int do_append(LWCHAR ch, char *rep, POSITION pos);
|
||||
static int do_append(LWCHAR ch, constant char *rep, POSITION pos);
|
||||
|
||||
extern int sigs;
|
||||
extern int bs_mode;
|
||||
|
|
@ -87,7 +87,6 @@ extern int proc_return;
|
|||
extern int linenums;
|
||||
extern int ctldisp;
|
||||
extern int twiddle;
|
||||
extern int binattr;
|
||||
extern int status_col;
|
||||
extern int status_col_width;
|
||||
extern int linenum_width;
|
||||
|
|
@ -100,7 +99,7 @@ extern int sc_width, sc_height;
|
|||
extern int utf_mode;
|
||||
extern POSITION start_attnpos;
|
||||
extern POSITION end_attnpos;
|
||||
extern char rscroll_char;
|
||||
extern LWCHAR rscroll_char;
|
||||
extern int rscroll_attr;
|
||||
extern int use_color;
|
||||
extern int status_line;
|
||||
|
|
@ -109,7 +108,7 @@ static char mbc_buf[MAX_UTF_CHAR_LEN];
|
|||
static int mbc_buf_len = 0;
|
||||
static int mbc_buf_index = 0;
|
||||
static POSITION mbc_pos;
|
||||
static int saved_line_end;
|
||||
static size_t saved_line_end;
|
||||
static int saved_end_column;
|
||||
|
||||
/* Configurable color map */
|
||||
|
|
@ -138,9 +137,8 @@ static struct color_map color_map[] = {
|
|||
|
||||
/* State while processing an ANSI escape sequence */
|
||||
struct ansi_state {
|
||||
int hindex; /* Index into hyperlink prefix */
|
||||
int hlink; /* Processing hyperlink address? */
|
||||
int prev_esc; /* Prev char was ESC (to detect ESC-\ seq) */
|
||||
int oindex; /* Index into OSC8 prefix */
|
||||
osc8_state ostate; /* State while processing OSC8 sequence */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -174,7 +172,7 @@ public void init_line(void)
|
|||
static int expand_linebuf(void)
|
||||
{
|
||||
/* Double the size of the line buffer. */
|
||||
int new_size = size_linebuf * 2;
|
||||
size_t new_size = size_linebuf * 2;
|
||||
char *new_buf = (char *) calloc(new_size, sizeof(char));
|
||||
int *new_attr = (int *) calloc(new_size, sizeof(int));
|
||||
if (new_buf == NULL || new_attr == NULL)
|
||||
|
|
@ -201,7 +199,7 @@ static int expand_linebuf(void)
|
|||
/*
|
||||
* Is a character ASCII?
|
||||
*/
|
||||
public int is_ascii_char(LWCHAR ch)
|
||||
public lbool is_ascii_char(LWCHAR ch)
|
||||
{
|
||||
return (ch <= 0x7F);
|
||||
}
|
||||
|
|
@ -213,7 +211,7 @@ static void inc_end_column(int w)
|
|||
if (end_column > right_column && w > 0)
|
||||
{
|
||||
right_column = end_column;
|
||||
right_curr = linebuf.end;
|
||||
right_curr = (int) linebuf.end;
|
||||
}
|
||||
end_column += w;
|
||||
}
|
||||
|
|
@ -245,10 +243,10 @@ public void prewind(void)
|
|||
overstrike = 0;
|
||||
last_overstrike = AT_NORMAL;
|
||||
mbc_buf_len = 0;
|
||||
is_null_line = 0;
|
||||
is_null_line = FALSE;
|
||||
pendc = '\0';
|
||||
in_hilite = 0;
|
||||
ansi_in_line = 0;
|
||||
ansi_in_line = FALSE;
|
||||
hlink_in_line = 0;
|
||||
line_mark_attr = 0;
|
||||
line_pos = NULL_POSITION;
|
||||
|
|
@ -262,7 +260,7 @@ public void prewind(void)
|
|||
/*
|
||||
* Set a character in the line buffer.
|
||||
*/
|
||||
static void set_linebuf(int n, char ch, int attr)
|
||||
static void set_linebuf(size_t n, char ch, int attr)
|
||||
{
|
||||
if (n >= size_linebuf)
|
||||
{
|
||||
|
|
@ -289,7 +287,7 @@ static void add_linebuf(char ch, int attr, int w)
|
|||
/*
|
||||
* Append a string to the line buffer.
|
||||
*/
|
||||
static void addstr_linebuf(char *s, int attr, int cw)
|
||||
static void addstr_linebuf(constant char *s, int attr, int cw)
|
||||
{
|
||||
for ( ; *s != '\0'; s++)
|
||||
add_linebuf(*s, attr, cw);
|
||||
|
|
@ -298,7 +296,7 @@ static void addstr_linebuf(char *s, int attr, int cw)
|
|||
/*
|
||||
* Set a character in the line prefix buffer.
|
||||
*/
|
||||
static void set_pfx(int n, char ch, int attr)
|
||||
static void set_pfx(size_t n, char ch, int attr)
|
||||
{
|
||||
linebuf.pfx[n] = ch;
|
||||
linebuf.pfx_attr[n] = attr;
|
||||
|
|
@ -318,7 +316,6 @@ static void add_pfx(char ch, int attr)
|
|||
public void plinestart(POSITION pos)
|
||||
{
|
||||
LINENUM linenum = 0;
|
||||
int i;
|
||||
|
||||
if (linenums == OPT_ONPLUS)
|
||||
{
|
||||
|
|
@ -347,7 +344,7 @@ public void plinestart(POSITION pos)
|
|||
if (status_col)
|
||||
{
|
||||
add_pfx(c ? c : ' ', line_mark_attr); /* column 0: status */
|
||||
while (linebuf.pfx_end < status_col_width)
|
||||
while (linebuf.pfx_end < (size_t) status_col_width) /*{{type-issue}}*/
|
||||
add_pfx(' ', AT_NORMAL);
|
||||
}
|
||||
}
|
||||
|
|
@ -359,7 +356,8 @@ public void plinestart(POSITION pos)
|
|||
if (linenums == OPT_ONPLUS)
|
||||
{
|
||||
char buf[INT_STRLEN_BOUND(linenum) + 2];
|
||||
int len;
|
||||
size_t len;
|
||||
size_t i;
|
||||
|
||||
linenum = vlinenum(linenum);
|
||||
if (linenum == 0)
|
||||
|
|
@ -367,15 +365,15 @@ public void plinestart(POSITION pos)
|
|||
else
|
||||
{
|
||||
linenumtoa(linenum, buf, 10);
|
||||
len = (int) strlen(buf);
|
||||
len = strlen(buf);
|
||||
}
|
||||
for (i = 0; i < linenum_width - len; i++)
|
||||
for (i = 0; i + len < (size_t) linenum_width; i++)
|
||||
add_pfx(' ', AT_NORMAL);
|
||||
for (i = 0; i < len; i++)
|
||||
add_pfx(buf[i], AT_BOLD|AT_COLOR_LINENUM);
|
||||
add_pfx(' ', AT_NORMAL);
|
||||
}
|
||||
end_column = linebuf.pfx_end;
|
||||
end_column = (int) linebuf.pfx_end; /*{{type-issue}}*/
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -398,12 +396,13 @@ public int line_pfx_width(void)
|
|||
*/
|
||||
public void pshift_all(void)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
for (i = linebuf.print; i < linebuf.end; i++)
|
||||
if (linebuf.attr[i] == AT_ANSI)
|
||||
xbuf_add_byte(&shifted_ansi, (unsigned char) linebuf.buf[i]);
|
||||
xbuf_add_char(&shifted_ansi, linebuf.buf[i]);
|
||||
linebuf.end = linebuf.print;
|
||||
end_column = linebuf.pfx_end;
|
||||
end_column = (int) linebuf.pfx_end; /*{{type-issue}}*/
|
||||
line_pos = NULL_POSITION;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -466,13 +465,13 @@ public int pwidth(LWCHAR ch, int a, LWCHAR prev_ch, int prev_a)
|
|||
* Backspace moves backwards one or two positions.
|
||||
*/
|
||||
if (prev_a & (AT_ANSI|AT_BINARY))
|
||||
return strlen(prchar('\b'));
|
||||
return (int) strlen(prchar('\b')); /*{{type-issue}}*/
|
||||
return (utf_mode && is_wide_char(prev_ch)) ? -2 : -1;
|
||||
}
|
||||
|
||||
if (!utf_mode || is_ascii_char(ch))
|
||||
{
|
||||
if (control_char((char)ch))
|
||||
if (control_char(ch))
|
||||
{
|
||||
/*
|
||||
* Control characters do unpredictable things,
|
||||
|
|
@ -532,7 +531,7 @@ static int backc(void)
|
|||
{
|
||||
LWCHAR prev_ch;
|
||||
int width;
|
||||
linebuf.end = (int) (p - linebuf.buf);
|
||||
linebuf.end = ptr_diff(p, linebuf.buf);
|
||||
prev_ch = step_char(&p, -1, linebuf.buf);
|
||||
width = pwidth(ch, linebuf.attr[linebuf.end], prev_ch, linebuf.attr[linebuf.end-1]);
|
||||
end_column -= width;
|
||||
|
|
@ -565,22 +564,22 @@ public void loadc(void)
|
|||
/*
|
||||
* Is a character the end of an ANSI escape sequence?
|
||||
*/
|
||||
public int is_ansi_end(LWCHAR ch)
|
||||
public lbool is_ansi_end(LWCHAR ch)
|
||||
{
|
||||
if (!is_ascii_char(ch))
|
||||
return (0);
|
||||
return (FALSE);
|
||||
return (strchr(end_ansi_chars, (char) ch) != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Can a char appear in an ANSI escape sequence, before the end char?
|
||||
*/
|
||||
public int is_ansi_middle(LWCHAR ch)
|
||||
public lbool is_ansi_middle(LWCHAR ch)
|
||||
{
|
||||
if (!is_ascii_char(ch))
|
||||
return (0);
|
||||
return (FALSE);
|
||||
if (is_ansi_end(ch))
|
||||
return (0);
|
||||
return (FALSE);
|
||||
return (strchr(mid_ansi_chars, (char) ch) != NULL);
|
||||
}
|
||||
|
||||
|
|
@ -588,11 +587,11 @@ public int is_ansi_middle(LWCHAR ch)
|
|||
* Skip past an ANSI escape sequence.
|
||||
* pp is initially positioned just after the CSI_START char.
|
||||
*/
|
||||
public void skip_ansi(struct ansi_state *pansi, char **pp, constant char *limit)
|
||||
public void skip_ansi(struct ansi_state *pansi, constant char **pp, constant char *limit)
|
||||
{
|
||||
LWCHAR c;
|
||||
do {
|
||||
c = step_char(pp, +1, limit);
|
||||
c = step_charc(pp, +1, limit);
|
||||
} while (*pp < limit && ansi_step(pansi, c) == ANSI_MID);
|
||||
/* Note that we discard final char, for which is_ansi_end is true. */
|
||||
}
|
||||
|
|
@ -608,9 +607,8 @@ public struct ansi_state * ansi_start(LWCHAR ch)
|
|||
if (!IS_CSI_START(ch))
|
||||
return NULL;
|
||||
pansi = ecalloc(1, sizeof(struct ansi_state));
|
||||
pansi->hindex = 0;
|
||||
pansi->hlink = 0;
|
||||
pansi->prev_esc = 0;
|
||||
pansi->oindex = 0;
|
||||
pansi->ostate = OSC8_PREFIX;
|
||||
return pansi;
|
||||
}
|
||||
|
||||
|
|
@ -618,30 +616,48 @@ public struct ansi_state * ansi_start(LWCHAR ch)
|
|||
* Determine whether the next char in an ANSI escape sequence
|
||||
* ends the sequence.
|
||||
*/
|
||||
public int ansi_step(struct ansi_state *pansi, LWCHAR ch)
|
||||
public ansi_state ansi_step(struct ansi_state *pansi, LWCHAR ch)
|
||||
{
|
||||
if (pansi->hlink)
|
||||
static constant char osc8_prefix[] = ESCS "]8;";
|
||||
|
||||
switch (pansi->ostate)
|
||||
{
|
||||
/* Hyperlink ends with \7 or ESC-backslash. */
|
||||
if (ch == '\7')
|
||||
return ANSI_END;
|
||||
if (pansi->prev_esc)
|
||||
return (ch == '\\') ? ANSI_END : ANSI_ERR;
|
||||
pansi->prev_esc = (ch == ESC);
|
||||
return ANSI_MID;
|
||||
}
|
||||
if (pansi->hindex >= 0)
|
||||
{
|
||||
static char hlink_prefix[] = ESCS "]8;";
|
||||
if (ch == hlink_prefix[pansi->hindex] ||
|
||||
(pansi->hindex == 0 && IS_CSI_START(ch)))
|
||||
case OSC8_PREFIX:
|
||||
if (ch != (LWCHAR) osc8_prefix[pansi->oindex] &&
|
||||
!(pansi->oindex == 0 && IS_CSI_START(ch)))
|
||||
{
|
||||
pansi->hindex++;
|
||||
if (hlink_prefix[pansi->hindex] == '\0')
|
||||
pansi->hlink = 1; /* now processing hyperlink addr */
|
||||
return ANSI_MID;
|
||||
pansi->ostate = OSC8_NOT; /* not an OSC8 sequence */
|
||||
break;
|
||||
}
|
||||
pansi->hindex = -1; /* not a hyperlink */
|
||||
pansi->oindex++;
|
||||
if (osc8_prefix[pansi->oindex] == '\0') /* end of prefix */
|
||||
pansi->ostate = OSC8_PARAMS;
|
||||
return ANSI_MID;
|
||||
case OSC8_PARAMS:
|
||||
if (ch == ';')
|
||||
pansi->ostate = OSC8_URI;
|
||||
return ANSI_MID;
|
||||
case OSC8_URI:
|
||||
/* URI ends with \7 or ESC-backslash. */
|
||||
if (ch == '\7')
|
||||
{
|
||||
pansi->ostate = OSC8_END;
|
||||
return ANSI_END;
|
||||
}
|
||||
if (ch == ESC)
|
||||
pansi->ostate = OSC8_ST_ESC;
|
||||
return ANSI_MID;
|
||||
case OSC8_ST_ESC:
|
||||
if (ch != '\\')
|
||||
{
|
||||
return ANSI_ERR;
|
||||
}
|
||||
pansi->ostate = OSC8_END;
|
||||
return ANSI_END;
|
||||
case OSC8_END:
|
||||
return ANSI_END;
|
||||
case OSC8_NOT:
|
||||
break;
|
||||
}
|
||||
/* Check for SGR sequences */
|
||||
if (is_ansi_middle(ch))
|
||||
|
|
@ -651,6 +667,14 @@ public int ansi_step(struct ansi_state *pansi, LWCHAR ch)
|
|||
return ANSI_ERR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the current OSC8 parsing state.
|
||||
*/
|
||||
public osc8_state ansi_osc8_state(struct ansi_state *pansi)
|
||||
{
|
||||
return pansi->ostate;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free an ansi_state structure.
|
||||
*/
|
||||
|
|
@ -678,16 +702,17 @@ static int fits_on_screen(int w, int a)
|
|||
if (store_char((ch),(a),(rep),(pos))) return (1); \
|
||||
} while (0)
|
||||
|
||||
static int store_char(LWCHAR ch, int a, char *rep, POSITION pos)
|
||||
static int store_char(LWCHAR ch, int a, constant char *rep, POSITION pos)
|
||||
{
|
||||
int w;
|
||||
int i;
|
||||
int replen;
|
||||
size_t i;
|
||||
size_t replen;
|
||||
char cs;
|
||||
int ov;
|
||||
|
||||
i = (a & (AT_UNDERLINE|AT_BOLD));
|
||||
if (i != AT_NORMAL)
|
||||
last_overstrike = i;
|
||||
ov = (a & (AT_UNDERLINE|AT_BOLD));
|
||||
if (ov != AT_NORMAL)
|
||||
last_overstrike = ov;
|
||||
|
||||
#if HILITE_SEARCH
|
||||
{
|
||||
|
|
@ -759,7 +784,7 @@ static int store_char(LWCHAR ch, int a, char *rep, POSITION pos)
|
|||
replen = 1;
|
||||
} else
|
||||
{
|
||||
replen = utf_len(rep[0]);
|
||||
replen = (size_t) utf_len(rep[0]); /*{{type-issue}}*/
|
||||
}
|
||||
|
||||
if (cshift == hshift)
|
||||
|
|
@ -770,7 +795,7 @@ static int store_char(LWCHAR ch, int a, char *rep, POSITION pos)
|
|||
{
|
||||
/* 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);
|
||||
add_linebuf((char) shifted_ansi.data[i], AT_ANSI, 0);
|
||||
xbuf_reset(&shifted_ansi);
|
||||
}
|
||||
}
|
||||
|
|
@ -784,11 +809,11 @@ static int store_char(LWCHAR ch, int a, char *rep, POSITION pos)
|
|||
{
|
||||
/* We haven't left-shifted enough yet. */
|
||||
if (a == AT_ANSI)
|
||||
xbuf_add_byte(&shifted_ansi, (unsigned char) ch); /* Save ANSI attributes */
|
||||
xbuf_add_char(&shifted_ansi, (char) ch); /* Save ANSI attributes */
|
||||
if (linebuf.end > linebuf.print)
|
||||
{
|
||||
/* Shift left enough to put last byte of this char at print-1. */
|
||||
int i;
|
||||
size_t i;
|
||||
for (i = 0; i < linebuf.print; i++)
|
||||
{
|
||||
linebuf.buf[i] = linebuf.buf[i+replen];
|
||||
|
|
@ -814,25 +839,21 @@ static int store_char(LWCHAR ch, int a, char *rep, POSITION pos)
|
|||
#define STORE_STRING(s,a,pos) \
|
||||
do { if (store_string((s),(a),(pos))) return (1); } while (0)
|
||||
|
||||
static int store_string(char *s, int a, POSITION pos)
|
||||
static int store_string(constant char *s, int a, POSITION pos)
|
||||
{
|
||||
if (!fits_on_screen(strlen(s), a))
|
||||
if (!fits_on_screen((int) strlen(s), a))
|
||||
return 1;
|
||||
for ( ; *s != 0; s++)
|
||||
STORE_CHAR(*s, a, NULL, pos);
|
||||
STORE_CHAR((LWCHAR)*s, a, NULL, pos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append a tab to the line buffer.
|
||||
* Store spaces to represent the tab.
|
||||
* Return number of spaces from col to the next tab stop.
|
||||
*/
|
||||
#define STORE_TAB(a,pos) \
|
||||
do { if (store_tab((a),(pos))) return (1); } while (0)
|
||||
|
||||
static int store_tab(int attr, POSITION pos)
|
||||
static int tab_spaces(int col)
|
||||
{
|
||||
int to_tab = end_column - linebuf.pfx_end;
|
||||
int to_tab = col - (int) linebuf.pfx_end; /*{{type-issue}}*/
|
||||
|
||||
if (ntabstops < 2 || to_tab >= tabstops[ntabstops-1])
|
||||
to_tab = tabdefault -
|
||||
|
|
@ -845,7 +866,19 @@ static int store_tab(int attr, POSITION pos)
|
|||
break;
|
||||
to_tab = tabstops[i+1] - to_tab;
|
||||
}
|
||||
return to_tab;
|
||||
}
|
||||
|
||||
/*
|
||||
* Append a tab to the line buffer.
|
||||
* Store spaces to represent the tab.
|
||||
*/
|
||||
#define STORE_TAB(a,pos) \
|
||||
do { if (store_tab((a),(pos))) return (1); } while (0)
|
||||
|
||||
static int store_tab(int attr, POSITION pos)
|
||||
{
|
||||
int to_tab = tab_spaces(end_column);
|
||||
do {
|
||||
STORE_CHAR(' ', attr, " ", pos);
|
||||
} while (--to_tab > 0);
|
||||
|
|
@ -869,7 +902,7 @@ static int flush_mbc_buf(POSITION pos)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < mbc_buf_index; i++)
|
||||
if (store_prchar(mbc_buf[i], pos))
|
||||
if (store_prchar((LWCHAR) mbc_buf[i], pos))
|
||||
return mbc_buf_index - i;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -879,13 +912,14 @@ static int flush_mbc_buf(POSITION pos)
|
|||
* Expand tabs into spaces, handle underlining, boldfacing, etc.
|
||||
* Returns 0 if ok, 1 if couldn't fit in buffer.
|
||||
*/
|
||||
public int pappend(int c, POSITION pos)
|
||||
public int pappend_b(char c, POSITION pos, lbool before_pendc)
|
||||
{
|
||||
LWCHAR ch = c & 0377;
|
||||
int r;
|
||||
|
||||
if (pendc)
|
||||
if (pendc && !before_pendc)
|
||||
{
|
||||
if (c == '\r' && pendc == '\r')
|
||||
if (ch == '\r' && pendc == '\r')
|
||||
return (0);
|
||||
if (do_append(pendc, NULL, pendpos))
|
||||
/*
|
||||
|
|
@ -896,7 +930,7 @@ public int pappend(int c, POSITION pos)
|
|||
pendc = '\0';
|
||||
}
|
||||
|
||||
if (c == '\r' && (proc_return == OPT_ON || (bs_mode == BS_SPECIAL && proc_return == OPT_OFF)))
|
||||
if (ch == '\r' && (proc_return == OPT_ON || (bs_mode == BS_SPECIAL && proc_return == OPT_OFF)))
|
||||
{
|
||||
if (mbc_buf_len > 0) /* utf_mode must be on. */
|
||||
{
|
||||
|
|
@ -913,14 +947,14 @@ public int pappend(int c, POSITION pos)
|
|||
* the next char. If the next char is a newline,
|
||||
* discard the CR.
|
||||
*/
|
||||
pendc = c;
|
||||
pendc = ch;
|
||||
pendpos = pos;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!utf_mode)
|
||||
{
|
||||
r = do_append(c, NULL, pos);
|
||||
r = do_append(ch, NULL, pos);
|
||||
} else
|
||||
{
|
||||
/* Perform strict validation in all possible cases. */
|
||||
|
|
@ -930,7 +964,7 @@ public int pappend(int c, POSITION pos)
|
|||
mbc_buf_index = 1;
|
||||
*mbc_buf = c;
|
||||
if (IS_ASCII_OCTET(c))
|
||||
r = do_append(c, NULL, pos);
|
||||
r = do_append(ch, NULL, pos);
|
||||
else if (IS_UTF8_LEAD(c))
|
||||
{
|
||||
mbc_buf_len = utf_len(c);
|
||||
|
|
@ -969,7 +1003,12 @@ public int pappend(int c, POSITION pos)
|
|||
return (r);
|
||||
}
|
||||
|
||||
static int store_control_char(LWCHAR ch, char *rep, POSITION pos)
|
||||
public int pappend(char c, POSITION pos)
|
||||
{
|
||||
return pappend_b(c, pos, FALSE);
|
||||
}
|
||||
|
||||
static int store_control_char(LWCHAR ch, constant char *rep, POSITION pos)
|
||||
{
|
||||
if (ctldisp == OPT_ON)
|
||||
{
|
||||
|
|
@ -978,26 +1017,26 @@ static int store_control_char(LWCHAR ch, char *rep, POSITION pos)
|
|||
} else
|
||||
{
|
||||
/* Output a printable representation of the character. */
|
||||
STORE_PRCHAR((char) ch, pos);
|
||||
STORE_PRCHAR(ch, pos);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int store_ansi(LWCHAR ch, char *rep, POSITION pos)
|
||||
static int store_ansi(LWCHAR ch, constant char *rep, POSITION pos)
|
||||
{
|
||||
switch (ansi_step(line_ansi, ch))
|
||||
{
|
||||
case ANSI_MID:
|
||||
STORE_CHAR(ch, AT_ANSI, rep, pos);
|
||||
if (line_ansi->hlink)
|
||||
if (ansi_osc8_state(line_ansi) == OSC8_PARAMS)
|
||||
hlink_in_line = 1;
|
||||
xbuf_add_byte(&last_ansi, (unsigned char) ch);
|
||||
xbuf_add_char(&last_ansi, (char) ch);
|
||||
break;
|
||||
case ANSI_END:
|
||||
STORE_CHAR(ch, AT_ANSI, rep, pos);
|
||||
ansi_done(line_ansi);
|
||||
line_ansi = NULL;
|
||||
xbuf_add_byte(&last_ansi, (unsigned char) ch);
|
||||
xbuf_add_char(&last_ansi, (char) ch);
|
||||
xbuf_set(&last_ansis[curr_last_ansi], &last_ansi);
|
||||
xbuf_reset(&last_ansi);
|
||||
curr_last_ansi = (curr_last_ansi + 1) % NUM_LAST_ANSIS;
|
||||
|
|
@ -1005,24 +1044,26 @@ static int store_ansi(LWCHAR ch, char *rep, POSITION pos)
|
|||
case ANSI_ERR:
|
||||
{
|
||||
/* Remove whole unrecognized sequence. */
|
||||
char *start = (cshift < hshift) ? xbuf_char_data(&shifted_ansi): linebuf.buf;
|
||||
int *end = (cshift < hshift) ? &shifted_ansi.end : &linebuf.end;
|
||||
char *p = start + *end;
|
||||
constant char *start = (cshift < hshift) ? xbuf_char_data(&shifted_ansi): linebuf.buf;
|
||||
size_t *end = (cshift < hshift) ? &shifted_ansi.end : &linebuf.end;
|
||||
constant char *p = start + *end;
|
||||
LWCHAR bch;
|
||||
do {
|
||||
bch = step_char(&p, -1, start);
|
||||
bch = step_charc(&p, -1, start);
|
||||
} while (p > start && !IS_CSI_START(bch));
|
||||
*end = (int) (p - start);
|
||||
*end = ptr_diff(p, start);
|
||||
}
|
||||
xbuf_reset(&last_ansi);
|
||||
ansi_done(line_ansi);
|
||||
line_ansi = NULL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int store_bs(LWCHAR ch, char *rep, POSITION pos)
|
||||
static int store_bs(LWCHAR ch, constant char *rep, POSITION pos)
|
||||
{
|
||||
if (proc_backspace == OPT_ONPLUS || (bs_mode == BS_CONTROL && proc_backspace == OPT_OFF))
|
||||
return store_control_char(ch, rep, pos);
|
||||
|
|
@ -1037,7 +1078,7 @@ static int store_bs(LWCHAR ch, char *rep, POSITION pos)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int do_append(LWCHAR ch, char *rep, POSITION pos)
|
||||
static int do_append(LWCHAR ch, constant char *rep, POSITION pos)
|
||||
{
|
||||
int a = AT_NORMAL;
|
||||
int in_overstrike = overstrike;
|
||||
|
|
@ -1046,7 +1087,7 @@ static int do_append(LWCHAR ch, char *rep, POSITION pos)
|
|||
{
|
||||
line_ansi = ansi_start(ch);
|
||||
if (line_ansi != NULL)
|
||||
ansi_in_line = 1;
|
||||
ansi_in_line = TRUE;
|
||||
}
|
||||
|
||||
overstrike = 0;
|
||||
|
|
@ -1125,7 +1166,7 @@ static int do_append(LWCHAR ch, char *rep, POSITION pos)
|
|||
STORE_TAB(a, pos);
|
||||
return (0);
|
||||
}
|
||||
if ((!utf_mode || is_ascii_char(ch)) && control_char((char)ch))
|
||||
if ((!utf_mode || is_ascii_char(ch)) && control_char(ch))
|
||||
{
|
||||
return store_control_char(ch, rep, pos);
|
||||
} else if (utf_mode && ctldisp != OPT_ON && is_ubin_char(ch))
|
||||
|
|
@ -1183,6 +1224,9 @@ public void pdone(int endline, int chopped, int forw)
|
|||
|
||||
if (chopped && rscroll_char)
|
||||
{
|
||||
char rscroll_utf8[MAX_UTF_CHAR_LEN+1];
|
||||
char *up = rscroll_utf8;
|
||||
|
||||
/*
|
||||
* Display the right scrolling char.
|
||||
* If we've already filled the rightmost screen char
|
||||
|
|
@ -1192,7 +1236,7 @@ public void pdone(int endline, int chopped, int forw)
|
|||
{
|
||||
/* We've already written in the rightmost char. */
|
||||
end_column = right_column;
|
||||
linebuf.end = right_curr;
|
||||
linebuf.end = (size_t) right_curr;
|
||||
}
|
||||
add_attr_normal();
|
||||
while (end_column < sc_width-1 + cshift)
|
||||
|
|
@ -1202,10 +1246,13 @@ public void pdone(int endline, int chopped, int forw)
|
|||
* This may be necessary if the char we overwrote
|
||||
* was double-width.
|
||||
*/
|
||||
add_linebuf(' ', rscroll_attr, 1);
|
||||
add_linebuf(' ', 0, 1);
|
||||
}
|
||||
/* Print rscroll char. It must be single-width. */
|
||||
add_linebuf(rscroll_char, rscroll_attr, 1);
|
||||
/* Print rscroll char. */
|
||||
put_wchar(&up, rscroll_char);
|
||||
*up = '\0';
|
||||
addstr_linebuf(rscroll_utf8, rscroll_attr, 0);
|
||||
inc_end_column(1); /* assume rscroll_char is single-width */
|
||||
} else
|
||||
{
|
||||
add_attr_normal();
|
||||
|
|
@ -1258,12 +1305,121 @@ public void pdone(int endline, int chopped, int forw)
|
|||
set_linebuf(linebuf.end, '\0', AT_NORMAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the column number (screen position) of a given file position in its line.
|
||||
* linepos = position of first char in line
|
||||
* spos = position of char being queried
|
||||
* saved_pos = position of a known column, or NULL_POSITION if no known column
|
||||
* saved_col = column number of a known column, or -1 if no known column
|
||||
*
|
||||
* This attempts to mimic the logic in pappend() and the store_*() functions.
|
||||
* Duplicating this complicated logic is not a good design.
|
||||
*/
|
||||
|
||||
struct col_pos { int col; POSITION pos; };
|
||||
|
||||
static void col_vs_pos(POSITION linepos, mutable struct col_pos *cp, POSITION saved_pos, int saved_col)
|
||||
{
|
||||
int col = (saved_col < 0) ? 0 : saved_col;
|
||||
LWCHAR prev_ch = 0;
|
||||
struct ansi_state *pansi = NULL;
|
||||
char utf8_buf[MAX_UTF_CHAR_LEN];
|
||||
int utf8_len = 0;
|
||||
POSITION chpos;
|
||||
|
||||
if (ch_seek(saved_pos != NULL_POSITION ? saved_pos : linepos))
|
||||
return;
|
||||
for (;;)
|
||||
{
|
||||
int ich;
|
||||
char ch;
|
||||
int cw = 0;
|
||||
|
||||
chpos = ch_tell();
|
||||
ich = ch_forw_get();
|
||||
ch = (char) ich;
|
||||
if (ich == EOI || ch == '\n')
|
||||
break;
|
||||
if (pansi != NULL)
|
||||
{
|
||||
if (ansi_step(pansi, ch) != ANSI_MID)
|
||||
{
|
||||
ansi_done(pansi);
|
||||
pansi = NULL;
|
||||
}
|
||||
} else if (ctldisp == OPT_ONPLUS && (pansi = ansi_start(ch)) != NULL)
|
||||
{
|
||||
/* start of ansi sequence */
|
||||
(void) ansi_step(pansi, ch);
|
||||
} else if (ch == '\b')
|
||||
{
|
||||
if (proc_backspace == OPT_ONPLUS || (bs_mode == BS_CONTROL && proc_backspace == OPT_OFF))
|
||||
cw = strlen(prchar(ch));
|
||||
else
|
||||
cw = (utf_mode && is_wide_char(prev_ch)) ? -2 : -1;
|
||||
} else if (ch == '\t')
|
||||
{
|
||||
if (proc_tab == OPT_ONPLUS || (bs_mode == BS_CONTROL && proc_tab == OPT_OFF))
|
||||
cw = strlen(prchar(ch));
|
||||
else
|
||||
cw = tab_spaces(col);
|
||||
} else if ((!utf_mode || is_ascii_char(ch)) && control_char(ch))
|
||||
{
|
||||
cw = strlen(prchar(ch));
|
||||
} else if (utf8_len < MAX_UTF_CHAR_LEN)
|
||||
{
|
||||
utf8_buf[utf8_len++] = ch;
|
||||
if (is_utf8_well_formed(utf8_buf, utf8_len))
|
||||
{
|
||||
LWCHAR wch = get_wchar(utf8_buf);
|
||||
utf8_len = 0;
|
||||
int attr = 0; /* {{ ignoring attribute is not correct for magic cookie terminals }} */
|
||||
if (utf_mode && ctldisp != OPT_ON && is_ubin_char(wch))
|
||||
cw = strlen(prutfchar(wch));
|
||||
else
|
||||
cw = pwidth(wch, attr, prev_ch, attr);
|
||||
prev_ch = wch;
|
||||
}
|
||||
} else
|
||||
{
|
||||
utf8_len = 0; /* flush invalid UTF-8 */
|
||||
}
|
||||
|
||||
if (cp->pos != NULL_POSITION && chpos == cp->pos) /* found the position we want */
|
||||
break;
|
||||
if (cp->col >= 0 && col >= cp->col && cw > 0) /* found the column we want */
|
||||
break;
|
||||
col += cw;
|
||||
prev_ch = ch;
|
||||
}
|
||||
cp->col = col;
|
||||
cp->pos = chpos;
|
||||
}
|
||||
|
||||
public int col_from_pos(POSITION linepos, POSITION spos, POSITION saved_pos, int saved_col)
|
||||
{
|
||||
struct col_pos cp;
|
||||
cp.pos = spos;
|
||||
cp.col = -1;
|
||||
col_vs_pos(linepos, &cp, saved_pos, saved_col);
|
||||
return cp.col;
|
||||
}
|
||||
|
||||
public POSITION pos_from_col(POSITION linepos, int col, POSITION saved_pos, int saved_col)
|
||||
{
|
||||
struct col_pos cp;
|
||||
cp.col = col + hshift - line_pfx_width();
|
||||
cp.pos = NULL_POSITION;
|
||||
col_vs_pos(linepos, &cp, saved_pos, saved_col);
|
||||
return cp.pos;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set an attribute on each char of the line in the line buffer.
|
||||
*/
|
||||
public void set_attr_line(int a)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
for (i = linebuf.print; i < linebuf.end; i++)
|
||||
if ((linebuf.attr[i] & AT_COLOR) == 0 || (a & AT_COLOR) == 0)
|
||||
|
|
@ -1283,7 +1439,7 @@ public void set_status_col(char c, int attr)
|
|||
* Return the character as the function return value,
|
||||
* and the character attribute in *ap.
|
||||
*/
|
||||
public int gline(int i, int *ap)
|
||||
public int gline(size_t i, int *ap)
|
||||
{
|
||||
if (is_null_line)
|
||||
{
|
||||
|
|
@ -1320,7 +1476,7 @@ public int gline(int i, int *ap)
|
|||
*/
|
||||
public void null_line(void)
|
||||
{
|
||||
is_null_line = 1;
|
||||
is_null_line = TRUE;
|
||||
cshift = 0;
|
||||
}
|
||||
|
||||
|
|
@ -1329,9 +1485,9 @@ public void null_line(void)
|
|||
* lines which are not split for screen width.
|
||||
* {{ This is supposed to be more efficient than forw_line(). }}
|
||||
*/
|
||||
public POSITION forw_raw_line(POSITION curr_pos, char **linep, int *line_lenp)
|
||||
public POSITION forw_raw_line_len(POSITION curr_pos, size_t read_len, constant char **linep, size_t *line_lenp)
|
||||
{
|
||||
int n;
|
||||
size_t n;
|
||||
int c;
|
||||
POSITION new_pos;
|
||||
|
||||
|
|
@ -1359,7 +1515,12 @@ public POSITION forw_raw_line(POSITION curr_pos, char **linep, int *line_lenp)
|
|||
break;
|
||||
}
|
||||
}
|
||||
linebuf.buf[n++] = c;
|
||||
linebuf.buf[n++] = (char) c;
|
||||
if (read_len != size_t_null && read_len > 0 && n >= read_len)
|
||||
{
|
||||
new_pos = ch_tell();
|
||||
break;
|
||||
}
|
||||
c = ch_forw_get();
|
||||
}
|
||||
linebuf.buf[n] = '\0';
|
||||
|
|
@ -1370,13 +1531,18 @@ public POSITION forw_raw_line(POSITION curr_pos, char **linep, int *line_lenp)
|
|||
return (new_pos);
|
||||
}
|
||||
|
||||
public POSITION forw_raw_line(POSITION curr_pos, constant char **linep, size_t *line_lenp)
|
||||
{
|
||||
return forw_raw_line_len(curr_pos, size_t_null, linep, line_lenp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Analogous to back_line(), but deals with "raw lines".
|
||||
* {{ This is supposed to be more efficient than back_line(). }}
|
||||
*/
|
||||
public POSITION back_raw_line(POSITION curr_pos, char **linep, int *line_lenp)
|
||||
public POSITION back_raw_line(POSITION curr_pos, constant char **linep, size_t *line_lenp)
|
||||
{
|
||||
int n;
|
||||
size_t n;
|
||||
int c;
|
||||
POSITION new_pos;
|
||||
|
||||
|
|
@ -1410,7 +1576,7 @@ public POSITION back_raw_line(POSITION curr_pos, char **linep, int *line_lenp)
|
|||
}
|
||||
if (n <= 0)
|
||||
{
|
||||
int old_size_linebuf = size_linebuf;
|
||||
size_t old_size_linebuf = size_linebuf;
|
||||
char *fm;
|
||||
char *to;
|
||||
if (expand_linebuf())
|
||||
|
|
@ -1431,7 +1597,7 @@ public POSITION back_raw_line(POSITION curr_pos, char **linep, int *line_lenp)
|
|||
*to = *fm;
|
||||
n = size_linebuf - old_size_linebuf;
|
||||
}
|
||||
linebuf.buf[--n] = c;
|
||||
linebuf.buf[--n] = (char) c;
|
||||
}
|
||||
if (linep != NULL)
|
||||
*linep = &linebuf.buf[n];
|
||||
|
|
@ -1444,16 +1610,16 @@ public POSITION back_raw_line(POSITION curr_pos, char **linep, int *line_lenp)
|
|||
* 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)
|
||||
public int skip_columns(int cols, constant char **linep, size_t *line_lenp)
|
||||
{
|
||||
char *line = *linep;
|
||||
char *eline = line + *line_lenp;
|
||||
constant char *line = *linep;
|
||||
constant char *eline = line + *line_lenp;
|
||||
LWCHAR pch = 0;
|
||||
int bytes;
|
||||
size_t bytes;
|
||||
|
||||
while (cols > 0 && line < eline)
|
||||
{
|
||||
LWCHAR ch = step_char(&line, +1, eline);
|
||||
LWCHAR ch = step_charc(&line, +1, eline);
|
||||
struct ansi_state *pansi = ansi_start(ch);
|
||||
if (pansi != NULL)
|
||||
{
|
||||
|
|
@ -1467,10 +1633,10 @@ public int skip_columns(int cols, char **linep, int *line_lenp)
|
|||
pch = ch;
|
||||
}
|
||||
}
|
||||
bytes = line - *linep;
|
||||
bytes = ptr_diff(line, *linep);
|
||||
*linep = line;
|
||||
*line_lenp -= bytes;
|
||||
return (bytes);
|
||||
return (int) bytes; /*{{type-issue}}*/
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1520,13 +1686,15 @@ public int rrshift(void)
|
|||
{
|
||||
POSITION pos;
|
||||
int save_width;
|
||||
int line;
|
||||
int sline;
|
||||
int longest = 0;
|
||||
|
||||
save_width = sc_width;
|
||||
sc_width = INT_MAX;
|
||||
pos = position(TOP);
|
||||
for (line = 0; line < sc_height && pos != NULL_POSITION; line++)
|
||||
sc_width = INT_MAX; /* so forw_line() won't chop */
|
||||
for (sline = TOP; sline < sc_height; sline++)
|
||||
if ((pos = position(sline)) != NULL_POSITION)
|
||||
break;
|
||||
for (; sline < sc_height && pos != NULL_POSITION; sline++)
|
||||
{
|
||||
pos = forw_line(pos);
|
||||
if (end_column > longest)
|
||||
|
|
@ -1544,7 +1712,7 @@ public int rrshift(void)
|
|||
static int lookup_color_index(int attr)
|
||||
{
|
||||
int cx;
|
||||
for (cx = 0; cx < sizeof(color_map)/sizeof(*color_map); cx++)
|
||||
for (cx = 0; cx < countof(color_map); cx++)
|
||||
if (color_map[cx].attr == attr)
|
||||
return cx;
|
||||
return -1;
|
||||
|
|
@ -1568,14 +1736,14 @@ static int color_index(int attr)
|
|||
/*
|
||||
* Set the color string to use for a given attribute.
|
||||
*/
|
||||
public int set_color_map(int attr, char *colorstr)
|
||||
public int set_color_map(int attr, constant char *colorstr)
|
||||
{
|
||||
int cx = color_index(attr);
|
||||
if (cx < 0)
|
||||
return -1;
|
||||
if (strlen(colorstr)+1 > sizeof(color_map[cx].color))
|
||||
return -1;
|
||||
if (*colorstr != '\0' && parse_color(colorstr, NULL, NULL) == CT_NULL)
|
||||
if (*colorstr != '\0' && parse_color(colorstr, NULL, NULL, NULL) == CT_NULL)
|
||||
return -1;
|
||||
strcpy(color_map[cx].color, colorstr);
|
||||
return 0;
|
||||
|
|
@ -1584,7 +1752,7 @@ public int set_color_map(int attr, char *colorstr)
|
|||
/*
|
||||
* Get the color string to use for a given attribute.
|
||||
*/
|
||||
public char * get_color_map(int attr)
|
||||
public constant char * get_color_map(int attr)
|
||||
{
|
||||
int cx = color_index(attr);
|
||||
if (cx < 0)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -63,12 +63,11 @@ static struct linenum_info anchor; /* Anchor of the list */
|
|||
static struct linenum_info *freelist; /* Anchor of the unused entries */
|
||||
static struct linenum_info pool[NPOOL]; /* The pool itself */
|
||||
static struct linenum_info *spare; /* We always keep one spare entry */
|
||||
public int scanning_eof = FALSE;
|
||||
public lbool scanning_eof = FALSE;
|
||||
|
||||
extern int linenums;
|
||||
extern int sigs;
|
||||
extern int sc_height;
|
||||
extern int screen_trashed;
|
||||
extern int header_lines;
|
||||
extern int nonum_headers;
|
||||
|
||||
|
|
@ -210,28 +209,41 @@ static void longloopmessage(void)
|
|||
ierror("Calculating line numbers", NULL_PARG);
|
||||
}
|
||||
|
||||
static int loopcount;
|
||||
struct delayed_msg
|
||||
{
|
||||
void (*message)(void);
|
||||
int loopcount;
|
||||
#if HAVE_TIME
|
||||
static time_type startime;
|
||||
time_type startime;
|
||||
#endif
|
||||
};
|
||||
|
||||
static void longish(void)
|
||||
static void start_delayed_msg(struct delayed_msg *dmsg, void (*message)(void))
|
||||
{
|
||||
dmsg->loopcount = 0;
|
||||
dmsg->message = message;
|
||||
#if HAVE_TIME
|
||||
dmsg->startime = get_time();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void delayed_msg(struct delayed_msg *dmsg)
|
||||
{
|
||||
#if HAVE_TIME
|
||||
if (loopcount >= 0 && ++loopcount > 100)
|
||||
if (dmsg->loopcount >= 0 && ++(dmsg->loopcount) > 100)
|
||||
{
|
||||
loopcount = 0;
|
||||
if (get_time() >= startime + LONGTIME)
|
||||
dmsg->loopcount = 0;
|
||||
if (get_time() >= dmsg->startime + LONGTIME)
|
||||
{
|
||||
longloopmessage();
|
||||
loopcount = -1;
|
||||
dmsg->message();
|
||||
dmsg->loopcount = -1;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (loopcount >= 0 && ++loopcount > LONGLOOP)
|
||||
if (dmsg->loopcount >= 0 && ++(dmsg->loopcount) > LONGLOOP)
|
||||
{
|
||||
longloopmessage();
|
||||
loopcount = -1;
|
||||
dmsg->message();
|
||||
dmsg->loopcount = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -240,15 +252,15 @@ static void longish(void)
|
|||
* Turn off line numbers because the user has interrupted
|
||||
* a lengthy line number calculation.
|
||||
*/
|
||||
static void abort_long(void)
|
||||
static void abort_delayed_msg(struct delayed_msg *dmsg)
|
||||
{
|
||||
if (loopcount >= 0)
|
||||
if (dmsg->loopcount >= 0)
|
||||
return;
|
||||
if (linenums == OPT_ONPLUS)
|
||||
/*
|
||||
* We were displaying line numbers, so need to repaint.
|
||||
*/
|
||||
screen_trashed = 1;
|
||||
screen_trashed();
|
||||
linenums = 0;
|
||||
error("Line numbers turned off", NULL_PARG);
|
||||
}
|
||||
|
|
@ -262,6 +274,7 @@ public LINENUM find_linenum(POSITION pos)
|
|||
struct linenum_info *p;
|
||||
LINENUM linenum;
|
||||
POSITION cpos;
|
||||
struct delayed_msg dmsg;
|
||||
|
||||
if (!linenums)
|
||||
/*
|
||||
|
|
@ -299,10 +312,7 @@ public LINENUM find_linenum(POSITION pos)
|
|||
* The decision is based on which way involves
|
||||
* traversing fewer bytes in the file.
|
||||
*/
|
||||
#if HAVE_TIME
|
||||
startime = get_time();
|
||||
#endif
|
||||
loopcount = 0;
|
||||
start_delayed_msg(&dmsg, longloopmessage);
|
||||
if (p == &anchor || pos - p->prev->pos < p->pos - pos)
|
||||
{
|
||||
/*
|
||||
|
|
@ -316,14 +326,14 @@ public LINENUM find_linenum(POSITION pos)
|
|||
/*
|
||||
* Allow a signal to abort this loop.
|
||||
*/
|
||||
cpos = forw_raw_line(cpos, (char **)NULL, (int *)NULL);
|
||||
cpos = forw_raw_line(cpos, NULL, NULL);
|
||||
if (ABORT_SIGS()) {
|
||||
abort_long();
|
||||
abort_delayed_msg(&dmsg);
|
||||
return (0);
|
||||
}
|
||||
if (cpos == NULL_POSITION)
|
||||
return (0);
|
||||
longish();
|
||||
delayed_msg(&dmsg);
|
||||
}
|
||||
/*
|
||||
* We might as well cache it.
|
||||
|
|
@ -347,21 +357,20 @@ public LINENUM find_linenum(POSITION pos)
|
|||
/*
|
||||
* Allow a signal to abort this loop.
|
||||
*/
|
||||
cpos = back_raw_line(cpos, (char **)NULL, (int *)NULL);
|
||||
cpos = back_raw_line(cpos, NULL, NULL);
|
||||
if (ABORT_SIGS()) {
|
||||
abort_long();
|
||||
abort_delayed_msg(&dmsg);
|
||||
return (0);
|
||||
}
|
||||
if (cpos == NULL_POSITION)
|
||||
return (0);
|
||||
longish();
|
||||
delayed_msg(&dmsg);
|
||||
}
|
||||
/*
|
||||
* We might as well cache it.
|
||||
*/
|
||||
add_lnum(linenum, cpos);
|
||||
}
|
||||
loopcount = 0;
|
||||
return (linenum);
|
||||
}
|
||||
|
||||
|
|
@ -403,7 +412,7 @@ public POSITION find_pos(LINENUM linenum)
|
|||
/*
|
||||
* Allow a signal to abort this loop.
|
||||
*/
|
||||
cpos = forw_raw_line(cpos, (char **)NULL, (int *)NULL);
|
||||
cpos = forw_raw_line(cpos, NULL, NULL);
|
||||
if (ABORT_SIGS())
|
||||
return (NULL_POSITION);
|
||||
if (cpos == NULL_POSITION)
|
||||
|
|
@ -421,7 +430,7 @@ public POSITION find_pos(LINENUM linenum)
|
|||
/*
|
||||
* Allow a signal to abort this loop.
|
||||
*/
|
||||
cpos = back_raw_line(cpos, (char **)NULL, (int *)NULL);
|
||||
cpos = back_raw_line(cpos, NULL, NULL);
|
||||
if (ABORT_SIGS())
|
||||
return (NULL_POSITION);
|
||||
if (cpos == NULL_POSITION)
|
||||
|
|
@ -458,6 +467,11 @@ public LINENUM currline(int where)
|
|||
return (linenum);
|
||||
}
|
||||
|
||||
static void detlenmessage(void)
|
||||
{
|
||||
ierror("Determining length of file", NULL_PARG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan entire file, counting line numbers.
|
||||
*/
|
||||
|
|
@ -465,23 +479,28 @@ public void scan_eof(void)
|
|||
{
|
||||
POSITION pos = ch_zero();
|
||||
LINENUM linenum = 0;
|
||||
struct delayed_msg dmsg;
|
||||
|
||||
if (ch_seek(0))
|
||||
return;
|
||||
ierror("Determining length of file", NULL_PARG);
|
||||
/*
|
||||
* scanning_eof prevents the "Waiting for data" message from
|
||||
* overwriting "Determining length of file".
|
||||
*/
|
||||
start_delayed_msg(&dmsg, detlenmessage);
|
||||
scanning_eof = TRUE;
|
||||
while (pos != NULL_POSITION)
|
||||
{
|
||||
/* For efficiency, only add one every 256 line numbers. */
|
||||
if ((linenum++ % 256) == 0)
|
||||
add_lnum(linenum, pos);
|
||||
pos = forw_raw_line(pos, (char **)NULL, (int *)NULL);
|
||||
pos = forw_raw_line(pos, NULL, NULL);
|
||||
if (ABORT_SIGS())
|
||||
{
|
||||
abort_delayed_msg(&dmsg);
|
||||
break;
|
||||
}
|
||||
delayed_msg(&dmsg);
|
||||
}
|
||||
scanning_eof = FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -32,7 +32,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
extern int screen_trashed;
|
||||
extern IFILE curr_ifile;
|
||||
|
||||
|
||||
|
|
@ -42,11 +41,11 @@ extern IFILE curr_ifile;
|
|||
* Pass the specified command to a shell to be executed.
|
||||
* Like plain "system()", but handles resetting terminal modes, etc.
|
||||
*/
|
||||
public void lsystem(char *cmd, char *donemsg)
|
||||
public void lsystem(constant char *cmd, constant char *donemsg)
|
||||
{
|
||||
int inp;
|
||||
#if HAVE_SHELL
|
||||
char *shell;
|
||||
constant char *shell;
|
||||
char *p;
|
||||
#endif
|
||||
IFILE save_ifile;
|
||||
|
|
@ -136,7 +135,7 @@ public void lsystem(char *cmd, char *donemsg)
|
|||
char *esccmd = shell_quote(cmd);
|
||||
if (esccmd != NULL)
|
||||
{
|
||||
int len = (int) (strlen(shell) + strlen(esccmd) + 5);
|
||||
size_t len = strlen(shell) + strlen(esccmd) + 5;
|
||||
p = (char *) ecalloc(len, sizeof(char));
|
||||
SNPRINTF3(p, len, "%s %s %s", shell, shell_coption(), esccmd);
|
||||
free(esccmd);
|
||||
|
|
@ -193,7 +192,7 @@ public void lsystem(char *cmd, char *donemsg)
|
|||
flush();
|
||||
}
|
||||
init();
|
||||
screen_trashed = 1;
|
||||
screen_trashed();
|
||||
|
||||
#if MSDOS_COMPILER && MSDOS_COMPILER!=WIN32C
|
||||
/*
|
||||
|
|
@ -248,7 +247,7 @@ public void lsystem(char *cmd, char *donemsg)
|
|||
* If the mark is on the current screen, or if the mark is ".",
|
||||
* the whole current screen is piped.
|
||||
*/
|
||||
public int pipe_mark(int c, char *cmd)
|
||||
public int pipe_mark(char c, constant char *cmd)
|
||||
{
|
||||
POSITION mpos, tpos, bpos;
|
||||
|
||||
|
|
@ -279,7 +278,7 @@ public int pipe_mark(int c, char *cmd)
|
|||
* Create a pipe to the given shell command.
|
||||
* Feed it the file contents between the positions spos and epos.
|
||||
*/
|
||||
public int pipe_data(char *cmd, POSITION spos, POSITION epos)
|
||||
public int pipe_data(constant char *cmd, POSITION spos, POSITION epos)
|
||||
{
|
||||
FILE *f;
|
||||
int c;
|
||||
|
|
@ -353,7 +352,7 @@ public int pipe_data(char *cmd, POSITION spos, POSITION epos)
|
|||
init_signals(1);
|
||||
raw_mode(1);
|
||||
init();
|
||||
screen_trashed = 1;
|
||||
screen_trashed();
|
||||
#if defined(SIGWINCH) || defined(SIGWIND)
|
||||
/* {{ Probably don't need this here. }} */
|
||||
winch(0);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* $FreeBSD$ */
|
||||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -17,10 +17,19 @@
|
|||
#if MSDOS_COMPILER==WIN32C
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#if defined(MINGW) || defined(_MSC_VER)
|
||||
#include <locale.h>
|
||||
#include <shellapi.h>
|
||||
#endif
|
||||
|
||||
public unsigned less_acp = CP_ACP;
|
||||
#endif
|
||||
|
||||
#include "option.h"
|
||||
|
||||
public char * every_first_cmd = NULL;
|
||||
public int new_file;
|
||||
public lbool new_file;
|
||||
public int is_tty;
|
||||
public IFILE curr_ifile = NULL_IFILE;
|
||||
public IFILE old_ifile = NULL_IFILE;
|
||||
|
|
@ -28,20 +37,21 @@ public struct scrpos initial_scrpos;
|
|||
public POSITION start_attnpos = NULL_POSITION;
|
||||
public POSITION end_attnpos = NULL_POSITION;
|
||||
public int wscroll;
|
||||
public char * progname;
|
||||
public constant char *progname;
|
||||
public int quitting;
|
||||
public int secure;
|
||||
public int dohelp;
|
||||
public char * init_header = NULL;
|
||||
static int secure_allow_features;
|
||||
|
||||
#if LOGFILE
|
||||
public int logfile = -1;
|
||||
public int force_logfile = FALSE;
|
||||
public lbool force_logfile = FALSE;
|
||||
public char * namelogfile = NULL;
|
||||
#endif
|
||||
|
||||
#if EDITOR
|
||||
public char * editor;
|
||||
public char * editproto;
|
||||
public constant char * editor;
|
||||
public constant char * editproto;
|
||||
#endif
|
||||
|
||||
#if TAGS
|
||||
|
|
@ -51,14 +61,13 @@ extern int jump_sline;
|
|||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
static char consoleTitle[256];
|
||||
static wchar_t consoleTitle[256];
|
||||
#endif
|
||||
|
||||
public int one_screen;
|
||||
extern int less_is_more;
|
||||
extern int missing_cap;
|
||||
extern int know_dumb;
|
||||
extern int pr_type;
|
||||
extern int quit_if_one_screen;
|
||||
extern int no_init;
|
||||
extern int errmsgs;
|
||||
|
|
@ -66,13 +75,178 @@ extern int redraw_on_quit;
|
|||
extern int term_init_done;
|
||||
extern int first_time;
|
||||
|
||||
#if MSDOS_COMPILER==WIN32C && (defined(MINGW) || defined(_MSC_VER))
|
||||
/* malloc'ed 0-terminated utf8 of 0-terminated wide ws, or null on errors */
|
||||
static char *utf8_from_wide(constant wchar_t *ws)
|
||||
{
|
||||
char *u8 = NULL;
|
||||
int n = WideCharToMultiByte(CP_UTF8, 0, ws, -1, NULL, 0, NULL, NULL);
|
||||
if (n > 0)
|
||||
{
|
||||
u8 = ecalloc(n, sizeof(char));
|
||||
WideCharToMultiByte(CP_UTF8, 0, ws, -1, u8, n, NULL, NULL);
|
||||
}
|
||||
return u8;
|
||||
}
|
||||
|
||||
/*
|
||||
* similar to using UTF8 manifest to make the ANSI APIs UTF8, but dynamically
|
||||
* with setlocale. unlike the manifest, argv and environ are already ACP, so
|
||||
* make them UTF8. Additionally, this affects only the libc/crt API, and so
|
||||
* e.g. fopen filename becomes UTF-8, but CreateFileA filename remains CP_ACP.
|
||||
* CP_ACP remains the original codepage - use the dynamic less_acp instead.
|
||||
* effective on win 10 1803 or later when compiled with ucrt, else no-op.
|
||||
*/
|
||||
static void try_utf8_locale(int *pargc, constant char ***pargv)
|
||||
{
|
||||
char *locale_orig = strdup(setlocale(LC_ALL, NULL));
|
||||
wchar_t **wargv = NULL, *wenv, *wp;
|
||||
constant char **u8argv;
|
||||
char *u8e;
|
||||
int i, n;
|
||||
|
||||
if (!setlocale(LC_ALL, ".UTF8"))
|
||||
goto cleanup; /* not win10 1803+ or not ucrt */
|
||||
|
||||
/*
|
||||
* wargv is before glob expansion. some ucrt builds may expand globs
|
||||
* before main is entered, so n may be smaller than the original argc.
|
||||
* that's ok, because later code at main expands globs anyway.
|
||||
*/
|
||||
wargv = CommandLineToArgvW(GetCommandLineW(), &n);
|
||||
if (!wargv)
|
||||
goto bad_args;
|
||||
|
||||
u8argv = (constant char **) ecalloc(n + 1, sizeof(char *));
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
if (!(u8argv[i] = utf8_from_wide(wargv[i])))
|
||||
goto bad_args;
|
||||
}
|
||||
u8argv[n] = 0;
|
||||
|
||||
less_acp = CP_UTF8;
|
||||
*pargc = n;
|
||||
*pargv = u8argv; /* leaked on exit */
|
||||
|
||||
/* convert wide env to utf8 where we can, but don't abort on errors */
|
||||
if ((wenv = GetEnvironmentStringsW()))
|
||||
{
|
||||
for (wp = wenv; *wp; wp += wcslen(wp) + 1)
|
||||
{
|
||||
if ((u8e = utf8_from_wide(wp)))
|
||||
_putenv(u8e);
|
||||
free(u8e); /* windows putenv makes a copy */
|
||||
}
|
||||
FreeEnvironmentStringsW(wenv);
|
||||
}
|
||||
|
||||
goto cleanup;
|
||||
|
||||
bad_args:
|
||||
error("WARNING: cannot use unicode arguments", NULL_PARG);
|
||||
setlocale(LC_ALL, locale_orig);
|
||||
|
||||
cleanup:
|
||||
free(locale_orig);
|
||||
LocalFree(wargv);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int security_feature_error(constant char *type, size_t len, constant char *name)
|
||||
{
|
||||
PARG parg;
|
||||
size_t msglen = len + strlen(type) + 64;
|
||||
char *msg = ecalloc(msglen, sizeof(char));
|
||||
SNPRINTF3(msg, msglen, "LESSSECURE_ALLOW: %s feature name \"%.*s\"", type, (int) len, name);
|
||||
parg.p_string = msg;
|
||||
error("%s", &parg);
|
||||
free(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the SF_xxx value of a secure feature given the name of the feature.
|
||||
*/
|
||||
static int security_feature(constant char *name, size_t len)
|
||||
{
|
||||
struct secure_feature { constant char *name; int sf_value; };
|
||||
static struct secure_feature features[] = {
|
||||
{ "edit", SF_EDIT },
|
||||
{ "examine", SF_EXAMINE },
|
||||
{ "glob", SF_GLOB },
|
||||
{ "history", SF_HISTORY },
|
||||
{ "lesskey", SF_LESSKEY },
|
||||
{ "lessopen", SF_LESSOPEN },
|
||||
{ "logfile", SF_LOGFILE },
|
||||
{ "osc8", SF_OSC8_OPEN },
|
||||
{ "pipe", SF_PIPE },
|
||||
{ "shell", SF_SHELL },
|
||||
{ "stop", SF_STOP },
|
||||
{ "tags", SF_TAGS },
|
||||
};
|
||||
int i;
|
||||
int match = -1;
|
||||
|
||||
for (i = 0; i < countof(features); i++)
|
||||
{
|
||||
if (strncmp(features[i].name, name, len) == 0)
|
||||
{
|
||||
if (match >= 0) /* name is ambiguous */
|
||||
return security_feature_error("ambiguous", len, name);
|
||||
match = i;
|
||||
}
|
||||
}
|
||||
if (match < 0)
|
||||
return security_feature_error("invalid", len, name);
|
||||
return features[match].sf_value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the secure_allow_features bitmask, which controls
|
||||
* whether certain secure features are allowed.
|
||||
*/
|
||||
static void init_secure(void)
|
||||
{
|
||||
#if SECURE
|
||||
secure_allow_features = 0;
|
||||
#else
|
||||
constant char *str = lgetenv("LESSSECURE");
|
||||
if (isnullenv(str))
|
||||
secure_allow_features = ~0; /* allow everything */
|
||||
else
|
||||
secure_allow_features = 0; /* allow nothing */
|
||||
|
||||
str = lgetenv("LESSSECURE_ALLOW");
|
||||
if (!isnullenv(str))
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
constant char *estr;
|
||||
while (*str == ' ' || *str == ',') ++str; /* skip leading spaces/commas */
|
||||
if (*str == '\0') break;
|
||||
estr = strchr(str, ',');
|
||||
if (estr == NULL) estr = str + strlen(str);
|
||||
while (estr > str && estr[-1] == ' ') --estr; /* trim trailing spaces */
|
||||
secure_allow_features |= security_feature(str, ptr_diff(estr, str));
|
||||
str = estr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Entry point.
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
int main(int argc, constant char *argv[])
|
||||
{
|
||||
IFILE ifile;
|
||||
char *s;
|
||||
constant char *s;
|
||||
|
||||
#if MSDOS_COMPILER==WIN32C && (defined(MINGW) || defined(_MSC_VER))
|
||||
if (GetACP() != CP_UTF8) /* not using a UTF-8 manifest */
|
||||
try_utf8_locale(&argc, &argv);
|
||||
#endif
|
||||
|
||||
#ifdef __EMX__
|
||||
_response(&argc, &argv);
|
||||
|
|
@ -81,15 +255,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
progname = *argv++;
|
||||
argc--;
|
||||
|
||||
#if SECURE
|
||||
secure = 1;
|
||||
#else
|
||||
secure = 0;
|
||||
s = lgetenv("LESSSECURE");
|
||||
if (!isnullenv(s))
|
||||
secure = 1;
|
||||
#endif
|
||||
init_secure();
|
||||
|
||||
#ifdef WIN32
|
||||
if (getenv("HOME") == NULL)
|
||||
|
|
@ -110,7 +276,8 @@ int main(int argc, char *argv[])
|
|||
putenv(env);
|
||||
}
|
||||
}
|
||||
GetConsoleTitle(consoleTitle, sizeof(consoleTitle)/sizeof(char));
|
||||
/* on failure, consoleTitle is already a valid empty string */
|
||||
GetConsoleTitleW(consoleTitle, countof(consoleTitle));
|
||||
#endif /* WIN32 */
|
||||
|
||||
/*
|
||||
|
|
@ -121,7 +288,6 @@ int main(int argc, char *argv[])
|
|||
init_mark();
|
||||
init_cmds();
|
||||
init_poll();
|
||||
get_term();
|
||||
init_charset();
|
||||
init_line();
|
||||
init_cmdhist();
|
||||
|
|
@ -132,15 +298,14 @@ int main(int argc, char *argv[])
|
|||
* If the name of the executable program is "more",
|
||||
* act like LESS_IS_MORE is set.
|
||||
*/
|
||||
s = last_component(progname);
|
||||
if (strcmp(s, "more") == 0)
|
||||
if (strcmp(last_component(progname), "more") == 0) {
|
||||
less_is_more = 1;
|
||||
scan_option("-fG");
|
||||
}
|
||||
|
||||
init_prompt();
|
||||
|
||||
if (less_is_more)
|
||||
scan_option("-fG");
|
||||
|
||||
init_unsupport();
|
||||
s = lgetenv(less_is_more ? "MORE" : "LESS");
|
||||
if (s != NULL)
|
||||
scan_option(s);
|
||||
|
|
@ -170,6 +335,7 @@ int main(int argc, char *argv[])
|
|||
if (less_is_more)
|
||||
no_init = TRUE;
|
||||
|
||||
get_term();
|
||||
expand_cmd_tables();
|
||||
|
||||
#if EDITOR
|
||||
|
|
@ -202,7 +368,7 @@ int main(int argc, char *argv[])
|
|||
* Expand the pattern and iterate over the expanded list.
|
||||
*/
|
||||
struct textlist tlist;
|
||||
char *filename;
|
||||
constant char *filename;
|
||||
char *gfilename;
|
||||
char *qfilename;
|
||||
|
||||
|
|
@ -294,6 +460,12 @@ int main(int argc, char *argv[])
|
|||
one_screen = get_one_screen();
|
||||
}
|
||||
}
|
||||
if (init_header != NULL)
|
||||
{
|
||||
opt_header(TOGGLE, init_header);
|
||||
free(init_header);
|
||||
init_header = NULL;
|
||||
}
|
||||
|
||||
if (errmsgs > 0)
|
||||
{
|
||||
|
|
@ -318,13 +490,17 @@ int main(int argc, char *argv[])
|
|||
* Copy a string to a "safe" place
|
||||
* (that is, to a buffer allocated by calloc).
|
||||
*/
|
||||
public char * saven(constant char *s, size_t n)
|
||||
{
|
||||
char *p = (char *) ecalloc(n+1, sizeof(char));
|
||||
strncpy(p, s, n);
|
||||
p[n] = '\0';
|
||||
return (p);
|
||||
}
|
||||
|
||||
public char * save(constant char *s)
|
||||
{
|
||||
char *p;
|
||||
|
||||
p = (char *) ecalloc(strlen(s)+1, sizeof(char));
|
||||
strcpy(p, s);
|
||||
return (p);
|
||||
return saven(s, strlen(s));
|
||||
}
|
||||
|
||||
public void out_of_memory(void)
|
||||
|
|
@ -337,7 +513,7 @@ public void out_of_memory(void)
|
|||
* Allocate memory.
|
||||
* Like calloc(), but never returns an error (NULL).
|
||||
*/
|
||||
public void * ecalloc(int count, unsigned int size)
|
||||
public void * ecalloc(size_t count, size_t size)
|
||||
{
|
||||
void * p;
|
||||
|
||||
|
|
@ -357,16 +533,24 @@ public char * skipsp(char *s)
|
|||
return (s);
|
||||
}
|
||||
|
||||
/* {{ There must be a better way. }} */
|
||||
public constant char * skipspc(constant char *s)
|
||||
{
|
||||
while (*s == ' ' || *s == '\t')
|
||||
s++;
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* See how many characters of two strings are identical.
|
||||
* If uppercase is true, the first string must begin with an uppercase
|
||||
* character; the remainder of the first string may be either case.
|
||||
*/
|
||||
public int sprefix(char *ps, char *s, int uppercase)
|
||||
public size_t sprefix(constant char *ps, constant char *s, int uppercase)
|
||||
{
|
||||
int c;
|
||||
int sc;
|
||||
int len = 0;
|
||||
char c;
|
||||
char sc;
|
||||
size_t len = 0;
|
||||
|
||||
for ( ; *s != '\0'; s++, ps++)
|
||||
{
|
||||
|
|
@ -374,7 +558,7 @@ public int sprefix(char *ps, char *s, int uppercase)
|
|||
if (uppercase)
|
||||
{
|
||||
if (len == 0 && ASCII_IS_LOWER(c))
|
||||
return (-1);
|
||||
return (0);
|
||||
if (ASCII_IS_UPPER(c))
|
||||
c = ASCII_TO_LOWER(c);
|
||||
}
|
||||
|
|
@ -433,8 +617,16 @@ public void quit(int status)
|
|||
close(2);
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
SetConsoleTitle(consoleTitle);
|
||||
SetConsoleTitleW(consoleTitle);
|
||||
#endif
|
||||
close_getchr();
|
||||
exit(status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Are all the features in the features mask allowed by security?
|
||||
*/
|
||||
public int secure_allow(int features)
|
||||
{
|
||||
return ((secure_allow_features & features) == features);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -73,7 +73,7 @@ public void init_mark(void)
|
|||
switch (i) {
|
||||
case MOUSEMARK: letter = '#'; break;
|
||||
case LASTMARK: letter = '\''; break;
|
||||
default: letter = (i < 26) ? 'a'+i : 'A'+i-26; break;
|
||||
default: letter = (char) ((i < 26) ? 'a'+i : 'A'+i-26); break;
|
||||
}
|
||||
marks[i].m_letter = letter;
|
||||
cmark(&marks[i], NULL_IFILE, NULL_POSITION, -1);
|
||||
|
|
@ -104,7 +104,7 @@ static void mark_get_ifile(struct mark *m)
|
|||
/*
|
||||
* Return the user mark struct identified by a character.
|
||||
*/
|
||||
static struct mark * getumark(LWCHAR c)
|
||||
static struct mark * getumark(char c)
|
||||
{
|
||||
PARG parg;
|
||||
if (c >= 'a' && c <= 'z')
|
||||
|
|
@ -125,7 +125,7 @@ static struct mark * getumark(LWCHAR c)
|
|||
* The mark struct may either be in the mark table (user mark)
|
||||
* or may be constructed on the fly for certain characters like ^, $.
|
||||
*/
|
||||
static struct mark * getmark(LWCHAR c)
|
||||
static struct mark * getmark(char c)
|
||||
{
|
||||
struct mark *m;
|
||||
static struct mark sm;
|
||||
|
|
@ -185,7 +185,7 @@ static struct mark * getmark(LWCHAR c)
|
|||
/*
|
||||
* Is a mark letter invalid?
|
||||
*/
|
||||
public int badmark(LWCHAR c)
|
||||
public int badmark(char c)
|
||||
{
|
||||
return (getmark(c) == NULL);
|
||||
}
|
||||
|
|
@ -193,7 +193,7 @@ public int badmark(LWCHAR c)
|
|||
/*
|
||||
* Set a user-defined mark.
|
||||
*/
|
||||
public void setmark(LWCHAR c, int where)
|
||||
public void setmark(char c, int where)
|
||||
{
|
||||
struct mark *m;
|
||||
struct scrpos scrpos;
|
||||
|
|
@ -214,7 +214,7 @@ public void setmark(LWCHAR c, int where)
|
|||
/*
|
||||
* Clear a user-defined mark.
|
||||
*/
|
||||
public void clrmark(LWCHAR c)
|
||||
public void clrmark(char c)
|
||||
{
|
||||
struct mark *m;
|
||||
|
||||
|
|
@ -249,7 +249,7 @@ public void lastmark(void)
|
|||
/*
|
||||
* Go to a mark.
|
||||
*/
|
||||
public void gomark(LWCHAR c)
|
||||
public void gomark(char c)
|
||||
{
|
||||
struct mark *m;
|
||||
struct scrpos scrpos;
|
||||
|
|
@ -290,7 +290,7 @@ public void gomark(LWCHAR c)
|
|||
* is associated with, but this doesn't matter much,
|
||||
* because it's always the first non-blank line on the screen.
|
||||
*/
|
||||
public POSITION markpos(LWCHAR c)
|
||||
public POSITION markpos(char c)
|
||||
{
|
||||
struct mark *m;
|
||||
|
||||
|
|
@ -311,15 +311,15 @@ public POSITION markpos(LWCHAR c)
|
|||
*/
|
||||
public char posmark(POSITION pos)
|
||||
{
|
||||
int i;
|
||||
unsigned char i;
|
||||
|
||||
/* Only user marks */
|
||||
for (i = 0; i < NUMARKS; i++)
|
||||
{
|
||||
if (marks[i].m_ifile == curr_ifile && marks[i].m_scrpos.pos == pos)
|
||||
{
|
||||
if (i < 26) return 'a' + i;
|
||||
if (i < 26*2) return 'A' + (i - 26);
|
||||
if (i < 26) return (char) ('a' + i);
|
||||
if (i < 26*2) return (char) ('A' + (i - 26));
|
||||
return '#';
|
||||
}
|
||||
}
|
||||
|
|
@ -345,7 +345,7 @@ public void unmark(IFILE ifile)
|
|||
public void mark_check_ifile(IFILE ifile)
|
||||
{
|
||||
int i;
|
||||
char *filename = get_real_filename(ifile);
|
||||
constant char *filename = get_real_filename(ifile);
|
||||
|
||||
for (i = 0; i < NMARKS; i++)
|
||||
{
|
||||
|
|
@ -366,7 +366,7 @@ public void mark_check_ifile(IFILE ifile)
|
|||
/*
|
||||
* Save marks to history file.
|
||||
*/
|
||||
public void save_marks(FILE *fout, char *hdr)
|
||||
public void save_marks(FILE *fout, constant char *hdr)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -376,7 +376,7 @@ public void save_marks(FILE *fout, char *hdr)
|
|||
fprintf(fout, "%s\n", hdr);
|
||||
for (i = 0; i < NMARKS; i++)
|
||||
{
|
||||
char *filename;
|
||||
constant char *filename;
|
||||
struct mark *m = &marks[i];
|
||||
char pos_str[INT_STRLEN_BOUND(m->m_scrpos.pos) + 2];
|
||||
if (m->m_scrpos.pos == NULL_POSITION)
|
||||
|
|
@ -394,7 +394,7 @@ public void save_marks(FILE *fout, char *hdr)
|
|||
/*
|
||||
* Restore one mark from the history file.
|
||||
*/
|
||||
public void restore_mark(char *line)
|
||||
public void restore_mark(constant char *line)
|
||||
{
|
||||
struct mark *m;
|
||||
int ln;
|
||||
|
|
@ -408,7 +408,7 @@ public void restore_mark(char *line)
|
|||
if (m == NULL)
|
||||
return;
|
||||
skip_whitespace;
|
||||
ln = lstrtoi(line, &line, 10);
|
||||
ln = lstrtoic(line, &line, 10);
|
||||
if (ln < 0)
|
||||
return;
|
||||
if (ln < 1)
|
||||
|
|
@ -416,7 +416,7 @@ public void restore_mark(char *line)
|
|||
if (ln > sc_height)
|
||||
ln = sc_height;
|
||||
skip_whitespace;
|
||||
pos = lstrtopos(line, &line, 10);
|
||||
pos = lstrtoposc(line, &line, 10);
|
||||
if (pos < 0)
|
||||
return;
|
||||
skip_whitespace;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -26,17 +26,15 @@
|
|||
|
||||
#include "less.h"
|
||||
#include "option.h"
|
||||
#include "position.h"
|
||||
|
||||
extern int nbufs;
|
||||
extern int bufspace;
|
||||
extern int pr_type;
|
||||
extern int plusoption;
|
||||
extern lbool plusoption;
|
||||
extern int swindow;
|
||||
extern int sc_width;
|
||||
extern int sc_height;
|
||||
extern int secure;
|
||||
extern int dohelp;
|
||||
extern int is_tty;
|
||||
extern char openquote;
|
||||
extern char closequote;
|
||||
extern char *prproto[];
|
||||
|
|
@ -50,7 +48,9 @@ extern int jump_sline;
|
|||
extern long jump_sline_fraction;
|
||||
extern int shift_count;
|
||||
extern long shift_count_fraction;
|
||||
extern char rscroll_char;
|
||||
extern int match_shift;
|
||||
extern long match_shift_fraction;
|
||||
extern LWCHAR rscroll_char;
|
||||
extern int rscroll_attr;
|
||||
extern int mousecap;
|
||||
extern int wheel_lines;
|
||||
|
|
@ -67,9 +67,13 @@ extern int tabstops[];
|
|||
extern int ntabstops;
|
||||
extern int tabdefault;
|
||||
extern char intr_char;
|
||||
extern int nosearch_header_lines;
|
||||
extern int nosearch_header_cols;
|
||||
extern POSITION header_start_pos;
|
||||
extern char *init_header;
|
||||
#if LOGFILE
|
||||
extern char *namelogfile;
|
||||
extern int force_logfile;
|
||||
extern lbool force_logfile;
|
||||
extern int logfile;
|
||||
#endif
|
||||
#if TAGS
|
||||
|
|
@ -78,19 +82,23 @@ extern char *tags;
|
|||
extern char ztags[];
|
||||
#endif
|
||||
#if LESSTEST
|
||||
extern char *ttyin_name;
|
||||
extern constant char *ttyin_name;
|
||||
extern int is_tty;
|
||||
#endif /*LESSTEST*/
|
||||
#if MSDOS_COMPILER
|
||||
extern int nm_fg_color, nm_bg_color;
|
||||
extern int bo_fg_color, bo_bg_color;
|
||||
extern int ul_fg_color, ul_bg_color;
|
||||
extern int so_fg_color, so_bg_color;
|
||||
extern int bl_fg_color, bl_bg_color;
|
||||
extern int nm_fg_color, nm_bg_color, nm_attr;
|
||||
extern int bo_fg_color, bo_bg_color, bo_attr;
|
||||
extern int ul_fg_color, ul_bg_color, ul_attr;
|
||||
extern int so_fg_color, so_bg_color, so_attr;
|
||||
extern int bl_fg_color, bl_bg_color, bl_attr;
|
||||
extern int sgr_mode;
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
#ifndef COMMON_LVB_UNDERSCORE
|
||||
#define COMMON_LVB_UNDERSCORE 0x8000
|
||||
#endif
|
||||
#ifndef COMMON_LVB_REVERSE_VIDEO
|
||||
#define COMMON_LVB_REVERSE_VIDEO 0x4000
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
@ -99,12 +107,12 @@ extern int sgr_mode;
|
|||
/*
|
||||
* Handler for -o option.
|
||||
*/
|
||||
public void opt_o(int type, char *s)
|
||||
public void opt_o(int type, constant char *s)
|
||||
{
|
||||
PARG parg;
|
||||
char *filename;
|
||||
|
||||
if (secure)
|
||||
if (!secure_allow(SF_LOGFILE))
|
||||
{
|
||||
error("log file support is not available", NULL_PARG);
|
||||
return;
|
||||
|
|
@ -125,7 +133,7 @@ public void opt_o(int type, char *s)
|
|||
error("Log file is already in use", NULL_PARG);
|
||||
return;
|
||||
}
|
||||
s = skipsp(s);
|
||||
s = skipspc(s);
|
||||
if (namelogfile != NULL)
|
||||
free(namelogfile);
|
||||
filename = lglob(s);
|
||||
|
|
@ -149,122 +157,109 @@ public void opt_o(int type, char *s)
|
|||
/*
|
||||
* Handler for -O option.
|
||||
*/
|
||||
public void opt__O(int type, char *s)
|
||||
public void opt__O(int type, constant char *s)
|
||||
{
|
||||
force_logfile = TRUE;
|
||||
opt_o(type, s);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int toggle_fraction(int *num, long *frac, constant char *s, constant char *printopt, void (*calc)(void))
|
||||
{
|
||||
lbool err;
|
||||
if (s == NULL)
|
||||
{
|
||||
(*calc)();
|
||||
} else if (*s == '.')
|
||||
{
|
||||
long tfrac;
|
||||
s++;
|
||||
tfrac = getfraction(&s, printopt, &err);
|
||||
if (err)
|
||||
{
|
||||
error("Invalid fraction", NULL_PARG);
|
||||
return -1;
|
||||
}
|
||||
*frac = tfrac;
|
||||
(*calc)();
|
||||
} else
|
||||
{
|
||||
int tnum = getnumc(&s, printopt, &err);
|
||||
if (err)
|
||||
{
|
||||
error("Invalid number", NULL_PARG);
|
||||
return -1;
|
||||
}
|
||||
*frac = -1;
|
||||
*num = tnum;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void query_fraction(int value, long fraction, constant char *int_msg, constant char *frac_msg)
|
||||
{
|
||||
PARG parg;
|
||||
|
||||
if (fraction < 0)
|
||||
{
|
||||
parg.p_int = value;
|
||||
error(int_msg, &parg);
|
||||
} else
|
||||
{
|
||||
char buf[INT_STRLEN_BOUND(long)+2];
|
||||
size_t len;
|
||||
SNPRINTF1(buf, sizeof(buf), ".%06ld", fraction);
|
||||
len = strlen(buf);
|
||||
while (len > 2 && buf[len-1] == '0')
|
||||
len--;
|
||||
buf[len] = '\0';
|
||||
parg.p_string = buf;
|
||||
error(frac_msg, &parg);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handlers for -j option.
|
||||
*/
|
||||
public void opt_j(int type, char *s)
|
||||
public void opt_j(int type, constant char *s)
|
||||
{
|
||||
PARG parg;
|
||||
int len;
|
||||
int err;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case INIT:
|
||||
case TOGGLE:
|
||||
if (*s == '.')
|
||||
{
|
||||
s++;
|
||||
jump_sline_fraction = getfraction(&s, "j", &err);
|
||||
if (err)
|
||||
error("Invalid line fraction", NULL_PARG);
|
||||
else
|
||||
calc_jump_sline();
|
||||
} else
|
||||
{
|
||||
int sline = getnum(&s, "j", &err);
|
||||
if (err)
|
||||
error("Invalid line number", NULL_PARG);
|
||||
else
|
||||
{
|
||||
jump_sline = sline;
|
||||
jump_sline_fraction = -1;
|
||||
}
|
||||
}
|
||||
toggle_fraction(&jump_sline, &jump_sline_fraction,
|
||||
s, "j", calc_jump_sline);
|
||||
break;
|
||||
case QUERY:
|
||||
if (jump_sline_fraction < 0)
|
||||
{
|
||||
parg.p_int = jump_sline;
|
||||
error("Position target at screen line %d", &parg);
|
||||
} else
|
||||
{
|
||||
char buf[INT_STRLEN_BOUND(long)+2];
|
||||
SNPRINTF1(buf, sizeof(buf), ".%06ld", jump_sline_fraction);
|
||||
len = (int) strlen(buf);
|
||||
while (len > 2 && buf[len-1] == '0')
|
||||
len--;
|
||||
buf[len] = '\0';
|
||||
parg.p_string = buf;
|
||||
error("Position target at screen position %s", &parg);
|
||||
}
|
||||
query_fraction(jump_sline, jump_sline_fraction,
|
||||
"Position target at screen line %d", "Position target at screen position %s");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void calc_jump_sline(void)
|
||||
{
|
||||
if (jump_sline_fraction < 0)
|
||||
return;
|
||||
jump_sline = (int) muldiv(sc_height, jump_sline_fraction, NUM_FRAC_DENOM);
|
||||
if (jump_sline_fraction >= 0)
|
||||
jump_sline = (int) muldiv(sc_height, jump_sline_fraction, NUM_FRAC_DENOM);
|
||||
if (jump_sline <= header_lines)
|
||||
jump_sline = header_lines + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handlers for -# option.
|
||||
*/
|
||||
public void opt_shift(int type, char *s)
|
||||
public void opt_shift(int type, constant char *s)
|
||||
{
|
||||
PARG parg;
|
||||
int len;
|
||||
int err;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case INIT:
|
||||
case TOGGLE:
|
||||
if (*s == '.')
|
||||
{
|
||||
s++;
|
||||
shift_count_fraction = getfraction(&s, "#", &err);
|
||||
if (err)
|
||||
error("Invalid column fraction", NULL_PARG);
|
||||
else
|
||||
calc_shift_count();
|
||||
} else
|
||||
{
|
||||
int hs = getnum(&s, "#", &err);
|
||||
if (err)
|
||||
error("Invalid column number", NULL_PARG);
|
||||
else
|
||||
{
|
||||
shift_count = hs;
|
||||
shift_count_fraction = -1;
|
||||
}
|
||||
}
|
||||
toggle_fraction(&shift_count, &shift_count_fraction,
|
||||
s, "#", calc_shift_count);
|
||||
break;
|
||||
case QUERY:
|
||||
if (shift_count_fraction < 0)
|
||||
{
|
||||
parg.p_int = shift_count;
|
||||
error("Horizontal shift %d columns", &parg);
|
||||
} else
|
||||
{
|
||||
char buf[INT_STRLEN_BOUND(long)+2];
|
||||
SNPRINTF1(buf, sizeof(buf), ".%06ld", shift_count_fraction);
|
||||
len = (int) strlen(buf);
|
||||
while (len > 2 && buf[len-1] == '0')
|
||||
len--;
|
||||
buf[len] = '\0';
|
||||
parg.p_string = buf;
|
||||
error("Horizontal shift %s of screen width", &parg);
|
||||
}
|
||||
query_fraction(shift_count, shift_count_fraction,
|
||||
"Horizontal shift %d columns", "Horizontal shift %s of screen width");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -277,7 +272,7 @@ public void calc_shift_count(void)
|
|||
}
|
||||
|
||||
#if USERFILE
|
||||
public void opt_k(int type, char *s)
|
||||
public void opt_k(int type, constant char *s)
|
||||
{
|
||||
PARG parg;
|
||||
|
||||
|
|
@ -294,7 +289,7 @@ public void opt_k(int type, char *s)
|
|||
}
|
||||
|
||||
#if HAVE_LESSKEYSRC
|
||||
public void opt_ks(int type, char *s)
|
||||
public void opt_ks(int type, constant char *s)
|
||||
{
|
||||
PARG parg;
|
||||
|
||||
|
|
@ -309,14 +304,41 @@ public void opt_ks(int type, char *s)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void opt_kc(int type, constant char *s)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case INIT:
|
||||
if (lesskey_content(s, 0))
|
||||
{
|
||||
error("Error in lesskey content", NULL_PARG);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HAVE_LESSKEYSRC */
|
||||
#endif /* USERFILE */
|
||||
|
||||
/*
|
||||
* Handler for -S option.
|
||||
*/
|
||||
public void opt__S(int type, constant char *s)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TOGGLE:
|
||||
pos_rehead();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if TAGS
|
||||
/*
|
||||
* Handler for -t option.
|
||||
*/
|
||||
public void opt_t(int type, char *s)
|
||||
public void opt_t(int type, constant char *s)
|
||||
{
|
||||
IFILE save_ifile;
|
||||
POSITION pos;
|
||||
|
|
@ -328,12 +350,12 @@ public void opt_t(int type, char *s)
|
|||
/* Do the rest in main() */
|
||||
break;
|
||||
case TOGGLE:
|
||||
if (secure)
|
||||
if (!secure_allow(SF_TAGS))
|
||||
{
|
||||
error("tags support is not available", NULL_PARG);
|
||||
break;
|
||||
}
|
||||
findtag(skipsp(s));
|
||||
findtag(skipspc(s));
|
||||
save_ifile = save_curr_ifile();
|
||||
/*
|
||||
* Try to open the file containing the tag
|
||||
|
|
@ -354,7 +376,7 @@ public void opt_t(int type, char *s)
|
|||
/*
|
||||
* Handler for -T option.
|
||||
*/
|
||||
public void opt__T(int type, char *s)
|
||||
public void opt__T(int type, constant char *s)
|
||||
{
|
||||
PARG parg;
|
||||
char *filename;
|
||||
|
|
@ -365,7 +387,7 @@ public void opt__T(int type, char *s)
|
|||
tags = save(s);
|
||||
break;
|
||||
case TOGGLE:
|
||||
s = skipsp(s);
|
||||
s = skipspc(s);
|
||||
if (tags != NULL && tags != ztags)
|
||||
free(tags);
|
||||
filename = lglob(s);
|
||||
|
|
@ -383,7 +405,7 @@ public void opt__T(int type, char *s)
|
|||
/*
|
||||
* Handler for -p option.
|
||||
*/
|
||||
public void opt_p(int type, char *s)
|
||||
public void opt_p(int type, constant char *s)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
|
@ -407,7 +429,7 @@ public void opt_p(int type, char *s)
|
|||
*/
|
||||
ungetsc("/");
|
||||
ungetsc(s);
|
||||
ungetcc_back(CHAR_END_COMMAND);
|
||||
ungetcc_end_command();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -416,7 +438,7 @@ public void opt_p(int type, char *s)
|
|||
/*
|
||||
* Handler for -P option.
|
||||
*/
|
||||
public void opt__P(int type, char *s)
|
||||
public void opt__P(int type, constant char *s)
|
||||
{
|
||||
char **proto;
|
||||
PARG parg;
|
||||
|
|
@ -452,7 +474,7 @@ public void opt__P(int type, char *s)
|
|||
* Handler for the -b option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_b(int type, char *s)
|
||||
public void opt_b(int type, constant char *s)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
|
@ -461,7 +483,7 @@ public void opt_b(int type, char *s)
|
|||
/*
|
||||
* Set the new number of buffers.
|
||||
*/
|
||||
ch_setbufspace(bufspace);
|
||||
ch_setbufspace((ssize_t) bufspace);
|
||||
break;
|
||||
case QUERY:
|
||||
break;
|
||||
|
|
@ -472,7 +494,7 @@ public void opt_b(int type, char *s)
|
|||
* Handler for the -i option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_i(int type, char *s)
|
||||
public void opt_i(int type, constant char *s)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
|
@ -489,7 +511,7 @@ public void opt_i(int type, char *s)
|
|||
* Handler for the -V option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt__V(int type, char *s)
|
||||
public void opt__V(int type, constant char *s)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
|
@ -506,7 +528,7 @@ public void opt__V(int type, char *s)
|
|||
putstr(" regular expressions)\n");
|
||||
{
|
||||
char constant *copyright =
|
||||
"Copyright (C) 1984-2023 Mark Nudelman\n\n";
|
||||
"Copyright (C) 1984-2024 Mark Nudelman\n\n";
|
||||
putstr(copyright);
|
||||
}
|
||||
if (version[strlen(version)-1] == 'x')
|
||||
|
|
@ -531,40 +553,26 @@ public void opt__V(int type, char *s)
|
|||
/*
|
||||
* Parse an MSDOS color descriptor.
|
||||
*/
|
||||
static void colordesc(char *s, int *fg_color, int *bg_color)
|
||||
static void colordesc(constant char *s, int *fg_color, int *bg_color, int *dattr)
|
||||
{
|
||||
int fg, bg;
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
int ul = 0;
|
||||
|
||||
if (*s == 'u')
|
||||
{
|
||||
ul = COMMON_LVB_UNDERSCORE;
|
||||
s++;
|
||||
if (*s == '\0')
|
||||
{
|
||||
*fg_color = nm_fg_color | ul;
|
||||
*bg_color = nm_bg_color;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (parse_color(s, &fg, &bg) == CT_NULL)
|
||||
CHAR_ATTR attr;
|
||||
if (parse_color(s, &fg, &bg, &attr) == CT_NULL)
|
||||
{
|
||||
PARG p;
|
||||
p.p_string = s;
|
||||
error("Invalid color string \"%s\"", &p);
|
||||
} else
|
||||
{
|
||||
if (fg == CV_NOCHANGE)
|
||||
fg = nm_fg_color;
|
||||
if (bg == CV_NOCHANGE)
|
||||
bg = nm_bg_color;
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
fg |= ul;
|
||||
#endif
|
||||
*fg_color = fg;
|
||||
*bg_color = bg;
|
||||
*dattr = 0;
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
if (attr & CATTR_UNDERLINE)
|
||||
*dattr |= COMMON_LVB_UNDERSCORE;
|
||||
if (attr & CATTR_STANDOUT)
|
||||
*dattr |= COMMON_LVB_REVERSE_VIDEO;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -599,7 +607,7 @@ static int color_from_namechar(char namechar)
|
|||
* Handler for the -D option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_D(int type, char *s)
|
||||
public void opt_D(int type, constant char *s)
|
||||
{
|
||||
PARG p;
|
||||
int attr;
|
||||
|
|
@ -634,23 +642,24 @@ public void opt_D(int type, char *s)
|
|||
switch (attr)
|
||||
{
|
||||
case AT_NORMAL:
|
||||
colordesc(s, &nm_fg_color, &nm_bg_color);
|
||||
colordesc(s, &nm_fg_color, &nm_bg_color, &nm_attr);
|
||||
break;
|
||||
case AT_BOLD:
|
||||
colordesc(s, &bo_fg_color, &bo_bg_color);
|
||||
colordesc(s, &bo_fg_color, &bo_bg_color, &bo_attr);
|
||||
break;
|
||||
case AT_UNDERLINE:
|
||||
colordesc(s, &ul_fg_color, &ul_bg_color);
|
||||
colordesc(s, &ul_fg_color, &ul_bg_color, &ul_attr);
|
||||
break;
|
||||
case AT_BLINK:
|
||||
colordesc(s, &bl_fg_color, &bl_bg_color);
|
||||
colordesc(s, &bl_fg_color, &bl_bg_color, &bl_attr);
|
||||
break;
|
||||
case AT_STANDOUT:
|
||||
colordesc(s, &so_fg_color, &so_bg_color);
|
||||
colordesc(s, &so_fg_color, &so_bg_color, &so_attr);
|
||||
break;
|
||||
}
|
||||
if (type == TOGGLE)
|
||||
{
|
||||
init_win_colors();
|
||||
at_enter(AT_STANDOUT);
|
||||
at_exit();
|
||||
}
|
||||
|
|
@ -674,21 +683,21 @@ public void opt_D(int type, char *s)
|
|||
|
||||
/*
|
||||
*/
|
||||
public void set_tabs(char *s, int len)
|
||||
public void set_tabs(constant char *s, size_t len)
|
||||
{
|
||||
int i;
|
||||
char *es = s + len;
|
||||
constant 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;
|
||||
lbool 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');
|
||||
v = v || ckd_mul(&n, n, 10);
|
||||
v = v || ckd_add(&n, n, *s - '0');
|
||||
}
|
||||
if (!v && n > tabstops[i-1])
|
||||
tabstops[i++] = n;
|
||||
|
|
@ -706,7 +715,7 @@ public void set_tabs(char *s, int len)
|
|||
/*
|
||||
* Handler for the -x option.
|
||||
*/
|
||||
public void opt_x(int type, char *s)
|
||||
public void opt_x(int type, constant char *s)
|
||||
{
|
||||
char msg[60+((INT_STRLEN_BOUND(int)+1)*TABSTOP_MAX)];
|
||||
int i;
|
||||
|
|
@ -742,7 +751,7 @@ public void opt_x(int type, char *s)
|
|||
/*
|
||||
* Handler for the -" option.
|
||||
*/
|
||||
public void opt_quote(int type, char *s)
|
||||
public void opt_quote(int type, constant char *s)
|
||||
{
|
||||
char buf[3];
|
||||
PARG parg;
|
||||
|
|
@ -781,7 +790,7 @@ public void opt_quote(int type, char *s)
|
|||
* Handler for the --rscroll option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_rscroll(int type, char *s)
|
||||
public void opt_rscroll(int type, constant char *s)
|
||||
{
|
||||
PARG p;
|
||||
|
||||
|
|
@ -789,7 +798,7 @@ public void opt_rscroll(int type, char *s)
|
|||
{
|
||||
case INIT:
|
||||
case TOGGLE: {
|
||||
char *fmt;
|
||||
constant char *fmt;
|
||||
int attr = AT_STANDOUT;
|
||||
setfmt(s, &fmt, &attr, "*s>", FALSE);
|
||||
if (strcmp(fmt, "-") == 0)
|
||||
|
|
@ -797,12 +806,21 @@ public void opt_rscroll(int type, char *s)
|
|||
rscroll_char = 0;
|
||||
} else
|
||||
{
|
||||
rscroll_char = *fmt ? *fmt : '>';
|
||||
rscroll_attr = attr|AT_COLOR_RSCROLL;
|
||||
if (*fmt == '\0')
|
||||
rscroll_char = '>';
|
||||
else
|
||||
{
|
||||
LWCHAR ch = step_charc(&fmt, +1, fmt+strlen(fmt));
|
||||
if (pwidth(ch, rscroll_attr, 0, 0) > 1)
|
||||
error("cannot set rscroll to a wide character", NULL_PARG);
|
||||
else
|
||||
rscroll_char = ch;
|
||||
}
|
||||
}
|
||||
break; }
|
||||
case QUERY: {
|
||||
p.p_string = rscroll_char ? prchar(rscroll_char) : "-";
|
||||
p.p_string = rscroll_char ? prchar((LWCHAR) rscroll_char) : "-";
|
||||
error("rscroll character is %s", &p);
|
||||
break; }
|
||||
}
|
||||
|
|
@ -813,7 +831,7 @@ public void opt_rscroll(int type, char *s)
|
|||
* If from the command line, exit immediately.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_query(int type, char *s)
|
||||
public void opt_query(int type, constant char *s)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
|
@ -826,11 +844,35 @@ public void opt_query(int type, char *s)
|
|||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
public void opt_match_shift(int type, constant char *s)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case INIT:
|
||||
case TOGGLE:
|
||||
toggle_fraction(&match_shift, &match_shift_fraction,
|
||||
s, "--match-shift", calc_match_shift);
|
||||
break;
|
||||
case QUERY:
|
||||
query_fraction(match_shift, match_shift_fraction,
|
||||
"Search match shift is %d", "Search match shift is %s of screen width");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void calc_match_shift(void)
|
||||
{
|
||||
if (match_shift_fraction < 0)
|
||||
return;
|
||||
match_shift = (int) muldiv(sc_width, match_shift_fraction, NUM_FRAC_DENOM);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler for the --mouse option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_mousecap(int type, char *s)
|
||||
public void opt_mousecap(int type, constant char *s)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
|
@ -850,7 +892,7 @@ public void opt_mousecap(int type, char *s)
|
|||
* Handler for the --wheel-lines option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_wheel_lines(int type, char *s)
|
||||
public void opt_wheel_lines(int type, constant char *s)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
|
@ -868,7 +910,7 @@ public void opt_wheel_lines(int type, char *s)
|
|||
* Handler for the --line-number-width option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_linenum_width(int type, char *s)
|
||||
public void opt_linenum_width(int type, constant char *s)
|
||||
{
|
||||
PARG parg;
|
||||
|
||||
|
|
@ -892,7 +934,7 @@ public void opt_linenum_width(int type, char *s)
|
|||
* Handler for the --status-column-width option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_status_col_width(int type, char *s)
|
||||
public void opt_status_col_width(int type, constant char *s)
|
||||
{
|
||||
PARG parg;
|
||||
|
||||
|
|
@ -916,7 +958,7 @@ public void opt_status_col_width(int type, char *s)
|
|||
* Handler for the --file-size option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_filesize(int type, char *s)
|
||||
public void opt_filesize(int type, constant char *s)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
|
@ -934,7 +976,7 @@ public void opt_filesize(int type, char *s)
|
|||
* Handler for the --intr option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_intr(int type, char *s)
|
||||
public void opt_intr(int type, constant char *s)
|
||||
{
|
||||
PARG p;
|
||||
|
||||
|
|
@ -947,56 +989,104 @@ public void opt_intr(int type, char *s)
|
|||
intr_char = CONTROL(s[1]);
|
||||
break;
|
||||
case QUERY: {
|
||||
p.p_string = prchar(intr_char);
|
||||
p.p_string = prchar((LWCHAR) intr_char);
|
||||
error("interrupt character is %s", &p);
|
||||
break; }
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the next number from a comma-separated list.
|
||||
* Return -1 if the list entry is missing or empty.
|
||||
* Updates *sp to point to the first char of the next number in the list.
|
||||
*/
|
||||
public int next_cnum(constant char **sp, constant char *printopt, constant char *errmsg, lbool *errp)
|
||||
{
|
||||
int n;
|
||||
*errp = FALSE;
|
||||
if (**sp == '\0') /* at end of line */
|
||||
return -1;
|
||||
if (**sp == ',') /* that's the next comma; we have an empty string */
|
||||
{
|
||||
++(*sp);
|
||||
return -1;
|
||||
}
|
||||
n = getnumc(sp, printopt, errp);
|
||||
if (*errp)
|
||||
{
|
||||
PARG parg;
|
||||
parg.p_string = errmsg;
|
||||
error("invalid %s", &parg);
|
||||
return -1;
|
||||
}
|
||||
if (**sp == ',')
|
||||
++(*sp);
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a parameter to the --header option.
|
||||
* Value is "L,C,N", where each field is a decimal number or empty.
|
||||
*/
|
||||
static lbool parse_header(constant char *s, int *lines, int *cols, POSITION *start_pos)
|
||||
{
|
||||
int n;
|
||||
lbool err;
|
||||
|
||||
if (*s == '-')
|
||||
s = "0,0";
|
||||
|
||||
n = next_cnum(&s, "header", "number of lines", &err);
|
||||
if (err) return FALSE;
|
||||
if (n >= 0) *lines = n;
|
||||
|
||||
n = next_cnum(&s, "header", "number of columns", &err);
|
||||
if (err) return FALSE;
|
||||
if (n >= 0) *cols = n;
|
||||
|
||||
n = next_cnum(&s, "header", "line number", &err);
|
||||
if (err) return FALSE;
|
||||
if (n > 0)
|
||||
{
|
||||
LINENUM lnum = (LINENUM) n;
|
||||
if (lnum < 1) lnum = 1;
|
||||
*start_pos = find_pos(lnum);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler for the --header option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_header(int type, char *s)
|
||||
public void opt_header(int type, constant char *s)
|
||||
{
|
||||
int err;
|
||||
int n;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case INIT:
|
||||
case TOGGLE:
|
||||
header_lines = 0;
|
||||
header_cols = 0;
|
||||
if (*s != ',')
|
||||
{
|
||||
n = getnum(&s, "header", &err);
|
||||
if (err)
|
||||
{
|
||||
error("invalid number of lines", NULL_PARG);
|
||||
return;
|
||||
}
|
||||
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;
|
||||
case QUERY:
|
||||
{
|
||||
char buf[2*INT_STRLEN_BOUND(int)+2];
|
||||
PARG parg;
|
||||
SNPRINTF2(buf, sizeof(buf), "%d,%d", header_lines, header_cols);
|
||||
parg.p_string = buf;
|
||||
error("header (lines,columns) is %s", &parg);
|
||||
}
|
||||
/* Can't call parse_header now because input file is not yet opened,
|
||||
* so find_pos won't work. */
|
||||
init_header = save(s);
|
||||
break;
|
||||
case TOGGLE: {
|
||||
int lines = header_lines;
|
||||
int cols = header_cols;
|
||||
POSITION start_pos = (type == INIT) ? ch_zero() : position(TOP);
|
||||
if (start_pos == NULL_POSITION) start_pos = ch_zero();
|
||||
if (!parse_header(s, &lines, &cols, &start_pos))
|
||||
break;
|
||||
header_lines = lines;
|
||||
header_cols = cols;
|
||||
set_header(start_pos);
|
||||
calc_jump_sline();
|
||||
break; }
|
||||
case QUERY: {
|
||||
char buf[3*INT_STRLEN_BOUND(long)+3];
|
||||
PARG parg;
|
||||
SNPRINTF3(buf, sizeof(buf), "%ld,%ld,%ld", (long) header_lines, (long) header_cols, (long) find_linenum(header_start_pos));
|
||||
parg.p_string = buf;
|
||||
error("Header (lines,columns,line-number) is %s", &parg);
|
||||
break; }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1004,7 +1094,7 @@ public void opt_header(int type, char *s)
|
|||
* Handler for the --search-options option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_search_type(int type, char *s)
|
||||
public void opt_search_type(int type, constant char *s)
|
||||
{
|
||||
int st;
|
||||
PARG parg;
|
||||
|
|
@ -1052,7 +1142,7 @@ public void opt_search_type(int type, char *s)
|
|||
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;
|
||||
*bp++ = (char) ('0'+i);
|
||||
if (bp == buf)
|
||||
*bp++ = '-';
|
||||
*bp = '\0';
|
||||
|
|
@ -1062,12 +1152,55 @@ public void opt_search_type(int type, char *s)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler for the --no-search-headers, --no-search-header-lines
|
||||
* and --no-search-header-cols options.
|
||||
*/
|
||||
static void do_nosearch_headers(int type, int no_header_lines, int no_header_cols)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case INIT:
|
||||
case TOGGLE:
|
||||
nosearch_header_lines = no_header_lines;
|
||||
nosearch_header_cols = no_header_cols;
|
||||
break;
|
||||
case QUERY:
|
||||
if (nosearch_header_lines && nosearch_header_cols)
|
||||
error("Search does not include header lines or columns", NULL_PARG);
|
||||
else if (nosearch_header_lines)
|
||||
error("Search includes header columns but not header lines", NULL_PARG);
|
||||
else if (nosearch_header_cols)
|
||||
error("Search includes header lines but not header columns", NULL_PARG);
|
||||
else
|
||||
error("Search includes header lines and columns", NULL_PARG);
|
||||
}
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
public void opt_nosearch_headers(int type, constant char *s)
|
||||
{
|
||||
do_nosearch_headers(type, 1, 1);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
public void opt_nosearch_header_lines(int type, constant char *s)
|
||||
{
|
||||
do_nosearch_headers(type, 1, 0);
|
||||
}
|
||||
|
||||
/*ARGSUSED*/
|
||||
public void opt_nosearch_header_cols(int type, constant char *s)
|
||||
{
|
||||
do_nosearch_headers(type, 0, 1);
|
||||
}
|
||||
|
||||
#if LESSTEST
|
||||
/*
|
||||
* Handler for the --tty option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void opt_ttyin_name(int type, char *s)
|
||||
public void opt_ttyin_name(int type, constant char *s)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -21,12 +21,11 @@
|
|||
#include "option.h"
|
||||
|
||||
static struct loption *pendopt;
|
||||
public int plusoption = FALSE;
|
||||
public lbool plusoption = FALSE;
|
||||
|
||||
static char *optstring(char *s, char **p_str, char *printopt, char *validchars);
|
||||
static constant char *optstring(constant char *s, char **p_str, constant char *printopt, constant char *validchars);
|
||||
static int flip_triple(int val, int lc);
|
||||
|
||||
extern int screen_trashed;
|
||||
extern int less_is_more;
|
||||
extern int quit_at_eof;
|
||||
extern char *every_first_cmd;
|
||||
|
|
@ -35,7 +34,7 @@ extern int opt_use_backslash;
|
|||
/*
|
||||
* Return a printable description of an option.
|
||||
*/
|
||||
static char * opt_desc(struct loption *o)
|
||||
static constant char * opt_desc(struct loption *o)
|
||||
{
|
||||
static char buf[OPTNAME_MAX + 10];
|
||||
if (o->oletter == OLETTER_NONE)
|
||||
|
|
@ -49,11 +48,11 @@ static char * opt_desc(struct loption *o)
|
|||
* Return a string suitable for printing as the "name" of an option.
|
||||
* For example, if the option letter is 'x', just return "-x".
|
||||
*/
|
||||
public char * propt(int c)
|
||||
public constant char * propt(char c)
|
||||
{
|
||||
static char buf[MAX_PRCHAR_LEN+2];
|
||||
|
||||
sprintf(buf, "-%s", prchar(c));
|
||||
sprintf(buf, "-%s", prchar((LWCHAR) c));
|
||||
return (buf);
|
||||
}
|
||||
|
||||
|
|
@ -61,16 +60,16 @@ public char * propt(int c)
|
|||
* Scan an argument (either from the command line or from the
|
||||
* LESS environment variable) and process it.
|
||||
*/
|
||||
public void scan_option(char *s)
|
||||
public void scan_option(constant char *s)
|
||||
{
|
||||
struct loption *o;
|
||||
int optc;
|
||||
char *optname;
|
||||
char *printopt;
|
||||
char optc;
|
||||
constant char *optname;
|
||||
constant char *printopt;
|
||||
char *str;
|
||||
int set_default;
|
||||
lbool set_default;
|
||||
int lc;
|
||||
int err;
|
||||
lbool ambig;
|
||||
PARG parg;
|
||||
|
||||
if (s == NULL)
|
||||
|
|
@ -85,15 +84,18 @@ public void scan_option(char *s)
|
|||
*/
|
||||
if (pendopt != NULL)
|
||||
{
|
||||
switch (pendopt->otype & OTYPE)
|
||||
if (!(pendopt->otype & UNSUPPORTED))
|
||||
{
|
||||
case STRING:
|
||||
(*pendopt->ofunc)(INIT, s);
|
||||
break;
|
||||
case NUMBER:
|
||||
printopt = opt_desc(pendopt);
|
||||
*(pendopt->ovar) = getnum(&s, printopt, (int*)NULL);
|
||||
break;
|
||||
switch (pendopt->otype & OTYPE)
|
||||
{
|
||||
case STRING:
|
||||
(*pendopt->ofunc)(INIT, s);
|
||||
break;
|
||||
case NUMBER:
|
||||
printopt = opt_desc(pendopt);
|
||||
*(pendopt->ovar) = getnumc(&s, printopt, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pendopt = NULL;
|
||||
return;
|
||||
|
|
@ -118,18 +120,19 @@ public void scan_option(char *s)
|
|||
* "--" indicates an option name instead of a letter.
|
||||
*/
|
||||
if (*s == '-')
|
||||
{
|
||||
optname = ++s;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* "-+" means set these options back to their defaults.
|
||||
* (They may have been set otherwise by previous
|
||||
* options.)
|
||||
* "-+" or "--+" means set these options back to their defaults.
|
||||
* (They may have been set otherwise by previous options.)
|
||||
*/
|
||||
set_default = (*s == '+');
|
||||
if (set_default)
|
||||
s++;
|
||||
if (optname != NULL)
|
||||
{
|
||||
optname = s;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
case '+':
|
||||
/*
|
||||
|
|
@ -151,7 +154,7 @@ public void scan_option(char *s)
|
|||
} else
|
||||
{
|
||||
ungetsc(str);
|
||||
ungetcc_back(CHAR_END_COMMAND);
|
||||
ungetcc_end_command();
|
||||
}
|
||||
free(str);
|
||||
continue;
|
||||
|
|
@ -175,7 +178,7 @@ public void scan_option(char *s)
|
|||
* Not a special case.
|
||||
* Look up the option letter in the option table.
|
||||
*/
|
||||
err = 0;
|
||||
ambig = FALSE;
|
||||
if (optname == NULL)
|
||||
{
|
||||
printopt = propt(optc);
|
||||
|
|
@ -185,7 +188,7 @@ public void scan_option(char *s)
|
|||
{
|
||||
printopt = optname;
|
||||
lc = ASCII_IS_LOWER(optname[0]);
|
||||
o = findopt_name(&optname, NULL, &err);
|
||||
o = findopt_name(&optname, NULL, &ambig);
|
||||
s = optname;
|
||||
optname = NULL;
|
||||
if (*s == '\0' || *s == ' ')
|
||||
|
|
@ -221,7 +224,7 @@ public void scan_option(char *s)
|
|||
if (o == NULL)
|
||||
{
|
||||
parg.p_string = printopt;
|
||||
if (err == OPT_AMBIG)
|
||||
if (ambig)
|
||||
error("%s is an ambiguous abbreviation (\"less --help\" for help)",
|
||||
&parg);
|
||||
else
|
||||
|
|
@ -234,16 +237,26 @@ public void scan_option(char *s)
|
|||
switch (o->otype & OTYPE)
|
||||
{
|
||||
case BOOL:
|
||||
if (set_default)
|
||||
*(o->ovar) = o->odefault;
|
||||
else
|
||||
*(o->ovar) = ! o->odefault;
|
||||
if (o->otype & UNSUPPORTED)
|
||||
break;
|
||||
if (o->ovar != NULL)
|
||||
{
|
||||
if (set_default)
|
||||
*(o->ovar) = o->odefault;
|
||||
else
|
||||
*(o->ovar) = ! o->odefault;
|
||||
}
|
||||
break;
|
||||
case TRIPLE:
|
||||
if (set_default)
|
||||
*(o->ovar) = o->odefault;
|
||||
else
|
||||
*(o->ovar) = flip_triple(o->odefault, lc);
|
||||
if (o->otype & UNSUPPORTED)
|
||||
break;
|
||||
if (o->ovar != NULL)
|
||||
{
|
||||
if (set_default)
|
||||
*(o->ovar) = o->odefault;
|
||||
else
|
||||
*(o->ovar) = flip_triple(o->odefault, lc);
|
||||
}
|
||||
break;
|
||||
case STRING:
|
||||
if (*s == '\0')
|
||||
|
|
@ -273,13 +286,15 @@ public void scan_option(char *s)
|
|||
pendopt = o;
|
||||
return;
|
||||
}
|
||||
*(o->ovar) = getnum(&s, printopt, (int*)NULL);
|
||||
if (o->otype & UNSUPPORTED)
|
||||
break;
|
||||
*(o->ovar) = getnumc(&s, printopt, NULL);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* If the option has a handling function, call it.
|
||||
*/
|
||||
if (o->ofunc != NULL)
|
||||
if (o->ofunc != NULL && !(o->otype & UNSUPPORTED))
|
||||
(*o->ofunc)(INIT, str);
|
||||
if (str != NULL)
|
||||
free(str);
|
||||
|
|
@ -295,11 +310,11 @@ public void scan_option(char *s)
|
|||
* OPT_UNSET set to the default value
|
||||
* OPT_SET set to the inverse of the default value
|
||||
*/
|
||||
public void toggle_option(struct loption *o, int lower, char *s, int how_toggle)
|
||||
public void toggle_option(struct loption *o, int lower, constant char *s, int how_toggle)
|
||||
{
|
||||
int num;
|
||||
int no_prompt;
|
||||
int err;
|
||||
lbool err;
|
||||
PARG parg;
|
||||
|
||||
no_prompt = (how_toggle & OPT_NO_PROMPT);
|
||||
|
|
@ -342,7 +357,7 @@ public void toggle_option(struct loption *o, int lower, char *s, int how_toggle)
|
|||
|
||||
#if HILITE_SEARCH
|
||||
if (how_toggle != OPT_NO_TOGGLE && (o->otype & HL_REPAINT))
|
||||
repaint_hilite(0);
|
||||
repaint_hilite(FALSE);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -356,17 +371,20 @@ public void toggle_option(struct loption *o, int lower, char *s, int how_toggle)
|
|||
/*
|
||||
* Boolean.
|
||||
*/
|
||||
switch (how_toggle)
|
||||
if (o->ovar != NULL)
|
||||
{
|
||||
case OPT_TOGGLE:
|
||||
*(o->ovar) = ! *(o->ovar);
|
||||
break;
|
||||
case OPT_UNSET:
|
||||
*(o->ovar) = o->odefault;
|
||||
break;
|
||||
case OPT_SET:
|
||||
*(o->ovar) = ! o->odefault;
|
||||
break;
|
||||
switch (how_toggle)
|
||||
{
|
||||
case OPT_TOGGLE:
|
||||
*(o->ovar) = ! *(o->ovar);
|
||||
break;
|
||||
case OPT_UNSET:
|
||||
*(o->ovar) = o->odefault;
|
||||
break;
|
||||
case OPT_SET:
|
||||
*(o->ovar) = ! o->odefault;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TRIPLE:
|
||||
|
|
@ -377,17 +395,20 @@ public void toggle_option(struct loption *o, int lower, char *s, int how_toggle)
|
|||
* If user gave the upper case letter, then switch
|
||||
* to 2 unless already 2, in which case make it 0.
|
||||
*/
|
||||
switch (how_toggle)
|
||||
if (o->ovar != NULL)
|
||||
{
|
||||
case OPT_TOGGLE:
|
||||
*(o->ovar) = flip_triple(*(o->ovar), lower);
|
||||
break;
|
||||
case OPT_UNSET:
|
||||
*(o->ovar) = o->odefault;
|
||||
break;
|
||||
case OPT_SET:
|
||||
*(o->ovar) = flip_triple(o->odefault, lower);
|
||||
break;
|
||||
switch (how_toggle)
|
||||
{
|
||||
case OPT_TOGGLE:
|
||||
*(o->ovar) = flip_triple(*(o->ovar), lower);
|
||||
break;
|
||||
case OPT_UNSET:
|
||||
*(o->ovar) = o->odefault;
|
||||
break;
|
||||
case OPT_SET:
|
||||
*(o->ovar) = flip_triple(o->odefault, lower);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STRING:
|
||||
|
|
@ -411,7 +432,7 @@ public void toggle_option(struct loption *o, int lower, char *s, int how_toggle)
|
|||
switch (how_toggle)
|
||||
{
|
||||
case OPT_TOGGLE:
|
||||
num = getnum(&s, NULL, &err);
|
||||
num = getnumc(&s, NULL, &err);
|
||||
if (!err)
|
||||
*(o->ovar) = num;
|
||||
break;
|
||||
|
|
@ -451,7 +472,8 @@ public void toggle_option(struct loption *o, int lower, char *s, int how_toggle)
|
|||
/*
|
||||
* Print the odesc message.
|
||||
*/
|
||||
error(o->odesc[*(o->ovar)], NULL_PARG);
|
||||
if (o->ovar != NULL)
|
||||
error(o->odesc[*(o->ovar)], NULL_PARG);
|
||||
break;
|
||||
case NUMBER:
|
||||
/*
|
||||
|
|
@ -470,7 +492,7 @@ public void toggle_option(struct loption *o, int lower, char *s, int how_toggle)
|
|||
}
|
||||
|
||||
if (how_toggle != OPT_NO_TOGGLE && (o->otype & REPAINT))
|
||||
screen_trashed = TRUE;
|
||||
screen_trashed();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -500,7 +522,7 @@ public int opt_has_param(struct loption *o)
|
|||
* Return the prompt to be used for a given option letter.
|
||||
* Only string and number valued options have prompts.
|
||||
*/
|
||||
public char * opt_prompt(struct loption *o)
|
||||
public constant char * opt_prompt(struct loption *o)
|
||||
{
|
||||
if (o == NULL || (o->otype & (STRING|NUMBER)) == 0)
|
||||
return ("?");
|
||||
|
|
@ -511,7 +533,7 @@ public char * opt_prompt(struct loption *o)
|
|||
* If the specified option can be toggled, return NULL.
|
||||
* Otherwise return an appropriate error message.
|
||||
*/
|
||||
public char * opt_toggle_disallowed(int c)
|
||||
public constant char * opt_toggle_disallowed(int c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
|
|
@ -530,7 +552,7 @@ public char * opt_toggle_disallowed(int c)
|
|||
* In that case, the current option is taken to be the string for
|
||||
* the previous option.
|
||||
*/
|
||||
public int isoptpending(void)
|
||||
public lbool isoptpending(void)
|
||||
{
|
||||
return (pendopt != NULL);
|
||||
}
|
||||
|
|
@ -538,7 +560,7 @@ public int isoptpending(void)
|
|||
/*
|
||||
* Print error message about missing string.
|
||||
*/
|
||||
static void nostring(char *printopt)
|
||||
static void nostring(constant char *printopt)
|
||||
{
|
||||
PARG parg;
|
||||
parg.p_string = printopt;
|
||||
|
|
@ -557,10 +579,16 @@ public void nopendopt(void)
|
|||
* Scan to end of string or to an END_OPTION_STRING character.
|
||||
* In the latter case, replace the char with a null char.
|
||||
* Return a pointer to the remainder of the string, if any.
|
||||
* validchars is of the form "[-][.]d[,]".
|
||||
* "-" means an optional leading "-" is allowed
|
||||
* "." means an optional leading "." is allowed (after any "-")
|
||||
* "d" indicates a string of one or more digits (0-9)
|
||||
* "," indicates a comma-separated list of digit strings is allowed
|
||||
* "s" means a space char terminates the argument
|
||||
*/
|
||||
static char * optstring(char *s, char **p_str, char *printopt, char *validchars)
|
||||
static constant char * optstring(constant char *s, char **p_str, constant char *printopt, constant char *validchars)
|
||||
{
|
||||
char *p;
|
||||
constant char *p;
|
||||
char *out;
|
||||
|
||||
if (*s == '\0')
|
||||
|
|
@ -580,8 +608,38 @@ static char * optstring(char *s, char **p_str, char *printopt, char *validchars)
|
|||
++p;
|
||||
} else
|
||||
{
|
||||
if (*p == END_OPTION_STRING ||
|
||||
(validchars != NULL && strchr(validchars, *p) == NULL))
|
||||
if (validchars != NULL)
|
||||
{
|
||||
if (validchars[0] == 's')
|
||||
{
|
||||
if (*p == ' ')
|
||||
break;
|
||||
} else if (*p == '-')
|
||||
{
|
||||
if (validchars[0] != '-')
|
||||
break;
|
||||
++validchars;
|
||||
} else if (*p == '.')
|
||||
{
|
||||
if (validchars[0] == '-')
|
||||
++validchars;
|
||||
if (validchars[0] != '.')
|
||||
break;
|
||||
++validchars;
|
||||
} else if (*p == ',')
|
||||
{
|
||||
if (validchars[0] == '\0' || validchars[1] != ',')
|
||||
break;
|
||||
} else if (*p >= '0' && *p <= '9')
|
||||
{
|
||||
while (validchars[0] == '-' || validchars[0] == '.')
|
||||
++validchars;
|
||||
if (validchars[0] != 'd')
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (*p == END_OPTION_STRING)
|
||||
/* End of option string. */
|
||||
break;
|
||||
}
|
||||
|
|
@ -593,7 +651,7 @@ static char * optstring(char *s, char **p_str, char *printopt, char *validchars)
|
|||
|
||||
/*
|
||||
*/
|
||||
static int num_error(char *printopt, int *errp, int overflow)
|
||||
static int num_error(constant char *printopt, lbool *errp, lbool overflow)
|
||||
{
|
||||
PARG parg;
|
||||
|
||||
|
|
@ -618,13 +676,13 @@ static int num_error(char *printopt, int *errp, int overflow)
|
|||
* Like atoi(), but takes a pointer to a char *, and updates
|
||||
* the char * to point after the translated number.
|
||||
*/
|
||||
public int getnum(char **sp, char *printopt, int *errp)
|
||||
public int getnumc(constant char **sp, constant char *printopt, lbool *errp)
|
||||
{
|
||||
char *s;
|
||||
constant char *s = *sp;
|
||||
int n;
|
||||
int neg;
|
||||
lbool neg;
|
||||
|
||||
s = skipsp(*sp);
|
||||
s = skipspc(s);
|
||||
neg = FALSE;
|
||||
if (*s == '-')
|
||||
{
|
||||
|
|
@ -634,7 +692,7 @@ public int getnum(char **sp, char *printopt, int *errp)
|
|||
if (*s < '0' || *s > '9')
|
||||
return (num_error(printopt, errp, FALSE));
|
||||
|
||||
n = lstrtoi(s, sp, 10);
|
||||
n = lstrtoic(s, sp, 10);
|
||||
if (n < 0)
|
||||
return (num_error(printopt, errp, TRUE));
|
||||
if (errp != NULL)
|
||||
|
|
@ -644,19 +702,27 @@ public int getnum(char **sp, char *printopt, int *errp)
|
|||
return (n);
|
||||
}
|
||||
|
||||
public int getnum(char **sp, constant char *printopt, lbool *errp)
|
||||
{
|
||||
constant char *cs = *sp;
|
||||
int r = getnumc(&cs, printopt, errp);
|
||||
*sp = (char *) cs;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate a string into a fraction, represented by the part of a
|
||||
* number which would follow a decimal point.
|
||||
* 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.
|
||||
*/
|
||||
public long getfraction(char **sp, char *printopt, int *errp)
|
||||
public long getfraction(constant char **sp, constant char *printopt, lbool *errp)
|
||||
{
|
||||
char *s;
|
||||
constant char *s;
|
||||
long frac = 0;
|
||||
int fraclen = 0;
|
||||
|
||||
s = skipsp(*sp);
|
||||
s = skipspc(*sp);
|
||||
if (*s < '0' || *s > '9')
|
||||
return (num_error(printopt, errp, FALSE));
|
||||
|
||||
|
|
@ -675,6 +741,34 @@ public long getfraction(char **sp, char *printopt, int *errp)
|
|||
return (frac);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the UNSUPPORTED bit in every option listed
|
||||
* in the LESS_UNSUPPORT environment variable.
|
||||
*/
|
||||
public void init_unsupport(void)
|
||||
{
|
||||
constant char *s = lgetenv("LESS_UNSUPPORT");
|
||||
if (isnullenv(s))
|
||||
return;
|
||||
for (;;)
|
||||
{
|
||||
struct loption *opt;
|
||||
s = skipspc(s);
|
||||
if (*s == '\0') break;
|
||||
if (*s == '-' && *++s == '\0') break;
|
||||
if (*s == '-') /* long option name */
|
||||
{
|
||||
++s;
|
||||
opt = findopt_name(&s, NULL, NULL);
|
||||
} else /* short (single-char) option */
|
||||
{
|
||||
opt = findopt(*s);
|
||||
if (opt != NULL) ++s;
|
||||
}
|
||||
if (opt != NULL)
|
||||
opt->otype |= UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the value of the -e flag.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
#define HL_REPAINT 0200 /* Repaint hilites after toggling option */
|
||||
#define NO_QUERY 0400 /* Option cannot be queried with "_" cmd */
|
||||
#define INIT_HANDLER 01000 /* Call option handler function at startup */
|
||||
#define UNSUPPORTED 02000 /* Option is unsupported via LESS_UNSUPPORT */
|
||||
|
||||
#define OTYPE (BOOL|TRIPLE|NUMBER|STRING|NOVAR)
|
||||
|
||||
|
|
@ -47,7 +48,7 @@
|
|||
|
||||
struct optname
|
||||
{
|
||||
char *oname; /* Long (GNU-style) option name */
|
||||
constant char *oname; /* Long (GNU-style) option name */
|
||||
struct optname *onext; /* List of synonymous option names */
|
||||
};
|
||||
|
||||
|
|
@ -60,7 +61,7 @@ struct loption
|
|||
int otype; /* Type of the option */
|
||||
int odefault; /* Default value */
|
||||
int *ovar; /* Pointer to the associated variable */
|
||||
void (*ofunc)(int, char*); /* Pointer to special handling function */
|
||||
char *odesc[3]; /* Description of each value */
|
||||
void (*ofunc)(int, constant char*); /* Pointer to special handling function */
|
||||
constant char *odesc[3]; /* Description of each value */
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -41,6 +41,7 @@ public int force_open; /* Open the file even if not regular file */
|
|||
public int swindow; /* Size of scrolling window */
|
||||
public int jump_sline; /* Screen line of "jump target" */
|
||||
public long jump_sline_fraction = -1;
|
||||
public int shift_count; /* Number of positions to shift horizontally */
|
||||
public long shift_count_fraction = -1;
|
||||
public int chopline; /* Truncate displayed lines at screen width */
|
||||
public int wordwrap; /* Wrap lines at space */
|
||||
|
|
@ -48,14 +49,13 @@ public int no_init; /* Disable sending ti/te termcap strings */
|
|||
public int no_keypad; /* Disable sending ks/ke termcap strings */
|
||||
public int twiddle; /* Show tildes after EOF */
|
||||
public int show_attn; /* Hilite first unread line */
|
||||
public int shift_count; /* Number of positions to shift horizontally */
|
||||
public int status_col; /* Display a status column */
|
||||
public int use_lessopen; /* Use the LESSOPEN filter */
|
||||
public int quit_on_intr; /* Quit on interrupt */
|
||||
public int follow_mode; /* F cmd Follows file desc or file name? */
|
||||
public int oldbot; /* Old bottom of screen behavior {{REMOVE}} */
|
||||
public int opt_use_backslash; /* Use backslash escaping in option parsing */
|
||||
public char rscroll_char; /* Char which marks chopped lines with -S */
|
||||
public LWCHAR rscroll_char; /* Char which marks chopped lines with -S */
|
||||
public int rscroll_attr; /* Attribute of rscroll_char */
|
||||
public int no_hist_dups; /* Remove dups from history list */
|
||||
public int mousecap; /* Allow mouse for scrolling */
|
||||
|
|
@ -70,7 +70,8 @@ public int status_line; /* Highlight entire marked lines */
|
|||
public int header_lines; /* Freeze header lines at top of screen */
|
||||
public int header_cols; /* Freeze header columns at left of screen */
|
||||
public int nonum_headers; /* Don't give headers line numbers */
|
||||
public int nosearch_headers; /* Don't search in header lines or columns */
|
||||
public int nosearch_header_lines = 0; /* Don't search in header lines */
|
||||
public int nosearch_header_cols = 0; /* Don't search in header columns */
|
||||
public int redraw_on_quit; /* Redraw last screen after term deinit */
|
||||
public int def_search_type; /* */
|
||||
public int exit_F_on_close; /* Exit F command when input closes */
|
||||
|
|
@ -79,6 +80,8 @@ 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 int match_shift; /* Extra horizontal shift on search match */
|
||||
public long match_shift_fraction = NUM_FRAC_DENOM/2; /* 1/2 of screen width */
|
||||
public char intr_char = CONTROL('X'); /* Char to interrupt reads */
|
||||
#if HILITE_SEARCH
|
||||
public int hilite_search; /* Highlight matched search patterns? */
|
||||
|
|
@ -109,6 +112,7 @@ static struct optname J__optname = { "status-column", NULL };
|
|||
static struct optname k_optname = { "lesskey-file", NULL };
|
||||
#if HAVE_LESSKEYSRC
|
||||
static struct optname ks_optname = { "lesskey-src", NULL };
|
||||
static struct optname kc_optname = { "lesskey-content", NULL };
|
||||
#endif /* HAVE_LESSKEYSRC */
|
||||
#endif
|
||||
static struct optname K__optname = { "quit-on-intr", NULL };
|
||||
|
|
@ -159,6 +163,8 @@ static struct optname status_line_optname = { "status-line", NULL };
|
|||
static struct optname header_optname = { "header", NULL };
|
||||
static struct optname nonum_headers_optname = { "no-number-headers", NULL };
|
||||
static struct optname nosearch_headers_optname = { "no-search-headers", NULL };
|
||||
static struct optname nosearch_header_lines_optname = { "no-search-header-lines", NULL };
|
||||
static struct optname nosearch_header_cols_optname = { "no-search-header-columns", NULL };
|
||||
static struct optname redraw_on_quit_optname = { "redraw-on-quit", NULL };
|
||||
static struct optname search_type_optname = { "search-options", NULL };
|
||||
static struct optname exit_F_on_close_optname = { "exit-follow-on-close", NULL };
|
||||
|
|
@ -170,6 +176,7 @@ 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 };
|
||||
static struct optname match_shift_optname = { "match-shift", NULL };
|
||||
#if LESSTEST
|
||||
static struct optname ttyin_name_optname = { "tty", NULL };
|
||||
#endif /*LESSTEST*/
|
||||
|
|
@ -232,11 +239,7 @@ static struct loption option[] =
|
|||
},
|
||||
{ 'D', &D__optname,
|
||||
STRING|REPAINT|NO_QUERY, 0, NULL, opt_D,
|
||||
{
|
||||
"color desc: ",
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
{ "color desc: ", "s", NULL }
|
||||
},
|
||||
{ 'e', &e_optname,
|
||||
TRIPLE, OPT_OFF, &quit_at_eof, NULL,
|
||||
|
|
@ -292,7 +295,7 @@ static struct loption option[] =
|
|||
STRING, 0, NULL, opt_j,
|
||||
{
|
||||
"Target line: ",
|
||||
"0123456789.-",
|
||||
"-.d",
|
||||
NULL
|
||||
}
|
||||
},
|
||||
|
|
@ -310,6 +313,10 @@ static struct loption option[] =
|
|||
{ NULL, NULL, NULL }
|
||||
},
|
||||
#if HAVE_LESSKEYSRC
|
||||
{ OLETTER_NONE, &kc_optname,
|
||||
STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_kc,
|
||||
{ NULL, NULL, NULL }
|
||||
},
|
||||
{ OLETTER_NONE, &ks_optname,
|
||||
STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_ks,
|
||||
{ NULL, NULL, NULL }
|
||||
|
|
@ -391,7 +398,7 @@ static struct loption option[] =
|
|||
}
|
||||
},
|
||||
{ 'S', &S__optname,
|
||||
BOOL|REPAINT, OPT_OFF, &chopline, NULL,
|
||||
BOOL|REPAINT, OPT_OFF, &chopline, opt__S,
|
||||
{
|
||||
"Fold long lines",
|
||||
"Chop long lines",
|
||||
|
|
@ -432,7 +439,7 @@ static struct loption option[] =
|
|||
STRING|REPAINT, 0, NULL, opt_x,
|
||||
{
|
||||
"Tab stops: ",
|
||||
"0123456789,",
|
||||
"d,",
|
||||
NULL
|
||||
}
|
||||
},
|
||||
|
|
@ -462,7 +469,7 @@ static struct loption option[] =
|
|||
},
|
||||
{ '"', "e_optname,
|
||||
STRING, 0, NULL, opt_quote,
|
||||
{ "quotes: ", NULL, NULL }
|
||||
{ "quotes: ", "s", NULL }
|
||||
},
|
||||
{ '~', &tilde_optname,
|
||||
BOOL|REPAINT, OPT_ON, &twiddle, NULL,
|
||||
|
|
@ -480,7 +487,7 @@ static struct loption option[] =
|
|||
STRING, 0, NULL, opt_shift,
|
||||
{
|
||||
"Horizontal shift: ",
|
||||
"0123456789.",
|
||||
".d",
|
||||
NULL
|
||||
}
|
||||
},
|
||||
|
|
@ -518,7 +525,7 @@ static struct loption option[] =
|
|||
},
|
||||
{ OLETTER_NONE, &rscroll_optname,
|
||||
STRING|REPAINT|INIT_HANDLER, 0, NULL, opt_rscroll,
|
||||
{ "rscroll character: ", NULL, NULL }
|
||||
{ "rscroll character: ", "s", NULL }
|
||||
},
|
||||
{ OLETTER_NONE, &nohistdups_optname,
|
||||
BOOL, OPT_OFF, &no_hist_dups, NULL,
|
||||
|
|
@ -602,11 +609,7 @@ static struct loption option[] =
|
|||
},
|
||||
{ OLETTER_NONE, &header_optname,
|
||||
STRING|REPAINT, 0, NULL, opt_header,
|
||||
{
|
||||
"Header lines: ",
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
{ "Header lines: ", "d,", NULL }
|
||||
},
|
||||
{ OLETTER_NONE, &nonum_headers_optname,
|
||||
BOOL|REPAINT, 0, &nonum_headers, NULL,
|
||||
|
|
@ -617,11 +620,21 @@ static struct loption option[] =
|
|||
}
|
||||
},
|
||||
{ OLETTER_NONE, &nosearch_headers_optname,
|
||||
BOOL|HL_REPAINT, 0, &nosearch_headers, NULL,
|
||||
BOOL|HL_REPAINT, 0, NULL, opt_nosearch_headers,
|
||||
{
|
||||
"Search includes header lines",
|
||||
"Search does not include header lines",
|
||||
NULL
|
||||
NULL, NULL, NULL
|
||||
}
|
||||
},
|
||||
{ OLETTER_NONE, &nosearch_header_lines_optname,
|
||||
BOOL|HL_REPAINT, 0, NULL, opt_nosearch_header_lines,
|
||||
{
|
||||
NULL, NULL, NULL
|
||||
}
|
||||
},
|
||||
{ OLETTER_NONE, &nosearch_header_cols_optname,
|
||||
BOOL|HL_REPAINT, 0, NULL, opt_nosearch_header_cols,
|
||||
{
|
||||
NULL, NULL, NULL
|
||||
}
|
||||
},
|
||||
{ OLETTER_NONE, &redraw_on_quit_optname,
|
||||
|
|
@ -634,11 +647,7 @@ static struct loption option[] =
|
|||
},
|
||||
{ OLETTER_NONE, &search_type_optname,
|
||||
STRING, 0, NULL, opt_search_type,
|
||||
{
|
||||
"Search options: ",
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
{ "Search options: ", "s", NULL }
|
||||
},
|
||||
{ OLETTER_NONE, &exit_F_on_close_optname,
|
||||
BOOL, OPT_OFF, &exit_F_on_close, NULL,
|
||||
|
|
@ -666,7 +675,7 @@ static struct loption option[] =
|
|||
},
|
||||
{ OLETTER_NONE, &intr_optname,
|
||||
STRING, 0, NULL, opt_intr,
|
||||
{ "interrupt character: ", NULL, NULL }
|
||||
{ "interrupt character: ", "s", NULL }
|
||||
},
|
||||
{ OLETTER_NONE, &wordwrap_optname,
|
||||
BOOL|REPAINT, OPT_OFF, &wordwrap, NULL,
|
||||
|
|
@ -708,6 +717,14 @@ static struct loption option[] =
|
|||
"Print carriage return as ^M"
|
||||
}
|
||||
},
|
||||
{ OLETTER_NONE, &match_shift_optname,
|
||||
STRING|INIT_HANDLER, 0, NULL, opt_match_shift,
|
||||
{
|
||||
"Search match shift: ",
|
||||
".d",
|
||||
NULL
|
||||
}
|
||||
},
|
||||
#if LESSTEST
|
||||
{ OLETTER_NONE, &ttyin_name_optname,
|
||||
STRING|NO_TOGGLE, 0, NULL, opt_ttyin_name,
|
||||
|
|
@ -728,7 +745,7 @@ static struct loption option[] =
|
|||
public void init_option(void)
|
||||
{
|
||||
struct loption *o;
|
||||
char *p;
|
||||
constant char *p;
|
||||
|
||||
p = lgetenv("LESS_IS_MORE");
|
||||
if (!isnullenv(p))
|
||||
|
|
@ -766,15 +783,15 @@ public struct loption * findopt(int c)
|
|||
/*
|
||||
*
|
||||
*/
|
||||
static int is_optchar(char c)
|
||||
static lbool is_optchar(char c)
|
||||
{
|
||||
if (ASCII_IS_UPPER(c))
|
||||
return 1;
|
||||
return TRUE;
|
||||
if (ASCII_IS_LOWER(c))
|
||||
return 1;
|
||||
return TRUE;
|
||||
if (c == '-')
|
||||
return 1;
|
||||
return 0;
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -783,18 +800,18 @@ static int is_optchar(char c)
|
|||
* is updated to point after the matched name.
|
||||
* p_oname if non-NULL is set to point to the full option name.
|
||||
*/
|
||||
public struct loption * findopt_name(char **p_optname, char **p_oname, int *p_err)
|
||||
public struct loption * findopt_name(constant char **p_optname, constant char **p_oname, lbool *p_ambig)
|
||||
{
|
||||
char *optname = *p_optname;
|
||||
constant char *optname = *p_optname;
|
||||
struct loption *o;
|
||||
struct optname *oname;
|
||||
int len;
|
||||
size_t len;
|
||||
int uppercase;
|
||||
struct loption *maxo = NULL;
|
||||
struct optname *maxoname = NULL;
|
||||
int maxlen = 0;
|
||||
int ambig = 0;
|
||||
int exact = 0;
|
||||
size_t maxlen = 0;
|
||||
lbool ambig = FALSE;
|
||||
lbool exact = FALSE;
|
||||
|
||||
/*
|
||||
* Check all options.
|
||||
|
|
@ -814,7 +831,7 @@ public struct loption * findopt_name(char **p_optname, char **p_oname, int *p_er
|
|||
for (uppercase = 0; uppercase <= 1; uppercase++)
|
||||
{
|
||||
len = sprefix(optname, oname->oname, uppercase);
|
||||
if (len <= 0 || is_optchar(optname[len]))
|
||||
if (len == 0 || is_optchar(optname[len]))
|
||||
{
|
||||
/*
|
||||
* We didn't use all of the option name.
|
||||
|
|
@ -827,7 +844,7 @@ public struct loption * findopt_name(char **p_optname, char **p_oname, int *p_er
|
|||
* and now there's another one that
|
||||
* matches the same length.
|
||||
*/
|
||||
ambig = 1;
|
||||
ambig = TRUE;
|
||||
else if (len > maxlen)
|
||||
{
|
||||
/*
|
||||
|
|
@ -837,21 +854,21 @@ public struct loption * findopt_name(char **p_optname, char **p_oname, int *p_er
|
|||
maxo = o;
|
||||
maxoname = oname;
|
||||
maxlen = len;
|
||||
ambig = 0;
|
||||
exact = (len == (int)strlen(oname->oname));
|
||||
ambig = FALSE;
|
||||
exact = (len == strlen(oname->oname));
|
||||
}
|
||||
if (!(o->otype & TRIPLE))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (p_ambig != NULL)
|
||||
*p_ambig = ambig;
|
||||
if (ambig)
|
||||
{
|
||||
/*
|
||||
* Name matched more than one option.
|
||||
*/
|
||||
if (p_err != NULL)
|
||||
*p_err = OPT_AMBIG;
|
||||
return (NULL);
|
||||
}
|
||||
*p_optname = optname + maxlen;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -42,13 +42,13 @@
|
|||
|
||||
#if HAVE_POLL && !MSDOS_COMPILER
|
||||
#define USE_POLL 1
|
||||
static int use_poll = TRUE;
|
||||
static lbool use_poll = TRUE;
|
||||
#else
|
||||
#define USE_POLL 0
|
||||
#endif
|
||||
#if USE_POLL
|
||||
#include <poll.h>
|
||||
static int any_data = FALSE;
|
||||
static lbool any_data = FALSE;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -67,7 +67,7 @@ static int any_data = FALSE;
|
|||
#endif
|
||||
|
||||
public int reading;
|
||||
public int waiting_for_data;
|
||||
public lbool waiting_for_data;
|
||||
public int consecutive_nulls = 0;
|
||||
|
||||
/* Milliseconds to wait for data before displaying "waiting for data" message. */
|
||||
|
|
@ -80,16 +80,14 @@ extern int exit_F_on_close;
|
|||
extern int follow_mode;
|
||||
extern int scanning_eof;
|
||||
extern char intr_char;
|
||||
extern int is_tty;
|
||||
#if !MSDOS_COMPILER
|
||||
extern int tty;
|
||||
#endif
|
||||
#if LESSTEST
|
||||
extern char *ttyin_name;
|
||||
#endif /*LESSTEST*/
|
||||
|
||||
public void init_poll(void)
|
||||
{
|
||||
char *delay = lgetenv("LESS_DATA_DELAY");
|
||||
constant char *delay = lgetenv("LESS_DATA_DELAY");
|
||||
int idelay = (delay == NULL) ? 0 : atoi(delay);
|
||||
if (idelay > 0)
|
||||
waiting_for_data_delay = idelay;
|
||||
|
|
@ -125,16 +123,16 @@ static int check_poll(int fd, int tty)
|
|||
}
|
||||
poll(poller, 2, timeout);
|
||||
#if LESSTEST
|
||||
if (ttyin_name == NULL) /* Check for ^X only on a real tty. */
|
||||
if (!is_lesstest()) /* Check for ^X only on a real tty. */
|
||||
#endif /*LESSTEST*/
|
||||
{
|
||||
if (poller[1].revents & POLLIN)
|
||||
{
|
||||
LWCHAR ch = getchr();
|
||||
if (ch == intr_char)
|
||||
int ch = getchr();
|
||||
if (ch < 0 || ch == intr_char)
|
||||
/* Break out of "waiting for data". */
|
||||
return (READ_INTR);
|
||||
ungetcc_back(ch);
|
||||
ungetcc_back((char) ch);
|
||||
}
|
||||
}
|
||||
if (ignore_eoi && exit_F_on_close && (poller[0].revents & (POLLHUP|POLLIN)) == POLLHUP)
|
||||
|
|
@ -150,11 +148,15 @@ static int check_poll(int fd, int tty)
|
|||
|
||||
public int supports_ctrl_x(void)
|
||||
{
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
return (TRUE);
|
||||
#else
|
||||
#if USE_POLL
|
||||
return (use_poll);
|
||||
#else
|
||||
return (FALSE);
|
||||
#endif /* USE_POLL */
|
||||
#endif /* MSDOS_COMPILER==WIN32C */
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -162,9 +164,9 @@ public int supports_ctrl_x(void)
|
|||
* A call to intread() from a signal handler will interrupt
|
||||
* any pending iread().
|
||||
*/
|
||||
public int iread(int fd, unsigned char *buf, unsigned int len)
|
||||
public ssize_t iread(int fd, unsigned char *buf, size_t len)
|
||||
{
|
||||
int n;
|
||||
ssize_t n;
|
||||
|
||||
start:
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
|
|
@ -188,7 +190,7 @@ start:
|
|||
/*
|
||||
* We jumped here from intread.
|
||||
*/
|
||||
reading = 0;
|
||||
reading = FALSE;
|
||||
#if HAVE_SIGPROCMASK
|
||||
{
|
||||
sigset_t mask;
|
||||
|
|
@ -213,7 +215,7 @@ start:
|
|||
}
|
||||
|
||||
flush();
|
||||
reading = 1;
|
||||
reading = TRUE;
|
||||
#if MSDOS_COMPILER==DJGPPC
|
||||
if (isatty(fd))
|
||||
{
|
||||
|
|
@ -230,20 +232,20 @@ start:
|
|||
FD_SET(fd, &readfds);
|
||||
if (select(fd+1, &readfds, 0, 0, 0) == -1)
|
||||
{
|
||||
reading = 0;
|
||||
reading = FALSE;
|
||||
return (READ_ERR);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if USE_POLL
|
||||
if (fd != tty && use_poll)
|
||||
if (is_tty && fd != tty && use_poll)
|
||||
{
|
||||
int ret = check_poll(fd, tty);
|
||||
if (ret != 0)
|
||||
{
|
||||
if (ret == READ_INTR)
|
||||
sigs |= S_INTERRUPT;
|
||||
reading = 0;
|
||||
reading = FALSE;
|
||||
return (ret);
|
||||
}
|
||||
}
|
||||
|
|
@ -257,7 +259,7 @@ start:
|
|||
if (c == intr_char)
|
||||
{
|
||||
sigs |= S_INTERRUPT;
|
||||
reading = 0;
|
||||
reading = FALSE;
|
||||
return (READ_INTR);
|
||||
}
|
||||
WIN32ungetch(c);
|
||||
|
|
@ -265,7 +267,7 @@ start:
|
|||
#endif
|
||||
#endif
|
||||
n = read(fd, buf, len);
|
||||
reading = 0;
|
||||
reading = FALSE;
|
||||
#if 1
|
||||
/*
|
||||
* This is a kludge to workaround a problem on some systems
|
||||
|
|
@ -355,11 +357,11 @@ static char * strerror(int err)
|
|||
/*
|
||||
* errno_message: Return an error message based on the value of "errno".
|
||||
*/
|
||||
public char * errno_message(char *filename)
|
||||
public char * errno_message(constant char *filename)
|
||||
{
|
||||
char *p;
|
||||
char *m;
|
||||
int len;
|
||||
size_t len;
|
||||
#if HAVE_ERRNO
|
||||
#if MUST_DEFINE_ERRNO
|
||||
extern int errno;
|
||||
|
|
@ -368,7 +370,7 @@ public char * errno_message(char *filename)
|
|||
#else
|
||||
p = "cannot open";
|
||||
#endif
|
||||
len = (int) (strlen(filename) + strlen(p) + 3);
|
||||
len = strlen(filename) + strlen(p) + 3;
|
||||
m = (char *) ecalloc(len, sizeof(char));
|
||||
SNPRINTF2(m, len, "%s: %s", filename, p);
|
||||
return (m);
|
||||
|
|
@ -378,11 +380,11 @@ public char * errno_message(char *filename)
|
|||
* Return a description of a signal.
|
||||
* The return value is good until the next call to this function.
|
||||
*/
|
||||
public char * signal_message(int sig)
|
||||
public constant char * signal_message(int sig)
|
||||
{
|
||||
static char sigbuf[sizeof("Signal ") + INT_STRLEN_BOUND(sig) + 1];
|
||||
#if HAVE_STRSIGNAL
|
||||
char *description = strsignal(sig);
|
||||
constant char *description = strsignal(sig);
|
||||
if (description)
|
||||
return description;
|
||||
#endif
|
||||
|
|
@ -395,7 +397,7 @@ public char * signal_message(int sig)
|
|||
* 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)
|
||||
public uintmax umuldiv(uintmax val, uintmax num, uintmax den)
|
||||
{
|
||||
/*
|
||||
* Like round(val * (double) num / den), but without rounding error.
|
||||
|
|
@ -416,7 +418,7 @@ public uintmax muldiv(uintmax val, uintmax num, uintmax den)
|
|||
*/
|
||||
public int percentage(POSITION num, POSITION den)
|
||||
{
|
||||
return (int) muldiv(num, (POSITION) 100, den);
|
||||
return (int) muldiv(num, 100, den);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -433,7 +435,7 @@ public POSITION percent_pos(POSITION pos, int percent, long fraction)
|
|||
*/
|
||||
POSITION pctden = (percent * NUM_FRAC_DENOM) + fraction;
|
||||
|
||||
return (POSITION) muldiv(pos, pctden, 100 * (POSITION) NUM_FRAC_DENOM);
|
||||
return (POSITION) muldiv(pos, pctden, 100 * NUM_FRAC_DENOM);
|
||||
}
|
||||
|
||||
#if !HAVE_STRCHR
|
||||
|
|
@ -452,7 +454,7 @@ char * strchr(char *s, char c)
|
|||
#endif
|
||||
|
||||
#if !HAVE_MEMCPY
|
||||
void * memcpy(void *dst, void *src, int len)
|
||||
void * memcpy(void *dst, void *src, size_t len)
|
||||
{
|
||||
char *dstp = (char *) dst;
|
||||
char *srcp = (char *) src;
|
||||
|
|
@ -498,7 +500,7 @@ public void sleep_ms(int ms)
|
|||
nanosleep(&t, NULL);
|
||||
#else
|
||||
#if HAVE_USLEEP
|
||||
usleep(ms);
|
||||
usleep(ms * 1000);
|
||||
#else
|
||||
sleep(ms / 1000 + (ms % 1000 != 0));
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -28,9 +28,9 @@ public int at_prompt;
|
|||
extern int sigs;
|
||||
extern int sc_width;
|
||||
extern int so_s_width, so_e_width;
|
||||
extern int screen_trashed;
|
||||
extern int is_tty;
|
||||
extern int oldbot;
|
||||
extern int utf_mode;
|
||||
extern char intr_char;
|
||||
|
||||
#if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
|
||||
|
|
@ -52,7 +52,7 @@ extern int vt_enabled;
|
|||
public void put_line(void)
|
||||
{
|
||||
int c;
|
||||
int i;
|
||||
size_t i;
|
||||
int a;
|
||||
|
||||
if (ABORT_SIGS())
|
||||
|
|
@ -60,7 +60,7 @@ public void put_line(void)
|
|||
/*
|
||||
* Don't output if a signal is pending.
|
||||
*/
|
||||
screen_trashed = 1;
|
||||
screen_trashed();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -79,59 +79,222 @@ public void put_line(void)
|
|||
at_exit();
|
||||
}
|
||||
|
||||
/*
|
||||
* win_flush has at least one non-critical issue when an escape sequence
|
||||
* begins at the last char of the buffer, and possibly more issues.
|
||||
* as a temporary measure to reduce likelyhood of encountering end-of-buffer
|
||||
* issues till the SGR parser is replaced, OUTBUF_SIZE is 8K on Windows.
|
||||
*/
|
||||
static char obuf[OUTBUF_SIZE];
|
||||
static char *ob = obuf;
|
||||
static int outfd = 2; /* stderr */
|
||||
|
||||
#if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
|
||||
|
||||
typedef unsigned t_attr;
|
||||
|
||||
#define A_BOLD (1u<<0)
|
||||
#define A_ITALIC (1u<<1)
|
||||
#define A_UNDERLINE (1u<<2)
|
||||
#define A_BLINK (1u<<3)
|
||||
#define A_INVERSE (1u<<4)
|
||||
#define A_CONCEAL (1u<<5)
|
||||
|
||||
/* long is guaranteed 32 bits, and we reserve bits for type + RGB */
|
||||
typedef unsigned long t_color;
|
||||
|
||||
#define T_DEFAULT 0ul
|
||||
#define T_ANSI 1ul /* colors 0-7 */
|
||||
|
||||
#define CGET_ANSI(c) ((c) & 0x7)
|
||||
|
||||
#define C_DEFAULT (T_DEFAULT <<24) /* 0 */
|
||||
#define C_ANSI(c) ((T_ANSI <<24) | (c))
|
||||
|
||||
/* attr/fg/bg/all 0 is the default attr/fg/bg/all, respectively */
|
||||
typedef struct t_sgr {
|
||||
t_attr attr;
|
||||
t_color fg;
|
||||
t_color bg;
|
||||
} t_sgr;
|
||||
|
||||
static constant t_sgr SGR_DEFAULT; /* = {0} */
|
||||
|
||||
/* returns 0 on success, non-0 on unknown SGR code */
|
||||
static int update_sgr(t_sgr *sgr, long code)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case 0: *sgr = SGR_DEFAULT; break;
|
||||
|
||||
case 1: sgr->attr |= A_BOLD; break;
|
||||
case 22: sgr->attr &= ~A_BOLD; break;
|
||||
|
||||
case 3: sgr->attr |= A_ITALIC; break;
|
||||
case 23: sgr->attr &= ~A_ITALIC; break;
|
||||
|
||||
case 4: sgr->attr |= A_UNDERLINE; break;
|
||||
case 24: sgr->attr &= ~A_UNDERLINE; break;
|
||||
|
||||
case 6: /* fast-blink, fallthrough */
|
||||
case 5: sgr->attr |= A_BLINK; break;
|
||||
case 25: sgr->attr &= ~A_BLINK; break;
|
||||
|
||||
case 7: sgr->attr |= A_INVERSE; break;
|
||||
case 27: sgr->attr &= ~A_INVERSE; break;
|
||||
|
||||
case 8: sgr->attr |= A_CONCEAL; break;
|
||||
case 28: sgr->attr &= ~A_CONCEAL; break;
|
||||
|
||||
case 39: sgr->fg = C_DEFAULT; break;
|
||||
case 49: sgr->bg = C_DEFAULT; break;
|
||||
|
||||
case 30: case 31: case 32: case 33:
|
||||
case 34: case 35: case 36: case 37:
|
||||
sgr->fg = C_ANSI(code - 30);
|
||||
break;
|
||||
|
||||
case 40: case 41: case 42: case 43:
|
||||
case 44: case 45: case 46: case 47:
|
||||
sgr->bg = C_ANSI(code - 40);
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_win_colors(t_sgr *sgr)
|
||||
{
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
/* Screen colors used by 3x and 4x SGR commands. */
|
||||
static unsigned char screen_color[] = {
|
||||
0, /* BLACK */
|
||||
FOREGROUND_RED,
|
||||
FOREGROUND_GREEN,
|
||||
FOREGROUND_RED|FOREGROUND_GREEN,
|
||||
FOREGROUND_BLUE,
|
||||
FOREGROUND_BLUE|FOREGROUND_RED,
|
||||
FOREGROUND_BLUE|FOREGROUND_GREEN,
|
||||
FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED
|
||||
};
|
||||
#else
|
||||
static enum COLORS screen_color[] = {
|
||||
BLACK, RED, GREEN, BROWN,
|
||||
BLUE, MAGENTA, CYAN, LIGHTGRAY
|
||||
};
|
||||
#endif
|
||||
|
||||
int fg, bg, tmp; /* Windows colors */
|
||||
|
||||
/* Not "SGR mode": apply -D<x> to default fg+bg with one attribute */
|
||||
if (!sgr_mode && sgr->fg == C_DEFAULT && sgr->bg == C_DEFAULT)
|
||||
{
|
||||
switch (sgr->attr)
|
||||
{
|
||||
case A_BOLD:
|
||||
WIN32setcolors(bo_fg_color, bo_bg_color);
|
||||
return;
|
||||
case A_UNDERLINE:
|
||||
WIN32setcolors(ul_fg_color, ul_bg_color);
|
||||
return;
|
||||
case A_BLINK:
|
||||
WIN32setcolors(bl_fg_color, bl_bg_color);
|
||||
return;
|
||||
case A_INVERSE:
|
||||
WIN32setcolors(so_fg_color, so_bg_color);
|
||||
return;
|
||||
/*
|
||||
* There's no -Di so italic should not be here, but to
|
||||
* preserve legacy behavior, apply -Ds to italic too.
|
||||
*/
|
||||
case A_ITALIC:
|
||||
WIN32setcolors(so_fg_color, so_bg_color);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* generic application of the SGR state as Windows colors */
|
||||
|
||||
fg = sgr->fg == C_DEFAULT ? nm_fg_color
|
||||
: screen_color[CGET_ANSI(sgr->fg)];
|
||||
|
||||
bg = sgr->bg == C_DEFAULT ? nm_bg_color
|
||||
: screen_color[CGET_ANSI(sgr->bg)];
|
||||
|
||||
if (sgr->attr & A_BOLD)
|
||||
fg |= 8;
|
||||
|
||||
if (sgr->attr & (A_BLINK | A_UNDERLINE))
|
||||
bg |= 8; /* TODO: can be illegible */
|
||||
|
||||
if (sgr->attr & (A_INVERSE | A_ITALIC))
|
||||
{
|
||||
tmp = fg;
|
||||
fg = bg;
|
||||
bg = tmp;
|
||||
}
|
||||
|
||||
if (sgr->attr & A_CONCEAL)
|
||||
fg = bg ^ 8;
|
||||
|
||||
WIN32setcolors(fg, bg);
|
||||
}
|
||||
|
||||
/* like is_ansi_end, but doesn't assume c != 0 (returns 0 for c == 0) */
|
||||
static int is_ansi_end_0(char c)
|
||||
{
|
||||
return c && is_ansi_end((unsigned char)c);
|
||||
}
|
||||
|
||||
static void win_flush(void)
|
||||
{
|
||||
if (ctldisp != OPT_ONPLUS || (vt_enabled && sgr_mode))
|
||||
WIN32textout(obuf, ob - obuf);
|
||||
if (ctldisp != OPT_ONPLUS
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
|| (vt_enabled && sgr_mode)
|
||||
#endif
|
||||
)
|
||||
WIN32textout(obuf, ptr_diff(ob, obuf));
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Look for SGR escape sequences, and convert them
|
||||
* to color commands. Replace bold, underline,
|
||||
* and italic escapes into colors specified via
|
||||
* the -D command-line option.
|
||||
* Digest text, apply embedded SGR sequences as Windows-colors.
|
||||
* By default - when -Da ("SGR mode") is unset - also apply
|
||||
* translation of -D command-line options (at set_win_colors)
|
||||
*/
|
||||
char *anchor, *p, *p_next;
|
||||
static int fg, fgi, bg, bgi;
|
||||
static int at;
|
||||
int f, b;
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
/* Screen colors used by 3x and 4x SGR commands. */
|
||||
static unsigned char screen_color[] = {
|
||||
0, /* BLACK */
|
||||
FOREGROUND_RED,
|
||||
FOREGROUND_GREEN,
|
||||
FOREGROUND_RED|FOREGROUND_GREEN,
|
||||
FOREGROUND_BLUE,
|
||||
FOREGROUND_BLUE|FOREGROUND_RED,
|
||||
FOREGROUND_BLUE|FOREGROUND_GREEN,
|
||||
FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED
|
||||
};
|
||||
#else
|
||||
static enum COLORS screen_color[] = {
|
||||
BLACK, RED, GREEN, BROWN,
|
||||
BLUE, MAGENTA, CYAN, LIGHTGRAY
|
||||
};
|
||||
#endif
|
||||
static t_sgr sgr;
|
||||
|
||||
/* when unsupported SGR value is encountered, like 38/48 for
|
||||
* 256/true colors, then we abort processing this sequence,
|
||||
* because it may expect followup values, but we don't know
|
||||
* how many, so we've lost sync of this sequence parsing.
|
||||
* Without VT enabled it's OK because we can't do much anyway,
|
||||
* but with VT enabled we choose to passthrough this sequence
|
||||
* to the terminal - which can handle it better than us.
|
||||
* however, this means that our "sgr" var is no longer in sync
|
||||
* with the actual terminal state, which can lead to broken
|
||||
* colors with future sequences which we _can_ fully parse.
|
||||
* in such case, once it happens, we keep passthrough sequences
|
||||
* until we know we're in sync again - on a valid reset.
|
||||
*/
|
||||
static int sgr_bad_sync;
|
||||
|
||||
if (fg == 0 && bg == 0)
|
||||
{
|
||||
fg = nm_fg_color & 7;
|
||||
fgi = nm_fg_color & 8;
|
||||
bg = nm_bg_color & 7;
|
||||
bgi = nm_bg_color & 8;
|
||||
}
|
||||
for (anchor = p_next = obuf;
|
||||
(p_next = memchr(p_next, ESC, ob - p_next)) != NULL; )
|
||||
{
|
||||
p = p_next;
|
||||
if (p[1] == '[') /* "ESC-[" sequence */
|
||||
{
|
||||
/*
|
||||
* unknown SGR code ignores the rest of the seq,
|
||||
* and allows ignoring sequences such as
|
||||
* ^[[38;5;123m or ^[[38;2;5;6;7m
|
||||
* (prior known codes at the same seq do apply)
|
||||
*/
|
||||
int bad_code = 0;
|
||||
|
||||
if (p > anchor)
|
||||
{
|
||||
/*
|
||||
|
|
@ -139,35 +302,30 @@ static void win_flush(void)
|
|||
* the last escape sequence,
|
||||
* write them out to the screen.
|
||||
*/
|
||||
WIN32textout(anchor, p-anchor);
|
||||
WIN32textout(anchor, ptr_diff(p, anchor));
|
||||
anchor = p;
|
||||
}
|
||||
p += 2; /* Skip the "ESC-[" */
|
||||
if (is_ansi_end(*p))
|
||||
if (is_ansi_end_0(*p))
|
||||
{
|
||||
/*
|
||||
* Handle null escape sequence
|
||||
* "ESC[m", which restores
|
||||
* the normal color.
|
||||
* "ESC[m" as if it was "ESC[0m"
|
||||
*/
|
||||
p++;
|
||||
anchor = p_next = p;
|
||||
fg = nm_fg_color & 7;
|
||||
fgi = nm_fg_color & 8;
|
||||
bg = nm_bg_color & 7;
|
||||
bgi = nm_bg_color & 8;
|
||||
at = 0;
|
||||
WIN32setcolors(nm_fg_color, nm_bg_color);
|
||||
update_sgr(&sgr, 0);
|
||||
set_win_colors(&sgr);
|
||||
sgr_bad_sync = 0;
|
||||
continue;
|
||||
}
|
||||
p_next = p;
|
||||
at &= ~32;
|
||||
|
||||
/*
|
||||
* Select foreground/background colors
|
||||
* Parse and apply SGR values to the SGR state
|
||||
* based on the escape sequence.
|
||||
*/
|
||||
while (!is_ansi_end(*p))
|
||||
while (!is_ansi_end_0(*p))
|
||||
{
|
||||
char *q;
|
||||
long code = strtol(p, &q, 10);
|
||||
|
|
@ -179,166 +337,54 @@ static void win_flush(void)
|
|||
* Leave it unprocessed
|
||||
* in the buffer.
|
||||
*/
|
||||
int slop = (int) (q - anchor);
|
||||
/* {{ strcpy args overlap! }} */
|
||||
strcpy(obuf, anchor);
|
||||
size_t slop = ptr_diff(q, anchor);
|
||||
memmove(obuf, anchor, slop);
|
||||
ob = &obuf[slop];
|
||||
return;
|
||||
}
|
||||
|
||||
if (q == p ||
|
||||
code > 49 || code < 0 ||
|
||||
(!is_ansi_end(*q) && *q != ';'))
|
||||
(!is_ansi_end_0(*q) && *q != ';'))
|
||||
{
|
||||
/*
|
||||
* can't parse. passthrough
|
||||
* till the end of the buffer
|
||||
*/
|
||||
p_next = q;
|
||||
break;
|
||||
}
|
||||
if (*q == ';')
|
||||
{
|
||||
q++;
|
||||
at |= 32;
|
||||
}
|
||||
|
||||
switch (code)
|
||||
{
|
||||
default:
|
||||
/* case 0: all attrs off */
|
||||
fg = nm_fg_color & 7;
|
||||
bg = nm_bg_color & 7;
|
||||
at &= 32;
|
||||
/*
|
||||
* \e[0m use normal
|
||||
* intensities, but
|
||||
* \e[0;...m resets them
|
||||
*/
|
||||
if (at & 32)
|
||||
{
|
||||
fgi = 0;
|
||||
bgi = 0;
|
||||
} else
|
||||
{
|
||||
fgi = nm_fg_color & 8;
|
||||
bgi = nm_bg_color & 8;
|
||||
}
|
||||
break;
|
||||
case 1: /* bold on */
|
||||
fgi = 8;
|
||||
at |= 1;
|
||||
break;
|
||||
case 3: /* italic on */
|
||||
case 7: /* inverse on */
|
||||
at |= 2;
|
||||
break;
|
||||
case 4: /* underline on */
|
||||
bgi = 8;
|
||||
at |= 4;
|
||||
break;
|
||||
case 5: /* slow blink on */
|
||||
case 6: /* fast blink on */
|
||||
bgi = 8;
|
||||
at |= 8;
|
||||
break;
|
||||
case 8: /* concealed on */
|
||||
at |= 16;
|
||||
break;
|
||||
case 22: /* bold off */
|
||||
fgi = 0;
|
||||
at &= ~1;
|
||||
break;
|
||||
case 23: /* italic off */
|
||||
case 27: /* inverse off */
|
||||
at &= ~2;
|
||||
break;
|
||||
case 24: /* underline off */
|
||||
bgi = 0;
|
||||
at &= ~4;
|
||||
break;
|
||||
case 28: /* concealed off */
|
||||
at &= ~16;
|
||||
break;
|
||||
case 30: case 31: case 32:
|
||||
case 33: case 34: case 35:
|
||||
case 36: case 37:
|
||||
fg = screen_color[code - 30];
|
||||
at |= 32;
|
||||
break;
|
||||
case 39: /* default fg */
|
||||
fg = nm_fg_color & 7;
|
||||
at |= 32;
|
||||
break;
|
||||
case 40: case 41: case 42:
|
||||
case 43: case 44: case 45:
|
||||
case 46: case 47:
|
||||
bg = screen_color[code - 40];
|
||||
at |= 32;
|
||||
break;
|
||||
case 49: /* default bg */
|
||||
bg = nm_bg_color & 7;
|
||||
at |= 32;
|
||||
break;
|
||||
}
|
||||
if (!bad_code)
|
||||
bad_code = update_sgr(&sgr, code);
|
||||
|
||||
if (bad_code)
|
||||
sgr_bad_sync = 1;
|
||||
else if (code == 0)
|
||||
sgr_bad_sync = 0;
|
||||
|
||||
p = q;
|
||||
}
|
||||
if (!is_ansi_end(*p) || p == p_next)
|
||||
if (!is_ansi_end_0(*p) || p == p_next)
|
||||
break;
|
||||
/*
|
||||
* In SGR mode, the ANSI sequence is
|
||||
* always honored; otherwise if an attr
|
||||
* is used by itself ("\e[1m" versus
|
||||
* "\e[1;33m", for example), set the
|
||||
* color assigned to that attribute.
|
||||
*/
|
||||
if (sgr_mode || (at & 32))
|
||||
{
|
||||
if (at & 2)
|
||||
{
|
||||
f = bg | bgi;
|
||||
b = fg | fgi;
|
||||
} else
|
||||
{
|
||||
f = fg | fgi;
|
||||
b = bg | bgi;
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (at & 1)
|
||||
{
|
||||
f = bo_fg_color;
|
||||
b = bo_bg_color;
|
||||
} else if (at & 2)
|
||||
{
|
||||
f = so_fg_color;
|
||||
b = so_bg_color;
|
||||
} else if (at & 4)
|
||||
{
|
||||
f = ul_fg_color;
|
||||
b = ul_bg_color;
|
||||
} else if (at & 8)
|
||||
{
|
||||
f = bl_fg_color;
|
||||
b = bl_bg_color;
|
||||
} else
|
||||
{
|
||||
f = nm_fg_color;
|
||||
b = nm_bg_color;
|
||||
}
|
||||
|
||||
if (sgr_bad_sync && vt_enabled) {
|
||||
/* this or a prior sequence had unknown
|
||||
* SGR value. passthrough all sequences
|
||||
* until we're in-sync again
|
||||
*/
|
||||
WIN32textout(anchor, ptr_diff(p+1, anchor));
|
||||
} else {
|
||||
set_win_colors(&sgr);
|
||||
}
|
||||
if (at & 16)
|
||||
f = b ^ 8;
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
f &= 0xf | COMMON_LVB_UNDERSCORE;
|
||||
#else
|
||||
f &= 0xf;
|
||||
#endif
|
||||
b &= 0xf;
|
||||
WIN32setcolors(f, b);
|
||||
p_next = anchor = p + 1;
|
||||
} else
|
||||
p_next++;
|
||||
}
|
||||
|
||||
/* Output what's left in the buffer. */
|
||||
WIN32textout(anchor, ob - anchor);
|
||||
WIN32textout(anchor, ptr_diff(ob, anchor));
|
||||
}
|
||||
ob = obuf;
|
||||
}
|
||||
|
|
@ -362,9 +408,9 @@ static void win_flush(void)
|
|||
*/
|
||||
public void flush(void)
|
||||
{
|
||||
int n;
|
||||
size_t n;
|
||||
|
||||
n = (int) (ob - obuf);
|
||||
n = ptr_diff(ob, obuf);
|
||||
if (n == 0)
|
||||
return;
|
||||
ob = obuf;
|
||||
|
|
@ -389,7 +435,7 @@ public void flush(void)
|
|||
#endif
|
||||
|
||||
if (write(outfd, obuf, n) != n)
|
||||
screen_trashed = 1;
|
||||
screen_trashed();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -403,9 +449,11 @@ public void set_output(int fd)
|
|||
|
||||
/*
|
||||
* Output a character.
|
||||
* ch is int for compatibility with tputs.
|
||||
*/
|
||||
public int putchr(int c)
|
||||
public int putchr(int ch)
|
||||
{
|
||||
char c = (char) ch;
|
||||
#if 0 /* fake UTF-8 output for testing */
|
||||
extern int utf_mode;
|
||||
if (utf_mode)
|
||||
|
|
@ -492,25 +540,32 @@ TYPE_TO_A_FUNC(inttoa, int)
|
|||
/*
|
||||
* Convert a string to an integral type. Return ((type) -1) on overflow.
|
||||
*/
|
||||
#define STR_TO_TYPE_FUNC(funcname, type) \
|
||||
type funcname(char *buf, char **ebuf, int radix) \
|
||||
#define STR_TO_TYPE_FUNC(funcname, cfuncname, type) \
|
||||
type cfuncname(constant char *buf, constant char **ebuf, int radix) \
|
||||
{ \
|
||||
type val = 0; \
|
||||
int v = 0; \
|
||||
lbool v = 0; \
|
||||
for (;; buf++) { \
|
||||
char c = *buf; \
|
||||
int digit = (c >= '0' && c <= '9') ? c - '0' : (c >= 'a' && c <= 'f') ? c - 'a' + 10 : (c >= 'A' && c <= 'F') ? c - 'A' + 10 : -1; \
|
||||
if (digit < 0 || digit >= radix) break; \
|
||||
v |= ckd_mul(&val, val, radix); \
|
||||
v |= ckd_add(&val, val, digit); \
|
||||
v = v || ckd_mul(&val, val, radix); \
|
||||
v = v || ckd_add(&val, val, digit); \
|
||||
} \
|
||||
if (ebuf != NULL) *ebuf = buf; \
|
||||
return v ? -1 : val; \
|
||||
return v ? (type)(-1) : val; \
|
||||
} \
|
||||
type funcname(char *buf, char **ebuf, int radix) \
|
||||
{ \
|
||||
constant char *cbuf = buf; \
|
||||
type r = cfuncname(cbuf, &cbuf, radix); \
|
||||
if (ebuf != NULL) *ebuf = (char *) cbuf; /*{{const-issue}}*/ \
|
||||
return r; \
|
||||
}
|
||||
|
||||
STR_TO_TYPE_FUNC(lstrtopos, POSITION)
|
||||
STR_TO_TYPE_FUNC(lstrtoi, int)
|
||||
STR_TO_TYPE_FUNC(lstrtoul, unsigned long)
|
||||
STR_TO_TYPE_FUNC(lstrtopos, lstrtoposc, POSITION)
|
||||
STR_TO_TYPE_FUNC(lstrtoi, lstrtoic, int)
|
||||
STR_TO_TYPE_FUNC(lstrtoul, lstrtoulc, unsigned long)
|
||||
|
||||
/*
|
||||
* Print an integral type.
|
||||
|
|
@ -534,9 +589,10 @@ IPRINT_FUNC(iprint_linenum, LINENUM, linenumtoa)
|
|||
* {{ This paranoia about the portability of printf dates from experiences
|
||||
* with systems in the 1980s and is of course no longer necessary. }}
|
||||
*/
|
||||
public int less_printf(char *fmt, PARG *parg)
|
||||
public int less_printf(constant char *fmt, PARG *parg)
|
||||
{
|
||||
char *s;
|
||||
constant char *s;
|
||||
constant char *es;
|
||||
int col;
|
||||
|
||||
col = 0;
|
||||
|
|
@ -553,11 +609,17 @@ public int less_printf(char *fmt, PARG *parg)
|
|||
{
|
||||
case 's':
|
||||
s = parg->p_string;
|
||||
es = s + strlen(s);
|
||||
parg++;
|
||||
while (*s != '\0')
|
||||
{
|
||||
putchr(*s++);
|
||||
col++;
|
||||
LWCHAR ch = step_charc(&s, +1, es);
|
||||
constant char *ps = utf_mode ? prutfchar(ch) : prchar(ch);
|
||||
while (*ps != '\0')
|
||||
{
|
||||
putchr(*ps++);
|
||||
col++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
|
|
@ -573,7 +635,7 @@ public int less_printf(char *fmt, PARG *parg)
|
|||
parg++;
|
||||
break;
|
||||
case 'c':
|
||||
s = prchar(parg->p_char);
|
||||
s = prchar((LWCHAR) parg->p_char);
|
||||
parg++;
|
||||
while (*s != '\0')
|
||||
{
|
||||
|
|
@ -605,7 +667,7 @@ public void get_return(void)
|
|||
#else
|
||||
c = getchr();
|
||||
if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR)
|
||||
ungetcc(c);
|
||||
ungetcc((char) c);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -613,7 +675,7 @@ public void get_return(void)
|
|||
* Output a message in the lower left corner of the screen
|
||||
* and wait for carriage return.
|
||||
*/
|
||||
public void error(char *fmt, PARG *parg)
|
||||
public void error(constant char *fmt, PARG *parg)
|
||||
{
|
||||
int col = 0;
|
||||
static char return_to_continue[] = " (press RETURN)";
|
||||
|
|
@ -636,7 +698,7 @@ public void error(char *fmt, PARG *parg)
|
|||
col += less_printf(fmt, parg);
|
||||
putstr(return_to_continue);
|
||||
at_exit();
|
||||
col += sizeof(return_to_continue) + so_e_width;
|
||||
col += (int) sizeof(return_to_continue) + so_e_width;
|
||||
|
||||
get_return();
|
||||
lower_left();
|
||||
|
|
@ -648,7 +710,7 @@ public void error(char *fmt, PARG *parg)
|
|||
* {{ Unless the terminal doesn't have auto margins,
|
||||
* in which case we just hammered on the right margin. }}
|
||||
*/
|
||||
screen_trashed = 1;
|
||||
screen_trashed();
|
||||
|
||||
flush();
|
||||
}
|
||||
|
|
@ -659,7 +721,7 @@ public void error(char *fmt, PARG *parg)
|
|||
* Usually used to warn that we are beginning a potentially
|
||||
* time-consuming operation.
|
||||
*/
|
||||
static void ierror_suffix(char *fmt, PARG *parg, char *suffix1, char *suffix2, char *suffix3)
|
||||
static void ierror_suffix(constant char *fmt, PARG *parg, constant char *suffix1, constant char *suffix2, constant char *suffix3)
|
||||
{
|
||||
at_exit();
|
||||
clear_bot();
|
||||
|
|
@ -673,25 +735,28 @@ static void ierror_suffix(char *fmt, PARG *parg, char *suffix1, char *suffix2, c
|
|||
need_clr = 1;
|
||||
}
|
||||
|
||||
public void ierror(char *fmt, PARG *parg)
|
||||
public void ierror(constant char *fmt, PARG *parg)
|
||||
{
|
||||
ierror_suffix(fmt, parg, "... (interrupt to abort)", "", "");
|
||||
}
|
||||
|
||||
public void ixerror(char *fmt, PARG *parg)
|
||||
public void ixerror(constant char *fmt, PARG *parg)
|
||||
{
|
||||
if (!supports_ctrl_x())
|
||||
ierror(fmt, parg);
|
||||
else
|
||||
ierror_suffix(fmt, parg,
|
||||
"... (", prchar(intr_char), " or interrupt to abort)");
|
||||
{
|
||||
char ichar[MAX_PRCHAR_LEN+1];
|
||||
strcpy(ichar, prchar((LWCHAR) intr_char));
|
||||
ierror_suffix(fmt, parg, "... (", ichar, " or interrupt to abort)");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Output a message in the lower left corner of the screen
|
||||
* and return a single-character response.
|
||||
*/
|
||||
public int query(char *fmt, PARG *parg)
|
||||
public int query(constant char *fmt, PARG *parg)
|
||||
{
|
||||
int c;
|
||||
int col = 0;
|
||||
|
|
@ -706,7 +771,7 @@ public int query(char *fmt, PARG *parg)
|
|||
{
|
||||
lower_left();
|
||||
if (col >= sc_width)
|
||||
screen_trashed = 1;
|
||||
screen_trashed();
|
||||
flush();
|
||||
} else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -20,7 +20,7 @@ extern int utf_mode;
|
|||
/*
|
||||
* Compile a search pattern, for future use by match_pattern.
|
||||
*/
|
||||
static int compile_pattern2(char *pattern, int search_type, PATTERN_TYPE *comp_pattern, int show_error)
|
||||
static int compile_pattern2(constant char *pattern, int search_type, PATTERN_TYPE *comp_pattern, int show_error)
|
||||
{
|
||||
if (search_type & SRCH_NO_REGEX)
|
||||
return (0);
|
||||
|
|
@ -142,21 +142,20 @@ static int compile_pattern2(char *pattern, int search_type, PATTERN_TYPE *comp_p
|
|||
/*
|
||||
* Like compile_pattern2, but convert the pattern to lowercase if necessary.
|
||||
*/
|
||||
public int compile_pattern(char *pattern, int search_type, int show_error, PATTERN_TYPE *comp_pattern)
|
||||
public int compile_pattern(constant char *pattern, int search_type, int show_error, PATTERN_TYPE *comp_pattern)
|
||||
{
|
||||
char *cvt_pattern;
|
||||
int result;
|
||||
|
||||
if (caseless != OPT_ONPLUS || (re_handles_caseless && !(search_type & SRCH_NO_REGEX)))
|
||||
cvt_pattern = pattern;
|
||||
else
|
||||
{
|
||||
cvt_pattern = (char*) ecalloc(1, cvt_length(strlen(pattern), CVT_TO_LC));
|
||||
cvt_text(cvt_pattern, pattern, (int *)NULL, (int *)NULL, CVT_TO_LC);
|
||||
}
|
||||
result = compile_pattern2(cvt_pattern, search_type, comp_pattern, show_error);
|
||||
if (cvt_pattern != pattern)
|
||||
result = compile_pattern2(pattern, search_type, comp_pattern, show_error);
|
||||
} else
|
||||
{
|
||||
char *cvt_pattern = (char*) ecalloc(1, cvt_length(strlen(pattern), CVT_TO_LC));
|
||||
cvt_text(cvt_pattern, pattern, NULL, NULL, CVT_TO_LC);
|
||||
result = compile_pattern2(cvt_pattern, search_type, comp_pattern, show_error);
|
||||
free(cvt_pattern);
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
|
|
@ -227,7 +226,7 @@ public int valid_pattern(char *pattern)
|
|||
/*
|
||||
* Is a compiled pattern null?
|
||||
*/
|
||||
public int is_null_pattern(PATTERN_TYPE pattern)
|
||||
public lbool is_null_pattern(PATTERN_TYPE pattern)
|
||||
{
|
||||
#if HAVE_GNU_REGEX
|
||||
return (pattern == NULL);
|
||||
|
|
@ -258,12 +257,14 @@ public int is_null_pattern(PATTERN_TYPE pattern)
|
|||
* Simple pattern matching function.
|
||||
* It supports no metacharacters like *, etc.
|
||||
*/
|
||||
static int match(char *pattern, int pattern_len, char *buf, int buf_len, char ***sp, char ***ep, int nsubs)
|
||||
static int match(constant char *pattern, size_t pattern_len, constant char *buf, int buf_len, constant char ***sp, constant char ***ep, int nsubs)
|
||||
{
|
||||
char *pp, *lp;
|
||||
char *pattern_end = pattern + pattern_len;
|
||||
char *buf_end = buf + buf_len;
|
||||
constant char *pp;
|
||||
constant char *lp;
|
||||
constant char *pattern_end = pattern + pattern_len;
|
||||
constant char *buf_end = buf + buf_len;
|
||||
|
||||
(void) nsubs;
|
||||
for ( ; buf < buf_end; buf++)
|
||||
{
|
||||
for (pp = pattern, lp = buf; ; pp++, lp++)
|
||||
|
|
@ -294,9 +295,10 @@ static int match(char *pattern, int pattern_len, char *buf, int buf_len, char **
|
|||
* 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.
|
||||
*/
|
||||
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)
|
||||
static int match_pattern1(PATTERN_TYPE pattern, constant char *tpattern, constant char *line, size_t aline_len, constant char **sp, constant char **ep, int nsp, int notbol, int search_type)
|
||||
{
|
||||
int matched;
|
||||
int line_len = (int) aline_len; /*{{type-issue}}*/
|
||||
|
||||
#if NO_REGEX
|
||||
search_type |= SRCH_NO_REGEX;
|
||||
|
|
@ -442,7 +444,7 @@ static int match_pattern1(PATTERN_TYPE pattern, char *tpattern, char *line, int
|
|||
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)
|
||||
public int match_pattern(PATTERN_TYPE pattern, constant char *tpattern, constant char *line, size_t line_len, constant char **sp, constant 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;
|
||||
|
|
@ -457,7 +459,7 @@ public int match_pattern(PATTERN_TYPE pattern, char *tpattern, char *line, int l
|
|||
/*
|
||||
* Return the name of the pattern matching library.
|
||||
*/
|
||||
public char * pattern_lib_name(void)
|
||||
public constant char * pattern_lib_name(void)
|
||||
{
|
||||
#if HAVE_GNU_REGEX
|
||||
return ("GNU");
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -47,8 +47,8 @@ extern int less_is_more;
|
|||
|
||||
/* ---- RE_COMP ---- */
|
||||
#if HAVE_RE_COMP
|
||||
char *re_comp(char*);
|
||||
int re_exec(char*);
|
||||
constant char *re_comp(constant char*);
|
||||
int re_exec(constant char*);
|
||||
#define PATTERN_TYPE int
|
||||
#define SET_NULL_PATTERN(name) name = 0
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -25,7 +25,7 @@ static POSITION *table = NULL; /* The position table */
|
|||
static int table_size = 0;
|
||||
|
||||
extern int sc_width, sc_height;
|
||||
extern int header_lines;
|
||||
extern int hshift;
|
||||
|
||||
/*
|
||||
* Return the starting file position of a line displayed on the screen.
|
||||
|
|
@ -113,7 +113,7 @@ public void pos_init(void)
|
|||
free((char*)table);
|
||||
} else
|
||||
scrpos.pos = NULL_POSITION;
|
||||
table = (POSITION *) ecalloc(sc_height, sizeof(POSITION));
|
||||
table = (POSITION *) ecalloc((size_t) sc_height, sizeof(POSITION)); /*{{type-issue}}*/
|
||||
table_size = sc_height;
|
||||
pos_clear();
|
||||
if (scrpos.pos != NULL_POSITION)
|
||||
|
|
@ -236,3 +236,67 @@ public int sindex_from_sline(int sline)
|
|||
*/
|
||||
return (sline-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a line that starts at linepos,
|
||||
* and the character at byte offset choff into that line,
|
||||
* return the number of characters (not bytes) between the
|
||||
* beginning of the line and the first byte of the choff character.
|
||||
*/
|
||||
static int pos_shift(POSITION linepos, size_t choff)
|
||||
{
|
||||
constant char *line;
|
||||
size_t line_len;
|
||||
POSITION pos;
|
||||
int cvt_ops;
|
||||
char *cline;
|
||||
|
||||
pos = forw_raw_line_len(linepos, choff, &line, &line_len);
|
||||
if (pos == NULL_POSITION || line_len != choff)
|
||||
return -1;
|
||||
cvt_ops = get_cvt_ops(0); /* {{ Passing 0 ignores SRCH_NO_REGEX; does it matter? }} */
|
||||
/* {{ It would be nice to be able to call cvt_text with dst=NULL, to avoid need to alloc a useless cline. }} */
|
||||
cline = (char *) ecalloc(1, cvt_length(line_len, cvt_ops));
|
||||
cvt_text(cline, line, NULL, &line_len, cvt_ops);
|
||||
free(cline);
|
||||
return (int) line_len; /*{{type-issue}}*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the position of the first char of the line containing tpos.
|
||||
* Thus if tpos is the first char of its line, just return tpos.
|
||||
*/
|
||||
static POSITION beginning_of_line(POSITION tpos)
|
||||
{
|
||||
ch_seek(tpos);
|
||||
while (ch_tell() != ch_zero())
|
||||
{
|
||||
int ch = ch_back_get();
|
||||
if (ch == '\n')
|
||||
{
|
||||
(void) ch_forw_get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ch_tell();
|
||||
}
|
||||
|
||||
/*
|
||||
* When viewing long lines, it may be that the first char in the top screen
|
||||
* line is not the first char in its (file) line (the table is "beheaded").
|
||||
* This function sets that entry to the position of the first char in the line,
|
||||
* and sets hshift so that the first char in the first line is unchanged.
|
||||
*/
|
||||
public void pos_rehead(void)
|
||||
{
|
||||
POSITION linepos;
|
||||
POSITION tpos = table[TOP];
|
||||
if (tpos == NULL_POSITION)
|
||||
return;
|
||||
linepos = beginning_of_line(tpos);
|
||||
if (linepos == tpos)
|
||||
return;
|
||||
table[TOP] = linepos;
|
||||
hshift = pos_shift(linepos, (size_t) (tpos - linepos));
|
||||
screen_trashed();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -21,19 +21,21 @@
|
|||
#include "position.h"
|
||||
|
||||
extern int pr_type;
|
||||
extern int new_file;
|
||||
extern int sc_width;
|
||||
extern int so_s_width, so_e_width;
|
||||
extern lbool new_file;
|
||||
extern int linenums;
|
||||
extern int hshift;
|
||||
extern int sc_height;
|
||||
extern int jump_sline;
|
||||
extern int less_is_more;
|
||||
extern int header_lines;
|
||||
extern int utf_mode;
|
||||
extern IFILE curr_ifile;
|
||||
#if OSC8_LINK
|
||||
extern char *osc8_path;
|
||||
#endif
|
||||
#if EDITOR
|
||||
extern char *editor;
|
||||
extern char *editproto;
|
||||
extern constant char *editor;
|
||||
extern constant char *editproto;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -78,29 +80,52 @@ public void init_prompt(void)
|
|||
|
||||
/*
|
||||
* Append a string to the end of the message.
|
||||
* nprt means the character *may* be nonprintable
|
||||
* and should be converted to printable form.
|
||||
*/
|
||||
static void ap_str(char *s)
|
||||
static void ap_estr(constant char *s, lbool nprt)
|
||||
{
|
||||
int len;
|
||||
constant char *es = s + strlen(s);
|
||||
while (*s != '\0')
|
||||
{
|
||||
LWCHAR ch = step_charc(&s, +1, es);
|
||||
constant char *ps;
|
||||
char ubuf[MAX_UTF_CHAR_LEN+1];
|
||||
size_t plen;
|
||||
|
||||
len = (int) strlen(s);
|
||||
if (mp + len >= message + PROMPT_SIZE)
|
||||
len = (int) (message + PROMPT_SIZE - mp - 1);
|
||||
strncpy(mp, s, len);
|
||||
mp += len;
|
||||
if (nprt)
|
||||
{
|
||||
ps = utf_mode ? prutfchar(ch) : prchar(ch);
|
||||
} else
|
||||
{
|
||||
char *up = ubuf;
|
||||
put_wchar(&up, ch);
|
||||
*up = '\0';
|
||||
ps = ubuf;
|
||||
}
|
||||
plen = strlen(ps);
|
||||
if (mp + plen >= message + PROMPT_SIZE)
|
||||
break;
|
||||
strcpy(mp, ps);
|
||||
mp += plen;
|
||||
}
|
||||
*mp = '\0';
|
||||
}
|
||||
|
||||
static void ap_str(constant char *s)
|
||||
{
|
||||
ap_estr(s, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append a character to the end of the message.
|
||||
*/
|
||||
static void ap_char(char c)
|
||||
{
|
||||
char buf[2];
|
||||
|
||||
buf[0] = c;
|
||||
buf[1] = '\0';
|
||||
ap_str(buf);
|
||||
if (mp + 1 >= message + PROMPT_SIZE)
|
||||
return;
|
||||
*mp++ = c;
|
||||
*mp = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -165,7 +190,7 @@ static POSITION curr_byte(int where)
|
|||
* question mark followed by a single letter.
|
||||
* Here we decode that letter and return the appropriate boolean value.
|
||||
*/
|
||||
static int cond(char c, int where)
|
||||
static lbool cond(char c, int where)
|
||||
{
|
||||
POSITION len;
|
||||
|
||||
|
|
@ -185,7 +210,7 @@ static int cond(char c, int where)
|
|||
case 'l': /* Line number known? */
|
||||
case 'd': /* Same as l */
|
||||
if (!linenums)
|
||||
return 0;
|
||||
return FALSE;
|
||||
return (currline(where) != 0);
|
||||
case 'L': /* Final line number known? */
|
||||
case 'D': /* Final page number known? */
|
||||
|
|
@ -198,13 +223,12 @@ static int cond(char c, int where)
|
|||
#endif
|
||||
case 'n': /* First prompt in a new file? */
|
||||
#if TAGS
|
||||
return (ntags() ? 1 : new_file);
|
||||
return (ntags() ? TRUE : new_file ? TRUE : FALSE);
|
||||
#else
|
||||
return (new_file);
|
||||
return (new_file ? TRUE : FALSE);
|
||||
#endif
|
||||
case 'p': /* Percent into file (bytes) known? */
|
||||
return (curr_byte(where) != NULL_POSITION &&
|
||||
ch_length() > 0);
|
||||
return (curr_byte(where) != NULL_POSITION && ch_length() > 0);
|
||||
case 'P': /* Percent into file (lines) known? */
|
||||
return (currline(where) != 0 &&
|
||||
(len = ch_length()) > 0 &&
|
||||
|
|
@ -215,11 +239,11 @@ static int cond(char c, int where)
|
|||
case 'x': /* Is there a "next" file? */
|
||||
#if TAGS
|
||||
if (ntags())
|
||||
return (0);
|
||||
return (FALSE);
|
||||
#endif
|
||||
return (next_ifile(curr_ifile) != NULL_IFILE);
|
||||
}
|
||||
return (0);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -229,7 +253,7 @@ static int cond(char c, int where)
|
|||
* Here we decode that letter and take the appropriate action,
|
||||
* usually by appending something to the message being built.
|
||||
*/
|
||||
static void protochar(int c, int where, int iseditproto)
|
||||
static void protochar(char c, int where)
|
||||
{
|
||||
POSITION pos;
|
||||
POSITION len;
|
||||
|
|
@ -284,10 +308,10 @@ static void protochar(int c, int where, int iseditproto)
|
|||
break;
|
||||
#endif
|
||||
case 'f': /* File name */
|
||||
ap_str(get_filename(curr_ifile));
|
||||
ap_estr(get_filename(curr_ifile), TRUE);
|
||||
break;
|
||||
case 'F': /* Last component of file name */
|
||||
ap_str(last_component(get_filename(curr_ifile)));
|
||||
ap_estr(last_component(get_filename(curr_ifile)), TRUE);
|
||||
break;
|
||||
case 'g': /* Shell-escaped file name */
|
||||
s = shell_quote(get_filename(curr_ifile));
|
||||
|
|
@ -326,6 +350,14 @@ static void protochar(int c, int where, int iseditproto)
|
|||
#endif
|
||||
ap_int(nifile());
|
||||
break;
|
||||
case 'o': /* path (URI without protocol) of selected OSC8 link */
|
||||
#if OSC8_LINK
|
||||
if (osc8_path != NULL)
|
||||
ap_str(osc8_path);
|
||||
else
|
||||
#endif
|
||||
ap_quest();
|
||||
break;
|
||||
case 'p': /* Percent into file (bytes) */
|
||||
pos = curr_byte(where);
|
||||
len = ch_length();
|
||||
|
|
@ -459,10 +491,10 @@ static constant char * wherechar(char constant *p, int *wp)
|
|||
/*
|
||||
* Construct a message based on a prototype string.
|
||||
*/
|
||||
public char * pr_expand(constant char *proto)
|
||||
public constant char * pr_expand(constant char *proto)
|
||||
{
|
||||
constant char *p;
|
||||
int c;
|
||||
char c;
|
||||
int where;
|
||||
|
||||
mp = message;
|
||||
|
|
@ -504,13 +536,7 @@ public char * pr_expand(constant char *proto)
|
|||
{
|
||||
where = 0;
|
||||
p = wherechar(p, &where);
|
||||
protochar(c, where,
|
||||
#if EDITOR
|
||||
(proto == editproto));
|
||||
#else
|
||||
0);
|
||||
#endif
|
||||
|
||||
protochar(c, where);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -524,7 +550,7 @@ public char * pr_expand(constant char *proto)
|
|||
/*
|
||||
* Return a message suitable for printing by the "=" command.
|
||||
*/
|
||||
public char * eq_message(void)
|
||||
public constant char * eq_message(void)
|
||||
{
|
||||
return (pr_expand(eqproto));
|
||||
}
|
||||
|
|
@ -535,22 +561,22 @@ public char * eq_message(void)
|
|||
* If we can't come up with an appropriate prompt, return NULL
|
||||
* and the caller will prompt with a colon.
|
||||
*/
|
||||
public char * pr_string(void)
|
||||
public constant char * pr_string(void)
|
||||
{
|
||||
char *prompt;
|
||||
constant char *prompt;
|
||||
int type;
|
||||
|
||||
type = (!less_is_more) ? pr_type : pr_type ? 0 : 1;
|
||||
prompt = pr_expand((ch_getflags() & CH_HELPFILE) ?
|
||||
hproto : prproto[type]);
|
||||
new_file = 0;
|
||||
new_file = FALSE;
|
||||
return (prompt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a message suitable for printing while waiting in the F command.
|
||||
*/
|
||||
public char * wait_message(void)
|
||||
public constant char * wait_message(void)
|
||||
{
|
||||
return (pr_expand(wproto));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@
|
|||
/*
|
||||
* Global work variables for regcomp().
|
||||
*/
|
||||
static char *regparse; /* Input-scan pointer. */
|
||||
static constant char *regparse; /* Input-scan pointer. */
|
||||
static int regnpar; /* () count. */
|
||||
static char regdummy;
|
||||
static char *regcode; /* Code-emit pointer; ®dummy = don't. */
|
||||
|
|
@ -177,18 +177,18 @@ static long regsize; /* Code size. */
|
|||
#ifndef STATIC
|
||||
#define STATIC static
|
||||
#endif
|
||||
STATIC char *reg();
|
||||
STATIC char *regbranch();
|
||||
STATIC char *regpiece();
|
||||
STATIC char *regatom();
|
||||
STATIC char *regnode();
|
||||
STATIC char *regnext();
|
||||
STATIC void regc();
|
||||
STATIC void reginsert();
|
||||
STATIC void regtail();
|
||||
STATIC void regoptail();
|
||||
STATIC char *reg(int, int *);
|
||||
STATIC char *regbranch(int *);
|
||||
STATIC char *regpiece(int *);
|
||||
STATIC char *regatom(int *);
|
||||
STATIC char *regnode(char);
|
||||
STATIC char *regnext(register char *);
|
||||
STATIC void regc(char);
|
||||
STATIC void reginsert(char, char *);
|
||||
STATIC void regtail(char *, char *);
|
||||
STATIC void regoptail(char *, char *);
|
||||
#ifdef STRCSPN
|
||||
STATIC int strcspn();
|
||||
STATIC int strcspn(constant char *, constant char *);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -207,8 +207,7 @@ STATIC int strcspn();
|
|||
* of the structure of the compiled regexp.
|
||||
*/
|
||||
regexp *
|
||||
regcomp(exp)
|
||||
char *exp;
|
||||
regcomp(constant char *exp)
|
||||
{
|
||||
register regexp *r;
|
||||
register char *scan;
|
||||
|
|
@ -297,9 +296,7 @@ char *exp;
|
|||
* follows makes it hard to avoid.
|
||||
*/
|
||||
static char *
|
||||
reg(paren, flagp)
|
||||
int paren; /* Parenthesized? */
|
||||
int *flagp;
|
||||
reg(int paren, int *flagp)
|
||||
{
|
||||
register char *ret;
|
||||
register char *br;
|
||||
|
|
@ -369,8 +366,7 @@ int *flagp;
|
|||
* Implements the concatenation operator.
|
||||
*/
|
||||
static char *
|
||||
regbranch(flagp)
|
||||
int *flagp;
|
||||
regbranch(int *flagp)
|
||||
{
|
||||
register char *ret;
|
||||
register char *chain;
|
||||
|
|
@ -408,8 +404,7 @@ int *flagp;
|
|||
* endmarker role is not redundant.
|
||||
*/
|
||||
static char *
|
||||
regpiece(flagp)
|
||||
int *flagp;
|
||||
regpiece(int *flagp)
|
||||
{
|
||||
register char *ret;
|
||||
register char op;
|
||||
|
|
@ -472,8 +467,7 @@ int *flagp;
|
|||
* separate node; the code is simpler that way and it's not worth fixing.
|
||||
*/
|
||||
static char *
|
||||
regatom(flagp)
|
||||
int *flagp;
|
||||
regatom(int *flagp)
|
||||
{
|
||||
register char *ret;
|
||||
int flags;
|
||||
|
|
@ -583,8 +577,7 @@ int *flagp;
|
|||
- regnode - emit a node
|
||||
*/
|
||||
static char * /* Location. */
|
||||
regnode(op)
|
||||
char op;
|
||||
regnode(char op)
|
||||
{
|
||||
register char *ret;
|
||||
register char *ptr;
|
||||
|
|
@ -608,8 +601,7 @@ char op;
|
|||
- regc - emit (if appropriate) a byte of code
|
||||
*/
|
||||
static void
|
||||
regc(b)
|
||||
char b;
|
||||
regc(char b)
|
||||
{
|
||||
if (regcode != ®dummy)
|
||||
*regcode++ = b;
|
||||
|
|
@ -623,11 +615,9 @@ char b;
|
|||
* Means relocating the operand.
|
||||
*/
|
||||
static void
|
||||
reginsert(op, opnd)
|
||||
char op;
|
||||
char *opnd;
|
||||
reginsert(char op, char *opnd)
|
||||
{
|
||||
register char *src;
|
||||
register constant char *src;
|
||||
register char *dst;
|
||||
register char *place;
|
||||
|
||||
|
|
@ -652,9 +642,7 @@ char *opnd;
|
|||
- regtail - set the next-pointer at the end of a node chain
|
||||
*/
|
||||
static void
|
||||
regtail(p, val)
|
||||
char *p;
|
||||
char *val;
|
||||
regtail(char *p, char *val)
|
||||
{
|
||||
register char *scan;
|
||||
register char *temp;
|
||||
|
|
@ -684,9 +672,7 @@ char *val;
|
|||
- regoptail - regtail on operand of first argument; nop if operandless
|
||||
*/
|
||||
static void
|
||||
regoptail(p, val)
|
||||
char *p;
|
||||
char *val;
|
||||
regoptail(char *p, char *val)
|
||||
{
|
||||
/* "Operandless" and "op != BRANCH" are synonymous in practice. */
|
||||
if (p == NULL || p == ®dummy || OP(p) != BRANCH)
|
||||
|
|
@ -701,17 +687,17 @@ char *val;
|
|||
/*
|
||||
* Global work variables for regexec().
|
||||
*/
|
||||
static char *reginput; /* String-input pointer. */
|
||||
static char *regbol; /* Beginning of input, for ^ check. */
|
||||
static char **regstartp; /* Pointer to startp array. */
|
||||
static char **regendp; /* Ditto for endp. */
|
||||
static constant char *reginput; /* String-input pointer. */
|
||||
static constant char *regbol; /* Beginning of input, for ^ check. */
|
||||
static constant char **regstartp; /* Pointer to startp array. */
|
||||
static constant char **regendp; /* Ditto for endp. */
|
||||
|
||||
/*
|
||||
* Forwards.
|
||||
*/
|
||||
STATIC int regtry();
|
||||
STATIC int regmatch();
|
||||
STATIC int regrepeat();
|
||||
STATIC int regtry(regexp *, constant char *);
|
||||
STATIC int regmatch(char *);
|
||||
STATIC int regrepeat(char *);
|
||||
|
||||
#ifdef DEBUG
|
||||
int regnarrate = 0;
|
||||
|
|
@ -723,12 +709,9 @@ STATIC char *regprop();
|
|||
- regexec - match a regexp against a string
|
||||
*/
|
||||
int
|
||||
regexec2(prog, string, notbol)
|
||||
register regexp *prog;
|
||||
register char *string;
|
||||
int notbol;
|
||||
regexec2(register regexp *prog, register constant char *string, int notbol)
|
||||
{
|
||||
register char *s;
|
||||
register constant char *s;
|
||||
|
||||
/* Be paranoid... */
|
||||
if (prog == NULL || string == NULL) {
|
||||
|
|
@ -785,9 +768,7 @@ int notbol;
|
|||
}
|
||||
|
||||
int
|
||||
regexec(prog, string)
|
||||
register regexp *prog;
|
||||
register char *string;
|
||||
regexec(register regexp *prog, register constant char *string)
|
||||
{
|
||||
return regexec2(prog, string, 0);
|
||||
}
|
||||
|
|
@ -796,13 +777,11 @@ register char *string;
|
|||
- regtry - try match at specific point
|
||||
*/
|
||||
static int /* 0 failure, 1 success */
|
||||
regtry(prog, string)
|
||||
regexp *prog;
|
||||
char *string;
|
||||
regtry(regexp *prog, constant char *string)
|
||||
{
|
||||
register int i;
|
||||
register char **sp;
|
||||
register char **ep;
|
||||
register constant char **sp;
|
||||
register constant char **ep;
|
||||
|
||||
reginput = string;
|
||||
regstartp = prog->startp;
|
||||
|
|
@ -833,8 +812,7 @@ char *string;
|
|||
* by recursion.
|
||||
*/
|
||||
static int /* 0 failure, 1 success */
|
||||
regmatch(prog)
|
||||
char *prog;
|
||||
regmatch(char *prog)
|
||||
{
|
||||
register char *scan; /* Current node. */
|
||||
char *next; /* Next node. */
|
||||
|
|
@ -903,7 +881,7 @@ char *prog;
|
|||
case OPEN+8:
|
||||
case OPEN+9: {
|
||||
register int no;
|
||||
register char *save;
|
||||
register constant char *save;
|
||||
|
||||
no = OP(scan) - OPEN;
|
||||
save = reginput;
|
||||
|
|
@ -932,7 +910,7 @@ char *prog;
|
|||
case CLOSE+8:
|
||||
case CLOSE+9: {
|
||||
register int no;
|
||||
register char *save;
|
||||
register constant char *save;
|
||||
|
||||
no = OP(scan) - CLOSE;
|
||||
save = reginput;
|
||||
|
|
@ -952,7 +930,7 @@ char *prog;
|
|||
/* NOTREACHED */
|
||||
break;
|
||||
case BRANCH: {
|
||||
register char *save;
|
||||
register constant char *save;
|
||||
|
||||
if (OP(next) != BRANCH) /* No choice. */
|
||||
next = OPERAND(scan); /* Avoid recursion. */
|
||||
|
|
@ -974,7 +952,7 @@ char *prog;
|
|||
case PLUS: {
|
||||
register char nextch;
|
||||
register int no;
|
||||
register char *save;
|
||||
register constant char *save;
|
||||
register int min;
|
||||
|
||||
/*
|
||||
|
|
@ -1026,11 +1004,10 @@ char *prog;
|
|||
- regrepeat - repeatedly match something simple, report how many
|
||||
*/
|
||||
static int
|
||||
regrepeat(p)
|
||||
char *p;
|
||||
regrepeat(char *p)
|
||||
{
|
||||
register int count = 0;
|
||||
register char *scan;
|
||||
register constant char *scan;
|
||||
register char *opnd;
|
||||
|
||||
scan = reginput;
|
||||
|
|
@ -1072,8 +1049,7 @@ char *p;
|
|||
- regnext - dig the "next" pointer out of a node
|
||||
*/
|
||||
static char *
|
||||
regnext(p)
|
||||
register char *p;
|
||||
regnext(register char *p)
|
||||
{
|
||||
register int offset;
|
||||
|
||||
|
|
@ -1140,9 +1116,9 @@ regexp *r;
|
|||
/*
|
||||
- regprop - printable representation of opcode
|
||||
*/
|
||||
static char *
|
||||
static constant char *
|
||||
regprop(op)
|
||||
char *op;
|
||||
constant char *op;
|
||||
{
|
||||
register char *p;
|
||||
static char buf[50];
|
||||
|
|
@ -1233,9 +1209,7 @@ char *op;
|
|||
*/
|
||||
|
||||
static int
|
||||
strcspn(s1, s2)
|
||||
char *s1;
|
||||
char *s2;
|
||||
strcspn(constant char *s1, constant char *s2)
|
||||
{
|
||||
register char *scan1;
|
||||
register char *scan2;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
#define NSUBEXP 10
|
||||
typedef struct regexp {
|
||||
char *startp[NSUBEXP];
|
||||
char *endp[NSUBEXP];
|
||||
constant char *startp[NSUBEXP];
|
||||
constant char *endp[NSUBEXP];
|
||||
char regstart; /* Internal use only. */
|
||||
char reganch; /* Internal use only. */
|
||||
char *regmust; /* Internal use only. */
|
||||
|
|
@ -25,10 +25,10 @@ typedef struct regexp {
|
|||
# define _ANSI_ARGS_(x) ()
|
||||
#endif
|
||||
|
||||
extern regexp *regcomp _ANSI_ARGS_((char *exp));
|
||||
extern int regexec _ANSI_ARGS_((regexp *prog, char *string));
|
||||
extern int regexec2 _ANSI_ARGS_((regexp *prog, char *string, int notbol));
|
||||
extern void regsub _ANSI_ARGS_((regexp *prog, char *source, char *dest));
|
||||
extern void regerror _ANSI_ARGS_((char *msg));
|
||||
extern regexp *regcomp _ANSI_ARGS_((constant char *exp));
|
||||
extern int regexec _ANSI_ARGS_((regexp *prog, constant char *string));
|
||||
extern int regexec2 _ANSI_ARGS_((regexp *prog, constant char *string, int notbol));
|
||||
extern void regsub _ANSI_ARGS_((regexp *prog, constant char *source, char *dest));
|
||||
extern void regerror _ANSI_ARGS_((constant char *msg));
|
||||
|
||||
#endif /* REGEXP */
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -28,13 +28,10 @@
|
|||
public int sigs;
|
||||
|
||||
extern int sc_width, sc_height;
|
||||
extern int screen_trashed;
|
||||
extern int lnloop;
|
||||
extern int linenums;
|
||||
extern int wscroll;
|
||||
extern int reading;
|
||||
extern int quit_on_intr;
|
||||
extern int secure;
|
||||
extern long jump_sline_fraction;
|
||||
|
||||
extern int less_is_more;
|
||||
|
|
@ -46,6 +43,7 @@ extern int less_is_more;
|
|||
/* ARGSUSED*/
|
||||
static RETSIGTYPE u_interrupt(int type)
|
||||
{
|
||||
(void) type;
|
||||
bell();
|
||||
#if OS2
|
||||
LSIGNAL(SIGINT, SIG_ACK);
|
||||
|
|
@ -78,6 +76,7 @@ static RETSIGTYPE u_interrupt(int type)
|
|||
/* ARGSUSED*/
|
||||
static RETSIGTYPE stop(int type)
|
||||
{
|
||||
(void) type;
|
||||
LSIGNAL(SIGTSTP, stop);
|
||||
sigs |= S_STOP;
|
||||
if (reading)
|
||||
|
|
@ -101,6 +100,7 @@ static RETSIGTYPE stop(int type)
|
|||
/* ARGSUSED*/
|
||||
public RETSIGTYPE winch(int type)
|
||||
{
|
||||
(void) type;
|
||||
LSIGNAL(SIG_LESSWINDOW, winch);
|
||||
sigs |= S_WINCH;
|
||||
if (reading)
|
||||
|
|
@ -135,6 +135,7 @@ static BOOL WINAPI wbreak_handler(DWORD dwCtrlType)
|
|||
|
||||
static RETSIGTYPE terminate(int type)
|
||||
{
|
||||
(void) type;
|
||||
quit(15);
|
||||
}
|
||||
|
||||
|
|
@ -154,7 +155,7 @@ public void init_signals(int on)
|
|||
(void) LSIGNAL(SIGINT, u_interrupt);
|
||||
#endif
|
||||
#ifdef SIGTSTP
|
||||
(void) LSIGNAL(SIGTSTP, secure ? SIG_IGN : stop);
|
||||
(void) LSIGNAL(SIGTSTP, !secure_allow(SF_STOP) ? SIG_IGN : stop);
|
||||
#endif
|
||||
#ifdef SIGWINCH
|
||||
(void) LSIGNAL(SIGWINCH, winch);
|
||||
|
|
@ -235,7 +236,7 @@ public void psignals(void)
|
|||
LSIGNAL(SIGTSTP, stop);
|
||||
raw_mode(1);
|
||||
init();
|
||||
screen_trashed = 1;
|
||||
screen_trashed();
|
||||
tsignals |= S_WINCH;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -252,15 +253,18 @@ public void psignals(void)
|
|||
if (sc_width != old_width || sc_height != old_height)
|
||||
{
|
||||
wscroll = (sc_height + 1) / 2;
|
||||
calc_jump_sline();
|
||||
calc_shift_count();
|
||||
screen_size_changed();
|
||||
}
|
||||
screen_trashed = 1;
|
||||
screen_trashed();
|
||||
}
|
||||
#endif
|
||||
if (tsignals & S_INTERRUPT)
|
||||
{
|
||||
if (quit_on_intr)
|
||||
quit(QUIT_INTERRUPT);
|
||||
getcc_clear();
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
win32_getch_clear();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -14,8 +14,8 @@
|
|||
|
||||
#if TAGS
|
||||
|
||||
public char ztags[] = "tags";
|
||||
public char *tags = ztags;
|
||||
public constant char ztags[] = "tags";
|
||||
public constant char *tags = ztags;
|
||||
|
||||
static int total;
|
||||
static int curseq;
|
||||
|
|
@ -44,13 +44,13 @@ enum {
|
|||
T_GPATH /* 'GPATH': path name (global) */
|
||||
};
|
||||
|
||||
static enum tag_result findctag(char *tag);
|
||||
static enum tag_result findgtag(char *tag, int type);
|
||||
static char *nextgtag(void);
|
||||
static char *prevgtag(void);
|
||||
static enum tag_result findctag(constant char *tag);
|
||||
static enum tag_result findgtag(constant char *tag, int type);
|
||||
static constant char *nextgtag(void);
|
||||
static constant char *prevgtag(void);
|
||||
static POSITION ctagsearch(void);
|
||||
static POSITION gtagsearch(void);
|
||||
static int getentry(char *buf, char **tag, char **file, char **line);
|
||||
static int getentry(char *buf, constant char **tag, constant char **file, constant char **line);
|
||||
|
||||
/*
|
||||
* The list of tags generated by the last findgtag() call.
|
||||
|
|
@ -69,7 +69,7 @@ struct tag {
|
|||
char *tag_file; /* Source file containing the tag */
|
||||
LINENUM tag_linenum; /* Appropriate line number in source file */
|
||||
char *tag_pattern; /* Pattern used to find the tag */
|
||||
char tag_endline; /* True if the pattern includes '$' */
|
||||
lbool tag_endline; /* True if the pattern includes '$' */
|
||||
};
|
||||
#define TAG_END ((struct tag *) &taglist)
|
||||
static struct taglist taglist = { TAG_END, TAG_END };
|
||||
|
|
@ -111,7 +111,7 @@ public void cleantags(void)
|
|||
/*
|
||||
* Create a new tag entry.
|
||||
*/
|
||||
static struct tag * maketagent(char *name, char *file, LINENUM linenum, char *pattern, int endline)
|
||||
static struct tag * maketagent(constant char *file, LINENUM linenum, constant char *pattern, lbool endline)
|
||||
{
|
||||
struct tag *tp;
|
||||
|
||||
|
|
@ -163,7 +163,7 @@ public int gettagtype(void)
|
|||
* and "tagpattern" to the search pattern which should be used
|
||||
* to find the tag.
|
||||
*/
|
||||
public void findtag(char *tag)
|
||||
public void findtag(constant char *tag)
|
||||
{
|
||||
int type = gettagtype();
|
||||
enum tag_result result;
|
||||
|
|
@ -205,9 +205,9 @@ public POSITION tagsearch(void)
|
|||
/*
|
||||
* Go to the next tag.
|
||||
*/
|
||||
public char * nexttag(int n)
|
||||
public constant char * nexttag(int n)
|
||||
{
|
||||
char *tagfile = (char *) NULL;
|
||||
constant char *tagfile = (char *) NULL;
|
||||
|
||||
while (n-- > 0)
|
||||
tagfile = nextgtag();
|
||||
|
|
@ -217,9 +217,9 @@ public char * nexttag(int n)
|
|||
/*
|
||||
* Go to the previous tag.
|
||||
*/
|
||||
public char * prevtag(int n)
|
||||
public constant char * prevtag(int n)
|
||||
{
|
||||
char *tagfile = (char *) NULL;
|
||||
constant char *tagfile = (char *) NULL;
|
||||
|
||||
while (n-- > 0)
|
||||
tagfile = prevgtag();
|
||||
|
|
@ -250,18 +250,18 @@ public int curr_tag(void)
|
|||
* Find tags in the "tags" file.
|
||||
* Sets curtag to the first tag entry.
|
||||
*/
|
||||
static enum tag_result findctag(char *tag)
|
||||
static enum tag_result findctag(constant char *tag)
|
||||
{
|
||||
char *p;
|
||||
char *q;
|
||||
FILE *f;
|
||||
int taglen;
|
||||
size_t taglen;
|
||||
LINENUM taglinenum;
|
||||
char *tagfile;
|
||||
char *tagpattern;
|
||||
int tagendline;
|
||||
lbool tagendline;
|
||||
int search_char;
|
||||
int err;
|
||||
lbool err;
|
||||
char tline[TAGLINE_SIZE];
|
||||
struct tag *tp;
|
||||
|
||||
|
|
@ -273,7 +273,7 @@ static enum tag_result findctag(char *tag)
|
|||
|
||||
cleantags();
|
||||
total = 0;
|
||||
taglen = (int) strlen(tag);
|
||||
taglen = strlen(tag);
|
||||
|
||||
/*
|
||||
* Search the tags file for the desired tag.
|
||||
|
|
@ -320,7 +320,7 @@ static enum tag_result findctag(char *tag)
|
|||
/*
|
||||
* First see if it is a line number.
|
||||
*/
|
||||
tagendline = 0;
|
||||
tagendline = FALSE;
|
||||
taglinenum = getnum(&p, 0, &err);
|
||||
if (err)
|
||||
{
|
||||
|
|
@ -353,7 +353,7 @@ static enum tag_result findctag(char *tag)
|
|||
q--;
|
||||
*q = '\0';
|
||||
}
|
||||
tp = maketagent(tag, tagfile, taglinenum, tagpattern, tagendline);
|
||||
tp = maketagent(tagfile, taglinenum, tagpattern, tagendline);
|
||||
TAG_INS(tp);
|
||||
total++;
|
||||
}
|
||||
|
|
@ -384,7 +384,7 @@ static int curtag_match(char constant *line, POSITION linepos)
|
|||
* If tagendline is set, make sure we match all
|
||||
* the way to end of line (no extra chars after the match).
|
||||
*/
|
||||
int len = (int) strlen(curtag->tag_pattern);
|
||||
size_t len = strlen(curtag->tag_pattern);
|
||||
if (strncmp(curtag->tag_pattern, line, len) == 0 &&
|
||||
(!curtag->tag_endline || line[len] == '\0' || line[len] == '\r'))
|
||||
{
|
||||
|
|
@ -407,8 +407,8 @@ static POSITION ctagsearch(void)
|
|||
{
|
||||
POSITION pos, linepos;
|
||||
LINENUM linenum;
|
||||
int line_len;
|
||||
char *line;
|
||||
size_t line_len;
|
||||
constant char *line;
|
||||
int found;
|
||||
|
||||
pos = ch_zero();
|
||||
|
|
@ -456,7 +456,7 @@ static POSITION ctagsearch(void)
|
|||
} else
|
||||
{
|
||||
int cvt_ops = CVT_ANSI;
|
||||
int cvt_len = cvt_length(line_len, cvt_ops);
|
||||
size_t cvt_len = cvt_length(line_len, cvt_ops);
|
||||
int *chpos = cvt_alloc_chpos(cvt_len);
|
||||
char *cline = (char *) ecalloc(1, cvt_len);
|
||||
cvt_text(cline, line, chpos, &line_len, cvt_ops);
|
||||
|
|
@ -481,7 +481,7 @@ static POSITION ctagsearch(void)
|
|||
* for future use by gtagsearch().
|
||||
* Sets curtag to the first tag entry.
|
||||
*/
|
||||
static enum tag_result findgtag(char *tag, int type)
|
||||
static enum tag_result findgtag(constant char *tag, int type)
|
||||
{
|
||||
char buf[1024];
|
||||
FILE *fp;
|
||||
|
|
@ -510,7 +510,7 @@ static enum tag_result findgtag(char *tag, int type)
|
|||
char *command;
|
||||
char *flag;
|
||||
char *qtag;
|
||||
char *cmd = lgetenv("LESSGLOBALTAGS");
|
||||
constant char *cmd = lgetenv("LESSGLOBALTAGS");
|
||||
|
||||
if (isnullenv(cmd))
|
||||
return TAG_NOFILE;
|
||||
|
|
@ -536,12 +536,11 @@ static enum tag_result findgtag(char *tag, int type)
|
|||
/* Get our data from global(1). */
|
||||
qtag = shell_quote(tag);
|
||||
if (qtag == NULL)
|
||||
qtag = tag;
|
||||
qtag = save(tag);
|
||||
command = (char *) ecalloc(strlen(cmd) + strlen(flag) +
|
||||
strlen(qtag) + 5, sizeof(char));
|
||||
sprintf(command, "%s -x%s %s", cmd, flag, qtag);
|
||||
if (qtag != tag)
|
||||
free(qtag);
|
||||
free(qtag);
|
||||
fp = popen(command, "r");
|
||||
free(command);
|
||||
#endif
|
||||
|
|
@ -550,8 +549,10 @@ static enum tag_result findgtag(char *tag, int type)
|
|||
{
|
||||
while (fgets(buf, sizeof(buf), fp))
|
||||
{
|
||||
char *name, *file, *line;
|
||||
int len;
|
||||
constant char *name;
|
||||
constant char *file;
|
||||
constant char *line;
|
||||
size_t len;
|
||||
|
||||
if (sigs)
|
||||
{
|
||||
|
|
@ -561,7 +562,7 @@ static enum tag_result findgtag(char *tag, int type)
|
|||
#endif
|
||||
return TAG_INTR;
|
||||
}
|
||||
len = (int) strlen(buf);
|
||||
len = strlen(buf);
|
||||
if (len > 0 && buf[len-1] == '\n')
|
||||
buf[len-1] = '\0';
|
||||
else
|
||||
|
|
@ -582,7 +583,7 @@ static enum tag_result findgtag(char *tag, int type)
|
|||
}
|
||||
|
||||
/* Make new entry and add to list. */
|
||||
tp = maketagent(name, file, (LINENUM) atoi(line), NULL, 0);
|
||||
tp = maketagent(file, (LINENUM) atoi(line), NULL, FALSE);
|
||||
TAG_INS(tp);
|
||||
total++;
|
||||
}
|
||||
|
|
@ -613,7 +614,7 @@ static int circular = 0; /* 1: circular tag structure */
|
|||
* by findgtag(). The next call to gtagsearch() will try to position at the
|
||||
* appropriate tag.
|
||||
*/
|
||||
static char * nextgtag(void)
|
||||
static constant char * nextgtag(void)
|
||||
{
|
||||
struct tag *tp;
|
||||
|
||||
|
|
@ -642,7 +643,7 @@ static char * nextgtag(void)
|
|||
* setup by findgtat(). The next call to gtagsearch() will try to position
|
||||
* at the appropriate tag.
|
||||
*/
|
||||
static char * prevgtag(void)
|
||||
static constant char * prevgtag(void)
|
||||
{
|
||||
struct tag *tp;
|
||||
|
||||
|
|
@ -688,7 +689,7 @@ static POSITION gtagsearch(void)
|
|||
* |func 21 subr.c func(arg)
|
||||
*
|
||||
* The following commands write this format.
|
||||
* o Traditinal Ctags with -x option
|
||||
* o Traditional Ctags with -x option
|
||||
* o Global with -x option
|
||||
* See <http://www.gnu.org/software/global/global.html>
|
||||
*
|
||||
|
|
@ -706,7 +707,7 @@ static POSITION gtagsearch(void)
|
|||
* The tag, file, and line will each be NUL-terminated pointers
|
||||
* into buf.
|
||||
*/
|
||||
static int getentry(char *buf, char **tag, char **file, char **line)
|
||||
static int getentry(char *buf, constant char **tag, constant char **file, constant char **line)
|
||||
{
|
||||
char *p = buf;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -23,17 +23,29 @@
|
|||
#define _WIN32_WINNT 0x400
|
||||
#endif
|
||||
#include <windows.h>
|
||||
public DWORD console_mode;
|
||||
#ifndef ENABLE_EXTENDED_FLAGS
|
||||
#define ENABLE_EXTENDED_FLAGS 0x80
|
||||
#define ENABLE_QUICK_EDIT_MODE 0x40
|
||||
#endif
|
||||
#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
|
||||
#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
|
||||
#endif
|
||||
public HANDLE tty;
|
||||
public DWORD init_console_input_mode;
|
||||
public DWORD curr_console_input_mode;
|
||||
public DWORD base_console_input_mode;
|
||||
public DWORD mouse_console_input_mode;
|
||||
#else
|
||||
public int tty;
|
||||
#endif
|
||||
extern int sigs;
|
||||
#if LESSTEST
|
||||
public char *ttyin_name = NULL;
|
||||
public lbool is_lesstest(void)
|
||||
{
|
||||
return ttyin_name != NULL;
|
||||
}
|
||||
#endif /*LESSTEST*/
|
||||
extern int sigs;
|
||||
extern int utf_mode;
|
||||
extern int wheel_lines;
|
||||
|
||||
#if !MSDOS_COMPILER
|
||||
static int open_tty_device(constant char* dev)
|
||||
|
|
@ -56,7 +68,7 @@ public int open_tty(void)
|
|||
{
|
||||
int fd = -1;
|
||||
#if LESSTEST
|
||||
if (ttyin_name != NULL)
|
||||
if (is_lesstest())
|
||||
fd = open_tty_device(ttyin_name);
|
||||
#endif /*LESSTEST*/
|
||||
#if HAVE_TTYNAME
|
||||
|
|
@ -71,6 +83,10 @@ public int open_tty(void)
|
|||
fd = open_tty_device("/dev/tty");
|
||||
if (fd < 0)
|
||||
fd = 2;
|
||||
#ifdef __MVS__
|
||||
struct f_cnvrt cvtreq = {SETCVTON, 0, 1047};
|
||||
fcntl(fd, F_CONTROL_CVT, &cvtreq);
|
||||
#endif
|
||||
return fd;
|
||||
}
|
||||
#endif /* MSDOS_COMPILER */
|
||||
|
|
@ -89,9 +105,14 @@ public void open_getchr(void)
|
|||
tty = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ, &sa,
|
||||
OPEN_EXISTING, 0L, NULL);
|
||||
GetConsoleMode(tty, &console_mode);
|
||||
/* Make sure we get Ctrl+C events. */
|
||||
SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
|
||||
GetConsoleMode(tty, &init_console_input_mode);
|
||||
/* base mode: ensure we get ctrl-C events, and don't get VT input. */
|
||||
base_console_input_mode = (init_console_input_mode | ENABLE_PROCESSED_INPUT) & ~ENABLE_VIRTUAL_TERMINAL_INPUT;
|
||||
/* mouse mode: enable mouse and disable quick edit. */
|
||||
mouse_console_input_mode = (base_console_input_mode | ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS) & ~ENABLE_QUICK_EDIT_MODE;
|
||||
/* Start with base mode. If --mouse is given, switch to mouse mode in init_mouse. */
|
||||
curr_console_input_mode = base_console_input_mode;
|
||||
SetConsoleMode(tty, curr_console_input_mode);
|
||||
#else
|
||||
#if MSDOS_COMPILER
|
||||
extern int fd0;
|
||||
|
|
@ -121,21 +142,21 @@ public void open_getchr(void)
|
|||
public void close_getchr(void)
|
||||
{
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
SetConsoleMode(tty, console_mode);
|
||||
SetConsoleMode(tty, init_console_input_mode);
|
||||
CloseHandle(tty);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
/*
|
||||
* Close the pipe, restoring the keyboard (CMD resets it, losing the mouse).
|
||||
* Close the pipe, restoring the console mode (CMD resets it, losing the mouse).
|
||||
*/
|
||||
public int pclose(FILE *f)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = _pclose(f);
|
||||
SetConsoleMode(tty, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
|
||||
SetConsoleMode(tty, curr_console_input_mode);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
|
@ -162,7 +183,7 @@ public int default_wheel_lines(void)
|
|||
public int getchr(void)
|
||||
{
|
||||
char c;
|
||||
int result;
|
||||
ssize_t result;
|
||||
|
||||
do
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Generated by "./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt" on Mon Nov 14 18:19:24 PST 2022 */
|
||||
/* Generated by "./mkutable -f2 Cc Cs Co Zl Zp -- unicode/UnicodeData.txt" on Sun Sep 17 17:56:27 PDT 2023 */
|
||||
{ 0x0000, 0x0007 }, /* Cc */
|
||||
{ 0x000b, 0x000b }, /* Cc */
|
||||
{ 0x000e, 0x001f }, /* Cc */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 1984-2023 Mark Nudelman
|
||||
* Copyright (C) 1984-2024 Mark Nudelman
|
||||
*
|
||||
* You may distribute under the terms of either the GNU General Public
|
||||
* License or the Less License, as specified in the README file.
|
||||
|
|
@ -40,7 +40,7 @@ v19 5/2/85 Got rid of "verbose" eq_message().
|
|||
v20 5/21/85 Fixed screen.c ioctls for System V.
|
||||
v21 5/23/85 Fixed some first_cmd bugs.
|
||||
v22 5/24/85 Added support for no RECOMP nor REGCMP.
|
||||
v23 5/25/85 Miscellanous changes and prettying up.
|
||||
v23 5/25/85 Miscellaneous changes and prettying up.
|
||||
Posted to USENET.
|
||||
-----------------------------------------------------------------
|
||||
v24 6/3/85 Added ti,te terminal init & de-init.
|
||||
|
|
@ -628,7 +628,7 @@ v373 1/14/02 Improve handling of filenames containing shell metachars.
|
|||
v374 2/7/02 Fix memory leak; fix bug in -x argument parsing.
|
||||
v375 4/7/02 Fix searching for SGR sequences; fix SECURE build;
|
||||
add SGR support to DJGPP version (thanks to Eli Zaretskii).
|
||||
v376 6/10/02 Fix bug in overstriking mulitbyte UTF-8 characters
|
||||
v376 6/10/02 Fix bug in overstriking multibyte UTF-8 characters
|
||||
(thanks to Jungshik Shin).
|
||||
Posted to Web page.
|
||||
-----------------------------------------------------------------
|
||||
|
|
@ -993,6 +993,45 @@ v640 7/10/23 Add lesstest to release.
|
|||
v641 7/10/23 Fix release.
|
||||
v642 7/10/23 Fix release.
|
||||
v643 7/20/23 Fix crash on Windows with -o.
|
||||
v644 9/16/23 Improve ^C on non-terminated pipe; fix crash when files are
|
||||
deleted; support large files and non-BMP chars on Windows;
|
||||
fix # bug; don't filter header lines; fix shifting long lines;
|
||||
add --match-shift.
|
||||
v645 11/5/23 Default Windows charset is utf-8; update Unicode tables;
|
||||
fix ESC-} bug; mouse right-click jumps to '#';
|
||||
add LESSSECURE_ALLOW; add --lesskey-content & LESSKEY_CONTENT;
|
||||
allow env var expansion in lesskey files; add LESS_UNSUPPORT.
|
||||
v646 11/6/23 Bug fixes.
|
||||
v647 11/16/23 Fix --+option; fix compiler warnings.
|
||||
v648 11/16/23 Add lang.h to release.
|
||||
v649 12/1/23 Add line number param to --header.
|
||||
v650 2/6/24 Add --no-search-header-lines and --no-search-header-columns;
|
||||
add ^L search modifier; add ^P shell command modifier;
|
||||
add search wrap message; add ^O^N, ^O^P, ^O^L and ^O^O commands.
|
||||
v651 3/4/24 Add --color attributes (*~_&); fix #/% substitution if name
|
||||
contains spaces; allow --rscroll with non-ASCII char.
|
||||
v652 3/11/24 Fix sleep_ms with usleep.
|
||||
v653 3/20/24 Make default charset utf-8.
|
||||
v654 4/28/24 Allow space to end parameter for some options; fix usleep bug;
|
||||
fix bugs when filename contains control chars; fix DJGPP build.
|
||||
v655 5/16/24 Fix search history bug with --incsearch.
|
||||
v656 5/23/24 Fix bug using escape sequences in prompt.
|
||||
v657 5/31/24 Fix buffer overrun when using LESSOPEN.
|
||||
v658 6/13/24 Fix double-free in lesskey parser; fix crash using small value
|
||||
for --line-num-width.
|
||||
v659 6/20/24 Fix typo in help.
|
||||
v660 6/24/24 Fix bug in ixerror.
|
||||
v661 6/29/24 Simpler fix for ixerror bug.
|
||||
v662 8/8/24 Fix build with --with-secure; improve true colors on Windows;
|
||||
fix crash with --header; fix crash with -S; fix #stop;
|
||||
fix --shift with fractional parameter; fix EOF bug in R command;
|
||||
fix --header with short file; fix ^X bug when output is not tty.
|
||||
v663 8/16/24 Fix ^X bug when output is not a tty.
|
||||
v664 8/28/24 Fix Windows compile error, fix output bug on Windows with -Da.
|
||||
v665 9/4/24 Fix ^Z bug.
|
||||
v666 9/21/24 Fix missing first byte from LESSOPEN if >0x7f.
|
||||
v667 9/26/24 Fix uninitialized variable in edit_ifile.
|
||||
v668 10/6/24 Fix UTF-8 chars in prompt.
|
||||
*/
|
||||
|
||||
char version[] = "643";
|
||||
char version[] = "668";
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Mon Nov 14 18:19:24 PST 2022 */
|
||||
/* Generated by "./mkutable -f1 W F -- unicode/EastAsianWidth.txt" on Sun Sep 17 17:56:27 PDT 2023 */
|
||||
{ 0x1100, 0x115f }, /* W */
|
||||
{ 0x231a, 0x231b }, /* W */
|
||||
{ 0x2329, 0x232a }, /* W */
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
{ 0x2e80, 0x2e99 }, /* W */
|
||||
{ 0x2e9b, 0x2ef3 }, /* W */
|
||||
{ 0x2f00, 0x2fd5 }, /* W */
|
||||
{ 0x2ff0, 0x2ffb }, /* W */
|
||||
{ 0x2ff0, 0x2fff }, /* W */
|
||||
{ 0x3000, 0x3000 }, /* F */
|
||||
{ 0x3001, 0x303e }, /* W */
|
||||
{ 0x3041, 0x3096 }, /* W */
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
{ 0x3105, 0x312f }, /* W */
|
||||
{ 0x3131, 0x318e }, /* W */
|
||||
{ 0x3190, 0x31e3 }, /* W */
|
||||
{ 0x31f0, 0x321e }, /* W */
|
||||
{ 0x31ef, 0x321e }, /* W */
|
||||
{ 0x3220, 0x3247 }, /* W */
|
||||
{ 0x3250, 0x4dbf }, /* W */
|
||||
{ 0x4e00, 0xa48c }, /* W */
|
||||
|
|
|
|||
|
|
@ -6,10 +6,19 @@
|
|||
*/
|
||||
public void xbuf_init(struct xbuffer *xbuf)
|
||||
{
|
||||
xbuf->data = NULL;
|
||||
xbuf->size = xbuf->end = 0;
|
||||
xbuf_init_size(xbuf, 16);
|
||||
}
|
||||
|
||||
public void xbuf_init_size(struct xbuffer *xbuf, size_t init_size)
|
||||
{
|
||||
xbuf->data = NULL;
|
||||
xbuf->size = xbuf->end = 0;
|
||||
xbuf->init_size = init_size;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free buffer space in an xbuf.
|
||||
*/
|
||||
public void xbuf_deinit(struct xbuffer *xbuf)
|
||||
{
|
||||
if (xbuf->data != NULL)
|
||||
|
|
@ -17,20 +26,23 @@ public void xbuf_deinit(struct xbuffer *xbuf)
|
|||
xbuf_init(xbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set xbuf to empty.
|
||||
*/
|
||||
public void xbuf_reset(struct xbuffer *xbuf)
|
||||
{
|
||||
xbuf->end = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a byte to an expandable text buffer.
|
||||
* Add a byte to an xbuf.
|
||||
*/
|
||||
public void xbuf_add_byte(struct xbuffer *xbuf, unsigned char b)
|
||||
{
|
||||
if (xbuf->end >= xbuf->size)
|
||||
{
|
||||
unsigned char *data;
|
||||
if (ckd_add(&xbuf->size, xbuf->size, xbuf->size ? xbuf->size : 16))
|
||||
if (ckd_add(&xbuf->size, xbuf->size, xbuf->size ? xbuf->size : xbuf->init_size))
|
||||
out_of_memory();
|
||||
data = (unsigned char *) ecalloc(xbuf->size, sizeof(unsigned char));
|
||||
if (xbuf->data != NULL)
|
||||
|
|
@ -40,16 +52,30 @@ public void xbuf_add_byte(struct xbuffer *xbuf, unsigned char b)
|
|||
}
|
||||
xbuf->data = data;
|
||||
}
|
||||
xbuf->data[xbuf->end++] = (unsigned char) b;
|
||||
xbuf->data[xbuf->end++] = b;
|
||||
}
|
||||
|
||||
public void xbuf_add_data(struct xbuffer *xbuf, unsigned char *data, int len)
|
||||
/*
|
||||
* Add a char to an xbuf.
|
||||
*/
|
||||
public void xbuf_add_char(struct xbuffer *xbuf, char c)
|
||||
{
|
||||
int i;
|
||||
xbuf_add_byte(xbuf, (unsigned char) c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add arbitrary data to an xbuf.
|
||||
*/
|
||||
public void xbuf_add_data(struct xbuffer *xbuf, constant unsigned char *data, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < len; i++)
|
||||
xbuf_add_byte(xbuf, data[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the last byte from an xbuf.
|
||||
*/
|
||||
public int xbuf_pop(struct xbuffer *buf)
|
||||
{
|
||||
if (buf->end == 0)
|
||||
|
|
@ -57,15 +83,21 @@ public int xbuf_pop(struct xbuffer *buf)
|
|||
return (int) buf->data[--(buf->end)];
|
||||
}
|
||||
|
||||
/*
|
||||
* Set an xbuf to the contents of another xbuf.
|
||||
*/
|
||||
public void xbuf_set(struct xbuffer *dst, struct xbuffer *src)
|
||||
{
|
||||
xbuf_reset(dst);
|
||||
xbuf_add_data(dst, src->data, src->end);
|
||||
}
|
||||
|
||||
public char * xbuf_char_data(struct xbuffer *xbuf)
|
||||
/*
|
||||
* Return xbuf data as a char*.
|
||||
*/
|
||||
public constant char * xbuf_char_data(constant struct xbuffer *xbuf)
|
||||
{
|
||||
return (char *)(xbuf->data);
|
||||
return (constant char *)(xbuf->data);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -84,7 +116,7 @@ public char * xbuf_char_data(struct xbuffer *xbuf)
|
|||
* 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)
|
||||
static lbool help_fixup(void *r, uintmax val, int rsize, int rsigned)
|
||||
{
|
||||
if (rsigned)
|
||||
{
|
||||
|
|
@ -100,14 +132,14 @@ static int help_fixup(void *r, uintmax val, int rsize, int rsigned)
|
|||
long long *pr = r;
|
||||
if (LLONG_MAX < val)
|
||||
return TRUE;
|
||||
*pr = val;
|
||||
*pr = (long long) val;
|
||||
#endif
|
||||
#ifdef INTMAX_MAX
|
||||
} else if (rsize == sizeof (intmax_t)) {
|
||||
intmax_t *pr = r;
|
||||
if (INTMAX_MAX < val)
|
||||
return TRUE;
|
||||
*pr = val;
|
||||
*pr = (intmax_t) val;
|
||||
#endif
|
||||
} else /* rsize == sizeof (long) */
|
||||
{
|
||||
|
|
@ -129,32 +161,34 @@ static int help_fixup(void *r, uintmax val, int rsize, int rsigned)
|
|||
*pr = (unsigned long) val;
|
||||
#ifdef ULLONG_MAX
|
||||
} else if (rsize == sizeof (unsigned long long)) {
|
||||
long long *pr = r;
|
||||
unsigned long long *pr = r;
|
||||
if (ULLONG_MAX < val)
|
||||
return TRUE;
|
||||
*pr = val;
|
||||
*pr = (unsigned long long) val;
|
||||
#endif
|
||||
} else /* rsize == sizeof (uintmax) */
|
||||
{
|
||||
uintmax *pr = r;
|
||||
*pr = val;
|
||||
*pr = (uintmax) 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)
|
||||
public lbool 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)
|
||||
public lbool help_ckd_mul(void *r, uintmax a, uintmax b, int rsize, int rsigned)
|
||||
{
|
||||
uintmax product = a * b;
|
||||
return ((b != 0 && a != product / b)
|
||||
|
|
|
|||
|
|
@ -1,19 +1,24 @@
|
|||
#ifndef XBUF_H_
|
||||
#define XBUF_H_
|
||||
|
||||
#include "lang.h"
|
||||
|
||||
struct xbuffer
|
||||
{
|
||||
unsigned char *data;
|
||||
int end;
|
||||
int size;
|
||||
size_t end;
|
||||
size_t size;
|
||||
size_t init_size;
|
||||
};
|
||||
|
||||
void xbuf_init(struct xbuffer *xbuf);
|
||||
void xbuf_init_size(struct xbuffer *xbuf, size_t init_size);
|
||||
void xbuf_deinit(struct xbuffer *xbuf);
|
||||
void xbuf_reset(struct xbuffer *xbuf);
|
||||
void xbuf_add_byte(struct xbuffer *xbuf, unsigned char b);
|
||||
void xbuf_add_data(struct xbuffer *xbuf, unsigned char *data, int len);
|
||||
void xbuf_add_char(struct xbuffer *xbuf, char c);
|
||||
void xbuf_add_data(struct xbuffer *xbuf, constant unsigned char *data, size_t len);
|
||||
int xbuf_pop(struct xbuffer *xbuf);
|
||||
char *xbuf_char_data(struct xbuffer *xbuf);
|
||||
constant char *xbuf_char_data(constant struct xbuffer *xbuf);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
PACKAGE= runtime
|
||||
PROG= less
|
||||
SRCS= main.c screen.c brac.c ch.c charset.c cmdbuf.c command.c cvt.c \
|
||||
decode.c edit.c filename.c forwback.c help.c ifile.c input.c \
|
||||
decode.c evar.c edit.c filename.c forwback.c help.c ifile.c input.c \
|
||||
jump.c lesskey_parse.c \
|
||||
line.c linenum.c lsystem.c mark.c optfunc.c option.c \
|
||||
opttbl.c os.c output.c pattern.c position.c prompt.c search.c \
|
||||
|
|
|
|||
|
|
@ -88,6 +88,12 @@
|
|||
*/
|
||||
#define LOGFILE (!SECURE)
|
||||
|
||||
/*
|
||||
* OSC8_SEARCH is 1 if you wish to allow the ^O^O and related commands
|
||||
* (to open OSC8 hyperlinks).
|
||||
*/
|
||||
#define OSC8_LINK 1
|
||||
|
||||
/*
|
||||
* GNU_OPTIONS is 1 if you wish to support the GNU-style command
|
||||
* line options --help and --version.
|
||||
|
|
@ -138,7 +144,7 @@
|
|||
/*
|
||||
* HAVE_ANSI_PROTOS is 1 if your compiler supports ANSI function prototypes.
|
||||
*/
|
||||
#define HAVE_ANSI_PROTOS 1
|
||||
#define HAVE_ANSI_PROTOS 1
|
||||
|
||||
/*
|
||||
* HAVE_SYS_TYPES_H is 1 if your system has <sys/types.h>.
|
||||
|
|
@ -235,7 +241,7 @@
|
|||
/* Define to 1 if you have the <errno.h> header file. */
|
||||
#define HAVE_ERRNO_H 1
|
||||
|
||||
/* Define to 1 if you have the `fchmod' function. */
|
||||
/* Define to 1 if you have the 'fchmod' function. */
|
||||
#define HAVE_FCHMOD 1
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
|
|
@ -244,7 +250,7 @@
|
|||
/* Define HAVE_FILENO if you have the fileno() macro. */
|
||||
#define HAVE_FILENO 1
|
||||
|
||||
/* Define to 1 if you have the `fsync' function. */
|
||||
/* Define to 1 if you have the 'fsync' function. */
|
||||
#define HAVE_FSYNC 1
|
||||
|
||||
/* GNU regex library */
|
||||
|
|
@ -262,7 +268,7 @@
|
|||
/* Define HAVE_LOCALE if you have locale.h and setlocale. */
|
||||
#define HAVE_LOCALE 1
|
||||
|
||||
/* Define to 1 if you have the `nanosleep' function. */
|
||||
/* Define to 1 if you have the 'nanosleep' function. */
|
||||
#define HAVE_NANOSLEEP 1
|
||||
|
||||
/* Define to 1 if you have the <ncursesw/termcap.h> header file. */
|
||||
|
|
@ -280,20 +286,16 @@
|
|||
/* PCRE2 (Perl-compatible regular expression) library */
|
||||
/* #undef HAVE_PCRE2 */
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
/* Define to 1 if you have the 'poll' function. */
|
||||
#define HAVE_POLL 1
|
||||
|
||||
/* Define to 1 if you have the `popen' function. */
|
||||
/* Define to 1 if you have the 'popen' function. */
|
||||
#define HAVE_POPEN 1
|
||||
|
||||
/* POSIX regcomp() and regex.h */
|
||||
#define HAVE_POSIX_REGCOMP 1
|
||||
|
||||
/* Define HAVE_PROCFS if have have fstatfs with f_type and PROC_SUPER_MAGIC.
|
||||
*/
|
||||
/* #undef HAVE_PROCFS */
|
||||
|
||||
/* Define to 1 if you have the `realpath' function. */
|
||||
/* Define to 1 if you have the 'realpath' function. */
|
||||
#define HAVE_REALPATH 1
|
||||
|
||||
/* System V regcmp() */
|
||||
|
|
@ -308,19 +310,19 @@
|
|||
/* Define HAVE_SIGEMPTYSET if you have the sigemptyset macro. */
|
||||
#define HAVE_SIGEMPTYSET 1
|
||||
|
||||
/* Define to 1 if you have the `sigprocmask' function. */
|
||||
/* Define to 1 if you have the 'sigprocmask' function. */
|
||||
#define HAVE_SIGPROCMASK 1
|
||||
|
||||
/* Define to 1 if you have the `sigsetmask' function. */
|
||||
/* Define to 1 if you have the 'sigsetmask' function. */
|
||||
#define HAVE_SIGSETMASK 1
|
||||
|
||||
/* Define to 1 if the system has the type `sigset_t'. */
|
||||
/* Define to 1 if the system has the type 'sigset_t'. */
|
||||
#define HAVE_SIGSET_T 1
|
||||
|
||||
/* Define to 1 if you have the `snprintf' function. */
|
||||
/* Define to 1 if you have the 'snprintf' function. */
|
||||
#define HAVE_SNPRINTF 1
|
||||
|
||||
/* Define to 1 if you have the `stat' function. */
|
||||
/* Define to 1 if you have the 'stat' function. */
|
||||
#define HAVE_STAT 1
|
||||
|
||||
/* Define HAVE_STAT_INO if your struct stat has st_ino and st_dev. */
|
||||
|
|
@ -347,10 +349,10 @@
|
|||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the `strsignal' function. */
|
||||
/* 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_SYS_ERRLIST if you have the sys_errlist[] variable. */
|
||||
|
|
@ -389,7 +391,7 @@
|
|||
/* Define HAVE_TIME_T if your system supports the "time_t" type. */
|
||||
#define HAVE_TIME_T 1
|
||||
|
||||
/* Define to 1 if you have the `ttyname' function. */
|
||||
/* Define to 1 if you have the 'ttyname' function. */
|
||||
#define HAVE_TTYNAME 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
|
|
@ -398,7 +400,7 @@
|
|||
/* Define HAVE_UPPER_LOWER if you have isupper, islower, toupper, tolower. */
|
||||
#define HAVE_UPPER_LOWER 1
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
/* Define to 1 if you have the 'usleep' function. */
|
||||
#define HAVE_USLEEP 1
|
||||
|
||||
/* Henry Spencer V8 regcomp() and regexp.h */
|
||||
|
|
@ -416,7 +418,7 @@
|
|||
/* Define to 1 if you have the <wctype.h> header file. */
|
||||
#define HAVE_WCTYPE_H 1
|
||||
|
||||
/* Define to 1 if you have the `_setjmp' function. */
|
||||
/* Define to 1 if you have the '_setjmp' function. */
|
||||
#define HAVE__SETJMP 1
|
||||
|
||||
/* Define MUST_DEFINE_ERRNO if you have errno but it is not define in errno.h.
|
||||
|
|
@ -451,10 +453,10 @@
|
|||
/* Define SECURE_COMPILE=1 to build a secure version of less. */
|
||||
#define SECURE_COMPILE 0
|
||||
|
||||
/* Define to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
/* Define to 1 if the 'S_IS*' macros in <sys/stat.h> do not work properly. */
|
||||
/* #undef STAT_MACROS_BROKEN */
|
||||
|
||||
/* Define to 1 if all of the C90 standard headers exist (not just the ones
|
||||
/* Define to 1 if all of the C89 standard headers exist (not just the ones
|
||||
required in a freestanding environment). This macro is provided for
|
||||
backward compatibility; new code need not use it. */
|
||||
#define STDC_HEADERS 1
|
||||
|
|
@ -462,14 +464,20 @@
|
|||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
/* #undef _FILE_OFFSET_BITS */
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
/* Define to 1 on platforms where this makes off_t a 64-bit type. */
|
||||
/* #undef _LARGE_FILES */
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* Number of bits in time_t, on hosts where this is settable. */
|
||||
/* #undef _TIME_BITS */
|
||||
|
||||
/* Define to 1 on platforms where this makes time_t a 64-bit type. */
|
||||
/* #undef __MINGW_USE_VC2005_COMPAT */
|
||||
|
||||
/* Define to empty if 'const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define to `long int' if <sys/types.h> does not define. */
|
||||
/* Define to 'long int' if <sys/types.h> does not define. */
|
||||
/* #undef off_t */
|
||||
|
||||
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||
/* Define as 'unsigned int' if <stddef.h> doesn't define. */
|
||||
/* #undef size_t */
|
||||
|
|
|
|||
Loading…
Reference in a new issue