{ This function provides sophisticated command line argument parsing.
  One often wants a program to be able to take arguments from the command
  line, yet at the same time provide prompts if they are not specified.
  Arguments are assumed to be delimited by spaces, tabs, or slashes.  A slash
  delimits a special argument, a switch.  Only non-positional switches are
  implemented.	A positional switch is a switch that affects only part of the
  command, i.e.
    dir file1/date file2
  meaning to add information about the date of file1, but not file2.
  Nonpositional switches, as implemented here, always affect the entire
  command.  So in this case, date information would be displayed for both
  files.

  To request a non-switch parameter, a call to the function is made with the
  boolean argument Switch set to false.  The function takes the first string
  parameter off the command line.  If there are none, it looks at the value
  of the Prompt argument.  If the prompt is specified, it prints it and reads
  in a line.  This line may contain more than one argument: the user can
  anticipate future prompts, or add switches.  The first argument on this line
  is returned.	If there are no string arguments on the read line, the value
  of the Default parameter is examined.  If it is empty, or contains a string,
  that string is returned.  But if it contains the string '/', the prompt/read
  is repeated.	This is for critical parameters.

  When a switch is requested, by setting the Switch parameter to true, the
  first switch in the buffer is returned.  This is a string whose leading
  character is a slash, i.e. '/date' in the earlier example.  If there are
  none, an empty string is returned.  The Prompt and Default arguments have no
  meaning when requesting a switch.

  The example program at the end of the file needs two file names: an input
  name which must be specified, and an output name that defaults to the input
  name with the extension '.OUT'.  It also checks for any switches specified.

  This system is modeled after the command line syntax of VAX/VMS, with the
  omission of positional parameters, and some of the more esoteric things like
  quoted arguments containing spaces.  Parsing of switches is left largely up
  to the user program.

  Comments are welcomed (also in the sense that if you'd like to add comments
  to my code, have fun)!

  -  Bela Lubkin
 }

Type
  BigString=String[127];

Function CommandLineArgument(Prompt, Default: BigString;
			     Switch:Boolean): BigString;
  Const
    Buffered: Boolean=False;
    CLBuffer: BigString='';
    Delim: Set Of Char=[^I,' ','/'];

  Var
    CommandLine: BigString Absolute CSeg:$0080;  { For MS-DOS  }
(*  CommandLine: BigString Absolute DSeg:$0080;  { For CP/M-86 }  *)
(*  CommandLine: BigString Absolute $0080;	 { For CP/M-80 }  *)
    CLA, CLBufferTemp: BigString;
    Posn,PosnA: Integer;
    Found: Boolean;

  Begin
    If Not Buffered Then CLBuffer:=CommandLine;
    Buffered:=True;
    Posn:=1;
    Found:=False;
    While Not Found Do
     Begin
      CLA:='';
      While (Posn<=Length(CLBuffer)) And (CLBuffer[Posn] In Delim) Do
	Posn:=Posn+1;
      PosnA:=Posn;
      If (Posn<>1) And (Posn<=Length(CLBuffer)) Then
	If CLBuffer[Posn-1]='/' Then
	 Begin
	  CLA:='/';
	  PosnA:=PosnA-1;
	 End;
      While (Posn<=Length(CLBuffer)) And (Not (CLBuffer[Posn] In Delim)) Do
       Begin
	CLA:=CLA+CLBuffer[Posn];
	Posn:=Posn+1;
       End;
      Found:=(Switch Xor (CLA[1]<>'/')) Or (CLA='');
     End;
    Delete(CLBuffer,PosnA,Posn-PosnA);
    If (CLA='') And Not Switch Then
     Begin
      Found:=False;
      While Not Found Do
       Begin
	If Prompt<>'' Then
	 Begin
	  Write(Prompt);
	  Flush(Output);						{009}
	  If EoF(Input) Then Halt;					{013}
	  ReadLn(CLBufferTemp);
	  If CtrlCOccurred Then Halt;					{012}
	  CLBuffer:=CLBufferTemp+CLBuffer;
	  CLA:=CommandLineArgument('','',False);
	 End;
	If CLA='' Then CLA:=Default;
	Found:=CLA<>'/';
       End;
     End;
    CommandLineArgument:=CLA;
  End;

{ Example program.  To enable, delete the next line.  }
(*

Var
  InName,OutName,Temp: BigString;

Begin
  InName:=CommandLineArgument('Input file name: ','/',False);
  Temp:=InName;
  If Pos('.',Temp)<>0 Then Delete(Temp,Pos('.',Temp),255);
  OutName:=CommandLineArgument('Output file name: ',Temp+'.OUT',False);
  WriteLn('Input file name = "',InName,'"');
  WriteLn('Output file name = "',OutName,'"');
  Temp:=' ';
  While Temp<>'' Do
   Begin
    Temp:=CommandLineArgument('','',True);
    WriteLn('Switch = "',Temp,'"');
   End;
End.
(**)
