1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
(* Wasm_of_ocaml compiler
* http://www.ocsigen.org/js_of_ocaml/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, with linking exception;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*)
open Cmdliner
open Js_of_ocaml_compiler.Stdlib
open Wasm_of_ocaml_compiler
let () = Sys.catch_break true
type variables =
{ enable : string list
; disable : string list
; set : (string * string) list
}
type options =
{ input_file : string option
; output_file : string option
; variables : variables
}
let variable_options =
let enable =
let doc = "Set preprocessor variable $(docv) to true." in
let arg =
Arg.(value & opt_all (list string) [] & info [ "enable" ] ~docv:"VAR" ~doc)
in
Term.(const List.flatten $ arg)
in
let disable =
let doc = "Set preprocessor variable $(docv) to false." in
let arg =
Arg.(value & opt_all (list string) [] & info [ "disable" ] ~docv:"VAR" ~doc)
in
Term.(const List.flatten $ arg)
in
let set =
let doc = "Set preprocessor variable $(i,VAR) to value $(i,VALUE)." in
let arg =
Arg.(
value
& opt_all (list (pair ~sep:'=' string string)) []
& info [ "set" ] ~docv:"VAR=VALUE" ~doc)
in
Term.(const List.flatten $ arg)
in
let build_t enable disable set = { enable; disable; set } in
Term.(const build_t $ enable $ disable $ set)
let options =
let input_file =
let doc =
"Use the Wasm text file $(docv) as input (default to the standard input)."
in
Arg.(value & pos 0 (some string) None & info [] ~docv:"INPUT_FILE" ~doc)
in
let output_file =
let doc = "Specify the output file $(docv) (default to the standard output)." in
Arg.(value & opt (some string) None & info [ "o" ] ~docv:"OUTPUT_FILE" ~doc)
in
let build_t input_file output_file variables =
`Ok { input_file; output_file; variables }
in
let t = Term.(const build_t $ input_file $ output_file $ variable_options) in
Term.ret t
let set_variables { enable; disable; set } =
List.map ~f:(fun nm -> nm, Wat_preprocess.Bool true) enable
@ List.map ~f:(fun nm -> nm, Wat_preprocess.Bool false) disable
@ List.map ~f:(fun (nm, v) -> nm, Wat_preprocess.String v) set
let preprocess { input_file; output_file; variables } =
let with_input f =
match input_file with
| None -> f stdin
| Some file ->
let ch = open_in_text file in
let res = f ch in
close_in ch;
res
in
let with_output f =
match output_file with
| Some "-" | None -> f stdout
| Some file -> Filename.gen_file file f
in
let contents = with_input In_channel.input_all in
let res =
Wat_preprocess.f
~filename:(Option.value ~default:"-" input_file)
~contents
~variables:(set_variables variables)
in
with_output (fun ch -> output_string ch res)
let term = Cmdliner.Term.(const preprocess $ options)
let info =
Info.make
~name:"preprocess"
~doc:"Wasm text file preprocessor"
~description:"$(b,wasmoo_util pp) is a Wasm text file preprocessor."
let command = Cmdliner.Cmd.v info term
(* Adapted from
https://github.com/ocaml/opam/blob/fbbe93c3f67034da62d28c8666ec6b05e0a9b17c/s
rc/client/opamArg.ml#L759 *)
let alias_command ?orig_name cmd term name =
let orig =
match orig_name with
| Some s -> s
| None -> Cmd.name cmd
in
let doc = Printf.sprintf "An alias for $(b,%s)." orig in
let man =
[ `S "DESCRIPTION"
; `P (Printf.sprintf "$(mname)$(b, %s) is an alias for $(mname)$(b, %s)." name orig)
; `P (Printf.sprintf "See $(mname)$(b, %s --help) for details." orig)
]
in
Cmd.v (Cmd.info name ~docs:"COMMAND ALIASES" ~doc ~man) term
let command_alias = alias_command ~orig_name:"preprocess" command term "pp"
|