Subversion Repositories gelsvn

Rev

Rev 198 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 198 Rev 217
Line 12... Line 12...
12
 
12
 
13
use strict;
13
use strict;
14
use FileHandle;
14
use FileHandle;
15
use File::Path;
15
use File::Path;
16
use File::Compare;
16
use File::Compare;
17
use File::Basename;
-
 
18
 
17
 
19
use Creator;
18
use Creator;
20
use Options;
19
use Options;
21
 
20
 
22
use vars qw(@ISA);
21
use vars qw(@ISA);
Line 213... Line 212...
213
          else {
212
          else {
214
            $name =~ s/^\(\s*//;
213
            $name =~ s/^\(\s*//;
215
            $name =~ s/\s*\)$//;
214
            $name =~ s/\s*\)$//;
216
 
215
 
217
            ## Replace any *'s with the default name
216
            ## Replace any *'s with the default name
218
            if ($name =~ /\*/) {
217
            if (index($name, '*') >= 0) {
219
              $name = $self->fill_type_name(
218
              $name = $self->fill_type_name(
220
                                    $name,
219
                                    $name,
221
                                    $self->get_default_workspace_name());
220
                                    $self->get_default_workspace_name());
222
            }
221
            }
223
 
222
 
Line 225... Line 224...
225
          }
224
          }
226
        }
225
        }
227
        $self->{$self->{'type_check'}} = 1;
226
        $self->{$self->{'type_check'}} = 1;
228
      }
227
      }
229
    }
228
    }
230
    elsif ($values[0] eq 'assignment') {
229
    elsif ($values[0] eq '=') {
231
      if (defined $validNames{$values[1]}) {
230
      if (defined $validNames{$values[1]}) {
232
        $self->process_assignment($values[1], $values[2]);
231
        $self->process_assignment($values[1], $values[2]);
233
      }
232
      }
234
      else {
233
      else {
235
        $error = "Invalid assignment name: $values[1]";
234
        $error = "Invalid assignment name: $values[1]";
236
        $status = 0;
235
        $status = 0;
237
      }
236
      }
238
    }
237
    }
239
    elsif ($values[0] eq 'assign_add') {
238
    elsif ($values[0] eq '+=') {
240
      if (defined $validNames{$values[1]}) {
239
      if (defined $validNames{$values[1]}) {
241
        $self->process_assignment_add($values[1], $values[2]);
240
        $self->process_assignment_add($values[1], $values[2]);
242
      }
241
      }
243
      else {
242
      else {
244
        $error = "Invalid addition name: $values[1]";
243
        $error = "Invalid addition name: $values[1]";
245
        $status = 0;
244
        $status = 0;
246
      }
245
      }
247
    }
246
    }
248
    elsif ($values[0] eq 'assign_sub') {
247
    elsif ($values[0] eq '-=') {
249
      if (defined $validNames{$values[1]}) {
248
      if (defined $validNames{$values[1]}) {
250
        $self->process_assignment_sub($values[1], $values[2]);
249
        $self->process_assignment_sub($values[1], $values[2]);
251
      }
250
      }
252
      else {
251
      else {
253
        $error = "Invalid subtraction name: $values[1]";
252
        $error = "Invalid subtraction name: $values[1]";
Line 264... Line 263...
264
      $error = "Unrecognized line: $line";
263
      $error = "Unrecognized line: $line";
265
      $status = 0;
264
      $status = 0;
266
    }
265
    }
267
  }
266
  }
268
  elsif ($status == -1) {
267
  elsif ($status == -1) {
-
 
268
    foreach my $expfile ($line =~ /[\?\*\[\]]/ ? $self->mpc_glob($line) :
-
 
269
                                                 $line) {
269
    if ($line =~ /\.$wsext$/) {
270
      if ($expfile =~ /\.$wsext$/) {
270
      ($status, $error) = $self->aggregated_workspace($line);
271
        ($status, $error) = $self->aggregated_workspace($expfile);
-
 
272
        last if (!$status);
271
    }
273
      }
272
    else {
274
      else {
273
      push(@{$self->{'project_files'}}, $line);
275
        push(@{$self->{'project_files'}}, $expfile);
274
      $status = 1;
276
        $status = 1;
-
 
277
      }
275
    }
278
    }
276
  }
279
  }
277
 
280
 
278
  return $status, $error;
281
  return $status, $error;
279
}
282
}
Line 303... Line 306...
303
      ## Was the line recognized?
306
      ## Was the line recognized?
304
      if ($status) {
307
      if ($status) {
305
        if (defined $values[0]) {
308
        if (defined $values[0]) {
306
          if ($values[0] eq $self->{'grammar_type'}) {
309
          if ($values[0] eq $self->{'grammar_type'}) {
307
            if (defined $values[2]) {
310
            if (defined $values[2]) {
308
              my($name) = basename($file);
311
              my($name) = $self->mpc_basename($file);
309
              $name =~ s/\.[^\.]+$//;
312
              $name =~ s/\.[^\.]+$//;
310
              $status = 0;
313
              $status = 0;
311
              $error  = 'Aggregated workspace (' . $name .
314
              $error  = 'Aggregated workspace (' . $name .
312
                        ') can not inherit from another workspace';
315
                        ') can not inherit from another workspace';
313
            }
316
            }
Line 384... Line 387...
384
  my(%types)   = ();
387
  my(%types)   = ();
385
  @types{split(/\s*,\s*/, $typestr)} = ();
388
  @types{split(/\s*,\s*/, $typestr)} = ();
386
 
389
 
387
  ## If there is a negation at all, add our
390
  ## If there is a negation at all, add our
388
  ## current type, it may be removed below
391
  ## current type, it may be removed below
389
  if ($typestr =~ /!/) {
392
  if (index($typestr, '!') >= 0) {
390
    $negated = 1;
393
    $negated = 1;
391
    $types{$self->{wctype}} = 1;
394
    $types{$self->{wctype}} = 1;
392
 
395
 
393
    ## Process negated exclusions
396
    ## Process negated exclusions
394
    foreach my $key (keys %types) {
397
    foreach my $key (keys %types) {
Line 418... Line 421...
418
          $errorString = undef;
421
          $errorString = undef;
419
        }
422
        }
420
        last;
423
        last;
421
      }
424
      }
422
      else {
425
      else {
-
 
426
        if ($line =~ /^"([^"]+)"$/) {
-
 
427
          $line = $1;
-
 
428
        }
423
        if (defined $self->{'scoped_basedir'}) {
429
        if (defined $self->{'scoped_basedir'}) {
424
          $line = $self->{'scoped_basedir'} . '/' . $line;
430
          $line = $self->{'scoped_basedir'} . '/' . $line;
425
        }
431
        }
-
 
432
        if ($line =~ /[\?\*\[\]]/) {
-
 
433
          push(@exclude, $self->mpc_glob($line));
-
 
434
        }
-
 
435
        else {
426
        push(@exclude, $line);
436
          push(@exclude, $line);
-
 
437
        }
427
      }
438
      }
428
    }
439
    }
429
 
440
 
430
    foreach my $type (keys %types) {
441
    foreach my $type (keys %types) {
431
      if (!defined $self->{'exclude'}->{$type}) {
442
      if (!defined $self->{'exclude'}->{$type}) {
Line 470... Line 481...
470
sub excluded {
481
sub excluded {
471
  my($self) = shift;
482
  my($self) = shift;
472
  my($file) = shift;
483
  my($file) = shift;
473
 
484
 
474
  foreach my $excluded (@{$self->{'exclude'}->{$self->{'wctype'}}}) {
485
  foreach my $excluded (@{$self->{'exclude'}->{$self->{'wctype'}}}) {
475
    if ($excluded eq $file || $file =~ /^$excluded\//) {
486
    if ($excluded eq $file || index($file, "$excluded/") == 0) {
476
      return 1;
487
      return 1;
477
    }
488
    }
478
  }
489
  }
479
 
490
 
480
  return 0;
491
  return 0;
Line 581... Line 592...
581
        }
592
        }
582
      }
593
      }
583
    }
594
    }
584
  }
595
  }
585
  else {
596
  else {
-
 
597
    foreach my $expfile ($line =~ /[\?\*\[\]]/ ? $self->mpc_glob($line) :
-
 
598
                                                 $line) {
586
    if ($line =~ /\.$wsext$/) {
599
      if ($expfile =~ /\.$wsext$/) {
587
      ## An aggregated workspace within an aggregated workspace.
600
        ## An aggregated workspace within an aggregated workspace.
588
      ($status, $error) = $self->aggregated_workspace($line);
601
        ($status, $error) = $self->aggregated_workspace($expfile);
-
 
602
        last if (!$status);
589
    }
603
      }
590
    else {
604
      else {
591
      if (!$self->excluded($line)) {
605
        if (!$self->excluded($expfile)) {
592
        if (defined $dupchk && exists $$dupchk{$line}) {
606
          if (defined $dupchk && exists $$dupchk{$expfile}) {
593
          $self->warning("Duplicate mpc file ($line) added by an " .
607
            $self->warning("Duplicate mpc file ($expfile) added by an " .
594
                         'aggregate workspace.  It will be ignored.');
608
                           'aggregate workspace.  It will be ignored.');
595
        }
609
          }
596
        else {
610
          else {
597
          $self->{'scoped_assign'}->{$line} = $flags;
611
            $self->{'scoped_assign'}->{$expfile} = $flags;
598
          push(@{$self->{'project_files'}}, $line);
612
            push(@{$self->{'project_files'}}, $expfile);
-
 
613
          }
599
        }
614
        }
600
      }
615
      }
601
    }
616
    }
602
  }
617
  }
603
  $self->{'handled_scopes'}->{$type} = 1;
618
  $self->{'handled_scopes'}->{$type} = 1;
Line 605... Line 620...
605
  return $status, $error;
620
  return $status, $error;
606
}
621
}
607
 
622
 
608
 
623
 
609
sub search_for_files {
624
sub search_for_files {
610
  my($self)  = shift;
625
  my($self)     = shift;
611
  my($files) = shift;
626
  my($files)    = shift;
612
  my($array) = shift;
627
  my($array)    = shift;
613
  my($impl)  = shift;
628
  my($impl)     = shift;
-
 
629
  my($excluded) = 0;
614
 
630
 
615
  foreach my $file (@$files) {
631
  foreach my $file (@$files) {
616
    if (-d $file) {
632
    if (-d $file) {
617
      my(@f) = $self->generate_default_file_list(
633
      my(@f) = $self->generate_default_file_list(
618
                         $file,
634
                         $file,
619
                         $self->{'exclude'}->{$self->{'wctype'}});
635
                         $self->{'exclude'}->{$self->{'wctype'}},
-
 
636
                         \$excluded);
620
      $self->search_for_files(\@f, $array, $impl);
637
      $self->search_for_files(\@f, $array, $impl);
621
      if ($impl) {
638
      if ($impl) {
622
        $file =~ s/^\.\///;
639
        $file =~ s/^\.\///;
623
        unshift(@$array, $file);
640
        unshift(@$array, $file);
624
      }
641
      }
Line 628... Line 645...
628
        $file =~ s/^\.\///;
645
        $file =~ s/^\.\///;
629
        unshift(@$array, $file);
646
        unshift(@$array, $file);
630
      }
647
      }
631
    }
648
    }
632
  }
649
  }
-
 
650
 
-
 
651
  return $excluded;
633
}
652
}
634
 
653
 
635
 
654
 
636
sub remove_duplicate_projects {
655
sub remove_duplicate_projects {
637
  my($self)  = shift;
656
  my($self)  = shift;
Line 639... Line 658...
639
  my($count) = scalar(@$list);
658
  my($count) = scalar(@$list);
640
 
659
 
641
  for(my $i = 0; $i < $count; ++$i) {
660
  for(my $i = 0; $i < $count; ++$i) {
642
    my($file) = $$list[$i];
661
    my($file) = $$list[$i];
643
    foreach my $inner (@$list) {
662
    foreach my $inner (@$list) {
-
 
663
      if ($file ne $inner &&
644
      if ($file ne $inner && $file eq $self->mpc_dirname($inner) && ! -d $inner) {
664
          $file eq $self->mpc_dirname($inner) && ! -d $inner) {
645
        splice(@$list, $i, 1);
665
        splice(@$list, $i, 1);
646
        --$count;
666
        --$count;
647
        --$i;
667
        --$i;
648
        last;
668
        last;
649
      }
669
      }
Line 651... Line 671...
651
  }
671
  }
652
}
672
}
653
 
673
 
654
 
674
 
655
sub generate_default_components {
675
sub generate_default_components {
656
  my($self)  = shift;
676
  my($self)     = shift;
657
  my($files) = shift;
677
  my($files)    = shift;
658
  my($impl)  = shift;
678
  my($impl)     = shift;
-
 
679
  my($excluded) = shift;
659
  my($pjf)   = $self->{'project_files'};
680
  my($pjf)      = $self->{'project_files'};
660
 
681
 
661
  if (defined $$pjf[0]) {
682
  if (defined $$pjf[0]) {
662
    ## If we have files, then process directories
683
    ## If we have files, then process directories
663
    my(@built) = ();
684
    my(@built) = ();
664
    foreach my $file (@$pjf) {
685
    foreach my $file (@$pjf) {
Line 690... Line 711...
690
    $self->{'project_files'} = \@built;
711
    $self->{'project_files'} = \@built;
691
  }
712
  }
692
  else {
713
  else {
693
    ## Add all of the wanted files in this directory
714
    ## Add all of the wanted files in this directory
694
    ## and in the subdirectories.
715
    ## and in the subdirectories.
695
    $self->search_for_files($files, $pjf, $impl);
716
    $excluded |= $self->search_for_files($files, $pjf, $impl);
696
 
717
 
697
    ## If the workspace is set to implicit
718
    ## If the workspace is set to implicit
698
    if ($impl) {
719
    if ($impl) {
699
      ## Remove duplicates from this list
720
      ## Remove duplicates from this list
700
      $self->remove_duplicate_projects($pjf);
721
      $self->remove_duplicate_projects($pjf);
701
    }
722
    }
702
 
723
 
703
    ## If no files were found, then we push the empty
724
    ## If no files were found, then we push the empty
704
    ## string, so the Project Creator will generate
725
    ## string, so the Project Creator will generate
705
    ## the default project file.
726
    ## the default project file.
706
    if (!defined $$pjf[0]) {
727
    if (!defined $$pjf[0] && !$excluded) {
707
      push(@$pjf, '');
728
      push(@$pjf, '');
708
    }
729
    }
709
  }
730
  }
710
}
731
}
711
 
732
 
Line 736... Line 757...
736
  ## Generate default workspace name
757
  ## Generate default workspace name
737
  if (!defined $self->{'workspace_name'}) {
758
  if (!defined $self->{'workspace_name'}) {
738
    $self->{'workspace_name'} = $self->get_default_workspace_name();
759
    $self->{'workspace_name'} = $self->get_default_workspace_name();
739
  }
760
  }
740
 
761
 
-
 
762
  ## Modify the exclude list if we have changed directory from the original
-
 
763
  ## starting directory.  Just take off the difference from the front.
-
 
764
  my(@original) = ();
-
 
765
  my($top)      = $self->getcwd() . '/';
-
 
766
  my($start)    = $self->getstartdir() . '/';
-
 
767
 
-
 
768
  if ($start ne $top && $top =~ s/^$start//) {
-
 
769
    foreach my $exclude (@{$self->{'exclude'}->{$self->{'wctype'}}}) {
-
 
770
      push(@original, $exclude);
-
 
771
      $exclude =~ s/^$top//;
-
 
772
    }
-
 
773
  }
-
 
774
 
-
 
775
  my($excluded) = 0;
741
  my(@files) = $self->generate_default_file_list(
776
  my(@files) = $self->generate_default_file_list(
742
                        '.',
777
                        '.',
743
                        $self->{'exclude'}->{$self->{'wctype'}});
778
                        $self->{'exclude'}->{$self->{'wctype'}},
-
 
779
                        \$excluded);
744
 
780
 
745
  ## Generate default components
781
  ## Generate default components
746
  $self->generate_default_components(\@files,
782
  $self->generate_default_components(\@files,
747
                                     $self->get_assignment('implicit'));
783
                                     $self->get_assignment('implicit'),
-
 
784
                                     $excluded);
-
 
785
 
-
 
786
  ## Return the actual exclude list of we modified it
-
 
787
  if (defined $original[0]) {
-
 
788
    $self->{'exclude'}->{$self->{'wctype'}} = \@original;
-
 
789
  }
748
}
790
}
749
 
791
 
750
 
792
 
751
sub get_workspace_name {
793
sub get_workspace_name {
752
  my($self) = shift;
794
  my($self) = shift;
Line 783... Line 825...
783
      foreach my $project (@{$self->{'projects'}}) {
825
      foreach my $project (@{$self->{'projects'}}) {
784
        my($name) = lc($self->{'project_info'}->{$project}->[0]);
826
        my($name) = lc($self->{'project_info'}->{$project}->[0]);
785
        if (defined $names{$name}) {
827
        if (defined $names{$name}) {
786
          ++$duplicates;
828
          ++$duplicates;
787
          $self->error("Duplicate case-insensitive project '$name'. " .
829
          $self->error("Duplicate case-insensitive project '$name'. " .
788
                       "Look in " . $self->mpc_dirname($project) . " and " .
830
                       "Look in " . $self->mpc_dirname($project) .
789
                       $self->mpc_dirname($names{$name}) .
831
                       " and " . $self->mpc_dirname($names{$name}) .
790
                       " for project name conflicts.");
832
                       " for project name conflicts.");
791
        }
833
        }
792
        else {
834
        else {
793
          $names{$name} = $project;
835
          $names{$name} = $project;
794
        }
836
        }
Line 1100... Line 1142...
1100
          $gen_proj_info = $allprinfo{$prkey};
1142
          $gen_proj_info = $allprinfo{$prkey};
1101
          $gen_lib_locs  = $allliblocs{$prkey};
1143
          $gen_lib_locs  = $allliblocs{$prkey};
1102
          $status = 1;
1144
          $status = 1;
1103
        }
1145
        }
1104
        else {
1146
        else {
1105
          $status = $creator->generate(basename($file));
1147
          $status = $creator->generate($self->mpc_basename($file));
1106
 
1148
 
1107
          ## If any one project file fails, then stop
1149
          ## If any one project file fails, then stop
1108
          ## processing altogether.
1150
          ## processing altogether.
1109
          if (!$status) {
1151
          if (!$status) {
1110
            ## We don't restore the state before we leave,
1152
            ## We don't restore the state before we leave,
Line 1227... Line 1269...
1227
  my($self)   = shift;
1269
  my($self)   = shift;
1228
  my($dir)    = shift;
1270
  my($dir)    = shift;
1229
  my($ccheck) = shift;
1271
  my($ccheck) = shift;
1230
  my($cfile)  = shift;
1272
  my($cfile)  = shift;
1231
 
1273
 
1232
  if ($self->{'project_info'}->{$ccheck}->[1] =~ /$cfile/) {
1274
  if (index($self->{'project_info'}->{$ccheck}->[1], $cfile) >= 0) {
1233
    return 1;
1275
    return 1;
1234
  }
1276
  }
1235
  else {
1277
  else {
1236
    my($deps) = $self->create_array(
1278
    my($deps) = $self->create_array(
1237
                         $self->{'project_info'}->{$ccheck}->[1]);
1279
                         $self->{'project_info'}->{$ccheck}->[1]);
Line 1290... Line 1332...
1290
            $bidir{$key} = [$ikey];
1332
            $bidir{$key} = [$ikey];
1291
          }
1333
          }
1292
          my($append) = $creator->translate_value('after', $key);
1334
          my($append) = $creator->translate_value('after', $key);
1293
          my($file)   = $self->{'project_file_list'}->{$ikey}->[0];
1335
          my($file)   = $self->{'project_file_list'}->{$ikey}->[0];
1294
          my($dir)    = $self->{'project_file_list'}->{$ikey}->[1];
1336
          my($dir)    = $self->{'project_file_list'}->{$ikey}->[1];
1295
          my($cfile)  = $self->escape_regex_special(
-
 
1296
                              $creator->translate_value('after', $ikey));
1337
          my($cfile)  = $creator->translate_value('after', $ikey);
1297
          ## Remove our starting directory from the projects directory
1338
          ## Remove our starting directory from the projects directory
1298
          ## to get the right part of the directory to prepend.
1339
          ## to get the right part of the directory to prepend.
1299
          $dir =~ s/^$cwd[\/\\]*//;
1340
          $dir =~ s/^$cwd[\/\\]*//;
1300
 
1341
 
1301
          ## Turn the append value into a key for 'project_info' and
1342
          ## Turn the append value into a key for 'project_info' and
Line 1415... Line 1456...
1415
      $movepjs = [];
1456
      $movepjs = [];
1416
    }
1457
    }
1417
    $previ = $i;
1458
    $previ = $i;
1418
 
1459
 
1419
    $deps = $self->get_validated_ordering($$list[$i]);
1460
    $deps = $self->get_validated_ordering($$list[$i]);
1420
    if ($deps ne '') {
1461
    if (defined $$deps[0]) {
1421
      my($baseproj) = basename($$list[$i]);
1462
      my($baseproj) = $self->mpc_basename($$list[$i]);
1422
      my($darr) = $self->create_array($deps);
-
 
1423
 
-
 
1424
      my($moved) = 0;
1463
      my($moved) = 0;
1425
      foreach my $dep (@$darr) {
1464
      foreach my $dep (@$deps) {
1426
        if ($baseproj ne $dep) {
1465
        if ($baseproj ne $dep) {
1427
          ## See if the dependency is listed after this project
1466
          ## See if the dependency is listed after this project
1428
          for(my $j = $i + 1; $j <= $end; ++$j) {
1467
          for(my $j = $i + 1; $j <= $end; ++$j) {
1429
            if (basename($$list[$j]) eq $dep) {
1468
            if ($self->mpc_basename($$list[$j]) eq $dep) {
1430
              $movepjs = [$i, $j];
1469
              $movepjs = [$i, $j];
1431
              ## If so, move it in front of the current project.
1470
              ## If so, move it in front of the current project.
1432
              ## The original code, which had splices, didn't always
1471
              ## The original code, which had splices, didn't always
1433
              ## work correctly (especially on AIX for some reason).
1472
              ## work correctly (especially on AIX for some reason).
1434
              my($save) = $$list[$j];
1473
              my($save) = $$list[$j];
Line 1450... Line 1489...
1450
    }
1489
    }
1451
  }
1490
  }
1452
}
1491
}
1453
 
1492
 
1454
 
1493
 
-
 
1494
sub build_dependency_chain {
-
 
1495
  my($self)   = shift;
-
 
1496
  my($name)   = shift;
-
 
1497
  my($len)    = shift;
-
 
1498
  my($list)   = shift;
-
 
1499
  my($ni)     = shift;
-
 
1500
  my($glen)   = shift;
-
 
1501
  my($groups) = shift;
-
 
1502
  my($map)    = shift;
-
 
1503
  my($gdeps)  = shift;
-
 
1504
  my($deps)   = $self->get_validated_ordering($name);
-
 
1505
 
-
 
1506
  if (defined $$deps[0]) {
-
 
1507
    foreach my $dep (@$deps) {
-
 
1508
      ## Find the item in the list that matches our current dependency
-
 
1509
      my($mapped) = $$map{$dep};
-
 
1510
      for(my $i = 0; $i < $len; $i++) {
-
 
1511
        if ($$list[$i] eq $mapped) {
-
 
1512
 
-
 
1513
          ## Locate the group number to which the dependency belongs
-
 
1514
          for(my $j = 0; $j < $glen; $j++) {
-
 
1515
            if ($i >= $$groups[$j]->[0] && $i <= $$groups[$j]->[1]) {
-
 
1516
 
-
 
1517
              if ($j != $ni) {
-
 
1518
                ## Add every project in the group to the dependency chain
-
 
1519
                for(my $k = $$groups[$j]->[0]; $k <= $$groups[$j]->[1]; $k++) {
-
 
1520
                  my($ldep) = $self->mpc_basename($$list[$k]);
-
 
1521
                  if (!exists $$gdeps{$ldep}) {
-
 
1522
                    $$gdeps{$ldep} = 1;
-
 
1523
                    $self->build_dependency_chain($$list[$k],
-
 
1524
                                                  $len, $list, $j,
-
 
1525
                                                  $glen, $groups,
-
 
1526
                                                  $map, $gdeps);
-
 
1527
                  }
-
 
1528
                }
-
 
1529
              }
-
 
1530
              last;
-
 
1531
            }
-
 
1532
          }
-
 
1533
          last;
-
 
1534
        }
-
 
1535
      }
-
 
1536
 
-
 
1537
      $$gdeps{$dep} = 1;
-
 
1538
    }
-
 
1539
  }
-
 
1540
}
-
 
1541
 
-
 
1542
 
1455
sub sort_by_groups {
1543
sub sort_by_groups {
1456
  my($self)    = shift;
1544
  my($self)    = shift;
1457
  my($list)    = shift;
1545
  my($list)    = shift;
1458
  my($grindex) = shift;
1546
  my($grindex) = shift;
1459
  my(@groups)  = @$grindex;
1547
  my(@groups)  = @$grindex;
1460
  my($ccount)  = 0;
-
 
1461
  my($cmax)    = $#groups;
1548
  my($llen)    = scalar(@$list);
1462
  my($prevgi)  = -1;
-
 
1463
  my($prevgrs) = [];
-
 
1464
  my($movegrs) = [];
-
 
1465
 
1549
 
1466
  for(my $gi = 0; $gi <= $#groups; ++$gi) {
-
 
1467
    ## If our moved group equals our previously moved group then
1550
  ## Check for duplicates first before we attempt to sort the groups.
1468
    ## we count this as a possible circular dependency.
1551
  ## If there is a duplicate, we quietly return immediately.  The
1469
    if (defined $$movegrs[0] && defined $$prevgrs[0] &&
-
 
1470
        $$movegrs[0] == $$prevgrs[0] && $$movegrs[1] == $$prevgrs[1]) {
1552
  ## duplicates will be flagged as an error when creating the main
1471
      ++$ccount;
1553
  ## workspace.
1472
    }
1554
  my(%dupcheck) = ();
1473
    else {
1555
  foreach my $proj (@$list) {
-
 
1556
    my($base) = $self->mpc_basename($proj);
-
 
1557
    if (defined $dupcheck{$base}) {
1474
      $ccount = 0;
1558
      return;
1475
    }
1559
    }
-
 
1560
    $dupcheck{$base} = $proj;
-
 
1561
  }
1476
 
1562
 
-
 
1563
  my(%circular_checked) = ();
-
 
1564
  for(my $gi = 0; $gi <= $#groups; ++$gi) {
1477
    ## Detect circular dependencies
1565
    ## Detect circular dependencies
1478
    if ($ccount > $cmax) {
1566
    if (!$circular_checked{$gi}) {
-
 
1567
      $circular_checked{$gi} = 1;
-
 
1568
      for(my $i = $groups[$gi]->[0]; $i <= $groups[$gi]->[1]; ++$i) {
-
 
1569
        my(%gdeps) = ();
-
 
1570
        $self->build_dependency_chain($$list[$i], $llen, $list, $gi,
-
 
1571
                                      $#groups + 1, \@groups,
-
 
1572
                                      \%dupcheck, \%gdeps);
-
 
1573
        if (exists $gdeps{$self->mpc_basename($$list[$i])}) {
-
 
1574
          ## There was a cirular dependency, get all of the directories
-
 
1575
          ## involved.
1479
      my(@dirs) = ();
1576
          my(%dirs) = ();
1480
      foreach my $mvgr (@$movegrs) {
1577
          foreach my $gdep (keys %gdeps) {
-
 
1578
            $dirs{$self->mpc_dirname($dupcheck{$gdep})} = 1;
-
 
1579
          }
-
 
1580
 
-
 
1581
          ## If the current directory was involved, translate that into
-
 
1582
          ## a directory relative to the start directory.
-
 
1583
          if (defined $dirs{'.'}) {
-
 
1584
            my($cwd) = $self->getcwd();
1481
        push(@dirs, $$list[$groups[$mvgr]->[0]]);
1585
            my($start) = $self->getstartdir();
-
 
1586
            if ($cwd ne $start) {
-
 
1587
              my($startre) = $self->escape_regex_special($start);
-
 
1588
              delete $dirs{'.'};
1482
        $dirs[$#dirs] =~ s/[\/\\].*//;
1589
              $cwd =~ s/^$startre[\\\/]//;
-
 
1590
              $dirs{$cwd} = 1;
-
 
1591
            }
-
 
1592
          }
-
 
1593
 
-
 
1594
          ## Display a warining to the user
-
 
1595
          my(@keys) = sort keys %dirs;
-
 
1596
          $self->warning('Circular directory dependency detected in the ' .
-
 
1597
                         ($self->{'current_input'} eq '' ?
-
 
1598
                           'default' : $self->{'current_input'}) .
-
 
1599
                         ' workspace. ' .
-
 
1600
                         'The following director' .
-
 
1601
                         ($#keys == 0 ? 'y is' : 'ies are') .
-
 
1602
                         ' involved: ' . join(', ', @keys));
-
 
1603
          return;
-
 
1604
        }
1483
      }
1605
      }
1484
      $self->warning('Circular dependency detected while processing the ' .
-
 
1485
                     ($self->{'current_input'} eq '' ?
-
 
1486
                       'default' : $self->{'current_input'}) .
-
 
1487
                     ' workspace. ' .
-
 
1488
                     'The following directories or projects are involved: ' .
-
 
1489
                     join(' and ', @dirs));
-
 
1490
      return;
-
 
1491
    }
1606
    }
1492
 
1607
 
1493
    ## Build up the group dependencies
1608
    ## Build up the group dependencies
1494
    my(%gdeps) = ();
1609
    my(%gdeps) = ();
1495
    for(my $i = $groups[$gi]->[0]; $i <= $groups[$gi]->[1]; ++$i) {
1610
    for(my $i = $groups[$gi]->[0]; $i <= $groups[$gi]->[1]; ++$i) {
1496
      my($deps) = $self->get_validated_ordering($$list[$i]);
1611
      my($deps) = $self->get_validated_ordering($$list[$i]);
1497
      if ($deps ne '') {
1612
      if (defined $$deps[0]) {
1498
        my($darr) = $self->create_array($deps);
-
 
1499
        foreach my $dep (@$darr) {
-
 
1500
          $gdeps{$dep} = 1;
1613
        @gdeps{@$deps} = ();
1501
        }
-
 
1502
      }
1614
      }
1503
    }
1615
    }
1504
 
1616
 
1505
    ## Keep track of the previous group movement
-
 
1506
    $prevgrs = $movegrs;
-
 
1507
    if ($prevgi < $gi) {
-
 
1508
      $movegrs = [];
-
 
1509
    }
-
 
1510
    $prevgi = $gi;
-
 
1511
 
-
 
1512
    ## Search the rest of the groups for any of the group dependencies
1617
    ## Search the rest of the groups for any of the group dependencies
1513
    my($moved) = 0;
-
 
1514
    for(my $gj = $gi + 1; $gj <= $#groups; ++$gj) {
1618
    for(my $gj = $gi + 1; $gj <= $#groups; ++$gj) {
1515
      for(my $i = $groups[$gj]->[0]; $i <= $groups[$gj]->[1]; ++$i) {
1619
      for(my $i = $groups[$gj]->[0]; $i <= $groups[$gj]->[1]; ++$i) {
1516
        if (defined $gdeps{basename($$list[$i])}) {
1620
        if (exists $gdeps{$self->mpc_basename($$list[$i])}) {
1517
          ## Move this group ($gj) in front of the current group ($gi)
1621
          ## Move this group ($gj) in front of the current group ($gi)
1518
          $movegrs = [$gj, $gi];
-
 
1519
          my(@save) = ();
1622
          my(@save) = ();
1520
          for(my $j = $groups[$gi]->[1] + 1; $j <= $groups[$gj]->[1]; ++$j) {
1623
          for(my $j = $groups[$gi]->[1] + 1; $j <= $groups[$gj]->[1]; ++$j) {
1521
            push(@save, $$list[$j]);
1624
            push(@save, $$list[$j]);
1522
          }
1625
          }
1523
          my($offset) = $groups[$gj]->[1] - $groups[$gi]->[1];
1626
          my($offset) = $groups[$gj]->[1] - $groups[$gi]->[1];
Line 1540... Line 1643...
1540
          for(my $j = $gi; $j < $gj; ++$j) {
1643
          for(my $j = $gi; $j < $gj; ++$j) {
1541
            $groups[$j] = $groups[$j + 1];
1644
            $groups[$j] = $groups[$j + 1];
1542
          }
1645
          }
1543
          $groups[$gj] = \@grsave;
1646
          $groups[$gj] = \@grsave;
1544
 
1647
 
1545
          ## Signify that we have moved a group
1648
          ## Start over from the first group
1546
          $moved = 1;
1649
          $gi = -1;
-
 
1650
 
-
 
1651
          ## Exit from the outter ($gj) loop
-
 
1652
          $gj = $#groups;
1547
          last;
1653
          last;
1548
        }
1654
        }
1549
      }
1655
      }
1550
      if ($moved) {
-
 
1551
        ## Start over from the first group
-
 
1552
        $gi = -1;
-
 
1553
        last;
-
 
1554
      }
-
 
1555
    }
1656
    }
1556
  }
1657
  }
1557
}
1658
}
1558
 
1659
 
1559
 
1660
 
1560
sub sort_dependencies {
1661
sub sort_dependencies {
1561
  my($self)     = shift;
1662
  my($self)     = shift;
1562
  my($projects) = shift;
1663
  my($projects) = shift;
-
 
1664
  my($groups)   = shift;
1563
  my(@list)     = sort { return $self->sort_projects_by_directory($a, $b) + 0;
1665
  my(@list)     = sort { return $self->sort_projects_by_directory($a, $b) + 0;
1564
                       } @$projects;
1666
                       } @$projects;
-
 
1667
  ## The list above is sorted by directory in order to keep projects
-
 
1668
  ## within the same directory together.  Otherwise, when groups are
-
 
1669
  ## created we may get multiple groups for the same directory.
1565
 
1670
 
1566
  ## Put the projects in the order specified
1671
  ## Put the projects in the order specified
1567
  ## by the project dpendencies.  We only need to do
1672
  ## by the project dpendencies.  We only need to do
1568
  ## this if there is more than one element in the array.
1673
  ## this if there is more than one element in the array.
1569
  if ($#list > 0) {
1674
  if ($#list > 0) {
-
 
1675
    ## If the parameter wasn't passed in or it was passed in
-
 
1676
    ## and was true, sort with directory groups in mind
-
 
1677
    if (!defined $groups || $groups) {
1570
    ## First determine the individual groups
1678
      ## First determine the individual groups
1571
    my(@grindex)  = ();
1679
      my(@grindex)  = ();
1572
    my($previous) = [0, undef];
1680
      my($previous) = [0, undef];
1573
    for(my $li = 0; $li <= $#list; ++$li) {
1681
      for(my $li = 0; $li <= $#list; ++$li) {
1574
      my($dir) = $self->get_first_level_directory($list[$li]);
1682
        my($dir) = $self->get_first_level_directory($list[$li]);
1575
      if (!defined $previous->[1]) {
1683
        if (!defined $previous->[1]) {
1576
        $previous = [$li, $dir];
1684
          $previous = [$li, $dir];
1577
      }
1685
        }
1578
      elsif ($previous->[1] ne $dir) {
1686
        elsif ($previous->[1] ne $dir) {
1579
        push(@grindex, [$previous->[0], $li - 1]);
1687
          push(@grindex, [$previous->[0], $li - 1]);
1580
        $previous = [$li, $dir];
1688
          $previous = [$li, $dir];
-
 
1689
        }
-
 
1690
      }
-
 
1691
      push(@grindex, [$previous->[0], $#list]);
-
 
1692
 
-
 
1693
      ## Next, sort the individual groups
-
 
1694
      foreach my $gr (@grindex) {
-
 
1695
        if ($$gr[0] != $$gr[1]) {
-
 
1696
          $self->sort_within_group(\@list, @$gr);
-
 
1697
        }
1581
      }
1698
      }
1582
    }
-
 
1583
    push(@grindex, [$previous->[0], $#list]);
-
 
1584
 
1699
 
1585
    ## Next, sort the individual groups
1700
      ## Now sort the groups as single entities
1586
    foreach my $gr (@grindex) {
-
 
1587
      if ($$gr[0] != $$gr[1]) {
1701
      if ($#grindex > 0) {
1588
        $self->sort_within_group(\@list, @$gr);
1702
        $self->sort_by_groups(\@list, \@grindex);
1589
      }
1703
      }
1590
    }
1704
    }
1591
 
-
 
1592
    ## Now sort the groups as single entities
-
 
1593
    if ($#grindex > 0) {
1705
    else {
1594
      $self->sort_by_groups(\@list, \@grindex);
1706
      $self->sort_within_group(\@list, 0, $#list);
1595
    }
1707
    }
1596
  }
1708
  }
1597
 
1709
 
1598
  return @list;
1710
  return @list;
1599
}
1711
}
Line 1602... Line 1714...
1602
sub number_target_deps {
1714
sub number_target_deps {
1603
  my($self)     = shift;
1715
  my($self)     = shift;
1604
  my($projects) = shift;
1716
  my($projects) = shift;
1605
  my($pjs)      = shift;
1717
  my($pjs)      = shift;
1606
  my($targets)  = shift;
1718
  my($targets)  = shift;
-
 
1719
  my($groups)   = shift;
1607
  my(@list)     = $self->sort_dependencies($projects);
1720
  my(@list)     = $self->sort_dependencies($projects, $groups);
1608
 
1721
 
1609
  ## This block of code must be done after the list of dependencies
1722
  ## This block of code must be done after the list of dependencies
1610
  ## has been sorted in order to get the correct project numbers.
1723
  ## has been sorted in order to get the correct project numbers.
1611
  for(my $i = 0; $i <= $#list; ++$i) {
1724
  for(my $i = 0; $i <= $#list; ++$i) {
1612
    my($project) = $list[$i];
1725
    my($project) = $list[$i];
1613
    if (defined $$pjs{$project}) {
1726
    if (defined $$pjs{$project}) {
1614
      my($name, $deps) = @{$$pjs{$project}};
1727
      my($name, $deps) = @{$$pjs{$project}};
1615
      if (defined $deps && $deps ne '') {
1728
      if (defined $deps && $deps ne '') {
1616
        my(%targetnumbers) = ();
1729
        my(@numbers) = ();
-
 
1730
        my(%dhash)   = ();
1617
        my($darr) = $self->create_array($deps);
1731
        @dhash{@{$self->create_array($deps)}} = ();
1618
 
1732
 
1619
        ## For each dependency, search in the sorted list
1733
        ## For each dependency, search in the sorted list
1620
        ## up to the point of this project for the projects
1734
        ## up to the point of this project for the projects
1621
        ## that this one depends on.  When the project is
1735
        ## that this one depends on.  When the project is
1622
        ## found, we put the target number in a hash map (to avoid
1736
        ## found, we put the target number in the numbers array.
1623
        ## duplicates).
-
 
1624
        foreach my $dep (@$darr) {
-
 
1625
          for(my $j = 0; $j < $i; ++$j) {
1737
        for(my $j = 0; $j < $i; ++$j) {
1626
            if (basename($list[$j]) eq $dep) {
1738
          if (exists $dhash{$self->mpc_basename($list[$j])}) {
1627
              $targetnumbers{$j} = 1;
1739
            push(@numbers, $j);
1628
            }
-
 
1629
          }
1740
          }
1630
        }
1741
        }
1631
 
1742
 
1632
        ## Get the keys of the hash map and store the
-
 
1633
        ## array in the hash keyed on the project file.
1743
        ## Store the array in the hash keyed on the project file.
1634
        my(@numbers) = sort { $a <=> $b } keys %targetnumbers;
-
 
1635
        if (defined $numbers[0]) {
1744
        if (defined $numbers[0]) {
1636
          $$targets{$project} = \@numbers;
1745
          $$targets{$project} = \@numbers;
1637
        }
1746
        }
1638
      }
1747
      }
1639
    }
1748
    }
Line 1730... Line 1839...
1730
        $self->optionError('-noreldefs is ignored');
1839
        $self->optionError('-noreldefs is ignored');
1731
      }
1840
      }
1732
      if (defined $options->{'coexistence'}) {
1841
      if (defined $options->{'coexistence'}) {
1733
        $self->optionError('-make_coexistence is ignored');
1842
        $self->optionError('-make_coexistence is ignored');
1734
      }
1843
      }
1735
      if (defined $options->{'genins'}) {
-
 
1736
        $self->optionError('-genins is ignored');
-
 
1737
      }
-
 
1738
      if (defined $options->{'into'}) {
1844
      if (defined $options->{'into'}) {
1739
        $self->optionError('-into is ignored');
1845
        $self->optionError('-into is ignored');
1740
      }
1846
      }
1741
      if (defined $options->{'language'}) {
-
 
1742
        $self->optionError('-language is ignored');
-
 
1743
      }
-
 
1744
      if (defined $options->{'input'}->[0]) {
1847
      if (defined $options->{'input'}->[0]) {
1745
        $self->optionError('Command line files ' .
1848
        $self->optionError('Command line files ' .
1746
                           'specified in a workspace are ignored');
1849
                           'specified in a workspace are ignored');
1747
      }
1850
      }
1748
 
1851
 
1749
      ## Determine if it's ok to use the cache
1852
      ## Determine if it's ok to use the cache
1750
      my(@cacheInvalidating) = ('global', 'include', 'baseprojs',
1853
      my(@cacheInvalidating) = ('global', 'include', 'baseprojs',
1751
                                'template', 'ti', 'relative',
1854
                                'template', 'ti', 'relative', 'language',
1752
                                'addtemp', 'addproj', 'feature_file',
1855
                                'addtemp', 'addproj', 'feature_file',
1753
                                'features', 'use_env', 'expand_vars');
1856
                                'features', 'use_env', 'expand_vars');
1754
      foreach my $key (@cacheInvalidating) {
1857
      foreach my $key (@cacheInvalidating) {
1755
        if ($self->is_set($key, $options)) {
1858
        if ($self->is_set($key, $options)) {
1756
          $self->{'cacheok'} = 0;
1859
          $self->{'cacheok'} = 0;
Line 1810... Line 1913...
1810
                   $parameters{'hierarchy'},
1913
                   $parameters{'hierarchy'},
1811
                   $self->{'exclude'}->{$self->{'wctype'}},
1914
                   $self->{'exclude'}->{$self->{'wctype'}},
1812
                   $self->make_coexistence(),
1915
                   $self->make_coexistence(),
1813
                   $parameters{'name_modifier'},
1916
                   $parameters{'name_modifier'},
1814
                   $parameters{'apply_project'},
1917
                   $parameters{'apply_project'},
1815
                   $self->{'generate_ins'},
1918
                   $self->{'generate_ins'} || $parameters{'genins'},
1816
                   $parameters{'into'},
1919
                   $parameters{'into'},
1817
                   $self->get_language(),
1920
                   $parameters{'language'},
1818
                   $parameters{'use_env'},
1921
                   $parameters{'use_env'},
1819
                   $parameters{'expand_vars'});
1922
                   $parameters{'expand_vars'});
1820
}
1923
}
1821
 
1924
 
1822
 
1925
 
Line 1903... Line 2006...
1903
 
2006
 
1904
  if (defined $self->{'ordering_cache'}->{$project}) {
2007
  if (defined $self->{'ordering_cache'}->{$project}) {
1905
    $deps = $self->{'ordering_cache'}->{$project};
2008
    $deps = $self->{'ordering_cache'}->{$project};
1906
  }
2009
  }
1907
  else {
2010
  else {
1908
    $deps = '';
2011
    $deps = [];
1909
    if (defined $self->{'project_info'}->{$project}) {
2012
    if (defined $self->{'project_info'}->{$project}) {
1910
      my($name) = undef;
-
 
1911
      ($name, $deps) = @{$self->{'project_info'}->{$project}};
2013
      my($name, $dstr) = @{$self->{'project_info'}->{$project}};
1912
      if (defined $deps && $deps ne '') {
2014
      if (defined $dstr && $dstr ne '') {
1913
        my($darr) = $self->create_array($deps);
2015
        $deps = $self->create_array($dstr);
-
 
2016
        my($dlen) = scalar(@$deps);
1914
        foreach my $dep (@$darr) {
2017
        for(my $i = 0; $i < $dlen; $i++) {
-
 
2018
          my($dep)   = $$deps[$i];
1915
          my($found) = 0;
2019
          my($found) = 0;
1916
          ## Avoid circular dependencies
2020
          ## Avoid circular dependencies
1917
          if ($dep ne $name && $dep ne basename($project)) {
2021
          if ($dep ne $name && $dep ne $self->mpc_basename($project)) {
1918
            foreach my $p (@{$self->{'projects'}}) {
2022
            foreach my $p (@{$self->{'projects'}}) {
1919
              if ($dep eq $self->{'project_info'}->{$p}->[0] ||
2023
              if ($dep eq $self->{'project_info'}->{$p}->[0] ||
1920
                  $dep eq basename($p)) {
2024
                  $dep eq $self->mpc_basename($p)) {
1921
                $found = 1;
2025
                $found = 1;
1922
                last;
2026
                last;
1923
              }
2027
              }
1924
            }
2028
            }
1925
            if (!$found) {
2029
            if (!$found) {
1926
              if (defined $ENV{MPC_VERBOSE_ORDERING}) {
2030
              if (defined $ENV{MPC_VERBOSE_ORDERING}) {
1927
                $self->warning("'$name' references '$dep' which has " .
2031
                $self->warning("'$name' references '$dep' which has " .
1928
                               "not been processed.");
2032
                               "not been processed.");
1929
              }
2033
              }
1930
              my($reg) = $self->escape_regex_special($dep);
2034
              splice(@$deps, $i, 1);
1931
              $deps =~ s/\s*"$reg"\s*/ /g;
2035
              --$dlen;
-
 
2036
              --$i;
1932
            }
2037
            }
1933
          }
2038
          }
-
 
2039
          else {
-
 
2040
            ## If a project references itself, we must remove it
-
 
2041
            ## from the list of dependencies.
-
 
2042
            splice(@$deps, $i, 1);
-
 
2043
            --$dlen;
-
 
2044
            --$i;
-
 
2045
          }
1934
        }
2046
        }
1935
 
-
 
1936
        $deps =~ s/^\s+//;
-
 
1937
        $deps =~ s/\s+$//;
-
 
1938
      }
2047
      }
1939
 
2048
 
1940
      $self->{'ordering_cache'}->{$project} = $deps;
2049
      $self->{'ordering_cache'}->{$project} = $deps;
1941
    }
2050
    }
1942
  }
2051
  }
Line 1947... Line 2056...
1947
 
2056
 
1948
sub source_listing_callback {
2057
sub source_listing_callback {
1949
  my($self)         = shift;
2058
  my($self)         = shift;
1950
  my($project_file) = shift;
2059
  my($project_file) = shift;
1951
  my($project_name) = shift;
2060
  my($project_name) = shift;
1952
  my(@files)        = @_;
-
 
1953
  my($cwd)          = $self->getcwd();
2061
  my($cwd)          = $self->getcwd();
1954
  $self->{'project_file_list'}->{$project_name} = [ $project_file,
2062
  $self->{'project_file_list'}->{$project_name} = [ $project_file,
1955
                                                    $cwd, \@files ];
2063
                                                    $cwd, \@_ ];
1956
}
2064
}
1957
 
2065
 
1958
 
2066
 
1959
sub sort_projects_by_directory {
2067
sub sort_projects_by_directory {
1960
  my($self)  = shift;
2068
  my($self)  = shift;
1961
  my($left)  = shift;
2069
  my($left)  = shift;
1962
  my($right) = shift;
2070
  my($right) = shift;
1963
  my($sa)    = ($left =~ /\//);
2071
  my($sa)    = index($left, '/');
1964
  my($sb)    = ($right =~ /\//);
2072
  my($sb)    = index($right, '/');
1965
 
2073
 
1966
  if ($sa && !$sb) {
2074
  if ($sa >= 0 && $sb == -1) {
1967
    return 1;
2075
    return 1;
1968
  }
2076
  }
1969
  elsif ($sb && !$sa) {
2077
  elsif ($sb >= 0 && $sa == -1) {
1970
    return -1;
2078
    return -1;
1971
  }
2079
  }
1972
  return $left cmp $right;
2080
  return $left cmp $right;
1973
}
2081
}
1974
 
2082