📄 workspacecreator.pm
字号:
package WorkspaceCreator;
# ************************************************************
# Description : Base class for all workspace creators
# Author : Chad Elliott
# Create Date : 5/13/2002
# ************************************************************
# ************************************************************
# Pragmas
# ************************************************************
use strict;
use FileHandle;
use File::Path;
use File::Compare;
use File::Basename;
use Creator;
use Options;
use vars qw(@ISA);
@ISA = qw(Creator Options);
# ************************************************************
# Data Section
# ************************************************************
my($wsext) = 'mwc';
my($wsbase) = 'mwb';
## Valid names for assignments within a workspace
my(%validNames) = ('cmdline' => 1,
'implicit' => 1,
);
## Singleton hash maps of project information
my(%allprinfo) = ();
my(%allprojects) = ();
## Global previous workspace names
my(%previous_workspace_name) = ();
## Constant aggregated workspace type name
my($aggregated) = 'aggregated_workspace';
# ************************************************************
# Subroutine Section
# ************************************************************
sub new {
my($class) = shift;
my($global) = shift;
my($inc) = shift;
my($template) = shift;
my($ti) = shift;
my($dynamic) = shift;
my($static) = shift;
my($relative) = shift;
my($addtemp) = shift;
my($addproj) = shift;
my($progress) = shift;
my($toplevel) = shift;
my($baseprojs) = shift;
my($gfeature) = shift;
my($feature) = shift;
my($hierarchy) = shift;
my($exclude) = shift;
my($makeco) = shift;
my($nmod) = shift;
my($applypj) = shift;
my($genins) = shift;
my($self) = Creator::new($class, $global, $inc,
$template, $ti, $dynamic, $static,
$relative, $addtemp, $addproj,
$progress, $toplevel, $baseprojs,
$feature, $hierarchy, $nmod, $applypj,
'workspace');
$self->{'workspace_name'} = undef;
$self->{$self->{'type_check'}} = 0;
$self->{'projects'} = [];
$self->{'project_info'} = {};
$self->{'reading_parent'} = [];
$self->{'project_files'} = [];
$self->{'scoped_assign'} = {};
$self->{'cacheok'} = 1;
$self->{'exclude'} = {};
$self->{'wctype'} = $self->extractType("$self");
$self->{'modified_count'} = 0;
$self->{'global_feature_file'} = $gfeature;
$self->{'coexistence'} = $makeco;
$self->{'project_file_list'} = {};
$self->{'ordering_cache'} = {};
$self->{'handled_scopes'} = {};
$self->{'generate_ins'} = $genins;
if (defined $$exclude[0]) {
my($type) = $self->{'wctype'};
if (!defined $self->{'exclude'}->{$type}) {
$self->{'exclude'}->{$type} = [];
}
push(@{$self->{'exclude'}->{$type}}, @$exclude);
}
## Add a hash reference for our workspace type
if (!defined $previous_workspace_name{$self->{'wctype'}}) {
$previous_workspace_name{$self->{'wctype'}} = {};
}
return $self;
}
sub modify_assignment_value {
my($self) = shift;
my($value) = shift;
## Workspace assignments do not need modification.
return $value;
}
sub parse_line {
my($self) = shift;
my($ih) = shift;
my($line) = shift;
my($status, $error, @values) = $self->parse_known($line);
## Was the line recognized?
if ($status && defined $values[0]) {
if ($values[0] eq $self->{'grammar_type'}) {
my($name) = $values[1];
if (defined $name && $name eq '}') {
if (!defined $self->{'reading_parent'}->[0]) {
## Fill in all the default values
$self->generate_defaults();
## End of workspace; Have subclass write out the file
## Generate the project files
my($gstat, $creator) = $self->generate_project_files();
if ($gstat) {
($status, $error) = $self->write_workspace($creator, 1);
$self->{'assign'} = {};
}
else {
$error = 'Unable to generate all of the project files';
$status = 0;
}
$self->{'modified_count'} = 0;
$self->{'workspace_name'} = undef;
$self->{'projects'} = [];
$self->{'project_info'} = {};
$self->{'project_files'} = [];
}
$self->{$self->{'type_check'}} = 0;
}
else {
## Workspace Beginning
## Deal with the inheritance hiearchy first
if (defined $values[2]) {
foreach my $parent (@{$values[2]}) {
## Read in the parent onto ourself
my($file) = $self->search_include_path("$parent.$wsbase");
if (!defined $file) {
$file = $self->search_include_path("$parent.$wsext");
}
if (defined $file) {
push(@{$self->{'reading_parent'}}, 1);
$status = $self->parse_file($file);
pop(@{$self->{'reading_parent'}});
if (!$status) {
$error = "Invalid parent: $parent";
}
}
else {
$status = 0;
$error = "Unable to locate parent: $parent";
}
}
}
## Set up some initial values
if (defined $name) {
if ($name =~ /[\/\\]/) {
$status = 0;
$error = 'Workspaces can not have a slash ' .
'or a back slash in the name';
}
else {
$name =~ s/^\(\s*//;
$name =~ s/\s*\)$//;
## Replace any *'s with the default name
my($def) = $self->get_default_workspace_name();
$name = $self->fill_type_name($name, $def);
$self->{'workspace_name'} = $name;
}
}
$self->{$self->{'type_check'}} = 1;
}
}
elsif ($values[0] eq 'assignment') {
if (defined $validNames{$values[1]}) {
$self->process_assignment($values[1], $values[2]);
}
else {
$error = "Invalid assignment name: $values[1]";
$status = 0;
}
}
elsif ($values[0] eq 'assign_add') {
if (defined $validNames{$values[1]}) {
$self->process_assignment_add($values[1], $values[2]);
}
else {
$error = "Invalid addition name: $values[1]";
$status = 0;
}
}
elsif ($values[0] eq 'assign_sub') {
if (defined $validNames{$values[1]}) {
$self->process_assignment_sub($values[1], $values[2]);
}
else {
$error = "Invalid subtraction name: $values[1]";
$status = 0;
}
}
elsif ($values[0] eq 'component') {
if ($values[1] eq 'exclude') {
($status, $error) = $self->parse_exclude($ih, $values[2]);
}
else {
($status, $error) = $self->parse_scope($ih,
$values[1],
$values[2],
\%validNames);
}
}
else {
$error = "Unrecognized line: $line";
$status = 0;
}
}
elsif ($status == -1) {
if ($line =~ /\.$wsext$/) {
($status, $error) = $self->aggregated_workspace($line);
}
else {
push(@{$self->{'project_files'}}, $line);
$status = 1;
}
}
return $status, $error;
}
sub aggregated_workspace {
my($self) = shift;
my($file) = shift;
my($fh) = new FileHandle();
if (open($fh, $file)) {
my($oline) = $self->get_line_number();
my($tc) = $self->{$self->{'type_check'}};
my($ag) = $self->{'handled_scopes'}->{$aggregated};
my($psbd) = $self->{'scoped_basedir'};
my($status, $error, @values) = (0, 'No recognizable lines');
$self->{'handled_scopes'}->{$aggregated} = undef;
$self->set_line_number(0);
$self->{$self->{'type_check'}} = 0;
$self->{'scoped_basedir'} = dirname($file);
while(<$fh>) {
my($line) = $self->preprocess_line($fh, $_);
($status, $error, @values) = $self->parse_known($line);
## Was the line recognized?
if ($status) {
if (defined $values[0]) {
if ($values[0] eq $self->{'grammar_type'}) {
if (defined $values[2]) {
my($name) = basename($file);
$name =~ s/\.[^\.]+$//;
$status = 0;
$error = 'Aggregated workspace (' . $name .
') can not inherit from another workspace';
}
else {
($status, $error) = $self->parse_scope($fh,
'',
$aggregated,
\%validNames);
}
}
else {
$status = 0;
$error = 'Unable to aggregate ' . $file;
}
last;
}
}
else {
last;
}
}
close($fh);
$self->{'scoped_basedir'} = $psbd;
$self->{'handled_scopes'}->{$aggregated} = $ag;
$self->{$self->{'type_check'}} = $tc;
$self->set_line_number($oline);
return $status, $error;
}
return 0, 'Unable to open ' . $file;
}
sub parse_exclude {
my($self) = shift;
my($fh) = shift;
my($typestr) = shift;
my($status) = 0;
my($errorString) = 'Unable to process exclude';
if ($typestr eq $self->get_default_component_name()) {
$typestr = $self->{'wctype'};
}
my(@types) = split(/\s*,\s*/, $typestr);
my(@exclude) = ();
while(<$fh>) {
my($line) = $self->preprocess_line($fh, $_);
if ($line eq '') {
}
elsif ($line =~ /^}/) {
$status = 1;
$errorString = undef;
last;
}
else {
push(@exclude, $line);
}
}
foreach my $type (@types) {
if (!defined $self->{'exclude'}->{$type}) {
$self->{'exclude'}->{$type} = [];
}
push(@{$self->{'exclude'}->{$type}}, @exclude);
}
return $status, $errorString;
}
sub excluded {
my($self) = shift;
my($file) = shift;
foreach my $excluded (@{$self->{'exclude'}->{$self->{'wctype'}}}) {
if ($excluded eq $file || $file =~ /$excluded\//) {
return 1;
}
}
return 0;
}
sub handle_scoped_end {
my($self) = shift;
my($type) = shift;
my($flags) = shift;
my($status) = 1;
my($error) = undef;
if ($type eq $aggregated &&
!defined $self->{'handled_scopes'}->{$type}) {
## Replace instances of $PWD with the current directory plus the
## scoped_basedir. We have to do it now otherwise, $PWD will be the
## wrong directory if it's done later.
if (defined $$flags{'cmdline'}) {
my($dir) = $self->getcwd() . '/' . $self->{'scoped_basedir'};
$$flags{'cmdline'} =~ s/\$PWD(\W)/$dir$1/g;
$$flags{'cmdline'} =~ s/\$PWD$/$dir/;
}
## Go back to the previous directory and add the directory contents
($status, $error) = $self->handle_scoped_unknown($type, $flags, '.');
}
$self->{'handled_scopes'}->{$type} = undef;
return $status, $error;
}
sub handle_scoped_unknown {
my($self) = shift;
my($type) = shift;
my($flags) = shift;
my($line) = shift;
my($status) = 1;
my($error) = undef;
my($dupchk) = undef;
if ($type eq $aggregated) {
$line = $self->{'scoped_basedir'} . ($line ne '.' ? "/$line" : '');
my(%dup) = ();
@dup{@{$self->{'project_files'}}} = ();
$dupchk = \%dup;
}
if (-d $line) {
my(@files) = ();
$self->search_for_files([ $line ], \@files, $$flags{'implicit'});
## If we are generating implicit projects within a scope, then
## we need to remove directories and the parent directories for which
## there is an mpc file. Otherwise, the projects will be added
## twice.
if ($$flags{'implicit'}) {
my(%remove) = ();
foreach my $file (@files) {
if ($file =~ /\.mpc$/) {
my($exc) = $file;
do {
$exc = dirname($exc);
$remove{$exc} = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -