diff options
author | elliott_c <ocielliottc@users.noreply.github.com> | 2006-01-23 18:09:34 +0000 |
---|---|---|
committer | elliott_c <ocielliottc@users.noreply.github.com> | 2006-01-23 18:09:34 +0000 |
commit | a60b0950fa172677ce5256cd019b62d121c10d1a (patch) | |
tree | 1acbdf14e6fb17d03596d268ad19fada45c47d92 | |
parent | cd9923f4d781a89d66c7836d9e14172ac348ce2f (diff) | |
download | MPC-a60b0950fa172677ce5256cd019b62d121c10d1a.tar.gz |
ChangeLogTag: Mon Jan 23 12:08:25 2006 Chad Elliott <elliott_c@ociweb.com>
-rw-r--r-- | ChangeLog | 23 | ||||
-rw-r--r-- | modules/BMakeWorkspaceCreator.pm | 2 | ||||
-rw-r--r-- | modules/MakeWorkspaceCreator.pm | 2 | ||||
-rw-r--r-- | modules/NMakeWorkspaceCreator.pm | 2 | ||||
-rw-r--r-- | modules/VC6WorkspaceCreator.pm | 9 | ||||
-rw-r--r-- | modules/VC71WorkspaceCreator.pm | 9 | ||||
-rw-r--r-- | modules/VC7WorkspaceCreator.pm | 2 | ||||
-rw-r--r-- | modules/WorkspaceCreator.pm | 245 |
8 files changed, 187 insertions, 107 deletions
@@ -1,3 +1,26 @@ +Mon Jan 23 12:08:25 2006 Chad Elliott <elliott_c@ociweb.com> + + * modules/BMakeWorkspaceCreator.pm: + * modules/MakeWorkspaceCreator.pm: + * modules/NMakeWorkspaceCreator.pm: + + Tell the number_target_deps() method that we do not want sorting + by directory groups. + + * modules/VC6WorkspaceCreator.pm: + * modules/VC71WorkspaceCreator.pm: + * modules/VC7WorkspaceCreator.pm: + + No need to check for circular dependencies here, it is now done + when validating the dependencies. + + * modules/WorkspaceCreator.pm: + + Re-wrote the circular directory dependency detection code in order + to detect multi-directory (3 or more) dependencies. This slowed + things down a bit, so I had to find performance in other locations + throughout the workspace creator. + Thu Jan 19 12:59:55 2006 Chad Elliott <elliott_c@ociweb.com> * USAGE: diff --git a/modules/BMakeWorkspaceCreator.pm b/modules/BMakeWorkspaceCreator.pm index 0dc6874f..398db8a1 100644 --- a/modules/BMakeWorkspaceCreator.pm +++ b/modules/BMakeWorkspaceCreator.pm @@ -136,7 +136,7 @@ sub write_comps { my($projects) = $self->get_projects(); my($pjs) = $self->get_project_info(); my(%targnum) = (); - my(@list) = $self->number_target_deps($projects, $pjs, \%targnum); + my(@list) = $self->number_target_deps($projects, $pjs, \%targnum, 0); my($crlf) = $self->crlf(); my(@ltargets) = @targets; diff --git a/modules/MakeWorkspaceCreator.pm b/modules/MakeWorkspaceCreator.pm index 60b6f62a..8823513c 100644 --- a/modules/MakeWorkspaceCreator.pm +++ b/modules/MakeWorkspaceCreator.pm @@ -70,7 +70,7 @@ sub write_comps { my($trans) = $self->project_target_translation(1); my(%targnum) = (); my($pjs) = $self->get_project_info(); - my(@list) = $self->number_target_deps($projects, $pjs, \%targnum); + my(@list) = $self->number_target_deps($projects, $pjs, \%targnum, 0); ## Print out the "all" target print $fh $crlf . 'all:'; diff --git a/modules/NMakeWorkspaceCreator.pm b/modules/NMakeWorkspaceCreator.pm index 39f38c00..4d8b1cd2 100644 --- a/modules/NMakeWorkspaceCreator.pm +++ b/modules/NMakeWorkspaceCreator.pm @@ -133,7 +133,7 @@ sub write_comps { my($pjs) = $self->get_project_info(); my($trans) = $self->project_target_translation(); my(%targnum) = (); - my(@list) = $self->number_target_deps($projects, $pjs, \%targnum); + my(@list) = $self->number_target_deps($projects, $pjs, \%targnum, 0); my($crlf) = $self->crlf(); my($default) = 'Win32 Debug'; diff --git a/modules/VC6WorkspaceCreator.pm b/modules/VC6WorkspaceCreator.pm index f4a4d67b..c9fb7661 100644 --- a/modules/VC6WorkspaceCreator.pm +++ b/modules/VC6WorkspaceCreator.pm @@ -86,12 +86,9 @@ sub write_comps { if (defined $deps && $deps ne '') { my($darr) = $self->create_array($deps); foreach my $dep (@$darr) { - ## Avoid cirular dependencies - if ($name ne $dep) { - print $fh " Begin Project Dependency$crlf" . - " Project_Dep_Name $dep$crlf" . - " End Project Dependency$crlf"; - } + print $fh " Begin Project Dependency$crlf" . + " Project_Dep_Name $dep$crlf" . + " End Project Dependency$crlf"; } } diff --git a/modules/VC71WorkspaceCreator.pm b/modules/VC71WorkspaceCreator.pm index c3d28b8f..ff8a5063 100644 --- a/modules/VC71WorkspaceCreator.pm +++ b/modules/VC71WorkspaceCreator.pm @@ -54,12 +54,9 @@ sub print_inner_project { print $fh "\tProjectSection(ProjectDependencies) = postProject$crlf"; my($darr) = $self->create_array($deps); foreach my $dep (@$darr) { - ## Avoid cirular dependencies - if ($project_name ne $dep) { - my($guid) = $name_to_guid_map->{$dep}; - if (defined $guid) { - print $fh "\t\t{$guid} = {$guid}$crlf"; - } + my($guid) = $name_to_guid_map->{$dep}; + if (defined $guid) { + print $fh "\t\t{$guid} = {$guid}$crlf"; } } print $fh "\tEndProjectSection$crlf"; diff --git a/modules/VC7WorkspaceCreator.pm b/modules/VC7WorkspaceCreator.pm index 1454dfca..539b1530 100644 --- a/modules/VC7WorkspaceCreator.pm +++ b/modules/VC7WorkspaceCreator.pm @@ -117,7 +117,7 @@ sub print_dependencies { my($i) = 0; foreach my $dep (@$darr) { my($guid) = $name_to_guid_map{$dep}; - if (defined $guid && $guid ne $project_guid) { + if (defined $guid) { print $fh "\t\t{$project_guid}.$i = {$guid}$crlf"; $i++; } diff --git a/modules/WorkspaceCreator.pm b/modules/WorkspaceCreator.pm index 97a4645b..058c4c04 100644 --- a/modules/WorkspaceCreator.pm +++ b/modules/WorkspaceCreator.pm @@ -215,7 +215,7 @@ sub parse_line { $name =~ s/\s*\)$//; ## Replace any *'s with the default name - if ($name =~ /\*/) { + if (index($name, '*') >= 0) { $name = $self->fill_type_name( $name, $self->get_default_workspace_name()); @@ -386,7 +386,7 @@ sub parse_exclude { ## If there is a negation at all, add our ## current type, it may be removed below - if ($typestr =~ /!/) { + if (index($typestr, '!') >= 0) { $negated = 1; $types{$self->{wctype}} = 1; @@ -472,7 +472,7 @@ sub excluded { my($file) = shift; foreach my $excluded (@{$self->{'exclude'}->{$self->{'wctype'}}}) { - if ($excluded eq $file || $file =~ /^$excluded\//) { + if ($excluded eq $file || index($file, "$excluded/") == 0) { return 1; } } @@ -1255,7 +1255,7 @@ sub indirect_depdency { my($ccheck) = shift; my($cfile) = shift; - if ($self->{'project_info'}->{$ccheck}->[1] =~ /$cfile/) { + if (index($self->{'project_info'}->{$ccheck}->[1], $cfile) >= 0) { return 1; } else { @@ -1318,8 +1318,7 @@ sub add_implicit_project_dependencies { my($append) = $creator->translate_value('after', $key); my($file) = $self->{'project_file_list'}->{$ikey}->[0]; my($dir) = $self->{'project_file_list'}->{$ikey}->[1]; - my($cfile) = $self->escape_regex_special( - $creator->translate_value('after', $ikey)); + my($cfile) = $creator->translate_value('after', $ikey); ## Remove our starting directory from the projects directory ## to get the right part of the directory to prepend. $dir =~ s/^$cwd[\/\\]*//; @@ -1478,16 +1477,61 @@ sub sort_within_group { } +sub build_dependency_chain { + my($self) = shift; + my($name) = shift; + my($len) = shift; + my($list) = shift; + my($ni) = shift; + my($glen) = shift; + my($groups) = shift; + my($map) = shift; + my($gdeps) = shift; + my($deps) = $self->get_validated_ordering($name); + + if ($deps ne '') { + foreach my $dep (@{$self->create_array($deps)}) { + ## Find the item in the list that matches our current dependency + my($mapped) = $$map{$dep}; + for(my $i = 0; $i < $len; $i++) { + if ($$list[$i] eq $mapped) { + + ## Locate the group number to which the dependency belongs + for(my $j = 0; $j < $glen; $j++) { + if ($i >= $$groups[$j]->[0] && $i <= $$groups[$j]->[1]) { + + if ($j != $ni) { + ## Add every project in the group to the dependency chain + for(my $k = $$groups[$j]->[0]; $k <= $$groups[$j]->[1]; $k++) { + my($ldep) = basename($$list[$k]); + if (!exists $$gdeps{$ldep}) { + $$gdeps{$ldep} = 1; + $self->build_dependency_chain($$list[$k], + $len, $list, $j, + $glen, $groups, + $map, $gdeps); + } + } + } + last; + } + } + last; + } + } + + $$gdeps{$dep} = 1; + } + } +} + + sub sort_by_groups { my($self) = shift; my($list) = shift; my($grindex) = shift; my(@groups) = @$grindex; - my($ccount) = 0; - my($cmax) = $#groups; - my($prevgi) = -1; - my($prevgrs) = []; - my($movegrs) = []; + my($llen) = scalar(@$list); ## Check for duplicates first before we attempt to sort the groups. ## If there is a duplicate, we quietly return immediately. The @@ -1499,34 +1543,52 @@ sub sort_by_groups { if (defined $dupcheck{$base}) { return; } - $dupcheck{$base} = 1; + $dupcheck{$base} = $proj; } + my(%circular_checked) = (); for(my $gi = 0; $gi <= $#groups; ++$gi) { - ## If our moved group equals our previously moved group then - ## we count this as a possible circular dependency. - if (defined $$movegrs[0] && defined $$prevgrs[0] && - $$movegrs[0] == $$prevgrs[0] && $$movegrs[1] == $$prevgrs[1]) { - ++$ccount; - } - else { - $ccount = 0; - } - ## Detect circular dependencies - if ($ccount > $cmax) { - my(@dirs) = (); - foreach my $mvgr (@$movegrs) { - push(@dirs, $$list[$groups[$mvgr]->[0]]); - $dirs[$#dirs] =~ s/[\/\\].*//; + if (!$circular_checked{$gi}) { + $circular_checked{$gi} = 1; + for(my $i = $groups[$gi]->[0]; $i <= $groups[$gi]->[1]; ++$i) { + my(%gdeps) = (); + $self->build_dependency_chain($$list[$i], $llen, $list, $gi, + $#groups + 1, \@groups, + \%dupcheck, \%gdeps); + if (exists $gdeps{basename($$list[$i])}) { + ## There was a cirular dependency, get all of the directories + ## involved. + my(%dirs) = (); + foreach my $gdep (keys %gdeps) { + $dirs{dirname($dupcheck{$gdep})} = 1; + } + + ## If the current directory was involved, translate that into + ## a directory relative to the start directory. + if (defined $dirs{'.'}) { + my($cwd) = $self->getcwd(); + my($start) = $self->getstartdir(); + if ($cwd ne $start) { + my($startre) = $self->escape_regex_special($start); + delete $dirs{'.'}; + $cwd =~ s/^$startre[\\\/]//; + $dirs{$cwd} = 1; + } + } + + ## Display a warining to the user + my(@keys) = sort keys %dirs; + $self->warning('Circular directory dependency detected in the ' . + ($self->{'current_input'} eq '' ? + 'default' : $self->{'current_input'}) . + ' workspace. ' . + 'The following director' . + ($#keys == 0 ? 'y is' : 'ies are') . + ' involved: ' . join(', ', @keys)); + return; + } } - $self->warning('Circular dependency detected while processing the ' . - ($self->{'current_input'} eq '' ? - 'default' : $self->{'current_input'}) . - ' workspace. ' . - 'The following directories or projects are involved: ' . - join(' and ', @dirs)); - return; } ## Build up the group dependencies @@ -1535,26 +1597,15 @@ sub sort_by_groups { my($deps) = $self->get_validated_ordering($$list[$i]); if ($deps ne '') { my($darr) = $self->create_array($deps); - foreach my $dep (@$darr) { - $gdeps{$dep} = 1; - } + @gdeps{@$darr} = (); } } - ## Keep track of the previous group movement - $prevgrs = $movegrs; - if ($prevgi < $gi) { - $movegrs = []; - } - $prevgi = $gi; - ## Search the rest of the groups for any of the group dependencies - my($moved) = 0; for(my $gj = $gi + 1; $gj <= $#groups; ++$gj) { for(my $i = $groups[$gj]->[0]; $i <= $groups[$gj]->[1]; ++$i) { - if (defined $gdeps{basename($$list[$i])}) { + if (exists $gdeps{basename($$list[$i])}) { ## Move this group ($gj) in front of the current group ($gi) - $movegrs = [$gj, $gi]; my(@save) = (); for(my $j = $groups[$gi]->[1] + 1; $j <= $groups[$gj]->[1]; ++$j) { push(@save, $$list[$j]); @@ -1581,16 +1632,14 @@ sub sort_by_groups { } $groups[$gj] = \@grsave; - ## Signify that we have moved a group - $moved = 1; + ## Start over from the first group + $gi = -1; + + ## Exit from the outter ($gj) loop + $gj = $#groups; last; } } - if ($moved) { - ## Start over from the first group - $gi = -1; - last; - } } } } @@ -1599,38 +1648,49 @@ sub sort_by_groups { sub sort_dependencies { my($self) = shift; my($projects) = shift; + my($groups) = shift; my(@list) = sort { return $self->sort_projects_by_directory($a, $b) + 0; } @$projects; + ## The list above is sorted by directory in order to keep projects + ## within the same directory together. Otherwise, when groups are + ## created we may get multiple groups for the same directory. ## Put the projects in the order specified ## by the project dpendencies. We only need to do ## this if there is more than one element in the array. if ($#list > 0) { - ## First determine the individual groups - my(@grindex) = (); - my($previous) = [0, undef]; - for(my $li = 0; $li <= $#list; ++$li) { - my($dir) = $self->get_first_level_directory($list[$li]); - if (!defined $previous->[1]) { - $previous = [$li, $dir]; + ## If the parameter wasn't passed in or it was passed in + ## and was true, sort with directory groups in mind + if (!defined $groups || $groups) { + ## First determine the individual groups + my(@grindex) = (); + my($previous) = [0, undef]; + for(my $li = 0; $li <= $#list; ++$li) { + my($dir) = $self->get_first_level_directory($list[$li]); + if (!defined $previous->[1]) { + $previous = [$li, $dir]; + } + elsif ($previous->[1] ne $dir) { + push(@grindex, [$previous->[0], $li - 1]); + $previous = [$li, $dir]; + } } - elsif ($previous->[1] ne $dir) { - push(@grindex, [$previous->[0], $li - 1]); - $previous = [$li, $dir]; + push(@grindex, [$previous->[0], $#list]); + + ## Next, sort the individual groups + foreach my $gr (@grindex) { + if ($$gr[0] != $$gr[1]) { + $self->sort_within_group(\@list, @$gr); + } } - } - push(@grindex, [$previous->[0], $#list]); - ## Next, sort the individual groups - foreach my $gr (@grindex) { - if ($$gr[0] != $$gr[1]) { - $self->sort_within_group(\@list, @$gr); + ## Now sort the groups as single entities + if ($#grindex > 0) { + $self->sort_by_groups(\@list, \@grindex); } } - - ## Now sort the groups as single entities - if ($#grindex > 0) { - $self->sort_by_groups(\@list, \@grindex); + else { + $self->sort_within_group(\@list, 0, $#list); } } @@ -1643,7 +1703,8 @@ sub number_target_deps { my($projects) = shift; my($pjs) = shift; my($targets) = shift; - my(@list) = $self->sort_dependencies($projects); + my($groups) = shift; + my(@list) = $self->sort_dependencies($projects, $groups); ## This block of code must be done after the list of dependencies ## has been sorted in order to get the correct project numbers. @@ -1652,25 +1713,21 @@ sub number_target_deps { if (defined $$pjs{$project}) { my($name, $deps) = @{$$pjs{$project}}; if (defined $deps && $deps ne '') { - my(%targetnumbers) = (); - my($darr) = $self->create_array($deps); + my(@numbers) = (); + my(%dhash) = (); + @dhash{@{$self->create_array($deps)}} = (); ## For each dependency, search in the sorted list ## up to the point of this project for the projects ## that this one depends on. When the project is - ## found, we put the target number in a hash map (to avoid - ## duplicates). - foreach my $dep (@$darr) { - for(my $j = 0; $j < $i; ++$j) { - if (basename($list[$j]) eq $dep) { - $targetnumbers{$j} = 1; - } + ## found, we put the target number in the numbers array. + for(my $j = 0; $j < $i; ++$j) { + if (exists $dhash{basename($list[$j])}) { + push(@numbers, $j); } } - ## Get the keys of the hash map and store the - ## array in the hash keyed on the project file. - my(@numbers) = sort { $a <=> $b } keys %targetnumbers; + ## Store the array in the hash keyed on the project file. if (defined $numbers[0]) { $$targets{$project} = \@numbers; } @@ -1967,6 +2024,12 @@ sub get_validated_ordering { $deps =~ s/\s*"$reg"\s*/ /g; } } + else { + ## If a project references itself, we must remove it + ## from the list of dependencies. + my($reg) = $self->escape_regex_special($dep); + $deps =~ s/\s*"$reg"\s*/ /g; + } } $deps =~ s/^\s+//; @@ -1996,13 +2059,13 @@ sub sort_projects_by_directory { my($self) = shift; my($left) = shift; my($right) = shift; - my($sa) = ($left =~ /\//); - my($sb) = ($right =~ /\//); + my($sa) = index($left, '/'); + my($sb) = index($right, '/'); - if ($sa && !$sb) { + if ($sa >= 0 && $sb == -1) { return 1; } - elsif ($sb && !$sa) { + elsif ($sb >= 0 && $sa == -1) { return -1; } return $left cmp $right; |