1 # Copyright (C) 2001-2007, The Perl Foundation.
6 config/gen/parrot_include.pm - Runtime Includes
10 Generates the F<runtime/parrot/include> files.
14 package gen
::parrot_include
;
19 use base
qw(Parrot::Configure::Step);
21 use Parrot
::Configure
::Utils
':gen';
27 $data{description
} = q{Generate runtime/parrot/include};
29 $data{source_files
} = [ qw(
30 include/parrot/cclass.h
31 include/parrot/datatypes.h
32 include/parrot/enums.h
33 include/parrot/events.h
34 include/parrot/scheduler.h
35 include/parrot/exceptions.h
36 include/parrot/interpreter.h
38 include/parrot/longopt.h
40 include/parrot/resources.h
42 include/parrot/string.h
44 include/parrot/warnings.h
48 $data{generated_files
} = [ qw(
49 include/parrot/vtable.h
50 include/parrot/core_pmcs.h
52 $data{destdir
} = 'runtime/parrot/include';
57 map ".macro_const $_->[0]\t$_->[1]", @_;
60 # refactor to generate 'use constant' statements, RT#42286
62 map "$_->[0] => $_->[1],", @_;
68 return map { [ $action->( $_->[0] ), $_->[1] ] } @_;
74 transform_name
( sub { $prefix . $_[0] }, @_ );
77 sub perform_directive
{
80 my @defs = prepend_prefix
$d->{prefix
}, @
{ $d->{defs
} };
81 if ( my $subst = $d->{subst
} ) {
82 @defs = transform_name
( sub { local $_ = shift; eval $subst; $_ }, @defs );
88 my ( $file, $fh ) = @_;
90 my ( @d, %values, $last_val, $cur, $or_continues );
91 while ( my $line = <$fh> ) {
94 &gen_from_
(enum
|def
) \
( ( [^)]* ) \
)
95 (?
: \s
+ prefix \
( (\w
+) \
) )?
96 (?
: \s
+ subst \
( (s/.*?/.*?/[eig
]?
) \
) )?
100 $cur and die "Missing '&end_gen' in $file\n";
103 files
=> [ split ' ', $2 ],
104 prefix
=> defined $3 ?
$3 : '',
105 defined $4 ?
( subst
=> $4 ) : (),
109 elsif ( $line =~ /&end_gen\b/ ) {
110 $cur or die "Missing &gen_from_(enum|def) in $file\n";
117 if ( $cur->{type
} eq 'def' && $line =~ /^\s*#define\s+(\w+)\s+(-?\w+|"[^"]*")/ ) {
118 push @
{ $cur->{defs
} }, [ $1, $2 ];
120 elsif ( $cur->{type
} eq 'enum' ) {
121 # Special case: enum value is or'd combination of other values
122 if ( $or_continues ) {
124 my $last_def = $cur->{defs
}->[-1];
125 my ($k, $v) = @
{$last_def};
126 my @or_values = grep {defined $_} $line =~ /^\s*(-?\w+)(?:\s*\|\s*(-?\w+))*/;
127 for my $or (@or_values) {
128 if ( defined $values{$or} ) {
131 elsif ( $or =~ /^0/ ) {
135 if ($line =~ /\|\s*$/) {
138 $values{$k} = $last_val = $v;
139 $cur->{defs
}->[-1]->[1] = $v;
141 elsif ( $line =~ /^\s*(\w+)\s*=\s*(-?\w+)\s*\|/ ) {
142 my ( $k, $v ) = ( $1, $2 );
143 my @or_values = ($v, $line =~ /\|\s*(-?\w+)/g);
145 for my $or (@or_values) {
146 if ( defined $values{$or} ) {
149 elsif ( $or =~ /^0/ ) {
153 if ($line =~ /\|\s*$/) {
156 $values{$k} = $last_val = $v;
157 push @
{ $cur->{defs
} }, [ $k, $v ];
159 elsif ( $line =~ /^\s*(\w+)\s*=\s*(-?\w+)/ ) {
160 my ( $k, $v ) = ( $1, $2 );
161 if ( defined $values{$v} ) {
164 elsif ( $v =~ /^0/ ) {
167 $values{$k} = $last_val = $v;
168 push @
{ $cur->{defs
} }, [ $k, $v ];
170 elsif ( $line =~ m!^\s*(\w+)\s*(?:,\s*)?(?:/\*|$)! ) {
172 my $v = $values{$k} = ++$last_val;
173 push @
{ $cur->{defs
} }, [ $k, $v ];
177 $cur and die "Missing '&end_gen' in $file\n";
183 my ( $self, $conf ) = @_;
184 my $verbose = $conf->options->get('verbose');
187 system( $^X
, "tools/build/vtable_h.pl" );
190 for my $file ( @
{ $self->{source_files
} }, @
{ $self->{generated_files
} } ) {
191 open my $fh, '<', $file or die "Can't open $file: $!\n";
192 my @directives = parse_file
$file, $fh;
194 for my $d (@directives) {
195 my @defs = perform_directive
$d;
196 for my $target ( @
{ $d->{files
} } ) {
197 $verbose and print "$target ";
199 ( $target =~ /\.pl$/ ? \
&const_to_perl
: \
&const_to_parrot
)->(@defs);
200 $conf->append_configure_log(qq{$self->{destdir
}/$target});
201 my $target_tmp = "$target.tmp";
202 open my $out, '>', $target_tmp or die "Can't open $target_tmp: $!\n";
204 # refactor to include package declarations and Export
205 # declarations for generated Perl constant modules, RT#42286
207 # DO NOT EDIT THIS FILE.
209 # This file is generated automatically from
210 # $file by config/gen/parrot_include.pm
212 # Any changes made here will be lost.
216 close $out or die "Can't write $target_tmp: $!\n";
217 $target =~ m
[/] or $target = "$self->{destdir}/$target";
218 move_if_diff( $target_tmp, $target );
219 push @generated, $target;
223 $conf->data->set( TEMP_gen_pasm_includes => join( " \\\n ", @generated ) );
232 # cperl-indent-level: 4
235 # vim: expandtab shiftwidth=4: