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
andscript
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
andrenum
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
andscript
keys have been provided to the constructor and that therenum
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
andoptable
.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
print_module()
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
andmodule
.)Return Value
Returns true value upon successful completion.
Comment
print_h()
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
andinc_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:
Write the specification for any additions or modifications to Parrot::Ops2pm::Utils' interface.
Write tests that reflect any such modifications.
Write the additional or modified code that reflects the new specification.
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
Use Devel::Cover to measure the extent to which the existing and new tests cover the existing and revised code.
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.