diff options
Diffstat (limited to '')
-rw-r--r-- | solenv/bin/modules/par2script/check.pm | 337 | ||||
-rw-r--r-- | solenv/bin/modules/par2script/converter.pm | 116 | ||||
-rw-r--r-- | solenv/bin/modules/par2script/exiter.pm | 112 | ||||
-rw-r--r-- | solenv/bin/modules/par2script/files.pm | 64 | ||||
-rw-r--r-- | solenv/bin/modules/par2script/globals.pm | 67 | ||||
-rw-r--r-- | solenv/bin/modules/par2script/module.pm | 255 | ||||
-rw-r--r-- | solenv/bin/modules/par2script/parameter.pm | 146 | ||||
-rw-r--r-- | solenv/bin/modules/par2script/remover.pm | 66 | ||||
-rw-r--r-- | solenv/bin/modules/par2script/systemactions.pm | 170 | ||||
-rw-r--r-- | solenv/bin/modules/par2script/undefine.pm | 135 | ||||
-rw-r--r-- | solenv/bin/modules/par2script/work.pm | 414 |
11 files changed, 1882 insertions, 0 deletions
diff --git a/solenv/bin/modules/par2script/check.pm b/solenv/bin/modules/par2script/check.pm new file mode 100644 index 000000000..727cd7c83 --- /dev/null +++ b/solenv/bin/modules/par2script/check.pm @@ -0,0 +1,337 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +package par2script::check; + +use par2script::globals; + +################################ +# Checks of the setup script +################################ + +######################################################## +# Checking if all defined directories are needed +######################################################## + +sub check_needed_directories +{ + my $allfiles = $par2script::globals::definitions{'File'}; + my $alldirs = $par2script::globals::definitions{'Directory'}; + + # checking if all defined directories are needed + + my $dir; + foreach $dir ( keys %{$alldirs} ) + { + # I. directory has create flag + if (( exists($alldirs->{$dir}->{'Styles'}) ) && ( $alldirs->{$dir}->{'Styles'} =~ /\bCREATE\b/ )) { next; } + + # II. there is at least one file in the directory + my $fileinside = 0; + my $file; + foreach $file ( keys %{$allfiles} ) + { + if (( $allfiles->{$file}->{'Dir'} eq $dir ) || ( $allfiles->{$file}->{'NetDir'} eq $dir )) + { + $fileinside = 1; + last; + } + } + if ( $fileinside ) { next; } + + # III. the directory is parent for another directory + my $isparent = 0; + my $onedir; + foreach $onedir ( keys %{$alldirs} ) + { + if ( $alldirs->{$onedir}->{'ParentID'} eq $dir ) + { + $isparent = 1; + last; + } + } + if ( $isparent ) { next; } + + # no condition is true -> directory definition is superfluous + my $infoline = "\tINFO: Directory definition $dir is superfluous\n"; + # print $infoline; + push(@par2script::globals::logfileinfo, $infoline); + } +} + +################################################## +# Checking if the directories in the item +# definitions are defined. +################################################## + +sub check_directories_in_item_definitions +{ + my $item; + foreach $item ( @par2script::globals::items_with_directories ) + { + my $allitems = $par2script::globals::definitions{$item}; + + my $onegid; + foreach $onegid ( keys %{$allitems} ) + { + if ( ! exists($allitems->{$onegid}->{'Dir'}) ) { die "\nERROR: No directory defined for item: $onegid!\n\n"; } + my $dir = $allitems->{$onegid}->{'Dir'}; + if (( $dir eq "PD_PROGDIR" ) || ( $dir =~ /PREDEFINED_/ )) { next; } + + # checking if this directoryid is defined + if ( ! exists($par2script::globals::definitions{'Directory'}->{$dir}) ) + { + die "\nERROR: Directory $dir in item $onegid not defined!\n\n"; + } + } + } +} + +######################################################## +# Checking for all Items, that know their modules, +# whether these modules exist. +######################################################## + +sub check_module_existence +{ + my $item; + foreach $item ( @par2script::globals::items_with_moduleid ) + { + my $allitems = $par2script::globals::definitions{$item}; + + my $onegid; + foreach $onegid ( keys %{$allitems} ) + { + if ( ! exists($allitems->{$onegid}->{'ModuleID'}) ) { die "\nERROR: No ModuleID defined for item: $onegid!\n\n"; } + my $moduleid = $allitems->{$onegid}->{'ModuleID'}; + + # checking if this directoryid is defined + if ( ! exists($par2script::globals::definitions{'Module'}->{$moduleid}) ) + { + die "\nERROR: ModuleID $moduleid in item $onegid not defined!\n\n"; + } + } + } +} + +######################################################## +# Every script has to contain exactly one root module. +# This module has no ParentID or an empty ParentID. +######################################################## + +sub check_rootmodule +{ + my $rootgid = ""; + my $foundroot = 0; + + my $allmodules = $par2script::globals::definitions{'Module'}; + + my $modulegid = ""; + foreach $modulegid (keys %{$allmodules} ) + { + if (( ! exists($allmodules->{$modulegid}->{'ParentID'}) ) || ( $allmodules->{$modulegid}->{'ParentID'} eq "" )) + { + if ( $foundroot ) + { + die "\nERROR: More than one Root module. Only one module without ParentID or with empty ParentID allowed ($rootgid and $modulegid).\n"; + } + $rootgid = $modulegid; + $foundroot = 1; + } + } + + if ( ! $foundroot ) + { + die "\nERROR: Could not find Root module. Did not find module without ParentID or with empty ParentID.\n"; + } + + print " $rootgid\n" if $par2script::globals::verbose; + +} + +######################################################## +# File, Shortcut, Directory, Unixlink must not +# contain a ModuleID +######################################################## + +sub check_moduleid_at_items +{ + my $item; + foreach $item ( @par2script::globals::items_without_moduleid ) + { + my $allitems = $par2script::globals::definitions{$item}; + + my $onegid; + foreach $onegid ( keys %{$allitems} ) + { + if ( exists($allitems->{$onegid}->{'ModuleID'}) ) + { + die "\nERROR: ModuleID assigned to $onegid! No module assignment to $item!\n\n"; + } + } + } +} + +######################################################## +# Controlling existence of multi assignments +######################################################## + +sub check_multiple_assignments +{ + my @multiassignments = (); + my $error; + + my $topitem; + foreach $topitem ( keys %par2script::globals::assignedgids ) + { + my $item; + foreach $item ( keys %{$par2script::globals::assignedgids{$topitem}} ) + { + if ( $par2script::globals::assignedgids{$topitem}->{$item} > 1 ) + { + $error = 1; + my $string = "\tGID: $item Assignments: $par2script::globals::assignedgids{$topitem}->{$item}"; + push(@multiassignments, $string); + } + } + } + + if ( $error ) { par2script::exiter::multiassignmenterror(\@multiassignments); } +} + +######################################################## +# Check, if a defined directory has a flag CREATE +######################################################## + +sub contains_create_flag +{ + my ($gid) = @_; + + my $createflag = 0; + + if (( exists($par2script::globals::definitions{'Directory'}->{$gid}->{'Styles'}) ) && + ( $par2script::globals::definitions{'Directory'}->{$gid}->{'Styles'} =~ /\bCREATE\b/ )) + { + $createflag = 1; + } + + return $createflag; +} + +######################################################## +# Controlling existence of definitions without +# any assignment +######################################################## + +sub check_missing_assignments +{ + # If defined gids for "File", "Directory" or "Unixlink" are not assigned, + # this causes an error. + # Directories only have to be assigned, if they have the flag "CREATE". + + my @missingassignments = (); + $error = 0; + + my $item; + foreach $item ( @par2script::globals::items_assigned_at_modules ) + { + my $assignedgids = $par2script::globals::assignedgids{$item}; + my $definedgids = $par2script::globals::definitions{$item}; + + my $gid; + foreach $gid ( keys %{$definedgids} ) + { + if ( $item eq "Directory" ) { if ( ! contains_create_flag($gid) ) { next; } } + + if ( ! exists( $assignedgids->{$gid} )) + { + $error = 1; + push(@missingassignments, $gid); + } + } + } + + if ( $error ) { par2script::exiter::missingassignmenterror(\@missingassignments); } +} + +############################################################# +# Controlling if for all shortcuts with file assignment +# the file is defined. And for all shortcuts with +# shortcut assignment the shortcut has to be defined. +############################################################# + +sub check_shortcut_assignments +{ + my $allshortcuts = $par2script::globals::definitions{'Shortcut'}; + my $allfiles = $par2script::globals::definitions{'File'}; + + my $shortcut; + foreach $shortcut ( keys %{$allshortcuts} ) + { + if (( exists($allshortcuts->{$shortcut}->{'FileID'}) ) && + ( ! exists($allfiles->{$allshortcuts->{$shortcut}->{'FileID'}}) )) + { + die "\nERROR: FileID $allshortcuts->{$shortcut}->{'FileID'} has no definition at shortcut $shortcut !\n"; + } + + if (( exists($allshortcuts->{$shortcut}->{'ShortcutID'}) ) && + ( ! exists($allshortcuts->{$allshortcuts->{$shortcut}->{'ShortcutID'}}) )) + { + die "\nERROR: ShortcutID $allshortcuts->{$shortcut}->{'ShortcutID'} has no definition at shortcut $shortcut !\n"; + } + + if (( ! exists($allshortcuts->{$shortcut}->{'ShortcutID'}) ) && + ( ! exists($allshortcuts->{$shortcut}->{'FileID'}) )) + { + die "\nERROR: Shortcut requires assignment to \"ShortcutID\" or \"FileID\". Missing at shortcut $shortcut !\n"; + } + } +} + +############################################################# +# Controlling if for Modules and Directories, the parents +# are defined. If not, this can lead to a problem during +# script creation, because only recursively added +# Modules or Directories are added to the script. +############################################################# + +sub check_missing_parents +{ + my @parentitems = ("Module", "Directory"); + my %rootparents = ("PREDEFINED_PROGDIR" => "1"); + + my $oneitem; + foreach $oneitem ( @parentitems ) + { + my $alldefinitions = $par2script::globals::definitions{$oneitem}; + + my $onegid; + foreach $onegid ( keys %{$alldefinitions} ) + { + # If there is a ParentID used, it must be defined + if (( exists($alldefinitions->{$onegid}->{'ParentID'}) ) && + ( ! exists($alldefinitions->{$alldefinitions->{$onegid}->{'ParentID'}}) ) && + ( ! exists($rootparents{$alldefinitions->{$onegid}->{'ParentID'}}) )) + { + die "\nERROR: Parent \"$alldefinitions->{$onegid}->{'ParentID'}\" at $oneitem \"$onegid\" is not defined!\n"; + } + } + } +} + +1; diff --git a/solenv/bin/modules/par2script/converter.pm b/solenv/bin/modules/par2script/converter.pm new file mode 100644 index 000000000..d8323f40d --- /dev/null +++ b/solenv/bin/modules/par2script/converter.pm @@ -0,0 +1,116 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + + +package par2script::converter; + +use par2script::remover; + +############################# +# Converter +############################# + +sub convert_array_to_hash +{ + my ($arrayref) = @_; + + my ($line, $key, $value); + + my %newhash = (); + + for ( my $i = 0; $i <= $#{$arrayref}; $i++ ) + { + $line = ${$arrayref}[$i]; + + if ( $line =~ /^\s*(\w+?)\s+(.*?)\s*$/ ) + { + $key = $1; + $value = $2; + $newhash{$key} = $value; + } + } + + return \%newhash; +} + +sub convert_stringlist_into_array_2 +{ + my ( $input, $separator ) = @_; + + my @newarray = (); + my $first = ""; + my $last = ""; + + $last = $input; + + while ( $last =~ /^\s*(.+?)\s*\Q$separator\E\s*(.+)\s*$/) # "$" for minimal matching + { + $first = $1; + $last = $2; + par2script::remover::remove_leading_and_ending_whitespaces(\$first); + if ( $first ) { push(@newarray, $first); } + } + + par2script::remover::remove_leading_and_ending_whitespaces(\$last); + if ( $last ) { push(@newarray, $last); } + + return \@newarray; +} + +sub convert_stringlist_into_array +{ + my ( $includestringref, $separator ) = @_; + + my @newarray = (); + my ($first, $last); + + $last = ${$includestringref}; + + while ( $last =~ /^\s*(.+?)\s*\Q$separator\E\s*(.+)\s*$/) # "$" for minimal matching + { + $first = $1; + $last = $2; + par2script::remover::remove_leading_and_ending_whitespaces(\$first); + push(@newarray, $first); + } + + par2script::remover::remove_leading_and_ending_whitespaces(\$last); + push(@newarray, $last); + + return \@newarray; +} + +############################################################################# +# The file name contains for some files "/". If this programs runs on +# a windows platform, this has to be converted to "\". +############################################################################# + +sub convert_slash_to_backslash +{ + my ($filesarrayref) = @_; + + my ($onefile, $filename); + + for ( my $i = 0; $i <= $#{$filesarrayref}; $i++ ) + { + $onefile = ${$filesarrayref}[$i]; + $onefile->{'Name'} =~ s/\//\\/g; + } +} + +1; diff --git a/solenv/bin/modules/par2script/exiter.pm b/solenv/bin/modules/par2script/exiter.pm new file mode 100644 index 000000000..f2d2ec649 --- /dev/null +++ b/solenv/bin/modules/par2script/exiter.pm @@ -0,0 +1,112 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + + +package par2script::exiter; + +use par2script::files; +use par2script::globals; + +############################################ +# Exiting the program with an error +# This function is used instead of "die" +############################################ + +sub exit_program +{ + my ($message, $function) = @_; + + my $infoline; + + $infoline = "\n***************************************************************\n"; + push(@par2script::globals::logfileinfo, $infoline); + print("$infoline"); + + $infoline = "$message\n"; + push(@par2script::globals::logfileinfo, $infoline); + print("$infoline"); + + $infoline = "in function: $function\n"; + push(@par2script::globals::logfileinfo, $infoline); + print("$infoline"); + + $infoline = "***************************************************************\n"; + push(@par2script::globals::logfileinfo, $infoline); + + if ($par2script::globals::logging) + { + par2script::files::save_file($par2script::globals::logfilename, \@par2script::globals::logfileinfo); + print("Saved logfile: $par2script::globals::logfilename\n"); + } + + print("$infoline"); + + exit(-1); +} + +##################################### +# Error, because a gid is defined +# more than once +##################################### + +sub multidefinitionerror +{ + my ( $multidefinitiongids ) = @_; + print "************************************************\n"; + print "ERROR: multiple definition of gids:\n"; + print "************************************************\n"; + + my $gid; + foreach $gid ( @{$multidefinitiongids} ) { print "\t$gid\n"; } + exit(-1); +} + +##################################### +# Error, because a gid is assigned +# more than once +##################################### + +sub multiassignmenterror +{ + my ( $multiassignmentgids ) = @_; + print "************************************************\n"; + print "WARNING: multiple assignments of gids:\n"; + print "************************************************\n"; + + my $line; + foreach $line ( @{$multiassignmentgids} ) { print "\t$line\n"; } +} + +##################################### +# Error, because a defined gid +# is not assigned +##################################### + +sub missingassignmenterror +{ + my ( $missingassignmentgids ) = @_; + print "********************************************************\n"; + print "ERROR: Missing assignments for the following GIDs:\n"; + print "********************************************************\n"; + + my $gid; + foreach $gid ( @{$missingassignmentgids} ) { print "\t$gid\n"; } + exit(-1); +} + +1; diff --git a/solenv/bin/modules/par2script/files.pm b/solenv/bin/modules/par2script/files.pm new file mode 100644 index 000000000..1e0aa6c44 --- /dev/null +++ b/solenv/bin/modules/par2script/files.pm @@ -0,0 +1,64 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + + +package par2script::files; + +use par2script::exiter; + +############################################ +# File Operations +############################################ + +sub check_file +{ + my ($arg) = @_; + + if(!( -f $arg )) + { + par2script::exiter::exit_program("ERROR: Cannot find file $arg", "check_file"); + } +} + +sub read_file +{ + my ($localfile) = @_; + + my @localfile = (); + + open( IN, "<$localfile" ) || par2script::exiter::exit_program("ERROR: Cannot open file: $localfile", "read_file"); + while ( <IN> ) { push(@localfile, $_); } + close( IN ); + + return \@localfile; +} + +########################################### +# Saving files +########################################### + +sub save_file +{ + my ($savefile, $savecontent) = @_; + open( OUT, ">$savefile" ); + print OUT @{$savecontent}; + close( OUT); + if (! -f $savefile) { pre2par::exiter::exit_program("ERROR: Cannot write file: $savefile", "save_file"); } +} + +1; diff --git a/solenv/bin/modules/par2script/globals.pm b/solenv/bin/modules/par2script/globals.pm new file mode 100644 index 000000000..02a399767 --- /dev/null +++ b/solenv/bin/modules/par2script/globals.pm @@ -0,0 +1,67 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + + +package par2script::globals; + +############################################ +# Global settings +############################################ + +BEGIN +{ + $prog="par2script"; + + $includepathlist = ""; + $scriptname = ""; + $parfilelistorig = ""; + $parfilelist = ""; + + @allitems = ("Installation", "ScpAction", "Directory", "File", + "Shortcut", "Unixlink", "Module", "Profile", "ProfileItem", + "Folder", "FolderItem", "FolderItemProperty", "RegistryItem", + "WindowsCustomAction", "MergeModule"); + + @items_assigned_at_modules = ("File", "Directory", "Unixlink"); + @items_with_directories = ("File", "Profile", "Shortcut", "Unixlink"); + @items_with_moduleid = ("Profile", "ProfileItem", "FolderItem", "RegistryItem"); + @items_without_moduleid = ("File", "FolderItemProperty", "Directory", "Shortcut", "Unixlink"); + + %searchkeys = ("File" => "Files", "Directory" => "Dirs", "Unixlink" => "Unixlinks"); + + $logging = 0; + $logfilename = "logfile.log"; # the default logfile name for global errors + @logfileinfo = (); + + $verbose = 1; + + $multidefinitionerror = 0; + $multiassignmenterror = 0; + + %definitions; + %assignedgids; + + $plat = $^O; + + $separator = "/"; + $pathseparator = "\:"; + $isunix = 1; + $iswin = 0; +} + +1; diff --git a/solenv/bin/modules/par2script/module.pm b/solenv/bin/modules/par2script/module.pm new file mode 100644 index 000000000..ef916650b --- /dev/null +++ b/solenv/bin/modules/par2script/module.pm @@ -0,0 +1,255 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +package par2script::module; + +use par2script::converter; +use par2script::exiter; + +########################################### +# Removing undefined gids +# from modules +########################################### + +sub remove_from_modules +{ + my ($gid, $item) = @_; + + my $counter = 0; + + if ( ! exists($par2script::globals::searchkeys{$item}) ) { par2script::exiter::exit_program("ERROR: Unknown type \"$item\" at modules.", "remove_from_modules"); } + my $searchkey = $par2script::globals::searchkeys{$item}; + + my $allmodules = $par2script::globals::definitions{'Module'}; + + my $onemodule; + foreach $onemodule (keys %{$allmodules}) + { + if (( exists($allmodules->{$onemodule}->{$searchkey}) ) && ( $allmodules->{$onemodule}->{$searchkey} =~ /\b$gid\b/ )) + { + my $infoline = "WARNING: Removing $gid because of missing definition\n"; + # print $infoline; + push(@par2script::globals::logfileinfo, $infoline); + + $allmodules->{$onemodule}->{$searchkey} =~ s/\b$gid\b//; + $allmodules->{$onemodule}->{$searchkey} =~ s/\,\s*\,/\,/; + $allmodules->{$onemodule}->{$searchkey} =~ s/\(\s*\,\s*/\(/; + $allmodules->{$onemodule}->{$searchkey} =~ s/\s*\,\s*\)/\)/; + + if (( $allmodules->{$onemodule}->{$searchkey} =~ /\(\s*\,\s*\)/ ) || + ( $allmodules->{$onemodule}->{$searchkey} =~ /\(\s*\)/ )) + { + delete($allmodules->{$onemodule}->{$searchkey}); + } + + $counter++; + } + } + + return $counter; +} + +########################################### +# Removing undefined gids automatically +# from modules +########################################### + +sub remove_undefined_gids_from_modules +{ + # If assigned gids for "File", "Directory" or "Unixlink" are not defined, + # they are automatically removed from the module + + foreach $item ( @par2script::globals::items_assigned_at_modules ) + { + my $assignedgids = $par2script::globals::assignedgids{$item}; + my $definedgids = $par2script::globals::definitions{$item}; + + my $gid; + foreach $gid ( keys %{$assignedgids} ) + { + if ( ! exists( $definedgids->{$gid} )) + { + # deleting entry in module definition + my $number_of_removals = remove_from_modules($gid, $item); + # decreasing counter in assignments + if ( $assignedgids->{$gid} > $number_of_removals ) { $assignedgids->{$gid} = $assignedgids->{$gid} - $number_of_removals; } + else { delete($assignedgids->{$gid}); } + } + } + } +} + +############################################ +# Getting the gid of the root module. The +# root module has no ParentID or an empty +# ParentID. +############################################ + +sub get_rootmodule_gid +{ + my $rootgid = ""; + my $foundroot = 0; + + my $allmodules = $par2script::globals::definitions{'Module'}; + + my $modulegid = ""; + foreach $modulegid (keys %{$allmodules} ) + { + # print "Module $modulegid\n"; + # my $content = ""; + # foreach $content (sort keys %{$allmodules->{$modulegid}}) { print "\t$content = $allmodules->{$modulegid}->{$content};\n"; } + # print "End\n"; + # print "\n"; + + if (( ! exists($allmodules->{$modulegid}->{'ParentID'})) || ( $allmodules->{$modulegid}->{'ParentID'} eq "" )) + { + if ( $foundroot ) { par2script::exiter::exit_program("ERROR: More than one Root module. Only one module without ParentID or with empty ParentID allowed ($rootgid and $modulegid).", "get_rootmodule_gid"); } + $rootgid = $modulegid; + $foundroot = 1; + } + } + + if ( ! $foundroot ) { par2script::exiter::exit_program("ERROR: Could not find Root module. Did not find module without ParentID or with empty ParentID.", "get_rootmodule_gid"); } + + return $rootgid; +} + +#################################### +# Adding defined items without +# assignment to the root module. +#################################### + +sub add_to_root_module +{ + # If defined gids for "File", "Directory" or "Unixlink" are not assigned, + # they are automatically assigned to the root module + + my $rootmodulegid = get_rootmodule_gid(); + + my $item; + foreach $item ( @par2script::globals::items_assigned_at_modules ) + { + my $assignedgids = $par2script::globals::assignedgids{$item}; + my $definedgids = $par2script::globals::definitions{$item}; + + my $gidstring = ""; + + # Perhaps there are already items assigned to the root + if ( ! exists($par2script::globals::searchkeys{$item}) ) { par2script::exiter::exit_program("ERROR: Unknown type \"$item\" at modules.", "remove_from_modules"); } + my $modulekey = $par2script::globals::searchkeys{$item}; + if ( exists($par2script::globals::definitions{'Module'}->{$rootmodulegid}->{$modulekey}) ) + { + $gidstring = $par2script::globals::definitions{'Module'}->{$rootmodulegid}->{$modulekey}; + $gidstring =~ s/\(//; + $gidstring =~ s/\)//; + } + + my $gid; + foreach $gid ( keys %{$definedgids} ) + { + if ( ! exists( $assignedgids->{$gid} )) + { + if ( $gidstring eq "" ) + { + $gidstring = $gid; + } + else + { + $gidstring = "$gidstring,$gid"; + } + + $assignedgids->{$gid} = 1; + } + } + + if ( $gidstring ne "" ) + { + $gidstring = "\($gidstring\)"; + $par2script::globals::definitions{'Module'}->{$rootmodulegid}->{$modulekey} = $gidstring; + } + } +} + +################################################### +# Including \n in a very long string +################################################### + +sub include_linebreaks +{ + my ($allgidstring) = @_; + + my $newline = ""; + my $newlength = 0; + + $allgidstring =~ s/\(//; + $allgidstring =~ s/\)//; + + my $allgids = par2script::converter::convert_stringlist_into_array_2($allgidstring, ","); + + if ( $#{$allgids} > -1 ) + { + my $onegid; + foreach $onegid ( @{$allgids} ) + { + $newline = "$newline$onegid,"; + $newlength = $newlength + length($onegid) + 1; # +1 for the comma + + if ( $newlength > 80 ) + { + $newline = $newline . "\n\t\t\t\t"; + $newlength = 0; + } + } + } + + $newline =~ s/,\s*$//; + $newline = "($newline)"; + + return $newline; +} + +################################################### +# Shorten the lines that belong to modules, if +# the length of the line is greater 100 +################################################### + +sub shorten_lines_at_modules +{ + my $item; + foreach $item ( @par2script::globals::items_assigned_at_modules ) + { + if ( ! exists($par2script::globals::searchkeys{$item}) ) { par2script::exiter::exit_program("ERROR: Unknown type \"$item\" at modules.", "shorten_lines_at_modules"); } + my $searchkey = $par2script::globals::searchkeys{$item}; + + my $allmodules = $par2script::globals::definitions{'Module'}; + + my $onemodule; + foreach $onemodule (keys %{$allmodules}) + { + if (( exists($allmodules->{$onemodule}->{$searchkey}) ) && + ( length($allmodules->{$onemodule}->{$searchkey}) > 100 )) + { + # including "\n\t\t\t\t" + my $newstring = include_linebreaks($allmodules->{$onemodule}->{$searchkey}); + $allmodules->{$onemodule}->{$searchkey} = $newstring; + } + } + } +} + +1; diff --git a/solenv/bin/modules/par2script/parameter.pm b/solenv/bin/modules/par2script/parameter.pm new file mode 100644 index 000000000..645b28255 --- /dev/null +++ b/solenv/bin/modules/par2script/parameter.pm @@ -0,0 +1,146 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + + +package par2script::parameter; + +use Cwd; +use par2script::files; +use par2script::globals; +use par2script::systemactions; + +############################################ +# Parameter Operations +############################################ + +############################################################################### +# Usage: +# perl par2script.pl -i ..\wntmsci8.pro\par,o:\SRX645\wntmsci8.pro\par.m24 +# @@C:\DOCUMEN~1\is\LOCALS~1\Temp\mk6pd +# -o ..\wntmsci8.pro\bin\osl\setup_osl.inf +############################################################################### + +sub usage +{ + print <<End; + +-------------------------------------------------------------- +$par2script::globals::prog +The following parameter are needed: +-i: include paths, comma separated list +-o: setup script file name +-v: writing logfile.txt (optional) +\@\@list: list of all par files + +Example: + perl par2script.pl -i ..\\wntmsci8\\par\,o\:\\SRX645\\wntmsci8\\par.m24 + \@\@C\:\\DOCUMEN\~1\\is\\LOCALS\~1\\Temp\\mk6pd + -o ..\\wntmsci8.pro\\bin\\osl\\setup_osl.inf \[-v\] + +-------------------------------------------------------------- +End + exit(-1); +} + +##################################### +# Reading parameter +##################################### + +sub getparameter +{ + while ( $#ARGV >= 0 ) + { + my $param = shift(@ARGV); + + if ($param eq "-o") { $par2script::globals::scriptname = shift(@ARGV); } + elsif ($param eq "-q") { $par2script::globals::verbose = 0; } + elsif ($param eq "-v") { $par2script::globals::logging = 1; } + elsif ($param =~ /\@\@/) { $par2script::globals::parfilelistorig = $param; } + elsif ($param eq "-i") { $par2script::globals::includepathlist = shift(@ARGV); } + elsif (($param =~ /\//) || ($param =~ /\\/)) # another include parameter! + { + $par2script::globals::includepathlist = $par2script::globals::includepathlist . "," . $param; + } + else + { + print("\n*************************************\n"); + print("Sorry, unknown parameter: $param"); + print("\n*************************************\n"); + usage(); + exit(-1); + } + } +} + +############################################ +# Controlling the fundamental parameter +# (required for every process) +############################################ + +sub control_parameter +{ + if ($par2script::globals::includepathlist eq "") + { + print "\n************************************************\n"; + print "Error: Include paths not set not set (-i)!"; + print "\n************************************************\n"; + usage(); + exit(-1); + } + + if ($par2script::globals::scriptname eq "") + { + print "\n************************************************\n"; + print "Error: Name of the setup script not set (-o)!"; + print "\n************************************************\n"; + usage(); + exit(-1); + } + + if ($par2script::globals::parfilelistorig eq "") + { + print "\n************************************************\n"; + print "Error: List of par files not set!"; + print "\n************************************************\n"; + usage(); + exit(-1); + } + + # The par file list has to exist + + $par2script::globals::parfilelist = $par2script::globals::parfilelistorig; + $par2script::globals::parfilelist =~ s/\@\@//; + par2script::files::check_file($par2script::globals::parfilelist); +} + +##################################### +# Writing parameter to shell +##################################### + +sub outputparameter +{ + my $outputline = "\n$par2script::globals::prog -i $par2script::globals::includepathlist $par2script::globals::parfilelistorig -o $par2script::globals::scriptname"; + + if ($par2script::globals::logging) { $outputline .= " -v"; } + + $outputline .= "\n"; + + print $outputline; +} + +1; diff --git a/solenv/bin/modules/par2script/remover.pm b/solenv/bin/modules/par2script/remover.pm new file mode 100644 index 000000000..4625bf0b0 --- /dev/null +++ b/solenv/bin/modules/par2script/remover.pm @@ -0,0 +1,66 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + + +package par2script::remover; + +############################################ +# Remover +############################################ + +sub remove_leading_and_ending_whitespaces +{ + my ( $stringref ) = @_; + + $$stringref =~ s/^\s*//g; + $$stringref =~ s/\s*$//g; +} + +sub remove_leading_and_ending_comma +{ + my ( $stringref ) = @_; + + $$stringref =~ s/^\s*\,//g; + $$stringref =~ s/\,\s*$//g; +} + +sub remove_leading_and_ending_quotationmarks +{ + my ( $stringref ) = @_; + + $$stringref =~ s/^\s*\"//g; + $$stringref =~ s/\"\s*$//g; +} + +sub remove_leading_and_ending_slashes +{ + my ( $stringref ) = @_; + + $$stringref =~ s/^\s*\///g; + $$stringref =~ s/\/\s*$//g; +} + +sub remove_leading_and_ending_backslashes +{ + my ( $stringref ) = @_; + + $$stringref =~ s/^\s*\\//g; + $$stringref =~ s/\\\s*$//g; +} + +1; diff --git a/solenv/bin/modules/par2script/systemactions.pm b/solenv/bin/modules/par2script/systemactions.pm new file mode 100644 index 000000000..b6e6b546b --- /dev/null +++ b/solenv/bin/modules/par2script/systemactions.pm @@ -0,0 +1,170 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + + +package par2script::systemactions; + +use File::Copy; +use par2script::exiter; +use par2script::globals; + +###################################################### +# Creating a new directory +###################################################### + +sub create_directory +{ + my ($directory) = @_; + + my $returnvalue = 1; + + if (!(-d $directory)) + { + $returnvalue = mkdir($directory, 0775); + + if ($returnvalue) + { + $infoline = "Created directory: $directory\n"; + push(@par2script::globals::logfileinfo, $infoline); + + if ($par2script::globals::isunix) + { + my $localcall = "chmod 775 $directory \>\/dev\/null 2\>\&1"; + system($localcall); + } + } + else + { + par2script::exiter::exit_program("Error: Could not create directory: $directory", "create_directory"); + } + } +} + +####################################################################### +# Creating the directories, in which files are generated or unzipped +####################################################################### + +sub create_directories +{ + my ($directory, $languagesref) =@_; + + $par2script::globals::unpackpath =~ s/\Q$par2script::globals::separator\E\s*$//; # removing ending slashes and backslashes + + my $path = $par2script::globals::unpackpath; # this path already exists + + $path = $path . $par2script::globals::separator . $par2script::globals::build . $par2script::globals::separator; + create_directory($path); + + $path = $path . $par2script::globals::minor . $par2script::globals::separator; + create_directory($path); + + if ($directory eq "unzip" ) + { + } + else + { + $path = $path . $par2script::globals::platformid . $par2script::globals::separator; + create_directory($path); + + $path = $path . $par2script::globals::product . $par2script::globals::separator; + create_directory($path); + + $path = $path . $directory . $par2script::globals::separator; + create_directory($path); + + if (!($$languagesref eq "" )) # this will be a path like "01_49", for Profiles and ConfigurationFiles, idt-Files + { + $path = $path . $$languagesref . $par2script::globals::separator; + create_directory($path); + } + } + + $path =~ s/\Q$par2script::globals::separator\E\s*$//; + + return $path; +} + +######################## +# Copying one file +######################## + +sub copy_one_file +{ + my ($source, $dest) = @_; + + my ($copyreturn, $returnvalue); + my $infoline; + + $copyreturn = copy($source, $dest); + + if ($copyreturn) + { + $infoline = "Copy: $source to $dest\n"; + $returnvalue = 1; + } + else + { + $infoline = "Error: Could not copy $source to $dest $!\n"; + $returnvalue = 0; + } + + push(@par2script::globals::logfileinfo, $infoline); + + return $returnvalue; +} + +########################################## +# Copying all files from one directory +# to another directory +########################################## + +sub copy_directory +{ + my ($sourcedir, $destdir) = @_; + + my ($onefile, $sourcefile, $destfile); + my @sourcefiles = (); + + $sourcedir =~ s/\Q$par2script::globals::separator\E\s*$//; + $destdir =~ s/\Q$par2script::globals::separator\E\s*$//; + + $infoline = "\n"; + push(@par2script::globals::logfileinfo, $infoline); + $infoline = "Copying files from directory $sourcedir to directory $destdir\n"; + push(@par2script::globals::logfileinfo, $infoline); + + opendir(DIR, $sourcedir); + @sourcefiles = readdir(DIR); + closedir(DIR); + + foreach $onefile (@sourcefiles) + { + if ((!($onefile eq ".")) && (!($onefile eq ".."))) + { + $sourcefile = $sourcedir . $par2script::globals::separator . $onefile; + $destfile = $destdir . $par2script::globals::separator . $onefile; + if ( -f $sourcefile ) # only files, no directories + { + copy_one_file($sourcefile, $destfile); + } + } + } +} + + +1; diff --git a/solenv/bin/modules/par2script/undefine.pm b/solenv/bin/modules/par2script/undefine.pm new file mode 100644 index 000000000..43cbe2619 --- /dev/null +++ b/solenv/bin/modules/par2script/undefine.pm @@ -0,0 +1,135 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + +package par2script::undefine; + +use par2script::globals; + +########################################################## +# Removing in the script all the gids, that are listed +# in undefine scp files +########################################################## + +sub undefine_gids +{ + my ($parfilecontent) = @_; + + my $item; + foreach $item ( @par2script::globals::allitems ) + { + my $unitem = "Un$item"; + + for ( my $i = 0; $i <= $#{$parfilecontent}; $i++ ) + { + if ( ${$parfilecontent}[$i] =~ /^\s*$unitem\s*(\w+?)\s*$/ ) + { + my $gid = $1; + delete($par2script::globals::definitions{$item}->{$gid}); + } + } + } +} + +########################################################## +# Collecting all subdirectories of a specified directory +########################################################## + +sub collect_children_dirs +{ + my ($gid, $collector) = @_; + + my $diritem = "Directory"; + my $parentkey = "ParentID"; + + if ( exists($par2script::globals::definitions{$diritem}) ) + { + my $onedefinition; + + foreach $onedefinition (keys %{$par2script::globals::definitions{$diritem}}) + { + if ( $par2script::globals::definitions{$diritem}->{$onedefinition}->{$parentkey} eq $gid ) + { + push(@{$collector}, $onedefinition); + collect_children_dirs($onedefinition, $collector); + } + } + } +} + +########################################################## +# Removing in the script complete profiles. +# This includes the Profile and its ProfileItems. +########################################################## + +sub remove_complete_item +{ + my ($item, $parfilecontent) = @_; + + my $removeitem = "Remove$item"; + my $dependentkey = ""; + my $collect_children = 0; + my @gidcollector = (); + my @dependentitems = (); + + if ( $item eq "Profile" ) + { + @dependentitems = ("ProfileItem"); + $dependentkey = "ProfileID"; + } + elsif ( $item eq "Directory" ) + { + @dependentitems = ("File", "Shortcut", "Unixlink"); + $dependentkey = "Dir"; + $collect_children = 1; + } + + for ( my $i = 0; $i <= $#{$parfilecontent}; $i++ ) + { + if ( ${$parfilecontent}[$i] =~ /^\s*$removeitem\s*(\w+?)\s*$/ ) + { + my $onegid = $1; + push(@gidcollector, $onegid); + if ( $collect_children ) { collect_children_dirs($onegid, \@gidcollector); } + + my $gid; + foreach $gid (@gidcollector) + { + delete($par2script::globals::definitions{$item}->{$gid}); + + # also deleting all dependent items, for example "ProfileItems" whose "ProfileID" is this "Profile" + my $depitem; + foreach $depitem ( @dependentitems ) + { + if ( exists($par2script::globals::definitions{$depitem}) ) + { + my $onedefinition; + foreach $onedefinition (keys %{$par2script::globals::definitions{$depitem}}) + { + if ( $par2script::globals::definitions{$depitem}->{$onedefinition}->{$dependentkey} eq $gid ) + { + delete($par2script::globals::definitions{$depitem}->{$onedefinition}); + } + } + } + } + } + } + } +} + +1; diff --git a/solenv/bin/modules/par2script/work.pm b/solenv/bin/modules/par2script/work.pm new file mode 100644 index 000000000..cc1f1e4d5 --- /dev/null +++ b/solenv/bin/modules/par2script/work.pm @@ -0,0 +1,414 @@ +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This file incorporates work covered by the following license notice: +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed +# with this work for additional information regarding copyright +# ownership. The ASF licenses this file to you under the Apache +# License, Version 2.0 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.apache.org/licenses/LICENSE-2.0 . +# + + +package par2script::work; + +use par2script::globals; +use par2script::remover; + +############################################ +# par2script working module +############################################ + +sub analyze_comma_separated_list +{ + my ($list, $listref) = @_; # second parameter is optional + + my @list = (); + my $locallistref; + + if (!( $listref )) { $locallistref = \@list; } + else { $locallistref = $listref; } + + par2script::remover::remove_leading_and_ending_comma(\$list); + par2script::remover::remove_leading_and_ending_whitespaces(\$list); + + while ( $list =~ /^\s*(.*?)\s*\,\s*(.*)\s*$/ ) + { + my $oneentry = $1; + $list = $2; + par2script::remover::remove_leading_and_ending_whitespaces(\$oneentry); + push(@{$locallistref}, $oneentry); + } + + # the last entry + + par2script::remover::remove_leading_and_ending_whitespaces(\$list); + push(@{$locallistref}, $list); + + return $locallistref; +} + +############################################ +# setting list of include paths +############################################ + +sub setincludes +{ + my ($list) = @_; + + # input is the comma separated list of include paths + + my $includes = analyze_comma_separated_list($list); + + return $includes; +} + +############################################ +# setting list of all par files +############################################ + +sub setparfiles +{ + my ($filename) = @_; + + # input is the name of the list file + my $filecontent = par2script::files::read_file($filename); + + my @parfiles = (); + my $parfilesref = \@parfiles; + + foreach ( @{$filecontent} ) { $parfilesref = analyze_comma_separated_list($_, $parfilesref); } + + return $parfilesref; +} + +############################################ +# finding the correct include path +# for the par files +############################################ + +sub make_complete_paths_for_parfiles +{ + my ($parfiles, $includes) = @_; + + my $oneparfile; + + foreach $oneparfile ( @{$parfiles} ) + { + my $foundparfile = 0; + my $includepath; + + foreach $includepath ( @{$includes} ) + { + my $parfile = "$includepath/$oneparfile"; + + if ( -f $parfile ) + { + $foundparfile = 1; + $oneparfile = $parfile; + last; + } + } + + if ( ! $foundparfile ) + { + die "ERROR: Could not find parfile ${$parfiles}[$i] in includes paths: $par2script::globals::includepathlist !\n"; + } + } +} + +###################################################### +# collecting one special item in the par files and +# including it into the "definitions" hash +###################################################### + +sub collect_definitions +{ + my ($parfilecontent) = @_; + + my $multidefinitionerror = 0; + my @multidefinitiongids = (); + + my %itemhash; + + # create empty item hashes + foreach $oneitem ( @par2script::globals::allitems ) { + my %items; + $par2script::globals::definitions{$oneitem} = \%items; + } + + for ( my $i = 0; $i <= $#{$parfilecontent}; $i++ ) + { + my $line = ${$parfilecontent}[$i]; + my $oneitem, $gid; + + $line =~ /^\s*$/ && next; # skip blank lines + + # lines should be well formed: + if ($line =~ m/^\s*(\w+)\s+(\w+)\s*$/) + { + $oneitem = $1; + $gid = $2; + } else { + chomp ($line); + my $invalid = $line; + $invalid =~ s/[\s\w]*//g; + par2script::exiter::exit_program("ERROR: malformed par file, invalid character '$invalid', expecting <token> <gid> but saw '$line'", "test_par_syntax"); + } +# print STDERR "line '$line' -> '$oneitem' '$gid'\n"; + + # hunt badness variously + if ( ! defined $par2script::globals::definitions{$oneitem} ) + { + par2script::exiter::exit_program("ERROR: invalid scp2 fragment item type '$oneitem' in line: '$line'", "test_par_syntax"); + } + + # no hyphen allowed in gids -> cannot happen here because (\w+) is required for gids + if ( $gid =~ /-/ ) { par2script::exiter::exit_program("ERROR: No hyphen allowed in global id: $gid", "test_of_hyphen"); } + + my %oneitemhash; + + while (! ( ${$parfilecontent}[$i] =~ /^\s*End\s*$/i ) ) + { + if ( ${$parfilecontent}[$i] =~ /^\s*(.+?)\s*\=\s*(.+?)\s*\;\s*$/ ) # only oneliner! + { + $itemkey = $1; + $itemvalue = $2; + + if ( $oneitem eq "Directory" ) { if ( $itemkey =~ "DosName" ) { $itemkey =~ s/DosName/HostName/; } } + if (( $oneitem eq "Directory" ) || ( $oneitem eq "File" ) || ( $oneitem eq "Unixlink" )) { if ( $itemvalue eq "PD_PROGDIR" ) { $itemvalue = "PREDEFINED_PROGDIR"; }} + if (( $itemkey eq "Styles" ) && ( $itemvalue =~ /^\s*(\w+)(\s*\;\s*)$/ )) { $itemvalue = "($1)$2"; } + elsif ( $itemkey eq "Files" ) # filter out empty file records, as they mess up assignment to modules + { + $itemvalue =~ /^\(([^)]*)\)$/; + $itemvalue = '(' . join( ',', grep( !/^$/, split( ',', $1 ) ) ) . ')'; + } + + $oneitemhash{$itemkey} = $itemvalue; + } + $i++; + } + + # test of uniqueness + if ( defined ($par2script::globals::definitions{$oneitem}->{$gid}) ) + { + $multidefinitionerror = 1; + push(@multidefinitiongids, $gid); + } + + $par2script::globals::definitions{$oneitem}->{$gid} = \%oneitemhash; + } + + if ( $multidefinitionerror ) { par2script::exiter::multidefinitionerror(\@multidefinitiongids); } + + # foreach $key (keys %par2script::globals::definitions) + # { + # print "Key: $key \n"; + # + # foreach $key (keys %{$par2script::globals::definitions{$key}}) + # { + # print "\t$key \n"; + # } + # } +} + +###################################################### +# Filling content into the script +###################################################### + +sub put_oneitem_into_script +{ + my ( $script, $item, $itemhash, $itemkey ) = @_; + + push(@{$script}, "$item $itemkey\n" ); + my $content = ""; + foreach $content (sort keys %{$itemhash->{$itemkey}}) { push(@{$script}, "\t$content = $itemhash->{$itemkey}->{$content};\n" ); } + push(@{$script}, "End\n" ); + push(@{$script}, "\n" ); +} + +###################################################### +# Creating the script +###################################################### + +sub create_script +{ + my @script = (); + my $oneitem; + + foreach $oneitem ( @par2script::globals::allitems ) + { + if ( exists($par2script::globals::definitions{$oneitem}) ) + { + if ( $oneitem eq "Shortcut" ) { next; } # "Shortcuts" after "Files" + + if (( $oneitem eq "Module" ) || ( $oneitem eq "Directory" )) { write_sorted_items(\@script, $oneitem); } + else { write_unsorted_items(\@script, $oneitem); } + } + } + + return \@script; +} + +###################################################### +# Adding script content for the unsorted items +###################################################### + +sub write_unsorted_items +{ + my ( $script, $oneitem ) = @_; + + my $itemhash = $par2script::globals::definitions{$oneitem}; + + my $itemkey = ""; + foreach $itemkey (sort keys %{$itemhash}) + { + put_oneitem_into_script($script, $oneitem, $itemhash, $itemkey); + + # special handling for Shortcuts after Files + if (( $oneitem eq "File" ) && ( exists($par2script::globals::definitions{"Shortcut"}) )) + { + my $shortcutkey; + foreach $shortcutkey ( keys %{$par2script::globals::definitions{"Shortcut"}} ) + { + if ( $par2script::globals::definitions{"Shortcut"}->{$shortcutkey}->{'FileID'} eq $itemkey ) + { + put_oneitem_into_script($script, "Shortcut", $par2script::globals::definitions{"Shortcut"}, $shortcutkey); + + # and Shortcut to Shortcut also + my $internshortcutkey; + foreach $internshortcutkey ( keys %{$par2script::globals::definitions{"Shortcut"}} ) + { + if ( $par2script::globals::definitions{"Shortcut"}->{$internshortcutkey}->{'ShortcutID'} eq $shortcutkey ) + { + put_oneitem_into_script($script, "Shortcut", $par2script::globals::definitions{"Shortcut"}, $internshortcutkey); + } + } + } + } + } + } +} + +###################################################### +# Collecting all children of a specified parent +###################################################### + +sub collect_children +{ + my ( $itemhash, $parent, $order ) = @_; + + my $item; + foreach $item ( sort keys %{$itemhash} ) + { + if ( $itemhash->{$item}->{'ParentID'} eq $parent ) + { + push(@{$order}, $item); + my $newparent = $item; + collect_children($itemhash, $newparent, $order); + } + } +} + +###################################################### +# Adding script content for the sorted items +###################################################### + +sub write_sorted_items +{ + my ( $script, $oneitem ) = @_; + + my $itemhash = $par2script::globals::definitions{$oneitem}; + + my @itemorder = (); + my @startparents = (); + + if ( $oneitem eq "Module" ) { push(@startparents, ""); } + elsif ( $oneitem eq "Directory" ) { push(@startparents, "PREDEFINED_PROGDIR"); } + else { die "ERROR: No root parent defined for item type $oneitem !\n"; } + + # supporting more than one toplevel item + my $parent; + foreach $parent ( @startparents ) { collect_children($itemhash, $parent, \@itemorder); } + + my $itemkey; + foreach $itemkey ( @itemorder ) { put_oneitem_into_script($script, $oneitem, $itemhash, $itemkey); } +} + +####################################################################### +# Collecting all assigned gids of the type "item" from the modules +# in the par files. Using a hash! +####################################################################### + +sub collect_assigned_gids +{ + my $allmodules = $par2script::globals::definitions{'Module'}; + + my $item; + foreach $item ( @par2script::globals::items_assigned_at_modules ) + { + if ( ! exists($par2script::globals::searchkeys{$item}) ) { par2script::exiter::exit_program("ERROR: Unknown type \"$item\" at modules.", "collect_assigned_gids"); } + + my $searchkey = $par2script::globals::searchkeys{$item}; + + my %assignitems = (); + my $modulegid = ""; + + foreach $modulegid (keys %{$allmodules} ) + { + # print "Module $modulegid\n"; + # my $content = ""; + # foreach $content (sort keys %{$allmodules->{$modulegid}}) { print "\t$content = $allmodules->{$modulegid}->{$content};\n"; } + # print "End\n"; + # print "\n"; + + if ( exists($allmodules->{$modulegid}->{$searchkey}) ) + { + my $list = $allmodules->{$modulegid}->{$searchkey}; + if ( $list =~ /^\s*\((.*?)\)\s*(.*?)\s*$/ ) { $list = $1; } + else { par2script::exiter::exit_program("ERROR: Invalid module list: $list", "collect_assigned_gids"); } + my $allassigneditems = par2script::converter::convert_stringlist_into_array_2($list, ","); + + my $gid; + foreach $gid ( @{$allassigneditems} ) + { + if ( exists($assignitems{$gid}) ) { $assignitems{$gid} = $assignitems{$gid} + 1; } + else { $assignitems{$gid} = 1; } + } + } + } + + $par2script::globals::assignedgids{$item} = \%assignitems; + } +} + +################################################## +# Collecting the content of all par files. +# Then the files do not need to be opened twice. +################################################## + +sub read_all_parfiles +{ + my ($parfiles) = @_; + + my @parfilecontent = (); + my $parfilename; + + foreach $parfilename ( @{$parfiles} ) + { + my $parfile = par2script::files::read_file($parfilename); + foreach ( @{$parfile} ) { push(@parfilecontent, $_); } + push(@parfilecontent, "\n"); + } + + return \@parfilecontent; +} + +1; |