less: upgrade to v590.
MFC after: 2 weeks
This commit is contained in:
commit
30a1828c51
@ -3,8 +3,7 @@
|
||||
|
||||
======================================================================
|
||||
|
||||
For the latest news about less, see the "less" Web page:
|
||||
https://greenwoodsoftware.com/less
|
||||
For the latest news about less, see https://greenwoodsoftware.com/less
|
||||
You can also download the latest version of less from there.
|
||||
|
||||
Report bugs, suggestions or comments at
|
||||
@ -12,7 +11,32 @@
|
||||
|
||||
======================================================================
|
||||
|
||||
Major changes between "less" versions 563 and 581.2
|
||||
Major changes between "less" versions 581 and 590
|
||||
|
||||
* Make less able to read lesskey source files (deprecating lesskey).
|
||||
|
||||
* If XDG_CONFIG_HOME is set, find lesskey source file
|
||||
in $XDG_CONFIG_HOME/lesskey rather than $HOME/.lesskey.
|
||||
|
||||
* If XDG_DATA_HOME is set, find and store history file
|
||||
in $XDG_DATA_HOME/lesshst rather than $HOME/.lesshst.
|
||||
|
||||
* Add the --lesskey-src option.
|
||||
|
||||
* Add the --file-size option.
|
||||
|
||||
* With -F, if screen is resized to make file fit on one screen, don't exit.
|
||||
|
||||
* Fix bug which could leave terminal in mouse-reporting mode
|
||||
after exiting less.
|
||||
|
||||
* Fix bug which caused failure to respond to window resize.
|
||||
|
||||
* Fix backslash bug searching in tag file.
|
||||
|
||||
======================================================================
|
||||
|
||||
Major changes between "less" versions 563 and 581
|
||||
|
||||
* Change ESC-u command to toggle, not disable, highlighting per man page.
|
||||
|
||||
|
@ -7,9 +7,7 @@
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
|
||||
Less, version 581.2
|
||||
|
||||
This is the distribution of less, version 581.2, released 28 Apr 2021.
|
||||
This is the source code distribution of "less".
|
||||
This program is part of the GNU project (http://www.gnu.org).
|
||||
|
||||
This program is free software. You may redistribute it and/or
|
||||
@ -27,6 +25,11 @@
|
||||
|
||||
=========================================================================
|
||||
|
||||
You should build from a clone of a git repository
|
||||
ONLY IF you are doing development on the less source itself.
|
||||
If you are merely using less as a tool, you should download a release
|
||||
from http://greenwoodsoftware.com and NOT from github.
|
||||
|
||||
The formatted manual page is in less.man.
|
||||
The manual page nroff source is in less.nro.
|
||||
Major changes made since the last posted version are in NEWS.
|
||||
|
@ -860,7 +860,7 @@ ch_init(f, flags)
|
||||
* Allocate and initialize a new filestate.
|
||||
*/
|
||||
thisfile = (struct filestate *)
|
||||
calloc(1, sizeof(struct filestate));
|
||||
ecalloc(1, sizeof(struct filestate));
|
||||
thisfile->buflist.next = thisfile->buflist.prev = END_OF_CHAIN;
|
||||
thisfile->nbufs = 0;
|
||||
thisfile->flags = flags;
|
||||
|
@ -1401,11 +1401,12 @@ mlist_size(ml)
|
||||
* Get the name of the history file.
|
||||
*/
|
||||
static char *
|
||||
histfile_name(VOID_PARAM)
|
||||
histfile_name(must_exist)
|
||||
int must_exist;
|
||||
{
|
||||
char *home;
|
||||
char *xdg;
|
||||
char *name;
|
||||
int len;
|
||||
|
||||
/* See if filename is explicitly specified by $LESSHISTFILE. */
|
||||
name = lgetenv("LESSHISTFILE");
|
||||
@ -1421,19 +1422,25 @@ histfile_name(VOID_PARAM)
|
||||
if (strcmp(LESSHISTFILE, "") == 0 || strcmp(LESSHISTFILE, "-") == 0)
|
||||
return (NULL);
|
||||
|
||||
/* Otherwise, file is in $HOME. */
|
||||
/* Try in $XDG_DATA_HOME first, then in $HOME. */
|
||||
xdg = lgetenv("XDG_DATA_HOME");
|
||||
home = lgetenv("HOME");
|
||||
if (isnullenv(home))
|
||||
{
|
||||
#if OS2
|
||||
if (isnullenv(home))
|
||||
home = lgetenv("INIT");
|
||||
if (isnullenv(home))
|
||||
#endif
|
||||
return (NULL);
|
||||
name = NULL;
|
||||
if (!must_exist)
|
||||
{
|
||||
/* If we're writing the file and the file already exists, use it. */
|
||||
name = dirfile(xdg, &LESSHISTFILE[1], 1);
|
||||
if (name == NULL)
|
||||
name = dirfile(home, LESSHISTFILE, 1);
|
||||
}
|
||||
len = (int) (strlen(home) + strlen(LESSHISTFILE) + 2);
|
||||
name = (char *) ecalloc(len, sizeof(char));
|
||||
SNPRINTF2(name, len, "%s/%s", home, LESSHISTFILE);
|
||||
if (name == NULL)
|
||||
name = dirfile(xdg, &LESSHISTFILE[1], must_exist);
|
||||
if (name == NULL)
|
||||
name = dirfile(home, LESSHISTFILE, must_exist);
|
||||
return (name);
|
||||
}
|
||||
|
||||
@ -1454,7 +1461,7 @@ read_cmdhist2(action, uparam, skip_search, skip_shell)
|
||||
char *p;
|
||||
int *skip = NULL;
|
||||
|
||||
filename = histfile_name();
|
||||
filename = histfile_name(1);
|
||||
if (filename == NULL)
|
||||
return;
|
||||
f = fopen(filename, "r");
|
||||
@ -1700,7 +1707,7 @@ save_cmdhist(VOID_PARAM)
|
||||
|
||||
if (!histfile_modified())
|
||||
return;
|
||||
histname = histfile_name();
|
||||
histname = histfile_name(0);
|
||||
if (histname == NULL)
|
||||
return;
|
||||
tempname = make_tempname(histname);
|
||||
|
@ -797,6 +797,7 @@ prompt(VOID_PARAM)
|
||||
entire_file_displayed() && !(ch_getflags() & CH_HELPFILE) &&
|
||||
next_ifile(curr_ifile) == NULL_IFILE)
|
||||
quit(QUIT_OK);
|
||||
quit_if_one_screen = FALSE; /* only get one chance at this */
|
||||
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
/*
|
||||
|
@ -339,21 +339,41 @@ init_cmds(VOID_PARAM)
|
||||
add_fcmd_table((char*)cmdtable, sizeof(cmdtable));
|
||||
add_ecmd_table((char*)edittable, sizeof(edittable));
|
||||
#if USERFILE
|
||||
/*
|
||||
* For backwards compatibility,
|
||||
* try to add tables in the OLD system lesskey file.
|
||||
*/
|
||||
#ifdef BINDIR
|
||||
add_hometable(NULL, BINDIR "/.sysless", 1);
|
||||
#ifdef BINDIR /* For backwards compatibility */
|
||||
/* Try to add tables in the OLD system lesskey file. */
|
||||
add_hometable(lesskey, NULL, BINDIR "/.sysless", 1);
|
||||
#endif
|
||||
/*
|
||||
* Try to add the tables in the system lesskey file.
|
||||
* Try to load lesskey source file or binary file.
|
||||
* If the source file succeeds, don't load binary file.
|
||||
* The binary file is likely to have been generated from
|
||||
* a (possibly out of date) copy of the src file,
|
||||
* so loading it is at best redundant.
|
||||
*/
|
||||
add_hometable("LESSKEY_SYSTEM", LESSKEYFILE_SYS, 1);
|
||||
/*
|
||||
* Try to add the tables in the standard lesskey file "$HOME/.less".
|
||||
* Try to add tables in system lesskey src file.
|
||||
*/
|
||||
add_hometable("LESSKEY", LESSKEYFILE, 0);
|
||||
#if HAVE_LESSKEYSRC
|
||||
if (add_hometable(lesskey_src, "LESSKEYIN_SYSTEM", LESSKEYINFILE_SYS, 1) != 0)
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* Try to add the tables in the system lesskey binary file.
|
||||
*/
|
||||
add_hometable(lesskey, "LESSKEY_SYSTEM", LESSKEYFILE_SYS, 1);
|
||||
}
|
||||
/*
|
||||
* Try to add tables in the lesskey src file "$HOME/.lesskey".
|
||||
*/
|
||||
#if HAVE_LESSKEYSRC
|
||||
if (add_hometable(lesskey_src, "LESSKEYIN", DEF_LESSKEYINFILE, 0) != 0)
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* Try to add the tables in the standard lesskey binary file "$HOME/.less".
|
||||
*/
|
||||
add_hometable(lesskey, "LESSKEY", LESSKEYFILE, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -877,32 +897,63 @@ lesskey(filename, sysvar)
|
||||
return (new_lesskey(buf, (int)len, sysvar));
|
||||
}
|
||||
|
||||
#if HAVE_LESSKEYSRC
|
||||
public int
|
||||
lesskey_src(filename, sysvar)
|
||||
char *filename;
|
||||
int sysvar;
|
||||
{
|
||||
static struct lesskey_tables tables;
|
||||
int r = parse_lesskey(filename, &tables);
|
||||
if (r != 0)
|
||||
return (r);
|
||||
add_fcmd_table(tables.cmdtable.buf.data, tables.cmdtable.buf.end);
|
||||
add_ecmd_table(tables.edittable.buf.data, tables.edittable.buf.end);
|
||||
add_var_table(sysvar ? &list_sysvar_tables : &list_var_tables,
|
||||
tables.vartable.buf.data, tables.vartable.buf.end);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
lesskey_parse_error(s)
|
||||
char *s;
|
||||
{
|
||||
PARG parg;
|
||||
parg.p_string = s;
|
||||
error("%s", &parg);
|
||||
}
|
||||
#endif /* HAVE_LESSKEYSRC */
|
||||
|
||||
/*
|
||||
* Add the standard lesskey file "$HOME/.less"
|
||||
* Add a lesskey file.
|
||||
*/
|
||||
public void
|
||||
add_hometable(envname, def_filename, sysvar)
|
||||
public int
|
||||
add_hometable(call_lesskey, envname, def_filename, sysvar)
|
||||
int (*call_lesskey)(char *, int);
|
||||
char *envname;
|
||||
char *def_filename;
|
||||
int sysvar;
|
||||
{
|
||||
char *filename;
|
||||
PARG parg;
|
||||
int r;
|
||||
|
||||
if (envname != NULL && (filename = lgetenv(envname)) != NULL)
|
||||
filename = save(filename);
|
||||
else if (sysvar)
|
||||
else if (sysvar) /* def_filename is full path */
|
||||
filename = save(def_filename);
|
||||
else
|
||||
filename = homefile(def_filename);
|
||||
if (filename == NULL)
|
||||
return;
|
||||
if (lesskey(filename, sysvar) < 0)
|
||||
else /* def_filename is just basename */
|
||||
{
|
||||
parg.p_string = filename;
|
||||
error("Cannot use lesskey file \"%s\"", &parg);
|
||||
char *xdg = lgetenv("XDG_CONFIG_HOME");
|
||||
if (!isnullenv(xdg))
|
||||
filename = dirfile(xdg, def_filename+1, 1);
|
||||
if (filename == NULL)
|
||||
filename = homefile(def_filename);
|
||||
}
|
||||
if (filename == NULL)
|
||||
return -1;
|
||||
r = (*call_lesskey)(filename, sysvar);
|
||||
free(filename);
|
||||
return (r);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -26,6 +26,7 @@ extern int force_open;
|
||||
extern int is_tty;
|
||||
extern int sigs;
|
||||
extern int hshift;
|
||||
extern int want_filesize;
|
||||
extern IFILE curr_ifile;
|
||||
extern IFILE old_ifile;
|
||||
extern struct scrpos initial_scrpos;
|
||||
@ -487,7 +488,8 @@ edit_ifile(ifile)
|
||||
cmd_addhist(ml_examine, qfilename, 1);
|
||||
free(qfilename);
|
||||
}
|
||||
|
||||
if (want_filesize)
|
||||
scan_eof();
|
||||
}
|
||||
free(filename);
|
||||
return (0);
|
||||
|
@ -216,10 +216,11 @@ shell_quote(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.
|
||||
*/
|
||||
static char *
|
||||
dirfile(dirname, filename)
|
||||
public char *
|
||||
dirfile(dirname, filename, must_exist)
|
||||
char *dirname;
|
||||
char *filename;
|
||||
int must_exist;
|
||||
{
|
||||
char *pathname;
|
||||
int len;
|
||||
@ -235,17 +236,20 @@ dirfile(dirname, filename)
|
||||
if (pathname == NULL)
|
||||
return (NULL);
|
||||
SNPRINTF3(pathname, len, "%s%s%s", dirname, PATHNAME_SEP, filename);
|
||||
/*
|
||||
* Make sure the file exists.
|
||||
*/
|
||||
f = open(pathname, OPEN_READ);
|
||||
if (f < 0)
|
||||
if (must_exist)
|
||||
{
|
||||
free(pathname);
|
||||
pathname = NULL;
|
||||
} else
|
||||
{
|
||||
close(f);
|
||||
/*
|
||||
* Make sure the file exists.
|
||||
*/
|
||||
f = open(pathname, OPEN_READ);
|
||||
if (f < 0)
|
||||
{
|
||||
free(pathname);
|
||||
pathname = NULL;
|
||||
} else
|
||||
{
|
||||
close(f);
|
||||
}
|
||||
}
|
||||
return (pathname);
|
||||
}
|
||||
@ -259,25 +263,19 @@ homefile(filename)
|
||||
{
|
||||
char *pathname;
|
||||
|
||||
/*
|
||||
* Try $HOME/filename.
|
||||
*/
|
||||
pathname = dirfile(lgetenv("HOME"), filename);
|
||||
/* Try $HOME/filename. */
|
||||
pathname = dirfile(lgetenv("HOME"), filename, 1);
|
||||
if (pathname != NULL)
|
||||
return (pathname);
|
||||
#if OS2
|
||||
/*
|
||||
* Try $INIT/filename.
|
||||
*/
|
||||
pathname = dirfile(lgetenv("INIT"), filename);
|
||||
/* Try $INIT/filename. */
|
||||
pathname = dirfile(lgetenv("INIT"), filename, 1);
|
||||
if (pathname != NULL)
|
||||
return (pathname);
|
||||
#endif
|
||||
#if MSDOS_COMPILER || OS2
|
||||
/*
|
||||
* Look for the file anywhere on search path.
|
||||
*/
|
||||
pathname = (char *) calloc(_MAX_PATH, sizeof(char));
|
||||
/* Look for the file anywhere on search path. */
|
||||
pathname = (char *) ecalloc(_MAX_PATH, sizeof(char));
|
||||
#if MSDOS_COMPILER==DJGPPC
|
||||
{
|
||||
char *res = searchpath(filename);
|
||||
@ -517,6 +515,7 @@ seek_filesize(f)
|
||||
return ((POSITION) spos);
|
||||
}
|
||||
|
||||
#if HAVE_POPEN
|
||||
/*
|
||||
* Read a string from a file.
|
||||
* Return a pointer to the string in memory.
|
||||
@ -560,10 +559,6 @@ readfd(fd)
|
||||
return (buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if HAVE_POPEN
|
||||
|
||||
/*
|
||||
* Execute a shell command.
|
||||
* Return a pointer to a pipe connected to the shell command's standard output.
|
||||
@ -812,6 +807,7 @@ lrealpath(path)
|
||||
return (save(path));
|
||||
}
|
||||
|
||||
#if HAVE_POPEN
|
||||
/*
|
||||
* Return number of %s escapes in a string.
|
||||
* Return a large number if there are any other % escapes besides %s.
|
||||
@ -837,6 +833,7 @@ num_pct_s(lessopen)
|
||||
}
|
||||
return (num);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* See if we should open a "replacement file"
|
||||
@ -953,10 +950,13 @@ open_altfile(filename, pf, pfd)
|
||||
cmd = readfd(fd);
|
||||
pclose(fd);
|
||||
if (*cmd == '\0')
|
||||
{
|
||||
/*
|
||||
* Pipe is empty. This means there is no alt file.
|
||||
*/
|
||||
free(cmd);
|
||||
return (NULL);
|
||||
}
|
||||
return (cmd);
|
||||
#endif /* HAVE_POPEN */
|
||||
}
|
||||
@ -1122,4 +1122,3 @@ last_component(name)
|
||||
}
|
||||
return (name);
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,8 @@ public int ecmd_decode LESSPARAMS ((char *cmd, char **sp));
|
||||
public char * lgetenv LESSPARAMS ((char *var));
|
||||
public int isnullenv LESSPARAMS ((char* s));
|
||||
public int lesskey LESSPARAMS ((char *filename, int sysvar));
|
||||
public void add_hometable LESSPARAMS ((char *envname, char *def_filename, int sysvar));
|
||||
public int lesskey_src LESSPARAMS ((char *filename, int sysvar));
|
||||
public int add_hometable LESSPARAMS ((int (*call_lesskey)(char *, int), char *envname, char *def_filename, int sysvar));
|
||||
public int editchar LESSPARAMS ((int c, int flags));
|
||||
public void init_textlist LESSPARAMS ((struct textlist *tlist, char *str));
|
||||
public char * forw_textlist LESSPARAMS ((struct textlist *tlist, char *prev));
|
||||
@ -129,6 +130,7 @@ public void use_logfile LESSPARAMS ((char *filename));
|
||||
public char * shell_unquote LESSPARAMS ((char *str));
|
||||
public char * get_meta_escape LESSPARAMS ((VOID_PARAM));
|
||||
public char * shell_quote LESSPARAMS ((char *s));
|
||||
public char * dirfile LESSPARAMS ((char *dirname, char *filename, int must_exist));
|
||||
public char * homefile LESSPARAMS ((char *filename));
|
||||
public char * fexpand LESSPARAMS ((char *s));
|
||||
public char * fcomplete LESSPARAMS ((char *s));
|
||||
@ -213,6 +215,7 @@ public void add_lnum LESSPARAMS ((LINENUM linenum, POSITION pos));
|
||||
public LINENUM find_linenum LESSPARAMS ((POSITION pos));
|
||||
public POSITION find_pos LESSPARAMS ((LINENUM linenum));
|
||||
public LINENUM currline LESSPARAMS ((int where));
|
||||
public void scan_eof LESSPARAMS ((VOID_PARAM));
|
||||
public void lsystem LESSPARAMS ((char *cmd, char *donemsg));
|
||||
public int pipe_mark LESSPARAMS ((int c, char *cmd));
|
||||
public int pipe_data LESSPARAMS ((char *cmd, POSITION spos, POSITION epos));
|
||||
@ -235,6 +238,7 @@ public void calc_jump_sline LESSPARAMS ((VOID_PARAM));
|
||||
public void opt_shift LESSPARAMS ((int type, char *s));
|
||||
public void calc_shift_count LESSPARAMS ((VOID_PARAM));
|
||||
public void opt_k LESSPARAMS ((int type, char *s));
|
||||
public void opt_ks LESSPARAMS ((int type, char *s));
|
||||
public void opt_t LESSPARAMS ((int type, char *s));
|
||||
public void opt__T LESSPARAMS ((int type, char *s));
|
||||
public void opt_p LESSPARAMS ((int type, char *s));
|
||||
@ -251,6 +255,7 @@ public void opt_mousecap LESSPARAMS ((int type, char *s));
|
||||
public void opt_wheel_lines LESSPARAMS ((int type, char *s));
|
||||
public void opt_linenum_width LESSPARAMS ((int type, char *s));
|
||||
public void opt_status_col_width LESSPARAMS ((int type, char *s));
|
||||
public void opt_filesize LESSPARAMS ((int type, char *s));
|
||||
public void opt_ttyin_name LESSPARAMS ((int type, char *s));
|
||||
public void opt_rstat LESSPARAMS ((int type, char *s));
|
||||
public int get_swindow LESSPARAMS ((VOID_PARAM));
|
||||
@ -280,6 +285,7 @@ public void put_line LESSPARAMS ((VOID_PARAM));
|
||||
public void flush LESSPARAMS ((VOID_PARAM));
|
||||
public void set_output LESSPARAMS ((int fd));
|
||||
public int putchr LESSPARAMS ((int c));
|
||||
public void clear_bot_if_needed LESSPARAMS ((VOID_PARAM));
|
||||
public void putstr LESSPARAMS ((constant char *s));
|
||||
public int less_printf LESSPARAMS ((char *fmt, PARG *parg));
|
||||
public void get_return LESSPARAMS ((VOID_PARAM));
|
||||
@ -342,3 +348,7 @@ public void close_getchr LESSPARAMS ((VOID_PARAM));
|
||||
public int default_wheel_lines LESSPARAMS ((VOID_PARAM));
|
||||
public void rstat LESSPARAMS ((char st));
|
||||
public int getchr LESSPARAMS ((VOID_PARAM));
|
||||
public void xbuf_init LESSPARAMS ((struct xbuffer *xbuf));
|
||||
public void xbuf_deinit LESSPARAMS ((struct xbuffer *xbuf));
|
||||
public void xbuf_reset LESSPARAMS ((struct xbuffer *xbuf));
|
||||
public void xbuf_add LESSPARAMS ((struct xbuffer *xbuf, char ch));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* This file was generated by mkhelp.pl from less.hlp at 14:59 on 2021/4/28 */
|
||||
/* This file was generated by mkhelp.pl from less.hlp at 17:45 on 2021/6/3 */
|
||||
#include "less.h"
|
||||
constant char helpdata[] = {
|
||||
'\n',
|
||||
@ -208,6 +208,8 @@ constant char helpdata[] = {
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','d','i','s','p','l','a','y',' ','t','i','l','d','e','s',' ','a','f','t','e','r',' ','e','n','d',' ','o','f',' ','f','i','l','e','.','\n',
|
||||
' ',' ','-','#',' ','[','_','\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',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','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',
|
||||
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','i','n','c','s','e','a','r','c','h','\n',
|
||||
|
@ -571,6 +571,7 @@ struct loption;
|
||||
struct hilite_tree;
|
||||
struct ansi_state;
|
||||
#include "pattern.h"
|
||||
#include "xbuf.h"
|
||||
#include "funcs.h"
|
||||
|
||||
/* Functions not included in funcs.h */
|
||||
|
@ -205,6 +205,8 @@
|
||||
Don't display tildes after end of file.
|
||||
-# [_N] .... --shift=[_N]
|
||||
Set horizontal scroll amount (0 = one half screen width).
|
||||
--file-size
|
||||
Automatically determine the size of the input file.
|
||||
--follow-name
|
||||
The F command changes files if the input file is renamed.
|
||||
--incsearch
|
||||
|
@ -1,5 +1,5 @@
|
||||
'\" t
|
||||
.TH LESS 1 "Version 581.2: 28 Apr 2021"
|
||||
.TH LESS 1 "Version 590: 03 Jun 2021"
|
||||
.SH NAME
|
||||
less \- opposite of more
|
||||
.SH SYNOPSIS
|
||||
@ -759,13 +759,38 @@ Causes
|
||||
.I less
|
||||
to open and interpret the named file as a
|
||||
.IR lesskey (1)
|
||||
file.
|
||||
binary file.
|
||||
Multiple \-k options may be specified.
|
||||
If the LESSKEY or LESSKEY_SYSTEM environment variable is set, or
|
||||
if a lesskey file is found in a standard place (see KEY BINDINGS),
|
||||
it is also used as a
|
||||
.I lesskey
|
||||
file.
|
||||
.IP "\-\-lesskey-src=\fIfilename\fP"
|
||||
Causes
|
||||
.I less
|
||||
to open and interpret the named file as a
|
||||
.IR lesskey (1)
|
||||
source file.
|
||||
If the LESSKEYIN or LESSKEYIN_SYSTEM environment variable is set, or
|
||||
if a lesskey source file is found in a standard place (see KEY BINDINGS),
|
||||
it is also used as a
|
||||
.I "lesskey source"
|
||||
file.
|
||||
Prior to version 582, the
|
||||
.I lesskey
|
||||
program needed to be run to convert a
|
||||
.I "lesskey source"
|
||||
file to a
|
||||
.I "lesskey binary"
|
||||
file for
|
||||
.I less
|
||||
to use.
|
||||
Newer versions of
|
||||
.I less
|
||||
read the
|
||||
.I "lesskey source"
|
||||
file directly and ignore the binary file if the source file exists.
|
||||
.IP "\-K or \-\-quit-on-intr"
|
||||
Causes
|
||||
.I less
|
||||
@ -1054,6 +1079,12 @@ If the number is specified as a fraction, the actual number of
|
||||
scroll positions is recalculated if the terminal window is resized,
|
||||
so that the actual scroll remains at the specified fraction
|
||||
of the screen width.
|
||||
.IP "\-\-file-size"
|
||||
If \-\-file-size is specified,
|
||||
.I less
|
||||
will determine the size of the file
|
||||
immediately after opening the file.
|
||||
Normally this is not done, because it can be slow if the input file is large.
|
||||
.IP "\-\-follow-name"
|
||||
Normally, if the input file is renamed while an F command is executing,
|
||||
.I less
|
||||
@ -1222,57 +1253,61 @@ Delete the entire command line and return to the main prompt.
|
||||
.SH "KEY BINDINGS"
|
||||
You may define your own
|
||||
.I less
|
||||
commands by using the program
|
||||
.IR lesskey (1)
|
||||
to create a lesskey file.
|
||||
commands by creating a lesskey source file.
|
||||
This file specifies a set of command keys and an action
|
||||
associated with each key.
|
||||
You may also use
|
||||
.I lesskey
|
||||
to change the line-editing keys (see LINE EDITING),
|
||||
You may also change the line-editing keys (see LINE EDITING),
|
||||
and to set environment variables.
|
||||
If the environment variable LESSKEY is set,
|
||||
If the environment variable LESSKEYIN is set,
|
||||
.I less
|
||||
uses that as the name of the lesskey file.
|
||||
uses that as the name of the lesskey source file.
|
||||
Otherwise,
|
||||
.I less
|
||||
looks in a standard place for the lesskey file:
|
||||
looks in a standard place for the lesskey source file:
|
||||
On Unix systems,
|
||||
.I less
|
||||
looks for a lesskey file called "$HOME/.less".
|
||||
looks for a lesskey file called "$XDG_CONFIG_HOME/lesskey" or "$HOME/.lesskey".
|
||||
On MS-DOS and Windows systems,
|
||||
.I less
|
||||
looks for a lesskey file called "$HOME/_less", and if it is not found there,
|
||||
then looks for a lesskey file called "_less" in any directory specified
|
||||
looks for a lesskey file called "$HOME/_lesskey", and if it is not found there,
|
||||
then looks for a lesskey file called "_lesskey" in any directory specified
|
||||
in the PATH environment variable.
|
||||
On OS/2 systems,
|
||||
.I less
|
||||
looks for a lesskey file called "$HOME/less.ini", and if it is not found,
|
||||
then looks for a lesskey file called "less.ini" in any directory specified
|
||||
looks for a lesskey file called "$HOME/lesskey.ini", and if it is not found,
|
||||
then looks for a lesskey file called "lesskey.ini" in any directory specified
|
||||
in the INIT environment variable, and if it not found there,
|
||||
then looks for a lesskey file called "less.ini" in any directory specified
|
||||
then looks for a lesskey file called "lesskey.ini" in any directory specified
|
||||
in the PATH environment variable.
|
||||
See the
|
||||
.I lesskey
|
||||
manual page for more details.
|
||||
.P
|
||||
A system-wide lesskey file may also be set up to provide key bindings.
|
||||
.PP
|
||||
A system-wide lesskey source file may also be set up to provide key bindings.
|
||||
If a key is defined in both a local lesskey file and in the
|
||||
system-wide file, key bindings in the local file take precedence over
|
||||
those in the system-wide file.
|
||||
If the environment variable LESSKEY_SYSTEM is set,
|
||||
If the environment variable LESSKEYIN_SYSTEM is set,
|
||||
.I less
|
||||
uses that as the name of the system-wide lesskey file.
|
||||
Otherwise,
|
||||
.I less
|
||||
looks in a standard place for the system-wide lesskey file:
|
||||
On Unix systems, the system-wide lesskey file is /usr/local/etc/sysless.
|
||||
On Unix systems, the system-wide lesskey file is /usr/local/etc/syslesskey.
|
||||
(However, if
|
||||
.I less
|
||||
was built with a different sysconf directory than /usr/local/etc,
|
||||
that directory is where the sysless file is found.)
|
||||
On MS-DOS and Windows systems, the system-wide lesskey file is c:\e_sysless.
|
||||
On OS/2 systems, the system-wide lesskey file is c:\esysless.ini.
|
||||
On MS-DOS and Windows systems, the system-wide lesskey file is c:\e_syslesskey.
|
||||
On OS/2 systems, the system-wide lesskey file is c:\esyslesskey.ini.
|
||||
.PP
|
||||
Previous versions of
|
||||
.I less
|
||||
(before v582) used lesskey files with a binary format, produced by the
|
||||
.I lesskey
|
||||
program. It is no longer necessary to use the
|
||||
.I lesskey
|
||||
program.
|
||||
.
|
||||
.SH "INPUT PREPROCESSOR"
|
||||
You may define an "input preprocessor" for
|
||||
@ -1890,20 +1925,29 @@ Name of the history file used to remember search commands and
|
||||
shell commands between invocations of
|
||||
.IR less .
|
||||
If set to "\-" or "/dev/null", a history file is not used.
|
||||
The default is "$HOME/.lesshst" on Unix systems, "$HOME/_lesshst" on
|
||||
DOS and Windows systems, or "$HOME/lesshst.ini" or "$INIT/lesshst.ini"
|
||||
The default is "$XDG_DATA_HOME/lesshst" or "$HOME/.lesshst" on Unix systems,
|
||||
"$HOME/_lesshst" on DOS and Windows systems,
|
||||
or "$HOME/lesshst.ini" or "$INIT/lesshst.ini"
|
||||
on OS/2 systems.
|
||||
.IP LESSHISTSIZE
|
||||
The maximum number of commands to save in the history file.
|
||||
The default is 100.
|
||||
.IP LESSKEYIN
|
||||
Name of the default
|
||||
.I "lesskey source"
|
||||
file.
|
||||
.IP LESSKEY
|
||||
Name of the default
|
||||
.IR lesskey (1)
|
||||
.I "lesskey binary"
|
||||
file. (Not used if "$LESSKEYIN" exists.)
|
||||
.IP LESSKEYIN_SYSTEM
|
||||
Name of the default system-wide
|
||||
.I "lesskey source"
|
||||
file.
|
||||
.IP LESSKEY_SYSTEM
|
||||
Name of the default system-wide
|
||||
.IR lesskey (1)
|
||||
file.
|
||||
.I "lesskey binary"
|
||||
file. (Not used if "$LESSKEYIN_SYSTEM" exists.)
|
||||
.IP LESSMETACHARS
|
||||
List of characters which are considered "metacharacters" by the shell.
|
||||
.IP LESSMETAESCAPE
|
||||
@ -1981,4 +2025,4 @@ Report bugs at https://github.com/gwsw/less/issues.
|
||||
.br
|
||||
For more information, see the less homepage at
|
||||
.br
|
||||
https://greenwoodsoftware.com/less.
|
||||
https://greenwoodsoftware.com/less
|
||||
|
@ -1,4 +1,4 @@
|
||||
.TH LESSECHO 1 "Version 581.2: 28 Apr 2021"
|
||||
.TH LESSECHO 1 "Version 590: 03 Jun 2021"
|
||||
.SH NAME
|
||||
lessecho \- expand metacharacters
|
||||
.SH SYNOPSIS
|
||||
|
@ -80,121 +80,12 @@
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*/
|
||||
|
||||
#include "less.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "lesskey.h"
|
||||
#include "cmd.h"
|
||||
|
||||
struct cmdname
|
||||
{
|
||||
char *cn_name;
|
||||
int cn_action;
|
||||
};
|
||||
|
||||
struct cmdname cmdnames[] =
|
||||
{
|
||||
{ "back-bracket", A_B_BRACKET },
|
||||
{ "back-line", A_B_LINE },
|
||||
{ "back-line-force", A_BF_LINE },
|
||||
{ "back-screen", A_B_SCREEN },
|
||||
{ "back-scroll", A_B_SCROLL },
|
||||
{ "back-search", A_B_SEARCH },
|
||||
{ "back-window", A_B_WINDOW },
|
||||
{ "clear-mark", A_CLRMARK },
|
||||
{ "debug", A_DEBUG },
|
||||
{ "digit", A_DIGIT },
|
||||
{ "display-flag", A_DISP_OPTION },
|
||||
{ "display-option", A_DISP_OPTION },
|
||||
{ "end", A_GOEND },
|
||||
{ "end-scroll", A_RRSHIFT },
|
||||
{ "examine", A_EXAMINE },
|
||||
{ "filter", A_FILTER },
|
||||
{ "first-cmd", A_FIRSTCMD },
|
||||
{ "firstcmd", A_FIRSTCMD },
|
||||
{ "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-window", A_F_WINDOW },
|
||||
{ "goto-end", A_GOEND },
|
||||
{ "goto-end-buffered", A_GOEND_BUF },
|
||||
{ "goto-line", A_GOLINE },
|
||||
{ "goto-mark", A_GOMARK },
|
||||
{ "help", A_HELP },
|
||||
{ "index-file", A_INDEX_FILE },
|
||||
{ "invalid", A_UINVALID },
|
||||
{ "left-scroll", A_LSHIFT },
|
||||
{ "next-file", A_NEXT_FILE },
|
||||
{ "next-tag", A_NEXT_TAG },
|
||||
{ "noaction", A_NOACTION },
|
||||
{ "no-scroll", A_LLSHIFT },
|
||||
{ "percent", A_PERCENT },
|
||||
{ "pipe", A_PIPE },
|
||||
{ "prev-file", A_PREV_FILE },
|
||||
{ "prev-tag", A_PREV_TAG },
|
||||
{ "quit", A_QUIT },
|
||||
{ "remove-file", A_REMOVE_FILE },
|
||||
{ "repaint", A_REPAINT },
|
||||
{ "repaint-flush", A_FREPAINT },
|
||||
{ "repeat-search", A_AGAIN_SEARCH },
|
||||
{ "repeat-search-all", A_T_AGAIN_SEARCH },
|
||||
{ "reverse-search", A_REVERSE_SEARCH },
|
||||
{ "reverse-search-all", A_T_REVERSE_SEARCH },
|
||||
{ "right-scroll", A_RSHIFT },
|
||||
{ "set-mark", A_SETMARK },
|
||||
{ "set-mark-bottom", A_SETMARKBOT },
|
||||
{ "shell", A_SHELL },
|
||||
{ "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 }
|
||||
};
|
||||
|
||||
struct cmdname editnames[] =
|
||||
{
|
||||
{ "back-complete", EC_B_COMPLETE },
|
||||
{ "backspace", EC_BACKSPACE },
|
||||
{ "delete", EC_DELETE },
|
||||
{ "down", EC_DOWN },
|
||||
{ "end", EC_END },
|
||||
{ "expand", EC_EXPAND },
|
||||
{ "forw-complete", EC_F_COMPLETE },
|
||||
{ "home", EC_HOME },
|
||||
{ "insert", EC_INSERT },
|
||||
{ "invalid", EC_UINVALID },
|
||||
{ "kill-line", EC_LINEKILL },
|
||||
{ "abort", EC_ABORT },
|
||||
{ "left", EC_LEFT },
|
||||
{ "literal", EC_LITERAL },
|
||||
{ "right", EC_RIGHT },
|
||||
{ "up", EC_UP },
|
||||
{ "word-backspace", EC_W_BACKSPACE },
|
||||
{ "word-delete", EC_W_DELETE },
|
||||
{ "word-left", EC_W_LEFT },
|
||||
{ "word-right", EC_W_RIGHT },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
struct table
|
||||
{
|
||||
struct cmdname *names;
|
||||
char *pbuffer;
|
||||
char buffer[MAX_USERCMD];
|
||||
};
|
||||
|
||||
struct table cmdtable;
|
||||
struct table edittable;
|
||||
struct table vartable;
|
||||
struct table *currtable = &cmdtable;
|
||||
#include "defines.h"
|
||||
|
||||
char fileheader[] = {
|
||||
C0_LESSKEY_MAGIC,
|
||||
@ -215,26 +106,44 @@ char endsection[1] = { END_SECTION };
|
||||
char *infile = NULL;
|
||||
char *outfile = NULL ;
|
||||
|
||||
int linenum;
|
||||
int errors;
|
||||
|
||||
extern char version[];
|
||||
|
||||
void
|
||||
usage(VOID_PARAM)
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: lesskey [-o output] [input]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *
|
||||
void
|
||||
lesskey_parse_error(s)
|
||||
char *s;
|
||||
{
|
||||
fprintf(stderr, "%s\n", s);
|
||||
}
|
||||
|
||||
void *
|
||||
ecalloc(count, size)
|
||||
int count;
|
||||
unsigned int size;
|
||||
{
|
||||
void *p;
|
||||
|
||||
p = calloc(count, size);
|
||||
if (p != NULL)
|
||||
return (p);
|
||||
fprintf(stderr, "lesskey: cannot allocate %d bytes of memory\n", count*size);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static char *
|
||||
mkpathname(dirname, filename)
|
||||
char *dirname;
|
||||
char *filename;
|
||||
{
|
||||
char *pathname;
|
||||
|
||||
pathname = calloc(strlen(dirname) + strlen(filename) + 2, sizeof(char));
|
||||
pathname = ecalloc(strlen(dirname) + strlen(filename) + 2, sizeof(char));
|
||||
strcpy(pathname, dirname);
|
||||
strcat(pathname, PATHNAME_SEP);
|
||||
strcat(pathname, filename);
|
||||
@ -268,7 +177,7 @@ homefile(filename)
|
||||
/*
|
||||
* Parse command line arguments.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
parse_args(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
@ -336,247 +245,12 @@ parse_args(argc, argv)
|
||||
*/
|
||||
if (argc > 0)
|
||||
infile = *argv;
|
||||
else
|
||||
infile = homefile(DEF_LESSKEYINFILE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize data structures.
|
||||
*/
|
||||
void
|
||||
init_tables(VOID_PARAM)
|
||||
{
|
||||
cmdtable.names = cmdnames;
|
||||
cmdtable.pbuffer = cmdtable.buffer;
|
||||
|
||||
edittable.names = editnames;
|
||||
edittable.pbuffer = edittable.buffer;
|
||||
|
||||
vartable.names = NULL;
|
||||
vartable.pbuffer = vartable.buffer;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse one character of a string.
|
||||
*/
|
||||
char *
|
||||
tstr(pp, xlate)
|
||||
char **pp;
|
||||
int xlate;
|
||||
{
|
||||
char *p;
|
||||
char ch;
|
||||
int i;
|
||||
static char buf[10];
|
||||
static char tstr_control_k[] =
|
||||
{ SK_SPECIAL_KEY, SK_CONTROL_K, 6, 1, 1, 1, '\0' };
|
||||
|
||||
p = *pp;
|
||||
switch (*p)
|
||||
{
|
||||
case '\\':
|
||||
++p;
|
||||
switch (*p)
|
||||
{
|
||||
case '0': case '1': case '2': case '3':
|
||||
case '4': case '5': case '6': case '7':
|
||||
/*
|
||||
* Parse an octal number.
|
||||
*/
|
||||
ch = 0;
|
||||
i = 0;
|
||||
do
|
||||
ch = 8*ch + (*p - '0');
|
||||
while (*++p >= '0' && *p <= '7' && ++i < 3);
|
||||
*pp = p;
|
||||
if (xlate && ch == CONTROL('K'))
|
||||
return tstr_control_k;
|
||||
buf[0] = ch;
|
||||
buf[1] = '\0';
|
||||
return (buf);
|
||||
case 'b':
|
||||
*pp = p+1;
|
||||
return ("\b");
|
||||
case 'e':
|
||||
*pp = p+1;
|
||||
buf[0] = ESC;
|
||||
buf[1] = '\0';
|
||||
return (buf);
|
||||
case 'n':
|
||||
*pp = p+1;
|
||||
return ("\n");
|
||||
case 'r':
|
||||
*pp = p+1;
|
||||
return ("\r");
|
||||
case 't':
|
||||
*pp = p+1;
|
||||
return ("\t");
|
||||
case 'k':
|
||||
if (xlate)
|
||||
{
|
||||
switch (*++p)
|
||||
{
|
||||
case 'u': ch = SK_UP_ARROW; break;
|
||||
case 'd': ch = SK_DOWN_ARROW; break;
|
||||
case 'r': ch = SK_RIGHT_ARROW; break;
|
||||
case 'l': ch = SK_LEFT_ARROW; break;
|
||||
case 'U': ch = SK_PAGE_UP; break;
|
||||
case 'D': ch = SK_PAGE_DOWN; break;
|
||||
case 'h': ch = SK_HOME; break;
|
||||
case 'e': ch = SK_END; break;
|
||||
case 'x': ch = SK_DELETE; break;
|
||||
default:
|
||||
error("illegal char after \\k", NULL_PARG);
|
||||
*pp = p+1;
|
||||
return ("");
|
||||
}
|
||||
*pp = p+1;
|
||||
buf[0] = SK_SPECIAL_KEY;
|
||||
buf[1] = ch;
|
||||
buf[2] = 6;
|
||||
buf[3] = 1;
|
||||
buf[4] = 1;
|
||||
buf[5] = 1;
|
||||
buf[6] = '\0';
|
||||
return (buf);
|
||||
}
|
||||
/* FALLTHRU */
|
||||
default:
|
||||
/*
|
||||
* Backslash followed by any other char
|
||||
* just means that char.
|
||||
*/
|
||||
*pp = p+1;
|
||||
buf[0] = *p;
|
||||
buf[1] = '\0';
|
||||
if (xlate && buf[0] == CONTROL('K'))
|
||||
return tstr_control_k;
|
||||
return (buf);
|
||||
}
|
||||
case '^':
|
||||
/*
|
||||
* Caret means CONTROL.
|
||||
*/
|
||||
*pp = p+2;
|
||||
buf[0] = CONTROL(p[1]);
|
||||
buf[1] = '\0';
|
||||
if (xlate && buf[0] == CONTROL('K'))
|
||||
return tstr_control_k;
|
||||
return (buf);
|
||||
}
|
||||
*pp = p+1;
|
||||
buf[0] = *p;
|
||||
buf[1] = '\0';
|
||||
if (xlate && buf[0] == CONTROL('K'))
|
||||
return tstr_control_k;
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip leading spaces in a string.
|
||||
*/
|
||||
public char *
|
||||
skipsp(s)
|
||||
char *s;
|
||||
{
|
||||
while (*s == ' ' || *s == '\t')
|
||||
s++;
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip non-space characters in a string.
|
||||
*/
|
||||
public char *
|
||||
skipnsp(s)
|
||||
char *s;
|
||||
{
|
||||
while (*s != '\0' && *s != ' ' && *s != '\t')
|
||||
s++;
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up an input line:
|
||||
* strip off the trailing newline & any trailing # comment.
|
||||
*/
|
||||
char *
|
||||
clean_line(s)
|
||||
char *s;
|
||||
{
|
||||
int i;
|
||||
|
||||
s = skipsp(s);
|
||||
for (i = 0; s[i] != '\n' && s[i] != '\r' && s[i] != '\0'; i++)
|
||||
if (s[i] == '#' && (i == 0 || s[i-1] != '\\'))
|
||||
break;
|
||||
s[i] = '\0';
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a byte to the output command table.
|
||||
*/
|
||||
void
|
||||
add_cmd_char(c)
|
||||
int c;
|
||||
{
|
||||
if (currtable->pbuffer >= currtable->buffer + MAX_USERCMD)
|
||||
{
|
||||
error("too many commands", NULL_PARG);
|
||||
exit(1);
|
||||
}
|
||||
*(currtable->pbuffer)++ = c;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a string to the output command table.
|
||||
*/
|
||||
void
|
||||
add_cmd_str(s)
|
||||
char *s;
|
||||
{
|
||||
for ( ; *s != '\0'; s++)
|
||||
add_cmd_char(*s);
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we have a special "control" line.
|
||||
*/
|
||||
int
|
||||
control_line(s)
|
||||
char *s;
|
||||
{
|
||||
#define PREFIX(str,pat) (strncmp(str,pat,strlen(pat)) == 0)
|
||||
|
||||
if (PREFIX(s, "#line-edit"))
|
||||
{
|
||||
currtable = &edittable;
|
||||
return (1);
|
||||
}
|
||||
if (PREFIX(s, "#command"))
|
||||
{
|
||||
currtable = &cmdtable;
|
||||
return (1);
|
||||
}
|
||||
if (PREFIX(s, "#env"))
|
||||
{
|
||||
currtable = &vartable;
|
||||
return (1);
|
||||
}
|
||||
if (PREFIX(s, "#stop"))
|
||||
{
|
||||
add_cmd_char('\0');
|
||||
add_cmd_char(A_END_LIST);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Output some bytes.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
fputbytes(fd, buf, len)
|
||||
FILE *fd;
|
||||
char *buf;
|
||||
@ -592,7 +266,7 @@ fputbytes(fd, buf, len)
|
||||
/*
|
||||
* Output an integer, in special KRADIX form.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
fputint(fd, val)
|
||||
FILE *fd;
|
||||
unsigned int val;
|
||||
@ -601,7 +275,7 @@ fputint(fd, val)
|
||||
|
||||
if (val >= KRADIX*KRADIX)
|
||||
{
|
||||
fprintf(stderr, "error: integer too big (%d > %d)\n",
|
||||
fprintf(stderr, "error: cannot write %d, max %d\n",
|
||||
val, KRADIX*KRADIX);
|
||||
exit(1);
|
||||
}
|
||||
@ -611,174 +285,14 @@ fputint(fd, val)
|
||||
fwrite(&c, sizeof(char), 1, fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an action, given the name of the action.
|
||||
*/
|
||||
int
|
||||
findaction(actname)
|
||||
char *actname;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; currtable->names[i].cn_name != NULL; i++)
|
||||
if (strcmp(currtable->names[i].cn_name, actname) == 0)
|
||||
return (currtable->names[i].cn_action);
|
||||
error("unknown action", NULL_PARG);
|
||||
return (A_INVALID);
|
||||
}
|
||||
|
||||
void
|
||||
error(s, parg)
|
||||
char *s;
|
||||
PARG *parg;
|
||||
{
|
||||
fprintf(stderr, "line %d: %s\n", linenum, s);
|
||||
errors++;
|
||||
(void) parg;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
parse_cmdline(p)
|
||||
char *p;
|
||||
{
|
||||
int cmdlen;
|
||||
char *actname;
|
||||
int action;
|
||||
char *s;
|
||||
char c;
|
||||
|
||||
/*
|
||||
* Parse the command string and store it in the current table.
|
||||
*/
|
||||
cmdlen = 0;
|
||||
do
|
||||
{
|
||||
s = tstr(&p, 1);
|
||||
cmdlen += (int) strlen(s);
|
||||
if (cmdlen > MAX_CMDLEN)
|
||||
error("command too long", NULL_PARG);
|
||||
else
|
||||
add_cmd_str(s);
|
||||
} while (*p != ' ' && *p != '\t' && *p != '\0');
|
||||
/*
|
||||
* Terminate the command string with a null byte.
|
||||
*/
|
||||
add_cmd_char('\0');
|
||||
|
||||
/*
|
||||
* Skip white space between the command string
|
||||
* and the action name.
|
||||
* Terminate the action name with a null byte.
|
||||
*/
|
||||
p = skipsp(p);
|
||||
if (*p == '\0')
|
||||
{
|
||||
error("missing action", NULL_PARG);
|
||||
return;
|
||||
}
|
||||
actname = p;
|
||||
p = skipnsp(p);
|
||||
c = *p;
|
||||
*p = '\0';
|
||||
|
||||
/*
|
||||
* Parse the action name and store it in the current table.
|
||||
*/
|
||||
action = findaction(actname);
|
||||
|
||||
/*
|
||||
* See if an extra string follows the action name.
|
||||
*/
|
||||
*p = c;
|
||||
p = skipsp(p);
|
||||
if (*p == '\0')
|
||||
{
|
||||
add_cmd_char(action);
|
||||
} else
|
||||
{
|
||||
/*
|
||||
* OR the special value A_EXTRA into the action byte.
|
||||
* Put the extra string after the action byte.
|
||||
*/
|
||||
add_cmd_char(action | A_EXTRA);
|
||||
while (*p != '\0')
|
||||
add_cmd_str(tstr(&p, 0));
|
||||
add_cmd_char('\0');
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
parse_varline(p)
|
||||
char *p;
|
||||
{
|
||||
char *s;
|
||||
|
||||
do
|
||||
{
|
||||
s = tstr(&p, 0);
|
||||
add_cmd_str(s);
|
||||
} while (*p != ' ' && *p != '\t' && *p != '=' && *p != '\0');
|
||||
/*
|
||||
* Terminate the variable name with a null byte.
|
||||
*/
|
||||
add_cmd_char('\0');
|
||||
|
||||
p = skipsp(p);
|
||||
if (*p++ != '=')
|
||||
{
|
||||
error("missing =", NULL_PARG);
|
||||
return;
|
||||
}
|
||||
|
||||
add_cmd_char(EV_OK|A_EXTRA);
|
||||
|
||||
p = skipsp(p);
|
||||
while (*p != '\0')
|
||||
{
|
||||
s = tstr(&p, 0);
|
||||
add_cmd_str(s);
|
||||
}
|
||||
add_cmd_char('\0');
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a line from the lesskey file.
|
||||
*/
|
||||
void
|
||||
parse_line(line)
|
||||
char *line;
|
||||
{
|
||||
char *p;
|
||||
|
||||
/*
|
||||
* See if it is a control line.
|
||||
*/
|
||||
if (control_line(line))
|
||||
return;
|
||||
/*
|
||||
* Skip leading white space.
|
||||
* Replace the final newline with a null byte.
|
||||
* Ignore blank lines and comments.
|
||||
*/
|
||||
p = clean_line(line);
|
||||
if (*p == '\0')
|
||||
return;
|
||||
|
||||
if (currtable == &vartable)
|
||||
parse_varline(p);
|
||||
else
|
||||
parse_cmdline(p);
|
||||
}
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
FILE *desc;
|
||||
struct lesskey_tables tables;
|
||||
FILE *out;
|
||||
char line[1024];
|
||||
int errors;
|
||||
|
||||
#ifdef WIN32
|
||||
if (getenv("HOME") == NULL)
|
||||
@ -791,7 +305,7 @@ main(argc, argv)
|
||||
char *path = getenv("HOMEPATH");
|
||||
if (drive != NULL && path != NULL)
|
||||
{
|
||||
char *env = (char *) calloc(strlen(drive) +
|
||||
char *env = (char *) ecalloc(strlen(drive) +
|
||||
strlen(path) + 6, sizeof(char));
|
||||
strcpy(env, "HOME=");
|
||||
strcat(env, drive);
|
||||
@ -805,44 +319,19 @@ main(argc, argv)
|
||||
* Process command line arguments.
|
||||
*/
|
||||
parse_args(argc, argv);
|
||||
init_tables();
|
||||
|
||||
/*
|
||||
* Open the input file.
|
||||
*/
|
||||
if (strcmp(infile, "-") == 0)
|
||||
desc = stdin;
|
||||
else if ((desc = fopen(infile, "r")) == NULL)
|
||||
errors = parse_lesskey(infile, &tables);
|
||||
if (errors)
|
||||
{
|
||||
#if HAVE_PERROR
|
||||
perror(infile);
|
||||
#else
|
||||
fprintf(stderr, "Cannot open %s\n", infile);
|
||||
#endif
|
||||
usage();
|
||||
fprintf(stderr, "%d errors; no output produced\n", errors);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read and parse the input file, one line at a time.
|
||||
*/
|
||||
errors = 0;
|
||||
linenum = 0;
|
||||
while (fgets(line, sizeof(line), desc) != NULL)
|
||||
{
|
||||
++linenum;
|
||||
parse_line(line);
|
||||
}
|
||||
fprintf(stderr, "NOTE: lesskey is deprecated.\n It is no longer necessary to run lesskey,\n when using less version 582 and later.\n");
|
||||
|
||||
/*
|
||||
* Write the output file.
|
||||
* If no output file was specified, use "$HOME/.less"
|
||||
*/
|
||||
if (errors > 0)
|
||||
{
|
||||
fprintf(stderr, "%d errors; no output produced\n", errors);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (outfile == NULL)
|
||||
outfile = getenv("LESSKEY");
|
||||
if (outfile == NULL)
|
||||
@ -854,7 +343,7 @@ main(argc, argv)
|
||||
#else
|
||||
fprintf(stderr, "Cannot open %s\n", outfile);
|
||||
#endif
|
||||
exit(1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* File header */
|
||||
@ -862,17 +351,17 @@ main(argc, argv)
|
||||
|
||||
/* Command key section */
|
||||
fputbytes(out, cmdsection, sizeof(cmdsection));
|
||||
fputint(out, cmdtable.pbuffer - cmdtable.buffer);
|
||||
fputbytes(out, (char *)cmdtable.buffer, cmdtable.pbuffer-cmdtable.buffer);
|
||||
fputint(out, tables.cmdtable.buf.end);
|
||||
fputbytes(out, (char *)tables.cmdtable.buf.data, tables.cmdtable.buf.end);
|
||||
/* Edit key section */
|
||||
fputbytes(out, editsection, sizeof(editsection));
|
||||
fputint(out, edittable.pbuffer - edittable.buffer);
|
||||
fputbytes(out, (char *)edittable.buffer, edittable.pbuffer-edittable.buffer);
|
||||
fputint(out, tables.edittable.buf.end);
|
||||
fputbytes(out, (char *)tables.edittable.buf.data, tables.edittable.buf.end);
|
||||
|
||||
/* Environment variable section */
|
||||
fputbytes(out, varsection, sizeof(varsection));
|
||||
fputint(out, vartable.pbuffer - vartable.buffer);
|
||||
fputbytes(out, (char *)vartable.buffer, vartable.pbuffer-vartable.buffer);
|
||||
fputint(out, tables.vartable.buf.end);
|
||||
fputbytes(out, (char *)tables.vartable.buf.data, tables.vartable.buf.end);
|
||||
|
||||
/* File trailer */
|
||||
fputbytes(out, endsection, sizeof(endsection));
|
||||
|
@ -7,6 +7,7 @@
|
||||
* For more information, see the README file.
|
||||
*/
|
||||
|
||||
#include "xbuf.h"
|
||||
|
||||
/*
|
||||
* Format of a lesskey file:
|
||||
@ -37,3 +38,26 @@
|
||||
|
||||
/* */
|
||||
#define KRADIX 64
|
||||
|
||||
struct lesskey_cmdname
|
||||
{
|
||||
char *cn_name;
|
||||
int cn_action;
|
||||
};
|
||||
|
||||
struct lesskey_table
|
||||
{
|
||||
struct lesskey_cmdname *names;
|
||||
struct xbuffer buf;
|
||||
int is_var;
|
||||
};
|
||||
|
||||
struct lesskey_tables
|
||||
{
|
||||
struct lesskey_table *currtable;
|
||||
struct lesskey_table cmdtable;
|
||||
struct lesskey_table edittable;
|
||||
struct lesskey_table vartable;
|
||||
};
|
||||
|
||||
extern int parse_lesskey(char *infile, struct lesskey_tables *tables);
|
||||
|
@ -1,8 +1,8 @@
|
||||
'\" t
|
||||
.TH LESSKEY 1 "Version 581.2: 28 Apr 2021"
|
||||
.TH LESSKEY 1 "Version 590: 03 Jun 2021"
|
||||
.SH NAME
|
||||
lesskey \- specify key bindings for less
|
||||
.SH SYNOPSIS
|
||||
.SH "SYNOPSIS (deprecated)"
|
||||
.B "lesskey [\-o output] [\-\-] [input]"
|
||||
.br
|
||||
.B "lesskey [\-\-output=output] [\-\-] [input]"
|
||||
@ -10,38 +10,27 @@ lesskey \- specify key bindings for less
|
||||
.B "lesskey \-V"
|
||||
.br
|
||||
.B "lesskey \-\-version"
|
||||
.SH DESCRIPTION
|
||||
.I Lesskey
|
||||
is used to specify a set of key bindings to be used by
|
||||
.IR less .
|
||||
The input file is a text file which describes the key bindings.
|
||||
If the input file is "\-", standard input is read.
|
||||
If no input file is specified, a standard filename is used
|
||||
as the name of the input file, which depends on the system being used:
|
||||
On Unix systems, "$HOME/.lesskey" is used;
|
||||
on MS-DOS systems, "$HOME/_lesskey" is used;
|
||||
and on OS/2 systems "$HOME/lesskey.ini" is used,
|
||||
or "$INIT/lesskey.ini" if $HOME is undefined.
|
||||
The output file is a binary file which is used by
|
||||
.IR less .
|
||||
If no output file is specified,
|
||||
and the environment variable LESSKEY is set,
|
||||
the value of LESSKEY is used as the name of the output file.
|
||||
Otherwise, a standard filename is used as the name of the output file,
|
||||
which depends on the system being used:
|
||||
On Unix and OS-9 systems, "$HOME/.less" is used;
|
||||
on MS-DOS systems, "$HOME/_less" is used;
|
||||
and on OS/2 systems, "$HOME/less.ini" is used,
|
||||
or "$INIT/less.ini" if $HOME is undefined.
|
||||
If the output file already exists,
|
||||
.SH SCOPE
|
||||
This document describes the format of the
|
||||
.I lesskey
|
||||
will overwrite it.
|
||||
.PP
|
||||
The \-V or \-\-version option causes
|
||||
source file, which is used by
|
||||
.I less
|
||||
version 582 and later.
|
||||
In previous versions of
|
||||
.IR less ,
|
||||
a separate program called
|
||||
.I lesskey
|
||||
to print its version number and immediately exit.
|
||||
If \-V or \-\-version is present, other options and arguments are ignored.
|
||||
was used to compile the
|
||||
.I lesskey
|
||||
source file into a format understood by
|
||||
.IR less .
|
||||
This compilation step is no longer required and the
|
||||
.I lesskey
|
||||
program is therefore deprecated although the file format remains supported by
|
||||
.I less
|
||||
itself.
|
||||
.PP
|
||||
.SH FILE FORMAT
|
||||
The input file consists of one or more
|
||||
.I sections.
|
||||
Each section starts with a line that identifies the type of section.
|
||||
|
580
contrib/less/lesskey_parse.c
Normal file
580
contrib/less/lesskey_parse.c
Normal file
@ -0,0 +1,580 @@
|
||||
/*
|
||||
* Copyright (C) 1984-2021 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "lesskey.h"
|
||||
#include "cmd.h"
|
||||
#include "xbuf.h"
|
||||
#include "defines.h"
|
||||
|
||||
#define CONTROL(c) ((c)&037)
|
||||
#define ESC CONTROL('[')
|
||||
|
||||
extern void lesskey_parse_error(char *msg);
|
||||
extern char *homefile(char *filename);
|
||||
extern void *ecalloc(int count, unsigned int size);
|
||||
|
||||
static int linenum;
|
||||
static int errors;
|
||||
static char *lesskey_file;
|
||||
|
||||
static struct lesskey_cmdname cmdnames[] =
|
||||
{
|
||||
{ "back-bracket", A_B_BRACKET },
|
||||
{ "back-line", A_B_LINE },
|
||||
{ "back-line-force", A_BF_LINE },
|
||||
{ "back-screen", A_B_SCREEN },
|
||||
{ "back-scroll", A_B_SCROLL },
|
||||
{ "back-search", A_B_SEARCH },
|
||||
{ "back-window", A_B_WINDOW },
|
||||
{ "clear-mark", A_CLRMARK },
|
||||
{ "debug", A_DEBUG },
|
||||
{ "digit", A_DIGIT },
|
||||
{ "display-flag", A_DISP_OPTION },
|
||||
{ "display-option", A_DISP_OPTION },
|
||||
{ "end", A_GOEND },
|
||||
{ "end-scroll", A_RRSHIFT },
|
||||
{ "examine", A_EXAMINE },
|
||||
{ "filter", A_FILTER },
|
||||
{ "first-cmd", A_FIRSTCMD },
|
||||
{ "firstcmd", A_FIRSTCMD },
|
||||
{ "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-window", A_F_WINDOW },
|
||||
{ "goto-end", A_GOEND },
|
||||
{ "goto-end-buffered", A_GOEND_BUF },
|
||||
{ "goto-line", A_GOLINE },
|
||||
{ "goto-mark", A_GOMARK },
|
||||
{ "help", A_HELP },
|
||||
{ "index-file", A_INDEX_FILE },
|
||||
{ "invalid", A_UINVALID },
|
||||
{ "left-scroll", A_LSHIFT },
|
||||
{ "next-file", A_NEXT_FILE },
|
||||
{ "next-tag", A_NEXT_TAG },
|
||||
{ "noaction", A_NOACTION },
|
||||
{ "no-scroll", A_LLSHIFT },
|
||||
{ "percent", A_PERCENT },
|
||||
{ "pipe", A_PIPE },
|
||||
{ "prev-file", A_PREV_FILE },
|
||||
{ "prev-tag", A_PREV_TAG },
|
||||
{ "quit", A_QUIT },
|
||||
{ "remove-file", A_REMOVE_FILE },
|
||||
{ "repaint", A_REPAINT },
|
||||
{ "repaint-flush", A_FREPAINT },
|
||||
{ "repeat-search", A_AGAIN_SEARCH },
|
||||
{ "repeat-search-all", A_T_AGAIN_SEARCH },
|
||||
{ "reverse-search", A_REVERSE_SEARCH },
|
||||
{ "reverse-search-all", A_T_REVERSE_SEARCH },
|
||||
{ "right-scroll", A_RSHIFT },
|
||||
{ "set-mark", A_SETMARK },
|
||||
{ "set-mark-bottom", A_SETMARKBOT },
|
||||
{ "shell", A_SHELL },
|
||||
{ "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[] =
|
||||
{
|
||||
{ "back-complete", EC_B_COMPLETE },
|
||||
{ "backspace", EC_BACKSPACE },
|
||||
{ "delete", EC_DELETE },
|
||||
{ "down", EC_DOWN },
|
||||
{ "end", EC_END },
|
||||
{ "expand", EC_EXPAND },
|
||||
{ "forw-complete", EC_F_COMPLETE },
|
||||
{ "home", EC_HOME },
|
||||
{ "insert", EC_INSERT },
|
||||
{ "invalid", EC_UINVALID },
|
||||
{ "kill-line", EC_LINEKILL },
|
||||
{ "abort", EC_ABORT },
|
||||
{ "left", EC_LEFT },
|
||||
{ "literal", EC_LITERAL },
|
||||
{ "right", EC_RIGHT },
|
||||
{ "up", EC_UP },
|
||||
{ "word-backspace", EC_W_BACKSPACE },
|
||||
{ "word-delete", EC_W_DELETE },
|
||||
{ "word-left", EC_W_LEFT },
|
||||
{ "word-right", EC_W_RIGHT },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* Print a parse error message.
|
||||
*/
|
||||
static void
|
||||
parse_error(s1, s2)
|
||||
char *s1;
|
||||
char *s2;
|
||||
{
|
||||
char buf[1024];
|
||||
++errors;
|
||||
snprintf(buf, sizeof(buf), "%s: line %d: %s%s", lesskey_file, linenum, s1, s2);
|
||||
lesskey_parse_error(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize lesskey_tables.
|
||||
*/
|
||||
static void
|
||||
init_tables(tables)
|
||||
struct lesskey_tables *tables;
|
||||
{
|
||||
tables->currtable = &tables->cmdtable;
|
||||
|
||||
tables->cmdtable.names = cmdnames;
|
||||
tables->cmdtable.is_var = 0;
|
||||
xbuf_init(&tables->cmdtable.buf);
|
||||
|
||||
tables->edittable.names = editnames;
|
||||
tables->edittable.is_var = 0;
|
||||
xbuf_init(&tables->edittable.buf);
|
||||
|
||||
tables->vartable.names = NULL;
|
||||
tables->vartable.is_var = 1;
|
||||
xbuf_init(&tables->vartable.buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse one character of a string.
|
||||
*/
|
||||
static char *
|
||||
tstr(pp, xlate)
|
||||
char **pp;
|
||||
int xlate;
|
||||
{
|
||||
char *p;
|
||||
char ch;
|
||||
int i;
|
||||
static char buf[10];
|
||||
static char tstr_control_k[] =
|
||||
{ SK_SPECIAL_KEY, SK_CONTROL_K, 6, 1, 1, 1, '\0' };
|
||||
|
||||
p = *pp;
|
||||
switch (*p)
|
||||
{
|
||||
case '\\':
|
||||
++p;
|
||||
switch (*p)
|
||||
{
|
||||
case '0': case '1': case '2': case '3':
|
||||
case '4': case '5': case '6': case '7':
|
||||
/*
|
||||
* Parse an octal number.
|
||||
*/
|
||||
ch = 0;
|
||||
i = 0;
|
||||
do
|
||||
ch = 8*ch + (*p - '0');
|
||||
while (*++p >= '0' && *p <= '7' && ++i < 3);
|
||||
*pp = p;
|
||||
if (xlate && ch == CONTROL('K'))
|
||||
return tstr_control_k;
|
||||
buf[0] = ch;
|
||||
buf[1] = '\0';
|
||||
return (buf);
|
||||
case 'b':
|
||||
*pp = p+1;
|
||||
return ("\b");
|
||||
case 'e':
|
||||
*pp = p+1;
|
||||
buf[0] = ESC;
|
||||
buf[1] = '\0';
|
||||
return (buf);
|
||||
case 'n':
|
||||
*pp = p+1;
|
||||
return ("\n");
|
||||
case 'r':
|
||||
*pp = p+1;
|
||||
return ("\r");
|
||||
case 't':
|
||||
*pp = p+1;
|
||||
return ("\t");
|
||||
case 'k':
|
||||
if (xlate)
|
||||
{
|
||||
switch (*++p)
|
||||
{
|
||||
case 'u': ch = SK_UP_ARROW; break;
|
||||
case 'd': ch = SK_DOWN_ARROW; break;
|
||||
case 'r': ch = SK_RIGHT_ARROW; break;
|
||||
case 'l': ch = SK_LEFT_ARROW; break;
|
||||
case 'U': ch = SK_PAGE_UP; break;
|
||||
case 'D': ch = SK_PAGE_DOWN; break;
|
||||
case 'h': ch = SK_HOME; break;
|
||||
case 'e': ch = SK_END; break;
|
||||
case 'x': ch = SK_DELETE; break;
|
||||
default: { char buf[2]; buf[0] = *p; buf[1] = '\0';
|
||||
parse_error("illegal escape sequence \\k", buf);
|
||||
*pp = p+1;
|
||||
return (""); }
|
||||
}
|
||||
*pp = p+1;
|
||||
buf[0] = SK_SPECIAL_KEY;
|
||||
buf[1] = ch;
|
||||
buf[2] = 6;
|
||||
buf[3] = 1;
|
||||
buf[4] = 1;
|
||||
buf[5] = 1;
|
||||
buf[6] = '\0';
|
||||
return (buf);
|
||||
}
|
||||
/* FALLTHRU */
|
||||
default:
|
||||
/*
|
||||
* Backslash followed by any other char
|
||||
* just means that char.
|
||||
*/
|
||||
*pp = p+1;
|
||||
buf[0] = *p;
|
||||
buf[1] = '\0';
|
||||
if (xlate && buf[0] == CONTROL('K'))
|
||||
return tstr_control_k;
|
||||
return (buf);
|
||||
}
|
||||
case '^':
|
||||
/*
|
||||
* Caret means CONTROL.
|
||||
*/
|
||||
*pp = p+2;
|
||||
buf[0] = CONTROL(p[1]);
|
||||
buf[1] = '\0';
|
||||
if (xlate && buf[0] == CONTROL('K'))
|
||||
return tstr_control_k;
|
||||
return (buf);
|
||||
}
|
||||
*pp = p+1;
|
||||
buf[0] = *p;
|
||||
buf[1] = '\0';
|
||||
if (xlate && buf[0] == CONTROL('K'))
|
||||
return tstr_control_k;
|
||||
return (buf);
|
||||
}
|
||||
|
||||
static int
|
||||
issp(ch)
|
||||
char ch;
|
||||
{
|
||||
return (ch == ' ' || ch == '\t');
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip leading spaces in a string.
|
||||
*/
|
||||
static char *
|
||||
skipsp(s)
|
||||
char *s;
|
||||
{
|
||||
while (issp(*s))
|
||||
s++;
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip non-space characters in a string.
|
||||
*/
|
||||
static char *
|
||||
skipnsp(s)
|
||||
char *s;
|
||||
{
|
||||
while (*s != '\0' && !issp(*s))
|
||||
s++;
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up an input line:
|
||||
* strip off the trailing newline & any trailing # comment.
|
||||
*/
|
||||
static char *
|
||||
clean_line(s)
|
||||
char *s;
|
||||
{
|
||||
int i;
|
||||
|
||||
s = skipsp(s);
|
||||
for (i = 0; s[i] != '\0' && s[i] != '\n' && s[i] != '\r'; i++)
|
||||
if (s[i] == '#' && (i == 0 || s[i-1] != '\\'))
|
||||
break;
|
||||
s[i] = '\0';
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a byte to the output command table.
|
||||
*/
|
||||
static void
|
||||
add_cmd_char(c, tables)
|
||||
int c;
|
||||
struct lesskey_tables *tables;
|
||||
{
|
||||
xbuf_add(&tables->currtable->buf, c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a string to the output command table.
|
||||
*/
|
||||
static void
|
||||
add_cmd_str(s, tables)
|
||||
char *s;
|
||||
struct lesskey_tables *tables;
|
||||
{
|
||||
for ( ; *s != '\0'; s++)
|
||||
add_cmd_char(*s, tables);
|
||||
}
|
||||
|
||||
/*
|
||||
* See if we have a special "control" line.
|
||||
*/
|
||||
static int
|
||||
control_line(s, tables)
|
||||
char *s;
|
||||
struct lesskey_tables *tables;
|
||||
{
|
||||
#define PREFIX(str,pat) (strncmp(str,pat,strlen(pat)) == 0)
|
||||
|
||||
if (PREFIX(s, "#line-edit"))
|
||||
{
|
||||
tables->currtable = &tables->edittable;
|
||||
return (1);
|
||||
}
|
||||
if (PREFIX(s, "#command"))
|
||||
{
|
||||
tables->currtable = &tables->cmdtable;
|
||||
return (1);
|
||||
}
|
||||
if (PREFIX(s, "#env"))
|
||||
{
|
||||
tables->currtable = &tables->vartable;
|
||||
return (1);
|
||||
}
|
||||
if (PREFIX(s, "#stop"))
|
||||
{
|
||||
add_cmd_char('\0', tables);
|
||||
add_cmd_char(A_END_LIST, tables);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an action, given the name of the action.
|
||||
*/
|
||||
static int
|
||||
findaction(actname, tables)
|
||||
char *actname;
|
||||
struct lesskey_tables *tables;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; tables->currtable->names[i].cn_name != NULL; i++)
|
||||
if (strcmp(tables->currtable->names[i].cn_name, actname) == 0)
|
||||
return (tables->currtable->names[i].cn_action);
|
||||
parse_error("unknown action: ", actname);
|
||||
return (A_INVALID);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a line describing one key binding, of the form
|
||||
* KEY ACTION [EXTRA]
|
||||
* where KEY is the user key sequence, ACTION is the
|
||||
* resulting less action, and EXTRA is an "extra" user
|
||||
* key sequence injected after the action.
|
||||
*/
|
||||
static void
|
||||
parse_cmdline(p, tables)
|
||||
char *p;
|
||||
struct lesskey_tables *tables;
|
||||
{
|
||||
char *actname;
|
||||
int action;
|
||||
char *s;
|
||||
char c;
|
||||
|
||||
/*
|
||||
* Parse the command string and store it in the current table.
|
||||
*/
|
||||
do
|
||||
{
|
||||
s = tstr(&p, 1);
|
||||
add_cmd_str(s, tables);
|
||||
} while (*p != '\0' && !issp(*p));
|
||||
/*
|
||||
* Terminate the command string with a null byte.
|
||||
*/
|
||||
add_cmd_char('\0', tables);
|
||||
|
||||
/*
|
||||
* Skip white space between the command string
|
||||
* and the action name.
|
||||
* Terminate the action name with a null byte.
|
||||
*/
|
||||
p = skipsp(p);
|
||||
if (*p == '\0')
|
||||
{
|
||||
parse_error("missing action", "");
|
||||
return;
|
||||
}
|
||||
actname = p;
|
||||
p = skipnsp(p);
|
||||
c = *p;
|
||||
*p = '\0';
|
||||
|
||||
/*
|
||||
* Parse the action name and store it in the current table.
|
||||
*/
|
||||
action = findaction(actname, tables);
|
||||
|
||||
/*
|
||||
* See if an extra string follows the action name.
|
||||
*/
|
||||
*p = c;
|
||||
p = skipsp(p);
|
||||
if (*p == '\0')
|
||||
{
|
||||
add_cmd_char(action, tables);
|
||||
} else
|
||||
{
|
||||
/*
|
||||
* OR the special value A_EXTRA into the action byte.
|
||||
* Put the extra string after the action byte.
|
||||
*/
|
||||
add_cmd_char(action | A_EXTRA, tables);
|
||||
while (*p != '\0')
|
||||
add_cmd_str(tstr(&p, 0), tables);
|
||||
add_cmd_char('\0', tables);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a variable definition line, of the form
|
||||
* NAME = VALUE
|
||||
*/
|
||||
static void
|
||||
parse_varline(line, tables)
|
||||
char *line;
|
||||
struct lesskey_tables *tables;
|
||||
{
|
||||
char *s;
|
||||
char *p = line;
|
||||
|
||||
do
|
||||
{
|
||||
s = tstr(&p, 0);
|
||||
add_cmd_str(s, tables);
|
||||
} while (*p != '\0' && !issp(*p) && *p != '=');
|
||||
/*
|
||||
* Terminate the variable name with a null byte.
|
||||
*/
|
||||
add_cmd_char('\0', tables);
|
||||
|
||||
p = skipsp(p);
|
||||
if (*p++ != '=')
|
||||
{
|
||||
parse_error("missing = in: ", line);
|
||||
return;
|
||||
}
|
||||
|
||||
add_cmd_char(EV_OK|A_EXTRA, tables);
|
||||
|
||||
p = skipsp(p);
|
||||
while (*p != '\0')
|
||||
{
|
||||
s = tstr(&p, 0);
|
||||
add_cmd_str(s, tables);
|
||||
}
|
||||
add_cmd_char('\0', tables);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a line from the lesskey file.
|
||||
*/
|
||||
static void
|
||||
parse_line(line, tables)
|
||||
char *line;
|
||||
struct lesskey_tables *tables;
|
||||
{
|
||||
char *p;
|
||||
|
||||
/*
|
||||
* See if it is a control line.
|
||||
*/
|
||||
if (control_line(line, tables))
|
||||
return;
|
||||
/*
|
||||
* Skip leading white space.
|
||||
* Replace the final newline with a null byte.
|
||||
* Ignore blank lines and comments.
|
||||
*/
|
||||
p = clean_line(line);
|
||||
if (*p == '\0')
|
||||
return;
|
||||
|
||||
if (tables->currtable->is_var)
|
||||
parse_varline(p, tables);
|
||||
else
|
||||
parse_cmdline(p, tables);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse a lesskey source file and store result in tables.
|
||||
*/
|
||||
int
|
||||
parse_lesskey(infile, tables)
|
||||
char *infile;
|
||||
struct lesskey_tables *tables;
|
||||
{
|
||||
FILE *desc;
|
||||
char line[1024];
|
||||
|
||||
if (infile == NULL)
|
||||
infile = homefile(DEF_LESSKEYINFILE);
|
||||
lesskey_file = infile;
|
||||
|
||||
init_tables(tables);
|
||||
errors = 0;
|
||||
linenum = 0;
|
||||
|
||||
/*
|
||||
* Open the input file.
|
||||
*/
|
||||
if (strcmp(infile, "-") == 0)
|
||||
desc = stdin;
|
||||
else if ((desc = fopen(infile, "r")) == NULL)
|
||||
{
|
||||
/* parse_error("cannot open lesskey file ", infile); */
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read and parse the input file, one line at a time.
|
||||
*/
|
||||
while (fgets(line, sizeof(line), desc) != NULL)
|
||||
{
|
||||
++linenum;
|
||||
parse_line(line, tables);
|
||||
}
|
||||
|
||||
return (errors);
|
||||
}
|
@ -33,11 +33,8 @@ static struct {
|
||||
int pfx_end; /* Number of chars in pfx */
|
||||
} linebuf;
|
||||
|
||||
static struct {
|
||||
char *buf;
|
||||
int size;
|
||||
int end;
|
||||
} shifted_ansi;
|
||||
struct xbuffer shifted_ansi;
|
||||
struct xbuffer last_ansi;
|
||||
|
||||
public int size_linebuf = 0; /* Size of line buffer (and attr buffer) */
|
||||
static struct ansi_state *line_ansi = NULL;
|
||||
@ -58,6 +55,7 @@ static LWCHAR pendc;
|
||||
static POSITION pendpos;
|
||||
static char *end_ansi_chars;
|
||||
static char *mid_ansi_chars;
|
||||
static int in_hilite;
|
||||
|
||||
static int attr_swidth LESSPARAMS ((int a));
|
||||
static int attr_ewidth LESSPARAMS ((int a));
|
||||
@ -131,8 +129,8 @@ init_line(VOID_PARAM)
|
||||
linebuf.buf = (char *) ecalloc(LINEBUF_SIZE, sizeof(char));
|
||||
linebuf.attr = (int *) ecalloc(LINEBUF_SIZE, sizeof(int));
|
||||
size_linebuf = LINEBUF_SIZE;
|
||||
shifted_ansi.buf = NULL;
|
||||
shifted_ansi.size = 0;
|
||||
xbuf_init(&shifted_ansi);
|
||||
xbuf_init(&last_ansi);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -222,7 +220,9 @@ prewind(VOID_PARAM)
|
||||
mbc_buf_len = 0;
|
||||
is_null_line = 0;
|
||||
pendc = '\0';
|
||||
shifted_ansi.end = 0;
|
||||
in_hilite = 0;
|
||||
xbuf_reset(&shifted_ansi);
|
||||
xbuf_reset(&last_ansi);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -354,26 +354,6 @@ line_pfx_width(VOID_PARAM)
|
||||
return width;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add char to the shifted_ansi buffer.
|
||||
*/
|
||||
static void
|
||||
add_ansi(ch)
|
||||
char ch;
|
||||
{
|
||||
if (shifted_ansi.end == shifted_ansi.size)
|
||||
{
|
||||
/* Expand shifted_ansi buffer. */
|
||||
int size = (shifted_ansi.size == 0) ? 8 : shifted_ansi.size * 2;
|
||||
char *buf = (char *) ecalloc(size, sizeof(char));
|
||||
memcpy(buf, shifted_ansi.buf, shifted_ansi.size);
|
||||
if (shifted_ansi.buf != NULL) free(shifted_ansi.buf);
|
||||
shifted_ansi.buf = buf;
|
||||
shifted_ansi.size = size;
|
||||
}
|
||||
shifted_ansi.buf[shifted_ansi.end++] = ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* Shift line left so that the last char is just to the left
|
||||
* of the first visible column.
|
||||
@ -384,7 +364,7 @@ pshift_all(VOID_PARAM)
|
||||
int i;
|
||||
for (i = linebuf.print; i < linebuf.end; i++)
|
||||
if (linebuf.attr[i] == AT_ANSI)
|
||||
add_ansi(linebuf.buf[i]);
|
||||
xbuf_add(&shifted_ansi, linebuf.buf[i]);
|
||||
linebuf.end = linebuf.print;
|
||||
end_column = linebuf.pfx_end;
|
||||
}
|
||||
@ -676,6 +656,7 @@ store_char(ch, a, rep, pos)
|
||||
#if HILITE_SEARCH
|
||||
{
|
||||
int matches;
|
||||
int resend_last = 0;
|
||||
int hl_attr = is_hilited_attr(pos, pos+1, 0, &matches);
|
||||
if (hl_attr)
|
||||
{
|
||||
@ -689,6 +670,23 @@ store_char(ch, a, rep, pos)
|
||||
highest_hilite = pos;
|
||||
a |= hl_attr;
|
||||
}
|
||||
in_hilite = 1;
|
||||
} else
|
||||
{
|
||||
if (in_hilite)
|
||||
{
|
||||
/*
|
||||
* This is the first non-hilited char after a hilite.
|
||||
* Resend the last ANSI seq to restore color.
|
||||
*/
|
||||
resend_last = 1;
|
||||
}
|
||||
in_hilite = 0;
|
||||
}
|
||||
if (resend_last)
|
||||
{
|
||||
for (i = 0; i < last_ansi.end; i++)
|
||||
STORE_CHAR(last_ansi.data[i], AT_ANSI, NULL, pos);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -731,8 +729,8 @@ store_char(ch, a, rep, pos)
|
||||
{
|
||||
/* Copy shifted ANSI sequences to beginning of line. */
|
||||
for (i = 0; i < shifted_ansi.end; i++)
|
||||
add_linebuf(shifted_ansi.buf[i], AT_ANSI, 0);
|
||||
shifted_ansi.end = 0;
|
||||
add_linebuf(shifted_ansi.data[i], AT_ANSI, 0);
|
||||
xbuf_reset(&shifted_ansi);
|
||||
}
|
||||
/* Add the char to the buf, even if we will left-shift it next. */
|
||||
inc_end_column(w);
|
||||
@ -743,12 +741,16 @@ store_char(ch, a, rep, pos)
|
||||
{
|
||||
/* We haven't left-shifted enough yet. */
|
||||
if (a == AT_ANSI)
|
||||
add_ansi(ch); /* Save ANSI attributes */
|
||||
xbuf_add(&shifted_ansi, ch); /* Save ANSI attributes */
|
||||
if (linebuf.end > linebuf.print)
|
||||
{
|
||||
/* Shift left enough to put last byte of this char at print-1. */
|
||||
memcpy(&linebuf.buf[0], &linebuf.buf[replen], linebuf.print);
|
||||
memcpy(&linebuf.attr[0], &linebuf.attr[replen], linebuf.print);
|
||||
int i;
|
||||
for (i = 0; i < linebuf.print; i++)
|
||||
{
|
||||
linebuf.buf[i] = linebuf.buf[i+replen];
|
||||
linebuf.attr[i] = linebuf.attr[i+replen];
|
||||
}
|
||||
linebuf.end -= replen;
|
||||
cshift += w;
|
||||
/*
|
||||
@ -954,16 +956,18 @@ store_ansi(ch, rep, pos)
|
||||
switch (ansi_step(line_ansi, ch))
|
||||
{
|
||||
case ANSI_MID:
|
||||
STORE_CHAR(ch, AT_ANSI, rep, pos);
|
||||
if (!in_hilite)
|
||||
STORE_CHAR(ch, AT_ANSI, rep, pos);
|
||||
break;
|
||||
case ANSI_END:
|
||||
STORE_CHAR(ch, AT_ANSI, rep, pos);
|
||||
if (!in_hilite)
|
||||
STORE_CHAR(ch, AT_ANSI, rep, pos);
|
||||
ansi_done(line_ansi);
|
||||
line_ansi = NULL;
|
||||
break;
|
||||
case ANSI_ERR: {
|
||||
/* Remove whole unrecognized sequence. */
|
||||
char *start = (cshift < hshift) ? shifted_ansi.buf : linebuf.buf;
|
||||
char *start = (cshift < hshift) ? shifted_ansi.data : linebuf.buf;
|
||||
int *end = (cshift < hshift) ? &shifted_ansi.end : &linebuf.end;
|
||||
char *p = start + *end;
|
||||
LWCHAR bch;
|
||||
@ -1006,10 +1010,17 @@ do_append(ch, rep, pos)
|
||||
int a = AT_NORMAL;
|
||||
|
||||
if (ctldisp == OPT_ONPLUS && line_ansi == NULL)
|
||||
{
|
||||
line_ansi = ansi_start(ch);
|
||||
if (line_ansi != NULL)
|
||||
xbuf_reset(&last_ansi);
|
||||
}
|
||||
|
||||
if (line_ansi != NULL)
|
||||
{
|
||||
xbuf_add(&last_ansi, ch);
|
||||
return store_ansi(ch, rep, pos);
|
||||
}
|
||||
|
||||
if (ch == '\b')
|
||||
return store_bs(ch, rep, pos);
|
||||
|
@ -469,3 +469,26 @@ currline(where)
|
||||
linenum--;
|
||||
return (linenum);
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan entire file, counting line numbers.
|
||||
*/
|
||||
public void
|
||||
scan_eof(VOID_PARAM)
|
||||
{
|
||||
POSITION pos = 0;
|
||||
LINENUM linenum = 0;
|
||||
|
||||
if (ch_seek(0))
|
||||
return;
|
||||
ierror("Determining length of file", NULL_PARG);
|
||||
while (pos != NULL_POSITION)
|
||||
{
|
||||
/* For efficiency, only add one every 256 line numbers. */
|
||||
if ((linenum++ % 256) == 0)
|
||||
add_lnum(linenum, pos);
|
||||
pos = forw_raw_line(pos, (char **)NULL, (int *)NULL);
|
||||
if (ABORT_SIGS())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ extern int less_is_more;
|
||||
extern int linenum_width;
|
||||
extern int status_col_width;
|
||||
extern int use_color;
|
||||
extern int want_filesize;
|
||||
#if LOGFILE
|
||||
extern char *namelogfile;
|
||||
extern int force_logfile;
|
||||
@ -163,7 +164,7 @@ opt_j(type, s)
|
||||
char *s;
|
||||
{
|
||||
PARG parg;
|
||||
char buf[16];
|
||||
char buf[24];
|
||||
int len;
|
||||
int err;
|
||||
|
||||
@ -199,7 +200,7 @@ opt_j(type, s)
|
||||
} else
|
||||
{
|
||||
|
||||
sprintf(buf, ".%06ld", jump_sline_fraction);
|
||||
SNPRINTF1(buf, sizeof(buf), ".%06ld", jump_sline_fraction);
|
||||
len = (int) strlen(buf);
|
||||
while (len > 2 && buf[len-1] == '0')
|
||||
len--;
|
||||
@ -228,7 +229,7 @@ opt_shift(type, s)
|
||||
char *s;
|
||||
{
|
||||
PARG parg;
|
||||
char buf[16];
|
||||
char buf[24];
|
||||
int len;
|
||||
int err;
|
||||
|
||||
@ -264,7 +265,7 @@ opt_shift(type, s)
|
||||
} else
|
||||
{
|
||||
|
||||
sprintf(buf, ".%06ld", shift_count_fraction);
|
||||
SNPRINTF1(buf, sizeof(buf), ".%06ld", shift_count_fraction);
|
||||
len = (int) strlen(buf);
|
||||
while (len > 2 && buf[len-1] == '0')
|
||||
len--;
|
||||
@ -275,6 +276,7 @@ opt_shift(type, s)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void
|
||||
calc_shift_count(VOID_PARAM)
|
||||
{
|
||||
@ -302,7 +304,28 @@ opt_k(type, s)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_LESSKEYSRC
|
||||
public void
|
||||
opt_ks(type, s)
|
||||
int type;
|
||||
char *s;
|
||||
{
|
||||
PARG parg;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case INIT:
|
||||
if (lesskey_src(s, 0))
|
||||
{
|
||||
parg.p_string = s;
|
||||
error("Cannot use lesskey source file \"%s\"", &parg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_LESSKEYSRC */
|
||||
#endif /* USERFILE */
|
||||
|
||||
#if TAGS
|
||||
/*
|
||||
@ -518,9 +541,8 @@ opt__V(type, s)
|
||||
putstr(pattern_lib_name());
|
||||
putstr(" regular expressions)\n");
|
||||
{
|
||||
char constant *copyright = "Copyright (C) 1984-2021 Mark Nudelman\n\n";
|
||||
if (copyright[0] == '@')
|
||||
copyright = "Copyright (C) 1984 Mark Nudelman\n\n";
|
||||
char constant *copyright =
|
||||
"Copyright (C) 1984-2021 Mark Nudelman\n\n";
|
||||
putstr(copyright);
|
||||
}
|
||||
if (version[strlen(version)-1] == 'x')
|
||||
@ -590,7 +612,7 @@ color_from_namechar(namechar)
|
||||
{
|
||||
switch (namechar)
|
||||
{
|
||||
case 'A': return AT_COLOR_ATTN;
|
||||
case 'W': case 'A': return AT_COLOR_ATTN;
|
||||
case 'B': return AT_COLOR_BIN;
|
||||
case 'C': return AT_COLOR_CTRL;
|
||||
case 'E': return AT_COLOR_ERROR;
|
||||
@ -940,6 +962,27 @@ opt_status_col_width(type, s)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler for the --file-size option.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
public void
|
||||
opt_filesize(type, s)
|
||||
int type;
|
||||
char *s;
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case INIT:
|
||||
case TOGGLE:
|
||||
if (want_filesize && curr_ifile != NULL && ch_length() == NULL_POSITION)
|
||||
scan_eof();
|
||||
break;
|
||||
case QUERY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if LESSTEST
|
||||
/*
|
||||
* Handler for the --tty option.
|
||||
|
@ -63,6 +63,7 @@ public int linenum_width; /* Width of line numbers */
|
||||
public int status_col_width; /* Width of status column */
|
||||
public int incr_search; /* Incremental search */
|
||||
public int use_color; /* Use UI color */
|
||||
public int want_filesize; /* */
|
||||
#if HILITE_SEARCH
|
||||
public int hilite_search; /* Highlight matched search patterns? */
|
||||
#endif
|
||||
@ -90,6 +91,9 @@ static struct optname j_optname = { "jump-target", NULL };
|
||||
static struct optname J__optname = { "status-column", NULL };
|
||||
#if USERFILE
|
||||
static struct optname k_optname = { "lesskey-file", NULL };
|
||||
#if HAVE_LESSKEYSRC
|
||||
static struct optname ks_optname = { "lesskey-src", NULL };
|
||||
#endif /* HAVE_LESSKEYSRC */
|
||||
#endif
|
||||
static struct optname K__optname = { "quit-on-intr", NULL };
|
||||
static struct optname L__optname = { "no-lessopen", NULL };
|
||||
@ -134,6 +138,7 @@ static struct optname linenum_width_optname = { "line-num-width", NULL };
|
||||
static struct optname status_col_width_optname = { "status-col-width", NULL };
|
||||
static struct optname incr_search_optname = { "incsearch", NULL };
|
||||
static struct optname use_color_optname = { "use-color", NULL };
|
||||
static struct optname want_filesize_optname = { "file-size", NULL };
|
||||
#if LESSTEST
|
||||
static struct optname ttyin_name_optname = { "tty", NULL };
|
||||
static struct optname rstat_optname = { "rstat", NULL };
|
||||
@ -274,6 +279,12 @@ static struct loption option[] =
|
||||
STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_k,
|
||||
{ NULL, NULL, NULL }
|
||||
},
|
||||
#if HAVE_LESSKEYSRC
|
||||
{ OLETTER_NONE, &ks_optname,
|
||||
STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_ks,
|
||||
{ NULL, NULL, NULL }
|
||||
},
|
||||
#endif /* HAVE_LESSKEYSRC */
|
||||
#endif
|
||||
{ 'K', &K__optname,
|
||||
BOOL, OPT_OFF, &quit_on_intr, NULL,
|
||||
@ -337,8 +348,8 @@ static struct loption option[] =
|
||||
TRIPLE|REPAINT, OPT_OFF, &ctldisp, NULL,
|
||||
{
|
||||
"Display control characters as ^X",
|
||||
"Display control characters directly",
|
||||
"Display control characters directly, processing ANSI sequences"
|
||||
"Display control characters directly (not recommended)",
|
||||
"Display ANSI sequences directly, other control characters as ^X"
|
||||
}
|
||||
},
|
||||
{ 's', &s_optname,
|
||||
@ -543,6 +554,14 @@ static struct loption option[] =
|
||||
NULL
|
||||
}
|
||||
},
|
||||
{ OLETTER_NONE, &want_filesize_optname,
|
||||
BOOL|REPAINT, OPT_OFF, &want_filesize, opt_filesize,
|
||||
{
|
||||
"Don't get size of each file",
|
||||
"Get size of each file",
|
||||
NULL
|
||||
}
|
||||
},
|
||||
#if LESSTEST
|
||||
{ OLETTER_NONE, &ttyin_name_optname,
|
||||
STRING|NO_TOGGLE, 0, NULL, opt_ttyin_name,
|
||||
|
@ -431,11 +431,7 @@ putchr(c)
|
||||
ubuf_len = 0;
|
||||
}
|
||||
#endif
|
||||
if (need_clr)
|
||||
{
|
||||
need_clr = 0;
|
||||
clear_bot();
|
||||
}
|
||||
clear_bot_if_needed();
|
||||
#if MSDOS_COMPILER
|
||||
if (c == '\n' && is_tty)
|
||||
{
|
||||
@ -459,6 +455,15 @@ putchr(c)
|
||||
return (c);
|
||||
}
|
||||
|
||||
public void
|
||||
clear_bot_if_needed(VOID_PARAM)
|
||||
{
|
||||
if (!need_clr)
|
||||
return;
|
||||
need_clr = 0;
|
||||
clear_bot();
|
||||
}
|
||||
|
||||
/*
|
||||
* Output a string.
|
||||
*/
|
||||
|
@ -843,10 +843,10 @@ scrsize(VOID_PARAM)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ((s = lgetenv("LINES")) != NULL)
|
||||
sc_height = atoi(s);
|
||||
else if (sys_height > 0)
|
||||
if (sys_height > 0)
|
||||
sc_height = sys_height;
|
||||
else if ((s = lgetenv("LINES")) != NULL)
|
||||
sc_height = atoi(s);
|
||||
#if !MSDOS_COMPILER
|
||||
else if ((n = ltgetnum("li")) > 0)
|
||||
sc_height = n;
|
||||
@ -854,10 +854,10 @@ scrsize(VOID_PARAM)
|
||||
if (sc_height <= 0)
|
||||
sc_height = DEF_SC_HEIGHT;
|
||||
|
||||
if ((s = lgetenv("COLUMNS")) != NULL)
|
||||
sc_width = atoi(s);
|
||||
else if (sys_width > 0)
|
||||
if (sys_width > 0)
|
||||
sc_width = sys_width;
|
||||
else if ((s = lgetenv("COLUMNS")) != NULL)
|
||||
sc_width = atoi(s);
|
||||
#if !MSDOS_COMPILER
|
||||
else if ((n = ltgetnum("co")) > 0)
|
||||
sc_width = n;
|
||||
@ -1707,6 +1707,7 @@ deinit_mouse(VOID_PARAM)
|
||||
public void
|
||||
init(VOID_PARAM)
|
||||
{
|
||||
clear_bot_if_needed();
|
||||
#if !MSDOS_COMPILER
|
||||
if (!(quit_if_one_screen && one_screen))
|
||||
{
|
||||
@ -2526,7 +2527,7 @@ tput_fmt(fmt, color, f_putc)
|
||||
int color;
|
||||
int (*f_putc)(int);
|
||||
{
|
||||
char buf[16];
|
||||
char buf[32];
|
||||
if (color == attrcolor)
|
||||
return;
|
||||
SNPRINTF1(buf, sizeof(buf), fmt, color);
|
||||
|
@ -272,6 +272,7 @@ findctag(tag)
|
||||
char *tag;
|
||||
{
|
||||
char *p;
|
||||
char *q;
|
||||
FILE *f;
|
||||
int taglen;
|
||||
LINENUM taglinenum;
|
||||
@ -352,17 +353,24 @@ findctag(tag)
|
||||
search_char = *p++;
|
||||
if (*p == '^')
|
||||
p++;
|
||||
tagpattern = p;
|
||||
tagpattern = q = p;
|
||||
while (*p != search_char && *p != '\0')
|
||||
{
|
||||
if (*p == '\\')
|
||||
p++;
|
||||
p++;
|
||||
if (q != p)
|
||||
{
|
||||
*q++ = *p++;
|
||||
} else
|
||||
{
|
||||
q++;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
tagendline = (p[-1] == '$');
|
||||
tagendline = (q[-1] == '$');
|
||||
if (tagendline)
|
||||
p--;
|
||||
*p = '\0';
|
||||
q--;
|
||||
*q = '\0';
|
||||
}
|
||||
tp = maketagent(tag, tagfile, taglinenum, tagpattern, tagendline);
|
||||
TAG_INS(tp);
|
||||
|
@ -919,7 +919,18 @@ v578 2/9/21 Doc
|
||||
v579 2/14/21 Fix double-width char bugs and non-match search crash.
|
||||
v580 3/2/21 Some color fixes; fix compiler warnings; some lesstest support.
|
||||
v581 4/6/21 Ignore SIGTSTP in secure mode; don't print "skipping" when filtering.
|
||||
v581.2 4/28/21 Fix failure to deinit mouse.
|
||||
v582 4/21/21 Less now reads lesskey source file rather than binary;
|
||||
fix bug in finding tags with backslashes.
|
||||
v583 4/21/21 Use XDG_CONFIG_HOME and XDG_DATA_HOME to find files.
|
||||
v584 4/30/21 Add --file-size option.
|
||||
v585 5/2/21 Allow color desc W per man page.
|
||||
v586 5/7/21 Doc changes.
|
||||
v587 5/27/21 Fix --with-secure; fix --file-size message on Windows;
|
||||
fix colored search hilite in colored text; don't exit
|
||||
if -F and screen is resized; fix memcpy usage.
|
||||
v588 5/27/21 Fix release.
|
||||
v589 5/29/21 Copyright & build changes.
|
||||
v590 6/3/21 Fix non-autoconf Makefiles.
|
||||
*/
|
||||
|
||||
char version[] = "581.2";
|
||||
char version[] = "590";
|
||||
|
52
contrib/less/xbuf.c
Normal file
52
contrib/less/xbuf.c
Normal file
@ -0,0 +1,52 @@
|
||||
#include "less.h"
|
||||
#include "xbuf.h"
|
||||
|
||||
/*
|
||||
* Initialize an expandable text buffer.
|
||||
*/
|
||||
public void
|
||||
xbuf_init(xbuf)
|
||||
struct xbuffer *xbuf;
|
||||
{
|
||||
xbuf->data = NULL;
|
||||
xbuf->size = xbuf->end = 0;
|
||||
}
|
||||
|
||||
public void
|
||||
xbuf_deinit(xbuf)
|
||||
struct xbuffer *xbuf;
|
||||
{
|
||||
if (xbuf->data != NULL)
|
||||
free(xbuf->data);
|
||||
xbuf_init(xbuf);
|
||||
}
|
||||
|
||||
public void
|
||||
xbuf_reset(xbuf)
|
||||
struct xbuffer *xbuf;
|
||||
{
|
||||
xbuf->end = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a char to an expandable text buffer.
|
||||
*/
|
||||
public void
|
||||
xbuf_add(xbuf, ch)
|
||||
struct xbuffer *xbuf;
|
||||
char ch;
|
||||
{
|
||||
if (xbuf->end >= xbuf->size)
|
||||
{
|
||||
char *data;
|
||||
xbuf->size = (xbuf->size == 0) ? 16 : xbuf->size * 2;
|
||||
data = (char *) ecalloc(xbuf->size, sizeof(char));
|
||||
if (xbuf->data != NULL)
|
||||
{
|
||||
memcpy(data, xbuf->data, xbuf->end);
|
||||
free(xbuf->data);
|
||||
}
|
||||
xbuf->data = data;
|
||||
}
|
||||
xbuf->data[xbuf->end++] = ch;
|
||||
}
|
15
contrib/less/xbuf.h
Normal file
15
contrib/less/xbuf.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef XBUF_H_
|
||||
#define XBUF_H_
|
||||
|
||||
struct xbuffer
|
||||
{
|
||||
char *data;
|
||||
int end;
|
||||
int size;
|
||||
};
|
||||
|
||||
void xbuf_init(struct xbuffer *xbuf);
|
||||
void xbuf_reset(struct xbuffer *xbuf);
|
||||
void xbuf_add(struct xbuffer *xbuf, char ch);
|
||||
|
||||
#endif
|
@ -5,7 +5,7 @@ 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 \
|
||||
jump.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 \
|
||||
signal.c tags.c ttyin.c version.c
|
||||
signal.c tags.c ttyin.c version.c xbuf.c
|
||||
SCRIPTS=lesspipe.sh zless.sh
|
||||
SCRIPTSNAME_lesspipe.sh=lesspipe.sh
|
||||
LIBADD= ncursesw
|
||||
|
@ -81,7 +81,7 @@
|
||||
* PIPEC is 1 if you wish to have the "|" command
|
||||
* which allows the user to pipe data into a shell command.
|
||||
*/
|
||||
#define PIPEC (!SECURE)
|
||||
#define PIPEC (!SECURE && HAVE_POPEN)
|
||||
|
||||
/*
|
||||
* LOGFILE is 1 if you wish to allow the -o option (to create log files).
|
||||
@ -113,6 +113,7 @@
|
||||
#define LESSKEYFILE ".less"
|
||||
#define LESSKEYFILE_SYS "/etc/lesskey"
|
||||
#define DEF_LESSKEYINFILE ".lesskey"
|
||||
#define LESSKEYINFILE_SYS "/etc/syslesskey"
|
||||
#define LESSHISTFILE ".lesshst"
|
||||
|
||||
|
||||
@ -185,6 +186,9 @@
|
||||
/* Define to 1 if you have the strstr() function. */
|
||||
#define HAVE_STRSTR 1
|
||||
|
||||
/* Define to 1 to support reading lesskey source files (not just binary). */
|
||||
#define HAVE_LESSKEYSRC 1
|
||||
|
||||
/*
|
||||
* Sizes of various buffers.
|
||||
*/
|
||||
|
@ -1,7 +1,7 @@
|
||||
# $FreeBSD$
|
||||
|
||||
PROG= lesskey
|
||||
SRCS= lesskey.c version.c
|
||||
SRCS= lesskey.c lesskey_parse.c version.c xbuf.c
|
||||
CLEANFILES= lesskey.1
|
||||
|
||||
.include "${SRCTOP}/usr.bin/less/Makefile.common"
|
||||
|
Loading…
Reference in New Issue
Block a user