1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-27 11:55:06 +00:00

Vendor import of less v436.

This commit is contained in:
Xin LI 2009-07-27 07:05:08 +00:00
parent e1193b7bca
commit f4cb5a505f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/less/dist/; revision=195902
svn path=/vendor/less/v436/; revision=195903; tag=vendor/less/v436
70 changed files with 1129 additions and 1033 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

12
NEWS
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

4
README
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

2
brac.c
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.

2
ch.c
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.

2
cmd.h
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 @@
# 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
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.

2
edit.c
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,17 +843,17 @@ open_altfile(filename, pf, pfd)
#else
lessopen++;
returnfd = 1;
if (*lessopen == '-') {
/*
* Lessopen preprocessor will accept "-" as a filename.
*/
lessopen++;
} else {
if (strcmp(filename, "-") == 0)
return (NULL);
}
#endif
}
if (*lessopen == '-') {
/*
* Lessopen preprocessor will accept "-" as a filename.
*/
lessopen++;
} else {
if (strcmp(filename, "-") == 0)
return (NULL);
}
len = strlen(lessopen) + strlen(filename) + 2;
cmd = (char *) ecalloc(len, sizeof(char));

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.

10
funcs.h
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))

2
jump.c
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.

8
less.h
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.
@ -488,6 +488,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 */

517
less.man
View File

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

22
line.c
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.
@ -989,12 +989,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))
@ -1041,7 +1039,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
@ -1050,12 +1048,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.

3
main.c
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.
@ -118,6 +118,7 @@ main(argc, argv)
init_line();
init_cmdhist();
init_option();
init_search();
/*
* If the name of the executable program is "more",

2
mark.c
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
}
},

2
os.c
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
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);
}

48
pattern.h Normal file
View File

@ -0,0 +1,48 @@
/*
* 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
#define REGCOMP_FLAG 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,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.

761
search.c
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.
@ -14,38 +14,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 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;
@ -66,9 +41,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
{
@ -83,112 +59,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
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 */
struct pattern_info {
DEFINE_PATTERN(compiled);
char* text;
int search_type;
};
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()
@ -234,28 +178,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
@ -297,26 +225,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();
}
(void) forw_line(pos);
goto_line(slinenum);
put_line();
}
if (!oldbot)
lower_left();
lower_left(); // if !oldbot
hide_hilite = save_hide_hilite;
}
@ -373,7 +286,7 @@ clear_attn()
public void
undo_search()
{
if (!prev_pattern())
if (!prev_pattern(&search_info))
{
error("No previous regular expression", NULL_PARG);
return;
@ -384,296 +297,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.
@ -842,130 +465,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;
@ -973,7 +483,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;
@ -988,22 +497,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,
@ -1016,23 +516,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
@ -1054,7 +539,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
@ -1187,6 +672,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);
@ -1258,7 +745,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;
@ -1270,19 +757,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 *)
@ -1299,10 +786,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)
{
/*
@ -1316,7 +803,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)
{
@ -1332,10 +819,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);
@ -1343,6 +831,7 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
}
}
free(cline);
free(chpos);
}
}
@ -1361,7 +850,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);
@ -1403,13 +892,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;
@ -1439,7 +928,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
@ -1547,13 +1036,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;
/*
@ -1646,7 +1136,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;
@ -1667,9 +1159,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;
}
@ -1681,43 +1173,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.
@ -244,6 +244,7 @@ psignals()
{
wscroll = (sc_height + 1) / 2;
calc_jump_sline();
calc_shift_count();
screen_trashed = 1;
}
}

2
tags.c
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";