| CARVIEW |
Select Language
HTTP/1.1 200 OK
Date: Sat, 03 Jan 2026 10:07:18 GMT
Server: Apache/2.4.66 (Unix) OpenSSL/3.5.4
Last-Modified: Wed, 04 Feb 2004 06:31:20 GMT
ETag: "408de-3d280f77dde00"
Accept-Ranges: bytes
Content-Length: 264414
Content-Type: application/x-tar
Content-Encoding: x-gzip
less-382/ 0040775 0000764 0000764 00000000000 10010076276 011355 5 ustar markn markn less-382/main.c 0100444 0000764 0000764 00000016765 10010075213 012443 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Entry point, initialization, miscellaneous routines.
*/
#include "less.h"
#if MSDOS_COMPILER==WIN32C
#include
#endif
public char * every_first_cmd = NULL;
public int new_file;
public int is_tty;
public IFILE curr_ifile = NULL_IFILE;
public IFILE old_ifile = NULL_IFILE;
public struct scrpos initial_scrpos;
public int any_display = FALSE;
public POSITION start_attnpos = NULL_POSITION;
public POSITION end_attnpos = NULL_POSITION;
public int wscroll;
public char * progname;
public int quitting;
public int secure;
public int dohelp;
#if LOGFILE
public int logfile = -1;
public int force_logfile = FALSE;
public char * namelogfile = NULL;
#endif
#if EDITOR
public char * editor;
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;
/*
* Entry point.
*/
int
main(argc, argv)
int argc;
char *argv[];
{
IFILE ifile;
char *s;
#ifdef __EMX__
_response(&argc, &argv);
_wildcard(&argc, &argv);
#endif
progname = *argv++;
argc--;
secure = 0;
s = lgetenv("LESSSECURE");
if (s != NULL && *s != '\0')
secure = 1;
#ifdef WIN32
if (getenv("HOME") == NULL)
{
/*
* If there is no HOME environment variable,
* try the concatenation of HOMEDRIVE + HOMEPATH.
*/
char *drive = getenv("HOMEDRIVE");
char *path = getenv("HOMEPATH");
if (drive != NULL && path != NULL)
{
char *env = (char *) ecalloc(strlen(drive) +
strlen(path) + 6, sizeof(char));
strcpy(env, "HOME=");
strcat(env, drive);
strcat(env, path);
putenv(env);
}
}
GetConsoleTitle(consoleTitle, sizeof(consoleTitle)/sizeof(char));
#endif /* WIN32 */
/*
* Process command line arguments and LESS environment arguments.
* Command line arguments override environment arguments.
*/
is_tty = isatty(1);
get_term();
init_cmds();
init_prompt();
init_charset();
init_line();
init_option();
s = lgetenv("LESS");
if (s != NULL)
scan_option(save(s));
#define isoptstring(s) (((s)[0] == '-' || (s)[0] == '+') && (s)[1] != '\0')
while (argc > 0 && (isoptstring(*argv) || isoptpending()))
{
s = *argv++;
argc--;
if (strcmp(s, "--") == 0)
break;
scan_option(s);
}
#undef isoptstring
if (isoptpending())
{
/*
* Last command line option was a flag requiring a
* following string, but there was no following string.
*/
nopendopt();
quit(QUIT_OK);
}
#if EDITOR
editor = lgetenv("VISUAL");
if (editor == NULL || *editor == '\0')
{
editor = lgetenv("EDITOR");
if (editor == NULL || *editor == '\0')
editor = EDIT_PGM;
}
editproto = lgetenv("LESSEDIT");
if (editproto == NULL || *editproto == '\0')
editproto = "%E ?lm+%lm. %f";
#endif
/*
* Call get_ifile with all the command line filenames
* to "register" them with the ifile system.
*/
ifile = NULL_IFILE;
if (dohelp)
ifile = get_ifile(FAKE_HELPFILE, ifile);
while (argc-- > 0)
{
char *filename;
#if (MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC)
/*
* Because the "shell" doesn't expand filename patterns,
* treat each argument as a filename pattern rather than
* a single filename.
* Expand the pattern and iterate over the expanded list.
*/
struct textlist tlist;
char *gfilename;
gfilename = lglob(*argv++);
init_textlist(&tlist, gfilename);
filename = NULL;
while ((filename = forw_textlist(&tlist, filename)) != NULL)
{
(void) get_ifile(filename, ifile);
ifile = prev_ifile(NULL_IFILE);
}
free(gfilename);
#else
filename = shell_quote(*argv);
if (filename == NULL)
filename = *argv;
argv++;
(void) get_ifile(filename, ifile);
ifile = prev_ifile(NULL_IFILE);
#endif
}
/*
* Set up terminal, etc.
*/
if (!is_tty)
{
/*
* Output is not a tty.
* Just copy the input file(s) to output.
*/
SET_BINARY(1);
if (nifile() == 0)
{
if (edit_stdin() == 0)
cat_file();
} else if (edit_first() == 0)
{
do {
cat_file();
} while (edit_next(1) == 0);
}
quit(QUIT_OK);
}
if (missing_cap && !know_dumb)
error("WARNING: terminal is not fully functional", NULL_PARG);
init_mark();
open_getchr();
raw_mode(1);
init_signals(1);
/*
* Select the first file to examine.
*/
#if TAGS
if (tagoption != NULL || strcmp(tags, "-") == 0)
{
/*
* A -t option was given.
* Verify that no filenames were also given.
* Edit the file selected by the "tags" search,
* and search for the proper line in the file.
*/
if (nifile() > 0)
{
error("No filenames allowed with -t option", NULL_PARG);
quit(QUIT_ERROR);
}
findtag(tagoption);
if (edit_tagfile()) /* Edit file which contains the tag */
quit(QUIT_ERROR);
/*
* Search for the line which contains the tag.
* Set up initial_scrpos so we display that line.
*/
initial_scrpos.pos = tagsearch();
if (initial_scrpos.pos == NULL_POSITION)
quit(QUIT_ERROR);
initial_scrpos.ln = jump_sline;
} else
#endif
if (nifile() == 0)
{
if (edit_stdin()) /* Edit standard input */
quit(QUIT_ERROR);
} else
{
if (edit_first()) /* Edit first valid file in cmd line */
quit(QUIT_ERROR);
}
init();
commands();
quit(QUIT_OK);
/*NOTREACHED*/
return (0);
}
/*
* Copy a string to a "safe" place
* (that is, to a buffer allocated by calloc).
*/
public char *
save(s)
char *s;
{
register char *p;
p = (char *) ecalloc(strlen(s)+1, sizeof(char));
strcpy(p, s);
return (p);
}
/*
* Allocate memory.
* Like calloc(), but never returns an error (NULL).
*/
public VOID_POINTER
ecalloc(count, size)
int count;
unsigned int size;
{
register VOID_POINTER p;
p = (VOID_POINTER) calloc(count, size);
if (p != NULL)
return (p);
error("Cannot allocate memory", NULL_PARG);
quit(QUIT_ERROR);
/*NOTREACHED*/
return (NULL);
}
/*
* Skip leading spaces in a string.
*/
public char *
skipsp(s)
register char *s;
{
while (*s == ' ' || *s == '\t')
s++;
return (s);
}
/*
* See how many characters of two strings are identical.
* If uppercase is true, the first string must begin with an uppercase
* character; the remainder of the first string may be either case.
*/
public int
sprefix(ps, s, uppercase)
char *ps;
char *s;
int uppercase;
{
register int c;
register int sc;
register int len = 0;
for ( ; *s != '\0'; s++, ps++)
{
c = *ps;
if (uppercase)
{
if (len == 0 && SIMPLE_IS_LOWER(c))
return (-1);
if (SIMPLE_IS_UPPER(c))
c = SIMPLE_TO_LOWER(c);
}
sc = *s;
if (len > 0 && SIMPLE_IS_UPPER(sc))
sc = SIMPLE_TO_LOWER(sc);
if (c != sc)
break;
len++;
}
return (len);
}
/*
* Exit the program.
*/
public void
quit(status)
int status;
{
static int save_status;
/*
* Put cursor at bottom left corner, clear the line,
* reset the terminal modes, and exit.
*/
if (status < 0)
status = save_status;
else
save_status = status;
quitting = 1;
edit((char*)NULL);
if (any_display && is_tty)
clear_bot();
deinit();
flush();
raw_mode(0);
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
/*
* If we don't close 2, we get some garbage from
* 2's buffer when it flushes automatically.
* I cannot track this one down RB
* The same bug shows up if we use ^C^C to abort.
*/
close(2);
#endif
#if WIN32
SetConsoleTitle(consoleTitle);
#endif
close_getchr();
exit(status);
}
less-382/screen.c 0100444 0000764 0000764 00000135630 10010075213 012767 0 ustar markn markn /*
* Copyright (C) 1984-2002 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines which deal with the characteristics of the terminal.
* Uses termcap to be as terminal-independent as possible.
*/
#include "less.h"
#include "cmd.h"
#if MSDOS_COMPILER
#include "pckeys.h"
#if MSDOS_COMPILER==MSOFTC
#include
#else
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
#include
#if MSDOS_COMPILER==DJGPPC
#include
extern int fd0;
#endif
#else
#if MSDOS_COMPILER==WIN32C
#include
#endif
#endif
#endif
#include
#else
#if HAVE_TERMIOS_H && HAVE_TERMIOS_FUNCS
#include
#if HAVE_SYS_IOCTL_H && !defined(TIOCGWINSZ)
#include
#endif
#else
#if HAVE_TERMIO_H
#include
#else
#if HAVE_SGSTAT_H
#include
#else
#include
#endif
#if HAVE_SYS_IOCTL_H && (defined(TIOCGWINSZ) || defined(TCGETA) || defined(TIOCGETP) || defined(WIOCGETD))
#include
#endif
#endif
#endif
#if HAVE_TERMCAP_H
#include
#endif
#ifdef _OSK
#include
#endif
#if OS2
#include
#include "pckeys.h"
#endif
#if HAVE_SYS_STREAM_H
#include
#endif
#if HAVE_SYS_PTEM_H
#include
#endif
#endif /* MSDOS_COMPILER */
/*
* Check for broken termios package that forces you to manually
* set the line discipline.
*/
#ifdef __ultrix__
#define MUST_SET_LINE_DISCIPLINE 1
#else
#define MUST_SET_LINE_DISCIPLINE 0
#endif
#if OS2
#define DEFAULT_TERM "ansi"
static char *windowid;
#else
#define DEFAULT_TERM "unknown"
#endif
#if MSDOS_COMPILER==MSOFTC
static int videopages;
static long msec_loops;
static int flash_created = 0;
#define SETCOLORS(fg,bg) { _settextcolor(fg); _setbkcolor(bg); }
#endif
#if MSDOS_COMPILER==BORLANDC
static unsigned short *whitescreen;
static int flash_created = 0;
#endif
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
#define _settextposition(y,x) gotoxy(x,y)
#define _clearscreen(m) clrscr()
#define _outtext(s) cputs(s)
#define SETCOLORS(fg,bg) { textcolor(fg); textbackground(bg); }
extern int sc_height;
#endif
#if MSDOS_COMPILER==WIN32C
struct keyRecord
{
int ascii;
int scan;
} currentKey;
static int keyCount = 0;
static WORD curr_attr;
static int pending_scancode = 0;
static WORD *whitescreen;
static HANDLE con_out_save = INVALID_HANDLE_VALUE; /* previous console */
static HANDLE con_out_ours = INVALID_HANDLE_VALUE; /* our own */
HANDLE con_out = INVALID_HANDLE_VALUE; /* current console */
extern int quitting;
static void win32_init_term();
static void win32_deinit_term();
#define FG_COLORS (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY)
#define BG_COLORS (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY)
#define MAKEATTR(fg,bg) ((WORD)((fg)|((bg)<<4)))
#define SETCOLORS(fg,bg) { curr_attr = MAKEATTR(fg,bg); \
if (SetConsoleTextAttribute(con_out, curr_attr) == 0) \
error("SETCOLORS failed"); }
#endif
#if MSDOS_COMPILER
public int nm_fg_color; /* Color of normal text */
public int nm_bg_color;
public int bo_fg_color; /* Color of bold text */
public int bo_bg_color;
public int ul_fg_color; /* Color of underlined text */
public int ul_bg_color;
public int so_fg_color; /* Color of standout text */
public int so_bg_color;
public int bl_fg_color; /* Color of blinking text */
public int bl_bg_color;
static int sy_fg_color; /* Color of system text (before less) */
static int sy_bg_color;
#else
/*
* Strings passed to tputs() to do various terminal functions.
*/
static char
*sc_pad, /* Pad string */
*sc_home, /* Cursor home */
*sc_addline, /* Add line, scroll down following lines */
*sc_lower_left, /* Cursor to last line, first column */
*sc_move, /* General cursor positioning */
*sc_clear, /* Clear screen */
*sc_eol_clear, /* Clear to end of line */
*sc_eos_clear, /* Clear to end of screen */
*sc_s_in, /* Enter standout (highlighted) mode */
*sc_s_out, /* Exit standout mode */
*sc_u_in, /* Enter underline mode */
*sc_u_out, /* Exit underline mode */
*sc_b_in, /* Enter bold mode */
*sc_b_out, /* Exit bold mode */
*sc_bl_in, /* Enter blink mode */
*sc_bl_out, /* Exit blink mode */
*sc_visual_bell, /* Visual bell (flash screen) sequence */
*sc_backspace, /* Backspace cursor */
*sc_s_keypad, /* Start keypad mode */
*sc_e_keypad, /* End keypad mode */
*sc_init, /* Startup terminal initialization */
*sc_deinit; /* Exit terminal de-initialization */
#endif
static int init_done = 0;
public int auto_wrap; /* Terminal does \r\n when write past margin */
public int ignaw; /* Terminal ignores \n immediately after wrap */
public int erase_char, kill_char; /* The user's erase and line-kill chars */
public int werase_char; /* The user's word-erase char */
public int sc_width, sc_height; /* Height & width of screen */
public int bo_s_width, bo_e_width; /* Printing width of boldface seq */
public int ul_s_width, ul_e_width; /* Printing width of underline seq */
public int so_s_width, so_e_width; /* Printing width of standout seq */
public int bl_s_width, bl_e_width; /* Printing width of blink seq */
public int above_mem, below_mem; /* Memory retained above/below screen */
public int can_goto_line; /* Can move cursor to any line */
public int clear_bg; /* Clear fills with background color */
public int missing_cap = 0; /* Some capability is missing */
static int attrmode = AT_NORMAL;
#if !MSDOS_COMPILER
static char *cheaper();
static void tmodes();
#endif
/*
* These two variables are sometimes defined in,
* and needed by, the termcap library.
*/
#if MUST_DEFINE_OSPEED
extern short ospeed; /* Terminal output baud rate */
extern char PC; /* Pad character */
#endif
#ifdef _OSK
short ospeed;
char PC_, *UP, *BC;
#endif
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;
extern int tty;
#if HILITE_SEARCH
extern int hilite_search;
#endif
extern char *tgetstr();
extern char *tgoto();
/*
* Change terminal to "raw mode", or restore to "normal" mode.
* "Raw mode" means
* 1. An outstanding read will complete on receipt of a single keystroke.
* 2. Input is not echoed.
* 3. On output, \n is mapped to \r\n.
* 4. \t is NOT expanded into spaces.
* 5. Signal-causing characters such as ctrl-C (interrupt),
* etc. are NOT disabled.
* It doesn't matter whether an input \n is mapped to \r, or vice versa.
*/
public void
raw_mode(on)
int on;
{
static int curr_on = 0;
if (on == curr_on)
return;
#if HAVE_TERMIOS_H && HAVE_TERMIOS_FUNCS
{
struct termios s;
static struct termios save_term;
static int saved_term = 0;
if (on)
{
/*
* Get terminal modes.
*/
tcgetattr(tty, &s);
/*
* Save modes and set certain variables dependent on modes.
*/
if (!saved_term)
{
save_term = s;
saved_term = 1;
}
#if HAVE_OSPEED
switch (cfgetospeed(&s))
{
#ifdef B0
case B0: ospeed = 0; break;
#endif
#ifdef B50
case B50: ospeed = 1; break;
#endif
#ifdef B75
case B75: ospeed = 2; break;
#endif
#ifdef B110
case B110: ospeed = 3; break;
#endif
#ifdef B134
case B134: ospeed = 4; break;
#endif
#ifdef B150
case B150: ospeed = 5; break;
#endif
#ifdef B200
case B200: ospeed = 6; break;
#endif
#ifdef B300
case B300: ospeed = 7; break;
#endif
#ifdef B600
case B600: ospeed = 8; break;
#endif
#ifdef B1200
case B1200: ospeed = 9; break;
#endif
#ifdef B1800
case B1800: ospeed = 10; break;
#endif
#ifdef B2400
case B2400: ospeed = 11; break;
#endif
#ifdef B4800
case B4800: ospeed = 12; break;
#endif
#ifdef B9600
case B9600: ospeed = 13; break;
#endif
#ifdef EXTA
case EXTA: ospeed = 14; break;
#endif
#ifdef EXTB
case EXTB: ospeed = 15; break;
#endif
#ifdef B57600
case B57600: ospeed = 16; break;
#endif
#ifdef B115200
case B115200: ospeed = 17; break;
#endif
default: ;
}
#endif
erase_char = s.c_cc[VERASE];
kill_char = s.c_cc[VKILL];
#ifdef VWERASE
werase_char = s.c_cc[VWERASE];
#else
werase_char = CONTROL('W');
#endif
/*
* Set the modes to the way we want them.
*/
s.c_lflag &= ~(0
#ifdef ICANON
| ICANON
#endif
#ifdef ECHO
| ECHO
#endif
#ifdef ECHOE
| ECHOE
#endif
#ifdef ECHOK
| ECHOK
#endif
#if ECHONL
| ECHONL
#endif
);
s.c_oflag |= (0
#ifdef OXTABS
| OXTABS
#else
#ifdef TAB3
| TAB3
#else
#ifdef XTABS
| XTABS
#endif
#endif
#endif
#ifdef OPOST
| OPOST
#endif
#ifdef ONLCR
| ONLCR
#endif
);
s.c_oflag &= ~(0
#ifdef ONOEOT
| ONOEOT
#endif
#ifdef OCRNL
| OCRNL
#endif
#ifdef ONOCR
| ONOCR
#endif
#ifdef ONLRET
| ONLRET
#endif
);
s.c_cc[VMIN] = 1;
s.c_cc[VTIME] = 0;
#ifdef VLNEXT
s.c_cc[VLNEXT] = 0;
#endif
#ifdef VDSUSP
s.c_cc[VDSUSP] = 0;
#endif
#if MUST_SET_LINE_DISCIPLINE
/*
* System's termios is broken; need to explicitly
* request TERMIODISC line discipline.
*/
s.c_line = TERMIODISC;
#endif
} else
{
/*
* Restore saved modes.
*/
s = save_term;
}
#if HAVE_FSYNC
fsync(tty);
#endif
tcsetattr(tty, TCSADRAIN, &s);
#if MUST_SET_LINE_DISCIPLINE
if (!on)
{
/*
* Broken termios *ignores* any line discipline
* except TERMIODISC. A different old line discipline
* is therefore not restored, yet. Restore the old
* line discipline by hand.
*/
ioctl(tty, TIOCSETD, &save_term.c_line);
}
#endif
}
#else
#ifdef TCGETA
{
struct termio s;
static struct termio save_term;
static int saved_term = 0;
if (on)
{
/*
* Get terminal modes.
*/
ioctl(tty, TCGETA, &s);
/*
* Save modes and set certain variables dependent on modes.
*/
if (!saved_term)
{
save_term = s;
saved_term = 1;
}
#if HAVE_OSPEED
ospeed = s.c_cflag & CBAUD;
#endif
erase_char = s.c_cc[VERASE];
kill_char = s.c_cc[VKILL];
#ifdef VWERASE
werase_char = s.c_cc[VWERASE];
#else
werase_char = CONTROL('W');
#endif
/*
* Set the modes to the way we want them.
*/
s.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
s.c_oflag |= (OPOST|ONLCR|TAB3);
s.c_oflag &= ~(OCRNL|ONOCR|ONLRET);
s.c_cc[VMIN] = 1;
s.c_cc[VTIME] = 0;
} else
{
/*
* Restore saved modes.
*/
s = save_term;
}
ioctl(tty, TCSETAW, &s);
}
#else
#ifdef TIOCGETP
{
struct sgttyb s;
static struct sgttyb save_term;
static int saved_term = 0;
if (on)
{
/*
* Get terminal modes.
*/
ioctl(tty, TIOCGETP, &s);
/*
* Save modes and set certain variables dependent on modes.
*/
if (!saved_term)
{
save_term = s;
saved_term = 1;
}
#if HAVE_OSPEED
ospeed = s.sg_ospeed;
#endif
erase_char = s.sg_erase;
kill_char = s.sg_kill;
werase_char = CONTROL('W');
/*
* Set the modes to the way we want them.
*/
s.sg_flags |= CBREAK;
s.sg_flags &= ~(ECHO|XTABS);
} else
{
/*
* Restore saved modes.
*/
s = save_term;
}
ioctl(tty, TIOCSETN, &s);
}
#else
#ifdef _OSK
{
struct sgbuf s;
static struct sgbuf save_term;
static int saved_term = 0;
if (on)
{
/*
* Get terminal modes.
*/
_gs_opt(tty, &s);
/*
* Save modes and set certain variables dependent on modes.
*/
if (!saved_term)
{
save_term = s;
saved_term = 1;
}
erase_char = s.sg_bspch;
kill_char = s.sg_dlnch;
werase_char = CONTROL('W');
/*
* Set the modes to the way we want them.
*/
s.sg_echo = 0;
s.sg_eofch = 0;
s.sg_pause = 0;
s.sg_psch = 0;
} else
{
/*
* Restore saved modes.
*/
s = save_term;
}
_ss_opt(tty, &s);
}
#else
/* MS-DOS, Windows, or OS2 */
#if OS2
/* OS2 */
LSIGNAL(SIGINT, SIG_IGN);
#endif
erase_char = '\b';
#if MSDOS_COMPILER==DJGPPC
kill_char = CONTROL('U');
/*
* So that when we shell out or run another program, its
* stdin is in cooked mode. We do not switch stdin to binary
* mode if fd0 is zero, since that means we were called before
* tty was reopened in open_getchr, in which case we would be
* changing the original stdin device outside less.
*/
if (fd0 != 0)
setmode(0, on ? O_BINARY : O_TEXT);
#else
kill_char = ESC;
#endif
werase_char = CONTROL('W');
#endif
#endif
#endif
#endif
curr_on = on;
}
#if !MSDOS_COMPILER
/*
* Some glue to prevent calling termcap functions if tgetent() failed.
*/
static int hardcopy;
static char *
ltget_env(capname)
char *capname;
{
char name[16];
strcpy(name, "LESS_TERMCAP_");
strcat(name, capname);
return (lgetenv(name));
}
static int
ltgetflag(capname)
char *capname;
{
char *s;
if ((s = ltget_env(capname)) != NULL)
return (*s != '\0' && *s != '0');
if (hardcopy)
return (0);
return (tgetflag(capname));
}
static int
ltgetnum(capname)
char *capname;
{
char *s;
if ((s = ltget_env(capname)) != NULL)
return (atoi(s));
if (hardcopy)
return (-1);
return (tgetnum(capname));
}
static char *
ltgetstr(capname, pp)
char *capname;
char **pp;
{
char *s;
if ((s = ltget_env(capname)) != NULL)
return (s);
if (hardcopy)
return (NULL);
return (tgetstr(capname, pp));
}
#endif /* MSDOS_COMPILER */
/*
* Get size of the output screen.
*/
public void
scrsize()
{
register char *s;
int sys_height;
int sys_width;
#if !MSDOS_COMPILER
int n;
#endif
#define DEF_SC_WIDTH 80
#if MSDOS_COMPILER
#define DEF_SC_HEIGHT 25
#else
#define DEF_SC_HEIGHT 24
#endif
sys_width = sys_height = 0;
#if MSDOS_COMPILER==MSOFTC
{
struct videoconfig w;
_getvideoconfig(&w);
sys_height = w.numtextrows;
sys_width = w.numtextcols;
}
#else
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
{
struct text_info w;
gettextinfo(&w);
sys_height = w.screenheight;
sys_width = w.screenwidth;
}
#else
#if MSDOS_COMPILER==WIN32C
{
CONSOLE_SCREEN_BUFFER_INFO scr;
GetConsoleScreenBufferInfo(con_out, &scr);
sys_height = scr.srWindow.Bottom - scr.srWindow.Top + 1;
sys_width = scr.srWindow.Right - scr.srWindow.Left + 1;
}
#else
#if OS2
{
int s[2];
_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
{
struct winsize w;
if (ioctl(2, TIOCGWINSZ, &w) == 0)
{
if (w.ws_row > 0)
sys_height = w.ws_row;
if (w.ws_col > 0)
sys_width = w.ws_col;
}
}
#else
#ifdef WIOCGETD
{
struct uwdata w;
if (ioctl(2, WIOCGETD, &w) == 0)
{
if (w.uw_height > 0)
sys_height = w.uw_height / w.uw_vs;
if (w.uw_width > 0)
sys_width = w.uw_width / w.uw_hs;
}
}
#endif
#endif
#endif
#endif
#endif
#endif
if (sys_height > 0)
sc_height = sys_height;
else if ((s = lgetenv("LINES")) != NULL)
sc_height = atoi(s);
#if !MSDOS_COMPILER
else if ((n = ltgetnum("li")) > 0)
sc_height = n;
#endif
else
sc_height = DEF_SC_HEIGHT;
if (sys_width > 0)
sc_width = sys_width;
else if ((s = lgetenv("COLUMNS")) != NULL)
sc_width = atoi(s);
#if !MSDOS_COMPILER
else if ((n = ltgetnum("co")) > 0)
sc_width = n;
#endif
else
sc_width = DEF_SC_WIDTH;
}
#if MSDOS_COMPILER==MSOFTC
/*
* Figure out how many empty loops it takes to delay a millisecond.
*/
static void
get_clock()
{
clock_t start;
/*
* Get synchronized at the start of a tick.
*/
start = clock();
while (clock() == start)
;
/*
* Now count loops till the next tick.
*/
start = clock();
msec_loops = 0;
while (clock() == start)
msec_loops++;
/*
* Convert from (loops per clock) to (loops per millisecond).
*/
msec_loops *= CLOCKS_PER_SEC;
msec_loops /= 1000;
}
/*
* Delay for a specified number of milliseconds.
*/
static void
dummy_func()
{
static long delay_dummy = 0;
delay_dummy++;
}
static void
delay(msec)
int msec;
{
long i;
while (msec-- > 0)
{
for (i = 0; i < msec_loops; i++)
{
/*
* Make it look like we're doing something here,
* so the optimizer doesn't remove the whole loop.
*/
dummy_func();
}
}
}
#endif
/*
* Return the characters actually input by a "special" key.
*/
public char *
special_key_str(key)
int key;
{
static char tbuf[40];
char *s;
#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 };
static char k_ctl_left[] = { '\340', PCK_CTL_LEFT, 0 };
static char k_insert[] = { '\340', PCK_INSERT, 0 };
static char k_delete[] = { '\340', PCK_DELETE, 0 };
static char k_ctl_delete[] = { '\340', PCK_CTL_DELETE, 0 };
static char k_ctl_backspace[] = { '\177', 0 };
static char k_home[] = { '\340', PCK_HOME, 0 };
static char k_end[] = { '\340', PCK_END, 0 };
static char k_up[] = { '\340', PCK_UP, 0 };
static char k_down[] = { '\340', PCK_DOWN, 0 };
static char k_backtab[] = { '\340', PCK_SHIFT_TAB, 0 };
static char k_pagedown[] = { '\340', PCK_PAGEDOWN, 0 };
static char k_pageup[] = { '\340', PCK_PAGEUP, 0 };
static char k_f1[] = { '\340', PCK_F1, 0 };
#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;
break;
case SK_LEFT_ARROW:
s = k_left;
break;
case SK_UP_ARROW:
s = k_up;
break;
case SK_DOWN_ARROW:
s = k_down;
break;
case SK_PAGE_UP:
s = k_pageup;
break;
case SK_PAGE_DOWN:
s = k_pagedown;
break;
case SK_HOME:
s = k_home;
break;
case SK_END:
s = k_end;
break;
case SK_DELETE:
s = k_delete;
break;
#endif
#if MSDOS_COMPILER || OS2
case SK_INSERT:
s = k_insert;
break;
case SK_CTL_LEFT_ARROW:
s = k_ctl_left;
break;
case SK_CTL_RIGHT_ARROW:
s = k_ctl_right;
break;
case SK_CTL_BACKSPACE:
s = k_ctl_backspace;
break;
case SK_CTL_DELETE:
s = k_ctl_delete;
break;
case SK_F1:
s = k_f1;
break;
case SK_BACKTAB:
s = k_backtab;
break;
#else
case SK_RIGHT_ARROW:
s = ltgetstr("kr", &sp);
break;
case SK_LEFT_ARROW:
s = ltgetstr("kl", &sp);
break;
case SK_UP_ARROW:
s = ltgetstr("ku", &sp);
break;
case SK_DOWN_ARROW:
s = ltgetstr("kd", &sp);
break;
case SK_PAGE_UP:
s = ltgetstr("kP", &sp);
break;
case SK_PAGE_DOWN:
s = ltgetstr("kN", &sp);
break;
case SK_HOME:
s = ltgetstr("kh", &sp);
break;
case SK_END:
s = ltgetstr("@7", &sp);
break;
case SK_DELETE:
s = ltgetstr("kD", &sp);
if (s == NULL)
{
tbuf[0] = '\177';
tbuf[1] = '\0';
s = tbuf;
}
break;
#endif
case SK_CONTROL_K:
tbuf[0] = CONTROL('K');
tbuf[1] = '\0';
s = tbuf;
break;
default:
return (NULL);
}
return (s);
}
/*
* Get terminal capabilities via termcap.
*/
public void
get_term()
{
#if MSDOS_COMPILER
auto_wrap = 1;
ignaw = 0;
can_goto_line = 1;
clear_bg = 1;
/*
* Set up default colors.
* The xx_s_width and xx_e_width vars are already initialized to 0.
*/
#if MSDOS_COMPILER==MSOFTC
sy_bg_color = _getbkcolor();
sy_fg_color = _gettextcolor();
get_clock();
#else
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
{
struct text_info w;
gettextinfo(&w);
sy_bg_color = (w.attribute >> 4) & 0x0F;
sy_fg_color = (w.attribute >> 0) & 0x0F;
}
#else
#if MSDOS_COMPILER==WIN32C
{
DWORD nread;
CONSOLE_SCREEN_BUFFER_INFO scr;
con_out_save = con_out = GetStdHandle(STD_OUTPUT_HANDLE);
/*
* Always open stdin in binary. Note this *must* be done
* before any file operations have been done on fd0.
*/
SET_BINARY(0);
GetConsoleScreenBufferInfo(con_out, &scr);
ReadConsoleOutputAttribute(con_out, &curr_attr,
1, scr.dwCursorPosition, &nread);
sy_bg_color = (curr_attr & BG_COLORS) >> 4; /* normalize */
sy_fg_color = curr_attr & FG_COLORS;
}
#endif
#endif
#endif
nm_fg_color = sy_fg_color;
nm_bg_color = sy_bg_color;
bo_fg_color = 11;
bo_bg_color = 0;
ul_fg_color = 9;
ul_bg_color = 0;
so_fg_color = 15;
so_bg_color = 9;
bl_fg_color = 15;
bl_bg_color = 0;
/*
* Get size of the screen.
*/
scrsize();
pos_init();
#else /* !MSDOS_COMPILER */
char *sp;
register char *t1, *t2;
char *term;
char termbuf[TERMBUF_SIZE];
static char sbuf[TERMSBUF_SIZE];
#if OS2
/*
* Make sure the termcap database is available.
*/
sp = lgetenv("TERMCAP");
if (sp == NULL || *sp == '\0')
{
char *termcap;
if ((sp = homefile("termcap.dat")) != NULL)
{
termcap = (char *) ecalloc(strlen(sp)+9, sizeof(char));
sprintf(termcap, "TERMCAP=%s", sp);
free(sp);
putenv(termcap);
}
}
#endif
/*
* Find out what kind of terminal this is.
*/
if ((term = lgetenv("TERM")) == NULL)
term = DEFAULT_TERM;
hardcopy = 0;
if (tgetent(termbuf, term) <= 0)
hardcopy = 1;
if (ltgetflag("hc"))
hardcopy = 1;
/*
* Get size of the screen.
*/
scrsize();
pos_init();
auto_wrap = ltgetflag("am");
ignaw = ltgetflag("xn");
above_mem = ltgetflag("da");
below_mem = ltgetflag("db");
clear_bg = ltgetflag("ut");
/*
* Assumes termcap variable "sg" is the printing width of:
* the standout sequence, the end standout sequence,
* the underline sequence, the end underline sequence,
* the boldface sequence, and the end boldface sequence.
*/
if ((so_s_width = ltgetnum("sg")) < 0)
so_s_width = 0;
so_e_width = so_s_width;
bo_s_width = bo_e_width = so_s_width;
ul_s_width = ul_e_width = so_s_width;
bl_s_width = bl_e_width = so_s_width;
#if HILITE_SEARCH
if (so_s_width > 0 || so_e_width > 0)
/*
* Disable highlighting by default on magic cookie terminals.
* Turning on highlighting might change the displayed width
* of a line, causing the display to get messed up.
* The user can turn it back on with -g,
* but she won't like the results.
*/
hilite_search = 0;
#endif
/*
* Get various string-valued capabilities.
*/
sp = sbuf;
#if HAVE_OSPEED
sc_pad = ltgetstr("pc", &sp);
if (sc_pad != NULL)
PC = *sc_pad;
#endif
sc_s_keypad = ltgetstr("ks", &sp);
if (sc_s_keypad == NULL)
sc_s_keypad = "";
sc_e_keypad = ltgetstr("ke", &sp);
if (sc_e_keypad == NULL)
sc_e_keypad = "";
sc_init = ltgetstr("ti", &sp);
if (sc_init == NULL)
sc_init = "";
sc_deinit= ltgetstr("te", &sp);
if (sc_deinit == NULL)
sc_deinit = "";
sc_eol_clear = ltgetstr("ce", &sp);
if (sc_eol_clear == NULL || *sc_eol_clear == '\0')
{
missing_cap = 1;
sc_eol_clear = "";
}
sc_eos_clear = ltgetstr("cd", &sp);
if (below_mem && (sc_eos_clear == NULL || *sc_eos_clear == '\0'))
{
missing_cap = 1;
sc_eol_clear = "";
}
sc_clear = ltgetstr("cl", &sp);
if (sc_clear == NULL || *sc_clear == '\0')
{
missing_cap = 1;
sc_clear = "\n\n";
}
sc_move = ltgetstr("cm", &sp);
if (sc_move == NULL || *sc_move == '\0')
{
/*
* This is not an error here, because we don't
* always need sc_move.
* We need it only if we don't have home or lower-left.
*/
sc_move = "";
can_goto_line = 0;
} else
can_goto_line = 1;
tmodes("so", "se", &sc_s_in, &sc_s_out, "", "", &sp);
tmodes("us", "ue", &sc_u_in, &sc_u_out, sc_s_in, sc_s_out, &sp);
tmodes("md", "me", &sc_b_in, &sc_b_out, sc_s_in, sc_s_out, &sp);
tmodes("mb", "me", &sc_bl_in, &sc_bl_out, sc_s_in, sc_s_out, &sp);
sc_visual_bell = ltgetstr("vb", &sp);
if (sc_visual_bell == NULL)
sc_visual_bell = "";
if (ltgetflag("bs"))
sc_backspace = "\b";
else
{
sc_backspace = ltgetstr("bc", &sp);
if (sc_backspace == NULL || *sc_backspace == '\0')
sc_backspace = "\b";
}
/*
* Choose between using "ho" and "cm" ("home" and "cursor move")
* to move the cursor to the upper left corner of the screen.
*/
t1 = ltgetstr("ho", &sp);
if (t1 == NULL)
t1 = "";
if (*sc_move == '\0')
t2 = "";
else
{
strcpy(sp, tgoto(sc_move, 0, 0));
t2 = sp;
sp += strlen(sp) + 1;
}
sc_home = cheaper(t1, t2, "|\b^");
/*
* Choose between using "ll" and "cm" ("lower left" and "cursor move")
* to move the cursor to the lower left corner of the screen.
*/
t1 = ltgetstr("ll", &sp);
if (t1 == NULL)
t1 = "";
if (*sc_move == '\0')
t2 = "";
else
{
strcpy(sp, tgoto(sc_move, 0, sc_height-1));
t2 = sp;
sp += strlen(sp) + 1;
}
sc_lower_left = cheaper(t1, t2, "\r");
/*
* Choose between using "al" or "sr" ("add line" or "scroll reverse")
* to add a line at the top of the screen.
*/
t1 = ltgetstr("al", &sp);
if (t1 == NULL)
t1 = "";
t2 = ltgetstr("sr", &sp);
if (t2 == NULL)
t2 = "";
#if OS2
if (*t1 == '\0' && *t2 == '\0')
sc_addline = "";
else
#endif
if (above_mem)
sc_addline = t1;
else
sc_addline = cheaper(t1, t2, "");
if (*sc_addline == '\0')
{
/*
* Force repaint on any backward movement.
*/
no_back_scroll = 1;
}
#endif /* MSDOS_COMPILER */
}
#if !MSDOS_COMPILER
/*
* Return the cost of displaying a termcap string.
* We use the trick of calling tputs, but as a char printing function
* we give it inc_costcount, which just increments "costcount".
* This tells us how many chars would be printed by using this string.
* {{ Couldn't we just use strlen? }}
*/
static int costcount;
/*ARGSUSED*/
static int
inc_costcount(c)
int c;
{
costcount++;
return (c);
}
static int
cost(t)
char *t;
{
costcount = 0;
tputs(t, sc_height, inc_costcount);
return (costcount);
}
/*
* Return the "best" of the two given termcap strings.
* The best, if both exist, is the one with the lower
* cost (see cost() function).
*/
static char *
cheaper(t1, t2, def)
char *t1, *t2;
char *def;
{
if (*t1 == '\0' && *t2 == '\0')
{
missing_cap = 1;
return (def);
}
if (*t1 == '\0')
return (t2);
if (*t2 == '\0')
return (t1);
if (cost(t1) < cost(t2))
return (t1);
return (t2);
}
static void
tmodes(incap, outcap, instr, outstr, def_instr, def_outstr, spp)
char *incap;
char *outcap;
char **instr;
char **outstr;
char *def_instr;
char *def_outstr;
char **spp;
{
*instr = ltgetstr(incap, spp);
if (*instr == NULL)
{
/* Use defaults. */
*instr = def_instr;
*outstr = def_outstr;
return;
}
*outstr = ltgetstr(outcap, spp);
if (*outstr == NULL)
/* No specific out capability; use "me". */
*outstr = ltgetstr("me", spp);
if (*outstr == NULL)
/* Don't even have "me"; use a null string. */
*outstr = "";
}
#endif /* MSDOS_COMPILER */
/*
* Below are the functions which perform all the
* terminal-specific screen manipulation.
*/
#if MSDOS_COMPILER
#if MSDOS_COMPILER==WIN32C
static void
_settextposition(int row, int col)
{
COORD cpos;
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(con_out, &csbi);
cpos.X = csbi.srWindow.Left + (col - 1);
cpos.Y = csbi.srWindow.Top + (row - 1);
SetConsoleCursorPosition(con_out, cpos);
}
#endif
/*
* Initialize the screen to the correct color at startup.
*/
static void
initcolor()
{
SETCOLORS(nm_fg_color, nm_bg_color);
#if 0
/*
* This clears the screen at startup. This is different from
* the behavior of other versions of less. Disable it for now.
*/
char *blanks;
int row;
int col;
/*
* Create a complete, blank screen using "normal" colors.
*/
SETCOLORS(nm_fg_color, nm_bg_color);
blanks = (char *) ecalloc(width+1, sizeof(char));
for (col = 0; col < sc_width; col++)
blanks[col] = ' ';
blanks[sc_width] = '\0';
for (row = 0; row < sc_height; row++)
_outtext(blanks);
free(blanks);
#endif
}
#endif
#if MSDOS_COMPILER==WIN32C
/*
* Termcap-like init with a private win32 console.
*/
static void
win32_init_term()
{
CONSOLE_SCREEN_BUFFER_INFO scr;
COORD size;
if (con_out_save == INVALID_HANDLE_VALUE)
return;
GetConsoleScreenBufferInfo(con_out_save, &scr);
if (con_out_ours == INVALID_HANDLE_VALUE)
{
/*
* Create our own screen buffer, so that we
* may restore the original when done.
*/
con_out_ours = CreateConsoleScreenBuffer(
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE | FILE_SHARE_READ,
(LPSECURITY_ATTRIBUTES) NULL,
CONSOLE_TEXTMODE_BUFFER,
(LPVOID) NULL);
}
size.X = scr.srWindow.Right - scr.srWindow.Left + 1;
size.Y = scr.srWindow.Bottom - scr.srWindow.Top + 1;
SetConsoleScreenBufferSize(con_out_ours, size);
SetConsoleActiveScreenBuffer(con_out_ours);
con_out = con_out_ours;
}
/*
* Restore the startup console.
*/
static void
win32_deinit_term()
{
if (con_out_save == INVALID_HANDLE_VALUE)
return;
if (quitting)
(void) CloseHandle(con_out_ours);
SetConsoleActiveScreenBuffer(con_out_save);
con_out = con_out_save;
}
#endif
/*
* Initialize terminal
*/
public void
init()
{
#if !MSDOS_COMPILER
if (!no_init)
tputs(sc_init, sc_height, putchr);
if (!no_keypad)
tputs(sc_s_keypad, sc_height, putchr);
#else
#if MSDOS_COMPILER==WIN32C
if (!no_init)
win32_init_term();
#endif
initcolor();
flush();
#endif
init_done = 1;
}
/*
* Deinitialize terminal
*/
public void
deinit()
{
if (!init_done)
return;
#if !MSDOS_COMPILER
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
if (!no_init)
win32_deinit_term();
#else
/* Need clreol to make SETCOLORS take effect. */
clreol();
#endif
#endif
init_done = 0;
}
/*
* Home cursor (move to upper left corner of screen).
*/
public void
home()
{
#if !MSDOS_COMPILER
tputs(sc_home, 1, putchr);
#else
flush();
_settextposition(1,1);
#endif
}
/*
* Add a blank line (called with cursor at home).
* Should scroll the display down.
*/
public void
add_line()
{
#if !MSDOS_COMPILER
tputs(sc_addline, sc_height, putchr);
#else
flush();
#if MSDOS_COMPILER==MSOFTC
_scrolltextwindow(_GSCROLLDOWN);
_settextposition(1,1);
#else
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
movetext(1,1, sc_width,sc_height-1, 1,2);
gotoxy(1,1);
clreol();
#else
#if MSDOS_COMPILER==WIN32C
{
CHAR_INFO fillchar;
SMALL_RECT rcSrc, rcClip;
COORD new_org;
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(con_out,&csbi);
/* The clip rectangle is the entire visible screen. */
rcClip.Left = csbi.srWindow.Left;
rcClip.Top = csbi.srWindow.Top;
rcClip.Right = csbi.srWindow.Right;
rcClip.Bottom = csbi.srWindow.Bottom;
/* The source rectangle is the visible screen minus the last line. */
rcSrc = rcClip;
rcSrc.Bottom--;
/* Move the top left corner of the source window down one row. */
new_org.X = rcSrc.Left;
new_org.Y = rcSrc.Top + 1;
/* Fill the right character and attributes. */
fillchar.Char.AsciiChar = ' ';
curr_attr = MAKEATTR(nm_fg_color, nm_bg_color);
fillchar.Attributes = curr_attr;
ScrollConsoleScreenBuffer(con_out, &rcSrc, &rcClip, new_org, &fillchar);
_settextposition(1,1);
}
#endif
#endif
#endif
#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
* into the scrollback buffer when we go down-one-line (in WIN32).
*/
public void
remove_top(n)
int n;
{
#if MSDOS_COMPILER==WIN32C
SMALL_RECT rcSrc, rcClip;
CHAR_INFO fillchar;
COORD new_org;
CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */
if (n >= sc_height - 1)
{
clear();
home();
return;
}
flush();
GetConsoleScreenBufferInfo(con_out, &csbi);
/* Get the extent of all-visible-rows-but-the-last. */
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 window up n rows. */
new_org.X = rcSrc.Left;
new_org.Y = rcSrc.Top - n;
/* Fill the right character and attributes. */
fillchar.Char.AsciiChar = ' ';
curr_attr = MAKEATTR(nm_fg_color, nm_bg_color);
fillchar.Attributes = curr_attr;
ScrollConsoleScreenBuffer(con_out, &rcSrc, &rcClip, new_org, &fillchar);
/* Position cursor on first blank line. */
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.
*/
public void
lower_left()
{
#if !MSDOS_COMPILER
tputs(sc_lower_left, 1, putchr);
#else
flush();
_settextposition(sc_height, 1);
#endif
}
/*
* Check if the console size has changed and reset internals
* (in lieu of SIGWINCH for WIN32).
*/
public void
check_winch()
{
#if MSDOS_COMPILER==WIN32C
CONSOLE_SCREEN_BUFFER_INFO scr;
COORD size;
if (con_out == INVALID_HANDLE_VALUE)
return;
flush();
GetConsoleScreenBufferInfo(con_out, &scr);
size.Y = scr.srWindow.Bottom - scr.srWindow.Top + 1;
size.X = scr.srWindow.Right - scr.srWindow.Left + 1;
if (size.Y != sc_height || size.X != sc_width)
{
sc_height = size.Y;
sc_width = size.X;
if (!no_init && con_out_ours == con_out)
SetConsoleScreenBufferSize(con_out, size);
pos_init();
wscroll = (sc_height + 1) / 2;
screen_trashed = 1;
}
#endif
}
/*
* Goto a specific line on the screen.
*/
public void
goto_line(slinenum)
int slinenum;
{
#if !MSDOS_COMPILER
tputs(tgoto(sc_move, 0, slinenum), 1, putchr);
#else
flush();
_settextposition(slinenum+1, 1);
#endif
}
#if MSDOS_COMPILER==MSOFTC || MSDOS_COMPILER==BORLANDC
/*
* Create an alternate screen which is all white.
* This screen is used to create a "flash" effect, by displaying it
* briefly and then switching back to the normal screen.
* {{ Yuck! There must be a better way to get a visual bell. }}
*/
static void
create_flash()
{
#if MSDOS_COMPILER==MSOFTC
struct videoconfig w;
char *blanks;
int row, col;
_getvideoconfig(&w);
videopages = w.numvideopages;
if (videopages < 2)
{
so_enter();
so_exit();
} else
{
_setactivepage(1);
so_enter();
blanks = (char *) ecalloc(w.numtextcols, sizeof(char));
for (col = 0; col < w.numtextcols; col++)
blanks[col] = ' ';
for (row = w.numtextrows; row > 0; row--)
_outmem(blanks, w.numtextcols);
_setactivepage(0);
_setvisualpage(0);
free(blanks);
so_exit();
}
#else
#if MSDOS_COMPILER==BORLANDC
register int n;
whitescreen = (unsigned short *)
malloc(sc_width * sc_height * sizeof(short));
if (whitescreen == NULL)
return;
for (n = 0; n < sc_width * sc_height; n++)
whitescreen[n] = 0x7020;
#else
#if MSDOS_COMPILER==WIN32C
register int n;
whitescreen = (WORD *)
malloc(sc_height * sc_width * sizeof(WORD));
if (whitescreen == NULL)
return;
/* Invert the standard colors. */
for (n = 0; n < sc_width * sc_height; n++)
whitescreen[n] = (WORD)((nm_fg_color << 4) | nm_bg_color);
#endif
#endif
#endif
flash_created = 1;
}
#endif /* MSDOS_COMPILER */
/*
* Output the "visual bell", if there is one.
*/
public void
vbell()
{
#if !MSDOS_COMPILER
if (*sc_visual_bell == '\0')
return;
tputs(sc_visual_bell, sc_height, putchr);
#else
#if MSDOS_COMPILER==DJGPPC
ScreenVisualBell();
#else
#if MSDOS_COMPILER==MSOFTC
/*
* Create a flash screen on the second video page.
* Switch to that page, then switch back.
*/
if (!flash_created)
create_flash();
if (videopages < 2)
return;
_setvisualpage(1);
delay(100);
_setvisualpage(0);
#else
#if MSDOS_COMPILER==BORLANDC
unsigned short *currscreen;
/*
* Get a copy of the current screen.
* Display the flash screen.
* Then restore the old screen.
*/
if (!flash_created)
create_flash();
if (whitescreen == NULL)
return;
currscreen = (unsigned short *)
malloc(sc_width * sc_height * sizeof(short));
if (currscreen == NULL) return;
gettext(1, 1, sc_width, sc_height, currscreen);
puttext(1, 1, sc_width, sc_height, whitescreen);
delay(100);
puttext(1, 1, sc_width, sc_height, currscreen);
free(currscreen);
#else
#if MSDOS_COMPILER==WIN32C
/* paint screen with an inverse color */
clear();
/* leave it displayed for 100 msec. */
Sleep(100);
/* restore with a redraw */
repaint();
#endif
#endif
#endif
#endif
#endif
}
/*
* Make a noise.
*/
static void
beep()
{
#if !MSDOS_COMPILER
putchr(CONTROL('G'));
#else
#if MSDOS_COMPILER==WIN32C
MessageBeep(0);
#else
write(1, "\7", 1);
#endif
#endif
}
/*
* Ring the terminal bell.
*/
public void
bell()
{
if (quiet == VERY_QUIET)
vbell();
else
beep();
}
/*
* Clear the screen.
*/
public void
clear()
{
#if !MSDOS_COMPILER
tputs(sc_clear, sc_height, putchr);
#else
flush();
#if MSDOS_COMPILER==WIN32C
win32_clear();
#else
_clearscreen(_GCLEARSCREEN);
#endif
#endif
}
/*
* Clear from the cursor to the end of the cursor's line.
* {{ This must not move the cursor. }}
*/
public void
clear_eol()
{
#if !MSDOS_COMPILER
tputs(sc_eol_clear, 1, putchr);
#else
#if MSDOS_COMPILER==MSOFTC
short top, left;
short bot, right;
struct rccoord tpos;
flush();
/*
* Save current state.
*/
tpos = _gettextposition();
_gettextwindow(&top, &left, &bot, &right);
/*
* Set a temporary window to the current line,
* from the cursor's position to the right edge of the screen.
* Then clear that window.
*/
_settextwindow(tpos.row, tpos.col, tpos.row, sc_width);
_clearscreen(_GWINDOW);
/*
* Restore state.
*/
_settextwindow(top, left, bot, right);
_settextposition(tpos.row, tpos.col);
#else
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
flush();
clreol();
#else
#if MSDOS_COMPILER==WIN32C
DWORD nchars;
COORD cpos;
CONSOLE_SCREEN_BUFFER_INFO scr;
flush();
memset(&scr, 0, sizeof(scr));
GetConsoleScreenBufferInfo(con_out, &scr);
cpos.X = scr.dwCursorPosition.X;
cpos.Y = scr.dwCursorPosition.Y;
curr_attr = MAKEATTR(nm_fg_color, nm_bg_color);
FillConsoleOutputAttribute(con_out, curr_attr,
scr.dwSize.X - cpos.X, cpos, &nchars);
FillConsoleOutputCharacter(con_out, ' ',
scr.dwSize.X - cpos.X, cpos, &nchars);
#endif
#endif
#endif
#endif
}
/*
* Clear the current line.
* Clear the screen if there's off-screen memory below the display.
*/
static void
clear_eol_bot()
{
#if MSDOS_COMPILER
clear_eol();
#else
if (below_mem)
tputs(sc_eos_clear, 1, putchr);
else
tputs(sc_eol_clear, 1, putchr);
#endif
}
/*
* Clear the bottom line of the display.
* Leave the cursor at the beginning of the bottom line.
*/
public void
clear_bot()
{
/*
* If we're in a non-normal attribute mode, temporarily exit
* the mode while we do the clear. Some terminals fill the
* cleared area with the current attribute.
*/
lower_left();
switch (attrmode)
{
case AT_STANDOUT:
so_exit();
clear_eol_bot();
so_enter();
break;
case AT_UNDERLINE:
ul_exit();
clear_eol_bot();
ul_enter();
break;
case AT_BOLD:
bo_exit();
clear_eol_bot();
bo_enter();
break;
case AT_BLINK:
bl_exit();
clear_eol_bot();
bl_enter();
break;
default:
clear_eol_bot();
break;
}
}
/*
* Begin "standout" (bold, underline, or whatever).
*/
public void
so_enter()
{
#if !MSDOS_COMPILER
tputs(sc_s_in, 1, putchr);
#else
flush();
SETCOLORS(so_fg_color, so_bg_color);
#endif
attrmode = AT_STANDOUT;
}
/*
* End "standout".
*/
public void
so_exit()
{
#if !MSDOS_COMPILER
tputs(sc_s_out, 1, putchr);
#else
flush();
SETCOLORS(nm_fg_color, nm_bg_color);
#endif
attrmode = AT_NORMAL;
}
/*
* Begin "underline" (hopefully real underlining,
* otherwise whatever the terminal provides).
*/
public void
ul_enter()
{
#if !MSDOS_COMPILER
tputs(sc_u_in, 1, putchr);
#else
flush();
SETCOLORS(ul_fg_color, ul_bg_color);
#endif
attrmode = AT_UNDERLINE;
}
/*
* End "underline".
*/
public void
ul_exit()
{
#if !MSDOS_COMPILER
tputs(sc_u_out, 1, putchr);
#else
flush();
SETCOLORS(nm_fg_color, nm_bg_color);
#endif
attrmode = AT_NORMAL;
}
/*
* Begin "bold"
*/
public void
bo_enter()
{
#if !MSDOS_COMPILER
tputs(sc_b_in, 1, putchr);
#else
flush();
SETCOLORS(bo_fg_color, bo_bg_color);
#endif
attrmode = AT_BOLD;
}
/*
* End "bold".
*/
public void
bo_exit()
{
#if !MSDOS_COMPILER
tputs(sc_b_out, 1, putchr);
#else
flush();
SETCOLORS(nm_fg_color, nm_bg_color);
#endif
attrmode = AT_NORMAL;
}
/*
* Begin "blink"
*/
public void
bl_enter()
{
#if !MSDOS_COMPILER
tputs(sc_bl_in, 1, putchr);
#else
flush();
SETCOLORS(bl_fg_color, bl_bg_color);
#endif
attrmode = AT_BLINK;
}
/*
* End "blink".
*/
public void
bl_exit()
{
#if !MSDOS_COMPILER
tputs(sc_bl_out, 1, putchr);
#else
flush();
SETCOLORS(nm_fg_color, nm_bg_color);
#endif
attrmode = AT_NORMAL;
}
#if 0 /* No longer used */
/*
* Erase the character to the left of the cursor
* and move the cursor left.
*/
public void
backspace()
{
#if !MSDOS_COMPILER
/*
* Erase the previous character by overstriking with a space.
*/
tputs(sc_backspace, 1, putchr);
putchr(' ');
tputs(sc_backspace, 1, putchr);
#else
#if MSDOS_COMPILER==MSOFTC
struct rccoord tpos;
flush();
tpos = _gettextposition();
if (tpos.col <= 1)
return;
_settextposition(tpos.row, tpos.col-1);
_outtext(" ");
_settextposition(tpos.row, tpos.col-1);
#else
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
cputs("\b");
#else
#if MSDOS_COMPILER==WIN32C
COORD cpos;
DWORD cChars;
CONSOLE_SCREEN_BUFFER_INFO scr;
flush();
GetConsoleScreenBufferInfo(con_out, &scr);
cpos = scr.dwCursorPosition;
if (cpos.X <= 0)
return;
cpos.X--;
SetConsoleCursorPosition(con_out, cpos);
FillConsoleOutputCharacter(con_out, (TCHAR)' ', 1, cpos, &cChars);
SetConsoleCursorPosition(con_out, cpos);
#endif
#endif
#endif
#endif
}
#endif /* 0 */
/*
* Output a plain backspace, without erasing the previous char.
*/
public void
putbs()
{
#if !MSDOS_COMPILER
tputs(sc_backspace, 1, putchr);
#else
int row, col;
flush();
{
#if MSDOS_COMPILER==MSOFTC
struct rccoord tpos;
tpos = _gettextposition();
row = tpos.row;
col = tpos.col;
#else
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
row = wherey();
col = wherex();
#else
#if MSDOS_COMPILER==WIN32C
CONSOLE_SCREEN_BUFFER_INFO scr;
GetConsoleScreenBufferInfo(con_out, &scr);
row = scr.dwCursorPosition.Y - scr.srWindow.Top + 1;
col = scr.dwCursorPosition.X - scr.srWindow.Left + 1;
#endif
#endif
#endif
}
if (col <= 1)
return;
_settextposition(row, col-1);
#endif /* MSDOS_COMPILER */
}
#if MSDOS_COMPILER==WIN32C
/*
* Determine whether an input character is waiting to be read.
*/
static int
win32_kbhit(tty)
HANDLE tty;
{
INPUT_RECORD ip;
DWORD read;
if (keyCount > 0)
return (TRUE);
currentKey.ascii = 0;
currentKey.scan = 0;
/*
* Wait for a real key-down event, but
* ignore SHIFT and CONTROL key events.
*/
do
{
PeekConsoleInput(tty, &ip, 1, &read);
if (read == 0)
return (FALSE);
ReadConsoleInput(tty, &ip, 1, &read);
} while (ip.EventType != KEY_EVENT ||
ip.Event.KeyEvent.bKeyDown != TRUE ||
ip.Event.KeyEvent.wVirtualScanCode == 0 ||
ip.Event.KeyEvent.wVirtualKeyCode == VK_SHIFT ||
ip.Event.KeyEvent.wVirtualKeyCode == VK_CONTROL ||
ip.Event.KeyEvent.wVirtualKeyCode == VK_MENU);
currentKey.ascii = ip.Event.KeyEvent.uChar.AsciiChar;
currentKey.scan = ip.Event.KeyEvent.wVirtualScanCode;
keyCount = ip.Event.KeyEvent.wRepeatCount;
if (ip.Event.KeyEvent.dwControlKeyState &
(LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
{
switch (currentKey.scan)
{
case PCK_ALT_E: /* letter 'E' */
currentKey.ascii = 0;
break;
}
} else if (ip.Event.KeyEvent.dwControlKeyState &
(LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
{
switch (currentKey.scan)
{
case PCK_RIGHT: /* right arrow */
currentKey.scan = PCK_CTL_RIGHT;
break;
case PCK_LEFT: /* left arrow */
currentKey.scan = PCK_CTL_LEFT;
break;
case PCK_DELETE: /* delete */
currentKey.scan = PCK_CTL_DELETE;
break;
}
}
return (TRUE);
}
/*
* Read a character from the keyboard.
*/
public char
WIN32getch(tty)
int tty;
{
int ascii;
if (pending_scancode)
{
pending_scancode = 0;
return ((char)(currentKey.scan & 0x00FF));
}
while (win32_kbhit((HANDLE)tty) == FALSE)
{
Sleep(20);
if (ABORT_SIGS())
return ('\003');
continue;
}
keyCount --;
ascii = currentKey.ascii;
/*
* On PC's, the extended keys return a 2 byte sequence beginning
* with '00', so if the ascii code is 00, the next byte will be
* the lsb of the scan code.
*/
pending_scancode = (ascii == 0x00);
return ((char)ascii);
}
#endif
less-382/brac.c 0100444 0000764 0000764 00000004434 10010075212 012413 0 ustar markn markn /*
* Copyright (C) 1984-2002 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines to perform bracket matching functions.
*/
#include "less.h"
#include "position.h"
/*
* Try to match the n-th open bracket
* which appears in the top displayed line (forwdir),
* or the n-th close bracket
* which appears in the bottom displayed line (!forwdir).
* The characters which serve as "open bracket" and
* "close bracket" are given.
*/
public void
match_brac(obrac, cbrac, forwdir, n)
register int obrac;
register int cbrac;
int forwdir;
int n;
{
register int c;
register int nest;
POSITION pos;
int (*chget)();
extern int ch_forw_get(), ch_back_get();
/*
* Seek to the line containing the open bracket.
* This is either the top or bottom line on the screen,
* depending on the type of bracket.
*/
pos = position((forwdir) ? TOP : BOTTOM);
if (pos == NULL_POSITION || ch_seek(pos))
{
if (forwdir)
error("Nothing in top line", NULL_PARG);
else
error("Nothing in bottom line", NULL_PARG);
return;
}
/*
* Look thru the line to find the open bracket to match.
*/
do
{
if ((c = ch_forw_get()) == '\n' || c == EOI)
{
if (forwdir)
error("No bracket in top line", NULL_PARG);
else
error("No bracket in bottom line", NULL_PARG);
return;
}
} while (c != obrac || --n > 0);
/*
* Position the file just "after" the open bracket
* (in the direction in which we will be searching).
* If searching forward, we are already after the bracket.
* If searching backward, skip back over the open bracket.
*/
if (!forwdir)
(void) ch_back_get();
/*
* Search the file for the matching bracket.
*/
chget = (forwdir) ? ch_forw_get : ch_back_get;
nest = 0;
while ((c = (*chget)()) != EOI)
{
if (c == obrac)
nest++;
else if (c == cbrac && --nest < 0)
{
/*
* Found the matching bracket.
* If searching backward, put it on the top line.
* If searching forward, put it on the bottom line.
*/
jump_line_loc(ch_tell(), forwdir ? -1 : 1);
return;
}
}
error("No matching bracket", NULL_PARG);
}
less-382/ch.c 0100444 0000764 0000764 00000037767 10010075212 012115 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Low level character input from the input file.
* We use these special purpose routines which optimize moving
* both forward and backward from the current read pointer.
*/
#include "less.h"
#if MSDOS_COMPILER==WIN32C
#include
#include
#endif
typedef POSITION BLOCKNUM;
public int ignore_eoi;
/*
* Pool of buffers holding the most recently used blocks of the input file.
* The buffer pool is kept as a doubly-linked circular list,
* in order from most- to least-recently used.
* The circular list is anchored by the file state "thisfile".
*/
#define LBUFSIZE 8192
struct buf {
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 {
struct buf *buf_next, *buf_prev;
struct buflist hashtbl[BUFHASH_SIZE];
int file;
int flags;
POSITION fpos;
int nbufs;
BLOCKNUM block;
unsigned int offset;
POSITION fsize;
};
#define ch_bufhead thisfile->buf_next
#define ch_buftail thisfile->buf_prev
#define ch_nbufs thisfile->nbufs
#define ch_block thisfile->block
#define ch_offset thisfile->offset
#define ch_fpos thisfile->fpos
#define ch_fsize thisfile->fsize
#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;
static int maxbufs = -1;
extern int autobuf;
extern int sigs;
extern int secure;
extern constant char helpdata[];
extern constant int size_helpdata;
extern IFILE curr_ifile;
#if LOGFILE
extern int logfile;
extern char *namelogfile;
#endif
static int ch_addbuf();
/*
* Get the character pointed to by the read pointer.
* ch_get() is a macro which is more efficient to call
* than fch_get (the function), in the usual case
* that the block desired is at the head of the chain.
*/
#define ch_get() ((ch_block == ch_bufhead->block && \
ch_offset < ch_bufhead->datasize) ? \
ch_bufhead->data[ch_offset] : fch_get())
int
fch_get()
{
register struct buf *bp;
register int n;
register int slept;
register int h;
POSITION pos;
POSITION len;
slept = FALSE;
/*
* Look for a buffer holding the desired block.
*/
h = BUFHASH(ch_block);
FOR_BUFS_IN_CHAIN(h, bp)
{
if (bp->block == ch_block)
{
if (ch_offset >= bp->datasize)
/*
* Need more data in this buffer.
*/
goto read_more;
goto found;
}
}
/*
* Block is not in a buffer.
* Take the least recently used buffer
* and read the desired block into it.
* If the LRU buffer has data in it,
* then maybe allocate a new buffer.
*/
if (ch_buftail == END_OF_CHAIN || ch_buftail->block != -1)
{
/*
* There is no empty buffer to use.
* Allocate a new buffer if:
* 1. We can't seek on this file and -b is not in effect; or
* 2. We haven't allocated the max buffers for this file yet.
*/
if ((autobuf && !(ch_flags & CH_CANSEEK)) ||
(maxbufs < 0 || ch_nbufs < maxbufs))
if (ch_addbuf())
/*
* Allocation failed: turn off autobuf.
*/
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;
if ((len = ch_length()) != NULL_POSITION && pos >= len)
/*
* At end of file.
*/
return (EOI);
if (pos != ch_fpos)
{
/*
* Not at the correct position: must seek.
* If input is a pipe, we're in trouble (can't seek on a pipe).
* Some data has been lost: just return "?".
*/
if (!(ch_flags & CH_CANSEEK))
return ('?');
if (lseek(ch_file, (off_t)pos, 0) == BAD_LSEEK)
{
error("seek error", NULL_PARG);
clear_eol();
return (EOI);
}
ch_fpos = pos;
}
/*
* Read the block.
* If we read less than a full block, that's ok.
* We use partial block and pick up the rest next time.
*/
if (ch_ungotchar != -1)
{
bp->data[bp->datasize] = ch_ungotchar;
n = 1;
ch_ungotchar = -1;
} else if (ch_flags & CH_HELPFILE)
{
bp->data[bp->datasize] = helpdata[ch_fpos];
n = 1;
} else
{
n = iread(ch_file, &bp->data[bp->datasize],
(unsigned int)(LBUFSIZE - bp->datasize));
}
if (n == READ_INTR)
return (EOI);
if (n < 0)
{
#if MSDOS_COMPILER==WIN32C
if (errno != EPIPE)
#endif
{
error("read error", NULL_PARG);
clear_eol();
}
n = 0;
}
#if LOGFILE
/*
* If we have a log file, write the new data to it.
*/
if (!secure && logfile >= 0 && n > 0)
write(logfile, (char *) &bp->data[bp->datasize], n);
#endif
ch_fpos += n;
bp->datasize += n;
/*
* If we have read to end of file, set ch_fsize to indicate
* the position of the end of file.
*/
if (n == 0)
{
ch_fsize = pos;
if (ignore_eoi)
{
/*
* We are ignoring EOF.
* Wait a while, then try again.
*/
if (!slept)
{
PARG parg;
parg.p_string = wait_message();
ierror("%s", &parg);
}
#if !MSDOS_COMPILER
sleep(1);
#else
#if MSDOS_COMPILER==WIN32C
Sleep(1000);
#endif
#endif
slept = TRUE;
}
if (sigs)
return (EOI);
}
found:
if (ch_bufhead != bp)
{
/*
* Move the buffer to the head of the buffer chain.
* This orders the buffer chain, most- to least-recently used.
*/
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)
/*
* After all that, we still don't have enough data.
* Go back and try again.
*/
goto read_more;
return (bp->data[ch_offset]);
}
/*
* ch_ungetchar is a rather kludgy and limited way to push
* a single char onto an input file descriptor.
*/
public void
ch_ungetchar(c)
int c;
{
if (c != -1 && ch_ungotchar != -1)
error("ch_ungetchar overrun", NULL_PARG);
ch_ungotchar = c;
}
#if LOGFILE
/*
* Close the logfile.
* If we haven't read all of standard input into it, do that now.
*/
public void
end_logfile()
{
static int tried = FALSE;
if (logfile < 0)
return;
if (!tried && ch_fsize == NULL_POSITION)
{
tried = TRUE;
ierror("Finishing logfile", NULL_PARG);
while (ch_forw_get() != EOI)
if (ABORT_SIGS())
break;
}
close(logfile);
logfile = -1;
namelogfile = NULL;
}
/*
* Start a log file AFTER less has already been running.
* Invoked from the - command; see toggle_option().
* Write all the existing buffered data to the log file.
*/
public void
sync_logfile()
{
register struct buf *bp;
int warned = FALSE;
BLOCKNUM block;
BLOCKNUM nblocks;
nblocks = (ch_fpos + LBUFSIZE - 1) / LBUFSIZE;
for (block = 0; block < nblocks; block++)
{
for (bp = ch_bufhead; ; bp = bp->next)
{
if (bp == END_OF_CHAIN)
{
if (!warned)
{
error("Warning: log file is incomplete",
NULL_PARG);
warned = TRUE;
}
break;
}
if (bp->block == block)
{
write(logfile, (char *) bp->data, bp->datasize);
break;
}
}
}
}
#endif
/*
* Determine if a specific block is currently in one of the buffers.
*/
static int
buffered(block)
BLOCKNUM block;
{
register struct buf *bp;
register int h;
h = BUFHASH(block);
FOR_BUFS_IN_CHAIN(h, bp)
{
if (bp->block == block)
return (TRUE);
}
return (FALSE);
}
/*
* Seek to a specified position in the file.
* Return 0 if successful, non-zero if can't seek there.
*/
public int
ch_seek(pos)
register POSITION pos;
{
BLOCKNUM new_block;
POSITION len;
len = ch_length();
if (pos < ch_zero() || (len != NULL_POSITION && pos > len))
return (1);
new_block = pos / LBUFSIZE;
if (!(ch_flags & CH_CANSEEK) && pos != ch_fpos && !buffered(new_block))
{
if (ch_fpos > pos)
return (1);
while (ch_fpos < pos)
{
if (ch_forw_get() == EOI)
return (1);
if (ABORT_SIGS())
return (1);
}
return (0);
}
/*
* Set read pointer.
*/
ch_block = new_block;
ch_offset = pos % LBUFSIZE;
return (0);
}
/*
* Seek to the end of the file.
*/
public int
ch_end_seek()
{
POSITION len;
if (ch_flags & CH_CANSEEK)
ch_fsize = filesize(ch_file);
len = ch_length();
if (len != NULL_POSITION)
return (ch_seek(len));
/*
* Do it the slow way: read till end of data.
*/
while (ch_forw_get() != EOI)
if (ABORT_SIGS())
return (1);
return (0);
}
/*
* Seek to the beginning of the file, or as close to it as we can get.
* We may not be able to seek there if input is a pipe and the
* beginning of the pipe is no longer buffered.
*/
public int
ch_beg_seek()
{
register struct buf *bp, *firstbp;
/*
* Try a plain ch_seek first.
*/
if (ch_seek(ch_zero()) == 0)
return (0);
/*
* Can't get to position 0.
* Look thru the buffers for the one closest to position 0.
*/
firstbp = bp = ch_bufhead;
if (bp == END_OF_CHAIN)
return (1);
while ((bp = bp->next) != END_OF_CHAIN)
if (bp->block < firstbp->block)
firstbp = bp;
ch_block = firstbp->block;
ch_offset = 0;
return (0);
}
/*
* Return the length of the file, if known.
*/
public POSITION
ch_length()
{
if (ignore_eoi)
return (NULL_POSITION);
if (ch_flags & CH_HELPFILE)
return (size_helpdata);
return (ch_fsize);
}
/*
* Return the current position in the file.
*/
public POSITION
ch_tell()
{
return (ch_block * LBUFSIZE) + ch_offset;
}
/*
* Get the current char and post-increment the read pointer.
*/
public int
ch_forw_get()
{
register int c;
c = ch_get();
if (c == EOI)
return (EOI);
if (ch_offset < LBUFSIZE-1)
ch_offset++;
else
{
ch_block ++;
ch_offset = 0;
}
return (c);
}
/*
* Pre-decrement the read pointer and get the new current char.
*/
public int
ch_back_get()
{
if (ch_offset > 0)
ch_offset --;
else
{
if (ch_block <= 0)
return (EOI);
if (!(ch_flags & CH_CANSEEK) && !buffered(ch_block-1))
return (EOI);
ch_block--;
ch_offset = LBUFSIZE-1;
}
return (ch_get());
}
/*
* Set max amount of buffer space.
* bufspace is in units of 1024 bytes. -1 mean no limit.
*/
public void
ch_setbufspace(bufspace)
int bufspace;
{
if (bufspace < 0)
maxbufs = -1;
else
{
maxbufs = ((bufspace * 1024) + LBUFSIZE-1) / LBUFSIZE;
if (maxbufs < 1)
maxbufs = 1;
}
}
/*
* Flush (discard) any saved file state, including buffer contents.
*/
public void
ch_flush()
{
register struct buf *bp;
if (!(ch_flags & CH_CANSEEK))
{
/*
* If input is a pipe, we don't flush buffer contents,
* since the contents can't be recovered.
*/
ch_fsize = NULL_POSITION;
return;
}
/*
* Initialize all the buffers.
*/
for (bp = ch_bufhead; bp != END_OF_CHAIN; bp = bp->next)
bp->block = -1;
/*
* Figure out the size of the file, if we can.
*/
ch_fsize = filesize(ch_file);
/*
* Seek to a known position: the beginning of the file.
*/
ch_fpos = 0;
ch_block = 0; /* ch_fpos / LBUFSIZE; */
ch_offset = 0; /* ch_fpos % LBUFSIZE; */
#if 1
/*
* This is a kludge to workaround a Linux kernel bug: files in
* /proc have a size of 0 according to fstat() but have readable
* data. They are sometimes, but not always, seekable.
* Force them to be non-seekable here.
*/
if (ch_fsize == 0)
{
ch_fsize = NULL_POSITION;
ch_flags &= ~CH_CANSEEK;
}
#endif
if (lseek(ch_file, (off_t)0, 0) == BAD_LSEEK)
{
/*
* Warning only; even if the seek fails for some reason,
* there's a good chance we're at the beginning anyway.
* {{ I think this is bogus reasoning. }}
*/
error("seek error to 0", NULL_PARG);
}
}
/*
* Allocate a new buffer.
* The buffer is added to the tail of the buffer chain.
*/
static int
ch_addbuf()
{
register struct buf *bp;
/*
* Allocate and initialize a new buffer and link it
* onto the tail of the buffer list.
*/
bp = (struct buf *) calloc(1, sizeof(struct buf));
if (bp == NULL)
return (1);
ch_nbufs++;
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.
*/
static void
ch_delbufs()
{
register struct buf *bp;
while (ch_bufhead != END_OF_CHAIN)
{
bp = ch_bufhead;
bp->next->prev = bp->prev;;
bp->prev->next = bp->next;
free(bp);
}
ch_nbufs = 0;
init_hashtbl();
}
/*
* Is it possible to seek on a file descriptor?
*/
public int
seekable(f)
int f;
{
#if MSDOS_COMPILER
extern int fd0;
if (f == fd0 && !isatty(fd0))
{
/*
* In MS-DOS, pipes are seekable. Check for
* standard input, and pretend it is not seekable.
*/
return (0);
}
#endif
return (lseek(f, (off_t)1, 0) != BAD_LSEEK);
}
/*
* Initialize file state for a new file.
*/
public void
ch_init(f, flags)
int f;
int flags;
{
/*
* See if we already have a filestate for this file.
*/
thisfile = (struct filestate *) get_filestate(curr_ifile);
if (thisfile == NULL)
{
/*
* Allocate and initialize a new filestate.
*/
thisfile = (struct filestate *)
calloc(1, sizeof(struct filestate));
thisfile->buf_next = thisfile->buf_prev = END_OF_CHAIN;
thisfile->nbufs = 0;
thisfile->flags = 0;
thisfile->fpos = 0;
thisfile->block = 0;
thisfile->offset = 0;
thisfile->file = -1;
thisfile->fsize = NULL_POSITION;
ch_flags = flags;
init_hashtbl();
/*
* Try to seek; set CH_CANSEEK if it works.
*/
if ((flags & CH_CANSEEK) && !seekable(f))
ch_flags &= ~CH_CANSEEK;
set_filestate(curr_ifile, (void *) thisfile);
}
if (thisfile->file == -1)
thisfile->file = f;
ch_flush();
}
/*
* Close a filestate.
*/
public void
ch_close()
{
int keepstate = FALSE;
if (ch_flags & (CH_CANSEEK|CH_POPENED|CH_HELPFILE))
{
/*
* We can seek or re-open, so we don't need to keep buffers.
*/
ch_delbufs();
} else
keepstate = TRUE;
if (!(ch_flags & CH_KEEPOPEN))
{
/*
* We don't need to keep the file descriptor open
* (because we can re-open it.)
* But don't really close it if it was opened via popen(),
* because pclose() wants to close it.
*/
if (!(ch_flags & (CH_POPENED|CH_HELPFILE)))
close(ch_file);
ch_file = -1;
} else
keepstate = TRUE;
if (!keepstate)
{
/*
* We don't even need to keep the filestate structure.
*/
free(thisfile);
thisfile = NULL;
set_filestate(curr_ifile, (void *) NULL);
}
}
/*
* Return ch_flags for the current file.
*/
public int
ch_getflags()
{
return (ch_flags);
}
#if 0
public void
ch_dump(struct filestate *fs)
{
struct buf *bp;
unsigned char *s;
if (fs == NULL)
{
printf(" --no filestate\n");
return;
}
printf(" file %d, flags %x, fpos %x, fsize %x, blk/off %x/%x\n",
fs->file, fs->flags, fs->fpos,
fs->fsize, fs->block, fs->offset);
printf(" %d bufs:\n", fs->nbufs);
for (bp = fs->buf_next; bp != (struct buf *)fs; bp = bp->next)
{
printf("%x: blk %x, size %x \"",
bp, bp->block, bp->datasize);
for (s = bp->data; s < bp->data + 30; s++)
if (*s >= ' ' && *s < 0x7F)
printf("%c", *s);
else
printf(".");
printf("\"\n");
}
}
#endif
less-382/charset.c 0100444 0000764 0000764 00000014120 10010075212 013126 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Functions to define the character set
* and do things specific to the character set.
*/
#include "less.h"
#if HAVE_LOCALE
#include
#include
#endif
public int utf_mode = 0;
/*
* Predefined character sets,
* selected by the LESSCHARSET environment variable.
*/
struct charset {
char *name;
int *p_flag;
char *desc;
} charsets[] = {
{ "ascii", NULL, "8bcccbcc18b95.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." },
{ "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
static char chardef[256];
static char *binfmt = NULL;
public int binattr = AT_STANDOUT;
/*
* Define a charset, given a description string.
* The string consists of 256 letters,
* one for each character in the charset.
* If the string is shorter than 256 letters, missing letters
* are taken to be identical to the last one.
* A decimal number followed by a letter is taken to be a
* repetition of the letter.
*
* Each letter is one of:
* . normal character
* b binary character
* c control character
*/
static void
ichardef(s)
char *s;
{
register char *cp;
register int n;
register char v;
n = 0;
v = 0;
cp = chardef;
while (*s != '\0')
{
switch (*s++)
{
case '.':
v = 0;
break;
case 'c':
v = IS_CONTROL_CHAR;
break;
case 'b':
v = IS_BINARY_CHAR|IS_CONTROL_CHAR;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
n = (10 * n) + (s[-1] - '0');
continue;
default:
error("invalid chardef", NULL_PARG);
quit(QUIT_ERROR);
/*NOTREACHED*/
}
do
{
if (cp >= chardef + sizeof(chardef))
{
error("chardef longer than 256", NULL_PARG);
quit(QUIT_ERROR);
/*NOTREACHED*/
}
*cp++ = v;
} while (--n > 0);
n = 0;
}
while (cp < chardef + sizeof(chardef))
*cp++ = v;
}
/*
* Define a charset, given a charset name.
* The valid charset names are listed in the "charsets" array.
*/
static int
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)
{
ichardef(p->desc);
if (p->p_flag != NULL)
*(p->p_flag) = 1;
return (1);
}
}
error("invalid charset name", NULL_PARG);
quit(QUIT_ERROR);
/*NOTREACHED*/
return (0);
}
#if HAVE_LOCALE
/*
* Define a charset, given a locale name.
*/
static void
ilocale()
{
register int c;
setlocale(LC_ALL, "");
for (c = 0; c < (int) sizeof(chardef); c++)
{
if (isprint(c))
chardef[c] = 0;
else if (iscntrl(c))
chardef[c] = IS_CONTROL_CHAR;
else
chardef[c] = IS_BINARY_CHAR|IS_CONTROL_CHAR;
}
}
#endif
/*
* Define the printing format for control chars.
*/
public void
setbinfmt(s)
char *s;
{
if (s == NULL || *s == '\0')
s = "*s<%X>";
/*
* Select the attributes if it starts with "*".
*/
if (*s == '*')
{
switch (s[1])
{
case 'd': binattr = AT_BOLD; break;
case 'k': binattr = AT_BLINK; break;
case 's': binattr = AT_STANDOUT; break;
case 'u': binattr = AT_UNDERLINE; break;
default: binattr = AT_NORMAL; break;
}
s += 2;
}
binfmt = s;
}
/*
* Initialize charset data structures.
*/
public void
init_charset()
{
register char *s;
s = lgetenv("LESSBINFMT");
setbinfmt(s);
/*
* See if environment variable LESSCHARSET is defined.
*/
s = lgetenv("LESSCHARSET");
if (icharset(s))
return;
/*
* LESSCHARSET is not defined: try LESSCHARDEF.
*/
s = lgetenv("LESSCHARDEF");
if (s != NULL && *s != '\0')
{
ichardef(s);
return;
}
#if HAVE_STRSTR
/*
* Check whether LC_ALL, LC_CTYPE or LANG look like UTF-8 is used.
*/
if ((s = lgetenv("LC_ALL")) != NULL ||
(s = lgetenv("LC_CTYPE")) != NULL ||
(s = lgetenv("LANG")) != NULL)
{
if (strstr(s, "UTF-8") != NULL || strstr(s, "utf-8") != NULL)
if (icharset("utf-8"))
return;
}
#endif
#if HAVE_LOCALE
/*
* Use setlocale.
*/
ilocale();
#else
#if MSDOS_COMPILER
/*
* Default to "dos".
*/
(void) icharset("dos");
#else
/*
* Default to "latin1".
*/
(void) icharset("latin1");
#endif
#endif
}
/*
* Is a given character a "binary" character?
*/
public int
binary_char(c)
unsigned char c;
{
c &= 0377;
return (chardef[c] & IS_BINARY_CHAR);
}
/*
* Is a given character a "control" character?
*/
public int
control_char(c)
int c;
{
c &= 0377;
return (chardef[c] & IS_CONTROL_CHAR);
}
/*
* Return the printable form of a character.
* For example, in the "ascii" charset '\3' is printed as "^C".
*/
public char *
prchar(c)
int c;
{
static char buf[8];
c &= 0377;
if (!control_char(c))
sprintf(buf, "%c", c);
else if (c == ESC)
sprintf(buf, "ESC");
#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);
}
less-382/cmdbuf.c 0100444 0000764 0000764 00000045664 10010075212 012756 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Functions which manipulate the command buffer.
* Used only by command() and related functions.
*/
#include "less.h"
#include "cmd.h"
extern int sc_width;
static char cmdbuf[CMDBUF_SIZE]; /* Buffer for holding a multi-char command */
static int cmd_col; /* Current column of the cursor */
static int prompt_col; /* Column of cursor just after prompt */
static char *cp; /* Pointer into cmdbuf */
static int cmd_offset; /* Index into cmdbuf of first displayed char */
static int literal; /* Next input char should not be interpreted */
#if TAB_COMPLETE_FILENAME
static int cmd_complete();
/*
* These variables are statics used by cmd_complete.
*/
static int in_completion = 0;
static char *tk_text;
static char *tk_original;
static char *tk_ipoint;
static char *tk_trial;
static struct textlist tk_tlist;
#endif
static int cmd_left();
static int cmd_right();
#if SPACES_IN_FILENAMES
public char openquote = '"';
public char closequote = '"';
#endif
#if CMD_HISTORY
/*
* A mlist structure represents a command history.
*/
struct mlist
{
struct mlist *next;
struct mlist *prev;
struct mlist *curr_mp;
char *string;
};
/*
* These are the various command histories that exist.
*/
struct mlist mlist_search =
{ &mlist_search, &mlist_search, &mlist_search, NULL };
public void * constant ml_search = (void *) &mlist_search;
struct mlist mlist_examine =
{ &mlist_examine, &mlist_examine, &mlist_examine, NULL };
public void * constant ml_examine = (void *) &mlist_examine;
#if SHELL_ESCAPE || PIPEC
struct mlist mlist_shell =
{ &mlist_shell, &mlist_shell, &mlist_shell, NULL };
public void * constant ml_shell = (void *) &mlist_shell;
#endif
#else /* CMD_HISTORY */
/* If CMD_HISTORY is off, these are just flags. */
public void * constant ml_search = (void *)1;
public void * constant ml_examine = (void *)2;
#if SHELL_ESCAPE || PIPEC
public void * constant ml_shell = (void *)3;
#endif
#endif /* CMD_HISTORY */
/*
* History for the current command.
*/
static struct mlist *curr_mlist = NULL;
static int curr_cmdflags;
/*
* Reset command buffer (to empty).
*/
public void
cmd_reset()
{
cp = cmdbuf;
*cp = '\0';
cmd_col = 0;
cmd_offset = 0;
literal = 0;
}
/*
* Clear command line on display.
*/
public void
clear_cmd()
{
clear_bot();
cmd_col = prompt_col = 0;
}
/*
* Display a string, usually as a prompt for input into the command buffer.
*/
public void
cmd_putstr(s)
char *s;
{
putstr(s);
cmd_col += strlen(s);
prompt_col += strlen(s);
}
/*
* How many characters are in the command buffer?
*/
public int
len_cmdbuf()
{
return (strlen(cmdbuf));
}
/*
* Repaint the line from cp onwards.
* Then position the cursor just after the char old_cp (a pointer into cmdbuf).
*/
static void
cmd_repaint(old_cp)
char *old_cp;
{
char *p;
/*
* Repaint the line from the current position.
*/
clear_eol();
for ( ; *cp != '\0'; cp++)
{
p = prchar(*cp);
if (cmd_col + (int)strlen(p) >= sc_width)
break;
putstr(p);
cmd_col += strlen(p);
}
/*
* Back up the cursor to the correct position.
*/
while (cp > old_cp)
cmd_left();
}
/*
* Put the cursor at "home" (just after the prompt),
* and set cp to the corresponding char in cmdbuf.
*/
static void
cmd_home()
{
while (cmd_col > prompt_col)
{
putbs();
cmd_col--;
}
cp = &cmdbuf[cmd_offset];
}
/*
* Shift the cmdbuf display left a half-screen.
*/
static void
cmd_lshift()
{
char *s;
char *save_cp;
int cols;
/*
* Start at the first displayed char, count how far to the
* right we'd have to move to reach the center of the screen.
*/
s = cmdbuf + cmd_offset;
cols = 0;
while (cols < (sc_width - prompt_col) / 2 && *s != '\0')
cols += strlen(prchar(*s++));
cmd_offset = s - cmdbuf;
save_cp = cp;
cmd_home();
cmd_repaint(save_cp);
}
/*
* Shift the cmdbuf display right a half-screen.
*/
static void
cmd_rshift()
{
char *s;
char *p;
char *save_cp;
int cols;
/*
* Start at the first displayed char, count how far to the
* left we'd have to move to traverse a half-screen width
* of displayed characters.
*/
s = cmdbuf + cmd_offset;
cols = 0;
while (cols < (sc_width - prompt_col) / 2 && s > cmdbuf)
{
p = prchar(*--s);
cols += strlen(p);
}
cmd_offset = s - cmdbuf;
save_cp = cp;
cmd_home();
cmd_repaint(save_cp);
}
/*
* Move cursor right one character.
*/
static int
cmd_right()
{
char *p;
if (*cp == '\0')
{
/*
* Already at the end of the line.
*/
return (CC_OK);
}
p = prchar(*cp);
if (cmd_col + (int)strlen(p) >= sc_width)
cmd_lshift();
else if (cmd_col + (int)strlen(p) == sc_width - 1 && cp[1] != '\0')
cmd_lshift();
cp++;
putstr(p);
cmd_col += strlen(p);
return (CC_OK);
}
/*
* Move cursor left one character.
*/
static int
cmd_left()
{
char *p;
if (cp <= cmdbuf)
{
/* Already at the beginning of the line */
return (CC_OK);
}
p = prchar(cp[-1]);
if (cmd_col < prompt_col + (int)strlen(p))
cmd_rshift();
cp--;
cmd_col -= strlen(p);
while (*p++ != '\0')
putbs();
return (CC_OK);
}
/*
* Insert a char into the command buffer, at the current position.
*/
static int
cmd_ichar(c)
int c;
{
char *s;
if (strlen(cmdbuf) >= sizeof(cmdbuf)-2)
{
/*
* No room in the command buffer for another char.
*/
bell();
return (CC_ERROR);
}
/*
* Insert the character into the buffer.
*/
for (s = &cmdbuf[strlen(cmdbuf)]; s >= cp; s--)
s[1] = s[0];
*cp = c;
/*
* Reprint the tail of the line from the inserted char.
*/
cmd_repaint(cp);
cmd_right();
return (CC_OK);
}
/*
* Backspace in the command buffer.
* Delete the char to the left of the cursor.
*/
static int
cmd_erase()
{
register char *s;
if (cp == cmdbuf)
{
/*
* Backspace past beginning of the buffer:
* this usually means abort the command.
*/
return (CC_QUIT);
}
/*
* Move cursor left (to the char being erased).
*/
cmd_left();
/*
* Remove the char from the buffer (shift the buffer left).
*/
for (s = cp; *s != '\0'; s++)
s[0] = s[1];
/*
* Repaint the buffer after the erased char.
*/
cmd_repaint(cp);
/*
* We say that erasing the entire command string causes us
* to abort the current command, if CF_QUIT_ON_ERASE is set.
*/
if ((curr_cmdflags & CF_QUIT_ON_ERASE) && cp == cmdbuf && *cp == '\0')
return (CC_QUIT);
return (CC_OK);
}
/*
* Delete the char under the cursor.
*/
static int
cmd_delete()
{
if (*cp == '\0')
{
/*
* At end of string; there is no char under the cursor.
*/
return (CC_OK);
}
/*
* Move right, then use cmd_erase.
*/
cmd_right();
cmd_erase();
return (CC_OK);
}
/*
* Delete the "word" to the left of the cursor.
*/
static int
cmd_werase()
{
if (cp > cmdbuf && cp[-1] == ' ')
{
/*
* If the char left of cursor is a space,
* erase all the spaces left of cursor (to the first non-space).
*/
while (cp > cmdbuf && cp[-1] == ' ')
(void) cmd_erase();
} else
{
/*
* If the char left of cursor is not a space,
* erase all the nonspaces left of cursor (the whole "word").
*/
while (cp > cmdbuf && cp[-1] != ' ')
(void) cmd_erase();
}
return (CC_OK);
}
/*
* Delete the "word" under the cursor.
*/
static int
cmd_wdelete()
{
if (*cp == ' ')
{
/*
* If the char under the cursor is a space,
* delete it and all the spaces right of cursor.
*/
while (*cp == ' ')
(void) cmd_delete();
} else
{
/*
* If the char under the cursor is not a space,
* delete it and all nonspaces right of cursor (the whole word).
*/
while (*cp != ' ' && *cp != '\0')
(void) cmd_delete();
}
return (CC_OK);
}
/*
* Delete all chars in the command buffer.
*/
static int
cmd_kill()
{
if (cmdbuf[0] == '\0')
{
/*
* Buffer is already empty; abort the current command.
*/
return (CC_QUIT);
}
cmd_offset = 0;
cmd_home();
*cp = '\0';
cmd_repaint(cp);
/*
* We say that erasing the entire command string causes us
* to abort the current command, if CF_QUIT_ON_ERASE is set.
*/
if (curr_cmdflags & CF_QUIT_ON_ERASE)
return (CC_QUIT);
return (CC_OK);
}
/*
* Select an mlist structure to be the current command history.
*/
public void
set_mlist(mlist, cmdflags)
void *mlist;
int cmdflags;
{
curr_mlist = (struct mlist *) mlist;
curr_cmdflags = cmdflags;
}
#if CMD_HISTORY
/*
* Move up or down in the currently selected command history list.
*/
static int
cmd_updown(action)
int action;
{
char *s;
if (curr_mlist == NULL)
{
/*
* The current command has no history list.
*/
bell();
return (CC_OK);
}
cmd_home();
clear_eol();
/*
* Move curr_mp to the next/prev entry.
*/
if (action == EC_UP)
curr_mlist->curr_mp = curr_mlist->curr_mp->prev;
else
curr_mlist->curr_mp = curr_mlist->curr_mp->next;
/*
* Copy the entry into cmdbuf and echo it on the screen.
*/
s = curr_mlist->curr_mp->string;
if (s == NULL)
s = "";
for (cp = cmdbuf; *s != '\0'; s++)
{
*cp = *s;
cmd_right();
}
*cp = '\0';
return (CC_OK);
}
#endif
/*
* Add a string to a history list.
*/
public void
cmd_addhist(mlist, cmd)
struct mlist *mlist;
char *cmd;
{
#if CMD_HISTORY
struct mlist *ml;
/*
* Don't save a trivial command.
*/
if (strlen(cmd) == 0)
return;
/*
* Don't save if a duplicate of a command which is already
* in the history.
* But select the one already in the history to be current.
*/
for (ml = mlist->next; ml != mlist; ml = ml->next)
{
if (strcmp(ml->string, cmd) == 0)
break;
}
if (ml == mlist)
{
/*
* Did not find command in history.
* Save the command and put it at the end of the history list.
*/
ml = (struct mlist *) ecalloc(1, sizeof(struct mlist));
ml->string = save(cmd);
ml->next = mlist;
ml->prev = mlist->prev;
mlist->prev->next = ml;
mlist->prev = ml;
}
/*
* Point to the cmd just after the just-accepted command.
* Thus, an UPARROW will always retrieve the previous command.
*/
mlist->curr_mp = ml->next;
#endif
}
/*
* Accept the command in the command buffer.
* Add it to the currently selected history list.
*/
public void
cmd_accept()
{
#if CMD_HISTORY
/*
* Nothing to do if there is no currently selected history list.
*/
if (curr_mlist == NULL)
return;
cmd_addhist(curr_mlist, cmdbuf);
#endif
}
/*
* Try to perform a line-edit function on the command buffer,
* using a specified char as a line-editing command.
* Returns:
* CC_PASS The char does not invoke a line edit function.
* CC_OK Line edit function done.
* CC_QUIT The char requests the current command to be aborted.
*/
static int
cmd_edit(c)
int c;
{
int action;
int flags;
#if TAB_COMPLETE_FILENAME
#define not_in_completion() in_completion = 0
#else
#define not_in_completion()
#endif
/*
* See if the char is indeed a line-editing command.
*/
flags = 0;
#if CMD_HISTORY
if (curr_mlist == NULL)
/*
* No current history; don't accept history manipulation cmds.
*/
flags |= EC_NOHISTORY;
#endif
#if TAB_COMPLETE_FILENAME
if (curr_mlist == ml_search)
/*
* In a search command; don't accept file-completion cmds.
*/
flags |= EC_NOCOMPLETE;
#endif
action = editchar(c, flags);
switch (action)
{
case EC_RIGHT:
not_in_completion();
return (cmd_right());
case EC_LEFT:
not_in_completion();
return (cmd_left());
case EC_W_RIGHT:
not_in_completion();
while (*cp != '\0' && *cp != ' ')
cmd_right();
while (*cp == ' ')
cmd_right();
return (CC_OK);
case EC_W_LEFT:
not_in_completion();
while (cp > cmdbuf && cp[-1] == ' ')
cmd_left();
while (cp > cmdbuf && cp[-1] != ' ')
cmd_left();
return (CC_OK);
case EC_HOME:
not_in_completion();
cmd_offset = 0;
cmd_home();
cmd_repaint(cp);
return (CC_OK);
case EC_END:
not_in_completion();
while (*cp != '\0')
cmd_right();
return (CC_OK);
case EC_INSERT:
not_in_completion();
return (CC_OK);
case EC_BACKSPACE:
not_in_completion();
return (cmd_erase());
case EC_LINEKILL:
not_in_completion();
return (cmd_kill());
case EC_W_BACKSPACE:
not_in_completion();
return (cmd_werase());
case EC_DELETE:
not_in_completion();
return (cmd_delete());
case EC_W_DELETE:
not_in_completion();
return (cmd_wdelete());
case EC_LITERAL:
literal = 1;
return (CC_OK);
#if CMD_HISTORY
case EC_UP:
case EC_DOWN:
not_in_completion();
return (cmd_updown(action));
#endif
#if TAB_COMPLETE_FILENAME
case EC_F_COMPLETE:
case EC_B_COMPLETE:
case EC_EXPAND:
return (cmd_complete(action));
#endif
case EC_NOACTION:
return (CC_OK);
default:
not_in_completion();
return (CC_PASS);
}
}
#if TAB_COMPLETE_FILENAME
/*
* Insert a string into the command buffer, at the current position.
*/
static int
cmd_istr(str)
char *str;
{
char *s;
int action;
for (s = str; *s != '\0'; s++)
{
action = cmd_ichar(*s);
if (action != CC_OK)
{
bell();
return (action);
}
}
return (CC_OK);
}
/*
* Find the beginning and end of the "current" word.
* This is the word which the cursor (cp) is inside or at the end of.
* Return pointer to the beginning of the word and put the
* cursor at the end of the word.
*/
static char *
delimit_word()
{
char *word;
#if SPACES_IN_FILENAMES
char *p;
int delim_quoted = 0;
int meta_quoted = 0;
char *esc = get_meta_escape();
int esclen = strlen(esc);
#endif
/*
* Move cursor to end of word.
*/
if (*cp != ' ' && *cp != '\0')
{
/*
* Cursor is on a nonspace.
* Move cursor right to the next space.
*/
while (*cp != ' ' && *cp != '\0')
cmd_right();
} else if (cp > cmdbuf && cp[-1] != ' ')
{
/*
* Cursor is on a space, and char to the left is a nonspace.
* We're already at the end of the word.
*/
;
#if 0
} else
{
/*
* Cursor is on a space and char to the left is a space.
* Huh? There's no word here.
*/
return (NULL);
#endif
}
/*
* Find the beginning of the word which the cursor is in.
*/
if (cp == cmdbuf)
return (NULL);
#if SPACES_IN_FILENAMES
/*
* If we have an unbalanced quote (that is, an open quote
* without a corresponding close quote), we return everything
* from the open quote, including spaces.
*/
for (word = cmdbuf; word < cp; word++)
if (*word != ' ')
break;
if (word >= cp)
return (cp);
for (p = cmdbuf; p < cp; p++)
{
if (meta_quoted)
{
meta_quoted = 0;
} else if (esclen > 0 && p + esclen < cp &&
strncmp(p, esc, esclen) == 0)
{
meta_quoted = 1;
p += esclen - 1;
} else if (delim_quoted)
{
if (*p == closequote)
delim_quoted = 0;
} else /* (!delim_quoted) */
{
if (*p == openquote)
delim_quoted = 1;
else if (*p == ' ')
word = p+1;
}
}
#endif
return (word);
}
/*
* Set things up to enter completion mode.
* Expand the word under the cursor into a list of filenames
* which start with that word, and set tk_text to that list.
*/
static void
init_compl()
{
char *word;
char c;
/*
* Get rid of any previous tk_text.
*/
if (tk_text != NULL)
{
free(tk_text);
tk_text = NULL;
}
/*
* Find the original (uncompleted) word in the command buffer.
*/
word = delimit_word();
if (word == NULL)
return;
/*
* Set the insertion point to the point in the command buffer
* where the original (uncompleted) word now sits.
*/
tk_ipoint = word;
/*
* Save the original (uncompleted) word
*/
if (tk_original != NULL)
free(tk_original);
tk_original = (char *) ecalloc(cp-word+1, sizeof(char));
strncpy(tk_original, word, cp-word);
/*
* Get the expanded filename.
* This may result in a single filename, or
* a blank-separated list of filenames.
*/
c = *cp;
*cp = '\0';
if (*word != openquote)
{
tk_text = fcomplete(word);
} else
{
char *qword = shell_quote(word+1);
if (qword == NULL)
tk_text = fcomplete(word+1);
else
{
tk_text = fcomplete(qword);
free(qword);
}
}
*cp = c;
}
/*
* Return the next word in the current completion list.
*/
static char *
next_compl(action, prev)
int action;
char *prev;
{
switch (action)
{
case EC_F_COMPLETE:
return (forw_textlist(&tk_tlist, prev));
case EC_B_COMPLETE:
return (back_textlist(&tk_tlist, prev));
}
/* Cannot happen */
return ("?");
}
/*
* Complete the filename before (or under) the cursor.
* cmd_complete may be called multiple times. The global in_completion
* remembers whether this call is the first time (create the list),
* or a subsequent time (step thru the list).
*/
static int
cmd_complete(action)
int action;
{
char *s;
if (!in_completion || action == EC_EXPAND)
{
/*
* Expand the word under the cursor and
* use the first word in the expansion
* (or the entire expansion if we're doing EC_EXPAND).
*/
init_compl();
if (tk_text == NULL)
{
bell();
return (CC_OK);
}
if (action == EC_EXPAND)
{
/*
* Use the whole list.
*/
tk_trial = tk_text;
} else
{
/*
* Use the first filename in the list.
*/
in_completion = 1;
init_textlist(&tk_tlist, tk_text);
tk_trial = next_compl(action, (char*)NULL);
}
} else
{
/*
* We already have a completion list.
* Use the next/previous filename from the list.
*/
tk_trial = next_compl(action, tk_trial);
}
/*
* Remove the original word, or the previous trial completion.
*/
while (cp > tk_ipoint)
(void) cmd_erase();
if (tk_trial == NULL)
{
/*
* There are no more trial completions.
* Insert the original (uncompleted) filename.
*/
in_completion = 0;
if (cmd_istr(tk_original) != CC_OK)
goto fail;
} else
{
/*
* Insert trial completion.
*/
if (cmd_istr(tk_trial) != CC_OK)
goto fail;
/*
* If it is a directory, append a slash.
*/
if (is_dir(tk_trial))
{
if (cp > cmdbuf && cp[-1] == closequote)
(void) cmd_erase();
s = lgetenv("LESSSEPARATOR");
if (s == NULL)
s = PATHNAME_SEP;
if (cmd_istr(s) != CC_OK)
goto fail;
}
}
return (CC_OK);
fail:
in_completion = 0;
bell();
return (CC_OK);
}
#endif /* TAB_COMPLETE_FILENAME */
/*
* Process a single character of a multi-character command, such as
* a number, or the pattern of a search command.
* Returns:
* CC_OK The char was accepted.
* CC_QUIT The char requests the command to be aborted.
* CC_ERROR The char could not be accepted due to an error.
*/
public int
cmd_char(c)
int c;
{
int action;
if (literal)
{
/*
* Insert the char, even if it is a line-editing char.
*/
literal = 0;
return (cmd_ichar(c));
}
/*
* See if it is a special line-editing character.
*/
if (in_mca())
{
action = cmd_edit(c);
switch (action)
{
case CC_OK:
case CC_QUIT:
return (action);
case CC_PASS:
break;
}
}
/*
* Insert the char into the command buffer.
*/
return (cmd_ichar(c));
}
/*
* Return the number currently in the command buffer.
*/
public LINENUM
cmd_int()
{
register char *p;
LINENUM n = 0;
for (p = cmdbuf; *p != '\0'; p++)
n = (10 * n) + (*p - '0');
return (n);
}
/*
* Return a pointer to the command buffer.
*/
public char *
get_cmdbuf()
{
return (cmdbuf);
}
less-382/command.c 0100444 0000764 0000764 00000073762 10010075212 013134 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* User-level command processor.
*/
#include "less.h"
#if MSDOS_COMPILER==WIN32C
#include
#endif
#include "position.h"
#include "option.h"
#include "cmd.h"
extern int erase_char, kill_char;
extern int sigs;
extern int quit_at_eof;
extern int quit_if_one_screen;
extern int squished;
extern int hit_eof;
extern int sc_width;
extern int sc_height;
extern int swindow;
extern int jump_sline;
extern int quitting;
extern int wscroll;
extern int top_scroll;
extern int ignore_eoi;
extern int secure;
extern int hshift;
extern int show_attn;
extern char *every_first_cmd;
extern char *curr_altfilename;
extern char version[];
extern struct scrpos initial_scrpos;
extern IFILE curr_ifile;
extern void constant *ml_search;
extern void constant *ml_examine;
#if SHELL_ESCAPE || PIPEC
extern void constant *ml_shell;
#endif
#if EDITOR
extern char *editor;
extern char *editproto;
#endif
extern int screen_trashed; /* The screen has been overwritten */
extern int shift_count;
static char ungot[UNGOT_SIZE];
static char *ungotp = NULL;
#if SHELL_ESCAPE
static char *shellcmd = NULL; /* For holding last shell command for "!!" */
#endif
static int mca; /* The multicharacter command (action) */
static int search_type; /* The previous type of search */
static LINENUM number; /* The number typed by the user */
static char optchar;
static int optflag;
static int optgetname;
static POSITION bottompos;
#if PIPEC
static char pipec;
#endif
static void multi_search();
/*
* Move the cursor to lower left before executing a command.
* This looks nicer if the command takes a long time before
* updating the screen.
*/
static void
cmd_exec()
{
clear_attn();
lower_left();
flush();
}
/*
* Set up the display to start a new multi-character command.
*/
static void
start_mca(action, prompt, mlist, cmdflags)
int action;
char *prompt;
void *mlist;
int cmdflags;
{
mca = action;
clear_cmd();
cmd_putstr(prompt);
set_mlist(mlist, cmdflags);
}
public int
in_mca()
{
return (mca != 0 && mca != A_PREFIX);
}
/*
* Set up the display to start a new search command.
*/
static void
mca_search()
{
if (search_type & SRCH_FORW)
mca = A_F_SEARCH;
else
mca = A_B_SEARCH;
clear_cmd();
if (search_type & SRCH_NO_MATCH)
cmd_putstr("Non-match ");
if (search_type & SRCH_FIRST_FILE)
cmd_putstr("First-file ");
if (search_type & SRCH_PAST_EOF)
cmd_putstr("EOF-ignore ");
if (search_type & SRCH_NO_MOVE)
cmd_putstr("Keep-pos ");
if (search_type & SRCH_NO_REGEX)
cmd_putstr("Regex-off ");
if (search_type & SRCH_FORW)
cmd_putstr("/");
else
cmd_putstr("?");
set_mlist(ml_search, 0);
}
/*
* Set up the display to start a new toggle-option command.
*/
static void
mca_opt_toggle()
{
int no_prompt;
int flag;
char *dash;
no_prompt = (optflag & OPT_NO_PROMPT);
flag = (optflag & ~OPT_NO_PROMPT);
dash = (flag == OPT_NO_TOGGLE) ? "_" : "-";
mca = A_OPT_TOGGLE;
clear_cmd();
cmd_putstr(dash);
if (optgetname)
cmd_putstr(dash);
if (no_prompt)
cmd_putstr("(P)");
switch (flag)
{
case OPT_UNSET:
cmd_putstr("+");
break;
case OPT_SET:
cmd_putstr("!");
break;
}
set_mlist(NULL, 0);
}
/*
* Execute a multicharacter command.
*/
static void
exec_mca()
{
register char *cbuf;
cmd_exec();
cbuf = get_cmdbuf();
switch (mca)
{
case A_F_SEARCH:
case A_B_SEARCH:
multi_search(cbuf, (int) number);
break;
case A_FIRSTCMD:
/*
* Skip leading spaces or + signs in the string.
*/
while (*cbuf == '+' || *cbuf == ' ')
cbuf++;
if (every_first_cmd != NULL)
free(every_first_cmd);
if (*cbuf == '\0')
every_first_cmd = NULL;
else
every_first_cmd = save(cbuf);
break;
case A_OPT_TOGGLE:
toggle_option(optchar, cbuf, optflag);
optchar = '\0';
break;
case A_F_BRACKET:
match_brac(cbuf[0], cbuf[1], 1, (int) number);
break;
case A_B_BRACKET:
match_brac(cbuf[1], cbuf[0], 0, (int) number);
break;
#if EXAMINE
case A_EXAMINE:
if (secure)
break;
edit_list(cbuf);
#if TAGS
/* If tag structure is loaded then clean it up. */
cleantags();
#endif
break;
#endif
#if SHELL_ESCAPE
case A_SHELL:
/*
* !! just uses whatever is in shellcmd.
* Otherwise, copy cmdbuf to shellcmd,
* expanding any special characters ("%" or "#").
*/
if (*cbuf != '!')
{
if (shellcmd != NULL)
free(shellcmd);
shellcmd = fexpand(cbuf);
}
if (secure)
break;
if (shellcmd == NULL)
lsystem("", "!done");
else
lsystem(shellcmd, "!done");
break;
#endif
#if PIPEC
case A_PIPE:
if (secure)
break;
(void) pipe_mark(pipec, cbuf);
error("|done", NULL_PARG);
break;
#endif
}
}
/*
* Add a character to a multi-character command.
*/
static int
mca_char(c)
int c;
{
char *p;
int flag;
char buf[3];
PARG parg;
switch (mca)
{
case 0:
/*
* Not in a multicharacter command.
*/
return (NO_MCA);
case A_PREFIX:
/*
* In the prefix of a command.
* This not considered a multichar command
* (even tho it uses cmdbuf, etc.).
* It is handled in the commands() switch.
*/
return (NO_MCA);
case A_DIGIT:
/*
* Entering digits of a number.
* Terminated by a non-digit.
*/
if ((c < '0' || c > '9') &&
editchar(c, EC_PEEK|EC_NOHISTORY|EC_NOCOMPLETE|EC_NORIGHTLEFT) == A_INVALID)
{
/*
* Not part of the number.
* Treat as a normal command character.
*/
number = cmd_int();
mca = 0;
cmd_accept();
return (NO_MCA);
}
break;
case A_OPT_TOGGLE:
/*
* Special case for the TOGGLE_OPTION command.
* If the option letter which was entered is a
* single-char option, execute the command immediately,
* so user doesn't have to hit RETURN.
* If the first char is + or -, this indicates
* OPT_UNSET or OPT_SET respectively, instead of OPT_TOGGLE.
* "--" begins inputting a long option name.
*/
if (optchar == '\0' && len_cmdbuf() == 0)
{
flag = (optflag & ~OPT_NO_PROMPT);
if (flag == OPT_NO_TOGGLE)
{
switch (c)
{
case '_':
/* "__" = long option name. */
optgetname = TRUE;
mca_opt_toggle();
return (MCA_MORE);
}
} else
{
switch (c)
{
case '+':
/* "-+" = UNSET. */
optflag = (flag == OPT_UNSET) ?
OPT_TOGGLE : OPT_UNSET;
mca_opt_toggle();
return (MCA_MORE);
case '!':
/* "-!" = SET */
optflag = (flag == OPT_SET) ?
OPT_TOGGLE : OPT_SET;
mca_opt_toggle();
return (MCA_MORE);
case CONTROL('P'):
optflag ^= OPT_NO_PROMPT;
mca_opt_toggle();
return (MCA_MORE);
case '-':
/* "--" = long option name. */
optgetname = TRUE;
mca_opt_toggle();
return (MCA_MORE);
}
}
}
if (optgetname)
{
/*
* We're getting a long option name.
* See if we've matched an option name yet.
* If so, display the complete name and stop
* accepting chars until user hits RETURN.
*/
struct loption *o;
char *oname;
int lc;
if (c == '\n' || c == '\r')
{
/*
* When the user hits RETURN, make sure
* we've matched an option name, then
* pretend he just entered the equivalent
* option letter.
*/
if (optchar == '\0')
{
parg.p_string = get_cmdbuf();
error("There is no --%s option", &parg);
return (MCA_DONE);
}
optgetname = FALSE;
cmd_reset();
c = optchar;
} else
{
if (optchar != '\0')
{
/*
* Already have a match for the name.
* Don't accept anything but erase/kill.
*/
if (c == erase_char || c == kill_char)
return (MCA_DONE);
return (MCA_MORE);
}
/*
* Add char to cmd buffer and try to match
* the option name.
*/
if (cmd_char(c) == CC_QUIT)
return (MCA_DONE);
p = get_cmdbuf();
lc = islower(p[0]);
o = findopt_name(&p, &oname, NULL);
if (o != NULL)
{
/*
* Got a match.
* Remember the option letter and
* display the full option name.
*/
optchar = o->oletter;
if (!lc && islower(optchar))
optchar = toupper(optchar);
cmd_reset();
mca_opt_toggle();
for (p = oname; *p != '\0'; p++)
{
c = *p;
if (!lc && islower(c))
c = toupper(c);
if (cmd_char(c) != CC_OK)
return (MCA_DONE);
}
}
return (MCA_MORE);
}
} else
{
if (c == erase_char || c == kill_char)
break;
if (optchar != '\0')
/* We already have the option letter. */
break;
}
optchar = c;
if ((optflag & ~OPT_NO_PROMPT) != OPT_TOGGLE ||
single_char_option(c))
{
toggle_option(c, "", optflag);
return (MCA_DONE);
}
/*
* Display a prompt appropriate for the option letter.
*/
if ((p = opt_prompt(c)) == NULL)
{
buf[0] = '-';
buf[1] = c;
buf[2] = '\0';
p = buf;
}
start_mca(A_OPT_TOGGLE, p, (void*)NULL, 0);
return (MCA_MORE);
case A_F_SEARCH:
case A_B_SEARCH:
/*
* Special case for search commands.
* Certain characters as the first char of
* the pattern have special meaning:
* ! Toggle the NO_MATCH flag
* * Toggle the PAST_EOF flag
* @ Toggle the FIRST_FILE flag
*/
if (len_cmdbuf() > 0)
/*
* Only works for the first char of the pattern.
*/
break;
flag = 0;
switch (c)
{
case CONTROL('E'): /* ignore END of file */
case '*':
flag = SRCH_PAST_EOF;
break;
case CONTROL('F'): /* FIRST file */
case '@':
flag = SRCH_FIRST_FILE;
break;
case CONTROL('K'): /* KEEP position */
flag = SRCH_NO_MOVE;
break;
case CONTROL('R'): /* Don't use REGULAR EXPRESSIONS */
flag = SRCH_NO_REGEX;
break;
case CONTROL('N'): /* NOT match */
case '!':
flag = SRCH_NO_MATCH;
break;
}
if (flag != 0)
{
search_type ^= flag;
mca_search();
return (MCA_MORE);
}
break;
}
/*
* Any other multicharacter command
* is terminated by a newline.
*/
if (c == '\n' || c == '\r')
{
/*
* Execute the command.
*/
exec_mca();
return (MCA_DONE);
}
/*
* Append the char to the command buffer.
*/
if (cmd_char(c) == CC_QUIT)
/*
* Abort the multi-char command.
*/
return (MCA_DONE);
if ((mca == A_F_BRACKET || mca == A_B_BRACKET) && len_cmdbuf() >= 2)
{
/*
* Special case for the bracket-matching commands.
* Execute the command after getting exactly two
* characters from the user.
*/
exec_mca();
return (MCA_DONE);
}
/*
* Need another character.
*/
return (MCA_MORE);
}
/*
* Make sure the screen is displayed.
*/
static void
make_display()
{
/*
* If nothing is displayed yet, display starting from initial_scrpos.
*/
if (empty_screen())
{
if (initial_scrpos.pos == NULL_POSITION)
/*
* {{ Maybe this should be:
* jump_loc(ch_zero(), jump_sline);
* but this behavior seems rather unexpected
* on the first screen. }}
*/
jump_loc(ch_zero(), 1);
else
jump_loc(initial_scrpos.pos, initial_scrpos.ln);
} else if (screen_trashed)
{
int save_top_scroll;
save_top_scroll = top_scroll;
top_scroll = 1;
repaint();
top_scroll = save_top_scroll;
}
}
/*
* Display the appropriate prompt.
*/
static void
prompt()
{
register char *p;
if (ungotp != NULL && ungotp > ungot)
{
/*
* No prompt necessary if commands are from
* ungotten chars rather than from the user.
*/
return;
}
/*
* Make sure the screen is displayed.
*/
make_display();
bottompos = position(BOTTOM_PLUS_ONE);
/*
* If the -E flag is set and we've hit EOF on the last file, quit.
*/
if ((quit_at_eof == OPT_ONPLUS || quit_if_one_screen) &&
hit_eof && !(ch_getflags() & CH_HELPFILE) &&
next_ifile(curr_ifile) == NULL_IFILE)
quit(QUIT_OK);
quit_if_one_screen = FALSE;
#if 0 /* This doesn't work well because some "te"s clear the screen. */
/*
* If the -e flag is set and we've hit EOF on the last file,
* and the file is squished (shorter than the screen), quit.
*/
if (quit_at_eof && squished &&
next_ifile(curr_ifile) == NULL_IFILE)
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.
*/
clear_cmd();
p = pr_string();
if (p == NULL)
putchr(':');
else
{
so_enter();
putstr(p);
so_exit();
}
}
/*
* Display the less version message.
*/
public void
dispversion()
{
PARG parg;
parg.p_string = version;
error("less %s", &parg);
}
/*
* Get command character.
* The character normally comes from the keyboard,
* but may come from ungotten characters
* (characters previously given to ungetcc or ungetsc).
*/
public int
getcc()
{
if (ungotp == NULL)
/*
* Normal case: no ungotten chars, so get one from the user.
*/
return (getchr());
if (ungotp > ungot)
/*
* Return the next ungotten char.
*/
return (*--ungotp);
/*
* We have just run out of ungotten chars.
*/
ungotp = NULL;
if (len_cmdbuf() == 0 || !empty_screen())
return (getchr());
/*
* Command is incomplete, so try to complete it.
*/
switch (mca)
{
case A_DIGIT:
/*
* We have a number but no command. Treat as #g.
*/
return ('g');
case A_F_SEARCH:
case A_B_SEARCH:
/*
* We have "/string" but no newline. Add the \n.
*/
return ('\n');
default:
/*
* Some other incomplete command. Let user complete it.
*/
return (getchr());
}
}
/*
* "Unget" a command character.
* The next getcc() will return this character.
*/
public void
ungetcc(c)
int c;
{
if (ungotp == NULL)
ungotp = ungot;
if (ungotp >= ungot + sizeof(ungot))
{
error("ungetcc overflow", NULL_PARG);
quit(QUIT_ERROR);
}
*ungotp++ = c;
}
/*
* Unget a whole string of command characters.
* The next sequence of getcc()'s will return this string.
*/
public void
ungetsc(s)
char *s;
{
register char *p;
for (p = s + strlen(s) - 1; p >= s; p--)
ungetcc(*p);
}
/*
* Search for a pattern, possibly in multiple files.
* If SRCH_FIRST_FILE is set, begin searching at the first file.
* If SRCH_PAST_EOF is set, continue the search thru multiple files.
*/
static void
multi_search(pattern, n)
char *pattern;
int n;
{
register int nomore;
IFILE save_ifile;
int changed_file;
changed_file = 0;
save_ifile = save_curr_ifile();
if (search_type & SRCH_FIRST_FILE)
{
/*
* Start at the first (or last) file
* in the command line list.
*/
if (search_type & SRCH_FORW)
nomore = edit_first();
else
nomore = edit_last();
if (nomore)
{
unsave_ifile(save_ifile);
return;
}
changed_file = 1;
search_type &= ~SRCH_FIRST_FILE;
}
for (;;)
{
n = search(search_type, pattern, n);
/*
* The SRCH_NO_MOVE flag doesn't "stick": it gets cleared
* after being used once. This allows "n" to work after
* using a /@@ search.
*/
search_type &= ~SRCH_NO_MOVE;
if (n == 0)
{
/*
* Found it.
*/
unsave_ifile(save_ifile);
return;
}
if (n < 0)
/*
* Some kind of error in the search.
* Error message has been printed by search().
*/
break;
if ((search_type & SRCH_PAST_EOF) == 0)
/*
* We didn't find a match, but we're
* supposed to search only one file.
*/
break;
/*
* Move on to the next file.
*/
if (search_type & SRCH_FORW)
nomore = edit_next(1);
else
nomore = edit_prev(1);
if (nomore)
break;
changed_file = 1;
}
/*
* Didn't find it.
* Print an error message if we haven't already.
*/
if (n > 0)
error("Pattern not found", NULL_PARG);
if (changed_file)
{
/*
* Restore the file we were originally viewing.
*/
reedit_ifile(save_ifile);
}
}
/*
* Main command processor.
* Accept and execute commands until a quit command.
*/
public void
commands()
{
register int c;
register int action;
register char *cbuf;
int newaction;
int save_search_type;
char *extra;
char tbuf[2];
PARG parg;
IFILE old_ifile;
IFILE new_ifile;
char *tagfile;
search_type = SRCH_FORW;
wscroll = (sc_height + 1) / 2;
newaction = A_NOACTION;
for (;;)
{
mca = 0;
cmd_accept();
number = 0;
optchar = '\0';
/*
* See if any signals need processing.
*/
if (sigs)
{
psignals();
if (quitting)
quit(QUIT_SAVED_STATUS);
}
/*
* See if window size changed, for systems that don't
* generate SIGWINCH.
*/
check_winch();
/*
* Display prompt and accept a character.
*/
cmd_reset();
prompt();
if (sigs)
continue;
if (newaction == A_NOACTION)
c = getcc();
again:
if (sigs)
continue;
if (newaction != A_NOACTION)
{
action = newaction;
newaction = A_NOACTION;
} else
{
/*
* If we are in a multicharacter command, call mca_char.
* Otherwise we call fcmd_decode to determine the
* action to be performed.
*/
if (mca)
switch (mca_char(c))
{
case MCA_MORE:
/*
* Need another character.
*/
c = getcc();
goto again;
case MCA_DONE:
/*
* Command has been handled by mca_char.
* Start clean with a prompt.
*/
continue;
case NO_MCA:
/*
* Not a multi-char command
* (at least, not anymore).
*/
break;
}
/*
* Decode the command character and decide what to do.
*/
if (mca)
{
/*
* We're in a multichar command.
* Add the character to the command buffer
* and display it on the screen.
* If the user backspaces past the start
* of the line, abort the command.
*/
if (cmd_char(c) == CC_QUIT || len_cmdbuf() == 0)
continue;
cbuf = get_cmdbuf();
} else
{
/*
* Don't use cmd_char if we're starting fresh
* at the beginning of a command, because we
* don't want to echo the command until we know
* it is a multichar command. We also don't
* want erase_char/kill_char to be treated
* as line editing characters.
*/
tbuf[0] = c;
tbuf[1] = '\0';
cbuf = tbuf;
}
extra = NULL;
action = fcmd_decode(cbuf, &extra);
/*
* If an "extra" string was returned,
* process it as a string of command characters.
*/
if (extra != NULL)
ungetsc(extra);
}
/*
* Clear the cmdbuf string.
* (But not if we're in the prefix of a command,
* because the partial command string is kept there.)
*/
if (action != A_PREFIX)
cmd_reset();
switch (action)
{
case A_DIGIT:
/*
* First digit of a number.
*/
start_mca(A_DIGIT, ":", (void*)NULL, CF_QUIT_ON_ERASE);
goto again;
case A_F_WINDOW:
/*
* Forward one window (and set the window size).
*/
if (number > 0)
swindow = (int) number;
/* FALLTHRU */
case A_F_SCREEN:
/*
* Forward one screen.
*/
if (number <= 0)
number = get_swindow();
cmd_exec();
if (show_attn)
set_attnpos(bottompos);
forward((int) number, 0, 1);
break;
case A_B_WINDOW:
/*
* Backward one window (and set the window size).
*/
if (number > 0)
swindow = (int) number;
/* FALLTHRU */
case A_B_SCREEN:
/*
* Backward one screen.
*/
if (number <= 0)
number = get_swindow();
cmd_exec();
backward((int) number, 0, 1);
break;
case A_F_LINE:
/*
* Forward N (default 1) line.
*/
if (number <= 0)
number = 1;
cmd_exec();
if (show_attn == OPT_ONPLUS && number > 1)
set_attnpos(bottompos);
forward((int) number, 0, 0);
break;
case A_B_LINE:
/*
* Backward N (default 1) line.
*/
if (number <= 0)
number = 1;
cmd_exec();
backward((int) number, 0, 0);
break;
case A_FF_LINE:
/*
* Force forward N (default 1) line.
*/
if (number <= 0)
number = 1;
cmd_exec();
if (show_attn == OPT_ONPLUS && number > 1)
set_attnpos(bottompos);
forward((int) number, 1, 0);
break;
case A_BF_LINE:
/*
* Force backward N (default 1) line.
*/
if (number <= 0)
number = 1;
cmd_exec();
backward((int) number, 1, 0);
break;
case A_FF_SCREEN:
/*
* Force forward one screen.
*/
if (number <= 0)
number = get_swindow();
cmd_exec();
if (show_attn == OPT_ONPLUS)
set_attnpos(bottompos);
forward((int) number, 1, 0);
break;
case A_F_FOREVER:
/*
* Forward forever, ignoring EOF.
*/
if (ch_getflags() & CH_HELPFILE)
break;
cmd_exec();
jump_forw();
ignore_eoi = 1;
hit_eof = 0;
while (!sigs)
forward(1, 0, 0);
ignore_eoi = 0;
/*
* This gets us back in "F mode" after processing
* a non-abort signal (e.g. window-change).
*/
if (sigs && !ABORT_SIGS())
newaction = A_F_FOREVER;
break;
case A_F_SCROLL:
/*
* Forward N lines
* (default same as last 'd' or 'u' command).
*/
if (number > 0)
wscroll = (int) number;
cmd_exec();
if (show_attn == OPT_ONPLUS)
set_attnpos(bottompos);
forward(wscroll, 0, 0);
break;
case A_B_SCROLL:
/*
* Forward N lines
* (default same as last 'd' or 'u' command).
*/
if (number > 0)
wscroll = (int) number;
cmd_exec();
backward(wscroll, 0, 0);
break;
case A_FREPAINT:
/*
* Flush buffers, then repaint screen.
* Don't flush the buffers on a pipe!
*/
if (ch_getflags() & CH_CANSEEK)
{
ch_flush();
clr_linenum();
#if HILITE_SEARCH
clr_hilite();
#endif
}
/* FALLTHRU */
case A_REPAINT:
/*
* Repaint screen.
*/
cmd_exec();
repaint();
break;
case A_GOLINE:
/*
* Go to line N, default beginning of file.
*/
if (number <= 0)
number = 1;
cmd_exec();
jump_back(number);
break;
case A_PERCENT:
/*
* Go to a specified percentage into the file.
*/
if (number < 0)
number = 0;
if (number > 100)
number = 100;
cmd_exec();
jump_percent((int) number);
break;
case A_GOEND:
/*
* Go to line N, default end of file.
*/
cmd_exec();
if (number <= 0)
jump_forw();
else
jump_back(number);
break;
case A_GOPOS:
/*
* Go to a specified byte position in the file.
*/
cmd_exec();
if (number < 0)
number = 0;
jump_line_loc((POSITION) number, jump_sline);
break;
case A_STAT:
/*
* Print file name, etc.
*/
if (ch_getflags() & CH_HELPFILE)
break;
cmd_exec();
parg.p_string = eq_message();
error("%s", &parg);
break;
case A_VERSION:
/*
* Print version number, without the "@(#)".
*/
cmd_exec();
dispversion();
break;
case A_QUIT:
/*
* Exit.
*/
if (curr_ifile != NULL_IFILE &&
ch_getflags() & CH_HELPFILE)
{
/*
* Quit while viewing the help file
* just means return to viewing the
* previous file.
*/
if (edit_prev(1) == 0)
break;
}
if (extra != NULL)
quit(*extra);
quit(QUIT_OK);
break;
/*
* Define abbreviation for a commonly used sequence below.
*/
#define DO_SEARCH() if (number <= 0) number = 1; \
mca_search(); \
cmd_exec(); \
multi_search((char *)NULL, (int) number);
case A_F_SEARCH:
/*
* Search forward for a pattern.
* Get the first char of the pattern.
*/
search_type = SRCH_FORW;
if (number <= 0)
number = 1;
mca_search();
c = getcc();
goto again;
case A_B_SEARCH:
/*
* Search backward for a pattern.
* Get the first char of the pattern.
*/
search_type = SRCH_BACK;
if (number <= 0)
number = 1;
mca_search();
c = getcc();
goto again;
case A_AGAIN_SEARCH:
/*
* Repeat previous search.
*/
DO_SEARCH();
break;
case A_T_AGAIN_SEARCH:
/*
* Repeat previous search, multiple files.
*/
search_type |= SRCH_PAST_EOF;
DO_SEARCH();
break;
case A_REVERSE_SEARCH:
/*
* Repeat previous search, in reverse direction.
*/
save_search_type = search_type;
search_type = SRCH_REVERSE(search_type);
DO_SEARCH();
search_type = save_search_type;
break;
case A_T_REVERSE_SEARCH:
/*
* Repeat previous search,
* multiple files in reverse direction.
*/
save_search_type = search_type;
search_type = SRCH_REVERSE(search_type);
search_type |= SRCH_PAST_EOF;
DO_SEARCH();
search_type = save_search_type;
break;
case A_UNDO_SEARCH:
undo_search();
break;
case A_HELP:
/*
* Help.
*/
if (ch_getflags() & CH_HELPFILE)
break;
cmd_exec();
(void) edit(FAKE_HELPFILE);
break;
case A_EXAMINE:
#if EXAMINE
/*
* Edit a new file. Get the filename.
*/
if (secure)
{
error("Command not available", NULL_PARG);
break;
}
start_mca(A_EXAMINE, "Examine: ", ml_examine, 0);
c = getcc();
goto again;
#else
error("Command not available", NULL_PARG);
break;
#endif
case A_VISUAL:
/*
* Invoke an editor on the input file.
*/
#if EDITOR
if (secure)
{
error("Command not available", NULL_PARG);
break;
}
if (ch_getflags() & CH_HELPFILE)
break;
if (strcmp(get_filename(curr_ifile), "-") == 0)
{
error("Cannot edit standard input", NULL_PARG);
break;
}
if (curr_altfilename != NULL)
{
error("Cannot edit file processed with LESSOPEN",
NULL_PARG);
break;
}
start_mca(A_SHELL, "!", ml_shell, 0);
/*
* Expand the editor prototype string
* and pass it to the system to execute.
* (Make sure the screen is displayed so the
* expansion of "+%lm" works.)
*/
make_display();
cmd_exec();
lsystem(pr_expand(editproto, 0), (char*)NULL);
break;
#else
error("Command not available", NULL_PARG);
break;
#endif
case A_NEXT_FILE:
/*
* Examine next file.
*/
#if TAGS
if (ntags())
{
error("No next file", NULL_PARG);
break;
}
#endif
if (number <= 0)
number = 1;
if (edit_next((int) number))
{
if (quit_at_eof && hit_eof &&
!(ch_getflags() & CH_HELPFILE))
quit(QUIT_OK);
parg.p_string = (number > 1) ? "(N-th) " : "";
error("No %snext file", &parg);
}
break;
case A_PREV_FILE:
/*
* Examine previous file.
*/
#if TAGS
if (ntags())
{
error("No previous file", NULL_PARG);
break;
}
#endif
if (number <= 0)
number = 1;
if (edit_prev((int) number))
{
parg.p_string = (number > 1) ? "(N-th) " : "";
error("No %sprevious file", &parg);
}
break;
case A_NEXT_TAG:
#if TAGS
if (number <= 0)
number = 1;
tagfile = nexttag((int) 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);
}
#else
error("Command not available", NULL_PARG);
#endif
break;
case A_PREV_TAG:
#if TAGS
if (number <= 0)
number = 1;
tagfile = prevtag((int) 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);
}
#else
error("Command not available", NULL_PARG);
#endif
break;
case A_INDEX_FILE:
/*
* Examine a particular file.
*/
if (number <= 0)
number = 1;
if (edit_index((int) number))
error("No such file", NULL_PARG);
break;
case A_REMOVE_FILE:
if (ch_getflags() & CH_HELPFILE)
break;
old_ifile = curr_ifile;
new_ifile = getoff_ifile(curr_ifile);
if (new_ifile == NULL_IFILE)
{
bell();
break;
}
if (edit_ifile(new_ifile) != 0)
{
reedit_ifile(old_ifile);
break;
}
del_ifile(old_ifile);
break;
case A_OPT_TOGGLE:
optflag = OPT_TOGGLE;
optgetname = FALSE;
mca_opt_toggle();
c = getcc();
goto again;
case A_DISP_OPTION:
/*
* Report a flag setting.
*/
optflag = OPT_NO_TOGGLE;
optgetname = FALSE;
mca_opt_toggle();
c = getcc();
goto again;
case A_FIRSTCMD:
/*
* Set an initial command for new files.
*/
start_mca(A_FIRSTCMD, "+", (void*)NULL, 0);
c = getcc();
goto again;
case A_SHELL:
/*
* Shell escape.
*/
#if SHELL_ESCAPE
if (secure)
{
error("Command not available", NULL_PARG);
break;
}
start_mca(A_SHELL, "!", ml_shell, 0);
c = getcc();
goto again;
#else
error("Command not available", NULL_PARG);
break;
#endif
case A_SETMARK:
/*
* Set a mark.
*/
if (ch_getflags() & CH_HELPFILE)
break;
start_mca(A_SETMARK, "mark: ", (void*)NULL, 0);
c = getcc();
if (c == erase_char || c == kill_char ||
c == '\n' || c == '\r')
break;
setmark(c);
break;
case A_GOMARK:
/*
* Go to a mark.
*/
start_mca(A_GOMARK, "goto mark: ", (void*)NULL, 0);
c = getcc();
if (c == erase_char || c == kill_char ||
c == '\n' || c == '\r')
break;
gomark(c);
break;
case A_PIPE:
#if PIPEC
if (secure)
{
error("Command not available", NULL_PARG);
break;
}
start_mca(A_PIPE, "|mark: ", (void*)NULL, 0);
c = getcc();
if (c == erase_char || c == kill_char)
break;
if (c == '\n' || c == '\r')
c = '.';
if (badmark(c))
break;
pipec = c;
start_mca(A_PIPE, "!", ml_shell, 0);
c = getcc();
goto again;
#else
error("Command not available", NULL_PARG);
break;
#endif
case A_B_BRACKET:
case A_F_BRACKET:
start_mca(action, "Brackets: ", (void*)NULL, 0);
c = getcc();
goto again;
case A_LSHIFT:
if (number > 0)
shift_count = number;
else
number = (shift_count > 0) ?
shift_count : sc_width / 2;
if (number > hshift)
number = hshift;
hshift -= number;
screen_trashed = 1;
break;
case A_RSHIFT:
if (number > 0)
shift_count = number;
else
number = (shift_count > 0) ?
shift_count : sc_width / 2;
hshift += number;
screen_trashed = 1;
break;
case A_PREFIX:
/*
* The command is incomplete (more chars are needed).
* Display the current char, so the user knows
* what's going on, and get another character.
*/
if (mca != A_PREFIX)
{
cmd_reset();
start_mca(A_PREFIX, " ", (void*)NULL,
CF_QUIT_ON_ERASE);
(void) cmd_char(c);
}
c = getcc();
goto again;
case A_NOACTION:
break;
default:
bell();
break;
}
}
}
less-382/decode.c 0100444 0000764 0000764 00000043347 10010075213 012736 0 ustar markn markn /*
* Copyright (C) 1984-2002 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines to decode user commands.
*
* This is all table driven.
* A command table is a sequence of command descriptors.
* Each command descriptor is a sequence of bytes with the following format:
* ...<0>
* The characters c1,c2,...,cN are the command string; that is,
* the characters which the user must type.
* It is terminated by a null <0> byte.
* The byte after the null byte is the action code associated
* with the command string.
* If an action byte is OR-ed with A_EXTRA, this indicates
* that the option byte is followed by an extra string.
*
* There may be many command tables.
* The first (default) table is built-in.
* Other tables are read in from "lesskey" files.
* All the tables are linked together and are searched in order.
*/
#include "less.h"
#include "cmd.h"
#include "lesskey.h"
extern int erase_char, kill_char;
extern int secure;
#define SK(k) \
SK_SPECIAL_KEY, (k), 6, 1, 1, 1
/*
* Command table is ordered roughly according to expected
* frequency of use, so the common commands are near the beginning.
*/
static unsigned char cmdtable[] =
{
'\r',0, A_F_LINE,
'\n',0, A_F_LINE,
'e',0, A_F_LINE,
'j',0, A_F_LINE,
SK(SK_DOWN_ARROW),0, A_F_LINE,
CONTROL('E'),0, A_F_LINE,
CONTROL('N'),0, A_F_LINE,
'k',0, A_B_LINE,
'y',0, A_B_LINE,
CONTROL('Y'),0, A_B_LINE,
SK(SK_CONTROL_K),0, A_B_LINE,
CONTROL('P'),0, A_B_LINE,
SK(SK_UP_ARROW),0, A_B_LINE,
'J',0, A_FF_LINE,
'K',0, A_BF_LINE,
'Y',0, A_BF_LINE,
'd',0, A_F_SCROLL,
CONTROL('D'),0, A_F_SCROLL,
'u',0, A_B_SCROLL,
CONTROL('U'),0, A_B_SCROLL,
' ',0, A_F_SCREEN,
'f',0, A_F_SCREEN,
CONTROL('F'),0, A_F_SCREEN,
CONTROL('V'),0, A_F_SCREEN,
SK(SK_PAGE_DOWN),0, A_F_SCREEN,
'b',0, A_B_SCREEN,
CONTROL('B'),0, A_B_SCREEN,
ESC,'v',0, A_B_SCREEN,
SK(SK_PAGE_UP),0, A_B_SCREEN,
'z',0, A_F_WINDOW,
'w',0, A_B_WINDOW,
ESC,' ',0, A_FF_SCREEN,
'F',0, A_F_FOREVER,
'R',0, A_FREPAINT,
'r',0, A_REPAINT,
CONTROL('R'),0, A_REPAINT,
CONTROL('L'),0, A_REPAINT,
ESC,'u',0, A_UNDO_SEARCH,
'g',0, A_GOLINE,
SK(SK_HOME),0, A_GOLINE,
'<',0, A_GOLINE,
ESC,'<',0, A_GOLINE,
'p',0, A_PERCENT,
'%',0, A_PERCENT,
ESC,'[',0, A_LSHIFT,
ESC,']',0, A_RSHIFT,
ESC,'(',0, A_LSHIFT,
ESC,')',0, A_RSHIFT,
SK(SK_RIGHT_ARROW),0, A_RSHIFT,
SK(SK_LEFT_ARROW),0, A_LSHIFT,
'{',0, A_F_BRACKET|A_EXTRA, '{','}',0,
'}',0, A_B_BRACKET|A_EXTRA, '{','}',0,
'(',0, A_F_BRACKET|A_EXTRA, '(',')',0,
')',0, A_B_BRACKET|A_EXTRA, '(',')',0,
'[',0, A_F_BRACKET|A_EXTRA, '[',']',0,
']',0, A_B_BRACKET|A_EXTRA, '[',']',0,
ESC,CONTROL('F'),0, A_F_BRACKET,
ESC,CONTROL('B'),0, A_B_BRACKET,
'G',0, A_GOEND,
ESC,'>',0, A_GOEND,
'>',0, A_GOEND,
SK(SK_END),0, A_GOEND,
'P',0, A_GOPOS,
'0',0, A_DIGIT,
'1',0, A_DIGIT,
'2',0, A_DIGIT,
'3',0, A_DIGIT,
'4',0, A_DIGIT,
'5',0, A_DIGIT,
'6',0, A_DIGIT,
'7',0, A_DIGIT,
'8',0, A_DIGIT,
'9',0, A_DIGIT,
'=',0, A_STAT,
CONTROL('G'),0, A_STAT,
':','f',0, A_STAT,
'/',0, A_F_SEARCH,
'?',0, A_B_SEARCH,
ESC,'/',0, A_F_SEARCH|A_EXTRA, '*',0,
ESC,'?',0, A_B_SEARCH|A_EXTRA, '*',0,
'n',0, A_AGAIN_SEARCH,
ESC,'n',0, A_T_AGAIN_SEARCH,
'N',0, A_REVERSE_SEARCH,
ESC,'N',0, A_T_REVERSE_SEARCH,
'm',0, A_SETMARK,
'\'',0, A_GOMARK,
CONTROL('X'),CONTROL('X'),0, A_GOMARK,
'E',0, A_EXAMINE,
':','e',0, A_EXAMINE,
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,
':','t',0, A_OPT_TOGGLE|A_EXTRA, 't',0,
's',0, A_OPT_TOGGLE|A_EXTRA, 'o',0,
'_',0, A_DISP_OPTION,
'|',0, A_PIPE,
'v',0, A_VISUAL,
'!',0, A_SHELL,
'+',0, A_FIRSTCMD,
'H',0, A_HELP,
'h',0, A_HELP,
SK(SK_F1),0, A_HELP,
'V',0, A_VERSION,
'q',0, A_QUIT,
'Q',0, A_QUIT,
':','q',0, A_QUIT,
':','Q',0, A_QUIT,
'Z','Z',0, A_QUIT
};
static unsigned char edittable[] =
{
'\t',0, EC_F_COMPLETE, /* TAB */
'\17',0, EC_B_COMPLETE, /* BACKTAB */
SK(SK_BACKTAB),0, EC_B_COMPLETE, /* BACKTAB */
ESC,'\t',0, EC_B_COMPLETE, /* ESC TAB */
CONTROL('L'),0, EC_EXPAND, /* CTRL-L */
CONTROL('V'),0, EC_LITERAL, /* BACKSLASH */
CONTROL('A'),0, EC_LITERAL, /* BACKSLASH */
ESC,'l',0, EC_RIGHT, /* ESC l */
SK(SK_RIGHT_ARROW),0, EC_RIGHT, /* RIGHTARROW */
ESC,'h',0, EC_LEFT, /* ESC h */
SK(SK_LEFT_ARROW),0, EC_LEFT, /* LEFTARROW */
ESC,'b',0, EC_W_LEFT, /* ESC b */
ESC,SK(SK_LEFT_ARROW),0, EC_W_LEFT, /* ESC LEFTARROW */
SK(SK_CTL_LEFT_ARROW),0, EC_W_LEFT, /* CTRL-LEFTARROW */
ESC,'w',0, EC_W_RIGHT, /* ESC w */
ESC,SK(SK_RIGHT_ARROW),0, EC_W_RIGHT, /* ESC RIGHTARROW */
SK(SK_CTL_RIGHT_ARROW),0, EC_W_RIGHT, /* CTRL-RIGHTARROW */
ESC,'i',0, EC_INSERT, /* ESC i */
SK(SK_INSERT),0, EC_INSERT, /* INSERT */
ESC,'x',0, EC_DELETE, /* ESC x */
SK(SK_DELETE),0, EC_DELETE, /* DELETE */
ESC,'X',0, EC_W_DELETE, /* ESC X */
ESC,SK(SK_DELETE),0, EC_W_DELETE, /* ESC DELETE */
SK(SK_CTL_DELETE),0, EC_W_DELETE, /* CTRL-DELETE */
SK(SK_CTL_BACKSPACE),0, EC_W_BACKSPACE, /* CTRL-BACKSPACE */
ESC,'\b',0, EC_W_BACKSPACE, /* ESC BACKSPACE */
ESC,'0',0, EC_HOME, /* ESC 0 */
SK(SK_HOME),0, EC_HOME, /* HOME */
ESC,'$',0, EC_END, /* ESC $ */
SK(SK_END),0, EC_END, /* END */
ESC,'k',0, EC_UP, /* ESC k */
SK(SK_UP_ARROW),0, EC_UP, /* UPARROW */
ESC,'j',0, EC_DOWN, /* ESC j */
SK(SK_DOWN_ARROW),0, EC_DOWN, /* DOWNARROW */
};
/*
* Structure to support a list of command tables.
*/
struct tablelist
{
struct tablelist *t_next;
char *t_start;
char *t_end;
};
/*
* List of command tables and list of line-edit tables.
*/
static struct tablelist *list_fcmd_tables = NULL;
static struct tablelist *list_ecmd_tables = NULL;
static struct tablelist *list_var_tables = NULL;
static struct tablelist *list_sysvar_tables = NULL;
/*
* Expand special key abbreviations in a command table.
*/
static void
expand_special_keys(table, len)
char *table;
int len;
{
register char *fm;
register char *to;
register int a;
char *repl;
int klen;
for (fm = table; fm < table + len; )
{
/*
* Rewrite each command in the table with any
* special key abbreviations expanded.
*/
for (to = fm; *fm != '\0'; )
{
if (*fm != SK_SPECIAL_KEY)
{
*to++ = *fm++;
continue;
}
/*
* After SK_SPECIAL_KEY, next byte is the type
* of special key (one of the SK_* contants),
* and the byte after that is the number of bytes,
* N, reserved by the abbreviation (including the
* SK_SPECIAL_KEY and key type bytes).
* Replace all N bytes with the actual bytes
* output by the special key on this terminal.
*/
repl = special_key_str(fm[1]);
klen = fm[2] & 0377;
fm += klen;
if (repl == NULL || (int) strlen(repl) > klen)
repl = "\377";
while (*repl != '\0')
*to++ = *repl++;
}
*to++ = '\0';
/*
* Fill any unused bytes between end of command and
* the action byte with A_SKIP.
*/
while (to <= fm)
*to++ = A_SKIP;
fm++;
a = *fm++ & 0377;
if (a & A_EXTRA)
{
while (*fm++ != '\0')
continue;
}
}
}
/*
* Initialize the command lists.
*/
public void
init_cmds()
{
/*
* Add the default command tables.
*/
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.
*/
add_hometable("LESSKEY_SYSTEM", LESSKEYFILE_SYS, 1);
/*
* Try to add the tables in the standard lesskey file "$HOME/.less".
*/
add_hometable("LESSKEY", LESSKEYFILE, 0);
#endif
}
/*
* Add a command table.
*/
static int
add_cmd_table(tlist, buf, len)
struct tablelist **tlist;
char *buf;
int len;
{
register struct tablelist *t;
if (len == 0)
return (0);
/*
* Allocate a tablelist structure, initialize it,
* and link it into the list of tables.
*/
if ((t = (struct tablelist *)
calloc(1, sizeof(struct tablelist))) == NULL)
{
return (-1);
}
expand_special_keys(buf, len);
t->t_start = buf;
t->t_end = buf + len;
t->t_next = *tlist;
*tlist = t;
return (0);
}
/*
* Add a command table.
*/
public void
add_fcmd_table(buf, len)
char *buf;
int len;
{
if (add_cmd_table(&list_fcmd_tables, buf, len) < 0)
error("Warning: some commands disabled", NULL_PARG);
}
/*
* Add an editing command table.
*/
public void
add_ecmd_table(buf, len)
char *buf;
int len;
{
if (add_cmd_table(&list_ecmd_tables, buf, len) < 0)
error("Warning: some edit commands disabled", NULL_PARG);
}
/*
* Add an environment variable table.
*/
static void
add_var_table(tlist, buf, len)
struct tablelist **tlist;
char *buf;
int len;
{
if (add_cmd_table(tlist, buf, len) < 0)
error("Warning: environment variables from lesskey file unavailable", NULL_PARG);
}
/*
* Search a single command table for the command string in cmd.
*/
static int
cmd_search(cmd, table, endtable, sp)
char *cmd;
char *table;
char *endtable;
char **sp;
{
register char *p;
register char *q;
register int a;
*sp = NULL;
for (p = table, q = cmd; p < endtable; p++, q++)
{
if (*p == *q)
{
/*
* Current characters match.
* If we're at the end of the string, we've found it.
* Return the action code, which is the character
* after the null at the end of the string
* in the command table.
*/
if (*p == '\0')
{
a = *++p & 0377;
while (a == A_SKIP)
a = *++p & 0377;
if (a == A_END_LIST)
{
/*
* We get here only if the original
* cmd string passed in was empty ("").
* I don't think that can happen,
* but just in case ...
*/
return (A_UINVALID);
}
/*
* Check for an "extra" string.
*/
if (a & A_EXTRA)
{
*sp = ++p;
a &= ~A_EXTRA;
}
return (a);
}
} else if (*q == '\0')
{
/*
* Hit the end of the user's command,
* but not the end of the string in the command table.
* The user's command is incomplete.
*/
return (A_PREFIX);
} else
{
/*
* Not a match.
* Skip ahead to the next command in the
* command table, and reset the pointer
* to the beginning of the user's command.
*/
if (*p == '\0' && p[1] == A_END_LIST)
{
/*
* A_END_LIST is a special marker that tells
* us to abort the cmd search.
*/
return (A_UINVALID);
}
while (*p++ != '\0')
continue;
while (*p == A_SKIP)
p++;
if (*p & A_EXTRA)
while (*++p != '\0')
continue;
q = cmd-1;
}
}
/*
* No match found in the entire command table.
*/
return (A_INVALID);
}
/*
* Decode a command character and return the associated action.
* The "extra" string, if any, is returned in sp.
*/
static int
cmd_decode(tlist, cmd, sp)
struct tablelist *tlist;
char *cmd;
char **sp;
{
register struct tablelist *t;
register int action = A_INVALID;
/*
* Search thru all the command tables.
* Stop when we find an action which is not A_INVALID.
*/
for (t = tlist; t != NULL; t = t->t_next)
{
action = cmd_search(cmd, t->t_start, t->t_end, sp);
if (action != A_INVALID)
break;
}
if (action == A_UINVALID)
action = A_INVALID;
return (action);
}
/*
* Decode a command from the cmdtables list.
*/
public int
fcmd_decode(cmd, sp)
char *cmd;
char **sp;
{
return (cmd_decode(list_fcmd_tables, cmd, sp));
}
/*
* Decode a command from the edittables list.
*/
public int
ecmd_decode(cmd, sp)
char *cmd;
char **sp;
{
return (cmd_decode(list_ecmd_tables, cmd, sp));
}
/*
* Get the value of an environment variable.
* Looks first in the lesskey file, then in the real environment.
*/
public char *
lgetenv(var)
char *var;
{
int a;
char *s;
a = cmd_decode(list_var_tables, var, &s);
if (a == EV_OK)
return (s);
s = getenv(var);
if (s != NULL && *s != '\0')
return (s);
a = cmd_decode(list_sysvar_tables, var, &s);
if (a == EV_OK)
return (s);
return (NULL);
}
#if USERFILE
/*
* Get an "integer" from a lesskey file.
* Integers are stored in a funny format:
* two bytes, low order first, in radix KRADIX.
*/
static int
gint(sp)
char **sp;
{
int n;
n = *(*sp)++;
n += *(*sp)++ * KRADIX;
return (n);
}
/*
* Process an old (pre-v241) lesskey file.
*/
static int
old_lesskey(buf, len)
char *buf;
int len;
{
/*
* Old-style lesskey file.
* The file must end with either
* ...,cmd,0,action
* or ...,cmd,0,action|A_EXTRA,string,0
* So the last byte or the second to last byte must be zero.
*/
if (buf[len-1] != '\0' && buf[len-2] != '\0')
return (-1);
add_fcmd_table(buf, len);
return (0);
}
/*
* Process a new (post-v241) lesskey file.
*/
static int
new_lesskey(buf, len, sysvar)
char *buf;
int len;
int sysvar;
{
char *p;
register int c;
register int n;
/*
* New-style lesskey file.
* Extract the pieces.
*/
if (buf[len-3] != C0_END_LESSKEY_MAGIC ||
buf[len-2] != C1_END_LESSKEY_MAGIC ||
buf[len-1] != C2_END_LESSKEY_MAGIC)
return (-1);
p = buf + 4;
for (;;)
{
c = *p++;
switch (c)
{
case CMD_SECTION:
n = gint(&p);
add_fcmd_table(p, n);
p += n;
break;
case EDIT_SECTION:
n = gint(&p);
add_ecmd_table(p, n);
p += n;
break;
case VAR_SECTION:
n = gint(&p);
add_var_table((sysvar) ?
&list_sysvar_tables : &list_var_tables, p, n);
p += n;
break;
case END_SECTION:
return (0);
default:
/*
* Unrecognized section type.
*/
return (-1);
}
}
}
/*
* Set up a user command table, based on a "lesskey" file.
*/
public int
lesskey(filename, sysvar)
char *filename;
int sysvar;
{
register char *buf;
register POSITION len;
register long n;
register int f;
if (secure)
return (1);
/*
* Try to open the lesskey file.
*/
filename = shell_unquote(filename);
f = open(filename, OPEN_READ);
free(filename);
if (f < 0)
return (1);
/*
* Read the file into a buffer.
* We first figure out the size of the file and allocate space for it.
* {{ Minimal error checking is done here.
* A garbage .less file will produce strange results.
* To avoid a large amount of error checking code here, we
* rely on the lesskey program to generate a good .less file. }}
*/
len = filesize(f);
if (len == NULL_POSITION || len < 3)
{
/*
* Bad file (valid file must have at least 3 chars).
*/
close(f);
return (-1);
}
if ((buf = (char *) calloc((int)len, sizeof(char))) == NULL)
{
close(f);
return (-1);
}
if (lseek(f, (off_t)0, 0) == BAD_LSEEK)
{
free(buf);
close(f);
return (-1);
}
n = read(f, buf, (unsigned int) len);
close(f);
if (n != len)
{
free(buf);
return (-1);
}
/*
* Figure out if this is an old-style (before version 241)
* or new-style lesskey file format.
*/
if (buf[0] != C0_LESSKEY_MAGIC || buf[1] != C1_LESSKEY_MAGIC ||
buf[2] != C2_LESSKEY_MAGIC || buf[3] != C3_LESSKEY_MAGIC)
return (old_lesskey(buf, (int)len));
return (new_lesskey(buf, (int)len, sysvar));
}
/*
* Add the standard lesskey file "$HOME/.less"
*/
public void
add_hometable(envname, def_filename, sysvar)
char *envname;
char *def_filename;
int sysvar;
{
char *filename;
PARG parg;
if (envname != NULL && (filename = lgetenv(envname)) != NULL)
filename = save(filename);
else if (sysvar)
filename = save(def_filename);
else
filename = homefile(def_filename);
if (filename == NULL)
return;
if (lesskey(filename, sysvar) < 0)
{
parg.p_string = filename;
error("Cannot use lesskey file \"%s\"", &parg);
}
free(filename);
}
#endif
/*
* See if a char is a special line-editing command.
*/
public int
editchar(c, flags)
int c;
int flags;
{
int action;
int nch;
char *s;
char usercmd[MAX_CMDLEN+1];
/*
* An editing character could actually be a sequence of characters;
* for example, an escape sequence sent by pressing the uparrow key.
* To match the editing string, we use the command decoder
* but give it the edit-commands command table
* This table is constructed to match the user's keyboard.
*/
if (c == erase_char)
return (EC_BACKSPACE);
if (c == kill_char)
return (EC_LINEKILL);
/*
* Collect characters in a buffer.
* Start with the one we have, and get more if we need them.
*/
nch = 0;
do {
if (nch > 0)
c = getcc();
usercmd[nch] = c;
usercmd[nch+1] = '\0';
nch++;
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)
{
/*
* The caller says there is no history list.
* Reject any history-manipulation action.
*/
switch (action)
{
case EC_UP:
case EC_DOWN:
action = A_INVALID;
break;
}
}
#endif
#if TAB_COMPLETE_FILENAME
if (flags & EC_NOCOMPLETE)
{
/*
* The caller says we don't want any filename completion cmds.
* Reject them.
*/
switch (action)
{
case EC_F_COMPLETE:
case EC_B_COMPLETE:
case EC_EXPAND:
action = A_INVALID;
break;
}
}
#endif
if ((flags & EC_PEEK) || action == A_INVALID)
{
/*
* We're just peeking, or we didn't understand the command.
* Unget all the characters we read in the loop above.
* This does NOT include the original character that was
* passed in as a parameter.
*/
while (nch > 1)
{
ungetcc(usercmd[--nch]);
}
} else
{
if (s != NULL)
ungetsc(s);
}
return action;
}
less-382/edit.c 0100444 0000764 0000764 00000035112 10010075213 012427 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
#include "less.h"
public int fd0 = 0;
extern int new_file;
extern int errmsgs;
extern int cbufs;
extern char *every_first_cmd;
extern int any_display;
extern int force_open;
extern int is_tty;
extern int sigs;
extern IFILE curr_ifile;
extern IFILE old_ifile;
extern struct scrpos initial_scrpos;
extern void constant *ml_examine;
#if SPACES_IN_FILENAMES
extern char openquote;
extern char closequote;
#endif
#if LOGFILE
extern int logfile;
extern int force_logfile;
extern char *namelogfile;
#endif
char *curr_altfilename = NULL;
static void *curr_altpipe;
/*
* Textlist functions deal with a list of words separated by spaces.
* init_textlist sets up a textlist structure.
* forw_textlist uses that structure to iterate thru the list of
* words, returning each one as a standard null-terminated string.
* back_textlist does the same, but runs thru the list backwards.
*/
public void
init_textlist(tlist, str)
struct textlist *tlist;
char *str;
{
char *s;
#if SPACES_IN_FILENAMES
int meta_quoted = 0;
int delim_quoted = 0;
char *esc = get_meta_escape();
int esclen = strlen(esc);
#endif
tlist->string = skipsp(str);
tlist->endstring = tlist->string + strlen(tlist->string);
for (s = str; s < tlist->endstring; s++)
{
#if SPACES_IN_FILENAMES
if (meta_quoted)
{
meta_quoted = 0;
} else if (esclen > 0 && s + esclen < tlist->endstring &&
strncmp(s, esc, esclen) == 0)
{
meta_quoted = 1;
s += esclen - 1;
} else if (delim_quoted)
{
if (*s == closequote)
delim_quoted = 0;
} else /* (!delim_quoted) */
{
if (*s == openquote)
delim_quoted = 1;
else if (*s == ' ')
*s = '\0';
}
#else
if (*s == ' ')
*s = '\0';
#endif
}
}
public char *
forw_textlist(tlist, prev)
struct textlist *tlist;
char *prev;
{
char *s;
/*
* prev == NULL means return the first word in the list.
* Otherwise, return the word after "prev".
*/
if (prev == NULL)
s = tlist->string;
else
s = prev + strlen(prev);
if (s >= tlist->endstring)
return (NULL);
while (*s == '\0')
s++;
if (s >= tlist->endstring)
return (NULL);
return (s);
}
public char *
back_textlist(tlist, prev)
struct textlist *tlist;
char *prev;
{
char *s;
/*
* prev == NULL means return the last word in the list.
* Otherwise, return the word before "prev".
*/
if (prev == NULL)
s = tlist->endstring;
else if (prev <= tlist->string)
return (NULL);
else
s = prev - 1;
while (*s == '\0')
s--;
if (s <= tlist->string)
return (NULL);
while (s[-1] != '\0' && s > tlist->string)
s--;
return (s);
}
/*
* Close the current input file.
*/
static void
close_file()
{
struct scrpos scrpos;
if (curr_ifile == NULL_IFILE)
return;
/*
* Save the current position so that we can return to
* the same position if we edit this file again.
*/
get_scrpos(&scrpos);
if (scrpos.pos != NULL_POSITION)
{
store_pos(curr_ifile, &scrpos);
lastmark();
}
/*
* Close the file descriptor, unless it is a pipe.
*/
ch_close();
/*
* If we opened a file using an alternate name,
* do special stuff to close it.
*/
if (curr_altfilename != NULL)
{
close_altfile(curr_altfilename, get_filename(curr_ifile),
curr_altpipe);
free(curr_altfilename);
curr_altfilename = NULL;
}
curr_ifile = NULL_IFILE;
}
/*
* Edit a new file (given its name).
* Filename == "-" means standard input.
* Filename == NULL means just close the current file.
*/
public int
edit(filename)
char *filename;
{
if (filename == NULL)
return (edit_ifile(NULL_IFILE));
return (edit_ifile(get_ifile(filename, curr_ifile)));
}
/*
* Edit a new file (given its IFILE).
* ifile == NULL means just close the current file.
*/
public int
edit_ifile(ifile)
IFILE ifile;
{
int f;
int answer;
int no_display;
int chflags;
char *filename;
char *open_filename;
char *qopen_filename;
char *alt_filename;
void *alt_pipe;
IFILE was_curr_ifile;
PARG parg;
if (ifile == curr_ifile)
{
/*
* Already have the correct file open.
*/
return (0);
}
/*
* We must close the currently open file now.
* This is necessary to make the open_altfile/close_altfile pairs
* nest properly (or rather to avoid nesting at all).
* {{ Some stupid implementations of popen() mess up if you do:
* fA = popen("A"); fB = popen("B"); pclose(fA); pclose(fB); }}
*/
#if LOGFILE
end_logfile();
#endif
was_curr_ifile = save_curr_ifile();
if (curr_ifile != NULL_IFILE)
{
chflags = ch_getflags();
close_file();
if ((chflags & CH_HELPFILE) && held_ifile(was_curr_ifile) <= 1)
{
/*
* Don't keep the help file in the ifile list.
*/
del_ifile(was_curr_ifile);
was_curr_ifile = old_ifile;
}
}
if (ifile == NULL_IFILE)
{
/*
* No new file to open.
* (Don't set old_ifile, because if you call edit_ifile(NULL),
* you're supposed to have saved curr_ifile yourself,
* and you'll restore it if necessary.)
*/
unsave_ifile(was_curr_ifile);
return (0);
}
filename = save(get_filename(ifile));
/*
* See if LESSOPEN specifies an "alternate" file to open.
*/
alt_pipe = NULL;
alt_filename = open_altfile(filename, &f, &alt_pipe);
open_filename = (alt_filename != NULL) ? alt_filename : filename;
qopen_filename = shell_unquote(open_filename);
chflags = 0;
if (alt_pipe != NULL)
{
/*
* The alternate "file" is actually a pipe.
* f has already been set to the file descriptor of the pipe
* in the call to open_altfile above.
* Keep the file descriptor open because it was opened
* via popen(), and pclose() wants to close it.
*/
chflags |= CH_POPENED;
} else if (strcmp(open_filename, "-") == 0)
{
/*
* Use standard input.
* Keep the file descriptor open because we can't reopen it.
*/
f = fd0;
chflags |= CH_KEEPOPEN;
/*
* Must switch stdin to BINARY mode.
*/
SET_BINARY(f);
#if MSDOS_COMPILER==DJGPPC
/*
* Setting stdin to binary by default causes
* Ctrl-C to not raise SIGINT. We must undo
* that side-effect.
*/
__djgpp_set_ctrl_c(1);
#endif
} else if (strcmp(open_filename, FAKE_HELPFILE) == 0)
{
f = -1;
chflags |= CH_HELPFILE;
} else if ((parg.p_string = bad_file(open_filename)) != NULL)
{
/*
* It looks like a bad file. Don't try to open it.
*/
error("%s", &parg);
free(parg.p_string);
err1:
if (alt_filename != NULL)
{
close_altfile(alt_filename, filename, alt_pipe);
free(alt_filename);
}
del_ifile(ifile);
free(qopen_filename);
free(filename);
/*
* Re-open the current file.
*/
reedit_ifile(was_curr_ifile);
return (1);
} else if ((f = open(qopen_filename, OPEN_READ)) < 0)
{
/*
* Got an error trying to open it.
*/
parg.p_string = errno_message(filename);
error("%s", &parg);
free(parg.p_string);
goto err1;
} else
{
chflags |= CH_CANSEEK;
if (!force_open && !opened(ifile) && bin_file(f))
{
/*
* Looks like a binary file.
* Ask user if we should proceed.
*/
parg.p_string = filename;
answer = query("\"%s\" may be a binary file. See it anyway? ",
&parg);
if (answer != 'y' && answer != 'Y')
{
close(f);
goto err1;
}
}
}
free(qopen_filename);
/*
* Get the new ifile.
* Get the saved position for the file.
*/
if (was_curr_ifile != NULL_IFILE)
{
old_ifile = was_curr_ifile;
unsave_ifile(was_curr_ifile);
}
curr_ifile = ifile;
curr_altfilename = alt_filename;
curr_altpipe = alt_pipe;
set_open(curr_ifile); /* File has been opened */
get_pos(curr_ifile, &initial_scrpos);
new_file = TRUE;
ch_init(f, chflags);
if (!(chflags & CH_HELPFILE))
{
#if LOGFILE
if (namelogfile != NULL && is_tty)
use_logfile(namelogfile);
#endif
if (every_first_cmd != NULL)
ungetsc(every_first_cmd);
}
no_display = !any_display;
flush();
any_display = TRUE;
if (is_tty)
{
/*
* Output is to a real tty.
*/
/*
* Indicate there is nothing displayed yet.
*/
pos_clear();
clr_linenum();
#if HILITE_SEARCH
clr_hilite();
#endif
cmd_addhist(ml_examine, filename);
if (no_display && errmsgs > 0)
{
/*
* We displayed some messages on error output
* (file descriptor 2; see error() function).
* Before erasing the screen contents,
* display the file name and wait for a keystroke.
*/
parg.p_string = filename;
error("%s", &parg);
}
}
free(filename);
return (0);
}
/*
* Edit a space-separated list of files.
* For each filename in the list, enter it into the ifile list.
* Then edit the first one.
*/
public int
edit_list(filelist)
char *filelist;
{
IFILE save_ifile;
char *good_filename;
char *filename;
char *gfilelist;
char *gfilename;
struct textlist tl_files;
struct textlist tl_gfiles;
save_ifile = save_curr_ifile();
good_filename = NULL;
/*
* Run thru each filename in the list.
* Try to glob the filename.
* If it doesn't expand, just try to open the filename.
* If it does expand, try to open each name in that list.
*/
init_textlist(&tl_files, filelist);
filename = NULL;
while ((filename = forw_textlist(&tl_files, filename)) != NULL)
{
gfilelist = lglob(filename);
init_textlist(&tl_gfiles, gfilelist);
gfilename = NULL;
while ((gfilename = forw_textlist(&tl_gfiles, gfilename)) != NULL)
{
if (edit(gfilename) == 0 && good_filename == NULL)
good_filename = get_filename(curr_ifile);
}
free(gfilelist);
}
/*
* Edit the first valid filename in the list.
*/
if (good_filename == NULL)
{
unsave_ifile(save_ifile);
return (1);
}
if (get_ifile(good_filename, curr_ifile) == curr_ifile)
{
/*
* Trying to edit the current file; don't reopen it.
*/
unsave_ifile(save_ifile);
return (0);
}
reedit_ifile(save_ifile);
return (edit(good_filename));
}
/*
* Edit the first file in the command line (ifile) list.
*/
public int
edit_first()
{
curr_ifile = NULL_IFILE;
return (edit_next(1));
}
/*
* Edit the last file in the command line (ifile) list.
*/
public int
edit_last()
{
curr_ifile = NULL_IFILE;
return (edit_prev(1));
}
/*
* Edit the next or previous file in the command line (ifile) list.
*/
static int
edit_istep(h, n, dir)
IFILE h;
int n;
int dir;
{
IFILE next;
/*
* Skip n filenames, then try to edit each filename.
*/
for (;;)
{
next = (dir > 0) ? next_ifile(h) : prev_ifile(h);
if (--n < 0)
{
if (edit_ifile(h) == 0)
break;
}
if (next == NULL_IFILE)
{
/*
* Reached end of the ifile list.
*/
return (1);
}
if (ABORT_SIGS())
{
/*
* Interrupt breaks out, if we're in a long
* list of files that can't be opened.
*/
return (1);
}
h = next;
}
/*
* Found a file that we can edit.
*/
return (0);
}
static int
edit_inext(h, n)
IFILE h;
int n;
{
return (edit_istep(h, n, 1));
}
public int
edit_next(n)
int n;
{
return edit_istep(curr_ifile, n, 1);
}
static int
edit_iprev(h, n)
IFILE h;
int n;
{
return (edit_istep(h, n, -1));
}
public int
edit_prev(n)
int n;
{
return edit_istep(curr_ifile, n, -1);
}
/*
* Edit a specific file in the command line (ifile) list.
*/
public int
edit_index(n)
int n;
{
IFILE h;
h = NULL_IFILE;
do
{
if ((h = next_ifile(h)) == NULL_IFILE)
{
/*
* Reached end of the list without finding it.
*/
return (1);
}
} while (get_index(h) != n);
return (edit_ifile(h));
}
public IFILE
save_curr_ifile()
{
if (curr_ifile != NULL_IFILE)
hold_ifile(curr_ifile, 1);
return (curr_ifile);
}
public void
unsave_ifile(save_ifile)
IFILE save_ifile;
{
if (save_ifile != NULL_IFILE)
hold_ifile(save_ifile, -1);
}
/*
* Reedit the ifile which was previously open.
*/
public void
reedit_ifile(save_ifile)
IFILE save_ifile;
{
IFILE next;
IFILE prev;
/*
* Try to reopen the ifile.
* Note that opening it may fail (maybe the file was removed),
* in which case the ifile will be deleted from the list.
* So save the next and prev ifiles first.
*/
unsave_ifile(save_ifile);
next = next_ifile(save_ifile);
prev = prev_ifile(save_ifile);
if (edit_ifile(save_ifile) == 0)
return;
/*
* If can't reopen it, open the next input file in the list.
*/
if (next != NULL_IFILE && edit_inext(next, 0) == 0)
return;
/*
* If can't open THAT one, open the previous input file in the list.
*/
if (prev != NULL_IFILE && edit_iprev(prev, 0) == 0)
return;
/*
* If can't even open that, we're stuck. Just quit.
*/
quit(QUIT_ERROR);
}
/*
* Edit standard input.
*/
public int
edit_stdin()
{
if (isatty(fd0))
{
error("Missing filename (\"less --help\" for help)", NULL_PARG);
quit(QUIT_OK);
}
return (edit("-"));
}
/*
* Copy a file directly to standard output.
* Used if standard output is not a tty.
*/
public void
cat_file()
{
register int c;
while ((c = ch_forw_get()) != EOI)
putchr(c);
flush();
}
#if LOGFILE
/*
* If the user asked for a log file and our input file
* is standard input, create the log file.
* We take care not to blindly overwrite an existing file.
*/
public void
use_logfile(filename)
char *filename;
{
register int exists;
register int answer;
PARG parg;
if (ch_getflags() & CH_CANSEEK)
/*
* Can't currently use a log file on a file that can seek.
*/
return;
/*
* {{ We could use access() here. }}
*/
filename = shell_unquote(filename);
exists = open(filename, OPEN_READ);
close(exists);
exists = (exists >= 0);
/*
* Decide whether to overwrite the log file or append to it.
* If it doesn't exist we "overwrite" it.
*/
if (!exists || force_logfile)
{
/*
* Overwrite (or create) the log file.
*/
answer = 'O';
} else
{
/*
* Ask user what to do.
*/
parg.p_string = filename;
answer = query("Warning: \"%s\" exists; Overwrite, Append or Don't log? ", &parg);
}
loop:
switch (answer)
{
case 'O': case 'o':
/*
* Overwrite: create the file.
*/
logfile = creat(filename, 0644);
break;
case 'A': case 'a':
/*
* Append: open the file and seek to the end.
*/
logfile = open(filename, OPEN_APPEND);
if (lseek(logfile, (off_t)0, 2) == BAD_LSEEK)
{
close(logfile);
logfile = -1;
}
break;
case 'D': case 'd':
/*
* Don't do anything.
*/
free(filename);
return;
case 'q':
quit(QUIT_OK);
/*NOTREACHED*/
default:
/*
* Eh?
*/
answer = query("Overwrite, Append, or Don't log? (Type \"O\", \"A\", \"D\" or \"q\") ", NULL_PARG);
goto loop;
}
if (logfile < 0)
{
/*
* Error in opening logfile.
*/
parg.p_string = filename;
error("Cannot write to \"%s\"", &parg);
free(filename);
return;
}
free(filename);
SET_BINARY(logfile);
}
#endif
less-382/filename.c 0100444 0000764 0000764 00000043770 10010075213 013273 0 ustar markn markn /*
* Copyright (C) 1984-2002 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines to mess around with filenames (and files).
* Much of this is very OS dependent.
*/
#include "less.h"
#include "lglob.h"
#if MSDOS_COMPILER
#include
#if MSDOS_COMPILER==WIN32C && !defined(_MSC_VER)
#include
#endif
#if MSDOS_COMPILER==DJGPPC
#include
#include
#define _MAX_PATH PATH_MAX
#endif
#endif
#ifdef _OSK
#include
#ifndef _OSK_MWC32
#include
#endif
#endif
#if OS2
#include
#endif
#if HAVE_STAT
#include
#ifndef S_ISDIR
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
#ifndef S_ISREG
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
#endif
extern int force_open;
extern int secure;
extern int use_lessopen;
extern IFILE curr_ifile;
extern IFILE old_ifile;
#if SPACES_IN_FILENAMES
extern char openquote;
extern char closequote;
#endif
/*
* Remove quotes around a filename.
*/
public char *
shell_unquote(str)
char *str;
{
char *name;
char *p;
name = p = (char *) ecalloc(strlen(str)+1, sizeof(char));
if (*str == openquote)
{
str++;
while (*str != '\0')
{
if (*str == closequote)
{
if (str[1] != closequote)
break;
str++;
}
*p++ = *str++;
}
} else
{
char *esc = get_meta_escape();
int esclen = strlen(esc);
while (*str != '\0')
{
if (esclen > 0 && strncmp(str, esc, esclen) == 0)
str += esclen;
*p++ = *str++;
}
}
*p = '\0';
return (name);
}
/*
* Get the shell's escape character.
*/
public char *
get_meta_escape()
{
char *s;
s = lgetenv("LESSMETAESCAPE");
if (s == NULL)
s = DEF_METAESCAPE;
return (s);
}
/*
* Get the characters which the shell considers to be "metacharacters".
*/
static char *
metachars()
{
static char *mchars = NULL;
if (mchars == NULL)
{
mchars = lgetenv("LESSMETACHARS");
if (mchars == NULL)
mchars = DEF_METACHARS;
}
return (mchars);
}
/*
* Is this a shell metacharacter?
*/
static int
metachar(c)
char c;
{
return (strchr(metachars(), c) != NULL);
}
/*
* Insert a backslash before each metacharacter in a string.
*/
public char *
shell_quote(s)
char *s;
{
char *p;
char *newstr;
int len;
char *esc = get_meta_escape();
int esclen = strlen(esc);
int use_quotes = 0;
int have_quotes = 0;
/*
* Determine how big a string we need to allocate.
*/
len = 1; /* Trailing null byte */
for (p = s; *p != '\0'; p++)
{
len++;
if (*p == openquote || *p == closequote)
have_quotes = 1;
if (metachar(*p))
{
if (esclen == 0)
{
/*
* We've got a metachar, but this shell
* doesn't support escape chars. Use quotes.
*/
use_quotes = 1;
} else
{
/*
* Allow space for the escape char.
*/
len += esclen;
}
}
}
if (use_quotes)
{
if (have_quotes)
/*
* We can't quote a string that contains quotes.
*/
return (NULL);
len = strlen(s) + 3;
}
/*
* Allocate and construct the new string.
*/
newstr = p = (char *) ecalloc(len, sizeof(char));
if (use_quotes)
{
sprintf(newstr, "%c%s%c", openquote, s, closequote);
} else
{
while (*s != '\0')
{
if (metachar(*s))
{
/*
* Add the escape char.
*/
strcpy(p, esc);
p += esclen;
}
*p++ = *s++;
}
*p = '\0';
}
return (newstr);
}
/*
* Return a pathname that points to a specified file in a specified directory.
* Return NULL if the file does not exist in the directory.
*/
static char *
dirfile(dirname, filename)
char *dirname;
char *filename;
{
char *pathname;
char *qpathname;
int f;
if (dirname == NULL || *dirname == '\0')
return (NULL);
/*
* Construct the full pathname.
*/
pathname = (char *) calloc(strlen(dirname) + strlen(filename) + 2,
sizeof(char));
if (pathname == NULL)
return (NULL);
sprintf(pathname, "%s%s%s", dirname, PATHNAME_SEP, filename);
/*
* Make sure the file exists.
*/
qpathname = shell_unquote(pathname);
f = open(qpathname, OPEN_READ);
if (f < 0)
{
free(pathname);
pathname = NULL;
} else
{
close(f);
}
free(qpathname);
return (pathname);
}
/*
* Return the full pathname of the given file in the "home directory".
*/
public char *
homefile(filename)
char *filename;
{
register char *pathname;
/*
* Try $HOME/filename.
*/
pathname = dirfile(lgetenv("HOME"), filename);
if (pathname != NULL)
return (pathname);
#if OS2
/*
* Try $INIT/filename.
*/
pathname = dirfile(lgetenv("INIT"), filename);
if (pathname != NULL)
return (pathname);
#endif
#if MSDOS_COMPILER || OS2
/*
* Look for the file anywhere on search path.
*/
pathname = (char *) calloc(_MAX_PATH, sizeof(char));
#if MSDOS_COMPILER==DJGPPC
{
char *res = searchpath(filename);
if (res == 0)
*pathname = '\0';
else
strcpy(pathname, res);
}
#else
_searchenv(filename, "PATH", pathname);
#endif
if (*pathname != '\0')
return (pathname);
free(pathname);
#endif
return (NULL);
}
/*
* Expand a string, substituting any "%" with the current filename,
* and any "#" with the previous filename.
* But a string of N "%"s is just replaced with N-1 "%"s.
* Likewise for a string of N "#"s.
* {{ This is a lot of work just to support % and #. }}
*/
public char *
fexpand(s)
char *s;
{
register char *fr, *to;
register int n;
register char *e;
IFILE ifile;
#define fchar_ifile(c) \
((c) == '%' ? curr_ifile : \
(c) == '#' ? old_ifile : NULL_IFILE)
/*
* Make one pass to see how big a buffer we
* need to allocate for the expanded string.
*/
n = 0;
for (fr = s; *fr != '\0'; fr++)
{
switch (*fr)
{
case '%':
case '#':
if (fr > s && fr[-1] == *fr)
{
/*
* Second (or later) char in a string
* of identical chars. Treat as normal.
*/
n++;
} else if (fr[1] != *fr)
{
/*
* Single char (not repeated). Treat specially.
*/
ifile = fchar_ifile(*fr);
if (ifile == NULL_IFILE)
n++;
else
n += strlen(get_filename(ifile));
}
/*
* Else it is the first char in a string of
* identical chars. Just discard it.
*/
break;
default:
n++;
break;
}
}
e = (char *) ecalloc(n+1, sizeof(char));
/*
* Now copy the string, expanding any "%" or "#".
*/
to = e;
for (fr = s; *fr != '\0'; fr++)
{
switch (*fr)
{
case '%':
case '#':
if (fr > s && fr[-1] == *fr)
{
*to++ = *fr;
} else if (fr[1] != *fr)
{
ifile = fchar_ifile(*fr);
if (ifile == NULL_IFILE)
*to++ = *fr;
else
{
strcpy(to, get_filename(ifile));
to += strlen(to);
}
}
break;
default:
*to++ = *fr;
break;
}
}
*to = '\0';
return (e);
}
#if TAB_COMPLETE_FILENAME
/*
* Return a blank-separated list of filenames which "complete"
* the given string.
*/
public char *
fcomplete(s)
char *s;
{
char *fpat;
char *qs;
if (secure)
return (NULL);
/*
* Complete the filename "s" by globbing "s*".
*/
#if MSDOS_COMPILER && (MSDOS_COMPILER == MSOFTC || MSDOS_COMPILER == BORLANDC)
/*
* But in DOS, we have to glob "s*.*".
* But if the final component of the filename already has
* a dot in it, just do "s*".
* (Thus, "FILE" is globbed as "FILE*.*",
* but "FILE.A" is globbed as "FILE.A*").
*/
{
char *slash;
for (slash = s+strlen(s)-1; slash > s; slash--)
if (*slash == *PATHNAME_SEP || *slash == '/')
break;
fpat = (char *) ecalloc(strlen(s)+4, sizeof(char));
if (strchr(slash, '.') == NULL)
sprintf(fpat, "%s*.*", s);
else
sprintf(fpat, "%s*", s);
}
#else
fpat = (char *) ecalloc(strlen(s)+2, sizeof(char));
sprintf(fpat, "%s*", s);
#endif
qs = lglob(fpat);
s = shell_unquote(qs);
if (strcmp(s,fpat) == 0)
{
/*
* The filename didn't expand.
*/
free(qs);
qs = NULL;
}
free(s);
free(fpat);
return (qs);
}
#endif
/*
* Try to determine if a file is "binary".
* This is just a guess, and we need not try too hard to make it accurate.
*/
public int
bin_file(f)
int f;
{
int i;
int n;
unsigned char data[64];
if (!seekable(f))
return (0);
if (lseek(f, (off_t)0, 0) == BAD_LSEEK)
return (0);
n = read(f, data, sizeof(data));
for (i = 0; i < n; i++)
if (binary_char(data[i]))
return (1);
return (0);
}
/*
* Try to determine the size of a file by seeking to the end.
*/
static POSITION
seek_filesize(f)
int f;
{
off_t spos;
spos = lseek(f, (off_t)0, 2);
if (spos == BAD_LSEEK)
return (NULL_POSITION);
return ((POSITION) spos);
}
/*
* Read a string from a file.
* Return a pointer to the string in memory.
*/
static char *
readfd(fd)
FILE *fd;
{
int len;
int ch;
char *buf;
char *p;
/*
* Make a guess about how many chars in the string
* and allocate a buffer to hold it.
*/
len = 100;
buf = (char *) ecalloc(len, sizeof(char));
for (p = buf; ; p++)
{
if ((ch = getc(fd)) == '\n' || ch == EOF)
break;
if (p - buf >= len-1)
{
/*
* The string is too big to fit in the buffer we have.
* Allocate a new buffer, twice as big.
*/
len *= 2;
*p = '\0';
p = (char *) ecalloc(len, sizeof(char));
strcpy(p, buf);
free(buf);
buf = p;
p = buf + strlen(buf);
}
*p = ch;
}
*p = '\0';
return (buf);
}
#if HAVE_POPEN
FILE *popen();
/*
* Execute a shell command.
* Return a pointer to a pipe connected to the shell command's standard output.
*/
static FILE *
shellcmd(cmd)
char *cmd;
{
FILE *fd;
#if HAVE_SHELL
char *shell;
shell = lgetenv("SHELL");
if (shell != NULL && *shell != '\0')
{
char *scmd;
char *esccmd;
/*
* Read the output of <$SHELL -c cmd>.
* Escape any metacharacters in the command.
*/
esccmd = shell_quote(cmd);
if (esccmd == NULL)
{
fd = popen(cmd, "r");
} else
{
scmd = (char *) ecalloc(strlen(shell) + strlen(esccmd) + 5,
sizeof(char));
sprintf(scmd, "%s %s %s", shell, shell_coption(), esccmd);
free(esccmd);
fd = popen(scmd, "r");
free(scmd);
}
} else
#endif
{
fd = popen(cmd, "r");
}
/*
* Redirection in `popen' might have messed with the
* standard devices. Restore binary input mode.
*/
SET_BINARY(0);
return (fd);
}
#endif /* HAVE_POPEN */
/*
* Expand a filename, doing any system-specific metacharacter substitutions.
*/
public char *
lglob(filename)
char *filename;
{
char *gfilename;
char *ofilename;
ofilename = fexpand(filename);
if (secure)
return (ofilename);
filename = shell_unquote(ofilename);
#ifdef DECL_GLOB_LIST
{
/*
* The globbing function returns a list of names.
*/
int length;
char *p;
char *qfilename;
DECL_GLOB_LIST(list)
GLOB_LIST(filename, list);
if (GLOB_LIST_FAILED(list))
{
free(filename);
return (ofilename);
}
length = 1; /* Room for trailing null byte */
for (SCAN_GLOB_LIST(list, p))
{
INIT_GLOB_LIST(list, p);
qfilename = shell_quote(p);
if (qfilename != NULL)
{
length += strlen(qfilename) + 1;
free(qfilename);
}
}
gfilename = (char *) ecalloc(length, sizeof(char));
for (SCAN_GLOB_LIST(list, p))
{
INIT_GLOB_LIST(list, p);
qfilename = shell_quote(p);
if (qfilename != NULL)
{
sprintf(gfilename + strlen(gfilename), "%s ", qfilename);
free(qfilename);
}
}
/*
* Overwrite the final trailing space with a null terminator.
*/
*--p = '\0';
GLOB_LIST_DONE(list);
}
#else
#ifdef DECL_GLOB_NAME
{
/*
* The globbing function returns a single name, and
* is called multiple times to walk thru all names.
*/
register char *p;
register int len;
register int n;
char *pathname;
char *qpathname;
DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle)
GLOB_FIRST_NAME(filename, &fnd, handle);
if (GLOB_FIRST_FAILED(handle))
{
free(filename);
return (ofilename);
}
_splitpath(filename, drive, dir, fname, ext);
len = 100;
gfilename = (char *) ecalloc(len, sizeof(char));
p = gfilename;
do {
n = strlen(drive) + strlen(dir) + strlen(fnd.GLOB_NAME) + 1;
pathname = (char *) ecalloc(n, sizeof(char));
sprintf(pathname, "%s%s%s", drive, dir, fnd.GLOB_NAME);
qpathname = shell_quote(pathname);
free(pathname);
if (qpathname != NULL)
{
n = strlen(qpathname);
while (p - gfilename + n + 2 >= len)
{
/*
* No room in current buffer.
* Allocate a bigger one.
*/
len *= 2;
*p = '\0';
p = (char *) ecalloc(len, sizeof(char));
strcpy(p, gfilename);
free(gfilename);
gfilename = p;
p = gfilename + strlen(gfilename);
}
strcpy(p, qpathname);
free(qpathname);
p += n;
*p++ = ' ';
}
} while (GLOB_NEXT_NAME(handle, &fnd) == 0);
/*
* Overwrite the final trailing space with a null terminator.
*/
*--p = '\0';
GLOB_NAME_DONE(handle);
}
#else
#if HAVE_POPEN
{
/*
* We get the shell to glob the filename for us by passing
* an "echo" command to the shell and reading its output.
*/
FILE *fd;
char *s;
char *lessecho;
char *cmd;
char *esc;
esc = get_meta_escape();
if (strlen(esc) == 0)
esc = "-";
esc = shell_quote(esc);
if (esc == NULL)
{
free(filename);
return (ofilename);
}
lessecho = lgetenv("LESSECHO");
if (lessecho == NULL || *lessecho == '\0')
lessecho = "lessecho";
/*
* Invoke lessecho, and read its output (a globbed list of filenames).
*/
cmd = (char *) ecalloc(strlen(lessecho) + strlen(ofilename) + (7*strlen(metachars())) + 24, sizeof(char));
sprintf(cmd, "%s -p0x%x -d0x%x -e%s ", lessecho, openquote, closequote, esc);
free(esc);
for (s = metachars(); *s != '\0'; s++)
sprintf(cmd + strlen(cmd), "-n0x%x ", *s);
sprintf(cmd + strlen(cmd), "-- %s", ofilename);
fd = shellcmd(cmd);
free(cmd);
if (fd == NULL)
{
/*
* Cannot create the pipe.
* Just return the original (fexpanded) filename.
*/
free(filename);
return (ofilename);
}
gfilename = readfd(fd);
pclose(fd);
if (*gfilename == '\0')
{
free(gfilename);
free(filename);
return (ofilename);
}
}
#else
/*
* No globbing functions at all. Just use the fexpanded filename.
*/
gfilename = save(filename);
#endif
#endif
#endif
free(filename);
free(ofilename);
return (gfilename);
}
/*
* See if we should open a "replacement file"
* instead of the file we're about to open.
*/
public char *
open_altfile(filename, pf, pfd)
char *filename;
int *pf;
void **pfd;
{
#if !HAVE_POPEN
return (NULL);
#else
char *lessopen;
char *cmd;
FILE *fd;
#if HAVE_FILENO
int returnfd = 0;
#endif
if (!use_lessopen || secure)
return (NULL);
ch_ungetchar(-1);
if ((lessopen = lgetenv("LESSOPEN")) == NULL)
return (NULL);
if (strcmp(filename, "-") == 0)
return (NULL);
if (*lessopen == '|')
{
/*
* If LESSOPEN starts with a |, it indicates
* a "pipe preprocessor".
*/
#if HAVE_FILENO
lessopen++;
returnfd = 1;
#else
error("LESSOPEN pipe is not supported", NULL_PARG);
return (NULL);
#endif
}
cmd = (char *) ecalloc(strlen(lessopen) + strlen(filename) + 2,
sizeof(char));
sprintf(cmd, lessopen, filename);
fd = shellcmd(cmd);
free(cmd);
if (fd == NULL)
{
/*
* Cannot create the pipe.
*/
return (NULL);
}
#if HAVE_FILENO
if (returnfd)
{
int f;
char c;
/*
* Read one char to see if the pipe will produce any data.
* If it does, push the char back on the pipe.
*/
f = fileno(fd);
SET_BINARY(f);
if (read(f, &c, 1) != 1)
{
/*
* Pipe is empty. This means there is no alt file.
*/
pclose(fd);
return (NULL);
}
ch_ungetchar(c);
*pfd = (void *) fd;
*pf = f;
return (save("-"));
}
#endif
cmd = readfd(fd);
pclose(fd);
if (*cmd == '\0')
/*
* Pipe is empty. This means there is no alt file.
*/
return (NULL);
return (cmd);
#endif /* HAVE_POPEN */
}
/*
* Close a replacement file.
*/
public void
close_altfile(altfilename, filename, pipefd)
char *altfilename;
char *filename;
void *pipefd;
{
#if HAVE_POPEN
char *lessclose;
FILE *fd;
char *cmd;
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;
cmd = (char *) ecalloc(strlen(lessclose) + strlen(filename) +
strlen(altfilename) + 2, sizeof(char));
sprintf(cmd, lessclose, filename, altfilename);
fd = shellcmd(cmd);
free(cmd);
if (fd != NULL)
pclose(fd);
#endif
}
/*
* Is the specified file a directory?
*/
public int
is_dir(filename)
char *filename;
{
int isdir = 0;
filename = shell_unquote(filename);
#if HAVE_STAT
{
int r;
struct stat statbuf;
r = stat(filename, &statbuf);
isdir = (r >= 0 && S_ISDIR(statbuf.st_mode));
}
#else
#ifdef _OSK
{
register int f;
f = open(filename, S_IREAD | S_IFDIR);
if (f >= 0)
close(f);
isdir = (f >= 0);
}
#endif
#endif
free(filename);
return (isdir);
}
/*
* Returns NULL if the file can be opened and
* is an ordinary file, otherwise an error message
* (if it cannot be opened or is a directory, etc.)
*/
public char *
bad_file(filename)
char *filename;
{
register char *m = NULL;
filename = shell_unquote(filename);
if (is_dir(filename))
{
static char is_a_dir[] = " is a directory";
m = (char *) ecalloc(strlen(filename) + sizeof(is_a_dir),
sizeof(char));
strcpy(m, filename);
strcat(m, is_a_dir);
} else
{
#if HAVE_STAT
int r;
struct stat statbuf;
r = stat(filename, &statbuf);
if (r < 0)
{
m = errno_message(filename);
} else if (force_open)
{
m = NULL;
} else if (!S_ISREG(statbuf.st_mode))
{
static char not_reg[] = " is not a regular file (use -f to see it)";
m = (char *) ecalloc(strlen(filename) + sizeof(not_reg),
sizeof(char));
strcpy(m, filename);
strcat(m, not_reg);
}
#endif
}
free(filename);
return (m);
}
/*
* Return the size of a file, as cheaply as possible.
* In Unix, we can stat the file.
*/
public POSITION
filesize(f)
int f;
{
#if HAVE_STAT
struct stat statbuf;
if (fstat(f, &statbuf) >= 0)
return ((POSITION) statbuf.st_size);
#else
#ifdef _OSK
long size;
if ((size = (long) _gs_size(f)) >= 0)
return ((POSITION) size);
#endif
#endif
return (seek_filesize(f));
}
/*
*
*/
public char *
shell_coption()
{
return ("-c");
}
less-382/forwback.c 0100444 0000764 0000764 00000021060 10010075213 013275 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Primitives for displaying the file on the screen,
* scrolling either forward or backward.
*/
#include "less.h"
#include "position.h"
public int hit_eof; /* Keeps track of how many times we hit end of file */
public int screen_trashed;
public int squished;
public int no_back_scroll = 0;
extern int sigs;
extern int top_scroll;
extern int quiet;
extern int sc_width, sc_height;
extern int quit_at_eof;
extern int plusoption;
extern int forw_scroll;
extern int back_scroll;
extern int ignore_eoi;
extern int clear_bg;
extern int final_attr;
#if TAGS
extern char *tagoption;
#endif
/*
* Sound the bell to indicate user is trying to move past end of file.
*/
static void
eof_bell()
{
if (quiet == NOT_QUIET)
bell();
else
vbell();
}
/*
* Check to see if the end of file is currently "displayed".
*/
static void
eof_check()
{
POSITION pos;
if (ignore_eoi)
return;
if (ABORT_SIGS())
return;
/*
* If the bottom line is empty, we are at EOF.
* If the bottom line ends at the file length,
* we must be just at EOF.
*/
pos = position(BOTTOM_PLUS_ONE);
if (pos == NULL_POSITION || pos == ch_length())
hit_eof++;
}
/*
* If the screen is "squished", repaint it.
* "Squished" means the first displayed line is not at the top
* of the screen; this can happen when we display a short file
* for the first time.
*/
static void
squish_check()
{
if (!squished)
return;
squished = 0;
repaint();
}
/*
* Display n lines, scrolling forward,
* starting at position pos in the input file.
* "force" means display the n lines even if we hit end of file.
* "only_last" means display only the last screenful if n > screen size.
* "nblank" is the number of blank lines to draw before the first
* real line. If nblank > 0, the pos must be NULL_POSITION.
* The first real line after the blanks will start at ch_zero().
*/
public void
forw(n, pos, force, only_last, nblank)
register int n;
POSITION pos;
int force;
int only_last;
int nblank;
{
int eof = 0;
int nlines = 0;
int do_repaint;
static int first_time = 1;
squish_check();
/*
* do_repaint tells us not to display anything till the end,
* then just repaint the entire screen.
* We repaint if we are supposed to display only the last
* screenful and the request is for more than a screenful.
* Also if the request exceeds the forward scroll limit
* (but not if the request is for exactly a screenful, since
* repainting itself involves scrolling forward a screenful).
*/
do_repaint = (only_last && n > sc_height-1) ||
(forw_scroll >= 0 && n > forw_scroll && n != sc_height-1);
if (!do_repaint)
{
/*
* Forget any current line shift we might have
* (from the last line of the previous screenful).
*/
extern int cshift;
cshift = 0;
if (top_scroll && n >= sc_height - 1 && pos != ch_length())
{
/*
* Start a new screen.
* {{ This is not really desirable if we happen
* to hit eof in the middle of this screen,
* but we don't yet know if that will happen. }}
*/
pos_clear();
add_forw_pos(pos);
force = 1;
if (top_scroll == OPT_ONPLUS || first_time)
clear();
home();
} else
{
clear_bot();
}
if (pos != position(BOTTOM_PLUS_ONE) || empty_screen())
{
/*
* This is not contiguous with what is
* currently displayed. Clear the screen image
* (position table) and start a new screen.
*/
pos_clear();
add_forw_pos(pos);
force = 1;
if (top_scroll)
{
if (top_scroll == OPT_ONPLUS)
clear();
home();
} else if (!first_time)
{
putstr("...skipping...\n");
}
}
}
while (--n >= 0)
{
/*
* Read the next line of input.
*/
if (nblank > 0)
{
/*
* Still drawing blanks; don't get a line
* from the file yet.
* If this is the last blank line, get ready to
* read a line starting at ch_zero() next time.
*/
if (--nblank == 0)
pos = ch_zero();
} else
{
/*
* Get the next line from the file.
*/
pos = forw_line(pos);
if (pos == NULL_POSITION)
{
/*
* End of file: stop here unless the top line
* is still empty, or "force" is true.
* Even if force is true, stop when the last
* line in the file reaches the top of screen.
*/
eof = 1;
if (!force && position(TOP) != NULL_POSITION)
break;
if (!empty_lines(0, 0) &&
!empty_lines(1, 1) &&
empty_lines(2, sc_height-1))
break;
}
}
/*
* Add the position of the next line to the position table.
* Display the current line on the screen.
*/
add_forw_pos(pos);
nlines++;
if (do_repaint)
continue;
/*
* If this is the first screen displayed and
* we hit an early EOF (i.e. before the requested
* number of lines), we "squish" the display down
* at the bottom of the screen.
* But don't do this if a + option or a -t option
* was given. These options can cause us to
* start the display after the beginning of the file,
* and it is not appropriate to squish in that case.
*/
if (first_time && pos == NULL_POSITION && !top_scroll &&
#if TAGS
tagoption == NULL &&
#endif
!plusoption)
{
squished = 1;
continue;
}
if (top_scroll == OPT_ON)
clear_eol();
put_line();
if (clear_bg && final_attr != AT_NORMAL)
{
/*
* Writing the last character on the last line
* of the display may have scrolled the screen.
* If we were in standout mode, clear_bg terminals
* will fill the new line with the standout color.
* Now we're in normal mode again, so clear the line.
*/
clear_eol();
}
}
if (ignore_eoi)
hit_eof = 0;
else if (eof && !ABORT_SIGS())
hit_eof++;
else
eof_check();
if (nlines == 0)
eof_bell();
else if (do_repaint)
repaint();
first_time = 0;
(void) currline(BOTTOM);
}
/*
* Display n lines, scrolling backward.
*/
public void
back(n, pos, force, only_last)
register int n;
POSITION pos;
int force;
int only_last;
{
int nlines = 0;
int do_repaint;
squish_check();
do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1));
hit_eof = 0;
while (--n >= 0)
{
/*
* Get the previous line of input.
*/
pos = back_line(pos);
if (pos == NULL_POSITION)
{
/*
* Beginning of file: stop here unless "force" is true.
*/
if (!force)
break;
}
/*
* Add the position of the previous line to the position table.
* Display the line on the screen.
*/
add_back_pos(pos);
nlines++;
if (!do_repaint)
{
home();
add_line();
put_line();
}
}
eof_check();
if (nlines == 0)
eof_bell();
else if (do_repaint)
repaint();
(void) currline(BOTTOM);
}
/*
* Display n more lines, forward.
* Start just after the line currently displayed at the bottom of the screen.
*/
public void
forward(n, force, only_last)
int n;
int force;
int only_last;
{
POSITION pos;
if (quit_at_eof && hit_eof && !(ch_getflags() & CH_HELPFILE))
{
/*
* If the -e flag is set and we're trying to go
* forward from end-of-file, go on to the next file.
*/
if (edit_next(1))
quit(QUIT_OK);
return;
}
pos = position(BOTTOM_PLUS_ONE);
if (pos == NULL_POSITION && (!force || empty_lines(2, sc_height-1)))
{
if (ignore_eoi)
{
/*
* ignore_eoi is to support A_F_FOREVER.
* Back up until there is a line at the bottom
* of the screen.
*/
if (empty_screen())
pos = ch_zero();
else
{
do
{
back(1, position(TOP), 1, 0);
pos = position(BOTTOM_PLUS_ONE);
} while (pos == NULL_POSITION);
}
} else
{
eof_bell();
hit_eof++;
return;
}
}
forw(n, pos, force, only_last, 0);
}
/*
* Display n more lines, backward.
* Start just before the line currently displayed at the top of the screen.
*/
public void
backward(n, force, only_last)
int n;
int force;
int only_last;
{
POSITION pos;
pos = position(TOP);
if (pos == NULL_POSITION && (!force || position(BOTTOM) == 0))
{
eof_bell();
return;
}
back(n, pos, force, only_last);
}
/*
* Get the backwards scroll limit.
* Must call this function instead of just using the value of
* back_scroll, because the default case depends on sc_height and
* top_scroll, as well as back_scroll.
*/
public int
get_back_scroll()
{
if (no_back_scroll)
return (0);
if (back_scroll >= 0)
return (back_scroll);
if (top_scroll)
return (sc_height - 2);
return (10000); /* infinity */
}
less-382/help.c 0100444 0000764 0000764 00000130745 07570064700 012462 0 ustar markn markn /* This file was generated by mkhelp from less.hlp */
#include "less.h"
constant char helpdata[] = {
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','\b','S','U','\b','U','M','\b','M','M','\b','M','A','\b','A','R','\b','R','Y','\b','Y',' ','O','\b','O','F','\b','F',' ','L','\b','L','E','\b','E','S','\b','S','S','\b','S',' ','C','\b','C','O','\b','O','M','\b','M','M','\b','M','A','\b','A','N','\b','N','D','\b','D','S','\b','S','\n',
'\n',
' ',' ',' ',' ',' ',' ','C','o','m','m','a','n','d','s',' ','m','a','r','k','e','d',' ','w','i','t','h',' ','*',' ','m','a','y',' ','b','e',' ','p','r','e','c','e','d','e','d',' ','b','y',' ','a',' ','n','u','m','b','e','r',',',' ','_','\b','N','.','\n',
' ',' ',' ',' ',' ',' ','N','o','t','e','s',' ','i','n',' ','p','a','r','e','n','t','h','e','s','e','s',' ','i','n','d','i','c','a','t','e',' ','t','h','e',' ','b','e','h','a','v','i','o','r',' ','i','f',' ','_','\b','N',' ','i','s',' ','g','i','v','e','n','.','\n',
'\n',
' ',' ','h',' ',' ','H',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','t','h','i','s',' ','h','e','l','p','.','\n',
' ',' ','q',' ',' ',':','q',' ',' ','Q',' ',' ',':','Q',' ',' ','Z','Z',' ',' ',' ',' ',' ','E','x','i','t','.','\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','\b','M','O','\b','O','V','\b','V','I','\b','I','N','\b','N','G','\b','G','\n',
'\n',
' ',' ','e',' ',' ','^','E',' ',' ','j',' ',' ','^','N',' ',' ','C','R',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','l','i','n','e',' ',' ',' ','(','o','r',' ','_','\b','N',' ','l','i','n','e','s',')','.','\n',
' ',' ','y',' ',' ','^','Y',' ',' ','k',' ',' ','^','K',' ',' ','^','P',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','l','i','n','e',' ',' ',' ','(','o','r',' ','_','\b','N',' ','l','i','n','e','s',')','.','\n',
' ',' ','f',' ',' ','^','F',' ',' ','^','V',' ',' ','S','P','A','C','E',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','w','i','n','d','o','w',' ','(','o','r',' ','_','\b','N',' ','l','i','n','e','s',')','.','\n',
' ',' ','b',' ',' ','^','B',' ',' ','E','S','C','-','v',' ',' ',' ',' ',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','w','i','n','d','o','w',' ','(','o','r',' ','_','\b','N',' ','l','i','n','e','s',')','.','\n',
' ',' ','z',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','w','i','n','d','o','w',' ','(','a','n','d',' ','s','e','t',' ','w','i','n','d','o','w',' ','t','o',' ','_','\b','N',')','.','\n',
' ',' ','w',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','w','i','n','d','o','w',' ','(','a','n','d',' ','s','e','t',' ','w','i','n','d','o','w',' ','t','o',' ','_','\b','N',')','.','\n',
' ',' ','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',' ',' ','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',
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
' ',' ',' ',' ',' ',' ',' ',' ','D','e','f','a','u','l','t',' ','"','w','i','n','d','o','w','"',' ','i','s',' ','t','h','e',' ','s','c','r','e','e','n',' ','h','e','i','g','h','t','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','D','e','f','a','u','l','t',' ','"','h','a','l','f','-','w','i','n','d','o','w','"',' ','i','s',' ','h','a','l','f',' ','o','f',' ','t','h','e',' ','s','c','r','e','e','n',' ','h','e','i','g','h','t','.','\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','\b','S','E','\b','E','A','\b','A','R','\b','R','C','\b','C','H','\b','H','I','\b','I','N','\b','N','G','\b','G','\n',
'\n',
' ',' ','/','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','S','e','a','r','c','h',' ','f','o','r','w','a','r','d',' ','f','o','r',' ','(','_','\b','N','-','t','h',')',' ','m','a','t','c','h','i','n','g',' ','l','i','n','e','.','\n',
' ',' ','?','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','S','e','a','r','c','h',' ','b','a','c','k','w','a','r','d',' ','f','o','r',' ','(','_','\b','N','-','t','h',')',' ','m','a','t','c','h','i','n','g',' ','l','i','n','e','.','\n',
' ',' ','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',' ','(','f','o','r',' ','_','\b','N','-','t','h',' ','o','c','c','u','r','r','e','n','c','e',')','.','\n',
' ',' ','N',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',' ','i','n',' ','r','e','v','e','r','s','e',' ','d','i','r','e','c','t','i','o','n','.','\n',
' ',' ','E','S','C','-','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',',',' ','s','p','a','n','n','i','n','g',' ','f','i','l','e','s','.','\n',
' ',' ','E','S','C','-','N',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',',',' ','r','e','v','e','r','s','e',' ','d','i','r','.',' ','&',' ','s','p','a','n','n','i','n','g',' ','f','i','l','e','s','.','\n',
' ',' ','E','S','C','-','u',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','n','d','o',' ','(','t','o','g','g','l','e',')',' ','s','e','a','r','c','h',' ','h','i','g','h','l','i','g','h','t','i','n','g','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
' ',' ',' ',' ',' ',' ',' ',' ','S','e','a','r','c','h',' ','p','a','t','t','e','r','n','s',' ','m','a','y',' ','b','e',' ','m','o','d','i','f','i','e','d',' ','b','y',' ','o','n','e',' ','o','r',' ','m','o','r','e',' ','o','f',':','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','N',' ','o','r',' ','!',' ',' ','S','e','a','r','c','h',' ','f','o','r',' ','N','O','N','-','m','a','t','c','h','i','n','g',' ','l','i','n','e','s','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','E',' ','o','r',' ','*',' ',' ','S','e','a','r','c','h',' ','m','u','l','t','i','p','l','e',' ','f','i','l','e','s',' ','(','p','a','s','s',' ','t','h','r','u',' ','E','N','D',' ','O','F',' ','F','I','L','E',')','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','F',' ','o','r',' ','@',' ',' ','S','t','a','r','t',' ','s','e','a','r','c','h',' ','a','t',' ','F','I','R','S','T',' ','f','i','l','e',' ','(','f','o','r',' ','/',')',' ','o','r',' ','l','a','s','t',' ','f','i','l','e',' ','(','f','o','r',' ','?',')','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','K',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','m','a','t','c','h','e','s',',',' ','b','u','t',' ','d','o','n','\'','t',' ','m','o','v','e',' ','(','K','E','E','P',' ','p','o','s','i','t','i','o','n',')','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','^','R',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','u','s','e',' ','R','E','G','U','L','A','R',' ','E','X','P','R','E','S','S','I','O','N','S','.','\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','J','\b','J','U','\b','U','M','\b','M','P','\b','P','I','\b','I','N','\b','N','G','\b','G','\n',
'\n',
' ',' ','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',
' ',' ','E','S','C','-','^','B',' ','_','\b','<','_','\b','c','_','\b','1','_','\b','>',' ','_','\b','<','_','\b','c','_','\b','2','_','\b','>',' ',' ','*',' ',' ','F','i','n','d',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','_','\b','<','_','\b','c','_','\b','1','_','\b','>',' ','\n',
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
' ',' ',' ',' ',' ',' ',' ',' ','E','a','c','h',' ','"','f','i','n','d',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t','"',' ','c','o','m','m','a','n','d',' ','g','o','e','s',' ','f','o','r','w','a','r','d',' ','t','o',' ','t','h','e',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','m','a','t','c','h','i','n','g',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','i','n',' ','t','h','e',' ','t','o','p',' ','l','i','n','e','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','E','a','c','h',' ','"','f','i','n','d',' ','o','p','e','n',' ','b','r','a','c','k','e','t','"',' ','c','o','m','m','a','n','d',' ','g','o','e','s',' ','b','a','c','k','w','a','r','d',' ','t','o',' ','t','h','e',' ','o','p','e','n',' ','b','r','a','c','k','e','t',' ','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','m','a','t','c','h','i','n','g',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','c','l','o','s','e',' ','b','r','a','c','k','e','t',' ','i','n',' ','t','h','e',' ','b','o','t','t','o','m',' ','l','i','n','e','.','\n',
'\n',
' ',' ','m','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','a','r','k',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','p','o','s','i','t','i','o','n',' ','w','i','t','h',' ','<','l','e','t','t','e','r','>','.','\n',
' ',' ','\'','_','\b','<','_','\b','l','_','\b','e','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','G','o',' ','t','o',' ','a',' ','p','r','e','v','i','o','u','s','l','y',' ','m','a','r','k','e','d',' ','p','o','s','i','t','i','o','n','.','\n',
' ',' ','\'','\'',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','G','o',' ','t','o',' ','t','h','e',' ','p','r','e','v','i','o','u','s',' ','p','o','s','i','t','i','o','n','.','\n',
' ',' ','^','X','^','X',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','a','m','e',' ','a','s',' ','\'','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
' ',' ',' ',' ',' ',' ',' ',' ','A',' ','m','a','r','k',' ','i','s',' ','a','n','y',' ','u','p','p','e','r','-','c','a','s','e',' ','o','r',' ','l','o','w','e','r','-','c','a','s','e',' ','l','e','t','t','e','r','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','C','e','r','t','a','i','n',' ','m','a','r','k','s',' ','a','r','e',' ','p','r','e','d','e','f','i','n','e','d',':','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','^',' ',' ','m','e','a','n','s',' ',' ','b','e','g','i','n','n','i','n','g',' ','o','f',' ','t','h','e',' ','f','i','l','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','$',' ',' ','m','e','a','n','s',' ',' ','e','n','d',' ','o','f',' ','t','h','e',' ','f','i','l','e','\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','\b','C','H','\b','H','A','\b','A','N','\b','N','G','\b','G','I','\b','I','N','\b','N','G','\b','G',' ','F','\b','F','I','\b','I','L','\b','L','E','\b','E','S','\b','S','\n',
'\n',
' ',' ',':','e',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','a','m','i','n','e',' ','a',' ','n','e','w',' ','f','i','l','e','.','\n',
' ',' ','^','X','^','V',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','a','m','e',' ','a','s',' ',':','e','.','\n',
' ',' ',':','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','E','x','a','m','i','n','e',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','n','e','x','t',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n',
' ',' ',':','p',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','E','x','a','m','i','n','e',' ','t','h','e',' ','(','_','\b','N','-','t','h',')',' ','p','r','e','v','i','o','u','s',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n',
' ',' ',':','x',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','E','x','a','m','i','n','e',' ','t','h','e',' ','f','i','r','s','t',' ','(','o','r',' ','_','\b','N','-','t','h',')',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n',
' ',' ',':','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','f','i','l','e',' ','f','r','o','m',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e',' ','l','i','s','t','.','\n',
' ',' ','=',' ',' ','^','G',' ',' ',':','f',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','r','i','n','t',' ','c','u','r','r','e','n','t',' ','f','i','l','e',' ','n','a','m','e','.','\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','M','\b','M','I','\b','I','S','\b','S','C','\b','C','E','\b','E','L','\b','L','L','\b','L','A','\b','A','N','\b','N','E','\b','E','O','\b','O','U','\b','U','S','\b','S',' ','C','\b','C','O','\b','O','M','\b','M','M','\b','M','A','\b','A','N','\b','N','D','\b','D','S','\b','S','\n',
'\n',
' ',' ','-','_','\b','<','_','\b','f','_','\b','l','_','\b','a','_','\b','g','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','o','g','g','l','e',' ','a',' ','c','o','m','m','a','n','d',' ','l','i','n','e',' ','o','p','t','i','o','n',' ','[','s','e','e',' ','O','P','T','I','O','N','S',' ','b','e','l','o','w',']','.','\n',
' ',' ','-','-','_','\b','<','_','\b','n','_','\b','a','_','\b','m','_','\b','e','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','T','o','g','g','l','e',' ','a',' ','c','o','m','m','a','n','d',' ','l','i','n','e',' ','o','p','t','i','o','n',',',' ','b','y',' ','n','a','m','e','.','\n',
' ',' ','_','_','\b','<','_','\b','f','_','\b','l','_','\b','a','_','\b','g','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','t','h','e',' ','s','e','t','t','i','n','g',' ','o','f',' ','a',' ','c','o','m','m','a','n','d',' ','l','i','n','e',' ','o','p','t','i','o','n','.','\n',
' ',' ','_','_','_','\b','<','_','\b','n','_','\b','a','_','\b','m','_','\b','e','_','\b','>',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','t','h','e',' ','s','e','t','t','i','n','g',' ','o','f',' ','a','n',' ','o','p','t','i','o','n',',',' ','b','y',' ','n','a','m','e','.','\n',
' ',' ','+','_','\b','c','_','\b','m','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','e','c','u','t','e',' ','t','h','e',' ','l','e','s','s',' ','c','m','d',' ','e','a','c','h',' ','t','i','m','e',' ','a',' ','n','e','w',' ','f','i','l','e',' ','i','s',' ','e','x','a','m','i','n','e','d','.','\n',
'\n',
' ',' ','!','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','x','e','c','u','t','e',' ','t','h','e',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d',' ','w','i','t','h',' ','$','S','H','E','L','L','.','\n',
' ',' ','|','X','\b','X','_','\b','c','_','\b','o','_','\b','m','_','\b','m','_','\b','a','_','\b','n','_','\b','d',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','i','p','e',' ','f','i','l','e',' ','b','e','t','w','e','e','n',' ','c','u','r','r','e','n','t',' ','p','o','s',' ','&',' ','m','a','r','k',' ','X','\b','X',' ','t','o',' ','s','h','e','l','l',' ','c','o','m','m','a','n','d','.','\n',
' ',' ','v',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','d','i','t',' ','t','h','e',' ','c','u','r','r','e','n','t',' ','f','i','l','e',' ','w','i','t','h',' ','$','V','I','S','U','A','L',' ','o','r',' ','$','E','D','I','T','O','R','.','\n',
' ',' ','V',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','P','r','i','n','t',' ','v','e','r','s','i','o','n',' ','n','u','m','b','e','r',' ','o','f',' ','"','l','e','s','s','"','.','\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','O','\b','O','P','\b','P','T','\b','T','I','\b','I','O','\b','O','N','\b','N','S','\b','S','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ','M','o','s','t',' ','o','p','t','i','o','n','s',' ','m','a','y',' ','b','e',' ','c','h','a','n','g','e','d',' ','e','i','t','h','e','r',' ','o','n',' ','t','h','e',' ','c','o','m','m','a','n','d',' ','l','i','n','e',',','\n',
' ',' ',' ',' ',' ',' ',' ',' ','o','r',' ','f','r','o','m',' ','w','i','t','h','i','n',' ','l','e','s','s',' ','b','y',' ','u','s','i','n','g',' ','t','h','e',' ','-',' ','o','r',' ','-','-',' ','c','o','m','m','a','n','d','.','\n',
' ',' ',' ',' ',' ',' ',' ',' ','O','p','t','i','o','n','s',' ','m','a','y',' ','b','e',' ','g','i','v','e','n',' ','i','n',' ','o','n','e',' ','o','f',' ','t','w','o',' ','f','o','r','m','s',':',' ','e','i','t','h','e','r',' ','a',' ','s','i','n','g','l','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ','c','h','a','r','a','c','t','e','r',' ','p','r','e','c','e','d','e','d',' ','b','y',' ','a',' ','-',',',' ','o','r',' ','a',' ','n','a','m','e',' ','p','r','e','c','e','e','d','e','d',' ','b','y',' ','-','-','.','\n',
'\n',
' ',' ','-','?',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','h','e','l','p','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','h','e','l','p',' ','(','f','r','o','m',' ','c','o','m','m','a','n','d',' ','l','i','n','e',')','.','\n',
' ',' ','-','a',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','s','e','a','r','c','h','-','s','k','i','p','-','s','c','r','e','e','n','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','o','r','w','a','r','d',' ','s','e','a','r','c','h',' ','s','k','i','p','s',' ','c','u','r','r','e','n','t',' ','s','c','r','e','e','n','.','\n',
' ',' ','-','b',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','b','u','f','f','e','r','s','=','[','_','\b','N',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','N','u','m','b','e','r',' ','o','f',' ','b','u','f','f','e','r','s','.','\n',
' ',' ','-','B',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','a','u','t','o','-','b','u','f','f','e','r','s','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','a','u','t','o','m','a','t','i','c','a','l','l','y',' ','a','l','l','o','c','a','t','e',' ','b','u','f','f','e','r','s',' ','f','o','r',' ','p','i','p','e','s','.','\n',
' ',' ','-','c',' ',' ','-','C',' ',' ','.','.','.','.',' ',' ','-','-','c','l','e','a','r','-','s','c','r','e','e','n',' ',' ','-','-','C','L','E','A','R','-','S','C','R','E','E','N','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','R','e','p','a','i','n','t',' ','b','y',' ','s','c','r','o','l','l','i','n','g','/','c','l','e','a','r','i','n','g','.','\n',
' ',' ','-','d',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','d','u','m','b','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','u','m','b',' ','t','e','r','m','i','n','a','l','.','\n',
' ',' ','-','D',' ','[','_','\b','x','_','\b','n','_','\b','.','_','\b','n',']',' ',' ','.',' ',' ','-','-','c','o','l','o','r','=','_','\b','x','_','\b','n','_','\b','.','_','\b','n','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','s','c','r','e','e','n',' ','c','o','l','o','r','s','.',' ','(','M','S','-','D','O','S',' ','o','n','l','y',')','\n',
' ',' ','-','e',' ',' ','-','E',' ',' ','.','.','.','.',' ',' ','-','-','q','u','i','t','-','a','t','-','e','o','f',' ',' ','-','-','Q','U','I','T','-','A','T','-','E','O','F','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','Q','u','i','t',' ','a','t',' ','e','n','d',' ','o','f',' ','f','i','l','e','.','\n',
' ',' ','-','f',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','f','o','r','c','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','o','r','c','e',' ','o','p','e','n',' ','n','o','n','-','r','e','g','u','l','a','r',' ','f','i','l','e','s','.','\n',
' ',' ','-','F',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','q','u','i','t','-','i','f','-','o','n','e','-','s','c','r','e','e','n','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','Q','u','i','t',' ','i','f',' ','e','n','t','i','r','e',' ','f','i','l','e',' ','f','i','t','s',' ','o','n',' ','f','i','r','s','t',' ','s','c','r','e','e','n','.','\n',
' ',' ','-','g',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','h','i','l','i','t','e','-','s','e','a','r','c','h','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','i','g','h','l','i','g','h','t',' ','o','n','l','y',' ','l','a','s','t',' ','m','a','t','c','h',' ','f','o','r',' ','s','e','a','r','c','h','e','s','.','\n',
' ',' ','-','G',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','H','I','L','I','T','E','-','S','E','A','R','C','H','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','h','i','g','h','l','i','g','h','t',' ','a','n','y',' ','m','a','t','c','h','e','s',' ','f','o','r',' ','s','e','a','r','c','h','e','s','.','\n',
' ',' ','-','h',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','m','a','x','-','b','a','c','k','-','s','c','r','o','l','l','=','[','_','\b','N',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','B','a','c','k','w','a','r','d',' ','s','c','r','o','l','l',' ','l','i','m','i','t','.','\n',
' ',' ','-','i',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','i','g','n','o','r','e','-','c','a','s','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','I','g','n','o','r','e',' ','c','a','s','e',' ','i','n',' ','s','e','a','r','c','h','e','s',' ','t','h','a','t',' ','d','o',' ','n','o','t',' ','c','o','n','t','a','i','n',' ','u','p','p','e','r','c','a','s','e','.','\n',
' ',' ','-','I',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','I','G','N','O','R','E','-','C','A','S','E','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','I','g','n','o','r','e',' ','c','a','s','e',' ','i','n',' ','a','l','l',' ','s','e','a','r','c','h','e','s','.','\n',
' ',' ','-','j',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','j','u','m','p','-','t','a','r','g','e','t','=','[','_','\b','N',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','c','r','e','e','n',' ','p','o','s','i','t','i','o','n',' ','o','f',' ','t','a','r','g','e','t',' ','l','i','n','e','s','.','\n',
' ',' ','-','J',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','s','t','a','t','u','s','-','c','o','l','u','m','n','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','a',' ','s','t','a','t','u','s',' ','c','o','l','u','m','n',' ','a','t',' ','l','e','f','t',' ','e','d','g','e',' ','o','f',' ','s','c','r','e','e','n','.','\n',
' ',' ','-','k',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','l','e','s','s','k','e','y','-','f','i','l','e','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','a',' ','l','e','s','s','k','e','y',' ','f','i','l','e','.','\n',
' ',' ','-','L',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','n','o','-','l','e','s','s','o','p','e','n','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','I','g','n','o','r','e',' ','t','h','e',' ','L','E','S','S','O','P','E','N',' ','e','n','v','i','r','o','n','m','e','n','t',' ','v','a','r','i','a','b','l','e','.','\n',
' ',' ','-','m',' ',' ','-','M',' ',' ','.','.','.','.',' ',' ','-','-','l','o','n','g','-','p','r','o','m','p','t',' ',' ','-','-','L','O','N','G','-','P','R','O','M','P','T','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','p','r','o','m','p','t',' ','s','t','y','l','e','.','\n',
' ',' ','-','n',' ',' ','-','N',' ',' ','.','.','.','.',' ',' ','-','-','l','i','n','e','-','n','u','m','b','e','r','s',' ',' ','-','-','L','I','N','E','-','N','U','M','B','E','R','S','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','l','i','n','e',' ','n','u','m','b','e','r','s','.','\n',
' ',' ','-','o',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','l','o','g','-','f','i','l','e','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','o','p','y',' ','t','o',' ','l','o','g',' ','f','i','l','e',' ','(','s','t','a','n','d','a','r','d',' ','i','n','p','u','t',' ','o','n','l','y',')','.','\n',
' ',' ','-','O',' ','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ',' ','.',' ',' ','-','-','L','O','G','-','F','I','L','E','=','[','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','o','p','y',' ','t','o',' ','l','o','g',' ','f','i','l','e',' ','(','u','n','c','o','n','d','i','t','i','o','n','a','l','l','y',' ','o','v','e','r','w','r','i','t','e',')','.','\n',
' ',' ','-','p',' ','[','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',']',' ',' ','-','-','p','a','t','t','e','r','n','=','[','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','t','a','r','t',' ','a','t',' ','p','a','t','t','e','r','n',' ','(','f','r','o','m',' ','c','o','m','m','a','n','d',' ','l','i','n','e',')','.','\n',
' ',' ','-','P',' ','[','_','\b','p','_','\b','r','_','\b','o','_','\b','m','_','\b','p','_','\b','t',']',' ',' ',' ','-','-','p','r','o','m','p','t','=','[','_','\b','p','_','\b','r','_','\b','o','_','\b','m','_','\b','p','_','\b','t',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','f','i','n','e',' ','n','e','w',' ','p','r','o','m','p','t','.','\n',
' ',' ','-','q',' ',' ','-','Q',' ',' ','.','.','.','.',' ',' ','-','-','q','u','i','e','t',' ',' ','-','-','Q','U','I','E','T',' ',' ','-','-','s','i','l','e','n','t',' ','-','-','S','I','L','E','N','T','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','Q','u','i','e','t',' ','t','h','e',' ','t','e','r','m','i','n','a','l',' ','b','e','l','l','.','\n',
' ',' ','-','r',' ',' ','-','R',' ',' ','.','.','.','.',' ',' ','-','-','r','a','w','-','c','o','n','t','r','o','l','-','c','h','a','r','s',' ',' ','-','-','R','A','W','-','C','O','N','T','R','O','L','-','C','H','A','R','S','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','O','u','t','p','u','t',' ','"','r','a','w','"',' ','c','o','n','t','r','o','l',' ','c','h','a','r','a','c','t','e','r','s','.','\n',
' ',' ','-','s',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','s','q','u','e','e','z','e','-','b','l','a','n','k','-','l','i','n','e','s','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','q','u','e','e','z','e',' ','m','u','l','t','i','p','l','e',' ','b','l','a','n','k',' ','l','i','n','e','s','.','\n',
' ',' ','-','S',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','c','h','o','p','-','l','o','n','g','-','l','i','n','e','s','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','h','o','p',' ','l','o','n','g',' ','l','i','n','e','s','.','\n',
' ',' ','-','t',' ','[','_','\b','t','_','\b','a','_','\b','g',']',' ',' ','.','.',' ',' ','-','-','t','a','g','=','[','_','\b','t','_','\b','a','_','\b','g',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','F','i','n','d',' ','a',' ','t','a','g','.','\n',
' ',' ','-','T',' ','[','_','\b','t','_','\b','a','_','\b','g','_','\b','s','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']',' ','-','-','t','a','g','-','f','i','l','e','=','[','_','\b','t','_','\b','a','_','\b','g','_','\b','s','_','\b','f','_','\b','i','_','\b','l','_','\b','e',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','s','e',' ','a','n',' ','a','l','t','e','r','n','a','t','e',' ','t','a','g','s',' ','f','i','l','e','.','\n',
' ',' ','-','u',' ',' ','-','U',' ',' ','.','.','.','.',' ',' ','-','-','u','n','d','e','r','l','i','n','e','-','s','p','e','c','i','a','l',' ',' ','-','-','U','N','D','E','R','L','I','N','E','-','S','P','E','C','I','A','L','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','h','a','n','g','e',' ','h','a','n','d','l','i','n','g',' ','o','f',' ','b','a','c','k','s','p','a','c','e','s','.','\n',
' ',' ','-','V',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','v','e','r','s','i','o','n','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','i','s','p','l','a','y',' ','t','h','e',' ','v','e','r','s','i','o','n',' ','n','u','m','b','e','r',' ','o','f',' ','"','l','e','s','s','"','.','\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',' ','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',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','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',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','s','i','z','e',' ','o','f',' ','w','i','n','d','o','w','.','\n',
' ',' ','-','"',' ','[','_','\b','c','[','_','\b','c',']',']',' ',' ','.',' ',' ','-','-','q','u','o','t','e','s','=','[','_','\b','c','[','_','\b','c',']',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','S','e','t',' ','s','h','e','l','l',' ','q','u','o','t','e',' ','c','h','a','r','a','c','t','e','r','s','.','\n',
' ',' ','-','~',' ',' ','.','.','.','.','.','.','.','.',' ',' ','-','-','t','i','l','d','e','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','o','n','\'','t',' ','d','i','s','p','l','a','y',' ','t','i','l','d','e','s',' ','a','f','t','e','r',' ','e','n','d',' ','o','f',' ','f','i','l','e','.','\n',
' ',' ','-','#',' ','[','_','\b','N',']',' ',' ','.','.','.','.',' ',' ','-','-','s','h','i','f','t','=','[','_','\b','N',']','\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','H','o','r','i','z','o','n','t','a','l',' ','s','c','r','o','l','l',' ','a','m','o','u','n','t',' ','(','0',' ','=',' ','o','n','e',' ','h','a','l','f',' ','s','c','r','e','e','n',' ','w','i','d','t','h',')','\n',
'\n',
' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','L','\b','L','I','\b','I','N','\b','N','E','\b','E',' ','E','\b','E','D','\b','D','I','\b','I','T','\b','T','I','\b','I','N','\b','N','G','\b','G','\n',
'\n',
' ',' ',' ',' ',' ',' ',' ',' ','T','h','e','s','e',' ','k','e','y','s',' ','c','a','n',' ','b','e',' ','u','s','e','d',' ','t','o',' ','e','d','i','t',' ','t','e','x','t',' ','b','e','i','n','g',' ','e','n','t','e','r','e','d',' ','\n',
' ',' ',' ',' ',' ',' ',' ',' ','o','n',' ','t','h','e',' ','"','c','o','m','m','a','n','d',' ','l','i','n','e','"',' ','a','t',' ','t','h','e',' ','b','o','t','t','o','m',' ','o','f',' ','t','h','e',' ','s','c','r','e','e','n','.','\n',
'\n',
' ','R','i','g','h','t','A','r','r','o','w',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','l',' ',' ',' ',' ',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','r','i','g','h','t',' ','o','n','e',' ','c','h','a','r','a','c','t','e','r','.','\n',
' ','L','e','f','t','A','r','r','o','w',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','h',' ',' ',' ',' ',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','l','e','f','t',' ','o','n','e',' ','c','h','a','r','a','c','t','e','r','.','\n',
' ','C','N','T','L','-','R','i','g','h','t','A','r','r','o','w',' ',' ','E','S','C','-','R','i','g','h','t','A','r','r','o','w',' ',' ','E','S','C','-','w',' ',' ',' ',' ',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','r','i','g','h','t',' ','o','n','e',' ','w','o','r','d','.','\n',
' ','C','N','T','L','-','L','e','f','t','A','r','r','o','w',' ',' ',' ','E','S','C','-','L','e','f','t','A','r','r','o','w',' ',' ',' ','E','S','C','-','b',' ',' ',' ',' ',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','l','e','f','t',' ','o','n','e',' ','w','o','r','d','.','\n',
' ','H','O','M','E',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','0',' ',' ',' ',' ',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','t','o',' ','s','t','a','r','t',' ','o','f',' ','l','i','n','e','.','\n',
' ','E','N','D',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','$',' ',' ',' ',' ',' ','M','o','v','e',' ','c','u','r','s','o','r',' ','t','o',' ','e','n','d',' ','o','f',' ','l','i','n','e','.','\n',
' ','B','A','C','K','S','P','A','C','E',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','c','h','a','r',' ','t','o',' ','l','e','f','t',' ','o','f',' ','c','u','r','s','o','r','.','\n',
' ','D','E','L','E','T','E',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','x',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','c','h','a','r',' ','u','n','d','e','r',' ','c','u','r','s','o','r','.','\n',
' ','C','N','T','L','-','B','A','C','K','S','P','A','C','E',' ',' ',' ','E','S','C','-','B','A','C','K','S','P','A','C','E',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','w','o','r','d',' ','t','o',' ','l','e','f','t',' ','o','f',' ','c','u','r','s','o','r','.','\n',
' ','C','N','T','L','-','D','E','L','E','T','E',' ',' ',' ',' ',' ',' ','E','S','C','-','D','E','L','E','T','E',' ',' ',' ',' ',' ',' ','E','S','C','-','X',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','w','o','r','d',' ','u','n','d','e','r',' ','c','u','r','s','o','r','.','\n',
' ','C','N','T','L','-','U',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C',' ','(','M','S','-','D','O','S',' ','o','n','l','y',')',' ',' ',' ',' ',' ',' ',' ',' ',' ','D','e','l','e','t','e',' ','e','n','t','i','r','e',' ','l','i','n','e','.','\n',
' ','U','p','A','r','r','o','w',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','k',' ',' ',' ',' ',' ','R','e','t','r','i','e','v','e',' ','p','r','e','v','i','o','u','s',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n',
' ','D','o','w','n','A','r','r','o','w',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','j',' ',' ',' ',' ',' ','R','e','t','r','i','e','v','e',' ','n','e','x','t',' ','c','o','m','m','a','n','d',' ','l','i','n','e','.','\n',
' ','T','A','B',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','o','m','p','l','e','t','e',' ','f','i','l','e','n','a','m','e',' ','&',' ','c','y','c','l','e','.','\n',
' ','S','H','I','F','T','-','T','A','B',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','E','S','C','-','T','A','B',' ',' ',' ','C','o','m','p','l','e','t','e',' ','f','i','l','e','n','a','m','e',' ','&',' ','r','e','v','e','r','s','e',' ','c','y','c','l','e','.','\n',
' ','C','N','T','L','-','L',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','C','o','m','p','l','e','t','e',' ','f','i','l','e','n','a','m','e',',',' ','l','i','s','t',' ','a','l','l','.','\n',
'\n',
0 };
constant int size_helpdata = sizeof(helpdata) - 1;
less-382/ifile.c 0100444 0000764 0000764 00000014452 10010075213 012576 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* An IFILE represents an input file.
*
* It is actually a pointer to an ifile structure,
* but is opaque outside this module.
* Ifile structures are kept in a linked list in the order they
* appear on the command line.
* Any new file which does not already appear in the list is
* inserted after the current file.
*/
#include "less.h"
extern IFILE curr_ifile;
struct ifile {
struct ifile *h_next; /* Links for command line list */
struct ifile *h_prev;
char *h_filename; /* Name of the file */
void *h_filestate; /* File state (used in ch.c) */
int h_index; /* Index within command line list */
int h_hold; /* Hold count */
char h_opened; /* Has this ifile been opened? */
struct scrpos h_scrpos; /* Saved position within the file */
};
/*
* Convert an IFILE (external representation)
* to a struct file (internal representation), and vice versa.
*/
#define int_ifile(h) ((struct ifile *)(h))
#define ext_ifile(h) ((IFILE)(h))
/*
* Anchor for linked list.
*/
static struct ifile anchor = { &anchor, &anchor, NULL, NULL, 0, 0, '\0',
{ NULL_POSITION, 0 } };
static int ifiles = 0;
static void
incr_index(p, incr)
register struct ifile *p;
int incr;
{
for (; p != &anchor; p = p->h_next)
p->h_index += incr;
}
/*
* Link an ifile into the ifile list.
*/
static void
link_ifile(p, prev)
struct ifile *p;
struct ifile *prev;
{
/*
* Link into list.
*/
if (prev == NULL)
prev = &anchor;
p->h_next = prev->h_next;
p->h_prev = prev;
prev->h_next->h_prev = p;
prev->h_next = p;
/*
* Calculate index for the new one,
* and adjust the indexes for subsequent ifiles in the list.
*/
p->h_index = prev->h_index + 1;
incr_index(p->h_next, 1);
ifiles++;
}
/*
* Unlink an ifile from the ifile list.
*/
static void
unlink_ifile(p)
struct ifile *p;
{
p->h_next->h_prev = p->h_prev;
p->h_prev->h_next = p->h_next;
incr_index(p->h_next, -1);
ifiles--;
}
/*
* Allocate a new ifile structure and stick a filename in it.
* It should go after "prev" in the list
* (or at the beginning of the list if "prev" is NULL).
* Return a pointer to the new ifile structure.
*/
static struct ifile *
new_ifile(filename, prev)
char *filename;
struct ifile *prev;
{
register struct ifile *p;
/*
* Allocate and initialize structure.
*/
p = (struct ifile *) ecalloc(1, sizeof(struct ifile));
p->h_filename = save(filename);
p->h_scrpos.pos = NULL_POSITION;
p->h_opened = 0;
p->h_hold = 0;
p->h_filestate = NULL;
link_ifile(p, prev);
return (p);
}
/*
* Delete an existing ifile structure.
*/
public void
del_ifile(h)
IFILE h;
{
register struct ifile *p;
if (h == NULL_IFILE)
return;
/*
* If the ifile we're deleting is the currently open ifile,
* move off it.
*/
unmark(h);
if (h == curr_ifile)
curr_ifile = getoff_ifile(curr_ifile);
p = int_ifile(h);
unlink_ifile(p);
free(p->h_filename);
free(p);
}
/*
* Get the ifile after a given one in the list.
*/
public IFILE
next_ifile(h)
IFILE h;
{
register struct ifile *p;
p = (h == NULL_IFILE) ? &anchor : int_ifile(h);
if (p->h_next == &anchor)
return (NULL_IFILE);
return (ext_ifile(p->h_next));
}
/*
* Get the ifile before a given one in the list.
*/
public IFILE
prev_ifile(h)
IFILE h;
{
register struct ifile *p;
p = (h == NULL_IFILE) ? &anchor : int_ifile(h);
if (p->h_prev == &anchor)
return (NULL_IFILE);
return (ext_ifile(p->h_prev));
}
/*
* Return a different ifile from the given one.
*/
public IFILE
getoff_ifile(ifile)
IFILE ifile;
{
IFILE newifile;
if ((newifile = prev_ifile(ifile)) != NULL_IFILE)
return (newifile);
if ((newifile = next_ifile(ifile)) != NULL_IFILE)
return (newifile);
return (NULL_IFILE);
}
/*
* Return the number of ifiles.
*/
public int
nifile()
{
return (ifiles);
}
/*
* Find an ifile structure, given a filename.
*/
static struct ifile *
find_ifile(filename)
char *filename;
{
register struct ifile *p;
for (p = anchor.h_next; p != &anchor; p = p->h_next)
if (strcmp(filename, p->h_filename) == 0)
return (p);
return (NULL);
}
/*
* Get the ifile associated with a filename.
* If the filename has not been seen before,
* insert the new ifile after "prev" in the list.
*/
public IFILE
get_ifile(filename, prev)
char *filename;
IFILE prev;
{
register struct ifile *p;
if ((p = find_ifile(filename)) == NULL)
p = new_ifile(filename, int_ifile(prev));
return (ext_ifile(p));
}
/*
* Get the filename associated with a ifile.
*/
public char *
get_filename(ifile)
IFILE ifile;
{
if (ifile == NULL)
return (NULL);
return (int_ifile(ifile)->h_filename);
}
/*
* Get the index of the file associated with a ifile.
*/
public int
get_index(ifile)
IFILE ifile;
{
return (int_ifile(ifile)->h_index);
}
/*
* Save the file position to be associated with a given file.
*/
public void
store_pos(ifile, scrpos)
IFILE ifile;
struct scrpos *scrpos;
{
int_ifile(ifile)->h_scrpos = *scrpos;
}
/*
* Recall the file position associated with a file.
* If no position has been associated with the file, return NULL_POSITION.
*/
public void
get_pos(ifile, scrpos)
IFILE ifile;
struct scrpos *scrpos;
{
*scrpos = int_ifile(ifile)->h_scrpos;
}
/*
* Mark the ifile as "opened".
*/
public void
set_open(ifile)
IFILE ifile;
{
int_ifile(ifile)->h_opened = 1;
}
/*
* Return whether the ifile has been opened previously.
*/
public int
opened(ifile)
IFILE ifile;
{
return (int_ifile(ifile)->h_opened);
}
public void
hold_ifile(ifile, incr)
IFILE ifile;
int incr;
{
int_ifile(ifile)->h_hold += incr;
}
public int
held_ifile(ifile)
IFILE ifile;
{
return (int_ifile(ifile)->h_hold);
}
public void *
get_filestate(ifile)
IFILE ifile;
{
return (int_ifile(ifile)->h_filestate);
}
public void
set_filestate(ifile, filestate)
IFILE ifile;
void *filestate;
{
int_ifile(ifile)->h_filestate = filestate;
}
#if 0
public void
if_dump()
{
register struct ifile *p;
for (p = anchor.h_next; p != &anchor; p = p->h_next)
{
printf("%x: %d. <%s> pos %d,%x\n",
p, p->h_index, p->h_filename,
p->h_scrpos.ln, p->h_scrpos.pos);
ch_dump(p->h_filestate);
}
}
#endif
less-382/input.c 0100444 0000764 0000764 00000015173 10010075213 012646 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* High level routines dealing with getting lines of input
* from the file being viewed.
*
* When we speak of "lines" here, we mean PRINTABLE lines;
* lines processed with respect to the screen width.
* We use the term "raw line" to refer to lines simply
* delimited by newlines; not processed with respect to screen width.
*/
#include "less.h"
extern int squeeze;
extern int chopline;
extern int hshift;
extern int quit_if_one_screen;
extern int sigs;
extern int ignore_eoi;
extern POSITION start_attnpos;
extern POSITION end_attnpos;
#if HILITE_SEARCH
extern int hilite_search;
extern int size_linebuf;
#endif
/*
* Get the next line.
* A "current" position is passed and a "new" position is returned.
* The current position is the position of the first character of
* a line. The new position is the position of the first character
* of the NEXT line. The line obtained is the line starting at curr_pos.
*/
public POSITION
forw_line(curr_pos)
POSITION curr_pos;
{
POSITION new_pos;
register int c;
int blankline;
int endline;
if (curr_pos == NULL_POSITION)
{
null_line();
return (NULL_POSITION);
}
#if HILITE_SEARCH
if (hilite_search == OPT_ONPLUS)
/*
* If we are ignoring EOI (command F), only prepare
* one line ahead, to avoid getting stuck waiting for
* slow data without displaying the data we already have.
* If we're not ignoring EOI, we *could* do the same, but
* for efficiency we prepare several lines ahead at once.
*/
prep_hilite(curr_pos, curr_pos + 3*size_linebuf,
ignore_eoi ? 1 : -1);
#endif
if (ch_seek(curr_pos))
{
null_line();
return (NULL_POSITION);
}
prewind();
plinenum(curr_pos);
(void) ch_seek(curr_pos);
c = ch_forw_get();
if (c == EOI)
{
null_line();
return (NULL_POSITION);
}
blankline = (c == '\n' || c == '\r');
for (;;)
{
if (ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
if (c == '\n' || c == EOI)
{
/*
* End of the line.
*/
new_pos = ch_tell();
endline = TRUE;
break;
}
/*
* Append the char to the line and get the next char.
*/
if (pappend(c, ch_tell()-1))
{
/*
* The char won't fit in the line; the line
* is too long to print in the screen width.
* End the line here.
*/
if (chopline || hshift > 0)
{
do
{
c = ch_forw_get();
} while (c != '\n' && c != EOI);
new_pos = ch_tell();
endline = TRUE;
quit_if_one_screen = FALSE;
} else
{
new_pos = ch_tell() - 1;
endline = FALSE;
}
break;
}
c = ch_forw_get();
}
pdone(endline);
if (squeeze && blankline)
{
/*
* This line is blank.
* Skip down to the last contiguous blank line
* and pretend it is the one which we are returning.
*/
while ((c = ch_forw_get()) == '\n' || c == '\r')
if (ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
if (c != EOI)
(void) ch_back_get();
new_pos = ch_tell();
}
return (new_pos);
}
/*
* Get the previous line.
* A "current" position is passed and a "new" position is returned.
* The current position is the position of the first character of
* a line. The new position is the position of the first character
* of the PREVIOUS line. The line obtained is the one starting at new_pos.
*/
public POSITION
back_line(curr_pos)
POSITION curr_pos;
{
POSITION new_pos, begin_new_pos;
int c;
int endline;
if (curr_pos == NULL_POSITION || curr_pos <= ch_zero())
{
null_line();
return (NULL_POSITION);
}
#if HILITE_SEARCH
if (hilite_search == OPT_ONPLUS)
prep_hilite((curr_pos < 3*size_linebuf) ?
0 : curr_pos - 3*size_linebuf, curr_pos, -1);
#endif
if (ch_seek(curr_pos-1))
{
null_line();
return (NULL_POSITION);
}
if (squeeze)
{
/*
* Find out if the "current" line was blank.
*/
(void) ch_forw_get(); /* Skip the newline */
c = ch_forw_get(); /* First char of "current" line */
(void) ch_back_get(); /* Restore our position */
(void) ch_back_get();
if (c == '\n' || c == '\r')
{
/*
* The "current" line was blank.
* Skip over any preceding blank lines,
* since we skipped them in forw_line().
*/
while ((c = ch_back_get()) == '\n' || c == '\r')
if (ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
if (c == EOI)
{
null_line();
return (NULL_POSITION);
}
(void) ch_forw_get();
}
}
/*
* Scan backwards until we hit the beginning of the line.
*/
for (;;)
{
if (ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
c = ch_back_get();
if (c == '\n')
{
/*
* This is the newline ending the previous line.
* We have hit the beginning of the line.
*/
new_pos = ch_tell() + 1;
break;
}
if (c == EOI)
{
/*
* We have hit the beginning of the file.
* This must be the first line in the file.
* This must, of course, be the beginning of the line.
*/
new_pos = ch_tell();
break;
}
}
/*
* Now scan forwards from the beginning of this line.
* We keep discarding "printable lines" (based on screen width)
* until we reach the curr_pos.
*
* {{ This algorithm is pretty inefficient if the lines
* are much longer than the screen width,
* but I don't know of any better way. }}
*/
if (ch_seek(new_pos))
{
null_line();
return (NULL_POSITION);
}
endline = FALSE;
loop:
begin_new_pos = new_pos;
prewind();
plinenum(new_pos);
(void) ch_seek(new_pos);
do
{
c = ch_forw_get();
if (c == EOI || ABORT_SIGS())
{
null_line();
return (NULL_POSITION);
}
new_pos++;
if (c == '\n')
{
endline = TRUE;
break;
}
if (pappend(c, ch_tell()-1))
{
/*
* Got a full printable line, but we haven't
* reached our curr_pos yet. Discard the line
* and start a new one.
*/
if (chopline || hshift > 0)
{
endline = TRUE;
quit_if_one_screen = FALSE;
break;
}
pdone(0);
(void) ch_back_get();
new_pos--;
goto loop;
}
} while (new_pos < curr_pos);
pdone(endline);
return (begin_new_pos);
}
/*
* Set attnpos.
*/
public void
set_attnpos(pos)
POSITION pos;
{
int c;
if (pos != NULL_POSITION)
{
if (ch_seek(pos))
return;
for (;;)
{
c = ch_forw_get();
if (c == EOI)
return;
if (c != '\n' && c != '\r')
break;
pos++;
}
}
start_attnpos = pos;
for (;;)
{
c = ch_forw_get();
pos++;
if (c == EOI || c == '\n' || c == '\r')
break;
}
end_attnpos = pos;
}
less-382/jump.c 0100444 0000764 0000764 00000013243 10010075213 012456 0 ustar markn markn /*
* Copyright (C) 1984-2002 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines which jump to a new location in the file.
*/
#include "less.h"
#include "position.h"
extern int hit_eof;
extern int jump_sline;
extern int squished;
extern int screen_trashed;
extern int sc_width, sc_height;
extern int show_attn;
/*
* Jump to the end of the file.
*/
public void
jump_forw()
{
POSITION pos;
if (ch_end_seek())
{
error("Cannot seek to end of file", NULL_PARG);
return;
}
/*
* Position the last line in the file at the last screen line.
* Go back one line from the end of the file
* to get to the beginning of the last line.
*/
pos = back_line(ch_tell());
if (pos == NULL_POSITION)
jump_loc((POSITION)0, sc_height-1);
else
jump_loc(pos, sc_height-1);
}
/*
* Jump to line n in the file.
*/
public void
jump_back(linenum)
LINENUM linenum;
{
POSITION pos;
PARG parg;
/*
* Find the position of the specified line.
* If we can seek there, just jump to it.
* If we can't seek, but we're trying to go to line number 1,
* use ch_beg_seek() to get as close as we can.
*/
pos = find_pos(linenum);
if (pos != NULL_POSITION && ch_seek(pos) == 0)
{
if (show_attn)
set_attnpos(pos);
jump_loc(pos, jump_sline);
} else if (linenum <= 1 && ch_beg_seek() == 0)
{
jump_loc(ch_tell(), jump_sline);
error("Cannot seek to beginning of file", NULL_PARG);
} else
{
parg.p_linenum = linenum;
error("Cannot seek to line number %n", &parg);
}
}
/*
* Repaint the screen.
*/
public void
repaint()
{
struct scrpos scrpos;
/*
* Start at the line currently at the top of the screen
* and redisplay the screen.
*/
get_scrpos(&scrpos);
pos_clear();
jump_loc(scrpos.pos, scrpos.ln);
}
/*
* Jump to a specified percentage into the file.
*/
public void
jump_percent(percent)
int percent;
{
POSITION pos, len;
/*
* Determine the position in the file
* (the specified percentage of the file's length).
*/
if ((len = ch_length()) == NULL_POSITION)
{
ierror("Determining length of file", NULL_PARG);
ch_end_seek();
}
if ((len = ch_length()) == NULL_POSITION)
{
error("Don't know length of file", NULL_PARG);
return;
}
pos = percent_pos(len, percent);
if (pos >= len)
pos = len-1;
jump_line_loc(pos, jump_sline);
}
/*
* Jump to a specified position in the file.
* Like jump_loc, but the position need not be
* the first character in a line.
*/
public void
jump_line_loc(pos, sline)
POSITION pos;
int sline;
{
int c;
if (ch_seek(pos) == 0)
{
/*
* Back up to the beginning of the line.
*/
while ((c = ch_back_get()) != '\n' && c != EOI)
;
if (c == '\n')
(void) ch_forw_get();
pos = ch_tell();
}
if (show_attn)
set_attnpos(pos);
jump_loc(pos, sline);
}
/*
* Jump to a specified position in the file.
* The position must be the first character in a line.
* Place the target line on a specified line on the screen.
*/
public void
jump_loc(pos, sline)
POSITION pos;
int sline;
{
register int nline;
POSITION tpos;
POSITION bpos;
/*
* Normalize sline.
*/
sline = adjsline(sline);
if ((nline = onscreen(pos)) >= 0)
{
/*
* The line is currently displayed.
* Just scroll there.
*/
nline -= sline;
if (nline > 0)
forw(nline, position(BOTTOM_PLUS_ONE), 1, 0, 0);
else
back(-nline, position(TOP), 1, 0);
if (show_attn)
repaint_hilite(1);
return;
}
/*
* Line is not on screen.
* Seek to the desired location.
*/
if (ch_seek(pos))
{
error("Cannot seek to that file position", NULL_PARG);
return;
}
/*
* See if the desired line is before or after
* the currently displayed screen.
*/
tpos = position(TOP);
bpos = position(BOTTOM_PLUS_ONE);
if (tpos == NULL_POSITION || pos >= tpos)
{
/*
* The desired line is after the current screen.
* Move back in the file far enough so that we can
* call forw() and put the desired line at the
* sline-th line on the screen.
*/
for (nline = 0; nline < sline; nline++)
{
if (bpos != NULL_POSITION && pos <= bpos)
{
/*
* Surprise! The desired line is
* close enough to the current screen
* that we can just scroll there after all.
*/
forw(sc_height-sline+nline-1, bpos, 1, 0, 0);
if (show_attn)
repaint_hilite(1);
return;
}
pos = back_line(pos);
if (pos == NULL_POSITION)
{
/*
* Oops. Ran into the beginning of the file.
* Exit the loop here and rely on forw()
* below to draw the required number of
* blank lines at the top of the screen.
*/
break;
}
}
lastmark();
hit_eof = 0;
squished = 0;
screen_trashed = 0;
forw(sc_height-1, pos, 1, 0, sline-nline);
} else
{
/*
* The desired line is before the current screen.
* Move forward in the file far enough so that we
* can call back() and put the desired line at the
* sline-th line on the screen.
*/
for (nline = sline; nline < sc_height - 1; nline++)
{
pos = forw_line(pos);
if (pos == NULL_POSITION)
{
/*
* Ran into end of file.
* This shouldn't normally happen,
* but may if there is some kind of read error.
*/
break;
}
if (pos >= tpos)
{
/*
* Surprise! The desired line is
* close enough to the current screen
* that we can just scroll there after all.
*/
back(nline+1, tpos, 1, 0);
if (show_attn)
repaint_hilite(1);
return;
}
}
lastmark();
clear();
screen_trashed = 0;
add_back_pos(pos);
back(sc_height-1, pos, 1, 0);
}
}
less-382/line.c 0100444 0000764 0000764 00000045446 10010075213 012444 0 ustar markn markn /*
* Copyright (C) 1984-2002 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines to manipulate the "line buffer".
* The line buffer holds a line of output as it is being built
* in preparation for output to the screen.
*/
#include "less.h"
#define IS_CONT(c) (((c) & 0xC0) == 0x80)
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 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 last_overstrike = AT_NORMAL;
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;
static int do_append();
extern int bs_mode;
extern int linenums;
extern int ctldisp;
extern int twiddle;
extern int binattr;
extern int status_col;
extern int auto_wrap, ignaw;
extern int bo_s_width, bo_e_width;
extern int ul_s_width, ul_e_width;
extern int bl_s_width, bl_e_width;
extern int so_s_width, so_e_width;
extern int sc_width, sc_height;
extern int utf_mode;
extern POSITION start_attnpos;
extern POSITION end_attnpos;
/*
* Initialize from environment variables.
*/
public void
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));
free(attr);
free(linebuf);
linebuf = new_buf;
attr = new_attr;
size_linebuf = new_size;
return 0;
}
/*
* Rewind the line buffer.
*/
public void
prewind()
{
curr = 0;
column = 0;
overstrike = 0;
is_null_line = 0;
pendc = '\0';
lmargin = 0;
if (status_col)
lmargin += 1;
#if HILITE_SEARCH
hilites = 0;
#endif
}
/*
* Insert the line number (of the given position) into the line buffer.
*/
public void
plinenum(pos)
POSITION pos;
{
register LINENUM linenum = 0;
register int i;
if (linenums == OPT_ONPLUS)
{
/*
* Get the line number and put it in the current line.
* {{ Note: since find_linenum calls forw_raw_line,
* it may seek in the input file, requiring the caller
* of plinenum to re-seek if necessary. }}
* {{ Since forw_raw_line modifies linebuf, we must
* do this first, before storing anything in linebuf. }}
*/
linenum = find_linenum(pos);
}
/*
* Display a status column if the -J option is set.
*/
if (status_col)
{
linebuf[curr] = ' ';
if (start_attnpos != NULL_POSITION &&
pos >= start_attnpos && pos < end_attnpos)
attr[curr] = AT_STANDOUT;
else
attr[curr] = 0;
curr++;
column++;
}
/*
* Display the line number at the start of each line
* if the -N option is set.
*/
if (linenums == OPT_ONPLUS)
{
char buf[INT_STRLEN_BOUND(pos) + 2];
int n;
linenumtoa(linenum, buf);
n = strlen(buf);
if (n < MIN_LINENUM_WIDTH)
n = MIN_LINENUM_WIDTH;
sprintf(linebuf+curr, "%*s ", n, buf);
n++; /* One space after the line number. */
for (i = 0; i < n; i++)
attr[curr+i] = AT_NORMAL;
curr += n;
column += n;
lmargin += n;
}
/*
* Append enough spaces to bring us to the lmargin.
*/
while (column < lmargin)
{
linebuf[curr] = ' ';
attr[curr++] = AT_NORMAL;
column++;
}
}
/*
* Determine how many characters are required to shift N columns.
*/
static int
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;
while (*s != '\0' && len > 0)
{
if (!IS_CONT(*s))
len--;
s++;
ulen++;
}
while (IS_CONT(*s))
{
s++;
ulen++;
}
return (ulen);
}
/*
* Shift the input line left.
* This means discarding N printable chars at the start of the buffer.
*/
static void
pshift(shift)
int shift;
{
int i;
int nchars;
if (shift > column - lmargin)
shift = column - lmargin;
if (shift > curr - lmargin)
shift = curr - lmargin;
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++)
{
linebuf[lmargin + i] = linebuf[lmargin + i + nchars];
attr[lmargin + i] = attr[lmargin + i + nchars];
}
curr -= nchars;
column -= shift;
cshift += shift;
}
/*
* Return the printing width of the start (enter) sequence
* for a given character attribute.
*/
static int
attr_swidth(a)
int a;
{
switch (a)
{
case AT_BOLD: return (bo_s_width);
case AT_UNDERLINE: return (ul_s_width);
case AT_BLINK: return (bl_s_width);
case AT_STANDOUT: return (so_s_width);
}
return (0);
}
/*
* Return the printing width of the end (exit) sequence
* for a given character attribute.
*/
static int
attr_ewidth(a)
int a;
{
switch (a)
{
case AT_BOLD: return (bo_e_width);
case AT_UNDERLINE: return (ul_e_width);
case AT_BLINK: return (bl_e_width);
case AT_STANDOUT: return (so_e_width);
}
return (0);
}
/*
* Return the printing width of a given character and attribute,
* if the character were added to the current position in the line buffer.
* Adding a character with a given attribute may cause an enter or exit
* attribute sequence to be inserted, so this must be taken into account.
*/
static int
pwidth(c, a)
int c;
int a;
{
register int w;
if (utf_mode && IS_CONT(c))
return (0);
if (c == '\b')
/*
* Backspace moves backwards one position.
*/
return (-1);
if (control_char(c))
/*
* Control characters do unpredicatable things,
* so we don't even try to guess; say it doesn't move.
* This can only happen if the -r flag is in effect.
*/
return (0);
/*
* Other characters take one space,
* plus the width of any attribute enter/exit sequence.
*/
w = 1;
if (curr > 0 && attr[curr-1] != a)
w += attr_ewidth(attr[curr-1]);
if (a && (curr == 0 || attr[curr-1] != a))
w += attr_swidth(a);
return (w);
}
/*
* Delete the previous character in the line buffer.
*/
static void
backc()
{
curr--;
column -= pwidth(linebuf[curr], attr[curr]);
}
/*
* Are we currently within a recognized ANSI escape sequence?
*/
static int
in_ansi_esc_seq()
{
int i;
/*
* Search backwards for either an ESC (which means we ARE in a seq);
* or an end char (which means we're NOT in a seq).
*/
for (i = curr-1; i >= 0; i--)
{
if (linebuf[i] == ESC)
return (1);
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
store_char(c, a, pos)
int c;
int a;
POSITION pos;
{
register int w;
if (a != AT_NORMAL)
last_overstrike = a;
#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;
else
w = pwidth(c, a);
if (ctldisp != OPT_ON && column + w + attr_ewidth(a) > sc_width)
/*
* Won't fit on screen.
*/
return (1);
if (curr >= size_linebuf-2)
{
/*
* Won't fit in line buffer.
* Try to expand it.
*/
if (expand_linebuf())
return (1);
}
/*
* Special handling for "magic cookie" terminals.
* If an attribute enter/exit sequence has a printing width > 0,
* and the sequence is adjacent to a space, delete the space.
* We just mark the space as invisible, to avoid having too
* many spaces deleted.
* {{ Note that even if the attribute width is > 1, we
* delete only one space. It's not worth trying to do more.
* It's hardly worth doing this much. }}
*/
if (curr > 0 && a != AT_NORMAL &&
linebuf[curr-1] == ' ' && attr[curr-1] == AT_NORMAL &&
attr_swidth(a) > 0)
{
/*
* We are about to append an enter-attribute sequence
* just after a space. Delete the space.
*/
attr[curr-1] = AT_INVIS;
column--;
} else if (curr > 0 && attr[curr-1] != AT_NORMAL &&
attr[curr-1] != AT_INVIS && c == ' ' && a == AT_NORMAL &&
attr_ewidth(attr[curr-1]) > 0)
{
/*
* We are about to append a space just after an
* exit-attribute sequence. Delete the space.
*/
a = AT_INVIS;
column--;
}
/* End of magic cookie handling. */
linebuf[curr] = c;
attr[curr] = a;
column += w;
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.
* Returns 0 if ok, 1 if couldn't fit in buffer.
*/
public int
pappend(c, pos)
register int c;
POSITION pos;
{
int r;
if (pendc)
{
if (do_append(pendc, pendpos))
/*
* Oops. We've probably lost the char which
* was in pendc, since caller won't back up.
*/
return (1);
pendc = '\0';
}
if (c == '\r' && bs_mode == BS_SPECIAL)
{
/*
* Don't put the CR into the buffer until we see
* the next char. If the next char is a newline,
* discard the CR.
*/
pendc = c;
pendpos = pos;
return (0);
}
r = do_append(c, pos);
/*
* If we need to shift the line, do it.
* But wait until we get to at least the middle of the screen,
* so shifting it doesn't affect the chars we're currently
* pappending. (Bold & underline can get messed up otherwise.)
*/
if (cshift < hshift && column > sc_width / 2)
{
linebuf[curr] = '\0';
pshift(hshift - cshift);
}
return (r);
}
#define IS_UTF8_4BYTE(c) ( ((c) & 0xf8) == 0xf0 )
#define IS_UTF8_3BYTE(c) ( ((c) & 0xf0) == 0xe0 )
#define IS_UTF8_2BYTE(c) ( ((c) & 0xe0) == 0xc0 )
#define IS_UTF8_TRAIL(c) ( ((c) & 0xc0) == 0x80 )
static int
do_append(c, pos)
int c;
POSITION pos;
{
register char *s;
register int a;
#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:
STORE_CHAR(c, AT_NORMAL, pos);
break;
case BS_CONTROL:
goto do_control_char;
case BS_SPECIAL:
if (curr == 0)
break;
backc();
overstrike = 1;
break;
}
} else if (overstrike)
{
/*
* Overstrike the character at the current position
* in the line buffer. This will cause either
* underline (if a "_" is overstruck),
* bold (if an identical character is overstruck),
* or just deletion of the character in the buffer.
*/
overstrike--;
if (utf_mode && IS_UTF8_4BYTE(c) && curr > 2 && (char)c == linebuf[curr-3])
{
backc();
backc();
backc();
STORE_CHAR(linebuf[curr], AT_BOLD, pos);
overstrike = 3;
} else if (utf_mode && (IS_UTF8_3BYTE(c) || (overstrike==2 && IS_UTF8_TRAIL(c))) && curr > 1 && (char)c == linebuf[curr-2])
{
backc();
backc();
STORE_CHAR(linebuf[curr], AT_BOLD, pos);
overstrike = 2;
} else if (utf_mode && curr > 0 && (IS_UTF8_2BYTE(c) || (overstrike==1 && IS_UTF8_TRAIL(c))) && (char)c == linebuf[curr-1])
{
backc();
STORE_CHAR(linebuf[curr], AT_BOLD, pos);
overstrike = 1;
} else if (utf_mode && curr > 0 && IS_UTF8_TRAIL(c) && attr[curr-1] == AT_UNDERLINE)
{
STOREC(c, AT_UNDERLINE);
} else if ((char)c == linebuf[curr])
{
/*
* Overstriking a char with itself means make it bold.
* But overstriking an underscore with itself is
* ambiguous. It could mean make it bold, or
* it could mean make it underlined.
* Use the previous overstrike to resolve it.
*/
if (c == '_' && last_overstrike != AT_NORMAL)
STOREC(c, last_overstrike);
else
STOREC(c, AT_BOLD);
} else if (c == '_')
{
if (utf_mode)
{
int i;
for (i = 0; i < 5; i++)
{
if (curr <= i || !IS_CONT(linebuf[curr-i]))
break;
attr[curr-i-1] = AT_UNDERLINE;
}
}
STOREC(linebuf[curr], AT_UNDERLINE);
} else if (linebuf[curr] == '_')
{
if (utf_mode)
{
if (IS_UTF8_2BYTE(c))
overstrike = 1;
else if (IS_UTF8_3BYTE(c))
overstrike = 2;
else if (IS_UTF8_4BYTE(c))
overstrike = 3;
}
STOREC(c, AT_UNDERLINE);
} else if (control_char(c))
goto do_control_char;
else
STOREC(c, AT_NORMAL);
} else if (c == '\t')
{
/*
* Expand a tab into spaces.
*/
switch (bs_mode)
{
case BS_CONTROL:
goto do_control_char;
case BS_NORMAL:
case BS_SPECIAL:
STORE_TAB(AT_NORMAL, pos);
break;
}
} else if (control_char(c))
{
do_control_char:
if (ctldisp == OPT_ON || (ctldisp == OPT_ONPLUS && c == ESC))
{
/*
* Output as a normal character.
*/
STORE_CHAR(c, AT_NORMAL, pos);
} else
{
/*
* Convert to printable representation.
*/
s = prchar(c);
a = binattr;
/*
* Make sure we can get the entire representation
* of the character on this line.
*/
if (column + (int) strlen(s) +
attr_swidth(a) + attr_ewidth(a) > sc_width)
return (1);
for ( ; *s != 0; s++)
STORE_CHAR(*s, a, pos);
}
} else
{
STOREC(c, AT_NORMAL);
}
return (0);
}
/*
* Terminate the line in the line buffer.
*/
public void
pdone(endline)
int endline;
{
if (pendc && (pendc != '\r' || !endline))
/*
* If we had a pending character, put it in the buffer.
* But discard a pending CR if we are at end of line
* (that is, discard the CR in a CR/LF sequence).
*/
(void) do_append(pendc, pendpos);
/*
* Make sure we've shifted the line, if we need to.
*/
if (cshift < hshift)
pshift(hshift - cshift);
/*
* Add a newline if necessary,
* and append a '\0' to the end of the line.
*/
if (column < sc_width || !auto_wrap || ignaw || ctldisp == OPT_ON)
{
linebuf[curr] = '\n';
attr[curr] = AT_NORMAL;
curr++;
}
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.
*/
if (endline)
cshift = 0;
}
/*
* Get a character from the current line.
* Return the character as the function return value,
* and the character attribute in *ap.
*/
public int
gline(i, ap)
register int i;
register int *ap;
{
char *s;
if (is_null_line)
{
/*
* If there is no current line, we pretend the line is
* either "~" or "", depending on the "twiddle" flag.
*/
*ap = AT_BOLD;
s = (twiddle) ? "~\n" : "\n";
return (s[i]);
}
*ap = attr[i];
return (linebuf[i] & 0377);
}
/*
* Indicate that there is no current line.
*/
public void
null_line()
{
is_null_line = 1;
cshift = 0;
}
/*
* Analogous to forw_line(), but deals with "raw lines":
* lines which are not split for screen width.
* {{ This is supposed to be more efficient than forw_line(). }}
*/
public POSITION
forw_raw_line(curr_pos, linep)
POSITION curr_pos;
char **linep;
{
register int n;
register int c;
POSITION new_pos;
if (curr_pos == NULL_POSITION || ch_seek(curr_pos) ||
(c = ch_forw_get()) == EOI)
return (NULL_POSITION);
n = 0;
for (;;)
{
if (c == '\n' || c == EOI)
{
new_pos = ch_tell();
break;
}
if (n >= size_linebuf-1)
{
if (expand_linebuf())
{
/*
* Overflowed the input buffer.
* Pretend the line ended here.
*/
new_pos = ch_tell() - 1;
break;
}
}
linebuf[n++] = c;
c = ch_forw_get();
}
linebuf[n] = '\0';
if (linep != NULL)
*linep = linebuf;
return (new_pos);
}
/*
* Analogous to back_line(), but deals with "raw lines".
* {{ This is supposed to be more efficient than back_line(). }}
*/
public POSITION
back_raw_line(curr_pos, linep)
POSITION curr_pos;
char **linep;
{
register int n;
register int c;
POSITION new_pos;
if (curr_pos == NULL_POSITION || curr_pos <= ch_zero() ||
ch_seek(curr_pos-1))
return (NULL_POSITION);
n = size_linebuf;
linebuf[--n] = '\0';
for (;;)
{
c = ch_back_get();
if (c == '\n')
{
/*
* This is the newline ending the previous line.
* We have hit the beginning of the line.
*/
new_pos = ch_tell() + 1;
break;
}
if (c == EOI)
{
/*
* We have hit the beginning of the file.
* This must be the first line in the file.
* This must, of course, be the beginning of the line.
*/
new_pos = ch_zero();
break;
}
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;
}
/*
* Shift the data to the end of the new linebuf.
*/
for (fm = linebuf + old_size_linebuf,
to = linebuf + size_linebuf;
fm >= linebuf; fm--, to--)
*to = *fm;
n = size_linebuf - old_size_linebuf;
}
linebuf[--n] = c;
}
if (linep != NULL)
*linep = &linebuf[n];
return (new_pos);
}
less-382/linenum.c 0100444 0000764 0000764 00000024305 10010075213 013153 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Code to handle displaying line numbers.
*
* Finding the line number of a given file position is rather tricky.
* We don't want to just start at the beginning of the file and
* count newlines, because that is slow for large files (and also
* wouldn't work if we couldn't get to the start of the file; e.g.
* if input is a long pipe).
*
* So we use the function add_lnum to cache line numbers.
* We try to be very clever and keep only the more interesting
* line numbers when we run out of space in our table. A line
* number is more interesting than another when it is far from
* other line numbers. For example, we'd rather keep lines
* 100,200,300 than 100,101,300. 200 is more interesting than
* 101 because 101 can be derived very cheaply from 100, while
* 200 is more expensive to derive from 100.
*
* The function currline() returns the line number of a given
* position in the file. As a side effect, it calls add_lnum
* to cache the line number. Therefore currline is occasionally
* called to make sure we cache line numbers often enough.
*/
#include "less.h"
/*
* Structure to keep track of a line number and the associated file position.
* A doubly-linked circular list of line numbers is kept ordered by line number.
*/
struct linenum_info
{
struct linenum_info *next; /* Link to next in the list */
struct linenum_info *prev; /* Line to previous in the list */
POSITION pos; /* File position */
POSITION gap; /* Gap between prev and next */
LINENUM line; /* Line number */
};
/*
* "gap" needs some explanation: the gap of any particular line number
* is the distance between the previous one and the next one in the list.
* ("Distance" means difference in file position.) In other words, the
* gap of a line number is the gap which would be introduced if this
* line number were deleted. It is used to decide which one to replace
* when we have a new one to insert and the table is full.
*/
#define NPOOL 50 /* Size of line number pool */
#define LONGTIME (2) /* In seconds */
public int lnloop = 0; /* Are we in the line num loop? */
static struct linenum_info anchor; /* Anchor of the list */
static struct linenum_info *freelist; /* Anchor of the unused entries */
static struct linenum_info pool[NPOOL]; /* The pool itself */
static struct linenum_info *spare; /* We always keep one spare entry */
extern int linenums;
extern int sigs;
extern int sc_height;
/*
* Initialize the line number structures.
*/
public void
clr_linenum()
{
register struct linenum_info *p;
/*
* Put all the entries on the free list.
* Leave one for the "spare".
*/
for (p = pool; p < &pool[NPOOL-2]; p++)
p->next = p+1;
pool[NPOOL-2].next = NULL;
freelist = pool;
spare = &pool[NPOOL-1];
/*
* Initialize the anchor.
*/
anchor.next = anchor.prev = &anchor;
anchor.gap = 0;
anchor.pos = (POSITION)0;
anchor.line = 1;
}
/*
* Calculate the gap for an entry.
*/
static void
calcgap(p)
register struct linenum_info *p;
{
/*
* Don't bother to compute a gap for the anchor.
* Also don't compute a gap for the last one in the list.
* The gap for that last one should be considered infinite,
* but we never look at it anyway.
*/
if (p == &anchor || p->next == &anchor)
return;
p->gap = p->next->pos - p->prev->pos;
}
/*
* Add a new line number to the cache.
* The specified position (pos) should be the file position of the
* FIRST character in the specified line.
*/
public void
add_lnum(linenum, pos)
LINENUM linenum;
POSITION pos;
{
register struct linenum_info *p;
register struct linenum_info *new;
register struct linenum_info *nextp;
register struct linenum_info *prevp;
register POSITION mingap;
/*
* Find the proper place in the list for the new one.
* The entries are sorted by position.
*/
for (p = anchor.next; p != &anchor && p->pos < pos; p = p->next)
if (p->line == linenum)
/* We already have this one. */
return;
nextp = p;
prevp = p->prev;
if (freelist != NULL)
{
/*
* We still have free (unused) entries.
* Use one of them.
*/
new = freelist;
freelist = freelist->next;
} else
{
/*
* No free entries.
* Use the "spare" entry.
*/
new = spare;
spare = NULL;
}
/*
* Fill in the fields of the new entry,
* and insert it into the proper place in the list.
*/
new->next = nextp;
new->prev = prevp;
new->pos = pos;
new->line = linenum;
nextp->prev = new;
prevp->next = new;
/*
* Recalculate gaps for the new entry and the neighboring entries.
*/
calcgap(new);
calcgap(nextp);
calcgap(prevp);
if (spare == NULL)
{
/*
* We have used the spare entry.
* Scan the list to find the one with the smallest
* gap, take it out and make it the spare.
* We should never remove the last one, so stop when
* we get to p->next == &anchor. This also avoids
* looking at the gap of the last one, which is
* not computed by calcgap.
*/
mingap = anchor.next->gap;
for (p = anchor.next; p->next != &anchor; p = p->next)
{
if (p->gap <= mingap)
{
spare = p;
mingap = p->gap;
}
}
spare->next->prev = spare->prev;
spare->prev->next = spare->next;
}
}
/*
* If we get stuck in a long loop trying to figure out the
* line number, print a message to tell the user what we're doing.
*/
static void
longloopmessage()
{
ierror("Calculating line numbers", NULL_PARG);
/*
* Set the lnloop flag here, so if the user interrupts while
* we are calculating line numbers, the signal handler will
* turn off line numbers (linenums=0).
*/
lnloop = 1;
}
static int loopcount;
#if HAVE_TIME
static long startime;
#endif
static void
longish()
{
#if HAVE_TIME
if (loopcount >= 0 && ++loopcount > 100)
{
loopcount = 0;
if (get_time() >= startime + LONGTIME)
{
longloopmessage();
loopcount = -1;
}
}
#else
if (loopcount >= 0 && ++loopcount > LONGLOOP)
{
longloopmessage();
loopcount = -1;
}
#endif
}
/*
* Find the line number associated with a given position.
* Return 0 if we can't figure it out.
*/
public LINENUM
find_linenum(pos)
POSITION pos;
{
register struct linenum_info *p;
register LINENUM linenum;
POSITION cpos;
if (!linenums)
/*
* We're not using line numbers.
*/
return (0);
if (pos == NULL_POSITION)
/*
* Caller doesn't know what he's talking about.
*/
return (0);
if (pos <= ch_zero())
/*
* Beginning of file is always line number 1.
*/
return (1);
/*
* Find the entry nearest to the position we want.
*/
for (p = anchor.next; p != &anchor && p->pos < pos; p = p->next)
continue;
if (p->pos == pos)
/* Found it exactly. */
return (p->line);
/*
* This is the (possibly) time-consuming part.
* We start at the line we just found and start
* reading the file forward or backward till we
* get to the place we want.
*
* First decide whether we should go forward from the
* previous one or backwards from the next one.
* The decision is based on which way involves
* traversing fewer bytes in the file.
*/
#if HAVE_TIME
startime = get_time();
#endif
if (p == &anchor || pos - p->prev->pos < p->pos - pos)
{
/*
* Go forward.
*/
p = p->prev;
if (ch_seek(p->pos))
return (0);
loopcount = 0;
for (linenum = p->line, cpos = p->pos; cpos < pos; linenum++)
{
/*
* Allow a signal to abort this loop.
*/
cpos = forw_raw_line(cpos, (char **)NULL);
if (ABORT_SIGS() || cpos == NULL_POSITION)
return (0);
longish();
}
lnloop = 0;
/*
* We might as well cache it.
*/
add_lnum(linenum, cpos);
/*
* If the given position is not at the start of a line,
* make sure we return the correct line number.
*/
if (cpos > pos)
linenum--;
} else
{
/*
* Go backward.
*/
if (ch_seek(p->pos))
return (0);
loopcount = 0;
for (linenum = p->line, cpos = p->pos; cpos > pos; linenum--)
{
/*
* Allow a signal to abort this loop.
*/
cpos = back_raw_line(cpos, (char **)NULL);
if (ABORT_SIGS() || cpos == NULL_POSITION)
return (0);
longish();
}
lnloop = 0;
/*
* We might as well cache it.
*/
add_lnum(linenum, cpos);
}
return (linenum);
}
/*
* Find the position of a given line number.
* Return NULL_POSITION if we can't figure it out.
*/
public POSITION
find_pos(linenum)
LINENUM linenum;
{
register struct linenum_info *p;
POSITION cpos;
LINENUM clinenum;
if (linenum <= 1)
/*
* Line number 1 is beginning of file.
*/
return (ch_zero());
/*
* Find the entry nearest to the line number we want.
*/
for (p = anchor.next; p != &anchor && p->line < linenum; p = p->next)
continue;
if (p->line == linenum)
/* Found it exactly. */
return (p->pos);
if (p == &anchor || linenum - p->prev->line < p->line - linenum)
{
/*
* Go forward.
*/
p = p->prev;
if (ch_seek(p->pos))
return (NULL_POSITION);
for (clinenum = p->line, cpos = p->pos; clinenum < linenum; clinenum++)
{
/*
* Allow a signal to abort this loop.
*/
cpos = forw_raw_line(cpos, (char **)NULL);
if (ABORT_SIGS() || cpos == NULL_POSITION)
return (NULL_POSITION);
}
} else
{
/*
* Go backward.
*/
if (ch_seek(p->pos))
return (NULL_POSITION);
for (clinenum = p->line, cpos = p->pos; clinenum > linenum; clinenum--)
{
/*
* Allow a signal to abort this loop.
*/
cpos = back_raw_line(cpos, (char **)NULL);
if (ABORT_SIGS() || cpos == NULL_POSITION)
return (NULL_POSITION);
}
}
/*
* We might as well cache it.
*/
add_lnum(clinenum, cpos);
return (cpos);
}
/*
* Return the line number of the "current" line.
* The argument "where" tells which line is to be considered
* the "current" line (e.g. TOP, BOTTOM, MIDDLE, etc).
*/
public LINENUM
currline(where)
int where;
{
POSITION pos;
POSITION len;
LINENUM linenum;
pos = position(where);
len = ch_length();
while (pos == NULL_POSITION && where >= 0 && where < sc_height)
pos = position(++where);
if (pos == NULL_POSITION)
pos = len;
linenum = find_linenum(pos);
if (pos == len)
linenum--;
return (linenum);
}
less-382/lsystem.c 0100444 0000764 0000764 00000016033 10010075237 013211 0 ustar markn markn /*
* Copyright (C) 1984-2002 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines to execute other programs.
* Necessarily very OS dependent.
*/
#include "less.h"
#include
#include "position.h"
#if MSDOS_COMPILER
#include
#ifdef _MSC_VER
#include
#define setdisk(n) _chdrive((n)+1)
#else
#include
#endif
#endif
extern int screen_trashed;
extern IFILE curr_ifile;
#if HAVE_SYSTEM
/*
* Pass the specified command to a shell to be executed.
* Like plain "system()", but handles resetting terminal modes, etc.
*/
public void
lsystem(cmd, donemsg)
char *cmd;
char *donemsg;
{
register int inp;
#if HAVE_SHELL
register char *shell;
register char *p;
#endif
IFILE save_ifile;
#if MSDOS_COMPILER
char cwd[FILENAME_MAX+1];
#endif
/*
* Print the command which is to be executed,
* unless the command starts with a "-".
*/
if (cmd[0] == '-')
cmd++;
else
{
clear_bot();
putstr("!");
putstr(cmd);
putstr("\n");
}
#if MSDOS_COMPILER
/*
* Working directory is global on MSDOS.
* The child might change the working directory, so we
* must save and restore CWD across calls to "system",
* or else we won't find our file when we return and
* try to "reedit_ifile" it.
*/
getcwd(cwd, FILENAME_MAX);
#endif
/*
* Close the current input file.
*/
save_ifile = save_curr_ifile();
(void) edit_ifile(NULL_IFILE);
/*
* De-initialize the terminal and take out of raw mode.
*/
deinit();
flush(); /* Make sure the deinit chars get out */
raw_mode(0);
#if MSDOS_COMPILER==WIN32C
close_getchr();
#endif
/*
* Restore signals to their defaults.
*/
init_signals(0);
#if HAVE_DUP
/*
* Force standard input to be the user's terminal
* (the normal standard input), even if less's standard input
* is coming from a pipe.
*/
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
/*
* Pass the command to the system to be executed.
* If we have a SHELL environment variable, use
* <$SHELL -c "command"> instead of just .
* If the command is empty, just invoke a shell.
*/
#if HAVE_SHELL
p = NULL;
if ((shell = lgetenv("SHELL")) != NULL && *shell != '\0')
{
if (*cmd == '\0')
p = save(shell);
else
{
char *esccmd = shell_quote(cmd);
if (esccmd != NULL)
{
p = (char *) ecalloc(strlen(shell) +
strlen(esccmd) + 5, sizeof(char));
sprintf(p, "%s %s %s", shell, shell_coption(), esccmd);
free(esccmd);
}
}
}
if (p == NULL)
{
if (*cmd == '\0')
p = save("sh");
else
p = save(cmd);
}
system(p);
free(p);
#else
#if MSDOS_COMPILER==DJGPPC
/*
* Make stdin of the child be in cooked mode.
*/
setmode(0, O_TEXT);
/*
* We don't need to catch signals of the child (it
* also makes trouble with some DPMI servers).
*/
__djgpp_exception_toggle();
system(cmd);
__djgpp_exception_toggle();
#else
system(cmd);
#endif
#endif
#if HAVE_DUP
/*
* Restore standard input, reset signals, raw mode, etc.
*/
close(0);
dup(inp);
close(inp);
#endif
#if MSDOS_COMPILER==WIN32C
open_getchr();
#endif
init_signals(1);
raw_mode(1);
if (donemsg != NULL)
{
putstr(donemsg);
putstr(" (press RETURN)");
get_return();
putchr('\n');
flush();
}
init();
screen_trashed = 1;
#if MSDOS_COMPILER
/*
* Restore the previous directory (possibly
* changed by the child program we just ran).
*/
chdir(cwd);
#if MSDOS_COMPILER != DJGPPC
/*
* Some versions of chdir() don't change to the drive
* which is part of CWD. (DJGPP does this in chdir.)
*/
if (cwd[1] == ':')
{
if (cwd[0] >= 'a' && cwd[0] <= 'z')
setdisk(cwd[0] - 'a');
else if (cwd[0] >= 'A' && cwd[0] <= 'Z')
setdisk(cwd[0] - 'A');
}
#endif
#endif
/*
* Reopen the current input file.
*/
reedit_ifile(save_ifile);
#if defined(SIGWINCH) || defined(SIGWIND)
/*
* Since we were ignoring window change signals while we executed
* the system command, we must assume the window changed.
* Warning: this leaves a signal pending (in "sigs"),
* so psignals() should be called soon after lsystem().
*/
winch(0);
#endif
}
#endif
#if PIPEC
/*
* Pipe a section of the input file into the given shell command.
* The section to be piped is the section "between" the current
* position and the position marked by the given letter.
*
* If the mark is after the current screen, the section between
* the top line displayed and the mark is piped.
* If the mark is before the current screen, the section between
* the mark and the bottom line displayed is piped.
* If the mark is on the current screen, or if the mark is ".",
* the whole current screen is piped.
*/
public int
pipe_mark(c, cmd)
int c;
char *cmd;
{
POSITION mpos, tpos, bpos;
/*
* mpos = the marked position.
* tpos = top of screen.
* bpos = bottom of screen.
*/
mpos = markpos(c);
if (mpos == NULL_POSITION)
return (-1);
tpos = position(TOP);
if (tpos == NULL_POSITION)
tpos = ch_zero();
bpos = position(BOTTOM);
if (c == '.')
return (pipe_data(cmd, tpos, bpos));
else if (mpos <= tpos)
return (pipe_data(cmd, mpos, bpos));
else if (bpos == NULL_POSITION)
return (pipe_data(cmd, tpos, bpos));
else
return (pipe_data(cmd, tpos, mpos));
}
/*
* Create a pipe to the given shell command.
* Feed it the file contents between the positions spos and epos.
*/
public int
pipe_data(cmd, spos, epos)
char *cmd;
POSITION spos;
POSITION epos;
{
register FILE *f;
register int c;
extern FILE *popen();
/*
* This is structured much like lsystem().
* Since we're running a shell program, we must be careful
* to perform the necessary deinitialization before running
* the command, and reinitialization after it.
*/
if (ch_seek(spos) != 0)
{
error("Cannot seek to start position", NULL_PARG);
return (-1);
}
if ((f = popen(cmd, "w")) == NULL)
{
error("Cannot create pipe", NULL_PARG);
return (-1);
}
clear_bot();
putstr("!");
putstr(cmd);
putstr("\n");
deinit();
flush();
raw_mode(0);
init_signals(0);
#if MSDOS_COMPILER==WIN32C
close_getchr();
#endif
#ifdef SIGPIPE
LSIGNAL(SIGPIPE, SIG_IGN);
#endif
c = EOI;
while (epos == NULL_POSITION || spos++ <= epos)
{
/*
* Read a character from the file and give it to the pipe.
*/
c = ch_forw_get();
if (c == EOI)
break;
if (putc(c, f) == EOF)
break;
}
/*
* Finish up the last line.
*/
while (c != '\n' && c != EOI )
{
c = ch_forw_get();
if (c == EOI)
break;
if (putc(c, f) == EOF)
break;
}
pclose(f);
#ifdef SIGPIPE
LSIGNAL(SIGPIPE, SIG_DFL);
#endif
#if MSDOS_COMPILER==WIN32C
open_getchr();
#endif
init_signals(1);
raw_mode(1);
init();
screen_trashed = 1;
#if defined(SIGWINCH) || defined(SIGWIND)
/* {{ Probably don't need this here. }} */
winch(0);
#endif
return (0);
}
#endif
less-382/mark.c 0100444 0000764 0000764 00000011044 10010075213 012432 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
#include "less.h"
extern IFILE curr_ifile;
extern int sc_height;
extern int jump_sline;
/*
* A mark is an ifile (input file) plus a position within the file.
*/
struct mark {
IFILE m_ifile;
struct scrpos m_scrpos;
};
/*
* The table of marks.
* Each mark is identified by a lowercase or uppercase letter.
* The final one is lmark, for the "last mark"; addressed by the apostrophe.
*/
#define NMARKS ((2*26)+1) /* a-z, A-Z, lastmark */
#define LASTMARK (NMARKS-1)
static struct mark marks[NMARKS];
/*
* Initialize the mark table to show no marks are set.
*/
public void
init_mark()
{
int i;
for (i = 0; i < NMARKS; i++)
marks[i].m_scrpos.pos = NULL_POSITION;
}
/*
* See if a mark letter is valid (between a and z).
*/
static struct mark *
getumark(c)
int c;
{
if (c >= 'a' && c <= 'z')
return (&marks[c-'a']);
if (c >= 'A' && c <= 'Z')
return (&marks[c-'A'+26]);
error("Invalid mark letter", NULL_PARG);
return (NULL);
}
/*
* Get the mark structure identified by a character.
* The mark struct may come either from the mark table
* or may be constructed on the fly for certain characters like ^, $.
*/
static struct mark *
getmark(c)
int c;
{
register struct mark *m;
static struct mark sm;
switch (c)
{
case '^':
/*
* Beginning of the current file.
*/
m = &sm;
m->m_scrpos.pos = ch_zero();
m->m_scrpos.ln = 0;
m->m_ifile = curr_ifile;
break;
case '$':
/*
* End of the current file.
*/
if (ch_end_seek())
{
error("Cannot seek to end of file", NULL_PARG);
return (NULL);
}
m = &sm;
m->m_scrpos.pos = ch_tell();
m->m_scrpos.ln = sc_height-1;
m->m_ifile = curr_ifile;
break;
case '.':
/*
* Current position in the current file.
*/
m = &sm;
get_scrpos(&m->m_scrpos);
m->m_ifile = curr_ifile;
break;
case '\'':
/*
* The "last mark".
*/
m = &marks[LASTMARK];
break;
default:
/*
* Must be a user-defined mark.
*/
m = getumark(c);
if (m == NULL)
break;
if (m->m_scrpos.pos == NULL_POSITION)
{
error("Mark not set", NULL_PARG);
return (NULL);
}
break;
}
return (m);
}
/*
* Is a mark letter is invalid?
*/
public int
badmark(c)
int c;
{
return (getmark(c) == NULL);
}
/*
* Set a user-defined mark.
*/
public void
setmark(c)
int c;
{
register struct mark *m;
struct scrpos scrpos;
m = getumark(c);
if (m == NULL)
return;
get_scrpos(&scrpos);
m->m_scrpos = scrpos;
m->m_ifile = curr_ifile;
}
/*
* Set lmark (the mark named by the apostrophe).
*/
public void
lastmark()
{
struct scrpos scrpos;
if (ch_getflags() & CH_HELPFILE)
return;
get_scrpos(&scrpos);
if (scrpos.pos == NULL_POSITION)
return;
marks[LASTMARK].m_scrpos = scrpos;
marks[LASTMARK].m_ifile = curr_ifile;
}
/*
* Go to a mark.
*/
public void
gomark(c)
int c;
{
register struct mark *m;
struct scrpos scrpos;
m = getmark(c);
if (m == NULL)
return;
/*
* If we're trying to go to the lastmark and
* it has not been set to anything yet,
* set it to the beginning of the current file.
*/
if (m == &marks[LASTMARK] && m->m_scrpos.pos == NULL_POSITION)
{
m->m_ifile = curr_ifile;
m->m_scrpos.pos = ch_zero();
m->m_scrpos.ln = jump_sline;
}
/*
* If we're using lmark, we must save the screen position now,
* because if we call edit_ifile() below, lmark will change.
* (We save the screen position even if we're not using lmark.)
*/
scrpos = m->m_scrpos;
if (m->m_ifile != curr_ifile)
{
/*
* Not in the current file; edit the correct file.
*/
if (edit_ifile(m->m_ifile))
return;
}
jump_loc(scrpos.pos, scrpos.ln);
}
/*
* Return the position associated with a given mark letter.
*
* We don't return which screen line the position
* is associated with, but this doesn't matter much,
* because it's always the first non-blank line on the screen.
*/
public POSITION
markpos(c)
int c;
{
register struct mark *m;
m = getmark(c);
if (m == NULL)
return (NULL_POSITION);
if (m->m_ifile != curr_ifile)
{
error("Mark not in current file", NULL_PARG);
return (NULL_POSITION);
}
return (m->m_scrpos.pos);
}
/*
* Clear the marks associated with a specified ifile.
*/
public void
unmark(ifile)
IFILE ifile;
{
int i;
for (i = 0; i < NMARKS; i++)
if (marks[i].m_ifile == ifile)
marks[i].m_scrpos.pos = NULL_POSITION;
}
less-382/optfunc.c 0100444 0000764 0000764 00000022560 10010075213 013163 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Handling functions for command line options.
*
* Most options are handled by the generic code in option.c.
* But all string options, and a few non-string options, require
* special handling specific to the particular option.
* This special processing is done by the "handling functions" in this file.
*
* Each handling function is passed a "type" and, if it is a string
* option, the string which should be "assigned" to the option.
* The type may be one of:
* INIT The option is being initialized from the command line.
* TOGGLE The option is being changed from within the program.
* QUERY The setting of the option is merely being queried.
*/
#include "less.h"
#include "option.h"
extern int nbufs;
extern int bufspace;
extern int pr_type;
extern int plusoption;
extern int swindow;
extern int sc_height;
extern int secure;
extern int dohelp;
extern int any_display;
extern char openquote;
extern char closequote;
extern char *prproto[];
extern char *eqproto;
extern char *hproto;
extern char *wproto;
extern IFILE curr_ifile;
extern char version[];
#if LOGFILE
extern char *namelogfile;
extern int force_logfile;
extern int logfile;
#endif
#if TAGS
public char *tagoption = NULL;
extern char *tags;
extern int jump_sline;
#endif
#if MSDOS_COMPILER
extern int nm_fg_color, nm_bg_color;
extern int bo_fg_color, bo_bg_color;
extern int ul_fg_color, ul_bg_color;
extern int so_fg_color, so_bg_color;
extern int bl_fg_color, bl_bg_color;
#endif
#if LOGFILE
/*
* Handler for -o option.
*/
public void
opt_o(type, s)
int type;
char *s;
{
PARG parg;
if (secure)
{
error("log file support is not available", NULL_PARG);
return;
}
switch (type)
{
case INIT:
namelogfile = s;
break;
case TOGGLE:
if (ch_getflags() & CH_CANSEEK)
{
error("Input is not a pipe", NULL_PARG);
return;
}
if (logfile >= 0)
{
error("Log file is already in use", NULL_PARG);
return;
}
s = skipsp(s);
namelogfile = lglob(s);
use_logfile(namelogfile);
sync_logfile();
break;
case QUERY:
if (logfile < 0)
error("No log file", NULL_PARG);
else
{
parg.p_string = namelogfile;
error("Log file \"%s\"", &parg);
}
break;
}
}
/*
* Handler for -O option.
*/
public void
opt__O(type, s)
int type;
char *s;
{
force_logfile = TRUE;
opt_o(type, s);
}
#endif
/*
* Handlers for -l option.
*/
public void
opt_l(type, s)
int type;
char *s;
{
int err;
int n;
char *t;
switch (type)
{
case INIT:
t = s;
n = getnum(&t, "l", &err);
if (err || n <= 0)
{
error("Line number is required after -l", NULL_PARG);
return;
}
plusoption = TRUE;
ungetsc(s);
break;
}
}
#if USERFILE
public void
opt_k(type, s)
int type;
char *s;
{
PARG parg;
switch (type)
{
case INIT:
if (lesskey(s, 0))
{
parg.p_string = s;
error("Cannot use lesskey file \"%s\"", &parg);
}
break;
}
}
#endif
#if TAGS
/*
* Handler for -t option.
*/
public void
opt_t(type, s)
int type;
char *s;
{
IFILE save_ifile;
POSITION pos;
switch (type)
{
case INIT:
tagoption = s;
/* Do the rest in main() */
break;
case TOGGLE:
if (secure)
{
error("tags support is not available", NULL_PARG);
break;
}
findtag(skipsp(s));
save_ifile = save_curr_ifile();
if (edit_tagfile())
break;
if ((pos = tagsearch()) == NULL_POSITION)
{
reedit_ifile(save_ifile);
break;
}
unsave_ifile(save_ifile);
jump_loc(pos, jump_sline);
break;
}
}
/*
* Handler for -T option.
*/
public void
opt__T(type, s)
int type;
char *s;
{
PARG parg;
switch (type)
{
case INIT:
tags = s;
break;
case TOGGLE:
s = skipsp(s);
tags = lglob(s);
break;
case QUERY:
parg.p_string = tags;
error("Tags file \"%s\"", &parg);
break;
}
}
#endif
/*
* Handler for -p option.
*/
public void
opt_p(type, s)
int type;
register char *s;
{
switch (type)
{
case INIT:
/*
* Unget a search command for the specified string.
* {{ This won't work if the "/" command is
* changed or invalidated by a .lesskey file. }}
*/
plusoption = TRUE;
ungetsc(s);
ungetsc("/");
break;
}
}
/*
* Handler for -P option.
*/
public void
opt__P(type, s)
int type;
register char *s;
{
register char **proto;
PARG parg;
switch (type)
{
case INIT:
case TOGGLE:
/*
* Figure out which prototype string should be changed.
*/
switch (*s)
{
case 's': proto = &prproto[PR_SHORT]; s++; break;
case 'm': proto = &prproto[PR_MEDIUM]; s++; break;
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);
*proto = save(s);
break;
case QUERY:
parg.p_string = prproto[pr_type];
error("%s", &parg);
break;
}
}
/*
* Handler for the -b option.
*/
/*ARGSUSED*/
public void
opt_b(type, s)
int type;
char *s;
{
switch (type)
{
case INIT:
case TOGGLE:
/*
* Set the new number of buffers.
*/
ch_setbufspace(bufspace);
break;
case QUERY:
break;
}
}
/*
* Handler for the -i option.
*/
/*ARGSUSED*/
public void
opt_i(type, s)
int type;
char *s;
{
switch (type)
{
case TOGGLE:
chg_caseless();
break;
case QUERY:
case INIT:
break;
}
}
/*
* Handler for the -V option.
*/
/*ARGSUSED*/
public void
opt__V(type, s)
int type;
char *s;
{
switch (type)
{
case TOGGLE:
case QUERY:
dispversion();
break;
case INIT:
/*
* Force output to stdout per GNU standard for --version output.
*/
any_display = 1;
putstr("less ");
putstr(version);
putstr("\nCopyright (C) 2002 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: https://www.greenwoodsoftware.com/less\n");
quit(QUIT_OK);
break;
}
}
#if MSDOS_COMPILER
/*
* Parse an MSDOS color descriptor.
*/
static void
colordesc(s, fg_color, bg_color)
char *s;
int *fg_color;
int *bg_color;
{
int fg, bg;
int err;
fg = getnum(&s, "D", &err);
if (err)
{
error("Missing fg color in -D", NULL_PARG);
return;
}
if (*s != '.')
bg = 0;
else
{
s++;
bg = getnum(&s, "D", &err);
if (err)
{
error("Missing fg color in -D", NULL_PARG);
return;
}
}
if (*s != '\0')
error("Extra characters at end of -D option", NULL_PARG);
*fg_color = fg;
*bg_color = bg;
}
/*
* Handler for the -D option.
*/
/*ARGSUSED*/
public void
opt_D(type, s)
int type;
char *s;
{
switch (type)
{
case INIT:
case TOGGLE:
switch (*s++)
{
case 'n':
colordesc(s, &nm_fg_color, &nm_bg_color);
break;
case 'd':
colordesc(s, &bo_fg_color, &bo_bg_color);
break;
case 'u':
colordesc(s, &ul_fg_color, &ul_bg_color);
break;
case 'k':
colordesc(s, &bl_fg_color, &bl_bg_color);
break;
case 's':
colordesc(s, &so_fg_color, &so_bg_color);
break;
default:
error("-D must be followed by n, d, u, k or s", NULL_PARG);
break;
}
if (type == TOGGLE)
{
so_enter();
so_exit();
}
break;
case QUERY:
break;
}
}
#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;
s = skipsp(s);
while (*s >= '0' && *s <= '9')
n = (10 * n) + (*s++ - '0');
if (n > tabstops[i-1])
tabstops[i++] = n;
s = skipsp(s);
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.
*/
public void
opt_quote(type, s)
int type;
register char *s;
{
char buf[3];
PARG parg;
switch (type)
{
case INIT:
case TOGGLE:
if (s[0] == '\0')
{
openquote = closequote = '\0';
break;
}
if (s[1] != '\0' && s[2] != '\0')
{
error("-\" must be followed by 1 or 2 chars", NULL_PARG);
return;
}
openquote = s[0];
if (s[1] == '\0')
closequote = openquote;
else
closequote = s[1];
break;
case QUERY:
buf[0] = openquote;
buf[1] = closequote;
buf[2] = '\0';
parg.p_string = buf;
error("quotes %s", &parg);
break;
}
}
/*
* "-?" means display a help message.
* If from the command line, exit immediately.
*/
/*ARGSUSED*/
public void
opt_query(type, s)
int type;
char *s;
{
switch (type)
{
case QUERY:
case TOGGLE:
error("Use \"h\" for help", NULL_PARG);
break;
case INIT:
dohelp = 1;
}
}
/*
* Get the "screen window" size.
*/
public int
get_swindow()
{
if (swindow > 0)
return (swindow);
return (sc_height + swindow);
}
less-382/option.c 0100444 0000764 0000764 00000030335 10010075213 013014 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Process command line options.
*
* Each option is a single letter which controls a program variable.
* The options have defaults which may be changed via
* the command line option, toggled via the "-" command,
* or queried via the "_" command.
*/
#include "less.h"
#include "option.h"
static struct loption *pendopt;
public int plusoption = FALSE;
static char *propt();
static char *optstring();
static int flip_triple();
extern int screen_trashed;
extern char *every_first_cmd;
/*
* Scan an argument (either from the command line or from the
* LESS environment variable) and process it.
*/
public void
scan_option(s)
char *s;
{
register struct loption *o;
register int optc;
char *optname;
char *printopt;
char *str;
int set_default;
int lc;
int err;
PARG parg;
if (s == NULL)
return;
/*
* If we have a pending option which requires an argument,
* handle it now.
* This happens if the previous option was, for example, "-P"
* without a following string. In that case, the current
* option is simply the argument for the previous option.
*/
if (pendopt != NULL)
{
switch (pendopt->otype & OTYPE)
{
case STRING:
(*pendopt->ofunc)(INIT, s);
break;
case NUMBER:
printopt = propt(pendopt->oletter);
*(pendopt->ovar) = getnum(&s, printopt, (int*)NULL);
break;
}
pendopt = NULL;
return;
}
set_default = FALSE;
optname = NULL;
while (*s != '\0')
{
/*
* Check some special cases first.
*/
switch (optc = *s++)
{
case ' ':
case '\t':
case END_OPTION_STRING:
continue;
case '-':
/*
* "--" indicates an option name instead of a letter.
*/
if (*s == '-')
{
optname = ++s;
break;
}
/*
* "-+" means set these options back to their defaults.
* (They may have been set otherwise by previous
* options.)
*/
set_default = (*s == '+');
if (set_default)
s++;
continue;
case '+':
/*
* An option prefixed by a "+" is ungotten, so
* that it is interpreted as less commands
* processed at the start of the first input file.
* "++" means process the commands at the start of
* EVERY input file.
*/
plusoption = TRUE;
s = optstring(s, &str, propt('+'), NULL);
if (*str == '+')
every_first_cmd = save(++str);
else
ungetsc(str);
continue;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
/*
* Special "more" compatibility form "-"
* instead of -z to set the scrolling
* window size.
*/
s--;
optc = 'z';
break;
}
/*
* Not a special case.
* Look up the option letter in the option table.
*/
err = 0;
if (optname == NULL)
{
printopt = propt(optc);
lc = SIMPLE_IS_LOWER(optc);
o = findopt(optc);
} else
{
printopt = optname;
lc = SIMPLE_IS_LOWER(optname[0]);
o = findopt_name(&optname, NULL, &err);
s = optname;
optname = NULL;
if (*s == '\0' || *s == ' ')
{
/*
* The option name matches exactly.
*/
;
} else if (*s == '=')
{
/*
* The option name is followed by "=value".
*/
if (o != NULL &&
(o->otype & OTYPE) != STRING &&
(o->otype & OTYPE) != NUMBER)
{
parg.p_string = printopt;
error("The %s option should not be followed by =",
&parg);
quit(QUIT_ERROR);
}
s++;
} else
{
/*
* The specified name is longer than the
* real option name.
*/
o = NULL;
}
}
if (o == NULL)
{
parg.p_string = printopt;
if (err == OPT_AMBIG)
error("%s is an ambiguous abbreviation (\"less --help\" for help)",
&parg);
else
error("There is no %s option (\"less --help\" for help)",
&parg);
quit(QUIT_ERROR);
}
str = NULL;
switch (o->otype & OTYPE)
{
case BOOL:
if (set_default)
*(o->ovar) = o->odefault;
else
*(o->ovar) = ! o->odefault;
break;
case TRIPLE:
if (set_default)
*(o->ovar) = o->odefault;
else
*(o->ovar) = flip_triple(o->odefault, lc);
break;
case STRING:
if (*s == '\0')
{
/*
* Set pendopt and return.
* We will get the string next time
* scan_option is called.
*/
pendopt = o;
return;
}
/*
* Don't do anything here.
* All processing of STRING options is done by
* the handling function.
*/
while (*s == ' ')
s++;
s = optstring(s, &str, printopt, o->odesc[1]);
break;
case NUMBER:
if (*s == '\0')
{
pendopt = o;
return;
}
*(o->ovar) = getnum(&s, printopt, (int*)NULL);
break;
}
/*
* If the option has a handling function, call it.
*/
if (o->ofunc != NULL)
(*o->ofunc)(INIT, str);
}
}
/*
* Toggle command line flags from within the program.
* Used by the "-" and "_" commands.
* how_toggle may be:
* OPT_NO_TOGGLE just report the current setting, without changing it.
* OPT_TOGGLE invert the current setting
* OPT_UNSET set to the default value
* OPT_SET set to the inverse of the default value
*/
public void
toggle_option(c, s, how_toggle)
int c;
char *s;
int how_toggle;
{
register struct loption *o;
register int num;
int no_prompt;
int err;
PARG parg;
no_prompt = (how_toggle & OPT_NO_PROMPT);
how_toggle &= ~OPT_NO_PROMPT;
/*
* Look up the option letter in the option table.
*/
o = findopt(c);
if (o == NULL)
{
parg.p_string = propt(c);
error("There is no %s option", &parg);
return;
}
if (how_toggle == OPT_TOGGLE && (o->otype & NO_TOGGLE))
{
parg.p_string = propt(c);
error("Cannot change the %s option", &parg);
return;
}
if (how_toggle == OPT_NO_TOGGLE && (o->otype & NO_QUERY))
{
parg.p_string = propt(c);
error("Cannot query the %s option", &parg);
return;
}
/*
* Check for something which appears to be a do_toggle
* (because the "-" command was used), but really is not.
* This could be a string option with no string, or
* a number option with no number.
*/
switch (o->otype & OTYPE)
{
case STRING:
case NUMBER:
if (how_toggle == OPT_TOGGLE && *s == '\0')
how_toggle = OPT_NO_TOGGLE;
break;
}
#if HILITE_SEARCH
if (how_toggle != OPT_NO_TOGGLE && (o->otype & HL_REPAINT))
repaint_hilite(0);
#endif
/*
* Now actually toggle (change) the variable.
*/
if (how_toggle != OPT_NO_TOGGLE)
{
switch (o->otype & OTYPE)
{
case BOOL:
/*
* Boolean.
*/
switch (how_toggle)
{
case OPT_TOGGLE:
*(o->ovar) = ! *(o->ovar);
break;
case OPT_UNSET:
*(o->ovar) = o->odefault;
break;
case OPT_SET:
*(o->ovar) = ! o->odefault;
break;
}
break;
case TRIPLE:
/*
* Triple:
* If user gave the lower case letter, then switch
* to 1 unless already 1, in which case make it 0.
* If user gave the upper case letter, then switch
* to 2 unless already 2, in which case make it 0.
*/
switch (how_toggle)
{
case OPT_TOGGLE:
*(o->ovar) = flip_triple(*(o->ovar),
islower(c));
break;
case OPT_UNSET:
*(o->ovar) = o->odefault;
break;
case OPT_SET:
*(o->ovar) = flip_triple(o->odefault,
islower(c));
break;
}
break;
case STRING:
/*
* String: don't do anything here.
* The handling function will do everything.
*/
switch (how_toggle)
{
case OPT_SET:
case OPT_UNSET:
error("Cannot use \"-+\" or \"--\" for a string option",
NULL_PARG);
return;
}
break;
case NUMBER:
/*
* Number: set the variable to the given number.
*/
switch (how_toggle)
{
case OPT_TOGGLE:
num = getnum(&s, NULL, &err);
if (!err)
*(o->ovar) = num;
break;
case OPT_UNSET:
*(o->ovar) = o->odefault;
break;
case OPT_SET:
error("Can't use \"-!\" for a numeric option",
NULL_PARG);
return;
}
break;
}
}
/*
* Call the handling function for any special action
* specific to this option.
*/
if (o->ofunc != NULL)
(*o->ofunc)((how_toggle==OPT_NO_TOGGLE) ? QUERY : TOGGLE, s);
#if HILITE_SEARCH
if (how_toggle != OPT_NO_TOGGLE && (o->otype & HL_REPAINT))
chg_hilite();
#endif
if (!no_prompt)
{
/*
* Print a message describing the new setting.
*/
switch (o->otype & OTYPE)
{
case BOOL:
case TRIPLE:
/*
* Print the odesc message.
*/
error(o->odesc[*(o->ovar)], NULL_PARG);
break;
case NUMBER:
/*
* The message is in odesc[1] and has a %d for
* the value of the variable.
*/
parg.p_int = *(o->ovar);
error(o->odesc[1], &parg);
break;
case STRING:
/*
* Message was already printed by the handling function.
*/
break;
}
}
if (how_toggle != OPT_NO_TOGGLE && (o->otype & REPAINT))
screen_trashed = TRUE;
}
/*
* "Toggle" a triple-valued option.
*/
static int
flip_triple(val, lc)
int val;
int lc;
{
if (lc)
return ((val == OPT_ON) ? OPT_OFF : OPT_ON);
else
return ((val == OPT_ONPLUS) ? OPT_OFF : OPT_ONPLUS);
}
/*
* Return a string suitable for printing as the "name" of an option.
* For example, if the option letter is 'x', just return "-x".
*/
static char *
propt(c)
int c;
{
static char buf[8];
sprintf(buf, "-%s", prchar(c));
return (buf);
}
/*
* Determine if an option is a single character option (BOOL or TRIPLE),
* or if it a multi-character option (NUMBER).
*/
public int
single_char_option(c)
int c;
{
register struct loption *o;
o = findopt(c);
if (o == NULL)
return (TRUE);
return ((o->otype & (BOOL|TRIPLE|NOVAR|NO_TOGGLE)) != 0);
}
/*
* Return the prompt to be used for a given option letter.
* Only string and number valued options have prompts.
*/
public char *
opt_prompt(c)
int c;
{
register struct loption *o;
o = findopt(c);
if (o == NULL || (o->otype & (STRING|NUMBER)) == 0)
return (NULL);
return (o->odesc[0]);
}
/*
* Return whether or not there is a string option pending;
* that is, if the previous option was a string-valued option letter
* (like -P) without a following string.
* In that case, the current option is taken to be the string for
* the previous option.
*/
public int
isoptpending()
{
return (pendopt != NULL);
}
/*
* Print error message about missing string.
*/
static void
nostring(printopt)
char *printopt;
{
PARG parg;
parg.p_string = printopt;
error("Value is required after %s", &parg);
}
/*
* Print error message if a STRING type option is not followed by a string.
*/
public void
nopendopt()
{
nostring(propt(pendopt->oletter));
}
/*
* Scan to end of string or to an END_OPTION_STRING character.
* In the latter case, replace the char with a null char.
* Return a pointer to the remainder of the string, if any.
*/
static char *
optstring(s, p_str, printopt, validchars)
char *s;
char **p_str;
char *printopt;
char *validchars;
{
register char *p;
if (*s == '\0')
{
nostring(printopt);
quit(QUIT_ERROR);
}
*p_str = s;
for (p = s; *p != '\0'; p++)
{
if (*p == END_OPTION_STRING ||
(validchars != NULL && strchr(validchars, *p) == NULL))
{
switch (*p)
{
case END_OPTION_STRING:
case ' ': case '\t': case '-':
/* Replace the char with a null to terminate string. */
*p++ = '\0';
break;
default:
/* Cannot replace char; make a copy of the string. */
*p_str = (char *) ecalloc(p-s+1, sizeof(char));
strncpy(*p_str, s, p-s);
(*p_str)[p-s] = '\0';
break;
}
break;
}
}
return (p);
}
/*
* Translate a string into a number.
* Like atoi(), but takes a pointer to a char *, and updates
* the char * to point after the translated number.
*/
public int
getnum(sp, printopt, errp)
char **sp;
char *printopt;
int *errp;
{
register char *s;
register int n;
register int neg;
PARG parg;
s = skipsp(*sp);
neg = FALSE;
if (*s == '-')
{
neg = TRUE;
s++;
}
if (*s < '0' || *s > '9')
{
if (errp != NULL)
{
*errp = TRUE;
return (-1);
}
if (printopt != NULL)
{
parg.p_string = printopt;
error("Number is required after %s", &parg);
}
quit(QUIT_ERROR);
}
n = 0;
while (*s >= '0' && *s <= '9')
n = 10 * n + *s++ - '0';
*sp = s;
if (errp != NULL)
*errp = FALSE;
if (neg)
n = -n;
return (n);
}
less-382/opttbl.c 0100444 0000764 0000764 00000034465 10010075213 013020 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* The option table.
*/
#include "less.h"
#include "option.h"
/*
* Variables controlled by command line options.
*/
public int quiet; /* Should we suppress the audible bell? */
public int how_search; /* Where should forward searches start? */
public int top_scroll; /* Repaint screen from top?
(alternative is scroll from bottom) */
public int pr_type; /* Type of prompt (short, medium, long) */
public int bs_mode; /* How to process backspaces */
public int know_dumb; /* Don't complain about dumb terminals */
public int quit_at_eof; /* Quit after hitting end of file twice */
public int quit_if_one_screen; /* Quit if EOF on first screen */
public int squeeze; /* Squeeze multiple blank lines into one */
public int tabstop; /* Tab settings */
public int back_scroll; /* Repaint screen on backwards movement */
public int forw_scroll; /* Repaint screen on forward movement */
public int caseless; /* Do "caseless" searches */
public int linenums; /* Use line numbers */
public int autobuf; /* Automatically allocate buffers as needed */
public int bufspace; /* Max buffer space per file (K) */
public int ctldisp; /* Send control chars to screen untranslated */
public int force_open; /* Open the file even if not regular file */
public int swindow; /* Size of scrolling window */
public int jump_sline; /* Screen line of "jump target" */
public 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 */
public int status_col; /* Display a status column */
public int use_lessopen; /* Use the LESSOPEN filter */
#if HILITE_SEARCH
public int hilite_search; /* Highlight matched search patterns? */
#endif
/*
* Long option names.
*/
static struct optname a_optname = { "search-skip-screen", NULL };
static struct optname b_optname = { "buffers", NULL };
static struct optname B__optname = { "auto-buffers", NULL };
static struct optname c_optname = { "clear-screen", NULL };
static struct optname d_optname = { "dumb", NULL };
#if MSDOS_COMPILER
static struct optname D__optname = { "color", NULL };
#endif
static struct optname e_optname = { "quit-at-eof", NULL };
static struct optname f_optname = { "force", NULL };
static struct optname F__optname = { "quit-if-one-screen", NULL };
#if HILITE_SEARCH
static struct optname g_optname = { "hilite-search", NULL };
#endif
static struct optname h_optname = { "max-back-scroll", NULL };
static struct optname i_optname = { "ignore-case", NULL };
static struct optname j_optname = { "jump-target", NULL };
static struct optname J__optname = { "status-column", NULL };
#if USERFILE
static struct optname k_optname = { "lesskey-file", NULL };
#endif
static struct optname L__optname = { "no-lessopen", NULL };
static struct optname m_optname = { "long-prompt", NULL };
static struct optname n_optname = { "line-numbers", NULL };
#if LOGFILE
static struct optname o_optname = { "log-file", NULL };
static struct optname O__optname = { "LOG-FILE", NULL };
#endif
static struct optname p_optname = { "pattern", NULL };
static struct optname P__optname = { "prompt", NULL };
static struct optname q2_optname = { "silent", NULL };
static struct optname q_optname = { "quiet", &q2_optname };
static struct optname r_optname = { "raw-control-chars", NULL };
static struct optname s_optname = { "squeeze-blank-lines", NULL };
static struct optname S__optname = { "chop-long-lines", NULL };
#if TAGS
static struct optname t_optname = { "tag", NULL };
static struct optname T__optname = { "tag-file", NULL };
#endif
static struct optname u_optname = { "underline-special", NULL };
static struct optname V__optname = { "version", NULL };
static struct optname w_optname = { "hilite-unread", NULL };
static struct optname x_optname = { "tabs", NULL };
static struct optname X__optname = { "no-init", NULL };
static struct optname y_optname = { "max-forw-scroll", NULL };
static struct optname z_optname = { "window", NULL };
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 loption option[] =
{
{ 'a', &a_optname,
BOOL, OPT_OFF, &how_search, NULL,
{
"Search includes displayed screen",
"Search skips displayed screen",
NULL
}
},
{ 'b', &b_optname,
NUMBER|INIT_HANDLER, 64, &bufspace, opt_b,
{
"Max buffer space per file (K): ",
"Max buffer space per file: %dK",
NULL
}
},
{ 'B', &B__optname,
BOOL, OPT_ON, &autobuf, NULL,
{
"Don't automatically allocate buffers",
"Automatically allocate buffers when needed",
NULL
}
},
{ 'c', &c_optname,
TRIPLE, OPT_OFF, &top_scroll, NULL,
{
"Repaint by scrolling from bottom of screen",
"Repaint by clearing each line",
"Repaint by painting from top of screen"
}
},
{ 'd', &d_optname,
BOOL|NO_TOGGLE, OPT_OFF, &know_dumb, NULL,
{
"Assume intelligent terminal",
"Assume dumb terminal",
NULL
}
},
#if MSDOS_COMPILER
{ 'D', &D__optname,
STRING|REPAINT|NO_QUERY, 0, NULL, opt_D,
{
"color desc: ",
"Ddknsu0123456789.",
NULL
}
},
#endif
{ 'e', &e_optname,
TRIPLE, OPT_OFF, &quit_at_eof, NULL,
{
"Don't quit at end-of-file",
"Quit at end-of-file",
"Quit immediately at end-of-file"
}
},
{ 'f', &f_optname,
BOOL, OPT_OFF, &force_open, NULL,
{
"Open only regular files",
"Open even non-regular files",
NULL
}
},
{ 'F', &F__optname,
BOOL, OPT_OFF, &quit_if_one_screen, NULL,
{
"Don't quit if end-of-file on first screen",
"Quit if end-of-file on first screen",
NULL
}
},
#if HILITE_SEARCH
{ 'g', &g_optname,
TRIPLE|HL_REPAINT, OPT_ONPLUS, &hilite_search, NULL,
{
"Don't highlight search matches",
"Highlight matches for previous search only",
"Highlight all matches for previous search pattern",
}
},
#endif
{ 'h', &h_optname,
NUMBER, -1, &back_scroll, NULL,
{
"Backwards scroll limit: ",
"Backwards scroll limit is %d lines",
NULL
}
},
{ 'i', &i_optname,
TRIPLE|HL_REPAINT, OPT_OFF, &caseless, opt_i,
{
"Case is significant in searches",
"Ignore case in searches",
"Ignore case in searches and in patterns"
}
},
{ 'j', &j_optname,
NUMBER, 1, &jump_sline, NULL,
{
"Target line: ",
"Position target at screen line %d",
NULL
}
},
{ 'J', &J__optname,
BOOL|REPAINT, OPT_OFF, &status_col, NULL,
{
"Don't display a status column",
"Display a status column",
NULL
}
},
#if USERFILE
{ 'k', &k_optname,
STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_k,
{ NULL, NULL, NULL }
},
#endif
{ 'l', NULL,
STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_l,
{ NULL, NULL, NULL }
},
{ 'L', &L__optname,
BOOL, OPT_ON, &use_lessopen, NULL,
{
"Don't use the LESSOPEN filter",
"Use the LESSOPEN filter",
NULL
}
},
{ 'm', &m_optname,
TRIPLE, OPT_OFF, &pr_type, NULL,
{
"Short prompt",
"Medium prompt",
"Long prompt"
}
},
{ 'n', &n_optname,
TRIPLE|REPAINT, OPT_ON, &linenums, NULL,
{
"Don't use line numbers",
"Use line numbers",
"Constantly display line numbers"
}
},
#if LOGFILE
{ 'o', &o_optname,
STRING, 0, NULL, opt_o,
{ "log file: ", NULL, NULL }
},
{ 'O', &O__optname,
STRING, 0, NULL, opt__O,
{ "Log file: ", NULL, NULL }
},
#endif
{ 'p', &p_optname,
STRING|NO_TOGGLE|NO_QUERY, 0, NULL, opt_p,
{ NULL, NULL, NULL }
},
{ 'P', &P__optname,
STRING, 0, NULL, opt__P,
{ "prompt: ", NULL, NULL }
},
{ 'q', &q_optname,
TRIPLE, OPT_OFF, &quiet, NULL,
{
"Ring the bell for errors AND at eof/bof",
"Ring the bell for errors but not at eof/bof",
"Never ring the bell"
}
},
{ 'r', &r_optname,
TRIPLE|REPAINT, OPT_OFF, &ctldisp, NULL,
{
"Display control characters as ^X",
"Display control characters directly",
"Display control characters directly, processing ANSI sequences"
}
},
{ 's', &s_optname,
BOOL|REPAINT, OPT_OFF, &squeeze, NULL,
{
"Display all blank lines",
"Squeeze multiple blank lines",
NULL
}
},
{ 'S', &S__optname,
BOOL|REPAINT, OPT_OFF, &chopline, NULL,
{
"Fold long lines",
"Chop long lines",
NULL
}
},
#if TAGS
{ 't', &t_optname,
STRING|NO_QUERY, 0, NULL, opt_t,
{ "tag: ", NULL, NULL }
},
{ 'T', &T__optname,
STRING, 0, NULL, opt__T,
{ "tags file: ", NULL, NULL }
},
#endif
{ 'u', &u_optname,
TRIPLE|REPAINT, OPT_OFF, &bs_mode, NULL,
{
"Display underlined text in underline mode",
"Backspaces cause overstrike",
"Print backspace as ^H"
}
},
{ 'V', &V__optname,
NOVAR, 0, NULL, opt__V,
{ NULL, NULL, NULL }
},
{ 'w', &w_optname,
TRIPLE|REPAINT, OPT_OFF, &show_attn, NULL,
{
"Don't highlight first unread line",
"Highlight first unread line after forward-screen",
"Highlight first unread line after any forward movement",
}
},
{ 'x', &x_optname,
STRING|REPAINT, 0, NULL, opt_x,
{
"Tab stops: ",
"0123456789,",
NULL
}
},
{ 'X', &X__optname,
BOOL|NO_TOGGLE, OPT_OFF, &no_init, NULL,
{
"Send init/deinit strings to terminal",
"Don't use init/deinit strings",
NULL
}
},
{ 'y', &y_optname,
NUMBER, -1, &forw_scroll, NULL,
{
"Forward scroll limit: ",
"Forward scroll limit is %d lines",
NULL
}
},
{ 'z', &z_optname,
NUMBER, -1, &swindow, NULL,
{
"Scroll window size: ",
"Scroll window size is %d lines",
NULL
}
},
{ '"', "e_optname,
STRING, 0, NULL, opt_quote,
{ "quotes: ", NULL, NULL }
},
{ '~', &tilde_optname,
BOOL|REPAINT, OPT_ON, &twiddle, NULL,
{
"Don't show tildes after end of file",
"Show tildes after end of file",
NULL
}
},
{ '?', &query_optname,
NOVAR, 0, NULL, opt_query,
{ NULL, NULL, NULL }
},
{ '#', £_optname,
NUMBER, 0, &shift_count, NULL,
{
"Horizontal shift: ",
"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 } }
};
/*
* Initialize each option to its default value.
*/
public void
init_option()
{
register struct loption *o;
for (o = option; o->oletter != '\0'; o++)
{
/*
* Set each variable to its default.
*/
if (o->ovar != NULL)
*(o->ovar) = o->odefault;
if (o->otype & INIT_HANDLER)
(*(o->ofunc))(INIT, (char *) NULL);
}
}
/*
* Find an option in the option table, given its option letter.
*/
public struct loption *
findopt(c)
int c;
{
register struct loption *o;
for (o = option; o->oletter != '\0'; o++)
{
if (o->oletter == c)
return (o);
if ((o->otype & TRIPLE) && toupper(o->oletter) == c)
return (o);
}
return (NULL);
}
/*
*
*/
static int
is_optchar(c)
char c;
{
if (SIMPLE_IS_UPPER(c))
return 1;
if (SIMPLE_IS_LOWER(c))
return 1;
if (c == '-')
return 1;
return 0;
}
/*
* Find an option in the option table, given its option name.
* p_optname is the (possibly partial) name to look for, and
* is updated to point after the matched name.
* p_oname if non-NULL is set to point to the full option name.
*/
public struct loption *
findopt_name(p_optname, p_oname, p_err)
char **p_optname;
char **p_oname;
int *p_err;
{
char *optname = *p_optname;
register struct loption *o;
register struct optname *oname;
register int len;
int uppercase;
struct loption *maxo = NULL;
struct optname *maxoname = NULL;
int maxlen = 0;
int ambig = 0;
int exact = 0;
char *eq;
/*
* Check all options.
*/
for (o = option; o->oletter != '\0'; o++)
{
/*
* Check all names for this option.
*/
for (oname = o->onames; oname != NULL; oname = oname->onext)
{
/*
* Try normal match first (uppercase == 0),
* then, then if it's a TRIPLE option,
* try uppercase match (uppercase == 1).
*/
for (uppercase = 0; uppercase <= 1; uppercase++)
{
len = sprefix(optname, oname->oname, uppercase);
if (len <= 0 || is_optchar(optname[len]))
{
/*
* We didn't use all of the option name.
*/
continue;
}
if (!exact && len == maxlen)
/*
* Already had a partial match,
* and now there's another one that
* matches the same length.
*/
ambig = 1;
else if (len > maxlen)
{
/*
* Found a better match than
* the one we had.
*/
maxo = o;
maxoname = oname;
maxlen = len;
ambig = 0;
exact = (len == (int)strlen(oname->oname));
}
if (!(o->otype & TRIPLE))
break;
}
}
}
if (ambig)
{
/*
* Name matched more than one option.
*/
if (p_err != NULL)
*p_err = OPT_AMBIG;
return (NULL);
}
*p_optname = optname + maxlen;
if (p_oname != NULL)
*p_oname = maxoname == NULL ? NULL : maxoname->oname;
return (maxo);
}
less-382/os.c 0100444 0000764 0000764 00000013052 10010075213 012122 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Operating system dependent routines.
*
* Most of the stuff in here is based on Unix, but an attempt
* has been made to make things work on other operating systems.
* This will sometimes result in a loss of functionality, unless
* someone rewrites code specifically for the new operating system.
*
* The makefile provides defines to decide whether various
* Unix features are present.
*/
#include "less.h"
#include
#include
#if HAVE_TIME_H
#include
#endif
#if HAVE_ERRNO_H
#include
#endif
#if HAVE_VALUES_H
#include
#endif
#if HAVE_TIME_T
#define time_type time_t
#else
#define time_type long
#endif
/*
* BSD setjmp() saves (and longjmp() restores) the signal mask.
* This costs a system call or two per setjmp(), so if possible we clear the
* signal mask with sigsetmask(), and use _setjmp()/_longjmp() instead.
* On other systems, setjmp() doesn't affect the signal mask and so
* _setjmp() does not exist; we just use setjmp().
*/
#if HAVE__SETJMP && HAVE_SIGSETMASK
#define SET_JUMP _setjmp
#define LONG_JUMP _longjmp
#else
#define SET_JUMP setjmp
#define LONG_JUMP longjmp
#endif
public int reading;
static jmp_buf read_label;
extern int sigs;
/*
* Like read() system call, but is deliberately interruptible.
* A call to intread() from a signal handler will interrupt
* any pending iread().
*/
public int
iread(fd, buf, len)
int fd;
char *buf;
unsigned int len;
{
register int n;
#if MSDOS_COMPILER==WIN32C
if (ABORT_SIGS())
return (READ_INTR);
#else
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
if (kbhit())
{
int c;
c = getch();
if (c == '\003')
return (READ_INTR);
ungetch(c);
}
#endif
#endif
if (SET_JUMP(read_label))
{
/*
* We jumped here from intread.
*/
reading = 0;
#if HAVE_SIGPROCMASK
{
sigset_t mask;
sigemptyset(&mask);
sigprocmask(SIG_SETMASK, &mask, NULL);
}
#else
#if HAVE_SIGSETMASK
sigsetmask(0);
#else
#ifdef _OSK
sigmask(~0);
#endif
#endif
#endif
return (READ_INTR);
}
flush();
reading = 1;
#if MSDOS_COMPILER==DJGPPC
if (isatty(fd))
{
/*
* Don't try reading from a TTY until a character is
* available, because that makes some background programs
* believe DOS is busy in a way that prevents those
* programs from working while "less" waits.
*/
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
if (select(fd+1, &readfds, 0, 0, 0) == -1)
return (-1);
}
#endif
n = read(fd, buf, len);
#if 1
/*
* This is a kludge to workaround a problem on some systems
* where terminating a remote tty connection causes read() to
* start returning 0 forever, instead of -1.
*/
{
extern int ignore_eoi;
if (!ignore_eoi)
{
static int consecutive_nulls = 0;
if (n == 0)
consecutive_nulls++;
else
consecutive_nulls = 0;
if (consecutive_nulls > 20)
quit(QUIT_ERROR);
}
}
#endif
reading = 0;
if (n < 0)
return (-1);
return (n);
}
/*
* Interrupt a pending iread().
*/
public void
intread()
{
LONG_JUMP(read_label, 1);
}
/*
* Return the current time.
*/
#if HAVE_TIME
public long
get_time()
{
time_type t;
time(&t);
return (t);
}
#endif
#if !HAVE_STRERROR
/*
* Local version of strerror, if not available from the system.
*/
static char *
strerror(err)
int err;
{
#if HAVE_SYS_ERRLIST
static char buf[16];
extern char *sys_errlist[];
extern int sys_nerr;
if (err < sys_nerr)
return sys_errlist[err];
sprintf(buf, "Error %d", err);
return buf;
#else
return ("cannot open");
#endif
}
#endif
/*
* errno_message: Return an error message based on the value of "errno".
*/
public char *
errno_message(filename)
char *filename;
{
register char *p;
register char *m;
#if HAVE_ERRNO
#if MUST_DEFINE_ERRNO
extern int errno;
#endif
p = strerror(errno);
#else
p = "cannot open";
#endif
m = (char *) ecalloc(strlen(filename) + strlen(p) + 3, sizeof(char));
sprintf(m, "%s: %s", filename, p);
return (m);
}
/*
* Return the ratio of two POSITIONS, as a percentage.
* {{ Assumes a POSITION is a long int. }}
*/
public int
percentage(num, den)
POSITION 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.
*/
public POSITION
percent_pos(pos, percent)
POSITION pos;
int percent;
{
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
/*
* This implements an ANSI-style intercept setup for Microware C 3.2
*/
public int
os9_signal(type, handler)
int type;
RETSIGTYPE (*handler)();
{
intercept(handler);
}
#include
int
isatty(f)
int f;
{
struct sgbuf sgbuf;
if (_gs_opt(f, &sgbuf) < 0)
return -1;
return (sgbuf.sg_class == 0);
}
#endif
less-382/output.c 0100444 0000764 0000764 00000026577 10010075213 013061 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* High level routines dealing with the output to the screen.
*/
#include "less.h"
#if MSDOS_COMPILER==WIN32C
#include "windows.h"
#endif
public int errmsgs; /* Count of messages displayed by error() */
public int need_clr;
public int final_attr;
extern int sigs;
extern int sc_width;
extern int so_s_width, so_e_width;
extern int screen_trashed;
extern int any_display;
extern int is_tty;
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
extern int ctldisp;
extern int nm_fg_color, nm_bg_color;
extern int bo_fg_color, bo_bg_color;
extern int ul_fg_color, ul_bg_color;
extern int so_fg_color, so_bg_color;
extern int bl_fg_color, bl_bg_color;
#endif
/*
* Display the line which is in the line buffer.
*/
public void
put_line()
{
register int c;
register int i;
int a;
int curr_attr;
if (ABORT_SIGS())
{
/*
* Don't output if a signal is pending.
*/
screen_trashed = 1;
return;
}
curr_attr = AT_NORMAL;
for (i = 0; (c = gline(i, &a)) != '\0'; i++)
{
if (a != curr_attr)
{
/*
* Changing attributes.
* Display the exit sequence for the old attribute
* and the enter sequence for the new one.
*/
switch (curr_attr)
{
case AT_UNDERLINE: ul_exit(); break;
case AT_BOLD: bo_exit(); break;
case AT_BLINK: bl_exit(); break;
case AT_STANDOUT: so_exit(); break;
}
switch (a)
{
case AT_UNDERLINE: ul_enter(); break;
case AT_BOLD: bo_enter(); break;
case AT_BLINK: bl_enter(); break;
case AT_STANDOUT: so_enter(); break;
}
curr_attr = a;
}
if (curr_attr == AT_INVIS)
continue;
if (c == '\b')
putbs();
else
putchr(c);
}
switch (curr_attr)
{
case AT_UNDERLINE: ul_exit(); break;
case AT_BOLD: bo_exit(); break;
case AT_BLINK: bl_exit(); break;
case AT_STANDOUT: so_exit(); break;
}
final_attr = curr_attr;
}
static char obuf[OUTBUF_SIZE];
static char *ob = obuf;
/*
* Flush buffered output.
*
* If we haven't displayed any file data yet,
* output messages on error output (file descriptor 2),
* otherwise output on standard output (file descriptor 1).
*
* This has the desirable effect of producing all
* error messages on error output if standard output
* is directed to a file. It also does the same if
* we never produce any real output; for example, if
* the input file(s) cannot be opened. If we do
* eventually produce output, code in edit() makes
* sure these messages can be seen before they are
* overwritten or scrolled away.
*/
public void
flush()
{
register int n;
register int fd;
n = ob - obuf;
if (n == 0)
return;
#if MSDOS_COMPILER==WIN32C
if (is_tty && any_display)
{
char *op;
DWORD nwritten = 0;
CONSOLE_SCREEN_BUFFER_INFO scr;
int row;
int col;
int olen;
extern HANDLE con_out;
olen = ob - obuf;
/*
* 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.
*/
GetConsoleScreenBufferInfo(con_out, &scr);
col = scr.dwCursorPosition.X;
row = scr.dwCursorPosition.Y;
for (op = obuf; op < obuf + olen; op++)
{
if (*op == '\n')
{
col = 0;
row++;
} else if (*op == '\r')
{
col = 0;
} else
{
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;
}
#else
#if MSDOS_COMPILER==MSOFTC
if (is_tty && any_display)
{
*ob = '\0';
_outtext(obuf);
ob = obuf;
return;
}
#else
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
if (is_tty && any_display)
{
*ob = '\0';
if (ctldisp != OPT_ONPLUS)
cputs(obuf);
else
{
/*
* Look for SGR escape sequences, and convert them
* to color commands. Replace bold, underline,
* and italic escapes into colors specified via
* the -D command-line option.
*/
char *anchor, *p, *p_next;
int buflen = ob - obuf;
unsigned char fg, bg, norm_attr;
/*
* Only dark colors mentioned here, so that
* bold has visible effect.
*/
static enum COLORS screen_color[] = {
BLACK, RED, GREEN, BROWN,
BLUE, MAGENTA, CYAN, LIGHTGRAY
};
/* Normal text colors are used as baseline. */
bg = nm_bg_color & 0xf;
fg = nm_fg_color & 0xf;
norm_attr = (bg << 4) | fg;
for (anchor = p_next = obuf;
(p_next = memchr (p_next, ESC,
buflen - (p_next - obuf)))
!= NULL; )
{
p = p_next;
/*
* Handle the null escape sequence
* (ESC-[m), which is used to restore
* the original color.
*/
if (p[1] == '[' && is_ansi_end(p[2]))
{
textattr(norm_attr);
p += 3;
anchor = p_next = p;
continue;
}
if (p[1] == '[') /* "Esc-[" sequence */
{
/*
* If some chars seen since
* the last escape sequence,
* write it out to the screen
* using current text attributes.
*/
if (p > anchor)
{
*p = '\0';
cputs (anchor);
*p = ESC;
anchor = p;
}
p += 2;
p_next = p;
while (!is_ansi_end(*p))
{
char *q;
long code = strtol(p, &q, 10);
if (!*q)
{
/*
* Incomplete sequence.
* Leave it unprocessed
* in the buffer.
*/
int slop = q - anchor;
strcpy(obuf, anchor);
ob = &obuf[slop];
return;
}
if (q == p
|| code > 49 || code < 0
|| (!is_ansi_end(*q)
&& *q != ';'))
{
p_next = q;
break;
}
if (*q == ';')
q++;
switch (code)
{
case 1: /* bold on */
fg = bo_fg_color;
bg = bo_bg_color;
break;
case 3: /* italic on */
fg = so_fg_color;
bg = so_bg_color;
break;
case 4: /* underline on */
fg = ul_fg_color;
bg = ul_bg_color;
break;
case 8: /* concealed on */
fg = (bg & 7) | 8;
break;
case 0: /* all attrs off */
case 22:/* bold off */
case 23:/* italic off */
case 24:/* underline off */
fg = nm_fg_color;
bg = nm_bg_color;
break;
case 30: case 31: case 32:
case 33: case 34: case 35:
case 36: case 37:
fg = (fg & 8) | (screen_color[code - 30]);
break;
case 39: /* default fg */
fg = nm_fg_color;
break;
case 40: case 41: case 42:
case 43: case 44: case 45:
case 46: case 47:
bg = (bg & 8) | (screen_color[code - 40]);
break;
case 49: /* default fg */
bg = nm_bg_color;
break;
}
p = q;
}
if (is_ansi_end(*p) && p > p_next)
{
bg &= 15;
fg &= 15;
textattr ((bg << 4)| fg);
p_next = anchor = p + 1;
} else
break;
} else
p_next++;
}
/* Output what's left in the buffer. */
cputs (anchor);
}
ob = obuf;
return;
}
#endif
#endif
#endif
fd = (any_display) ? 1 : 2;
if (write(fd, obuf, n) != n)
screen_trashed = 1;
ob = obuf;
}
/*
* Output a character.
*/
public int
putchr(c)
int c;
{
if (need_clr)
{
need_clr = 0;
clear_bot();
}
#if MSDOS_COMPILER
if (c == '\n' && is_tty)
{
/* remove_top(1); */
putchr('\r');
}
#else
#ifdef _OSK
if (c == '\n' && is_tty) /* In OS-9, '\n' == 0x0D */
putchr(0x0A);
#endif
#endif
/*
* Some versions of flush() write to *ob, so we must flush
* when we are still one char from the end of obuf.
*/
if (ob >= &obuf[sizeof(obuf)-1])
flush();
*ob++ = c;
return (c);
}
/*
* Output a string.
*/
public void
putstr(s)
register char *s;
{
while (*s != '\0')
putchr(*s++);
}
/*
* Convert an integral type to a string.
*/
#define TYPE_TO_A_FUNC(funcname, type) \
void funcname(num, buf) \
type num; \
char *buf; \
{ \
int neg = (num < 0); \
char tbuf[INT_STRLEN_BOUND(num)+2]; \
register char *s = tbuf + sizeof(tbuf); \
if (neg) num = -num; \
*--s = '\0'; \
do { \
*--s = (num % 10) + '0'; \
} while ((num /= 10) != 0); \
if (neg) *--s = '-'; \
strcpy(buf, s); \
}
TYPE_TO_A_FUNC(postoa, POSITION)
TYPE_TO_A_FUNC(linenumtoa, LINENUM)
TYPE_TO_A_FUNC(inttoa, int)
/*
* Output an integer in a given radix.
*/
static int
iprint_int(num)
int num;
{
char buf[INT_STRLEN_BOUND(num)];
inttoa(num, buf);
putstr(buf);
return (strlen(buf));
}
/*
* Output a line number in a given radix.
*/
static int
iprint_linenum(num)
LINENUM num;
{
char buf[INT_STRLEN_BOUND(num)];
linenumtoa(num, buf);
putstr(buf);
return (strlen(buf));
}
/*
* This function implements printf-like functionality
* using a more portable argument list mechanism than printf's.
*/
static int
less_printf(fmt, parg)
register char *fmt;
PARG *parg;
{
register char *s;
register int col;
col = 0;
while (*fmt != '\0')
{
if (*fmt != '%')
{
putchr(*fmt++);
col++;
} else
{
++fmt;
switch (*fmt++)
{
case 's':
s = parg->p_string;
parg++;
while (*s != '\0')
{
putchr(*s++);
col++;
}
break;
case 'd':
col += iprint_int(parg->p_int);
parg++;
break;
case 'n':
col += iprint_linenum(parg->p_linenum);
parg++;
break;
}
}
}
return (col);
}
/*
* Get a RETURN.
* If some other non-trivial char is pressed, unget it, so it will
* become the next command.
*/
public void
get_return()
{
int c;
#if ONLY_RETURN
while ((c = getchr()) != '\n' && c != '\r')
bell();
#else
c = getchr();
if (c != '\n' && c != '\r' && c != ' ' && c != READ_INTR)
ungetcc(c);
#endif
}
/*
* Output a message in the lower left corner of the screen
* and wait for carriage return.
*/
public void
error(fmt, parg)
char *fmt;
PARG *parg;
{
int col = 0;
static char return_to_continue[] = " (press RETURN)";
errmsgs++;
if (any_display && is_tty)
{
clear_bot();
so_enter();
col += so_s_width;
}
col += less_printf(fmt, parg);
if (!(any_display && is_tty))
{
putchr('\n');
return;
}
putstr(return_to_continue);
so_exit();
col += sizeof(return_to_continue) + so_e_width;
get_return();
lower_left();
if (col >= sc_width)
/*
* Printing the message has probably scrolled the screen.
* {{ Unless the terminal doesn't have auto margins,
* in which case we just hammered on the right margin. }}
*/
screen_trashed = 1;
flush();
}
static char intr_to_abort[] = "... (interrupt to abort)";
/*
* Output a message in the lower left corner of the screen
* and don't wait for carriage return.
* Usually used to warn that we are beginning a potentially
* time-consuming operation.
*/
public void
ierror(fmt, parg)
char *fmt;
PARG *parg;
{
clear_bot();
so_enter();
(void) less_printf(fmt, parg);
putstr(intr_to_abort);
so_exit();
flush();
need_clr = 1;
}
/*
* Output a message in the lower left corner of the screen
* and return a single-character response.
*/
public int
query(fmt, parg)
char *fmt;
PARG *parg;
{
register int c;
int col = 0;
if (any_display && is_tty)
clear_bot();
(void) less_printf(fmt, parg);
c = getchr();
if (!(any_display && is_tty))
{
putchr('\n');
return (c);
}
lower_left();
if (col >= sc_width)
screen_trashed = 1;
flush();
return (c);
}
less-382/position.c 0100444 0000764 0000764 00000011446 10010075213 013352 0 ustar markn markn /*
* Copyright (C) 1984-2002 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines dealing with the "position" table.
* This is a table which tells the position (in the input file) of the
* first char on each currently displayed line.
*
* {{ The position table is scrolled by moving all the entries.
* Would be better to have a circular table
* and just change a couple of pointers. }}
*/
#include "less.h"
#include "position.h"
static POSITION *table = NULL; /* The position table */
static int table_size;
extern int sc_width, sc_height;
/*
* Return the starting file position of a line displayed on the screen.
* The line may be specified as a line number relative to the top
* of the screen, but is usually one of these special cases:
* the top (first) line on the screen
* the second line on the screen
* the bottom line on the screen
* the line after the bottom line on the screen
*/
public POSITION
position(where)
int where;
{
switch (where)
{
case BOTTOM:
where = sc_height - 2;
break;
case BOTTOM_PLUS_ONE:
where = sc_height - 1;
break;
case MIDDLE:
where = (sc_height - 1) / 2;
}
return (table[where]);
}
/*
* Add a new file position to the bottom of the position table.
*/
public void
add_forw_pos(pos)
POSITION pos;
{
register int i;
/*
* Scroll the position table up.
*/
for (i = 1; i < sc_height; i++)
table[i-1] = table[i];
table[sc_height - 1] = pos;
}
/*
* Add a new file position to the top of the position table.
*/
public void
add_back_pos(pos)
POSITION pos;
{
register int i;
/*
* Scroll the position table down.
*/
for (i = sc_height - 1; i > 0; i--)
table[i] = table[i-1];
table[0] = pos;
}
/*
* Initialize the position table, done whenever we clear the screen.
*/
public void
pos_clear()
{
register int i;
for (i = 0; i < sc_height; i++)
table[i] = NULL_POSITION;
}
/*
* Allocate or reallocate the position table.
*/
public void
pos_init()
{
struct scrpos scrpos;
if (sc_height <= table_size)
return;
/*
* If we already have a table, remember the first line in it
* before we free it, so we can copy that line to the new table.
*/
if (table != NULL)
{
get_scrpos(&scrpos);
free((char*)table);
} else
scrpos.pos = NULL_POSITION;
table = (POSITION *) ecalloc(sc_height, sizeof(POSITION));
table_size = sc_height;
pos_clear();
if (scrpos.pos != NULL_POSITION)
table[scrpos.ln-1] = scrpos.pos;
}
/*
* See if the byte at a specified position is currently on the screen.
* Check the position table to see if the position falls within its range.
* Return the position table entry if found, -1 if not.
*/
public int
onscreen(pos)
POSITION pos;
{
register int i;
if (pos < table[0])
return (-1);
for (i = 1; i < sc_height; i++)
if (pos < table[i])
return (i-1);
return (-1);
}
/*
* See if the entire screen is empty.
*/
public int
empty_screen()
{
return (empty_lines(0, sc_height-1));
}
public int
empty_lines(s, e)
int s;
int e;
{
register int i;
for (i = s; i <= e; i++)
if (table[i] != NULL_POSITION)
return (0);
return (1);
}
/*
* Get the current screen position.
* The screen position consists of both a file position and
* a screen line number where the file position is placed on the screen.
* Normally the screen line number is 0, but if we are positioned
* such that the top few lines are empty, we may have to set
* the screen line to a number > 0.
*/
public void
get_scrpos(scrpos)
struct scrpos *scrpos;
{
register int i;
/*
* Find the first line on the screen which has something on it,
* and return the screen line number and the file position.
*/
for (i = 0; i < sc_height; i++)
if (table[i] != NULL_POSITION)
{
scrpos->ln = i+1;
scrpos->pos = table[i];
return;
}
/*
* The screen is empty.
*/
scrpos->pos = NULL_POSITION;
}
/*
* Adjust a screen line number to be a simple positive integer
* in the range { 0 .. sc_height-2 }.
* (The bottom line, sc_height-1, is reserved for prompts, etc.)
* The given "sline" may be in the range { 1 .. sc_height-1 }
* to refer to lines relative to the top of the screen (starting from 1),
* or it may be in { -1 .. -(sc_height-1) } to refer to lines
* relative to the bottom of the screen.
*/
public int
adjsline(sline)
int sline;
{
/*
* Negative screen line number means
* relative to the bottom of the screen.
*/
if (sline < 0)
sline += sc_height;
/*
* Can't be less than 1 or greater than sc_height-1.
*/
if (sline <= 0)
sline = 1;
if (sline >= sc_height)
sline = sc_height - 1;
/*
* Return zero-based line number, not one-based.
*/
return (sline-1);
}
less-382/prompt.c 0100444 0000764 0000764 00000026361 10010075213 013031 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Prompting and other messages.
* There are three flavors of prompts, SHORT, MEDIUM and LONG,
* selected by the -m/-M options.
* There is also the "equals message", printed by the = command.
* A prompt is a message composed of various pieces, such as the
* name of the file being viewed, the percentage into the file, etc.
*/
#include "less.h"
#include "position.h"
extern int pr_type;
extern int hit_eof;
extern int new_file;
extern int sc_width;
extern int so_s_width, so_e_width;
extern int linenums;
extern int hshift;
extern int sc_height;
extern int jump_sline;
extern IFILE curr_ifile;
#if EDITOR
extern char *editor;
extern char *editproto;
#endif
/*
* Prototypes for the three flavors of prompts.
* These strings are expanded by pr_expand().
*/
static constant char s_proto[] =
"?n?f%f .?m(%T %i of %m) ..?e(END) ?x- Next\\: %x..%t";
static constant char m_proto[] =
"?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(%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(%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;
/*
* Initialize the prompt prototype strings.
*/
public void
init_prompt()
{
prproto[0] = save(s_proto);
prproto[1] = save(m_proto);
prproto[2] = save(M_proto);
eqproto = save(e_proto);
hproto = save(h_proto);
wproto = save(w_proto);
}
/*
* Append a string to the end of the message.
*/
static void
ap_str(s)
char *s;
{
int len;
len = strlen(s);
if (mp + len >= message + PROMPT_SIZE)
len = message + PROMPT_SIZE - mp - 1;
strncpy(mp, s, len);
mp += len;
*mp = '\0';
}
/*
* Append a character to the end of the message.
*/
static void
ap_char(c)
char c;
{
char buf[2];
buf[0] = c;
buf[1] = '\0';
ap_str(buf);
}
/*
* Append a POSITION (as a decimal integer) to the end of the message.
*/
static void
ap_pos(pos)
POSITION pos;
{
char buf[INT_STRLEN_BOUND(pos) + 2];
postoa(pos, buf);
ap_str(buf);
}
/*
* Append a line number to the end of the message.
*/
static void
ap_linenum(linenum)
LINENUM linenum;
{
char buf[INT_STRLEN_BOUND(linenum) + 2];
linenumtoa(linenum, buf);
ap_str(buf);
}
/*
* Append an integer to the end of the message.
*/
static void
ap_int(num)
int num;
{
char buf[INT_STRLEN_BOUND(num) + 2];
inttoa(num, buf);
ap_str(buf);
}
/*
* Append a question mark to the end of the message.
*/
static void
ap_quest()
{
ap_str("?");
}
/*
* Return the "current" byte offset in the file.
*/
static POSITION
curr_byte(where)
int where;
{
POSITION pos;
pos = position(where);
while (pos == NULL_POSITION && where >= 0 && where < sc_height)
pos = position(++where);
if (pos == NULL_POSITION)
pos = ch_length();
return (pos);
}
/*
* Return the value of a prototype conditional.
* A prototype string may include conditionals which consist of a
* question mark followed by a single letter.
* Here we decode that letter and return the appropriate boolean value.
*/
static int
cond(c, where)
char c;
int where;
{
POSITION len;
switch (c)
{
case 'a': /* Anything in the message yet? */
return (mp > message);
case 'b': /* Current byte offset known? */
return (curr_byte(where) != NULL_POSITION);
case 'c':
return (hshift != 0);
case 'e': /* At end of file? */
return (hit_eof);
case 'f': /* Filename known? */
return (strcmp(get_filename(curr_ifile), "-") != 0);
case 'l': /* Line number known? */
case 'd': /* Same as l */
return (linenums);
case 'L': /* Final line number known? */
case 'D': /* Same as L */
return (linenums && ch_length() != NULL_POSITION);
case 'm': /* More than one file? */
#if TAGS
return (ntags() ? (ntags() > 1) : (nifile() > 1));
#else
return (nifile() > 1);
#endif
case 'n': /* First prompt in a new file? */
#if TAGS
return (ntags() ? 1 : new_file);
#else
return (new_file);
#endif
case 'p': /* Percent into file (bytes) known? */
return (curr_byte(where) != NULL_POSITION &&
ch_length() > 0);
case 'P': /* Percent into file (lines) known? */
return (currline(where) != 0 &&
(len = ch_length()) > 0 &&
find_linenum(len) != 0);
case 's': /* Size of file known? */
case 'B':
return (ch_length() != NULL_POSITION);
case 'x': /* Is there a "next" file? */
#if TAGS
if (ntags())
return (0);
#endif
return (next_ifile(curr_ifile) != NULL_IFILE);
}
return (0);
}
/*
* Decode a "percent" prototype character.
* A prototype string may include various "percent" escapes;
* that is, a percent sign followed by a single letter.
* Here we decode that letter and take the appropriate action,
* usually by appending something to the message being built.
*/
static void
protochar(c, where, iseditproto)
int c;
int where;
int iseditproto;
{
POSITION pos;
POSITION len;
int n;
LINENUM linenum;
LINENUM last_linenum;
IFILE h;
switch (c)
{
case 'b': /* Current byte offset */
pos = curr_byte(where);
if (pos != NULL_POSITION)
ap_pos(pos);
else
ap_quest();
break;
case 'c':
ap_int(hshift);
break;
case 'd': /* Current page number */
linenum = currline(where);
if (linenum > 0 && sc_height > 1)
ap_linenum(((linenum - 1) / (sc_height - 1)) + 1);
else
ap_quest();
break;
case 'D': /* Last page number */
len = ch_length();
if (len == NULL_POSITION || len == ch_zero() ||
(linenum = find_linenum(len)) <= 0)
ap_quest();
else
ap_linenum(((linenum - 1) / (sc_height - 1)) + 1);
break;
#if EDITOR
case 'E': /* Editor name */
ap_str(editor);
break;
#endif
case 'f': /* File name */
ap_str(get_filename(curr_ifile));
break;
case 'i': /* Index into list of files */
#if TAGS
if (ntags())
ap_int(curr_tag());
else
#endif
ap_int(get_index(curr_ifile));
break;
case 'l': /* Current line number */
linenum = currline(where);
if (linenum != 0)
ap_linenum(linenum);
else
ap_quest();
break;
case 'L': /* Final line number */
len = ch_length();
if (len == NULL_POSITION || len == ch_zero() ||
(linenum = find_linenum(len)) <= 0)
ap_quest();
else
ap_linenum(linenum-1);
break;
case 'm': /* Number of files */
#if TAGS
n = ntags();
if (n)
ap_int(n);
else
#endif
ap_int(nifile());
break;
case 'p': /* Percent into file (bytes) */
pos = curr_byte(where);
len = ch_length();
if (pos != NULL_POSITION && len > 0)
ap_int(percentage(pos,len));
else
ap_quest();
break;
case 'P': /* Percent into file (lines) */
linenum = currline(where);
if (linenum == 0 ||
(len = ch_length()) == NULL_POSITION || len == ch_zero() ||
(last_linenum = find_linenum(len)) <= 0)
ap_quest();
else
ap_int(percentage(linenum, last_linenum));
break;
case 's': /* Size of file */
case 'B':
len = ch_length();
if (len != NULL_POSITION)
ap_pos(len);
else
ap_quest();
break;
case 't': /* Truncate trailing spaces in the message */
while (mp > message && mp[-1] == ' ')
mp--;
break;
case 'T': /* Type of list */
#if TAGS
if (ntags())
ap_str("tag");
else
#endif
ap_str("file");
break;
case 'x': /* Name of next file */
h = next_ifile(curr_ifile);
if (h != NULL_IFILE)
ap_str(get_filename(h));
else
ap_quest();
break;
}
}
/*
* Skip a false conditional.
* When a false condition is found (either a false IF or the ELSE part
* of a true IF), this routine scans the prototype string to decide
* where to resume parsing the string.
* We must keep track of nested IFs and skip them properly.
*/
static char *
skipcond(p)
register char *p;
{
register int iflevel;
/*
* We came in here after processing a ? or :,
* so we start nested one level deep.
*/
iflevel = 1;
for (;;) switch (*++p)
{
case '?':
/*
* Start of a nested IF.
*/
iflevel++;
break;
case ':':
/*
* Else.
* If this matches the IF we came in here with,
* then we're done.
*/
if (iflevel == 1)
return (p);
break;
case '.':
/*
* Endif.
* If this matches the IF we came in here with,
* then we're done.
*/
if (--iflevel == 0)
return (p);
break;
case '\\':
/*
* Backslash escapes the next character.
*/
++p;
break;
case '\0':
/*
* Whoops. Hit end of string.
* This is a malformed conditional, but just treat it
* as if all active conditionals ends here.
*/
return (p-1);
}
/*NOTREACHED*/
}
/*
* Decode a char that represents a position on the screen.
*/
static char *
wherechar(p, wp)
char *p;
int *wp;
{
switch (*p)
{
case 'b': case 'd': case 'l': case 'p': case 'P':
switch (*++p)
{
case 't': *wp = TOP; break;
case 'm': *wp = MIDDLE; break;
case 'b': *wp = BOTTOM; break;
case 'B': *wp = BOTTOM_PLUS_ONE; break;
case 'j': *wp = adjsline(jump_sline); break;
default: *wp = TOP; p--; break;
}
}
return (p);
}
/*
* Construct a message based on a prototype string.
*/
public char *
pr_expand(proto, maxwidth)
char *proto;
int maxwidth;
{
register char *p;
register int c;
int where;
mp = message;
if (*proto == '\0')
return ("");
for (p = proto; *p != '\0'; p++)
{
switch (*p)
{
default: /* Just put the character in the message */
ap_char(*p);
break;
case '\\': /* Backslash escapes the next character */
p++;
ap_char(*p);
break;
case '?': /* Conditional (IF) */
if ((c = *++p) == '\0')
--p;
else
{
where = 0;
p = wherechar(p, &where);
if (!cond(c, where))
p = skipcond(p);
}
break;
case ':': /* ELSE */
p = skipcond(p);
break;
case '.': /* ENDIF */
break;
case '%': /* Percent escape */
if ((c = *++p) == '\0')
--p;
else
{
where = 0;
p = wherechar(p, &where);
protochar(c, where,
#if EDITOR
(proto == editproto));
#else
0);
#endif
}
break;
}
}
if (mp == message)
return (NULL);
if (maxwidth > 0 && mp >= message + maxwidth)
{
/*
* Message is too long.
* Return just the final portion of it.
*/
return (mp - maxwidth);
}
return (message);
}
/*
* Return a message suitable for printing by the "=" command.
*/
public char *
eq_message()
{
return (pr_expand(eqproto, 0));
}
/*
* Return a prompt.
* This depends on the prompt type (SHORT, MEDIUM, LONG), etc.
* If we can't come up with an appropriate prompt, return NULL
* and the caller will prompt with a colon.
*/
public char *
pr_string()
{
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));
}
less-382/search.c 0100444 0000764 0000764 00000067060 10010075213 012756 0 ustar markn markn /*
* Copyright (C) 1984-2002 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines to search a file for a pattern.
*/
#include "less.h"
#include "position.h"
#define MINPOS(a,b) (((a) < (b)) ? (a) : (b))
#define MAXPOS(a,b) (((a) > (b)) ? (a) : (b))
#if HAVE_POSIX_REGCOMP
#include
#ifdef REG_EXTENDED
#define REGCOMP_FLAG REG_EXTENDED
#else
#define REGCOMP_FLAG 0
#endif
#endif
#if HAVE_PCRE
#include
#endif
#if HAVE_RE_COMP
char *re_comp();
int re_exec();
#endif
#if HAVE_REGCMP
char *regcmp();
char *regex();
extern char *__loc1;
#endif
#if HAVE_V8_REGCOMP
#include "regexp.h"
#endif
static int match();
extern int sigs;
extern int how_search;
extern int caseless;
extern int linenums;
extern int sc_height;
extern int jump_sline;
extern int bs_mode;
extern int ctldisp;
extern int status_col;
extern POSITION start_attnpos;
extern POSITION end_attnpos;
#if HILITE_SEARCH
extern int hilite_search;
extern int screen_trashed;
extern int size_linebuf;
extern int squished;
extern int can_goto_line;
static int hide_hilite;
static POSITION prep_startpos;
static POSITION prep_endpos;
struct hilite
{
struct hilite *hl_next;
POSITION hl_startpos;
POSITION hl_endpos;
};
static struct hilite hilite_anchor = { NULL, NULL_POSITION, NULL_POSITION };
#define hl_first hl_next
#endif
/*
* These are the static variables that represent the "remembered"
* search pattern.
*/
#if HAVE_POSIX_REGCOMP
static regex_t *regpattern = NULL;
#endif
#if HAVE_PCRE
pcre *regpattern = NULL;
#endif
#if HAVE_RE_COMP
int re_pattern = 0;
#endif
#if HAVE_REGCMP
static char *cpattern = NULL;
#endif
#if HAVE_V8_REGCOMP
static struct regexp *regpattern = NULL;
#endif
static int is_caseless;
static int is_ucase_pattern;
static int last_search_type;
static char *last_pattern = NULL;
/*
* Convert text. Perform one or more of these transformations:
*/
#define CVT_TO_LC 01 /* Convert upper-case to lower-case */
#define CVT_BS 02 /* Do backspace processing */
#define CVT_CRLF 04 /* Remove CR after LF */
#define CVT_ANSI 010 /* Remove ANSI escape sequences */
static void
cvt_text(odst, osrc, ops)
char *odst;
char *osrc;
int ops;
{
register char *dst;
register char *src;
for (src = osrc, dst = odst; *src != '\0'; src++)
{
if ((ops & CVT_TO_LC) && isupper((unsigned char) *src))
/* Convert uppercase to lowercase. */
*dst++ = tolower((unsigned char) *src);
else if ((ops & CVT_BS) && *src == '\b' && dst > odst)
/* Delete BS and preceding char. */
dst--;
else if ((ops & CVT_ANSI) && *src == ESC)
{
/* Skip to end of ANSI escape sequence. */
while (src[1] != '\0')
if (is_ansi_end(*++src))
break;
} else
/* Just copy. */
*dst++ = *src;
}
if ((ops & CVT_CRLF) && dst > odst && dst[-1] == '\r')
dst--;
*dst = '\0';
}
/*
* Determine which conversions to perform.
*/
static int
get_cvt_ops()
{
int ops = 0;
if (is_caseless || bs_mode == BS_SPECIAL)
{
if (is_caseless)
ops |= CVT_TO_LC;
if (bs_mode == BS_SPECIAL)
ops |= CVT_BS;
if (bs_mode != BS_CONTROL)
ops |= CVT_CRLF;
} else if (bs_mode != BS_CONTROL)
{
ops |= CVT_CRLF;
}
if (ctldisp == OPT_ONPLUS)
ops |= CVT_ANSI;
return (ops);
}
/*
* Are there any uppercase letters in this string?
*/
static int
is_ucase(s)
char *s;
{
register char *p;
for (p = s; *p != '\0'; p++)
if (isupper((unsigned char) *p))
return (1);
return (0);
}
/*
* Is there a previous (remembered) search pattern?
*/
static int
prev_pattern()
{
if (last_search_type & SRCH_NO_REGEX)
return (last_pattern != NULL);
#if HAVE_POSIX_REGCOMP
return (regpattern != NULL);
#endif
#if HAVE_PCRE
return (regpattern != NULL);
#endif
#if HAVE_RE_COMP
return (re_pattern != 0);
#endif
#if HAVE_REGCMP
return (cpattern != NULL);
#endif
#if HAVE_V8_REGCOMP
return (regpattern != NULL);
#endif
#if NO_REGEX
return (last_pattern != NULL);
#endif
}
#if HILITE_SEARCH
/*
* Repaint the hilites currently displayed on the screen.
* Repaint each line which contains highlighted text.
* If on==0, force all hilites off.
*/
public void
repaint_hilite(on)
int on;
{
int slinenum;
POSITION pos;
POSITION epos;
int save_hide_hilite;
if (squished)
repaint();
save_hide_hilite = hide_hilite;
if (!on)
{
if (hide_hilite)
return;
hide_hilite = 1;
}
if (!can_goto_line)
{
repaint();
hide_hilite = save_hide_hilite;
return;
}
for (slinenum = TOP; slinenum < TOP + sc_height-1; slinenum++)
{
pos = position(slinenum);
if (pos == NULL_POSITION)
continue;
epos = position(slinenum+1);
/*
* If any character in the line is highlighted,
* repaint the line.
*/
if (is_hilited(pos, epos, 1))
{
(void) forw_line(pos);
goto_line(slinenum);
put_line();
}
}
hide_hilite = save_hide_hilite;
}
/*
* Clear the attn hilite.
*/
public void
clear_attn()
{
int slinenum;
POSITION old_start_attnpos;
POSITION old_end_attnpos;
POSITION pos;
POSITION epos;
if (start_attnpos == NULL_POSITION)
return;
old_start_attnpos = start_attnpos;
old_end_attnpos = end_attnpos;
start_attnpos = end_attnpos = NULL_POSITION;
if (!can_goto_line)
{
repaint();
return;
}
if (squished)
repaint();
for (slinenum = TOP; slinenum < TOP + sc_height-1; slinenum++)
{
pos = position(slinenum);
if (pos == NULL_POSITION)
continue;
epos = position(slinenum+1);
if (pos < old_end_attnpos &&
(epos == NULL_POSITION || epos > old_start_attnpos))
{
(void) forw_line(pos);
goto_line(slinenum);
put_line();
}
}
}
#endif
/*
* Hide search string highlighting.
*/
public void
undo_search()
{
if (!prev_pattern())
{
error("No previous regular expression", NULL_PARG);
return;
}
#if HILITE_SEARCH
hide_hilite = !hide_hilite;
repaint_hilite(1);
#endif
}
/*
* Compile a search pattern, for future use by match_pattern.
*/
static int
compile_pattern(pattern, search_type)
char *pattern;
int search_type;
{
if ((search_type & SRCH_NO_REGEX) == 0)
{
#if HAVE_POSIX_REGCOMP
regex_t *s = (regex_t *) ecalloc(1, sizeof(regex_t));
if (regcomp(s, pattern, REGCOMP_FLAG))
{
free(s);
error("Invalid pattern", NULL_PARG);
return (-1);
}
if (regpattern != NULL)
regfree(regpattern);
regpattern = s;
#endif
#if HAVE_PCRE
pcre *comp;
const char *errstring;
int erroffset;
PARG parg;
comp = pcre_compile(pattern, 0,
&errstring, &erroffset, NULL);
if (comp == NULL)
{
parg.p_string = (char *) errstring;
error("%s", &parg);
return (-1);
}
regpattern = comp;
#endif
#if HAVE_RE_COMP
PARG parg;
if ((parg.p_string = re_comp(pattern)) != NULL)
{
error("%s", &parg);
return (-1);
}
re_pattern = 1;
#endif
#if HAVE_REGCMP
char *s;
if ((s = regcmp(pattern, 0)) == NULL)
{
error("Invalid pattern", NULL_PARG);
return (-1);
}
if (cpattern != NULL)
free(cpattern);
cpattern = s;
#endif
#if HAVE_V8_REGCOMP
struct regexp *s;
if ((s = regcomp(pattern)) == NULL)
{
/*
* regcomp has already printed an error message
* via regerror().
*/
return (-1);
}
if (regpattern != NULL)
free(regpattern);
regpattern = s;
#endif
}
if (last_pattern != NULL)
free(last_pattern);
last_pattern = (char *) calloc(1, strlen(pattern)+1);
if (last_pattern != NULL)
strcpy(last_pattern, pattern);
last_search_type = search_type;
return (0);
}
/*
* Forget that we have a compiled pattern.
*/
static void
uncompile_pattern()
{
#if HAVE_POSIX_REGCOMP
if (regpattern != NULL)
regfree(regpattern);
regpattern = NULL;
#endif
#if HAVE_PCRE
if (regpattern != NULL)
pcre_free(regpattern);
regpattern = NULL;
#endif
#if HAVE_RE_COMP
re_pattern = 0;
#endif
#if HAVE_REGCMP
if (cpattern != NULL)
free(cpattern);
cpattern = NULL;
#endif
#if HAVE_V8_REGCOMP
if (regpattern != NULL)
free(regpattern);
regpattern = NULL;
#endif
last_pattern = NULL;
}
/*
* Perform a pattern match with the previously compiled pattern.
* Set sp and ep to the start and end of the matched string.
*/
static int
match_pattern(line, sp, ep, notbol)
char *line;
char **sp;
char **ep;
int notbol;
{
int matched;
if (last_search_type & SRCH_NO_REGEX)
return (match(last_pattern, line, sp, ep));
#if HAVE_POSIX_REGCOMP
{
regmatch_t rm;
int flags = (notbol) ? REG_NOTBOL : 0;
matched = !regexec(regpattern, line, 1, &rm, flags);
if (!matched)
return (0);
#ifndef __WATCOMC__
*sp = line + rm.rm_so;
*ep = line + rm.rm_eo;
#else
*sp = rm.rm_sp;
*ep = rm.rm_ep;
#endif
}
#endif
#if HAVE_PCRE
{
int flags = (notbol) ? PCRE_NOTBOL : 0;
int ovector[3];
matched = pcre_exec(regpattern, NULL, line, strlen(line),
0, flags, ovector, 3) >= 0;
if (!matched)
return (0);
*sp = line + ovector[0];
*ep = line + ovector[1];
}
#endif
#if HAVE_RE_COMP
matched = (re_exec(line) == 1);
/*
* re_exec doesn't seem to provide a way to get the matched string.
*/
*sp = *ep = NULL;
#endif
#if HAVE_REGCMP
*ep = regex(cpattern, line);
matched = (*ep != NULL);
if (!matched)
return (0);
*sp = __loc1;
#endif
#if HAVE_V8_REGCOMP
#if HAVE_REGEXEC2
matched = regexec2(regpattern, line, notbol);
#else
matched = regexec(regpattern, line);
#endif
if (!matched)
return (0);
*sp = regpattern->startp[0];
*ep = regpattern->endp[0];
#endif
#if NO_REGEX
matched = match(last_pattern, line, sp, ep);
#endif
return (matched);
}
#if HILITE_SEARCH
/*
* Clear the hilite list.
*/
public void
clr_hilite()
{
struct hilite *hl;
struct hilite *nexthl;
for (hl = hilite_anchor.hl_first; hl != NULL; hl = nexthl)
{
nexthl = hl->hl_next;
free((void*)hl);
}
hilite_anchor.hl_first = NULL;
prep_startpos = prep_endpos = NULL_POSITION;
}
/*
* Should any characters in a specified range be highlighted?
* If nohide is nonzero, don't consider hide_hilite.
*/
public int
is_hilited(pos, epos, nohide)
POSITION pos;
POSITION epos;
int nohide;
{
struct hilite *hl;
if (!status_col &&
start_attnpos != NULL_POSITION &&
pos < end_attnpos &&
(epos == NULL_POSITION || epos > start_attnpos))
/*
* The attn line overlaps this range.
*/
return (1);
if (hilite_search == 0)
/*
* Not doing highlighting.
*/
return (0);
if (!nohide && hide_hilite)
/*
* Highlighting is hidden.
*/
return (0);
/*
* Look at each highlight and see if any part of it falls in the range.
*/
for (hl = hilite_anchor.hl_first; hl != NULL; hl = hl->hl_next)
{
if (hl->hl_endpos > pos &&
(epos == NULL_POSITION || epos > hl->hl_startpos))
return (1);
}
return (0);
}
/*
* Add a new hilite to a hilite list.
*/
static void
add_hilite(anchor, hl)
struct hilite *anchor;
struct hilite *hl;
{
struct hilite *ihl;
/*
* Hilites are sorted in the list; find where new one belongs.
* Insert new one after ihl.
*/
for (ihl = anchor; ihl->hl_next != NULL; ihl = ihl->hl_next)
{
if (ihl->hl_next->hl_startpos > hl->hl_startpos)
break;
}
/*
* Truncate hilite so it doesn't overlap any existing ones
* above and below it.
*/
if (ihl != anchor)
hl->hl_startpos = MAXPOS(hl->hl_startpos, ihl->hl_endpos);
if (ihl->hl_next != NULL)
hl->hl_endpos = MINPOS(hl->hl_endpos, ihl->hl_next->hl_startpos);
if (hl->hl_startpos >= hl->hl_endpos)
{
/*
* Hilite was truncated out of existence.
*/
free(hl);
return;
}
hl->hl_next = ihl->hl_next;
ihl->hl_next = hl;
}
/*
* Adjust hl_startpos & hl_endpos to account for backspace processing.
*/
static void
adj_hilite(anchor, linepos, cvt_ops)
struct hilite *anchor;
POSITION linepos;
int cvt_ops;
{
char *line;
struct hilite *hl;
int checkstart;
POSITION opos;
POSITION npos;
/*
* The line was already scanned and hilites were added (in hilite_line).
* But it was assumed that each char position in the line
* correponds to one char position in the file.
* This may not be true if there are backspaces in the line.
* Get the raw line again. Look at each character.
*/
(void) forw_raw_line(linepos, &line);
opos = npos = linepos;
hl = anchor->hl_first;
checkstart = TRUE;
while (hl != NULL)
{
/*
* See if we need to adjust the current hl_startpos or
* hl_endpos. After adjusting startpos[i], move to endpos[i].
* After adjusting endpos[i], move to startpos[i+1].
* The hilite list must be sorted thus:
* startpos[0] < endpos[0] <= startpos[1] < endpos[1] <= etc.
*/
if (checkstart && hl->hl_startpos == opos)
{
hl->hl_startpos = npos;
checkstart = FALSE;
continue; /* {{ not really necessary }} */
} else if (!checkstart && hl->hl_endpos == opos)
{
hl->hl_endpos = npos;
checkstart = TRUE;
hl = hl->hl_next;
continue; /* {{ necessary }} */
}
if (*line == '\0')
break;
if (cvt_ops & CVT_ANSI)
{
while (line[0] == ESC)
{
/*
* Found an ESC. The file position moves
* forward past the entire ANSI escape sequence.
*/
line++;
npos++;
while (*line != '\0')
{
npos++;
if (is_ansi_end(*line++))
break;
}
}
}
opos++;
npos++;
line++;
if (cvt_ops & CVT_BS)
{
while (line[0] == '\b' && line[1] != '\0')
{
/*
* Found a backspace. The file position moves
* forward by 2 relative to the processed line
* which was searched in hilite_line.
*/
npos += 2;
line += 2;
}
}
}
}
/*
* Make a hilite for each string in a physical line which matches
* the current pattern.
* sp,ep delimit the first match already found.
*/
static void
hilite_line(linepos, line, sp, ep, cvt_ops)
POSITION linepos;
char *line;
char *sp;
char *ep;
int cvt_ops;
{
char *searchp;
struct hilite *hl;
struct hilite hilites;
if (sp == NULL || ep == NULL)
return;
/*
* sp and ep delimit the first match in the line.
* Mark the corresponding file positions, then
* look for further matches and mark them.
* {{ This technique, of calling match_pattern on subsequent
* substrings of the line, may mark more than is correct
* if the pattern starts with "^". This bug is fixed
* for those regex functions that accept a notbol parameter
* (currently POSIX and V8-with-regexec2). }}
*/
searchp = line;
/*
* Put the hilites into a temporary list until they're adjusted.
*/
hilites.hl_first = NULL;
do {
if (ep > sp)
{
/*
* Assume that each char position in the "line"
* buffer corresponds to one char position in the file.
* This is not quite true; we need to adjust later.
*/
hl = (struct hilite *) ecalloc(1, sizeof(struct hilite));
hl->hl_startpos = linepos + (sp-line);
hl->hl_endpos = linepos + (ep-line);
add_hilite(&hilites, hl);
}
/*
* If we matched more than zero characters,
* move to the first char after the string we matched.
* If we matched zero, just move to the next char.
*/
if (ep > searchp)
searchp = ep;
else if (*searchp != '\0')
searchp++;
else /* end of line */
break;
} while (match_pattern(searchp, &sp, &ep, 1));
/*
* If there were backspaces in the original line, they
* were removed, and hl_startpos/hl_endpos are not correct.
* {{ This is very ugly. }}
*/
adj_hilite(&hilites, linepos, cvt_ops);
/*
* Now put the hilites into the real list.
*/
while ((hl = hilites.hl_next) != NULL)
{
hilites.hl_next = hl->hl_next;
add_hilite(&hilite_anchor, hl);
}
}
#endif
/*
* Change the caseless-ness of searches.
* Updates the internal search state to reflect a change in the -i flag.
*/
public void
chg_caseless()
{
if (!is_ucase_pattern)
/*
* Pattern did not have uppercase.
* Just set the search caselessness to the global caselessness.
*/
is_caseless = caseless;
else
/*
* Pattern did have uppercase.
* Discard the pattern; we can't change search caselessness now.
*/
uncompile_pattern();
}
#if HILITE_SEARCH
/*
* Find matching text which is currently on screen and highlight it.
*/
static void
hilite_screen()
{
struct scrpos scrpos;
get_scrpos(&scrpos);
if (scrpos.pos == NULL_POSITION)
return;
prep_hilite(scrpos.pos, position(BOTTOM_PLUS_ONE), -1);
repaint_hilite(1);
}
/*
* Change highlighting parameters.
*/
public void
chg_hilite()
{
/*
* Erase any highlights currently on screen.
*/
clr_hilite();
hide_hilite = 0;
if (hilite_search == OPT_ONPLUS)
/*
* Display highlights.
*/
hilite_screen();
}
#endif
/*
* Figure out where to start a search.
*/
static POSITION
search_pos(search_type)
int search_type;
{
POSITION pos;
int linenum;
if (empty_screen())
{
/*
* Start at the beginning (or end) of the file.
* The empty_screen() case is mainly for
* command line initiated searches;
* for example, "+/xyz" on the command line.
* Also for multi-file (SRCH_PAST_EOF) searches.
*/
if (search_type & SRCH_FORW)
{
return (ch_zero());
} else
{
pos = ch_length();
if (pos == NULL_POSITION)
{
(void) ch_end_seek();
pos = ch_length();
}
return (pos);
}
}
if (how_search)
{
/*
* Search does not include current screen.
*/
if (search_type & SRCH_FORW)
linenum = BOTTOM_PLUS_ONE;
else
linenum = TOP;
pos = position(linenum);
} else
{
/*
* Search includes current screen.
* It starts at the jump target (if searching backwards),
* or at the jump target plus one (if forwards).
*/
linenum = adjsline(jump_sline);
pos = position(linenum);
if (search_type & SRCH_FORW)
{
pos = forw_raw_line(pos, (char **)NULL);
while (pos == NULL_POSITION)
{
if (++linenum >= sc_height)
break;
pos = position(linenum);
}
} else
{
while (pos == NULL_POSITION)
{
if (--linenum < 0)
break;
pos = position(linenum);
}
}
}
return (pos);
}
/*
* Search a subset of the file, specified by start/end position.
*/
static int
search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos)
POSITION pos;
POSITION endpos;
int search_type;
int matches;
int maxlines;
POSITION *plinepos;
POSITION *pendpos;
{
char *line;
LINENUM linenum;
char *sp, *ep;
int line_match;
int cvt_ops;
POSITION linepos, oldpos;
linenum = find_linenum(pos);
oldpos = pos;
for (;;)
{
/*
* Get lines until we find a matching one or until
* we hit end-of-file (or beginning-of-file if we're
* going backwards), or until we hit the end position.
*/
if (ABORT_SIGS())
{
/*
* A signal aborts the search.
*/
return (-1);
}
if ((endpos != NULL_POSITION && pos >= endpos) || maxlines == 0)
{
/*
* Reached end position without a match.
*/
if (pendpos != NULL)
*pendpos = pos;
return (matches);
}
if (maxlines > 0)
maxlines--;
if (search_type & SRCH_FORW)
{
/*
* Read the next line, and save the
* starting position of that line in linepos.
*/
linepos = pos;
pos = forw_raw_line(pos, &line);
if (linenum != 0)
linenum++;
} else
{
/*
* Read the previous line and save the
* starting position of that line in linepos.
*/
pos = back_raw_line(pos, &line);
linepos = pos;
if (linenum != 0)
linenum--;
}
if (pos == NULL_POSITION)
{
/*
* Reached EOF/BOF without a match.
*/
if (pendpos != NULL)
*pendpos = oldpos;
return (matches);
}
/*
* If we're using line numbers, we might as well
* remember the information we have now (the position
* and line number of the current line).
* Don't do it for every line because it slows down
* the search. Remember the line number only if
* we're "far" from the last place we remembered it.
*/
if (linenums && abs((int)(pos - oldpos)) > 1024)
add_lnum(linenum, pos);
oldpos = pos;
/*
* If it's a caseless search, convert the line to lowercase.
* If we're doing backspace processing, delete backspaces.
*/
cvt_ops = get_cvt_ops();
cvt_text(line, line, cvt_ops);
/*
* Test the next line to see if we have a match.
* We are successful if we either want a match and got one,
* or if we want a non-match and got one.
*/
line_match = match_pattern(line, &sp, &ep, 0);
line_match = (!(search_type & SRCH_NO_MATCH) && line_match) ||
((search_type & SRCH_NO_MATCH) && !line_match);
if (!line_match)
continue;
/*
* Got a match.
*/
if (search_type & SRCH_FIND_ALL)
{
#if HILITE_SEARCH
/*
* We are supposed to find all matches in the range.
* Just add the matches in this line to the
* hilite list and keep searching.
*/
if (line_match)
hilite_line(linepos, line, sp, ep, cvt_ops);
#endif
} else if (--matches <= 0)
{
/*
* Found the one match we're looking for.
* Return it.
*/
#if HILITE_SEARCH
if (hilite_search == 1)
{
/*
* Clear the hilite list and add only
* the matches in this one line.
*/
clr_hilite();
if (line_match)
hilite_line(linepos, line, sp, ep, cvt_ops);
}
#endif
if (plinepos != NULL)
*plinepos = linepos;
return (0);
}
}
}
/*
* Search for the n-th occurrence of a specified pattern,
* either forward or backward.
* Return the number of matches not yet found in this file
* (that is, n minus the number of matches found).
* Return -1 if the search should be aborted.
* Caller may continue the search in another file
* if less than n matches are found in this file.
*/
public int
search(search_type, pattern, n)
int search_type;
char *pattern;
int n;
{
POSITION pos;
int ucase;
if (pattern == NULL || *pattern == '\0')
{
/*
* A null pattern means use the previously compiled pattern.
*/
if (!prev_pattern())
{
error("No previous regular expression", NULL_PARG);
return (-1);
}
if ((search_type & SRCH_NO_REGEX) !=
(last_search_type & SRCH_NO_REGEX))
{
error("Please re-enter search pattern", NULL_PARG);
return -1;
}
#if HILITE_SEARCH
if (hilite_search == OPT_ON)
{
/*
* Erase the highlights currently on screen.
* If the search fails, we'll redisplay them later.
*/
repaint_hilite(0);
}
if (hilite_search == OPT_ONPLUS && hide_hilite)
{
/*
* Highlight any matches currently on screen,
* before we actually start the search.
*/
hide_hilite = 0;
hilite_screen();
}
hide_hilite = 0;
#endif
} else
{
/*
* Compile the pattern.
*/
ucase = is_ucase(pattern);
if (caseless == OPT_ONPLUS)
cvt_text(pattern, pattern, CVT_TO_LC);
if (compile_pattern(pattern, search_type) < 0)
return (-1);
/*
* Ignore case if -I is set OR
* -i is set AND the pattern is all lowercase.
*/
is_ucase_pattern = ucase;
if (is_ucase_pattern && caseless != OPT_ONPLUS)
is_caseless = 0;
else
is_caseless = caseless;
#if HILITE_SEARCH
if (hilite_search)
{
/*
* Erase the highlights currently on screen.
* Also permanently delete them from the hilite list.
*/
repaint_hilite(0);
hide_hilite = 0;
clr_hilite();
}
if (hilite_search == OPT_ONPLUS)
{
/*
* Highlight any matches currently on screen,
* before we actually start the search.
*/
hilite_screen();
}
#endif
}
/*
* Figure out where to start the search.
*/
pos = search_pos(search_type);
if (pos == NULL_POSITION)
{
/*
* Can't find anyplace to start searching from.
*/
if (search_type & SRCH_PAST_EOF)
return (n);
/* repaint(); -- why was this here? */
error("Nothing to search", NULL_PARG);
return (-1);
}
n = search_range(pos, NULL_POSITION, search_type, n, -1,
&pos, (POSITION*)NULL);
if (n != 0)
{
/*
* Search was unsuccessful.
*/
#if HILITE_SEARCH
if (hilite_search == OPT_ON && n > 0)
/*
* Redisplay old hilites.
*/
repaint_hilite(1);
#endif
return (n);
}
if (!(search_type & SRCH_NO_MOVE))
{
/*
* Go to the matching line.
*/
jump_loc(pos, jump_sline);
}
#if HILITE_SEARCH
if (hilite_search == OPT_ON)
/*
* Display new hilites in the matching line.
*/
repaint_hilite(1);
#endif
return (0);
}
#if HILITE_SEARCH
/*
* Prepare hilites in a given range of the file.
*
* The pair (prep_startpos,prep_endpos) delimits a contiguous region
* of the file that has been "prepared"; that is, scanned for matches for
* the current search pattern, and hilites have been created for such matches.
* If prep_startpos == NULL_POSITION, the prep region is empty.
* If prep_endpos == NULL_POSITION, the prep region extends to EOF.
* prep_hilite asks that the range (spos,epos) be covered by the prep region.
*/
public void
prep_hilite(spos, epos, maxlines)
POSITION spos;
POSITION epos;
int maxlines;
{
POSITION nprep_startpos = prep_startpos;
POSITION nprep_endpos = prep_endpos;
POSITION new_epos;
POSITION max_epos;
int result;
int i;
/*
* Search beyond where we're asked to search, so the prep region covers
* more than we need. Do one big search instead of a bunch of small ones.
*/
#define SEARCH_MORE (3*size_linebuf)
if (!prev_pattern())
return;
/*
* If we're limited to a max number of lines, figure out the
* file position we should stop at.
*/
if (maxlines < 0)
max_epos = NULL_POSITION;
else
{
max_epos = spos;
for (i = 0; i < maxlines; i++)
max_epos = forw_raw_line(max_epos, (char **)NULL);
}
/*
* Find two ranges:
* The range that we need to search (spos,epos); and the range that
* the "prep" region will then cover (nprep_startpos,nprep_endpos).
*/
if (prep_startpos == NULL_POSITION ||
(epos != NULL_POSITION && epos < prep_startpos) ||
spos > prep_endpos)
{
/*
* New range is not contiguous with old prep region.
* Discard the old prep region and start a new one.
*/
clr_hilite();
if (epos != NULL_POSITION)
epos += SEARCH_MORE;
nprep_startpos = spos;
} else
{
/*
* New range partially or completely overlaps old prep region.
*/
if (epos == NULL_POSITION)
{
/*
* New range goes to end of file.
*/
;
} else if (epos > prep_endpos)
{
/*
* New range ends after old prep region.
* Extend prep region to end at end of new range.
*/
epos += SEARCH_MORE;
} else /* (epos <= prep_endpos) */
{
/*
* New range ends within old prep region.
* Truncate search to end at start of old prep region.
*/
epos = prep_startpos;
}
if (spos < prep_startpos)
{
/*
* New range starts before old prep region.
* Extend old prep region backwards to start at
* start of new range.
*/
if (spos < SEARCH_MORE)
spos = 0;
else
spos -= SEARCH_MORE;
nprep_startpos = spos;
} else /* (spos >= prep_startpos) */
{
/*
* New range starts within or after old prep region.
* Trim search to start at end of old prep region.
*/
spos = prep_endpos;
}
}
if (epos != NULL_POSITION && max_epos != NULL_POSITION &&
epos > max_epos)
/*
* Don't go past the max position we're allowed.
*/
epos = max_epos;
if (epos == NULL_POSITION || epos > spos)
{
result = search_range(spos, epos, SRCH_FORW|SRCH_FIND_ALL, 0,
maxlines, (POSITION*)NULL, &new_epos);
if (result < 0)
return;
if (prep_endpos == NULL_POSITION || new_epos > prep_endpos)
nprep_endpos = new_epos;
}
prep_startpos = nprep_startpos;
prep_endpos = nprep_endpos;
}
#endif
/*
* Simple pattern matching function.
* It supports no metacharacters like *, etc.
*/
static int
match(pattern, buf, pfound, pend)
char *pattern, *buf;
char **pfound, **pend;
{
register char *pp, *lp;
for ( ; *buf != '\0'; buf++)
{
for (pp = pattern, lp = buf; *pp == *lp; pp++, lp++)
if (*pp == '\0' || *lp == '\0')
break;
if (*pp == '\0')
{
if (pfound != NULL)
*pfound = buf;
if (pend != NULL)
*pend = lp;
return (1);
}
}
return (0);
}
#if HAVE_V8_REGCOMP
/*
* This function is called by the V8 regcomp to report
* errors in regular expressions.
*/
void
regerror(s)
char *s;
{
PARG parg;
parg.p_string = s;
error("%s", &parg);
}
#endif
less-382/signal.c 0100444 0000764 0000764 00000011177 10010075213 012764 0 ustar markn markn /*
* Copyright (C) 1984-2002 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines dealing with signals.
*
* A signal usually merely causes a bit to be set in the "signals" word.
* At some convenient time, the mainline code checks to see if any
* signals need processing by calling psignal().
* If we happen to be reading from a file [in iread()] at the time
* the signal is received, we call intread to interrupt the iread.
*/
#include "less.h"
#include
/*
* "sigs" contains bits indicating signals which need to be processed.
*/
public int sigs;
extern int sc_width, sc_height;
extern int screen_trashed;
extern int lnloop;
extern int linenums;
extern int wscroll;
extern int reading;
/*
* Interrupt signal handler.
*/
/* ARGSUSED*/
static RETSIGTYPE
u_interrupt(type)
int type;
{
#if OS2
LSIGNAL(SIGINT, SIG_ACK);
#endif
LSIGNAL(SIGINT, u_interrupt);
sigs |= S_INTERRUPT;
#if MSDOS_COMPILER==DJGPPC
/*
* If a keyboard has been hit, it must be Ctrl-C
* (as opposed to Ctrl-Break), so consume it.
* (Otherwise, Less will beep when it sees Ctrl-C from keyboard.)
*/
if (kbhit())
getkey();
#endif
if (reading)
intread();
}
#ifdef SIGTSTP
/*
* "Stop" (^Z) signal handler.
*/
/* ARGSUSED*/
static RETSIGTYPE
stop(type)
int type;
{
LSIGNAL(SIGTSTP, stop);
sigs |= S_STOP;
if (reading)
intread();
}
#endif
#ifdef SIGWINCH
/*
* "Window" change handler
*/
/* ARGSUSED*/
public RETSIGTYPE
winch(type)
int type;
{
LSIGNAL(SIGWINCH, winch);
sigs |= S_WINCH;
if (reading)
intread();
}
#else
#ifdef SIGWIND
/*
* "Window" change handler
*/
/* ARGSUSED*/
public RETSIGTYPE
winch(type)
int type;
{
LSIGNAL(SIGWIND, winch);
sigs |= S_WINCH;
if (reading)
intread();
}
#endif
#endif
#if MSDOS_COMPILER==WIN32C
/*
* Handle CTRL-C and CTRL-BREAK keys.
*/
#include "windows.h"
static BOOL WINAPI
wbreak_handler(dwCtrlType)
DWORD dwCtrlType;
{
switch (dwCtrlType)
{
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
sigs |= S_INTERRUPT;
return (TRUE);
default:
break;
}
return (FALSE);
}
#endif
/*
* Set up the signal handlers.
*/
public void
init_signals(on)
int on;
{
if (on)
{
/*
* Set signal handlers.
*/
(void) LSIGNAL(SIGINT, u_interrupt);
#if MSDOS_COMPILER==WIN32C
SetConsoleCtrlHandler(wbreak_handler, TRUE);
#endif
#ifdef SIGTSTP
(void) LSIGNAL(SIGTSTP, stop);
#endif
#ifdef SIGWINCH
(void) LSIGNAL(SIGWINCH, winch);
#else
#ifdef SIGWIND
(void) LSIGNAL(SIGWIND, winch);
#endif
#ifdef SIGQUIT
(void) LSIGNAL(SIGQUIT, SIG_IGN);
#endif
#endif
} else
{
/*
* Restore signals to defaults.
*/
(void) LSIGNAL(SIGINT, SIG_DFL);
#if MSDOS_COMPILER==WIN32C
SetConsoleCtrlHandler(wbreak_handler, FALSE);
#endif
#ifdef SIGTSTP
(void) LSIGNAL(SIGTSTP, SIG_DFL);
#endif
#ifdef SIGWINCH
(void) LSIGNAL(SIGWINCH, SIG_IGN);
#endif
#ifdef SIGWIND
(void) LSIGNAL(SIGWIND, SIG_IGN);
#endif
#ifdef SIGQUIT
(void) LSIGNAL(SIGQUIT, SIG_DFL);
#endif
}
}
/*
* Process any signals we have received.
* A received signal cause a bit to be set in "sigs".
*/
public void
psignals()
{
register int tsignals;
if ((tsignals = sigs) == 0)
return;
sigs = 0;
#ifdef SIGTSTP
if (tsignals & S_STOP)
{
/*
* Clean up the terminal.
*/
#ifdef SIGTTOU
LSIGNAL(SIGTTOU, SIG_IGN);
#endif
clear_bot();
deinit();
flush();
raw_mode(0);
#ifdef SIGTTOU
LSIGNAL(SIGTTOU, SIG_DFL);
#endif
LSIGNAL(SIGTSTP, SIG_DFL);
kill(getpid(), SIGTSTP);
/*
* ... Bye bye. ...
* Hopefully we'll be back later and resume here...
* Reset the terminal and arrange to repaint the
* screen when we get back to the main command loop.
*/
LSIGNAL(SIGTSTP, stop);
raw_mode(1);
init();
screen_trashed = 1;
tsignals |= S_WINCH;
}
#endif
#ifdef S_WINCH
if (tsignals & S_WINCH)
{
int old_width, old_height;
/*
* Re-execute scrsize() to read the new window size.
*/
old_width = sc_width;
old_height = sc_height;
get_term();
if (sc_width != old_width || sc_height != old_height)
{
wscroll = (sc_height + 1) / 2;
screen_trashed = 1;
}
}
#endif
if (tsignals & S_INTERRUPT)
{
bell();
/*
* {{ You may wish to replace the bell() with
* error("Interrupt", NULL_PARG); }}
*/
/*
* If we were interrupted while in the "calculating
* line numbers" loop, turn off line numbers.
*/
if (lnloop)
{
lnloop = 0;
if (linenums == 2)
screen_trashed = 1;
linenums = 0;
error("Line numbers turned off", NULL_PARG);
}
}
}
less-382/tags.c 0100444 0000764 0000764 00000036050 10010075213 012442 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
#include "less.h"
#define WHITESP(c) ((c)==' ' || (c)=='\t')
#if TAGS
public char *tags = "tags";
static int total;
static int curseq;
extern int linenums;
extern int sigs;
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 */
LINENUM 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;
LINENUM 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 "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 = (char *) NULL;
while (n-- > 0)
tagfile = nextgtag();
return tagfile;
}
/*
* Go to the previous tag.
*/
public char *
prevtag(n)
int n;
{
char *tagfile = (char *) NULL;
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;
register FILE *f;
register int taglen;
LINENUM taglinenum;
char *tagfile;
char *tagpattern;
int tagendline;
int search_char;
int err;
char tline[TAGLINE_SIZE];
struct tag *tp;
p = shell_unquote(tags);
f = fopen(p, "r");
free(p);
if (f == NULL)
return TAG_NOFILE;
cleantags();
total = 0;
taglen = strlen(tag);
/*
* Search the tags file for the desired 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;
/*
* Found it.
* The line contains the tag, the filename and the
* location in the file, separated by white space.
* The location is either a decimal line number,
* or a search pattern surrounded by a pair of delimiters.
* Parse the line and extract these parts.
*/
tagpattern = NULL;
/*
* Skip over the whitespace after the tag name.
*/
p = skipsp(tline+taglen);
if (*p == '\0')
/* File name is missing! */
continue;
/*
* Save the file name.
* Skip over the whitespace after the file name.
*/
tagfile = p;
while (!WHITESP(*p) && *p != '\0')
p++;
*p++ = '\0';
p = skipsp(p);
if (*p == '\0')
/* Pattern is missing! */
continue;
/*
* First see if it is a line number.
*/
tagendline = 0;
taglinenum = getnum(&p, 0, &err);
if (err)
{
/*
* No, it must be a pattern.
* Delete the initial "^" (if present) and
* the final "$" from the pattern.
* Delete any backslash in the pattern.
*/
taglinenum = 0;
search_char = *p++;
if (*p == '^')
p++;
tagpattern = p;
while (*p != search_char && *p != '\0')
{
if (*p == '\\')
p++;
p++;
}
tagendline = (p[-1] == '$');
if (tagendline)
p--;
*p = '\0';
}
tp = maketagent(tag, tagfile, taglinenum, tagpattern, tagendline);
TAG_INS(tp);
total++;
}
fclose(f);
if (total == 0)
return TAG_NOTAG;
curtag = taglist.tl_first;
curseq = 1;
return TAG_FOUND;
}
/*
* Edit current tagged file.
*/
public int
edit_tagfile()
{
if (curtag == NULL)
return (1);
return (edit(curtag->tag_file));
}
/*
* Search for a tag.
* This is a stripped-down version of search().
* We don't use search() for several reasons:
* - We don't want to blow away any search string we may have saved.
* - The various regular-expression functions (from different systems:
* regcmp vs. re_comp) behave differently in the presence of
* parentheses (which are almost always found in a tag).
*/
static POSITION
ctagsearch()
{
POSITION pos, linepos;
LINENUM linenum;
int len;
char *line;
pos = ch_zero();
linenum = find_linenum(pos);
for (;;)
{
/*
* Get lines until we find a matching one or
* until we hit end-of-file.
*/
if (ABORT_SIGS())
return (NULL_POSITION);
/*
* Read the next line, and save the
* starting position of that line in linepos.
*/
linepos = pos;
pos = forw_raw_line(pos, &line);
if (linenum != 0)
linenum++;
if (pos == NULL_POSITION)
{
/*
* We hit EOF without a match.
*/
error("Tag not found", NULL_PARG);
return (NULL_POSITION);
}
/*
* If we're using line numbers, we might as well
* remember the information we have now (the position
* and line number of the current line).
*/
if (linenums)
add_lnum(linenum, pos);
/*
* Test the line to see if we have a match.
* Use strncmp because the pattern may be
* truncated (in the tags file) if it is too long.
* If tagendline is set, make sure we match all
* the way to end of line (no extra chars after the match).
*/
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;
}
}
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 *qtag;
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). */
qtag = shell_quote(tag);
if (qtag == NULL)
qtag = tag;
sprintf(command, "%s -x%s %s", cmd, flag, qtag);
if (qtag != tag)
free(qtag);
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, (LINENUM) 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]
*
* +------------------------------------------------
* |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
*
* [extended format]
*
* +----------------------------------------------------------
* |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
*
* 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
less-382/ttyin.c 0100444 0000764 0000764 00000005556 10010075213 012662 0 ustar markn markn /*
* Copyright (C) 1984-2002 Mark Nudelman
*
* You may distribute under the terms of either the GNU General Public
* License or the Less License, as specified in the README file.
*
* For more information about less, or for information on how to
* contact the author, see the README file.
*/
/*
* Routines dealing with getting input from the keyboard (i.e. from the user).
*/
#include "less.h"
#if OS2
#include "cmd.h"
#include "pckeys.h"
#endif
#if MSDOS_COMPILER==WIN32C
#include "windows.h"
extern char WIN32getch();
static DWORD console_mode;
#endif
public int tty;
extern int sigs;
/*
* Open keyboard for input.
*/
public void
open_getchr()
{
#if MSDOS_COMPILER==WIN32C
/* Need this to let child processes inherit our console handle */
SECURITY_ATTRIBUTES sa;
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
tty = (int) CreateFile("CONIN$", GENERIC_READ,
FILE_SHARE_READ, &sa,
OPEN_EXISTING, 0L, NULL);
GetConsoleMode((HANDLE)tty, &console_mode);
/* Make sure we get Ctrl+C events. */
SetConsoleMode((HANDLE)tty, ENABLE_PROCESSED_INPUT);
#else
#if MSDOS_COMPILER
extern int fd0;
/*
* Open a new handle to CON: in binary mode
* for unbuffered keyboard read.
*/
fd0 = dup(0);
close(0);
tty = open("CON", OPEN_READ);
#if MSDOS_COMPILER==DJGPPC
/*
* Setting stdin to binary causes Ctrl-C to not
* raise SIGINT. We must undo that side-effect.
*/
(void) __djgpp_set_ctrl_c(1);
#endif
#else
/*
* Try /dev/tty.
* If that doesn't work, use file descriptor 2,
* 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
#endif
}
/*
* Close the keyboard.
*/
public void
close_getchr()
{
#if MSDOS_COMPILER==WIN32C
SetConsoleMode((HANDLE)tty, console_mode);
CloseHandle((HANDLE)tty);
#endif
}
/*
* Get a character from the keyboard.
*/
public int
getchr()
{
char c;
int result;
do
{
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
/*
* In raw read, we don't see ^C so look here for it.
*/
flush();
#if MSDOS_COMPILER==WIN32C
if (ABORT_SIGS())
return (READ_INTR);
c = WIN32getch(tty);
#else
c = getch();
#endif
result = 1;
if (c == '\003')
return (READ_INTR);
#else
result = iread(tty, &c, sizeof(char));
if (result == READ_INTR)
return (READ_INTR);
if (result < 0)
{
/*
* Don't call error() here,
* because error calls getchr!
*/
quit(QUIT_ERROR);
}
#endif
/*
* Various parts of the program cannot handle
* an input character of '\0'.
* If a '\0' was actually typed, convert it to '\340' here.
*/
if (c == '\0')
c = '\340';
} while (result != 1);
return (c & 0377);
}
less-382/version.c 0100444 0000764 0000764 00000072053 10010075237 013202 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
----------------------- CHANGE HISTORY --------------------------
1/29/84 Allowed use on standard input
2/1/84 Added E, N, P commands
4/17/84 Added '=' command, 'stop' signal handling
4/20/84 Added line folding
v2 4/27/84 Fixed '=' command to use BOTTOM_PLUS_ONE,
instead of TOP, added 'p' & 'v' commands
v3 5/3/84 Added -m and -t options, '-' command
v4 5/3/84 Added LESS environment variable
v5 5/3/84 New comments, fixed '-' command slightly
v6 5/15/84 Added -Q, visual bell
v7 5/24/84 Fixed jump_back(n) bug: n should count real
lines, not folded lines. Also allow number on G command.
v8 5/30/84 Re-do -q and -Q commands
v9 9/25/84 Added "+" argument
v10 10/10/84 Fixed bug in -b argument processing
v11 10/18/84 Made error() ring bell if \n not entered.
-----------------------------------------------------------------
v12 2/13/85 Reorganized signal handling and made portable to 4.2bsd.
v13 2/16/85 Reword error message for '-' command.
v14 2/22/85 Added -bf and -bp variants of -b.
v15 2/25/85 Miscellaneous changes.
v16 3/13/85 Added -u flag for backspace processing.
v17 4/13/85 Added j and k commands, changed -t default.
v18 4/20/85 Rewrote signal handling code.
v19 5/2/85 Got rid of "verbose" eq_message().
Made search() scroll in some cases.
v20 5/21/85 Fixed screen.c ioctls for System V.
v21 5/23/85 Fixed some first_cmd bugs.
v22 5/24/85 Added support for no RECOMP nor REGCMP.
v23 5/25/85 Miscellanous changes and prettying up.
Posted to USENET.
-----------------------------------------------------------------
v24 6/3/85 Added ti,te terminal init & de-init.
(Thanks to Mike Kersenbrock)
v25 6/8/85 Added -U flag, standout mode underlining.
v26 6/9/85 Added -M flag.
Use underline termcap (us) if it exists.
v27 6/15/85 Renamed some variables to make unique in
6 chars. Minor fix to -m.
v28 6/28/85 Fixed right margin bug.
v29 6/28/85 Incorporated M.Rose's changes to signal.c
v30 6/29/85 Fixed stupid bug in argument processing.
v31 7/15/85 Added -p flag, changed repaint algorithm.
Added kludge for magic cookie terminals.
v32 7/16/85 Added cat_file if output not a tty.
v33 7/23/85 Added -e flag and EDITOR.
v34 7/26/85 Added -s flag.
v35 7/27/85 Rewrote option handling; added option.c.
v36 7/29/85 Fixed -e flag to work if not last file.
v37 8/10/85 Added -x flag.
v38 8/19/85 Changed prompting; created prompt.c.
v39 8/24/85 (Not -p) does not initially clear screen.
v40 8/26/85 Added "skipping" indicator in forw().
Posted to USENET.
-----------------------------------------------------------------
v41 9/17/85 ONLY_RETURN, control char commands,
faster search, other minor fixes.
v42 9/25/85 Added ++ command line syntax;
ch_fsize for pipes.
v43 10/15/85 Added -h flag, changed prim.c algorithms.
v44 10/16/85 Made END print in all cases of eof;
ignore SIGTTOU after receiv ing SIGTSTP.
v45 10/16/85 Never print backspaces unless -u.
v46 10/24/85 Backwards scroll in jump_loc.
v47 10/30/85 Fixed bug in edit(): *first_cmd==0
v48 11/16/85 Use TIOCSETN instead of TIOCSETP.
Added marks (m and ' commands).
Posted to USENET.
-----------------------------------------------------------------
v49 1/9/86 Fixed bug: signal didn't clear mcc.
v50 1/15/86 Added ' (quote) to gomark.
v51 1/16/86 Added + cmd, fixed problem if first_cmd
fails, made g cmd sort of "work" on pipes
ev en if bof is no longer buffered.
v52 1/17/86 Made short files work better.
v53 1/20/86 Added -P option.
v54 1/20/86 Changed help to use HELPFILE.
v55 1/23/86 Messages work better if not tty output.
v56 1/24/86 Added -l option.
v57 1/31/86 Fixed -l to get confirmation before
ov erwriting an existing file.
v58 8/28/86 Added filename globbing.
v59 9/15/86 Fixed some bugs with very long filenames.
v60 9/26/86 Incorporated changes from Leith (Casey)
Leedom for boldface and -z option.
v61 9/26/86 Got rid of annoying repaints after ! cmd.
Posted to USENET.
-----------------------------------------------------------------
v62 12/23/86 Added is_directory(); change -z default to
-1 instead of 24; cat-and-exit if -e and
file is less than a screenful.
v63 1/8/87 Fixed bug in cat-and-exit if > 1 file.
v64 1/12/87 Changed puts/putstr, putc/putchr,
getc/getchr to av oid name conflict with
stdio functions.
v65 1/26/87 Allowed '-' command to change NUMBER
v alued options (thanks to Gary Puckering)
v66 2/13/87 Fixed bug: prepaint should use force=1.
v67 2/24/87 Added !! and % expansion to ! command.
v68 2/25/87 Added SIGWINCH and TIOCGWINSZ support;
changed is_directory to bad_file.
(thanks to J. Robert Ward)
v69 2/25/87 Added SIGWIND and WIOCGETD (for Unix PC).
v70 3/13/87 Changed help cmd from 'h' to 'H'; better
error msgs in bad_file, errno_message.
v71 5/11/87 Changed -p to -c, made triple -c/-C
for clear-eol like more's -c.
v72 6/26/87 Added -E, -L, use $SHELL in lsystem().
(thanks to Stev e Spearman)
v73 6/26/87 Allow Examine "#" for previous file.
Posted to USENET 8/25/87.
-----------------------------------------------------------------
v74 9/18/87 Fix conflict in EOF symbol with stdio.h,
Make os.c more portable to BSD.
v75 9/23/87 Fix problems in get_term (thanks to
Paul Eggert); new backwards scrolling in
jump_loc (thanks to Marion Hakanson).
v76 9/23/87 Added -i flag; allow single "!" to
inv oke a shell (thanks to Franco Barber).
v77 9/24/87 Added -n flag and line number support.
v78 9/25/87 Fixed problem with prompts longer than
the screen width.
v79 9/29/87 Added the _ command.
v80 10/6/87 Allow signal to break out of linenum scan.
v81 10/6/87 Allow -b to be changed from within less.
v82 10/7/87 Add cmd_decode to use a table for key
binding (thanks to Dav id Nason).
v83 10/9/87 Allow .less file for user-defined keys.
v84 10/11/87 Fix -e/-E problems (thanks to Felix Lee).
v85 10/15/87 Search now keeps track of line numbers.
v86 10/20/87 Added -B option and autobuf; fixed
"pipe error" bug.
v87 3/1/88 Fix bug re BSD signals while reading file.
v88 3/12/88 Use new format for -P option (thanks to
der Mouse), allow "+-c" without message,
fix bug re BSD hangup.
v89 3/18/88 Turn off line numbers if linenum scan
is interrupted.
v90 3/30/88 Allow -P from within less.
v91 3/30/88 Added tags file support (new -t option)
(thanks to Brian Campbell).
v92 4/4/88 Added -+option syntax.
v93 4/11/88 Add support for slow input (thanks to
Joe Orost & apologies for taking almost
3 years to get this in!)
v94 4/11/88 Redo reading/signal stuff.
v95 4/20/88 Repaint screen better after signal.
v96 4/21/88 Add /! and ?! commands.
v97 5/17/88 Allow -l/-L from within less.
Eliminate some static arrays (use calloc).
Posted to USENET.
-----------------------------------------------------------------
v98 10/14/88 Fix incorrect calloc call; uninitialized
var in exec_mca; core dump on unknown TERM.
Make v cmd work if past last line of file.
Fix some signal bugs.
v99 10/29/88 Allow space between -X and string,
when X is a string-valued option.
v100 1/5/89 Fix globbing bug when $SHELL not set;
allow spaces after -t command.
v101 1/6/89 Fix problem with long (truncated) lines
in tags file (thanks to Neil Dixon).
v102 1/6/89 Fix bug with E# when no prev file;
allow spaces after -l command.
v103 3/14/89 Add -N, -f and -? options. Add z and w
commands. Add %L for prompt strings.
v104 3/16/89 Added EDITPROTO.
v105 3/20/89 Fix bug in find_linenum which cached
incorrectly on long lines.
v106 3/31/89 Added -k option and multiple lesskey
files.
v107 4/27/89 Add 8-bit char support and -g option.
Split option code into 3 files.
v108 5/5/89 Allocate position table dynamically
(thanks to Paul Eggert); change % command
from "percent" to vi-style brace finder.
v109 5/10/89 Added ESC-% command, split prim.c.
v110 5/24/89 Fixed bug in + option; fixed repaint bug
under Sun windows (thanks to Paul Eggert).
v111 5/25/89 Generalized # and % expansion; use
calloc for some error messages.
v112 5/30/89 Get rid of ESC-%, add {}()[] commands.
v113 5/31/89 Optimize lseeks (thanks to Paul Eggert).
v114 7/25/89 Added ESC-/ and ESC-/! commands.
v115 7/26/89 Added ESC-n command.
v116 7/31/89 Added find_pos to optimize g command.
v117 8/1/89 Change -f option to -r.
v118 8/2/89 Save positions for all previous files,
not just the immediately previous one.
v119 8/7/89 Save marks across file boundaries.
Add file handle stuff.
v120 8/11/89 Add :ta command.
v121 8/16/89 Add -f option.
v122 8/30/89 Fix performance with many buffers.
v123 8/31/89 Verbose prompts for string options.
Posted beta to USENET.
-----------------------------------------------------------------
v124 9/18/89 Reorganize search commands,
N = rev, ESC-n = span, add ESC-N.
v125 9/18/89 Fix tab bug (thanks to Alex Liu).
Fix EOF bug when both -w and -c.
v126 10/25/89 Add -j option.
v127 10/27/89 Fix problems with blank lines before BOF.
v128 10/27/89 Add %bj, etc. to prompt strings.
v129 11/3/89 Add -+,-- commands; add set-option and
unset-option to lesskey.
v130 11/6/89 Generalize A_EXTRA to string, remove
set-option, unset-option from lesskey.
v131 11/7/89 Changed name of EDITPROTO to LESSEDIT.
v132 11/8/89 Allow editing of command prefix.
v133 11/16/89 Add -y option (thanks to Jeff Sullivan).
v134 12/1/89 Glob filenames in the -l command.
v135 12/5/89 Combined {}()[] commands into one, and
added ESC-^F and ESC-^B commands.
v136 1/20/90 Added -S, -R flags. Added | command.
Added warning for binary files. (thanks
to Richard Brittain and J. Sullivan).
v137 1/21/90 Rewrote horrible pappend code.
Added * notation for hi-bit chars.
v138 1/24/90 Fix magic cookie terminal handling.
Get rid of "cleanup" loop in ch_get.
v139 1/27/90 Added MSDOS support. (many thanks
to Richard Brittain).
v140 2/7/90 Editing a new file adds it to the
command line list.
v141 2/8/90 Add edit_list for editing >1 file.
v142 2/10/90 Add :x command.
v143 2/11/90 Add * and @ modifies to search cmds.
Change ESC-/ cmd from /@* to / *.
v144 3/1/90 Messed around with ch_zero;
no real change.
v145 3/2/90 Added -R and -v/-V for MSDOS;
renamed FILENAME to avoid conflict.
v146 3/5/90 Pull cmdbuf functions out of command.c
v147 3/7/90 Implement ?@; fix multi-file edit bugs.
v148 3/29/90 Fixed bug in :e then :e#.
v149 4/3/90 Change error,ierror,query to use PARG.
v150 4/6/90 Add LESS_CHARSET, LESS_CHARDEF.
v151 4/13/90 Remove -g option; clean up ispipe.
v152 4/14/90 lsystem() closes input file, for
editors which require exclusive open.
v153 4/18/90 Fix bug if SHELL unset;
fix bug in overstrike control char.
v154 4/25/90 Output to fd 2 via buffer.
v155 4/30/90 Ignore -i if uppercase in pattern
(thanks to Michael Rendell.)
v156 5/3/90 Remove scroll limits in forw() & back();
causes problems with -c.
v157 5/4/90 Forward search starts at next real line
(not screen line) after jump target.
v158 6/14/90 Added F command.
v159 7/29/90 Fix bug in exiting: output not flushed.
v160 7/29/90 Clear screen before initial output w/ -c.
v161 7/29/90 Add -T flag.
v162 8/14/90 Fix bug with +F on command line.
v163 8/21/90 Added LESSBINFMT variable.
v164 9/5/90 Added -p, LINES, COLUMNS and
unset mark ' == BOF, for 1003.2 D5.
v165 9/6/90 At EOF with -c set, don't display empty
screen when try to page forward.
v166 9/6/90 Fix G when final line in file wraps.
v167 9/11/90 Translate CR/LF -> LF for 1003.2.
v168 9/13/90 Return to curr file if "tag not found".
v169 12/12/90 G goes to EOF even if file has grown.
v170 1/17/91 Add optimization for BSD _setjmp;
fix #include ioctl.h TERMIO problem.
(thanks to Paul Eggert)
Posted to USENET.
-----------------------------------------------------------------
v171 3/6/91 Fix -? bug in get_filename.
v172 3/15/91 Fix G bug in empty file.
Fix bug with ?\n and -i and uppercase
pattern at EOF!
(thanks to Paul Eggert)
v173 3/17/91 Change N cmd to not permanently change
direction. (thanks to Brian Matthews)
v174 3/18/91 Fix bug with namelogfile not getting
cleared when change files.
v175 3/18/91 Fix bug with ++cmd on command line.
(thanks to Jim Meyering)
v176 4/2/91 Change | to not force current screen,
include marked line, start/end from
top of screen. Improve search speed.
(thanks to Don Mears)
v177 4/2/91 Add LESSHELP variable.
Fix bug with F command with -e.
Try /dev/tty for input before using fd 2.
Patches posted to USENET 4/2/91.
-----------------------------------------------------------------
v178 4/8/91 Fixed bug in globbing logfile name.
(thanks to Jim Meyering)
v179 4/9/91 Allow negative -z for screen-relative.
v180 4/9/91 Clear to eos rather than eol if "db";
don't use "sr" if "da".
(thanks to Tor Lillqvist)
v181 4/18/91 Fixed bug with "negative" chars 80 - FF.
(thanks to Benny Sander Hofmann)
v182 5/16/91 Fixed bug with attribute at EOL.
(thanks to Brian Matthews)
v183 6/1/91 Rewrite linstall to do smart config.
v184 7/11/91 Process \b in searches based on -u
rather than -i.
v185 7/11/91 -Pxxx sets short prompt; assume SIGWINCH
after a SIGSTOP. (thanks to Ken Laprade)
-----------------------------------------------------------------
v186 4/20/92 Port to MS-DOS (Microsoft C).
v187 4/23/92 Added -D option & TAB_COMPLETE_FILENAME.
v188 4/28/92 Added command line editing features.
v189 12/8/92 Fix mem overrun in anscreen.c:init;
fix edit_list to recover from bin file.
v190 2/13/93 Make TAB enter one filename at a time;
create ^L with old TAB functionality.
v191 3/10/93 Defer creating "flash" page for MS-DOS.
v192 9/6/93 Add BACK-TAB.
v193 9/17/93 Simplify binary_file handling.
v194 1/4/94 Add rudiments of alt_filename handling.
v195 1/11/94 Port back to Unix; support keypad.
-----------------------------------------------------------------
v196 6/7/94 Fix bug with bad filename; fix IFILE
type problem. (thanks to David MacKenzie)
v197 6/7/94 Fix bug with .less tables inserted wrong.
v198 6/23/94 Use autoconf installation technology.
(thanks to David MacKenzie)
v199 6/29/94 Fix MS-DOS build (thanks to Tim Wiegman).
v200 7/25/94 Clean up copyright, minor fixes.
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v201 7/27/94 Check for no memcpy; add casts to calloc;
look for regcmp in libgen.a.
(thanks to Kaveh Ghazi).
v202 7/28/94 Fix bug in edit_next/edit_prev with
non-existant files.
v203 8/2/94 Fix a variety of configuration bugs on
various systems. (thanks to Sakai
Kiyotaka, Harald Koenig, Bjorn Brox,
Teemu Rantanen, and Thorsten Lockert)
v204 8/3/94 Use strerror if available.
(thanks to J.T. Conklin)
v205 8/5/94 Fix bug in finding "me" termcap entry.
(thanks to Andreas Stolcke)
8/10/94 v205+: Change BUFSIZ to LBUFSIZE to avoid name
conflict with stdio.h.
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v206 8/10/94 Use initial_scrpos for -t to avoid
displaying first page before init().
(thanks to Dominique Petitpierre)
v207 8/12/94 Fix bug if stdout is not tty.
v208 8/16/94 Fix bug in close_altfile if goto err1
in edit_ifile. (Thanks to M.J. Hewitt)
v209 8/16/94 Change scroll to wscroll to avoid
conflict with library function.
v210 8/16/94 Fix bug with bold on 8 bit chars.
(thanks to Vitor Duarte)
v211 8/16/94 Don't quit on EOI in jump_loc / forw.
v212 8/18/94 Use time_t if available.
v213 8/20/94 Allow ospeed to be defined in termcap.h.
v214 8/20/94 Added HILITE_SEARCH, -F, ESC-u cmd.
(thanks to Paul Lew and Bob Byrnes)
v215 8/23/94 Fix -i toggle behavior.
v216 8/23/94 Process BS in all searches, not only -u.
v217 8/24/94 Added -X flag.
v218 8/24/94 Reimplement undo_search.
v219 8/24/94 Find tags marked with line number
instead of pattern.
v220 8/24/94 Stay at same position after SIG_WINCH.
v221 8/24/94 Fix bug in file percentage in big file.
v222 8/25/94 Do better if can't reopen current file.
v223 8/27/94 Support setlocale.
(thanks to Robert Joop)
v224 8/29/94 Revert v216: process BS in search
only if -u.
v225 9/6/94 Rewrite undo_search again: toggle.
v226 9/15/94 Configuration fixes.
(thanks to David MacKenzie)
v227 9/19/94 Fixed strerror config problem.
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v228 9/21/94 Fix bug in signals: repeated calls to
get_editkeys overflowed st_edittable.
v229 9/21/94 Fix "Nothing to search" error if -a
and SRCH_PAST_EOF.
v230 9/21/94 Don't print extra error msg in search
after regerror().
v231 9/22/94 Fix hilite bug if search matches 0 chars.
(thanks to John Polstra)
v232 9/23/94 Deal with weird systems that have
termios.h but not tcgetattr().
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v233 9/26/94 Use get_term() instead of pos_init() in
psignals to re-get lower_left termcap.
(Thanks to John Malecki)
v234 9/26/94 Make MIDDLE closer to middle of screen.
v235 9/27/94 Use local strchr if system doesn't have.
v236 9/28/94 Don't use libucb; use libterm if
libtermcap & libcurses doesn't work.
(Fix for Solaris; thanks to Frank Kaefer)
v237 9/30/94 Use system isupper() etc if provided.
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v238 10/6/94 Make binary non-blinking if LESSBINFMT
is set to a string without a *.
v239 10/7/94 Don't let delimit_word run back past
beginning of cmdbuf.
v240 10/10/94 Don't write into termcap buffer.
(Thanks to Benoit Speckel)
v241 10/13/94 New lesskey file format.
Don't expand filenames in search command.
v242 10/14/94 Allow lesskey specification of "literal".
v243 10/14/94 Add #stop command to lesskey.
v244 10/16/94 Add -f flag to lesskey.
v245 10/25/94 Allow TAB_COMPLETE_FILENAME to be undefd.
v246 10/27/94 Move help file to /usr/local/share.
v247 10/27/94 Add -V option.
v248 11/5/94 Add -V option to lesskey.
v249 11/5/94 Remove -f flag from lesskey; default
input file is ~/.lesskey.in, not stdin.
v250 11/7/94 Lesskey input file "-" means stdin.
v251 11/9/94 Convert cfgetospeed result to ospeed.
(Thanks to Andrew Chernov)
v252 11/16/94 Change default lesskey input file from
.lesskey.in to .lesskey.
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v253 11/21/94 Fix bug when tags file has a backslash.
v254 12/6/94 Fix -k option.
v255 12/8/94 Add #define EXAMINE to disable :e etc.
v256 12/10/94 Change highlighting: only highlite search
results (but now it is reliable).
v257 12/10/94 Add goto_line and repaint_highlight
to optimize highlight repaints.
v258 12/12/94 Fixup in hilite_line if BS_SPECIAL.
v259 12/12/94 Convert to autoconf 2.0.
v260 12/13/94 Add SECURE define.
v261 12/14/94 Use system WERASE char as EC_W_BACKSPACE.
v262 12/16/94 Add -g/-G flag and screen_hilite.
v263 12/20/94 Reimplement/optimize -G flag behavior.
v264 12/23/94 Allow EXTRA string after line-edit cmd
in lesskey file.
v265 12/24/94 Add LESSOPEN=|cmd syntax.
v266 12/26/94 Add -I flag.
v267 12/28/94 Formalize the four-byte header emitted
by a LESSOPEN pipe.
v268 12/28/94 Get rid of four-byte header.
v269 1/2/95 Close alt file before open new one.
Avoids multiple popen().
v270 1/3/95 Use VISUAL; use S_ISDIR/S_ISREG; fix
config problem with Solaris POSIX regcomp.
v271 1/4/95 Don't quit on read error.
v272 1/5/95 Get rid of -L.
v273 1/6/95 Fix ch_ungetchar bug; don't call
LESSOPEN on a pipe.
v274 1/6/95 Ported to OS/2 (thanks to Kai Uwe Rommel)
v275 1/18/95 Fix bug if toggle -G at EOF.
v276 1/30/95 Fix OS/2 version.
v277 1/31/95 Add "next" charset; don't display ^X
for X > 128.
v278 2/14/95 Change default for -G.
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v279 2/22/95 Add GNU options --help, --version.
Minor config fixes.
v280 2/24/95 Clean up calls to glob(); don't set #
if we can't open the new file.
v281 2/24/95 Repeat search should turn on hilites.
v282 3/2/95 Minor fixes.
v283 3/2/95 Fix homefile; make OS2 look in $HOME.
v284 3/2/95 Error if "v" on LESSOPENed file;
"%" figures out file size on pipe.
v285 3/7/95 Don't set # in lsystem;
lesskey try $HOME first.
v286 3/7/95 Reformat change history (too much free time?).
v287 3/8/95 Fix hilite bug if overstrike multiple chars.
v288 3/8/95 Allow lesskey to override get_editkey keys.
v289 3/9/95 Fix adj_hilite bug when line gets processed by
hilite_line more than once.
v290 3/9/95 Make configure automatically. Fix Sequent problem
with incompatible sigsetmask().
Posted to prep.ai.mit.edu
-----------------------------------------------------------------
v291 3/21/95 Add #env to lesskey. Fix MS-DOS build.
Posted to simtel.
-----------------------------------------------------------------
v292 4/24/95 Add MS-DOS support for Borland C.
Fix arrow keys in MS-DOS versions.
v293 4/28/95 Add auto-versioning stuff to make dist.
v294 5/12/95 Fix Borland build.
v295 1/20/96 Fix search on squished file; add /@@.
v296 1/23/96 Allow cmdbuf larger than screen width.
v297 1/24/96 Don't call termcap if tgetent fails;
add #defines for buffers.
v298 1/24/96 Change @@ to ^K.
Add alternate search modifiers ^N, ^F, ^E.
v299 1/25/96 Fix percent overflow in jump_percent (thanks to Brent Wiese);
don't send "ti" after shell command till RETURN pressed.
v300 1/25/96 Change -U to print tabs as ^I.
v301 1/30/96 Make hilites work in cmd F output.
v302 1/31/96 Fix cmd F to notice window-change signals.
v303 1/31/96 Add ESC-SPACE command.
v304 2/1/96 Add ^R search modifier; add LESSSECURE.
v305 2/2/96 Workaround Linux /proc kernel bug; add LESSKEY.
v306 3/16/96 Minor fixes.
v307 3/25/96 Allow cmd line arg "--"; fix DOS & OS/2 defines.h.
v308 4/4/96 Port to OS-9 (thanks to Boisy Pitre); fix -d.
v309 4/9/96 Fix OS-9 version; fix tags bug with "$".
v310 4/10/96 Get rid of HELPFILE.
v311 4/22/96 Add Windows32 support; merge doscreen.c into screen.c.
v312 4/24/96 Don't quit after "cannot reopen" error.
v313 4/25/96 Added horizontal scrolling.
v314 4/26/96 Modified -e to quit on reaching end of a squished file.
v315 4/26/96 Fix "!;TAB" bug.
v316 5/2/96 Make "|a" when (a < curr screen) go to end of curr screen.
v317 5/14/96 Various fixes for the MS-DOS and OS/2 builds.
Added ## and %% handling for filenames
v318 5/29/96 Port to OS-9 Microware compiler; minor fixes
(thanks to Martin Gregorie).
v319 7/8/96 Fix Windows port (thanks to Jeff Paquette).
v320 7/11/96 Final fixes for Windows port.
v321 7/18/96 Minor fixes.
Posted to Web page.
-----------------------------------------------------------------
v322 8/13/96 Fix bug in shell escape from help file; add support for
Microsoft Visual C under Windows; numerous small fixes.
v323 8/19/96 Fixes for Windows version (thanks to Simon Munton);
fix for Linux library weirdness (thanks to Jim Diamond);
port to DJGPP (thanks to Eli Zaretskii).
v324 8/21/96 Add support for spaces in filenames (thanks to Simon Munton).
v325 8/21/96 Add lessecho, for spaces in filenames under Unix.
v326 8/27/96 Fix DJGPP version.
v327 9/1/96 Reorganize lglob, make spaces in filenames work better in Unix.
v328 10/7/96 Append / to directory name in filename completion.
Fix MS-DOS and OS-9 versions.
v329 10/11/96 Fix more MS-DOS bugs; add LESSSEPARATOR; add -" option.
Add LESSMETACHARS, LESSMETAESCAPE.
v330 10/21/96 Minor fixes.
Posted to Web page.
-----------------------------------------------------------------
v331 4/22/97 Various Windows fixes (thanks to Gurusamy Sarathy).
v332 4/22/97 Enter filenames from cmd line into edit history.
Posted to Web page.
-----------------------------------------------------------------
v333 3/4/99 Changed -w to highlite new line after forward movement.
v334 3/9/99 Avoid overflowing prompt buffer; add %d and %D.
v335 3/20/99 Add EBCDIC support (thanks to Thomas Dorner).
Use HOMEDRIVE/HOMEPATH on Windows (thanks to Preston Bannister).
Posted to Web page.
-----------------------------------------------------------------
v336 4/8/99 Fix installation bugs.
v337 4/9/99 Fix another installation bug.
Posted to Web page.
-----------------------------------------------------------------
v338 4/13/99 Add support for long option names.
v339 4/18/99 Add \k, long option names to lesskey. Add -^P. Add :d.
v340 4/21/99 Add regexec2. Fix Windows build.
Posted to Web page.
-----------------------------------------------------------------
v341 5/6/99 Add -F option; %c & ?c prompt escapes.
(Thanks to Michele Maltoni)
v342 7/22/99 Add system-wide lesskey file; allow GPL or Less License.
v343 9/23/99 Support UTF-8 (Thanks to Robert Brady).
Add %P and ?P in prompts.
v344 10/27/99 -w highlights target line of g and p commands.
v345 10/29/99 Make -R pass thru ESC but not other control chars.
Posted to Web page.
-----------------------------------------------------------------
v346 11/4/99 Fix bugs in long option processing; R cmd should clear hilites.
Posted to Web page.
-----------------------------------------------------------------
v347 12/13/99 Fixes for DJGPP version (thanks to Eli Zaretskii).
v348 12/28/99 Fix deleting file with marks (thanks to Dimitar Jekov).
Fix color problem in DJGPP version (thanks to Eli Zaretskii).
v349 1/24/00 Fix minor DJGPP bugs; check environment vars for UTF-8;
add --with-editor (thanks to Eli, Markus Kuhn, Thomas Schoepf).
v350 3/1/00 Fix clear-while-standout bug.
v351 3/5/00 Change -M and = prompts to show top & bottom line number.
Posted to Web page.
-----------------------------------------------------------------
v352 3/8/00 Fix scan_option NULL dereference.
-----------------------------------------------------------------
v353 3/20/00 Fix SECURE compile bug, allow space after numeric option.
v354 3/23/00 Add support for PCRE; add --with-regex configure option.
-----------------------------------------------------------------
v355 6/28/00 Add -# option (thanks to Andy Levinson).
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.
v372 12/29/01 Make -b be in units of 1K.
v373 1/14/02 Improve handling of filenames containing shell metachars.
v374 2/7/02 Fix memory leak; fix bug in -x argument parsing.
v375 4/7/02 Fix searching for SGR sequences; fix SECURE build;
add SGR support to DJGPP version (thanks to Eli Zaretskii).
v376 6/10/02 Fix bug in overstriking mulitbyte UTF-8 characters
(thanks to Jungshik Shin).
Posted to Web page.
-----------------------------------------------------------------
v377 9/10/02 Fix bug in Windows version when file contains CR;
fix bug in search highlights with -R;
make initial buffer limit really be 64K not unlimited.
v378 9/30/02 Misc bug fixes and compiler warning cleanup.
Posted to Web page.
-----------------------------------------------------------------
v379 11/23/02 Add -L option; fix bug with ctrl-K in lesskey files;
improve UTF-8 overstriking and underscore overstriking;
fix minor man page problems; change to autoconf 2.54.
v380 11/24/02 Make LINENUM same as POSITION.
v381 11/28/02 Make -N use 7 columns for line number if possible.
-----------------------------------------------------------------
v382 2/3/04 Remove copyrighted code.
*/
char version[] = "382";
less-382/regexp.c 0100444 0000764 0000764 00000067274 10010075213 013012 0 ustar markn markn /*
* regcomp and regexec -- regsub and regerror are elsewhere
*
* Copyright (c) 1986 by University of Toronto.
* Written by Henry Spencer. Not derived from licensed software.
*
* Permission is granted to anyone to use this software for any
* purpose on any computer system, and to redistribute it freely,
* subject to the following restrictions:
*
* 1. The author is not responsible for the consequences of use of
* this software, no matter how awful, even if they arise
* from defects in it.
*
* 2. The origin of this software must not be misrepresented, either
* by explicit claim or by omission.
*
* 3. Altered versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* Beware that some of this code is subtly aware of the way operator
* precedence is structured in regular expressions. Serious changes in
* regular-expression syntax might require a total rethink.
*
* *** NOTE: this code has been altered slightly for use in Tcl. ***
* Slightly modified by David MacKenzie to undo most of the changes for TCL.
* Added regexec2 with notbol parameter. -- 4/19/99 Mark Nudelman
*/
#include "less.h"
#if HAVE_STDIO_H
#include
#endif
#if HAVE_STDLIB_H
#include
#endif
#if HAVE_STRING_H
#include
#endif
#include "regexp.h"
/*
* The "internal use only" fields in regexp.h are present to pass info from
* compile to execute that permits the execute phase to run lots faster on
* simple cases. They are:
*
* regstart char that must begin a match; '\0' if none obvious
* reganch is the match anchored (at beginning-of-line only)?
* regmust string (pointer into program) that match must include, or NULL
* regmlen length of regmust string
*
* Regstart and reganch permit very fast decisions on suitable starting points
* for a match, cutting down the work a lot. Regmust permits fast rejection
* of lines that cannot possibly match. The regmust tests are costly enough
* that regcomp() supplies a regmust only if the r.e. contains something
* potentially expensive (at present, the only such thing detected is * or +
* at the start of the r.e., which can involve a lot of backup). Regmlen is
* supplied because the test in regexec() needs it and regcomp() is
* computing it anyway.
*/
/*
* Structure for regexp "program". This is essentially a linear encoding
* of a nondeterministic finite-state machine (aka syntax charts or
* "railroad normal form" in parsing technology). Each node is an opcode
* plus a "next" pointer, possibly plus an operand. "Next" pointers of
* all nodes except BRANCH implement concatenation; a "next" pointer with
* a BRANCH on both ends of it is connecting two alternatives. (Here we
* have one of the subtle syntax dependencies: an individual BRANCH (as
* opposed to a collection of them) is never concatenated with anything
* because of operator precedence.) The operand of some types of node is
* a literal string; for others, it is a node leading into a sub-FSM. In
* particular, the operand of a BRANCH node is the first node of the branch.
* (NB this is *not* a tree structure: the tail of the branch connects
* to the thing following the set of BRANCHes.) The opcodes are:
*/
/* definition number opnd? meaning */
#undef EOL
#define END 0 /* no End of program. */
#define BOL 1 /* no Match "" at beginning of line. */
#define EOL 2 /* no Match "" at end of line. */
#define ANY 3 /* no Match any one character. */
#define ANYOF 4 /* str Match any character in this string. */
#define ANYBUT 5 /* str Match any character not in this string. */
#define BRANCH 6 /* node Match this alternative, or the next... */
#define BACK 7 /* no Match "", "next" ptr points backward. */
#define EXACTLY 8 /* str Match this string. */
#define NOTHING 9 /* no Match empty string. */
#define STAR 10 /* node Match this (simple) thing 0 or more times. */
#define PLUS 11 /* node Match this (simple) thing 1 or more times. */
#define OPEN 20 /* no Mark this point in input as start of #n. */
/* OPEN+1 is number 1, etc. */
#define CLOSE 30 /* no Analogous to OPEN. */
/*
* Opcode notes:
*
* BRANCH The set of branches constituting a single choice are hooked
* together with their "next" pointers, since precedence prevents
* anything being concatenated to any individual branch. The
* "next" pointer of the last BRANCH in a choice points to the
* thing following the whole choice. This is also where the
* final "next" pointer of each individual branch points; each
* branch starts with the operand node of a BRANCH node.
*
* BACK Normal "next" pointers all implicitly point forward; BACK
* exists to make loop structures possible.
*
* STAR,PLUS '?', and complex '*' and '+', are implemented as circular
* BRANCH structures using BACK. Simple cases (one character
* per match) are implemented with STAR and PLUS for speed
* and to minimize recursive plunges.
*
* OPEN,CLOSE ...are numbered at compile time.
*/
/*
* A node is one char of opcode followed by two chars of "next" pointer.
* "Next" pointers are stored as two 8-bit pieces, high order first. The
* value is a positive offset from the opcode of the node containing it.
* An operand, if any, simply follows the node. (Note that much of the
* code generation knows about this implicit relationship.)
*
* Using two bytes for the "next" pointer is vast overkill for most things,
* but allows patterns to get big without disasters.
*/
#define OP(p) (*(p))
#define NEXT(p) (((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
#define OPERAND(p) ((p) + 3)
/*
* See regmagic.h for one further detail of program structure.
*/
/*
* Utility definitions.
*/
#ifndef CHARBITS
#define UCHARAT(p) ((int)*(unsigned char *)(p))
#else
#define UCHARAT(p) ((int)*(p)&CHARBITS)
#endif
#define FAIL(m) { regerror(m); return(NULL); }
#define ISMULT(c) ((c) == '*' || (c) == '+' || (c) == '?')
#define META "^$.[()|?+*\\"
/*
* Flags to be passed up and down.
*/
#define HASWIDTH 01 /* Known never to match null string. */
#define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */
#define SPSTART 04 /* Starts with * or +. */
#define WORST 0 /* Worst case. */
/*
* Global work variables for regcomp().
*/
static char *regparse; /* Input-scan pointer. */
static int regnpar; /* () count. */
static char regdummy;
static char *regcode; /* Code-emit pointer; ®dummy = don't. */
static long regsize; /* Code size. */
/*
* The first byte of the regexp internal "program" is actually this magic
* number; the start node begins in the second byte.
*/
#define MAGIC 0234
/*
* Forward declarations for regcomp()'s friends.
*/
#ifndef STATIC
#define STATIC static
#endif
STATIC char *reg();
STATIC char *regbranch();
STATIC char *regpiece();
STATIC char *regatom();
STATIC char *regnode();
STATIC char *regnext();
STATIC void regc();
STATIC void reginsert();
STATIC void regtail();
STATIC void regoptail();
#ifdef STRCSPN
STATIC int strcspn();
#endif
/*
- regcomp - compile a regular expression into internal code
*
* We can't allocate space until we know how big the compiled form will be,
* but we can't compile it (and thus know how big it is) until we've got a
* place to put the code. So we cheat: we compile it twice, once with code
* generation turned off and size counting turned on, and once "for real".
* This also means that we don't allocate space until we are sure that the
* thing really will compile successfully, and we never have to move the
* code and thus invalidate pointers into it. (Note that it has to be in
* one piece because free() must be able to free it all.)
*
* Beware that the optimization-preparation code in here knows about some
* of the structure of the compiled regexp.
*/
regexp *
regcomp(exp)
char *exp;
{
register regexp *r;
register char *scan;
register char *longest;
register int len;
int flags;
if (exp == NULL)
FAIL("NULL argument");
/* First pass: determine size, legality. */
regparse = exp;
regnpar = 1;
regsize = 0L;
regcode = ®dummy;
regc(MAGIC);
if (reg(0, &flags) == NULL)
return(NULL);
/* Small enough for pointer-storage convention? */
if (regsize >= 32767L) /* Probably could be 65535L. */
FAIL("regexp too big");
/* Allocate space. */
r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize);
if (r == NULL)
FAIL("out of space");
/* Second pass: emit code. */
regparse = exp;
regnpar = 1;
regcode = r->program;
regc(MAGIC);
if (reg(0, &flags) == NULL)
return(NULL);
/* Dig out information for optimizations. */
r->regstart = '\0'; /* Worst-case defaults. */
r->reganch = 0;
r->regmust = NULL;
r->regmlen = 0;
scan = r->program+1; /* First BRANCH. */
if (OP(regnext(scan)) == END) { /* Only one top-level choice. */
scan = OPERAND(scan);
/* Starting-point info. */
if (OP(scan) == EXACTLY)
r->regstart = *OPERAND(scan);
else if (OP(scan) == BOL)
r->reganch++;
/*
* If there's something expensive in the r.e., find the
* longest literal string that must appear and make it the
* regmust. Resolve ties in favor of later strings, since
* the regstart check works with the beginning of the r.e.
* and avoiding duplication strengthens checking. Not a
* strong reason, but sufficient in the absence of others.
*/
if (flags&SPSTART) {
longest = NULL;
len = 0;
for (; scan != NULL; scan = regnext(scan))
if (OP(scan) == EXACTLY && ((int) strlen(OPERAND(scan))) >= len) {
longest = OPERAND(scan);
len = strlen(OPERAND(scan));
}
r->regmust = longest;
r->regmlen = len;
}
}
return(r);
}
/*
- reg - regular expression, i.e. main body or parenthesized thing
*
* Caller must absorb opening parenthesis.
*
* Combining parenthesis handling with the base level of regular expression
* is a trifle forced, but the need to tie the tails of the branches to what
* follows makes it hard to avoid.
*/
static char *
reg(paren, flagp)
int paren; /* Parenthesized? */
int *flagp;
{
register char *ret;
register char *br;
register char *ender;
register int parno = 0;
int flags;
*flagp = HASWIDTH; /* Tentatively. */
/* Make an OPEN node, if parenthesized. */
if (paren) {
if (regnpar >= NSUBEXP)
FAIL("too many ()");
parno = regnpar;
regnpar++;
ret = regnode(OPEN+parno);
} else
ret = NULL;
/* Pick up the branches, linking them together. */
br = regbranch(&flags);
if (br == NULL)
return(NULL);
if (ret != NULL)
regtail(ret, br); /* OPEN -> first. */
else
ret = br;
if (!(flags&HASWIDTH))
*flagp &= ~HASWIDTH;
*flagp |= flags&SPSTART;
while (*regparse == '|') {
regparse++;
br = regbranch(&flags);
if (br == NULL)
return(NULL);
regtail(ret, br); /* BRANCH -> BRANCH. */
if (!(flags&HASWIDTH))
*flagp &= ~HASWIDTH;
*flagp |= flags&SPSTART;
}
/* Make a closing node, and hook it on the end. */
ender = regnode((paren) ? CLOSE+parno : END);
regtail(ret, ender);
/* Hook the tails of the branches to the closing node. */
for (br = ret; br != NULL; br = regnext(br))
regoptail(br, ender);
/* Check for proper termination. */
if (paren && *regparse++ != ')') {
FAIL("unmatched ()");
} else if (!paren && *regparse != '\0') {
if (*regparse == ')') {
FAIL("unmatched ()");
} else
FAIL("junk on end"); /* "Can't happen". */
/* NOTREACHED */
}
return(ret);
}
/*
- regbranch - one alternative of an | operator
*
* Implements the concatenation operator.
*/
static char *
regbranch(flagp)
int *flagp;
{
register char *ret;
register char *chain;
register char *latest;
int flags;
*flagp = WORST; /* Tentatively. */
ret = regnode(BRANCH);
chain = NULL;
while (*regparse != '\0' && *regparse != '|' && *regparse != ')') {
latest = regpiece(&flags);
if (latest == NULL)
return(NULL);
*flagp |= flags&HASWIDTH;
if (chain == NULL) /* First piece. */
*flagp |= flags&SPSTART;
else
regtail(chain, latest);
chain = latest;
}
if (chain == NULL) /* Loop ran zero times. */
(void) regnode(NOTHING);
return(ret);
}
/*
- regpiece - something followed by possible [*+?]
*
* Note that the branching code sequences used for ? and the general cases
* of * and + are somewhat optimized: they use the same NOTHING node as
* both the endmarker for their branch list and the body of the last branch.
* It might seem that this node could be dispensed with entirely, but the
* endmarker role is not redundant.
*/
static char *
regpiece(flagp)
int *flagp;
{
register char *ret;
register char op;
register char *next;
int flags;
ret = regatom(&flags);
if (ret == NULL)
return(NULL);
op = *regparse;
if (!ISMULT(op)) {
*flagp = flags;
return(ret);
}
if (!(flags&HASWIDTH) && op != '?')
FAIL("*+ operand could be empty");
*flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
if (op == '*' && (flags&SIMPLE))
reginsert(STAR, ret);
else if (op == '*') {
/* Emit x* as (x&|), where & means "self". */
reginsert(BRANCH, ret); /* Either x */
regoptail(ret, regnode(BACK)); /* and loop */
regoptail(ret, ret); /* back */
regtail(ret, regnode(BRANCH)); /* or */
regtail(ret, regnode(NOTHING)); /* null. */
} else if (op == '+' && (flags&SIMPLE))
reginsert(PLUS, ret);
else if (op == '+') {
/* Emit x+ as x(&|), where & means "self". */
next = regnode(BRANCH); /* Either */
regtail(ret, next);
regtail(regnode(BACK), ret); /* loop back */
regtail(next, regnode(BRANCH)); /* or */
regtail(ret, regnode(NOTHING)); /* null. */
} else if (op == '?') {
/* Emit x? as (x|) */
reginsert(BRANCH, ret); /* Either x */
regtail(ret, regnode(BRANCH)); /* or */
next = regnode(NOTHING); /* null. */
regtail(ret, next);
regoptail(ret, next);
}
regparse++;
if (ISMULT(*regparse))
FAIL("nested *?+");
return(ret);
}
/*
- regatom - the lowest level
*
* Optimization: gobbles an entire sequence of ordinary characters so that
* it can turn them into a single node, which is smaller to store and
* faster to run. Backslashed characters are exceptions, each becoming a
* separate node; the code is simpler that way and it's not worth fixing.
*/
static char *
regatom(flagp)
int *flagp;
{
register char *ret;
int flags;
*flagp = WORST; /* Tentatively. */
switch (*regparse++) {
case '^':
ret = regnode(BOL);
break;
case '$':
ret = regnode(EOL);
break;
case '.':
ret = regnode(ANY);
*flagp |= HASWIDTH|SIMPLE;
break;
case '[': {
register int clss;
register int classend;
if (*regparse == '^') { /* Complement of range. */
ret = regnode(ANYBUT);
regparse++;
} else
ret = regnode(ANYOF);
if (*regparse == ']' || *regparse == '-')
regc(*regparse++);
while (*regparse != '\0' && *regparse != ']') {
if (*regparse == '-') {
regparse++;
if (*regparse == ']' || *regparse == '\0')
regc('-');
else {
clss = UCHARAT(regparse-2)+1;
classend = UCHARAT(regparse);
if (clss > classend+1)
FAIL("invalid [] range");
for (; clss <= classend; clss++)
regc(clss);
regparse++;
}
} else
regc(*regparse++);
}
regc('\0');
if (*regparse != ']')
FAIL("unmatched []");
regparse++;
*flagp |= HASWIDTH|SIMPLE;
}
break;
case '(':
ret = reg(1, &flags);
if (ret == NULL)
return(NULL);
*flagp |= flags&(HASWIDTH|SPSTART);
break;
case '\0':
case '|':
case ')':
FAIL("internal urp"); /* Supposed to be caught earlier. */
/* NOTREACHED */
break;
case '?':
case '+':
case '*':
FAIL("?+* follows nothing");
/* NOTREACHED */
break;
case '\\':
if (*regparse == '\0')
FAIL("trailing \\");
ret = regnode(EXACTLY);
regc(*regparse++);
regc('\0');
*flagp |= HASWIDTH|SIMPLE;
break;
default: {
register int len;
register char ender;
regparse--;
len = strcspn(regparse, META);
if (len <= 0)
FAIL("internal disaster");
ender = *(regparse+len);
if (len > 1 && ISMULT(ender))
len--; /* Back off clear of ?+* operand. */
*flagp |= HASWIDTH;
if (len == 1)
*flagp |= SIMPLE;
ret = regnode(EXACTLY);
while (len > 0) {
regc(*regparse++);
len--;
}
regc('\0');
}
break;
}
return(ret);
}
/*
- regnode - emit a node
*/
static char * /* Location. */
regnode(op)
char op;
{
register char *ret;
register char *ptr;
ret = regcode;
if (ret == ®dummy) {
regsize += 3;
return(ret);
}
ptr = ret;
*ptr++ = op;
*ptr++ = '\0'; /* Null "next" pointer. */
*ptr++ = '\0';
regcode = ptr;
return(ret);
}
/*
- regc - emit (if appropriate) a byte of code
*/
static void
regc(b)
char b;
{
if (regcode != ®dummy)
*regcode++ = b;
else
regsize++;
}
/*
- reginsert - insert an operator in front of already-emitted operand
*
* Means relocating the operand.
*/
static void
reginsert(op, opnd)
char op;
char *opnd;
{
register char *src;
register char *dst;
register char *place;
if (regcode == ®dummy) {
regsize += 3;
return;
}
src = regcode;
regcode += 3;
dst = regcode;
while (src > opnd)
*--dst = *--src;
place = opnd; /* Op node, where operand used to be. */
*place++ = op;
*place++ = '\0';
*place++ = '\0';
}
/*
- regtail - set the next-pointer at the end of a node chain
*/
static void
regtail(p, val)
char *p;
char *val;
{
register char *scan;
register char *temp;
register int offset;
if (p == ®dummy)
return;
/* Find last node. */
scan = p;
for (;;) {
temp = regnext(scan);
if (temp == NULL)
break;
scan = temp;
}
if (OP(scan) == BACK)
offset = scan - val;
else
offset = val - scan;
*(scan+1) = (offset>>8)&0377;
*(scan+2) = offset&0377;
}
/*
- regoptail - regtail on operand of first argument; nop if operandless
*/
static void
regoptail(p, val)
char *p;
char *val;
{
/* "Operandless" and "op != BRANCH" are synonymous in practice. */
if (p == NULL || p == ®dummy || OP(p) != BRANCH)
return;
regtail(OPERAND(p), val);
}
/*
* regexec and friends
*/
/*
* Global work variables for regexec().
*/
static char *reginput; /* String-input pointer. */
static char *regbol; /* Beginning of input, for ^ check. */
static char **regstartp; /* Pointer to startp array. */
static char **regendp; /* Ditto for endp. */
/*
* Forwards.
*/
STATIC int regtry();
STATIC int regmatch();
STATIC int regrepeat();
#ifdef DEBUG
int regnarrate = 0;
void regdump();
STATIC char *regprop();
#endif
/*
- regexec - match a regexp against a string
*/
int
regexec2(prog, string, notbol)
register regexp *prog;
register char *string;
int notbol;
{
register char *s;
/* Be paranoid... */
if (prog == NULL || string == NULL) {
regerror("NULL parameter");
return(0);
}
/* Check validity of program. */
if (UCHARAT(prog->program) != MAGIC) {
regerror("corrupted program");
return(0);
}
/* If there is a "must appear" string, look for it. */
if (prog->regmust != NULL) {
s = string;
while ((s = strchr(s, prog->regmust[0])) != NULL) {
if (strncmp(s, prog->regmust, prog->regmlen) == 0)
break; /* Found it. */
s++;
}
if (s == NULL) /* Not present. */
return(0);
}
/* Mark beginning of line for ^ . */
if (notbol)
regbol = NULL;
else
regbol = string;
/* Simplest case: anchored match need be tried only once. */
if (prog->reganch)
return(regtry(prog, string));
/* Messy cases: unanchored match. */
s = string;
if (prog->regstart != '\0')
/* We know what char it must start with. */
while ((s = strchr(s, prog->regstart)) != NULL) {
if (regtry(prog, s))
return(1);
s++;
}
else
/* We don't -- general case. */
do {
if (regtry(prog, s))
return(1);
} while (*s++ != '\0');
/* Failure. */
return(0);
}
int
regexec(prog, string)
register regexp *prog;
register char *string;
{
return regexec2(prog, string, 0);
}
/*
- regtry - try match at specific point
*/
static int /* 0 failure, 1 success */
regtry(prog, string)
regexp *prog;
char *string;
{
register int i;
register char **sp;
register char **ep;
reginput = string;
regstartp = prog->startp;
regendp = prog->endp;
sp = prog->startp;
ep = prog->endp;
for (i = NSUBEXP; i > 0; i--) {
*sp++ = NULL;
*ep++ = NULL;
}
if (regmatch(prog->program + 1)) {
prog->startp[0] = string;
prog->endp[0] = reginput;
return(1);
} else
return(0);
}
/*
- regmatch - main matching routine
*
* Conceptually the strategy is simple: check to see whether the current
* node matches, call self recursively to see whether the rest matches,
* and then act accordingly. In practice we make some effort to avoid
* recursion, in particular by going through "ordinary" nodes (that don't
* need to know whether the rest of the match failed) by a loop instead of
* by recursion.
*/
static int /* 0 failure, 1 success */
regmatch(prog)
char *prog;
{
register char *scan; /* Current node. */
char *next; /* Next node. */
scan = prog;
#ifdef DEBUG
if (scan != NULL && regnarrate)
fprintf(stderr, "%s(\n", regprop(scan));
#endif
while (scan != NULL) {
#ifdef DEBUG
if (regnarrate)
fprintf(stderr, "%s...\n", regprop(scan));
#endif
next = regnext(scan);
switch (OP(scan)) {
case BOL:
if (reginput != regbol)
return(0);
break;
case EOL:
if (*reginput != '\0')
return(0);
break;
case ANY:
if (*reginput == '\0')
return(0);
reginput++;
break;
case EXACTLY: {
register int len;
register char *opnd;
opnd = OPERAND(scan);
/* Inline the first character, for speed. */
if (*opnd != *reginput)
return(0);
len = strlen(opnd);
if (len > 1 && strncmp(opnd, reginput, len) != 0)
return(0);
reginput += len;
}
break;
case ANYOF:
if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
return(0);
reginput++;
break;
case ANYBUT:
if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
return(0);
reginput++;
break;
case NOTHING:
break;
case BACK:
break;
case OPEN+1:
case OPEN+2:
case OPEN+3:
case OPEN+4:
case OPEN+5:
case OPEN+6:
case OPEN+7:
case OPEN+8:
case OPEN+9: {
register int no;
register char *save;
no = OP(scan) - OPEN;
save = reginput;
if (regmatch(next)) {
/*
* Don't set startp if some later
* invocation of the same parentheses
* already has.
*/
if (regstartp[no] == NULL)
regstartp[no] = save;
return(1);
} else
return(0);
}
/* NOTREACHED */
break;
case CLOSE+1:
case CLOSE+2:
case CLOSE+3:
case CLOSE+4:
case CLOSE+5:
case CLOSE+6:
case CLOSE+7:
case CLOSE+8:
case CLOSE+9: {
register int no;
register char *save;
no = OP(scan) - CLOSE;
save = reginput;
if (regmatch(next)) {
/*
* Don't set endp if some later
* invocation of the same parentheses
* already has.
*/
if (regendp[no] == NULL)
regendp[no] = save;
return(1);
} else
return(0);
}
/* NOTREACHED */
break;
case BRANCH: {
register char *save;
if (OP(next) != BRANCH) /* No choice. */
next = OPERAND(scan); /* Avoid recursion. */
else {
do {
save = reginput;
if (regmatch(OPERAND(scan)))
return(1);
reginput = save;
scan = regnext(scan);
} while (scan != NULL && OP(scan) == BRANCH);
return(0);
/* NOTREACHED */
}
}
/* NOTREACHED */
break;
case STAR:
case PLUS: {
register char nextch;
register int no;
register char *save;
register int min;
/*
* Lookahead to avoid useless match attempts
* when we know what character comes next.
*/
nextch = '\0';
if (OP(next) == EXACTLY)
nextch = *OPERAND(next);
min = (OP(scan) == STAR) ? 0 : 1;
save = reginput;
no = regrepeat(OPERAND(scan));
while (no >= min) {
/* If it could work, try it. */
if (nextch == '\0' || *reginput == nextch)
if (regmatch(next))
return(1);
/* Couldn't or didn't -- back up. */
no--;
reginput = save + no;
}
return(0);
}
/* NOTREACHED */
break;
case END:
return(1); /* Success! */
/* NOTREACHED */
break;
default:
regerror("memory corruption");
return(0);
/* NOTREACHED */
break;
}
scan = next;
}
/*
* We get here only if there's trouble -- normally "case END" is
* the terminating point.
*/
regerror("corrupted pointers");
return(0);
}
/*
- regrepeat - repeatedly match something simple, report how many
*/
static int
regrepeat(p)
char *p;
{
register int count = 0;
register char *scan;
register char *opnd;
scan = reginput;
opnd = OPERAND(p);
switch (OP(p)) {
case ANY:
count = strlen(scan);
scan += count;
break;
case EXACTLY:
while (*opnd == *scan) {
count++;
scan++;
}
break;
case ANYOF:
while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
count++;
scan++;
}
break;
case ANYBUT:
while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
count++;
scan++;
}
break;
default: /* Oh dear. Called inappropriately. */
regerror("internal foulup");
count = 0; /* Best compromise. */
break;
}
reginput = scan;
return(count);
}
/*
- regnext - dig the "next" pointer out of a node
*/
static char *
regnext(p)
register char *p;
{
register int offset;
if (p == ®dummy)
return(NULL);
offset = NEXT(p);
if (offset == 0)
return(NULL);
if (OP(p) == BACK)
return(p-offset);
else
return(p+offset);
}
#ifdef DEBUG
STATIC char *regprop();
/*
- regdump - dump a regexp onto stdout in vaguely comprehensible form
*/
void
regdump(r)
regexp *r;
{
register char *s;
register char op = EXACTLY; /* Arbitrary non-END op. */
register char *next;
s = r->program + 1;
while (op != END) { /* While that wasn't END last time... */
op = OP(s);
printf("%2d%s", s-r->program, regprop(s)); /* Where, what. */
next = regnext(s);
if (next == NULL) /* Next ptr. */
printf("(0)");
else
printf("(%d)", (s-r->program)+(next-s));
s += 3;
if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
/* Literal string, where present. */
while (*s != '\0') {
putchar(*s);
s++;
}
s++;
}
putchar('\n');
}
/* Header fields of interest. */
if (r->regstart != '\0')
printf("start `%c' ", r->regstart);
if (r->reganch)
printf("anchored ");
if (r->regmust != NULL)
printf("must have \"%s\"", r->regmust);
printf("\n");
}
/*
- regprop - printable representation of opcode
*/
static char *
regprop(op)
char *op;
{
register char *p;
static char buf[50];
(void) strcpy(buf, ":");
switch (OP(op)) {
case BOL:
p = "BOL";
break;
case EOL:
p = "EOL";
break;
case ANY:
p = "ANY";
break;
case ANYOF:
p = "ANYOF";
break;
case ANYBUT:
p = "ANYBUT";
break;
case BRANCH:
p = "BRANCH";
break;
case EXACTLY:
p = "EXACTLY";
break;
case NOTHING:
p = "NOTHING";
break;
case BACK:
p = "BACK";
break;
case END:
p = "END";
break;
case OPEN+1:
case OPEN+2:
case OPEN+3:
case OPEN+4:
case OPEN+5:
case OPEN+6:
case OPEN+7:
case OPEN+8:
case OPEN+9:
sprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
p = NULL;
break;
case CLOSE+1:
case CLOSE+2:
case CLOSE+3:
case CLOSE+4:
case CLOSE+5:
case CLOSE+6:
case CLOSE+7:
case CLOSE+8:
case CLOSE+9:
sprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
p = NULL;
break;
case STAR:
p = "STAR";
break;
case PLUS:
p = "PLUS";
break;
default:
regerror("corrupted opcode");
break;
}
if (p != NULL)
(void) strcat(buf, p);
return(buf);
}
#endif
/*
* The following is provided for those people who do not have strcspn() in
* their C libraries. They should get off their butts and do something
* about it; at least one public-domain implementation of those (highly
* useful) string routines has been published on Usenet.
*/
#ifdef STRCSPN
/*
* strcspn - find length of initial segment of s1 consisting entirely
* of characters not from s2
*/
static int
strcspn(s1, s2)
char *s1;
char *s2;
{
register char *scan1;
register char *scan2;
register int count;
count = 0;
for (scan1 = s1; *scan1 != '\0'; scan1++) {
for (scan2 = s2; *scan2 != '\0';) /* ++ moved down. */
if (*scan1 == *scan2++)
return(count);
count++;
}
return(count);
}
#endif
less-382/regexp.h 0100444 0000764 0000764 00000001715 10010075213 013003 0 ustar markn markn /*
* Definitions etc. for regexp(3) routines.
*
* Caveat: this is V8 regexp(3) [actually, a reimplementation thereof],
* not the System V one.
*/
#ifndef _REGEXP
#define _REGEXP 1
#define NSUBEXP 10
typedef struct regexp {
char *startp[NSUBEXP];
char *endp[NSUBEXP];
char regstart; /* Internal use only. */
char reganch; /* Internal use only. */
char *regmust; /* Internal use only. */
int regmlen; /* Internal use only. */
char program[1]; /* Unwarranted chumminess with compiler. */
} regexp;
#if defined(__STDC__) || defined(__cplusplus)
# define _ANSI_ARGS_(x) x
#else
# define _ANSI_ARGS_(x) ()
#endif
extern regexp *regcomp _ANSI_ARGS_((char *exp));
extern int regexec _ANSI_ARGS_((regexp *prog, char *string));
extern int regexec2 _ANSI_ARGS_((regexp *prog, char *string, int notbol));
extern void regsub _ANSI_ARGS_((regexp *prog, char *source, char *dest));
extern void regerror _ANSI_ARGS_((char *msg));
#endif /* REGEXP */
less-382/COPYING 0100444 0000764 0000764 00000043132 10010075212 012371 0 ustar markn markn GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
less-382/INSTALL 0100444 0000764 0000764 00000017326 10010075212 012375 0 ustar markn markn This file describes how to build and install less using
the "configure" script. This only works on Unix systems.
To install on other systems, read the README file.
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=PATH' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made.
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.
less-382/LICENSE 0100444 0000764 0000764 00000002367 10010075212 012350 0 ustar markn markn Less License
------------
Less
Copyright (C) 1984-2002 Mark Nudelman
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice in the documentation and/or other materials provided with
the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
less-382/Makefile.in 0100444 0000764 0000764 00000005733 10010075212 013410 0 ustar markn markn # Makefile for less.
#### Start of system configuration section. ####
srcdir = @srcdir@
VPATH = @srcdir@
CC = @CC@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CFLAGS = @CFLAGS@
CFLAGS_COMPILE_ONLY = -c
LDFLAGS = @LDFLAGS@
O=o
LIBS = @LIBS@
prefix = @prefix@
exec_prefix = @exec_prefix@
# Where the installed binary goes.
bindir = @bindir@
binprefix =
sysconfdir = @sysconfdir@
mandir = @mandir@
manext = 1
manprefix =
#### End of system configuration section. ####
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} -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} \
help.${O} ifile.${O} input.${O} jump.${O} line.${O} linenum.${O} \
lsystem.${O} mark.${O} optfunc.${O} option.${O} opttbl.${O} os.${O} \
output.${O} position.${O} prompt.${O} search.${O} signal.${O} \
tags.${O} ttyin.${O} version.${O} @REGEX_O@
all: less lesskey lessecho
less: ${OBJ}
${CC} ${LDFLAGS} -o $@ ${OBJ} ${LIBS}
lesskey: lesskey.${O} version.${O}
${CC} ${LDFLAGS} -o $@ lesskey.${O} version.${O}
lessecho: lessecho.${O} version.${O}
${CC} ${LDFLAGS} -o $@ lessecho.${O} version.${O}
${OBJ}: ${srcdir}/less.h ${srcdir}/funcs.h defines.h
install: all ${srcdir}/less.nro ${srcdir}/lesskey.nro installdirs
${INSTALL_PROGRAM} less ${bindir}/${binprefix}less
${INSTALL_PROGRAM} lesskey ${bindir}/${binprefix}lesskey
${INSTALL_PROGRAM} lessecho ${bindir}/${binprefix}lessecho
${INSTALL_DATA} ${srcdir}/less.nro ${mandir}/man${manext}/${manprefix}less.${manext}
${INSTALL_DATA} ${srcdir}/lesskey.nro ${mandir}/man${manext}/${manprefix}lesskey.${manext}
install-strip:
${MAKE} INSTALL_PROGRAM='${INSTALL_PROGRAM} -s' install
installdirs: mkinstalldirs
${srcdir}/mkinstalldirs ${bindir} ${mandir}/man${manext}
uninstall:
rm -f ${bindir}/${binprefix}less ${bindir}/${binprefix}lesskey ${bindir}/${binprefix}lessecho
rm -f ${mandir}/man${manext}/${manprefix}less.${manext} ${mandir}/man${manext}/${manprefix}lesskey.${manext}
info:
install-info:
dvi:
check:
installcheck:
TAGS:
cd ${srcdir} && etags *.c *.h
# config.status might not change defines.h
# Don't rerun config.status if we just configured (so there's no stamp-h).
defines.h: stamp-h
stamp-h: defines.h.in config.status
test ! -f stamp-h || CONFIG_FILES= CONFIG_HEADERS=defines.h ./config.status
touch stamp-h
Makefile: ${srcdir}/Makefile.in config.status
CONFIG_FILES=Makefile CONFIG_HEADERS= ./config.status
config.status: ${srcdir}/configure
./config.status --recheck
${srcdir}/configure: ${srcdir}/configure.ac
cd ${srcdir}; autoheader; autoconf
clean:
rm -f *.${O} core less lesskey lessecho
mostlyclean: clean
distclean: clean
rm -f Makefile config.status config.log config.cache defines.h stamp-h
realclean: distclean
rm -f TAGS
less-382/Makefile.aut 0100444 0000764 0000764 00000007301 10010075212 013564 0 ustar markn markn # Makefile for authoring less.
EMAIL = markn@greenwoodsoftware.com
HOMEPAGE = https://www.greenwoodsoftware.com/less
SHELL = /bin/sh
RCS = rcs
NROFF = nroff -man
srcdir = .
SRC = \
main.c screen.c brac.c ch.c charset.c cmdbuf.c \
command.c decode.c edit.c filename.c forwback.c \
help.c ifile.c input.c jump.c line.c linenum.c \
lsystem.c mark.c optfunc.c option.c opttbl.c os.c \
output.c position.c prompt.c search.c signal.c \
tags.c ttyin.c version.c
DISTFILES_W = \
defines.ds Makefile.dsb Makefile.dsg Makefile.dsu \
defines.o2 Makefile.o2e \
defines.o9 Makefile.o9c Makefile.o9u \
defines.wn Makefile.wnm Makefile.wnb
DISTFILES = \
${SRC} regexp.c regexp.h \
COPYING INSTALL LICENSE Makefile.in Makefile.aut NEWS README \
configure configure.ac 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 mkinstalldirs \
less.nro lesskey.nro less.man lesskey.man less.hlp \
mkfuncs.awk mkhelp.c \
${DISTFILES_W}
all: help.c funcs.h ${srcdir}/configure
help.c: less.hlp mkhelp
-mv -f ${srcdir}/help.c ${srcdir}/help.c.old
rm -rf help.c
./mkhelp < less.hlp > help.c
if cmp -s help.c help.c.old; then mv help.c.old help.c; fi
mkhelp: mkhelp.c
${CC} -o mkhelp mkhelp.c
${srcdir}/configure: ${srcdir}/configure.ac \
${srcdir}/Makefile.in
cd ${srcdir}; autoheader; autoconf
funcs.h: ${SRC:%=${srcdir}/%}
-mv -f ${srcdir}/funcs.h ${srcdir}/funcs.h.old
awk -f ${srcdir}/mkfuncs.awk ${SRC:%=${srcdir}/%} >${srcdir}/funcs.h
if cmp -s funcs.h funcs.h.old; then mv funcs.h.old funcs.h; fi
lint:
lint -I. ${CPPFLAGS} ${SRC}
clean:
rm -f Makefile config.status config.log config.cache defines.h stamp-h \
README NEWS less.nro lesskey.nro less.man lesskey.man
distclean: clean
realclean: clean
REPLACE_VERSION = \
@REL=`sed -e '/char version/!d' -e 's/[^0-9.]*\([0-9.]*\).*/\1/' -e q ${srcdir}/version.c`; \
DT=`date '+%d %h %Y'`; \
echo "Stuffing version number $$REL into $@"; \
sed \
-e "s;@@VERSION@@;$$REL;" \
-e "s;@@DATE@@;$$DT;" \
-e "s;@@EMAIL@@;${EMAIL};" \
-e "s;@@HOMEPAGE@@;${HOMEPAGE};" >$@
${srcdir}/README: ${srcdir}/README.VER ${srcdir}/version.c
${REPLACE_VERSION} ${srcdir}/README.VER
${srcdir}/NEWS: ${srcdir}/NEWS.VER ${srcdir}/version.c
${REPLACE_VERSION} ${srcdir}/NEWS.VER
${srcdir}/less.nro: ${srcdir}/less.nro.VER ${srcdir}/version.c
${REPLACE_VERSION} ${srcdir}/less.nro.VER
${srcdir}/lesskey.nro: ${srcdir}/lesskey.nro.VER ${srcdir}/version.c
${REPLACE_VERSION} ${srcdir}/lesskey.nro.VER
${srcdir}/less.hlp: ${srcdir}/less.hlp.VER ${srcdir}/version.c
${REPLACE_VERSION} ${srcdir}/less.hlp.VER
${srcdir}/less.man: ${srcdir}/less.nro
${NROFF} ${srcdir}/less.nro >${srcdir}/less.man
${srcdir}/lesskey.man: ${srcdir}/lesskey.nro
${NROFF} ${srcdir}/lesskey.nro >${srcdir}/lesskey.man
distfiles: ${DISTFILES}
dist: ${DISTFILES}
if [ ! -d ${srcdir}/release ]; then mkdir ${srcdir}/release; fi
@cd ${srcdir}; \
REL=`sed -e '/char version/!d' -e 's/[^0-9.]*\([0-9.]*\).*/less-\1/' -e q version.c`; \
rm -rf release/$$REL; mkdir release/$$REL; \
echo "Preparing $$REL"; \
rm -rf $$REL; mkdir $$REL; \
for file in ${DISTFILES}; do \
cp -p $$file $$REL; \
chmod -w $$REL/$$file; \
done; \
cd $$REL; chmod +w ${DISTFILES_W}; cd ..; \
echo "Creating release/$$REL/$$REL.tar.gz"; \
tar -cf - $$REL | gzip -c >release/$$REL/$$REL.tar.gz; \
echo "Creating release/$$REL/$$REL.zip"; \
zip -rq release/$$REL/$$REL.zip $$REL; \
rm -rf $$REL
tagall:
@REL=`sed -e '/char version/!d' -e 's/[^0-9.]*\([0-9.]*\).*/v\1/' -e q ${srcdir}/version.c`; \
echo "tagging $$REL"; \
for f in ${srcdir}/RCS/*,v; do \
REV=`co -p $$f 2>&1 | sed -e '1d' -e '3,$$d' -e 's/revision //'`; \
${RCS} -N$$REL:$$REV $$f; \
done
less-382/NEWS 0100444 0000764 0000764 00000045577 10010076270 012061 0 ustar markn markn
NEWS about less
======================================================================
For the latest news about less, see the "less" Web page:
https://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 markn@greenwoodsoftware.com.
======================================================================
Major changes between "less" versions 381 and 382
* Removed some old copyrighted code.
This probably breaks OS/9 support.
======================================================================
Major changes between "less" versions 378 and 381
* New -L option to disable LESSOPEN processing.
* Further support for large (64 bit) file addressing.
Large file support is now set up by the configure script.
* Use autoconf 2.54.
Replace configure.in, acconfig.h, defines.h.top with configure.ac.
* Overstriking underscore with underscore is now bold or underlined
depending on context.
* Use only 7 spaces for line numbers in -N mode, if possible.
* Fix some bugs in handling overstriking in UTF-8 files.
* Fix some nroff issues in the man page.
======================================================================
Major changes between "less" versions 376 and 378
* Bug fixes:
Default buffer space is now 64K as documented.
Search highlighting works properly when used with -R.
Windows version works properly when input file contains carriage returns.
Clean up some compiler warnings.
======================================================================
Major changes between "less" versions 358 and 376
* -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 https://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".
* Searching works better with ANSI (SGR) escape sequences.
ANSI color escape sequences are now supported in the MS-DOS (DJGPP) version.
* Improved performance in reading very large pipes.
* 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.
* Improved handling of filenames containing shell metacharacters.
* 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.
* Add -# (--shift) option to set default horizontal shift distance.
Default horizontal shift distance is now one-half screen width.
* Horizontal shifting does not shift line numbers if -N is in effect.
* Horizontal shifting acts as though -S were set, to avoid confusion.
======================================================================
Major changes between "less" versions 352 and 354
* Allow space after numeric-valued command line options.
* Fix problem with configuring terminal libraries on some systems.
* Add support for PCRE regular expression library.
* Add --with-regex option to configure to allow manually selecting
a regular expression library.
* Fix bug compiling with SECURE = 1.
======================================================================
Major changes between "less" versions 346 and 352
* Enable UTF-8 if "UTF-8" appears in locale-related environment variables.
* Add --with-editor option to configure script.
* The -M prompt and = message now show the top and bottom line number.
* Fix bug in running the editor on a file whose name contains quotes, etc.
* Fix bug in horizontal scrolling of long lines.
* Fix bug in doing :d on a file which contains marks.
* Fix bug causing cleared lines to sometimes be filled with standout,
bold, underline, etc. on certain terminals.
* Fixes for MS-DOS (DJGPP) version.
======================================================================
Major changes between "less" versions 340 and 346
* The UTF-8 character set is now supported.
* The default character set is now latin1 rather than ascii.
* New option -R (--RAW-CONTROL-CHARS) is like -r but handles
long (wrapped) lines correctly, as long as the input contains only
normal text and ANSI color escape sequences.
* New option -F (--quit-if-one-screen) quits if the text fits on
the first screen.
* The -w option now highlights the target line of a g or p command.
* A system-wide lesskey file is supported (LESSKEY_SYSTEM).
* New escape for prompt strings: %c is replaced by column number.
* New escape for prompt strings: %P is replaced by percentage into
file, based on line number rather than byte offset.
* HOME and END keys now jump to beginning of file or end of file.
======================================================================
Major changes between "less" versions 337 and 340
* Command line options for less may now be given in either the old
single-letter form, or a new long name form (--option-name).
See the less man page or "less --help" for the list of long option names.
* Command line options for lesskey may now be given in a new long name
form. See the lesskey man page for the list of long option names.
* New command -- toggles an option using the long option name.
* New command __ queries an option using the long option name.
* The old -- command is renamed as -!.
* If a ^P is entered between the dash and the option letter of the -
command, the message describing the new setting is suppressed.
* Lesskey files may now contain \k escape sequences to represent the
"special" keys (arrows, PAGE-UP/PAGE-DOWN, HOME, END, INSERT, DELETE).
* New command :d removes the current file from the list of files.
* New option -~ (like -w before version 335)
suppresses tildes after end-of-file.
* Less is now released under the GNU General Public License.
======================================================================
Major changes between "less" versions 335 and 337
* Fixed bugs in "make install".
======================================================================
Major changes between "less" versions 332 and 335
* The old -w flag (suppress tildes after end-of-file) has been removed.
* New -w flag highlights the first new line after a forward-screen.
* New -W flag highlights the first new line after any forward movement.
* Window resize works even if LINES and/or COLUMNS environment
variables are incorrect.
* New percent escapes for prompt strings:
%d is replaced by the page number, and
%D is replaced by the number of pages in the file.
* Added charsets "iso8859" and "ebcdic".
* In Windows version, uses HOMEDRIVE and HOMEPATH if HOME is not defined.
* Fixed some bugs causing incorrect display on DOS/Windows.
======================================================================
Major changes between "less" versions 330 and 332
* Filenames from the command line are entered into the command history,
so UPARROW/DOWNARROW can be used to retrieve them from the :e command.
* Now works correctly on Windows when using a scrolling terminal
window (buffer larger than display window).
* On Windows, now restores the console screen on exit.
Use -X to get the old behavior.
* Fixed bug on Windows when CAPS-LOCK or NUM-LOCK is pressed.
* Fixed bug on Windows when piping output of an interactive program.
* Fixed bug in tags file processing when tags file has DOS-style
line terminators (CR/LF).
* Fixed compilation problem on OS/2.
======================================================================
Major changes between "less" versions 321 and 330
* Now supports filenames containing spaces (in double quotes).
New option -" can be used to change the quoting characters.
* In filename completion, a slash is appended to a directory name.
If the environment variable LESSSEPARATOR is set, the value of
that variable, rather than a slash, is appended.
* LeftArrow and RightArrow are same as ESC-[ and ESC-].
* Added commands ESC-( and ESC-), same as ESC-[ and ESC-].
* A "quit" command defined in a lesskey file may now have an "extra"
string, which is used to return an exit code from less when it quits.
* New environment variables LESSMETACHARS and LESSMETAESCAPE provide
more control over how less interfaces to the shell.
* Ported to Microsoft Visual C compiler for Windows.
* Ported to DJGPP compiler for MS-DOS.
* Bug fixes.
======================================================================
Major changes between "less" versions 291 and 321
* Command line at bottom of screen now scrolls, so it can be longer
than the screen width.
* New commands ESC-] and ESC-[ scroll the display horizontally.
* New command ESC-SPACE scrolls forward a full screen, even if it
hits end-of-file.
* Alternate modifiers for search commands: ^N is same as !,
^F is same as @, and ^E is same as *.
* New modifier for search commands: ^K means highlight the matches
currently on-screen, but don't move to the first match.
* New modifier for search commands: ^R means don't use regular
expressions in the search.
* Environment variable LESSKEY gives name of default lesskey file.
* Environment variable LESSSECURE will force less to run in
"secure" mode.
* Command line argument "--" signals that the rest of the arguments
are files (not option flags).
* Help file (less.hlp) is no longer installed. Help text is now
embedded in the less executable itself.
* Added -Ph to change the prompt for the help text.
Added -Ps to change the default short prompt (same as plain -P).
* Ported to the Borland C compiler for MS-DOS.
* Ported to Windows 95 & Windows NT.
* Ported to OS-9.
* Ported to GNU Hurd.
======================================================================
Major changes between "less" versions 290 and 291
* Less environment variables can be specified in lesskey files.
* Fixed MS-DOS build.
======================================================================
Major changes between "less" versions 278 and 290
* Accepts GNU-style options "--help" and "--version".
* OS/2 version looks for less.ini in $HOME before $INIT and $PATH.
* Bug fixes
======================================================================
Major changes between "less" versions 252 and 278
* A LESSOPEN preprocessor may now pipe the converted file data to less,
rather than writing it to a temporary file.
* Search pattern highlighting has been fixed. It now highlights
reliably, even if a string is split across two screen lines,
contains TABs, etc.
* The -F flag (which suppress search highlighting) has been changed
to -G. A new flag, -g, changes search highlighting to highlight
only the string found by the last search command, instead of all
strings which match the last search command.
* New flag -I acts like -i, but ignores case even if the search
pattern contains uppercase letters.
* Less now checks for the environment variable VISUAL before EDITOR.
* Ported to OS/2.
======================================================================
Major changes between "less" versions 237 and 252
* Changes in line-editing keys:
The literal key is now ^V or ^A rather than \ (backslash).
Filename completion commands (TAB and ^L) are disabled
when typing a search pattern.
* Line-editing command keys can be redefined using lesskey.
* Lesskey with no input file defaults to $HOME/.lesskey
rather than standard input.
* New option -V displays version number of less.
* New option -V displays version number of lesskey.
* Help file less.hlp is now installed by default in /usr/local/share
rather than /usr/local/lib.
======================================================================
Major changes between "less" versions 170 and 237
* By popular demand, text which matches the current search pattern
is highlighted. New -F flag disables this feature.
* Henry Spencer's regexp.c is now included, for systems which do not
have a regular expression library.
regexp.c is Copyright (c) 1986 by University of Toronto.
* New line-editing keys, including command history (arrow keys) and
filename completion (TAB).
* Input preprocessor allows modification of input files (e.g. uncompress)
via LESSOPEN/LESSCLOSE environment variables.
* New -X flag disables sending termcap "ti" and "te" (initialize and
deinitialize) strings to the terminal.
* Changing -i from within less now correctly affects a subsequent
repeated search.
* Searching for underlined or overstruck text now works when the -u
flag is in effect, rather than the -i flag.
* Use setlocale (LANG and LC_CTYPE environment variables) to determine
the character set if LESSCHARSET/LESSCHARDEF are not set.
* The default format for displaying binary characters is now standout
(reverse video) rather than blinking. This can still be changed by
setting the LESSBINFMT environment variable.
* Use autoconf installation technology.
* Ported to MS-DOS.
********************************
Things that may surprise you
********************************
* When you enter text at the bottom of the screen (search string,
filename, etc.), some keys act different than previously.
Specifically, \ (backslash), ESC, TAB, BACKTAB, and control-L
now have line editing functions.
* Some previous unofficial versions of less were able to display
compressed files. The new LESSOPEN/LESSCLOSE feature now provides
this functionality in a different way.
* Some previous unofficial versions of less provided a -Z flag to
set the number of lines of text to retain between full screen scrolls.
The -z-n flag (that is, -z with a negative number) provides this
functionality.
======================================================================
Major changes between "less" versions 123 and 170
* New option -j allows target lines to be positioned anywhere on screen.
* New option -S truncates displayed line at the screen width,
rather than wrapping onto the next line.
* New option -y limits amount of forward scroll.
* New option -T specifies a "tags" file.
* Non-printable, non-control characters are displayed in octal.
Such characters, as well as control characters, are displayed
in blinking mode.
* New command -+ sets an option to its default.
* New command -- sets an option to the opposite of its default.
* Lesskey file may have a string appended to a key's action,
which acts as though typed in after the command.
* New commands ESC-^F and ESC-^B match arbitrary types of brackets.
* New command F monitors a growing file (like "tail -f").
* New command | pipes a section of the input file into a shell command.
* New command :x directly jumps to a file in the command line list.
* Search commands have been enhanced and reorganized:
n Repeat search, same direction.
N Repeat search, opposite direction.
ESC-/ Search forward thru file boundaries
ESC-? Search backward thru file boundaries
ESC-n Repeat search thru file boundaries, same direction.
ESC-N Repeat search thru file boundaries, opposite direction.
Special character * causes search to search thru file boundaries.
Special character @ causes search to begin at start/end of file list.
* Examining a new file adds it to the command line list.
A list of files, or an expression which matches more than one file,
may be examined; all of them are added to the command line list.
* Environment variables LESSCHARSET and LESSCHARDEF can define
a non-ASCII character set.
* Partial support for MSDOS, including options -R for repainting screen
on quit, -v/-V to select video mode, and -W to change window size.
======================================================================
Major changes between "less" versions 97 and 123
* New option (-N) causes line numbers to be displayed in the
text of the file (like vi "set nu").
* New option (-?) prints help message immediately.
* New option (-r) displays "raw" control characters, without
mapping them to ^X notation.
* New option (-f) forces less to open non-regular files
(directories, etc).
* New option (-k) can be used to specify lesskey files by name.
* New option (-y) can be used to set a forward scroll limit
(like -h sets a backward scroll limit).
* File marks (set by the m command) are now preserved when a new
file is edited. The ' command can thus be used to switch files.
* New command ESC-/ searches all files (on the command line)
for a pattern.
* New command ESC-n repeats previous search, spanning files.
* The N command has been changed to repeat the previous search
in the reverse direction. The old N command is still available
via :n.
* New command ESC-N repeats previous search in the reverse
direction and spanning files.
* 8 bit characters are now supported. A new option (-g) can be
used to strip off the eighth bit (the previous behavior).
* Options which take a following string (like -t) may now
optionally have a space between the option letter and the string.
* Six new commands { } ( ) [ and ] can be used to match
brackets of specific types, similar to vi % command.
* New commands z and w move forward/backward one window and
simultaneously set the window size.
* Prompt string expansion now has %L for line number of the last
line in the file, and %E for the name of the editor.
Also, % escapes which refer to a line (b=bottom, t=top, etc.)
can use j for the jump target line.
* New environment variable LESSEDIT can be used to tailor the
command string passed to the editor by the v command.
* Examining a file which was previously examined will return
to the same position in the file.
* A "%" is expanded to the current filename and a "#" to the
previous filename, in both shell commands and the E command.
(Previously % worked only in shell commands and # worked
only in the E command.)
* New command ":ta" is equivalent to "-t".
* New command "s" is equivalent to "-l".
* The - command may be followed by "+X" to revert to the default
for option X, or "-X" to get the opposite of the default.
* Lesskey files may now include characters after the action as
extra input to be parsed after the action; for example:
"toggle-option X" to toggle a specific option X.
less-382/README 0100444 0000764 0000764 00000023410 10010076270 012220 0 ustar markn markn
Less, version 382
This is the distribution of less, version 382, released 03 Feb 2004.
This program is part of the GNU project (https://www.gnu.org).
This program is free software. You may redistribute it and/or
modify it under the terms of either:
1. The GNU General Public License, as published by the Free
Software Foundation; either version 2, or (at your option) any
later version. A copy of this license is in the file COPYING.
or
2. The Less License, in the file LICENSE.
Please report any problems to bug-less@gnu.org or markn@greenwoodsoftware.com.
See https://www.greenwoodsoftware.com/less for the latest info.
You may also contact the author at:
Mark Nudelman
Greenwood Software
PO Box 2402
El Granada, CA 94018
USA
=========================================================================
This is the distribution of "less", a paginator similar to "more" or "pg".
The formatted manual page is in less.man.
The manual page nroff source is in less.nro.
Major changes made since the last posted version are in NEWS.
=======================================================================
INSTALLATION (Unix systems only):
1. Move the distributed source to its own directory and unpack it,
if you have not already done so.
2. Type "sh configure".
This will generate a Makefile and a defines.h.
Warning: if you have a GNU sed, make sure it is version 2.05 or later.
The file INSTALL describes the usage of the configure program in
general. In addition, these options to configure are supported:
--with-editor=program
Specifies the default editor program used by the "v" command.
The default is "vi".
--with-regex=lib
Specifies the regular expression library used by less for pattern
matching. The default is "auto", which means the configure program
finds a regular expression library automatically. Other values are:
posix Use the POSIX-compatible regcomp.
pcre Use the PCRE library.
regcmp Use the regcmp library.
re_comp Use the re_comp library.
regcomp Use the V8-compatible regcomp.
regcomp-local Use Henry Spencer's V8-compatible regcomp
(source is supplied with less).
3. It is a good idea to look over the generated Makefile and defines.h
and make sure they look ok. If you know of any peculiarities of
your system that configure might not have detected, you may fix the
Makefile now. Take particular notice of the list of "terminal"
libraries in the LIBS definition in the Makefile; these may need
to be edited. The terminal libraries will be some subset of
-lncurses -lcurses -ltermcap -ltermlib
If you wish, you may edit defines.h to remove some optional features.
If you wish to build a "secure" version of less (which disables all
features which might allow a user to do unintended things to the system
on which less is running), edit defines.h and define SECURE to 1.
If you choose not to include some features in your version, you may
wish to edit the manual page "less.nro" and the help page "less.hlp"
to remove the descriptions of the features which you are removing.
If you edit less.hlp, you should run "make -f Makefile.aut help.c".
4. Type "make" and watch the fun.
5. If the make succeeds, it will generate the programs "less",
"lesskey" and "lessecho" in your current directory. Test the
generated programs.
6. When satisfied that it works, if you wish to install it
in a public place, type "make install".
The default install destinations are:
Executables (less, lesskey, lessecho) in /usr/local/bin
Documentation (less.nro, lesskey.nro) in /usr/local/man/man1
If you want to install any of these files elsewhere, define
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 markn@greenwoodsoftware.com.
Note to hackers: comments noting possible improvements are enclosed
in double curly brackets {{ like this }}.
=======================================================================
INSTALLATION (MS-DOS systems only,
with Microsoft C, Borland C, or DJGPP)
1. Move the distributed source to its own directory.
Depending on your compiler, you may need to convert the source
to have CR-LF rather than LF as line terminators.
2. If you are using Microsoft C, rename MAKEFILE.DSU to MAKEFILE.
If you are using Borland C, rename MAKEFILE.DSB to MAKEFILE.
If you are using DJGPP, rename MAKEFILE.DSG to MAKEFILE.
3. Look at MAKEFILE to make sure that the definitions for CC and LIBDIR
are correct. CC should be the name of your C compiler and
LIBDIR should be the directory where the C libraries reside (for
Microsoft C only). If these definitions need to be changed, you can
either modify the definitions directly in MAKEFILE, or set your
environment variables CC and/or LIBDIR to override the definitions
in MAKEFILE.
4. If you wish, you may edit DEFINES.DS to remove some optional features.
If you choose not to include some features in your version, you may
wish to edit the manual page LESS.MAN and the help page HELP.C
to remove the descriptions of the features which you are removing.
5. Run your "make" program and watch the fun.
If your "make" requires a flag to import environment variables,
you should use that flag.
If your compiler runs out of memory, try running "make -n >cmds.bat"
and then run cmds.bat.
6. If the make succeeds, it will generate the programs "LESS.EXE" and
"LESSKEY.EXE" in your current directory. Test the generated programs.
7. When satisfied that it works, you may wish to install LESS.EXE and
LESSKEY.EXE in a directory which is included in your PATH.
=======================================================================
INSTALLATION (Windows-95, Windows-98 and Windows-NT systems only,
with Borland C or Microsoft Visual C++)
1. Move the distributed source to its own directory.
2. If you are using Borland C, rename Makefile.wnb to Makefile.
If you are using Microsoft Visual C++, rename Makefile.wnm to Makefile.
3. Check the Makefile to make sure the definitions look ok.
4. If you wish, you may edit defines.wn to remove some optional features.
If you choose not to include some features in your version, you may
wish to edit the manual page less.man and the help page help.c
to remove the descriptions of the features which you are removing.
5. Type "make" and watch the fun.
6. If the make succeeds, it will generate the programs "less.exe" and
"lesskey.exe" in your current directory. Test the generated programs.
7. When satisfied that it works, if you wish to install it
in a public place, type "make install".
See step 6 of the Unix installation instructions for details
on how to change the default installation directories.
=======================================================================
INSTALLATION (OS/2 systems only,
with EMX C)
1. Move the distributed source to its own directory.
2. Rename Makefile.o2e to Makefile.
3. Check the Makefile to make sure the definitions look ok.
4. If you wish, you may edit defines.o2 to remove some optional features.
If you choose not to include some features in your version, you may
wish to edit the manual page less.man and the help page help.c
to remove the descriptions of the features which you are removing.
5. Type "make" and watch the fun.
6. If the make succeeds, it will generate the programs "less.exe" and
"lesskey.exe" in your current directory. Test the generated programs.
7. Make sure you have the emx runtime installed. You need the emx DLLs
emx.dll and emxlibcs.dll and also the termcap database, termcap.dat.
Make sure you have termcap.dat either in the default location or
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,
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.
=======================================================================
INSTALLATION (OS-9 systems only,
with Microware C or Ultra C)
1. Move the distributed source to its own directory.
2. If you are using Microware C, rename Makefile.o9c to Makefile.
If you are using Ultra C, rename Makefile.o9u to Makefile.
3. Check the Makefile to make sure the definitions look ok.
4. If you wish, you may edit defines.o9 to remove some optional features.
If you choose not to include some features in your version, you may
wish to edit the manual page less.man and the help page help.c
to remove the descriptions of the features which you are removing.
5. Type "dmake" and watch the fun.
The standard OS-9 "make" will probably not work. If you don't
have dmake, you can get a copy from os9archive.rtsi.com.
6. If the make succeeds, it will generate the programs "less" and
"lesskey" in your current directory. Test the generated programs.
7. When satisfied that it works, if you wish to install it
in a public place, type "dmake install".
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.
less-382/configure 0100555 0000764 0000764 00000545374 10010075301 013263 0 ustar markn markn #! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.54 for less 1.
#
# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## --------------------- ##
## M4sh Initialization. ##
## --------------------- ##
# Be Bourne compatible
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
emulate sh
NULLCMD=:
# Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
set -o posix
fi
# Support unset when possible.
if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
as_unset=unset
else
as_unset=false
fi
# Work around bugs in pre-3.0 UWIN ksh.
$as_unset ENV MAIL MAILPATH
PS1='$ '
PS2='> '
PS4='+ '
# NLS nuisances.
for as_var in LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE LC_NUMERIC LC_MESSAGES LC_TIME
do
if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
eval $as_var=C; export $as_var
else
$as_unset $as_var
fi
done
# Required to use basename.
if expr a : '\(a\)' >/dev/null 2>&1; then
as_expr=expr
else
as_expr=false
fi
if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
as_basename=basename
else
as_basename=false
fi
# Name of the executable.
as_me=`$as_basename "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)$' \| \
. : '\(.\)' 2>/dev/null ||
echo X/"$0" |
sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
/^X\/\(\/\/\)$/{ s//\1/; q; }
/^X\/\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
# PATH needs CR, and LINENO needs CR and PATH.
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
echo "#! /bin/sh" >conftest.sh
echo "exit 0" >>conftest.sh
chmod +x conftest.sh
if (PATH="/nonexistent;."; conftest.sh) >/dev/null 2>&1; then
PATH_SEPARATOR=';'
else
PATH_SEPARATOR=:
fi
rm -f conftest.sh
fi
as_lineno_1=$LINENO
as_lineno_2=$LINENO
as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
test "x$as_lineno_1" != "x$as_lineno_2" &&
test "x$as_lineno_3" = "x$as_lineno_2" || {
# Find who we are. Look in the path if we contain no path at all
# relative or not.
case $0 in
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
done
;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
as_myself=$0
fi
if test ! -f "$as_myself"; then
{ echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
{ (exit 1); exit 1; }; }
fi
case $CONFIG_SHELL in
'')
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for as_base in sh bash ksh sh5; do
case $as_dir in
/*)
if ("$as_dir/$as_base" -c '
as_lineno_1=$LINENO
as_lineno_2=$LINENO
as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
test "x$as_lineno_1" != "x$as_lineno_2" &&
test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
$as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
$as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
CONFIG_SHELL=$as_dir/$as_base
export CONFIG_SHELL
exec "$CONFIG_SHELL" "$0" ${1+"$@"}
fi;;
esac
done
done
;;
esac
# Create $as_me.lineno as a copy of $as_myself, but with $LINENO
# uniformly replaced by the line number. The first 'sed' inserts a
# line-number line before each line; the second 'sed' does the real
# work. The second script uses 'N' to pair each line-number line
# with the numbered line, and appends trailing '-' during
# substitution so that $LINENO is not a special case at line end.
# (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
# second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
sed '=' <$as_myself |
sed '
N
s,$,-,
: loop
s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
t loop
s,-$,,
s,^['$as_cr_digits']*\n,,
' >$as_me.lineno &&
chmod +x $as_me.lineno ||
{ echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
{ (exit 1); exit 1; }; }
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensible to this).
. ./$as_me.lineno
# Exit status is that of the last command.
exit
}
case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
*c*,-n*) ECHO_N= ECHO_C='
' ECHO_T=' ' ;;
*c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
*) ECHO_N= ECHO_C='\c' ECHO_T= ;;
esac
if expr a : '\(a\)' >/dev/null 2>&1; then
as_expr=expr
else
as_expr=false
fi
rm -f conf$$ conf$$.exe conf$$.file
echo >conf$$.file
if ln -s conf$$.file conf$$ 2>/dev/null; then
# We could just check for DJGPP; but this test a) works b) is more generic
# and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
if test -f conf$$.exe; then
# Don't use ln at all; we don't have any links
as_ln_s='cp -p'
else
as_ln_s='ln -s'
fi
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
as_ln_s='cp -p'
fi
rm -f conf$$ conf$$.exe conf$$.file
if mkdir -p . 2>/dev/null; then
as_mkdir_p=:
else
as_mkdir_p=false
fi
as_executable_p="test -f"
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
# Sed expression to map a string onto a valid variable name.
as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
# IFS
# We need space, tab and new line, in precisely that order.
as_nl='
'
IFS=" $as_nl"
# CDPATH.
$as_unset CDPATH
# Name of the host.
# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
# so uname gets run too.
ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
exec 6>&1
#
# Initializations.
#
ac_default_prefix=/usr/local
ac_config_libobj_dir=.
cross_compiling=no
subdirs=
MFLAGS=
MAKEFLAGS=
SHELL=${CONFIG_SHELL-/bin/sh}
# Maximum number of lines to put in a shell here document.
# This variable seems obsolete. It should probably be removed, and
# only ac_max_sed_lines should be used.
: ${ac_max_here_lines=38}
# Identity of this package.
PACKAGE_NAME='less'
PACKAGE_TARNAME='less'
PACKAGE_VERSION='1'
PACKAGE_STRING='less 1'
PACKAGE_BUGREPORT=''
ac_unique_file="forwback.c"
# Factoring default headers for most tests.
ac_includes_default="\
#include
#if HAVE_SYS_TYPES_H
# include
#endif
#if HAVE_SYS_STAT_H
# include
#endif
#if STDC_HEADERS
# include
# include
#else
# if HAVE_STDLIB_H
# include
# endif
#endif
#if HAVE_STRING_H
# if !STDC_HEADERS && HAVE_MEMORY_H
# include
# endif
# include
#endif
#if HAVE_STRINGS_H
# include
#endif
#if HAVE_INTTYPES_H
# include
#else
# if HAVE_STDINT_H
# include
# endif
#endif
#if HAVE_UNISTD_H
# include
#endif"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA REGEX_O LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
ac_init_help=
ac_init_version=false
# The variables have the same names as the options, with
# dashes changed to underlines.
cache_file=/dev/null
exec_prefix=NONE
no_create=
no_recursion=
prefix=NONE
program_prefix=NONE
program_suffix=NONE
program_transform_name=s,x,x,
silent=
site=
srcdir=
verbose=
x_includes=NONE
x_libraries=NONE
# Installation directory options.
# These are left unexpanded so users can "make install exec_prefix=/foo"
# and all the variables that are supposed to be based on exec_prefix
# by default will actually change.
# Use braces instead of parens because sh, perl, etc. also accept them.
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datadir='${prefix}/share'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
libdir='${exec_prefix}/lib'
includedir='${prefix}/include'
oldincludedir='/usr/include'
infodir='${prefix}/info'
mandir='${prefix}/man'
ac_prev=
for ac_option
do
# If the previous option needs an argument, assign it.
if test -n "$ac_prev"; then
eval "$ac_prev=\$ac_option"
ac_prev=
continue
fi
ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
# Accept the important Cygnus configure options, so we can diagnose typos.
case $ac_option in
-bindir | --bindir | --bindi | --bind | --bin | --bi)
ac_prev=bindir ;;
-bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
bindir=$ac_optarg ;;
-build | --build | --buil | --bui | --bu)
ac_prev=build_alias ;;
-build=* | --build=* | --buil=* | --bui=* | --bu=*)
build_alias=$ac_optarg ;;
-cache-file | --cache-file | --cache-fil | --cache-fi \
| --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
ac_prev=cache_file ;;
-cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
| --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
cache_file=$ac_optarg ;;
--config-cache | -C)
cache_file=config.cache ;;
-datadir | --datadir | --datadi | --datad | --data | --dat | --da)
ac_prev=datadir ;;
-datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
| --da=*)
datadir=$ac_optarg ;;
-disable-* | --disable-*)
ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
{ echo "$as_me: error: invalid feature name: $ac_feature" >&2
{ (exit 1); exit 1; }; }
ac_feature=`echo $ac_feature | sed 's/-/_/g'`
eval "enable_$ac_feature=no" ;;
-enable-* | --enable-*)
ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
{ echo "$as_me: error: invalid feature name: $ac_feature" >&2
{ (exit 1); exit 1; }; }
ac_feature=`echo $ac_feature | sed 's/-/_/g'`
case $ac_option in
*=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
*) ac_optarg=yes ;;
esac
eval "enable_$ac_feature='$ac_optarg'" ;;
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
| --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
| --exec | --exe | --ex)
ac_prev=exec_prefix ;;
-exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
| --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
| --exec=* | --exe=* | --ex=*)
exec_prefix=$ac_optarg ;;
-gas | --gas | --ga | --g)
# Obsolete; use --with-gas.
with_gas=yes ;;
-help | --help | --hel | --he | -h)
ac_init_help=long ;;
-help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
ac_init_help=recursive ;;
-help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
ac_init_help=short ;;
-host | --host | --hos | --ho)
ac_prev=host_alias ;;
-host=* | --host=* | --hos=* | --ho=*)
host_alias=$ac_optarg ;;
-includedir | --includedir | --includedi | --included | --include \
| --includ | --inclu | --incl | --inc)
ac_prev=includedir ;;
-includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
| --includ=* | --inclu=* | --incl=* | --inc=*)
includedir=$ac_optarg ;;
-infodir | --infodir | --infodi | --infod | --info | --inf)
ac_prev=infodir ;;
-infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
infodir=$ac_optarg ;;
-libdir | --libdir | --libdi | --libd)
ac_prev=libdir ;;
-libdir=* | --libdir=* | --libdi=* | --libd=*)
libdir=$ac_optarg ;;
-libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
| --libexe | --libex | --libe)
ac_prev=libexecdir ;;
-libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
| --libexe=* | --libex=* | --libe=*)
libexecdir=$ac_optarg ;;
-localstatedir | --localstatedir | --localstatedi | --localstated \
| --localstate | --localstat | --localsta | --localst \
| --locals | --local | --loca | --loc | --lo)
ac_prev=localstatedir ;;
-localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
| --localstate=* | --localstat=* | --localsta=* | --localst=* \
| --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
localstatedir=$ac_optarg ;;
-mandir | --mandir | --mandi | --mand | --man | --ma | --m)
ac_prev=mandir ;;
-mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
mandir=$ac_optarg ;;
-nfp | --nfp | --nf)
# Obsolete; use --without-fp.
with_fp=no ;;
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
| --no-cr | --no-c | -n)
no_create=yes ;;
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
| --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
no_recursion=yes ;;
-oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
| --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
| --oldin | --oldi | --old | --ol | --o)
ac_prev=oldincludedir ;;
-oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
| --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
| --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
oldincludedir=$ac_optarg ;;
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
ac_prev=prefix ;;
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
prefix=$ac_optarg ;;
-program-prefix | --program-prefix | --program-prefi | --program-pref \
| --program-pre | --program-pr | --program-p)
ac_prev=program_prefix ;;
-program-prefix=* | --program-prefix=* | --program-prefi=* \
| --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
program_prefix=$ac_optarg ;;
-program-suffix | --program-suffix | --program-suffi | --program-suff \
| --program-suf | --program-su | --program-s)
ac_prev=program_suffix ;;
-program-suffix=* | --program-suffix=* | --program-suffi=* \
| --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
program_suffix=$ac_optarg ;;
-program-transform-name | --program-transform-name \
| --program-transform-nam | --program-transform-na \
| --program-transform-n | --program-transform- \
| --program-transform | --program-transfor \
| --program-transfo | --program-transf \
| --program-trans | --program-tran \
| --progr-tra | --program-tr | --program-t)
ac_prev=program_transform_name ;;
-program-transform-name=* | --program-transform-name=* \
| --program-transform-nam=* | --program-transform-na=* \
| --program-transform-n=* | --program-transform-=* \
| --program-transform=* | --program-transfor=* \
| --program-transfo=* | --program-transf=* \
| --program-trans=* | --program-tran=* \
| --progr-tra=* | --program-tr=* | --program-t=*)
program_transform_name=$ac_optarg ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
| --sbi=* | --sb=*)
sbindir=$ac_optarg ;;
-sharedstatedir | --sharedstatedir | --sharedstatedi \
| --sharedstated | --sharedstate | --sharedstat | --sharedsta \
| --sharedst | --shareds | --shared | --share | --shar \
| --sha | --sh)
ac_prev=sharedstatedir ;;
-sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
| --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
| --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
| --sha=* | --sh=*)
sharedstatedir=$ac_optarg ;;
-site | --site | --sit)
ac_prev=site ;;
-site=* | --site=* | --sit=*)
site=$ac_optarg ;;
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
srcdir=$ac_optarg ;;
-sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
| --syscon | --sysco | --sysc | --sys | --sy)
ac_prev=sysconfdir ;;
-sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
| --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
sysconfdir=$ac_optarg ;;
-target | --target | --targe | --targ | --tar | --ta | --t)
ac_prev=target_alias ;;
-target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
target_alias=$ac_optarg ;;
-v | -verbose | --verbose | --verbos | --verbo | --verb)
verbose=yes ;;
-version | --version | --versio | --versi | --vers | -V)
ac_init_version=: ;;
-with-* | --with-*)
ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
{ echo "$as_me: error: invalid package name: $ac_package" >&2
{ (exit 1); exit 1; }; }
ac_package=`echo $ac_package| sed 's/-/_/g'`
case $ac_option in
*=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
*) ac_optarg=yes ;;
esac
eval "with_$ac_package='$ac_optarg'" ;;
-without-* | --without-*)
ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
{ echo "$as_me: error: invalid package name: $ac_package" >&2
{ (exit 1); exit 1; }; }
ac_package=`echo $ac_package | sed 's/-/_/g'`
eval "with_$ac_package=no" ;;
--x)
# Obsolete; use --with-x.
with_x=yes ;;
-x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
| --x-incl | --x-inc | --x-in | --x-i)
ac_prev=x_includes ;;
-x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
| --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
x_includes=$ac_optarg ;;
-x-libraries | --x-libraries | --x-librarie | --x-librari \
| --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
ac_prev=x_libraries ;;
-x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
x_libraries=$ac_optarg ;;
-*) { echo "$as_me: error: unrecognized option: $ac_option
Try \`$0 --help' for more information." >&2
{ (exit 1); exit 1; }; }
;;
*=*)
ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
# Reject names that are not valid shell variable names.
expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
{ echo "$as_me: error: invalid variable name: $ac_envvar" >&2
{ (exit 1); exit 1; }; }
ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
eval "$ac_envvar='$ac_optarg'"
export $ac_envvar ;;
*)
# FIXME: should be removed in autoconf 3.0.
echo "$as_me: WARNING: you should use --build, --host, --target" >&2
expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
echo "$as_me: WARNING: invalid host type: $ac_option" >&2
: ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
;;
esac
done
if test -n "$ac_prev"; then
ac_option=--`echo $ac_prev | sed 's/_/-/g'`
{ echo "$as_me: error: missing argument to $ac_option" >&2
{ (exit 1); exit 1; }; }
fi
# Be sure to have absolute paths.
for ac_var in exec_prefix prefix
do
eval ac_val=$`echo $ac_var`
case $ac_val in
[\\/$]* | ?:[\\/]* | NONE | '' ) ;;
*) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
{ (exit 1); exit 1; }; };;
esac
done
# Be sure to have absolute paths.
for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
localstatedir libdir includedir oldincludedir infodir mandir
do
eval ac_val=$`echo $ac_var`
case $ac_val in
[\\/$]* | ?:[\\/]* ) ;;
*) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
{ (exit 1); exit 1; }; };;
esac
done
# There might be people who depend on the old broken behavior: `$host'
# used to hold the argument of --host etc.
# FIXME: To remove some day.
build=$build_alias
host=$host_alias
target=$target_alias
# FIXME: To remove some day.
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
If a cross compiler is detected then cross compile mode will be used." >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
fi
ac_tool_prefix=
test -n "$host_alias" && ac_tool_prefix=$host_alias-
test "$silent" = yes && exec 6>/dev/null
# Find the source files, if location was not specified.
if test -z "$srcdir"; then
ac_srcdir_defaulted=yes
# Try the directory containing this script, then its parent.
ac_confdir=`(dirname "$0") 2>/dev/null ||
$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$0" : 'X\(//\)[^/]' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$0" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
srcdir=$ac_confdir
if test ! -r $srcdir/$ac_unique_file; then
srcdir=..
fi
else
ac_srcdir_defaulted=no
fi
if test ! -r $srcdir/$ac_unique_file; then
if test "$ac_srcdir_defaulted" = yes; then
{ echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
{ (exit 1); exit 1; }; }
else
{ echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
{ (exit 1); exit 1; }; }
fi
fi
(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
{ echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
{ (exit 1); exit 1; }; }
srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
ac_env_build_alias_set=${build_alias+set}
ac_env_build_alias_value=$build_alias
ac_cv_env_build_alias_set=${build_alias+set}
ac_cv_env_build_alias_value=$build_alias
ac_env_host_alias_set=${host_alias+set}
ac_env_host_alias_value=$host_alias
ac_cv_env_host_alias_set=${host_alias+set}
ac_cv_env_host_alias_value=$host_alias
ac_env_target_alias_set=${target_alias+set}
ac_env_target_alias_value=$target_alias
ac_cv_env_target_alias_set=${target_alias+set}
ac_cv_env_target_alias_value=$target_alias
ac_env_CC_set=${CC+set}
ac_env_CC_value=$CC
ac_cv_env_CC_set=${CC+set}
ac_cv_env_CC_value=$CC
ac_env_CFLAGS_set=${CFLAGS+set}
ac_env_CFLAGS_value=$CFLAGS
ac_cv_env_CFLAGS_set=${CFLAGS+set}
ac_cv_env_CFLAGS_value=$CFLAGS
ac_env_LDFLAGS_set=${LDFLAGS+set}
ac_env_LDFLAGS_value=$LDFLAGS
ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
ac_cv_env_LDFLAGS_value=$LDFLAGS
ac_env_CPPFLAGS_set=${CPPFLAGS+set}
ac_env_CPPFLAGS_value=$CPPFLAGS
ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
ac_cv_env_CPPFLAGS_value=$CPPFLAGS
ac_env_CPP_set=${CPP+set}
ac_env_CPP_value=$CPP
ac_cv_env_CPP_set=${CPP+set}
ac_cv_env_CPP_value=$CPP
#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures less 1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE. See below for descriptions of some of the useful variables.
Defaults for the options are specified in brackets.
Configuration:
-h, --help display this help and exit
--help=short display options specific to this package
--help=recursive display the short help of all the included packages
-V, --version display version information and exit
-q, --quiet, --silent do not print \`checking...' messages
--cache-file=FILE cache test results in FILE [disabled]
-C, --config-cache alias for \`--cache-file=config.cache'
-n, --no-create do not create output files
--srcdir=DIR find the sources in DIR [configure dir or \`..']
_ACEOF
cat <<_ACEOF
Installation directories:
--prefix=PREFIX install architecture-independent files in PREFIX
[$ac_default_prefix]
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
[PREFIX]
By default, \`make install' will install all the files in
\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
an installation prefix other than \`$ac_default_prefix' using \`--prefix',
for instance \`--prefix=\$HOME'.
For better control, use the options below.
Fine tuning of the installation directories:
--bindir=DIR user executables [EPREFIX/bin]
--sbindir=DIR system admin executables [EPREFIX/sbin]
--libexecdir=DIR program executables [EPREFIX/libexec]
--datadir=DIR read-only architecture-independent data [PREFIX/share]
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
--infodir=DIR info documentation [PREFIX/info]
--mandir=DIR man documentation [PREFIX/man]
_ACEOF
cat <<\_ACEOF
_ACEOF
fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of less 1:";;
esac
cat <<\_ACEOF
Optional Features:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-largefile omit support for large files
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-regex={auto,pcre,posix,regcmp,re_comp,regcomp,regcomp-local} Select a regular expression library auto
--with-editor=PROGRAM use PROGRAM as the default editor vi
Some influential environment variables:
CC C compiler command
CFLAGS C compiler flags
LDFLAGS linker flags, e.g. -L if you have libraries in a
nonstandard directory
CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have
headers in a nonstandard directory
CPP C preprocessor
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
_ACEOF
fi
if test "$ac_init_help" = "recursive"; then
# If there are subdirs, report their specific --help.
ac_popdir=`pwd`
for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
test -d $ac_dir || continue
ac_builddir=.
if test "$ac_dir" != .; then
ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
# A "../" for each directory in $ac_dir_suffix.
ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
else
ac_dir_suffix= ac_top_builddir=
fi
case $srcdir in
.) # No --srcdir option. We are building in place.
ac_srcdir=.
if test -z "$ac_top_builddir"; then
ac_top_srcdir=.
else
ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
fi ;;
[\\/]* | ?:[\\/]* ) # Absolute path.
ac_srcdir=$srcdir$ac_dir_suffix;
ac_top_srcdir=$srcdir ;;
*) # Relative path.
ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
ac_top_srcdir=$ac_top_builddir$srcdir ;;
esac
# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
# absolute.
ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
cd $ac_dir
# Check for guested configure; otherwise get Cygnus style configure.
if test -f $ac_srcdir/configure.gnu; then
echo
$SHELL $ac_srcdir/configure.gnu --help=recursive
elif test -f $ac_srcdir/configure; then
echo
$SHELL $ac_srcdir/configure --help=recursive
elif test -f $ac_srcdir/configure.ac ||
test -f $ac_srcdir/configure.in; then
echo
$ac_configure --help
else
echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
fi
cd $ac_popdir
done
fi
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
less configure 1
generated by GNU Autoconf 2.54
Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
exit 0
fi
exec 5>config.log
cat >&5 <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by less $as_me 1, which was
generated by GNU Autoconf 2.54. Invocation command line was
$ $0 $@
_ACEOF
{
cat <<_ASUNAME
## --------- ##
## Platform. ##
## --------- ##
hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
uname -m = `(uname -m) 2>/dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`
/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
_ASUNAME
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
echo "PATH: $as_dir"
done
} >&5
cat >&5 <<_ACEOF
## ----------- ##
## Core tests. ##
## ----------- ##
_ACEOF
# Keep a trace of the command line.
# Strip out --no-create and --no-recursion so they do not pile up.
# Also quote any args containing shell meta-characters.
ac_configure_args=
ac_sep=
for ac_arg
do
case $ac_arg in
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
| --no-cr | --no-c | -n ) continue ;;
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
| --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
continue ;;
*" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
esac
ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
# Get rid of the leading space.
ac_sep=" "
done
# When interrupted or exit'd, cleanup temporary files, and complete
# config.log. We remove comments because anyway the quotes in there
# would cause problems or look ugly.
# WARNING: Be sure not to use single quotes in there, as some shells,
# such as our DU 5.0 friend, will then `close' the trap.
trap 'exit_status=$?
# Save into config.log some information that might help in debugging.
{
echo
cat <<\_ASBOX
## ---------------- ##
## Cache variables. ##
## ---------------- ##
_ASBOX
echo
# The following way of writing the cache mishandles newlines in values,
{
(set) 2>&1 |
case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
*ac_space=\ *)
sed -n \
"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
;;
*)
sed -n \
"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
;;
esac;
}
echo
cat <<\_ASBOX
## ----------------- ##
## Output variables. ##
## ----------------- ##
_ASBOX
echo
for ac_var in $ac_subst_vars
do
eval ac_val=$`echo $ac_var`
echo "$ac_var='"'"'$ac_val'"'"'"
done | sort
echo
if test -n "$ac_subst_files"; then
cat <<\_ASBOX
## ------------- ##
## Output files. ##
## ------------- ##
_ASBOX
echo
for ac_var in $ac_subst_files
do
eval ac_val=$`echo $ac_var`
echo "$ac_var='"'"'$ac_val'"'"'"
done | sort
echo
fi
if test -s confdefs.h; then
cat <<\_ASBOX
## ----------- ##
## confdefs.h. ##
## ----------- ##
_ASBOX
echo
sed "/^$/d" confdefs.h | sort
echo
fi
test "$ac_signal" != 0 &&
echo "$as_me: caught signal $ac_signal"
echo "$as_me: exit $exit_status"
} >&5
rm -f core core.* *.core &&
rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
exit $exit_status
' 0
for ac_signal in 1 2 13 15; do
trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
done
ac_signal=0
# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -rf conftest* confdefs.h
# AIX cpp loses on an empty file, so make sure it contains at least a newline.
echo >confdefs.h
# Predefined preprocessor variables.
cat >>confdefs.h <<_ACEOF
#define PACKAGE_NAME "$PACKAGE_NAME"
_ACEOF
cat >>confdefs.h <<_ACEOF
#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
_ACEOF
cat >>confdefs.h <<_ACEOF
#define PACKAGE_VERSION "$PACKAGE_VERSION"
_ACEOF
cat >>confdefs.h <<_ACEOF
#define PACKAGE_STRING "$PACKAGE_STRING"
_ACEOF
cat >>confdefs.h <<_ACEOF
#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
_ACEOF
# Let the site file select an alternate cache file if it wants to.
# Prefer explicitly selected file to automatically selected ones.
if test -z "$CONFIG_SITE"; then
if test "x$prefix" != xNONE; then
CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
else
CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
fi
fi
for ac_site_file in $CONFIG_SITE; do
if test -r "$ac_site_file"; then
{ echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
echo "$as_me: loading site script $ac_site_file" >&6;}
sed 's/^/| /' "$ac_site_file" >&5
. "$ac_site_file"
fi
done
if test -r "$cache_file"; then
# Some versions of bash will fail to source /dev/null (special
# files actually), so we avoid doing that.
if test -f "$cache_file"; then
{ echo "$as_me:$LINENO: loading cache $cache_file" >&5
echo "$as_me: loading cache $cache_file" >&6;}
case $cache_file in
[\\/]* | ?:[\\/]* ) . $cache_file;;
*) . ./$cache_file;;
esac
fi
else
{ echo "$as_me:$LINENO: creating cache $cache_file" >&5
echo "$as_me: creating cache $cache_file" >&6;}
>$cache_file
fi
# Check that the precious variables saved in the cache have kept the same
# value.
ac_cache_corrupted=false
for ac_var in `(set) 2>&1 |
sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
eval ac_old_set=\$ac_cv_env_${ac_var}_set
eval ac_new_set=\$ac_env_${ac_var}_set
eval ac_old_val="\$ac_cv_env_${ac_var}_value"
eval ac_new_val="\$ac_env_${ac_var}_value"
case $ac_old_set,$ac_new_set in
set,)
{ echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
ac_cache_corrupted=: ;;
,set)
{ echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
ac_cache_corrupted=: ;;
,);;
*)
if test "x$ac_old_val" != "x$ac_new_val"; then
{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
{ echo "$as_me:$LINENO: former value: $ac_old_val" >&5
echo "$as_me: former value: $ac_old_val" >&2;}
{ echo "$as_me:$LINENO: current value: $ac_new_val" >&5
echo "$as_me: current value: $ac_new_val" >&2;}
ac_cache_corrupted=:
fi;;
esac
# Pass precious variables to config.status.
if test "$ac_new_set" = set; then
case $ac_new_val in
*" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
*) ac_arg=$ac_var=$ac_new_val ;;
esac
case " $ac_configure_args " in
*" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
*) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
esac
fi
done
if $ac_cache_corrupted; then
{ echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
echo "$as_me: error: changes in the environment can compromise the build" >&2;}
{ { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
{ (exit 1); exit 1; }; }
fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_config_headers="$ac_config_headers defines.h"
# Checks for programs.
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
set dummy ${ac_tool_prefix}gcc; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
fi
if test -z "$ac_cv_prog_CC"; then
ac_ct_CC=$CC
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$ac_ct_CC"; then
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
echo "${ECHO_T}$ac_ct_CC" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
CC=$ac_ct_CC
else
CC="$ac_cv_prog_CC"
fi
if test -z "$CC"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
set dummy ${ac_tool_prefix}cc; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}cc"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
fi
if test -z "$ac_cv_prog_CC"; then
ac_ct_CC=$CC
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$ac_ct_CC"; then
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="cc"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
echo "${ECHO_T}$ac_ct_CC" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
CC=$ac_ct_CC
else
CC="$ac_cv_prog_CC"
fi
fi
if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
ac_prog_rejected=no
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
ac_prog_rejected=yes
continue
fi
ac_cv_prog_CC="cc"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
if test $ac_prog_rejected = yes; then
# We found a bogon in the path, so make sure we never use it.
set dummy $ac_cv_prog_CC
shift
if test $# != 0; then
# We chose a different compiler from the bogus one.
# However, it has the same basename, so the bogon will be chosen
# first if we set CC to just the basename; use the full file name.
shift
ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
fi
fi
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
fi
if test -z "$CC"; then
if test -n "$ac_tool_prefix"; then
for ac_prog in cl
do
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
echo "$as_me:$LINENO: result: $CC" >&5
echo "${ECHO_T}$CC" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
test -n "$CC" && break
done
fi
if test -z "$CC"; then
ac_ct_CC=$CC
for ac_prog in cl
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if test -n "$ac_ct_CC"; then
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
echo "${ECHO_T}$ac_ct_CC" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
test -n "$ac_ct_CC" && break
done
CC=$ac_ct_CC
fi
fi
test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH" >&5
echo "$as_me: error: no acceptable C compiler found in \$PATH" >&2;}
{ (exit 1); exit 1; }; }
# Provide some information about the compiler.
echo "$as_me:$LINENO:" \
"checking for C compiler version" >&5
ac_compiler=`set X $ac_compile; echo $2`
{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5
(eval $ac_compiler --version &5) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }
{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5
(eval $ac_compiler -v &5) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }
{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5
(eval $ac_compiler -V &5) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
int
main ()
{
;
return 0;
}
_ACEOF
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files a.out a.exe"
# Try to create an executable without -o first, disregard a.out.
# It will help us diagnose broken compilers, and finding out an intuition
# of exeext.
echo "$as_me:$LINENO: checking for C compiler default output" >&5
echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6
ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
(eval $ac_link_default) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; then
# Find the output, starting from the most likely. This scheme is
# not robust to junk in `.', hence go to wildcards (a.*) only as a last
# resort.
# Be careful to initialize this variable, since it used to be cached.
# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
ac_cv_exeext=
for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.*; do
test -f "$ac_file" || continue
case $ac_file in
*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
a.out ) # We found the default executable, but exeext='' is most
# certainly right.
break;;
*.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
# FIXME: I believe we export ac_cv_exeext for Libtool --akim.
export ac_cv_exeext
break;;
* ) break;;
esac
done
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
check \`config.log' for details." >&5
echo "$as_me: error: C compiler cannot create executables
check \`config.log' for details." >&2;}
{ (exit 77); exit 77; }; }
fi
ac_exeext=$ac_cv_exeext
echo "$as_me:$LINENO: result: $ac_file" >&5
echo "${ECHO_T}$ac_file" >&6
# Check the compiler produces executables we can run. If not, either
# the compiler is broken, or we cross compile.
echo "$as_me:$LINENO: checking whether the C compiler works" >&5
echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
# If not cross compiling, check that we can run a simple program.
if test "$cross_compiling" != yes; then
if { ac_try='./$ac_file'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
cross_compiling=no
else
if test "$cross_compiling" = maybe; then
cross_compiling=yes
else
{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
If you meant to cross compile, use \`--host'." >&5
echo "$as_me: error: cannot run C compiled programs.
If you meant to cross compile, use \`--host'." >&2;}
{ (exit 1); exit 1; }; }
fi
fi
fi
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6
rm -f a.out a.exe conftest$ac_cv_exeext
ac_clean_files=$ac_clean_files_save
# Check the compiler produces executables we can run. If not, either
# the compiler is broken, or we cross compile.
echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
echo "$as_me:$LINENO: result: $cross_compiling" >&5
echo "${ECHO_T}$cross_compiling" >&6
echo "$as_me:$LINENO: checking for suffix of executables" >&5
echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; then
# If both `conftest.exe' and `conftest' are `present' (well, observable)
# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
# work properly (i.e., refer to `conftest.exe'), while it won't with
# `rm'.
for ac_file in conftest.exe conftest conftest.*; do
test -f "$ac_file" || continue
case $ac_file in
*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
*.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
export ac_cv_exeext
break;;
* ) break;;
esac
done
else
{ { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link" >&5
echo "$as_me: error: cannot compute suffix of executables: cannot compile and link" >&2;}
{ (exit 1); exit 1; }; }
fi
rm -f conftest$ac_cv_exeext
echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
echo "${ECHO_T}$ac_cv_exeext" >&6
rm -f conftest.$ac_ext
EXEEXT=$ac_cv_exeext
ac_exeext=$EXEEXT
echo "$as_me:$LINENO: checking for suffix of object files" >&5
echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
if test "${ac_cv_objext+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.o conftest.obj
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; then
for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
case $ac_file in
*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
*) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
break;;
esac
done
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile" >&5
echo "$as_me: error: cannot compute suffix of object files: cannot compile" >&2;}
{ (exit 1); exit 1; }; }
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
echo "${ECHO_T}$ac_cv_objext" >&6
OBJEXT=$ac_cv_objext
ac_objext=$OBJEXT
echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
if test "${ac_cv_c_compiler_gnu+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
int
main ()
{
#ifndef __GNUC__
choke me
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_compiler_gnu=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_compiler_gnu=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
ac_cv_c_compiler_gnu=$ac_compiler_gnu
fi
echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
GCC=`test $ac_compiler_gnu = yes && echo yes`
ac_test_CFLAGS=${CFLAGS+set}
ac_save_CFLAGS=$CFLAGS
CFLAGS="-g"
echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
if test "${ac_cv_prog_cc_g+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_prog_cc_g=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_prog_cc_g=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
if test "$ac_test_CFLAGS" = set; then
CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
if test "$GCC" = yes; then
CFLAGS="-g -O2"
else
CFLAGS="-g"
fi
else
if test "$GCC" = yes; then
CFLAGS="-O2"
else
CFLAGS=
fi
fi
echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
if test "${ac_cv_prog_cc_stdc+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_cv_prog_cc_stdc=no
ac_save_CC=$CC
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
#include
#include
#include
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
static char *e (p, i)
char **p;
int i;
{
return p[i];
}
static char *f (char * (*g) (char **, int), char **p, ...)
{
char *s;
va_list v;
va_start (v,p);
s = g (p, va_arg (v,int));
va_end (v);
return s;
}
int test (int i, double x);
struct s1 {int (*f) (int a);};
struct s2 {int (*f) (double a);};
int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
int argc;
char **argv;
int
main ()
{
return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
;
return 0;
}
_ACEOF
# Don't try gcc -ansi; that turns off useful extensions and
# breaks some systems' header files.
# AIX -qlanglvl=ansi
# Ultrix and OSF/1 -std1
# HP-UX 10.20 and later -Ae
# HP-UX older versions -Aa -D_HPUX_SOURCE
# SVR4 -Xc -D__EXTENSIONS__
for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
do
CC="$ac_save_CC $ac_arg"
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_prog_cc_stdc=$ac_arg
break
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext
done
rm -f conftest.$ac_ext conftest.$ac_objext
CC=$ac_save_CC
fi
case "x$ac_cv_prog_cc_stdc" in
x|xno)
echo "$as_me:$LINENO: result: none needed" >&5
echo "${ECHO_T}none needed" >&6 ;;
*)
echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
CC="$CC $ac_cv_prog_cc_stdc" ;;
esac
# Some people use a C++ compiler to compile C. Since we use `exit',
# in C++ we need to declare it. In case someone uses the same compiler
# for both compiling C and C++ we need to have the C++ compiler decide
# the declaration of exit, since it's the most demanding environment.
cat >conftest.$ac_ext <<_ACEOF
#ifndef __cplusplus
choke me
#endif
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
for ac_declaration in \
''\
'#include ' \
'extern "C" void std::exit (int) throw (); using std::exit;' \
'extern "C" void std::exit (int); using std::exit;' \
'extern "C" void exit (int) throw ();' \
'extern "C" void exit (int);' \
'void exit (int);'
do
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
$ac_declaration
int
main ()
{
exit (42);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
:
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
continue
fi
rm -f conftest.$ac_objext conftest.$ac_ext
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
$ac_declaration
int
main ()
{
exit (42);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
break
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext conftest.$ac_ext
done
rm -f conftest*
if test -n "$ac_declaration"; then
echo '#ifdef __cplusplus' >>confdefs.h
echo $ac_declaration >>confdefs.h
echo '#endif' >>confdefs.h
fi
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext conftest.$ac_ext
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
echo "$as_me:$LINENO: checking for library containing strerror" >&5
echo $ECHO_N "checking for library containing strerror... $ECHO_C" >&6
if test "${ac_cv_search_strerror+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_func_search_save_LIBS=$LIBS
ac_cv_search_strerror=no
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char strerror ();
int
main ()
{
strerror ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_search_strerror="none required"
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
if test "$ac_cv_search_strerror" = no; then
for ac_lib in cposix; do
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char strerror ();
int
main ()
{
strerror ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_search_strerror="-l$ac_lib"
break
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
done
fi
LIBS=$ac_func_search_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_search_strerror" >&5
echo "${ECHO_T}$ac_cv_search_strerror" >&6
if test "$ac_cv_search_strerror" != no; then
test "$ac_cv_search_strerror" = "none required" || LIBS="$ac_cv_search_strerror $LIBS"
fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
fi
if test -z "$CPP"; then
if test "${ac_cv_prog_CPP+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
# Double quotes because CPP needs to be expanded
for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
do
ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
# Use a header file that comes with gcc, so configuring glibc
# with a fresh cross-compiler works.
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. "Syntax error" is here to catch this case.
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
Syntax error
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
:
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
# Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.$ac_ext
# OK, works on sane cases. Now check whether non-existent headers
# can be detected and how.
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
# Broken: success on invalid input.
continue
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
# Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.$ac_ext
done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.err conftest.$ac_ext
if $ac_preproc_ok; then
break
fi
done
ac_cv_prog_CPP=$CPP
fi
CPP=$ac_cv_prog_CPP
else
ac_cv_prog_CPP=$CPP
fi
echo "$as_me:$LINENO: result: $CPP" >&5
echo "${ECHO_T}$CPP" >&6
ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
# Use a header file that comes with gcc, so configuring glibc
# with a fresh cross-compiler works.
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. "Syntax error" is here to catch this case.
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
Syntax error
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
:
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
# Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.$ac_ext
# OK, works on sane cases. Now check whether non-existent headers
# can be detected and how.
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
# Broken: success on invalid input.
continue
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
# Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.$ac_ext
done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.err conftest.$ac_ext
if $ac_preproc_ok; then
:
else
{ { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check" >&5
echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check" >&2;}
{ (exit 1); exit 1; }; }
fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
echo "$as_me:$LINENO: checking for egrep" >&5
echo $ECHO_N "checking for egrep... $ECHO_C" >&6
if test "${ac_cv_prog_egrep+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
if echo a | (grep -E '(a|b)') >/dev/null 2>&1
then ac_cv_prog_egrep='grep -E'
else ac_cv_prog_egrep='egrep'
fi
fi
echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
echo "${ECHO_T}$ac_cv_prog_egrep" >&6
EGREP=$ac_cv_prog_egrep
if test $ac_cv_c_compiler_gnu = yes; then
echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5
echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6
if test "${ac_cv_prog_gcc_traditional+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_pattern="Autoconf.*'x'"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
Autoconf TIOCGETP
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "$ac_pattern" >/dev/null 2>&1; then
ac_cv_prog_gcc_traditional=yes
else
ac_cv_prog_gcc_traditional=no
fi
rm -f conftest*
if test $ac_cv_prog_gcc_traditional = no; then
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
Autoconf TCGETA
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "$ac_pattern" >/dev/null 2>&1; then
ac_cv_prog_gcc_traditional=yes
fi
rm -f conftest*
fi
fi
echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5
echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6
if test $ac_cv_prog_gcc_traditional = yes; then
CC="$CC -traditional"
fi
fi
ac_aux_dir=
for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
if test -f $ac_dir/install-sh; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/install-sh -c"
break
elif test -f $ac_dir/install.sh; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/install.sh -c"
break
elif test -f $ac_dir/shtool; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/shtool install -c"
break
fi
done
if test -z "$ac_aux_dir"; then
{ { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
{ (exit 1); exit 1; }; }
fi
ac_config_guess="$SHELL $ac_aux_dir/config.guess"
ac_config_sub="$SHELL $ac_aux_dir/config.sub"
ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
# incompatible versions:
# SysV /etc/install, /usr/sbin/install
# SunOS /usr/etc/install
# IRIX /sbin/install
# AIX /bin/install
# AmigaOS /C/install, which installs bootblocks on floppy discs
# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
if test -z "$INSTALL"; then
if test "${ac_cv_path_install+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
# Account for people who put trailing slashes in PATH elements.
case $as_dir/ in
./ | .// | /cC/* | \
/etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
/usr/ucb/* ) ;;
*)
# OSF1 and SCO ODT 3.0 have their own names for install.
# Don't use installbsd from OSF since it installs stuff as root
# by default.
for ac_prog in ginstall scoinst install; do
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
if test $ac_prog = install &&
grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
:
elif test $ac_prog = install &&
grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# program-specific install script used by HP pwplus--don't use.
:
else
ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
break 3
fi
fi
done
done
;;
esac
done
fi
if test "${ac_cv_path_install+set}" = set; then
INSTALL=$ac_cv_path_install
else
# As a last resort, use the slow shell script. We don't cache a
# path for INSTALL within a source directory, because that will
# break other packages using the cache if that directory is
# removed, or if the path is relative.
INSTALL=$ac_install_sh
fi
fi
echo "$as_me:$LINENO: result: $INSTALL" >&5
echo "${ECHO_T}$INSTALL" >&6
# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
# It thinks the first close brace ends the variable substitution.
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
# Checks for compilation model.
# Check whether --enable-largefile or --disable-largefile was given.
if test "${enable_largefile+set}" = set; then
enableval="$enable_largefile"
fi;
if test "$enable_largefile" != no; then
echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5
echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6
if test "${ac_cv_sys_largefile_CC+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_cv_sys_largefile_CC=no
if test "$GCC" != yes; then
ac_save_CC=$CC
while :; do
# IRIX 6.2 and later do not support large files by default,
# so use the C compiler's -n32 option if that helps.
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
/* Check that off_t can represent 2**63 - 1 correctly.
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
break
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext
CC="$CC -n32"
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_sys_largefile_CC=' -n32'; break
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext
break
done
CC=$ac_save_CC
rm -f conftest.$ac_ext
fi
fi
echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5
echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6
if test "$ac_cv_sys_largefile_CC" != no; then
CC=$CC$ac_cv_sys_largefile_CC
fi
echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5
echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6
if test "${ac_cv_sys_file_offset_bits+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
while :; do
ac_cv_sys_file_offset_bits=no
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
/* Check that off_t can represent 2**63 - 1 correctly.
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
break
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext conftest.$ac_ext
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#define _FILE_OFFSET_BITS 64
#include
/* Check that off_t can represent 2**63 - 1 correctly.
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_sys_file_offset_bits=64; break
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext conftest.$ac_ext
break
done
fi
echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5
echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6
if test "$ac_cv_sys_file_offset_bits" != no; then
cat >>confdefs.h <<_ACEOF
#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
_ACEOF
fi
rm -f conftest*
echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5
echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6
if test "${ac_cv_sys_large_files+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
while :; do
ac_cv_sys_large_files=no
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
/* Check that off_t can represent 2**63 - 1 correctly.
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
break
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext conftest.$ac_ext
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#define _LARGE_FILES 1
#include
/* Check that off_t can represent 2**63 - 1 correctly.
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_sys_large_files=1; break
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext conftest.$ac_ext
break
done
fi
echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5
echo "${ECHO_T}$ac_cv_sys_large_files" >&6
if test "$ac_cv_sys_large_files" != no; then
cat >>confdefs.h <<_ACEOF
#define _LARGE_FILES $ac_cv_sys_large_files
_ACEOF
fi
rm -f conftest*
fi
# Checks for general libraries.
echo "$as_me:$LINENO: checking for initscr in -lxcurses" >&5
echo $ECHO_N "checking for initscr in -lxcurses... $ECHO_C" >&6
if test "${ac_cv_lib_xcurses_initscr+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lxcurses $LIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char initscr ();
int
main ()
{
initscr ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_xcurses_initscr=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_lib_xcurses_initscr=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_xcurses_initscr" >&5
echo "${ECHO_T}$ac_cv_lib_xcurses_initscr" >&6
if test $ac_cv_lib_xcurses_initscr = yes; then
have_xcurses=yes
else
have_xcurses=no
fi
echo "$as_me:$LINENO: checking for initscr in -lncurses" >&5
echo $ECHO_N "checking for initscr in -lncurses... $ECHO_C" >&6
if test "${ac_cv_lib_ncurses_initscr+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lncurses $LIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char initscr ();
int
main ()
{
initscr ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_ncurses_initscr=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_lib_ncurses_initscr=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_ncurses_initscr" >&5
echo "${ECHO_T}$ac_cv_lib_ncurses_initscr" >&6
if test $ac_cv_lib_ncurses_initscr = yes; then
have_ncurses=yes
else
have_ncurses=no
fi
echo "$as_me:$LINENO: checking for initscr in -lcurses" >&5
echo $ECHO_N "checking for initscr in -lcurses... $ECHO_C" >&6
if test "${ac_cv_lib_curses_initscr+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lcurses $LIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char initscr ();
int
main ()
{
initscr ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_curses_initscr=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_lib_curses_initscr=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_curses_initscr" >&5
echo "${ECHO_T}$ac_cv_lib_curses_initscr" >&6
if test $ac_cv_lib_curses_initscr = yes; then
have_curses=yes
else
have_curses=no
fi
echo "$as_me:$LINENO: checking for tgetent in -ltermcap" >&5
echo $ECHO_N "checking for tgetent in -ltermcap... $ECHO_C" >&6
if test "${ac_cv_lib_termcap_tgetent+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-ltermcap $LIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char tgetent ();
int
main ()
{
tgetent ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_termcap_tgetent=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_lib_termcap_tgetent=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_termcap_tgetent" >&5
echo "${ECHO_T}$ac_cv_lib_termcap_tgetent" >&6
if test $ac_cv_lib_termcap_tgetent = yes; then
have_termcap=yes
else
have_termcap=no
fi
echo "$as_me:$LINENO: checking for tgetent in -ltermlib" >&5
echo $ECHO_N "checking for tgetent in -ltermlib... $ECHO_C" >&6
if test "${ac_cv_lib_termlib_tgetent+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-ltermlib $LIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char tgetent ();
int
main ()
{
tgetent ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_termlib_tgetent=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_lib_termlib_tgetent=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_termlib_tgetent" >&5
echo "${ECHO_T}$ac_cv_lib_termlib_tgetent" >&6
if test $ac_cv_lib_termlib_tgetent = yes; then
have_termlib=yes
else
have_termlib=no
fi
# Regular expressions (regcmp) are in -lgen on Solaris 2,
# and in -lintl on SCO Unix.
echo "$as_me:$LINENO: checking for regcmp in -lgen" >&5
echo $ECHO_N "checking for regcmp in -lgen... $ECHO_C" >&6
if test "${ac_cv_lib_gen_regcmp+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lgen $LIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char regcmp ();
int
main ()
{
regcmp ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_gen_regcmp=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_lib_gen_regcmp=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_gen_regcmp" >&5
echo "${ECHO_T}$ac_cv_lib_gen_regcmp" >&6
if test $ac_cv_lib_gen_regcmp = yes; then
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBGEN 1
_ACEOF
LIBS="-lgen $LIBS"
fi
echo "$as_me:$LINENO: checking for regcmp in -lintl" >&5
echo $ECHO_N "checking for regcmp in -lintl... $ECHO_C" >&6
if test "${ac_cv_lib_intl_regcmp+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lintl $LIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char regcmp ();
int
main ()
{
regcmp ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_intl_regcmp=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_lib_intl_regcmp=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_intl_regcmp" >&5
echo "${ECHO_T}$ac_cv_lib_intl_regcmp" >&6
if test $ac_cv_lib_intl_regcmp = yes; then
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBINTL 1
_ACEOF
LIBS="-lintl $LIBS"
fi
echo "$as_me:$LINENO: checking for regcmp in -lPW" >&5
echo $ECHO_N "checking for regcmp in -lPW... $ECHO_C" >&6
if test "${ac_cv_lib_PW_regcmp+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lPW $LIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char regcmp ();
int
main ()
{
regcmp ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_PW_regcmp=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_lib_PW_regcmp=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_PW_regcmp" >&5
echo "${ECHO_T}$ac_cv_lib_PW_regcmp" >&6
if test $ac_cv_lib_PW_regcmp = yes; then
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBPW 1
_ACEOF
LIBS="-lPW $LIBS"
fi
# Checks for terminal libraries
echo "$as_me:$LINENO: checking for working terminal libraries" >&5
echo $ECHO_N "checking for working terminal libraries... $ECHO_C" >&6
TERMLIBS=
# Check for systems where curses is broken.
curses_broken=0
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
# -- Try xcurses.
if test "x$TERMLIBS" = x; then
if test $have_xcurses = yes; then
TERMLIBS="-lxcurses"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
int
main ()
{
tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
termok=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
termok=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
# -- Try ncurses.
if test "x$TERMLIBS" = x; then
if test $have_ncurses = yes; then
TERMLIBS="-lncurses"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
int
main ()
{
tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
termok=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
termok=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
# -- Try curses.
if test "x$TERMLIBS" = x; then
if test $have_curses = yes; then
TERMLIBS="-lcurses"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
int
main ()
{
tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
termok=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
termok=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
# -- Try curses & termcap.
if test "x$TERMLIBS" = x; then
if test $have_curses = yes; then
if test $have_termcap = yes; then
TERMLIBS="-lcurses -ltermcap"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
int
main ()
{
tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
termok=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
termok=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
fi
fi
# -- Try termcap.
if test "x$TERMLIBS" = x; then
if test $have_termcap = yes; then
TERMLIBS="-ltermcap"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
int
main ()
{
tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
termok=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
termok=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
# -- Try termlib.
if test "x$TERMLIBS" = x; then
if test $have_termlib = yes; then
TERMLIBS="-lcurses -ltermlib"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
int
main ()
{
tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
termok=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
termok=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
if test "x$TERMLIBS" = x; then
echo "$as_me:$LINENO: result: Cannot find terminal libraries - configure failed" >&5
echo "${ECHO_T}Cannot find terminal libraries - configure failed" >&6
exit 1
fi
echo "$as_me:$LINENO: result: using $TERMLIBS" >&5
echo "${ECHO_T}using $TERMLIBS" >&6
LIBS="$LIBS $TERMLIBS"
# Checks for header files.
echo "$as_me:$LINENO: checking for ANSI C header files" >&5
echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
if test "${ac_cv_header_stdc+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
#include
#include
#include
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
ac_cv_header_stdc=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_header_stdc=no
fi
rm -f conftest.err conftest.$ac_ext
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "memchr" >/dev/null 2>&1; then
:
else
ac_cv_header_stdc=no
fi
rm -f conftest*
fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "free" >/dev/null 2>&1; then
:
else
ac_cv_header_stdc=no
fi
rm -f conftest*
fi
if test $ac_cv_header_stdc = yes; then
# /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
if test "$cross_compiling" = yes; then
:
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
#if ((' ' & 0x0FF) == 0x020)
# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#else
# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \
|| ('j' <= (c) && (c) <= 'r') \
|| ('s' <= (c) && (c) <= 'z'))
# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
#endif
#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
int
main ()
{
int i;
for (i = 0; i < 256; i++)
if (XOR (islower (i), ISLOWER (i))
|| toupper (i) != TOUPPER (i))
exit(2);
exit (0);
}
_ACEOF
rm -f conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
:
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
( exit $ac_status )
ac_cv_header_stdc=no
fi
rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
fi
fi
echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
echo "${ECHO_T}$ac_cv_header_stdc" >&6
if test $ac_cv_header_stdc = yes; then
cat >>confdefs.h <<\_ACEOF
#define STDC_HEADERS 1
_ACEOF
fi
# On IRIX 5.3, sys/types and inttypes.h are conflicting.
for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
inttypes.h stdint.h unistd.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
$ac_includes_default
#include <$ac_header>
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
eval "$as_ac_Header=yes"
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
eval "$as_ac_Header=no"
fi
rm -f conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
if test `eval echo '${'$as_ac_Header'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
fi
done
for ac_header in ctype.h errno.h fcntl.h limits.h stdio.h stdlib.h string.h termcap.h termio.h termios.h time.h unistd.h values.h sys/ioctl.h sys/stream.h sys/ptem.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
else
# Is the header compilable?
echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
$ac_includes_default
#include <$ac_header>
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_header_compiler=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6
# Is the header present?
echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include <$ac_header>
_ACEOF
if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
(eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
ac_cpp_err=$ac_c_preproc_warn_flag
else
ac_cpp_err=
fi
else
ac_cpp_err=yes
fi
if test -z "$ac_cpp_err"; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6
# So? What about this header?
case $ac_header_compiler:$ac_header_preproc in
yes:no )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
no:yes )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};;
esac
echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
if eval "test \"\${$as_ac_Header+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
eval "$as_ac_Header=$ac_header_preproc"
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
fi
if test `eval echo '${'$as_ac_Header'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
fi
done
# Checks for typedefs, structures, and compiler characteristics.
echo "$as_me:$LINENO: checking whether stat file-mode macros are broken" >&5
echo $ECHO_N "checking whether stat file-mode macros are broken... $ECHO_C" >&6
if test "${ac_cv_header_stat_broken+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
#include
#if defined(S_ISBLK) && defined(S_IFDIR)
# if S_ISBLK (S_IFDIR)
You lose.
# endif
#endif
#if defined(S_ISBLK) && defined(S_IFCHR)
# if S_ISBLK (S_IFCHR)
You lose.
# endif
#endif
#if defined(S_ISLNK) && defined(S_IFREG)
# if S_ISLNK (S_IFREG)
You lose.
# endif
#endif
#if defined(S_ISSOCK) && defined(S_IFREG)
# if S_ISSOCK (S_IFREG)
You lose.
# endif
#endif
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "You lose" >/dev/null 2>&1; then
ac_cv_header_stat_broken=yes
else
ac_cv_header_stat_broken=no
fi
rm -f conftest*
fi
echo "$as_me:$LINENO: result: $ac_cv_header_stat_broken" >&5
echo "${ECHO_T}$ac_cv_header_stat_broken" >&6
if test $ac_cv_header_stat_broken = yes; then
cat >>confdefs.h <<\_ACEOF
#define STAT_MACROS_BROKEN 1
_ACEOF
fi
echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6
if test "${ac_cv_c_const+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
int
main ()
{
/* FIXME: Include the comments suggested by Paul. */
#ifndef __cplusplus
/* Ultrix mips cc rejects this. */
typedef int charset[2];
const charset x;
/* SunOS 4.1.1 cc rejects this. */
char const *const *ccp;
char **p;
/* NEC SVR4.0.2 mips cc rejects this. */
struct point {int x, y;};
static struct point const zero = {0,0};
/* AIX XL C 1.02.0.0 rejects this.
It does not let you subtract one const X* pointer from another in
an arm of an if-expression whose if-part is not a constant
expression */
const char *g = "string";
ccp = &g + (g ? g-g : 0);
/* HPUX 7.0 cc rejects these. */
++ccp;
p = (char**) ccp;
ccp = (char const *const *) p;
{ /* SCO 3.2v4 cc rejects this. */
char *t;
char const *s = 0 ? (char *) 0 : (char const *) 0;
*t++ = 0;
}
{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
int x[] = {25, 17};
const int *foo = &x[0];
++foo;
}
{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
typedef const int *iptr;
iptr p = 0;
++p;
}
{ /* AIX XL C 1.02.0.0 rejects this saying
"k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
struct s { int j; const int *ap[3]; };
struct s *b; b->j = 5;
}
{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
const int foo = 10;
}
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_c_const=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_c_const=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5
echo "${ECHO_T}$ac_cv_c_const" >&6
if test $ac_cv_c_const = no; then
cat >>confdefs.h <<\_ACEOF
#define const
_ACEOF
fi
echo "$as_me:$LINENO: checking for off_t" >&5
echo $ECHO_N "checking for off_t... $ECHO_C" >&6
if test "${ac_cv_type_off_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
$ac_includes_default
int
main ()
{
if ((off_t *) 0)
return 0;
if (sizeof (off_t))
return 0;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_type_off_t=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_type_off_t=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
echo "${ECHO_T}$ac_cv_type_off_t" >&6
if test $ac_cv_type_off_t = yes; then
:
else
cat >>confdefs.h <<_ACEOF
#define off_t long
_ACEOF
fi
echo "$as_me:$LINENO: checking for size_t" >&5
echo $ECHO_N "checking for size_t... $ECHO_C" >&6
if test "${ac_cv_type_size_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
$ac_includes_default
int
main ()
{
if ((size_t *) 0)
return 0;
if (sizeof (size_t))
return 0;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_type_size_t=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_type_size_t=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
echo "${ECHO_T}$ac_cv_type_size_t" >&6
if test $ac_cv_type_size_t = yes; then
:
else
cat >>confdefs.h <<_ACEOF
#define size_t unsigned
_ACEOF
fi
echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6
if test "${ac_cv_header_time+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
#include
#include
int
main ()
{
if ((struct tm *) 0)
return 0;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_header_time=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_header_time=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
echo "${ECHO_T}$ac_cv_header_time" >&6
if test $ac_cv_header_time = yes; then
cat >>confdefs.h <<\_ACEOF
#define TIME_WITH_SYS_TIME 1
_ACEOF
fi
# Autoheader templates for symbols defined later by AC_DEFINE.
# Checks for identifiers.
echo "$as_me:$LINENO: checking for off_t" >&5
echo $ECHO_N "checking for off_t... $ECHO_C" >&6
if test "${ac_cv_type_off_t+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
$ac_includes_default
int
main ()
{
if ((off_t *) 0)
return 0;
if (sizeof (off_t))
return 0;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_type_off_t=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_type_off_t=no
fi
rm -f conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5
echo "${ECHO_T}$ac_cv_type_off_t" >&6
if test $ac_cv_type_off_t = yes; then
:
else
cat >>confdefs.h <<_ACEOF
#define off_t long
_ACEOF
fi
echo "$as_me:$LINENO: checking for void" >&5
echo $ECHO_N "checking for void... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
int
main ()
{
void *foo = 0;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_VOID 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: checking for const" >&5
echo $ECHO_N "checking for const... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
int
main ()
{
const int foo = 0;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_CONST 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.$ac_objext conftest.$ac_ext
echo "$as_me:$LINENO: checking for time_t" >&5
echo $ECHO_N "checking for time_t... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
int
main ()
{
time_t t = 0;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_TIME_T 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.$ac_objext conftest.$ac_ext
# Checks for library functions.
echo "$as_me:$LINENO: checking return type of signal handlers" >&5
echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6
if test "${ac_cv_type_signal+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
#include
#ifdef signal
# undef signal
#endif
#ifdef __cplusplus
extern "C" void (*signal (int, void (*)(int)))(int);
#else
void (*signal ()) ();
#endif
int
main ()
{
int i;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest.$ac_objext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_type_signal=void
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_type_signal=int
fi
rm -f conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5
echo "${ECHO_T}$ac_cv_type_signal" >&6
cat >>confdefs.h <<_ACEOF
#define RETSIGTYPE $ac_cv_type_signal
_ACEOF
for ac_func in fsync memcpy popen _setjmp sigprocmask sigsetmask stat strchr strstr system
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
if eval "test \"\${$as_ac_var+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func (); below. */
#include
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char $ac_func ();
char (*f) ();
int
main ()
{
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
choke me
#else
f = $ac_func;
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
eval "$as_ac_var=yes"
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
eval "$as_ac_var=no"
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
if test `eval echo '${'$as_ac_var'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
# Some systems have termios.h but not the corresponding functions.
echo "$as_me:$LINENO: checking for tcgetattr" >&5
echo $ECHO_N "checking for tcgetattr... $ECHO_C" >&6
if test "${ac_cv_func_tcgetattr+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char tcgetattr (); below. */
#include
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char tcgetattr ();
char (*f) ();
int
main ()
{
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_tcgetattr) || defined (__stub___tcgetattr)
choke me
#else
f = tcgetattr;
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_func_tcgetattr=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_func_tcgetattr=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_func_tcgetattr" >&5
echo "${ECHO_T}$ac_cv_func_tcgetattr" >&6
if test $ac_cv_func_tcgetattr = yes; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_TERMIOS_FUNCS 1
_ACEOF
fi
echo "$as_me:$LINENO: checking for fileno" >&5
echo $ECHO_N "checking for fileno... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#if HAVE_STDIO_H
#include
#endif
int
main ()
{
static int x; x = fileno(stdin);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_FILENO 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
echo "$as_me:$LINENO: checking for strerror" >&5
echo $ECHO_N "checking for strerror... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#if HAVE_STDIO_H
#include
#endif
#if HAVE_STRING_H
#include
#endif
#if HAVE_ERRNO_H
#include
#endif
int
main ()
{
static char *x; x = strerror(0);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_STRERROR 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
echo "$as_me:$LINENO: checking for sys_errlist" >&5
echo $ECHO_N "checking for sys_errlist... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
int
main ()
{
extern char *sys_errlist[]; static char **x; x = sys_errlist;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_SYS_ERRLIST 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
echo "$as_me:$LINENO: checking for sigset_t" >&5
echo $ECHO_N "checking for sigset_t... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
int
main ()
{
sigset_t s; s = 0;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_SIGSET_T 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
echo "$as_me:$LINENO: checking for sigemptyset" >&5
echo $ECHO_N "checking for sigemptyset... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
int
main ()
{
sigset_t s; sigemptyset(&s);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_SIGEMPTYSET 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
have_errno=no
echo "$as_me:$LINENO: checking for errno" >&5
echo $ECHO_N "checking for errno... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#if HAVE_ERRNO_H
#include
#endif
int
main ()
{
static int x; x = errno;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes - in errno.h" >&5
echo "${ECHO_T}yes - in errno.h" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_ERRNO 1
_ACEOF
have_errno=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
if test $have_errno = no; then
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#if HAVE_ERRNO_H
#include
#endif
int
main ()
{
extern int errno; static int x; x = errno;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes - must define" >&5
echo "${ECHO_T}yes - must define" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_ERRNO 1
_ACEOF
cat >>confdefs.h <<\_ACEOF
#define MUST_DEFINE_ERRNO 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: checking for locale" >&5
echo $ECHO_N "checking for locale... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
#include
int
main ()
{
setlocale(LC_CTYPE,""); isprint(0); iscntrl(0);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_LOCALE 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
echo "$as_me:$LINENO: checking for ctype functions" >&5
echo $ECHO_N "checking for ctype functions... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#if HAVE_CTYPE_H
#include
#endif
int
main ()
{
static int x; x = isupper(x); x = tolower(x); x = toupper(x);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes" >&5
echo "${ECHO_T}yes" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_UPPER_LOWER 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
# Checks for external variable ospeed in the termcap library.
have_ospeed=no
echo "$as_me:$LINENO: checking termcap for ospeed" >&5
echo $ECHO_N "checking termcap for ospeed... $ECHO_C" >&6
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
#if HAVE_TERMIOS_H
#include
#endif
#if HAVE_TERMCAP_H
#include
#endif
int
main ()
{
ospeed = 0;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes - in termcap.h" >&5
echo "${ECHO_T}yes - in termcap.h" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_OSPEED 1
_ACEOF
have_ospeed=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
if test $have_ospeed = no; then
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
int
main ()
{
extern short ospeed; ospeed = 0;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: yes - must define" >&5
echo "${ECHO_T}yes - must define" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_OSPEED 1
_ACEOF
cat >>confdefs.h <<\_ACEOF
#define MUST_DEFINE_OSPEED 1
_ACEOF
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
fi
# Checks for regular expression functions.
have_regex=no
have_posix_regex=unknown
echo "$as_me:$LINENO: checking for regcomp" >&5
echo $ECHO_N "checking for regcomp... $ECHO_C" >&6
WANT_REGEX=auto
# Check whether --with-regex or --without-regex was given.
if test "${with_regex+set}" = set; then
withval="$with_regex"
WANT_REGEX="$withval"
fi;
if test $have_regex = no; then
if test $WANT_REGEX = auto -o $WANT_REGEX = posix; then
# Some versions of Solaris have a regcomp() function, but it doesn't work!
# So we run a test program. If we're cross-compiling, do it the old way.
if test "$cross_compiling" = yes; then
have_posix_regex=unknown
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
#include
main() { regex_t r; regmatch_t rm; char *text = "xabcy";
if (regcomp(&r, "abc", 0)) exit(1);
if (regexec(&r, text, 1, &rm, 0)) exit(1);
#ifndef __WATCOMC__
if (rm.rm_so != 1) exit(1); /* check for correct offset */
#else
if (rm.rm_sp != text + 1) exit(1); /* check for correct offset */
#endif
exit(0); }
_ACEOF
rm -f conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && { ac_try='./conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
have_posix_regex=yes
else
echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
( exit $ac_status )
have_posix_regex=no
fi
rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
if test $have_posix_regex = yes; then
echo "$as_me:$LINENO: result: using POSIX regcomp" >&5
echo "${ECHO_T}using POSIX regcomp" >&6
cat >>confdefs.h <<\_ACEOF
#define HAVE_POSIX_REGCOMP 1
_ACEOF
have_regex=yes
elif test $have_posix_regex = unknown; then
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include
#include
int
main ()
{
regex_t *r; regfree(r);
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: using POSIX regcomp" >&5
echo "${ECHO_T}using POSIX regcomp" >&6
cat >>confdefs.h <<\_ACEOF
#define HAVE_POSIX_REGCOMP 1
_ACEOF
have_regex=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
fi
fi
if test $have_regex = no; then
if test $WANT_REGEX = auto -o $WANT_REGEX = pcre; then
echo "$as_me:$LINENO: checking for pcre_compile in -lpcre" >&5
echo $ECHO_N "checking for pcre_compile in -lpcre... $ECHO_C" >&6
if test "${ac_cv_lib_pcre_pcre_compile+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lpcre $LIBS"
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char pcre_compile ();
int
main ()
{
pcre_compile ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_pcre_pcre_compile=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_lib_pcre_pcre_compile=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_pcre_pcre_compile" >&5
echo "${ECHO_T}$ac_cv_lib_pcre_pcre_compile" >&6
if test $ac_cv_lib_pcre_pcre_compile = yes; then
echo "$as_me:$LINENO: result: using pcre" >&5
echo "${ECHO_T}using pcre" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_PCRE 1
_ACEOF
LIBS="$LIBS -lpcre" have_regex=yes
fi
fi
fi
if test $have_regex = no; then
if test $WANT_REGEX = auto -o $WANT_REGEX = regcmp; then
echo "$as_me:$LINENO: checking for regcmp" >&5
echo $ECHO_N "checking for regcmp... $ECHO_C" >&6
if test "${ac_cv_func_regcmp+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char regcmp (); below. */
#include
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char regcmp ();
char (*f) ();
int
main ()
{
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_regcmp) || defined (__stub___regcmp)
choke me
#else
f = regcmp;
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_func_regcmp=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_func_regcmp=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_func_regcmp" >&5
echo "${ECHO_T}$ac_cv_func_regcmp" >&6
if test $ac_cv_func_regcmp = yes; then
echo "$as_me:$LINENO: result: using regcmp" >&5
echo "${ECHO_T}using regcmp" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_REGCMP 1
_ACEOF
have_regex=yes
fi
fi
fi
if test $have_regex = no; then
if test $WANT_REGEX = auto -o $WANT_REGEX = regcomp; then
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
#include "regexp.h"
int
main ()
{
regcomp("");
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
echo "$as_me:$LINENO: result: using V8 regcomp" >&5
echo "${ECHO_T}using V8 regcomp" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_V8_REGCOMP 1
_ACEOF
have_regex=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
fi
fi
if test $have_regex = no && test -f ${srcdir}/regexp.c; then
if test $WANT_REGEX = auto -o $WANT_REGEX = regcomp-local; then
echo "$as_me:$LINENO: result: using V8 regcomp -- local source" >&5
echo "${ECHO_T}using V8 regcomp -- local source" >&6; cat >>confdefs.h <<\_ACEOF
#define HAVE_V8_REGCOMP 1
_ACEOF
cat >>confdefs.h <<\_ACEOF
#define HAVE_REGEXEC2 1
_ACEOF
REGEX_O='regexp.$(O)' have_regex=yes
fi
fi
if test $have_regex = no; then
if test $WANT_REGEX = auto -o $WANT_REGEX = re_comp; then
echo "$as_me:$LINENO: result: using re_comp" >&5
echo "${ECHO_T}using re_comp" >&6; echo "$as_me:$LINENO: checking for re_comp" >&5
echo $ECHO_N "checking for re_comp... $ECHO_C" >&6
if test "${ac_cv_func_re_comp+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
#line $LINENO "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char re_comp (); below. */
#include
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char re_comp ();
char (*f) ();
int
main ()
{
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_re_comp) || defined (__stub___re_comp)
choke me
#else
f = re_comp;
#endif
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_func_re_comp=yes
else
echo "$as_me: failed program was:" >&5
cat conftest.$ac_ext >&5
ac_cv_func_re_comp=no
fi
rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_func_re_comp" >&5
echo "${ECHO_T}$ac_cv_func_re_comp" >&6
if test $ac_cv_func_re_comp = yes; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_RE_COMP 1
_ACEOF
have_regex=yes
fi
fi
fi
if test $have_regex = no; then
echo "$as_me:$LINENO: result: cannot find regular expression library" >&5
echo "${ECHO_T}cannot find regular expression library" >&6; cat >>confdefs.h <<\_ACEOF
#define NO_REGEX 1
_ACEOF
fi
# Check whether --with-editor or --without-editor was given.
if test "${with_editor+set}" = set; then
withval="$with_editor"
cat >>confdefs.h <<_ACEOF
#define EDIT_PGM "$withval"
_ACEOF
else
cat >>confdefs.h <<\_ACEOF
#define EDIT_PGM "vi"
_ACEOF
fi;
ac_config_files="$ac_config_files Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs, see configure's option --config-cache.
# It is not useful on other systems. If it contains results you don't
# want to keep, you may remove or edit it.
#
# config.status only pays attention to the cache file if you give it
# the --recheck option to rerun configure.
#
# `ac_cv_env_foo' variables (set or unset) will be overridden when
# loading this file, other *unset* `ac_cv_foo' will be assigned the
# following values.
_ACEOF
# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, don't put newlines in cache variables' values.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
{
(set) 2>&1 |
case `(ac_space=' '; set | grep ac_space) 2>&1` in
*ac_space=\ *)
# `set' does not quote correctly, so add quotes (double-quote
# substitution turns \\\\ into \\, and sed turns \\ into \).
sed -n \
"s/'/'\\\\''/g;
s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
;;
*)
# `set' quotes correctly as required by POSIX, so do not add quotes.
sed -n \
"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
;;
esac;
} |
sed '
t clear
: clear
s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
t end
/^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
: end' >>confcache
if cmp -s $cache_file confcache; then :; else
if test -w $cache_file; then
test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
cat confcache >$cache_file
else
echo "not updating unwritable cache $cache_file"
fi
fi
rm -f confcache
test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
# VPATH may cause trouble with some makes, so we remove $(srcdir),
# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
# trailing colons and then remove the whole line if VPATH becomes empty
# (actually we leave an empty line to preserve line numbers).
if test "x$srcdir" = x.; then
ac_vpsub='/^[ ]*VPATH[ ]*=/{
s/:*\$(srcdir):*/:/;
s/:*\${srcdir}:*/:/;
s/:*@srcdir@:*/:/;
s/^\([^=]*=[ ]*\):*/\1/;
s/:*$//;
s/^[^=]*=[ ]*$//;
}'
fi
DEFS=-DHAVE_CONFIG_H
ac_libobjs=
ac_ltlibobjs=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
# 1. Remove the extension, and $U if already installed.
ac_i=`echo "$ac_i" |
sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
# 2. Add them.
ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
done
LIBOBJS=$ac_libobjs
LTLIBOBJS=$ac_ltlibobjs
: ${CONFIG_STATUS=./config.status}
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files $CONFIG_STATUS"
{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
echo "$as_me: creating $CONFIG_STATUS" >&6;}
cat >$CONFIG_STATUS <<_ACEOF
#! $SHELL
# Generated by $as_me.
# Run this file to recreate the current configuration.
# Compiler output produced by configure, useful for debugging
# configure, is in config.log if it exists.
debug=false
SHELL=\${CONFIG_SHELL-$SHELL}
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
## --------------------- ##
## M4sh Initialization. ##
## --------------------- ##
# Be Bourne compatible
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
emulate sh
NULLCMD=:
# Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
set -o posix
fi
# Support unset when possible.
if (FOO=FOO; unset FOO) >/dev/null 2>&1; then
as_unset=unset
else
as_unset=false
fi
# Work around bugs in pre-3.0 UWIN ksh.
$as_unset ENV MAIL MAILPATH
PS1='$ '
PS2='> '
PS4='+ '
# NLS nuisances.
for as_var in LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE LC_NUMERIC LC_MESSAGES LC_TIME
do
if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then
eval $as_var=C; export $as_var
else
$as_unset $as_var
fi
done
# Required to use basename.
if expr a : '\(a\)' >/dev/null 2>&1; then
as_expr=expr
else
as_expr=false
fi
if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
as_basename=basename
else
as_basename=false
fi
# Name of the executable.
as_me=`$as_basename "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)$' \| \
. : '\(.\)' 2>/dev/null ||
echo X/"$0" |
sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
/^X\/\(\/\/\)$/{ s//\1/; q; }
/^X\/\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
# PATH needs CR, and LINENO needs CR and PATH.
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
echo "#! /bin/sh" >conftest.sh
echo "exit 0" >>conftest.sh
chmod +x conftest.sh
if (PATH="/nonexistent;."; conftest.sh) >/dev/null 2>&1; then
PATH_SEPARATOR=';'
else
PATH_SEPARATOR=:
fi
rm -f conftest.sh
fi
as_lineno_1=$LINENO
as_lineno_2=$LINENO
as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
test "x$as_lineno_1" != "x$as_lineno_2" &&
test "x$as_lineno_3" = "x$as_lineno_2" || {
# Find who we are. Look in the path if we contain no path at all
# relative or not.
case $0 in
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
done
;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
as_myself=$0
fi
if test ! -f "$as_myself"; then
{ { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
{ (exit 1); exit 1; }; }
fi
case $CONFIG_SHELL in
'')
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for as_base in sh bash ksh sh5; do
case $as_dir in
/*)
if ("$as_dir/$as_base" -c '
as_lineno_1=$LINENO
as_lineno_2=$LINENO
as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
test "x$as_lineno_1" != "x$as_lineno_2" &&
test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
$as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
$as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
CONFIG_SHELL=$as_dir/$as_base
export CONFIG_SHELL
exec "$CONFIG_SHELL" "$0" ${1+"$@"}
fi;;
esac
done
done
;;
esac
# Create $as_me.lineno as a copy of $as_myself, but with $LINENO
# uniformly replaced by the line number. The first 'sed' inserts a
# line-number line before each line; the second 'sed' does the real
# work. The second script uses 'N' to pair each line-number line
# with the numbered line, and appends trailing '-' during
# substitution so that $LINENO is not a special case at line end.
# (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
# second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
sed '=' <$as_myself |
sed '
N
s,$,-,
: loop
s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
t loop
s,-$,,
s,^['$as_cr_digits']*\n,,
' >$as_me.lineno &&
chmod +x $as_me.lineno ||
{ { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
{ (exit 1); exit 1; }; }
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensible to this).
. ./$as_me.lineno
# Exit status is that of the last command.
exit
}
case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
*c*,-n*) ECHO_N= ECHO_C='
' ECHO_T=' ' ;;
*c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
*) ECHO_N= ECHO_C='\c' ECHO_T= ;;
esac
if expr a : '\(a\)' >/dev/null 2>&1; then
as_expr=expr
else
as_expr=false
fi
rm -f conf$$ conf$$.exe conf$$.file
echo >conf$$.file
if ln -s conf$$.file conf$$ 2>/dev/null; then
# We could just check for DJGPP; but this test a) works b) is more generic
# and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
if test -f conf$$.exe; then
# Don't use ln at all; we don't have any links
as_ln_s='cp -p'
else
as_ln_s='ln -s'
fi
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
as_ln_s='cp -p'
fi
rm -f conf$$ conf$$.exe conf$$.file
if mkdir -p . 2>/dev/null; then
as_mkdir_p=:
else
as_mkdir_p=false
fi
as_executable_p="test -f"
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g"
# Sed expression to map a string onto a valid variable name.
as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g"
# IFS
# We need space, tab and new line, in precisely that order.
as_nl='
'
IFS=" $as_nl"
# CDPATH.
$as_unset CDPATH
exec 6>&1
# Open the log real soon, to keep \$[0] and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. Logging --version etc. is OK.
exec 5>>config.log
{
echo
sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
## Running $as_me. ##
_ASBOX
} >&5
cat >&5 <<_CSEOF
This file was extended by less $as_me 1, which was
generated by GNU Autoconf 2.54. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
CONFIG_LINKS = $CONFIG_LINKS
CONFIG_COMMANDS = $CONFIG_COMMANDS
$ $0 $@
_CSEOF
echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
echo >&5
_ACEOF
# Files that config.status was made for.
if test -n "$ac_config_files"; then
echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
fi
if test -n "$ac_config_headers"; then
echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
fi
if test -n "$ac_config_links"; then
echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
fi
if test -n "$ac_config_commands"; then
echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
fi
cat >>$CONFIG_STATUS <<\_ACEOF
ac_cs_usage="\
\`$as_me' instantiates files from templates according to the
current configuration.
Usage: $0 [OPTIONS] [FILE]...
-h, --help print this help, then exit
-V, --version print version number, then exit
-d, --debug don't remove temporary files
--recheck update $as_me by reconfiguring in the same conditions
--file=FILE[:TEMPLATE]
instantiate the configuration file FILE
--header=FILE[:TEMPLATE]
instantiate the configuration header FILE
Configuration files:
$config_files
Configuration headers:
$config_headers
Report bugs to ."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
less config.status 1
configured by $0, generated by GNU Autoconf 2.54,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
srcdir=$srcdir
INSTALL="$INSTALL"
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
# If no file are specified by the user, then we need to provide default
# value. By we need to know if files were specified by the user.
ac_need_defaults=:
while test $# != 0
do
case $1 in
--*=*)
ac_option=`expr "x$1" : 'x\([^=]*\)='`
ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
ac_shift=:
;;
-*)
ac_option=$1
ac_optarg=$2
ac_shift=shift
;;
*) # This is not an option, so the user has probably given explicit
# arguments.
ac_option=$1
ac_need_defaults=false;;
esac
case $ac_option in
# Handling of the options.
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
echo "running $SHELL $0 " $ac_configure_args " --no-create --no-recursion"
exec $SHELL $0 $ac_configure_args --no-create --no-recursion ;;
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
--version | --vers* | -V )
echo "$ac_cs_version"; exit 0 ;;
--he | --h)
# Conflict between --help and --header
{ { echo "$as_me:$LINENO: error: ambiguous option: $1
Try \`$0 --help' for more information." >&5
echo "$as_me: error: ambiguous option: $1
Try \`$0 --help' for more information." >&2;}
{ (exit 1); exit 1; }; };;
--help | --hel | -h )
echo "$ac_cs_usage"; exit 0 ;;
--debug | --d* | -d )
debug=: ;;
--file | --fil | --fi | --f )
$ac_shift
CONFIG_FILES="$CONFIG_FILES $ac_optarg"
ac_need_defaults=false;;
--header | --heade | --head | --hea )
$ac_shift
CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
ac_need_defaults=false;;
# This is an error.
-*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
Try \`$0 --help' for more information." >&5
echo "$as_me: error: unrecognized option: $1
Try \`$0 --help' for more information." >&2;}
{ (exit 1); exit 1; }; } ;;
*) ac_config_targets="$ac_config_targets $1" ;;
esac
shift
done
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
for ac_config_target in $ac_config_targets
do
case "$ac_config_target" in
# Handling of arguments.
"Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"defines.h" ) CONFIG_HEADERS="$CONFIG_HEADERS defines.h" ;;
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
{ (exit 1); exit 1; }; };;
esac
done
# If the user did not use the arguments to specify the items to instantiate,
# then the envvar interface is used. Set only those that are not.
# We use the long form for the default assignment because of an extremely
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
fi
# Create a temporary directory, and hook for its removal unless debugging.
$debug ||
{
trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
trap '{ (exit 1); exit 1; }' 1 2 13 15
}
# Create a (secure) tmp directory for tmp files.
: ${TMPDIR=/tmp}
{
tmp=`(umask 077 && mktemp -d -q "$TMPDIR/csXXXXXX") 2>/dev/null` &&
test -n "$tmp" && test -d "$tmp"
} ||
{
tmp=$TMPDIR/cs$$-$RANDOM
(umask 077 && mkdir $tmp)
} ||
{
echo "$me: cannot create a temporary directory in $TMPDIR" >&2
{ (exit 1); exit 1; }
}
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
#
# CONFIG_FILES section.
#
# No need to generate the scripts if there are no CONFIG_FILES.
# This happens for instance when ./config.status config.h
if test -n "\$CONFIG_FILES"; then
# Protect against being on the right side of a sed subst in config.status.
sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
s,@SHELL@,$SHELL,;t t
s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
s,@exec_prefix@,$exec_prefix,;t t
s,@prefix@,$prefix,;t t
s,@program_transform_name@,$program_transform_name,;t t
s,@bindir@,$bindir,;t t
s,@sbindir@,$sbindir,;t t
s,@libexecdir@,$libexecdir,;t t
s,@datadir@,$datadir,;t t
s,@sysconfdir@,$sysconfdir,;t t
s,@sharedstatedir@,$sharedstatedir,;t t
s,@localstatedir@,$localstatedir,;t t
s,@libdir@,$libdir,;t t
s,@includedir@,$includedir,;t t
s,@oldincludedir@,$oldincludedir,;t t
s,@infodir@,$infodir,;t t
s,@mandir@,$mandir,;t t
s,@build_alias@,$build_alias,;t t
s,@host_alias@,$host_alias,;t t
s,@target_alias@,$target_alias,;t t
s,@DEFS@,$DEFS,;t t
s,@ECHO_C@,$ECHO_C,;t t
s,@ECHO_N@,$ECHO_N,;t t
s,@ECHO_T@,$ECHO_T,;t t
s,@LIBS@,$LIBS,;t t
s,@CC@,$CC,;t t
s,@CFLAGS@,$CFLAGS,;t t
s,@LDFLAGS@,$LDFLAGS,;t t
s,@CPPFLAGS@,$CPPFLAGS,;t t
s,@ac_ct_CC@,$ac_ct_CC,;t t
s,@EXEEXT@,$EXEEXT,;t t
s,@OBJEXT@,$OBJEXT,;t t
s,@CPP@,$CPP,;t t
s,@EGREP@,$EGREP,;t t
s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
s,@INSTALL_DATA@,$INSTALL_DATA,;t t
s,@REGEX_O@,$REGEX_O,;t t
s,@LIBOBJS@,$LIBOBJS,;t t
s,@LTLIBOBJS@,$LTLIBOBJS,;t t
CEOF
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
# Split the substitutions into bite-sized pieces for seds with
# small command number limits, like on Digital OSF/1 and HP-UX.
ac_max_sed_lines=48
ac_sed_frag=1 # Number of current file.
ac_beg=1 # First line for current file.
ac_end=$ac_max_sed_lines # Line after last line for current file.
ac_more_lines=:
ac_sed_cmds=
while $ac_more_lines; do
if test $ac_beg -gt 1; then
sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
else
sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
fi
if test ! -s $tmp/subs.frag; then
ac_more_lines=false
else
# The purpose of the label and of the branching condition is to
# speed up the sed processing (if there are no `@' at all, there
# is no need to browse any of the substitutions).
# These are the two extra sed commands mentioned above.
(echo ':t
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
if test -z "$ac_sed_cmds"; then
ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
else
ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
fi
ac_sed_frag=`expr $ac_sed_frag + 1`
ac_beg=$ac_end
ac_end=`expr $ac_end + $ac_max_sed_lines`
fi
done
if test -z "$ac_sed_cmds"; then
ac_sed_cmds=cat
fi
fi # test -n "$CONFIG_FILES"
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case $ac_file in
- | *:- | *:-:* ) # input from stdin
cat >$tmp/stdin
ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
*:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
* ) ac_file_in=$ac_file.in ;;
esac
# Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
ac_dir=`(dirname "$ac_file") 2>/dev/null ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$ac_file" : 'X\(//\)[^/]' \| \
X"$ac_file" : 'X\(//\)$' \| \
X"$ac_file" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$ac_file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
{ if $as_mkdir_p; then
mkdir -p "$ac_dir"
else
as_dir="$ac_dir"
as_dirs=
while test ! -d "$as_dir"; do
as_dirs="$as_dir $as_dirs"
as_dir=`(dirname "$as_dir") 2>/dev/null ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$as_dir" : 'X\(//\)[^/]' \| \
X"$as_dir" : 'X\(//\)$' \| \
X"$as_dir" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
done
test ! -n "$as_dirs" || mkdir $as_dirs
fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
{ (exit 1); exit 1; }; }; }
ac_builddir=.
if test "$ac_dir" != .; then
ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
# A "../" for each directory in $ac_dir_suffix.
ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
else
ac_dir_suffix= ac_top_builddir=
fi
case $srcdir in
.) # No --srcdir option. We are building in place.
ac_srcdir=.
if test -z "$ac_top_builddir"; then
ac_top_srcdir=.
else
ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
fi ;;
[\\/]* | ?:[\\/]* ) # Absolute path.
ac_srcdir=$srcdir$ac_dir_suffix;
ac_top_srcdir=$srcdir ;;
*) # Relative path.
ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
ac_top_srcdir=$ac_top_builddir$srcdir ;;
esac
# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be
# absolute.
ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd`
ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd`
ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd`
ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd`
case $INSTALL in
[\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
*) ac_INSTALL=$ac_top_builddir$INSTALL ;;
esac
if test x"$ac_file" != x-; then
{ echo "$as_me:$LINENO: creating $ac_file" >&5
echo "$as_me: creating $ac_file" >&6;}
rm -f "$ac_file"
fi
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
if test x"$ac_file" = x-; then
configure_input=
else
configure_input="$ac_file. "
fi
configure_input=$configure_input"Generated from `echo $ac_file_in |
sed 's,.*/,,'` by configure."
# First look for the input files in the build tree, otherwise in the
# src tree.
ac_file_inputs=`IFS=:
for f in $ac_file_in; do
case $f in
-) echo $tmp/stdin ;;
[\\/$]*)
# Absolute (can't be DOS-style, as IFS=:)
test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
echo $f;;
*) # Relative
if test -f "$f"; then
# Build tree
echo $f
elif test -f "$srcdir/$f"; then
# Source tree
echo $srcdir/$f
else
# /dev/null tree
{ { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
fi;;
esac
done` || { (exit 1); exit 1; }
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
sed "$ac_vpsub
$extrasub
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
:t
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
s,@configure_input@,$configure_input,;t t
s,@srcdir@,$ac_srcdir,;t t
s,@abs_srcdir@,$ac_abs_srcdir,;t t
s,@top_srcdir@,$ac_top_srcdir,;t t
s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
s,@builddir@,$ac_builddir,;t t
s,@abs_builddir@,$ac_abs_builddir,;t t
s,@top_builddir@,$ac_top_builddir,;t t
s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
s,@INSTALL@,$ac_INSTALL,;t t
" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
rm -f $tmp/stdin
if test x"$ac_file" != x-; then
mv $tmp/out $ac_file
else
cat $tmp/out
rm -f $tmp/out
fi
done
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
#
# CONFIG_HEADER section.
#
# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
# NAME is the cpp macro being defined and VALUE is the value it is being given.
#
# ac_d sets the value in "#define NAME VALUE" lines.
ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
ac_dB='[ ].*$,\1#\2'
ac_dC=' '
ac_dD=',;t'
# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
ac_uB='$,\1#\2define\3'
ac_uC=' '
ac_uD=',;t'
for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case $ac_file in
- | *:- | *:-:* ) # input from stdin
cat >$tmp/stdin
ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
*:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
* ) ac_file_in=$ac_file.in ;;
esac
test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
echo "$as_me: creating $ac_file" >&6;}
# First look for the input files in the build tree, otherwise in the
# src tree.
ac_file_inputs=`IFS=:
for f in $ac_file_in; do
case $f in
-) echo $tmp/stdin ;;
[\\/$]*)
# Absolute (can't be DOS-style, as IFS=:)
test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
echo $f;;
*) # Relative
if test -f "$f"; then
# Build tree
echo $f
elif test -f "$srcdir/$f"; then
# Source tree
echo $srcdir/$f
else
# /dev/null tree
{ { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
fi;;
esac
done` || { (exit 1); exit 1; }
# Remove the trailing spaces.
sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
_ACEOF
# Transform confdefs.h into two sed scripts, `conftest.defines' and
# `conftest.undefs', that substitutes the proper values into
# config.h.in to produce config.h. The first handles `#define'
# templates, and the second `#undef' templates.
# And first: Protect against being on the right side of a sed subst in
# config.status. Protect against being in an unquoted here document
# in config.status.
rm -f conftest.defines conftest.undefs
# Using a here document instead of a string reduces the quoting nightmare.
# Putting comments in sed scripts is not portable.
#
# `end' is used to avoid that the second main sed command (meant for
# 0-ary CPP macros) applies to n-ary macro definitions.
# See the Autoconf documentation for `clear'.
cat >confdef2sed.sed <<\_ACEOF
s/[\\&,]/\\&/g
s,[\\$`],\\&,g
t clear
: clear
s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
t end
s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
: end
_ACEOF
# If some macros were called several times there might be several times
# the same #defines, which is useless. Nevertheless, we may not want to
# sort them, since we want the *last* AC-DEFINE to be honored.
uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
rm -f confdef2sed.sed
# This sed command replaces #undef with comments. This is necessary, for
# example, in the case of _POSIX_SOURCE, which is predefined and required
# on some systems where configure will not decide to define it.
cat >>conftest.undefs <<\_ACEOF
s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
_ACEOF
# Break up conftest.defines because some shells have a limit on the size
# of here documents, and old seds have small limits too (100 cmds).
echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
echo ' :' >>$CONFIG_STATUS
rm -f conftest.tail
while grep . conftest.defines >/dev/null
do
# Write a limited-size here document to $tmp/defines.sed.
echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS
# Speed up: don't consider the non `#define' lines.
echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS
# Work around the forget-to-reset-the-flag bug.
echo 't clr' >>$CONFIG_STATUS
echo ': clr' >>$CONFIG_STATUS
sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
echo 'CEOF
sed -f $tmp/defines.sed $tmp/in >$tmp/out
rm -f $tmp/in
mv $tmp/out $tmp/in
' >>$CONFIG_STATUS
sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
rm -f conftest.defines
mv conftest.tail conftest.defines
done
rm -f conftest.defines
echo ' fi # grep' >>$CONFIG_STATUS
echo >>$CONFIG_STATUS
# Break up conftest.undefs because some shells have a limit on the size
# of here documents, and old seds have small limits too (100 cmds).
echo ' # Handle all the #undef templates' >>$CONFIG_STATUS
rm -f conftest.tail
while grep . conftest.undefs >/dev/null
do
# Write a limited-size here document to $tmp/undefs.sed.
echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS
# Speed up: don't consider the non `#undef'
echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS
# Work around the forget-to-reset-the-flag bug.
echo 't clr' >>$CONFIG_STATUS
echo ': clr' >>$CONFIG_STATUS
sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
echo 'CEOF
sed -f $tmp/undefs.sed $tmp/in >$tmp/out
rm -f $tmp/in
mv $tmp/out $tmp/in
' >>$CONFIG_STATUS
sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
rm -f conftest.undefs
mv conftest.tail conftest.undefs
done
rm -f conftest.undefs
cat >>$CONFIG_STATUS <<\_ACEOF
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
if test x"$ac_file" = x-; then
echo "/* Generated by configure. */" >$tmp/config.h
else
echo "/* $ac_file. Generated by configure. */" >$tmp/config.h
fi
cat $tmp/in >>$tmp/config.h
rm -f $tmp/in
if test x"$ac_file" != x-; then
if cmp -s $ac_file $tmp/config.h 2>/dev/null; then
{ echo "$as_me:$LINENO: $ac_file is unchanged" >&5
echo "$as_me: $ac_file is unchanged" >&6;}
else
ac_dir=`(dirname "$ac_file") 2>/dev/null ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$ac_file" : 'X\(//\)[^/]' \| \
X"$ac_file" : 'X\(//\)$' \| \
X"$ac_file" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$ac_file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
{ if $as_mkdir_p; then
mkdir -p "$ac_dir"
else
as_dir="$ac_dir"
as_dirs=
while test ! -d "$as_dir"; do
as_dirs="$as_dir $as_dirs"
as_dir=`(dirname "$as_dir") 2>/dev/null ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$as_dir" : 'X\(//\)[^/]' \| \
X"$as_dir" : 'X\(//\)$' \| \
X"$as_dir" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
done
test ! -n "$as_dirs" || mkdir $as_dirs
fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
{ (exit 1); exit 1; }; }; }
rm -f $ac_file
mv $tmp/config.h $ac_file
fi
else
cat $tmp/config.h
rm -f $tmp/config.h
fi
done
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
{ (exit 0); exit 0; }
_ACEOF
chmod +x $CONFIG_STATUS
ac_clean_files=$ac_clean_files_save
# configure is writing to config.log, and then calls config.status.
# config.status does its own redirection, appending to config.log.
# Unfortunately, on DOS this fails, as config.log is still kept open
# by configure, so config.status won't be able to write to it; its
# output is simply discarded. So we exec the FD to /dev/null,
# effectively closing config.log, so it can be properly (re)opened and
# appended to by config.status. When coming back to configure, we
# need to make the FD available again.
if test "$no_create" != yes; then
ac_cs_success=:
exec 5>/dev/null
$SHELL $CONFIG_STATUS || ac_cs_success=false
exec 5>>config.log
# Use ||, not &&, to avoid exiting from the if with $? = 1, which
# would make configure fail if this is the last instruction.
$ac_cs_success || { (exit 1); exit 1; }
fi
less-382/configure.ac 0100444 0000764 0000764 00000040060 10010075212 013621 0 ustar markn markn # Process this file with autoconf to produce a configure script.
# Copyright (C) 1984-2002 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.
# Autoconf initialization.
AC_INIT(less, 1)
AC_CONFIG_SRCDIR([forwback.c])
AC_CONFIG_HEADER([defines.h])
# Checks for programs.
AC_PROG_CC
AC_ISC_POSIX
AC_PROG_GCC_TRADITIONAL
AC_PROG_INSTALL
# Checks for compilation model.
AC_SYS_LARGEFILE
# Checks for general libraries.
AC_CHECK_LIB(xcurses, initscr, [have_xcurses=yes], [have_xcurses=no])
AC_CHECK_LIB(ncurses, initscr, [have_ncurses=yes], [have_ncurses=no])
AC_CHECK_LIB(curses, initscr, [have_curses=yes], [have_curses=no])
AC_CHECK_LIB(termcap, tgetent, [have_termcap=yes], [have_termcap=no])
AC_CHECK_LIB(termlib, tgetent, [have_termlib=yes], [have_termlib=no])
# Regular expressions (regcmp) are in -lgen on Solaris 2,
# and in -lintl on SCO Unix.
AC_CHECK_LIB(gen, regcmp)
AC_CHECK_LIB(intl, regcmp)
AC_CHECK_LIB(PW, regcmp)
# Checks for terminal libraries
AC_MSG_CHECKING([for working terminal libraries])
TERMLIBS=
# Check for systems where curses is broken.
curses_broken=0
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
# -- Try xcurses.
if test "x$TERMLIBS" = x; then
if test $have_xcurses = yes; then
TERMLIBS="-lxcurses"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
# -- Try ncurses.
if test "x$TERMLIBS" = x; then
if test $have_ncurses = yes; then
TERMLIBS="-lncurses"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
# -- Try curses.
if test "x$TERMLIBS" = x; then
if test $have_curses = yes; then
TERMLIBS="-lcurses"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
# -- Try curses & termcap.
if test "x$TERMLIBS" = x; then
if test $have_curses = yes; then
if test $have_termcap = yes; then
TERMLIBS="-lcurses -ltermcap"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
fi
fi
# -- Try termcap.
if test "x$TERMLIBS" = x; then
if test $have_termcap = yes; then
TERMLIBS="-ltermcap"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
# -- Try termlib.
if test "x$TERMLIBS" = x; then
if test $have_termlib = yes; then
TERMLIBS="-lcurses -ltermlib"
SAVE_LIBS=$LIBS
LIBS="$LIBS $TERMLIBS"
AC_TRY_LINK(, [tgetent(0,0); tgetflag(0); tgetnum(0); tgetstr(0,0);],
[termok=yes], [termok=no])
LIBS=$SAVE_LIBS
if test $termok = no; then TERMLIBS=""; fi
fi
fi
if test "x$TERMLIBS" = x; then
AC_MSG_RESULT(Cannot find terminal libraries - configure failed)
exit 1
fi
AC_MSG_RESULT(using $TERMLIBS)
LIBS="$LIBS $TERMLIBS"
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([ctype.h errno.h fcntl.h limits.h stdio.h stdlib.h string.h termcap.h termio.h termios.h time.h unistd.h values.h sys/ioctl.h sys/stream.h sys/ptem.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STAT
AC_C_CONST
AC_TYPE_OFF_T
AC_TYPE_SIZE_T
AC_HEADER_TIME
# Autoheader templates for symbols defined later by AC_DEFINE.
AH_TEMPLATE([HAVE_POSIX_REGCOMP],
[POSIX regcomp() and regex.h])
AH_TEMPLATE([HAVE_PCRE],
[PCRE (Perl-compatible regular expression) library])
AH_TEMPLATE([HAVE_RE_COMP],
[BSD re_comp()])
AH_TEMPLATE([HAVE_REGCMP],
[System V regcmp()])
AH_TEMPLATE([HAVE_V8_REGCOMP],
[Henry Spencer V8 regcomp() and regexp.h])
AH_TEMPLATE([NO_REGEX],
[pattern matching is supported, but without metacharacters.])
AH_TEMPLATE([HAVE_REGEXEC2],
[])
AH_TEMPLATE([HAVE_VOID],
[Define HAVE_VOID if your compiler supports the "void" type.])
AH_TEMPLATE([HAVE_CONST],
[Define HAVE_CONST if your compiler supports the "const" modifier.])
AH_TEMPLATE([HAVE_TIME_T],
[Define HAVE_TIME_T if your system supports the "time_t" type.])
AH_TEMPLATE([HAVE_STRERROR],
[Define HAVE_STRERROR if you have the strerror() function.])
AH_TEMPLATE([HAVE_FILENO],
[Define HAVE_FILENO if you have the fileno() macro.])
AH_TEMPLATE([HAVE_ERRNO],
[Define HAVE_ERRNO if you have the errno variable.])
AH_TEMPLATE([MUST_DEFINE_ERRNO],
[Define MUST_DEFINE_ERRNO if you have errno but it is not define in errno.h.])
AH_TEMPLATE([HAVE_SYS_ERRLIST],
[Define HAVE_SYS_ERRLIST if you have the sys_errlist[] variable.])
AH_TEMPLATE([HAVE_OSPEED],
[Define HAVE_OSPEED if your termcap library has the ospeed variable.])
AH_TEMPLATE([MUST_DEFINE_OSPEED],
[Define MUST_DEFINE_OSPEED if you have ospeed but it is not defined in termcap.h.])
AH_TEMPLATE([HAVE_LOCALE],
[Define HAVE_LOCALE if you have locale.h and setlocale.])
AH_TEMPLATE([HAVE_TERMIOS_FUNCS],
[Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr.])
AH_TEMPLATE([HAVE_UPPER_LOWER],
[Define HAVE_UPPER_LOWER if you have isupper, islower, toupper, tolower.])
AH_TEMPLATE([HAVE_SIGSET_T],
[Define HAVE_SIGSET_T you have the sigset_t type.])
AH_TEMPLATE([HAVE_SIGEMPTYSET],
[Define HAVE_SIGEMPTYSET if you have the sigemptyset macro.])
AH_TEMPLATE([EDIT_PGM],
[Define EDIT_PGM to your editor.])
# Checks for identifiers.
AC_TYPE_OFF_T
AC_MSG_CHECKING(for void)
AC_TRY_COMPILE(, [void *foo = 0;],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_VOID)], [AC_MSG_RESULT(no)])
AC_MSG_CHECKING(for const)
AC_TRY_COMPILE(, [const int foo = 0;],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_CONST)], [AC_MSG_RESULT(no)])
AC_MSG_CHECKING(for time_t)
AC_TRY_COMPILE([#include ], [time_t t = 0;],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_TIME_T)], [AC_MSG_RESULT(no)])
# Checks for library functions.
AC_TYPE_SIGNAL
AC_CHECK_FUNCS([fsync memcpy popen _setjmp sigprocmask sigsetmask stat strchr strstr system])
# Some systems have termios.h but not the corresponding functions.
AC_CHECK_FUNC(tcgetattr, AC_DEFINE(HAVE_TERMIOS_FUNCS))
AC_MSG_CHECKING(for fileno)
AC_TRY_LINK([
#if HAVE_STDIO_H
#include
#endif], [static int x; x = fileno(stdin);],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_FILENO)], [AC_MSG_RESULT(no)])
AC_MSG_CHECKING(for strerror)
AC_TRY_LINK([
#if HAVE_STDIO_H
#include
#endif
#if HAVE_STRING_H
#include
#endif
#if HAVE_ERRNO_H
#include
#endif], [static char *x; x = strerror(0);],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_STRERROR)], [AC_MSG_RESULT(no)])
AC_MSG_CHECKING(for sys_errlist)
AC_TRY_LINK(, [extern char *sys_errlist[]; static char **x; x = sys_errlist;],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYS_ERRLIST)], [AC_MSG_RESULT(no)])
AC_MSG_CHECKING(for sigset_t)
AC_TRY_LINK([
#include
], [sigset_t s; s = 0;],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SIGSET_T)], [AC_MSG_RESULT(no)])
AC_MSG_CHECKING(for sigemptyset)
AC_TRY_LINK([
#include
], [sigset_t s; sigemptyset(&s);],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SIGEMPTYSET)], [AC_MSG_RESULT(no)])
have_errno=no
AC_MSG_CHECKING(for errno)
AC_TRY_LINK([
#if HAVE_ERRNO_H
#include
#endif], [static int x; x = errno;],
[AC_MSG_RESULT(yes - in errno.h); AC_DEFINE(HAVE_ERRNO) have_errno=yes])
if test $have_errno = no; then
AC_TRY_LINK([
#if HAVE_ERRNO_H
#include
#endif], [extern int errno; static int x; x = errno;],
[AC_MSG_RESULT(yes - must define); AC_DEFINE(HAVE_ERRNO) AC_DEFINE(MUST_DEFINE_ERRNO)],
[AC_MSG_RESULT(no)])
fi
AC_MSG_CHECKING(for locale)
AC_TRY_LINK([#include
#include ], [setlocale(LC_CTYPE,""); isprint(0); iscntrl(0);],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_LOCALE)], [AC_MSG_RESULT(no)])
AC_MSG_CHECKING(for ctype functions)
AC_TRY_LINK([
#if HAVE_CTYPE_H
#include
#endif], [static int x; x = isupper(x); x = tolower(x); x = toupper(x);],
[AC_MSG_RESULT(yes); AC_DEFINE(HAVE_UPPER_LOWER)], [AC_MSG_RESULT(no)])
# Checks for external variable ospeed in the termcap library.
have_ospeed=no
AC_MSG_CHECKING(termcap for ospeed)
AC_TRY_LINK([
#include
#if HAVE_TERMIOS_H
#include
#endif
#if HAVE_TERMCAP_H
#include
#endif], [ospeed = 0;],
[AC_MSG_RESULT(yes - in termcap.h); AC_DEFINE(HAVE_OSPEED) have_ospeed=yes])
if test $have_ospeed = no; then
AC_TRY_LINK(, [extern short ospeed; ospeed = 0;],
[AC_MSG_RESULT(yes - must define); AC_DEFINE(HAVE_OSPEED) AC_DEFINE(MUST_DEFINE_OSPEED)],
[AC_MSG_RESULT(no)])
fi
# Checks for regular expression functions.
have_regex=no
have_posix_regex=unknown
AC_MSG_CHECKING(for regcomp)
WANT_REGEX=auto
AC_ARG_WITH(regex,
[ --with-regex={auto,pcre,posix,regcmp,re_comp,regcomp,regcomp-local} Select a regular expression library [auto]],
WANT_REGEX="$withval")
if test $have_regex = no; then
if test $WANT_REGEX = auto -o $WANT_REGEX = posix; then
# Some versions of Solaris have a regcomp() function, but it doesn't work!
# So we run a test program. If we're cross-compiling, do it the old way.
AC_TRY_RUN([
#include
#include
main() { regex_t r; regmatch_t rm; char *text = "xabcy";
if (regcomp(&r, "abc", 0)) exit(1);
if (regexec(&r, text, 1, &rm, 0)) exit(1);
#ifndef __WATCOMC__
if (rm.rm_so != 1) exit(1); /* check for correct offset */
#else
if (rm.rm_sp != text + 1) exit(1); /* check for correct offset */
#endif
exit(0); }],
have_posix_regex=yes, have_posix_regex=no, have_posix_regex=unknown)
if test $have_posix_regex = yes; then
AC_MSG_RESULT(using POSIX regcomp)
AC_DEFINE(HAVE_POSIX_REGCOMP)
have_regex=yes
elif test $have_posix_regex = unknown; then
AC_TRY_LINK([
#include
#include ],
[regex_t *r; regfree(r);],
AC_MSG_RESULT(using POSIX regcomp)
AC_DEFINE(HAVE_POSIX_REGCOMP) have_regex=yes)
else
AC_MSG_RESULT(no)
fi
fi
fi
if test $have_regex = no; then
if test $WANT_REGEX = auto -o $WANT_REGEX = pcre; then
AC_CHECK_LIB(pcre, pcre_compile,
[AC_MSG_RESULT(using pcre); AC_DEFINE(HAVE_PCRE) LIBS="$LIBS -lpcre" have_regex=yes], [])
fi
fi
if test $have_regex = no; then
if test $WANT_REGEX = auto -o $WANT_REGEX = regcmp; then
AC_CHECK_FUNC(regcmp,
AC_MSG_RESULT(using regcmp); AC_DEFINE(HAVE_REGCMP) have_regex=yes)
fi
fi
if test $have_regex = no; then
if test $WANT_REGEX = auto -o $WANT_REGEX = regcomp; then
AC_TRY_LINK([
#include "regexp.h"], [regcomp("");],
AC_MSG_RESULT(using V8 regcomp); AC_DEFINE(HAVE_V8_REGCOMP) have_regex=yes)
fi
fi
if test $have_regex = no && test -f ${srcdir}/regexp.c; then
if test $WANT_REGEX = auto -o $WANT_REGEX = regcomp-local; then
AC_MSG_RESULT(using V8 regcomp -- local source); AC_DEFINE(HAVE_V8_REGCOMP) AC_DEFINE(HAVE_REGEXEC2) REGEX_O='regexp.$(O)' AC_SUBST(REGEX_O) have_regex=yes
fi
fi
if test $have_regex = no; then
if test $WANT_REGEX = auto -o $WANT_REGEX = re_comp; then
AC_MSG_RESULT(using re_comp); AC_CHECK_FUNC(re_comp, AC_DEFINE(HAVE_RE_COMP) have_regex=yes)
fi
fi
if test $have_regex = no; then
AC_MSG_RESULT(cannot find regular expression library); AC_DEFINE(NO_REGEX)
fi
AC_ARG_WITH(editor,
[ --with-editor=PROGRAM use PROGRAM as the default editor [vi]],
AC_DEFINE_UNQUOTED(EDIT_PGM, "$withval"), AC_DEFINE(EDIT_PGM, "vi"))
AH_TOP([
/* Unix definition file for less. -*- C -*-
*
* This file has 3 sections:
* User preferences.
* Settings always true on Unix.
* Settings automatically determined by configure.
*
* * * * * * WARNING * * * * * *
* If you edit defines.h by hand, do "touch stamp-h" before you run make
* so config.status doesn't overwrite your changes.
*/
/* User preferences. */
/*
* SECURE is 1 if you wish to disable a bunch of features in order to
* be safe to run by unprivileged users.
*/
#define SECURE 0
/*
* SHELL_ESCAPE is 1 if you wish to allow shell escapes.
* (This is possible only if your system supplies the system() function.)
*/
#define SHELL_ESCAPE (!SECURE)
/*
* EXAMINE is 1 if you wish to allow examining files by name from within less.
*/
#define EXAMINE (!SECURE)
/*
* TAB_COMPLETE_FILENAME is 1 if you wish to allow the TAB key
* to complete filenames at prompts.
*/
#define TAB_COMPLETE_FILENAME (!SECURE)
/*
* CMD_HISTORY is 1 if you wish to allow keys to cycle through
* previous commands at prompts.
*/
#define CMD_HISTORY 1
/*
* HILITE_SEARCH is 1 if you wish to have search targets to be
* displayed in standout mode.
*/
#define HILITE_SEARCH 1
/*
* EDITOR is 1 if you wish to allow editor invocation (the "v" command).
* (This is possible only if your system supplies the system() function.)
* EDIT_PGM is the name of the (default) editor to be invoked.
*/
#define EDITOR (!SECURE)
/*
* TAGS is 1 if you wish to support tag files.
*/
#define TAGS (!SECURE)
/*
* USERFILE is 1 if you wish to allow a .less file to specify
* user-defined key bindings.
*/
#define USERFILE (!SECURE)
/*
* GLOB is 1 if you wish to have shell metacharacters expanded in filenames.
* This will generally work if your system provides the "popen" function
* and the "echo" shell command.
*/
#define GLOB (!SECURE)
/*
* PIPEC is 1 if you wish to have the "|" command
* which allows the user to pipe data into a shell command.
*/
#define PIPEC (!SECURE)
/*
* LOGFILE is 1 if you wish to allow the -l option (to create log files).
*/
#define LOGFILE (!SECURE)
/*
* GNU_OPTIONS is 1 if you wish to support the GNU-style command
* line options --help and --version.
*/
#define GNU_OPTIONS 1
/*
* ONLY_RETURN is 1 if you want RETURN to be the only input which
* will continue past an error message.
* Otherwise, any key will continue past an error message.
*/
#define ONLY_RETURN 0
/*
* LESSKEYFILE is the filename of the default lesskey output file
* (in the HOME directory).
* LESSKEYFILE_SYS is the filename of the system-wide lesskey output file.
* DEF_LESSKEYINFILE is the filename of the default lesskey input
* (in the HOME directory).
*/
#define LESSKEYFILE ".less"
#define LESSKEYFILE_SYS SYSDIR "/sysless"
#define DEF_LESSKEYINFILE ".lesskey"
/* Settings always true on Unix. */
/*
* Define MSDOS_COMPILER if compiling under Microsoft C.
*/
#define MSDOS_COMPILER 0
/*
* Pathname separator character.
*/
#define PATHNAME_SEP "/"
/*
* HAVE_SYS_TYPES_H is 1 if your system has .
*/
#define HAVE_SYS_TYPES_H 1
/*
* Define if you have the header file.
*/
#undef HAVE_SGSTAT_H
/*
* HAVE_PERROR is 1 if your system has the perror() call.
* (Actually, if it has sys_errlist, sys_nerr and errno.)
*/
#define HAVE_PERROR 1
/*
* HAVE_TIME is 1 if your system has the time() call.
*/
#define HAVE_TIME 1
/*
* HAVE_SHELL is 1 if your system supports a SHELL command interpreter.
*/
#define HAVE_SHELL 1
/*
* Default shell metacharacters and meta-escape character.
*/
#define DEF_METACHARS "; *?\t\n'\"()<>|&^`#\\"
#define DEF_METAESCAPE "\\"
/*
* HAVE_DUP is 1 if your system has the dup() call.
*/
#define HAVE_DUP 1
/*
* Sizes of various buffers.
*/
#define CMDBUF_SIZE 512 /* Buffer for multichar commands */
#define UNGOT_SIZE 100 /* Max chars to unget() */
#define LINEBUF_SIZE 1024 /* Max size of line in input file */
#define OUTBUF_SIZE 1024 /* Output buffer */
#define PROMPT_SIZE 200 /* Max size of prompt string */
#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. */
])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
less-382/lesskey.c 0100444 0000764 0000764 00000042226 10010075213 013165 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* lesskey [-o output] [input]
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Make a .less file.
* If no input file is specified, standard input is used.
* If no output file is specified, $HOME/.less is used.
*
* The .less file is used to specify (to "less") user-defined
* key bindings. Basically any sequence of 1 to MAX_CMDLEN
* keystrokes may be bound to an existing less function.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* The input file is an ascii file consisting of a
* sequence of lines of the form:
* string action [chars]
*
* "string" is a sequence of command characters which form
* the new user-defined command. The command
* characters may be:
* 1. The actual character itself.
* 2. A character preceded by ^ to specify a
* control character (e.g. ^X means control-X).
* 3. A backslash followed by one to three octal digits
* to specify a character by its octal value.
* 4. A backslash followed by b, e, n, r or t
* to specify \b, ESC, \n, \r or \t, respectively.
* 5. Any character (other than those mentioned above) preceded
* by a \ to specify the character itself (characters which
* must be preceded by \ include ^, \, and whitespace.
* "action" is the name of a "less" action, from the table below.
* "chars" is an optional sequence of characters which is treated
* as keyboard input after the command is executed.
*
* Blank lines and lines which start with # are ignored,
* except for the special control lines:
* #command Signals the beginning of the command
* keys section.
* #line-edit Signals the beginning of the line-editing
* keys section.
* #env Signals the beginning of the environment
* variable section.
* #stop Stops command parsing in less;
* causes all default keys to be disabled.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* The output file is a non-ascii file, consisting of a header,
* one or more sections, and a trailer.
* Each section begins with a section header, a section length word
* and the section data. Normally there are three sections:
* CMD_SECTION Definition of command keys.
* EDIT_SECTION Definition of editing keys.
* END_SECTION A special section header, with no
* length word or section data.
*
* Section data consists of zero or more byte sequences of the form:
* string <0>
* or
* string <0> chars <0>
*
* "string" is the command string.
* "<0>" is one null byte.
* "" is one byte containing the action code (the A_xxx value).
* If action is ORed with A_EXTRA, the action byte is followed
* by the null-terminated "chars" string.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
#include "less.h"
#include "lesskey.h"
#include "cmd.h"
struct cmdname
{
char *cn_name;
int cn_action;
};
struct cmdname cmdnames[] =
{
{ "back-bracket", A_B_BRACKET },
{ "back-line", A_B_LINE },
{ "back-line-force", A_BF_LINE },
{ "back-screen", A_B_SCREEN },
{ "back-scroll", A_B_SCROLL },
{ "back-search", A_B_SEARCH },
{ "back-window", A_B_WINDOW },
{ "debug", A_DEBUG },
{ "digit", A_DIGIT },
{ "display-flag", A_DISP_OPTION },
{ "display-option", A_DISP_OPTION },
{ "end", A_GOEND },
{ "examine", A_EXAMINE },
{ "first-cmd", A_FIRSTCMD },
{ "firstcmd", A_FIRSTCMD },
{ "flush-repaint", A_FREPAINT },
{ "forw-bracket", A_F_BRACKET },
{ "forw-forever", A_F_FOREVER },
{ "forw-line", A_F_LINE },
{ "forw-line-force", A_FF_LINE },
{ "forw-screen", A_F_SCREEN },
{ "forw-screen-force", A_FF_SCREEN },
{ "forw-scroll", A_F_SCROLL },
{ "forw-search", A_F_SEARCH },
{ "forw-window", A_F_WINDOW },
{ "goto-end", A_GOEND },
{ "goto-line", A_GOLINE },
{ "goto-mark", A_GOMARK },
{ "help", A_HELP },
{ "index-file", A_INDEX_FILE },
{ "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 },
{ "repeat-search-all", A_T_AGAIN_SEARCH },
{ "reverse-search", A_REVERSE_SEARCH },
{ "reverse-search-all", A_T_REVERSE_SEARCH },
{ "right-scroll", A_RSHIFT },
{ "set-mark", A_SETMARK },
{ "shell", A_SHELL },
{ "status", A_STAT },
{ "toggle-flag", A_OPT_TOGGLE },
{ "toggle-option", A_OPT_TOGGLE },
{ "undo-hilite", A_UNDO_SEARCH },
{ "version", A_VERSION },
{ "visual", A_VISUAL },
{ NULL, 0 }
};
struct cmdname editnames[] =
{
{ "back-complete", EC_B_COMPLETE },
{ "backspace", EC_BACKSPACE },
{ "delete", EC_DELETE },
{ "down", EC_DOWN },
{ "end", EC_END },
{ "expand", EC_EXPAND },
{ "forw-complete", EC_F_COMPLETE },
{ "home", EC_HOME },
{ "insert", EC_INSERT },
{ "invalid", EC_UINVALID },
{ "kill-line", EC_LINEKILL },
{ "left", EC_LEFT },
{ "literal", EC_LITERAL },
{ "right", EC_RIGHT },
{ "up", EC_UP },
{ "word-backspace", EC_W_BACKSPACE },
{ "word-delete", EC_W_DELETE },
{ "word-left", EC_W_LEFT },
{ "word-right", EC_W_RIGHT },
{ NULL, 0 }
};
struct table
{
struct cmdname *names;
char *pbuffer;
char buffer[MAX_USERCMD];
};
struct table cmdtable;
struct table edittable;
struct table vartable;
struct table *currtable = &cmdtable;
char fileheader[] = {
C0_LESSKEY_MAGIC,
C1_LESSKEY_MAGIC,
C2_LESSKEY_MAGIC,
C3_LESSKEY_MAGIC
};
char filetrailer[] = {
C0_END_LESSKEY_MAGIC,
C1_END_LESSKEY_MAGIC,
C2_END_LESSKEY_MAGIC
};
char cmdsection[1] = { CMD_SECTION };
char editsection[1] = { EDIT_SECTION };
char varsection[1] = { VAR_SECTION };
char endsection[1] = { END_SECTION };
char *infile = NULL;
char *outfile = NULL ;
int linenum;
int errors;
extern char version[];
void
usage()
{
fprintf(stderr, "usage: lesskey [-o output] [input]\n");
exit(1);
}
char *
mkpathname(dirname, filename)
char *dirname;
char *filename;
{
char *pathname;
pathname = calloc(strlen(dirname) + strlen(filename) + 2, sizeof(char));
strcpy(pathname, dirname);
strcat(pathname, PATHNAME_SEP);
strcat(pathname, filename);
return (pathname);
}
/*
* Figure out the name of a default file (in the user's HOME directory).
*/
char *
homefile(filename)
char *filename;
{
char *p;
char *pathname;
if ((p = getenv("HOME")) != NULL && *p != '\0')
pathname = mkpathname(p, filename);
#if OS2
else if ((p = getenv("INIT")) != NULL && *p != '\0')
pathname = mkpathname(p, filename);
#endif
else
{
fprintf(stderr, "cannot find $HOME - using current directory\n");
pathname = mkpathname(".", filename);
}
return (pathname);
}
/*
* Parse command line arguments.
*/
void
parse_args(argc, argv)
int argc;
char **argv;
{
char *arg;
outfile = NULL;
while (--argc > 0)
{
arg = *++argv;
if (arg[0] != '-')
/* Arg does not start with "-"; it's not an option. */
break;
if (arg[1] == '\0')
/* "-" means standard input. */
break;
if (arg[1] == '-' && arg[2] == '\0')
{
/* "--" means end of options. */
argc--;
argv++;
break;
}
switch (arg[1])
{
case '-':
if (strncmp(arg, "--output", 8) == 0)
{
if (arg[8] == '\0')
outfile = &arg[8];
else if (arg[8] == '=')
outfile = &arg[9];
else
usage();
goto opt_o;
}
if (strcmp(arg, "--version") == 0)
{
goto opt_V;
}
usage();
break;
case 'o':
outfile = &argv[0][2];
opt_o:
if (*outfile == '\0')
{
if (--argc <= 0)
usage();
outfile = *(++argv);
}
break;
case 'V':
opt_V:
printf("lesskey version %s\n", version);
exit(0);
default:
usage();
}
}
if (argc > 1)
usage();
/*
* Open the input file, or use DEF_LESSKEYINFILE if none specified.
*/
if (argc > 0)
infile = *argv;
else
infile = homefile(DEF_LESSKEYINFILE);
}
/*
* Initialize data structures.
*/
void
init_tables()
{
cmdtable.names = cmdnames;
cmdtable.pbuffer = cmdtable.buffer;
edittable.names = editnames;
edittable.pbuffer = edittable.buffer;
vartable.names = NULL;
vartable.pbuffer = vartable.buffer;
}
/*
* Parse one character of a string.
*/
char *
tstr(pp, xlate)
char **pp;
int xlate;
{
register char *p;
register char ch;
register int i;
static char buf[10];
static char tstr_control_k[] =
{ SK_SPECIAL_KEY, SK_CONTROL_K, 6, 1, 1, 1, '\0' };
p = *pp;
switch (*p)
{
case '\\':
++p;
switch (*p)
{
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
/*
* Parse an octal number.
*/
ch = 0;
i = 0;
do
ch = 8*ch + (*p - '0');
while (*++p >= '0' && *p <= '7' && ++i < 3);
*pp = p;
if (xlate && ch == CONTROL('K'))
return tstr_control_k;
buf[0] = ch;
buf[1] = '\0';
return (buf);
case 'b':
*pp = p+1;
return ("\b");
case 'e':
*pp = p+1;
buf[0] = ESC;
buf[1] = '\0';
return (buf);
case 'n':
*pp = p+1;
return ("\n");
case 'r':
*pp = p+1;
return ("\r");
case 't':
*pp = p+1;
return ("\t");
case 'k':
if (xlate)
{
switch (*++p)
{
case 'u': ch = SK_UP_ARROW; break;
case 'd': ch = SK_DOWN_ARROW; break;
case 'r': ch = SK_RIGHT_ARROW; break;
case 'l': ch = SK_LEFT_ARROW; break;
case 'U': ch = SK_PAGE_UP; break;
case 'D': ch = SK_PAGE_DOWN; break;
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;
buf[1] = ch;
buf[2] = 6;
buf[3] = 1;
buf[4] = 1;
buf[5] = 1;
buf[6] = '\0';
return (buf);
}
/* FALLTHRU */
default:
/*
* Backslash followed by any other char
* just means that char.
*/
*pp = p+1;
buf[0] = *p;
buf[1] = '\0';
if (xlate && buf[0] == CONTROL('K'))
return tstr_control_k;
return (buf);
}
case '^':
/*
* Carat means CONTROL.
*/
*pp = p+2;
buf[0] = CONTROL(p[1]);
buf[1] = '\0';
if (buf[0] == CONTROL('K'))
return tstr_control_k;
return (buf);
}
*pp = p+1;
buf[0] = *p;
buf[1] = '\0';
if (xlate && buf[0] == CONTROL('K'))
return tstr_control_k;
return (buf);
}
/*
* Skip leading spaces in a string.
*/
public char *
skipsp(s)
register char *s;
{
while (*s == ' ' || *s == '\t')
s++;
return (s);
}
/*
* Skip non-space characters in a string.
*/
public char *
skipnsp(s)
register char *s;
{
while (*s != '\0' && *s != ' ' && *s != '\t')
s++;
return (s);
}
/*
* Clean up an input line:
* strip off the trailing newline & any trailing # comment.
*/
char *
clean_line(s)
char *s;
{
register int i;
s = skipsp(s);
for (i = 0; s[i] != '\n' && s[i] != '\r' && s[i] != '\0'; i++)
if (s[i] == '#' && (i == 0 || s[i-1] != '\\'))
break;
s[i] = '\0';
return (s);
}
/*
* Add a byte to the output command table.
*/
void
add_cmd_char(c)
int c;
{
if (currtable->pbuffer >= currtable->buffer + MAX_USERCMD)
{
error("too many commands");
exit(1);
}
*(currtable->pbuffer)++ = c;
}
/*
* Add a string to the output command table.
*/
void
add_cmd_str(s)
char *s;
{
for ( ; *s != '\0'; s++)
add_cmd_char(*s);
}
/*
* See if we have a special "control" line.
*/
int
control_line(s)
char *s;
{
#define PREFIX(str,pat) (strncmp(str,pat,strlen(pat)-1) == 0)
if (PREFIX(s, "#line-edit"))
{
currtable = &edittable;
return (1);
}
if (PREFIX(s, "#command"))
{
currtable = &cmdtable;
return (1);
}
if (PREFIX(s, "#env"))
{
currtable = &vartable;
return (1);
}
if (PREFIX(s, "#stop"))
{
add_cmd_char('\0');
add_cmd_char(A_END_LIST);
return (1);
}
return (0);
}
/*
* Output some bytes.
*/
void
fputbytes(fd, buf, len)
FILE *fd;
char *buf;
int len;
{
while (len-- > 0)
{
fwrite(buf, sizeof(char), 1, fd);
buf++;
}
}
/*
* Output an integer, in special KRADIX form.
*/
void
fputint(fd, val)
FILE *fd;
unsigned int val;
{
char c;
if (val >= KRADIX*KRADIX)
{
fprintf(stderr, "error: integer too big (%d > %d)\n",
val, KRADIX*KRADIX);
exit(1);
}
c = val % KRADIX;
fwrite(&c, sizeof(char), 1, fd);
c = val / KRADIX;
fwrite(&c, sizeof(char), 1, fd);
}
/*
* Find an action, given the name of the action.
*/
int
findaction(actname)
char *actname;
{
int i;
for (i = 0; currtable->names[i].cn_name != NULL; i++)
if (strcmp(currtable->names[i].cn_name, actname) == 0)
return (currtable->names[i].cn_action);
error("unknown action");
return (A_INVALID);
}
void
error(s)
char *s;
{
fprintf(stderr, "line %d: %s\n", linenum, s);
errors++;
}
void
parse_cmdline(p)
char *p;
{
int cmdlen;
char *actname;
int action;
char *s;
char c;
/*
* Parse the command string and store it in the current table.
*/
cmdlen = 0;
do
{
s = tstr(&p, 1);
cmdlen += strlen(s);
if (cmdlen > MAX_CMDLEN)
error("command too long");
else
add_cmd_str(s);
} while (*p != ' ' && *p != '\t' && *p != '\0');
/*
* Terminate the command string with a null byte.
*/
add_cmd_char('\0');
/*
* Skip white space between the command string
* and the action name.
* Terminate the action name with a null byte.
*/
p = skipsp(p);
if (*p == '\0')
{
error("missing action");
return;
}
actname = p;
p = skipnsp(p);
c = *p;
*p = '\0';
/*
* Parse the action name and store it in the current table.
*/
action = findaction(actname);
/*
* See if an extra string follows the action name.
*/
*p = c;
p = skipsp(p);
if (*p == '\0')
{
add_cmd_char(action);
} else
{
/*
* OR the special value A_EXTRA into the action byte.
* Put the extra string after the action byte.
*/
add_cmd_char(action | A_EXTRA);
while (*p != '\0')
add_cmd_str(tstr(&p, 0));
add_cmd_char('\0');
}
}
void
parse_varline(p)
char *p;
{
char *s;
do
{
s = tstr(&p, 0);
add_cmd_str(s);
} while (*p != ' ' && *p != '\t' && *p != '=' && *p != '\0');
/*
* Terminate the variable name with a null byte.
*/
add_cmd_char('\0');
p = skipsp(p);
if (*p++ != '=')
{
error("missing =");
return;
}
add_cmd_char(EV_OK|A_EXTRA);
p = skipsp(p);
while (*p != '\0')
{
s = tstr(&p, 0);
add_cmd_str(s);
}
add_cmd_char('\0');
}
/*
* Parse a line from the lesskey file.
*/
void
parse_line(line)
char *line;
{
char *p;
/*
* See if it is a control line.
*/
if (control_line(line))
return;
/*
* Skip leading white space.
* Replace the final newline with a null byte.
* Ignore blank lines and comments.
*/
p = clean_line(line);
if (*p == '\0')
return;
if (currtable == &vartable)
parse_varline(p);
else
parse_cmdline(p);
}
int
main(argc, argv)
int argc;
char *argv[];
{
FILE *desc;
FILE *out;
char line[1024];
#ifdef WIN32
if (getenv("HOME") == NULL)
{
/*
* If there is no HOME environment variable,
* try the concatenation of HOMEDRIVE + HOMEPATH.
*/
char *drive = getenv("HOMEDRIVE");
char *path = getenv("HOMEPATH");
if (drive != NULL && path != NULL)
{
char *env = (char *) calloc(strlen(drive) +
strlen(path) + 6, sizeof(char));
strcpy(env, "HOME=");
strcat(env, drive);
strcat(env, path);
putenv(env);
}
}
#endif /* WIN32 */
/*
* Process command line arguments.
*/
parse_args(argc, argv);
init_tables();
/*
* Open the input file.
*/
if (strcmp(infile, "-") == 0)
desc = stdin;
else if ((desc = fopen(infile, "r")) == NULL)
{
#if HAVE_PERROR
perror(infile);
#else
fprintf(stderr, "Cannot open %s\n", infile);
#endif
usage();
}
/*
* Read and parse the input file, one line at a time.
*/
errors = 0;
linenum = 0;
while (fgets(line, sizeof(line), desc) != NULL)
{
++linenum;
parse_line(line);
}
/*
* Write the output file.
* If no output file was specified, use "$HOME/.less"
*/
if (errors > 0)
{
fprintf(stderr, "%d errors; no output produced\n", errors);
exit(1);
}
if (outfile == NULL)
outfile = getenv("LESSKEY");
if (outfile == NULL)
outfile = homefile(LESSKEYFILE);
if ((out = fopen(outfile, "wb")) == NULL)
{
#if HAVE_PERROR
perror(outfile);
#else
fprintf(stderr, "Cannot open %s\n", outfile);
#endif
exit(1);
}
/* File header */
fputbytes(out, fileheader, sizeof(fileheader));
/* Command key section */
fputbytes(out, cmdsection, sizeof(cmdsection));
fputint(out, cmdtable.pbuffer - cmdtable.buffer);
fputbytes(out, (char *)cmdtable.buffer, cmdtable.pbuffer-cmdtable.buffer);
/* Edit key section */
fputbytes(out, editsection, sizeof(editsection));
fputint(out, edittable.pbuffer - edittable.buffer);
fputbytes(out, (char *)edittable.buffer, edittable.pbuffer-edittable.buffer);
/* Environment variable section */
fputbytes(out, varsection, sizeof(varsection));
fputint(out, vartable.pbuffer - vartable.buffer);
fputbytes(out, (char *)vartable.buffer, vartable.pbuffer-vartable.buffer);
/* File trailer */
fputbytes(out, endsection, sizeof(endsection));
fputbytes(out, filetrailer, sizeof(filetrailer));
return (0);
}
less-382/lessecho.c 0100444 0000764 0000764 00000011564 10010075213 013314 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* lessecho [-ox] [-cx] [-pn] [-dn] [-a] file ...
* Simply echos its filename arguments on standard output.
* But any argument containing spaces is enclosed in quotes.
*
* -ox Specifies "x" to be the open quote character.
* -cx Specifies "x" to be the close quote character.
* -pn Specifies "n" to be the open quote character, as an integer.
* -dn Specifies "n" to be the close quote character, as an integer.
* -mx Specifies "x" to be a metachar.
* -nn Specifies "n" to be a metachar, as an integer.
* -ex Specifies "x" to be the escape char for metachars.
* -fn Specifies "x" to be the escape char for metachars, as an integer.
* -a Specifies that all arguments are to be quoted.
* The default is that only arguments containing spaces are quoted.
*/
#include "less.h"
static char *version = "$Revision: 1.9 $";
static int quote_all = 0;
static char openquote = '"';
static char closequote = '"';
static char *meta_escape = "\\";
static char meta_escape_buf[2];
static char metachars[64] = "";
static int num_metachars = 0;
static void
pr_usage()
{
fprintf(stderr,
"usage: lessecho [-ox] [-cx] [-pn] [-dn] [-mx] [-nn] [-ex] [-fn] [-a] file ...\n");
}
static void
pr_version()
{
char *p;
char buf[10];
char *pbuf = buf;
for (p = version; *p != ' '; p++)
if (*p == '\0')
return;
for (p++; *p != '$' && *p != ' ' && *p != '\0'; p++)
*pbuf++ = *p;
*pbuf = '\0';
printf("%s\n", buf);
}
static void
pr_error(s)
char *s;
{
fprintf(stderr, "%s\n", s);
exit(1);
}
static long
lstrtol(s, radix, pend)
char *s;
int radix;
char **pend;
{
int v;
int neg = 0;
long n = 0;
/* Skip leading white space. */
while (*s == ' ' || *s == '\t')
s++;
/* Check for a leading + or -. */
if (*s == '-')
{
neg = 1;
s++;
} else if (*s == '+')
{
s++;
}
/* Determine radix if caller does not specify. */
if (radix == 0)
{
radix = 10;
if (*s == '0')
{
switch (*++s)
{
case 'x':
radix = 16;
s++;
break;
default:
radix = 8;
break;
}
}
}
/* Parse the digits of the number. */
for (;;)
{
if (*s >= '0' && *s <= '9')
v = *s - '0';
else if (*s >= 'a' && *s <= 'f')
v = *s - 'a' + 10;
else if (*s >= 'A' && *s <= 'F')
v = *s - 'A' + 10;
else
break;
if (v >= radix)
break;
n = n * radix + v;
s++;
}
if (pend != NULL)
{
/* Skip trailing white space. */
while (*s == ' ' || *s == '\t')
s++;
*pend = s;
}
if (neg)
return (-n);
return (n);
}
#if !HAVE_STRCHR
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
int
main(argc, argv)
int argc;
char *argv[];
{
char *arg;
char *s;
int no_more_options;
no_more_options = 0;
while (--argc > 0)
{
arg = *++argv;
if (*arg != '-' || no_more_options)
break;
switch (*++arg)
{
case 'a':
quote_all = 1;
break;
case 'c':
closequote = *++arg;
break;
case 'd':
closequote = lstrtol(++arg, 0, &s);
if (s == arg)
pr_error("Missing number after -d");
break;
case 'e':
if (strcmp(++arg, "-") == 0)
meta_escape = "";
else
meta_escape = arg;
break;
case 'f':
meta_escape_buf[0] = lstrtol(++arg, 0, &s);
meta_escape = meta_escape_buf;
if (s == arg)
pr_error("Missing number after -f");
break;
case 'o':
openquote = *++arg;
break;
case 'p':
openquote = lstrtol(++arg, 0, &s);
if (s == arg)
pr_error("Missing number after -p");
break;
case 'm':
metachars[num_metachars++] = *++arg;
metachars[num_metachars] = '\0';
break;
case 'n':
metachars[num_metachars++] = lstrtol(++arg, 0, &s);
if (s == arg)
pr_error("Missing number after -n");
metachars[num_metachars] = '\0';
break;
case '?':
pr_usage();
return (0);
case '-':
if (*++arg == '\0')
{
no_more_options = 1;
break;
}
if (strcmp(arg, "version") == 0)
{
pr_version();
return (0);
}
if (strcmp(arg, "help") == 0)
{
pr_usage();
return (0);
}
pr_error("Invalid option after --");
default:
pr_error("Invalid option letter");
}
}
while (argc-- > 0)
{
int has_meta = 0;
arg = *argv++;
for (s = arg; *s != '\0'; s++)
{
if (strchr(metachars, *s) != NULL)
{
has_meta = 1;
break;
}
}
if (quote_all || (has_meta && strlen(meta_escape) == 0))
printf("%c%s%c", openquote, arg, closequote);
else
{
for (s = arg; *s != '\0'; s++)
{
if (strchr(metachars, *s) != NULL)
printf("%s", meta_escape);
printf("%c", *s);
}
}
if (argc > 0)
printf(" ");
else
printf("\n");
}
return (0);
}
less-382/scrsize.c 0100444 0000764 0000764 00000006172 10010075213 013170 0 ustar markn markn /*
* Copyright (C) 1984-2002 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
#include
#include
#include
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);
}
less-382/cmd.h 0100444 0000764 0000764 00000005516 10010075212 012256 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
#define MAX_USERCMD 500
#define MAX_CMDLEN 16
#define A_B_LINE 2
#define A_B_SCREEN 3
#define A_B_SCROLL 4
#define A_B_SEARCH 5
#define A_DIGIT 6
#define A_DISP_OPTION 7
#define A_DEBUG 8
#define A_EXAMINE 9
#define A_FIRSTCMD 10
#define A_FREPAINT 11
#define A_F_LINE 12
#define A_F_SCREEN 13
#define A_F_SCROLL 14
#define A_F_SEARCH 15
#define A_GOEND 16
#define A_GOLINE 17
#define A_GOMARK 18
#define A_HELP 19
#define A_NEXT_FILE 20
#define A_PERCENT 21
#define A_PREFIX 22
#define A_PREV_FILE 23
#define A_QUIT 24
#define A_REPAINT 25
#define A_SETMARK 26
#define A_SHELL 27
#define A_STAT 28
#define A_FF_LINE 29
#define A_BF_LINE 30
#define A_VERSION 31
#define A_VISUAL 32
#define A_F_WINDOW 33
#define A_B_WINDOW 34
#define A_F_BRACKET 35
#define A_B_BRACKET 36
#define A_PIPE 37
#define A_INDEX_FILE 38
#define A_UNDO_SEARCH 39
#define A_FF_SCREEN 40
#define A_LSHIFT 41
#define A_RSHIFT 42
#define A_AGAIN_SEARCH 43
#define A_T_AGAIN_SEARCH 44
#define A_REVERSE_SEARCH 45
#define A_T_REVERSE_SEARCH 46
#define A_OPT_TOGGLE 47
#define A_OPT_SET 48
#define A_OPT_UNSET 49
#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
#define A_UINVALID 102
#define A_END_LIST 103
#define A_SPECIAL_KEY 104
#define A_SKIP 127
#define A_EXTRA 0200
/* Line editting characters */
#define EC_BACKSPACE 1
#define EC_LINEKILL 2
#define EC_RIGHT 3
#define EC_LEFT 4
#define EC_W_LEFT 5
#define EC_W_RIGHT 6
#define EC_INSERT 7
#define EC_DELETE 8
#define EC_HOME 9
#define EC_END 10
#define EC_W_BACKSPACE 11
#define EC_W_DELETE 12
#define EC_UP 13
#define EC_DOWN 14
#define EC_EXPAND 15
#define EC_F_COMPLETE 17
#define EC_B_COMPLETE 18
#define EC_LITERAL 19
#define EC_NOACTION 101
#define EC_UINVALID 102
/* Flags for editchar() */
#define EC_PEEK 01
#define EC_NOHISTORY 02
#define EC_NOCOMPLETE 04
#define EC_NORIGHTLEFT 010
/* Environment variable stuff */
#define EV_OK 01
/* Special keys (keys which output different strings on different terminals) */
#define SK_SPECIAL_KEY CONTROL('K')
#define SK_RIGHT_ARROW 1
#define SK_LEFT_ARROW 2
#define SK_UP_ARROW 3
#define SK_DOWN_ARROW 4
#define SK_PAGE_UP 5
#define SK_PAGE_DOWN 6
#define SK_HOME 7
#define SK_END 8
#define SK_DELETE 9
#define SK_INSERT 10
#define SK_CTL_LEFT_ARROW 11
#define SK_CTL_RIGHT_ARROW 12
#define SK_CTL_DELETE 13
#define SK_F1 14
#define SK_BACKTAB 15
#define SK_CTL_BACKSPACE 16
#define SK_CONTROL_K 40
less-382/funcs.h 0100444 0000764 0000764 00000015214 07570330247 012650 0 ustar markn markn public char * save ();
public VOID_POINTER ecalloc ();
public char * skipsp ();
public int sprefix ();
public void quit ();
public void raw_mode ();
public void scrsize ();
public char * special_key_str ();
public void get_term ();
public void init ();
public void deinit ();
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 ();
public void vbell ();
public void bell ();
public void clear ();
public void clear_eol ();
public void clear_bot ();
public void so_enter ();
public void so_exit ();
public void ul_enter ();
public void ul_exit ();
public void bo_enter ();
public void bo_exit ();
public void bl_enter ();
public void bl_exit ();
public void backspace ();
public void putbs ();
public char WIN32getch ();
public void match_brac ();
public void ch_ungetchar ();
public void end_logfile ();
public void sync_logfile ();
public int ch_seek ();
public int ch_end_seek ();
public int ch_beg_seek ();
public POSITION ch_length ();
public POSITION ch_tell ();
public int ch_forw_get ();
public int ch_back_get ();
public void ch_setbufspace ();
public void ch_flush ();
public int seekable ();
public void ch_init ();
public void ch_close ();
public int ch_getflags ();
public void ch_dump ();
public void init_charset ();
public int binary_char ();
public int control_char ();
public char * prchar ();
public void cmd_reset ();
public void clear_cmd ();
public void cmd_putstr ();
public int len_cmdbuf ();
public void set_mlist ();
public void cmd_addhist ();
public void cmd_accept ();
public int cmd_char ();
public LINENUM cmd_int ();
public char * get_cmdbuf ();
public int in_mca ();
public void dispversion ();
public int getcc ();
public void ungetcc ();
public void ungetsc ();
public void commands ();
public void init_cmds ();
public void add_fcmd_table ();
public void add_ecmd_table ();
public int fcmd_decode ();
public int ecmd_decode ();
public char * lgetenv ();
public int lesskey ();
public void add_hometable ();
public int editchar ();
public void init_textlist ();
public char * forw_textlist ();
public char * back_textlist ();
public int edit ();
public int edit_ifile ();
public int edit_list ();
public int edit_first ();
public int edit_last ();
public int edit_next ();
public int edit_prev ();
public int edit_index ();
public IFILE save_curr_ifile ();
public void unsave_ifile ();
public void reedit_ifile ();
public int edit_stdin ();
public void cat_file ();
public void use_logfile ();
public char * shell_unquote ();
public char * get_meta_escape ();
public char * shell_quote ();
public char * homefile ();
public char * fexpand ();
public char * fcomplete ();
public int bin_file ();
public char * lglob ();
public char * open_altfile ();
public void close_altfile ();
public int is_dir ();
public char * bad_file ();
public POSITION filesize ();
public char * shell_coption ();
public void forw ();
public void back ();
public void forward ();
public void backward ();
public int get_back_scroll ();
public void del_ifile ();
public IFILE next_ifile ();
public IFILE prev_ifile ();
public IFILE getoff_ifile ();
public int nifile ();
public IFILE get_ifile ();
public char * get_filename ();
public int get_index ();
public void store_pos ();
public void get_pos ();
public void set_open ();
public int opened ();
public void hold_ifile ();
public int held_ifile ();
public void * get_filestate ();
public void set_filestate ();
public void if_dump ();
public POSITION forw_line ();
public POSITION back_line ();
public void set_attnpos ();
public void jump_forw ();
public void jump_back ();
public void repaint ();
public void jump_percent ();
public void jump_line_loc ();
public void jump_loc ();
public void init_line ();
public void prewind ();
public void plinenum ();
public int is_ansi_end ();
public int pappend ();
public void pdone ();
public int gline ();
public void null_line ();
public POSITION forw_raw_line ();
public POSITION back_raw_line ();
public void clr_linenum ();
public void add_lnum ();
public LINENUM find_linenum ();
public POSITION find_pos ();
public LINENUM currline ();
public void lsystem ();
public int pipe_mark ();
public int pipe_data ();
public void init_mark ();
public int badmark ();
public void setmark ();
public void lastmark ();
public void gomark ();
public POSITION markpos ();
public void unmark ();
public void opt_o ();
public void opt__O ();
public void opt_l ();
public void opt_k ();
public void opt_t ();
public void opt__T ();
public void opt_p ();
public void opt__P ();
public void opt_b ();
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 ();
public void scan_option ();
public void toggle_option ();
public int single_char_option ();
public char * opt_prompt ();
public int isoptpending ();
public void nopendopt ();
public int getnum ();
public void init_option ();
public struct loption * findopt ();
public struct loption * findopt_name ();
public int iread ();
public void intread ();
public long get_time ();
public char * errno_message ();
public int percentage ();
public POSITION percent_pos ();
public int os9_signal ();
public void put_line ();
public void flush ();
public int putchr ();
public void putstr ();
public void get_return ();
public void error ();
public void ierror ();
public int query ();
public POSITION position ();
public void add_forw_pos ();
public void add_back_pos ();
public void pos_clear ();
public void pos_init ();
public int onscreen ();
public int empty_screen ();
public int empty_lines ();
public void get_scrpos ();
public int adjsline ();
public void init_prompt ();
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 ();
public void clr_hilite ();
public int is_hilited ();
public void chg_caseless ();
public void chg_hilite ();
public int search ();
public void prep_hilite ();
public RETSIGTYPE winch ();
public RETSIGTYPE winch ();
public void init_signals ();
public void psignals ();
public void cleantags ();
public int gettagtype ();
public void findtag ();
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 ();
less-382/lglob.h 0100444 0000764 0000764 00000006020 10010075213 012602 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Macros to define the method of doing filename "globbing".
* There are three possible mechanisms:
* 1. GLOB_LIST
* This defines a function that returns a list of matching filenames.
* 2. GLOB_NAME
* This defines a function that steps thru the list of matching
* filenames, returning one name each time it is called.
* 3. GLOB_STRING
* This defines a function that returns the complete list of
* matching filenames as a single space-separated string.
*/
#if OS2
#define DECL_GLOB_LIST(list) char **list; char **pp;
#define GLOB_LIST(filename,list) list = _fnexplode(filename)
#define GLOB_LIST_FAILED(list) list == NULL
#define SCAN_GLOB_LIST(list,p) pp = list; *pp != NULL; pp++
#define INIT_GLOB_LIST(list,p) p = *pp
#define GLOB_LIST_DONE(list) _fnexplodefree(list)
#else
#if MSDOS_COMPILER==DJGPPC
#define DECL_GLOB_LIST(list) glob_t list; int i;
#define GLOB_LIST(filename,list) glob(filename,GLOB_NOCHECK,0,&list)
#define GLOB_LIST_FAILED(list) 0
#define SCAN_GLOB_LIST(list,p) i = 0; i < list.gl_pathc; i++
#define INIT_GLOB_LIST(list,p) p = list.gl_pathv[i]
#define GLOB_LIST_DONE(list) globfree(&list)
#else
#if MSDOS_COMPILER==MSOFTC || MSDOS_COMPILER==BORLANDC
#define GLOB_FIRST_NAME(filename,fndp,h) h = _dos_findfirst(filename, ~_A_VOLID, fndp)
#define GLOB_FIRST_FAILED(handle) ((handle) != 0)
#define GLOB_NEXT_NAME(handle,fndp) _dos_findnext(fndp)
#define GLOB_NAME_DONE(handle)
#define GLOB_NAME name
#define DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle) \
struct find_t fnd; \
char drive[_MAX_DRIVE]; \
char dir[_MAX_DIR]; \
char fname[_MAX_FNAME]; \
char ext[_MAX_EXT]; \
int handle;
#else
#if MSDOS_COMPILER==WIN32C && defined(_MSC_VER)
#define GLOB_FIRST_NAME(filename,fndp,h) h = _findfirst(filename, fndp)
#define GLOB_FIRST_FAILED(handle) ((handle) == -1)
#define GLOB_NEXT_NAME(handle,fndp) _findnext(handle, fndp)
#define GLOB_NAME_DONE(handle) _findclose(handle)
#define GLOB_NAME name
#define DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle) \
struct _finddata_t fnd; \
char drive[_MAX_DRIVE]; \
char dir[_MAX_DIR]; \
char fname[_MAX_FNAME]; \
char ext[_MAX_EXT]; \
long handle;
#else
#if MSDOS_COMPILER==WIN32C && !defined(_MSC_VER) /* Borland C for Windows */
#define GLOB_FIRST_NAME(filename,fndp,h) h = findfirst(filename, fndp, ~FA_LABEL)
#define GLOB_FIRST_FAILED(handle) ((handle) != 0)
#define GLOB_NEXT_NAME(handle,fndp) findnext(fndp)
#define GLOB_NAME_DONE(handle)
#define GLOB_NAME ff_name
#define DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle) \
struct ffblk fnd; \
char drive[MAXDRIVE]; \
char dir[MAXDIR]; \
char fname[MAXFILE]; \
char ext[MAXEXT]; \
int handle;
#endif
#endif
#endif
#endif
#endif
less-382/less.h 0100444 0000764 0000764 00000021440 10010075213 012454 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Standard include file for "less".
*/
/*
* Defines for MSDOS_COMPILER.
*/
#define MSOFTC 1 /* Microsoft C */
#define BORLANDC 2 /* Borland C */
#define WIN32C 3 /* Windows (Borland C or Microsoft C) */
#define DJGPPC 4 /* DJGPP C */
/*
* Include the file of compile-time options.
* The <> make cc search for it in -I., not srcdir.
*/
#include
#ifdef _SEQUENT_
/*
* Kludge for Sequent Dynix systems that have sigsetmask, but
* it's not compatible with the way less calls it.
* {{ Do other systems need this? }}
*/
#undef HAVE_SIGSETMASK
#endif
/*
* Language details.
*/
#if HAVE_VOID
#define VOID_POINTER void *
#else
#define VOID_POINTER char *
#define void int
#endif
#if HAVE_CONST
#define constant const
#else
#define constant
#endif
#define public /* PUBLIC FUNCTION */
/* Library function declarations */
#if HAVE_SYS_TYPES_H
#include
#endif
#if HAVE_STDIO_H
#include
#endif
#if HAVE_FCNTL_H
#include
#endif
#if HAVE_UNISTD_H
#include
#endif
#if HAVE_CTYPE_H
#include
#endif
#if HAVE_LIMITS_H
#include
#endif
#if HAVE_STDLIB_H
#include
#endif
#if HAVE_STRING_H
#include
#endif
#ifdef _OSK
#include
#include
#endif
#if MSDOS_COMPILER==WIN32C || OS2
#include
#endif
#if MSDOS_COMPILER==DJGPPC
#include
#include
#include
#include
#endif
#if !HAVE_STDLIB_H
char *getenv();
off_t lseek();
VOID_POINTER calloc();
void free();
#endif
/*
* Simple lowercase test which can be used during option processing
* (before options are parsed which might tell us what charset to use).
*/
#define SIMPLE_IS_UPPER(c) ((c) >= 'A' && (c) <= 'Z')
#define SIMPLE_IS_LOWER(c) ((c) >= 'a' && (c) <= 'z')
#define SIMPLE_TO_UPPER(c) ((c) - 'a' + 'A')
#define SIMPLE_TO_LOWER(c) ((c) - 'A' + 'a')
#if !HAVE_UPPER_LOWER
#define isupper(c) SIMPLE_IS_UPPER(c)
#define islower(c) SIMPLE_IS_LOWER(c)
#define toupper(c) SIMPLE_TO_UPPER(c)
#define tolower(c) SIMPLE_TO_LOWER(c)
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define OPT_OFF 0
#define OPT_ON 1
#define OPT_ONPLUS 2
#if !HAVE_MEMCPY
#ifndef memcpy
#define memcpy(to,from,len) bcopy((from),(to),(len))
#endif
#endif
#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;
typedef off_t LINENUM;
#define MIN_LINENUM_WIDTH 7 /* Min printing width of a line number */
#define NULL_POSITION ((POSITION)(-1))
/*
* Flags for open()
*/
#if MSDOS_COMPILER || OS2
#define OPEN_READ (O_RDONLY|O_BINARY)
#else
#ifdef _OSK
#define OPEN_READ (S_IREAD)
#else
#ifdef O_RDONLY
#define OPEN_READ (O_RDONLY)
#else
#define OPEN_READ (0)
#endif
#endif
#endif
#if defined(O_WRONLY) && defined(O_APPEND)
#define OPEN_APPEND (O_APPEND|O_WRONLY)
#else
#ifdef _OSK
#define OPEN_APPEND (S_IWRITE)
#else
#define OPEN_APPEND (1)
#endif
#endif
/*
* Set a file descriptor to binary mode.
*/
#if MSDOS_COMPILER==MSOFTC
#define SET_BINARY(f) _setmode(f, _O_BINARY);
#else
#if MSDOS_COMPILER || OS2
#define SET_BINARY(f) setmode(f, O_BINARY)
#else
#define SET_BINARY(f)
#endif
#endif
/*
* Does the shell treat "?" as a metacharacter?
*/
#if MSDOS_COMPILER || OS2 || _OSK
#define SHELL_META_QUEST 0
#else
#define SHELL_META_QUEST 1
#endif
#define SPACES_IN_FILENAMES 1
/*
* An IFILE represents an input file.
*/
#define IFILE VOID_POINTER
#define NULL_IFILE ((IFILE)NULL)
/*
* The structure used to represent a "screen position".
* This consists of a file position, and a screen line number.
* The meaning is that the line starting at the given file
* position is displayed on the ln-th line of the screen.
* (Screen lines before ln are empty.)
*/
struct scrpos
{
POSITION pos;
int ln;
};
typedef union parg
{
char *p_string;
int p_int;
LINENUM p_linenum;
} PARG;
#define NULL_PARG ((PARG *)NULL)
struct textlist
{
char *string;
char *endstring;
};
#define EOI (-1)
#define READ_INTR (-2)
/* How quiet should we be? */
#define NOT_QUIET 0 /* Ring bell at eof and for errors */
#define LITTLE_QUIET 1 /* Ring bell only for errors */
#define VERY_QUIET 2 /* Never ring bell */
/* How should we prompt? */
#define PR_SHORT 0 /* Prompt with colon */
#define PR_MEDIUM 1 /* Prompt with message */
#define PR_LONG 2 /* Prompt with longer message */
/* How should we handle backspaces? */
#define BS_SPECIAL 0 /* Do special things for underlining and bold */
#define BS_NORMAL 1 /* \b treated as normal char; actually output */
#define BS_CONTROL 2 /* \b treated as control char; prints as ^H */
/* How should we search? */
#define SRCH_FORW 000001 /* Search forward from current position */
#define SRCH_BACK 000002 /* Search backward from current position */
#define SRCH_NO_MOVE 000004 /* Highlight, but don't move */
#define SRCH_FIND_ALL 000010 /* Find and highlight all matches */
#define SRCH_NO_MATCH 000100 /* Search for non-matching lines */
#define SRCH_PAST_EOF 000200 /* Search past end-of-file, into next file */
#define SRCH_FIRST_FILE 000400 /* Search starting at the first file */
#define SRCH_NO_REGEX 001000 /* Don't use regular expressions */
#define SRCH_REVERSE(t) (((t) & SRCH_FORW) ? \
(((t) & ~SRCH_FORW) | SRCH_BACK) : \
(((t) & ~SRCH_BACK) | SRCH_FORW))
/* */
#define NO_MCA 0
#define MCA_DONE 1
#define MCA_MORE 2
#define CC_OK 0 /* Char was accepted & processed */
#define CC_QUIT 1 /* Char was a request to abort current cmd */
#define CC_ERROR 2 /* Char could not be accepted due to error */
#define CC_PASS 3 /* Char was rejected (internal) */
#define CF_QUIT_ON_ERASE 0001 /* Abort cmd if its entirely erased */
/* Special chars used to tell put_line() to do something special */
#define AT_NORMAL (0)
#define AT_UNDERLINE (1)
#define AT_BOLD (2)
#define AT_BLINK (3)
#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.
* Since the argument is usually a constant, this macro normally compiles
* into a constant.
*/
#define CONTROL(c) ( \
(c)=='[' ? '\047' : \
(c)=='a' ? '\001' : \
(c)=='b' ? '\002' : \
(c)=='c' ? '\003' : \
(c)=='d' ? '\067' : \
(c)=='e' ? '\055' : \
(c)=='f' ? '\056' : \
(c)=='g' ? '\057' : \
(c)=='h' ? '\026' : \
(c)=='i' ? '\005' : \
(c)=='j' ? '\025' : \
(c)=='k' ? '\013' : \
(c)=='l' ? '\014' : \
(c)=='m' ? '\015' : \
(c)=='n' ? '\016' : \
(c)=='o' ? '\017' : \
(c)=='p' ? '\020' : \
(c)=='q' ? '\021' : \
(c)=='r' ? '\022' : \
(c)=='s' ? '\023' : \
(c)=='t' ? '\074' : \
(c)=='u' ? '\075' : \
(c)=='v' ? '\062' : \
(c)=='w' ? '\046' : \
(c)=='x' ? '\030' : \
(c)=='y' ? '\031' : \
(c)=='z' ? '\077' : \
(c)=='A' ? '\001' : \
(c)=='B' ? '\002' : \
(c)=='C' ? '\003' : \
(c)=='D' ? '\067' : \
(c)=='E' ? '\055' : \
(c)=='F' ? '\056' : \
(c)=='G' ? '\057' : \
(c)=='H' ? '\026' : \
(c)=='I' ? '\005' : \
(c)=='J' ? '\025' : \
(c)=='K' ? '\013' : \
(c)=='L' ? '\014' : \
(c)=='M' ? '\015' : \
(c)=='N' ? '\016' : \
(c)=='O' ? '\017' : \
(c)=='P' ? '\020' : \
(c)=='Q' ? '\021' : \
(c)=='R' ? '\022' : \
(c)=='S' ? '\023' : \
(c)=='T' ? '\074' : \
(c)=='U' ? '\075' : \
(c)=='V' ? '\062' : \
(c)=='W' ? '\046' : \
(c)=='X' ? '\030' : \
(c)=='Y' ? '\031' : \
(c)=='Z' ? '\077' : \
(c)=='|' ? '\031' : \
(c)=='\\' ? '\034' : \
(c)=='^' ? '\036' : \
(c)&077)
#else
#define CONTROL(c) ((c)&037)
#endif /* IS_EBCDIC_HOST */
#define ESC CONTROL('[')
#if _OSK_MWC32
#define LSIGNAL(sig,func) os9_signal(sig,func)
#else
#define LSIGNAL(sig,func) signal(sig,func)
#endif
#if HAVE_SIGPROCMASK
#if HAVE_SIGSET_T
#else
#undef HAVE_SIGPROCMASK
#endif
#endif
#if HAVE_SIGPROCMASK
#if HAVE_SIGEMPTYSET
#else
#undef sigemptyset
#define sigemptyset(mp) *(mp) = 0
#endif
#endif
#define S_INTERRUPT 01
#define S_STOP 02
#define S_WINCH 04
#define ABORT_SIGS() (sigs & (S_INTERRUPT|S_STOP))
#define QUIT_OK 0
#define QUIT_ERROR 1
#define QUIT_SAVED_STATUS (-1)
/* filestate flags */
#define CH_CANSEEK 001
#define CH_KEEPOPEN 002
#define CH_POPENED 004
#define CH_HELPFILE 010
#define ch_zero() ((POSITION)0)
#define FAKE_HELPFILE "@/\\less/\\help/\\file/\\@"
#include "funcs.h"
/* Functions not included in funcs.h */
void postoa();
void linenumtoa();
void inttoa();
less-382/lesskey.h 0100444 0000764 0000764 00000001555 10010075213 013172 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Format of a lesskey file:
*
* LESSKEY_MAGIC (4 bytes)
* sections...
* END_LESSKEY_MAGIC (4 bytes)
*
* Each section is:
*
* section_MAGIC (1 byte)
* section_length (2 bytes)
* key table (section_length bytes)
*/
#define C0_LESSKEY_MAGIC '\0'
#define C1_LESSKEY_MAGIC 'M'
#define C2_LESSKEY_MAGIC '+'
#define C3_LESSKEY_MAGIC 'G'
#define CMD_SECTION 'c'
#define EDIT_SECTION 'e'
#define VAR_SECTION 'v'
#define END_SECTION 'x'
#define C0_END_LESSKEY_MAGIC 'E'
#define C1_END_LESSKEY_MAGIC 'n'
#define C2_END_LESSKEY_MAGIC 'd'
/* */
#define KRADIX 64
less-382/option.h 0100444 0000764 0000764 00000003656 10010075213 013027 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
#define END_OPTION_STRING ('$')
/*
* Types of options.
*/
#define BOOL 01 /* Boolean option: 0 or 1 */
#define TRIPLE 02 /* Triple-valued option: 0, 1 or 2 */
#define NUMBER 04 /* Numeric option */
#define STRING 010 /* String-valued option */
#define NOVAR 020 /* No associated variable */
#define REPAINT 040 /* Repaint screen after toggling option */
#define NO_TOGGLE 0100 /* Option cannot be toggled with "-" cmd */
#define HL_REPAINT 0200 /* Repaint hilites after toggling option */
#define NO_QUERY 0400 /* Option cannot be queried with "_" cmd */
#define INIT_HANDLER 01000 /* Call option handler function at startup */
#define OTYPE (BOOL|TRIPLE|NUMBER|STRING|NOVAR)
/*
* Argument to a handling function tells what type of activity:
*/
#define INIT 0 /* Initialization (from command line) */
#define QUERY 1 /* Query (from _ or - command) */
#define TOGGLE 2 /* Change value (from - command) */
/* Flag to toggle_option to specify how to "toggle" */
#define OPT_NO_TOGGLE 0
#define OPT_TOGGLE 1
#define OPT_UNSET 2
#define OPT_SET 3
#define OPT_NO_PROMPT 0100
/* Error code from findopt_name */
#define OPT_AMBIG 1
struct optname
{
char *oname; /* Long (GNU-style) option name */
struct optname *onext; /* List of synonymous option names */
};
struct loption
{
char oletter; /* The controlling letter (a-z) */
struct optname *onames; /* Long (GNU-style) option name */
int otype; /* Type of the option */
int odefault; /* Default value */
int *ovar; /* Pointer to the associated variable */
void (*ofunc)(); /* Pointer to special handling function */
char *odesc[3]; /* Description of each value */
};
less-382/pckeys.h 0100444 0000764 0000764 00000001702 10010075213 013003 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Definitions of keys on the PC.
* Special (non-ASCII) keys on the PC send a two-byte sequence,
* where the first byte is 0 and the second is as defined below.
*/
#define PCK_SHIFT_TAB '\017'
#define PCK_ALT_E '\022'
#define PCK_CAPS_LOCK '\072'
#define PCK_F1 '\073'
#define PCK_NUM_LOCK '\105'
#define PCK_HOME '\107'
#define PCK_UP '\110'
#define PCK_PAGEUP '\111'
#define PCK_LEFT '\113'
#define PCK_RIGHT '\115'
#define PCK_END '\117'
#define PCK_DOWN '\120'
#define PCK_PAGEDOWN '\121'
#define PCK_INSERT '\122'
#define PCK_DELETE '\123'
#define PCK_CTL_LEFT '\163'
#define PCK_CTL_RIGHT '\164'
#define PCK_CTL_DELETE '\223'
less-382/position.h 0100444 0000764 0000764 00000000736 10010075213 013357 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Include file for interfacing to position.c modules.
*/
#define TOP (0)
#define TOP_PLUS_ONE (1)
#define BOTTOM (-1)
#define BOTTOM_PLUS_ONE (-2)
#define MIDDLE (-3)
less-382/install.sh 0100555 0000764 0000764 00000004212 10010075213 013340 0 ustar markn markn #!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5; it is not part of GNU.
#
# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
#
# This script is compatible with the BSD install script, but was written
# from scratch.
#
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
instcmd="$mvprog"
chmodcmd=""
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
fi
# Make a temp file name in the proper directory.
dstdir=`dirname $dst`
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp
# and set any options; do chmod last to preserve setuid bits
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
# Now rename the file to the real destination.
$doit $rmcmd $dst
$doit $mvcmd $dsttmp $dst
exit 0
less-382/defines.h.in 0100444 0000764 0000764 00000023671 10010075273 013546 0 ustar markn markn /* defines.h.in. Generated from configure.ac by autoheader. */
/* Unix definition file for less. -*- C -*-
*
* This file has 3 sections:
* User preferences.
* Settings always true on Unix.
* Settings automatically determined by configure.
*
* * * * * * WARNING * * * * * *
* If you edit defines.h by hand, do "touch stamp-h" before you run make
* so config.status doesn't overwrite your changes.
*/
/* User preferences. */
/*
* SECURE is 1 if you wish to disable a bunch of features in order to
* be safe to run by unprivileged users.
*/
#define SECURE 0
/*
* SHELL_ESCAPE is 1 if you wish to allow shell escapes.
* (This is possible only if your system supplies the system() function.)
*/
#define SHELL_ESCAPE (!SECURE)
/*
* EXAMINE is 1 if you wish to allow examining files by name from within less.
*/
#define EXAMINE (!SECURE)
/*
* TAB_COMPLETE_FILENAME is 1 if you wish to allow the TAB key
* to complete filenames at prompts.
*/
#define TAB_COMPLETE_FILENAME (!SECURE)
/*
* CMD_HISTORY is 1 if you wish to allow keys to cycle through
* previous commands at prompts.
*/
#define CMD_HISTORY 1
/*
* HILITE_SEARCH is 1 if you wish to have search targets to be
* displayed in standout mode.
*/
#define HILITE_SEARCH 1
/*
* EDITOR is 1 if you wish to allow editor invocation (the "v" command).
* (This is possible only if your system supplies the system() function.)
* EDIT_PGM is the name of the (default) editor to be invoked.
*/
#define EDITOR (!SECURE)
/*
* TAGS is 1 if you wish to support tag files.
*/
#define TAGS (!SECURE)
/*
* USERFILE is 1 if you wish to allow a .less file to specify
* user-defined key bindings.
*/
#define USERFILE (!SECURE)
/*
* GLOB is 1 if you wish to have shell metacharacters expanded in filenames.
* This will generally work if your system provides the "popen" function
* and the "echo" shell command.
*/
#define GLOB (!SECURE)
/*
* PIPEC is 1 if you wish to have the "|" command
* which allows the user to pipe data into a shell command.
*/
#define PIPEC (!SECURE)
/*
* LOGFILE is 1 if you wish to allow the -l option (to create log files).
*/
#define LOGFILE (!SECURE)
/*
* GNU_OPTIONS is 1 if you wish to support the GNU-style command
* line options --help and --version.
*/
#define GNU_OPTIONS 1
/*
* ONLY_RETURN is 1 if you want RETURN to be the only input which
* will continue past an error message.
* Otherwise, any key will continue past an error message.
*/
#define ONLY_RETURN 0
/*
* LESSKEYFILE is the filename of the default lesskey output file
* (in the HOME directory).
* LESSKEYFILE_SYS is the filename of the system-wide lesskey output file.
* DEF_LESSKEYINFILE is the filename of the default lesskey input
* (in the HOME directory).
*/
#define LESSKEYFILE ".less"
#define LESSKEYFILE_SYS SYSDIR "/sysless"
#define DEF_LESSKEYINFILE ".lesskey"
/* Settings always true on Unix. */
/*
* Define MSDOS_COMPILER if compiling under Microsoft C.
*/
#define MSDOS_COMPILER 0
/*
* Pathname separator character.
*/
#define PATHNAME_SEP "/"
/*
* HAVE_SYS_TYPES_H is 1 if your system has .
*/
#define HAVE_SYS_TYPES_H 1
/*
* Define if you have the header file.
*/
#undef HAVE_SGSTAT_H
/*
* HAVE_PERROR is 1 if your system has the perror() call.
* (Actually, if it has sys_errlist, sys_nerr and errno.)
*/
#define HAVE_PERROR 1
/*
* HAVE_TIME is 1 if your system has the time() call.
*/
#define HAVE_TIME 1
/*
* HAVE_SHELL is 1 if your system supports a SHELL command interpreter.
*/
#define HAVE_SHELL 1
/*
* Default shell metacharacters and meta-escape character.
*/
#define DEF_METACHARS "; *?\t\n'\"()<>|&^`#\\"
#define DEF_METAESCAPE "\\"
/*
* HAVE_DUP is 1 if your system has the dup() call.
*/
#define HAVE_DUP 1
/*
* Sizes of various buffers.
*/
#define CMDBUF_SIZE 512 /* Buffer for multichar commands */
#define UNGOT_SIZE 100 /* Max chars to unget() */
#define LINEBUF_SIZE 1024 /* Max size of line in input file */
#define OUTBUF_SIZE 1024 /* Output buffer */
#define PROMPT_SIZE 200 /* Max size of prompt string */
#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. */
/* Define EDIT_PGM to your editor. */
#undef EDIT_PGM
/* Define HAVE_CONST if your compiler supports the "const" modifier. */
#undef HAVE_CONST
/* Define to 1 if you have the header file. */
#undef HAVE_CTYPE_H
/* Define HAVE_ERRNO if you have the errno variable. */
#undef HAVE_ERRNO
/* Define to 1 if you have the header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if you have the header file. */
#undef HAVE_FCNTL_H
/* Define HAVE_FILENO if you have the fileno() macro. */
#undef HAVE_FILENO
/* Define to 1 if you have the `fsync' function. */
#undef HAVE_FSYNC
/* Define to 1 if you have the header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `gen' library (-lgen). */
#undef HAVE_LIBGEN
/* Define to 1 if you have the `intl' library (-lintl). */
#undef HAVE_LIBINTL
/* Define to 1 if you have the `PW' library (-lPW). */
#undef HAVE_LIBPW
/* Define to 1 if you have the header file. */
#undef HAVE_LIMITS_H
/* Define HAVE_LOCALE if you have locale.h and setlocale. */
#undef HAVE_LOCALE
/* Define to 1 if you have the `memcpy' function. */
#undef HAVE_MEMCPY
/* Define to 1 if you have the header file. */
#undef HAVE_MEMORY_H
/* Define HAVE_OSPEED if your termcap library has the ospeed variable. */
#undef HAVE_OSPEED
/* PCRE (Perl-compatible regular expression) library */
#undef HAVE_PCRE
/* Define to 1 if you have the `popen' function. */
#undef HAVE_POPEN
/* POSIX regcomp() and regex.h */
#undef HAVE_POSIX_REGCOMP
/* System V regcmp() */
#undef HAVE_REGCMP
/* */
#undef HAVE_REGEXEC2
/* BSD re_comp() */
#undef HAVE_RE_COMP
/* Define HAVE_SIGEMPTYSET if you have the sigemptyset macro. */
#undef HAVE_SIGEMPTYSET
/* Define to 1 if you have the `sigprocmask' function. */
#undef HAVE_SIGPROCMASK
/* Define to 1 if you have the `sigsetmask' function. */
#undef HAVE_SIGSETMASK
/* Define HAVE_SIGSET_T you have the sigset_t type. */
#undef HAVE_SIGSET_T
/* Define to 1 if you have the `stat' function. */
#undef HAVE_STAT
/* Define to 1 if you have the header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the header file. */
#undef HAVE_STDIO_H
/* Define to 1 if you have the header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strchr' function. */
#undef HAVE_STRCHR
/* Define HAVE_STRERROR if you have the strerror() function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strstr' function. */
#undef HAVE_STRSTR
/* Define to 1 if you have the `system' function. */
#undef HAVE_SYSTEM
/* Define HAVE_SYS_ERRLIST if you have the sys_errlist[] variable. */
#undef HAVE_SYS_ERRLIST
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_IOCTL_H
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_PTEM_H
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_STREAM_H
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the header file. */
#undef HAVE_TERMCAP_H
/* Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr. */
#undef HAVE_TERMIOS_FUNCS
/* Define to 1 if you have the header file. */
#undef HAVE_TERMIOS_H
/* Define to 1 if you have the header file. */
#undef HAVE_TERMIO_H
/* Define to 1 if you have the header file. */
#undef HAVE_TIME_H
/* Define HAVE_TIME_T if your system supports the "time_t" type. */
#undef HAVE_TIME_T
/* Define to 1 if you have the header file. */
#undef HAVE_UNISTD_H
/* Define HAVE_UPPER_LOWER if you have isupper, islower, toupper, tolower. */
#undef HAVE_UPPER_LOWER
/* Henry Spencer V8 regcomp() and regexp.h */
#undef HAVE_V8_REGCOMP
/* Define to 1 if you have the header file. */
#undef HAVE_VALUES_H
/* Define HAVE_VOID if your compiler supports the "void" type. */
#undef HAVE_VOID
/* Define to 1 if you have the `_setjmp' function. */
#undef HAVE__SETJMP
/* Define MUST_DEFINE_ERRNO if you have errno but it is not define in errno.h.
*/
#undef MUST_DEFINE_ERRNO
/* Define MUST_DEFINE_OSPEED if you have ospeed but it is not defined in
termcap.h. */
#undef MUST_DEFINE_OSPEED
/* pattern matching is supported, but without metacharacters. */
#undef NO_REGEX
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
/* Define to 1 if the `S_IS*' macros in do not work properly. */
#undef STAT_MACROS_BROKEN
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if you can safely include both and . */
#undef TIME_WITH_SYS_TIME
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
/* Define for large files, on AIX-style hosts. */
#undef _LARGE_FILES
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `long' if does not define. */
#undef off_t
/* Define to `unsigned' if does not define. */
#undef size_t
less-382/mkinstalldirs 0100555 0000764 0000764 00000001211 10010075213 014135 0 ustar markn markn #!/bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman
# Created: 1993-05-16
# Last modified: 1994-03-25
# Public domain
errstatus=0
for file in ${1+"$@"} ; do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d in ${1+"$@"} ; do
pathcomp="$pathcomp$d"
case "$pathcomp" in
-* ) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp" 1>&2
mkdir "$pathcomp" || errstatus=$?
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# mkinstalldirs ends here
less-382/less.nro 0100444 0000764 0000764 00000164017 10010076271 013040 0 ustar markn markn .TH LESS 1 "Version 382: 03 Feb 2004"
.SH NAME
less \- opposite of more
.SH SYNOPSIS
.B "less -?"
.br
.B "less --help"
.br
.B "less -V"
.br
.B "less --version"
.br
.B "less [-[+]aBcCdeEfFgGiIJLmMnNqQrRsSuUVwWX~]"
.br
.B " [-b \fIspace\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]"
.br
.B " [-# \fIshift\fP] [+[+]\fIcmd\fP] [--] [\fIfilename\fP]..."
.br
(See the OPTIONS section for alternate option syntax with long option names.)
.SH DESCRIPTION
.I Less
is a program similar to
.I more
(1), but which allows backward movement
in the file as well as forward movement.
Also,
.I less
does not have to read the entire input file before starting,
so with large input files it starts up faster than text editors like
.I vi
(1).
.I Less
uses termcap (or terminfo on some systems),
so it can run on a variety of terminals.
There is even limited support for hardcopy terminals.
(On a hardcopy terminal, lines which should be printed at the top
of the screen are prefixed with a caret.)
.PP
Commands are based on both
.I more
and
.I vi.
Commands may be preceded by a decimal number,
called N in the descriptions below.
The number is used by some commands, as indicated.
.SH COMMANDS
In the following descriptions, ^X means control-X.
ESC stands for the ESCAPE key; for example ESC-v means the
two character sequence "ESCAPE", then "v".
.IP "h or H"
Help: display a summary of these commands.
If you forget all the other commands, remember this one.
.IP "SPACE or ^V or f or ^F"
Scroll forward N lines, default one window (see option -z below).
If N is more than the screen size, only the final screenful is displayed.
Warning: some systems use ^V as a special literalization character.
.IP "z"
Like SPACE, but if N is specified, it becomes the new window size.
.IP "ESC-SPACE"
Like SPACE, but scrolls a full screenful, even if it reaches
end-of-file in the process.
.IP "RETURN or ^N or e or ^E or j or ^J"
Scroll forward N lines, default 1.
The entire N lines are displayed, even if N is more than the screen size.
.IP "d or ^D"
Scroll forward N lines, default one half of the screen size.
If N is specified, it becomes the new default for
subsequent d and u commands.
.IP "b or ^B or ESC-v"
Scroll backward N lines, default one window (see option -z below).
If N is more than the screen size, only the final screenful is displayed.
.IP "w"
Like ESC-v, but if N is specified, it becomes the new window size.
.IP "y or ^Y or ^P or k or ^K"
Scroll backward N lines, default 1.
The entire N lines are displayed, even if N is more than the screen size.
Warning: some systems use ^Y as a special job control character.
.IP "u or ^U"
Scroll backward N lines, default one half of the screen size.
If N is specified, it becomes the new default for
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.
.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
Repaint the screen, discarding any buffered input.
Useful if the file is changing while it is being viewed.
.IP "F"
Scroll forward, and keep trying to read when the
end of file is reached.
Normally this command would be used when already at the end of the file.
It is a way to monitor the tail of a file which is growing
while it is being viewed.
(The behavior is similar to the "tail -f" command.)
.IP "g or < or ESC-<"
Go to line N in the file, default 1 (beginning of file).
(Warning: this may be slow if N is large.)
.IP "G or > or ESC->"
Go to line N in the file, default the end of the file.
(Warning: this may be slow if N is large,
or if N is not specified and
standard input, rather than a file, is being read.)
.IP "p or %"
Go to a position N percent into the file.
N should be between 0 and 100.
.IP "{"
If a left curly bracket appears in the top line displayed
on the screen,
the { command will go to the matching right curly bracket.
The matching right curly bracket is positioned on the bottom
line of the screen.
If there is more than one left curly bracket on the top line,
a number N may be used to specify the N-th bracket on the line.
.IP "}"
If a right curly bracket appears in the bottom line displayed
on the screen,
the } command will go to the matching left curly bracket.
The matching left curly bracket is positioned on the top
line of the screen.
If there is more than one right curly bracket on the top line,
a number N may be used to specify the N-th bracket on the line.
.IP "("
Like {, but applies to parentheses rather than curly brackets.
.IP ")"
Like }, but applies to parentheses rather than curly brackets.
.IP "["
Like {, but applies to square brackets rather than curly brackets.
.IP "]"
Like }, but applies to square brackets rather than curly brackets.
.IP "ESC-^F"
Followed by two characters,
acts like {, but uses the two characters as open and close brackets,
respectively.
For example, "ESC ^F < >" could be used to
go forward to the > which matches the < in the top displayed line.
.IP "ESC-^B"
Followed by two characters,
acts like }, but uses the two characters as open and close brackets,
respectively.
For example, "ESC ^B < >" could be used to
go backward to the < which matches the > in the bottom displayed line.
.IP m
Followed by any lowercase letter,
marks the current position with that letter.
.IP "'"
(Single quote.)
Followed by any lowercase letter, returns to the position which
was previously marked with that letter.
Followed by another single quote, returns to the position at
which the last "large" movement command was executed.
Followed by a ^ or $, jumps to the beginning or end of the
file respectively.
Marks are preserved when a new file is examined,
so the ' command can be used to switch between input files.
.IP "^X^X"
Same as single quote.
.IP /pattern
Search forward in the file for the N-th line containing the pattern.
N defaults to 1.
The pattern is a regular expression, as recognized by
.I ed.
The search starts at the second line displayed
(but see the -a and -j options, which change this).
.sp
Certain characters are special
if entered at the beginning of the pattern;
they modify the type of search rather than become part of the pattern:
.RS
.IP "^N or !"
Search for lines which do NOT match the pattern.
.IP "^E or *"
Search multiple files.
That is, if the search reaches the END of the current file
without finding a match,
the search continues in the next file in the command line list.
.IP "^F or @"
Begin the search at the first line of the FIRST file
in the command line list,
regardless of what is currently displayed on the screen
or the settings of the -a or -j options.
.IP "^K"
Highlight any text which matches the pattern on the current screen,
but don't move to the first match (KEEP current position).
.IP "^R"
Don't interpret regular expression metacharacters;
that is, do a simple textual comparison.
.RE
.IP ?pattern
Search backward in the file for the N-th line containing the pattern.
The search starts at the line immediately before the top line displayed.
.sp
Certain characters are special as in the / command:
.RS
.IP "^N or !"
Search for lines which do NOT match the pattern.
.IP "^E or *"
Search multiple files.
That is, if the search reaches the beginning of the current file
without finding a match,
the search continues in the previous file in the command line list.
.IP "^F or @"
Begin the search at the last line of the last file
in the command line list,
regardless of what is currently displayed on the screen
or the settings of the -a or -j options.
.IP "^K"
As in forward searches.
.IP "^R"
As in forward searches.
.RE
.IP "ESC-/pattern"
Same as "/*".
.IP "ESC-?pattern"
Same as "?*".
.IP n
Repeat previous search, for N-th line containing the last pattern.
If the previous search was modified by ^N, the search is made for the
N-th line NOT containing the pattern.
If the previous search was modified by ^E, the search continues
in the next (or previous) file if not satisfied in the current file.
If the previous search was modified by ^R, the search is done
without using regular expressions.
There is no effect if the previous search was modified by ^F or ^K.
.IP N
Repeat previous search, but in the reverse direction.
.IP "ESC-n"
Repeat previous search, but crossing file boundaries.
The effect is as if the previous search were modified by *.
.IP "ESC-N"
Repeat previous search, but in the reverse direction
and crossing file boundaries.
.IP "ESC-u"
Undo search highlighting.
Turn off highlighting of strings matching the current search pattern.
If highlighting is already off because of a previous ESC-u command,
turn highlighting back on.
Any search command will also turn highlighting back on.
(Highlighting can also be disabled by toggling the -G option;
in that case search commands do not turn highlighting back on.)
.IP ":e [filename]"
Examine a new file.
If the filename is missing, the "current" file (see the :n and :p commands
below) from the list of files in the command line is re-examined.
A percent sign (%) in the filename is replaced by the name of the
current file.
A pound sign (#) is replaced by the name of the previously examined file.
However, two consecutive percent signs are simply
replaced with a single percent sign.
This allows you to enter a filename that contains a percent sign
in the name.
Similarly, two consecutive pound signs are replaced with a single pound sign.
The filename is inserted into the command line list of files
so that it can be seen by subsequent :n and :p commands.
If the filename consists of several files, they are all inserted into
the list of files and the first one is examined.
If the filename contains one or more spaces,
the entire filename should be enclosed in double quotes
(also see the -" option).
.IP "^X^V or E"
Same as :e.
Warning: some systems use ^V as a special literalization character.
On such systems, you may not be able to use ^V.
.IP ":n"
Examine the next file (from the list of files given in the command line).
If a number N is specified, the N-th next file is examined.
.IP ":p"
Examine the previous file in the command line list.
If a number N is specified, the N-th previous file is examined.
.IP ":x"
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
and the line number and byte offset of the bottom line being displayed.
If possible, it also prints the length of the file,
the number of lines in the file
and the percent of the file above the last displayed line.
.IP \-
Followed by one of the command line option letters (see OPTIONS below),
this will change the setting of that option
and print a message describing the new setting.
If a ^P (CONTROL-P) is entered immediately after the dash,
the setting of the option is changed but no message is printed.
If the option letter has a numeric value (such as -b or -h),
or a string value (such as -P or -t),
a new value may be entered after the option letter.
If no new value is entered, a message describing
the current setting is printed and nothing is changed.
.IP \-\-
Like the \- command, but takes a long option name (see OPTIONS below)
rather than a single option letter.
You must press RETURN after typing the option name.
A ^P immediately after the second dash suppresses printing of a
message describing the new setting, as in the \- command.
.IP \-+
Followed by one of the command line option letters
this will reset the option to its default setting
and print a message describing the new setting.
(The "\-+\fIX\fP" command does the same thing
as "\-+\fIX\fP" on the command line.)
This does not work for string-valued options.
.IP \-\-+
Like the \-+ command, but takes a long option name
rather than a single option letter.
.IP \-!
Followed by one of the command line option letters,
this will reset the option to the "opposite" of its default setting
and print a message describing the new setting.
This does not work for numeric or string-valued options.
.IP \-\-!
Like the \-! command, but takes a long option name
rather than a single option letter.
.IP _
(Underscore.)
Followed by one of the command line option letters,
this will print a message describing the current setting of that option.
The setting of the option is not changed.
.IP __
(Double underscore.)
Like the _ (underscore) command, but takes a long option name
rather than a single option letter.
You must press RETURN after typing the option name.
.IP +cmd
Causes the specified cmd to be executed each time a new file is examined.
For example, +G causes
.I less
to initially display each file starting at the end
rather than the beginning.
.IP V
Prints the version number of
.I less
being run.
.IP "q or Q or :q or :Q or ZZ"
Exits
.I less.
.PP
The following
four
commands may or may not be valid, depending on your particular installation.
.PP
.IP v
Invokes an editor to edit the current file being viewed.
The editor is taken from the environment variable VISUAL if defined,
or EDITOR if VISUAL is not defined,
or defaults to "vi" if neither VISUAL nor EDITOR is defined.
See also the discussion of LESSEDIT under the section on PROMPTS below.
.IP "! shell-command"
Invokes a shell to run the shell-command given.
A percent sign (%) in the command is replaced by the name of the
current file.
A pound sign (#) is replaced by the name of the previously examined file.
"!!" repeats the last shell command.
"!" with no shell command simply invokes a shell.
On Unix systems, the shell is taken from the environment variable SHELL,
or defaults to "sh".
On MS-DOS and OS/2 systems, the shell is the normal command processor.
.IP "| shell-command"
represents any mark letter.
Pipes a section of the input file to the given shell command.
The section of the file to be piped is between the first line on
the current screen and the position marked by the letter.
may also be ^ or $ to indicate beginning or end of file respectively.
If is . or newline, the current screen is piped.
.IP "s filename"
Save the input to a file.
This only works if the input is a pipe, not an ordinary file.
.PP
.SH OPTIONS
Command line options are described below.
Most options may be changed while
.I less
is running, via the "\-" command.
.PP
Most options may be given in one of two forms:
either a dash followed by a single letter,
or two dashes followed by a long option name.
A long option name may be abbreviated as long as
the abbreviation is unambiguous.
For example, --quit-at-eof may be abbreviated --quit, but not
--qui, since both --quit-at-eof and --quiet begin with --qui.
Some long option names are in uppercase, such as --QUIT-AT-EOF, as
distinct from --quit-at-eof.
Such option names need only have their first letter capitalized;
the remainder of the name may be in either case.
For example, --Quit-at-eof is equivalent to --QUIT-AT-EOF.
.PP
Options are also taken from the environment variable "LESS".
For example,
to avoid typing "less -options ..." each time
.I less
is invoked, you might tell
.I csh:
.sp
setenv LESS "-options"
.sp
or if you use
.I sh:
.sp
LESS="-options"; export LESS
.sp
On MS-DOS, you don't need the quotes, but you should replace any
percent signs in the options string by double percent signs.
.sp
The environment variable is parsed before the command line,
so command line options override the LESS environment variable.
If an option appears in the LESS variable, it can be reset
to its default value on the command line by beginning the command
line option with "\-+".
.sp
For options like -P or -D which take a following string,
a dollar sign ($) must be used to signal the end of the string.
For example, to set two -D options on MS-DOS, you must have
a dollar sign between them, like this:
.sp
LESS="-Dn9.1$-Ds4.1"
.sp
.IP "-? or --help"
This option displays a summary of the commands accepted by
.I less
(the same as the h command).
(Depending on how your shell interprets the question mark,
it may be necessary to quote the question mark, thus: "-\e?".)
.IP "-a or --search-skip-screen"
Causes searches to start after the last line
displayed on the screen,
thus skipping all lines displayed on the screen.
By default, searches start at the second line on the screen
(or after the last found line; see the -j option).
.IP "-b\fIn\fP or --buffers=\fIn\fP"
Specifies the amount of buffer space
.I less
will use for each file, in units of kilobytes (1024 bytes).
By default 64K of buffer space is used for each file
(unless the file is a pipe; see the -B option).
The -b option specifies instead that \fIn\fP kilobytes of
buffer space should be used for each file.
If \fIn\fP is -1, buffer space is unlimited; that is,
the entire file is read into memory.
.IP "-B or --auto-buffers"
By default, when data is read from a pipe,
buffers are allocated automatically as needed.
If a large amount of data is read from the pipe, this can cause
a large amount of memory to be allocated.
The -B option disables this automatic allocation of buffers for pipes,
so that only 64K
(or the amount of space specified by the -b option)
is used for the pipe.
Warning: use of -B can result in erroneous display, since only the
most recently viewed part of the file is kept in memory;
any earlier data is lost.
.IP "-c or --clear-screen"
Causes full screen repaints to be painted from the top line down.
By default,
full screen repaints are done by scrolling from the bottom of the screen.
.IP "-C or --CLEAR-SCREEN"
The -C option is like -c, but the screen is cleared before it is repainted.
.IP "-d or --dumb"
The -d option suppresses the error message
normally displayed if the terminal is dumb;
that is, lacks some important capability,
such as the ability to clear the screen or scroll backward.
The -d option does not otherwise change the behavior of
.I less
on a dumb terminal.
.IP "-D\fBx\fP\fIcolor\fP or --color=\fBx\fP\fIcolor\fP"
[MS-DOS only]
Sets the color of the text displayed.
\fBx\fP is a single character which selects the type of text whose color is
being set: n=normal, s=standout, d=bold, u=underlined, k=blink.
\fIcolor\fP is a pair of numbers separated by a period.
The first number selects the foreground color and the second selects
the background color of the text.
A single number \fIN\fP is the same as \fIN.0\fP.
.IP "-e or --quit-at-eof"
Causes
.I less
to automatically exit
the second time it reaches end-of-file.
By default, the only way to exit
.I less
is via the "q" command.
.IP "-E or --QUIT-AT-EOF"
Causes
.I less
to automatically exit the first time it reaches end-of-file.
.IP "-f or --force"
Forces non-regular files to be opened.
(A non-regular file is a directory or a device special file.)
Also suppresses the warning message when a binary file is opened.
By default,
.I less
will refuse to open non-regular files.
.IP "-F or --quit-if-one-screen"
Causes
.I less
to automatically exit
if the entire file can be displayed on the first screen.
.IP "-g or --hilite-search"
Normally,
.I less
will highlight ALL strings which match the last search command.
The -g option changes this behavior to highlight only the particular string
which was found by the last search command.
This can cause
.I less
to run somewhat faster than the default.
.IP "-G or --HILITE-SEARCH"
The -G option suppresses all highlighting of strings found by search commands.
.IP "-h\fIn\fP or ---max-back-scroll=\fIn\fP"
Specifies a maximum number of lines to scroll backward.
If it is necessary to scroll backward more than \fIn\fP lines,
the screen is repainted in a forward direction instead.
(If the terminal does not have the ability to scroll
backward, -h0 is implied.)
.IP "-i or --ignore-case"
Causes searches to ignore case; that is,
uppercase and lowercase are considered identical.
This option is ignored if any uppercase letters
appear in the search pattern;
in other words,
if a pattern contains uppercase letters, then that search does not ignore case.
.IP "-I or --IGNORE-CASE"
Like -i, but searches ignore case even if
the pattern contains uppercase letters.
.IP "-j\fIn\fP or --jump-target=\fIn\fP"
Specifies a line on the screen where the "target" line
is to be positioned.
A target line is the object of a text search,
tag search, jump to a line number,
jump to a file percentage, or jump to a marked position.
The screen line is specified by a number: the top line on the screen
is 1, the next is 2, and so on.
The number may be negative to specify a line relative to the bottom
of the screen: the bottom line on the screen is -1, the second
to the bottom is -2, and so on.
If the -j option is used, searches begin at the line immediately
after the target line.
For example, if "-j4" is used, the target line is the
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 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
to open and interpret the named file as a
.I lesskey
(1) file.
Multiple -k options may be specified.
If the LESSKEY or LESSKEY_SYSTEM environment variable is set, or
if a lesskey file is found in a standard place (see KEY BINDINGS),
it is also used as a
.I lesskey
file.
.IP "-L or --no-lessopen"
Ignore the LESSOPEN environment variable
(see the INPUT PREPROCESSOR section below).
This option can be set from within \fIless\fP,
but it will apply only to files opened subsequently, not to the
file which is currently open.
.IP "-m or --long-prompt"
Causes
.I less
to prompt verbosely (like \fImore\fP),
with the percent into the file.
By default,
.I less
prompts with a colon.
.IP "-M or --LONG-PROMPT"
Causes
.I less
to prompt even more verbosely than
.I more.
.IP "-n or --line-numbers"
Suppresses line numbers.
The default (to use line numbers) may cause
.I less
to run more slowly in some cases, especially with a very large input file.
Suppressing line numbers with the -n option will avoid this problem.
Using line numbers means: the line number will be displayed in the verbose
prompt and in the = command,
and the v command will pass the current line number to the editor
(see also the discussion of LESSEDIT in PROMPTS below).
.IP "-N or --LINE-NUMBERS"
Causes a line number to be displayed at the beginning of
each line in the display.
.IP "-o\fIfilename\fP or --log-file=\fIfilename\fP"
Causes
.I less
to copy its input to the named file as it is being viewed.
This applies only when the input file is a pipe,
not an ordinary file.
If the file already exists,
.I less
will ask for confirmation before overwriting it.
.IP "-O\fIfilename\fP or --LOG-FILE=\fIfilename\fP"
The -O option is like -o, but it will overwrite an existing
file without asking for confirmation.
.sp
If no log file has been specified,
the -o and -O options can be used from within
.I less
to specify a log file.
Without a file name, they will simply report the name of the log file.
The "s" command is equivalent to specifying -o from within
.I less.
.IP "-p\fIpattern\fP or --pattern=\fIpattern\fP"
The -p option on the command line is equivalent to
specifying +/\fIpattern\fP;
that is, it tells
.I less
to start at the first occurrence of \fIpattern\fP in the file.
.IP "-P\fIprompt\fP or --prompt=\fIprompt\fP"
Provides a way to tailor the three prompt
styles to your own preference.
This option would normally be put in the LESS environment
variable, rather than being typed in with each
.I less
command.
Such an option must either be the last option in the LESS variable,
or be terminated by a dollar sign.
-Ps followed by a string changes the default (short) prompt
to that string.
-Pm changes the medium (-m) prompt.
-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.
.IP "-q or --quiet or --silent"
Causes moderately "quiet" operation:
the terminal bell is not rung
if an attempt is made to scroll past the end of the file
or before the beginning of the file.
If the terminal has a "visual bell", it is used instead.
The bell will be rung on certain other errors,
such as typing an invalid character.
The default is to ring the terminal bell in all such cases.
.IP "-Q or --QUIET or --SILENT"
Causes totally "quiet" operation:
the terminal bell is never rung.
.IP "-r or --raw-control-chars"
Causes "raw" control characters to be displayed.
The default is to display control characters using the caret notation;
for example, a control-A (octal 001) is displayed as "^A".
Warning: when the -r option is used,
.I less
cannot keep track of the actual appearance of the screen
(since this depends on how the screen responds to
each type of control character).
Thus, various display problems may result,
such as long lines being split in the wrong place.
.IP "-R or --RAW-CONTROL-CHARS"
Like -r, but tries to keep track of the screen appearance where possible.
This works only if the input consists of normal text and possibly some
ANSI "color" escape sequences, which are sequences of the form:
.sp
ESC [ ... m
.sp
where the "..." is zero or more characters other than "m".
For the purpose of keeping track of screen appearance,
all control characters and all ANSI color escape sequences are
assumed to not move the cursor.
You can make
.I less
think that characters other than "m" can end ANSI color escape sequences
by setting the environment variable LESSANSIENDCHARS to the list of
characters which can end a color escape sequence.
.IP "-s or --squeeze-blank-lines"
Causes consecutive blank lines to be squeezed into a single blank line.
This is useful when viewing
.I nroff
output.
.IP "-S or --chop-long-lines"
Causes lines longer than the screen width to be
chopped rather than folded.
That is, the portion of a long line that does not fit in
the screen width is not shown.
The default is to fold long lines; that is, display the remainder
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, 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) 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 https://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
.I less.
.IP "-T\fItagsfile\fP or --tag-file=\fItagsfile\fP"
Specifies a tags file to be used instead of "tags".
.IP "-u or --underline-special"
Causes backspaces and carriage returns to be treated as printable characters;
that is, they are sent to the terminal when they appear in the input.
.IP "-U or --UNDERLINE-SPECIAL"
Causes backspaces, tabs and carriage returns to be
treated as control characters;
that is, they are handled as specified by the -r option.
.sp
By default, if neither -u nor -U is given,
backspaces which appear adjacent to an underscore character
are treated specially:
the underlined text is displayed
using the terminal's hardware underlining capability.
Also, backspaces which appear between two identical characters
are treated specially:
the overstruck text is printed
using the terminal's hardware boldface capability.
Other backspaces are deleted, along with the preceding character.
Carriage returns immediately followed by a newline are deleted.
other carriage returns are handled as specified by the -r option.
Text which is overstruck or underlined can be searched for
if neither -u nor -U is in effect.
.IP "-V or --version"
Displays the version number of
.I less.
.IP "-w or --hilite-unread"
Temporarily highlights the first "new" line after a forward movement
of a full page.
The first "new" line is the line immediately following the line previously
at the bottom of the screen.
Also highlights the target line after a g or p command.
The highlight is removed at the next command which causes movement.
The entire line is highlighted, unless the -J option is in effect,
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.
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,
the screen is repainted instead.
The -c or -C option may be used to repaint from the top of
the screen if desired.
By default, any forward movement causes scrolling.
.IP "-[z]\fIn\fP or --window=\fIn\fP"
Changes the default scrolling window size to \fIn\fP lines.
The default is one screenful.
The z and w commands can also be used to change the window size.
The "z" may be omitted for compatibility with
.I more.
If the number
.I n
is negative, it indicates
.I n
lines less than the current screen size.
For example, if the screen is 24 lines, \fI-z-4\fP sets the
scrolling window to 20 lines. If the screen is resized to 40 lines,
the scrolling window automatically changes to 36 lines.
.IP "-\fI\(dqcc\fP\ or\ --quotes=\fIcc\fP"
Changes the filename quoting character.
This may be necessary if you are trying to name a file
which contains both spaces and quote characters.
Followed by a single character, this changes the quote character to that
character.
Filenames containing a space should then be surrounded by that character
rather than by double quotes.
Followed by two characters, changes the open quote to the first character,
and the close quote to the second character.
Filenames containing a space should then be preceded by the open quote
character and followed by the close quote character.
Note that even after the quote characters are changed, this option
remains -" (a dash followed by a double quote).
.IP "-~ or --tilde"
Normally lines after end of file are displayed as a single tilde (~).
This option causes lines after end of file to be displayed as blank lines.
.IP "-# or --shift"
Specifies the default number of positions to scroll horizontally
in the RIGHTARROW and LEFTARROW commands.
If the number specified is zero, it sets the default number of
positions to one half of the screen width.
.IP --
A command line argument of "--" marks the end of option arguments.
Any arguments following this are interpreted as filenames.
This can be useful when viewing a file whose name begins with a "-" or "+".
.IP +
If a command line option begins with \fB+\fP,
the remainder of that option is taken to be an initial command to
.I less.
For example, +G tells
.I less
to start at the end of the file rather than the beginning,
and +/xyz tells it to start at the first occurrence of "xyz" in the file.
As a special case, + acts like +g;
that is, it starts the display at the specified line number
(however, see the caveat under the "g" command above).
If the option starts with ++, the initial command applies to
every file being viewed, not just the first one.
The + command described previously
may also be used to set (or change) an initial command for every file.
.SH "LINE EDITING"
When entering command line at the bottom of the screen
(for example, a filename for the :e command,
or the pattern for a search command),
certain keys can be used to manipulate the command line.
Most commands have an alternate form in [ brackets ] which can be used if
a key does not exist on a particular keyboard.
(The bracketed forms do not work in the MS-DOS version.)
Any of these special keys may be entered literally by preceding
it with the "literal" character, either ^V or ^A.
A backslash itself may also be entered literally by entering two backslashes.
.IP "LEFTARROW [ ESC-h ]"
Move the cursor one space to the left.
.IP "RIGHTARROW [ ESC-l ]"
Move the cursor one space to the right.
.IP "^LEFTARROW [ ESC-b or ESC-LEFTARROW ]"
(That is, CONTROL and LEFTARROW simultaneously.)
Move the cursor one word to the left.
.IP "^RIGHTARROW [ ESC-w or ESC-RIGHTARROW ]"
(That is, CONTROL and RIGHTARROW simultaneously.)
Move the cursor one word to the right.
.IP "HOME [ ESC-0 ]"
Move the cursor to the beginning of the line.
.IP "END [ ESC-$ ]"
Move the cursor to the end of the line.
.IP "BACKSPACE"
Delete the character to the left of the cursor,
or cancel the command if the command line is empty.
.IP "DELETE or [ ESC-x ]"
Delete the character under the cursor.
.IP "^BACKSPACE [ ESC-BACKSPACE ]"
(That is, CONTROL and BACKSPACE simultaneously.)
Delete the word to the left of the cursor.
.IP "^DELETE [ ESC-X or ESC-DELETE ]"
(That is, CONTROL and DELETE simultaneously.)
Delete the word under the cursor.
.IP "UPARROW [ ESC-k ]"
Retrieve the previous command line.
.IP "DOWNARROW [ ESC-j ]"
Retrieve the next command line.
.IP "TAB"
Complete the partial filename to the left of the cursor.
If it matches more than one filename, the first match
is entered into the command line.
Repeated TABs will cycle thru the other matching filenames.
If the completed filename is a directory, a "/" is appended to the filename.
(On MS-DOS systems, a "\e" is appended.)
The environment variable LESSSEPARATOR can be used to specify a
different character to append to a directory name.
.IP "BACKTAB [ ESC-TAB ]"
Like, TAB, but cycles in the reverse direction thru the matching filenames.
.IP "^L"
Complete the partial filename to the left of the cursor.
If it matches more than one filename, all matches are entered into
the command line (if they fit).
.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
other than ^U, that character is used instead of ^U.
.SH "KEY BINDINGS"
You may define your own
.I less
commands by using the program
.I lesskey
(1)
to create a lesskey file.
This file specifies a set of command keys and an action
associated with each key.
You may also use
.I lesskey
to change the line-editing keys (see LINE EDITING),
and to set environment variables.
If the environment variable LESSKEY is set,
.I less
uses that as the name of the lesskey file.
Otherwise,
.I less
looks in a standard place for the lesskey file:
On Unix systems,
.I less
looks for a lesskey file called "$HOME/.less".
On MS-DOS and Windows systems,
.I less
looks for a lesskey file called "$HOME/_less", and if it is not found there,
then looks for a lesskey file called "_less" in any directory specified
in the PATH environment variable.
On OS/2 systems,
.I less
looks for a lesskey file called "$HOME/less.ini", and if it is not found,
then looks for a lesskey file called "less.ini" in any directory specified
in the INIT environment variable, and if it not found there,
then looks for a lesskey file called "less.ini" in any directory specified
in the PATH environment variable.
See the
.I lesskey
manual page for more details.
.P
A system-wide lesskey file may also be set up to provide key bindings.
If a key is defined in both a local lesskey file and in the
system-wide file, key bindings in the local file take precedence over
those in the system-wide file.
If the environment variable LESSKEY_SYSTEM is set,
.I less
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/etc/sysless.
(However, if
.I less
was built with a different sysconf directory than /usr/local/etc,
that directory is where the sysless file is found.)
On MS-DOS and Windows systems, the system-wide lesskey file is c:\e_sysless.
On OS/2 systems, the system-wide lesskey file is c:\esysless.ini.
.SH "INPUT PREPROCESSOR"
You may define an "input preprocessor" for
.I less.
Before
.I less
opens a file, it first gives your input preprocessor a chance to modify the
way the contents of the file are displayed.
An input preprocessor is simply an executable program (or shell script),
which writes the contents of the file to a different file,
called the replacement file.
The contents of the replacement file are then displayed
in place of the contents of the original file.
However, it will appear to the user as if the original file is opened;
that is,
.I less
will display the original filename as the name of the current file.
.PP
An input preprocessor receives one command line argument, the original filename,
as entered by the user.
It should create the replacement file, and when finished,
print the name of the replacement file to its standard output.
If the input preprocessor does not output a replacement filename,
.I less
uses the original file, as normal.
The input preprocessor is not called when viewing standard input.
To set up an input preprocessor, set the LESSOPEN environment variable
to a command line which will invoke your input preprocessor.
This command line should include one occurrence of the string "%s",
which will be replaced by the filename
when the input preprocessor command is invoked.
.PP
When
.I less
closes a file opened in such a way, it will call another program,
called the input postprocessor,
which may perform any desired clean-up action (such as deleting the
replacement file created by LESSOPEN).
This program receives two command line arguments, the original filename
as entered by the user, and the name of the replacement file.
To set up an input postprocessor, set the LESSCLOSE environment variable
to a command line which will invoke your input postprocessor.
It may include two occurrences of the string "%s";
the first is replaced with the original name of the file and
the second with the name of the replacement file,
which was output by LESSOPEN.
.PP
For example, on many Unix systems, these two scripts will allow you
to keep files in compressed format, but still let
.I less
view them directly:
.PP
lessopen.sh:
.br
#! /bin/sh
.br
case "$1" in
.br
*.Z) uncompress -c $1 >/tmp/less.$$ 2>/dev/null
.br
if [ -s /tmp/less.$$ ]; then
.br
echo /tmp/less.$$
.br
else
.br
rm -f /tmp/less.$$
.br
fi
.br
;;
.br
esac
.PP
lessclose.sh:
.br
#! /bin/sh
.br
rm $2
.PP
To use these scripts, put them both where they can be executed and
set LESSOPEN="lessopen.sh\ %s", and
LESSCLOSE="lessclose.sh\ %s\ %s".
More complex LESSOPEN and LESSCLOSE scripts may be written
to accept other types of compressed files, and so on.
.PP
It is also possible to set up an input preprocessor to
pipe the file data directly to
.I less,
rather than putting the data into a replacement file.
This avoids the need to decompress the entire file before
starting to view it.
An input preprocessor that works this way is called an input pipe.
An input pipe, instead of writing the name of a replacement file on
its standard output,
writes the entire contents of the replacement file on its standard output.
If the input pipe does not write any characters on its standard output,
then there is no replacement file and
.I less
uses the original file, as normal.
To use an input pipe,
make the first character in the LESSOPEN environment variable a
vertical bar (|) to signify that the input preprocessor is an input pipe.
.PP
For example, on many Unix systems, this script will work like the
previous example scripts:
.PP
lesspipe.sh:
.br
#! /bin/sh
.br
case "$1" in
.br
*.Z) uncompress -c $1 2>/dev/null
.br
;;
.br
esac
.br
.PP
To use this script, put it where it can be executed and set
LESSOPEN="|lesspipe.sh %s".
When an input pipe is used, a LESSCLOSE postprocessor can be used,
but it is usually not necessary since there is no replacement file
to clean up.
In this case, the replacement file name passed to the LESSCLOSE
postprocessor is "-".
.SH "NATIONAL CHARACTER SETS"
There are three types of characters in the input file:
.IP "normal characters"
can be displayed directly to the screen.
.IP "control characters"
should not be displayed directly, but are expected to be found
in ordinary text files (such as backspace and tab).
.IP "binary characters"
should not be displayed directly and are not expected to be found
in text files.
.PP
A "character set" is simply a description of which characters are to
be considered normal, control, and binary.
The LESSCHARSET environment variable may be used to select a character set.
Possible values for LESSCHARSET are:
.IP ascii
BS, TAB, NL, CR, and formfeed are control characters,
all chars with values between 32 and 126 are normal,
and all others are binary.
.IP iso8859
Selects an ISO 8859 character set.
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
Selects a character set appropriate for NeXT computers.
.IP utf-8
Selects the UTF-8 encoding of the ISO 10646 character set.
.PP
In special cases, it may be desired to tailor
.I less
to use a character set other than the ones definable by LESSCHARSET.
In this case, the environment variable LESSCHARDEF can be used
to define a character set.
It should be set to a string where each character in the string represents
one character in the character set.
The character "." is used for a normal character, "c" for control,
and "b" for binary.
A decimal number may be used for repetition.
For example, "bccc4b." would mean character 0 is binary,
1, 2 and 3 are control, 4, 5, 6 and 7 are binary, and 8 is normal.
All characters after the last are taken to be the same as the last,
so characters 9 through 255 would be normal.
(This is an example, and does not necessarily
represent any real character set.)
.PP
This table shows the value of LESSCHARDEF which is equivalent
to each of the possible values for LESSCHARSET:
.sp
ascii\ 8bcccbcc18b95.b
.br
dos\ \ \ 8bcccbcc12bc5b95.b.
.br
ebcdic 5bc6bcc7bcc41b.9b7.9b5.b..8b6.10b6.b9.7b
.br
\ \ \ \ \ \ 9.8b8.17b3.3b9.7b9.8b8.6b10.b.b.b.
.br
IBM-1047 4cbcbc3b9cbccbccbb4c6bcc5b3cbbc4bc4bccbc
.br
\ \ \ \ \ \ 191.b
.br
iso8859 8bcccbcc18b95.33b.
.br
koi8-r 8bcccbcc18b95.b128.
.br
latin1 8bcccbcc18b95.33b.
.br
next\ \ 8bcccbcc18b95.bb125.bb
.PP
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.
.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
(e.g. ^A for control-A). Caret notation is used only if
inverting the 0100 bit results in a normal printable character.
Otherwise, the character is displayed as a hex number in angle brackets.
This format can be changed by
setting the LESSBINFMT environment variable.
LESSBINFMT may begin with a "*" and one character to select
the display attribute:
"*k" is blinking, "*d" is bold, "*u" is underlined, "*s" is standout,
and "*n" is normal.
If LESSBINFMT does not begin with a "*", normal attribute is assumed.
The remainder of LESSBINFMT is a string which may include one
printf-style escape sequence (a % followed by x, X, o, d, etc.).
For example, if LESSBINFMT is "*u[%x]", binary characters
are displayed in underlined hexadecimal surrounded by brackets.
The default if no LESSBINFMT is specified is "*s<%X>".
.SH "PROMPTS"
The -P option allows you to tailor the prompt to your preference.
The string given to the -P option replaces the specified prompt string.
Certain characters in the string are interpreted specially.
The prompt mechanism is rather complicated to provide flexibility,
but the ordinary user need not understand the details of constructing
personalized prompt strings.
.sp
A percent sign followed by a single character is expanded
according to what the following character is:
.IP "%b\fIX\fP"
Replaced by the byte offset into the current input file.
The b is followed by a single character (shown as \fIX\fP above)
which specifies the line whose byte offset is to be used.
If the character is a "t", the byte offset of the top line in the
display is used,
an "m" means use the middle line,
a "b" means use the bottom line,
a "B" means use the line just after the bottom line,
and a "j" means use the "target" line, as specified by the -j option.
.IP "%B"
Replaced by the size of the current input file.
.IP "%c"
Replaced by the column number of the text appearing in the first
column of the screen.
.IP "%d\fIX\fP"
Replaced by the page number of a line in the input file.
The line to be used is determined by the \fIX\fP, as with the %b option.
.IP "%D"
Replaced by the number of pages in the input file,
or equivalently, the page number of the last line in the input file.
.IP "%E"
Replaced by the name of the editor (from the VISUAL environment variable,
or the EDITOR environment variable if VISUAL is not defined).
See the discussion of the LESSEDIT feature below.
.IP "%f"
Replaced by the name of the current input file.
.IP "%i"
Replaced by the index of the current file in the list of
input files.
.IP "%l\fIX\fP"
Replaced by the line number of a line in the input file.
The line to be used is determined by the \fIX\fP, as with the %b option.
.IP "%L"
Replaced by the line number of the last line in the input file.
.IP "%m"
Replaced by the total number of input files.
.IP "%p\fIX\fP"
Replaced by the percent into the current input file, based on byte offsets.
The line used is determined by the \fIX\fP as with the %b option.
.IP "%P\fIX\fP"
Replaced by the percent into the current input file, based on line numbers.
The line used is determined by the \fIX\fP as with the %b option.
.IP "%s"
Same as %B.
.IP "%t"
Causes any trailing spaces to be removed.
Usually used at the end of the string, but may appear anywhere.
.IP "%x"
Replaced by the name of the next input file in the list.
.PP
If any item is unknown (for example, the file size if input
is a pipe), a question mark is printed instead.
.PP
The format of the prompt string can be changed
depending on certain conditions.
A question mark followed by a single character acts like an "IF":
depending on the following character, a condition is evaluated.
If the condition is true, any characters following the question mark
and condition character, up to a period, are included in the prompt.
If the condition is false, such characters are not included.
A colon appearing between the question mark and the
period can be used to establish an "ELSE": any characters between
the colon and the period are included in the string if and only if
the IF condition is false.
Condition characters (which follow a question mark) may be:
.IP "?a"
True if any characters have been included in the prompt so far.
.IP "?b\fIX\fP"
True if the byte offset of the specified line is known.
.IP "?B"
True if the size of current input file is known.
.IP "?c"
True if the text is horizontally shifted (%c is not zero).
.IP "?d\fIX\fP"
True if the page number of the specified line is known.
.IP "?e"
True if at end-of-file.
.IP "?f"
True if there is an input filename
(that is, if input is not a pipe).
.IP "?l\fIX\fP"
True if the line number of the specified line is known.
.IP "?L"
True if the line number of the last line in the file is known.
.IP "?m"
True if there is more than one input file.
.IP "?n"
True if this is the first prompt in a new input file.
.IP "?p\fIX\fP"
True if the percent into the current input file, based on byte offsets,
of the specified line is known.
.IP "?P\fIX\fP"
True if the percent into the current input file, based on line numbers,
of the specified line is known.
.IP "?s"
Same as "?B".
.IP "?x"
True if there is a next input file
(that is, if the current input file is not the last one).
.PP
Any characters other than the special ones
(question mark, colon, period, percent, and backslash)
become literally part of the prompt.
Any of the special characters may be included in the prompt literally
by preceding it with a backslash.
.PP
Some examples:
.sp
?f%f:Standard input.
.sp
This prompt prints the filename, if known;
otherwise the string "Standard input".
.sp
?f%f .?ltLine %lt:?pt%pt\e%:?btByte %bt:-...
.sp
This prompt would print the filename, if known.
The filename is followed by the line number, if known,
otherwise the percent if known, otherwise the byte offset if known.
Otherwise, a dash is printed.
Notice how each question mark has a matching period,
and how the % after the %pt
is included literally by escaping it with a backslash.
.sp
?n?f%f\ .?m(file\ %i\ of\ %m)\ ..?e(END)\ ?x-\ Next\e:\ %x..%t
.sp
This prints the filename if this is the first prompt in a file,
followed by the "file N of N" message if there is more
than one input file.
Then, if we are at end-of-file, the string "(END)" is printed
followed by the name of the next file, if there is one.
Finally, any trailing spaces are truncated.
This is the default prompt.
For reference, here are the defaults for
the other two prompts (-m and -M respectively).
Each is broken into two lines here for readability only.
.nf
.sp
?n?f%f\ .?m(file\ %i\ of\ %m)\ ..?e(END)\ ?x-\ Next\e:\ %x.:
?pB%pB\e%:byte\ %bB?s/%s...%t
.sp
?f%f\ .?n?m(file\ %i\ of\ %m)\ ..?ltlines\ %lt-%lb?L/%L.\ :
byte\ %bB?s/%s.\ .?e(END)\ ?x-\ Next\e:\ %x.:?pB%pB\e%..%t
.sp
.fi
And here is the default message produced by the = command:
.nf
.sp
?f%f\ .?m(file\ %i\ of\ %m)\ .?ltlines\ %lt-%lb?L/%L.\ .
byte\ %bB?s/%s.\ ?e(END)\ :?pB%pB\e%..%t
.fi
.PP
The prompt expansion features are also used for another purpose:
if an environment variable LESSEDIT is defined, it is used
as the command to be executed when the v command is invoked.
The LESSEDIT string is expanded in the same way as the prompt strings.
The default value for LESSEDIT is:
.nf
.sp
%E\ ?lm+%lm.\ %f
.sp
.fi
Note that this expands to the editor name, followed by a + and the
line number, followed by the file name.
If your editor does not accept the "+linenumber" syntax, or has other
differences in invocation syntax, the LESSEDIT variable can be
changed to modify this default.
.SH SECURITY
When the environment variable LESSSECURE is set to 1,
.I less
runs in a "secure" mode.
This means these features are disabled:
.RS
.IP "!"
the shell command
.IP "|"
the pipe command
.IP ":e"
the examine command.
.IP "v"
the editing command
.IP "s -o"
log files
.IP "-k"
use of lesskey files
.IP "-t"
use of tags files
.IP " "
metacharacters in filenames, such as *
.IP " "
filename completion (TAB, ^L)
.RE
.PP
Less can also be compiled to be permanently in "secure" mode.
.SH "ENVIRONMENT VARIABLES"
Environment variables may be specified either in the system environment
as usual, or in a
.I lesskey
(1) file.
If environment variables are defined in more than one place,
variables defined in a local lesskey file take precedence over
variables defined in the system environment, which take precedence
over variables defined in the system-wide lesskey file.
.IP COLUMNS
Sets the number of columns on the screen.
Takes precedence over the number of columns specified by the TERM variable.
(But if you have a windowing system which supports TIOCGWINSZ or WIOCGETD,
the window system's idea of the screen size takes precedence over the
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 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
(only in the Windows version).
.IP INIT
Name of the user's init directory (used to find a lesskey file on OS/2 systems).
.IP LANG
Language for determining the character set.
.IP LC_CTYPE
Language for determining the character set.
.IP LESS
Options which are passed to
.I less
automatically.
.IP LESSANSIENDCHARS
Characters which are assumed to end an ANSI color escape sequence
(default "m").
.IP LESSBINFMT
Format for displaying non-printable, non-control characters.
.IP LESSCHARDEF
Defines a character set.
.IP LESSCHARSET
Selects a predefined character set.
.IP LESSCLOSE
Command line to invoke the (optional) input-postprocessor.
.IP LESSECHO
Name of the lessecho program (default "lessecho").
The lessecho program is needed to expand metacharacters, such as * and ?,
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
Name of the default system-wide lesskey(1) file.
.IP LESSMETACHARS
List of characters which are considered "metacharacters" by the shell.
.IP LESSMETAESCAPE
Prefix which less will add before each metacharacter in a
command sent to the shell.
If LESSMETAESCAPE is an empty string, commands containing
metacharacters will not be passed to the shell.
.IP LESSOPEN
Command line to invoke the (optional) input-preprocessor.
.IP LESSSECURE
Runs less in "secure" mode.
See discussion under SECURITY.
.IP LESSSEPARATOR
String to be appended to a directory name in filename completion.
.IP LINES
Sets the number of lines on the screen.
Takes precedence over the number of lines specified by the TERM variable.
(But if you have a windowing system which supports TIOCGWINSZ or WIOCGETD,
the window system's idea of the screen size takes precedence over the
LINES and COLUMNS environment variables.)
.IP PATH
User's search path (used to find a lesskey file
on MS-DOS and OS/2 systems).
.IP SHELL
The shell used to execute the ! command, as well as to expand filenames.
.IP TERM
The type of terminal on which
.I less
is being run.
.IP VISUAL
The name of the editor (used for the v command).
.SH "SEE ALSO"
lesskey(1)
.SH WARNINGS
The = command and prompts (unless changed by -P)
report the line numbers of the lines at the top and bottom of the screen,
but the byte and percent of the line after the one at the bottom of the screen.
.PP
If the :e command is used to name more than one file,
and one of the named files has been viewed previously,
the new files may be entered into the list in an unexpected order.
.PP
On certain older terminals (the so-called "magic cookie" terminals),
search highlighting will cause an erroneous display.
On such terminals, search highlighting is disabled by default
to avoid possible problems.
.PP
In certain cases, when search highlighting is enabled and
a search pattern begins with a ^,
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
rather than binary characters.
This causes
.I less
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 https://www.greenwoodsoftware.com/less for the latest list of known bugs in this
version of less.
.SH COPYRIGHT
Copyright (C) 2002 Mark Nudelman
.PP
less is part of the GNU project and is free software.
You can redistribute it and/or modify it
under the terms of either
(1) the GNU General Public License as published by
the Free Software Foundation; or (2) the Less License.
See the file README in the less distribution for more details
regarding redistribution.
You should have received a copy of the GNU General Public License
along with the source for less; see the file COPYING.
If not, write to the Free Software Foundation, 59 Temple Place,
Suite 330, Boston, MA 02111-1307, USA.
You should also have received a copy of the Less License;
see the file LICENSE.
.PP
less is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
.SH AUTHOR
.PP
Mark Nudelman
.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 https://www.greenwoodsoftware.com/less.
less-382/lesskey.nro 0100444 0000764 0000764 00000022610 10010076271 013541 0 ustar markn markn .TH LESSKEY 1 "Version 382: 03 Feb 2004"
.SH NAME
lesskey \- specify key bindings for less
.SH SYNOPSIS
.B "lesskey [-o output] [--] [input]"
.br
.B "lesskey [--output=output] [--] [input]"
.br
.B "lesskey -V"
.br
.B "lesskey --version"
.SH DESCRIPTION
.I Lesskey
is used to specify a set of key bindings to be used by
.I less.
The input file is a text file which describes the key bindings,
If the input file is "-", standard input is read.
If no input file is specified, a standard filename is used
as the name of the input file, which depends on the system being used:
On Unix systems, $HOME/.lesskey is used;
on MS-DOS systems, $HOME/_lesskey is used;
and on OS/2 systems $HOME/lesskey.ini is used,
or $INIT/lesskey.ini if $HOME is undefined.
The output file is a binary file which is used by
.I less.
If no output file is specified,
and the environment variable LESSKEY is set,
the value of LESSKEY is used as the name of the output file.
Otherwise, a standard filename is used as the name of the output file,
which depends on the system being used:
On Unix and OS-9 systems, $HOME/.less is used;
on MS-DOS systems, $HOME/_less is used;
and on OS/2 systems, $HOME/less.ini is used,
or $INIT/less.ini if $HOME is undefined.
If the output file already exists,
.I lesskey
will overwrite it.
.PP
The -V or --version option causes
.I lesskey
to print its version number and immediately exit.
If -V or --version is present, other options and arguments are ignored.
.PP
The input file consists of one or more
.I sections.
Each section starts with a line that identifies the type of section.
Possible sections are:
.IP #command
Defines new command keys.
.IP #line-edit
Defines new line-editing keys.
.IP #env
Defines environment variables.
.PP
Blank lines and lines which start with a pound sign (#) are ignored,
except for the special section header lines.
.SH "COMMAND SECTION"
The command section begins with the line
.sp
#command
.sp
If the command section is the first section in the file,
this line may be omitted.
The command section consists of lines of the form:
.sp
\fIstring\fP \fIaction\fP [extra-string]
.sp
Whitespace is any sequence of one or more spaces and/or tabs.
The \fIstring\fP is the command key(s) which invoke the action.
The \fIstring\fP may be a single command key, or a sequence of up to 15 keys.
The \fIaction\fP is the name of the less action, from the list below.
The characters in the \fIstring\fP 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 characters specifies input
characters as follows:
.IP \eb
BACKSPACE
.IP \ee
ESCAPE
.IP \en
NEWLINE
.IP \er
RETURN
.IP \et
TAB
.IP \eku
UP ARROW
.IP \ekd
DOWN ARROW
.IP \ekr
RIGHT ARROW
.IP \ekl
LEFT ARROW
.IP \ekU
PAGE UP
.IP \ekD
PAGE DOWN
.IP \ekh
HOME
.IP \eke
END
.IP \ekx
DELETE
.PP
A backslash followed by any other character indicates that character is
to be taken literally.
Characters which must be preceded by backslash include
caret, space, tab and the backslash itself.
.PP
An action may be followed by an "extra" string.
When such a command is entered while running
.I less,
the action is performed, and then the extra
string is parsed, just as if it were typed in to
.I less.
This feature can be used in certain cases to extend
the functionality of a command.
For example, see the "{" and ":t" commands in the example below.
The extra string has a special meaning for the "quit" action:
when
.I less
quits, first character of the extra string is used as its exit status.
.SH EXAMPLE
The following input file describes the set of
default command keys used by less:
.sp
.nf
#command
\er forw-line
\en forw-line
e forw-line
j forw-line
\ekd forw-line
^E forw-line
^N forw-line
k back-line
y back-line
^Y back-line
^K back-line
^P back-line
J forw-line-force
K back-line-force
Y back-line-force
d forw-scroll
^D forw-scroll
u back-scroll
^U back-scroll
\e40 forw-screen
f forw-screen
^F forw-screen
^V forw-screen
\ekD forw-screen
b back-screen
^B back-screen
\eev back-screen
\ekU back-screen
z forw-window
w back-window
\ee\e40 forw-screen-force
F forw-forever
R repaint-flush
r repaint
^R repaint
^L repaint
\eeu undo-hilite
g goto-line
\ekh goto-line
< goto-line
\ee< goto-line
p percent
% percent
\ee[ left-scroll
\ee] right-scroll
\ee( left-scroll
\ee) right-scroll
{ forw-bracket {}
} back-bracket {}
( forw-bracket ()
) back-bracket ()
[ forw-bracket []
] back-bracket []
\ee^F forw-bracket
\ee^B back-bracket
G goto-end
\ee> goto-end
> goto-end
\eke goto-end
= status
^G status
:f status
/ forw-search
? back-search
\ee/ forw-search *
\ee? back-search *
n repeat-search
\een repeat-search-all
N reverse-search
\eeN reverse-search-all
m set-mark
' goto-mark
^X^X goto-mark
E examine
:e examine
^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
_ display-option
| pipe
v visual
! shell
+ firstcmd
H help
h help
V version
0 digit
1 digit
2 digit
3 digit
4 digit
5 digit
6 digit
7 digit
8 digit
9 digit
q quit
Q quit
:q quit
:Q quit
ZZ quit
.fi
.sp
.SH PRECEDENCE
Commands specified by
.I lesskey
take precedence over the default commands.
A default command key may be disabled by including it in the
input file with the action "invalid".
Alternatively, a key may be defined
to do nothing by using the action "noaction".
"noaction" is similar to "invalid", but
.I less
will give an error beep for an "invalid" command,
but not for a "noaction" command.
In addition, ALL default commands may be disabled by
adding this control line to the input file:
.sp
#stop
.sp
This will cause all default commands to be ignored.
The #stop line should be the last line in that section of the file.
.PP
Be aware that #stop can be dangerous.
Since all default commands are disabled,
you must provide sufficient commands before the #stop line
to enable all necessary actions.
For example, failure to provide a "quit" command can lead to frustration.
.SH "LINE EDITING SECTION"
The line-editing section begins with the line:
.sp
#line-edit
.sp
This section specifies new key bindings for the line editing commands,
in a manner similar to the way key bindings for
ordinary commands are specified in the #command section.
The line-editing section consists of a list of keys and actions,
one per line as in the example below.
.SH EXAMPLE
The following input file describes the set of
default line-editing keys used by less:
.sp
.nf
#line-edit
\et forw-complete
\e17 back-complete
\ee\et back-complete
^L expand
^V literal
^A literal
\eel right
\ekr right
\eeh left
\ekl left
\eeb word-left
\ee\ekl word-left
\eew word-right
\ee\ekr word-right
\eei insert
\eex delete
\ekx delete
\eeX word-delete
\eekx word-delete
\ee\eb word-backspace
\ee0 home
\ekh home
\ee$ end
\eke end
\eek up
\eku up
\eej down
.fi
.sp
.SH "LESS ENVIRONMENT VARIABLES"
The environment variable section begins with the line
.sp
#env
.sp
Following this line is a list of environment variable assignments.
Each line consists of an environment variable 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 way are visible only to
.I less.
If a variable is specified in the system environment and also in a
lesskey file, the value in the lesskey file takes precedence.
Although the lesskey file can be used to override variables set in the
environment, the main purpose of assigning variables in the lesskey file
is simply to have all
.I less
configuration information stored in one file.
.SH EXAMPLE
The following input file sets the -i option whenever
.I less
is run, and specifies the character set to be "latin1":
.sp
.nf
#env
LESS = -i
LESSCHARSET = latin1
.fi
.sp
.SH "SEE ALSO"
less(1)
.SH WARNINGS
It is not possible to specify special keys, such as uparrow,
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 key is pressed.
.PP
On MS-DOS and OS/2 systems, certain keys send a sequence of characters
which start with a NUL character (0).
This NUL character should be represented as \e340 in a lesskey file.
.SH COPYRIGHT
Copyright (C) 2000 Mark Nudelman
.PP
lesskey is part of the GNU project and is free software;
you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation;
either version 2, or (at your option) any later version.
.PP
lesskey is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
.PP
You should have received a copy of the GNU General Public License
along with lesskey; see the file COPYING.
If not, write to the Free Software Foundation, 59 Temple Place,
Suite 330, Boston, MA 02111-1307, USA.
.SH AUTHOR
.PP
Mark Nudelman
.br
Send bug reports or comments to the above address or to bug-less@gnu.org.
less-382/less.man 0100444 0000764 0000764 00000235431 10010076273 013016 0 ustar markn markn
LESS(1) LESS(1)
NNAAMMEE
less - opposite of more
SSYYNNOOPPSSIISS
lleessss --??
lleessss ----hheellpp
lleessss --VV
lleessss ----vveerrssiioonn
lleessss [[--[[++]]aaBBccCCddeeEEffFFggGGiiIIJJLLmmMMnnNNqqQQrrRRssSSuuUUVVwwWWXX~~]]
[[--bb _s_p_a_c_e]] [[--hh _l_i_n_e_s]] [[--jj _l_i_n_e]] [[--kk _k_e_y_f_i_l_e]]
[[--{{ooOO}} _l_o_g_f_i_l_e]] [[--pp _p_a_t_t_e_r_n]] [[--PP _p_r_o_m_p_t]] [[--tt _t_a_g]]
[[--TT _t_a_g_s_f_i_l_e]] [[--xx _t_a_b,,......]] [[--yy _l_i_n_e_s]] [[--[[zz]] _l_i_n_e_s]]
[[--## _s_h_i_f_t]] [[++[[++]]_c_m_d]] [[----]] [[_f_i_l_e_n_a_m_e]]......
(See the OPTIONS section for alternate option syntax with
long option names.)
DDEESSCCRRIIPPTTIIOONN
_L_e_s_s is a program similar to _m_o_r_e (1), but which allows
backward movement in the file as well as forward movement.
Also, _l_e_s_s does not have to read the entire input file
before starting, so with large input files it starts up
faster than text editors like _v_i (1). _L_e_s_s uses termcap
(or terminfo on some systems), so it can run on a variety
of terminals. There is even limited support for hardcopy
terminals. (On a hardcopy terminal, lines which should be
printed at the top of the screen are prefixed with a
caret.)
Commands are based on both _m_o_r_e and _v_i_. Commands may be
preceded by a decimal number, called N in the descriptions
below. The number is used by some commands, as indicated.
CCOOMMMMAANNDDSS
In the following descriptions, ^X means control-X. ESC
stands for the ESCAPE key; for example ESC-v means the two
character sequence "ESCAPE", then "v".
h or H Help: display a summary of these commands. If you
forget all the other commands, remember this one.
SPACE or ^V or f or ^F
Scroll forward N lines, default one window (see
option -z below). If N is more than the screen
size, only the final screenful is displayed. Warn?
ing: some systems use ^V as a special literaliza?
tion character.
z Like SPACE, but if N is specified, it becomes the
new window size.
ESC-SPACE
Like SPACE, but scrolls a full screenful, even if
Version 382: 03 Feb 2004 1
LESS(1) LESS(1)
it reaches end-of-file in the process.
RETURN or ^N or e or ^E or j or ^J
Scroll forward N lines, default 1. The entire N
lines are displayed, even if N is more than the
screen size.
d or ^D
Scroll forward N lines, default one half of the
screen size. If N is specified, it becomes the new
default for subsequent d and u commands.
b or ^B or ESC-v
Scroll backward N lines, default one window (see
option -z below). If N is more than the screen
size, only the final screenful is displayed.
w Like ESC-v, but if N is specified, it becomes the
new window size.
y or ^Y or ^P or k or ^K
Scroll backward N lines, default 1. The entire N
lines are displayed, even if N is more than the
screen size. Warning: some systems use ^Y as a
special job control character.
u or ^U
Scroll backward N lines, default one half of the
screen size. If N is specified, it becomes the new
default for subsequent d and u commands.
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.
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.
r or ^R or ^L
Repaint the screen.
R Repaint the screen, discarding any buffered input.
Useful if the file is changing while it is being
viewed.
F Scroll forward, and keep trying to read when the
end of file is reached. Normally this command
Version 382: 03 Feb 2004 2
LESS(1) LESS(1)
would be used when already at the end of the file.
It is a way to monitor the tail of a file which is
growing while it is being viewed. (The behavior is
similar to the "tail -f" command.)
g or < or ESC-<
Go to line N in the file, default 1 (beginning of
file). (Warning: this may be slow if N is large.)
G or > or ESC->
Go to line N in the file, default the end of the
file. (Warning: this may be slow if N is large, or
if N is not specified and standard input, rather
than a file, is being read.)
p or % Go to a position N percent into the file. N should
be between 0 and 100.
{ If a left curly bracket appears in the top line
displayed on the screen, the { command will go to
the matching right curly bracket. The matching
right curly bracket is positioned on the bottom
line of the screen. If there is more than one left
curly bracket on the top line, a number N may be
used to specify the N-th bracket on the line.
} If a right curly bracket appears in the bottom line
displayed on the screen, the } command will go to
the matching left curly bracket. The matching left
curly bracket is positioned on the top line of the
screen. If there is more than one right curly
bracket on the top line, a number N may be used to
specify the N-th bracket on the line.
( Like {, but applies to parentheses rather than
curly brackets.
) Like }, but applies to parentheses rather than
curly brackets.
[ Like {, but applies to square brackets rather than
curly brackets.
] Like }, but applies to square brackets rather than
curly brackets.
ESC-^F Followed by two characters, acts like {, but uses
the two characters as open and close brackets,
respectively. For example, "ESC ^F < >" could be
used to go forward to the > which matches the < in
the top displayed line.
ESC-^B Followed by two characters, acts like }, but uses
the two characters as open and close brackets,
Version 382: 03 Feb 2004 3
LESS(1) LESS(1)
respectively. For example, "ESC ^B < >" could be
used to go backward to the < which matches the > in
the bottom displayed line.
m Followed by any lowercase letter, marks the current
position with that letter.
' (Single quote.) Followed by any lowercase letter,
returns to the position which was previously marked
with that letter. Followed by another single
quote, returns to the position at which the last
"large" movement command was executed. Followed by
a ^ or $, jumps to the beginning or end of the file
respectively. Marks are preserved when a new file
is examined, so the ' command can be used to switch
between input files.
^X^X Same as single quote.
/pattern
Search forward in the file for the N-th line con?
taining the pattern. N defaults to 1. The pattern
is a regular expression, as recognized by _e_d_. The
search starts at the second line displayed (but see
the -a and -j options, which change this).
Certain characters are special if entered at the
beginning of the pattern; they modify the type of
search rather than become part of the pattern:
^N or !
Search for lines which do NOT match the pat?
tern.
^E or *
Search multiple files. That is, if the
search reaches the END of the current file
without finding a match, the search contin?
ues in the next file in the command line
list.
^F or @
Begin the search at the first line of the
FIRST file in the command line list, regard?
less of what is currently displayed on the
screen or the settings of the -a or -j
options.
^K Highlight any text which matches the pattern
on the current screen, but don't move to the
first match (KEEP current position).
^R Don't interpret regular expression metachar?
acters; that is, do a simple textual
Version 382: 03 Feb 2004 4
LESS(1) LESS(1)
comparison.
?pattern
Search backward in the file for the N-th line con?
taining the pattern. The search starts at the line
immediately before the top line displayed.
Certain characters are special as in the / command:
^N or !
Search for lines which do NOT match the pat?
tern.
^E or *
Search multiple files. That is, if the
search reaches the beginning of the current
file without finding a match, the search
continues in the previous file in the com?
mand line list.
^F or @
Begin the search at the last line of the
last file in the command line list, regard?
less of what is currently displayed on the
screen or the settings of the -a or -j
options.
^K As in forward searches.
^R As in forward searches.
ESC-/pattern
Same as "/*".
ESC-?pattern
Same as "?*".
n Repeat previous search, for N-th line containing
the last pattern. If the previous search was modi?
fied by ^N, the search is made for the N-th line
NOT containing the pattern. If the previous search
was modified by ^E, the search continues in the
next (or previous) file if not satisfied in the
current file. If the previous search was modified
by ^R, the search is done without using regular
expressions. There is no effect if the previous
search was modified by ^F or ^K.
N Repeat previous search, but in the reverse direc?
tion.
ESC-n Repeat previous search, but crossing file bound?
aries. The effect is as if the previous search
were modified by *.
Version 382: 03 Feb 2004 5
LESS(1) LESS(1)
ESC-N Repeat previous search, but in the reverse direc?
tion and crossing file boundaries.
ESC-u Undo search highlighting. Turn off highlighting of
strings matching the current search pattern. If
highlighting is already off because of a previous
ESC-u command, turn highlighting back on. Any
search command will also turn highlighting back on.
(Highlighting can also be disabled by toggling the
-G option; in that case search commands do not turn
highlighting back on.)
:e [filename]
Examine a new file. If the filename is missing,
the "current" file (see the :n and :p commands
below) from the list of files in the command line
is re-examined. A percent sign (%) in the filename
is replaced by the name of the current file. A
pound sign (#) is replaced by the name of the pre?
viously examined file. However, two consecutive
percent signs are simply replaced with a single
percent sign. This allows you to enter a filename
that contains a percent sign in the name. Simi?
larly, two consecutive pound signs are replaced
with a single pound sign. The filename is inserted
into the command line list of files so that it can
be seen by subsequent :n and :p commands. If the
filename consists of several files, they are all
inserted into the list of files and the first one
is examined. If the filename contains one or more
spaces, the entire filename should be enclosed in
double quotes (also see the -" option).
^X^V or E
Same as :e. Warning: some systems use ^V as a spe?
cial literalization character. On such systems,
you may not be able to use ^V.
:n Examine the next file (from the list of files given
in the command line). If a number N is specified,
the N-th next file is examined.
:p Examine the previous file in the command line list.
If a number N is specified, the N-th previous file
is examined.
:x Examine the first file in the command line list.
If a number N is specified, the N-th file in the
list is examined.
:d Remove the current file from the list of files.
t Go to the next tag, if there were more than one
matches for the current tag. See the -t option for
Version 382: 03 Feb 2004 6
LESS(1) LESS(1)
more details about tags.
T Go to the previous tag, if there were more than one
matches for the current tag.
= or ^G or :f
Prints some information about the file being
viewed, including its name and the line number and
byte offset of the bottom line being displayed. If
possible, it also prints the length of the file,
the number of lines in the file and the percent of
the file above the last displayed line.
- Followed by one of the command line option letters
(see OPTIONS below), this will change the setting
of that option and print a message describing the
new setting. If a ^P (CONTROL-P) is entered imme?
diately after the dash, the setting of the option
is changed but no message is printed. If the
option letter has a numeric value (such as -b or
-h), or a string value (such as -P or -t), a new
value may be entered after the option letter. If
no new value is entered, a message describing the
current setting is printed and nothing is changed.
-- Like the - command, but takes a long option name
(see OPTIONS below) rather than a single option
letter. You must press RETURN after typing the
option name. A ^P immediately after the second
dash suppresses printing of a message describing
the new setting, as in the - command.
-+ Followed by one of the command line option letters
this will reset the option to its default setting
and print a message describing the new setting.
(The "-+_X" command does the same thing as "-+_X" on
the command line.) This does not work for string-
valued options.
--+ Like the -+ command, but takes a long option name
rather than a single option letter.
-! Followed by one of the command line option letters,
this will reset the option to the "opposite" of its
default setting and print a message describing the
new setting. This does not work for numeric or
string-valued options.
--! Like the -! command, but takes a long option name
rather than a single option letter.
_ (Underscore.) Followed by one of the command line
option letters, this will print a message describ?
ing the current setting of that option. The
Version 382: 03 Feb 2004 7
LESS(1) LESS(1)
setting of the option is not changed.
__ (Double underscore.) Like the _ (underscore) com?
mand, but takes a long option name rather than a
single option letter. You must press RETURN after
typing the option name.
+cmd Causes the specified cmd to be executed each time a
new file is examined. For example, +G causes _l_e_s_s
to initially display each file starting at the end
rather than the beginning.
V Prints the version number of _l_e_s_s being run.
q or Q or :q or :Q or ZZ
Exits _l_e_s_s_.
The following four commands may or may not be valid,
depending on your particular installation.
v Invokes an editor to edit the current file being
viewed. The editor is taken from the environment
variable VISUAL if defined, or EDITOR if VISUAL is
not defined, or defaults to "vi" if neither VISUAL
nor EDITOR is defined. See also the discussion of
LESSEDIT under the section on PROMPTS below.
! shell-command
Invokes a shell to run the shell-command given. A
percent sign (%) in the command is replaced by the
name of the current file. A pound sign (#) is
replaced by the name of the previously examined
file. "!!" repeats the last shell command. "!"
with no shell command simply invokes a shell. On
Unix systems, the shell is taken from the environ?
ment variable SHELL, or defaults to "sh". On MS-
DOS and OS/2 systems, the shell is the normal com?
mand processor.
| shell-command
represents any mark letter. Pipes a section of
the input file to the given shell command. The
section of the file to be piped is between the
first line on the current screen and the position
marked by the letter. may also be ^ or $ to
indicate beginning or end of file respectively. If
is . or newline, the current screen is piped.
s filename
Save the input to a file. This only works if the
input is a pipe, not an ordinary file.
Version 382: 03 Feb 2004 8
LESS(1) LESS(1)
OOPPTTIIOONNSS
Command line options are described below. Most options
may be changed while _l_e_s_s is running, via the "-" command.
Most options may be given in one of two forms: either a
dash followed by a single letter, or two dashes followed
by a long option name. A long option name may be abbrevi?
ated as long as the abbreviation is unambiguous. For
example, --quit-at-eof may be abbreviated --quit, but not
--qui, since both --quit-at-eof and --quiet begin with
--qui. Some long option names are in uppercase, such as
--QUIT-AT-EOF, as distinct from --quit-at-eof. Such
option names need only have their first letter capital?
ized; the remainder of the name may be in either case.
For example, --Quit-at-eof is equivalent to --QUIT-AT-EOF.
Options are also taken from the environment variable
"LESS". For example, to avoid typing "less -options ..."
each time _l_e_s_s is invoked, you might tell _c_s_h_:
setenv LESS "-options"
or if you use _s_h_:
LESS="-options"; export LESS
On MS-DOS, you don't need the quotes, but you should
replace any percent signs in the options string by double
percent signs.
The environment variable is parsed before the command
line, so command line options override the LESS environ?
ment variable. If an option appears in the LESS variable,
it can be reset to its default value on the command line
by beginning the command line option with "-+".
For options like -P or -D which take a following string, a
dollar sign ($) must be used to signal the end of the
string. For example, to set two -D options on MS-DOS, you
must have a dollar sign between them, like this:
LESS="-Dn9.1$-Ds4.1"
-? or --help
This option displays a summary of the commands
accepted by _l_e_s_s (the same as the h command).
(Depending on how your shell interprets the ques?
tion mark, it may be necessary to quote the ques?
tion mark, thus: "-\?".)
-a or --search-skip-screen
Causes searches to start after the last line dis?
played on the screen, thus skipping all lines
Version 382: 03 Feb 2004 9
LESS(1) LESS(1)
displayed on the screen. By default, searches
start at the second line on the screen (or after
the last found line; see the -j option).
-b_n or --buffers=_n
Specifies the amount of buffer space _l_e_s_s will use
for each file, in units of kilobytes (1024 bytes).
By default 64K of buffer space is used for each
file (unless the file is a pipe; see the -B
option). The -b option specifies instead that _n
kilobytes of buffer space should be used for each
file. If _n is -1, buffer space is unlimited; that
is, the entire file is read into memory.
-B or --auto-buffers
By default, when data is read from a pipe, buffers
are allocated automatically as needed. If a large
amount of data is read from the pipe, this can
cause a large amount of memory to be allocated.
The -B option disables this automatic allocation of
buffers for pipes, so that only 64K (or the amount
of space specified by the -b option) is used for
the pipe. Warning: use of -B can result in erro?
neous display, since only the most recently viewed
part of the file is kept in memory; any earlier
data is lost.
-c or --clear-screen
Causes full screen repaints to be painted from the
top line down. By default, full screen repaints
are done by scrolling from the bottom of the
screen.
-C or --CLEAR-SCREEN
The -C option is like -c, but the screen is cleared
before it is repainted.
-d or --dumb
The -d option suppresses the error message normally
displayed if the terminal is dumb; that is, lacks
some important capability, such as the ability to
clear the screen or scroll backward. The -d option
does not otherwise change the behavior of _l_e_s_s on a
dumb terminal.
-Dxx_c_o_l_o_r or --color=xx_c_o_l_o_r
[MS-DOS only] Sets the color of the text displayed.
xx is a single character which selects the type of
text whose color is being set: n=normal, s=stand?
out, d=bold, u=underlined, k=blink. _c_o_l_o_r is a
pair of numbers separated by a period. The first
number selects the foreground color and the second
selects the background color of the text. A single
number _N is the same as _N_._0.
Version 382: 03 Feb 2004 10
LESS(1) LESS(1)
-e or --quit-at-eof
Causes _l_e_s_s to automatically exit the second time
it reaches end-of-file. By default, the only way
to exit _l_e_s_s is via the "q" command.
-E or --QUIT-AT-EOF
Causes _l_e_s_s to automatically exit the first time it
reaches end-of-file.
-f or --force
Forces non-regular files to be opened. (A non-reg?
ular file is a directory or a device special file.)
Also suppresses the warning message when a binary
file is opened. By default, _l_e_s_s will refuse to
open non-regular files.
-F or --quit-if-one-screen
Causes _l_e_s_s to automatically exit if the entire
file can be displayed on the first screen.
-g or --hilite-search
Normally, _l_e_s_s will highlight ALL strings which
match the last search command. The -g option
changes this behavior to highlight only the partic?
ular string which was found by the last search com?
mand. This can cause _l_e_s_s to run somewhat faster
than the default.
-G or --HILITE-SEARCH
The -G option suppresses all highlighting of
strings found by search commands.
-h_n or ---max-back-scroll=_n
Specifies a maximum number of lines to scroll back?
ward. If it is necessary to scroll backward more
than _n lines, the screen is repainted in a forward
direction instead. (If the terminal does not have
the ability to scroll backward, -h0 is implied.)
-i or --ignore-case
Causes searches to ignore case; that is, uppercase
and lowercase are considered identical. This
option is ignored if any uppercase letters appear
in the search pattern; in other words, if a pattern
contains uppercase letters, then that search does
not ignore case.
-I or --IGNORE-CASE
Like -i, but searches ignore case even if the pat?
tern contains uppercase letters.
-j_n or --jump-target=_n
Specifies a line on the screen where the "target"
line is to be positioned. A target line is the
Version 382: 03 Feb 2004 11
LESS(1) LESS(1)
object of a text search, tag search, jump to a line
number, jump to a file percentage, or jump to a
marked position. The screen line is specified by a
number: the top line on the screen is 1, the next
is 2, and so on. The number may be negative to
specify a line relative to the bottom of the
screen: the bottom line on the screen is -1, the
second to the bottom is -2, and so on. If the -j
option is used, searches begin at the line immedi?
ately after the target line. For example, if "-j4"
is used, the target line is the fourth line on the
screen, so searches begin at the fifth line on the
screen.
-J or --status-column
Displays a status column at the left edge of the
screen. 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.
-k_f_i_l_e_n_a_m_e or --lesskey-file=_f_i_l_e_n_a_m_e
Causes _l_e_s_s to open and interpret the named file as
a _l_e_s_s_k_e_y (1) file. Multiple -k options may be
specified. If the LESSKEY or LESSKEY_SYSTEM envi?
ronment variable is set, or if a lesskey file is
found in a standard place (see KEY BINDINGS), it is
also used as a _l_e_s_s_k_e_y file.
-L or --no-lessopen
Ignore the LESSOPEN environment variable (see the
INPUT PREPROCESSOR section below). This option can
be set from within _l_e_s_s, but it will apply only to
files opened subsequently, not to the file which is
currently open.
-m or --long-prompt
Causes _l_e_s_s to prompt verbosely (like _m_o_r_e), with
the percent into the file. By default, _l_e_s_s
prompts with a colon.
-M or --LONG-PROMPT
Causes _l_e_s_s to prompt even more verbosely than
_m_o_r_e_.
-n or --line-numbers
Suppresses line numbers. The default (to use line
numbers) may cause _l_e_s_s to run more slowly in some
cases, especially with a very large input file.
Suppressing line numbers with the -n option will
avoid this problem. Using line numbers means: the
line number will be displayed in the verbose prompt
and in the = command, and the v command will pass
the current line number to the editor (see also the
discussion of LESSEDIT in PROMPTS below).
Version 382: 03 Feb 2004 12
LESS(1) LESS(1)
-N or --LINE-NUMBERS
Causes a line number to be displayed at the begin?
ning of each line in the display.
-o_f_i_l_e_n_a_m_e or --log-file=_f_i_l_e_n_a_m_e
Causes _l_e_s_s to copy its input to the named file as
it is being viewed. This applies only when the
input file is a pipe, not an ordinary file. If the
file already exists, _l_e_s_s will ask for confirmation
before overwriting it.
-O_f_i_l_e_n_a_m_e or --LOG-FILE=_f_i_l_e_n_a_m_e
The -O option is like -o, but it will overwrite an
existing file without asking for confirmation.
If no log file has been specified, the -o and -O
options can be used from within _l_e_s_s to specify a
log file. Without a file name, they will simply
report the name of the log file. The "s" command
is equivalent to specifying -o from within _l_e_s_s_.
-p_p_a_t_t_e_r_n or --pattern=_p_a_t_t_e_r_n
The -p option on the command line is equivalent to
specifying +/_p_a_t_t_e_r_n; that is, it tells _l_e_s_s to
start at the first occurrence of _p_a_t_t_e_r_n in the
file.
-P_p_r_o_m_p_t or --prompt=_p_r_o_m_p_t
Provides a way to tailor the three prompt styles to
your own preference. This option would normally be
put in the LESS environment variable, rather than
being typed in with each _l_e_s_s command. Such an
option must either be the last option in the LESS
variable, or be terminated by a dollar sign. -Ps
followed by a string changes the default (short)
prompt to that string. -Pm changes the medium (-m)
prompt. -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.
-q or --quiet or --silent
Causes moderately "quiet" operation: the terminal
bell is not rung if an attempt is made to scroll
past the end of the file or before the beginning of
the file. If the terminal has a "visual bell", it
is used instead. The bell will be rung on certain
other errors, such as typing an invalid character.
The default is to ring the terminal bell in all
such cases.
Version 382: 03 Feb 2004 13
LESS(1) LESS(1)
-Q or --QUIET or --SILENT
Causes totally "quiet" operation: the terminal bell
is never rung.
-r or --raw-control-chars
Causes "raw" control characters to be displayed.
The default is to display control characters using
the caret notation; for example, a control-A (octal
001) is displayed as "^A". Warning: when the -r
option is used, _l_e_s_s cannot keep track of the
actual appearance of the screen (since this depends
on how the screen responds to each type of control
character). Thus, various display problems may
result, such as long lines being split in the wrong
place.
-R or --RAW-CONTROL-CHARS
Like -r, but tries to keep track of the screen
appearance where possible. This works only if the
input consists of normal text and possibly some
ANSI "color" escape sequences, which are sequences
of the form:
ESC [ ... m
where the "..." is zero or more characters other
than "m". For the purpose of keeping track of
screen appearance, all control characters and all
ANSI color escape sequences are assumed to not move
the cursor. You can make _l_e_s_s think that charac?
ters other than "m" can end ANSI color escape
sequences by setting the environment variable
LESSANSIENDCHARS to the list of characters which
can end a color escape sequence.
-s or --squeeze-blank-lines
Causes consecutive blank lines to be squeezed into
a single blank line. This is useful when viewing
_n_r_o_f_f output.
-S or --chop-long-lines
Causes lines longer than the screen width to be
chopped rather than folded. That is, the portion
of a long line that does not fit in the screen
width is not shown. The default is to fold long
lines; that is, display the remainder on the next
line.
-t_t_a_g or --tag=_t_a_g
The -t option, followed immediately by a TAG, will
edit the file containing that tag. For this to
work, tag information must be available; for exam?
ple, there may be a file in the current directory
called "tags", which was previously built by _c_t_a_g_s
Version 382: 03 Feb 2004 14
LESS(1) LESS(1)
(1) or an equivalent command. If the environment
variable LESSGLOBALTAGS is set, it is taken to be
the name of a command compatible with _g_l_o_b_a_l (1),
and that command is executed to find the tag. (See
https://www.gnu.org/software/global/global.html).
The -t option may also be specified from within
_l_e_s_s (using the - command) as a way of examining a
new file. The command ":t" is equivalent to speci?
fying -t from within _l_e_s_s_.
-T_t_a_g_s_f_i_l_e or --tag-file=_t_a_g_s_f_i_l_e
Specifies a tags file to be used instead of "tags".
-u or --underline-special
Causes backspaces and carriage returns to be
treated as printable characters; that is, they are
sent to the terminal when they appear in the input.
-U or --UNDERLINE-SPECIAL
Causes backspaces, tabs and carriage returns to be
treated as control characters; that is, they are
handled as specified by the -r option.
By default, if neither -u nor -U is given,
backspaces which appear adjacent to an underscore
character are treated specially: the underlined
text is displayed using the terminal's hardware
underlining capability. Also, backspaces which
appear between two identical characters are treated
specially: the overstruck text is printed using the
terminal's hardware boldface capability. Other
backspaces are deleted, along with the preceding
character. Carriage returns immediately followed
by a newline are deleted. other carriage returns
are handled as specified by the -r option. Text
which is overstruck or underlined can be searched
for if neither -u nor -U is in effect.
-V or --version
Displays the version number of _l_e_s_s_.
-w or --hilite-unread
Temporarily highlights the first "new" line after a
forward movement of a full page. The first "new"
line is the line immediately following the line
previously at the bottom of the screen. Also high?
lights the target line after a g or p command. The
highlight is removed at the next command which
causes movement. The entire line is highlighted,
unless the -J option is in effect, in which case
only the status column is highlighted.
-W or --HILITE-UNREAD
Like -w, but temporarily highlights the first new
Version 382: 03 Feb 2004 15
LESS(1) LESS(1)
line after any forward movement command larger than
one line.
-x_n,... or --tabs=_n,...
Sets tab stops. If only one _n is specified, tab
stops are set at multiples of _n. If multiple val?
ues 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,
_-_x_9_,_1_7 will set tabs at positions 9, 17, 25, 33,
etc. The default for _n is 8.
-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.
--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.
-y_n or --max-forw-scroll=_n
Specifies a maximum number of lines to scroll for?
ward. If it is necessary to scroll forward more
than _n lines, the screen is repainted instead. The
-c or -C option may be used to repaint from the top
of the screen if desired. By default, any forward
movement causes scrolling.
-[z]_n or --window=_n
Changes the default scrolling window size to _n
lines. The default is one screenful. The z and w
commands can also be used to change the window
size. The "z" may be omitted for compatibility
with _m_o_r_e_. If the number _n is negative, it indi?
cates _n lines less than the current screen size.
For example, if the screen is 24 lines, _-_z_-_4 sets
the scrolling window to 20 lines. If the screen is
resized to 40 lines, the scrolling window automati?
cally changes to 36 lines.
-_"_c_c or --quotes=_c_c
Changes the filename quoting character. This may
be necessary if you are trying to name a file which
contains both spaces and quote characters. Fol?
lowed by a single character, this changes the quote
character to that character. Filenames containing
a space should then be surrounded by that character
rather than by double quotes. Followed by two
characters, changes the open quote to the first
Version 382: 03 Feb 2004 16
LESS(1) LESS(1)
character, and the close quote to the second char?
acter. Filenames containing a space should then be
preceded by the open quote character and followed
by the close quote character. Note that even after
the quote characters are changed, this option
remains -" (a dash followed by a double quote).
-~ or --tilde
Normally lines after end of file are displayed as a
single tilde (~). This option causes lines after
end of file to be displayed as blank lines.
-# or --shift
Specifies the default number of positions to scroll
horizontally in the RIGHTARROW and LEFTARROW com?
mands. If the number specified is zero, it sets
the default number of positions to one half of the
screen width.
-- A command line argument of "--" marks the end of
option arguments. Any arguments following this are
interpreted as filenames. This can be useful when
viewing a file whose name begins with a "-" or "+".
+ If a command line option begins with ++, the remain?
der of that option is taken to be an initial com?
mand to _l_e_s_s_. For example, +G tells _l_e_s_s to start
at the end of the file rather than the beginning,
and +/xyz tells it to start at the first occurrence
of "xyz" in the file. As a special case, +
acts like +g; that is, it starts the dis?
play at the specified line number (however, see the
caveat under the "g" command above). If the option
starts with ++, the initial command applies to
every file being viewed, not just the first one.
The + command described previously may also be used
to set (or change) an initial command for every
file.
LLIINNEE EEDDIITTIINNGG
When entering command line at the bottom of the screen
(for example, a filename for the :e command, or the pat?
tern for a search command), certain keys can be used to
manipulate the command line. Most commands have an alter?
nate form in [ brackets ] which can be used if a key does
not exist on a particular keyboard. (The bracketed forms
do not work in the MS-DOS version.) Any of these special
keys may be entered literally by preceding it with the
"literal" character, either ^V or ^A. A backslash itself
may also be entered literally by entering two backslashes.
LEFTARROW [ ESC-h ]
Move the cursor one space to the left.
Version 382: 03 Feb 2004 17
LESS(1) LESS(1)
RIGHTARROW [ ESC-l ]
Move the cursor one space to the right.
^LEFTARROW [ ESC-b or ESC-LEFTARROW ]
(That is, CONTROL and LEFTARROW simultaneously.)
Move the cursor one word to the left.
^RIGHTARROW [ ESC-w or ESC-RIGHTARROW ]
(That is, CONTROL and RIGHTARROW simultaneously.)
Move the cursor one word to the right.
HOME [ ESC-0 ]
Move the cursor to the beginning of the line.
END [ ESC-$ ]
Move the cursor to the end of the line.
BACKSPACE
Delete the character to the left of the cursor, or
cancel the command if the command line is empty.
DELETE or [ ESC-x ]
Delete the character under the cursor.
^BACKSPACE [ ESC-BACKSPACE ]
(That is, CONTROL and BACKSPACE simultaneously.)
Delete the word to the left of the cursor.
^DELETE [ ESC-X or ESC-DELETE ]
(That is, CONTROL and DELETE simultaneously.)
Delete the word under the cursor.
UPARROW [ ESC-k ]
Retrieve the previous command line.
DOWNARROW [ ESC-j ]
Retrieve the next command line.
TAB Complete the partial filename to the left of the
cursor. If it matches more than one filename, the
first match is entered into the command line.
Repeated TABs will cycle thru the other matching
filenames. If the completed filename is a direc?
tory, a "/" is appended to the filename. (On MS-
DOS systems, a "\" is appended.) The environment
variable LESSSEPARATOR can be used to specify a
different character to append to a directory name.
BACKTAB [ ESC-TAB ]
Like, TAB, but cycles in the reverse direction thru
the matching filenames.
^L Complete the partial filename to the left of the
cursor. If it matches more than one filename, all
Version 382: 03 Feb 2004 18
LESS(1) LESS(1)
matches are entered into the command line (if they
fit).
^U (Unix and OS/2) or ESC (MS-DOS)
Delete the entire command line, or cancel the com?
mand if the command line is empty. If you have
changed your line-kill character in Unix to some?
thing other than ^U, that character is used instead
of ^U.
KKEEYY BBIINNDDIINNGGSS
You may define your own _l_e_s_s commands by using the program
_l_e_s_s_k_e_y (1) to create a lesskey file. This file specifies
a set of command keys and an action associated with each
key. You may also use _l_e_s_s_k_e_y to change the line-editing
keys (see LINE EDITING), and to set environment variables.
If the environment variable LESSKEY is set, _l_e_s_s uses that
as the name of the lesskey file. Otherwise, _l_e_s_s looks in
a standard place for the lesskey file: On Unix systems,
_l_e_s_s looks for a lesskey file called "$HOME/.less". On
MS-DOS and Windows systems, _l_e_s_s looks for a lesskey file
called "$HOME/_less", and if it is not found there, then
looks for a lesskey file called "_less" in any directory
specified in the PATH environment variable. On OS/2 sys?
tems, _l_e_s_s looks for a lesskey file called
"$HOME/less.ini", and if it is not found, then looks for a
lesskey file called "less.ini" in any directory specified
in the INIT environment variable, and if it not found
there, then looks for a lesskey file called "less.ini" in
any directory specified in the PATH environment variable.
See the _l_e_s_s_k_e_y manual page for more details.
A system-wide lesskey file may also be set up to provide
key bindings. If a key is defined in both a local lesskey
file and in the system-wide file, key bindings in the
local file take precedence over those in the system-wide
file. If the environment variable LESSKEY_SYSTEM is set,
_l_e_s_s uses that as the name of the system-wide lesskey
file. Otherwise, _l_e_s_s looks in a standard place for the
system-wide lesskey file: On Unix systems, the system-wide
lesskey file is /usr/local/etc/sysless. (However, if _l_e_s_s
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.
IINNPPUUTT PPRREEPPRROOCCEESSSSOORR
You may define an "input preprocessor" for _l_e_s_s_. Before
_l_e_s_s opens a file, it first gives your input preprocessor
a chance to modify the way the contents of the file are
displayed. An input preprocessor is simply an executable
Version 382: 03 Feb 2004 19
LESS(1) LESS(1)
program (or shell script), which writes the contents of
the file to a different file, called the replacement file.
The contents of the replacement file are then displayed in
place of the contents of the original file. However, it
will appear to the user as if the original file is opened;
that is, _l_e_s_s will display the original filename as the
name of the current file.
An input preprocessor receives one command line argument,
the original filename, as entered by the user. It should
create the replacement file, and when finished, print the
name of the replacement file to its standard output. If
the input preprocessor does not output a replacement file?
name, _l_e_s_s uses the original file, as normal. The input
preprocessor is not called when viewing standard input.
To set up an input preprocessor, set the LESSOPEN environ?
ment variable to a command line which will invoke your
input preprocessor. This command line should include one
occurrence of the string "%s", which will be replaced by
the filename when the input preprocessor command is
invoked.
When _l_e_s_s closes a file opened in such a way, it will call
another program, called the input postprocessor, which may
perform any desired clean-up action (such as deleting the
replacement file created by LESSOPEN). This program
receives two command line arguments, the original filename
as entered by the user, and the name of the replacement
file. To set up an input postprocessor, set the LESSCLOSE
environment variable to a command line which will invoke
your input postprocessor. It may include two occurrences
of the string "%s"; the first is replaced with the origi?
nal name of the file and the second with the name of the
replacement file, which was output by LESSOPEN.
For example, on many Unix systems, these two scripts will
allow you to keep files in compressed format, but still
let _l_e_s_s view them directly:
lessopen.sh:
#! /bin/sh
case "$1" in
*.Z) uncompress -c $1 >/tmp/less.$$ 2>/dev/null
if [ -s /tmp/less.$$ ]; then
echo /tmp/less.$$
else
rm -f /tmp/less.$$
fi
;;
esac
lessclose.sh:
#! /bin/sh
rm $2
Version 382: 03 Feb 2004 20
LESS(1) LESS(1)
To use these scripts, put them both where they can be exe?
cuted and set LESSOPEN="lessopen.sh %s", and
LESSCLOSE="lessclose.sh %s %s". More complex LESSOPEN and
LESSCLOSE scripts may be written to accept other types of
compressed files, and so on.
It is also possible to set up an input preprocessor to
pipe the file data directly to _l_e_s_s_, rather than putting
the data into a replacement file. This avoids the need to
decompress the entire file before starting to view it. An
input preprocessor that works this way is called an input
pipe. An input pipe, instead of writing the name of a
replacement file on its standard output, writes the entire
contents of the replacement file on its standard output.
If the input pipe does not write any characters on its
standard output, then there is no replacement file and
_l_e_s_s uses the original file, as normal. To use an input
pipe, make the first character in the LESSOPEN environment
variable a vertical bar (|) to signify that the input pre?
processor is an input pipe.
For example, on many Unix systems, this script will work
like the previous example scripts:
lesspipe.sh:
#! /bin/sh
case "$1" in
*.Z) uncompress -c $1 2>/dev/null
;;
esac
To use this script, put it where it can be executed and
set LESSOPEN="|lesspipe.sh %s". When an input pipe is
used, a LESSCLOSE postprocessor can be used, but it is
usually not necessary since there is no replacement file
to clean up. In this case, the replacement file name
passed to the LESSCLOSE postprocessor is "-".
NNAATTIIOONNAALL CCHHAARRAACCTTEERR SSEETTSS
There are three types of characters in the input file:
normal characters
can be displayed directly to the screen.
control characters
should not be displayed directly, but are expected
to be found in ordinary text files (such as
backspace and tab).
binary characters
should not be displayed directly and are not
expected to be found in text files.
Version 382: 03 Feb 2004 21
LESS(1) LESS(1)
A "character set" is simply a description of which charac?
ters are to be considered normal, control, and binary.
The LESSCHARSET environment variable may be used to select
a character set. Possible values for LESSCHARSET are:
ascii BS, TAB, NL, CR, and formfeed are control charac?
ters, all chars with values between 32 and 126 are
normal, and all others are binary.
iso8859
Selects an ISO 8859 character set. This is the
same as ASCII, except characters between 160 and
255 are treated as normal characters.
latin1 Same as iso8859.
latin9 Same as iso8859.
dos Selects a character set appropriate for MS-DOS.
ebcdic Selects an EBCDIC character set.
IBM-1047
Selects an EBCDIC character set used by OS/390 Unix
Services. This is the EBCDIC analogue of latin1.
You get similar results by setting either LESS?
CHARSET=IBM-1047 or LC_CTYPE=en_US in your environ?
ment.
koi8-r Selects a Russian character set.
next Selects a character set appropriate for NeXT com?
puters.
utf-8 Selects the UTF-8 encoding of the ISO 10646 charac?
ter set.
In special cases, it may be desired to tailor _l_e_s_s to use
a character set other than the ones definable by LESS?
CHARSET. In this case, the environment variable LESS?
CHARDEF can be used to define a character set. It should
be set to a string where each character in the string rep?
resents one character in the character set. The character
"." is used for a normal character, "c" for control, and
"b" for binary. A decimal number may be used for repeti?
tion. For example, "bccc4b." would mean character 0 is
binary, 1, 2 and 3 are control, 4, 5, 6 and 7 are binary,
and 8 is normal. All characters after the last are taken
to be the same as the last, so characters 9 through 255
would be normal. (This is an example, and does not neces?
sarily represent any real character set.)
This table shows the value of LESSCHARDEF which is equiva?
lent to each of the possible values for LESSCHARSET:
Version 382: 03 Feb 2004 22
LESS(1) LESS(1)
ascii 8bcccbcc18b95.b
dos 8bcccbcc12bc5b95.b.
ebcdic 5bc6bcc7bcc41b.9b7.9b5.b..8b6.10b6.b9.7b
9.8b8.17b3.3b9.7b9.8b8.6b10.b.b.b.
IBM-1047 4cbcbc3b9cbccbccbb4c6bcc5b3cbbc4bc4bccbc
191.b
iso8859 8bcccbcc18b95.33b.
koi8-r 8bcccbcc18b95.b128.
latin1 8bcccbcc18b95.33b.
next 8bcccbcc18b95.bb125.bb
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.
If that string is not found, but your system supports the
_s_e_t_l_o_c_a_l_e interface, _l_e_s_s will use setlocale to determine
the character set. setlocale is controlled by setting the
LANG or LC_CTYPE environment variables.
Finally, if the _s_e_t_l_o_c_a_l_e interface is also not available,
the default character set is latin1.
Control and binary characters are displayed in standout
(reverse video). Each such character is displayed in
caret notation if possible (e.g. ^A for control-A). Caret
notation is used only if inverting the 0100 bit results in
a normal printable character. Otherwise, the character is
displayed as a hex number in angle brackets. This format
can be changed by setting the LESSBINFMT environment vari?
able. LESSBINFMT may begin with a "*" and one character
to select the display attribute: "*k" is blinking, "*d" is
bold, "*u" is underlined, "*s" is standout, and "*n" is
normal. If LESSBINFMT does not begin with a "*", normal
attribute is assumed. The remainder of LESSBINFMT is a
string which may include one printf-style escape sequence
(a % followed by x, X, o, d, etc.). For example, if LESS?
BINFMT is "*u[%x]", binary characters are displayed in
underlined hexadecimal surrounded by brackets. The
default if no LESSBINFMT is specified is "*s<%X>".
PPRROOMMPPTTSS
The -P option allows you to tailor the prompt to your
preference. The string given to the -P option replaces
the specified prompt string. Certain characters in the
string are interpreted specially. The prompt mechanism is
rather complicated to provide flexibility, but the ordi?
nary user need not understand the details of constructing
personalized prompt strings.
A percent sign followed by a single character is expanded
according to what the following character is:
Version 382: 03 Feb 2004 23
LESS(1) LESS(1)
%b_X Replaced by the byte offset into the current input
file. The b is followed by a single character
(shown as _X above) which specifies the line whose
byte offset is to be used. If the character is a
"t", the byte offset of the top line in the display
is used, an "m" means use the middle line, a "b"
means use the bottom line, a "B" means use the line
just after the bottom line, and a "j" means use the
"target" line, as specified by the -j option.
%B Replaced by the size of the current input file.
%c Replaced by the column number of the text appearing
in the first column of the screen.
%d_X Replaced by the page number of a line in the input
file. The line to be used is determined by the _X,
as with the %b option.
%D Replaced by the number of pages in the input file,
or equivalently, the page number of the last line
in the input file.
%E Replaced by the name of the editor (from the VISUAL
environment variable, or the EDITOR environment
variable if VISUAL is not defined). See the dis?
cussion of the LESSEDIT feature below.
%f Replaced by the name of the current input file.
%i Replaced by the index of the current file in the
list of input files.
%l_X Replaced by the line number of a line in the input
file. The line to be used is determined by the _X,
as with the %b option.
%L Replaced by the line number of the last line in the
input file.
%m Replaced by the total number of input files.
%p_X Replaced by the percent into the current input
file, based on byte offsets. The line used is
determined by the _X as with the %b option.
%P_X Replaced by the percent into the current input
file, based on line numbers. The line used is
determined by the _X as with the %b option.
%s Same as %B.
%t Causes any trailing spaces to be removed. Usually
used at the end of the string, but may appear
Version 382: 03 Feb 2004 24
LESS(1) LESS(1)
anywhere.
%x Replaced by the name of the next input file in the
list.
If any item is unknown (for example, the file size if
input is a pipe), a question mark is printed instead.
The format of the prompt string can be changed depending
on certain conditions. A question mark followed by a sin?
gle character acts like an "IF": depending on the follow?
ing character, a condition is evaluated. If the condition
is true, any characters following the question mark and
condition character, up to a period, are included in the
prompt. If the condition is false, such characters are
not included. A colon appearing between the question mark
and the period can be used to establish an "ELSE": any
characters between the colon and the period are included
in the string if and only if the IF condition is false.
Condition characters (which follow a question mark) may
be:
?a True if any characters have been included in the
prompt so far.
?b_X True if the byte offset of the specified line is
known.
?B True if the size of current input file is known.
?c True if the text is horizontally shifted (%c is not
zero).
?d_X True if the page number of the specified line is
known.
?e True if at end-of-file.
?f True if there is an input filename (that is, if
input is not a pipe).
?l_X True if the line number of the specified line is
known.
?L True if the line number of the last line in the
file is known.
?m True if there is more than one input file.
?n True if this is the first prompt in a new input
file.
?p_X True if the percent into the current input file,
based on byte offsets, of the specified line is
Version 382: 03 Feb 2004 25
LESS(1) LESS(1)
known.
?P_X True if the percent into the current input file,
based on line numbers, of the specified line is
known.
?s Same as "?B".
?x True if there is a next input file (that is, if the
current input file is not the last one).
Any characters other than the special ones (question mark,
colon, period, percent, and backslash) become literally
part of the prompt. Any of the special characters may be
included in the prompt literally by preceding it with a
backslash.
Some examples:
?f%f:Standard input.
This prompt prints the filename, if known; otherwise the
string "Standard input".
?f%f .?ltLine %lt:?pt%pt\%:?btByte %bt:-...
This prompt would print the filename, if known. The file?
name is followed by the line number, if known, otherwise
the percent if known, otherwise the byte offset if known.
Otherwise, a dash is printed. Notice how each question
mark has a matching period, and how the % after the %pt is
included literally by escaping it with a backslash.
?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\: %x..%t
This prints the filename if this is the first prompt in a
file, followed by the "file N of N" message if there is
more than one input file. Then, if we are at end-of-file,
the string "(END)" is printed followed by the name of the
next file, if there is one. Finally, any trailing spaces
are truncated. This is the default prompt. For refer?
ence, here are the defaults for the other two prompts (-m
and -M respectively). Each is broken into two lines here
for readability only.
?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\: %x.:
?pB%pB\%:byte %bB?s/%s...%t
?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
And here is the default message produced by the = command:
?f%f .?m(file %i of %m) .?ltlines %lt-%lb?L/%L. .
Version 382: 03 Feb 2004 26
LESS(1) LESS(1)
byte %bB?s/%s. ?e(END) :?pB%pB\%..%t
The prompt expansion features are also used for another
purpose: if an environment variable LESSEDIT is defined,
it is used as the command to be executed when the v com?
mand is invoked. The LESSEDIT string is expanded in the
same way as the prompt strings. The default value for
LESSEDIT is:
%E ?lm+%lm. %f
Note that this expands to the editor name, followed by a +
and the line number, followed by the file name. If your
editor does not accept the "+linenumber" syntax, or has
other differences in invocation syntax, the LESSEDIT vari?
able can be changed to modify this default.
SSEECCUURRIITTYY
When the environment variable LESSSECURE is set to 1, _l_e_s_s
runs in a "secure" mode. This means these features are
disabled:
! the shell command
| the pipe command
:e the examine command.
v the editing command
s -o log files
-k use of lesskey files
-t use of tags files
metacharacters in filenames, such as *
filename completion (TAB, ^L)
Less can also be compiled to be permanently in "secure"
mode.
EENNVVIIRROONNMMEENNTT VVAARRIIAABBLLEESS
Environment variables may be specified either in the sys?
tem environment as usual, or in a _l_e_s_s_k_e_y (1) file. If
environment variables are defined in more than one place,
variables defined in a local lesskey file take precedence
over variables defined in the system environment, which
take precedence over variables defined in the system-wide
lesskey file.
Version 382: 03 Feb 2004 27
LESS(1) LESS(1)
COLUMNS
Sets the number of columns on the screen. Takes
precedence over the number of columns specified by
the TERM variable. (But if you have a windowing
system which supports TIOCGWINSZ or WIOCGETD, the
window system's idea of the screen size takes
precedence over the LINES and COLUMNS environment
variables.)
EDITOR The name of the editor (used for the v command).
HOME Name of the user's home directory (used to find a
lesskey file on Unix and OS/2 systems).
HOMEDRIVE, HOMEPATH
Concatenation of the HOMEDRIVE and HOMEPATH envi?
ronment variables is the name of the user's home
directory if the HOME variable is not set (only in
the Windows version).
INIT Name of the user's init directory (used to find a
lesskey file on OS/2 systems).
LANG Language for determining the character set.
LC_CTYPE
Language for determining the character set.
LESS Options which are passed to _l_e_s_s automatically.
LESSANSIENDCHARS
Characters which are assumed to end an ANSI color
escape sequence (default "m").
LESSBINFMT
Format for displaying non-printable, non-control
characters.
LESSCHARDEF
Defines a character set.
LESSCHARSET
Selects a predefined character set.
LESSCLOSE
Command line to invoke the (optional) input-post?
processor.
LESSECHO
Name of the lessecho program (default "lessecho").
The lessecho program is needed to expand metachar?
acters, such as * and ?, in filenames on Unix sys?
tems.
Version 382: 03 Feb 2004 28
LESS(1) LESS(1)
LESSEDIT
Editor prototype string (used for the v command).
See discussion under PROMPTS.
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 _g_l_o_b_a_l (1) command. If not
set, global tags are not used.
LESSKEY
Name of the default lesskey(1) file.
LESSKEY_SYSTEM
Name of the default system-wide lesskey(1) file.
LESSMETACHARS
List of characters which are considered "metachar?
acters" by the shell.
LESSMETAESCAPE
Prefix which less will add before each metacharac?
ter in a command sent to the shell. If LESS?
METAESCAPE is an empty string, commands containing
metacharacters will not be passed to the shell.
LESSOPEN
Command line to invoke the (optional) input-prepro?
cessor.
LESSSECURE
Runs less in "secure" mode. See discussion under
SECURITY.
LESSSEPARATOR
String to be appended to a directory name in file?
name completion.
LINES Sets the number of lines on the screen. Takes
precedence over the number of lines specified by
the TERM variable. (But if you have a windowing
system which supports TIOCGWINSZ or WIOCGETD, the
window system's idea of the screen size takes
precedence over the LINES and COLUMNS environment
variables.)
PATH User's search path (used to find a lesskey file on
MS-DOS and OS/2 systems).
SHELL The shell used to execute the ! command, as well as
to expand filenames.
TERM The type of terminal on which _l_e_s_s is being run.
Version 382: 03 Feb 2004 29
LESS(1) LESS(1)
VISUAL The name of the editor (used for the v command).
SSEEEE AALLSSOO
lesskey(1)
WWAARRNNIINNGGSS
The = command and prompts (unless changed by -P) report
the line numbers of the lines at the top and bottom of the
screen, but the byte and percent of the line after the one
at the bottom of the screen.
If the :e command is used to name more than one file, and
one of the named files has been viewed previously, the new
files may be entered into the list in an unexpected order.
On certain older terminals (the so-called "magic cookie"
terminals), search highlighting will cause an erroneous
display. On such terminals, search highlighting is dis?
abled by default to avoid possible problems.
In certain cases, when search highlighting is enabled and
a search pattern begins with a ^, 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.)
When viewing text containing ANSI color escape sequences
using the -R option, searching will not find text contain?
ing an embedded escape sequence. Also, search highlight?
ing may change the color of some of the text which follows
the highlighted text.
On some systems, _s_e_t_l_o_c_a_l_e claims that ASCII characters 0
thru 31 are control characters rather than binary charac?
ters. This causes _l_e_s_s 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).
See https://www.greenwoodsoftware.com/less for the latest
list of known bugs in this version of less.
CCOOPPYYRRIIGGHHTT
Copyright (C) 2002 Mark Nudelman
less is part of the GNU project and is free software. You
can redistribute it and/or modify it under the terms of
either (1) the GNU General Public License as published by
the Free Software Foundation; or (2) the Less License.
See the file README in the less distribution for more
details regarding redistribution. You should have
Version 382: 03 Feb 2004 30
LESS(1) LESS(1)
received a copy of the GNU General Public License along
with the source for less; see the file COPYING. If not,
write to the Free Software Foundation, 59 Temple Place,
Suite 330, Boston, MA 02111-1307, USA. You should also
have received a copy of the Less License; see the file
LICENSE.
less is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied war?
ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PUR?
POSE. See the GNU General Public License for more
details.
AAUUTTHHOORR
Mark Nudelman
Send bug reports or comments to the above address or to
bug-less@gnu.org.
For more information, see the less homepage at
https://www.greenwoodsoftware.com/less.
Version 382: 03 Feb 2004 31
less-382/lesskey.man 0100444 0000764 0000764 00000034240 10010076274 013523 0 ustar markn markn
LESSKEY(1) LESSKEY(1)
NNAAMMEE
lesskey - specify key bindings for less
SSYYNNOOPPSSIISS
lleesssskkeeyy [[--oo oouuttppuutt]] [[----]] [[iinnppuutt]]
lleesssskkeeyy [[----oouuttppuutt==oouuttppuutt]] [[----]] [[iinnppuutt]]
lleesssskkeeyy --VV
lleesssskkeeyy ----vveerrssiioonn
DDEESSCCRRIIPPTTIIOONN
_L_e_s_s_k_e_y is used to specify a set of key bindings to be
used by _l_e_s_s_. The input file is a text file which
describes the key bindings, If the input file is "-",
standard input is read. If no input file is specified, a
standard filename is used as the name of the input file,
which depends on the system being used: On Unix systems,
$HOME/.lesskey is used; on MS-DOS systems, $HOME/_lesskey
is used; and on OS/2 systems $HOME/lesskey.ini is used, or
$INIT/lesskey.ini if $HOME is undefined. The output file
is a binary file which is used by _l_e_s_s_. If no output file
is specified, and the environment variable LESSKEY is set,
the value of LESSKEY is used as the name of the output
file. Otherwise, a standard filename is used as the name
of the output file, which depends on the system being
used: On Unix and OS-9 systems, $HOME/.less is used; on
MS-DOS systems, $HOME/_less is used; and on OS/2 systems,
$HOME/less.ini is used, or $INIT/less.ini if $HOME is
undefined. If the output file already exists, _l_e_s_s_k_e_y
will overwrite it.
The -V or --version option causes _l_e_s_s_k_e_y to print its
version number and immediately exit. If -V or --version
is present, other options and arguments are ignored.
The input file consists of one or more _s_e_c_t_i_o_n_s_. Each
section starts with a line that identifies the type of
section. Possible sections are:
#command
Defines new command keys.
#line-edit
Defines new line-editing keys.
#env Defines environment variables.
Blank lines and lines which start with a pound sign (#)
are ignored, except for the special section header lines.
CCOOMMMMAANNDD SSEECCTTIIOONN
The command section begins with the line
#command
Version 382: 03 Feb 2004 1
LESSKEY(1) LESSKEY(1)
If the command section is the first section in the file,
this line may be omitted. The command section consists of
lines of the form:
_s_t_r_i_n_g _a_c_t_i_o_n [extra-string]
Whitespace is any sequence of one or more spaces and/or
tabs. The _s_t_r_i_n_g is the command key(s) which invoke the
action. The _s_t_r_i_n_g may be a single command key, or a
sequence of up to 15 keys. The _a_c_t_i_o_n is the name of the
less action, from the list below. The characters in the
_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?
ters specifies input characters as follows:
\b BACKSPACE
\e ESCAPE
\n NEWLINE
\r RETURN
\t TAB
\ku UP ARROW
\kd DOWN ARROW
\kr RIGHT ARROW
\kl LEFT ARROW
\kU PAGE UP
\kD PAGE DOWN
\kh HOME
\ke END
\kx DELETE
A backslash followed by any other character indicates that
character is to be taken literally. Characters which must
be preceded by backslash include caret, space, tab and the
backslash itself.
An action may be followed by an "extra" string. When such
a command is entered while running _l_e_s_s_, the action is
performed, and then the extra string is parsed, just as if
it were typed in to _l_e_s_s_. This feature can be used in
Version 382: 03 Feb 2004 2
LESSKEY(1) LESSKEY(1)
certain cases to extend the functionality of a command.
For example, see the "{" and ":t" commands in the example
below. The extra string has a special meaning for the
"quit" action: when _l_e_s_s quits, first character of the
extra string is used as its exit status.
EEXXAAMMPPLLEE
The following input file describes the set of default com?
mand keys used by less:
#command
\r forw-line
\n forw-line
e forw-line
j forw-line
\kd forw-line
^E forw-line
^N forw-line
k back-line
y back-line
^Y back-line
^K back-line
^P back-line
J forw-line-force
K back-line-force
Y back-line-force
d forw-scroll
^D forw-scroll
u back-scroll
^U back-scroll
\40 forw-screen
f forw-screen
^F forw-screen
^V forw-screen
\kD forw-screen
b back-screen
^B back-screen
\ev back-screen
\kU back-screen
z forw-window
w back-window
\e\40 forw-screen-force
F forw-forever
R repaint-flush
r repaint
^R repaint
^L repaint
\eu undo-hilite
g goto-line
\kh goto-line
< goto-line
\e< goto-line
p percent
Version 382: 03 Feb 2004 3
LESSKEY(1) LESSKEY(1)
% percent
\e[ left-scroll
\e] right-scroll
\e( left-scroll
\e) right-scroll
{ forw-bracket {}
} back-bracket {}
( forw-bracket ()
) back-bracket ()
[ forw-bracket []
] back-bracket []
\e^F forw-bracket
\e^B back-bracket
G goto-end
\e> goto-end
> goto-end
\ke goto-end
= status
^G status
:f status
/ forw-search
? back-search
\e/ forw-search *
\e? back-search *
n repeat-search
\en repeat-search-all
N reverse-search
\eN reverse-search-all
m set-mark
' goto-mark
^X^X goto-mark
E examine
:e examine
^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
_ display-option
| pipe
v visual
! shell
+ firstcmd
H help
h help
V version
0 digit
1 digit
2 digit
Version 382: 03 Feb 2004 4
LESSKEY(1) LESSKEY(1)
3 digit
4 digit
5 digit
6 digit
7 digit
8 digit
9 digit
q quit
Q quit
:q quit
:Q quit
ZZ quit
PPRREECCEEDDEENNCCEE
Commands specified by _l_e_s_s_k_e_y take precedence over the
default commands. A default command key may be disabled
by including it in the input file with the action
"invalid". Alternatively, a key may be defined to do
nothing by using the action "noaction". "noaction" is
similar to "invalid", but _l_e_s_s will give an error beep for
an "invalid" command, but not for a "noaction" command.
In addition, ALL default commands may be disabled by
adding this control line to the input file:
#stop
This will cause all default commands to be ignored. The
#stop line should be the last line in that section of the
file.
Be aware that #stop can be dangerous. Since all default
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.
LLIINNEE EEDDIITTIINNGG SSEECCTTIIOONN
The line-editing section begins with the line:
#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?
tion. The line-editing section consists of a list of keys
and actions, one per line as in the example below.
EEXXAAMMPPLLEE
The following input file describes the set of default
line-editing keys used by less:
Version 382: 03 Feb 2004 5
LESSKEY(1) LESSKEY(1)
#line-edit
\t forw-complete
\17 back-complete
\e\t back-complete
^L expand
^V literal
^A literal
\el right
\kr right
\eh left
\kl left
\eb word-left
\e\kl word-left
\ew word-right
\e\kr word-right
\ei insert
\ex delete
\kx delete
\eX word-delete
\ekx word-delete
\e\b word-backspace
\e0 home
\kh home
\e$ end
\ke end
\ek up
\ku up
\ej down
LLEESSSS EENNVVIIRROONNMMEENNTT VVAARRIIAABBLLEESS
The environment variable section begins with the line
#env
Following this line is a list of environment variable
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
way are visible only to _l_e_s_s_. If a variable is specified
in the system environment and also in a lesskey file, the
value in the lesskey file takes precedence. Although the
lesskey file can be used to override variables set in the
environment, the main purpose of assigning variables in
the lesskey file is simply to have all _l_e_s_s configuration
information stored in one file.
EEXXAAMMPPLLEE
The following input file sets the -i option whenever _l_e_s_s
is run, and specifies the character set to be "latin1":
Version 382: 03 Feb 2004 6
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?
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 key is pressed.
On MS-DOS and OS/2 systems, certain keys send a sequence
of characters which start with a NUL character (0). This
NUL character should be represented as \340 in a lesskey
file.
CCOOPPYYRRIIGGHHTT
Copyright (C) 2000 Mark Nudelman
lesskey is part of the GNU project and is free software;
you can redistribute it and/or modify it under the terms
of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option)
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?
POSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public
License along with lesskey; see the file COPYING. If not,
write to the Free Software Foundation, 59 Temple Place,
Suite 330, Boston, MA 02111-1307, USA.
AAUUTTHHOORR
Mark Nudelman
Send bug reports or comments to the above address or to
bug-less@gnu.org.
Version 382: 03 Feb 2004 7
less-382/less.hlp 0100444 0000764 0000764 00000025621 10010076262 013022 0 ustar markn markn
SSUUMMMMAARRYY OOFF LLEESSSS CCOOMMMMAANNDDSS
Commands marked with * may be preceded by a number, _N.
Notes in parentheses indicate the behavior if _N is given.
h H Display this help.
q :q Q :Q ZZ Exit.
---------------------------------------------------------------------------
MMOOVVIINNGG
e ^E j ^N CR * Forward one line (or _N lines).
y ^Y k ^K ^P * Backward one line (or _N lines).
f ^F ^V SPACE * Forward one window (or _N lines).
b ^B ESC-v * Backward one window (or _N lines).
z * Forward one window (and set window to _N).
w * Backward one window (and set window to _N).
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 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.
---------------------------------------------------
Default "window" is the screen height.
Default "half-window" is half of the screen height.
---------------------------------------------------------------------------
SSEEAARRCCHHIINNGG
/_p_a_t_t_e_r_n * Search forward for (_N-th) matching line.
?_p_a_t_t_e_r_n * Search backward for (_N-th) matching line.
n * Repeat previous search (for _N-th occurrence).
N * Repeat previous search in reverse direction.
ESC-n * Repeat previous search, spanning files.
ESC-N * Repeat previous search, reverse dir. & spanning files.
ESC-u Undo (toggle) search highlighting.
---------------------------------------------------
Search patterns may be modified by one or more of:
^N or ! Search for NON-matching lines.
^E or * Search multiple files (pass thru END OF FILE).
^F or @ Start search at FIRST file (for /) or last file (for ?).
^K Highlight matches, but don't move (KEEP position).
^R Don't use REGULAR EXPRESSIONS.
---------------------------------------------------------------------------
JJUUMMPPIINNGG
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_>.
ESC-^B _<_c_1_> _<_c_2_> * Find open bracket _<_c_1_>
---------------------------------------------------
Each "find close bracket" command goes forward to the close bracket
matching the (_N-th) open bracket in the top line.
Each "find open bracket" command goes backward to the open bracket
matching the (_N-th) close bracket in the bottom line.
m_<_l_e_t_t_e_r_> Mark the current position with .
'_<_l_e_t_t_e_r_> Go to a previously marked position.
'' Go to the previous position.
^X^X Same as '.
---------------------------------------------------
A mark is any upper-case or lower-case letter.
Certain marks are predefined:
^ means beginning of the file
$ means end of the file
---------------------------------------------------------------------------
CCHHAANNGGIINNGG FFIILLEESS
:e [_f_i_l_e] Examine a new file.
^X^V Same as :e.
:n * Examine the (_N-th) next file from the command line.
:p * Examine the (_N-th) previous file from the command line.
:x * Examine the first (or _N-th) file from the command line.
:d Delete the current file from the command line list.
= ^G :f Print current file name.
---------------------------------------------------------------------------
MMIISSCCEELLLLAANNEEOOUUSS CCOOMMMMAANNDDSS
-_<_f_l_a_g_> Toggle a command line option [see OPTIONS below].
--_<_n_a_m_e_> Toggle a command line option, by name.
__<_f_l_a_g_> Display the setting of a command line option.
___<_n_a_m_e_> Display the setting of an option, by name.
+_c_m_d Execute the less cmd each time a new file is examined.
!_c_o_m_m_a_n_d Execute the shell command with $SHELL.
|XX_c_o_m_m_a_n_d Pipe file between current pos & mark XX to shell command.
v Edit the current file with $VISUAL or $EDITOR.
V Print version number of "less".
---------------------------------------------------------------------------
OOPPTTIIOONNSS
Most options may be changed either on the command line,
or from within less by using the - or -- command.
Options may be given in one of two forms: either a single
character preceded by a -, or a name preceeded by --.
-? ........ --help
Display help (from command line).
-a ........ --search-skip-screen
Forward search skips current screen.
-b [_N] .... --buffers=[_N]
Number of buffers.
-B ........ --auto-buffers
Don't automatically allocate buffers for pipes.
-c -C .... --clear-screen --CLEAR-SCREEN
Repaint by scrolling/clearing.
-d ........ --dumb
Dumb terminal.
-D [_x_n_._n] . --color=_x_n_._n
Set screen colors. (MS-DOS only)
-e -E .... --quit-at-eof --QUIT-AT-EOF
Quit at end of file.
-f ........ --force
Force open non-regular files.
-F ........ --quit-if-one-screen
Quit if entire file fits on first screen.
-g ........ --hilite-search
Highlight only last match for searches.
-G ........ --HILITE-SEARCH
Don't highlight any matches for searches.
-h [_N] .... --max-back-scroll=[_N]
Backward scroll limit.
-i ........ --ignore-case
Ignore case in searches that do not contain uppercase.
-I ........ --IGNORE-CASE
Ignore case in all searches.
-j [_N] .... --jump-target=[_N]
Screen position of target lines.
-J ........ --status-column
Display a status column at left edge of screen.
-k [_f_i_l_e] . --lesskey-file=[_f_i_l_e]
Use a lesskey file.
-L ........ --no-lessopen
Ignore the LESSOPEN environment variable.
-m -M .... --long-prompt --LONG-PROMPT
Set prompt style.
-n -N .... --line-numbers --LINE-NUMBERS
Use line numbers.
-o [_f_i_l_e] . --log-file=[_f_i_l_e]
Copy to log file (standard input only).
-O [_f_i_l_e] . --LOG-FILE=[_f_i_l_e]
Copy to log file (unconditionally overwrite).
-p [_p_a_t_t_e_r_n] --pattern=[_p_a_t_t_e_r_n]
Start at pattern (from command line).
-P [_p_r_o_m_p_t] --prompt=[_p_r_o_m_p_t]
Define new prompt.
-q -Q .... --quiet --QUIET --silent --SILENT
Quiet the terminal bell.
-r -R .... --raw-control-chars --RAW-CONTROL-CHARS
Output "raw" control characters.
-s ........ --squeeze-blank-lines
Squeeze multiple blank lines.
-S ........ --chop-long-lines
Chop long lines.
-t [_t_a_g] .. --tag=[_t_a_g]
Find a tag.
-T [_t_a_g_s_f_i_l_e] --tag-file=[_t_a_g_s_f_i_l_e]
Use an alternate tags file.
-u -U .... --underline-special --UNDERLINE-SPECIAL
Change handling of backspaces.
-V ........ --version
Display the version number of "less".
-w ........ --hilite-unread
Highlight first new line after forward-screen.
-W ........ --HILITE-UNREAD
Highlight first new line after any forward movement.
-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]
Set size of window.
-" [_c[_c]] . --quotes=[_c[_c]]
Set shell quote characters.
-~ ........ --tilde
Don't display tildes after end of file.
-# [_N] .... --shift=[_N]
Horizontal scroll amount (0 = one half screen width)
---------------------------------------------------------------------------
LLIINNEE EEDDIITTIINNGG
These keys can be used to edit text being entered
on the "command line" at the bottom of the screen.
RightArrow ESC-l Move cursor right one character.
LeftArrow ESC-h Move cursor left one character.
CNTL-RightArrow ESC-RightArrow ESC-w Move cursor right one word.
CNTL-LeftArrow ESC-LeftArrow ESC-b Move cursor left one word.
HOME ESC-0 Move cursor to start of line.
END ESC-$ Move cursor to end of line.
BACKSPACE Delete char to left of cursor.
DELETE ESC-x Delete char under cursor.
CNTL-BACKSPACE ESC-BACKSPACE Delete word to left of cursor.
CNTL-DELETE ESC-DELETE ESC-X Delete word under cursor.
CNTL-U ESC (MS-DOS only) Delete entire line.
UpArrow ESC-k Retrieve previous command line.
DownArrow ESC-j Retrieve next command line.
TAB Complete filename & cycle.
SHIFT-TAB ESC-TAB Complete filename & reverse cycle.
CNTL-L Complete filename, list all.
less-382/mkfuncs.awk 0100444 0000764 0000764 00000000236 10010075213 013507 0 ustar markn markn BEGIN { FS="("; state = 0 }
/^ public/ { ftype = $0; state = 1 }
{ if (state == 1)
state = 2
else if (state == 2)
{ print ftype,$1,"();"; state = 0 }
}
less-382/mkhelp.c 0100444 0000764 0000764 00000002574 10010075213 012770 0 ustar markn markn /*
* Copyright (C) 1984-2002 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.
*/
/*
* Silly little program to generate the help.c source file
* from the less.hlp text file.
* help.c just contains a char array whose contents are
* the contents of less.hlp.
*/
#include
int
main(argc, argv)
int argc;
char *argv[];
{
int ch;
int prevch;
printf("/* This file was generated by mkhelp from less.hlp */\n");
printf("#include \"less.h\"\n");
printf("constant char helpdata[] = {\n");
ch = 0;
while (prevch = ch, (ch = getchar()) != EOF)
{
switch (ch)
{
case '\'':
printf("'\\'',");
break;
case '\\':
printf("'\\\\',");
break;
case '\b':
printf("'\\b',");
break;
case '\t':
printf("'\\t',");
break;
case '\n':
if (prevch != '\r')
printf("'\\n',\n");
break;
case '\r':
if (prevch != '\n')
printf("'\\n',\n");
break;
default:
if (ch >= ' ' && ch < 0x7f)
printf("'%c',", ch);
else
printf("0x%02x,", ch);
break;
}
}
/* Add an extra null char to avoid having a trailing comma. */
printf(" 0 };\n");
printf("constant int size_helpdata = sizeof(helpdata) - 1;\n");
return (0);
}
less-382/defines.ds 0100664 0000764 0000764 00000023045 10010075213 013311 0 ustar markn markn /*
* Copyright (C) 1984-2000 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.
*/
/* DOS definition file for less. */
/*
* This file has 2 sections:
* User preferences.
* Settings always true for MS-DOS systems.
*/
/* User preferences. */
/*
* SECURE is 1 if you wish to disable a bunch of features in order to
* be safe to run by unprivileged users.
*/
#define SECURE 0
/*
* SHELL_ESCAPE is 1 if you wish to allow shell escapes.
* (This is possible only if your system supplies the system() function.)
*/
#define SHELL_ESCAPE (!SECURE)
/*
* EXAMINE is 1 if you wish to allow examining files by name from within less.
*/
#define EXAMINE (!SECURE)
/*
* TAB_COMPLETE_FILENAME is 1 if you wish to allow the TAB key
* to complete filenames at prompts.
*/
#define TAB_COMPLETE_FILENAME (!SECURE)
/*
* CMD_HISTORY is 1 if you wish to allow keys to cycle through
* previous commands at prompts.
*/
#define CMD_HISTORY 1
/*
* HILITE_SEARCH is 1 if you wish to have search targets to be
* displayed in standout mode.
*/
#define HILITE_SEARCH 1
/*
* EDITOR is 1 if you wish to allow editor invocation (the "v" command).
* (This is possible only if your system supplies the system() function.)
* EDIT_PGM is the name of the (default) editor to be invoked.
*/
#define EDITOR (!SECURE)
#define EDIT_PGM "vi"
/*
* TAGS is 1 if you wish to support tag files.
*/
#define TAGS (!SECURE)
/*
* USERFILE is 1 if you wish to allow a .less file to specify
* user-defined key bindings.
*/
#define USERFILE (!SECURE)
/*
* GLOB is 1 if you wish to have shell metacharacters expanded in filenames.
* This will generally work if your system provides the "popen" function
* and the "echo" shell command.
*/
#ifdef __DJGPP__
#define GLOB (!SECURE)
#else
#define GLOB 0
#endif
/*
* PIPEC is 1 if you wish to have the "|" command
* which allows the user to pipe data into a shell command.
*/
#ifdef __DJGPP__
#define PIPEC (!SECURE)
#else
#define PIPEC 0
#endif
/*
* LOGFILE is 1 if you wish to allow the -l option (to create log files).
*/
#define LOGFILE (!SECURE)
/*
* GNU_OPTIONS is 1 if you wish to support the GNU-style command
* line options --help and --version.
*/
#define GNU_OPTIONS 1
/*
* ONLY_RETURN is 1 if you want RETURN to be the only input which
* will continue past an error message.
* Otherwise, any key will continue past an error message.
*/
#define ONLY_RETURN 0
/*
* LESSKEYFILE is the filename of the default lesskey output file
* (in the HOME directory).
* LESSKEYFILE_SYS is the filename of the system-wide lesskey output file.
* DEF_LESSKEYINFILE is the filename of the default lesskey input
* (in the HOME directory).
*/
#define LESSKEYFILE "_less"
#define LESSKEYFILE_SYS "c:\\_sysless"
#define DEF_LESSKEYINFILE "_lesskey"
/* Settings always true for MS-DOS systems. */
/*
* Define MSDOS_COMPILER if compiling for MS-DOS.
*/
#ifdef __DJGPP__
#define MSDOS_COMPILER DJGPPC
#else
#ifdef __BORLANDC__
#define MSDOS_COMPILER BORLANDC
#else
#define MSDOS_COMPILER MSOFTC
#endif
#endif
/*
* Pathname separator character.
*/
#define PATHNAME_SEP "\\"
/*
* HAVE_SYS_TYPES_H is 1 if your system has .
*/
#define HAVE_SYS_TYPES_H 1
/*
* Define if you have the header file.
*/
#define HAVE_SGSTAT_H 0
/*
* HAVE_PERROR is 1 if your system has the perror() call.
* (Actually, if it has sys_errlist, sys_nerr and errno.)
*/
#define HAVE_PERROR 1
/*
* HAVE_TIME is 1 if your system has the time() call.
*/
#define HAVE_TIME 1
/*
* HAVE_SHELL is 1 if your system supports a SHELL command interpreter.
*/
#define HAVE_SHELL 0
/*
* Default shell metacharacters and meta-escape character.
*/
#define DEF_METACHARS "; *?\t\n'\"()<>|&"
#define DEF_METAESCAPE ""
/*
* HAVE_DUP is 1 if your system has the dup() call.
*/
#define HAVE_DUP 1
/*
* Sizes of various buffers.
*/
#define CMDBUF_SIZE 512 /* Buffer for multichar commands */
#define UNGOT_SIZE 100 /* Max chars to unget() */
#define LINEBUF_SIZE 1024 /* Max size of line in input file */
#define OUTBUF_SIZE 1024 /* Output buffer */
#define PROMPT_SIZE 200 /* Max size of prompt string */
#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 doesn't define. */
#if MSDOS_COMPILER==BORLANDC
#define off_t long
#endif
/* Define if you need to in order for stat and other things to work. */
/* #undef _POSIX_SOURCE */
/* Define as the return type of signal handlers (int or void). */
#define RETSIGTYPE void
/*
* Regular expression library.
* Define exactly one of the following to be 1:
* HAVE_POSIX_REGCOMP: POSIX regcomp() and regex.h
* HAVE_RE_COMP: BSD re_comp()
* HAVE_REGCMP: System V regcmp()
* HAVE_V8_REGCOMP: Henry Spencer V8 regcomp() and regexp.h
* NO_REGEX: pattern matching is supported, but without metacharacters.
*/
/* #undef HAVE_POSIX_REGCOMP */
/* #undef HAVE_RE_COMP */
/* #undef HAVE_REGCMP */
/* #undef HAVE_V8_REGCOMP */
#if MSDOS_COMPILER==DJGPPC
#define HAVE_POSIX_REGCOMP 1
#else
#define NO_REGEX 1
#endif
/* Define HAVE_VOID if your compiler supports the "void" type. */
#define HAVE_VOID 1
/* Define HAVE_CONST if your compiler supports the "const" modifier. */
#define HAVE_CONST 1
/* Define HAVE_TIME_T if your system supports the "time_t" type. */
#define HAVE_TIME_T 1
/* Define HAVE_STRERROR if you have the strerror() function. */
#define HAVE_STRERROR 1
/* Define HAVE_FILENO if you have the fileno() macro. */
#define HAVE_FILENO 1
/* Define HAVE_ERRNO if you have the errno variable */
/* Define MUST_DEFINE_ERRNO if you have errno but it is not defined
* in errno.h */
#if MSDOS_COMPILER==MSOFTC || MSDOS_COMPILER==DJGPPC
#define HAVE_ERRNO 1
#define MUST_DEFINE_ERRNO 0
#else
#define HAVE_ERRNO 1
#define MUST_DEFINE_ERRNO 1
#endif
/* 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 MUST_DEFINE_OSPEED if you have ospeed but it is not defined
* in termcap.h. */
#define HAVE_OSPEED 0
#define MUST_DEFINE_OSPEED 0
/* Define HAVE_LOCALE if you have locale.h and setlocale. */
#define HAVE_LOCALE 0
/* Define HAVE_TERMIOS_FUNCS if you have tcgetattr/tcsetattr */
#define HAVE_TERMIOS_FUNCS 0
/* Define HAVE_UPPER_LOWER if you have isupper, islower, toupper, tolower */
#define HAVE_UPPER_LOWER 1
/* Define if you have the _setjmp function. */
#if MSDOS_COMPILER==MSOFTC || MSDOS_COMPILER==DJGPPC
#define HAVE__SETJMP 0
#else
#define HAVE__SETJMP 1
#endif
/* Define if you have the memcpy function. */
#define HAVE_MEMCPY 1
/* Define if you have the popen function. */
#if MSDOS_COMPILER==DJGPPC
#define HAVE_POPEN 1
#else
#define HAVE_POPEN 0
#endif
/* Define if you have the sigsetmask function. */
#define HAVE_SIGSETMASK 0
/* Define if you have the sigprocmask function. */
#define HAVE_SIGPROCMASK 0
/* Define if you have the sigset_t type and sigemptyset macro */
#define HAVE_SIGSET_T 0
#define HAVE_SIGEMPTYSET 0
/* Define if you have the stat function. */
#define HAVE_STAT 1
/* Define if you have the strchr function. */
#define HAVE_STRCHR 1
/* Define if you have the system function. */
#define HAVE_SYSTEM 1
/* Define if you have the header file. */
#define HAVE_CTYPE_H 1
/* Define if you have the header file. */
#define HAVE_ERRNO_H 1
/* Define if you have the header file. */
#define HAVE_FCNTL_H 1
/* Define if you have the