6 ___________________________________________________________________________
10 Copyright (C) 2003-2008 Greg Valure
12 http://www.naturaldocs.org
17 Licensed under the GNU General Public License
19 This program is free software; you can redistribute it and/or modify
20 it under the terms of the GNU General Public License as published by
21 the Free Software Foundation; either version 2 of the License, or
22 (at your option) any later version.
24 This program is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 GNU General Public License for more details.
29 You should have received a copy of the GNU General Public License
30 along with this program; if not, visit http://www.gnu.org/licenses/gpl.txt
31 or write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
32 Boston, MA 02111-1307 USA.
35 Topic: Code Conventions
37 - Every package function is called with an arrow operator. It's needed for inheritance in some places, and consistency
40 - No constant will ever be zero or undef. Those are reserved so any piece of code can allow a "none of the above" option
41 and not worry about conflicts with an existing value.
43 - Existence hashes are hashes where the value doesn't matter. It acts more as a set, where the existence of the key is
47 Topic: File Format Conventions
49 - All integers appear in big-endian format. So a UInt16 should be handled with a 'n' in pack and unpack, not with a 'S'.
51 - AString16's are a big-endian UInt16 followed by that many ASCII characters. A null-terminator is not stored.
53 - If a higher-level type is described in a file format, that means the loading and saving format is handled by that package.
54 For example, if you see <SymbolString> in the format, that means <NaturalDocs::SymbolString->ToBinaryFile()> and
55 <NaturalDocs::SymbolString->FromBinaryFile()> are used to manipulate it, and the underlying format should be treated
64 use 5.005; # When File::Spec was included by default
66 use English
'-no_match_vars';
69 use lib
"$FindBin::RealBin/Modules";
73 # This function is just here so that when I start the debugger, it doesn't open a new file. Normally it would jump to an INIT
74 # function in some other file since that's the first piece of code to execute.
78 use NaturalDocs
::Constants
;
79 use NaturalDocs
::Version
;
80 use NaturalDocs
::File
;
81 use NaturalDocs
::Error
;
83 use NaturalDocs
::ConfigFile
;
84 use NaturalDocs
::BinaryFile
;
85 use NaturalDocs
::StatusMessage
;
86 use NaturalDocs
::SymbolString
;
87 use NaturalDocs
::ReferenceString
;
88 use NaturalDocs
::NDMarkup
;
90 use NaturalDocs
::Settings
;
91 use NaturalDocs
::Topics
;
92 use NaturalDocs
::Languages
;
93 use NaturalDocs
::Project
;
94 use NaturalDocs
::Menu
;
95 use NaturalDocs
::SymbolTable
;
96 use NaturalDocs
::ClassHierarchy
;
97 use NaturalDocs
::SourceDB
;
98 use NaturalDocs
::ImageReferenceTable
;
99 use NaturalDocs
::Parser
;
100 use NaturalDocs
::Builder
;
104 ###############################################################################
108 # Types used throughout the program. As Perl is a weakly-typed language unless you box things into objects, these types are
109 # for documentation purposes and are not enforced.
114 # A string representing the absolute, platform-dependent path to a file. Relative file paths are no longer in use anywhere in the
115 # program. All path manipulation should be done through <NaturalDocs::File>.
120 # A comparable integer representing a version number. Converting them to and from text and binary should be handled by
121 # <NaturalDocs::Version>.
126 # A scalar which encodes a normalized array of identifier strings representing a full or partially-resolved symbol. All symbols
127 # must be retrieved from plain text via <NaturalDocs::SymbolString->FromText()> so that the separation and normalization is
128 # always consistent. SymbolStrings are comparable via string compare functions and are sortable.
131 # Type: ReferenceString
133 # All the information about a reference that makes it unique encoded into a string. This includes the <SymbolString> of the
134 # reference, the scope <SymbolString> it appears in, the scope <SymbolStrings> it has access to via "using", and the
135 # <ReferenceType>. This is done because if any of those parameters change, it needs to be treated as a completely separate
141 ###############################################################################
142 # Group: Support Functions
143 # General functions that are used throughout the program, and that don't really fit anywhere else.
147 # Function: StringCompare
149 # Compares two strings so that the result is good for proper sorting. A proper sort orders the characters as
153 # - Whitespace. Line break-tab-space.
154 # - Symbols, which is anything not included in the other entries.
156 # - Letters, case insensitive except to break ties.
158 # If you use cmp instead of this function, the result would go by ASCII/Unicode values which would place certain symbols
159 # between letters and numbers instead of having them all grouped together. Also, you would have to choose between case
160 # sensitivity or complete case insensitivity, in which ties are broken arbitrarily.
164 # Like cmp, it returns zero if A and B are equal, a positive value if A is greater than B, and a negative value if A is less than B.
166 sub StringCompare
#(a, b)
182 my $translatedA = lc($a);
183 my $translatedB = lc($b);
185 $translatedA =~ tr/\n\r\t 0-9a-z/\x01\x02\x03\x04\xDB-\xFE/;
186 $translatedB =~ tr/\n\r\t 0-9a-z/\x01\x02\x03\x04\xDB-\xFE/;
188 my $result = $translatedA cmp $translatedB;
192 # Break the tie by comparing their case. Lowercase before uppercase.
194 # If statement just to keep everything theoretically kosher, even though in practice we don't need this.
195 if (ord('A') > ord('a'))
196 { return ($a cmp $b); }
198 { return ($b cmp $a); };
206 # Function: ShortenToMatchStrings
208 # Compares two arrayrefs and shortens the first array to only contain shared entries. Assumes all entries are strings.
212 # sharedArrayRef - The arrayref that will be shortened to only contain common elements.
213 # compareArrayRef - The arrayref to match.
215 sub ShortenToMatchStrings
#(sharedArrayRef, compareArrayRef)
217 my ($sharedArrayRef, $compareArrayRef) = @_;
221 while ($index < scalar @
$sharedArrayRef && $index < scalar @
$compareArrayRef &&
222 $sharedArrayRef->[$index] eq $compareArrayRef->[$index])
225 if ($index < scalar @
$sharedArrayRef)
226 { splice(@
$sharedArrayRef, $index); };
233 # A cross-platform chomp function. Regular chomp fails when parsing Windows-format line breaks on a Unix platform. It
234 # leaves the /r on, which screws everything up. This does not.
238 # lineRef - A *reference* to the line to chomp.
240 sub XChomp
#(lineRef)
243 $$lineRef =~ s/[\n\r]+$//;
248 # Function: FindFirstSymbol
250 # Searches a string for a number of symbols to see which appears first.
254 # string - The string to search.
255 # symbols - An arrayref of symbols to look for.
256 # index - The index to start at, if any.
260 # The array ( index, symbol ).
262 # index - The index the first symbol appears at, or -1 if none appear.
263 # symbol - The symbol that appeared, or undef if none.
265 sub FindFirstSymbol
#(string, symbols, index)
267 my ($string, $symbols, $index) = @_;
272 my $lowestIndex = -1;
275 foreach my $symbol (@
$symbols)
277 my $testIndex = index($string, $symbol, $index);
279 if ($testIndex != -1 && ($lowestIndex == -1 || $testIndex < $lowestIndex))
281 $lowestIndex = $testIndex;
282 $lowestSymbol = $symbol;
286 return ($lowestIndex, $lowestSymbol);
292 ###############################################################################
296 # The order in which functions are called here is critically important. Read the "Usage and Dependencies" sections of all the
297 # packages before even thinking about rearranging these.
303 # Check that our required packages are okay.
305 NaturalDocs
::File
->CheckCompatibility();
308 # Almost everything requires Settings to be initialized.
310 NaturalDocs
::Settings
->Load();
313 NaturalDocs
::Project
->LoadConfigFileInfo();
315 NaturalDocs
::Topics
->Load();
316 NaturalDocs
::Languages
->Load();
319 # Migrate from the old file names that were used prior to 1.14.
321 NaturalDocs
::Project
->MigrateOldFiles();
324 if (!NaturalDocs
::Settings
->IsQuiet())
325 { print "Finding files and detecting changes...\n"; };
327 NaturalDocs
::Project
->LoadSourceFileInfo();
328 NaturalDocs
::Project
->LoadImageFileInfo();
330 # Register SourceDB extensions. Order is important.
331 NaturalDocs
::ImageReferenceTable
->Register();
333 NaturalDocs
::SymbolTable
->Load();
334 NaturalDocs
::ClassHierarchy
->Load();
335 NaturalDocs
::SourceDB
->Load();
337 NaturalDocs
::SymbolTable
->Purge();
338 NaturalDocs
::ClassHierarchy
->Purge();
339 NaturalDocs
::SourceDB
->PurgeDeletedSourceFiles();
342 # Parse any supported files that have changed.
344 my $filesToParse = NaturalDocs
::Project
->FilesToParse();
345 my $amount = scalar keys %$filesToParse;
349 NaturalDocs
::StatusMessage
->Start('Parsing ' . $amount . ' file' . ($amount > 1 ?
's' : '') . '...', $amount);
351 foreach my $file (keys %$filesToParse)
353 NaturalDocs
::Parser
->ParseForInformation($file);
354 NaturalDocs
::StatusMessage
->CompletedItem();
359 # The symbol table is now fully resolved, so we can reduce its memory footprint.
361 NaturalDocs
::SymbolTable
->PurgeResolvingInfo();
364 # Load and update the menu file. We need to do this after parsing so when it is updated, it will detect files where the
365 # default menu title has changed and files that have added or deleted Natural Docs content.
367 NaturalDocs
::Menu
->LoadAndUpdate();
370 # Build any files that need it. This needs to be run regardless of whether there are any files to build. It will handle its own
373 NaturalDocs
::Builder
->Run();
376 # Write the changes back to disk.
378 NaturalDocs
::Menu
->Save();
379 NaturalDocs
::Project
->SaveImageFileInfo();
380 NaturalDocs
::Project
->SaveSourceFileInfo();
381 NaturalDocs
::SymbolTable
->Save();
382 NaturalDocs
::ClassHierarchy
->Save();
383 NaturalDocs
::SourceDB
->Save();
384 NaturalDocs
::Settings
->Save();
385 NaturalDocs
::Topics
->Save();
386 NaturalDocs
::Languages
->Save();
389 NaturalDocs
::Project
->SaveConfigFileInfo();
391 if (!NaturalDocs
::Settings
->IsQuiet())
392 { print "Done.\n"; };
396 if ($EVAL_ERROR) # Oops.
398 NaturalDocs
::Error
->HandleDeath();