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
Copyright (C) 1984-2008 Mark Nudelman
Copyright (C) 1984-2009 Mark Nudelman
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions

View File

@ -10,10 +10,10 @@ srcdir = .
SRC = \
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 \
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
DISTFILES_W = \
defines.ds Makefile.dsb Makefile.dsg Makefile.dsu \
@ -24,7 +24,8 @@ DISTFILES = \
${SRC} regexp.c regexp.h \
COPYING INSTALL LICENSE Makefile.in Makefile.aut NEWS README \
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 \
less.nro less.man lesskey.nro lesskey.man lessecho.nro lessecho.man \
less.hlp \
@ -109,6 +110,8 @@ dist: ${DISTFILES}
cd $$REL; chmod +w ${DISTFILES_W}; cd ..; \
echo "Creating release/$$REL/$$REL.tar.gz"; \
tar -cf - $$REL | gzip -c >release/$$REL/$$REL.tar.gz; \
echo "Signing release/$$REL/$$REL.tar.gz"; \
gpg --detach-sign release/$$REL/$$REL.tar.gz; \
echo "Creating release/$$REL/$$REL.zip"; \
zip -rq release/$$REL/$$REL.zip $$REL; \
rm -rf $$REL

View File

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

View File

@ -33,11 +33,12 @@ manext = 1
.c.o:
${CC} -I. ${CFLAGS_COMPILE_ONLY} -DBINDIR=\"${bindir}\" -DSYSDIR=\"${sysconfdir}\" ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \
OBJ = \
main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} cvt.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \
help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \
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}
all: less lesskey lessecho

View File

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

View File

@ -43,11 +43,12 @@ SHELL = /bin/sh
.c.o:
${CC} -I. ${CFLAGS_COMPILE_ONLY} -DBINDIR=\"${bindir}\" -DSYSDIR=\"${sysconfdir}\" ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \
OBJ = \
main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} cvt.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \
help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \
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@
all: less$(EXEEXT) lesskey$(EXEEXT) lessecho$(EXEEXT)

View File

@ -18,11 +18,12 @@ O = obj
.c.${O}:
${CC} -c ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \
OBJ = \
main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} cvt.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \
help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \
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}
all: less.exe lesskey.exe scrsize.exe

View File

@ -22,11 +22,12 @@ O = r
.c.${O}:
${CC} ${CFLAGS_COMPILE_ONLY} ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \
OBJ = \
main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} cvt.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \
help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \
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}
all: less lessecho lesskey

View File

@ -21,11 +21,12 @@ O = r
.c.${O}:
${CC} ${CFLAGS_COMPILE_ONLY} ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \
OBJ = \
main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} cvt.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \
help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \
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}
all: less lesskey

View File

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

View File

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

View File

@ -10,6 +10,18 @@
To report bugs, suggestions or comments, send email to
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

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 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
* 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
* 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
* License or the Less License, as specified in the README file.
@ -425,7 +425,7 @@ prchar(c)
c &= 0377;
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)
strcpy(buf, "ESC");
#if IS_EBCDIC_HOST
@ -442,7 +442,7 @@ prchar(c)
"..V....D....TU.Z"[c]);
#else
else if (c < 128 && !control_char(c ^ 0100))
SNPRINTF1(buf, sizeof(buf), "^%c", c ^ 0100);
SNPRINTF1(buf, sizeof(buf), "^%c", (int) (c ^ 0100));
#endif
else
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
* 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
* 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
* License or the Less License, as specified in the README file.

View File

@ -1,6 +1,6 @@
/* $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
* 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.
# Copyright (C) 1984-2008 Mark Nudelman
# 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.

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
* 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
* 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
* 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
* 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
* 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
* 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
* License or the Less License, as specified in the README file.
@ -843,6 +843,8 @@ open_altfile(filename, pf, pfd)
#else
lessopen++;
returnfd = 1;
#endif
}
if (*lessopen == '-') {
/*
* Lessopen preprocessor will accept "-" as a filename.
@ -852,8 +854,6 @@ open_altfile(filename, pf, pfd)
if (strcmp(filename, "-") == 0)
return (NULL);
}
#endif
}
len = strlen(lessopen) + strlen(filename) + 2;
cmd = (char *) ecalloc(len, sizeof(char));

View File

@ -1,6 +1,6 @@
/* $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
* License or the Less License, as specified in the README file.

View File

@ -83,6 +83,9 @@
public void ungetcc ();
public void ungetsc ();
public void commands ();
public int cvt_length ();
public int * cvt_alloc_chpos ();
public void cvt_text ();
public void init_cmds ();
public void add_fcmd_table ();
public void add_ecmd_table ();
@ -193,6 +196,8 @@
public void opt_l ();
public void opt_j ();
public void calc_jump_sline ();
public void opt_shift ();
public void calc_shift_count ();
public void opt_k ();
public void opt_t ();
public void opt__T ();
@ -233,6 +238,10 @@
public void error ();
public void ierror ();
public int query ();
public int compile_pattern ();
public void uncompile_pattern ();
public int is_null_pattern ();
public int match_pattern ();
public POSITION position ();
public void add_forw_pos ();
public void add_back_pos ();
@ -248,6 +257,7 @@
public char * eq_message ();
public char * pr_string ();
public char * wait_message ();
public void init_search ();
public void repaint_hilite ();
public void clear_attn ();
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
* 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
* License or the Less License, as specified in the README file.
@ -196,7 +196,7 @@ forw_line(curr_pos)
c = ch_forw_get();
}
pdone(endline, c);
pdone(endline, 1);
#if HILITE_SEARCH
if (is_filtered(base_pos))
@ -398,7 +398,7 @@ back_line(curr_pos)
}
} while (new_pos < curr_pos);
pdone(endline, ch_forw_get());
pdone(endline, 0);
#if HILITE_SEARCH
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
* License or the Less License, as specified in the README file.

View File

@ -1,6 +1,6 @@
/* $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
* License or the Less License, as specified in the README file.
@ -489,6 +489,12 @@ struct textlist
#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"
/* 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
in the RIGHTARROW and LEFTARROW commands. If the number speci-
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
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
name passed to the LESSCLOSE postprocessor is "-".
For compatibility with previous versions of less, the input pipe is not
used if less is viewing standard input. However, if the character
after the vertical bar is a dash (-), the input pipe is used on stan-
dard input as well as other files.
For compatibility with previous versions of less, the input preproces-
sor or pipe is not used if less is viewing standard input. However, if
the first character of LESSOPEN is a dash (-), the input preprocessor
is used on standard input as well as other files. In this case, the
dash is not considered to be part of the preprocessor command. If
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
@ -1520,7 +1533,7 @@ LESS(1) LESS(1)
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-
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
less \- opposite of more
.SH SYNOPSIS
@ -864,6 +864,13 @@ Specifies the default number of positions to scroll horizontally
in the RIGHTARROW and LEFTARROW commands.
If the number specified is zero, it sets the default number of
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"
Disables sending the keypad initialization and deinitialization strings
to the terminal.
@ -1149,11 +1156,19 @@ postprocessor is "\-".
.PP
For compatibility with previous versions of
.I less,
the input pipe is not used if
the input preprocessor or pipe is not used if
.I less
is viewing standard input.
However, if the character after the vertical bar is a dash (\-),
the input pipe is used on standard input as well as other files.
However, if the first character of LESSOPEN is a dash (\-),
the input preprocessor is used on standard input as well as other files.
In this case, the dash is not considered to be part of
the preprocessor command.
If 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"
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)
.SH COPYRIGHT
Copyright (C) 1984-2008 Mark Nudelman
Copyright (C) 1984-2009 Mark Nudelman
.PP
less is part of the GNU project and is free software.
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
* License or the Less License, as specified in the README file.
@ -28,7 +28,7 @@
#include "less.h"
static char *version = "$Revision: 1.12 $";
static char *version = "$Revision: 1.13 $";
static int quote_all = 0;
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
lessecho \- expand metacharacters
.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
* 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
* License or the Less License, as specified in the README file.

View File

@ -333,7 +333,7 @@ LESSKEY(1) LESSKEY(1)
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-
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
lesskey \- specify key bindings for less
.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.
.SH COPYRIGHT
Copyright (C) 2000-2008 Mark Nudelman
Copyright (C) 2000-2009 Mark Nudelman
.PP
lesskey is part of the GNU project and is free software;
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
* License or the Less License, as specified in the README file.

View File

@ -1,6 +1,6 @@
/* $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
* License or the Less License, as specified in the README file.
@ -990,12 +990,10 @@ pflushmbc()
* Terminate the line in the line buffer.
*/
public void
pdone(endline, nextc)
pdone(endline, forw)
int endline;
int nextc;
int forw;
{
int nl;
(void) pflushmbc();
if (pendc && (pendc != '\r' || !endline))
@ -1042,7 +1040,7 @@ pdone(endline, nextc)
attr[curr] = AT_NORMAL;
curr++;
}
else if (ignaw && column >= sc_width)
else if (ignaw && column >= sc_width && forw)
{
/*
* 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
* have been output but the cursor is sitting on the right edge
* instead of at the start of the next line.
* So we nudge them into wrapping by outputting the next
* character plus a backspace. (This wouldn't be right for
* "!auto_wrap" terminals, but they always end up in the
* branch above.)
* So we nudge them into wrapping by outputting a space
* character plus a backspace. But do this only if moving
* forward; if we're moving backward and drawing this line at
* 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;
linebuf[curr] = '\b';
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
* 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
* License or the Less License, as specified in the README file.

View File

@ -1,6 +1,6 @@
/* $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
* License or the Less License, as specified in the README file.
@ -121,6 +121,7 @@ main(argc, argv)
init_line();
init_cmdhist();
init_option();
init_search();
/*
* 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
* 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
* 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
* License or the Less License, as specified in the README file.
@ -33,6 +33,7 @@ extern int bufspace;
extern int pr_type;
extern int plusoption;
extern int swindow;
extern int sc_width;
extern int sc_height;
extern int secure;
extern int dohelp;
@ -47,6 +48,8 @@ extern IFILE curr_ifile;
extern char version[];
extern int jump_sline;
extern int jump_sline_fraction;
extern int shift_count;
extern int shift_count_fraction;
extern int less_is_more;
#if LOGFILE
extern char *namelogfile;
@ -221,6 +224,70 @@ calc_jump_sline()
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
public void
opt_k(type, s)
@ -442,7 +509,7 @@ opt__V(type, s)
any_display = 1;
putstr("less ");
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("For information about the terms of redistribution,\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
* 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
* 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
* License or the Less License, as specified in the README file.
@ -41,6 +41,7 @@ public int force_open; /* Open the file even if not regular file */
public int swindow; /* Size of scrolling window */
public int jump_sline; /* Screen line of "jump target" */
public long jump_sline_fraction = -1;
public long shift_count_fraction = -1;
public int chopline; /* Truncate displayed lines at screen width */
public int no_init; /* Disable sending ti/te termcap strings */
public int no_keypad; /* Disable sending ks/ke termcap strings */
@ -419,10 +420,10 @@ static struct loption option[] =
{ NULL, NULL, NULL }
},
{ '#', &pound_optname,
NUMBER, 0, &shift_count, NULL,
STRING, 0, NULL, opt_shift,
{
"Horizontal shift: ",
"Horizontal shift %d positions",
"0123456789.",
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
* 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
* 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
* 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
* 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
* License or the Less License, as specified in the README file.

View File

@ -1,6 +1,6 @@
/* $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
* License or the Less License, as specified in the README file.

View File

@ -1,6 +1,6 @@
/* $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
* 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
* License or the Less License, as specified in the README file.

View File

@ -1,6 +1,6 @@
/* $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
* License or the Less License, as specified in the README file.
@ -15,38 +15,13 @@
*/
#include "less.h"
#include "pattern.h"
#include "position.h"
#include "charset.h"
#define MINPOS(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 how_search;
extern int caseless;
@ -68,9 +43,10 @@ extern int size_linebuf;
extern int squished;
extern int can_goto_line;
static int hide_hilite;
static int oldbot;
static POSITION prep_startpos;
static POSITION prep_endpos;
static int is_caseless;
static int is_ucase_pattern;
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"
* search pattern.
* search pattern and filter pattern.
*/
#if HAVE_POSIX_REGCOMP
#define DEFINE_PATTERN(name) static regex_t *name = NULL
#endif
#if HAVE_PCRE
#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
struct pattern_info {
DEFINE_PATTERN(compiled);
char* text;
int search_type;
};
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 */
static struct pattern_info search_info;
static struct pattern_info filter_info;
/*
* Get the length of a buffer needed to convert a string.
* Compile and save a search pattern.
*/
static int
cvt_length(len, ops)
int len;
int ops;
set_pattern(info, pattern, search_type)
struct pattern_info *info;
char *pattern;
int search_type;
{
if (utf_mode)
/*
* Just copying a string in UTF-8 mode can cause it to grow
* in length.
* Six output bytes for one input byte is the worst case
* (and unfortunately is far more than is needed in any
* non-pathological situation, so this is very wasteful).
*/
len *= 6;
return len + 1;
if (pattern == NULL)
CLEAR_PATTERN(search_info.compiled);
else if (compile_pattern(pattern, search_type, &info->compiled) < 0)
return -1;
/* Pattern compiled successfully; save the text too. */
if (info->text != NULL)
free(info->text);
info->text = NULL;
if (pattern != NULL)
{
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
cvt_text(odst, osrc, lenp, ops)
char *odst;
char *osrc;
int *lenp;
int ops;
clear_pattern(info)
struct pattern_info *info;
{
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; )
{
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;
if (info->text != NULL)
free(info->text);
info->text = NULL;
uncompile_pattern(&info->compiled);
}
/*
* 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
get_cvt_ops()
@ -236,28 +180,12 @@ is_ucase(str)
* Is there a previous (remembered) search pattern?
*/
static int
prev_pattern()
prev_pattern(info)
struct pattern_info *info;
{
if (last_search_type & SRCH_NO_REGEX)
return (last_pattern != NULL);
#if HAVE_POSIX_REGCOMP
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 (info->search_type & SRCH_NO_REGEX)
return (info->text != NULL);
return (!is_null_pattern(info->compiled));
}
#if HILITE_SEARCH
@ -299,26 +227,11 @@ repaint_hilite(on)
if (pos == NULL_POSITION)
continue;
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);
goto_line(slinenum);
put_line();
}
}
if (!oldbot)
lower_left();
lower_left(); // if !oldbot
hide_hilite = save_hide_hilite;
}
@ -375,7 +288,7 @@ clear_attn()
public void
undo_search()
{
if (!prev_pattern())
if (!prev_pattern(&search_info))
{
error("No previous regular expression", NULL_PARG);
return;
@ -386,296 +299,6 @@ undo_search()
#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
/*
* Clear the hilite list.
@ -844,130 +467,17 @@ add_hilite(anchor, 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
* the current pattern.
* sp,ep delimit the first match already found.
*/
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;
char *line;
int line_len;
int *chpos;
char *sp;
char *ep;
int cvt_ops;
@ -975,7 +485,6 @@ hilite_line(linepos, line, line_len, sp, ep, cvt_ops)
char *searchp;
char *line_end = line + line_len;
struct hilite *hl;
struct hilite hilites;
if (sp == NULL || ep == NULL)
return;
@ -990,22 +499,13 @@ hilite_line(linepos, line, line_len, sp, ep, cvt_ops)
* (currently POSIX, PCRE and V8-with-regexec2). }}
*/
searchp = line;
/*
* Put the hilites into a temporary list until they're adjusted.
*/
hilites.hl_first = NULL;
do {
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->hl_startpos = linepos + (sp-line);
hl->hl_endpos = linepos + (ep-line);
add_hilite(&hilites, hl);
hl->hl_startpos = linepos + chpos[sp-line];
hl->hl_endpos = linepos + chpos[ep-line];
add_hilite(&hilite_anchor, hl);
}
/*
* If we matched more than zero characters,
@ -1018,23 +518,8 @@ hilite_line(linepos, line, line_len, sp, ep, cvt_ops)
searchp++;
else /* end of line */
break;
} while (match_pattern(search_pattern, searchp, line_end - searchp, &sp, &ep, 1, last_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);
}
} while (match_pattern(search_info.compiled, search_info.text,
searchp, line_end - searchp, &sp, &ep, 1, search_info.search_type));
}
#endif
@ -1056,7 +541,7 @@ chg_caseless()
* Pattern did have uppercase.
* Discard the pattern; we can't change search caselessness now.
*/
uncompile_search_pattern();
clear_pattern(&search_info);
}
#if HILITE_SEARCH
@ -1189,6 +674,8 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
char *sp, *ep;
int line_match;
int cvt_ops;
int cvt_len;
int *chpos;
POSITION linepos, oldpos;
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
* 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);
oldpos = pos;
@ -1272,19 +759,19 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
* If we're doing backspace processing, delete backspaces.
*/
cvt_ops = get_cvt_ops();
cline = calloc(1, cvt_length(line_len, cvt_ops));
cvt_text(cline, line, &line_len, cvt_ops);
cvt_len = cvt_length(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
/*
* Check to see if the line matches the filter pattern.
* If so, add an entry to the filter list.
*/
if ((search_type & SRCH_FIND_ALL) &&
!is_null_pattern(filter_pattern))
{
int line_filter = match_pattern(filter_pattern,
cline, line_len, &sp, &ep, 0, last_filter_type);
if ((search_type & SRCH_FIND_ALL) && prev_pattern(&filter_info)) {
int line_filter = match_pattern(filter_info.compiled, filter_info.text,
cline, line_len, &sp, &ep, 0, filter_info.search_type);
if (line_filter)
{
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,
* 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,
cline, line_len, &sp, &ep, 0, search_type);
line_match = match_pattern(search_info.compiled, search_info.text,
cline, line_len, &sp, &ep, 0, search_type); //FIXME search_info.search_type
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
* 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
} else if (--matches <= 0)
{
@ -1334,10 +821,11 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
* the matches in this one line.
*/
clr_hilite();
hilite_line(linepos, cline, line_len, sp, ep, cvt_ops);
hilite_line(linepos, cline, line_len, chpos, sp, ep, cvt_ops);
}
#endif
free(cline);
free(chpos);
if (plinepos != NULL)
*plinepos = linepos;
return (0);
@ -1345,6 +833,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
}
}
free(cline);
free(chpos);
}
}
@ -1363,7 +852,7 @@ hist_pattern(search_type)
if (pattern == NULL)
return (0);
if (compile_pattern(pattern, search_type, &search_pattern) < 0)
if (set_pattern(&search_info, pattern, search_type) < 0)
return (0);
is_ucase_pattern = is_ucase(pattern);
@ -1405,13 +894,13 @@ search(search_type, pattern, n)
/*
* 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);
return (-1);
}
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);
return -1;
@ -1441,7 +930,7 @@ search(search_type, pattern, n)
/*
* Compile the pattern.
*/
if (compile_pattern(pattern, search_type, &search_pattern) < 0)
if (set_pattern(&search_info, pattern, search_type) < 0)
return (-1);
/*
* Ignore case if -I is set OR
@ -1549,13 +1038,14 @@ prep_hilite(spos, epos, maxlines)
POSITION max_epos;
int result;
int i;
/*
* 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.
*/
#define SEARCH_MORE (3*size_linebuf)
if (!prev_pattern() && !is_filtering())
if (!prev_pattern(&search_info) && !is_filtering())
return;
/*
@ -1648,7 +1138,9 @@ prep_hilite(spos, epos, maxlines)
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);
if (result < 0)
return;
@ -1669,9 +1161,9 @@ set_filter_pattern(pattern, search_type)
{
clr_filter();
if (pattern == NULL || *pattern == '\0')
uncompile_filter_pattern();
clear_pattern(&filter_info);
else
compile_pattern(pattern, search_type, &filter_pattern);
set_pattern(&filter_info, pattern, search_type);
screen_trashed = 1;
}
@ -1683,43 +1175,10 @@ is_filtering()
{
if (ch_getflags() & CH_HELPFILE)
return (0);
return !is_null_pattern(filter_pattern);
return prev_pattern(&filter_info);
}
#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
/*
* 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
* License or the Less License, as specified in the README file.
@ -248,6 +248,7 @@ psignals()
{
wscroll = (sc_height + 1) / 2;
calc_jump_sline();
calc_shift_count();
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
* 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
* 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
* 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).
v428 3/30/09 Add "|-" syntax to LESSOPEN.
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$
PROG= less
SRCS= main.c screen.c brac.c ch.c charset.c cmdbuf.c command.c decode.c \
edit.c filename.c forwback.c help.c ifile.c input.c jump.c line.c \
linenum.c lsystem.c mark.c optfunc.c option.c opttbl.c os.c output.c \
position.c prompt.c search.c signal.c tags.c ttyin.c version.c
SRCS= main.c screen.c brac.c ch.c charset.c cmdbuf.c command.c cvt.c \
decode.c edit.c filename.c forwback.c help.c ifile.c input.c \
jump.c line.c linenum.c lsystem.c mark.c optfunc.c option.c \
opttbl.c os.c output.c pattern.c position.c prompt.c search.c \
signal.c tags.c ttyin.c version.c
SCRIPTS=lesspipe.sh zless.sh
SCRIPTSNAME_lesspipe.sh=lesspipe.sh
DPADD= ${LIBTERMCAP}