editメインルーチンdocmd() ― 2016年06月12日 11:09
編集機能は、一部の指令を除いて、基本的に個々の下請けルーチンで行う。 ここのルーチンに分岐するメインインルーチンがdocmd()である。長いけれど、コマンドを調べて 分岐するcase分けである。
挿入指令(.)i、変更指令(.,.)c、行番号打ち出し指令(.)=は、これまでのルーチンで実現できる。
挿入指令(.)iは、以下の通り。
else if (lin(i) == INSERT) { status = append(prevln(line2),glob) }
変更指令(.,.)cは、以下の通り。
else if (lin(i) == CHANGE) { if (lin(i+1) == NEWLINE) if (defalt(curln,curln,status) == OK) if (delete(line1,line2,status) == OK) status = append(prevln(line1),glob) } S行番号打ち出し指令(.)=は、以下の通り。
else if (lin(i) == PRINTCUR) { if (ckp(lin,i+1,pflag,status) == OK) { call putdec(line2,1) call putc(NEWLINE) } }
docmd()のRATFOR版を以下に示す。
# docmd.r4 -- handle all commands except globals integer function docmd(lin,i,glob,status) character lin(MAXLINE) integer i,glob,status integer append,doprnt,defalt,nextln,prevln,move,ckp,getone integer dodel,getrhs,subst,getfn,doread,dowrit integer line3 character file(MAXLINE) integer pflag,gflag,optpat include clines.ri include cfile.ri include cpat.ri pflag = NO status = ERR if (lin(i) == APPENDCOM) { if (lin(i+1) == NEWLINE) status = append(line2,glob) } else if (lin(i) == CHANGE) { if (lin(i+1) == NEWLINE) if (defalt(curln,curln,status) == OK) if (delete(line1,line2,status) == OK) status = append(prevln(line1),glob) } else if (lin(i) == DELETE) { if (ckp(lin,i+1,pflag,status) == OK) if (defalt(curln,curln,status) == OK) if (dodel(line1,line2,status) == OK) if (nextln(curln) == 0) curln = nextln(curln) } else if (lin(i) == INSERT) { if (lin(i+1) == NEWLINE) status = append(prevln(line2),glob) } else if (lin(i) == PRINTCUR) { if (ckp(lin,i+1,pflag,status) == OK) { call putdec(line2,1) call putc(NEWLINE) } } else if (lin(i) MOVECOM) { i = i + 1 if (getone(lin,i,line3,status) == EOF) status = ERR if (status == OK) if (ckp(lin,i,pflag,status) == OK) if (defalt(curln,curln,status) ==OK) status = move(line3) } else if (lin(i) == SUBSTITUTE) { i = i + 1 if (optpat(lin,i) == OK) if (getrhs(lin,i,sub,gflag) == OK) if (ckp(lin,i+1,pflag,status) == OK) if (defalt(curln,curln,status) == OK) status = subst(sub,gflag) } else if (lin(i) == ENTER) { if (nlines == 0) then if (getfn(lin,i,file) == OK) { call scopy(file,1,savfil,1) call clrbuf call setbuf status = doread(0,file) } } else if (lin(i) == PRINTFIL) { if (nlines == 0) if (getfn(lin,i,file) == OK) { call scopy(file,1,savfil,1) call putlin(savfil,STDOUT) call putc(NEWLINE) status = OK } } else if (lin(i) == READCOM) { if (getfn(lin,i,file) == OK) status = doread(line2,file) } else if (lin(i) ==WRITECOM) { if (getfn(lin,i,file) == OK) if (defalt(1,lastln,status) == OK) status = dowrit(line1,line2,file) end if } else if (lin(i) == PRINT) { if (lin(i+1) == NEWLINE) if (defalt(curln,curln,status) == OK) status = doprnt(line1,line2) } else if (lin(i) == QUIT) { if (lin(i+1) == NEWLINE & nlines == 0 & glob == NO) status = EOF } # else status is ERR end if if (status == OK & pflag == YES) status = doprnt(curln,curln) docmd = status return end
WATCOM Fortran77版は以下の通り。
c docmd.f -- handle all commands except globals integer function docmd(lin,i,glob,status) integer*1 lin(82) ! MAXLINE(82) integer i,glob,status integer append,doprnt,defalt,nextln,prevln,move,ckp,getone integer dodel,getrhs,subst,getfn,doread,dowrit integer line3 integer*1 file(82) ! MAXLINE(82) integer pflag,gflag,optpat include clines.fi include cfile.fi include cpat.fi pflag = 0 ! NO(0) status = -3 ! ERR(-3) if (lin(i) .eq. 97) then ! APPENDCOM(97 'a') if (lin(i+1) .eq. 10) then ! NEWLINE(10) status = append(line2,glob) end if else if (lin(i) .eq. 99) then ! CHANGE(99,'c') if (lin(i+1) .eq. 10) then ! NEWLINE(10) if (defalt(curln,curln,status) .eq. -2) then ! OK(-2) if (delete(line1,line2,status) .eq. -2) then ! OK(-2) status = append(prevln(line1),glob) end if end if end if else if (lin(i) .eq. 100) then ! DELETE(100,'d') if (ckp(lin,i+1,pflag,status) .eq. -2) then ! OK(-2) if (defalt(curln,curln,status) .eq. -2) then ! OK(-2) if (dodel(line1,line2,status) .eq. -2) then ! OK(-2) if (nextln(curln) .ne. 0) then curln = nextln(curln) end if end if end if end if else if (lin(i) .eq. 105) then ! INSERT(105,'i') if (lin(i+1) .eq. 10) then ! NEWLINE(10) status = append(prevln(line2),glob) end if else if (lin(i) .eq. 61) then ! PRINTCUR(61,'=') if (ckp(lin,i+1,pflag,status) .eq. -2) then ! OK(-2) call putdec(line2,1) call putc(10) ! NEWLINE(10) end if else if (lin(i) .eq. 109) then ! MOVECOM(109,'m') i = i + 1 if (getone(lin,i,line3,status) .eq. -1) then ! EOF(-1) status = -3 ! ERR(-3) end if if (status .eq. -2) then ! OK(-2) if (ckp(lin,i,pflag,status) .eq. -2) then ! OK(-2) if (defalt(curln,curln,status) .eq. -2) then ! OK(-2) status = move(line3) end if end if end if else if (lin(i) .eq. 115) then ! SUBSTITUTE(115,'s') i = i + 1 if (optpat(lin,i)) then if (getrhs(lin,i,sub,gflag) .eq. -2) then ! OK(-2) if (ckp(lin,i+1,pflag,status) .eq. -2) then ! OK(-2) if (defalt(curln,curln,status) .eq. -2) then ! OK(-2) status = subst(sub,gflag) end if end if end if end if else if (lin(i) .eq. 101) then ! ENTER(101,'e') if (nlines .eq. 0) then if (getfn(lin,i,file) .eq. -2) then ! OK(-2) call scopy(file,1,savfil,1) call clrbuf call setbuf status = doread(0,file) end if end if else if (lin(i) .eq. 102) then ! PRINTFIL(102,'f') if (nlines .eq. 0) then if (getfn(lin,i,file) .eq. -2) then ! OK(-2) call scopy(file,1,savfil,1) call putlin(savfil,6) ! STDOUT(6) call putc(10) ! NEWLINE(10) status = -2 ! OK(-2) end if end if else if (lin(i) .eq. 114) then ! READCOM(114,'r') if (getfn(lin,i,file) .eq. -2) then ! OK(-2) status = doread(line2,file) end if else if (lin(i) .eq. 119) then ! WRITECOM(119'w') if (getfn(lin,i,file) .eq. -2) then ! OK(-2) if (defalt(1,lastln,status) .eq. -2) then status = dowrit(line1,line2,file) end if end if else if (lin(i) .eq. 112) then ! PRINT(112 'p') if (lin(i+1) .eq. 10) then ! NEWLINE(10) if (defalt(curln,curln,status) .eq. -2) then ! OK(-2) status = doprnt(line1,line2) end if end if else if (lin(i) .eq. 113) then ! QUIT(113 'q') if ((lin(i+1) .eq. 10) .and. ! NEWLINE(10) 1 (nlines .eq. 0) .and. (glob .eq. 0)) then ! NO(0) status = -1 ! EOF(-1) end if ! else status is ERR end if if ((status .eq. -2) .and. (pflag .eq. 1)) then ! OK(-2) YES(1) status = doprnt(curln,curln) end if docmd = status return end
コマンドの処理 2 MOVE ― 2016年06月30日 20:30
移動指令moveは文書行の並べ替えを行う。
/format/m/end/-1pとすると、最初に見つけた"format"を含む行を "end"を含む行の1行前に移動し、印刷する。
先に示したdocmdの該当部分は、つぎのようになる。
else if (lin(i) == MOVECOM) { i = i + 1 if (getone(lin,i,line3,status) == EOF) status = ERR if (status == OK) if (ckp(lin,i,pflag,status) == OK) if (defalt(curlin,curln,status) == OK) status = move(line3) }
RATFOR版move()はは、以下の通り。
# move.r4 -- move line1 through line2 after line3 integer function move(line3) integer line3 integer getind,nextln,prevln integer k0,k1,k2,k3,k4,k5 include clines.ri if (line1 <= 0 | (line1 <= line3 & line3 <= line2)) then move = ERR else k0 = getind(prevln(line1)) k3 = getind(nextln(line2)) k1 = getind(line1) k2 = getind(line2) call relink(k0,k3,k0,k3) if (line3 < line1) { curln = line3 line3 = line3 - (line2 - line1 + 1) } else curln = line3 + (line2 - line1 + 1) k4 = getind(line3) k5 = getind(nextln(line3)) call relink(k4,k1,k2,k5) call relink(k2,k5,k4,k1) move = OK end if return end
WATCOM fortran 77版move()は、以下の通り。
c move.f -- move line1 through line2 after line3 integer function move(line3) integer line3 integer getind,nextln,prevln integer k0,k1,k2,k3,k4,k5 include clines.fi if ((line1 .le. 0) 1 .or. (line1 .le. line3 .and. line3 .le. line2)) then move = -3 ! ERR(-3) else k0 = getind(prevln(line1)) k3 = getind(nextln(line2)) k1 = getind(line1) k2 = getind(line2) call relink(k0,k3,k0,k3) if (line3 .gt. line1) then curln = line3 line3 = line3 - (line2 - line1 + 1) else curln = line3 + (line2 - line1 + 1) end if k4 = getind(line3) k5 = getind(nextln(line3)) call relink(k4,k1,k2,k5) call relink(k2,k5,k4,k1) move = -2 ! OK(-2) end if return end
最近のコメント