{ Program to read a disk file }
{ and remove any control characters or change them to }
{ a sequence of printable characters. }
{ Also finds any high-bit-set characters, }
{ strips the high bit and optionally prefixes the char }
{ with an escape character. }
{Assume the escape char for control chars is chosen to }
{be "%". Then this table shows how control codes are }
{represented in the output file. }
{ binary char value (ORD) representation
------------------------- --------------
0 NUL %@
1 SOH %A
2 STX %B
. .
. .
. .
25 EM %Y
26 SUB %Z
27 ESC %[
28 FS %\
29 GS %]
30 RS %^
31 US %_
92 % %% ***** note this special representation!
127 DEL %? ***** note this special representation!
}
CONST
version = '1.1';
sector_size = 128; {#bytes in a sector}
BEGIN
flag := TRUE;
WHILE flag DO BEGIN
WRITE ('Enter the control-chars escape character: ');
READLN (response);
IF response=' ' THEN BEGIN
WRITELN ('No escape char; control codes remain as is.');
esc_control_char := 0;
flag := FALSE;
END
ELSE IF response IN ['!', '#', '$', '%', '&', '*',
'|', '~', '`', '''', '{', '}',
'=', '"', '<', '>', '/']
THEN BEGIN
flag := FALSE;
esc_control_char := ORD (response);
END
ELSE BEGIN
WRITELN('*** Not an acceptable character. Try again.');
END{IF};
END{WHILE};
flag := TRUE;
WHILE flag DO BEGIN
WRITE ('Enter the highbit-chars escape character: ');
READLN (response);
IF response=' ' THEN BEGIN
WRITELN ('No escape char; high bits will be stripped.');
esc_highbit_char := 0;
flag := FALSE;
END
ELSE IF response IN ['!', '#', '$', '%', '&', '*',
'|', '~', '`', '''', '{', '}',
'=', '"', '<', '>', '/'] THEN BEGIN
flag := FALSE;
esc_highbit_char := ORD (response);
END
ELSE BEGIN
WRITELN('*** Not an acceptable character. Try again.');
END{IF};
IF (esc_highbit_char>0) AND
(esc_control_char = esc_highbit_char) THEN BEGIN
WRITELN ('*** Cannot be the same as the control escape char.');
WRITELN (' Try again. ');
flag := TRUE;
END{IF};
END{WHILE};
END{PROCEDURE};
{ Translates the char in in_char into a 1 to 3 byte}
{ sequence stored in out_chars. Sets nchars to the}
{ # of chars. }
PROCEDURE xlate_char ( in_char :byte;
VAR out_chars :outch_array;
VAR nchars :INTEGER );
BEGIN{PROCEDURE}
nchars := 0;
IF in_char > 127 THEN BEGIN
{Handle high-bit chars}
in_char := in_char - 128;
ctr_highbit := ctr_highbit + 1;
IF esc_highbit_char > 0 THEN BEGIN
nchars := nchars + 1;
out_chars[nchars] := esc_highbit_char;
END{IF};
END{IF};
IF (in_char>31) AND (in_char<127) THEN BEGIN
{Handle "ordinary" characters. }
nchars := nchars + 1;
out_chars[nchars] := in_char;
IF (in_char=esc_control_char) OR
(in_char=esc_highbit_char)
THEN BEGIN
nchars := nchars + 1;
out_chars[nchars] := in_char;
END{IF};
END
ELSE IF (in_char=carriage_return) OR
(in_char=line_feed) THEN BEGIN
nchars := nchars + 1;
out_chars[nchars] := in_char;
END
ELSE IF (in_char<=31) OR (in_char=127) THEN BEGIN
{ Handle control chars. }
{ We have already excluded CR and LF}
ctr_cc := ctr_cc + 1;
IF esc_control_char=0 THEN BEGIN
nchars := nchars + 1;
out_chars[nchars] := in_char;
END
ELSE BEGIN
nchars := nchars + 1;
out_chars[nchars] := esc_control_char;
nchars := nchars + 1;
out_chars[nchars] := in_char + ORD('@');
IF in_char=127 THEN out_chars[nchars] := ORD('?');
END{IF};
END{IF};
END{PROCEDURE};
FUNCTION close_outfile :INTEGER;
BEGIN{FUNCTION}
close_outfile := 0;
END{FUNCTION};
{--------------------------------------------------------}
{Gets the next char (pseudochar, a byte) from the input buffer.}
{Signals EOF by returning -1. Returns 0 if get a char. }
FUNCTION get_char ( VAR in_char :byte ) :INTEGER;
VAR
status :INTEGER;
BEGIN{FUNCTION}
status := 0;
IF in_bufptr >= sector_size THEN BEGIN
status := read_infile;
END{IF};
IF status = 0 THEN BEGIN
in_bufptr := in_bufptr + 1;
in_char := in_buffer[in_bufptr];
IF in_char = eof_char THEN status := -1;
END{IF};
BEGIN{PROCEDURE}
WRITELN('enter CR to continue');
READLN(response);
END{PROCEDURE};
{--------------------------------------------------}
FUNCTION copy_file :INTEGER;
VAR
status :INTEGER;
i :INTEGER;
in_char :byte;
out_chars :outch_array;
nchars :INTEGER;
BEGIN{FUNCTION}
status := 0;
WHILE status = 0 DO BEGIN
status := get_char (in_char);
IF status <> 0 THEN BEGIN
put_purge;
END
ELSE BEGIN
xlate_char (in_char, out_chars, nchars);
FOR i := 1 TO nchars DO BEGIN
IF status = 0 THEN status := put_char (out_chars[i]);
END{FOR};
END{IF};
END{WHILE};
copy_file := status;
END{FUNCTION};