fixed editor zooming if gui is not active
[twcon.git] / docs / tool / NaturalDocs
blobb5ddaea124137a60d69656b0ccb34e68fc08deb5
1 #!/usr/bin/perl
3 =begin nd
5 Script: NaturalDocs
6 ___________________________________________________________________________
8 Version 1.4
10 Copyright (C) 2003-2008 Greg Valure
12 http://www.naturaldocs.org
15 About: License
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
38 when it's not.
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
44 the significant part.
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
56 as opaque.
58 =cut
61 use strict;
62 use integer;
64 use 5.005; # When File::Spec was included by default
66 use English '-no_match_vars';
68 use FindBin;
69 use lib "$FindBin::RealBin/Modules";
71 sub INIT
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 ###############################################################################
106 # Group: Basic Types
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.
112 # Type: FileName
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>.
118 # Type: VersionInt
120 # A comparable integer representing a version number. Converting them to and from text and binary should be handled by
121 # <NaturalDocs::Version>.
124 # Type: SymbolString
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
136 # reference.
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
150 # follows:
152 # - End of string.
153 # - Whitespace. Line break-tab-space.
154 # - Symbols, which is anything not included in the other entries.
155 # - Numbers, 0-9.
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.
162 # Returns:
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)
168 my ($a, $b) = @_;
170 if (!defined $a)
172 if (!defined $b)
173 { return 0; }
174 else
175 { return -1; };
177 elsif (!defined $b)
179 return 1;
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;
190 if ($result == 0)
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); }
197 else
198 { return ($b cmp $a); };
200 else
201 { return $result; };
206 # Function: ShortenToMatchStrings
208 # Compares two arrayrefs and shortens the first array to only contain shared entries. Assumes all entries are strings.
210 # Parameters:
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) = @_;
219 my $index = 0;
221 while ($index < scalar @$sharedArrayRef && $index < scalar @$compareArrayRef &&
222 $sharedArrayRef->[$index] eq $compareArrayRef->[$index])
223 { $index++; };
225 if ($index < scalar @$sharedArrayRef)
226 { splice(@$sharedArrayRef, $index); };
231 # Function: XChomp
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.
236 # Parameters:
238 # lineRef - A *reference* to the line to chomp.
240 sub XChomp #(lineRef)
242 my $lineRef = shift;
243 $$lineRef =~ s/[\n\r]+$//;
248 # Function: FindFirstSymbol
250 # Searches a string for a number of symbols to see which appears first.
252 # Parameters:
254 # string - The string to search.
255 # symbols - An arrayref of symbols to look for.
256 # index - The index to start at, if any.
258 # Returns:
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) = @_;
269 if (!defined $index)
270 { $index = 0; };
272 my $lowestIndex = -1;
273 my $lowestSymbol;
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 ###############################################################################
294 # Main Code
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.
301 eval {
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;
347 if ($amount > 0)
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
371 # output messages.
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();
388 # Must be done last.
389 NaturalDocs::Project->SaveConfigFileInfo();
391 if (!NaturalDocs::Settings->IsQuiet())
392 { print "Done.\n"; };
396 if ($EVAL_ERROR) # Oops.
398 NaturalDocs::Error->HandleDeath();