ast@cs.vu.nl (Andy Tanenbaum) (09/14/87)
: This is a shar archive. Extract with sh, not csh. : This archive ends with exit, so do not worry about trailing junk. : --------------------------- cut here -------------------------- PATH=/bin:/usr/bin echo Extracting \a\m\a\t\c\h\.\c sed 's/^X//' > \a\m\a\t\c\h\.\c << '+ END-OF-FILE '\a\m\a\t\c\h\.\c X#include <stdio.h> X#include "tools.h" X X/* Scans throught the pattern template looking for a match X * with lin. Each element of lin is compared with the template X * until either a mis-match is found or the end of the template X * is reached. In the former case a 0 is returned; in the latter, X * a pointer into lin (pointing to the character following the X * matched pattern) is returned. X * X * "lin" is a pointer to the line being searched. X * "pat" is a pointer to a template made by makepat(). X * "boln" is a pointer into "lin" which points at the X * character at the beginning of the line. X */ Xchar * Xamatch(lin, pat, boln) Xchar *lin; XTOKEN *pat; Xchar *boln; X{ X register char *bocl, *rval, *strstart; X X if(pat == 0) X return 0; X X strstart = lin; X X while(pat) X { X if(pat->tok == CLOSURE && pat->next) X { X /* Process a closure: X * first skip over the closure token to the X * object to be repeated. This object can be X * a character class. X */ X X pat = pat->next; X X /* Now match as many occurrences of the X * closure pattern as possible. X */ X bocl = lin; X X while( *lin && omatch(&lin, pat)) X ; X X /* 'Lin' now points to the character that made X * made us fail. Now go on to process the X * rest of the string. A problem here is X * a character following the closure which X * could have been in the closure. X * For example, in the pattern "[a-z]*t" (which X * matches any lower-case word ending in a t), X * the final 't' will be sucked up in the while X * loop. So, if the match fails, we back up a X * notch and try to match the rest of the X * string again, repeating this process X * recursively until we get back to the X * beginning of the closure. The recursion X * goes, at most two levels deep. X */ X X if(pat = pat->next) X { X while(bocl <= lin) X { X if(rval = amatch(lin, pat, boln)) X { X /* success */ X return(rval); X } else X --lin; X } X return (0); /* match failed */ X } X } else if (omatch(&lin, pat, boln)) X { X pat = pat->next; X } else { X return (0); X } X } X /* Note that omatch() advances lin to point at the next X * character to be matched. Consequently, when we reach X * the end of the template, lin will be pointing at the X * character following the last character matched. The X * exceptions are templates containing only a BOLN or EOLN X * token. In these cases omatch doesn't advance. X * X * A philosophical point should be mentioned here. Is $ X * a position or a character? (i.e. does $ mean the EOL X * character itself or does it mean the character at the end X * of the line.) I decided here to make it mean the former, X * in order to make the behavior of amatch() consistent. If X * you give amatch the pattern ^$ (match all lines consisting X * only of an end of line) then, since something has to be X * returned, a pointer to the end of line character itself is X * returned. X */ X X return ((char *)max(strstart , lin)); X} + END-OF-FILE amatch.c chmod 'u=rw,g=r,o=r' \a\m\a\t\c\h\.\c set `sum \a\m\a\t\c\h\.\c` sum=$1 case $sum in 63558) :;; *) echo 'Bad sum in '\a\m\a\t\c\h\.\c >&2 esac echo Extracting \a\p\p\e\n\d\.\c sed 's/^X//' > \a\p\p\e\n\d\.\c << '+ END-OF-FILE '\a\p\p\e\n\d\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xappend(line, glob) Xint line, glob; X{ X int stat; X char lin[MAXLINE]; X X if(glob) X return(ERR); X curln = line; X while(1) X { X if(nflg) X fprintf(stdout,"%6d. ",curln+1); X X if(fgets(lin, MAXLINE, stdin) == NULL) X return( EOF ); X if(lin[0] == '.' && lin[1] == '\n') X return(0); X stat = ins(lin); X if(stat < 0) X return( ERR ); X X } X} + END-OF-FILE append.c chmod 'u=rw,g=r,o=r' \a\p\p\e\n\d\.\c set `sum \a\p\p\e\n\d\.\c` sum=$1 case $sum in 24487) :;; *) echo 'Bad sum in '\a\p\p\e\n\d\.\c >&2 esac echo Extracting \b\i\t\m\a\p\.\c sed 's/^X//' > \b\i\t\m\a\p\.\c << '+ END-OF-FILE '\b\i\t\m\a\p\.\c X/* X * BITMAP.C - makebitmap, setbit, testbit X * bit-map manipulation routines. X * X * Copyright (c) Allen I. Holub, all rights reserved. This program may X * for copied for personal, non-profit use only. X * X */ X X#ifdef DEBUG X#include <stdio.h> X#endif X X#include "tools.h" X X XBITMAP *makebitmap( size ) Xunsigned size; X{ X /* Make a bit map with "size" bits. The first entry in X * the map is an "unsigned int" representing the maximum X * bit. The map itself is concatenated to this integer. X * Return a pointer to a map on success, 0 if there's X * not enough memory. X */ X X unsigned *map, numbytes; X X numbytes = (size >> 3) + ((size & 0x07) ? 1 : 0 ); X X#ifdef DEBUG X printf("Making a %d bit map (%d bytes required)\n", size, numbytes); X#endif X X if( map = (unsigned *) malloc( numbytes + sizeof(unsigned) )) X *map = size; X X return ((BITMAP *)map); X} X Xsetbit( c, map, val ) Xunsigned c, val; Xchar *map; X{ X /* Set bit c in the map to val. X * If c > map-size, 0 is returned, else 1 is returned. X */ X X if( c >= *(unsigned *)map ) /* if c >= map size */ X return 0; X X map += sizeof(unsigned); /* skip past size */ X X if( val ) X map[c >> 3] |= 1 << (c & 0x07); X else X map[c >> 3] &= ~(1 << (c & 0x07)); X X return( 1 ); X} X Xtestbit( c, map ) Xunsigned c; Xchar *map; X{ X /* Return 1 if the bit corresponding to c in map is set. X * 0 if it is not. X */ X X if( c >= *(unsigned *)map ) X return 0; X X map += sizeof(unsigned); X X return(map[ c >> 3 ] & (1 << (c & 0x07))); X} + END-OF-FILE bitmap.c chmod 'u=rw,g=r,o=r' \b\i\t\m\a\p\.\c set `sum \b\i\t\m\a\p\.\c` sum=$1 case $sum in 33873) :;; *) echo 'Bad sum in '\b\i\t\m\a\p\.\c >&2 esac echo Extracting \c\a\t\s\u\b\.\c sed 's/^X//' > \c\a\t\s\u\b\.\c << '+ END-OF-FILE '\c\a\t\s\u\b\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xchar * Xcatsub(from, to, sub, new, newend) Xchar *from, *to, *sub, *new, *newend; X{ X char *cp, *cp2; X X for(cp = new; *sub != EOS && cp < newend;) X { X if(*sub == DITTO) X for(cp2 = from; cp2 < to;) X { X *cp++ = *cp2++; X if(cp >= newend) X break; X } X else X *cp++ = *sub; X sub++; X } X X return(cp); X} + END-OF-FILE catsub.c chmod 'u=rw,g=r,o=r' \c\a\t\s\u\b\.\c set `sum \c\a\t\s\u\b\.\c` sum=$1 case $sum in 19491) :;; *) echo 'Bad sum in '\c\a\t\s\u\b\.\c >&2 esac echo Extracting \c\k\g\l\o\b\.\c sed 's/^X//' > \c\k\g\l\o\b\.\c << '+ END-OF-FILE '\c\k\g\l\o\b\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xckglob() X{ X static TOKEN *glbpat; X char c, delim, *lin; X int num, nmatch; X LINE *ptr; X X c = toupper(*inptr); X nmatch = 0; X X if(c == 'G' || c == 'V') X { X delim = *++inptr; X if(delim <= ' ') X return(0); X if(inptr[0] != inptr[1]) /* if null string use last */ X { X glbpat = optpat(glbpat); X } X if(*inptr == delim) X inptr++; X num = curln; X while(1) X { X if(num) /* do not do zero */ X { X ptr = getptr(num); X lin = gettxt(num); X if(matchs(lin, glbpat, 0)) X { X ptr->l_stat = (c == 'G' ? LGLOB:LEXCL); X nmatch++; X } X } X if((num = nextln(num)) == curln) X break; X } X } X return(nmatch); X} + END-OF-FILE ckglob.c chmod 'u=rw,g=r,o=r' \c\k\g\l\o\b\.\c set `sum \c\k\g\l\o\b\.\c` sum=$1 case $sum in 46924) :;; *) echo 'Bad sum in '\c\k\g\l\o\b\.\c >&2 esac echo Extracting \d\e\f\l\t\.\c sed 's/^X//' > \d\e\f\l\t\.\c << '+ END-OF-FILE '\d\e\f\l\t\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xdeflt(def1, def2) Xint def1, def2; X{ X if(nlines == 0) X { X line1 = def1; X line2 = def2; X } X if(line1 > line2 || line1 <= 0) X return (ERR); X} + END-OF-FILE deflt.c chmod 'u=rw,g=r,o=r' \d\e\f\l\t\.\c set `sum \d\e\f\l\t\.\c` sum=$1 case $sum in 21184) :;; *) echo 'Bad sum in '\d\e\f\l\t\.\c >&2 esac echo Extracting \d\e\l\.\c sed 's/^X//' > \d\e\l\.\c << '+ END-OF-FILE '\d\e\l\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xdel(from, to) Xint from, to; X{ X LINE *first, *last, *next, *tmp; X X if(from < 1) X from = 1; X first = getptr(prevln(from)); X last = getptr(nextln(to)); X next = first->l_next; X while(next != last && next != &line0) X { X tmp = next->l_next; X free(next); X next = tmp; X } X relink(first, last, first, last); X lastln -= (to - from)+1; X curln = prevln(from); X} + END-OF-FILE del.c chmod 'u=rw,g=r,o=r' \d\e\l\.\c set `sum \d\e\l\.\c` sum=$1 case $sum in 52329) :;; *) echo 'Bad sum in '\d\e\l\.\c >&2 esac echo Extracting \d\o\c\m\d\.\c sed 's/^X//' > \d\o\c\m\d\.\c << '+ END-OF-FILE '\d\o\c\m\d\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xchar fname[MAXFNAME]; Xint fchanged; X Xdocmd(glob) Xint glob; X{ X static char rhs[MAXPAT]; X static TOKEN *subpat; X int c, err, line3; X int i, apflg, pflag, gflag; X int nchng; X char *fptr; X X pflag = FALSE; X while(*inptr == SP && *inptr == HT) X inptr++; X X c = *inptr++; X X switch(c) X { X case NL: X if(nlines == 0) X { X line2 = nextln(curln); X } X curln = line2; X return (1); X break; X X case '=': X printf("%6d=\n",line2); X break; X X case 'A': X case 'a': X if(*inptr != NL || nlines > 1) X return(ERR); X X if(append(line1, glob) < 0) X return(ERR);; X fchanged = TRUE; X break; X X case 'C': X case 'c': X if(*inptr != NL) X return(ERR); X X if(deflt(curln, curln) < 0) X return(ERR); X X if(del(line1, line2) < 0) X return(ERR); X if(append(curln, glob) < 0) X return(ERR); X fchanged = TRUE; X break; X X case 'D': X case 'd': X if(*inptr != NL) X return(ERR); X X if(deflt(curln, curln) < 0) X return(ERR); X X if(del(line1, line2) < 0) X return(ERR); X if(nextln(curln) != 0) X curln = nextln(curln); X fchanged = TRUE; X break; X X case 'E': X case 'e': X if(nlines > 0) X return(ERR); X if(fchanged && *inptr != '!') X { X printf("File not saved\n"); X return(ERR); X } X if(*inptr == '!') X inptr++; X X if(*inptr != ' ' && *inptr != HT && *inptr != NL) X return(ERR); X X if((fptr = getfn()) == NULL) X return(ERR); X X clrbuf(); X if((err = doread(0, fptr)) < 0) X return(err); X X strcpy(fname, fptr); X fchanged = FALSE; X break; X X case 'I': X case 'i': X if(*inptr != NL || nlines > 1) X return(ERR); X X if(append(prevln(line1), glob) < 0) X return(ERR); X fchanged = TRUE; X break; X X case 'M': X case 'm': X if((line3 = getone()) < 0) X return(ERR); X if(deflt(curln,curln) < 0) X return(ERR); X if(move(line3) < 0) X return(ERR); X fchanged = TRUE; X break; X X case 'P': X case 'p': X if(*inptr != NL) X return(ERR); X if(deflt(curln,curln) < 0) X return(ERR); X if(doprnt(line1,line2) < 0) X return(ERR); X break; X X case 'Q': X case 'q': X if(fchanged && *inptr != '!') X { X printf("File not saved\n"); X return(ERR); X } X if(*inptr == '!') X inptr++; X if(*inptr == NL && nlines == 0 && !glob) X return(EOF); X else X return(ERR); X X case 'R': X case 'r': X if(nlines > 1) X return(ERR); X X if(nlines = 0) X line2 = lastln; X X if(*inptr != ' ' && *inptr != HT && *inptr != NL) X return(ERR); X X if((fptr = getfn()) == NULL) X return(ERR); X X if((err = doread(line2, fptr)) < 0) X return(err); X fchanged = TRUE; X break; X X case 'S': X case 's': X if(toupper(*inptr) == 'E') X return(set()); X while(*inptr == SP || *inptr == HT) X inptr++; X if((subpat = optpat(subpat)) == NULL) X return(ERR); X if((gflag = getrhs(rhs)) < 0) X return(ERR); X if(toupper(*inptr) == 'P') X pflag++; X if(deflt(curln, curln) < 0) X return(ERR); X if((nchng = subst(subpat, rhs, gflag, pflag)) < 0) X return(ERR); X if(nchng) X fchanged = TRUE; X return (1); X X case 'W': X case 'w': X apflg = 0; X if(inptr[0] == '>' && inptr[1] == '>') X { X apflg++; X inptr++; X inptr++; X } X X if(*inptr != ' ' && *inptr != HT && *inptr != NL) X return(ERR); X X if((fptr = getfn()) == NULL) X return(ERR); X X if(deflt(1, lastln) < 0) X return(ERR); X if(dowrite(line1, line2, fptr, apflg) < 0) X return(ERR); X fchanged = FALSE; X break; X X case 'X': X case 'x': X if(*inptr == NL && nlines == 0 && !glob) X { X if((fptr = getfn()) == NULL) X return(ERR); X if(dowrite(1, lastln, fptr, 0) >= 0) X return(EOF); X } X return(ERR); X X case 'Z': X case 'z': X if(deflt(curln,curln) < 0) X return(ERR); X X switch(*inptr) X { X case '-': X if(doprnt(line1-21,line1) < 0) X return(ERR); X break; X X case '.': X if(doprnt(line1-11,line1+10) < 0) X return(ERR); X break; X X case '+': X case '\n': X if(doprnt(line1,line1+21) < 0) X return(ERR); X break; X } X break; X X default: X return(ERR); X } X return (0); X} + END-OF-FILE docmd.c chmod 'u=rw,g=r,o=r' \d\o\c\m\d\.\c set `sum \d\o\c\m\d\.\c` sum=$1 case $sum in 51484) :;; *) echo 'Bad sum in '\d\o\c\m\d\.\c >&2 esac echo Extracting \d\o\d\a\s\h\.\c sed 's/^X//' > \d\o\d\a\s\h\.\c << '+ END-OF-FILE '\d\o\d\a\s\h\.\c X#include <stdio.h> X#include "tools.h" X X/* Expand the set pointed to by *src into dest. X * Stop at delim. Return 0 on error or size of X * character class on success. Update *src to X * point at delim. A set can have one element X * {x} or several elements ( {abcdefghijklmnopqrstuvwxyz} X * and {a-z} are equivalent ). Note that the dash X * notation is expanded as sequential numbers. X * This means (since we are using the ASCII character X * set) that a-Z will contain the entire alphabet X * plus the symbols: [\]^_`. The maximum number of X * characters in a character class is defined by maxccl. X */ Xchar * Xdodash(delim, src, map) X Xint delim; Xchar *src, *map; X{ X X register int first, last; X char *start; X X start = src; X X while( *src && *src != delim ) X { X if( *src != '-') X setbit( esc( &src ), map, 1 ); X X else if( src == start || *(src + 1) == delim ) X setbit( '-', map, 1 ); X else { X src++; X X if( *src < *(src - 2)) X { X first = *src; X last = *(src - 2); X } else { X first = *(src - 2); X last = *src; X } X X while( ++first <= last ) X setbit( first, map, 1); X X } X src++; X } X return( src ); X} + END-OF-FILE dodash.c chmod 'u=rw,g=r,o=r' \d\o\d\a\s\h\.\c set `sum \d\o\d\a\s\h\.\c` sum=$1 case $sum in 17370) :;; *) echo 'Bad sum in '\d\o\d\a\s\h\.\c >&2 esac echo Extracting \d\o\g\l\o\b\.\c sed 's/^X//' > \d\o\g\l\o\b\.\c << '+ END-OF-FILE '\d\o\g\l\o\b\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xdoglob() X{ X int cursav, lin, stat, count; X char *cmd; X LINE *ptr; X X lin = 1; X count = 0; X X cmd = inptr; X while(1) X { X ptr = getptr(lin); X if(ptr->l_stat & (LGLOB|LEXCL)) X { X ptr->l_stat &= ~(LGLOB|LEXCL); X cursav = curln = lin; X inptr = cmd; X if((stat = getlst()) < 0) X return(stat); X if((stat = docmd(1)) < 0) X return(stat); X count = 0; X } else { X count++; X lin = nextln(lin); X } X if(count > lastln) X return(0); X } X} + END-OF-FILE doglob.c chmod 'u=rw,g=r,o=r' \d\o\g\l\o\b\.\c set `sum \d\o\g\l\o\b\.\c` sum=$1 case $sum in 03480) :;; *) echo 'Bad sum in '\d\o\g\l\o\b\.\c >&2 esac echo Extracting \d\o\p\r\n\t\.\c sed 's/^X//' > \d\o\p\r\n\t\.\c << '+ END-OF-FILE '\d\o\p\r\n\t\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xdoprnt(from, to) Xint from, to; X{ X int i; X X from = from < 1 ? 1 : from; X to = to > lastln ? lastln : to; X X if(to != 0) X { X for(i = from; i <= to; i++) X prntln(gettxt(i), lflg, (nflg ? i : 0)); X curln = to; X } X X return(0); X} X Xprntln(str, vflg, lin) Xchar *str; Xint vflg, lin; X{ X if(lin) X fprintf(stdout,"%7d ",lin); X while(*str && *str != NL) X { X if(*str < ' ' || *str >= 0x7f) X { X switch(*str) X { X case '\t': X if(vflg) X putcntl(*str, stdout); X else X putc(*str, stdout); X break; X X case DEL: X putc('^', stdout); X putc('?', stdout); X break; X X default: X putcntl(*str, stdout); X break; X } X } else X putc(*str, stdout); X str++; X } X if(vflg) X putc('$',stdout); X putc('\n', stdout); X} X Xputcntl(c, stream) Xchar c; XFILE *stream; X{ X putc('^', stream); X putc((c&31)|'@', stream); X} + END-OF-FILE doprnt.c chmod 'u=rw,g=r,o=r' \d\o\p\r\n\t\.\c set `sum \d\o\p\r\n\t\.\c` sum=$1 case $sum in 05813) :;; *) echo 'Bad sum in '\d\o\p\r\n\t\.\c >&2 esac echo Extracting \d\o\r\e\a\d\.\c sed 's/^X//' > \d\o\r\e\a\d\.\c << '+ END-OF-FILE '\d\o\r\e\a\d\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xdoread(lin, fname) Xint lin; Xchar *fname; X{ X extern FILE *fopen(); X FILE *fp; X int err; X long bytes; X int lines; X static char str[MAXLINE]; X X err = 0; X nonascii = nullchar = truncated = 0; X X printf("\"%s\" ",fname); X if((fp = fopen(fname, "r")) == NULL) X { X printf("file open err\n"); X return( ERR ); X } X curln = lin; X for(lines = 0, bytes = 0;(err = egets(str,MAXLINE,fp)) > 0;) X { X bytes += strlen(str); X if(ins(str) < 0) X { X printf("file insert error\n"); X err++; X break; X } X lines++; X } X fclose(fp); X if(err < 0) X return(err); X printf("%d lines %d bytes",lines,bytes); X if(nonascii) X printf(" [%d non-ascii]",nonascii); X if(nullchar) X printf(" [%d nul]",nullchar); X if(truncated) X printf(" [%d lines truncated]",truncated); X printf("\n"); X return( err ); X} + END-OF-FILE doread.c chmod 'u=rw,g=r,o=r' \d\o\r\e\a\d\.\c set `sum \d\o\r\e\a\d\.\c` sum=$1 case $sum in 07945) :;; *) echo 'Bad sum in '\d\o\r\e\a\d\.\c >&2 esac echo Extracting \d\o\w\r\i\t\e\.\c sed 's/^X//' > \d\o\w\r\i\t\e\.\c << '+ END-OF-FILE '\d\o\w\r\i\t\e\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xdowrite(from, to, fname, apflg) Xint from, to; Xchar *fname; Xint apflg; X{ X extern FILE *fopen(); X FILE *fp; X int lin, err; X int lines, bytes; X char *str; X X err = 0; X X lines = bytes = 0; X printf("\"%s\" ",fname); X if((fp = fopen(fname,(apflg?"a":"w"))) == NULL) X { X printf("file open error\n"); X return( ERR ); X } X for(lin = from; lin <= to; lin++) X { X str = gettxt(lin); X lines++; X bytes += strlen(str); X if(fputs(str, fp) == EOF) X { X printf("file write error\n"); X err++; X break; X } X } X printf("%d lines %d bytes\n",lines,bytes); X fclose(fp); X return( err ); X} + END-OF-FILE dowrite.c chmod 'u=rw,g=r,o=r' \d\o\w\r\i\t\e\.\c set `sum \d\o\w\r\i\t\e\.\c` sum=$1 case $sum in 45900) :;; *) echo 'Bad sum in '\d\o\w\r\i\t\e\.\c >&2 esac echo Extracting \e\d\.\c sed 's/^X//' > \e\d\.\c << '+ END-OF-FILE '\e\d\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X#include <setjmp.h> Xjmp_buf env; X XLINE line0; Xint curln = 0; Xint lastln = 0; Xchar *inptr; Xstatic char inlin[MAXLINE]; Xint nflg, lflg, pflg, pflag; Xint line1, line2, nlines; Xextern char fname[]; Xint version = 1; X Xintr() X{ X printf("Interrupt:\n"); X longjmp(env, 1); X} X Xmain(argc,argv) Xint argc; Xchar **argv; X{ X int stat, i, j, prmpt; X X setbuf(); X prmpt = isatty(0); /* if interactive */ X if(argc > 1) X { X for(i = 1; i < argc; i++) X { X if(doread(0,argv[i])) X curln = 1; X strcpy(fname, argv[i]); X break; X } X } X while(1) X { X setjmp(env); X signal(2, intr); X X if(nflg) X fprintf(stdout,"%d: ",curln); X else if(prmpt) X fprintf(stdout,": "); X X if (fgets(inlin, sizeof(inlin),stdin) == NULL) X { X break; X } X if(*inlin == '!') X { X for(inptr = inlin; *inptr != NL; inptr++) X ; X *inptr = EOS; X system(inlin+1); X continue; X } X inptr = inlin; X if(getlst() >= 0) X if(ckglob()) X { X if((stat = doglob()) >= 0) X { X curln = stat; X continue; X } X } else { X if((stat = docmd(0)) >= 0) X { X if(stat == 1) X doprnt(curln, curln); X continue; X } X } X if(stat == EOF) X { X exit(0); X } X if(stat == FATAL) X { X fputs("FATAL ERROR\n",stderr); X exit(1); X } X fputs("\007",stderr); X } X} + END-OF-FILE ed.c chmod 'u=rw,g=r,o=r' \e\d\.\c set `sum \e\d\.\c` sum=$1 case $sum in 52523) :;; *) echo 'Bad sum in '\e\d\.\c >&2 esac echo Extracting \e\d\.\h sed 's/^X//' > \e\d\.\h << '+ END-OF-FILE '\e\d\.\h X/* ed.h */ X#define FATAL (ERR-1) Xstruct line { X int l_stat; /* empty, mark */ X struct line *l_prev; X struct line *l_next; X char l_buff[1]; X}; X Xtypedef struct line LINE; X X#define LINFREE 1 /* entry not in use */ X#define LGLOB 2 /* line marked global */ X#define LEXCL 4 /* line marked exclude */ X X#define MAXLINE 256 /* max number of chars per line */ X#define MAXPAT 256 /* max number of chars per replacement pattern */ X#define MAXFNAME 256 /* max file name size */ X Xextern LINE line0; Xextern int curln, lastln, line1, line2, nlines; Xextern int nflg; /* print line number flag */ Xextern int lflg; /* print line in verbose mode */ Xextern int pflg; /* print current line after each command */ Xextern char *inptr; /* tty input buffer */ Xextern char linbuf[], *linptr; /* current line */ Xextern int truncflg; /* truncate long line flag */ Xextern int eightbit; /* save eighth bit */ Xextern int nonascii; /* count of non-ascii chars read */ Xextern int nullchar; /* count of null chars read */ Xextern int truncated; /* count of lines truncated */ Xextern int fchanged; /* file changed */ X X#define nextln(l) ((l)+1 > lastln ? 0 : (l)+1) X#define prevln(l) ((l)-1 < 0 ? lastln : (l)-1) X Xextern char *getfn(); Xextern LINE *getptr(); Xextern char *gettxt(); Xextern char *maksub(); Xextern TOKEN *optpat(); X Xextern char *catsub(); X Xextern char *strcpy(); Xextern int *malloc(); X/*********************************************************************/ + END-OF-FILE ed.h chmod 'u=rw,g=r,o=r' \e\d\.\h set `sum \e\d\.\h` sum=$1 case $sum in 34840) :;; *) echo 'Bad sum in '\e\d\.\h >&2 esac echo Extracting \e\g\e\t\s\.\c sed 's/^X//' > \e\g\e\t\s\.\c << '+ END-OF-FILE '\e\g\e\t\s\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xint truncflg = 1; /* truncate long line flag */ Xint eightbit = 1; /* save eight bit */ Xint nonascii, nullchar, truncated; Xegets(str,size,stream) Xchar *str; Xint size; XFILE *stream; X{ X int c, count; X char *cp; X X for(count = 0, cp = str; size > count;) X { X c = getc(stream); X if(c == EOF) X { X *cp++ = '\n'; X *cp = EOS; X if(count) X { X printf("[Incomplete last line]\n"); X } X return(count); X } X if(c == NL) X { X *cp++ = c; X *cp = EOS; X return(++count); X } X if(c > 127) X { X if(!eightbit) /* if not saving eighth bit */ X c = c&127; /* strip eigth bit */ X nonascii++; /* count it */ X } X if(c) X { X *cp++ = c; /* not null, keep it */ X count++; X } else X nullchar++; /* count nulls */ X } X str[count-1] = EOS; X if(c != NL) X { X printf("truncating line\n"); X truncated++; X while((c = getc(stream)) != EOF) X if(c == NL) X break; X } X return(count); X} + END-OF-FILE egets.c chmod 'u=rw,g=r,o=r' \e\g\e\t\s\.\c set `sum \e\g\e\t\s\.\c` sum=$1 case $sum in 00743) :;; *) echo 'Bad sum in '\e\g\e\t\s\.\c >&2 esac echo Extracting \e\s\c\.\c sed 's/^X//' > \e\s\c\.\c << '+ END-OF-FILE '\e\s\c\.\c X#include <stdio.h> X#include "tools.h" X X/* Map escape sequences into their equivalent symbols. Returns the X * correct ASCII character. If no escape prefix is present then s X * is untouched and *s is returned, otherwise **s is advanced to point X * at the escaped character and the translated character is returned. X */ Xesc(s) Xchar **s; X{ X register int rval; X X X if (**s != ESCAPE) X { X rval = **s; X } else { X (*s)++; X X switch(toupper(**s)) X { X case '\000': X rval = ESCAPE; break; X case 'S': X rval = ' '; break; X case 'N': X rval = '\n'; break; X case 'T': X rval = '\t'; break; X case 'B': X rval = '\b'; break; X case 'R': X rval = '\r'; break; X default: X rval = **s; break; X } X } X X return (rval); X} + END-OF-FILE esc.c chmod 'u=rw,g=r,o=r' \e\s\c\.\c set `sum \e\s\c\.\c` sum=$1 case $sum in 30870) :;; *) echo 'Bad sum in '\e\s\c\.\c >&2 esac echo Extracting \f\i\n\d\.\c sed 's/^X//' > \f\i\n\d\.\c << '+ END-OF-FILE '\f\i\n\d\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xfind(pat, dir) XTOKEN *pat; Xint dir; X{ X int num; X char *lin; X X for(num = curln;(num = (dir ? nextln(num) : prevln(num))) != curln;) X { X lin = gettxt(num); X if(matchs(lin, pat, 0)) X { X return(num); X } X } X return ( ERR ); X} + END-OF-FILE find.c chmod 'u=rw,g=r,o=r' \f\i\n\d\.\c set `sum \f\i\n\d\.\c` sum=$1 case $sum in 38841) :;; *) echo 'Bad sum in '\f\i\n\d\.\c >&2 esac echo Extracting \g\e\t\f\n\.\c sed 's/^X//' > \g\e\t\f\n\.\c << '+ END-OF-FILE '\g\e\t\f\n\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xextern char fname[MAXFNAME]; Xchar * Xgetfn() X{ X static char file[256]; X char *cp; X X if(*inptr == NL) X { X strcpy(file, fname); X } else { X while(*inptr == SP || *inptr == HT) X inptr++; X X cp = file; X while(*inptr && *inptr != NL && *inptr != SP && *inptr != HT) X { X *cp++ = *inptr++; X } X *cp = '\0'; X X if(strlen(file) == 0) X { X printf("bad file name\n"); X return( NULL ); X } X } X X if(strlen(file) == 0) X { X printf("no file name\n"); X return(NULL); X } X return( file ); X} + END-OF-FILE getfn.c chmod 'u=rw,g=r,o=r' \g\e\t\f\n\.\c set `sum \g\e\t\f\n\.\c` sum=$1 case $sum in 02358) :;; *) echo 'Bad sum in '\g\e\t\f\n\.\c >&2 esac echo Extracting \g\e\t\l\s\t\.\c sed 's/^X//' > \g\e\t\l\s\t\.\c << '+ END-OF-FILE '\g\e\t\l\s\t\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xgetlst() X{ X int num; X X line2 = 0; X for(nlines = 0; (num = getone()) >= 0;) X { X line1 = line2; X line2 = num; X nlines++; X if(*inptr != ',' && *inptr != ';') X break; X if(*inptr == ';') X curln = num; X inptr++; X } X nlines = min(nlines, 2); X if(nlines == 0) X line2 = curln; X if(nlines <= 1) X line1 = line2; X X if(num == ERR) X return(num); X else X return(nlines); X} + END-OF-FILE getlst.c chmod 'u=rw,g=r,o=r' \g\e\t\l\s\t\.\c set `sum \g\e\t\l\s\t\.\c` sum=$1 case $sum in 58013) :;; *) echo 'Bad sum in '\g\e\t\l\s\t\.\c >&2 esac echo Extracting \g\e\t\n\u\m\.\c sed 's/^X//' > \g\e\t\n\u\m\.\c << '+ END-OF-FILE '\g\e\t\n\u\m\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X XTOKEN *srchpat; Xchar lstsrch; Xgetnum() X{ X int num; X char c; X X while(*inptr == SP || *inptr == HT) X inptr++; X X if(*inptr >= '0' && *inptr <= '9') /* line number */ X { X for(num = 0; *inptr >= '0' && *inptr <= '9';) X { X num = (num * 10) + *inptr - '0'; X inptr++; X } X return ( num > lastln ? ERR : num ); X } X X switch(c = *inptr) X { X case '.': X inptr++; X return (curln); X X case '$': X inptr++; X return (lastln); X X case '/': X case '?': X lstsrch = c; X srchpat = optpat(srchpat); X if(*inptr == c) X *inptr++; X return(find(srchpat,c == '/'?1:0)); X X case '-': X case '+': X return(curln); X X default: X return ( EOF ); /* unknown address */ X } X} + END-OF-FILE getnum.c chmod 'u=rw,g=r,o=r' \g\e\t\n\u\m\.\c set `sum \g\e\t\n\u\m\.\c` sum=$1 case $sum in 25408) :;; *) echo 'Bad sum in '\g\e\t\n\u\m\.\c >&2 esac echo Extracting \g\e\t\o\n\e\.\c sed 's/^X//' > \g\e\t\o\n\e\.\c << '+ END-OF-FILE '\g\e\t\o\n\e\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xgetone() X{ X int c, i, num; X X if((num = getnum()) >= 0) X { X while(1) X { X while(*inptr == SP || *inptr == HT) X inptr++; X X if(*inptr != '+'&& *inptr != '-') X break; X c = *inptr++; X X if((i = getnum()) < 0) X return ( i ); X if(c == '+') X { X num += i; X } else { X num -= i; X } X } X } X return ( num ); X} + END-OF-FILE getone.c chmod 'u=rw,g=r,o=r' \g\e\t\o\n\e\.\c set `sum \g\e\t\o\n\e\.\c` sum=$1 case $sum in 15814) :;; *) echo 'Bad sum in '\g\e\t\o\n\e\.\c >&2 esac echo Extracting \g\e\t\p\a\t\.\c sed 's/^X//' > \g\e\t\p\a\t\.\c << '+ END-OF-FILE '\g\e\t\p\a\t\.\c X#include <stdio.h> X#include "tools.h" X X/* Translate arg into a TOKEN string */ XTOKEN * Xgetpat (arg) Xchar *arg; X{ X X return (makepat(arg, '\000')); X} + END-OF-FILE getpat.c chmod 'u=rw,g=r,o=r' \g\e\t\p\a\t\.\c set `sum \g\e\t\p\a\t\.\c` sum=$1 case $sum in 08917) :;; *) echo 'Bad sum in '\g\e\t\p\a\t\.\c >&2 esac echo Extracting \g\e\t\p\t\r\.\c sed 's/^X//' > \g\e\t\p\t\r\.\c << '+ END-OF-FILE '\g\e\t\p\t\r\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X XLINE * Xgetptr(num) Xint num; X{ X LINE *ptr; X int j; X X ptr = &line0; X j = 0; X for(j = 0; j < num; j++) X ptr = ptr->l_next; X return(ptr); X} + END-OF-FILE getptr.c chmod 'u=rw,g=r,o=r' \g\e\t\p\t\r\.\c set `sum \g\e\t\p\t\r\.\c` sum=$1 case $sum in 13048) :;; *) echo 'Bad sum in '\g\e\t\p\t\r\.\c >&2 esac echo Extracting \g\e\t\r\h\s\.\c sed 's/^X//' > \g\e\t\r\h\s\.\c << '+ END-OF-FILE '\g\e\t\r\h\s\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xgetrhs(sub) Xchar *sub; X{ X if(inptr[0] == NL || inptr[1] == NL) /* check for eol */ X return( ERR ); X X if(maksub(sub, MAXPAT) == NULL) X return( ERR ); X X inptr++; /* skip over delimter */ X while(*inptr == SP || *inptr == HT) X inptr++; X if(toupper(*inptr) == 'G') X { X *inptr++; X return( 1 ); X } X return( 0 ); X} + END-OF-FILE getrhs.c chmod 'u=rw,g=r,o=r' \g\e\t\r\h\s\.\c set `sum \g\e\t\r\h\s\.\c` sum=$1 case $sum in 60050) :;; *) echo 'Bad sum in '\g\e\t\r\h\s\.\c >&2 esac echo Extracting \g\e\t\t\x\t\.\c sed 's/^X//' > \g\e\t\t\x\t\.\c << '+ END-OF-FILE '\g\e\t\t\x\t\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xchar * Xgettxt(num) Xint num; X{ X LINE *lin; X static char txtbuf[MAXLINE]; X X lin = getptr(num); X strcpy(txtbuf,lin->l_buff); X strcat(txtbuf,"\n"); X return(txtbuf); X} + END-OF-FILE gettxt.c chmod 'u=rw,g=r,o=r' \g\e\t\t\x\t\.\c set `sum \g\e\t\t\x\t\.\c` sum=$1 case $sum in 62154) :;; *) echo 'Bad sum in '\g\e\t\t\x\t\.\c >&2 esac echo Extracting \i\n\s\.\c sed 's/^X//' > \i\n\s\.\c << '+ END-OF-FILE '\i\n\s\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xins(str) Xchar *str; X{ X char buf[MAXLINE], *cp; X LINE *new, *cur, *nxt; X X cp = buf; X while(1) X { X if((*cp = *str++) == NL) X *cp = EOS; X if(*cp) X { X cp++; X continue; X } X if((new = (LINE *)malloc(sizeof(LINE)+strlen(buf))) == NULL) X return( ERR ); /* no memory */ X X strcpy(new->l_buff,buf); /* build new line */ X cur = getptr(curln); /* get current line */ X nxt = getptr(nextln(curln)); /* get next line */ X relink(cur, new, new, nxt); /* add to linked list */ X relink(new, nxt, cur, new); X lastln++; X curln++; X X if(*str == EOS) /* end of line ? */ X return( 1 ); X X cp = buf; X } X} + END-OF-FILE ins.c chmod 'u=rw,g=r,o=r' \i\n\s\.\c set `sum \i\n\s\.\c` sum=$1 case $sum in 15263) :;; *) echo 'Bad sum in '\i\n\s\.\c >&2 esac echo Extracting \m\a\k\e\f\i\l\e sed 's/^X//' > \m\a\k\e\f\i\l\e << '+ END-OF-FILE '\m\a\k\e\f\i\l\e X.SUFFIXES: .c .s X XCFLAGS = -F X XOBJS = append.s catsub.s ckglob.s deflt.s del.s docmd.s doglob.s\ X doprnt.s doread.s dowrite.s ed.s egets.s find.s getfn.s getlst.s\ X getnum.s getone.s getptr.s getrhs.s gettxt.s ins.s maksub.s move.s\ X optpat.s set.s setbuf.s subst.s getpat.s matchs.s amatch.s\ X unmkpat.s omatch.s makepat.s bitmap.s dodash.s esc.s system.s X Xed: $(OBJS) X cc -i -o ed $(OBJS) X + END-OF-FILE makefile chmod 'u=rw,g=r,o=r' \m\a\k\e\f\i\l\e set `sum \m\a\k\e\f\i\l\e` sum=$1 case $sum in 35727) :;; *) echo 'Bad sum in '\m\a\k\e\f\i\l\e >&2 esac echo Extracting \m\a\k\e\p\a\t\.\c sed 's/^X//' > \m\a\k\e\p\a\t\.\c << '+ END-OF-FILE '\m\a\k\e\p\a\t\.\c X#include <stdio.h> X#include "tools.h" X X/* X * Make a pattern template from the strinng pointed to by arg. Stop X * when delim or '\000' or '\n' is found in arg. Return a pointer to X * the pattern template. X * X * The pattern template used here are somewhat different than those X * used in the "Software Tools" book; each token is a structure of X * the form TOKEN (see tools.h). A token consists of an identifier, X * a pointer to a string, a literal character and a pointer to another X * token. This last is 0 if there is no subsequent token. X * X * The one strangeness here is caused (again) by CLOSURE which has X * to be put in front of the previous token. To make this insertion a X * little easier, the 'next' field of the last to point at the chain X * (the one pointed to by 'tail) is made to point at the previous node. X * When we are finished, tail->next is set to 0. X */ XTOKEN * Xmakepat(arg, delim) Xchar *arg; Xint delim; X{ X TOKEN *head, *tail, *ntok; X char buf[CLS_SIZE]; X int error; X X /* X * Check for characters that aren't legal at the beginning of X * a template. X */ X X if (*arg=='\0' || *arg==delim || *arg=='\n' || *arg==CLOSURE) X return(0); X X error = 0; X tail = head = NULL; X X while (*arg && *arg != delim && *arg != '\n' && !error) X { X ntok = (TOKEN *)malloc(TOKSIZE); X ntok->lchar = '\000'; X ntok->next = 0; X X switch(*arg) X { X case ANY: X ntok->tok = ANY; X break; X X case BOL: X if (head == 0) /* then this is the first symbol */ X ntok->tok = BOL; X else X ntok->tok = LITCHAR; X ntok->lchar = BOL; X break; X X case EOL: X if(*(arg+1) == delim || *(arg+1) == '\000' || X *(arg+1) == '\n') X { X ntok->tok = EOL; X } else { X ntok->tok = LITCHAR; X ntok->lchar = EOL; X } X break; X X case CLOSURE: X if (head != 0) X { X switch (tail->tok) X { X case BOL: X case EOL: X case CLOSURE: X return (0); X X default: X ntok->tok = CLOSURE; X } X } X break; X X case CCL: X X if(*(arg + 1) == NEGATE) X { X ntok->tok = NCCL; X arg += 2; X } else { X ntok->tok = CCL; X arg++; X } X X if( ntok->bitmap = makebitmap(CLS_SIZE) ) X arg = dodash(CCLEND, arg, ntok->bitmap ); X else { X fprintf(stderr,"Not enough memory for pat\n"); X error = 1; X } X break; X X default: X ntok->tok = LITCHAR; X ntok->lchar = esc(&arg); X } X X if (error || ntok == 0) X { X unmakepat(head); X return (0); X } else if (head == 0) X { X /* This is the first node in the chain. */ X X ntok->next = 0; X head = tail = ntok; X } else if (ntok->tok != CLOSURE) X { X /* Insert at end of list (after tail) */ X X tail->next = ntok; X ntok->next = tail; X tail = ntok; X } else if (head != tail) X { X /* X * More than one node in the chain. Insert the X * CLOSURE node immediately in front of tail. X */ X X (tail->next)->next = ntok; X ntok->next = tail; X } else { X /* X * Only one node in the chain, Insert the CLOSURE X * node at the head of the linked list. X */ X X ntok->next = head; X tail->next = ntok; X head = ntok; X } X arg++; X } X X tail->next = 0; X return (head); X} + END-OF-FILE makepat.c chmod 'u=rw,g=r,o=r' \m\a\k\e\p\a\t\.\c set `sum \m\a\k\e\p\a\t\.\c` sum=$1 case $sum in 60826) :;; *) echo 'Bad sum in '\m\a\k\e\p\a\t\.\c >&2 esac echo Extracting \m\a\k\s\u\b\.\c sed 's/^X//' > \m\a\k\s\u\b\.\c << '+ END-OF-FILE '\m\a\k\s\u\b\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xchar * Xmaksub(sub, subsz) Xchar *sub; Xint subsz; X{ X int size; X char delim, *cp; X X size = 0; X cp = sub; X X delim = *inptr++; X for(size = 0; *inptr != delim && *inptr != NL && size < subsz; size++) X { X if(*inptr == '&') X { X *cp++ = DITTO; X inptr++; X } else { X if(*inptr == ESCAPE) X { X inptr++; X if(*inptr < '0' || *inptr > '7') X switch(toupper(*++inptr)) X { X case NL: X *cp++ == ESCAPE; X break; X case 'S': X *cp++ = SP; X inptr++; X break; X case 'N': X *cp++ = NL; X inptr++; X break; X case 'T': X *cp++ = HT; X inptr++; X break; X case 'B': X *cp++ = BS; X inptr++; X break; X case 'R': X *cp++ = CR; X inptr++; X break; X default: X *cp++ = *inptr; X inptr++; X break; X } X else { X *cp = 0; X while(*inptr >= '0' && *inptr <= '7') X { X *cp = (*cp << 3)+(*inptr-'0'); X inptr++; X } X cp++; X } X } else X *cp++ = *inptr++; X } X } X if(size >= subsz) X return( NULL ); X X *cp = EOS; X return( sub ); X} + END-OF-FILE maksub.c chmod 'u=rw,g=r,o=r' \m\a\k\s\u\b\.\c set `sum \m\a\k\s\u\b\.\c` sum=$1 case $sum in 37872) :;; *) echo 'Bad sum in '\m\a\k\s\u\b\.\c >&2 esac echo Extracting \m\a\t\c\h\s\.\c sed 's/^X//' > \m\a\t\c\h\s\.\c << '+ END-OF-FILE '\m\a\t\c\h\s\.\c X#include <stdio.h> X#include "tools.h" X X/* X * Compares line and pattern. Line is a character string while pat X * is a pattern template made by getpat(). X * Returns: X * 1. A zero if no match was found. X * X * 2. A pointer to the last character satisfing the match X * if ret_endp is non-zero. X * X * 3. A pointer to the beginning of the matched string if X * ret_endp is zero. X * X * e.g.: X * X * matchs ("1234567890", getpat("4[0-9]*7), 0); X * will return a pointer to the '4', while: X * X * matchs ("1234567890", getpat("4[0-9]*7), 1); X * will return a pointer to the '7'. X */ Xchar * Xmatchs(line, pat, ret_endp) Xchar *line; XTOKEN *pat; Xint ret_endp; X{ X X char *rval, *bptr; X X bptr = line; X X while(*line) X { X if ((rval = amatch(line, pat, bptr)) == 0) X { X line++; X } else { X if(rval > bptr && rval > line) X rval--; /* point to last char matched */ X rval = ret_endp ? rval : line; X break; X } X } X return (rval); X} + END-OF-FILE matchs.c chmod 'u=rw,g=r,o=r' \m\a\t\c\h\s\.\c set `sum \m\a\t\c\h\s\.\c` sum=$1 case $sum in 03605) :;; *) echo 'Bad sum in '\m\a\t\c\h\s\.\c >&2 esac echo Extracting \m\o\v\e\.\c sed 's/^X//' > \m\o\v\e\.\c << '+ END-OF-FILE '\m\o\v\e\.\c X/* X * Copyright 1987 Brian Beattie Rights Reserved. X * X * Permission to copy and/or distribute granted under the X * following conditions: X * X * 1). No charge may be made other than resonable charges X * for reproduction. X * X * 2). This notice must remain intact. X * X * 3). No further restrictions may be added. X * X */ X#include <stdio.h> X#include "tools.h" X#include "ed.h" X Xmove(num) Xint num; X{ X LINE *k0, *k1, *k2, *k3; X X if(line1 <= 0 || line1 <= num && num <= line2) X return( ERR ); X k0 = getptr(prevln(line1)); X k1 = getptr(line1); X k2 = getptr(line2); X k3 = getptr(nextln(line2)); X X relink(k0, k3, k0, k3); X X if(num > line1) X { X curln = num; X num += line2-line1+1; X } else X curln = num + (line2 - line1 + 1); X X k0 = getptr(num); X k3 = getptr(nextln(num)); X X relink(k0, k1, k2, k3); X relink(k2, k3, k0, k1); X X return( 1 ); X} + END-OF-FILE move.c chmod 'u=rw,g=r,o=r' \m\o\v\e\.\c set `sum \m\o\v\e\.\c` sum=$1 case $sum in 07064) :;; *) echo 'Bad sum in '\m\o\v\e\.\c >&2 esac exit 0