OSDN Git Service

Version 5.91
[vbslib/main.git] / GPL_bin_fullset / NaturalDocs / Modules / NaturalDocs / Builder.pm
1 ###############################################################################
2 #
3 #   Package: NaturalDocs::Builder
4 #
5 ###############################################################################
6 #
7 #   A package that takes parsed source file and builds the output for it.
8 #
9 #   Usage and Dependencies:
10 #
11 #       - <Add()> can be called immediately.
12 #       - <OutputPackages()> and <OutputPackageOf()> can be called once all sub-packages have been registered via <Add()>.
13 #         Since this is normally done in their INIT functions, they should be available to all normal functions immediately.
14 #
15 #       - Prior to calling <Run()>, <NaturalDocs::Settings>, <NaturalDocs::Project>, <NaturalDocs::Menu>, and
16 #         <NaturalDocs::Parser> must be initialized.  <NaturalDocs::Settings->GenerateDirectoryNames()> must be called.
17 #         <NaturalDocs::SymbolTable> and <NaturalDocs::ClassHierarchy> must be initialized and fully resolved.
18 #
19 ###############################################################################
20
21 # This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
22 # Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
23 # Refer to License.txt for the complete details
24
25
26 use strict;
27 use integer;
28
29 use NaturalDocs::Builder::Base;
30 use NaturalDocs::Builder::HTML;
31 use NaturalDocs::Builder::FramedHTML;
32
33 package NaturalDocs::Builder;
34
35
36 ###############################################################################
37 # Group: Variables
38
39 #
40 #   Array: outputPackages
41 #
42 #   An array of the output packages available for use.
43 #
44 my @outputPackages;
45
46
47 ###############################################################################
48 # Group: Functions
49
50
51 #
52 #   Function: OutputPackages
53 #
54 #   Returns an arrayref of the output packages available for use.  The arrayref is not a copy of the data, so don't change it.
55 #
56 #   Add output packages to this list with the <Add()> function.
57 #
58 sub OutputPackages
59     {  return \@outputPackages;  };
60
61
62 #
63 #   Function: OutputPackageOf
64 #
65 #   Returns the output package corresponding to the passed command line option, or undef if none.
66 #
67 sub OutputPackageOf #(commandLineOption)
68     {
69     my ($self, $commandLineOption) = @_;
70
71     $commandLineOption = lc($commandLineOption);
72
73     foreach my $package (@outputPackages)
74         {
75         if (lc($package->CommandLineOption()) eq $commandLineOption)
76             {  return $package;  };
77         };
78
79     return undef;
80     };
81
82
83
84 #
85 #   Function: Add
86 #
87 #   Adds an output package to those available for use.  All output packages must call this function in order to be recognized.
88 #
89 #   Parameters:
90 #
91 #       package - The package name.
92 #
93 sub Add #(package)
94     {
95     my ($self, $package) = @_;
96
97     # Output packages shouldn't register themselves more than once, so we don't need to check for it.
98     push @outputPackages, $package;
99     };
100
101
102 #
103 #   Function: Run
104 #
105 #   Runs the build process.  This must be called *every time* Natural Docs is run, regardless of whether any source files changed
106 #   or not.  Some output packages have dependencies on files outside of the source tree that need to be checked.
107 #
108 #   Since there are multiple stages to the build process, this function will handle its own status messages.  There's no need to print
109 #   "Building files..." or something similar beforehand.
110 #
111 sub Run
112     {
113     my ($self) = @_;
114
115
116     # Determine what we're doing.
117
118     my $buildTargets = NaturalDocs::Settings->BuildTargets();
119
120     my $filesToBuild = NaturalDocs::Project->FilesToBuild();
121     my $numberOfFilesToBuild = (scalar keys %$filesToBuild) * (scalar @$buildTargets);
122
123     my $filesToPurge = NaturalDocs::Project->FilesToPurge();
124     my $numberOfFilesToPurge = (scalar keys %$filesToPurge) * (scalar @$buildTargets);
125
126     my $imagesToUpdate = NaturalDocs::Project->ImageFilesToUpdate();
127     my $numberOfImagesToUpdate = (scalar keys %$imagesToUpdate) * (scalar @$buildTargets);
128
129     my $imagesToPurge = NaturalDocs::Project->ImageFilesToPurge();
130     my $numberOfImagesToPurge = (scalar keys %$imagesToPurge) * (scalar @$buildTargets);
131
132     my %indexesToBuild;
133     my %indexesToPurge;
134
135     my $currentIndexes = NaturalDocs::Menu->Indexes();
136     my $previousIndexes = NaturalDocs::Menu->PreviousIndexes();
137
138     foreach my $index (keys %$currentIndexes)
139         {
140         if (NaturalDocs::SymbolTable->IndexChanged($index) || !exists $previousIndexes->{$index})
141             {
142             $indexesToBuild{$index} = 1;
143             };
144         };
145
146     # All indexes that still exist should have been deleted.
147     foreach my $index (keys %$previousIndexes)
148         {
149         if (!exists $currentIndexes->{$index})
150             {
151             $indexesToPurge{$index} = 1;
152             };
153         };
154
155     my $numberOfIndexesToBuild = (scalar keys %indexesToBuild) * (scalar @$buildTargets);
156     my $numberOfIndexesToPurge = (scalar keys %indexesToPurge) * (scalar @$buildTargets);
157
158
159     # Start the build process
160
161     foreach my $buildTarget (@$buildTargets)
162         {
163         $buildTarget->Builder()->BeginBuild( $numberOfFilesToBuild || $numberOfFilesToPurge ||
164                                                                $numberOfImagesToUpdate || $numberOfImagesToPurge ||
165                                                                $numberOfIndexesToBuild || $numberOfIndexesToPurge ||
166                                                                NaturalDocs::Menu->HasChanged() );
167         };
168
169     if ($numberOfFilesToPurge)
170         {
171         NaturalDocs::StatusMessage->Start('Purging ' . $numberOfFilesToPurge
172                                                           . ' file' . ($numberOfFilesToPurge > 1 ? 's' : '') . '...',
173                                                              scalar @$buildTargets);
174
175         foreach my $buildTarget (@$buildTargets)
176             {
177             $buildTarget->Builder()->PurgeFiles($filesToPurge);
178             NaturalDocs::StatusMessage->CompletedItem();
179             };
180         };
181
182     if ($numberOfIndexesToPurge)
183         {
184         NaturalDocs::StatusMessage->Start('Purging ' . $numberOfIndexesToPurge
185                                                            . ' index' . ($numberOfIndexesToPurge > 1 ? 'es' : '') . '...',
186                                                              scalar @$buildTargets);
187
188         foreach my $buildTarget (@$buildTargets)
189             {
190             $buildTarget->Builder()->PurgeIndexes(\%indexesToPurge);
191             NaturalDocs::StatusMessage->CompletedItem();
192             };
193         };
194
195     if ($numberOfImagesToPurge)
196         {
197         NaturalDocs::StatusMessage->Start('Purging ' . $numberOfImagesToPurge
198                                                           . ' image' . ($numberOfImagesToPurge > 1 ? 's' : '') . '...',
199                                                              scalar @$buildTargets);
200
201         foreach my $buildTarget (@$buildTargets)
202             {
203             $buildTarget->Builder()->PurgeImages($imagesToPurge);
204             NaturalDocs::StatusMessage->CompletedItem();
205             };
206         };
207
208     if ($numberOfFilesToBuild)
209         {
210         NaturalDocs::StatusMessage->Start('Building ' . $numberOfFilesToBuild
211                                                            . ' file' . ($numberOfFilesToBuild > 1 ? 's' : '') . '...',
212                                                              $numberOfFilesToBuild);
213
214         foreach my $file (keys %$filesToBuild)
215             {
216             my $parsedFile = NaturalDocs::Parser->ParseForBuild($file);
217
218             NaturalDocs::Error->OnStartBuilding($file);
219
220             foreach my $buildTarget (@$buildTargets)
221                 {
222                 $buildTarget->Builder()->BuildFile($file, $parsedFile);
223                 NaturalDocs::StatusMessage->CompletedItem();
224                 };
225
226             NaturalDocs::Error->OnEndBuilding($file);
227             };
228         };
229
230     if ($numberOfIndexesToBuild)
231         {
232         NaturalDocs::StatusMessage->Start('Building ' . $numberOfIndexesToBuild
233                                                           . ' index' . ($numberOfIndexesToBuild > 1 ? 'es' : '') . '...',
234                                                              $numberOfIndexesToBuild);
235
236         foreach my $index (keys %indexesToBuild)
237             {
238             foreach my $buildTarget (@$buildTargets)
239                 {
240                 $buildTarget->Builder()->BuildIndex($index);
241                 NaturalDocs::StatusMessage->CompletedItem();
242                 };
243             };
244         };
245
246     if ($numberOfImagesToUpdate)
247         {
248         NaturalDocs::StatusMessage->Start('Updating ' . $numberOfImagesToUpdate
249                                                           . ' image' . ($numberOfImagesToUpdate > 1 ? 's' : '') . '...',
250                                                              $numberOfImagesToUpdate);
251
252         foreach my $image (keys %$imagesToUpdate)
253             {
254             foreach my $buildTarget (@$buildTargets)
255                 {
256                 $buildTarget->Builder()->UpdateImage($image);
257                 NaturalDocs::StatusMessage->CompletedItem();
258                 };
259             };
260         };
261
262     if (NaturalDocs::Menu->HasChanged())
263         {
264         if (!NaturalDocs::Settings->IsQuiet())
265             {  print "Updating menu...\n";  };
266
267         foreach my $buildTarget (@$buildTargets)
268             {  $buildTarget->Builder()->UpdateMenu();  };
269         };
270
271     foreach my $buildTarget (@$buildTargets)
272         {
273         $buildTarget->Builder()->EndBuild($numberOfFilesToBuild || $numberOfFilesToPurge ||
274                                                            $numberOfIndexesToBuild || $numberOfIndexesToPurge ||
275                                                            $numberOfImagesToUpdate || $numberOfImagesToPurge ||
276                                                            NaturalDocs::Menu->HasChanged());
277         };
278     };
279
280
281 1;