home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
archives
/
mskermit.tar.gz
/
mskermit.tar
/
msbpct.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1989-02-06
|
8KB
|
221 lines
(* TURBO PASCAL 4.0 version of MSBPCT *)
(* *)
(* Author: Helmut Waelder (ZRWA001 at DTUZDV1.BITNET) *)
(* Zentrum fuer Datenverarbeitung *)
(* Brunnenstr. 27 *)
(* D-7400 Tuebingen *)
(* *)
(* Version 1.1 of 87/11/22 - modified to check for *)
(* corrupted input (optional) and to allow *)
(* output file name overriding *)
(* Gisbert W.Selke (RECK@DBNUAMA1.BITNET) *)
(* Wissenschaftliches Institut der Ortskrankenkassen*)
(* Kortrijker Strasse 1 *)
(* D-5300 Bonn 1 *)
(* West Germany *)
(* Version 1.2 of 88/02/10 - modified for Turbo Pascal 4.0 *)
(* *)
(* Decodes the mskermit.boo file about three times as fast *)
(* as the C version (if checking is not ON) *)
(*$S-*) (* Stack checking off *)
(*$R-*) (* Range checking off *)
(*$B-*) (* Boolean complete evaluation off *)
(*$I+*) (* I/O checking on *)
(*$N-*) (* No numeric coprocessor *)
(*$M 65500,16384,16384*) (* Reduce maximum heap *)
program msbpct;
uses crt;
const repbyte : byte = 78; (* ord('tilde') - ord('0') *)
zerobyte : byte = 48;
zerochar = '0';
smallo = 'o';
tilde = '~';
nullchar : char = #0;
maxlinlength = 76;
bufsize = 31500;
defaultinname = 'MSTIBM.BOO';
defaultoutname = 'MSTIBM.EXE';
defaultext = '.BOO';
type buftype = array (.1..bufsize.) of byte;
var a, b, c, d : byte;
i, index, linno, linlength : integer;
isend, ok, relax : boolean;
infilename, outfilename, originalname : string(.63.);
(* maximum path length in DOS *)
line : string(.132.);
inbuffer, outbuffer : buftype;
infile, outfile : text;
function getbyte(mode : integer) : byte;
(* get one proper character from input stream and decode it *)
var c : char;
ok : boolean;
procedure errmsg(errmode : integer);
(* output various error messages *)
begin
case errmode of
0 : writeln('Improper character #',ord(c),
' at line/column ',linno,'/',index);
1 : writeln('Improper null repeat count #',ord(c),
' at line/column ',linno,'/',index);
2 : writeln('Input line #',linno,' too long');
end;
end; (* errmsg *)
begin (* getbyte *)
repeat (* until proper character or eof *)
c := zerochar;
inc(index);
while (index > linlength) and (not isend) do
begin (* get new input line *)
inc(linno);
if lo(linno) = 0 then write(chr(13),'Line ',linno);
isend := eof(infile);
if not isend then readln(infile,line);
linlength := length(line);
if linlength > maxlinlength then errmsg(2);
index := 1;
end; (* get new input line *)
if not isend then c := line(.index.);
ok := isend or relax;
if not ok then
begin (* be suspicious *)
if c in (.zerochar..smallo.) then ok := true (* vanilla character *)
else (* depending on context *)
begin (* be suspicious *)
if c <> ' ' then
case mode of
0 : errmsg(0); (* within ordinary chunk *)
1 : if c = tilde then ok := true (* first byte of chunk... *)
else errmsg(0); (* ... may also be tilde *)
2 : if c in (.smallo..tilde.) then ok := true (* repeat count *)
else errmsg(1);
end; (* depending on context *)
end;
end; (* be suspicious *)
until ok; (* until proper character or eof *)
getbyte := ord(c) - zerobyte;
end; (* getbyte *)
procedure prepare;
(* get input and output file names; open files *)
var ch : char;
option : string(.10.);
ctemp : string(.63.);
begin
if paramcount > 3 then
Begin (* argument number error *)
writeln('Wrong number of parameters.');
writeln('Usage: MSBPCT (<input file name> (<output file name>)) (/C)');
halt(1);
end; (* argument number error *)
if paramcount >= 1 then infilename := paramstr(1)
else infilename := defaultinname;
if pos('.',infilename) = 0 then infilename := infilename + defaultext;
assign(infile,infilename);
settextbuf(infile,inbuffer);
(*$I-*) reset(infile); (*$I+*)
if IOResult <> 0 then
begin
writeln(infilename,' not found');
halt(1);
end;
readln(infile,originalname);
while ((length(originalname) > 0) and (originalname(.1.) = ' ')) do
delete(originalname,1,1);
if pos(' ',originalname) > 0 then
delete(originalname,pos(' ',originalname),999);
if length(originalname) = 0 then
begin
writeln('Original file name missing - replaced by ',defaultoutname);
originalname := defaultoutname;
end;
outfilename := originalname;
option := '';
if paramcount >= 2 then
begin (* more parameters *)
if paramcount > 2 then
begin (* still more parameters *)
outfilename := paramstr(2);
option := copy(paramstr(3),1,10);
end (* still more parameters *)
else
begin (* two parameters *)
ctemp := paramstr(2);
if ctemp(.1.) = '/' then option := copy(ctemp,1,10)
else outfilename := ctemp;
end; (* two parameters *)
end; (* more parameters *)
relax := true;
if option <> '' then
begin
if (option = '/C') or (option = '/c') then relax := false
else writeln('Only option available is [/C[')
end;
assign(outfile,outfilename);
settextbuf(outfile,outbuffer);
(*$I-*) reset(outfile); (*$I+*)
if IOResult = 0 then
begin (* overwrite existing file? *)
write('Output file ',outfilename,
' already exists. Continue (y/n)? ');
repeat
ch := readkey;
ch := upcase(ch);
until ch in (.'N','0','J','Y','1'.);
writeln;
if ch in (.'N','0'.) then halt(1);
end; (* overwrite existing file? *)
(*$I-*) rewrite(outfile); (*$I+*)
if IOResult<>0 then
begin
writeln('Couldn''t open ',outfilename);
halt(1);
end;
checkbreak := false;
end; (* prepare *)
Begin (* main *)
writeln('MSBPCT 1.2');
prepare;
writeln('Decoding ',infilename,', creating ',outfilename);
if outfilename <> originalname then write(' (Original name was ',
originalname,')');
if not relax then write(' (checking integrity)');
writeln;
isend := false;
linlength := 0;
index := succ(maxlinlength);
linno := 1;
while not isend do
begin (* get all chunks *)
a := getbyte(1);
if a = repbyte then
begin (* null repeating *)
b := getbyte(2);
for i:=1 to b do write(outfile,nullchar);
end (* null repeating *)
else
begin (* ordinary chunk *)
b := getbyte(0);
c := getbyte(0);
d := getbyte(0);
write(outfile,chr((a shl 2) or (b shr 4)));
write(outfile,chr((b shl 4) or (c shr 2)));
write(outfile,chr((c shl 6) or d));
end; (* ordinary chunk *)
end; (* get all chunks *)
(* write(outfile,#26); *) (* there is no need to append a ctrl-z *)
flush(outfile);
close(infile);
close(outfile);
writeln(chr(13),linno,' lines read.');
end. (* main *)