1 | # ---------------------------------------------------------------------- |
---|
2 | # COMPONENT: exec - simple way to exec with streaming output |
---|
3 | # |
---|
4 | # This utility makes it easy to exec another tool and get streaming |
---|
5 | # output from stdout and stderr. Any stderr messages are specially |
---|
6 | # encoded with the =RAPPTURE-ERROR=> tag, so they show up in red |
---|
7 | # in the execution output. |
---|
8 | # ====================================================================== |
---|
9 | # AUTHOR: Michael McLennan, Purdue University |
---|
10 | # Copyright (c) 2004-2005 |
---|
11 | # Purdue Research Foundation, West Lafayette, IN |
---|
12 | # ====================================================================== |
---|
13 | package require BLT |
---|
14 | |
---|
15 | namespace eval Rappture { # forward declaration } |
---|
16 | |
---|
17 | # ---------------------------------------------------------------------- |
---|
18 | # USAGE: exec <arg> <arg>... |
---|
19 | # |
---|
20 | # This utility acts like the standard Tcl "exec" command, but it also |
---|
21 | # streams stdout and stderr messages while the command is executing, |
---|
22 | # instead of waiting till the end. Any error messages are prefixed |
---|
23 | # with the special =RAPPTURE-ERROR=> tag, so they are recognized as |
---|
24 | # errors within Rappture. |
---|
25 | # ---------------------------------------------------------------------- |
---|
26 | proc Rappture::exec {args} { |
---|
27 | variable execout |
---|
28 | |
---|
29 | set execout "" |
---|
30 | eval blt::bgexec control \ |
---|
31 | -onoutput {{::Rappture::_exec_out stdout}} \ |
---|
32 | -onerror {{::Rappture::_exec_out stderr}} \ |
---|
33 | $args |
---|
34 | |
---|
35 | return $execout |
---|
36 | } |
---|
37 | |
---|
38 | # ---------------------------------------------------------------------- |
---|
39 | # USAGE: _exec_out <channel> <message> |
---|
40 | # |
---|
41 | # Called automatically whenever output comes in from the Rappture::exec |
---|
42 | # utility. Streams the output to stdout and adds it to the "execout" |
---|
43 | # variable, so it can be returned as one large string at the end of |
---|
44 | # the exec. |
---|
45 | # ---------------------------------------------------------------------- |
---|
46 | proc Rappture::_exec_out {channel message} { |
---|
47 | variable execout |
---|
48 | |
---|
49 | # |
---|
50 | # If this message is being written to the stderr channel, then |
---|
51 | # add the =RAPPTURE-ERROR=> prefix to each line. |
---|
52 | # |
---|
53 | if {$channel == "stderr"} { |
---|
54 | set newmesg "" |
---|
55 | if {[string length $execout] > 0 |
---|
56 | && [string index $execout end] != "\n"} { |
---|
57 | set newmesg "\n" |
---|
58 | } |
---|
59 | foreach line [split $message \n] { |
---|
60 | append newmesg "=RAPPTURE-ERROR=>$line\n" |
---|
61 | } |
---|
62 | set message [string trimright $newmesg \n] |
---|
63 | } |
---|
64 | |
---|
65 | puts -nonewline $message |
---|
66 | append execout $message |
---|
67 | } |
---|