117 lines
4.4 KiB
Standard ML
117 lines
4.4 KiB
Standard ML
signature EsisOptions =
|
|
sig
|
|
val O_SILENT : bool ref
|
|
val O_ERROR_DEVICE : TextIO.outstream ref
|
|
val O_ERROR_LINEWIDTH : int ref
|
|
val O_OUTPUT_FILE : string ref
|
|
val O_NON_DIRECT : UniChar.Char ref
|
|
|
|
val setEsisDefaults : unit -> unit
|
|
val setEsisOptions : Options.Option list * (string -> unit)
|
|
-> bool * bool * string option * string option
|
|
|
|
val esisUsage : Options.Usage
|
|
end
|
|
|
|
structure EsisOptions : EsisOptions =
|
|
struct
|
|
open Options
|
|
|
|
val O_SILENT = ref false
|
|
val O_ERROR_DEVICE = ref TextIO.stdErr
|
|
val O_ERROR_LINEWIDTH = ref 80
|
|
val O_OUTPUT_FILE = ref "-"
|
|
val O_NON_DIRECT = ref (0wx100 : UniChar.Char)
|
|
|
|
fun setEsisDefaults () =
|
|
let
|
|
val _ = O_SILENT := false
|
|
val _ = O_ERROR_DEVICE := TextIO.stdErr
|
|
val _ = O_OUTPUT_FILE := "-"
|
|
val _ = O_NON_DIRECT := 0wx100
|
|
in ()
|
|
end
|
|
|
|
val esisUsage =
|
|
[U_ITEM(["-o <file>","--output=<file>"],"Write output to file (stdout)"),
|
|
U_ITEM(["-s","--silent"],"Suppress reporting of errors and warnings"),
|
|
U_ITEM(["-e <file>","--error-output=<file>"],"Redirect errors to file (stderr)"),
|
|
U_SEP,
|
|
U_ITEM(["-7","--ascii"],"Produce output in ASCII (7 bit) encoding"),
|
|
U_ITEM(["-8","--latin1"],"Produce output in LATIN1 (8 bit) encoding (default)"),
|
|
U_SEP,
|
|
U_ITEM(["--version"],"Print the version number and exit"),
|
|
U_ITEM(["-?","--help"],"Print this text and exit"),
|
|
U_ITEM(["--"],"Do not recognize remaining arguments as options")
|
|
]
|
|
|
|
fun setEsisOptions (opts,optError) =
|
|
let
|
|
fun onlyOne what = "at most one "^what^" may be specified"
|
|
fun unknown pre opt = String.concat ["unknown option ",pre,opt]
|
|
fun hasNoArg pre key = String.concat ["option ",pre,key," expects no argument"]
|
|
fun mustHave pre key = String.concat ["option ",pre,key," must have an argument"]
|
|
|
|
fun check_noarg(key,valOpt) =
|
|
if isSome valOpt then optError (hasNoArg "--" key) else ()
|
|
|
|
fun do_long (pars as (v,h,e,f)) (key,valOpt) =
|
|
case key
|
|
of "help" => (v,true,e,f) before check_noarg(key,valOpt)
|
|
| "version" => (true,h,e,f) before check_noarg(key,valOpt)
|
|
| "silent" => pars before O_SILENT := true before check_noarg(key,valOpt)
|
|
| "ascii" => pars before O_NON_DIRECT := 0wx80 before check_noarg(key,valOpt)
|
|
| "latin1" => pars before O_NON_DIRECT := 0wx100 before check_noarg(key,valOpt)
|
|
| "output" =>
|
|
(case valOpt
|
|
of NONE => pars before optError (mustHave "--" key)
|
|
| SOME s => pars before O_OUTPUT_FILE := s)
|
|
| "error-output" =>
|
|
(case valOpt
|
|
of NONE => pars before optError (mustHave "--" key)
|
|
| SOME s => (v,h,SOME s,f))
|
|
| _ => pars before optError(unknown "--" key)
|
|
|
|
fun do_short (pars as (v,h,e,f)) (cs,opts) =
|
|
case cs
|
|
of nil => doit pars opts
|
|
| [#"o"] => (case opts
|
|
of OPT_STRING s::opts1 => (O_OUTPUT_FILE := s;
|
|
doit pars opts1)
|
|
| _ => (optError (mustHave "-" "o"); doit pars opts))
|
|
| [#"e"] => (case opts
|
|
of OPT_STRING s::opts1 => doit (v,h,SOME s,f) opts1
|
|
| _ => (optError (mustHave "-" "e"); doit pars opts))
|
|
| cs => doit (foldr
|
|
(fn (c,pars)
|
|
=> case c
|
|
of #"s" => pars before O_SILENT := true
|
|
| #"7" => pars before O_NON_DIRECT := 0wx80
|
|
| #"8" => pars before O_NON_DIRECT := 0wx100
|
|
| #"o" => pars before optError (mustHave "-" "o")
|
|
| #"e" => pars before optError (mustHave "-" "e")
|
|
| #"?" => (v,true,e,f)
|
|
| c => pars before
|
|
optError(unknown "-" (String.implode [c])))
|
|
pars cs) opts
|
|
|
|
and doit pars nil = pars
|
|
| doit (pars as (v,h,e,f)) (opt::opts) =
|
|
case opt
|
|
of OPT_LONG(key,valOpt) => doit (do_long pars (key,valOpt)) opts
|
|
| OPT_SHORT cs => do_short pars (cs,opts)
|
|
| OPT_STRING s => if isSome f
|
|
then let val _ = optError(onlyOne "input file")
|
|
in doit pars opts
|
|
end
|
|
else doit (v,h,e,SOME s) opts
|
|
| OPT_NOOPT => doit pars opts
|
|
| OPT_NEG cs => let val _ = if null cs then ()
|
|
else app (fn c => optError
|
|
(unknown "-n" (String.implode[c]))) cs
|
|
in doit pars opts
|
|
end
|
|
in doit (false,false,NONE,NONE) opts
|
|
end
|
|
end
|