Import less v371

This commit is contained in:
ps 2002-01-07 20:29:38 +00:00
parent 5d465776b9
commit c0c85bc41c
45 changed files with 2986 additions and 1419 deletions

View File

@ -1,7 +1,7 @@
# Makefile for authoring less.
EMAIL = marknu@flash.net
HOMEPAGE = http://www.flash.net/~marknu/less
EMAIL = markn@greenwoodsoftware.com
HOMEPAGE = http://www.greenwoodsoftware.com/less
SHELL = /bin/sh
RCS = rcs
NROFF = nroff -man
@ -23,7 +23,7 @@ DISTFILES_W = \
DISTFILES = \
${SRC} regexp.c regexp.h \
COPYING INSTALL LICENSE Makefile.in Makefile.aut NEWS README \
configure configure.in acconfig.h lesskey.c lessecho.c \
configure configure.in acconfig.h lesskey.c lessecho.c scrsize.c \
cmd.h funcs.h lglob.h less.h lesskey.h option.h pckeys.h position.h \
install.sh defines.h.in defines.h.top mkinstalldirs \
less.nro lesskey.nro less.man lesskey.man less.hlp \

View File

@ -24,6 +24,8 @@ exec_prefix = @exec_prefix@
bindir = @bindir@
binprefix =
sysconfdir = @sysconfdir@
mandir = @mandir@
manext = 1
manprefix =
@ -35,7 +37,7 @@ SHELL = /bin/sh
# This rule allows us to supply the necessary -D options
# in addition to whatever the user asks for.
.c.o:
${CC} -I. ${CFLAGS_COMPILE_ONLY} -DSYSDIR=\"${bindir}\" ${CPPFLAGS} ${CFLAGS} $<
${CC} -I. ${CFLAGS_COMPILE_ONLY} -DBINDIR=\"${bindir}\" -DSYSDIR=\"${sysconfdir}\" ${CPPFLAGS} ${CFLAGS} $<
OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
command.${O} decode.${O} edit.${O} filename.${O} forwback.${O} \

View File

@ -4,8 +4,8 @@
#### Start of system configuration section. ####
CC = gcc -Zomf
CFLAGS = -I. -O
LDFLAGS = -s -Zcrtdll -Zstack 512
CFLAGS = -I. -O2 -Wall
LDFLAGS = -s -Zcrtdll
LIBS = -ltermcap
O = obj
@ -25,7 +25,7 @@ OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \
output.${O} position.${O} prompt.${O} search.${O} signal.${O} \
tags.${O} ttyin.${O} version.${O} regexp.${O}
all: less.exe lesskey.exe
all: less.exe lesskey.exe scrsize.exe
less.exe: ${OBJ}
${CC} ${OBJ} -o $@ ${LDFLAGS} ${LIBS}
@ -33,6 +33,9 @@ less.exe: ${OBJ}
lesskey.exe: lesskey.${O} version.${O}
${CC} lesskey.${O} version.${O} -o $@ ${LDFLAGS}
scrsize.exe: scrsize.c
${CC} ${CFLAGS} -D__ST_MT_ERRNO__ -s -Zmtd -lX11 $<
${OBJ}: defines.h less.h
defines.h: defines.o2

View File

@ -4,15 +4,59 @@
======================================================================
For the latest news about less, see the "less" Web page:
http://www.flash.net/~marknu/less
http://www.greenwoodsoftware.com/less
You can also download the latest version of less from there.
To report bugs, suggestions or comments, send email to
bug-less@gnu.org or marknu@flash.net.
bug-less@gnu.org or markn@greenwoodsoftware.com.
======================================================================
Major changes between "less" versions 358 and 371
* -x option can now specify multiple variable-width tab stops.
* -X option no longer disables keypad initialization.
New option --no-keypad disables keypad initialization.
* New commands t and T step through multiple tag matches.
Added support for "global(1)" tags
(see http://www.gnu.org/software/global/global.html).
* New prompt style set by option -Pw defines the message printed
while waiting for data in the F command.
* System-wide lesskey file now defaults to sysless in etc directory
instead of .sysless in bin directory.
Use "configure --sysconfdir=..." to change it.
(For backwards compatibility, .sysless in bin is still recognized.)
* Pressing RightArrow or LeftArrow while entering a number now shifts
the display N columns rather than editing the number itself.
* Status column (enabled with -J) now shows search results.
* Windows version sets window title.
* Default LESSCHARSET for MS-DOS versions is now "dos".
* Improved performance in reading very large files.
* Eliminated some dependencies on file offets being 32 bits.
* Fixed problems when viewing files with very long lines.
* Fixed overstriking in UTF-8 mode, and overstriking tabs.
* Improved horizontal shifting of text using -R option with ANSI color.
* Some fixes for EBCDIC systems.
* Some fixes for OS/2 systems.
======================================================================
Major changes between "less" versions 354 and 358
* Add -J (--status-column) option to display a status column.

View File

@ -1,7 +1,7 @@
Less, version 358
Less, version 371
This is the distribution of less, version 358, released 08 Jul 2000.
This is the distribution of less, version 371, released 26 Dec 2001.
This program is part of the GNU project (http://www.gnu.org).
This program is free software. You may redistribute it and/or
@ -13,8 +13,8 @@
or
2. The Less License, in the file LICENSE.
Please report any problems to bug-less@gnu.org or marknu@flash.net.
See http://www.flash.net/~marknu/less for the latest info.
Please report any problems to bug-less@gnu.org or markn@greenwoodsoftware.com.
See http://www.greenwoodsoftware.com/less for the latest info.
You may also contact the author at:
Mark Nudelman
Greenwood Software
@ -91,7 +91,7 @@ INSTALLATION (Unix systems only):
bindir and/or mandir to the appropriate directories.
If you have any problems building or running "less", suggestions,
complaints, etc., you may mail to the author at marknu@flash.net.
complaints, etc., you may mail to the author at markn@greenwoodsoftware.com.
Note to hackers: comments noting possible improvements are enclosed
in double curly brackets {{ like this }}.
@ -191,8 +191,10 @@ INSTALLATION (OS/2 systems only,
somewhere in a directory listed in the PATH or INIT environment
variables.
8. When satisfied that it works, you may wish to install less.exe and
lesskey.exe in a directory which is included in your PATH.
8. When satisfied that it works, you may wish to install less.exe,
lesskey.exe and scrsize.exe in a directory which is included in
your PATH. scrsize.exe is required only if you use a terminal
emulator such as xterm or rxvt.
@ -224,3 +226,10 @@ INSTALLATION (OS-9 systems only,
See step 6 of the Unix installation instructions for details
on how to change the default installation directories.
=======================================================================
ACKNOWLEDGMENTS:
Some versions of the less distribution are packaged using
Info-ZIP's compression utility.
Info-ZIP's software is free and can be obtained as source
code or executables from various anonymous-ftp sites,
including ftp.uu.net:/pub/archiving/zip.

View File

@ -21,6 +21,8 @@
#include <windows.h>
#endif
typedef POSITION BLOCKNUM;
public int ignore_eoi;
/*
@ -29,34 +31,38 @@ public int ignore_eoi;
* in order from most- to least-recently used.
* The circular list is anchored by the file state "thisfile".
*/
#define LBUFSIZE 1024
#define LBUFSIZE 8192
struct buf {
struct buf *next, *prev; /* Must be first to match struct filestate */
long block;
struct buf *next, *prev;
struct buf *hnext, *hprev;
BLOCKNUM block;
unsigned int datasize;
unsigned char data[LBUFSIZE];
};
struct buflist {
/* -- Following members must match struct buf */
struct buf *buf_next, *buf_prev;
struct buf *buf_hnext, *buf_hprev;
};
/*
* The file state is maintained in a filestate structure.
* A pointer to the filestate is kept in the ifile structure.
*/
#define BUFHASH_SIZE 64
struct filestate {
/* -- Following members must match struct buf */
struct buf *buf_next, *buf_prev;
long buf_block;
/* -- End of struct buf copy */
struct buflist hashtbl[BUFHASH_SIZE];
int file;
int flags;
POSITION fpos;
int nbufs;
long block;
BLOCKNUM block;
unsigned int offset;
POSITION fsize;
};
#define END_OF_CHAIN ((struct buf *)thisfile)
#define ch_bufhead thisfile->buf_next
#define ch_buftail thisfile->buf_prev
#define ch_nbufs thisfile->nbufs
@ -67,6 +73,24 @@ struct filestate {
#define ch_flags thisfile->flags
#define ch_file thisfile->file
#define END_OF_CHAIN ((struct buf *)&thisfile->buf_next)
#define END_OF_HCHAIN(h) ((struct buf *)&thisfile->hashtbl[h])
#define BUFHASH(blk) ((blk) & (BUFHASH_SIZE-1))
#define FOR_BUFS_IN_CHAIN(h,bp) \
for (bp = thisfile->hashtbl[h].buf_hnext; \
bp != END_OF_HCHAIN(h); bp = bp->hnext)
#define HASH_RM(bp) \
(bp)->hnext->hprev = (bp)->hprev; \
(bp)->hprev->hnext = (bp)->hnext;
#define HASH_INS(bp,h) \
(bp)->hnext = thisfile->hashtbl[h].buf_hnext; \
(bp)->hprev = END_OF_HCHAIN(h); \
thisfile->hashtbl[h].buf_hnext->hprev = (bp); \
thisfile->hashtbl[h].buf_hnext = (bp);
static struct filestate *thisfile;
static int ch_ungotchar = -1;
@ -100,6 +124,7 @@ fch_get()
register struct buf *bp;
register int n;
register int slept;
register int h;
POSITION pos;
POSITION len;
@ -108,7 +133,9 @@ fch_get()
/*
* Look for a buffer holding the desired block.
*/
for (bp = ch_bufhead; bp != END_OF_CHAIN; bp = bp->next)
h = BUFHASH(ch_block);
FOR_BUFS_IN_CHAIN(h, bp)
{
if (bp->block == ch_block)
{
if (ch_offset >= bp->datasize)
@ -118,6 +145,7 @@ fch_get()
goto read_more;
goto found;
}
}
/*
* Block is not in a buffer.
* Take the least recently used buffer
@ -125,7 +153,7 @@ fch_get()
* If the LRU buffer has data in it,
* then maybe allocate a new buffer.
*/
if (ch_buftail == END_OF_CHAIN || ch_buftail->block != (long)(-1))
if (ch_buftail == END_OF_CHAIN || ch_buftail->block != -1)
{
/*
* There is no empty buffer to use.
@ -142,8 +170,10 @@ fch_get()
autobuf = OPT_OFF;
}
bp = ch_buftail;
HASH_RM(bp); /* Remove from old hash chain. */
bp->block = ch_block;
bp->datasize = 0;
HASH_INS(bp, h); /* Insert into new hash chain. */
read_more:
pos = (ch_block * LBUFSIZE) + bp->datasize;
@ -230,7 +260,11 @@ fch_get()
* Wait a while, then try again.
*/
if (!slept)
ierror("Waiting for data", NULL_PARG);
{
PARG parg;
parg.p_string = wait_message();
ierror("%s", &parg);
}
#if !MSDOS_COMPILER
sleep(1);
#else
@ -253,11 +287,16 @@ fch_get()
*/
bp->next->prev = bp->prev;
bp->prev->next = bp->next;
bp->next = ch_bufhead;
bp->prev = END_OF_CHAIN;
ch_bufhead->prev = bp;
ch_bufhead = bp;
/*
* Move to head of hash chain too.
*/
HASH_RM(bp);
HASH_INS(bp, h);
}
if (ch_offset >= bp->datasize)
@ -318,8 +357,8 @@ sync_logfile()
{
register struct buf *bp;
int warned = FALSE;
long block;
long nblocks;
BLOCKNUM block;
BLOCKNUM nblocks;
nblocks = (ch_fpos + LBUFSIZE - 1) / LBUFSIZE;
for (block = 0; block < nblocks; block++)
@ -352,13 +391,17 @@ sync_logfile()
*/
static int
buffered(block)
long block;
BLOCKNUM block;
{
register struct buf *bp;
register int h;
for (bp = ch_bufhead; bp != END_OF_CHAIN; bp = bp->next)
h = BUFHASH(block);
FOR_BUFS_IN_CHAIN(h, bp)
{
if (bp->block == block)
return (TRUE);
}
return (FALSE);
}
@ -370,7 +413,7 @@ buffered(block)
ch_seek(pos)
register POSITION pos;
{
long new_block;
BLOCKNUM new_block;
POSITION len;
len = ch_length();
@ -470,12 +513,10 @@ ch_length()
/*
* Return the current position in the file.
*/
#define tellpos(blk,off) ((POSITION)((((long)(blk)) * LBUFSIZE) + (off)))
public POSITION
ch_tell()
{
return (tellpos(ch_block, ch_offset));
return (ch_block * LBUFSIZE) + ch_offset;
}
/*
@ -570,7 +611,7 @@ ch_flush()
* Initialize all the buffers.
*/
for (bp = ch_bufhead; bp != END_OF_CHAIN; bp = bp->next)
bp->block = (long)(-1);
bp->block = -1;
/*
* Figure out the size of the file, if we can.
@ -626,14 +667,30 @@ ch_addbuf()
if (bp == NULL)
return (1);
ch_nbufs++;
bp->block = (long)(-1);
bp->block = -1;
bp->next = END_OF_CHAIN;
bp->prev = ch_buftail;
ch_buftail->next = bp;
ch_buftail = bp;
HASH_INS(bp, 0);
return (0);
}
/*
*
*/
static void
init_hashtbl()
{
register int h;
for (h = 0; h < BUFHASH_SIZE; h++)
{
thisfile->hashtbl[h].buf_hnext = END_OF_HCHAIN(h);
thisfile->hashtbl[h].buf_hprev = END_OF_HCHAIN(h);
}
}
/*
* Delete all buffers for this file.
*/
@ -650,6 +707,7 @@ ch_delbufs()
free(bp);
}
ch_nbufs = 0;
init_hashtbl();
}
/*
@ -693,7 +751,6 @@ ch_init(f, flags)
thisfile = (struct filestate *)
calloc(1, sizeof(struct filestate));
thisfile->buf_next = thisfile->buf_prev = END_OF_CHAIN;
thisfile->buf_block = (long)(-1);
thisfile->nbufs = 0;
thisfile->flags = 0;
thisfile->fpos = 0;
@ -702,6 +759,7 @@ ch_init(f, flags)
thisfile->file = -1;
thisfile->fsize = NULL_POSITION;
ch_flags = flags;
init_hashtbl();
/*
* Try to seek; set CH_CANSEEK if it works.
*/

View File

@ -32,16 +32,25 @@ struct charset {
char *desc;
} charsets[] = {
{ "ascii", NULL, "8bcccbcc18b95.b" },
{ "dos", NULL, "8bcccbcc12bc5b95.b." },
{ "dos", NULL, "8bcccbcc12bc5b223.b" },
{ "ebcdic", NULL, "5bc6bcc7bcc41b.9b7.9b5.b..8b6.10b6.b9.7b9.8b8.17b3.3b9.7b9.8b8.6b10.b.b.b." },
{ "IBM-1047", NULL, "4cbcbc3b9cbccbccbb4c6bcc5b3cbbc4bc4bccbc191.b" },
{ "iso8859", NULL, "8bcccbcc18b95.33b." },
{ "koi8-r", NULL, "8bcccbcc18b95.b128." },
{ "latin1", NULL, "8bcccbcc18b95.33b." },
{ "next", NULL, "8bcccbcc18b95.bb125.bb" },
{ "utf-8", &utf_mode, "8bcccbcc18b." },
{ NULL, NULL, NULL }
};
struct cs_alias {
char *name;
char *oname;
} cs_aliases[] = {
{ "latin1", "iso8859" },
{ "latin9", "iso8859" },
{ NULL, NULL }
};
#define IS_BINARY_CHAR 01
#define IS_CONTROL_CHAR 02
@ -126,10 +135,21 @@ icharset(name)
register char *name;
{
register struct charset *p;
register struct cs_alias *a;
if (name == NULL || *name == '\0')
return (0);
/* First see if the name is an alias. */
for (a = cs_aliases; a->name != NULL; a++)
{
if (strcmp(name, a->name) == 0)
{
name = a->oname;
break;
}
}
for (p = charsets; p->name != NULL; p++)
{
if (strcmp(name, p->name) == 0)
@ -241,12 +261,19 @@ init_charset()
* Use setlocale.
*/
ilocale();
#else
#if MSDOS_COMPILER
/*
* Default to "dos".
*/
(void) icharset("dos");
#else
/*
* Default to "latin1".
*/
(void) icharset("latin1");
#endif
#endif
}
/*
@ -286,8 +313,22 @@ prchar(c)
sprintf(buf, "%c", c);
else if (c == ESC)
sprintf(buf, "ESC");
else if (c < 128 && !control_char(c ^ 0100))
sprintf(buf, "^%c", c ^ 0100);
#if IS_EBCDIC_HOST
else if (!binary_char(c) && c < 64)
sprintf(buf, "^%c",
/*
* This array roughly inverts CONTROL() #defined in less.h,
* and should be kept in sync with CONTROL() and IBM-1047.
*/
"@ABC.I.?...KLMNO"
"PQRS.JH.XY.."
"\\]^_"
"......W[.....EFG"
"..V....D....TU.Z"[c]);
#else
else if (c < 128 && !control_char(c ^ 0100))
sprintf(buf, "^%c", c ^ 0100);
#endif
else
sprintf(buf, binfmt, c);
return (buf);

View File

@ -63,6 +63,8 @@
#define A_F_FOREVER 50
#define A_GOPOS 51
#define A_REMOVE_FILE 52
#define A_NEXT_TAG 53
#define A_PREV_TAG 54
#define A_INVALID 100
#define A_NOACTION 101
@ -103,6 +105,7 @@
#define EC_PEEK 01
#define EC_NOHISTORY 02
#define EC_NOCOMPLETE 04
#define EC_NORIGHTLEFT 010
/* Environment variable stuff */
#define EV_OK 01

View File

@ -155,7 +155,7 @@ cmd_repaint(old_cp)
for ( ; *cp != '\0'; cp++)
{
p = prchar(*cp);
if (cmd_col + strlen(p) >= sc_width)
if (cmd_col + (int)strlen(p) >= sc_width)
break;
putstr(p);
cmd_col += strlen(p);
@ -255,9 +255,9 @@ cmd_right()
return (CC_OK);
}
p = prchar(*cp);
if (cmd_col + strlen(p) >= sc_width)
if (cmd_col + (int)strlen(p) >= sc_width)
cmd_lshift();
else if (cmd_col + strlen(p) == sc_width - 1 && cp[1] != '\0')
else if (cmd_col + (int)strlen(p) == sc_width - 1 && cp[1] != '\0')
cmd_lshift();
cp++;
putstr(p);
@ -279,7 +279,7 @@ cmd_left()
return (CC_OK);
}
p = prchar(cp[-1]);
if (cmd_col < prompt_col + strlen(p))
if (cmd_col < prompt_col + (int)strlen(p))
cmd_rshift();
cp--;
cmd_col -= strlen(p);

View File

@ -14,6 +14,9 @@
*/
#include "less.h"
#if MSDOS_COMPILER==WIN32C
#include <windows.h>
#endif
#include "position.h"
#include "option.h"
#include "cmd.h"
@ -214,6 +217,8 @@ exec_mca()
if (secure)
break;
edit_list(cbuf);
/* If tag structure is loaded then clean it up. */
cleantags();
break;
#endif
#if SHELL_ESCAPE
@ -284,7 +289,7 @@ mca_char(c)
* Terminated by a non-digit.
*/
if ((c < '0' || c > '9') &&
editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE) == A_INVALID)
editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE|EC_NORIGHTLEFT) == A_INVALID)
{
/*
* Not part of the number.
@ -608,6 +613,13 @@ prompt()
quit(QUIT_OK);
#endif
#if MSDOS_COMPILER==WIN32C
/*
* In Win32, display the file name in the window title.
*/
if (!(ch_getflags() & CH_HELPFILE))
SetConsoleTitle(pr_expand("Less?f - %f.", 0));
#endif
/*
* Select the proper prompt and display it.
*/
@ -832,6 +844,7 @@ commands()
PARG parg;
IFILE old_ifile;
IFILE new_ifile;
char *tagfile;
search_type = SRCH_FORW;
wscroll = (sc_height + 1) / 2;
@ -1349,6 +1362,11 @@ commands()
/*
* Examine next file.
*/
if (ntags())
{
error("No next file", NULL_PARG);
break;
}
if (number <= 0)
number = 1;
if (edit_next(number))
@ -1365,6 +1383,11 @@ commands()
/*
* Examine previous file.
*/
if (ntags())
{
error("No previous file", NULL_PARG);
break;
}
if (number <= 0)
number = 1;
if (edit_prev(number))
@ -1374,6 +1397,40 @@ commands()
}
break;
case A_NEXT_TAG:
if (number <= 0)
number = 1;
tagfile = nexttag(number);
if (tagfile == NULL)
{
error("No next tag", NULL_PARG);
break;
}
if (edit(tagfile) == 0)
{
POSITION pos = tagsearch();
if (pos != NULL_POSITION)
jump_loc(pos, jump_sline);
}
break;
case A_PREV_TAG:
if (number <= 0)
number = 1;
tagfile = prevtag(number);
if (tagfile == NULL)
{
error("No previous tag", NULL_PARG);
break;
}
if (edit(tagfile) == 0)
{
POSITION pos = tagsearch();
if (pos != NULL_POSITION)
jump_loc(pos, jump_sline);
}
break;
case A_INDEX_FILE:
/*
* Examine a particular file.
@ -1502,7 +1559,9 @@ commands()
goto again;
case A_LSHIFT:
if (number <= 0)
if (number > 0)
shift_count = number;
else
number = (shift_count > 0) ?
shift_count : sc_width / 2;
if (number > hshift)
@ -1512,7 +1571,9 @@ commands()
break;
case A_RSHIFT:
if (number <= 0)
if (number > 0)
shift_count = number;
else
number = (shift_count > 0) ?
shift_count : sc_width / 2;
hshift += number;

411
contrib/less/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,11 @@ AC_ISC_POSIX
AC_PROG_GCC_TRADITIONAL
AC_PROG_INSTALL
dnl Check for compilation model.
dnl AC_SYS_LARGEFILE is not supported in all versions of autoconf.
dnl Remove the dnl comment on the next line to use large (64 bit) files.
dnl AC_SYS_LARGEFILE
dnl Checks for libraries.
AC_CHECK_LIB(xcurses, initscr, [have_xcurses=yes], [have_xcurses=no])
AC_CHECK_LIB(ncurses, initscr, [have_ncurses=yes], [have_ncurses=no])
@ -30,6 +35,9 @@ if test x`uname -s` = "xHP-UX" >/dev/null 2>&1; then
if test x`uname -r` = "xB.11.00" >/dev/null 2>&1; then
curses_broken=1
fi
if test x`uname -r` = "xB.11.11" >/dev/null 2>&1; then
curses_broken=1
fi
fi
if test $curses_broken = 0; then
@ -139,7 +147,7 @@ AC_TRY_COMPILE([#include <time.h>], [time_t t = 0;],
dnl Checks for functions and external variables.
AC_TYPE_SIGNAL
AC_CHECK_FUNCS(memcpy popen _setjmp sigprocmask sigsetmask stat strchr strstr system)
AC_CHECK_FUNCS(fsync memcpy popen _setjmp sigprocmask sigsetmask stat strchr strstr system)
dnl Some systems have termios.h but not the corresponding functions.
AC_CHECK_FUNC(tcgetattr, AC_DEFINE(HAVE_TERMIOS_FUNCS))

View File

@ -140,6 +140,8 @@ static unsigned char cmdtable[] =
CONTROL('X'),CONTROL('V'),0, A_EXAMINE,
':','n',0, A_NEXT_FILE,
':','p',0, A_PREV_FILE,
't',0, A_NEXT_TAG,
'T',0, A_PREV_TAG,
':','x',0, A_INDEX_FILE,
':','d',0, A_REMOVE_FILE,
'-',0, A_OPT_TOGGLE,
@ -292,6 +294,13 @@ init_cmds()
add_fcmd_table((char*)cmdtable, sizeof(cmdtable));
add_ecmd_table((char*)edittable, sizeof(edittable));
#if USERFILE
/*
* For backwards compatibility,
* try to add tables in the OLD system lesskey file.
*/
#ifdef BINDIR
add_hometable(NULL, BINDIR "/.sysless", 1);
#endif
/*
* Try to add the tables in the system lesskey file.
*/
@ -708,7 +717,7 @@ add_hometable(envname, def_filename, sysvar)
char *filename;
PARG parg;
if ((filename = lgetenv(envname)) != NULL)
if (envname != NULL && (filename = lgetenv(envname)) != NULL)
filename = save(filename);
else if (sysvar)
filename = save(def_filename);
@ -764,6 +773,16 @@ editchar(c, flags)
action = ecmd_decode(usercmd, &s);
} while (action == A_PREFIX);
if (flags & EC_NORIGHTLEFT)
{
switch (action)
{
case EC_RIGHT:
case EC_LEFT:
action = A_INVALID;
break;
}
}
#if CMD_HISTORY
if (flags & EC_NOHISTORY)
{

View File

@ -185,6 +185,7 @@
#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
#define TAGLINE_SIZE 512 /* Max size of line in tags file */
#define TABSTOP_MAX 32 /* Max number of custom tab stops */
/* Define to `long' if <sys/types.h> doesn't define. */
#if MSDOS_COMPILER==BORLANDC
@ -253,7 +254,7 @@
#define MUST_DEFINE_OSPEED 0
/* Define HAVE_LOCALE if you have locale.h and setlocale. */
#define HAVE_LOCALE 1
#define HAVE_LOCALE 0
/* Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr */
#define HAVE_TERMIOS_FUNCS 0

View File

@ -105,7 +105,7 @@
* (in the HOME directory).
*/
#define LESSKEYFILE ".less"
#define LESSKEYFILE_SYS SYSDIR "/.sysless"
#define LESSKEYFILE_SYS SYSDIR "/sysless"
#define DEF_LESSKEYINFILE ".lesskey"
@ -169,6 +169,7 @@
#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
#define TAGLINE_SIZE 512 /* Max size of line in tags file */
#define TABSTOP_MAX 32 /* Max number of custom tab stops */
/* Settings automatically determined by configure. */
@ -253,6 +254,9 @@
/* Define if you have the _setjmp function. */
#undef HAVE__SETJMP
/* Define if you have the fsync function. */
#undef HAVE_FSYNC
/* Define if you have the memcpy function. */
#undef HAVE_MEMCPY

View File

@ -104,7 +104,7 @@
* (in the HOME directory).
*/
#define LESSKEYFILE ".less"
#define LESSKEYFILE_SYS SYSDIR "/.sysless"
#define LESSKEYFILE_SYS SYSDIR "/sysless"
#define DEF_LESSKEYINFILE ".lesskey"
@ -168,5 +168,6 @@
#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
#define TAGLINE_SIZE 512 /* Max size of line in tags file */
#define TABSTOP_MAX 32 /* Max number of custom tab stops */
/* Settings automatically determined by configure. */

View File

@ -60,7 +60,7 @@
* EDIT_PGM is the name of the (default) editor to be invoked.
*/
#define EDITOR (!SECURE)
#define EDIT_PGM "me"
#define EDIT_PGM "vi"
/*
* TAGS is 1 if you wish to support tag files.
@ -112,7 +112,7 @@
* (in the HOME directory).
*/
#define LESSKEYFILE "less.ini"
#define LESSKEYFILE_SYS "\\sysless.ini"
#define LESSKEYFILE_SYS "C:\\sysless.ini"
#define DEF_LESSKEYINFILE "lesskey.ini"
@ -166,6 +166,7 @@
#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
#define TAGLINE_SIZE 512 /* Max size of line in tags file */
#define TABSTOP_MAX 32 /* Max number of custom tab stops */
/* Define to `long' if <sys/types.h> doesn't define. */
/* #define off_t long */
@ -200,7 +201,7 @@
#define HAVE_CONST 1
/* Define HAVE_TIME_T if your system supports the "time_t" type. */
#define HAVE_TIME_T 0
#define HAVE_TIME_T 1
/* Define HAVE_STRERROR if you have the strerror() function. */
#define HAVE_STRERROR 1
@ -212,22 +213,22 @@
/* Define MUST_DEFINE_ERRNO if you have errno but it is not define
* in errno.h */
#define HAVE_ERRNO 1
#define MUST_DEFINE_ERRNO 1
/* #undef MUST_DEFINE_ERRNO */
/* Define HAVE_SYS_ERRLIST if you have the sys_errlist[] variable */
#define HAVE_SYS_ERRLIST 1
/* Define HAVE_OSPEED if your termcap library has the ospeed variable */
#define HAVE_OSPEED 0
#define HAVE_OSPEED 1
/* Define MUST_DEFINE_OSPEED if you have ospeed but it is not defined
* in termcap.h. */
#define MUST_DEFINE_OSPEED 0
/* Define HAVE_LOCALE if you have locale.h and setlocale. */
#define HAVE_LOCALE 0
#define HAVE_LOCALE 1
/* Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr */
#define HAVE_TERMIOS_FUNCS 0
#define HAVE_TERMIOS_FUNCS 1
/* Define HAVE_UPPER_LOWER if you have isupper, islower, toupper, tolower */
#define HAVE_UPPER_LOWER 1
@ -239,17 +240,17 @@
#define HAVE_MEMCPY 1
/* Define if you have the popen function. */
#define HAVE_POPEN 0
#define HAVE_POPEN 1
/* Define if you have the sigsetmask function. */
#define HAVE_SIGSETMASK 0
/* Define if you have the sigprocmask function. */
#define HAVE_SIGPROCMASK 0
#define HAVE_SIGPROCMASK 1
/* Define if you have the sigset_t type and sigemptyset macro */
#define HAVE_SIGSET_T 0
#define HAVE_SIGEMPTYSET 0
#define HAVE_SIGSET_T 1
#define HAVE_SIGEMPTYSET 1
/* Define if you have the stat function. */
#define HAVE_STAT 1
@ -257,6 +258,9 @@
/* Define if you have the strchr function. */
#define HAVE_STRCHR 1
/* Define if you have the strstr function. */
#define HAVE_STRSTR 1
/* Define if you have the system function. */
#define HAVE_SYSTEM 1
@ -264,13 +268,13 @@
#define HAVE_CTYPE_H 1
/* Define if you have the <errno.h> header file. */
#define HAVE_ERRNO_H 0
#define HAVE_ERRNO_H 1
/* Define if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 0
#define HAVE_LIMITS_H 1
/* Define if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
@ -282,7 +286,7 @@
#define HAVE_STRING_H 1
/* Define if you have the <sys/ioctl.h> header file. */
#define HAVE_SYS_IOCTL_H 0
#define HAVE_SYS_IOCTL_H 1
/* Define if you have the <sys/ptem.h> header file. */
#define HAVE_SYS_PTEM_H 0
@ -291,13 +295,13 @@
#define HAVE_SYS_STREAM_H 0
/* Define if you have the <termcap.h> header file. */
#define HAVE_TERMCAP_H 0
#define HAVE_TERMCAP_H 1
/* Define if you have the <termio.h> header file. */
#define HAVE_TERMIO_H 0
#define HAVE_TERMIO_H 1
/* Define if you have the <termios.h> header file. */
#define HAVE_TERMIOS_H 0
#define HAVE_TERMIOS_H 1
/* Define if you have the <time.h> header file. */
#define HAVE_TIME_H 1

View File

@ -179,6 +179,7 @@
#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
#define TAGLINE_SIZE 512 /* Max size of line in tags file */
#define TABSTOP_MAX 32 /* Max number of custom tab stops */
/* Define to `long' if <sys/types.h> doesn't define. */
#define off_t long

View File

@ -167,6 +167,7 @@
#define TERMBUF_SIZE 2048 /* Termcap buffer for tgetent */
#define TERMSBUF_SIZE 1024 /* Buffer to hold termcap strings */
#define TAGLINE_SIZE 512 /* Max size of line in tags file */
#define TABSTOP_MAX 32 /* Max number of custom tab stops */
/* Define to `long' if <sys/types.h> doesn't define. */
/* #define off_t long */
@ -225,7 +226,7 @@
#define MUST_DEFINE_OSPEED 0
/* Define HAVE_LOCALE if you have locale.h and setlocale. */
#define HAVE_LOCALE 1
#define HAVE_LOCALE 0
/* Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr */
#define HAVE_TERMIOS_FUNCS 0
@ -240,7 +241,7 @@
#define HAVE_MEMCPY 1
/* Define if you have the popen function. */
#define HAVE_POPEN 0
#define HAVE_POPEN 1
/* Define if you have the sigsetmask function. */
#define HAVE_SIGSETMASK 0

View File

@ -24,7 +24,6 @@
#if MSDOS_COMPILER==DJGPPC
#include <glob.h>
#include <dir.h>
#include <limits.h>
#define _MAX_PATH PATH_MAX
#endif
#endif
@ -34,6 +33,9 @@
#include <modes.h>
#endif
#endif
#if OS2
#include <signal.h>
#endif
#if HAVE_STAT
#include <sys/stat.h>
@ -878,7 +880,16 @@ close_altfile(altfilename, filename, pipefd)
if (secure)
return;
if (pipefd != NULL)
{
#if OS2
/*
* The pclose function of OS/2 emx sometimes fails.
* Send SIGINT to the piped process before closing it.
*/
kill(((FILE*)pipefd)->_pid, SIGINT);
#endif
pclose((FILE*) pipefd);
}
if ((lessclose = lgetenv("LESSCLOSE")) == NULL)
return;
gfilename = esc_metachars(filename);

View File

@ -12,6 +12,7 @@
public void home ();
public void add_line ();
public void remove_top ();
public void win32_scroll_up ();
public void lower_left ();
public void check_winch ();
public void goto_line ();
@ -142,6 +143,7 @@
public void init_line ();
public void prewind ();
public void plinenum ();
public int is_ansi_end ();
public int pappend ();
public void pdone ();
public int gline ();
@ -175,6 +177,7 @@
public void opt_i ();
public void opt__V ();
public void opt_D ();
public void opt_x ();
public void opt_quote ();
public void opt_query ();
public int get_swindow ();
@ -195,7 +198,6 @@
public int percentage ();
public POSITION percent_pos ();
public int os9_signal ();
public int isatty ();
public void put_line ();
public void flush ();
public int putchr ();
@ -218,6 +220,7 @@
public char * pr_expand ();
public char * eq_message ();
public char * pr_string ();
public char * wait_message ();
public void repaint_hilite ();
public void clear_attn ();
public void undo_search ();
@ -231,9 +234,15 @@
public RETSIGTYPE winch ();
public void init_signals ();
public void psignals ();
public void cleantags ();
public int gettagtype ();
public void findtag ();
public int edit_tagfile ();
public POSITION tagsearch ();
public char * nexttag ();
public char * prevtag ();
public int ntags ();
public int curr_tag ();
public int edit_tagfile ();
public void open_getchr ();
public void close_getchr ();
public int getchr ();

View File

@ -22,8 +22,8 @@ constant char helpdata[] = {
' ',' ','E','S','C','-','S','P','A','C','E',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','w','i','n','d','o','w',',',' ','b','u','t',' ','d','o','n','\'','t',' ','s','t','o','p',' ','a','t',' ','e','n','d','-','o','f','-','f','i','l','e','.','\n',
' ',' ','d',' ',' ','^','D',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','h','a','l','f','-','w','i','n','d','o','w',' ','(','a','n','d',' ','s','e','t',' ','h','a','l','f','-','w','i','n','d','o','w',' ','t','o',' ','_','\b','N',')','.','\n',
' ',' ','u',' ',' ','^','U',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','h','a','l','f','-','w','i','n','d','o','w',' ','(','a','n','d',' ','s','e','t',' ','h','a','l','f','-','w','i','n','d','o','w',' ','t','o',' ','_','\b','N',')','.','\n',
' ',' ','E','S','C','-','(',' ',' ','R','i','g','h','t','A','r','r','o','w',' ','*',' ',' ','L','e','f','t',' ',' ','8',' ','c','h','a','r','a','c','t','e','r',' ','p','o','s','i','t','i','o','n','s',' ','(','o','r',' ','_','\b','N',' ','p','o','s','i','t','i','o','n','s',')','.','\n',
' ',' ','E','S','C','-',')',' ',' ','L','e','f','t','A','r','r','o','w',' ',' ','*',' ',' ','R','i','g','h','t',' ','8',' ','c','h','a','r','a','c','t','e','r',' ','p','o','s','i','t','i','o','n','s',' ','(','o','r',' ','_','\b','N',' ','p','o','s','i','t','i','o','n','s',')','.','\n',
' ',' ','E','S','C','-','(',' ',' ','R','i','g','h','t','A','r','r','o','w',' ','*',' ',' ','L','e','f','t',' ',' ','o','n','e',' ','h','a','l','f',' ','s','c','r','e','e','n',' ','w','i','d','t','h',' ','(','o','r',' ','_','\b','N',' ','p','o','s','i','t','i','o','n','s',')','.','\n',
' ',' ','E','S','C','-',')',' ',' ','L','e','f','t','A','r','r','o','w',' ',' ','*',' ',' ','R','i','g','h','t',' ','o','n','e',' ','h','a','l','f',' ','s','c','r','e','e','n',' ','w','i','d','t','h',' ','(','o','r',' ','_','\b','N',' ','p','o','s','i','t','i','o','n','s',')','.','\n',
' ',' ','F',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','o','r','w','a','r','d',' ','f','o','r','e','v','e','r',';',' ','l','i','k','e',' ','"','t','a','i','l',' ','-','f','"','.','\n',
' ',' ','r',' ',' ','^','R',' ',' ','^','L',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','s','c','r','e','e','n','.','\n',
' ',' ','R',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','s','c','r','e','e','n',',',' ','d','i','s','c','a','r','d','i','n','g',' ','b','u','f','f','e','r','e','d',' ','i','n','p','u','t','.','\n',
@ -55,6 +55,8 @@ constant char helpdata[] = {
' ',' ','g',' ',' ','<',' ',' ','E','S','C','-','<',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','f','i','r','s','t',' ','l','i','n','e',' ','i','n',' ','f','i','l','e',' ','(','o','r',' ','l','i','n','e',' ','_','\b','N',')','.','\n',
' ',' ','G',' ',' ','>',' ',' ','E','S','C','-','>',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','l','a','s','t',' ','l','i','n','e',' ','i','n',' ','f','i','l','e',' ','(','o','r',' ','l','i','n','e',' ','_','\b','N',')','.','\n',
' ',' ','p',' ',' ','%',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','b','e','g','i','n','n','i','n','g',' ','o','f',' ','f','i','l','e',' ','(','o','r',' ','_','\b','N',' ','p','e','r','c','e','n','t',' ','i','n','t','o',' ','f','i','l','e',')','.','\n',
' ',' ','t',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','n','e','x','t',' ','t','a','g','.','\n',
' ',' ','T',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','G','o',' ','t','o',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','p','r','e','v','i','o','u','s',' ','t','a','g','.','\n',
' ',' ','{',' ',' ','(',' ',' ','[',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','i','n','d',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','}',' ',')',' ',']','.','\n',
' ',' ','}',' ',' ',')',' ',' ',']',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','i','n','d',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','{',' ','(',' ','[','.','\n',
' ',' ','E','S','C','-','^','F',' ','_','\b','<','_','\b','c','_','\b','1','_','\b','>',' ','_','\b','<','_','\b','c','_','\b','2','_','\b','>',' ',' ','*',' ',' ','F','i','n','d',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','_','\b','<','_','\b','c','_','\b','2','_','\b','>','.','\n',
@ -176,10 +178,12 @@ constant char helpdata[] = {
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','f','i','r','s','t',' ','n','e','w',' ','l','i','n','e',' ','a','f','t','e','r',' ','f','o','r','w','a','r','d','-','s','c','r','e','e','n','.','\n',
' ',' ','-','W',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','H','I','L','I','T','E','-','U','N','R','E','A','D','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','f','i','r','s','t',' ','n','e','w',' ','l','i','n','e',' ','a','f','t','e','r',' ','a','n','y',' ','f','o','r','w','a','r','d',' ','m','o','v','e','m','e','n','t','.','\n',
' ',' ','-','x',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','t','a','b','s','=','[','_','\b','N',']','\n',
' ',' ','-','x',' ','[','_','\b','N','[',',','.','.','.',']',']',' ',' ','-','-','t','a','b','s','=','[','_','\b','N','[',',','.','.','.',']',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','t','a','b',' ','s','t','o','p','s','.','\n',
' ',' ','-','X',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','n','o','-','i','n','i','t','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','u','s','e',' ','t','e','r','m','c','a','p',' ','i','n','i','t','/','d','e','i','n','i','t',' ','s','t','r','i','n','g','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','-','-','n','o','-','k','e','y','p','a','d','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','u','s','e',' ','t','e','r','m','c','a','p',' ','k','e','y','p','a','d',' ','i','n','i','t','/','d','e','i','n','i','t',' ','s','t','r','i','n','g','s','.','\n',
' ',' ','-','y',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','m','a','x','-','f','o','r','w','-','s','c','r','o','l','l','=','[','_','\b','N',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','o','r','w','a','r','d',' ','s','c','r','o','l','l',' ','l','i','m','i','t','.','\n',
' ',' ','-','z',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','w','i','n','d','o','w','=','[','_','\b','N',']','\n',

View File

@ -70,6 +70,9 @@
#if HAVE_CTYPE_H
#include <ctype.h>
#endif
#if HAVE_LIMITS_H
#include <limits.h>
#endif
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
@ -80,7 +83,7 @@
#include <modes.h>
#include <strings.h>
#endif
#if MSDOS_COMPILER==WIN32C
#if MSDOS_COMPILER==WIN32C || OS2
#include <io.h>
#endif
#if MSDOS_COMPILER==DJGPPC
@ -136,13 +139,21 @@ void free();
#define BAD_LSEEK ((off_t)-1)
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
/*
* Upper bound on the string length of an integer converted to string.
* 302 / 1000 is ceil (log10 (2.0)). Subtract 1 for the sign bit;
* add 1 for integer division truncation; add 1 more for a minus sign.
*/
#define INT_STRLEN_BOUND(t) ((sizeof(t) * CHAR_BIT - 1) * 302 / 1000 + 1 + 1)
/*
* Special types and constants.
*/
typedef off_t POSITION;
#define PR_POSITION "%ld"
#define MAX_PRINT_POSITION 20
#define MAX_PRINT_INT 10
#define NULL_POSITION ((POSITION)(-1))
@ -179,7 +190,7 @@ typedef off_t POSITION;
#if MSDOS_COMPILER==MSOFTC
#define SET_BINARY(f) _setmode(f, _O_BINARY);
#else
#if MSDOS_COMPILER
#if MSDOS_COMPILER || OS2
#define SET_BINARY(f) setmode(f, O_BINARY)
#else
#define SET_BINARY(f)
@ -283,6 +294,10 @@ struct textlist
#define AT_INVIS (4)
#define AT_STANDOUT (5)
#if '0' == 240
#define IS_EBCDIC_HOST 1
#endif
#if IS_EBCDIC_HOST
/*
* Long definition for EBCDIC.

View File

@ -19,8 +19,8 @@
ESC-SPACE * Forward one window, but don't stop at end-of-file.
d ^D * Forward one half-window (and set half-window to _N).
u ^U * Backward one half-window (and set half-window to _N).
ESC-( RightArrow * Left 8 character positions (or _N positions).
ESC-) LeftArrow * Right 8 character positions (or _N positions).
ESC-( RightArrow * Left one half screen width (or _N positions).
ESC-) LeftArrow * Right one half screen width (or _N positions).
F Forward forever; like "tail -f".
r ^R ^L Repaint screen.
R Repaint screen, discarding buffered input.
@ -52,6 +52,8 @@
g < ESC-< * Go to first line in file (or line _N).
G > ESC-> * Go to last line in file (or line _N).
p % * Go to beginning of file (or _N percent into file).
t * Go to the (_N-th) next tag.
T * Go to the (_N-th) previous tag.
{ ( [ * Find close bracket } ) ].
} ) ] * Find open bracket { ( [.
ESC-^F _<_c_1_> _<_c_2_> * Find close bracket _<_c_2_>.
@ -173,10 +175,12 @@
Highlight first new line after forward-screen.
-W ........ --HILITE-UNREAD
Highlight first new line after any forward movement.
-x [_N] .... --tabs=[_N]
-x [_N[,...]] --tabs=[_N[,...]]
Set tab stops.
-X ........ --no-init
Don't use termcap init/deinit strings.
--no-keypad
Don't use termcap keypad init/deinit strings.
-y [_N] .... --max-forw-scroll=[_N]
Forward scroll limit.
-z [_N] .... --window=[_N]

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
.TH LESS 1 "Version 358: 08 Jul 2000"
.TH LESS 1 "Version 371: 26 Dec 2001"
.SH NAME
less \- opposite of more
.SH SYNOPSIS
@ -10,13 +10,13 @@ less \- opposite of more
.br
.B "less --version"
.br
.B "less [-[+]aBcCdeEfgGiImMnNqQrsSuUVwX]"
.B "less [-[+]aBcCdeEfFgGiIJmMnNqQrRsSuUVwWX]"
.br
.B " [-b \fIbufs\fP] [-h \fIlines\fP] [-j \fIline\fP] [-k \fIkeyfile\fP]"
.br
.B " [-{oO} \fIlogfile\fP] [-p \fIpattern\fP] [-P \fIprompt\fP] [-t \fItag\fP]"
.br
.B " [-T \fItagsfile\fP] [-x \fItab\fP] [-y \fIlines\fP] [-[z] \fIlines\fP]"
.B " [-T \fItagsfile\fP] [-x \fItab\fP,...] [-y \fIlines\fP] [-[z] \fIlines\fP]"
.br
.B " [+[+]\fIcmd\fP] [--] [\fIfilename\fP]..."
.br
@ -88,14 +88,15 @@ subsequent d and u commands.
.IP "ESC-) or RIGHTARROW"
Scroll horizontally right N characters, default half the screen width
(see the -# option).
If a number N is specified, it becomes the default for future RIGHTARROW
and LEFTARROW commands.
While the text is scrolled, it acts as though the -S option
(chop lines) were in effect.
Note that if you wish to enter a number N, you must use ESC-), not RIGHTARROW,
because the arrow is taken to be a line editing command
(see the LINE EDITING section).
.IP "ESC-( or LEFTARROW"
Scroll horizontally left N characters, default half the screen width
(see the -# option).
If a number N is specified, it becomes the default for future RIGHTARROW
and LEFTARROW commands.
.IP "r or ^R or ^L"
Repaint the screen.
.IP R
@ -287,6 +288,11 @@ Examine the first file in the command line list.
If a number N is specified, the N-th file in the list is examined.
.IP ":d"
Remove the current file from the list of files.
.IP "t"
Go to the next tag, if there were more than one matches for the current tag.
See the \-t option for more details about tags.
.IP "T"
Go to the previous tag, if there were more than one matches for the current tag.
.IP "= or ^G or :f"
Prints some information about the file being viewed,
including its name
@ -554,7 +560,8 @@ fourth line on the screen, so searches begin at the fifth line
on the screen.
.IP "-J or --status-column"
Displays a status column at the left edge of the screen.
The status column is used only if the -w or -W option is in effect.
The status column shows the lines that matched the current search.
The status column is also used if the -w or -W option is in effect.
.IP "-k\fIfilename\fP or --lesskey-file=\fIfilename\fP"
Causes
.I less
@ -634,6 +641,7 @@ to that string.
-PM changes the long (-M) prompt.
-Ph changes the prompt for the help screen.
-P= changes the message printed by the = command.
-Pw changes the message printed while waiting for data (in the F command).
All prompt strings consist of a sequence of
letters and special escape sequences.
See the section on PROMPTS for more details.
@ -690,11 +698,17 @@ on the next line.
.IP "-t\fItag\fP or --tag=\fItag\fP"
The -t option, followed immediately by a TAG,
will edit the file containing that tag.
For this to work, there must be a file called "tags" in the
current directory, which was previously built by the
For this to work, tag information must be available;
for example, there may be a file in the current directory called "tags",
which was previously built by
.I ctags
(1) command.
This option may also be specified from within
(1) or an equivalent command.
If the environment variable LESSGLOBALTAGS is set, it is taken to be
the name of a command compatible with
.I global
(1), and that command is executed to find the tag.
(See http://www.gnu.org/software/global/global.html).
The -t option may also be specified from within
.I less
(using the \- command) as a way of examining a new file.
The command ":t" is equivalent to specifying -t from within
@ -738,14 +752,24 @@ in which case only the status column is highlighted.
.IP "-W or --HILITE-UNREAD"
Like -w, but temporarily highlights the first new line after any
forward movement command larger than one line.
.IP "-x\fIn\fP or --tabs=\fIn\fP"
Sets tab stops every \fIn\fP positions.
.IP "-x\fIn\fP,... or --tabs=\fIn\fP,..."
Sets tab stops.
If only one \fIn\fP is specified, tab stops are set at multiples of \fIn\fP.
If multiple values separated by commas are specified, tab stops
are set at those positions, and then continue with the same spacing as the
last two.
For example, \fI-x9,17\fP will set tabs at positions 9, 17, 25, 33, etc.
The default for \fIn\fP is 8.
.IP "-X or --no-init"
Disables sending the termcap initialization and deinitialization strings
to the terminal.
This is sometimes desirable if the deinitialization string does
something unnecessary, like clearing the screen.
.IP "--no-keypad"
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.
.IP "-y\fIn\fP or --max-forw-scroll=\fIn\fP"
Specifies a maximum number of lines to scroll forward.
If it is necessary to scroll forward more than \fIn\fP lines,
@ -864,7 +888,7 @@ Like, TAB, but cycles in the reverse direction thru the matching filenames.
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).
.IP "^U (Unix) or ESC (MS-DOS)"
.IP "^U (Unix and OS/2) or ESC (MS-DOS)"
Delete the entire command line,
or cancel the command if the command line is empty.
If you have changed your line-kill character in Unix to something
@ -918,11 +942,11 @@ uses that as the name of the system-wide lesskey file.
Otherwise,
.I less
looks in a standard place for the system-wide lesskey file:
On Unix systems, the system-wide lesskey file is /usr/local/bin/.sysless.
On Unix systems, the system-wide lesskey file is /usr/local/etc/sysless.
(However, if
.I less
was built with a different binary directory than /usr/local/bin,
that directory is where the .sysless file is found.)
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:\\_sysless.
On OS/2 systems, the system-wide lesskey file is c:\\sysless.ini.
@ -1078,10 +1102,17 @@ This is the same as ASCII, except characters between 160 and 255 are
treated as normal characters.
.IP latin1
Same as iso8859.
.IP latin9
Same as iso8859.
.IP dos
Selects a character set appropriate for MS-DOS.
.IP ebcdic
Selects an EBCDIC character set.
.IP IBM-1047
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.
.IP koi8-r
Selects a Russian character set.
.IP next
@ -1089,11 +1120,6 @@ Selects a character set appropriate for NeXT computers.
.IP utf-8
Selects the UTF-8 encoding of the ISO 10646 character set.
.PP
If the LESSCHARSET environment variable is not set,
the default character set is latin1.
However, if the string "UTF-8" is found in the LC_ALL, LC_CTYPE or LANG
environment variables, then the default character set is utf-8 instead.
.PP
In special cases, it may be desired to tailor
.I less
to use a character set other than the ones definable by LESSCHARSET.
@ -1121,6 +1147,9 @@ to each of the possible values for LESSCHARSET:
ebcdic 5bc6bcc7bcc41b.9b7.9b5.b..8b6.10b6.b9.7b
.br
\ \ \ \ \ \ 9.8b8.17b3.3b9.7b9.8b8.6b10.b.b.b.
.br
IBM-1047 4cbcbc3b9cbccbccbb4c6bcc5b3cbbc4bc4bccbc
\ \ \ \ \ \ 191.b
.br
iso8859 8bcccbcc18b95.33b.
.br
@ -1130,13 +1159,21 @@ to each of the possible values for LESSCHARSET:
.br
next\ \ 8bcccbcc18b95.bb125.bb
.PP
If neither LESSCHARSET nor LESSCHARDEF is set,
but your system supports the
If neither LESSCHARSET nor LESSCHARDEF is set,
but the string "UTF-8" is found in the LC_ALL, LC_TYPE or LANG
environment variables, then the default character set is utf-8.
.PP
If that string is not found, but your system supports the
.I setlocale
interface,
.I less
will use setlocale to determine the character set.
setlocale is controlled by setting the LANG or LC_CTYPE environment variables.
setlocale is controlled by setting the LANG or LC_CTYPE environment
variables.
.PP
Finally, if the
.I setlocale
interface is also not available, the default character set is latin1.
.PP
Control and binary characters are displayed in standout (reverse video).
Each such character is displayed in caret notation if possible
@ -1380,7 +1417,8 @@ LINES and COLUMNS environment variables.)
.IP EDITOR
The name of the editor (used for the v command).
.IP HOME
Name of the user's home directory (used to find a lesskey file on Unix systems).
Name of the user's home directory
(used to find a lesskey file on Unix and OS/2 systems).
.IP "HOMEDRIVE, HOMEPATH"
Concatenation of the HOMEDRIVE and HOMEPATH environment variables is
the name of the user's home directory if the HOME variable is not set
@ -1413,6 +1451,11 @@ in filenames on Unix systems.
.IP LESSEDIT
Editor prototype string (used for the v command).
See discussion under PROMPTS.
.IP LESSGLOBALTAGS
Name of the command used by the -t option to find global tags.
Normally should be set to "global" if your system has the
.I global
(1) command. If not set, global tags are not used.
.IP LESSKEY
Name of the default lesskey(1) file.
.IP LESSKEY_SYSTEM
@ -1472,6 +1515,11 @@ more text than the matching string may be highlighted.
(This problem does not occur when less is compiled to use the POSIX
regular expression package.)
.PP
When viewing text containing ANSI color escape sequences using the -R option,
searching will not find text containing an embedded escape sequence.
Also, search highlighting may change the color of some of the text
which follows the highlighted text.
.PP
On some systems,
.I setlocale
claims that ASCII characters 0 thru 31 are control characters
@ -1482,11 +1530,11 @@ to treat some binary files as ordinary, non-binary files.
To workaround this problem, set the environment variable
LESSCHARSET to "ascii" (or whatever character set is appropriate).
.PP
See http://www.flash.net/~marknu/less for the latest list of known bugs in this
See http://www.greenwoodsoftware.com/less for the latest list of known bugs in this
version of less.
.SH COPYRIGHT
Copyright (C) 2000 Mark Nudelman
Copyright (C) 2001 Mark Nudelman
.PP
less is part of the GNU project and is free software.
You can redistribute it and/or modify it
@ -1509,7 +1557,8 @@ See the GNU General Public License for more details.
.SH AUTHOR
.PP
Mark Nudelman <marknu@flash.net>
Mark Nudelman <markn@greenwoodsoftware.com>
.br
Send bug reports or comments to the above address or to bug-less@gnu.org.
.br
For more information, see the less homepage at http://www.greenwoodsoftware.com/less.

View File

@ -126,11 +126,14 @@ struct cmdname cmdnames[] =
"invalid", A_UINVALID,
"left-scroll", A_LSHIFT,
"next-file", A_NEXT_FILE,
"next-tag", A_NEXT_TAG,
"noaction", A_NOACTION,
"percent", A_PERCENT,
"pipe", A_PIPE,
"prev-file", A_PREV_FILE,
"prev-tag", A_PREV_TAG,
"quit", A_QUIT,
"remove-file", A_REMOVE_FILE,
"repaint", A_REPAINT,
"repaint-flush", A_FREPAINT,
"repeat-search", A_AGAIN_SEARCH,
@ -411,6 +414,10 @@ tstr(pp)
case 'h': ch = SK_HOME; break;
case 'e': ch = SK_END; break;
case 'x': ch = SK_DELETE; break;
default:
error("illegal char after \\k");
*pp = p+1;
return ("");
}
*pp = p+1;
buf[0] = SK_SPECIAL_KEY;

View File

@ -61,7 +61,7 @@ CCOOMMMMAANNDD SSEECCTTIIOONN
Version 358: 08 Jul 2000 1
Version 371: 26 Dec 2001 1
@ -84,7 +84,7 @@ LESSKEY(1) LESSKEY(1)
_s_t_r_i_n_g may appear literally, or be prefixed by a caret to
indicate a control key. A backslash followed by one to
three octal digits may be used to specify a character by
its octal value. A backslash followed by certain charac-
its octal value. A backslash followed by certain charac­
ters specifies input characters as follows:
\b BACKSPACE
@ -127,7 +127,7 @@ LESSKEY(1) LESSKEY(1)
Version 358: 08 Jul 2000 2
Version 371: 26 Dec 2001 2
@ -144,7 +144,7 @@ LESSKEY(1) LESSKEY(1)
EEXXAAMMPPLLEE
The following input file describes the set of default com-
The following input file describes the set of default com­
mand keys used by less:
#command
@ -186,14 +186,14 @@ EEXXAAMMPPLLEE
^L repaint
\eu undo-hilite
g goto-line
\kh goto-line
< goto-line
\e< goto-line
p percent
% percent
Version 358: 08 Jul 2000 3
Version 371: 26 Dec 2001 3
@ -202,6 +202,7 @@ EEXXAAMMPPLLEE
LESSKEY(1) LESSKEY(1)
% percent
\e[ left-scroll
\e] right-scroll
\e( left-scroll
@ -217,6 +218,7 @@ LESSKEY(1) LESSKEY(1)
G goto-end
\e> goto-end
> goto-end
\ke goto-end
= status
^G status
:f status
@ -236,7 +238,10 @@ LESSKEY(1) LESSKEY(1)
^X^V examine
:n next-file
:p prev-file
t next-tag
T prev-tag
:x index-file
:d remove-file
- toggle-option
:t toggle-option t
s toggle-option o
@ -251,15 +256,10 @@ LESSKEY(1) LESSKEY(1)
0 digit
1 digit
2 digit
3 digit
4 digit
5 digit
6 digit
7 digit
Version 358: 08 Jul 2000 4
Version 371: 26 Dec 2001 4
@ -268,6 +268,11 @@ LESSKEY(1) LESSKEY(1)
LESSKEY(1) LESSKEY(1)
3 digit
4 digit
5 digit
6 digit
7 digit
8 digit
9 digit
q quit
@ -295,7 +300,7 @@ PPRREECCEEDDEENNCCEE
file.
Be aware that #stop can be dangerous. Since all default
commands are disabled, you must provide sufficient com-
commands are disabled, you must provide sufficient com­
mands before the #stop line to enable all necessary
actions. For example, failure to provide a "quit" command
can lead to frustration.
@ -306,9 +311,9 @@ LLIINNEE EEDDIITTIINNGG SSEECCTTIIOONN
#line-edit
This section specifies new key bindings for the line edit-
This section specifies new key bindings for the line edit­
ing commands, in a manner similar to the way key bindings
for ordinary commands are specified in the #command sec-
for ordinary commands are specified in the #command sec­
tion. The line-editing section consists of a list of keys
and actions, one per line as in the example below.
@ -317,15 +322,10 @@ EEXXAAMMPPLLEE
The following input file describes the set of default
line-editing keys used by less:
#line-edit
\t forw-complete
\17 back-complete
\e\t back-complete
^L expand
Version 358: 08 Jul 2000 5
Version 371: 26 Dec 2001 5
@ -334,6 +334,11 @@ EEXXAAMMPPLLEE
LESSKEY(1) LESSKEY(1)
#line-edit
\t forw-complete
\17 back-complete
\e\t back-complete
^L expand
^V literal
^A literal
\el right
@ -366,7 +371,7 @@ LLEESSSS EENNVVIIRROONNMMEENNTT VVAARRIIAABBLLEESS
#env
Following this line is a list of environment variable
assignments. Each line consists of an environment vari-
assignments. Each line consists of an environment vari­
able name, an equals sign (=) and the value to be assigned
to the environment variable. White space before and after
the equals sign is ignored. Variables assigned in this
@ -383,15 +388,10 @@ EEXXAAMMPPLLEE
The following input file sets the -i option whenever _l_e_s_s
is run, and specifies the character set to be "latin1":
#env
LESS = -i
LESSCHARSET = latin1
Version 358: 08 Jul 2000 6
Version 371: 26 Dec 2001 6
@ -400,12 +400,18 @@ EEXXAAMMPPLLEE
LESSKEY(1) LESSKEY(1)
#env
LESS = -i
LESSCHARSET = latin1
SSEEEE AALLSSOO
less(1)
WWAARRNNIINNGGSS
It is not possible to specify special keys, such as upar-
It is not possible to specify special keys, such as upar­
row, in a keyboard-independent manner. The only way to
specify such keys is to specify the escape sequence which
a particular keyboard sends when such a keys is pressed.
@ -426,8 +432,8 @@ CCOOPPYYRRIIGGHHTT
any later version.
lesskey is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied war-
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PUR-
but WITHOUT ANY WARRANTY; without even the implied war­
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PUR­
POSE. See the GNU General Public License for more
details.
@ -438,7 +444,7 @@ CCOOPPYYRRIIGGHHTT
AAUUTTHHOORR
Mark Nudelman <marknu@flash.net>
Mark Nudelman <markn@greenwoodsoftware.com>
Send bug reports or comments to the above address or to
bug-less@gnu.org.
@ -451,12 +457,6 @@ AAUUTTHHOORR
Version 358: 08 Jul 2000 7
Version 371: 26 Dec 2001 7

View File

@ -1,4 +1,4 @@
.TH LESSKEY 1 "Version 358: 08 Jul 2000"
.TH LESSKEY 1 "Version 371: 26 Dec 2001"
.SH NAME
lesskey \- specify key bindings for less
.SH SYNOPSIS
@ -168,6 +168,7 @@ default command keys used by less:
^L repaint
\eeu undo-hilite
g goto-line
\ekh goto-line
< goto-line
\ee< goto-line
p percent
@ -187,6 +188,7 @@ default command keys used by less:
G goto-end
\ee> goto-end
> goto-end
\eke goto-end
= status
^G status
:f status
@ -206,7 +208,10 @@ default command keys used by less:
^X^V examine
:n next-file
:p prev-file
t next-tag
T prev-tag
:x index-file
:d remove-file
- toggle-option
:t toggle-option t
s toggle-option o
@ -373,7 +378,7 @@ Suite 330, Boston, MA 02111-1307, USA.
.SH AUTHOR
.PP
Mark Nudelman <marknu@flash.net>
Mark Nudelman <markn@greenwoodsoftware.com>
.br
Send bug reports or comments to the above address or to bug-less@gnu.org.

View File

@ -20,20 +20,23 @@
#define IS_CONT(c) (((c) & 0xC0) == 0x80)
#define LINENUM_WIDTH 8 /* Chars to use for line number */
/* Buffer which holds the current output line */
public char linebuf[LINEBUF_SIZE];
public int size_linebuf = sizeof(linebuf);
public char *linebuf = NULL; /* Buffer which holds the current output line */
static char *attr = NULL; /* Extension of linebuf to hold attributes */
public int size_linebuf = 0; /* Size of line buffer (and attr buffer) */
public int cshift; /* Current left-shift of output line buffer */
public int hshift; /* Desired left-shift of output line buffer */
public int tabstops[TABSTOP_MAX] = { 0 }; /* Custom tabstops */
public int ntabstops = 1; /* Number of tabstops */
public int tabdefault = 8; /* Default repeated tabstops */
static char attr[LINEBUF_SIZE]; /* Extension of linebuf to hold attributes */
static int curr; /* Index into linebuf */
static int column; /* Printable length, accounting for
backspaces, etc. */
static int overstrike; /* Next char should overstrike previous char */
static int is_null_line; /* There is no current line */
static int lmargin; /* Left margin */
static int hilites; /* Number of hilites in this line */
static char pendc;
static POSITION pendpos;
static char *end_ansi_chars;
@ -41,7 +44,6 @@ static char *end_ansi_chars;
static int do_append();
extern int bs_mode;
extern int tabstop;
extern int linenums;
extern int ctldisp;
extern int twiddle;
@ -66,6 +68,34 @@ init_line()
end_ansi_chars = lgetenv("LESSANSIENDCHARS");
if (end_ansi_chars == NULL || *end_ansi_chars == '\0')
end_ansi_chars = "m";
linebuf = (char *) ecalloc(LINEBUF_SIZE, sizeof(char));
attr = (char *) ecalloc(LINEBUF_SIZE, sizeof(char));
size_linebuf = LINEBUF_SIZE;
}
/*
* Expand the line buffer.
*/
static int
expand_linebuf()
{
int new_size = size_linebuf + LINEBUF_SIZE;
char *new_buf = (char *) calloc(new_size, sizeof(char));
char *new_attr = (char *) calloc(new_size, sizeof(char));
if (new_buf == NULL || new_attr == NULL)
{
if (new_attr != NULL)
free(new_attr);
if (new_buf != NULL)
free(new_buf);
return 1;
}
memcpy(new_buf, linebuf, size_linebuf * sizeof(char));
memcpy(new_attr, attr, size_linebuf * sizeof(char));
linebuf = new_buf;
attr = new_attr;
size_linebuf = new_size;
return 0;
}
/*
@ -80,6 +110,9 @@ prewind()
is_null_line = 0;
pendc = '\0';
lmargin = 0;
#if HILITE_SEARCH
hilites = 0;
#endif
if (status_col)
lmargin += 1;
if (linenums == OPT_ONPLUS)
@ -146,10 +179,44 @@ plinenum(pos)
}
/*
*
* Determine how many characters are required to shift N columns.
*/
static int
utf_len(char *s, int len)
shift_chars(s, len)
char *s;
int len;
{
char *p = s;
/*
* Each char counts for one column, except ANSI color escape
* sequences use no columns since they don't move the cursor.
*/
while (*p != '\0' && len > 0)
{
if (*p++ != ESC)
{
len--;
} else
{
while (*p != '\0')
{
if (is_ansi_end(*p++))
break;
}
}
}
return (p - s);
}
/*
* Determine how many characters are required to shift N columns (UTF version).
* {{ FIXME: what about color escape sequences in UTF mode? }}
*/
static int
utf_shift_chars(s, len)
char *s;
int len;
{
int ulen = 0;
@ -177,28 +244,26 @@ pshift(shift)
int shift;
{
int i;
int real_shift;
int nchars;
if (shift > column - lmargin)
shift = column - lmargin;
if (shift > curr - lmargin)
shift = curr - lmargin;
if (!utf_mode)
real_shift = shift;
if (utf_mode)
nchars = utf_shift_chars(linebuf + lmargin, shift);
else
nchars = shift_chars(linebuf + lmargin, shift);
if (nchars > curr)
nchars = curr;
for (i = 0; i < curr - nchars; i++)
{
real_shift = utf_len(linebuf + lmargin, shift);
if (real_shift > curr)
real_shift = curr;
}
for (i = 0; i < curr - real_shift; i++)
{
linebuf[lmargin + i] = linebuf[lmargin + i + real_shift];
attr[lmargin + i] = attr[lmargin + i + real_shift];
linebuf[lmargin + i] = linebuf[lmargin + i + nchars];
attr[lmargin + i] = attr[lmargin + i + nchars];
}
curr -= nchars;
column -= shift;
curr -= real_shift;
cshift += shift;
}
@ -306,17 +371,30 @@ in_ansi_esc_seq()
{
if (linebuf[i] == ESC)
return (1);
if (strchr(end_ansi_chars, linebuf[i]) != NULL)
if (is_ansi_end(linebuf[i]))
return (0);
}
return (0);
}
/*
* Is a character the end of an ANSI escape sequence?
*/
public int
is_ansi_end(c)
char c;
{
return (strchr(end_ansi_chars, c) != NULL);
}
/*
* Append a character and attribute to the line buffer.
*/
#define STORE_CHAR(c,a,pos) \
do { if (store_char((c),(a),(pos))) return (1); else curr++; } while (0)
static int
storec(c, a, pos)
store_char(c, a, pos)
int c;
int a;
POSITION pos;
@ -325,11 +403,14 @@ storec(c, a, pos)
#if HILITE_SEARCH
if (is_hilited(pos, pos+1, 0))
{
/*
* This character should be highlighted.
* Override the attribute passed in.
*/
a = AT_STANDOUT;
hilites++;
}
#endif
if (ctldisp == OPT_ONPLUS && in_ansi_esc_seq())
w = 0;
@ -341,11 +422,15 @@ storec(c, a, pos)
*/
return (1);
if (curr >= sizeof(linebuf)-2)
if (curr >= size_linebuf-2)
{
/*
* Won't fit in line buffer.
* Try to expand it.
*/
return (1);
if (expand_linebuf())
return (1);
}
/*
* Special handling for "magic cookie" terminals.
@ -386,6 +471,38 @@ storec(c, a, pos)
return (0);
}
/*
* Append a tab to the line buffer.
* Store spaces to represent the tab.
*/
#define STORE_TAB(a,pos) \
do { if (store_tab((a),(pos))) return (1); } while (0)
static int
store_tab(attr, pos)
int attr;
POSITION pos;
{
int to_tab = column + cshift - lmargin;
int i;
if (ntabstops < 2 || to_tab >= tabstops[ntabstops-1])
to_tab = tabdefault -
((to_tab - tabstops[ntabstops-1]) % tabdefault);
else
{
for (i = ntabstops - 2; i >= 0; i--)
if (to_tab >= tabstops[i])
break;
to_tab = tabstops[i+1] - to_tab;
}
do {
STORE_CHAR(' ', attr, pos);
} while (--to_tab > 0);
return 0;
}
/*
* Append a character to the line buffer.
* Expand tabs into spaces, handle underlining, boldfacing, etc.
@ -429,7 +546,10 @@ pappend(c, pos)
* pappending. (Bold & underline can get messed up otherwise.)
*/
if (cshift < hshift && column > sc_width / 2)
{
linebuf[curr] = '\0';
pshift(hshift - cshift);
}
return (r);
}
@ -441,15 +561,15 @@ do_append(c, pos)
register char *s;
register int a;
#define STOREC(c,a) \
if (storec((c),(a),pos)) return (1); else curr++
#define STOREC(c,a) \
if ((c) == '\t') STORE_TAB((a),pos); else STORE_CHAR((c),(a),pos)
if (c == '\b')
{
switch (bs_mode)
{
case BS_NORMAL:
STOREC(c, AT_NORMAL);
STORE_CHAR(c, AT_NORMAL, pos);
break;
case BS_CONTROL:
goto do_control_char;
@ -469,14 +589,40 @@ do_append(c, pos)
* bold (if an identical character is overstruck),
* or just deletion of the character in the buffer.
*/
overstrike = 0;
if ((char)c == linebuf[curr])
STOREC(linebuf[curr], AT_BOLD);
else if (c == '_')
overstrike--;
if (utf_mode && curr > 1 && (char)c == linebuf[curr-2])
{
backc();
backc();
overstrike = 2;
} else if (utf_mode && curr > 0 && (char)c == linebuf[curr-1])
{
backc();
STORE_CHAR(linebuf[curr], AT_BOLD, pos);
overstrike = 1;
} else if ((char)c == linebuf[curr])
{
STOREC(c, AT_BOLD);
} else if (c == '_')
{
if (utf_mode)
{
if (curr > 0 && IS_CONT(linebuf[curr]))
attr[curr-1] = AT_UNDERLINE;
if (curr > 1 && IS_CONT(linebuf[curr-1]))
attr[curr-2] = AT_UNDERLINE;
if (curr > 2 && IS_CONT(linebuf[curr-2]))
attr[curr-3] = AT_UNDERLINE;
if (curr > 3 && IS_CONT(linebuf[curr-3]))
attr[curr-4] = AT_UNDERLINE;
if (curr > 4 && IS_CONT(linebuf[curr-4]))
attr[curr-5] = AT_UNDERLINE;
}
STOREC(linebuf[curr], AT_UNDERLINE);
else if (linebuf[curr] == '_')
} else if (linebuf[curr] == '_')
{
STOREC(c, AT_UNDERLINE);
else if (control_char(c))
} else if (control_char(c))
goto do_control_char;
else
STOREC(c, AT_NORMAL);
@ -485,18 +631,13 @@ do_append(c, pos)
/*
* Expand a tab into spaces.
*/
if (tabstop == 0)
tabstop = 1;
switch (bs_mode)
{
case BS_CONTROL:
goto do_control_char;
case BS_NORMAL:
case BS_SPECIAL:
do
{
STOREC(' ', AT_NORMAL);
} while (((column + cshift - lmargin) % tabstop) != 0);
STORE_TAB(AT_NORMAL, pos);
break;
}
} else if (control_char(c))
@ -507,7 +648,7 @@ do_append(c, pos)
/*
* Output as a normal character.
*/
STOREC(c, AT_NORMAL);
STORE_CHAR(c, AT_NORMAL, pos);
} else
{
/*
@ -525,7 +666,7 @@ do_append(c, pos)
return (1);
for ( ; *s != 0; s++)
STOREC(*s, a);
STORE_CHAR(*s, a, pos);
}
} else
{
@ -568,6 +709,14 @@ pdone(endline)
}
linebuf[curr] = '\0';
attr[curr] = AT_NORMAL;
#if HILITE_SEARCH
if (status_col && hilites > 0)
{
linebuf[0] = '*';
attr[0] = AT_STANDOUT;
}
#endif
/*
* If we are done with this line, reset the current shift.
*/
@ -622,7 +771,7 @@ forw_raw_line(curr_pos, linep)
POSITION curr_pos;
char **linep;
{
register char *p;
register int n;
register int c;
POSITION new_pos;
@ -630,8 +779,7 @@ forw_raw_line(curr_pos, linep)
(c = ch_forw_get()) == EOI)
return (NULL_POSITION);
p = linebuf;
n = 0;
for (;;)
{
if (c == '\n' || c == EOI)
@ -639,21 +787,22 @@ forw_raw_line(curr_pos, linep)
new_pos = ch_tell();
break;
}
if (p >= &linebuf[sizeof(linebuf)-1])
if (n >= size_linebuf-1)
{
/*
* Overflowed the input buffer.
* Pretend the line ended here.
* {{ The line buffer is supposed to be big
* enough that this never happens. }}
*/
new_pos = ch_tell() - 1;
break;
if (expand_linebuf())
{
/*
* Overflowed the input buffer.
* Pretend the line ended here.
*/
new_pos = ch_tell() - 1;
break;
}
}
*p++ = c;
linebuf[n++] = c;
c = ch_forw_get();
}
*p = '\0';
linebuf[n] = '\0';
if (linep != NULL)
*linep = linebuf;
return (new_pos);
@ -668,7 +817,7 @@ back_raw_line(curr_pos, linep)
POSITION curr_pos;
char **linep;
{
register char *p;
register int n;
register int c;
POSITION new_pos;
@ -676,9 +825,8 @@ back_raw_line(curr_pos, linep)
ch_seek(curr_pos-1))
return (NULL_POSITION);
p = &linebuf[sizeof(linebuf)];
*--p = '\0';
n = size_linebuf;
linebuf[--n] = '\0';
for (;;)
{
c = ch_back_get();
@ -701,18 +849,32 @@ back_raw_line(curr_pos, linep)
new_pos = ch_zero();
break;
}
if (p <= linebuf)
if (n <= 0)
{
int old_size_linebuf = size_linebuf;
char *fm;
char *to;
if (expand_linebuf())
{
/*
* Overflowed the input buffer.
* Pretend the line ended here.
*/
new_pos = ch_tell() + 1;
break;
}
/*
* Overflowed the input buffer.
* Pretend the line ended here.
* Shift the data to the end of the new linebuf.
*/
new_pos = ch_tell() + 1;
break;
for (fm = linebuf + old_size_linebuf,
to = linebuf + size_linebuf;
fm >= linebuf; fm--, to--)
*to = *fm;
n = size_linebuf - old_size_linebuf;
}
*--p = c;
linebuf[--n] = c;
}
if (linep != NULL)
*linep = p;
*linep = &linebuf[n];
return (new_pos);
}

View File

@ -297,7 +297,6 @@ find_linenum(pos)
* The decision is based on which way involves
* traversing fewer bytes in the file.
*/
flush();
#if HAVE_TIME
startime = get_time();
#endif
@ -386,7 +385,6 @@ find_pos(lno)
/* Found it exactly. */
return (p->pos);
flush();
if (p == &anchor || lno - p->prev->line < p->line - lno)
{
/*

View File

@ -14,8 +14,8 @@
* Necessarily very OS dependent.
*/
#include <signal.h>
#include "less.h"
#include <signal.h>
#include "position.h"
#if MSDOS_COMPILER
@ -107,7 +107,12 @@ lsystem(cmd, donemsg)
*/
inp = dup(0);
close(0);
#if OS2
/* The __open() system call translates "/dev/tty" to "con". */
if (__open("/dev/tty", OPEN_READ) < 0)
#else
if (open("/dev/tty", OPEN_READ) < 0)
#endif
dup(inp);
#endif

View File

@ -14,6 +14,9 @@
*/
#include "less.h"
#if MSDOS_COMPILER==WIN32C
#include <windows.h>
#endif
public char * every_first_cmd = NULL;
public int new_file;
@ -42,10 +45,15 @@ public char * editproto;
#endif
#if TAGS
extern char * tags;
extern char * tagoption;
extern int jump_sline;
#endif
#ifdef WIN32
static char consoleTitle[256];
#endif
extern int missing_cap;
extern int know_dumb;
@ -93,6 +101,7 @@ main(argc, argv)
putenv(env);
}
}
GetConsoleTitle(consoleTitle, sizeof(consoleTitle)/sizeof(char));
#endif /* WIN32 */
/*
@ -153,7 +162,7 @@ main(argc, argv)
ifile = get_ifile(FAKE_HELPFILE, ifile);
while (argc-- > 0)
{
#if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC) || OS2
#if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC)
/*
* Because the "shell" doesn't expand filename patterns,
* treat each argument as a filename pattern rather than
@ -209,7 +218,7 @@ main(argc, argv)
* Select the first file to examine.
*/
#if TAGS
if (tagoption != NULL)
if (tagoption != NULL || strcmp(tags, "-") == 0)
{
/*
* A -t option was given.
@ -364,6 +373,9 @@ quit(status)
* The same bug shows up if we use ^C^C to abort.
*/
close(2);
#endif
#if WIN32
SetConsoleTitle(consoleTitle);
#endif
close_getchr();
exit(status);

View File

@ -42,6 +42,7 @@ extern char closequote;
extern char *prproto[];
extern char *eqproto;
extern char *hproto;
extern char *wproto;
extern IFILE curr_ifile;
extern char version[];
#if LOGFILE
@ -291,6 +292,7 @@ opt__P(type, s)
case 'M': proto = &prproto[PR_LONG]; s++; break;
case '=': proto = &eqproto; s++; break;
case 'h': proto = &hproto; s++; break;
case 'w': proto = &wproto; s++; break;
default: proto = &prproto[PR_SHORT]; break;
}
free(*proto);
@ -368,10 +370,11 @@ opt__V(type, s)
any_display = 1;
putstr("less ");
putstr(version);
putstr("\nCopyright (C) 2000 Mark Nudelman\n\n");
putstr("\nCopyright (C) 2001 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");
putstr("Homepage: http://www.greenwoodsoftware.com/less\n");
quit(QUIT_OK);
break;
}
@ -460,6 +463,62 @@ opt_D(type, s)
}
#endif
/*
* Handler for the -x option.
*/
public void
opt_x(type, s)
int type;
register char *s;
{
extern int tabstops[];
extern int ntabstops;
extern int tabdefault;
char msg[60+(4*TABSTOP_MAX)];
int i;
PARG p;
switch (type)
{
case INIT:
case TOGGLE:
/* Start at 1 because tabstops[0] is always zero. */
for (i = 1; i < TABSTOP_MAX; )
{
int n = 0;
while (*s >= '0' && *s <= '9')
n = (10 * n) + (*s++ - '0');
if (n > tabstops[i-1])
tabstops[i++] = n;
if (*s++ != ',')
break;
}
if (i < 2)
return;
ntabstops = i;
tabdefault = tabstops[ntabstops-1] - tabstops[ntabstops-2];
break;
case QUERY:
strcpy(msg, "Tab stops ");
if (ntabstops > 2)
{
for (i = 1; i < ntabstops; i++)
{
if (i > 1)
strcat(msg, ",");
sprintf(msg+strlen(msg), "%d", tabstops[i]);
}
sprintf(msg+strlen(msg), " and then ");
}
sprintf(msg+strlen(msg), "every %d spaces",
tabdefault);
p.p_string = msg;
error("%s", &p);
break;
}
}
/*
* Handler for the -" option.
*/

View File

@ -116,11 +116,12 @@ scan_option(s)
* EVERY input file.
*/
plusoption = TRUE;
if (*s == '+')
every_first_cmd = save(++s);
str = s;
s = optstring(s, propt('+'), NULL);
if (*str == '+')
every_first_cmd = save(++str);
else
ungetsc(s);
s = optstring(s, propt('+'));
ungetsc(str);
continue;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
@ -225,7 +226,7 @@ scan_option(s)
* the handling function.
*/
str = s;
s = optstring(s, printopt);
s = optstring(s, printopt, o->odesc[1]);
break;
case NUMBER:
if (*s == '\0')
@ -543,11 +544,13 @@ nopendopt()
* Return a pointer to the remainder of the string, if any.
*/
static char *
optstring(s, printopt)
optstring(s, printopt, validchars)
char *s;
char *printopt;
char *validchars;
{
register char *p;
PARG parg;
if (*s == '\0')
{
@ -555,8 +558,19 @@ optstring(s, printopt)
quit(QUIT_ERROR);
}
for (p = s; *p != '\0'; p++)
if (*p == END_OPTION_STRING)
if (*p == END_OPTION_STRING ||
(validchars != NULL && strchr(validchars, *p) == NULL))
{
switch (*p)
{
case END_OPTION_STRING:
case ' ': case '\t': case '-':
break;
default:
parg.p_string = p;
error("Option string needs delimiter before %s", &parg);
break;
}
*p = '\0';
return (p+1);
}

View File

@ -42,6 +42,7 @@ public int swindow; /* Size of scrolling window */
public int jump_sline; /* Screen line of "jump target" */
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 */
public int twiddle; /* Show tildes after EOF */
public int show_attn; /* Hilite first unread line */
public int shift_count; /* Number of positions to shift horizontally */
@ -102,10 +103,20 @@ static struct optname quote_optname = { "quotes", NULL };
static struct optname tilde_optname = { "tilde", NULL };
static struct optname query_optname = { "help", NULL };
static struct optname pound_optname = { "shift", NULL };
static struct optname keypad_optname = { "no-keypad", NULL };
/*
* Table of all options and their semantics.
*
* For BOOL and TRIPLE options, odesc[0], odesc[1], odesc[2] are
* the description of the option when set to 0, 1 or 2, respectively.
* For NUMBER options, odesc[0] is the prompt to use when entering
* a new value, and odesc[1] is the description, which should contain
* one %d which is replaced by the value of the number.
* For STRING options, odesc[0] is the prompt to use when entering
* a new value, and odesc[1], if not NULL, is the set of characters
* that are valid in the string.
*/
static struct option option[] =
{
@ -143,7 +154,9 @@ static struct option option[] =
#if MSDOS_COMPILER
{ 'D', &D__optname,
STRING|REPAINT|NO_QUERY, 0, NULL, opt_D,
"color desc: ", NULL, NULL
"color desc: ",
"Ddknsu0123456789.",
NULL
},
#endif
{ 'e', &e_optname,
@ -287,9 +300,9 @@ static struct option option[] =
"Highlight first unread line after any forward movement",
},
{ 'x', &x_optname,
NUMBER|REPAINT, 8, &tabstop, NULL,
STRING|REPAINT, 0, NULL, opt_x,
"Tab stops: ",
"Tab stops every %d spaces",
"0123456789,",
NULL
},
{ 'X', &X__optname,
@ -330,6 +343,12 @@ static struct option option[] =
"Horizontal shift %d positions",
NULL
},
{ '.', &keypad_optname,
BOOL|NO_TOGGLE, OPT_OFF, &no_keypad, NULL,
"Use keypad mode",
"Don't use keypad mode",
NULL
},
{ '\0', NULL, NOVAR, 0, NULL, NULL, NULL, NULL, NULL }
};
@ -429,7 +448,7 @@ findopt_name(p_optname, p_oname, p_err)
maxoname = oname;
maxlen = len;
ambig = 0;
exact = (len == strlen(oname->oname));
exact = (len == (int)strlen(oname->oname));
}
if (!(o->otype & TRIPLE))
break;

View File

@ -33,9 +33,6 @@
#if HAVE_VALUES_H
#include <values.h>
#endif
#if HAVE_LIMITS_H
#include <limits.h>
#endif
#if HAVE_TIME_T
#define time_type time_t
@ -232,36 +229,6 @@ errno_message(filename)
return (m);
}
/*
* Return the largest possible number that can fit in a long.
*/
static long
get_maxlong()
{
#ifdef LONG_MAX
return (LONG_MAX);
#else
#ifdef MAXLONG
return (MAXLONG);
#else
long n, n2;
/*
* Keep doubling n until we overflow.
* {{ This actually only returns the largest power of two that
* can fit in a long, but percentage() doesn't really need
* it any more accurate than that. }}
*/
n2 = 128; /* Hopefully no maxlong is less than 128! */
do {
n = n2;
n2 *= 2;
} while (n2 / 2 == n);
return (n);
#endif
#endif
}
/*
* Return the ratio of two POSITIONS, as a percentage.
* {{ Assumes a POSITION is a long int. }}
@ -270,27 +237,67 @@ get_maxlong()
percentage(num, den)
POSITION num, den;
{
if (num <= get_maxlong() / 100)
return ((100 * num) / den);
POSITION num100 = num * 100;
if (num100 / 100 == num)
return (num100 / den);
else
return (num / (den / 100));
}
/*
* Return the specified percentage of a POSITION.
* {{ Assumes a POSITION is a long int. }}
*/
public POSITION
percent_pos(pos, percent)
POSITION pos;
int percent;
{
if (pos <= get_maxlong() / 100)
return ((percent * pos) / 100);
POSITION result100;
if (percent == 0)
return (0);
else if ((result100 = pos * percent) / percent == pos)
return (result100 / 100);
else
return (percent * (pos / 100));
}
#if !HAVE_STRCHR
/*
* strchr is used by regexp.c.
*/
char *
strchr(s, c)
char *s;
int c;
{
for ( ; *s != '\0'; s++)
if (*s == c)
return (s);
if (c == '\0')
return (s);
return (NULL);
}
#endif
#if !HAVE_MEMCPY
VOID_POINTER
memcpy(dst, src, len)
VOID_POINTER dst;
VOID_POINTER src;
int len;
{
char *dstp = (char *) dst;
char *srcp = (char *) src;
int i;
for (i = 0; i < len; i++)
dstp[i] = srcp[i];
return (dst);
}
#endif
#ifdef _OSK_MWC32
/*
@ -306,7 +313,7 @@ os9_signal(type, handler)
#include <sgstat.h>
public int
int
isatty(f)
int f;
{

View File

@ -125,68 +125,43 @@ flush()
#if MSDOS_COMPILER==WIN32C
if (is_tty && any_display)
{
char *p;
char *op;
DWORD nwritten = 0;
CONSOLE_SCREEN_BUFFER_INFO scr;
DWORD nchars;
COORD cpos;
WORD nm_attr;
int row;
int col;
int olen;
extern HANDLE con_out;
extern int nm_fg_color;
extern int nm_bg_color;
#define MAKEATTR(fg,bg) ((WORD)((fg)|((bg)<<4)))
*ob = '\0';
olen = ob - obuf;
/*
* To avoid color problems, if we're scrolling the screen,
* we write only up to the char that causes the scroll,
* (a newline or a char in the last column), then fill
* the bottom line with the "normal" attribute, then
* write the rest.
* When Windows scrolls, it takes the attributes for the
* new line from the first char of the (previously)
* bottom line.
*
* {{ This still doesn't work correctly in all cases! }}
* There is a bug in Win32 WriteConsole() if we're
* writing in the last cell with a different color.
* To avoid color problems in the bottom line,
* we scroll the screen manually, before writing.
*/
nm_attr = MAKEATTR(nm_fg_color, nm_bg_color);
for (op = obuf; *op != '\0'; )
GetConsoleScreenBufferInfo(con_out, &scr);
col = scr.dwCursorPosition.X;
row = scr.dwCursorPosition.Y;
for (op = obuf; op < obuf + olen; op++)
{
GetConsoleScreenBufferInfo(con_out, &scr);
/* Find the next newline. */
p = strchr(op, '\n');
if (p == NULL &&
scr.dwCursorPosition.X + olen >= sc_width)
if (*op == '\n')
{
/*
* No newline, but writing in the
* last column causes scrolling.
*/
p = op + sc_width - scr.dwCursorPosition.X - 1;
}
if (scr.dwCursorPosition.Y != scr.srWindow.Bottom ||
p == NULL)
{
/* Write the entire buffer. */
WriteConsole(con_out, op, olen,
&nwritten, NULL);
op += olen;
col = 0;
row++;
} else
{
/* Write only up to the scrolling char. */
WriteConsole(con_out, op, p - op + 1,
&nwritten, NULL);
cpos.X = 0;
cpos.Y = scr.dwCursorPosition.Y;
FillConsoleOutputAttribute(con_out, nm_attr,
sc_width, cpos, &nchars);
olen -= p - op + 1;
op = p + 1;
col++;
if (col >= sc_width)
{
col = 0;
row++;
}
}
}
if (row > scr.srWindow.Bottom)
win32_scroll_up(row - scr.srWindow.Bottom);
WriteConsole(con_out, obuf, olen, &nwritten, NULL);
ob = obuf;
return;
}
@ -274,7 +249,7 @@ iprintnum(num, radix)
register char *s;
int r;
int neg;
char buf[10];
char buf[INT_STRLEN_BOUND(num)];
neg = (num < 0);
if (neg)

View File

@ -41,19 +41,22 @@ extern char *editproto;
* These strings are expanded by pr_expand().
*/
static constant char s_proto[] =
"?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\\: %x..%t";
"?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\\: %x..%t";
static constant char m_proto[] =
"?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t";
"?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\\: %x.:?pB%pB\\%:byte %bB?s/%s...%t";
static constant char M_proto[] =
"?f%f .?n?m(file %i of %m) ..?ltlines %lt-%lb?L/%L. :byte %bB?s/%s. .?e(END) ?x- Next\\: %x.:?pB%pB\\%..%t";
"?f%f .?n?m(%T %i of %m) ..?ltlines %lt-%lb?L/%L. :byte %bB?s/%s. .?e(END) ?x- Next\\: %x.:?pB%pB\\%..%t";
static constant char e_proto[] =
"?f%f .?m(file %i of %m) .?ltlines %lt-%lb?L/%L. .byte %bB?s/%s. ?e(END) :?pB%pB\\%..%t";
"?f%f .?m(%T %i of %m) .?ltlines %lt-%lb?L/%L. .byte %bB?s/%s. ?e(END) :?pB%pB\\%..%t";
static constant char h_proto[] =
"HELP -- ?eEND -- Press g to see it again:Press RETURN for more., or q when done";
static constant char w_proto[] =
"Waiting for data";
public char *prproto[3];
public char constant *eqproto = e_proto;
public char constant *hproto = h_proto;
public char constant *wproto = w_proto;
static char message[PROMPT_SIZE];
static char *mp;
@ -69,6 +72,7 @@ init_prompt()
prproto[2] = save(M_proto);
eqproto = save(e_proto);
hproto = save(h_proto);
wproto = save(w_proto);
}
/*
@ -109,10 +113,19 @@ ap_char(c)
ap_pos(pos)
POSITION pos;
{
char buf[MAX_PRINT_POSITION];
sprintf(buf, PR_POSITION, pos);
ap_str(buf);
char buf[INT_STRLEN_BOUND(pos) + 1];
char *p = buf + sizeof(buf) - 1;
int neg = (pos < 0);
if (neg)
pos = -pos;
*p = '\0';
do
*--p = '0' + (pos % 10);
while ((pos /= 10) != 0);
if (neg)
*--p = '-';
ap_str(p);
}
/*
@ -122,7 +135,7 @@ ap_pos(pos)
ap_int(n)
int n;
{
char buf[MAX_PRINT_INT];
char buf[INT_STRLEN_BOUND(n) + 1];
sprintf(buf, "%d", n);
ap_str(buf);
@ -186,9 +199,9 @@ cond(c, where)
case 'D': /* Same as L */
return (linenums && ch_length() != NULL_POSITION);
case 'm': /* More than one file? */
return (nifile() > 1);
return (ntags() ? (ntags() > 1) : (nifile() > 1));
case 'n': /* First prompt in a new file? */
return (new_file);
return (ntags() ? 1 : new_file);
case 'p': /* Percent into file (bytes) known? */
return (curr_byte(where) != NULL_POSITION &&
ch_length() > 0);
@ -200,6 +213,8 @@ cond(c, where)
case 'B':
return (ch_length() != NULL_POSITION);
case 'x': /* Is there a "next" file? */
if (ntags())
return (0);
return (next_ifile(curr_ifile) != NULL_IFILE);
}
return (0);
@ -272,7 +287,10 @@ protochar(c, where, iseditproto)
free(s);
break;
case 'i': /* Index into list of files */
ap_int(get_index(curr_ifile));
if (ntags())
ap_int(curr_tag());
else
ap_int(get_index(curr_ifile));
break;
case 'l': /* Current line number */
n = currline(where);
@ -290,7 +308,11 @@ protochar(c, where, iseditproto)
ap_int(n-1);
break;
case 'm': /* Number of files */
ap_int(nifile());
n = ntags();
if (n)
ap_int(n);
else
ap_int(nifile());
break;
case 'p': /* Percent into file (bytes) */
pos = curr_byte(where);
@ -321,6 +343,12 @@ protochar(c, where, iseditproto)
while (mp > message && mp[-1] == ' ')
mp--;
break;
case 'T': /* Type of list */
if (ntags())
ap_str("tag");
else
ap_str("file");
break;
case 'x': /* Name of next file */
h = next_ifile(curr_ifile);
if (h != NULL_IFILE)
@ -483,7 +511,6 @@ pr_expand(proto, maxwidth)
}
}
new_file = 0;
if (mp == message)
return (NULL);
if (maxwidth > 0 && mp >= message + maxwidth)
@ -515,7 +542,20 @@ eq_message()
public char *
pr_string()
{
if (ch_getflags() & CH_HELPFILE)
return (pr_expand(hproto, sc_width-so_s_width-so_e_width-2));
return (pr_expand(prproto[pr_type], sc_width-so_s_width-so_e_width-2));
char *prompt;
prompt = pr_expand((ch_getflags() & CH_HELPFILE) ?
hproto : prproto[pr_type],
sc_width-so_s_width-so_e_width-2);
new_file = 0;
return (prompt);
}
/*
* Return a message suitable for printing while waiting in the F command.
*/
public char *
wait_message()
{
return (pr_expand(wproto, sc_width-so_s_width-so_e_width-2));
}

View File

@ -66,6 +66,7 @@ extern int fd0;
#endif
#if OS2
#include <sys/signal.h>
#include "pckeys.h"
#endif
#if HAVE_SYS_STREAM_H
#include <sys/stream.h>
@ -88,6 +89,7 @@ extern int fd0;
#if OS2
#define DEFAULT_TERM "ansi"
static char *windowid;
#else
#define DEFAULT_TERM "unknown"
#endif
@ -223,6 +225,7 @@ extern int quiet; /* If VERY_QUIET, use visual bell for bell */
extern int no_back_scroll;
extern int swindow;
extern int no_init;
extern int no_keypad;
extern int sigs;
extern int wscroll;
extern int screen_trashed;
@ -419,6 +422,9 @@ raw_mode(on)
*/
s = save_term;
}
#if HAVE_FSYNC
fsync(2);
#endif
tcsetattr(2, TCSADRAIN, &s);
#if MUST_SET_LINE_DISCIPLINE
if (!on)
@ -708,6 +714,27 @@ scrsize()
_scrsize(s);
sys_width = s[0];
sys_height = s[1];
/*
* When using terminal emulators for XFree86/OS2, the
* _scrsize function does not work well.
* Call the scrsize.exe program to get the window size.
*/
windowid = getenv("WINDOWID");
if (windowid != NULL)
{
FILE *fd = popen("scrsize", "rt");
if (fd != NULL)
{
int w, h;
fscanf(fd, "%i %i", &w, &h);
if (w > 0 && h > 0)
{
sys_width = w;
sys_height = h;
}
pclose(fd);
}
}
}
#else
#ifdef TIOCGWINSZ
@ -831,7 +858,7 @@ special_key_str(key)
{
static char tbuf[40];
char *s;
#if MSDOS_COMPILER
#if MSDOS_COMPILER || OS2
static char k_right[] = { '\340', PCK_RIGHT, 0 };
static char k_left[] = { '\340', PCK_LEFT, 0 };
static char k_ctl_right[] = { '\340', PCK_CTL_RIGHT, 0 };
@ -848,12 +875,56 @@ special_key_str(key)
static char k_pagedown[] = { '\340', PCK_PAGEDOWN, 0 };
static char k_pageup[] = { '\340', PCK_PAGEUP, 0 };
static char k_f1[] = { '\340', PCK_F1, 0 };
#else
#endif
#if !MSDOS_COMPILER
char *sp = tbuf;
#endif
switch (key)
{
#if OS2
/*
* If windowid is not NULL, assume less is executed in
* the XFree86 environment.
*/
case SK_RIGHT_ARROW:
s = windowid ? ltgetstr("kr", &sp) : k_right;
break;
case SK_LEFT_ARROW:
s = windowid ? ltgetstr("kl", &sp) : k_left;
break;
case SK_UP_ARROW:
s = windowid ? ltgetstr("ku", &sp) : k_up;
break;
case SK_DOWN_ARROW:
s = windowid ? ltgetstr("kd", &sp) : k_down;
break;
case SK_PAGE_UP:
s = windowid ? ltgetstr("kP", &sp) : k_pageup;
break;
case SK_PAGE_DOWN:
s = windowid ? ltgetstr("kN", &sp) : k_pagedown;
break;
case SK_HOME:
s = windowid ? ltgetstr("kh", &sp) : k_home;
break;
case SK_END:
s = windowid ? ltgetstr("@7", &sp) : k_end;
break;
case SK_DELETE:
if (windowid)
{
s = ltgetstr("kD", &sp);
if (s == NULL)
{
tbuf[0] = '\177';
tbuf[1] = '\0';
s = tbuf;
}
} else
s = k_delete;
break;
#endif
#if MSDOS_COMPILER
case SK_RIGHT_ARROW:
s = k_right;
@ -882,6 +953,8 @@ special_key_str(key)
case SK_DELETE:
s = k_delete;
break;
#endif
#if MSDOS_COMPILER || OS2
case SK_INSERT:
s = k_insert;
break;
@ -1426,21 +1499,15 @@ win32_deinit_term()
public void
init()
{
if (no_init)
{
#if MSDOS_COMPILER==WIN32C
/* no_init or not, never trash win32 console colors. */
initcolor();
flush();
#endif
return;
}
#if !MSDOS_COMPILER
tputs(sc_init, sc_height, putchr);
tputs(sc_s_keypad, sc_height, putchr);
if (!no_init)
tputs(sc_init, sc_height, putchr);
if (!no_keypad)
tputs(sc_s_keypad, sc_height, putchr);
#else
#if MSDOS_COMPILER==WIN32C
win32_init_term();
if (!no_init)
win32_init_term();
#endif
initcolor();
flush();
@ -1454,24 +1521,22 @@ init()
public void
deinit()
{
if (no_init)
{
#if MSDOS_COMPILER==WIN32C
/* no_init or not, never trash win32 console colors. */
SETCOLORS(sy_fg_color, sy_bg_color);
#endif
return;
}
if (!init_done)
return;
#if !MSDOS_COMPILER
tputs(sc_e_keypad, sc_height, putchr);
tputs(sc_deinit, sc_height, putchr);
if (!no_keypad)
tputs(sc_e_keypad, sc_height, putchr);
if (!no_init)
tputs(sc_deinit, sc_height, putchr);
#else
/* Restore system colors. */
SETCOLORS(sy_fg_color, sy_bg_color);
#if MSDOS_COMPILER==WIN32C
win32_deinit_term();
if (!no_init)
win32_deinit_term();
#else
/* Need clreol to make SETCOLORS take effect. */
clreol();
#endif
#endif
init_done = 0;
@ -1547,6 +1612,7 @@ add_line()
#endif
}
#if 0
/*
* Remove the n topmost lines and scroll everything below it in the
* window upward. This is needed to stop leaking the topmost line
@ -1600,6 +1666,105 @@ remove_top(n)
goto_line(sc_height - n - 1);
#endif
}
#endif
#if MSDOS_COMPILER==WIN32C
/*
* Clear the screen.
*/
static void
win32_clear()
{
/*
* This will clear only the currently visible rows of the NT
* console buffer, which means none of the precious scrollback
* rows are touched making for faster scrolling. Note that, if
* the window has fewer columns than the console buffer (i.e.
* there is a horizontal scrollbar as well), the entire width
* of the visible rows will be cleared.
*/
COORD topleft;
DWORD nchars;
DWORD winsz;
CONSOLE_SCREEN_BUFFER_INFO csbi;
/* get the number of cells in the current buffer */
GetConsoleScreenBufferInfo(con_out, &csbi);
winsz = csbi.dwSize.X * (csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
topleft.X = 0;
topleft.Y = csbi.srWindow.Top;
curr_attr = MAKEATTR(nm_fg_color, nm_bg_color);
FillConsoleOutputCharacter(con_out, ' ', winsz, topleft, &nchars);
FillConsoleOutputAttribute(con_out, curr_attr, winsz, topleft, &nchars);
}
/*
* Remove the n topmost lines and scroll everything below it in the
* window upward.
*/
public void
win32_scroll_up(n)
int n;
{
SMALL_RECT rcSrc, rcClip;
CHAR_INFO fillchar;
COORD topleft;
COORD new_org;
DWORD nchars;
DWORD size;
CONSOLE_SCREEN_BUFFER_INFO csbi;
if (n <= 0)
return;
if (n >= sc_height - 1)
{
win32_clear();
_settextposition(1,1);
return;
}
/* Get the extent of what will remain visible after scrolling. */
GetConsoleScreenBufferInfo(con_out, &csbi);
rcSrc.Left = csbi.srWindow.Left;
rcSrc.Top = csbi.srWindow.Top + n;
rcSrc.Right = csbi.srWindow.Right;
rcSrc.Bottom = csbi.srWindow.Bottom;
/* Get the clip rectangle. */
rcClip.Left = rcSrc.Left;
rcClip.Top = csbi.srWindow.Top;
rcClip.Right = rcSrc.Right;
rcClip.Bottom = rcSrc.Bottom ;
/* Move the source text to the top of the screen. */
new_org.X = rcSrc.Left;
new_org.Y = 0;
/* Fill the right character and attributes. */
fillchar.Char.AsciiChar = ' ';
fillchar.Attributes = MAKEATTR(nm_fg_color, nm_bg_color);
/* Scroll the window. */
SetConsoleTextAttribute(con_out, fillchar.Attributes);
ScrollConsoleScreenBuffer(con_out, &rcSrc, &rcClip, new_org, &fillchar);
/* Clear remaining lines at bottom. */
topleft.X = csbi.dwCursorPosition.X;
topleft.Y = rcSrc.Bottom - n;
size = (n * csbi.dwSize.X) + (rcSrc.Right - topleft.X);
FillConsoleOutputCharacter(con_out, ' ', size, topleft,
&nchars);
FillConsoleOutputAttribute(con_out, fillchar.Attributes, size, topleft,
&nchars);
SetConsoleTextAttribute(con_out, curr_attr);
/* Move cursor n lines up from where it was. */
csbi.dwCursorPosition.Y -= n;
SetConsoleCursorPosition(con_out, csbi.dwCursorPosition);
}
#endif
/*
* Move cursor to lower left corner of screen.
@ -1795,7 +1960,7 @@ vbell()
beep()
{
#if !MSDOS_COMPILER
putchr('\7');
putchr(CONTROL('G'));
#else
#if MSDOS_COMPILER==WIN32C
MessageBeep(0);
@ -1828,30 +1993,7 @@ clear()
#else
flush();
#if MSDOS_COMPILER==WIN32C
/*
* This will clear only the currently visible rows of the NT
* console buffer, which means none of the precious scrollback
* rows are touched making for faster scrolling. Note that, if
* the window has fewer columns than the console buffer (i.e.
* there is a horizontal scrollbar as well), the entire width
* of the visible rows will be cleared.
*/
{
COORD topleft;
DWORD nchars;
DWORD winsz;
CONSOLE_SCREEN_BUFFER_INFO csbi;
/* get the number of cells in the current buffer */
GetConsoleScreenBufferInfo(con_out, &csbi);
winsz = csbi.dwSize.X * (csbi.srWindow.Bottom - csbi.srWindow.Top + 1);
topleft.X = 0;
topleft.Y = csbi.srWindow.Top;
curr_attr = MAKEATTR(nm_fg_color, nm_bg_color);
FillConsoleOutputCharacter(con_out, ' ', winsz, topleft, &nchars);
FillConsoleOutputAttribute(con_out, curr_attr, winsz, topleft, &nchars);
}
win32_clear();
#else
_clearscreen(_GCLEARSCREEN);
#endif

104
contrib/less/scrsize.c Normal file
View File

@ -0,0 +1,104 @@
/*
* Copyright (C) 1984-2001 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.
*/
/*
* This program is used to determine the screen dimensions on OS/2 systems.
* Adapted from code written by Kyosuke Tokoro (NBG01720@nifty.ne.jp).
*/
/*
* When I wrote this routine, I consulted some part of the source code
* of the xwininfo utility by X Consortium.
*
* Copyright (c) 1987, X Consortium
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of the X Consortium shall not
* be used in advertising or otherwise to promote the sale, use or other
* dealings in this Software without prior written authorization from the X
* Consortium.
*/
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdlib.h>
#include <stdio.h>
static int get_winsize(dpy, window, p_width, p_height)
Display *dpy;
Window window;
int *p_width;
int *p_height;
{
XWindowAttributes win_attributes;
XSizeHints hints;
long longjunk;
if (!XGetWindowAttributes(dpy, window, &win_attributes))
return 1;
if (!XGetWMNormalHints(dpy, window, &hints, &longjunk))
return 1;
if (!(hints.flags & PResizeInc))
return 1;
if (hints.width_inc == 0 || hints.height_inc == 0)
return 1;
if (!(hints.flags & (PBaseSize|PMinSize)))
return 1;
if (hints.flags & PBaseSize)
{
win_attributes.width -= hints.base_width;
win_attributes.height -= hints.base_height;
} else
{
win_attributes.width -= hints.min_width;
win_attributes.height -= hints.min_height;
}
*p_width = win_attributes.width / hints.width_inc;
*p_height = win_attributes.height / hints.height_inc;
return 0;
}
int main(argc, argv)
int argc;
char *argv[];
{
char *cp;
Display *dpy;
int size[2];
_scrsize(size);
cp = getenv("WINDOWID");
if (cp != NULL)
{
dpy = XOpenDisplay(NULL);
if (dpy != NULL)
{
get_winsize(dpy, (Window) atol(cp), &size[0], &size[1]);
XCloseDisplay(dpy);
}
}
printf("%i %i\n", size[0], size[1]);
return (0);
}

View File

@ -1341,21 +1341,3 @@ regerror(s)
}
#endif
#if !HAVE_STRCHR
/*
* strchr is used by regexp.c.
*/
char *
strchr(s, c)
char *s;
int c;
{
for ( ; *s != '\0'; s++)
if (*s == c)
return (s);
if (c == '\0')
return (s);
return (NULL);
}
#endif

View File

@ -17,43 +17,277 @@
public char *tags = "tags";
static char *tagfile;
static char *tagpattern;
static int taglinenum;
static int tagendline;
static int total;
static int curseq;
extern int linenums;
extern int sigs;
extern int jump_sline;
enum tag_result {
TAG_FOUND,
TAG_NOFILE,
TAG_NOTAG,
TAG_NOTYPE,
TAG_INTR
};
/*
* Tag type
*/
enum {
T_CTAGS, /* 'tags': standard and extended format (ctags) */
T_CTAGS_X, /* stdin: cross reference format (ctags) */
T_GTAGS, /* 'GTAGS': function defenition (global) */
T_GRTAGS, /* 'GRTAGS': function reference (global) */
T_GSYMS, /* 'GSYMS': other symbols (global) */
T_GPATH /* 'GPATH': path name (global) */
};
static enum tag_result findctag();
static enum tag_result findgtag();
static char *nextgtag();
static char *prevgtag();
static POSITION ctagsearch();
static POSITION gtagsearch();
static int getentry();
/*
* The list of tags generated by the last findgtag() call.
*
* Use either pattern or line number.
* findgtag() always uses line number, so pattern is always NULL.
* findctag() usually either pattern (in which case line number is 0),
* or line number (in which case pattern is NULL).
*/
struct taglist {
struct tag *tl_first;
struct tag *tl_last;
};
#define TAG_END ((struct tag *) &taglist)
static struct taglist taglist = { TAG_END, TAG_END };
struct tag {
struct tag *next, *prev; /* List links */
char *tag_file; /* Source file containing the tag */
int tag_linenum; /* Appropriate line number in source file */
char *tag_pattern; /* Pattern used to find the tag */
char tag_endline; /* True if the pattern includes '$' */
};
static struct tag *curtag;
#define TAG_INS(tp) \
(tp)->next = taglist.tl_first; \
(tp)->prev = TAG_END; \
taglist.tl_first->prev = (tp); \
taglist.tl_first = (tp);
#define TAG_RM(tp) \
(tp)->next->prev = (tp)->prev; \
(tp)->prev->next = (tp)->next;
/*
* Delete tag structures.
*/
public void
cleantags()
{
register struct tag *tp;
/*
* Delete any existing tag list.
* {{ Ideally, we wouldn't do this until after we know that we
* can load some other tag information. }}
*/
while ((tp = taglist.tl_first) != TAG_END)
{
TAG_RM(tp);
free(tp);
}
curtag = NULL;
total = curseq = 0;
}
/*
* Create a new tag entry.
*/
static struct tag *
maketagent(name, file, linenum, pattern, endline)
char *name;
char *file;
int linenum;
char *pattern;
int endline;
{
register struct tag *tp;
tp = (struct tag *) ecalloc(sizeof(struct tag), 1);
tp->tag_file = (char *) ecalloc(strlen(file) + 1, sizeof(char));
strcpy(tp->tag_file, file);
tp->tag_linenum = linenum;
tp->tag_endline = endline;
if (pattern == NULL)
tp->tag_pattern = NULL;
else
{
tp->tag_pattern = (char *) ecalloc(strlen(pattern) + 1, sizeof(char));
strcpy(tp->tag_pattern, pattern);
}
return (tp);
}
/*
* Get tag mode.
*/
public int
gettagtype()
{
int f;
if (strcmp(tags, "GTAGS") == 0)
return T_GTAGS;
if (strcmp(tags, "GRTAGS") == 0)
return T_GRTAGS;
if (strcmp(tags, "GSYMS") == 0)
return T_GSYMS;
if (strcmp(tags, "GPATH") == 0)
return T_GPATH;
if (strcmp(tags, "-") == 0)
return T_CTAGS_X;
f = open(tags, OPEN_READ);
if (f >= 0)
{
close(f);
return T_CTAGS;
}
return T_GTAGS;
}
/*
* Find tags in tag file.
* Find a tag in the "tags" file.
* Sets "tagfile" to the name of the file containing the tag,
* Sets "tag_file" to the name of the file containing the tag,
* and "tagpattern" to the search pattern which should be used
* to find the tag.
*/
public void
findtag(tag)
register char *tag;
{
int type = gettagtype();
enum tag_result result;
if (type == T_CTAGS)
result = findctag(tag);
else
result = findgtag(tag, type);
switch (result)
{
case TAG_FOUND:
case TAG_INTR:
break;
case TAG_NOFILE:
error("No tags file", NULL_PARG);
break;
case TAG_NOTAG:
error("No such tag in tags file", NULL_PARG);
break;
case TAG_NOTYPE:
error("unknown tag type", NULL_PARG);
break;
}
}
/*
* Search for a tag.
*/
public POSITION
tagsearch()
{
if (curtag == NULL)
return (NULL_POSITION); /* No gtags loaded! */
if (curtag->tag_linenum != 0)
return gtagsearch();
else
return ctagsearch();
}
/*
* Go to the next tag.
*/
public char *
nexttag(n)
int n;
{
char *tagfile;
while (n-- > 0)
tagfile = nextgtag();
return tagfile;
}
/*
* Go to the previous tag.
*/
public char *
prevtag(n)
int n;
{
char *tagfile;
while (n-- > 0)
tagfile = prevgtag();
return tagfile;
}
/*
* Return the total number of tags.
*/
public int
ntags()
{
return total;
}
/*
* Return the sequence number of current tag.
*/
public int
curr_tag()
{
return curseq;
}
/*****************************************************************************
* ctags
*/
/*
* Find tags in the "tags" file.
* Sets curtag to the first tag entry.
*/
static enum tag_result
findctag(tag)
register char *tag;
{
char *p;
char *q;
register FILE *f;
register int taglen;
register int taglinenum;
char *tagfile;
char *tagpattern;
int tagendline;
int search_char;
int err;
char tline[TAGLINE_SIZE];
struct tag *tp;
p = unquote_file(tags);
f = fopen(p, "r");
free(p);
if (f == NULL)
{
error("No tags file", NULL_PARG);
tagfile = NULL;
return;
}
return TAG_NOFILE;
cleantags();
total = 0;
taglen = strlen(tag);
/*
@ -61,6 +295,9 @@ findtag(tag)
*/
while (fgets(tline, sizeof(tline), f) != NULL)
{
if (tline[0] == '!')
/* Skip header of extended format. */
continue;
if (strncmp(tag, tline, taglen) != 0 || !WHITESP(tline[taglen]))
continue;
@ -72,8 +309,7 @@ findtag(tag)
* or a search pattern surrounded by a pair of delimiters.
* Parse the line and extract these parts.
*/
tagfile = tagpattern = NULL;
taglinenum = 0;
tagpattern = NULL;
/*
* Skip over the whitespace after the tag name.
@ -95,7 +331,6 @@ findtag(tag)
if (*p == '\0')
/* Pattern is missing! */
continue;
tagfile = save(tagfile);
/*
* First see if it is a line number.
@ -113,39 +348,39 @@ findtag(tag)
search_char = *p++;
if (*p == '^')
p++;
tagpattern = (char *) ecalloc(strlen(p)+1, sizeof(char));
q = tagpattern;
tagpattern = p;
while (*p != search_char && *p != '\0')
{
if (*p == '\\')
p++;
*q++ = *p++;
p++;
}
tagendline = (q[-1] == '$');
tagendline = (p[-1] == '$');
if (tagendline)
q--;
*q = '\0';
p--;
*p = '\0';
}
fclose(f);
return;
tp = maketagent(tag, tagfile, taglinenum, tagpattern, tagendline);
TAG_INS(tp);
total++;
}
fclose(f);
error("No such tag in tags file", NULL_PARG);
tagfile = NULL;
if (total == 0)
return TAG_NOTAG;
curtag = taglist.tl_first;
curseq = 1;
return TAG_FOUND;
}
/*
* Edit current tagged file.
*/
public int
edit_tagfile()
{
int r;
if (tagfile == NULL)
if (curtag == NULL)
return (1);
r = edit(tagfile);
free(tagfile);
tagfile = NULL;
return (r);
return (edit(curtag->tag_file));
}
/*
@ -157,21 +392,14 @@ edit_tagfile()
* regcmp vs. re_comp) behave differently in the presence of
* parentheses (which are almost always found in a tag).
*/
public POSITION
tagsearch()
static POSITION
ctagsearch()
{
POSITION pos, linepos;
int linenum;
int len;
char *line;
/*
* If we have the line number of the tag instead of the pattern,
* just use find_pos.
*/
if (taglinenum)
return (find_pos(taglinenum));
pos = ch_zero();
linenum = find_linenum(pos);
@ -217,15 +445,311 @@ tagsearch()
* If tagendline is set, make sure we match all
* the way to end of line (no extra chars after the match).
*/
len = strlen(tagpattern);
if (strncmp(tagpattern, line, len) == 0 &&
(!tagendline || line[len] == '\0' || line[len] == '\r'))
len = strlen(curtag->tag_pattern);
if (strncmp(curtag->tag_pattern, line, len) == 0 &&
(!curtag->tag_endline || line[len] == '\0' || line[len] == '\r'))
{
curtag->tag_linenum = find_linenum(linepos);
break;
}
}
free(tagpattern);
tagpattern = NULL;
return (linepos);
}
/*******************************************************************************
* gtags
*/
/*
* Find tags in the GLOBAL's tag file.
* The findgtag() will try and load information about the requested tag.
* It does this by calling "global -x tag" and storing the parsed output
* for future use by gtagsearch().
* Sets curtag to the first tag entry.
*/
static enum tag_result
findgtag(tag, type)
char *tag; /* tag to load */
int type; /* tags type */
{
char buf[256];
FILE *fp;
struct tag *tp;
if (type != T_CTAGS_X && tag == NULL)
return TAG_NOFILE;
cleantags();
total = 0;
/*
* If type == T_CTAGS_X then read ctags's -x format from stdin
* else execute global(1) and read from it.
*/
if (type == T_CTAGS_X)
{
fp = stdin;
/* Set tag default because we cannot read stdin again. */
tags = "tags";
} else
{
#if !HAVE_POPEN
return TAG_NOFILE;
#else
char command[512];
char *flag;
char *cmd = lgetenv("LESSGLOBALTAGS");
if (cmd == NULL || *cmd == '\0')
return TAG_NOFILE;
/* Get suitable flag value for global(1). */
switch (type)
{
case T_GTAGS:
flag = "" ;
break;
case T_GRTAGS:
flag = "r";
break;
case T_GSYMS:
flag = "s";
break;
case T_GPATH:
flag = "P";
break;
default:
return TAG_NOTYPE;
}
/* Get our data from global(1). */
tag = esc_metachars(tag);
sprintf(command, "%s -x%s %s", cmd, flag, tag);
free(tag);
fp = popen(command, "r");
#endif
}
if (fp != NULL)
{
while (fgets(buf, sizeof(buf), fp))
{
char *name, *file, *line;
if (sigs)
{
#if HAVE_POPEN
if (fp != stdin)
pclose(fp);
#endif
return TAG_INTR;
}
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = 0;
else
{
int c;
do {
c = fgetc(fp);
} while (c != '\n' && c != EOF);
}
if (getentry(buf, &name, &file, &line))
{
/*
* Couldn't parse this line for some reason.
* We'll just pretend it never happened.
*/
break;
}
/* Make new entry and add to list. */
tp = maketagent(name, file, atoi(line), NULL, 0);
TAG_INS(tp);
total++;
}
if (fp != stdin)
{
if (pclose(fp))
{
curtag = NULL;
total = curseq = 0;
return TAG_NOFILE;
}
}
}
/* Check to see if we found anything. */
tp = taglist.tl_first;
if (tp == TAG_END)
return TAG_NOTAG;
curtag = tp;
curseq = 1;
return TAG_FOUND;
}
static int circular = 0; /* 1: circular tag structure */
/*
* Return the filename required for the next gtag in the queue that was setup
* by findgtag(). The next call to gtagsearch() will try to position at the
* appropriate tag.
*/
static char *
nextgtag()
{
struct tag *tp;
if (curtag == NULL)
/* No tag loaded */
return NULL;
tp = curtag->next;
if (tp == TAG_END)
{
if (!circular)
return NULL;
/* Wrapped around to the head of the queue */
curtag = taglist.tl_first;
curseq = 1;
} else
{
curtag = tp;
curseq++;
}
return (curtag->tag_file);
}
/*
* Return the filename required for the previous gtag in the queue that was
* setup by findgtat(). The next call to gtagsearch() will try to position
* at the appropriate tag.
*/
static char *
prevgtag()
{
struct tag *tp;
if (curtag == NULL)
/* No tag loaded */
return NULL;
tp = curtag->prev;
if (tp == TAG_END)
{
if (!circular)
return NULL;
/* Wrapped around to the tail of the queue */
curtag = taglist.tl_last;
curseq = total;
} else
{
curtag = tp;
curseq--;
}
return (curtag->tag_file);
}
/*
* Position the current file at at what is hopefully the tag that was chosen
* using either findtag() or one of nextgtag() and prevgtag(). Returns -1
* if it was unable to position at the tag, 0 if succesful.
*/
static POSITION
gtagsearch()
{
if (curtag == NULL)
return (NULL_POSITION); /* No gtags loaded! */
return (find_pos(curtag->tag_linenum));
}
/*
* The getentry() parses both standard and extended ctags -x format.
*
* [standard format]
* <tag> <lineno> <file> <image>
* +------------------------------------------------
* |main 30 main.c main(argc, argv)
* |func 21 subr.c func(arg)
*
* The following commands write this format.
* o Traditinal Ctags with -x option
* o Global with -x option
* See <http://www.gnu.org/software/global/global.html>
*
* [extended format]
* <tag> <type> <lineno> <file> <image>
* +----------------------------------------------------------
* |main function 30 main.c main(argc, argv)
* |func function 21 subr.c func(arg)
*
* The following commands write this format.
* o Exuberant Ctags with -x option
* See <http://ctags.sourceforge.net>
*
* Returns 0 on success, -1 on error.
* The tag, file, and line will each be NUL-terminated pointers
* into buf.
*/
#ifndef isspace
#define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r' || (c) == '\f')
#endif
#ifndef isdigit
#define isdigit(c) ((c) >= '0' && (c <= '9'))
#endif
static int
getentry(buf, tag, file, line)
char *buf; /* standard or extended ctags -x format data */
char **tag; /* name of the tag we actually found */
char **file; /* file in which to find this tag */
char **line; /* line number of file where this tag is found */
{
char *p = buf;
for (*tag = p; *p && !isspace(*p); p++) /* tag name */
;
if (*p == 0)
return (-1);
*p++ = 0;
for ( ; *p && isspace(*p); p++) /* (skip blanks) */
;
if (*p == 0)
return (-1);
/*
* If the second part begin with other than digit,
* it is assumed tag type. Skip it.
*/
if (!isdigit(*p))
{
for ( ; *p && !isspace(*p); p++) /* (skip tag type) */
;
for (; *p && isspace(*p); p++) /* (skip blanks) */
;
}
if (!isdigit(*p))
return (-1);
*line = p; /* line number */
for (*line = p; *p && !isspace(*p); p++)
;
if (*p == 0)
return (-1);
*p++ = 0;
for ( ; *p && isspace(*p); p++) /* (skip blanks) */
;
if (*p == 0)
return (-1);
*file = p; /* file name */
for (*file = p; *p && !isspace(*p); p++)
;
if (*p == 0)
return (-1);
*p = 0;
/* value check */
if (strlen(*tag) && strlen(*line) && strlen(*file) && atoi(*line) > 0)
return (0);
return (-1);
}
#endif

View File

@ -14,6 +14,10 @@
*/
#include "less.h"
#if OS2
#include "cmd.h"
#include "pckeys.h"
#endif
#if MSDOS_COMPILER==WIN32C
#include "windows.h"
extern char WIN32getch();
@ -42,7 +46,7 @@ open_getchr()
/* Make sure we get Ctrl+C events. */
SetConsoleMode((HANDLE)tty, ENABLE_PROCESSED_INPUT);
#else
#if MSDOS_COMPILER || OS2
#if MSDOS_COMPILER
extern int fd0;
/*
* Open a new handle to CON: in binary mode
@ -65,7 +69,12 @@ open_getchr()
* which in Unix is usually attached to the screen,
* but also usually lets you read from the keyboard.
*/
#if OS2
/* The __open() system call translates "/dev/tty" to "con". */
tty = __open("/dev/tty", OPEN_READ);
#else
tty = open("/dev/tty", OPEN_READ);
#endif
if (tty < 0)
tty = 2;
#endif
@ -110,30 +119,6 @@ getchr()
result = 1;
if (c == '\003')
return (READ_INTR);
#else
#if OS2
{
static int scan = -1;
flush();
if (scan >= 0)
{
c = scan;
scan = -1;
} else
{
if ((c = _read_kbd(0, 1, 0)) == -1)
return (READ_INTR);
if (c == '\0')
{
/*
* Zero is usually followed by another byte,
* since certain keys send two bytes.
*/
scan = _read_kbd(0, 0, 0);
}
}
result = 1;
}
#else
result = iread(tty, &c, sizeof(char));
if (result == READ_INTR)
@ -146,7 +131,6 @@ getchr()
*/
quit(QUIT_ERROR);
}
#endif
#endif
/*
* Various parts of the program cannot handle

View File

@ -600,6 +600,31 @@ v356 7/5/00 Add -J option.
v357 7/6/00 Support sigprocmask.
-----------------------------------------------------------------
v358 7/8/00 Fix problems with #stop in lesskey file.
Posted to Web page.
-----------------------------------------------------------------
v359 9/10/00 Fixes for Win32 display problems (thanks to Maurizio Vairani).
v360 1/17/01 Move sysless to etc.
v361 12/4/01 Add IBM-1047 charset & EBCDIC fixes (thanks to Thomas Dorner).
Fix 32 bit dependencies (thanks to Paul Eggert).
Fix UTF-8 overstriking (thanks to Robert Brady).
v362 12/4/01 Make status column show search targets.
v363 12/6/01 Add --no-keypad option.
Add variable width tabstops (thanks to Peter Samuelson).
v364 12/10/01 Better handling of very long lines in input;
Fix horizontal shifting of colored text.
v365 12/11/01 Fix overstriking of tabs;
Add support for global(1) and multiple tag matches
(thanks to Shigio Yamaguchi and Tim Vanderhoek).
v366 12/11/01 Fixes for OS/2 (thanks to Kyosuke Tokoro).
v367 12/13/01 Allow -D and -x options to terminate without dollar sign;
Right/left arrow when entering N are shift cmds, not line edit.
v368 12/18/01 Update lesskey commands.
v370 12/23/01 Fix tags error messages.
Posted to Web page.
-----------------------------------------------------------------
v371 12/26/01 Fix new_file bug; use popen in Windows version;
fix some compiler warnings.
*/
char version[] = "358";
char version[] = "371";