/** * Used for POSIX and POSIX+XSI */ module stratego/xtc/posix/Proc strategies /** * Reads a term from a file. If the given file exists, it will be * treated as an ATerm and its content will be returned, as a term. * * @type FILE -> t */ read-from : FILE(name) -> t where <file-exists; ReadFromFile> name => t strategies // XTC-COMMAND // Executing an external process // a -> String :: List(String) -> List(String) /** * Invokes the XT component given by tool. The input term is * a list of command line arguments that will be passed to the * invoked component. * * @param tool _ -> String * @type List(a) -> Int */ xtc-command(tool) = where(tool; xtc-find-warning => loc) ; log(|Debug(),<concat-strings>["Invoking tool ",<tool>," at location ",loc," with arguments: "],<id>) ; where(<call> (loc, <id>)) // Transparent transformation of terms and files by external processes /** * Invokes the XT component given by tool to transform the current term. * The tool strategy must give the name of the component to invoke. The * The current term will be serialized to the invoked component, and the * result of its execution will become the new current term. No command * line arguments are given. * * @param tool _ -> String * @type t -> u */ xtc-transform(tool) = xtc-transform(tool, ![]) /** * Invokes the XT component given by tool to transform the current term. * The tool strategy must give the name of the component to invoke. The * The current term will be serialized to the invoked component, and the * result of its execution will become the new current term. The args * parameter must return a list of arguments that will be given to the * invoked component. * * @param tool _ -> String * @type t -> u */ xtc-transform(tool, args) = (FILE(id) + stdin) < xtc-transform-file(tool, args) + xtc-transform-term(tool, args) strategies xtc-transform-file = ?(tool, args, file) /** * Transforms an existing file with an external process into a new file. * The resulting file will be created automatically, and a handle will * be returned by this strategy. The tool strategy must give the name * of the component to invoke. No arguments will be passed to the * transforming component. * * @param tool _ -> n * @type FILE(a) -> FILE(b) */ xtc-transform-file(tool) = xtc-transform-file(tool, ![]) /** * Transforms an existing file with an external process into a new file. * The resulting file will be created automatically, and a handle will * be returned by this strategy. * * The tool strategy must give the name of the component to invoke. The * args strategy must give a list of arguments to pass to the component. * * @param tool _ -> n * @param args _ -> List(arg) * @type FILE(a) -> FILE(b) */ xtc-transform-file(tool, args) : FILE(f) -> FILE(g) where <xtc-new-file> f => g ; <conc; xtc-command(tool)> (<args>, ["-i", f, "-o", g]) xtc-transform-file(tool, args) : stdin -> FILE(g) where xtc-new-file => g ; <conc; xtc-command(tool)> (<args>, ["-o", g]) /** * Transforms the current term with an external process. The current * term will be serialized and handed off to the component identified * by the tool strategy argument. The result of the component will * be returned by this strategy. * * The tool strategy must give the name of the component to invoke. The * args strategy must give a list of arguments to pass to the component. * @param tool _ -> n * @param args _ -> List(arg) * @type t -> u */ xtc-transform-term(tool, args) = write-to ; xtc-transform-file(tool, args) ; read-from /** * Transforms a file with an internal strategy s. This strategy * will open an external file, apply s to it, and write the * result back to the file. * * @param s a -> b * @type File -> File */ xtc-io-transform(s) = read-from; s; write-to /** * Transforms a file with an internal strategy s into a text file. * This strategy will open an external file (which must be an ATerm), * apply s to it, and print the result as a string back into the * file. * * @param s a -> b * @type File -> File */ xtc-io-transform-text(s) = read-from; s; print-to /** * Generates a new file using the component identified by tool. This * strategy will invoke the component given by tool with no arguments, * and write the resulting term to a new file. A handle to the new * file will be returned. No arguments will be passed on to the * invoked component (except the implicit -o). * * @param tool _ -> name * @type _ -> FILE(b) */ xtc-generate(tool) = xtc-generate(tool, ![]) /** * Generates a new file using the component identified by tool. This * strategy will invoke the component given by tool with no arguments, * and write the resulting term to a new file. A handle to the new * file will be returned. The strategy args must produce a list of * arguments which are passed to the invoked component. * * @param tool _ -> name * @type _ -> FILE(b) */ xtc-generate(tool, args) : _ -> FILE(g) where <xtc-new-file> () => g ; <conc; xtc-command(tool)> (<args>, ["-o", g]) strategies /** * Opens a file, applies the strategy s the file descriptor, * and ensures that the file descriptor is closed on return * of s, regardless of outcome. The strategy s will be * handed a file descriptor for the the FILE given to * File-as-fd. The result of s will become the result * of File-as-fd, and the file descriptor will always be * closed, also when s fails. * * @param s Int -> b * @type FILE -> b */ File-as-fd(s) = xtc-open-fd => fd ; finally(s, where(try(<xtc-close-fd> fd))) /** * Opens a file and returns a file descriptor. This strategy * can be used to open any <tt>FILE</tt>s as well as * <tt>stdin</tt>, <tt>stdout</tt> and <tt>stderr</tt>. The * file descriptor should be closed with <tt>xtc-close-fd</tt>. * * @type FILE -> Int */ xtc-open-fd = \ FILE(s) -> <open> s \ + \ stdin() -> < STDIN_FILENO> () \ + \ stdout() -> <STDOUT_FILENO> () \ + \ stderr() -> <STDERR_FILENO> () \ /** * Closes a file descriptor. This strategy can be used to close * any file opened by <tt>xtc-open-fd</tt>, and also the * standard files <tt>stdin</tt>, <tt>stdout</tt> and * <tt>stderr</tt>. * * @type FILE -> Int */ xtc-close-fd = finally( ( where(<eq> (<id>, < STDIN_FILENO> ())) + where(<eq> (<id>, <STDOUT_FILENO> ())) + where(<eq> (<id>, <STDERR_FILENO> ())) ) <+ close , !()) /** * Generates a new file name, but does not create the file on * disk. As the file is not created on disk, another process * may theoretically create it (and thus own it), thus causing * a race condition. For this reason, you may prefer to us * <tt>xtc-new-file</tt> instead. * * @type _ -> FILE */ xtc-new-file-name = obsolete(!"xtc-new-file-name; use xtc-new-file") ; new-file => f ; where(<assert(!TempFiles)> (f, ())) ; !FILE(f)