/** * This module contains strategies for handling command line options * and simple serialization/unserialization of ATerms. These strategies * are particularly useful for writing command line tools in Stratego * that may be connected into pipelines by the standard Unix piping * mechanism. * */ module util/config/options imports system/io/char system/io/term system/io/dir system/io/file system/io/process util/config/parse-options util/config/common util/config/verbose util/config/keep util/time util/log term/string strategies /** * Wraps a strategy into a strategy handling options and io of terms. * * @param strategy to apply on the input term */ io-wrap(s) = io-wrap(fail, s) /** * Wraps a strategy into a strategy handling options and io of terms. * * @param extra options besides the default io-options * use fail if you have no additional options. * @param strategy to apply on the input term */ io-wrap(extra-opts, s) = io-wrap(extra-opts, system-usage, system-about, s) /** * * @param extra options besides the default io-options. * use fail if you have no additional options. * * @param strategy to apply on the input term */ io-wrap(extra-opts, usage, about, s) = option-wrap(extra-opts <+ io-options, usage, about, id, io(s)) output-wrap(s) = output-wrap(fail, s) output-wrap(extra-opts, s) = option-wrap(extra-opts <+ output-options, output(s)) input-wrap(s) = input-wrap(fail, s) input-wrap(extra-opts, s) = option-wrap(extra-opts <+ input-options, input(s)) strategies /** * Wraps a strategy into a strategy that handles io options. * * Reads a term from the file specified by the -i option (or stdin). * Writes to a file specified by the -o option (or stdout). * * @param strategy to apply on the input term */ io(s) = input(output(s)) /** * Wraps a strategy into a strategy that handles output options. * * Writes to a file specified by the -o option (or stdout). */ output(s) = s ; !(<<get-config> "-o" <+ !stdout()>, <id>) ; ( where(<get-config> "-b") < WriteToBinaryFile + WriteToTextFile ) /** * Wraps a strategy into a strategy that handles input options. * * Reads a term from the file specified by the -i option (or stdin). */ input(s) = ( <get-config> "-i" <+ !stdin() ) ; ReadFromFile ; s /** * Stream based wrappers */ strategies /** * Wraps a strategy into a strategy that handles input and output options. * The strategy arguments is applied to a tuple of streams: the input and the output stream. * * @param (Stream, Stream) -> _ */ io-stream-wrap(s) = io-stream-wrap(fail, s) io-stream-wrap(extra-opts, s) = io-stream-wrap(extra-opts, system-usage, system-about, s) io-stream-wrap(extra-opts, usage, about, s) = option-wrap(extra-opts <+ io-options, usage, about, id, io-stream(s)) io-stream(s) = let open = open-stream <+ ?(<id>, _); perror; <exit> 1 in fin := <get-config < <open> (<id>, "r") + stdin-stream> "-i" ; fout := <get-config < <open> (<id>, "w") + stdout-stream> "-o" ; if <s> (fin, fout) then try(<fclose> fout); try(<fclose> fin) ; report-success else prim("SSL_stacktrace_get_all_frame_names") => trace ; try(<fclose> fout); try(<fclose> fin) ; try(<get-config> "-o"; remove-file) ; <report-failure> trace end end strategies option-wrap(opts, s) = option-wrap(opts, system-usage, id, s) option-wrap(opts, usage, announce, s) = option-wrap(opts, usage, system-about, announce, s) /** * Read options, display help, report success or failure, call strategy */ option-wrap(opts, usage, about, announce, s) = parse-options(opts, usage, about) ; announce ; (s; report-success <+ prim("SSL_stacktrace_get_all_frame_names") ; report-failure) strategies /** * Handles all common options for a transformation tool. */ io-options = input-option + aterm-output-option + general-options input-options = input-option + general-options output-options = aterm-output-option + general-options general-options = verbose-option + keep-option + statistics-option + aterm-lib-options /** * Allow all flag starting with -at-* (these are ATerm library flags) */ aterm-lib-options = Option( string-starts-with(|"-at-") , id , fail ) /** * Option specifcation for level of keeping intermediate results. */ keep-option = ArgOption("-k" + "--keep" , where(<set-config> ("--keep", <string-to-int>)) , !"-k i | --keep i Keep intermediates (default 0)" ) /** * Option specifcation for level of statistics printing */ statistics-option = ArgOption("--statistics" , where(<set-config> ("--statistics", <string-to-int>)) , !"--statistics i Print statistics (default 0 = none)" ) /** * Option specifications for reading input. * * Defines -i. */ input-option = ArgOption("-i" + "--input" , where(<set-config> ("-i",<id>)) , !"-i f|--input f Read input from f" ) /** * Option specifications for writing output. * * Defines -o. */ output-option = ArgOption("-o" + "--output" , where(<set-config> ("-o",<id>)) , !"-o f|--output f Write output to f" ) /** * Option specifications for ATerm output. * * Defines -b option for binary output. */ aterm-output-option = output-option + Option("-b" , where(<set-config> ("-b",())) , !"-b Write binary output" ) /** * Option specifications for verbosity. * * Defines -S, --silent, --verbose and -s. */ verbose-option = Option("-S"+"--silent" , where(<set-verbosity> 0) , !"-S|--silent Silent execution (same as --verbose 0)" ) + ArgOption("--verbose" , where(verbose-to-int; set-verbosity) , !"--verbose i Verbosity level i (default 1) ( i as a number or as a verbosity descriptor: emergency, alert, critical, error, warning, notice, info, debug, vomit )" ) strategies verbose-to-int = string-to-level <+ string-to-int need-help(u) = <get-config> "--help" ; u if-not-silent(s) = test(verbosity => 0) <+ s report-success = report-run-time ; <exit> 0 /** * Report the failure of this program. Must be applied to a list of * strings obtained by calling the SSL_stacktrace_get_all_frame_names * directly after the failure occurred (without any intervening calls * to any rules/strategies). * * @type List(String) -> _ * * @param exit * The exit strategy to use, e.g., xtc-exit. */ report-failure = report-failure(exit) report-failure(exit) = ?stacktrace ; report-run-time ; <fprintnl> (stderr(), [<log-src> (), ": rewriting failed, trace:"]) ; <reverse ; map(<fprintnl> (stderr(), ["\t", <id>]))> stacktrace ; <exit> 1 /** * Report the failure of this program, without showing a stack trace. * * @see report-failure * @see fatal-err(|msg) */ report-failure-no-trace = report-failure-no-trace(exit) report-failure-no-trace(exit) = <fprintnl> (stderr(), [<log-src> (), ": rewriting failed"]) ; <exit> 1 whoami = <get-config> "program"