NAME

Parrot::Ops2pm::Utils - Methods holding functionality for tools/build/ops2pm.pl.

SYNOPSIS

use Parrot::Ops2pm::Utils;

$self = Parrot::Ops2pm::Utils->new( {
    argv            => [ @ARGV ],
    nolines         => $nolines_flag,
    renum           => $renum_flag,
    moddir          => 'lib/Parrot/OpLib',
    module          => 'core.pm',
    inc_dir         => 'include/parrot/oplib',
    inc_f           => 'ops.h',
    script          => 'tools/build/ops2pm.pl',
} );

$self->prepare_ops();

if ($renum_flag) {
    $self->renum_op_map_file();

    exit 0;
}

$self->load_op_map_files();
$self->sort_ops();
$self->prepare_real_ops();
$self->print_module();
$self->print_h();

exit 0;

DESCRIPTION

Parrot::Ops2pm::Utils provides methods called by tools/build/ops2pm.pl, a program which is called at the very beginning of the Parrot make process. The program's function is to build two files:

  • lib/Parrot/OpLib/core.pm

  • include/parrot/oplib/ops.h

The functionality originally found in tools/build/ops2pm.pl has been extracted into this package's methods in order to support component-focused testing and future refactoring.

METHODS

new()

  • Purpose

    Process files provided as command-line arguments to tools/build/ops2pm.pl and construct a Parrot::Ops2pm::Utils object.

  • Arguments

    Hash reference with the following elements:

    argv        :   reference to @ARGV
    nolines     :   set to true value to eliminate #line
                    directives in output
    renum       :   set to true value if
    moddir      :   directory where output module is created
                    (generally, lib/Parrot/OpLib)
    module      :   name of output module
                    (generally, core.pm)
    inc_dir     :   directory where C-header file is created
                    (generally, include/parrot/oplib)
    inc_f       :   name of output C-header file
                    (generally, ops.h)
    script      :   name of the script to be executed by 'make'
                    (generally, tools/build/ops2pm.pl)
  • Return Value

    Parrot::Ops2pm::Utils object.

  • Comment

    Arguments for the constructor have been selected so as to provide subsequent methods with all information needed to execute properly and to be testable. A Parrot::Ops2pm::Utils object can be constructed lacking some of these arguments and still suffice for the execution of particular methods -- this is done during the test suite -- but such an object would not suffice for make's call to tools/build/ops2pm.pl.

prepare_ops()

  • Purpose

    Call Parrot::OpsFile::new(), then populate the resulting $opts hash reference with information from each of the .ops files provided as command-line arguments to tools/build/ops2pm.pl.

  • Arguments

    None. (Implicitly requires that at least the argv and script elements were provided to the constructor.)

  • Return Value

    None. Internally, sets the ops key in the object's data structure.

  • Comment

    This method calls Parrot::OpsFile::new() on the first .ops file found in @ARGV, then copies the ops from the remaining .ops files to the object just created. Experimental ops are marked as such.

renum_op_map_file()

  • Purpose

    Triggered when tools/build/ops2pm.pl is called with the --renum flag, this method renumbers src/ops/ops.num based on the already existing file of that name and additional .ops files.

  • Arguments

    String holding name of an .ops file; defaults to src/ops/ops.num. (Implicitly requires that the argv, script and renum elements were provided to the constructor.)

  • Return Value

    Returns true value upon success.

  • Comment

    When tools/build/ops2pm.pl is called with the --renum option, this method is triggered, after which ops2pm.pl exits. Consequently, this is the only Parrot::Ops2pm::Utils method which is not a stepping stone on the path to building lib/Parrot/OpLib/core.pm.

load_op_map_files()

  • Purpose

    When tools/build/ops2pm.pl is called by make, this method checks the number of ops strictly against src/ops/ops.num and renumbers as needed.

  • Arguments

    None. (Implicitly requires that the argv and script keys have been provided to the constructor and that the renum key not have a true value -- which will be the case when the --renum option is not provided to tools/build/ops2pm.pl.)

  • Return Value

    Returns true value upon success. Internally, sets these values in these elements in the object's data structure: max_op_num, skiptable and optable.

  • Comments

    This is the default case, i.e., the case that prevails when tools/build/ops2pm.pl is not called with the --renum flag. In addition to src/ops/ops.num, this method also draws upon information in src/ops/ops.skip.

sort_ops()

  • Purpose

    Internal manipulation of the Parrot::Ops2pm::Utils object: sorting by number of the list of op codes found in the object's {ops}->{OPS} element.

  • Arguments

    None.

  • Return Value

    Returns true value upon successful completion. Internally, sets the ops key of the object's data structure.

  • Comment

    Will emit warnings under these circumstances:

prepare_real_ops()

  • Purpose

    Final stage of preparation of ops.

  • Arguments

    None. (Same implicit requirements for the constructor as load_op_map_files() above.)

  • Return Value

    Returns true value upon successful completion. Internally, sets the real_ops key of the object's data structure.

  • Comment

  • Purpose

    Uses information in the object's data structure -- principally the real_ops element -- to create lib/Parrot/OpLib/core.pm.

  • Arguments

    None. (Implicitly requires that the constructor have the following keys defined: argv, script, moddir and module.)

  • Return Value

    Returns true value upon successful completion.

  • Comment

  • Purpose

    Uses information in the object's data structure -- principally the real_ops key -- to create include/parrot/oplib/ops.h.

  • Arguments

    None. (Implicitly requires that the constructor have the following keys defined: argv, script, inc_dir and inc_f.)

  • Return Value

    Returns true value upon success.

  • Comment

NOTE ON TESTING

A suite of test files to accompany this package is found in t/tools/ops2pmutils. This suite has been developed to maximize its coverage of the code of Parrot::Ops2pm::Utils (as measured by Perl module Devel::Cover). Should you wish to refactor this package, it is recommended that you do so in a test-driven manner:

  1. Write the specification for any additions or modifications to Parrot::Ops2pm::Utils' interface.

  2. Write tests that reflect any such modifications.

  3. Write the additional or modified code that reflects the new specification.

  4. Test the new code and debug. The tests in the suite should be run after Parrot's Configure.pl has run but before make has run. Example:

    $> perl Configure.pl
    $> prove -v t/tools/ops2pmutils/*.t
    $> make
  5. Use Devel::Cover to measure the extent to which the existing and new tests cover the existing and revised code.

  6. Refactor and retest to ensure high test coverage.

This package's methods are called by tools/build/ops2pm.pl, which in turn is invoked by make in the Parrot build process. Successful execution of make proves that the functionality in this package achieved its overall objective but does not necessarily invoke many of the individual code statements in the package. That is the rationale for the component-focused testing provided by the test suite.

AUTHOR

See tools/build/ops2pm.pl for a list of the Parrot hackers who, over a period of several years, developed the functionality now found in the methods of Parrot::Ops2pm::Utils. Jim Keenan extracted that functionality and placed it in this package's methods.