-- 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