(*-------------------------------------------------------------------------
:Program.       MUGcut13
: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% are correct)
: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 MUGcut13;

FROM Arguments  IMPORT GetArg         , NumArgs        ;
FROM Arts       IMPORT BreakPoint     , Exit           ;
                IMPORT Break          ;
                IMPORT d : DosD       ;
FROM DosL       IMPORT Close          , Open           , Read           ,
                       Seek           , Write          ;
FROM InOut      IMPORT WriteString    ;
FROM SYSTEM     IMPORT ADR            , ASSEMBLE       , BYTE           ,
                       CAST           ;

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

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

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

VAR
      actual         : LONGINT;
      argCount       : INTEGER;
      destFile       : d.FileHandlePtr;
      destFileName   : String;
      len            : INTEGER;
      myBuffer       : ARRAY [1 .. 62] OF BYTE;
      posBegin       : LONGINT;
      posDum         : LONGINT;
      posEnd         : LONGINT;
      sourceFile     : d.FileHandlePtr;
      sourceFileName : String;


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

VAR ch : CHAR;

BEGIN
  REPEAT
    posBegin := Seek (sourceFile, posBegin, d.beginning);
    REPEAT
      actual := Read (sourceFile, ADR (ch), 1);
    UNTIL ch = "M";
    posBegin := Seek (sourceFile, 0, d.current);
    actual   := Read (sourceFile, ADR (myBuffer), 62);
  UNTIL (CAST (SHORTCARD, myBuffer [62]) = charM);
  posBegin := Seek (sourceFile, posBegin - 1, d.beginning);
END SearchM;


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

BEGIN
  REPEAT
    actual := Read (sourceFile, ADR (myBuffer), 62);
    IF (CAST (SHORTCARD, myBuffer [1]) = charM) THEN
      actual := Write (destFile, ADR (myBuffer), actual);
    END;
  UNTIL (CAST (SHORTCARD, 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 ch : CHAR;

BEGIN
  (*
  ** When  it  is  the first file, we search for "begin" and copy all lines
  ** starting with "M"
  *)
  IF (argCount = 1) THEN
    SearchM();
    posEnd := Seek (sourceFile, 0, d.beginning);
    WHILE (posEnd < posBegin - 1) DO
      actual := Read  (sourceFile, ADR (ch), 1);
      actual := Write (  destFile, ADR (ch), 1);
      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 > 0) DO
      actual := Write (  destFile, ADR (myBuffer), actual);
      actual := Read  (sourceFile, ADR (myBuffer), 62    );
    END;
  (*
  ** Just a file in between. Copy all lines starting with "M"
  *)
  ELSE
    SearchM();
    CopyM();
  END;
END Parse;

(*=======================================================================*
 *                                M a i n                                *
 *=======================================================================*)
BEGIN
  Break.InstallException;
  GetArg (1, sourceFileName, len);
  IF (NumArgs() < 3) OR (sourceFileName[0] = '?') THEN
    WriteString (version + "\n");
    WriteString ("  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
      WriteString ("Could not open file '");
      WriteString (destFileName);
      WriteString ("'!\n");
      Exit (d.fail);
    END;
    WHILE argCount < NumArgs () DO
      GetArg (argCount, sourceFileName, len);
      sourceFile := Open (ADR (sourceFileName), d.readOnly);
      IF (sourceFile = NIL) THEN
        WriteString ("Could not open file '");
        WriteString (sourceFileName);
        WriteString ("'!\n");
        Exit (d.fail);
      END;
      posBegin := Seek (sourceFile, 0, d.beginning);
      Parse();
      INC (argCount);
    END;
  END;
CLOSE
  Close (sourceFile);
  Close (  destFile);
END MUGcut13.
