added ed, from Andrew Moore, alm@netcom.com

This commit is contained in:
cgd 1993-04-08 01:07:16 +00:00
parent f6a28bf135
commit 9b082a69f0
136 changed files with 5178 additions and 0 deletions

9
bin/ed/Makefile Normal file
View File

@ -0,0 +1,9 @@
# $Header: /cvsroot/src/bin/ed/Makefile,v 1.1 1993/04/08 01:07:16 cgd Exp $
PROG =ed
CFLAGS+=-I${.CURDIR} -DDES -W -DGNU_REGEX
SRCS= ed.c re.c buf.c cbc.c
LDADD= -lgnuregex
NOMAN= noman
.include <bsd.prog.mk>

17
bin/ed/README Normal file
View File

@ -0,0 +1,17 @@
ed is a POSIX-compliant line editor. It should work with any regular
expression package that conforms to the POSIX interface standard, such as
GNU regex(3).
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
The file `ed-1003.2' in the ./doc directory describes POSIX ed. Extensions
to the POSIX standard are described in the file `extensions.'
The ./test directory contains regression tests for ed. The README
file in that directory explains how to run these.
For a description of the ed algorithm, see Kernighan and Pike's book
"Software Tools in Pascal," Addison-Wesley, 1981.

217
bin/ed/buf.c Normal file
View File

@ -0,0 +1,217 @@
/* 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.
* 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:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, 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
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static char sccsid[] = "@(#)buf.c 5.5 (Berkeley) 3/28/93";
#endif /* not lint */
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <unistd.h>
#include "ed.h"
extern line_t line0;
FILE *sfp; /* scratch file pointer */
off_t sfseek; /* scratch file position */
int seek_write; /* seek before writing */
/* gettxt: get a line of text from the scratch file; return pointer
to the text */
char *
gettxt(lp)
line_t *lp;
{
static char txtbuf[MAXLINE];
int len, ct;
if (lp == &line0)
return NULL;
seek_write = 1; /* force seek on write */
/* out of position */
if (sfseek != lp->seek) {
sfseek = lp->seek;
if (fseek(sfp, sfseek, SEEK_SET) < 0) {
fprintf(stderr, "cannot seek temp file\n");
return (char *) ERR;
}
}
len = lp->len & ~ACTV;
if ((ct = fread(txtbuf, sizeof(char), len, sfp)) < 0 || ct != len) {
fprintf(stderr, "cannot read temp file\n");
return (char *) ERR;
}
sfseek += len; /* update file position */
txtbuf[len] = '\0';
return txtbuf;
}
extern long curln;
extern long lastln;
/* puttxt: write a line of text to the scratch file and add a line node
to the editor buffer; return a pointer to the end of the text */
char *
puttxt(cs)
char *cs;
{
line_t *lp;
int len, ct;
char *s;
if ((lp = (line_t *) malloc(sizeof(line_t))) == NULL) {
fprintf(stderr, "out of memory\n");
return (char *) ERR;
}
/* assert: cs is '\n' terminated */
for (s = cs; *s != '\n'; s++)
;
len = (s - cs) & ~ACTV;
/* out of position */
if (seek_write) {
if (fseek(sfp, 0L, SEEK_END) < 0) {
fprintf(stderr, "cannot seek temp file\n");
return (char *) ERR;
}
sfseek = ftell(sfp);
seek_write = 0;
}
/* assert: spl1() */
if ((ct = fwrite(cs, sizeof(char), len, sfp)) < 0 || ct != len) {
sfseek = -1;
fprintf(stderr, "cannot write temp file\n");
return (char *) ERR;
}
lp->len = len;
lp->seek = sfseek;
lpqueue(lp);
sfseek += len; /* update file position */
return (*++s == '\0') ? NULL : s;
}
/* lpqueue: add a line node in the editor buffer after the current line */
void
lpqueue(lp)
line_t *lp;
{
line_t *cp;
cp = getptr(curln); /* this getptr last! */
insqueue(lp, cp);
lastln++;
curln++;
}
extern int mutex;
extern int sigflags;
/* getptr: return pointer to a line node in the editor buffer */
line_t *
getptr(n)
long n;
{
static line_t *lp = &line0;
static long on = 0;
spl1();
if (n > on)
if (n <= (on + lastln) >> 1) {
for (; on < n; on++)
lp = lp->next;
} else {
lp = line0.prev;
for (on = lastln; on > n; on--)
lp = lp->prev;
}
else
if (n >= on >> 1) {
for (; on > n; on--)
lp = lp->prev;
} else {
lp = &line0;
for (on = 0; on < n; on++)
lp = lp->next;
}
spl0();
return lp;
}
char sfn[15] = ""; /* scratch file name */
/* sbopen: open scratch file */
sbopen()
{
strcpy(sfn, "/tmp/ed.XXXXXX");
if (mktemp(sfn) == NULL || (sfp = fopen(sfn, "w+")) == NULL) {
fprintf(stderr, "cannot open temp file\n");
return ERR;
}
return 0;
}
/* sbclose: close scratch file */
sbclose()
{
if (sfp) {
unlink(sfn);
fclose(sfp);
sfp = NULL;
}
sfseek = seek_write = 0;
}
/* quit: remove scratch file and exit */
void
quit(n)
int n;
{
if (sfp) {
unlink(sfn);
fclose(sfp);
}
exit(n);
}

376
bin/ed/cbc.c Normal file
View File

@ -0,0 +1,376 @@
/* cbc.c: This file contains the encryption routines for the ed line editor */
/*-
* Copyright (c) 1991 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.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, 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
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static char sccsid[] = "@(#)cbc.c 5.5 (Berkeley) 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).
*/
#ifdef DES
#include <errno.h>
#include <pwd.h>
#include <unistd.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
/*
* Define a divisor for rand() that yields a uniform distribution in the
* range 0-255.
*/
#define RAND_DIV (((unsigned) RAND_MAX + 1) >> 8)
/*
* BSD and System V systems offer special library calls that do
* block moves and fills, so if possible we take advantage of them
*/
#define MEMCPY(dest,src,len) bcopy((src),(dest),(len))
#define MEMZERO(dest,len) bzero((dest),(len))
/* Hide the calls to the primitive encryption routines. */
#define DES_KEY(buf) \
if (des_setkey(buf)) \
err("des_setkey");
#define DES_XFORM(buf) \
if (des_cipher(buf, buf, 0L, (inverse ? -1 : 1))) \
err("des_cipher");
/*
* read/write - no error checking
*/
#define READ(buf, n, fp) fread(buf, sizeof(char), n, fp)
#define WRITE(buf, n, fp) fwrite(buf, sizeof(char), n, fp)
/*
* some things to make references easier
*/
typedef char Desbuf[8];
#define CHAR(x,i) (x[i])
#define UCHAR(x,i) (x[i])
#define BUFFER(x) (x)
#define UBUFFER(x) (x)
/*
* global variables and related macros
*/
enum { /* encrypt, decrypt, authenticate */
MODE_ENCRYPT, MODE_DECRYPT, MODE_AUTHENTICATE
} mode = MODE_ENCRYPT;
Desbuf ivec; /* initialization vector */
Desbuf pvec; /* padding vector */
char bits[] = { /* used to extract bits from a char */
'\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'
};
int pflag; /* 1 to preserve parity bits */
/*
* initialize cbc
*/
void
cbcinit()
{
int i;
/* initialize the initialization vctor */
MEMZERO(ivec, 8);
/* intialize the padding vector */
srand((unsigned) time((time_t *) 0));
for (i = 0; i < 8; i++)
CHAR(pvec, i) = (char) (rand()/RAND_DIV);
}
/*
* get keyword from tty or stdin
*/
getkey()
{
register char *p; /* used to obtain the key */
Desbuf msgbuf; /* I/O buffer */
/*
* get the key
*/
if (*(p = getpass("Enter key: "))) {
/*
* copy it, nul-padded, into the key area
*/
cvtkey(BUFFER(msgbuf), p);
MEMZERO(p, _PASSWORD_LEN);
makekey(msgbuf);
MEMZERO(msgbuf, sizeof msgbuf);
return 1;
}
return 0;
}
/*
* print a warning message and, possibly, terminate
*/
err(s)
char *s; /* the message */
{
(void)fprintf(stderr, "?%s\n", s ? s : strerror(errno));
}
/*
* map a hex character to an integer
*/
tobinhex(c, radix)
char c; /* char to be converted */
int radix; /* base (2 to 16) */
{
switch(c) {
case '0': return(0x0);
case '1': return(0x1);
case '2': return(radix > 2 ? 0x2 : -1);
case '3': return(radix > 3 ? 0x3 : -1);
case '4': return(radix > 4 ? 0x4 : -1);
case '5': return(radix > 5 ? 0x5 : -1);
case '6': return(radix > 6 ? 0x6 : -1);
case '7': return(radix > 7 ? 0x7 : -1);
case '8': return(radix > 8 ? 0x8 : -1);
case '9': return(radix > 9 ? 0x9 : -1);
case 'A': case 'a': return(radix > 10 ? 0xa : -1);
case 'B': case 'b': return(radix > 11 ? 0xb : -1);
case 'C': case 'c': return(radix > 12 ? 0xc : -1);
case 'D': case 'd': return(radix > 13 ? 0xd : -1);
case 'E': case 'e': return(radix > 14 ? 0xe : -1);
case 'F': case 'f': return(radix > 15 ? 0xf : -1);
}
/*
* invalid character
*/
return(-1);
}
/*
* convert the key to a bit pattern
*/
cvtkey(obuf, ibuf)
char *obuf; /* bit pattern */
char *ibuf; /* the key itself */
{
register int i, j; /* counter in a for loop */
int nbuf[64]; /* used for hex/key translation */
/*
* leading '0x' or '0X' == hex key
*/
if (ibuf[0] == '0' && (ibuf[1] == 'x' || ibuf[1] == 'X')) {
ibuf = &ibuf[2];
/*
* now translate it, bombing on any illegal hex digit
*/
for (i = 0; ibuf[i] && i < 16; i++)
if ((nbuf[i] = tobinhex(ibuf[i], 16)) == -1)
err("bad hex digit in key");
while (i < 16)
nbuf[i++] = 0;
for (i = 0; i < 8; i++)
obuf[i] =
((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf);
/* preserve parity bits */
pflag = 1;
return;
}
/*
* leading '0b' or '0B' == binary key
*/
if (ibuf[0] == '0' && (ibuf[1] == 'b' || ibuf[1] == 'B')) {
ibuf = &ibuf[2];
/*
* now translate it, bombing on any illegal binary digit
*/
for (i = 0; ibuf[i] && i < 16; i++)
if ((nbuf[i] = tobinhex(ibuf[i], 2)) == -1)
err("bad binary digit in key");
while (i < 64)
nbuf[i++] = 0;
for (i = 0; i < 8; i++)
for (j = 0; j < 8; j++)
obuf[i] = (obuf[i]<<1)|nbuf[8*i+j];
/* preserve parity bits */
pflag = 1;
return;
}
/*
* no special leader -- ASCII
*/
(void)strncpy(obuf, ibuf, 8);
}
/*****************
* DES FUNCTIONS *
*****************/
/*
* This sets the DES key and (if you're using the deszip version)
* the direction of the transformation. This uses the Sun
* to map the 64-bit key onto the 56 bits that the key schedule
* generation routines use: the old way, which just uses the user-
* supplied 64 bits as is, and the new way, which resets the parity
* bit to be the same as the low-order bit in each character. The
* new way generates a greater variety of key schedules, since many
* systems set the parity (high) bit of each character to 0, and the
* DES ignores the low order bit of each character.
*/
makekey(buf)
Desbuf buf; /* key block */
{
register int i, j; /* counter in a for loop */
register int par; /* parity counter */
/*
* if the parity is not preserved, flip it
*/
if (!pflag) {
for (i = 0; i < 8; i++) {
par = 0;
for (j = 1; j < 8; j++)
if ((bits[j]&UCHAR(buf, i)) != 0)
par++;
if ((par&01) == 01)
UCHAR(buf, i) = UCHAR(buf, i)&0177;
else
UCHAR(buf, i) = (UCHAR(buf, i)&0177)|0200;
}
}
DES_KEY(UBUFFER(buf));
}
/*
* This encrypts using the Cipher Block Chaining mode of DES
*/
cbcenc(msgbuf, n, fp)
char *msgbuf;
int n;
FILE *fp;
{
int inverse = 0; /* 0 to encrypt, 1 to decrypt */
/*
* do the transformation
*/
if (n == 8) {
for (n = 0; n < 8; n++)
CHAR(msgbuf, n) ^= CHAR(ivec, n);
DES_XFORM(UBUFFER(msgbuf));
MEMCPY(BUFFER(ivec), BUFFER(msgbuf), 8);
return WRITE(BUFFER(msgbuf), 8, fp);
}
/*
* at EOF or last block -- in either case, the last byte contains
* the character representation of the number of bytes in it
*/
/*
MEMZERO(msgbuf + n, 8 - n);
*/
/*
* Pad the last block randomly
*/
(void)MEMCPY(BUFFER(msgbuf + n), BUFFER(pvec), 8 - n);
CHAR(msgbuf, 7) = n;
for (n = 0; n < 8; n++)
CHAR(msgbuf, n) ^= CHAR(ivec, n);
DES_XFORM(UBUFFER(msgbuf));
return WRITE(BUFFER(msgbuf), 8, fp);
}
/*
* This decrypts using the Cipher Block Chaining mode of DES
*/
cbcdec(msgbuf, fp)
char *msgbuf; /* I/O buffer */
FILE *fp; /* input file descriptor */
{
Desbuf ibuf; /* temp buffer for initialization vector */
register int n; /* number of bytes actually read */
register int c; /* used to test for EOF */
register int bn; /* block number */
int inverse = 1; /* 0 to encrypt, 1 to decrypt */
if ((n = READ(BUFFER(msgbuf), 8, fp)) == 8) {
/*
* do the transformation
*/
MEMCPY(BUFFER(ibuf), BUFFER(msgbuf), 8);
DES_XFORM(UBUFFER(msgbuf));
for (c = 0; c < 8; c++)
UCHAR(msgbuf, c) ^= UCHAR(ivec, c);
MEMCPY(BUFFER(ivec), BUFFER(ibuf), 8);
/*
* if the last one, handle it specially
*/
if ((c = fgetc(fp)) == EOF) {
n = CHAR(msgbuf, 7);
if (n < 0 || n > 7) {
err("decryption failed (block corrupted)");
return EOF;
}
} else
(void)ungetc(c, fp);
return n;
}
if (n > 0)
err("decryption failed (incomplete block)");
return EOF;
}
#endif /* DES */

1314
bin/ed/doc/ed-1003.2 Normal file

File diff suppressed because it is too large Load Diff

50
bin/ed/doc/extensions Normal file
View File

@ -0,0 +1,50 @@
This version of ed is not strictly POSIX compliant, as described in the
POSIX 1003.2 Draft 11.2 document (see the file `ed-1003.2'). BSD commands
have been implemented wherever they do not conflict with the POSIX
standard. This includes the BSD `W' command for appending text to an
existing file; the BSD `s' command (i.e., s[rgp]*) to repeat a previous
substitution; the BSD `z' command for scrolling through the buffer; and
the BSD `wq' command for exiting after write. BSD line addressing syntax
(i.e., `^' and `%' - see the file `legal.addrs') is also recognized.
The POSIX interactive global commands `G' and `V' are extended to support
multiple commands, including `a', `i' and `c'. The command format is the
same as for the global commands `g' and `v', i.e., one command per line
with each line, except for the last, ending in a backslash (\).
If crypt is available, files can be read and written using DES encryption.
The `x' command prompts the user to enter a key for encrypting/decrypting
subsequent reads and writes. If only a newline is entered as the key,
then encryption is disabled. Otherwise, a key is read with echoing turned
off until a newline is entered. For more information on the encryption
algorithm, see the bdes(1) man page. Encryption/decryption should be
fully compatible with SunOS DES.
An extension to the POSIX file commands `E', `e', `r', `W' and `w' is that
<file> arguments are processed for backslash (\) escapes, i.e., any
character preceded by a backslash is interpreted literally. A trailing
backslash is ignored. If the first unescaped character of a <file>
argument is a bang (!), then the rest of the line is interpreted as a
shell command and no escape processing is performed by ed. This rule does
not apply to the 'f' command (described below).
While the default file name cannot be set to a shell command (i.e.,
!<shell-cmd>) via any of the `r', `w', and `e' commands, POSIX evidently
does not preclude using the `f' command for this purpose. Upon reading
or writing the default file when its name begins with a bang (!), ed
interprets the rest of the line as a shell command and attempts to execute
it. Escape processing is not performed in this case. The `f' command
can be used in this way as a simple macro function. For example, after
setting the default file name to `!echo hello, world', the command `.r'
inserts the line `hello world' after the current line. The `f' command
with no arguments prints the default unescaped file name.
--
The following commands are neither part of POSIX 1003.2 D11/2 nor are
they supported in this version of ed.
The vi command: (addr1,addr2) !<shell-cmd> which replaces a range of
lines with the output of a shell command is not supported.
The vi command: [rwe] !!, where !! is replaced by the previous
!<shell-cmd> is not supported.

50
bin/ed/doc/legal.addrs Normal file
View File

@ -0,0 +1,50 @@
The following describes line addressing syntax. This is a combination of
both BSD and POSIX.
Addresses are computed from left to right relative to the current address.
Addresses in a pair are separated by either a comma or a semi-colon. If
a semi-colon is used as a separator instead of a comma, then the pair is
interpreted as only a single address (though syntactically still a pair)
as follows: the first address is computed, and the current address is
set to this address; then the second address is computed relative to the
new current address.
If multiple separated addresses are given, then only the last pair is
used. Address pairs are not legal where only a single address is expected.
Addresses may be composed of the following:
. - current line
$ - last line
- - previous line - may be repeated
-<n> - <n>th previous line, where <n> is a non-negative number
^ - previous line - may be repeated (BSD)
^<n> - <n>th previous line, where <n> is a non-negative number
+ - next line - may be repeated
+<n> - <n>th next line, where <n> is a non-negative number
% - first through last lines (BSD), i.e., equivalent to: 1,$
, - first through last lines (POSIX), i.e., equivalent to: 1,$
; - current through last lines (POSIX), i.e., equivalent to: .,$
/pat/ - next line containing pattern pat
?pat? - previous line containing pattern pat
[0-9]* - line <n>, where <n> is a decimal number in the range [0,$]
<ws><n> - any whitespace <ws> after the first address followed by a number
nn is interpreted as +nn
'<lc> - line previously marked by k command, where <lc> is a
lower case letter
After the first component of an address, only digits, whitespace and
increments (i.e., `+', `-', and '^') are legal. Leading whitespace is
ignored.
Examples:
The address pair 0;+1 is equivalent to the single address 1.
The address triple 4;-1,$ is equivalent to the address pair 3,$.
The address triple 1,$;-1 is equivalent only to the single address $-1.
If the current line is 1, then the address triple +1,+2,+3 is equivalent
to the pair 3,4.
If the current line is 1, then the address triple +1;+2,+3 is equivalent
to the pair 4,5.
The command t$;-1 is invalid because, syntactically, $;-1 is an address
pair. The correct syntax is t$-.
The command 0;/pat/;// prints the second line containing the pattern pat.

48
bin/ed/doc/legal.cmds Normal file
View File

@ -0,0 +1,48 @@
The following commands are recognized. These are a combination of BSD
and POSIX. The POSIX version of a command always overrides any
BSD version. The commands are shown together with their permissible number
of addresses.
!<shell-cmd> - run <shell-cmd> via sh {1} (POSIX)
($)= - print line number
E <file> - edit a file unconditionally {1}
E !<shell-cmd> - edit the standard output of <shell-cmd> {1} (POSIX)
(1,$)G/pat/ - interactively edit lines matching a pattern (POSIX) {1}
H - print explanations of all errors (POSIX)
P - toggle command prompt (POSIX)
Q - quit ed unconditionally
(1,$)V - interactively edit lines not matching a pattern (POSIX) {1}
(1,$)W - append lines to a file (BSD)
(.)a - append text to the buffer
(.,.)c - change lines in the buffer
(.,.)d - delete lines from the buffer
e <file> - edit a file {1}
e !<shell-cmd> - edit the standard output of shell-cmd {1} (POSIX)
f <file> - set the default file to <file> {1}
(1,$)g/pat/<cmd-list> - apply <cmd-list> to lines matching a pattern
h - print explanation of the last error (POSIX)
(.)i - insert text in the buffer
(.,.+1)j - join lines in the buffer
(.)k<lc> - mark a line for later '<lc> addressing
(.,.)l - print lines unambiguously to stdout
(.,.)m<addr> - move lines in the buffer
(.,.)n - enumerate lines to stdout (POSIX)
(.,.)p - print lines to stdout
q - quit ed
($)r <file> - read a file {1}
($)r !<shell-cmd> - read the stdout of <shell-cmd> {1} (POSIX)
(.,.)s/pat/sub/g - substitute matching text in a line via a template
(.,.)s/pat/sub/<n> - substitute the <n>th match in a line (POSIX)
(.,.)s[rgp]* - repeat the last substitution (BSD)
(.,.)t<addr> - copy (transfer) lines in the buffer
u - undo the last command (POSIX)
(1,$)v/pat/<cmd-list> - apply <cmd-list> to lines not matching a pattern
(1,$)w <file> - write lines in the buffer to a file
(1,$)w !<shell-cmd> - write lines to the stdin of <shell-cmd> (POSIX)
x - prompt for an encryption key (SunOS) {1}
(.,.+22)z - page lines in the buffer to stdout (BSD)
(.,.)<newline> - print lines to stdout (BSD)
--
{1} See the file `extensions' for additional information on these
commands.

1969
bin/ed/ed.c Normal file

File diff suppressed because it is too large Load Diff

204
bin/ed/ed.h Normal file
View File

@ -0,0 +1,204 @@
/* ed.h: type and constant definitions for the ed editor. */
/*
* Copyright (c) 1993 The Regents of the University of California.
* 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:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, 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
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ed.h 5.5 (Berkeley) 3/28/93
*/
#include <unistd.h>
# include <regex.h>
#if defined(BSD) && BSD >= 199103 || defined(__386BSD__)
# include <sys/param.h> /* for MAXPATHLEN */
#endif
#define BITSPERBYTE 8
#define BITS(type) (BITSPERBYTE * (int)sizeof(type))
#define CHARBITS BITS(char)
#define INTBITS BITS(int)
#define ESCHAR '\\'
#define CCL '[' /* Character class: [...] */
#define CCLEND ']'
#define DITTO '&'
/* sigflags values */
#define SIG_INT 1
#define SIG_HUP 2
#define TRUE 1
#define FALSE 0
#define ERR (-2)
#define EMOD (ERR - 1)
#ifndef MAXPATHLEN
# define MAXPATHLEN 255 /* _POSIX_PATH_MAX */
#endif
#define MAXFNAME MAXPATHLEN /* max file name size */
#define MAXLINE (4 << 10) /* max number of chars per line */
#define SE_MAX 30 /* max subexpressions in a regular expression */
typedef regex_t pattern_t;
#ifdef GNU_REGEX
# define FASTMAP_SIZE 256 /* size of fastmap for 8 bit character set */
#endif
/* Line node */
typedef struct line {
struct line *next;
struct line *prev;
off_t seek; /* address of line in scratch buffer */
#define ACTV (1 << (INTBITS - 1)) /* active status: high bit of len */
int len; /* length of line */
} line_t;
typedef struct undo {
/* type of undo nodes */
#define UADD 0
#define UDEL 1
int type; /* command type */
line_t *h; /* head of list */
line_t *t; /* tail of list */
} undo_t;
#ifndef max
# define max(a,b) ((a) > (b) ? (a) : (b))
#endif
#ifndef min
# define min(a,b) ((a) < (b) ? (a) : (b))
#endif
/* nextln: return line after l wrt k */
#define nextln(l,k) ((l)+1 > (k) ? 0 : (l)+1)
/* nextln: return line before l wrt k */
#define prevln(l,k) ((l)-1 < 0 ? (k) : (l)-1)
#define skipblanks() while (isspace(*ibufp) && *ibufp != '\n') ibufp++
/* spl1: disable some interrupts (requires reliable signals) */
#define spl1() mutex++
/* spl0: enable all interrupts; check sigflags (requires reliable signals) */
#define spl0() \
if (--mutex == 0) { \
if (sigflags & SIG_HUP) dohup(); \
if (sigflags & SIG_INT) dointr(); \
}
/* requeue: link pred before succ */
#define requeue(pred, succ) (pred)->next = (succ), (succ)->prev = (pred)
/* insqueue: insert elem in circular queue after pred */
#define insqueue(elem, pred) \
{ \
requeue((elem), (pred)->next); \
requeue((pred), elem); \
}
/* remqueue: remove elem from circular queue */
#define remqueue(elem) requeue((elem)->prev, (elem)->next);
#ifndef __P
# ifndef __STDC__
# define __P(proto) ()
# else
# define __P(proto) proto
# endif
#endif
/* local function declarations */
int append __P((long, int));
int cbcdec __P((char *, FILE *));
int cbcenc __P((char *, int, FILE *));
void cbcinit __P((void));
int ckglob __P((void));
int deflt __P((long, long));
int del __P((long, long));
int desgetc __P((FILE *));
FILE *desopen __P((char *, char *));
int desputc __P((int, FILE *));
int docmd __P((int));
char *ccl __P((int, char *));
long doglob __P((void));
void dohup __P((void));
void dointr __P((void));
int doprnt __P((long, long, int));
long doread __P((long, char *));
long dowrite __P((long, long, char *, char *));
char *esctos __P((char *));
long find __P((pattern_t *, int));
void freecmdv __P((void));
char *getcmdv __P((void));
char *getfn __P((void));
int getkey __P((void));
char *getlhs __P((int));
int getline __P((char *, int));
int getlist __P((void));
long getnum __P((int));
long getone __P((void));
line_t *getptr __P((long));
long getrange __P((line_t *, line_t *));
int getrhs __P((char *, int));
char *gettxt __P((line_t *));
undo_t *getuptr __P((int, long, long));
int join __P((long, long));
line_t *lpdup __P((line_t *));
void lpqueue __P((line_t *));
char *makesub __P((char *, int, int));
int move __P((long, int));
int oddesc __P((char *, char *));
void onhup __P((int));
void onintr __P((int));
pattern_t *optpat __P((void));
void prntln __P((char *, long, int));
char *puttxt __P((char *));
void quit __P((int));
char *regsub __P((pattern_t *, char *, char *, int));
int sbclose __P((void));
int sbopen __P((void));
int sgetline __P((char *, int, FILE *));
char *subcat __P((char *, regmatch_t *, char *, char *, char *));
int subst __P((pattern_t *, char *, int));
int transfer __P((long));
int undo __P((void));
void ureset __P((void));

142
bin/ed/re.c Normal file
View File

@ -0,0 +1,142 @@
/* 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.
* 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:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, 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
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static char sccsid[] = "@(#)re.c 5.5 (Berkeley) 3/28/93";
#endif /* not lint */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ed.h"
extern char *ibufp;
extern int patlock;
char errmsg[MAXFNAME + 40] = "";
/* optpat: return pointer to compiled pattern from command buffer */
pattern_t *
optpat()
{
static pattern_t *exp = NULL;
char *exps;
char delim;
int n;
if ((delim = *ibufp) == '\n')
return exp;
else if (delim == ' ' || *++ibufp == '\n') {
sprintf(errmsg, "invalid pattern delimiter");
return NULL;
} else if (*ibufp == delim)
return exp;
else if ((exps = getlhs(delim)) == NULL)
return NULL;
/* buffer alloc'd && not reserved */
if (exp && !patlock)
regfree(exp);
else if ((exp = (pattern_t *) malloc(sizeof(pattern_t))) == NULL) {
fprintf(stderr, "out of memory\n");
return NULL;
}
patlock = 0;
#ifdef GNU_REGEX
/* initialize pattern buffer */
exp->buffer = NULL;
exp->allocated = 0L;
exp->fastmap = (char *) malloc(FASTMAP_SIZE);
exp->translate = 0;
#endif
if (n = regcomp(exp, exps, 0)) {
regerror(n, exp, errmsg, sizeof errmsg);
return NULL;
}
return exp;
}
/* getlhs: copy a pattern string from the command buffer; return pointer
to the copy */
char *
getlhs(delim)
int delim;
{
static char buf[MAXLINE];
char *nd;
for (nd = ibufp; *nd != delim && *nd != '\n'; nd++)
switch (*nd) {
default:
break;
case CCL:
if ((nd = ccl(CCLEND, ++nd)) == NULL) {
sprintf(errmsg, "unbalanced brackets ([])");
return NULL;
}
break;
case ESCHAR:
if (*++nd == '\n') {
sprintf(errmsg, "trailing backslash (\\)");
return NULL;
}
break;
}
strncpy(buf, ibufp, nd - ibufp);
buf[nd - ibufp] = '\0';
ibufp = nd;
return buf;
}
/* ccl: expand a character class */
char *
ccl(delim, src)
int delim;
char *src;
{
if (*src == '^')
src++;
if (*src == delim)
src++;
while (*src != delim && *src != '\n')
src++;
return (*src == delim) ? src : NULL;
}

0
bin/ed/test/!.d Normal file
View File

10
bin/ed/test/!.ed Normal file
View File

@ -0,0 +1,10 @@
#!/bin/sh -
../ed - <<\EOT
r \!.d
!read one
hello, world
a
okay
.
w \!.o
EOT

1
bin/ed/test/!.o Normal file
View File

@ -0,0 +1 @@
okay

1
bin/ed/test/!.r Normal file
View File

@ -0,0 +1 @@
okay

5
bin/ed/test/!.t Normal file
View File

@ -0,0 +1,5 @@
!read one
hello, world
a
okay
.

5
bin/ed/test/!.z Normal file
View File

@ -0,0 +1,5 @@
line 1
line 2
line 3
line 4
line5

16
bin/ed/test/Makefile Normal file
View File

@ -0,0 +1,16 @@
ED= ../ed
all: mkscripts ckscripts
mkscripts: mkscripts.sh
@echo building test scripts...
@chmod +x mkscripts.sh
@ED=${ED} mkscripts.sh
ckscripts: ckscripts.sh
@echo running test scripts...
@chmod +x ckscripts.sh
@ED=${ED} ckscripts.sh
clean:
rm -f *.ed *.[oz]

18
bin/ed/test/README Normal file
View File

@ -0,0 +1,18 @@
The .t and .d and .r files in this directory are used for testing ed.
To run the tests, set the ED variable in the Makefile for the path name
of the program to be tested (e.g., /bin/ed), and type `make'.
Some spurious data may appear as the test runs. Errors appear
as:
*** The script u.ed exited abnormally ***
or:
*** Output u.o of script u.ed is incorrect ***
It is assumed that the ed being tested processes escapes (\) in file names.
This is so that a name starting with bang (!) can be read, via:
r \!file
Without the escape, a POSIX ed would attempt to read the output of
the shell command `file'.
Though numerous, the tests are very incomplete. Please send any new
tests/bug reports to: alm@netcom.com

5
bin/ed/test/a.d Normal file
View File

@ -0,0 +1,5 @@
line 1
line 2
line 3
line 4
line5

14
bin/ed/test/a.ed Normal file
View File

@ -0,0 +1,14 @@
#!/bin/sh -
../ed - <<\EOT
r \a.d
0a
hello world
.
2a
hello world!
.
$a
hello world!!
.
w \a.o
EOT

8
bin/ed/test/a.o Normal file
View File

@ -0,0 +1,8 @@
hello world
line 1
hello world!
line 2
line 3
line 4
line5
hello world!!

8
bin/ed/test/a.r Normal file
View File

@ -0,0 +1,8 @@
hello world
line 1
hello world!
line 2
line 3
line 4
line5
hello world!!

9
bin/ed/test/a.t Normal file
View File

@ -0,0 +1,9 @@
0a
hello world
.
2a
hello world!
.
$a
hello world!!
.

5
bin/ed/test/c.d Normal file
View File

@ -0,0 +1,5 @@
line 1
line 2
line 3
line 4
line5

17
bin/ed/test/c.ed Normal file
View File

@ -0,0 +1,17 @@
#!/bin/sh -
../ed - <<\EOT
r \c.d
1c
at the top
.
4c
in the middle
.
$c
at the bottom
.
2,3c
between top/middle
.
w \c.o
EOT

4
bin/ed/test/c.o Normal file
View File

@ -0,0 +1,4 @@
at the top
between top/middle
in the middle
at the bottom

4
bin/ed/test/c.r Normal file
View File

@ -0,0 +1,4 @@
at the top
between top/middle
in the middle
at the bottom

12
bin/ed/test/c.t Normal file
View File

@ -0,0 +1,12 @@
1c
at the top
.
4c
in the middle
.
$c
at the bottom
.
2,3c
between top/middle
.

22
bin/ed/test/ckscripts.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/sh -
# This script runs the .ed scripts generated by mkscripts.sh
# and compares their output against the .r files, which contain
# the correct output
PATH="/bin:/usr/bin:/usr/local/bin/:."
[ X"$ED" = X ] && ED="../ed"
for i in *.ed; do
base=`echo $i | sed 's/\..*/'`
# base=`$ED - <<-EOF
# r !echo $i
# s/\..*
# EOF`
if $base.ed >/dev/null 2>&1; then
if cmp -s $base.o $base.r; then :; else
echo "*** Output $base.o of script $i is incorrect ***"
fi
else
echo "*** The script $i exited abnormally ***"
fi
done

5
bin/ed/test/d.d Normal file
View File

@ -0,0 +1,5 @@
line 1
line 2
line 3
line 4
line5

8
bin/ed/test/d.ed Normal file
View File

@ -0,0 +1,8 @@
#!/bin/sh -
../ed - <<\EOT
r \d.d
1d
2,3d
$d
w \d.o
EOT

1
bin/ed/test/d.o Normal file
View File

@ -0,0 +1 @@
line 2

1
bin/ed/test/d.r Normal file
View File

@ -0,0 +1 @@
line 2

3
bin/ed/test/d.t Normal file
View File

@ -0,0 +1,3 @@
1d
2,3d
$d

1
bin/ed/test/e1.d Normal file
View File

@ -0,0 +1 @@
hello world

6
bin/ed/test/e1.ed Normal file
View File

@ -0,0 +1,6 @@
#!/bin/sh -
../ed - <<\EOT
r \e1.d
E e1.t
w \e1.o
EOT

1
bin/ed/test/e1.o Normal file
View File

@ -0,0 +1 @@
E e1.t

1
bin/ed/test/e1.r Normal file
View File

@ -0,0 +1 @@
E e1.t

1
bin/ed/test/e1.t Normal file
View File

@ -0,0 +1 @@
E e1.t

1
bin/ed/test/e2.d Normal file
View File

@ -0,0 +1 @@
E !echo hello world-

6
bin/ed/test/e2.ed Normal file
View File

@ -0,0 +1,6 @@
#!/bin/sh -
../ed - <<\EOT
r \e2.d
E !echo hello world-
w \e2.o
EOT

1
bin/ed/test/e2.o Normal file
View File

@ -0,0 +1 @@
hello world-

1
bin/ed/test/e2.r Normal file
View File

@ -0,0 +1 @@
hello world-

1
bin/ed/test/e2.t Normal file
View File

@ -0,0 +1 @@
E !echo hello world-

1
bin/ed/test/e3.d Normal file
View File

@ -0,0 +1 @@
E !echo hello world-

6
bin/ed/test/e3.ed Normal file
View File

@ -0,0 +1,6 @@
#!/bin/sh -
../ed - <<\EOT
r \e3.d
E
w \e3.o
EOT

1
bin/ed/test/e3.o Normal file
View File

@ -0,0 +1 @@
E !echo hello world-

1
bin/ed/test/e3.r Normal file
View File

@ -0,0 +1 @@
E !echo hello world-

1
bin/ed/test/e3.t Normal file
View File

@ -0,0 +1 @@
E

5
bin/ed/test/g1.d Normal file
View File

@ -0,0 +1,5 @@
line 1
line 2
line 3
line 4
line5

11
bin/ed/test/g1.ed Normal file
View File

@ -0,0 +1,11 @@
#!/bin/sh -
../ed - <<\EOT
r \g1.d
g/./m0
g/./s/$/\
hello world
g/hello /s/lo/p!/\
a\
order
w \g1.o
EOT

15
bin/ed/test/g1.o Normal file
View File

@ -0,0 +1,15 @@
line5
help! world
order
line 4
help! world
order
line 3
help! world
order
line 2
help! world
order
line 1
help! world
order

15
bin/ed/test/g1.r Normal file
View File

@ -0,0 +1,15 @@
line5
help! world
order
line 4
help! world
order
line 3
help! world
order
line 2
help! world
order
line 1
help! world
order

6
bin/ed/test/g1.t Normal file
View File

@ -0,0 +1,6 @@
g/./m0
g/./s/$/\
hello world
g/hello /s/lo/p!/\
a\
order

5
bin/ed/test/g2.d Normal file
View File

@ -0,0 +1,5 @@
line 1
line 2
line 3
line 4
line5

7
bin/ed/test/g2.ed Normal file
View File

@ -0,0 +1,7 @@
#!/bin/sh -
../ed - <<\EOT
r \g2.d
g/[2-4]/-1,+1c\
hello world
w \g2.o
EOT

1
bin/ed/test/g2.o Normal file
View File

@ -0,0 +1 @@
hello world

1
bin/ed/test/g2.r Normal file
View File

@ -0,0 +1 @@
hello world

2
bin/ed/test/g2.t Normal file
View File

@ -0,0 +1,2 @@
g/[2-4]/-1,+1c\
hello world

5
bin/ed/test/i.d Normal file
View File

@ -0,0 +1,5 @@
line 1
line 2
line 3
line 4
line5

14
bin/ed/test/i.ed Normal file
View File

@ -0,0 +1,14 @@
#!/bin/sh -
../ed - <<\EOT
r \i.d
1i
hello world
.
2i
hello world!
.
$i
hello world!!
.
w \i.o
EOT

8
bin/ed/test/i.o Normal file
View File

@ -0,0 +1,8 @@
hello world
hello world!
line 1
line 2
line 3
line 4
hello world!!
line5

8
bin/ed/test/i.r Normal file
View File

@ -0,0 +1,8 @@
hello world
hello world!
line 1
line 2
line 3
line 4
hello world!!
line5

9
bin/ed/test/i.t Normal file
View File

@ -0,0 +1,9 @@
1i
hello world
.
2i
hello world!
.
$i
hello world!!
.

5
bin/ed/test/j.d Normal file
View File

@ -0,0 +1,5 @@
line 1
line 2
line 3
line 4
line5

7
bin/ed/test/j.ed Normal file
View File

@ -0,0 +1,7 @@
#!/bin/sh -
../ed - <<\EOT
r \j.d
1,1j
2,3j
w \j.o
EOT

4
bin/ed/test/j.o Normal file
View File

@ -0,0 +1,4 @@
line 1
line 2line 3
line 4
line5

4
bin/ed/test/j.r Normal file
View File

@ -0,0 +1,4 @@
line 1
line 2line 3
line 4
line5

2
bin/ed/test/j.t Normal file
View File

@ -0,0 +1,2 @@
1,1j
2,3j

0
bin/ed/test/l.d Normal file
View File

5
bin/ed/test/l.ed Normal file
View File

@ -0,0 +1,5 @@
#!/bin/sh -
../ed - <<\EOT
r \l.d
w \l.o
EOT

0
bin/ed/test/l.o Normal file
View File

0
bin/ed/test/l.r Normal file
View File

0
bin/ed/test/l.t Normal file
View File

5
bin/ed/test/m.d Normal file
View File

@ -0,0 +1,5 @@
line 1
line 2
line 3
line 4
line5

12
bin/ed/test/m.ed Normal file
View File

@ -0,0 +1,12 @@
#!/bin/sh -
../ed - <<\EOT
r \m.d
1,2m$
1,2m$
1,2m$
$m0
$m0
2,3m1
2,3m3
w \m.o
EOT

5
bin/ed/test/m.o Normal file
View File

@ -0,0 +1,5 @@
line5
line 1
line 2
line 3
line 4

5
bin/ed/test/m.r Normal file
View File

@ -0,0 +1,5 @@
line5
line 1
line 2
line 3
line 4

7
bin/ed/test/m.t Normal file
View File

@ -0,0 +1,7 @@
1,2m$
1,2m$
1,2m$
$m0
$m0
2,3m1
2,3m3

37
bin/ed/test/mkscripts.sh Executable file
View File

@ -0,0 +1,37 @@
#!/bin/sh -
# This script generates ed test scripts (.ed) from .t files
PATH="/bin:/usr/bin:/usr/local/bin/:."
[ X"$ED" = X ] && ED="../ed"
for i in *.t; do
# base=${i%.*}
base=`echo $i | sed 's/\..*/'`
(
echo "#!/bin/sh -"
echo "$ED - <<\EOT"
echo "r \\$base.d"
cat $i
echo "w \\$base.o"
echo EOT
) >$base.ed
chmod +x $base.ed
# The following is pretty ugly and not appropriate use of ed
# but the point is that it can be done...
# base=`$ED - <<-EOF
# r !echo $i
# s/\..*
# EOF`
# $ED - <<-EOF
# a
# #!/bin/sh -
# $ED - <<\EOT
# r \\$base.d
# w \\$base.o
# EOT
# .
# -2r \\$i
# w \\$base.ed
# !chmod +x $base.ed
# EOF
done

0
bin/ed/test/n.d Normal file
View File

5
bin/ed/test/n.ed Normal file
View File

@ -0,0 +1,5 @@
#!/bin/sh -
../ed - <<\EOT
r \n.d
w \n.o
EOT

0
bin/ed/test/n.o Normal file
View File

0
bin/ed/test/n.r Normal file
View File

0
bin/ed/test/n.t Normal file
View File

0
bin/ed/test/p.d Normal file
View File

5
bin/ed/test/p.ed Normal file
View File

@ -0,0 +1,5 @@
#!/bin/sh -
../ed - <<\EOT
r \p.d
w \p.o
EOT

0
bin/ed/test/p.o Normal file
View File

0
bin/ed/test/p.r Normal file
View File

0
bin/ed/test/p.t Normal file
View File

5
bin/ed/test/r1.d Normal file
View File

@ -0,0 +1,5 @@
line 1
line 2
line 3
line 4
line5

8
bin/ed/test/r1.ed Normal file
View File

@ -0,0 +1,8 @@
#!/bin/sh -
../ed - <<\EOT
r \r1.d
1;r !echo hello world
1
r !echo hello world
w \r1.o
EOT

7
bin/ed/test/r1.o Normal file
View File

@ -0,0 +1,7 @@
line 1
hello world
line 2
line 3
line 4
line5
hello world

7
bin/ed/test/r1.r Normal file
View File

@ -0,0 +1,7 @@
line 1
hello world
line 2
line 3
line 4
line5
hello world

3
bin/ed/test/r1.t Normal file
View File

@ -0,0 +1,3 @@
1;r !echo hello world
1
r !echo hello world

5
bin/ed/test/r2.d Normal file
View File

@ -0,0 +1,5 @@
line 1
line 2
line 3
line 4
line5

6
bin/ed/test/r2.ed Normal file
View File

@ -0,0 +1,6 @@
#!/bin/sh -
../ed - <<\EOT
r \r2.d
r
w \r2.o
EOT

10
bin/ed/test/r2.o Normal file
View File

@ -0,0 +1,10 @@
line 1
line 2
line 3
line 4
line5
line 1
line 2
line 3
line 4
line5

10
bin/ed/test/r2.r Normal file
View File

@ -0,0 +1,10 @@
line 1
line 2
line 3
line 4
line5
line 1
line 2
line 3
line 4
line5

Some files were not shown because too many files have changed in this diff Show More