Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file lv6MainArgs.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629(* Time-stamp: <modified the 13/07/2021 (at 11:22) by Erwan Jahier> *)(*
Le manager d'argument adapté de celui de lutin, plus joli
N.B. solution un peu batarde : les options sont stockées, comme avant, dans Global,
du coup, le fait de rendre un type "t" est une koketerie !
*)openArglettool_name=Lv6version.toolletusage_msg="usage: "^tool_name^" [options] <file> | "^tool_name^" -help"typeenum_mode=AsInt|AsBool(* finishme *)|AsConst|AsEnumtypeio_transmit_mode=Stack|Heap|HeapStacktypeschedul_mode=Simple|Sort|Reordertypet={mutableopts:(string*Arg.spec*string)list;(* classical Arg option tab used by Arg.parse *)mutableuser_man:(string*stringlist)list;(* ad hoc tab for pretty prtting usage *)mutablehidden_man:(string*stringlist)list;(* ad hoc tab for pretty prtting usage *)mutabledev_man:(string*stringlist)list;(* ad hoc tab for pretty prtting usage *)mutableothers:stringlist;mutablemargin:int;mutableoutfile:string;mutableinfiles:stringlist;mutablemain_node:string;mutablecompile_all_items:bool;mutablerun_unit_test:bool;mutableprint_interface:bool;mutableinline_iterator:bool;mutableexpand_nodes:bool;mutableexpand_node_call:stringlist;mutableexpand_arrays:bool;mutableexpand_io_type:bool;mutableoptim_ite:bool;mutableoc:out_channel;mutabletlex:bool;mutableexec:bool;mutablegen_c:bool;mutablerif:bool;mutablegen_ocaml:bool;mutablelaunch_cc:bool;mutablelaunch_exec:bool;mutableprecision:intoption;mutablegen_lic:bool;mutablekeep_aliases:bool;}(* Those are really too boring to be functionnal (used in all over the places) *)typeglobal_opt={mutabledir:string;mutablegen_c_inline_predef:bool;mutablelv4:bool;mutablekcg:bool;mutableec:bool;mutablegen_autotest:bool;mutableexpand_enums:enum_mode;mutableone_op_per_equation:bool;mutablewhen_on_ident:bool;mutableno_when_not:bool;mutableno_prefix:bool;mutablenonreg_test:bool;mutablecurrent_file:string;mutableline_num:int;mutableline_start_pos:int;mutablesoc2c_no_switch:bool;mutablesoc2c_one_file:bool;mutablesoc2c_inline_loops:bool;mutablesoc2c_global_ctx:bool;mutablesoc2c_dro:bool;mutablegen_wcet:bool;mutableio_transmit_mode:io_transmit_mode;mutableschedul_mode:schedul_mode;}let(global_opt:global_opt)={dir="";gen_c_inline_predef=true;gen_autotest=false;lv4=false;kcg=false;ec=false;one_op_per_equation=true;when_on_ident=false;no_when_not=false;no_prefix=false;nonreg_test=false;line_num=1;line_start_pos=0;current_file="";expand_enums=AsEnum;soc2c_no_switch=false;soc2c_one_file=true;soc2c_inline_loops=false;soc2c_global_ctx=false;soc2c_dro=false;gen_wcet=false;io_transmit_mode=Stack;schedul_mode=Simple;}let(make_opt:unit->t)=fun()->{opts=[];user_man=[];hidden_man=[];dev_man=[];others=[];margin=12;outfile="";infiles=[];main_node="";compile_all_items=true;run_unit_test=false;print_interface=false;inline_iterator=false;expand_nodes=false;expand_node_call=[];expand_arrays=false;expand_io_type=false;optim_ite=false;oc=stdout;(* the output channel *)tlex=false;exec=false;gen_c=false;rif=false;gen_ocaml=false;precision=None;launch_cc=false;launch_exec=false;keep_aliases=false;gen_lic=false;}(** flag 'paranoid' utile pour forcer (via le mecanisme Lv6Verbose.exe)
des vérifs de trucs douteux ...
*)letparanoid=(Lv6Verbose.get_flag"paranoid")let(lexbuf_of_file_name:string->Lexing.lexbuf)=funfile->letinchannel=Lv6Verbose.print_string~level:1(* ("Opening file " ^ (Filename.concat (Sys.getcwd ()) file) ^ "\n"); *)("Opening file "^(file)^"\n");open_infileinglobal_opt.line_num<-1;global_opt.line_start_pos<-0;global_opt.current_file<-file;Lexing.from_channelinchannel(* all unrecognized options are accumulated *)let(add_other:t->string->unit)=funopts->opt.others<-s::opt.othersletpspecosopt(c,ml)=(let(m1,oth)=matchmlwith|h::t->(h,t)|_->("",[])inlett2=String.makeopt.margin' 'inletcl=String.lengthcinlett1=if(cl<opt.margin)thenString.make(opt.margin-cl)' 'else"\n"^t2inPrintf.fprintfos"%s%s%s"ct1m1;List.iter(functionx->Printf.fprintfos"\n%s%s"t2x)oth;Printf.fprintfos"\n";)letusageosopt=(letl=List.revopt.user_maninPrintf.fprintfos"%s\n\n"usage_msg;List.iter(pspecosopt)l)lethelpopt()=(usagestdoutopt;exit0)letfull_usageosopt=(Printf.fprintfos"%s\n"usage_msg;(* let l = List.rev opt.user_man in *)(* List.iter (pspec os opt) l; *)letl=List.rev(opt.hidden_man)inList.iter(pspecosopt)l)letdev_usageosopt=(Printf.fprintfos"%s\n"usage_msg;letl=List.rev(opt.dev_man)inList.iter(pspecosopt)l)letfull_helpopt()=(full_usagestdoutopt;exit0)letdev_helpopt()=(dev_usagestdoutopt;exit0)letunexpectedsopt=(prerr_string("Error: unexpected argument \""^s^"\"");prerr_newline();usagestderropt;exit1)letfile_notfoundfopt=(prerr_string("Error: file not found: \""^f^"\"");prerr_newline();usagestderropt;exit1)typedoc_level=Basic|Advanced|Devlet(mkopt:t->stringlist->?doc_level:doc_level->?arg:string->Arg.spec->stringlist->unit)=funoptol?(doc_level=Basic)?(arg="")seml->lettretoo=opt.opts<-(o,se,"")::opt.optsinList.itertretool;letcol1=(String.concat", "ol)^arginmatchdoc_levelwith|Basic->opt.user_man<-(col1,ml)::opt.user_man|Advanced->opt.hidden_man<-(col1,ml)::opt.hidden_man|Dev->opt.dev_man<-(col1,ml)::opt.dev_man(*
let tabs = String.make (col - (String.length o) - (String.length arg)) ' ' in
(* (o, se, arg^tabs^m) *)
(o, se, arg^"\n "^m)
*)(* utils *)letset_v4_optionsopt=global_opt.lv4<-true;(matchglobal_opt.expand_enumswith|AsEnum->global_opt.expand_enums<-AsConst;(* only override the default *)|AsInt|AsConst|AsBool->());opt.inline_iterator<-true;global_opt.when_on_ident<-true;opt.expand_arrays<-true;opt.expand_nodes<-true(* because expand_arrays is true *)letset_ec_optionsopt=(matchglobal_opt.expand_enumswith|AsEnum->global_opt.expand_enums<-AsConst;(* only override the default *)|AsInt|AsConst|AsBool->());set_v4_optionsopt;global_opt.ec<-true;global_opt.no_when_not<-true;global_opt.no_prefix<-true;opt.expand_nodes<-true;()letset_c_optionsopt=opt.gen_c<-true;(matchglobal_opt.expand_enumswith|AsEnum->global_opt.expand_enums<-AsInt;(* only override the default in this case *)|AsInt|AsConst|AsBool->());()(*** USER OPTIONS TAB **)letmkoptab(opt:t):unit=(mkoptopt["-n";"-node"]~arg:" <string>"(Arg.String(functionx->opt.main_node<-x;opt.compile_all_items<-false))["Set the main node (all items are compiled if unset)"];mkoptopt["-o";"--output-file"]~arg:" <string>"(Arg.String(functionx->opt.outfile<-x))["Set the output file name"];mkoptopt["-dir";"--directory"]~arg:" <string>"(Arg.String(functionx->ifnot(Sys.file_existsx)thenUnix.mkdirx0o744;global_opt.dir<-x))["Set the directory into which output files are generated"];mkoptopt["-exec"](Arg.Unit(fun_->opt.exec<-true;global_opt.expand_enums<-AsInt;))["Interpret the program using RIF conventions for I/O (force -eei)"];mkoptopt["-2c";"--to-c"](Arg.Unit(fun_->set_c_optionsopt))["Generate C code"];mkoptopt~doc_level:Basic["-cc";"--compile-generated-c"](Arg.Unit(fun()->set_c_optionsopt;opt.launch_cc<-true))["Try to compile the generated C files (force -2c)"];mkoptopt["-2c-exec";"--to-c-execute"](Arg.Unit(fun()->set_c_optionsopt;opt.launch_cc<-true;opt.launch_exec<-true))["Try to execute the generated C files (force -cc)."];mkoptopt["-rif"](Arg.Unit(function()->opt.rif<-true))["Behave as a rif input file (meaningless without -exec)"];mkoptopt~doc_level:Advanced["-ocaml"](Arg.Unit(function()->opt.gen_ocaml<-true))["Generate ocaml glue code that makes it possible to call the lv6 interpreter ";"from ocaml with the current set of arguments (with Lv6Run.make)"];mkoptopt~doc_level:Dev["-knc";"--keep-nested-calls"](Arg.Unit(fun_->global_opt.one_op_per_equation<-false))["Keep nested calls (inhibited by -en). By default, only one node ";"per equation is generated (don't work with -exec or -2c)"];mkoptopt~doc_level:Advanced["--when-on-ident"](Arg.Unit(fun_->global_opt.when_on_ident<-true))["Invent ident names so that when only operates on idents (to be able ";"to translate enums into ec/v4)"];mkoptopt~doc_level:Advanced["--no-when-not"](Arg.Unit(fun_->global_opt.no_when_not<-true))["Remove 'when not' statements (for ec) "];mkoptopt~doc_level:Advanced["-ei";"--expand-iterators"](Arg.Unit(fun_->opt.inline_iterator<-true))["Expand array iterators (i.e., generate iterator-free code)"];mkoptopt~doc_level:Advanced["-ee";"--expand-enums"](Arg.Unit(fun_->global_opt.expand_enums<-AsConst))["Translate enums using extern types and consts"];mkoptopt~doc_level:Advanced["-eei";"--expand-enums-as-int"](Arg.Unit(fun_->global_opt.expand_enums<-AsInt))["Translate enums into integers (to be kind with data plotters)"];mkoptopt~doc_level:Dev["-eeb";"--expand-enums-as-bool"](Arg.Unit(fun_->global_opt.expand_enums<-AsBool))["Translate enums into boolean arrays (to be kind with model-checkers)"];mkoptopt~doc_level:Advanced["-esa";"--expand-structs-and-arrays"](Arg.Unit(fun_->opt.expand_arrays<-true;opt.expand_nodes<-true;opt.inline_iterator<-true))["Expand structures and arrays (force '-ei' and '-en')"];mkoptopt~doc_level:Advanced["-en";"--expand-nodes"](Arg.Unit(fun_->opt.expand_nodes<-true;opt.inline_iterator<-true(* an iterator is a kind of node *)))["Expand all node calls in the main node"];mkoptopt["-et";"--expand-io-type"](Arg.Unit(fun_->opt.expand_io_type<-true))["Expand structured types of the main node (impact the rif output only).";"Necessary to use lurette and rdbg in presence of lutin (that only ";"knows about basic the types int/bool/real)"];mkoptopt~doc_level:Advanced["-enc";"--expand-node-call"]~arg:" <string> "(Arg.String(funstr->opt.expand_node_call<-str::opt.expand_node_call))["Expand the call of the specified node (can be used for several nodes)"];mkoptopt~doc_level:Advanced["-oite";"--optimize-ite"](Arg.Unit(fun_->opt.optim_ite<-true))["Transform if/then/else into merge when possible"];mkoptopt~doc_level:Advanced["-lv4";"--lustre-v4"](Arg.Unit(fun_->set_v4_optionsopt))["deprecated: generate Lustre V4 code (force '-ei -ee -esa')"];mkoptopt~doc_level:Dev["-kcg";"--generate-scade-lustre"](Arg.Unit(fun_->(* opt.expand_arrays <- true; for problem of "#"; XXX remove me ! *)global_opt.kcg<-true))["Generate Lustre code that is compatible with the lustre of scade"];mkoptopt["-ec";"--expanded-code"](Arg.Unit(fun_->set_ec_optionsopt))["Generate ec programs (force '--expand-nodes --no-when-not --expand-enums --lustre-v4 --no-prefix')"];mkoptopt~doc_level:Advanced["-np";"--no-prefix"](Arg.Unit(fun()->global_opt.no_prefix<-true))["Do not prefix variable names by their module \n\t(beware: variable names may clash with this option)"];mkoptopt~doc_level:Advanced["-2cdil";"--to-c-dont-inline-predef"](Arg.Unit(fun_->global_opt.gen_c_inline_predef<-false))["Do not inline predef calls when generating C code"];mkoptopt~doc_level:Advanced["-2cil";"--2c-inline-loop"](Arg.Unit(fun()->global_opt.soc2c_inline_loops<-true;set_c_optionsopt))["Inline loops (that come from array iterators)"];mkoptopt~doc_level:Advanced["-2csf";"--2c-several-files"](Arg.Unit(fun()->global_opt.soc2c_one_file<-false;set_c_optionsopt))["Generate one .c and one .h file per node"];mkoptopt~doc_level:Advanced["-2cgc";"--2c-global-ctx"](Arg.Unit(fun()->global_opt.soc2c_global_ctx<-true;set_c_optionsopt))["Node context allocated as global variable (no \"new_ctx\" method)"];mkoptopt~doc_level:Advanced["-dro";"--2c-dro"](Arg.Unit(fun()->global_opt.soc2c_dro<-true;set_c_optionsopt;global_opt.io_transmit_mode<-Heap))["Generate a .dro file (for luciole)"];mkoptopt~doc_level:Advanced["-lic";"--gen-lic"](Arg.Unit(fun()->opt.gen_lic<-true))["Generate lic"];mkoptopt["-version";"--version"](Arg.Unit(function_->Printf.fprintfstdout"%s\n"Lv6version.str;exit0))["Print the current version and exit"];(* verbose *)mkoptopt["-v";"--verbose"](Arg.Unit(function_->Lv6Verbose.on()))["Set the verbose level to 1"];mkoptopt["-vl"]~arg:" <int>"(Arg.Int(functioni->Lv6Verbose.seti))["Set the verbose level"];mkoptopt["-h";"-help";"--help"](Arg.Unit(helpopt))["Display this message"];(* to show Hidden opt *)mkoptopt["-more";"--advanced-options"](* (Arg.Unit(fun _ -> opt.see_all_options <- true)) *)(Arg.Unit(full_helpopt))["Show more options"];(* to show Hidden opt *)mkoptopt~doc_level:Basic["-dev";"--dev-options"](* (Arg.Unit(fun _ -> opt.see_all_options <- true)) *)(Arg.Unit(dev_helpopt))["Show experimental/internal options"];(* HIDDEN *)(* test lexical *)mkoptopt~doc_level:Dev["-tlex";"--test-lexer"](Arg.Unit(fun()->opt.tlex<-true))["Test the lexical analysis"];(* test syntaxique
mkopt opt ~hide:true
["-tparse"]
(Arg.Unit(function _ -> opt.gen_mode <- GenLuc ; opt.test_parse <- true ; ()))
["Test the syntactic analysis"]
;
*)mkoptopt~doc_level:Advanced["-2cw7";"--2c-wcet"](Arg.Unit(fun()->set_c_optionsopt;global_opt.gen_wcet<-true;global_opt.soc2c_no_switch<-true;global_opt.soc2c_global_ctx<-true))["Generate a main file for computing the wcet (force -2c -2cgc)"];mkoptopt~doc_level:Dev["-2cs";"--2c-stack"](Arg.Unit(fun()->set_c_optionsopt;global_opt.io_transmit_mode<-Stack))["Transmit Soc I/O as params of the step functions (force -2c)"];mkoptopt~doc_level:Dev["-2ch";"--2c-heap"](Arg.Unit(fun()->set_c_optionsopt;global_opt.io_transmit_mode<-Heap))["Transmit Soc I/O via a ctx structure in the heap (force -2c)"];mkoptopt~doc_level:Dev["-2chs";"--2c-heap-and-stack"](Arg.Unit(fun()->set_c_optionsopt;global_opt.io_transmit_mode<-HeapStack))["Transmit soc memoryless I/O via the stack, and the heap otherwise (force -2c)"];mkoptopt~doc_level:Dev["--schedule-simple"](Arg.Unit(fun()->global_opt.schedul_mode<-Simple))["No re-ordering after topological sort"];mkoptopt~doc_level:Dev["--schedule-sort"](Arg.Unit(fun()->global_opt.schedul_mode<-Sort))["Sort wrt guard before after topological sort"];mkoptopt~doc_level:Dev["--schedule-reorder"](Arg.Unit(fun()->global_opt.schedul_mode<-Reorder))["Re-order Soc.gao after scheduling to increase the clock factorisation"];mkoptopt~doc_level:Advanced["-2cns";"--2c-no-switch"](Arg.Unit(fun()->global_opt.soc2c_no_switch<-true))["Use if-then-else instead of switches when generating C codes"];mkoptopt~doc_level:Dev["-interface"](Arg.Unit(fun()->opt.print_interface<-true))["Print the node interface"];mkoptopt~doc_level:Dev["--keep-aliases"](Arg.Unit(fun()->opt.keep_aliases<-true))["Do not perform aliases elimination"];mkoptopt~doc_level:Dev["-unit"](Arg.Unit(fun()->opt.run_unit_test<-true))["Run embedded unit tests"];mkoptopt~doc_level:Advanced["--precision"](Arg.Int(funi->opt.precision<-Somei))["Number of digits after ther dot used to print floats in -exec mode"];mkoptopt~doc_level:Dev["--nonreg-test"](Arg.Unit(fun()->global_opt.nonreg_test<-true))["Avoid printing full path error msgs to ease non-reg test decision"];mkoptopt~doc_level:Dev["--gen-autotest"](Arg.Unit(fun()->global_opt.gen_autotest<-true))["Generate a Lutin Stimulator and a Lustre oracle to compare the ";"result of 2 Lustre compilers"];(* misc debug flag *)mkoptopt~doc_level:Advanced["-dbg";"--debug"](Arg.Symbol(Lv6Verbose.flag_list(),funs->letf=Lv6Verbose.get_flagsinLv6Verbose.set_flagf))["<dbg_flag>";"Possible dbg_flag are: "^(String.concat", "(Lv6Verbose.flag_list()))])letfirst_lineb=(try(letf=String.indexb'\n'inString.subb0f)withNot_found->b)letcurrent=ref0;;(* La ``méthode'' principale *)letparseargv=(letopt=make_opt()inletsave_current=!currentintry(mkoptabopt;Arg.parse_argv~current:currentargvopt.opts(add_otheropt)usage_msg;(List.iter(funf->if(String.subf01="-")thenunexpectedfoptelseifnot(Sys.file_existsf)thenfile_notfoundfoptelse())opt.others);opt.infiles<-(List.revopt.others);ifopt.main_node=""&&(opt.gen_c||opt.exec||opt.gen_lic)then(Printf.fprintfstderr"No node set: use -n to set a node\n";exit2);current:=save_current;opt)with(* only 1rst line is interesting ! *)|Badmsg->Printf.fprintfstderr"%s\n"(first_linemsg);usagestderropt;exit2;|Help_msg->helpopt();)