1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
#!/usr/bin/perl -w
BEGIN {
for my $n (qw(lib regen)) {
if (-e "../$n") {
push @INC, "../$n";
} elsif (-e "./$n") {
push @INC, "./$n";
}
}
}
use strict;
use warnings;
use HeaderParser;
# read embed.fnc and regen/opcodes, needed by regen/embed.pl, makedef.pl,
# autodoc.pl and t/porting/diag.t
require 5.004; # keep this compatible, an old perl is all we may have before
# we build the new one
sub setup_embed {
my $prefix = shift || '';
my $parser= HeaderParser->new(
pre_process_content => sub {
my ($self,$line_data)= @_;
# HeaderParser knows how to parse and normalize embed_fnc.
# calling this here ensures sets up the embed subpacket.
$self->tidy_embed_fnc_entry($line_data);
my $embed= $line_data->{embed}
or return;
},
post_process_grouped_content => sub {
# sort the group content by name.
@{$_[1]}=
sort {
$a->{embed}{name} cmp $b->{embed}{name}
} @{$_[1]};
},
)->read_file($prefix . 'embed.fnc');
my $lines= $parser->lines();
# add the opcode checker functions automatically.
open my $in_fh, '<', $prefix . 'regen/opcodes' or die $!;
{
my %syms;
my $line_num = 0;
while (my $line= <$in_fh>) {
$line_num++;
chomp($line);
next unless $line;
next if $line=~/^#/;
my $check = (split /\t+/, $line)[2];
next if $syms{$check}++;
# These are all indirectly referenced by globals.c.
my $new= HeaderLine->new(
cond => [["defined(PERL_IN_GLOBALS_C) || defined(PERL_IN_OP_C) || defined(PERL_IN_PEEP_C) || defined(PERL_IN_CLASS_C)"]],
raw => "pR|OP *|$check|NN OP *o",
line => "pR|OP *|$check|NN OP *o",
type => "content",
level => 1,
source => 'regen/opcodes',
start_line_num => $line_num,
);
$parser->tidy_embed_fnc_entry($new);
push @$lines, $new;
}
}
close $in_fh
or die "Problem reading regen/opcodes: $!";
# Cluster entries in embed.fnc that have the same #ifdef guards.
# Also, split out at the top level the three classes of functions.
# The result for each group_content() calls is an arrayref containing
# HeaderLine objects, with the embed.fnc data prenormalized, and each
# conditional clause containing a sorted list of functions, with
# any further conditional clauses following.
# Note this is a normalized and relatively smart grouping, and we can
# handle if/elif and etc properly. At the cost of being a touch slow.
return (
$parser->group_content($lines,
sub { $_[1]->{embed} }), # everything
$parser->group_content($lines,
sub { $_[1]->{embed} &&
$_[1]->{embed}{flags}=~/[AC]/ }), # only API and private API
$parser->group_content($lines,
sub { $_[1]->{embed} &&
$_[1]->{embed}{flags}!~/[AC]/ && # otherwise Extensions
$_[1]->{embed}{flags}=~/[E]/ }),
$parser->group_content($lines,
sub { $_[1]->{embed} &&
$_[1]->{embed}{flags}!~/[AC]/ && # everything else.
$_[1]->{embed}{flags}!~/[E]/ }),
);
}
1;
|