summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryye00 <yye00@17b73243-c579-4c4c-a9d2-2d5706c11dac>2005-08-16 17:26:48 +0000
committeryye00 <yye00@17b73243-c579-4c4c-a9d2-2d5706c11dac>2005-08-16 17:26:48 +0000
commit8c8a283caecd5acddb6466c79be1513aae2fb70c (patch)
tree642b03bc32935a83799268c00a00cd65d7d754c7
parent8bbd884aa6aa78bb0b60eae385f4d9ba0de92982 (diff)
configuration.ccl fix. Please test and report if anything breaks
git-svn-id: http://svn.cactuscode.org/flesh/trunk@4109 17b73243-c579-4c4c-a9d2-2d5706c11dac
-rw-r--r--lib/make/make.configuration4
-rw-r--r--lib/make/make.thornlib6
-rw-r--r--lib/sbin/CST23
-rw-r--r--lib/sbin/CSTUtils.pl89
-rw-r--r--lib/sbin/ConfigurationParser.pl24
-rw-r--r--lib/sbin/CreateConfigurationBindings.pl202
-rw-r--r--lib/sbin/interface_parser.pl76
7 files changed, 330 insertions, 94 deletions
diff --git a/lib/make/make.configuration b/lib/make/make.configuration
index b115d6a4..5163fe47 100644
--- a/lib/make/make.configuration
+++ b/lib/make/make.configuration
@@ -96,7 +96,7 @@ endif
# generated from a thorn's configuration.ccl
ifeq ($(strip $(UTILS)),)
ifneq ($(strip $(THORN_LINKLIST)),)
--include $(THORN_LINKLIST:%=$(BINDINGS_DIR)/Configuration/%/make.configuration.defn)
+-include $(THORN_LINKLIST:%=$(BINDINGS_DIR)/Configuration/Thorns/make.%.defn)
endif
endif
@@ -232,7 +232,7 @@ $(TOP)/ThornList:
# Allow each thorn to include some global dependencies
ifneq ($(strip $(THORNS)),)
--include $(THORNS:%=$(PACKAGE_DIR)/%/src/make.configuration.deps) $(THORNS:%=$(BINDINGS_DIR)/Configuration/%/make.configuration.deps)
+-include $(THORNS:%=$(PACKAGE_DIR)/%/src/make.configuration.deps) $(THORNS:%=$(BINDINGS_DIR)/Configuration/Thorns/make.%.deps)
endif
# Catch the special case of a thorn being removed from the disk entirely.
diff --git a/lib/make/make.thornlib b/lib/make/make.thornlib
index 84223bda..6f1a9fd9 100644
--- a/lib/make/make.thornlib
+++ b/lib/make/make.thornlib
@@ -20,17 +20,17 @@ include $(CONFIG)/make.config.defn
BINDINGS_DIR=$(TOP)/bindings
-# Include the configuration make.code.defn for the thorn
+# Include the configuration make.THORN_NAME.defn for the thorn
# if it is not Cactus or CactusBindings
INC_DIRS =
ifneq ($(THORN), CactusBindings)
ifneq ($(THORN), Cactus)
--include $(BINDINGS_DIR)/Configuration/$(THORN)/make.configuration.defn
+-include $(BINDINGS_DIR)/Configuration/Thorns/make.$(THORN).defn
endif
endif
# Add appropriate include lines
-INC_DIRS += $(SYS_INC_DIRS) $(SRCDIR) $(SRCDIR)/include $(CONFIG) $(BINDINGS_DIR)/include $(CCTK_HOME)/src/include $(CCTK_HOME)/arrangements
+INC_DIRS += $(SYS_INC_DIRS) $(SRCDIR) $(SRCDIR)/include $(CONFIG) $(BINDINGS_DIR)/include $(CCTK_HOME)/src/include $(CCTK_HOME)/arrangements $(BINDINGS_DIR)/Configuration/Thorns
# Allow subdirectories to inherit these include directories
export INC_DIRS
diff --git a/lib/sbin/CST b/lib/sbin/CST
index e3cf03ef..894614b8 100644
--- a/lib/sbin/CST
+++ b/lib/sbin/CST
@@ -6,7 +6,7 @@
# @desc
# Parses the the configuration files for thorns.
# @enddesc
-# @version $Header: /mnt/data2/cvs2svn/cvs-repositories/Cactus/lib/sbin/CST,v 1.73 2004-11-30 23:22:00 goodale Exp $
+# @version $Header: /mnt/data2/cvs2svn/cvs-repositories/Cactus/lib/sbin/CST,v 1.74 2005-08-16 17:25:52 yye00 Exp $
#@@*/
# Global parameter to track the number of errors from the CST
@@ -149,7 +149,7 @@ print "Creating Thorn-Flesh bindings...\n";
&CreateLogFile($config_dir, $configuration_database,\%thorns);
# Finally (must be last), create the make.thornlist file.
-$make_thornlist = &CreateMakeThornlist(\%thorns, $configuration_database);
+$make_thornlist = &CreateMakeThornlist(\%thorns, \%interface_database, $configuration_database);
# Stop the make process if there were any errors
if ($CST_errors)
@@ -316,7 +316,7 @@ sub get_global_parameters
sub CreateMakeThornlist
{
- my($thorns, $config) = @_;
+ my($thorns ,$interface, $config) = @_;
my($thorn);
my($thornlist);
my($thorn_linklist);
@@ -342,8 +342,7 @@ sub CreateMakeThornlist
$config_thornlist .= " $1";
}
}
-
- $thorn_linklist .= ' ' . &TopoSort(\%thorns, $config);
+ $thorn_linklist .= ' ' . &TopoSort($thorns, $interface, $config);
$thorn_dependencies = join ("\n", &CreateThornDependencyList($thorns, $config));
return ($thornlist . "\n" . $thorn_linklist . "\n" . $config_thornlist . "\n" . $thorn_dependencies . "\n");
@@ -564,7 +563,7 @@ sub CreateBindings
#@@*/
sub TopoSort
{
- my($thorns, $cfg)= @_;
+ my($thorns, $interface, $cfg)= @_;
my($data) = '';
my($nouse) = '';
my $thorn;
@@ -573,9 +572,13 @@ sub TopoSort
foreach $thorn (sort keys %thorns)
{
next if ("\U$thorn\E" eq "CACTUS");
+ $thorn_ancestor{"\U$thorn\E"} = '';
+ foreach $ancestor_imp ( split(' ', $interface->{"\U$thorn INHERITS\E"}))
+ {
+ $thorn_ancestor{"\U$thorn\E"} .= $interface->{"IMPLEMENTATION \U$ancestor_imp\E THORNS"}. ' ';
+ }
- my @uses_thorns = split (' ', $cfg->{"\U$thorn\E USES THORNS"});
-
+ my @uses_thorns = split (' ', $cfg->{"\U$thorn\E USES THORNS"} . ' ' . $thorn_ancestor{"\U$thorn\E"});
my $uses_thorns = '';
foreach (@uses_thorns)
{
@@ -607,8 +610,8 @@ sub TopoSort
$data =~ s/dummy//;
$data =~ s/ / /;
}
-
- return $data;
+
+return $data;
}
diff --git a/lib/sbin/CSTUtils.pl b/lib/sbin/CSTUtils.pl
index c7043647..0090852d 100644
--- a/lib/sbin/CSTUtils.pl
+++ b/lib/sbin/CSTUtils.pl
@@ -749,4 +749,93 @@ sub GetOptionsFromEnv
return \%options;
}
+#/*@@
+# @routine find_dep_cycles
+# @date Fri Apr 15 20:47:00 2005
+# @author Josh Abadie
+# @desc
+# Iterates over all the thorns, and finds out if there are any cycles
+# This function is the wrapper around the recursive one.
+# @enddesc
+#@@*/
+sub find_dep_cycles
+{
+ my(%thorns) = @_;
+ my(%visited) = {};
+ my($stack,$keyu,$returned);
+ my $debug = 0;
+
+ foreach $key (keys %thorns)
+ {
+ $key = uc ($key);
+ #next if($visted{$key} && 1 == $visted{$key});
+ next if(1 == $visited{$key});
+ print "testing $key for deps\n" if (1 == $debug);
+ $stack = $key." ";
+ $returned = &recurse_deps($key, \%thorns, $stack, \%visited);
+ $visted{$key} = 1;
+ if("" ne $returned)
+ {
+ print "Found cycle while testing $key for deps.[$returned]\n" if (1 == $debug);
+ return $returned;
+ }
+ }
+ return "";
+}
+
+#/*@@
+# @routine recurse_deps
+# @date Fri Apr 15 20:47:00 2005
+# @author Josh Abadie
+# @desc
+# Iterates over all the thorns, and finds out if there are any cycles
+#
+# @enddesc
+#@@*/
+sub recurse_deps
+{
+ my($key, $thornsTemp,$stack, $visitedTemp) = @_;
+ my %thorns = %$thornsTemp;
+ my %visited = %$visitedTemp;
+ my($depThorni,$loop,$returned,$temp);
+ my (@arr)=();
+ my $debug = 0;
+
+ # Iterates over all thorns this one depends on, and checks to see if any
+ # form a cycle.
+ foreach $depThorn (split(" ", uc($thorns{"\U$key\E"})))
+ {
+ $depThorn = uc($depThorn);
+
+ if($stack =~ /\b$depThorn\b/i)
+ {
+ $stack =~ /.*\b($depThorn\b.*)$/i;
+ $loop = $1.$depThorn;
+ return $loop;
+ }
+ else
+ {
+ # We don't have a cycle yet, so let's recurse on this thorn's deps.
+ $stack = $stack.$depThorn. ' ';
+ print "Recursing into $depThorn. Stack is [$stack]\n" if (1 == $debug);
+ $returned = &recurse_deps($depThorn, \%thorns, $stack, \%visited);
+ if("" ne $returned)
+ {
+ return $returned;
+ }
+ $visited{$depThorn} = 1;
+ $temp = $";
+ $" = " ";
+ $stack =~ s/^(.*)\s*$/$1/;
+ $stack =~ s/^\s*(.*)$/$1/;
+ @arr = split(" ", $stack);
+ pop(@arr);
+ $stack = "@arr ";
+ $" = $temp;
+ }
+ }
+ $visited{$key} = 1;
+ return "";
+}
+
1;
diff --git a/lib/sbin/ConfigurationParser.pl b/lib/sbin/ConfigurationParser.pl
index 346b4c75..41500f50 100644
--- a/lib/sbin/ConfigurationParser.pl
+++ b/lib/sbin/ConfigurationParser.pl
@@ -24,7 +24,7 @@ sub CreateConfigurationDatabase
{
my($config_dir, %thorns) = @_;
my(%cfg) = ();
- my($thorn, $required, @missing, @foundlist, $founderrlist, $filename, %thorncap, $foundcap, $temp,$cap);
+ my($thorn, $required, @missing, @foundlist, $founderrlist, $filename, %thorncap, $foundcap, $temp,$cap,$message,$hint);
# Loop through each thorn's configuration file.
foreach $thorn (sort keys %thorns)
@@ -111,7 +111,26 @@ sub CreateConfigurationDatabase
}
}
- # # Print configuration database
+# Check for cyclic dependencies
+# create a hash with thorn-> used thorns (no prefix)
+ foreach $thorn (sort keys %thorns)
+ {
+ $thorn_dependencies{uc($thorn)}=$cfg{"\U$thorn\E USES THORNS"};
+ }
+
+ $message = &find_dep_cycles(%thorn_dependencies);
+
+ if ("" ne $message)
+ {
+ $message =~ s/^\s*//g;
+ $message =~ s/\s*$//g;
+ $message =~ s/\s+/->/g;
+ $message = "Found a cyclic dependency in configuration requirements:".$message."\n";
+ &CST_error(0,$message,$hint,__LINE__,__FILE__);
+ }
+
+
+# # Print configuration database
# my($field);
# foreach $field ( sort keys %cfg)
# {
@@ -194,6 +213,7 @@ sub ParseConfigurationCCL
{
($optional, $define, $line_number) = &ParseOptionalBlock($line_number, \@data);
$cfg->{"\U$thorn\E OPTIONAL"} .= "$optional ";
+ $cfg->{"\U$thorn\E OPTIONAL \U$optional\E DEFINE"} = $define;
}
elsif($line =~ m/^\s*NO_SOURCE\s*/i)
{
diff --git a/lib/sbin/CreateConfigurationBindings.pl b/lib/sbin/CreateConfigurationBindings.pl
index a8745d37..dc967c5d 100644
--- a/lib/sbin/CreateConfigurationBindings.pl
+++ b/lib/sbin/CreateConfigurationBindings.pl
@@ -8,11 +8,10 @@
# @version $Header$
#@@*/
-
require "$sbin_dir/CSTUtils.pl";
#/*@@
-# @routine CreateScheduleBindings
+# @routine CreateConfigurationBindings
# @date Thu Mar 25 14:25:13 2004
# @author Yaakoub Y El-Khamra
# @desc
@@ -22,7 +21,8 @@ require "$sbin_dir/CSTUtils.pl";
sub CreateConfigurationBindings
{
my($bindings_dir, $cfg, $thorns)=@_;
- my($field, $providedcap, $thorn, $temp);
+ my($field, $providedcap, $providedcaplist, $thorn, $temp,$defs,$incs,$deps,$linkerflagdirs,$linkerflaglibs);
+ my(%linker_thorns, %linker_cfg, $linker_list, $linkerdirs, $linkerlibs);
if(! $build_dir)
{
@@ -48,27 +48,24 @@ sub CreateConfigurationBindings
mkdir('include', 0755) || die 'Unable to create include directory';
}
- if(! -d "$build_dir")
+ chdir 'Configuration';
+
+ if(! -d "Capabilities")
{
- mkdir("$build_dir", 0755) || die "Unable to create $build_dir";
+ mkdir("Capabilities", 0755) || die "Unable to create Capabilities directory";
}
-
- foreach $thorn (sort keys %thorns)
+ if(! -d 'Thorns')
{
- if ($cfg->{"\U$thorn\E REQUIRES"} || $cfg->{"\U$thorn\E OPTIONAL"})
- {
- if(! -d "$bindings_dir/Configuration/$thorn")
- {
- mkdir("$bindings_dir/Configuration/$thorn", 0755) || die "Unable to create Thorn $thorn Configuration directory";
- }
- }
+ mkdir('Thorns', 0755) || die "Unable to create Thorns directory";
}
- # this string goes into the cactus executable directly
- my @cap_libdirs = ();
- my @cap_libs = ();
- # here we put all the PROVIDES to where they belong
+ # this string goes into the cactus executable directly
+ $linkerflagdirs = '';
+ $linkerflaglibs = '';
+
+ $providedcaplist = '';
+ # here we put all the provided capabilities where they belong
foreach $thorn (sort keys %thorns)
{
# we know that all the requirements have been satisfied
@@ -76,74 +73,139 @@ sub CreateConfigurationBindings
# and make references to them from the requirements and optional
# since we can have multiple provides, we make each capability
# separate
- foreach $providedcap (split (' ', $cfg->{"\U$thorn\E PROVIDES"}))
+ if ($cfg->{"\U$thorn\E PROVIDES"})
{
- my $thorn_providedcap = "\U$thorn $providedcap\E";
-
- if ($cfg->{"$thorn_providedcap DEFINE"})
- {
- &WriteFile("include/\U$providedcap\E.h",
- \$cfg->{"$thorn_providedcap DEFINE"});
- }
- if ($cfg->{"$thorn_providedcap MAKE_DEFINITION"})
- {
- &WriteFile("Configuration/make.\U$providedcap\E.defn",
- \$cfg->{"$thorn_providedcap MAKE_DEFINITION"});
- }
- if ($cfg->{"$thorn_providedcap MAKE_DEPENDENCY"})
+ foreach $providedcap (split (' ', $cfg->{"\U$thorn\E PROVIDES"}))
{
- &WriteFile("Configuration/make.\U$providedcap\E.deps",
- \$cfg->{"$thorn_providedcap MAKE_DEPENDENCY"});
- }
+ $providedcaplist .= "$providedcap ";
+ $temp = "\n";
+ # put include_dirs and make.definition in one file: make.capability.defn
+ if ($cfg->{"\U$thorn $providedcap\E INCLUDE_DIRECTORY"})
+ {
+ $temp .="INC_DIRS +=" . $cfg->{"\U$thorn $providedcap\E INCLUDE_DIRECTORY"} . "\n";
+ }
- push (@cap_libs, $cfg->{"$thorn_providedcap LIBRARY"});
- push (@cap_libdirs, $cfg->{"$thorn_providedcap LIBRARY_DIRECTORY"});
- }
- }
+ if ($cfg->{"\U$thorn $providedcap\E MAKE_DEFINITION"})
+ {
+ $temp .= $cfg->{"\U$thorn $providedcap\E MAKE_DEFINITION"} . "\n";
+ }
+
+ &WriteFile("Capabilities/make.\U$providedcap\E.defn",\$temp);
- $cap_ldflags = 'LIBDIRS += ' . join (' ', @cap_libdirs) . "\n";
- $cap_ldflags .= 'LIBS += ' . join (' ', @cap_libs);
+ $temp = "\n";
+ # put include and DEFINE in one file: capability.h
+ if ($cfg->{"\U$thorn $providedcap\E INCLUDE"})
+ {
+ $temp .= $cfg->{"\U$thorn $providedcap\E INCLUDE"} . "\n";
+ }
+
+ if ($cfg->{"\U$thorn $providedcap\E DEFINE"})
+ {
+ $temp .= "#define " . $cfg->{"\U$thorn $providedcap\E DEFINE"} . "\n";
+ }
+
+ &WriteFile("Capabilities/\U$providedcap\E.h",\$temp);
+ $temp = "\n";
- &WriteFile("Configuration/make.link",\$cap_ldflags);
+ # put make.capability.deps in one file: make.capabiltiy.deps
+ if ($cfg->{"\U$thorn $providedcap\E MAKE_DEPENDENCY"})
+ {
+ $temp .= $cfg->{"\U$thorn $providedcap\E MAKE_DEPENDENCY"} . "\n";
+ }
- # here we gather all the REQUIRES and OPTIONAL capabilities for each thorn
+ &WriteFile("Capabilities/make.\U$providedcap\E.deps",\$temp);
+ $temp = "\n";
+
+ if ( $cfg->{"\U$thorn $providedcap\E LIBRARY"} )
+ {
+ $linker_thorns{"$thorn"} = $thorn;
+ $linker_cfg{"\U$thorn\E USES"} = $cfg->{"\U$thorn\E USES THORNS"};
+ }
+
+ if ( $cfg->{"\U$thorn $providedcap\E LIBRARY_DIRECTORY"} )
+ {
+ $linker_thorns{"$thorn"} = $thorn;
+ $linker_cfg{"\U$thorn\E USES"} = $cfg->{"\U$thorn\E USES THORNS"};
+ }
+ }
+ }
+ }
+
+ # here we add the files to the thorns that require capabilities
foreach $thorn (sort keys %thorns)
{
- my $thornDefnFile = '';
- my $thornDepsFile = '';
- my $requires_optional = $cfg->{"\U$thorn\E REQUIRES"} . ' ' .
- $cfg->{"\U$thorn\E OPTIONAL"};
- foreach $requiredcap (split (' ', $requires_optional))
+ # we know that all the requirements have been satisfied
+ # so all we need to do is make references to the capabilities
+ # from the requirements since we can have multiple provides,
+ # we make each capability separate
+
+ $defs = '';
+ $incs = '';
+ $deps = '';
+
+ if ($cfg->{"\U$thorn\E REQUIRES"})
{
- foreach $provider (sort keys %thorns)
+ foreach $providedcap (split (' ', $cfg->{"\U$thorn\E REQUIRES"}))
{
- foreach $providedcap (split (' ', $cfg->{"\U$provider\E PROVIDES"}))
+ # put reference to provided capability
+ $defs .= "include $bindings_dir/Configuration/Capabilities/make.\U$providedcap\E.defn" . "\n";
+ $incs .= "#include \"../Capabilities/\U$providedcap\E.h\"" . "\n";
+ $deps .= "include $bindings_dir/Configuration/Capabilities/make.\U$providedcap\E.deps" . "\n";
+ }
+ }
+
+ if ($cfg->{"\U$thorn\E OPTIONAL"})
+ {
+ foreach $providedcap (split (' ', $cfg->{"\U$thorn\E OPTIONAL"}))
+ {
+ if ($providedcaplist =~ m/$providedcap/i)
{
- next if ($requiredcap ne $providedcap);
-
- my $cap = "\U$provider $providedcap\E";
-
- if ($cfg->{"$cap MAKE_DEFINITION"})
- {
- $thornDefnFile .= "-include \$(BINDINGS_DIR)/Configuration/make.\U$providedcap\E.defn\n";
- }
- if ($cfg->{"$cap MAKE_DEPENDENCY"})
- {
- $thornDepsFile .= "-include \$(BINDINGS_DIR)/Configuration/make.\U$providedcap\E.deps\n";
- }
- if ($cfg->{"$cap INCLUDE_DIRECTORY"})
- {
- $thornDefnFile .= 'INC_DIRS += ' . $cfg->{"$cap INCLUDE_DIRECTORY"} . "\n";
- }
+ $defs .= $providedcap . " = 1\n";
+ $defs .= "include $bindings_dir/Configuration/Capabilities/make.\U$providedcap\E.defn" . "\n";
+ $incs .= "#define " . $cfg->{"\U$thorn\E OPTIONAL \U$providedcap\E DEFINE"} . " 1\n";
+ $incs .= "#include \"../Capabilities/\U$providedcap\E.h\"" . "\n";
+ $deps .= "include $bindings_dir/Configuration/Capabilities/make.\U$providedcap\E.deps" . "\n";
}
}
}
- &WriteFile("Configuration/$thorn/make.configuration.defn",\$thornDefnFile)
- if ($thornDefnFile);
- &WriteFile("Configuration/$thorn/make.configuration.deps",\$thornDepsFile)
- if ($thornDepsFile);
+ # write everything to file
+ &WriteFile("./Thorns/make.$thorn.defn",\$defs);
+ &WriteFile("./Thorns/$thorn.h",\$incs);
+ &WriteFile("./Thorns/make.$thorn.deps",\$deps);
+
+ }
+
+ # Sort the linker thorns
+ $linkerdirs = "LIBDIRS += ";
+ $linkerlibs = "LIBS += ";
+
+ $linker_list = &TopoSort(\%linker_thorns, \%linker_cfg);
+ foreach $thorn (split (' ', $linker_list))
+ {
+ foreach $providedcap (split (' ', $cfg->{"\U$thorn\E PROVIDES"}))
+ {
+ $linkerdirs .= ' ' . $cfg->{"\U$thorn $providedcap\E LIBRARY_DIRECTORY"};
+ $linkerlibs .= ' ' . $cfg->{"\U$thorn $providedcap\E LIBRARY"};
+ }
+ }
+ $temp = $linkerdirs . "\n" . $linkerlibs;
+ &WriteFile("make.link",\$temp);
+
+ # write cctki_Capabilities.h file to bindings/include
+ # this file adds the if_i_am_thorn stuff
+ $temp = "#ifdef __cplusplus\nextern \"C\"\n#endif\n";
+ foreach $thorn (sort keys %thorns)
+ {
+ if ($cfg->{"\U$thorn\E REQUIRES"} || $cfg->{"\U$thorn\E OPTIONAL"})
+ {
+ $temp .= "\n";
+ $temp .= "#ifdef THORN_IS_$thorn" . "\n";
+ $temp .= "#include \"../Configuration/Thorns/$thorn.h\"" . "\n";
+ $temp .= '#endif' . "\n";
+ }
}
+ &WriteFile("../include/cctki_Capabilities.h",\$temp);
}
return 1;
diff --git a/lib/sbin/interface_parser.pl b/lib/sbin/interface_parser.pl
index 40e16f7e..23e24f71 100644
--- a/lib/sbin/interface_parser.pl
+++ b/lib/sbin/interface_parser.pl
@@ -69,6 +69,7 @@ sub cross_index_interface_data
my($implementation);
my(%ancestors);
my(%friends);
+ my($thorn,$thorn_implements,$ancestor_imp,$thorn_ancestor,$message,$hint);
@thorns = @indata[0..$n_thorns-1];
%system_database = @indata[$n_thorns..$n_thorns+2*$n_system-1];
@@ -122,6 +123,28 @@ sub cross_index_interface_data
$interface_data{"IMPLEMENTATION \U$implementation\E FRIENDS"} = &get_friends_of_me($implementation, scalar(keys %implementations), (sort keys %implementations),%interface_data);
}
+
+ # Create Hash table with thorns as ancestors
+ foreach $thorn (@thorns)
+ {
+ $thorn_implements = $interface_data{"\U$thorn\E IMPLEMENTS"};
+ foreach $ancestor_imp ( split(' ', $interface_data{"\U$thorn INHERITS\E"}))
+ {
+ next if($ancestor_imp eq '');
+ $thorn_ancestor{uc($thorn)} .= $interface_data{"IMPLEMENTATION \U$ancestor_imp\E THORNS"}. ' ';
+ }
+ }
+
+ # Call find_dep_cycles to find and report cycles
+ $message = &find_dep_cycles(%thorn_ancestor);
+ if ("" ne $message)
+ {
+ $message =~ s/^\s*//g;
+ $message =~ s/\s*$//g;
+ $message =~ s/\s+/->/g;
+ $message = "Found a cyclic dependency in implementation inheritance: ".$message."\n";
+ &CST_error(0,$message,$hint,__LINE__,__FILE__);
+ }
foreach $thorn (@thorns)
{
@@ -618,8 +641,8 @@ sub check_interface_consistency
{
my($thorn, %interface_data) = @_;
my($implementation);
- my($private_group);
- my($ancestor_imp,$ancestor_thorn);
+ my($group,$var1,$var2,$group1,$group2);
+ my($ancestor_imp,$ancestor_thorn,$ancestor2_imp,$ancestor2);
my($message);
# Find implementation
@@ -634,20 +657,59 @@ sub check_interface_consistency
{
$ancestor_thorn = $1;
}
- foreach $private_group (split " ",$interface_data{"\U$thorn\E PRIVATE GROUPS"})
+ foreach $group1 (split ' ', $interface_data{"\U$ancestor_thorn\E PUBLIC GROUPS"})
+ {
+ foreach $var1 (split ' ', $interface_data{"\U$ancestor_thorn\E GROUP \U$group1\E"})
+ {
+ foreach $ancestor2_imp (split " ",$interface_data{"IMPLEMENTATION \U$implementation\E ANCESTORS"})
+ {
+ $ancestor2 = $interface_data{"IMPLEMENTATION \U$ancestor2_imp\E THORNS"};
+ if ($ancestor2 =~ m:(\w+)[^\w]*:)
+ {
+ $ancestor2 = $1;
+ }
+ # skip the second ancestor if it is the first one
+ next if (uc($ancestor2) eq uc($ancestor_thorn));
+
+ foreach $group2 (split ' ', $interface_data{"\U$ancestor2\E PUBLIC GROUPS"})
+ {
+ if (uc($group1) eq uc($group2))
+ {
+ $message = "Group $group1 from ancestor implementation $ancestor_imp in thorn $thorn has same name as \n a public group: $group2 in ancestor implementation $ancestor2_imp (e.g. thorn $ancestor2)";
+ &CST_error(1,$message,"",__LINE__,__FILE__);
+ }
+ if (uc($var1) eq uc($group2))
+ {
+ $message = "Variable $var1 in group $group1 from ancestor implementation $ancestor_imp in thorn $thorn has same name as \n a public group: $group2 in ancestor implementation $ancestor2_imp (e.g. thorn $ancestor2)";
+ &CST_error(1,$message,"",__LINE__,__FILE__);
+ }
+ foreach $var2 (split ' ', $interface_data{"\U$ancestor2\E GROUP \U$group2\E"})
+ {
+ if (uc($var2) eq uc($var1))
+ {
+ $message = "Variable $var1 in group $group1 from ancestor $ancestor_imp in thorn $thorn has same name as \n variable $var2 in public group: $group2 in ancestor implementation $ancestor2_imp (e.g. thorn $ancestor2)";
+ &CST_error(0,$message,"",__LINE__,__FILE__);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ foreach $group (split " ",$interface_data{"\U$thorn\E PRIVATE GROUPS"} . ' '. $interface_data{"\U$thorn\E PUBLIC GROUPS"} )
{
- if ($interface_data{"\U$ancestor_thorn\E PUBLIC GROUPS"} =~ m:(\b$private_group\b):)
+ if ($interface_data{"\U$ancestor_thorn\E PUBLIC GROUPS"} =~ m:(\b$group\b):)
{
- $message = "Private group $private_group in thorn $thorn has same name as \n public group in ancestor implementation $ancestor_imp (e.g. thorn $ancestor_thorn)";
+ $message = "Group $group in thorn $thorn has same name as \n public group in ancestor implementation $ancestor_imp (e.g. thorn $ancestor_thorn)";
&CST_error(0,$message,"",__LINE__,__FILE__);
}
- foreach $var (split " ", $interface_data{"\U$thorn\E GROUP \U$private_group\E"})
+ foreach $var (split " ", $interface_data{"\U$thorn\E GROUP \U$group\E"})
{
foreach $pub_anc(split " ", $interface_data{"\U$ancestor_thorn\E PUBLIC GROUPS"})
{
if ($interface_data{"\U$ancestor_thorn\E GROUP \U$pub_anc\E"} =~ m/\b$var\b/i)
{
- $message = "Private variable $var in group $private_group in thorn $thorn has same name as \n a variable in public group: $pub_anc in ancestor implementation $ancestor_imp (e.g. thorn $ancestor_thorn)";
+ $message = "Variable $var in group $group in thorn $thorn has same name as \n a variable in public group: $pub_anc in ancestor implementation $ancestor_imp (e.g. thorn $ancestor_thorn)";
&CST_error(0,$message,"",__LINE__,__FILE__);
}