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 |