Author: jkeenan
Date: Sun Feb 11 11:11:34 2007
New Revision: 16943

Added:
   branches/buildtools/lib/Parrot/Ops2c/Utils.pm
   branches/buildtools/t/tools/ops2cutils/01-new.t
Modified:
   branches/buildtools/tools/build/ops2c.pl

Log:
1.  Created lib/Parrot/Ops2c/Utils.pm.  Within that package, created sub
new(); transferred subs _prepare_core() and _prepare_non_core() from
tools/build/ops2c.pl thereto.
2.  Having concluded refactoring most of the code within tools/build/ops2c.pl
into internal subroutines, I've begun moving that code out of the script and
into lib/Parrot/Ops2c/Utils.pm.  So far most of the initialization has been
moved into that package's new() function.  To guarantee that this transferral
is taking place safely, once I return the Utils object, I assign its keys to
the variables which will be needed in the remaining subroutines in ops2c.pl,
then test that 'make' works successfully.
3.  Created t/tools/ops2cutils/01-new.t.  Some tests in it will currently fail
because I have not yet set up a way to create prerequisite
Parrot::OpLib::core.  (This was the last bit of functionality imported into
the constructor.  Prior to doing that, all tests in 01-new.t were passing.)


Added: branches/buildtools/lib/Parrot/Ops2c/Utils.pm
==============================================================================
--- (empty file)
+++ branches/buildtools/lib/Parrot/Ops2c/Utils.pm       Sun Feb 11 11:11:34 2007
@@ -0,0 +1,153 @@
+# Copyright (C) 2004-2006, The Perl Foundation.
+# $Id: Utils.pm 16894 2007-02-04 22:54:29Z jkeenan $
+package Parrot::Ops2c::Utils;
+use strict;
+#use warnings;
+#use Cwd;
+#use Data::Dumper;
+#use File::Path ();
+#use File::Spec;
+use lib ("lib/");
+use Parrot::OpLib::core;
+use Parrot::OpsFile;
+
+sub new {
+    my ($class, $argsref) = @_;
+    unless (defined $argsref->{flag}) {
+        print STDERR "Parrot::Ops2c::Utils::new() requires reference to hash 
of command-line options: $!";
+        return;
+    }
+    my $flagref = $argsref->{flag};
+    my @argv = @{$argsref->{argv}};
+    unless (@argv) {
+        print STDERR "Parrot::Ops2c::Utils::new() requires 'trans' options: 
$!";
+        return;
+    };
+    my $class_name = shift @argv;
+    my %is_allowed = map { $_ => 1 } qw(C CGoto CGP CSwitch CPrederef);
+    unless ($is_allowed{$class_name}) {
+        print STDERR "Parrot::Ops2c::Utils::new() requires C, CGoto, CGP, 
CSwitch and/or  CPrederef: $!";
+        return;
+    };
+
+    my $trans_class = "Parrot::OpTrans::" . $class_name;
+    eval "require $trans_class";
+    my $trans   = $trans_class->new();
+    # Don't yet know how to test the following.
+    unless (defined $trans) {
+        print STDERR "Unable to construct $trans object: $!";
+        return;
+    };
+
+    my $suffix  = $trans->suffix();     # Invoked (sometimes) as ${suffix}
+
+    my $file = $flagref->{core} ? 'core.ops' : shift @argv;
+    my $base = $file;   # Invoked (sometimes) as ${base}
+    $base =~ s/\.ops$//;
+    my $base_ops_stub = $base . q{_ops} . $suffix;
+    my $base_ops_h    = $base_ops_stub . q{.h};
+    
+    my $incdir  = "include/parrot/oplib";
+    my $include = "parrot/oplib/$base_ops_h";
+    my $header  = "include/$include";
+    
+    # SOURCE is closed and reread, which confuses make -j
+    # create a temp file and rename it
+    my $source = "src/ops/$base_ops_stub.c.temp";
+    
+    if ( $base =~ m!^src/dynoplibs/! || $flagref->{dynamic} ) {
+        $source             =~ s!src/ops/!!;
+        $header             = $base_ops_h;
+        $base               =~ s!^.*[/\\]!!;
+        $include            = $base_ops_h;
+        $flagref->{dynamic} = 1;
+    }
+    
+    my $sym_export = $flagref->{dynamic} 
+        ? 'PARROT_DYNEXT_EXPORT'
+        : 'PARROT_API';
+
+    my $ops;
+    if ($flagref->{core}) {
+        $ops = _prepare_core( {
+            file        => $file,
+            flag        => $flagref,
+        } );
+    }
+    else {
+        $ops = _prepare_non_core( {
+            file        => $file,
+#            argv        => [ @ARGV ],
+            argv        => [ @argv ],
+            flag        => $flagref,
+        } );
+    }
+    
+    my %versions = (
+        major => $ops->major_version,
+        minor => $ops->minor_version,
+        patch => $ops->patch_version,
+    );
+    my $num_ops       = scalar $ops->ops;
+    my $num_entries   = $num_ops + 1;          # For trailing NULL
+
+###############################
+    $argsref->{argv} = [EMAIL PROTECTED];
+    $argsref->{trans} = $trans;
+    $argsref->{suffix} = $suffix;
+
+    $argsref->{file} = $file;
+    $argsref->{base} = $base;
+    $argsref->{incdir} = $incdir;
+    $argsref->{include} = $include;
+    $argsref->{header} = $header;
+    $argsref->{source} = $source;
+    $argsref->{sym_export} = $sym_export;
+
+    $argsref->{ops} = $ops;
+    $argsref->{versions} = \%versions;
+    $argsref->{num_ops} = $num_ops;
+    $argsref->{num_entries} = $num_entries;
+
+    $argsref->{flag} = $flagref;
+    return bless $argsref, $class;
+}
+
+sub _prepare_core {
+    my $argsref = shift;
+    my $ops = Parrot::OpsFile->new(
+        [ qq|src/ops/$argsref->{file}| ],
+        $argsref->{flag}->{nolines},
+    );
+    $ops->{OPS}      = $Parrot::OpLib::core::ops;
+    $ops->{PREAMBLE} = $Parrot::OpLib::core::preamble;
+    return $ops;
+}
+
+sub _prepare_non_core {
+    my $argsref = shift;
+    my %opsfiles;
+    my @opsfiles;
+
+    foreach my $f ( $argsref->{file}, @{$argsref->{argv}} ) {
+        if ( $opsfiles{$f} ) {
+            print STDERR "$0: Ops file '$f' mentioned more than once!\n";
+            next;
+        }
+
+        $opsfiles{$f} = 1;
+        push @opsfiles, $f;
+
+        die "$0: Could not read ops file '$f'!\n" unless -r $f;
+    }
+
+    my $ops = Parrot::OpsFile->new( [EMAIL PROTECTED], 
$argsref->{flag}->{nolines} );
+
+    my $cur_code = 0;
+    for my $el ( @{ $ops->{OPS} } ) {
+        $el->{CODE} = $cur_code++;
+    }
+    return $ops;
+}
+
+1;

Added: branches/buildtools/t/tools/ops2cutils/01-new.t
==============================================================================
--- (empty file)
+++ branches/buildtools/t/tools/ops2cutils/01-new.t     Sun Feb 11 11:11:34 2007
@@ -0,0 +1,146 @@
+#! perl
+# Copyright (C) 2006, The Perl Foundation.
+# $Id: 01-new.t 16894 2007-02-04 22:54:29Z jkeenan $
+# 01-new.t
+
+use strict;
+use warnings;
+BEGIN {
+    use FindBin qw($Bin);
+    use Cwd qw(cwd realpath);
+    realpath($Bin) =~ m{^(.*\/parrot)\/[^/]*\/[^/]*\/[^/]*$};
+    our $topdir = $1;
+    if (defined $topdir) {
+        print "\nOK:  Parrot top directory located\n";
+    } else {
+        $topdir = realpath($Bin) . "/../../..";
+    }
+    unshift @INC, qq{$topdir/lib};
+}
+use Test::More qw(no_plan); # tests =>  30;
+use Carp;
+use Cwd;
+use_ok( 'Parrot::Ops2c::Utils' );
+use lib ("$main::topdir/t/tools/ops2cutils/testlib");
+use_ok( "Capture" );
+
+
+ok(chdir $main::topdir, "Positioned at top-level Parrot directory");
+my $cwd = cwd();
+my ($msg, $tie);
+
+{
+    local @ARGV = qw();
+    $tie = tie *STDERR, "Capture" or croak "Unable to tie";
+    my $self = Parrot::Ops2c::Utils->new( {
+        argv            => [ @ARGV ],
+        flag            => {},
+    } );
+    $msg = $tie->READLINE;
+    untie *STDERR or croak "Unable to untie";
+    ok(! defined $self, 
+        "Constructor correctly returned undef due to lack of command-line 
arguments");
+    like($msg,
+        qr/^Parrot::Ops2c::Utils::new\(\) requires 'trans' options/,
+        "Error message is correct");
+}
+
+{
+    local @ARGV = qw( gobbledygook );
+    $tie = tie *STDERR, "Capture" or croak "Unable to tie";
+    my $self = Parrot::Ops2c::Utils->new( {
+        argv            => [ @ARGV ],
+        flag            => {},
+    } );
+    $msg = $tie->READLINE;
+    untie *STDERR or croak "Unable to untie";
+    ok(! defined $self, 
+        "Constructor correctly returned undef due to bad class name 
command-line argument");
+    like($msg,
+        qr/Parrot::Ops2c::Utils::new\(\) requires C, CGoto, CGP, CSwitch 
and\/or  CPrederef/,
+        "Got correct error message");
+}
+
+{
+    local @ARGV = qw( C );
+    my $self = Parrot::Ops2c::Utils->new( {
+        argv            => [ @ARGV ],
+        flag            => {},
+    } );
+    ok(defined $self, 
+        "Constructor correctly returned when provided 1 argument");
+}
+
+{
+    local @ARGV = qw( C );
+    $tie = tie *STDERR, "Capture" or croak "Unable to tie";
+    my $self = Parrot::Ops2c::Utils->new( {
+        argv            => [ @ARGV ],
+    } );
+    $msg = $tie->READLINE;
+    untie *STDERR or croak "Unable to untie";
+    ok(! defined $self, 
+        "Constructor correctly returned undef when lacking reference to 
options");
+    like($msg,
+        qr/^Parrot::Ops2c::Utils::new\(\) requires reference to hash of 
command-line options/,
+        "Error message correctly returned");
+}
+
+{
+    local @ARGV = qw( C CGoto CGP CSwitch CPrederef);
+    my $self = Parrot::Ops2c::Utils->new( {
+        argv            => [ @ARGV ],
+        flag            => {},
+    } );
+    ok(defined $self, 
+        "Constructor correctly returned when provided >= 1 arguments");
+}
+
+#$VAR1 = [];
+#$VAR2 = bless( {
+#                 'split_count' => 0
+#               }, 'Parrot::OpTrans::CSwitch' );
+#$VAR3 = '_switch';
+#/usr/local/bin/perl tools/build/vtable_extend.pl
+#/usr/local/bin/perl tools/build/ops2c.pl CGoto --core
+#$VAR1 = [];
+#$VAR2 = bless( {}, 'Parrot::OpTrans::CGoto' );
+#$VAR3 = '_cg';
+#/usr/local/bin/perl tools/build/ops2c.pl CGP --core
+#$VAR1 = [];
+#$VAR2 = bless( {}, 'Parrot::OpTrans::CGP' );
+#$VAR3 = '_cgp';
+
+pass("Completed all tests in $0");
+
+################### DOCUMENTATION ###################
+
+=head1 NAME
+
+01-new.t - test C<Parrot::Ops2c::Utils::new()>
+
+=head1 SYNOPSIS
+
+    % prove t/tools/ops2cutils/01-new.t
+
+=head1 DESCRIPTION
+
+The files in this directory test the publicly callable subroutines of 
+F<lib/Parrot/Ops2c/Utils.pm> and F<lib/Parrot/Ops2c/Auxiliary.pm>.   
+By doing so, they test the functionality of the F<ops2c.pl> utility.  
+That functionality has largely been extracted 
+into the methods of F<Utils.pm>.
+
+F<01-new.t> tests whether C<Parrot::Ops2c::Auxiliary::Usage()> 
+and F<getoptions()> work properly.
+
+=head1 AUTHOR
+
+James E Keenan
+
+=head1 SEE ALSO
+
+Parrot::Ops2c::Auxiliary, F<ops2c.pl>.
+
+=cut
+

Modified: branches/buildtools/tools/build/ops2c.pl
==============================================================================
--- branches/buildtools/tools/build/ops2c.pl    (original)
+++ branches/buildtools/tools/build/ops2c.pl    Sun Feb 11 11:11:34 2007
@@ -3,14 +3,13 @@
 # $Id$
 use warnings;
 use strict;
+use Data::Dumper;
 use lib 'lib';
-
-use Getopt::Long qw(:config permute);
-
-use Parrot::OpsFile;
-use Parrot::OpLib::core;
+#use Parrot::OpsFile;
+#use Parrot::OpLib::core;
 use Parrot::Config;
 use Parrot::Ops2c::Auxiliary qw( Usage getoptions );
+use Parrot::Ops2c::Utils;
 
 #
 # Look at the command line options
@@ -26,66 +25,112 @@
         exit 1;
 }
 
-my $class_name = shift @ARGV;
-my %is_allowed = map { $_ => 1 } qw(C CGoto CGP CSwitch CPrederef);
-unless ($is_allowed{$class_name}) {
+#my $class_name = shift @ARGV;
+#print STDERR Dumper ([EMAIL PROTECTED], $class_name);
+#my %is_allowed = map { $_ => 1 } qw(C CGoto CGP CSwitch CPrederef);
+#unless ($is_allowed{$class_name}) {
+#    Usage();
+#    exit 1;
+#}
+
+#########################
+my $self = Parrot::Ops2c::Utils->new( {
+    argv            => [ @ARGV ],
+    flag            => $flagref,
+} );
+if (not defined $self) {
     Usage();
     exit 1;
 }
-
-my $trans_class = "Parrot::OpTrans::" . $class_name;
-eval "require $trans_class";
-my $trans           = $trans_class->new();
-my $suffix          = $trans->suffix();     # Invoked (sometimes) as ${suffix}
-
-my $file = $flagref->{core} ? 'core.ops' : shift @ARGV;
-my $base = $file;   # Invoked (sometimes) as ${base}
-$base =~ s/\.ops$//;
-my $base_ops_stub = $base . q{_ops} . $suffix;
-my $base_ops_h    = $base_ops_stub . q{.h};
-
-my $incdir  = "include/parrot/oplib";
-my $include = "parrot/oplib/$base_ops_h";
-my $header  = "include/$include";
-
-# SOURCE is closed and reread, which confuses make -j
-# create a temp file and rename it
-my $source = "src/ops/$base_ops_stub.c.temp";
-
-if ( $base =~ m!^src/dynoplibs/! || $flagref->{dynamic} ) {
-    $source             =~ s!src/ops/!!;
-    $header             = $base_ops_h;
-    $base               =~ s!^.*[/\\]!!;
-    $include            = $base_ops_h;
-    $flagref->{dynamic} = 1;
-}
-
-my $sym_export = $flagref->{dynamic} ? 'PARROT_DYNEXT_EXPORT' : 'PARROT_API';
+#########################
+#my $trans_class = "Parrot::OpTrans::" . $class_name;
+#eval "require $trans_class";
+#my $trans           = $trans_class->new();
+#my $suffix          = $trans->suffix();     # Invoked (sometimes) as ${suffix}
+
+#my $file = $flagref->{core} ? 'core.ops' : shift @ARGV;
+#my $base = $file;   # Invoked (sometimes) as ${base}
+#$base =~ s/\.ops$//;
+#my $base_ops_stub = $base . q{_ops} . $suffix;
+#my $base_ops_h    = $base_ops_stub . q{.h};
+#
+#my $incdir  = "include/parrot/oplib";
+#my $include = "parrot/oplib/$base_ops_h";
+#my $header  = "include/$include";
+#
+## SOURCE is closed and reread, which confuses make -j
+## create a temp file and rename it
+#my $source = "src/ops/$base_ops_stub.c.temp";
+#
+#if ( $base =~ m!^src/dynoplibs/! || $flagref->{dynamic} ) {
+#    $source             =~ s!src/ops/!!;
+#    $header             = $base_ops_h;
+#    $base               =~ s!^.*[/\\]!!;
+#    $include            = $base_ops_h;
+#    $flagref->{dynamic} = 1;
+#}
+#
+#my $sym_export = $flagref->{dynamic} ? 'PARROT_DYNEXT_EXPORT' : 'PARROT_API';
 
 # Read the input files:
-my $ops;
-if ($flagref->{core}) {
-    $ops = _prepare_core( {
-        file        => $file,
-        flag        => $flagref,
-    } );
-}
-else {
-    $ops = _prepare_non_core( {
-        file        => $file,
-        argv        => [ @ARGV ],
-        flag        => $flagref,
-    } );
-}
-
-my %versions = (
-    major => $ops->major_version,
-    minor => $ops->minor_version,
-    patch => $ops->patch_version,
-);
-my $num_ops       = scalar $ops->ops;
-my $num_entries   = $num_ops + 1;          # For trailing NULL
-
+#my $ops;
+#if ($flagref->{core}) {
+#    $ops = _prepare_core( {
+#        file        => $file,
+#        flag        => $flagref,
+#    } );
+#}
+#else {
+#    $ops = _prepare_non_core( {
+#        file        => $file,
+#        argv        => [ @ARGV ],
+#        flag        => $flagref,
+#    } );
+#}
+#
+#my %versions = (
+#    major => $ops->major_version,
+#    minor => $ops->minor_version,
+#    patch => $ops->patch_version,
+#);
+#my $num_ops       = scalar $ops->ops;
+#my $num_entries   = $num_ops + 1;          # For trailing NULL
+
+#########################
+local @ARGV = @{$self->{argv}};
+my $trans = $self->{trans};
+my $suffix = $self->{suffix};
+
+my $file    = $self->{file};
+my $base    = $self->{base};
+my $incdir    = $self->{incdir};
+my $include    = $self->{include};
+my $header    = $self->{header};
+my $source    = $self->{source};
+my $sym_export    = $self->{sym_export};
+
+my $ops = $self->{ops};
+my %versions = %{$self->{versions}};
+my $num_ops = $self->{num_ops};
+my $num_entries  = $self->{num_entries};
+
+#print STDERR Dumper (
+#    [EMAIL PROTECTED],
+#    $trans,
+#    $suffix,
+#    $file,
+#    $base,
+#    $incdir,
+#    $include,
+#    $header,
+#    $source,
+#    $sym_export,
+#    $ops,
+#    \%versions,
+#    $num_ops,
+#    $num_entries,
+#);
+#########################
 #
 # Open the output files:
 #
@@ -277,42 +322,42 @@
 
 #################### SUBROUTINES ####################
 
-sub _prepare_core {
-    my $argsref = shift;
-    my $ops = Parrot::OpsFile->new(
-        [ qq|src/ops/$argsref->{file}| ],
-        $argsref->{flag}->{nolines},
-    );
-    $ops->{OPS}      = $Parrot::OpLib::core::ops;
-    $ops->{PREAMBLE} = $Parrot::OpLib::core::preamble;
-    return $ops;
-}
-
-sub _prepare_non_core {
-    my $argsref = shift;
-    my %opsfiles;
-    my @opsfiles;
-
-    foreach my $f ( $argsref->{file}, @{$argsref->{argv}} ) {
-        if ( $opsfiles{$f} ) {
-            print STDERR "$0: Ops file '$f' mentioned more than once!\n";
-            next;
-        }
-
-        $opsfiles{$f} = 1;
-        push @opsfiles, $f;
-
-        die "$0: Could not read ops file '$f'!\n" unless -r $f;
-    }
-
-    my $ops = Parrot::OpsFile->new( [EMAIL PROTECTED], 
$argsref->{flag}->{nolines} );
-
-    my $cur_code = 0;
-    for my $el ( @{ $ops->{OPS} } ) {
-        $el->{CODE} = $cur_code++;
-    }
-    return $ops;
-}
+#sub _prepare_core {
+#    my $argsref = shift;
+#    my $ops = Parrot::OpsFile->new(
+#        [ qq|src/ops/$argsref->{file}| ],
+#        $argsref->{flag}->{nolines},
+#    );
+#    $ops->{OPS}      = $Parrot::OpLib::core::ops;
+#    $ops->{PREAMBLE} = $Parrot::OpLib::core::preamble;
+#    return $ops;
+#}
+#
+#sub _prepare_non_core {
+#    my $argsref = shift;
+#    my %opsfiles;
+#    my @opsfiles;
+#
+#    foreach my $f ( $argsref->{file}, @{$argsref->{argv}} ) {
+#        if ( $opsfiles{$f} ) {
+#            print STDERR "$0: Ops file '$f' mentioned more than once!\n";
+#            next;
+#        }
+#
+#        $opsfiles{$f} = 1;
+#        push @opsfiles, $f;
+#
+#        die "$0: Could not read ops file '$f'!\n" unless -r $f;
+#    }
+#
+#    my $ops = Parrot::OpsFile->new( [EMAIL PROTECTED], 
$argsref->{flag}->{nolines} );
+#
+#    my $cur_code = 0;
+#    for my $el ( @{ $ops->{OPS} } ) {
+#        $el->{CODE} = $cur_code++;
+#    }
+#    return $ops;
+#}
 
 sub _compose_preamble {
     my ($file, $script) = @_;

Reply via email to