(***************************************************************************)
(*                                                                         *)
(*									   *)
(*                       IMPLEMENTATION MODULE CmdLin			   *)
(*                                                                         *)
(*                     Modula-2 Utility Library Module			   *)
(*                                                                         *)
(*                                for the				   *)
(*                                                                         *)
(*                     Modula-2 System for Z80 / CP/M 			   *)
(*                                                                         *)
(*                                   by					   *)
(*                                                                         *)
(*                        Hochstrasser Computing AG			   *)
(*                           Leonhardshalde 21				   *)
(*                              8001 Zuerich				   *)
(*                              Switzerland				   *)
(*                                                                         *)
(*                                                                         *)
(*                                                                         *)
(* created	Oct - 29 - 1984 pwh                                        *)
(* updated	Jan -  8 - 1985 pwh                                        *)
(*		May - 28 - 1985 pwh -- bugs of OA version fixed; shortened *)
(*		Jul -  2 - 1985 pwh -- ReadLn instead of ReadString        *)
(***************************************************************************)
IMPLEMENTATION MODULE CmdLin;

  FROM SYSTEM IMPORT
	ADR;

  FROM Strings IMPORT
	STRING,
	Assign, Concat, Delete, Pos, Length;

  FROM Moves IMPORT
	MoveLeft, Fill;

  FROM Terminal IMPORT
	Write, WriteLn, WriteString, ReadLn;

  FROM ASCII IMPORT
	nul;


  TYPE 
    CPMCmdLine = RECORD
                   length: CHAR;
                   text	 : STRING;
                 END;

    ShortFCB = RECORD
                 drive	  : CHAR;
                 name	  : ARRAY [0..7] OF CHAR;
                 extension: ARRAY [0..2] OF CHAR;
               END;
                  
  VAR
    i, n, l: CARDINAL;
    used: BOOLEAN;

(*--------------------------------------------------------------*)
(* PROCEDURE ReadCommandLine -- read command line into comLin.  *)
(* Correctness is checked. comLin cannot be empty on return	*)
(* from this procedure.				        	*)
(*--------------------------------------------------------------*)
  PROCEDURE ReadCommandLine(VAR comLin: ARRAY OF CHAR);
  VAR 
    commandLine[80H]: CPMCmdLine;
    fcb        [5CH]: ShortFCB;
    expString       : STRING;
    comCh, expCh    : CHAR;

  PROCEDURE AppendToExpected(newPart: ARRAY OF CHAR);
  BEGIN
    Concat(expString,newPart,expString);
    n := Pos(' ',expString);
    IF n <= HIGH(expString) THEN 
      Delete(expString,n,HIGH(expString) + 1 - n);
    END;
  END AppendToExpected;


  PROCEDURE SkipBlanks;
  BEGIN
    WHILE comLin[0] = ' ' DO Delete(comLin,0,1); END;
  END SkipBlanks;


  BEGIN (* ReadCommandLine *)
    IF NOT used THEN		(* get it first time *)
      used := TRUE;
      Assign(commandLine.text,comLin);
      expString := '';		(* this clears whole string -> 0C *)
      IF fcb.drive > nul THEN	(* construct expected command line *)
        expString[0] := CHR(ORD(fcb.drive) + ORD('@'));
        expString[1] := ':'; 
        expString[2] := 0C;
      END;
      AppendToExpected(fcb.name);
      AppendToExpected('.');
      IF fcb.extension[0] # ' ' THEN
        AppendToExpected(fcb.extension);
      END;

      SkipBlanks;
      i := 0;
      n := 0;
      LOOP
	expCh := expString[n];
	comCh := comLin[i];
        IF (n = Length(expString)) OR
           (expCh = '.') & (comCh # '.') THEN 
	  i := 0; 
	  EXIT;
	END;

        IF comCh # expCh THEN
	  Delete(comLin,0,i);
          SkipBlanks;
          EXIT;
        END;

        n := n + 1;
	i := i + 1;
      END;

      IF Length(comLin) = 0 THEN   (* commandline empty *)
	ReadCommandLine(comLin);
      END;
    ELSE
      REPEAT
        WriteLn; Write('*'); ReadLn(comLin);
        SkipBlanks;
      UNTIL Length(comLin) # 0;
    END;
    i := Length(comLin);
    Fill(ADR(comLin[i]),HIGH(comLin)+1-i, 0C);
  END ReadCommandLine;

BEGIN
  used := FALSE;
END CmdLin.
