incorporated alm's update of elvis to 1.7
This commit is contained in:
parent
744d9dbe75
commit
18969c77a9
@ -1,6 +1,8 @@
|
||||
|
||||
PROG= elvispreserve
|
||||
CFLAGS= -I${.CURDIR}/../../usr.bin/elvis
|
||||
BINOWN= root
|
||||
BINMODE=4755
|
||||
MAN8=elvispreserve.0
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,15 +1,15 @@
|
||||
.TH ELVISPRESERVE 8
|
||||
.TH ELVPRSV 1
|
||||
.SH NAME
|
||||
elvispreserve - Preserve the the modified version of a file after a crash.
|
||||
elvprsv - Preserve the the modified version of a file after a crash.
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB\fBelvispreserve\fP ["-\fIwhy elvis died\fP"] /tmp/\fIfilename\fP...
|
||||
\fB\fBelvispreserve\fP -R /tmp/\fIfilename\fP...
|
||||
\fB\fBelvprsv\fP ["-\fIwhy elvis died\fP"] /tmp/\fIfilename\fP...
|
||||
\fB\fBelvprsv\fP -R /tmp/\fIfilename\fP...
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
\fIelvispreserve\fP preserves your edited text after \fIelvis\fP dies.
|
||||
The text can be recovered later, via the \fIelvispreserve\fP program.
|
||||
\fIelvprsv\fP preserves your edited text after \fIelvis\fP dies.
|
||||
The text can be recovered later, via the \fIelvprsv\fP program.
|
||||
.PP
|
||||
For UNIX-like systems,
|
||||
you should never need to run this program from the command line.
|
||||
@ -17,35 +17,35 @@ It is run automatically when \fIelvis\fP is about to die,
|
||||
and it should be run (via /etc/rc) when the computer is booted.
|
||||
THAT'S ALL!
|
||||
.PP
|
||||
For non-UNIX systems such as MS-DOS, you can either use \fIelvispreserve\fP
|
||||
For non-UNIX systems such as MS-DOS, you can either use \fIelvprsv\fP
|
||||
the same way as under UNIX systems (by running it from your AUTOEXEC.BAT file),
|
||||
or you can run it separately with the "-R" flag to recover the files
|
||||
in one step.
|
||||
.PP
|
||||
If you're editing a file when \fIelvis\fP dies
|
||||
(due to a bug, system crash, power failure, etc.)
|
||||
then \fIelvispreserve\fP will preserve the most recent version of your text.
|
||||
then \fIelvprsv\fP will preserve the most recent version of your text.
|
||||
The preserved text is stored in a special directory; it does NOT overwrite
|
||||
your text file automatically.
|
||||
.PP
|
||||
\fIelvispreserve\fP will send mail to any user whose work it preserves,
|
||||
\fIelvprsv\fP will send mail to any user whose work it preserves,
|
||||
if your operating system normally supports mail.
|
||||
.SH FILES
|
||||
.IP /tmp/elv*
|
||||
The temporary file that \fIelvis\fP was using when it died.
|
||||
.IP /usr/preserve/p*
|
||||
The text that is preserved by \fIelvispreserve\fP.
|
||||
The text that is preserved by \fIelvprsv\fP.
|
||||
.IP /usr/preserve/Index
|
||||
A text file which lists the names of all preserved files, and the names
|
||||
of the /usr/preserve/p* files which contain their preserved text.
|
||||
.SH BUGS
|
||||
.PP
|
||||
Due to the permissions on the /usr/preserve directory, on UNIX systems
|
||||
\fIelvispreserve\fP must be run as superuser.
|
||||
This is accomplished by making the \fIelvispreserve\fP executable be owned by "root"
|
||||
\fIelvprsv\fP must be run as superuser.
|
||||
This is accomplished by making the \fIelvprsv\fP executable be owned by "root"
|
||||
and turning on its "set user id" bit.
|
||||
.PP
|
||||
If you're editing a nameless buffer when \fIelvis\fP dies, then \fIelvispreserve\fP will pretend
|
||||
If you're editing a nameless buffer when \fIelvis\fP dies, then \fIelvprsv\fP will pretend
|
||||
that the file was named "foo".
|
||||
.SH AUTHOR
|
||||
.nf
|
||||
|
@ -53,6 +53,17 @@
|
||||
#include "config.h"
|
||||
#include "vi.h"
|
||||
|
||||
/* We include ctype.c here (instead of including just ctype.h and linking
|
||||
* with ctype.o) because on some systems ctype.o will have been compiled in
|
||||
* "large model" and the elvprsv program is to be compiled in "small model"
|
||||
* You can't mix models. By including ctype.c here, we can avoid linking
|
||||
* with ctype.o.
|
||||
*/
|
||||
#include "ctype.c"
|
||||
|
||||
void preserve P_((char *, char *));
|
||||
void main P_((int, char **));
|
||||
|
||||
#if AMIGA
|
||||
BLK tmpblk;
|
||||
# include "amiwild.c"
|
||||
@ -121,7 +132,7 @@ void preserve(tname, when)
|
||||
|| read(infd, name.c, BLKSIZE) != BLKSIZE)
|
||||
{
|
||||
/* something wrong with the file - sorry */
|
||||
fprintf(stderr, "%s: trucated header blocks\n", tname);
|
||||
fprintf(stderr, "%s: truncated header blocks\n", tname);
|
||||
close(infd);
|
||||
return;
|
||||
}
|
||||
@ -138,6 +149,16 @@ void preserve(tname, when)
|
||||
return;
|
||||
}
|
||||
|
||||
/* If there are no text blocks in the file, then we must've never
|
||||
* really started editing. Discard the file.
|
||||
*/
|
||||
if (hdr.n[1] == 0)
|
||||
{
|
||||
close(infd);
|
||||
unlink(tname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rewrite_now)
|
||||
{
|
||||
/* we don't need to open the index file */
|
||||
@ -147,7 +168,8 @@ void preserve(tname, when)
|
||||
for (i = 1; i < MAXBLKS && hdr.n[i]; i++)
|
||||
{
|
||||
lseek(infd, (long)hdr.n[i] * (long)BLKSIZE, 0);
|
||||
if (read(infd, buf.c, BLKSIZE) != BLKSIZE)
|
||||
if (read(infd, buf.c, BLKSIZE) != BLKSIZE
|
||||
|| buf.c[0] == '\0')
|
||||
{
|
||||
/* messed up header */
|
||||
fprintf(stderr, "%s: unrecoverable -- header trashed\n", name.c);
|
||||
@ -172,9 +194,12 @@ void preserve(tname, when)
|
||||
if (!index)
|
||||
{
|
||||
perror(PRSVINDEX);
|
||||
exit(1);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/* should be at the end of the file already, but MAKE SURE */
|
||||
fseek(index, 0L, 2);
|
||||
|
||||
/* create the recovery file in the PRESVDIR directory */
|
||||
#if AMIGA
|
||||
prsvdir = &PRSVDIR[strlen(PRSVDIR) - 1];
|
||||
@ -199,7 +224,8 @@ void preserve(tname, when)
|
||||
for (i = 1; i < MAXBLKS && hdr.n[i]; i++)
|
||||
{
|
||||
lseek(infd, (long)hdr.n[i] * (long)BLKSIZE, 0);
|
||||
if (read(infd, buf.c, BLKSIZE) != BLKSIZE)
|
||||
if (read(infd, buf.c, BLKSIZE) != BLKSIZE
|
||||
|| buf.c[0] == '\0')
|
||||
{
|
||||
/* messed up header */
|
||||
fprintf(stderr, "%s: unrecoverable -- header trashed\n", name.c);
|
||||
@ -242,7 +268,7 @@ void preserve(tname, when)
|
||||
}
|
||||
}
|
||||
|
||||
main(argc, argv)
|
||||
void main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
@ -251,10 +277,11 @@ main(argc, argv)
|
||||
|
||||
#if MSDOS || TOS
|
||||
/* expand any wildcards in the command line */
|
||||
_ct_init("");
|
||||
argv = wildexpand(&argc, argv);
|
||||
#endif
|
||||
|
||||
/* do we have a "when" argument? */
|
||||
/* do we have a "-c", "-R", or "-when elvis died" argument? */
|
||||
i = 1;
|
||||
if (argc >= i + 1 && !strcmp(argv[i], "-R"))
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
# @(#)Makefile 5.8.1.1 (Berkeley) 5/8/91
|
||||
#
|
||||
# $Header: /cvsroot/src/usr.bin/Makefile,v 1.7 1993/04/04 20:14:43 cgd Exp $
|
||||
# $Header: /cvsroot/src/usr.bin/Makefile,v 1.8 1993/04/08 02:22:57 cgd Exp $
|
||||
|
||||
# BROKEN: tn3270 rcs
|
||||
|
||||
@ -13,7 +13,7 @@ SUBDIR= ar awk biff basename cal calendar \
|
||||
login logname lorder m4 machine mail make man mesg mkdep mkfifo \
|
||||
mkstr more netstat nfsstat nice nm nohup pagesize \
|
||||
passwd paste pr printenv printf ranlib \
|
||||
rdist renice rlogin rpcgen rpcinfo rsh ruptime rwall rwho \
|
||||
rdist ref renice rlogin rpcgen rpcinfo rsh ruptime rwall rwho \
|
||||
script sed shar showmount size soelim sort split strings \
|
||||
strip su symorder tail talk tar tee telnet tftp time \
|
||||
tip touch tput tr true tsort tty ul unexpand unifdef uniq \
|
||||
|
@ -38,6 +38,9 @@ static struct _blkbuf
|
||||
|
||||
|
||||
|
||||
void blkflush P_((REG struct _blkbuf *this));
|
||||
|
||||
|
||||
|
||||
|
||||
/* This function wipes out all buffers */
|
||||
@ -72,7 +75,7 @@ BLK *blkget(logical)
|
||||
/* see if we have that block in mem already */
|
||||
for (this = blk; this < &blk[NBUFS]; this++)
|
||||
{
|
||||
if (this->logical == logical)
|
||||
if (this->logical == (unsigned)logical)
|
||||
{
|
||||
newtoo = toonew;
|
||||
toonew = this;
|
||||
@ -162,6 +165,7 @@ void blkflush(this)
|
||||
if (write(tmpfd, this->buf.c, (unsigned)BLKSIZE) != BLKSIZE)
|
||||
{
|
||||
msg("Trouble writing to tmp file");
|
||||
deathtrap(0);
|
||||
}
|
||||
this->dirty = FALSE;
|
||||
|
||||
@ -243,7 +247,7 @@ void blkdirty(bp)
|
||||
k = blk[i].logical;
|
||||
for (j = 0; j < NBUFS; j++)
|
||||
{
|
||||
if (blk[j].logical >= k)
|
||||
if (blk[j].logical >= (unsigned)k)
|
||||
{
|
||||
blk[j].logical--;
|
||||
}
|
||||
@ -268,8 +272,21 @@ void blkdirty(bp)
|
||||
BLK *blkadd(logical)
|
||||
int logical; /* where to insert the new block */
|
||||
{
|
||||
static long chg;
|
||||
REG int i;
|
||||
|
||||
/* if we're approaching the limit, then give a warning */
|
||||
if (hdr.n[MAXBLKS - 10] && chg != changes)
|
||||
{
|
||||
chg = changes;
|
||||
msg("WARNING: The edit buffer will overflow soon.");
|
||||
}
|
||||
if (hdr.n[MAXBLKS - 2])
|
||||
{
|
||||
msg("BAD NEWS: edit buffer overflow -- GOOD NEWS: text preserved");
|
||||
deathtrap(0);
|
||||
}
|
||||
|
||||
/* adjust hdr and lnum[] */
|
||||
for (i = MAXBLKS - 1; i > logical; i--)
|
||||
{
|
||||
@ -282,7 +299,7 @@ BLK *blkadd(logical)
|
||||
/* adjust the cache */
|
||||
for (i = 0; i < NBUFS; i++)
|
||||
{
|
||||
if (blk[i].logical >= logical)
|
||||
if (blk[i].logical >= (unsigned)logical)
|
||||
{
|
||||
blk[i].logical++;
|
||||
}
|
||||
@ -343,7 +360,8 @@ void beforedo(forundo)
|
||||
lseek(tmpfd, 0L, 0);
|
||||
if (write(tmpfd, hdr.c, (unsigned)BLKSIZE) != BLKSIZE)
|
||||
{
|
||||
msg("Trouble writing header to tmp file ");
|
||||
msg("Trouble writing header to tmp file");
|
||||
deathtrap(0);
|
||||
}
|
||||
|
||||
/* copy or swap oldnlines <--> nlines, oldlnum <--> lnum */
|
||||
|
@ -17,6 +17,19 @@
|
||||
#include "vi.h"
|
||||
#include "regexp.h"
|
||||
|
||||
#ifndef NO_TAGSTACK
|
||||
/* These describe the current state of the tag related commands */
|
||||
#define MAXTAGS 15
|
||||
|
||||
struct Tag_item {
|
||||
MARK tag_mark;
|
||||
char *tag_file;
|
||||
};
|
||||
|
||||
static struct Tag_item tag_stack[MAXTAGS];
|
||||
static int curr_tag = -1;
|
||||
#endif /* !NO_TAGSTACK */
|
||||
|
||||
#ifdef DEBUG
|
||||
/* print the selected lines with info on the blocks */
|
||||
/*ARGSUSED*/
|
||||
@ -197,7 +210,7 @@ void cmd_write(frommark, tomark, cmd, bang, extra)
|
||||
}
|
||||
|
||||
/* either the file must not exist, or we must have a ! or be appending */
|
||||
if (access(extra, 0) == 0 && !bang && !append)
|
||||
if (*extra && access(extra, 0) == 0 && !bang && !append)
|
||||
{
|
||||
msg("File already exists - Use :w! to overwrite");
|
||||
return;
|
||||
@ -337,7 +350,7 @@ void cmd_global(frommark, tomark, cmd, bang, extra)
|
||||
}
|
||||
|
||||
/* make sure we got a search pattern */
|
||||
if (*extra != '/' && *extra != '?')
|
||||
if (*extra == ' ' || *extra == '\n')
|
||||
{
|
||||
msg("Usage: %c /regular expression/ command", cmd == CMD_GLOBAL ? 'g' : 'v');
|
||||
return;
|
||||
@ -395,7 +408,7 @@ void cmd_global(frommark, tomark, cmd, bang, extra)
|
||||
doingglobal = FALSE;
|
||||
|
||||
/* free the regexp */
|
||||
free(re);
|
||||
_free_(re);
|
||||
|
||||
/* Reporting...*/
|
||||
rptlines = nchanged;
|
||||
@ -421,9 +434,9 @@ void cmd_file(frommark, tomark, cmd, bang, extra)
|
||||
if (cmd == CMD_FILE)
|
||||
{
|
||||
#ifndef CRUNCH
|
||||
msg("\"%s\" %s%s%s %ld lines, line %ld [%ld%%]",
|
||||
msg("\"%s\" %s%s%s line %ld of %ld [%ld%%]",
|
||||
#else
|
||||
msg("\"%s\" %s%s %ld lines, line %ld [%ld%%]",
|
||||
msg("\"%s\" %s%s line %ld of %ld [%ld%%]",
|
||||
#endif
|
||||
*origname ? origname : "[NO FILE]",
|
||||
tstflag(file, MODIFIED) ? "[MODIFIED]" : "",
|
||||
@ -431,8 +444,8 @@ void cmd_file(frommark, tomark, cmd, bang, extra)
|
||||
tstflag(file, NOTEDITED) ?"[NOT EDITED]":"",
|
||||
#endif
|
||||
tstflag(file, READONLY) ? "[READONLY]" : "",
|
||||
nlines,
|
||||
markline(frommark),
|
||||
nlines,
|
||||
markline(frommark) * 100 / nlines);
|
||||
}
|
||||
#ifndef CRUNCH
|
||||
@ -590,8 +603,8 @@ void cmd_next(frommark, tomark, cmd, bang, extra)
|
||||
}
|
||||
}
|
||||
|
||||
/* also called from :wq -- always writes back in this case */
|
||||
|
||||
/* also called for :wq -- always writes back in this case */
|
||||
/* also called for :q -- never writes back in that case */
|
||||
/*ARGSUSED*/
|
||||
void cmd_xit(frommark, tomark, cmd, bang, extra)
|
||||
MARK frommark, tomark;
|
||||
@ -602,45 +615,40 @@ void cmd_xit(frommark, tomark, cmd, bang, extra)
|
||||
static long whenwarned; /* when the user was last warned of extra files */
|
||||
int oldflag;
|
||||
|
||||
/* if there are more files to edit, then warn user */
|
||||
if (argno >= 0 && argno + 1 < nargs && whenwarned != changes && (!bang || cmd != CMD_QUIT))
|
||||
/* Unless the command is ":q", save the file if it has been modified */
|
||||
if (cmd != CMD_QUIT
|
||||
&& (cmd == CMD_WQUIT || tstflag(file, MODIFIED))
|
||||
&& !tmpsave((char *)0, FALSE) && !bang)
|
||||
{
|
||||
msg("Could not save file -- use quit! to abort changes, or w filename");
|
||||
return;
|
||||
}
|
||||
|
||||
/* If there are more files to edit, then warn user */
|
||||
if (argno >= 0 && argno + 1 < nargs /* more args */
|
||||
&& whenwarned != changes /* user not already warned */
|
||||
&& (!bang || cmd != CMD_QUIT)) /* command not ":q!" */
|
||||
{
|
||||
msg("More files to edit -- Use \":n\" to go to next file");
|
||||
whenwarned = changes;
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd == CMD_QUIT)
|
||||
/* Discard the temp file. Note that we should already have saved the
|
||||
* the file, unless the command is ":q", so the only way that tmpabort
|
||||
* could fail would be if you did a ":q" on a modified file.
|
||||
*/
|
||||
oldflag = *o_autowrite;
|
||||
*o_autowrite = FALSE;
|
||||
if (tmpabort(bang))
|
||||
{
|
||||
oldflag = *o_autowrite;
|
||||
*o_autowrite = FALSE;
|
||||
if (tmpabort(bang))
|
||||
{
|
||||
mode = MODE_QUIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg("Use q! to abort changes, or wq to save changes");
|
||||
}
|
||||
*o_autowrite = oldflag;
|
||||
mode = MODE_QUIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* else try to save this file */
|
||||
oldflag = tstflag(file, MODIFIED);
|
||||
if (cmd == CMD_WQUIT)
|
||||
setflag(file, MODIFIED);
|
||||
if (tmpend(bang))
|
||||
{
|
||||
mode = MODE_QUIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg("Could not save file -- use quit! to abort changes, or w filename");
|
||||
}
|
||||
if (!oldflag)
|
||||
clrflag(file, MODIFIED);
|
||||
msg("Use q! to abort changes, or wq to save changes");
|
||||
}
|
||||
*o_autowrite = oldflag;
|
||||
}
|
||||
|
||||
|
||||
@ -746,8 +754,6 @@ void cmd_cd(frommark, tomark, cmd, bang, extra)
|
||||
int bang;
|
||||
char *extra;
|
||||
{
|
||||
char *getenv();
|
||||
|
||||
#ifndef CRUNCH
|
||||
/* if current file is modified, and no '!' was given, then error */
|
||||
if (tstflag(file, MODIFIED) && !bang)
|
||||
@ -759,7 +765,7 @@ void cmd_cd(frommark, tomark, cmd, bang, extra)
|
||||
/* default directory name is $HOME */
|
||||
if (!*extra)
|
||||
{
|
||||
extra = getenv("HOME");
|
||||
extra = gethome((char *)0);
|
||||
if (!extra)
|
||||
{
|
||||
msg("environment variable $HOME not set");
|
||||
@ -928,7 +934,14 @@ void cmd_tag(frommark, tomark, cmd, bang, extra)
|
||||
#ifdef INTERNAL_TAGS
|
||||
char *cmp; /* char of tag name we're comparing, or NULL */
|
||||
char *end; /* marks the end of chars in tmpblk.c */
|
||||
char file[128]; /* name of file containing tag */
|
||||
int found; /* whether the tag has been found */
|
||||
int file_exists; /* whether any tag file exists */
|
||||
char *s, *t;
|
||||
#else
|
||||
# ifndef NO_TAGSTACK
|
||||
char *s;
|
||||
# endif
|
||||
int i;
|
||||
#endif
|
||||
#ifndef NO_MAGIC
|
||||
@ -971,66 +984,96 @@ void cmd_tag(frommark, tomark, cmd, bang, extra)
|
||||
*scan = '\0';
|
||||
|
||||
/* close the pipe. abort if error */
|
||||
if (rpclose(fd) != 0 || scan < tmpblk.c + 3)
|
||||
if (rpclose(fd) != 0)
|
||||
{
|
||||
msg("Trouble running \"ref\" -- Can't do tag lookup");
|
||||
return;
|
||||
}
|
||||
else if (scan < tmpblk.c + 3)
|
||||
{
|
||||
msg("tag \"%s\" not found", extra);
|
||||
return;
|
||||
}
|
||||
|
||||
#else /* use internal code to look up the tag */
|
||||
/* open the tags file */
|
||||
fd = open(TAGS, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
found = 0;
|
||||
file_exists = 0;
|
||||
s = o_tags;
|
||||
while (!found && *s != 0) {
|
||||
while (isspace(*s)) s++;
|
||||
for(t = file; s && *s && !isspace(*s); s++)
|
||||
*t++ = *s;
|
||||
*t = '\0';
|
||||
|
||||
/* open the next tags file */
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0)
|
||||
continue;
|
||||
else
|
||||
file_exists = 1;
|
||||
|
||||
/* Hmmm... this would have been a lot easier with <stdio.h> */
|
||||
|
||||
/* find the line with our tag in it */
|
||||
for(scan = end = tmpblk.c, cmp = extra; ; scan++)
|
||||
{
|
||||
/* read a block, if necessary */
|
||||
if (scan >= end)
|
||||
{
|
||||
end = tmpblk.c + tread(fd, tmpblk.c, BLKSIZE);
|
||||
scan = tmpblk.c;
|
||||
if (scan >= end)
|
||||
{
|
||||
close(fd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we're comparing, compare... */
|
||||
if (cmp)
|
||||
{
|
||||
/* matched??? wow! */
|
||||
if (!*cmp && *scan == '\t')
|
||||
{
|
||||
if ((s = strrchr(file, '/')) != 0 ||
|
||||
(s = strrchr(file, '\\')) != 0)
|
||||
++s;
|
||||
else
|
||||
s = file;
|
||||
*s = '\0';
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
if (*cmp++ != *scan)
|
||||
{
|
||||
/* failed! skip to newline */
|
||||
cmp = (char *)0;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we're skipping to newline, do it fast! */
|
||||
if (!cmp)
|
||||
{
|
||||
while (scan < end && *scan != '\n')
|
||||
{
|
||||
scan++;
|
||||
}
|
||||
if (scan < end)
|
||||
{
|
||||
cmp = extra;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!file_exists) {
|
||||
msg("No tags file");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Hmmm... this would have been a lot easier with <stdio.h> */
|
||||
|
||||
/* find the line with our tag in it */
|
||||
for(scan = end = tmpblk.c, cmp = extra; ; scan++)
|
||||
{
|
||||
/* read a block, if necessary */
|
||||
if (scan >= end)
|
||||
{
|
||||
end = tmpblk.c + tread(fd, tmpblk.c, BLKSIZE);
|
||||
scan = tmpblk.c;
|
||||
if (scan >= end)
|
||||
{
|
||||
msg("tag \"%s\" not found", extra);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we're comparing, compare... */
|
||||
if (cmp)
|
||||
{
|
||||
/* matched??? wow! */
|
||||
if (!*cmp && *scan == '\t')
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (*cmp++ != *scan)
|
||||
{
|
||||
/* failed! skip to newline */
|
||||
cmp = (char *)0;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we're skipping to newline, do it fast! */
|
||||
if (!cmp)
|
||||
{
|
||||
while (scan < end && *scan != '\n')
|
||||
{
|
||||
scan++;
|
||||
}
|
||||
if (scan < end)
|
||||
{
|
||||
cmp = extra;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
msg("tag \"%s\" not found", extra);
|
||||
return;
|
||||
}
|
||||
|
||||
/* found it! get the rest of the line into memory */
|
||||
@ -1062,7 +1105,32 @@ void cmd_tag(frommark, tomark, cmd, bang, extra)
|
||||
return;
|
||||
}
|
||||
tmpstart(tmpblk.c);
|
||||
#ifdef NO_TAGSTACK
|
||||
}
|
||||
#else /* tagstack enabled */
|
||||
s = prevorig;
|
||||
}
|
||||
else
|
||||
s = origname;
|
||||
|
||||
if (frommark != MARK_UNSET && *s && *o_tagstack)
|
||||
{
|
||||
curr_tag++;
|
||||
if (curr_tag >= MAXTAGS)
|
||||
{
|
||||
/* discard the oldest tag position */
|
||||
free(tag_stack[0].tag_file);
|
||||
for (curr_tag = 0; curr_tag < MAXTAGS - 1; curr_tag++)
|
||||
{
|
||||
tag_stack[curr_tag] = tag_stack[curr_tag + 1];
|
||||
}
|
||||
/* at this point, curr_tag = MAXTAGS-1 */
|
||||
}
|
||||
tag_stack[curr_tag].tag_file = (char *) malloc(strlen(s) + 1);
|
||||
strcpy(tag_stack[curr_tag].tag_file, s);
|
||||
tag_stack[curr_tag].tag_mark = frommark;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* move to the desired line (or to line 1 if that fails) */
|
||||
#ifndef NO_MAGIC
|
||||
@ -1082,6 +1150,44 @@ void cmd_tag(frommark, tomark, cmd, bang, extra)
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_TAGSTACK
|
||||
/*ARGSUSED*/
|
||||
void cmd_pop(frommark, tomark, cmd, bang, extra)
|
||||
MARK frommark, tomark;
|
||||
CMD cmd;
|
||||
int bang;
|
||||
char *extra;
|
||||
{
|
||||
char buf[8];
|
||||
|
||||
if (!*o_tagstack)
|
||||
{
|
||||
msg("Tagstack not enabled");
|
||||
return;
|
||||
}
|
||||
|
||||
if (curr_tag < 0)
|
||||
msg("Tagstack empty");
|
||||
else
|
||||
{
|
||||
if (strcmp(origname, tag_stack[curr_tag].tag_file) != 0)
|
||||
{
|
||||
if (!tmpabort(bang))
|
||||
{
|
||||
msg("Use :pop! to abort changes, or :w to save changes");
|
||||
return;
|
||||
}
|
||||
tmpstart(tag_stack[curr_tag].tag_file);
|
||||
}
|
||||
cursor = tag_stack[curr_tag].tag_mark;
|
||||
if (cursor < MARK_FIRST || cursor > MARK_LAST + BLKSIZE)
|
||||
{
|
||||
cursor = MARK_FIRST;
|
||||
}
|
||||
free(tag_stack[curr_tag--].tag_file);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@ -1247,7 +1353,7 @@ static char *parse_errmsg(text)
|
||||
}
|
||||
|
||||
/* if the number is part of a larger word, then ignore this line */
|
||||
if (*text && isalpha(text[-1]))
|
||||
if (*text && (isalpha(text[-1]) || text[-1] == '_'))
|
||||
{
|
||||
return (char *)0;
|
||||
}
|
||||
@ -1451,15 +1557,38 @@ void cmd_make(frommark, tomark, cmd, bang, extra)
|
||||
errfd = -3;
|
||||
}
|
||||
|
||||
#if MINT
|
||||
/* I guess MiNT can't depend on the shell for redirection? */
|
||||
close(creat(ERRLIST, 0666));
|
||||
if ((fd = open(ERRLIST, O_RDWR)) == -1)
|
||||
{
|
||||
unlink(ERRLIST);
|
||||
return;
|
||||
}
|
||||
suspend_curses();
|
||||
old2 = dup(2);
|
||||
dup2(fd, 2);
|
||||
system(buf.c);
|
||||
dup2(old2, 2);
|
||||
close(old2);
|
||||
close(fd);
|
||||
#else
|
||||
/* run the command, with curses temporarily disabled */
|
||||
suspend_curses();
|
||||
system(buf.c);
|
||||
#endif
|
||||
resume_curses(mode == MODE_EX);
|
||||
if (mode == MODE_COLON)
|
||||
mode = MODE_VI;
|
||||
/* ':' hit instead of CR, so let him escape... -nox */
|
||||
return;
|
||||
|
||||
/* run the "errlist" command */
|
||||
cmd_errlist(MARK_UNSET, MARK_UNSET, cmd, bang, ERRLIST);
|
||||
|
||||
/* avoid spurious `Hit <RETURN>' after 1st error message -nox */
|
||||
/* (which happened when cmd_errlist didn't have to change files...) */
|
||||
if (mode == MODE_VI)
|
||||
refresh();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1738,9 +1867,9 @@ void cmd_suspend(frommark, tomark, cmd, bang, extra)
|
||||
int bang;
|
||||
char *extra;
|
||||
{
|
||||
void (*func)(); /* stores the previous setting of SIGTSTP */
|
||||
SIGTYPE (*func)(); /* stores the previous setting of SIGTSTP */
|
||||
|
||||
#if !defined(__386BSD__) && defined(ANY_UNIX)
|
||||
#if ANY_UNIX
|
||||
/* the Bourne shell can't handle ^Z */
|
||||
if (!strcmp(o_shell, "/bin/sh"))
|
||||
{
|
||||
@ -1749,11 +1878,6 @@ void cmd_suspend(frommark, tomark, cmd, bang, extra)
|
||||
}
|
||||
#endif
|
||||
|
||||
func = signal(SIGTSTP, SIG_DFL);
|
||||
if ( func == SIG_IGN ) {
|
||||
msg("SIGTSTP is being ignored, you may not suspend the editor", func);
|
||||
return;
|
||||
}
|
||||
move(LINES - 1, 0);
|
||||
if (tstflag(file, MODIFIED))
|
||||
{
|
||||
@ -1764,7 +1888,7 @@ void cmd_suspend(frommark, tomark, cmd, bang, extra)
|
||||
}
|
||||
refresh();
|
||||
suspend_curses();
|
||||
/* was here func = signal(SIGTSTP, SIG_DFL); /* races ??? */
|
||||
func = signal(SIGTSTP, SIG_DFL);
|
||||
kill (0, SIGTSTP);
|
||||
|
||||
/* the process stops and resumes here */
|
||||
|
@ -76,7 +76,7 @@ void cmd_substitute(frommark, tomark, cmd, bang, extra)
|
||||
else /* CMD_SUBSTITUTE */
|
||||
{
|
||||
/* make sure we got a search pattern */
|
||||
if (*extra != '/' && *extra != '?')
|
||||
if (*extra == ' ' || *extra == '\n')
|
||||
{
|
||||
msg("Usage: s/regular expression/new text/");
|
||||
return;
|
||||
@ -253,7 +253,7 @@ Continue:
|
||||
}
|
||||
|
||||
/* free the regexp */
|
||||
free(re);
|
||||
_free_(re);
|
||||
|
||||
/* if done from within a ":g" command, then finish silently */
|
||||
if (doingglobal)
|
||||
@ -447,7 +447,7 @@ void cmd_join(frommark, tomark, cmd, bang, extra)
|
||||
}
|
||||
|
||||
/* see if the line will fit */
|
||||
if (strlen(scan) + len + 3 > BLKSIZE)
|
||||
if (strlen(scan) + len + 3 > (unsigned)BLKSIZE)
|
||||
{
|
||||
msg("Can't join -- the resulting line would be too long");
|
||||
return;
|
||||
@ -461,10 +461,14 @@ void cmd_join(frommark, tomark, cmd, bang, extra)
|
||||
if (tmpblk.c[len - 1] == '.'
|
||||
|| tmpblk.c[len - 1] == '?'
|
||||
|| tmpblk.c[len - 1] == '!')
|
||||
{
|
||||
tmpblk.c[len++] = ' ';
|
||||
tmpblk.c[len++] = ' ';
|
||||
}
|
||||
else if (tmpblk.c[len - 1] != ' ')
|
||||
{
|
||||
tmpblk.c[len++] = ' ';
|
||||
}
|
||||
tmpblk.c[len++] = ' ';
|
||||
}
|
||||
}
|
||||
strcpy(tmpblk.c + len, scan);
|
||||
@ -769,7 +773,7 @@ void cmd_print(frommark, tomark, cmd, bang, extra)
|
||||
col++;
|
||||
} while (col % *o_tabstop != 0);
|
||||
}
|
||||
else if (*scan > 0 && *scan < ' ' || *scan == '\177')
|
||||
else if (*scan >= 1 && *scan < ' ' || *scan == '\177')
|
||||
{
|
||||
qaddch('^');
|
||||
qaddch(*scan ^ 0x40);
|
||||
@ -801,6 +805,9 @@ void cmd_print(frommark, tomark, cmd, bang, extra)
|
||||
addch('\n');
|
||||
exrefresh();
|
||||
}
|
||||
|
||||
/* leave the cursor on the last line printed */
|
||||
cursor = tomark;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,28 +1,225 @@
|
||||
/*
|
||||
* vi configuration file
|
||||
* We try to automatically configure to various compilers and operating
|
||||
* systems. Extend the autoconf section as needed.
|
||||
*/
|
||||
|
||||
# define BSD 1
|
||||
#ifndef _CONFIG_H
|
||||
# define _CONFIG_H
|
||||
|
||||
/*************************** autoconf section ************************/
|
||||
|
||||
/* Commodore-Amiga */
|
||||
#ifdef amiga
|
||||
# define AMIGA 1
|
||||
# define COMPILED_BY "Manx Aztec C 5.2b"
|
||||
# define TINYSTACK 1
|
||||
#endif
|
||||
|
||||
/* standard unix V (?) */
|
||||
#ifdef M_SYSV
|
||||
# define UNIXV 1
|
||||
# ifdef M_XENIX
|
||||
# ifndef M_I386
|
||||
# define TINYSTACK 1
|
||||
# endif
|
||||
# endif
|
||||
# undef COHERENT
|
||||
#endif
|
||||
|
||||
/* xelos system, University of Ulm */
|
||||
#ifdef xelos
|
||||
# define UNIXV 1
|
||||
#endif
|
||||
|
||||
/* BSD UNIX? */
|
||||
#ifdef bsd
|
||||
# define BSD 1
|
||||
#else
|
||||
# ifdef sun
|
||||
# ifndef M_SYSV
|
||||
# define BSD 1
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Microsoft C: sorry, Watcom does the same thing */
|
||||
#ifdef M_I86
|
||||
# ifndef M_SYSV
|
||||
# define MSDOS 1
|
||||
# ifdef IBMC2
|
||||
# define COMPILED_BY "IBM C/2 1.00"
|
||||
# else
|
||||
# define MICROSOFT 1
|
||||
# define COMPILED_BY "Microsoft C 5.10"
|
||||
# endif
|
||||
# define TINYSTACK 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Borland's Turbo C */
|
||||
#ifdef __TURBOC__
|
||||
# define MSDOS 1
|
||||
# define TURBOC 1
|
||||
# ifdef __BORLANDC__
|
||||
# define COMPILED_BY "Borland C 2.00"
|
||||
# else
|
||||
# define COMPILED_BY (__TURBOC__ >= 661 ? "Turbo C++ 1.00" : "Turbo C 2.00")
|
||||
# endif
|
||||
# define TINYSTACK 1
|
||||
#endif
|
||||
|
||||
/* Tos Mark-Williams */
|
||||
#ifdef M68000
|
||||
# define TOS 1
|
||||
# define COMPILED_BY "Mark Williams C"
|
||||
# define TINYSTACK 1
|
||||
#endif
|
||||
|
||||
/* Tos GNU-C */
|
||||
#ifdef __atarist__
|
||||
# ifdef __gem__
|
||||
# define TOS 1
|
||||
# define COMPILED_BY "GNU-C " __VERSION__
|
||||
# define TINYSTACK 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* OS9/68000 */
|
||||
#ifdef OSK
|
||||
# define COMPILED_BY "Microware C V2.3 Edition 40"
|
||||
# define TINYSTACK 1
|
||||
#endif
|
||||
|
||||
/* DEC Rainbow, running MS-DOS (handled by earlier MS-DOS tests) */
|
||||
/* (would need -DRAINBOW in CFLAGS to compile a Rainbow-compatible .EXE) */
|
||||
|
||||
#ifdef VMS
|
||||
# define COMPILED_BY "VAX/VMS VAXC compiler"
|
||||
# undef VMS
|
||||
# define VMS 1
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef COHERENT
|
||||
# ifdef _I386
|
||||
# define COH_386 1
|
||||
# define COH_286 0
|
||||
# else
|
||||
# define COH_386 0
|
||||
# define COH_286 1
|
||||
# endif
|
||||
# undef COHERENT
|
||||
# define COHERENT 1
|
||||
#endif
|
||||
|
||||
/*************************** end of autoconf section ************************/
|
||||
|
||||
/* All undefined symbols are defined to zero here, to allow for older */
|
||||
/* compilers which dont understand #if defined() or #if UNDEFINED_SYMBOL */
|
||||
|
||||
# define UNIXV 0 /* UNIX - AT&T SYSV */
|
||||
# define UNIX7 0 /* UNIX - version 7 */
|
||||
# define MSDOS 0 /* PC */
|
||||
# define TOS 0 /* Atari ST */
|
||||
# define AMIGA 0 /* Commodore Amiga */
|
||||
# define OSK 0 /* OS-9 / 68k */
|
||||
# define COHERENT 0 /* Coherent */
|
||||
# define MINIX 0
|
||||
/*************************** operating systems *****************************/
|
||||
|
||||
#ifndef BSD
|
||||
# define BSD 0 /* UNIX - Berkeley 4.x */
|
||||
#endif
|
||||
|
||||
#ifndef UNIXV
|
||||
# define UNIXV 0 /* UNIX - AT&T SYSV */
|
||||
#endif
|
||||
|
||||
#ifndef UNIX7
|
||||
# define UNIX7 0 /* UNIX - version 7 */
|
||||
#endif
|
||||
|
||||
#ifndef MSDOS
|
||||
# define MSDOS 0 /* PC */
|
||||
#endif
|
||||
|
||||
#ifndef TOS
|
||||
# define TOS 0 /* Atari ST */
|
||||
#endif
|
||||
|
||||
#ifndef AMIGA
|
||||
# define AMIGA 0 /* Commodore Amiga */
|
||||
#endif
|
||||
|
||||
#ifndef OSK
|
||||
# define OSK 0 /* OS-9 / 68k */
|
||||
#endif
|
||||
|
||||
#ifndef COHERENT
|
||||
# define COHERENT 0 /* Coherent */
|
||||
#endif
|
||||
|
||||
#ifndef RAINBOW /* DEC Rainbow support, under MS-DOS */
|
||||
# define RAINBOW 0
|
||||
#endif
|
||||
|
||||
#ifndef VMS
|
||||
# define VMS 0 /* VAX/VMS */
|
||||
#endif
|
||||
|
||||
/* Minix has no predefines */
|
||||
#if !BSD && !UNIXV && !UNIX7 && !MSDOS && !TOS && !AMIGA && !OSK && !COHERENT && !VMS
|
||||
# define MINIX 1
|
||||
#else
|
||||
# define MINIX 0
|
||||
#endif
|
||||
|
||||
/* generic combination of Unices */
|
||||
#if UNIXV || UNIX7 || BSD || MINIX || COHERENT
|
||||
# define ANY_UNIX 1
|
||||
#else
|
||||
# define ANY_UNIX 0
|
||||
#endif
|
||||
|
||||
#ifndef TINYSTACK
|
||||
# define TINYSTACK 0
|
||||
#endif
|
||||
|
||||
/*************************** compilers **************************************/
|
||||
|
||||
#ifndef AZTEC_C
|
||||
# define AZTEC_C 0
|
||||
#endif
|
||||
|
||||
#ifndef MICROSOFT
|
||||
# define MICROSOFT 0
|
||||
#endif
|
||||
|
||||
#ifndef TURBOC
|
||||
# define TURBOC 0
|
||||
#endif
|
||||
|
||||
/* Should we use "new style" ANSI C prototypes? */
|
||||
#ifdef __STDC__
|
||||
# define NEWSTYLE 1
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
# define NEWSTYLE 1
|
||||
#endif
|
||||
#ifndef NEWSTYLE
|
||||
# define NEWSTYLE 0
|
||||
#endif
|
||||
|
||||
#if NEWSTYLE
|
||||
# define P_(s) s
|
||||
#else
|
||||
# define P_(s) ()
|
||||
#endif
|
||||
|
||||
/******************************* Credit ************************************/
|
||||
|
||||
#if MSDOS
|
||||
# define CREDIT "Ported to MS-DOS by Guntram Blohm & Martin Patzel"
|
||||
# if RAINBOW
|
||||
# define CREDIT2 "Rainbow support added by Willett Kempton"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if AMIGA
|
||||
# define CREDIT "Ported to AmigaDOS 2.04 by Mike Rieser & Dale Rahn"
|
||||
#endif
|
||||
|
||||
#if TOS
|
||||
@ -37,39 +234,130 @@
|
||||
# define CREDIT "Ported to Coherent by Esa Ahola"
|
||||
#endif
|
||||
|
||||
#if VMS
|
||||
# define CREDIT "Ported to VAX/VMS by John Campbell"
|
||||
#endif
|
||||
/*************************** functions depending on OS *********************/
|
||||
|
||||
extern char *strchr();
|
||||
|
||||
#define tread(fd,buf,n) read(fd,buf,(unsigned)(n))
|
||||
#define twrite(fd,buf,n) write(fd,buf,(unsigned)(n))
|
||||
|
||||
#define ttywrite(buf, len) write(1, buf, (unsigned)(len)) /* raw write */
|
||||
|
||||
extern void *malloc();
|
||||
|
||||
/* Most compilers could benefit from using the "register" storage class */
|
||||
#if 1
|
||||
# define REG register
|
||||
/* There are two terminal-related functions that we need: ttyread() and
|
||||
* ttywrite(). The ttyread() function implements read-with-timeout and is
|
||||
* a true function on all systems. The ttywrite() function is almost always
|
||||
* just a macro...
|
||||
*/
|
||||
#if !TOS && !AMIGA
|
||||
# define ttywrite(buf, len) write(1, buf, (unsigned)(len)) /* raw write */
|
||||
#endif
|
||||
|
||||
typedef unsigned char uchar;
|
||||
#define UCHAR(s) ((unsigned char) (s))
|
||||
/* The strchr() function is an official standard now, so everybody has it
|
||||
* except Unix version 7 (which is old) and BSD Unix (which is academic).
|
||||
* Those guys use something called index() to do the same thing.
|
||||
*/
|
||||
#if BSD || UNIX7 || OSK
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
#endif
|
||||
#if !NEWSTYLE
|
||||
extern char *strchr();
|
||||
#endif
|
||||
|
||||
/* BSD uses bcopy() instead of memcpy() */
|
||||
#if BSD
|
||||
# define memcpy(dest, src, siz) bcopy(src, dest, siz)
|
||||
#endif
|
||||
|
||||
/* BSD uses getwd() instead of getcwd(). The arguments are a little different,
|
||||
* but we'll ignore that and hope for the best; adding arguments to the macro
|
||||
* would mess up an "extern" declaration of the function.
|
||||
*
|
||||
* Also, the Coherent-286 uses getwd(), but Coherent-386 uses getcwd()
|
||||
*/
|
||||
#if BSD
|
||||
#ifndef __386BSD__
|
||||
# define getcwd getwd
|
||||
#endif
|
||||
#endif
|
||||
#if COH_286
|
||||
# define getcwd getwd
|
||||
#endif
|
||||
extern char *getcwd();
|
||||
|
||||
/* text versa binary mode for read/write */
|
||||
#if !TOS
|
||||
#define tread(fd,buf,n) read(fd,buf,(unsigned)(n))
|
||||
#define twrite(fd,buf,n) write(fd,buf,(unsigned)(n))
|
||||
#endif
|
||||
|
||||
/**************************** Compiler quirks *********************************/
|
||||
|
||||
/* the UNIX version 7 and (some) TOS compilers, don't allow "void" */
|
||||
#if UNIX7 || TOS
|
||||
# define void int
|
||||
#endif
|
||||
|
||||
/* as far as I know, all compilers except version 7 support unsigned char */
|
||||
/* NEWFLASH: the Minix-ST compiler has subtle problems with unsigned char */
|
||||
#if UNIX7 || MINIX
|
||||
# define UCHAR(c) ((c) & 0xff)
|
||||
# define uchar char
|
||||
#else
|
||||
# define UCHAR(c) ((unsigned char)(c))
|
||||
# define uchar unsigned char
|
||||
#endif
|
||||
|
||||
/* Some compilers prefer to have malloc declared as returning a (void *) */
|
||||
/* ANSI, on the other hand, needs the arguments to free() to be cast */
|
||||
#ifndef __STDC__
|
||||
# if BSD || AMIGA || MINIX
|
||||
extern void *malloc();
|
||||
# define _free_(ptr) free((void *)ptr)
|
||||
# else
|
||||
extern char *malloc();
|
||||
# define _free_(ptr) free((char *)ptr)
|
||||
# endif
|
||||
#else
|
||||
# define _free_(ptr) free((void *)ptr)
|
||||
#endif /* __STDC__ */
|
||||
|
||||
/* everybody but Amiga wants lseek declared here */
|
||||
#if !AMIGA
|
||||
extern long lseek();
|
||||
#endif
|
||||
|
||||
/* ANSI C has getenv() declared in stdlib.h, which we've already included.
|
||||
* Other compilers will need it declared here, though.
|
||||
*/
|
||||
#ifndef __STDC__
|
||||
extern char *getenv();
|
||||
#endif
|
||||
|
||||
/* Signal handler functions used to return an int value, which was ignored.
|
||||
* On newer systems, signal handlers are void functions. Here, we try to
|
||||
* guess the proper return type for this system.
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
# define SIGTYPE void
|
||||
#else
|
||||
# if MSDOS
|
||||
# define SIGTYPE void
|
||||
# else
|
||||
# if UNIXV
|
||||
# define SIGTYPE void /* Note: This is wrong for SCO Xenix. */
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#ifndef SIGTYPE
|
||||
# define SIGTYPE int
|
||||
#endif
|
||||
|
||||
/******************* Names of files and environment vars **********************/
|
||||
|
||||
#define TMPDIR "/var/tmp"
|
||||
#define TMPNAME "%s/elvis%04x%03x" /* temp file */
|
||||
#define CUTNAME "%s/elvis_%04x%03x" /* cut buffer's temp file */
|
||||
# ifndef EXRC
|
||||
# define EXRC ".exrc" /* init file in current directory */
|
||||
# endif
|
||||
# define SCRATCHOUT "%s/soXXXXXX" /* temp file used as input to filter */
|
||||
# ifndef EXINIT
|
||||
# define EXINIT "EXINIT"
|
||||
# endif
|
||||
# ifndef SHELL
|
||||
# define SHELL "/bin/sh" /* default shell */
|
||||
#if ANY_UNIX
|
||||
# ifndef TMPDIR
|
||||
# if MINIX
|
||||
# define TMPDIR "/usr/tmp" /* Keep elvis' temp files off RAM disk! */
|
||||
# else
|
||||
# define TMPDIR "/var/tmp" /* directory where temp files live */
|
||||
# endif
|
||||
# endif
|
||||
# ifndef PRSVDIR
|
||||
# define PRSVDIR "/var/preserve" /* directory where preserved file live */
|
||||
@ -77,9 +365,200 @@ typedef unsigned char uchar;
|
||||
# ifndef PRSVINDEX
|
||||
# define PRSVINDEX "/var/preserve/Index" /* index of files in PRSVDIR */
|
||||
# endif
|
||||
# ifndef EXRC
|
||||
# define EXRC ".exrc" /* init file in current directory */
|
||||
# endif
|
||||
# define SCRATCHOUT "%s/soXXXXXX" /* temp file used as input to filter */
|
||||
# ifndef SHELL
|
||||
# define SHELL "/bin/sh" /* default shell */
|
||||
# endif
|
||||
# if COHERENT
|
||||
# ifndef REDIRECT
|
||||
# define REDIRECT ">" /* Coherent CC writes errors to stdout */
|
||||
# endif
|
||||
# endif
|
||||
# define gethome(x) getenv("HOME")
|
||||
#endif
|
||||
|
||||
#if AMIGA /* Specify AMIGA environment */
|
||||
# ifndef CC_COMMAND
|
||||
# define CC_COMMAND "cc" /* generic C compiler */
|
||||
# endif
|
||||
# ifndef COLON
|
||||
# define COLON ':' /* Amiga files can also end in `:' */
|
||||
# endif
|
||||
# ifndef SYSEXRC
|
||||
# define SYSEXRC "S:" EXRC /* name of ".exrc" file in system dir */
|
||||
# endif
|
||||
# ifndef MAXRCLEN
|
||||
# define MAXRCLEN 2048 /* max size of a .exrc file */
|
||||
# endif
|
||||
# ifndef NBUFS
|
||||
# define NBUFS 10 /* must be at least 3 -- more is better */
|
||||
# endif
|
||||
# ifndef NEEDSYNC
|
||||
# define NEEDSYNC TRUE /* assume ":se sync" by default */
|
||||
# endif
|
||||
# ifndef PRSVDIR
|
||||
# define PRSVDIR "Elvis:" /* directory where preserved file live */
|
||||
# endif
|
||||
# ifndef PRSVINDEX
|
||||
# define PRSVINDEX "Elvis:Index" /* index of files in PRSVDIR */
|
||||
# endif
|
||||
# ifndef REDIRECT
|
||||
# define REDIRECT ">" /* Amiga writes errors to stdout */
|
||||
# endif
|
||||
# ifndef SCRATCHIN
|
||||
# define SCRATCHIN "%sSIXXXXXX"
|
||||
# endif
|
||||
# ifndef SCRATCHOUT
|
||||
# define SCRATCHOUT "%sSOXXXXXX"
|
||||
# endif
|
||||
# ifndef SHELL
|
||||
# define SHELL "newshell" /* default shell */
|
||||
# endif
|
||||
# ifndef TERMTYPE
|
||||
# define TERMTYPE "amiga" /* default termtype */
|
||||
# endif
|
||||
# ifndef TMPDIR /* for AMIGA should end in `:' or `/' */
|
||||
# define TMPDIR "T:" /* directory where temp files live */
|
||||
# endif
|
||||
# ifndef TMPNAME
|
||||
# define TMPNAME "%selv_%x.%x" /* format of names for temp files */
|
||||
# endif
|
||||
# define gethome(x) getenv("HOME")
|
||||
#endif
|
||||
|
||||
#if MSDOS || TOS
|
||||
/* do not change TMPNAME and SCRATCH*: they MUST begin with '%s\\'! */
|
||||
# ifndef TMPDIR
|
||||
# define TMPDIR "C:\\tmp" /* directory where temp files live */
|
||||
# endif
|
||||
# ifndef PRSVDIR
|
||||
# define PRSVDIR "C:\\preserve" /* directory where preserved file live */
|
||||
# endif
|
||||
# ifndef PRSVINDEX
|
||||
# define PRSVINDEX "C:\\preserve\\Index" /* index of files in PRSVDIR */
|
||||
# endif
|
||||
# define TMPNAME "%s\\elv_%x.%x" /* temp file */
|
||||
# if MSDOS
|
||||
# if MICROSOFT
|
||||
# define CC_COMMAND "cl -c" /* C compiler */
|
||||
# else
|
||||
# if __BORLANDC__ /* Borland C */
|
||||
# define CC_COMMAND "bcc" /* C compiler */
|
||||
# else
|
||||
# if TURBOC /* Turbo C */
|
||||
# define CC_COMMAND "tcc" /* C compiler */
|
||||
# endif /* TURBOC */
|
||||
# endif /* BORLANDC */
|
||||
# endif /* MICROSOFT */
|
||||
# endif /* MSDOS */
|
||||
# define SCRATCHIN "%s\\siXXXXXX" /* DOS ONLY - output of filter program */
|
||||
# define SCRATCHOUT "%s\\soXXXXXX" /* temp file used as input to filter */
|
||||
# define SLASH '\\'
|
||||
# ifndef SHELL
|
||||
# if TOS
|
||||
# define SHELL "shell.ttp" /* default shell */
|
||||
# else
|
||||
# define SHELL "command.com" /* default shell */
|
||||
# endif
|
||||
# endif
|
||||
# define NEEDSYNC TRUE /* assume ":se sync" by default */
|
||||
# if TOS && __GNUC__ /* probably on other systems, too */
|
||||
# define REDIRECT "2>" /* GNUC reports on 2, others on 1 */
|
||||
# define CC_COMMAND "gcc -c"
|
||||
# else
|
||||
# define REDIRECT ">" /* shell's redirection of stderr */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if VMS
|
||||
/* do not change TMPNAME, and SCRATCH*: they MUST begin with '%s\\'! */
|
||||
# ifndef TMPDIR
|
||||
# define TMPDIR "sys$scratch:" /* directory where temp files live */
|
||||
# endif
|
||||
# define TMPNAME "%selv_%x.%x;1" /* temp file */
|
||||
# define SCRATCHIN "%ssiXXXXXX" /* DOS ONLY - output of filter program */
|
||||
# define SCRATCHOUT "%ssoXXXXXX" /* temp file used as input to filter */
|
||||
# define SLASH '\:' /* Worry point... jdc */
|
||||
# ifndef SHELL
|
||||
# define SHELL "" /* default shell */
|
||||
# endif
|
||||
# define REDIRECT ">" /* shell's redirection of stderr */
|
||||
# define tread(fd,buf,n) vms_read(fd,buf,(unsigned)(n))
|
||||
# define close vms_close
|
||||
# define lseek vms_lseek
|
||||
# define unlink vms_delete
|
||||
# define delete __delete /* local routine conflicts w/VMS rtl routine. */
|
||||
# define rpipe vms_rpipe
|
||||
# define rpclose vms_rpclose
|
||||
# define ttyread vms_ttyread
|
||||
# define gethome(x) getenv("HOME")
|
||||
/* There is no sync() on vms */
|
||||
# define sync()
|
||||
/* jdc -- seems VMS external symbols are case insensitive */
|
||||
# define m_fWord m_fw_ord
|
||||
# define m_bWord m_bw_ord
|
||||
# define m_eWord m_ew_ord
|
||||
# define m_Nsrch m_n_srch
|
||||
# define m_Fch m_f_ch
|
||||
# define m_Tch m_t_ch
|
||||
# define v_Xchar v_x_char
|
||||
/* jdc -- also, braindead vms curses always found by linker. */
|
||||
# define LINES elvis_LINES
|
||||
# define COLS elvis_COLS
|
||||
# define curscr elvis_curscr
|
||||
# define stdscr elvis_stdscr
|
||||
# define initscr elvis_initscr
|
||||
# define endwin elvis_endwin
|
||||
# define wrefresh elvis_wrefresh
|
||||
#endif
|
||||
|
||||
#if OSK
|
||||
# ifndef TMPDIR
|
||||
# define TMPDIR "/dd/tmp" /* directory where temp files live */
|
||||
# endif
|
||||
# ifndef PRSVDIR
|
||||
# define PRSVDIR "/dd/usr/preserve" /* directory where preserved file live */
|
||||
# endif
|
||||
# ifndef PRSVINDEX
|
||||
# define PRSVINDEX "/dd/usr/preserve/Index" /* index of files in PRSVDIR */
|
||||
# endif
|
||||
# ifndef CC_COMMAND
|
||||
# define CC_COMMAND "cc -r" /* name of the compiler */
|
||||
# endif
|
||||
# ifndef EXRC
|
||||
# define EXRC ".exrc" /* init file in current directory */
|
||||
# endif
|
||||
# define SCRATCHOUT "%s/soXXXXXX" /* temp file used as input to filter */
|
||||
# ifndef SHELL
|
||||
# define SHELL "shell" /* default shell */
|
||||
# endif
|
||||
# define FILEPERMS (S_IREAD|S_IWRITE) /* file permissions used for creat() */
|
||||
# define REDIRECT ">>-" /* shell's redirection of stderr */
|
||||
# define sync() /* OS9 doesn't need a sync() */
|
||||
# define gethome(x) getenv("HOME")
|
||||
#endif
|
||||
|
||||
#ifndef TAGS
|
||||
# define TAGS "tags" /* tags file */
|
||||
# define TAGS "tags" /* name of the tags file */
|
||||
#endif
|
||||
|
||||
#ifndef TMPNAME
|
||||
# define TMPNAME "%s/elv_%x.%x" /* format of names for temp files */
|
||||
#endif
|
||||
|
||||
#ifndef EXINIT
|
||||
# define EXINIT "EXINIT" /* name of EXINIT environment variable */
|
||||
#endif
|
||||
|
||||
#ifndef EXRC
|
||||
# define EXRC "elvis.rc" /* name of ".exrc" file in current dir */
|
||||
#endif
|
||||
|
||||
#ifndef HMEXRC
|
||||
# define HMEXRC EXRC /* name of ".exrc" file in home dir */
|
||||
#endif
|
||||
|
||||
#ifndef KEYWORDPRG
|
||||
@ -92,7 +571,7 @@ typedef unsigned char uchar;
|
||||
#endif
|
||||
|
||||
#ifndef ERRLIST
|
||||
# define ERRLIST "errlist"
|
||||
# define ERRLIST "errs"
|
||||
#endif
|
||||
|
||||
#ifndef SLASH
|
||||
@ -104,7 +583,7 @@ typedef unsigned char uchar;
|
||||
#endif
|
||||
|
||||
#ifndef REG
|
||||
# define REG
|
||||
# define REG register
|
||||
#endif
|
||||
|
||||
#ifndef NEEDSYNC
|
||||
@ -115,6 +594,10 @@ typedef unsigned char uchar;
|
||||
# define FILEPERMS 0666
|
||||
#endif
|
||||
|
||||
#ifndef PRESERVE
|
||||
# define PRESERVE "/usr/libexec/elvispreserve" /* name of the "preserve" program */
|
||||
#endif
|
||||
|
||||
#ifndef CC_COMMAND
|
||||
# define CC_COMMAND "cc -c"
|
||||
#endif
|
||||
@ -127,18 +610,6 @@ typedef unsigned char uchar;
|
||||
# define REDIRECT "2>"
|
||||
#endif
|
||||
|
||||
#ifndef PRESERVE
|
||||
# define PRESERVE "/usr/libexec/elvispreserve" /* name of the "preserve" program */
|
||||
#endif
|
||||
|
||||
#if !defined(CRUNCH) && defined(LETS_GET_SMALL)
|
||||
#define CRUNCH
|
||||
#endif
|
||||
|
||||
#if defined(CRUNCH) && !defined(LETS_GET_SMALL)
|
||||
#define LETS_GET_SMALL
|
||||
#endif
|
||||
|
||||
#ifndef BLKSIZE
|
||||
# ifdef CRUNCH
|
||||
# define BLKSIZE 1024
|
||||
@ -151,16 +622,12 @@ typedef unsigned char uchar;
|
||||
# define KEYBUFSIZE 1000
|
||||
#endif
|
||||
|
||||
#ifdef LETS_GET_SMALL
|
||||
#define NO_CHARATTR
|
||||
#define NO_DIGRAPH
|
||||
#define NO_SENTENCE
|
||||
#define NO_EXTENSIONS
|
||||
#define NO_MAGIC
|
||||
#define NO_ERRLIST
|
||||
#define NO_MODELINE
|
||||
#define NO_SHOWMATCH
|
||||
#define NO_SHOWMODE
|
||||
#define NO_OPTCOLS
|
||||
#define NO_MKEXRC
|
||||
#ifndef MAILER
|
||||
# define MAILER "mail"
|
||||
#endif
|
||||
|
||||
#ifndef gethome
|
||||
extern char *gethome();
|
||||
#endif
|
||||
|
||||
#endif /* ndef _CONFIG_H */
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include "config.h"
|
||||
#include "ctype.h"
|
||||
|
||||
void _ct_init P_((uchar *));
|
||||
|
||||
uchar _ct_toupper[256];
|
||||
uchar _ct_tolower[256];
|
||||
uchar _ct_ctypes[256];
|
||||
|
@ -18,15 +18,17 @@
|
||||
#include "vi.h"
|
||||
|
||||
#if ANY_UNIX
|
||||
# if UNIXV
|
||||
# if UNIXV || COH_386
|
||||
# ifdef TERMIOS
|
||||
# include <termios.h>
|
||||
# else
|
||||
# include <termio.h>
|
||||
# endif
|
||||
# ifdef S5WINSIZE
|
||||
# include <sys/stream.h> /* winsize struct defined in one of these? */
|
||||
# include <sys/ptem.h>
|
||||
# ifndef NO_S5WINSIZE
|
||||
# ifndef _SEQUENT_
|
||||
# include <sys/stream.h> /* winsize struct defined in one of these? */
|
||||
# include <sys/ptem.h>
|
||||
# endif
|
||||
# else
|
||||
# undef TIOCGWINSZ /* we can't handle it correctly yet */
|
||||
# endif
|
||||
@ -48,7 +50,6 @@ extern int VMS_read_raw; /* Set in initscr() */
|
||||
#endif
|
||||
|
||||
|
||||
extern char *getenv();
|
||||
static void starttcap();
|
||||
|
||||
/* variables, publicly available & used in the macros */
|
||||
@ -89,8 +90,8 @@ char *SR_; /* :sr=: scroll reverse */
|
||||
#else
|
||||
char *SR; /* :sr=: scroll reverse */
|
||||
#endif
|
||||
char *KS = ""; /* :ks=: init string for cursor */
|
||||
char *KE = ""; /* :ke=: restore string for cursor */
|
||||
char *KS = ""; /* :ks=: switch keypad to application mode */
|
||||
char *KE = ""; /* :ke=: switch keypad to system mode */
|
||||
char *KU; /* :ku=: key sequence sent by up arrow */
|
||||
char *KD; /* :kd=: key sequence sent by down arrow */
|
||||
char *KL; /* :kl=: key sequence sent by left arrow */
|
||||
@ -127,25 +128,25 @@ char *CR = ""; /* :cR=: cursor used for VI replace mode */
|
||||
char *aend = ""; /* end an attribute -- either UE or ME */
|
||||
char ERASEKEY; /* backspace key taken from ioctl structure */
|
||||
#ifndef NO_COLOR
|
||||
char normalcolor[16];
|
||||
char SOcolor[16];
|
||||
char SEcolor[16];
|
||||
char UScolor[16];
|
||||
char UEcolor[16];
|
||||
char MDcolor[16];
|
||||
char MEcolor[16];
|
||||
char AScolor[16];
|
||||
char AEcolor[16];
|
||||
char normalcolor[24];
|
||||
char SOcolor[24];
|
||||
char SEcolor[24];
|
||||
char UScolor[24];
|
||||
char UEcolor[24];
|
||||
char MDcolor[24];
|
||||
char MEcolor[24];
|
||||
char AScolor[24];
|
||||
char AEcolor[24];
|
||||
# ifndef NO_POPUP
|
||||
char POPUPcolor[16];
|
||||
char POPUPcolor[24];
|
||||
# endif
|
||||
# ifndef NO_VISIBLE
|
||||
char VISIBLEcolor[16];
|
||||
char VISIBLEcolor[24];
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if ANY_UNIX
|
||||
# if UNIXV
|
||||
# if UNIXV || COH_386
|
||||
# ifdef TERMIOS
|
||||
static struct termios oldtermio; /* original tty mode */
|
||||
static struct termios newtermio; /* cbreak/noecho tty mode */
|
||||
@ -210,11 +211,11 @@ void initscr()
|
||||
{
|
||||
#if ANY_UNIX
|
||||
write(2, "Environment variable TERM must be set\n", (unsigned)38);
|
||||
exit(1);
|
||||
exit(2);
|
||||
#endif
|
||||
#if OSK
|
||||
writeln(2, "Environment variable TERM must be set\n", (unsigned)38);
|
||||
exit(1);
|
||||
exit(2);
|
||||
#endif
|
||||
#if AMIGA
|
||||
termtype = TERMTYPE;
|
||||
@ -229,7 +230,7 @@ void initscr()
|
||||
#endif
|
||||
#if VMS
|
||||
write(2, "UNKNOWN terminal: define ELVIS_TERM\n", (unsigned)36);
|
||||
exit(1);
|
||||
exit(2);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@ -246,7 +247,7 @@ void initscr()
|
||||
|
||||
/* change the terminal mode to cbreak/noecho */
|
||||
#if ANY_UNIX
|
||||
# if UNIXV
|
||||
# if UNIXV || COH_386
|
||||
# ifdef TERMIOS
|
||||
tcgetattr(2, &oldtermio);
|
||||
# else
|
||||
@ -281,10 +282,12 @@ void endwin()
|
||||
|
||||
static int curses_active = FALSE;
|
||||
|
||||
extern int oldcurs;
|
||||
|
||||
/* Send any required termination strings. Turn off "raw" mode. */
|
||||
void suspend_curses()
|
||||
{
|
||||
#if ANY_UNIX && !UNIXV
|
||||
#if ANY_UNIX && !(UNIXV || COH_386)
|
||||
struct tchars tbuf;
|
||||
# ifdef TIOCSLTC
|
||||
struct ltchars ltbuf;
|
||||
@ -294,6 +297,7 @@ void suspend_curses()
|
||||
if (has_CQ)
|
||||
{
|
||||
do_CQ();
|
||||
oldcurs = 0;
|
||||
}
|
||||
#endif
|
||||
if (has_TE) /* GB */
|
||||
@ -311,8 +315,8 @@ void suspend_curses()
|
||||
|
||||
/* change the terminal mode back the way it was */
|
||||
#if ANY_UNIX
|
||||
# if UNIXV
|
||||
# if TERMIOS
|
||||
# if (UNIXV || COH_386)
|
||||
# ifdef TERMIOS
|
||||
tcsetattr(2, TCSADRAIN, &oldtermio);
|
||||
# else
|
||||
ioctl(2, TCSETAW, &oldtermio);
|
||||
@ -360,7 +364,7 @@ void resume_curses(quietly)
|
||||
{
|
||||
/* change the terminal mode to cbreak/noecho */
|
||||
#if ANY_UNIX
|
||||
# if UNIXV
|
||||
# if UNIXV || COH_386
|
||||
ospeed = (oldtermio.c_cflag & CBAUD);
|
||||
ERASEKEY = oldtermio.c_cc[VERASE];
|
||||
newtermio = oldtermio;
|
||||
@ -381,7 +385,7 @@ void resume_curses(quietly)
|
||||
# else
|
||||
ioctl(2, TCSETAW, &newtermio);
|
||||
# endif
|
||||
# else /* BSD or V7 or Coherent or Minix */
|
||||
# else /* BSD, V7, Coherent-286, or Minix */
|
||||
struct tchars tbuf;
|
||||
# ifdef TIOCSLTC
|
||||
struct ltchars ltbuf;
|
||||
@ -438,6 +442,12 @@ void resume_curses(quietly)
|
||||
ERASEKEY = '\177'; /* Accept <DEL> as <^H> for VMS */
|
||||
#endif
|
||||
|
||||
curses_active = TRUE;
|
||||
}
|
||||
|
||||
/* If we're supposed to quit quietly, then we're done */
|
||||
if (quietly)
|
||||
{
|
||||
if (has_TI) /* GB */
|
||||
{
|
||||
do_TI();
|
||||
@ -447,12 +457,6 @@ void resume_curses(quietly)
|
||||
do_KS();
|
||||
}
|
||||
|
||||
curses_active = TRUE;
|
||||
}
|
||||
|
||||
/* If we're supposed to quit quietly, then we're done */
|
||||
if (quietly)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@ -468,6 +472,10 @@ void resume_curses(quietly)
|
||||
do_SE();
|
||||
refresh();
|
||||
ttyread(kbuf, 20, 0); /* in RAW mode, so <20 is very likely */
|
||||
if (has_TI)
|
||||
{
|
||||
do_TI();
|
||||
}
|
||||
if (kbuf[0] == ':')
|
||||
{
|
||||
mode = MODE_COLON;
|
||||
@ -481,11 +489,7 @@ void resume_curses(quietly)
|
||||
}
|
||||
exwrote = FALSE;
|
||||
|
||||
#if TURBOC || __GNUC__
|
||||
signal(SIGINT, (void(*)()) trapint);
|
||||
#else
|
||||
signal(SIGINT, trapint);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This function fetches an optional string from termcap */
|
||||
@ -517,7 +521,7 @@ static void musthave(T, s)
|
||||
#if OSK
|
||||
write(2, "\l", 1);
|
||||
#endif
|
||||
exit(1);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -615,11 +619,16 @@ static void starttcap(term)
|
||||
getsize(0);
|
||||
|
||||
/* Key sequences */
|
||||
pair(&KS, &KE, "ks", "ke");
|
||||
pair(&KS, &KE, "ks", "ke"); /* keypad enable/disable */
|
||||
mayhave(&KU, "ku"); /* up */
|
||||
mayhave(&KD, "kd"); /* down */
|
||||
mayhave(&KL, "kl"); /* left */
|
||||
mayhave(&KR, "kr"); /* right */
|
||||
mayhave(&KL, "kl"); /* left */
|
||||
if (KL && KL[0]=='\b' && !KL[1])
|
||||
{
|
||||
/* never use '\b' as a left arrow! */
|
||||
KL = (char *)0;
|
||||
}
|
||||
mayhave(&PU, "kP"); /* PgUp */
|
||||
mayhave(&PD, "kN"); /* PgDn */
|
||||
mayhave(&HM, "kh"); /* Home */
|
||||
@ -913,8 +922,8 @@ void wqrefresh()
|
||||
/* This function is called during termination. It resets color modes */
|
||||
int ansiquit()
|
||||
{
|
||||
/* if ANSI color terminal, then reset the colors */
|
||||
if (!strcmp(UP, "\033[A"))
|
||||
/* if ANSI terminal & colors were set, then reset the colors */
|
||||
if (!strcmp(UP, "\033[A") && strcmp(SOcolor, SO))
|
||||
{
|
||||
tputs("\033[37;40m\033[m", 1, faddch);
|
||||
clrtoeol();
|
||||
@ -931,21 +940,33 @@ int ansicolor(cmode, attrbyte)
|
||||
int cmode; /* mode to set, e.g. A_NORMAL */
|
||||
int attrbyte; /* IBM PC attribute byte */
|
||||
{
|
||||
char temp[16]; /* hold the new mode string */
|
||||
char temp[24]; /* hold the new mode string */
|
||||
|
||||
/* if not ANSI-ish, then fail */
|
||||
if (strcmp(UP, "\033[A") && strcmp(UP, "\033OA"))
|
||||
{
|
||||
msg("Don't know how to set colors for this terminal");
|
||||
return 0;
|
||||
/* Only give an error message if we're editing a file.
|
||||
* (I.e., if we're *NOT* currently doing a ".exrc")
|
||||
*/
|
||||
if (tmpfd >= 0)
|
||||
msg("Don't know how to set colors for this terminal");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* construct the color string */
|
||||
#ifdef MWC /* either Coherent-286 ("COHERENT"), or Coherent-386 ("M_SYSV") */
|
||||
sprintf(temp, "\033[m\033[3%cm\033[4%cm%s%s",
|
||||
"04261537"[attrbyte & 0x07],
|
||||
"04261537"[(attrbyte >> 4) & 0x07],
|
||||
(attrbyte & 0x08) ? "\033[1m" : "",
|
||||
(attrbyte & 0x80) ? "\033[5m" : "");
|
||||
#else
|
||||
sprintf(temp, "\033[m\033[3%c;4%c%s%sm",
|
||||
"04261537"[attrbyte & 0x07],
|
||||
"04261537"[(attrbyte >> 4) & 0x07],
|
||||
(attrbyte & 0x08) ? ";1" : "",
|
||||
(attrbyte & 0x80) ? ";5" : "");
|
||||
#endif
|
||||
|
||||
/* stick it in the right place */
|
||||
switch (cmode)
|
||||
@ -997,7 +1018,7 @@ int ansicolor(cmode, attrbyte)
|
||||
#endif
|
||||
}
|
||||
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -1006,6 +1027,7 @@ int ansicolor(cmode, attrbyte)
|
||||
* yet, this is one of the termcap strings; for color terminals that really
|
||||
* have had colors defined, we just the "normal color" escape sequence.
|
||||
*/
|
||||
int
|
||||
endcolor()
|
||||
{
|
||||
if (aend == ME)
|
||||
|
@ -150,7 +150,7 @@ static void cutfree(buf)
|
||||
msg("cutfree() tried to free a NULL buf->phys pointer.");
|
||||
else
|
||||
#endif
|
||||
free((char *)buf->phys);
|
||||
_free_((char *)buf->phys);
|
||||
|
||||
/* maybe delete the temp file */
|
||||
maybezap(num);
|
||||
@ -666,7 +666,7 @@ int cb2str(name, buf, size)
|
||||
}
|
||||
|
||||
/* if too big, return the size now, without doing anything */
|
||||
if (cb->end - cb->start >= size)
|
||||
if ((unsigned)(cb->end - cb->start) >= size)
|
||||
{
|
||||
return cb->end - cb->start;
|
||||
}
|
||||
|
@ -72,6 +72,58 @@ is executed as a series of \fIex\fR commands.
|
||||
A file by the same name may be executed in the current directory, too.
|
||||
On non-UNIX systems, ".exrc" is usually an invalid file name;
|
||||
there, the initialization file is called "elvis.rc" instead.
|
||||
.SH ENVIRONMENT
|
||||
.IP TERM
|
||||
This is the name of your terminal's entry in the termcap or terminfo
|
||||
database.
|
||||
The list of legal values varies from one system to another.
|
||||
.IP TERMCAP
|
||||
Optional.
|
||||
If your system uses termcap, and the TERMCAP variable is unset, then
|
||||
\*E will read your terminal's definition from \fB/etc/termcap\fR.
|
||||
If TERMCAP is set to the full pathname of a file (starting with a '/')
|
||||
then \*E will look in the named file instead of \fB/etc/termcap\fR.
|
||||
If TERMCAP is set to a value which doesn't start with a '/',
|
||||
then its value is assumed to be the full termcap entry for your terminal.
|
||||
.IP TERMINFO
|
||||
Optional.
|
||||
If your system uses terminfo, and the TERMINFO variable is unset, then
|
||||
\*E will read your terminal's definition from the database in the
|
||||
\fB/usr/lib/terminfo\fR database.
|
||||
If TERMINFO is set, then its value is used as the database name to use
|
||||
instead of \fB/usr/lib/terminfo\fR.
|
||||
.IP "LINES, COLUMNS"
|
||||
Optional.
|
||||
These variables, if set, will override the screen size values given in
|
||||
the termcap/terminfo for your terminal.
|
||||
On windowing systems such as X, \*E has other ways of determining the
|
||||
screen size, so you should probably leave these variables unset.
|
||||
.IP EXINIT
|
||||
Optional.
|
||||
This variable can hold EX commands which will be executed before any .exrc
|
||||
files.
|
||||
.IP SHELL
|
||||
Optional.
|
||||
The SHELL variable sets the default value for the "shell" option,
|
||||
which determines which shell program is used to perform wildcard
|
||||
expansion in file names, and also which is used to execute filters
|
||||
or external programs.
|
||||
The default value on UNIX systems is "/bin/sh".
|
||||
.IP
|
||||
Note: Under MS-DOS, this variable is called COMSPEC instead of SHELL.
|
||||
.IP HOME
|
||||
This variable should be set to the name of your home directory.
|
||||
\*E looks for its initialization file there;
|
||||
if HOME is unset then the initialization file will not be executed.
|
||||
.IP TAGPATH
|
||||
Optional.
|
||||
This variable is used by the "ref" program, which is invoked by the shift-K,
|
||||
control-], and :tag commands.
|
||||
See "ref" for more information.
|
||||
.IP "TMP, TEMP"
|
||||
These optional environment variables are only used in non-UNIX versions
|
||||
of \*E.
|
||||
They allow you to supply a directory name to be used for storing temporary files.
|
||||
.SH "SEE ALSO"
|
||||
ctags(1), ref(1), virec(1)
|
||||
.PP
|
||||
|
@ -5,14 +5,6 @@
|
||||
* 14407 SW Teal Blvd. #C
|
||||
* Beaverton, OR 97005
|
||||
* kirkenda@cs.pdx.edu
|
||||
*
|
||||
* PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
|
||||
* -------------------- ----- ----------------------
|
||||
* CURRENT PATCH LEVEL: 1 00043
|
||||
* -------------------- ----- ----------------------
|
||||
*
|
||||
* 27 Nov 1992 Felix Gaehtgens Fixed <ESC>:wq!
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@ -60,6 +52,8 @@ static struct
|
||||
}
|
||||
cmdnames[] =
|
||||
{ /* cmd name cmd code function arguments */
|
||||
{"print", CMD_PRINT, cmd_print, RANGE+NL },
|
||||
|
||||
{"append", CMD_APPEND, cmd_append, FROM+ZERO+BANG },
|
||||
#ifdef DEBUG
|
||||
{"bug", CMD_DEBUG, cmd_debug, RANGE+BANG+EXTRA+NL},
|
||||
@ -76,7 +70,6 @@ static struct
|
||||
{"move", CMD_MOVE, cmd_move, RANGE+EXTRA },
|
||||
{"next", CMD_NEXT, cmd_next, BANG+NAMEDFS },
|
||||
{"Next", CMD_PREVIOUS, cmd_next, BANG },
|
||||
{"print", CMD_PRINT, cmd_print, RANGE+NL },
|
||||
{"quit", CMD_QUIT, cmd_xit, BANG },
|
||||
{"read", CMD_READ, cmd_read, FROM+ZERO+NAMEDF},
|
||||
{"substitute", CMD_SUBSTITUTE, cmd_substitute, RANGE+EXTRA },
|
||||
@ -118,6 +111,9 @@ static struct
|
||||
{"mkexrc", CMD_MKEXRC, cmd_mkexrc, NAMEDF },
|
||||
#endif
|
||||
{"number", CMD_NUMBER, cmd_print, RANGE+NL },
|
||||
#ifndef NO_TAGSTACK
|
||||
{"pop", CMD_POP, cmd_pop, BANG+WORD1 },
|
||||
#endif
|
||||
{"put", CMD_PUT, cmd_put, FROM+ZERO+WORD1 },
|
||||
{"set", CMD_SET, cmd_set, EXRCOK+EXTRA },
|
||||
{"shell", CMD_SHELL, cmd_shell, NL },
|
||||
@ -128,7 +124,7 @@ static struct
|
||||
{"tag", CMD_TAG, cmd_tag, BANG+WORD1 },
|
||||
{"version", CMD_VERSION, cmd_version, EXRCOK+NONE },
|
||||
{"visual", CMD_VISUAL, cmd_edit, BANG+NAMEDF },
|
||||
{"wq", CMD_WQUIT, cmd_xit, BANG+NL },
|
||||
{"wq", CMD_WQUIT, cmd_xit, NL },
|
||||
|
||||
#ifdef DEBUG
|
||||
{"debug", CMD_DEBUG, cmd_debug, RANGE+BANG+EXTRA+NL},
|
||||
@ -392,8 +388,8 @@ void doexcmd(cmdbuf)
|
||||
}
|
||||
else if (*scan == '0')
|
||||
{
|
||||
frommark = tomark = MARK_UNSET;
|
||||
scan++;
|
||||
frommark = tomark = (*scan ? MARK_UNSET : MARK_FIRST);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -424,16 +420,23 @@ void doexcmd(cmdbuf)
|
||||
scan++;
|
||||
}
|
||||
|
||||
/* if no command, then just move the cursor to the mark */
|
||||
/* Figure out how long the command name is. If no command, then the
|
||||
* length is 0, which will match the "print" command.
|
||||
*/
|
||||
if (!*scan)
|
||||
{
|
||||
if (tomark != MARK_UNSET)
|
||||
cursor = tomark;
|
||||
return;
|
||||
/* if not in ex mode, and both endpoints are at the line,
|
||||
* then just move to the start of that line without printing
|
||||
*/
|
||||
if (mode != MODE_EX && frommark == tomark)
|
||||
{
|
||||
if (tomark != MARK_UNSET)
|
||||
cursor = tomark;
|
||||
return;
|
||||
}
|
||||
cmdlen = 0;
|
||||
}
|
||||
|
||||
/* figure out how long the command name is */
|
||||
if (!isalpha(*scan))
|
||||
else if (!isalpha(*scan))
|
||||
{
|
||||
cmdlen = 1;
|
||||
}
|
||||
@ -672,23 +675,60 @@ int doexrc(filename)
|
||||
int fd; /* file descriptor */
|
||||
int len; /* length of the ".exrc" file */
|
||||
|
||||
#ifdef CRUNCH
|
||||
/* small address space - we need to conserve space */
|
||||
|
||||
/* !!! kludge: we use U_text as the buffer. This has the side-effect
|
||||
* of interfering with the shift-U visual command. Disable shift-U.
|
||||
*/
|
||||
U_line = 0L;
|
||||
#else
|
||||
# if TINYSTACK
|
||||
# if TOS || MINT
|
||||
/* small stack, but big heap. Allocate buffer from heap */
|
||||
char *U_text = (char *)malloc(4096);
|
||||
if (!U_text)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
# else
|
||||
/* small stack - we need to conserve space */
|
||||
|
||||
/* !!! kludge: we use U_text as the buffer. This has the side-effect
|
||||
* of interfering with the shift-U visual command. Disable shift-U.
|
||||
*/
|
||||
U_line = 0L;
|
||||
# endif
|
||||
# else
|
||||
/* This is how we would *like* to do it -- with a large buffer on the
|
||||
* stack, so we can handle large .exrc files and also recursion.
|
||||
*/
|
||||
char U_text[4096];
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* open the file, read it, and close */
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
#if TINYSTACK && (TOS || MINT)
|
||||
free(U_text);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
len = tread(fd, U_text, BLKSIZE);
|
||||
#if TINYSTACK && (TOS || MINT)
|
||||
len = tread(fd, U_text, 4096);
|
||||
#else
|
||||
len = tread(fd, U_text, sizeof U_text);
|
||||
#endif
|
||||
close(fd);
|
||||
|
||||
/* execute the string */
|
||||
exstring(U_text, len, ctrl('V'));
|
||||
|
||||
#if TINYSTACK && (TOS || MINT)
|
||||
free(U_text);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -28,8 +28,8 @@ static struct _DIG
|
||||
} *digs;
|
||||
|
||||
char digraph(key1, key2)
|
||||
char key1; /* the underlying character */
|
||||
char key2; /* the second character */
|
||||
int key1; /* the underlying character */
|
||||
int key2; /* the second character */
|
||||
{
|
||||
int newkey;
|
||||
REG struct _DIG *dp;
|
||||
@ -158,7 +158,7 @@ void do_digraph(bang, extra)
|
||||
prev->next = dp->next;
|
||||
else
|
||||
digs = dp->next;
|
||||
free(dp);
|
||||
_free_(dp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -211,11 +211,11 @@ void savedigs(fd)
|
||||
* chunk of text with typed-in text. It returns the MARK of the last character
|
||||
* that the user typed in.
|
||||
*/
|
||||
MARK input(from, to, when, above)
|
||||
MARK input(from, to, when, delta)
|
||||
MARK from; /* where to start inserting text */
|
||||
MARK to; /* extent of text to delete */
|
||||
int when; /* either WHEN_VIINP or WHEN_VIREP */
|
||||
int above; /* boolean: take indentation from lower line? */
|
||||
int delta; /* 1 to take indent from lower line, -1 for upper, 0 for none */
|
||||
{
|
||||
char key[2]; /* key char followed by '\0' char */
|
||||
char *build; /* used in building a newline+indent string */
|
||||
@ -287,8 +287,8 @@ MARK input(from, to, when, above)
|
||||
|
||||
/* handle autoindent of the first line, maybe */
|
||||
cursor = from;
|
||||
m = (above ? (cursor + BLKSIZE) : (cursor - BLKSIZE));
|
||||
if (*o_autoindent && markidx(m) == 0
|
||||
m = cursor + MARK_AT_LINE(delta);
|
||||
if (delta != 0 && *o_autoindent && markidx(m) == 0
|
||||
&& markline(m) >= 1L && markline(m) <= nlines)
|
||||
{
|
||||
/* Only autoindent blank lines. */
|
||||
@ -307,7 +307,7 @@ MARK input(from, to, when, above)
|
||||
{
|
||||
*build = '\0';
|
||||
add(cursor, tmpblk.c);
|
||||
cursor += (build - tmpblk.c);
|
||||
cursor += (int)(build - tmpblk.c);
|
||||
if (cursor > to)
|
||||
to = cursor;
|
||||
}
|
||||
@ -329,7 +329,7 @@ MARK input(from, to, when, above)
|
||||
build = ptext;
|
||||
if (pline == markline(from))
|
||||
build += markidx(from);
|
||||
for (scan = ptext + markidx(cursor); --scan >= build && isalnum(*scan); )
|
||||
for (scan = ptext + markidx(cursor); --scan >= build && !isspace(*scan); )
|
||||
{
|
||||
}
|
||||
scan++;
|
||||
@ -338,7 +338,7 @@ MARK input(from, to, when, above)
|
||||
key[0] = getkey(when);
|
||||
#endif
|
||||
#ifndef NO_VISIBLE
|
||||
if (key[0] != '\0' && V_from != MARK_UNSET)
|
||||
if (key[0] != ctrl('O') && V_from != MARK_UNSET)
|
||||
{
|
||||
msg("Can't modify text during a selection");
|
||||
beep();
|
||||
@ -375,10 +375,11 @@ MARK input(from, to, when, above)
|
||||
* warpmargin, then change the last whitespace
|
||||
* characters on line into a newline
|
||||
*/
|
||||
if (*o_wrapmargin != 0)
|
||||
if (*o_wrapmargin)
|
||||
{
|
||||
pfetch(markline(cursor));
|
||||
if (idx2col(cursor, ptext, TRUE) > COLS - (*o_wrapmargin & 0xff))
|
||||
if (plen == idx2col(cursor, ptext, TRUE)
|
||||
&& plen > COLS - (*o_wrapmargin & 0xff))
|
||||
{
|
||||
build = tmpblk.c;
|
||||
*build++ = '\n';
|
||||
@ -401,11 +402,15 @@ MARK input(from, to, when, above)
|
||||
continue;
|
||||
|
||||
/*break up line, and we do autoindent if needed*/
|
||||
change(m + (scan - ptext), m + (scan - ptext) + 1, tmpblk.c);
|
||||
cursor = (cursor & ~(BLKSIZE - 1))
|
||||
+ BLKSIZE
|
||||
+ strlen(tmpblk.c) - 1
|
||||
+ plen - (scan - ptext) - 1;
|
||||
change(m + (int)(scan - ptext), m + (int)(scan - ptext) + 1, tmpblk.c);
|
||||
|
||||
/* NOTE: for some reason, MSC 5.10 doesn't
|
||||
* like for these lines to be combined!!!
|
||||
*/
|
||||
cursor = (cursor & ~(BLKSIZE - 1));
|
||||
cursor += BLKSIZE;
|
||||
cursor += strlen(tmpblk.c) - 1;
|
||||
cursor += plen - (int)(scan - ptext) - 1;
|
||||
|
||||
/*remove trailing spaces on previous line*/
|
||||
pfetch(markline(m));
|
||||
@ -416,7 +421,7 @@ MARK input(from, to, when, above)
|
||||
if (*scan != ' ' && *scan != '\t')
|
||||
break;
|
||||
}
|
||||
delete(m + (scan-ptext) + 1, m + plen);
|
||||
delete(m + (int)(scan - ptext) + 1, m + plen);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -559,7 +564,7 @@ MARK input(from, to, when, above)
|
||||
V_from = MARK_UNSET;
|
||||
ChangeText
|
||||
{
|
||||
m = from = to = cursor = paste(cursor, (*key == 'p'), FALSE);
|
||||
m = paste(cursor, (*key == 'p'), FALSE);
|
||||
}
|
||||
break;
|
||||
# endif /* !NO_VISIBLE */
|
||||
@ -569,8 +574,8 @@ MARK input(from, to, when, above)
|
||||
/* adjust the moved cursor */
|
||||
if (m != cursor)
|
||||
{
|
||||
m = adjmove(cursor, m, (*key == 'j' || *key == 'k' ? 0x20 : 0));
|
||||
if (*key == '$' || (*key == 'l' && m <= cursor))
|
||||
m = adjmove(cursor, m, (*key == 'j' || *key == 'k' ? NCOL|FINL : FINL));
|
||||
if (plen && (*key == '$' || (*key == 'l' && m <= cursor)))
|
||||
{
|
||||
m++;
|
||||
}
|
||||
@ -696,11 +701,21 @@ MARK input(from, to, when, above)
|
||||
}
|
||||
|
||||
/* remove indent from this line, if blank */
|
||||
if ((scan - ptext) >= markidx(cursor) && plen > 0)
|
||||
if ((int)(scan - ptext) >= markidx(cursor) && plen > 0)
|
||||
{
|
||||
to = cursor &= ~(BLKSIZE - 1);
|
||||
delete(cursor, cursor + plen);
|
||||
delete(cursor, cursor + (int)(scan - ptext));
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* advance "to" past whitespace at the cursor */
|
||||
if (to >= cursor)
|
||||
{
|
||||
for (scan = ptext + markidx(cursor), to = cursor; *scan == ' ' || *scan == '\t'; scan++, to++)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
*build = 0;
|
||||
if (cursor >= to && when != WHEN_VIREP)
|
||||
@ -727,7 +742,11 @@ MARK input(from, to, when, above)
|
||||
{
|
||||
cutname('.');
|
||||
}
|
||||
to = cursor = paste(cursor, FALSE, TRUE) + 1L;
|
||||
m = paste(cursor, FALSE, TRUE);
|
||||
if (m != MARK_UNSET)
|
||||
{
|
||||
to = cursor = m + 1L;
|
||||
}
|
||||
break;
|
||||
|
||||
case ctrl('V'):
|
||||
|
@ -20,8 +20,7 @@
|
||||
#include <setjmp.h>
|
||||
#include "vi.h"
|
||||
|
||||
extern trapint(); /* defined below */
|
||||
extern char *getenv();
|
||||
extern SIGTYPE trapint(); /* defined below */
|
||||
jmp_buf jmpenv;
|
||||
|
||||
#ifndef NO_DIGRAPH
|
||||
@ -89,33 +88,33 @@ void main(argc, argv)
|
||||
|
||||
/* arrange for deadly signals to be caught */
|
||||
# ifdef SIGHUP
|
||||
signal(SIGHUP, (void(*)()) deathtrap);
|
||||
signal(SIGHUP, deathtrap);
|
||||
# endif
|
||||
# ifndef DEBUG
|
||||
# ifdef SIGILL
|
||||
signal(SIGILL, (void(*)()) deathtrap);
|
||||
signal(SIGILL, deathtrap);
|
||||
# endif
|
||||
# ifdef SIGBUS
|
||||
signal(SIGBUS, (void(*)()) deathtrap);
|
||||
signal(SIGBUS, deathtrap);
|
||||
# endif
|
||||
# ifdef SIGSEGV
|
||||
signal(SIGSEGV, (void(*)()) deathtrap);
|
||||
signal(SIGSEGV, deathtrap);
|
||||
# endif
|
||||
# ifdef SIGSYS
|
||||
signal(SIGSYS, (void(*)()) deathtrap);
|
||||
signal(SIGSYS, deathtrap);
|
||||
# endif
|
||||
# endif /* !DEBUG */
|
||||
# ifdef SIGPIPE
|
||||
signal(SIGPIPE, (void(*)()) deathtrap);
|
||||
signal(SIGPIPE, deathtrap);
|
||||
# endif
|
||||
# ifdef SIGTERM
|
||||
signal(SIGTERM, (void(*)()) deathtrap);
|
||||
signal(SIGTERM, deathtrap);
|
||||
# endif
|
||||
# ifdef SIGUSR1
|
||||
signal(SIGUSR1, (void(*)()) deathtrap);
|
||||
signal(SIGUSR1, deathtrap);
|
||||
# endif
|
||||
# ifdef SIGUSR2
|
||||
signal(SIGUSR2, (void(*)()) deathtrap);
|
||||
signal(SIGUSR2, deathtrap);
|
||||
# endif
|
||||
|
||||
/* initialize the options - must be done after initscr(), so that
|
||||
@ -187,11 +186,11 @@ void main(argc, argv)
|
||||
|
||||
case 'L':
|
||||
case 'r': /* recover */
|
||||
msg("Use the `elvisrecover` program to recover lost files");
|
||||
msg("Use the `elvrec` program to recover lost files");
|
||||
endmsgs();
|
||||
refresh();
|
||||
endwin();
|
||||
exit(0);
|
||||
exit(1);
|
||||
break;
|
||||
|
||||
case 't': /* tag */
|
||||
@ -309,7 +308,7 @@ void main(argc, argv)
|
||||
doexrc(SYSEXRC);
|
||||
#endif
|
||||
#ifdef HMEXRC
|
||||
str = getenv("HOME");
|
||||
str = gethome(argv[0]);
|
||||
if (str && *str)
|
||||
{
|
||||
strcpy(tmpblk.c, str);
|
||||
@ -346,7 +345,7 @@ void main(argc, argv)
|
||||
blkinit();
|
||||
if (tag)
|
||||
{
|
||||
cmd_tag(MARK_FIRST, MARK_FIRST, CMD_TAG, 0, tag);
|
||||
cmd_tag(MARK_UNSET, MARK_FIRST, CMD_TAG, 0, tag);
|
||||
}
|
||||
#ifndef NO_ERRLIST
|
||||
else if (err)
|
||||
@ -386,7 +385,7 @@ void main(argc, argv)
|
||||
/* Maybe we just aborted a change? */
|
||||
abortdo();
|
||||
}
|
||||
signal(SIGINT, (void(*)()) trapint);
|
||||
signal(SIGINT, trapint);
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
@ -419,13 +418,13 @@ void main(argc, argv)
|
||||
refresh();
|
||||
endwin();
|
||||
|
||||
exit(0);
|
||||
exit(exitcode);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
|
||||
/*ARGSUSED*/
|
||||
int trapint(signo)
|
||||
SIGTYPE trapint(signo)
|
||||
int signo;
|
||||
{
|
||||
beep();
|
||||
@ -434,16 +433,11 @@ int trapint(signo)
|
||||
#if OSK
|
||||
sigmask(-1);
|
||||
#endif
|
||||
#if TURBOC || __GNUC__
|
||||
signal(signo, (void (*)())trapint);
|
||||
#else
|
||||
signal(signo, trapint);
|
||||
#endif
|
||||
doingglobal = FALSE;
|
||||
|
||||
longjmp(jmpenv, 1);
|
||||
|
||||
return 0;
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
|
||||
@ -502,7 +496,7 @@ static char digtable[][4] =
|
||||
""
|
||||
};
|
||||
|
||||
static init_digraphs()
|
||||
static int init_digraphs()
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -378,7 +378,7 @@ void add(atmark, newtext)
|
||||
{
|
||||
/* hey, we probably can! Get the following block & see... */
|
||||
following = blkget(blkno + 1);
|
||||
if (strlen(following->c) + (build - blk->c) < BLKSIZE - 1)
|
||||
if (strlen(following->c) + (build - blk->c) < (unsigned)(BLKSIZE - 1))
|
||||
{
|
||||
/* we can! Copy text from following to blk */
|
||||
for (scan = following->c; *scan; )
|
||||
|
@ -17,7 +17,7 @@
|
||||
MARK m_updnto(m, cnt, cmd)
|
||||
MARK m; /* movement is relative to this mark */
|
||||
long cnt; /* a numeric argument */
|
||||
char cmd; /* the command character */
|
||||
int cmd; /* the command character */
|
||||
{
|
||||
DEFAULT(cmd == 'G' ? nlines : 1L);
|
||||
|
||||
@ -245,6 +245,10 @@ MARK m_sentence(m, cnt, cmd)
|
||||
{
|
||||
REG char *text;
|
||||
REG long l;
|
||||
#ifndef CRUNCH
|
||||
/* figure out where the paragraph boundary is */
|
||||
MARK pp = m_paragraph(m, 1L, cmd=='(' ? '{' : '}');
|
||||
#endif
|
||||
|
||||
DEFAULT(1);
|
||||
|
||||
@ -277,9 +281,9 @@ MARK m_sentence(m, cnt, cmd)
|
||||
/* move forward, wrap at end of line */
|
||||
if (!text[0])
|
||||
{
|
||||
if (l >= nlines)
|
||||
if (l == nlines)
|
||||
{
|
||||
return MARK_UNSET;
|
||||
goto BreakBreak;
|
||||
}
|
||||
l++;
|
||||
pfetch(l);
|
||||
@ -297,9 +301,9 @@ MARK m_sentence(m, cnt, cmd)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (l <= 1)
|
||||
if (l == 1L)
|
||||
{
|
||||
return MARK_FIRST;
|
||||
goto BreakBreak;
|
||||
}
|
||||
l--;
|
||||
pfetch(l);
|
||||
@ -313,12 +317,25 @@ MARK m_sentence(m, cnt, cmd)
|
||||
}
|
||||
} while (!isperiod(text));
|
||||
}
|
||||
BreakBreak:
|
||||
|
||||
/* construct a mark for this location */
|
||||
m = buildmark(text);
|
||||
|
||||
/* move forward to the first word of the next sentence */
|
||||
m = m_fword(m, 1L, 'w', '\0');
|
||||
if (m == MARK_UNSET)
|
||||
{
|
||||
m = MARK_EOF;
|
||||
}
|
||||
|
||||
#ifndef CRUNCH
|
||||
/* don't cross the paragraph boundary */
|
||||
if (pp && ((cmd=='(') ? (m<pp) : (m>pp)))
|
||||
{
|
||||
m = pp;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m;
|
||||
}
|
||||
@ -334,11 +351,15 @@ MARK m_paragraph(m, cnt, cmd)
|
||||
long l, ol; /* current line number, original line number */
|
||||
int dir; /* -1 if we're moving up, or 1 if down */
|
||||
char col0; /* character to expect in column 0 */
|
||||
long limit; /* line where searching must stop */
|
||||
#ifndef NO_SENTENCE
|
||||
# define SENTENCE(x) (x)
|
||||
char *list; /* either o_sections or o_paragraph */
|
||||
#else
|
||||
# define SENTENCE(x)
|
||||
#endif
|
||||
#ifndef CRUNCH
|
||||
MARK ss;
|
||||
#endif
|
||||
|
||||
DEFAULT(1);
|
||||
@ -350,12 +371,26 @@ MARK m_paragraph(m, cnt, cmd)
|
||||
dir = -1;
|
||||
col0 = '\0';
|
||||
SENTENCE(list = o_paragraphs);
|
||||
#ifndef CRUNCH
|
||||
ss = m_paragraph(m, 1L, '<');
|
||||
if (ss)
|
||||
limit = markline(ss);
|
||||
else
|
||||
#endif
|
||||
limit = 1L;
|
||||
break;
|
||||
|
||||
case '}':
|
||||
dir = 1;
|
||||
col0 = '\0';
|
||||
SENTENCE(list = o_paragraphs);
|
||||
#ifndef CRUNCH
|
||||
ss = m_paragraph(m, 1L, '>');
|
||||
if (ss)
|
||||
limit = markline(ss);
|
||||
else
|
||||
#endif
|
||||
limit = nlines;
|
||||
break;
|
||||
|
||||
case '[':
|
||||
@ -363,9 +398,12 @@ MARK m_paragraph(m, cnt, cmd)
|
||||
{
|
||||
return MARK_UNSET;
|
||||
}
|
||||
/* fall through... */
|
||||
case '<':
|
||||
dir = -1;
|
||||
col0 = '{';
|
||||
SENTENCE(list = o_sections);
|
||||
limit = 1L;
|
||||
break;
|
||||
|
||||
case ']':
|
||||
@ -373,18 +411,21 @@ MARK m_paragraph(m, cnt, cmd)
|
||||
{
|
||||
return MARK_UNSET;
|
||||
}
|
||||
/* fall through... */
|
||||
case '>':
|
||||
dir = 1;
|
||||
col0 = '{';
|
||||
SENTENCE(list = o_sections);
|
||||
limit = nlines;
|
||||
break;
|
||||
}
|
||||
ol = l = markline(m);
|
||||
|
||||
/* for each paragraph that we want to travel through... */
|
||||
while (l > 0 && l <= nlines && cnt-- > 0)
|
||||
while (l != limit && cnt-- > 0)
|
||||
{
|
||||
/* skip blank lines between paragraphs */
|
||||
while (l > 0 && l <= nlines && col0 == *(text = fetchline(l)))
|
||||
while (l != limit && col0 == *(text = fetchline(l)))
|
||||
{
|
||||
l += dir;
|
||||
}
|
||||
@ -407,22 +448,14 @@ MARK m_paragraph(m, cnt, cmd)
|
||||
}
|
||||
#endif
|
||||
l += dir;
|
||||
} while (l > 0 && l <= nlines && col0 != *(text = fetchline(l)));
|
||||
} while (l != limit && col0 != *(text = fetchline(l)));
|
||||
BreakBreak: ;
|
||||
}
|
||||
|
||||
if (l > nlines)
|
||||
{
|
||||
m = MARK_LAST;
|
||||
}
|
||||
else if (l <= 0)
|
||||
{
|
||||
m = MARK_FIRST;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = MARK_AT_LINE(l);
|
||||
}
|
||||
m = MARK_AT_LINE(l);
|
||||
#ifdef DEBUG2
|
||||
debout("m_paragraph() returning %ld.%d\n", markline(m), markidx(m));
|
||||
#endif
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -44,37 +44,50 @@ MARK m_wsrch(word, m, cnt)
|
||||
}
|
||||
#endif
|
||||
|
||||
MARK m_nsrch(m)
|
||||
MARK m_nsrch(m, cnt, cmd)
|
||||
MARK m; /* where to start searching */
|
||||
long cnt; /* number of searches to do */
|
||||
int cmd; /* command character -- 'n' or 'N' */
|
||||
{
|
||||
if (prevsf)
|
||||
int oldprevsf; /* original value of prevsf, so we can fix any changes */
|
||||
|
||||
DEFAULT(1L);
|
||||
|
||||
/* clear the bottom line. In particular, we want to loose any
|
||||
* "(wrapped)" notice.
|
||||
*/
|
||||
move(LINES - 1, 0);
|
||||
clrtoeol();
|
||||
|
||||
/* if 'N' command, then invert the "prevsf" variable */
|
||||
oldprevsf = prevsf;
|
||||
if (cmd == 'N')
|
||||
{
|
||||
m = m_fsrch(m, (char *)0);
|
||||
prevsf = TRUE;
|
||||
prevsf = !prevsf;
|
||||
}
|
||||
else
|
||||
|
||||
/* search forward if prevsf -- i.e., if previous search was forward */
|
||||
while (--cnt >= 0L && m != MARK_UNSET)
|
||||
{
|
||||
m = m_bsrch(m, (char *)0);
|
||||
prevsf = FALSE;
|
||||
if (prevsf)
|
||||
{
|
||||
m = m_fsrch(m, (char *)0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m = m_bsrch(m, (char *)0);
|
||||
}
|
||||
}
|
||||
|
||||
/* restore the old value of prevsf -- if cmd=='N' then it was inverted,
|
||||
* and the m_fsrch() and m_bsrch() functions force it to a (possibly
|
||||
* incorrect) value. The value of prevsf isn't supposed to be changed
|
||||
* at all here!
|
||||
*/
|
||||
prevsf = oldprevsf;
|
||||
return m;
|
||||
}
|
||||
|
||||
MARK m_Nsrch(m)
|
||||
MARK m; /* where to start searching */
|
||||
{
|
||||
if (prevsf)
|
||||
{
|
||||
m = m_bsrch(m, (char *)0);
|
||||
prevsf = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = m_fsrch(m, (char *)0);
|
||||
prevsf = FALSE;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
MARK m_fsrch(m, ptrn)
|
||||
MARK m; /* where to start searching */
|
||||
@ -104,7 +117,7 @@ MARK m_fsrch(m, ptrn)
|
||||
ptrn++;
|
||||
|
||||
/* free the previous pattern */
|
||||
if (re) free(re);
|
||||
if (re) _free_(re);
|
||||
|
||||
/* compile the pattern */
|
||||
re = regcomp(ptrn);
|
||||
@ -214,7 +227,7 @@ MARK m_bsrch(m, ptrn)
|
||||
ptrn++;
|
||||
|
||||
/* free the previous pattern, if any */
|
||||
if (re) free(re);
|
||||
if (re) _free_(re);
|
||||
|
||||
/* compile the pattern */
|
||||
re = regcomp(ptrn);
|
||||
|
@ -21,7 +21,7 @@ static char prev_key; /* sought cvhar from previous [fFtT] */
|
||||
MARK m__ch(m, cnt, cmd)
|
||||
MARK m; /* current position */
|
||||
long cnt;
|
||||
char cmd; /* command: either ',' or ';' */
|
||||
int cmd; /* command: either ',' or ';' */
|
||||
{
|
||||
MARK (*tmp)();
|
||||
|
||||
@ -52,7 +52,7 @@ MARK m__ch(m, cnt, cmd)
|
||||
MARK m_fch(m, cnt, key)
|
||||
MARK m; /* where to search from */
|
||||
long cnt;
|
||||
char key; /* what to search for */
|
||||
int key; /* what to search for */
|
||||
{
|
||||
REG char *text;
|
||||
|
||||
@ -83,7 +83,7 @@ MARK m_fch(m, cnt, key)
|
||||
MARK m_Fch(m, cnt, key)
|
||||
MARK m; /* where to search from */
|
||||
long cnt;
|
||||
char key; /* what to search for */
|
||||
int key; /* what to search for */
|
||||
{
|
||||
REG char *text;
|
||||
|
||||
@ -114,50 +114,32 @@ MARK m_Fch(m, cnt, key)
|
||||
MARK m_tch(m, cnt, key)
|
||||
MARK m; /* where to search from */
|
||||
long cnt;
|
||||
char key; /* what to search for */
|
||||
int key; /* what to search for */
|
||||
{
|
||||
/* skip the adjacent char */
|
||||
pfetch(markline(m));
|
||||
if (plen <= markidx(m))
|
||||
{
|
||||
return MARK_UNSET;
|
||||
}
|
||||
m++;
|
||||
|
||||
m = m_fch(m, cnt, key);
|
||||
if (m == MARK_UNSET)
|
||||
if (m != MARK_UNSET)
|
||||
{
|
||||
return MARK_UNSET;
|
||||
prevfwdfn = m_tch;
|
||||
prevrevfn = m_Tch;
|
||||
m--;
|
||||
}
|
||||
|
||||
prevfwdfn = m_tch;
|
||||
prevrevfn = m_Tch;
|
||||
|
||||
return m - 1;
|
||||
return m;
|
||||
}
|
||||
|
||||
/* move backward within this line almost to previous occurrence of key */
|
||||
MARK m_Tch(m, cnt, key)
|
||||
MARK m; /* where to search from */
|
||||
long cnt;
|
||||
char key; /* what to search for */
|
||||
int key; /* what to search for */
|
||||
{
|
||||
/* skip the adjacent char */
|
||||
if (markidx(m) == 0)
|
||||
{
|
||||
return MARK_UNSET;
|
||||
}
|
||||
m--;
|
||||
|
||||
m = m_Fch(m, cnt, key);
|
||||
if (m == MARK_UNSET)
|
||||
{
|
||||
return MARK_UNSET;
|
||||
prevfwdfn = m_Tch;
|
||||
prevrevfn = m_tch;
|
||||
m++;
|
||||
}
|
||||
|
||||
prevfwdfn = m_Tch;
|
||||
prevrevfn = m_tch;
|
||||
|
||||
return m + 1;
|
||||
return m;
|
||||
}
|
||||
#endif
|
||||
|
@ -136,6 +136,12 @@ MARK m_scroll(m, cnt, key)
|
||||
int key; /* keystroke that causes this movement */
|
||||
{
|
||||
MARK tmp; /* a temporary mark, used as arg to redraw() */
|
||||
#ifndef CRUNCH
|
||||
int savenearscroll;
|
||||
|
||||
savenearscroll = *o_nearscroll;
|
||||
*o_nearscroll = LINES;
|
||||
#endif
|
||||
|
||||
/* adjust cnt, and maybe *o_scroll, depending of key */
|
||||
switch (key)
|
||||
@ -207,5 +213,8 @@ MARK m_scroll(m, cnt, key)
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef CRUNCH
|
||||
*o_nearscroll = savenearscroll;
|
||||
#endif
|
||||
return m;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ MARK m_fword(m, cnt, cmd, prevkey)
|
||||
*/
|
||||
if (cnt == 1L && prevkey == 'c' && isspace(*text))
|
||||
{
|
||||
return m + 1L;
|
||||
return m;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
#ifndef NULL
|
||||
#define NULL (char *)0
|
||||
#endif
|
||||
extern char *getenv();
|
||||
|
||||
/* maximum width to permit for strings, including ="" */
|
||||
#define MAXWIDTH 20
|
||||
@ -28,7 +27,7 @@ char o_autoindent[1] = {FALSE};
|
||||
char o_autoprint[1] = {TRUE};
|
||||
char o_autotab[1] = {TRUE};
|
||||
char o_autowrite[1] = {FALSE};
|
||||
char o_columns[3] = {80, 32, 255};
|
||||
char o_columns[3] = {80, 32, ~0};
|
||||
char o_directory[30] = TMPDIR;
|
||||
char o_edcompatible[1] = {FALSE};
|
||||
char o_equalprg[80] = {"fmt"};
|
||||
@ -45,7 +44,7 @@ char o_remap[1] = {TRUE};
|
||||
char o_report[3] = {5, 1, 127};
|
||||
char o_scroll[3] = {12, 1, 127};
|
||||
char o_shell[60] = SHELL;
|
||||
char o_shiftwidth[3] = {8, 1, 255};
|
||||
char o_shiftwidth[3] = {8, 1, ~0};
|
||||
char o_sidescroll[3] = {8, 1, 40};
|
||||
char o_sync[1] = {NEEDSYNC};
|
||||
char o_tabstop[3] = {8, 1, 40};
|
||||
@ -59,12 +58,14 @@ char o_beautify[1] = {FALSE};
|
||||
char o_exrc[1] = {FALSE};
|
||||
char o_mesg[1] = {TRUE};
|
||||
char o_more[1] = {TRUE};
|
||||
char o_nearscroll[3] = {15, 0, ~0};
|
||||
char o_novice[1] = {FALSE};
|
||||
char o_prompt[1] = {TRUE};
|
||||
char o_taglength[3] = {0, 0, 30};
|
||||
char o_tags[256] = {"tags"};
|
||||
char o_terse[1] = {FALSE};
|
||||
char o_window[3] = {0, 1, 24};
|
||||
char o_wrapmargin[3] = {0, 0, 255};
|
||||
char o_wrapmargin[3] = {0, 0, ~0};
|
||||
char o_writeany[1] = {FALSE};
|
||||
#endif
|
||||
|
||||
@ -123,6 +124,11 @@ char o_showmatch[1] = {FALSE};
|
||||
char o_smd[1] = {FALSE};
|
||||
#endif
|
||||
|
||||
#ifndef NO_TAGSTACK
|
||||
char o_tagstack[1] = {TRUE};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* The following describes the names & types of all options */
|
||||
#define BOOL 0
|
||||
@ -199,6 +205,7 @@ struct
|
||||
#endif
|
||||
#ifndef CRUNCH
|
||||
{ "more", "mo", BOOL, CANSET, o_more },
|
||||
{ "nearscroll", "ns", NUM, CANSET, o_nearscroll },
|
||||
{ "novice", "nov", BOOL, CANSET, o_novice },
|
||||
#endif
|
||||
{ "number", "nu", BOOL, CANSET|MR, o_number },
|
||||
@ -234,6 +241,10 @@ struct
|
||||
{ "tabstop", "ts", NUM, CANSET|MR, o_tabstop },
|
||||
#ifndef CRUNCH
|
||||
{ "taglength", "tl", NUM, CANSET, o_taglength },
|
||||
{ "tags", "tag", STR, CANSET, o_tags },
|
||||
#endif
|
||||
#ifndef NO_TAGSTACK
|
||||
{ "tagstack", "tgs", BOOL, CANSET, o_tagstack },
|
||||
#endif
|
||||
{ "term", "te", STR, SET, o_term },
|
||||
#ifndef CRUNCH
|
||||
@ -304,6 +315,7 @@ void initopts()
|
||||
{
|
||||
o_window[0] = o_window[2] = *o_lines;
|
||||
}
|
||||
*o_nearscroll = *o_lines;
|
||||
#endif
|
||||
|
||||
/* disable the flash option if we don't know how to do a flash */
|
||||
@ -685,7 +697,11 @@ void setopts(assignments)
|
||||
/* change the variable */
|
||||
if (!opts[i].name)
|
||||
{
|
||||
msg("invalid option name \"%s\"", name);
|
||||
/* only complain about unknown options if we're editing
|
||||
* a file; i.e., if we're not executing the .exrc now.
|
||||
*/
|
||||
if (tmpfd >= 0)
|
||||
msg("invalid option name \"%s\"", name);
|
||||
}
|
||||
else if ((opts[i].flags & CANSET) != CANSET)
|
||||
{
|
||||
|
@ -180,4 +180,31 @@ dbfree(ptr, file, line)
|
||||
}
|
||||
free(ptr - sizeof(long));
|
||||
}
|
||||
|
||||
dbcheckmem(file, line)
|
||||
char *file;
|
||||
int line;
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = j = 0; i < MAXALLOC && allocated[i]; i++)
|
||||
{
|
||||
if (((long *)allocated[i])[-1] != MEMMAGIC)
|
||||
{
|
||||
if (!j) endwin();
|
||||
fprintf(stderr, "\r\n%s(%d): underflowed malloc space, allocated at %s(%d)\n", file, line, fromfile[i], fromline[i]);
|
||||
j++;
|
||||
}
|
||||
if (((long *)allocated[i])[sizes[i]] != MEMMAGIC)
|
||||
{
|
||||
if (!j) endwin();
|
||||
fprintf(stderr, "\r\n%s(%d): overflowed malloc space, allocated at %s(%d)\n", file, line, fromfile[i], fromline[i]);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
if (j)
|
||||
{
|
||||
abort();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -19,6 +19,11 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "vi.h"
|
||||
#ifdef CRUNCH
|
||||
# define NEAR LINES
|
||||
#else
|
||||
# define NEAR (*o_nearscroll&0xff)
|
||||
#endif
|
||||
|
||||
/* This variable contains the line number that smartdrawtext() knows best */
|
||||
static long smartlno;
|
||||
@ -367,7 +372,7 @@ static void drawtext(text, lno, clr)
|
||||
/* show the line number, if necessary */
|
||||
if (*o_number)
|
||||
{
|
||||
sprintf(numstr, "%6ld |", lno);
|
||||
sprintf(numstr, "%6ld ", lno);
|
||||
qaddstr(numstr);
|
||||
}
|
||||
|
||||
@ -494,7 +499,7 @@ static void drawtext(text, lno, clr)
|
||||
{
|
||||
qaddch(' ');
|
||||
col++;
|
||||
} while (col < i);
|
||||
} while (col < i && col < limitcol);
|
||||
}
|
||||
else
|
||||
#endif /* !NO_VISIBLE */
|
||||
@ -522,11 +527,16 @@ static void drawtext(text, lno, clr)
|
||||
{
|
||||
qaddch(' ');
|
||||
col++;
|
||||
} while (col < i);
|
||||
} while (col < i && col < limitcol);
|
||||
}
|
||||
}
|
||||
else /* tab ending after screen? next line! */
|
||||
{
|
||||
#ifdef CRUNCH
|
||||
/* needed at least when scrolling the screen right -nox */
|
||||
if (clr && col < limitcol)
|
||||
clrtoeol();
|
||||
#endif
|
||||
col = limitcol;
|
||||
if (has_AM)
|
||||
{
|
||||
@ -798,7 +808,7 @@ static void smartdrawtext(text, lno, showit)
|
||||
/* show the line number, if necessary */
|
||||
if (*o_number)
|
||||
{
|
||||
sprintf(numstr, "%6ld |", lno);
|
||||
sprintf(numstr, "%6ld ", lno);
|
||||
qaddstr(numstr);
|
||||
}
|
||||
|
||||
@ -980,7 +990,7 @@ void redraw(curs, inputting)
|
||||
smartdrawtext(text, l, (chgs != changes));
|
||||
}
|
||||
}
|
||||
else if (l < topline && l > topline - LINES && (has_SR || has_AL))
|
||||
else if (l < topline && l >= topline - NEAR && (has_SR || has_AL))
|
||||
{
|
||||
/* near top - scroll down */
|
||||
if (!mustredraw)
|
||||
@ -1012,7 +1022,7 @@ void redraw(curs, inputting)
|
||||
redrawrange(0L, INFINITY, INFINITY);
|
||||
}
|
||||
}
|
||||
else if (l > topline && l < botline + LINES)
|
||||
else if (l > topline && l <= botline + NEAR)
|
||||
{
|
||||
/* near bottom -- scroll up */
|
||||
if (!mustredraw)
|
||||
@ -1038,12 +1048,13 @@ void redraw(curs, inputting)
|
||||
else
|
||||
{
|
||||
/* distant line - center it & force a redraw */
|
||||
topline = l - (LINES / 2) - 1;
|
||||
topline = l - (LINES - 1) / 2;
|
||||
if (topline < 1)
|
||||
{
|
||||
topline = 1;
|
||||
}
|
||||
redrawrange(0L, INFINITY, INFINITY);
|
||||
smartlno = 0L;
|
||||
changes++;
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,8 @@ static char *makeclass(text, bmap)
|
||||
int complement = 0;
|
||||
|
||||
|
||||
checkmem();
|
||||
|
||||
/* zero the bitmap */
|
||||
for (i = 0; bmap && i < 32; i++)
|
||||
{
|
||||
@ -119,7 +121,7 @@ static char *makeclass(text, bmap)
|
||||
}
|
||||
|
||||
/* add each character in the span to the bitmap */
|
||||
for (i = text[0]; bmap && i <= text[2]; i++)
|
||||
for (i = UCHAR(text[0]); bmap && (unsigned)i <= UCHAR(text[2]); i++)
|
||||
{
|
||||
bmap[i >> 3] |= (1 << (i & 7));
|
||||
}
|
||||
@ -133,7 +135,7 @@ static char *makeclass(text, bmap)
|
||||
i = *text++;
|
||||
if (bmap)
|
||||
{
|
||||
bmap[i >> 3] |= (1 << (i & 7));
|
||||
bmap[UCHAR(i) >> 3] |= (1 << (UCHAR(i) & 7));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -153,6 +155,8 @@ static char *makeclass(text, bmap)
|
||||
}
|
||||
}
|
||||
|
||||
checkmem();
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
@ -171,6 +175,10 @@ static int gettoken(sptr, re)
|
||||
int c;
|
||||
|
||||
c = **sptr;
|
||||
if (!c)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
++*sptr;
|
||||
if (c == '\\')
|
||||
{
|
||||
@ -353,21 +361,30 @@ regexp *regcomp(exp)
|
||||
int token;
|
||||
int peek;
|
||||
char *build;
|
||||
#if __STDC__
|
||||
volatile
|
||||
#endif
|
||||
regexp *re;
|
||||
#ifndef CRUNCH
|
||||
int from;
|
||||
int to;
|
||||
int digit;
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
int calced;
|
||||
#endif
|
||||
|
||||
|
||||
checkmem();
|
||||
|
||||
/* prepare for error handling */
|
||||
re = (regexp *)0;
|
||||
if (setjmp(errorhandler))
|
||||
{
|
||||
checkmem();
|
||||
if (re)
|
||||
{
|
||||
free(re);
|
||||
_free_(re);
|
||||
}
|
||||
return (regexp *)0;
|
||||
}
|
||||
@ -384,20 +401,26 @@ regexp *regcomp(exp)
|
||||
else /* non-empty regexp given, so remember it */
|
||||
{
|
||||
if (previous)
|
||||
free(previous);
|
||||
_free_(previous);
|
||||
previous = (char *)malloc((unsigned)(strlen(exp) + 1));
|
||||
if (previous)
|
||||
strcpy(previous, exp);
|
||||
}
|
||||
|
||||
/* allocate memory */
|
||||
checkmem();
|
||||
class_cnt = 0;
|
||||
start_cnt = 1;
|
||||
end_sp = 0;
|
||||
retext = exp;
|
||||
#ifdef DEBUG
|
||||
calced = calcsize(exp);
|
||||
size = calced + sizeof(regexp);
|
||||
#else
|
||||
size = calcsize(exp) + sizeof(regexp) + 10; /* !!! 10 bytes for slop */
|
||||
#endif
|
||||
#ifdef lint
|
||||
re = ((regexp *)0) + size;
|
||||
re = (regexp *)0;
|
||||
#else
|
||||
re = (regexp *)malloc((unsigned)size);
|
||||
#endif
|
||||
@ -405,6 +428,7 @@ regexp *regcomp(exp)
|
||||
{
|
||||
FAIL("Not enough memory for this RE");
|
||||
}
|
||||
checkmem();
|
||||
|
||||
/* compile it */
|
||||
build = &re->program[1 + 32 * class_cnt];
|
||||
@ -541,6 +565,7 @@ regexp *regcomp(exp)
|
||||
*build++ = token;
|
||||
}
|
||||
}
|
||||
checkmem();
|
||||
|
||||
/* end it with a \) which MUST MATCH the opening \( */
|
||||
ADD_META(build, M_END(0));
|
||||
@ -549,6 +574,15 @@ regexp *regcomp(exp)
|
||||
FAIL("Not enough \\)s");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if ((int)(build - re->program) != calced)
|
||||
{
|
||||
msg("regcomp error: calced=%d, actual=%d", calced, (int)(build - re->program));
|
||||
getkey(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
checkmem();
|
||||
return re;
|
||||
}
|
||||
|
||||
@ -577,7 +611,7 @@ int match1(re, ch, token)
|
||||
}
|
||||
else if (IS_CLASS(token))
|
||||
{
|
||||
if (re->program[1 + 32 * (token - M_CLASS(0)) + (ch >> 3)] & (1 << (ch & 7)))
|
||||
if (re->program[1 + 32 * (token - M_CLASS(0)) + (UCHAR(ch) >> 3)] & (1 << (UCHAR(ch) & 7)))
|
||||
return 0;
|
||||
}
|
||||
else if (ch == token || *o_ignorecase && tolower(ch) == tolower(token))
|
||||
@ -733,6 +767,8 @@ int regexec(re, str, bol)
|
||||
int len; /* length of the string */
|
||||
REG char *here;
|
||||
|
||||
checkmem();
|
||||
|
||||
/* if must start at the beginning of a line, and this isn't, then fail */
|
||||
if (re->bol && !bol)
|
||||
{
|
||||
@ -780,6 +816,7 @@ int regexec(re, str, bol)
|
||||
}
|
||||
|
||||
/* if we didn't fail, then we must have succeeded */
|
||||
checkmem();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@ void regsub(re, src, dst)
|
||||
}
|
||||
|
||||
/* allocate memory for the ~ed version of src */
|
||||
checkmem();
|
||||
start = cpy = (char *)malloc((unsigned)(len + 1));
|
||||
if (!cpy)
|
||||
{
|
||||
@ -94,10 +95,11 @@ void regsub(re, src, dst)
|
||||
msg("Bug in regsub.c! Predicted length = %d, Actual length = %d", len, (int)(cpy - start));
|
||||
}
|
||||
#endif
|
||||
checkmem();
|
||||
|
||||
/* remember this as the "previous" for next time */
|
||||
if (prev)
|
||||
free(prev);
|
||||
_free_(prev);
|
||||
prev = src = start;
|
||||
|
||||
#endif /* undef CRUNCH */
|
||||
|
@ -22,7 +22,9 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "vi.h"
|
||||
#ifndef XDOS
|
||||
extern char **environ;
|
||||
#endif
|
||||
|
||||
#if ANY_UNIX
|
||||
|
||||
@ -30,6 +32,9 @@ extern char **environ;
|
||||
* between this one and the library one is: this one uses the o_shell option.
|
||||
*/
|
||||
int system(cmd)
|
||||
#ifdef __STDC__
|
||||
const
|
||||
#endif
|
||||
char *cmd; /* a command to run */
|
||||
{
|
||||
int pid; /* process ID of child */
|
||||
@ -73,11 +78,7 @@ int system(cmd)
|
||||
{
|
||||
status = -1;
|
||||
}
|
||||
#if __GNUC__
|
||||
signal(SIGINT, (void (*)()) trapint);
|
||||
#else
|
||||
signal(SIGINT, trapint);
|
||||
#endif
|
||||
}
|
||||
|
||||
return status;
|
||||
@ -168,11 +169,7 @@ int rpclose(fd)
|
||||
|
||||
close(fd);
|
||||
wait(&status);
|
||||
#if __GNUC__
|
||||
signal(SIGINT, (void (*)()) trapint);
|
||||
#else
|
||||
signal(SIGINT, trapint);
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -372,13 +369,13 @@ int filter(from, to, cmd, back)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* delete old text, if any */
|
||||
if (to)
|
||||
{
|
||||
cut(from, to);
|
||||
delete(from, to);
|
||||
/* delete old text, if any */
|
||||
if (to)
|
||||
{
|
||||
cut(from, to);
|
||||
delete(from, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -14,10 +14,11 @@
|
||||
#include "vi.h"
|
||||
#include "ctype.h"
|
||||
|
||||
static int showmsg P_((void));
|
||||
|
||||
/* This function reads in a line from the terminal. */
|
||||
int vgets(prompt, buf, bsize)
|
||||
char prompt; /* the prompt character, or '\0' for none */
|
||||
int prompt; /* the prompt character, or '\0' for none */
|
||||
char *buf; /* buffer into which the string is read */
|
||||
int bsize; /* size of the buffer */
|
||||
{
|
||||
@ -57,7 +58,7 @@ int vgets(prompt, buf, bsize)
|
||||
else
|
||||
{
|
||||
/* maybe expand an abbreviation while getting key */
|
||||
for (word = len; --word >= 0 && isalnum(buf[word]); )
|
||||
for (word = len; --word >= 0 && !isspace(buf[word]); )
|
||||
{
|
||||
}
|
||||
word++;
|
||||
@ -74,8 +75,10 @@ int vgets(prompt, buf, bsize)
|
||||
#endif
|
||||
|
||||
/* some special conversions */
|
||||
#if 0
|
||||
if (ch == ctrl('D') && len == 0)
|
||||
ch = ctrl('[');
|
||||
#endif
|
||||
#ifndef NO_DIGRAPH
|
||||
if (*o_digraph && erased != 0 && ch != '\b')
|
||||
{
|
||||
@ -99,9 +102,10 @@ int vgets(prompt, buf, bsize)
|
||||
quoted = TRUE;
|
||||
break;
|
||||
|
||||
case ctrl('['):
|
||||
case ctrl('D'):
|
||||
return -1;
|
||||
|
||||
case ctrl('['):
|
||||
case '\n':
|
||||
#if OSK
|
||||
case '\l':
|
||||
@ -111,6 +115,21 @@ int vgets(prompt, buf, bsize)
|
||||
clrtoeol();
|
||||
goto BreakBreak;
|
||||
|
||||
#ifndef CRUNCH
|
||||
case ctrl('U'):
|
||||
while (len > 0)
|
||||
{
|
||||
len--;
|
||||
while (widths[len]-- > 0)
|
||||
{
|
||||
qaddch('\b');
|
||||
qaddch(' ');
|
||||
qaddch('\b');
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case '\b':
|
||||
if (len > 0)
|
||||
{
|
||||
@ -235,14 +254,24 @@ void endmsgs()
|
||||
* msg("") - clears the message line
|
||||
* msg("%s %d", ...) - does a printf onto the message line
|
||||
*/
|
||||
/*VARARGS1*/
|
||||
#ifdef __STDC__
|
||||
void msg (char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, fmt);
|
||||
#else
|
||||
void msg(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
||||
char *fmt;
|
||||
long arg1, arg2, arg3, arg4, arg5, arg6, arg7;
|
||||
{
|
||||
#endif
|
||||
if (mode != MODE_VI)
|
||||
{
|
||||
#ifdef __STDC__
|
||||
vsprintf (pmsg, fmt, ap);
|
||||
#else
|
||||
sprintf(pmsg, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
#endif
|
||||
qaddstr(pmsg);
|
||||
addch('\n');
|
||||
exrefresh();
|
||||
@ -256,12 +285,19 @@ void msg(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
||||
}
|
||||
|
||||
/* real message */
|
||||
#ifdef __STDC__
|
||||
vsprintf (pmsg, fmt, ap);
|
||||
#else
|
||||
sprintf(pmsg, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
||||
#endif
|
||||
if (*fmt)
|
||||
{
|
||||
manymsgs = TRUE;
|
||||
}
|
||||
}
|
||||
#ifdef __STDC__
|
||||
va_end (ap);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -330,7 +366,7 @@ void beep()
|
||||
}
|
||||
else if (*o_errorbells)
|
||||
{
|
||||
ttywrite("\007", 1);
|
||||
tputs("\007", 1, faddch);
|
||||
}
|
||||
|
||||
/* discard any buffered input, and abort macros */
|
||||
@ -426,6 +462,10 @@ void execmap(rawlen, cookedstr, visual)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef NO_CURSORSHAPE
|
||||
/* made global so that suspend_curses() can reset it. -nox */
|
||||
int oldcurs;
|
||||
#endif
|
||||
/* This function calls ttyread(). If necessary, it will also redraw the screen,
|
||||
* change the cursor shape, display the mode, and update the ruler. If the
|
||||
* number of characters read is 0, and we didn't time-out, then it exits because
|
||||
@ -443,9 +483,6 @@ static int fillkeybuf(when, timeout)
|
||||
static long oldnlines;
|
||||
char *str;
|
||||
#endif
|
||||
#ifndef NO_CURSORSHAPE
|
||||
static int oldcurs;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
watch();
|
||||
@ -480,7 +517,10 @@ static int fillkeybuf(when, timeout)
|
||||
redraw(cursor, !(when & WHEN_VICMD));
|
||||
|
||||
/* now the "topline" test should be valid */
|
||||
if (when != oldwhen || topline != oldtop || leftcol != oldleft || nlines != oldnlines)
|
||||
if (when != oldwhen
|
||||
|| topline != oldtop
|
||||
|| leftcol != oldleft
|
||||
|| nlines != oldnlines)
|
||||
{
|
||||
oldwhen = when;
|
||||
oldtop = topline;
|
||||
@ -490,9 +530,9 @@ static int fillkeybuf(when, timeout)
|
||||
if (when & WHEN_VICMD) str = "Command";
|
||||
else if (when & WHEN_VIINP) str = " Input ";
|
||||
else if (when & WHEN_VIREP) str = "Replace";
|
||||
else if (when & WHEN_REP1) str = " Rep 1 ";
|
||||
else if (when & WHEN_CUT) str = "BufName";
|
||||
else if (when & WHEN_MARK) str = "Mark AZ";
|
||||
else if (when & WHEN_REP1) str = "Replc 1";
|
||||
else if (when & WHEN_CUT) str = "Buffer ";
|
||||
else if (when & WHEN_MARK) str = " Mark ";
|
||||
else if (when & WHEN_CHAR) str = "Dest Ch";
|
||||
else str = (char *)0;
|
||||
|
||||
@ -539,7 +579,7 @@ static int fillkeybuf(when, timeout)
|
||||
clrtoeol();
|
||||
refresh();
|
||||
endwin();
|
||||
exit(1);
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
cend += nkeys;
|
||||
@ -592,7 +632,12 @@ static int countmatch(when)
|
||||
/* No, it wouldn't. But check for partial match */
|
||||
if (!strncmp(map->rawin, &keybuf[next], cend - next))
|
||||
{
|
||||
count++;
|
||||
/* increment by 2 instead of 1 so that, in the
|
||||
* event that we have a partial match with a
|
||||
* single map, we don't mistakenly assume we
|
||||
* have resolved the map yet.
|
||||
*/
|
||||
count += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -612,7 +657,7 @@ static void expandabbr(word, wlen)
|
||||
MAP *abbr;
|
||||
|
||||
/* if the next character wouldn't end the word, then don't expand */
|
||||
if (isalnum(keybuf[next]) || keybuf[next] == ctrl('V'))
|
||||
if (isalnum(keybuf[next]) || keybuf[next] == ctrl('V') || keybuf[next] == '\b')
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -696,7 +741,7 @@ int getabkey(when, word, wlen)
|
||||
}
|
||||
|
||||
/* try to map the key, unless already mapped and not ":set noremap" */
|
||||
if (next >= user || *o_remap)
|
||||
if (next <= user || *o_remap)
|
||||
{
|
||||
do
|
||||
{
|
||||
@ -713,6 +758,12 @@ int getabkey(when, word, wlen)
|
||||
} while (*o_remap && matches == 1);
|
||||
}
|
||||
|
||||
/* ERASEKEY should always be mapped to '\b'. */
|
||||
if (keybuf[next] == ERASEKEY)
|
||||
{
|
||||
keybuf[next] = '\b';
|
||||
}
|
||||
|
||||
#ifndef NO_ABBR
|
||||
/* try to expand an abbreviation, except in visual command mode */
|
||||
if (wlen > 0 && (mode & (WHEN_EX|WHEN_VIINP|WHEN_VIREP)) != 0)
|
||||
@ -721,12 +772,6 @@ int getabkey(when, word, wlen)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ERASEKEY should always be mapped to '\b'. */
|
||||
if (keybuf[next] == ERASEKEY)
|
||||
{
|
||||
keybuf[next] = '\b';
|
||||
}
|
||||
|
||||
/* return the next key */
|
||||
return keybuf[next++];
|
||||
}
|
||||
@ -735,7 +780,7 @@ int getabkey(when, word, wlen)
|
||||
void mapkey(rawin, cooked, when, name)
|
||||
char *rawin; /* the input key sequence, before mapping */
|
||||
char *cooked;/* after mapping -- or NULL to remove map */
|
||||
short when; /* bitmap of when mapping should happen */
|
||||
int when; /* bitmap of when mapping should happen */
|
||||
char *name; /* name of the key, NULL for no name, "abbr" for abbr */
|
||||
{
|
||||
MAP **head; /* head of list of maps or abbreviations */
|
||||
@ -751,7 +796,7 @@ void mapkey(rawin, cooked, when, name)
|
||||
|
||||
/* try to find the map in the list */
|
||||
for (scan = *head, prev = (MAP *)0;
|
||||
scan && (strcmp(rawin, scan->rawin) ||
|
||||
scan && (strcmp(rawin, scan->rawin) && strcmp(rawin, scan->cooked) ||
|
||||
!(scan->flags & when & (WHEN_EX|WHEN_VICMD|WHEN_VIINP|WHEN_VIREP)));
|
||||
prev = scan, scan = scan->next)
|
||||
{
|
||||
@ -778,7 +823,7 @@ void mapkey(rawin, cooked, when, name)
|
||||
{
|
||||
scan = (MAP *)malloc(sizeof(MAP));
|
||||
scan->len = strlen(rawin);
|
||||
scan->rawin = malloc(scan->len + 1);
|
||||
scan->rawin = malloc((unsigned)(scan->len + 1));
|
||||
strcpy(scan->rawin, rawin);
|
||||
scan->flags = when;
|
||||
scan->label = name;
|
||||
@ -794,9 +839,9 @@ void mapkey(rawin, cooked, when, name)
|
||||
}
|
||||
else /* recycle old structure */
|
||||
{
|
||||
free(scan->cooked);
|
||||
_free_(scan->cooked);
|
||||
}
|
||||
scan->cooked = malloc(strlen(cooked) + 1);
|
||||
scan->cooked = malloc((unsigned)(strlen(cooked) + 1));
|
||||
strcpy(scan->cooked, cooked);
|
||||
}
|
||||
else /* unmapping */
|
||||
@ -818,9 +863,9 @@ void mapkey(rawin, cooked, when, name)
|
||||
}
|
||||
|
||||
/* free it, and the strings that it refers to */
|
||||
free(scan->rawin);
|
||||
free(scan->cooked);
|
||||
free(scan);
|
||||
_free_(scan->rawin);
|
||||
_free_(scan->cooked);
|
||||
_free_(scan);
|
||||
}
|
||||
}
|
||||
|
||||
@ -924,7 +969,7 @@ void dumpkey(when, abbr)
|
||||
|
||||
#ifndef NO_MKEXRC
|
||||
|
||||
static safequote(str)
|
||||
static void safequote(str)
|
||||
char *str;
|
||||
{
|
||||
char *build;
|
||||
@ -949,15 +994,14 @@ static safequote(str)
|
||||
* :abbr dumpkey(WHEN_VIINP|WHEN_VIREP, TRUE);
|
||||
* :abbr! dumpkey(WHEN_EX|WHEN_VIINP|WHEN_VIREP, TRUE);
|
||||
*/
|
||||
void
|
||||
savemaps(fd, abbr)
|
||||
int fd; /* file descriptor of an open file to write to */
|
||||
int abbr; /* boolean: do abbr table? (else do map table) */
|
||||
{
|
||||
MAP *scan;
|
||||
char *str;
|
||||
int bang;
|
||||
int when;
|
||||
int len;
|
||||
|
||||
# ifndef NO_ABBR
|
||||
for (scan = (abbr ? abbrs : maps); scan; scan = scan->next)
|
||||
|
@ -5,13 +5,6 @@
|
||||
* 14407 SW Teal Blvd. #C
|
||||
* Beaverton, OR 97005
|
||||
* kirkenda@cs.pdx.edu
|
||||
*
|
||||
* PATCHES MAGIC LEVEL PATCH THAT GOT US HERE
|
||||
* -------------------- ----- ----------------------
|
||||
* CURRENT PATCH LEVEL: 1 00041
|
||||
* -------------------- ----- ----------------------
|
||||
*
|
||||
* 12 Aug 92 Bob Wilcox Fixed named yank buffer problem
|
||||
*/
|
||||
|
||||
|
||||
@ -153,11 +146,15 @@ int tmpstart(filename)
|
||||
((getuid() >> 16) == 0 ? S_IOWRITE | S_IWRITE :
|
||||
((statb.st_gid != (getuid() >> 16) ? S_IOWRITE : S_IWRITE)))))
|
||||
#endif
|
||||
#if AMIGA || MSDOS || (TOS && defined(__GNUC__))
|
||||
#if AMIGA || MSDOS
|
||||
if (*o_readonly || !(statb.st_mode & S_IWRITE))
|
||||
#endif
|
||||
#if TOS && !defined(__GNUC__)
|
||||
#if TOS
|
||||
# ifdef __GNUC__
|
||||
if (*o_readonly || !(statb.st_mode & S_IWRITE))
|
||||
# else
|
||||
if (*o_readonly || (statb.st_mode & S_IJRON))
|
||||
# endif
|
||||
#endif
|
||||
#if ANY_UNIX
|
||||
if (*o_readonly || !(statb.st_mode &
|
||||
@ -185,25 +182,36 @@ int tmpstart(filename)
|
||||
}
|
||||
|
||||
/* make a name for the tmp file */
|
||||
tmpnum++;
|
||||
#if MSDOS || TOS
|
||||
/* MS-Dos doesn't allow multiple slashes, but supports drives
|
||||
* with current directories.
|
||||
* This relies on TMPNAME beginning with "%s\\"!!!!
|
||||
*/
|
||||
strcpy(tmpname, o_directory);
|
||||
if ((i = strlen(tmpname)) && !strchr(":/\\", tmpname[i-1]))
|
||||
tmpname[i++]=SLASH;
|
||||
sprintf(tmpname+i, TMPNAME+3, getpid(), tmpnum);
|
||||
#else
|
||||
sprintf(tmpname, TMPNAME, o_directory, getpid(), tmpnum);
|
||||
#endif
|
||||
|
||||
/* make sure nobody else is editing the same file */
|
||||
if (access(tmpname, 0) == 0)
|
||||
do
|
||||
{
|
||||
FAIL("Temp file \"%s\" already exists?", tmpname);
|
||||
}
|
||||
tmpnum++;
|
||||
#if MSDOS || TOS
|
||||
/* MS-Dos doesn't allow multiple slashes, but supports drives
|
||||
* with current directories.
|
||||
* This relies on TMPNAME beginning with "%s\\"!!!!
|
||||
*/
|
||||
strcpy(tmpname, o_directory);
|
||||
if ((i = strlen(tmpname)) && !strchr(":/\\", tmpname[i-1]))
|
||||
tmpname[i++]=SLASH;
|
||||
sprintf(tmpname+i, TMPNAME+3, getpid(), tmpnum);
|
||||
#else
|
||||
sprintf(tmpname, TMPNAME, o_directory, getpid(), tmpnum);
|
||||
#endif
|
||||
} while (access(tmpname, 0) == 0);
|
||||
|
||||
/* !!! RACE CONDITION HERE - some other process with the same PID could
|
||||
* create the temp file between the access() call and the creat() call.
|
||||
* This could happen in a couple of ways:
|
||||
* - different workstation may share the same temp dir via NFS. Each
|
||||
* workstation could have a process with the same number.
|
||||
* - The DOS version may be running multiple times on the same physical
|
||||
* machine in different virtual machines. The DOS pid number will
|
||||
* be the same on all virtual machines.
|
||||
*
|
||||
* This race condition could be fixed by replacing access(tmpname, 0)
|
||||
* with open(tmpname, O_CREAT|O_EXCL, 0600), if we could only be sure
|
||||
* that open() *always* used modern UNIX semantics.
|
||||
*/
|
||||
|
||||
/* create the temp file */
|
||||
#if ANY_UNIX
|
||||
@ -219,8 +227,11 @@ int tmpstart(filename)
|
||||
}
|
||||
|
||||
/* allocate space for the header in the file */
|
||||
write(tmpfd, hdr.c, (unsigned)BLKSIZE);
|
||||
write(tmpfd, tmpblk.c, (unsigned)BLKSIZE);
|
||||
if (write(tmpfd, hdr.c, (unsigned)BLKSIZE) < BLKSIZE
|
||||
|| write(tmpfd, tmpblk.c, (unsigned)BLKSIZE) < BLKSIZE)
|
||||
{
|
||||
FAIL("Error writing headers to \"%s\"", tmpname);
|
||||
}
|
||||
|
||||
#ifndef NO_RECYCLE
|
||||
/* initialize the block allocator */
|
||||
@ -292,7 +303,7 @@ int tmpstart(filename)
|
||||
this->c[j++] = 0x80;
|
||||
}
|
||||
#ifndef CRUNCH
|
||||
else if (*o_beautify && this->c[k] < ' ' && this->c[k] > 0)
|
||||
else if (*o_beautify && this->c[k] < ' ' && this->c[k] >= 1)
|
||||
{
|
||||
if (this->c[k] == '\t'
|
||||
|| this->c[k] == '\n'
|
||||
@ -345,6 +356,10 @@ int tmpstart(filename)
|
||||
}
|
||||
|
||||
/* allocate next buffer */
|
||||
if (i >= MAXBLKS - 2)
|
||||
{
|
||||
FAIL("File too big. Limit is approx %ld kbytes.", MAXBLKS * BLKSIZE / 1024L);
|
||||
}
|
||||
next = blkget(++i);
|
||||
|
||||
/* move fragmentary last line to next buffer */
|
||||
@ -475,11 +490,7 @@ int tmpsave(filename, bang)
|
||||
}
|
||||
|
||||
/* can't rewrite a READONLY file */
|
||||
#if AMIGA
|
||||
if (!strcmp(filename, origname) && tstflag(file, READONLY) && !bang)
|
||||
#else
|
||||
if (!strcmp(filename, origname) && *o_readonly && !bang)
|
||||
#endif
|
||||
{
|
||||
msg("\"%s\" [READONLY] -- NOT WRITTEN", filename);
|
||||
return FALSE;
|
||||
@ -552,6 +563,10 @@ int tmpsave(filename, bang)
|
||||
/* reset the "modified" flag, but not the "undoable" flag */
|
||||
clrflag(file, MODIFIED);
|
||||
significant = FALSE;
|
||||
if (!strcmp(origname, filename))
|
||||
{
|
||||
exitcode &= ~1;
|
||||
}
|
||||
|
||||
/* report lines & characters */
|
||||
#if MSDOS || TOS
|
||||
@ -601,11 +616,6 @@ int tmpabort(bang)
|
||||
blkinit();
|
||||
nlines = 0;
|
||||
initflags();
|
||||
#ifdef BROKEN_YANK_BUFFERS /* 12 Aug 92*/
|
||||
close(tmpfd);
|
||||
tmpfd = -1;
|
||||
unlink(tmpname);
|
||||
#endif /* BROKEN_YANK_BUFFERS*/
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -652,6 +662,7 @@ sync()
|
||||
* to store the arguments to a command, so we can't use it here. Instead,
|
||||
* we'll borrow the buffer that is used for "shift-U".
|
||||
*/
|
||||
int
|
||||
storename(name)
|
||||
char *name; /* the name of the file - normally origname */
|
||||
{
|
||||
@ -669,7 +680,11 @@ storename(name)
|
||||
U_text[1] = 127;
|
||||
}
|
||||
#ifndef CRUNCH
|
||||
# if TOS || MINT || MSDOS || AMIGA
|
||||
else if (*name != '/' && *name != '\\' && !(*name && name[1] == ':'))
|
||||
# else
|
||||
else if (*name != SLASH)
|
||||
# endif
|
||||
{
|
||||
/* get the directory name */
|
||||
ptr = getcwd(U_text, BLKSIZE);
|
||||
@ -696,7 +711,10 @@ storename(name)
|
||||
{
|
||||
/* write the name out to second block of the temp file */
|
||||
lseek(tmpfd, (long)BLKSIZE, 0);
|
||||
write(tmpfd, U_text, (unsigned)BLKSIZE);
|
||||
if (write(tmpfd, U_text, (unsigned)BLKSIZE) < BLKSIZE)
|
||||
{
|
||||
FAIL("Error stuffing name \"%s\" into temp file", U_text);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -706,7 +724,7 @@ storename(name)
|
||||
/* This function handles deadly signals. It restores sanity to the terminal
|
||||
* preserves the current temp file, and deletes any old temp files.
|
||||
*/
|
||||
int deathtrap(sig)
|
||||
SIGTYPE deathtrap(sig)
|
||||
int sig; /* the deadly signal that we caught */
|
||||
{
|
||||
char *why;
|
||||
@ -730,8 +748,10 @@ int deathtrap(sig)
|
||||
# ifdef SIGBUS
|
||||
case SIGBUS: why = "-Elvis had a bus error"; break;
|
||||
# endif
|
||||
# if defined(SIGSEGV) && !defined(TOS)
|
||||
# ifdef SIGSEGV
|
||||
# if !TOS
|
||||
case SIGSEGV: why = "-Elvis had a segmentation violation"; break;
|
||||
# endif
|
||||
# endif
|
||||
# ifdef SIGSYS
|
||||
case SIGSYS: why = "-Elvis munged a system call"; break;
|
||||
|
@ -79,6 +79,9 @@ int ttyread(buf, len, time)
|
||||
case -1: /* assume we got an EINTR because of SIGWINCH */
|
||||
if (*o_lines != LINES || *o_columns != COLS)
|
||||
{
|
||||
#ifndef CRUNCH
|
||||
*o_nearscroll =
|
||||
#endif
|
||||
*o_lines = LINES;
|
||||
*o_columns = COLS;
|
||||
#ifndef CRUNCH
|
||||
@ -106,10 +109,10 @@ int ttyread(buf, len, time)
|
||||
}
|
||||
# else
|
||||
|
||||
# if M_SYSV
|
||||
/* For System-V or Coherent, we use VMIN/VTIME to implement the timeout.
|
||||
* For no timeout, VMIN should be 1 and VTIME should be 0; for timeout,
|
||||
* VMIN should be 0 and VTIME should be the timeout value.
|
||||
# if UNIXV || COH_386
|
||||
/* For System-V, we use VMIN/VTIME to implement the timeout. For no timeout,
|
||||
* VMIN should be 1 and VTIME should be 0; for timeout, VMIN should be 0 and
|
||||
* VTIME should be the timeout value.
|
||||
*/
|
||||
# include <termio.h>
|
||||
int ttyread(buf, len, time)
|
||||
@ -135,7 +138,7 @@ int ttyread(buf, len, time)
|
||||
ioctl(0, TCSETA, &tio);
|
||||
|
||||
/* Perform the read. Loop if EINTR error happens */
|
||||
while ((bytes = read(0, buf, len)) < 0)
|
||||
while ((bytes = read(0, buf, (unsigned)len)) < 0)
|
||||
{
|
||||
/* probably EINTR error because a SIGWINCH was received */
|
||||
if (*o_lines != LINES || *o_columns != COLS)
|
||||
@ -145,6 +148,7 @@ int ttyread(buf, len, time)
|
||||
#ifndef CRUNCH
|
||||
if (!wset)
|
||||
{
|
||||
*o_nearscroll = LINES;
|
||||
*o_window = LINES - 1;
|
||||
}
|
||||
#endif
|
||||
@ -178,7 +182,7 @@ int ttyread(buf, len, time)
|
||||
static jmp_buf env;
|
||||
|
||||
/*ARGSUSED*/
|
||||
int dummy(signo)
|
||||
SIGTYPE dummy(signo)
|
||||
int signo;
|
||||
{
|
||||
longjmp(env, 1);
|
||||
@ -189,17 +193,13 @@ int ttyread(buf, len, time)
|
||||
int time; /* maximum time to allow for reading */
|
||||
{
|
||||
/* arrange for timeout */
|
||||
#if __GNUC__
|
||||
signal(SIGALRM, (void (*)()) dummy);
|
||||
#else
|
||||
signal(SIGALRM, dummy);
|
||||
#endif
|
||||
alarm(time);
|
||||
|
||||
/* perform the blocking read */
|
||||
if (setjmp(env) == 0)
|
||||
{
|
||||
len = read(0, buf, len);
|
||||
len = read(0, buf, (unsigned)len);
|
||||
}
|
||||
else /* I guess we timed out */
|
||||
{
|
||||
@ -216,7 +216,7 @@ int ttyread(buf, len, time)
|
||||
return len;
|
||||
}
|
||||
|
||||
# endif /* !(M_SYSV || COHERENT) */
|
||||
# endif /* M_SYSV */
|
||||
# endif /* !BSD */
|
||||
|
||||
#endif /* ANY_UNIX */
|
||||
|
@ -51,6 +51,7 @@ int bavar; /* used only in BeforeAfter macros */
|
||||
/* used to detect changes that invalidate cached text/blocks */
|
||||
long changes; /* incremented when file is changed */
|
||||
int significant; /* boolean: was a *REAL* change made? */
|
||||
int exitcode = 1; /* 0=overwritten, 1=not updated, else error */
|
||||
|
||||
/* used to support the pfetch() macro */
|
||||
int plen; /* length of the line */
|
||||
|
@ -264,7 +264,7 @@ MARK v_overtype(m)
|
||||
/* Normally, we input starting here, in replace mode */
|
||||
ChangeText
|
||||
{
|
||||
end = input(m, m, WHEN_VIREP, FALSE);
|
||||
end = input(m, m, WHEN_VIREP, 0);
|
||||
}
|
||||
|
||||
/* if we ended on the same line we started on, then this
|
||||
@ -361,14 +361,13 @@ MARK v_insert(m, cnt, key)
|
||||
{
|
||||
int wasdot;
|
||||
long reps;
|
||||
int above; /* boolean: new line going above old line? */
|
||||
int delta = 0;/* 1 to take autoindent from line below, -1 for above */
|
||||
|
||||
DEFAULT(1);
|
||||
|
||||
ChangeText
|
||||
{
|
||||
/* tweak the insertion point, based on command key */
|
||||
above = FALSE;
|
||||
switch (key)
|
||||
{
|
||||
case 'i':
|
||||
@ -394,19 +393,20 @@ MARK v_insert(m, cnt, key)
|
||||
case 'O':
|
||||
m &= ~(BLKSIZE - 1);
|
||||
add(m, "\n");
|
||||
above = TRUE;
|
||||
delta = 1;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
m = (m & ~(BLKSIZE - 1)) + BLKSIZE;
|
||||
add(m, "\n");
|
||||
delta = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* insert the same text once or more */
|
||||
for (reps = cnt, wasdot = doingdot; reps > 0; reps--, doingdot = TRUE)
|
||||
{
|
||||
m = input(m, m, WHEN_VIINP, above) + 1;
|
||||
m = input(m, m, WHEN_VIINP, delta) + 1;
|
||||
}
|
||||
if (markidx(m) > 0)
|
||||
{
|
||||
@ -455,7 +455,7 @@ MARK v_change(m, n)
|
||||
ChangeText
|
||||
{
|
||||
cut(m, n);
|
||||
m = input(m, n, WHEN_VIINP, FALSE);
|
||||
m = input(m, n, WHEN_VIINP, 0);
|
||||
}
|
||||
|
||||
return m;
|
||||
@ -479,7 +479,7 @@ MARK v_subst(m, cnt)
|
||||
ChangeText
|
||||
{
|
||||
cut(m, m + cnt);
|
||||
m = input(m, m + cnt, WHEN_VIINP, FALSE);
|
||||
m = input(m, m + cnt, WHEN_VIINP, 0);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
@ -964,12 +964,24 @@ MARK v_popup(m, n)
|
||||
break;
|
||||
}
|
||||
|
||||
/* arrange for the menu to be erased (except that "chg from kbd"
|
||||
* already erased it, and "save & exit" doesn't care)
|
||||
/* arrange for the menu to be erased (except "save & exit" doesn't care)
|
||||
*/
|
||||
if (sel != 5 && sel != 9)
|
||||
if (mode == MODE_VI)
|
||||
redraw(MARK_UNSET, FALSE);
|
||||
|
||||
return m;
|
||||
}
|
||||
#endif /* undef NO_POPUP */
|
||||
|
||||
#ifndef NO_TAGSTACK
|
||||
MARK v_pop(m, cnt, cmd)
|
||||
MARK m; /* original cursor position (ignored) */
|
||||
long cnt; /* number of levels to pop */
|
||||
int cmd; /* command key -- ^T (ignored) */
|
||||
{
|
||||
DEFAULT(1L);
|
||||
sprintf(tmpblk.c, "%ld", cnt);
|
||||
cmd_pop(m, m, CMD_POP, FALSE, tmpblk.c);
|
||||
return cursor;
|
||||
}
|
||||
#endif
|
||||
|
@ -73,7 +73,11 @@ static struct keystru
|
||||
/* ^Q not defined */ {NO_FUNC, NO_ARGS, NO_FLAGS},
|
||||
/* ^R redraw screen */ {v_redraw, NO_ARGS, NO_FLAGS|VIZ},
|
||||
/* ^S not defined */ {NO_FUNC, NO_ARGS, NO_FLAGS},
|
||||
#ifndef NO_TAGSTACK
|
||||
/* ^T pop tagstack */ {v_pop, CURSOR, NO_FLAGS},
|
||||
#else
|
||||
/* ^T not defined */ {NO_FUNC, NO_ARGS, NO_FLAGS},
|
||||
#endif
|
||||
/* ^U scroll up 1/2page*/ {m_scroll, CURSOR, NCOL|VIZ},
|
||||
/* ^V not defined */ {NO_FUNC, NO_ARGS, NO_FLAGS},
|
||||
/* ^W not defined */ {NO_FUNC, NO_ARGS, NO_FLAGS},
|
||||
@ -87,7 +91,7 @@ static struct keystru
|
||||
/* ESC not defined */ {NO_FUNC, NO_ARGS, NO_FLAGS},
|
||||
/* ^\ not defined */ {NO_FUNC, NO_ARGS, NO_FLAGS},
|
||||
/* ^] keyword is tag */ {v_tag, KEYWORD, NO_FLAGS},
|
||||
/* ^^ previous file */ {v_switch, CURSOR, NO_FLAGS},
|
||||
/* ^^ previous file */ {v_switch, CURSOR, FRNT},
|
||||
/* ^_ not defined */ {NO_FUNC, NO_ARGS, NO_FLAGS},
|
||||
/* SPC move right,like l*/ {m_right, CURSOR, MVMT|INCL|VIZ},
|
||||
/* ! run thru filter */ {v_filter, CURSOR_MOVED, FRNT|LNMD|INCL|VIZ},
|
||||
@ -168,7 +172,7 @@ static struct keystru
|
||||
#endif
|
||||
/* L move to last row */ {m_row, CURSOR, MVMT|LNMD|FRNT|VIZ|INCL},
|
||||
/* M move to mid row */ {m_row, CURSOR, MVMT|LNMD|FRNT|VIZ|INCL},
|
||||
/* N reverse prev srch*/ {m_Nsrch, CURSOR, MVMT|NREL|VIZ},
|
||||
/* N reverse prev srch*/ {m_nsrch, CURSOR, MVMT|NREL|VIZ},
|
||||
/* O insert above line*/ {v_insert, CURSOR, SDOT},
|
||||
/* P paste before */ {v_paste, CURSOR, SDOT},
|
||||
/* Q quit to EX mode */ {v_quit, NO_ARGS, NO_FLAGS},
|
||||
@ -185,7 +189,7 @@ static struct keystru
|
||||
#else
|
||||
/* V not defined */ {NO_FUNC, NO_ARGS, NO_FLAGS},
|
||||
#endif
|
||||
/* W move forward Word*/ {m_fword, CURSOR, MVMT|INCL|VIZ},
|
||||
/* W move forward Word*/ {m_fword, CURSOR, MVMT|INCL|NWRP|VIZ},
|
||||
/* X delete to left */ {v_xchar, CURSOR, SDOT},
|
||||
/* Y yank text */ {v_yank, CURSOR_MOVED, NCOL},
|
||||
/* Z save file & exit */ {v_xit, CURSOR_CNT_KEY, NO_FLAGS},
|
||||
@ -233,13 +237,13 @@ static struct keystru
|
||||
#else
|
||||
/* v not defined */ {NO_FUNC, NO_ARGS, NO_FLAGS},
|
||||
#endif
|
||||
/* w move fwd word */ {m_fword, CURSOR, MVMT|INCL|VIZ},
|
||||
/* w move fwd word */ {m_fword, CURSOR, MVMT|INCL|NWRP|VIZ},
|
||||
/* x delete character */ {v_xchar, CURSOR, SDOT},
|
||||
/* y yank text */ {v_yank, CURSOR_MOVED, NCOL|VIZ},
|
||||
/* z adjust scrn row */ {m_z, CURSOR_CNT_KEY, NCOL|VIZ},
|
||||
/* { back paragraph */ {m_paragraph, CURSOR, MVMT|LNMD|VIZ},
|
||||
/* { back paragraph */ {m_paragraph, CURSOR, MVMT|VIZ},
|
||||
/* | move to column */ {m_tocol, CURSOR, MVMT|NREL|VIZ},
|
||||
/* } fwd paragraph */ {m_paragraph, CURSOR, MVMT|LNMD|VIZ},
|
||||
/* } fwd paragraph */ {m_paragraph, CURSOR, MVMT|VIZ},
|
||||
/* ~ upper/lowercase */ {v_ulcase, CURSOR, SDOT},
|
||||
/* DEL not defined */ {NO_FUNC, NO_ARGS, NO_FLAGS}
|
||||
};
|
||||
@ -316,6 +320,9 @@ void vi()
|
||||
key = getkey(WHEN_VICMD);
|
||||
} while (key < 0 || key > 127);
|
||||
}
|
||||
#ifdef DEBUG2
|
||||
debout("\nkey='%c'\n", key);
|
||||
#endif
|
||||
|
||||
/* Convert a doubled-up operator such as "dd" into "d_" */
|
||||
if (prevkey && key == prevkey)
|
||||
@ -551,7 +558,8 @@ void vi()
|
||||
do
|
||||
{
|
||||
text[0] = key;
|
||||
if (vgets(key, text + 1, sizeof text - 1) >= 0)
|
||||
text[1] = '\0';
|
||||
if (doingdot || vgets(key, text + 1, sizeof text - 1) >= 0)
|
||||
{
|
||||
/* reassure user that <CR> was hit */
|
||||
qaddch('\r');
|
||||
@ -583,16 +591,25 @@ void vi()
|
||||
}
|
||||
|
||||
/* now move the cursor, as appropriate */
|
||||
if (keyptr->args == CURSOR_MOVED)
|
||||
if (prevkey && ((keyptr->flags & MVMT)
|
||||
#ifndef NO_VISIBLE
|
||||
|| V_from
|
||||
#endif
|
||||
) && count == 0L)
|
||||
{
|
||||
/* movements used as targets are less strict */
|
||||
tcurs = adjmove(cursor, tcurs, (int)(keyptr->flags | force_flags));
|
||||
}
|
||||
else if (keyptr->args == CURSOR_MOVED)
|
||||
{
|
||||
/* the < and > keys have FRNT,
|
||||
* but it shouldn't be applied yet
|
||||
*/
|
||||
tcurs = adjmove(cursor, tcurs, 0);
|
||||
tcurs = adjmove(cursor, tcurs, FINL);
|
||||
}
|
||||
else
|
||||
{
|
||||
tcurs = adjmove(cursor, tcurs, (int)keyptr->flags | force_flags);
|
||||
tcurs = adjmove(cursor, tcurs, (int)(keyptr->flags | force_flags | FINL));
|
||||
}
|
||||
|
||||
/* was that the end of a d/c/y/</>/! command? */
|
||||
@ -629,7 +646,7 @@ void vi()
|
||||
* to the front of a line. Instead, they should take
|
||||
* us only to the end of the preceding line.
|
||||
*/
|
||||
if ((keyptr->flags & (MVMT|NREL|LNMD|FRNT|INCL)) == MVMT
|
||||
if ((keyptr->flags & NWRP) == NWRP
|
||||
&& markline(range) < markline(tcurs)
|
||||
&& (markline(tcurs) > nlines || tcurs == m_front(tcurs, 0L)))
|
||||
{
|
||||
@ -660,8 +677,8 @@ void vi()
|
||||
tcurs = (*vikeys[prevkey].func)(range, tcurs);
|
||||
if (mode == MODE_VI)
|
||||
{
|
||||
(void)adjmove(cursor, cursor, 0);
|
||||
cursor = adjmove(cursor, tcurs, (int)vikeys[prevkey].flags);
|
||||
(void)adjmove(cursor, cursor, FINL);
|
||||
cursor = adjmove(cursor, tcurs, (int)(vikeys[prevkey].flags | FINL));
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
@ -688,6 +705,9 @@ MARK adjmove(old, new, flags)
|
||||
REG char *text; /* used to scan through the line's text */
|
||||
REG int i;
|
||||
|
||||
#ifdef DEBUG2
|
||||
debout("adjmove(%ld.%d, %ld.%d, 0x%x)\n", markline(old), markidx(old), markline(new), markidx(new), flags);
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
watch();
|
||||
#endif
|
||||
@ -695,8 +715,12 @@ MARK adjmove(old, new, flags)
|
||||
/* if the command failed, bag it! */
|
||||
if (new == MARK_UNSET)
|
||||
{
|
||||
beep();
|
||||
return old;
|
||||
if (flags & FINL)
|
||||
{
|
||||
beep();
|
||||
return old;
|
||||
}
|
||||
return new;
|
||||
}
|
||||
|
||||
/* if this is a non-relative movement, set the '' mark */
|
||||
@ -712,6 +736,10 @@ MARK adjmove(old, new, flags)
|
||||
}
|
||||
else if (markline(new) > nlines)
|
||||
{
|
||||
if (!(flags & FINL))
|
||||
{
|
||||
return MARK_EOF;
|
||||
}
|
||||
new = MARK_LAST;
|
||||
}
|
||||
|
||||
|
@ -7,13 +7,14 @@
|
||||
* kirkenda@cs.pdx.edu
|
||||
*/
|
||||
|
||||
#define VERSION "ELVIS 1.5, by Steve Kirkendall (23 March 1992)"
|
||||
#define VERSION "ELVIS 1.7, by Steve Kirkendall (30 December 1992)"
|
||||
#define COPYING "This version of ELVIS is freely redistributable."
|
||||
|
||||
#include <errno.h>
|
||||
extern int errno;
|
||||
#if TOS && !defined(__GNUC__)
|
||||
#define ENOENT (-AEFILNF)
|
||||
#if TOS
|
||||
# ifndef __GNUC__
|
||||
# define ENOENT (-AEFILNF)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if TOS || VMS
|
||||
@ -33,8 +34,10 @@ extern int errno;
|
||||
# define ENOENT E_PNNF
|
||||
# define sprintf Sprintf
|
||||
# else
|
||||
# include <sys/types.h>
|
||||
# if COHERENT
|
||||
# if !AMIGA
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# if COH_286
|
||||
# include <sys/fcntl.h>
|
||||
# else
|
||||
# include <fcntl.h>
|
||||
@ -49,6 +52,16 @@ extern int errno;
|
||||
#include "curses.h"
|
||||
|
||||
#include <signal.h>
|
||||
#ifdef __STDC__
|
||||
# include <stdio.h> /* for [v]sprintf prototype */
|
||||
# include <string.h> /* for str* prototypes */
|
||||
# include <stdlib.h> /* for atoi, system, malloc, free */
|
||||
# include <stdarg.h> /* for vararg definitions */
|
||||
# if ANY_UNIX
|
||||
# include <unistd.h> /* for read, write, ... prototypes */
|
||||
# include <sys/wait.h> /* for wait prototype */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Miscellaneous constants. */
|
||||
@ -74,8 +87,8 @@ typedef union
|
||||
/* These are used manipulate BLK buffers. */
|
||||
|
||||
extern BLK hdr; /* buffer for the header block */
|
||||
extern BLK *blkget(); /* given index into hdr.c[], reads block */
|
||||
extern BLK *blkadd(); /* inserts a new block into hdr.c[] */
|
||||
extern BLK *blkget P_((int)); /* given index into hdr.c[], reads block */
|
||||
extern BLK *blkadd P_((int)); /* inserts a new block into hdr.c[] */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* These are used to keep track of various flags */
|
||||
@ -138,9 +151,11 @@ extern char o_beautify[1];
|
||||
extern char o_exrc[1];
|
||||
extern char o_mesg[1];
|
||||
extern char o_more[1];
|
||||
extern char o_nearscroll[3];
|
||||
extern char o_novice[1];
|
||||
extern char o_prompt[1];
|
||||
extern char o_taglength[3];
|
||||
extern char o_tags[256];
|
||||
extern char o_terse[1];
|
||||
extern char o_window[3];
|
||||
extern char o_wrapmargin[3];
|
||||
@ -195,6 +210,10 @@ extern char o_showmatch[1];
|
||||
extern char o_smd[1];
|
||||
#endif
|
||||
|
||||
#ifndef NO_TAGSTACK
|
||||
extern char o_tagstack[1];
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* These help support the single-line multi-change "undo" -- shift-U */
|
||||
|
||||
@ -210,6 +229,7 @@ typedef long MARK;
|
||||
#define MARK_UNSET ((MARK)0)
|
||||
#define MARK_FIRST ((MARK)BLKSIZE)
|
||||
#define MARK_LAST ((MARK)(nlines * BLKSIZE))
|
||||
#define MARK_EOF ((MARK)((nlines + 1) * BLKSIZE))
|
||||
#define MARK_AT_LINE(x) ((MARK)(x) * BLKSIZE)
|
||||
|
||||
#define NMARKS 29
|
||||
@ -227,78 +247,101 @@ extern long prevline; /* line number from preceding file */
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* misc housekeeping variables & functions */
|
||||
|
||||
extern int tmpfd; /* fd used to access the tmp file */
|
||||
extern int tmpnum; /* counter used to generate unique filenames */
|
||||
extern long lnum[MAXBLKS]; /* last line# of each block */
|
||||
extern long nlines; /* number of lines in the file */
|
||||
extern char args[BLKSIZE]; /* file names given on the command line */
|
||||
extern int argno; /* the current element of args[] */
|
||||
extern int nargs; /* number of filenames in args */
|
||||
extern long changes; /* counts changes, to prohibit short-cuts */
|
||||
extern int significant; /* boolean: was a *REAL* change made? */
|
||||
extern BLK tmpblk; /* a block used to accumulate changes */
|
||||
extern long topline; /* file line number of top line */
|
||||
extern int leftcol; /* column number of left col */
|
||||
extern int tmpfd; /* fd used to access the tmp file */
|
||||
extern int tmpnum; /* counter used to generate unique filenames */
|
||||
extern long lnum[MAXBLKS]; /* last line# of each block */
|
||||
extern long nlines; /* number of lines in the file */
|
||||
extern char args[BLKSIZE]; /* file names given on the command line */
|
||||
extern int argno; /* the current element of args[] */
|
||||
extern int nargs; /* number of filenames in args */
|
||||
extern long changes; /* counts changes, to prohibit short-cuts */
|
||||
extern int significant; /* boolean: was a *REAL* change made? */
|
||||
extern int exitcode; /* 0=not updated, 1=overwritten, else error */
|
||||
extern BLK tmpblk; /* a block used to accumulate changes */
|
||||
extern long topline; /* file line number of top line */
|
||||
extern int leftcol; /* column number of left col */
|
||||
#define botline (topline + LINES - 2)
|
||||
#define rightcol (leftcol + COLS - (*o_number ? 9 : 1))
|
||||
extern int physcol; /* physical column number that cursor is on */
|
||||
extern int physrow; /* physical row number that cursor is on */
|
||||
extern int exwrote; /* used to detect verbose ex commands */
|
||||
extern int doingdot; /* boolean: are we doing the "." command? */
|
||||
extern int doingglobal; /* boolean: are doing a ":g" command? */
|
||||
extern long rptlines; /* number of lines affected by a command */
|
||||
extern char *rptlabel; /* description of how lines were affected */
|
||||
extern char *fetchline(); /* read a given line from tmp file */
|
||||
extern char *parseptrn(); /* isolate a regexp in a line */
|
||||
extern MARK paste(); /* paste from cut buffer to a given point */
|
||||
extern char *wildcard(); /* expand wildcards in filenames */
|
||||
extern MARK input(); /* inserts characters from keyboard */
|
||||
extern char *linespec(); /* finds the end of a /regexp/ string */
|
||||
extern int physcol; /* physical column number that cursor is on */
|
||||
extern int physrow; /* physical row number that cursor is on */
|
||||
extern int exwrote; /* used to detect verbose ex commands */
|
||||
extern int doingdot; /* boolean: are we doing the "." command? */
|
||||
extern int doingglobal; /* boolean: are doing a ":g" command? */
|
||||
extern long rptlines; /* number of lines affected by a command */
|
||||
extern char *rptlabel; /* description of how lines were affected */
|
||||
extern char *fetchline P_((long)); /* read a given line from tmp file */
|
||||
extern char *parseptrn P_((REG char *)); /* isolate a regexp in a line */
|
||||
extern MARK paste P_((MARK, int, int)); /* paste from cut buffer to a given point */
|
||||
extern char *wildcard P_((char *)); /* expand wildcards in filenames */
|
||||
extern MARK input P_((MARK, MARK, int, int)); /* inserts characters from keyboard */
|
||||
extern char *linespec P_((REG char *, MARK *)); /* finds the end of a /regexp/ string */
|
||||
#define ctrl(ch) ((ch)&037)
|
||||
#ifndef NO_RECYCLE
|
||||
extern long allocate(); /* allocate a free block of the tmp file */
|
||||
extern long allocate P_((void)); /* allocate a free block of the tmp file */
|
||||
#endif
|
||||
extern int trapint(); /* trap handler for SIGINT */
|
||||
extern int deathtrap(); /* trap handler for deadly signals */
|
||||
extern void blkdirty(); /* marks a block as being "dirty" */
|
||||
extern void blkflush(); /* writes a single dirty block to the disk */
|
||||
extern void blksync(); /* forces all "dirty" blocks to disk */
|
||||
extern void blkinit(); /* resets the block cache to "empty" state */
|
||||
extern void beep(); /* rings the terminal's bell */
|
||||
extern void exrefresh(); /* writes text to the screen */
|
||||
extern void msg(); /* writes a printf-style message to the screen */
|
||||
extern void endmsgs(); /* if "manymsgs" is set, then scroll up 1 line */
|
||||
extern void garbage(); /* reclaims any garbage blocks */
|
||||
extern void redraw(); /* updates the screen after a change */
|
||||
extern void resume_curses();/* puts the terminal in "cbreak" mode */
|
||||
extern void beforedo(); /* saves current revision before a new change */
|
||||
extern void afterdo(); /* marks end of a beforedo() change */
|
||||
extern void abortdo(); /* like "afterdo()" followed by "undo()" */
|
||||
extern int undo(); /* restores file to previous undo() */
|
||||
extern void dumpkey(); /* lists key mappings to the screen */
|
||||
extern void mapkey(); /* defines a new key mapping */
|
||||
extern void savekeys(); /* lists key mappings to a file */
|
||||
extern void redrawrange(); /* records clues from modify.c */
|
||||
extern void cut(); /* saves text in a cut buffer */
|
||||
extern void delete(); /* deletes text */
|
||||
extern void add(); /* adds text */
|
||||
extern void change(); /* deletes text, and then adds other text */
|
||||
extern void cutswitch(); /* updates cut buffers when we switch files */
|
||||
extern void do_abbr(); /* defines or lists abbreviations */
|
||||
extern void do_digraph(); /* defines or lists digraphs */
|
||||
extern void exstring(); /* execute a string as EX commands */
|
||||
extern void dumpopts();
|
||||
extern void setopts();
|
||||
extern void saveopts();
|
||||
extern void savedigs();
|
||||
extern void saveabbr();
|
||||
extern void savecolor();
|
||||
extern void cutname();
|
||||
extern void cutname();
|
||||
extern void initopts();
|
||||
extern void cutend();
|
||||
extern SIGTYPE trapint P_((int)); /* trap handler for SIGINT */
|
||||
extern SIGTYPE deathtrap P_((int)); /* trap handler for deadly signals */
|
||||
extern void blkdirty P_((BLK *)); /* marks a block as being "dirty" */
|
||||
extern void blksync P_((void)); /* forces all "dirty" blocks to disk */
|
||||
extern void blkinit P_((void)); /* resets the block cache to "empty" state */
|
||||
extern void beep P_((void)); /* rings the terminal's bell */
|
||||
extern void exrefresh P_((void)); /* writes text to the screen */
|
||||
#ifdef __STDC__
|
||||
extern void msg (char *, ...); /* writes a printf-style message to the screen */
|
||||
#else
|
||||
extern void msg (); /* writes a printf-style message to the screen */
|
||||
#endif
|
||||
extern void endmsgs P_((void)); /* if "manymsgs" is set, then scroll up 1 line */
|
||||
extern void garbage P_((void)); /* reclaims any garbage blocks */
|
||||
extern void redraw P_((MARK, int)); /* updates the screen after a change */
|
||||
extern void resume_curses P_((int)); /* puts the terminal in "cbreak" mode */
|
||||
extern void beforedo P_((int)); /* saves current revision before a new change */
|
||||
extern void afterdo P_((void)); /* marks end of a beforedo() change */
|
||||
extern void abortdo P_((void)); /* like "afterdo()" followed by "undo()" */
|
||||
extern int undo P_((void)); /* restores file to previous undo() */
|
||||
extern void dumpkey P_((int, int)); /* lists key mappings to the screen */
|
||||
extern void mapkey P_((char *, char *, int, char *)); /* defines a new key mapping */
|
||||
extern void redrawrange P_((long, long, long)); /* records clues from modify.c */
|
||||
extern void cut P_((MARK, MARK)); /* saves text in a cut buffer */
|
||||
extern void delete P_((MARK, MARK)); /* deletes text */
|
||||
extern void add P_((MARK, char *)); /* adds text */
|
||||
extern void change P_((MARK, MARK, char *));/* deletes text, and then adds other text */
|
||||
extern void cutswitch P_((void)); /* updates cut buffers when we switch files */
|
||||
extern void do_digraph P_((int, char [])); /* defines or lists digraphs */
|
||||
extern void exstring P_((char *, int, int));/* execute a string as EX commands */
|
||||
extern void dumpopts P_((int)); /* display current option settings on the screen */
|
||||
extern void setopts P_((char *)); /* assign new values to options */
|
||||
extern void saveopts P_((int)); /* save current option values to a given fd */
|
||||
extern void savedigs P_((int)); /* save current non-standard digraphs to fd */
|
||||
extern void savecolor P_((int)); /* save current color settings (if any) to fd */
|
||||
extern void cutname P_((int)); /* select cut buffer for next cut/paste */
|
||||
extern void initopts P_((void)); /* initialize options */
|
||||
extern void cutend P_((void)); /* free all cut buffers & delete temp files */
|
||||
extern int storename P_((char *)); /* stamp temp file with pathname of text file */
|
||||
extern int tmpstart P_((char *)); /* load a text file into edit buffer */
|
||||
extern int tmpsave P_((char *, int)); /* write edit buffer out to text file */
|
||||
extern int tmpend P_((int)); /* call tmpsave(), and then tmpabort */
|
||||
extern int tmpabort P_((int)); /* abandon the current edit buffer */
|
||||
extern void savemaps P_((int, int)); /* write current :map or :ab commands to fd */
|
||||
extern int ansicolor P_((int, int)); /* emit ANSI color command to terminal */
|
||||
extern int filter P_((MARK, MARK, char *, int)); /* I/O though another program */
|
||||
extern int getkey P_((int)); /* return a keystroke, interpretting maps */
|
||||
extern int vgets P_((int, char *, int)); /* read a single line from keyboard */
|
||||
extern int doexrc P_((char *)); /* execute a string as a sequence of EX commands */
|
||||
extern int cb2str P_((int, char *, unsigned));/* return a string containing cut buffer's contents */
|
||||
extern int ansiquit P_((void)); /* neutralize previous ansicolor() call */
|
||||
extern int ttyread P_((char *, int, int)); /* read from keyboard with optional timeout */
|
||||
extern int tgetent P_((char *, char *)); /* start termcap */
|
||||
extern int tgetnum P_((char *)); /* get a termcap number */
|
||||
extern int tgetflag P_((char *)); /* get a termcap boolean */
|
||||
extern int getsize P_((int)); /* determine how big the screen is */
|
||||
extern int endcolor P_((void)); /* used during color output */
|
||||
extern int getabkey P_((int, char *, int));/* like getkey(), but also does abbreviations */
|
||||
extern int idx2col P_((MARK, REG char *, int)); /* returns column# of a given MARK */
|
||||
extern int cutneeds P_((BLK *)); /* returns bitmap of blocks needed to hold cutbuffer text */
|
||||
extern void execmap P_((int, char *, int)); /* replaces "raw" keys with "mapped" keys */
|
||||
#ifndef CRUNCH
|
||||
extern int wset; /* boolean: has the "window" size been set? */
|
||||
extern int wset; /* boolean: has the "window" size been set? */
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
@ -313,42 +356,41 @@ extern int bavar; /* used only in BeforeAfter macros */
|
||||
/* These are the movement commands. Each accepts a mark for the starting */
|
||||
/* location & number and returns a mark for the destination. */
|
||||
|
||||
extern MARK m_updnto(); /* k j G */
|
||||
extern MARK m_right(); /* h */
|
||||
extern MARK m_left(); /* l */
|
||||
extern MARK m_tocol(); /* | */
|
||||
extern MARK m_front(); /* ^ */
|
||||
extern MARK m_rear(); /* $ */
|
||||
extern MARK m_fword(); /* w */
|
||||
extern MARK m_bword(); /* b */
|
||||
extern MARK m_eword(); /* e */
|
||||
extern MARK m_paragraph(); /* { } [[ ]] */
|
||||
extern MARK m_match(); /* % */
|
||||
extern MARK m_updnto P_((MARK, long, int)); /* k j G */
|
||||
extern MARK m_right P_((MARK, long, int, int)); /* h */
|
||||
extern MARK m_left P_((MARK, long)); /* l */
|
||||
extern MARK m_tocol P_((MARK, long, int)); /* | */
|
||||
extern MARK m_front P_((MARK, long)); /* ^ */
|
||||
extern MARK m_rear P_((MARK, long)); /* $ */
|
||||
extern MARK m_fword P_((MARK, long, int, int)); /* w */
|
||||
extern MARK m_bword P_((MARK, long, int)); /* b */
|
||||
extern MARK m_eword P_((MARK, long, int)); /* e */
|
||||
extern MARK m_paragraph P_((MARK, long, int)); /* { } [[ ]] */
|
||||
extern MARK m_match P_((MARK, long)); /* % */
|
||||
#ifndef NO_SENTENCE
|
||||
extern MARK m_sentence(); /* ( ) */
|
||||
extern MARK m_sentence P_((MARK, long, int)); /* ( ) */
|
||||
#endif
|
||||
extern MARK m_tomark(); /* 'm */
|
||||
extern MARK m_tomark P_((MARK, long, int)); /* 'm */
|
||||
#ifndef NO_EXTENSIONS
|
||||
extern MARK m_wsrch(); /* ^A */
|
||||
extern MARK m_wsrch P_((char *, MARK, int)); /* ^A */
|
||||
#endif
|
||||
extern MARK m_nsrch(); /* n */
|
||||
extern MARK m_Nsrch(); /* N */
|
||||
extern MARK m_fsrch(); /* /regexp */
|
||||
extern MARK m_bsrch(); /* ?regexp */
|
||||
extern MARK m_nsrch P_((MARK, long, int)); /* n */
|
||||
extern MARK m_fsrch P_((MARK, char *)); /* /regexp */
|
||||
extern MARK m_bsrch P_((MARK, char *)); /* ?regexp */
|
||||
#ifndef NO_CHARSEARCH
|
||||
extern MARK m__ch(); /* ; , */
|
||||
extern MARK m_fch(); /* f */
|
||||
extern MARK m_tch(); /* t */
|
||||
extern MARK m_Fch(); /* F */
|
||||
extern MARK m_Tch(); /* T */
|
||||
extern MARK m__ch P_((MARK, long, int)); /* ; , */
|
||||
extern MARK m_fch P_((MARK, long, int)); /* f */
|
||||
extern MARK m_tch P_((MARK, long, int)); /* t */
|
||||
extern MARK m_Fch P_((MARK, long, int)); /* F */
|
||||
extern MARK m_Tch P_((MARK, long, int)); /* T */
|
||||
#endif
|
||||
extern MARK m_row(); /* H L M */
|
||||
extern MARK m_z(); /* z */
|
||||
extern MARK m_scroll(); /* ^B ^F ^E ^Y ^U ^D */
|
||||
extern MARK m_row P_((MARK, long, int)); /* H L M */
|
||||
extern MARK m_z P_((MARK, long, int)); /* z */
|
||||
extern MARK m_scroll P_((MARK, long, int)); /* ^B ^F ^E ^Y ^U ^D */
|
||||
|
||||
/* Some stuff that is used by movement functions... */
|
||||
|
||||
extern MARK adjmove(); /* a helper fn, used by move fns */
|
||||
extern MARK adjmove P_((MARK, REG MARK, int)); /* a helper fn, used by move fns */
|
||||
|
||||
/* This macro is used to set the default value of cnt */
|
||||
#define DEFAULT(val) if (cnt < 1) cnt = (val)
|
||||
@ -358,8 +400,8 @@ extern int plen; /* length of the line */
|
||||
extern long pline; /* line number that len refers to */
|
||||
extern long pchgs; /* "changes" level that len refers to */
|
||||
extern char *ptext; /* text of previous line, if valid */
|
||||
extern void pfetch();
|
||||
extern char digraph();
|
||||
extern void pfetch P_((long));
|
||||
extern char digraph P_((int, int));
|
||||
|
||||
/* This is used to build a MARK that corresponds to a specific point in the
|
||||
* line that was most recently pfetch'ed.
|
||||
@ -370,169 +412,174 @@ extern char digraph();
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* These are used to handle EX commands. */
|
||||
|
||||
#define CMD_NULL 0 /* NOT A VALID COMMAND */
|
||||
#define CMD_ABBR 1 /* "define an abbreviation" */
|
||||
#define CMD_ARGS 2 /* "show me the args" */
|
||||
#define CMD_APPEND 3 /* "insert lines after this line" */
|
||||
#define CMD_AT 4 /* "execute a cut buffer's contents via EX" */
|
||||
#define CMD_BANG 5 /* "run a single shell command" */
|
||||
#define CMD_CC 6 /* "run `cc` and then do CMD_ERRLIST" */
|
||||
#define CMD_CD 7 /* "change directories" */
|
||||
#define CMD_CHANGE 8 /* "change some lines" */
|
||||
#define CMD_COLOR 9 /* "change the default colors" */
|
||||
#define CMD_COPY 10 /* "copy the selected text to a given place" */
|
||||
#define CMD_DELETE 11 /* "delete the selected text" */
|
||||
#define CMD_DIGRAPH 12 /* "add a digraph, or display them all" */
|
||||
#define CMD_EDIT 13 /* "switch to a different file" */
|
||||
#define CMD_EQUAL 14 /* "display a line number" */
|
||||
#define CMD_ERRLIST 15 /* "locate the next error in a list" */
|
||||
#define CMD_FILE 16 /* "show the file's status" */
|
||||
#define CMD_GLOBAL 17 /* "globally search & do a command" */
|
||||
#define CMD_INSERT 18 /* "insert lines before the current line" */
|
||||
#define CMD_JOIN 19 /* "join the selected line & the one after" */
|
||||
#define CMD_LIST 20 /* "print lines, making control chars visible" */
|
||||
#define CMD_MAKE 21 /* "run `make` and then do CMD_ERRLIST" */
|
||||
#define CMD_MAP 22 /* "adjust the keyboard map" */
|
||||
#define CMD_MARK 23 /* "mark this line" */
|
||||
#define CMD_MKEXRC 24 /* "make a .exrc file" */
|
||||
#define CMD_MOVE 25 /* "move the selected text to a given place" */
|
||||
#define CMD_NEXT 26 /* "switch to next file in args" */
|
||||
#define CMD_NUMBER 27 /* "print lines from the file w/ line numbers" */
|
||||
#define CMD_PRESERVE 28 /* "act as though vi crashed" */
|
||||
#define CMD_PREVIOUS 29 /* "switch to the previous file in args" */
|
||||
#define CMD_PRINT 30 /* "print the selected text" */
|
||||
#define CMD_PUT 31 /* "insert any cut lines before this line" */
|
||||
#define CMD_QUIT 32 /* "quit without writing the file" */
|
||||
#define CMD_READ 33 /* "append the given file after this line */
|
||||
#define CMD_RECOVER 34 /* "recover file after vi crashes" - USE -r FLAG */
|
||||
#define CMD_REWIND 35 /* "rewind to first file" */
|
||||
#define CMD_SET 36 /* "set a variable's value" */
|
||||
#define CMD_SHELL 37 /* "run some lines through a command" */
|
||||
#define CMD_SHIFTL 38 /* "shift lines left" */
|
||||
#define CMD_SHIFTR 39 /* "shift lines right" */
|
||||
#define CMD_SOURCE 40 /* "interpret a file's contents as ex commands" */
|
||||
#define CMD_STOP 41 /* same as CMD_SUSPEND */
|
||||
#define CMD_SUBAGAIN 42 /* "repeat the previous substitution" */
|
||||
#define CMD_SUBSTITUTE 43 /* "substitute text in this line" */
|
||||
#define CMD_SUSPEND 44 /* "suspend the vi session" */
|
||||
#define CMD_TR 45 /* "transliterate chars in the selected lines" */
|
||||
#define CMD_TAG 46 /* "go to a particular tag" */
|
||||
#define CMD_UNABBR 47 /* "remove an abbreviation definition" */
|
||||
#define CMD_UNDO 48 /* "undo the previous command" */
|
||||
#define CMD_UNMAP 49 /* "remove a key sequence map */
|
||||
#define CMD_VERSION 50 /* "describe which version this is" */
|
||||
#define CMD_VGLOBAL 51 /* "apply a cmd to lines NOT containing an RE" */
|
||||
#define CMD_VISUAL 52 /* "go into visual mode" */
|
||||
#define CMD_WQUIT 53 /* "write this file out (any case) & quit" */
|
||||
#define CMD_WRITE 54 /* "write the selected(?) text to a given file" */
|
||||
#define CMD_XIT 55 /* "write this file out (if modified) & quit" */
|
||||
#define CMD_YANK 56 /* "copy the selected text into the cut buffer" */
|
||||
#ifdef DEBUG
|
||||
# define CMD_DEBUG 57 /* access to internal data structures */
|
||||
# define CMD_VALIDATE 58 /* check for internal consistency */
|
||||
#endif
|
||||
#define CMD_NULL 0 /* NOT A VALID COMMAND */
|
||||
#define CMD_ABBR 1 /* "define an abbreviation" */
|
||||
#define CMD_ARGS 2 /* "show me the args" */
|
||||
#define CMD_APPEND 3 /* "insert lines after this line" */
|
||||
#define CMD_AT 4 /* "execute a cut buffer's contents via EX" */
|
||||
#define CMD_BANG 5 /* "run a single shell command" */
|
||||
#define CMD_CC 6 /* "run `cc` and then do CMD_ERRLIST" */
|
||||
#define CMD_CD 7 /* "change directories" */
|
||||
#define CMD_CHANGE 8 /* "change some lines" */
|
||||
#define CMD_COLOR 9 /* "change the default colors" */
|
||||
#define CMD_COPY 10 /* "copy the selected text to a given place" */
|
||||
#define CMD_DELETE 11 /* "delete the selected text" */
|
||||
#define CMD_DIGRAPH 12 /* "add a digraph, or display them all" */
|
||||
#define CMD_EDIT 13 /* "switch to a different file" */
|
||||
#define CMD_EQUAL 14 /* "display a line number" */
|
||||
#define CMD_ERRLIST 15 /* "locate the next error in a list" */
|
||||
#define CMD_FILE 16 /* "show the file's status" */
|
||||
#define CMD_GLOBAL 17 /* "globally search & do a command" */
|
||||
#define CMD_INSERT 18 /* "insert lines before the current line" */
|
||||
#define CMD_JOIN 19 /* "join the selected line & the one after" */
|
||||
#define CMD_LIST 20 /* "print lines, making control chars visible" */
|
||||
#define CMD_MAKE 21 /* "run `make` and then do CMD_ERRLIST" */
|
||||
#define CMD_MAP 22 /* "adjust the keyboard map" */
|
||||
#define CMD_MARK 23 /* "mark this line" */
|
||||
#define CMD_MKEXRC 24 /* "make a .exrc file" */
|
||||
#define CMD_MOVE 25 /* "move the selected text to a given place" */
|
||||
#define CMD_NEXT 26 /* "switch to next file in args" */
|
||||
#define CMD_NUMBER 27 /* "print lines from the file w/ line numbers" */
|
||||
#define CMD_POP 28 /* "pop a position off the tagstack" */
|
||||
#define CMD_PRESERVE 29 /* "act as though vi crashed" */
|
||||
#define CMD_PREVIOUS 30 /* "switch to the previous file in args" */
|
||||
#define CMD_PRINT 31 /* "print the selected text" */
|
||||
#define CMD_PUT 32 /* "insert any cut lines before this line" */
|
||||
#define CMD_QUIT 33 /* "quit without writing the file" */
|
||||
#define CMD_READ 34 /* "append the given file after this line */
|
||||
#define CMD_RECOVER 35 /* "recover file after vi crashes" - USE -r FLAG */
|
||||
#define CMD_REWIND 36 /* "rewind to first file" */
|
||||
#define CMD_SET 37 /* "set a variable's value" */
|
||||
#define CMD_SHELL 38 /* "run some lines through a command" */
|
||||
#define CMD_SHIFTL 39 /* "shift lines left" */
|
||||
#define CMD_SHIFTR 40 /* "shift lines right" */
|
||||
#define CMD_SOURCE 41 /* "interpret a file's contents as ex commands" */
|
||||
#define CMD_STOP 42 /* same as CMD_SUSPEND */
|
||||
#define CMD_SUBAGAIN 43 /* "repeat the previous substitution" */
|
||||
#define CMD_SUBSTITUTE 44 /* "substitute text in this line" */
|
||||
#define CMD_SUSPEND 45 /* "suspend the vi session" */
|
||||
#define CMD_TR 46 /* "transliterate chars in the selected lines" */
|
||||
#define CMD_TAG 47 /* "go to a particular tag" */
|
||||
#define CMD_UNABBR 48 /* "remove an abbreviation definition" */
|
||||
#define CMD_UNDO 49 /* "undo the previous command" */
|
||||
#define CMD_UNMAP 50 /* "remove a key sequence map */
|
||||
#define CMD_VERSION 51 /* "describe which version this is" */
|
||||
#define CMD_VGLOBAL 52 /* "apply a cmd to lines NOT containing an RE" */
|
||||
#define CMD_VISUAL 53 /* "go into visual mode" */
|
||||
#define CMD_WQUIT 54 /* "write this file out (any case) & quit" */
|
||||
#define CMD_WRITE 55 /* "write the selected(?) text to a given file" */
|
||||
#define CMD_XIT 56 /* "write this file out (if modified) & quit" */
|
||||
#define CMD_YANK 57 /* "copy the selected text into the cut buffer" */
|
||||
#define CMD_DEBUG 58 /* access to internal data structures */
|
||||
#define CMD_VALIDATE 59 /* check for internal consistency */
|
||||
typedef int CMD;
|
||||
|
||||
extern void ex();
|
||||
extern void vi();
|
||||
extern void doexcmd();
|
||||
extern void ex P_((void));
|
||||
extern void vi P_((void));
|
||||
extern void doexcmd P_((char *));
|
||||
|
||||
extern void cmd_append();
|
||||
extern void cmd_args();
|
||||
extern void cmd_append P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_args P_((MARK, MARK, CMD, int, char *));
|
||||
#ifndef NO_AT
|
||||
extern void cmd_at();
|
||||
extern void cmd_at P_((MARK, MARK, CMD, int, char *));
|
||||
#endif
|
||||
extern void cmd_cd();
|
||||
extern void cmd_cd P_((MARK, MARK, CMD, int, char *));
|
||||
#ifndef NO_COLOR
|
||||
extern void cmd_color();
|
||||
extern void cmd_color P_((MARK, MARK, CMD, int, char *));
|
||||
#endif
|
||||
extern void cmd_delete();
|
||||
extern void cmd_delete P_((MARK, MARK, CMD, int, char *));
|
||||
#ifndef NO_DIGRAPH
|
||||
extern void cmd_digraph();
|
||||
extern void cmd_digraph P_((MARK, MARK, CMD, int, char *));
|
||||
#endif
|
||||
extern void cmd_edit();
|
||||
extern void cmd_edit P_((MARK, MARK, CMD, int, char *));
|
||||
#ifndef NO_ERRLIST
|
||||
extern void cmd_errlist();
|
||||
extern void cmd_errlist P_((MARK, MARK, CMD, int, char *));
|
||||
#endif
|
||||
extern void cmd_file();
|
||||
extern void cmd_global();
|
||||
extern void cmd_join();
|
||||
extern void cmd_mark();
|
||||
extern void cmd_file P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_global P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_join P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_mark P_((MARK, MARK, CMD, int, char *));
|
||||
#ifndef NO_ERRLIST
|
||||
extern void cmd_make();
|
||||
extern void cmd_make P_((MARK, MARK, CMD, int, char *));
|
||||
#endif
|
||||
extern void cmd_map();
|
||||
extern void cmd_map P_((MARK, MARK, CMD, int, char *));
|
||||
#ifndef NO_MKEXRC
|
||||
extern void cmd_mkexrc();
|
||||
extern void cmd_mkexrc P_((MARK, MARK, CMD, int, char *));
|
||||
#endif
|
||||
extern void cmd_next();
|
||||
extern void cmd_print();
|
||||
extern void cmd_put();
|
||||
extern void cmd_read();
|
||||
extern void cmd_set();
|
||||
extern void cmd_shell();
|
||||
extern void cmd_shift();
|
||||
extern void cmd_source();
|
||||
extern void cmd_substitute();
|
||||
extern void cmd_tag();
|
||||
extern void cmd_undo();
|
||||
extern void cmd_version();
|
||||
extern void cmd_write();
|
||||
extern void cmd_xit();
|
||||
extern void cmd_move();
|
||||
extern void cmd_next P_((MARK, MARK, CMD, int, char *));
|
||||
#ifndef NO_TAGSTACK
|
||||
extern void cmd_pop P_((MARK, MARK, CMD, int, char *));
|
||||
#endif
|
||||
extern void cmd_print P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_put P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_read P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_set P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_shell P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_shift P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_source P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_substitute P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_tag P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_undo P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_version P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_write P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_xit P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_move P_((MARK, MARK, CMD, int, char *));
|
||||
#ifdef DEBUG
|
||||
extern void cmd_debug();
|
||||
extern void cmd_validate();
|
||||
extern void cmd_debug P_((MARK, MARK, CMD, int, char *));
|
||||
extern void cmd_validate P_((MARK, MARK, CMD, int, char *));
|
||||
#endif
|
||||
#ifdef SIGTSTP
|
||||
extern void cmd_suspend();
|
||||
extern void cmd_suspend P_((MARK, MARK, CMD, int, char *));
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* These are used to handle VI commands */
|
||||
|
||||
extern MARK v_1ex(); /* : */
|
||||
extern MARK v_mark(); /* m */
|
||||
extern MARK v_quit(); /* Q */
|
||||
extern MARK v_redraw(); /* ^L ^R */
|
||||
extern MARK v_ulcase(); /* ~ */
|
||||
extern MARK v_undo(); /* u */
|
||||
extern MARK v_xchar(); /* x X */
|
||||
extern MARK v_replace(); /* r */
|
||||
extern MARK v_overtype(); /* R */
|
||||
extern MARK v_selcut(); /* " */
|
||||
extern MARK v_paste(); /* p P */
|
||||
extern MARK v_yank(); /* y Y */
|
||||
extern MARK v_delete(); /* d D */
|
||||
extern MARK v_join(); /* J */
|
||||
extern MARK v_insert(); /* a A i I o O */
|
||||
extern MARK v_change(); /* c C */
|
||||
extern MARK v_subst(); /* s */
|
||||
extern MARK v_lshift(); /* < */
|
||||
extern MARK v_rshift(); /* > */
|
||||
extern MARK v_reformat(); /* = */
|
||||
extern MARK v_filter(); /* ! */
|
||||
extern MARK v_status(); /* ^G */
|
||||
extern MARK v_switch(); /* ^^ */
|
||||
extern MARK v_tag(); /* ^] */
|
||||
extern MARK v_xit(); /* ZZ */
|
||||
extern MARK v_undoline(); /* U */
|
||||
extern MARK v_again(); /* & */
|
||||
extern MARK v_1ex P_((MARK, char *)); /* : */
|
||||
extern MARK v_mark P_((MARK, long, int)); /* m */
|
||||
extern MARK v_quit P_((void)); /* Q */
|
||||
extern MARK v_redraw P_((void)); /* ^L ^R */
|
||||
extern MARK v_ulcase P_((MARK, long)); /* ~ */
|
||||
extern MARK v_undo P_((MARK)); /* u */
|
||||
extern MARK v_xchar P_((MARK, long, int)); /* x X */
|
||||
extern MARK v_replace P_((MARK, long, int));/* r */
|
||||
extern MARK v_overtype P_((MARK)); /* R */
|
||||
extern MARK v_selcut P_((MARK, long, int)); /* " */
|
||||
extern MARK v_paste P_((MARK, long, int)); /* p P */
|
||||
extern MARK v_yank P_((MARK, MARK)); /* y Y */
|
||||
extern MARK v_delete P_((MARK, MARK)); /* d D */
|
||||
extern MARK v_join P_((MARK, long)); /* J */
|
||||
extern MARK v_insert P_((MARK, long, int)); /* a A i I o O */
|
||||
extern MARK v_change P_((MARK, MARK)); /* c C */
|
||||
extern MARK v_subst P_((MARK, long)); /* s */
|
||||
extern MARK v_lshift P_((MARK, MARK)); /* < */
|
||||
extern MARK v_rshift P_((MARK, MARK)); /* > */
|
||||
extern MARK v_reformat P_((MARK, MARK)); /* = */
|
||||
extern MARK v_filter P_((MARK, MARK)); /* ! */
|
||||
extern MARK v_status P_((void)); /* ^G */
|
||||
extern MARK v_switch P_((void)); /* ^^ */
|
||||
extern MARK v_tag P_((char *, MARK, long)); /* ^] */
|
||||
extern MARK v_xit P_((MARK, long, int)); /* ZZ */
|
||||
extern MARK v_undoline P_((MARK)); /* U */
|
||||
extern MARK v_again P_((MARK, MARK)); /* & */
|
||||
#ifndef NO_EXTENSIONS
|
||||
extern MARK v_keyword(); /* K */
|
||||
extern MARK v_increment(); /* * */
|
||||
extern MARK v_keyword P_((char *, MARK, long)); /* K */
|
||||
extern MARK v_increment P_((char *, MARK, long)); /* * */
|
||||
#endif
|
||||
#ifndef NO_ERRLIST
|
||||
extern MARK v_errlist(); /* * */
|
||||
extern MARK v_errlist P_((MARK)); /* * */
|
||||
#endif
|
||||
#ifndef NO_AT
|
||||
extern MARK v_at(); /* @ */
|
||||
extern MARK v_at P_((MARK, long, int)); /* @ */
|
||||
#endif
|
||||
#ifdef SIGTSTP
|
||||
extern MARK v_suspend(); /* ^Z */
|
||||
extern MARK v_suspend P_((void)); /* ^Z */
|
||||
#endif
|
||||
#ifndef NO_POPUP
|
||||
extern MARK v_popup(); /* \ */
|
||||
extern MARK v_popup P_((MARK, MARK)); /* \ */
|
||||
#endif
|
||||
#ifndef NO_TAGSTACK
|
||||
extern MARK v_pop P_((MARK, long, int)); /* ^T */
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
@ -546,8 +593,10 @@ extern MARK v_again(); /* & */
|
||||
#define NCOL 0x20 /* this command can't change the column# */
|
||||
#define NREL 0x40 /* this is "non-relative" -- set the '' mark */
|
||||
#define SDOT 0x80 /* set the "dot" variables, for the "." cmd */
|
||||
#define FINL 0x100 /* final testing, more strict! */
|
||||
#define NWRP 0x200 /* no line-wrap (used for 'w' and 'W') */
|
||||
#ifndef NO_VISIBLE
|
||||
# define VIZ 0x100 /* commands which can be used with 'v' */
|
||||
# define VIZ 0x400 /* commands which can be used with 'v' */
|
||||
#else
|
||||
# define VIZ 0
|
||||
#endif
|
||||
@ -586,11 +635,14 @@ extern int mode;
|
||||
#ifndef NO_VISIBLE
|
||||
extern MARK V_from;
|
||||
extern int V_linemd;
|
||||
extern MARK v_start();
|
||||
extern MARK v_start P_((MARK m, long cnt, int cmd));
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
# define malloc(size) dbmalloc(size, __FILE__, __LINE__)
|
||||
# define free(ptr) dbfree(ptr, __FILE__, __LINE__)
|
||||
extern char *dbmalloc();
|
||||
# define checkmem() dbcheckmem(__FILE__, __LINE__)
|
||||
extern char *dbmalloc P_((int, char *, int));
|
||||
#else
|
||||
# define checkmem()
|
||||
#endif
|
||||
|
@ -14,6 +14,10 @@
|
||||
#include "config.h"
|
||||
#include "vi.h"
|
||||
|
||||
void recover P_((char *, char *));
|
||||
void main P_((int, char **));
|
||||
|
||||
|
||||
void recover(basename, outname)
|
||||
char *basename; /* the name of the file to recover */
|
||||
char *outname; /* the name of the file to write to */
|
||||
@ -164,6 +168,7 @@ void recover(basename, outname)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
@ -172,7 +177,7 @@ main(argc, argv)
|
||||
if (argc > 3)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [preserved_file [recovery_file]]\n", argv[0]);
|
||||
exit(1);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/* recover the requested file, or list recoverable files */
|
||||
|
7
usr.bin/ref/Makefile
Normal file
7
usr.bin/ref/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
PROG= ref
|
||||
CFLAGS+=-I${.CURDIR}/../elvis
|
||||
SRCS= ref.c
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
.PATH: ${.CURDIR}/../elvis
|
88
usr.bin/ref/ref.1
Normal file
88
usr.bin/ref/ref.1
Normal file
@ -0,0 +1,88 @@
|
||||
.TH REF 1
|
||||
.SH NAME
|
||||
ref - Display a C function header
|
||||
.SH SYNOPSIS
|
||||
\fBref\fR [-t] [-c \fIclass\fR]... [-f \fIfile\fR]... \fItag\fR
|
||||
.SH DESCRIPTION
|
||||
\fIref\fP quickly locates and displays the header of a function.
|
||||
To do this, \fIref\fR
|
||||
looks in the "tags" file for the line that describes the function, and then
|
||||
scans the source file for the function.
|
||||
When it locates the function, it displays an introductory comment
|
||||
(if there is one), the function's declaration, and the declarations of all
|
||||
arguments.
|
||||
.SH "SEARCH METHOD"
|
||||
.PP
|
||||
\fIref\fR uses a fairly sophisticated tag look-up algorithm.
|
||||
If you supply a filename via \fB-f\fR \fIfile\fR, then elvis first scans
|
||||
the tags file for a static tag from that file.
|
||||
This search is limited to the tags file in the current directory.
|
||||
.PP
|
||||
If you supply a classname via \fB-c\fR \fIclass\fR, then elvis searches
|
||||
for a tag from that class.
|
||||
This search is not limited to the current directory;
|
||||
You can supply a list of directories in the environment variable \fITAGPATH\fR,
|
||||
and \fIref\fR will search through the "tags" file in each directory until it finds
|
||||
a tag in the desired class.
|
||||
.PP
|
||||
If that fails, \fIref\fR will then try to look up an ordinary global tag.
|
||||
This search checks all of the directories listed in \fITAGPATH\fR, too.
|
||||
.PP
|
||||
If you've given the \fB-t\fR flag, then \fIref\fR will simply output the tag line that
|
||||
it found, and then exit.
|
||||
Without \fB-t\fR, though, \fIref\fR will search for the tag line.
|
||||
It will try to open the source file, which should be in the same directory
|
||||
as the tags file where the tag was discovered.
|
||||
If the source file doesn't exist, or is unreadable, then \fIref\fR will try to open
|
||||
a file called "\fIrefs\fR" in that directory.
|
||||
Either way, \fIref\fR will try to locate the tag, and display whatever it finds.
|
||||
.SH "INTERACTION WITH ELVIS"
|
||||
.PP
|
||||
\fIref\fP is used by \fIelvis\fR' shift-K command.
|
||||
If the cursor is located on a word such as "splat", in the file "foo.c",
|
||||
then \fIelvis\fR will invoke \fIref\fR with the command "ref -f foo.c splat".
|
||||
.PP
|
||||
If \fIelvis\fR has been compiled with the -DEXTERNAL_TAGS flag, then \fIelvis\fR will
|
||||
use \fIref\fR \fB\fRto scan the tags files.
|
||||
This is slower than the built-in tag searching, but it allows \fIelvis\fR to access
|
||||
the more sophisticated tag lookup provided by \fIref\fR.
|
||||
Other than that, external tags should act exactly like internal tags.
|
||||
.SH OPTIONS
|
||||
.IP \fB-t\fR
|
||||
Output tag info, instead of the function header.
|
||||
.IP "\fB-f\fR \fIfile\fR"
|
||||
The tag might be a static function in \fIfile\fR.
|
||||
You can use several -f flags to have \fIref\fR consider static tags from more than one file.
|
||||
.IP "\fB-c\fR \fIclass\fR"
|
||||
The tag might be a member of class \fIclass\fR.
|
||||
You can use several -c flags to have \fIref\fR consider tags from more than one class.
|
||||
.SH FILES
|
||||
.IP \fBtags\fR
|
||||
List of function names and their locations, generated by \fIctags\fR.
|
||||
.IP \fBrefs\fR
|
||||
Function headers extracted from source files (optional).
|
||||
.SH ENVIRONMENT
|
||||
.IP \fBTAGPATH\fR
|
||||
List of directories to be searched.
|
||||
The elements in the list are separated by either
|
||||
semicolons (for MS-DOS, Atari TOS, and AmigaDos), or
|
||||
by colons (every other operating system).
|
||||
For each operating system, \fIref\fR has a built-in default which is probably
|
||||
adequate.
|
||||
.SH NOTES
|
||||
.PP
|
||||
You might want to generate a "tags" file the directory that contains the
|
||||
source code for standard C library on your system.
|
||||
If licensing restrictions prevent you from making the library source readable
|
||||
by everybody, then you can have \fIctags\fR generate a "refs" file,
|
||||
and make "refs" readable by everybody.
|
||||
.PP
|
||||
If your system doesn't come with the library source code, then perhaps you
|
||||
can produce something workable from the \fIlint\fR libraries.
|
||||
.SH "SEE ALSO"
|
||||
elvis(1), ctags(1)
|
||||
.SH AUTHOR
|
||||
.nf
|
||||
Steve Kirkendall
|
||||
kirkenda@cs.pdx.edu
|
||||
.fi
|
550
usr.bin/ref/ref.c
Normal file
550
usr.bin/ref/ref.c
Normal file
@ -0,0 +1,550 @@
|
||||
/* ref2.c */
|
||||
|
||||
/* This is a totally rewritten version of ref. This version looks for the
|
||||
* desired function name in the "tags" file, and then reads the header out
|
||||
* from the source file. There is no longer any need for a "refs" file.
|
||||
*
|
||||
* Usage: ref [-t] [-f file] [-c class] tag
|
||||
* Options: -t output tag info, not the description
|
||||
* -f file default filename for static functions
|
||||
* -c class default class names for class functions
|
||||
*/
|
||||
#ifdef __STDC__
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "config.h"
|
||||
|
||||
extern char *cktagdir P_((char *, char *));
|
||||
extern int getline P_((char *, int, FILE *));
|
||||
extern int lookup P_((char *, char *));
|
||||
extern int find P_((char *));
|
||||
extern void usage P_((void));
|
||||
extern int countcolons P_((char *));
|
||||
extern void main P_((int, char **));
|
||||
|
||||
|
||||
/* This is the default path that is searched for tags */
|
||||
#if OSK
|
||||
# define DEFTAGPATH ".:/dd/defs:/dd/defs/sys:/dd/usr/src/lib:../lib:/dd/usr/lib"
|
||||
#else
|
||||
# if ANY_UNIX
|
||||
# define DEFTAGPATH ".:/usr/include:/usr/include/sys:/usr/src/lib:../lib:/usr/local/lib"
|
||||
# else
|
||||
# if MSDOS || TOS
|
||||
# define DEFTAGPATH ".;C:\\include;C:\\include\\sys;C:\\lib;..\\lib"
|
||||
# define SEP ';'
|
||||
# else
|
||||
# if AMIGA
|
||||
# define DEFTAGPATH ".;Include:;Include:sys"
|
||||
# define SEP ';'
|
||||
# else /* any other OS */
|
||||
# define DEFTAGPATH "."
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef SEP
|
||||
# define SEP ':'
|
||||
#endif
|
||||
|
||||
|
||||
/* These variables reflect the command-line options given by the user. */
|
||||
int taginfo; /* boolean: give only the tag info? (not header?) */
|
||||
char *def_file; /* default filename for static functions */
|
||||
char *def_class; /* default classname for class members */
|
||||
int colons; /* #colons in tag: 0=normal, 1=static, 2=member */
|
||||
|
||||
/* This function checks for a tag in the "tags" file of given directory.
|
||||
* If the tag is found, then it returns a pointer to a static buffer which
|
||||
* contains the filename, a tab character, and a linespec for finding the
|
||||
* the tag. If the tag is not found in the "tags" file, or if the "tags"
|
||||
* file cannot be opened or doesn't exist, then this function returns NULL.
|
||||
*/
|
||||
char *cktagdir(tag, dir)
|
||||
char *tag; /* name of the tag to look for */
|
||||
char *dir; /* name of the directory to check */
|
||||
{
|
||||
char buf[BLKSIZE];
|
||||
static char found[BLKSIZE];
|
||||
FILE *tfile;
|
||||
int len;
|
||||
|
||||
#if AMIGA
|
||||
if (dir[strlen(dir) - 1] == COLON)
|
||||
sprintf(buf, "%s%s", dir, TAGS); /* no slash after colon. */
|
||||
else
|
||||
#endif
|
||||
/* construct the name of the "tags" file in this directory */
|
||||
sprintf(buf, "%s%c%s", dir, SLASH, TAGS);
|
||||
|
||||
/* Try to open the tags file. Return NULL if can't open */
|
||||
#if AMIGA
|
||||
if (buf[0] == '.' && buf[1] == SLASH)
|
||||
tfile = fopen(&buf[2], "r");
|
||||
else
|
||||
#endif
|
||||
tfile = fopen(buf, "r");
|
||||
if (!tfile)
|
||||
{
|
||||
return (char *)0;
|
||||
}
|
||||
|
||||
/* compute the length of the tagname once */
|
||||
len = strlen(tag);
|
||||
|
||||
/* read lines until we get the one for this tag */
|
||||
found[0] = '\0';
|
||||
while (fgets(buf, sizeof buf, tfile))
|
||||
{
|
||||
/* is this the one we want? */
|
||||
if (!strncmp(buf, tag, len) && buf[len] == '\t')
|
||||
{
|
||||
/* we've found a match -- remember it */
|
||||
strcpy(found, buf);
|
||||
|
||||
/* if there is no default file, or this match is in
|
||||
* the default file, then we've definitely found the
|
||||
* one we want. Break out of the loop now.
|
||||
*/
|
||||
if (!def_file || !strncmp(&buf[len + 1], def_file, strlen(def_file)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* we're through reading */
|
||||
fclose(tfile);
|
||||
|
||||
/* if there's anything in found[], use it */
|
||||
if (found[0])
|
||||
{
|
||||
return &found[len + 1];
|
||||
}
|
||||
|
||||
/* else we didn't find it */
|
||||
return (char *)0;
|
||||
}
|
||||
|
||||
/* This function reads a single textline from a binary file. It returns
|
||||
* the number of bytes read, or 0 at EOF.
|
||||
*/
|
||||
int getline(buf, limit, fp)
|
||||
char *buf; /* buffer to read into */
|
||||
int limit; /* maximum characters to read */
|
||||
FILE *fp; /* binary stream to read from */
|
||||
{
|
||||
int bytes; /* number of bytes read so far */
|
||||
int ch; /* single character from file */
|
||||
|
||||
for (bytes = 0, ch = 0; ch != '\n' && --limit > 0 && (ch = getc(fp)) != EOF; bytes++)
|
||||
{
|
||||
#if MSDOS || TOS
|
||||
/* since this is a binary file, we'll need to manually strip CR's */
|
||||
if (ch == '\r')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
*buf++ = ch;
|
||||
}
|
||||
*buf = '\0';
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
/* This function reads a source file, looking for a given tag. If it finds
|
||||
* the tag, then it displays it and returns TRUE. Otherwise it returns FALSE.
|
||||
* To display the tag, it attempts to output any introductory comment, the
|
||||
* tag line itself, and any arguments. Arguments are assumed to immediately
|
||||
* follow the tag line, and start with whitespace. Comments are assumed to
|
||||
* start with lines that begin with "/*", "//", "(*", or "--", and end at the
|
||||
* tag line or at a blank line.
|
||||
*/
|
||||
int lookup(dir, entry)
|
||||
char *dir; /* name of the directory that contains the source */
|
||||
char *entry; /* source filename, <Tab>, linespec */
|
||||
{
|
||||
char *name; /* basename of source file */
|
||||
char buf[BLKSIZE]; /* pathname of source file */
|
||||
long lnum; /* desired line number */
|
||||
long thislnum; /* current line number */
|
||||
long here; /* seek position where current line began */
|
||||
long comment; /* seek position of introductory comment, or -1L */
|
||||
FILE *sfile; /* used for reading the source file */
|
||||
int len; /* length of string */
|
||||
int noargs = 0; /* boolean: don't show lines after tag line? */
|
||||
char *ptr;
|
||||
|
||||
|
||||
/* construct the pathname of the source file */
|
||||
name = entry;
|
||||
strcpy(buf, dir);
|
||||
ptr = buf + strlen(buf);
|
||||
#if AMIGA
|
||||
if (ptr[-1] != COLON)
|
||||
#endif
|
||||
*ptr++ = SLASH;
|
||||
while (*entry != '\t')
|
||||
{
|
||||
*ptr++ = *entry++;
|
||||
}
|
||||
*entry++ = *ptr = '\0';
|
||||
|
||||
/* searching for string or number? */
|
||||
if (*entry >= '0' && *entry <= '9')
|
||||
{
|
||||
/* given a specific line number */
|
||||
lnum = atol(entry);
|
||||
entry = (char *)0;
|
||||
noargs = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* given a string -- strip off "/^" and "$/\n" */
|
||||
entry += 2;
|
||||
len = strlen(entry) - 2;
|
||||
if (entry[len - 1] == '$')
|
||||
{
|
||||
entry[len - 1] = '\n';
|
||||
}
|
||||
if (!strchr(entry, '('))
|
||||
{
|
||||
noargs = 1;
|
||||
}
|
||||
lnum = 0L;
|
||||
}
|
||||
|
||||
/* Open the file. Note that we open the file in binary mode even
|
||||
* though we know it is a text file, because ftell() and fseek()
|
||||
* don't work on text files.
|
||||
*/
|
||||
#if MSDOS || TOS
|
||||
sfile = fopen(buf, "rb");
|
||||
#else
|
||||
# if AMIGA
|
||||
if (buf[0] == '.' && buf[1] == SLASH)
|
||||
sfile = fopen(&buf[2], "r");
|
||||
else
|
||||
# endif
|
||||
sfile = fopen(buf, "r");
|
||||
#endif
|
||||
if (!sfile)
|
||||
{
|
||||
/* can't open the real source file. Try "refs" instead */
|
||||
#if AMIGA
|
||||
if (dir[strlen(dir) - 1] == COLON)
|
||||
sprintf(buf, "%srefs", dir);
|
||||
else
|
||||
#endif
|
||||
sprintf(buf, "%s%crefs", dir, SLASH);
|
||||
#if MSDOS || TOS
|
||||
sfile = fopen(buf, "rb");
|
||||
#else
|
||||
# if AMIGA
|
||||
if (buf[0] == '.' && buf[1] == SLASH)
|
||||
sfile = fopen(&buf[2], "r");
|
||||
else
|
||||
# endif
|
||||
sfile = fopen(buf, "r");
|
||||
#endif
|
||||
if (!sfile)
|
||||
{
|
||||
/* failed! */
|
||||
return 0;
|
||||
}
|
||||
name = "refs";
|
||||
}
|
||||
|
||||
/* search the file */
|
||||
for (comment = -1L, thislnum = 0; here = ftell(sfile), thislnum++, getline(buf, BLKSIZE, sfile) > 0; )
|
||||
{
|
||||
/* Is this the start/end of a comment? */
|
||||
if (comment == -1L)
|
||||
{
|
||||
/* starting a comment? */
|
||||
if (buf[0] == '/' && buf[1] == '*'
|
||||
|| buf[0] == '/' && buf[1] == '/'
|
||||
|| buf[0] == '(' && buf[1] == '*'
|
||||
|| buf[0] == '-' && buf[1] == '-')
|
||||
{
|
||||
comment = here;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ending a comment? */
|
||||
if (buf[0] == '\n' || buf[0] == '#')
|
||||
{
|
||||
comment = -1L;
|
||||
}
|
||||
}
|
||||
|
||||
/* is this the tag line? */
|
||||
if (lnum == thislnum || (entry && !strncmp(buf, entry, len)))
|
||||
{
|
||||
/* display the filename & line number where found */
|
||||
if (strcmp(dir, "."))
|
||||
printf("%s%c%s, line %ld:\n", dir, SLASH, name, thislnum);
|
||||
else
|
||||
printf("%s, line %ld:\n", name, thislnum);
|
||||
|
||||
/* if there were introductory comments, show them */
|
||||
if (comment != -1L)
|
||||
{
|
||||
fseek(sfile, comment, 0);
|
||||
while (comment != here)
|
||||
{
|
||||
getline(buf, BLKSIZE, sfile);
|
||||
fputs(buf, stdout);
|
||||
comment = ftell(sfile);
|
||||
}
|
||||
|
||||
/* re-fetch the tag line */
|
||||
fgets(buf, BLKSIZE, sfile);
|
||||
}
|
||||
|
||||
/* show the tag line */
|
||||
fputs(buf, stdout);
|
||||
|
||||
/* are we expected to show argument lines? */
|
||||
if (!noargs)
|
||||
{
|
||||
/* show any argument lines */
|
||||
while (getline(buf, BLKSIZE, sfile) > 0
|
||||
&& buf[0] != '#'
|
||||
&& strchr(buf, '{') == (char *)0)
|
||||
{
|
||||
fputs(buf, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
/* Done! Close the file, and return TRUE */
|
||||
fclose(sfile);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* not found -- return FALSE */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This function searches through the entire search path for a given tag.
|
||||
* If it finds the tag, then it displays the info and returns TRUE;
|
||||
* otherwise it returns FALSE.
|
||||
*/
|
||||
int find(tag)
|
||||
char *tag; /* the tag to look up */
|
||||
{
|
||||
char *tagpath;
|
||||
char dir[80];
|
||||
char *ptr;
|
||||
int len;
|
||||
|
||||
if (colons == 1)
|
||||
{
|
||||
/* looking for static function -- only look in current dir */
|
||||
tagpath = ".";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* get the tagpath from the environment. Default to DEFTAGPATH */
|
||||
tagpath = getenv("TAGPATH");
|
||||
if (!tagpath)
|
||||
{
|
||||
tagpath = DEFTAGPATH;
|
||||
}
|
||||
}
|
||||
|
||||
/* for each entry in the path... */
|
||||
while (*tagpath)
|
||||
{
|
||||
/* Copy the entry into the dir[] buffer */
|
||||
for (ptr = dir; *tagpath && *tagpath != SEP; tagpath++)
|
||||
{
|
||||
*ptr++ = *tagpath;
|
||||
}
|
||||
if (*tagpath == SEP)
|
||||
{
|
||||
tagpath++;
|
||||
}
|
||||
|
||||
/* if the entry ended with "/tags", then strip that off */
|
||||
len = strlen(TAGS);
|
||||
if (&dir[len] < ptr && ptr[-len - 1] == SLASH && !strncmp(&ptr[-len], TAGS, len))
|
||||
{
|
||||
ptr -= len + 1;
|
||||
}
|
||||
|
||||
/* if the entry is now an empty string, then assume "." */
|
||||
if (ptr == dir)
|
||||
{
|
||||
*ptr++ = '.';
|
||||
}
|
||||
*ptr = '\0';
|
||||
|
||||
/* look for the tag in this path. If found, then display it
|
||||
* and exit.
|
||||
*/
|
||||
ptr = cktagdir(tag, dir);
|
||||
if (ptr)
|
||||
{
|
||||
/* just supposed to display tag info? */
|
||||
if (taginfo)
|
||||
{
|
||||
/* then do only that! */
|
||||
if (strcmp(dir, "."))
|
||||
{
|
||||
printf("%s%c%s", dir, SLASH, ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* avoid leading "./" if possible */
|
||||
fputs(ptr, stdout);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* else look up the declaration of the thing */
|
||||
return lookup(dir, ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if we get here, then the tag wasn't found anywhere */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void usage()
|
||||
{
|
||||
fputs("usage: ref [-t] [-c class] [-f file] tag\n", stderr);
|
||||
fputs(" -t output tag info, instead of the function header\n", stderr);
|
||||
fputs(" -f File tag might be a static function in File\n", stderr);
|
||||
fputs(" -c Class tag might be a member of class Class\n", stderr);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
|
||||
int countcolons(str)
|
||||
char *str;
|
||||
{
|
||||
while (*str != ':' && *str)
|
||||
{
|
||||
str++;
|
||||
}
|
||||
if (str[0] != ':')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (str[1] != ':')
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
void main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char def_tag[100]; /* used to build tag name with default file/class */
|
||||
int i;
|
||||
|
||||
/* parse flags */
|
||||
for (i = 1; i < argc && argv[i][0] == '-'; i++)
|
||||
{
|
||||
switch (argv[i][1])
|
||||
{
|
||||
case 't':
|
||||
taginfo = 1;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (argv[i][2])
|
||||
{
|
||||
def_file = &argv[i][2];
|
||||
}
|
||||
else if (++i < argc)
|
||||
{
|
||||
def_file = argv[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
if (argv[i][2])
|
||||
{
|
||||
def_class = &argv[i][2];
|
||||
}
|
||||
else if (++i < argc)
|
||||
{
|
||||
def_class = argv[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
/* if no tag was given, complain */
|
||||
if (i + 1 != argc)
|
||||
{
|
||||
usage();
|
||||
}
|
||||
|
||||
/* does the tag have an explicit class or file? */
|
||||
colons = countcolons(argv[i]);
|
||||
|
||||
/* if not, then maybe try some defaults */
|
||||
if (colons == 0)
|
||||
{
|
||||
/* try a static function in the file first */
|
||||
if (def_file)
|
||||
{
|
||||
sprintf(def_tag, "%s:%s", def_file, argv[i]);
|
||||
colons = 1;
|
||||
if (find(def_tag))
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* try a member function for a class */
|
||||
if (def_class)
|
||||
{
|
||||
sprintf(def_tag, "%s::%s", def_class, argv[i]);
|
||||
colons = 2;
|
||||
if (find(def_tag))
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* oh, well */
|
||||
colons = 0;
|
||||
}
|
||||
|
||||
/* find the tag */
|
||||
if (find(argv[i]))
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Give up. If doing tag lookup then exit(0), else exit(1) */
|
||||
exit(!taginfo);
|
||||
/*NOTREACHED*/
|
||||
}
|
Loading…
Reference in New Issue
Block a user