2 # This file is part of the LibreOffice project.
4 # This Source Code Form is subject to the terms of the Mozilla Public
5 # License, v. 2.0. If a copy of the MPL was not distributed with this
6 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 # This file incorporates work covered by the following license notice:
10 # Licensed to the Apache Software Foundation (ASF) under one or more
11 # contributor license agreements. See the NOTICE file distributed
12 # with this work for additional information regarding copyright
13 # ownership. The ASF licenses this file to you under the Apache
14 # License, Version 2.0 (the "License"); you may not use this file
15 # except in compliance with the License. You may obtain a copy of
16 # the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 package par2script
::work
;
22 use par2script
::globals
;
23 use par2script
::remover
;
25 ############################################
26 # par2script working module
27 ############################################
29 sub analyze_comma_separated_list
31 my ($list, $listref) = @_; # second parameter is optional
36 if (!( $listref )) { $locallistref = \
@list; }
37 else { $locallistref = $listref; }
39 par2script
::remover
::remove_leading_and_ending_comma
(\
$list);
40 par2script
::remover
::remove_leading_and_ending_whitespaces
(\
$list);
42 while ( $list =~ /^\s*(.*?)\s*\,\s*(.*)\s*$/ )
46 par2script
::remover
::remove_leading_and_ending_whitespaces
(\
$oneentry);
47 push(@
{$locallistref}, $oneentry);
52 par2script
::remover
::remove_leading_and_ending_whitespaces
(\
$list);
53 push(@
{$locallistref}, $list);
58 ############################################
59 # setting list of include paths
60 ############################################
66 # input is the comma separated list of include paths
68 my $includes = analyze_comma_separated_list
($list);
73 ############################################
74 # setting list of all par files
75 ############################################
81 # input is the name of the list file
82 $filename =~ s/\@//; # removing the leading \@
84 my $filecontent = par2script
::files
::read_file
($filename);
87 my $parfilesref = \
@parfiles;
89 foreach ( @
{$filecontent} ) { $parfilesref = analyze_comma_separated_list
($_, $parfilesref); }
94 ############################################
95 # finding the correct include path
97 ############################################
99 sub make_complete_paths_for_parfiles
101 my ($parfiles, $includes) = @_;
105 foreach $oneparfile ( @
{$parfiles} )
107 my $foundparfile = 0;
110 foreach $includepath ( @
{$includes} )
112 my $parfile = "$includepath/$oneparfile";
117 $oneparfile = $parfile;
122 if ( ! $foundparfile )
124 die "ERROR: Could not find parfile ${$parfiles}[$i] in includes paths: $par2script::globals::includepathlist !\n";
129 ######################################################
130 # collecting one special item in the par files and
131 # including it into the "definitions" hash
132 ######################################################
134 sub collect_definitions
136 my ($parfilecontent) = @_;
138 my $multidefinitionerror = 0;
139 my @multidefinitiongids = ();
143 # create empty item hashes
144 foreach $oneitem ( @par2script::globals
::allitems
) {
146 $par2script::globals
::definitions
{$oneitem} = \
%items;
149 for ( my $i = 0; $i <= $#{$parfilecontent}; $i++ )
151 my $line = ${$parfilecontent}[$i];
154 $line =~ /^\s*$/ && next; # skip blank lines
156 # lines should be well formed:
157 if ($line =~ m/^\s*(\w+)\s+(\w+)\s*$/)
164 $invalid =~ s/[\s\w]*//g;
165 par2script
::exiter
::exit_program
("ERROR: malformed par file, invalid character '$invalid', expecting <token> <gid> but saw '$line'", "test_par_syntax");
167 # print STDERR "line '$line' -> '$oneitem' '$gid'\n";
169 # hunt badness variously
170 if ( ! defined $par2script::globals
::definitions
{$oneitem} )
172 par2script
::exiter
::exit_program
("ERROR: invalid scp2 fragment item type '$oneitem' in line: '$line'", "test_par_syntax");
175 # no hyphen allowed in gids -> cannot happen here because (\w+) is required for gids
176 if ( $gid =~ /-/ ) { par2script
::exiter
::exit_program
("ERROR: No hyphen allowed in global id: $gid", "test_of_hyphen"); }
180 while (! ( ${$parfilecontent}[$i] =~ /^\s*End\s*$/i ) )
182 if ( ${$parfilecontent}[$i] =~ /^\s*(.+?)\s*\=\s*(.+?)\s*\;\s*$/ ) # only oneliner!
187 if ( $oneitem eq "Directory" ) { if ( $itemkey =~ "DosName" ) { $itemkey =~ s/DosName/HostName/; } }
188 if (( $oneitem eq "Directory" ) || ( $oneitem eq "File" ) || ( $oneitem eq "Unixlink" )) { if ( $itemvalue eq "PD_PROGDIR" ) { $itemvalue = "PREDEFINED_PROGDIR"; }}
189 if (( $itemkey eq "Styles" ) && ( $itemvalue =~ /^\s*(\w+)(\s*\;\s*)$/ )) { $itemvalue = "($1)$2"; }
190 elsif ( $itemkey eq "Files" ) # filter out empty file records, as they mess up assignment to modules
192 $itemvalue =~ /^\(([^)]*)\)$/;
193 $itemvalue = '(' . join( ',', grep( !/^$/, split( ',', $1 ) ) ) . ')';
196 $oneitemhash{$itemkey} = $itemvalue;
202 if ( defined ($par2script::globals
::definitions
{$oneitem}->{$gid}) )
204 $multidefinitionerror = 1;
205 push(@multidefinitiongids, $gid);
208 $par2script::globals
::definitions
{$oneitem}->{$gid} = \
%oneitemhash;
211 if ( $multidefinitionerror ) { par2script
::exiter
::multidefinitionerror
(\
@multidefinitiongids); }
213 # foreach $key (keys %par2script::globals::definitions)
215 # print "Key: $key \n";
217 # foreach $key (keys %{$par2script::globals::definitions{$key}})
224 ######################################################
225 # Filling content into the script
226 ######################################################
228 sub put_oneitem_into_script
230 my ( $script, $item, $itemhash, $itemkey ) = @_;
232 push(@
{$script}, "$item $itemkey\n" );
234 foreach $content (sort keys %{$itemhash->{$itemkey}}) { push(@
{$script}, "\t$content = $itemhash->{$itemkey}->{$content};\n" ); }
235 push(@
{$script}, "End\n" );
236 push(@
{$script}, "\n" );
239 ######################################################
240 # Creating the script
241 ######################################################
248 foreach $oneitem ( @par2script::globals
::allitems
)
250 if ( exists($par2script::globals
::definitions
{$oneitem}) )
252 if ( $oneitem eq "Shortcut" ) { next; } # "Shortcuts" after "Files"
254 if (( $oneitem eq "Module" ) || ( $oneitem eq "Directory" )) { write_sorted_items
(\
@script, $oneitem); }
255 else { write_unsorted_items
(\
@script, $oneitem); }
262 ######################################################
263 # Adding script content for the unsorted items
264 ######################################################
266 sub write_unsorted_items
268 my ( $script, $oneitem ) = @_;
270 my $itemhash = $par2script::globals
::definitions
{$oneitem};
273 foreach $itemkey (sort keys %{$itemhash})
275 put_oneitem_into_script
($script, $oneitem, $itemhash, $itemkey);
277 # special handling for Shortcuts after Files
278 if (( $oneitem eq "File" ) && ( exists($par2script::globals
::definitions
{"Shortcut"}) ))
281 foreach $shortcutkey ( keys %{$par2script::globals
::definitions
{"Shortcut"}} )
283 if ( $par2script::globals
::definitions
{"Shortcut"}->{$shortcutkey}->{'FileID'} eq $itemkey )
285 put_oneitem_into_script
($script, "Shortcut", $par2script::globals
::definitions
{"Shortcut"}, $shortcutkey);
287 # and Shortcut to Shortcut also
288 my $internshortcutkey;
289 foreach $internshortcutkey ( keys %{$par2script::globals
::definitions
{"Shortcut"}} )
291 if ( $par2script::globals
::definitions
{"Shortcut"}->{$internshortcutkey}->{'ShortcutID'} eq $shortcutkey )
293 put_oneitem_into_script
($script, "Shortcut", $par2script::globals
::definitions
{"Shortcut"}, $internshortcutkey);
302 ######################################################
303 # Collecting all children of a specified parent
304 ######################################################
308 my ( $itemhash, $parent, $order ) = @_;
311 foreach $item ( sort keys %{$itemhash} )
313 if ( $itemhash->{$item}->{'ParentID'} eq $parent )
315 push(@
{$order}, $item);
316 my $newparent = $item;
317 collect_children
($itemhash, $newparent, $order);
322 ######################################################
323 # Adding script content for the sorted items
324 ######################################################
326 sub write_sorted_items
328 my ( $script, $oneitem ) = @_;
330 my $itemhash = $par2script::globals
::definitions
{$oneitem};
333 my @startparents = ();
335 if ( $oneitem eq "Module" ) { push(@startparents, ""); }
336 elsif ( $oneitem eq "Directory" ) { push(@startparents, "PREDEFINED_PROGDIR"); }
337 else { die "ERROR: No root parent defined for item type $oneitem !\n"; }
339 # supporting more than one toplevel item
341 foreach $parent ( @startparents ) { collect_children
($itemhash, $parent, \
@itemorder); }
344 foreach $itemkey ( @itemorder ) { put_oneitem_into_script
($script, $oneitem, $itemhash, $itemkey); }
347 #######################################################################
348 # Collecting all assigned gids of the type "item" from the modules
349 # in the par files. Using a hash!
350 #######################################################################
352 sub collect_assigned_gids
354 my $allmodules = $par2script::globals
::definitions
{'Module'};
357 foreach $item ( @par2script::globals
::items_assigned_at_modules
)
359 if ( ! exists($par2script::globals
::searchkeys
{$item}) ) { par2script
::exiter
::exit_program
("ERROR: Unknown type \"$item\" at modules.", "collect_assigned_gids"); }
361 my $searchkey = $par2script::globals
::searchkeys
{$item};
363 my %assignitems = ();
366 foreach $modulegid (keys %{$allmodules} )
368 # print "Module $modulegid\n";
370 # foreach $content (sort keys %{$allmodules->{$modulegid}}) { print "\t$content = $allmodules->{$modulegid}->{$content};\n"; }
374 if ( exists($allmodules->{$modulegid}->{$searchkey}) )
376 my $list = $allmodules->{$modulegid}->{$searchkey};
377 if ( $list =~ /^\s*\((.*?)\)\s*(.*?)\s*$/ ) { $list = $1; }
378 else { par2script
::exiter
::exit_program
("ERROR: Invalid module list: $list", "collect_assigned_gids"); }
379 my $allassigneditems = par2script
::converter
::convert_stringlist_into_array_2
($list, ",");
382 foreach $gid ( @
{$allassigneditems} )
384 if ( exists($assignitems{$gid}) ) { $assignitems{$gid} = $assignitems{$gid} + 1; }
385 else { $assignitems{$gid} = 1; }
390 $par2script::globals
::assignedgids
{$item} = \
%assignitems;
394 ##################################################
395 # Collecting the content of all par files.
396 # Then the files do not need to be opened twice.
397 ##################################################
399 sub read_all_parfiles
403 my @parfilecontent = ();
406 foreach $parfilename ( @
{$parfiles} )
408 my $parfile = par2script
::files
::read_file
($parfilename);
409 foreach ( @
{$parfile} ) { push(@parfilecontent, $_); }
410 push(@parfilecontent, "\n");
413 return \
@parfilecontent;