Update of /cvsroot/fink/fink/perlmod/Fink
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv10767/perlmod/Fink

Modified Files:
        CLI.pm ChangeLog 
Log Message:
CLI::capture

Index: CLI.pm
===================================================================
RCS file: /cvsroot/fink/fink/perlmod/Fink/CLI.pm,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- CLI.pm      3 Jan 2006 20:14:46 -0000       1.39
+++ CLI.pm      21 Mar 2006 19:20:53 -0000      1.40
@@ -24,6 +24,8 @@
 package Fink::CLI;
 
 use Carp;
+use Fcntl qw(:seek);
+use IO::Handle;
 
 use strict;
 use warnings;
@@ -43,7 +45,7 @@
                                          &prompt &prompt_boolean 
&prompt_selection
                                          &print_optionlist
                                          &get_term_width &should_skip_prompt
-                                         &word_wrap);
+                                         &word_wrap &capture);
 }
 our @EXPORT_OK;
 
@@ -653,6 +655,83 @@
        return $width;
 }
 
+=item capture
+
+  my $return = capture { BLOCK }, \$out, \$err;
+
+Executes BLOCK, but intercepts STDOUT and STDERR, putting them into the
+arguments $out and $err. The return value is simply the BLOCK's return value.
+
+If $out and $err point to the same scalar, STDOUT and STDERR will have their
+outputs merged.
+
+=cut
+
+# my $saved = _fh_save \*FH;
+sub _fh_save {
+       my ($fh, $scalar) = @_;
+       die "Argument must be a scalar ref"
+               unless ref($scalar) && ref($scalar) eq 'SCALAR';
+       open my $save, '>&', $fh or die "Can't save filehandle: $!";
+       close $fh or die "Can't temporarily close filehandle: $!";
+       return $save;
+}
+
+# _fh_restore \*FH, $save, \$read_into;  Last arg optional
+sub _fh_restore {
+       my ($fh, $save, $into) = @_;
+       if (defined $into) {
+               $fh->flush or die "Can't flush: $!";
+               seek $fh, 0, SEEK_SET or die "Can't seek: $!";
+               $$into = join('', <$fh>);
+               die "Can't read filehandle: $!" if $fh->error;
+       }
+       close $fh or die "Can't close filehandle: $!";
+       
+       # It appears perl ignores more permissive modes for STD*, so '+>&' is ok
+       open $fh, '+>&', $save or die "Can't reopen filehandle: $!";
+       close $save or die "Can't close saved filehandle: $!";
+}      
+
+sub capture (&@) {
+       my ($code, $out, $err, @toomany) = @_;
+       die "Too many arguments!" if @toomany;
+       my ($die, $ret, $setupok);
+       my $array = wantarray;
+       
+       # Setup the filehandles
+       my ($savout, $saverr);
+       if (defined $out) {
+               $savout = _fh_save(*STDOUT{IO}, $out); # ok to die
+               open STDOUT, '+>', undef or die "Can't reopen STDOUT: $!";
+       }
+       eval { # cleanup stdout if error within this block
+               if (defined $err) {
+                       $saverr = _fh_save(*STDERR{IO}, $err);
+                       if ($out eq $err) {
+                               open STDERR, '>&', STDOUT or die "Can't merge 
STDERR: $!";
+                       } else {
+                               open STDERR, '+>', undef or die "Can't reopen 
STDERR: $!";
+                       }
+               }
+               $setupok = 1; # Now ok to save output
+               
+               # Run!
+               eval { $ret = $array ? [ &$code() ] : scalar(&$code()) };
+               $die ||= $@;
+               
+               # Tear down
+               _fh_restore(*STDERR{IO}, $saverr, $setupok && $out eq $err ? () 
: $err)
+                       if defined $saverr;
+       };
+       $die ||= $@;
+       _fh_restore(*STDOUT{IO}, $savout, $setupok ? $out : ()) if defined 
$savout;
+       
+       # Finish up
+       die $die if $die;
+       return $array ? @$ret : $ret;
+}
+
 =back
 
 =cut

Index: ChangeLog
===================================================================
RCS file: /cvsroot/fink/fink/perlmod/Fink/ChangeLog,v
retrieving revision 1.1279
retrieving revision 1.1280
diff -u -d -r1.1279 -r1.1280
--- ChangeLog   21 Mar 2006 06:30:14 -0000      1.1279
+++ ChangeLog   21 Mar 2006 19:20:53 -0000      1.1280
@@ -1,4 +1,8 @@
-2006-03-21  Daniel Macks  <[EMAIL PROTECTED]>
+2006-03-20  Dave Vasilevsky  <[EMAIL PROTECTED]>
+
+       * CLI.pm: New function &capture, to hijack STDOUT and STDERR.
+
+2006-03-21  Dave Vasilevsky  <[EMAIL PROTECTED]>
 
        * FinkVersion.pm.in: Collapse copy/pasted code into a loop.
 



-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
Fink-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/fink-commits

Reply via email to