{$LINESIZE:130,$TITLE:'Command line access routine and interpretter'}
{$SYMTAB-}
{$DEBUG-}

{$INCLUDE:'FILKQQ.INC',$LIST-}
{$LIST+}
{$INCLUDE:'FILUQQ.INC',$LIST-}
{$LIST+}

MODULE COMMANDLINE [public];

USES FILUQQ,FILKQQ;

function GetNextArg(var SwitchType,Numeric:boolean;var SwitchChar:char;
			var StringArg:lstring;var NumericArg:integer):boolean[public];
			{ returns next argument from command line }
			{ returns true if there was an argument }
			{ arguments are fields separated by spaces or a slash (/) }
{			SwitchType      true if argument begins with a slash
			Numeric         true if argument is an integer
			SwitchChar      char following / for switch type args
								 (SwitchChar is folded to upper case)
			StringArg       contains the ASCII argument (not the /)
			NumericArg      contains the value of arg, if applicable

			double quotes ("...") must be used to enclose an arg 
				containing a space or slash (/). 
}

const
   fix = ord('a') - ord('A');

var
	Length[static]          : integer;			{ length of command line }
	CmdLine[static]         : Lstring(128);
	CmdLinePointer[static]  : integer;	{ pointer into command line }
	FirstCall [static] : boolean;
	CMLC : char;		{ CmdLine[CmdLinePointer] }
	InQuote : boolean;		{ true when inside a quoted string "" }

value
	FirstCall := true;		{ set false after first call }

begin
	if FirstCall then begin { get command line }
		Eval  (PPMUQQ (0,ADR NULL,CmdLine));	 {get cmd line from DOS}
		concat(CmdLine,' ');			{ add a blank to stop scanner at end }
		Length := ord(CmdLine.len);
		FirstCall := false;
		CmdLinePointer := 1;
	end;

	if CmdLinePointer < Length	then { get next argument } begin
		GetNextArg := true;
															{ see if switch type }
		if CmdLine[CmdLinePointer] = '/' then begin
			SwitchType := true;
			CmdLinePointer := CmdLinePointer + 1;
			SwitchChar := CmdLine[CmdLinePointer];
			if (SwitchChar >= 'a') and (SwitchChar <= 'z') then 
				SwitchChar := chr(ord(SwitchChar)-fix); { make upper case }
			CmdLinePointer := CmdLinePointer + 1	{ point after switch char }
		end else SwitchType := false;
															{ move arg. to string }
		InQuote := false;
		StringArg.len := 0;
		CMLC := CmdLine[CmdLinePointer];
		while  (CmdLinePointer < Length)  and
			( ( (CMLC <> '/') and (CMLC <> ' ') ) or InQuote)  do
			{ move and count } begin 
			if CMLC = '"' then InQuote := not Inquote
			else concat(StringArg,CMLC);
			
			CmdLinePointer := CmdLinePointer + 1;
			CMLC := CmdLine[CmdLinePointer];
		end;
															{ convert to number }
		Numeric := decode(StringArg,NumericArg);

						{ leave CmdLinePointer pointing at start of next arg }
	while (Cmdline[CmdLinePointer] = ' ') and (CmdLinePointer < Length) do
		CmdLinePointer := CmdLinePointer + 1; { move to start of next arg. }

	end {get next arg} else {no more args}	GetNextArg := false;

end;   {GetNextArg}
			

END.   { commandline }
