File: NaturalDocs

package info (click to toggle)
naturaldocs 1.35%2Bdevel.2007.12.07-2
  • links: PTS
  • area: main
  • in suites: lenny, squeeze
  • size: 1,460 kB
  • ctags: 966
  • sloc: perl: 17,253; makefile: 49; sh: 1
file content (400 lines) | stat: -rw-r--r-- 11,991 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
#!/usr/bin/perl

=begin nd

    Script: NaturalDocs
    ___________________________________________________________________________

    Version 1.4

    Copyright (C) 2003-2006 Greg Valure

    http://www.naturaldocs.org


    About: License

        Licensed under the GNU General Public License

        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 2 of the License, or
        (at your option) any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program; if not, visit http://www.gnu.org/licenses/gpl.txt
        or write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
        Boston, MA  02111-1307  USA.


    Topic: Code Conventions

        - Every package function is called with an arrow operator.  It's needed for inheritance in some places, and consistency
         when it's not.

        - No constant will ever be zero or undef.  Those are reserved so any piece of code can allow a "none of the above" option
         and not worry about conflicts with an existing value.

        - Existence hashes are hashes where the value doesn't matter.  It acts more as a set, where the existence of the key is
         the significant part.


    Topic: File Format Conventions

        - All integers appear in big-endian format.  So a UInt16 should be handled with a 'n' in pack and unpack, not with a 'S'.

        - AString16's are a big-endian UInt16 followed by that many ASCII characters.  A null-terminator is not stored.

        - If a higher-level type is described in a file format, that means the loading and saving format is handled by that package.
         For example, if you see <SymbolString> in the format, that means <NaturalDocs::SymbolString->ToBinaryFile()> and
         <NaturalDocs::SymbolString->FromBinaryFile()> are used to manipulate it, and the underlying format should be treated
         as opaque.

=cut


use strict;
use integer;

use 5.005;  # When File::Spec was included by default

use English '-no_match_vars';

use FindBin;
use lib "$FindBin::RealBin/Modules";

sub INIT
    {
    # 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
    # function in some other file since that's the first piece of code to execute.
    };


use NaturalDocs::Constants;
use NaturalDocs::Version;
use NaturalDocs::File;
use NaturalDocs::Error;

use NaturalDocs::ConfigFile;
use NaturalDocs::BinaryFile;
use NaturalDocs::StatusMessage;
use NaturalDocs::SymbolString;
use NaturalDocs::ReferenceString;
use NaturalDocs::NDMarkup;

use NaturalDocs::Settings;
use NaturalDocs::Topics;
use NaturalDocs::Languages;
use NaturalDocs::Project;
use NaturalDocs::Menu;
use NaturalDocs::SymbolTable;
use NaturalDocs::ClassHierarchy;
use NaturalDocs::SourceDB;
use NaturalDocs::ImageReferenceTable;
use NaturalDocs::Parser;
use NaturalDocs::Builder;



###############################################################################
#
#   Group: Basic Types
#
#   Types used throughout the program.  As Perl is a weakly-typed language unless you box things into objects, these types are
#   for documentation purposes and are not enforced.
#
#
#   Type: FileName
#
#   A string representing the absolute, platform-dependent path to a file.  Relative file paths are no longer in use anywhere in the
#   program.  All path manipulation should be done through <NaturalDocs::File>.
#
#
#   Type: VersionInt
#
#   A comparable integer representing a version number.  Converting them to and from text and binary should be handled by
#   <NaturalDocs::Version>.
#
#
#   Type: SymbolString
#
#   A scalar which encodes a normalized array of identifier strings representing a full or partially-resolved symbol.  All symbols
#   must be retrieved from plain text via <NaturalDocs::SymbolString->FromText()> so that the separation and normalization is
#   always consistent.  SymbolStrings are comparable via string compare functions and are sortable.
#
#
#   Type: ReferenceString
#
#   All the information about a reference that makes it unique encoded into a string.  This includes the <SymbolString> of the
#   reference, the scope <SymbolString> it appears in, the scope <SymbolStrings> it has access to via "using", and the
#   <ReferenceType>.  This is done because if any of those parameters change, it needs to be treated as a completely separate
#   reference.
#



###############################################################################
# Group: Support Functions
# General functions that are used throughout the program, and that don't really fit anywhere else.


#
#   Function: StringCompare
#
#   Compares two strings so that the result is good for proper sorting.  A proper sort orders the characters as
#   follows:
#
#   - End of string.
#   - Whitespace.  Line break-tab-space.
#   - Symbols, which is anything not included in the other entries.
#   - Numbers, 0-9.
#   - Letters, case insensitive except to break ties.
#
#   If you use cmp instead of this function, the result would go by ASCII/Unicode values which would place certain symbols
#   between letters and numbers instead of having them all grouped together.  Also, you would have to choose between case
#   sensitivity or complete case insensitivity, in which ties are broken arbitrarily.
#
#   Returns:
#
#   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.
#
sub StringCompare #(a, b)
    {
    my ($a, $b) = @_;

    if (!defined $a)
        {
        if (!defined $b)
            {  return 0;  }
        else
            {  return -1;  };
        }
    elsif (!defined $b)
        {
        return 1;
        };

    my $translatedA = lc($a);
    my $translatedB = lc($b);

    $translatedA =~ tr/\n\r\t 0-9a-z/\x01\x02\x03\x04\xDB-\xFE/;
    $translatedB =~ tr/\n\r\t 0-9a-z/\x01\x02\x03\x04\xDB-\xFE/;

    my $result = $translatedA cmp $translatedB;

    if ($result == 0)
        {
        # Break the tie by comparing their case.  Lowercase before uppercase.

        # If statement just to keep everything theoretically kosher, even though in practice we don't need this.
        if (ord('A') > ord('a'))
            {  return ($a cmp $b);  }
        else
            {  return ($b cmp $a);  };
        }
    else
        {  return $result;  };
    };


#
#   Function: ShortenToMatchStrings
#
#   Compares two arrayrefs and shortens the first array to only contain shared entries.  Assumes all entries are strings.
#
#   Parameters:
#
#       sharedArrayRef - The arrayref that will be shortened to only contain common elements.
#       compareArrayRef - The arrayref to match.
#
sub ShortenToMatchStrings #(sharedArrayRef, compareArrayRef)
    {
    my ($sharedArrayRef, $compareArrayRef) = @_;

    my $index = 0;

    while ($index < scalar @$sharedArrayRef && $index < scalar @$compareArrayRef &&
             $sharedArrayRef->[$index] eq $compareArrayRef->[$index])
        {  $index++;  };

    if ($index < scalar @$sharedArrayRef)
        {  splice(@$sharedArrayRef, $index);  };
    };


#
#   Function: XChomp
#
#   A cross-platform chomp function.  Regular chomp fails when parsing Windows-format line breaks on a Unix platform.  It
#   leaves the /r on, which screws everything up.  This does not.
#
#   Parameters:
#
#       lineRef - A *reference* to the line to chomp.
#
sub XChomp #(lineRef)
    {
    my $lineRef = shift;
    $$lineRef =~ s/[\n\r]+$//;
    };


#
#   Function: FindFirstSymbol
#
#   Searches a string for a number of symbols to see which appears first.
#
#   Parameters:
#
#       string - The string to search.
#       symbols - An arrayref of symbols to look for.
#       index - The index to start at, if any.
#
#   Returns:
#
#       The array ( index, symbol ).
#
#       index - The index the first symbol appears at, or -1 if none appear.
#       symbol - The symbol that appeared, or undef if none.
#
sub FindFirstSymbol #(string, symbols, index)
    {
    my ($string, $symbols, $index) = @_;

    if (!defined $index)
        {  $index = 0;  };

    my $lowestIndex = -1;
    my $lowestSymbol;

    foreach my $symbol (@$symbols)
        {
        my $testIndex = index($string, $symbol, $index);

        if ($testIndex != -1 && ($lowestIndex == -1 || $testIndex < $lowestIndex))
            {
            $lowestIndex = $testIndex;
            $lowestSymbol = $symbol;
            };
        };

    return ($lowestIndex, $lowestSymbol);
    };




###############################################################################
#
#   Main Code
#
#   The order in which functions are called here is critically important.  Read the "Usage and Dependencies" sections of all the
#   packages before even thinking about rearranging these.
#


eval {

    # Check that our required packages are okay.

    NaturalDocs::File->CheckCompatibility();


    # Almost everything requires Settings to be initialized.

    NaturalDocs::Settings->Load();


    NaturalDocs::Project->LoadConfigFileInfo();

    NaturalDocs::Topics->Load();
    NaturalDocs::Languages->Load();


    # Migrate from the old file names that were used prior to 1.14.

    NaturalDocs::Project->MigrateOldFiles();


    if (!NaturalDocs::Settings->IsQuiet())
        {  print "Finding files and detecting changes...\n";  };

    NaturalDocs::Project->LoadSourceFileInfo();
    NaturalDocs::Project->LoadImageFileInfo();

    # Register SourceDB extensions.  Order is important.
    NaturalDocs::ImageReferenceTable->Register();

    NaturalDocs::SymbolTable->Load();
    NaturalDocs::ClassHierarchy->Load();
    NaturalDocs::SourceDB->Load();

    NaturalDocs::SymbolTable->Purge();
    NaturalDocs::ClassHierarchy->Purge();
    NaturalDocs::SourceDB->PurgeDeletedSourceFiles();


    # Parse any supported files that have changed.

    my $filesToParse = NaturalDocs::Project->FilesToParse();
    my $amount = scalar keys %$filesToParse;

    if ($amount > 0)
        {
        NaturalDocs::StatusMessage->Start('Parsing ' . $amount . ' file' . ($amount > 1 ? 's' : '') . '...', $amount);

        foreach my $file (keys %$filesToParse)
            {
            NaturalDocs::Parser->ParseForInformation($file);
            NaturalDocs::StatusMessage->CompletedItem();
            };
        };


    # The symbol table is now fully resolved, so we can reduce its memory footprint.

    NaturalDocs::SymbolTable->PurgeResolvingInfo();


    # Load and update the menu file.  We need to do this after parsing so when it is updated, it will detect files where the
    # default menu title has changed and files that have added or deleted Natural Docs content.

    NaturalDocs::Menu->LoadAndUpdate();


    # 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
    # output messages.

    NaturalDocs::Builder->Run();


    # Write the changes back to disk.

    NaturalDocs::Menu->Save();
    NaturalDocs::Project->SaveImageFileInfo();
    NaturalDocs::Project->SaveSourceFileInfo();
    NaturalDocs::SymbolTable->Save();
    NaturalDocs::ClassHierarchy->Save();
    NaturalDocs::SourceDB->Save();
    NaturalDocs::Settings->Save();
    NaturalDocs::Topics->Save();
    NaturalDocs::Languages->Save();

    # Must be done last.
    NaturalDocs::Project->SaveConfigFileInfo();

    if (!NaturalDocs::Settings->IsQuiet())
        {  print "Done.\n";  };

};

if ($EVAL_ERROR)  # Oops.
    {
    NaturalDocs::Error->HandleDeath();
    };