Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file CLIArgExt.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394(******************************************************************************)(* OASIS: architecture for building OCaml libraries and applications *)(* *)(* Copyright (C) 2011-2016, Sylvain Le Gall *)(* Copyright (C) 2008-2011, OCamlCore SARL *)(* *)(* This library 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; either version 2.1 of the License, or (at *)(* your option) any later version, with the OCaml static compilation *)(* exception. *)(* *)(* This library 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 file COPYING for more *)(* details. *)(* *)(* You should have received a copy of the GNU Lesser General Public License *)(* along with this library; if not, write to the Free Software Foundation, *)(* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *)(******************************************************************************)(** Parsing of command line arguments
*)openOASISGettextopenOASISMessageopenCLISubCommandopenOASISUtilsopenFormatopenFormatExttypehelp_extent=|NoSubCommand|SubCommandofstring|AllSubCommandtypehelp_style=|Markdown|Outputletusage_msg=Printf.sprintf(f_"\
OASIS v%s (C) 2009-2014 OCamlCore SARL, Sylvain Le Gall
oasis [global-options*] subcommand [subcommand-options*]
Environment variables:
OASIS_PAGER: pager to use to display long textual output.
Global command line options:")(OASISVersion.string_of_versionOASISConf.version_full)letfspecs=OASISContext.fspecsletpp_print_help~ctxthexthstyfmt()=(* Print with a precise length *)letpp_print_justifiedszfmtstr=letpadding=String.make(sz-String.lengthstr)' 'inpp_print_stringfmt(str^padding)in(* Print definition for the output style *)letpp_print_output_defszfmt(term,def)=pp_print_stringfmt" ";pp_print_justifiedszfmtterm;pp_print_stringfmt" ";pp_open_boxfmt0;pp_print_string_spacedfmtdef;pp_close_boxfmt();pp_print_newlinefmt()inletpp_print_specsspec_helpfmtspecs=lethelp_specs=List.rev_append(List.rev_map(fun(cli,t,hlp)->letarg,hlp=matchOASISString.nsplithlp' 'with|hd::tl->hd,(String.concat" "tl)|[]->"",""inletarg=matchtwith|Arg.Symbol(lst,_)->"{"^(String.concat"|"lst)^"}"|_->arginletterm=ifarg<>""thencli^" "^argelsecliinterm,hlp)specs)(ifspec_helpthen["-help|--help",s_"Display this list of options"]else[])inletsz=List.fold_left(funacc(s,_)->max(String.lengths)acc)0help_specsinletpp_print_specfmt(term,hlp)=matchhstywith|Markdown->pp_print_deffmt("`"^term^"`")[pp_print_string_spaced,hlp]|Output->pp_print_output_defszfmt(term,hlp)inpp_print_listpp_print_spec""fmthelp_specs;ifhsty=Outputthenpp_print_newlinefmt()inletpp_print_scmdsfmt()=letscmds=List.rev_map(funscmd->scmd.scmd_name,`Builtinscmd)(CLISubCommand.list_builtin~deprecated:false())inletplugin_scmds=ifnotctxt.OASISContext.ignore_pluginsthenList.rev_map(funplugin->plugin.PluginLoader.name,`Pluginplugin)(CLISubCommand.list_plugin~deprecated:false())else[]inletall_scmds=List.sort(fun(nm1,_)(nm2,_)->String.comparenm1nm2)(List.rev_appendscmdsplugin_scmds)inletsz=(* Compute max size of the name. *)List.fold_left(funsz(nm,c)->maxsz(String.lengthnm))0all_scmdsinletplugin_synopsisplg=matchplg.PluginLoader.synopsiswith|Somee->e|None->"No synopsis"inletplugin_markdown_dataplg=letlst=matchplg.PluginLoader.versionwith|Somev->["Version: "^v]|None->[]in(plugin_synopsisplg)::("Findlib: "^plg.PluginLoader.findlib_name)::lstinletplugin_output_dataplg=letfindlib_name=plg.PluginLoader.findlib_nameinletsynopsis=plugin_synopsisplginmatchplg.PluginLoader.versionwith|Somever_str->Printf.sprintf"%s (%s v%s)"synopsisfindlib_namever_str|None->Printf.sprintf"%s (%s)"synopsisfindlib_nameinpp_print_parafmt(s_"Available subcommands:");List.iter(fun(name,e)->matchhsty,ewith|Markdown,`Builtinscmd->pp_print_deffmt("`"^name^"`")[pp_print_string_spaced,scmd.scmd_synopsis]|Markdown,`Pluginplg->pp_print_deffmt("`"^name^"`")(List.map(funs->pp_print_string_spaced,s)(plugin_markdown_dataplg))|Output,`Builtinscmd->pp_print_output_defszfmt(name,scmd.scmd_synopsis)|Output,`Pluginplg->pp_print_output_defszfmt(name,plugin_output_dataplg))all_scmds;ifhsty=Outputthenpp_print_newlinefmt()inletpp_print_scmdfmt~global_options?originscmd=let(scmd_specs,_),_=scmd.scmd_run()inifnotscmd.scmd_deprecatedthenpp_print_titlefmt2(Printf.sprintf(f_"Subcommand %s")scmd.scmd_name)elsepp_print_titlefmt2(Printf.sprintf(f_"Subcommand %s (deprecated)")scmd.scmd_name);beginmatchoriginwith|Some(`Pluginplg)->fprintffmt"@[<v>__Version__: %s<br/>@,__Findlib__: %s<br/>@]"(matchplg.PluginLoader.versionwith|Somever_str->ver_str|None->"undefined")plg.PluginLoader.findlib_name;|Some`Builtin|None->()end;pp_print_stringfmtscmd.scmd_help;pp_print_endblock~check_last_char:scmd.scmd_helpfmt();fprintffmt(f_"Usage: oasis [global-options*] %s %s")scmd.scmd_name(s_scmd.scmd_usage);pp_print_endblockfmt();ifglobal_optionsthenbeginpp_print_parafmt(s_"Global options: ");pp_print_specstruefmt(fst(fspecs()))end;ifscmd_specs<>[]thenbeginpp_print_parafmt(s_"Options: ");pp_print_specsfalsefmtscmd_specsendin(* Write general introduction. *)beginmatchhextwith|NoSubCommand|AllSubCommand->beginpp_print_stringfmtusage_msg;pp_print_endblockfmt();pp_print_stringfmtCLIData.main_mkd;pp_print_endblock~check_last_char:CLIData.main_mkdfmt();pp_print_specstruefmt(fst(fspecs()));pp_print_scmdsfmt();end|SubCommand_->()end;(* Write body, focusing on specific command selected. *)beginmatchhextwith|NoSubCommand->()|SubCommandnm->pp_print_scmdfmt~global_options:true(CLISubCommand.findnm)|AllSubCommand->letscmds=List.rev_map(funscmd->scmd,`Builtin)(CLISubCommand.list_builtin~deprecated:false())inletplugin_scmds=ifnotctxt.OASISContext.ignore_pluginsthenList.rev_map(funplugin->CLISubCommand.findplugin.PluginLoader.name,`Pluginplugin)(CLISubCommand.list_plugin~deprecated:false())else[]inList.iter(fun(scmd,origin)->pp_print_scmdfmt~global_options:false~originscmd)(List.sort(fun(scmd1,_)(scmd2,_)->String.comparescmd1.scmd_namescmd2.scmd_name)(List.rev_appendplugin_scmdsscmds))endletparse_and_run()=letpos=ref0in(* Common args. *)letctxt_specs,ctxt_gen=fspecs()in(* Choose a command. *)letscmd=refNoneinletscmd_args=ref[||]inletset_scmds=scmd:=Some(CLISubCommand.finds);(* Get the rest of arguments *)scmd_args:=Array.subSys.argv!pos((Array.lengthSys.argv)-!pos);(* Skip arguments *)pos:=!pos+Array.length!scmd_argsinlethandle_errorexchext=letget_badstr=matchOASISString.split_newline~do_trim:falsestrwith|fst::_->fst|[]->s_"Unknown error on the command line"inmatchexcwith|Arg.Badtxt->pp_print_help~ctxt:(ctxt_gen())hextOutputerr_formatter();prerr_newline();prerr_endline(get_badtxt);exit2|Arg.Helptxt->pp_print_help~ctxt:(ctxt_gen())hextOutputstd_formatter();exit0|e->raiseein(* Parse global options and set scmd *)let()=tryArg.parse_argv~current:posSys.argv(Arg.alignctxt_specs)set_scmdusage_msgwithe->handle_erroreNoSubCommandin(* Parse subcommand options *)letscmd=match!scmdwith|Somescmd->scmd|None->failwith(s_"No subcommand defined, call 'oasis help' for help")inlet(scmd_specs,scmd_anon),main=scmd.scmd_run()inlet()=tryArg.parse_argv~current:(ref0)!scmd_args(Arg.alignscmd_specs)scmd_anon(Printf.sprintf(f_"Subcommand %s options:\n")scmd.scmd_name)withe->handle_errore(SubCommandscmd.scmd_name)inletctxt=ctxt_gen()inifscmd.scmd_deprecatedthenwarning~ctxt"Subcommand %s is deprecated."scmd.scmd_name;main~ctxt