: eval 'exec perl -wS $0 ${1+"$@"}' if 0; #************************************************************************* # # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # Copyright 2008 by Sun Microsystems, Inc. # # OpenOffice.org - a multi-platform office productivity suite # # $RCSfile: XMLBuildListParser.pm,v $ # # $Revision: 1.3 $ # # This file is part of OpenOffice.org. # # OpenOffice.org is free software: you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License version 3 # only, as published by the Free Software Foundation. # # OpenOffice.org is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License version 3 for more details # (a copy is included in the LICENSE file that accompanied this code). # # You should have received a copy of the GNU Lesser General Public License # version 3 along with OpenOffice.org. If not, see # # for a copy of the LGPLv3 License. # #************************************************************************* #************************************************************ # Data structure and XML parser/creator for the changeover * # of the current build.lst to build.xlist files * # programmer: Pascal Junck, Sun Microsystems GmbH * #************************************************************ # The current XMLBuildListParser is the second step for the changeover to XML. # It was written to create a complex structure with more possibilities to store informations # of the 'build.lst' files in the new XML files. The important informations were parsed by the # 'buildlst_parser.pl' from the old files and then are (temporary) stored by the set and add # methods in the module 'XMLBuildListParser' and 'XML::Parser'. By the API of this module it's # possible to create the new XML 'build.xlist' files. # If the '$Product' or the '$JobPlatform' (as also '$BuildReqPlatform') have no value, # their value are automatically 'all'. # It doesn't matter whether it's the set/add or the get method, that receives or sends # these optional parameters. # In the created XML file the default values aren't set, because of the constraints of the # 'Document Type Definition'(DTD). # If there is no product/platform attribute in the 'build.xlist' it means a default of 'all'! # The important parameters are: # $ModuleName = it's the name of the current module # $DependencyType = here are the three possible scalar dependency values # for all other depending modules(of the current module): # 'md-simple', 'md-always' and 'md-force' # $Products = which products can be used for the module dependencies # and might have more different whitespace separated values # e.g.'so oo' (scalar type) # $Dir = it means a string(scalar) with the current working directory, # with a '/'(current directory) at the beginning of the string # $JobType = it means a job e.g. 'make' # $Platforms = in this scalar parameter might be more than one different value, # like: 'wnt unx mac' and 'all'('all' includes the three values) # it must be whitespace separated # @DependingDirs = a list(array) of all inner depending directories # of the current working directory # %BuildReq = means a hash with build requirement pairs: # 'BuildReqName'(key) => 'BuildReqPlatform'(value) ############################## begin of main ######################################## use strict; use XML::Parser; package XMLBuildListParser; # global variable for printing out all results at parsing # if the debug variable is set to '1' it prints the results to STDOUT my $Debug = 0; ############################# begin of subroutines ################################### sub new { my $invocant = shift; my $class = ref($invocant) || $invocant; my $self = {}; # no real instance data yet, might change if package is extended bless($self, $class); $$self{'error_string'} = ''; $self->beginXMLStructure(); return $self; } # VG: procedure for a better error handling sub getError { my $self = shift; return $$self{'error_string'}; }; ######################################################################################## # sub: loadXMLFile # gets: $File # optional: - # returns: - # description: get the 'path' of the 'build.xlist'(s), load it in the 'xml parser tree' # and fill it in the own data_structure to make it available for the API ######################################################################################## sub loadXMLFile { my $self = shift; my $File = shift; if (-f $File) { my $TreeParse = new XML::Parser(Style => 'Tree'); my $File_ref; eval { $File_ref = $TreeParse->parsefile($File); }; if ($@) { $@ =~ s/[\r\n]//g; print"ERROR: $@" if ($Debug); $$self{'error_string'} = 'ERROR: ' . $@ . ". Error occured while trying to parse $File"; return 0; } else { filterXMLFile($File_ref); $$self{"ModuleData"} = $File_ref; return 1; } } else { $$self{'error_string'} = "ERROR: cannot find file $File"; return 0; } } ######################################################################################## # sub: filterXMLFile # gets: $ArrayContent_ref # optional: - # returns: - # description: filters all '0' and whitespace based pairs of the XML file # -> all spaces, tabs and new lines ######################################################################################## sub filterXMLFile { my $ArrayContent_ref = shift; # get the number of elements of the array_ref my $Count = getContentCount($ArrayContent_ref); for (my $i = 0; $i < $Count;) { # get each content pair my $Content_ref = getContent($ArrayContent_ref, $i); # in each content pair the first element is either # a tag name or the value '0' my $FirstContent = getTagName($Content_ref); # we need the second part of the content pair to check # which value is inside my $SecondContent = getSecondContent($Content_ref); my $tempArray_ref = ""; if (($FirstContent eq "task") or ($FirstContent eq "depend")) { my $dir = $Content_ref->[1]->[0]->{dir}; $dir =~ s/\/$//; $Content_ref->[1]->[0]->{dir} = $dir; $i++; filterXMLFile($Content_ref); } elsif ($FirstContent eq "0") { # only if there is in the first part a '0' and in the # second part are whitespaces... if ($SecondContent =~ /\s+/) { # ...make a ref at this position $tempArray_ref = @$ArrayContent_ref[1]; # and delete this element pair removeContent($tempArray_ref, $i); # now we have one element pair fewer $Count--; } else { # is there a '0' but in the second part not a whitespace, # increase 'i' by 1 $i++; } } else { # if it's a tag name, increase 'i' by one and call recursive # the 'filterXMLFile' with the 'content ref' $i++; # look further after the '0' and whitespace content filterXMLFile($Content_ref); } } } ######################################################################################## # sub: removeContent # gets: $File_ref, $Count # optional: - # returns: - # description: removes the '0' and the whitespace based pairs of the XML structure # whitespace could be: tabs, new lines and whitespace itself ######################################################################################## sub removeContent { my $tempArray_ref = shift; my $i = shift; my $Start = (2*$i) + 1; splice(@$tempArray_ref, $Start, 2); } ######################################################################################## # sub: beginXMLStructure # gets: $ModuleData_ref # optional: - # returns: - # description: create a new beginning of the XML file structure ######################################################################################## sub beginXMLStructure { my $self = shift; # global variable for the complete filled data structure my $ModuleData_ref = createTag("build-list", {}); $$self{"ModuleData"} = $ModuleData_ref; } ######################################################################################## # sub: insertContent # gets: $HigherLevelTag_ref, $currentTag_ref, $Pos # optional: - # returns: - # description: insert a content at the right (alphabetical sorted) position ######################################################################################## sub insertContent { my $HigherLevelTag_ref = shift; my $currentTag_ref = shift; my $Pos = shift; my $Array_ref = $HigherLevelTag_ref->[1]; $Pos = ($Pos*2)+1; splice(@$Array_ref, $Pos, 0, @$currentTag_ref); } ######################################################################################## # sub: saveXMLFile # gets: $Path # optional: - # returns: - # description: creates a XML file of the whole data structure ######################################################################################## sub saveXMLFile { my $self = shift; my $Path = shift; my $ModuleData_ref = $$self{"ModuleData"}; # open the filehandle 'CREATE_XML' for creating the XML files open (SAVE_XML, ">".$Path) or die "Error. Open the file wasn't successful!\n\n"; select SAVE_XML; print"\n"; print"\n"; print"\n"; printTag($ModuleData_ref); # flush the buffer # it's the same like the both lines below here, but we make it manually without module 'IO' # use IO::Handle; # SAVE_XML -> autoflush(1); $| = 1; select STDOUT; close (SAVE_XML); } ######################################################################################## # sub: printTag # gets: $Tag_ref # optional: - # returns: - # description: prints out each tag of the existing data structure (XML tree) ######################################################################################## sub printTag { my $Tag_ref = shift; # the first time we call this function the 'pos counter' has the default value of '0', # because it is for the begin tag -> it shouldn't have a distance to the left side my $PosCounter = shift || 0; # makes it possible that each tag has a specified distance from the left sided margin my $Distance = " " x $PosCounter; # it's possible that the content is a text(case 1) between a begin and end tag # or a tag name(case 2) # case 1: ( 0 , "Text between the begin and end tag" ) my $TagName = getTagName($Tag_ref); if ($TagName eq "0") { print"$Tag_ref->[1]"; } # case 2: ( "TagName" , (...) ) else { # open the tag # only a new line if it is not the first tag print"\n" if ($PosCounter != 0); print $Distance."<".$TagName; my $Attributes_ref = getAttributesRef($Tag_ref); # print all sorted attributes of this tag foreach my $Attribute (sort keys %$Attributes_ref) { my $value = $$Attributes_ref{$Attribute}; print" $Attribute=\"$value\""; } # get the number of elements of the array my $ContentCount = getContentCount($Tag_ref); # close the tag # if it is an empty tag create a '/' before we close it with '>' print"/" if ($ContentCount == 0); print">"; # get and print all tags recursive for (my $i = 0; $i < $ContentCount; $i++) { # here we get the content of the current tag, # we rise the 'pos counter' that each level of tags # has a specified distance from the left side printTag(getContent($Tag_ref, $i), $PosCounter + 2); } # check that the tag has a text between the begin and end tag # first: had the tag further inner tags? if ($ContentCount > 0) { my $Content_ref = getContent($Tag_ref, 0); my $TagName = getTagName($Tag_ref); my $TagContent = getTagName($Content_ref); # if a tag has a begin tag and a following text, create the end tag behind the text print"" if ($TagContent eq "0"); print"\n".$Distance."" if ($TagContent ne "0"); } } } ######################################################################################## # sub: getTagName # gets: $Content_ref # optional: - # returns: $TagName # description: gets a reference of an array and returns the tag name at position '0' ######################################################################################## sub getTagName { my $Content_ref = shift; my $TagName = $$Content_ref[0]; return $TagName; } ######################################################################################## # sub: getSecondContent # gets: $Content_ref # optional: - # returns: $SecondContent # description: gets a reference of an array and returns the second value(index '1') ######################################################################################## sub getSecondContent { my $Content_ref = shift; my $SecondContent = $$Content_ref[1]; return $SecondContent; } ######################################################################################## # sub: createSortKey # gets: $DependencyType, $DepModuleName # optional: - # returns: $SortKey # description: creates a key with a number(depending of the dependency type) # and a string and returns it ######################################################################################## sub createSortKey { my $DependencyType = shift; my $DepModuleName = shift; my $DepTypeAsValue = 0; if ($DependencyType eq "md-simple") { $DepTypeAsValue = 1; } elsif ($DependencyType eq "md-always") { $DepTypeAsValue = 2; } elsif ($DependencyType eq "md-force") { $DepTypeAsValue = 3; } my $SortKey = $DepTypeAsValue.$DepModuleName; return $SortKey; } ######################################################################################## # sub: searchTag # gets: $TagName, $Tag_ref # optional: - # returns: $TagValues_ref # description: gets a reference and goes in the lower level tag, # looks after the specified tag name and returns the reference # of itself and the neighbour element ######################################################################################## sub searchTag { my $TagName = shift; my $Tag_ref = shift; my $TagSerie_ref = $Tag_ref->[1]; # (all elements of the array) - 1 => highest index of the array my $IndexEnd = scalar(@$TagSerie_ref)-1; my $TagValues_ref = undef; for (my $i = 1; $i <= $IndexEnd; $i += 2) { if ($TagSerie_ref->[$i] eq $TagName) { @$TagValues_ref = @$TagSerie_ref[$i..$i+1]; last; } } return $TagValues_ref; } ######################################################################################## # sub: createTag # gets: $TagName, $Attribute_ref # optional: - # returns: $Tag_ref # description: creates an anonymous array with a tag name and the reference of its # attributes; then returns the reference of this array ######################################################################################## sub createTag { my $TagName = shift; my $Attribute_ref = shift; my $Tag_ref = [$TagName, [$Attribute_ref]]; return $Tag_ref; } ######################################################################################## # sub: createText # gets: $Text # optional: - # returns: $TagText_ref # description: creates an anonymous array(which contains a '0' and a string) # for the data structure and returns a reference of it ######################################################################################## sub createText { my $Text = shift; my $TagText_ref = [0, $Text]; return $TagText_ref; } ######################################################################################## # sub: addContent # gets: $Tag_ref, $NextInfos_ref # optional: - # returns: - # description: creates and adds a tag with its following content ######################################################################################## sub addContent { # '$NextInfos_ref' has two infos: # either: '0' and a string -> [Tag, [{}, 0 , string ]] # or: 'tag' and a ref of a anonymous array -> [Tag, [{}, newTag, [.....] ]] my $Tag_ref = shift; my $NextInfos_ref = shift; my $SecondPart_ref = $Tag_ref->[1]; # '$Tag_ref' gets now the right structure: # e.g. ['tag1', [{}, 0, "text of tag1" ...]...] # or ['tag1', [{}, 'tag2', [...] ...]...] push(@$SecondPart_ref, @$NextInfos_ref); } ######################################################################################## # sub: getContent # gets: $Tag_ref, $i # optional: - # returns: \@Content (ref of array 'content') # description: creates and returns a reference of an array with two elements, # which are a part of the array of the current tag ######################################################################################## sub getContent { my $Tag_ref = shift; my $i = shift; # e.g. # [ "tag 1", [ {} , 0 , "string", "tag 2", [{}..], "tag 3", [{}..], ..] ..] # $Tag_ref [ [0] [1] ..] # $Content_ref [ [0] [1] [2] [3] [4] [5] [6] ..] my $Content_ref = $$Tag_ref[1]; # '$start' contains: elements with the index 1, 3, 5 ...(and so on) # '$end' contains: elements with the index 2, 4, 6 ...(and so on) my $start = (2 * $i) + 1; my $end = $start + 1; my @Content = @$Content_ref[$start..$end]; return \@Content; } ######################################################################################## # sub: getAttribute # gets: $Tag_ref, $AttributeName # optional: - # returns: $Attribute # description: finds and returns an attribute as a string ######################################################################################## sub getAttribute { my $Tag_ref = shift; my $AttributeName = shift; # [ "tag1", [ { attribute1 = "..", attribute2 = ".." } , "tag2"... ] ] # Tag_ref [ [0] [1] ] ] # [ [0]->'attribute1' , [0]->'attribute2' , [1] ... ] ] # get the scalar of the value of the 'AttributeName' in the anonymous hash my $Attribute = $Tag_ref->[1]->[0]->{$AttributeName}; return $Attribute; } ######################################################################################## # sub: getAttributeRef # gets: $Tag_ref # optional: - # returns: $Attribute_ref # description: finds and returns the reference of the hash which contains the attributes ######################################################################################## sub getAttributesRef { my $Tag_ref = shift; # [ "tag1", [ { attribute1 = "..", attribute2 = ".." } , "tag2"... ] ] # Tag_ref [ [0] [1] ] ] # [ [0] , [1] ] ] # get the reference of the anonymous hash my $Attribute_ref = $Tag_ref->[1]->[0]; return $Attribute_ref; } ######################################################################################## # sub: getContentCount # gets: $Tag_ref # optional: - # returns: $IndexValue # description: returns the sum of elements pairs of the array (less the anonymous hash) ######################################################################################## sub getContentCount { my $Tag_ref = shift; # get the content array (address of the inner array) my $Content_ref = $$Tag_ref[1]; # get the number of the element pairs of the array (without the anonymous hash) my $IndexValue = scalar(@$Content_ref); $IndexValue = ($IndexValue-1)/2; return $IndexValue; } ######################################################################################## # sub: getIterationData # gets: $TagName # optional: - # returns: $IndexValue, $TagDepend_ref # description: gets a tag name and returns the sum of elements pairs of the array # (less the anonymous hash) and the reference of the anonymous array ######################################################################################## sub getIterationData { my $self = shift; my $TagName = shift; my $ModuleData_ref = $$self{"ModuleData"}; my $TagDepend_ref = searchTag($TagName, $ModuleData_ref); my $IndexValue = getContentCount($TagDepend_ref); return ($IndexValue, $TagDepend_ref); } ######################################################################################## # sub: printErrorMessage # gets: $BuildReqPlatforms or $Platforms or $Products # optional: - # returns: - # description: it's an error, if a platform or a product content (e.g.'so oo') # has at least one valid value and also the value 'all', # because 'all' includes all other possible values ######################################################################################## sub printErrorMessage { my $self = shift; my $Content = shift; my $ModuleData_ref = $$self{"ModuleData"}; my $Module_ref = searchTag("module-name", $ModuleData_ref); my $ModuleContent_ref = getContent($Module_ref, 0); my $Module = @$ModuleContent_ref[1]; print"Error in module <$Module> in Content <$Content>!\n"; print"The value 'all' includes all currently existing valid values.\n\n"; } ######################################################################################## # sub: adjustRedundancy # gets: $Task_ref, $JobPlatform, $BuildReq_ref # optional: - # returns: - # description: the tag (it means 'job') should be created with no redundant infos, # like: ... # ... # # # it should be: # ######################################################################################## sub adjustRedundancy { my $Task_ref = shift; my $JobPlatform = shift; my $BuildReq_ref = shift; my %sortedJobPlatforms = (); my @JobPlatforms = (); my $PlatformContent = ""; # get the 'task platforms' in one content my $Attributes_ref = getAttributesRef($Task_ref); # get the existing 'task platform' my $existingPlatform = getAttribute($Task_ref, "platform"); $existingPlatform = "all" if (!($existingPlatform)); if ( ($existingPlatform ne "all") && ($JobPlatform ne "all") ) { # get the sorted platform content $sortedJobPlatforms{$JobPlatform} = ""; $sortedJobPlatforms{$existingPlatform} = ""; @JobPlatforms = sort keys %sortedJobPlatforms; $PlatformContent = join " ", @JobPlatforms; $$Attributes_ref{"platform"} = $PlatformContent; } elsif ( ($existingPlatform ne "all") && ($JobPlatform eq "all") ) { delete $$Attributes_ref{"platform"}; } if ($BuildReq_ref) { my $JobType_ref = getContent($Task_ref, 0); # if it exists add the 'build requirements' at the # previous(with the same directory as the current) tag addBuildReq($JobType_ref, $BuildReq_ref); } } ######################################################################################## # sub: addBuildReq # gets: $JobTypeInfos_ref, $BuildReq_ref # optional: - # returns: - # description: add the 'build requirements' to the existing data structure # case 1: if the 'job directory' is not redundant # case 2: if it is redundant create it to the first existing 'job' ######################################################################################## sub addBuildReq { my $JobTypeInfos_ref = shift; my $BuildReq_ref = shift; my @sortedBuildReqPlatforms = (); foreach my $BuildReqName (sort keys %$BuildReq_ref) { my $BuildReqPlatforms = $$BuildReq_ref{$BuildReqName}; $BuildReqPlatforms = "all" if (!($BuildReqPlatforms)); my $Attributes_ref = {"name" => "$BuildReqName"}; # it's wrong, if in a platform content(e.g. "unx wnt") are at least # one or more platform(s) and within a 'all' term, # because 'all' is default and means it includes all other possible values! if ( ($BuildReqPlatforms ne "all") && ($BuildReqPlatforms =~ /\ball\b/) ) { printErrorMessage($BuildReqPlatforms); } elsif (!($BuildReqPlatforms =~ /\ball\b/)) { @sortedBuildReqPlatforms = sort(split(/\s+/, $BuildReqPlatforms)); $BuildReqPlatforms = join " ", @sortedBuildReqPlatforms; $$Attributes_ref{"platform"} = "$BuildReqPlatforms"; } # create the tag my $BuildReqInfos_ref = createTag("build-requirement", $Attributes_ref); # append the tag to the <'$JobType'> tag addContent($JobTypeInfos_ref, $BuildReqInfos_ref); } } ######################################################################################## # sub: checkJobRedundancy # gets: $Task_ref, $JobType, $DependingDirs_ref, $JobPlatform, $BuildReq_ref # optional: - # returns: $LineIsRedundant # description: checks whether the values of the 'job' line are redundant, like: # 'job dir', 'job'(e.g.: make) and 'depending dirs' ######################################################################################## sub checkJobRedundancy { my $Task_ref = shift; my $JobType = shift; my $DependingDirs_ref = shift; my $JobPlatform = shift; my $BuildReq_ref = shift; my $LineIsRedundant = 0; # get the ref of the existing 'depending directories' # if they also equal with the current 'depending directories', # make one tag instead of two, which differences only in the platform # (and the 'build requirement', if it exists) my $JobType_ref = getContent($Task_ref, 0); my $JobName = getTagName($JobType_ref); # get the existing 'task platform' my $existingPlatform = getAttribute($Task_ref, "platform"); # are the jobs equal? if ($JobType eq $JobName) { my @existingDepDirs = (); my $IndexEnd = getContentCount($JobType_ref); # get all existing 'depending dirs' of this redundant 'job' for (my $j = 0; $j < $IndexEnd; $j++) { my $Content_ref = getContent($JobType_ref, $j); my $TagName = getTagName($Content_ref); # create an array of the 'depending directories' if ($TagName eq "depend") { my $DepDir = getAttribute($Content_ref, "depend"); push(@existingDepDirs, $DepDir); } } # if now the current 'depending dirs' equal with the existing, # we know that is redundant and have to create only one instead # of two tags, e.g. # before: ... # ... # # # it should be: # if (@$DependingDirs_ref eq @existingDepDirs) { $LineIsRedundant = 1; # check redundant directories and create no redundant 'task dirs' adjustRedundancy($Task_ref, $JobPlatform, $BuildReq_ref); } } return $LineIsRedundant; } ######################################################################################## # sub: existsTag # gets: $TagName # optional: - # returns: $TagExists_ref # description: checks whether that a tag exists and returns the ref of the content ######################################################################################## sub existsTag { my $self = shift; my $TagName = shift; my $TagExists_ref = undef; my $ModuleData_ref = $$self{"ModuleData"}; # check whether that the tag exists $TagExists_ref = searchTag($TagName, $ModuleData_ref); return $TagExists_ref; } ######################################################################################## # API - (internal) 'set/add' methods # ######################################################################################## ######################################################################################## # sub: setModuleName # gets: $ModuleName # optional: - # returns: - # description: gets the name of the current module and set it at the right position # in the data structure ######################################################################################## sub setModuleName { my $self = shift; my $ModuleName = shift; my $ModuleData_ref = $$self{"ModuleData"}; my $Tag_ref = createTag("module-name", {}); my $TagText_ref = createText($ModuleName); addContent($Tag_ref, $TagText_ref); addContent($ModuleData_ref, $Tag_ref); } ######################################################################################## # sub: addModuleDependencies # gets: $ModuleName, $DependencyType, $Products # optional: $Products(default: 'all' -> includes currently 'so' and 'oo') # but the default should not set in the data structure, # it's only a 'Document Type Definition' based term # returns: - # description: add the module dependencies and their attributes into the data structure ######################################################################################## sub addModuleDependencies { my $self = shift; my $ModuleName = shift; my $DependencyType = shift; my $Products = shift || "all"; my $ModuleData_ref = $$self{"ModuleData"}; my @sortedProducts = (); # change all possible upper cases to lower cases $Products =~ s/($Products)/\L$Products/; # before we add the module dependencies, we have to prove that the tag was set # because this tag must be set once before the module dependency tags begin my $ModuleDepend_ref = searchTag("module-depend", $ModuleData_ref); # if it doesn't exist, create this tag '' if (!($ModuleDepend_ref)) { $ModuleDepend_ref = createTag("module-depend", {}); # add it to the global data structure addContent($ModuleData_ref, $ModuleDepend_ref); } my $Attributes_ref = {"module" => "$ModuleName"}; # it's wrong, if in a product content(e.g. "so") are at least # one or more product(s) and within a 'all' term, # because 'all' is default and means it includes all other possible values! if ( ($Products ne "all") && ($Products =~ /\ball\b/) ) { printErrorMessage($Products); } elsif (!($Products =~ /\ball\b/)) { @sortedProducts = sort(split(/\s+/ ,$Products)); $Products = join " ", @sortedProducts; $$Attributes_ref{"product"} = "$Products"; } my $ModuleDependenciesInfos_ref = createTag("$DependencyType", $Attributes_ref); my $currentKey = createSortKey($DependencyType, $ModuleName); # search and get the position in which we have to insert the current 'module depend name' # at first get the current 'module depend name' my $currentName = getAttribute($ModuleDependenciesInfos_ref, "module"); # get the information about the number of 'Contents'(= elements) of the array my $ContentCount = getContentCount($ModuleDepend_ref); # we have to sort the serie of the 'name' contents, # therefore we need a 'Pos'(position) of the array in which we want to sort in the 'name' content my $Pos = 0; # and we need a control variable 'isInsert' # that we won't add the 'name' and the content more than one time my $isInsert = 0; for (my $i = 0; $i < $ContentCount; $i++) { # get each 'Content' of the array = ('task', ARRAY(...)) my $Content_ref = getContent($ModuleDepend_ref, $i); my $TagName = getTagName($Content_ref); # get the existing 'task dir' to compare it with the current 'task dir' my $existingName = getAttribute($Content_ref, "module"); my $existingKey = createSortKey(getTagName($Content_ref), $existingName); # compare both dirs... # only if the 'current dir' is lower than a 'existing dir' # insert it in the data structure if ($currentKey lt $existingKey) { $Pos = $i; insertContent($ModuleDepend_ref, $ModuleDependenciesInfos_ref, $Pos); $isInsert = 1; last; } } # only if the 'current name' is greater (or equal) than the other 'existing names' # insert it at the end of the data structure addContent($ModuleDepend_ref, $ModuleDependenciesInfos_ref) if ($isInsert == 0); } ######################################################################################## # sub: addJob # gets: $Dir, $JobType, $JobPlatform, $DependingDirs_ref, $BuildReq_ref, # $JobPlatform, $DependingDirs_ref, $BuildReq_ref # optional: $JobPlatform(default: 'all' -> includes all other possible values), # $DependingDirs_ref, $BuildReq_ref # returns: - # description: add the infos about a job from the old build lists(by ascii parser) and # sort it in the data structure ######################################################################################## sub addJob { my $self = shift; my $Dir = shift; my $JobType = shift; my $JobPlatform = shift || "all"; my $DependingDirs_ref = shift; my $BuildReq_ref = shift; my $ModuleData_ref = $$self{"ModuleData"}; # before we add the "build" tag, we have to prove that the tag was set # because this tag must be set once before the job tag(s) follows my $buildTag_ref = searchTag("build", $ModuleData_ref); # if it doesn't exist, create the tag '' if (!($buildTag_ref)) { # If the tag wasn't found, create it $buildTag_ref = createTag("build", {}); # add it to the global data structure addContent($ModuleData_ref, $buildTag_ref); } my $Attributes_ref = {"dir" => "$Dir"}; # it's wrong, if a 'job platform' content(e.g. "unx wnt") has at least # one or more 'job platform(s)' and an 'all' term, # because 'all' is default and means it includes all other possible values if ( ($JobPlatform ne "all") && ($JobPlatform =~ /\ball\b/) ) { printErrorMessage($JobPlatform); } elsif (!($JobPlatform =~ /\ball\b/)) { my @sortedPlatforms = sort(split /\s+/, $JobPlatform); $JobPlatform = join " ", @sortedPlatforms; $$Attributes_ref{"platform"} = "$JobPlatform"; } # create the tags: , and (if it exists)... # and/or my $taskInfos_ref = createTag("task", $Attributes_ref); # search and get the position in which we have to insert the current task # at first get the current 'task directory' my $currentDir = getAttribute($taskInfos_ref, "dir"); # get the information about the number of 'Contents'(= elements) of the array my $IndexValue = getContentCount($buildTag_ref); # we have to sort the serie of the 'task contents', # therefore we need a '$pos'(position) of the array in which we want to sort in the 'task content' my $Pos = 0; # and we need a control variable 'isInsert' # that we won't add the 'task content' more than one time my $isInsert = 0; # control variable for the redundancy check my $LineIsRedundant = 0; # go in the array of the corresponding tag element for (my $i = 0; $i < $IndexValue; $i++) { # get each content of the tag => ('task1', ARRAY1(...), task2...) my $Task_ref = getContent($buildTag_ref, $i); # get the existing 'task dir' to compare it with the current 'task dir' my $existingDir = getAttribute($Task_ref, "dir"); # is the 'job dir' redundant? if ($currentDir eq $existingDir) { $LineIsRedundant = checkJobRedundancy($Task_ref, $JobType, $DependingDirs_ref, $JobPlatform, $BuildReq_ref); } # if it's not a redundant line, compare both dirs: # only if the 'current dir' is lower than an 'existing dir' # insert it in the data structure if ( ($LineIsRedundant == 0) && ($currentDir lt $existingDir) ) { $Pos = $i; insertContent($buildTag_ref, $taskInfos_ref, $Pos); $isInsert = 1; last; } } # only if the 'current dir' is greater (or equal) than the other 'existing dirs' # and it is not redundant insert it at the end of the data structure if ( ($isInsert == 0) && ($LineIsRedundant == 0) ) { addContent($buildTag_ref, $taskInfos_ref); } if ($LineIsRedundant == 0) { # create the <'$JobType'> tag my $JobTypeInfos_ref = createTag($JobType, {}); # append the <'$JobType'> tag to the tag addContent($taskInfos_ref, $JobTypeInfos_ref); # before we add the "depend" infos # we have to get the alphabetical sorted 'Depending Directories' @$DependingDirs_ref = sort(@$DependingDirs_ref) if ($DependingDirs_ref); foreach my $DependDir (@$DependingDirs_ref) { my $DependInfos_ref = createTag("depend", {"dir" => "$DependDir"}); # append the tag to the <'$JobType'> tag addContent($JobTypeInfos_ref, $DependInfos_ref); } # if a 'build requirement' exists, create the tag if ($BuildReq_ref) { addBuildReq($JobTypeInfos_ref, $BuildReq_ref); } } } ######################################################################################## # end of (internal) 'set/add' methods # ######################################################################################## ######################################################################################## # API - (external) 'get' methods # ######################################################################################## ######################################################################################## # sub: getModuleDependencies # gets: $Product, $DependencyType # optional: $Product(default: 'all', means all currently used valid values), # $DependencyType(default: 'md-simple', 'md-always' and 'md-force') # returns: @ModuleDependencies # description: gets a ref of an array (with the products) and creates and # returns an array with the sorted depending modules ######################################################################################## sub getModuleName { my $self = shift; if ($self->existsTag("module-name")) { my ($IndexValue, $ModuleDepend_ref) = $self->getIterationData("module-name"); return $$ModuleDepend_ref[1][2]; }; return ""; }; sub getModuleDependencies { my $self = shift; my $Products_ref = shift; my $DependencyType = shift || "all"; push(@$Products_ref, "all") if (!scalar @$Products_ref); my $Product = ""; my %tempModuleDeps = (); my @ModuleDependencies = (); my $ModuleData_ref = $$self{"ModuleData"}; # check whether that the tag exists if ($self->existsTag("module-depend")) { # change all possible upper cases to lower cases $DependencyType =~ s/($DependencyType)/\L$DependencyType/ if ($DependencyType ne "all"); foreach $Product (@$Products_ref) { # change all possible upper cases to lower cases $Product =~ s/($Product)/\L$Product/; my $ProductContent = undef; my $ModuleDependencyName = ""; # get the number of elements and the ref of the tag my ($IndexValue, $ModuleDepend_ref) = $self->getIterationData("module-depend"); for (my $i = 0; $i < $IndexValue; $i++) { my $Content_ref = getContent($ModuleDepend_ref, $i); my $ModuleDependencyName = getAttribute($Content_ref, "module"); # get the name of each existing tag my $TagName = getTagName($Content_ref); $ProductContent = getAttribute($Content_ref, "product"); # if the attribute 'product' wasn't set in the internal data structure, # it means the default of 'all' is valid and includes all other possible values $ProductContent = "all" if (!($ProductContent)); if ($Product ne "all") { if ($DependencyType ne "all") { # if the caller wants all (e.g.)'so' product based dependency types, # we must get the 'so' and the 'all' matching products # because 'all' matches also the product 'so' if ( ($DependencyType eq $TagName) && ((($ProductContent eq "all") || $ProductContent =~ /\b($Product)\b/)) ) { $tempModuleDeps{$ModuleDependencyName} = ""; print"ModuleDeps (Product != 'all' && DepType != 'all') = <$ModuleDependencyName>\n" if ($Debug); } } # we get from the caller only the 'product' parameter, # 'dependency type' is now 'all'(default) and includes all possible values elsif ( ($ProductContent =~ /\b($Product)\b/) || ($ProductContent eq "all") ) { $tempModuleDeps{$ModuleDependencyName} = ""; print"ModuleDeps (Product != 'all' && DepType = 'all') = <$ModuleDependencyName>\n" if ($Debug); } } # now the product is 'all' and we only need to check the 'dependency type' elsif ($DependencyType ne "all") { if ($DependencyType eq $TagName) { $tempModuleDeps{$ModuleDependencyName} = ""; print"ModuleDeps (Product = 'all' && DepType != 'all') = <$ModuleDependencyName>\n" if ($Debug); } } else { $tempModuleDeps{$ModuleDependencyName} = ""; print"ModuleDeps (Product = 'all' && DepType = 'all') = <$ModuleDependencyName>\n" if ($Debug); } } } @ModuleDependencies = sort keys %tempModuleDeps; } print"ModuleDependencies = <@ModuleDependencies>\n" if ($Debug); return @ModuleDependencies; } ######################################################################################## # sub: getModuleDepType # gets: $DepModuleName # optional: - # returns: $DependencyType # description: gets a module name and returns the dependency type of it ######################################################################################## sub getModuleDepType { my $self = shift; my $DepModuleName = shift; my $DependencyType = ""; my $ModuleData_ref = $$self{"ModuleData"}; # check whether that the tag exists if ($self->existsTag("module-depend")) { # change all possible upper cases to lower cases $DepModuleName =~ s/($DepModuleName)/\L$DepModuleName/; my ($IndexValue, $ModuleDepend_ref) = $self->getIterationData("module-depend"); for (my $i = 0; $i < $IndexValue; $i++) { my $Content_ref = getContent($ModuleDepend_ref, $i); my $existingModuleName = getAttribute($Content_ref, "module"); if ($DepModuleName eq $existingModuleName) { $DependencyType = getTagName($Content_ref); last; } } } print"DependencyType = <$DependencyType>\n" if ($Debug); return $DependencyType; } ######################################################################################## # sub: getModuleProducts # gets: $DepModuleName # optional: - # returns: @ModuleProducts # description: gets a module name and returns the associated products ######################################################################################## sub getModuleProducts { my $self = shift; my $DepModuleName = shift; my @ModuleProducts = (); my $ModuleData_ref = $$self{"ModuleData"}; # check whether that the tag exists if ($self->existsTag("module-depend")) { # change all possible upper cases to lower cases $DepModuleName =~ s/($DepModuleName)/\L$DepModuleName/; my $ProductContent = undef; my ($IndexValue, $ModuleDepend_ref) = $self->getIterationData("module-depend"); for (my $i = 0; $i < $IndexValue; $i++) { my $Content_ref = getContent($ModuleDepend_ref, $i); my $existingModuleName = getAttribute($Content_ref, "module"); # if the attribute 'product' wasn't set in the internal data structure, # it means the default of 'all' is valid and includes all other possible values $ProductContent = getAttribute($Content_ref, "product"); if ($DepModuleName eq $existingModuleName) { $ProductContent = "all" if (!($ProductContent)); @ModuleProducts = split /\s+/, $ProductContent; last; } } } print"Products = <@ModuleProducts>\n" if ($Debug); return @ModuleProducts; } ######################################################################################## # sub: getProducts # gets: - # optional: - # returns: @ModuleProducts # description: returns the products of the whole depending modules # each found product name may occurs only once in the module products array ######################################################################################## sub getProducts { my $self = shift; my $ProductContent = undef; my @tempProducts = (); my @ModuleProducts = (); my %Products = (); my $ModuleData_ref = $$self{"ModuleData"}; # check whether that the tag exists if ($self->existsTag("module-depend")) { my ($IndexValue, $ModuleDepend_ref) = $self->getIterationData("module-depend"); for (my $i = 0; $i < $IndexValue; $i++) { my $Content_ref = getContent($ModuleDepend_ref, $i); $ProductContent = getAttribute($Content_ref, "product"); # if the attribute 'product' wasn't set in the internal data structure, # it means the default of 'all' is valid and includes all other possible values # but here we need only all 'not-all' values! if (!($ProductContent)) { $ProductContent=""; } else { # here are the products of the current depending module @tempProducts = split /\s+/, $ProductContent; foreach my $Product (@tempProducts) { $Products{$Product} = ""; } } } # fill the sorted 'module products' in the array @ModuleProducts = sort keys %Products; } print"All ModuleProducts = <@ModuleProducts>\n" if ($Debug); return @ModuleProducts; } ######################################################################################## # sub: getJobDirectories # gets: $JobType, $JobPlatform # optional: $JobType, $JobPlatform(default: 'all' -> includes all possible values) # returns: @JobDirectories # description: creates and returns an array with the sorted directories, which # fulfil the expected values of the job type and the job platform ######################################################################################## sub getJobDirectories { my $self = shift; my $JobType = shift; my $JobPlatform = shift || "all"; my @JobDirectories = (); my $ModuleData_ref = $$self{"ModuleData"}; # check whether that the tag exists if ($self->existsTag("build")) { # change all possible upper cases to lower cases $JobType =~ s/($JobType)/\L$JobType/ if ($JobType); $JobPlatform =~ s/($JobPlatform)/\L$JobPlatform/ if ($JobPlatform ne "all"); my $PlatformContent = undef; my %tempJobDirectories = (); # get the ref of the tag my ($IndexValue, $Build_ref) = $self->getIterationData("build"); for (my $i = 0; $i < $IndexValue; $i++) { my $Content_ref = getContent($Build_ref, $i); my $PlatformContent = getAttribute($Content_ref, "platform"); my $existingDir = getAttribute($Content_ref, "dir"); # three cases are possible... if ($JobType) { my $JobType_ref = getContent($Content_ref, 0); my $existingJobType = getTagName($JobType_ref); # if the attribute 'job platform' wasn't set in the internal data structure, # it means the default of 'all' is valid and includes all other possible values $PlatformContent = "all" if (!($PlatformContent)); # first case: we get from the caller the parameters 'job type' and 'job platform' if ($JobPlatform ne "all") { # if the caller wants all e.g.'wnt' job platform based directories, # we have to get the 'wnt' or the 'all' matching platform # because 'all' includes also 'wnt' if ( ($JobType eq $existingJobType) && (($PlatformContent =~ /\b($JobPlatform)\b/) || ($PlatformContent eq "all")) ) { $tempJobDirectories{$existingDir} = ""; } } # second case: we get from the caller only the 'job type' parameter # 'job platform' is now 'all'(default) and includes all possible values elsif ($JobType eq $existingJobType) { $tempJobDirectories{$existingDir} = ""; } } # third case: we get from the caller no parameter; now we take each existing 'job directory', # no matter which 'job type' and 'job platform' it has else { $tempJobDirectories{$existingDir} = ""; } } # sort each unique 'job directory' alphabetical @JobDirectories = sort keys %tempJobDirectories; } print"JobDirectories = <@JobDirectories>\n" if ($Debug); return @JobDirectories; } ######################################################################################## # sub: getDirDependencies # gets: $Dir, $JobType, $JobPlatform # optional: $JobPlatform(default: 'all' -> includes all possible values) # returns: @JobDependencies # description: creates and returns an array with the sorted depending directories ######################################################################################## sub getDirDependencies { my $self = shift; my $Dir = shift; my $JobType = shift; my $JobPlatform = shift || "all"; my @JobDependencies = (); my $ModuleData_ref = $$self{"ModuleData"}; # check whether that the tag exists if ($self->existsTag("build")) { # change all possible upper cases to lower cases $JobType =~ s/($JobType)/\L$JobType/; $JobPlatform =~ s/($JobPlatform)/\L$JobPlatform/ if ($JobPlatform ne "all"); my $PlatformContent = undef; my %tempJobDependencies = (); # first we need a reference of the higher level tag my ($IndexValue, $Build_ref) = $self->getIterationData("build"); # get all 'job directories' with the matching values of the 'job type' and the 'job platform' my @tempDepDirs = (); @tempDepDirs = $self->getJobDirectories($JobType, $JobPlatform); # get each content of the tag for (my $i = 0; $i < $IndexValue; $i++) { # get the ref of the content of the tag my $Task_ref = getContent($Build_ref, $i); # get both attributes: 'job dir' and 'job platform' my $existingDir = getAttribute($Task_ref, "dir"); my $PlatformContent = getAttribute($Task_ref, "platform"); # if the attribute 'job platform' wasn't set in the internal data structure, # it means the default of 'all' is valid and includes all other possible values $PlatformContent = "all" if (!($PlatformContent)); # get the 'job type' ref which is inside the tag on position '0' my $JobType_ref = getContent($Task_ref, 0); my $existingJobType = getTagName($JobType_ref); if ( ($Dir eq $existingDir) && ($JobType eq $existingJobType) ) { # each 'job type' can have several 'depends' and 'build requirements' # here we get the number of the including elements my $IndexEnd = getContentCount($JobType_ref); for (my $j = 0; $j < $IndexEnd; $j++) { # create a ref of the existing content my $Content_ref = getContent($JobType_ref, $j); # the content_ref can be 'depend' or 'build requirement' # but we only need the 'depend' informations next if (getTagName($Content_ref) ne "depend"); # get the 'depend dir' my $DependDir = getAttribute($Content_ref, "dir"); # look in the list of all existing 'job directories' foreach my $DepDir (@tempDepDirs) { # get it, if one of these 'job dirs' is equal with one of the 'depending dirs' if ($DepDir eq $DependDir) { # get all unique values only once $tempJobDependencies{$DepDir} = ""; } } } } } # get the unique sorted values in the array @JobDependencies = sort keys %tempJobDependencies; } print"Depending Dirs = <@JobDependencies>\n" if ($Debug); return @JobDependencies; } ######################################################################################## # sub: getJobTypes # gets: $Dir # optional: - # returns: @JobTypes # description: creates and returns an array with the sorted 'job types' ######################################################################################## sub getJobTypes { my $self = shift; my $Dir = shift; my @JobTypes = (); my $ModuleData_ref = $$self{"ModuleData"}; # check whether that the tag exists if ($self->existsTag("build")) { # it's for creating unique 'job types' which exists only once in the (later) array my %tempJobTypes = (); # first we need a reference of the higher level tag my ($IndexValue, $Build_ref) = $self->getIterationData("build"); for (my $i = 0; $i < $IndexValue; $i++) { # get the ref of the tag my $Task_ref = getContent($Build_ref, $i); my $existingDir = getAttribute($Task_ref, "dir"); # we only need the 'task(s)' with the matching dir next if ($Dir ne $existingDir); # get the ref of the tag at the position '0' my $JobType_ref = getContent($Task_ref, 0); my $JobType = getTagName($JobType_ref); # get the 'job type' as a key in the hash # so we can guarantee that each 'job type' stays unique! $tempJobTypes{$JobType} = ""; } # fill the unique sorted 'job types' in the array @JobTypes = sort keys %tempJobTypes; } print"JobTypes = <@JobTypes>\n" if ($Debug); return @JobTypes; } ######################################################################################## # sub: getJobBuildReqs # gets: $Dir, $BuildReqPlatform # optional: $BuildReqPlatform(default: 'all' -> includes all possible values) # returns: @JobBuildRequirements # description: creates and returns an array with the sorted 'job build requirements' ######################################################################################## sub getJobBuildReqs { my $self = shift; my $Dir = shift; my $BuildReqPlatform = shift || "all"; my @JobBuildRequirements = (); my $ModuleData_ref = $$self{"ModuleData"}; # check whether that the tag exists if ($self->existsTag("build")) { # change all possible upper cases to lower cases $BuildReqPlatform =~ s/($BuildReqPlatform)/\L$BuildReqPlatform/ if ($BuildReqPlatform ne "all"); my $BuildReqPlatformContent = undef; my %tempJobBuildRequirements = (); # first we need a reference of the higher level tag my ($IndexValue, $Build_ref) = $self->getIterationData("build"); for (my $i = 0; $i < $IndexValue; $i++) { # get the ref to the content of the array of the tag my $Task_ref = getContent($Build_ref, $i); # get the attribute 'task dir' my $existingDir = getAttribute($Task_ref, "dir"); # get the 'job type' ref which is inside the tag my $JobType_ref = getContent($Task_ref, 0); # each 'job type' can have several 'depends' and 'build requirements' # here we get the number of the included elements my $IndexEnd = getContentCount($JobType_ref); for (my $j = 0; $j < $IndexEnd; $j++) { # create a ref of the existing content my $Content_ref = getContent($JobType_ref, $j); # the content_ref can be 'build requirement' or 'depend' # but we need only the 'build requirement' informations next if (getTagName($Content_ref) ne "build-requirement"); my $BuildReqName = getAttribute($Content_ref, "name"); $BuildReqPlatformContent = getAttribute($Content_ref, "platform"); $BuildReqPlatformContent = "all" if (!($BuildReqPlatformContent)); if ($BuildReqPlatform ne "all") { # compare the parameters: 'dir' and 'platform' # other values('wnt', 'unx' and 'mac') for 'platform' # including the value 'all' in the existing 'platform' list # get each 'build requirement name' only once (unique) if ( ($Dir eq $existingDir) && (($BuildReqPlatformContent =~ /\b($BuildReqPlatform)\b/) || ($BuildReqPlatformContent =~ /\ball\b/)) ) { $tempJobBuildRequirements{$BuildReqName} = ""; print"JobBuildRequirements (if) = <$BuildReqName>\n" if ($Debug); } } # if the 'build requirement platform' was not allocated, it is "all" (default) # now we only need to compare the directories elsif ($Dir eq $existingDir) { $tempJobBuildRequirements{$BuildReqName} = ""; print"JobBuildRequirements (elsif) = <$BuildReqName>\n" if ($Debug); } } } # fill the unique sorted 'build requirement names' in the array @JobBuildRequirements = sort keys %tempJobBuildRequirements; } print"JobBuildRequirements = <@JobBuildRequirements>\n" if ($Debug); return @JobBuildRequirements; } ######################################################################################## # sub: getJobBuildReqPlatforms # gets: $Dir, $BuildReqName # optional: - # returns: @JobBuildReqPlatforms # description: creates and returns an array with # the sorted 'job build requirement platforms' ######################################################################################## sub getJobBuildReqPlatforms { my $self = shift; my $Dir = shift; my $JobBuildReqName = shift; my @JobBuildReqPlatforms = (); my $ModuleData_ref = $$self{"ModuleData"}; # check whether that the tag exists if ($self->existsTag("build")) { # change all possible upper cases to lower cases $JobBuildReqName =~ s/($JobBuildReqName)/\L$JobBuildReqName/; my $BuildReqPlatformContent = undef; my @tempPlatforms = (); my %tempJobBuildReqPlatforms = (); # first we need a reference of the higher level tag my ($IndexValue, $Build_ref) = $self->getIterationData("build"); for (my $i = 0; $i < $IndexValue; $i++) { # get the ref to the content of the array of the tag my $Task_ref = getContent($Build_ref, $i); # get the attribute 'task dir' my $existingDir = getAttribute($Task_ref, "dir"); # get the 'job type' ref which is inside the tag my $JobType_ref = getContent($Task_ref, 0); # each 'job type' can have several 'depends' and 'build requirements' # here we get the number of the included elements my $IndexEnd = getContentCount($JobType_ref); for (my $j = 0; $j < $IndexEnd; $j++) { # create a ref of the existing content my $Content_ref = getContent($JobType_ref, $j); # the content_ref can be 'build requirement' or 'depend' # but we need only the 'build requirement' informations next if (getTagName($Content_ref) ne "build-requirement"); my $existingJobBuildReqName = getAttribute($Content_ref, "name"); $BuildReqPlatformContent = getAttribute($Content_ref, "platform"); $BuildReqPlatformContent = "all" if (!($BuildReqPlatformContent)); if ( ($Dir eq $existingDir) && ($JobBuildReqName eq $existingJobBuildReqName) ) { # here are the platforms of the current 'build requirement' @tempPlatforms = split /\s+/, $BuildReqPlatformContent; foreach my $BuildReqPlatform (@tempPlatforms) { $tempJobBuildReqPlatforms{$BuildReqPlatform} = ""; } ######### } } } # fill the unique sorted 'build requirement platforms' in the array @JobBuildReqPlatforms = sort keys %tempJobBuildReqPlatforms; } print"JobBuildReqPlatforms = <@JobBuildReqPlatforms>\n" if ($Debug); return @JobBuildReqPlatforms; } ######################################################################################## # sub: getJobPlatforms # gets: $Dir # optional: - # returns: @JobPlatforms # description: creates and returns an array with the sorted depending 'job platforms' ######################################################################################## sub getJobPlatforms { my $self = shift; my $Dir = shift; my @JobPlatforms = (); my $ModuleData_ref = $$self{"ModuleData"}; # check whether that the tag exists if ($self->existsTag("build")) { my $PlatformContent = undef; my %tempJobPlatforms = (); # control variable: if a value 'all' exists in the platform content # it doesn't matter which platforms are also existing, # because 'all' includes all possible values! my $allExists = 0; # first we need a reference of the higher level tag my ($IndexValue, $Build_ref) = $self->getIterationData("build"); for (my $i = 0; $i < $IndexValue; $i++) { my $Task_ref = getContent($Build_ref, $i); # get the attributes of the tag my $existingTaskDir = getAttribute($Task_ref, "dir"); $PlatformContent = getAttribute($Task_ref, "platform"); # if it is not set in the data structure, # it has automatically the default value 'all' $PlatformContent = "all" if (!($PlatformContent)); if ($Dir eq $existingTaskDir) { # if a platform value 'all' exists, we remember it # and don't look further after other platforms if ($PlatformContent =~ /\ball\b/) { $allExists = 1; @JobPlatforms = "all"; last; } my @tempPlatforms = (); push(@tempPlatforms, split(/\s+/, $PlatformContent)); foreach my $Platform (@tempPlatforms) { $tempJobPlatforms{$Platform} = ""; } } } # fill the unique sorted 'job platforms' in the array, # but only if the content "all" is not present in the platform content @JobPlatforms = sort keys %tempJobPlatforms if ($allExists == 0); } print"JobPlatforms = <@JobPlatforms>\n" if ($Debug); return @JobPlatforms; } ######################################################################################## # end of 'get' methods # ######################################################################################## 1 ;