3ed303f60d
like the absence of an input filename. (This simplifies all the clients codes.) Fixed the dune file for the preprocessor. Fixed the build of PreprocMain.exe and PreprocMain.byte. Restricted preprocessing errors [Preproc.Newline_in_string] and [Preproc.Open_string] to the argument of the #include directive (instead of general strings: this is for the LIGO lexer to report the error). I removed the error [Preproc.Open_comment] as this is for the LIGO lexer to report. The preprocessor scanner [Preproc.lex] does not take a parameter [is_file:bool] now: the source file (if any) is determined from the lexing buffer. Accordingly, the field [is_file] of the state of the preprocessing lexer has been removed: the lexing buffer becomes now the reference for the input source (bug fix and interface improvement). Fixed the comments of the test contract pledge.religo. I removed the data constructor [Lexer.Stdin], as redundant with [Lexer.Channel].
125 lines
3.3 KiB
OCaml
125 lines
3.3 KiB
OCaml
(* Parsing command-line options *)
|
|
|
|
(* The type [options] gathers the command-line options. *)
|
|
|
|
type language = [`PascaLIGO | `CameLIGO | `ReasonLIGO]
|
|
|
|
let lang_to_string = function
|
|
`PascaLIGO -> "PascaLIGO"
|
|
| `CameLIGO -> "CameLIGO"
|
|
| `ReasonLIGO -> "ReasonLIGO"
|
|
|
|
module SSet = Set.Make (String)
|
|
|
|
type options = <
|
|
input : string option;
|
|
libs : string list;
|
|
verbose : SSet.t;
|
|
offsets : bool;
|
|
lang : language;
|
|
ext : string (* ".ligo", ".mligo", ".religo" *)
|
|
>
|
|
|
|
let make ~input ~libs ~lang ~offsets ~verbose ~ext : options =
|
|
object
|
|
method input = input
|
|
method libs = libs
|
|
method lang = lang
|
|
method offsets = offsets
|
|
method verbose = verbose
|
|
method ext = ext
|
|
end
|
|
|
|
(* Auxiliary functions and modules *)
|
|
|
|
let printf = Printf.printf
|
|
let sprintf = Printf.sprintf
|
|
let print = print_endline
|
|
|
|
(* Printing a string in red to standard error *)
|
|
|
|
let highlight msg = Printf.eprintf "\027[31m%s\027[0m%!" msg
|
|
|
|
(* Failure *)
|
|
|
|
let abort msg =
|
|
highlight (sprintf "Command-line error: %s\n" msg); exit 1
|
|
|
|
(* Help *)
|
|
|
|
let help lang ext () =
|
|
let file = Filename.basename Sys.argv.(0) in
|
|
printf "Usage: %s [<option> ...] [<input>%s | \"-\"]\n" file ext;
|
|
printf "where <input>%s is the %s source file (default: stdin),\n" ext lang;
|
|
print "and each <option> (if any) is one of the following:";
|
|
print " -I <paths> Inclusion paths (colon-separated)";
|
|
print " --columns Columns for source locations";
|
|
print " --verbose=<stages> preproc";
|
|
print " -h, --help This help";
|
|
exit 0
|
|
|
|
(* Specifying the command-line options a la GNU *)
|
|
|
|
let input = ref None
|
|
and libs = ref []
|
|
and columns = ref false
|
|
and verbose = ref SSet.empty
|
|
and verb_str = ref ""
|
|
|
|
let split_at_colon = Str.(split (regexp ":"))
|
|
|
|
let add_path p = libs := !libs @ split_at_colon p
|
|
|
|
let add_verbose d =
|
|
verbose := List.fold_left (fun x y -> SSet.add y x)
|
|
!verbose
|
|
(split_at_colon d)
|
|
let specs lang ext =
|
|
let lang_str = lang_to_string lang in
|
|
let open!Getopt in [
|
|
'I', nolong, None, Some add_path;
|
|
'h', "help", Some (help lang_str ext), None;
|
|
noshort, "columns", set columns true, None;
|
|
noshort, "verbose", None, Some add_verbose
|
|
]
|
|
|
|
(* Handler of anonymous arguments *)
|
|
|
|
let anonymous arg =
|
|
match !input with
|
|
None -> input := Some arg
|
|
| Some _ -> abort (sprintf "Multiple inputs")
|
|
|
|
(* Checking options and exporting them as non-mutable values *)
|
|
|
|
let check lang ext =
|
|
let libs = !libs
|
|
|
|
and offsets = not !columns
|
|
|
|
and verbose = !verbose
|
|
|
|
and input =
|
|
match !input with
|
|
None | Some "-" -> None
|
|
| Some file_path ->
|
|
if Filename.check_suffix file_path ext
|
|
then if Sys.file_exists file_path
|
|
then Some file_path
|
|
else abort "Source file not found."
|
|
else abort ("Source file lacks the extension " ^ ext ^ ".")
|
|
|
|
in make ~input ~libs ~lang ~offsets ~verbose ~ext
|
|
|
|
(* Parsing the command-line options *)
|
|
|
|
let read ~lang:(lang : language) ~ext:(ext : string) =
|
|
try
|
|
Getopt.parse_cmdline (specs lang ext) anonymous;
|
|
(verb_str :=
|
|
let apply e a =
|
|
if a = "" then e else sprintf "%s, %s" e a
|
|
in SSet.fold apply !verbose "");
|
|
check lang ext
|
|
with Getopt.Error msg -> abort msg
|