less 322.
This commit is contained in:
parent
f83ae6979b
commit
5eb1412525
|
@ -4,8 +4,62 @@
|
|||
======================================================================
|
||||
|
||||
For the latest news about less, see the "less" Web page:
|
||||
http://members.aol.com/marknudel/less
|
||||
You can also download the latest version of less there.
|
||||
http://www.fog.net/markn/less
|
||||
You can also download the latest version of less from there.
|
||||
|
||||
The email address for questions about less
|
||||
has been changed to markn@fog.net.
|
||||
|
||||
======================================================================
|
||||
|
||||
|
||||
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.
|
||||
|
||||
======================================================================
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
=========================================================================
|
||||
=== This is the distribution of less, version 321, released 18 Jul 96 ===
|
||||
=== Please report any problems to the author at markn@3do.com. ===
|
||||
=== See http://members.aol.com/marknudel/less for the latest info. ===
|
||||
This is the distribution of less, version 332, released 22 Apr 97
|
||||
Please report any problems to the author at markn@fog.net.
|
||||
(Please note change of email address.)
|
||||
See http://www.fog.net/markn/less for the latest info.
|
||||
=========================================================================
|
||||
|
||||
This is the distribution of "less", a paginator similar to "more" or "pg".
|
||||
|
@ -9,18 +10,17 @@ 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.
|
||||
Known bugs in this version are in BUGS.
|
||||
|
||||
===================
|
||||
===== WARNING =====
|
||||
===================
|
||||
The Microsoft C port for MS-DOS and the Ultra C port
|
||||
for OS-9 are not currently working.
|
||||
Until these are fixed, for MS-DOS use Borland C,
|
||||
Until these are fixed, for MS-DOS use Borland C or DJGPP,
|
||||
and for OS-9 use Microware C.
|
||||
If you have fixes for either of these ports,
|
||||
send them to markn@3do.com.
|
||||
|
||||
send them to markn@fog.net.
|
||||
|
||||
=======================================================================
|
||||
INSTALLATION (Unix systems only):
|
||||
|
||||
|
@ -47,20 +47,21 @@ INSTALLATION (Unix systems only):
|
|||
|
||||
4. Type "make" and watch the fun.
|
||||
|
||||
5. If the make succeeds, it will generate the programs "less" and
|
||||
"lesskey" in your current directory. Test the generated programs.
|
||||
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) in /usr/local/bin
|
||||
Documentation (less.nro, lesskey.nro) in /usr/local/man/man1
|
||||
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@3do.com
|
||||
complaints, etc., you may mail to the author at markn@fog.net.
|
||||
|
||||
Note to hackers: comments noting possible improvements are enclosed
|
||||
in double curly brackets {{ like this }}.
|
||||
|
@ -68,23 +69,26 @@ in double curly brackets {{ like this }}.
|
|||
|
||||
|
||||
=======================================================================
|
||||
INSTALLATION (MS-DOS systems only)
|
||||
INSTALLATION (MS-DOS systems only,
|
||||
with Microsoft C, Borland C, or DJGPP)
|
||||
|
||||
1. Move the distributed source to its own directory.
|
||||
Make sure the source has been converted to have CR-LF rather than
|
||||
LF as line terminators.
|
||||
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.DOS to MAKEFILE.
|
||||
If you are using Borland C, rename MAKEFILE.BCC to MAKEFILE.
|
||||
2. If you are using Microsoft C, rename MAKEFILE.DSM 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. 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.
|
||||
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.DOS to remove some optional features.
|
||||
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.
|
||||
|
@ -104,15 +108,17 @@ INSTALLATION (MS-DOS systems only)
|
|||
|
||||
|
||||
=======================================================================
|
||||
INSTALLATION (Windows-95 and Windows-NT systems only)
|
||||
INSTALLATION (Windows-95 and Windows-NT systems only,
|
||||
with Borland C or Microsoft Visual C++)
|
||||
|
||||
1. Move the distributed source to its own directory.
|
||||
|
||||
2. Rename Makefile.w32 to Makefile.
|
||||
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.w32 to remove some optional features.
|
||||
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.
|
||||
|
@ -130,15 +136,16 @@ INSTALLATION (Windows-95 and Windows-NT systems only)
|
|||
|
||||
|
||||
=======================================================================
|
||||
INSTALLATION (OS/2 systems only)
|
||||
INSTALLATION (OS/2 systems only,
|
||||
with EMX C)
|
||||
|
||||
1. Move the distributed source to its own directory.
|
||||
|
||||
2. Rename Makefile.os2 to Makefile.
|
||||
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.os2 to remove some optional features.
|
||||
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.
|
||||
|
@ -160,7 +167,8 @@ INSTALLATION (OS/2 systems only)
|
|||
|
||||
|
||||
=======================================================================
|
||||
INSTALLATION (OS-9 systems only)
|
||||
INSTALLATION (OS-9 systems only,
|
||||
with Microware C or Ultra C)
|
||||
|
||||
1. Move the distributed source to its own directory.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: acconfig.h,v 1.1.1.2 1997/04/22 13:45:27 mrg Exp $ */
|
||||
/* $NetBSD: acconfig.h,v 1.1.1.3 1997/09/21 12:22:57 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: brac.c,v 1.1.1.2 1997/04/22 13:45:41 mrg Exp $ */
|
||||
/* $NetBSD: brac.c,v 1.1.1.3 1997/09/21 12:23:11 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ch.c,v 1.1.1.2 1997/04/22 13:45:13 mrg Exp $ */
|
||||
/* $NetBSD: ch.c,v 1.1.1.3 1997/09/21 12:22:45 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -36,6 +36,7 @@
|
|||
#include "less.h"
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
#include <errno.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
public int ignore_eoi;
|
||||
|
@ -250,6 +251,10 @@ fch_get()
|
|||
ierror("Waiting for data", NULL_PARG);
|
||||
#if !MSDOS_COMPILER
|
||||
sleep(1);
|
||||
#else
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
Sleep(1000);
|
||||
#endif
|
||||
#endif
|
||||
slept = TRUE;
|
||||
}
|
||||
|
@ -672,6 +677,17 @@ ch_delbufs()
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -707,8 +723,8 @@ ch_init(f, flags)
|
|||
/*
|
||||
* Try to seek; set CH_CANSEEK if it works.
|
||||
*/
|
||||
if (!(flags & CH_HELPFILE) && seekable(f))
|
||||
ch_flags |= CH_CANSEEK;
|
||||
if ((flags & CH_CANSEEK) && !seekable(f))
|
||||
ch_flags &= ~CH_CANSEEK;
|
||||
set_filestate(curr_ifile, (void *) thisfile);
|
||||
}
|
||||
if (thisfile->file == -1)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: charset.c,v 1.1.1.2 1997/04/22 13:45:28 mrg Exp $ */
|
||||
/* $NetBSD: charset.c,v 1.1.1.3 1997/09/21 12:22:58 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -165,7 +165,7 @@ ilocale()
|
|||
{
|
||||
register int c;
|
||||
|
||||
setlocale(LC_CTYPE, "");
|
||||
setlocale(LC_ALL, "");
|
||||
for (c = 0; c < sizeof(chardef); c++)
|
||||
{
|
||||
if (isprint(c))
|
||||
|
@ -249,7 +249,7 @@ init_charset()
|
|||
*/
|
||||
public int
|
||||
binary_char(c)
|
||||
int c;
|
||||
unsigned char c;
|
||||
{
|
||||
c &= 0377;
|
||||
return (chardef[c] & IS_BINARY_CHAR);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cmd.h,v 1.1.1.2 1997/04/22 13:45:43 mrg Exp $ */
|
||||
/* $NetBSD: cmd.h,v 1.1.1.3 1997/09/21 12:23:11 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -110,6 +110,7 @@
|
|||
#define EC_B_COMPLETE 18
|
||||
#define EC_LITERAL 19
|
||||
|
||||
#define EC_NOACTION 101
|
||||
#define EC_UINVALID 102
|
||||
|
||||
/* Flags for editchar() */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cmdbuf.c,v 1.1.1.2 1997/04/22 13:45:14 mrg Exp $ */
|
||||
/* $NetBSD: cmdbuf.c,v 1.1.1.3 1997/09/21 12:22:46 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -60,6 +60,11 @@ static struct textlist tk_tlist;
|
|||
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.
|
||||
|
@ -307,7 +312,6 @@ cmd_left()
|
|||
cmd_ichar(c)
|
||||
int c;
|
||||
{
|
||||
int col;
|
||||
char *s;
|
||||
|
||||
if (strlen(cmdbuf) >= sizeof(cmdbuf)-2)
|
||||
|
@ -341,8 +345,6 @@ cmd_ichar(c)
|
|||
cmd_erase()
|
||||
{
|
||||
register char *s;
|
||||
char *p;
|
||||
int col;
|
||||
|
||||
if (cp == cmdbuf)
|
||||
{
|
||||
|
@ -386,8 +388,6 @@ cmd_erase()
|
|||
static int
|
||||
cmd_delete()
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (*cp == '\0')
|
||||
{
|
||||
/*
|
||||
|
@ -499,7 +499,6 @@ set_mlist(mlist)
|
|||
cmd_updown(action)
|
||||
int action;
|
||||
{
|
||||
char *p;
|
||||
char *s;
|
||||
|
||||
if (curr_mlist == NULL)
|
||||
|
@ -535,6 +534,53 @@ cmd_updown(action)
|
|||
}
|
||||
#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.
|
||||
|
@ -543,45 +589,12 @@ cmd_updown(action)
|
|||
cmd_accept()
|
||||
{
|
||||
#if CMD_HISTORY
|
||||
struct mlist *ml;
|
||||
|
||||
/*
|
||||
* Nothing to do if there is no currently selected history list.
|
||||
*/
|
||||
if (curr_mlist == NULL)
|
||||
return;
|
||||
/*
|
||||
* Don't save a trivial command.
|
||||
*/
|
||||
if (strlen(cmdbuf) == 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 = curr_mlist->next; ml != curr_mlist; ml = ml->next)
|
||||
{
|
||||
if (strcmp(ml->string, cmdbuf) == 0)
|
||||
break;
|
||||
}
|
||||
if (ml == curr_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(cmdbuf);
|
||||
ml->next = curr_mlist;
|
||||
ml->prev = curr_mlist->prev;
|
||||
curr_mlist->prev->next = ml;
|
||||
curr_mlist->prev = ml;
|
||||
}
|
||||
/*
|
||||
* Point to the cmd just after the just-accepted command.
|
||||
* Thus, an UPARROW will always retrieve the previous command.
|
||||
*/
|
||||
curr_mlist->curr_mp = ml->next;
|
||||
cmd_addhist(curr_mlist, cmdbuf);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -693,6 +706,8 @@ cmd_edit(c)
|
|||
case EC_EXPAND:
|
||||
return (cmd_complete(action));
|
||||
#endif
|
||||
case EC_NOACTION:
|
||||
return (CC_OK);
|
||||
default:
|
||||
not_in_completion();
|
||||
return (CC_PASS);
|
||||
|
@ -732,6 +747,10 @@ cmd_istr(str)
|
|||
delimit_word()
|
||||
{
|
||||
char *word;
|
||||
#if SPACES_IN_FILENAMES
|
||||
char *p;
|
||||
int quoted;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Move cursor to end of word.
|
||||
|
@ -764,6 +783,27 @@ delimit_word()
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
quoted = 0;
|
||||
for (p = cmdbuf; p < cp; p++)
|
||||
{
|
||||
if (!quoted && *p == openquote)
|
||||
{
|
||||
quoted = 1;
|
||||
word = p;
|
||||
} else if (quoted && *p == closequote)
|
||||
{
|
||||
quoted = 0;
|
||||
}
|
||||
}
|
||||
if (quoted)
|
||||
return (word);
|
||||
#endif
|
||||
for (word = cp-1; word > cmdbuf; word--)
|
||||
if (word[-1] == ' ')
|
||||
break;
|
||||
|
@ -814,6 +854,10 @@ init_compl()
|
|||
*/
|
||||
c = *cp;
|
||||
*cp = '\0';
|
||||
#if SPACES_IN_FILENAMES
|
||||
if (*word == openquote)
|
||||
word++;
|
||||
#endif
|
||||
tk_text = fcomplete(word);
|
||||
*cp = c;
|
||||
}
|
||||
|
@ -847,6 +891,7 @@ next_compl(action, prev)
|
|||
cmd_complete(action)
|
||||
int action;
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (!in_completion || action == EC_EXPAND)
|
||||
{
|
||||
|
@ -907,6 +952,19 @@ cmd_complete(action)
|
|||
*/
|
||||
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);
|
||||
|
@ -961,10 +1019,7 @@ cmd_char(c)
|
|||
/*
|
||||
* Insert the char into the command buffer.
|
||||
*/
|
||||
action = cmd_ichar(c);
|
||||
if (action != CC_OK)
|
||||
return (action);
|
||||
return (CC_OK);
|
||||
return (cmd_ichar(c));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: decode.c,v 1.1.1.2 1997/04/22 13:45:44 mrg Exp $ */
|
||||
/* $NetBSD: decode.c,v 1.1.1.3 1997/09/21 12:23:12 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -102,6 +102,8 @@ static unsigned char cmdtable[] =
|
|||
'%',0, A_PERCENT,
|
||||
ESC,'[',0, A_LSHIFT,
|
||||
ESC,']',0, A_RSHIFT,
|
||||
ESC,'(',0, A_LSHIFT,
|
||||
ESC,')',0, A_RSHIFT,
|
||||
'{',0, A_F_BRACKET|A_EXTRA, '{','}',0,
|
||||
'}',0, A_B_BRACKET|A_EXTRA, '{','}',0,
|
||||
'(',0, A_F_BRACKET|A_EXTRA, '(',')',0,
|
||||
|
@ -547,7 +549,9 @@ lesskey(filename)
|
|||
/*
|
||||
* Try to open the lesskey file.
|
||||
*/
|
||||
filename = unquote_file(filename);
|
||||
f = open(filename, OPEN_READ);
|
||||
free(filename);
|
||||
if (f < 0)
|
||||
return (1);
|
||||
|
||||
|
@ -606,7 +610,9 @@ add_hometable()
|
|||
char *filename;
|
||||
PARG parg;
|
||||
|
||||
if ((filename = lgetenv("LESSKEY")) == NULL)
|
||||
if ((filename = lgetenv("LESSKEY")) != NULL)
|
||||
filename = save(filename);
|
||||
else
|
||||
filename = homefile(LESSKEYFILE);
|
||||
if (filename == NULL)
|
||||
return;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: defines.h,v 1.1.1.2 1997/04/22 13:45:15 mrg Exp $ */
|
||||
/* $NetBSD: defines.h,v 1.1.1.3 1997/09/21 12:22:47 mrg Exp $ */
|
||||
|
||||
/* defines.h. Generated automatically by configure. */
|
||||
/* defines.h.in. Generated automatically from configure.in by autoheader. */
|
||||
|
@ -133,11 +133,6 @@
|
|||
*/
|
||||
/* #undef HAVE_SGSTAT_H */
|
||||
|
||||
/*
|
||||
* HAVE_STAT is 1 if your system has the stat() call.
|
||||
*/
|
||||
#define HAVE_STAT 1
|
||||
|
||||
/*
|
||||
* HAVE_PERROR is 1 if your system has the perror() call.
|
||||
* (Actually, if it has sys_errlist, sys_nerr and errno.)
|
||||
|
@ -154,6 +149,12 @@
|
|||
*/
|
||||
#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.
|
||||
*/
|
||||
|
@ -245,9 +246,15 @@
|
|||
/* Define if you have the memcpy function. */
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
/* Define if you have the popen function. */
|
||||
#define HAVE_POPEN 1
|
||||
|
||||
/* Define if you have the sigsetmask function. */
|
||||
#define HAVE_SIGSETMASK 1
|
||||
|
||||
/* Define if you have the stat function. */
|
||||
#define HAVE_STAT 1
|
||||
|
||||
/* Define if you have the strchr function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: edit.c,v 1.1.1.2 1997/04/22 13:45:45 mrg Exp $ */
|
||||
/* $NetBSD: edit.c,v 1.1.1.3 1997/09/21 12:23:13 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -38,9 +38,15 @@ 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;
|
||||
|
@ -65,13 +71,25 @@ init_textlist(tlist, str)
|
|||
char *str;
|
||||
{
|
||||
char *s;
|
||||
#if SPACES_IN_FILENAMES
|
||||
int quoted = 0;
|
||||
#endif
|
||||
|
||||
tlist->string = skipsp(str);
|
||||
tlist->endstring = tlist->string + strlen(tlist->string);
|
||||
for (s = str; s < tlist->endstring; s++)
|
||||
{
|
||||
#if SPACES_IN_FILENAMES
|
||||
if (*s == ' ' && !quoted)
|
||||
*s = '\0';
|
||||
if (!quoted && *s == openquote)
|
||||
quoted = 1;
|
||||
else if (quoted && *s == closequote)
|
||||
quoted = 0;
|
||||
#else
|
||||
if (*s == ' ')
|
||||
*s = '\0';
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,6 +150,7 @@ back_textlist(tlist, prev)
|
|||
close_file()
|
||||
{
|
||||
struct scrpos scrpos;
|
||||
char *filename;
|
||||
|
||||
if (curr_ifile == NULL_IFILE)
|
||||
return;
|
||||
|
@ -156,8 +175,9 @@ close_file()
|
|||
*/
|
||||
if (curr_altfilename != NULL)
|
||||
{
|
||||
close_altfile(curr_altfilename, get_filename(curr_ifile),
|
||||
curr_altpipe);
|
||||
filename = unquote_file(get_filename(curr_ifile));
|
||||
close_altfile(curr_altfilename, filename, curr_altpipe);
|
||||
free(filename);
|
||||
free(curr_altfilename);
|
||||
curr_altfilename = NULL;
|
||||
}
|
||||
|
@ -215,12 +235,12 @@ edit_ifile(ifile)
|
|||
#if LOGFILE
|
||||
end_logfile();
|
||||
#endif
|
||||
was_curr_ifile = curr_ifile;
|
||||
was_curr_ifile = save_curr_ifile();
|
||||
if (curr_ifile != NULL_IFILE)
|
||||
{
|
||||
chflags = ch_getflags();
|
||||
close_file();
|
||||
if (chflags & CH_HELPFILE)
|
||||
if ((chflags & CH_HELPFILE) && held_ifile(was_curr_ifile) <= 1)
|
||||
{
|
||||
/*
|
||||
* Don't keep the help file in the ifile list.
|
||||
|
@ -238,10 +258,11 @@ edit_ifile(ifile)
|
|||
* you're supposed to have saved curr_ifile yourself,
|
||||
* and you'll restore it if necessary.)
|
||||
*/
|
||||
unsave_ifile(was_curr_ifile);
|
||||
return (0);
|
||||
}
|
||||
|
||||
filename = get_filename(ifile);
|
||||
filename = unquote_file(get_filename(ifile));
|
||||
/*
|
||||
* See if LESSOPEN specifies an "alternate" file to open.
|
||||
*/
|
||||
|
@ -268,14 +289,17 @@ edit_ifile(ifile)
|
|||
*/
|
||||
f = fd0;
|
||||
chflags |= CH_KEEPOPEN;
|
||||
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==WIN32C
|
||||
/*
|
||||
* Must switch stdin to BINARY mode.
|
||||
*/
|
||||
setmode(f, O_BINARY);
|
||||
#endif
|
||||
#if MSDOS_COMPILER==MSOFTC
|
||||
_setmode(f, _O_BINARY);
|
||||
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)
|
||||
{
|
||||
|
@ -295,10 +319,11 @@ edit_ifile(ifile)
|
|||
free(alt_filename);
|
||||
}
|
||||
del_ifile(ifile);
|
||||
free(filename);
|
||||
/*
|
||||
* Re-open the current file.
|
||||
*/
|
||||
(void) edit_ifile(was_curr_ifile);
|
||||
reedit_ifile(was_curr_ifile);
|
||||
return (1);
|
||||
} else if ((f = open(open_filename, OPEN_READ)) < 0)
|
||||
{
|
||||
|
@ -309,18 +334,23 @@ edit_ifile(ifile)
|
|||
error("%s", &parg);
|
||||
free(parg.p_string);
|
||||
goto err1;
|
||||
} else if (!force_open && !opened(ifile) && bin_file(f))
|
||||
} else
|
||||
{
|
||||
/*
|
||||
* 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')
|
||||
chflags |= CH_CANSEEK;
|
||||
if (!force_open && !opened(ifile) && bin_file(f))
|
||||
{
|
||||
close(f);
|
||||
goto err1;
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,7 +359,10 @@ edit_ifile(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;
|
||||
|
@ -366,6 +399,7 @@ edit_ifile(ifile)
|
|||
#if HILITE_SEARCH
|
||||
clr_hilite();
|
||||
#endif
|
||||
cmd_addhist(ml_examine, filename);
|
||||
if (no_display && errmsgs > 0)
|
||||
{
|
||||
/*
|
||||
|
@ -378,6 +412,7 @@ edit_ifile(ifile)
|
|||
error("%s", &parg);
|
||||
}
|
||||
}
|
||||
free(filename);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -390,7 +425,7 @@ edit_ifile(ifile)
|
|||
edit_list(filelist)
|
||||
char *filelist;
|
||||
{
|
||||
IFILE save_curr_ifile;
|
||||
IFILE save_ifile;
|
||||
char *good_filename;
|
||||
char *filename;
|
||||
char *gfilelist;
|
||||
|
@ -398,7 +433,7 @@ edit_list(filelist)
|
|||
struct textlist tl_files;
|
||||
struct textlist tl_gfiles;
|
||||
|
||||
save_curr_ifile = curr_ifile;
|
||||
save_ifile = save_curr_ifile();
|
||||
good_filename = NULL;
|
||||
|
||||
/*
|
||||
|
@ -425,13 +460,19 @@ edit_list(filelist)
|
|||
* 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_curr_ifile);
|
||||
}
|
||||
reedit_ifile(save_ifile);
|
||||
return (edit(good_filename));
|
||||
}
|
||||
|
||||
|
@ -457,12 +498,13 @@ edit_last()
|
|||
|
||||
|
||||
/*
|
||||
* Edit the next file in the command line (ifile) list.
|
||||
* Edit the next or previous file in the command line (ifile) list.
|
||||
*/
|
||||
static int
|
||||
edit_inext(h, n)
|
||||
edit_istep(h, n, dir)
|
||||
IFILE h;
|
||||
int n;
|
||||
int dir;
|
||||
{
|
||||
IFILE next;
|
||||
|
||||
|
@ -471,7 +513,7 @@ edit_inext(h, n)
|
|||
*/
|
||||
for (;;)
|
||||
{
|
||||
next = next_ifile(h);
|
||||
next = (dir > 0) ? next_ifile(h) : prev_ifile(h);
|
||||
if (--n < 0)
|
||||
{
|
||||
if (edit_ifile(h) == 0)
|
||||
|
@ -484,46 +526,11 @@ edit_inext(h, n)
|
|||
*/
|
||||
return (1);
|
||||
}
|
||||
h = next;
|
||||
}
|
||||
/*
|
||||
* Found a file that we can edit.
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
|
||||
public int
|
||||
edit_next(n)
|
||||
int n;
|
||||
{
|
||||
return edit_inext(curr_ifile, n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Edit the previous file in the command line list.
|
||||
*/
|
||||
static int
|
||||
edit_iprev(h, n)
|
||||
IFILE h;
|
||||
int n;
|
||||
{
|
||||
IFILE next;
|
||||
|
||||
/*
|
||||
* Skip n filenames, then try to edit each filename.
|
||||
*/
|
||||
for (;;)
|
||||
{
|
||||
next = prev_ifile(h);
|
||||
if (--n < 0)
|
||||
{
|
||||
if (edit_ifile(h) == 0)
|
||||
break;
|
||||
}
|
||||
if (next == NULL_IFILE)
|
||||
if (ABORT_SIGS())
|
||||
{
|
||||
/*
|
||||
* Reached beginning of the ifile list.
|
||||
* Interrupt breaks out, if we're in a long
|
||||
* list of files that can't be opened.
|
||||
*/
|
||||
return (1);
|
||||
}
|
||||
|
@ -535,11 +542,34 @@ edit_iprev(h, n)
|
|||
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_iprev(curr_ifile, n);
|
||||
return edit_istep(curr_ifile, n, -1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -566,6 +596,22 @@ edit_index(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.
|
||||
*/
|
||||
|
@ -582,6 +628,7 @@ reedit_ifile(save_ifile)
|
|||
* 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)
|
||||
|
@ -658,6 +705,7 @@ use_logfile(filename)
|
|||
/*
|
||||
* {{ We could use access() here. }}
|
||||
*/
|
||||
filename = unquote_file(filename);
|
||||
exists = open(filename, OPEN_READ);
|
||||
close(exists);
|
||||
exists = (exists >= 0);
|
||||
|
@ -705,6 +753,7 @@ loop:
|
|||
/*
|
||||
* Don't do anything.
|
||||
*/
|
||||
free(filename);
|
||||
return;
|
||||
case 'q':
|
||||
quit(QUIT_OK);
|
||||
|
@ -724,7 +773,11 @@ loop:
|
|||
*/
|
||||
parg.p_string = filename;
|
||||
error("Cannot write to \"%s\"", &parg);
|
||||
free(filename);
|
||||
return;
|
||||
}
|
||||
free(filename);
|
||||
SET_BINARY(logfile);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: filename.c,v 1.1.1.2 1997/04/22 13:45:16 mrg Exp $ */
|
||||
/* $NetBSD: filename.c,v 1.1.1.3 1997/09/21 12:22:47 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -33,11 +33,18 @@
|
|||
*/
|
||||
|
||||
#include "less.h"
|
||||
#include "lglob.h"
|
||||
#if MSDOS_COMPILER
|
||||
#include <dos.h>
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
#if MSDOS_COMPILER==WIN32C && !defined(_MSC_VER)
|
||||
#include <dir.h>
|
||||
#endif
|
||||
#if MSDOS_COMPILER==DJGPPC
|
||||
#include <glob.h>
|
||||
#include <dir.h>
|
||||
#include <limits.h>
|
||||
#define _MAX_PATH PATH_MAX
|
||||
#endif
|
||||
#endif
|
||||
#ifdef _OSK
|
||||
#include <rbf.h>
|
||||
|
@ -46,10 +53,49 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_STAT
|
||||
#include <sys/stat.h>
|
||||
#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 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 *
|
||||
unquote_file(str)
|
||||
char *str;
|
||||
{
|
||||
#if SPACES_IN_FILENAMES
|
||||
char *name;
|
||||
char *p;
|
||||
|
||||
if (*str != openquote)
|
||||
return (save(str));
|
||||
name = (char *) ecalloc(strlen(str), sizeof(char));
|
||||
strcpy(name, str+1);
|
||||
p = name + strlen(name) - 1;
|
||||
if (*p == closequote)
|
||||
*p = '\0';
|
||||
return (name);
|
||||
#else
|
||||
return (save(str));
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a pathname that points to a specified file in a specified directory.
|
||||
|
@ -61,6 +107,7 @@ dirfile(dirname, filename)
|
|||
char *filename;
|
||||
{
|
||||
char *pathname;
|
||||
char *qpathname;
|
||||
int f;
|
||||
|
||||
if (dirname == NULL || *dirname == '\0')
|
||||
|
@ -76,7 +123,8 @@ dirfile(dirname, filename)
|
|||
/*
|
||||
* Make sure the file exists.
|
||||
*/
|
||||
f = open(pathname, OPEN_READ);
|
||||
qpathname = unquote_file(pathname);
|
||||
f = open(qpathname, OPEN_READ);
|
||||
if (f < 0)
|
||||
{
|
||||
free(pathname);
|
||||
|
@ -85,6 +133,7 @@ dirfile(dirname, filename)
|
|||
{
|
||||
close(f);
|
||||
}
|
||||
free(qpathname);
|
||||
return (pathname);
|
||||
}
|
||||
|
||||
|
@ -116,7 +165,17 @@ homefile(filename)
|
|||
* 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);
|
||||
|
@ -169,8 +228,9 @@ fexpand(s)
|
|||
*/
|
||||
ifile = fchar_ifile(*fr);
|
||||
if (ifile == NULL_IFILE)
|
||||
return (save(s));
|
||||
n += strlen(get_filename(ifile));
|
||||
n++;
|
||||
else
|
||||
n += strlen(get_filename(ifile));
|
||||
}
|
||||
/*
|
||||
* Else it is the first char in a string of
|
||||
|
@ -201,8 +261,13 @@ fexpand(s)
|
|||
} else if (fr[1] != *fr)
|
||||
{
|
||||
ifile = fchar_ifile(*fr);
|
||||
strcpy(to, get_filename(ifile));
|
||||
to += strlen(to);
|
||||
if (ifile == NULL_IFILE)
|
||||
*to++ = *fr;
|
||||
else
|
||||
{
|
||||
strcpy(to, get_filename(ifile));
|
||||
to += strlen(to);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -231,7 +296,7 @@ fcomplete(s)
|
|||
/*
|
||||
* Complete the filename "s" by globbing "s*".
|
||||
*/
|
||||
#if MSDOS_COMPILER
|
||||
#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
|
||||
|
@ -242,7 +307,7 @@ fcomplete(s)
|
|||
{
|
||||
char *slash;
|
||||
for (slash = s+strlen(s)-1; slash > s; slash--)
|
||||
if (*slash = *PATHNAME_SEP || *slash == '/')
|
||||
if (*slash == *PATHNAME_SEP || *slash == '/')
|
||||
break;
|
||||
fpat = (char *) ecalloc(strlen(s)+4, sizeof(char));
|
||||
if (strchr(slash, '.') == NULL)
|
||||
|
@ -306,10 +371,11 @@ seek_filesize(f)
|
|||
return ((POSITION) spos);
|
||||
}
|
||||
|
||||
#if GLOB
|
||||
#if HAVE_POPEN
|
||||
|
||||
FILE *popen();
|
||||
|
||||
|
||||
/*
|
||||
* Read a string from a file.
|
||||
* Return a pointer to the string in memory.
|
||||
|
@ -353,121 +419,360 @@ readfd(fd)
|
|||
return (buf);
|
||||
}
|
||||
|
||||
#if HAVE_SHELL
|
||||
|
||||
/*
|
||||
* Get the shell's escape character.
|
||||
*/
|
||||
static char *
|
||||
get_meta_escape()
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = lgetenv("LESSMETAESCAPE");
|
||||
if (s == NULL)
|
||||
s = DEF_METAESCAPE;
|
||||
return (s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Is this a shell metacharacter?
|
||||
*/
|
||||
static int
|
||||
metachar(c)
|
||||
char c;
|
||||
{
|
||||
static char *metachars = NULL;
|
||||
|
||||
if (metachars == NULL)
|
||||
{
|
||||
metachars = lgetenv("LESSMETACHARS");
|
||||
if (metachars == NULL)
|
||||
metachars = DEF_METACHARS;
|
||||
}
|
||||
return (strchr(metachars, c) != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert a backslash before each metacharacter in a string.
|
||||
*/
|
||||
static char *
|
||||
esc_metachars(s)
|
||||
char *s;
|
||||
{
|
||||
char *p;
|
||||
char *newstr;
|
||||
int len;
|
||||
char *esc;
|
||||
int esclen;
|
||||
|
||||
/*
|
||||
* Determine how big a string we need to allocate.
|
||||
*/
|
||||
esc = get_meta_escape();
|
||||
esclen = strlen(esc);
|
||||
len = 1; /* Trailing null byte */
|
||||
for (p = s; *p != '\0'; p++)
|
||||
{
|
||||
len++;
|
||||
if (metachar(*p))
|
||||
{
|
||||
if (*esc == '\0')
|
||||
{
|
||||
/*
|
||||
* We've got a metachar, but this shell
|
||||
* doesn't support escape chars. Give up.
|
||||
*/
|
||||
return (NULL);
|
||||
}
|
||||
/*
|
||||
* Allow space for the escape char.
|
||||
*/
|
||||
len += esclen;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Allocate and construct the new string.
|
||||
*/
|
||||
newstr = p = (char *) ecalloc(len, sizeof(char));
|
||||
while (*s != '\0')
|
||||
{
|
||||
if (metachar(*s))
|
||||
{
|
||||
/*
|
||||
* Add the escape char.
|
||||
*/
|
||||
strcpy(p, esc);
|
||||
p += esclen;
|
||||
}
|
||||
*p++ = *s++;
|
||||
}
|
||||
*p = '\0';
|
||||
return (newstr);
|
||||
}
|
||||
|
||||
#else /* HAVE_SHELL */
|
||||
|
||||
static char *
|
||||
esc_metachars(s)
|
||||
char *s;
|
||||
{
|
||||
return (save(s));
|
||||
}
|
||||
|
||||
#endif /* HAVE_SHELL */
|
||||
|
||||
/*
|
||||
* Execute a shell command.
|
||||
* Return a pointer to a pipe connected to the shell command's standard output.
|
||||
*/
|
||||
static FILE *
|
||||
shellcmd(cmd, s1, s2)
|
||||
shellcmd(cmd)
|
||||
char *cmd;
|
||||
char *s1;
|
||||
char *s2;
|
||||
{
|
||||
char *scmd;
|
||||
char *shell;
|
||||
FILE *fd;
|
||||
int len;
|
||||
|
||||
len = strlen(cmd) +
|
||||
(s1 == NULL ? 0 : strlen(s1)) +
|
||||
(s2 == NULL ? 0 : strlen(s2)) + 1;
|
||||
scmd = (char *) ecalloc(len, sizeof(char));
|
||||
sprintf(scmd, cmd, s1, s2);
|
||||
|
||||
#if HAVE_SHELL
|
||||
char *shell;
|
||||
|
||||
shell = lgetenv("SHELL");
|
||||
if (shell != NULL && *shell != '\0')
|
||||
{
|
||||
char *scmd;
|
||||
char *esccmd;
|
||||
|
||||
/*
|
||||
* Read the output of <$SHELL -c "cmd">.
|
||||
* Try to escape any metacharacters in the command.
|
||||
* If we can't do that, just put the command in quotes.
|
||||
* (But that doesn't work well if the command itself
|
||||
* contains quotes.)
|
||||
*/
|
||||
char *scmd2;
|
||||
scmd2 = (char *) ecalloc(strlen(shell) + strlen(scmd) + 7,
|
||||
sizeof(char));
|
||||
sprintf(scmd2, "%s -c \"%s\"", shell, scmd);
|
||||
if ((esccmd = esc_metachars(cmd)) == NULL)
|
||||
{
|
||||
/*
|
||||
* Cannot escape the metacharacters, so use quotes.
|
||||
* Read the output of <$SHELL -c "cmd">.
|
||||
*/
|
||||
scmd = (char *) ecalloc(strlen(shell) + strlen(cmd) + 7,
|
||||
sizeof(char));
|
||||
sprintf(scmd, "%s -c \"%s\"", shell, cmd);
|
||||
} else
|
||||
{
|
||||
/*
|
||||
* Read the output of <$SHELL -c cmd>.
|
||||
* No quotes; use the escaped cmd.
|
||||
*/
|
||||
scmd = (char *) ecalloc(strlen(shell) + strlen(esccmd) + 5,
|
||||
sizeof(char));
|
||||
sprintf(scmd, "%s -c %s", shell, esccmd);
|
||||
free(esccmd);
|
||||
}
|
||||
fd = popen(scmd, "r");
|
||||
free(scmd);
|
||||
scmd = scmd2;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
fd = popen(scmd, "r");
|
||||
free(scmd);
|
||||
{
|
||||
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 shell-level substitutions.
|
||||
* Expand a filename, doing any system-specific metacharacter substitutions.
|
||||
*/
|
||||
public char *
|
||||
lglob(filename)
|
||||
char *filename;
|
||||
{
|
||||
char *gfilename;
|
||||
char *ofilename;
|
||||
|
||||
filename = fexpand(filename);
|
||||
|
||||
ofilename = fexpand(filename);
|
||||
if (secure)
|
||||
return (filename);
|
||||
#if OS2
|
||||
{
|
||||
char **list;
|
||||
int cnt;
|
||||
int length;
|
||||
return (ofilename);
|
||||
filename = unquote_file(ofilename);
|
||||
|
||||
list = _fnexplode(filename);
|
||||
if (list == NULL)
|
||||
return (filename);
|
||||
length = 1; /* Room for trailing null byte */
|
||||
for (cnt = 0; list[cnt] != NULL; cnt++)
|
||||
length += strlen(list[cnt]) + 1;
|
||||
gfilename = (char *) ecalloc(length, sizeof(char));
|
||||
for (cnt = 0; list[cnt] != NULL; cnt++)
|
||||
#ifdef DECL_GLOB_LIST
|
||||
{
|
||||
/*
|
||||
* The globbing function returns a list of names.
|
||||
*/
|
||||
int length;
|
||||
char *p;
|
||||
DECL_GLOB_LIST(list)
|
||||
|
||||
GLOB_LIST(filename, list);
|
||||
if (GLOB_LIST_FAILED(list))
|
||||
{
|
||||
strcat(gfilename, list[cnt]);
|
||||
strcat(gfilename, " ");
|
||||
free(filename);
|
||||
return (ofilename);
|
||||
}
|
||||
_fnexplodefree(list);
|
||||
length = 1; /* Room for trailing null byte */
|
||||
for (SCAN_GLOB_LIST(list, p))
|
||||
{
|
||||
INIT_GLOB_LIST(list, p);
|
||||
length += strlen(p) + 1;
|
||||
#if SPACES_IN_FILENAMES
|
||||
if (strchr(p, ' ') != NULL)
|
||||
length += 2; /* Allow for quotes */
|
||||
#endif
|
||||
}
|
||||
gfilename = (char *) ecalloc(length, sizeof(char));
|
||||
for (SCAN_GLOB_LIST(list, p))
|
||||
{
|
||||
INIT_GLOB_LIST(list, p);
|
||||
#if SPACES_IN_FILENAMES
|
||||
if (strchr(p, ' ') != NULL)
|
||||
sprintf(gfilename + strlen(gfilename), "%c%s%c ",
|
||||
openquote, p, closequote);
|
||||
else
|
||||
#endif
|
||||
sprintf(gfilename + strlen(gfilename), "%s ", p);
|
||||
}
|
||||
/*
|
||||
* Overwrite the final trailing space with a null terminator.
|
||||
*/
|
||||
*--p = '\0';
|
||||
GLOB_LIST_DONE(list);
|
||||
}
|
||||
#else
|
||||
#ifdef DECL_GLOB_NAME
|
||||
{
|
||||
FILE *fd;
|
||||
char *s;
|
||||
|
||||
/*
|
||||
* We get the shell to expand the filename for us by passing
|
||||
* an "echo" command to the shell and reading its output.
|
||||
* The globbing function returns a single name, and
|
||||
* is called multiple times to walk thru all names.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Certain characters will cause problems if passed to the shell,
|
||||
* so we disallow them.
|
||||
* {{ This presumes too much knowlege about the shell, but not
|
||||
* doing this can cause serious problems. For example, do
|
||||
* "!;TAB" when the first file in the dir is named "rm". }}
|
||||
*/
|
||||
for (s = filename; *s != '\0'; s++)
|
||||
register char *p;
|
||||
register int len;
|
||||
register int n;
|
||||
#if SPACES_IN_FILENAMES
|
||||
register int spaces_in_file;
|
||||
#endif
|
||||
DECL_GLOB_NAME(fnd,drive,dir,fname,ext,handle)
|
||||
|
||||
GLOB_FIRST_NAME(filename, &fnd, handle);
|
||||
if (GLOB_FIRST_FAILED(handle))
|
||||
{
|
||||
if (*s == ';' || *s == '\'' || *s == '\"' || *s == '\\')
|
||||
return (filename);
|
||||
free(filename);
|
||||
return (ofilename);
|
||||
}
|
||||
|
||||
fd = shellcmd("echo %s", filename, (char*)NULL);
|
||||
_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;
|
||||
#if SPACES_IN_FILENAMES
|
||||
spaces_in_file = 0;
|
||||
if (strchr(fnd.GLOB_NAME, ' ') != NULL ||
|
||||
strchr(filename, ' ') != NULL)
|
||||
{
|
||||
spaces_in_file = 1;
|
||||
n += 2;
|
||||
}
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
#if SPACES_IN_FILENAMES
|
||||
if (spaces_in_file)
|
||||
sprintf(p, "%c%s%s%s%c ", openquote,
|
||||
drive, dir, fnd.GLOB_NAME, closequote);
|
||||
else
|
||||
#endif
|
||||
sprintf(p, "%s%s%s ", drive, dir, fnd.GLOB_NAME);
|
||||
p += n;
|
||||
} 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;
|
||||
|
||||
lessecho = lgetenv("LESSECHO");
|
||||
if (lessecho == NULL || *lessecho == '\0')
|
||||
lessecho = "lessecho";
|
||||
s = esc_metachars(filename);
|
||||
if (s == NULL)
|
||||
{
|
||||
/*
|
||||
* There may be dangerous metachars in this name.
|
||||
* We can't risk passing it to the shell.
|
||||
* {{ For example, do "!;TAB" when the first file
|
||||
* in the dir is named "rm". }}
|
||||
*/
|
||||
free(filename);
|
||||
return (ofilename);
|
||||
}
|
||||
/*
|
||||
* Invoke lessecho, and read its output (a globbed list of filenames).
|
||||
*/
|
||||
cmd = (char *) ecalloc(strlen(lessecho) + strlen(s) + 24, sizeof(char));
|
||||
sprintf(cmd, "%s -p0x%x -d0x%x -- %s",
|
||||
lessecho, openquote, closequote, s);
|
||||
fd = shellcmd(cmd);
|
||||
free(s);
|
||||
free(cmd);
|
||||
if (fd == NULL)
|
||||
{
|
||||
/*
|
||||
* Cannot create the pipe.
|
||||
* Just return the original (fexpanded) filename.
|
||||
*/
|
||||
return (filename);
|
||||
free(filename);
|
||||
return (ofilename);
|
||||
}
|
||||
gfilename = readfd(fd);
|
||||
pclose(fd);
|
||||
if (*gfilename == '\0')
|
||||
{
|
||||
free(gfilename);
|
||||
return (filename);
|
||||
free(filename);
|
||||
return (ofilename);
|
||||
}
|
||||
free(filename);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* No globbing functions at all. Just use the fexpanded filename.
|
||||
*/
|
||||
gfilename = save(filename);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
free(filename);
|
||||
free(ofilename);
|
||||
return (gfilename);
|
||||
}
|
||||
|
||||
|
@ -481,8 +786,12 @@ open_altfile(filename, pf, pfd)
|
|||
int *pf;
|
||||
void **pfd;
|
||||
{
|
||||
#if !HAVE_POPEN
|
||||
return (NULL);
|
||||
#else
|
||||
char *lessopen;
|
||||
char *gfilename;
|
||||
char *cmd;
|
||||
FILE *fd;
|
||||
#if HAVE_FILENO
|
||||
int returnfd = 0;
|
||||
|
@ -509,7 +818,21 @@ open_altfile(filename, pf, pfd)
|
|||
return (NULL);
|
||||
#endif
|
||||
}
|
||||
fd = shellcmd(lessopen, filename, (char*)NULL);
|
||||
|
||||
gfilename = esc_metachars(filename);
|
||||
if (gfilename == NULL)
|
||||
{
|
||||
/*
|
||||
* Cannot escape metacharacters.
|
||||
*/
|
||||
return (NULL);
|
||||
}
|
||||
cmd = (char *) ecalloc(strlen(lessopen) + strlen(gfilename) + 2,
|
||||
sizeof(char));
|
||||
sprintf(cmd, lessopen, gfilename);
|
||||
fd = shellcmd(cmd);
|
||||
free(gfilename);
|
||||
free(cmd);
|
||||
if (fd == NULL)
|
||||
{
|
||||
/*
|
||||
|
@ -528,6 +851,7 @@ open_altfile(filename, pf, pfd)
|
|||
* If it does, push the char back on the pipe.
|
||||
*/
|
||||
f = fileno(fd);
|
||||
SET_BINARY(f);
|
||||
if (read(f, &c, 1) != 1)
|
||||
{
|
||||
/*
|
||||
|
@ -550,6 +874,7 @@ open_altfile(filename, pf, pfd)
|
|||
*/
|
||||
return (NULL);
|
||||
return (gfilename);
|
||||
#endif /* HAVE_POPEN */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -561,8 +886,12 @@ close_altfile(altfilename, filename, pipefd)
|
|||
char *filename;
|
||||
void *pipefd;
|
||||
{
|
||||
#if HAVE_POPEN
|
||||
char *lessclose;
|
||||
char *gfilename;
|
||||
char *galtfilename;
|
||||
FILE *fd;
|
||||
char *cmd;
|
||||
|
||||
if (secure)
|
||||
return;
|
||||
|
@ -570,142 +899,62 @@ close_altfile(altfilename, filename, pipefd)
|
|||
pclose((FILE*) pipefd);
|
||||
if ((lessclose = lgetenv("LESSCLOSE")) == NULL)
|
||||
return;
|
||||
fd = shellcmd(lessclose, filename, altfilename);
|
||||
pclose(fd);
|
||||
gfilename = esc_metachars(filename);
|
||||
if (gfilename == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
galtfilename = esc_metachars(altfilename);
|
||||
if (galtfilename == NULL)
|
||||
{
|
||||
free(gfilename);
|
||||
return;
|
||||
}
|
||||
cmd = (char *) ecalloc(strlen(lessclose) + strlen(gfilename) +
|
||||
strlen(galtfilename) + 2, sizeof(char));
|
||||
sprintf(cmd, lessclose, gfilename, galtfilename);
|
||||
fd = shellcmd(cmd);
|
||||
free(galtfilename);
|
||||
free(gfilename);
|
||||
free(cmd);
|
||||
if (fd != NULL)
|
||||
pclose(fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
#if MSDOS_COMPILER
|
||||
|
||||
/*
|
||||
* Define macros for the MS-DOS "find file" interfaces.
|
||||
* Is the specified file a directory?
|
||||
*/
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
|
||||
#define FIND_FIRST(filename,fndp) findfirst(filename, fndp, ~0)
|
||||
#define FIND_NEXT(fndp) findnext(fndp)
|
||||
#define FND_NAME ff_name
|
||||
#define DECLARE_FIND(fnd,drive,dir,fname,ext) \
|
||||
struct ffblk fnd; \
|
||||
char drive[MAXDRIVE]; \
|
||||
char dir[MAXDIR]; \
|
||||
char fname[MAXFILE]; \
|
||||
char ext[MAXEXT];
|
||||
|
||||
#else
|
||||
|
||||
#define FIND_FIRST(filename,fndp) _dos_findfirst(filename, ~0, fndp)
|
||||
#define FIND_NEXT(fndp) _dos_findnext(fndp)
|
||||
#define FND_NAME name
|
||||
#define DECLARE_FIND(fnd,drive,dir,fname,ext) \
|
||||
struct find_t fnd; \
|
||||
char drive[_MAX_DRIVE]; \
|
||||
char dir[_MAX_DIR]; \
|
||||
char fname[_MAX_FNAME]; \
|
||||
char ext[_MAX_EXT];
|
||||
|
||||
#endif
|
||||
|
||||
public char *
|
||||
lglob(filename)
|
||||
public int
|
||||
is_dir(filename)
|
||||
char *filename;
|
||||
{
|
||||
register char *gfilename;
|
||||
register char *p;
|
||||
register int len;
|
||||
register int n;
|
||||
DECLARE_FIND(fnd,drive,dir,fname,ext)
|
||||
|
||||
filename = fexpand(filename);
|
||||
|
||||
if (secure)
|
||||
return (filename);
|
||||
|
||||
if (FIND_FIRST(filename, &fnd) != 0)
|
||||
return (filename);
|
||||
|
||||
_splitpath(filename, drive, dir, fname, ext);
|
||||
len = 100;
|
||||
gfilename = (char *) ecalloc(len, sizeof(char));
|
||||
p = gfilename;
|
||||
do {
|
||||
n = strlen(drive) + strlen(dir) + strlen(fnd.FND_NAME);
|
||||
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);
|
||||
}
|
||||
sprintf(p, "%s%s%s", drive, dir, fnd.FND_NAME);
|
||||
p += n;
|
||||
*p++ = ' ';
|
||||
} while (FIND_NEXT(&fnd) == 0);
|
||||
|
||||
/*
|
||||
* Overwrite the final trailing space with a null terminator.
|
||||
*/
|
||||
*--p = '\0';
|
||||
return (gfilename);
|
||||
}
|
||||
|
||||
public char *
|
||||
open_altfile(filename)
|
||||
char *filename;
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
public void
|
||||
close_altfile(altfilename, filename)
|
||||
char *altfilename;
|
||||
char *filename;
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
public char *
|
||||
lglob(filename)
|
||||
char *filename;
|
||||
{
|
||||
return (fexpand(filename));
|
||||
}
|
||||
|
||||
|
||||
public char *
|
||||
open_altfile(filename)
|
||||
char *filename;
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
public void
|
||||
close_altfile(altfilename, filename)
|
||||
char *altfilename;
|
||||
char *filename;
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
int isdir = 0;
|
||||
|
||||
filename = unquote_file(filename);
|
||||
#if HAVE_STAT
|
||||
{
|
||||
int r;
|
||||
struct stat statbuf;
|
||||
|
||||
#include <sys/stat.h>
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
||||
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
|
||||
#ifndef S_ISREG
|
||||
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
free(filename);
|
||||
return (isdir);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns NULL if the file can be opened and
|
||||
|
@ -716,35 +965,42 @@ close_altfile(altfilename, filename)
|
|||
bad_file(filename)
|
||||
char *filename;
|
||||
{
|
||||
register char *m;
|
||||
struct stat statbuf;
|
||||
register char *m = NULL;
|
||||
|
||||
if (stat(filename, &statbuf) < 0)
|
||||
return (errno_message(filename));
|
||||
|
||||
if (force_open)
|
||||
return (NULL);
|
||||
|
||||
if (S_ISDIR(statbuf.st_mode))
|
||||
filename = unquote_file(filename);
|
||||
if (is_dir(filename))
|
||||
{
|
||||
static char is_dir[] = " is a directory";
|
||||
|
||||
m = (char *) ecalloc(strlen(filename) + sizeof(is_dir),
|
||||
sizeof(char));
|
||||
strcpy(m, filename);
|
||||
strcat(m, is_dir);
|
||||
return (m);
|
||||
}
|
||||
if (!S_ISREG(statbuf.st_mode))
|
||||
} else
|
||||
{
|
||||
static char not_reg[] = " is not a regular file";
|
||||
m = (char *) ecalloc(strlen(filename) + sizeof(not_reg),
|
||||
sizeof(char));
|
||||
strcpy(m, filename);
|
||||
strcat(m, not_reg);
|
||||
return (m);
|
||||
}
|
||||
#if HAVE_STAT
|
||||
int r;
|
||||
struct stat statbuf;
|
||||
|
||||
return (NULL);
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -755,81 +1011,20 @@ bad_file(filename)
|
|||
filesize(f)
|
||||
int f;
|
||||
{
|
||||
#if HAVE_STAT
|
||||
struct stat statbuf;
|
||||
|
||||
if (fstat(f, &statbuf) < 0)
|
||||
/*
|
||||
* Can't stat; try seeking to the end.
|
||||
*/
|
||||
return (seek_filesize(f));
|
||||
|
||||
return ((POSITION) statbuf.st_size);
|
||||
}
|
||||
|
||||
if (fstat(f, &statbuf) >= 0)
|
||||
return ((POSITION) statbuf.st_size);
|
||||
#else
|
||||
#ifdef _OSK
|
||||
|
||||
public char *
|
||||
bad_file(filename)
|
||||
char *filename;
|
||||
{
|
||||
register int f;
|
||||
register char *m;
|
||||
|
||||
if ((f = open(filename, S_IREAD | S_IFDIR)) >= 0)
|
||||
{
|
||||
static char is_dir[] = " is a directory";
|
||||
close(f);
|
||||
if (force_open)
|
||||
return (NULL);
|
||||
m = (char *) ecalloc(strlen(filename) + sizeof(is_dir),
|
||||
sizeof(char));
|
||||
strcpy(m, filename);
|
||||
strcat(m, is_dir);
|
||||
return (m);
|
||||
}
|
||||
if ((f = open(filename, S_IREAD)) < 0)
|
||||
return (errno_message(filename));
|
||||
close(f);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
public POSITION
|
||||
filesize(f)
|
||||
int f;
|
||||
{
|
||||
long size;
|
||||
|
||||
if ((size = (long)_gs_size(f)) < 0)
|
||||
/*
|
||||
* Can't stat; try seeking to the end.
|
||||
*/
|
||||
return (seek_filesize(f));
|
||||
|
||||
return ((POSITION) size);
|
||||
}
|
||||
|
||||
if ((size = (long) _gs_size(f)) >= 0)
|
||||
return ((POSITION) size);
|
||||
#else
|
||||
|
||||
/*
|
||||
* If we have no way to find out, just say the file is good.
|
||||
*/
|
||||
public char *
|
||||
bad_file(filename)
|
||||
char *filename;
|
||||
{
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* We can find the file size by seeking.
|
||||
*/
|
||||
public POSITION
|
||||
filesize(f)
|
||||
int f;
|
||||
{
|
||||
return (seek_filesize(f));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: funcs.h,v 1.1.1.2 1997/04/22 13:45:46 mrg Exp $ */
|
||||
/* $NetBSD: funcs.h,v 1.1.1.3 1997/09/21 12:23:14 mrg Exp $ */
|
||||
|
||||
public void strtcpy ();
|
||||
public char * save ();
|
||||
|
@ -13,7 +13,9 @@
|
|||
public void deinit ();
|
||||
public void home ();
|
||||
public void add_line ();
|
||||
public void remove_top ();
|
||||
public void lower_left ();
|
||||
public void check_winch ();
|
||||
public void goto_line ();
|
||||
public void vbell ();
|
||||
public void bell ();
|
||||
|
@ -58,6 +60,7 @@
|
|||
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 int cmd_int ();
|
||||
|
@ -90,10 +93,13 @@
|
|||
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 * unquote_file ();
|
||||
public char * homefile ();
|
||||
public char * fexpand ();
|
||||
public char * fcomplete ();
|
||||
|
@ -101,16 +107,7 @@
|
|||
public char * lglob ();
|
||||
public char * open_altfile ();
|
||||
public void close_altfile ();
|
||||
public char * lglob ();
|
||||
public char * open_altfile ();
|
||||
public void close_altfile ();
|
||||
public char * lglob ();
|
||||
public char * open_altfile ();
|
||||
public void close_altfile ();
|
||||
public char * bad_file ();
|
||||
public POSITION filesize ();
|
||||
public char * bad_file ();
|
||||
public POSITION filesize ();
|
||||
public int is_dir ();
|
||||
public char * bad_file ();
|
||||
public POSITION filesize ();
|
||||
public void forw ();
|
||||
|
@ -130,6 +127,8 @@
|
|||
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 ();
|
||||
|
@ -175,6 +174,7 @@
|
|||
public void opt_i ();
|
||||
public void opt__V ();
|
||||
public void opt_D ();
|
||||
public void opt_quote ();
|
||||
public void opt_query ();
|
||||
public int get_swindow ();
|
||||
public void scan_option ();
|
||||
|
@ -229,6 +229,7 @@
|
|||
public void init_signals ();
|
||||
public void psignals ();
|
||||
public void findtag ();
|
||||
public int edit_tagfile ();
|
||||
public POSITION tagsearch ();
|
||||
public void open_getchr ();
|
||||
public void close_getchr ();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: help.c,v 1.1.1.2 1997/04/22 13:45:17 mrg Exp $ */
|
||||
/* $NetBSD: help.c,v 1.1.1.3 1997/09/21 12:22:48 mrg Exp $ */
|
||||
|
||||
/* This file was generated by mkhelp from less.hlp */
|
||||
#include "less.h"
|
||||
|
@ -21,8 +21,8 @@ constant char helpdata[] = {
|
|||
' ',' ','E','S','C','-','S','P','A','C','E',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','w','i','n','d','o','w',',',' ','b','u','t',' ','d','o','n','\'','t',' ','s','t','o','p',' ','a','t',' ','e','n','d','-','o','f','-','f','i','l','e','.','\n',
|
||||
' ',' ','d',' ',' ','^','D',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','F','o','r','w','a','r','d',' ',' ','o','n','e',' ','h','a','l','f','-','w','i','n','d','o','w',' ','(','a','n','d',' ','s','e','t',' ','h','a','l','f','-','w','i','n','d','o','w',' ','t','o',' ','_','\b','N',')','.','\n',
|
||||
' ',' ','u',' ',' ','^','U',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','B','a','c','k','w','a','r','d',' ','o','n','e',' ','h','a','l','f','-','w','i','n','d','o','w',' ','(','a','n','d',' ','s','e','t',' ','h','a','l','f','-','w','i','n','d','o','w',' ','t','o',' ','_','\b','N',')','.','\n',
|
||||
' ',' ','E','S','C','-','[',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','L','e','f','t',' ',' ','8',' ','c','h','a','r','a','c','t','e','r',' ','p','o','s','i','t','i','o','n','s',' ','(','o','r',' ','_','\b','N',' ','p','o','s','i','t','i','o','n','s',')','.','\n',
|
||||
' ',' ','E','S','C','-',']',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','i','g','h','t',' ','8',' ','c','h','a','r','a','c','t','e','r',' ','p','o','s','i','t','i','o','n','s',' ','(','o','r',' ','_','\b','N',' ','p','o','s','i','t','i','o','n','s',')','.','\n',
|
||||
' ',' ','E','S','C','-','(',' ',' ','R','i','g','h','t','A','r','r','o','w',' ','*',' ',' ','L','e','f','t',' ',' ','8',' ','c','h','a','r','a','c','t','e','r',' ','p','o','s','i','t','i','o','n','s',' ','(','o','r',' ','_','\b','N',' ','p','o','s','i','t','i','o','n','s',')','.','\n',
|
||||
' ',' ','E','S','C','-',')',' ',' ','L','e','f','t','A','r','r','o','w',' ',' ','*',' ',' ','R','i','g','h','t',' ','8',' ','c','h','a','r','a','c','t','e','r',' ','p','o','s','i','t','i','o','n','s',' ','(','o','r',' ','_','\b','N',' ','p','o','s','i','t','i','o','n','s',')','.','\n',
|
||||
' ',' ','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',
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ifile.c,v 1.1.1.2 1997/04/22 13:45:30 mrg Exp $ */
|
||||
/* $NetBSD: ifile.c,v 1.1.1.3 1997/09/21 12:23:01 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -48,7 +48,8 @@ struct ifile {
|
|||
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_opened; /* Only need one bit */
|
||||
int h_hold; /* Hold count */
|
||||
char h_opened; /* Has this ifile been opened? */
|
||||
struct scrpos h_scrpos; /* Saved position within the file */
|
||||
};
|
||||
|
||||
|
@ -127,6 +128,8 @@ new_ifile(filename, prev)
|
|||
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);
|
||||
}
|
||||
|
@ -306,6 +309,21 @@ opened(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;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: input.c,v 1.1.1.2 1997/04/22 13:45:46 mrg Exp $ */
|
||||
/* $NetBSD: input.c,v 1.1.1.3 1997/09/21 12:23:15 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: jump.c,v 1.1.1.2 1997/04/22 13:45:18 mrg Exp $ */
|
||||
/* $NetBSD: jump.c,v 1.1.1.3 1997/09/21 12:22:50 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: less.h,v 1.1.1.2 1997/04/22 13:45:47 mrg Exp $ */
|
||||
/* $NetBSD: less.h,v 1.1.1.3 1997/09/21 12:23:16 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -36,7 +36,8 @@
|
|||
*/
|
||||
#define MSOFTC 1 /* Microsoft C */
|
||||
#define BORLANDC 2 /* Borland C */
|
||||
#define WIN32C 3 /* Windows (Borland C) */
|
||||
#define WIN32C 3 /* Windows (Borland C or Microsoft C) */
|
||||
#define DJGPPC 4 /* DJGPP C */
|
||||
|
||||
/*
|
||||
* Include the file of compile-time options.
|
||||
|
@ -95,7 +96,7 @@
|
|||
#include <modes.h>
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
#if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==DJGPPC
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
|
@ -128,7 +129,7 @@ void free();
|
|||
#define OPT_ON 1
|
||||
#define OPT_ONPLUS 2
|
||||
|
||||
#ifndef HAVE_MEMCPY
|
||||
#if !HAVE_MEMCPY
|
||||
#ifndef memcpy
|
||||
#define memcpy(to,from,len) bcopy((from),(to),(len))
|
||||
#endif
|
||||
|
@ -175,18 +176,30 @@ typedef long POSITION;
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if MSDOS_COMPILER || OS2
|
||||
#define OPEN_TTYIN() open("CON", OPEN_READ)
|
||||
/*
|
||||
* Set a file descriptor to binary mode.
|
||||
*/
|
||||
#if MSDOS_COMPILER==MSOFTC
|
||||
#define SET_BINARY(f) _setmode(f, _O_BINARY);
|
||||
#else
|
||||
#define OPEN_TTYIN() open("/dev/tty", OPEN_READ)
|
||||
#if MSDOS_COMPILER
|
||||
#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.
|
||||
*/
|
||||
|
@ -300,3 +313,4 @@ struct textlist
|
|||
#define FAKE_HELPFILE "@/\\less/\\help/\\file/\\@"
|
||||
|
||||
#include "funcs.h"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: line.c,v 1.1.1.2 1997/04/22 13:45:19 mrg Exp $ */
|
||||
/* $NetBSD: line.c,v 1.1.1.3 1997/09/21 12:22:51 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: linenum.c,v 1.1.1.2 1997/04/22 13:45:31 mrg Exp $ */
|
||||
/* $NetBSD: linenum.c,v 1.1.1.3 1997/09/21 12:23:02 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: lsystem.c,v 1.1.1.2 1997/04/22 13:45:48 mrg Exp $ */
|
||||
/* $NetBSD: lsystem.c,v 1.1.1.3 1997/09/21 12:23:17 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -38,6 +38,12 @@
|
|||
|
||||
#if MSDOS_COMPILER
|
||||
#include <dos.h>
|
||||
#ifdef _MSC_VER
|
||||
#include <direct.h>
|
||||
#define setdisk(n) _chdrive((n)+1)
|
||||
#else
|
||||
#include <dir.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern int screen_trashed;
|
||||
|
@ -56,9 +62,14 @@ lsystem(cmd, donemsg)
|
|||
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,
|
||||
|
@ -74,10 +85,21 @@ lsystem(cmd, donemsg)
|
|||
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 = curr_ifile;
|
||||
save_ifile = save_curr_ifile();
|
||||
(void) edit_ifile(NULL_IFILE);
|
||||
|
||||
/*
|
||||
|
@ -86,6 +108,9 @@ lsystem(cmd, donemsg)
|
|||
deinit();
|
||||
flush(); /* Make sure the deinit chars get out */
|
||||
raw_mode(0);
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
close_getchr();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Restore signals to their defaults.
|
||||
|
@ -100,7 +125,7 @@ lsystem(cmd, donemsg)
|
|||
*/
|
||||
inp = dup(0);
|
||||
close(0);
|
||||
if (OPEN_TTYIN() < 0)
|
||||
if (open("/dev/tty", OPEN_READ) < 0)
|
||||
dup(inp);
|
||||
#endif
|
||||
|
||||
|
@ -133,9 +158,19 @@ lsystem(cmd, donemsg)
|
|||
|
||||
system(p);
|
||||
free(p);
|
||||
#else
|
||||
#if MSDOS_COMPILER==DJGPPC
|
||||
/*
|
||||
* 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
|
||||
/*
|
||||
|
@ -146,6 +181,9 @@ lsystem(cmd, donemsg)
|
|||
close(inp);
|
||||
#endif
|
||||
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
open_getchr();
|
||||
#endif
|
||||
init_signals(1);
|
||||
raw_mode(1);
|
||||
if (donemsg != NULL)
|
||||
|
@ -157,6 +195,27 @@ lsystem(cmd, donemsg)
|
|||
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.
|
||||
*/
|
||||
|
@ -259,6 +318,9 @@ pipe_data(cmd, spos, epos)
|
|||
flush();
|
||||
raw_mode(0);
|
||||
init_signals(0);
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
close_getchr();
|
||||
#endif
|
||||
#ifdef SIGPIPE
|
||||
LSIGNAL(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
|
@ -292,6 +354,9 @@ pipe_data(cmd, spos, epos)
|
|||
|
||||
#ifdef SIGPIPE
|
||||
LSIGNAL(SIGPIPE, SIG_DFL);
|
||||
#endif
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
open_getchr();
|
||||
#endif
|
||||
init_signals(1);
|
||||
raw_mode(1);
|
||||
|
@ -308,91 +373,140 @@ pipe_data(cmd, spos, epos)
|
|||
|
||||
#ifdef _OSK
|
||||
/*
|
||||
* Popen, and Pclose, for OS-9.
|
||||
* Popen, and Pclose, for OS-9.
|
||||
*
|
||||
* Based on code copyright (c) 1988 by Wolfgang Ocker, Puchheim,
|
||||
* Ulli Dessauer, Germering and
|
||||
* Reimer Mellin, Muenchen
|
||||
* (W-Germany)
|
||||
*
|
||||
* These functions can be copied and distributed freely for any
|
||||
* non-commercial purposes. It can only be incorporated into
|
||||
* commercial software with the written permission of the authors.
|
||||
*
|
||||
* TOP-specific code stripped out and adapted for less by M.Gregorie, 1996
|
||||
*
|
||||
* address: Wolfgang Ocker
|
||||
* Lochhauserstrasse 35a
|
||||
* D-8039 Puchheim
|
||||
* West Germany
|
||||
*
|
||||
* e-mail: weo@altger.UUCP, ud@altger.UUCP, ram@altger.UUCP
|
||||
* pyramid!tmpmbx!recco!weo
|
||||
* pyramid!tmpmbx!nitmar!ud
|
||||
* pyramid!tmpmbx!ramsys!ram
|
||||
*
|
||||
* Martin Gregorie
|
||||
* 10 Sadlers Mead
|
||||
* Harlow
|
||||
* Essex, CM18 6HG
|
||||
* U.K.
|
||||
*
|
||||
* gregorie@logica.com
|
||||
*/
|
||||
|
||||
#define ERR (-1)
|
||||
#define PIPEMAX _NFILE
|
||||
#define READ 1 /* For OS-9 */
|
||||
#define WRITE 2 /* For OS-9 */
|
||||
#define STDIN 0 /* For OS-9 */
|
||||
#define STDOUT 1 /* For OS-9 */
|
||||
|
||||
#define RESTORE free(parameter); close(path); dup(save); close(save);
|
||||
|
||||
static int _pid[PIPEMAX];
|
||||
|
||||
FILE *popen(command, type)
|
||||
char *command, *type;
|
||||
#include <strings.h>
|
||||
#include <errno.h>
|
||||
extern char **environ;
|
||||
extern char *getenv();
|
||||
extern int os9forkc();
|
||||
static int pids[_NFILE] = { 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
/*
|
||||
* p o p e n
|
||||
*/
|
||||
FILE *popen(name, mode)
|
||||
char *name,
|
||||
*mode;
|
||||
{
|
||||
register char *p = command;
|
||||
char *parameter;
|
||||
FILE *_pfp;
|
||||
int l, path, pipe, pcnt, save;
|
||||
|
||||
path = (*type == 'w') ? STDIN : STDOUT;
|
||||
|
||||
if ((pipe = open("/pipe", READ+WRITE)) == ERR)
|
||||
return (NULL);
|
||||
pcnt = pipe;
|
||||
|
||||
if ((save = dup(path)) == ERR)
|
||||
{
|
||||
close(pipe);
|
||||
return (NULL);
|
||||
}
|
||||
close(path);
|
||||
|
||||
if (dup(pipe) == ERR)
|
||||
{
|
||||
dup(save);
|
||||
close(save);
|
||||
close(pipe);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
while (*p != ' ' && *p)
|
||||
p++;
|
||||
if (*p == ' ')
|
||||
p++;
|
||||
l = strlen(p);
|
||||
parameter = (char *) malloc(l+2);
|
||||
strcpy(parameter,p);
|
||||
strcat(parameter,"\n");
|
||||
|
||||
if ((_pid[pcnt] = os9fork(command,l+1,parameter,1,1,0)) == ERR)
|
||||
{
|
||||
{ RESTORE }
|
||||
close(pipe);
|
||||
_pid[pcnt] = 0;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
{ RESTORE }
|
||||
|
||||
if ((_pfp = fdopen(pipe,type)) == NULL)
|
||||
{
|
||||
close(pipe);
|
||||
while (((l=wait(0)) != _pid[pcnt]) && l != ERR)
|
||||
;
|
||||
_pid[pcnt] = 0;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (_pfp);
|
||||
int fd, fd2, fdsav, pid;
|
||||
static char *argv[] = {NULL, NULL, NULL };
|
||||
static char cmd[200];
|
||||
static char cmd_path[200];
|
||||
char *cp;
|
||||
char *shell;
|
||||
FILE *r;
|
||||
if ((shell = getenv("SHELL")) == NULL)
|
||||
return(NULL);
|
||||
cp = name;
|
||||
while (*cp == ' ')
|
||||
cp++;
|
||||
strcpy(cmd_path, cp);
|
||||
if (cp = index(cmd_path, ' '))
|
||||
*cp++ = '\0';
|
||||
strcpy(cmd, "ex ");
|
||||
strcat(cmd, cmd_path);
|
||||
if (cp)
|
||||
{
|
||||
strcat(cmd, " ");
|
||||
strcat(cmd, cp);
|
||||
}
|
||||
argv[0] = shell;
|
||||
argv[1] = cmd;
|
||||
/*
|
||||
mode is "r" (stdout) or "w" (stdin)
|
||||
*/
|
||||
switch(mode[0])
|
||||
{
|
||||
case 'w': fd = 0;
|
||||
break;
|
||||
case 'r': fd = 1;
|
||||
break;
|
||||
default: return(NULL);
|
||||
}
|
||||
if (fd == 1)
|
||||
fflush(stdout);
|
||||
fdsav = dup(fd);
|
||||
close(fd);
|
||||
|
||||
creat("/pipe", S_IWRITE+S_IREAD);
|
||||
pid = os9exec(os9forkc, argv[0], argv, environ, 0, 0, 3);
|
||||
fd2 = dup(fd);
|
||||
close(fd);
|
||||
dup(fdsav);
|
||||
close(fdsav);
|
||||
if (pid > 0)
|
||||
{
|
||||
pids[fd2] = pid;
|
||||
r = fdopen(fd2, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
close(fd2);
|
||||
r = NULL;
|
||||
}
|
||||
return(r);
|
||||
}
|
||||
|
||||
int pclose(stream)
|
||||
FILE *stream;
|
||||
/*
|
||||
* p c l o s e
|
||||
*/
|
||||
int pclose(fp)
|
||||
FILE *fp;
|
||||
{
|
||||
register int i;
|
||||
int f, status;
|
||||
|
||||
f = fileno(stream);
|
||||
fclose(stream);
|
||||
while ((i = wait(&status)) != _pid[f] && i != ERR)
|
||||
;
|
||||
_pid[f] = 0;
|
||||
return ((i == ERR) ? ERR : status);
|
||||
unsigned int status;
|
||||
int pid;
|
||||
int fd,
|
||||
i;
|
||||
fd = fileno(fp);
|
||||
if (pids[fd] == 0)
|
||||
return(-1);
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
while ((pid = wait(&status)) != -1)
|
||||
if (pid == pids[fd])
|
||||
break;
|
||||
else
|
||||
for (i = 0; i < _NFILE; i++)
|
||||
if (pids[i] == pid)
|
||||
{
|
||||
pids[i] = 0;
|
||||
break;
|
||||
}
|
||||
if (pid == -1)
|
||||
status = -1;
|
||||
pids[fd] = 0;
|
||||
return(status);
|
||||
}
|
||||
#endif /* _OSK */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: mark.c,v 1.1.1.2 1997/04/22 13:45:32 mrg Exp $ */
|
||||
/* $NetBSD: mark.c,v 1.1.1.3 1997/09/21 12:23:03 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: optfunc.c,v 1.1.1.2 1997/04/22 13:45:21 mrg Exp $ */
|
||||
/* $NetBSD: optfunc.c,v 1.1.1.3 1997/09/21 12:22:52 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -52,9 +52,10 @@ extern int pr_type;
|
|||
extern int plusoption;
|
||||
extern int swindow;
|
||||
extern int sc_height;
|
||||
extern int any_display;
|
||||
extern int secure;
|
||||
extern int dohelp;
|
||||
extern char openquote;
|
||||
extern char closequote;
|
||||
extern char *prproto[];
|
||||
extern char *eqproto;
|
||||
extern char *hproto;
|
||||
|
@ -66,7 +67,6 @@ extern int logfile;
|
|||
#endif
|
||||
#if TAGS
|
||||
public char *tagoption = NULL;
|
||||
extern char *tagfile;
|
||||
extern char *tags;
|
||||
extern int jump_sline;
|
||||
#endif
|
||||
|
@ -121,8 +121,9 @@ opt_o(type, s)
|
|||
error("No log file", NULL_PARG);
|
||||
else
|
||||
{
|
||||
parg.p_string = namelogfile;
|
||||
parg.p_string = unquote_file(namelogfile);
|
||||
error("Log file \"%s\"", &parg);
|
||||
free(parg.p_string);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -182,8 +183,9 @@ opt_k(type, s)
|
|||
case INIT:
|
||||
if (lesskey(s))
|
||||
{
|
||||
parg.p_string = s;
|
||||
parg.p_string = unquote_file(s);
|
||||
error("Cannot use lesskey file \"%s\"", &parg);
|
||||
free(parg.p_string);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -215,16 +217,15 @@ opt_t(type, s)
|
|||
break;
|
||||
}
|
||||
findtag(skipsp(s));
|
||||
if (tagfile == NULL)
|
||||
break;
|
||||
save_ifile = curr_ifile;
|
||||
if (edit(tagfile))
|
||||
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;
|
||||
}
|
||||
|
@ -250,8 +251,9 @@ opt__T(type, s)
|
|||
tags = lglob(s);
|
||||
break;
|
||||
case QUERY:
|
||||
parg.p_string = tags;
|
||||
parg.p_string = unquote_file(tags);
|
||||
error("Tags file \"%s\"", &parg);
|
||||
free(parg.p_string);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -462,6 +464,42 @@ opt_D(type, s)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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[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.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: option.c,v 1.1.1.2 1997/04/22 13:45:33 mrg Exp $ */
|
||||
/* $NetBSD: option.c,v 1.1.1.3 1997/09/21 12:23:04 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -147,6 +147,7 @@ scan_option(s)
|
|||
quit(QUIT_ERROR);
|
||||
}
|
||||
|
||||
str = NULL;
|
||||
switch (o->otype & OTYPE)
|
||||
{
|
||||
case BOOL:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: option.h,v 1.1.1.2 1997/04/22 13:45:49 mrg Exp $ */
|
||||
/* $NetBSD: option.h,v 1.1.1.3 1997/09/21 12:23:17 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: os.c,v 1.1.1.2 1997/04/22 13:45:34 mrg Exp $ */
|
||||
/* $NetBSD: os.c,v 1.1.1.3 1997/09/21 12:23:05 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -80,6 +80,8 @@ 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
|
||||
|
@ -93,7 +95,11 @@ iread(fd, buf, len)
|
|||
{
|
||||
register int n;
|
||||
|
||||
#if MSDOS_COMPILER
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
if (ABORT_SIGS())
|
||||
return (READ_INTR);
|
||||
#else
|
||||
#if MSDOS_COMPILER && MSDOS_COMPILER != DJGPPC
|
||||
if (kbhit())
|
||||
{
|
||||
int c;
|
||||
|
@ -103,6 +109,7 @@ iread(fd, buf, len)
|
|||
return (READ_INTR);
|
||||
ungetch(c);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
if (SET_JUMP(read_label))
|
||||
{
|
||||
|
@ -122,6 +129,23 @@ iread(fd, buf, len)
|
|||
|
||||
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);
|
||||
reading = 0;
|
||||
if (n < 0)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: output.c,v 1.1.1.2 1997/04/22 13:45:50 mrg Exp $ */
|
||||
/* $NetBSD: output.c,v 1.1.1.3 1997/09/21 12:23:18 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -135,16 +135,50 @@ flush()
|
|||
register int n;
|
||||
register int fd;
|
||||
|
||||
n = ob - obuf;
|
||||
if (n == 0)
|
||||
return;
|
||||
#if MSDOS_COMPILER==WIN32C
|
||||
if (is_tty && any_display)
|
||||
{
|
||||
{
|
||||
char *p;
|
||||
DWORD nwritten = 0;
|
||||
CONSOLE_SCREEN_BUFFER_INFO scr;
|
||||
DWORD nchars;
|
||||
COORD cpos;
|
||||
extern HANDLE con_out;
|
||||
|
||||
*ob = '\0';
|
||||
WriteConsole(con_out, obuf, strlen(obuf), &nwritten, NULL);
|
||||
GetConsoleScreenBufferInfo(con_out, &scr);
|
||||
if (scr.dwCursorPosition.Y != scr.srWindow.Bottom ||
|
||||
(p = strchr(obuf, '\n')) == NULL)
|
||||
{
|
||||
WriteConsole(con_out, obuf, strlen(obuf),
|
||||
&nwritten, NULL);
|
||||
} else
|
||||
{
|
||||
/*
|
||||
* To avoid color problems, if we're writing a
|
||||
* newline at the bottom of the screen, we write
|
||||
* only up to the newline, then fill the bottom
|
||||
* line with the correct attribute, then write
|
||||
* the rest. When Windows-95 scrolls, it takes the
|
||||
* attributes for the new line from the first char
|
||||
* of the (previously) bottom line.
|
||||
*/
|
||||
WriteConsole(con_out, obuf, p - obuf + 1,
|
||||
&nwritten, NULL);
|
||||
cpos.X = 0;
|
||||
cpos.Y = scr.dwCursorPosition.Y;
|
||||
FillConsoleOutputAttribute(con_out, scr.wAttributes,
|
||||
sc_width, cpos, &nchars);
|
||||
WriteConsole(con_out, p + 1, strlen(p + 1),
|
||||
&nwritten, NULL);
|
||||
}
|
||||
ob = obuf;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#if MSDOS_COMPILER==MSOFTC
|
||||
if (is_tty && any_display)
|
||||
|
@ -155,7 +189,7 @@ flush()
|
|||
return;
|
||||
}
|
||||
#else
|
||||
#if MSDOS_COMPILER==BORLANDC
|
||||
#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC
|
||||
if (is_tty && any_display)
|
||||
{
|
||||
*ob = '\0';
|
||||
|
@ -166,9 +200,6 @@ flush()
|
|||
#endif
|
||||
#endif
|
||||
#endif
|
||||
n = ob - obuf;
|
||||
if (n == 0)
|
||||
return;
|
||||
fd = (any_display) ? 1 : 2;
|
||||
if (write(fd, obuf, n) != n)
|
||||
screen_trashed = 1;
|
||||
|
@ -182,8 +213,6 @@ flush()
|
|||
putchr(c)
|
||||
int c;
|
||||
{
|
||||
if (ob >= &obuf[sizeof(obuf)])
|
||||
flush();
|
||||
if (need_clr)
|
||||
{
|
||||
need_clr = 0;
|
||||
|
@ -198,6 +227,12 @@ putchr(c)
|
|||
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);
|
||||
}
|
||||
|
@ -324,7 +359,7 @@ error(fmt, parg)
|
|||
|
||||
errmsgs++;
|
||||
|
||||
if (any_display)
|
||||
if (any_display && is_tty)
|
||||
{
|
||||
clear_bot();
|
||||
so_enter();
|
||||
|
@ -333,7 +368,7 @@ error(fmt, parg)
|
|||
|
||||
col += iprintf(fmt, parg);
|
||||
|
||||
if (!any_display)
|
||||
if (!(any_display && is_tty))
|
||||
{
|
||||
putchr('\n');
|
||||
return;
|
||||
|
@ -391,13 +426,13 @@ query(fmt, parg)
|
|||
register int c;
|
||||
int col = 0;
|
||||
|
||||
if (any_display)
|
||||
if (any_display && is_tty)
|
||||
clear_bot();
|
||||
|
||||
(void) iprintf(fmt, parg);
|
||||
c = getchr();
|
||||
|
||||
if (!any_display)
|
||||
if (!(any_display && is_tty))
|
||||
{
|
||||
putchr('\n');
|
||||
return (c);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: position.c,v 1.1.1.2 1997/04/22 13:45:35 mrg Exp $ */
|
||||
/* $NetBSD: position.c,v 1.1.1.3 1997/09/21 12:23:06 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: position.h,v 1.1.1.2 1997/04/22 13:45:51 mrg Exp $ */
|
||||
/* $NetBSD: position.h,v 1.1.1.3 1997/09/21 12:23:19 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: regexp.c,v 1.1.1.2 1997/04/22 13:45:36 mrg Exp $ */
|
||||
/* $NetBSD: regexp.c,v 1.1.1.3 1997/09/21 12:23:07 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* regcomp and regexec -- regsub and regerror are elsewhere
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: regexp.h,v 1.1.1.2 1997/04/22 13:45:52 mrg Exp $ */
|
||||
/* $NetBSD: regexp.h,v 1.1.1.3 1997/09/21 12:23:20 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Definitions etc. for regexp(3) routines.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: search.c,v 1.1.1.2 1997/04/22 13:45:37 mrg Exp $ */
|
||||
/* $NetBSD: search.c,v 1.1.1.3 1997/09/21 12:23:08 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -125,9 +125,9 @@ cvt_text(odst, osrc, ops)
|
|||
|
||||
for (src = osrc, dst = odst; *src != '\0'; src++, dst++)
|
||||
{
|
||||
if ((ops & CVT_TO_LC) && isupper(*src))
|
||||
if ((ops & CVT_TO_LC) && isupper((unsigned char) *src))
|
||||
/* Convert uppercase to lowercase. */
|
||||
*dst = tolower(*src);
|
||||
*dst = tolower((unsigned char) *src);
|
||||
else if ((ops & CVT_BS) && *src == '\b' && dst > odst)
|
||||
/* Delete BS and preceding char. */
|
||||
dst -= 2;
|
||||
|
@ -148,7 +148,7 @@ is_ucase(s)
|
|||
register char *p;
|
||||
|
||||
for (p = s; *p != '\0'; p++)
|
||||
if (isupper(*p))
|
||||
if (isupper((unsigned char) *p))
|
||||
return (1);
|
||||
return (0);
|
||||
}
|
||||
|
@ -159,6 +159,8 @@ is_ucase(s)
|
|||
static int
|
||||
prev_pattern()
|
||||
{
|
||||
if (last_search_type & SRCH_NO_REGEX)
|
||||
return (last_pattern != NULL);
|
||||
#if HAVE_POSIX_REGCOMP
|
||||
return (regpattern != NULL);
|
||||
#endif
|
||||
|
@ -256,51 +258,55 @@ compile_pattern(pattern, search_type)
|
|||
char *pattern;
|
||||
int search_type;
|
||||
{
|
||||
#if HAVE_POSIX_REGCOMP
|
||||
regex_t *s = (regex_t *) ecalloc(1, sizeof(regex_t));
|
||||
if (regcomp(s, pattern, REGCOMP_FLAG))
|
||||
if ((search_type & SRCH_NO_REGEX) == 0)
|
||||
{
|
||||
free(s);
|
||||
error("Invalid pattern", NULL_PARG);
|
||||
return (-1);
|
||||
}
|
||||
if (regpattern != NULL)
|
||||
regfree(regpattern);
|
||||
regpattern = s;
|
||||
#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_RE_COMP
|
||||
PARG parg;
|
||||
if ((parg.p_string = re_comp(pattern)) != NULL)
|
||||
{
|
||||
error("%s", &parg);
|
||||
return (-1);
|
||||
}
|
||||
re_pattern = 1;
|
||||
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;
|
||||
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 error message via regerror().
|
||||
*/
|
||||
return (-1);
|
||||
}
|
||||
if (regpattern != NULL)
|
||||
free(regpattern);
|
||||
regpattern = s;
|
||||
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);
|
||||
|
@ -336,9 +342,7 @@ uncompile_pattern()
|
|||
free(regpattern);
|
||||
regpattern = NULL;
|
||||
#endif
|
||||
#if NO_REGEX
|
||||
last_pattern = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: signal.c,v 1.1.1.2 1997/04/22 13:45:52 mrg Exp $ */
|
||||
/* $NetBSD: signal.c,v 1.1.1.3 1997/09/21 12:23:21 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -65,6 +65,15 @@ u_interrupt(type)
|
|||
#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();
|
||||
}
|
||||
|
@ -117,6 +126,29 @@ winch(type)
|
|||
#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.
|
||||
*/
|
||||
|
@ -130,6 +162,9 @@ init_signals(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
|
||||
|
@ -146,6 +181,9 @@ init_signals(on)
|
|||
* 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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: tags.c,v 1.1.1.2 1997/04/22 13:45:25 mrg Exp $ */
|
||||
/* $NetBSD: tags.c,v 1.1.1.3 1997/09/21 12:22:56 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -33,9 +33,9 @@
|
|||
|
||||
#if TAGS
|
||||
|
||||
public char *tagfile;
|
||||
public char *tags = "tags";
|
||||
|
||||
static char *tagfile;
|
||||
static char *tagpattern;
|
||||
static int taglinenum;
|
||||
static int tagendline;
|
||||
|
@ -62,7 +62,10 @@ findtag(tag)
|
|||
int err;
|
||||
char tline[TAGLINE_SIZE];
|
||||
|
||||
if ((f = fopen(tags, "r")) == NULL)
|
||||
p = unquote_file(tags);
|
||||
f = fopen(p, "r");
|
||||
free(p);
|
||||
if (f == NULL)
|
||||
{
|
||||
error("No tags file", NULL_PARG);
|
||||
tagfile = NULL;
|
||||
|
@ -110,6 +113,7 @@ findtag(tag)
|
|||
if (*p == '\0')
|
||||
/* Pattern is missing! */
|
||||
continue;
|
||||
tagfile = save(tagfile);
|
||||
|
||||
/*
|
||||
* First see if it is a line number.
|
||||
|
@ -149,6 +153,19 @@ findtag(tag)
|
|||
tagfile = NULL;
|
||||
}
|
||||
|
||||
public int
|
||||
edit_tagfile()
|
||||
{
|
||||
int r;
|
||||
|
||||
if (tagfile == NULL)
|
||||
return (1);
|
||||
r = edit(tagfile);
|
||||
free(tagfile);
|
||||
tagfile = NULL;
|
||||
return (r);
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for a tag.
|
||||
* This is a stripped-down version of search().
|
||||
|
@ -163,6 +180,7 @@ tagsearch()
|
|||
{
|
||||
POSITION pos, linepos;
|
||||
int linenum;
|
||||
int len;
|
||||
char *line;
|
||||
|
||||
/*
|
||||
|
@ -217,8 +235,9 @@ tagsearch()
|
|||
* If tagendline is set, make sure we match all
|
||||
* the way to end of line (no extra chars after the match).
|
||||
*/
|
||||
if (strncmp(tagpattern, line, strlen(tagpattern)) == 0 &&
|
||||
(!tagendline || line[strlen(tagpattern)] == '\0'))
|
||||
len = strlen(tagpattern);
|
||||
if (strncmp(tagpattern, line, len) == 0 &&
|
||||
(!tagendline || line[len] == '\0' || line[len] == '\r'))
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ttyin.c,v 1.1.1.2 1997/04/22 13:45:39 mrg Exp $ */
|
||||
/* $NetBSD: ttyin.c,v 1.1.1.3 1997/09/21 12:23:09 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -39,6 +39,7 @@ static DWORD console_mode;
|
|||
#endif
|
||||
|
||||
static int tty;
|
||||
extern int sigs;
|
||||
|
||||
/*
|
||||
* Open keyboard for input.
|
||||
|
@ -52,12 +53,12 @@ open_getchr()
|
|||
memset(&sa, 0, sizeof(SECURITY_ATTRIBUTES));
|
||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa.bInheritHandle = TRUE;
|
||||
tty = (int) CreateFile("CONIN$", GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
|
||||
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, 0); /* doesn't work for some reason --jdp */
|
||||
SetConsoleMode((HANDLE)tty, ENABLE_PROCESSED_INPUT);
|
||||
#else
|
||||
#if MSDOS_COMPILER || OS2
|
||||
extern int fd0;
|
||||
|
@ -67,7 +68,14 @@ open_getchr()
|
|||
*/
|
||||
fd0 = dup(0);
|
||||
close(0);
|
||||
tty = OPEN_TTYIN();
|
||||
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.
|
||||
|
@ -75,7 +83,7 @@ open_getchr()
|
|||
* which in Unix is usually attached to the screen,
|
||||
* but also usually lets you read from the keyboard.
|
||||
*/
|
||||
tty = OPEN_TTYIN();
|
||||
tty = open("/dev/tty", OPEN_READ);
|
||||
if (tty < 0)
|
||||
tty = 2;
|
||||
#endif
|
||||
|
@ -105,12 +113,14 @@ getchr()
|
|||
|
||||
do
|
||||
{
|
||||
#if MSDOS_COMPILER
|
||||
#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();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: version.c,v 1.1.1.2 1997/04/22 13:45:53 mrg Exp $ */
|
||||
/* $NetBSD: version.c,v 1.1.1.3 1997/09/21 12:23:21 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -550,6 +550,26 @@ v318 5/29/96 Port to OS-9 Microware compiler; minor fixes
|
|||
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.
|
||||
*/
|
||||
|
||||
char version[] = "321";
|
||||
char version[] = "332";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.TH LESSKEY 1 "Version 321: 18 Jul 96"
|
||||
.TH LESSKEY 1 "Version 332: 22 Apr 97"
|
||||
.SH NAME
|
||||
lesskey \- specify key bindings for less
|
||||
.SH SYNOPSIS
|
||||
|
@ -86,6 +86,10 @@ string is parsed, just as if it were typed in to
|
|||
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
|
||||
|
@ -292,4 +296,4 @@ This NUL character should be represented as \e340 in a lesskey file.
|
|||
.SH COPYRIGHT
|
||||
Copyright (c) 1984,1985,1989,1994,1995 Mark Nudelman
|
||||
.br
|
||||
Comments to: markn@3do.com
|
||||
Comments to: markn@fog.net
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: lesskey.c,v 1.1.1.2 1997/04/22 13:45:56 mrg Exp $ */
|
||||
/* $NetBSD: lesskey.c,v 1.1.1.3 1997/09/21 12:23:24 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1984,1985,1989,1994,1995,1996 Mark Nudelman
|
||||
|
@ -185,8 +185,8 @@ struct cmdname editnames[] =
|
|||
"up", EC_UP,
|
||||
"word-backspace", EC_W_BACKSPACE,
|
||||
"word-delete", EC_W_DELETE,
|
||||
"word-left", EC_W_RIGHT,
|
||||
"word-right", EC_W_LEFT,
|
||||
"word-left", EC_W_LEFT,
|
||||
"word-right", EC_W_RIGHT,
|
||||
NULL, 0
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: lesskey.h,v 1.1.1.2 1997/04/22 13:45:56 mrg Exp $ */
|
||||
/* $NetBSD: lesskey.h,v 1.1.1.3 1997/09/21 12:23:25 mrg Exp $ */
|
||||
|
||||
/*
|
||||
* Format of a lesskey file:
|
||||
|
|
Loading…
Reference in New Issue