Update less to v436. This is considered as a bugfix release from vendor.

Major changes from v429:
 * Don't pass "-" to non-pipe LESSOPEN unless it starts with "-".
 * Allow a fraction as the argument to the -# (--shift) option.
 * Fix highlight bug when underlined/overstruck text matches at end of line.
 * Fix non-regex searches with ctrl-R.

Approved by:	re (kensmith, kib)
This commit is contained in:
Xin LI 2009-07-29 09:20:32 +00:00
commit f0be0a1f8c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=195941
71 changed files with 1135 additions and 1037 deletions

View File

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

View File

@ -10,10 +10,10 @@ srcdir = .
SRC = \ SRC = \
main.c screen.c brac.c ch.c charset.c cmdbuf.c \ main.c screen.c brac.c ch.c charset.c cmdbuf.c \
command.c decode.c edit.c filename.c forwback.c \ command.c cvt.c decode.c edit.c filename.c forwback.c \
help.c ifile.c input.c jump.c line.c linenum.c \ help.c ifile.c input.c jump.c line.c linenum.c \
lsystem.c mark.c optfunc.c option.c opttbl.c os.c \ lsystem.c mark.c optfunc.c option.c opttbl.c os.c \
output.c position.c prompt.c search.c signal.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
DISTFILES_W = \ DISTFILES_W = \
defines.ds Makefile.dsb Makefile.dsg Makefile.dsu \ defines.ds Makefile.dsb Makefile.dsg Makefile.dsu \
@ -24,7 +24,8 @@ DISTFILES = \
${SRC} regexp.c regexp.h \ ${SRC} regexp.c regexp.h \
COPYING INSTALL LICENSE Makefile.in Makefile.aut NEWS README \ COPYING INSTALL LICENSE Makefile.in Makefile.aut NEWS README \
configure configure.ac lesskey.c lessecho.c scrsize.c \ configure configure.ac lesskey.c lessecho.c scrsize.c \
charset.h cmd.h funcs.h lglob.h less.h lesskey.h option.h pckeys.h position.h \ charset.h cmd.h funcs.h lglob.h less.h lesskey.h option.h \
pckeys.h pattern.h position.h \
install.sh defines.h.in mkinstalldirs \ install.sh defines.h.in mkinstalldirs \
less.nro less.man lesskey.nro lesskey.man lessecho.nro lessecho.man \ less.nro less.man lesskey.nro lesskey.man lessecho.nro lessecho.man \
less.hlp \ less.hlp \
@ -109,6 +110,8 @@ dist: ${DISTFILES}
cd $$REL; chmod +w ${DISTFILES_W}; cd ..; \ cd $$REL; chmod +w ${DISTFILES_W}; cd ..; \
echo "Creating release/$$REL/$$REL.tar.gz"; \ echo "Creating release/$$REL/$$REL.tar.gz"; \
tar -cf - $$REL | gzip -c >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; \
echo "Creating release/$$REL/$$REL.zip"; \ echo "Creating release/$$REL/$$REL.zip"; \
zip -rq release/$$REL/$$REL.zip $$REL; \ zip -rq release/$$REL/$$REL.zip $$REL; \
rm -rf $$REL rm -rf $$REL

View File

@ -18,12 +18,13 @@ EXT = .EXE
.c.obj: .c.obj:
$(CC) -c -I. $(CPPFLAGS) $(CFLAGS) $< $(CC) -c -I. $(CPPFLAGS) $(CFLAGS) $<
OBJ = main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj command.obj \ OBJ = \
decode.obj edit.obj filename.obj forwback.obj help.obj ifile.obj \ main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj \
input.obj jump.obj line.obj linenum.obj lsystem.obj \ command.obj cvt.obj decode.obj edit.obj filename.obj forwback.obj \
mark.obj optfunc.obj option.obj opttbl.obj os.obj output.obj \ help.obj ifile.obj input.obj jump.obj line.obj linenum.obj \
position.obj prompt.obj search.obj signal.obj tags.obj \ lsystem.obj mark.obj optfunc.obj option.obj opttbl.obj os.obj \
ttyin.obj version.obj output.obj pattern.obj position.obj prompt.obj search.obj signal.obj \
tags.obj ttyin.obj version.obj
all: less$(EXT) lesskey$(EXT) all: less$(EXT) lesskey$(EXT)

View File

@ -33,11 +33,12 @@ manext = 1
.c.o: .c.o:
${CC} -I. ${CFLAGS_COMPILE_ONLY} -DBINDIR=\"${bindir}\" -DSYSDIR=\"${sysconfdir}\" ${CPPFLAGS} ${CFLAGS} $< ${CC} -I. ${CFLAGS_COMPILE_ONLY} -DBINDIR=\"${bindir}\" -DSYSDIR=\"${sysconfdir}\" ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \ OBJ = \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \ 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} \ lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \
output.${O} position.${O} prompt.${O} search.${O} signal.${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}
all: less lesskey lessecho all: less lesskey lessecho

View File

@ -27,12 +27,13 @@ LIBS = $(LIBDIR)\llibce.lib $(LIBDIR)\graphics.lib
.c.obj: .c.obj:
$(CC) -c -I. -I$(INCDIR) $(CPPFLAGS) $(CFLAGS) $< $(CC) -c -I. -I$(INCDIR) $(CPPFLAGS) $(CFLAGS) $<
OBJ = main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj command.obj \ OBJ = \
decode.obj edit.obj filename.obj forwback.obj help.obj ifile.obj \ main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj \
input.obj jump.obj line.obj linenum.obj lsystem.obj \ command.obj cvt.obj decode.obj edit.obj filename.obj forwback.obj \
mark.obj optfunc.obj option.obj opttbl.obj os.obj output.obj \ help.obj ifile.obj input.obj jump.obj line.obj linenum.obj \
position.obj prompt.obj search.obj signal.obj tags.obj \ lsystem.obj mark.obj optfunc.obj option.obj opttbl.obj os.obj \
ttyin.obj version.obj output.obj pattern.obj position.obj prompt.obj search.obj signal.obj \
tags.obj ttyin.obj version.obj
all: less lesskey all: less lesskey

View File

@ -43,11 +43,12 @@ SHELL = /bin/sh
.c.o: .c.o:
${CC} -I. ${CFLAGS_COMPILE_ONLY} -DBINDIR=\"${bindir}\" -DSYSDIR=\"${sysconfdir}\" ${CPPFLAGS} ${CFLAGS} $< ${CC} -I. ${CFLAGS_COMPILE_ONLY} -DBINDIR=\"${bindir}\" -DSYSDIR=\"${sysconfdir}\" ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \ OBJ = \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \ 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} \ lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \
output.${O} position.${O} prompt.${O} search.${O} signal.${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} @REGEX_O@
all: less$(EXEEXT) lesskey$(EXEEXT) lessecho$(EXEEXT) all: less$(EXEEXT) lesskey$(EXEEXT) lessecho$(EXEEXT)

View File

@ -18,11 +18,12 @@ O = obj
.c.${O}: .c.${O}:
${CC} -c ${CPPFLAGS} ${CFLAGS} $< ${CC} -c ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \ OBJ = \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \ 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} \ lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \
output.${O} position.${O} prompt.${O} search.${O} signal.${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} regexp.${O}
all: less.exe lesskey.exe scrsize.exe all: less.exe lesskey.exe scrsize.exe

View File

@ -22,11 +22,12 @@ O = r
.c.${O}: .c.${O}:
${CC} ${CFLAGS_COMPILE_ONLY} ${CPPFLAGS} ${CFLAGS} $< ${CC} ${CFLAGS_COMPILE_ONLY} ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \ OBJ = \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \ 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} \ lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \
output.${O} position.${O} prompt.${O} search.${O} signal.${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} regexp.${O}
all: less lessecho lesskey all: less lessecho lesskey

View File

@ -21,11 +21,12 @@ O = r
.c.${O}: .c.${O}:
${CC} ${CFLAGS_COMPILE_ONLY} ${CPPFLAGS} ${CFLAGS} $< ${CC} ${CFLAGS_COMPILE_ONLY} ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \ OBJ = \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \ 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} \ lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \
output.${O} position.${O} prompt.${O} search.${O} signal.${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} regexp.${O}
all: less lesskey all: less lesskey

View File

@ -25,12 +25,13 @@ LIBS = ${LIBDIR}\import32.lib ${LIBDIR}\cw32.lib
.c.obj: .c.obj:
${CC} -c -I. ${CPPFLAGS} ${CFLAGS} $< ${CC} -c -I. ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj command.obj \ OBJ = \
decode.obj edit.obj filename.obj forwback.obj help.obj ifile.obj \ main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj \
input.obj jump.obj line.obj linenum.obj lsystem.obj \ command.obj cvt.obj decode.obj edit.obj filename.obj forwback.obj \
mark.obj optfunc.obj option.obj opttbl.obj os.obj output.obj \ help.obj ifile.obj input.obj jump.obj line.obj linenum.obj \
position.obj prompt.obj search.obj signal.obj tags.obj \ lsystem.obj mark.obj optfunc.obj option.obj opttbl.obj os.obj \
ttyin.obj version.obj regexp.obj output.obj pattern.obj position.obj prompt.obj search.obj signal.obj \
tags.obj ttyin.obj version.obj regexp.obj
all: less lesskey lessecho all: less lesskey lessecho

View File

@ -23,12 +23,13 @@ LIBS = user32.lib
.c.obj: .c.obj:
$(CC) $(CFLAGS) $< $(CC) $(CFLAGS) $<
OBJ = main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj command.obj \ OBJ = \
decode.obj edit.obj filename.obj forwback.obj help.obj ifile.obj \ main.obj screen.obj brac.obj ch.obj charset.obj cmdbuf.obj \
input.obj jump.obj line.obj linenum.obj lsystem.obj \ command.obj cvt.obj decode.obj edit.obj filename.obj forwback.obj \
mark.obj optfunc.obj option.obj opttbl.obj os.obj output.obj \ help.obj ifile.obj input.obj jump.obj line.obj linenum.obj \
position.obj prompt.obj search.obj signal.obj tags.obj \ lsystem.obj mark.obj optfunc.obj option.obj opttbl.obj os.obj \
ttyin.obj version.obj regexp.obj output.obj pattern.obj position.obj prompt.obj search.obj signal.obj \
tags.obj ttyin.obj version.obj regexp.obj
all: less.exe lesskey.exe all: less.exe lesskey.exe

View File

@ -10,6 +10,18 @@
To report bugs, suggestions or comments, send email to To report bugs, suggestions or comments, send email to
bug-less@gnu.org or markn@greenwoodsoftware.com. bug-less@gnu.org or markn@greenwoodsoftware.com.
======================================================================
Major changes between "less" versions 429 and 436
* Don't pass "-" to non-pipe LESSOPEN unless it starts with "-".
* Allow a fraction as the argument to the -# (--shift) option.
* Fix highlight bug when underlined/overstruck text matches at end of line.
* Fix non-regex searches with ctrl-R.
====================================================================== ======================================================================
Major changes between "less" versions 424 and 429 Major changes between "less" versions 424 and 429

View File

@ -1,7 +1,7 @@
Less, version 429 Less, version 436
This is the distribution of less, version 429, released 11 Apr 2009. This is the distribution of less, version 436, released 07 Jul 2009.
This program is part of the GNU project (http://www.gnu.org). This program is part of the GNU project (http://www.gnu.org).
This program is free software. You may redistribute it and/or This program is free software. You may redistribute it and/or

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2008 Mark Nudelman * Copyright (C) 1984-2009 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -425,7 +425,7 @@ prchar(c)
c &= 0377; c &= 0377;
if ((c < 128 || !utf_mode) && !control_char(c)) if ((c < 128 || !utf_mode) && !control_char(c))
SNPRINTF1(buf, sizeof(buf), "%c", c); SNPRINTF1(buf, sizeof(buf), "%c", (int) c);
else if (c == ESC) else if (c == ESC)
strcpy(buf, "ESC"); strcpy(buf, "ESC");
#if IS_EBCDIC_HOST #if IS_EBCDIC_HOST
@ -442,7 +442,7 @@ prchar(c)
"..V....D....TU.Z"[c]); "..V....D....TU.Z"[c]);
#else #else
else if (c < 128 && !control_char(c ^ 0100)) else if (c < 128 && !control_char(c ^ 0100))
SNPRINTF1(buf, sizeof(buf), "^%c", c ^ 0100); SNPRINTF1(buf, sizeof(buf), "^%c", (int) (c ^ 0100));
#endif #endif
else else
SNPRINTF1(buf, sizeof(buf), binfmt, c); SNPRINTF1(buf, sizeof(buf), binfmt, c);

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
# Copyright (C) 1984-2008 Mark Nudelman # Copyright (C) 1984-2009 Mark Nudelman
# #
# You may distribute under the terms of either the GNU General Public # You may distribute under the terms of either the GNU General Public
# License or the Less License, as specified in the README file. # License or the Less License, as specified in the README file.

120
contrib/less/cvt.c Normal file
View File

@ -0,0 +1,120 @@
/*
* Copyright (C) 1984-2009 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 about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines to convert text in various ways. Used by search.
*/
#include "less.h"
#include "charset.h"
extern int utf_mode;
/*
* Get the length of a buffer needed to convert a string.
*/
public int
cvt_length(len, ops)
int len;
int ops;
{
if (utf_mode)
/*
* Just copying a string in UTF-8 mode can cause it to grow
* in length.
* Four output bytes for one input byte is the worst case.
*/
len *= 4;
return (len + 1);
}
/*
* Allocate a chpos array for use by cvt_text.
*/
public int *
cvt_alloc_chpos(len)
int len;
{
int i;
int *chpos = (int *) ecalloc(sizeof(int), len);
/* Initialize all entries to an invalid position. */
for (i = 0; i < len; i++)
chpos[i] = -1;
return (chpos);
}
/*
* Convert text. Perform the transformations specified by ops.
* Returns converted text in odst. The original offset of each
* odst character (when it was in osrc) is returned in the chpos array.
*/
public void
cvt_text(odst, osrc, chpos, lenp, ops)
char *odst;
char *osrc;
int *chpos;
int *lenp;
int ops;
{
char *dst;
char *src;
register char *src_end;
LWCHAR ch;
if (lenp != NULL)
src_end = osrc + *lenp;
else
src_end = osrc + strlen(osrc);
for (src = osrc, dst = odst; src < src_end; )
{
int src_pos = src - osrc;
int dst_pos = dst - odst;
ch = step_char(&src, +1, src_end);
if ((ops & CVT_BS) && ch == '\b' && dst > odst)
{
/* Delete backspace and preceding char. */
do {
dst--;
} while (dst > odst &&
!IS_ASCII_OCTET(*dst) && !IS_UTF8_LEAD(*dst));
} else if ((ops & CVT_ANSI) && IS_CSI_START(ch))
{
/* Skip to end of ANSI escape sequence. */
src++; /* skip the CSI start char */
while (src < src_end)
if (!is_ansi_middle(*src++))
break;
} else
{
/* Just copy the char to the destination buffer. */
if ((ops & CVT_TO_LC) && IS_UPPER(ch))
ch = TO_LOWER(ch);
put_wchar(&dst, ch);
/*
* Record the original position of the char.
* But if we've already recorded a position
* for this char (due to a backspace), leave
* it alone; if multiple source chars map to
* one destination char, we want the position
* of the first one.
*/
if (chpos != NULL && chpos[dst_pos] < 0)
chpos[dst_pos] = src_pos;
}
}
if ((ops & CVT_CRLF) && dst > odst && dst[-1] == '\r')
dst--;
*dst = '\0';
if (lenp != NULL)
*lenp = dst - odst;
if (chpos != NULL)
chpos[dst - odst] = src - osrc;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2008 Mark Nudelman * Copyright (C) 1984-2009 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -843,17 +843,17 @@ open_altfile(filename, pf, pfd)
#else #else
lessopen++; lessopen++;
returnfd = 1; returnfd = 1;
if (*lessopen == '-') {
/*
* Lessopen preprocessor will accept "-" as a filename.
*/
lessopen++;
} else {
if (strcmp(filename, "-") == 0)
return (NULL);
}
#endif #endif
} }
if (*lessopen == '-') {
/*
* Lessopen preprocessor will accept "-" as a filename.
*/
lessopen++;
} else {
if (strcmp(filename, "-") == 0)
return (NULL);
}
len = strlen(lessopen) + strlen(filename) + 2; len = strlen(lessopen) + strlen(filename) + 2;
cmd = (char *) ecalloc(len, sizeof(char)); cmd = (char *) ecalloc(len, sizeof(char));

View File

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

View File

@ -83,6 +83,9 @@
public void ungetcc (); public void ungetcc ();
public void ungetsc (); public void ungetsc ();
public void commands (); public void commands ();
public int cvt_length ();
public int * cvt_alloc_chpos ();
public void cvt_text ();
public void init_cmds (); public void init_cmds ();
public void add_fcmd_table (); public void add_fcmd_table ();
public void add_ecmd_table (); public void add_ecmd_table ();
@ -193,6 +196,8 @@
public void opt_l (); public void opt_l ();
public void opt_j (); public void opt_j ();
public void calc_jump_sline (); public void calc_jump_sline ();
public void opt_shift ();
public void calc_shift_count ();
public void opt_k (); public void opt_k ();
public void opt_t (); public void opt_t ();
public void opt__T (); public void opt__T ();
@ -233,6 +238,10 @@
public void error (); public void error ();
public void ierror (); public void ierror ();
public int query (); public int query ();
public int compile_pattern ();
public void uncompile_pattern ();
public int is_null_pattern ();
public int match_pattern ();
public POSITION position (); public POSITION position ();
public void add_forw_pos (); public void add_forw_pos ();
public void add_back_pos (); public void add_back_pos ();
@ -248,6 +257,7 @@
public char * eq_message (); public char * eq_message ();
public char * pr_string (); public char * pr_string ();
public char * wait_message (); public char * wait_message ();
public void init_search ();
public void repaint_hilite (); public void repaint_hilite ();
public void clear_attn (); public void clear_attn ();
public void undo_search (); public void undo_search ();

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2008 Mark Nudelman * Copyright (C) 1984-2009 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -196,7 +196,7 @@ forw_line(curr_pos)
c = ch_forw_get(); c = ch_forw_get();
} }
pdone(endline, c); pdone(endline, 1);
#if HILITE_SEARCH #if HILITE_SEARCH
if (is_filtered(base_pos)) if (is_filtered(base_pos))
@ -398,7 +398,7 @@ back_line(curr_pos)
} }
} while (new_pos < curr_pos); } while (new_pos < curr_pos);
pdone(endline, ch_forw_get()); pdone(endline, 0);
#if HILITE_SEARCH #if HILITE_SEARCH
if (is_filtered(base_pos)) if (is_filtered(base_pos))

View File

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

View File

@ -1,6 +1,6 @@
/* $FreeBSD$ */ /* $FreeBSD$ */
/* /*
* Copyright (C) 1984-2008 Mark Nudelman * Copyright (C) 1984-2009 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -489,6 +489,12 @@ struct textlist
#define FAKE_HELPFILE "@/\\less/\\help/\\file/\\@" #define FAKE_HELPFILE "@/\\less/\\help/\\file/\\@"
/* Flags for cvt_text */
#define CVT_TO_LC 01 /* Convert upper-case to lower-case */
#define CVT_BS 02 /* Do backspace processing */
#define CVT_CRLF 04 /* Remove CR after LF */
#define CVT_ANSI 010 /* Remove ANSI escape sequences */
#include "funcs.h" #include "funcs.h"
/* Functions not included in funcs.h */ /* Functions not included in funcs.h */

View File

@ -809,51 +809,58 @@ LESS(1) LESS(1)
Specifies the default number of positions to scroll horizontally Specifies the default number of positions to scroll horizontally
in the RIGHTARROW and LEFTARROW commands. If the number speci- in the RIGHTARROW and LEFTARROW commands. If the number speci-
fied is zero, it sets the default number of positions to one fied is zero, it sets the default number of positions to one
half of the screen width. half of the screen width. Alternately, the number may be speci-
fied as a fraction of the width of the screen, starting with a
decimal point: .5 is half of the screen width, .3 is three
tenths of the screen width, and so on. If the number is speci-
fied 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.
--no-keypad --no-keypad
Disables sending the keypad initialization and deinitialization Disables sending the keypad initialization and deinitialization
strings to the terminal. This is sometimes useful if the keypad strings to the terminal. This is sometimes useful if the keypad
strings make the numeric keypad behave in an undesirable manner. strings make the numeric keypad behave in an undesirable manner.
--follow-name --follow-name
Normally, if the input file is renamed while an F command is Normally, if the input file is renamed while an F command is
executing, less will continue to display the contents of the executing, less will continue to display the contents of the
original file despite its name change. If --follow-name is original file despite its name change. If --follow-name is
specified, during an F command less will periodically attempt to specified, during an F command less will periodically attempt to
reopen the file by name. If the reopen succeeds and the file is reopen the file by name. If the reopen succeeds and the file is
a different file from the original (which means that a new file a different file from the original (which means that a new file
has been created with the same name as the original (now has been created with the same name as the original (now
renamed) file), less will display the contents of that new file. renamed) file), less will display the contents of that new file.
-- A command line argument of "--" marks the end of option argu- -- A command line argument of "--" marks the end of option argu-
ments. Any arguments following this are interpreted as file- ments. Any arguments following this are interpreted as file-
names. This can be useful when viewing a file whose name begins names. This can be useful when viewing a file whose name begins
with a "-" or "+". with a "-" or "+".
+ If a command line option begins with +, the remainder of that + If a command line option begins with +, the remainder of that
option is taken to be an initial command to less. For example, option is taken to be an initial command to less. For example,
+G tells less to start at the end of the file rather than the +G tells less to start at the end of the file rather than the
beginning, and +/xyz tells it to start at the first occurrence beginning, and +/xyz tells it to start at the first occurrence
of "xyz" in the file. As a special case, +<number> acts like of "xyz" in the file. As a special case, +<number> acts like
+<number>g; that is, it starts the display at the specified line +<number>g; that is, it starts the display at the specified line
number (however, see the caveat under the "g" command above). number (however, see the caveat under the "g" command above).
If the option starts with ++, the initial command applies to If the option starts with ++, the initial command applies to
every file being viewed, not just the first one. The + command every file being viewed, not just the first one. The + command
described previously may also be used to set (or change) an ini- described previously may also be used to set (or change) an ini-
tial command for every file. tial command for every file.
LINE EDITING LINE EDITING
When entering command line at the bottom of the screen (for example, a When entering command line at the bottom of the screen (for example, a
filename for the :e command, or the pattern for a search command), cer- filename for the :e command, or the pattern for a search command), cer-
tain keys can be used to manipulate the command line. Most commands tain keys can be used to manipulate the command line. Most commands
have an alternate form in [ brackets ] which can be used if a key does have an alternate form in [ brackets ] which can be used if a key does
not exist on a particular keyboard. (Note that the forms beginning not exist on a particular keyboard. (Note that the forms beginning
with ESC do not work in some MS-DOS and Windows systems because ESC is with ESC do not work in some MS-DOS and Windows systems because ESC is
the line erase character.) Any of these special keys may be entered the line erase character.) Any of these special keys may be entered
literally by preceding it with the "literal" character, either ^V or literally by preceding it with the "literal" character, either ^V or
^A. A backslash itself may also be entered literally by entering two ^A. A backslash itself may also be entered literally by entering two
backslashes. backslashes.
LEFTARROW [ ESC-h ] LEFTARROW [ ESC-h ]
@ -863,7 +870,7 @@ LESS(1) LESS(1)
Move the cursor one space to the right. Move the cursor one space to the right.
^LEFTARROW [ ESC-b or ESC-LEFTARROW ] ^LEFTARROW [ ESC-b or ESC-LEFTARROW ]
(That is, CONTROL and LEFTARROW simultaneously.) Move the cur- (That is, CONTROL and LEFTARROW simultaneously.) Move the cur-
sor one word to the left. sor one word to the left.
^RIGHTARROW [ ESC-w or ESC-RIGHTARROW ] ^RIGHTARROW [ ESC-w or ESC-RIGHTARROW ]
@ -877,18 +884,18 @@ LESS(1) LESS(1)
Move the cursor to the end of the line. Move the cursor to the end of the line.
BACKSPACE BACKSPACE
Delete the character to the left of the cursor, or cancel the Delete the character to the left of the cursor, or cancel the
command if the command line is empty. command if the command line is empty.
DELETE or [ ESC-x ] DELETE or [ ESC-x ]
Delete the character under the cursor. Delete the character under the cursor.
^BACKSPACE [ ESC-BACKSPACE ] ^BACKSPACE [ ESC-BACKSPACE ]
(That is, CONTROL and BACKSPACE simultaneously.) Delete the (That is, CONTROL and BACKSPACE simultaneously.) Delete the
word to the left of the cursor. word to the left of the cursor.
^DELETE [ ESC-X or ESC-DELETE ] ^DELETE [ ESC-X or ESC-DELETE ]
(That is, CONTROL and DELETE simultaneously.) Delete the word (That is, CONTROL and DELETE simultaneously.) Delete the word
under the cursor. under the cursor.
UPARROW [ ESC-k ] UPARROW [ ESC-k ]
@ -897,96 +904,96 @@ LESS(1) LESS(1)
DOWNARROW [ ESC-j ] DOWNARROW [ ESC-j ]
Retrieve the next command line. Retrieve the next command line.
TAB Complete the partial filename to the left of the cursor. If it TAB Complete the partial filename to the left of the cursor. If it
matches more than one filename, the first match is entered into matches more than one filename, the first match is entered into
the command line. Repeated TABs will cycle thru the other the command line. Repeated TABs will cycle thru the other
matching filenames. If the completed filename is a directory, a matching filenames. If the completed filename is a directory, a
"/" is appended to the filename. (On MS-DOS systems, a "\" is "/" is appended to the filename. (On MS-DOS systems, a "\" is
appended.) The environment variable LESSSEPARATOR can be used appended.) The environment variable LESSSEPARATOR can be used
to specify a different character to append to a directory name. to specify a different character to append to a directory name.
BACKTAB [ ESC-TAB ] BACKTAB [ ESC-TAB ]
Like, TAB, but cycles in the reverse direction thru the matching Like, TAB, but cycles in the reverse direction thru the matching
filenames. filenames.
^L Complete the partial filename to the left of the cursor. If it ^L Complete the partial filename to the left of the cursor. If it
matches more than one filename, all matches are entered into the matches more than one filename, all matches are entered into the
command line (if they fit). command line (if they fit).
^U (Unix and OS/2) or ESC (MS-DOS) ^U (Unix and OS/2) or ESC (MS-DOS)
Delete the entire command line, or cancel the command if the Delete the entire command line, or cancel the command if the
command line is empty. If you have changed your line-kill char- command line is empty. If you have changed your line-kill char-
acter in Unix to something other than ^U, that character is used acter in Unix to something other than ^U, that character is used
instead of ^U. instead of ^U.
KEY BINDINGS KEY BINDINGS
You may define your own less commands by using the program lesskey (1) 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 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 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 change the line-editing keys (see LINE EDITING), and to set environment
variables. If the environment variable LESSKEY is set, less uses that variables. If the environment variable LESSKEY is set, less uses that
as the name of the lesskey file. Otherwise, less looks in a standard 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 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 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, 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 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 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 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 "less.ini" in any directory specified
in the INIT environment variable, and if it not found there, then looks 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 for a lesskey file called "less.ini" in any directory specified in the
PATH environment variable. See the lesskey manual page for more PATH environment variable. See the lesskey manual page for more
details. details.
A system-wide lesskey file may also be set up to provide key bindings. 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 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 file, key bindings in the local file take precedence over those in the
system-wide file. If the environment variable LESSKEY_SYSTEM is set, 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 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 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. Unix systems, the system-wide lesskey file is /usr/local/etc/sysless.
(However, if less was built with a different sysconf directory than (However, if less was built with a different sysconf directory than
/usr/local/etc, that directory is where the sysless file is found.) On /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- 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. less. On OS/2 systems, the system-wide lesskey file is c:\sysless.ini.
INPUT PREPROCESSOR 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 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- the contents of the file are displayed. An input preprocessor is sim-
ply an executable program (or shell script), which writes the contents ply an executable program (or shell script), which writes the contents
of the file to a different file, called the replacement file. The con- 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 replacement file are then displayed in place of the con-
tents of the original file. However, it will appear to the user as if 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 the original file is opened; that is, less will display the original
filename as the name of the current file. filename as the name of the current file.
An input preprocessor receives one command line argument, the original An input preprocessor receives one command line argument, the original
filename, as entered by the user. It should create the replacement filename, as entered by the user. It should create the replacement
file, and when finished, print the name of the replacement file to its file, and when finished, print the name of the replacement file to its
standard output. If the input preprocessor does not output a replace- standard output. If the input preprocessor does not output a replace-
ment filename, less uses the original file, as normal. The input pre- ment filename, less uses the original file, as normal. The input pre-
processor is not called when viewing standard input. To set up an processor is not called when viewing standard input. To set up an
input preprocessor, set the LESSOPEN environment variable to a command input preprocessor, set the LESSOPEN environment variable to a command
line which will invoke your input preprocessor. This command line line which will invoke your input preprocessor. This command line
should include one occurrence of the string "%s", which will be should include one occurrence of the string "%s", which will be
replaced by the filename when the input preprocessor command is replaced by the filename when the input preprocessor command is
invoked. invoked.
When less closes a file opened in such a way, it will call another pro- 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 gram, called the input postprocessor, which may perform any desired
clean-up action (such as deleting the replacement file created by clean-up action (such as deleting the replacement file created by
LESSOPEN). This program receives two command line arguments, the orig- LESSOPEN). This program receives two command line arguments, the orig-
inal filename as entered by the user, and the name of the replacement inal filename as entered by the user, and the name of the replacement
file. To set up an input postprocessor, set the LESSCLOSE environment file. To set up an input postprocessor, set the LESSCLOSE environment
variable to a command line which will invoke your input postprocessor. variable to a command line which will invoke your input postprocessor.
It may include two occurrences of the string "%s"; the first is It may include two occurrences of the string "%s"; the first is
replaced with the original name of the file and the second with the replaced with the original name of the file and the second with the
name of the replacement file, which was output by LESSOPEN. 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: keep files in compressed format, but still let less view them directly:
lessopen.sh: lessopen.sh:
@ -1005,25 +1012,25 @@ LESS(1) LESS(1)
#! /bin/sh #! /bin/sh
rm $2 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 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. types of compressed files, and so on.
It is also possible to set up an input preprocessor to pipe the file 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 data directly to less, rather than putting the data into a replacement
file. This avoids the need to decompress the entire file before start- 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 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 ment file on its standard output, writes the entire contents of the
replacement file on its standard output. If the input pipe does not replacement file on its standard output. If the input pipe does not
write any characters on its standard output, then there is no replace- 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 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 pipe, make the first character in the LESSOPEN environment variable a
vertical bar (|) to signify that the input preprocessor is an input vertical bar (|) to signify that the input preprocessor is an input
pipe. pipe.
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: vious example scripts:
lesspipe.sh: lesspipe.sh:
@ -1034,15 +1041,21 @@ LESS(1) LESS(1)
esac esac
To use this script, put it where it can be executed and set To use this script, put it where it can be executed and set
LESSOPEN="|lesspipe.sh %s". When an input pipe is used, a LESSCLOSE LESSOPEN="|lesspipe.sh %s". When an input pipe is used, a LESSCLOSE
postprocessor can be used, but it is usually not necessary since there 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 is no replacement file to clean up. In this case, the replacement file
name passed to the LESSCLOSE postprocessor is "-". name passed to the LESSCLOSE postprocessor is "-".
For compatibility with previous versions of less, the input pipe is not For compatibility with previous versions of less, the input preproces-
used if less is viewing standard input. However, if the character sor or pipe is not used if less is viewing standard input. However, if
after the vertical bar is a dash (-), the input pipe is used on stan- the first character of LESSOPEN is a dash (-), the input preprocessor
dard input as well as other files. 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 (|-), 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.
NATIONAL CHARACTER SETS NATIONAL CHARACTER SETS
@ -1052,25 +1065,25 @@ LESS(1) LESS(1)
can be displayed directly to the screen. can be displayed directly to the screen.
control characters 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). in ordinary text files (such as backspace and tab).
binary characters 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. found in text files.
A "character set" is simply a description of which characters are to be A "character set" is simply a description of which characters are to be
considered normal, control, and binary. The LESSCHARSET environment considered normal, control, and binary. The LESSCHARSET environment
variable may be used to select a character set. Possible values for variable may be used to select a character set. Possible values for
LESSCHARSET are: LESSCHARSET are:
ascii BS, TAB, NL, CR, and formfeed are control characters, all chars ascii BS, TAB, NL, CR, and formfeed are control characters, all chars
with values between 32 and 126 are normal, and all others are with values between 32 and 126 are normal, and all others are
binary. binary.
iso8859 iso8859
Selects an ISO 8859 character set. This is the same as ASCII, Selects an ISO 8859 character set. This is the same as ASCII,
except characters between 160 and 255 are treated as normal except characters between 160 and 255 are treated as normal
characters. characters.
latin1 Same as iso8859. latin1 Same as iso8859.
@ -1082,8 +1095,8 @@ LESS(1) LESS(1)
ebcdic Selects an EBCDIC character set. ebcdic Selects an EBCDIC character set.
IBM-1047 IBM-1047
Selects an EBCDIC character set used by OS/390 Unix Services. Selects an EBCDIC character set used by OS/390 Unix Services.
This is the EBCDIC analogue of latin1. You get similar results This is the EBCDIC analogue of latin1. You get similar results
by setting either LESSCHARSET=IBM-1047 or LC_CTYPE=en_US in your by setting either LESSCHARSET=IBM-1047 or LC_CTYPE=en_US in your
environment. environment.
@ -1091,29 +1104,29 @@ LESS(1) LESS(1)
next Selects a character set appropriate for NeXT computers. next Selects a character set appropriate for NeXT computers.
utf-8 Selects the UTF-8 encoding of the ISO 10646 character set. 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 is special in that it supports multi-byte characters in
the input file. It is the only character set that supports the input file. It is the only character set that supports
multi-byte characters. multi-byte characters.
windows windows
Selects a character set appropriate for Microsoft Windows (cp Selects a character set appropriate for Microsoft Windows (cp
1251). 1251).
In rare cases, it may be desired to tailor less to use a character set 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- other than the ones definable by LESSCHARSET. In this case, the envi-
ronment variable LESSCHARDEF can be used to define a character set. It 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 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 one character in the character set. The character "." is used for a
normal character, "c" for control, and "b" for binary. A decimal num- normal character, "c" for control, and "b" for binary. A decimal num-
ber may be used for repetition. For example, "bccc4b." would mean 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 character 0 is binary, 1, 2 and 3 are control, 4, 5, 6 and 7 are
binary, and 8 is normal. All characters after the last are taken to be binary, 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. the same as the last, so characters 9 through 255 would be normal.
(This is an example, and does not necessarily represent any real char- (This is an example, and does not necessarily represent any real char-
acter set.) acter 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: of the possible values for LESSCHARSET:
ascii 8bcccbcc18b95.b ascii 8bcccbcc18b95.b
@ -1127,66 +1140,66 @@ LESS(1) LESS(1)
latin1 8bcccbcc18b95.33b. latin1 8bcccbcc18b95.33b.
next 8bcccbcc18b95.bb125.bb next 8bcccbcc18b95.bb125.bb
If neither LESSCHARSET nor LESSCHARDEF is set, but any of the strings 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_TYPE or "UTF-8", "UTF8", "utf-8" or "utf8" is found in the LC_ALL, LC_TYPE or
LANG environment variables, then the default character set is utf-8. LANG environment variables, then the default character set is utf-8.
If that string is not found, but your system supports the setlocale If that string is not found, but your system supports the setlocale
interface, less will use setlocale to determine the character set. interface, less will use setlocale to determine the character set.
setlocale is controlled by setting the LANG or LC_CTYPE environment setlocale is controlled by setting the LANG or LC_CTYPE environment
variables. variables.
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. 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 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- 0100 bit results in a normal printable character. Otherwise, the char-
acter is displayed as a hex number in angle brackets. This format can acter is displayed as a hex number in angle brackets. This format can
be changed by setting the LESSBINFMT environment variable. LESSBINFMT be changed by setting the LESSBINFMT environment variable. LESSBINFMT
may begin with a "*" and one character to select the display attribute: may begin with a "*" and one character to select the display attribute:
"*k" is blinking, "*d" is bold, "*u" is underlined, "*s" is standout, "*k" is blinking, "*d" is bold, "*u" is underlined, "*s" is standout,
and "*n" is normal. If LESSBINFMT does not begin with a "*", normal and "*n" is normal. If LESSBINFMT does not begin with a "*", normal
attribute is assumed. The remainder of LESSBINFMT is a string which attribute is assumed. The remainder of LESSBINFMT is a string which
may include one printf-style escape sequence (a % followed by x, X, o, may include one printf-style escape sequence (a % followed by x, X, o,
d, etc.). For example, if LESSBINFMT is "*u[%x]", binary characters d, etc.). For example, if LESSBINFMT is "*u[%x]", binary characters
are displayed in underlined hexadecimal surrounded by brackets. The are displayed in underlined hexadecimal surrounded by brackets. The
default if no LESSBINFMT is specified is "*s<%X>". The default if no default if no LESSBINFMT is specified is "*s<%X>". The default if no
LESSBINFMT is specified is "*s<%02X>". Warning: the result of expand- LESSBINFMT is specified is "*s<%02X>". Warning: the result of expand-
ing the character via LESSBINFMT must be less than 31 characters. ing the character via LESSBINFMT must be less than 31 characters.
When the character set is utf-8, the LESSUTFBINFMT environment variable When the character set is utf-8, the LESSUTFBINFMT environment variable
acts similarly to LESSBINFMT but it applies to Unicode code points that acts similarly to LESSBINFMT but it applies to Unicode code points that
were successfully decoded but are unsuitable for display (e.g., unas- were successfully decoded but are unsuitable for display (e.g., unas-
signed code points). Its default value is "<U+%04lX>". Note that signed code points). Its default value is "<U+%04lX>". Note that
LESSUTFBINFMT and LESSBINFMT share their display attribute setting LESSUTFBINFMT and LESSBINFMT share their display attribute setting
("*x") so specifying one will affect both; LESSUTFBINFMT is read after ("*x") so specifying one will affect both; LESSUTFBINFMT is read after
LESSBINFMT so its setting, if any, will have priority. Problematic LESSBINFMT so its setting, if any, will have priority. Problematic
octets in a UTF-8 file (octets of a truncated sequence, octets of a octets in a UTF-8 file (octets of a truncated sequence, octets of a
complete but non-shortest form sequence, illegal octets, and stray complete but non-shortest form sequence, illegal octets, and stray
trailing octets) are displayed individually using LESSBINFMT so as to trailing octets) are displayed individually using LESSBINFMT so as to
facilitate diagnostic of how the UTF-8 file is ill-formed. facilitate diagnostic of how the UTF-8 file is ill-formed.
PROMPTS PROMPTS
The -P option allows you to tailor the prompt to your preference. The The -P option allows you to tailor the prompt to your preference. The
string given to the -P option replaces the specified prompt string. string given to the -P option replaces the specified prompt string.
Certain characters in the string are interpreted specially. The prompt Certain characters in the string are interpreted specially. The prompt
mechanism is rather complicated to provide flexibility, but the ordi- mechanism is rather complicated to provide flexibility, but the ordi-
nary user need not understand the details of constructing personalized nary user need not understand the details of constructing personalized
prompt strings. 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: 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- 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- 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 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- 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, 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 and a "j" means use the "target" line, as specified by the -j
option. option.
%B Replaced by the size of the current input file. %B Replaced by the size of the current input file.
@ -1194,39 +1207,39 @@ LESS(1) LESS(1)
%c Replaced by the column number of the text appearing in the first %c Replaced by the column number of the text appearing in the first
column of the screen. 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. 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. lently, the page number of the last line in the input file.
%E Replaced by the name of the editor (from the VISUAL environment %E Replaced by the name of the editor (from the VISUAL environment
variable, or the EDITOR environment variable if VISUAL is not variable, or the EDITOR environment variable if VISUAL is not
defined). See the discussion of the LESSEDIT feature below. defined). See the discussion of the LESSEDIT feature below.
%f Replaced by the name of the current input file. %f Replaced by the name of the current input file.
%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. 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. 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. %L Replaced by the line number of the last line in the input file.
%m Replaced by the total number of input files. %m Replaced by the total number of input files.
%pX Replaced by the percent into the current input file, based on %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 byte offsets. The line used is determined by the X as with the
%b option. %b option.
%PX Replaced by the percent into the current input file, based on %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 line numbers. The line used is determined by the X as with the
%b option. %b option.
%s Same as %B. %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. end of the string, but may appear anywhere.
%x Replaced by the name of the next input file in the list. %x Replaced by the name of the next input file in the list.
@ -1234,18 +1247,18 @@ LESS(1) LESS(1)
If any item is unknown (for example, the file size if input is a pipe), If any item is unknown (for example, the file size if input is a pipe),
a question mark is printed instead. a question mark is printed instead.
The format of the prompt string can be changed depending on certain The format of the prompt string can be changed depending on certain
conditions. A question mark followed by a single character acts like conditions. A question mark followed by a single character acts like
an "IF": depending on the following character, a condition is evalu- an "IF": depending on the following character, a condition is evalu-
ated. If the condition is true, any characters following the question ated. If the condition is true, any characters following the question
mark and condition character, up to a period, are included in the mark and condition character, up to a period, are included in the
prompt. If the condition is false, such characters are not included. prompt. If the condition is false, such characters are not included.
A colon appearing between the question mark and the period can be used 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 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: Condition characters (which follow a question mark) may be:
?a True if any characters have been included in the prompt so far. ?a True if any characters have been included in the prompt so far.
?bX True if the byte offset of the specified line is known. ?bX True if the byte offset of the specified line is known.
@ -1257,7 +1270,7 @@ LESS(1) LESS(1)
?e True if at end-of-file. ?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). pipe).
?lX True if the line number of the specified line is known. ?lX True if the line number of the specified line is known.
@ -1268,46 +1281,46 @@ LESS(1) LESS(1)
?n True if this is the first prompt in a new input file. ?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. 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. numbers, of the specified line is known.
?s Same as "?B". ?s Same as "?B".
?x True if there is a next input file (that is, if the current ?x True if there is a next input file (that is, if the current
input file is not the last one). input file is not the last one).
Any characters other than the special ones (question mark, colon, Any characters other than the special ones (question mark, colon,
period, percent, and backslash) become literally part of the prompt. period, percent, and backslash) become literally part of the prompt.
Any of the special characters may be included in the prompt literally Any of the special characters may be included in the prompt literally
by preceding it with a backslash. by preceding it with a backslash.
Some examples: Some examples:
?f%f:Standard input. ?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". dard input".
?f%f .?ltLine %lt:?pt%pt\%:?btByte %bt:-... ?f%f .?ltLine %lt:?pt%pt\%:?btByte %bt:-...
This prompt would print the filename, if known. The filename is fol- This prompt would print the filename, if known. The filename is fol-
lowed by the line number, if known, otherwise the percent if known, lowed by the line number, if known, otherwise the percent if known,
otherwise the byte offset if known. Otherwise, a dash is printed. otherwise the byte offset if known. Otherwise, a dash is printed.
Notice how each question mark has a matching period, and how the % Notice how each question mark has a matching period, and how the %
after the %pt is included literally by escaping it with a backslash. after the %pt is included literally by escaping it with a backslash.
?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\: %x..%t ?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\: %x..%t
This prints the filename if this is the first prompt in a file, fol- 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 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 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 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- trailing spaces are truncated. This is the default prompt. For refer-
ence, here are the defaults for the other two prompts (-m and -M ence, here are the defaults for the other two prompts (-m and -M
respectively). Each is broken into two lines here for readability respectively). Each is broken into two lines here for readability
only. only.
?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\: %x.: ?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\: %x.:
@ -1321,22 +1334,22 @@ LESS(1) LESS(1)
?f%f .?m(file %i of %m) .?ltlines %lt-%lb?L/%L. . ?f%f .?m(file %i of %m) .?ltlines %lt-%lb?L/%L. .
byte %bB?s/%s. ?e(END) :?pB%pB\%..%t byte %bB?s/%s. ?e(END) :?pB%pB\%..%t
The prompt expansion features are also used for another purpose: if an The prompt expansion features are also used for another purpose: if an
environment variable LESSEDIT is defined, it is used as the command to environment variable LESSEDIT is defined, it is used as the command to
be executed when the v command is invoked. The LESSEDIT string is be executed when the v command is invoked. The LESSEDIT string is
expanded in the same way as the prompt strings. The default value for expanded in the same way as the prompt strings. The default value for
LESSEDIT is: LESSEDIT is:
%E ?lm+%lm. %f %E ?lm+%lm. %f
Note that this expands to the editor name, followed by a + and the line Note that this expands to the editor name, followed by a + and the line
number, followed by the file name. If your editor does not accept the number, followed by the file name. If your editor does not accept the
"+linenumber" syntax, or has other differences in invocation syntax, "+linenumber" syntax, or has other differences in invocation syntax,
the LESSEDIT variable can be changed to modify this default. the LESSEDIT variable can be changed to modify this default.
SECURITY 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: "secure" mode. This means these features are disabled:
! the shell command ! the shell command
@ -1362,54 +1375,54 @@ LESS(1) LESS(1)
COMPATIBILITY WITH MORE COMPATIBILITY WITH MORE
If the environment variable LESS_IS_MORE is set to 1, or if the program 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- is invoked via a file link named "more", less behaves (mostly) in con-
formance with the POSIX "more" command specification. In this mode, formance with the POSIX "more" command specification. In this mode,
less behaves differently in these ways: less behaves differently in these ways:
The -e option works differently. If the -e option is not set, less The -e option works differently. If the -e option is not set, less
behaves as if the -E option were set. If the -e option is set, less behaves as if the -E option were set. If the -e option is set, less
behaves as if the -e and -F options were set. behaves as if the -e and -F options were set.
The -m option works differently. If the -m option is not set, the 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--". medium prompt is used, and it is prefixed with the string "--More--".
If the -m option is set, the short prompt is used. 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. 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. 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. variable is used in its place.
ENVIRONMENT VARIABLES ENVIRONMENT VARIABLES
Environment variables may be specified either in the system environment Environment variables may be specified either in the system environment
as usual, or in a lesskey (1) file. If environment variables are as usual, or in a lesskey (1) file. If environment variables are
defined in more than one place, variables defined in a local lesskey defined in more than one place, variables defined in a local lesskey
file take precedence over variables defined in the system environment, file take precedence over variables defined in the system environment,
which take precedence over variables defined in the system-wide lesskey which take precedence over variables defined in the system-wide lesskey
file. file.
COLUMNS COLUMNS
Sets the number of columns on the screen. Takes precedence over 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 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.) precedence over the LINES and COLUMNS environment variables.)
EDITOR The name of the editor (used for the v command). 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). on Unix and OS/2 systems).
HOMEDRIVE, HOMEPATH 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- ables is the name of the user's home directory if the HOME vari-
able is not set (only in the Windows version). 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). on OS/2 systems).
LANG Language for determining the character set. LANG Language for determining the character set.
@ -1420,12 +1433,12 @@ LESS(1) LESS(1)
LESS Options which are passed to less automatically. LESS Options which are passed to less automatically.
LESSANSIENDCHARS LESSANSIENDCHARS
Characters which may end an ANSI color escape sequence (default Characters which may end an ANSI color escape sequence (default
"m"). "m").
LESSANSIMIDCHARS LESSANSIMIDCHARS
Characters which may appear between the ESC character and the Characters which may appear between the ESC character and the
end character in an ANSI color escape sequence (default end character in an ANSI color escape sequence (default
"0123456789;[?!"'#%()*+ ". "0123456789;[?!"'#%()*+ ".
LESSBINFMT LESSBINFMT
@ -1442,24 +1455,24 @@ LESS(1) LESS(1)
LESSECHO LESSECHO
Name of the lessecho program (default "lessecho"). The 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. filenames on Unix systems.
LESSEDIT LESSEDIT
Editor prototype string (used for the v command). See discus- Editor prototype string (used for the v command). See discus-
sion under PROMPTS. sion under PROMPTS.
LESSGLOBALTAGS LESSGLOBALTAGS
Name of the command used by the -t option to find global tags. Name of the command used by the -t option to find global tags.
Normally should be set to "global" if your system has the global Normally should be set to "global" if your system has the global
(1) command. If not set, global tags are not used. (1) command. If not set, global tags are not used.
LESSHISTFILE LESSHISTFILE
Name of the history file used to remember search commands and Name of the history file used to remember search commands and
shell commands between invocations of less. If set to "-" or shell commands between invocations of less. If set to "-" or
"/dev/null", a history file is not used. The default is "/dev/null", a history file is not used. The default is
"$HOME/.lesshst" on Unix systems, "$HOME/_lesshst" on DOS and "$HOME/.lesshst" on Unix systems, "$HOME/_lesshst" on DOS and
Windows systems, or "$HOME/lesshst.ini" or "$INIT/lesshst.ini" Windows systems, or "$HOME/lesshst.ini" or "$INIT/lesshst.ini"
on OS/2 systems. on OS/2 systems.
LESSHISTSIZE LESSHISTSIZE
@ -1473,13 +1486,13 @@ LESS(1) LESS(1)
Name of the default system-wide lesskey(1) file. Name of the default system-wide lesskey(1) file.
LESSMETACHARS LESSMETACHARS
List of characters which are considered "metacharacters" by the List of characters which are considered "metacharacters" by the
shell. shell.
LESSMETAESCAPE LESSMETAESCAPE
Prefix which less will add before each metacharacter in a com- Prefix which less will add before each metacharacter in a com-
mand sent to the shell. If LESSMETAESCAPE is an empty string, mand sent to the shell. If LESSMETAESCAPE is an empty string,
commands containing metacharacters will not be passed to the commands containing metacharacters will not be passed to the
shell. shell.
LESSOPEN LESSOPEN
@ -1489,7 +1502,7 @@ LESS(1) LESS(1)
Runs less in "secure" mode. See discussion under SECURITY. Runs less in "secure" mode. See discussion under SECURITY.
LESSSEPARATOR LESSSEPARATOR
String to be appended to a directory name in filename comple- String to be appended to a directory name in filename comple-
tion. tion.
LESSUTFBINFMT LESSUTFBINFMT
@ -1498,16 +1511,16 @@ LESS(1) LESS(1)
LESS_IS_MORE LESS_IS_MORE
Emulate the more (1) command. 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 the number of lines specified by the TERM variable. (But if you
have a windowing system which supports TIOCGWINSZ or WIOCGETD, have a windowing system which supports TIOCGWINSZ or WIOCGETD,
the window system's idea of the screen size takes precedence the window system's idea of the screen size takes precedence
over the LINES and COLUMNS environment variables.) over the LINES and COLUMNS environment variables.)
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). 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. filenames.
TERM The type of terminal on which less is being run. TERM The type of terminal on which less is being run.
@ -1520,21 +1533,21 @@ LESS(1) LESS(1)
COPYRIGHT COPYRIGHT
Copyright (C) 1984-2008 Mark Nudelman Copyright (C) 1984-2009 Mark Nudelman
less is part of the GNU project and is free software. You can redis- 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- 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 eral Public License as published by the Free Software Foundation; or
(2) the Less License. See the file README in the less distribution for (2) the Less License. See the file README in the less distribution for
more details regarding redistribution. You should have received a copy more details regarding redistribution. You should have received a copy
of the GNU General Public License along with the source for less; see 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 the file COPYING. If not, write to the Free Software Foundation, 59
Temple Place, Suite 330, Boston, MA 02111-1307, USA. You should also Temple Place, Suite 330, Boston, MA 02111-1307, USA. You should also
have received a copy of the Less License; see the file LICENSE. 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 less is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FIT- WARRANTY; without even the implied warranty of MERCHANTABILITY or FIT-
NESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for NESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. more details.
@ -1549,4 +1562,4 @@ LESS(1) LESS(1)
Version 429: 11 Apr 2009 LESS(1) Version 436: 07 Jul 2009 LESS(1)

View File

@ -1,4 +1,4 @@
.TH LESS 1 "Version 429: 11 Apr 2009" .TH LESS 1 "Version 436: 07 Jul 2009"
.SH NAME .SH NAME
less \- opposite of more less \- opposite of more
.SH SYNOPSIS .SH SYNOPSIS
@ -864,6 +864,13 @@ Specifies the default number of positions to scroll horizontally
in the RIGHTARROW and LEFTARROW commands. in the RIGHTARROW and LEFTARROW commands.
If the number specified is zero, it sets the default number of If the number specified is zero, it sets the default number of
positions to one half of the screen width. positions to one half of the screen width.
Alternately, the number may be specified as a fraction of the width
of the screen, starting with a decimal point: .5 is half of the
screen width, .3 is three tenths of the screen width, and so on.
If the number is specified as a fraction, the actual number of
scroll positions is recalculated if the terminal window is resized,
so that the actual scroll remains at the specified fraction
of the screen width.
.IP "\-\-no-keypad" .IP "\-\-no-keypad"
Disables sending the keypad initialization and deinitialization strings Disables sending the keypad initialization and deinitialization strings
to the terminal. to the terminal.
@ -1149,11 +1156,19 @@ postprocessor is "\-".
.PP .PP
For compatibility with previous versions of For compatibility with previous versions of
.I less, .I less,
the input pipe is not used if the input preprocessor or pipe is not used if
.I less .I less
is viewing standard input. is viewing standard input.
However, if the character after the vertical bar is a dash (\-), However, if the first character of LESSOPEN is a dash (\-),
the input pipe is used on standard input as well as other files. 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 characters of LESSOPEN are vertical bar and 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.
.SH "NATIONAL CHARACTER SETS" .SH "NATIONAL CHARACTER SETS"
There are three types of characters in the input file: There are three types of characters in the input file:
@ -1649,7 +1664,7 @@ The name of the editor (used for the v command).
lesskey(1) lesskey(1)
.SH COPYRIGHT .SH COPYRIGHT
Copyright (C) 1984-2008 Mark Nudelman Copyright (C) 1984-2009 Mark Nudelman
.PP .PP
less is part of the GNU project and is free software. less is part of the GNU project and is free software.
You can redistribute it and/or modify it You can redistribute it and/or modify it

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2008 Mark Nudelman * Copyright (C) 1984-2009 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -28,7 +28,7 @@
#include "less.h" #include "less.h"
static char *version = "$Revision: 1.12 $"; static char *version = "$Revision: 1.13 $";
static int quote_all = 0; static int quote_all = 0;
static char openquote = '"'; static char openquote = '"';

View File

@ -46,4 +46,4 @@ LESSECHO(1) LESSECHO(1)
Version 429: 11 Apr 2009 LESSECHO(1) Version 436: 07 Jul 2009 LESSECHO(1)

View File

@ -1,4 +1,4 @@
.TH LESSECHO 1 "Version 429: 11 Apr 2009" .TH LESSECHO 1 "Version 436: 07 Jul 2009"
.SH NAME .SH NAME
lessecho \- expand metacharacters lessecho \- expand metacharacters
.SH SYNOPSIS .SH SYNOPSIS

View File

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

View File

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

View File

@ -333,7 +333,7 @@ LESSKEY(1) LESSKEY(1)
COPYRIGHT COPYRIGHT
Copyright (C) 2000-2008 Mark Nudelman Copyright (C) 2000-2009 Mark Nudelman
lesskey is part of the GNU project and is free software; you can redis- lesskey is part of the GNU project and is free software; you can redis-
tribute it and/or modify it under the terms of the GNU General Public tribute it and/or modify it under the terms of the GNU General Public
@ -358,4 +358,4 @@ LESSKEY(1) LESSKEY(1)
Version 429: 11 Apr 2009 LESSKEY(1) Version 436: 07 Jul 2009 LESSKEY(1)

View File

@ -1,4 +1,4 @@
.TH LESSKEY 1 "Version 429: 11 Apr 2009" .TH LESSKEY 1 "Version 436: 07 Jul 2009"
.SH NAME .SH NAME
lesskey \- specify key bindings for less lesskey \- specify key bindings for less
.SH SYNOPSIS .SH SYNOPSIS
@ -359,7 +359,7 @@ which start with a NUL character (0).
This NUL character should be represented as \e340 in a lesskey file. This NUL character should be represented as \e340 in a lesskey file.
.SH COPYRIGHT .SH COPYRIGHT
Copyright (C) 2000-2008 Mark Nudelman Copyright (C) 2000-2009 Mark Nudelman
.PP .PP
lesskey is part of the GNU project and is free software; lesskey is part of the GNU project and is free software;
you can redistribute it and/or modify it you can redistribute it and/or modify it

View File

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

View File

@ -1,6 +1,6 @@
/* $FreeBSD$ */ /* $FreeBSD$ */
/* /*
* Copyright (C) 1984-2008 Mark Nudelman * Copyright (C) 1984-2009 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -990,12 +990,10 @@ pflushmbc()
* Terminate the line in the line buffer. * Terminate the line in the line buffer.
*/ */
public void public void
pdone(endline, nextc) pdone(endline, forw)
int endline; int endline;
int nextc; int forw;
{ {
int nl;
(void) pflushmbc(); (void) pflushmbc();
if (pendc && (pendc != '\r' || !endline)) if (pendc && (pendc != '\r' || !endline))
@ -1042,7 +1040,7 @@ pdone(endline, nextc)
attr[curr] = AT_NORMAL; attr[curr] = AT_NORMAL;
curr++; curr++;
} }
else if (ignaw && column >= sc_width) else if (ignaw && column >= sc_width && forw)
{ {
/* /*
* Terminals with "ignaw" don't wrap until they *really* need * Terminals with "ignaw" don't wrap until they *really* need
@ -1051,12 +1049,14 @@ pdone(endline, nextc)
* get in the state where a full screen width of characters * get in the state where a full screen width of characters
* have been output but the cursor is sitting on the right edge * have been output but the cursor is sitting on the right edge
* instead of at the start of the next line. * instead of at the start of the next line.
* So we nudge them into wrapping by outputting the next * So we nudge them into wrapping by outputting a space
* character plus a backspace. (This wouldn't be right for * character plus a backspace. But do this only if moving
* "!auto_wrap" terminals, but they always end up in the * forward; if we're moving backward and drawing this line at
* branch above.) * the top of the screen, the space would overwrite the first
* char on the next line. We don't need to do this "nudge"
* at the top of the screen anyway.
*/ */
linebuf[curr] = nextc; linebuf[curr] = ' ';
attr[curr++] = AT_NORMAL; attr[curr++] = AT_NORMAL;
linebuf[curr] = '\b'; linebuf[curr] = '\b';
attr[curr++] = AT_NORMAL; attr[curr++] = AT_NORMAL;

View File

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

View File

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

View File

@ -1,6 +1,6 @@
/* $FreeBSD$ */ /* $FreeBSD$ */
/* /*
* Copyright (C) 1984-2008 Mark Nudelman * Copyright (C) 1984-2009 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -121,6 +121,7 @@ main(argc, argv)
init_line(); init_line();
init_cmdhist(); init_cmdhist();
init_option(); init_option();
init_search();
/* /*
* If the name of the executable program is "more", * If the name of the executable program is "more",

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2008 Mark Nudelman * Copyright (C) 1984-2009 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -33,6 +33,7 @@ extern int bufspace;
extern int pr_type; extern int pr_type;
extern int plusoption; extern int plusoption;
extern int swindow; extern int swindow;
extern int sc_width;
extern int sc_height; extern int sc_height;
extern int secure; extern int secure;
extern int dohelp; extern int dohelp;
@ -47,6 +48,8 @@ extern IFILE curr_ifile;
extern char version[]; extern char version[];
extern int jump_sline; extern int jump_sline;
extern int jump_sline_fraction; extern int jump_sline_fraction;
extern int shift_count;
extern int shift_count_fraction;
extern int less_is_more; extern int less_is_more;
#if LOGFILE #if LOGFILE
extern char *namelogfile; extern char *namelogfile;
@ -221,6 +224,70 @@ calc_jump_sline()
jump_sline = sc_height * jump_sline_fraction / NUM_FRAC_DENOM; jump_sline = sc_height * jump_sline_fraction / NUM_FRAC_DENOM;
} }
/*
* Handlers for -# option.
*/
public void
opt_shift(type, s)
int type;
char *s;
{
PARG parg;
char buf[16];
int len;
int err;
switch (type)
{
case INIT:
case TOGGLE:
if (*s == '.')
{
s++;
shift_count_fraction = getfraction(&s, "#", &err);
if (err)
error("Invalid column fraction", NULL_PARG);
else
calc_shift_count();
} else
{
int hs = getnum(&s, "#", &err);
if (err)
error("Invalid column number", NULL_PARG);
else
{
shift_count = hs;
shift_count_fraction = -1;
}
}
break;
case QUERY:
if (shift_count_fraction < 0)
{
parg.p_int = shift_count;
error("Horizontal shift %d columns", &parg);
} else
{
sprintf(buf, ".%06d", shift_count_fraction);
len = strlen(buf);
while (len > 2 && buf[len-1] == '0')
len--;
buf[len] = '\0';
parg.p_string = buf;
error("Horizontal shift %s of screen width", &parg);
}
break;
}
}
public void
calc_shift_count()
{
if (shift_count_fraction < 0)
return;
shift_count = sc_width * shift_count_fraction / NUM_FRAC_DENOM;
}
#if USERFILE #if USERFILE
public void public void
opt_k(type, s) opt_k(type, s)
@ -442,7 +509,7 @@ opt__V(type, s)
any_display = 1; any_display = 1;
putstr("less "); putstr("less ");
putstr(version); putstr(version);
putstr("\nCopyright (C) 1984-2008 Mark Nudelman\n\n"); putstr("\nCopyright (C) 1984-2009 Mark Nudelman\n\n");
putstr("less comes with NO WARRANTY, to the extent permitted by law.\n"); putstr("less comes with NO WARRANTY, to the extent permitted by law.\n");
putstr("For information about the terms of redistribution,\n"); putstr("For information about the terms of redistribution,\n");
putstr("see the file named README in the less distribution.\n"); putstr("see the file named README in the less distribution.\n");

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2008 Mark Nudelman * Copyright (C) 1984-2009 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -41,6 +41,7 @@ public int force_open; /* Open the file even if not regular file */
public int swindow; /* Size of scrolling window */ public int swindow; /* Size of scrolling window */
public int jump_sline; /* Screen line of "jump target" */ public int jump_sline; /* Screen line of "jump target" */
public long jump_sline_fraction = -1; public long jump_sline_fraction = -1;
public long shift_count_fraction = -1;
public int chopline; /* Truncate displayed lines at screen width */ public int chopline; /* Truncate displayed lines at screen width */
public int no_init; /* Disable sending ti/te termcap strings */ public int no_init; /* Disable sending ti/te termcap strings */
public int no_keypad; /* Disable sending ks/ke termcap strings */ public int no_keypad; /* Disable sending ks/ke termcap strings */
@ -419,10 +420,10 @@ static struct loption option[] =
{ NULL, NULL, NULL } { NULL, NULL, NULL }
}, },
{ '#', &pound_optname, { '#', &pound_optname,
NUMBER, 0, &shift_count, NULL, STRING, 0, NULL, opt_shift,
{ {
"Horizontal shift: ", "Horizontal shift: ",
"Horizontal shift %d positions", "0123456789.",
NULL NULL
} }
}, },

View File

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

View File

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

322
contrib/less/pattern.c Normal file
View File

@ -0,0 +1,322 @@
/*
* Copyright (C) 1984-2009 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 about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines to do pattern matching.
*/
#include "less.h"
#include "pattern.h"
extern int caseless;
/*
* Compile a search pattern, for future use by match_pattern.
*/
static int
compile_pattern2(pattern, search_type, comp_pattern)
char *pattern;
int search_type;
void **comp_pattern;
{
if ((search_type & SRCH_NO_REGEX) == 0)
{
#if HAVE_POSIX_REGCOMP
regex_t *comp = (regex_t *) ecalloc(1, sizeof(regex_t));
regex_t **pcomp = (regex_t **) comp_pattern;
if (regcomp(comp, pattern, REGCOMP_FLAG))
{
free(comp);
error("Invalid pattern", NULL_PARG);
return (-1);
}
if (*pcomp != NULL)
regfree(*pcomp);
*pcomp = comp;
#endif
#if HAVE_PCRE
pcre *comp;
pcre **pcomp = (pcre **) comp_pattern;
const char *errstring;
int erroffset;
PARG parg;
comp = pcre_compile(pattern, 0,
&errstring, &erroffset, NULL);
if (comp == NULL)
{
parg.p_string = (char *) errstring;
error("%s", &parg);
return (-1);
}
*pcomp = comp;
#endif
#if HAVE_RE_COMP
PARG parg;
int *pcomp = (int *) comp_pattern;
if ((parg.p_string = re_comp(pattern)) != NULL)
{
error("%s", &parg);
return (-1);
}
*pcomp = 1;
#endif
#if HAVE_REGCMP
char *comp;
char **pcomp = (char **) comp_pattern;
if ((comp = regcmp(pattern, 0)) == NULL)
{
error("Invalid pattern", NULL_PARG);
return (-1);
}
if (pcomp != NULL)
free(*pcomp);
*pcomp = comp;
#endif
#if HAVE_V8_REGCOMP
struct regexp *comp;
struct regexp **pcomp = (struct regexp **) comp_pattern;
if ((comp = regcomp(pattern)) == NULL)
{
/*
* regcomp has already printed an error message
* via regerror().
*/
return (-1);
}
if (*pcomp != NULL)
free(*pcomp);
*pcomp = comp;
#endif
}
return (0);
}
/*
* Like compile_pattern2, but convert the pattern to lowercase if necessary.
*/
public int
compile_pattern(pattern, search_type, comp_pattern)
char *pattern;
int search_type;
void **comp_pattern;
{
char *cvt_pattern;
int result;
if (caseless != OPT_ONPLUS)
cvt_pattern = pattern;
else
{
cvt_pattern = (char*) ecalloc(1, cvt_length(strlen(pattern), CVT_TO_LC));
cvt_text(cvt_pattern, pattern, (int *)NULL, (int *)NULL, CVT_TO_LC);
}
result = compile_pattern2(cvt_pattern, search_type, comp_pattern);
if (cvt_pattern != pattern)
free(cvt_pattern);
return (result);
}
/*
* Forget that we have a compiled pattern.
*/
public void
uncompile_pattern(pattern)
void **pattern;
{
#if HAVE_POSIX_REGCOMP
regex_t **pcomp = (regex_t **) pattern;
if (*pcomp != NULL)
regfree(*pcomp);
*pcomp = NULL;
#endif
#if HAVE_PCRE
pcre **pcomp = (pcre **) pattern;
if (*pcomp != NULL)
pcre_free(*pcomp);
*pcomp = NULL;
#endif
#if HAVE_RE_COMP
int *pcomp = (int *) pattern;
*pcomp = 0;
#endif
#if HAVE_REGCMP
char **pcomp = (char **) pattern;
if (*pcomp != NULL)
free(*pcomp);
*pcomp = NULL;
#endif
#if HAVE_V8_REGCOMP
struct regexp **pcomp = (struct regexp **) pattern;
if (*pcomp != NULL)
free(*pcomp);
*pcomp = NULL;
#endif
}
/*
* Is a compiled pattern null?
*/
public int
is_null_pattern(pattern)
void *pattern;
{
#if HAVE_POSIX_REGCOMP
return (pattern == NULL);
#endif
#if HAVE_PCRE
return (pattern == NULL);
#endif
#if HAVE_RE_COMP
return (pattern == 0);
#endif
#if HAVE_REGCMP
return (pattern == NULL);
#endif
#if HAVE_V8_REGCOMP
return (pattern == NULL);
#endif
#if NO_REGEX
return (search_pattern != NULL);
#endif
}
/*
* Simple pattern matching function.
* It supports no metacharacters like *, etc.
*/
static int
match(pattern, pattern_len, buf, buf_len, pfound, pend)
char *pattern;
int pattern_len;
char *buf;
int buf_len;
char **pfound, **pend;
{
register char *pp, *lp;
register char *pattern_end = pattern + pattern_len;
register char *buf_end = buf + buf_len;
for ( ; buf < buf_end; buf++)
{
for (pp = pattern, lp = buf; *pp == *lp; pp++, lp++)
if (pp == pattern_end || lp == buf_end)
break;
if (pp == pattern_end)
{
if (pfound != NULL)
*pfound = buf;
if (pend != NULL)
*pend = lp;
return (1);
}
}
return (0);
}
/*
* Perform a pattern match with the previously compiled pattern.
* Set sp and ep to the start and end of the matched string.
*/
public int
match_pattern(pattern, tpattern, line, line_len, sp, ep, notbol, search_type)
void *pattern;
char *tpattern;
char *line;
int line_len;
char **sp;
char **ep;
int notbol;
int search_type;
{
int matched;
#if HAVE_POSIX_REGCOMP
regex_t *spattern = (regex_t *) pattern;
#endif
#if HAVE_PCRE
pcre *spattern = (pcre *) pattern;
#endif
#if HAVE_RE_COMP
int spattern = (int) pattern;
#endif
#if HAVE_REGCMP
char *spattern = (char *) pattern;
#endif
#if HAVE_V8_REGCOMP
struct regexp *spattern = (struct regexp *) pattern;
#endif
if (search_type & SRCH_NO_REGEX)
matched = match(tpattern, strlen(tpattern), line, line_len, sp, ep);
else
{
#if HAVE_POSIX_REGCOMP
{
regmatch_t rm;
int flags = (notbol) ? REG_NOTBOL : 0;
matched = !regexec(spattern, line, 1, &rm, flags);
if (matched)
{
#ifndef __WATCOMC__
*sp = line + rm.rm_so;
*ep = line + rm.rm_eo;
#else
*sp = rm.rm_sp;
*ep = rm.rm_ep;
#endif
}
}
#endif
#if HAVE_PCRE
{
int flags = (notbol) ? PCRE_NOTBOL : 0;
int ovector[3];
matched = pcre_exec(spattern, NULL, line, line_len,
0, flags, ovector, 3) >= 0;
if (matched)
{
*sp = line + ovector[0];
*ep = line + ovector[1];
}
}
#endif
#if HAVE_RE_COMP
matched = (re_exec(line) == 1);
/*
* re_exec doesn't seem to provide a way to get the matched string.
*/
*sp = *ep = NULL;
#endif
#if HAVE_REGCMP
*ep = regex(spattern, line);
matched = (*ep != NULL);
if (matched)
*sp = __loc1;
#endif
#if HAVE_V8_REGCOMP
#if HAVE_REGEXEC2
matched = regexec2(spattern, line, notbol);
#else
matched = regexec(spattern, line);
#endif
if (matched)
{
*sp = spattern->startp[0];
*ep = spattern->endp[0];
}
#endif
#if NO_REGEX
matched = match(tpattern, strlen(tpattern), line, line_len, sp, ep);
#endif
}
matched = (!(search_type & SRCH_NO_MATCH) && matched) ||
((search_type & SRCH_NO_MATCH) && !matched);
return (matched);
}

49
contrib/less/pattern.h Normal file
View File

@ -0,0 +1,49 @@
/*
* Copyright (C) 1984-2009 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 about less, or for information on how to
* contact the author, see the README file.
*/
#if HAVE_POSIX_REGCOMP
#include <regex.h>
#ifdef REG_EXTENDED
extern int less_is_more;
#define REGCOMP_FLAG (less_is_more ? 0 : REG_EXTENDED)
#else
#define REGCOMP_FLAG 0
#endif
#define DEFINE_PATTERN(name) regex_t *name
#define CLEAR_PATTERN(name) name = NULL
#endif
#if HAVE_PCRE
#include <pcre.h>
#define DEFINE_PATTERN(name) pcre *name
#define CLEAR_PATTERN(name) name = NULL
#endif
#if HAVE_RE_COMP
char *re_comp();
int re_exec();
#define DEFINE_PATTERN(name) int name
#define CLEAR_PATTERN(name) name = 0
#endif
#if HAVE_REGCMP
char *regcmp();
char *regex();
extern char *__loc1;
#define DEFINE_PATTERN(name) char *name
#define CLEAR_PATTERN(name) name = NULL
#endif
#if HAVE_V8_REGCOMP
#include "regexp.h"
#define DEFINE_PATTERN(name) struct regexp *name
#define CLEAR_PATTERN(name) name = NULL
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
/* $FreeBSD$ */ /* $FreeBSD$ */
/* /*
* Copyright (C) 1984-2008 Mark Nudelman * Copyright (C) 1984-2009 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -15,38 +15,13 @@
*/ */
#include "less.h" #include "less.h"
#include "pattern.h"
#include "position.h" #include "position.h"
#include "charset.h" #include "charset.h"
#define MINPOS(a,b) (((a) < (b)) ? (a) : (b)) #define MINPOS(a,b) (((a) < (b)) ? (a) : (b))
#define MAXPOS(a,b) (((a) > (b)) ? (a) : (b)) #define MAXPOS(a,b) (((a) > (b)) ? (a) : (b))
#if HAVE_POSIX_REGCOMP
#include <regex.h>
#ifdef REG_EXTENDED
#define REGCOMP_FLAG (less_is_more ? 0 : REG_EXTENDED)
#else
#define REGCOMP_FLAG 0
#endif
#endif
#if HAVE_PCRE
#include <pcre.h>
#endif
#if HAVE_RE_COMP
char *re_comp();
int re_exec();
#endif
#if HAVE_REGCMP
char *regcmp();
char *regex();
extern char *__loc1;
#endif
#if HAVE_V8_REGCOMP
#include "regexp.h"
#endif
static int match();
extern int sigs; extern int sigs;
extern int how_search; extern int how_search;
extern int caseless; extern int caseless;
@ -68,9 +43,10 @@ extern int size_linebuf;
extern int squished; extern int squished;
extern int can_goto_line; extern int can_goto_line;
static int hide_hilite; static int hide_hilite;
static int oldbot;
static POSITION prep_startpos; static POSITION prep_startpos;
static POSITION prep_endpos; static POSITION prep_endpos;
static int is_caseless;
static int is_ucase_pattern;
struct hilite struct hilite
{ {
@ -85,112 +61,80 @@ static struct hilite filter_anchor = { NULL, NULL_POSITION, NULL_POSITION };
/* /*
* These are the static variables that represent the "remembered" * These are the static variables that represent the "remembered"
* search pattern. * search pattern and filter pattern.
*/ */
#if HAVE_POSIX_REGCOMP struct pattern_info {
#define DEFINE_PATTERN(name) static regex_t *name = NULL DEFINE_PATTERN(compiled);
#endif char* text;
#if HAVE_PCRE int search_type;
#define DEFINE_PATTERN(name) pcre *name = NULL; };
#endif
#if HAVE_RE_COMP static struct pattern_info search_info;
#define DEFINE_PATTERN(name) int name = 0; static struct pattern_info filter_info;
#endif
#if HAVE_REGCMP
#define DEFINE_PATTERN(name) static char *name = NULL;
#endif
#if HAVE_V8_REGCOMP
#define DEFINE_PATTERN(name) static struct regexp *name = NULL;
#endif
DEFINE_PATTERN(search_pattern);
DEFINE_PATTERN(filter_pattern);
static int is_caseless;
static int is_ucase_pattern;
static int last_search_type;
static int last_filter_type;
static char *last_pattern = NULL;
#define CVT_TO_LC 01 /* Convert upper-case to lower-case */
#define CVT_BS 02 /* Do backspace processing */
#define CVT_CRLF 04 /* Remove CR after LF */
#define CVT_ANSI 010 /* Remove ANSI escape sequences */
/* /*
* Get the length of a buffer needed to convert a string. * Compile and save a search pattern.
*/ */
static int static int
cvt_length(len, ops) set_pattern(info, pattern, search_type)
int len; struct pattern_info *info;
int ops; char *pattern;
int search_type;
{ {
if (utf_mode) if (pattern == NULL)
/* CLEAR_PATTERN(search_info.compiled);
* Just copying a string in UTF-8 mode can cause it to grow else if (compile_pattern(pattern, search_type, &info->compiled) < 0)
* in length. return -1;
* Six output bytes for one input byte is the worst case /* Pattern compiled successfully; save the text too. */
* (and unfortunately is far more than is needed in any if (info->text != NULL)
* non-pathological situation, so this is very wasteful). free(info->text);
*/ info->text = NULL;
len *= 6; if (pattern != NULL)
return len + 1; {
info->text = (char *) ecalloc(1, strlen(pattern)+1);
strcpy(info->text, pattern);
}
info->search_type = search_type;
return 0;
} }
/* /*
* Convert text. Perform the transformations specified by ops. * Discard a saved pattern.
*/ */
static void static void
cvt_text(odst, osrc, lenp, ops) clear_pattern(info)
char *odst; struct pattern_info *info;
char *osrc;
int *lenp;
int ops;
{ {
char *dst; if (info->text != NULL)
char *src; free(info->text);
register char *src_end; info->text = NULL;
LWCHAR ch; uncompile_pattern(&info->compiled);
if (lenp != NULL)
src_end = osrc + *lenp;
else
src_end = osrc + strlen(osrc);
for (src = osrc, dst = odst; src < src_end; )
{
ch = step_char(&src, +1, src_end);
if ((ops & CVT_TO_LC) && IS_UPPER(ch))
{
/* Convert uppercase to lowercase. */
put_wchar(&dst, TO_LOWER(ch));
} else if ((ops & CVT_BS) && ch == '\b' && dst > odst)
{
/* Delete backspace and preceding char. */
do {
dst--;
} while (dst > odst &&
!IS_ASCII_OCTET(*dst) && !IS_UTF8_LEAD(*dst));
} else if ((ops & CVT_ANSI) && IS_CSI_START(ch))
{
/* Skip to end of ANSI escape sequence. */
src++; /* skip the CSI start char */
while (src < src_end)
if (!is_ansi_middle(*src++))
break;
} else
/* Just copy. */
put_wchar(&dst, ch);
}
if ((ops & CVT_CRLF) && dst > odst && dst[-1] == '\r')
dst--;
*dst = '\0';
if (lenp != NULL)
*lenp = dst - odst;
} }
/* /*
* Determine which conversions to perform. * Initialize saved pattern to nothing.
*/
static void
init_pattern(info)
struct pattern_info *info;
{
CLEAR_PATTERN(info->compiled);
info->text = NULL;
info->search_type = 0;
}
/*
* Initialize search variables.
*/
public void
init_search()
{
init_pattern(&search_info);
init_pattern(&filter_info);
}
/*
* Determine which text conversions to perform before pattern matching.
*/ */
static int static int
get_cvt_ops() get_cvt_ops()
@ -236,28 +180,12 @@ is_ucase(str)
* Is there a previous (remembered) search pattern? * Is there a previous (remembered) search pattern?
*/ */
static int static int
prev_pattern() prev_pattern(info)
struct pattern_info *info;
{ {
if (last_search_type & SRCH_NO_REGEX) if (info->search_type & SRCH_NO_REGEX)
return (last_pattern != NULL); return (info->text != NULL);
#if HAVE_POSIX_REGCOMP return (!is_null_pattern(info->compiled));
return (search_pattern != NULL);
#endif
#if HAVE_PCRE
return (search_pattern != NULL);
#endif
#if HAVE_RE_COMP
return (search_pattern != 0);
#endif
#if HAVE_REGCMP
return (search_pattern != NULL);
#endif
#if HAVE_V8_REGCOMP
return (search_pattern != NULL);
#endif
#if NO_REGEX
return (search_pattern != NULL);
#endif
} }
#if HILITE_SEARCH #if HILITE_SEARCH
@ -299,26 +227,11 @@ repaint_hilite(on)
if (pos == NULL_POSITION) if (pos == NULL_POSITION)
continue; continue;
epos = position(slinenum+1); epos = position(slinenum+1);
#if 0 (void) forw_line(pos);
/* goto_line(slinenum);
* If any character in the line is highlighted, put_line();
* repaint the line.
*
* {{ This doesn't work -- if line is drawn with highlights
* which should be erased (e.g. toggle -i with status column),
* we must redraw the line even if it has no highlights.
* For now, just repaint every line. }}
*/
if (is_hilited(pos, epos, 1, NULL))
#endif
{
(void) forw_line(pos);
goto_line(slinenum);
put_line();
}
} }
if (!oldbot) lower_left(); // if !oldbot
lower_left();
hide_hilite = save_hide_hilite; hide_hilite = save_hide_hilite;
} }
@ -375,7 +288,7 @@ clear_attn()
public void public void
undo_search() undo_search()
{ {
if (!prev_pattern()) if (!prev_pattern(&search_info))
{ {
error("No previous regular expression", NULL_PARG); error("No previous regular expression", NULL_PARG);
return; return;
@ -386,296 +299,6 @@ undo_search()
#endif #endif
} }
/*
* Compile a search pattern, for future use by match_pattern.
*/
static int
compile_pattern2(pattern, search_type, comp_pattern)
char *pattern;
int search_type;
void **comp_pattern;
{
if ((search_type & SRCH_NO_REGEX) == 0)
{
#if HAVE_POSIX_REGCOMP
regex_t *comp = (regex_t *) ecalloc(1, sizeof(regex_t));
regex_t **pcomp = (regex_t **) comp_pattern;
if (regcomp(comp, pattern, REGCOMP_FLAG))
{
free(comp);
error("Invalid pattern", NULL_PARG);
return (-1);
}
if (*pcomp != NULL)
regfree(*pcomp);
*pcomp = comp;
#endif
#if HAVE_PCRE
pcre *comp;
pcre **pcomp = (pcre **) comp_pattern;
const char *errstring;
int erroffset;
PARG parg;
comp = pcre_compile(pattern, 0,
&errstring, &erroffset, NULL);
if (comp == NULL)
{
parg.p_string = (char *) errstring;
error("%s", &parg);
return (-1);
}
*pcomp = comp;
#endif
#if HAVE_RE_COMP
PARG parg;
int *pcomp = (int *) comp_pattern;
if ((parg.p_string = re_comp(pattern)) != NULL)
{
error("%s", &parg);
return (-1);
}
*pcomp = 1;
#endif
#if HAVE_REGCMP
char *comp;
char **pcomp = (char **) comp_pattern;
if ((comp = regcmp(pattern, 0)) == NULL)
{
error("Invalid pattern", NULL_PARG);
return (-1);
}
if (pcomp != NULL)
free(*pcomp);
*pcomp = comp;
#endif
#if HAVE_V8_REGCOMP
struct regexp *comp;
struct regexp **pcomp = (struct regexp **) comp_pattern;
if ((comp = regcomp(pattern)) == NULL)
{
/*
* regcomp has already printed an error message
* via regerror().
*/
return (-1);
}
if (*pcomp != NULL)
free(*pcomp);
*pcomp = comp;
#endif
}
if (comp_pattern == (void **) &search_pattern)
{
if (last_pattern != NULL)
free(last_pattern);
last_pattern = (char *) calloc(1, strlen(pattern)+1);
if (last_pattern != NULL)
strcpy(last_pattern, pattern);
last_search_type = search_type;
} else
{
last_filter_type = search_type;
}
return (0);
}
/*
* Like compile_pattern2, but convert the pattern to lowercase if necessary.
*/
static int
compile_pattern(pattern, search_type, comp_pattern)
char *pattern;
int search_type;
void **comp_pattern;
{
char *cvt_pattern;
int result;
if (caseless != OPT_ONPLUS)
cvt_pattern = pattern;
else
{
cvt_pattern = (char*) ecalloc(1, cvt_length(strlen(pattern), CVT_TO_LC));
cvt_text(cvt_pattern, pattern, (int *)NULL, CVT_TO_LC);
}
result = compile_pattern2(cvt_pattern, search_type, comp_pattern);
if (cvt_pattern != pattern)
free(cvt_pattern);
return (result);
}
/*
* Forget that we have a compiled pattern.
*/
static void
uncompile_pattern(pattern)
void **pattern;
{
#if HAVE_POSIX_REGCOMP
regex_t **pcomp = (regex_t **) pattern;
if (*pcomp != NULL)
regfree(*pcomp);
*pcomp = NULL;
#endif
#if HAVE_PCRE
pcre **pcomp = (pcre **) pattern;
if (*pcomp != NULL)
pcre_free(*pcomp);
*pcomp = NULL;
#endif
#if HAVE_RE_COMP
int *pcomp = (int *) pattern;
*pcomp = 0;
#endif
#if HAVE_REGCMP
char **pcomp = (char **) pattern;
if (*pcomp != NULL)
free(*pcomp);
*pcomp = NULL;
#endif
#if HAVE_V8_REGCOMP
struct regexp **pcomp = (struct regexp **) pattern;
if (*pcomp != NULL)
free(*pcomp);
*pcomp = NULL;
#endif
}
static void
uncompile_search_pattern()
{
uncompile_pattern(&search_pattern);
last_pattern = NULL;
}
static void
uncompile_filter_pattern()
{
uncompile_pattern(&filter_pattern);
}
/*
* Is a compiled pattern null?
*/
static int
is_null_pattern(pattern)
void *pattern;
{
#if HAVE_POSIX_REGCOMP
return (pattern == NULL);
#endif
#if HAVE_PCRE
return (pattern == NULL);
#endif
#if HAVE_RE_COMP
return (pattern == 0);
#endif
#if HAVE_REGCMP
return (pattern == NULL);
#endif
#if HAVE_V8_REGCOMP
return (pattern == NULL);
#endif
}
/*
* Perform a pattern match with the previously compiled pattern.
* Set sp and ep to the start and end of the matched string.
*/
static int
match_pattern(pattern, line, line_len, sp, ep, notbol, search_type)
void *pattern;
char *line;
int line_len;
char **sp;
char **ep;
int notbol;
int search_type;
{
int matched;
#if HAVE_POSIX_REGCOMP
regex_t *spattern = (regex_t *) pattern;
#endif
#if HAVE_PCRE
pcre *spattern = (pcre *) pattern;
#endif
#if HAVE_RE_COMP
int spattern = (int) pattern;
#endif
#if HAVE_REGCMP
char *spattern = (char *) pattern;
#endif
#if HAVE_V8_REGCOMP
struct regexp *spattern = (struct regexp *) pattern;
#endif
if (search_type & SRCH_NO_REGEX)
return (match(last_pattern, strlen(last_pattern), line, line_len, sp, ep));
#if HAVE_POSIX_REGCOMP
{
regmatch_t rm;
int flags = (notbol) ? REG_NOTBOL : 0;
matched = !regexec(spattern, line, 1, &rm, flags);
if (matched)
{
#ifndef __WATCOMC__
*sp = line + rm.rm_so;
*ep = line + rm.rm_eo;
#else
*sp = rm.rm_sp;
*ep = rm.rm_ep;
#endif
}
}
#endif
#if HAVE_PCRE
{
int flags = (notbol) ? PCRE_NOTBOL : 0;
int ovector[3];
matched = pcre_exec(spattern, NULL, line, line_len,
0, flags, ovector, 3) >= 0;
if (matched)
{
*sp = line + ovector[0];
*ep = line + ovector[1];
}
}
#endif
#if HAVE_RE_COMP
matched = (re_exec(line) == 1);
/*
* re_exec doesn't seem to provide a way to get the matched string.
*/
*sp = *ep = NULL;
#endif
#if HAVE_REGCMP
*ep = regex(spattern, line);
matched = (*ep != NULL);
if (matched)
*sp = __loc1;
#endif
#if HAVE_V8_REGCOMP
#if HAVE_REGEXEC2
matched = regexec2(spattern, line, notbol);
#else
matched = regexec(spattern, line);
#endif
if (matched)
{
*sp = spattern->startp[0];
*ep = spattern->endp[0];
}
#endif
#if NO_REGEX
matched = match(last_pattern, strlen(last_pattern), line, line_len, sp, ep);
#endif
matched = (!(search_type & SRCH_NO_MATCH) && matched) ||
((search_type & SRCH_NO_MATCH) && !matched);
return (matched);
}
#if HILITE_SEARCH #if HILITE_SEARCH
/* /*
* Clear the hilite list. * Clear the hilite list.
@ -844,130 +467,17 @@ add_hilite(anchor, hl)
ihl->hl_next = hl; ihl->hl_next = hl;
} }
/*
* Adjust hl_startpos & hl_endpos to account for processing by cvt_text.
*/
static void
adj_hilite(anchor, linepos, cvt_ops)
struct hilite *anchor;
POSITION linepos;
int cvt_ops;
{
char *line;
char *oline;
int line_len;
char *line_end;
struct hilite *hl;
int checkstart;
POSITION opos;
POSITION npos;
POSITION hl_opos;
POSITION hl_npos;
LWCHAR ch;
int ncwidth;
/*
* The line was already scanned and hilites were added (in hilite_line).
* But it was assumed that each char position in the line
* correponds to one char position in the file.
* This may not be true if cvt_text modified the line.
* Get the raw line again. Look at each character.
*/
(void) forw_raw_line(linepos, &line, &line_len);
line_end = line + line_len;
opos = npos = linepos;
hl = anchor->hl_first;
if (hl == NULL)
return;
hl_opos = hl_npos = hl->hl_startpos;
checkstart = TRUE;
while (hl != NULL && line < line_end)
{
/*
* See if we need to adjust the current hl_startpos or
* hl_endpos. After adjusting startpos[i], move to endpos[i].
* After adjusting endpos[i], move to startpos[i+1].
* The hilite list must be sorted thus:
* startpos[0] < endpos[0] <= startpos[1] < endpos[1] <= etc.
*/
oline = line;
ch = step_char(&line, +1, line_end);
ncwidth = line - oline;
npos += ncwidth;
/* Figure out how this char was processed by cvt_text. */
if ((cvt_ops & CVT_BS) && ch == '\b')
{
/* Skip the backspace and the following char. */
oline = line;
ch = step_char(&line, +1, line_end);
ncwidth = line - oline;
npos += ncwidth;
} else if ((cvt_ops & CVT_TO_LC) && IS_UPPER(ch))
{
/* Converted uppercase to lower.
* Note that this may have changed the number of bytes
* that the character occupies. */
char dbuf[6];
char *dst = dbuf;
put_wchar(&dst, TO_LOWER(ch));
opos += dst - dbuf;
} else if ((cvt_ops & CVT_ANSI) && IS_CSI_START(ch))
{
/* Skip to end of ANSI escape sequence. */
line++; /* skip the CSI start char */
npos++;
while (line < line_end)
{
npos++;
if (!is_ansi_middle(*line++))
break;
}
} else
{
/* Ordinary unprocessed character. */
opos += ncwidth;
}
if (opos == hl_opos) {
/* Adjust highlight position. */
hl_npos = npos;
}
if (opos > hl_opos)
{
/*
* We've moved past the highlight position; store the
* adjusted highlight position and move to the next highlight.
*/
if (checkstart)
{
hl->hl_startpos = hl_npos;
hl_opos = hl->hl_endpos;
checkstart = FALSE;
} else
{
hl->hl_endpos = hl_npos;
hl = hl->hl_next;
if (hl != NULL)
hl_opos = hl->hl_startpos;
checkstart = TRUE;
}
hl_npos = npos;
}
}
}
/* /*
* Make a hilite for each string in a physical line which matches * Make a hilite for each string in a physical line which matches
* the current pattern. * the current pattern.
* sp,ep delimit the first match already found. * sp,ep delimit the first match already found.
*/ */
static void static void
hilite_line(linepos, line, line_len, sp, ep, cvt_ops) hilite_line(linepos, line, line_len, chpos, sp, ep, cvt_ops)
POSITION linepos; POSITION linepos;
char *line; char *line;
int line_len; int line_len;
int *chpos;
char *sp; char *sp;
char *ep; char *ep;
int cvt_ops; int cvt_ops;
@ -975,7 +485,6 @@ hilite_line(linepos, line, line_len, sp, ep, cvt_ops)
char *searchp; char *searchp;
char *line_end = line + line_len; char *line_end = line + line_len;
struct hilite *hl; struct hilite *hl;
struct hilite hilites;
if (sp == NULL || ep == NULL) if (sp == NULL || ep == NULL)
return; return;
@ -990,22 +499,13 @@ hilite_line(linepos, line, line_len, sp, ep, cvt_ops)
* (currently POSIX, PCRE and V8-with-regexec2). }} * (currently POSIX, PCRE and V8-with-regexec2). }}
*/ */
searchp = line; searchp = line;
/*
* Put the hilites into a temporary list until they're adjusted.
*/
hilites.hl_first = NULL;
do { do {
if (ep > sp) if (ep > sp)
{ {
/*
* Assume that each char position in the "line"
* buffer corresponds to one char position in the file.
* This is not quite true; we need to adjust later.
*/
hl = (struct hilite *) ecalloc(1, sizeof(struct hilite)); hl = (struct hilite *) ecalloc(1, sizeof(struct hilite));
hl->hl_startpos = linepos + (sp-line); hl->hl_startpos = linepos + chpos[sp-line];
hl->hl_endpos = linepos + (ep-line); hl->hl_endpos = linepos + chpos[ep-line];
add_hilite(&hilites, hl); add_hilite(&hilite_anchor, hl);
} }
/* /*
* If we matched more than zero characters, * If we matched more than zero characters,
@ -1018,23 +518,8 @@ hilite_line(linepos, line, line_len, sp, ep, cvt_ops)
searchp++; searchp++;
else /* end of line */ else /* end of line */
break; break;
} while (match_pattern(search_pattern, searchp, line_end - searchp, &sp, &ep, 1, last_search_type)); } while (match_pattern(search_info.compiled, search_info.text,
searchp, line_end - searchp, &sp, &ep, 1, search_info.search_type));
/*
* If there were backspaces in the original line, they
* were removed, and hl_startpos/hl_endpos are not correct.
* {{ This is very ugly. }}
*/
adj_hilite(&hilites, linepos, cvt_ops);
/*
* Now put the hilites into the real list.
*/
while ((hl = hilites.hl_next) != NULL)
{
hilites.hl_next = hl->hl_next;
add_hilite(&hilite_anchor, hl);
}
} }
#endif #endif
@ -1056,7 +541,7 @@ chg_caseless()
* Pattern did have uppercase. * Pattern did have uppercase.
* Discard the pattern; we can't change search caselessness now. * Discard the pattern; we can't change search caselessness now.
*/ */
uncompile_search_pattern(); clear_pattern(&search_info);
} }
#if HILITE_SEARCH #if HILITE_SEARCH
@ -1189,6 +674,8 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
char *sp, *ep; char *sp, *ep;
int line_match; int line_match;
int cvt_ops; int cvt_ops;
int cvt_len;
int *chpos;
POSITION linepos, oldpos; POSITION linepos, oldpos;
linenum = find_linenum(pos); linenum = find_linenum(pos);
@ -1260,7 +747,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
* the search. Remember the line number only if * the search. Remember the line number only if
* we're "far" from the last place we remembered it. * we're "far" from the last place we remembered it.
*/ */
if (linenums && abs((int)(pos - oldpos)) > 1024) if (linenums && abs((int)(pos - oldpos)) > 2048)
add_lnum(linenum, pos); add_lnum(linenum, pos);
oldpos = pos; oldpos = pos;
@ -1272,19 +759,19 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
* If we're doing backspace processing, delete backspaces. * If we're doing backspace processing, delete backspaces.
*/ */
cvt_ops = get_cvt_ops(); cvt_ops = get_cvt_ops();
cline = calloc(1, cvt_length(line_len, cvt_ops)); cvt_len = cvt_length(line_len, cvt_ops);
cvt_text(cline, line, &line_len, cvt_ops); cline = (char *) ecalloc(1, cvt_len);
chpos = cvt_alloc_chpos(cvt_len);
cvt_text(cline, line, chpos, &line_len, cvt_ops);
#if HILITE_SEARCH #if HILITE_SEARCH
/* /*
* Check to see if the line matches the filter pattern. * Check to see if the line matches the filter pattern.
* If so, add an entry to the filter list. * If so, add an entry to the filter list.
*/ */
if ((search_type & SRCH_FIND_ALL) && if ((search_type & SRCH_FIND_ALL) && prev_pattern(&filter_info)) {
!is_null_pattern(filter_pattern)) int line_filter = match_pattern(filter_info.compiled, filter_info.text,
{ cline, line_len, &sp, &ep, 0, filter_info.search_type);
int line_filter = match_pattern(filter_pattern,
cline, line_len, &sp, &ep, 0, last_filter_type);
if (line_filter) if (line_filter)
{ {
struct hilite *hl = (struct hilite *) struct hilite *hl = (struct hilite *)
@ -1301,10 +788,10 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
* We are successful if we either want a match and got one, * We are successful if we either want a match and got one,
* or if we want a non-match and got one. * or if we want a non-match and got one.
*/ */
if (!is_null_pattern(search_pattern)) if (prev_pattern(&search_info))
{ {
line_match = match_pattern(search_pattern, line_match = match_pattern(search_info.compiled, search_info.text,
cline, line_len, &sp, &ep, 0, search_type); cline, line_len, &sp, &ep, 0, search_type); //FIXME search_info.search_type
if (line_match) if (line_match)
{ {
/* /*
@ -1318,7 +805,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
* Just add the matches in this line to the * Just add the matches in this line to the
* hilite list and keep searching. * hilite list and keep searching.
*/ */
hilite_line(linepos, cline, line_len, sp, ep, cvt_ops); hilite_line(linepos, cline, line_len, chpos, sp, ep, cvt_ops);
#endif #endif
} else if (--matches <= 0) } else if (--matches <= 0)
{ {
@ -1334,10 +821,11 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
* the matches in this one line. * the matches in this one line.
*/ */
clr_hilite(); clr_hilite();
hilite_line(linepos, cline, line_len, sp, ep, cvt_ops); hilite_line(linepos, cline, line_len, chpos, sp, ep, cvt_ops);
} }
#endif #endif
free(cline); free(cline);
free(chpos);
if (plinepos != NULL) if (plinepos != NULL)
*plinepos = linepos; *plinepos = linepos;
return (0); return (0);
@ -1345,6 +833,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
} }
} }
free(cline); free(cline);
free(chpos);
} }
} }
@ -1363,7 +852,7 @@ hist_pattern(search_type)
if (pattern == NULL) if (pattern == NULL)
return (0); return (0);
if (compile_pattern(pattern, search_type, &search_pattern) < 0) if (set_pattern(&search_info, pattern, search_type) < 0)
return (0); return (0);
is_ucase_pattern = is_ucase(pattern); is_ucase_pattern = is_ucase(pattern);
@ -1405,13 +894,13 @@ search(search_type, pattern, n)
/* /*
* A null pattern means use the previously compiled pattern. * A null pattern means use the previously compiled pattern.
*/ */
if (!prev_pattern() && !hist_pattern(search_type)) if (!prev_pattern(&search_info) && !hist_pattern(search_type))
{ {
error("No previous regular expression", NULL_PARG); error("No previous regular expression", NULL_PARG);
return (-1); return (-1);
} }
if ((search_type & SRCH_NO_REGEX) != if ((search_type & SRCH_NO_REGEX) !=
(last_search_type & SRCH_NO_REGEX)) (search_info.search_type & SRCH_NO_REGEX))
{ {
error("Please re-enter search pattern", NULL_PARG); error("Please re-enter search pattern", NULL_PARG);
return -1; return -1;
@ -1441,7 +930,7 @@ search(search_type, pattern, n)
/* /*
* Compile the pattern. * Compile the pattern.
*/ */
if (compile_pattern(pattern, search_type, &search_pattern) < 0) if (set_pattern(&search_info, pattern, search_type) < 0)
return (-1); return (-1);
/* /*
* Ignore case if -I is set OR * Ignore case if -I is set OR
@ -1549,13 +1038,14 @@ prep_hilite(spos, epos, maxlines)
POSITION max_epos; POSITION max_epos;
int result; int result;
int i; int i;
/* /*
* Search beyond where we're asked to search, so the prep region covers * Search beyond where we're asked to search, so the prep region covers
* more than we need. Do one big search instead of a bunch of small ones. * more than we need. Do one big search instead of a bunch of small ones.
*/ */
#define SEARCH_MORE (3*size_linebuf) #define SEARCH_MORE (3*size_linebuf)
if (!prev_pattern() && !is_filtering()) if (!prev_pattern(&search_info) && !is_filtering())
return; return;
/* /*
@ -1648,7 +1138,9 @@ prep_hilite(spos, epos, maxlines)
if (epos == NULL_POSITION || epos > spos) if (epos == NULL_POSITION || epos > spos)
{ {
result = search_range(spos, epos, SRCH_FORW|SRCH_FIND_ALL, 0, int search_type = SRCH_FORW | SRCH_FIND_ALL;
search_type |= (search_info.search_type & SRCH_NO_REGEX);
result = search_range(spos, epos, search_type, 0,
maxlines, (POSITION*)NULL, &new_epos); maxlines, (POSITION*)NULL, &new_epos);
if (result < 0) if (result < 0)
return; return;
@ -1669,9 +1161,9 @@ set_filter_pattern(pattern, search_type)
{ {
clr_filter(); clr_filter();
if (pattern == NULL || *pattern == '\0') if (pattern == NULL || *pattern == '\0')
uncompile_filter_pattern(); clear_pattern(&filter_info);
else else
compile_pattern(pattern, search_type, &filter_pattern); set_pattern(&filter_info, pattern, search_type);
screen_trashed = 1; screen_trashed = 1;
} }
@ -1683,43 +1175,10 @@ is_filtering()
{ {
if (ch_getflags() & CH_HELPFILE) if (ch_getflags() & CH_HELPFILE)
return (0); return (0);
return !is_null_pattern(filter_pattern); return prev_pattern(&filter_info);
} }
#endif #endif
/*
* Simple pattern matching function.
* It supports no metacharacters like *, etc.
*/
static int
match(pattern, pattern_len, buf, buf_len, pfound, pend)
char *pattern;
int pattern_len;
char *buf;
int buf_len;
char **pfound, **pend;
{
register char *pp, *lp;
register char *pattern_end = pattern + pattern_len;
register char *buf_end = buf + buf_len;
for ( ; buf < buf_end; buf++)
{
for (pp = pattern, lp = buf; *pp == *lp; pp++, lp++)
if (pp == pattern_end || lp == buf_end)
break;
if (pp == pattern_end)
{
if (pfound != NULL)
*pfound = buf;
if (pend != NULL)
*pend = lp;
return (1);
}
}
return (0);
}
#if HAVE_V8_REGCOMP #if HAVE_V8_REGCOMP
/* /*
* This function is called by the V8 regcomp to report * This function is called by the V8 regcomp to report

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2008 Mark Nudelman * Copyright (C) 1984-2009 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -248,6 +248,7 @@ psignals()
{ {
wscroll = (sc_height + 1) / 2; wscroll = (sc_height + 1) / 2;
calc_jump_sline(); calc_jump_sline();
calc_shift_count();
screen_trashed = 1; screen_trashed = 1;
} }
} }

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 1984-2008 Mark Nudelman * Copyright (C) 1984-2009 Mark Nudelman
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file. * License or the Less License, as specified in the README file.
@ -720,6 +720,15 @@ v426 10/27/08 Fix ignaw terminal handling (thanks to Per Hedeland);
v427 3/16/09 A few Win32 fixes (thanks to Jason Hood). v427 3/16/09 A few Win32 fixes (thanks to Jason Hood).
v428 3/30/09 Add "|-" syntax to LESSOPEN. v428 3/30/09 Add "|-" syntax to LESSOPEN.
v429 4/10/09 Fix search highlighting bug with underlined text. v429 4/10/09 Fix search highlighting bug with underlined text.
-----------------------------------------------------------------
v430 4/22/09 Don't pass "-" to non-pipe LESSOPEN unless it starts with "-".
v431 4/29/09 Fix highlight bug when match is at end of line.
v432 6/27/09 Better fix for highlight bugs;
fix new problems with ignaw terminals.
v433 6/28/09 Cleanup search code.
v434 6/29/09 More cleanup.
v435 7/04/09 Fix bugs with non-regex filtering.
v436 7/05/09 Fix memory leak.
*/ */
char version[] = "429"; char version[] = "436";

View File

@ -1,10 +1,11 @@
# $FreeBSD$ # $FreeBSD$
PROG= less PROG= less
SRCS= main.c screen.c brac.c ch.c charset.c cmdbuf.c command.c decode.c \ SRCS= main.c screen.c brac.c ch.c charset.c cmdbuf.c command.c cvt.c \
edit.c filename.c forwback.c help.c ifile.c input.c jump.c line.c \ decode.c edit.c filename.c forwback.c help.c ifile.c input.c \
linenum.c lsystem.c mark.c optfunc.c option.c opttbl.c os.c output.c \ jump.c line.c linenum.c lsystem.c mark.c optfunc.c option.c \
position.c prompt.c search.c signal.c tags.c ttyin.c version.c opttbl.c os.c output.c pattern.c position.c prompt.c search.c \
signal.c tags.c ttyin.c version.c
SCRIPTS=lesspipe.sh zless.sh SCRIPTS=lesspipe.sh zless.sh
SCRIPTSNAME_lesspipe.sh=lesspipe.sh SCRIPTSNAME_lesspipe.sh=lesspipe.sh
DPADD= ${LIBTERMCAP} DPADD= ${LIBTERMCAP}