fix line addressing so that 1,2, == 2,2 (as per SunOS ed) not 1,2

add global-active routines to replace some bad hacks
remove obsolescent Addison-Wesley copyrights
This commit is contained in:
alm 1993-11-12 10:48:43 +00:00
parent b14e2fa6d0
commit ba4d688de2
8 changed files with 273 additions and 279 deletions

View File

@ -1,8 +1,8 @@
This version of ed is not strictly POSIX compliant, as described in the
POSIX 1003.2 Draft 11.2 document. BSD commands have been implemented
wherever they do not conflict with the POSIX standard. For backwards
compatibility, the POSIX rule that says a range of addresses cannot be
used where only a single address is expected has been relaxed.
POSIX 1003.2 document. BSD commands have been implemented wherever they
do not conflict with the POSIX standard. For backwards compatibility,
the POSIX rule that says a range of addresses cannot be used where only
a single address is expected has been relaxed.
The BSD commands included are:
1) `s' (i.e., s[rgp]*) to repeat a previous substitution,
@ -50,7 +50,7 @@ least one ASCII NUL character is written, a newline is not appended
if it did not already contain one upon reading.
Since the behavior of `u' (undo) within a `g' (global) command list is
not specified by POSIX D11/2, it follows the behavior of the SunOS ed
not specified by POSIX, it follows the behavior of the SunOS ed
(this is the best way, I think, in that the alternatives are either too
complicated to implement or too confusing to use): undo forces a global
command list to be executed only once, rather than for each line matching

View File

@ -7,7 +7,6 @@ compile with little trouble. Otherwise, the macros spl1() and spl0()
should be redefined to disable interrupts.
The following compiler directives are recognized:
GNU_REGEX - use with GNU regex(3)
DES - use to add encryption support (requires crypt(3))
NO_REALLOC_NULL - use if realloc(3) does not accept a NULL pointer
BACKWARDS - use for backwards compatibility

View File

@ -1,12 +1,9 @@
/* buf.c: This file contains the scratch-file buffer rountines for the
ed line editor. */
/*-
* Copyright (c) 1992 The Regents of the University of California.
* Copyright (c) 1993 Andrew Moore, Talke Studio.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rodney Ruddock of the University of Guelph.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -15,18 +12,11 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@ -35,10 +25,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
/*static char sccsid[] = "from: @(#)buf.c 5.5 (Berkeley) 3/28/93";*/
static char rcsid[] = "$Id: buf.c,v 1.8 1993/08/01 18:59:50 mycroft Exp $";
static char sccsid[] = "@(#)buf.c 5.5 (Talke Studio) 3/28/93";
#endif /* not lint */
#include <stdio.h>
@ -78,7 +66,7 @@ gettxt(lp)
return NULL;
}
}
len = lp->len & ~ACTV;
len = lp->len;
CKBUF(sfbuf, sfbufsz, len + 1, NULL);
if ((ct = fread(sfbuf, sizeof(char), len, sfp)) < 0 || ct != len) {
fprintf(stderr, "%s\n", strerror(errno));
@ -116,7 +104,7 @@ puttxt(cs)
sprintf(errmsg, "line too long");
return NULL;
}
len = (s - cs) & ~ACTV;
len = (s - cs);
/* out of position */
if (seek_write) {
if (fseek(sfp, 0L, SEEK_END) < 0) {
@ -253,9 +241,9 @@ quit(n)
unsigned char ctab[256]; /* character translation table */
/* init_buf: open scratch buffer; initialize line queue */
/* inited: open scratch buffer; initialize line queue */
void
init_buf()
inited()
{
int i = 0;
@ -285,5 +273,3 @@ translit(s, len, from, to)
*us = ctab[*us];
return s;
}

View File

@ -1,14 +1,10 @@
/* cbc.c: This file contains the encryption routines for the ed line editor */
/*-
* Copyright (c) 1991 The Regents of the University of California.
* Copyright (c) 1993 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Matt Bishop of Dartmouth College.
*
* The United States Government has rights in this work pursuant
* to contract no. NAG 2-680 between the National Aeronautics and
* Space Administration and Dartmouth College.
* Copyright (c) 1993 Andrew Moore, Talke Studio.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -37,27 +33,14 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)bdes.c 5.5 (Berkeley) 6/27/91
*/
#ifndef lint
/*static char sccsid[] = "from: @(#)cbc.c 5.5 (Berkeley) 6/27/91";*/
static char rcsid[] = "$Id: cbc.c,v 1.5 1993/08/01 18:59:49 mycroft Exp $";
static char sccsid[] = "@(#)cbc.c 5.5 (Talke Studio) 6/27/91";
#endif /* not lint */
/* Author: Matt Bishop
* Department of Mathematics and Computer Science
* Dartmouth College
* Hanover, NH 03755
* Email: Matt.Bishop@dartmouth.edu
* ...!decvax!dartvax!Matt.Bishop
*
* See Technical Report PCS-TR91-158, Department of Mathematics and Computer
* Science, Dartmouth College, for a detailed description of the implemen-
* tation and differences between it and Sun's. The DES is described in
* FIPS PUB 46, and the modes in FIPS PUB 81 (see either the manual page
* or the technical report for a complete reference).
*/
#include <errno.h>
#include <pwd.h>
#include <unistd.h>

View File

@ -1,4 +1,3 @@
.\" $Id: ed.1,v 1.8 1993/08/02 17:15:35 mycroft Exp $ -*- nroff -*-
.TH ED 1 "21 May 1993"
.SH NAME
ed, red \- text editor
@ -135,7 +134,7 @@ The default filename is set to
only if it is not prefixed with a bang.
.SS LINE ADDRESSING
An address represents the number of line in the buffer.
An address represents the number of a line in the buffer.
.B ed
maintains a
.I current address
@ -166,25 +165,26 @@ and is legal wherever it makes sense.
An address range is two addresses separated either by a comma or
semi-colon. The value of the first address in a range cannot exceed the
value of the the second. If an
value of the the second. If only one address is given in a range, then
the second address is set to the given address. If an
.IR n- tuple
of addresses is given where
.I n > 2,
then the corresponding range is determined by the last two addresses
in the
then the corresponding range is determined by the last two addresses in
the
.IR n- tuple.
If only one address is expected, then the last
address is used.
If only one address is expected, then the last address is used.
Each address in a comma-delimited range is interpreted relative to the
current address. In a semi-colon-delimited range, the first address is
used to set the current address, and the second address is interpreted
relative to the first.
The following address symbols are recognized.
.TP 8
\fR.\fR
\&.
The current line (address) in the buffer.
.TP 8

View File

@ -1,12 +1,9 @@
/* ed.c: This file contains the main control and user-interface routines
for the ed line editor. */
/*-
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1993 Andrew Moore, Talke Studio.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley
* by Andrew Moore, Talke Studio.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -15,18 +12,11 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@ -35,39 +25,26 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*-
* Kernighan/Plauger, "Software Tools in Pascal," (c) 1981 by
* Addison-Wesley Publishing Company, Inc. Reprinted with permission of
* the publisher.
*/
#ifndef lint
char copyright1[] =
"@(#) Copyright (c) 1993 The Regents of the University of California.\n\
"@(#) Copyright (c) 1993 Andrew Moore, Talke Studio.\n\
All rights reserved.\n";
char copyright2[] =
"@(#) Kernighan/Plauger, Software Tools in Pascal, (c) 1981 by\n\
Addison-Wesley Publishing Company, Inc. Reprinted with permission of\n\
the publisher.\n";
#endif /* not lint */
#ifndef lint
/*static char sccsid[] = "from: @(#)ed.c 5.5 (Berkeley) 3/28/93";*/
static char rcsid[] = "$Id: ed.c,v 1.17 1993/08/30 02:20:22 alm Exp $";
static char sccsid[] = "@(#)ed.c 5.5 (Talke Studio) 3/28/93";
#endif /* not lint */
/*
* CREDITS
* The buf.c algorithm is attributed to Rodney Ruddock of
* The buffering algorithm is attributed to Rodney Ruddock of
* the University of Guelph, Guelph, Ontario.
*
* The cbc.c encryption code is adapted from
* the bdes program by Matt Bishop of Dartmouth College,
* Hanover, NH.
*
* Addison-Wesley Publishing Company generously granted
* permission to distribute this program over Internet.
*
*/
#include <unistd.h>
@ -188,7 +165,7 @@ top:
fputs("\n?\n", stderr);
sprintf(errmsg, "interrupt");
} else {
init_buf();
inited();
sigactive = 1; /* enable signal handlers */
if (argc && **argv && ckfn(*argv)) {
if (doread(0, *argv) < 0 && !isatty(0))
@ -279,110 +256,104 @@ top:
long line1, line2, nlines;
/* getlist: get line numbers from the command buffer until an illegal
address is seen. return range status */
address is seen; return status */
getlist()
{
long num;
long addr;
nlines = line2 = 0;
while ((num = getone()) >= 0) {
line1 = line2;
line2 = num;
nlines = 0;
line1 = line2 = curln;
while ((addr = getone()) >= 0) {
nlines++;
line1 = line2;
line2 = addr;
if (*ibufp != ',' && *ibufp != ';')
break;
else if (*ibufp++ == ';')
curln = num;
curln = addr;
}
nlines = min(nlines, 2);
if (nlines == 0)
line2 = curln;
if (nlines <= 1)
if ((nlines = min(nlines, 2)) == 1 || line2 != addr)
line1 = line2;
return (num == ERR) ? ERR : nlines;
return (addr == ERR) ? ERR : 0;
}
#define ckfirst() \
if (!first) { sprintf(errmsg, "invalid address"); return ERR; }
/* getone: return the next line number in the command buffer */
long
getone()
{
char *hd;
long addr = curln;
int first = 1;
int c;
long i, num;
if ((num = getnum(1)) < 0)
return num;
for (;;) {
c = isspace(*ibufp);
skipblanks();
c = c && isdigit(*ibufp);
if (!c && *ibufp != '+' && *ibufp != '-' && *ibufp != '^')
break;
c = c ? '+' : *ibufp++;
if ((i = getnum(0)) < 0) {
sprintf(errmsg, "invalid address");
return i;
}
if (c == '+')
num += i;
else num -= i;
}
if (num > lastln || num < 0) {
sprintf(errmsg, "invalid address");
return ERR;
}
return num;
}
/* getnum: return a relative line number from the command buffer */
long
getnum(first)
int first;
{
pattern_t *pat;
char c;
skipblanks();
if (isdigit(*ibufp))
return strtol(ibufp, &ibufp, 10);
switch(c = *ibufp) {
case '.':
ibufp++;
return first ? curln : ERR;
case '$':
ibufp++;
return first ? lastln : ERR;
case '/':
case '?':
if ((pat = optpat()) == NULL)
return ERR;
else if (*ibufp == c)
for (hd = ibufp;; first = 0)
switch (c = *ibufp) {
case '+':
case '\t':
case ' ':
case '-':
case '^':
ibufp++;
return first ? patscan(pat, (c == '/') ? 1 : 0) : ERR;
case '^':
case '-':
case '+':
return first ? curln : 1;
case '\'':
ibufp++;
return first ? getmark(*ibufp++) : ERR;
case '%':
case ',':
case ';':
if (first) {
skipblanks();
c = (c == '-' || c == '^') ? -1 : 1;
if (isdigit(*ibufp))
addr += c * strtol(ibufp, &ibufp, 10);
else
addr += c;
break;
case '0': case '1': case '2':
case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
ckfirst();
addr = strtol(ibufp, &ibufp, 10);
break;
case '.':
case '$':
ckfirst();
ibufp++;
line2 = (c == ';') ? curln : 1;
nlines++;
return lastln;
addr = (c == '.') ? curln : lastln;
break;
case '/':
case '?':
ckfirst();
if ((addr = patscan(optpat(), (c == '/') ? 1 : 0)) < 0)
return ERR;
if (c == *ibufp)
ibufp++;
break;
case '\'':
ckfirst();
ibufp++;
if ((addr = getmark(*ibufp++)) < 0)
return ERR;
break;
case '%':
case ',':
case ';':
if (first) {
ibufp++;
nlines++;
line2 = (c == ';') ? curln : 1;
addr = lastln;
break;
}
/* FALL THROUGH */
default:
if (ibufp == hd)
return EOF;
else if (addr < 0 || lastln < addr) {
sprintf(errmsg, "invalid address");
return ERR;
} else
return addr;
}
return 1;
default:
return first ? EOF : 1;
}
/* NOTREACHED */
}
/* gflags */
#define GLB 001 /* global command */
#define GPR 002 /* print after command */
@ -423,7 +394,6 @@ ckglob()
pattern_t *pat;
char c, delim;
char *s;
int nomatch;
long n;
line_t *lp;
int gflag = 0; /* print suffix of interactive cmd */
@ -443,17 +413,16 @@ ckglob()
ibufp++;
if (gflag)
VRFYCMD(); /* get print suffix */
clractive();
for (lp = getlp(n = 1); n <= lastln; n++, lp = lp->next) {
if ((s = gettxt(lp)) == NULL)
return ERR;
lp->len &= ~ACTV; /* zero ACTV bit */
if (isbinary)
s = nultonl(s, lp->len & ~ACTV);
s = nultonl(s, lp->len);
if (line1 <= n && n <= line2
&& (!(nomatch = regexec(pat, s, 0, NULL, 0))
&& (c == 'g' || c == 'G')
|| nomatch && (c == 'v' || c == 'V')))
lp->len |= ACTV;
&& !regexec(pat, s, 0, NULL, 0) == (c == 'g' || c == 'G'))
if (insactive(lp) < 0)
return ERR;
}
return gflag | GSG;
}
@ -469,7 +438,6 @@ doglob(gflag)
static int ocmdsz = 0;
line_t *lp = NULL;
long lc;
int status;
int n;
int interact = gflag & ~GSG; /* GLB & gflag ? */
@ -486,14 +454,9 @@ doglob(gflag)
return ERR;
#endif
ureset();
for (;;) {
for (lp = getlp(lc = 1); lc <= lastln; lc++, lp = lp->next)
if (lp->len & ACTV) /* active line */
break;
if (lc > lastln)
break;
lp->len ^= ACTV; /* zero ACTV bit */
curln = lc;
while ((lp = nextactive()) != NULL) {
if ((curln = getaddr(lp)) < 0)
return ERR;
if (interact) {
/* print curln and get a command in global syntax */
if (doprint(curln, curln, 0) < 0)
@ -533,6 +496,85 @@ doglob(gflag)
return ((interact & ~GLB ) && doprint(curln, curln, interact) < 0) ? ERR : curln;
}
line_t **active_list; /* list of lines active in a global command */
long active_last; /* index of last active line in active_list */
long active_size; /* size of active_list */
long active_ptr; /* active_list index (non-decreasing) */
long active_ndx; /* active_list index (modulo active_last) */
/* insactive: add a line node to the global-active list */
insactive(lp)
line_t *lp;
{
if (active_last + 1 > active_size) {
int ti = active_size;
line_t **ts;
spl1();
#if defined(sun) || defined(NO_REALLOC_NULL)
if (active_list != NULL) {
#endif
if ((ts = (line_t **) realloc(active_list, (ti += MINBUFSZ) * sizeof(line_t **))) == NULL)
{
fprintf(stderr, "%s\n", strerror(errno));
sprintf(errmsg, "out of memory");
spl0();
return ERR;
}
#if defined(sun) || defined(NO_REALLOC_NULL)
} else {
if ((ts = (line_t **) malloc((ti += MINBUFSZ) * sizeof(line_t **))) == NULL)
{
fprintf(stderr, "%s\n", strerror(errno));
sprintf(errmsg, "out of memory");
spl0();
return ERR;
}
}
#endif
active_size = ti;
active_list = ts;
spl0();
}
active_list[active_last++] = lp;
return 0;
}
/* remactive: remove a line node from the global-active list */
void
remactive(lp)
line_t *lp;
{
long i;
for (i = 0; i < active_last; i++)
if (active_list[active_ndx] == lp) {
active_list[active_ndx] = NULL;
if (++active_ndx >= active_last) active_ndx = 0;
break;
} else {
if (++active_ndx >= active_last) active_ndx = 0;
}
}
/* nextactive: return the next global-active line node */
line_t *
nextactive()
{
while (active_ptr < active_last && active_list[active_ptr] == NULL)
active_ptr++;
return (active_ptr < active_last) ? active_list[active_ptr++] : NULL;
}
/* clractive: clear the global-active list */
void
clractive()
{
spl1();
active_size = active_last = active_ptr = active_ndx = 0;
free(active_list);
active_list = NULL;
spl0();
}
#ifdef BACKWARDS
/* GETLINE3: get a legal address from the command buffer */
@ -612,7 +654,7 @@ docmd(glob)
return ERR;
VRFYCMD();
if (!glob) ureset();
if (lndelete(line1, line2) < 0 || append(curln, glob) < 0)
if (lndelete(line1, line2, glob) < 0 || append(curln, glob) < 0)
return ERR;
break;
case 'd':
@ -620,7 +662,7 @@ docmd(glob)
return ERR;
VRFYCMD();
if (!glob) ureset();
if (lndelete(line1, line2) < 0)
if (lndelete(line1, line2, glob) < 0)
return ERR;
else if (nextln(curln, lastln) != 0)
curln = nextln(curln, lastln);
@ -640,7 +682,7 @@ docmd(glob)
} else if ((fnp = getfn()) == NULL)
return ERR;
VRFYCMD();
if (lndelete(1, lastln) < 0)
if (lndelete(1, lastln, glob) < 0)
return ERR;
ureset();
if (sbclose() < 0)
@ -713,7 +755,7 @@ docmd(glob)
return ERR;
VRFYCMD();
if (!glob) ureset();
if (line1 != line2 && join(line1, line2) < 0)
if (line1 != line2 && join(line1, line2, glob) < 0)
return ERR;
break;
case 'k':
@ -721,7 +763,7 @@ docmd(glob)
if (line2 == 0) {
sprintf(errmsg, "invalid address");
return ERR;
}
}
VRFYCMD();
if (putmark(c, getlp(line2)) < 0)
return ERR;
@ -885,7 +927,7 @@ docmd(glob)
return ERR;
VRFYCMD();
if (!glob) ureset();
if ((n = subst(pat, sgflag)) < 0)
if ((n = subst(pat, sgflag, glob)) < 0)
return ERR;
else if (n)
modified = 1;
@ -999,7 +1041,7 @@ docmd(glob)
return ERR;
else {
if (!glob) ureset();
if (lndelete(line1, line2) < 0)
if (lndelete(line1, line2, glob) < 0)
return ERR;
line2 = curln;
modified = 1;
@ -1054,12 +1096,13 @@ patscan(pat, dir)
long n = curln;
line_t *lp;
if (!pat) return ERR;
do {
if (n = dir ? nextln(n, lastln) : prevln(n, lastln)) {
if ((s = gettxt(lp = getlp(n))) == NULL)
return ERR;
if (isbinary)
s = nultonl(s, lp->len & ~ACTV);
s = nultonl(s, lp->len);
if (!regexec(pat, s, 0, NULL, 0))
return n;
}
@ -1296,9 +1339,10 @@ append(n, glob)
/* subst: change all text matching a pattern in a range of lines according to
a substitution template; return status */
subst(pat, gflag)
subst(pat, gflag, glob)
pattern_t *pat;
int gflag;
int glob;
{
undo_t *up;
char *txt;
@ -1315,7 +1359,7 @@ subst(pat, gflag)
return ERR;
else if (len) {
up = NULL;
if (lndelete(curln, curln) < 0)
if (lndelete(curln, curln, glob) < 0)
return ERR;
txt = rbuf;
eot = rbuf + len;
@ -1356,7 +1400,6 @@ regsub(pat, lp, gflag)
int kth = gflag >> 8; /* substitute kth match only */
int chngd = 0;
int matchno = 0;
int len;
int i = 0;
regmatch_t rm[SE_MAX];
char *txt;
@ -1364,9 +1407,8 @@ regsub(pat, lp, gflag)
if ((txt = gettxt(lp)) == NULL)
return ERR;
len = lp->len & ~ACTV;
eot = txt + len;
if (isbinary) txt = nultonl(txt, len);
if (isbinary) txt = nultonl(txt, lp->len);
eot = txt + lp->len;
if (!regexec(pat, txt, SE_MAX, rm, 0)) {
do {
if (!kth || kth == ++matchno) {
@ -1375,7 +1417,7 @@ regsub(pat, lp, gflag)
CKBUF(rbuf, rbufsz, off + i, ERR);
if (isbinary) txt = nltonul(txt, rm[0].rm_eo);
memcpy(rbuf + off, txt, i);
if ((off = catsub(txt, rm, off += i)) < 0)
if ((off = catsub(txt, rm, off += i, pat->re_nsub)) < 0)
return ERR;
} else {
i = rm[0].rm_eo;
@ -1402,29 +1444,28 @@ regsub(pat, lp, gflag)
/* join: replace a range of lines with the joined text of those lines */
join(from, to)
join(from, to, glob)
long from;
long to;
int glob;
{
static char *buf = NULL;
static int n;
char *s;
int len = 0;
int size = 0;
line_t *bp, *ep;
ep = getlp(nextln(to, lastln));
for (bp = getlp(from); bp != ep; bp = bp->next, size += len) {
for (bp = getlp(from); bp != ep; size += bp->len, bp = bp->next) {
if ((s = gettxt(bp)) == NULL)
return ERR;
len = bp->len & ~ACTV;
CKBUF(buf, n, size + len, ERR);
memcpy(buf + size, s, len);
CKBUF(buf, n, size + bp->len, ERR);
memcpy(buf + size, s, bp->len);
}
CKBUF(buf, n, size + 2, ERR);
memcpy(buf + size, "\n", 2);
if (lndelete(from, to) < 0)
if (lndelete(from, to, glob) < 0)
return ERR;
curln = from - 1;
spl1();
@ -1471,7 +1512,7 @@ move(num, glob)
}
if (glob)
for (lp = b2->next; lp != a2; lp = lp->next)
lp->len &= ~ACTV; /* zero ACTV bit */
remactive(lp);
spl0();
return 0;
}
@ -1522,10 +1563,11 @@ transfer(num)
/* lndelete: delete a range of lines */
lndelete(from, to)
lndelete(from, to, glob)
long from, to;
int glob;
{
line_t *before, *after;
line_t *before, *after, *lp;
spl1();
if (upush(UDEL, from, to) == NULL) {
@ -1534,6 +1576,9 @@ lndelete(from, to)
}
after = getlp(nextln(to, lastln));
before = getlp(prevln(from, lastln)); /* this getlp last! */
if (glob)
for (lp = before->next; lp != after; lp = lp->next)
remactive(lp);
requeue(before, after);
lastln -= to - from + 1;
curln = prevln(from, lastln);
@ -1544,13 +1589,15 @@ lndelete(from, to)
/* catsub: modify text according to a substitution template;
return offset to end of modified text */
catsub(boln, rm, off)
catsub(boln, rm, off, re_nsub)
char *boln;
regmatch_t *rm;
int off;
int re_nsub;
{
int j = 0;
int k = 0;
int n;
char *sub = rhbuf;
for (; sub - rhbuf < rhbufi; sub++)
@ -1561,10 +1608,9 @@ catsub(boln, rm, off)
while (j < k)
rbuf[off++] = boln[j++];
} else if (*sub == '\\' && '1' <= *++sub && *sub <= '9'
&& rm[*sub - '0'].rm_so >= 0
&& rm[*sub - '0'].rm_eo >= 0) {
j = rm[*sub - '0'].rm_so;
k = rm[*sub - '0'].rm_eo;
&& (n = *sub - '0') <= re_nsub) {
j = rm[n].rm_so;
k = rm[n].rm_eo;
CKBUF(rbuf, rbufsz, off + k - j, ERR);
while (j < k)
rbuf[off++] = boln[j++];
@ -1595,7 +1641,7 @@ doprint(from, to, gflag)
for (bp = getlp(from); bp != ep; bp = bp->next) {
if ((s = gettxt(bp)) == NULL)
return ERR;
putstr(s, bp->len & ~ACTV, curln = from++, gflag);
putstr(s, bp->len, curln = from++, gflag);
}
return 0;
}
@ -1624,6 +1670,9 @@ putstr(s, l, n, gflag)
}
if (gflag & GLS) {
switch (*s) {
case '\a':
fputs("\\a", stdout);
break;
case '\b':
fputs("\\b", stdout);
break;
@ -1743,7 +1792,7 @@ dowrite(n, m, fn, mode)
for (lp = getlp(n); n <= m; n++, lp = lp->next) {
if ((s = gettxt(lp)) == NULL)
return ERR;
len = lp->len & ~ACTV;
len = lp->len;
if (n != lastln || !isbinary || !newline_added)
s[len++] = '\n';
if ((ct = fwrite(s, sizeof(char), len, fp)) < 0 || ct != len) {
@ -1757,7 +1806,7 @@ dowrite(n, m, fn, mode)
for (lp = getlp(n); n <= m; n++, lp = lp->next) {
if ((s = gettxt(lp)) == NULL)
return ERR;
len = lp->len & ~ACTV;
len = lp->len;
while (len--) {
if (desputc(*s++, fp) == EOF && ferror(fp)) {
fprintf(stderr, "%s: %s\n", fn, strerror(errno));
@ -1773,7 +1822,7 @@ dowrite(n, m, fn, mode)
}
size++; /* for '\n' */
}
size += (lp->len & ~ACTV);
size += lp->len;
}
if (des) {
desflush(fp); /* flush buffer */
@ -1845,7 +1894,6 @@ undo(glob)
long n;
long ocurln = curln;
long olastln = lastln;
line_t *lp, *np;
if (ucurln == -1 || ulastln == -1) {
sprintf(errmsg, "nothing to undo");
@ -1880,8 +1928,7 @@ undo(glob)
for (n = u_p; n-- > (u_p + 1)/ 2;)
USWAP(ustack[n], ustack[u_p - 1 - n]);
if (glob)
for (lp = np = getlp(0); (lp = lp->next) != np;)
lp->len &= ~ACTV; /* zero ACTV bit */
clractive();
curln = ucurln, ucurln = ocurln;
lastln = ulastln, ulastln = olastln;
spl0();
@ -1919,7 +1966,7 @@ int markno; /* line marker count */
long
getmark(n)
int n;
{
{
if (!islower(n)) {
sprintf(errmsg, "invalid mark character");
return ERR;
@ -1943,6 +1990,7 @@ putmark(n, lp)
return 0;
}
/* clrmark: clear line node marks */
void
clrmark(lp)
@ -2086,7 +2134,7 @@ lpdup(lp)
return NULL;
}
np->seek = lp->seek;
np->len = (lp->len & ~ACTV); /* zero ACTV bit */
np->len = lp->len;
return np;
}

View File

@ -1,11 +1,8 @@
/* ed.h: type and constant definitions for the ed editor. */
/*
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1993 Andrew Moore
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Andrew Moore, Talke Studio.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -14,13 +11,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
@ -34,8 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)ed.h 5.5 (Berkeley) 3/28/93
* $Id: ed.h,v 1.15 1993/08/30 02:20:26 alm Exp $
* @(#)ed.h 5.5 (Talke Studio) 3/28/93
*/
#include <unistd.h>
@ -45,12 +34,9 @@
#endif
#include <regex.h>
#include <signal.h>
#define BITSPERBYTE 8
#define BITS(type) (BITSPERBYTE * (int)sizeof(type))
#define CHARBITS BITS(char)
#define INTBITS BITS(int)
#define INTHIBIT (unsigned) (1 << (INTBITS - 1))
#ifdef sun
# include <limits.h>
#endif
#define ERR (-2)
#define EMOD (-3)
@ -62,8 +48,12 @@
#define MAXFNAME MAXPATHLEN /* max file name size */
#define MINBUFSZ 512 /* minimum buffer size - must be > 0 */
#define LINECHARS (INTHIBIT - 1) /* max chars per line */
#define SE_MAX 30 /* max subexpressions in a regular expression */
#ifdef INT_MAX
# define LINECHARS INT_MAX /* max chars per line */
#else
# define LINECHARS MAXINT /* max chars per line */
#endif
typedef regex_t pattern_t;
@ -72,9 +62,6 @@ typedef struct line {
struct line *next;
struct line *prev;
off_t seek; /* address of line in scratch buffer */
#define ACTV INTHIBIT /* active bit: high bit of len */
int len; /* length of line */
} line_t;
@ -102,7 +89,7 @@ typedef struct undo {
/* nextln: return line after l mod k */
#define nextln(l,k) ((l)+1 > (k) ? 0 : (l)+1)
/* nextln: return line before l mod k */
/* prevln: return line before l mod k */
#define prevln(l,k) ((l)-1 < 0 ? (k) : (l)-1)
#define skipblanks() while (isspace(*ibufp) && *ibufp != '\n') ibufp++
@ -193,31 +180,32 @@ if ((i) > (n)) { \
# endif
#endif
/* local function declarations */
/* Local Function Declarations */
int append __P((long, int));
int catsub __P((char *, regmatch_t *, int, int));
int cbcdec __P((char *, FILE *));
int cbcenc __P((char *, int, FILE *));
char *ccl __P((char *));
char *ckfn __P((char *));
int ckglob __P((void));
int ckrange __P((long, long));
void clractive __P((void));
void clrmark __P((line_t *));
void cvtkey __P((char *, char *));
int desflush __P((FILE *));
int desgetc __P((FILE *));
void desinit __P((void));
int desputc __P((int, FILE *));
int docmd __P((int));
void err __P((char *));
char *ccl __P((char *));
void clrmark __P((line_t *));
void cvtkey __P((char *, char *));
long doglob __P((int));
void dohup __P((int));
void dointr __P((int));
void dowinch __P((int));
int doprint __P((long, long, int));
long doread __P((long, char *));
void dowinch __P((int));
long dowrite __P((long, long, char *, char *));
void err __P((char *));
char *esctos __P((char *));
long patscan __P((pattern_t *, int));
long getaddr __P((line_t *));
char *getcmdv __P((int *, int));
char *getfn __P((void));
@ -225,21 +213,23 @@ int getkey __P((void));
char *getlhs __P((int));
int getline __P((void));
int getlist __P((void));
long getmark __P((int));
long getnum __P((int));
long getone __P((void));
line_t *getlp __P((long));
long getmark __P((int));
long getone __P((void));
int getrhs __P((int));
int getshcmd __P((void));
char *gettxt __P((line_t *));
void init_buf __P((void));
int join __P((long, long));
int lndelete __P((long, long));
void inited __P((void));
int insactive __P((line_t *));
int join __P((long, long, int));
int lndelete __P((long, long, int));
line_t *lpdup __P((line_t *));
void lpqueue __P((line_t *));
long patscan __P((pattern_t *, int));
void makekey __P((char *));
char *makesub __P((int));
int move __P((long, int));
line_t *nextactive __P(());
int oddesc __P((char *, char *));
void onhup __P((int));
void onintr __P((int));
@ -249,11 +239,11 @@ void putstr __P((char *, int, long, int));
char *puttxt __P((char *));
void quit __P((int));
int regsub __P((pattern_t *, line_t *, int));
void remactive __P((line_t *));
int sbclose __P((void));
int sbopen __P((void));
int sgetline __P((FILE *));
int catsub __P((char *, regmatch_t *, int));
int subst __P((pattern_t *, int));
int subst __P((pattern_t *, int, int));
int tobinhex __P((int, int));
int transfer __P((long));
char *translit __P((char *, int, int, int));
@ -261,7 +251,6 @@ int undo __P((int));
undo_t *upush __P((int, long, long));
void ureset __P((void));
extern char *sys_errlist[];
extern int mutex;
extern int sigflags;

View File

@ -1,12 +1,9 @@
/* re.c: This file contains the regular expression interface routines for
the ed line editor. */
/*-
* Copyright (c) 1993 The Regents of the University of California.
* Copyright (c) 1993 Andrew Moore, Talke Studio.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley
* by Andrew Moore, Talke Studio.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@ -15,18 +12,11 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@ -37,8 +27,7 @@
*/
#ifndef lint
/*static char sccsid[] = "from: @(#)re.c 5.5 (Berkeley) 3/28/93";*/
static char rcsid[] = "$Id: re.c,v 1.10 1993/08/30 02:20:28 alm Exp $";
static char sccsid[] = "@(#)re.c 5.5 (Talke Studio) 3/28/93";
#endif /* not lint */
#include <stdio.h>