1#*************************************************************************
2#
3# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4#
5# Copyright 2000, 2010 Oracle and/or its affiliates.
6#
7# OpenOffice.org - a multi-platform office productivity suite
8#
9# This file is part of OpenOffice.org.
10#
11# OpenOffice.org is free software: you can redistribute it and/or modify
12# it under the terms of the GNU Lesser General Public License version 3
13# only, as published by the Free Software Foundation.
14#
15# OpenOffice.org is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18# GNU Lesser General Public License version 3 for more details
19# (a copy is included in the LICENSE file that accompanied this code).
20#
21# You should have received a copy of the GNU Lesser General Public License
22# version 3 along with OpenOffice.org.  If not, see
23# <http://www.openoffice.org/license.html>
24# for a copy of the LGPLv3 License.
25#
26#*************************************************************************
27
28
29package par2script::work;
30
31use par2script::existence;
32use par2script::globals;
33use par2script::remover;
34
35############################################
36# par2script working module
37############################################
38
39sub analyze_comma_separated_list
40{
41	my ($list, $listref) = @_;	# second parameter is optional
42
43	my @list = ();
44	my $locallistref;
45
46	if (!( $listref )) { $locallistref = \@list; }
47	else { $locallistref = $listref; }
48
49	par2script::remover::remove_leading_and_ending_comma(\$list);
50	par2script::remover::remove_leading_and_ending_whitespaces(\$list);
51
52	while ( $list =~ /^\s*(.*?)\s*\,\s*(.*)\s*$/ )
53	{
54		my $oneentry = $1;
55		$list = $2;
56		par2script::remover::remove_leading_and_ending_whitespaces(\$oneentry);
57		push(@{$locallistref}, $oneentry);
58	}
59
60	# the last entry
61
62	par2script::remover::remove_leading_and_ending_whitespaces(\$list);
63	push(@{$locallistref}, $list);
64
65	return $locallistref;
66}
67
68############################################
69# setting list of include pathes
70############################################
71
72sub setincludes
73{
74	my ($list) = @_;
75
76	# input is the comma separated list of include pathes
77
78	my $includes = analyze_comma_separated_list($list);
79
80	return $includes;
81}
82
83############################################
84# setting list of all par files
85############################################
86
87sub setparfiles
88{
89	my ($filename) = @_;
90
91	# input is the name of the list file
92	$filename =~ s/\@//;	# removing the leading \@
93
94	my $filecontent = par2script::files::read_file($filename);
95
96	my @parfiles = ();
97	my $parfilesref = \@parfiles;
98
99	foreach ( @{$filecontent} ) { $parfilesref = analyze_comma_separated_list($_, $parfilesref); }
100
101	return $parfilesref;
102}
103
104############################################
105# finding the correct include path
106# for the par files
107############################################
108
109sub make_complete_pathes_for_parfiles
110{
111	my ($parfiles, $includes) = @_;
112
113	my $oneparfile;
114
115	foreach $oneparfile ( @{$parfiles} )
116	{
117		my $foundparfile = 0;
118		my $includepath;
119
120		foreach $includepath ( @{$includes} )
121		{
122			my $parfile = "$includepath/$oneparfile";
123
124			if ( -f $parfile )
125			{
126				$foundparfile = 1;
127				$oneparfile = $parfile;
128				last;
129			}
130		}
131
132		if ( ! $foundparfile )
133		{
134			die "ERROR: Could not find parfile ${$parfiles}[$i] in includes pathes: $par2script::globals::includepathlist !\n";
135		}
136	}
137}
138
139######################################################
140# collecting one special item in the par files and
141# including it into the "definitions" hash
142######################################################
143
144sub collect_definitions
145{
146	my ($parfilecontent) = @_;
147
148	my $multidefinitionerror = 0;
149	my @multidefinitiongids = ();
150
151
152	foreach $oneitem ( @par2script::globals::allitems )
153	{
154		my $docollect = 0;
155		my $gid = "";
156		my %allitemhash = ();
157
158		for ( my $i = 0; $i <= $#{$parfilecontent}; $i++ )
159		{
160			my $line = ${$parfilecontent}[$i];
161
162			if ( $line =~ /^\s*$oneitem\s+(\w+)\s*$/ )
163			{
164				$gid = $1;
165				$docollect = 1;
166			}
167			else
168			{
169				$docollect = 0;
170			}
171
172			if ( $docollect )
173			{
174				my $currentline = $i;
175				my %oneitemhash;
176
177				while (! ( ${$parfilecontent}[$currentline] =~ /^\s*End\s*$/i ) )
178				{
179					if ( ${$parfilecontent}[$currentline] =~ /^\s*(.+?)\s*\=\s*(.+?)\s*\;\s*$/ )	# only oneliner!
180					{
181						$itemkey = $1;
182						$itemvalue = $2;
183
184						if ( $oneitem eq "Directory" ) { if ( $itemkey =~ "DosName" ) { $itemkey =~ s/DosName/HostName/; } }
185						if (( $oneitem eq "Directory" ) || ( $oneitem eq "File" ) || ( $oneitem eq "Unixlink" )) { if ( $itemvalue eq "PD_PROGDIR" ) { $itemvalue = "PREDEFINED_PROGDIR"; }}
186						if (( $itemkey eq "Styles" ) && ( $itemvalue =~ /^\s*(\w+)(\s*\;\s*)$/ )) { $itemvalue = "($1)$2"; }
187
188						$oneitemhash{$itemkey} = $itemvalue;
189					}
190
191					$currentline++;
192				}
193
194				# no hyphen allowed in gids -> cannot happen here because (\w+) is required for gids
195				if ( $gid =~ /-/ ) { par2script::exiter::exit_program("ERROR: No hyphen allowed in global id: $gid", "test_of_hyphen"); }
196
197				# test of uniqueness
198				if ( exists($allitemhash{$gid}) )
199				{
200					$multidefinitionerror = 1;
201					push(@multidefinitiongids, $gid);
202				}
203
204				$allitemhash{$gid} = \%oneitemhash;
205			}
206		}
207
208		$par2script::globals::definitions{$oneitem} = \%allitemhash;
209	}
210
211	if ( $multidefinitionerror ) {	par2script::exiter::multidefinitionerror(\@multidefinitiongids); }
212
213	# foreach $key (keys %par2script::globals::definitions)
214	# {
215	#	print "Key: $key \n";
216	#
217	#	foreach $key (keys %{$par2script::globals::definitions{$key}})
218	#	{
219	#		print "\t$key \n";
220	#	}
221	# }
222}
223
224######################################################
225# Filling content into the script
226######################################################
227
228sub put_oneitem_into_script
229{
230	my ( $script, $item, $itemhash, $itemkey ) = @_;
231
232	push(@{$script}, "$item $itemkey\n" );
233	my $content = "";
234	foreach $content (sort keys %{$itemhash->{$itemkey}}) { push(@{$script}, "\t$content = $itemhash->{$itemkey}->{$content};\n" ); }
235	push(@{$script}, "End\n" );
236	push(@{$script}, "\n" );
237}
238
239######################################################
240# Creating the script
241######################################################
242
243sub create_script
244{
245	my @script = ();
246	my $oneitem;
247
248	foreach $oneitem ( @par2script::globals::allitems )
249	{
250		if ( exists($par2script::globals::definitions{$oneitem}) )
251		{
252			if ( $oneitem eq "Shortcut" ) { next; } # "Shortcuts" after "Files"
253
254			if (( $oneitem eq "Module" ) || ( $oneitem eq "Directory" )) { write_sorted_items(\@script, $oneitem); }
255			else { write_unsorted_items(\@script, $oneitem); }
256		}
257	}
258
259	return \@script;
260}
261
262######################################################
263# Adding script content for the unsorted items
264######################################################
265
266sub write_unsorted_items
267{
268	my ( $script, $oneitem ) = @_;
269
270	my $itemhash = $par2script::globals::definitions{$oneitem};
271
272	my $itemkey = "";
273	foreach $itemkey (sort keys %{$itemhash})
274	{
275		put_oneitem_into_script($script, $oneitem, $itemhash, $itemkey);
276
277		# special handling for Shortcuts after Files
278		if (( $oneitem eq "File" ) && ( exists($par2script::globals::definitions{"Shortcut"}) ))
279		{
280			my $shortcutkey;
281			foreach $shortcutkey ( keys %{$par2script::globals::definitions{"Shortcut"}} )
282			{
283				if ( $par2script::globals::definitions{"Shortcut"}->{$shortcutkey}->{'FileID'} eq $itemkey )
284				{
285					put_oneitem_into_script($script, "Shortcut", $par2script::globals::definitions{"Shortcut"}, $shortcutkey);
286
287					# and Shortcut to Shortcut also
288					my $internshortcutkey;
289					foreach $internshortcutkey ( keys %{$par2script::globals::definitions{"Shortcut"}} )
290					{
291						if ( $par2script::globals::definitions{"Shortcut"}->{$internshortcutkey}->{'ShortcutID'} eq $shortcutkey )
292						{
293							put_oneitem_into_script($script, "Shortcut", $par2script::globals::definitions{"Shortcut"}, $internshortcutkey);
294						}
295					}
296				}
297			}
298		}
299	}
300}
301
302######################################################
303# Collecting all children of a specified parent
304######################################################
305
306sub collect_children
307{
308	my ( $itemhash, $parent, $order ) = @_;
309
310	my $item;
311	foreach $item ( keys %{$itemhash} )
312	{
313		if ( $itemhash->{$item}->{'ParentID'} eq $parent )
314		{
315			push(@{$order}, $item);
316			my $newparent = $item;
317			collect_children($itemhash, $newparent, $order);
318		}
319	}
320}
321
322######################################################
323# Adding script content for the sorted items
324######################################################
325
326sub write_sorted_items
327{
328	my ( $script, $oneitem ) = @_;
329
330	my $itemhash = $par2script::globals::definitions{$oneitem};
331
332	my @itemorder = ();
333	my @startparents = ();
334
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"; }
338
339	# supporting more than one toplevel item
340	my $parent;
341	foreach $parent ( @startparents ) { collect_children($itemhash, $parent, \@itemorder); }
342
343	my $itemkey;
344	foreach $itemkey ( @itemorder ) { put_oneitem_into_script($script, $oneitem, $itemhash, $itemkey); }
345}
346
347#######################################################################
348# Collecting all assigned gids of the type "item" from the modules
349# in the par files. Using a hash!
350#######################################################################
351
352sub collect_assigned_gids
353{
354	my $allmodules = $par2script::globals::definitions{'Module'};
355
356	my $item;
357	foreach $item ( @par2script::globals::items_assigned_at_modules )
358	{
359		if ( ! exists($par2script::globals::searchkeys{$item}) ) { par2script::exiter::exit_program("ERROR: Unknown type \"$item\" at modules.", "collect_assigned_gids"); }
360
361		my $searchkey = $par2script::globals::searchkeys{$item};
362
363		my %assignitems = ();
364		my $modulegid = "";
365
366		foreach $modulegid (keys %{$allmodules} )
367		{
368			# print "Module $modulegid\n";
369			# my $content = "";
370			# foreach $content (sort keys %{$allmodules->{$modulegid}}) { print "\t$content = $allmodules->{$modulegid}->{$content};\n"; }
371			# print "End\n";
372			# print "\n";
373
374			if ( exists($allmodules->{$modulegid}->{$searchkey}) )
375			{
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, ",");
380
381				my $gid;
382				foreach $gid ( @{$allassigneditems} )
383				{
384					if ( exists($assignitems{$gid}) ) { $assignitems{$gid} = $assignitems{$gid} + 1; }
385					else { $assignitems{$gid} = 1; }
386				}
387			}
388		}
389
390		$par2script::globals::assignedgids{$item} = \%assignitems;
391	}
392}
393
394##################################################
395# Collecting the content of all par files.
396# Then the files do not need to be opened twice.
397##################################################
398
399sub read_all_parfiles
400{
401	my ($parfiles) = @_;
402
403	my @parfilecontent = ();
404	my $parfilename;
405
406	foreach $parfilename ( @{$parfiles} )
407	{
408		my $parfile = par2script::files::read_file($parfilename);
409		foreach ( @{$parfile} ) { push(@parfilecontent, $_); }
410		push(@parfilecontent, "\n");
411	}
412
413	return \@parfilecontent;
414}
415
4161;
417