コマンドの処理 3 COPY(修正版) ― 2016年07月03日 09:50
転写指令copy行の転写を行う。形式は、
(.,.)k行3
指定された範囲を行3の後ろに転写する。転写だから指令を"c"にしたいが、 すでに使ってしまったので、苦しいが"k"とする。 転写指令ののためのdocmdの該当部分は、以下の通り。
else if (lin(i) == COPYCMD) { 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 = kopy(line3) }
実際の転写はkopy()で行う。
Kopy()のRATFOR版は、以下の通り。
# kopy.r4 -- copy lines into aonother line integer function kopy(line3) integer line3 integer line,junk integer gettxt,inject,nextln include ctxt.fi include clines.fi kopy = ERR if (line3 <= line1 | line3 < line2) return curln = line3 for (line = line1; line <= line2; line = nextln(line)) { junk = gettxt(line) kopy = inject(txt) } return end
Kopy()のWATCOM fortran77版は、以下の通り。
c kopy.f -- copy lines into aonother line integer function kopy(line3) integer line3 integer line,junk integer gettxt,inject,nextln include ctxt.fi include clines.fi kopy = -3 ! ERR(-3) if ((line3 .le. line1) .or. (line3 .lt. line2)) then return end if curln = line3 line = line1 while (line .le. line2) do junk = gettxt(line) kopy = inject(txt) line = nextln(line) end while return end
コマンドの処理 4 SUBSTITUTE(修正) ― 2016年07月10日 17:31
(.,.)s/文型/更新型/gp置換指令ののためのdocmdの該当部分は、以下の通り。
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) }
optpat()で文型を取得し、getrhs()で更新型を取得する。実際の置換はsubst()で行う。
getrhs()のRATFOR版は以下の通り。
# getrhs.r4 -- get substitution string for "s" command integer function getrhs(lin,i,sub,gflag) character lin(MAXLINE),sub(MAXPAT) integer i,gflag,maksub getrhs = ERR if (lin(i) == EOS) return if (lin(i+1) == EOS) return i = maksub(lin,i+1,lin(i),sub) if (i == ERR) return if (lin(i+1) == GLOBAL) { i = i + 1 gflag = YES } else gflag = NO getrhs = OK return end
WATCOM fortran77版は以下の通り。
c getrhs.for -- get substitution string for "s" command integer function getrhs(lin,i,sub,gflag) integer*1 lin(81),sub(81) ! MAXLINE(81) MAXPAT(81) integer i,gflag,maksub getrhs = -3 ! ERR(-3) if (lin(i) .eq. -2) then ! EOS(-2) return end if if (lin(i+1) .eq. -2) then ! EOS(-2) return end if i = maksub(lin,i+1,lin(i),sub) if (i .eq. -3) then ! ERR(-3) return end if if (lin(i+1) .eq. 103) then ! GLOBAL('g'103) i = i + 1 gflag = 1 ! YES(1) else gflag = 0 ! NO(0) end if getrhs = -2 ! OK(-2) return end
subst()のRAFOR版は以下の通り。
# subst.r4 -- substitute "sub" for occurrences of pattern integer function subst(sub,gflag) character sub(MAXPAT) integer gflag character new(MAXLINE) integer amatch,gettxt,inject,delete integer j,junk,lastm,line,m,status integer addset,subbed include clines.ri include cpat.ri include ctxt.ri subst = ERR if (line1 <= 0) return for (line = line1;line <= line2;line=line+1) { j = 1 subbed = YES 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 machied text subbed = YES call catsub(txt,k,m,sub,new,j,MAXLINE) lastm = m } if ((m == 0) | m == k) then { # 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 } jumk = delete(line,line,status) # remembers dot subst = inject(new) if (subst == ERR) break subst = OK } } return end
WATCOM fortran77版は以下の通り。
c subst.f -- substitute "sub" for occurrences of pattern integer function subst(sub,gflag) integer*1 sub(81) ! MAXPAT(81) integer gflag integer*1 new(82) ! MAXLINE(82) integer amatch,gettxt,inject,delcmd integer j,junk,lastm,line,m,status integer addset,subbed include clines.fi include cpat.fi include ctxt.fi subst = -3 ! ERR(-3) if (line1 .le. 0) then return end if line = line1 while (line .le. line2) do j = 1 subbed = 1 ! YES(1) junk = gettxt(line) lastm = 0 k = 1 while (txt(k) .ne. -2) do ! EOS(-2) if (gflag .eq. 1 .or. subbed .eq. 0) then m = amatch(txt,k,pat) else m = 0 end if if ((m .gt. 0) .and. (lastm .ne. m)) then ! replace machied text subbed = 1 ! YES(1) call catsub(txt,k,m,sub,new,j,82) ! MAXLINE(82) lastm = m end if if ((m .eq.0) .or. (m .eq. k)) then ! no match or null match junk = addset(txt(k),new,j,82) ! MAXLINE(82) k = k + 1 else ! skip matched text k = m end if end while if (subbed .eq. 1) then ! YES(1) if (addset(-2,new,j,82) .eq. 0) then ! EOS(-2) MAXLINE(82) NO(0) subst = -3 ! ERR(-3) exit end if jumk = delcmd(line,line,status) ! remembers dot subst = inject(new) if (subst .eq. -3) then ! ERR(-3) exit end if subst = -2 ! OK(-2) end if line = line + 1 end while return end
コマンドの処理 5 入出力 ― 2016年07月20日 10:49
editは、
edit ファイル名
とすれば、指定されたファイル名のファイルがあれば、それをバッファに読み込み編集作業を 開始するようにする。ファイルがなければ、作成する。
さらに、ファイルの読み込み、書き込みのための指令を以下に示す。
読み込み指令は、バッファを空にしてから読み込む指令"e"と、現在のバッファーを 変更せずにその場所に読み込む"r"がある。
e ファイル名 (.)r ファイル名
また、ファイルへの書き出し命令"w"がある。
(.,.)w ファイル名
編集中のファイルをすべて書き出すには、"1,$w ファイル名"とする。
ファイル名が一度指定されると、それを記憶できるようにしておくと便利である。 ファイル名を省略した場合、記憶してあるファイル名を使うことにする。このファイル名を 記憶する場所は、以下の通り。
RATFOR版を以下に示す。
# cfile.ri -- remember file name common /cfile/savfil character savfil(MAXLINE) # remembered file name
WATCOM fortran77版を以下に示す。
c cfile.fi -- remember file name common /cfile/savfil integer*1 savfil(82) ! remembered file name MAXLINE(82)
これらのコマンドのdocmd()の部分を 以下に示す。
else if (lin(i) == ENTER) { if (nlines == 0) if (getfn(lin,i,file) == OK) { call scopy(file,1,savefil,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,savefil,1) call putlin(savefil,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,lastn,status) == OK) status = dowrit(line1,line2,file) }
getfn()はファイル名の取得と検査を行う。
RATFOR版は以下の通り。
# getfn.r4 -- get file name lin(i)... integer function getfn(lin,i,file) character lin(MAXLINE),file(MAXLINE) integer i integer j,k include cfile.ri getfn = ERR if (lin(i+1) == BLANK) j = i + 2 call skipbl(lin,j) for (k = 1; lin(j) != MEWLINE; k = k + 1) { file(k) = lin(j) j = J + 1 } file(k) = EOS if (k > 1) getfn = OK else if (lin(i+1) == NEWLINE & savfil(1) != EOS) { call scopy(savfil,1,file,1) # or old one getfn = OK # else error if (getfn == OK & savfil(1) != EOS) call scopy(file,1,savfil,1) # save if no old one return end
WATCOM fortran77版は以下の通り。
c getfn.f -- get file name lin(i)... integer function getfn(lin,i,file) integer*1 lin(81),file(81) ! MAXLINE(81) integer i integer j,k include cfile.fi getfn = -3 ! ERR(-3) if (lin(i+1) .eq. 32) then ! BLANK(32) j = i + 2 call skipbl(lin,j) k = 1 while (lin(j) .ne. 10) do ! NEWLINE(10) file(k) = lin(j) j = J + 1 k = k + 1 end while file(k) = -2 ! EOS(-2) if (k .gt. 1) then getfn = -2 ! OK(-2) end if else if ((lin(i+1) .eq. 10) .and. (savfil(1) .ne. -2)) then ! NEWLINE(10) EOS(-2) call scopy(savfil,1,file,1) ! or old one getfn = -2 ! OK(-2) ! else error end if if ((getfn .eq. -2) .and. (savfil(1) .ne. -2)) then ! OK(-2) EOS(-2) call scopy(file,1,savfil,1) ! save if no old one end if return end
doread()のRAFOR版は以下の通り。
# doread.r4 -- read "file" after "line" integer function doread(line,file) integer line character file(MAXLINE) character lin(MAXLINE) integer getlin,inject integer count,fd integer fopen include clines.ri fd = fopen(fd,file,READ) if (fd == ERR) doread = ERR else { curln = line doread = OK for (count = 0; getlin(lin,fd) != EOF; count = count + 1) { doread = inject(lin) if (doread == ERR) break } call fclose(fd) call putdec(count,1) call putc(NEWLINE) } return end
WATCOM fortran77版は以下の通り。
c doread.f -- read "file" after "line" integer function doread(line,file) integer line integer*1 file(81) ! MAXLINE(81) integer*1 lin(81) ! MAXLINE(81) integer getlin,inject integer count,fd integer fopen include clines.fi fd = fopen(fd,file,82) ! READ(82) if (fd .eq. -3 ) then ! ERR(-3) doread = -3 ! ERR(-3) else curln = line doread = -2 ! OK(-2) count = 0 while (getlin(lin,fd) .ne. -1) do ! EOF(-1) doread = inject(lin) if (doread .eq. -3) then ! ERR(-3) exit end if count = count + 1 end while call fclose(fd) call putdec(count,1) call putc(10) ! NEWLINE end if return end
dowrit()のRAFOR版は以下の通り。
# dowrit.r4 -- write "from" through "to" into file integer function dowrit(from,to,file) integer from,to character file(MAXLINE) integer gettxt integer fcreate,fopen integer fd,k,line include ctxt.ri fd = fcreate(file) if (fd == ERR) dowrit = ERR else { fd = fopen(fd,file,WRITE) if (fd == ERR) dwrit = ERR else { for (line = from; line <= to; line = line + 1) { k = gettxt(line) call putlin(txt,fd) } call fclose(fd) call putdec(to-from+1,1) call putc(NEWLINE) dowrit = OK } } return end
WATCOM fortran77版は以下の通り。
c dowrit.f -- write "from" through "to" into file integer function dowrit(from,to,file) integer from,to integer*1 file(81) ! MAXLINE(81) integer gettxt integer fcreate,fopen integer fd,k,line include ctxt.fi fd = fcreate(file) if (fd .eq. -3) then ! ERR(-3) dowrit = -3 ! ERR(-3) else fd = fopen(fd,file,87) ! WRITE(87) if (fd .eq. -3 ) then ! ERR(-3) dwrit = -3 ! ERR(-3) else line = from while (line .le. to) do k = gettxt(line) call putlin(txt,fd) line = line + 1 end while call fclose(fd) call putdec(to-from+1,1) call putc(10) ! NEWLINE(10) dowrit = -2 ! OK(-2) end if end if return end
コマンドの処理 6 広域指定gとx ― 2016年07月29日 15:18
指令a,c,i,qを除く任意の指令の前には、広域指定を 付けることができる。
広域指定gは、
g/文型/指令とすると、文型に合致する各行について、指令を実行する。 広域指定xは、
x/文型/指令とすると、文型に一致しない各行について、指令を実行する。
g/%#/pでは、RATFORの行頭から始まるコメント行を すべて、印刷する。
x/%#/pでは、RATFORの行頭から始まるコメント行以外の行すべてを 印刷する。
広域指定は、まず、ckglob()で該当行のMARK位置にYESを記録する。 ついで、doglob()でMARK位置がYESの行について、docmd()で指令を実行する。
ckglob()のRATFOR版は以下の通り。
# ckglob.r4 -- if global prefix, mark lines to be affected integer function ckglob(lin,i,status) character lin(MAXLINE) integer i,status integer defalt,getind,gettxt,nextln,optpat integer k,line,match,gflag include cbuf.fi include clines.fi include cpat.fi include ctxt.fi if (lin(i) != GLOBAL & lin(i) != EXCLUDE) status = EOF else { if (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 setgflag(buf(k+8),YES) else call setgflag(buf(k+8),NO) } for (line = nextln(line2); line != line1; line = nextln(line)) { k = getind(line) call setgflag(buf(k+8),NO) } status = OK } } ckglob = status return end
WATCOM fortran77版は以下の通り。
c ckglob.f -- if global prefix, mark lines to be affected integer function ckglob(lin,i,status) integer*1 lin(81) ! MAXLINE(81) integer i,status integer defalt,getind,gettxt,nextln,optpat integer k,line,match,gflag include cbuf.fi include clines.fi include cpat.fi include ctxt.fi if (lin(i) .ne. 103 ! GLOBAL('g',103) 1 .and. lin(i) .ne. 120) then ! EXCLUDE('x',120) status = -1 ! EOF(-1) else if (lin(i) .eq. 103) then ! GLOBAL('g',103) gflag = 1 ! YES(1) else gflag = 0 ! NO(0) end if i = i + 1 if (optpat(lin,i) .eq. -3 ! ERR(-3) 1 .or. defalt(1,lastln,status) .eq. -3) then ! ! ERR(-3) status = -3 ! ERR(-3) else i = i + 1 line = line1 while (line .le. line2) do k = gettxt(line) if (match(txt,pat) .eq. gflag) then call setgflag(buf(k+8),1) ! YES(1) else call setgflag(buf(k+8),0) ! NO(0) end if line = line + 1 end while line = nextln(line2) while (line .ne. line1) do k = getind(line) call setgflag(buf(k+8),0) ! NO(0) line = nextln(line) end while status = -2 ! OK(-2) end if end if ckglob = status return end
doglob()のRATFOR版は以下の通り。
# doglob.r4 -- do command at lin(i) on all marked lines integer function doglob(lin,i,cursav,status) character lin(MAXLINE) integer i,cursav,status integer docmd,getind,getlst,nextln integer getgflag integer count,istart,k,line include cbuf.fi include clines.fi status = OK count = 0 line = line1 istart = i repeat k = getind(line) if (getgflag(buf(k+MARK)) == YES) { call setgflag(buf(k+MARK),NO) curln = line cursav = curln i = istart if (getlst(lin,i,status) == OK) if (docmd(lin,i,YES,status) == OK) count = 0 } else { line = nextln(line) count = count + 1 } until (count > lastln | status != OK) doglob = status return end
WATCOM fortran77版は以下の通り。
c doglob.f -- do command at lin(i) on all marked lines integer function doglob(lin,i,cursav,status) integer*1 lin(82) ! MAXLINE(82) integer i,cursav,status integer docmd,getind,getlst,nextln integer getgflag integer count,istart,k,line include cbuf.fi include clines.fi status = -2 ! OK(-2) count = 0 line = line1 istart = i loop k = getind(line) if (getgflag(buf(k+8)) .eq. 1) then ! MARK(8) YES(1) call setgflag(buf(k+8),0) ! MARK(8) NO(0) curln = line cursav = curln i = istart if (getlst(lin,i,status) .eq. -2) then ! OK(-2) if (docmd(lin,i,1,status) .eq. -2) then ! YES(1) OK(-2) count = 0 end if end if else line = nextln(line) count = count + 1 end if until ((count .gt. lastln) .or. (status .ne. -2)) ! OK(-2) doglob = status return end
最近のコメント