(*-------------------------------------------------------------------------
:Program.       MUGcut20
:Contents.      extracts comments from .UUE binaries. For use with UUDecode
:Author.        Mark Rose [mug]
:Copyright.     Freely distributable copyrighted software
:Language.      Modula-2
:Translator.    M2Amiga 4.1
:History.       0.1 [mug] 17-Dec-92 First Version
:History.       0.2 [mug] 21-Dec-92 changed to "erratic" performance
:History.       0.3 [mug] 08-Jan-93 Algorithm changed (60% of .UUEs were
:History.                           processed correctly)
:History        0.4 [mug] 26-Jan-93 problems fixed using Dos-calls
:History.       1.0 [mug] 12-Feb-93 -- first public release --
:Usage.         MUGcut file1 file2 [<file3> .. <FileN>] OutFile
-------------------------------------------------------------------------*)
(*$ NilChk      := FALSE ReturnChk   := FALSE CaseChk     := FALSE *)
(*$ Volatile    := FALSE StackParms  := FALSE LargeVars   := FALSE *)
(*$ StackChk    := FALSE RangeChk    := FALSE OverflowChk := FALSE *)

MODULE MUGcut20;

FROM Arguments  IMPORT GetArg         , NumArgs        ;
FROM Arts       IMPORT Exit           ;
                IMPORT d : DosD       ;
FROM DosL       IMPORT Close          , FGets          , FPuts          ,
                       IoErr          , Open           , PrintFault     ,
                       PutStr         , Seek           ;
                IMPORT R              ;
FROM SYSTEM     IMPORT ADR            ;

(*----------------------------------------------------------------------*)

TYPE  String         = ARRAY [1 .. 80] OF CHAR;

CONST
      version        = "MUGcut 1.00 (26-Jan-93)  © Mark Rose";
      versionStr     = ADR ("$VER: " + version);
      charM          = "M";

VAR
      actual         : d.StrPtr;
      argCount       : INTEGER;
      destFile       : d.FileHandlePtr;
      destFileName   : String;
      dum            : BOOLEAN;
      len            : INTEGER;
      myBuffer       : String;
      myBufferPtr    : d.StrPtr;
      posBegin       : LONGINT;
      sourceFile     : d.FileHandlePtr;
      sourceFileName : String;


(*-----------------------------------------------------------------------*)
PROCEDURE SearchM();
(*-----------------------------------------------------------------------*)

BEGIN
  REPEAT
    REPEAT
      posBegin := Seek (sourceFile, posBegin, d.beginning);
      actual   := FGets (sourceFile, myBufferPtr, 80);
    UNTIL (myBuffer [1] = charM);
    actual     := FGets (sourceFile, myBufferPtr, 80);
  UNTIL (myBuffer [1] = charM);
  posBegin := Seek (sourceFile, posBegin, d.beginning);
END SearchM;


(*-----------------------------------------------------------------------*)
PROCEDURE CopyM();
(*-----------------------------------------------------------------------*)

BEGIN
  REPEAT
    actual := FGets (sourceFile, myBufferPtr, 80);
    IF (myBuffer [1] = charM) THEN
      dum  := FPuts (  destFile, myBufferPtr);
    END;
  UNTIL (myBuffer [1] # charM);
END CopyM;


(*-----------------------------------------------------------------------*)
PROCEDURE Parse;
(*-----------------------------------------------------------------------*
 * Look into 'sourceFile' and  search for not .UUE things.  If it is the *
 * first file check for "begin". If it is the last search for "end".  In *
 * between just look for lines starting with "M".                        *
 *-----------------------------------------------------------------------*)

VAR
    posEnd{R.A3} : LONGINT;

BEGIN
  (*
  ** If  it is the first file,  we copy lines upto begin and then all lines
  ** starting with "M"
  *)
  IF (argCount = 1) THEN
    SearchM();
    posEnd := Seek (sourceFile, 0, d.beginning);
    WHILE (posEnd < posBegin - 1) DO
      actual := FGets (sourceFile, myBufferPtr, 80);
      dum    := FPuts (  destFile, myBufferPtr);
      posEnd := Seek  (sourceFile, 0, d.current);
    END;
    CopyM();
  (*
  ** Last file: we copy lines starting with "M" until EOF
  *)
  ELSIF (argCount = NumArgs() - 1) THEN
    SearchM();
    CopyM();
    WHILE (actual # NIL) DO
      dum    := FPuts (  destFile, myBufferPtr);
      actual := FGets (sourceFile, myBufferPtr, 80);
    END;
  (*
  ** Just a file in between. Copy all lines starting with "M"
  *)
  ELSE
    SearchM();
    CopyM();
  END;
END Parse;


(*-----------------------------------------------------------------------*)
PROCEDURE MUGerror();
(*-----------------------------------------------------------------------*)

BEGIN
  dum := PrintFault (IoErr(), NIL);
  Exit (d.fail);
END MUGerror;


(*=======================================================================*
 *                                M a i n                                *
 *=======================================================================*)
BEGIN
  myBufferPtr := ADR (myBuffer);
  GetArg (1, sourceFileName, len);
  IF (NumArgs() < 3) OR (sourceFileName[0] = '?') THEN
    dum := PutStr (ADR (version));
    dum := PutStr (ADR (
          "\n  Usage: MUGcut file1 file2 [<file3> .. <FileN>] OutFile\n"));
    Exit (d.fail);
  ELSE
    argCount := 1;
    GetArg (NumArgs(), destFileName, len);
    destFile := Open (ADR (destFileName), d.newFile);
    IF (destFile = NIL) THEN
      MUGerror();
    END;
    WHILE argCount < NumArgs () DO
      GetArg (argCount, sourceFileName, len);
      sourceFile := Open (ADR (sourceFileName), d.readOnly);
      IF (sourceFile = NIL) THEN
        MUGerror();
      END;
      posBegin := Seek (sourceFile, 0, d.beginning);
      Parse();
      IF (sourceFile # NIL) THEN
        Close (sourceFile);
        sourceFile := NIL;
      END;
      INC (argCount);
    END;
  END;
CLOSE
  IF (sourceFile # NIL) THEN Close (sourceFile); sourceFile := NIL; END;
  IF (  destFile # NIL) THEN Close (  destFile);   destFile := NIL; END;
END MUGcut20.
