[svn:mod_parrot] r566 - in mod_parrot/trunk: languages/perl6/lib/ModPerl6 lib/ModParrot lib/ModParrot/HLL src/pmc t/response/TestAPI

[email protected] Thu, 1 Jan 2009 13:19:37 -0800 (PST)
Newsgroups perl.cvs.mod_parrot
Message-ID <[email protected]>
Author: jhorwitz
Date: Thu Jan  1 13:19:36 2009
New Revision: 566

Added:
   mod_parrot/trunk/t/response/TestAPI/modparrothandle.pir
Modified:
   mod_parrot/trunk/languages/perl6/lib/ModPerl6/Registry.pm
   mod_parrot/trunk/lib/ModParrot/HLL/perl6.pir
   mod_parrot/trunk/lib/ModParrot/Interpreter.pir
   mod_parrot/trunk/src/pmc/modparrothandle.pmc

Log:
add 'stdout' and 'stdin' methods to ModParrotHandle to tie Parrot I/O to Apache I/O


Modified: mod_parrot/trunk/languages/perl6/lib/ModPerl6/Registry.pm
==============================================================================
--- mod_parrot/trunk/languages/perl6/lib/ModPerl6/Registry.pm	(original)
+++ mod_parrot/trunk/languages/perl6/lib/ModPerl6/Registry.pm	Thu Jan  1 13:19:36 2009
@@ -4,6 +4,7 @@
 
 # for perl 6 functionality not yet supported by rakudo
 use ModPerl6::Fudge;
+use Apache::Const;
 
 module ModPerl6::Registry;
 
@@ -53,15 +54,6 @@
     return $out;
 }
 
-
-# XXX kludge alert!  temporary workaround until we can subclass FileHandle
-sub registry_print($r, $do_headers, *@args)
-{
-    for @args -> $arg {
-        $r.puts($do_headers ?? parse_headers($r, $arg) !! $arg);
-    }
-}
-
 sub handler($r)
 {
     my %cfg = ModParrot::Apache::Module::get_config("modparrot_perl6_module");
@@ -98,22 +90,26 @@
     ## XXX requires server_rec
     #ModPerl6::Fudge::setenv('SERVER_PORT', $server_port);
 
-    # XXX kludge alert!  temporary workaround until we can subclass FileHandle
-    our &CORE::say := &*say;
-    our &CORE::print := &*print;
     my $do_headers = %dircfg<options><parseheaders>;
 
-    &*say = sub (*@args) { registry_print($r, $do_headers, |@args, "\n"); };
-    &*print = sub (*@args) { registry_print($r, $do_headers, |@args); };
-
     my $mod = %registry{$script};
-    #::($mod)::_handler();
 
+    # XXX rip this out when we have a pure-perl6 Apache::RequestRec
+    my $rr = q:PIR<
+        $P0 = find_lex "$r"
+        getattribute %r, $P0, 'r'
+    >;
+
+    # tie stdout to $r, saving the old stdout filehandle
+    my $mpi = ModParrot::Interpreter.new();
+    my $stdout = $mpi.stdout($r);
+
+    # run our code
+    #::($mod)::_handler();
     my $res = ModPerl6::Fudge::call_sub_with_namespace($mod, '_handler');
 
-    # XXX kludge alert!  temporary workaround until we can subclass FileHandle
-    &*say = &CORE::say;
-    &*print = &CORE::print;
+    # reset stdout
+    $mpi.stdout($stdout);
 
-    return 0;
+    return $Apache::Const::OK;
 }

Modified: mod_parrot/trunk/lib/ModParrot/HLL/perl6.pir
==============================================================================
--- mod_parrot/trunk/lib/ModParrot/HLL/perl6.pir	(original)
+++ mod_parrot/trunk/lib/ModParrot/HLL/perl6.pir	Thu Jan  1 13:19:36 2009
@@ -39,6 +39,8 @@
     $P0.'register'($P1)
     $P1 = get_class ['ModParrot'; 'Context']
     $P0.'register'($P1)
+    $P1 = get_class ['ModParrotHandle']
+    $P0.'register'($P1)
 .end
 
 # declare namespace AFTER loading compiler

Modified: mod_parrot/trunk/lib/ModParrot/Interpreter.pir
==============================================================================
--- mod_parrot/trunk/lib/ModParrot/Interpreter.pir	(original)
+++ mod_parrot/trunk/lib/ModParrot/Interpreter.pir	Thu Jan  1 13:19:36 2009
@@ -140,55 +140,104 @@
     .return($S0)
 .end
 
-=item C<capture_stdout(INT flag)>
+=item C<PMC stdout(PMC handle :optional)>
 
 =over 4
 
-WARNING: This method is temporary and WILL go away.  Enables capture of
-standard output to an internal string buffer.
+With no arguments, returns the current stdout.
+
+If C<handle> is provided, this method will assign it to stdout.  If the
+C<handle> is a ModParrot;Apache;RequestRec object, a new ModParrotHandle will
+be created and tied to stdout.  FileHandles and ModParrotHandles will be
+assigned directly to stdout.  After assignment, returns the previous stdout.
 
 =back
 
 =cut
 
-.sub capture_stdout :method
-    .param int enabled
-    .local pmc pio
-
-    pio = getstdout
-    unless enabled goto disable_capture
-    push pio, "string"
+.sub stdout :method
+    .param pmc handle :optional
+    .param int got_handle :opt_flag
+    .local pmc stdout, fh
+
+    stdout = getstdout
+    unless got_handle goto done
+    $I0 = isa handle, ['ModParrot';'Apache';'RequestRec']
+    if $I0 goto have_r
+    $I0 = isa handle, ['FileHandle']
+    if $I0 goto have_filehandle
+    $I0 = isa handle, ['ModParrotHandle']
+    if $I0 goto have_modparrothandle
+    $P0 = new 'Exception'
+    $P0 = 'Cannot set stdout to an incompatible PMC'
+    throw $P0
+
+  have_r:
+    fh = new 'ModParrotHandle'
+    fh.'open'(handle, 'w')
+    fh.'setstdout'(fh)
+    goto done
+
+  have_filehandle:
+    fh = new 'ModParrotHandle'
+    fh.'setstdout'(handle)
     goto done
-  disable_capture:
-    $S0 = pop pio
+
+  have_modparrothandle:
+    handle.'setstdout'()
+
   done:
-.end
+    .return(stdout)
+.end 
 
-=item C<STRING dump_stdout(INT flag)>
+=item C<PMC stdin(PMC handle :optional)>
 
 =over 4
 
-WARNING: This method is temporary and WILL go away.  Returns the contents of
-the stdout string buffer created by C<capture_stdout()>.
+With no arguments, returns the current stdin.
+
+If C<handle> is provided, this method will assign it to stdin.  If the
+C<handle> is a ModParrot;Apache;RequestRec object, a new ModParrotHandle will
+be created and tied to stdin.  FileHandles and ModParrotHandles will be
+assigned directly to stdin.  After assignment, returns the previous stdin.
 
 =back
 
 =cut
 
-.sub dump_stdout :method
-    .local pmc pio
-    .local string buf, data
-
-    pio = getstdout
-    data = ""
-
-  read_loop:
-    buf = read pio, 4096
-    data .= buf
-    $I0 = length buf
-    if $I0 == 4096 goto read_loop
+.sub stdin :method
+    .param pmc handle :optional
+    .param int got_handle :opt_flag
+    .local pmc stdin, fh
+
+    stdin = getstdin
+    unless got_handle goto done
+    $I0 = isa handle, ['ModParrot';'Apache';'RequestRec']
+    if $I0 goto have_r
+    $I0 = isa handle, ['FileHandle']
+    if $I0 goto have_filehandle
+    $I0 = isa handle, ['ModParrotHandle']
+    if $I0 goto have_modparrothandle
+    $P0 = new 'Exception'
+    $P0 = 'Cannot set stdin to an incompatible PMC'
+    throw $P0
+
+  have_r:
+    fh = new 'ModParrotHandle'
+    fh.'open'(handle, 'r')
+    fh.'setstdin'(fh)
+    goto done
+
+  have_filehandle:
+    fh = new 'ModParrotHandle'
+    fh.'setstdin'(handle)
+    goto done
+
+  have_modparrothandle:
+    handle.'setstdin'()
 
-  .return(data)
+  done:
+    .return(stdin)
 .end
 
 =back

Modified: mod_parrot/trunk/src/pmc/modparrothandle.pmc
==============================================================================
--- mod_parrot/trunk/src/pmc/modparrothandle.pmc	(original)
+++ mod_parrot/trunk/src/pmc/modparrothandle.pmc	Thu Jan  1 13:19:36 2009
@@ -531,6 +531,40 @@
 
 /*
 
+=item C<METHOD setstdout(PMC *fh :optional)>
+
+TEMPORARY method to set this filehandle as stdout.  Will be removed in favor
+of a non-experimental setstdout or identical functionality in Parrot.
+
+Sets the provided filehandle as stdout, or SELF if no arguments are provided.
+
+=cut
+
+*/
+
+    METHOD setstdout(PMC *fh :optional, INTVAL got_fh :opt_flag) {
+        _PIO_STDOUT(INTERP) = got_fh ? fh : SELF;
+    }
+
+/*
+
+=item C<METHOD setstdin(PMC *fh :optional)>
+
+TEMPORARY method to set a filehandle as stdin.  Will be removed in favor
+of a non-experimental setstdin or identical functionality in Parrot.
+
+Sets the provided filehandle as stdin, or SELF if no arguments are provided.
+
+=cut
+
+*/
+
+    METHOD setstdin(PMC *fh :optional, INTVAL got_fh :opt_flag) {
+         _PIO_STDIN(INTERP) = got_fh ? fh : SELF;
+    }
+
+/*
+
 =back
 
 =cut

Added: mod_parrot/trunk/t/response/TestAPI/modparrothandle.pir
==============================================================================
--- (empty file)
+++ mod_parrot/trunk/t/response/TestAPI/modparrothandle.pir	Thu Jan  1 13:19:36 2009
@@ -0,0 +1,80 @@
+# $Id$
+
+.namespace [ 'TestAPI::modparrothandle' ]
+
+.sub handler
+    .param pmc r
+    .local pmc fh, old, ap_const
+
+    ap_const = get_root_global [ 'ModParrot'; 'Apache'; 'Constants' ], 'table'
+
+    r.'puts'("1..11\n")
+
+  START_1:
+    fh = new 'ModParrotHandle'
+    $S0 = typeof fh
+    if $S0 == "ModParrotHandle" goto OK_1
+    r.'puts'("not ")
+  OK_1:
+    r.'puts'("ok 1 - object\n")
+
+  START_2:
+    push_eh NOT_OK_2
+    fh.'open'(r, "w")
+    pop_eh
+    goto OK_2
+  NOT_OK_2:
+    r.'puts'("not ")
+  OK_2:
+    r.'puts'("ok 2 - open\n") 
+
+  START_3:
+    fh.'puts'("ok 3 - puts\n") 
+
+  START_4:
+    old = getstdout
+    fh.'setstdout'()
+    say "ok 4 - setstdout (ModParrotHandle)"
+
+  START_5:
+    fh.'setstdout'(old)
+    print "not "
+    r.'puts'("ok 5 - setstdout (reset to old stdout)\n")
+
+  START_6:
+    old = getstdin
+    fh.'setstdin'()
+    r.'puts'("ok 6 - setstdin (ModParrotHandle)\n")
+
+  START_7:
+    push_eh NOT_OK_7
+    fh.'close'()
+    pop_eh
+    goto OK_7
+  NOT_OK_7:
+    r.'puts'("not ")
+  OK_7:
+    r.'puts'("ok 7 - close\n")
+
+  START_8:
+    fh.'open'(r, "r")
+    $S0 = fh.'read'(1024)
+    if $S0 == "" goto OK_8
+    r.'puts'("not ")
+  OK_8:
+    r.'puts'("ok 8 - read\n")
+
+  START_9:
+    r.'puts'("not ok 9 - readline # TODO\n")
+
+  START_10:
+    r.'puts'("not ok 10 - readall # TODO\n")
+
+  START_11:
+    fh.'setstdin'(old)
+    r.'puts'("ok 11 - setstdin (reset to old stdin)\n")
+
+    $I0 = ap_const['OK']
+    .return($I0)
+.end
+