1 # Copyright (C) 2001-2008, The Perl Foundation.
6 config/auto/pmc.pm - PMC Files
10 Asks the user to select which PMC files to include.
19 use base
qw(Parrot::Configure::Step);
21 use File
::Basename qw
/basename/;
22 use File
::Spec
::Functions qw
/catfile/;
24 use Parrot
::Configure
::Utils
':auto';
29 description
=> 'Determining what pmc files should be compiled in',
32 srcpmc
=> [ sort map { basename
($_) } glob "./src/pmc/*.pmc" ],
36 # Return the (lowercased) name of the immediate parent of the given
37 # (lowercased) pmc name.
39 my ($self, $pmc) = @_;
41 return $self->{PMC_PARENTS
}{$pmc} if defined $self->{PMC_PARENTS
}{$pmc};
44 open( my $PMC, '<', "src/pmc/$pmc.pmc" )
45 or die "open src/pmc/$pmc.pmc failed: $!";
49 # Throw out everything but the pmclass declaration
53 return $self->{PMC_PARENTS
}{$pmc} = lc($1) if m/extends\s+(\w+)/;
54 return $self->{PMC_PARENTS
}{$pmc} = 'default';
57 # Return an array of all
59 my ($self, $pmc) = @_;
62 push @parents, $self->pmc_parent( $parents[-1] )
63 until $parents[-1] eq 'default';
70 open my $IN, '<', 'src/pmc/pmc.num' or die "Can't read src/pmc/pmc.num";
75 if (/(\w+\.\w+)\s+(\d+)/) {
87 my $pmc_order = get_pmc_order
();
88 my $n = keys %$pmc_order;
92 if ( exists $pmc_order->{$pmc} ) {
93 $sorted_pmcs[ $pmc_order->{$pmc} ] = $pmc;
96 $sorted_pmcs[ $n++ ] = $pmc;
103 sub contains_pccmethod
{
105 open( my $fh, '<', $file ) or die "Can't read '$file': $!\n";
109 next unless /METHOD/;
116 # Given a PMC file name, get a list of all the includes it specifies
119 open( my $fh, '<', $file ) or die "Can't read '$file': $!\n";
124 next unless /^\s*#include\s+["<](.*)[">]\s+$/;
126 if ($include =~ m{^(\.|parrot/)}) { # main parrot include dir
127 $include = "include/" . $include;
128 } elsif ($include =~ m/^pmc_|\.str$/) { # local pmc header
129 $include = "src/pmc/" . $include;
130 } # else it's probably a system header, don't depend on it.
131 push @retval, $include;
134 return join(' ', @retval);
139 my ( $self, $conf ) = @_;
141 my @pmc = sort_pmcs
( @
{ $self->{srcpmc
} } );
143 my $pmc_list = $conf->options->get('pmc')
144 || join( ' ', grep { defined $_ } @pmc );
146 # names of class files for src/pmc/Makefile
147 ( my $TEMP_pmc_o = $pmc_list ) =~ s/\.pmc/\$(O)/g;
148 ( my $TEMP_pmc_str = $pmc_list ) =~ s/\.pmc/\.str/g;
150 # calls to pmc2c.pl for src/pmc/Makefile
151 my $TEMP_pmc_build = <<"E_NOTE";
153 # the following part of the Makefile was built by 'config/auto/pmc.pm'
157 $TEMP_pmc_build .= <<END;
159 lib/Parrot/Pmc2c/Pmc2cMain.pm \\
160 lib/Parrot/Pmc2c/Parser.pm \\
161 lib/Parrot/Pmc2c/Dumper.pm \\
162 lib/Parrot/Pmc2c/PMC.pm \\
163 lib/Parrot/Pmc2c/Method.pm \\
164 lib/Parrot/Pmc2c/PCCMETHOD.pm \\
165 lib/Parrot/Pmc2c/PMCEmitter.pm \\
166 lib/Parrot/Pmc2c/MethodEmitter.pm \\
167 lib/Parrot/Pmc2c/Library.pm \\
168 lib/Parrot/Pmc2c/UtilFunctions.pm \\
169 lib/Parrot/Pmc2c/PMC/default.pm \\
170 lib/Parrot/Pmc2c/PMC/delegate.pm \\
171 lib/Parrot/Pmc2c/PMC/deleg_pmc.pm \\
172 lib/Parrot/Pmc2c/PMC/Null.pm \\
173 lib/Parrot/Pmc2c/PMC/Ref.pm \\
174 lib/Parrot/Pmc2c/PMC/SharedRef.pm \\
175 lib/Parrot/Pmc2c/PMC/STMRef.pm \\
176 lib/Parrot/Pmc2c/PMC/RO.pm
179 for my $pmc ( split( /\s+/, $pmc_list ) ) {
181 next if $pmc =~ /^const/;
183 # make each pmc depend upon its parent.
184 my $parent_dumps = '';
185 $parent_dumps .= "src/pmc/$_.dump "
186 foreach reverse( ( $self->pmc_parents($pmc) ) );
187 my $parent_headers = '';
188 $parent_headers .= "src/pmc/pmc_$_.h "
189 for $self->pmc_parents($pmc);
191 # add dependencies that result from METHOD usage.
192 my $pmc_fname = catfile
('src', 'pmc', "$pmc.pmc");
193 my $pccmethod_depend = '';
194 if (contains_pccmethod
($pmc_fname)) {
195 $pccmethod_depend = 'lib/Parrot/Pmc2c/PCCMETHOD.pm';
196 if ($pmc ne 'fixedintegerarray') {
197 $pccmethod_depend .= ' src/pmc/pmc_fixedintegerarray.h';
200 my $include_headers = get_includes
($pmc_fname);
202 $TEMP_pmc_build .= <<END
203 src/pmc/$pmc.c : src/pmc/$pmc.dump
204 \t\$(PMC2CC) src/pmc/$pmc.pmc
206 src/pmc/$pmc.dump : vtable.dump $parent_dumps src/pmc/$pmc.pmc \$(PMC2C_FILES) $pccmethod_depend
207 \t\$(PMC2CD) src/pmc/$pmc.pmc
209 src/pmc/pmc_$pmc.h: src/pmc/$pmc.c
211 src/pmc/$pmc\$(O): src/pmc/$pmc.str \$(NONGEN_HEADERS) \\
212 $parent_headers $include_headers
217 # src/pmc/$pmc\$(O): \$(NONGEN_HEADERS) $parent_headers src/pmc/pmc_$pmc.h
219 # build list of libraries for link line in Makefile
220 my $slash = $conf->data->get('slash');
221 ( my $TEMP_pmc_classes_o = $TEMP_pmc_o ) =~ s/^| / src${slash}pmc${slash}/g;
222 ( my $TEMP_pmc_classes_str = $TEMP_pmc_str ) =~ s/^| / src${slash}pmc${slash}/g;
223 ( my $TEMP_pmc_classes_pmc = $pmc_list ) =~ s/^| / src${slash}pmc${slash}/g;
225 # Gather the actual names (with MixedCase) of all of the
226 # non-abstract built-in PMCs.
228 PMC
: for my $pmc_file ( split( /\s+/, $pmc_list ) ) {
229 next if $pmc_file =~ /^const/;
231 open my $PMC, "<", "src/pmc/$pmc_file"
232 or die "open src/pmc/$pmc_file: $!";
235 if (/^pmclass (\w+)(.*)/) {
238 $decl .= <$PMC> until $decl =~ s/\{.*//;
240 $const = 1 if $decl =~ /\bconst_too\b/;
241 next PMC
if $decl =~ /\babstract\b/;
242 next PMC
if $decl =~ /\bextension\b/;
250 die "No pmclass declaration found in $pmc_file"
251 unless defined $name;
253 # please note that normal and Const PMCs must be in this order
255 push @names, "Const$name" if $const;
260 pmc_names
=> join( ' ', @names ),
261 TEMP_pmc_o
=> $TEMP_pmc_o,
262 TEMP_pmc_build
=> $TEMP_pmc_build,
263 TEMP_pmc_classes_o
=> $TEMP_pmc_classes_o,
264 TEMP_pmc_classes_str
=> $TEMP_pmc_classes_str,
265 TEMP_pmc_classes_pmc
=> $TEMP_pmc_classes_pmc,
275 # cperl-indent-level: 4
278 # vim: expandtab shiftwidth=4: