beattie@netxcom.UUCP (Brian Beattie) (06/23/87)
You'd think I'd learn. Never ever release software with out testing the release. This time I have tested the shar file. If it don't work I'm gonna quit programming and take up COBOL. ----------------------------- 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: # Makefile # ed.h # tools.h # 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 # getpat.c # matchs.c # amatch.c # unmkpat.c # omatch.c # makepat.c # bitmap.c # dodash.c # esc.c # system.c # This archive created: Mon Jun 22 21:06:18 1987 export PATH; PATH=/bin:$PATH 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 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 'ed.h' then echo shar: will not over-write existing file "'ed.h'" else cat << \SHAR_EOF > 'ed.h' /* ed.h */ #define FATAL (ERR-1) struct line { int l_stat; /* empty, mark */ struct line *l_prev; struct line *l_next; char l_buff[1]; }; typedef struct line LINE; #define LINFREE 1 /* entry not in use */ #define LGLOB 2 /* line marked global */ #define LEXCL 4 /* line marked exclude */ #define MAXLINE 256 /* max number of chars per line */ #define MAXPAT 256 /* max number of chars per replacement pattern */ #define MAXFNAME 256 /* max file name size */ extern LINE line0; extern int curln, lastln, line1, line2, nlines; extern int nflg; /* print line number flag */ extern int lflg; /* print line in verbose mode */ extern int pflg; /* print current line after each command */ extern char *inptr; /* tty input buffer */ extern char linbuf[], *linptr; /* current line */ extern int truncflg; /* truncate long line flag */ extern int eightbit; /* save eighth bit */ extern int nonascii; /* count of non-ascii chars read */ extern int nullchar; /* count of null chars read */ extern int truncated; /* count of lines truncated */ extern int fchanged; /* file changed */ #define nextln(l) ((l)+1 > lastln ? 0 : (l)+1) #define prevln(l) ((l)-1 < 0 ? lastln : (l)-1) extern char *getfn(); extern LINE *getptr(); extern char *gettxt(); extern char *maksub(); extern TOKEN *optpat(); extern char *catsub(); extern char *strcpy(); extern int *malloc(); /*********************************************************************/ SHAR_EOF fi # end of overwriting check if test -f 'tools.h' then echo shar: will not over-write existing file "'tools.h'" else cat << \SHAR_EOF > 'tools.h' static char tools_h[] = "$Header: tools.h,v 2.1 85/11/14 11:30:00 beattie Exp $"; /* * #defines for non-printing ASCII characters */ #define NUL 0x00 /* ^@ */ #define EOS 0x00 /* end of string */ #define SOH 0x01 /* ^A */ #define STX 0x02 /* ^B */ #define ETX 0x03 /* ^C */ #define EOT 0x04 /* ^D */ #define ENQ 0x05 /* ^E */ #define ACK 0x06 /* ^F */ #define BEL 0x07 /* ^G */ #define BS 0x08 /* ^H */ #define HT 0x09 /* ^I */ #define LF 0x0a /* ^J */ #define NL '\n' #define VT 0x0b /* ^K */ #define FF 0x0c /* ^L */ #define CR 0x0d /* ^M */ #define SO 0x0e /* ^N */ #define SI 0x0f /* ^O */ #define DLE 0x10 /* ^P */ #define DC1 0x11 /* ^Q */ #define DC2 0x12 /* ^R */ #define DC3 0x13 /* ^S */ #define DC4 0x14 /* ^T */ #define NAK 0x15 /* ^U */ #define SYN 0x16 /* ^V */ #define ETB 0x17 /* ^W */ #define CAN 0x18 /* ^X */ #define EM 0x19 /* ^Y */ #define SUB 0x1a /* ^Z */ #define ESC 0x1b /* ^[ */ #define FS 0x1c /* ^\ */ #define GS 0x1d /* ^] */ #define RS 0x1e /* ^^ */ #define US 0x1f /* ^_ */ #define SP 0x20 /* space */ #define DEL 0x7f /* DEL*/ #define TRUE 1 #define FALSE 0 #define ERR -2 /* Definitions of meta-characters used in pattern matching * routines. LITCHAR & NCCL are only used as token identifiers; * all the others are also both token identifier and actual symbol * used in the regular expression. */ #define BOL '^' #define EOL '$' #define ANY '.' #define LITCHAR 'L' #define ESCAPE '\\' #define CCL '[' /* Character class: [...] */ #define CCLEND ']' #define NEGATE '~' #define NCCL '!' /* Negative character class [^...] */ #define CLOSURE '*' #define OR_SYM '|' #define DITTO '&' /* Largest permitted size for an expanded character class. (i.e. the class * [a-z] will expand into 26 symbols; [a-z0-9] will expand into 36.) */ #define CLS_SIZE 128 /* * Tokens are used to hold pattern templates. (see makepat()) */ typedef char BITMAP; typedef struct token { char tok; char lchar; BITMAP *bitmap; struct token *next; } TOKEN; #define TOKSIZE sizeof (TOKEN) /* * An absolute maximun for strings. */ #define MAXSTR 132 /* Maximum numbers of characters in a line */ extern char *matchs(); extern char *amatch(); extern char *in_string(); extern TOKEN *getpat(); extern int esc(); extern char *dodash(); extern TOKEN *makepat(); extern int unmakepat(); extern int insert(); extern int delete(); extern int isalphanum(); extern char *stoupper(); extern int pr_tok(); extern int pr_line(); extern BITMAP *makebitmap(); /* macros */ #define max(a,b) ((a>b)?a:b) #define min(a,b) ((a<b)?a:b) #define toupper(c) (c>='a'&&c<='z'?c-32:c) 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]; 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); stat = ins(lin); if(stat < 0) return( ERR ); } } 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 '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 'dowrite.c' then echo shar: will not over-write existing file "'dowrite.c'" else cat << \SHAR_EOF > 'dowrite.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" dowrite(from, to, fname, apflg) int from, to; char *fname; int apflg; { extern FILE *fopen(); FILE *fp; int lin, err; int lines, bytes; char *str; err = 0; lines = bytes = 0; printf("\"%s\" ",fname); if((fp = fopen(fname,(apflg?"a":"w"))) == NULL) { printf("file open error\n"); return( ERR ); } for(lin = from; lin <= to; lin++) { str = gettxt(lin); lines++; bytes += strlen(str); if(fputs(str, fp) == EOF) { printf("file write error\n"); err++; break; } } printf("%d lines %d bytes\n",lines,bytes); fclose(fp); return( err ); } SHAR_EOF fi # end of overwriting check if test -f 'ed.c' then echo shar: will not over-write existing file "'ed.c'" else cat << \SHAR_EOF > 'ed.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" #include <setjmp.h> jmp_buf env; LINE line0; int curln = 0; int lastln = 0; char *inptr; static char inlin[MAXLINE]; int nflg, lflg, pflg, pflag; int line1, line2, nlines; extern char fname[]; int version = 1; intr() { printf("Interrupt:\n"); longjmp(env, 1); } main(argc,argv) int argc; char **argv; { int stat, i, j, prmpt; setbuf(); prmpt = isatty(0); /* if interactive */ if(argc > 1) { for(i = 1; i < argc; i++) { if(doread(0,argv[i])) curln = 1; strcpy(fname, argv[i]); break; } } while(1) { setjmp(env); signal(2, intr); if(nflg) fprintf(stdout,"%d: ",curln); else if(prmpt) fprintf(stdout,": "); if (fgets(inlin, sizeof(inlin),stdin) == NULL) { break; } if(*inlin == '!') { for(inptr = inlin; *inptr != NL; inptr++) ; *inptr = EOS; system(inlin+1); continue; } inptr = inlin; if(getlst() >= 0) if(ckglob()) { if((stat = doglob()) >= 0) { curln = stat; continue; } } else { if((stat = docmd(0)) >= 0) { if(stat == 1) doprnt(curln, curln); continue; } } if(stat == EOF) { exit(0); } if(stat == FATAL) { fputs("FATAL ERROR\n",stderr); exit(1); } fputs("\007",stderr); } } 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 '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 'getfn.c' then echo shar: will not over-write existing file "'getfn.c'" else cat << \SHAR_EOF > 'getfn.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" extern char fname[MAXFNAME]; char * getfn() { static char file[256]; char *cp; if(*inptr == NL) { strcpy(file, fname); } else { while(*inptr == SP || *inptr == HT) inptr++; cp = file; while(*inptr && *inptr != NL && *inptr != SP && *inptr != HT) { *cp++ = *inptr++; } *cp = '\0'; if(strlen(file) == 0) { printf("bad file name\n"); return( NULL ); } } if(strlen(file) == 0) { printf("no file name\n"); return(NULL); } return( file ); } 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 '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 '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 '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 '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 '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 '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 'unmkpat.c' then echo shar: will not over-write existing file "'unmkpat.c'" else cat << \SHAR_EOF > 'unmkpat.c' #include <stdio.h> #include "tools.h" /* Free up the memory usde for token string */ unmakepat(head) TOKEN *head; { register TOKEN *old_head; while (head) { switch (head->tok) { case CCL: case NCCL: free(head->bitmap); /* fall through to default */ default: old_head = head; head = head->next; free (old_head); break; } } } 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 'makepat.c' then echo shar: will not over-write existing file "'makepat.c'" else cat << \SHAR_EOF > 'makepat.c' #include <stdio.h> #include "tools.h" /* * Make a pattern template from the strinng pointed to by arg. Stop * when delim or '\000' or '\n' is found in arg. Return a pointer to * the pattern template. * * The pattern template used here are somewhat different than those * used in the "Software Tools" book; each token is a structure of * the form TOKEN (see tools.h). A token consists of an identifier, * a pointer to a string, a literal character and a pointer to another * token. This last is 0 if there is no subsequent token. * * The one strangeness here is caused (again) by CLOSURE which has * to be put in front of the previous token. To make this insertion a * little easier, the 'next' field of the last to point at the chain * (the one pointed to by 'tail) is made to point at the previous node. * When we are finished, tail->next is set to 0. */ TOKEN * makepat(arg, delim) char *arg; int delim; { TOKEN *head, *tail, *ntok; char buf[CLS_SIZE]; int error; /* * Check for characters that aren't legal at the beginning of * a template. */ if (*arg=='\0' || *arg==delim || *arg=='\n' || *arg==CLOSURE) return(0); error = 0; tail = head = NULL; while (*arg && *arg != delim && *arg != '\n' && !error) { ntok = (TOKEN *)malloc(TOKSIZE); ntok->lchar = '\000'; ntok->next = 0; switch(*arg) { case ANY: ntok->tok = ANY; break; case BOL: if (head == 0) /* then this is the first symbol */ ntok->tok = BOL; else ntok->tok = LITCHAR; ntok->lchar = BOL; break; case EOL: if(*(arg+1) == delim || *(arg+1) == '\000' || *(arg+1) == '\n') { ntok->tok = EOL; } else { ntok->tok = LITCHAR; ntok->lchar = EOL; } break; case CLOSURE: if (head != 0) { switch (tail->tok) { case BOL: case EOL: case CLOSURE: return (0); default: ntok->tok = CLOSURE; } } break; case CCL: if(*(arg + 1) == NEGATE) { ntok->tok = NCCL; arg += 2; } else { ntok->tok = CCL; arg++; } if( ntok->bitmap = makebitmap(CLS_SIZE) ) arg = dodash(CCLEND, arg, ntok->bitmap ); else { fprintf(stderr,"Not enough memory for pat\n"); error = 1; } break; default: ntok->tok = LITCHAR; ntok->lchar = esc(&arg); } if (error || ntok == 0) { unmakepat(head); return (0); } else if (head == 0) { /* This is the first node in the chain. */ ntok->next = 0; head = tail = ntok; } else if (ntok->tok != CLOSURE) { /* Insert at end of list (after tail) */ tail->next = ntok; ntok->next = tail; tail = ntok; } else if (head != tail) { /* * More than one node in the chain. Insert the * CLOSURE node immediately in front of tail. */ (tail->next)->next = ntok; ntok->next = tail; } else { /* * Only one node in the chain, Insert the CLOSURE * node at the head of the linked list. */ ntok->next = head; tail->next = ntok; head = ntok; } arg++; } tail->next = 0; return (head); } 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 '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 '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 'system.c' then echo shar: will not over-write existing file "'system.c'" else cat << \SHAR_EOF > 'system.c' #define SHELL "/bin/sh" system(c) char *c; { int pid, status; switch (pid = fork()) { case -1: return -1; case 0: execl(SHELL, "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 |