From 1f8b3bb911e37330e00dab1b1e6cba65c573e63c Mon Sep 17 00:00:00 2001 From: Xin LI Date: Sat, 17 Jul 2021 22:00:54 -0700 Subject: [PATCH] Vendor import of less v590. --- Makefile.aut | 70 +++--- Makefile.dsb | 8 +- Makefile.dsg | 8 +- Makefile.dsu | 8 +- Makefile.in | 13 +- Makefile.o2e | 8 +- Makefile.o9c | 8 +- Makefile.o9u | 8 +- Makefile.wnb | 6 +- Makefile.wng | 10 +- Makefile.wnm | 8 +- NEWS | 30 ++- README | 9 +- ch.c | 2 +- cmdbuf.c | 31 ++- command.c | 1 + configure | 5 + configure.ac | 10 +- decode.c | 95 ++++++-- defines.ds | 4 + defines.h.in | 6 +- defines.o2 | 4 + defines.o9 | 4 + defines.wn | 4 + edit.c | 4 +- filename.c | 57 +++-- funcs.h | 12 +- help.c | 4 +- less.h | 1 + less.hlp | 2 + less.man | 503 ++++++++++++++++++++------------------- less.nro | 102 +++++--- lessecho.man | 2 +- lessecho.nro | 2 +- lesskey.c | 607 ++++-------------------------------------------- lesskey.h | 24 ++ lesskey.man | 38 ++- lesskey.nro | 51 ++-- lesskey_parse.c | 580 +++++++++++++++++++++++++++++++++++++++++++++ line.c | 85 ++++--- linenum.c | 23 ++ optfunc.c | 61 ++++- opttbl.c | 23 +- output.c | 15 +- screen.c | 15 +- tags.c | 18 +- version.c | 15 +- xbuf.c | 52 +++++ xbuf.h | 15 ++ 49 files changed, 1572 insertions(+), 1099 deletions(-) create mode 100644 lesskey_parse.c create mode 100644 xbuf.c create mode 100644 xbuf.h diff --git a/Makefile.aut b/Makefile.aut index b6f2101cf10f..f0eb26d41e23 100644 --- a/Makefile.aut +++ b/Makefile.aut @@ -7,6 +7,7 @@ GIT = git NROFF = nroff -t -man srcdir = . +REL := $(shell sed -e '/char version/!d' -e 's/[^0-9.]*\([0-9.]*\).*/\1/' -e q ${srcdir}/version.c) ifeq ($(USE_PYTHON),1) MKHELP = mkhelp.py @@ -22,7 +23,7 @@ SRC = \ 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 + tags.c ttyin.c version.c xbuf.c DISTFILES_W = \ defines.ds Makefile.dsb Makefile.dsg Makefile.dsu \ defines.o2 Makefile.o2e \ @@ -34,9 +35,9 @@ UNICODE_FILES = \ DISTFILES = \ ${SRC} regexp.c regexp.h \ COPYING INSTALL LICENSE Makefile.in Makefile.aut NEWS README \ - configure.ac lesskey.c lessecho.c scrsize.c \ + configure.ac lesskey.c lesskey_parse.c lessecho.c scrsize.c \ charset.h cmd.h funcs.h lglob.h less.h lesskey.h option.h \ - pckeys.h pattern.h position.h \ + pckeys.h pattern.h position.h xbuf.h \ install.sh defines.h.in mkinstalldirs \ less.nro less.man lesskey.nro lesskey.man lessecho.nro lessecho.man \ less.hlp \ @@ -48,6 +49,7 @@ DISTFILES = \ all: help.c funcs.h $(UNICODE_FILES) ${srcdir}/configure release: .FORCE + @if grep -s 'Major changes between .*${REL}' NEWS ; then :; else echo '*** NEWS is not updated for ${REL}'; exit 1; fi ${MAKE} -f Makefile.aut tagall ${MAKE} -f Makefile.aut all ${MAKE} -f Makefile.aut clean @@ -75,26 +77,19 @@ lint: clean: rm -f Makefile config.status config.log config.cache defines.h stamp-h \ configure defines.h.in funcs.h help.c \ - README NEWS \ less.nro less.man lesskey.nro lesskey.man lessecho.nro lessecho.man distclean: clean realclean: clean REPLACE_VERSION = \ - @REL=`sed -e '/char version/!d' -e 's/[^0-9.]*\([0-9.]*\).*/\1/' -e q ${srcdir}/version.c`; \ DT=`date '+%d %h %Y'`; \ - echo "Stuffing version number $$REL into $@"; \ + echo "Stuffing version number ${REL} into $@"; \ rm -f $@; \ sed \ - -e "s;@@VERSION@@;$$REL;" \ - -e "s;@@DATE@@;$$DT;" \ - -e "s;@@HOMEPAGE@@;${HOMEPAGE};" >$@ + -e "s;@@VERSION@@;${REL};" \ + -e "s;@@DATE@@;$$DT;" >$@ -${srcdir}/README: ${srcdir}/README.VER ${srcdir}/version.c - ${REPLACE_VERSION} ${srcdir}/README.VER -${srcdir}/NEWS: ${srcdir}/NEWS.VER ${srcdir}/version.c - ${REPLACE_VERSION} ${srcdir}/NEWS.VER ${srcdir}/less.nro: ${srcdir}/less.nro.VER ${srcdir}/version.c ${REPLACE_VERSION} ${srcdir}/less.nro.VER ${srcdir}/lesskey.nro: ${srcdir}/lesskey.nro.VER ${srcdir}/version.c @@ -127,27 +122,36 @@ unicode/EastAsianWidth.txt: distfiles: ${DISTFILES} +echo_distfiles: + echo ${DISTFILES} + dist: ${DISTFILES} if [ ! -d ${srcdir}/release ]; then mkdir ${srcdir}/release; fi - @cd ${srcdir}; \ - REL=`sed -e '/char version/!d' -e 's/[^0-9.]*\([0-9.]*\).*/less-\1/' -e q version.c`; \ - rm -rf release/$$REL; mkdir release/$$REL; \ - echo "Preparing $$REL"; \ - rm -rf $$REL; mkdir $$REL; \ - for file in ${DISTFILES}; do \ - ./add_copyright $$file $$REL; \ - done; \ - cd $$REL; chmod -w *; chmod +w ${DISTFILES_W}; chmod +x configure; cd ..; \ - echo "Creating release/$$REL/$$REL.tar.gz"; \ - tar -cf - $$REL | gzip -c >release/$$REL/$$REL.tar.gz; \ - echo "Signing release/$$REL/$$REL.tar.gz"; \ - gpg --detach-sign release/$$REL/$$REL.tar.gz; \ - mv release/$$REL/$$REL.tar.gz.sig release/$$REL/$$REL.sig; \ - echo "Creating release/$$REL/$$REL.zip"; \ - zip -rq release/$$REL/$$REL.zip $$REL; \ - rm -rf $$REL + @LESSREL=less-${REL} && RELDIR=release/$$LESSREL && \ + cd ${srcdir} && \ + rm -rf $$RELDIR && mkdir $$RELDIR && \ + echo "Preparing $$LESSREL" && \ + rm -rf $$LESSREL && mkdir $$LESSREL && \ + cp ${DISTFILES} $$LESSREL && \ + cd $$LESSREL && chmod -w * && chmod +w ${DISTFILES_W} && chmod +x configure && cd .. && \ + echo "Creating $$RELDIR/${REL}.tar.gz" && \ + tar -cf - $$LESSREL | gzip -c >$$RELDIR/$$LESSREL.tar.gz && \ + echo "Signing $$RELDIR/$$LESSREL.tar.gz" && \ + gpg --detach-sign $$RELDIR/$$LESSREL.tar.gz && \ + mv $$RELDIR/$$LESSREL.tar.gz.sig $$RELDIR/$$LESSREL.sig && \ + echo "Creating $$RELDIR/$$LESSREL.zip" && \ + zip -rq $$RELDIR/$$LESSREL.zip $$LESSREL && \ + rm -rf $$LESSREL tagall: - @REL=`sed -e '/char version/!d' -e 's/[^0-9.]*\([0-9.]*\).*/v\1/' -e q ${srcdir}/version.c`; \ - echo "tagging $$REL"; \ - $(GIT) tag -a -f -m "$$REL" "$$REL" + echo "tagging v${REL}"; \ + $(GIT) tag -a -f -m "v${REL}" "v${REL}" + +gnu_upload: + @if [ -z "${REL}" ]; then echo "Please set REL=nnn"; exit 1; fi; \ + if [ ! -s release/less-${REL}/less-${REL}.tar.gz ]; then echo "release/less-${REL}/less-${REL}.tar.gz does not exist"; exit 1; fi; \ + cd release/less-${REL} && \ + gpg -b less-${REL}.tar.gz && \ + ( echo "version: 1.2"; echo "directory: less"; echo "filename: less-${REL}.tar.gz" ) > less-${REL}.tar.gz.directive && \ + gpg --clearsign less-${REL}.tar.gz.directive + @echo "upload ready: cd release/less-${REL}; ftp ftp-upload.gnu.org; cd /incoming/ftp; put less-${REL}.tar.gz less-${REL}.tar.gz.sig less-${REL}.tar.gz.directive.asc" diff --git a/Makefile.dsb b/Makefile.dsb index e45b6025cf44..64bb1d8bdbc1 100644 --- a/Makefile.dsb +++ b/Makefile.dsb @@ -21,10 +21,10 @@ EXT = .EXE OBJ = \ main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj \ command.obj cvt.obj decode.obj edit.obj filename.obj forwback.obj \ - help.obj ifile.obj input.obj jump.obj line.obj linenum.obj \ + help.obj ifile.obj input.obj jump.obj lesskey_parse.obj line.obj linenum.obj \ lsystem.obj mark.obj optfunc.obj option.obj opttbl.obj os.obj \ output.obj pattern.obj position.obj prompt.obj search.obj signal.obj \ - tags.obj ttyin.obj version.obj + tags.obj ttyin.obj version.obj xbuf.obj all: less$(EXT) lesskey$(EXT) @@ -35,8 +35,8 @@ less$(EXT): $(OBJ) $(CC) $(LDFLAGS) -e$@ *.obj $(LIBS) ren lesskey.obo lesskey.obj -lesskey$(EXT): lesskey.obj version.obj - $(CC) $(LDFLAGS) -e$@ lesskey.obj version.obj $(LIBS) +lesskey$(EXT): lesskey.obj lesskey_parse.obj version.obj xbuf.obj + $(CC) $(LDFLAGS) -e$@ lesskey.obj lesskey_parse.obj version.obj xbuf.obj $(LIBS) defines.h: defines.ds -del defines.h diff --git a/Makefile.dsg b/Makefile.dsg index 4c11be0e6464..4866d3162748 100644 --- a/Makefile.dsg +++ b/Makefile.dsg @@ -36,18 +36,18 @@ manext = 1 OBJ = \ main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \ command.${O} cvt.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \ - help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \ + help.${O} ifile.${O} input.${O} jump.${O} lesskey_parse.${O} line.${O} linenum.${O} \ lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \ output.${O} pattern.${O} position.${O} prompt.${O} search.${O} signal.${O} \ - tags.${O} ttyin.${O} version.${O} + tags.${O} ttyin.${O} version.${O} xbuf.${O} all: less lesskey lessecho less: ${OBJ} ${CC} ${LDFLAGS} -o $@ ${OBJ} ${LIBS} -lesskey: lesskey.${O} version.${O} - ${CC} ${LDFLAGS} -o $@ lesskey.${O} version.${O} +lesskey: lesskey.${O} lesskey_parse.${O} version.${O} xbuf.${O} + ${CC} ${LDFLAGS} -o $@ lesskey.${O} lesskey_parse.${O} version.${O} xbuf.${O} lessecho: lessecho.${O} version.${O} ${CC} ${LDFLAGS} -o $@ lessecho.${O} version.${O} diff --git a/Makefile.dsu b/Makefile.dsu index 40a253848f6f..ed71163667ba 100644 --- a/Makefile.dsu +++ b/Makefile.dsu @@ -30,10 +30,10 @@ LIBS = $(LIBDIR)\llibce.lib $(LIBDIR)\graphics.lib OBJ = \ main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj \ command.obj cvt.obj decode.obj edit.obj filename.obj forwback.obj \ - help.obj ifile.obj input.obj jump.obj line.obj linenum.obj \ + help.obj ifile.obj input.obj jump.obj lesskey_parse.obj line.obj linenum.obj \ lsystem.obj mark.obj optfunc.obj option.obj opttbl.obj os.obj \ output.obj pattern.obj position.obj prompt.obj search.obj signal.obj \ - tags.obj ttyin.obj version.obj + tags.obj ttyin.obj version.obj xbuf.obj all: less lesskey @@ -43,8 +43,8 @@ less: $(OBJ) -if exist lesskey.obj del lesskey.obj $(CC) $(LDFLAGS) -o $@ *.obj $(LIBS) -lesskey: lesskey.obj version.obj - $(CC) $(LDFLAGS) -o $@ lesskey.obj version.obj $(LIBS) +lesskey: lesskey.obj lesskey_parse.obj version.obj xbuf.obj + $(CC) $(LDFLAGS) -o $@ lesskey.obj lesskey_parse.obj version.obj xbuf.obj $(LIBS) defines.h: defines.ds -del defines.h diff --git a/Makefile.in b/Makefile.in index c9cbf8e82e9a..d087e9e06a08 100644 --- a/Makefile.in +++ b/Makefile.in @@ -46,18 +46,23 @@ SHELL = /bin/sh OBJ = \ main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \ command.${O} cvt.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \ - help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \ + help.${O} ifile.${O} input.${O} jump.${O} \ + line.${O} linenum.${O} \ lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \ output.${O} pattern.${O} position.${O} prompt.${O} search.${O} signal.${O} \ - tags.${O} ttyin.${O} version.${O} @REGEX_O@ + tags.${O} ttyin.${O} version.${O} xbuf.${O} @REGEX_O@ + +ifneq (@SECURE_COMPILE@,1) +OBJ += lesskey_parse.${O} +endif all: less$(EXEEXT) lesskey$(EXEEXT) lessecho$(EXEEXT) less$(EXEEXT): ${OBJ} ${CC} ${LDFLAGS} -o $@ ${OBJ} ${LIBS} -lesskey$(EXEEXT): lesskey.${O} version.${O} - ${CC} ${LDFLAGS} -o $@ lesskey.${O} version.${O} +lesskey$(EXEEXT): lesskey.${O} lesskey_parse.${O} xbuf.${O} version.${O} + ${CC} ${LDFLAGS} -o $@ lesskey.${O} lesskey_parse.${O} xbuf.${O} version.${O} lessecho$(EXEEXT): lessecho.${O} version.${O} ${CC} ${LDFLAGS} -o $@ lessecho.${O} version.${O} diff --git a/Makefile.o2e b/Makefile.o2e index 3bb6dfc4eb5c..15341768b49f 100644 --- a/Makefile.o2e +++ b/Makefile.o2e @@ -21,18 +21,18 @@ O = obj OBJ = \ main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \ command.${O} cvt.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \ - help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \ + help.${O} ifile.${O} input.${O} jump.${O} lesskey_parse.${O} line.${O} linenum.${O} \ lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \ output.${O} pattern.${O} position.${O} prompt.${O} search.${O} signal.${O} \ - tags.${O} ttyin.${O} version.${O} regexp.${O} + tags.${O} ttyin.${O} version.${O} xbuf.${O} regexp.${O} all: less.exe lesskey.exe scrsize.exe less.exe: ${OBJ} ${CC} ${OBJ} -o $@ ${LDFLAGS} ${LIBS} -lesskey.exe: lesskey.${O} version.${O} - ${CC} lesskey.${O} version.${O} -o $@ ${LDFLAGS} +lesskey.exe: lesskey.${O} lesskey_parse.${O} version.${O} xbuf.${O} + ${CC} lesskey.${O} lesskey_parse.${O} version.${O} xbuf.${O} -o $@ ${LDFLAGS} scrsize.exe: scrsize.c ${CC} ${CFLAGS} -D__ST_MT_ERRNO__ -s -Zmtd -lX11 $< diff --git a/Makefile.o9c b/Makefile.o9c index e107f55946bc..aa51ccac0c64 100644 --- a/Makefile.o9c +++ b/Makefile.o9c @@ -25,18 +25,18 @@ O = r OBJ = \ main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \ command.${O} cvt.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \ - help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \ + help.${O} ifile.${O} input.${O} jump.${O} lesskey_parse.${O} line.${O} linenum.${O} \ lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \ output.${O} pattern.${O} position.${O} prompt.${O} search.${O} signal.${O} \ - tags.${O} ttyin.${O} version.${O} regexp.${O} + tags.${O} ttyin.${O} version.${O} xbuf.${O} regexp.${O} all: less lessecho lesskey less: ${OBJ} ${CC} ${OBJ} -f=$@ ${LDFLAGS} ${LIBS} -lesskey: lesskey.${O} version.${O} - ${CC} lesskey.${O} version.${O} -f=$@ ${LDFLAGS} +lesskey: lesskey.${O} lesskey_parse.${O} version.${O} xbuf.${O} + ${CC} lesskey.${O} lesskey_parse.${O} version.${O} xbuf.${O} -f=$@ ${LDFLAGS} lessecho: lessecho.${O} version.${O} ${CC} lessecho.${O} version.${O} -f=$@ ${LDFLAGS} diff --git a/Makefile.o9u b/Makefile.o9u index 8ca84c897253..99a9b730684e 100644 --- a/Makefile.o9u +++ b/Makefile.o9u @@ -24,18 +24,18 @@ O = r OBJ = \ main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \ command.${O} cvt.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \ - help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \ + help.${O} ifile.${O} input.${O} jump.${O} lesskey_parse.${O} line.${O} linenum.${O} \ lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \ output.${O} pattern.${O} position.${O} prompt.${O} search.${O} signal.${O} \ - tags.${O} ttyin.${O} version.${O} regexp.${O} + tags.${O} ttyin.${O} version.${O} xbuf.${O} regexp.${O} all: less lesskey less: ${OBJ} ${CC} ${OBJ} -f=$@ ${LDFLAGS} ${LIBS} -lesskey: lesskey.${O} version.${O} - ${CC} lesskey.${O} version.${O} -f=$@ ${LDFLAGS} +lesskey: lesskey.${O} lesskey_parse.${O} version.${O} xbuf.${O} + ${CC} lesskey.${O} lesskey_parse.${O} version.${O} xbuf.${O} -f=$@ ${LDFLAGS} ${OBJ}: defines.h less.h diff --git a/Makefile.wnb b/Makefile.wnb index 75a65cdd2c5b..5f9db1f74c47 100644 --- a/Makefile.wnb +++ b/Makefile.wnb @@ -28,10 +28,10 @@ LIBS = ${LIBDIR}\import32.lib ${LIBDIR}\cw32.lib OBJ = \ main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj \ command.obj cvt.obj decode.obj edit.obj filename.obj forwback.obj \ - help.obj ifile.obj input.obj jump.obj line.obj linenum.obj \ + help.obj ifile.obj input.obj jump.obj lesskey_parse.obj line.obj linenum.obj \ lsystem.obj mark.obj optfunc.obj option.obj opttbl.obj os.obj \ output.obj pattern.obj position.obj prompt.obj search.obj signal.obj \ - tags.obj ttyin.obj version.obj regexp.obj + tags.obj ttyin.obj version.obj xbuf.obj regexp.obj all: less lesskey lessecho @@ -42,7 +42,7 @@ all: less lesskey lessecho less: ${OBJ} ${LD} ${LDFLAGS} ${LIBDIR}\c0x32.obj $**, $@,,${LIBS} -lesskey: lesskey.obj version.obj +lesskey: lesskey.obj lesskey_parse.obj version.obj xbuf.obj ${LD} ${LDFLAGS} ${LIBDIR}\c0x32.obj $**, $@,,${LIBS} lessecho: lessecho.obj version.obj diff --git a/Makefile.wng b/Makefile.wng index 85686068c57b..d33378dba7d0 100644 --- a/Makefile.wng +++ b/Makefile.wng @@ -81,7 +81,7 @@ LESS_SRC = brac.c ch.c charset.c cmdbuf.c command.c \ lsystem.c main.c mark.c optfunc.c option.c \ opttbl.c os.c output.c pattern.c position.c \ prompt.c screen.c scrsize.c search.c \ - signal.c tags.c ttyin.c version.c + signal.c tags.c ttyin.c version.c xbuf.c ifeq (${REGEX_PACKAGE},regcomp-local) LESS_SRC += regexp.c endif @@ -89,10 +89,10 @@ endif OBJ = \ main.o screen.o brac.o ch.o charset.o cmdbuf.o \ command.o cvt.o decode.o edit.o filename.o forwback.o \ - help.o ifile.o input.o jump.o line.o linenum.o \ + help.o ifile.o input.o jump.o lesskey_parse.o line.o linenum.o \ lsystem.o mark.o optfunc.o option.o opttbl.o os.o \ output.o pattern.o position.o prompt.o search.o signal.o \ - tags.o ttyin.o version.o + tags.o ttyin.o version.o xbuf.o ifeq (${REGEX_PACKAGE},regcomp-local) OBJ += regexp.o endif @@ -103,8 +103,8 @@ all: clean less lesskey lessecho less: ${OBJ} ${CC} ${LDFLAGS} -o $@ ${OBJ} ${LIBS} -lesskey: lesskey.o version.o - ${CC} ${LDFLAGS} -o $@ lesskey.o version.o +lesskey: lesskey.o lesskey_parse.o version.o xbuf.o + ${CC} ${LDFLAGS} -o $@ lesskey.o lesskey_parse.o version.o xbuf.o lessecho: lessecho.o version.o ${CC} ${LDFLAGS} -o $@ lessecho.o version.o diff --git a/Makefile.wnm b/Makefile.wnm index cc084a7c96b9..a0148db47a16 100644 --- a/Makefile.wnm +++ b/Makefile.wnm @@ -26,18 +26,18 @@ LIBS = user32.lib OBJ = \ main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj \ command.obj cvt.obj decode.obj edit.obj filename.obj forwback.obj \ - help.obj ifile.obj input.obj jump.obj line.obj linenum.obj \ + help.obj ifile.obj input.obj jump.obj lesskey_parse.obj line.obj linenum.obj \ lsystem.obj mark.obj optfunc.obj option.obj opttbl.obj os.obj \ output.obj pattern.obj position.obj prompt.obj search.obj signal.obj \ - tags.obj ttyin.obj version.obj regexp.obj + tags.obj ttyin.obj version.obj xbuf.obj regexp.obj all: less.exe lesskey.exe less.exe: $(OBJ) $(LD) $(LDFLAGS) $** $(LIBS) /out:$@ -lesskey.exe: lesskey.obj version.obj - $(LD) $(LDFLAGS) lesskey.obj version.obj $(LIBS) /out:$@ +lesskey.exe: lesskey.obj lesskey_parse.obj version.obj xbuf.obj + $(LD) $(LDFLAGS) lesskey.obj lesskey_parse.obj version.obj xbuf.obj $(LIBS) /out:$@ defines.h: defines.wn -del defines.h diff --git a/NEWS b/NEWS index bc5afd655ddc..a403c5d8a875 100644 --- a/NEWS +++ b/NEWS @@ -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. diff --git a/README b/README index b5bf899c7170..955bf82822ea 100644 --- a/README +++ b/README @@ -1,7 +1,5 @@ - 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 @@ -19,6 +17,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. diff --git a/ch.c b/ch.c index bab0692f7437..379dd84c41b8 100644 --- a/ch.c +++ b/ch.c @@ -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; diff --git a/cmdbuf.c b/cmdbuf.c index 9cc1f3e94977..dd135382aa11 100644 --- a/cmdbuf.c +++ b/cmdbuf.c @@ -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); diff --git a/command.c b/command.c index cf691a7988b3..88a2f8b34a7d 100644 --- a/command.c +++ b/command.c @@ -791,6 +791,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 /* diff --git a/configure b/configure index e3be2c0faf1b..5589f8e761f0 100755 --- a/configure +++ b/configure @@ -622,6 +622,7 @@ ac_includes_default="\ ac_subst_vars='LTLIBOBJS LIBOBJS REGEX_O +SECURE_COMPILE INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM @@ -5269,9 +5270,13 @@ fi if test "${with_secure+set}" = set; then : withval=$with_secure; $as_echo "#define SECURE_COMPILE 1" >>confdefs.h + SECURE_COMPILE=1 + else $as_echo "#define SECURE_COMPILE 0" >>confdefs.h + SECURE_COMPILE=0 + fi diff --git a/configure.ac b/configure.ac index 34077366f2dd..21f550a1a609 100644 --- a/configure.ac +++ b/configure.ac @@ -387,7 +387,9 @@ fi # Compile in secure mode? AC_ARG_WITH(secure, [ --with-secure Compile in secure mode], - AC_DEFINE(SECURE_COMPILE, 1), AC_DEFINE(SECURE_COMPILE, 0)) + AC_DEFINE(SECURE_COMPILE, 1) + AC_SUBST(SECURE_COMPILE,1), AC_DEFINE(SECURE_COMPILE, 0) + AC_SUBST(SECURE_COMPILE,0)) # Should we use floating point? AC_MSG_CHECKING(for floating point) @@ -595,7 +597,7 @@ AH_TOP([ * 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). @@ -627,6 +629,7 @@ AH_TOP([ #define LESSKEYFILE ".less" #define LESSKEYFILE_SYS SYSDIR "/sysless" #define DEF_LESSKEYINFILE ".lesskey" +#define LESSKEYINFILE_SYS SYSDIR "/syslesskey" #define LESSHISTFILE ".lesshst" @@ -699,6 +702,9 @@ AH_TOP([ /* 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. */ diff --git a/decode.c b/decode.c index f3bfb7a8ead2..7e9b167bc786 100644 --- a/decode.c +++ b/decode.c @@ -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 diff --git a/defines.ds b/defines.ds index fb02c89b6065..1bd50261561b 100644 --- a/defines.ds +++ b/defines.ds @@ -122,6 +122,7 @@ #define LESSKEYFILE "_less" #define LESSKEYFILE_SYS "c:\\_sysless" #define DEF_LESSKEYINFILE "_lesskey" +#define LESSKEYINFILE_SYS "c:\\_syslesskey" #define LESSHISTFILE "_lesshst" @@ -187,6 +188,9 @@ */ #define HAVE_DUP 1 +/* Define to 1 to support reading lesskey source files (not just binary). */ +#define HAVE_LESSKEYSRC 1 + /* * Sizes of various buffers. */ diff --git a/defines.h.in b/defines.h.in index 389a24fc5e59..9a36f1b857f2 100644 --- a/defines.h.in +++ b/defines.h.in @@ -80,7 +80,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). @@ -112,6 +112,7 @@ #define LESSKEYFILE ".less" #define LESSKEYFILE_SYS SYSDIR "/sysless" #define DEF_LESSKEYINFILE ".lesskey" +#define LESSKEYINFILE_SYS SYSDIR "/syslesskey" #define LESSHISTFILE ".lesshst" @@ -184,6 +185,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. */ diff --git a/defines.o2 b/defines.o2 index 267ef5edae74..5499bb401c89 100644 --- a/defines.o2 +++ b/defines.o2 @@ -115,6 +115,7 @@ #define LESSKEYFILE "less.ini" #define LESSKEYFILE_SYS "C:\\sysless.ini" #define DEF_LESSKEYINFILE "lesskey.ini" +#define LESSKEYINFILE_SYS "C:\\syslesskey.ini" #define LESSHISTFILE "lesshst.ini" @@ -168,6 +169,9 @@ */ #define HAVE_DUP 1 +/* Define to 1 to support reading lesskey source files (not just binary). */ +#define HAVE_LESSKEYSRC 1 + /* * Sizes of various buffers. */ diff --git a/defines.o9 b/defines.o9 index 22740ef8fb29..cb5de661ec99 100644 --- a/defines.o9 +++ b/defines.o9 @@ -114,6 +114,7 @@ #define LESSKEYFILE ".less" #define LESSKEYFILE_SYS "/.sysless" #define DEF_LESSKEYINFILE ".lesskey" +#define LESSKEYINFILE_SYS "/.syslesskey" #define LESSHISTFILE ".lesshst" @@ -175,6 +176,9 @@ */ #define HAVE_DUP 0 +/* Define to 1 to support reading lesskey source files (not just binary). */ +#define HAVE_LESSKEYSRC 1 + /* * Sizes of various buffers. */ diff --git a/defines.wn b/defines.wn index b8256e1d7cd2..390eb17e834e 100644 --- a/defines.wn +++ b/defines.wn @@ -115,6 +115,7 @@ #define LESSKEYFILE "_less" #define LESSKEYFILE_SYS "c:\\_sysless" #define DEF_LESSKEYINFILE "_lesskey" +#define LESSKEYINFILE_SYS "c:\\_syslesskey" #define LESSHISTFILE "_lesshst" @@ -169,6 +170,9 @@ */ #define HAVE_DUP 1 +/* Define to 1 to support reading lesskey source files (not just binary). */ +#define HAVE_LESSKEYSRC 1 + /* * Sizes of various buffers. */ diff --git a/edit.c b/edit.c index 12631dba6bac..529ed75b0afe 100644 --- a/edit.c +++ b/edit.c @@ -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); diff --git a/filename.c b/filename.c index 177cb946364a..aba8d3a362e3 100644 --- a/filename.c +++ b/filename.c @@ -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); } - diff --git a/funcs.h b/funcs.h index 12930356c938..330540ac2156 100644 --- a/funcs.h +++ b/funcs.h @@ -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)); diff --git a/help.c b/help.c index f5b4aa1fbf1a..9dabd43ca221 100644 --- a/help.c +++ b/help.c @@ -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', diff --git a/less.h b/less.h index 4751976bac18..83e31514be3e 100644 --- a/less.h +++ b/less.h @@ -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 */ diff --git a/less.hlp b/less.hlp index 1e1ebf447711..333a0b576c5e 100644 --- a/less.hlp +++ b/less.hlp @@ -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 diff --git a/less.man b/less.man index 6efe7a99d464..c25b2a1fa560 100644 --- a/less.man +++ b/less.man @@ -723,10 +723,21 @@ LESS(1) General Commands Manual LESS(1) -kfilename or --lesskey-file=filename Causes less to open and interpret the named file as a lesskey(1) - 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 lesskey 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 lesskey file. + + --lesskey-src=filename + Causes less to open and interpret the named file as a lesskey(1) + source file. If the LESSKEYIN or LESSKEYIN_SYSTEM environment + variable is set, or if a lesskey source file is found in a stan- + dard place (see KEY BINDINGS), it is also used as a lesskey + source file. Prior to version 582, the lesskey program needed + to be run to convert a lesskey source file to a lesskey binary + file for less to use. Newer versions of less read the lesskey + source file directly and ignore the binary file if the source + file exists. -K or --quit-on-intr Causes less to exit immediately (with status 2) when an inter- @@ -986,6 +997,11 @@ LESS(1) General Commands Manual LESS(1) calculated if the terminal window is resized, so that the actual scroll remains at the specified fraction of the screen width. + --file-size + If --file-size is specified, 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. + --follow-name Normally, if the input file is renamed while an F command is ex- ecuting, less will continue to display the contents of the orig- @@ -1164,70 +1180,75 @@ LESS(1) General Commands Manual LESS(1) ^G Delete the entire command line and return to the main prompt. KEY BINDINGS - You may define your own less commands by using the program lesskey(1) - to create a lesskey file. This file specifies a set of command keys - and an action associated with each key. You may also use lesskey to - change the line-editing keys (see LINE EDITING), and to set environment - variables. If the environment variable LESSKEY is set, less uses that - as the name of the lesskey file. Otherwise, less looks in a standard - place for the lesskey file: On Unix systems, less looks for a lesskey - file called "$HOME/.less". On MS-DOS and Windows systems, 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 - in the PATH environment variable. On OS/2 systems, 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 - in the INIT environment variable, and if it not found there, then looks - for a lesskey file called "less.ini" in any directory specified in the - PATH environment variable. See the lesskey manual page for more de- - tails. + You may define your own less commands by creating a lesskey source + file. This file specifies a set of command keys and an action associ- + ated with each key. You may also change the line-editing keys (see + LINE EDITING), and to set environment variables. If the environment + variable LESSKEYIN is set, less uses that as the name of the lesskey + source file. Otherwise, less looks in a standard place for the lesskey + source file: On Unix systems, less looks for a lesskey file called + "$XDG_CONFIG_HOME/lesskey" or "$HOME/.lesskey". On MS-DOS and Windows + systems, less 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, less 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 "lesskey.ini" in + any directory specified in the PATH environment variable. See the + lesskey manual page for more details. - A system-wide lesskey 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, - less uses that as the name of the system-wide lesskey file. Otherwise, - 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. - (However, if 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:\_sys- - less. On OS/2 systems, the system-wide lesskey file is c:\sysless.ini. + 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 + LESSKEYIN_SYSTEM is set, less uses that as the name of the system-wide + lesskey file. Otherwise, less looks in a standard place for the sys- + tem-wide lesskey file: On Unix systems, the system-wide lesskey file is + /usr/local/etc/syslesskey. (However, if less was built with a differ- + ent 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:\_syslesskey. On OS/2 systems, the system-wide + lesskey file is c:\syslesskey.ini. + + Previous versions of less (before v582) used lesskey files with a bina- + ry format, produced by the lesskey program. It is no longer necessary + to use the lesskey program. INPUT PREPROCESSOR - You may define an "input preprocessor" for less. Before less opens a + You may define an "input preprocessor" for less. Before less opens a file, it first gives your input preprocessor a chance to modify the way - the contents of the file are displayed. An input preprocessor is sim- - ply an executable program (or shell script), which writes the contents + the contents of the file are displayed. An input preprocessor is sim- + ply an executable program (or shell script), which writes the contents of the file to a different file, called the replacement file. The con- - tents of the replacement file are then displayed in place of the con- - tents of the original file. However, it will appear to the user as if - the original file is opened; that is, less will display the original + tents of the replacement file are then displayed in place of the con- + tents of the original file. However, it will appear to the user as if + the original file is opened; that is, less will display the original filename as the name of the current file. - An input preprocessor receives one command line argument, the original - filename, as entered by the user. It should create the replacement - file, and when finished, print the name of the replacement file to its - standard output. If the input preprocessor does not output a replace- - ment filename, less uses the original file, as normal. The input pre- - processor is not called when viewing standard input. To set up an in- - put preprocessor, set the LESSOPEN environment variable to a command - line which will invoke your input preprocessor. This command line - should include one occurrence of the string "%s", which will be re- + An input preprocessor receives one command line argument, the original + filename, as entered by the user. It should create the replacement + file, and when finished, print the name of the replacement file to its + standard output. If the input preprocessor does not output a replace- + ment filename, less uses the original file, as normal. The input pre- + processor is not called when viewing standard input. To set up an in- + put preprocessor, set the LESSOPEN environment variable to a command + line which will invoke your input preprocessor. This command line + should include one occurrence of the string "%s", which will be re- placed by the filename when the input preprocessor command is invoked. When less closes a file opened in such a way, it will call another pro- - gram, called the input postprocessor, which may perform any desired - clean-up action (such as deleting the replacement file created by + gram, called the input postprocessor, which may perform any desired + clean-up action (such as deleting the replacement file created by LESSOPEN). This program receives two command line arguments, the orig- - inal filename as entered by the user, and the name of the replacement - file. To set up an input postprocessor, set the LESSCLOSE environment - variable to a command line which will invoke your input postprocessor. - It may include two occurrences of the string "%s"; the first is re- - placed with the original name of the file and the second with the name + inal filename as entered by the user, and the name of the replacement + file. To set up an input postprocessor, set the LESSCLOSE environment + variable to a command line which will invoke your input postprocessor. + It may include two occurrences of the string "%s"; the first is re- + placed with the original name of the file and the second with the name of the replacement file, which was output by LESSOPEN. - For example, on many Unix systems, these two scripts will allow you to + For example, on many Unix systems, these two scripts will allow you to keep files in compressed format, but still let less view them directly: lessopen.sh: @@ -1247,27 +1268,27 @@ LESS(1) General Commands Manual LESS(1) #! /bin/sh rm $2 - To use these scripts, put them both where they can be executed and set + To use these scripts, put them both where they can be executed and set LESSOPEN="lessopen.sh %s", and LESSCLOSE="lessclose.sh %s %s". More - complex LESSOPEN and LESSCLOSE scripts may be written to accept other + complex LESSOPEN and LESSCLOSE scripts may be written to accept other types of compressed files, and so on. - It is also possible to set up an input preprocessor to pipe the file - data directly to less, rather than putting the data into a replacement + It is also possible to set up an input preprocessor to pipe the file + data directly to less, rather than putting the data into a replacement file. This avoids the need to decompress the entire file before start- ing to view it. An input preprocessor that works this way is called an - input pipe. An input pipe, instead of writing the name of a replace- + input pipe. An input pipe, instead of writing the name of a replace- ment file on its standard output, writes the entire contents of the re- - placement file on its standard output. If the input pipe does not - write any characters on its standard output, then there is no replace- - ment file and less uses the original file, as normal. To use an input - pipe, make the first character in the LESSOPEN environment variable a - vertical bar (|) to signify that the input preprocessor is an input - pipe. As with non-pipe input preprocessors, the command string must - contain one occurrence of %s, which is replaced with the filename of + placement file on its standard output. If the input pipe does not + write any characters on its standard output, then there is no replace- + ment file and less uses the original file, as normal. To use an input + pipe, make the first character in the LESSOPEN environment variable a + vertical bar (|) to signify that the input preprocessor is an input + pipe. As with non-pipe input preprocessors, the command string must + contain one occurrence of %s, which is replaced with the filename of the input file. - For example, on many Unix systems, this script will work like the pre- + For example, on many Unix systems, this script will work like the pre- vious example scripts: lesspipe.sh: @@ -1284,29 +1305,29 @@ LESS(1) General Commands Manual LESS(1) LESSOPEN="|lesspipe.sh %s". Note that a preprocessor cannot output an empty file, since that is in- - terpreted as meaning there is no replacement, and the original file is - used. To avoid this, if LESSOPEN starts with two vertical bars, the - exit status of the script becomes meaningful. If the exit status is - zero, the output is considered to be replacement text, even if it is - empty. If the exit status is nonzero, any output is ignored and the - original file is used. For compatibility with previous versions of + terpreted as meaning there is no replacement, and the original file is + used. To avoid this, if LESSOPEN starts with two vertical bars, the + exit status of the script becomes meaningful. If the exit status is + zero, the output is considered to be replacement text, even if it is + empty. If the exit status is nonzero, any output is ignored and the + original file is used. For compatibility with previous versions of less, if LESSOPEN starts with only one vertical bar, the exit status of the preprocessor is ignored. - When an input pipe is used, a LESSCLOSE postprocessor can be used, but + When an input pipe is used, a LESSCLOSE postprocessor can be used, but it is usually not necessary since there is no replacement file to clean - up. In this case, the replacement file name passed to the LESSCLOSE + up. In this case, the replacement file name passed to the LESSCLOSE postprocessor is "-". - For compatibility with previous versions of less, the input preproces- + For compatibility with previous versions of less, the input preproces- sor or pipe is not used if less is viewing standard input. However, if - the first character of LESSOPEN is a dash (-), the input preprocessor - is used on standard input as well as other files. In this case, the - dash is not considered to be part of the preprocessor command. If + the first character of LESSOPEN is a dash (-), the input preprocessor + is used on standard input as well as other files. In this case, the + dash is not considered to be part of the preprocessor command. If standard input is being viewed, the input preprocessor is passed a file - name consisting of a single dash. Similarly, if the first two charac- - ters of LESSOPEN are vertical bar and dash (|-) or two vertical bars - and a dash (||-), the input pipe is used on standard input as well as + name consisting of a single dash. Similarly, if the first two charac- + ters of LESSOPEN are vertical bar and dash (|-) or two vertical bars + and a dash (||-), the input pipe is used on standard input as well as other files. Again, in this case the dash is not considered to be part of the input pipe command. @@ -1317,25 +1338,25 @@ LESS(1) General Commands Manual LESS(1) can be displayed directly to the screen. control characters - should not be displayed directly, but are expected to be found + should not be displayed directly, but are expected to be found in ordinary text files (such as backspace and tab). binary characters - should not be displayed directly and are not expected to be + should not be displayed directly and are not expected to be found in text files. A "character set" is simply a description of which characters are to be - considered normal, control, and binary. The LESSCHARSET environment - variable may be used to select a character set. Possible values for + considered normal, control, and binary. The LESSCHARSET environment + variable may be used to select a character set. Possible values for LESSCHARSET are: - ascii BS, TAB, NL, CR, and formfeed are control characters, all chars - with values between 32 and 126 are normal, and all others are + ascii BS, TAB, NL, CR, and formfeed are control characters, all chars + with values between 32 and 126 are normal, and all others are binary. iso8859 - Selects an ISO 8859 character set. This is the same as ASCII, - except characters between 160 and 255 are treated as normal + Selects an ISO 8859 character set. This is the same as ASCII, + except characters between 160 and 255 are treated as normal characters. latin1 Same as iso8859. @@ -1347,8 +1368,8 @@ LESS(1) General Commands Manual LESS(1) ebcdic Selects an EBCDIC character set. IBM-1047 - Selects an EBCDIC character set used by OS/390 Unix Services. - This is the EBCDIC analogue of latin1. You get similar results + Selects an EBCDIC character set used by OS/390 Unix Services. + This is the EBCDIC analogue of latin1. You get similar results by setting either LESSCHARSET=IBM-1047 or LC_CTYPE=en_US in your environment. @@ -1356,29 +1377,29 @@ LESS(1) General Commands Manual LESS(1) next Selects a character set appropriate for NeXT computers. - utf-8 Selects the UTF-8 encoding of the ISO 10646 character set. - UTF-8 is special in that it supports multi-byte characters in + utf-8 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 mul- ti-byte characters. windows - Selects a character set appropriate for Microsoft Windows (cp + Selects a character set appropriate for Microsoft Windows (cp 1251). - In rare cases, it may be desired to tailor less to use a character set - other than the ones definable by LESSCHARSET. In this case, the envi- + In rare cases, it may be desired to tailor less to use a character set + other than the ones definable by LESSCHARSET. In this case, the envi- ronment variable LESSCHARDEF can be used to define a character set. It should be set to a string where each character in the string represents - one character in the character set. The character "." is used for a - normal character, "c" for control, and "b" for binary. A decimal num- - ber may be used for repetition. For example, "bccc4b." would mean - character 0 is binary, 1, 2 and 3 are control, 4, 5, 6 and 7 are bina- + one character in the character set. The character "." is used for a + normal character, "c" for control, and "b" for binary. A decimal num- + ber may be used for repetition. For example, "bccc4b." would mean + character 0 is binary, 1, 2 and 3 are control, 4, 5, 6 and 7 are bina- ry, and 8 is normal. All characters after the last are taken to be the - same as the last, so characters 9 through 255 would be normal. (This - is an example, and does not necessarily represent any real character + same as the last, so characters 9 through 255 would be normal. (This + is an example, and does not necessarily represent any real character set.) - This table shows the value of LESSCHARDEF which is equivalent to each + This table shows the value of LESSCHARDEF which is equivalent to each of the possible values for LESSCHARSET: ascii 8bcccbcc18b95.b @@ -1392,65 +1413,65 @@ LESS(1) General Commands Manual LESS(1) latin1 8bcccbcc18b95.33b. next 8bcccbcc18b95.bb125.bb - If neither LESSCHARSET nor LESSCHARDEF is set, but any of the strings - "UTF-8", "UTF8", "utf-8" or "utf8" is found in the LC_ALL, LC_CTYPE or + If neither LESSCHARSET nor LESSCHARDEF is set, but any of the strings + "UTF-8", "UTF8", "utf-8" or "utf8" is found in the LC_ALL, LC_CTYPE or LANG environment variables, then the default character set is utf-8. If that string is not found, but your system supports the setlocale in- - terface, less will use setlocale to determine the character set. set- - locale is controlled by setting the LANG or LC_CTYPE environment vari- + terface, less will use setlocale to determine the character set. set- + locale is controlled by setting the LANG or LC_CTYPE environment vari- ables. - Finally, if the setlocale interface is also not available, the default + Finally, if the setlocale interface is also not available, the default character set is latin1. - Control and binary characters are displayed in standout (reverse + Control and binary characters are displayed in standout (reverse video). Each such character is displayed in caret notation if possible - (e.g. ^A for control-A). Caret notation is used only if inverting the + (e.g. ^A for control-A). Caret notation is used only if inverting the 0100 bit results in a normal printable character. Otherwise, the char- - acter is displayed as a hex number in angle brackets. This format can - be changed by setting the LESSBINFMT environment variable. LESSBINFMT + acter is displayed as a hex number in angle brackets. This format can + be changed by setting the LESSBINFMT environment variable. LESSBINFMT may begin with a "*" and one character to select the display attribute: - "*k" is blinking, "*d" is bold, "*u" is underlined, "*s" is standout, - and "*n" is normal. If LESSBINFMT does not begin with a "*", normal - attribute is assumed. The remainder of LESSBINFMT is a string which - may include one printf-style escape sequence (a % followed by x, X, o, - d, etc.). For example, if LESSBINFMT is "*u[%x]", binary characters - are displayed in underlined hexadecimal surrounded by brackets. The - default if no LESSBINFMT is specified is "*s<%02X>". Warning: the re- - sult of expanding the character via LESSBINFMT must be less than 31 + "*k" is blinking, "*d" is bold, "*u" is underlined, "*s" is standout, + and "*n" is normal. If LESSBINFMT does not begin with a "*", normal + attribute is assumed. The remainder of LESSBINFMT is a string which + may include one printf-style escape sequence (a % followed by x, X, o, + d, etc.). For example, if LESSBINFMT is "*u[%x]", binary characters + are displayed in underlined hexadecimal surrounded by brackets. The + default if no LESSBINFMT is specified is "*s<%02X>". Warning: the re- + sult of expanding the character via LESSBINFMT must be less than 31 characters. When the character set is utf-8, the LESSUTFBINFMT environment variable acts similarly to LESSBINFMT but it applies to Unicode code points that - were successfully decoded but are unsuitable for display (e.g., unas- - signed code points). Its default value is "". Note that - LESSUTFBINFMT and LESSBINFMT share their display attribute setting - ("*x") so specifying one will affect both; LESSUTFBINFMT is read after - LESSBINFMT so its setting, if any, will have priority. Problematic - octets in a UTF-8 file (octets of a truncated sequence, octets of a - complete but non-shortest form sequence, invalid octets, and stray - trailing octets) are displayed individually using LESSBINFMT so as to + were successfully decoded but are unsuitable for display (e.g., unas- + signed code points). Its default value is "". Note that + LESSUTFBINFMT and LESSBINFMT share their display attribute setting + ("*x") so specifying one will affect both; LESSUTFBINFMT is read after + LESSBINFMT so its setting, if any, will have priority. Problematic + octets in a UTF-8 file (octets of a truncated sequence, octets of a + complete but non-shortest form sequence, invalid octets, and stray + trailing octets) are displayed individually using LESSBINFMT so as to facilitate diagnostic of how the UTF-8 file is ill-formed. PROMPTS - The -P option allows you to tailor the prompt to your preference. The - string given to the -P option replaces the specified prompt string. + The -P option allows you to tailor the prompt to your preference. The + string given to the -P option replaces the specified prompt string. Certain characters in the string are interpreted specially. The prompt - mechanism is rather complicated to provide flexibility, but the ordi- - nary user need not understand the details of constructing personalized + mechanism is rather complicated to provide flexibility, but the ordi- + nary user need not understand the details of constructing personalized prompt strings. - A percent sign followed by a single character is expanded according to + A percent sign followed by a single character is expanded according to what the following character is: - %bX Replaced by the byte offset into the current input file. The b + %bX Replaced by the byte offset into the current input file. The b is followed by a single character (shown as X above) which spec- - ifies the line whose byte offset is to be used. If the charac- - ter is a "t", the byte offset of the top line in the display is + ifies the line whose byte offset is to be used. If the charac- + ter is a "t", the byte offset of the top line in the display is used, an "m" means use the middle line, a "b" means use the bot- - tom line, a "B" means use the line just after the bottom line, - and a "j" means use the "target" line, as specified by the -j + tom line, a "B" means use the line just after the bottom line, + and a "j" means use the "target" line, as specified by the -j option. %B Replaced by the size of the current input file. @@ -1458,50 +1479,50 @@ LESS(1) General Commands Manual LESS(1) %c Replaced by the column number of the text appearing in the first column of the screen. - %dX Replaced by the page number of a line in the input file. The + %dX Replaced by the page number of a line in the input file. The line to be used is determined by the X, as with the %b option. - %D Replaced by the number of pages in the input file, or equiva- + %D Replaced by the number of pages in the input file, or equiva- lently, the page number of the last line in the input file. - %E Replaced by the name of the editor (from the VISUAL environment - variable, or the EDITOR environment variable if VISUAL is not + %E Replaced by the name of the editor (from the VISUAL environment + variable, or the EDITOR environment variable if VISUAL is not defined). See the discussion of the LESSEDIT feature below. %f Replaced by the name of the current input file. - %F Replaced by the last component of the name of the current input + %F Replaced by the last component of the name of the current input file. - %g Replaced by the shell-escaped name of the current input file. - This is useful when the expanded string will be used in a shell + %g Replaced by the shell-escaped name of the current input file. + This is useful when the expanded string will be used in a shell command, such as in LESSEDIT. - %i Replaced by the index of the current file in the list of input + %i Replaced by the index of the current file in the list of input files. - %lX Replaced by the line number of a line in the input file. The + %lX Replaced by the line number of a line in the input file. The line to be used is determined by the X, as with the %b option. %L Replaced by the line number of the last line in the input file. %m Replaced by the total number of input files. - %pX Replaced by the percent into the current input file, based on - byte offsets. The line used is determined by the X as with the + %pX Replaced by the percent into the current input file, based on + byte offsets. The line used is determined by the X as with the %b option. - %PX Replaced by the percent into the current input file, based on - line numbers. The line used is determined by the X as with the + %PX Replaced by the percent into the current input file, based on + line numbers. The line used is determined by the X as with the %b option. %s Same as %B. - %t Causes any trailing spaces to be removed. Usually used at the + %t Causes any trailing spaces to be removed. Usually used at the end of the string, but may appear anywhere. - %T Normally expands to the word "file". However if viewing files - via a tags list using the -t option, it expands to the word + %T Normally expands to the word "file". However if viewing files + via a tags list using the -t option, it expands to the word "tag". %x Replaced by the name of the next input file in the list. @@ -1509,15 +1530,15 @@ LESS(1) General Commands Manual LESS(1) If any item is unknown (for example, the file size if input is a pipe), a question mark is printed instead. - The format of the prompt string can be changed depending on certain - conditions. A question mark followed by a single character acts like - an "IF": depending on the following character, a condition is evaluat- - ed. If the condition is true, any characters following the question - mark and condition character, up to a period, are included in the - prompt. If the condition is false, such characters are not included. - A colon appearing between the question mark and the period can be used + The format of the prompt string can be changed depending on certain + conditions. A question mark followed by a single character acts like + an "IF": depending on the following character, a condition is evaluat- + ed. If the condition is true, any characters following the question + mark and condition character, up to a period, are included in the + prompt. If the condition is false, such characters are not included. + A colon appearing between the question mark and the period can be used to establish an "ELSE": any characters between the colon and the period - are included in the string if and only if the IF condition is false. + are included in the string if and only if the IF condition is false. Condition characters (which follow a question mark) may be: ?a True if any characters have been included in the prompt so far. @@ -1532,7 +1553,7 @@ LESS(1) General Commands Manual LESS(1) ?e True if at end-of-file. - ?f True if there is an input filename (that is, if input is not a + ?f True if there is an input filename (that is, if input is not a pipe). ?lX True if the line number of the specified line is known. @@ -1543,45 +1564,45 @@ LESS(1) General Commands Manual LESS(1) ?n True if this is the first prompt in a new input file. - ?pX True if the percent into the current input file, based on byte + ?pX True if the percent into the current input file, based on byte offsets, of the specified line is known. - ?PX True if the percent into the current input file, based on line + ?PX True if the percent into the current input file, based on line numbers, of the specified line is known. ?s Same as "?B". - ?x True if there is a next input file (that is, if the current in- + ?x True if there is a next input file (that is, if the current in- put file is not the last one). Any characters other than the special ones (question mark, colon, peri- - od, percent, and backslash) become literally part of the prompt. Any - of the special characters may be included in the prompt literally by + od, percent, and backslash) become literally part of the prompt. Any + of the special characters may be included in the prompt literally by preceding it with a backslash. Some examples: ?f%f:Standard input. - This prompt prints the filename, if known; otherwise the string "Stan- + This prompt prints the filename, if known; otherwise the string "Stan- dard input". ?f%f .?ltLine %lt:?pt%pt\%:?btByte %bt:-... - This prompt would print the filename, if known. The filename is fol- - lowed by the line number, if known, otherwise the percent if known, + This prompt would print the filename, if known. The filename is fol- + lowed by the line number, if known, otherwise the percent if known, otherwise the byte offset if known. Otherwise, a dash is printed. No- - tice how each question mark has a matching period, and how the % after + tice how each question mark has a matching period, and how the % after the %pt is included literally by escaping it with a backslash. ?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\: %x..%t"; - This prints the filename if this is the first prompt in a file, fol- - lowed by the "file N of N" message if there is more than one input - file. Then, if we are at end-of-file, the string "(END)" is printed - followed by the name of the next file, if there is one. Finally, any + This prints the filename if this is the first prompt in a file, fol- + lowed by the "file N of N" message if there is more than one input + file. Then, if we are at end-of-file, the string "(END)" is printed + followed by the name of the next file, if there is one. Finally, any trailing spaces are truncated. This is the default prompt. For refer- - ence, here are the defaults for the other two prompts (-m and -M re- + ence, here are the defaults for the other two prompts (-m and -M re- spectively). Each is broken into two lines here for readability only. ?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\: %x.: @@ -1595,22 +1616,22 @@ LESS(1) General Commands Manual LESS(1) ?f%f .?m(%T %i of %m) .?ltlines %lt-%lb?L/%L. . byte %bB?s/%s. ?e(END) :?pB%pB\%..%t - The prompt expansion features are also used for another purpose: if an - environment variable LESSEDIT is defined, it is used as the command to - be executed when the v command is invoked. The LESSEDIT string is ex- - panded in the same way as the prompt strings. The default value for + The prompt expansion features are also used for another purpose: if an + environment variable LESSEDIT is defined, it is used as the command to + be executed when the v command is invoked. The LESSEDIT string is ex- + panded in the same way as the prompt strings. The default value for LESSEDIT is: %E ?lm+%lm. %g Note that this expands to the editor name, followed by a + and the line - number, followed by the shell-escaped file name. If your editor does - not accept the "+linenumber" syntax, or has other differences in invo- - cation syntax, the LESSEDIT variable can be changed to modify this de- + number, followed by the shell-escaped file name. If your editor does + not accept the "+linenumber" syntax, or has other differences in invo- + cation syntax, the LESSEDIT variable can be changed to modify this de- fault. SECURITY - When the environment variable LESSSECURE is set to 1, less runs in a + When the environment variable LESSSECURE is set to 1, less runs in a "secure" mode. This means these features are disabled: ! the shell command @@ -1635,52 +1656,52 @@ LESS(1) General Commands Manual LESS(1) COMPATIBILITY WITH MORE If the environment variable LESS_IS_MORE is set to 1, or if the program - is invoked via a file link named "more", less behaves (mostly) in con- - formance with the POSIX "more" command specification. In this mode, + is invoked via a file link named "more", less behaves (mostly) in con- + formance with the POSIX "more" command specification. In this mode, less behaves differently in these ways: The -e option works differently. If the -e option is not set, less be- - haves as if the -e option were set. If the -e option is set, less be- + haves as if the -e option were set. If the -e option is set, less be- haves as if the -E option were set. - The -m option works differently. If the -m option is not set, the - medium prompt is used, and it is prefixed with the string "--More--". + The -m option works differently. If the -m option is not set, the + medium prompt is used, and it is prefixed with the string "--More--". If the -m option is set, the short prompt is used. - The -n option acts like the -z option. The normal behavior of the -n + The -n option acts like the -z option. The normal behavior of the -n option is unavailable in this mode. - The parameter to the -p option is taken to be a less command rather + The parameter to the -p option is taken to be a less command rather than a search pattern. - The LESS environment variable is ignored, and the MORE environment + The LESS environment variable is ignored, and the MORE environment variable is used in its place. ENVIRONMENT VARIABLES Environment variables may be specified either in the system environment - as usual, or in a lesskey(1) file. If environment variables are de- + as usual, or in a lesskey(1) file. If environment variables are de- fined in more than one place, variables defined in a local lesskey file take precedence over variables defined in the system environment, which take precedence over variables defined in the system-wide lesskey file. COLUMNS Sets the number of columns on the screen. Takes precedence over - the number of columns specified by the TERM variable. (But if + the number of columns specified by the TERM variable. (But if you have a windowing system which supports TIOCGWINSZ or - WIOCGETD, the window system's idea of the screen size takes + WIOCGETD, the window system's idea of the screen size takes precedence over the LINES and COLUMNS environment variables.) EDITOR The name of the editor (used for the v command). - HOME Name of the user's home directory (used to find a lesskey file + HOME Name of the user's home directory (used to find a lesskey file on Unix and OS/2 systems). HOMEDRIVE, HOMEPATH - Concatenation of the HOMEDRIVE and HOMEPATH environment vari- + Concatenation of the HOMEDRIVE and HOMEPATH environment vari- ables is the name of the user's home directory if the HOME vari- able is not set (only in the Windows version). - INIT Name of the user's init directory (used to find a lesskey file + INIT Name of the user's init directory (used to find a lesskey file on OS/2 systems). LANG Language for determining the character set. @@ -1691,12 +1712,12 @@ LESS(1) General Commands Manual LESS(1) LESS Options which are passed to less automatically. LESSANSIENDCHARS - Characters which may end an ANSI color escape sequence (default + Characters which may end an ANSI color escape sequence (default "m"). LESSANSIMIDCHARS - Characters which may appear between the ESC character and the - end character in an ANSI color escape sequence (default + Characters which may appear between the ESC character and the + end character in an ANSI color escape sequence (default "0123456789:;[?!"'#%()*+ ". LESSBINFMT @@ -1713,44 +1734,52 @@ LESS(1) General Commands Manual LESS(1) LESSECHO Name of the lessecho program (default "lessecho"). The lessecho - program is needed to expand metacharacters, such as * and ?, in + program is needed to expand metacharacters, such as * and ?, in filenames on Unix systems. LESSEDIT - Editor prototype string (used for the v command). See discus- + Editor prototype string (used for the v command). See discus- sion under PROMPTS. LESSGLOBALTAGS - Name of the command used by the -t option to find global tags. - Normally should be set to "global" if your system has the glob- + Name of the command used by the -t option to find global tags. + Normally should be set to "global" if your system has the glob- al(1) command. If not set, global tags are not used. LESSHISTFILE - Name of the history file used to remember search commands and - shell commands between invocations of 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" - on OS/2 systems. + Name of the history file used to remember search commands and + shell commands between invocations of less. If set to "-" or + "/dev/null", a history file is not used. The default is + "$XDG_DATA_HOME/lesshst" or "$HOME/.lesshst" on Unix systems, + "$HOME/_lesshst" on DOS and Windows systems, or + "$HOME/lesshst.ini" or "$INIT/lesshst.ini" on OS/2 systems. LESSHISTSIZE The maximum number of commands to save in the history file. The default is 100. + LESSKEYIN + Name of the default lesskey source file. + LESSKEY - Name of the default lesskey(1) file. + Name of the default lesskey binary file. (Not used if + "$LESSKEYIN" exists.) + + LESSKEYIN_SYSTEM + Name of the default system-wide lesskey source file. LESSKEY_SYSTEM - Name of the default system-wide lesskey(1) file. + Name of the default system-wide lesskey binary file. (Not used + if "$LESSKEYIN_SYSTEM" exists.) LESSMETACHARS - List of characters which are considered "metacharacters" by the + List of characters which are considered "metacharacters" by the shell. LESSMETAESCAPE - Prefix which less will add before each metacharacter in a com- - mand sent to the shell. If LESSMETAESCAPE is an empty string, - commands containing metacharacters will not be passed to the + Prefix which less will add before each metacharacter in a com- + mand sent to the shell. If LESSMETAESCAPE is an empty string, + commands containing metacharacters will not be passed to the shell. LESSOPEN @@ -1760,7 +1789,7 @@ LESS(1) General Commands Manual LESS(1) Runs less in "secure" mode. See discussion under SECURITY. LESSSEPARATOR - String to be appended to a directory name in filename comple- + String to be appended to a directory name in filename comple- tion. LESSUTFBINFMT @@ -1769,19 +1798,19 @@ LESS(1) General Commands Manual LESS(1) LESS_IS_MORE Emulate the more(1) command. - LINES Sets the number of lines on the screen. Takes precedence over + LINES Sets the number of lines on the screen. Takes precedence over the number of lines specified by the TERM variable. (But if you - have a windowing system which supports TIOCGWINSZ or WIOCGETD, - the window system's idea of the screen size takes precedence + have a windowing system which supports TIOCGWINSZ or WIOCGETD, + the window system's idea of the screen size takes precedence over the LINES and COLUMNS environment variables.) - MORE Options which are passed to less automatically when running in + MORE Options which are passed to less automatically when running in more compatible mode. - PATH User's search path (used to find a lesskey file on MS-DOS and + PATH User's search path (used to find a lesskey file on MS-DOS and OS/2 systems). - SHELL The shell used to execute the ! command, as well as to expand + SHELL The shell used to execute the ! command, as well as to expand filenames. TERM The type of terminal on which less is being run. @@ -1794,27 +1823,27 @@ LESS(1) General Commands Manual LESS(1) COPYRIGHT Copyright (C) 1984-2021 Mark Nudelman - less is part of the GNU project and is free software. You can redis- - tribute it and/or modify it under the terms of either (1) the GNU Gen- - eral Public License as published by the Free Software Foundation; or + less is part of the GNU project and is free software. You can redis- + tribute it and/or modify it under the terms of either (1) the GNU Gen- + eral Public License as published by the Free Software Foundation; or (2) the Less License. See the file README in the less distribution for more details regarding redistribution. You should have received a copy - of the GNU General Public License along with the source for less; see - the file COPYING. If not, write to the Free Software Foundation, 59 - Temple Place, Suite 330, Boston, MA 02111-1307, USA. You should also + of the GNU General Public License along with the source for less; see + the file COPYING. If not, write to the Free Software Foundation, 59 + Temple Place, Suite 330, Boston, MA 02111-1307, USA. You should also have received a copy of the Less License; see the file LICENSE. less is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FIT- - NESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + WARRANTY; without even the implied warranty of MERCHANTABILITY or FIT- + NESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. AUTHOR Mark Nudelman Report bugs at https://github.com/gwsw/less/issues. For more information, see the less homepage at - https://greenwoodsoftware.com/less. + https://greenwoodsoftware.com/less - Version 581.2: 28 Apr 2021 LESS(1) + Version 590: 03 Jun 2021 LESS(1) diff --git a/less.nro b/less.nro index f148ccb76d98..7c8372b500c6 100644 --- a/less.nro +++ b/less.nro @@ -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 diff --git a/lessecho.man b/lessecho.man index 6a47aba2dab6..ec33d196967e 100644 --- a/lessecho.man +++ b/lessecho.man @@ -51,4 +51,4 @@ LESSECHO(1) General Commands Manual LESSECHO(1) - Version 581.2: 28 Apr 2021 LESSECHO(1) + Version 590: 03 Jun 2021 LESSECHO(1) diff --git a/lessecho.nro b/lessecho.nro index 484efa135d34..4733a93edd68 100644 --- a/lessecho.nro +++ b/lessecho.nro @@ -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 diff --git a/lesskey.c b/lesskey.c index de7a9bfc8311..b5130cccb8f7 100644 --- a/lesskey.c +++ b/lesskey.c @@ -80,121 +80,12 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include "less.h" +#include +#include +#include #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)); diff --git a/lesskey.h b/lesskey.h index 3a8f83682a90..1e70a7fe09a5 100644 --- a/lesskey.h +++ b/lesskey.h @@ -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); diff --git a/lesskey.man b/lesskey.man index 36a629ef850e..56c75db080b6 100644 --- a/lesskey.man +++ b/lesskey.man @@ -5,34 +5,21 @@ LESSKEY(1) General Commands Manual LESSKEY(1) NAME lesskey - specify key bindings for less -SYNOPSIS +SYNOPSIS (deprecated) lesskey [-o output] [--] [input] lesskey [--output=output] [--] [input] lesskey -V lesskey --version -DESCRIPTION - Lesskey is used to specify a set of key bindings to be used by 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 speci- - fied, 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 unde- - fined. The output file is a binary file which is used by 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. Other- - wise, 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, lesskey will overwrite - it. - - The -V or --version option causes lesskey to print its version number - and immediately exit. If -V or --version is present, other options and - arguments are ignored. +SCOPE + This document describes the format of the lesskey source file, which is + used by less version 582 and later. In previous versions of less, a + separate program called lesskey was used to compile the lesskey source + file into a format understood by less. This compilation step is no + longer required and the lesskey program is therefore deprecated al- + though the file format remains supported by less itself. +FILE FORMAT The input file consists of one or more sections. Each section starts with a line that identifies the type of section. Possible sections are: @@ -129,7 +116,6 @@ LESSKEY(1) General Commands Manual LESSKEY(1) J forw-line-force K back-line-force Y back-line-force - d forw-scroll ^D forw-scroll u back-scroll @@ -143,6 +129,7 @@ LESSKEY(1) General Commands Manual LESSKEY(1) ^B back-screen \ev back-screen \kU back-screen + z forw-window w back-window \e\40 forw-screen-force @@ -195,7 +182,6 @@ LESSKEY(1) General Commands Manual LESSKEY(1) & filter m set-mark M set-mark-bottom - \em clear-mark ' goto-mark ^X^X goto-mark @@ -209,6 +195,7 @@ LESSKEY(1) General Commands Manual LESSKEY(1) :x index-file :d remove-file - toggle-option + :t toggle-option t s toggle-option o _ display-option @@ -274,6 +261,7 @@ LESSKEY(1) General Commands Manual LESSKEY(1) \t forw-complete \17 back-complete \e\t back-complete + ^L expand ^V literal ^A literal @@ -358,4 +346,4 @@ LESSKEY(1) General Commands Manual LESSKEY(1) - Version 581.2: 28 Apr 2021 LESSKEY(1) + Version 590: 03 Jun 2021 LESSKEY(1) diff --git a/lesskey.nro b/lesskey.nro index 1f8e5b39ecaf..9b3ec1672f9c 100644 --- a/lesskey.nro +++ b/lesskey.nro @@ -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. diff --git a/lesskey_parse.c b/lesskey_parse.c new file mode 100644 index 000000000000..18cdf3753d53 --- /dev/null +++ b/lesskey_parse.c @@ -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 +#include +#include +#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); +} diff --git a/line.c b/line.c index 57d3cbef2f4d..b8f609e9d4df 100644 --- a/line.c +++ b/line.c @@ -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); diff --git a/linenum.c b/linenum.c index 00cac60d14d3..a3e1b2fcb52d 100644 --- a/linenum.c +++ b/linenum.c @@ -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; + } +} diff --git a/optfunc.c b/optfunc.c index 768fe0e98aed..9e7c86925b3a 100644 --- a/optfunc.c +++ b/optfunc.c @@ -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. diff --git a/opttbl.c b/opttbl.c index 3a5d28385162..73f8435043e6 100644 --- a/opttbl.c +++ b/opttbl.c @@ -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, diff --git a/output.c b/output.c index ddb6ad2779af..a865f4f0ce0b 100644 --- a/output.c +++ b/output.c @@ -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. */ diff --git a/screen.c b/screen.c index ff6b6d785af7..033a5b9cf23f 100644 --- a/screen.c +++ b/screen.c @@ -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); diff --git a/tags.c b/tags.c index d449c0333deb..23a9b92f018b 100644 --- a/tags.c +++ b/tags.c @@ -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); diff --git a/version.c b/version.c index 7ca31e0930fa..cab2690176fe 100644 --- a/version.c +++ b/version.c @@ -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"; diff --git a/xbuf.c b/xbuf.c new file mode 100644 index 000000000000..f20dfae1e7df --- /dev/null +++ b/xbuf.c @@ -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; +} diff --git a/xbuf.h b/xbuf.h new file mode 100644 index 000000000000..ba62ef1722b1 --- /dev/null +++ b/xbuf.h @@ -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