
(* mutable collection of flags and string constants 

   Typically, you use this by writing at the top of each
   structure which needs to refer to myflag.

   val myflag = Params.flag false NONE "myflag" 

   or, if you want this parameter to be settable from the command line,

   val myflag = Params.flag false (SOME ("-myflag", 
                                         "Turns on my flag.")) "myflag"

   Now you can test the flag during the execution of your program:

   if !myflag then ...
              else ...

   (of course, !myflag means to dereference the ref cell, not logical
   not.)

*)

signature PARAMS =
sig

  (* flag default commandline-spec name

     adds a new flag to the collection (or retrieves
     a pre-existing one with that name) and returns
     a reference to its value (initialized to the default).

     If commandline-spec is SOME(s1, s2) then specifying
     s1 on the command line sets the flag to the opposite
     of its default. s2 is used as help text in the usage message.
  *)
  val flag : bool -> (string * string) option -> string -> bool ref

  (* param default commandline-name name

     similar as above, but for string parameters.
     
     If commandline-spec is SOME(s1, s2) then specifying
     s1 new-value sets the param to new-value.
  *)
  val param : string -> (string * string) option -> string -> string ref

  (* get a reference to the flag or parameter, if it exists *)
  val getflag : string -> bool ref option
  val getparam : string -> string ref option

  (* returns usage information as a string, listing all public
     flags/parameters and their documentation string *)

  val usage : unit -> string

  exception BadOption of string

  (* process the command line, setting flags and parameters.
     returns strings which aren't flags or parameters.
   
     raises BadOption "-s needs a parameter" if given a parameter
     -s as the last argument (but no corresponding value).
   *)
  val docommandline : unit -> string list

end
