-- EtoAImpl.mesa
-- last edit: Stewart 22-Feb-82 17:48:16
DIRECTORY
CComParse USING [Close, Get, Open],
EBCDICTables,
Exec,
IOStream,
PrivateIOStream,
Rope;
EtoAImpl: PROGRAM IMPORTS CComParse, Exec, IOStream, PrivateIOStream, Rope =
BEGIN
Main: PROC = {
infilename, outfilename: Rope.ROPE;
in, out: IOStream.Handle;
infs, outfs: IOStream.Handle;
recordLength, lengthRead, bptr, i, lineLength: NAT;
buffer: REF TEXT ← NEW[TEXT[10000]];
{
[in, out] ← PrivateIOStream.CreateTajoStreamsFromTTYHandle[LOOPHOLE[Exec.w]];
CComParse.Open[switchchar: '-];
infilename ← CComParse.Get[];
outfilename ← CComParse.Get[];
CComParse.Close[];
IF outfilename.Length[]=0 THEN outfilename ← Rope.Cat["o", infilename];
out.PutF["EtoA, reading from %s, writing to %s\n", IOStream.rope[infilename], IOStream.rope[outfilename]];
infs ← IOStream.CreateFileStream[fileName: infilename, accessOptions: IOStream.AccessOptions[read], createOptions: IOStream.CreateOptions[oldOnly] ! IOStream.Error => {
out.PutF["%s not found\n", IOStream.rope[infilename]];
GOTO GiveUp;
}];
outfs ← IOStream.CreateFileStream[fileName: outfilename, accessOptions: IOStream.AccessOptions[overwrite]];
DO
recordLength ← GetWord[infs !IOStream.EndOfStream => EXIT];
out.PutF["rl=%5d ", IOStream.int[recordLength]];
lengthRead ← infs.GetBlock[buffer, 0, recordLength];
IF lengthRead#recordLength THEN {
out.PutF["GetBlock didn't read enough!\n"];
GOTO GiveUp;
};
bptr ← 4;
DO
IF Natify[buffer[bptr+1]] # 84 THEN {
out.PutF[" Record length not 84\n"];
GOTO GiveUp;
};
FOR i IN [bptr+4..bptr+84) DO
buffer[i] ← LOOPHOLE[EBCDICTables.EtoA[LOOPHOLE[buffer[i], EBCDICTables.Byte]], CHAR];
ENDLOOP;
FOR i DECREASING IN [bptr+4..bptr+84) DO
IF LOOPHOLE[buffer[i], CHAR]#' THEN {
lineLength ← i;
EXIT;
};
REPEAT
FINISHED => lineLength ← 0;
ENDLOOP;
IF lineLength>0 THEN outfs.PutBlock[buffer, bptr+4, lineLength+1];
outfs.PutChar['\n];
bptr ← bptr + 84;
IF bptr>=lengthRead THEN EXIT;
ENDLOOP;
ENDLOOP;
GOTO GiveUp;
EXITS
GiveUp => {
IF infs#NIL THEN infs.Close[];
IF outfs#NIL THEN outfs.Close[];
};
};
};
GetWord: PROC [h: IOStream.Handle] RETURNS [NAT] = {
x: NAT ← LOOPHOLE[h.GetChar[], NAT];
x ← x*256;
x ← x+LOOPHOLE[h.GetChar[], NAT];
RETURN[x];
};
Natify: PROC [c: CHAR] RETURNS [NAT] = INLINE {
RETURN[LOOPHOLE[c, NAT]];
};
Init: PROC = {
Exec.AddCommand["EtoA.~", Main];
-- the main program exits at this point
-- SimpleExec will call Main when the user invokes it
};
-- main program
Init[];
END.
2-Nov-80 18:16:04, Stewart, created