program SUBS { see procedure Say (next) } ; procedure Say(const K : word ; const St : string) ; begin if K>0 then Writeln(' Parameter ', K, ' wrong, ', St) else Writeln(' SUBS www.merlyn.demon.co.uk >= 2003-12-31'^M^J, ' Filter : parameters A=B, each B replaces A'^M^J, ' A & B each 0..255 / $0..$FF / '' #26=^Z out terminates'^M^J, ' [XY]# shifts all X..Y by #, # is signed integer') ; HALT(1) end {Say} ; const BuffSize = $8000 ; CharSet : set of char = [] ; var Buff : array [1..BuffSize] of char ; Xlat : array [char] of char ; StdIn, StdOut : file ; DQ, J : integer ; K, ReadCount : word ; P : byte ; Q1, Q2 : char ; S, T : string [11] ; Done : boolean ; BEGIN ; if (ParamCount=0) or (ParamStr(1)='/?') then Say(0, '') ; for K := 1 to ParamCount do begin S := ParamStr(K) ; { if S='' then Say(0, '') ; } if S[1]='[' then begin Val(Copy(S, 5, 255), DQ, J) ; if J<>0 then Say(K, 'bad increment') ; for Q1 := S[2] to S[3] do begin Q2 := Q1 ; Inc(Q2, DQ) ; Include(CharSet, Q1) ; Xlat[Q1] := Q2 end ; CONTINUE end ; P := Pos('=', S) ; if P=0 then Say(K, 'no =') ; T[1] := #0 ; T := Copy(S, 1, P-1) ; if T[1]='''' then Q1 := T[2] else begin Val(T, byte(Q1), J) ; if J<>0 then Say(K, 'bad 1st number') end ; T[1] := #0 ; T := Copy(S, P+1, 255) ; if T[1]='''' then Q2 := T[2] else begin Val(T, byte(Q2), J) ; if J<>0 then Say(K, 'bad 2nd number') end ; Include(CharSet, Q1) ; Xlat[Q1] := Q2 ; end {K} ; Assign(StdIn, '') ; Reset(StdIn, 1) ; Assign(StdOut, '') ; Rewrite(StdOut, 1) ; repeat BlockRead(StdIn, Buff, BuffSize, ReadCount) ; Done := ReadCount = 0 ; for K := 1 to ReadCount do begin Q1 := Buff[K] ; if Q1 in CharSet then Buff[K] := Xlat[Q1] ; end ; for K := 1 to ReadCount do if Buff[K] = #26 then begin Done := true ; ReadCount := Pred(K) ; BREAK end ; BlockWrite(StdOut, Buff, ReadCount) { would fail on #26 = ^Z } ; until Done ; Close(StdOut) ; Close(StdIn) ; END.