<commit_before>#! perl -w
# Copyright: 2001-2005 The Perl Foundation.  All Rights Reserved.
# $Id$

=head1 NAME

tools/build/ops2c.pl - Parser for .ops files

=head1 SYNOPSIS

    % perl tools/build/ops2c.pl trans [--help] [--no-lines] [--dynamic] [--core | input.ops [input2.ops ...]]
       trans := C | CGoto | CGP | CSwitch | CPrederef

For example:

    % perl tools/build/ops2c.pl C --core

    % perl tools/build/ops2c.pl C --dynamic myops.ops

=head1 DESCRIPTION

This script uses a supplied transform to create a pair of C header and
implementation files from the operation definitions found in one or more
F<*.ops> files.

=head2 Transforms

The first command-line argument is the last package name component of a
subclass of C<Parrot::OpTrans>. These subclasses all have full names of
the form C<Parrot::OpTrans::*>. An instance of the class is created and
later consulted for various bits of information needed to generate the C
code. Each creates a different type of run loop.

=over

=item C<C>

Create the function-based (slow or fast core) run loop.

=item C<CGoto>

Create the C<goto> run loop.

=item C<CGP>

Create the C<goto> and predereferenced run loop.

=item C<CSwitch>

Create the C<switch>ed and predereferenced run loop.

=item C<CPrederef>

Create the predereferenced run loop.

=back

=head2 Options

=over 4

=item C<--help>

Print synopsis.

=item C<--dynamic>

Indicate that the opcode library is dynamic.

=item C<--core>

Build the Parrot core opcode library.

=item C<--no-lines>

Do not generate C<#line> directives in the generated C code.

=back

=head1 SEE ALSO

=over 4

=item F<tools/build/ops2pm.pl>

=item C<Parrot::OpsFile>

=item C<Parrot::Op>

=item C<Parrot::OpTrans>

=item C<Parrot::OpTrans::C>

=item C<Parrot::OpTrans::CGoto>

=item C<Parrot::OpTrans::Compiled>

=item C<Parrot::OpTrans::CGP>

=item C<Parrot::OpTrans::CSwitch>

=item C<Parrot::OpTrans::CPrederef>

=back

=cut

use strict;
use lib 'lib';

use Pod::Usage;
use Getopt::Long;

use Parrot::OpsFile;
use Parrot::OpLib::core;
use Parrot::Config;

my %arg_dir_mapping = (
	''   => 'PARROT_ARGDIR_IGNORED',
	'i'  => 'PARROT_ARGDIR_IN',
	'o'  => 'PARROT_ARGDIR_OUT',
	'io' => 'PARROT_ARGDIR_INOUT'
);

#
# Look at the command line options
#
sub Usage {
    pod2usage(-exitval => 1, -verbose => 0, -output => \*STDERR);
}

my ( $nolines_flag, $help_flag, $dynamic_flag, $core_flag );
GetOptions( "no-lines"      => \$nolines_flag,
            "help"          => \$help_flag,
            "dynamic|d"     => \$dynamic_flag,
            "core"          => \$core_flag,
          ) || Usage();

Usage() if $help_flag;
Usage() unless @ARGV;

my $class_name = shift @ARGV;
my %is_allowed = map { $_ => 1 } qw(C CGoto CGP CSwitch CPrederef);
Usage() unless $is_allowed{$class_name};
my $trans_class = "Parrot::OpTrans::" . $class_name;

eval "require $trans_class";

my $trans = $trans_class->new();

# Not used
my $prefix  = $trans->prefix();
my $suffix  = $trans->suffix();
# Used as ${defines}
my $defines = $trans->defines();
my $opsarraytype = $trans->opsarraytype();
my $core_type = $trans->core_type();

my $file = $core_flag ? 'core.ops' : shift @ARGV;

my $base = $file;
$base =~ s/\.ops$//;

my $incdir  = "include/parrot/oplib";
my $include = "parrot/oplib/${base}_ops${suffix}.h";
my $header  = "include/$include";
my $source  = "src/ops/${base}_ops${suffix}.c";

if ($base =~ m!^src/dynoplibs/! || $dynamic_flag) {
    $source  =~ s!src/ops/!!;
    $header = "${base}_ops${suffix}.h";
    $base =~ s!^.*[/\\]!!;
    $include = "${base}_ops${suffix}.h";
    $dynamic_flag = 1;
}

my $sym_export = '';
if ($dynamic_flag && ($PConfig{'osname'} =~ /cygwin/i ||
    ($PConfig{'osname'} =~ /win32/i && $PConfig{'cc'} =~ /cl|gcc/i))) {
    $sym_export = '__declspec(dllexport)';
}

my %hashed_ops;

#
# Read the input files:
#

my $ops;
if ($core_flag) {
    $ops = Parrot::OpsFile->new( [ "src/ops/$file" ], $nolines_flag );
    $ops->{OPS} = $Parrot::OpLib::core::ops;
    $ops->{PREAMBLE} = $Parrot::OpLib::core::preamble;
}
else {
    my %opsfiles;
    my @opsfiles;

    foreach my $opsfile ($file, @ARGV) {
	if ($opsfiles{$opsfile}) {
	    print STDERR "$0: Ops file '$opsfile' mentioned more than once!\n";
	    next;
	}

	$opsfiles{$opsfile} = 1;<commit_msg>PARROT_API marking #5: modify tools/build/ops2c.pl to decorate the generated header files ~ all necessary functions now marked for export<commit_after>#! perl -w
# Copyright: 2001-2005 The Perl Foundation.  All Rights Reserved.
# $Id$

=head1 NAME

tools/build/ops2c.pl - Parser for .ops files

=head1 SYNOPSIS

    % perl tools/build/ops2c.pl trans [--help] [--no-lines] [--dynamic] [--core | input.ops [input2.ops ...]]
       trans := C | CGoto | CGP | CSwitch | CPrederef

For example:

    % perl tools/build/ops2c.pl C --core

    % perl tools/build/ops2c.pl C --dynamic myops.ops

=head1 DESCRIPTION

This script uses a supplied transform to create a pair of C header and
implementation files from the operation definitions found in one or more
F<*.ops> files.

=head2 Transforms

The first command-line argument is the last package name component of a
subclass of C<Parrot::OpTrans>. These subclasses all have full names of
the form C<Parrot::OpTrans::*>. An instance of the class is created and
later consulted for various bits of information needed to generate the C
code. Each creates a different type of run loop.

=over

=item C<C>

Create the function-based (slow or fast core) run loop.

=item C<CGoto>

Create the C<goto> run loop.

=item C<CGP>

Create the C<goto> and predereferenced run loop.

=item C<CSwitch>

Create the C<switch>ed and predereferenced run loop.

=item C<CPrederef>

Create the predereferenced run loop.

=back

=head2 Options

=over 4

=item C<--help>

Print synopsis.

=item C<--dynamic>

Indicate that the opcode library is dynamic.

=item C<--core>

Build the Parrot core opcode library.

=item C<--no-lines>

Do not generate C<#line> directives in the generated C code.

=back

=head1 SEE ALSO

=over 4

=item F<tools/build/ops2pm.pl>

=item C<Parrot::OpsFile>

=item C<Parrot::Op>

=item C<Parrot::OpTrans>

=item C<Parrot::OpTrans::C>

=item C<Parrot::OpTrans::CGoto>

=item C<Parrot::OpTrans::Compiled>

=item C<Parrot::OpTrans::CGP>

=item C<Parrot::OpTrans::CSwitch>

=item C<Parrot::OpTrans::CPrederef>

=back

=cut

use strict;
use lib 'lib';

use Pod::Usage;
use Getopt::Long;

use Parrot::OpsFile;
use Parrot::OpLib::core;
use Parrot::Config;

my %arg_dir_mapping = (
	''   => 'PARROT_ARGDIR_IGNORED',
	'i'  => 'PARROT_ARGDIR_IN',
	'o'  => 'PARROT_ARGDIR_OUT',
	'io' => 'PARROT_ARGDIR_INOUT'
);

#
# Look at the command line options
#
sub Usage {
    pod2usage(-exitval => 1, -verbose => 0, -output => \*STDERR);
}

my ( $nolines_flag, $help_flag, $dynamic_flag, $core_flag );
GetOptions( "no-lines"      => \$nolines_flag,
            "help"          => \$help_flag,
            "dynamic|d"     => \$dynamic_flag,
            "core"          => \$core_flag,
          ) || Usage();

Usage() if $help_flag;
Usage() unless @ARGV;

my $class_name = shift @ARGV;
my %is_allowed = map { $_ => 1 } qw(C CGoto CGP CSwitch CPrederef);
Usage() unless $is_allowed{$class_name};
my $trans_class = "Parrot::OpTrans::" . $class_name;

eval "require $trans_class";

my $trans = $trans_class->new();

# Not used
my $prefix  = $trans->prefix();
my $suffix  = $trans->suffix();
# Used as ${defines}
my $defines = $trans->defines();
my $opsarraytype = $trans->opsarraytype();
my $core_type = $trans->core_type();

my $file = $core_flag ? 'core.ops' : shift @ARGV;

my $base = $file;
$base =~ s/\.ops$//;

my $incdir  = "include/parrot/oplib";
my $include = "parrot/oplib/${base}_ops${suffix}.h";
my $header  = "include/$include";
my $source  = "src/ops/${base}_ops${suffix}.c";

if ($base =~ m!^src/dynoplibs/! || $dynamic_flag) {
    $source  =~ s!src/ops/!!;
    $header = "${base}_ops${suffix}.h";
    $base =~ s!^.*[/\\]!!;
    $include = "${base}_ops${suffix}.h";
    $dynamic_flag = 1;
}

my $sym_export = $PConfig{'sym_export'};
#if ($dynamic_flag && ($PConfig{'osname'} =~ /cygwin/i ||
#    ($PConfig{'osname'} =~ /win32/i && $PConfig{'cc'} =~ /cl|gcc/i))) {
#    $sym_export = '__declspec(dllexport)';
#}

my %hashed_ops;

#
# Read the input files:
#

my $ops;
if ($core_flag) {
    $ops = Parrot::OpsFile->new( [ "src/ops/$file" ], $nolines_flag );
    $ops->{OPS} = $Parrot::OpLib::core::ops;
    $ops->{PREAMBLE} = $Parrot::OpLib::core::preamble;
}
else {
    my %opsfiles;
    my @opsfiles;

    foreach my $opsfile ($file, @ARGV) {
	if ($opsfiles{$opsfile}) {
	    print STDERR "$0: Ops file '$opsfile' mentioned more than once!\n";
	    next;
	}

	$opsfiles{$opsfile} = 1;
{'fraction_non_alphanumeric': 0.16777828886844526, 'fraction_numerical': 0.007359705611775529, 'mean_word_length': 3.773326015367728, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 97, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1265321', 'n_tokens_mistral': 3411, 'n_tokens_neox': 3292, 'n_words': 895}