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,6 +843,8 @@ open_altfile(filename, pf, pfd)
#else #else
lessopen++; lessopen++;
returnfd = 1; returnfd = 1;
#endif
}
if (*lessopen == '-') { if (*lessopen == '-') {
/* /*
* Lessopen preprocessor will accept "-" as a filename. * Lessopen preprocessor will accept "-" as a filename.
@ -852,8 +854,6 @@ open_altfile(filename, pf, pfd)
if (strcmp(filename, "-") == 0) if (strcmp(filename, "-") == 0)
return (NULL); return (NULL);
} }
#endif
}
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,7 +809,14 @@ 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
@ -1039,10 +1046,16 @@ LESS(1) LESS(1)
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
@ -1520,7 +1533,7 @@ 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-
@ -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
#define DEFINE_PATTERN(name) int name = 0;
#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); static struct pattern_info search_info;
DEFINE_PATTERN(filter_pattern); static struct pattern_info filter_info;
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
/*
* If any character in the line is highlighted,
* 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); (void) forw_line(pos);
goto_line(slinenum); goto_line(slinenum);
put_line(); put_line();
} }
} lower_left(); // if !oldbot
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}