#-h- cbuf 892 asc 29-apr-81 19:08:44 [002,100] # /cbuf/ common block # put on a file called 'cbuf' # Used only by the editor common /cbuf/ buf(MAXBUF), lastbf, free #NOTBKY integer buf, lastbf, free #NOTBKY #buf(k+0) PREV previous line #buf(k+1) NEXT next line #buf(k+2) MARK mark for global commands #buf(k+3) SEEDADR where line is on scratch file #------------------------------------------------------------- #Special version for BKY #BKY common /cbuf/ buf(MAXBUF, lastbf, #BKY descr(NTYPS), locb(NTYPS), mskb(NTYPS) #BKY integer buf, lastb, descr, locb, mskb #BKY # structure of line pointers for all lines #BKY # MARK (LENG) SEEKADR PREV NEXT #BKY # 3 -- 18 15 15 #BKY #Variables in the arrays 'descr', 'locb', and 'mskb' describe #BKY #the line pointer structures. They are all initialized in #BKY #subroutine ed. #-h- cdel 295 asc 29-apr-81 19:08:46 [002,100] ## cdel - info on most recently deleted range of lines ## put on a file named 'cdel'. ## used only by the editor common / cdel / delcnt, fstdel, lstdel integer delcnt # number of lines deleted; init=0 integer fstdel # index of first line deleted integer lstdel # index of last line deleted #-h- cfile 174 asc 29-apr-81 19:08:47 [002,100] ## cfile common block - for editor # put on a file named 'cfile' # Used only by the editor common /cfile/ savfil(FILENAMESIZE) character savfil #remembered file name #-h- clines 796 asc 29-apr-81 19:08:48 [002,100] # /clines/ - common block for editor; holds line flags # put on a file called 'clines' # Used only by the editor common /clines/ line1, line2, nlines, curln, lastln, print, cursav, oldlin, oldndx, ifmod, number integer line1 # first line number integer line2 # second line number integer nlines # number of line numbers specified integer curln # current line: value of dot integer lastln # last line: value of $ integer print # flag to cause/suppress printing of line count integer cursav # value of current line before new command integer oldlin # last line number used by getind integer oldndx # last index returned by getind integer ifmod # if buffer has been modified since last write integer number # set if lines are to be numbered #-h- cnoreg 181 asc 29-apr-81 19:08:49 [002,100] # /cnoreg/ - common block to hold number register for editor # put in a file called 'cnoreg' # used by ch and ed common / cnoreg / noreg integer noreg # number register for ed #-h- cpat 156 asc 29-apr-81 19:08:50 [002,100] # /cpat/ - common block for editor # put on a file named 'cpat' # Used only by the editor common /cpat/ pat(MAXPAT) character pat # pattern #-h- csclin 199 asc 29-apr-81 19:08:51 [002,100] ## csclin common block - for editor # put on a file named 'csclin' # Used only by the editor common /csclin/ lin(MAXLINE) character lin # scratch line for reading lines to be injected #-h- cscrat 316 asc 29-apr-81 19:08:52 [002,100] # /cscrat/ - common block for editor; holds scratch file info # put on a file called 'cscrat' # Used only by the editor common /cscrat/ scr, scrend(2) , scrfil(FILENAMESIZE) integer scr # scratch file id integer scrend # end of info on scratch file character scrfil # name of scratch file #-h- ctbufs 108 asc 29-apr-81 19:08:53 [002,100] common / ctbufs / edtbuf(FILENAMESIZE, MAXTBUFS) character edtbuf # name of scratch files for temp buffs #-h- ctxt 184 asc 29-apr-81 19:08:54 [002,100] # /ctxt/ - common block for editor # put on a file called 'ctxt' # Used only by the editor common /ctxt/ txt(MAXLINE) character txt # text line for matching and output #-h- patdef 812 asc 29-apr-81 19:08:55 [002,100] ## definitions for the pattern matching routines # put on a file named 'defns' # Used by pattern.r and ed & sedit tools define(ANY,QMARK) define(BOL,PERCENT) define(BOT,LBRACE) define(CCL,LBRACK) define(CCLEND,RBRACK) define(CHAR,LETA) define(CLOSIZE,4) define(CLOSURE,STAR) define(CLOSURE1,PLUS) # closure of one or more occurrences # i.e. (pat)+ == (pat)(pat)* define(COUNT,1) define(EOL,DOLLAR) define(EOT,RBRACE) define(MAXTAG,10) define(NCCL,LETN) define(PREVCL,2) define(START,3) define(DITTO,(-3)) define(SECTION,(-4)) # /ctag/ - common block to hold section limits for ch # put in a file called 'ctag' # Used by find, ch, and ed #common /ctag/ taglim(MAXTAG2) #integer taglim define(I_CTAG,common/ctag/taglim(arith(2,*,MAXTAG)) integer taglim) #-h- ed.r 43966 asc 03-may-81 01:19:25 [002,100] #-h- defns 1697 asc 03-may-81 01:10:31 [002,100] # definitions for editor # put on a file called 'defns' # Used only by the editor include patdef # definitions for pattern matching stuff define(NUMBER_REGISTER,(-5)) # code for number register define(GLOBAL,LETG) define(PRINT,LETP) define(LIST,LETL) define(NREGCOM,LETN) define(MARKED,LETY) define(NOMARK,LETN) define(FORWARD,0) define(BACKWARD,-1) define(EXCLUDE,LETX) define(APPENDCOM,LETA) define(CHANGE,LETC) define(DELCOM,LETD) define(ENTER,LETE) define(JOINCOM,LETJ) define(PRINTFIL,LETF) define(READCOM,LETR) define(WRITECOM,LETW) define(INSERT,LETI) define(PRINTCUR,EQUALS) define(MOVECOM,LETM) define(QUIT,LETQ) define(SUBSTITUTE,LETS) define(CURLINE,PERIOD) define(PREVLINE,MINUS) define(NEXTLINE,PLUS) define(LASTLINE,DOLLAR) define(BACKUPLINE,MINUS) define(SCAN,SLASH) define(BACKSCAN,BACKSLASH) define(NOSTATUS,1) define(LINE0,1) define(PREV,0) define(NEXT,1) define(MARK,2) define(TEXT,3) define(MAX_ED_LINES,750) # maximum number of lines define(BUFENT,4) # words in buffer needed/line # now calculate size of buffer array # is equal to BUFENT * (MAX_ED_LINES + 2) # the 2 is to account for dummy lines before and after real lines define(MAXBUF,arith(BUFENT,*,arith(MAX_ED_LINES,+,2))) #BKY define(MAXBUF,1002) #BKY needs 1 word/line; also smaller buffer define(SEEKADR,3) define(LENG,4) define(BROWSE,LETB) define(SCREENSIZE,22) define(SPAWNCOM,CARET) define(COMMENT,SHARP) define(FORWARD,PLUS) define(CENTER,PERIOD) define(BACKWARD,MINUS) define(MAXTBUFS,4) define(TYPESET,LETT) define(UNDELETE,LETU) define(KOPYCOM,LETK) #-h- main 2184 asc 09-apr-81 10:44:46 [002,101] ## ed - driver subroutine for editor DRIVER(ed) character lin(MAXLINE), pstr(11), clower integer ckglob, docmd, doglob, doread, getarg, prompt, getlst integer i, status, clrbuf include cfile include clines include cpat include cbuf #Initialize flag for printing/suppression of line counts data print /YES/ data pstr(1), pstr(2), pstr(3)/COLON, BLANK, EOS/ #Initialize BKY line pointer descriptions #BKY data desc /PREV, NEXT, MARK, SEEKADR / #BKY data locb / 45, 0, 3, 30 / #BKY data mskb /77777b, 77777b, 7b, 777777b/ # Initialize variables and buffers call query("usage: ed [-] [-p[string]] [-n] [file].") call inited call setbuf number = NO # do not number lines!!! pat(1) = EOS savfil(1) = EOS #BKY filtyp = ASCII #Pick up file name and possible flag(s) for (i=1; getarg(i, lin, MAXLINE) != EOF; i=i+1) { if (lin(1) == DASH) { if (lin(2) == EOS) print = NO else if (clower(lin(2)) == LETP) { lin(13) = EOS call scopy(lin, 3, pstr, 1) } else if (clower(lin(2)) == LETN) number = YES } else { call scopy (lin, 1, savfil, 1) if (doread (0, savfil, ENTER) == ERR) call remark ('?.') } } repeat { status = prompt(pstr, lin, STDIN) if (status == EOF) # MUST clear buffer on EOF of input file { status = clrbuf(EOF) break } else if (status != ERR) { i = 1 cursav = curln if (getlst(lin, i, status) == OK) { if (ckglob(lin, i, status) == OK) status = doglob(lin, i, status) else if (status != ERR) status = docmd(lin, i, NO, status) # else error, do nothing } } if (status == ERR) { call remark('?.') curln = cursav } else if (status == EOF) if (clrbuf(QUIT) == OK) # will return ERR if changes since last w break # else OK, loop } call ended DRETURN end #-h- append 547 asc 09-apr-81 10:44:48 [002,101] ## append - append lines after 'line' /*/sor/edr/append integer function append(line, glob) integer inplin, inject integer line, glob include clines include csclin if (glob == YES) append = ERR else { curln = line for (append = NOSTATUS; append == NOSTATUS; ) if (inplin(lin, STDIN, curln+1) == EOF) append = EOF else if (lin(1) == PERIOD & lin(2) == NEWLINE) append = OK else if (inject(lin) == ERR) append = ERR } return end #-h- browse 736 asc 09-apr-81 10:44:49 [002,101] integer function browse(line, lin, i) character lin(ARB), direc integer line, i, screen, curscr, ctoi, lin1, lin2 include clines data screen, curscr/SCREENSIZE, SCREENSIZE/ if (lin(i) == NEWLINE) { direc = FORWARD screen = curscr } else { if (lin(i) == FORWARD | lin(i) == CENTER | lin(i) == BACKWARD) { direc = lin(i) i = i + 1 } else direc = FORWARD screen = ctoi(lin, i) - 1 if (screen <= 0) screen = curscr else curscr = screen } if (direc == FORWARD) lin1 = line else if (direc == CENTER) lin1 = line - (screen / 2) else lin1 = line - screen lin2 = lin1 + screen lin1 = max(1, lin1) lin2 = min(lin2, lastln) browse = doprnt(lin1, lin2) return end #-h- catsub 1498 asc 09-apr-81 10:44:51 [002,101] ## catsub - add replacement text to end of new. subroutine catsub(lin, from, to, sub, new, k, maxnew) integer addset , itoc, ctoi integer from, i, j, junk, k, maxnew, to character lin(MAXLINE), new(maxnew), sub(MAXPAT) , c I_CTAG # include tag common block include cnoreg for (i = 1; sub(i) != EOS; i = i + 1) if (sub(i) == DITTO) for (j = from; j < to; j = j + 1) junk = addset(lin(j), new, k, maxnew) else if (sub(i) == SECTION) { i = i + 1 n = sub(i) if (n <= 0 | n > MAXTAG) call error("CATSUB: illegal section.") for (j = taglim(2*n-1); j < taglim(2*n); j = j+1) junk = addset(lin(j), new, k, maxnew) } else if (sub(i) == NUMBER_REGISTER) { k = k + itoc(noreg, new(k), maxnew - k + 1) i = i + 1 c = sub(i) if (c == PLUS | c == MINUS) { i = i + 1 if (sub(i) != BLANK & sub(i) != TAB) { junk = ctoi(sub, i) if (junk == 0) junk = 1 } else junk = 1 if (c == PLUS) noreg = noreg + junk else noreg = noreg - junk } i = i - 1 # went one too far } else junk = addset(sub(i), new, k, maxnew) return end #-h- ckglob 1110 asc 09-apr-81 10:44:52 [002,101] ## ckglob - if global prefix, mark lines to be affected /*/sor/edr/ckglob integer function ckglob(lin, i, status) character lin(MAXLINE) integer defalt, getind, gettxt, match, nextln, optpat integer gflag, i, k, line, status character clower include cbuf include clines include cpat include ctxt if (clower(lin(i)) != GLOBAL & clower(lin(i)) != EXCLUDE) status = EOF else { if (clower(lin(i)) == GLOBAL) gflag = YES else gflag = NO i = i + 1 if (optpat(lin, i) == ERR | defalt(1, lastln, status) == ERR) status = ERR else { i = i + 1 for (line = line1; line <= line2; line = line + 1) { k = gettxt(line) if (match(txt, pat) == gflag) call setb (k, MARK, YES) else call setb (k, MARK, NO) } for (line=nextln(line2); line!=line1; line=nextln(line)) { k = getind(line) call setb (k, MARK, NO) } status = OK } } ckglob = status return end #-h- ckp 431 asc 09-apr-81 10:44:54 [002,101] ## ckp - check for 'p' or 'l' after command /*/sor/edr/ckp integer function ckp(lin, i, pflag, status) character lin(MAXLINE), c integer i, j, pflag, status character clower j = i c = clower(lin(j)) if (c == PRINT | c == LIST) { j = j + 1 pflag = c } else pflag = NO if (lin(j) == NEWLINE) status = OK else status = ERR ckp = status return end #-h- clrbuf 691 asc 09-apr-81 10:44:55 [002,101] ## clrbuf - dispose of editor scratch file /*/sor/edr/clrbuf define(BELL,7) # ^G, may have to be changed on your system integer function clrbuf(comand) character comand integer junk, prompt, isatty include cscrat include clines include csclin string pstr(30) "Are you SURE (y means YES)? " if (comand == QUIT & isatty(STDIN) == YES & ifmod == YES) { pstr(29) = BELL pstr(30) = EOS junk = prompt(pstr, lin, STDIN) if (lin(1) != LETY & lin(1) != BIGY) return(ERR) } call close(scr) #BKY call close (wscr) #BKY - close both open instances of file call remove(scrfil) return(OK) end #-h- conct 438 asc 09-apr-81 10:44:56 [002,101] ## conct - concat line to next line if necessary integer function conct (nbr, lin) integer nbr, i, gettxt, junk character lin(ARB) include clines include ctxt conct = OK for (i=1; lin(i)!=EOS; i=i+1) #check for lack of NEWLINE if (lin(i) == NEWLINE) return if (nbr+1 > lastln) #no next line { conct = ERR return } junk = gettxt (nbr+1) call scopy (txt, 1, lin, i) call delete (nbr+1, nbr+1, junk) return end #-h- defalt 342 asc 09-apr-81 10:44:56 [002,101] ## defalt - set defaulted line numbers /*/sor/edr/defalt integer function defalt(def1, def2, status) integer def1, def2, status include clines if (nlines == 0) { line1 = def1 line2 = def2 } if (line1 > line2 | line1 <= 0) status = ERR else status = OK defalt = status return end #-h- delete 770 asc 09-apr-81 10:44:58 [002,101] ## delete - delete lines 'from' through 'to' /*/sor/edr/delete integer function delete(from, to, status) integer getind, nextln, prevln integer from, k1, k2, status, to include cdel include clines if (from <= 0) status = ERR else { if (delcnt != 0) # return last lines deleted to free list. call ptfndx(fstdel, lstdel) fstdel = getind(from) # save index of first deleted line lstdel = getind(to) # save index of last delete line k1 = getind(prevln(from)) k2 = getind(nextln(to)) delcnt = to - from + 1 # save number of lines deleted lastln = lastln - delcnt curln = prevln(from) call relink(k1, k2, k1, k2) status = OK } delete = status return end #-h- docmd 4782 asc 09-apr-81 10:45:00 [002,101] ## docmd - handle all editor commands except globals /*/sor/edr/docmd integer function docmd(lin, i, glob, status) character file(FILENAMESIZE), lin(MAXLINE), sub(MAXPAT) integer append, delete, doprnt, doread, dowrit, lmove, subst, undel integer ckp, defalt, getfn, getone, getrhs, nextln, optpat, prevln character clower, comand integer gflag, glob, i, line3, pflag, status, dospwn, browse, dolist integer dojoin, donreg, typset, kopy integer clrbuf include cfile include clines include cpat pflag = NO # may be set by d, m, s status = ERR comand = clower(lin(i)) # make sure comparing with lower case i = i + 1 # point at next character if (comand == APPENDCOM) { if (lin(i) == NEWLINE) status = append(line2, glob) } else if (comand == CHANGE) { if (lin(i) == NEWLINE) andif (defalt(curln, curln, status) == OK) andif (delete(line1, line2, status) == OK) status = append(prevln(line1), glob) } else if (comand == DELCOM) { if (ckp(lin, i, pflag, status) == OK) andif (defalt(curln, curln, status) == OK) andif (delete(line1, line2, status) == OK) andif (nextln(curln) != 0) curln = nextln(curln) } else if (comand == INSERT) { if (lin(i) == NEWLINE) status = append(prevln(line2), glob) } else if (comand == JOINCOM) { if (ckp(lin, i, pflag, status) == OK) andif(defalt(curln, nextln(curln), status) == OK) status = dojoin(line1, line2) } else if (comand == PRINTCUR) { if (ckp(lin, i, pflag, status) == OK) { call putdec(line2, 1) call putc(NEWLINE) } } else if (comand == NREGCOM) { status = donreg(lin, i) } else if (comand == MOVECOM) { if (getone(lin, i, line3, status) == EOF) status = ERR if (status == OK) andif (ckp(lin, i, pflag, status) == OK) andif (defalt(curln, curln, status) == OK) status = lmove(line3) } else if (comand == KOPYCOM) { if (getone(lin, i, line3, status) == EOF) status = ERR if (status == OK) andif (ckp(lin, i, pflag, status) == OK) andif (defalt(curln, curln, status) == OK) status = kopy(line3) } else if (comand == SUBSTITUTE) { if (optpat(lin, i) == OK) andif (getrhs(lin, i, sub, gflag) == OK) andif (ckp(lin, i + 1, pflag, status) == OK) andif (defalt(curln, curln, status) == OK) status = subst(sub, gflag) } else if (comand == SPAWNCOM) { status = dospwn(lin, i) } else if (comand == ENTER) { if (nlines == 0) andif (getfn(lin, i, file) == OK) if (clrbuf(QUIT) == OK) { call scopy(file, 1, savfil, 1) call setbuf status = doread(0, file, ENTER) } else status = OK } else if (comand == PRINTFIL) { if (nlines == 0) andif (getfn(lin, i, file) == OK) { call scopy(file, 1, savfil, 1) call putlin(savfil, STDOUT) call putc(NEWLINE) status = OK } } else if (comand == READCOM) { if (getfn(lin, i, file) == OK) status = doread(line2, file, READCOM) } else if (comand == WRITECOM) { if (getfn(lin, i, file) == OK) andif (defalt(1, lastln, status) == OK) status = dowrit(line1, line2, file) } else if (comand == PRINT) { if (lin(i) == NEWLINE) andif (defalt(curln, curln, status) == OK) status = doprnt(line1, line2) } else if (comand == LIST) { if (lin(i) == NEWLINE) andif (defalt(curln, curln, status) == OK) status = dolist(line1, line2) } else if (comand == BROWSE) { if (defalt(curln, curln, status) == OK) status = browse(line2, lin, i) } else if (comand == COMMENT) status = OK else if (comand == NEWLINE) { if (nlines == 0) line2 = nextln(curln) status = doprnt(line2, line2) } else if (comand == BACKUPLINE) { if (nlines == 0) line2 = prevln(curln) status = doprnt(line2, line2) } else if (comand == QUIT) { if (lin(i) == NEWLINE & nlines == 0 & glob == NO) status = EOF } else if (comand == TYPESET) { status = typset(lin, i) } else if (comand == UNDELETE) { if (lin(i) == NEWLINE) status = undel(line2, glob) } # else status is ERR if (status == OK) if (pflag == PRINT) status = doprnt(curln, curln) else if (pflag == LIST) status = dolist(curln, curln) docmd = status return end #-h- doglob 1104 asc 09-apr-81 10:45:03 [002,101] ## doglob - do command at lin(i) on all marked lines /*/sor/edr/doglob integer function doglob(lin, i, status) character lin(MAXLINE) integer docmd, getind, getlst, nextln, prompt integer value(2) integer count, i, istart, k, line, status, last include cbuf include clines string gpstr "g_" for (last = length(lin); lin(last - 1) == ATSIGN; last = length(lin)) { lin(last - 1) = NEWLINE junk = prompt(gpstr, lin(last),STDIN) } status = OK count = 0 line = line1 istart = i repeat { k = getind(line) call getb(k, MARK, value) if (value(1) == YES) { call setb(k, MARK, NO) cursav = line i = istart repeat { curln = line if (getlst(lin, i, status) == OK) andif (docmd(lin, i, YES, status) == OK) count = 0 while(lin(i) != NEWLINE) i = i + 1 i = i + 1 if (lin(i) == EOS) break } } else { line = nextln(line) count = count + 1 } } until (count > lastln | status != OK) doglob = status return end #-h- dojoin 810 asc 09-apr-81 10:45:04 [002,101] ## dojoin - join (from,to) into one line integer function dojoin(from, to) integer from, to integer status, j, i, junk, k, savcln integer gettxt, prevln, delete, inject include clines include csclin include ctxt if (from <= 0) status = ERR else { status = OK if (from < to) { j = 1 for (i=from; i <= to; i=i+1) { junk = gettxt(i) for (k=1; txt(k) != NEWLINE & txt(k) != EOS; k=k+1) if (j >= MAXCARD) { status = ERR break 2 } else { lin(j) = txt(k) j = j + 1 } } lin(j) = NEWLINE lin(j+1) = EOS if (status == OK) { savcln = curln curln = prevln(curln) if (delete(from, to, status) == OK) status = inject(lin) else curln = savcln } } } dojoin = status return end #-h- dolist 767 asc 09-apr-81 10:45:06 [002,101] ## dolist - print lines 'from' through 'to' with control chars expanded integer function dolist(from, to) integer gettxt integer from, i, j, to, k character c include clines include ctxt if (from <= 0) dolist = ERR else { for (i = from; i <= to; i = i + 1) { j = gettxt(i) call ptlnum(i, STDOUT) # output line number, if required for (k=1; txt(k) != EOS; k=k+1) if (txt(k) >= BLANK | txt(k) == NEWLINE) call putch(txt(k), STDOUT) else { call putch(CARET, STDOUT) c = txt(k) + ATSIGN call putch(c, STDOUT) } } curln = to dolist = OK } return end #-h- donreg 657 asc 27-apr-81 17:19:01 [002,100] integer function donreg(lin, i) character lin(ARB), op integer i, j, status, pflag, dif integer index, ctoi include cnoreg string legal "=+-" status = OK pflag = NO if (lin(i) == NEWLINE) pflag = YES else { op = lin(i) if (index(legal, op) == 0) status = ERR else { j = i + 1 dif = ctoi(lin, j) if (dif == 0 & op != EQUALS) dif = 1 if (op == PLUS) noreg = noreg + dif else if (op == EQUALS) noreg = dif else noreg = noreg - dif if (lin(j) == LETP | lin(J) == BIGP) pflag = YES } } if (status == OK & pflag == YES) { call putdec(noreg, 1) call putc(NEWLINE) } return(status) end #-h- doprnt 442 asc 09-apr-81 10:45:07 [002,101] ## doprnt - print lines 'from' through 'to' integer function doprnt(from, to) integer gettxt integer from, i, j, to include clines include ctxt if (from <= 0) doprnt = ERR else { for (i = from; i <= to; i = i + 1) { j = gettxt(i) call ptlnum(i, STDOUT) # output line number, if necessary call putlin(txt, STDOUT) } curln = to doprnt = OK } return end #-h- doread 1081 asc 09-apr-81 10:45:09 [002,101] ## doread - read 'file' into scratch after 'line' /*/sor/edr/doread integer function doread(line, file, comand) character file(FILENAMESIZE), comand integer getlin, inject, open, access #BKY integer equal, gettyp integer count, fd, line include clines include cfile include csclin if (comand == ENTER) # enter new file - open at READWRITE access = READWRITE else # read command - open at READ access = READ call findit(file, lin) fd = open(lin, access) if (fd == ERR) doread = ERR else { #BKY if (equal(savfil,file) == YES) #pick up file type #BKY junk = gettyp (fd, filtyp) curln = line doread = OK for (count = 0; getlin(lin, fd) != EOF; count = count + 1) { doread = inject(lin) if (doread == ERR) break } call close(fd) if (print == YES) { call putdec(count, 1) call putc(NEWLINE) } if (comand == ENTER) # reset changes since last write switches ifmod = NO } return end #-h- dospwn 1128 asc 29-apr-81 18:58:42 [002,100] # spawns a shell command from within the editor # integer function dospwn(lin, i) character lin(ARB), proces(FILENAMESIZE), args(ARGBUFSIZE), sh(3), desc(PIDSIZE) integer i, j, spawn, init, k, int, create, loccom, status include ctbufs string suffix IMAGE_SUFFIX data init/YES/ data sh/LETS, LETH, EOS/ if (init == YES) { call impath(args) # get search path if (loccom(sh, args, suffix, proces) != BINARY) { call remark("Cannot find sh image file.") dospwn = ERR return } k = 1 call stcopy(sh, 1, args, k) call chcopy(BLANK, args, k) for (j=1; j <= MAXTBUFS; j=j+1) { call stcopy(edtbuf(1,j), 1, args, k) args(k) = BLANK k = k + 1 } args(k) = EOS init = NO } call skipbl(lin, i) # extra blanks not necessary if (lin(i) == NEWLINE | lin(i) == EOS) # no shell command status = spawn(proces, sh, desc, WAIT) else { int = create(edtbuf(1,1), WRITE) if (int == ERR) status = ERR else { call putlin(lin(i), int) call close(int) status = spawn(proces, args, desc, WAIT) } } if (status != ERR) status = OK return(status) end #-h- dowrit 795 asc 09-apr-81 10:45:11 [002,101] integer function dowrit(from, to, file) character file(MAXLINE), lin(FILENAMESIZE) integer create, gettxt integer fd, from, k, line, to include ctxt include clines include cfile call findit(file, lin) fd = create(lin, WRITE) if (fd == ERR) dowrit = ERR else { #BKY call settyp (fd, filtyp) #Set output file to type of input file for (line = from; line <= to; line = line + 1) { k = gettxt(line) call putlin(txt, fd) } call close(fd) if (print == YES) { call putdec(to-from+1, 1) call putc(NEWLINE) } dowrit = OK ifmod = NO # reset changes since last w flags } return end ## dowrit - write 'from' through 'to' into file /*/sor/edr/dowrit #-h- ended 124 asc 09-apr-81 10:45:12 [002,101] subroutine ended integer i include ctbufs for (i=1; i <= MAXTBUFS; i=i+1) call remove(edtbuf(1,i)) return end #-h- findit 280 asc 09-apr-81 10:45:13 [002,101] subroutine findit(in, out) character in(ARB), out(ARB) integer i, n, ctoi include ctbufs call scopy(in, 1, out, 1) if (in(1) == DOLLAR) { i = 2 n = ctoi(in, i) + 1 if (n > 1 & n <= MAXTBUFS) call scopy(edtbuf(1,n), 1, out, 1) } return end #-h- getb 573 asc 09-apr-81 10:45:13 [002,101] ## getb - retrieve 'value' of 'type' in buf(index) /*/sor/edr/getb subroutine getb (index, type, value) integer index, type integer value(2) include cbuf # ------ IAS and VMS version (16- and 32--bit words) if (type == PREV) #this word also holds MARK bit value(1) = abs(buf(index)) else if (type == NEXT) value(1) = buf(index+1) else if (type == MARK) { if (buf(index) < 0) value(1) = YES else value(1) = NO } else if (type == SEEKADR) { value(1) = buf(index+2) value(2) = buf(index+3) } return end #-h- getfn 737 asc 09-apr-81 10:45:14 [002,101] ## getfn - get file name frm lin(i) /*/sor/edr/getfn integer function getfn(lin, i, file) character lin(MAXLINE), file(MAXLINE) integer i, j, k include cfile getfn = ERR if (lin(i) == BLANK | lin(i) == TAB) { j = i + 1 # get new file name call skipbl(lin, j) for (k = 1; lin(j) != NEWLINE; k = k + 1) { file(k) = lin(j) j = j + 1 } file(k) = EOS if (k > 1) getfn = OK } else if (lin(i) == NEWLINE & savfil(1) != EOS) { call scopy(savfil, 1, file, 1) # or old name getfn = OK } # else error # if (getfn == OK & savfil(1) == EOS) # call scopy(file, 1, savfil, 1) # save if no old one return end #-h- getind 657 asc 09-apr-81 10:45:16 [002,101] ## getind - locate line index in buffer /*/sor/edr/getind integer function getind(line) integer line, k, j integer nextln, prevln include clines data oldndx /ERR/ data oldlin /-2/ if (oldndx != ERR & line == nextln(oldlin)) call getb(oldndx, NEXT, k) else if (oldndx != ERR & line == oldlin) k = oldndx else if (oldndx != ERR & line == prevln(oldlin)) call getb(oldndx, PREV, k) else { k = LINE0 if (line < lastln/2) for (j=0; j=line; j=j-1) #search backwards call getb(k, PREV, k) } oldlin = line oldndx = k getind = k return end #-h- getlst 665 asc 09-apr-81 10:45:17 [002,101] ## getlst - collect line numbers at lin(i), increment i /*/sor/edr/getlst integer function getlst(lin, i, status) character lin(MAXLINE) integer getone integer i, num, status include clines line2 = 0 for (nlines = 0; getone(lin, i, num, status) == OK; ) { line1 = line2 line2 = num nlines = nlines + 1 if (lin(i) != COMMA & lin(i) != SEMICOL) break if (lin(i) == SEMICOL) curln = num i = i + 1 } nlines = min(nlines, 2) if (nlines == 0) line2 = curln if (nlines <= 1) line1 = line2 if (status != ERR) status = OK getlst = status return end #-h- getnum 1329 asc 09-apr-81 10:45:17 [002,101] ## getnum - convert one term to line number /*/sor/edr/getnum integer function getnum(lin, i, pnum, status) character lin(MAXLINE) integer ctoi, index, optpat, ptscan integer i, pnum, status include clines include cpat # string digits '0123456789' character digits(11) data digits(01)/DIG0/ data digits(02)/DIG1/ data digits(03)/DIG2/ data digits(04)/DIG3/ data digits(05)/DIG4/ data digits(06)/DIG5/ data digits(07)/DIG6/ data digits(08)/DIG7/ data digits(09)/DIG8/ data digits(10)/DIG9/ data digits(11)/EOS/ getnum = OK if (index(digits, lin(i)) > 0) { pnum = ctoi(lin, i) i = i - 1 # move back; to be advanced at the end } else if (lin(i) == CURLINE) pnum = curln else if (lin(i) == LASTLINE) pnum = lastln else if (lin(i) == PREVLINE) pnum = curln - 1 else if (lin(i) == NEXTLINE) pnum = curln + 1 else if (lin(i) == SCAN | lin(i) == BACKSCAN) { if (optpat(lin, i) == ERR) # build the pattern getnum = ERR else if (lin(i) == SCAN) getnum = ptscan(FORWARD, pnum) else getnum = ptscan(BACKWARD, pnum) } else getnum = EOF if (getnum == OK) i = i + 1 # point at next character to be examined status = getnum return end #-h- getone 1011 asc 09-apr-81 10:45:19 [002,101] ## getone - evaluate one line number expression /*/sor/edr/getone integer function getone(lin, i, num, status) character lin(MAXLINE) integer getnum integer i, istart, mul, num, pnum, status include clines istart = i num = 0 call skipbl(lin, i) if (getnum(lin, i, num, status) == OK) # first term repeat { # + or - terms call skipbl(lin, i) if (lin(i) != PLUS & lin(i) != MINUS) { status = EOF break } if (lin(i) == PLUS) mul = +1 else mul = -1 i = i + 1 call skipbl(lin, i) if (getnum(lin, i, pnum, status) == OK) num = num + mul * pnum if (status == EOF) status = ERR } until (status != OK) if (num < 0 | num > lastln) status = ERR if (status == ERR) getone = ERR else if (i <= istart) getone = EOF else getone = OK status = getone return end #-h- getrhs 744 asc 09-apr-81 10:45:20 [002,101] ## getrhs - get substitution string for 's' command /*/sor/edr/getrhs integer function getrhs(lin, i, sub, gflag) character lin(MAXLINE), sub(MAXPAT) integer maksub, length, index integer gflag, i, j character clower string pnl "p@n" getrhs = ERR if (lin(i) == EOS) return if (lin(i + 1) == EOS) return if (index(lin(i+1), lin(i)) == 0) # insert missing delimiter { j = length(lin) call chcopy(lin(i), lin, j) call stcopy(pnl, 1, lin, j) # add trailing p for print } i = maksub(lin, i + 1, lin(i), sub) if (i == ERR) return if (clower(lin(i+1)) == GLOBAL) { i = i + 1 gflag = YES } else gflag = NO getrhs = OK return end #-h- gettxt 464 asc 09-apr-81 10:45:22 [002,101] ## gettxt - locate text for line, copy to txt /*/sor/edr/gettxt integer function gettxt(line) character null(1) integer getind integer line, len, j, k integer loc(2) include cbuf include cscrat include ctxt data null/EOS/ k = getind(line) if (line != 0) { call getb (k, SEEKADR, loc) call seek (loc, scr) call readf (txt, dummy, scr) } else call scopy(null, 1, txt, 1) gettxt = k return end #-h- gtfndx 325 asc 09-apr-81 10:45:22 [002,101] integer function gtfndx(newind) include cbuf if (free != 0) # something in free list { newind = free call getb(free, NEXT, free) # relink free list } else if (lastbf + BUFENT <= MAXBUF) { newind = lastbf lastbf = lastbf + BUFENT } else newind = ERR gtfndx = newind return end #-h- inited 336 asc 09-apr-81 10:45:23 [002,101] subroutine inited character num(2), edt(4) integer i, j, junk, itoc include ctbufs include cnoreg data edt/LETE, LETD, LETT, EOS/ for (j=1; j <= MAXTBUFS; j=j+1) { i = j - 1 junk = itoc(i, num, 2) edt(3) = num(1) call scratf(edt, edtbuf(1,j)) } noreg = 0 # initialize number register return end #-h- inject 576 asc 09-apr-81 10:45:24 [002,101] ## inject - insert lin after curln, write scratch /*/sor/edr/inject integer function inject(lin) character lin(MAXLINE) integer getind, maklin, nextln integer i, k1, k2, k3 include clines for (i = 1; lin(i) != EOS; ) { i = maklin(lin, i, k3) if (i == ERR) { inject = ERR break } k1 = getind(curln) k2 = getind(nextln(curln)) call relink(k1, k3, k3, k2) call relink(k3, k2, k1, k3) curln = curln + 1 lastln = lastln + 1 inject = OK } return end #-h- inplin 564 asc 09-apr-81 10:45:24 [002,101] ## inplin - conditionally output line number, then get line integer function inplin(lin, chn, num) character lin(ARB), pstr(9) integer chn, i, n, num integer prompt, itoc include clines string tail "=>" if (number == YES) { n = itoc(num, pstr, 7) # format number no wider than 6 chars for (i=6; n > 0; i=i-1) # shift number right in pstr { pstr(i) = pstr(n) n = n - 1 } for ( ; i > 0; i=i-1) # fill with BLANKS pstr(i) = BLANK call scopy(tail, 1, pstr, 7) } else pstr(1) = EOS inplin = prompt(pstr, lin, chn) return end #-h- kopy 574 asc 09-apr-81 10:45:26 [002,101] ## kopy - copy lines (line1,line2) after line3 integer function kopy(line3) integer line3, nline, junk, lstlin integer gettxt, inject include clines include ctxt if (line1 <= 0 | (line1 <= line3 & line3 <= line2)) kopy = ERR else { kopy = OK curln = line3 lstlin = line2 for (nline = line1; nline <= lstlin; nline = nline + 1) { junk = gettxt(nline) kopy = inject(txt) if (line3 < line1) # compensate for injected line. { nline = nline + 1 lstlin = lstlin + 1 } if (kopy == ERR) break } } return end #-h- lmove 832 asc 09-apr-81 10:45:27 [002,101] ## lmove - move line1 through line2 after line 3 /*/sor/edr/lmove integer function lmove(line3) integer getind, nextln, prevln integer k0, k1, k2, k3, k4, k5, line3, delta include clines if (line1 <= 0 | (line1 <= line3 & line3 <= line2)) lmove = ERR else { k0 = getind(prevln(line1)) k3 = getind(nextln(line2)) k1 = getind(line1) k2 = getind(line2) call relink(k0, k3, k0, k3) delta = line2 - line1 + 1 lastln = lastln - delta if (line3 > line1) { curln = line3 line3 = line3 - delta } else curln = line3 + delta k4 = getind(line3) k5 = getind(nextln(line3)) call relink(k4, k1, k2, k5) call relink(k2, k5, k4, k1) lastln = lastln + delta lmove = OK } return end #-h- maklin 1051 asc 09-apr-81 10:45:28 [002,101] ## maklin - make new line entry, copy text to scratch /*/sor/edr/maklin integer function maklin(lin, i, newind) character lin(MAXLINE) integer addset, gtfndx integer i, j, junk, newind, txtend include cbuf include cscrat include ctxt include clines maklin = ERR oldndx = ERR if (gtfndx(newind) == ERR) { # no room for new line entry call remark ('File size exceeded.') return } txtend = 1 for (j = i; lin(j) != EOS; ) { junk = addset(lin(j), txt, txtend, MAXLINE) j = j + 1 if (lin(j - 1) == NEWLINE) break } if (addset(EOS, txt, txtend, MAXLINE) == NO) { call ptfndx(newind, newind) # return free index block return } call setb (newind, SEEKADR, scrend) call seek (scrend, scr) call putlin (txt, scr) #NOTBKY #BKY call putlin(txt, wscr) call markl (scr, scrend) call setb (newind, MARK, NO) maklin = j # next character to be examined in lin return end #-h- maksub 1067 asc 09-apr-81 10:45:29 [002,101] ## maksub - make substitution string in sub (/*/sor/chr) integer function maksub(arg, from, delim, sub) character esc character arg(MAXARG), delim, sub(MAXPAT) integer addset, type, ctoi integer from, i, j, junk j = 1 for (i = from; arg(i) != delim & arg(i) != EOS; i = i + 1) if (arg(i) == AND) junk = addset(DITTO, sub, j, MAXPAT) else if (arg(i) == DOLLAR & type(arg(i+1)) == DIGIT) { i = i + 1 n = ctoi(arg, i) junk = addset(SECTION, sub, j, MAXPAT) junk = addset(n, sub, j, MAXPAT) i = i - 1 } else if (arg(i) == DOLLAR & (arg(i+1) == LETN | arg(i+1) == BIGN)) { i = i + 1 junk = addset(NUMBER_REGISTER, sub, j, MAXPAT) } else junk = addset(esc(arg, i), sub, j, MAXPAT) if (arg(i) != delim) # missing delimiter maksub = ERR else if (addset(EOS, sub, j, MAXPAT) == NO) # no room maksub = ERR else maksub = i return end #-h- nextln 206 asc 09-apr-81 10:45:30 [002,101] ## nextln - get line after 'line' /*/sor/edr/nextln integer function nextln(line) integer line include clines nextln = line + 1 if (nextln > lastln) nextln = 0 return end #-h- optpat 567 asc 09-apr-81 10:45:31 [002,101] ## optpat - make pattern if specified at lin(i) /*/sor/edr/optpat integer function optpat(lin, i) character lin(MAXLINE) integer makpat integer i include cpat if (lin(i) == EOS) i = ERR else if (lin(i + 1) == EOS) i = ERR else if (lin(i + 1) == lin(i)) # repeated delimiter i = i + 1 # leave existing pattern alone else i = makpat(lin, i + 1, lin(i), pat) if (pat(1) == EOS) i = ERR if (i == ERR) { pat(1) = EOS optpat = ERR } else optpat = OK return end #-h- prevln 206 asc 09-apr-81 10:45:32 [002,101] ## prevln - get line before 'line' /*/sor/edr/prevln integer function prevln(line) integer line include clines prevln = line - 1 if (prevln < 0) prevln = lastln return end #-h- ptfndx 127 asc 09-apr-81 10:45:33 [002,101] subroutine ptfndx(start, stop) integer start, stop include cbuf call setb(stop, NEXT, free) free = start return end #-h- ptlnum 230 asc 09-apr-81 10:45:33 [002,101] ## ptlnum - conditionally output line number on unit subroutine ptlnum(num, unit) integer num, unit include clines string tail "=>" if (number == YES) { call putint(num, 6, unit) call putlin(tail, unit) } return end #-h- ptscan 509 asc 09-apr-81 10:45:34 [002,101] ## ptscan - scan for next occurrence of pattern /*/sor/edr/ptscan integer function ptscan(way, num) integer gettxt, match, nextln, prevln integer k, num, way include clines include cpat include ctxt num = curln repeat { if (way == FORWARD) num = nextln(num) else num = prevln(num) k = gettxt(num) if (match(txt, pat) == YES) { ptscan = OK return } } until (num == curln) ptscan = ERR return end #-h- readf 309 asc 09-apr-81 10:45:35 [002,101] ## readf - read line from file (random access) subroutine readf (buffer, count, int) #note--in this implementation, a call to getlin is made rather #than reading a specified number of characters integer count, int, getlin, junk character buffer(ARB) junk = getlin (buffer, int) return end #-h- relink 239 asc 09-apr-81 10:45:35 [002,101] ## relink - rewrite two half line links /*/sor/edr/relink subroutine relink(a, x, y, b) integer a, b, x, y include clines oldndx = ERR call setb (x, PREV, a) call setb (y, NEXT, b) ifmod = YES return end #-h- setb 667 asc 09-apr-81 10:45:36 [002,101] ## setb - Set 'type' in buf(index) to 'value' /*/sor/edr/setb subroutine setb (index, type, value) integer index, type integer value(2) include cbuf # ------ VMS and IAS version (32- and 16-bit words) if (type == PREV) #the leftmost bit of this word holds MARK { if (buf(index) < 0) buf(index) = -value(1) else buf(index) = value(1) } else if (type == NEXT) buf(index+1) = value(1) else if (type == MARK) { if (value(1) == YES) buf(index) = -abs(buf(index)) else buf(index) = abs(buf(index)) } else if (type == SEEKADR) { buf(index+2) = value(1) buf(index+3) = value(2) } return end #-h- setbuf 1103 asc 09-apr-81 10:45:37 [002,101] ## setbuf - create scratch file, set up line 0 /*/sor/edr/setbuf subroutine setbuf integer create #BKY integer open integer k, j include cbuf include clines include cscrat include cdel character fil(4) # string null '' character null(1) data fil(1)/LETE/ data fil(2)/LETD/ data fil(3)/LETS/ data fil(4)/EOS/ data null(1) /EOS/ call scratf(fil, scrfil) #get unique name for scratch file scr = create(scrfil, READWRITE) #NOTBKY #BKY scr = create(scrfil, READ) if (scr == ERR) call cant(scrfil) #For BKY - needs file opened twice - once at READ and one at WRITE access #BKY wscr = open(scrfil, WRITE) #BKY if (wscr == ERR) #BKY call cant (scrfil) call markl (scr, scrend) lastbf = LINE0 free = 0 # initialize free list call maklin(null, 1, k) # create empty line 0 call relink(k, k, k, k) # establish initial linked list curln = 0 lastln = 0 cursav = 0 delcnt = 0 # initialize # of deleted lines ifmod = NO # initialize changes since last w variables return end #-h- subst 1465 asc 09-apr-81 10:45:39 [002,101] ## subst - substitute "sub" for occurrences of pattern /*/sor/edr/subst integer function subst(sub, gflag) character new(MAXLINE), sub(MAXPAT) integer addset, amatch, gettxt, inject, conct integer gflag, j, junk, k, lastm, line, m, status, subbed include clines include cpat include ctxt subst = ERR if (line1 <= 0) return for (line = line1; line <= line2; line = line + 1) { j = 1 subbed = NO junk = gettxt(line) lastm = 0 for (k = 1; txt(k) != EOS; ) { if (gflag == YES | subbed == NO) m = amatch(txt, k, pat) else m = 0 if (m > 0 & lastm != m) { # replace matched text subbed = YES call catsub(txt, k, m, sub, new, j, MAXLINE) lastm = m } if (m == 0 | m == k) { # no match or null match junk = addset(txt(k), new, j, MAXLINE) k = k + 1 } else # skip matched text k = m } if (subbed == YES) { if (addset(EOS, new, j, MAXLINE) == NO) { subst = ERR break } subst = conct(line, new) #check for conctenation if (subst == ERR) break call delete(line, line, status) # remembers dot subst = inject(new) if (subst == ERR) break subst = OK } } return end #-h- typset 701 asc 09-apr-81 10:45:40 [002,101] ## typset - roff the current buffer integer function typset(lin, i) character lin(ARB), temp(81) integer dowrit, dospwn integer i, j, modtmp, prttmp, status include clines string scrfil "$3" string roffst "roff $3 " modtmp = ifmod # save state of ifmod flag prttmp = print # save state of print flag print = NO # no line numbers please if (dowrit(1, lastln, scrfil) != ERR) { j = 1 call stcopy(roffst, 1, temp, j) for ( ; lin(i) != NEWLINE & lin(i) != EOS; i=i+1) call chcopy(lin(i), temp, j) j = 1 status = dospwn(temp, j) } else { call remark("? Cannot create scratch file.") status = ERR } ifmod = modtmp # restore flags print = prttmp # ... return(status) end #-h- undel 556 asc 09-apr-81 10:45:41 [002,101] ## undel - undelete last lines deleted; insert them after `line'. integer function undel(line, glob) integer getind, nextln, prevln integer glob, line, k1, k2, status include cdel include clines if (delcnt == 0 | glob == YES) status = ERR else { curln = line k1 = getind(curln) k2 = getind(nextln(curln)) if (curln == lastln) curln = curln + delcnt else curln = nextln(curln) lastln = lastln + delcnt call relink(k1, fstdel, lstdel, k2) call relink(lstdel, k2, k1, fstdel) delcnt = 0 status = OK } return(status) end #-h- ed.rof 17424 asc 06-may-81 07:37:22 [002,100] .bp .pl 60 .rm 70 .in 0 .he *ED*04/21/78*ED .fo ''-#-'' .fi .in 7 .ti -7 NAME .br ed - text editor .sp 1 .ti -7 SYNOPSIS .br ed [-] [-n] [-pstring] [file] .sp 1 .ti -7 DESCRIPTION .br Ed is a text editor. If the 'file' argument is given, the file is read into ed's buffer so that it can be edited and its name is remembered for possible future use. Ed operates on a copy of any file it is editing; changes made in the copy have no effect on the file until a w (write) command is given. The optional '-' suppresses the printing of line counts by the e (edit), r (read), and w (write) commands. The -p flag may be used to specify ed's prompt string. The default is ": ". If prompting is not desired, a bare -p in the command line will turn it off. The -n flag indicates that the user desires to see line numbers prepended to each line of the buffer. Ed accepts commands from script files as well as a terminal. To do this, invoke ed and substitute the script file name for the standard input, as follows - ed [file]