beattie@netxcom.UUCP (Brian Beattie) (06/19/87)
This is an editor ported from the Software Tools book.
Good Luck and have fun.
----------------------- cut here ---------------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# ReadMe
# Makefile
# amatch.c
# append.c
# bitmap.c
# catsub.c
# ckglob.c
# deflt.c
# del.c
# docmd.c
# dodash.c
# doglob.c
# doprnt.c
# doread.c
# egets.c
# esc.c
# find.c
# getlst.c
# getnum.c
# getone.c
# getpat.c
# getptr.c
# getrhs.c
# gettxt.c
# ins.c
# maksub.c
# matchs.c
# move.c
# omatch.c
# optpat.c
# set.c
# setbuf.c
# subst.c
# system.c
# This archive created: Thu Jun 18 21:08:37 1987
export PATH; PATH=/bin:$PATH
if test -f 'ReadMe'
then
echo shar: will not over-write existing file "'ReadMe'"
else
cat << \SHAR_EOF > 'ReadMe'
Software Tools ed.
This editor is based in the editor described in the original
Software Tools book. The code for pattern matching/regular
expressions is based on code printed in Dr. Dobbs Journal
"running light with-out overbyte".
This editor is very similar to the UNIX "ed" editor but not
identical.
SHAR_EOF
fi # end of overwriting check
if test -f 'Makefile'
then
echo shar: will not over-write existing file "'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
.SUFFIXES: .c .s
CFLAGS = -F -T. -O
SRCS = append.c catsub.c ckglob.c deflt.c del.c docmd.c doglob.c\
doprnt.c doread.c dowrite.c ed.c egets.c find.c getfn.c getlst.c\
getnum.c getone.c getptr.c getrhs.c gettxt.c ins.c maksub.c move.c\
optpat.c set.c setbuf.c subst.c stoupper.c getpat.c matchs.c amatch.c\
unmkpat.c omatch.c makepat.c bitmap.c dodash.c esc.c system.c
OBJS = append.s catsub.s ckglob.s deflt.s del.s docmd.s doglob.s\
doprnt.s doread.s dowrite.s ed.s egets.s find.s getfn.s getlst.s\
getnum.s getone.s getptr.s getrhs.s gettxt.s ins.s maksub.s move.s\
optpat.s set.s setbuf.s subst.s getpat.s matchs.s amatch.s\
unmkpat.s omatch.s makepat.s bitmap.s dodash.s esc.s system.s
ed: $(OBJS)
asld -T. -i -o ed /usr/lib/crtso.s $(OBJS) /usr/lib/libc.a /usr/lib/end.s
clean:
-rm -f $(OBJS) ed
shar:
shar Makefile ed.h tools.h $(SRCS) >ed.shar
SHAR_EOF
fi # end of overwriting check
if test -f 'amatch.c'
then
echo shar: will not over-write existing file "'amatch.c'"
else
cat << \SHAR_EOF > 'amatch.c'
#include <stdio.h>
#include "tools.h"
/* Scans throught the pattern template looking for a match
* with lin. Each element of lin is compared with the template
* until either a mis-match is found or the end of the template
* is reached. In the former case a 0 is returned; in the latter,
* a pointer into lin (pointing to the character following the
* matched pattern) is returned.
*
* "lin" is a pointer to the line being searched.
* "pat" is a pointer to a template made by makepat().
* "boln" is a pointer into "lin" which points at the
* character at the beginning of the line.
*/
char *
amatch(lin, pat, boln)
char *lin;
TOKEN *pat;
char *boln;
{
register char *bocl, *rval, *strstart;
if(pat == 0)
return 0;
strstart = lin;
while(pat)
{
if(pat->tok == CLOSURE && pat->next)
{
/* Process a closure:
* first skip over the closure token to the
* object to be repeated. This object can be
* a character class.
*/
pat = pat->next;
/* Now match as many occurrences of the
* closure pattern as possible.
*/
bocl = lin;
while( *lin && omatch(&lin, pat))
;
/* 'Lin' now points to the character that made
* made us fail. Now go on to process the
* rest of the string. A problem here is
* a character following the closure which
* could have been in the closure.
* For example, in the pattern "[a-z]*t" (which
* matches any lower-case word ending in a t),
* the final 't' will be sucked up in the while
* loop. So, if the match fails, we back up a
* notch and try to match the rest of the
* string again, repeating this process
* recursively until we get back to the
* beginning of the closure. The recursion
* goes, at most two levels deep.
*/
if(pat = pat->next)
{
while(bocl <= lin)
{
if(rval = amatch(lin, pat, boln))
{
/* success */
return(rval);
} else
--lin;
}
return (0); /* match failed */
}
} else if (omatch(&lin, pat, boln))
{
pat = pat->next;
} else {
return (0);
}
}
/* Note that omatch() advances lin to point at the next
* character to be matched. Consequently, when we reach
* the end of the template, lin will be pointing at the
* character following the last character matched. The
* exceptions are templates containing only a BOLN or EOLN
* token. In these cases omatch doesn't advance.
*
* A philosophical point should be mentioned here. Is $
* a position or a character? (i.e. does $ mean the EOL
* character itself or does it mean the character at the end
* of the line.) I decided here to make it mean the former,
* in order to make the behavior of amatch() consistent. If
* you give amatch the pattern ^$ (match all lines consisting
* only of an end of line) then, since something has to be
* returned, a pointer to the end of line character itself is
* returned.
*/
return ((char *)max(strstart , lin));
}
SHAR_EOF
fi # end of overwriting check
if test -f 'append.c'
then
echo shar: will not over-write existing file "'append.c'"
else
cat << \SHAR_EOF > 'append.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
append(line, glob)
int line, glob;
{
int stat;
char lin[MAXLINE];
char lin2[MAXLINE];
if(glob)
return(ERR);
curln = line;
while(1)
{
if(nflg)
fprintf(stdout,"%6d. ",curln+1);
if(fgets(lin, MAXLINE, stdin) == NULL)
return( EOF );
if(lin[0] == '.' && lin[1] == '\n')
return(0);
doesc(lin2, lin);
stat = ins(lin2);
if(stat < 0)
return( ERR );
}
}
doesc(dest, src)
char *dest, *src;
{
while(*src)
{
if(*src == ESCAPE)
{
src++;
if(*src < '0' || *src > '7')
switch(toupper(*++src))
{
case NL:
*dest++ == ESCAPE;
break;
case 'S':
*dest++ = SP;
src++;
break;
case 'N':
*dest++ = NL;
src++;
break;
case 'T':
*dest++ = HT;
src++;
break;
case 'B':
*dest++ = BS;
src++;
break;
case 'R':
*dest++ = CR;
src++;
break;
default:
/* all others */
*dest++ = *src;
src++;
break;
}
else {
/* do \nnn */
*dest = 0;
while(*src >= '0' && *src <= '7')
{
*dest = (*dest << 3)+(*src-'0');
src++;
}
dest++;
}
} else
/* do non-ecsaped char */
*dest++ = *src++;
}
*dest = '\0';
}
SHAR_EOF
fi # end of overwriting check
if test -f 'bitmap.c'
then
echo shar: will not over-write existing file "'bitmap.c'"
else
cat << \SHAR_EOF > 'bitmap.c'
/*
* BITMAP.C - makebitmap, setbit, testbit
* bit-map manipulation routines.
*
* Copyright (c) Allen I. Holub, all rights reserved. This program may
* for copied for personal, non-profit use only.
*
*/
#ifdef DEBUG
#include <stdio.h>
#endif
#include "tools.h"
BITMAP *makebitmap( size )
unsigned size;
{
/* Make a bit map with "size" bits. The first entry in
* the map is an "unsigned int" representing the maximum
* bit. The map itself is concatenated to this integer.
* Return a pointer to a map on success, 0 if there's
* not enough memory.
*/
unsigned *map, numbytes;
numbytes = (size >> 3) + ((size & 0x07) ? 1 : 0 );
#ifdef DEBUG
printf("Making a %d bit map (%d bytes required)\n", size, numbytes);
#endif
if( map = (unsigned *) malloc( numbytes + sizeof(unsigned) ))
*map = size;
return ((BITMAP *)map);
}
setbit( c, map, val )
unsigned c, val;
char *map;
{
/* Set bit c in the map to val.
* If c > map-size, 0 is returned, else 1 is returned.
*/
if( c >= *(unsigned *)map ) /* if c >= map size */
return 0;
map += sizeof(unsigned); /* skip past size */
if( val )
map[c >> 3] |= 1 << (c & 0x07);
else
map[c >> 3] &= ~(1 << (c & 0x07));
return( 1 );
}
testbit( c, map )
unsigned c;
char *map;
{
/* Return 1 if the bit corresponding to c in map is set.
* 0 if it is not.
*/
if( c >= *(unsigned *)map )
return 0;
map += sizeof(unsigned);
return(map[ c >> 3 ] & (1 << (c & 0x07)));
}
SHAR_EOF
fi # end of overwriting check
if test -f 'catsub.c'
then
echo shar: will not over-write existing file "'catsub.c'"
else
cat << \SHAR_EOF > 'catsub.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
char *
catsub(from, to, sub, new, newend)
char *from, *to, *sub, *new, *newend;
{
char *cp, *cp2;
for(cp = new; *sub != EOS && cp < newend;)
{
if(*sub == DITTO)
for(cp2 = from; cp2 < to;)
{
*cp++ = *cp2++;
if(cp >= newend)
break;
}
else
*cp++ = *sub;
sub++;
}
return(cp);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'ckglob.c'
then
echo shar: will not over-write existing file "'ckglob.c'"
else
cat << \SHAR_EOF > 'ckglob.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
ckglob()
{
static TOKEN *glbpat;
char c, delim, *lin;
int num, nmatch;
LINE *ptr;
c = toupper(*inptr);
nmatch = 0;
if(c == 'G' || c == 'V')
{
delim = *++inptr;
if(delim <= ' ')
return(0);
if(inptr[0] != inptr[1]) /* if null string use last */
{
glbpat = optpat(glbpat);
}
if(*inptr == delim)
inptr++;
num = curln;
while(1)
{
if(num) /* do not do zero */
{
ptr = getptr(num);
lin = gettxt(num);
if(matchs(lin, glbpat, 0))
{
ptr->l_stat = (c == 'G' ? LGLOB:LEXCL);
nmatch++;
}
}
if((num = nextln(num)) == curln)
break;
}
}
return(nmatch);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'deflt.c'
then
echo shar: will not over-write existing file "'deflt.c'"
else
cat << \SHAR_EOF > 'deflt.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
deflt(def1, def2)
int def1, def2;
{
if(nlines == 0)
{
line1 = def1;
line2 = def2;
}
if(line1 > line2 || line1 <= 0)
return (ERR);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'del.c'
then
echo shar: will not over-write existing file "'del.c'"
else
cat << \SHAR_EOF > 'del.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
del(from, to)
int from, to;
{
LINE *first, *last, *next, *tmp;
if(from < 1)
from = 1;
first = getptr(prevln(from));
last = getptr(nextln(to));
next = first->l_next;
while(next != last && next != &line0)
{
tmp = next->l_next;
free(next);
next = tmp;
}
relink(first, last, first, last);
lastln -= (to - from)+1;
curln = prevln(from);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'docmd.c'
then
echo shar: will not over-write existing file "'docmd.c'"
else
cat << \SHAR_EOF > 'docmd.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
char fname[MAXFNAME];
int fchanged;
docmd(glob)
int glob;
{
static char rhs[MAXPAT];
static TOKEN *subpat;
int c, err, line3;
int i, apflg, pflag, gflag;
int nchng;
char *fptr;
pflag = FALSE;
while(*inptr == SP && *inptr == HT)
inptr++;
c = *inptr++;
switch(c)
{
case NL:
if(nlines == 0)
{
line2 = nextln(curln);
}
curln = line2;
return (1);
break;
case '=':
printf("%6d=\n",line2);
break;
case 'A':
case 'a':
if(*inptr != NL || nlines > 1)
return(ERR);
if(append(line1, glob) < 0)
return(ERR);;
fchanged = TRUE;
break;
case 'C':
case 'c':
if(*inptr != NL)
return(ERR);
if(deflt(curln, curln) < 0)
return(ERR);
if(del(line1, line2) < 0)
return(ERR);
if(append(curln, glob) < 0)
return(ERR);
fchanged = TRUE;
break;
case 'D':
case 'd':
if(*inptr != NL)
return(ERR);
if(deflt(curln, curln) < 0)
return(ERR);
if(del(line1, line2) < 0)
return(ERR);
if(nextln(curln) != 0)
curln = nextln(curln);
fchanged = TRUE;
break;
case 'E':
case 'e':
if(nlines > 0)
return(ERR);
if(fchanged && *inptr != '!')
{
printf("File not saved\n");
return(ERR);
}
if(*inptr == '!')
inptr++;
if(*inptr != ' ' && *inptr != HT && *inptr != NL)
return(ERR);
if((fptr = getfn()) == NULL)
return(ERR);
clrbuf();
if((err = doread(0, fptr)) < 0)
return(err);
strcpy(fname, fptr);
fchanged = FALSE;
break;
case 'I':
case 'i':
if(*inptr != NL || nlines > 1)
return(ERR);
if(append(prevln(line1), glob) < 0)
return(ERR);
fchanged = TRUE;
break;
case 'M':
case 'm':
if((line3 = getone()) < 0)
return(ERR);
if(deflt(curln,curln) < 0)
return(ERR);
if(move(line3) < 0)
return(ERR);
fchanged = TRUE;
break;
case 'P':
case 'p':
if(*inptr != NL)
return(ERR);
if(deflt(curln,curln) < 0)
return(ERR);
if(doprnt(line1,line2) < 0)
return(ERR);
break;
case 'Q':
case 'q':
if(fchanged && *inptr != '!')
{
printf("File not saved\n");
return(ERR);
}
if(*inptr == '!')
inptr++;
if(*inptr == NL && nlines == 0 && !glob)
return(EOF);
else
return(ERR);
case 'R':
case 'r':
if(nlines > 1)
return(ERR);
if(nlines = 0)
line2 = lastln;
if(*inptr != ' ' && *inptr != HT && *inptr != NL)
return(ERR);
if((fptr = getfn()) == NULL)
return(ERR);
if((err = doread(line2, fptr)) < 0)
return(err);
fchanged = TRUE;
break;
case 'S':
case 's':
if(toupper(*inptr) == 'E')
return(set());
while(*inptr == SP || *inptr == HT)
inptr++;
if((subpat = optpat(subpat)) == NULL)
return(ERR);
if((gflag = getrhs(rhs)) < 0)
return(ERR);
if(toupper(*inptr) == 'P')
pflag++;
if(deflt(curln, curln) < 0)
return(ERR);
if((nchng = subst(subpat, rhs, gflag, pflag)) < 0)
return(ERR);
if(nchng)
fchanged = TRUE;
return (1);
case 'W':
case 'w':
apflg = 0;
if(inptr[0] == '>' && inptr[1] == '>')
{
apflg++;
inptr++;
inptr++;
}
if(*inptr != ' ' && *inptr != HT && *inptr != NL)
return(ERR);
if((fptr = getfn()) == NULL)
return(ERR);
if(deflt(1, lastln) < 0)
return(ERR);
if(dowrite(line1, line2, fptr, apflg) < 0)
return(ERR);
fchanged = FALSE;
break;
case 'X':
case 'x':
if(*inptr == NL && nlines == 0 && !glob)
{
if((fptr = getfn()) == NULL)
return(ERR);
if(dowrite(1, lastln, fptr, 0) >= 0)
return(EOF);
}
return(ERR);
case 'Z':
case 'z':
if(deflt(curln,curln) < 0)
return(ERR);
switch(*inptr)
{
case '-':
if(doprnt(line1-21,line1) < 0)
return(ERR);
break;
case '.':
if(doprnt(line1-11,line1+10) < 0)
return(ERR);
break;
case '+':
case '\n':
if(doprnt(line1,line1+21) < 0)
return(ERR);
break;
}
break;
default:
return(ERR);
}
return (0);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'dodash.c'
then
echo shar: will not over-write existing file "'dodash.c'"
else
cat << \SHAR_EOF > 'dodash.c'
#include <stdio.h>
#include "tools.h"
/* Expand the set pointed to by *src into dest.
* Stop at delim. Return 0 on error or size of
* character class on success. Update *src to
* point at delim. A set can have one element
* {x} or several elements ( {abcdefghijklmnopqrstuvwxyz}
* and {a-z} are equivalent ). Note that the dash
* notation is expanded as sequential numbers.
* This means (since we are using the ASCII character
* set) that a-Z will contain the entire alphabet
* plus the symbols: [\]^_`. The maximum number of
* characters in a character class is defined by maxccl.
*/
char *
dodash(delim, src, map)
int delim;
char *src, *map;
{
register int first, last;
char *start;
start = src;
while( *src && *src != delim )
{
if( *src != '-')
setbit( esc( &src ), map, 1 );
else if( src == start || *(src + 1) == delim )
setbit( '-', map, 1 );
else {
src++;
if( *src < *(src - 2))
{
first = *src;
last = *(src - 2);
} else {
first = *(src - 2);
last = *src;
}
while( ++first <= last )
setbit( first, map, 1);
}
src++;
}
return( src );
}
SHAR_EOF
fi # end of overwriting check
if test -f 'doglob.c'
then
echo shar: will not over-write existing file "'doglob.c'"
else
cat << \SHAR_EOF > 'doglob.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
doglob()
{
int cursav, lin, stat, count;
char *cmd;
LINE *ptr;
lin = 1;
count = 0;
cmd = inptr;
while(1)
{
ptr = getptr(lin);
if(ptr->l_stat & (LGLOB|LEXCL))
{
ptr->l_stat &= ~(LGLOB|LEXCL);
cursav = curln = lin;
inptr = cmd;
if((stat = getlst()) < 0)
return(stat);
if((stat = docmd(1)) < 0)
return(stat);
count = 0;
} else {
count++;
lin = nextln(lin);
}
if(count > lastln)
return(0);
}
}
SHAR_EOF
fi # end of overwriting check
if test -f 'doprnt.c'
then
echo shar: will not over-write existing file "'doprnt.c'"
else
cat << \SHAR_EOF > 'doprnt.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
doprnt(from, to)
int from, to;
{
int i;
from = from < 1 ? 1 : from;
to = to > lastln ? lastln : to;
if(to != 0)
{
for(i = from; i <= to; i++)
prntln(gettxt(i), lflg, (nflg ? i : 0));
curln = to;
}
return(0);
}
prntln(str, vflg, lin)
char *str;
int vflg, lin;
{
if(lin)
fprintf(stdout,"%7d ",lin);
while(*str && *str != NL)
{
if(*str < ' ' || *str >= 0x7f)
{
switch(*str)
{
case '\t':
if(vflg)
putcntl(*str, stdout);
else
putc(*str, stdout);
break;
case DEL:
putc('^', stdout);
putc('?', stdout);
break;
default:
putcntl(*str, stdout);
break;
}
} else
putc(*str, stdout);
str++;
}
if(vflg)
putc('$',stdout);
putc('\n', stdout);
}
putcntl(c, stream)
char c;
FILE *stream;
{
putc('^', stream);
putc((c&31)|'@', stream);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'doread.c'
then
echo shar: will not over-write existing file "'doread.c'"
else
cat << \SHAR_EOF > 'doread.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
doread(lin, fname)
int lin;
char *fname;
{
extern FILE *fopen();
FILE *fp;
int err;
long bytes;
int lines;
static char str[MAXLINE];
err = 0;
nonascii = nullchar = truncated = 0;
printf("\"%s\" ",fname);
if((fp = fopen(fname, "r")) == NULL)
{
printf("file open err\n");
return( ERR );
}
curln = lin;
for(lines = 0, bytes = 0;(err = egets(str,MAXLINE,fp)) > 0;)
{
bytes += strlen(str);
if(ins(str) < 0)
{
printf("file insert error\n");
err++;
break;
}
lines++;
}
fclose(fp);
if(err < 0)
return(err);
printf("%d lines %d bytes",lines,bytes);
if(nonascii)
printf(" [%d non-ascii]",nonascii);
if(nullchar)
printf(" [%d nul]",nullchar);
if(truncated)
printf(" [%d lines truncated]",truncated);
printf("\n");
return( err );
}
SHAR_EOF
fi # end of overwriting check
if test -f 'egets.c'
then
echo shar: will not over-write existing file "'egets.c'"
else
cat << \SHAR_EOF > 'egets.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
int truncflg = 1; /* truncate long line flag */
int eightbit = 1; /* save eight bit */
int nonascii, nullchar, truncated;
egets(str,size,stream)
char *str;
int size;
FILE *stream;
{
int c, count;
char *cp;
for(count = 0, cp = str; size > count;)
{
c = getc(stream);
if(c == EOF)
{
*cp++ = '\n';
*cp = EOS;
if(count)
{
printf("[Incomplete last line]\n");
}
return(count);
}
if(c == NL)
{
*cp++ = c;
*cp = EOS;
return(++count);
}
if(c > 127)
{
if(!eightbit) /* if not saving eighth bit */
c = c&127; /* strip eigth bit */
nonascii++; /* count it */
}
if(c)
{
*cp++ = c; /* not null, keep it */
count++;
} else
nullchar++; /* count nulls */
}
str[count-1] = EOS;
if(c != NL)
{
printf("truncating line\n");
truncated++;
while((c = getc(stream)) != EOF)
if(c == NL)
break;
}
return(count);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'esc.c'
then
echo shar: will not over-write existing file "'esc.c'"
else
cat << \SHAR_EOF > 'esc.c'
#include <stdio.h>
#include "tools.h"
/* Map escape sequences into their equivalent symbols. Returns the
* correct ASCII character. If no escape prefix is present then s
* is untouched and *s is returned, otherwise **s is advanced to point
* at the escaped character and the translated character is returned.
*/
esc(s)
char **s;
{
register int rval;
if (**s != ESCAPE)
{
rval = **s;
} else {
(*s)++;
switch(toupper(**s))
{
case '\000':
rval = ESCAPE; break;
case 'S':
rval = ' '; break;
case 'N':
rval = '\n'; break;
case 'T':
rval = '\t'; break;
case 'B':
rval = '\b'; break;
case 'R':
rval = '\r'; break;
default:
rval = **s; break;
}
}
return (rval);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'find.c'
then
echo shar: will not over-write existing file "'find.c'"
else
cat << \SHAR_EOF > 'find.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
find(pat, dir)
TOKEN *pat;
int dir;
{
int num;
char *lin;
for(num = curln;(num = (dir ? nextln(num) : prevln(num))) != curln;)
{
lin = gettxt(num);
if(matchs(lin, pat, 0))
{
return(num);
}
}
return ( ERR );
}
SHAR_EOF
fi # end of overwriting check
if test -f 'getlst.c'
then
echo shar: will not over-write existing file "'getlst.c'"
else
cat << \SHAR_EOF > 'getlst.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
getlst()
{
int num;
line2 = 0;
for(nlines = 0; (num = getone()) >= 0;)
{
line1 = line2;
line2 = num;
nlines++;
if(*inptr != ',' && *inptr != ';')
break;
if(*inptr == ';')
curln = num;
inptr++;
}
nlines = min(nlines, 2);
if(nlines == 0)
line2 = curln;
if(nlines <= 1)
line1 = line2;
if(num == ERR)
return(num);
else
return(nlines);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'getnum.c'
then
echo shar: will not over-write existing file "'getnum.c'"
else
cat << \SHAR_EOF > 'getnum.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
TOKEN *srchpat;
char lstsrch;
getnum()
{
int num;
char c;
while(*inptr == SP || *inptr == HT)
inptr++;
if(*inptr >= '0' && *inptr <= '9') /* line number */
{
for(num = 0; *inptr >= '0' && *inptr <= '9';)
{
num = (num * 10) + *inptr - '0';
inptr++;
}
return ( num > lastln ? ERR : num );
}
switch(c = *inptr)
{
case '.':
inptr++;
return (curln);
case '$':
inptr++;
return (lastln);
case '/':
case '?':
lstsrch = c;
srchpat = optpat(srchpat);
if(*inptr == c)
*inptr++;
return(find(srchpat,c == '/'?1:0));
case '-':
case '+':
return(curln);
default:
return ( EOF ); /* unknown address */
}
}
SHAR_EOF
fi # end of overwriting check
if test -f 'getone.c'
then
echo shar: will not over-write existing file "'getone.c'"
else
cat << \SHAR_EOF > 'getone.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
getone()
{
int c, i, num;
if((num = getnum()) >= 0)
{
while(1)
{
while(*inptr == SP || *inptr == HT)
inptr++;
if(*inptr != '+'&& *inptr != '-')
break;
c = *inptr++;
if((i = getnum()) < 0)
return ( i );
if(c == '+')
{
num += i;
} else {
num -= i;
}
}
}
return ( num );
}
SHAR_EOF
fi # end of overwriting check
if test -f 'getpat.c'
then
echo shar: will not over-write existing file "'getpat.c'"
else
cat << \SHAR_EOF > 'getpat.c'
#include <stdio.h>
#include "tools.h"
/* Translate arg into a TOKEN string */
TOKEN *
getpat (arg)
char *arg;
{
return (makepat(arg, '\000'));
}
SHAR_EOF
fi # end of overwriting check
if test -f 'getptr.c'
then
echo shar: will not over-write existing file "'getptr.c'"
else
cat << \SHAR_EOF > 'getptr.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
LINE *
getptr(num)
int num;
{
LINE *ptr;
int j;
ptr = &line0;
j = 0;
for(j = 0; j < num; j++)
ptr = ptr->l_next;
return(ptr);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'getrhs.c'
then
echo shar: will not over-write existing file "'getrhs.c'"
else
cat << \SHAR_EOF > 'getrhs.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
getrhs(sub)
char *sub;
{
if(inptr[0] == NL || inptr[1] == NL) /* check for eol */
return( ERR );
if(maksub(sub, MAXPAT) == NULL)
return( ERR );
inptr++; /* skip over delimter */
while(*inptr == SP || *inptr == HT)
inptr++;
if(toupper(*inptr) == 'G')
{
*inptr++;
return( 1 );
}
return( 0 );
}
SHAR_EOF
fi # end of overwriting check
if test -f 'gettxt.c'
then
echo shar: will not over-write existing file "'gettxt.c'"
else
cat << \SHAR_EOF > 'gettxt.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
char *
gettxt(num)
int num;
{
LINE *lin;
static char txtbuf[MAXLINE];
lin = getptr(num);
strcpy(txtbuf,lin->l_buff);
strcat(txtbuf,"\n");
return(txtbuf);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'ins.c'
then
echo shar: will not over-write existing file "'ins.c'"
else
cat << \SHAR_EOF > 'ins.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
ins(str)
char *str;
{
char buf[MAXLINE], *cp;
LINE *new, *cur, *nxt;
cp = buf;
while(1)
{
if((*cp = *str++) == NL)
*cp = EOS;
if(*cp)
{
cp++;
continue;
}
if((new = (LINE *)malloc(sizeof(LINE)+strlen(buf))) == NULL)
return( ERR ); /* no memory */
strcpy(new->l_buff,buf); /* build new line */
cur = getptr(curln); /* get current line */
nxt = getptr(nextln(curln)); /* get next line */
relink(cur, new, new, nxt); /* add to linked list */
relink(new, nxt, cur, new);
lastln++;
curln++;
if(*str == EOS) /* end of line ? */
return( 1 );
cp = buf;
}
}
SHAR_EOF
fi # end of overwriting check
if test -f 'maksub.c'
then
echo shar: will not over-write existing file "'maksub.c'"
else
cat << \SHAR_EOF > 'maksub.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
char *
maksub(sub, subsz)
char *sub;
int subsz;
{
int size;
char delim, *cp;
size = 0;
cp = sub;
delim = *inptr++;
for(size = 0; *inptr != delim && *inptr != NL && size < subsz; size++)
{
if(*inptr == '&')
{
*cp++ = DITTO;
inptr++;
} else {
if(*inptr == ESCAPE)
{
inptr++;
if(*inptr < '0' || *inptr > '7')
switch(toupper(*++inptr))
{
case NL:
*cp++ == ESCAPE;
break;
case 'S':
*cp++ = SP;
inptr++;
break;
case 'N':
*cp++ = NL;
inptr++;
break;
case 'T':
*cp++ = HT;
inptr++;
break;
case 'B':
*cp++ = BS;
inptr++;
break;
case 'R':
*cp++ = CR;
inptr++;
break;
default:
*cp++ = *inptr;
inptr++;
break;
}
else {
*cp = 0;
while(*inptr >= '0' && *inptr <= '7')
{
*cp = (*cp << 3)+(*inptr-'0');
inptr++;
}
cp++;
}
} else
*cp++ = *inptr++;
}
}
if(size >= subsz)
return( NULL );
*cp = EOS;
return( sub );
}
SHAR_EOF
fi # end of overwriting check
if test -f 'matchs.c'
then
echo shar: will not over-write existing file "'matchs.c'"
else
cat << \SHAR_EOF > 'matchs.c'
#include <stdio.h>
#include "tools.h"
/*
* Compares line and pattern. Line is a character string while pat
* is a pattern template made by getpat().
* Returns:
* 1. A zero if no match was found.
*
* 2. A pointer to the last character satisfing the match
* if ret_endp is non-zero.
*
* 3. A pointer to the beginning of the matched string if
* ret_endp is zero.
*
* e.g.:
*
* matchs ("1234567890", getpat("4[0-9]*7), 0);
* will return a pointer to the '4', while:
*
* matchs ("1234567890", getpat("4[0-9]*7), 1);
* will return a pointer to the '7'.
*/
char *
matchs(line, pat, ret_endp)
char *line;
TOKEN *pat;
int ret_endp;
{
char *rval, *bptr;
bptr = line;
while(*line)
{
if ((rval = amatch(line, pat, bptr)) == 0)
{
line++;
} else {
if(rval > bptr && rval > line)
rval--; /* point to last char matched */
rval = ret_endp ? rval : line;
break;
}
}
return (rval);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'move.c'
then
echo shar: will not over-write existing file "'move.c'"
else
cat << \SHAR_EOF > 'move.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
move(num)
int num;
{
LINE *k0, *k1, *k2, *k3;
if(line1 <= 0 || line1 <= num && num <= line2)
return( ERR );
k0 = getptr(prevln(line1));
k1 = getptr(line1);
k2 = getptr(line2);
k3 = getptr(nextln(line2));
relink(k0, k3, k0, k3);
if(num > line1)
{
curln = num;
num += line2-line1+1;
} else
curln = num + (line2 - line1 + 1);
k0 = getptr(num);
k3 = getptr(nextln(num));
relink(k0, k1, k2, k3);
relink(k2, k3, k0, k1);
return( 1 );
}
SHAR_EOF
fi # end of overwriting check
if test -f 'omatch.c'
then
echo shar: will not over-write existing file "'omatch.c'"
else
cat << \SHAR_EOF > 'omatch.c'
#include <stdio.h>
#include "tools.h"
/*
* Match one pattern element, pointed at by pat, with the character at
* **linp. Return non-zero on match. Otherwise, return 0. *Linp is
* advanced to skip over the matched character; it is not advanced on
* failure. The amount of advance is 0 for patterns that match null
* strings, 1 otherwise. "boln" should point at the position that will
* match a BOL token.
*/
omatch(linp, pat, boln)
char **linp;
TOKEN *pat;
char *boln;
{
register int advance;
advance = -1;
if (**linp)
{
switch (pat->tok)
{
case LITCHAR:
if (**linp == pat->lchar)
advance = 1;
break;
case BOL:
if (*linp = boln)
advance = 0;
break;
case ANY:
if (**linp != '\n')
advance = 1;
break;
case EOL:
if (**linp == '\n')
advance = 0;
break;
case CCL:
if( testbit( **linp, pat->bitmap))
advance = 1;
break;
case NCCL:
if (!testbit (**linp, pat->bitmap))
advance = 1;
break;
default:
printf("omatch: can't happen\n");
}
}
if (advance >= 0)
*linp += advance;
return (++advance);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'optpat.c'
then
echo shar: will not over-write existing file "'optpat.c'"
else
cat << \SHAR_EOF > 'optpat.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
TOKEN *
optpat(oldpat)
TOKEN *oldpat;
{
char delim, str[MAXPAT], *cp;
delim = *inptr++;
cp = str;
while(*inptr != delim && *inptr != NL)
{
if(*inptr == ESCAPE)
if(inptr[1] == '/' || inptr[1] == '?')
inptr++;
*cp++ = *inptr++;
}
*cp = EOS;
if(*str == EOS)
return(oldpat);
if(oldpat)
unmakepat(oldpat);
return(getpat(str));
}
SHAR_EOF
fi # end of overwriting check
if test -f 'set.c'
then
echo shar: will not over-write existing file "'set.c'"
else
cat << \SHAR_EOF > 'set.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
struct tbl {
char *t_str;
int *t_ptr;
int t_val;
} *t, tbl[] = {
"number", &nflg, TRUE,
"nonumber", &nflg, FALSE,
"list", &lflg, TRUE,
"nolist", &lflg, FALSE,
"eightbit", &eightbit, TRUE,
"noeightbit", &eightbit, FALSE,
0
};
set()
{
char word[16];
int i;
inptr++;
if(toupper(*inptr) != 'T')
{
if(*inptr != SP && *inptr != HT && *inptr != NL)
return(ERR);
} else
inptr++;
if(*inptr == NL)
return(show("all"));
/* skip white space */
while(*inptr == SP || *inptr == HT)
inptr++;
for(i = 0; *inptr != SP && *inptr != HT && *inptr != NL;)
word[i++] = *inptr++;
word[i] = EOS;
for(t = tbl; t->t_str; t++)
{
if(strcmp(word,t->t_str) == 0)
{
*t->t_ptr = t->t_val;
return(0);
}
}
}
show()
{
extern int version;
printf("ed version %d.%d\n",version/100,version%100);
printf("number %s, list %s\n",nflg?"ON":"OFF",lflg?"ON":"OFF");
return(0);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'setbuf.c'
then
echo shar: will not over-write existing file "'setbuf.c'"
else
cat << \SHAR_EOF > 'setbuf.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
relink(a, x, y, b)
LINE *a, *x, *y, *b;
{
x->l_prev = a;
y->l_next = b;
}
clrbuf()
{
del(1, lastln);
}
setbuf()
{
relink(&line0, &line0, &line0, &line0);
curln = lastln = 0;
}
SHAR_EOF
fi # end of overwriting check
if test -f 'subst.c'
then
echo shar: will not over-write existing file "'subst.c'"
else
cat << \SHAR_EOF > 'subst.c'
/*
* Copyright 1987 Brian Beattie Rights Reserved.
*
* Permission to copy and/or distribute granted under the
* following conditions:
*
* 1). No charge may be made other than resonable charges
* for reproduction.
*
* 2). This notice must remain intact.
*
* 3). No further restrictions may be added.
*
*/
#include <stdio.h>
#include "tools.h"
#include "ed.h"
subst(pat, sub, gflg, pflag)
TOKEN *pat;
char *sub;
int gflg, pflag;
{
int lin, chngd, nchngd;
char *txtptr, *txt;
char *lastm, *m, *new, buf[MAXLINE];
if(line1 <= 0)
return( ERR );
nchngd = 0; /* reset count of lines changed */
for(lin = line1; lin <= line2; lin++)
{
txt = txtptr = gettxt(lin);
new = buf;
chngd = 0;
lastm = NULL;
while(*txtptr)
{
if(gflg || !chngd)
m = amatch(txtptr, pat, txt);
else
m = NULL;
if(m != NULL && lastm != m)
{
chngd++;
new = catsub(txtptr, m, sub, new,
buf+MAXLINE);
lastm = m;
}
if(m == NULL || m == txtptr)
{
*new++ = *txtptr++;
} else {
txtptr = m;
}
}
if(chngd)
{
if(new >= buf+MAXLINE)
return( ERR );
*new++ = EOS;
del(lin,lin);
ins(buf);
nchngd++;
if(pflag)
doprnt(curln, curln);
}
}
if(nchngd == 0 && !gflg)
{
printf("string not found\n");
return(ERR);
}
return( nchngd );
}
SHAR_EOF
fi # end of overwriting check
if test -f 'system.c'
then
echo shar: will not over-write existing file "'system.c'"
else
cat << \SHAR_EOF > 'system.c'
system(c)
char *c; {
int pid, exstat;
switch (pid = fork()) {
case -1:
return -1;
case 0:
execl("/bin/sh", "sh", "-c", c, (char *) 0);
exit(-1);
default:
while (wait(&status) != pid)
;
}
return status;
}
SHAR_EOF
fi # end of overwriting check
# End of shell archive
exit 0
--
-----------------------------------------------------------------------
Brian Beattie | Phone: (703)749-2365
NetExpress Communications, Inc. | uucp: seismo!sundc!netxcom!beattie
1953 Gallows Road, Suite 300 |
Vienna,VA 22180 |