makepp
view release on metacpan or search on metacpan
Mpp/CommandParser/Vcs.pm view on Meta::CPAN
# $Id: Vcs.pm,v 1.33 2012/10/25 21:10:43 pfeiffer Exp $
=head1 NAME
Mpp::CommandParser::Vcs - makepp command parser for Synopsys VCS
=head1 DESCRIPTION
Parses a vcs command for implicit dependencies.
=cut
use strict;
package Mpp::CommandParser::Vcs;
use Mpp::CommandParser;
our @ISA = qw/Mpp::CommandParser/;
use Mpp::File;
use Mpp::Text;
*factory = \&Mpp::Subs::p_vcs_compilation;
sub new {
my $self = &Mpp::CommandParser::new;
require Mpp::Scanner::Verilog;
require Mpp::Scanner::Vera;
$self->{SCANNER}=new Mpp::Scanner::Verilog($self->rule, $self->dir);
$self->{VERA_SCANNER}=new Mpp::Scanner::Vera($self->rule, $self->dir);
$self;
}
# free function
sub updir {
my ($name) = @_;
return $name if $name =~ m@^/@;
return "../$name";
}
# This can be modified from the outside for site-specific suffixes:
our @verilog_suffixes = qw(v gv vlib vt bvrl vg vgs vgp sv);
my %info_string = (user => 'VERA_INCLUDES',
sys => 'VERA_SYSTEM_INCLUDES');
sub xparse_command {
my( $self, $command, $setenv ) = @_;
# Use the MD5 signature checking when we can.
$self->rule->set_signature_class( 'C.v', 1 );
my @words=@$command;
my $dir=$self->dir;
my $file_regexp = $self->input_filename_regexp(
$command->[0], [map { ".$_" } @verilog_suffixes]
);
my $scanner=$self->{SCANNER};
$scanner->should_find("vinc");
$scanner->add_include_dir("vinc", ".");
$scanner->should_find("vlog");
# NOTE: We can't set an info_string for the "vlog" tag, because
# whether the files are actually needed depends on whether the
# module containing the instance was itself instantiated. And
# because Mpp::Scanner::Verilog goes out of its way to model that,
# instances can get imputed to the wrong module! And since we
# can't set it for "vlog", we can't set it for any tag, or else
# we violate the requirements of the Mpp::Scanner base class.
my $vera_scanner=$self->{VERA_SCANNER};
$vera_scanner->should_find("user");
$vera_scanner->info_string( \%info_string );
$vera_scanner->add_include_dir("user", undef);
my %visited;
my @libs; # -v files
my @files;
my @vera_files;
my @c_args;
my $cmd = shift @words; # Remove command name
WORD: while(defined($_ = shift @words)) {
if(ref $_) {
# This was inserted by a -f option to indicate that
# we're no longer reading args that came from the
# particular file. Neat hack, eh?
delete $visited{$_};
} elsif(/^\+incdir\+(.*)/) {
my @args=map { $_ ? ($_) : () } (split(/\+/, $1));
for(@args) {
$scanner->add_include_dir("vinc", $_);
}
} elsif(/^\+define\+(.*)/) {
my @defs=map { $_ ? ($_) : () } (split(/\+/, $1));
for(@defs) {
if(/^(\w+)=(.*)/) {
$scanner->set_var($1, $2);
} else {
$scanner->set_var($_, "");
}
}
} elsif(/^-ntb_incdir$/) {
my @args=map { $_ ? ($_) : () }
(split(/\+/, shift @words));
for(@args) {
$vera_scanner->add_include_dir("user", $_);
$vera_scanner->add_include_dir("sys", $_);
}
Mpp/CommandParser/Vcs.pm view on Meta::CPAN
push @c_args, split;
} elsif(/^-l./) {
push @c_args, $_;
}
# TBD: What does -cm_name do?
elsif(/^-cm_(?:assert_hier|constfile|fsmcfg|hier|opfile|resetfilter|sigfile|stoppropagation|tglfile)$/ || /^-ova_(?:cov_hier|file)$/) {
my $file = shift @words;
$self->add_simple_dependency($file);
} elsif(/^(?:\+ad=|\+applylearn\+|\+optconfigfile\+|-Minclude=)(.*)/) {
$self->add_simple_dependency($1);
} elsif(/^-(?:vcd2vpd|vpd2vcd)$/) {
my $file = shift @words;
$self->add_simple_dependency($file);
$file = shift @words;
$self->add_target($file);
} elsif(/^-l$/) {
my $file = shift @words;
$self->add_target($file);
} elsif(/^\+vslogfile(?:sim)?\+(.*)/) {
$self->add_target($1);
} elsif(/^-C$/i) {
push @c_args, '-c';
} elsif(/^-o$/) {
push @c_args, $_, updir(shift @words);
}
}
require Mpp::Subs;
foreach (@Mpp::Subs::system_include_dirs) {
for my $tag ("user", "sys") {
$vera_scanner->add_include_dir( $tag, $_ );
}
}
for my $file (@libs) {
$scanner->scan_file($self, "vlib", $file) or return undef;
}
for my $file (@files) {
$scanner->scan_file($self, "vinc", $file) or return undef;
}
my $files_left = 1;
while($files_left) {
$files_left = $scanner->resolve($self) &&
$scanner->continue_scanning($self);
}
return undef unless defined($files_left);
for(@vera_files) {
$vera_scanner->scan_file($self, "vera", $_) or return undef;
}
if(@c_args) {
# Because some relative paths in @c_args are interpreted
# by VCS as being relative to the csrc subdirectory, we model
# that by having the scanner think that it's in that dir,
# but munge the @c_args that *aren't* relative to csrc before
# we get here.
Mpp::File::mark_as_directory file_info "csrc", $self->dirinfo;
require Mpp::CommandParser::Gcc;
my $c_parser=new_no_gcc Mpp::CommandParser::Gcc(
$self->rule, $self->dir."/csrc"
);
$c_parser->xparse_command([$cmd, @c_args], $setenv)
or return undef;
}
return 1;
}
1;
( run in 0.656 second using v1.01-cache-2.11-cpan-39bf76dae61 )